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 */
237 }, /* ARCHITECTURE */
240 int evalop(struct pri
);
241 struct value
tokval(Token
*);
242 struct value vals
[NSTAK
], *vp
;
243 enum toktype ops
[NSTAK
], *op
;
246 * Evaluate an #if #elif #ifdef #ifndef line. trp->tp points to the keyword.
249 eval(Tokenrow
* trp
, int kw
)
257 if (kw
== KIFDEF
|| kw
== KIFNDEF
)
259 if (trp
->lp
- trp
->bp
!= 4 || trp
->tp
->type
!= NAME
)
261 error(ERROR
, "Syntax error in #ifdef/#ifndef");
264 np
= lookup(trp
->tp
, 0);
265 return (kw
== KIFDEF
) == (np
&& np
->flag
& (ISDEFINED
| ISMAC
));
267 ntok
= trp
->tp
- trp
->bp
;
268 kwdefined
->val
= KDEFINED
; /* activate special meaning of
270 expandrow(trp
, "<if>");
271 kwdefined
->val
= NAME
;
275 for (rnd
= 0, tp
= trp
->bp
+ ntok
; tp
< trp
->lp
; tp
++)
312 if (tp
->type
== MINUS
)
314 if (tp
->type
== STAR
|| tp
->type
== AND
)
316 error(ERROR
, "Illegal operator * or & in #if/#elif");
343 if (evalop(priority
[tp
->type
]) != 0)
358 if (evalop(priority
[RP
]) != 0)
360 if (op
<= ops
|| op
[-1] != LP
)
368 if ((tp
+ 1) < trp
->lp
)
370 np
= lookup(tp
+ 1, 0);
371 if (np
&& (np
->val
== KMACHINE
))
376 *op
++ = ARCHITECTURE
;
383 error(ERROR
, "Bad operator (%t) in #if/#elif", tp
);
389 if (evalop(priority
[END
]) != 0)
391 if (op
!= &ops
[1] || vp
!= &vals
[1])
393 error(ERROR
, "Botch in #if/#elif");
396 if (vals
[0].type
== UND
)
397 error(ERROR
, "Undefined expression value");
400 error(ERROR
, "Syntax error in #if/#elif");
405 evalop(struct pri pri
)
408 struct value v2
= { 0, UND
};
414 while (pri
.pri
< priority
[op
[-1]].pri
)
417 if (priority
[oper
].arity
== 2)
424 /*lint -e574 -e644 */
425 switch (priority
[oper
].ctype
)
429 error(WARNING
, "Syntax error in #if/#endif");
433 if (v1
.type
== UNS
|| v2
.type
== UNS
)
437 if (v1
.type
== UND
|| v2
.type
== UND
)
439 if (priority
[oper
].ctype
== RELAT
&& rtype
== UNS
)
446 if (v1
.type
== UND
|| v2
.type
== UND
)
483 rv1
= (unsigned long)rv1
<= (unsigned long)rv2
;
486 rv1
= (unsigned long)rv1
>= (unsigned long)rv2
;
489 rv1
= (unsigned long)rv1
< (unsigned long)rv2
;
492 rv1
= (unsigned long)rv1
> (unsigned long)rv2
;
498 rv1
= (unsigned long) rv1
<< rv2
;
504 rv1
= (unsigned long) rv1
>> rv2
;
572 rv1
/= (unsigned long) rv2
;
583 rv1
%= (unsigned long) rv2
;
589 error(ERROR
, "Bad ?: in #if/endif");
593 if ((--vp
)->val
== 0)
605 error(ERROR
, "Eval botch (unknown operator)");
608 /*lint +e574 +e644 */
635 if ((np
= lookup(tp
, 0)) != NULL
&& np
->flag
& (ISDEFINED
| ISMAC
))
640 if ((np
= lookup(tp
, 0)) != NULL
&& np
->flag
& (ISARCHITECTURE
))
653 if (p
[1] == 'x' || p
[1] == 'X')
662 if ((i
= digit(*p
)) < 0)
666 "Bad digit in number %t", tp
);
670 if (n
>= 0x80000000 && base
!= 10)
674 if (*p
== 'u' || *p
== 'U')
677 if (*p
== 'l' || *p
== 'L')
682 "Bad number %t in #if/#elif", tp
);
696 error(WARNING
, "Wide char constant value undefined");
702 if ((i
= digit(*p
)) >= 0 && i
<= 7)
706 if ((i
= digit(*p
)) >= 0 && i
<= 7)
711 if ((i
= digit(*p
)) >= 0 && i
<= 7)
723 while ((i
= digit(*p
)) >= 0 && i
<= 15)
732 static const char cvcon
[] = "b\bf\fn\nr\rt\tv\v''\"\"??\\\\";
733 static size_t cvlen
= sizeof(cvcon
) - 1;
736 for (j
= 0; j
< cvlen
; j
+= 2)
747 "Undefined escape in character constant");
752 error(ERROR
, "Empty character constant");
756 error(WARNING
, "Multibyte character constant undefined");
759 error(WARNING
, "Character constant taken as not signed");
764 error(ERROR
, "String in #if/#elif");
773 if ('0' <= i
&& i
<= '9')
776 if ('a' <= i
&& i
<= 'f')
779 if ('A' <= i
&& i
<= 'F')
786 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */