Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members  

cppexp.c File Reference

#include <string.h>
#include "lclintMacros.nf"
#include "llbasic.h"
#include "cpp.h"
#include "cpplib.h"
#include "cpphash.h"
#include "cppexp.h"
#include "cpperror.h"
#include <stdio.h>

Go to the source code of this file.

Compounds

struct  operation
struct  token

Defines

#define possibleSumSign(a, b, sum)    ((((a) ^ (b)) | ~ ((a) ^ (sum))) < 0)
#define BITS_PER_UNIT   8
#define BITS_PER_CHAR   8
#define BITS_PER_WORD   32
#define HOST_BITS_PER_INT   32
#define HOST_BITS_PER_LONG   32
#define TARGET_BELL   (char) 6
#define TARGET_BS   (char) 7
#define TARGET_FF   (char) 8
#define TARGET_NEWLINE   '\n'
#define TARGET_CR   '\n'
#define TARGET_TAB   '\t'
#define TARGET_VT   '\v'
#define INT_TYPE_SIZE   BITS_PER_WORD
#define LONG_TYPE_SIZE   BITS_PER_WORD
#define WCHAR_TYPE_SIZE   INT_TYPE_SIZE
#define CHAR_TYPE_SIZE   BITS_PER_CHAR
#define MAX_CHAR_TYPE_SIZE   CHAR_TYPE_SIZE
#define MAX_LONG_TYPE_SIZE   LONG_TYPE_SIZE
#define MAX_WCHAR_TYPE_SIZE   WCHAR_TYPE_SIZE
#define CPPREADER_ERRORTOK   299
#define OROR   300
#define ANDAND   301
#define CPP_EQUALTOK   302
#define NOTEQUAL   303
#define LEQ   304
#define GEQ   305
#define LSH   306
#define RSH   307
#define NAME   308
#define CPPEXP_INT   309
#define CPPEXP_CHAR   310
#define LEFT_OPERAND_REQUIRED   1
#define RIGHT_OPERAND_REQUIRED   2
#define HAVE_VALUE   4
#define HOST_BITS_PER_WIDE_INT   HOST_BITS_PER_INT
#define HOST_WIDE_INT   long
#define PAREN_INNER_PRIO   0
#define COMMA_PRIO   4
#define COND_PRIO   (COMMA_PRIO+2)
#define OROR_PRIO   (COND_PRIO+2)
#define ANDAND_PRIO   (OROR_PRIO+2)
#define OR_PRIO   (ANDAND_PRIO+2)
#define XOR_PRIO   (OR_PRIO+2)
#define AND_PRIO   (XOR_PRIO+2)
#define CPP_EQUAL_PRIO   (AND_PRIO+2)
#define LESS_PRIO   (CPP_EQUAL_PRIO+2)
#define SHIFT_PRIO   (LESS_PRIO+2)
#define PLUS_PRIO   (SHIFT_PRIO+2)
#define MUL_PRIO   (PLUS_PRIO+2)
#define UNARY_PRIO   (MUL_PRIO+2)
#define PAREN_OUTER_PRIO   (UNARY_PRIO+2)
#define COMPARE(OP)
#define INIT_STACK_SIZE   20
#define LOGICAL(OP)

Functions

struct operation cppReader_parseNumber (cppReader *pfile, char *start, int olen)
int cppReader_parseEscape (cppReader *pfile, char **string_ptr)
HOST_WIDE_INT cppReader_parseExpression (cppReader *pfile)


Define Documentation

#define ANDAND   301
 

Definition at line 168 of file cppexp.c.

#define ANDAND_PRIO   (OROR_PRIO+2)
 

Definition at line 833 of file cppexp.c.

#define AND_PRIO   (XOR_PRIO+2)
 

Definition at line 842 of file cppexp.c.

#define BITS_PER_CHAR   8
 

Definition at line 82 of file cppexp.c.

#define BITS_PER_UNIT   8
 

Definition at line 79 of file cppexp.c.

#define BITS_PER_WORD   32
 

Definition at line 85 of file cppexp.c.

#define CHAR_TYPE_SIZE   BITS_PER_CHAR
 

Definition at line 138 of file cppexp.c.

#define COMMA_PRIO   4
 

Definition at line 824 of file cppexp.c.

#define COMPARE( OP )
 

Initializer:

\
  top->unsignedp = FALSE;\
  top->value = ((unsigned1 || unsigned2) \
                 ? (unsigned long) v1 OP (unsigned long) v2 \
                 : ((long) v1 OP (long) v2)) ? 1 : 0

