1*7ce20373SAndrew Rist /************************************************************** 2*7ce20373SAndrew Rist * 3*7ce20373SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*7ce20373SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*7ce20373SAndrew Rist * distributed with this work for additional information 6*7ce20373SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*7ce20373SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*7ce20373SAndrew Rist * "License"); you may not use this file except in compliance 9*7ce20373SAndrew Rist * with the License. You may obtain a copy of the License at 10*7ce20373SAndrew Rist * 11*7ce20373SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*7ce20373SAndrew Rist * 13*7ce20373SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*7ce20373SAndrew Rist * software distributed under the License is distributed on an 15*7ce20373SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*7ce20373SAndrew Rist * KIND, either express or implied. See the License for the 17*7ce20373SAndrew Rist * specific language governing permissions and limitations 18*7ce20373SAndrew Rist * under the License. 19*7ce20373SAndrew Rist * 20*7ce20373SAndrew Rist *************************************************************/ 21*7ce20373SAndrew Rist 22cdf0e10cSrcweir #include "cpp.h" 23cdf0e10cSrcweir 24cdf0e10cSrcweir #include <stdlib.h> 25cdf0e10cSrcweir #include <string.h> 26cdf0e10cSrcweir 27cdf0e10cSrcweir #define NSTAK 32 28cdf0e10cSrcweir #define SGN 0 29cdf0e10cSrcweir #define UNS 1 30cdf0e10cSrcweir #define UND 2 31cdf0e10cSrcweir 32cdf0e10cSrcweir #define UNSMARK 0x1000 33cdf0e10cSrcweir 34cdf0e10cSrcweir struct value 35cdf0e10cSrcweir { 36cdf0e10cSrcweir long val; 37cdf0e10cSrcweir int type; 38cdf0e10cSrcweir }; 39cdf0e10cSrcweir 40cdf0e10cSrcweir /* conversion types */ 41cdf0e10cSrcweir #define RELAT 1 42cdf0e10cSrcweir #define ARITH 2 43cdf0e10cSrcweir #define LOGIC 3 44cdf0e10cSrcweir #define SPCL 4 45cdf0e10cSrcweir #define SHIFT 5 46cdf0e10cSrcweir #define UNARY 6 47cdf0e10cSrcweir 48cdf0e10cSrcweir /* operator priority, arity, and conversion type, indexed by tokentype */ 49cdf0e10cSrcweir struct pri 50cdf0e10cSrcweir { 51cdf0e10cSrcweir char pri; 52cdf0e10cSrcweir char arity; 53cdf0e10cSrcweir char ctype; 54cdf0e10cSrcweir } priority[] = 55cdf0e10cSrcweir 56cdf0e10cSrcweir { 57cdf0e10cSrcweir { 58cdf0e10cSrcweir 0, 0, 0 59cdf0e10cSrcweir }, /* END */ 60cdf0e10cSrcweir { 61cdf0e10cSrcweir 0, 0, 0 62cdf0e10cSrcweir }, /* UNCLASS */ 63cdf0e10cSrcweir { 64cdf0e10cSrcweir 0, 0, 0 65cdf0e10cSrcweir }, /* NAME */ 66cdf0e10cSrcweir { 67cdf0e10cSrcweir 0, 0, 0 68cdf0e10cSrcweir }, /* NUMBER */ 69cdf0e10cSrcweir { 70cdf0e10cSrcweir 0, 0, 0 71cdf0e10cSrcweir }, /* STRING */ 72cdf0e10cSrcweir { 73cdf0e10cSrcweir 0, 0, 0 74cdf0e10cSrcweir }, /* CCON */ 75cdf0e10cSrcweir { 76cdf0e10cSrcweir 0, 0, 0 77cdf0e10cSrcweir }, /* NL */ 78cdf0e10cSrcweir { 79cdf0e10cSrcweir 0, 0, 0 80cdf0e10cSrcweir }, /* WS */ 81cdf0e10cSrcweir { 82cdf0e10cSrcweir 0, 0, 0 83cdf0e10cSrcweir }, /* DSHARP */ 84cdf0e10cSrcweir { 85cdf0e10cSrcweir 11, 2, RELAT 86cdf0e10cSrcweir }, /* EQ */ 87cdf0e10cSrcweir { 88cdf0e10cSrcweir 11, 2, RELAT 89cdf0e10cSrcweir }, /* NEQ */ 90cdf0e10cSrcweir { 91cdf0e10cSrcweir 12, 2, RELAT 92cdf0e10cSrcweir }, /* LEQ */ 93cdf0e10cSrcweir { 94cdf0e10cSrcweir 12, 2, RELAT 95cdf0e10cSrcweir }, /* GEQ */ 96cdf0e10cSrcweir { 97cdf0e10cSrcweir 13, 2, SHIFT 98cdf0e10cSrcweir }, /* LSH */ 99cdf0e10cSrcweir { 100cdf0e10cSrcweir 13, 2, SHIFT 101cdf0e10cSrcweir }, /* RSH */ 102cdf0e10cSrcweir { 103cdf0e10cSrcweir 7, 2, LOGIC 104cdf0e10cSrcweir }, /* LAND */ 105cdf0e10cSrcweir { 106cdf0e10cSrcweir 6, 2, LOGIC 107cdf0e10cSrcweir }, /* LOR */ 108cdf0e10cSrcweir { 109cdf0e10cSrcweir 0, 0, 0 110cdf0e10cSrcweir }, /* PPLUS */ 111cdf0e10cSrcweir { 112cdf0e10cSrcweir 0, 0, 0 113cdf0e10cSrcweir }, /* MMINUS */ 114cdf0e10cSrcweir { 115cdf0e10cSrcweir 0, 0, 0 116cdf0e10cSrcweir }, /* ARROW */ 117cdf0e10cSrcweir { 118cdf0e10cSrcweir 0, 0, 0 119cdf0e10cSrcweir }, /* SBRA */ 120cdf0e10cSrcweir { 121cdf0e10cSrcweir 0, 0, 0 122cdf0e10cSrcweir }, /* SKET */ 123cdf0e10cSrcweir { 124cdf0e10cSrcweir 3, 0, 0 125cdf0e10cSrcweir }, /* LP */ 126cdf0e10cSrcweir { 127cdf0e10cSrcweir 3, 0, 0 128cdf0e10cSrcweir }, /* RP */ 129cdf0e10cSrcweir { 130cdf0e10cSrcweir 0, 0, 0 131cdf0e10cSrcweir }, /* DOT */ 132cdf0e10cSrcweir { 133cdf0e10cSrcweir 10, 2, ARITH 134cdf0e10cSrcweir }, /* AND */ 135cdf0e10cSrcweir { 136cdf0e10cSrcweir 15, 2, ARITH 137cdf0e10cSrcweir }, /* STAR */ 138cdf0e10cSrcweir { 139cdf0e10cSrcweir 14, 2, ARITH 140cdf0e10cSrcweir }, /* PLUS */ 141cdf0e10cSrcweir { 142cdf0e10cSrcweir 14, 2, ARITH 143cdf0e10cSrcweir }, /* MINUS */ 144cdf0e10cSrcweir { 145cdf0e10cSrcweir 16, 1, UNARY 146cdf0e10cSrcweir }, /* TILDE */ 147cdf0e10cSrcweir { 148cdf0e10cSrcweir 16, 1, UNARY 149cdf0e10cSrcweir }, /* NOT */ 150cdf0e10cSrcweir { 151cdf0e10cSrcweir 15, 2, ARITH 152cdf0e10cSrcweir }, /* SLASH */ 153cdf0e10cSrcweir { 154cdf0e10cSrcweir 15, 2, ARITH 155cdf0e10cSrcweir }, /* PCT */ 156cdf0e10cSrcweir { 157cdf0e10cSrcweir 12, 2, RELAT 158cdf0e10cSrcweir }, /* LT */ 159cdf0e10cSrcweir { 160cdf0e10cSrcweir 12, 2, RELAT 161cdf0e10cSrcweir }, /* GT */ 162cdf0e10cSrcweir { 163cdf0e10cSrcweir 9, 2, ARITH 164cdf0e10cSrcweir }, /* CIRC */ 165cdf0e10cSrcweir { 166cdf0e10cSrcweir 8, 2, ARITH 167cdf0e10cSrcweir }, /* OR */ 168cdf0e10cSrcweir { 169cdf0e10cSrcweir 5, 2, SPCL 170cdf0e10cSrcweir }, /* QUEST */ 171cdf0e10cSrcweir { 172cdf0e10cSrcweir 5, 2, SPCL 173cdf0e10cSrcweir }, /* COLON */ 174cdf0e10cSrcweir { 175cdf0e10cSrcweir 0, 0, 0 176cdf0e10cSrcweir }, /* ASGN */ 177cdf0e10cSrcweir { 178cdf0e10cSrcweir 4, 2, 0 179cdf0e10cSrcweir }, /* COMMA */ 180cdf0e10cSrcweir { 181cdf0e10cSrcweir 0, 0, 0 182cdf0e10cSrcweir }, /* SHARP */ 183cdf0e10cSrcweir { 184cdf0e10cSrcweir 0, 0, 0 185cdf0e10cSrcweir }, /* SEMIC */ 186cdf0e10cSrcweir { 187cdf0e10cSrcweir 0, 0, 0 188cdf0e10cSrcweir }, /* CBRA */ 189cdf0e10cSrcweir { 190cdf0e10cSrcweir 0, 0, 0 191cdf0e10cSrcweir }, /* CKET */ 192cdf0e10cSrcweir { 193cdf0e10cSrcweir 0, 0, 0 194cdf0e10cSrcweir }, /* ASPLUS */ 195cdf0e10cSrcweir { 196cdf0e10cSrcweir 0, 0, 0 197cdf0e10cSrcweir }, /* ASMINUS */ 198cdf0e10cSrcweir { 199cdf0e10cSrcweir 0, 0, 0 200cdf0e10cSrcweir }, /* ASSTAR */ 201cdf0e10cSrcweir { 202cdf0e10cSrcweir 0, 0, 0 203cdf0e10cSrcweir }, /* ASSLASH */ 204cdf0e10cSrcweir { 205cdf0e10cSrcweir 0, 0, 0 206cdf0e10cSrcweir }, /* ASPCT */ 207cdf0e10cSrcweir { 208cdf0e10cSrcweir 0, 0, 0 209cdf0e10cSrcweir }, /* ASCIRC */ 210cdf0e10cSrcweir { 211cdf0e10cSrcweir 0, 0, 0 212cdf0e10cSrcweir }, /* ASLSH */ 213cdf0e10cSrcweir { 214cdf0e10cSrcweir 0, 0, 0 215cdf0e10cSrcweir }, /* ASRSH */ 216cdf0e10cSrcweir { 217cdf0e10cSrcweir 0, 0, 0 218cdf0e10cSrcweir }, /* ASOR */ 219cdf0e10cSrcweir { 220cdf0e10cSrcweir 0, 0, 0 221cdf0e10cSrcweir }, /* ASAND */ 222cdf0e10cSrcweir { 223cdf0e10cSrcweir 0, 0, 0 224cdf0e10cSrcweir }, /* ELLIPS */ 225cdf0e10cSrcweir { 226cdf0e10cSrcweir 0, 0, 0 227cdf0e10cSrcweir }, /* DSHARP1 */ 228cdf0e10cSrcweir { 229cdf0e10cSrcweir 0, 0, 0 230cdf0e10cSrcweir }, /* NAME1 */ 231cdf0e10cSrcweir { 232cdf0e10cSrcweir 0, 0, 0 233cdf0e10cSrcweir }, /* NAME2 */ 234cdf0e10cSrcweir { 235cdf0e10cSrcweir 16, 1, UNARY 236cdf0e10cSrcweir }, /* DEFINED */ 237cdf0e10cSrcweir { 238cdf0e10cSrcweir 16, 0, UNARY 239cdf0e10cSrcweir }, /* UMINUS */ 240cdf0e10cSrcweir { 241cdf0e10cSrcweir 16, 1, UNARY 242cdf0e10cSrcweir }, /* ARCHITECTURE */ 243cdf0e10cSrcweir }; 244cdf0e10cSrcweir 245cdf0e10cSrcweir int evalop(struct pri); 246cdf0e10cSrcweir struct value tokval(Token *); 247cdf0e10cSrcweir struct value vals[NSTAK], *vp; 248cdf0e10cSrcweir enum toktype ops[NSTAK], *op; 249cdf0e10cSrcweir 250cdf0e10cSrcweir /* 251cdf0e10cSrcweir * Evaluate an #if #elif #ifdef #ifndef line. trp->tp points to the keyword. 252cdf0e10cSrcweir */ 253cdf0e10cSrcweir long eval(Tokenrow * trp,int kw)254cdf0e10cSrcweir eval(Tokenrow * trp, int kw) 255cdf0e10cSrcweir { 256cdf0e10cSrcweir Token *tp; 257cdf0e10cSrcweir Nlist *np; 258cdf0e10cSrcweir int ntok, rnd; 259cdf0e10cSrcweir 260cdf0e10cSrcweir trp->tp++; 261cdf0e10cSrcweir if (kw == KIFDEF || kw == KIFNDEF) 262cdf0e10cSrcweir { 263cdf0e10cSrcweir if (trp->lp - trp->bp != 4 || trp->tp->type != NAME) 264cdf0e10cSrcweir { 265cdf0e10cSrcweir error(ERROR, "Syntax error in #ifdef/#ifndef"); 266cdf0e10cSrcweir return 0; 267cdf0e10cSrcweir } 268cdf0e10cSrcweir np = lookup(trp->tp, 0); 269cdf0e10cSrcweir return (kw == KIFDEF) == (np && np->flag & (ISDEFINED | ISMAC)); 270cdf0e10cSrcweir } 271cdf0e10cSrcweir ntok = trp->tp - trp->bp; 272cdf0e10cSrcweir kwdefined->val = KDEFINED; /* activate special meaning of 273cdf0e10cSrcweir * defined */ 274cdf0e10cSrcweir expandrow(trp, "<if>"); 275cdf0e10cSrcweir kwdefined->val = NAME; 276cdf0e10cSrcweir vp = vals; 277cdf0e10cSrcweir op = ops; 278cdf0e10cSrcweir *op++ = END; 279cdf0e10cSrcweir for (rnd = 0, tp = trp->bp + ntok; tp < trp->lp; tp++) 280cdf0e10cSrcweir { 281cdf0e10cSrcweir switch (tp->type) 282cdf0e10cSrcweir { 283cdf0e10cSrcweir case WS: 284cdf0e10cSrcweir case NL: 285cdf0e10cSrcweir continue; 286cdf0e10cSrcweir 287cdf0e10cSrcweir /* nilary */ 288cdf0e10cSrcweir case NAME: 289cdf0e10cSrcweir case NAME1: 290cdf0e10cSrcweir case NAME2: 291cdf0e10cSrcweir case NUMBER: 292cdf0e10cSrcweir case CCON: 293cdf0e10cSrcweir case STRING: 294cdf0e10cSrcweir if (rnd) 295cdf0e10cSrcweir goto syntax; 296cdf0e10cSrcweir *vp++ = tokval(tp); 297cdf0e10cSrcweir rnd = 1; 298cdf0e10cSrcweir continue; 299cdf0e10cSrcweir 300cdf0e10cSrcweir /* unary */ 301cdf0e10cSrcweir case DEFINED: 302cdf0e10cSrcweir case TILDE: 303cdf0e10cSrcweir case NOT: 304cdf0e10cSrcweir if (rnd) 305cdf0e10cSrcweir goto syntax; 306cdf0e10cSrcweir *op++ = tp->type; 307cdf0e10cSrcweir continue; 308cdf0e10cSrcweir 309cdf0e10cSrcweir /* unary-binary */ 310cdf0e10cSrcweir case PLUS: 311cdf0e10cSrcweir case MINUS: 312cdf0e10cSrcweir case STAR: 313cdf0e10cSrcweir case AND: 314cdf0e10cSrcweir if (rnd == 0) 315cdf0e10cSrcweir { 316cdf0e10cSrcweir if (tp->type == MINUS) 317cdf0e10cSrcweir *op++ = UMINUS; 318cdf0e10cSrcweir if (tp->type == STAR || tp->type == AND) 319cdf0e10cSrcweir { 320cdf0e10cSrcweir error(ERROR, "Illegal operator * or & in #if/#elsif"); 321cdf0e10cSrcweir return 0; 322cdf0e10cSrcweir } 323cdf0e10cSrcweir continue; 324cdf0e10cSrcweir } 325cdf0e10cSrcweir /* flow through */ 326cdf0e10cSrcweir 327cdf0e10cSrcweir /* plain binary */ 328cdf0e10cSrcweir case EQ: 329cdf0e10cSrcweir case NEQ: 330cdf0e10cSrcweir case LEQ: 331cdf0e10cSrcweir case GEQ: 332cdf0e10cSrcweir case LSH: 333cdf0e10cSrcweir case RSH: 334cdf0e10cSrcweir case LAND: 335cdf0e10cSrcweir case LOR: 336cdf0e10cSrcweir case SLASH: 337cdf0e10cSrcweir case PCT: 338cdf0e10cSrcweir case LT: 339cdf0e10cSrcweir case GT: 340cdf0e10cSrcweir case CIRC: 341cdf0e10cSrcweir case OR: 342cdf0e10cSrcweir case QUEST: 343cdf0e10cSrcweir case COLON: 344cdf0e10cSrcweir case COMMA: 345cdf0e10cSrcweir if (rnd == 0) 346cdf0e10cSrcweir goto syntax; 347cdf0e10cSrcweir if (evalop(priority[tp->type]) != 0) 348cdf0e10cSrcweir return 0; 349cdf0e10cSrcweir *op++ = tp->type; 350cdf0e10cSrcweir rnd = 0; 351cdf0e10cSrcweir continue; 352cdf0e10cSrcweir 353cdf0e10cSrcweir case LP: 354cdf0e10cSrcweir if (rnd) 355cdf0e10cSrcweir goto syntax; 356cdf0e10cSrcweir *op++ = LP; 357cdf0e10cSrcweir continue; 358cdf0e10cSrcweir 359cdf0e10cSrcweir case RP: 360cdf0e10cSrcweir if (!rnd) 361cdf0e10cSrcweir goto syntax; 362cdf0e10cSrcweir if (evalop(priority[RP]) != 0) 363cdf0e10cSrcweir return 0; 364cdf0e10cSrcweir if (op <= ops || op[-1] != LP) 365cdf0e10cSrcweir { 366cdf0e10cSrcweir goto syntax; 367cdf0e10cSrcweir } 368cdf0e10cSrcweir op--; 369cdf0e10cSrcweir continue; 370cdf0e10cSrcweir 371cdf0e10cSrcweir case SHARP: 372cdf0e10cSrcweir if ((tp + 1) < trp->lp) 373cdf0e10cSrcweir { 374cdf0e10cSrcweir np = lookup(tp + 1, 0); 375cdf0e10cSrcweir if (np && (np->val == KMACHINE)) 376cdf0e10cSrcweir { 377cdf0e10cSrcweir tp++; 378cdf0e10cSrcweir if (rnd) 379cdf0e10cSrcweir goto syntax; 380cdf0e10cSrcweir *op++ = ARCHITECTURE; 381cdf0e10cSrcweir continue; 382cdf0e10cSrcweir } 383cdf0e10cSrcweir } 384cdf0e10cSrcweir /* fall through */ 385cdf0e10cSrcweir 386cdf0e10cSrcweir default: 387cdf0e10cSrcweir error(ERROR, "Bad operator (%t) in #if/#elsif", tp); 388cdf0e10cSrcweir return 0; 389cdf0e10cSrcweir } 390cdf0e10cSrcweir } 391cdf0e10cSrcweir if (rnd == 0) 392cdf0e10cSrcweir goto syntax; 393cdf0e10cSrcweir if (evalop(priority[END]) != 0) 394cdf0e10cSrcweir return 0; 395cdf0e10cSrcweir if (op != &ops[1] || vp != &vals[1]) 396cdf0e10cSrcweir { 397cdf0e10cSrcweir error(ERROR, "Botch in #if/#elsif"); 398cdf0e10cSrcweir return 0; 399cdf0e10cSrcweir } 400cdf0e10cSrcweir if (vals[0].type == UND) 401cdf0e10cSrcweir error(ERROR, "Undefined expression value"); 402cdf0e10cSrcweir return vals[0].val; 403cdf0e10cSrcweir syntax: 404cdf0e10cSrcweir error(ERROR, "Syntax error in #if/#elsif"); 405cdf0e10cSrcweir return 0; 406cdf0e10cSrcweir } 407cdf0e10cSrcweir 408cdf0e10cSrcweir int evalop(struct pri pri)409cdf0e10cSrcweir evalop(struct pri pri) 410cdf0e10cSrcweir { 411cdf0e10cSrcweir struct value v1; 412cdf0e10cSrcweir struct value v2 = { 0, UND }; 413cdf0e10cSrcweir long rv1, rv2; 414cdf0e10cSrcweir int rtype, oper; 415cdf0e10cSrcweir 416cdf0e10cSrcweir rv2 = 0; 417cdf0e10cSrcweir rtype = 0; 418cdf0e10cSrcweir while (pri.pri < priority[op[-1]].pri) 419cdf0e10cSrcweir { 420cdf0e10cSrcweir oper = *--op; 421cdf0e10cSrcweir if (priority[oper].arity == 2) 422cdf0e10cSrcweir { 423cdf0e10cSrcweir v2 = *--vp; 424cdf0e10cSrcweir rv2 = v2.val; 425cdf0e10cSrcweir } 426cdf0e10cSrcweir v1 = *--vp; 427cdf0e10cSrcweir rv1 = v1.val; 428cdf0e10cSrcweir /*lint -e574 -e644 */ 429cdf0e10cSrcweir switch (priority[oper].ctype) 430cdf0e10cSrcweir { 431cdf0e10cSrcweir case 0: 432cdf0e10cSrcweir default: 433cdf0e10cSrcweir error(WARNING, "Syntax error in #if/#endif"); 434cdf0e10cSrcweir return 1; 435cdf0e10cSrcweir case ARITH: 436cdf0e10cSrcweir case RELAT: 437cdf0e10cSrcweir if (v1.type == UNS || v2.type == UNS) 438cdf0e10cSrcweir rtype = UNS; 439cdf0e10cSrcweir else 440cdf0e10cSrcweir rtype = SGN; 441cdf0e10cSrcweir if (v1.type == UND || v2.type == UND) 442cdf0e10cSrcweir rtype = UND; 443cdf0e10cSrcweir if (priority[oper].ctype == RELAT && rtype == UNS) 444cdf0e10cSrcweir { 445cdf0e10cSrcweir oper |= UNSMARK; 446cdf0e10cSrcweir rtype = SGN; 447cdf0e10cSrcweir } 448cdf0e10cSrcweir break; 449cdf0e10cSrcweir case SHIFT: 450cdf0e10cSrcweir if (v1.type == UND || v2.type == UND) 451cdf0e10cSrcweir rtype = UND; 452cdf0e10cSrcweir else 453cdf0e10cSrcweir rtype = v1.type; 454cdf0e10cSrcweir if (rtype == UNS) 455cdf0e10cSrcweir oper |= UNSMARK; 456cdf0e10cSrcweir break; 457cdf0e10cSrcweir case UNARY: 458cdf0e10cSrcweir rtype = v1.type; 459cdf0e10cSrcweir break; 460cdf0e10cSrcweir case LOGIC: 461cdf0e10cSrcweir case SPCL: 462cdf0e10cSrcweir break; 463cdf0e10cSrcweir } 464cdf0e10cSrcweir switch (oper) 465cdf0e10cSrcweir { 466cdf0e10cSrcweir case EQ: 467cdf0e10cSrcweir case EQ | UNSMARK: 468cdf0e10cSrcweir rv1 = rv1 == rv2; 469cdf0e10cSrcweir break; 470cdf0e10cSrcweir case NEQ: 471cdf0e10cSrcweir case NEQ | UNSMARK: 472cdf0e10cSrcweir rv1 = rv1 != rv2; 473cdf0e10cSrcweir break; 474cdf0e10cSrcweir case LEQ: 475cdf0e10cSrcweir rv1 = rv1 <= rv2; 476cdf0e10cSrcweir break; 477cdf0e10cSrcweir case GEQ: 478cdf0e10cSrcweir rv1 = rv1 >= rv2; 479cdf0e10cSrcweir break; 480cdf0e10cSrcweir case LT: 481cdf0e10cSrcweir rv1 = rv1 < rv2; 482cdf0e10cSrcweir break; 483cdf0e10cSrcweir case GT: 484cdf0e10cSrcweir rv1 = rv1 > rv2; 485cdf0e10cSrcweir break; 486cdf0e10cSrcweir case LEQ | UNSMARK: 487cdf0e10cSrcweir rv1 = (unsigned long)rv1 <= (unsigned long)rv2; 488cdf0e10cSrcweir break; 489cdf0e10cSrcweir case GEQ | UNSMARK: 490cdf0e10cSrcweir rv1 = (unsigned long)rv1 >= (unsigned long)rv2; 491cdf0e10cSrcweir break; 492cdf0e10cSrcweir case LT | UNSMARK: 493cdf0e10cSrcweir rv1 = (unsigned long)rv1 < (unsigned long)rv2; 494cdf0e10cSrcweir break; 495cdf0e10cSrcweir case GT | UNSMARK: 496cdf0e10cSrcweir rv1 = (unsigned long)rv1 > (unsigned long)rv2; 497cdf0e10cSrcweir break; 498cdf0e10cSrcweir case LSH: 499cdf0e10cSrcweir rv1 <<= rv2; 500cdf0e10cSrcweir break; 501cdf0e10cSrcweir case LSH | UNSMARK: 502cdf0e10cSrcweir rv1 = (unsigned long) rv1 << rv2; 503cdf0e10cSrcweir break; 504cdf0e10cSrcweir case RSH: 505cdf0e10cSrcweir rv1 >>= rv2; 506cdf0e10cSrcweir break; 507cdf0e10cSrcweir case RSH | UNSMARK: 508cdf0e10cSrcweir rv1 = (unsigned long) rv1 >> rv2; 509cdf0e10cSrcweir break; 510cdf0e10cSrcweir case LAND: 511cdf0e10cSrcweir rtype = UND; 512cdf0e10cSrcweir if (v1.type == UND) 513cdf0e10cSrcweir break; 514cdf0e10cSrcweir if (rv1 != 0) 515cdf0e10cSrcweir { 516cdf0e10cSrcweir if (v2.type == UND) 517cdf0e10cSrcweir break; 518cdf0e10cSrcweir rv1 = rv2 != 0; 519cdf0e10cSrcweir } 520cdf0e10cSrcweir else 521cdf0e10cSrcweir rv1 = 0; 522cdf0e10cSrcweir rtype = SGN; 523cdf0e10cSrcweir break; 524cdf0e10cSrcweir case LOR: 525cdf0e10cSrcweir rtype = UND; 526cdf0e10cSrcweir if (v1.type == UND) 527cdf0e10cSrcweir break; 528cdf0e10cSrcweir if (rv1 == 0) 529cdf0e10cSrcweir { 530cdf0e10cSrcweir if (v2.type == UND) 531cdf0e10cSrcweir break; 532cdf0e10cSrcweir rv1 = rv2 != 0; 533cdf0e10cSrcweir } 534cdf0e10cSrcweir else 535cdf0e10cSrcweir rv1 = 1; 536cdf0e10cSrcweir rtype = SGN; 537cdf0e10cSrcweir break; 538cdf0e10cSrcweir case AND: 539cdf0e10cSrcweir rv1 &= rv2; 540cdf0e10cSrcweir break; 541cdf0e10cSrcweir case STAR: 542cdf0e10cSrcweir rv1 *= rv2; 543cdf0e10cSrcweir break; 544cdf0e10cSrcweir case PLUS: 545cdf0e10cSrcweir rv1 += rv2; 546cdf0e10cSrcweir break; 547cdf0e10cSrcweir case MINUS: 548cdf0e10cSrcweir rv1 -= rv2; 549cdf0e10cSrcweir break; 550cdf0e10cSrcweir case UMINUS: 551cdf0e10cSrcweir if (v1.type == UND) 552cdf0e10cSrcweir rtype = UND; 553cdf0e10cSrcweir rv1 = -rv1; 554cdf0e10cSrcweir break; 555cdf0e10cSrcweir case OR: 556cdf0e10cSrcweir rv1 |= rv2; 557cdf0e10cSrcweir break; 558cdf0e10cSrcweir case CIRC: 559cdf0e10cSrcweir rv1 ^= rv2; 560cdf0e10cSrcweir break; 561cdf0e10cSrcweir case TILDE: 562cdf0e10cSrcweir rv1 = ~rv1; 563cdf0e10cSrcweir break; 564cdf0e10cSrcweir case NOT: 565cdf0e10cSrcweir rv1 = !rv1; 566cdf0e10cSrcweir if (rtype != UND) 567cdf0e10cSrcweir rtype = SGN; 568cdf0e10cSrcweir break; 569cdf0e10cSrcweir case SLASH: 570cdf0e10cSrcweir if (rv2 == 0) 571cdf0e10cSrcweir { 572cdf0e10cSrcweir rtype = UND; 573cdf0e10cSrcweir break; 574cdf0e10cSrcweir } 575cdf0e10cSrcweir if (rtype == UNS) 576cdf0e10cSrcweir rv1 /= (unsigned long) rv2; 577cdf0e10cSrcweir else 578cdf0e10cSrcweir rv1 /= rv2; 579cdf0e10cSrcweir break; 580cdf0e10cSrcweir case PCT: 581cdf0e10cSrcweir if (rv2 == 0) 582cdf0e10cSrcweir { 583cdf0e10cSrcweir rtype = UND; 584cdf0e10cSrcweir break; 585cdf0e10cSrcweir } 586cdf0e10cSrcweir if (rtype == UNS) 587cdf0e10cSrcweir rv1 %= (unsigned long) rv2; 588cdf0e10cSrcweir else 589cdf0e10cSrcweir rv1 %= rv2; 590cdf0e10cSrcweir break; 591cdf0e10cSrcweir case COLON: 592cdf0e10cSrcweir if (op[-1] != QUEST) 593cdf0e10cSrcweir error(ERROR, "Bad ?: in #if/endif"); 594cdf0e10cSrcweir else 595cdf0e10cSrcweir { 596cdf0e10cSrcweir op--; 597cdf0e10cSrcweir if ((--vp)->val == 0) 598cdf0e10cSrcweir v1 = v2; 599cdf0e10cSrcweir rtype = v1.type; 600cdf0e10cSrcweir rv1 = v1.val; 601cdf0e10cSrcweir } 602cdf0e10cSrcweir break; 603cdf0e10cSrcweir 604cdf0e10cSrcweir case DEFINED: 605cdf0e10cSrcweir case ARCHITECTURE: 606cdf0e10cSrcweir break; 607cdf0e10cSrcweir 608cdf0e10cSrcweir default: 609cdf0e10cSrcweir error(ERROR, "Eval botch (unknown operator)"); 610cdf0e10cSrcweir return 1; 611cdf0e10cSrcweir } 612cdf0e10cSrcweir /*lint +e574 +e644 */ 613cdf0e10cSrcweir v1.val = rv1; 614cdf0e10cSrcweir v1.type = rtype; 615cdf0e10cSrcweir *vp++ = v1; 616cdf0e10cSrcweir } 617cdf0e10cSrcweir return 0; 618cdf0e10cSrcweir } 619cdf0e10cSrcweir 620cdf0e10cSrcweir struct value tokval(Token * tp)621cdf0e10cSrcweir tokval(Token * tp) 622cdf0e10cSrcweir { 623cdf0e10cSrcweir struct value v; 624cdf0e10cSrcweir Nlist *np; 625cdf0e10cSrcweir int i, base; 626cdf0e10cSrcweir unsigned long n; 627cdf0e10cSrcweir uchar *p, c; 628cdf0e10cSrcweir 629cdf0e10cSrcweir v.type = SGN; 630cdf0e10cSrcweir v.val = 0; 631cdf0e10cSrcweir switch (tp->type) 632cdf0e10cSrcweir { 633cdf0e10cSrcweir 634cdf0e10cSrcweir case NAME: 635cdf0e10cSrcweir v.val = 0; 636cdf0e10cSrcweir break; 637cdf0e10cSrcweir 638cdf0e10cSrcweir case NAME1: 639cdf0e10cSrcweir if ((np = lookup(tp, 0)) != NULL && np->flag & (ISDEFINED | ISMAC)) 640cdf0e10cSrcweir v.val = 1; 641cdf0e10cSrcweir break; 642cdf0e10cSrcweir 643cdf0e10cSrcweir case NAME2: 644cdf0e10cSrcweir if ((np = lookup(tp, 0)) != NULL && np->flag & (ISARCHITECTURE)) 645cdf0e10cSrcweir v.val = 1; 646cdf0e10cSrcweir break; 647cdf0e10cSrcweir 648cdf0e10cSrcweir case NUMBER: 649cdf0e10cSrcweir n = 0; 650cdf0e10cSrcweir base = 10; 651cdf0e10cSrcweir p = tp->t; 652cdf0e10cSrcweir c = p[tp->len]; 653cdf0e10cSrcweir p[tp->len] = '\0'; 654cdf0e10cSrcweir if (*p == '0') 655cdf0e10cSrcweir { 656cdf0e10cSrcweir base = 8; 657cdf0e10cSrcweir if (p[1] == 'x' || p[1] == 'X') 658cdf0e10cSrcweir { 659cdf0e10cSrcweir base = 16; 660cdf0e10cSrcweir p++; 661cdf0e10cSrcweir } 662cdf0e10cSrcweir p++; 663cdf0e10cSrcweir } 664cdf0e10cSrcweir for (;; p++) 665cdf0e10cSrcweir { 666cdf0e10cSrcweir if ((i = digit(*p)) < 0) 667cdf0e10cSrcweir break; 668cdf0e10cSrcweir if (i >= base) 669cdf0e10cSrcweir error(WARNING, 670cdf0e10cSrcweir "Bad digit in number %t", tp); 671cdf0e10cSrcweir n *= base; 672cdf0e10cSrcweir n += i; 673cdf0e10cSrcweir } 674cdf0e10cSrcweir if (n >= 0x80000000 && base != 10) 675cdf0e10cSrcweir v.type = UNS; 676cdf0e10cSrcweir for (; *p; p++) 677cdf0e10cSrcweir { 678cdf0e10cSrcweir if (*p == 'u' || *p == 'U') 679cdf0e10cSrcweir v.type = UNS; 680cdf0e10cSrcweir else 681cdf0e10cSrcweir if (*p == 'l' || *p == 'L') 682cdf0e10cSrcweir ; 683cdf0e10cSrcweir else 684cdf0e10cSrcweir { 685cdf0e10cSrcweir error(ERROR, 686cdf0e10cSrcweir "Bad number %t in #if/#elsif", tp); 687cdf0e10cSrcweir break; 688cdf0e10cSrcweir } 689cdf0e10cSrcweir } 690cdf0e10cSrcweir v.val = n; 691cdf0e10cSrcweir tp->t[tp->len] = c; 692cdf0e10cSrcweir break; 693cdf0e10cSrcweir 694cdf0e10cSrcweir case CCON: 695cdf0e10cSrcweir n = 0; 696cdf0e10cSrcweir p = tp->t; 697cdf0e10cSrcweir if (*p == 'L') 698cdf0e10cSrcweir { 699cdf0e10cSrcweir p += 1; 700cdf0e10cSrcweir error(WARNING, "Wide char constant value undefined"); 701cdf0e10cSrcweir } 702cdf0e10cSrcweir p += 1; 703cdf0e10cSrcweir if (*p == '\\') 704cdf0e10cSrcweir { 705cdf0e10cSrcweir p += 1; 706cdf0e10cSrcweir if ((i = digit(*p)) >= 0 && i <= 7) 707cdf0e10cSrcweir { 708cdf0e10cSrcweir n = i; 709cdf0e10cSrcweir p += 1; 710cdf0e10cSrcweir if ((i = digit(*p)) >= 0 && i <= 7) 711cdf0e10cSrcweir { 712cdf0e10cSrcweir p += 1; 713cdf0e10cSrcweir n <<= 3; 714cdf0e10cSrcweir n += i; 715cdf0e10cSrcweir if ((i = digit(*p)) >= 0 && i <= 7) 716cdf0e10cSrcweir { 717cdf0e10cSrcweir p += 1; 718cdf0e10cSrcweir n <<= 3; 719cdf0e10cSrcweir n += i; 720cdf0e10cSrcweir } 721cdf0e10cSrcweir } 722cdf0e10cSrcweir } 723cdf0e10cSrcweir else 724cdf0e10cSrcweir if (*p == 'x') 725cdf0e10cSrcweir { 726cdf0e10cSrcweir p += 1; 727cdf0e10cSrcweir while ((i = digit(*p)) >= 0 && i <= 15) 728cdf0e10cSrcweir { 729cdf0e10cSrcweir p += 1; 730cdf0e10cSrcweir n <<= 4; 731cdf0e10cSrcweir n += i; 732cdf0e10cSrcweir } 733cdf0e10cSrcweir } 734cdf0e10cSrcweir else 735cdf0e10cSrcweir { 736cdf0e10cSrcweir static char cvcon[] = "b\bf\fn\nr\rt\tv\v''\"\"??\\\\"; 737cdf0e10cSrcweir static size_t cvlen = sizeof(cvcon) - 1; 738cdf0e10cSrcweir 739cdf0e10cSrcweir size_t j; 740cdf0e10cSrcweir for (j = 0; j < cvlen; j += 2) 741cdf0e10cSrcweir { 742cdf0e10cSrcweir if (*p == cvcon[j]) 743cdf0e10cSrcweir { 744cdf0e10cSrcweir n = cvcon[j + 1]; 745cdf0e10cSrcweir break; 746cdf0e10cSrcweir } 747cdf0e10cSrcweir } 748cdf0e10cSrcweir p += 1; 749cdf0e10cSrcweir if (j >= cvlen) 750cdf0e10cSrcweir error(WARNING, 751cdf0e10cSrcweir "Undefined escape in character constant"); 752cdf0e10cSrcweir } 753cdf0e10cSrcweir } 754cdf0e10cSrcweir else 755cdf0e10cSrcweir if (*p == '\'') 756cdf0e10cSrcweir error(ERROR, "Empty character constant"); 757cdf0e10cSrcweir else 758cdf0e10cSrcweir n = *p++; 759cdf0e10cSrcweir if (*p != '\'') 760cdf0e10cSrcweir error(WARNING, "Multibyte character constant undefined"); 761cdf0e10cSrcweir else 762cdf0e10cSrcweir if (n > 127) 763cdf0e10cSrcweir error(WARNING, "Character constant taken as not signed"); 764cdf0e10cSrcweir v.val = n; 765cdf0e10cSrcweir break; 766cdf0e10cSrcweir 767cdf0e10cSrcweir case STRING: 768cdf0e10cSrcweir error(ERROR, "String in #if/#elsif"); 769cdf0e10cSrcweir break; 770cdf0e10cSrcweir } 771cdf0e10cSrcweir return v; 772cdf0e10cSrcweir } 773cdf0e10cSrcweir 774cdf0e10cSrcweir int digit(int i)775cdf0e10cSrcweir digit(int i) 776cdf0e10cSrcweir { 777cdf0e10cSrcweir if ('0' <= i && i <= '9') 778cdf0e10cSrcweir i -= '0'; 779cdf0e10cSrcweir else 780cdf0e10cSrcweir if ('a' <= i && i <= 'f') 781cdf0e10cSrcweir i -= 'a' - 10; 782cdf0e10cSrcweir else 783cdf0e10cSrcweir if ('A' <= i && i <= 'F') 784cdf0e10cSrcweir i -= 'A' - 10; 785cdf0e10cSrcweir else 786cdf0e10cSrcweir i = -1; 787cdf0e10cSrcweir return i; 788cdf0e10cSrcweir } 789