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
8char outbuf[OUTS];
9char *outp = outbuf;
10Source *cursource;
11int nerrs;
12struct token nltoken = { NL, 0, 0, 0, 1, (uchar*)"\n" };
13char *curtime;
14int incdepth;
15int ifdepth;
16int ifsatisfied[NIF];
17int skipping;
18
19void
20main(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
41void
42process(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
84void
85control(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
246void *
247domalloc(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
256void
257dofree(void *p)
258{
259 free(p);
260}
261
262void
263error(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