1: /* 2: * Main program that controls the translation of Icon programs. 3: */ 4: 5: #include "itran.h" 6: #include "sym.h" 7: #include "tree.h" 8: #include "token.h" 9: 10: #define MAXFILES 64 /* maximum number of file names */ 11: #define MAXNAME 40 /* maximum length of file name */ 12: 13: int fatalerrs = 0; /* total number of fatal errors */ 14: int warnings = 0; /* total number of warnings */ 15: int nocode = 0; /* non-zero to suppress code generation */ 16: int inline = 1; /* current input line number */ 17: int incol = 0; /* current input column number */ 18: int peekc = 0; /* one-character look ahead */ 19: int implicit = LOCAL; /* implicit scope for undeclared identifiers */ 20: int silence = 0; /* don't be silent (default) */ 21: int trace = 0; /* initial setting of &trace */ 22: 23: FILE *infile; /* current input file */ 24: FILE *codefile; /* current ucode output file */ 25: FILE *globfile; /* current global table output file */ 26: char inbuf[BUFSIZ]; /* buffers for above files */ 27: char codebuf[BUFSIZ]; /* to avoid automatic */ 28: char globbuf[BUFSIZ]; /* allocation by i/o system */ 29: char codename[MAXNAME]; /* name of ucode output file */ 30: char globname[MAXNAME]; /* name of global table output file */ 31: 32: char *filelist[MAXFILES]; /* list of input file names */ 33: char **filep; /* pointer to current input file name */ 34: 35: main(argc,argv) 36: int argc; 37: char **argv; 38: { 39: int aval; 40: int mflag = 0; /* m4 preprocessed */ 41: char *progname; 42: static char mname[80]; /* m4 command string */ 43: register char **fp; /* indexes filelist while scanning args */ 44: char *maknam(); 45: extern FILE *popen(); 46: 47: progname = argv[0]; 48: filep = fp = filelist; 49: while (--argc) { 50: if (**++argv == '-') { /* argument starts with a '-' */ 51: switch ((*argv)[1]) { 52: case '\0': /* read standard input */ 53: *fp++ = *argv; 54: continue; 55: case 'm': /* process with m4 */ 56: mflag++; 57: continue; 58: case 'u': /* tell ilink to note undeclared identifiers*/ 59: implicit = 0; 60: continue; 61: case 't': /* tell ilink to turn on tracing */ 62: trace++; 63: continue; 64: case 's': /* don't produce informative messages */ 65: silence++; 66: continue; 67: case 'D': /* debug flag for ilink, ignored by itran */ 68: continue; 69: case 'S': 70: if ((*argv)[3] == 'h') { /* change hash table size */ 71: aval = atoi(&(*argv)[4]); 72: if (aval <= 0) 73: goto badarg; 74: switch ((*argv)[2]) { 75: case 'i': ihsize = aval; continue; 76: case 'g': ghsize = aval; continue; 77: case 'c': chsize = aval; continue; 78: case 'l': lhsize = aval; continue; 79: case 'f': continue; 80: } 81: } 82: else { /* change symbol table size */ 83: aval = atoi(&(*argv)[3]); 84: if (aval <= 0) 85: goto badarg; 86: switch ((*argv)[2]) { 87: case 'c': csize = aval; continue; 88: case 'i': isize = aval; continue; 89: case 'g': gsize = aval; continue; 90: case 'l': lsize = aval; continue; 91: case 's': ssize = aval; continue; 92: case 't': tsize = aval; continue; 93: case 'f': continue; 94: case 'r': continue; 95: case 'L': continue; 96: case 'C': continue; 97: } 98: } 99: default: 100: badarg: 101: fprintf(stderr, "bad argument: %s\n", *argv); 102: continue; 103: } 104: } 105: else /* argument doesn't start with a '-', assume it's a file */ 106: *fp++ = *argv; 107: } 108: *fp++ = 0; /* terminate list of files with a NULL */ 109: /* 110: * Process each input file in turn. If m4 processing is to be done (mflag 111: * is set), a pipe is opened to m4 with the current file name, otherwise, 112: * the input file is opened. infile is the file pointer for the current 113: * input file and filep is the name of the file. 114: */ 115: for ( ; *filep; filep++) { 116: inline = 1; 117: if (!mflag) { 118: if (*filep[0] == '-') 119: infile = stdin; 120: else 121: infile = fopen(*filep, "r"); 122: } 123: else { 124: strcpy(mname, "m4 "); 125: strcat(mname, *filep); 126: infile = popen(mname, "r"); 127: } 128: if (*filep[0] == '-') 129: *filep = "stdin"; 130: if (infile == NULL) { 131: fprintf(stderr, "%s: cannot open %s\n", progname, *filep); 132: fatalerrs++; 133: continue; 134: } 135: setbuf(infile, inbuf); 136: 137: if (!silence) 138: fprintf(stderr, "%s:\n", *filep); 139: 140: /* 141: * Form names for the .u1 and .u2 files and open them. 142: */ 143: maknam(codename, *filep, ".u1"); 144: maknam(globname, *filep, ".u2"); 145: codefile = fopen(codename, "w"); 146: if (codefile == NULL) { 147: fprintf(stderr, "%s: cannot create %s\n", progname, codename); 148: fatalerrs++; 149: continue; 150: } 151: setbuf(codefile, codebuf); 152: globfile = fopen(globname, "w"); 153: if (globfile == NULL) { 154: fprintf(stderr, "%s: cannot create %s\n", progname, globname); 155: fatalerrs++; 156: continue; 157: } 158: setbuf(globfile, globbuf); 159: 160: meminit(); /* Initialize data structures */ 161: 162: yyparse(); /* Parse the input */ 163: 164: /* 165: * Close the input file and the .u1 and .u2 files. 166: */ 167: if (!mflag) 168: fclose(infile); 169: else { 170: if (pclose(infile) != 0) { 171: fprintf(stderr, "%s: m4 terminated abnormally\n", progname); 172: fatalerrs++; 173: } 174: } 175: fclose(codefile); 176: fclose(globfile); 177: } 178: 179: /* 180: * Produce information about errors and warnings and be correct about it. 181: */ 182: if (fatalerrs == 1) 183: fprintf(stderr, "1 error; "); 184: else if (fatalerrs > 1) 185: fprintf(stderr, "%d errors; ", fatalerrs); 186: else if (!silence) 187: fprintf(stderr, "No errors; "); 188: if (warnings == 1) 189: fprintf(stderr, "1 warning\n"); 190: else if (warnings > 1) 191: fprintf(stderr, "%d warnings\n", warnings); 192: else if (!silence) 193: fprintf(stderr, "no warnings\n"); 194: else if (fatalerrs > 0) 195: fprintf(stderr, "\n"); 196: if (fatalerrs > 0) 197: exit(1); 198: exit(0); 199: } 200: 201: /* 202: * maknam - makes a file name from prefix and suffix. 203: * 204: * Uses only the last file specification if name is a path, 205: * replaces suffix of name with suffix argument. 206: */ 207: 208: char *maknam(dest, name, suffix) 209: char *dest, *name, *suffix; 210: { 211: register char *d, *pre, *suf; 212: char *mark; 213: 214: d = dest; 215: pre = name; 216: suf = suffix; 217: mark = pre; 218: while (*pre) /* find last slash */ 219: if (*pre++ == '/') 220: mark = pre; 221: pre = mark; 222: mark = 0; 223: while (*d = *pre++) /* copy from last slash into dest */ 224: if (*d++ == '.') /* look for last dot, too */ 225: mark = d - 1; 226: if (mark) /* if no dot, just append suffix */ 227: d = mark; 228: while (*d++ = *suf++) ; /* copy suffix into dest */ 229: return (dest); 230: }