Annotation of OpenXM_contrib2/windows/mcpp/eval.c, Revision 1.1
1.1 ! ohara 1: /* $OpenXM$ */
! 2: /*-
! 3: * Copyright (c) 1998, 2002-2008 Kiyoshi Matsui <kmatsui@t3.rim.or.jp>
! 4: * All rights reserved.
! 5: *
! 6: * Some parts of this code are derived from the public domain software
! 7: * DECUS cpp (1984,1985) written by Martin Minow.
! 8: *
! 9: * Redistribution and use in source and binary forms, with or without
! 10: * modification, are permitted provided that the following conditions
! 11: * are met:
! 12: * 1. Redistributions of source code must retain the above copyright
! 13: * notice, this list of conditions and the following disclaimer.
! 14: * 2. Redistributions in binary form must reproduce the above copyright
! 15: * notice, this list of conditions and the following disclaimer in the
! 16: * documentation and/or other materials provided with the distribution.
! 17: *
! 18: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
! 19: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 20: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 21: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
! 22: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 23: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 24: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 25: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 26: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 27: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 28: * SUCH DAMAGE.
! 29: */
! 30:
! 31: /*
! 32: * E V A L . C
! 33: * E x p r e s s i o n E v a l u a t i o n
! 34: *
! 35: * The routines to evaluate #if expression are placed here.
! 36: * Some routines are used also to evaluate the value of numerical tokens.
! 37: */
! 38:
! 39: #if PREPROCESSED
! 40: #include "mcpp.H"
! 41: #else
! 42: #include "system.H"
! 43: #include "internal.H"
! 44: #endif
! 45:
! 46: typedef struct optab {
! 47: char op; /* Operator */
! 48: char prec; /* Its precedence */
! 49: char skip; /* Short-circuit: non-0 to skip */
! 50: } OPTAB;
! 51:
! 52: static int eval_lex( void);
! 53: /* Get type and value of token */
! 54: static int chk_ops( void);
! 55: /* Check identifier-like ops */
! 56: static VAL_SIGN * eval_char( char * const token);
! 57: /* Evaluate character constant */
! 58: static expr_t eval_one( char ** seq_pp, int wide, int mbits, int * ucn8);
! 59: /* Evaluate a character */
! 60: static VAL_SIGN * eval_eval( VAL_SIGN * valp, int op);
! 61: /* Entry to #if arithmetic */
! 62: static expr_t eval_signed( VAL_SIGN ** valpp, expr_t v1, expr_t v2, int op);
! 63: /* Do signed arithmetic of expr.*/
! 64: static expr_t eval_unsigned( VAL_SIGN ** valpp, uexpr_t v1u, uexpr_t v2u
! 65: , int op);
! 66: /* Do unsigned arithmetic */
! 67: static void overflow( const char * op_name, VAL_SIGN ** valpp
! 68: , int ll_overflow);
! 69: /* Diagnose overflow of expr. */
! 70: static int do_sizeof( void);
! 71: /* Evaluate sizeof (type) */
! 72: static int look_type( int typecode);
! 73: /* Look for type of the name */
! 74: static void dump_val( const char * msg, const VAL_SIGN * valp);
! 75: /* Print value of an operand */
! 76: static void dump_stack( const OPTAB * opstack, const OPTAB * opp
! 77: , const VAL_SIGN * value, const VAL_SIGN * valp);
! 78: /* Print stacked operators */
! 79:
! 80: /* For debug and error messages. */
! 81: static const char * const opname[ OP_END + 1] = {
! 82: "end of expression", "val", "(",
! 83: "unary +", "unary -", "~", "!",
! 84: "*", "/", "%",
! 85: "+", "-", "<<", ">>",
! 86: "<", "<=", ">", ">=", "==", "!=",
! 87: "&", "^", "|", "&&", "||",
! 88: "?", ":",
! 89: ")", "(none)"
! 90: };
! 91:
! 92: /*
! 93: * opdope[] has the operator (and operand) precedence:
! 94: * Bits
! 95: * 7 Unused (so the value is always positive)
! 96: * 6-2 Precedence (0000 .. 0174)
! 97: * 1-0 Binary op. flags:
! 98: * 10 The next binop flag (binop should/not follow).
! 99: * 01 The binop flag (should be set/cleared when this op is seen).
! 100: * Note: next binop
! 101: * value 1 0 Value doesn't follow value.
! 102: * Binop, ), END should follow value, value or unop doesn't.
! 103: * ( 0 0 ( doesn't follow value. Value follows.
! 104: * unary 0 0 Unop doesn't follow value. Value follows.
! 105: * binary 0 1 Binary op follows value. Value follows.
! 106: * ) 1 1 ) follows value. Binop, ), END follows.
! 107: * END 0 1 END follows value, doesn't follow ops.
! 108: */
! 109:
! 110: static const char opdope[ OP_END + 1] = {
! 111: 0001, /* End of expression */
! 112: 0002, 0170, /* VAL (constant), LPA */
! 113: /* Unary op's */
! 114: 0160, 0160, 0160, 0160, /* PLU, NEG, COM, NOT */
! 115: /* Binary op's */
! 116: 0151, 0151, 0151, /* MUL, DIV, MOD, */
! 117: 0141, 0141, 0131, 0131, /* ADD, SUB, SL, SR */
! 118: 0121, 0121, 0121, 0121, 0111, 0111, /* LT, LE, GT, GE, EQ, NE */
! 119: 0101, 0071, 0061, 0051, 0041, /* AND, XOR, OR, ANA, ORO */
! 120: 0031, 0031, /* QUE, COL */
! 121: /* Parens */
! 122: 0013, 0023 /* RPA, END */
! 123: };
! 124: /*
! 125: * OP_QUE, OP_RPA and unary operators have alternate precedences:
! 126: */
! 127: #define OP_RPA_PREC 0013
! 128: #define OP_QUE_PREC 0024 /* From right to left grouping */
! 129: #define OP_UNOP_PREC 0154 /* ditto */
! 130:
! 131: /*
! 132: * S_ANDOR and S_QUEST signal "short-circuit" boolean evaluation, so that
! 133: * #if FOO != 0 && 10 / FOO ...
! 134: * doesn't generate an error message. They are stored in optab.skip.
! 135: */
! 136: #define S_ANDOR 2
! 137: #define S_QUEST 1
! 138:
! 139: static VAL_SIGN ev; /* Current value and signedness */
! 140: static int skip = 0; /* 3-way signal of skipping expr*/
! 141: static const char * const non_eval
! 142: = " (in non-evaluated sub-expression)"; /* _W8_ */
! 143:
! 144: #if HAVE_LONG_LONG && COMPILER == INDEPENDENT
! 145: static int w_level = 1; /* warn_level at overflow of long */
! 146: #else
! 147: static int w_level = 2;
! 148: #endif
! 149:
! 150: /*
! 151: * In KR and OLD_PREP modes.
! 152: * Define bits for the basic types and their adjectives.
! 153: */
! 154: #define T_CHAR 1
! 155: #define T_INT 2
! 156: #define T_FLOAT 4
! 157: #define T_DOUBLE 8
! 158: #define T_LONGDOUBLE 16
! 159: #define T_SHORT 32
! 160: #define T_LONG 64
! 161: #define T_LONGLONG 128
! 162: #define T_SIGNED 256
! 163: #define T_UNSIGNED 512
! 164: #define T_PTR 1024 /* Pointer to data objects */
! 165: #define T_FPTR 2048 /* Pointer to functions */
! 166:
! 167: /*
! 168: * The SIZES structure is used to store the values for #if sizeof.
! 169: */
! 170: typedef struct sizes {
! 171: int bits; /* If this bit is set, */
! 172: int size; /* this is the datum size value */
! 173: int psize; /* this is the pointer size */
! 174: } SIZES;
! 175:
! 176: /*
! 177: * S_CHAR, etc. define the sizeof the basic TARGET machine word types.
! 178: * By default, sizes are set to the values for the HOST computer. If
! 179: * this is inappropriate, see those tables for details on what to change.
! 180: * Also, if you have a machine where sizeof (signed int) differs from
! 181: * sizeof (unsigned int), you will have to edit those tables and code in
! 182: * eval.c.
! 183: * Note: sizeof in #if expression is disallowed by Standard.
! 184: */
! 185:
! 186: #define S_CHAR (sizeof (char))
! 187: #define S_SINT (sizeof (short int))
! 188: #define S_INT (sizeof (int))
! 189: #define S_LINT (sizeof (long int))
! 190: #define S_FLOAT (sizeof (float))
! 191: #define S_DOUBLE (sizeof (double))
! 192: #define S_PCHAR (sizeof (char *))
! 193: #define S_PSINT (sizeof (short int *))
! 194: #define S_PINT (sizeof (int *))
! 195: #define S_PLINT (sizeof (long int *))
! 196: #define S_PFLOAT (sizeof (float *))
! 197: #define S_PDOUBLE (sizeof (double *))
! 198: #define S_PFPTR (sizeof (int (*)()))
! 199: #if HAVE_LONG_LONG
! 200: #if (HOST_COMPILER == BORLANDC) \
! 201: || (HOST_COMPILER == MSC && defined(_MSC_VER) && (_MSC_VER < 1300))
! 202: #define S_LLINT (sizeof (__int64))
! 203: #define S_PLLINT (sizeof (__int64 *))
! 204: #else
! 205: #define S_LLINT (sizeof (long long int))
! 206: #define S_PLLINT (sizeof (long long int *))
! 207: #endif
! 208: #endif
! 209: #define S_LDOUBLE (sizeof (long double))
! 210: #define S_PLDOUBLE (sizeof (long double *))
! 211:
! 212: typedef struct types {
! 213: int type; /* This is the bits for types */
! 214: char * token_name; /* this is the token word */
! 215: int excluded; /* but these aren't legal here. */
! 216: } TYPES;
! 217:
! 218: #define ANYSIGN (T_SIGNED | T_UNSIGNED)
! 219: #define ANYFLOAT (T_FLOAT | T_DOUBLE | T_LONGDOUBLE)
! 220: #if HAVE_LONG_LONG
! 221: #define ANYINT (T_CHAR | T_SHORT | T_INT | T_LONG | T_LONGLONG)
! 222: #else
! 223: #define ANYINT (T_CHAR | T_SHORT | T_INT | T_LONG)
! 224: #endif
! 225:
! 226: static const TYPES basic_types[] = {
! 227: { T_CHAR, "char", ANYFLOAT | ANYINT },
! 228: { T_SHORT, "short", ANYFLOAT | ANYINT },
! 229: { T_INT, "int", ANYFLOAT | T_CHAR | T_INT },
! 230: { T_LONG, "long", ANYFLOAT | ANYINT },
! 231: #if HAVE_LONG_LONG
! 232: #if HOST_COMPILER == BORLANDC
! 233: { T_LONGLONG, "__int64", ANYFLOAT | ANYINT },
! 234: #else
! 235: { T_LONGLONG, "long long", ANYFLOAT | ANYINT },
! 236: #endif
! 237: #endif
! 238: { T_FLOAT, "float", ANYFLOAT | ANYINT | ANYSIGN },
! 239: { T_DOUBLE, "double", ANYFLOAT | ANYINT | ANYSIGN },
! 240: { T_LONGDOUBLE, "long double", ANYFLOAT | ANYINT | ANYSIGN },
! 241: { T_SIGNED, "signed", ANYFLOAT | ANYINT | ANYSIGN },
! 242: { T_UNSIGNED, "unsigned", ANYFLOAT | ANYINT | ANYSIGN },
! 243: { 0, NULL, 0 } /* Signal end */
! 244: };
! 245:
! 246: /*
! 247: * In this table, T_FPTR (pointer to function) should be placed last.
! 248: */
! 249: static const SIZES size_table[] = {
! 250: { T_CHAR, S_CHAR, S_PCHAR }, /* char */
! 251: { T_SHORT, S_SINT, S_PSINT }, /* short int */
! 252: { T_INT, S_INT, S_PINT }, /* int */
! 253: { T_LONG, S_LINT, S_PLINT }, /* long */
! 254: #if HAVE_LONG_LONG
! 255: { T_LONGLONG, S_LLINT, S_PLLINT }, /* long long */
! 256: #endif
! 257: { T_FLOAT, S_FLOAT, S_PFLOAT }, /* float */
! 258: { T_DOUBLE, S_DOUBLE, S_PDOUBLE }, /* double */
! 259: { T_LONGDOUBLE, S_LDOUBLE, S_PLDOUBLE }, /* long double */
! 260: { T_FPTR, 0, S_PFPTR }, /* int (*()) */
! 261: { 0, 0, 0 } /* End of table */
! 262: };
! 263:
! 264: #define is_binary(op) (FIRST_BINOP <= op && op <= LAST_BINOP)
! 265: #define is_unary(op) (FIRST_UNOP <= op && op <= LAST_UNOP)
! 266:
! 267:
! 268: #if MCPP_LIB
! 269: void init_eval( void)
! 270: {
! 271: skip = 0;
! 272: }
! 273: #endif
! 274:
! 275: expr_t eval_if( void)
! 276: /*
! 277: * Evaluate a #if expression. Straight-forward operator precedence.
! 278: * This is called from directive() on encountering an #if directive.
! 279: * It calls the following routines:
! 280: * eval_lex() Lexical analyser -- returns the type and value of
! 281: * the next input token.
! 282: * eval_eval() Evaluates the current operator, given the values on the
! 283: * value stack. Returns a pointer to the (new) value stack.
! 284: */
! 285: {
! 286: VAL_SIGN value[ NEXP * 2 + 1]; /* Value stack */
! 287: OPTAB opstack[ NEXP * 3 + 1]; /* Operator stack */
! 288: int parens = 0; /* Nesting levels of (, ) */
! 289: int prec; /* Operator precedence */
! 290: int binop = 0; /* Set if binary op. needed */
! 291: int op1; /* Operator from stack */
! 292: int skip_cur; /* For short-circuit testing */
! 293: VAL_SIGN * valp = value; /* -> Value and signedness */
! 294: OPTAB * opp = opstack; /* -> Operator stack */
! 295: int op; /* Current operator */
! 296:
! 297: opp->op = OP_END; /* Mark bottom of stack */
! 298: opp->prec = opdope[ OP_END]; /* And its precedence */
! 299: skip = skip_cur = opp->skip = 0; /* Not skipping now */
! 300:
! 301: while (1) {
! 302: if (mcpp_debug & EXPRESSION)
! 303: mcpp_fprintf( DBG
! 304: , "In eval loop skip = %d, binop = %d, line is: %s\n"
! 305: , opp->skip, binop, infile->bptr);
! 306: skip = opp->skip;
! 307: op = eval_lex();
! 308: skip = 0; /* Reset to be ready to return */
! 309: switch (op) {
! 310: case OP_SUB :
! 311: if (binop == 0)
! 312: op = OP_NEG; /* Unary minus */
! 313: break;
! 314: case OP_ADD :
! 315: if (binop == 0)
! 316: op = OP_PLU; /* Unary plus */
! 317: break;
! 318: case OP_FAIL:
! 319: return 0L; /* Token error */
! 320: }
! 321: if (mcpp_debug & EXPRESSION)
! 322: mcpp_fprintf( DBG
! 323: , "op = %s, opdope = %04o, binop = %d, skip = %d\n"
! 324: , opname[ op], opdope[ op], binop, opp->skip);
! 325: if (op == VAL) { /* Value? */
! 326: if (binop != 0) { /* Binop is needed */
! 327: cerror( "Misplaced constant \"%s\"" /* _E_ */
! 328: , work_buf, 0L, NULL);
! 329: return 0L;
! 330: } else if (& value[ NEXP * 2] <= valp) {
! 331: cerror( "More than %.0s%ld constants stacked at %s" /* _E_ */
! 332: , NULL, (long) (NEXP * 2 - 1), work_buf);
! 333: return 0L;
! 334: } else {
! 335: if (mcpp_debug & EXPRESSION) {
! 336: dump_val( "pushing ", &ev);
! 337: mcpp_fprintf( DBG, " onto value stack[%d]\n"
! 338: , (int)(valp - value));
! 339: }
! 340: valp->val = ev.val;
! 341: (valp++)->sign = ev.sign;
! 342: binop = 1; /* Binary operator or so should follow */
! 343: }
! 344: continue;
! 345: } /* Else operators */
! 346: prec = opdope[ op];
! 347: if (binop != (prec & 1)) {
! 348: if (op == OP_EOE)
! 349: cerror( "Unterminated expression" /* _E_ */
! 350: , NULL, 0L, NULL);
! 351: else
! 352: cerror( "Operator \"%s\" in incorrect context" /* _E_ */
! 353: , opname[ op], 0L, NULL);
! 354: return 0L;
! 355: }
! 356: binop = (prec & 2) >> 1; /* Binop should follow? */
! 357:
! 358: while (1) {
! 359: if (mcpp_debug & EXPRESSION)
! 360: mcpp_fprintf( DBG
! 361: , "op %s, prec %d, stacked op %s, prec %d, skip %d\n"
! 362: , opname[ op], prec, opname[ opp->op], opp->prec, opp->skip);
! 363:
! 364: /* Stack coming sub-expression of higher precedence. */
! 365: if (opp->prec < prec) {
! 366: if (op == OP_LPA) {
! 367: prec = OP_RPA_PREC;
! 368: if (standard && (warn_level & 4)
! 369: && ++parens == std_limits.exp_nest + 1)
! 370: cwarn(
! 371: "More than %.0s%ld nesting of parens" /* _W4_ */
! 372: , NULL, (long) std_limits.exp_nest, NULL);
! 373: } else if (op == OP_QUE) {
! 374: prec = OP_QUE_PREC;
! 375: } else if (is_unary( op)) {
! 376: prec = OP_UNOP_PREC;
! 377: }
! 378: op1 = opp->skip; /* Save skip for test */
! 379: /*
! 380: * Push operator onto operator stack.
! 381: */
! 382: opp++;
! 383: if (& opstack[ NEXP * 3] <= opp) {
! 384: cerror(
! 385: "More than %.0s%ld operators and parens stacked at %s" /* _E_ */
! 386: , NULL, (long) (NEXP * 3 - 1), opname[ op]);
! 387: return 0L;
! 388: }
! 389: opp->op = op;
! 390: opp->prec = prec;
! 391: if (&value[0] < valp)
! 392: skip_cur = (valp[-1].val != 0L);
! 393: /* Short-circuit tester */
! 394: /*
! 395: * Do the short-circuit stuff here. Short-circuiting
! 396: * stops automagically when operators are evaluated.
! 397: */
! 398: if ((op == OP_ANA && ! skip_cur)
! 399: || (op == OP_ORO && skip_cur)) {
! 400: opp->skip = S_ANDOR; /* And/or skip starts */
! 401: if (skip_cur) /* Evaluate non-zero */
! 402: valp[-1].val = 1L; /* value to 1 */
! 403: } else if (op == OP_QUE) { /* Start of ?: operator */
! 404: opp->skip = (op1 & S_ANDOR) | (!skip_cur ? S_QUEST : 0);
! 405: } else if (op == OP_COL) { /* : inverts S_QUEST */
! 406: opp->skip = (op1 & S_ANDOR)
! 407: | (((op1 & S_QUEST) != 0) ? 0 : S_QUEST);
! 408: } else { /* Other operators leave*/
! 409: opp->skip = op1; /* skipping unchanged. */
! 410: }
! 411: if (mcpp_debug & EXPRESSION) {
! 412: mcpp_fprintf( DBG, "stacking %s, ", opname[ op]);
! 413: if (&value[0] < valp)
! 414: dump_val( "valp[-1].val == ", valp - 1);
! 415: mcpp_fprintf( DBG, " at %s\n", infile->bptr);
! 416: dump_stack( opstack, opp, value, valp);
! 417: }
! 418: break;
! 419: }
! 420:
! 421: /*
! 422: * Coming sub-expression is of lower precedence.
! 423: * Evaluate stacked sub-expression.
! 424: * Pop operator from operator stack and evaluate it.
! 425: * End of stack and '(', ')' are specials.
! 426: */
! 427: skip_cur = opp->skip; /* Remember skip value */
! 428: switch ((op1 = opp->op)) { /* Look at stacked op */
! 429: case OP_END: /* Stack end marker */
! 430: if (op == OP_RPA) { /* No corresponding ( */
! 431: cerror( "Excessive \")\"", NULL, 0L, NULL); /* _E_ */
! 432: return 0L;
! 433: }
! 434: if (op == OP_EOE)
! 435: return valp[-1].val; /* Finished ok. */
! 436: break;
! 437: case OP_LPA: /* ( on stack */
! 438: if (op != OP_RPA) { /* Matches ) on input? */
! 439: cerror( "Missing \")\"", NULL, 0L, NULL); /* _E_ */
! 440: return 0L;
! 441: }
! 442: opp--; /* Unstack it */
! 443: parens--; /* Count down nest level*/
! 444: break;
! 445: case OP_QUE: /* Evaluate true expr. */
! 446: break;
! 447: case OP_COL: /* : on stack */
! 448: opp--; /* Unstack : */
! 449: if (opp->op != OP_QUE) { /* Matches ? on stack? */
! 450: cerror(
! 451: "Misplaced \":\", previous operator is \"%s\"" /* _E_ */
! 452: , opname[opp->op], 0L, NULL);
! 453: return 0L;
! 454: }
! 455: /* Evaluate op1. Fall through */
! 456: default: /* Others: */
! 457: opp--; /* Unstack the operator */
! 458: if (mcpp_debug & EXPRESSION) {
! 459: mcpp_fprintf( DBG, "Stack before evaluation of %s\n"
! 460: , opname[ op1]);
! 461: dump_stack( opstack, opp, value, valp);
! 462: }
! 463: if (op1 == OP_COL)
! 464: skip = 0;
! 465: else
! 466: skip = skip_cur;
! 467: valp = eval_eval( valp, op1);
! 468: if (valp->sign == VAL_ERROR)
! 469: return 0L; /* Out of range or divide by 0 */
! 470: valp++;
! 471: skip = 0;
! 472: if (mcpp_debug & EXPRESSION) {
! 473: mcpp_fprintf( DBG, "Stack after evaluation\n");
! 474: dump_stack( opstack, opp, value, valp);
! 475: }
! 476: } /* op1 switch end */
! 477:
! 478: if (op1 == OP_END || op1 == OP_LPA || op1 == OP_QUE)
! 479: break; /* Read another op. */
! 480: } /* Stack unwind loop */
! 481:
! 482: }
! 483:
! 484: return 0L; /* Never reach here */
! 485: }
! 486:
! 487: static int eval_lex( void)
! 488: /*
! 489: * Return next operator or constant to evaluate. Called from eval_if(). It
! 490: * calls a special-purpose routines for character constants and numeric values:
! 491: * eval_char() called to evaluate 'x'
! 492: * eval_num() called to evaluate numbers
! 493: * C++98 treats 11 identifier-like tokens as operators.
! 494: * POST_STD forbids character constants in #if expression.
! 495: */
! 496: {
! 497: int c1;
! 498: VAL_SIGN * valp;
! 499: int warn = ! skip || (warn_level & 8);
! 500: int token_type;
! 501: int c;
! 502:
! 503: ev.sign = SIGNED; /* Default signedness */
! 504: ev.val = 0L; /* Default value (on error or 0 value) */
! 505: in_if = ! skip; /* Inform to expand_macro() that the macro is */
! 506: /* in #if line and not skipped expression. */
! 507: c = skip_ws();
! 508: if (c == '\n') {
! 509: unget_ch();
! 510: return OP_EOE; /* End of expression */
! 511: }
! 512: token_type = get_unexpandable( c, warn);
! 513: if (standard && macro_line == MACRO_ERROR)
! 514: return OP_FAIL; /* Unterminated macro call */
! 515: if (token_type == NO_TOKEN)
! 516: return OP_EOE; /* Only macro(s) expanding to 0-token */
! 517:
! 518: switch (token_type) {
! 519: case NAM:
! 520: if (standard && str_eq( identifier, "defined")) { /* defined name */
! 521: c1 = c = skip_ws();
! 522: if (c == '(') /* Allow defined (name) */
! 523: c = skip_ws();
! 524: if (scan_token( c, (workp = work_buf, &workp), work_end) == NAM) {
! 525: DEFBUF * defp = look_id( identifier);
! 526: if (warn) {
! 527: ev.val = (defp != NULL);
! 528: if ((mcpp_debug & MACRO_CALL) && ! skip && defp)
! 529: /* Annotate if the macro is in non-skipped expr. */
! 530: mcpp_fprintf( OUT, "/*%s*/", defp->name);
! 531: }
! 532: if (c1 != '(' || skip_ws() == ')') /* Balanced ? */
! 533: return VAL; /* Parsed ok */
! 534: }
! 535: cerror( "Bad defined syntax: %s" /* _E_ */
! 536: , infile->fp ? "" : infile->buffer, 0L, NULL);
! 537: break;
! 538: } else if (cplus_val) {
! 539: if (str_eq( identifier, "true")) {
! 540: ev.val = 1L;
! 541: return VAL;
! 542: } else if (str_eq( identifier, "false")) {
! 543: ev.val = 0L;
! 544: return VAL;
! 545: } else if (mcpp_mode != POST_STD
! 546: && (openum = id_operator( identifier)) != 0) {
! 547: /* Identifier-like operator in C++98 */
! 548: strcpy( work_buf, identifier);
! 549: return chk_ops();
! 550: }
! 551: } else if (! standard && str_eq( identifier, "sizeof")) {
! 552: /* sizeof hackery */
! 553: return do_sizeof(); /* Gets own routine */
! 554: }
! 555: /*
! 556: * The ANSI C Standard says that an undefined symbol
! 557: * in an #if has the value zero. We are a bit pickier,
! 558: * warning except where the programmer was careful to write
! 559: * #if defined(foo) ? foo : 0
! 560: */
! 561: if ((! skip && (warn_level & 4)) || (skip && (warn_level & 8)))
! 562: cwarn( "Undefined symbol \"%s\"%.0ld%s" /* _W4_ _W8_ */
! 563: , identifier, 0L, skip ? non_eval : ", evaluated to 0");
! 564: return VAL;
! 565: case CHR: /* Character constant */
! 566: case WCHR: /* Wide char constant */
! 567: if (mcpp_mode == POST_STD) {
! 568: cerror( "Can't use a character constant %s" /* _E_ */
! 569: , work_buf, 0L, NULL);
! 570: break;
! 571: }
! 572: valp = eval_char( work_buf); /* 'valp' points 'ev' */
! 573: if (valp->sign == VAL_ERROR)
! 574: break;
! 575: if (mcpp_debug & EXPRESSION) {
! 576: dump_val( "eval_char returns ", &ev);
! 577: mcpp_fputc( '\n', DBG);
! 578: }
! 579: return VAL; /* Return a value */
! 580: case STR: /* String literal */
! 581: case WSTR: /* Wide string literal */
! 582: cerror(
! 583: "Can't use a string literal %s", work_buf, 0L, NULL); /* _E_ */
! 584: break;
! 585: case NUM: /* Numbers are harder */
! 586: valp = eval_num( work_buf); /* 'valp' points 'ev' */
! 587: if (valp->sign == VAL_ERROR)
! 588: break;
! 589: if (mcpp_debug & EXPRESSION) {
! 590: dump_val( "eval_num returns ", &ev);
! 591: mcpp_fputc( '\n', DBG);
! 592: }
! 593: return VAL;
! 594: case OPE: /* Operator or punctuator */
! 595: return chk_ops();
! 596:
! 597: default: /* Total nonsense */
! 598: cerror( "Can't use the character %.0s0x%02lx" /* _E_ */
! 599: , NULL, (long) c, NULL);
! 600: break;
! 601: }
! 602:
! 603: return OP_FAIL; /* Any errors */
! 604: }
! 605:
! 606: static int chk_ops( void)
! 607: /*
! 608: * Check the operator.
! 609: * If it can't be used in #if expression return OP_FAIL
! 610: * else return openum.
! 611: */
! 612: {
! 613: switch (openum) {
! 614: case OP_STR: case OP_CAT: case OP_ELL:
! 615: case OP_1: case OP_2: case OP_3:
! 616: cerror( "Can't use the operator \"%s\"" /* _E_ */
! 617: , work_buf, 0L, NULL);
! 618: return OP_FAIL;
! 619: default:
! 620: return openum;
! 621: }
! 622: }
! 623:
! 624: static int do_sizeof( void)
! 625: /*
! 626: * Process the sizeof (basic type) operation in an #if string.
! 627: * Sets ev.val to the size and returns
! 628: * VAL success
! 629: * OP_FAIL bad parse or something.
! 630: * This routine is never called in STD and POST_STD mode.
! 631: */
! 632: {
! 633: const char * const no_type = "sizeof: No type specified"; /* _E_ */
! 634: int warn = ! skip || (warn_level & 8);
! 635: int type_end = FALSE;
! 636: int typecode = 0;
! 637: int token_type = NO_TOKEN;
! 638: const SIZES * sizp = NULL;
! 639:
! 640: if (get_unexpandable( skip_ws(), warn) != OPE || openum != OP_LPA)
! 641: goto no_good; /* Not '(' */
! 642:
! 643: /*
! 644: * Scan off the tokens.
! 645: */
! 646:
! 647: while (! type_end) {
! 648: token_type = get_unexpandable( skip_ws(), warn);
! 649: /* Get next token expanding macros */
! 650: switch (token_type) {
! 651: case OPE:
! 652: if (openum == OP_LPA) { /* thing (*)() func ptr */
! 653: if (get_unexpandable( skip_ws(), warn) == OPE
! 654: && openum == OP_MUL
! 655: && get_unexpandable( skip_ws(), warn) == OPE
! 656: && openum == OP_RPA) { /* (*) */
! 657: if (get_unexpandable( skip_ws(), warn) != OPE
! 658: || openum != OP_LPA
! 659: || get_unexpandable( skip_ws(), warn) != OPE
! 660: || openum != OP_RPA) /* Not () */
! 661: goto no_good;
! 662: typecode |= T_FPTR; /* Function pointer */
! 663: } else { /* Junk is an error */
! 664: goto no_good;
! 665: }
! 666: } else { /* '*' or ')' */
! 667: type_end = TRUE;
! 668: }
! 669: break;
! 670: case NAM: /* Look for type comb. */
! 671: if ((typecode = look_type( typecode)) == 0)
! 672: return OP_FAIL; /* Illegal type or comb.*/
! 673: break;
! 674: default: goto no_good; /* Illegal token */
! 675: }
! 676: } /* End of while */
! 677:
! 678: /*
! 679: * We are at the end of the type scan. Chew off '*' if necessary.
! 680: */
! 681: if (token_type == OPE) {
! 682: if (openum == OP_MUL) { /* '*' */
! 683: typecode |= T_PTR;
! 684: if (get_unexpandable( skip_ws(), warn) != OPE)
! 685: goto no_good;
! 686: }
! 687: if (openum == OP_RPA) { /* ')' */
! 688: /*
! 689: * Last syntax check
! 690: * We assume that all function pointers are the same size:
! 691: * sizeof (int (*)()) == sizeof (float (*)())
! 692: * We assume that signed and unsigned don't change the size:
! 693: * sizeof (signed int) == sizeof (unsigned int)
! 694: */
! 695: if ((typecode & T_FPTR) != 0) { /* Function pointer */
! 696: typecode = T_FPTR | T_PTR;
! 697: } else { /* Var or var * datum */
! 698: typecode &= ~(T_SIGNED | T_UNSIGNED);
! 699: #if HAVE_LONG_LONG
! 700: if ((typecode & (T_SHORT | T_LONG | T_LONGLONG)) != 0)
! 701: #else
! 702: if ((typecode & (T_SHORT | T_LONG)) != 0)
! 703: #endif
! 704: typecode &= ~T_INT;
! 705: }
! 706: if ((typecode & ~T_PTR) == 0) {
! 707: cerror( no_type, NULL, 0L, NULL);
! 708: return OP_FAIL;
! 709: } else {
! 710: /*
! 711: * Exactly one bit (and possibly T_PTR) may be set.
! 712: */
! 713: for (sizp = size_table; sizp->bits != 0; sizp++) {
! 714: if ((typecode & ~T_PTR) == sizp->bits) {
! 715: ev.val = ((typecode & T_PTR) != 0)
! 716: ? sizp->psize : sizp->size;
! 717: break;
! 718: }
! 719: }
! 720: }
! 721: } else {
! 722: goto no_good;
! 723: }
! 724: } else {
! 725: goto no_good;
! 726: }
! 727:
! 728: if (mcpp_debug & EXPRESSION) {
! 729: if (sizp)
! 730: mcpp_fprintf( DBG,
! 731: "sizp->bits:0x%x sizp->size:0x%x sizp->psize:0x%x ev.val:0x%lx\n"
! 732: , sizp->bits, sizp->size, sizp->psize
! 733: , (unsigned long) ev.val);
! 734: }
! 735: return VAL;
! 736:
! 737: no_good:
! 738: unget_ch();
! 739: cerror( "sizeof: Syntax error", NULL, 0L, NULL); /* _E_ */
! 740: return OP_FAIL;
! 741: }
! 742:
! 743: static int look_type(
! 744: int typecode
! 745: )
! 746: {
! 747: const char * const unknown_type
! 748: = "sizeof: Unknown type \"%s\"%.0ld%s"; /* _E_ _W8_ */
! 749: const char * const illeg_comb
! 750: = "sizeof: Illegal type combination with \"%s\"%.0ld%s"; /* _E_ _W8_ */
! 751: int token_type;
! 752: const TYPES * tp;
! 753:
! 754: if (str_eq( identifier, "long")) {
! 755: if ((token_type
! 756: = get_unexpandable( skip_ws(), !skip || (warn_level & 8)))
! 757: == NO_TOKEN)
! 758: return typecode;
! 759: if (token_type == NAM) {
! 760: #if HAVE_LONG_LONG
! 761: if (str_eq( identifier, "long")) {
! 762: strcpy( work_buf, "long long");
! 763: goto basic;
! 764: }
! 765: #endif
! 766: if (str_eq( identifier, "double")) {
! 767: strcpy( work_buf, "long double");
! 768: goto basic;
! 769: }
! 770: }
! 771: unget_string( work_buf, NULL); /* Not long long */
! 772: strcpy( work_buf, "long"); /* nor long double */
! 773: }
! 774:
! 775: /*
! 776: * Look for this unexpandable token in basic_types.
! 777: */
! 778: basic:
! 779: for (tp = basic_types; tp->token_name != NULL; tp++) {
! 780: if (str_eq( work_buf, tp->token_name))
! 781: break;
! 782: }
! 783:
! 784: if (tp->token_name == NULL) {
! 785: if (! skip) {
! 786: cerror( unknown_type, work_buf, 0L, NULL);
! 787: return 0;
! 788: } else if (warn_level & 8) {
! 789: cwarn( unknown_type, work_buf, 0L, non_eval);
! 790: }
! 791: }
! 792: if ((typecode & tp->excluded) != 0) {
! 793: if (! skip) {
! 794: cerror( illeg_comb, work_buf, 0L, NULL);
! 795: return 0;
! 796: } else if (warn_level & 8) {
! 797: cwarn( illeg_comb, work_buf, 0L, non_eval);
! 798: }
! 799: }
! 800:
! 801: if (mcpp_debug & EXPRESSION) {
! 802: if (tp->token_name)
! 803: mcpp_fprintf( DBG,
! 804: "sizeof -- typecode:0x%x tp->token_name:\"%s\" tp->type:0x%x\n"
! 805: , typecode, tp->token_name, tp->type);
! 806: }
! 807: return typecode |= tp->type; /* Or in the type bit */
! 808: }
! 809:
! 810: VAL_SIGN * eval_num(
! 811: const char * nump /* Preprocessing number */
! 812: )
! 813: /*
! 814: * Evaluate number for #if lexical analysis. Note: eval_num recognizes
! 815: * the unsigned suffix, but only returns a signed expr_t value, and stores
! 816: * the signedness to ev.sign, which is set UNSIGNED (== unsigned) if the
! 817: * value is not in the range of positive (signed) expr_t.
! 818: */
! 819: {
! 820: const char * const not_integer = "Not an integer \"%s\""; /* _E_ */
! 821: const char * const out_of_range
! 822: = "Constant \"%s\"%.0ld%s is out of range"; /* _E_ _W1_ _W8_ */
! 823: expr_t value;
! 824: uexpr_t v, v1; /* unsigned long long or unsigned long */
! 825: int uflag = FALSE;
! 826: int lflag = FALSE;
! 827: int erange = FALSE;
! 828: int base;
! 829: int c, c1;
! 830: const char * cp = nump;
! 831: #if HAVE_LONG_LONG
! 832: const char * const out_of_range_long =
! 833: "Constant \"%s\"%.0ld%s is out of range " /* _E_ _W1_ _W2_ _W8_ */
! 834: "of (unsigned) long";
! 835: const char * const ll_suffix =
! 836: "LL suffix is used in other than C99 mode \"%s\"%.0ld%s"; /* _W1_ _W2_ _W8_ */
! 837: #if COMPILER == MSC || COMPILER == BORLANDC
! 838: const char * const i64_suffix =
! 839: "I64 suffix is used in other than C99 mode \"%s\"%.0ld%s"; /* _W2_ _W8_ */
! 840: #endif
! 841: int llflag = FALSE;
! 842: int erange_long = FALSE;
! 843: #endif
! 844:
! 845: ev.sign = SIGNED; /* Default signedness */
! 846: ev.val = 0L; /* Default value */
! 847: if ((char_type[ c = *cp++ & UCHARMAX] & DIG) == 0) /* Dot */
! 848: goto num_err;
! 849: if (c != '0') { /* Decimal */
! 850: base = 10;
! 851: } else if ((c = *cp++ & UCHARMAX) == 'x' || c == 'X') {
! 852: base = 16; /* Hexadecimal */
! 853: c = *cp++ & UCHARMAX;
! 854: } else if (c == EOS) { /* 0 */
! 855: return & ev;
! 856: } else { /* Octal or illegal */
! 857: base = 8;
! 858: }
! 859:
! 860: v = v1 = 0L;
! 861: for (;;) {
! 862: c1 = c;
! 863: if (isupper( c1))
! 864: c1 = tolower( c1);
! 865: if (c1 >= 'a')
! 866: c1 -= ('a' - 10);
! 867: else
! 868: c1 -= '0';
! 869: if (c1 < 0 || base <= c1)
! 870: break;
! 871: v1 *= base;
! 872: v1 += c1;
! 873: if (v1 / base < v) { /* Overflow */
! 874: if (! skip)
! 875: goto range_err;
! 876: else
! 877: erange = TRUE;
! 878: }
! 879: #if HAVE_LONG_LONG
! 880: if (! stdc3 && v1 > ULONGMAX)
! 881: /* Overflow of long or unsigned long */
! 882: erange_long = TRUE;
! 883: #endif
! 884: v = v1;
! 885: c = *cp++ & UCHARMAX;
! 886: }
! 887:
! 888: value = v;
! 889: while (c == 'u' || c == 'U' || c == 'l' || c == 'L') {
! 890: if (c == 'u' || c == 'U') {
! 891: if (uflag)
! 892: goto num_err;
! 893: uflag = TRUE;
! 894: } else if (c == 'l' || c == 'L') {
! 895: #if HAVE_LONG_LONG
! 896: if (llflag) {
! 897: goto num_err;
! 898: } else if (lflag) {
! 899: llflag = TRUE;
! 900: if (! stdc3 && ((! skip && (warn_level & w_level))
! 901: || (skip && (warn_level & 8))))
! 902: cwarn( ll_suffix, nump, 0L, skip ? non_eval : NULL);
! 903: } else {
! 904: lflag = TRUE;
! 905: }
! 906: #else
! 907: if (lflag)
! 908: goto num_err;
! 909: else
! 910: lflag = TRUE;
! 911: #endif
! 912: }
! 913: c = *cp++;
! 914: }
! 915: #if HAVE_LONG_LONG && (COMPILER == MSC || COMPILER == BORLANDC)
! 916: if (tolower( c) == 'i') {
! 917: c1 = atoi( cp);
! 918: if (c1 == 64) {
! 919: if (! stdc3 && ((! skip && (warn_level & w_level))
! 920: || (skip && (warn_level & 8))))
! 921: cwarn( i64_suffix, nump, 0L, skip ? non_eval : NULL);
! 922: cp += 2;
! 923: } else if (c1 == 32 || c1 == 16) {
! 924: cp += 2;
! 925: } else if (c1 == 8) {
! 926: cp++;
! 927: }
! 928: c = *cp++;
! 929: }
! 930: #endif
! 931:
! 932: if (c != EOS)
! 933: goto num_err;
! 934:
! 935: if (standard) {
! 936: if (uflag) /* If 'U' suffixed, uexpr_t is treated as unsigned */
! 937: ev.sign = UNSIGNED;
! 938: else
! 939: ev.sign = (value >= 0L);
! 940: #if HAVE_LONG_LONG
! 941: } else {
! 942: if (value > LONGMAX)
! 943: erange_long = TRUE;
! 944: #endif
! 945: }
! 946:
! 947: ev.val = value;
! 948: if (erange && (warn_level & 8))
! 949: cwarn( out_of_range, nump, 0L, non_eval);
! 950: #if HAVE_LONG_LONG
! 951: else if (erange_long && ((skip && (warn_level & 8))
! 952: || (! stdc3 && ! skip && (warn_level & w_level))))
! 953: cwarn( out_of_range_long, nump, 0L, skip ? non_eval : NULL);
! 954: #endif
! 955: return & ev;
! 956:
! 957: range_err:
! 958: cerror( out_of_range, nump, 0L, NULL);
! 959: ev.sign = VAL_ERROR;
! 960: return & ev;
! 961: num_err:
! 962: cerror( not_integer, nump, 0L, NULL);
! 963: ev.sign = VAL_ERROR;
! 964: return & ev;
! 965: }
! 966:
! 967: static VAL_SIGN * eval_char(
! 968: char * const token
! 969: )
! 970: /*
! 971: * Evaluate a character constant.
! 972: * This routine is never called in POST_STD mode.
! 973: */
! 974: {
! 975: const char * const w_out_of_range
! 976: = "Wide character constant %s%.0ld%s is out of range"; /* _E_ _W8_ */
! 977: const char * const c_out_of_range
! 978: = "Integer character constant %s%.0ld%s is out of range"; /* _E_ _W8_ */
! 979: uexpr_t value;
! 980: uexpr_t tmp;
! 981: expr_t cl;
! 982: int erange = FALSE;
! 983: int wide = (*token == 'L');
! 984: int ucn8;
! 985: int i;
! 986: int bits, mbits, u8bits, bits_save;
! 987: char * cp = token + 1; /* Character content */
! 988: #if HAVE_LONG_LONG
! 989: const char * const w_out_of_range_long =
! 990: "Wide character constant %s%.0ld%s is " /* _E_ _W1_ _W2_ _W8_ */
! 991: "out of range of unsigned long";
! 992: const char * const c_out_of_range_long =
! 993: "Integer character constant %s%.0ld%s is " /* _E_ _W1_ _W2_ _W8_ */
! 994: "out of range of unsigned long";
! 995: int erange_long = FALSE;
! 996: #endif
! 997:
! 998: bits = CHARBIT;
! 999: u8bits = CHARBIT * 4;
! 1000: if (mbchar & UTF8)
! 1001: mbits = CHARBIT * 4;
! 1002: else
! 1003: mbits = CHARBIT * 2;
! 1004: if (mcpp_mode == STD && wide) { /* Wide character constant */
! 1005: cp++; /* Skip 'L' */
! 1006: bits = mbits;
! 1007: }
! 1008: if (char_type[ *cp & UCHARMAX] & mbchk) {
! 1009: cl = mb_eval( &cp);
! 1010: bits = mbits;
! 1011: } else if ((cl = eval_one( &cp, wide, mbits, (ucn8 = FALSE, &ucn8)))
! 1012: == -1L) {
! 1013: ev.sign = VAL_ERROR;
! 1014: return & ev;
! 1015: }
! 1016: bits_save = bits;
! 1017: value = cl;
! 1018:
! 1019: for (i = 0; *cp != '\'' && *cp != EOS; i++) {
! 1020: if (char_type[ *cp & UCHARMAX] & mbchk) {
! 1021: cl = mb_eval( &cp);
! 1022: if (cl == 0)
! 1023: /* Shift-out sequence of multi-byte or wide character */
! 1024: continue;
! 1025: bits = mbits;
! 1026: } else {
! 1027: cl = eval_one( &cp, wide, mbits, (ucn8 = FALSE, &ucn8));
! 1028: if (cl == -1L) {
! 1029: ev.sign = VAL_ERROR;
! 1030: return & ev;
! 1031: }
! 1032: #if OK_UCN
! 1033: if (ucn8 == TRUE)
! 1034: bits = u8bits;
! 1035: else
! 1036: bits = bits_save;
! 1037: #endif
! 1038: }
! 1039: tmp = value;
! 1040: value = (value << bits) | cl; /* Multi-char or multi-byte char */
! 1041: if ((value >> bits) < tmp) { /* Overflow */
! 1042: if (! skip)
! 1043: goto range_err;
! 1044: else
! 1045: erange = TRUE;
! 1046: }
! 1047: #if HAVE_LONG_LONG
! 1048: if ((mcpp_mode == STD && (! stdc3 && value > ULONGMAX))
! 1049: || (! standard && value > LONGMAX))
! 1050: erange_long = TRUE;
! 1051: #endif
! 1052: }
! 1053:
! 1054: ev.sign = ((expr_t) value >= 0L);
! 1055: ev.val = value;
! 1056:
! 1057: if (erange && skip && (warn_level & 8)) {
! 1058: if (wide)
! 1059: cwarn( w_out_of_range, token, 0L, non_eval);
! 1060: else
! 1061: cwarn( c_out_of_range, token, 0L, non_eval);
! 1062: #if HAVE_LONG_LONG
! 1063: } else if (erange_long && ((skip && (warn_level & 8))
! 1064: || (! stdc3 && ! skip && (warn_level & w_level)))) {
! 1065: if (wide)
! 1066: cwarn( w_out_of_range_long, token, 0L, skip ? non_eval : NULL);
! 1067: else
! 1068: cwarn( c_out_of_range_long, token, 0L, skip ? non_eval : NULL);
! 1069: #endif
! 1070: }
! 1071:
! 1072: if (i == 0) /* Constant of single (character or wide-character) */
! 1073: return & ev;
! 1074:
! 1075: if ((! skip && (warn_level & 4)) || (skip && (warn_level & 8))) {
! 1076: if (mcpp_mode == STD && wide)
! 1077: cwarn(
! 1078: "Multi-character wide character constant %s%.0ld%s isn't portable" /* _W4_ _W8_ */
! 1079: , token, 0L, skip ? non_eval : NULL);
! 1080: else
! 1081: cwarn(
! 1082: "Multi-character or multi-byte character constant %s%.0ld%s isn't portable" /* _W4_ _W8_ */
! 1083: , token, 0L, skip ? non_eval : NULL);
! 1084: }
! 1085: return & ev;
! 1086:
! 1087: range_err:
! 1088: if (wide)
! 1089: cerror( w_out_of_range, token, 0L, NULL);
! 1090: else
! 1091: cerror( c_out_of_range, token, 0L, NULL);
! 1092: ev.sign = VAL_ERROR;
! 1093: return & ev;
! 1094: }
! 1095:
! 1096: static expr_t eval_one(
! 1097: char ** seq_pp, /* Address of pointer to sequence */
! 1098: /* eval_one() advances the pointer to sequence */
! 1099: int wide, /* Flag of wide-character */
! 1100: int mbits, /* Number of bits of a wide-char */
! 1101: int * ucn8 /* Flag of UCN-32 bits */
! 1102: )
! 1103: /*
! 1104: * Called from eval_char() above to get a single character, single multi-
! 1105: * byte character or wide character (with or without \ escapes).
! 1106: * Returns the value of the character or -1L on error.
! 1107: */
! 1108: {
! 1109: #if OK_UCN
! 1110: const char * const ucn_malval
! 1111: = "UCN cannot specify the value %.0s\"%08lx\""; /* _E_ _W8_ */
! 1112: #endif
! 1113: const char * const out_of_range
! 1114: = "%s%ld bits can't represent escape sequence '%s'"; /* _E_ _W8_ */
! 1115: uexpr_t value;
! 1116: int erange = FALSE;
! 1117: char * seq = *seq_pp; /* Initial seq_pp for diagnostic*/
! 1118: const char * cp;
! 1119: const char * digits;
! 1120: unsigned uc;
! 1121: unsigned uc1;
! 1122: int count;
! 1123: int bits;
! 1124: size_t wchar_max;
! 1125:
! 1126: uc = *(*seq_pp)++ & UCHARMAX;
! 1127:
! 1128: if (uc != '\\') /* Other than escape sequence */
! 1129: return (expr_t) uc;
! 1130:
! 1131: /* escape sequence */
! 1132: uc1 = uc = *(*seq_pp)++ & UCHARMAX;
! 1133: switch (uc) {
! 1134: case 'a':
! 1135: return '\a';
! 1136: case 'b':
! 1137: return '\b';
! 1138: case 'f':
! 1139: return '\f';
! 1140: case 'n':
! 1141: return '\n';
! 1142: case 'r':
! 1143: return '\r';
! 1144: case 't':
! 1145: return '\t';
! 1146: case 'v':
! 1147: return '\v';
! 1148: #if OK_UCN
! 1149: case 'u': case 'U':
! 1150: if (! stdc2)
! 1151: goto undefined;
! 1152: /* Else Universal character name */
! 1153: /* Fall through */
! 1154: #endif
! 1155: case 'x': /* '\xFF' */
! 1156: if (! standard)
! 1157: goto undefined;
! 1158: digits = "0123456789abcdef";
! 1159: bits = 4;
! 1160: uc = *(*seq_pp)++ & UCHARMAX;
! 1161: break;
! 1162: case '0': case '1': case '2': case '3':
! 1163: case '4': case '5': case '6': case '7':
! 1164: digits = "01234567";
! 1165: bits = 3;
! 1166: break;
! 1167: case '\'': case '"': case '?': case '\\':
! 1168: return (expr_t) uc;
! 1169: default:
! 1170: goto undefined;
! 1171: }
! 1172:
! 1173: wchar_max = (UCHARMAX << CHARBIT) | UCHARMAX;
! 1174: if (mbits == CHARBIT * 4) {
! 1175: if (mcpp_mode == STD)
! 1176: wchar_max = (wchar_max << CHARBIT * 2) | wchar_max;
! 1177: else
! 1178: wchar_max = LONGMAX;
! 1179: }
! 1180:
! 1181: value = 0L;
! 1182: for (count = 0; ; ++count) {
! 1183: if (isupper( uc))
! 1184: uc = tolower( uc);
! 1185: if ((cp = strchr( digits, uc)) == NULL)
! 1186: break;
! 1187: if (count >= 3 && bits == 3)
! 1188: break; /* Octal escape sequence at most 3 digits */
! 1189: #if OK_UCN
! 1190: if ((count >= 4 && uc1 == 'u') || (count >= 8 && uc1 == 'U'))
! 1191: break;
! 1192: #endif
! 1193: value = (value << bits) | (cp - digits);
! 1194: #if OK_UCN
! 1195: if (wchar_max < value && uc1 != 'u' && uc1 != 'U')
! 1196: #else
! 1197: if (wchar_max < value)
! 1198: #endif
! 1199: {
! 1200: if (! skip)
! 1201: goto range_err;
! 1202: else
! 1203: erange = TRUE;
! 1204: }
! 1205: uc = *(*seq_pp)++ & UCHARMAX;
! 1206: }
! 1207: (*seq_pp)--;
! 1208:
! 1209: if (erange) {
! 1210: value &= wchar_max;
! 1211: goto range_err;
! 1212: }
! 1213:
! 1214: if (count == 0 && bits == 4) /* '\xnonsense' */
! 1215: goto undefined;
! 1216: #if OK_UCN
! 1217: if (uc1 == 'u' || uc1 == 'U') {
! 1218: if ((count < 4 && uc1 == 'u') || (count < 8 && uc1 == 'U'))
! 1219: goto undefined;
! 1220: if ((value >= 0L && value <= 0x9FL
! 1221: && value != 0x24L && value != 0x40L && value != 0x60L)
! 1222: || (!stdc3 && value >= 0xD800L && value <= 0xDFFFL)) {
! 1223: if (!skip)
! 1224: cerror( ucn_malval, NULL, (long) value, NULL);
! 1225: else if (warn_level & 8)
! 1226: cwarn( ucn_malval, NULL, (long) value, NULL);
! 1227: }
! 1228: if (count >= 8 && uc1 == 'U')
! 1229: *ucn8 = TRUE;
! 1230: return (expr_t) value;
! 1231: }
! 1232: #endif /* OK_UCN */
! 1233: if (! wide && (UCHARMAX < value)) {
! 1234: value &= UCHARMAX;
! 1235: goto range_err;
! 1236: }
! 1237: return (expr_t) value;
! 1238:
! 1239: undefined:
! 1240: uc1 = **seq_pp;
! 1241: **seq_pp = EOS; /* For diagnostic */
! 1242: if ((! skip && (warn_level & 1)) || (skip && (warn_level & 8)))
! 1243: cwarn(
! 1244: "Undefined escape sequence%s %.0ld'%s'" /* _W1_ _W8_ */
! 1245: , skip ? non_eval : NULL, 0L, seq);
! 1246: **seq_pp = uc1;
! 1247: *seq_pp = seq + 1;
! 1248: return (expr_t) '\\'; /* Returns the escape char */
! 1249:
! 1250: range_err:
! 1251: uc1 = **seq_pp;
! 1252: **seq_pp = EOS; /* For diagnostic */
! 1253: if (wide) {
! 1254: if (! skip)
! 1255: cerror( out_of_range, NULL, (long) mbits, seq);
! 1256: else if (warn_level & 8)
! 1257: cwarn( out_of_range, non_eval, (long) mbits, seq);
! 1258: } else {
! 1259: if (! skip)
! 1260: cerror( out_of_range, NULL, (long) CHARBIT, seq);
! 1261: else if (warn_level & 8)
! 1262: cwarn( out_of_range, non_eval, (long) CHARBIT, seq);
! 1263: }
! 1264:
! 1265: **seq_pp = uc1;
! 1266: if (! skip)
! 1267: return -1L;
! 1268: else
! 1269: return (expr_t) value;
! 1270: }
! 1271:
! 1272: static VAL_SIGN * eval_eval(
! 1273: VAL_SIGN * valp,
! 1274: int op
! 1275: )
! 1276: /*
! 1277: * One or two values are popped from the value stack and do arithmetic.
! 1278: * The result is pushed onto the value stack.
! 1279: * eval_eval() returns the new pointer to the top of the value stack.
! 1280: */
! 1281: {
! 1282: const char * const zero_div = "%sDivision by zero%.0ld%s"; /* _E_ _W8_ */
! 1283: #if HAVE_LONG_LONG
! 1284: const char * const neg_format =
! 1285: "Negative value \"%" LL_FORM "d\" is converted to positive \"%" /* _W1_ _W8_*/
! 1286: LL_FORM "u\"%%s";
! 1287: #else
! 1288: const char * const neg_format =
! 1289: "Negative value \"%ld\" is converted to positive \"%lu\"%%s"; /* _W1_ _W8_*/
! 1290: #endif
! 1291: expr_t v1, v2;
! 1292: int sign1, sign2;
! 1293:
! 1294: if (is_binary( op)) {
! 1295: v2 = (--valp)->val;
! 1296: sign2 = valp->sign;
! 1297: } else {
! 1298: v2 = 0L; /* Dummy */
! 1299: sign2 = SIGNED; /* Dummy */
! 1300: }
! 1301: v1 = (--valp)->val;
! 1302: sign1 = valp->sign;
! 1303: if (mcpp_debug & EXPRESSION) {
! 1304: mcpp_fprintf( DBG, "%s op %s", (is_binary( op)) ? "binary" : "unary"
! 1305: , opname[ op]);
! 1306: dump_val( ", v1 = ", valp);
! 1307: if (is_binary( op))
! 1308: dump_val( ", v2 = ", valp + 1);
! 1309: mcpp_fputc( '\n', DBG);
! 1310: }
! 1311:
! 1312: if (standard
! 1313: && (sign1 == UNSIGNED || sign2 == UNSIGNED) && is_binary( op)
! 1314: && op != OP_ANA && op != OP_ORO && op != OP_SR && op != OP_SL) {
! 1315: if (((sign1 == SIGNED && v1 < 0L) || (sign2 == SIGNED && v2 < 0L)
! 1316: ) && ((! skip && (warn_level & 1))
! 1317: || (skip && (warn_level & 8)))) {
! 1318: char negate[(((sizeof (expr_t) * 8) / 3) + 1) * 2 + 50];
! 1319: expr_t v3;
! 1320:
! 1321: v3 = (sign1 == SIGNED ? v1 : v2);
! 1322: sprintf( negate, neg_format, v3, v3);
! 1323: cwarn( negate, skip ? non_eval : NULL, 0L, NULL);
! 1324: }
! 1325: valp->sign = sign1 = sign2 = UNSIGNED;
! 1326: }
! 1327: if ((op == OP_SL || op == OP_SR)
! 1328: && ((! skip && (warn_level & 1)) || (skip && (warn_level & 8)))) {
! 1329: if (v2 < 0L || v2 >= sizeof (expr_t) * CHARBIT)
! 1330: cwarn( "Illegal shift count %.0s\"%ld\"%s" /* _W1_ _W8_ */
! 1331: , NULL, (long) v2, skip ? non_eval : NULL);
! 1332: #if HAVE_LONG_LONG
! 1333: else if (! stdc3 && v2 >= sizeof (long) * CHARBIT
! 1334: && ((! skip && (warn_level & w_level))
! 1335: || (skip && (warn_level & 8))))
! 1336: cwarn(
! 1337: "Shift count %.0s\"%ld\" is larger than bit count of long%s" /* _W1_ _W8_*/
! 1338: , NULL, (long) v2, skip ? non_eval : NULL);
! 1339: #endif
! 1340: }
! 1341: if ((op == OP_DIV || op == OP_MOD) && v2 == 0L) {
! 1342: if (! skip) {
! 1343: cerror( zero_div, NULL, 0L, NULL);
! 1344: valp->sign = VAL_ERROR;
! 1345: return valp;
! 1346: } else {
! 1347: if (warn_level & 8)
! 1348: cwarn( zero_div, NULL, 0L, non_eval);
! 1349: valp->sign = sign1;
! 1350: valp->val = (expr_t) EXPR_MAX;
! 1351: return valp;
! 1352: }
! 1353: }
! 1354:
! 1355: if (! standard || sign1 == SIGNED)
! 1356: v1 = eval_signed( & valp, v1, v2, op);
! 1357: else
! 1358: v1 = eval_unsigned( & valp, (uexpr_t) v1, (uexpr_t) v2, op);
! 1359:
! 1360: if (valp->sign == VAL_ERROR) /* Out of range */
! 1361: return valp;
! 1362:
! 1363: switch (op) {
! 1364: case OP_NOT: case OP_EQ: case OP_NE:
! 1365: case OP_LT: case OP_LE: case OP_GT: case OP_GE:
! 1366: case OP_ANA: case OP_ORO:
! 1367: valp->sign = SIGNED;
! 1368: break;
! 1369: default:
! 1370: valp->sign = sign1;
! 1371: break;
! 1372: }
! 1373: valp->val = v1;
! 1374: return valp;
! 1375: }
! 1376:
! 1377: static expr_t eval_signed(
! 1378: VAL_SIGN ** valpp,
! 1379: expr_t v1,
! 1380: expr_t v2,
! 1381: int op
! 1382: )
! 1383: /*
! 1384: * Apply the argument operator to the signed data.
! 1385: * OP_COL is a special case.
! 1386: */
! 1387: {
! 1388: const char * const illeg_op
! 1389: = "Bug: Illegal operator \"%s\" in eval_signed()"; /* _F_ */
! 1390: const char * const not_portable
! 1391: = "\"%s\" of negative number isn't portable%.0ld%s"; /* _W1_ _W8_*/
! 1392: const char * op_name = opname[ op];
! 1393: VAL_SIGN * valp = *valpp;
! 1394: expr_t val;
! 1395: int chk; /* Flag of overflow in long long */
! 1396:
! 1397: switch (op) {
! 1398: case OP_EOE:
! 1399: case OP_PLU: break;
! 1400: case OP_NEG:
! 1401: chk = v1 && v1 == -v1;
! 1402: if (chk
! 1403: #if HAVE_LONG_LONG
! 1404: || (! stdc3 && v1 && (long) v1 == (long) -v1)
! 1405: #endif
! 1406: )
! 1407: overflow( op_name, valpp, chk);
! 1408: v1 = -v1;
! 1409: break;
! 1410: case OP_COM: v1 = ~v1; break;
! 1411: case OP_NOT: v1 = !v1; break;
! 1412: case OP_MUL:
! 1413: val = v1 * v2;
! 1414: chk = v1 && v2 && (val / v1 != v2 || val / v2 != v1);
! 1415: if (chk
! 1416: #if HAVE_LONG_LONG
! 1417: || (! stdc3 && v1 && v2
! 1418: && ((long)val / (long)v1 != (long)v2
! 1419: || (long)val / (long)v2 != (long)v1))
! 1420: #endif
! 1421: )
! 1422: overflow( op_name, valpp, chk);
! 1423: v1 = val;
! 1424: break;
! 1425: case OP_DIV:
! 1426: case OP_MOD:
! 1427: /* Division by 0 has been already diagnosed by eval_eval(). */
! 1428: chk = -v1 == v1 && v2 == -1;
! 1429: if (chk /* LONG_MIN / -1 on two's complement */
! 1430: #if HAVE_LONG_LONG
! 1431: || (! stdc3
! 1432: && (long)-v1 == (long)v1 && (long)v2 == (long)-1)
! 1433: #endif
! 1434: )
! 1435: overflow( op_name, valpp, chk);
! 1436: else if (! stdc3 && (v1 < 0L || v2 < 0L)
! 1437: && ((! skip && (warn_level & 1))
! 1438: || (skip && (warn_level & 8))))
! 1439: cwarn( not_portable, op_name, 0L, skip ? non_eval : NULL);
! 1440: if (op == OP_DIV)
! 1441: v1 /= v2;
! 1442: else
! 1443: v1 %= v2;
! 1444: break;
! 1445: case OP_ADD:
! 1446: val = v1 + v2;
! 1447: chk = (v2 > 0L && v1 > val) || (v2 < 0L && v1 < val);
! 1448: if (chk
! 1449: #if HAVE_LONG_LONG
! 1450: || (! stdc3
! 1451: && (((long)v2 > 0L && (long)v1 > (long)val)
! 1452: || ((long)v2 < 0L && (long)v1 < (long)val)))
! 1453: #endif
! 1454: )
! 1455: overflow( op_name, valpp, chk);
! 1456: v1 = val;
! 1457: break;
! 1458: case OP_SUB:
! 1459: val = v1 - v2;
! 1460: chk = (v2 > 0L && val > v1) || (v2 < 0L && val < v1);
! 1461: if (chk
! 1462: #if HAVE_LONG_LONG
! 1463: || (! stdc3
! 1464: && (((long)v2 > 0L && (long)val > (long)v1)
! 1465: || ((long)v2 < 0L && (long)val < (long)v1)))
! 1466: #endif
! 1467: )
! 1468: overflow( op_name, valpp, chk);
! 1469: v1 = val;
! 1470: break;
! 1471: case OP_SL: v1 <<= v2; break;
! 1472: case OP_SR:
! 1473: if (v1 < 0L
! 1474: && ((!skip && (warn_level & 1))
! 1475: || (skip && (warn_level & 8))))
! 1476: cwarn( not_portable, op_name, 0L, skip ? non_eval : NULL);
! 1477: v1 >>= v2;
! 1478: break;
! 1479: case OP_LT: v1 = (v1 < v2); break;
! 1480: case OP_LE: v1 = (v1 <= v2); break;
! 1481: case OP_GT: v1 = (v1 > v2); break;
! 1482: case OP_GE: v1 = (v1 >= v2); break;
! 1483: case OP_EQ: v1 = (v1 == v2); break;
! 1484: case OP_NE: v1 = (v1 != v2); break;
! 1485: case OP_AND: v1 &= v2; break;
! 1486: case OP_XOR: v1 ^= v2; break;
! 1487: case OP_OR: v1 |= v2; break;
! 1488: case OP_ANA: v1 = (v1 && v2); break;
! 1489: case OP_ORO: v1 = (v1 || v2); break;
! 1490: case OP_COL:
! 1491: /*
! 1492: * If v1 has the "true" value, v2 has the "false" value.
! 1493: * The top of the value stack has the test.
! 1494: */
! 1495: v1 = (--*valpp)->val ? v1 : v2;
! 1496: break;
! 1497: default:
! 1498: cfatal( illeg_op, op_name, 0L, NULL);
! 1499: }
! 1500:
! 1501: *valpp = valp;
! 1502: return v1;
! 1503: }
! 1504:
! 1505: static expr_t eval_unsigned(
! 1506: VAL_SIGN ** valpp,
! 1507: uexpr_t v1u,
! 1508: uexpr_t v2u,
! 1509: int op
! 1510: )
! 1511: /*
! 1512: * Apply the argument operator to the unsigned data.
! 1513: * Called from eval_eval() only in Standard mode.
! 1514: */
! 1515: {
! 1516: const char * const illeg_op
! 1517: = "Bug: Illegal operator \"%s\" in eval_unsigned()"; /* _F_ */
! 1518: const char * op_name = opname[ op];
! 1519: VAL_SIGN * valp = *valpp;
! 1520: uexpr_t v1 = 0;
! 1521: int chk; /* Flag of overflow in unsigned long long */
! 1522: int minus; /* Big integer converted from signed long */
! 1523:
! 1524: minus = ! stdc3 && (v1u > ULONGMAX || v2u > ULONGMAX);
! 1525:
! 1526: switch (op) {
! 1527: case OP_EOE:
! 1528: case OP_PLU: v1 = v1u; break;
! 1529: case OP_NEG:
! 1530: v1 = -v1u;
! 1531: if (v1u)
! 1532: overflow( op_name, valpp, TRUE);
! 1533: break;
! 1534: case OP_COM: v1 = ~v1u; break;
! 1535: case OP_NOT: v1 = !v1u; break;
! 1536: case OP_MUL:
! 1537: v1 = v1u * v2u;
! 1538: chk = v1u && v2u && (v1 / v2u != v1u || v1 / v1u != v2u);
! 1539: if (chk
! 1540: #if HAVE_LONG_LONG
! 1541: || (! stdc3 && ! minus && v1 > ULONGMAX)
! 1542: #endif
! 1543: )
! 1544: overflow( op_name, valpp, chk);
! 1545: break;
! 1546: case OP_DIV:
! 1547: /* Division by 0 has been already diagnosed by eval_eval(). */
! 1548: v1 = v1u / v2u;
! 1549: break;
! 1550: case OP_MOD:
! 1551: v1 = v1u % v2u;
! 1552: break;
! 1553: case OP_ADD:
! 1554: v1 = v1u + v2u;
! 1555: chk = v1 < v1u;
! 1556: if (chk
! 1557: #if HAVE_LONG_LONG
! 1558: || (! stdc3 && ! minus && v1 > ULONGMAX)
! 1559: #endif
! 1560: )
! 1561: overflow( op_name, valpp, chk);
! 1562: break;
! 1563: case OP_SUB:
! 1564: v1 = v1u - v2u;
! 1565: chk = v1 > v1u;
! 1566: if (chk
! 1567: #if HAVE_LONG_LONG
! 1568: || (! stdc3 && ! minus && v1 > ULONGMAX)
! 1569: #endif
! 1570: )
! 1571: overflow( op_name, valpp, chk);
! 1572: break;
! 1573: case OP_SL: v1 = v1u << v2u; break;
! 1574: case OP_SR: v1 = v1u >> v2u; break;
! 1575: case OP_LT: v1 = (v1u < v2u); break;
! 1576: case OP_LE: v1 = (v1u <= v2u); break;
! 1577: case OP_GT: v1 = (v1u > v2u); break;
! 1578: case OP_GE: v1 = (v1u >= v2u); break;
! 1579: case OP_EQ: v1 = (v1u == v2u); break;
! 1580: case OP_NE: v1 = (v1u != v2u); break;
! 1581: case OP_AND: v1 = v1u & v2u; break;
! 1582: case OP_XOR: v1 = v1u ^ v2u; break;
! 1583: case OP_OR: v1 = v1u | v2u; break;
! 1584: case OP_ANA: v1 = (v1u && v2u); break;
! 1585: case OP_ORO: v1 = (v1u || v2u); break;
! 1586: case OP_COL: valp--;
! 1587: if (valp->val)
! 1588: v1 = v1u;
! 1589: else
! 1590: v1 = v2u;
! 1591: break;
! 1592: default:
! 1593: cfatal( illeg_op, op_name, 0L, NULL);
! 1594: }
! 1595:
! 1596: *valpp = valp;
! 1597: return v1;
! 1598: }
! 1599:
! 1600: static void overflow(
! 1601: const char * op_name,
! 1602: VAL_SIGN ** valpp,
! 1603: int ll_overflow /* Flag of overflow in long long */
! 1604: )
! 1605: {
! 1606: const char * const out_of_range
! 1607: = "Result of \"%s\" is out of range%.0ld%s"; /* _E_ _W1_ _W8_ */
! 1608:
! 1609: #if HAVE_LONG_LONG
! 1610: if (standard && ! ll_overflow) {
! 1611: /* Overflow of long not in C99 mode */
! 1612: if ((! skip && (warn_level & w_level)) || (skip && (warn_level & 8)))
! 1613: cwarn( out_of_range, op_name, 0L, " of (unsigned) long");
! 1614: } else
! 1615: #endif
! 1616: if (skip) {
! 1617: if (warn_level & 8)
! 1618: cwarn( out_of_range, op_name, 0L, non_eval);
! 1619: /* Else don't warn */
! 1620: } else if (standard && (*valpp)->sign == UNSIGNED) {/* Never overflow */
! 1621: if (warn_level & 1)
! 1622: cwarn( out_of_range, op_name, 0L, NULL);
! 1623: } else {
! 1624: cerror( out_of_range, op_name, 0L, NULL);
! 1625: (*valpp)->sign = VAL_ERROR;
! 1626: }
! 1627: }
! 1628:
! 1629: static void dump_val(
! 1630: const char * msg,
! 1631: const VAL_SIGN * valp
! 1632: )
! 1633: /*
! 1634: * Dump a value by internal representation.
! 1635: */
! 1636: {
! 1637: #if HAVE_LONG_LONG
! 1638: const char * const format
! 1639: = "%s(%ssigned long long) 0x%016" LL_FORM "x";
! 1640: #else
! 1641: const char * const format = "%s(%ssigned long) 0x%08lx";
! 1642: #endif
! 1643: int sign = valp->sign;
! 1644:
! 1645: mcpp_fprintf( DBG, format, msg, sign ? "" : "un", valp->val);
! 1646: }
! 1647:
! 1648: static void dump_stack(
! 1649: const OPTAB * opstack, /* Operator stack */
! 1650: const OPTAB * opp, /* Pointer into operator stack */
! 1651: const VAL_SIGN * value, /* Value stack */
! 1652: const VAL_SIGN * valp /* -> value vector */
! 1653: )
! 1654: /*
! 1655: * Dump stacked operators and values.
! 1656: */
! 1657: {
! 1658: if (opstack < opp)
! 1659: mcpp_fprintf( DBG, "Index op prec skip name -- op stack at %s"
! 1660: , infile->bptr);
! 1661:
! 1662: while (opstack < opp) {
! 1663: mcpp_fprintf( DBG, " [%2d] %2d %04o %d %s\n", (int)(opp - opstack)
! 1664: , opp->op, opp->prec, opp->skip, opname[ opp->op]);
! 1665: opp--;
! 1666: }
! 1667:
! 1668: while (value <= --valp) {
! 1669: mcpp_fprintf( DBG, "value[%d].val = ", (int)(valp - value));
! 1670: dump_val( "", valp);
! 1671: mcpp_fputc( '\n', DBG);
! 1672: }
! 1673: }
! 1674:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>