diff options
Diffstat (limited to 'ioq3-r437/src/tools/lcc/cpp/eval.c')
-rw-r--r-- | ioq3-r437/src/tools/lcc/cpp/eval.c | 520 |
1 files changed, 0 insertions, 520 deletions
diff --git a/ioq3-r437/src/tools/lcc/cpp/eval.c b/ioq3-r437/src/tools/lcc/cpp/eval.c deleted file mode 100644 index 7061effd..00000000 --- a/ioq3-r437/src/tools/lcc/cpp/eval.c +++ /dev/null @@ -1,520 +0,0 @@ -#include <stdlib.h> -#include <string.h> -#include "cpp.h" - -#define NSTAK 32 -#define SGN 0 -#define UNS 1 -#define UND 2 - -#define UNSMARK 0x1000 - -struct value { - long val; - int type; -}; - -/* conversion types */ -#define RELAT 1 -#define ARITH 2 -#define LOGIC 3 -#define SPCL 4 -#define SHIFT 5 -#define UNARY 6 - -/* operator priority, arity, and conversion type, indexed by tokentype */ -struct pri { - char pri; - char arity; - char ctype; -} priority[] = { - { 0, 0, 0 }, /* END */ - { 0, 0, 0 }, /* UNCLASS */ - { 0, 0, 0 }, /* NAME */ - { 0, 0, 0 }, /* NUMBER */ - { 0, 0, 0 }, /* STRING */ - { 0, 0, 0 }, /* CCON */ - { 0, 0, 0 }, /* NL */ - { 0, 0, 0 }, /* WS */ - { 0, 0, 0 }, /* DSHARP */ - { 11, 2, RELAT }, /* EQ */ - { 11, 2, RELAT }, /* NEQ */ - { 12, 2, RELAT }, /* LEQ */ - { 12, 2, RELAT }, /* GEQ */ - { 13, 2, SHIFT }, /* LSH */ - { 13, 2, SHIFT }, /* RSH */ - { 7, 2, LOGIC }, /* LAND */ - { 6, 2, LOGIC }, /* LOR */ - { 0, 0, 0 }, /* PPLUS */ - { 0, 0, 0 }, /* MMINUS */ - { 0, 0, 0 }, /* ARROW */ - { 0, 0, 0 }, /* SBRA */ - { 0, 0, 0 }, /* SKET */ - { 3, 0, 0 }, /* LP */ - { 3, 0, 0 }, /* RP */ - { 0, 0, 0 }, /* DOT */ - { 10, 2, ARITH }, /* AND */ - { 15, 2, ARITH }, /* STAR */ - { 14, 2, ARITH }, /* PLUS */ - { 14, 2, ARITH }, /* MINUS */ - { 16, 1, UNARY }, /* TILDE */ - { 16, 1, UNARY }, /* NOT */ - { 15, 2, ARITH }, /* SLASH */ - { 15, 2, ARITH }, /* PCT */ - { 12, 2, RELAT }, /* LT */ - { 12, 2, RELAT }, /* GT */ - { 9, 2, ARITH }, /* CIRC */ - { 8, 2, ARITH }, /* OR */ - { 5, 2, SPCL }, /* QUEST */ - { 5, 2, SPCL }, /* COLON */ - { 0, 0, 0 }, /* ASGN */ - { 4, 2, 0 }, /* COMMA */ - { 0, 0, 0 }, /* SHARP */ - { 0, 0, 0 }, /* SEMIC */ - { 0, 0, 0 }, /* CBRA */ - { 0, 0, 0 }, /* CKET */ - { 0, 0, 0 }, /* ASPLUS */ - { 0, 0, 0 }, /* ASMINUS */ - { 0, 0, 0 }, /* ASSTAR */ - { 0, 0, 0 }, /* ASSLASH */ - { 0, 0, 0 }, /* ASPCT */ - { 0, 0, 0 }, /* ASCIRC */ - { 0, 0, 0 }, /* ASLSH */ - { 0, 0, 0 }, /* ASRSH */ - { 0, 0, 0 }, /* ASOR */ - { 0, 0, 0 }, /* ASAND */ - { 0, 0, 0 }, /* ELLIPS */ - { 0, 0, 0 }, /* DSHARP1 */ - { 0, 0, 0 }, /* NAME1 */ - { 16, 1, UNARY }, /* DEFINED */ - { 16, 0, UNARY }, /* UMINUS */ -}; - -int evalop(struct pri); -struct value tokval(Token *); -struct value vals[NSTAK], *vp; -enum toktype ops[NSTAK], *op; - -/* - * Evaluate an #if #elif #ifdef #ifndef line. trp->tp points to the keyword. - */ -long -eval(Tokenrow *trp, int kw) -{ - Token *tp; - Nlist *np; - int ntok, rand; - - trp->tp++; - if (kw==KIFDEF || kw==KIFNDEF) { - if (trp->lp - trp->bp != 4 || trp->tp->type!=NAME) { - error(ERROR, "Syntax error in #ifdef/#ifndef"); - return 0; - } - np = lookup(trp->tp, 0); - return (kw==KIFDEF) == (np && np->flag&(ISDEFINED|ISMAC)); - } - ntok = trp->tp - trp->bp; - kwdefined->val = KDEFINED; /* activate special meaning of defined */ - expandrow(trp, "<if>"); - kwdefined->val = NAME; - vp = vals; - op = ops; - *op++ = END; - for (rand=0, tp = trp->bp+ntok; tp < trp->lp; tp++) { - switch(tp->type) { - case WS: - case NL: - continue; - - /* nilary */ - case NAME: - case NAME1: - case NUMBER: - case CCON: - case STRING: - if (rand) - goto syntax; - *vp++ = tokval(tp); - rand = 1; - continue; - - /* unary */ - case DEFINED: - case TILDE: - case NOT: - if (rand) - goto syntax; - *op++ = tp->type; - continue; - - /* unary-binary */ - case PLUS: case MINUS: case STAR: case AND: - if (rand==0) { - if (tp->type==MINUS) - *op++ = UMINUS; - if (tp->type==STAR || tp->type==AND) { - error(ERROR, "Illegal operator * or & in #if/#elsif"); - return 0; - } - continue; - } - /* flow through */ - - /* plain binary */ - case EQ: case NEQ: case LEQ: case GEQ: case LSH: case RSH: - case LAND: case LOR: case SLASH: case PCT: - case LT: case GT: case CIRC: case OR: case QUEST: - case COLON: case COMMA: - if (rand==0) - goto syntax; - if (evalop(priority[tp->type])!=0) - return 0; - *op++ = tp->type; - rand = 0; - continue; - - case LP: - if (rand) - goto syntax; - *op++ = LP; - continue; - - case RP: - if (!rand) - goto syntax; - if (evalop(priority[RP])!=0) - return 0; - if (op<=ops || op[-1]!=LP) { - goto syntax; - } - op--; - continue; - - default: - error(ERROR,"Bad operator (%t) in #if/#elsif", tp); - return 0; - } - } - if (rand==0) - goto syntax; - if (evalop(priority[END])!=0) - return 0; - if (op!=&ops[1] || vp!=&vals[1]) { - error(ERROR, "Botch in #if/#elsif"); - return 0; - } - if (vals[0].type==UND) - error(ERROR, "Undefined expression value"); - return vals[0].val; -syntax: - error(ERROR, "Syntax error in #if/#elsif"); - return 0; -} - -int -evalop(struct pri pri) -{ - struct value v1, v2; - long rv1, rv2; - int rtype, oper; - - rv2=0; - rtype=0; - while (pri.pri < priority[op[-1]].pri) { - oper = *--op; - if (priority[oper].arity==2) { - v2 = *--vp; - rv2 = v2.val; - } - v1 = *--vp; - rv1 = v1.val; -/*lint -e574 -e644 */ - switch (priority[oper].ctype) { - case 0: - default: - error(WARNING, "Syntax error in #if/#endif"); - return 1; - case ARITH: - case RELAT: - if (v1.type==UNS || v2.type==UNS) - rtype = UNS; - else - rtype = SGN; - if (v1.type==UND || v2.type==UND) - rtype = UND; - if (priority[oper].ctype==RELAT && rtype==UNS) { - oper |= UNSMARK; - rtype = SGN; - } - break; - case SHIFT: - if (v1.type==UND || v2.type==UND) - rtype = UND; - else - rtype = v1.type; - if (rtype==UNS) - oper |= UNSMARK; - break; - case UNARY: - rtype = v1.type; - break; - case LOGIC: - case SPCL: - break; - } - switch (oper) { - case EQ: case EQ|UNSMARK: - rv1 = rv1==rv2; break; - case NEQ: case NEQ|UNSMARK: - rv1 = rv1!=rv2; break; - case LEQ: - rv1 = rv1<=rv2; break; - case GEQ: - rv1 = rv1>=rv2; break; - case LT: - rv1 = rv1<rv2; break; - case GT: - rv1 = rv1>rv2; break; - case LEQ|UNSMARK: - rv1 = (unsigned long)rv1<=rv2; break; - case GEQ|UNSMARK: - rv1 = (unsigned long)rv1>=rv2; break; - case LT|UNSMARK: - rv1 = (unsigned long)rv1<rv2; break; - case GT|UNSMARK: - rv1 = (unsigned long)rv1>rv2; break; - case LSH: - rv1 <<= rv2; break; - case LSH|UNSMARK: - rv1 = (unsigned long)rv1<<rv2; break; - case RSH: - rv1 >>= rv2; break; - case RSH|UNSMARK: - rv1 = (unsigned long)rv1>>rv2; break; - case LAND: - rtype = UND; - if (v1.type==UND) - break; - if (rv1!=0) { - if (v2.type==UND) - break; - rv1 = rv2!=0; - } else - rv1 = 0; - rtype = SGN; - break; - case LOR: - rtype = UND; - if (v1.type==UND) - break; - if (rv1==0) { - if (v2.type==UND) - break; - rv1 = rv2!=0; - } else - rv1 = 1; - rtype = SGN; - break; - case AND: - rv1 &= rv2; break; - case STAR: - rv1 *= rv2; break; - case PLUS: - rv1 += rv2; break; - case MINUS: - rv1 -= rv2; break; - case UMINUS: - if (v1.type==UND) - rtype = UND; - rv1 = -rv1; break; - case OR: - rv1 |= rv2; break; - case CIRC: - rv1 ^= rv2; break; - case TILDE: - rv1 = ~rv1; break; - case NOT: - rv1 = !rv1; if (rtype!=UND) rtype = SGN; break; - case SLASH: - if (rv2==0) { - rtype = UND; - break; - } - if (rtype==UNS) - rv1 /= (unsigned long)rv2; - else - rv1 /= rv2; - break; - case PCT: - if (rv2==0) { - rtype = UND; - break; - } - if (rtype==UNS) - rv1 %= (unsigned long)rv2; - else - rv1 %= rv2; - break; - case COLON: - if (op[-1] != QUEST) - error(ERROR, "Bad ?: in #if/endif"); - else { - op--; - if ((--vp)->val==0) - v1 = v2; - rtype = v1.type; - rv1 = v1.val; - } - break; - case DEFINED: - break; - default: - error(ERROR, "Eval botch (unknown operator)"); - return 1; - } -/*lint +e574 +e644 */ - v1.val = rv1; - v1.type = rtype; - *vp++ = v1; - } - return 0; -} - -struct value -tokval(Token *tp) -{ - struct value v; - Nlist *np; - int i, base, c; - unsigned long n; - uchar *p; - - v.type = SGN; - v.val = 0; - switch (tp->type) { - - case NAME: - v.val = 0; - break; - - case NAME1: - if ((np = lookup(tp, 0)) != NULL && np->flag&(ISDEFINED|ISMAC)) - v.val = 1; - break; - - case NUMBER: - n = 0; - base = 10; - p = tp->t; - c = p[tp->len]; - p[tp->len] = '\0'; - if (*p=='0') { - base = 8; - if (p[1]=='x' || p[1]=='X') { - base = 16; - p++; - } - p++; - } - for (;; p++) { - if ((i = digit(*p)) < 0) - break; - if (i>=base) - error(WARNING, - "Bad digit in number %t", tp); - n *= base; - n += i; - } - if (n>=0x80000000 && base!=10) - v.type = UNS; - for (; *p; p++) { - if (*p=='u' || *p=='U') - v.type = UNS; - else if (*p=='l' || *p=='L') - ; - else { - error(ERROR, - "Bad number %t in #if/#elsif", tp); - break; - } - } - v.val = n; - tp->t[tp->len] = c; - break; - - case CCON: - n = 0; - p = tp->t; - if (*p=='L') { - p += 1; - error(WARNING, "Wide char constant value undefined"); - } - p += 1; - if (*p=='\\') { - p += 1; - if ((i = digit(*p))>=0 && i<=7) { - n = i; - p += 1; - if ((i = digit(*p))>=0 && i<=7) { - p += 1; - n <<= 3; - n += i; - if ((i = digit(*p))>=0 && i<=7) { - p += 1; - n <<= 3; - n += i; - } - } - } else if (*p=='x') { - p += 1; - while ((i = digit(*p))>=0 && i<=15) { - p += 1; - n <<= 4; - n += i; - } - } else { - static char cvcon[] - = "b\bf\fn\nr\rt\tv\v''\"\"??\\\\"; - for (i=0; i<sizeof(cvcon); i+=2) { - if (*p == cvcon[i]) { - n = cvcon[i+1]; - break; - } - } - p += 1; - if (i>=sizeof(cvcon)) - error(WARNING, - "Undefined escape in character constant"); - } - } else if (*p=='\'') - error(ERROR, "Empty character constant"); - else - n = *p++; - if (*p!='\'') - error(WARNING, "Multibyte character constant undefined"); - else if (n>127) - error(WARNING, "Character constant taken as not signed"); - v.val = n; - break; - - case STRING: - error(ERROR, "String in #if/#elsif"); - break; - } - return v; -} - -int -digit(int i) -{ - if ('0'<=i && i<='9') - i -= '0'; - else if ('a'<=i && i<='f') - i -= 'a'-10; - else if ('A'<=i && i<='F') - i -= 'A'-10; - else - i = -1; - return i; -} |