11 struct token nltoken = { NL, 0, 0, 0, 1, (uchar*)"\n" };
19 main(int argc, char **argv)
37 exits(nerrs? "errors" : 0);
42 process(Tokenrow *trp)
47 if (trp->tp >= trp->lp) {
48 trp->tp = trp->lp = trp->bp;
50 anymacros |= gettokens(trp, 1);
53 if (trp->tp->type == END) {
55 if (cursource->ifdepth)
57 "Unterminated conditional in #include");
59 cursource->line += cursource->lineinc;
65 error(ERROR, "Unterminated #if/#ifdef/#ifndef");
68 if (trp->tp->type==SHARP) {
71 } else if (!skipping && anymacros)
72 expandrow(trp, NULL, Notinmacro);
77 cursource->line += cursource->lineinc;
78 if (cursource->lineinc>1) {
85 control(Tokenrow *trp)
95 error(ERROR, "Unidentifiable control line");
96 return; /* else empty line */
98 if ((np = lookup(tp, 0))==NULL || (np->flag&ISKW)==0 && !skipping) {
99 error(WARNING, "Unknown preprocessor control %t", tp);
103 if ((np->flag&ISKW)==0)
107 if (--ifdepth<skipping)
109 --cursource->ifdepth;
116 if (++ifdepth >= NIF)
117 error(FATAL, "#if too deeply nested");
118 ++cursource->ifdepth;
123 if (ifdepth<=skipping)
138 if (tp->type!=NAME || trp->lp - trp->bp != 4) {
139 error(ERROR, "Syntax error in #undef");
142 if ((np = lookup(tp, 0))) {
143 if (np->flag&ISUNCHANGE) {
144 error(ERROR, "#defined token %t can't be undefined", tp);
147 np->flag &= ~ISDEFINED;
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;
169 error(ERROR, "#elif with no #if");
172 if (ifsatisfied[ifdepth]==2)
173 error(ERROR, "#elif after #else");
174 if (eval(trp, np->val)) {
175 if (ifsatisfied[ifdepth])
179 ifsatisfied[ifdepth] = 1;
186 if (ifdepth==0 || cursource->ifdepth==0) {
187 error(ERROR, "#else with no #if");
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;
199 if (ifdepth==0 || cursource->ifdepth==0) {
200 error(ERROR, "#endif with no #if");
204 --cursource->ifdepth;
205 if (trp->lp - trp->bp != 3)
206 error(WARNING, "Syntax error in #endif");
211 error(ERROR, "#error directive: %r", trp);
216 error(WARNING, "#warning directive: %r", trp);
221 expandrow(trp, "<line>", Notinmacro);
224 if (tp+1>=trp->lp || tp->type!=NUMBER || tp+3<trp->lp
225 || (tp+3==trp->lp && ((tp+1)->type!=STRING)||*(tp+1)->t=='L')){
226 error(ERROR, "Syntax error in #line");
229 cursource->line = atol((char*)tp->t)-1;
230 if (cursource->line<0 || cursource->line>=32768)
231 error(WARNING, "#line specifies number out of range");
234 cursource->filename=(char*)newstring(tp->t+1,tp->len-2,0);
238 error(ERROR, "Bad syntax for control line");
251 error(ERROR, "Preprocessor control `%t' not yet implemented", tp);
259 dorealloc(void *ptr, int size)
261 void *p = realloc(ptr, size);
264 error(FATAL, "Out of memory from realloc");
271 void *p = malloc(size);
274 error(FATAL, "Out of memory from malloc");
285 error(enum errtype type, char *string, ...)
295 fprintf(stderr, "cpp: ");
296 for (s=cursource; s; s=s->next)
298 fprintf(stderr, "%s:%d ", s->filename, s->line);
299 va_start(ap, string);
300 for (ep=string; *ep; ep++) {
305 cp = va_arg(ap, char *);
306 fprintf(stderr, "%s", cp);
310 fprintf(stderr, "%d", i);
313 p = va_arg(ap, void *);
314 fprintf(stderr, "%p", p);
317 tp = va_arg(ap, Token *);
318 fprintf(stderr, "%.*s", tp->len, tp->t);
322 trp = va_arg(ap, Tokenrow *);
323 for (tp=trp->tp; tp<trp->lp&&tp->type!=NL; tp++) {
324 if (tp>trp->tp && tp->wslen)
326 fprintf(stderr, "%.*s", tp->len, tp->t);