Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libpp/ppmisc.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1986-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
/*
22
* Glenn Fowler
23
* AT&T Research
24
*
25
* miscellaneous preprocessor support
26
*/
27
28
#include "pplib.h"
29
30
/*
31
* macro symbol def|ref
32
*/
33
34
struct ppsymbol*
35
pprefmac(char* name, int ref)
36
{
37
register struct ppsymbol* sym;
38
39
if (!(sym = ppsymget(pp.symtab, name)) && (ref <= REF_NORMAL && pp.macref || ref == REF_CREATE || ref == REF_DELETE && (pp.mode & (INIT|READONLY))))
40
{
41
if ((pp.state & COMPILE) && pp.truncate && strlen(name) > pp.truncate)
42
name[pp.truncate] = 0;
43
sym = ppsymset(pp.symtab, NiL);
44
}
45
if (sym && ref <= REF_NORMAL)
46
{
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;
49
}
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)))
54
{
55
if (pp.state & STRICT)
56
{
57
error(1, "%s: obsolete predefined symbol reference disabled", name);
58
return(0);
59
}
60
error(1, "%s: obsolete predefined symbol referenced", name);
61
}
62
return(sym);
63
}
64
65
/*
66
* common predicate assertion operations
67
* op is DEFINE or UNDEF
68
*/
69
70
void
71
ppassert(int op, char* pred, char* args)
72
{
73
register struct pplist* a;
74
register struct ppsymbol* sym;
75
register struct pplist* p;
76
register struct pplist* q;
77
78
if (!args) switch (op)
79
{
80
case DEFINE:
81
goto mark;
82
case UNDEF:
83
a = 0;
84
goto unmark;
85
}
86
if (a = (struct pplist*)hashget(pp.prdtab, pred))
87
{
88
p = 0;
89
q = a;
90
while (q)
91
{
92
if (streq(q->value, args))
93
{
94
if (op == DEFINE) return;
95
q = q->next;
96
if (p) p->next = q;
97
else a = q;
98
}
99
else
100
{
101
p = q;
102
q = q->next;
103
}
104
}
105
if (op == UNDEF)
106
{
107
unmark:
108
hashput(pp.prdtab, pred, a);
109
if (sym = ppsymref(pp.symtab, pred))
110
sym->flags &= ~SYM_PREDICATE;
111
return;
112
}
113
}
114
if (op == DEFINE)
115
{
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;
124
}
125
}
126
127
/*
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:
132
*
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>
138
*/
139
140
int
141
pppredargs(void)
142
{
143
register int c;
144
register int n;
145
register int type;
146
char* pptoken;
147
148
pptoken = pp.token;
149
pp.token = pp.args;
150
switch (type = pplex())
151
{
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 (;;)
160
{
161
switch (c)
162
{
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;
174
}
175
pp.token = pp.toknxt;
176
if (c != ' ')
177
{
178
if (type) type = T_STRING;
179
else type = (c == T_ID) ? T_ID : T_STRING;
180
}
181
c = pplex();
182
}
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;
193
}
194
pp.token = pptoken;
195
return(type);
196
}
197
198
/*
199
* sync output line number
200
*/
201
202
int
203
ppsync(void)
204
{
205
long m;
206
207
if ((pp.state & (ADD|HIDDEN)))
208
{
209
if (pp.state & ADD)
210
{
211
pp.state &= ~ADD;
212
m = pp.addp - pp.addbuf;
213
pp.addp = pp.addbuf;
214
ppprintf("%-.*s", m, pp.addbuf);
215
}
216
if (pp.linesync)
217
{
218
if ((pp.state & SYNCLINE) || pp.hidden >= MAXHIDDEN)
219
{
220
pp.hidden = 0;
221
pp.state &= ~(HIDDEN|SYNCLINE);
222
if (error_info.line)
223
(*pp.linesync)(error_info.line, error_info.file);
224
}
225
else
226
{
227
m = pp.hidden;
228
pp.hidden = 0;
229
pp.state &= ~HIDDEN;
230
while (m-- > 0)
231
ppputchar('\n');
232
}
233
}
234
else
235
{
236
pp.hidden = 0;
237
pp.state &= ~HIDDEN;
238
ppputchar('\n');
239
}
240
}
241
return 0;
242
}
243
244