Definition at line 866 of file cppexp.c.

Referenced by cppReader_parseExpression().

#define COND_PRIO   (COMMA_PRIO+2)
 

Definition at line 827 of file cppexp.c.

#define CPPEXP_CHAR   310
 

Definition at line 195 of file cppexp.c.

#define CPPEXP_INT   309
 

Definition at line 192 of file cppexp.c.

#define CPPREADER_ERRORTOK   299
 

Definition at line 162 of file cppexp.c.

#define CPP_EQUALTOK   302
 

Definition at line 171 of file cppexp.c.

#define CPP_EQUAL_PRIO   (AND_PRIO+2)
 

Definition at line 845 of file cppexp.c.

#define GEQ   305
 

Definition at line 180 of file cppexp.c.

#define HAVE_VALUE   4
 

Definition at line 204 of file cppexp.c.

#define HOST_BITS_PER_INT   32
 

Definition at line 88 of file cppexp.c.

#define HOST_BITS_PER_LONG   32
 

Definition at line 91 of file cppexp.c.

#define HOST_BITS_PER_WIDE_INT   HOST_BITS_PER_INT
 

Definition at line 215 of file cppexp.c.

#define HOST_WIDE_INT   long
 

Definition at line 217 of file cppexp.c.

#define INIT_STACK_SIZE   20
 

Definition at line 876 of file cppexp.c.

#define INT_TYPE_SIZE   BITS_PER_WORD
 

Definition at line 123 of file cppexp.c.

#define LEFT_OPERAND_REQUIRED   1
 

Definition at line 198 of file cppexp.c.

#define LEQ   304
 

Definition at line 177 of file cppexp.c.

#define LESS_PRIO   (CPP_EQUAL_PRIO+2)
 

Definition at line 848 of file cppexp.c.

#define LOGICAL( OP )
 

Initializer:

\
              top->value = v1 OP v2;\
              top->unsignedp = unsigned1 || unsigned2;

Referenced by cppReader_parseExpression().

#define LONG_TYPE_SIZE   BITS_PER_WORD
 

Definition at line 128 of file cppexp.c.

#define LSH   306
 

Definition at line 183 of file cppexp.c.

#define MAX_CHAR_TYPE_SIZE   CHAR_TYPE_SIZE
 

Definition at line 143 of file cppexp.c.

#define MAX_LONG_TYPE_SIZE   LONG_TYPE_SIZE
 

Definition at line 148 of file cppexp.c.

#define MAX_WCHAR_TYPE_SIZE   WCHAR_TYPE_SIZE
 

Definition at line 153 of file cppexp.c.

#define MUL_PRIO   (PLUS_PRIO+2)
 

Definition at line 857 of file cppexp.c.

#define NAME   308
 

Definition at line 189 of file cppexp.c.

#define NOTEQUAL   303
 

Definition at line 174 of file cppexp.c.

#define OROR   300
 

Definition at line 165 of file cppexp.c.

#define OROR_PRIO   (COND_PRIO+2)
 

Definition at line 830 of file cppexp.c.

#define OR_PRIO   (ANDAND_PRIO+2)
 

Definition at line 836 of file cppexp.c.

#define PAREN_INNER_PRIO   0
 

Definition at line 821 of file cppexp.c.

#define PAREN_OUTER_PRIO   (UNARY_PRIO+2)
 

Definition at line 863 of file cppexp.c.

#define PLUS_PRIO   (SHIFT_PRIO+2)
 

Definition at line 854 of file cppexp.c.

#define RIGHT_OPERAND_REQUIRED   2
 

Definition at line 201 of file cppexp.c.

#define RSH   307
 

Definition at line 186 of file cppexp.c.

#define SHIFT_PRIO   (LESS_PRIO+2)
 

Definition at line 851 of file cppexp.c.

#define TARGET_BELL   (char) 6
 

Definition at line 94 of file cppexp.c.

#define TARGET_BS   (char) 7
 

Definition at line 97 of file cppexp.c.

#define TARGET_CR   '\n'
 

Definition at line 106 of file cppexp.c.

#define TARGET_FF   (char) 8
 

Definition at line 100 of file cppexp.c.

#define TARGET_NEWLINE   '\n'
 

Definition at line 103 of file cppexp.c.

#define TARGET_TAB   '\t'
 

Definition at line 109 of file cppexp.c.

#define TARGET_VT   '\v'
 

