1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
27 #define UNSMARK 0x1000
35 /* conversion types */
43 /* operator priority, arity, and conversion type, indexed by tokentype */
51 static const struct pri priority
[] =
238 }, /* ARCHITECTURE */
241 static int evalop(struct pri
);
242 static struct value
tokval(Token
*);
243 static struct value vals
[NSTAK
], *vp
;
244 static enum toktype ops
[NSTAK
], *op
;
247 * Evaluate an #if #elif #ifdef #ifndef line. trp->tp points to the keyword.
250 eval(Tokenrow
* trp
, int kw
)
258 if (kw
== KIFDEF
|| kw
== KIFNDEF
)
260 if (trp
->lp
- trp
->bp
!= 4 || trp
->tp
->type
!= NAME
)
262 error(ERROR
, "Syntax error in #ifdef/#ifndef");
265 np
= lookup(trp
->tp
, 0);
266 return (kw
== KIFDEF
) == (np
&& np
->flag
& (ISDEFINED
| ISMAC
));
268 ntok
= trp
->tp
- trp
->bp
;
269 kwdefined
->val
= KDEFINED
; /* activate special meaning of
271 expandrow(trp
, "<if>");
272 kwdefined
->val
= NAME
;
276 for (rnd
= 0, tp
= trp
->bp
+ ntok
; tp
< trp
->lp
; tp
++)
313 if (tp
->type
== MINUS
)
315 if (tp
->type
== STAR
|| tp
->type
== AND
)
317 error(ERROR
, "Illegal operator * or & in #if/#elif");
344 if (evalop(priority
[tp
->type
]) != 0)
359 if (evalop(priority
[RP
]) != 0)
361 if (op
<= ops
|| op
[-1] != LP
)
369 if ((tp
+ 1) < trp
->lp
)
371 np
= lookup(tp
+ 1, 0);
372 if (np
&& (np
->val
== KMACHINE
))
377 *op
++ = ARCHITECTURE
;
384 error(ERROR
, "Bad operator (%t) in #if/#elif", tp
);
390 if (evalop(priority
[END
]) != 0)
392 if (op
!= &ops
[1] || vp
!= &vals
[1])
394 error(ERROR
, "Botch in #if/#elif");
397 if (vals
[0].type
== UND
)
398 error(ERROR
, "Undefined expression value");
401 error(ERROR
, "Syntax error in #if/#elif");
406 evalop(struct pri pri
)
409 struct value v2
= { 0, UND
};
415 while (pri
.pri
< priority
[op
[-1]].pri
)
418 if (priority
[oper
].arity
== 2)
425 /*lint -e574 -e644 */
426 switch (priority
[oper
].ctype
)
430 error(WARNING
, "Syntax error in #if/#endif");
434 if (v1
.type
== UNS
|| v2
.type
== UNS
)
438 if (v1
.type
== UND
|| v2
.type
== UND
)
440 if (priority
[oper
].ctype
== RELAT
&& rtype
== UNS
)
447 if (v1
.type
== UND
|| v2
.type
== UND
)
484 rv1
= (unsigned long)rv1
<= (unsigned long)rv2
;
487 rv1
= (unsigned long)rv1
>= (unsigned long)rv2
;
490 rv1
= (unsigned long)rv1
< (unsigned long)rv2
;
493 rv1
= (unsigned long)rv1
> (unsigned long)rv2
;
499 rv1
= (unsigned long) rv1
<< rv2
;
505 rv1
= (unsigned long) rv1
>> rv2
;
573 rv1
/= (unsigned long) rv2
;
584 rv1
%= (unsigned long) rv2
;
590 error(ERROR
, "Bad ?: in #if/endif");
594 if ((--vp
)->val
== 0)
606 error(ERROR
, "Eval botch (unknown operator)");
609 /*lint +e574 +e644 */
636 if ((np
= lookup(tp
, 0)) != NULL
&& np
->flag
& (ISDEFINED
| ISMAC
))
641 if ((np
= lookup(tp
, 0)) != NULL
&& np
->flag
& (ISARCHITECTURE
))
654 if (p
[1] == 'x' || p
[1] == 'X')
663 if ((i
= digit(*p
)) < 0)
667 "Bad digit in number %t", tp
);
671 if (n
>= 0x80000000 && base
!= 10)
675 if (*p
== 'u' || *p
== 'U')
678 if (*p
== 'l' || *p
== 'L')
683 "Bad number %t in #if/#elif", tp
);
697 error(WARNING
, "Wide char constant value undefined");
703 if ((i
= digit(*p
)) >= 0 && i
<= 7)
707 if ((i
= digit(*p
)) >= 0 && i
<= 7)
712 if ((i
= digit(*p
)) >= 0 && i
<= 7)
724 while ((i
= digit(*p
)) >= 0 && i
<= 15)
733 static const char cvcon
[] = "b\bf\fn\nr\rt\tv\v''\"\"??\\\\";
734 static size_t cvlen
= sizeof(cvcon
) - 1;
737 for (j
= 0; j
< cvlen
; j
+= 2)
748 "Undefined escape in character constant");
753 error(ERROR
, "Empty character constant");
757 error(WARNING
, "Multibyte character constant undefined");
760 error(WARNING
, "Character constant taken as not signed");
765 error(ERROR
, "String in #if/#elif");
774 if ('0' <= i
&& i
<= '9')
777 if ('a' <= i
&& i
<= 'f')
780 if ('A' <= i
&& i
<= 'F')
787 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */