1*cdf0e10cSrcweir #include <stdio.h> 2*cdf0e10cSrcweir #include <stdlib.h> 3*cdf0e10cSrcweir #include <string.h> 4*cdf0e10cSrcweir #include <time.h> 5*cdf0e10cSrcweir #include <stdarg.h> 6*cdf0e10cSrcweir #include "cpp.h" 7*cdf0e10cSrcweir 8*cdf0e10cSrcweir #define OUTS 16384 9*cdf0e10cSrcweir char outbuf[OUTS]; 10*cdf0e10cSrcweir char *outptr = outbuf; 11*cdf0e10cSrcweir Source *cursource; 12*cdf0e10cSrcweir int nerrs; 13*cdf0e10cSrcweir struct token nltoken = {NL, 0, 0, 1, (uchar *) "\n", 0}; 14*cdf0e10cSrcweir char *curtime; 15*cdf0e10cSrcweir int incdepth; 16*cdf0e10cSrcweir int ifdepth; 17*cdf0e10cSrcweir int ifsatisfied[NIF]; 18*cdf0e10cSrcweir int skipping; 19*cdf0e10cSrcweir 20*cdf0e10cSrcweir char rcsid[] = "$Version 1.2 $ $Revision: 1.5 $ $Date: 2006-06-20 05:05:46 $"; 21*cdf0e10cSrcweir 22*cdf0e10cSrcweir int 23*cdf0e10cSrcweir #ifdef _WIN32 24*cdf0e10cSrcweir __cdecl 25*cdf0e10cSrcweir #endif // _WIN32 26*cdf0e10cSrcweir main(int argc, char **argv) 27*cdf0e10cSrcweir { 28*cdf0e10cSrcweir 29*cdf0e10cSrcweir Tokenrow tr; 30*cdf0e10cSrcweir time_t t; 31*cdf0e10cSrcweir char ebuf[BUFSIZ]; 32*cdf0e10cSrcweir 33*cdf0e10cSrcweir setbuf(stderr, ebuf); 34*cdf0e10cSrcweir t = time(NULL); 35*cdf0e10cSrcweir curtime = ctime(&t); 36*cdf0e10cSrcweir maketokenrow(3, &tr); 37*cdf0e10cSrcweir expandlex(); 38*cdf0e10cSrcweir setup(argc, argv); 39*cdf0e10cSrcweir fixlex(); 40*cdf0e10cSrcweir if (!Pflag) 41*cdf0e10cSrcweir genline(); 42*cdf0e10cSrcweir process(&tr); 43*cdf0e10cSrcweir flushout(); 44*cdf0e10cSrcweir fflush(stderr); 45*cdf0e10cSrcweir exit(nerrs > 0); 46*cdf0e10cSrcweir } 47*cdf0e10cSrcweir 48*cdf0e10cSrcweir void 49*cdf0e10cSrcweir process(Tokenrow * trp) 50*cdf0e10cSrcweir { 51*cdf0e10cSrcweir int anymacros = 0; 52*cdf0e10cSrcweir 53*cdf0e10cSrcweir for (;;) 54*cdf0e10cSrcweir { 55*cdf0e10cSrcweir if (trp->tp >= trp->lp) 56*cdf0e10cSrcweir { 57*cdf0e10cSrcweir trp->tp = trp->lp = trp->bp; 58*cdf0e10cSrcweir outptr = outbuf; 59*cdf0e10cSrcweir anymacros |= gettokens(trp, 1); 60*cdf0e10cSrcweir trp->tp = trp->bp; 61*cdf0e10cSrcweir } 62*cdf0e10cSrcweir if (trp->tp->type == END) 63*cdf0e10cSrcweir { 64*cdf0e10cSrcweir if (--incdepth >= 0) 65*cdf0e10cSrcweir { 66*cdf0e10cSrcweir if (cursource->ifdepth) 67*cdf0e10cSrcweir error(ERROR, 68*cdf0e10cSrcweir "Unterminated conditional in #include"); 69*cdf0e10cSrcweir unsetsource(); 70*cdf0e10cSrcweir cursource->line += cursource->lineinc; 71*cdf0e10cSrcweir trp->tp = trp->lp; 72*cdf0e10cSrcweir if (!Pflag) 73*cdf0e10cSrcweir genline(); 74*cdf0e10cSrcweir continue; 75*cdf0e10cSrcweir } 76*cdf0e10cSrcweir if (ifdepth) 77*cdf0e10cSrcweir error(ERROR, "Unterminated #if/#ifdef/#ifndef"); 78*cdf0e10cSrcweir break; 79*cdf0e10cSrcweir } 80*cdf0e10cSrcweir if (trp->tp->type == SHARP) 81*cdf0e10cSrcweir { 82*cdf0e10cSrcweir trp->tp += 1; 83*cdf0e10cSrcweir control(trp); 84*cdf0e10cSrcweir } 85*cdf0e10cSrcweir else 86*cdf0e10cSrcweir if (!skipping && anymacros) 87*cdf0e10cSrcweir expandrow(trp, NULL); 88*cdf0e10cSrcweir if (skipping) 89*cdf0e10cSrcweir setempty(trp); 90*cdf0e10cSrcweir puttokens(trp); 91*cdf0e10cSrcweir anymacros = 0; 92*cdf0e10cSrcweir cursource->line += cursource->lineinc; 93*cdf0e10cSrcweir if (cursource->lineinc > 1) 94*cdf0e10cSrcweir { 95*cdf0e10cSrcweir if (!Pflag) 96*cdf0e10cSrcweir genline(); 97*cdf0e10cSrcweir } 98*cdf0e10cSrcweir } 99*cdf0e10cSrcweir } 100*cdf0e10cSrcweir 101*cdf0e10cSrcweir void 102*cdf0e10cSrcweir control(Tokenrow * trp) 103*cdf0e10cSrcweir { 104*cdf0e10cSrcweir Nlist *np; 105*cdf0e10cSrcweir Token *tp; 106*cdf0e10cSrcweir 107*cdf0e10cSrcweir tp = trp->tp; 108*cdf0e10cSrcweir if (tp->type != NAME) 109*cdf0e10cSrcweir { 110*cdf0e10cSrcweir if (tp->type == NUMBER) 111*cdf0e10cSrcweir goto kline; 112*cdf0e10cSrcweir if (tp->type != NL) 113*cdf0e10cSrcweir error(ERROR, "Unidentifiable control line"); 114*cdf0e10cSrcweir return; /* else empty line */ 115*cdf0e10cSrcweir } 116*cdf0e10cSrcweir if ((np = lookup(tp, 0)) == NULL || ((np->flag & ISKW) == 0 && !skipping)) 117*cdf0e10cSrcweir { 118*cdf0e10cSrcweir error(WARNING, "Unknown preprocessor control %t", tp); 119*cdf0e10cSrcweir return; 120*cdf0e10cSrcweir } 121*cdf0e10cSrcweir if (skipping) 122*cdf0e10cSrcweir { 123*cdf0e10cSrcweir switch (np->val) 124*cdf0e10cSrcweir { 125*cdf0e10cSrcweir case KENDIF: 126*cdf0e10cSrcweir if (--ifdepth < skipping) 127*cdf0e10cSrcweir skipping = 0; 128*cdf0e10cSrcweir --cursource->ifdepth; 129*cdf0e10cSrcweir setempty(trp); 130*cdf0e10cSrcweir return; 131*cdf0e10cSrcweir 132*cdf0e10cSrcweir case KIFDEF: 133*cdf0e10cSrcweir case KIFNDEF: 134*cdf0e10cSrcweir case KIF: 135*cdf0e10cSrcweir if (++ifdepth >= NIF) 136*cdf0e10cSrcweir error(FATAL, "#if too deeply nested"); 137*cdf0e10cSrcweir ++cursource->ifdepth; 138*cdf0e10cSrcweir return; 139*cdf0e10cSrcweir 140*cdf0e10cSrcweir case KELIF: 141*cdf0e10cSrcweir case KELSE: 142*cdf0e10cSrcweir if (ifdepth <= skipping) 143*cdf0e10cSrcweir break; 144*cdf0e10cSrcweir return; 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir default: 147*cdf0e10cSrcweir return; 148*cdf0e10cSrcweir } 149*cdf0e10cSrcweir } 150*cdf0e10cSrcweir switch (np->val) 151*cdf0e10cSrcweir { 152*cdf0e10cSrcweir case KDEFINE: 153*cdf0e10cSrcweir dodefine(trp); 154*cdf0e10cSrcweir break; 155*cdf0e10cSrcweir 156*cdf0e10cSrcweir case KUNDEF: 157*cdf0e10cSrcweir tp += 1; 158*cdf0e10cSrcweir if (tp->type != NAME || trp->lp - trp->bp != 4) 159*cdf0e10cSrcweir { 160*cdf0e10cSrcweir error(ERROR, "Syntax error in #undef"); 161*cdf0e10cSrcweir break; 162*cdf0e10cSrcweir } 163*cdf0e10cSrcweir if ((np = lookup(tp, 0)) != NULL) 164*cdf0e10cSrcweir { 165*cdf0e10cSrcweir np->flag &= ~ISDEFINED; 166*cdf0e10cSrcweir 167*cdf0e10cSrcweir if (Mflag) 168*cdf0e10cSrcweir { 169*cdf0e10cSrcweir if (np->ap) 170*cdf0e10cSrcweir error(INFO, "Macro deletion of %s(%r)", np->name, np->ap); 171*cdf0e10cSrcweir else 172*cdf0e10cSrcweir error(INFO, "Macro deletion of %s", np->name); 173*cdf0e10cSrcweir } 174*cdf0e10cSrcweir } 175*cdf0e10cSrcweir break; 176*cdf0e10cSrcweir 177*cdf0e10cSrcweir case KPRAGMA: 178*cdf0e10cSrcweir case KIDENT: 179*cdf0e10cSrcweir for (tp = trp->tp - 1; ((tp->type != NL) && (tp < trp->lp)); tp++) 180*cdf0e10cSrcweir tp->type = UNCLASS; 181*cdf0e10cSrcweir return; 182*cdf0e10cSrcweir 183*cdf0e10cSrcweir case KIFDEF: 184*cdf0e10cSrcweir case KIFNDEF: 185*cdf0e10cSrcweir case KIF: 186*cdf0e10cSrcweir if (++ifdepth >= NIF) 187*cdf0e10cSrcweir error(FATAL, "#if too deeply nested"); 188*cdf0e10cSrcweir ++cursource->ifdepth; 189*cdf0e10cSrcweir ifsatisfied[ifdepth] = 0; 190*cdf0e10cSrcweir if (eval(trp, np->val)) 191*cdf0e10cSrcweir ifsatisfied[ifdepth] = 1; 192*cdf0e10cSrcweir else 193*cdf0e10cSrcweir skipping = ifdepth; 194*cdf0e10cSrcweir break; 195*cdf0e10cSrcweir 196*cdf0e10cSrcweir case KELIF: 197*cdf0e10cSrcweir if (ifdepth == 0) 198*cdf0e10cSrcweir { 199*cdf0e10cSrcweir error(ERROR, "#elif with no #if"); 200*cdf0e10cSrcweir return; 201*cdf0e10cSrcweir } 202*cdf0e10cSrcweir if (ifsatisfied[ifdepth] == 2) 203*cdf0e10cSrcweir error(ERROR, "#elif after #else"); 204*cdf0e10cSrcweir if (eval(trp, np->val)) 205*cdf0e10cSrcweir { 206*cdf0e10cSrcweir if (ifsatisfied[ifdepth]) 207*cdf0e10cSrcweir skipping = ifdepth; 208*cdf0e10cSrcweir else 209*cdf0e10cSrcweir { 210*cdf0e10cSrcweir skipping = 0; 211*cdf0e10cSrcweir ifsatisfied[ifdepth] = 1; 212*cdf0e10cSrcweir } 213*cdf0e10cSrcweir } 214*cdf0e10cSrcweir else 215*cdf0e10cSrcweir skipping = ifdepth; 216*cdf0e10cSrcweir break; 217*cdf0e10cSrcweir 218*cdf0e10cSrcweir case KELSE: 219*cdf0e10cSrcweir if (ifdepth == 0 || cursource->ifdepth == 0) 220*cdf0e10cSrcweir { 221*cdf0e10cSrcweir error(ERROR, "#else with no #if"); 222*cdf0e10cSrcweir return; 223*cdf0e10cSrcweir } 224*cdf0e10cSrcweir if (ifsatisfied[ifdepth] == 2) 225*cdf0e10cSrcweir error(ERROR, "#else after #else"); 226*cdf0e10cSrcweir if (trp->lp - trp->bp != 3) 227*cdf0e10cSrcweir error(ERROR, "Syntax error in #else"); 228*cdf0e10cSrcweir skipping = ifsatisfied[ifdepth] ? ifdepth : 0; 229*cdf0e10cSrcweir ifsatisfied[ifdepth] = 2; 230*cdf0e10cSrcweir break; 231*cdf0e10cSrcweir 232*cdf0e10cSrcweir case KENDIF: 233*cdf0e10cSrcweir if (ifdepth == 0 || cursource->ifdepth == 0) 234*cdf0e10cSrcweir { 235*cdf0e10cSrcweir error(ERROR, "#endif with no #if"); 236*cdf0e10cSrcweir return; 237*cdf0e10cSrcweir } 238*cdf0e10cSrcweir --ifdepth; 239*cdf0e10cSrcweir --cursource->ifdepth; 240*cdf0e10cSrcweir if (trp->lp - trp->bp != 3) 241*cdf0e10cSrcweir error(WARNING, "Syntax error in #endif"); 242*cdf0e10cSrcweir break; 243*cdf0e10cSrcweir 244*cdf0e10cSrcweir case KERROR: 245*cdf0e10cSrcweir trp->tp = tp + 1; 246*cdf0e10cSrcweir error(WARNING, "#error directive: %r", trp); 247*cdf0e10cSrcweir break; 248*cdf0e10cSrcweir 249*cdf0e10cSrcweir case KLINE: 250*cdf0e10cSrcweir trp->tp = tp + 1; 251*cdf0e10cSrcweir expandrow(trp, "<line>"); 252*cdf0e10cSrcweir tp = trp->bp + 2; 253*cdf0e10cSrcweir kline: 254*cdf0e10cSrcweir if (tp + 1 >= trp->lp || tp->type != NUMBER || tp + 3 < trp->lp 255*cdf0e10cSrcweir || (tp + 3 == trp->lp 256*cdf0e10cSrcweir && ((tp + 1)->type != STRING || *(tp + 1)->t == 'L'))) 257*cdf0e10cSrcweir { 258*cdf0e10cSrcweir error(ERROR, "Syntax error in #line"); 259*cdf0e10cSrcweir return; 260*cdf0e10cSrcweir } 261*cdf0e10cSrcweir cursource->line = atol((char *) tp->t) - 1; 262*cdf0e10cSrcweir if (cursource->line < 0 || cursource->line >= 32768) 263*cdf0e10cSrcweir error(WARNING, "#line specifies number out of range"); 264*cdf0e10cSrcweir tp = tp + 1; 265*cdf0e10cSrcweir if (tp + 1 < trp->lp) 266*cdf0e10cSrcweir cursource->filename = (char *) newstring(tp->t + 1, tp->len - 2, 0); 267*cdf0e10cSrcweir return; 268*cdf0e10cSrcweir 269*cdf0e10cSrcweir case KDEFINED: 270*cdf0e10cSrcweir error(ERROR, "Bad syntax for control line"); 271*cdf0e10cSrcweir break; 272*cdf0e10cSrcweir 273*cdf0e10cSrcweir case KIMPORT: 274*cdf0e10cSrcweir doinclude(trp, -1, 1); 275*cdf0e10cSrcweir trp->lp = trp->bp; 276*cdf0e10cSrcweir return; 277*cdf0e10cSrcweir 278*cdf0e10cSrcweir case KINCLUDE: 279*cdf0e10cSrcweir doinclude(trp, -1, 0); 280*cdf0e10cSrcweir trp->lp = trp->bp; 281*cdf0e10cSrcweir return; 282*cdf0e10cSrcweir 283*cdf0e10cSrcweir case KINCLUDENEXT: 284*cdf0e10cSrcweir doinclude(trp, cursource->pathdepth, 0); 285*cdf0e10cSrcweir trp->lp = trp->bp; 286*cdf0e10cSrcweir return; 287*cdf0e10cSrcweir 288*cdf0e10cSrcweir case KEVAL: 289*cdf0e10cSrcweir eval(trp, np->val); 290*cdf0e10cSrcweir break; 291*cdf0e10cSrcweir 292*cdf0e10cSrcweir default: 293*cdf0e10cSrcweir error(ERROR, "Preprocessor control `%t' not yet implemented", tp); 294*cdf0e10cSrcweir break; 295*cdf0e10cSrcweir } 296*cdf0e10cSrcweir setempty(trp); 297*cdf0e10cSrcweir return; 298*cdf0e10cSrcweir } 299*cdf0e10cSrcweir 300*cdf0e10cSrcweir void * 301*cdf0e10cSrcweir domalloc(int size) 302*cdf0e10cSrcweir { 303*cdf0e10cSrcweir void *p = malloc(size); 304*cdf0e10cSrcweir 305*cdf0e10cSrcweir if (p == NULL) 306*cdf0e10cSrcweir error(FATAL, "Out of memory from malloc"); 307*cdf0e10cSrcweir return p; 308*cdf0e10cSrcweir } 309*cdf0e10cSrcweir 310*cdf0e10cSrcweir void 311*cdf0e10cSrcweir dofree(void *p) 312*cdf0e10cSrcweir { 313*cdf0e10cSrcweir free(p); 314*cdf0e10cSrcweir } 315*cdf0e10cSrcweir 316*cdf0e10cSrcweir void 317*cdf0e10cSrcweir error(enum errtype type, char *string,...) 318*cdf0e10cSrcweir { 319*cdf0e10cSrcweir va_list ap; 320*cdf0e10cSrcweir char c, *cp, *ep; 321*cdf0e10cSrcweir Token *tp; 322*cdf0e10cSrcweir Tokenrow *trp; 323*cdf0e10cSrcweir Source *s; 324*cdf0e10cSrcweir int i; 325*cdf0e10cSrcweir 326*cdf0e10cSrcweir fprintf(stderr, "cpp: "); 327*cdf0e10cSrcweir for (s = cursource; s; s = s->next) 328*cdf0e10cSrcweir if (*s->filename) 329*cdf0e10cSrcweir fprintf(stderr, "%s:%d ", s->filename, s->line); 330*cdf0e10cSrcweir va_start(ap, string); 331*cdf0e10cSrcweir for (ep = string; *ep; ep++) 332*cdf0e10cSrcweir { 333*cdf0e10cSrcweir if (*ep == '%') 334*cdf0e10cSrcweir { 335*cdf0e10cSrcweir switch (*++ep) 336*cdf0e10cSrcweir { 337*cdf0e10cSrcweir 338*cdf0e10cSrcweir case 'c': 339*cdf0e10cSrcweir c = (char) va_arg(ap, int); 340*cdf0e10cSrcweir fprintf(stderr, "%c", c); 341*cdf0e10cSrcweir break; 342*cdf0e10cSrcweir 343*cdf0e10cSrcweir case 's': 344*cdf0e10cSrcweir cp = va_arg(ap, char *); 345*cdf0e10cSrcweir fprintf(stderr, "%s", cp); 346*cdf0e10cSrcweir break; 347*cdf0e10cSrcweir 348*cdf0e10cSrcweir case 'd': 349*cdf0e10cSrcweir i = va_arg(ap, int); 350*cdf0e10cSrcweir fprintf(stderr, "%d", i); 351*cdf0e10cSrcweir break; 352*cdf0e10cSrcweir 353*cdf0e10cSrcweir case 't': 354*cdf0e10cSrcweir tp = va_arg(ap, Token *); 355*cdf0e10cSrcweir fprintf(stderr, "%.*s", (int)tp->len, tp->t); 356*cdf0e10cSrcweir break; 357*cdf0e10cSrcweir 358*cdf0e10cSrcweir case 'r': 359*cdf0e10cSrcweir trp = va_arg(ap, Tokenrow *); 360*cdf0e10cSrcweir for (tp = trp->tp; tp < trp->lp && tp->type != NL; tp++) 361*cdf0e10cSrcweir { 362*cdf0e10cSrcweir if (tp > trp->tp && tp->wslen) 363*cdf0e10cSrcweir fputc(' ', stderr); 364*cdf0e10cSrcweir fprintf(stderr, "%.*s", (int)tp->len, tp->t); 365*cdf0e10cSrcweir } 366*cdf0e10cSrcweir break; 367*cdf0e10cSrcweir 368*cdf0e10cSrcweir default: 369*cdf0e10cSrcweir fputc(*ep, stderr); 370*cdf0e10cSrcweir break; 371*cdf0e10cSrcweir } 372*cdf0e10cSrcweir } 373*cdf0e10cSrcweir else 374*cdf0e10cSrcweir fputc(*ep, stderr); 375*cdf0e10cSrcweir } 376*cdf0e10cSrcweir va_end(ap); 377*cdf0e10cSrcweir fputc('\n', stderr); 378*cdf0e10cSrcweir if (type == FATAL) 379*cdf0e10cSrcweir exit(1); 380*cdf0e10cSrcweir if (type != WARNING) 381*cdf0e10cSrcweir nerrs = 1; 382*cdf0e10cSrcweir fflush(stderr); 383*cdf0e10cSrcweir } 384