Definition at line 112 of file cppexp.c.

#define UNARY_PRIO   (MUL_PRIO+2)
 

Definition at line 860 of file cppexp.c.

#define WCHAR_TYPE_SIZE   INT_TYPE_SIZE
 

Definition at line 133 of file cppexp.c.

#define XOR_PRIO   (OR_PRIO+2)
 

Definition at line 839 of file cppexp.c.

#define possibleSumSign( a, b, sum )   ((((a) ^ (b)) | ~ ((a) ^ (sum))) < 0)
 

Definition at line 74 of file cppexp.c.

Referenced by cppReader_parseExpression().


Function Documentation

int cppReader_parseEscape ( cppReader * pfile,
char ** string_ptr )
 

Definition at line 653 of file cppexp.c.

00654 {
00655   char c = *(*string_ptr)++;
00656 
00657   switch (c)
00658     {
00659     case 'a':
00660       return TARGET_BELL;
00661     case 'b':
00662       return TARGET_BS;
00663     case 'e':
00664     case 'E':
00665       if (cppReader_isPedantic (pfile))
00666         {
00667           cppReader_pedwarn (pfile, 
00668                        message ("non-ANSI-standard escape sequence, `\\%c'", c));
00669         }
00670       return (char) 033;
00671     case 'f':
00672       return TARGET_FF;
00673     case 'n':
00674       return TARGET_NEWLINE;
00675     case 'r':
00676       return TARGET_CR;
00677     case 't':
00678       return TARGET_TAB;
00679     case 'v':
00680       return TARGET_VT;
00681     case '\n':
00682       return -2;
00683     case 0:
00684       (*string_ptr)--;
00685       return 0;
00686       
00687     case '0':
00688     case '1':
00689     case '2':
00690     case '3':
00691     case '4':
00692     case '5':
00693     case '6':
00694     case '7':
00695       {
00696         int i = (int) c - '0';
00697         int count = 0;
00698 
00699         while (++count < 3)
00700           {
00701             c = *(*string_ptr)++;
00702             if (c >= '0' && c <= '7')
00703               {
00704                 i = ((unsigned) i << 3) + c - '0';
00705               }
00706 
00707             else
00708               {
00709                 (*string_ptr)--;
00710                 /*@loopbreak@*/ break;
00711               }
00712           }
00713         if ((i & ~((1 << MAX_CHAR_TYPE_SIZE) - 1)) != 0)
00714           {
00715             i &= (1 << MAX_CHAR_TYPE_SIZE) - 1;
00716             cppReader_pedwarnLit (pfile,
00717                             cstring_makeLiteralTemp ("octal character constant does not fit in a byte"));
00718           }
00719         return i;
00720       }
00721     case 'x':
00722       {
00723         register unsigned i = 0, overflow = 0, digits_found = 0, digit;
00724         for (;;)
00725           {
00726             c = *(*string_ptr)++;
00727 
00728             if (c >= '0' && c <= '9')
00729               {
00730                 digit = (unsigned int) (c - '0');
00731               }
00732             else if (c >= 'a' && c <= 'f')
00733               {
00734                 digit = (unsigned int) (c - 'a') + 10;
00735               }
00736             else if (c >= 'A' && c <= 'F')
00737               {
00738                 digit = (unsigned int) (c - 'A') + 10;
00739               }
00740             else
00741               {
00742                 (*string_ptr)--;
00743                 /*@loopbreak@*/ break;
00744               }
00745             overflow |= i ^ (i << 4 >> 4);
00746             i = (i << 4) + digit;
00747             digits_found = 1;
00748           }
00749         
00750         if (digits_found == 0)
00751           {
00752             cppReader_errorLit (pfile,
00753                                 cstring_makeLiteralTemp ("\\x used with no following hex digits"));
00754           }
00755 
00756         if ((overflow | (i & ~((1 << BITS_PER_UNIT) - 1))) != 0)
00757           {
00758             i &= (1 << BITS_PER_UNIT) - 1;
00759             cppReader_pedwarnLit (pfile,
00760                             cstring_makeLiteralTemp ("hex character constant does not fit in a byte"));
00761           }
00762 
00763         return i;
00764       }
00765     default:
00766       return c;
00767     }
00768 }

HOST_WIDE_INT cppReader_parseExpression ( cppReader * pfile )
 

Definition at line 879 of file cppexp.c.

