home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_progs / prog_c / zc.lzh / ZC / ZCSRC.LZH / src / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-06-12  |  9.8 KB  |  547 lines

  1. /* Copyright (c) 1988 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.  *   Revised: Dec 1988    Joe Montgomery
  17.  *
  18.  *   Revised main.c to use Amiga File System Naming Conventions
  19.  *    Added ?,C,F switches. ? help
  20.  *                  C force data,bss into Chip memory
  21.  *                  F force data,bss into Fast memory
  22.  *    To be added -o switch to specify assembly output
  23.  *
  24.  *     other modules:
  25.  *   Revised out.c to use MOTOROLA assembly directives in order
  26.  *    to be compatible with C.Gibbs a68k assembler & blink
  27.  *    Added END statement
  28.  *    Changed .comm label,size to label DC.x 0
  29.  *   Revised d2.c so that externs are declared as XREF -----
  30.  *   Revised g2.c & gen.c to declare all called functions XREF
  31.  *     (will need to change this to declare only external functions)
  32.  *
  33.  *
  34.  *   All changes labeled JMM
  35.  */
  36.  
  37. /*
  38.  * Amiga version changes by Jeff Lydiatt labled "Jal".
  39.  */
  40.  
  41. #include <stdio.h>
  42. #include "param.h"
  43. #include "nodes.h"
  44. #include "tok.h"
  45.  
  46. extern short usechipmemory,usefastmemory;
  47. int lineno;
  48. int nmerrors;
  49. int oflags[26];
  50. int xflags[26];
  51. int pflag = 0;            /* enable profiling */
  52. static int anydebug;
  53. #define debug oflags['z'-'a']
  54.  
  55.  
  56. FILE *input;
  57. FILE *output;
  58. #if CC68
  59. FILE *fopenb();
  60. #define fopen fopenb
  61. #endif
  62. char *inname;
  63.  
  64. #if NEEDBUF
  65. char my_ibuf[BUFSIZ];
  66. #endif
  67.  
  68. NODEP cur;
  69.  
  70. /* JMM changed defines to be compatible with AMIGA */
  71. static    char *defines[] = {
  72.     "MC68000",
  73.     "mc68000",
  74.     "SOZOBON",
  75.     "MCH_AMIGA",
  76.     "AmigaDOS",
  77.     NULL
  78. };
  79.  
  80. static    char    Version[] =
  81. "zc: Amiga Version 1.01  Copyright (c) 1988 by Sozobon, Limited.\n";
  82.  
  83. static char Version2[] =    /*Jal*/
  84. "    Port by Jeff Lydiatt, J.Montgomery - 13Jun89.\n";
  85.  
  86. extern char *outfilename,*errorfile;
  87.  
  88.  
  89. main(argc, argv)
  90. char **argv;
  91. {
  92.     char    *p, *getenv();
  93.     int shownames;
  94.     int i;
  95.  
  96. /* JMM added switches to force data,bss into chip or fast memory */
  97.     usefastmemory = 0;
  98.     usechipmemory = 0;  /* don't force data into either chip or fast*/
  99.     outfilename = (char *) NULL;
  100.  
  101. /* JMM force hcc to always print out version */
  102.     printf(Version);
  103.     if (sizeof(NODE) & 3) {
  104.         printf("sizeof NODE not mult of 4\n");
  105.         exit(1);
  106.     }
  107.  
  108.     /*
  109.      * Define the "built-in" macros
  110.      */
  111.     for (i=0; defines[i] != NULL; i++)
  112.         optdef(defines[i]);
  113.  
  114.     /*
  115.      * Parse the INCLUDE environment variable, if present.
  116.      */
  117.     if ((p = getenv("INCLUDE")) != NULL){
  118.         if( doincl(p) == 1 )exit(0);
  119.     }
  120.     shownames = 0;
  121.     if (isatty(0)) {
  122.         write(1, "\33v", 2);
  123.         setbuf(stdout, NULL);
  124.     }
  125. /* put author here */
  126.     while (argc-- > 1) {
  127.         argv++;
  128.         if(argv[0][0] == '?') {
  129.             doopt(&argv[0][0]);
  130.             exit(1);
  131.         }
  132.         if(argv[0][0] == '-')
  133.               doopt(&argv[0][1]);
  134. #if CC68
  135.         else if (argv[0][0] == '+') {
  136.             upstr(&argv[0][1]);
  137.             doopt(&argv[0][1]);
  138.         }
  139. #endif
  140.         else {
  141.             if (argc > 1 || shownames) {
  142.                 shownames++;
  143.                 printf("%s:\n", argv[0]);
  144.             }
  145.             if (input != NULL)
  146.                 fclose(input);
  147.             input = fopen(argv[0], ROPEN);
  148.             if (input == NULL) {
  149.                 printf("Cant open %s\n", argv[0]);
  150.                 exit(1);
  151.             }
  152. #if NEEDBUF
  153.             setbuf(input, my_ibuf);
  154. #endif
  155.             inname = argv[0];
  156.             dofile();
  157.         }
  158.     }
  159.     if (input == NULL) {
  160.         input = stdin;
  161.         output = stdout;
  162.         inname = "<STDIN>";
  163.         dofile();
  164.     }
  165.     exit(0);
  166. }
  167.  
  168. doincl(s)
  169. char    *s;
  170. {
  171.     char    *malloc(), *strcpy();
  172.     char    buf[256];
  173.     char    dir[128];
  174.     register char    *p;
  175.  
  176.  
  177.     strcpy(buf, s);
  178.     /*
  179.      * Convert ',' and ';' to nulls
  180.      */
  181.     for (p=buf; *p != '\0' ;p++)
  182.         if (*p == ',' || *p == ';')
  183.             *p = '\0';
  184.     p[1] = '\0';                    /* double null terminated */
  185.  
  186.     /*
  187.      * Grab each directory, make sure it ends with a slash,
  188.      * and add it to the directory list.
  189.      */
  190.     for (p=buf; *p != '\0' ;p++) {
  191.         strcpy(dir, p);
  192.       /* JMM use Amiga file naming conventions */
  193.         if (dir[strlen(dir)-1] != '/' && dir[strlen(dir)-1] != ':')
  194.             strcat(dir, "/");
  195.  
  196.         optincl( strcpy(malloc((unsigned) (strlen(dir) + 1)), dir) );
  197.  
  198.         while (*p != '\0')
  199.             p++;
  200.     }
  201. }
  202.  
  203.  
  204. extern int nodesmade, nodesavail;
  205. extern NODEP deflist[], symtab[], tagtab;
  206. extern NODEP strsave;
  207. extern int level;
  208. dofile()
  209. {
  210.     char *scopy();
  211.     int i;
  212.  
  213.     out_start(inname);
  214.     inname = scopy(inname);
  215.     lineno = 1;
  216.     nmerrors = 0;
  217.     advnode();
  218.  
  219.     level = 0;
  220.     program();
  221.     dumpstrs(strsave);
  222.     for (i=0; i<NHASH; i++){
  223.         if (symtab[i] != NULL)
  224.             do_public(symtab[i]);
  225.     }
  226.     putlibcalls();
  227.  
  228.     out_end();
  229.     if (cur && cur->e_token == EOFTOK)
  230.         freenode(cur);
  231.     sfree(inname);
  232.     for (i=0; i<NHASH; i++) {
  233.         if (debug>1 && deflist[i]) {
  234.             printf("defines[%d]", i);
  235.             printlist(deflist[i]);
  236.         }
  237.         freenode(deflist[i]);
  238.         deflist[i] = NULL;
  239.         if (debug && symtab[i]) {
  240.             printf("gsyms[%d]", i);
  241.             printlist(symtab[i]);
  242.         }
  243.         freenode(symtab[i]);
  244.         symtab[i] = NULL;
  245.     }
  246.     if (debug) {
  247.         printf("structs");
  248.         printlist(tagtab);
  249.     }
  250.     freenode(tagtab);
  251.     tagtab = NULL;
  252.     freenode(strsave);
  253.     strsave = NULL;
  254.     if (nmerrors) {
  255.         printf("%d errors\n", nmerrors);
  256.         exit(1);
  257.     }
  258.     if (nodesmade != nodesavail) {
  259.         printf("lost %d nodes!!!\n", nodesmade-nodesavail);
  260.         exit(1);
  261.     }
  262. /*
  263.     printf("Space = %ldK\n", ((long)nodesavail*sizeof(NODE))/1024);
  264. */
  265. }
  266.  
  267. dooutfile(s)
  268. char    *s;
  269. {
  270.      char    *malloc(), *strcpy();
  271.  
  272.      outfilename = strcpy(malloc((unsigned)(strlen(s) + 1)), s );
  273. }
  274.  
  275. doerrorfile(s)
  276. char *s;
  277. {
  278.      char  *malloc(),*strcpy();
  279.  
  280.      errorfile = strcpy(malloc((unsigned)(strlen(s) + 1)), s);
  281. }
  282.  
  283. doopt(s)
  284. char *s;
  285. {
  286.     register char c;
  287.  
  288.     while ((c = *s++)) {
  289. #ifdef    DEBUG
  290.         if (c >= 'a' && c <='z') {
  291.             oflags[c-'a']++;
  292.             anydebug++;
  293.         } else
  294. #endif
  295.         if ( (c >= 'A' && c <= 'Z') || c == '?') {
  296.             switch (c) {
  297.             case 'D':
  298.                 optdef(s);
  299.                 return;
  300.             case 'U':
  301.                 optundef(s);
  302.                 return;
  303.             case 'I':
  304.                 doincl(s);
  305.                 return;
  306.             case 'P':
  307.                 pflag = 1;
  308.                 continue;
  309.             case 'V':
  310.                 printf("%s",Version2); /*Jal*/
  311.                 continue;
  312. /* JMM added ?,C,F,O,E    switches */
  313.             case 'E': /* specify error file */
  314.                 doerrorfile(s);
  315.                 return(1);
  316.             case 'O':
  317.                 dooutfile(s);
  318.                 return(1);
  319.             case 'C':
  320.                 if(usefastmemory){
  321.                    printf(" Can't use both Chip & Fast memory\n");
  322.                    return(1);
  323.                 }
  324.                 usechipmemory = 1;
  325.                 continue;
  326.              case 'F':
  327.                 if(usechipmemory){
  328.                    printf(" Can't use both Chip & Fast memory\n");
  329.                    return(1);
  330.                 }
  331.                 usefastmemory = 1;
  332.                 continue;
  333.             case '?':
  334.                 printf("%s",Version2); /*Jal*/
  335.                 printf("    The Correct Syntax is \n");
  336.                 printf("zc [FLAGS] SOURCEFILE \n");
  337.                 printf("    The valid compiler flags are : \n");
  338.                 printf("\n  -Dxxxx   Define xxxx\n  -Uxxxx   Undefine xxxx\n");
  339.                 printf("  -Ixxxx   Include Directory = xxxx\n  -P   profiler\n");
  340.                 printf("  -Oxxxx   outputfile name = xxxx\n");
  341.                 printf("  -V   display compiler version\n  -?   Help\n");
  342.                 printf("  -C   force Data,Bss into Chip memory \n");
  343.                 printf("  -F   force Data,Bss into Fast memory \n");
  344.                 return(1);
  345.                 continue;
  346.             }
  347. #ifdef    DEBUG
  348.             xflags[c-'A']++;
  349.             anydebug++;
  350. #endif
  351.         }
  352.     }
  353. return(0);
  354. }
  355.  
  356. errors(s,t)
  357. char *s, *t;
  358. {
  359.     optnl();
  360.     printf("error in %s on line %d: %s %s\n", inname, lineno, s,t);
  361.     nmerrors++;
  362. }
  363.  
  364. errorn(s,np)
  365. char *s;
  366. NODE *np;
  367. {
  368.     optnl();
  369.     printf("error in %s on line %d: %s ", inname, lineno, s);
  370.     put_nnm(np);
  371.     putchar('\n');
  372.     nmerrors++;
  373. }
  374.  
  375. error(s)
  376. char *s;
  377. {
  378.     optnl();
  379.     printf("error in %s on line %d: %s\n", inname, lineno, s);
  380.     nmerrors++;
  381. }
  382.  
  383. warns(s,t)
  384. char *s, *t;
  385. {
  386.     optnl();
  387.     printf("warning in %s on line %d: %s %s\n", inname, lineno, s,t);
  388. }
  389.  
  390. warnn(s,np)
  391. char *s;
  392. NODE *np;
  393. {
  394.     optnl();
  395.     printf("warning in %s on line %d: %s ", inname, lineno, s);
  396.     put_nnm(np);
  397.     putchar('\n');
  398. }
  399.  
  400. warn(s)
  401. char *s;
  402. {
  403.     optnl();
  404.     printf("warning in %s on line %d: %s\n", inname, lineno, s);
  405. }
  406.  
  407. fatals(s,t)
  408. char *s, *t;
  409. {
  410.     optnl();
  411.     printf("fatal error in %s on line %d: %s %s\n", inname, lineno, s,t);
  412.     exit(1);
  413. }
  414.  
  415. fataln(s,np)
  416. char *s;
  417. NODE *np;
  418. {
  419.     optnl();
  420.     printf("fatal error in %s on line %d: %s ", inname, lineno, s);
  421.     put_nnm(np);
  422.     putchar('\n');
  423.     exit(1);
  424. }
  425.  
  426. fatal(s)
  427. char *s;
  428. {
  429.     optnl();
  430.     printf("fatal error in %s on line %d: %s\n", inname, lineno, s);
  431.     exit(1);
  432. }
  433.  
  434. static
  435. optnl()
  436. {
  437.     if (anydebug)
  438.         putchar('\n');
  439. }
  440.  
  441. struct kwtbl {
  442.     char *name;
  443.     int    kwval;
  444.     int    kflags;
  445. } kwtab[] = {
  446.     /* must be sorted */
  447.     {"asm", K_ASM},
  448.     {"auto", K_AUTO},
  449.     {"break", K_BREAK},
  450.     {"case", K_CASE},
  451.     {"char", K_CHAR},
  452.     {"continue", K_CONTINUE},
  453.     {"default", K_DEFAULT},
  454.     {"do", K_DO},
  455.     {"double", K_DOUBLE},
  456.     {"else", K_ELSE},
  457.     {"enum", K_ENUM},
  458.     {"extern", K_EXTERN},
  459.     {"float", K_FLOAT},
  460.     {"for", K_FOR},
  461.     {"goto", K_GOTO},
  462.     {"if", K_IF},
  463.     {"int", K_INT},
  464.     {"long", K_LONG},
  465.     {"register", K_REGISTER},
  466.     {"return", K_RETURN},
  467.     {"short", K_SHORT},
  468.     {"sizeof", K_SIZEOF},
  469.     {"static", K_STATIC},
  470.     {"struct", K_STRUCT},
  471.     {"switch", K_SWITCH},
  472.     {"typedef", K_TYPEDEF},
  473.     {"union", K_UNION},
  474.     {"unsigned", K_UNSIGNED},
  475.     {"void", K_VOID},
  476.     {"while", K_WHILE},
  477.  
  478.     {0,0}
  479. };
  480.  
  481. #define FIRST_C 'a'
  482. #define LAST_C    'z'
  483. struct kwtbl *kwstart[LAST_C-FIRST_C+1];
  484.  
  485. kw_init()
  486. {
  487.     register struct kwtbl *p;
  488.     register c;
  489.  
  490.     for (p=kwtab; p->name; p++) {
  491.         c = p->name[0];
  492.         if (kwstart[c-FIRST_C] == 0)
  493.             kwstart[c-FIRST_C] = p;
  494.     }
  495. }
  496.  
  497. kw_tok(tp)
  498. NODE *tp;
  499. {
  500.     register struct kwtbl *kp;
  501.     register char *nm;
  502.     register i;
  503.     static first = 0;
  504.  
  505.     nm = tp->n_name;
  506.     if (first == 0) {
  507.         kw_init();
  508.         first = 1;
  509.     }
  510.     i = nm[0];
  511.     if (i < FIRST_C || i > LAST_C)
  512.         return;
  513.     kp = kwstart[i-FIRST_C];
  514.     if (kp)
  515.     for (; kp->name; kp++) {
  516.         i = strcmp(nm, kp->name);
  517.         if (i == 0) {
  518.             tp->e_token = kp->kwval;
  519.             tp->e_flags = kp->kflags;
  520.             return;
  521.         } else if (i < 0)
  522.             return;
  523.     }
  524. }
  525.  
  526. #if CC68
  527. /* fix args since stupid lib makes all lower case */
  528. upstr(s)
  529. char *s;
  530. {
  531.     while (*s) {
  532.         if (*s >= 'a' && *s <= 'z')
  533.             *s += 'A'-'a';
  534.         s++;
  535.     }
  536. }
  537. downstr(s)
  538. char *s;
  539. {
  540.     while (*s) {
  541.         if (*s >= 'A' && *s <= 'Z')
  542.             *s -= 'A'-'a';
  543.         s++;
  544.     }
  545. }
  546. #endif
  547.