14887Schin /*********************************************************************** 24887Schin * * 34887Schin * This software is part of the ast package * 4*8462SApril.Chin@Sun.COM * Copyright (c) 1986-2008 AT&T Intellectual Property * 54887Schin * and is licensed under the * 64887Schin * Common Public License, Version 1.0 * 7*8462SApril.Chin@Sun.COM * by AT&T Intellectual Property * 84887Schin * * 94887Schin * A copy of the License is available at * 104887Schin * http://www.opensource.org/licenses/cpl1.0.txt * 114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 124887Schin * * 134887Schin * Information and Software Systems Research * 144887Schin * AT&T Research * 154887Schin * Florham Park NJ * 164887Schin * * 174887Schin * Glenn Fowler <gsf@research.att.com> * 184887Schin * * 194887Schin ***********************************************************************/ 204887Schin #pragma prototyped 214887Schin /* 224887Schin * Glenn Fowler 234887Schin * AT&T Research 244887Schin * 254887Schin * miscellaneous preprocessor support 264887Schin */ 274887Schin 284887Schin #include "pplib.h" 294887Schin 304887Schin /* 314887Schin * macro symbol def|ref 324887Schin */ 334887Schin 344887Schin struct ppsymbol* 354887Schin pprefmac(char* name, int ref) 364887Schin { 374887Schin register struct ppsymbol* sym; 384887Schin 394887Schin if (!(sym = ppsymget(pp.symtab, name)) && (ref <= REF_NORMAL && pp.macref || ref == REF_CREATE || ref == REF_DELETE && (pp.mode & (INIT|READONLY)))) 404887Schin { 414887Schin if ((pp.state & COMPILE) && pp.truncate && strlen(name) > pp.truncate) 424887Schin name[pp.truncate] = 0; 434887Schin sym = ppsymset(pp.symtab, NiL); 444887Schin } 454887Schin if (sym && ref <= REF_NORMAL) 464887Schin { 474887Schin if (pp.macref) (*pp.macref)(sym, error_info.file, error_info.line, ref == REF_NORMAL && (pp.state & CONDITIONAL) ? REF_IF : ref, 0L); 484887Schin if (!sym->macro) sym = 0; 494887Schin } 504887Schin #if COMPATIBLE 514887Schin if (!(pp.state & COMPATIBILITY)) 524887Schin #endif 534887Schin if (ref == REF_IF && sym && (sym->flags & SYM_PREDEFINED) && *name != '_' && !(pp.mode & (HOSTED|INACTIVE))) 544887Schin { 554887Schin if (pp.state & STRICT) 564887Schin { 574887Schin error(1, "%s: obsolete predefined symbol reference disabled", name); 584887Schin return(0); 594887Schin } 604887Schin error(1, "%s: obsolete predefined symbol referenced", name); 614887Schin } 624887Schin return(sym); 634887Schin } 644887Schin 654887Schin /* 664887Schin * common predicate assertion operations 674887Schin * op is DEFINE or UNDEF 684887Schin */ 694887Schin 704887Schin void 714887Schin ppassert(int op, char* pred, char* args) 724887Schin { 734887Schin register struct pplist* a; 744887Schin register struct ppsymbol* sym; 754887Schin register struct pplist* p; 764887Schin register struct pplist* q; 774887Schin 784887Schin if (!args) switch (op) 794887Schin { 804887Schin case DEFINE: 814887Schin goto mark; 824887Schin case UNDEF: 834887Schin a = 0; 844887Schin goto unmark; 854887Schin } 864887Schin if (a = (struct pplist*)hashget(pp.prdtab, pred)) 874887Schin { 884887Schin p = 0; 894887Schin q = a; 904887Schin while (q) 914887Schin { 924887Schin if (streq(q->value, args)) 934887Schin { 944887Schin if (op == DEFINE) return; 954887Schin q = q->next; 964887Schin if (p) p->next = q; 974887Schin else a = q; 984887Schin } 994887Schin else 1004887Schin { 1014887Schin p = q; 1024887Schin q = q->next; 1034887Schin } 1044887Schin } 1054887Schin if (op == UNDEF) 1064887Schin { 1074887Schin unmark: 1084887Schin hashput(pp.prdtab, pred, a); 1094887Schin if (sym = ppsymref(pp.symtab, pred)) 1104887Schin sym->flags &= ~SYM_PREDICATE; 1114887Schin return; 1124887Schin } 1134887Schin } 1144887Schin if (op == DEFINE) 1154887Schin { 1164887Schin p = newof(0, struct pplist, 1, 0); 1174887Schin p->next = a; 1184887Schin p->value = strdup(args); 1194887Schin hashput(pp.prdtab, NiL, p); 1204887Schin mark: 1214887Schin if ((pp.state & COMPILE) && pp.truncate) return; 1224887Schin if (sym = ppsymset(pp.symtab, pred)) 1234887Schin sym->flags |= SYM_PREDICATE; 1244887Schin } 1254887Schin } 1264887Schin 1274887Schin /* 1284887Schin * parse a predicate argument list 1294887Schin * the args are placed in pp.args 1304887Schin * the first non-space/paren argument token type is returned 1314887Schin * forms: 1324887Schin * 1334887Schin * predicate <identifier> type=T_ID 1344887Schin * predicate ( <identifier> ) type=T_ID 1354887Schin * predicate ( ) type=0 1364887Schin * predicate ( <balanced-paren-list> ) type=T_STRING 1374887Schin * otherwise type=<other> 1384887Schin */ 1394887Schin 1404887Schin int 1414887Schin pppredargs(void) 1424887Schin { 1434887Schin register int c; 1444887Schin register int n; 1454887Schin register int type; 1464887Schin char* pptoken; 1474887Schin 1484887Schin pptoken = pp.token; 1494887Schin pp.token = pp.args; 1504887Schin switch (type = pplex()) 1514887Schin { 1524887Schin case '(': 1534887Schin type = 0; 1544887Schin n = 1; 1554887Schin pp.state |= HEADER; 1564887Schin pp.state &= ~STRIP; 1574887Schin c = pplex(); 1584887Schin pp.state &= ~NOSPACE; 1594887Schin for (;;) 1604887Schin { 1614887Schin switch (c) 1624887Schin { 1634887Schin case '(': 1644887Schin n++; 1654887Schin break; 1664887Schin case '\n': 1674887Schin ungetchr(c); 1684887Schin error(2, "missing %d )%s in predicate argument list", n, n == 1 ? "" : "'s"); 1694887Schin type = 0; 1704887Schin goto done; 1714887Schin case ')': 1724887Schin if (!--n) goto done; 1734887Schin break; 1744887Schin } 1754887Schin pp.token = pp.toknxt; 1764887Schin if (c != ' ') 1774887Schin { 1784887Schin if (type) type = T_STRING; 1794887Schin else type = (c == T_ID) ? T_ID : T_STRING; 1804887Schin } 1814887Schin c = pplex(); 1824887Schin } 1834887Schin done: 1844887Schin pp.state &= ~HEADER; 1854887Schin pp.state |= NOSPACE|STRIP; 1864887Schin if (pp.token > pp.args && *(pp.token - 1) == ' ') pp.token--; 1874887Schin *pp.token = 0; 1884887Schin break; 1894887Schin case '\n': 1904887Schin ungetchr('\n'); 1914887Schin type = 0; 1924887Schin break; 1934887Schin } 1944887Schin pp.token = pptoken; 1954887Schin return(type); 1964887Schin } 1974887Schin 1984887Schin /* 1994887Schin * sync output line number 2004887Schin */ 2014887Schin 2024887Schin int 2034887Schin ppsync(void) 2044887Schin { 2054887Schin long m; 2064887Schin 2074887Schin if ((pp.state & (ADD|HIDDEN))) 2084887Schin { 2094887Schin if (pp.state & ADD) 2104887Schin { 2114887Schin pp.state &= ~ADD; 2124887Schin m = pp.addp - pp.addbuf; 2134887Schin pp.addp = pp.addbuf; 2144887Schin ppprintf("%-.*s", m, pp.addbuf); 2154887Schin } 2164887Schin if (pp.linesync) 2174887Schin { 2184887Schin if ((pp.state & SYNCLINE) || pp.hidden >= MAXHIDDEN) 2194887Schin { 2204887Schin pp.hidden = 0; 2214887Schin pp.state &= ~(HIDDEN|SYNCLINE); 2224887Schin if (error_info.line) 2234887Schin (*pp.linesync)(error_info.line, error_info.file); 2244887Schin } 2254887Schin else 2264887Schin { 2274887Schin m = pp.hidden; 2284887Schin pp.hidden = 0; 2294887Schin pp.state &= ~HIDDEN; 2304887Schin while (m-- > 0) 2314887Schin ppputchar('\n'); 2324887Schin } 2334887Schin } 2344887Schin else 2354887Schin { 2364887Schin pp.hidden = 0; 2374887Schin pp.state &= ~HIDDEN; 2384887Schin ppputchar('\n'); 2394887Schin } 2404887Schin } 2414887Schin return 0; 2424887Schin } 243