History

initial

rminnich committed 16 years ago

Commit 1fcdf79No parent (first commit)7733 files · +2461126 −-39Browse files

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

Unified · Split

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