|
|
1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.