11 struct token nltoken = { NL, 0, 0, 0, 1, (uchar*)"\n" };
19 main(int argc, char **argv)
36 exits(nerrs? "errors" : 0);
41 process(Tokenrow *trp)
46 if (trp->tp >= trp->lp) {
47 trp->tp = trp->lp = trp->bp;
49 anymacros |= gettokens(trp, 1);
52 if (trp->tp->type == END) {
54 if (cursource->ifdepth)
56 "Unterminated conditional in #include");
58 cursource->line += cursource->lineinc;
64 error(ERROR, "Unterminated #if/#ifdef/#ifndef");
67 if (trp->tp->type==SHARP) {
70 } else if (!skipping && anymacros)
71 expandrow(trp, NULL, Notinmacro);
76 cursource->line += cursource->lineinc;
77 if (cursource->lineinc>1) {
84 control(Tokenrow *trp)
94 error(ERROR, "Unidentifiable control line");
95 return; /* else empty line */
97 if ((np = lookup(tp, 0))==NULL || (np->flag&ISKW)==0 && !skipping) {
98 error(WARNING, "Unknown preprocessor control %t", tp);
102 if ((np->flag&ISKW)==0)
106 if (--ifdepth<skipping)
108 --cursource->ifdepth;
115 if (++ifdepth >= NIF)
116 error(FATAL, "#if too deeply nested");
117 ++cursource->ifdepth;
122 if (ifdepth<=skipping)
137 if (tp->type!=NAME || trp->lp - trp->bp != 4) {
138 error(ERROR, "Syntax error in #undef");
141 if ((np = lookup(tp, 0))) {
142 if (np->flag&ISUNCHANGE) {
143 error(ERROR, "#defined token %t can't be undefined", tp);
146 np->flag &= ~ISDEFINED;
156 if (++ifdepth >= NIF)
157 error(FATAL, "#if too deeply nested");
158 ++cursource->ifdepth;
159 ifsatisfied[ifdepth] = 0;
160 if (eval(trp, np->val))
161 ifsatisfied[ifdepth] = 1;
168 error(ERROR, "#elif with no #if");
171 if (ifsatisfied[ifdepth]==2)
172 error(ERROR, "#elif after #else");
173 if (eval(trp, np->val)) {
174 if (ifsatisfied[ifdepth])
178 ifsatisfied[ifdepth] = 1;
185 if (ifdepth==0 || cursource->ifdepth==0) {
186 error(ERROR, "#else with no #if");
189 if (ifsatisfied[ifdepth]==2)
190 error(ERROR, "#else after #else");
191 if (trp->lp - trp->bp != 3)
192 error(ERROR, "Syntax error in #else");
193 skipping = ifsatisfied[ifdepth]? ifdepth: 0;
194 ifsatisfied[ifdepth] = 2;
198 if (ifdepth==0 || cursource->ifdepth==0) {
199 error(ERROR, "#endif with no #if");
203 --cursource->ifdepth;
204 if (trp->lp - trp->bp != 3)
205 error(WARNING, "Syntax error in #endif");
210 error(ERROR, "#error directive: %r", trp);
215 error(WARNING, "#warning directive: %r", trp);
220 expandrow(trp, "<line>", Notinmacro);
223 if (tp+1>=trp->lp || tp->type!=NUMBER || tp+3<trp->lp
224 || (tp+3==trp->lp && ((tp+1)->type!=STRING)||*(tp+1)->t=='L')){
225 error(ERROR, "Syntax error in #line");
228 cursource->line = atol((char*)tp->t)-1;
229 if (cursource->line<0 || cursource->line>=32768)
230 error(WARNING, "#line specifies number out of range");
233 cursource->filename=(char*)newstring(tp->t+1,tp->len-2,0);
237 error(ERROR, "Bad syntax for control line");
250 error(ERROR, "Preprocessor control `%t' not yet implemented", tp);
258 dorealloc(void *ptr, int size)
260 void *p = realloc(ptr, size);
263 error(FATAL, "Out of memory from realloc");
270 void *p = malloc(size);
273 error(FATAL, "Out of memory from malloc");
284 error(enum errtype type, char *string, ...)
294 fprintf(stderr, "cpp: ");
295 for (s=cursource; s; s=s->next)
297 fprintf(stderr, "%s:%d ", s->filename, s->line);
298 va_start(ap, string);
299 for (ep=string; *ep; ep++) {
304 cp = va_arg(ap, char *);
305 fprintf(stderr, "%s", cp);
309 fprintf(stderr, "%d", i);
312 p = va_arg(ap, void *);
313 fprintf(stderr, "%p", p);
316 tp = va_arg(ap, Token *);
317 fprintf(stderr, "%.*s", tp->len, tp->t);
321 trp = va_arg(ap, Tokenrow *);
322 for (tp=trp->tp; tp<trp->lp&&tp->type!=NL; tp++) {
323 if (tp>trp->tp && tp->wslen)
325 fprintf(stderr, "%.*s", tp->len, tp->t);