1 #include "c.h"
2 
3 static char rcsid[] = "main.c - faked rcsid";
4 
5 static void typestab(Symbol, void *);
6 
7 static void stabline(Coordinate *);
8 static void stabend(Coordinate *, Symbol, Coordinate **, Symbol *, Symbol *);
9 Interface *IR = NULL;
10 
11 int Aflag;		/* >= 0 if -A specified */
12 int Pflag;		/* != 0 if -P specified */
13 int glevel;		/* == [0-9] if -g[0-9] specified */
14 int xref;		/* != 0 for cross-reference data */
15 Symbol YYnull;		/* _YYnull  symbol if -n or -nvalidate specified */
16 Symbol YYcheck;		/* _YYcheck symbol if -nvalidate,check specified */
17 
18 static char *comment;
19 static Interface stabIR;
20 static char *currentfile;       /* current file name */
21 static int currentline;		/* current line number */
22 static FILE *srcfp;		/* stream for current file, if non-NULL */
23 static int srcpos;		/* position of srcfp, if srcfp is non-NULL */
main(int argc,char * argv[])24 int main(int argc, char *argv[]) {
25 	int i, j;
26 	for (i = argc - 1; i > 0; i--)
27 		if (strncmp(argv[i], "-target=", 8) == 0)
28 			break;
29 	if (i > 0) {
30 		char *s = strchr(argv[i], '\\');
31 		if (s != NULL)
32 			*s = '/';
33 		for (j = 0; bindings[j].name && bindings[j].ir; j++)
34 			if (strcmp(&argv[i][8], bindings[j].name) == 0) {
35 				IR = bindings[j].ir;
36 				break;
37 			}
38 		if (s != NULL)
39 			*s = '\\';
40 	}
41 	if (!IR) {
42 		fprint(stderr, "%s: unknown target", argv[0]);
43 		if (i > 0)
44 			fprint(stderr, " `%s'", &argv[i][8]);
45 		fprint(stderr, "; must specify one of\n");
46 		for (i = 0; bindings[i].name; i++)
47 			fprint(stderr, "\t-target=%s\n", bindings[i].name);
48 		exit(EXIT_FAILURE);
49 	}
50 	init(argc, argv);
51 	t = gettok();
52 	(*IR->progbeg)(argc, argv);
53 	if (glevel && IR->stabinit)
54 		(*IR->stabinit)(firstfile, argc, argv);
55 	program();
56 	if (events.end)
57 		apply(events.end, NULL, NULL);
58 	memset(&events, 0, sizeof events);
59 	if (glevel || xref) {
60 		Symbol symroot = NULL;
61 		Coordinate src;
62 		foreach(types,       GLOBAL, typestab, &symroot);
63 		foreach(identifiers, GLOBAL, typestab, &symroot);
64 		src.file = firstfile;
65 		src.x = 0;
66 		src.y = lineno;
67 		if ((glevel > 2 || xref) && IR->stabend)
68 			(*IR->stabend)(&src, symroot,
69 				ltov(&loci,    PERM),
70 				ltov(&symbols, PERM), NULL);
71 		else if (IR->stabend)
72 			(*IR->stabend)(&src, NULL, NULL, NULL, NULL);
73 	}
74 	finalize();
75 	(*IR->progend)();
76 	deallocate(PERM);
77 	return errcnt > 0;
78 }
79 /* main_init - process program arguments */
main_init(int argc,char * argv[])80 void main_init(int argc, char *argv[]) {
81 	char *infile = NULL, *outfile = NULL;
82 	int i;
83 	static int inited;
84 
85 	if (inited)
86 		return;
87 	inited = 1;
88 	type_init(argc, argv);
89 	for (i = 1; i < argc; i++)
90 		if (strcmp(argv[i], "-g") == 0 || strcmp(argv[i], "-g2") == 0)
91 			glevel = 2;
92 		else if (strncmp(argv[i], "-g", 2) == 0) {	/* -gn[,x] */
93 			char *p = strchr(argv[i], ',');
94 			glevel = atoi(argv[i]+2);
95 			if (p) {
96 				comment = p + 1;
97 				if (glevel == 0)
98 					glevel = 1;
99 				if (stabIR.stabline == NULL) {
100 					stabIR.stabline = IR->stabline;
101 					stabIR.stabend = IR->stabend;
102 					IR->stabline = stabline;
103 					IR->stabend = stabend;
104 				}
105 			}
106 		} else if (strcmp(argv[i], "-x") == 0)
107 			xref++;
108 		else if (strcmp(argv[i], "-A") == 0) {
109 			++Aflag;
110 		} else if (strcmp(argv[i], "-P") == 0)
111 			Pflag++;
112 		else if (strcmp(argv[i], "-w") == 0)
113 			wflag++;
114 		else if (strcmp(argv[i], "-n") == 0) {
115 			if (!YYnull) {
116 				YYnull = install(string("_YYnull"), &globals, GLOBAL, PERM);
117 				YYnull->type = func(voidptype, NULL, 1);
118 				YYnull->sclass = EXTERN;
119 				(*IR->defsymbol)(YYnull);
120 			}
121 		} else if (strncmp(argv[i], "-n", 2) == 0) {	/* -nvalid[,check] */
122 			char *p = strchr(argv[i], ',');
123 			if (p) {
124 				YYcheck = install(string(p+1), &globals, GLOBAL, PERM);
125 				YYcheck->type = func(voidptype, NULL, 1);
126 				YYcheck->sclass = EXTERN;
127 				(*IR->defsymbol)(YYcheck);
128 				p = stringn(argv[i]+2, p - (argv[i]+2));
129 			} else
130 				p = string(argv[i]+2);
131 			YYnull = install(p, &globals, GLOBAL, PERM);
132 			YYnull->type = func(voidptype, NULL, 1);
133 			YYnull->sclass = EXTERN;
134 			(*IR->defsymbol)(YYnull);
135 		} else if (strcmp(argv[i], "-v") == 0)
136 			fprint(stderr, "%s %s\n", argv[0], rcsid);
137 		else if (strncmp(argv[i], "-s", 2) == 0)
138 			density = strtod(&argv[i][2], NULL);
139 		else if (strncmp(argv[i], "-errout=", 8) == 0) {
140 			FILE *f = fopen(argv[i]+8, "w");
141 			if (f == NULL) {
142 				fprint(stderr, "%s: can't write errors to `%s'\n", argv[0], argv[i]+8);
143 				exit(EXIT_FAILURE);
144 			}
145 			fclose(f);
146 			f = freopen(argv[i]+8, "w", stderr);
147 			assert(f);
148 		} else if (strncmp(argv[i], "-e", 2) == 0) {
149 			int x;
150 			if ((x = strtol(&argv[i][2], NULL, 0)) > 0)
151 				errlimit = x;
152 		} else if (strncmp(argv[i], "-little_endian=", 15) == 0)
153 			IR->little_endian = argv[i][15] - '0';
154 		else if (strncmp(argv[i], "-mulops_calls=", 18) == 0)
155 			IR->mulops_calls = argv[i][18] - '0';
156 		else if (strncmp(argv[i], "-wants_callb=", 13) == 0)
157 			IR->wants_callb = argv[i][13] - '0';
158 		else if (strncmp(argv[i], "-wants_argb=", 12) == 0)
159 			IR->wants_argb = argv[i][12] - '0';
160 		else if (strncmp(argv[i], "-left_to_right=", 15) == 0)
161 			IR->left_to_right = argv[i][15] - '0';
162 		else if (strncmp(argv[i], "-wants_dag=", 11) == 0)
163 			IR->wants_dag = argv[i][11] - '0';
164 		else if (*argv[i] != '-' || strcmp(argv[i], "-") == 0) {
165 			if (infile == NULL)
166 				infile = argv[i];
167 			else if (outfile == NULL)
168 				outfile = argv[i];
169 		}
170 
171 	if (infile != NULL && strcmp(infile, "-") != 0
172 	&& freopen(infile, "r", stdin) == NULL) {
173 		fprint(stderr, "%s: can't read `%s'\n", argv[0], infile);
174 		exit(EXIT_FAILURE);
175 	}
176 	if (outfile != NULL && strcmp(outfile, "-") != 0
177 	&& freopen(outfile, "w", stdout) == NULL) {
178 		fprint(stderr, "%s: can't write `%s'\n", argv[0], outfile);
179 		exit(EXIT_FAILURE);
180 	}
181 }
182 /* typestab - emit stab entries for p */
typestab(Symbol p,void * cl)183 static void typestab(Symbol p, void *cl) {
184 	if (*(Symbol *)cl == 0 && p->sclass && p->sclass != TYPEDEF)
185 		*(Symbol *)cl = p;
186 	if ((p->sclass == TYPEDEF || p->sclass == 0) && IR->stabtype)
187 		(*IR->stabtype)(p);
188 }
189 
190 /* stabline - emit source code for source coordinate *cp */
stabline(Coordinate * cp)191 static void stabline(Coordinate *cp) {
192 	if (cp->file && cp->file != currentfile) {
193 		if (srcfp)
194 			fclose(srcfp);
195 		currentfile = cp->file;
196 		srcfp = fopen(currentfile, "r");
197 		srcpos = 0;
198 		currentline = 0;
199 	}
200 	if (currentline != cp->y && srcfp) {
201 		char buf[512];
202 		if (srcpos > cp->y) {
203 			rewind(srcfp);
204 			srcpos = 0;
205 		}
206 		for ( ; srcpos < cp->y; srcpos++)
207 			if (fgets(buf, sizeof buf, srcfp) == NULL) {
208 				fclose(srcfp);
209 				srcfp = NULL;
210 				break;
211 			}
212 		if (srcfp && srcpos == cp->y)
213 			print("%s%s", comment, buf);
214 	}
215 	currentline = cp->y;
216 	if (stabIR.stabline)
217 		(*stabIR.stabline)(cp);
218 }
219 
stabend(Coordinate * cp,Symbol p,Coordinate ** cpp,Symbol * sp,Symbol * stab)220 static void stabend(Coordinate *cp, Symbol p, Coordinate **cpp, Symbol *sp, Symbol *stab) {
221 	if (stabIR.stabend)
222 		(*stabIR.stabend)(cp, p, cpp, sp, stab);
223 	if (srcfp)
224 		fclose(srcfp);
225 }
226