home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 163_01 / cc22.c < prev    next >
Text File  |  1990-11-20  |  9KB  |  465 lines

  1. ifline() {
  2.   char *ptr, mname[NAMESIZE];
  3.   while(1) {
  4.     inline();
  5.     if(eof) return;
  6.     if(match("#ifdef")) {
  7.       ++iflevel;
  8.       if(skiplevel) continue;
  9.       blanks();
  10.       if(symname(mname, NO)==0) {
  11.         illname();
  12.         kill();
  13.         continue;
  14.         }
  15. #ifdef HASH
  16.       if(search(mname, macm, NAMESIZE+2, MACNEND, MACNBR, 0)==0)
  17. #else
  18.       if(findmac(mname)==0)
  19. #endif
  20.         skiplevel=iflevel;
  21.       continue;
  22.       }
  23.     if(match("#ifndef")) {
  24.       ++iflevel;
  25.       if(skiplevel) continue;
  26.       blanks();
  27.       if(symname(mname, NO)==0) {
  28.         illname();
  29.         kill();
  30.         continue;
  31.         }
  32. #ifdef HASH
  33.       if(search(mname, macn, NAMESIZE+2, MACNEND, MACNBR, 0))
  34. #else
  35.       if(findmac(mname))
  36. #endif
  37.         skiplevel=iflevel;
  38.       continue;
  39.       }
  40.     if(match("#else")) {
  41.       if(iflevel) {
  42.         if(skiplevel==iflevel) skiplevel=0;
  43.         else if(skiplevel==0)  skiplevel=iflevel;
  44.         }
  45.       else noiferr();
  46.       continue;
  47.       }
  48.     if(match("#endif")) {
  49.       if(iflevel) {
  50.         if(skiplevel==iflevel) skiplevel=0;
  51.         --iflevel;
  52.         }
  53.       else noiferr();
  54.       continue;
  55.       }
  56.     if(skiplevel) continue;
  57.     if(ctext) { /* if interleaving source */
  58.       /* interleave only non-blank lines */
  59.       ptr = line;
  60.       while(*ptr) if(*ptr == ' ') ++ptr; else break;
  61.       if(*ptr) { /* if non-blank */
  62.         comment();
  63.         lout(line, output);
  64.         }
  65.       }
  66.     if(listfp) {
  67.       lout(line, listfp);
  68.       }
  69.     if(ch==0) continue;
  70.     break;
  71.     }
  72.   }
  73.  
  74. keepch(c) char c; {
  75.   if(pptr<LINEMAX) pline[++pptr]=c;
  76.   }
  77.  
  78. preprocess() {
  79.   int k;
  80.   char c;
  81.   if(ccode) {
  82.     line=mline;
  83.     ifline();
  84.     if(eof) return;
  85.     }
  86.   else {
  87.     line=pline;
  88.     inline();
  89.     return;
  90.     }
  91.   pptr = -1;
  92.   while(ch) {
  93.     if(white()) {
  94.       keepch(' ');
  95.       while(white()) gch();
  96.       }
  97.     else if(ch=='"') {
  98.       keepch(ch);
  99.       gch();
  100.       while((ch!='"')|((*(lptr-1)==92)&(*(lptr-2)!=92))) {
  101.         if(ch==0) {
  102.           error("no quote");
  103.           break;
  104.           }
  105.         keepch(gch());
  106.         }
  107.       gch();
  108.       keepch('"');
  109.       }
  110.     else if(ch==39) {
  111.       keepch(39);
  112.       gch();
  113.       while((ch!=39)|((*(lptr-1)==92)&(*(lptr-2)!=92))) {
  114.         if(ch==0) {
  115.           error("no apostrophe");
  116.           break;
  117.           }
  118.         keepch(gch());
  119.         }
  120.       gch();
  121.       keepch(39);
  122.       }
  123.     else if((ch=='/')&(nch=='*')) {
  124.       bump(2);
  125.       while(((ch=='*')&(nch=='/'))==0) {
  126.         if(ch) bump(1);
  127.         else {
  128.           ifline();
  129.           if(eof) break;
  130.           }
  131.         }
  132.       bump(2);
  133.       }
  134.     else if(an(ch)) {
  135.       k=0;
  136.       while(an(ch)) {
  137.         if(k<NAMEMAX) msname[k++]=ch;
  138.         gch();
  139.         }
  140.       msname[k]=0;
  141. #ifdef HASH
  142.       if(search(msname, macn, NAMESIZE+2, MACNEND, MACNBR, 0)) {
  143.         k=getint(cptr+NAMESIZE, 2);
  144.         while(c=macq[k++]) keepch(c);
  145.         }
  146. #else
  147.       if(k=findmac(msname)) while(c=macq[k++]) keepch(c);
  148. #endif
  149.       else {
  150.         k=0;
  151.         while(c=msname[k++]) keepch(c);
  152.         }
  153.       }
  154.     else keepch(gch());
  155.     }
  156.   if(pptr>=LINEMAX) error("line too long");
  157.   keepch(0);
  158.   line=pline;
  159.   bump(0);
  160.   }
  161.  
  162. noiferr() {
  163.   error("no matching #if...");
  164.   errflag=0;
  165.   }
  166.  
  167. addmac() {
  168.   int k;
  169.   if(symname(msname, NO)==0) {
  170.     illname();
  171.     kill();
  172.     return;
  173.     }
  174.   k=0;
  175. #ifdef HASH
  176.   if(search(msname, macn, NAMESIZE+2, MACNEND, MACNBR, 0)==0) {
  177.     if(cptr2=cptr) while(*cptr2++ = msname[k++]);
  178.     else {
  179.       error("macro name table full");
  180.       return;
  181.       }
  182.     }
  183.   putint(macptr, cptr+NAMESIZE, 2);
  184. #else
  185.   while(putmac(msname[k++]));
  186. #endif
  187.   while(white()) gch();
  188.   while(putmac(gch()));
  189.   if(macptr>=MACMAX) {
  190.     error("macro string queue full"); exit(EUSER);
  191.     }
  192.   }
  193.  
  194. putmac(c) char c; {
  195.   macq[macptr]=c;
  196.   if(macptr<MACMAX) ++macptr;
  197.   return c;
  198.   }
  199.  
  200. #ifdef HASH
  201. /*
  202. ** search for symbol match
  203. ** on return cptr points to slot found or empty slot
  204. */
  205. search(sname, buf, len, end, max, off)
  206.   char *sname, *buf, *end; int len, max, off; {
  207.   cptr=cptr2=buf+((hash(sname)%(max-1))*len);
  208.   while(*cptr != 0) {
  209.     if(astreq(sname, cptr+off, NAMEMAX)) return 1;
  210.     if((cptr=cptr+len) >= end) cptr=buf;
  211.     if(cptr == cptr2) return (cptr=0);
  212.     }
  213.   return 0;
  214.   }
  215.  
  216. hash(sname) char *sname; {
  217.   int i, c;
  218.   i=0;
  219.   while(c=*sname++) i=(i<<1)+c;
  220.   return i;
  221.   }
  222.  
  223. #else
  224.  
  225. findmac(sname) char *sname; {
  226.   mack=0;
  227.   while(mack<macptr) {
  228.     if(astreq(sname,macq+mack,NAMEMAX)) {
  229.       while(macq[mack++]);
  230.       return mack;
  231.       }
  232.     while(macq[mack++]);
  233.     while(macq[mack++]);
  234.     }
  235.   return 0;
  236.   }
  237. #endif
  238.  
  239. setstage(before, start) int *before, *start; {
  240.   if((*before=stagenext)==0) stagenext=stage; /* save last byte already
  241.                                   generated and, if starting outermost expr,
  242.                                   point to the front of the staging buffer */
  243.   *start=stagenext; /* first byte generated at this level of nesting */
  244.   }
  245.  
  246. clearstage(before, start) char *before, *start; {
  247.   *stagenext=0; /* terminate current character string */
  248.   if(stagenext=before) return; /* defer all code output until outermost
  249.                                   expression is exited */
  250.   if(start) { /* if code is not to be flushed, output it --
  251.                                   note that this will only be done when
  252.                                   exiting outermost expression, and thus,
  253.                                   start addresses the front of the buffer */
  254.     peephole(start);
  255.     }
  256.   }
  257.  
  258. outdec(number)  int number; {
  259.   int k,zs;
  260.   char c;
  261.   zs = 0;
  262.   k=10000;
  263.   if (number<0) {
  264.     number=(-number);
  265.     outbyte('-');
  266.     }
  267.   if(number < 0) { /* must have been -32768 */
  268.     outstr("32768");
  269.     }
  270.   else while (k>=1) {
  271.     c=number/k + '0';
  272.     if ((c!='0')|(k==1)|(zs)) {
  273.       zs=1;
  274.       outbyte(c);
  275.       }
  276.     number=number%k;
  277.     k=k/10;
  278.     }
  279.   }
  280.  
  281. errdec(number)  int number; {
  282.   int k,zs;
  283.   char c;
  284.   zs = 0;
  285.   k=10000;
  286.   if (number<0) {
  287.     number=(-number);
  288.     cout('-', stderr);
  289.     }
  290.   if(number < 0) { /* must have been -32768 */
  291.     outstr("32768");
  292.     }
  293.   else while (k>=1) {
  294.     c=number/k + '0';
  295.     if ((c!='0')|(k==1)|(zs)) {
  296.       zs=1;
  297.       cout(c, stderr);
  298.       }
  299.     number=number%k;
  300.     k=k/10;
  301.     }
  302.   }
  303.  
  304. ol(ptr)  char ptr[];  {
  305.   ot(ptr);
  306.   nl();
  307.   }
  308.  
  309. ot(ptr) char ptr[]; {
  310.   tab();
  311.   outstr(ptr);
  312.   }
  313.  
  314. outstr(ptr) char ptr[]; {
  315.   /* must work with symbol table names terminated by length */
  316.   while(*ptr >= ' ') outbyte(*ptr++);
  317.   }
  318.  
  319. errstr(ptr) char ptr[]; {
  320.   /* must work with symbol table names terminated by length */
  321.   while(*ptr >= ' ') cout(*ptr++, stderr);
  322.   }
  323.  
  324. outbyte(c) char c; {
  325.   if(stagenext) {
  326.     if(stagenext==stagelast) {
  327.       error("staging buffer overflow");
  328.       return 0;
  329.       }
  330.     else *stagenext++ = c;
  331.     }
  332.   else cout(c,output);
  333.   return c;
  334.   }
  335.  
  336. cout(c, fd) char c; int fd; {
  337.   if(fputc(c, fd)==EOF) xout();
  338.   }
  339.  
  340. sout(string, fd) char *string; int fd; {
  341.   if(fputs(string, fd)==EOF) xout();
  342.   }
  343.  
  344. lout(line, fd) char *line; int fd; {
  345.   sout(line, fd);
  346.   cout('\n', fd);
  347.   }
  348.  
  349. xout() {
  350.   fputs("output error\n", stderr);
  351.   abort(errno);
  352.   }
  353.  
  354. nl() {
  355.   outbyte('\n');
  356.   }
  357.  
  358. tab() {
  359.   outbyte(TAB);
  360.   }
  361.  
  362. col() {
  363.   outbyte(':');
  364.   }
  365.  
  366. error(msg) char msg[]; {
  367.   if(errflag) return; else errflag=1;
  368.   ++errcnt;
  369.   lout(line, stderr);
  370.   errout(msg, stderr);
  371.   if(alarm) fputc(7, stderr);
  372.   if(pause) while(fgetc(stderr)!='\n');
  373.   if(listfp>0) errout(msg, listfp);
  374.   }
  375.  
  376. errout(msg, fp) char msg[]; int fp; {
  377.   int k; k=line+2;
  378.   while(k++ <= lptr) cout(' ', fp);
  379.   lout("/\\", fp);
  380.   sout("**** ",fp); lout(msg, fp);
  381.   }
  382.  
  383. streq(str1,str2) char str1[],str2[]; {
  384.   int k;
  385.   k=0;
  386.   while (str2[k]) {
  387.     if ((str1[k])!=(str2[k])) return 0;
  388.     ++k;
  389.     }
  390.   return k;
  391.   }
  392.  
  393. astreq(str1,str2,len) char str1[],str2[];int len; {
  394.   int k;
  395.   k=0;
  396.   while (k<len) {
  397.     if ((str1[k])!=(str2[k]))break;
  398.     /*
  399.     ** must detect end of symbol table names terminated by
  400.     ** symbol length in binary
  401.     */
  402.     if(str1[k] < ' ') break;
  403.     if(str2[k] < ' ') break;
  404.     ++k;
  405.     }
  406.   if (an(str1[k]))return 0;
  407.   if (an(str2[k]))return 0;
  408.   return k;
  409.   }
  410.  
  411. match(lit)  char *lit; {
  412.   int k;
  413.   blanks();
  414.   if (k=streq(lptr,lit)) {
  415.     bump(k);
  416.     return 1;
  417.     }
  418.   return 0;
  419.   }
  420.  
  421. amatch(lit,len)  char *lit;int len; {
  422.   int k;
  423.   blanks();
  424.   if(k=astreq(lptr,lit,len)) {
  425.     bump(k);
  426.     while(an(ch)) inbyte();
  427.     return 1;
  428.     }
  429.   return 0;
  430.   }
  431.  
  432. nextop(list) char *list; {
  433.   char op[4];
  434.   opindex=0;
  435.   blanks();
  436.   while(1) {
  437.     opsize=0;
  438.     while(*list > ' ') op[opsize++]=*list++;
  439.     op[opsize]=0;
  440.     if(opsize=streq(lptr, op))
  441.       if((*(lptr+opsize) != '=')&
  442.          (*(lptr+opsize) != *(lptr+opsize-1)))
  443.          return 1;
  444.       if(*list) {
  445.         ++list;
  446.         ++opindex;
  447.         }
  448.       else return 0;
  449.       }
  450.     }
  451.  
  452. blanks() {
  453.   while(1) {
  454.     while(ch) {
  455.       if(white()) gch();
  456.       else return;
  457.       }
  458.     if(line==mline) return;
  459.     preprocess();
  460.     if(eof)break;
  461.     }
  462.   }
  463.  
  464.  
  465.