1*da2e3ebdSchin /*********************************************************************** 2*da2e3ebdSchin * * 3*da2e3ebdSchin * This software is part of the ast package * 4*da2e3ebdSchin * Copyright (c) 1986-2007 AT&T Knowledge Ventures * 5*da2e3ebdSchin * and is licensed under the * 6*da2e3ebdSchin * Common Public License, Version 1.0 * 7*da2e3ebdSchin * by AT&T Knowledge Ventures * 8*da2e3ebdSchin * * 9*da2e3ebdSchin * A copy of the License is available at * 10*da2e3ebdSchin * http://www.opensource.org/licenses/cpl1.0.txt * 11*da2e3ebdSchin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12*da2e3ebdSchin * * 13*da2e3ebdSchin * Information and Software Systems Research * 14*da2e3ebdSchin * AT&T Research * 15*da2e3ebdSchin * Florham Park NJ * 16*da2e3ebdSchin * * 17*da2e3ebdSchin * Glenn Fowler <gsf@research.att.com> * 18*da2e3ebdSchin * * 19*da2e3ebdSchin ***********************************************************************/ 20*da2e3ebdSchin #pragma prototyped 21*da2e3ebdSchin /* 22*da2e3ebdSchin * Glenn Fowler 23*da2e3ebdSchin * AT&T Research 24*da2e3ebdSchin * 25*da2e3ebdSchin * miscellaneous preprocessor support 26*da2e3ebdSchin */ 27*da2e3ebdSchin 28*da2e3ebdSchin #include "pplib.h" 29*da2e3ebdSchin 30*da2e3ebdSchin /* 31*da2e3ebdSchin * macro symbol def|ref 32*da2e3ebdSchin */ 33*da2e3ebdSchin 34*da2e3ebdSchin struct ppsymbol* 35*da2e3ebdSchin pprefmac(char* name, int ref) 36*da2e3ebdSchin { 37*da2e3ebdSchin register struct ppsymbol* sym; 38*da2e3ebdSchin 39*da2e3ebdSchin if (!(sym = ppsymget(pp.symtab, name)) && (ref <= REF_NORMAL && pp.macref || ref == REF_CREATE || ref == REF_DELETE && (pp.mode & (INIT|READONLY)))) 40*da2e3ebdSchin { 41*da2e3ebdSchin if ((pp.state & COMPILE) && pp.truncate && strlen(name) > pp.truncate) 42*da2e3ebdSchin name[pp.truncate] = 0; 43*da2e3ebdSchin sym = ppsymset(pp.symtab, NiL); 44*da2e3ebdSchin } 45*da2e3ebdSchin if (sym && ref <= REF_NORMAL) 46*da2e3ebdSchin { 47*da2e3ebdSchin if (pp.macref) (*pp.macref)(sym, error_info.file, error_info.line, ref == REF_NORMAL && (pp.state & CONDITIONAL) ? REF_IF : ref, 0L); 48*da2e3ebdSchin if (!sym->macro) sym = 0; 49*da2e3ebdSchin } 50*da2e3ebdSchin #if COMPATIBLE 51*da2e3ebdSchin if (!(pp.state & COMPATIBILITY)) 52*da2e3ebdSchin #endif 53*da2e3ebdSchin if (ref == REF_IF && sym && (sym->flags & SYM_PREDEFINED) && *name != '_' && !(pp.mode & (HOSTED|INACTIVE))) 54*da2e3ebdSchin { 55*da2e3ebdSchin if (pp.state & STRICT) 56*da2e3ebdSchin { 57*da2e3ebdSchin error(1, "%s: obsolete predefined symbol reference disabled", name); 58*da2e3ebdSchin return(0); 59*da2e3ebdSchin } 60*da2e3ebdSchin error(1, "%s: obsolete predefined symbol referenced", name); 61*da2e3ebdSchin } 62*da2e3ebdSchin return(sym); 63*da2e3ebdSchin } 64*da2e3ebdSchin 65*da2e3ebdSchin /* 66*da2e3ebdSchin * common predicate assertion operations 67*da2e3ebdSchin * op is DEFINE or UNDEF 68*da2e3ebdSchin */ 69*da2e3ebdSchin 70*da2e3ebdSchin void 71*da2e3ebdSchin ppassert(int op, char* pred, char* args) 72*da2e3ebdSchin { 73*da2e3ebdSchin register struct pplist* a; 74*da2e3ebdSchin register struct ppsymbol* sym; 75*da2e3ebdSchin register struct pplist* p; 76*da2e3ebdSchin register struct pplist* q; 77*da2e3ebdSchin 78*da2e3ebdSchin if (!args) switch (op) 79*da2e3ebdSchin { 80*da2e3ebdSchin case DEFINE: 81*da2e3ebdSchin goto mark; 82*da2e3ebdSchin case UNDEF: 83*da2e3ebdSchin a = 0; 84*da2e3ebdSchin goto unmark; 85*da2e3ebdSchin } 86*da2e3ebdSchin if (a = (struct pplist*)hashget(pp.prdtab, pred)) 87*da2e3ebdSchin { 88*da2e3ebdSchin p = 0; 89*da2e3ebdSchin q = a; 90*da2e3ebdSchin while (q) 91*da2e3ebdSchin { 92*da2e3ebdSchin if (streq(q->value, args)) 93*da2e3ebdSchin { 94*da2e3ebdSchin if (op == DEFINE) return; 95*da2e3ebdSchin q = q->next; 96*da2e3ebdSchin if (p) p->next = q; 97*da2e3ebdSchin else a = q; 98*da2e3ebdSchin } 99*da2e3ebdSchin else 100*da2e3ebdSchin { 101*da2e3ebdSchin p = q; 102*da2e3ebdSchin q = q->next; 103*da2e3ebdSchin } 104*da2e3ebdSchin } 105*da2e3ebdSchin if (op == UNDEF) 106*da2e3ebdSchin { 107*da2e3ebdSchin unmark: 108*da2e3ebdSchin hashput(pp.prdtab, pred, a); 109*da2e3ebdSchin if (sym = ppsymref(pp.symtab, pred)) 110*da2e3ebdSchin sym->flags &= ~SYM_PREDICATE; 111*da2e3ebdSchin return; 112*da2e3ebdSchin } 113*da2e3ebdSchin } 114*da2e3ebdSchin if (op == DEFINE) 115*da2e3ebdSchin { 116*da2e3ebdSchin p = newof(0, struct pplist, 1, 0); 117*da2e3ebdSchin p->next = a; 118*da2e3ebdSchin p->value = strdup(args); 119*da2e3ebdSchin hashput(pp.prdtab, NiL, p); 120*da2e3ebdSchin mark: 121*da2e3ebdSchin if ((pp.state & COMPILE) && pp.truncate) return; 122*da2e3ebdSchin if (sym = ppsymset(pp.symtab, pred)) 123*da2e3ebdSchin sym->flags |= SYM_PREDICATE; 124*da2e3ebdSchin } 125*da2e3ebdSchin } 126*da2e3ebdSchin 127*da2e3ebdSchin /* 128*da2e3ebdSchin * parse a predicate argument list 129*da2e3ebdSchin * the args are placed in pp.args 130*da2e3ebdSchin * the first non-space/paren argument token type is returned 131*da2e3ebdSchin * forms: 132*da2e3ebdSchin * 133*da2e3ebdSchin * predicate <identifier> type=T_ID 134*da2e3ebdSchin * predicate ( <identifier> ) type=T_ID 135*da2e3ebdSchin * predicate ( ) type=0 136*da2e3ebdSchin * predicate ( <balanced-paren-list> ) type=T_STRING 137*da2e3ebdSchin * otherwise type=<other> 138*da2e3ebdSchin */ 139*da2e3ebdSchin 140*da2e3ebdSchin int 141*da2e3ebdSchin pppredargs(void) 142*da2e3ebdSchin { 143*da2e3ebdSchin register int c; 144*da2e3ebdSchin register int n; 145*da2e3ebdSchin register int type; 146*da2e3ebdSchin char* pptoken; 147*da2e3ebdSchin 148*da2e3ebdSchin pptoken = pp.token; 149*da2e3ebdSchin pp.token = pp.args; 150*da2e3ebdSchin switch (type = pplex()) 151*da2e3ebdSchin { 152*da2e3ebdSchin case '(': 153*da2e3ebdSchin type = 0; 154*da2e3ebdSchin n = 1; 155*da2e3ebdSchin pp.state |= HEADER; 156*da2e3ebdSchin pp.state &= ~STRIP; 157*da2e3ebdSchin c = pplex(); 158*da2e3ebdSchin pp.state &= ~NOSPACE; 159*da2e3ebdSchin for (;;) 160*da2e3ebdSchin { 161*da2e3ebdSchin switch (c) 162*da2e3ebdSchin { 163*da2e3ebdSchin case '(': 164*da2e3ebdSchin n++; 165*da2e3ebdSchin break; 166*da2e3ebdSchin case '\n': 167*da2e3ebdSchin ungetchr(c); 168*da2e3ebdSchin error(2, "missing %d )%s in predicate argument list", n, n == 1 ? "" : "'s"); 169*da2e3ebdSchin type = 0; 170*da2e3ebdSchin goto done; 171*da2e3ebdSchin case ')': 172*da2e3ebdSchin if (!--n) goto done; 173*da2e3ebdSchin break; 174*da2e3ebdSchin } 175*da2e3ebdSchin pp.token = pp.toknxt; 176*da2e3ebdSchin if (c != ' ') 177*da2e3ebdSchin { 178*da2e3ebdSchin if (type) type = T_STRING; 179*da2e3ebdSchin else type = (c == T_ID) ? T_ID : T_STRING; 180*da2e3ebdSchin } 181*da2e3ebdSchin c = pplex(); 182*da2e3ebdSchin } 183*da2e3ebdSchin done: 184*da2e3ebdSchin pp.state &= ~HEADER; 185*da2e3ebdSchin pp.state |= NOSPACE|STRIP; 186*da2e3ebdSchin if (pp.token > pp.args && *(pp.token - 1) == ' ') pp.token--; 187*da2e3ebdSchin *pp.token = 0; 188*da2e3ebdSchin break; 189*da2e3ebdSchin case '\n': 190*da2e3ebdSchin ungetchr('\n'); 191*da2e3ebdSchin type = 0; 192*da2e3ebdSchin break; 193*da2e3ebdSchin } 194*da2e3ebdSchin pp.token = pptoken; 195*da2e3ebdSchin return(type); 196*da2e3ebdSchin } 197*da2e3ebdSchin 198*da2e3ebdSchin /* 199*da2e3ebdSchin * sync output line number 200*da2e3ebdSchin */ 201*da2e3ebdSchin 202*da2e3ebdSchin int 203*da2e3ebdSchin ppsync(void) 204*da2e3ebdSchin { 205*da2e3ebdSchin long m; 206*da2e3ebdSchin 207*da2e3ebdSchin if ((pp.state & (ADD|HIDDEN))) 208*da2e3ebdSchin { 209*da2e3ebdSchin if (pp.state & ADD) 210*da2e3ebdSchin { 211*da2e3ebdSchin pp.state &= ~ADD; 212*da2e3ebdSchin m = pp.addp - pp.addbuf; 213*da2e3ebdSchin pp.addp = pp.addbuf; 214*da2e3ebdSchin ppprintf("%-.*s", m, pp.addbuf); 215*da2e3ebdSchin } 216*da2e3ebdSchin if (pp.linesync) 217*da2e3ebdSchin { 218*da2e3ebdSchin if ((pp.state & SYNCLINE) || pp.hidden >= MAXHIDDEN) 219*da2e3ebdSchin { 220*da2e3ebdSchin pp.hidden = 0; 221*da2e3ebdSchin pp.state &= ~(HIDDEN|SYNCLINE); 222*da2e3ebdSchin if (error_info.line) 223*da2e3ebdSchin (*pp.linesync)(error_info.line, error_info.file); 224*da2e3ebdSchin } 225*da2e3ebdSchin else 226*da2e3ebdSchin { 227*da2e3ebdSchin m = pp.hidden; 228*da2e3ebdSchin pp.hidden = 0; 229*da2e3ebdSchin pp.state &= ~HIDDEN; 230*da2e3ebdSchin while (m-- > 0) 231*da2e3ebdSchin ppputchar('\n'); 232*da2e3ebdSchin } 233*da2e3ebdSchin } 234*da2e3ebdSchin else 235*da2e3ebdSchin { 236*da2e3ebdSchin pp.hidden = 0; 237*da2e3ebdSchin pp.state &= ~HIDDEN; 238*da2e3ebdSchin ppputchar('\n'); 239*da2e3ebdSchin } 240*da2e3ebdSchin } 241*da2e3ebdSchin return 0; 242*da2e3ebdSchin } 243