home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / enterprs / cpm / utils / s / smc21src.lzh / CC22.C < prev    next >
Encoding:
Text File  |  1992-12-08  |  7.9 KB  |  402 lines

  1.  
  2. ifline() {
  3.   while(1) {
  4.     inline();
  5.     if(eof) return;
  6.     if(match("#ifdef")) {
  7.       ++iflevel;
  8.       if(skiplevel) continue;
  9.       blanks();
  10.       symname(msname, NO);        /*19*/
  11.       if(search(msname, macn, NAMESIZE+2, MACNEND, MACNBR, 0)==0) /*19*/
  12.         skiplevel=iflevel;
  13.       continue;
  14.       }
  15.     if(match("#ifndef")) {
  16.       ++iflevel;
  17.       if(skiplevel) continue;
  18.       symname(msname, NO);        /*19*/
  19.       if(search(msname, macn, NAMESIZE+2, MACNEND, MACNBR, 0))    /*19*/
  20.       skiplevel=iflevel;
  21.     continue;
  22.       }
  23.     if(match("#else")) {
  24.       if(iflevel) {
  25.         if(skiplevel==iflevel) skiplevel=0;
  26.         else if(skiplevel==0)  skiplevel=iflevel;
  27.         }
  28.       else noiferr();
  29.       continue;
  30.       }
  31.     if(match("#endif")) {
  32.       if(iflevel) {
  33.         if(skiplevel==iflevel) skiplevel=0;
  34.         --iflevel;
  35.         }
  36.       else noiferr();
  37.       continue;
  38.       }
  39.     if(skiplevel) continue;
  40.     if(listfp) {
  41.       if(listfp==output) cout(';', output);
  42.       sout(line, listfp);
  43.       }
  44.     if(ch==0) continue;
  45.     break;
  46.     }
  47.   }
  48.  
  49. keepch(c)  char c; {
  50.   if(pptr<LINEMAX) pline[++pptr]=c;
  51.   }
  52.  
  53. preprocess() {
  54.   int k;
  55.   char c;
  56.   if(ccode) {
  57.     line=mline;
  58.     ifline();
  59.     if(eof) return;
  60.     }
  61.   else {
  62.     line=pline;
  63.     inline();
  64.     return;
  65.     }
  66.   pptr = -1;
  67.   while(ch != '\n' && ch) {                 /*32*/
  68.     if(white()) {
  69.       keepch(' ');
  70.       while(white()) gch();
  71.       }
  72.     else if(ch=='"') {
  73.       keepch(ch);
  74.       gch();
  75.       while((ch!='"')|((*(lptr-1)==92)&(*(lptr-2)!=92))) {
  76.         if(ch==0) {
  77.           error("no quote");
  78.           break;
  79.           }
  80.         keepch(gch());
  81.         }
  82.       gch();
  83.       keepch('"');
  84.       }
  85.     else if(ch==39) {
  86.       keepch(39);
  87.       gch();
  88.       while((ch!=39)|((*(lptr-1)==92)&(*(lptr-2)!=92))) {
  89.         if(ch==0) {
  90.           error("no apostrophe");
  91.           break;
  92.           }
  93.         keepch(gch());
  94.         }
  95.       gch();
  96.       keepch(39);
  97.       }
  98.     else if((ch=='/')&(nch=='*')) {
  99.       bump(2);
  100.       while(((ch=='*')&(nch=='/'))==0) {
  101.         if(ch) bump(1);
  102.         else {
  103.           ifline();
  104.           if(eof) break;
  105.           }
  106.         }
  107.       bump(2);
  108.       }
  109.     else if(an(ch)) {
  110.       k=0;
  111.       while((an(ch)) & (k<NAMEMAX)) {             /*07*/
  112.         msname[k++]=ch;                           /*07*/
  113.         gch();
  114.         }
  115.       msname[k]=0;
  116.       if(search(msname, macn, NAMESIZE+2, MACNEND, MACNBR, 0)) {
  117.         k=getint(cptr+NAMESIZE, 2);
  118.         while(c=macq[k++]) keepch(c);
  119.         while(an(ch))  gch();                       /*07*/
  120.         }
  121.       else {
  122.         k=0;
  123.         while(c=msname[k++]) keepch(c);
  124.         }
  125.       }
  126.     else keepch(gch());
  127.     }
  128.   if(pptr>=LINEMAX) error("line too long");
  129.   keepch(0);
  130.   line=pline;
  131.   bump(0);
  132.   }
  133.  
  134. noiferr() {
  135.   error("no matching #if...");
  136.   errflag=0;
  137.   }
  138.  
  139. addmac() {
  140.   int k;
  141.   if(symname(msname, NO)==0) {
  142.     illname();
  143.     kill();
  144.     return;
  145.     }
  146.   k=0;
  147.   if(search(msname, macn, NAMESIZE+2, MACNEND, MACNBR, 0)==0) {
  148.     if(cptr2=cptr) while(*cptr2++ = msname[k++]);
  149.     else {
  150.       error("macro name table full");
  151.       return;
  152.       }
  153.     }
  154.   putint(macptr, cptr+NAMESIZE, 2);
  155.   while(white()) gch();
  156.   while(putmac(gch()));
  157.   if(macptr>=MACMAX) {
  158.     error("macro string queue full"); abort(ERRCODE);
  159.     }
  160.   }
  161. putmac(c)  char c; {
  162.  
  163.   macq[macptr]=c;
  164.   if(macptr<MACMAX) ++macptr;
  165.   return c;
  166.   }
  167.  
  168. /*
  169. ** search for symbol match
  170. ** on return cptr points to slot found or empty slot
  171. */
  172. search(sname, buf, len, end, max, off)
  173.   char *sname, *buf, *end;  int len, max, off; {
  174.   cptr=cptr2=buf+((hash(sname)%(max-1))*len);
  175.   while(*cptr != 0) {
  176.     if(astreq(sname, cptr+off, NAMEMAX)) return 1;
  177.     if((cptr=cptr+len) >= end) cptr=buf;
  178.     if(cptr == cptr2) return (cptr=0);
  179.     }
  180.   return 0;
  181.   }
  182.  
  183. hash(sname) char *sname; {
  184.   int i, c;
  185.   i=0;
  186.   while(c = *sname++) i=(i<<1)+c;
  187.   return i;
  188.   }
  189.  
  190. setstage(before, start) int *before, *start; {
  191.   if((*before=stagenext)==0) stagenext=stage;
  192.   *start=stagenext;
  193.   }
  194.  
  195. clearstage(before, start) char *before, *start; {
  196.   *stagenext=0;
  197.   if(stagenext=before) return;
  198.   if(start) {
  199.  
  200. #ifdef OPTIMIZE
  201.  
  202.     peephole(start);
  203.  
  204. #else /* OPTIMIZE */
  205.  
  206.     sout(start, output);
  207.  
  208. #endif /* OPTIMIZE */
  209.  
  210.     }
  211.   }
  212.  
  213. outdec(number)  int number; {
  214.   int k,zs;
  215.   char c, *q, *r;                       /*09*/
  216.   zs = 0;
  217.   k=10000;
  218.   if (number<0) {
  219.     number=(-number);
  220.     outbyte('-');
  221.     }
  222.   while (k>=1) {
  223.     q=0; r=number;                      /*09*/
  224.     while(r >= k) {++q; r -=k;}         /*09*/
  225.     c = q + '0';                        /*09*/
  226.     if ((c!='0')|(k==1)|(zs)) {
  227.       zs=1;
  228.       outbyte(c);
  229.       }
  230.     number = r;                         /*09*/
  231.     k=k/10;
  232.     }
  233.   }
  234.  
  235. ol(ptr)  char ptr[];  {
  236.   ot(ptr);
  237.   nl();
  238.   }
  239.  
  240. ot(ptr) char ptr[]; {
  241.   outstr(ptr);
  242.   }
  243.  
  244. outstr(ptr) char ptr[]; {
  245.   poll(1); /* allow program interruption */
  246.   /* must work with symbol table names terminated by length */
  247.   while(*ptr >= ' ') outbyte(*ptr++);
  248.   }
  249.  
  250. outbyte(c) char c; {
  251.   if(stagenext) {
  252.     if(stagenext==stagelast) {
  253.       error("staging buffer overflow");
  254.       return 0;
  255.       }
  256.     else *stagenext++ = c;
  257.     }
  258.   else cout(c,output);
  259.   return c;
  260.   }
  261.  
  262. cout(c, fd) char c; int fd; {
  263.   if(fputc(c, fd)==EOF) xout();
  264.   }
  265.  
  266. sout(string, fd) char *string; int fd; {
  267.   if(fputs(string, fd)==EOF) xout();
  268.   }
  269.  
  270. lout(line, fd) char *line; int fd; {
  271.   sout(line, fd);
  272.   cout('\n', fd);
  273.   }
  274.  
  275. xout() {
  276.   fputs("output error\n", stderr);
  277.   abort(ERRCODE);
  278.   }
  279.  
  280. nl() {
  281.   outbyte('\n');
  282.   }
  283.  
  284. col() {
  285.  
  286. #ifdef COL
  287.  
  288.   outbyte(':');
  289.  
  290. #endif /* COL */
  291.  
  292.   }
  293.  
  294. error(msg) char msg[]; {
  295.   if(errflag) return; else errflag=1;
  296.   lout(line, stderr);
  297.   errout(msg, stderr);
  298.   if(alarm) fputc(7, stderr);
  299.   /*
  300.   ** while reading from stderr is not strictly legal,
  301.   ** stderr will always be assigned to the user's terminal
  302.   ** (CON: on CP/M systems [should be /dev/tty on Unix]).
  303.   */
  304.   if(pause) while(fgetc(stderr)!='\n');
  305.   if(listfp>0) errout(msg, listfp);
  306.   }
  307.  
  308. errout(msg, fp) char msg[]; int fp; {
  309.   int k; k=line+2;
  310.   while(k++ <= lptr) cout(' ', fp);
  311.   lout("/\\", fp);
  312.   sout("**** ", fp); lout(msg, fp);
  313.   }
  314.  
  315. streq(str1,str2)  char str1[],str2[]; {
  316.   /* check for string equality over whole string */
  317.   int k;
  318.   k=0;
  319.   while (str2[k]) {
  320.     if ((str1[k])!=(str2[k])) return 0;
  321.     ++k;
  322.     }
  323.   return k;
  324.  }
  325.  
  326. astreq(str1,str2,len)  char str1[],str2[];int len; {
  327.   /* check for string equality over first 'len' characters */
  328.   int k;
  329.   k=0;
  330.   while (k<len) {
  331.     if ((str1[k])!=(str2[k]))break;
  332.     /*
  333.     ** must detect end of symbol table names terminated by
  334.     ** symbol length in binary
  335.     */
  336.     if(str1[k] < ' ') break;
  337.     if(str2[k] < ' ') break;
  338.     ++k;
  339.     }
  340.  
  341.   if (an(str1[k])) return 0;
  342.   if (an(str2[k])) return 0;
  343.  
  344.   return k;
  345.  }
  346.  
  347. match(lit)  char *lit; {
  348.   int k;
  349.   blanks();
  350.   if (k=streq(lptr,lit)) {
  351.     bump(k);
  352.     return 1;
  353.     }
  354.   return 0;
  355.   }
  356.  
  357. amatch(lit,len)  char *lit;int len; {
  358.   int k;
  359.   blanks();
  360.   if (k=astreq(lptr,lit,len)) {
  361.     bump(k);
  362.     while(an(ch)) inbyte();
  363.     return 1;
  364.     }
  365.   return 0;
  366.  }
  367.  
  368. nextop(list) char *list; {
  369.   char op[4];
  370.   opindex=0;
  371.   blanks();
  372.   while(1) {
  373.     opsize=0;
  374.     while(*list > ' ') op[opsize++] = *list++;
  375.     op[opsize]=0;
  376.     if(opsize=streq(lptr, op))
  377.       if((*(lptr+opsize) != '=')&
  378.          (*(lptr+opsize) != *(lptr+opsize-1)))
  379.          return 1;
  380.     if(*list) {
  381.       ++list;
  382.       ++opindex;
  383.       }
  384.     else return 0;
  385.     }
  386.   }
  387.  
  388. blanks() {
  389.   while(1) {
  390.     while(ch) {
  391.       if(white()) gch();
  392.       else return;
  393.       }
  394.     if(line==mline) return;
  395.  
  396.     preprocess();
  397.     if(eof) break;
  398.     }
  399.   }
  400.  
  401.  
  402.