1 /* Parse C expressions for CCCP.
2 Copyright (C) 1987, 92, 94, 95, 97, 98, 1999 Free Software Foundation.
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 2, or (at your option) any
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
19 In other words, you are welcome to use, share and improve this program.
20 You are forbidden to forbid anyone else to use, share and improve
21 what you give them. Help stamp out software-hoarding!
23 Written by Per Bothner 1994. */
25 /* Parse a C expression from text in a string */
31 #ifdef MULTIBYTE_CHARS
35 #ifndef CHAR_TYPE_SIZE
36 #define CHAR_TYPE_SIZE BITS_PER_UNIT
40 #define INT_TYPE_SIZE BITS_PER_WORD
43 #ifndef LONG_TYPE_SIZE
44 #define LONG_TYPE_SIZE BITS_PER_WORD
47 #ifndef WCHAR_TYPE_SIZE
48 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
51 #ifndef MAX_CHAR_TYPE_SIZE
52 #define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
55 #ifndef MAX_INT_TYPE_SIZE
56 #define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
59 #ifndef MAX_LONG_TYPE_SIZE
60 #define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
63 #ifndef MAX_WCHAR_TYPE_SIZE
64 #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
67 #define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
68 ? (~ (~ (HOST_WIDEST_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
69 : ~ (HOST_WIDEST_INT) 0)
71 #define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
72 ? ~ (~ (HOST_WIDEST_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
73 : ~ (HOST_WIDEST_INT) 0)
75 /* Yield nonzero if adding two numbers with A's and B's signs can yield a
76 number with SUM's sign, where A, B, and SUM are all C integers. */
77 #define possible_sum_sign(a, b, sum) ((((a) ^ (b)) | ~ ((a) ^ (sum))) < 0)
79 static void integer_overflow
PARAMS ((cpp_reader
*));
80 static HOST_WIDEST_INT left_shift
PARAMS ((cpp_reader
*, HOST_WIDEST_INT
, int, unsigned HOST_WIDEST_INT
));
81 static HOST_WIDEST_INT right_shift
PARAMS ((cpp_reader
*, HOST_WIDEST_INT
, int, unsigned HOST_WIDEST_INT
));
96 #define LEFT_OPERAND_REQUIRED 1
97 #define RIGHT_OPERAND_REQUIRED 2
99 /* SKIP_OPERAND is set for '&&' '||' '?' and ':' when the
100 following operand should be short-circuited instead of evaluated. */
101 #define SKIP_OPERAND 8
102 /*#define UNSIGNEDP 16*/
106 char rprio
; /* Priority of op (relative to it right operand). */
108 char unsignedp
; /* true if value should be treated as unsigned */
109 HOST_WIDEST_INT value
; /* The value logically "right" of op. */
112 /* Parse and convert an integer for #if. Accepts decimal, hex, or octal
113 with or without size suffixes. */
115 static struct operation
116 parse_number (pfile
, start
, end
)
124 unsigned HOST_WIDEST_INT n
= 0, nd
, MAX_over_base
;
127 int digit
, largest_digit
= 0;
134 if (end
- start
>= 3 && (p
[1] == 'x' || p
[1] == 'X'))
146 /* Some buggy compilers (e.g. MPW C) seem to need both casts. */
147 MAX_over_base
= (((unsigned HOST_WIDEST_INT
) -1)
148 / ((unsigned HOST_WIDEST_INT
) base
));
154 if (c
>= '0' && c
<= '9')
156 else if (base
== 16 && c
>= 'a' && c
<= 'f') /* FIXME: assumes ASCII */
157 digit
= c
- 'a' + 10;
158 else if (base
== 16 && c
>= 'A' && c
<= 'F')
159 digit
= c
- 'A' + 10;
162 /* It's a float since it contains a point. */
164 "floating point numbers are not allowed in #if expressions");
169 /* `l' means long, and `u' means unsigned. */
172 if (c
== 'l' || c
== 'L')
174 else if (c
== 'u' || c
== 'U')
178 /* Decrement p here so that the error for an invalid number
179 will be generated below in the case where this is the
180 last character in the buffer. */
188 /* Don't look for any more digits after the suffixes. */
192 if (largest_digit
< digit
)
193 largest_digit
= digit
;
194 nd
= n
* base
+ digit
;
195 overflow
|= MAX_over_base
< n
|| nd
< n
;
201 cpp_error (pfile
, "invalid number in #if expression");
204 else if (spec_long
> (CPP_OPTIONS (pfile
)->c89
? 1 : 2))
206 cpp_error (pfile
, "too many `l' suffixes in integer constant");
209 else if (op
.unsignedp
> 1)
211 cpp_error (pfile
, "too many `u' suffixes in integer constant");
215 if (base
<= largest_digit
)
216 cpp_pedwarn (pfile
, "integer constant contains digits beyond the radix");
219 cpp_pedwarn (pfile
, "integer constant out of range");
221 /* If too big to be signed, consider it unsigned. */
222 else if ((HOST_WIDEST_INT
) n
< 0 && ! op
.unsignedp
)
226 "integer constant is so large that it is unsigned");
239 /* Parse and convert a character constant for #if. Understands backslash
240 escapes (\n, \031) and multibyte characters (if so configured). */
241 static struct operation
242 parse_charconst (pfile
, start
, end
)
248 HOST_WIDEST_INT result
= 0;
251 unsigned int width
= MAX_CHAR_TYPE_SIZE
, mask
= MAX_CHAR_TYPE_MASK
;
255 /* FIXME: Should use reentrant multibyte functions. */
256 #ifdef MULTIBYTE_CHARS
257 wchar_t c
= (wchar_t)-1;
258 (void) mbtowc (NULL_PTR
, NULL_PTR
, 0);
266 width
= MAX_WCHAR_TYPE_SIZE
, mask
= MAX_WCHAR_TYPE_MASK
;
268 max_chars
= MAX_LONG_TYPE_SIZE
/ width
;
270 ++ptr
; /* skip initial quote */
274 #ifndef MULTIBYTE_CHARS
277 ptr
+= mbtowc (&c
, ptr
, end
- ptr
);
279 if (c
== '\'' || c
== '\0')
283 /* Hopefully valid assumption: if mbtowc returns a backslash,
284 we are in initial shift state. No valid escape-sequence
285 character can take us out of initial shift state or begin
286 an unshifted multibyte char, so cpp_parse_escape doesn't
287 need to know about multibyte chars. */
289 c
= cpp_parse_escape (pfile
, (char **) &ptr
, mask
);
290 if (width
< HOST_BITS_PER_INT
291 && (unsigned int) c
>= (unsigned int)(1 << width
))
292 cpp_pedwarn (pfile
, "escape sequence out of range for character");
295 /* Merge character into result; ignore excess chars. */
296 if (++num_chars
<= max_chars
)
298 if (width
< HOST_BITS_PER_INT
)
299 result
= (result
<< width
) | (c
& ((1 << width
) - 1));
307 cpp_error (pfile
, "empty character constant");
312 /* cpp_get_token has already emitted an error if !traditional. */
313 if (! CPP_TRADITIONAL (pfile
))
314 cpp_error (pfile
, "malformatted character constant");
317 else if (num_chars
> max_chars
)
319 cpp_error (pfile
, "character constant too long");
322 else if (num_chars
!= 1 && ! CPP_TRADITIONAL (pfile
))
323 cpp_warning (pfile
, "multi-character character constant");
325 /* If char type is signed, sign-extend the constant. */
326 num_bits
= num_chars
* width
;
328 if (cpp_lookup (pfile
, (U_CHAR
*)"__CHAR_UNSIGNED__",
329 sizeof ("__CHAR_UNSIGNED__")-1, -1)
330 || ((result
>> (num_bits
- 1)) & 1) == 0)
331 op
.value
= result
& ((unsigned HOST_WIDEST_INT
) ~0
332 >> (HOST_BITS_PER_WIDEST_INT
- num_bits
));
334 op
.value
= result
| ~((unsigned HOST_WIDEST_INT
) ~0
335 >> (HOST_BITS_PER_WIDEST_INT
- num_bits
));
337 /* This is always a signed type. */
353 static struct token tokentab2
[] = {
367 /* Read one token. */
369 static struct operation
370 cpp_lex (pfile
, skip_evaluation
)
375 struct token
*toktab
;
376 enum cpp_token token
;
378 U_CHAR
*tok_start
, *tok_end
;
383 old_written
= CPP_WRITTEN (pfile
);
384 cpp_skip_hspace (pfile
);
385 c
= CPP_BUF_PEEK (CPP_BUFFER (pfile
));
389 op
.value
= cpp_read_check_assertion (pfile
);
399 token
= cpp_get_token (pfile
);
400 tok_start
= pfile
->token_buffer
+ old_written
;
401 tok_end
= CPP_PWRITTEN (pfile
);
402 pfile
->limit
= tok_start
;
405 case CPP_EOF
: /* Should not happen ... */
410 if (CPP_BUFFER (pfile
)->fname
!= NULL
)
415 cpp_pop_buffer (pfile
);
421 return parse_number (pfile
, tok_start
, tok_end
);
423 cpp_error (pfile
, "string constants not allowed in #if expressions");
427 return parse_charconst (pfile
, tok_start
, tok_end
);
433 if (strcmp (tok_start
, "defined"))
435 if (CPP_WARN_UNDEF (pfile
) && !skip_evaluation
)
436 cpp_warning (pfile
, "`%.*s' is not defined",
437 (int) (tok_end
- tok_start
), tok_start
);
442 cpp_buffer
*ip
= CPP_BUFFER (pfile
);
445 cpp_skip_hspace (pfile
);
449 ip
->cur
++; /* Skip over the paren */
450 cpp_skip_hspace (pfile
);
453 if (!is_idstart
[*ip
->cur
])
455 if (ip
->cur
[0] == 'L' && (ip
->cur
[1] == '\'' || ip
->cur
[1] == '"'))
458 while (is_idchar
[*ip
->cur
])
461 cpp_skip_hspace (pfile
);
468 if (cpp_lookup (pfile
, tok
, len
, -1))
475 cpp_error (pfile
, "`defined' without an identifier");
479 /* See if it is a special token of length 2. */
480 if (tok_start
+ 2 == tok_end
)
482 for (toktab
= tokentab2
; toktab
->operator != NULL
; toktab
++)
483 if (tok_start
[0] == toktab
->operator[0]
484 && tok_start
[1] == toktab
->operator[1])
486 if (toktab
->token
== ERROR
)
487 cpp_error (pfile
, "`%s' not allowed in operand of `#if'",
489 op
.op
= toktab
->token
;
500 /* Parse a C escape sequence. STRING_PTR points to a variable
501 containing a pointer to the string to parse. That pointer
502 is updated past the characters we use. The value of the
503 escape sequence is returned.
505 A negative value means the sequence \ newline was seen,
506 which is supposed to be equivalent to nothing at all.
508 If \ is followed by a null character, we return a negative
509 value and leave the string pointer pointing at the null character.
511 If \ is followed by 000, we return 0 and leave the string pointer
512 after the zeros. A value of 0 does not mean end of string. */
515 cpp_parse_escape (pfile
, string_ptr
, result_mask
)
518 HOST_WIDEST_INT result_mask
;
520 register int c
= *(*string_ptr
)++;
529 if (CPP_OPTIONS (pfile
)->pedantic
)
530 cpp_pedwarn (pfile
, "non-ANSI-standard escape sequence, `\\%c'", c
);
535 return TARGET_NEWLINE
;
557 register HOST_WIDEST_INT i
= c
- '0';
558 register int count
= 0;
561 c
= *(*string_ptr
)++;
562 if (c
>= '0' && c
<= '7')
563 i
= (i
<< 3) + c
- '0';
570 if (i
!= (i
& result_mask
))
573 cpp_pedwarn (pfile
, "octal escape sequence out of range");
579 register unsigned HOST_WIDEST_INT i
= 0, overflow
= 0;
580 register int digits_found
= 0, digit
;
583 c
= *(*string_ptr
)++;
584 if (c
>= '0' && c
<= '9')
586 else if (c
>= 'a' && c
<= 'f')
587 digit
= c
- 'a' + 10;
588 else if (c
>= 'A' && c
<= 'F')
589 digit
= c
- 'A' + 10;
595 overflow
|= i
^ (i
<< 4 >> 4);
596 i
= (i
<< 4) + digit
;
600 cpp_error (pfile
, "\\x used with no following hex digits");
601 if (overflow
| (i
!= (i
& result_mask
)))
604 cpp_pedwarn (pfile
, "hex escape sequence out of range");
614 integer_overflow (pfile
)
617 if (CPP_PEDANTIC (pfile
))
618 cpp_pedwarn (pfile
, "integer overflow in preprocessor expression");
621 static HOST_WIDEST_INT
622 left_shift (pfile
, a
, unsignedp
, b
)
626 unsigned HOST_WIDEST_INT b
;
628 if (b
>= HOST_BITS_PER_WIDEST_INT
)
630 if (! unsignedp
&& a
!= 0)
631 integer_overflow (pfile
);
635 return (unsigned HOST_WIDEST_INT
) a
<< b
;
638 HOST_WIDEST_INT l
= a
<< b
;
640 integer_overflow (pfile
);
645 static HOST_WIDEST_INT
646 right_shift (pfile
, a
, unsignedp
, b
)
647 cpp_reader
*pfile ATTRIBUTE_UNUSED
;
650 unsigned HOST_WIDEST_INT b
;
652 if (b
>= HOST_BITS_PER_WIDEST_INT
)
653 return unsignedp
? 0 : a
>> (HOST_BITS_PER_WIDEST_INT
- 1);
655 return (unsigned HOST_WIDEST_INT
) a
>> b
;
660 /* These priorities are all even, so we can handle associatively. */
661 #define PAREN_INNER_PRIO 0
663 #define COND_PRIO (COMMA_PRIO+2)
664 #define OROR_PRIO (COND_PRIO+2)
665 #define ANDAND_PRIO (OROR_PRIO+2)
666 #define OR_PRIO (ANDAND_PRIO+2)
667 #define XOR_PRIO (OR_PRIO+2)
668 #define AND_PRIO (XOR_PRIO+2)
669 #define EQUAL_PRIO (AND_PRIO+2)
670 #define LESS_PRIO (EQUAL_PRIO+2)
671 #define SHIFT_PRIO (LESS_PRIO+2)
672 #define PLUS_PRIO (SHIFT_PRIO+2)
673 #define MUL_PRIO (PLUS_PRIO+2)
674 #define UNARY_PRIO (MUL_PRIO+2)
675 #define PAREN_OUTER_PRIO (UNARY_PRIO+2)
677 #define COMPARE(OP) \
679 top->value = (unsigned1 || unsigned2) \
680 ? (unsigned HOST_WIDEST_INT) v1 OP (unsigned HOST_WIDEST_INT) v2 : (v1 OP v2)
682 /* Parse and evaluate a C expression, reading from PFILE.
683 Returns the value of the expression. */
686 cpp_parse_expr (pfile
)
689 /* The implementation is an operator precedence parser,
690 i.e. a bottom-up parser, using a stack for not-yet-reduced tokens.
692 The stack base is 'stack', and the current stack pointer is 'top'.
693 There is a stack element for each operator (only),
694 and the most recently pushed operator is 'top->op'.
695 An operand (value) is stored in the 'value' field of the stack
696 element of the operator that precedes it.
697 In that case the 'flags' field has the HAVE_VALUE flag set. */
699 #define INIT_STACK_SIZE 20
700 struct operation init_stack
[INIT_STACK_SIZE
];
701 struct operation
*stack
= init_stack
;
702 struct operation
*limit
= stack
+ INIT_STACK_SIZE
;
703 register struct operation
*top
= stack
;
704 int lprio
, rprio
= 0;
705 int skip_evaluation
= 0;
715 op
= cpp_lex (pfile
, skip_evaluation
);
717 /* See if the token is an operand, in which case go to set_value.
718 If the token is an operator, figure out its left and right
719 priorities, and then goto maybe_reduce. */
724 cpp_fatal (pfile
, "internal error: cpp_lex returns a NAME");
727 top
->value
= op
.value
;
728 top
->unsignedp
= op
.unsignedp
;
731 lprio
= 0; goto maybe_reduce
;
733 /* Is this correct if unary ? FIXME */
734 flags
= RIGHT_OPERAND_REQUIRED
;
735 lprio
= PLUS_PRIO
; rprio
= lprio
+ 1; goto maybe_reduce
;
737 flags
= RIGHT_OPERAND_REQUIRED
;
738 rprio
= UNARY_PRIO
; lprio
= rprio
+ 1; goto maybe_reduce
;
739 case '*': case '/': case '%':
740 lprio
= MUL_PRIO
; goto binop
;
741 case '<': case '>': case LEQ
: case GEQ
:
742 lprio
= LESS_PRIO
; goto binop
;
743 case EQUAL
: case NOTEQUAL
:
744 lprio
= EQUAL_PRIO
; goto binop
;
746 lprio
= SHIFT_PRIO
; goto binop
;
747 case '&': lprio
= AND_PRIO
; goto binop
;
748 case '^': lprio
= XOR_PRIO
; goto binop
;
749 case '|': lprio
= OR_PRIO
; goto binop
;
750 case ANDAND
: lprio
= ANDAND_PRIO
; goto binop
;
751 case OROR
: lprio
= OROR_PRIO
; goto binop
;
753 lprio
= COMMA_PRIO
; goto binop
;
755 lprio
= PAREN_OUTER_PRIO
; rprio
= PAREN_INNER_PRIO
;
758 lprio
= PAREN_INNER_PRIO
; rprio
= PAREN_OUTER_PRIO
;
761 lprio
= COND_PRIO
; rprio
= COND_PRIO
;
764 lprio
= COND_PRIO
+ 1; rprio
= COND_PRIO
;
769 flags
= LEFT_OPERAND_REQUIRED
|RIGHT_OPERAND_REQUIRED
;
773 cpp_error (pfile
, "invalid character in #if");
778 /* Push a value onto the stack. */
779 if (top
->flags
& HAVE_VALUE
)
781 cpp_error (pfile
, "syntax error in #if");
784 top
->flags
|= HAVE_VALUE
;
788 /* Push an operator, and check if we can reduce now. */
789 while (top
->rprio
> lprio
)
791 HOST_WIDEST_INT v1
= top
[-1].value
, v2
= top
[0].value
;
792 int unsigned1
= top
[-1].unsignedp
, unsigned2
= top
[0].unsignedp
;
794 if ((top
[1].flags
& LEFT_OPERAND_REQUIRED
)
795 && ! (top
[0].flags
& HAVE_VALUE
))
797 cpp_error (pfile
, "syntax error - missing left operand");
800 if ((top
[1].flags
& RIGHT_OPERAND_REQUIRED
)
801 && ! (top
[1].flags
& HAVE_VALUE
))
803 cpp_error (pfile
, "syntax error - missing right operand");
806 /* top[0].value = (top[1].op)(v1, v2);*/
810 if (!(top
->flags
& HAVE_VALUE
))
813 top
->unsignedp
= unsigned2
;
814 top
->flags
|= HAVE_VALUE
;
818 top
->value
= v1
+ v2
;
819 top
->unsignedp
= unsigned1
|| unsigned2
;
820 if (! top
->unsignedp
&& ! skip_evaluation
821 && ! possible_sum_sign (v1
, v2
, top
->value
))
822 integer_overflow (pfile
);
826 if (!(top
->flags
& HAVE_VALUE
))
829 if (!skip_evaluation
&& (top
->value
& v2
) < 0 && !unsigned2
)
830 integer_overflow (pfile
);
831 top
->unsignedp
= unsigned2
;
832 top
->flags
|= HAVE_VALUE
;
836 top
->value
= v1
- v2
;
837 top
->unsignedp
= unsigned1
|| unsigned2
;
838 if (! top
->unsignedp
&& ! skip_evaluation
839 && ! possible_sum_sign (top
->value
, v2
, v1
))
840 integer_overflow (pfile
);
844 top
->unsignedp
= unsigned1
|| unsigned2
;
846 top
->value
= (unsigned HOST_WIDEST_INT
) v1
* v2
;
847 else if (!skip_evaluation
)
849 top
->value
= v1
* v2
;
851 && (top
->value
/ v1
!= v2
852 || (top
->value
& v1
& v2
) < 0))
853 integer_overflow (pfile
);
861 cpp_error (pfile
, "division by zero in #if");
864 top
->unsignedp
= unsigned1
|| unsigned2
;
866 top
->value
= (unsigned HOST_WIDEST_INT
) v1
/ v2
;
869 top
->value
= v1
/ v2
;
870 if ((top
->value
& v1
& v2
) < 0)
871 integer_overflow (pfile
);
879 cpp_error (pfile
, "division by zero in #if");
882 top
->unsignedp
= unsigned1
|| unsigned2
;
884 top
->value
= (unsigned HOST_WIDEST_INT
) v1
% v2
;
886 top
->value
= v1
% v2
;
889 if (top
->flags
& HAVE_VALUE
)
891 cpp_error (pfile
, "syntax error");
896 top
->flags
|= HAVE_VALUE
;
899 if (top
->flags
& HAVE_VALUE
)
901 cpp_error (pfile
, "syntax error");
905 top
->unsignedp
= unsigned2
;
906 top
->flags
|= HAVE_VALUE
;
908 case '<': COMPARE(<); break;
909 case '>': COMPARE(>); break;
910 case LEQ
: COMPARE(<=); break;
911 case GEQ
: COMPARE(>=); break;
913 top
->value
= (v1
== v2
);
917 top
->value
= (v1
!= v2
);
923 top
->unsignedp
= unsigned1
;
924 if (v2
< 0 && ! unsigned2
)
925 top
->value
= right_shift (pfile
, v1
, unsigned1
, -v2
);
927 top
->value
= left_shift (pfile
, v1
, unsigned1
, v2
);
932 top
->unsignedp
= unsigned1
;
933 if (v2
< 0 && ! unsigned2
)
934 top
->value
= left_shift (pfile
, v1
, unsigned1
, -v2
);
936 top
->value
= right_shift (pfile
, v1
, unsigned1
, v2
);
938 #define LOGICAL(OP) \
939 top->value = v1 OP v2;\
940 top->unsignedp = unsigned1 || unsigned2;
941 case '&': LOGICAL(&); break;
942 case '^': LOGICAL(^); break;
943 case '|': LOGICAL(|); break;
945 top
->value
= v1
&& v2
; top
->unsignedp
= 0;
946 if (!v1
) skip_evaluation
--;
949 top
->value
= v1
|| v2
; top
->unsignedp
= 0;
950 if (v1
) skip_evaluation
--;
953 if (CPP_PEDANTIC (pfile
))
954 cpp_pedwarn (pfile
, "comma operator in operand of `#if'");
956 top
->unsignedp
= unsigned2
;
959 cpp_error (pfile
, "syntax error in #if");
962 if (top
[0].op
!= '?')
965 "syntax error ':' without preceding '?'");
968 else if (! (top
[1].flags
& HAVE_VALUE
)
969 || !(top
[-1].flags
& HAVE_VALUE
)
970 || !(top
[0].flags
& HAVE_VALUE
))
972 cpp_error (pfile
, "bad syntax for ?: operator");
978 if (top
->value
) skip_evaluation
--;
979 top
->value
= top
->value
? v1
: v2
;
980 top
->unsignedp
= unsigned1
|| unsigned2
;
984 if ((top
[1].flags
& HAVE_VALUE
)
985 || ! (top
[0].flags
& HAVE_VALUE
)
987 || (top
[-1].flags
& HAVE_VALUE
))
989 cpp_error (pfile
, "mismatched parentheses in #if");
996 top
->unsignedp
= unsigned1
;
997 top
->flags
|= HAVE_VALUE
;
1002 (top
[1].op
>= ' ' && top
[1].op
<= '~'
1003 ? "unimplemented operator '%c'\n"
1004 : "unimplemented operator '\\%03o'\n"),
1011 cpp_error (pfile
, "internal error in #if expression");
1012 if (stack
!= init_stack
)
1018 /* Check for and handle stack overflow. */
1021 struct operation
*new_stack
;
1022 int old_size
= (char *) limit
- (char *) stack
;
1023 int new_size
= 2 * old_size
;
1024 if (stack
!= init_stack
)
1025 new_stack
= (struct operation
*) xrealloc (stack
, new_size
);
1028 new_stack
= (struct operation
*) xmalloc (new_size
);
1029 bcopy ((char *) stack
, (char *) new_stack
, old_size
);
1032 top
= (struct operation
*) ((char *) new_stack
+ old_size
);
1033 limit
= (struct operation
*) ((char *) new_stack
+ new_size
);
1039 if ((op
.op
== OROR
&& top
[-1].value
)
1040 || (op
.op
== ANDAND
&& !top
[-1].value
)
1041 || (op
.op
== '?' && !top
[-1].value
))
1045 else if (op
.op
== ':')
1047 if (top
[-2].value
) /* Was condition true? */
1054 if (stack
!= init_stack
)
1056 skip_rest_of_line (pfile
);