00880 {
00881   /* The implementation is an operator precedence parser,
00882      i.e. a bottom-up parser, using a stack for not-yet-reduced tokens.
00883 
00884      The stack base is 'stack', and the current stack pointer is 'top'.
00885      There is a stack element for each operator (only),
00886      and the most recently pushed operator is 'top->op'.
00887      An operand (value) is stored in the 'value' field of the stack
00888      element of the operator that precedes it.
00889      In that case the 'flags' field has the HAVE_VALUE flag set.  */
00890 
00891   struct operation init_stack[INIT_STACK_SIZE];
00892   struct operation *stack = init_stack;
00893   struct operation *limit = stack + INIT_STACK_SIZE;
00894   register struct operation *top = stack;
00895   int lprio, rprio = 0;
00896   int skip_evaluation = 0;
00897 
00898   top->rprio = 0;
00899   top->flags = 0;
00900 
00901   for (;;)
00902     {
00903       struct operation op;
00904       int flags = 0;
00905 
00906       /* Read a token */
00907       op =  cppReader_lex (pfile);
00908 
00909       /* See if the token is an operand, in which case go to set_value.
00910          If the token is an operator, figure out its left and right
00911          priorities, and then goto maybe_reduce.  */
00912 
00913       switch (op.op)
00914         {
00915         case NAME:
00916           top->value = 0, top->unsignedp = FALSE;
00917           goto set_value;
00918         case CPPEXP_INT:
00919         case CPPEXP_CHAR:
00920           top->value = op.value;
00921           top->unsignedp = op.unsignedp;
00922           goto set_value;
00923         case 0:
00924           lprio = 0;  goto maybe_reduce;
00925         case '+':  case '-':
00926           /* Is this correct if unary ? FIXME */
00927           flags = RIGHT_OPERAND_REQUIRED;
00928           lprio = PLUS_PRIO;  rprio = lprio + 1;  goto maybe_reduce;
00929         case '!':  case '~':
00930           flags = RIGHT_OPERAND_REQUIRED;
00931           rprio = UNARY_PRIO;  lprio = rprio + 1;  goto maybe_reduce;
00932         case '*':  case '/':  case '%':
00933           lprio = MUL_PRIO;  goto binop;
00934         case '<':  case '>':  case LEQ:  case GEQ:
00935           lprio = LESS_PRIO;  goto binop;
00936         case CPP_EQUALTOK:  case NOTEQUAL:
00937           lprio = CPP_EQUAL_PRIO;  goto binop;
00938         case LSH:  case RSH:
00939           lprio = SHIFT_PRIO;  goto binop;
00940         case '&':  lprio = AND_PRIO;  goto binop;
00941         case '^':  lprio = XOR_PRIO;  goto binop;
00942         case '|':  lprio = OR_PRIO;  goto binop;
00943         case ANDAND:  lprio = ANDAND_PRIO;  goto binop;
00944         case OROR:  lprio = OROR_PRIO;  goto binop;
00945         case ',':
00946           lprio = COMMA_PRIO;  goto binop;
00947         case '(':
00948           lprio = PAREN_OUTER_PRIO;  rprio = PAREN_INNER_PRIO;
00949           goto maybe_reduce;
00950         case ')':
00951           lprio = PAREN_INNER_PRIO;  rprio = PAREN_OUTER_PRIO;
00952           goto maybe_reduce;
00953         case ':':
00954           lprio = COND_PRIO;  rprio = COND_PRIO;
00955           goto maybe_reduce;
00956         case '?':
00957           lprio = COND_PRIO + 1;  rprio = COND_PRIO;
00958           goto maybe_reduce;
00959         binop:
00960           flags = LEFT_OPERAND_REQUIRED | RIGHT_OPERAND_REQUIRED;
00961           rprio = lprio + 1;
00962           goto maybe_reduce;
00963         default:
00964           cppReader_error 
00965             (pfile, 
00966              message ("Invalid character in #if: %c", 
00967                       (char) op.op));
00968           goto syntax_error;
00969         }
00970 
00971     set_value:
00972       /* Push a value onto the stack.  */
00973       if ((top->flags & HAVE_VALUE) != 0)
00974         {
00975           cppReader_errorLit (pfile, 
00976                         cstring_makeLiteralTemp ("syntax error in #if"));
00977           goto syntax_error;
00978         }
00979       top->flags |= HAVE_VALUE;
00980       continue;
00981 
00982     maybe_reduce:
00983       /* Push an operator, and check if we can reduce now.  */
00984       while (top->rprio > lprio)
00985         {
00986           /*@-usedef@*/
00987           long v1 = top[-1].value, v2 = top[0].value;
00988           bool unsigned1 = top[-1].unsignedp;
00989           bool unsigned2 = top[0].unsignedp;
00990 
00991           top--;
00992 
00993           if (((top[1].flags & LEFT_OPERAND_REQUIRED) != 0)
00994               && ((top[0].flags & HAVE_VALUE) == 0))
00995             {
00996               cppReader_errorLit (pfile, 
00997                             cstring_makeLiteralTemp ("syntax error - missing left operand"));
00998               goto syntax_error;
00999             }
01000           if (((top[1].flags & RIGHT_OPERAND_REQUIRED) != 0)
01001               && ((top[1].flags & HAVE_VALUE) == 0))
01002             {
01003               cppReader_errorLit (pfile, 
01004                             cstring_makeLiteralTemp ("syntax error - missing right operand"));
01005               goto syntax_error;
01006             }
01007           /* top[0].value = (top[1].op)(v1, v2);*/
01008           switch (top[1].op)
01009             {
01010             case '+':
01011               if ((top->flags & HAVE_VALUE) == 0)
01012                 { /* Unary '+' */
01013                   top->value = v2;
01014                   top->unsignedp = unsigned2;
01015                   top->flags |= HAVE_VALUE;
01016                 }
01017               else
01018                 {
01019                   top->value = v1 + v2;
01020                   top->unsignedp = unsigned1 || unsigned2;
01021                   if (!top->unsignedp && (skip_evaluation == 0)
01022                       && ! possibleSumSign (v1, v2, top->value))
01023                     integer_overflow (pfile);
01024                 }
01025               /*@switchbreak@*/ break;
01026             case '-':
01027               if ((top->flags & HAVE_VALUE) == 0)
01028                 { /* Unary '-' */
01029                   top->value = - v2;
01030                   if ((skip_evaluation == 0) 
01031                       && (top->value & v2) < 0 && !unsigned2)
01032                     integer_overflow (pfile);
01033                   top->unsignedp = unsigned2;
01034                   top->flags |= HAVE_VALUE;
01035                 }
01036               else
01037                 { /* Binary '-' */
01038                   top->value = v1 - v2;
01039                   top->unsignedp = unsigned1 || unsigned2;
01040                   if (!top->unsignedp && (skip_evaluation == 0)
01041                       && !possibleSumSign (top->value, v2, v1))
01042                     {
01043                       integer_overflow (pfile);
01044                     }
01045                 }
01046               /*@switchbreak@*/ break;
01047             case '*':
01048               top->unsignedp = unsigned1 || unsigned2;
01049 
01050               if (top->unsignedp)
01051                 {
01052                   top->value = (unsigned long) v1 * v2;
01053                 }
01054               else if (skip_evaluation == 0)
01055                 {
01056                   top->value = v1 * v2;
01057                   if ((v1 != 0)
01058                       && (top->value / v1 != v2
01059                           || (top->value & v1 & v2) < 0))
01060                     {
01061                       integer_overflow (pfile);
01062                     }
01063                 }
01064               else
01065                 {
01066                   ;
01067                 }
01068 
01069               /*@switchbreak@*/ break;
01070             case '/':
01071               if (skip_evaluation != 0)
01072                 /*@switchbreak@*/ break;
01073               if (v2 == 0)
01074                 {
01075                   cppReader_errorLit (pfile, 
01076                                 cstring_makeLiteralTemp ("Division by zero in #if"));
01077                   v2 = 1;
01078                 }
01079               top->unsignedp = unsigned1 || unsigned2;
01080               if (top->unsignedp)
01081                 top->value = (unsigned long) v1 / v2;
01082               else
01083                 {
01084                   top->value = v1 / v2;
01085                   if ((top->value & v1 & v2) < 0)
01086                     integer_overflow (pfile);
01087                 }
01088               /*@switchbreak@*/ break;
01089             case '%':
01090               if (skip_evaluation != 0)
01091                 /*@switchbreak@*/ break;
01092               if (v2 == 0)
01093                 {
01094                   cppReader_errorLit (pfile, 
01095                                 cstring_makeLiteralTemp ("Division by zero in #if"));
01096                   v2 = 1;
01097                 }
01098               top->unsignedp = unsigned1 || unsigned2;
01099               if (top->unsignedp)
01100                 top->value = (unsigned long) v1 % v2;
01101               else
01102                 top->value = v1 % v2;
01103               /*@switchbreak@*/ break;
01104             case '!':
01105               if ((top->flags & HAVE_VALUE) != 0)
01106                 {
01107                   cppReader_errorLit (pfile, 
01108                                       cstring_makeLiteralTemp ("Syntax error"));
01109                   goto syntax_error;
01110                 }
01111 
01112               top->value = (v2 == 0) ? 1 : 0;
01113               top->unsignedp = FALSE;
01114               top->flags |= HAVE_VALUE;
01115               /*@switchbreak@*/ break;
01116             case '~':
01117               if ((top->flags & HAVE_VALUE) != 0)
01118                 {
01119                   cppReader_errorLit (pfile, 
01120                                 cstring_makeLiteralTemp ("syntax error"));
01121                   goto syntax_error;
01122                 }
01123               top->value = ~ v2;
01124               top->unsignedp = unsigned2;
01125               top->flags |= HAVE_VALUE;
01126               /*@switchbreak@*/ break;
01127             case '<':  COMPARE(<);  /*@switchbreak@*/ break;
01128             case '>':  COMPARE(>);  /*@switchbreak@*/ break;
01129             case LEQ:  COMPARE(<=); /*@switchbreak@*/ break;
01130             case GEQ:  COMPARE(>=); /*@switchbreak@*/ break;
01131             case CPP_EQUALTOK:
01132               top->value = (v1 == v2) ? 1 : 0;
01133               top->unsignedp = FALSE;
01134               /*@switchbreak@*/ break;
01135             case NOTEQUAL:
01136               top->value = (v1 != v2) ? 1 : 0;
01137               top->unsignedp = FALSE;
01138               /*@switchbreak@*/ break;
01139             case LSH:
01140               if (skip_evaluation != 0)
01141                 {
01142                   /*@switchbreak@*/ break;
01143                 }
01144 
01145               top->unsignedp = unsigned1;
01146               if (v2 < 0 && ! unsigned2)
01147                 top->value = right_shift (v1, unsigned1, -v2);
01148               else
01149                 top->value = left_shift (pfile, v1, unsigned1, v2);
01150               /*@switchbreak@*/ break;
01151             case RSH:
01152               if (skip_evaluation != 0)
01153                 {
01154                   /*@switchbreak@*/ break;
01155                 }
01156               top->unsignedp = unsigned1;
01157               if (v2 < 0 && ! unsigned2)
01158                 top->value = left_shift (pfile, v1, unsigned1, -v2);
01159               else
01160                 top->value = right_shift (v1, unsigned1, v2);
01161               /*@switchbreak@*/ break;
01162 
01163 /*@notfunction@*/
01164 #define LOGICAL(OP) \
01165               top->value = v1 OP v2;\
01166               top->unsignedp = unsigned1 || unsigned2;
01167 
01168             case '&':  LOGICAL(&); /*@switchbreak@*/ break;
01169             case '^':  LOGICAL(^); /*@switchbreak@*/ break;
01170             case '|':  LOGICAL(|); /*@switchbreak@*/ break;
01171             case ANDAND:
01172               top->value = ((v1 != 0) && (v2 != 0)) ? 1 : 0;
01173               top->unsignedp = FALSE;
01174 
01175               if (v1 == 0)
01176                 {
01177                   skip_evaluation--;
01178                 }
01179               /*@switchbreak@*/ break;
01180             case OROR:
01181               top->value = ((v1 != 0) || (v2 != 0)) ? 1 : 0;
01182               top->unsignedp = FALSE;
01183               if (v1 != 0)
01184                 {
01185                   skip_evaluation--;
01186                 }
01187               /*@switchbreak@*/ break;
01188             case ',':
01189               if (cppReader_isPedantic (pfile))
01190                 cppReader_pedwarnLit (pfile, 
01191                                 cstring_makeLiteralTemp ("comma operator in operand of `#if'"));
01192               top->value = v2;
01193               top->unsignedp = unsigned2;
01194               /*@switchbreak@*/ break;
01195             case '(':  case '?':
01196               cppReader_errorLit (pfile, 
01197                             cstring_makeLiteralTemp ("syntax error in #if"));
01198               goto syntax_error;
01199             case ':':
01200               if (top[0].op != '?')
01201                 {
01202                   cppReader_errorLit (pfile,
01203                                 cstring_makeLiteralTemp ("syntax error ':' without preceding '?'"));
01204                   goto syntax_error;
01205                 }
01206               else if (((top[1].flags & HAVE_VALUE) == 0)
01207                        || ((top[-1].flags & HAVE_VALUE) == 0)
01208                        || ((top[0].flags & HAVE_VALUE) == 0))
01209                 {
01210                   cppReader_errorLit (pfile, 
01211                                 cstring_makeLiteralTemp ("bad syntax for ?: operator"));
01212                   goto syntax_error;
01213                 }
01214               else
01215                 {
01216                   top--;
01217                   if (top->value != 0)
01218                     {
01219                       skip_evaluation--;
01220                     }
01221 
01222                   top->value = (top->value != 0) ? v1 : v2;
01223                   top->unsignedp = unsigned1 || unsigned2;
01224                 }
01225               /*@switchbreak@*/ break;
01226             case ')':
01227               if (((top[1].flags & HAVE_VALUE) != 0)
01228                   || ((top[0].flags & HAVE_VALUE) == 0)
01229                   || top[0].op != '('
01230                   || ((top[-1].flags & HAVE_VALUE) != 0))
01231                 {
01232                   cppReader_errorLit (pfile, 
01233                                 cstring_makeLiteralTemp ("mismatched parentheses in #if"));
01234                   goto syntax_error;
01235                 }
01236               else
01237                 {
01238                   top--;
01239                   top->value = v1;
01240                   top->unsignedp = unsigned1;
01241                   top->flags |= HAVE_VALUE;
01242                 }
01243               /*@switchbreak@*/ break;
01244             default:
01245               fprintf (stderr,
01246                        top[1].op >= ' ' && top[1].op <= '~'
01247                        ? "unimplemented operator '%c'\n"
01248                        : "unimplemented operator '\\%03o'\n",
01249                        top[1].op);
01250             }
01251         }
01252       if (op.op == 0)
01253         {
01254           long val;
01255 
01256           if (top != stack)
01257             {
01258               cppReader_errorLit (pfile, 
01259                             cstring_makeLiteralTemp ("internal error in #if expression"));
01260             }
01261 
01262           val = top->value;
01263 
01264           if (stack != init_stack)
01265             {
01266               sfree (stack);
01267               /*@-branchstate@*/
01268             } /*@=branchstate@*/
01269 
01270           return val;
01271         }
01272       top++;
01273       
01274       /* Check for and handle stack overflow.  */
01275       if (top == limit)
01276         {
01277           struct operation *new_stack;
01278           int old_size = (char *) limit - (char *) stack;
01279           size_t new_size = size_fromInt (2 * old_size);
01280 
01281           if (stack != init_stack)
01282             {
01283               new_stack = (struct operation *) drealloc ((char *) stack,
01284                                                          new_size);
01285             }
01286           else
01287             {
01288               new_stack = (struct operation *) dmalloc (new_size);
01289 
01290               /* Bug: the parameters were in the wrong order! */
01291               memcpy ((char *) new_stack, (char *) stack, old_size);
01292               /*@-branchstate@*/
01293             } /*@=branchstate@*/
01294 
01295           stack = new_stack;
01296           top = (struct operation *) ((char *) new_stack + old_size);
01297           limit = (struct operation *) ((char *) new_stack + new_size);
01298           /*@-branchstate@*/ 
01299         } /*@=branchstate@*/ 
01300       
01301       top->flags = flags;
01302       top->rprio = rprio;
01303       top->op = op.op;
01304       if ((op.op == OROR && (top[-1].value != 0))
01305           || (op.op == ANDAND && (top[-1].value == 0))
01306           || (op.op == '?' && (top[-1].value == 0)))
01307         {
01308           skip_evaluation++;
01309         }
01310       else if (op.op == ':')
01311         {
01312           if (top[-2].value != 0) /* Was condition true? */
01313             {
01314               skip_evaluation++;
01315             }
01316           else
01317             {
01318               skip_evaluation--;
01319             }
01320         }
01321       else
01322         {
01323           ;
01324         }
01325     }
01326  syntax_error:
01327   /*@-usereleased@*/
01328   if (stack != init_stack)
01329     {
01330       sfree (stack);
01331       /*@-branchstate@*/
01332     } /*@=branchstate@*/
01333   /*@=usereleased@*/
01334 
01335   cppReader_skipRestOfLine (pfile);
01336   return 0;
01337 }

