home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / sozobon / scsrc20 / hcc / main.c < prev    next >
C/C++ Source or Header  |  1991-02-22  |  9KB  |  535 lines

  1. /* Copyright (c) 1988,1989,1991 by Sozobon, Limited.  Author: Johann Ruegg
  2.  *
  3.  * Permission is granted to anyone to use this software for any purpose
  4.  * on any computer system, and to redistribute it freely, with the
  5.  * following restrictions:
  6.  * 1) No charge may be made other than reasonable charges for reproduction.
  7.  * 2) Modified versions must be clearly marked as such.
  8.  * 3) The authors are not responsible for any harmful consequences
  9.  *    of using this software, even if they result from defects in it.
  10.  *
  11.  *    main.c
  12.  *
  13.  *    Main routine, error handling, keyword lookup.
  14.  */
  15.  
  16. #include <stdio.h>
  17. #include "param.h"
  18. #include "nodes.h"
  19. #include "tok.h"
  20.  
  21. int lineno;
  22. int nmerrors;
  23. int oflags[26];
  24. int xflags[26];
  25. int pflag = 0;            /* enable profiling */
  26. static int anydebug;
  27. #define debug oflags['z'-'a']
  28.  
  29. FILE *input;
  30. FILE *output;
  31. #if CC68
  32. FILE *fopenb();
  33. #define fopen fopenb
  34. #endif
  35. char *inname;
  36.  
  37. #if NEEDBUF
  38. char my_ibuf[BUFSIZ];
  39. #endif
  40.  
  41. #ifdef MINIX
  42. #define strchr    index
  43. #endif
  44.  
  45. NODEP cur;
  46.  
  47. #define MAXPREDEF    20
  48.  
  49. struct def {
  50.     char *dname, *dval;
  51. } defines[MAXPREDEF] = {
  52.     {"MC68000"},
  53.     {"mc68000"},
  54.     {"SOZOBON"},
  55. #ifdef FOR_AMIGA
  56.     {"AMIGA"},
  57.     {"AMIGADOS"},
  58. #else
  59.     {"ATARI_ST"},
  60. #ifdef MINIX
  61.     {"MINIX"},
  62. #else
  63.     {"TOS"},
  64. #endif
  65. #endif
  66. };
  67. static int npred = 5;
  68.  
  69. char    tmpdir[128] = ".";        /* where the output goes */
  70.  
  71. main(argc, argv)
  72. char **argv;
  73. {
  74.     char    *p, *getenv();
  75.     int shownames;
  76.     int i;
  77.  
  78.     if (sizeof(NODE) & 3) {
  79.         printf("sizeof NODE not mult of 4\n");
  80.         exit(1);
  81.     }
  82.  
  83.     /*
  84.      * Parse the INCLUDE environment variable, if present.
  85.      */
  86.     if ((p = getenv("INCLUDE")) != NULL)
  87.         doincl(p);
  88.  
  89.     shownames = 0;
  90. #ifndef FOR_AMIGA
  91.     if (isatty(0)) {
  92. #ifdef    TOS
  93.         write(1, "\33v", 2);
  94. #endif
  95.         setbuf(stdout, NULL);
  96.     }
  97. #endif
  98. /* put author here */
  99.     while (argc-- > 1) {
  100.         argv++;
  101.         if (argv[0][0] == '-')
  102.             doopt(&argv[0][1]);
  103. #if CC68
  104.         else if (argv[0][0] == '+') {
  105.             upstr(&argv[0][1]);
  106.             doopt(&argv[0][1]);
  107.         }
  108. #endif
  109.         else {
  110.             if (argc > 1 || shownames) {
  111.                 shownames++;
  112.                 printf("%s:\n", argv[0]);
  113.             }
  114.             if (input != NULL)
  115.                 fclose(input);
  116.             input = fopen(argv[0], ROPEN);
  117.             if (input == NULL) {
  118.                 printf("Cant open %s\n", argv[0]);
  119.                 exit(1);
  120.             }
  121. #if NEEDBUF
  122.             setbuf(input, my_ibuf);
  123. #endif
  124.             inname = argv[0];
  125.             dofile();
  126.         }
  127.     }
  128.     if (input == NULL) {
  129.         input = stdin;
  130.         output = stdout;
  131.         inname = "<STDIN>";
  132.         dofile();
  133.     }
  134.     exit(0);
  135. }
  136.  
  137. adddef(s)
  138. char *s;
  139. {
  140.     char *as, *strchr();
  141.  
  142.     if (npred >= MAXPREDEF) {
  143.         warn("too many -D 's");
  144.         return;
  145.     }
  146.     if ((as = strchr(s,'=')) != NULL)
  147.         *as++ = 0;
  148.     else
  149.         as = NULL;
  150.     defines[npred].dname = s;
  151.     defines[npred].dval = as;
  152.     npred++;
  153. }
  154.  
  155. subdef(s)
  156. char *s;
  157. {
  158.     int i;
  159.  
  160.     for (i=0; i<npred; i++)
  161.         if (strcmp(s, defines[i].dname) == 0)
  162.             goto found;
  163.     return;
  164. found:
  165.     while (i < npred) {
  166.         defines[i] = defines[i+1];
  167.         i++;
  168.     }
  169.     npred--;
  170. }
  171.  
  172. dodefs()
  173. {
  174.     int i;
  175.     struct def *p;
  176.  
  177.     /*
  178.      * Define the "built-in" macros
  179.      */
  180.     p = defines;
  181.     for (i=0; i < npred; i++,p++)
  182.         optdef(p->dname, p->dval ? p->dval : "1");
  183. }
  184.  
  185. doincl(s)
  186. char    *s;
  187. {
  188.     char    *malloc(), *strcpy();
  189.     char    buf[256];
  190.     char    dir[128];
  191.     register char    *p;
  192.     char c;
  193.  
  194.     strcpy(buf, s);
  195.  
  196.     /*
  197.      * Convert ',' and ';' to nulls
  198.      */
  199.     for (p=buf; *p != '\0' ;p++)
  200.         if (*p == ',' || *p == ';')
  201.             *p = '\0';
  202.     p[1] = '\0';            /* double null terminated */
  203.  
  204.     /*
  205.      * Grab each directory, make sure it ends with a slash
  206.      * and add it to the directory list.
  207.      */
  208.     for (p=buf; *p != '\0' ;p++) {
  209.         strcpy(dir, p);
  210.         c = dir[strlen(dir)-1];
  211. #ifndef FOR_AMIGA
  212. #if MINIX || UNIX
  213.         if (c != '/')
  214.             strcat(dir, "/");
  215. #else
  216.         if (c != '\\')
  217.             strcat(dir, "\\");
  218. #endif
  219. #else
  220.         if (c != '/' && c != ':')
  221.             strcat(dir, "/");
  222. #endif
  223.  
  224.         optincl( strcpy(malloc((unsigned) (strlen(dir) + 1)), dir) );
  225.  
  226.         while (*p != '\0')
  227.             p++;
  228.     }
  229. }
  230.  
  231. dofile()
  232. {
  233.     extern int nodesmade, nodesavail;
  234.     char *scopy();
  235.     extern NODEP deflist[], symtab[], tagtab;
  236.     extern NODEP strsave;
  237.     extern int level;
  238.     int i;
  239.  
  240.     out_start(inname);
  241.     inname = scopy(inname);
  242.     lineno = 1;
  243.     nmerrors = 0;
  244.     dodefs();
  245.     advnode();
  246.  
  247.     level = 0;
  248.     program();
  249.     dumpstrs(strsave);
  250. #ifdef OUT_AZ
  251.     xrefs();
  252. #endif
  253.  
  254.     out_end();
  255.     if (cur && cur->e_token == EOFTOK)
  256.         freenode(cur);
  257.     sfree(inname);
  258.     for (i=0; i<NHASH; i++) {
  259.         if (debug>1 && deflist[i]) {
  260.             printf("defines[%d]", i);
  261.             printlist(deflist[i]);
  262.         }
  263.         freenode(deflist[i]);
  264.         deflist[i] = NULL;
  265.         if (debug && symtab[i]) {
  266.             printf("gsyms[%d]", i);
  267.             printlist(symtab[i]);
  268.         }
  269.         freenode(symtab[i]);
  270.         symtab[i] = NULL;
  271.     }
  272.     if (debug) {
  273.         printf("structs");
  274.         printlist(tagtab);
  275.     }
  276.     freenode(tagtab);
  277.     tagtab = NULL;
  278.     freenode(strsave);
  279.     strsave = NULL;
  280.     if (nmerrors) {
  281.         printf("%d errors\n", nmerrors);
  282.         exit(1);
  283.     }
  284.     if (nodesmade != nodesavail) {
  285.         printf("lost %d nodes!!!\n", nodesmade-nodesavail);
  286.         exit(1);
  287.     }
  288. /*
  289.     printf("Space = %ldK\n", ((long)nodesavail*sizeof(NODE))/1024);
  290. */
  291. }
  292.  
  293. static    char    Version[] =
  294. "hcc: version 2.0  Copyright (c) 1988,1989,1991 by Sozobon, Limited.";
  295.  
  296. doopt(s)
  297. char *s;
  298. {
  299.     register char c;
  300.  
  301.     while ((c = *s++)) {
  302. #ifdef    DEBUG
  303.         if (c >= 'a' && c <='z') {
  304.             oflags[c-'a']++;
  305.             anydebug++;
  306.         } else
  307. #endif
  308.         if (c >= 'A' && c <= 'Z') {
  309.             switch (c) {
  310.             case 'D':
  311.                 adddef(s);
  312.                 return;
  313.             case 'U':
  314.                 subdef(s);
  315.                 return;
  316.             case 'I':
  317.                 doincl(s);
  318.                 return;
  319.             case 'P':
  320.                 pflag = 1;
  321.                 continue;
  322.             case 'V':
  323.                 printf("%s\n", Version);
  324.                 continue;
  325.             case 'T':
  326.                 strcpy(tmpdir, s);
  327. #if MINIX || UNIX
  328.                 if (tmpdir[strlen(tmpdir)-1] == '/')
  329.                     tmpdir[strlen(tmpdir)-1] = '\0';
  330. #else
  331.                 if (tmpdir[strlen(tmpdir)-1] == '\\')
  332.                     tmpdir[strlen(tmpdir)-1] = '\0';
  333. #endif
  334.                 return;
  335.             }
  336. #ifdef    DEBUG
  337.             xflags[c-'A']++;
  338.             anydebug++;
  339. #endif
  340.         }
  341.     }
  342. }
  343.  
  344. errors(s,t)
  345. char *s, *t;
  346. {
  347.     optnl();
  348.     printf("error in %s on line %d: %s %s\n", inname, lineno, s,t);
  349.     nmerrors++;
  350. }
  351.  
  352. errorn(s,np)
  353. char *s;
  354. NODE *np;
  355. {
  356.     optnl();
  357.     printf("error in %s on line %d: %s ", inname, lineno, s);
  358.     put_nnm(np);
  359.     putchar('\n');
  360.     nmerrors++;
  361. }
  362.  
  363. error(s)
  364. char *s;
  365. {
  366.     optnl();
  367.     printf("error in %s on line %d: %s\n", inname, lineno, s);
  368.     nmerrors++;
  369. }
  370.  
  371. warns(s,t)
  372. char *s, *t;
  373. {
  374.     optnl();
  375.     printf("warning in %s on line %d: %s %s\n", inname, lineno, s,t);
  376. }
  377.  
  378. warnn(s,np)
  379. char *s;
  380. NODE *np;
  381. {
  382.     optnl();
  383.     printf("warning in %s on line %d: %s ", inname, lineno, s);
  384.     put_nnm(np);
  385.     putchar('\n');
  386. }
  387.  
  388. warn(s)
  389. char *s;
  390. {
  391.     optnl();
  392.     printf("warning in %s on line %d: %s\n", inname, lineno, s);
  393. }
  394.  
  395. fatals(s,t)
  396. char *s, *t;
  397. {
  398.     optnl();
  399.     printf("fatal error in %s on line %d: %s %s\n", inname, lineno, s,t);
  400.     exit(1);
  401. }
  402.  
  403. fataln(s,np)
  404. char *s;
  405. NODE *np;
  406. {
  407.     optnl();
  408.     printf("fatal error in %s on line %d: %s ", inname, lineno, s);
  409.     put_nnm(np);
  410.     putchar('\n');
  411.     exit(1);
  412. }
  413.  
  414. fatal(s)
  415. char *s;
  416. {
  417.     optnl();
  418.     printf("fatal error in %s on line %d: %s\n", inname, lineno, s);
  419.     exit(1);
  420. }
  421.  
  422. static
  423. optnl()
  424. {
  425.     if (anydebug)
  426.         putchar('\n');
  427. }
  428.  
  429. struct kwtbl {
  430.     char *name;
  431.     int    kwval;
  432.     int    kflags;
  433. } kwtab[] = {
  434.     /* must be sorted */
  435.     {"asm", K_ASM},
  436.     {"auto", K_AUTO},
  437.     {"break", K_BREAK},
  438.     {"case", K_CASE},
  439.     {"char", K_CHAR},
  440.     {"continue", K_CONTINUE},
  441.     {"default", K_DEFAULT},
  442.     {"do", K_DO},
  443.     {"double", K_DOUBLE},
  444.     {"else", K_ELSE},
  445.     {"enum", K_ENUM},
  446.     {"extern", K_EXTERN},
  447.     {"float", K_FLOAT},
  448.     {"for", K_FOR},
  449.     {"goto", K_GOTO},
  450.     {"if", K_IF},
  451.     {"int", K_INT},
  452.     {"long", K_LONG},
  453.     {"register", K_REGISTER},
  454.     {"return", K_RETURN},
  455.     {"short", K_SHORT},
  456.     {"sizeof", K_SIZEOF},
  457.     {"static", K_STATIC},
  458.     {"struct", K_STRUCT},
  459.     {"switch", K_SWITCH},
  460.     {"typedef", K_TYPEDEF},
  461.     {"union", K_UNION},
  462.     {"unsigned", K_UNSIGNED},
  463.     {"void", K_VOID},
  464.     {"while", K_WHILE},
  465.  
  466.     {0,0}
  467. };
  468.  
  469. #define FIRST_C    'a'
  470. #define LAST_C    'z'
  471. struct kwtbl *kwstart[LAST_C-FIRST_C+1];
  472.  
  473. kw_init()
  474. {
  475.     register struct kwtbl *p;
  476.     register c;
  477.  
  478.     for (p=kwtab; p->name; p++) {
  479.         c = p->name[0];
  480.         if (kwstart[c-FIRST_C] == 0)
  481.             kwstart[c-FIRST_C] = p;
  482.     }
  483. }
  484.  
  485. kw_tok(tp)
  486. NODE *tp;
  487. {
  488.     register struct kwtbl *kp;
  489.     register char *nm;
  490.     register i;
  491.     static first = 0;
  492.  
  493.     nm = tp->n_name;
  494.     if (first == 0) {
  495.         kw_init();
  496.         first = 1;
  497.     }
  498.     i = nm[0];
  499.     if (i < FIRST_C || i > LAST_C)
  500.         return;
  501.     kp = kwstart[i-FIRST_C];
  502.     if (kp)
  503.     for (; kp->name; kp++) {
  504.         i = strcmp(nm, kp->name);
  505.         if (i == 0) {
  506.             tp->e_token = kp->kwval;
  507.             tp->e_flags = kp->kflags;
  508.             return;
  509.         } else if (i < 0)
  510.             return;
  511.     }
  512. }
  513.  
  514. #if CC68
  515. /* fix args since stupid lib makes all lower case */
  516. upstr(s)
  517. char *s;
  518. {
  519.     while (*s) {
  520.         if (*s >= 'a' && *s <= 'z')
  521.             *s += 'A'-'a';
  522.         s++;
  523.     }
  524. }
  525. downstr(s)
  526. char *s;
  527. {
  528.     while (*s) {
  529.         if (*s >= 'A' && *s <= 'Z')
  530.             *s -= 'A'-'a';
  531.         s++;
  532.     }
  533. }
  534. #endif
  535.