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