home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V6 / usr / source / s1 / cc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1975-05-17  |  12.6 KB  |  812 lines

  1. #define    SBSIZE    2000
  2. char    sbf[SBSIZE];
  3. /* C command */
  4.  
  5. char *tmp0;
  6. char *tmp1;
  7. char *tmp2;
  8. char *tmp3;
  9. char *tmp4;
  10. char *tmp5;
  11. char ts[1000];
  12. char *tsp ts;
  13. char *av[50];
  14. char *clist[50];
  15. char *llist[50];
  16. int instring;
  17. int pflag;
  18. int sflag;
  19. int cflag;
  20. int oflag;
  21. int proflag;
  22. int depth;
  23. int *ibuf;
  24. int *ibuf1;
  25. int *ibuf2;
  26. int *obuf;
  27. char *lp;
  28. char *line;
  29. int lineno;
  30. int exfail;
  31. struct symtab {
  32.     char name[8];
  33.     char *value;
  34. } *symtab;
  35. int symsiz 200;
  36. struct symtab *defloc;
  37. struct symtab *incloc;
  38. struct symtab *eifloc;
  39. struct symtab *ifdloc;
  40. struct symtab *ifnloc;
  41. struct symtab *unxloc;
  42. int    trulvl;
  43. int    flslvl;
  44. char *stringbuf;
  45. char *pass0 "/lib/c0";
  46. char *pass1 "/lib/c1";
  47. char *pass2 "/lib/c2";
  48. char *pref "/lib/crt0.o";
  49.  
  50. main(argc, argv)
  51. char *argv[]; {
  52.     char *t;
  53.     int nc, nl, i, j, c, f20, nxo;
  54.     int dexit();
  55.  
  56.     i = nc = nl = f20 = nxo = 0;
  57.     while(++i < argc) {
  58.         if(*argv[i] == '-')
  59.             switch (argv[i][1]) {
  60.                 default:
  61.                     goto passa;
  62.                 case 'S':
  63.                     sflag++;
  64.                     cflag++;
  65.                     break;
  66.                 case 'O':
  67.                     oflag++;
  68.                     break;
  69.                 case 'p':
  70.                     proflag++;
  71.                     pref = "/lib/mcrt0.o";
  72.                     break;
  73.                 case 'P':
  74.                     pflag++;
  75.                 case 'c':
  76.                     cflag++;
  77.                     break;
  78.  
  79.                 case 'f':
  80.                     pref = "/lib/fcrt0.o";
  81.                     pass0 = "/lib/fc0";
  82.                     pass1 = "/lib/fc1";
  83.                     break;
  84.  
  85.                 case '2':
  86.                     if(argv[i][2] == '\0')
  87.                         pref = "/lib/crt2.o";
  88.                     else {
  89.                         pref = "/lib/crt20.o";
  90.                         f20 = 1;
  91.                     }
  92.                     break;
  93.                 case 't':
  94.                     if (argv[i][2]=='0')
  95.                         pass0 = "/usr/c/c0";
  96.                     if (argv[i][2]=='1')
  97.                         pass1 = "/usr/c/c1";
  98.                     if (argv[i][2]=='2')
  99.                         pass2 = "/usr/c/c2";
  100.                     break;
  101.             }
  102.         else {
  103.         passa:
  104.             t = argv[i];
  105.             if(getsuf(t)=='c') {
  106.                 clist[nc++] = t;
  107.                 t = setsuf(t, 'o');
  108.             }
  109.             if (nodup(llist, t)) {
  110.                 llist[nl++] = t;
  111.                 if (getsuf(t)=='o')
  112.                     nxo++;
  113.             }
  114.         }
  115.     }
  116.     if(nc==0)
  117.         goto nocom;
  118.     if (pflag==0) {
  119.         tmp0 = copy("/tmp/ctm0a");
  120.         while((c=open(tmp0, 0))>=0) {
  121.             close(c);
  122.             tmp0[9]++;
  123.         }
  124.         while((creat(tmp0, 0400))<0)
  125.             tmp0[9]++;
  126.     }
  127.     if ((signal(2, 1) & 01) == 0)
  128.         signal(2, &dexit);
  129.     (tmp1 = copy(tmp0))[8] = '1';
  130.     (tmp2 = copy(tmp0))[8] = '2';
  131.     (tmp3 = copy(tmp0))[8] = '3';
  132.     if (oflag)
  133.         (tmp5 = copy(tmp0))[8] = '5';
  134.     if (pflag==0)
  135.         (tmp4 = copy(tmp0))[8] = '4';
  136.     for (i=0; i<nc; i++) {
  137.         if (nc>1)
  138.             printf("%s:\n", clist[i]);
  139.         av[0] = "c0";
  140.         if (pflag)
  141.             tmp4 = setsuf(clist[i], 'i');
  142.         av[1] = expand(clist[i]);
  143.         if (pflag || exfail)
  144.             continue;
  145.         if (av[1] == 0) {
  146.             cflag++;
  147.             continue;
  148.         }
  149.         av[2] = tmp1;
  150.         av[3] = tmp2;
  151.         if (proflag) {
  152.             av[4] = "-P";
  153.             av[5] = 0;
  154.         } else
  155.             av[4] = 0;
  156.         if (callsys(pass0, av)) {
  157.             cflag++;
  158.             continue;
  159.         }
  160.         av[0] = "c1";
  161.         av[1] = tmp1;
  162.         av[2] = tmp2;
  163.         if (sflag)
  164.             tmp3 = setsuf(clist[i], 's');
  165.         av[3] = tmp3;
  166.         if (oflag)
  167.             av[3] = tmp5;
  168.         av[4] = 0;
  169.         if(callsys(pass1, av)) {
  170.             cflag++;
  171.             continue;
  172.         }
  173.         if (oflag) {
  174.             av[0] = "c2";
  175.             av[1] = tmp5;
  176.             av[2] = tmp3;
  177.             av[3] = 0;
  178.             callsys(pass2, av);
  179.             unlink(tmp5);
  180.         }
  181.         if (sflag)
  182.             continue;
  183.         av[0] = "as";
  184.         av[1] = "-";
  185.         av[2] = tmp3;
  186.         av[3] = 0;
  187.         cunlink(tmp1);
  188.         cunlink(tmp2);
  189.         cunlink(tmp4);
  190.         callsys("/bin/as", av);
  191.         t = setsuf(clist[i], 'o');
  192.         cunlink(t);
  193.         if(link("a.out", t) || cunlink("a.out")) {
  194.             printf("move failed: %s\n", t);
  195.             cflag++;
  196.         }
  197.     }
  198. nocom:
  199.     if (cflag==0 && nl!=0) {
  200.         i = 0;
  201.         av[0] = "ld";
  202.         av[1] = "-X";
  203.         av[2] = pref;
  204.         j = 3;
  205.         while(i<nl)
  206.             av[j++] = llist[i++];
  207.         if(f20)
  208.             av[j++] = "-l2";
  209.         else {
  210.             av[j++] = "-lc";
  211.             av[j++] = "-l";
  212.         }
  213.         av[j++] = 0;
  214.         callsys("/bin/ld", av);
  215.         if (nc==1 && nxo==1)
  216.             cunlink(setsuf(clist[0], 'o'));
  217.     }
  218.     dexit();
  219. }
  220.  
  221. dexit()
  222. {
  223.     if (!pflag) {
  224.         cunlink(tmp1);
  225.         cunlink(tmp2);
  226.         if (sflag==0)
  227.             cunlink(tmp3);
  228.         cunlink(tmp4);
  229.         cunlink(tmp5);
  230.         cunlink(tmp0);
  231.     }
  232.     exit();
  233. }
  234.  
  235. expand(file)
  236. char *file;
  237. {
  238.     int ib1[259], ib2[259], ob[259];
  239.     struct symtab stab[200];
  240.     char ln[196];
  241.     register int c;
  242.     register char *rlp;
  243.  
  244.     exfail = 0;
  245.     ibuf = ibuf1 = ib1;
  246.     ibuf2 = ib2;
  247.     if (fopen(file, ibuf1)<0)
  248.         return(file);
  249.     if (getc(ibuf1) != '#') {
  250.         close(ibuf1[0]);
  251.         return(file);
  252.     }
  253.     ibuf1[1]++;
  254.     ibuf1[2]--;
  255.     obuf = ob;
  256.     symtab = stab;
  257.     for (c=0; c<200; c++) {
  258.         stab[c].name[0] = '\0';
  259.         stab[c].value = 0;
  260.     }
  261.     insym(&defloc, "define");
  262.     insym(&incloc, "include");
  263.     insym(&eifloc, "endif");
  264.     insym(&ifdloc, "ifdef");
  265.     insym(&ifnloc, "ifndef");
  266.     insym(&unxloc, "unix");
  267.     stringbuf = sbf;
  268.     trulvl = 0;
  269.     flslvl = 0;
  270.     line  = ln;
  271.     lineno = 0;
  272.     if (fcreat(tmp4, obuf) < 0) {
  273.         printf("Can't creat %s\n", tmp4);
  274.         dexit();
  275.     }
  276.     while(getline()) {
  277.         if (ibuf==ibuf2 && pflag==0)
  278.             putc(001, obuf);    /*SOH: insert */
  279.         if (ln[0] != '#' && flslvl==0)
  280.             for (rlp = line; c = *rlp++;)
  281.                 putc(c, obuf);
  282.         putc('\n', obuf);
  283.     }
  284.     for(rlp=line; c = *rlp++;)
  285.             putc(c,obuf);
  286.     fflush(obuf);
  287.     close(obuf[0]);
  288.     close(ibuf1[0]);
  289.     return(tmp4);
  290. }
  291.  
  292. getline()
  293. {
  294.     register int c, sc, state;
  295.     struct symtab *np;
  296.     char *namep, *filname;
  297.  
  298.     if (ibuf==ibuf1)
  299.         lineno++;
  300.     lp = line;
  301.     *lp = '\0';
  302.     state = 0;
  303.     if ((c=getch()) == '#')
  304.         state = 1;
  305.     while (c!='\n' && c!='\0') {
  306.         if ('a'<=c && c<='z' || 'A'<=c && c<='Z' || c=='_') {
  307.             namep = lp;
  308.             sch(c);
  309.             while ('a'<=(c=getch()) && c<='z'
  310.                   ||'A'<=c && c<='Z'
  311.                   ||'0'<=c && c<='9' 
  312.                   ||c=='_')
  313.                 sch(c);
  314.             sch('\0');
  315.             lp--;
  316.             if (state>3) {
  317.                 if (flslvl==0 &&(state+!lookup(namep,-1)->name[0])==5)
  318.                     trulvl++;
  319.                 else
  320.                     flslvl++;
  321.         out:
  322.                 while (c!='\n' && c!= '\0')
  323.                     c = getch();
  324.                 return(c);
  325.             }
  326.             if (state!=2 || flslvl==0)
  327.                 {
  328.                 ungetc(c);
  329.                 np = lookup(namep, state);
  330.                 c = getch();
  331.                 }
  332.             if (state==1) {
  333.                 if (np==defloc)
  334.                     state = 2;
  335.                 else if (np==incloc)
  336.                     state = 3;
  337.                 else if (np==ifnloc)
  338.                     state = 4;
  339.                 else if (np==ifdloc)
  340.                     state = 5;
  341.                 else if (np==eifloc) {
  342.                     if (flslvl)
  343.                         --flslvl;
  344.                     else if (trulvl)
  345.                         --trulvl;
  346.                     else error("If-less endif");
  347.                     goto out;
  348.                 }
  349.                 else {
  350.                     error("Undefined control");
  351.                     while (c!='\n' && c!='\0')
  352.                         c = getch();
  353.                     return(c);
  354.                 }
  355.             } else if (state==2) {
  356.                 if (flslvl)
  357.                     goto out;
  358.                 np->value = stringbuf;
  359.                 savch(c);
  360.                 while ((c=getch())!='\n' && c!='\0')
  361.                     savch(c);
  362.                 savch('\0');
  363.                 return(1);
  364.             }
  365.             continue;
  366.         } else if ((sc=c)=='\'' || sc=='"') {
  367.             sch(sc);
  368.             filname = lp;
  369.             instring++;
  370.             while ((c=getch())!=sc && c!='\n' && c!='\0') {
  371.                 sch(c);
  372.                 if (c=='\\')
  373.                     sch(getch());
  374.             }
  375.             instring = 0;
  376.             if (flslvl)
  377.                 goto out;
  378.             if (state==3) {
  379.                 if (flslvl)
  380.                     goto out;
  381.                 *lp = '\0';
  382.                 while ((c=getch())!='\n' && c!='\0');
  383.                 if (ibuf==ibuf2)
  384.                     error("Nested 'include'");
  385.                 if (fopen(filname, ibuf2)<0)
  386.                     error("Missing file %s", filname);
  387.                 else
  388.                     ibuf = ibuf2;
  389.                 return(c);
  390.             }
  391.         }
  392.         sch(c);
  393.         c = getch();
  394.     }
  395.     sch('\0');
  396.     if (state>1)
  397.         error("Control syntax");
  398.     return(c);
  399. }
  400.  
  401. insym(sp, namep)
  402. struct symtab **sp;
  403. char *namep;
  404. {
  405.     register struct symtab *np;
  406.  
  407.     *sp = np = lookup(namep, 1);
  408.     np->value = np->name;
  409. }
  410.  
  411. error(s, x)
  412. {
  413.     printf("%d: ", lineno);
  414.     printf(s, x);
  415.     putchar('\n');
  416.     exfail++;
  417.     cflag++;
  418. }
  419.  
  420. sch(c)
  421. {
  422.     register char *rlp;
  423.  
  424.     rlp = lp;
  425.     if (rlp==line+194)
  426.         error("Line overflow");
  427.     *rlp++ = c;
  428.     if (rlp>line+195)
  429.         rlp = line+195;
  430.     lp = rlp;
  431. }
  432.  
  433. savch(c)
  434. {
  435.     *stringbuf++ = c;
  436.     if (stringbuf-sbf < SBSIZE)
  437.         return;
  438.     error("Too much defining");
  439.     dexit();
  440. }
  441.  
  442. getch()
  443. {
  444.     register int c;
  445.  
  446. loop:
  447.     if ((c=getc1())=='/' && !instring) {
  448.         if ((c=getc1())!='*')
  449.             {
  450.             ungetc(c);
  451.             return('/');
  452.             }
  453.         for(;;) {
  454.             c = getc1();
  455.         cloop:
  456.             switch (c) {
  457.  
  458.             case '\0':
  459.                 return('\0');
  460.  
  461.             case '*':
  462.                 if ((c=getc1())=='/')
  463.                     goto loop;
  464.                 goto cloop;
  465.  
  466.             case '\n':
  467.                 if (ibuf==ibuf1) {
  468.                     putc('\n', obuf);
  469.                     lineno++;
  470.                 }
  471.                 continue;
  472.             }
  473.         }
  474.     }
  475.     return(c);
  476. }
  477. char pushbuff[300];
  478. char *pushp pushbuff;
  479. ungetc(c)
  480.     {
  481.     *++pushp = c;
  482.     }
  483.  
  484. getc1()
  485. {
  486.     register c;
  487.  
  488.     if (*pushp !=0)
  489.         return(*pushp--);
  490.     depth=0;
  491.     if ((c = getc(ibuf)) < 0 && ibuf==ibuf2) {
  492.         close(ibuf2[0]);
  493.         ibuf = ibuf1;
  494.         putc('\n', obuf);
  495.         lineno++;
  496.         c = getc1();
  497.     }
  498.     if (c<0)
  499.         return(0);
  500.     return(c);
  501. }
  502.  
  503. lookup(namep, enterf)
  504. char *namep;
  505. {
  506.     register char *np, *snp;
  507.     register struct symtab *sp;
  508.     int i, c, around;
  509.     np = namep;
  510.     around = i = 0;
  511.     while (c = *np++)
  512.         i =+ c;
  513.     i =% symsiz;
  514.     sp = &symtab[i];
  515.     while (sp->name[0]) {
  516.         snp = sp;
  517.         np = namep;
  518.         while (*snp++ == *np)
  519.             if (*np++ == '\0' || np==namep+8) {
  520.                 if (!enterf)
  521.                     subst(namep, sp);
  522.                 return(sp);
  523.             }
  524.         if (++sp >= &symtab[symsiz])
  525.             if (around++)
  526.                 {
  527.                 error("too many defines");
  528.                 dexit();
  529.                 }
  530.             else
  531.             sp = symtab;
  532.     }
  533.     if (enterf>0) {
  534.         snp = namep;
  535.         for (np = &sp->name[0]; np < &sp->name[8];)
  536.             if (*np++ = *snp)
  537.                 snp++;
  538.     }
  539.     return(sp);
  540. }
  541. char revbuff[200];
  542. char    *bp;
  543. backsch(c)
  544.     {
  545.     if (bp-revbuff > 200)
  546.         error("Excessive define looping", bp--);
  547.     *bp++ = c;
  548.     }
  549.  
  550. subst(np, sp)
  551. char *np;
  552. struct symtab *sp;
  553. {
  554.     register char *vp;
  555.  
  556.     lp = np;
  557.     bp = revbuff;
  558.     if (depth++>100)
  559.         {
  560.         error("define recursion loop\n");
  561.         return;
  562.         }
  563.     if ((vp = sp->value) == 0)
  564.         return;
  565.     /* arrange that define unix unix still
  566.     has no effect, avoiding rescanning */
  567.     if (streq(sp->name,sp->value))
  568.         {
  569.         while (*vp)
  570.             sch(*vp++);
  571.         return;
  572.         }
  573.     backsch(' ');
  574.     if (*vp == '(')
  575.         expdef(vp);
  576.     else
  577.     while (*vp)
  578.         backsch(*vp++);
  579.     backsch(' ');
  580.     while (bp>revbuff)
  581.         ungetc(*--bp);
  582. }
  583.  
  584. getsuf(as)
  585. char as[];
  586. {
  587.     register int c;
  588.     register char *s;
  589.     register int t;
  590.  
  591.     s = as;
  592.     c = 0;
  593.     while(t = *s++)
  594.         if (t=='/')
  595.             c = 0;
  596.         else
  597.             c++;
  598.     s =- 3;
  599.     if (c<=14 && c>2 && *s++=='.')
  600.         return(*s);
  601.     return(0);
  602. }
  603.  
  604. setsuf(as, ch)
  605. char as[];
  606. {
  607.     register char *s, *s1;
  608.  
  609.     s = s1 = copy(as);
  610.     while(*s)
  611.         if (*s++ == '/')
  612.             s1 = s;
  613.     s[-1] = ch;
  614.     return(s1);
  615. }
  616.  
  617. callsys(f, v)
  618. char f[], *v[]; {
  619.     int t, status;
  620.  
  621.     if ((t=fork())==0) {
  622.         execv(f, v);
  623.         printf("Can't find %s\n", f);
  624.         exit(1);
  625.     } else
  626.         if (t == -1) {
  627.             printf("Try again\n");
  628.             return(1);
  629.         }
  630.     while(t!=wait(&status));
  631.     if ((t=(status&0377)) != 0 && t!=14) {
  632.         if (t!=2)        /* interrupt */
  633.             printf("Fatal error in %s\n", f);
  634.         dexit();
  635.     }
  636.     return((status>>8) & 0377);
  637. }
  638.  
  639. copy(as)
  640. char as[];
  641. {
  642.     register char *otsp, *s;
  643.  
  644.     otsp = tsp;
  645.     s = as;
  646.     while(*tsp++ = *s++);
  647.     return(otsp);
  648. }
  649.  
  650. nodup(l, os)
  651. char **l, *os;
  652. {
  653.     register char *t, *s;
  654.     register int c;
  655.  
  656.     s = os;
  657.     if (getsuf(s) != 'o')
  658.         return(1);
  659.     while(t = *l++) {
  660.         while(c = *s++)
  661.             if (c != *t++)
  662.                 break;
  663.         if (*t=='\0' && c=='\0')
  664.             return(0);
  665.         s = os;
  666.     }
  667.     return(1);
  668. }
  669.  
  670. cunlink(f)
  671. char *f;
  672. {
  673.     if (f==0)
  674.         return(0);
  675.     return(unlink(f));
  676. }
  677. expdef(proto)
  678.   char *proto;
  679. {
  680. char buffer[100], *parg[20], *pval[20], name[20], *cspace, *wp;
  681. char protcop[100], *pr;
  682. int narg, k, i, c;
  683. pr = protcop;
  684. while (*pr++ = *proto++);
  685. proto= protcop;
  686. for (narg=0; (parg[narg] = token(&proto)) != 0; narg++)
  687.     ;
  688. /* now scan input */
  689. cspace = buffer;
  690. while ((c=getch()) == ' ');
  691. if (c != '(')
  692.     {
  693.     error("defined function requires arguments");
  694.     return;
  695.     }
  696. ungetc(c);
  697. for(k=0; pval[k] = coptok(&cspace); k++);
  698. if (k!=narg)
  699.  {
  700.   error("define argument mismatch");
  701.   return;
  702.  }
  703. while (c= *proto++)
  704.    {
  705.    if (!letter(c))
  706.       backsch(c);
  707.    else
  708.       {
  709.       wp = name;
  710.       *wp++ = c;
  711.       while (letnum(*proto))
  712.         *wp++ = *proto++;
  713.       *wp = 0;
  714.       for (k=0; k<narg; k++)
  715.       if(streq(name,parg[k]))
  716.         break;
  717.       wp = k <narg ? pval[k] : name;
  718.       while (*wp) backsch(*wp++);
  719.       }
  720.    }
  721. }
  722. token(cpp) char **cpp;
  723. {
  724. char *val;
  725. int stc;
  726. stc = **cpp;
  727. *(*cpp)++ = '\0';
  728. if (stc==')') return(0);
  729. while (**cpp == ' ') (*cpp)++;
  730. for (val = *cpp; (stc= **cpp) != ',' && stc!= ')'; (*cpp)++)
  731.   {
  732.   if (!letnum(stc) || (val == *cpp && !letter(stc)))
  733.     {
  734.     error("define prototype argument error");
  735.     break;
  736.     }
  737.   }
  738. return(val);
  739. }
  740. coptok (cpp) char **cpp; {
  741. char *val;
  742. int stc, stop,paren;
  743. paren = 0;
  744. val = *cpp;
  745. if (getch() == ')')
  746.   return(0);
  747. while (((stc = getch()) != ',' && stc != ')') || paren > 0)
  748.   {
  749.   if (stc == '"' || stc == '\'')
  750.     {
  751.     stop = stc;
  752.     if (stop == '\'')
  753.       *(*cpp)++ = '\'';
  754.     while ( (stc = getch()) != stop)
  755.       {
  756.       if (stc == '\n')
  757.         {
  758.         error ("non-terminated string");
  759.         break;
  760.         }
  761.       if (stc == '\\')
  762.         if ((stc= getch()) != stop && stc != '\\')
  763.           *(*cpp)++ = '\\';
  764.       *(*cpp)++ = stc;
  765.       }
  766.     if (stop == '\'') 
  767.       *(*cpp)++ = '\'';
  768.     }
  769.   else if (stc == '\\')
  770.       {
  771.       stc = getch();
  772.       if (stc != '"' && stc != '\\')
  773.         *(*cpp)++ = '\\';
  774.       *(*cpp)++ = stc;
  775.       }
  776.   else
  777.     {
  778.     *(*cpp)++ = stc;
  779.     if (stc == '(')
  780.         paren++;
  781.     if (stc == ')')
  782.         paren--;
  783.     }
  784.   }
  785. *(*cpp)++ = 0;
  786. ungetc(stc);
  787. return(val);
  788. }
  789. letter(c)
  790. {
  791. if ((c >= 'a' && c <= 'z') ||
  792.     (c >= 'A' && c <= 'Z') ||
  793.     (c == '_'))
  794.     return (1);
  795. else
  796.     return(0);
  797. }
  798. letnum(c)
  799. {
  800. if (letter(c) || (c >= '0' && c <= '9'))
  801.   return(1);
  802. else
  803.   return(0);
  804. }
  805. streq(s,t) char *s, *t;
  806. {
  807. int c;
  808. while ( (c= *s++) == *t++)
  809.    if (c==0) return(1);
  810. return(0);
  811. }
  812.