|
|
1.1 root 1: /*
2: * Lexer and mainline for new screen builder.
3: */
4: #include <scnbld.h>
5: #include <y.tab.h>
6: #include <string.h>
7: #include <ctype.h>
8:
9: FILE *ifp, *ofp, *ohp;
10: int line = 1;
11: int fieldDesig = '!';
12: static int errors;
13: static char *name;
14:
15: #ifdef TRACE
16: #define RET(val) { printf("%d: trace %d\n", __LINE__, val); return(val); }
17: #else
18: #define RET(val) return(val);
19: #endif
20: #define POINT printf("%d: trace point\n", __LINE__);
21:
22: /*
23: * Fatal error.
24: */
25: void
26: fatal(s)
27: char *s;
28: {
29: printf("%d: %r\n%d error%s detected\n",
30: line, &s, (errors + 1), (errors ? "s": ""));
31: exit(1);
32: }
33:
34: /*
35: * Nonfatal error.
36: */
37: yyerror(s)
38: char *s;
39: {
40: printf("%d: %r\n", line, &s);
41: errors++;
42: }
43:
44: main(argc, argv)
45: char *argv[];
46: {
47: char *p, *q, *fileName;
48: char file[20];
49:
50: if (NULL == (fileName = argv[1]))
51: fatal("No work.");
52:
53: ifp = xopen(fileName, "r");
54:
55: /* Turn file name into .c and .h version in current dir */
56: if (NULL == (p = strrchr(fileName, '/')))
57: p = fileName;
58: else
59: p++;
60:
61: if (NULL != (q = strrchr(p, '.')))
62: *q = '\0';
63:
64: sprintf(file, "%s.c", p);
65: ofp = xopen(file, "w");
66:
67: sprintf(file, "%s.h", p);
68: ohp = xopen(file, "w");
69:
70: name = newcpy(p);
71:
72: if(NULL != q)
73: *q = '.';
74:
75: fprintf(ofp, "/*\n");
76: fprintf(ofp, " * Screen definition file\n");
77: fprintf(ofp, " * This file generated from %s\n", fileName);
78: fprintf(ofp, " */\n");
79: fprintf(ofp, "#include <%s>\n\n", file);
80:
81: fprintf(ohp, "/*\n");
82: fprintf(ohp, " * Screen definition header\n");
83: fprintf(ohp, " * This file generated from %s\n", fileName);
84: fprintf(ohp, " */\n");
85: fprintf(ohp, "#include <scn.h>\n\n");
86: fprintf(ohp, "extern backGrnd %s_data[];\n", name);
87: fprintf(ohp, "extern loc %s_locs[];\n", name);
88:
89: yyparse();
90:
91: finish();
92: }
93:
94: typedef enum state state;
95: enum state { start, inname, innum, instr, bsl, incomm, pct, pctEnd };
96:
97: struct sym {
98: char *name;
99: int ytype;
100: } table[] = {
101: "external", EXT,
102: "readonly", RONLY,
103: "long", LONG,
104: "default", DEFAULT,
105: "skip", SKIP,
106: "group", GROUP,
107: "help", HELP,
108: "verify", VERIFY,
109: "designator", DESIG,
110: "do", DO,
111: "done", DONE,
112: NULL
113: };
114:
115: yylex()
116: {
117: register int c;
118: register struct sym *tp;
119: state st, pst;
120: char buf[80], *p;
121:
122: for (pst = st = start; ; ) {
123: if (EOF == (c = fgetc(ifp)))
124: fatal("unexpected EOF");
125:
126: switch (st) {
127: case pctEnd:
128: if ('\n' == c) {
129: line++;
130: RET(EOF)
131: }
132: continue;
133:
134: case pct:
135: if ('%' != c) {
136: yyerror("Lex error %%%c", c);
137: st = start;
138: continue;
139: }
140: st = pctEnd;
141: continue;
142:
143: case bsl:
144: if (start == pst) {
145: if ('\n' == c) {
146: line++;
147: st = start;
148: continue;
149: }
150: yyerror("%c after \\ outside of string");
151: st = start;
152: continue;
153: }
154: *p++ = c;
155: st = pst;
156: continue;
157:
158: case instr:
159: switch (c) {
160: case '\\':
161: pst = st;
162: st = bsl;
163: *p++ = c;
164: continue;
165: case '\n':
166: yyerror("new line in string");
167: case '"':
168: *p++ = '"';
169: *p = 0;
170: yylval.string = newcpy(buf);
171: RET(STRING)
172: default:
173: *p++ = c;
174: continue;
175: }
176: case inname:
177: if (isalnum(c)) {
178: *p++ = c;
179: continue;
180: }
181: st = start;
182: ungetc(c, ifp);
183: *p = '\0';
184:
185: for (tp = table; tp->name != NULL; tp++)
186: if (!strcmp(tp->name, buf))
187: RET(tp->ytype)
188:
189: yylval.string = newcpy(buf);
190: RET(NAME)
191:
192: case innum:
193: if (isdigit(c)) {
194: *p++ = c;
195: continue;
196: }
197: st = start;
198: ungetc(c, ifp);
199: *p = '\0';
200: yylval.val = atoi(buf);
201: RET(NUMBER)
202:
203: case incomm:
204: switch (c) {
205: case '\\':
206: pst = start;
207: break;
208: case '\n':
209: line++;
210: st = start;
211: }
212: continue;
213:
214: case start:
215: switch (c) {
216: case '#':
217: st = incomm;
218: continue;
219: case '%':
220: st = pct;
221: continue;
222: case '\n':
223: line++;
224: RET(NL)
225: case '\\':
226: pst = st;
227: st = bsl;
228: continue;
229: case '"':
230: st = instr;
231: p = buf;
232: *p++ = c;
233: continue;
234: default:
235: if (isspace(c))
236: continue;
237:
238: if (isdigit(c)) {
239: st = innum;
240: p = buf;
241: *p++ = c;
242: continue;
243: }
244:
245: if (isalpha(c)) {
246: st = inname;
247: p = buf;
248: *p++ = c;
249: continue;
250: }
251: yyerror("Lexical error %c", c);
252: }
253: }
254: }
255: }
256:
257: typedef struct namelist namelist;
258: struct namelist {
259: namelist *next;
260: char *name;
261: };
262:
263: /*
264: * output extern for verify routine.
265: */
266: void
267: outExtern(n)
268: char *n;
269: {
270: static namelist *root = NULL;
271: register namelist *p;
272:
273: for (p = root; p != NULL; p = p->next)
274: if (!strcmp(p->name, n))
275: return;
276:
277: p = alloc(sizeof(*p));
278: p->next = root;
279: p->name = n;
280: root = p;
281: fprintf(ohp, "extern int %s();\n", n);
282: }
283:
284: /*
285: * finish processing the scn tables.
286: */
287: finish()
288: {
289: int c;
290: clump *cp;
291: loc *lp;
292: int times, count, toOut;
293: int row, col, started;
294: char *p, buf[80];
295:
296: fprintf(ofp, "backGrnd %s_data[] = {\n", name);
297:
298: for (row = col = started = times = count = 0, lp = locs, cp = clumps;
299: EOF != (c = fgetc(ifp)); ) {
300: if (c == fieldDesig) {
301: c = ' ';
302: if (NULL == lp) {
303: yyerror("To few fields defined");
304: break;
305: }
306:
307: if (NULL != cp && (cp->from == lp) && !times) {
308: times = cp->times;
309: count = cp->count;
310: }
311: if (count) {
312: if (NULL == lp->these)
313: lp->these = alloc(sizeof(pair) * times);
314: lp->these[times - 1].row = row;
315: lp->these[times - 1].col = col;
316: }
317: else {
318: lp->row = row;
319: lp->col = col;
320: }
321: lp = lp->next;
322: if (count && !--count) { /* last in group */
323: if (--times) { /* go around again */
324: count = cp->count;
325: lp = cp->from;
326: }
327: else /* next group */
328: cp = cp->next;
329: }
330: }
331: if (!started) { /* No chars output for this line yet */
332: switch (c) {
333: case '\n':
334: row++;
335: col = 0;
336: continue;
337: case '\t':
338: col |= 7;
339: case ' ':
340: col++;
341: continue;
342: }
343: started++;
344: toOut = col;
345: p = buf;
346: fputc('"', ofp);
347: }
348: switch (c) {
349: case '\t':
350: col |= 7;
351: col++;
352: *p++ = '\\';
353: *p++ = 't';
354: continue;
355: case '\n':
356: fprintf(ofp, "\",\n\t%d, %d,\n", row, toOut);
357: row++;
358: col = 0;
359: started = 0;
360: continue;
361: case ' ':
362: *p++ = c;
363: col++;
364: continue;
365: }
366: col++;
367: if (buf != p) { /* we have saved some whitespace */
368: *p = 0;
369: fprintf(ofp, "%s", buf);
370: p = buf;
371: }
372: switch (c) { /* we are putting stuff into c strings */
373: case '\\':
374: case '"':
375: fputc('\\', ofp);
376: }
377: fputc(c, ofp);
378: }
379: fprintf(ofp, "\tNULL\n};\n");
380: if (NULL != lp)
381: yyerror("To many fields defined");
382:
383: /*
384: * Output field descriptors.
385: */
386: for (times = count = 0, cp = clumps, lp = locs;
387: lp != NULL;
388: lp = lp->next) {
389: if (NULL != cp && (cp->from == lp)) {
390: count = cp->count;
391: times = cp->times;
392: }
393: if (count) {
394: if(lp->flags & LONGFIELD) {
395: if (!(lp->flags & EXTERNAL))
396: fprintf(ofp, "char *%s[%d];\n",
397: lp->field, times);
398: fprintf(ohp, "extern char *%s[%d];\n",
399: lp->field, times);
400: }
401: else {
402: if (!(lp->flags & EXTERNAL))
403: fprintf(ofp, "char %s[%d][%d];\n",
404: lp->field, times, lp->len + 1);
405: fprintf(ohp, "extern char %s[%d][%d];\n",
406: lp->field, times, lp->len + 1);
407: }
408: if(!--count)
409: cp = cp->next;
410: }
411: else {
412: if(lp->flags & LONGFIELD) {
413: if (!(lp->flags & EXTERNAL))
414: fprintf(ofp, "char *%s;\n", lp->field);
415: fprintf(ohp, "extern char *%s;\n", lp->field);
416: }
417: else {
418: if (!(lp->flags & EXTERNAL))
419: fprintf(ofp, "char %s[%d];\n",
420: lp->field, lp->len + 1);
421: fprintf(ohp, "extern char %s[%d];\n",
422: lp->field, lp->len + 1);
423: }
424: }
425: if (NULL == lp->verify)
426: lp->verify = "noVerify";
427: outExtern(lp->verify);
428: }
429: fprintf(ofp, "\n");
430:
431: /*
432: * Output loc table.
433: */
434: fprintf(ofp, "loc %s_locs[] = {\n", name);
435:
436: for (times = count = 0, cp = clumps, lp = locs; lp != NULL;) {
437: if (NULL != cp && (cp->from == lp) && !times) {
438: times = cp->times;
439: count = cp->count;
440: toOut = (times * count);
441: }
442:
443: if (count) {
444: toOut--;
445: lp->row = lp->these[times - 1].row;
446: lp->col = lp->these[times - 1].col;
447:
448: if(lp->flags & LONGFIELD)
449: sprintf(buf, "%s + %d",
450: lp->field, cp->times - times);
451: else
452: sprintf(buf, "%s[%d]",
453: lp->field, cp->times - times);
454: }
455: else {
456: if(lp->flags & LONGFIELD)
457: sprintf(buf, "&%s", lp->field);
458: else
459: sprintf(buf, "%s", lp->field);
460: }
461:
462: fprintf(ofp, "\t{ %s, %d, %s, %s, %d, %d, %d, %d, %s },\n",
463: buf,
464: lp->len,
465: ((NULL == lp->Default) ? buf : lp->Default),
466: lp->verify,
467: lp->flags & (LONGFIELD|READONLY),
468: lp->row,
469: lp->col,
470: ((255 == lp->skipf) ? toOut : lp->skipf),
471: ((NULL == lp->help) ? "NULL" : lp->help));
472:
473: lp = lp->next;
474: if (count && !--count) { /* last in group */
475: if (--times) { /* go around again */
476: count = cp->count;
477: lp = cp->from;
478: }
479: else
480: cp = cp->next; /* next group */
481: }
482: }
483: fprintf(ofp, "\tNULL\n};\n");
484: if(errors) {
485: printf("%d error%s detected\n",
486: errors, ((1 == errors) ? "s": ""));
487: exit(1);
488: }
489: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.