home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 163_01 / cc11.c < prev    next >
Text File  |  1991-01-07  |  13KB  |  463 lines

  1. /*
  2. ** execution begins here
  3. */
  4. #ifdef CMD_LINE
  5. main(argc, argv) int argc, *argv; {
  6.   argcs=argc;
  7.   argvs=argv;
  8. #else
  9. main() {
  10. #endif
  11.   sout("Small-C Version 2.0 for the IBM PC -- Release 1.01\n", stderr);
  12.   sout("Portions Copyright 1982 by J. E. Hendrix\n", stderr);
  13.   sout("Converted to the IBM PC by D. R. Hicks\n", stderr);
  14.   sout("\n", stderr);
  15. #ifdef DYNAMIC
  16.   swnext=malloc(SWTABSZ);
  17.   swend=swnext+((SWTABSZ-SWSIZ)>>1);
  18.   stage=malloc(STAGESIZE);
  19.   stagelast=stage+STAGELIMIT;
  20.   wq=malloc(WQTABSZ*BPW);
  21.   litq=malloc(LITABSZ);
  22. #ifdef HASH
  23.   macn=malloc(MACNSIZE);
  24.   cptr=macn-1;
  25.   while(++cptr < MACNEND) *cptr=0;
  26. #endif
  27.   macq=malloc(MACQSIZE);
  28.   pline=malloc(LINESIZE);
  29.   mline=malloc(LINESIZE);
  30. #else
  31.   swend=(swnext=swq)+SWTABSZ-SWSIZ;
  32.   stagelast=stage+STAGELIMIT;
  33. #endif
  34.   swactive=         /* not in switch                         */
  35.   stagenext=        /* direct output mode                    */
  36.   iflevel=          /* #if... nesting level =0               */
  37.   skiplevel=        /* #if... not encountered                */
  38.   macptr=           /* clear the macro pool                  */
  39.   csp =             /* stack ptr (relative)                  */
  40.   errcnt=           /* number of errors flagged              */
  41.   errflag=0;        /* not skipping errors till ";"          */
  42.   eof=              /* not eof yet                           */
  43.   ncmp=             /* not in compound statement             */
  44.   dmode=            /* not in DATASEG                        */
  45.   files=
  46.   filearg=
  47.   nxtlab=
  48.   quote[1]=0;
  49.   ccode=1;          /* enable preprocessing                  */
  50.   wqptr=wq;         /* clear while queue                     */
  51.   quote[0]='"';     /* fake a quote literal                  */
  52.   input=input2=EOF;
  53.   ask();            /* get user options                      */
  54.   sout("\n", stderr); /* blank line to separate options from listing */
  55.   kill(); /* reset input buffer prior to first read */
  56.   preprocess();     /* fetch first line                      */
  57. #ifdef DYNAMIC
  58. #ifdef HASH
  59.   symtab=malloc(NUMLOCS*SYMAVG + NUMGLBS*SYMMAX);
  60. #else
  61.   symtab=malloc(NUMLOCS*SYMAVG);
  62.   /* global space is allocated with each new entry           */
  63. #endif
  64. #endif
  65. #ifdef HASH
  66.   cptr=STARTGLB-1;
  67.   while(++cptr < ENDGLB) *cptr=0;
  68. #endif
  69.   glbptr=STARTGLB;
  70.   glbflag=1;
  71.   header();         /* intro code */
  72.   setops();         /* set values in op arrays */
  73.   parse();          /* process ALL values */
  74.   outside();        /* verify outside any function */
  75.   externs();        /* declare all externals to the assembler */
  76.   trailer();        /* follow-up code */
  77.   if(output != stdout) fclose(output);
  78.   summary();        /* print error summary */
  79.   }
  80.  
  81. /*
  82. ** process all input text
  83. **
  84. ** At this level, only static declarations.
  85. **       defines, includes and function
  86. **       definitions are legal ...
  87. */
  88. parse() {
  89.   while (eof==0) {
  90.     if(amatch("extern", 6))       dodeclare(EXTERNAL);
  91.     else if(amatch("static", 6))  dodeclare(STATIC);
  92.     else if(dodeclare(PUBLIC))    ;
  93.     else if(match("#asm"))        doasm();
  94.     else if(match("#include"))    doinclude();
  95.     else if(match("#define"))     addmac();
  96.     else                          newfunc(PUBLIC);
  97.     blanks();      /* force eof if pending                   */
  98.     }
  99.   }
  100.  
  101. /*
  102. ** dump the literal pool
  103. */
  104. dumplits(size) int size;  {
  105.   int j, k;
  106.   k=0;
  107.   while (k<litptr)  {
  108.     defstorage(size);
  109.     j=10;
  110.     while(j--) {
  111.       outdec(getint(litq+k, size));
  112.       k=k+size;
  113.       if ((j==0) | (k>=litptr))  {
  114.         nl();
  115.         break;
  116.         }
  117.       outbyte(',');
  118.       }
  119.     }
  120.   }
  121. /*
  122. ** dump zeroes for default initial values
  123. */
  124. dumpzero(size, count) int size, count; {
  125.   int j;
  126.   while (count > 0) {
  127.     defstorage(size);
  128.     count = genzeros(count); /* generate literal zeros */
  129.     }
  130.   }
  131. /*
  132. ** verify compile ends outside any function
  133. */
  134. outside()  {
  135.   if (ncmp) error("no closing bracket");
  136.   }
  137.  
  138. /*
  139. ** get run options
  140. */
  141. ask() {
  142.   int defin, defout, deflist, defi, defm, defa, defp;
  143.   int dftin, dftout, dftlist;
  144.   char inname[81], outname[81], listname[81];
  145. #ifdef CMD_LINE
  146.   int argnum, truth;
  147.   char *ptr;
  148. #endif
  149.   defin = defout = deflist = defi = defm = defa = defp = 0;
  150.   dftin = dftout = dftlist = 1;
  151.   ctext = monitor = alarm = pause = 1;
  152.   input = stdin;
  153.   output = stdout;
  154.   listfp=0;
  155.   strcpy(inname, "con.C");
  156.   strcpy(outname, "con.ASM");
  157.   strcpy(listname, "NUL.LST");
  158. #ifdef CMD_LINE
  159.   argnum = 1;
  160.   while(argnum < argcs) {
  161.     ptr = argvs[argnum++]; /* cast arg as char * */
  162.     if(*ptr == ';') { /* if defaults to be taken */
  163.       defin = defout = deflist = defi = defm = defa = defp = 1;
  164.       break;
  165.       }
  166.     else if(*ptr != '-') { /* if file name */
  167.       if(!defin) {
  168.         if(*ptr != ',') {
  169.           joinname(inname, ptr);
  170.           dupename(outname, inname);
  171.           dftin = 0;
  172.           dftout = 0;
  173.           }
  174.         defin = 1;
  175.         }
  176.       else if(!defout) {
  177.         if(*ptr != ',') {
  178.           joinname(outname, ptr);
  179.           dftout = 0;
  180.           }
  181.         defout = 1;
  182.         }
  183.       else if(!deflist) {
  184.         if(*ptr != ',') {
  185.           joinname(listname, ptr);
  186.           dftlist = 0;
  187.           }
  188.         deflist = 1;
  189.         }
  190.       else {
  191.         fprintf(stderr, "ERROR:  Extraneous parameter %s\n", ptr);
  192.         errcnt++;
  193.         }
  194.       }
  195.     else { /* must be option */
  196.       ptr++; /* skip "-" */
  197.       truth = 1;
  198.       if(upper(*ptr) == 'N') {
  199.         truth = 0;
  200.         ptr++;
  201.         }
  202.       switch(upper(*ptr)) {
  203.         case 'I': { /* interleave C source */
  204.           ctext = truth;
  205.           defi = 1;
  206.           break;
  207.           }
  208.         case 'M': { /* monitor function headers */
  209.           monitor = truth;
  210.           defm = 1;
  211.           break;
  212.           }
  213.         case 'A': { /* sound alarm on errors */
  214.           alarm = truth;
  215.           defa = 1;
  216.           break;
  217.           }
  218.         case 'P': { /* pause on errors */
  219.           pause = truth;
  220.           defp = 1;
  221.           break;
  222.           }
  223.         default:
  224.           fprintf(stderr, "ERROR:  Extraneous option -%c\n", *ptr);
  225.           errcnt++;
  226.         }
  227.       }
  228.     }
  229. #endif
  230.   line=mline; /* use macro buffer for kbd buffer */
  231.   if(!defin) {
  232.     fprintf(stdout, "Input filename [%s]: ", inname);
  233.     if(prompt("", line, LINESIZE)) {
  234.       joinname(inname, line);
  235.       dupename(outname, inname);
  236.       dftin = 0;
  237.       }
  238.     }
  239.   if(!defout) {
  240.     fprintf(stdout, "Output filename [%s]: ", outname);
  241.     if(prompt("", line, LINESIZE)) {
  242.       joinname(outname, line);
  243.       dftout = 0;
  244.       }
  245.     }
  246.   if(!deflist) {
  247.     fprintf(stdout, "Listing filename [%s]: ", listname);
  248.     if(prompt("", line, LINESIZE)) {
  249.       joinname(listname, line);
  250.       dftlist = 0;
  251.       }
  252.     }
  253.   while(!defi) {
  254.     prompt("Interleave C source? ", line, LINESIZE);
  255.     if(upper(*line)=='Y') ctext=YES;
  256.     else if(upper(*line)!='N') continue;
  257.     defi = 1;
  258.     }
  259.   if((!defm) && dftout) { /* don't monitor if output to con */
  260.     monitor = 0;
  261.     defm = 1;
  262.     }
  263.   while(!defm) {
  264.     prompt("Monitor function headers? ", line, LINESIZE);
  265.     if(upper(*line)=='Y') monitor=YES;
  266.     else if(upper(*line)!='N') continue;
  267.     defm = 1;
  268.     }
  269.   while(!defa) {
  270.     prompt("Sound alarm on errors? ", line, LINESIZE);
  271.     if(upper(*line)=='Y') alarm=YES;
  272.     else if(upper(*line)!='N') continue;
  273.     defa = 1;
  274.     }
  275.   while(!defp) {
  276.     prompt("Pause on errors? ", line, LINESIZE);
  277.     if(upper(*line)=='Y') pause=YES;
  278.     else if(upper(*line)!='N') continue;
  279.     defp = 1;
  280.     }
  281.   if(!dftin) {
  282.     input=fopen(inname,"r");
  283.     if(!input) {
  284.       fprintf(stderr, "ERROR: Cannot open %s for input\n", inname);
  285.       exit(errno);
  286.       }
  287.     }
  288.   if(!dftout) {
  289.     output=fopen(outname,"w");
  290.     if(!output) {
  291.       fprintf(stderr, "ERROR: Cannot open %s for output\n", outname);
  292.       exit(errno);
  293.       }
  294.     }
  295.   if(!dftlist) {
  296.     listfp=fopen(listname,"w");
  297.     if(!listfp) {
  298.       fprintf(stderr, "ERROR: Cannot open %s for listing\n", listname);
  299.       exit(errno);
  300.       }
  301.     }
  302.   }
  303.  
  304. /*
  305. ** combine file names overlaying source on default target
  306. */
  307. joinname(target, source) char target[], source[]; {
  308.   int srcdrive, srcpath, srcname, srcext;
  309.   int tgtdrive, tgtpath, tgtname, tgtext;
  310.   int templen;
  311.   char *savetgt, tempstr[81], *ptr;
  312.   savetgt = target;
  313.   ptr = tempstr;
  314.   templen = 0;
  315.   parsename(source, &srcdrive, &srcpath, &srcname, &srcext);
  316.   parsename(target, &tgtdrive, &tgtpath, &tgtname, &tgtext);
  317.   if(srcdrive) {
  318.     templen += srcdrive;
  319.     if(templen > 80) {fputs("ERROR:  File name too long", stderr); exit(100);}
  320.     strncpy(ptr, source, srcdrive);
  321.     ptr += srcdrive;
  322.     }
  323.   else {
  324.     templen += tgtdrive;
  325.     if(templen > 80) {fputs("ERROR:  File name too long", stderr); exit(100);}
  326.     strncpy(ptr, target, tgtdrive);
  327.     ptr += tgtdrive;
  328.     }
  329.   source += srcdrive;
  330.   target += tgtdrive;
  331.   if(srcpath) {
  332.     templen += srcpath;
  333.     if(templen > 80) {fputs("ERROR:  File name too long", stderr); exit(100);}
  334.     strncpy(ptr, source, srcpath);
  335.     ptr += srcpath;
  336.     }
  337.   else {
  338.     templen += tgtpath;
  339.     if(templen > 80) {fputs("ERROR:  File name too long", stderr); exit(100);}
  340.     strncpy(ptr, target, tgtpath);
  341.     ptr += tgtpath;
  342.     }
  343.   source += srcpath;
  344.   target += tgtpath;
  345.   if(srcname) {
  346.     templen += srcname;
  347.     if(templen > 80) {fputs("ERROR:  File name too long", stderr); exit(100);}
  348.     strncpy(ptr, source, srcname);
  349.     ptr += srcname;
  350.     }
  351.   else {
  352.     templen += tgtname;
  353.     if(templen > 80) {fputs("ERROR:  File name too long", stderr); exit(100);}
  354.     strncpy(ptr, target, tgtname);
  355.     ptr += tgtname;
  356.     }
  357.   source += srcname;
  358.   target += tgtname;
  359.   if(srcext) {
  360.     templen += srcext;
  361.     if(templen > 80) {fputs("ERROR:  File name too long", stderr); exit(100);}
  362.     strncpy(ptr, source, srcext);
  363.     ptr += srcext;
  364.     }
  365.   else {
  366.     templen += tgtext;
  367.     if(templen > 80) {fputs("ERROR:  File name too long", stderr); exit(100);}
  368.     strncpy(ptr, target, tgtext);
  369.     ptr += tgtext;
  370.     }
  371.   ptr[0] = 0; /* assure null termination */
  372.   strcpy(savetgt, tempstr);
  373.   }
  374.  
  375. /*
  376. ** copy just file name, not path or extension, to target
  377. */
  378. dupename(target, source) char target[], source[]; {
  379.   int srcdrive, srcpath, srcname, srcext;
  380.   int tgtdrive, tgtpath, tgtname, tgtext;
  381.   int templen;
  382.   char *savetgt, tempstr[81], *ptr;
  383.   savetgt = target;
  384.   ptr = tempstr;
  385.   parsename(source, &srcdrive, &srcpath, &srcname, &srcext);
  386.   parsename(target, &tgtdrive, &tgtpath, &tgtname, &tgtext);
  387.   if(srcname) {
  388.     templen = tgtdrive + tgtpath + srcname + tgtext;
  389.     if(templen > 80) {fputs("ERROR:  File name too long", stderr); exit(100);}
  390.     strncpy(ptr, target, tgtdrive + tgtpath);
  391.     ptr += tgtdrive + tgtpath;
  392.     source += srcdrive + srcpath;
  393.     strncpy(ptr, source, srcname);
  394.     ptr += srcname;
  395.     target += tgtdrive + tgtpath + tgtname;
  396.     strncpy(ptr, target, tgtext);
  397.     ptr += tgtext;
  398.     ptr[0] = 0;
  399.     strcpy(savetgt, tempstr);
  400.     }
  401.   }
  402.  
  403. /*
  404. ** parse file name into [d:] [path\] [name] [.ext]
  405. ** return length of each part
  406. */
  407. parsename(string, drivelen, pathlen, namelen, extlen)
  408.     char *string;  int *drivelen, *pathlen, *namelen, *extlen; {
  409.   char *temp;
  410.   *drivelen = *pathlen = *namelen = *extlen = 0;
  411.   if(alpha(string[0]) && (string[1] == ':')) *drivelen = 2;
  412.   string += *drivelen;
  413.   temp = rindex(string, '\\');
  414.   if(temp) *pathlen = temp - string + 1;
  415.   string += *pathlen;
  416.   temp = index(string, '.');
  417.   if(temp) *namelen = temp - string;
  418.   else *namelen = strlen(string);
  419.   string += *namelen;
  420.   if(string[0] == '.') *extlen = strlen(string);
  421.   }
  422.  
  423. prompt(msg, ans, anslen) char *msg, *ans; int anslen; {
  424.   char *ptr;
  425.   sout(msg, stdout);
  426.   fgets(ans, anslen, stdin);
  427.   if (*ans=='\n') return 0;
  428.   if(ptr = index(ans, '\n')) *ptr = 0; /* zap trailing end-of-line */
  429.   return 1; /* result is true unless line is null */
  430.   }
  431.  
  432. /*
  433. ** print an error summary
  434. */
  435. summary() {
  436.   sout("\n", stdout);
  437.   if(alarm) sout("\7", stdout);
  438.   sout("There were ", stdout);
  439.   errdec(errcnt);
  440.   lout(" errors in this compilation", stdout);
  441.   }
  442.  
  443. setops() {
  444.   op2[0] =       op[0] =  or;          /* heir5  */
  445.   op2[1] =       op[1] = xor;          /* heir6  */
  446.   op2[2] =       op[2] = and;          /* heir7  */
  447.   op2[3] =       op[3] =  eq;          /* heir8  */
  448.   op2[4] =       op[4] =  ne;
  449.   op2[5] =ule;   op[5] =  le;          /* heir9  */
  450.   op2[6] =uge;   op[6] =  ge;
  451.   op2[7] =ult;   op[7] =  lt;
  452.   op2[8] =ugt;   op[8] =  gt;
  453.   op2[9] =       op[9] = asr;          /* heir10 */
  454.   op2[10]=       op[10]= asl;
  455.   op2[11]=       op[11]= add;          /* heir11 */
  456.   op2[12]=       op[12]= sub;
  457.   op2[13]=       op[13]=mult;          /* heir12 */
  458.   op2[14]=       op[14]= div;
  459.   op2[15]=       op[15]= mod;
  460.   }
  461.  
  462.  
  463.