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
16+char outbuf[OUTS];
17+char *outp = outbuf;
18+Source *cursource;
19+int nerrs;
20+struct token nltoken = { NL, 0, 0, 0, 1, (uchar*)"\n" };
21+char *curtime;
22+int incdepth;
23+int ifdepth;
24+int ifsatisfied[NIF];
25+int skipping;
26+
27+int
28+main(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+
50+void
51+process(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+
93+void
94+control(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+
267+void *
268+dorealloc(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+
277+void *
278+domalloc(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+
287+void
288+dofree(void *p)
289+{
290+ free(p);
291+}
292+
293+void
294+error(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+}