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