[BACK]Return to eval.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / windows / mcpp

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>