History

init from p9f

henesy committed 5 years agomaster

Commit d787fdaNo parent (first commit)10490 files · +3095713 −-1933Browse files

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

Unified · Split

sys/src/cmd/cpp/cpp.c+329−0
@@ -0,0 +1,329 @@
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);
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(WARNING, "#error directive: %r", trp);
212+ break;
213+
214+ case KLINE:
215+ trp->tp = tp+1;
216+ expandrow(trp, "<line>");
217+ tp = trp->bp+2;
218+ kline:
219+ if (tp+1>=trp->lp || tp->type!=NUMBER || tp+3<trp->lp
220+ || (tp+3==trp->lp && ((tp+1)->type!=STRING)||*(tp+1)->t=='L')){
221+ error(ERROR, "Syntax error in #line");
222+ return;
223+ }
224+ cursource->line = atol((char*)tp->t)-1;
225+ if (cursource->line<0 || cursource->line>=32768)
226+ error(WARNING, "#line specifies number out of range");
227+ tp = tp+1;
228+ if (tp+1<trp->lp)
229+ cursource->filename=(char*)newstring(tp->t+1,tp->len-2,0);
230+ return;
231+
232+ case KDEFINED:
233+ error(ERROR, "Bad syntax for control line");
234+ break;
235+
236+ case KINCLUDE:
237+ doinclude(trp);
238+ trp->lp = trp->bp;
239+ return;
240+
241+ case KEVAL:
242+ eval(trp, np->val);
243+ break;
244+
245+ default:
246+ error(ERROR, "Preprocessor control `%t' not yet implemented", tp);
247+ break;
248+ }
249+ setempty(trp);
250+ return;
251+}
252+
253+void *
254+domalloc(int size)
255+{
256+ void *p = malloc(size);
257+
258+ if (p==NULL)
259+ error(FATAL, "Out of memory from malloc");
260+ return p;
261+}
262+
263+void
264+dofree(void *p)
265+{
266+ free(p);
267+}
268+
269+void
270+error(enum errtype type, char *string, ...)
271+{
272+ va_list ap;
273+ char *cp, *ep;
274+ Token *tp;
275+ Tokenrow *trp;
276+ Source *s;
277+ int i;
278+ void *p;
279+
280+ fprintf(stderr, "cpp: ");
281+ for (s=cursource; s; s=s->next)
282+ if (*s->filename)
283+ fprintf(stderr, "%s:%d ", s->filename, s->line);
284+ va_start(ap, string);
285+ for (ep=string; *ep; ep++) {
286+ if (*ep=='%') {
287+ switch (*++ep) {
288+
289+ case 's':
290+ cp = va_arg(ap, char *);
291+ fprintf(stderr, "%s", cp);
292+ break;
293+ case 'd':
294+ i = va_arg(ap, int);
295+ fprintf(stderr, "%d", i);
296+ break;
297+ case 'p':
298+ p = va_arg(ap, void *);
299+ fprintf(stderr, "%p", p);
300+ break;
301+ case 't':
302+ tp = va_arg(ap, Token *);
303+ fprintf(stderr, "%.*s", tp->len, tp->t);
304+ break;
305+
306+ case 'r':
307+ trp = va_arg(ap, Tokenrow *);
308+ for (tp=trp->tp; tp<trp->lp&&tp->type!=NL; tp++) {
309+ if (tp>trp->tp && tp->wslen)
310+ fputc(' ', stderr);
311+ fprintf(stderr, "%.*s", tp->len, tp->t);
312+ }
313+ break;
314+
315+ default:
316+ fputc(*ep, stderr);
317+ break;
318+ }
319+ } else
320+ fputc(*ep, stderr);
321+ }
322+ va_end(ap);
323+ fputc('\n', stderr);
324+ if (type==FATAL)
325+ exits("error");
326+ if (type!=WARNING)
327+ nerrs = 1;
328+ fflush(stderr);
329+}