Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

eval.c (9815B)


      1 #include <stdlib.h>
      2 #include <string.h>
      3 #include "cpp.h"
      4 
      5 #define	NSTAK	32
      6 #define	SGN	0
      7 #define	UNS	1
      8 #define	UND	2
      9 
     10 #define	UNSMARK	0x1000
     11 
     12 struct value {
     13 	long	val;
     14 	int	type;
     15 };
     16 
     17 /* conversion types */
     18 #define	RELAT	1
     19 #define	ARITH	2
     20 #define	LOGIC	3
     21 #define	SPCL	4
     22 #define	SHIFT	5
     23 #define	UNARY	6
     24 
     25 /* operator priority, arity, and conversion type, indexed by tokentype */
     26 struct pri {
     27 	char	pri;
     28 	char	arity;
     29 	char	ctype;
     30 } priority[] = {
     31 	{ 0, 0, 0 },		/* END */
     32 	{ 0, 0, 0 },		/* UNCLASS */
     33 	{ 0, 0, 0 },		/* NAME */
     34 	{ 0, 0, 0 },		/* NUMBER */
     35 	{ 0, 0, 0 },		/* STRING */
     36 	{ 0, 0, 0 },		/* CCON */
     37 	{ 0, 0, 0 },		/* NL */
     38 	{ 0, 0, 0 },		/* WS */
     39 	{ 0, 0, 0 },		/* DSHARP */
     40 	{ 11, 2, RELAT },	/* EQ */
     41 	{ 11, 2, RELAT },	/* NEQ */
     42 	{ 12, 2, RELAT },	/* LEQ */
     43 	{ 12, 2, RELAT },	/* GEQ */
     44 	{ 13, 2, SHIFT },	/* LSH */
     45 	{ 13, 2, SHIFT },	/* RSH */
     46 	{ 7, 2, LOGIC },	/* LAND */
     47 	{ 6, 2, LOGIC },	/* LOR */
     48 	{ 0, 0, 0 },		/* PPLUS */
     49 	{ 0, 0, 0 },		/* MMINUS */
     50 	{ 0, 0, 0 },		/* ARROW */
     51 	{ 0, 0, 0 },		/* SBRA */
     52 	{ 0, 0, 0 },		/* SKET */
     53 	{ 3, 0, 0 },		/* LP */
     54 	{ 3, 0, 0 },		/* RP */
     55 	{ 0, 0, 0 },		/* DOT */
     56 	{ 10, 2, ARITH },	/* AND */
     57 	{ 15, 2, ARITH },	/* STAR */
     58 	{ 14, 2, ARITH },	/* PLUS */
     59 	{ 14, 2, ARITH },	/* MINUS */
     60 	{ 16, 1, UNARY },	/* TILDE */
     61 	{ 16, 1, UNARY },	/* NOT */
     62 	{ 15, 2, ARITH },	/* SLASH */
     63 	{ 15, 2, ARITH },	/* PCT */
     64 	{ 12, 2, RELAT },	/* LT */
     65 	{ 12, 2, RELAT },	/* GT */
     66 	{ 9, 2, ARITH },	/* CIRC */
     67 	{ 8, 2, ARITH },	/* OR */
     68 	{ 5, 2, SPCL },		/* QUEST */
     69 	{ 5, 2, SPCL },		/* COLON */
     70 	{ 0, 0, 0 },		/* ASGN */
     71 	{ 4, 2, 0 },		/* COMMA */
     72 	{ 0, 0, 0 },		/* SHARP */
     73 	{ 0, 0, 0 },		/* SEMIC */
     74 	{ 0, 0, 0 },		/* CBRA */
     75 	{ 0, 0, 0 },		/* CKET */
     76 	{ 0, 0, 0 },		/* ASPLUS */
     77  	{ 0, 0, 0 },		/* ASMINUS */
     78  	{ 0, 0, 0 },		/* ASSTAR */
     79  	{ 0, 0, 0 },		/* ASSLASH */
     80  	{ 0, 0, 0 },		/* ASPCT */
     81  	{ 0, 0, 0 },		/* ASCIRC */
     82  	{ 0, 0, 0 },		/* ASLSH */
     83 	{ 0, 0, 0 },		/* ASRSH */
     84  	{ 0, 0, 0 },		/* ASOR */
     85  	{ 0, 0, 0 },		/* ASAND */
     86 	{ 0, 0, 0 },		/* ELLIPS */
     87 	{ 0, 0, 0 },		/* DSHARP1 */
     88 	{ 0, 0, 0 },		/* NAME1 */
     89 	{ 16, 1, UNARY },	/* DEFINED */
     90 	{ 16, 0, UNARY },	/* UMINUS */
     91 };
     92 
     93 int	evalop(struct pri);
     94 struct	value tokval(Token *);
     95 struct value vals[NSTAK], *vp;
     96 enum toktype ops[NSTAK], *op;
     97 
     98 /*
     99  * Evaluate an #if #elif #ifdef #ifndef line.  trp->tp points to the keyword.
    100  */
    101 long
    102 eval(Tokenrow *trp, int kw)
    103 {
    104 	Token *tp;
    105 	Nlist *np;
    106 	int ntok, rand;
    107 
    108 	trp->tp++;
    109 	if (kw==KIFDEF || kw==KIFNDEF) {
    110 		if (trp->lp - trp->bp != 4 || trp->tp->type!=NAME) {
    111 			error(ERROR, "Syntax error in #ifdef/#ifndef");
    112 			return 0;
    113 		}
    114 		np = lookup(trp->tp, 0);
    115 		return (kw==KIFDEF) == (np && np->flag&(ISDEFINED|ISMAC));
    116 	}
    117 	ntok = trp->tp - trp->bp;
    118 	kwdefined->val = KDEFINED;	/* activate special meaning of defined */
    119 	expandrow(trp, "<if>");
    120 	kwdefined->val = NAME;
    121 	vp = vals;
    122 	op = ops;
    123 	*op++ = END;
    124 	for (rand=0, tp = trp->bp+ntok; tp < trp->lp; tp++) {
    125 		switch(tp->type) {
    126 		case WS:
    127 		case NL:
    128 			continue;
    129 
    130 		/* nilary */
    131 		case NAME:
    132 		case NAME1:
    133 		case NUMBER:
    134 		case CCON:
    135 		case STRING:
    136 			if (rand)
    137 				goto syntax;
    138 			*vp++ = tokval(tp);
    139 			rand = 1;
    140 			continue;
    141 
    142 		/* unary */
    143 		case DEFINED:
    144 		case TILDE:
    145 		case NOT:
    146 			if (rand)
    147 				goto syntax;
    148 			*op++ = tp->type;
    149 			continue;
    150 
    151 		/* unary-binary */
    152 		case PLUS: case MINUS: case STAR: case AND:
    153 			if (rand==0) {
    154 				if (tp->type==MINUS)
    155 					*op++ = UMINUS;
    156 				if (tp->type==STAR || tp->type==AND) {
    157 					error(ERROR, "Illegal operator * or & in #if/#elsif");
    158 					return 0;
    159 				}
    160 				continue;
    161 			}
    162 			/* flow through */
    163 
    164 		/* plain binary */
    165 		case EQ: case NEQ: case LEQ: case GEQ: case LSH: case RSH:
    166 		case LAND: case LOR: case SLASH: case PCT:
    167 		case LT: case GT: case CIRC: case OR: case QUEST:
    168 		case COLON: case COMMA:
    169 			if (rand==0)
    170 				goto syntax;
    171 			if (evalop(priority[tp->type])!=0)
    172 				return 0;
    173 			*op++ = tp->type;
    174 			rand = 0;
    175 			continue;
    176 
    177 		case LP:
    178 			if (rand)
    179 				goto syntax;
    180 			*op++ = LP;
    181 			continue;
    182 
    183 		case RP:
    184 			if (!rand)
    185 				goto syntax;
    186 			if (evalop(priority[RP])!=0)
    187 				return 0;
    188 			if (op<=ops || op[-1]!=LP) {
    189 				goto syntax;
    190 			}
    191 			op--;
    192 			continue;
    193 
    194 		default:
    195 			error(ERROR,"Bad operator (%t) in #if/#elsif", tp);
    196 			return 0;
    197 		}
    198 	}
    199 	if (rand==0)
    200 		goto syntax;
    201 	if (evalop(priority[END])!=0)
    202 		return 0;
    203 	if (op!=&ops[1] || vp!=&vals[1]) {
    204 		error(ERROR, "Botch in #if/#elsif");
    205 		return 0;
    206 	}
    207 	if (vals[0].type==UND)
    208 		error(ERROR, "Undefined expression value");
    209 	return vals[0].val;
    210 syntax:
    211 	error(ERROR, "Syntax error in #if/#elsif");
    212 	return 0;
    213 }
    214 
    215 int
    216 evalop(struct pri pri)
    217 {
    218 	struct value v1, v2;
    219 	long rv1, rv2;
    220 	int rtype, oper;
    221 
    222 	rv2=0;
    223 	rtype=0;
    224 	while (pri.pri < priority[op[-1]].pri) {
    225 		oper = *--op;
    226 		if (priority[oper].arity==2) {
    227 			v2 = *--vp;
    228 			rv2 = v2.val;
    229 		}
    230 		v1 = *--vp;
    231 		rv1 = v1.val;
    232 /*lint -e574 -e644 */
    233 		switch (priority[oper].ctype) {
    234 		case 0:
    235 		default:
    236 			error(WARNING, "Syntax error in #if/#endif");
    237 			return 1;
    238 		case ARITH:
    239 		case RELAT:
    240 			if (v1.type==UNS || v2.type==UNS)
    241 				rtype = UNS;
    242 			else
    243 				rtype = SGN;
    244 			if (v1.type==UND || v2.type==UND)
    245 				rtype = UND;
    246 			if (priority[oper].ctype==RELAT && rtype==UNS) {
    247 				oper |= UNSMARK;
    248 				rtype = SGN;
    249 			}
    250 			break;
    251 		case SHIFT:
    252 			if (v1.type==UND || v2.type==UND)
    253 				rtype = UND;
    254 			else
    255 				rtype = v1.type;
    256 			if (rtype==UNS)
    257 				oper |= UNSMARK;
    258 			break;
    259 		case UNARY:
    260 			rtype = v1.type;
    261 			break;
    262 		case LOGIC:
    263 		case SPCL:
    264 			break;
    265 		}
    266 		switch (oper) {
    267 		case EQ: case EQ|UNSMARK:
    268 			rv1 = rv1==rv2; break;
    269 		case NEQ: case NEQ|UNSMARK:
    270 			rv1 = rv1!=rv2; break;
    271 		case LEQ:
    272 			rv1 = rv1<=rv2; break;
    273 		case GEQ:
    274 			rv1 = rv1>=rv2; break;
    275 		case LT:
    276 			rv1 = rv1<rv2; break;
    277 		case GT:
    278 			rv1 = rv1>rv2; break;
    279 		case LEQ|UNSMARK:
    280 			rv1 = (unsigned long)rv1<=rv2; break;
    281 		case GEQ|UNSMARK:
    282 			rv1 = (unsigned long)rv1>=rv2; break;
    283 		case LT|UNSMARK:
    284 			rv1 = (unsigned long)rv1<rv2; break;
    285 		case GT|UNSMARK:
    286 			rv1 = (unsigned long)rv1>rv2; break;
    287 		case LSH:
    288 			rv1 <<= rv2; break;
    289 		case LSH|UNSMARK:
    290 			rv1 = (unsigned long)rv1<<rv2; break;
    291 		case RSH:
    292 			rv1 >>= rv2; break;
    293 		case RSH|UNSMARK:
    294 			rv1 = (unsigned long)rv1>>rv2; break;
    295 		case LAND:
    296 			rtype = UND;
    297 			if (v1.type==UND)
    298 				break;
    299 			if (rv1!=0) {
    300 				if (v2.type==UND)
    301 					break;
    302 				rv1 = rv2!=0;
    303 			} else
    304 				rv1 = 0;
    305 			rtype = SGN;
    306 			break;
    307 		case LOR:
    308 			rtype = UND;
    309 			if (v1.type==UND)
    310 				break;
    311 			if (rv1==0) {
    312 				if (v2.type==UND)
    313 					break;
    314 				rv1 = rv2!=0;
    315 			} else
    316 				rv1 = 1;
    317 			rtype = SGN;
    318 			break;
    319 		case AND:
    320 			rv1 &= rv2; break;
    321 		case STAR:
    322 			rv1 *= rv2; break;
    323 		case PLUS:
    324 			rv1 += rv2; break;
    325 		case MINUS:
    326 			rv1 -= rv2; break;
    327 		case UMINUS:
    328 			if (v1.type==UND)
    329 				rtype = UND;
    330 			rv1 = -rv1; break;
    331 		case OR:
    332 			rv1 |= rv2; break;
    333 		case CIRC:
    334 			rv1 ^= rv2; break;
    335 		case TILDE:
    336 			rv1 = ~rv1; break;
    337 		case NOT:
    338 			rv1 = !rv1; if (rtype!=UND) rtype = SGN; break;
    339 		case SLASH:
    340 			if (rv2==0) {
    341 				rtype = UND;
    342 				break;
    343 			}
    344 			if (rtype==UNS)
    345 				rv1 /= (unsigned long)rv2;
    346 			else
    347 				rv1 /= rv2;
    348 			break;
    349 		case PCT:
    350 			if (rv2==0) {
    351 				rtype = UND;
    352 				break;
    353 			}
    354 			if (rtype==UNS)
    355 				rv1 %= (unsigned long)rv2;
    356 			else
    357 				rv1 %= rv2;
    358 			break;
    359 		case COLON:
    360 			if (op[-1] != QUEST)
    361 				error(ERROR, "Bad ?: in #if/endif");
    362 			else {
    363 				op--;
    364 				if ((--vp)->val==0)
    365 					v1 = v2;
    366 				rtype = v1.type;
    367 				rv1 = v1.val;
    368 			}
    369 			break;
    370 		case DEFINED:
    371 			break;
    372 		default:
    373 			error(ERROR, "Eval botch (unknown operator)");
    374 			return 1;
    375 		}
    376 /*lint +e574 +e644 */
    377 		v1.val = rv1;
    378 		v1.type = rtype;
    379 		*vp++ = v1;
    380 	}
    381 	return 0;
    382 }
    383 
    384 struct value
    385 tokval(Token *tp)
    386 {
    387 	struct value v;
    388 	Nlist *np;
    389 	int i, base, c;
    390 	unsigned long n;
    391 	uchar *p;
    392 
    393 	v.type = SGN;
    394 	v.val = 0;
    395 	switch (tp->type) {
    396 
    397 	case NAME:
    398 		v.val = 0;
    399 		break;
    400 
    401 	case NAME1:
    402 		if ((np = lookup(tp, 0)) != NULL && np->flag&(ISDEFINED|ISMAC))
    403 			v.val = 1;
    404 		break;
    405 
    406 	case NUMBER:
    407 		n = 0;
    408 		base = 10;
    409 		p = tp->t;
    410 		c = p[tp->len];
    411 		p[tp->len] = '\0';
    412 		if (*p=='0') {
    413 			base = 8;
    414 			if (p[1]=='x' || p[1]=='X') {
    415 				base = 16;
    416 				p++;
    417 			}
    418 			p++;
    419 		}
    420 		for (;; p++) {
    421 			if ((i = digit(*p)) < 0)
    422 				break;
    423 			if (i>=base)
    424 				error(WARNING,
    425 				  "Bad digit in number %t", tp);
    426 			n *= base;
    427 			n += i;
    428 		}
    429 		if (n>=0x80000000 && base!=10)
    430 			v.type = UNS;
    431 		for (; *p; p++) {
    432 			if (*p=='u' || *p=='U')
    433 				v.type = UNS;
    434 			else if (*p=='l' || *p=='L')
    435 				;
    436 			else {
    437 				error(ERROR,
    438 				  "Bad number %t in #if/#elsif", tp);
    439 				break;
    440 			}
    441 		}
    442 		v.val = n;
    443 		tp->t[tp->len] = c;
    444 		break;
    445 
    446 	case CCON:
    447 		n = 0;
    448 		p = tp->t;
    449 		if (*p=='L') {
    450 			p += 1;
    451 			error(WARNING, "Wide char constant value undefined");
    452 		}
    453 		p += 1;
    454 		if (*p=='\\') {
    455 			p += 1;
    456 			if ((i = digit(*p))>=0 && i<=7) {
    457 				n = i;
    458 				p += 1;
    459 				if ((i = digit(*p))>=0 && i<=7) {
    460 					p += 1;
    461 					n <<= 3;
    462 					n += i;
    463 					if ((i = digit(*p))>=0 && i<=7) {
    464 						p += 1;
    465 						n <<= 3;
    466 						n += i;
    467 					}
    468 				}
    469 			} else if (*p=='x') {
    470 				p += 1;
    471 				while ((i = digit(*p))>=0 && i<=15) {
    472 					p += 1;
    473 					n <<= 4;
    474 					n += i;
    475 				}
    476 			} else {
    477 				static char cvcon[]
    478 				  = "b\bf\fn\nr\rt\tv\v''\"\"??\\\\";
    479 				for (i=0; i<sizeof(cvcon); i+=2) {
    480 					if (*p == cvcon[i]) {
    481 						n = cvcon[i+1];
    482 						break;
    483 					}
    484 				}
    485 				p += 1;
    486 				if (i>=sizeof(cvcon))
    487 					error(WARNING,
    488 					 "Undefined escape in character constant");
    489 			}
    490 		} else if (*p=='\'')
    491 			error(ERROR, "Empty character constant");
    492 		else
    493 			n = *p++;
    494 		if (*p!='\'')
    495 			error(WARNING, "Multibyte character constant undefined");
    496 		else if (n>127)
    497 			error(WARNING, "Character constant taken as not signed");
    498 		v.val = n;
    499 		break;
    500 
    501 	case STRING:
    502 		error(ERROR, "String in #if/#elsif");
    503 		break;
    504 	}
    505 	return v;
    506 }
    507 
    508 int
    509 digit(int i)
    510 {
    511 	if ('0'<=i && i<='9')
    512 		i -= '0';
    513 	else if ('a'<=i && i<='f')
    514 		i -= 'a'-10;
    515 	else if ('A'<=i && i<='F')
    516 		i -= 'A'-10;
    517 	else
    518 		i = -1;
    519 	return i;
    520 }