History

Plan 9 from Bell Labs First Edition 1992-09-21

David du Colombier committed 34 years ago1e-1992-09-21

Commit 3e12c5dNo parent (first commit)9043 files · +2238644 −-2199Browse files

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

Unified · Split

sys/src/cmd/cpp/cpp.c+316−0
@@ -0,0 +1,316 @@
1+#include <u.h>
2+#include <libc.h>
3+#include <stdio.h>
4+#include <stdarg.h>
5+#include "cpp.h"
6+
7+#define OUTS 16384
8+char outbuf[OUTS];
9+char *outp = outbuf;
10+Source *cursource;
11+int nerrs;
12+struct token nltoken = { NL, 0, 0, 0, 1, (uchar*)"\n" };
13+char *curtime;
14+int incdepth;
15+int ifdepth;
16+int ifsatisfied[NIF];
17+int skipping;
18+
19+void
20+main(int argc, char **argv)
21+{
22+ Tokenrow tr;
23+ long t;
24+ char ebuf[BUFSIZ];
25+
26+ setbuf(stderr, ebuf);
27+ t = time(NULL);
28+ curtime = ctime(t);
29+ maketokenrow(3, &tr);
30+ expandlex();
31+ setup(argc, argv);
32+ fixlex();
33+ iniths();
34+ genline();
35+ process(&tr);
36+ flushout();
37+ fflush(stderr);
38+ exits(nerrs? "errors" : 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+ switch (np->val) {
104+ case KENDIF:
105+ if (--ifdepth<skipping)
106+ skipping = 0;
107+ --cursource->ifdepth;
108+ setempty(trp);
109+ return;
110+
111+ case KIFDEF:
112+ case KIFNDEF:
113+ case KIF:
114+ if (++ifdepth >= NIF)
115+ error(FATAL, "#if too deeply nested");
116+ ++cursource->ifdepth;
117+ return;
118+
119+ case KELIF:
120+ case KELSE:
121+ if (ifdepth<=skipping)
122+ break;
123+ return;
124+
125+ default:
126+ return;
127+ }
128+ }
129+ switch (np->val) {
130+ case KDEFINE:
131+ dodefine(trp);
132+ break;
133+
134+ case KUNDEF:
135+ tp += 1;
136+ if (tp->type!=NAME || trp->lp - trp->bp != 4) {
137+ error(ERROR, "Syntax error in #undef");
138+ break;
139+ }
140+ if ((np = lookup(tp, 0)))
141+ np->flag &= ~ISDEFINED;
142+ break;
143+
144+ case KPRAGMA:
145+ return;
146+
147+ case KIFDEF:
148+ case KIFNDEF:
149+ case KIF:
150+ if (++ifdepth > NIF)
151+ error(FATAL, "#if too deeply nested");
152+ ++cursource->ifdepth;
153+ ifsatisfied[ifdepth] = 0;
154+ if (eval(trp, np->val))
155+ ifsatisfied[ifdepth] = 1;
156+ else
157+ skipping = ifdepth;
158+ break;
159+
160+ case KELIF:
161+ if (ifdepth==0) {
162+ error(ERROR, "#elif with no #if");
163+ return;
164+ }
165+ if (ifsatisfied[ifdepth]==2)
166+ error(ERROR, "#elif after #else");
167+ if (eval(trp, np->val)) {
168+ if (ifsatisfied[ifdepth])
169+ skipping = ifdepth;
170+ else {
171+ skipping = 0;
172+ ifsatisfied[ifdepth] = 1;
173+ }
174+ } else
175+ skipping = ifdepth;
176+ break;
177+
178+ case KELSE:
179+ if (ifdepth==0 || cursource->ifdepth==0) {
180+ error(ERROR, "#else with no #if");
181+ return;
182+ }
183+ if (ifsatisfied[ifdepth]==2)
184+ error(ERROR, "#else after #else");
185+ if (trp->lp - trp->bp != 3)
186+ error(ERROR, "Syntax error in #else");
187+ skipping = ifsatisfied[ifdepth]? ifdepth: 0;
188+ ifsatisfied[ifdepth] = 2;
189+ break;
190+
191+ case KENDIF:
192+ if (ifdepth==0 || cursource->ifdepth==0) {
193+ error(ERROR, "#endif with no #if");
194+ return;
195+ }
196+ --ifdepth;
197+ --cursource->ifdepth;
198+ if (trp->lp - trp->bp != 3)
199+ error(WARNING, "Syntax error in #endif");
200+ break;
201+
202+ case KERROR:
203+ trp->tp = tp+1;
204+ error(WARNING, "#error directive: %r", trp);
205+ break;
206+
207+ case KLINE:
208+ trp->tp = tp+1;
209+ expandrow(trp, "<line>");
210+ tp = trp->bp+2;
211+ kline:
212+ if (tp+1>=trp->lp || tp->type!=NUMBER || tp+3<trp->lp
213+ || (tp+3==trp->lp && ((tp+1)->type!=STRING)||*(tp+1)->t=='L')){
214+ error(ERROR, "Syntax error in #line");
215+ return;
216+ }
217+ cursource->line = atol((char*)tp->t)-1;
218+ if (cursource->line<0 || cursource->line>=32768)
219+ error(WARNING, "#line specifies number out of range");
220+ tp = tp+1;
221+ if (tp+1<trp->lp)
222+ cursource->filename=(char*)newstring(tp->t+1,tp->len-2,0);
223+ return;
224+
225+ case KDEFINED:
226+ error(ERROR, "Bad syntax for control line");
227+ break;
228+
229+ case KINCLUDE:
230+ doinclude(trp);
231+ trp->lp = trp->bp;
232+ return;
233+
234+ case KEVAL:
235+ eval(trp, np->val);
236+ break;
237+
238+ default:
239+ error(ERROR, "Preprocessor control `%t' not yet implemented", tp);
240+ break;
241+ }
242+ setempty(trp);
243+ return;
244+}
245+
246+void *
247+domalloc(int size)
248+{
249+ void *p = malloc(size);
250+
251+ if (p==NULL)
252+ error(FATAL, "Out of memory from malloc");
253+ return p;
254+}
255+
256+void
257+dofree(void *p)
258+{
259+ free(p);
260+}
261+
262+void
263+error(enum errtype type, char *string, ...)
264+{
265+ va_list ap;
266+ char *cp, *ep;
267+ Token *tp;
268+ Tokenrow *trp;
269+ int i;
270+
271+ if (*cursource->filename)
272+ fprintf(stderr, "cpp: %s:%d: ", cursource->filename, cursource->line);
273+ else
274+ fprintf(stderr, "cpp: ");
275+ va_start(ap, string);
276+ for (ep=string; *ep; ep++) {
277+ if (*ep=='%') {
278+ switch (*++ep) {
279+
280+ case 's':
281+ cp = va_arg(ap, char *);
282+ fprintf(stderr, "%s", cp);
283+ break;
284+ case 'd':
285+ i = va_arg(ap, int);
286+ fprintf(stderr, "%d", i);
287+ break;
288+ case 't':
289+ tp = va_arg(ap, Token *);
290+ fprintf(stderr, "%.*s", tp->len, tp->t);
291+ break;
292+
293+ case 'r':
294+ trp = va_arg(ap, Tokenrow *);
295+ for (tp=trp->tp; tp<trp->lp&&tp->type!=NL; tp++) {
296+ if (tp>trp->tp && tp->wslen)
297+ fputc(' ', stderr);
298+ fprintf(stderr, "%.*s", tp->len, tp->t);
299+ }
300+ break;
301+
302+ default:
303+ fputc(*ep, stderr);
304+ break;
305+ }
306+ } else
307+ fputc(*ep, stderr);
308+ }
309+ va_end(ap);
310+ fputc('\n', stderr);
311+ if (type==FATAL)
312+ exits("error");
313+ if (type!=WARNING)
314+ nerrs = 1;
315+ fflush(stderr);
316+}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t