History

bleh, still have to .keep some dirs.

initial commit

echoline committed 11 years ago

Commit 3833b13No parent (first commit)14470 files · +3080158 −-4496Browse files

Showing the changes to sys/src/cmd/cpp/cpp.c (1 of 14470 files). Show all

Unified · Split

sys/src/cmd/cpp/cpp.c+353−0
@@ -0,0 +1,353 @@
1/*
2 * This file is part of the UCB release of Plan 9. It is subject to the license
3 * terms in the LICENSE file found in the top-level directory of this
4 * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
5 * part of the UCB release of Plan 9, including this file, may be copied,
6 * modified, propagated, or distributed except according to the terms contained
7 * in the LICENSE file.
8 */
9
10#include <u.h>
11#include <libc.h>
12#include <stdio.h>
13#include "cpp.h"
14
15#define OUTS 16384
16char outbuf[OUTS];
17char *outp = outbuf;
18Source *cursource;
19int nerrs;
20struct token nltoken = { NL, 0, 0, 0, 1, (uchar*)"\n" };
21char *curtime;
22int incdepth;
23int ifdepth;
24int ifsatisfied[NIF];
25int skipping;
26
27int
28main(int argc, char **argv)
29{
30 Tokenrow tr;
31 long t;
32 char ebuf[BUFSIZ];
33
34 setbuf(stderr, ebuf);
35 t = time(NULL);
36 curtime = ctime(t);
37 maketokenrow(3, &tr);
38 expandlex();
39 setup(argc, argv);
40 fixlex();
41 iniths();
42 genline();
43 process(&tr);
44 flushout();
45 fflush(stderr);
46 exits(nerrs? "errors" : 0);
47 return 0;
48}
49
50void
51process(Tokenrow *trp)
52{
53 int anymacros = 0;
54
55 for (;;) {
56 if (trp->tp >= trp->lp) {
57 trp->tp = trp->lp = trp->bp;
58 outp = outbuf;
59 anymacros |= gettokens(trp, 1);
60 trp->tp = trp->bp;
61 }
62 if (trp->tp->type == END) {
63 if (--incdepth>=0) {
64 if (cursource->ifdepth)
65 error(ERROR,
66 "Unterminated conditional in #include");
67 unsetsource();
68 cursource->line += cursource->lineinc;
69 trp->tp = trp->lp;
70 genline();
71 continue;
72 }
73 if (ifdepth)
74 error(ERROR, "Unterminated #if/#ifdef/#ifndef");
75 break;
76 }
77 if (trp->tp->type==SHARP) {
78 trp->tp += 1;
79 control(trp);
80 } else if (!skipping && anymacros)
81 expandrow(trp, NULL, Notinmacro);
82 if (skipping)
83 setempty(trp);
84 puttokens(trp);
85 anymacros = 0;
86 cursource->line += cursource->lineinc;
87 if (cursource->lineinc>1) {
88 genline();
89 }
90 }
91}
92
93void
94control(Tokenrow *trp)
95{
96 Nlist *np;
97 Token *tp;
98
99 tp = trp->tp;
100 if (tp->type!=NAME) {
101 if (tp->type==NUMBER)
102 goto kline;
103 if (tp->type != NL)
104 error(ERROR, "Unidentifiable control line");
105 return; /* else empty line */
106 }
107 if ((np = lookup(tp, 0))==NULL || (np->flag&ISKW)==0 && !skipping) {
108 error(WARNING, "Unknown preprocessor control %t", tp);
109 return;
110 }
111 if (skipping) {
112 if ((np->flag&ISKW)==0)
113 return;
114 switch (np->val) {
115 case KENDIF:
116 if (--ifdepth<skipping)
117 skipping = 0;
118 --cursource->ifdepth;
119 setempty(trp);
120 return;
121
122 case KIFDEF:
123 case KIFNDEF:
124 case KIF:
125 if (++ifdepth >= NIF)
126 error(FATAL, "#if too deeply nested");
127 ++cursource->ifdepth;
128 return;
129
130 case KELIF:
131 case KELSE:
132 if (ifdepth<=skipping)
133 break;
134 return;
135
136 default:
137 return;
138 }
139 }
140 switch (np->val) {
141 case KDEFINE:
142 dodefine(trp);
143 break;
144
145 case KUNDEF:
146 tp += 1;
147 if (tp->type!=NAME || trp->lp - trp->bp != 4) {
148 error(ERROR, "Syntax error in #undef");
149 break;
150 }
151 if ((np = lookup(tp, 0))) {
152 if (np->flag&ISUNCHANGE) {
153 error(ERROR, "#defined token %t can't be undefined", tp);
154 return;
155 }
156 np->flag &= ~ISDEFINED;
157 }
158 break;
159
160 case KPRAGMA:
161 return;
162
163 case KIFDEF:
164 case KIFNDEF:
165 case KIF:
166 if (++ifdepth >= NIF)
167 error(FATAL, "#if too deeply nested");
168 ++cursource->ifdepth;
169 ifsatisfied[ifdepth] = 0;
170 if (eval(trp, np->val))
171 ifsatisfied[ifdepth] = 1;
172 else
173 skipping = ifdepth;
174 break;
175
176 case KELIF:
177 if (ifdepth==0) {
178 error(ERROR, "#elif with no #if");
179 return;
180 }
181 if (ifsatisfied[ifdepth]==2)
182 error(ERROR, "#elif after #else");
183 if (eval(trp, np->val)) {
184 if (ifsatisfied[ifdepth])
185 skipping = ifdepth;
186 else {
187 skipping = 0;
188 ifsatisfied[ifdepth] = 1;
189 }
190 } else
191 skipping = ifdepth;
192 break;
193
194 case KELSE:
195 if (ifdepth==0 || cursource->ifdepth==0) {
196 error(ERROR, "#else with no #if");
197 return;
198 }
199 if (ifsatisfied[ifdepth]==2)
200 error(ERROR, "#else after #else");
201 if (trp->lp - trp->bp != 3)
202 error(ERROR, "Syntax error in #else");
203 skipping = ifsatisfied[ifdepth]? ifdepth: 0;
204 ifsatisfied[ifdepth] = 2;
205 break;
206
207 case KENDIF:
208 if (ifdepth==0 || cursource->ifdepth==0) {
209 error(ERROR, "#endif with no #if");
210 return;
211 }
212 --ifdepth;
213 --cursource->ifdepth;
214 if (trp->lp - trp->bp != 3)
215 error(WARNING, "Syntax error in #endif");
216 break;
217
218 case KERROR:
219 trp->tp = tp+1;
220 error(ERROR, "#error directive: %r", trp);
221 break;
222
223 case KWARNING:
224 trp->tp = tp+1;
225 error(WARNING, "#warning directive: %r", trp);
226 break;
227
228 case KLINE:
229 trp->tp = tp+1;
230 expandrow(trp, "<line>", Notinmacro);
231 tp = trp->bp+2;
232 kline:
233 if (tp+1>=trp->lp || tp->type!=NUMBER || tp+3<trp->lp
234 || (tp+3==trp->lp && ((tp+1)->type!=STRING)||*(tp+1)->t=='L')){
235 error(ERROR, "Syntax error in #line");
236 return;
237 }
238 cursource->line = atol((char*)tp->t)-1;
239 if (cursource->line<0 || cursource->line>=32768)
240 error(WARNING, "#line specifies number out of range");
241 tp = tp+1;
242 if (tp+1<trp->lp)
243 cursource->filename=(char*)newstring(tp->t+1,tp->len-2,0);
244 return;
245
246 case KDEFINED:
247 error(ERROR, "Bad syntax for control line");
248 break;
249
250 case KINCLUDE:
251 doinclude(trp);
252 trp->lp = trp->bp;
253 return;
254
255 case KEVAL:
256 eval(trp, np->val);
257 break;
258
259 default:
260 error(ERROR, "Preprocessor control `%t' not yet implemented", tp);
261 break;
262 }
263 setempty(trp);
264 return;
265}
266
267void *
268dorealloc(void *ptr, int size)
269{
270 void *p = realloc(ptr, size);
271
272 if (p==NULL)
273 error(FATAL, "Out of memory from realloc");
274 return p;
275}
276
277void *
278domalloc(int size)
279{
280 void *p = malloc(size);
281
282 if (p==NULL)
283 error(FATAL, "Out of memory from malloc");
284 return p;
285}
286
287void
288dofree(void *p)
289{
290 free(p);
291}
292
293void
294error(enum errtype type, char *string, ...)
295{
296 va_list ap;
297 char *cp, *ep;
298 Token *tp;
299 Tokenrow *trp;
300 Source *s;
301 int i;
302 void *p;
303
304 fprintf(stderr, "cpp: ");
305 for (s=cursource; s; s=s->next)
306 if (*s->filename)
307 fprintf(stderr, "%s:%d ", s->filename, s->line);
308 va_start(ap, string);
309 for (ep=string; *ep; ep++) {
310 if (*ep=='%') {
311 switch (*++ep) {
312
313 case 's':
314 cp = va_arg(ap, char *);
315 fprintf(stderr, "%s", cp);
316 break;
317 case 'd':
318 i = va_arg(ap, int);
319 fprintf(stderr, "%d", i);
320 break;
321 case 'p':
322 p = va_arg(ap, void *);
323 fprintf(stderr, "%p", p);
324 break;
325 case 't':
326 tp = va_arg(ap, Token *);
327 fprintf(stderr, "%.*s", tp->len, tp->t);
328 break;
329
330 case 'r':
331 trp = va_arg(ap, Tokenrow *);
332 for (tp=trp->tp; tp<trp->lp&&tp->type!=NL; tp++) {
333 if (tp>trp->tp && tp->wslen)
334 fputc(' ', stderr);
335 fprintf(stderr, "%.*s", tp->len, tp->t);
336 }
337 break;
338
339 default:
340 fputc(*ep, stderr);
341 break;
342 }
343 } else
344 fputc(*ep, stderr);
345 }
346 va_end(ap);
347 fputc('\n', stderr);
348 if (type==FATAL)
349 exits("error");
350 if (type!=WARNING)
351 nerrs = 1;
352 fflush(stderr);
353}