home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / misc / emu / AROSdev.lha / AROS / compiler / vcpp / cpp.c next >
Encoding:
C/C++ Source or Header  |  1997-01-15  |  5.8 KB  |  323 lines

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