1 /* $NetBSD: main.c,v 1.10 2004/02/13 17:56:17 wiz Exp $ */
2
3 /*
4 * TODO:
5 * rewrite the command line stuff altogether - it's kludged beyond
6 * belief (as is the rest of the code...)
7 *
8 * DISCLAIMER DISCLAIMER DISCLAIMER
9 * This code is such a kludge that I don't want to put my name on it.
10 * It was a ridiculously fast hack and needs rewriting.
11 * However it does work...
12 */
13
14 #include <sys/cdefs.h>
15 __KERNEL_RCSID(0, "$NetBSD: main.c,v 1.10 2004/02/13 17:56:17 wiz Exp $");
16
17 #include <stdio.h>
18 #include <strings.h>
19 #include <time.h>
20 #include "malloc.h"
21 #include "debug.h"
22 #include "main.h"
23 #include "procs.h"
24
25 int debug[128];
26
27 int lineno = 1;
28
29 FILE *statefile, *actfile, *eventfile_h, *statevalfile;
30 FILE *infile, *astringfile;
31 char *Transfilename;
32 char *astringfile_name = DEBUGFILE;
33 char *actfile_name = ACTFILE;
34 char *statefile_name = STATEFILE;
35 char *statevalfile_name = STATEVALFILE;
36 char *eventfile_h_name = EVENTFILE_H;
37 int print_trans = 0;
38 int print_protoerrs = 0;
39 int pgoption = 0;
40 char kerneldirname[50] = "\0";
41
42 char protocol[50];
43
44 char *synonyms[] = {
45 "EVENT",
46 "PCB",
47 0
48 };
49
50 void FakeFilename();
51 extern void llparse();
52 extern void initsets();
53 extern void init_alloc();
54 extern void dump_predtable();
55 extern void printprotoerrs();
56
57 void
58 usage(a)
59 char *a;
60 {
61 fprintf(stderr,
62 "usage: %s <transition file> {-D<debug options>} <other options>\n",
63 a);
64 fprintf(stderr, "\t<other options> is any combination of:\n");
65 fprintf(stderr, "\t\t-A<action file name>\n");
66 fprintf(stderr, "\t\t-E<event file name>\n");
67 fprintf(stderr, "\t\t-S<state file name>\n");
68 fprintf(stderr, "\t\t-I<initial values file name>\n");
69 fprintf(stderr, "\t\t-X<debugging file name>\n");
70 fprintf(stderr, "\t\t-K<directory name>\n");
71 fprintf(stderr,
72 "\tThese names do NOT include the suffixes (.c, .h)\n");
73 fprintf(stderr,
74 "\t\t-D<options> to turn on debug options for xebec itself\n");
75 fprintf(stderr, "\t-<nn> for levels of debugging output\n");
76 fprintf(stderr, "\t\t<nn> ranges from 1 to 3, 1 is default(everything)\n");
77 fprintf(stderr, "\t\t-T to print transitions\n");
78 fprintf(stderr, "\t\t-e to print list of combinations of\n");
79 fprintf(stderr, "\t\t\t [event,old_state] that produce protocol errors\n");
80 fprintf(stderr, "\t\t-g include profiling code in driver\n");
81 Exit(-1);
82 }
83
84 void
85 openfiles(proto)
86 register char *proto;
87 {
88 register char *junk;
89 register int lenp = strlen(proto);
90
91 IFDEBUG(b)
92 fprintf(OUT, "openfiles %s\n",proto);
93 ENDDEBUG
94
95 #define HEADER Header
96 #define SOURCE Source
97 #define DOIT(X)\
98 /* GAG */\
99 junk = Malloc( 2 + lenp + strlen(X/**/_name) );\
100 (void) sprintf(junk, "%s_", proto);\
101 X/**/_name = strcat(junk, X/**/_name);\
102 X = fopen(X/**/_name, "w");\
103 if((X)==(FILE *)0)\
104 { fprintf(stderr,"Open failed: %s\n", "X"); Exit(-1); }\
105 fprintf(X, "/* %cHeader%c */\n",'$', '$' );\
106 fprintf(X, "/* %cSource%c */\n",'$', '$' );
107
108 DOIT(eventfile_h);
109
110 IFDEBUG(X)
111 #ifdef DEBUG
112 DOIT(astringfile);
113 #endif /* DEBUG */
114 fprintf(astringfile,
115 "#ifndef _NFILE\n#include <stdio.h>\n#endif /* _NFILE */\n" );
116 ENDDEBUG
117
118 DOIT(statevalfile);
119 DOIT(statefile);
120 DOIT(actfile);
121 fprintf(actfile,
122 "#ifndef lint\nstatic char *rcsid = \"$Header/**/$\";\n#endif /* lint */\n");
123
124 if(pgoption)
125 putdriver(actfile, 15);
126 else
127 putdriver(actfile, 14);
128
129 FakeFilename(actfile, Transfilename, lineno);
130 putdriver(actfile, 1);
131 FakeFilename(actfile, Transfilename, lineno);
132 putdriver(actfile, 12);
133 fprintf(actfile, "#include \"%s%s\"\n", kerneldirname, statevalfile_name);
134 FakeFilename(actfile, Transfilename, lineno);
135 putdriver(actfile, 2);
136
137 initsets(eventfile_h, statefile);
138 }
139
140 void
141 includecode(file, f)
142 FILE *file;
143 register char *f;
144 {
145 register int count=1;
146 static char o='{';
147 static char c='}';
148 register char *g;
149
150 IFDEBUG(a)
151 fprintf(stdout, "including: %s, f=0x%p", f,f);
152 ENDDEBUG
153 g = ++f;
154 while(count>0) {
155 if(*g == o) count++;
156 if(*g == c) count--;
157 g++;
158 }
159 *(--g) = '\0';
160 IFDEBUG(a)
161 fprintf(stdout, "derived: %s", f);
162 ENDDEBUG
163 fprintf(file, "%s", f);
164 FakeFilename(file, Transfilename, lineno);
165 }
166
167 void
168 putincludes()
169 {
170 FakeFilename(actfile, Transfilename, lineno);
171 fprintf(actfile, "\n#include \"%s%s\"\n", kerneldirname, eventfile_h_name);
172 IFDEBUG(X)
173 if( !debug['K'] )
174 fprintf(actfile, "\n#include \"%s\"\n", astringfile_name);
175 /* not in kernel mode */
176 ENDDEBUG
177 FakeFilename(actfile, Transfilename, lineno);
178 }
179
180 int
181 main(argc, argv)
182 int argc;
183 char *argv[];
184 {
185 register int i = 2;
186 extern char *strcpy();
187 int start, finish;
188 extern int FirstEventAttribute;
189 extern int Nevents, Nstates;
190
191 start = time(0);
192 if(argc < 2) {
193 usage(argv[0]);
194 }
195 IFDEBUG(a)
196 fprintf(stdout, "infile = %s\n",argv[1]);
197 ENDDEBUG
198 Transfilename = argv[1];
199 infile = fopen(argv[1], "r");
200
201 if(argc > 2) while(i < argc) {
202 register int j=0;
203 char c;
204 char *name;
205
206 if(argv[i][j] == '-') j++;
207 switch(c = argv[i][j]) {
208
209 /* GROT */
210 case 'A':
211 name = &argv[i][++j];
212 actfile_name = Malloc( strlen(name)+4);
213 actfile_name = (char *)strcpy(actfile_name,name);
214 #ifdef LINT
215 name =
216 #endif /* LINT */
217 strcat(actfile_name, ".c");
218 fprintf(stdout, "debugging file is %s\n",actfile_name);
219 break;
220 case 'K':
221 debug[(unsigned char) c]=1;
222 fprintf(OUT, "option %c file %s\n",c, &argv[i][j+1]);
223 (void) strcpy(kerneldirname,&argv[i][++j]);
224 break;
225 case 'X':
226 debug[(unsigned char) c]=1;
227 name = &argv[i][++j];
228 astringfile_name = Malloc( strlen(name)+4);
229 astringfile_name = (char *)strcpy(astringfile_name,name);
230 #ifdef LINT
231 name =
232 #endif /* LINT */
233 strcat(astringfile_name, ".c");
234 fprintf(OUT, "option %c, astringfile name %s\n",c, name);
235 break;
236 case 'E':
237 name = &argv[i][++j];
238 eventfile_h_name = Malloc( strlen(name)+4);
239 eventfile_h_name = (char *)strcpy(eventfile_h_name,name);
240 #ifdef LINT
241 name =
242 #endif /* LINT */
243 strcat(eventfile_h_name, ".h");
244 fprintf(stdout, "event files is %s\n",eventfile_h_name);
245 break;
246 case 'I':
247 name = &argv[i][++j];
248 statevalfile_name = Malloc( strlen(name)+4 );
249 statevalfile_name = (char *)strcpy(statevalfile_name,name);
250 #ifdef LINT
251 name =
252 #endif /* LINT */
253 strcat(statevalfile_name, ".init");
254 fprintf(stdout, "state table initial values file is %s\n",statevalfile_name);
255 break;
256 case 'S':
257 name = &argv[i][++j];
258 statefile_name = Malloc( strlen(name)+4);
259 statefile_name = (char *)strcpy(statefile_name,name);
260 #ifdef LINT
261 name =
262 #endif /* LINT */
263 strcat(statefile_name, ".h");
264 fprintf(stdout, "state file is %s\n",statefile_name);
265 break;
266 /* END GROT */
267 case '1':
268 case '2':
269 case '3':
270 debug['X']= (int)argv[i][j] - (int) '';
271 fprintf(OUT, "value of debug['X'] is 0x%x,%d\n", debug['X'],
272 debug['X']);
273 break;
274 case 'D':
275 while((c = argv[i][++j])) {
276 if(c == 'X') {
277 fprintf(OUT, "debugging on");
278 if(debug['X']) fprintf(OUT,
279 " - overrides any -%d flags used\n", debug['X']);
280 }
281 debug[(unsigned char) c]=1;
282 fprintf(OUT, "debug %c\n",c);
283 }
284 break;
285 case 'g':
286 pgoption = 1;
287 fprintf(stdout, "Profiling\n");
288 break;
289 case 'e':
290 print_protoerrs = 1;
291 fprintf(stdout, "Protocol error table:\n");
292 break;
293
294 case 'T':
295 print_trans = 1;
296 fprintf(stdout, "Transitions:\n");
297 break;
298 default:
299 usage(argv[0]);
300 break;
301 }
302 i++;
303 }
304 if(kerneldirname[0]) {
305 char *c;
306 #ifdef notdef
307 if(debug['X']) {
308 fprintf(OUT, "Option K overrides option X\n");
309 debug['X'] = 0;
310 }
311 #endif /* notdef */
312 if(strlen(kerneldirname)<1) {
313 fprintf(OUT, "K option: dir name too short!\n");
314 exit(1);
315 }
316 /* add ../name/ */
317 c = (char *) Malloc(strlen(kerneldirname)+6) ;
318 if(c <= (char *)0) {
319 fprintf(OUT, "Cannot allocate %d bytes for kerneldirname\n",
320 strlen(kerneldirname + 6) );
321 fprintf(OUT, "kerneldirname is %s\n", kerneldirname );
322 exit(1);
323 }
324 *c = '.';
325 *(c+1) = '.';
326 *(c+2) = '/';
327 (void) strcat(c, kerneldirname);
328 (void) strcat(c, "/\0");
329 strcpy(kerneldirname, c);
330 }
331
332 init_alloc();
333
334 (void) llparse();
335
336 /* {{ */
337 if( !FirstEventAttribute )
338 fprintf(eventfile_h, "\t}ev_union;\n");
339 fprintf(eventfile_h, "};/* end struct event */\n");
340 fprintf(eventfile_h, "\n#define %s_NEVENTS 0x%x\n", protocol, Nevents);
341 fprintf(eventfile_h,
342 "\n#define ATTR(X)ev_union.%s/**/X/**/\n",EV_PREFIX);
343 (void) fclose(eventfile_h);
344
345 /* {{ */ fprintf(actfile, "\t}\nreturn 0;\n}\n"); /* end switch; end action() */
346 dump_predtable(actfile);
347
348 putdriver(actfile, 3);
349 IFDEBUG(X)
350 if(!debug['K'])
351 putdriver(actfile, 4);
352 ENDDEBUG
353 putdriver(actfile, 6);
354 IFDEBUG(X)
355 /*
356 putdriver(actfile, 10);
357 */
358 if(debug['K']) {
359 putdriver(actfile, 11);
360 } else {
361 switch(debug['X']) {
362 case 1:
363 default:
364 putdriver(actfile, 7);
365 break;
366 case 2:
367 putdriver(actfile, 13);
368 break;
369 case 3:
370 break;
371 }
372 }
373 ENDDEBUG
374 putdriver(actfile, 8);
375 (void) fclose(actfile);
376 IFDEBUG(X)
377 /* { */
378 fprintf(astringfile, "};\n");
379 (void) fclose(astringfile);
380 ENDDEBUG
381
382 (void) fclose(statevalfile);
383
384 fprintf(statefile, "\n#define %s_NSTATES 0x%x\n", protocol, Nstates);
385 (void) fclose(statefile);
386
387 finish = time(0);
388 fprintf(stdout, "%d seconds\n", finish - start);
389 if( print_protoerrs )
390 printprotoerrs();
391
392 exit(0);
393 }
394
395 int transno = 0;
396
397 void
398 Exit(n)
399 {
400 fprintf(stderr, "Error at line %d\n",lineno);
401 if(transno) fprintf(stderr, "Transition number %d\n",transno);
402 (void) fflush(stdout);
403 (void) fflush(statefile);
404 (void) fflush(eventfile_h);
405 (void) fflush(actfile);
406 exit(n);
407 }
408
409 #if 0
410 syntax()
411 {
412 static char *synt[] = {
413 "*PROTOCOL <string>\n",
414 "*PCB <string> <optional: SYNONYM synonymstring>\n",
415 "<optional: *INCLUDE {\n<C source>\n} >\n",
416 "*STATES <string>\n",
417 "*EVENTS <string>\n",
418 "*TRANSITIONS <string>\n",
419 };
420 }
421 #endif
422
423 void
424 FakeFilename(outfile, name, l)
425 FILE *outfile;
426 char *name;
427 int l;
428 {
429 /*
430 doesn't work
431 fprintf(outfile, "\n\n\n\n# line %d \"%s\"\n", l, name);
432 */
433 }
Cache object: f87589563d3f0b72003ee0fa65a238f4
|