struct operation cppReader_parseNumber ( cppReader * pfile,
char * start,
int olen )
 

Definition at line 243 of file cppexp.c.

00244 {
00245   struct operation op;
00246   char *p = start;
00247   char c;
00248   int i;
00249   long n = 0;
00250   unsigned long nd, ULONG_MAX_over_base;
00251   int base = 10;
00252   int len = olen;
00253   bool overflow = FALSE;
00254   int digit, largest_digit = 0;
00255   bool spec_long = FALSE;
00256 
00257   op.unsignedp = FALSE;
00258 
00259   for (i = 0; i < len; i++)
00260     {
00261       if (p[i] == '.') {
00262         /* It's a float since it contains a point.  */
00263         cppReader_errorLit
00264           (pfile,
00265            cstring_makeLiteralTemp
00266            ("Floating point numbers not allowed in #if expressions"));
00267         op.op = CPPREADER_ERRORTOK;
00268         return op;
00269       }
00270     }
00271       
00272   if (len >= 3 && (mstring_equalPrefix (p, "0x") 
00273                    || mstring_equalPrefix (p, "0X")))
00274     {
00275       p += 2;
00276       base = 16;
00277       len -= 2;
00278     }
00279   else if (*p == '0')
00280     {
00281       base = 8;
00282     }
00283   else
00284     {
00285       ;
00286     }
00287 
00288   /* Some buggy compilers (e.g. MPW C) seem to need both casts.  */
00289   ULONG_MAX_over_base = ((unsigned long) -1) / ((unsigned long) base);
00290 
00291   for (; len > 0; len--) {
00292     c = *p++;
00293 
00294     if (c >= '0' && c <= '9')
00295       {
00296         digit = (int) (c - '0');
00297       }
00298     else if (base == 16 && c >= 'a' && c <= 'f')
00299       {
00300         digit = (int) (c - 'a') + 10;
00301       }
00302     else if (base == 16 && c >= 'A' && c <= 'F')
00303       {
00304         digit = (int) (c - 'A') + 10;
00305       }
00306     else 
00307       {
00308         /* `l' means long, and `u' means unsigned.  */
00309         while (TRUE)
00310           {
00311             if (c == 'l' || c == 'L')
00312               {
00313                 if (spec_long)
00314                   cppReader_errorLit (pfile,
00315                                       cstring_makeLiteralTemp ("two `l's in integer constant"));
00316                 spec_long = TRUE;
00317               }
00318             else if (c == 'u' || c == 'U')
00319               {
00320                 if (op.unsignedp)
00321                   cppReader_errorLit (pfile, 
00322                                       cstring_makeLiteralTemp ("two `u's in integer constant"));
00323                 op.unsignedp = TRUE;
00324               }
00325             else
00326               {
00327                 /*@innerbreak@*/ break;
00328               }
00329             
00330             if (--len == 0)
00331               {
00332                 /*@innerbreak@*/ break;
00333               }
00334 
00335             c = *p++;
00336           }
00337         /* Don't look for any more digits after the suffixes.  */
00338         break;
00339       }
00340     
00341     if (largest_digit < digit)
00342       {
00343         largest_digit = digit;
00344       }
00345     
00346     nd = (long unsigned) (n * base + digit);
00347     overflow |= (ULONG_MAX_over_base < (unsigned long) n) 
00348       | (nd < (unsigned long) n);
00349     n = (long) nd;
00350   }
00351 
00352   if (len != 0)
00353     {
00354       cppReader_errorLit 
00355         (pfile, 
00356          cstring_makeLiteralTemp ("Invalid number in #if expression"));
00357       op.op = CPPREADER_ERRORTOK;
00358       return op;
00359     }
00360   
00361   if (base <= largest_digit)
00362     {
00363       cppReader_pedwarnLit 
00364         (pfile, 
00365          cstring_makeLiteralTemp 
00366          ("Integer constant contains digits beyond the radix"));
00367     }
00368   
00369   if (overflow)
00370     {
00371       cppReader_pedwarnLit
00372         (pfile, 
00373          cstring_makeLiteralTemp ("Integer constant out of range"));
00374     }
00375 
00376   /* If too big to be signed, consider it unsigned.  */
00377   if ((long) n < 0 && ! op.unsignedp)
00378     {
00379       if (base == 10)
00380         {
00381           cppReader_warningLit
00382             (pfile,
00383              cstring_makeLiteralTemp ("Integer constant is so large that it is unsigned"));
00384         }
00385          
00386       op.unsignedp = TRUE;
00387     }
00388   
00389   op.value = n;
00390   op.op = CPPEXP_INT;
00391   return op;
00392 }


Generated at Fri Nov 3 18:57:53 2000 for LCLint by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000