|
|
1.1 root 1: #include "local-system"
2: #include <stdio.h>
3: #include <ctype.h>
4: #include "sets.h"
5:
6: typedef struct _symbol symbol;
7: struct _symbol
8: {
9: int value;
10: int range;
11: short flags;
12: symbol *great;
13: symbol *less;
14: char *name;
15: };
16:
17: char *myname;
18: FILE *dump_f;
19: FILE *type_f;
20: int yylval;
21: int want_table;
22: state s = in_source;
23: token t;
24: char iset[(MAX_INDEX / 8) + 1];
25:
26: extern char *malloc();
27: extern char *strcpy();
28: extern char *strrchr();
29:
30: char *
31: salloc(n)
32: register int n;
33: {
34: register char *p;
35:
36: if ((p = malloc(n)) != NULL)
37: return p;
38: fprintf(stderr, "%s: ran out of memory\n", myname);
39: exit(1);
40: }
41:
42: char *
43: scalloc(n)
44: register int n;
45: {
46: register char *p;
47:
48: if ((p = malloc(n)) == NULL)
49: fprintf(stderr, "%s: ran out of memory\n", myname);
50: while (n--)
51: p[n] = '\0';
52: return p;
53: }
54:
55: /*
56: * Find symbol with name s.
57: */
58: symbol *
59: find(s)
60: register char *s;
61: {
62: register symbol **n;
63: register int i;
64: static symbol *stab[STABZ];
65:
66: {
67: register char *p;
68:
69: for (p = s, i = 0; *p != '\0'; i += i ^ *p++)
70: ;
71: n = &stab[i & (STABZ - 1)];
72: }
73: while (*n != NULL)
74: {
75: register int i;
76:
77: if ((i = strcmp(s, (*n)->name)) == 0)
78: return *n;
79: n = i < 0 ? &((*n)->less) : &((*n)->great);
80: }
81: (*n = talloc(symbol))->name = strcpy(salloc(strlen(s) + 1), s);
82: (*n)->flags = 0;
83: (*n)->range = 0;
84: return *n;
85: }
86:
87: gather_enum()
88: {
89: int value = 0;
90: symbol *id;
91:
92: while ((t = get_token()) == sy_id || t == sy_comma)
93: {
94: if (t != sy_comma)
95: {
96: if (want_table)
97: {
98: fprintf
99: (
100: dump_f,
101: "%s%c%c%c",
102: yytext,
103: '\0',
104: (value >> 8) & 0xFF,
105: value & 0xFF
106: );
107: }
108: id = find(yytext);
109: id->flags |= ENUM_ELEMENT;
110: id->value = value++;
111: }
112: }
113: return t == sy_off_curly ? value - 1 : 0;
114: }
115:
116: id_to_yylval()
117: {
118: register symbol *id;
119:
120: if (!((id = find(yytext))->flags & ENUM_ELEMENT))
121: fprintf(stderr, "%s: line %d, '%s' is not a member of any known enum\n", myname, yylineno, id->name);
122: yylval = id->value;
123: }
124:
125: read_enum(silent)
126: int silent;
127: {
128: register int i;
129: register int c;
130: register FILE *f;
131: register symbol *p;
132: char buff[BUFSIZ];
133:
134: if ((f = fopen("enum_tab", "r")) == NULL)
135: {
136: if (silent)
137: goto fpd;
138: fprintf(stderr, "%s: cannot open `enum_tab'.\n", myname);
139: exit(1);
140: }
141:
142: while ((c = getc(f)) != EOF)
143: {
144: i = 0;
145: do
146: {
147: if (i < BUFSIZ - 1)
148: buff[i++] = c;
149: c = getc(f);
150: }
151: while (c != '\0' && c != EOF);
152:
153: buff[i] = '\0';
154:
155: if
156: (
157: c == EOF
158: ||
159: (c = getc(f)) == EOF
160: ||
161: (i = getc(f)) == EOF
162: )
163: {
164: fprintf(stderr, "%s: bad `enum_tab'.\n", myname);
165: exit(1);
166: }
167:
168: if ((p = find(buff))->flags != 0)
169: {
170: fprintf(stderr, "%s: redefinition of %s in `enum_tab'.\n", myname, buff);
171: exit(1);
172: }
173:
174: i &= 0xFF;
175: p->value = i | ((c & 0xFF) << 8);
176: p->flags = ENUM_ELEMENT;
177: }
178:
179: fclose(f);
180:
181: fpd:
182: if ((f = fopen("type_file", "r")) == NULL)
183: {
184: if (silent)
185: return;
186: fprintf(stderr, "%s: cannot open `type_file'.\n", myname);
187: exit(1);
188: }
189:
190: while ((c = getc(f)) != EOF)
191: {
192: i = 0;
193: do
194: {
195: if (i < BUFSIZ - 1)
196: buff[i++] = c;
197: c = getc(f);
198: }
199: while (c != '\0' && c != EOF);
200:
201: buff[i] = '\0';
202:
203: if
204: (
205: c == EOF
206: ||
207: (c = getc(f)) == EOF
208: ||
209: (i = getc(f)) == EOF
210: )
211: {
212: fprintf(stderr, "%s: bad `type_file'.\n", myname);
213: exit(1);
214: }
215:
216: p = find(buff);
217:
218: i &= 0xFF;
219: p->range = i | ((c & 0xFF) << 8);
220: p->flags |= ENUM_TYPE;
221: }
222:
223: fclose(f);
224: }
225:
226: gather_set()
227: {
228: register int largest_index = 0;
229: register int from;
230: register int i;
231:
232: if (t != sy_int && t != sy_id)
233: return 0;
234: for (i = 0; i < (MAX_INDEX / 8) + 1; i++)
235: iset[i] = 0;
236: do
237: {
238: if (t == sy_id)
239: id_to_yylval();
240: from = yylval;
241: if ((t = get_token()) == sy_dot_dot)
242: {
243: if ((t = get_token()) != sy_int && t != sy_id)
244: {
245: fprintf(stderr, "%s: line %d, constant expected after '..'\n", myname, yylineno);
246: return 0;
247: }
248: if (t == sy_id)
249: id_to_yylval();
250: t = get_token();
251: }
252: if (!(t == sy_comma || t == sy_off_squares))
253: fprintf(stderr, "%s: line %d, ',' or ']]' expected\n", myname, yylineno);
254: if (yylval > MAX_INDEX)
255: {
256: fprintf(stderr, "%s: line %d, set element to large\n", myname, yylineno);
257: return 0;
258: }
259: if (from > yylval)
260: {
261: fprintf(stderr, "%s: line %d, left operand of '..' greater than right\n", myname, yylineno);
262: return 0;
263: }
264: while (from <= yylval)
265: {
266: insert(iset, from);
267: from++;
268: }
269: if (yylval > largest_index)
270: largest_index = yylval;
271: } while (t != sy_off_squares && ((t = get_token()) == sy_int || t == sy_id));
272: return t == sy_off_squares ? largest_index + 1 : 0;
273: }
274:
275: main(argc, argv)
276: int argc;
277: char *argv[];
278: {
279: register symbol *enum_id;
280: register int i;
281:
282: if ((myname = strrchr(argv[0], '/')) == NULL || *++myname == '\0')
283: myname = argv[0];
284:
285: switch (argc)
286: {
287: case 3:
288: if (strcmp(argv[2], "-") != 0)
289: {
290: if (freopen(argv[2], "w", stdout) == NULL)
291: {
292: fprintf(stderr, "%s: Cannot open %s.\n", myname, argv[2]);
293: return 1;
294: }
295: }
296: case 2:
297: if (strcmp(argv[1], "-") != 0)
298: {
299: if (freopen(argv[1], "r", stdin) == NULL)
300: {
301: fprintf(stderr, "%s: Cannot open %s.\n", myname, argv[1]);
302: return 1;
303: }
304: }
305: case 1:
306: break;
307:
308: default:
309: fprintf(stderr, "usage: %s [infile [outfile]]\n", myname);
310: return 1;
311: }
312:
313: if (strcmp(myname, "set_expand") == 0)
314: read_enum(0);
315: else if (strcmp(myname, "dump_enum") == 0)
316: {
317: read_enum(1);
318: want_table = 1;
319: if ((i = dup(fileno(stdout))) == SYSERROR)
320: {
321: fprintf(stderr, "%s: Cannot dup stdout.\n", myname);
322: return 1;
323: }
324: if (freopen("/dev/null", "w", stdout) == NULL)
325: {
326: fprintf(stderr, "%s: Cannot open %s.\n", myname, "/dev/null");
327: return 1;
328: }
329: if ((dump_f = fdopen(i, "w")) == NULL)
330: {
331: fprintf(stderr, "%s: Cannot reopen stdout.\n", myname);
332: return 1;
333: }
334: if ((type_f = fopen("type_file", "a")) == NULL)
335: {
336: fprintf(stderr, "%s: Cannot open %s.\n", myname, "type_file");
337: return 1;
338: }
339: }
340:
341: begin_source();
342:
343: while ((t = get_token()) != sy_eof)
344: {
345: switch (s)
346: {
347: case in_source:
348: switch (t)
349: {
350: case sy_set:
351: s = got_set;
352: continue;
353:
354: case sy_typedef:
355: s = got_typedef;
356: continue;
357:
358: case sy_enum:
359: s = got_enum;
360: continue;
361:
362: case sy_on_squares:
363: s = got_on_squares;
364: continue;
365: }
366:
367: case got_set:
368: switch (t)
369: {
370: case sy_char:
371: i = 127;
372: s = want_setid;
373: continue;
374:
375: case sy_id:
376: if ((enum_id = find(yytext))->flags & ENUM_TYPE)
377: {
378: i = enum_id->range;
379: s = want_setid;
380: continue;
381: }
382: fprintf(stderr, "%s: line %d, %s is not an enum\n", myname, yylineno, enum_id->name);
383: s = in_source;
384: begin_source();
385: continue;
386:
387: case sy_enum:
388: /* not_yet();*/
389: s = in_source;
390: begin_source();
391: continue;
392:
393: default:
394: fprintf(stderr, "%s: line %d, bad set declaration\n", myname, yylineno);
395: continue;
396: }
397:
398: case want_setid:
399: if (t == sy_id)
400: printf("char\t%s[%d]", yytext, (i / 8) + 1);
401: s = in_source;
402: begin_source();
403: continue;
404:
405: case got_typedef:
406: if (t == sy_set)
407: {
408: s = got_set;
409: begin_setdefn();
410: }
411: else if (t == sy_enum)
412: s = got_tenum;
413: else
414: {
415: s = in_source;
416: begin_source();
417: }
418: continue;
419:
420: case got_tenum:
421: if (t == sy_id)
422: {
423: enum_id = find(yytext);
424: enum_id->flags |= ENUM_ID;
425: s = got_etypedef;
426: continue;
427: }
428: if (t == sy_on_curly && (i = gather_enum()) != 0)
429: {
430: enum_id = NULL;
431: s = got_etypedef;
432: continue;
433: }
434: s = in_source;
435: begin_source();
436: continue;
437:
438: case got_etypedef:
439: if (t == sy_id)
440: {
441: if (enum_id != NULL)
442: enum_id->range = i;
443: enum_id = find(yytext);
444: enum_id->flags |= ENUM_TYPE;
445: enum_id->range = i;
446: if (want_table)
447: {
448: fprintf
449: (
450: type_f,
451: "%s%c%c%c",
452: yytext,
453: '\0',
454: (i >> 8) & 0xFF,
455: i & 0xFF
456: );
457: }
458: }
459: s = in_source;
460: begin_source();
461: continue;
462:
463: case got_enum:
464: if (t != sy_id)
465: {
466: s = in_source;
467: begin_source();
468: continue;
469: }
470: enum_id = find(yytext);
471: s = got_eid;
472: continue;
473:
474: case got_eid:
475: if (t == sy_on_curly && (i = gather_enum()) != 0)
476: {
477: enum_id->range = i;
478: enum_id->flags |= ENUM_ID;
479: }
480: s = in_source;
481: begin_source();
482: continue;
483:
484: case got_on_squares:
485: if ((i = gather_set()) != 0)
486: {
487: register int j;
488:
489: i = (i + 7) / 8;
490:
491: printf("{");
492: for (j = 0; j < i; j++)
493: printf("0x%X, ", 0xFF & (int)iset[j]);
494: printf("}");
495: }
496: s = in_source;
497: begin_source();
498: continue;
499:
500: default:
501: fprintf(stderr, "%s: unrecognised state %d\n", myname, s);
502: exit(1);
503: }
504: }
505: }
506:
507: char *
508: print_char()
509: {
510: register int c;
511: static char buff[3];
512:
513: c = *yytext & 0x7F;
514:
515: if (c < ' ' || c == 0x3F)
516: {
517: buff[0] = '^';
518: buff[1] = c ^ 0x40;
519: buff[2] = '\0';
520: }
521: else
522: {
523: buff[0] = c;
524: buff[1] = '\0';
525: }
526: return buff;
527: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.