|
|
1.1 root 1: From allegra!vivace!dec Mon Apr 25 20:21:44 1983
2: Date: Mon Apr 25 20:18:09 1983
3: config: lex.yy.c y.tab.c
4: cc -o config y.tab.c -ll
5:
6: all: config
7:
8: lex.yy.c: config.l
9: lex config.l
10:
11: y.tab.c: config.y
12: yacc config.y
13:
14: install: config
15: mv config ../sys/config
16:
17: clean:
18: rm -f lex.yy.c y.tab.c core
19: -------------------------------------------------------------------------------
20: A [a-z_A-Z]
21: M [a-z_A-Z0-9]
22: int skipping;
23: %%
24: "/*" {skipping = 1;}
25: "*/" {skipping = 0;}
26: "%" {extern int brkcount;
27: if (! skipping)
28: if (++brkcount == 2)
29: return(0); /* end-of-file */
30: else
31: return(DEFBRK);
32: }
33: ":" {if (! skipping) return(COLON);}
34: 0[0-9]* {if (! skipping) return(OCTAL);}
35: [1-9][0-9]+ {if (! skipping) return(INTEGER);}
36: is {if (! skipping) return(IS);}
37: on {if (! skipping) return(ON);}
38: "=" ;
39: "iint" {if (! skipping) return(IINT);}
40: "-iint" {if (! skipping) return(IINT);}
41: "oint" {if (! skipping) return(OINT);}
42: "-oint" {if (! skipping) return(OINT);}
43: "-csr" {if (! skipping) return(CSR);}
44: "csr" {if (! skipping) return(CSR);}
45: "-ivec" {if (! skipping) return(IVEC);}
46: "ivec" {if (! skipping) return(IVEC);}
47: "-ovec" {if (! skipping) return(OVEC);}
48: "ovec" {if (! skipping) return(OVEC);}
49: "-i" {if (! skipping) return(INIT);}
50: "i" {if (! skipping) return(INIT);}
51: "-o" {if (! skipping) return(OPEN);}
52: "o" {if (! skipping) return(OPEN);}
53: "-c" {if (! skipping) return(CLOSE);}
54: "c" {if (! skipping) return(CLOSE);}
55: "-r" {if (! skipping) return(READ);}
56: "r" {if (! skipping) return(READ);}
57: "-g" {if (! skipping) return(GETC);}
58: "g" {if (! skipping) return(GETC);}
59: "-p" {if (! skipping) return(PUTC);}
60: "p" {if (! skipping) return(PUTC);}
61: "-w" {if (! skipping) return(WRITE);}
62: "w" {if (! skipping) return(WRITE);}
63: "-s" {if (! skipping) return(SEEK);}
64: "s" {if (! skipping) return(SEEK);}
65: "-n" {if (! skipping) return(CNTL);}
66: "n" {if (! skipping) return(CNTL);}
67: [ \t]+ ;
68: "\n" {extern int linectr;
69: linectr++;
70: }
71: {A}{M}* {if (! skipping) return(IDENT);}
72: . {if (! skipping) return(yytext[0]);}
73: -------------------------------------------------------------------------------
74: %token DEFBRK COLON OCTAL INTEGER IDENT CSR IVEC OVEC IINT OINT
75: INIT OPEN CLOSE READ WRITE SEEK CNTL IS ON GETC PUTC
76: %{
77: #include <stdio.h>
78:
79: #define NIL (dvptr)0
80:
81: #define CONFIGC "../sys/conf.c" /* name of .c output */
82: #define CONFIGH "../h/conf.h" /* name of .h output */
83: #define CONFIGIN "Configuration" /* name of input file */
84:
85: FILE *confc;
86: FILE *confh;
87:
88: char *dbstr;
89: extern char *malloc();
90: int ndevs = 0;
91: int currname = -1;
92: int currtname = -1;
93: int currdname = -1;
94: int brkcount = 0;
95:
96: struct syment { /* symbol table */
97: char *symname;
98: int symoccurs;
99: } symtab[250];
100:
101: int nsym = 0;
102: int lookup();
103: int linectr = 1;
104: char *doing = "device type declaration";
105: char *s;
106: struct dvtype {
107: char *dvname; /* device name (not used in types)*/
108: char *dvtname; /* type name */
109: int dvtnum; /* symbol table index of type */
110: char *dvdevice; /* device name */
111: int dvcsr; /* Control Status Register addr */
112: int dvivec; /* input interrupt vector */
113: int dvovec; /* Output interrupt vector */
114: char dviint[20]; /* input interrupt routine */
115: char dvoint[20]; /* output interrupt routine */
116: char dvinit[20]; /* init routine name */
117: char dvopen[20]; /* open routine name */
118: char dvclose[20]; /* close routine name */
119: char dvread[20]; /* read routine name */
120: char dvwrite[20]; /* write routine name */
121: char dvcntl[20]; /* control routine name */
122: char dvseek[20]; /* seek routine name */
123: char dvgetc[20]; /* getc routine name */
124: char dvputc[20]; /* putc routine name */
125: int dvminor; /* device number 0,1,... */
126: struct dvtype *dvnext; /* next node on the list */
127: };
128: typedef struct dvtype *dvptr;
129: dvptr ftypes = NIL; /* linked list of device types */
130: dvptr devs = NIL; /* linked list of device decls. */
131: dvptr lastdv = NIL;
132: dvptr currtype = NIL;
133:
134: char *ftout[] =
135: {"struct\tdevsw\t{\t\t\t/* device table entry */\n",
136: "\tint\tdvnum;\n",
137: "\tint\t(*dvinit)();\n",
138: "\tint\t(*dvopen)();\n",
139: "\tint\t(*dvclose)();\n",
140: "\tint\t(*dvread)();\n",
141: "\tint\t(*dvwrite)();\n",
142: "\tint\t(*dvseek)();\n",
143: "\tint\t(*dvgetc)();\n",
144: "\tint\t(*dvputc)();\n",
145: "\tint\t(*dvcntl)();\n",
146: "\tint\tdvcsr;\n",
147: "\tint\tdvivec;\n",
148: "\tint\tdvovec;\n",
149: "\tint\t(*dviint)();\n",
150: "\tint\t(*dvoint)();\n",
151: "\tchar\t*dvioblk;\n",
152: "\tint\tdvminor;\n",
153: "\t};\n\n",
154: "extern\tstruct\tdevsw devtab[];",
155: "\t\t/* one entry per device */\n\n",
156: NULL};
157: %}
158: %%
159: config.input : devicetypes devicedescriptors
160: ;
161: devicetypes : ftypes DEFBRK
162: {doing = "device definitions";}
163: ;
164: ftypes : /**/
165: | ftypes ftype
166: ;
167: ftype : tname device.list
168: ;
169: device.list : devheader attribute.list
170: | device.list devheader attribute.list
171: ;
172: devheader : ON id
173: {mktype($2);}
174: ;
175: tname : id COLON
176: {$$ = currtname = cktname($1);}
177: ;
178: id : IDENT
179: {$$ = currname =
180: lookup(yytext,yyleng);
181: }
182: ;
183: attribute.list : /**/
184: | attribute.list attribute
185: ;
186: attribute : CSR number
187: {newattr(CSR,$2);}
188: | IVEC number
189: {newattr(IVEC,$2);}
190: | OVEC number
191: {newattr(OVEC,$2);}
192: | IINT id
193: {newattr(IINT,$2);}
194: | OINT id
195: {newattr(OINT,$2);}
196: | OPEN id
197: {newattr(OPEN,$2);}
198: | CLOSE id
199: {newattr(CLOSE,$2);}
200: | INIT id
201: {newattr(INIT,$2);}
202: | GETC id
203: {newattr(GETC,$2);}
204: | PUTC id
205: {newattr(PUTC,$2);}
206: | READ id
207: {newattr(READ,$2);}
208: | WRITE id
209: {newattr(WRITE,$2);}
210: | SEEK id
211: {newattr(SEEK,$2);}
212: | CNTL id
213: {newattr(CNTL,$2);}
214: ;
215: number : INTEGER
216: /* Assume all input is octal */
217: /* for now; distinction is */
218: /* made in lexical routines */
219: /* just in case of change */
220:
221: {$$ = otoi(yytext,yyleng);}
222: | OCTAL
223: {$$ = otoi(yytext,yyleng);}
224: ;
225: devicedescriptors : /**/
226: | devicedescriptors descriptor
227: ;
228: descriptor : fspec attribute.list
229: ;
230: fspec : dname IS id optional.on
231: {mkdev($1,$3,$4);}
232: ;
233: dname : id
234: {$$ = currdname = ckdname($1);}
235: ;
236: optional.on : /**/
237: {$$ = 0;}
238: | ON id
239: {$$ = $2;}
240: ;
241: %%
242: #include "lex.yy.c"
243: main(argc, argv)
244: int argc;
245: char *argv[];
246: {
247: int n, i, j, l, fcount;
248: dvptr s;
249: int verbose = 0;
250: char *p;
251: char c;
252:
253: if (argc>1 && (strcmp("-v",argv[1])==0)) {
254: argc--;
255: argv++;
256: verbose++;
257: }
258: if (argc>2) {
259: fprintf(stderr,"use: config [-v] [file]\n");
260: exit(1);
261: }
262: if (verbose)
263: printf("Opening input file...\n");
264: if (argc == 2) {
265: if (freopen(argv[1], "r", stdin) == NULL) {
266: fprintf(stderr,"Can't open %s\n",argv[1]);
267: exit(1);
268: }
269: } else { /* try to open Configuration file */
270: if (freopen(CONFIGIN, "r", stdin) == NULL) {
271: fprintf(stderr,"Can't open %s\n", CONFIGIN);
272: exit(1);
273: }
274: }
275:
276: /* Parse the Configuration file */
277:
278: if (verbose)
279: printf("Parsing configuration specs...\n");
280: if ((n=yyparse()) != 0)
281: exit(n);
282:
283: /* write config.h and config.c */
284:
285: if (verbose)
286: printf("Opening output files...\n");
287: if ( (confc=fopen(CONFIGC,"w") ) == NULL) {
288: fprintf(stderr, "Can't write on %s\n", CONFIGC);
289: exit(1);
290: }
291:
292: if ( (confh=fopen(CONFIGH,"w") ) == NULL) {
293: fprintf(stderr, "Can't write on %s\n", CONFIGH);
294: exit(1);
295: }
296: fprintf(confh,
297: "/* conf.h (GENERATED FILE; DO NOT EDIT) */\n");
298: fprintf(confc,
299: "/* conf.c (GENERATED FILE; DO NOT EDIT) */\n");
300: fprintf(confc, "\n#include \"%s\"\n", CONFIGH);
301: fprintf(confh, "\n#define\tNULLPTR\t(char *)0\n");
302:
303:
304: if (verbose)
305: printf("Writing output...\n");
306: fprintf(confh,"\n/* Device table declarations */\n");
307: for (i=0 ; (p=ftout[i])!=NULL ; i++)
308: fprintf(confh, "%s", p);
309:
310: /* write device declarations and definitions; count type refs. */
311:
312: fprintf(confh, "\n/* Device name definitions */\n\n");
313: for (i=0,s=devs; s!=NIL ; s=s->dvnext,i++) {
314: fprintf(confh, "#define\t%-12s%d\t\t\t/* type %-8s */\n",
315: s->dvname, i, s->dvtname);
316: s->dvminor = symtab[s->dvtnum].symoccurs++;
317: }
318:
319: /* write count of device types */
320:
321: fprintf(confh,"\n/* Control block sizes */\n\n");
322: for (i=0 ; i<nsym ; i++)
323: if (symtab[i].symoccurs > 0) {
324: fprintf(confh, "#define\tN%s\t%d\n",
325: symtab[i].symname, symtab[i].symoccurs);
326: }
327: if (ndevs > 0)
328: fprintf(confh, "\n#define\tNDEVS\t%d\n\n", ndevs);
329:
330: /* empty symbol table, collect, and write names of all I/O routines */
331:
332: nsym = 0;
333: for (s=devs; s!=NIL ; s=s->dvnext) {
334: lookup(s->dvinit,strlen(s->dvinit));
335: lookup(s->dvopen,strlen(s->dvopen));
336: lookup(s->dvclose,strlen(s->dvclose));
337: lookup(s->dvread,strlen(s->dvread));
338: lookup(s->dvwrite,strlen(s->dvwrite));
339: lookup(s->dvseek,strlen(s->dvseek));
340: lookup(s->dvcntl,strlen(s->dvcntl));
341: lookup(s->dvgetc,strlen(s->dvgetc));
342: lookup(s->dvputc,strlen(s->dvputc));
343: lookup(s->dviint,strlen(s->dviint));
344: lookup(s->dvoint,strlen(s->dvoint));
345:
346: }
347: fprintf(confh,
348: "/* Declarations of I/O routines referenced */\n\n");
349: for (i=0 ; i<nsym ; i++)
350: fprintf(confh, "extern\tint\t%s();\n", symtab[i].symname);
351:
352:
353: /* produce devtab (giant I/O switch table) */
354:
355: fprintf(confc, "\n/* device independent I/O switch */\n\n");
356: if (ndevs > 0)
357: fprintf(confc, "struct\tdevsw\tdevtab[NDEVS] = {\n");
358: for (fcount=0,s=devs ; s!=NIL ; s=s->dvnext,fcount++) {
359: fprintf(confc, "\n/* %s */\n", s->dvname, s->dvtname);
360: fprintf(confc, "%d,\n", fcount);
361: fprintf(confc, "%s, %s, %s,\n",
362: s->dvinit, s->dvopen, s->dvclose);
363: fprintf(confc, "%s, %s, %s,\n",
364: s->dvread, s->dvwrite, s->dvseek);
365: fprintf(confc, "%s, %s, %s,\n",
366: s->dvgetc, s->dvputc, s->dvcntl);
367: fprintf(confc, "0%06o, 0%03o, 0%03o,\n",
368: s->dvcsr, s->dvivec, s->dvovec);
369: fprintf(confc, "%s, %s, NULLPTR, %d",
370: s->dviint, s->dvoint, s->dvminor);
371: if ( s->dvnext != NIL )
372: fprintf(confc, ",\n");
373: else
374: fprintf(confc, "\n\t};");
375: }
376:
377: /* Copy definitions to output */
378:
379: if (brkcount == 2 && verbose)
380: printf("Copying definitions to %s...\n", CONFIGH);
381: if (brkcount == 2 )
382: while ( (c=input()) != 0) /* lex input routine */
383: putc(c, confh);
384:
385: /* guarantee conf.c written later than conf.c for make */
386:
387: fclose(confh);
388: fprintf(confc, "\n");
389: fclose(confc);
390:
391: /* finish up and write report for user if requested */
392:
393: if (verbose) {
394: printf("\nConfiguration complete. Number of devs=%d:\n\n",ndevs);
395: for (s=devs; s!=NIL ; s=s->dvnext)
396: printf(
397: "Device %s (on %s) csr=0%-7o, ivec=0%-3o, ovec=0%-3o, minor=%d\n",
398: s->dvname, s->dvdevice, s->dvcsr, s->dvivec, s->dvovec,
399: s->dvminor);
400: }
401:
402:
403: }
404:
405:
406: yyerror(s)
407: char *s;
408: {
409: fprintf(stderr,"Syntax error in %s on line %d\n",
410: doing,linectr);
411: }
412:
413:
414: /* lookup -- lookup a name in the symbol table; return position */
415:
416: lookup(str,len)
417: char *str;
418: int len;
419: {
420: int i;
421: char *s;
422:
423: if (len >= 20) {
424: len = 19;
425: fprintf(stderr,"warning: name %s truncated\n",str);
426: }
427: s = malloc(len+1);
428: strncpy(s,str,len);
429: s[len] = '\000';
430: for (i=0 ; i<nsym ; i++)
431: if (strcmp(s,symtab[i].symname) == 0){
432: return(i);
433: }
434: symtab[nsym].symname = s;
435: symtab[nsym].symoccurs = 0;
436: return(nsym++);
437: }
438:
439: atoi(str,len)
440: char *str;
441: int len;
442: {
443: int i;
444: char c;
445:
446: for (i=0; len > 0 ; len--) {
447: c = *str++;
448: i = 10*i + (c - '0');
449: }
450: }
451: otoi(str,len)
452: char *str;
453: int len;
454: {
455: int i;
456: char c;
457:
458: for (i=0; len > 0 ; len--) {
459: c = *str++;
460: if (c > '7')
461: fprintf(stderr,"invalid octal digit on line %d\n",
462: linectr);
463: else
464: i = 8*i + (c - '0');
465: }
466: }
467:
468: /* newattr -- add a new attribute spec to current type/device description */
469:
470: newattr(tok,val)
471: int tok; /* token type (attribute type) */
472: int val; /* symbol number of value */
473: {
474: char *c;
475: dvptr s;
476:
477: if (devs == NIL) /* doing types */
478: s = currtype;
479: else
480: s = lastdv;
481: if (val>=0 && val<nsym) {
482: c = symtab[val].symname;
483: if (strlen(c) > 20 ) {
484: fprintf(stderr,"Internal overflow\n");
485: exit(1);
486: }
487: } else
488: c = NULL;
489:
490: switch (tok) {
491:
492: case CSR: s->dvcsr = val;
493: break;
494: case IVEC: s->dvivec = val;
495: break;
496: case OVEC: s->dvovec = val;
497: break;
498: case IINT: strcpy(s->dviint,c);
499: break;
500: case OINT: strcpy(s->dvoint,c);
501: break;
502: case READ: strcpy(s->dvread,c);
503: break;
504: case WRITE: strcpy(s->dvwrite,c);
505: break;
506: case GETC: strcpy(s->dvgetc,c);
507: break;
508: case PUTC: strcpy(s->dvputc,c);
509: break;
510: case OPEN: strcpy(s->dvopen,c);
511: break;
512: case CLOSE: strcpy(s->dvclose,c);
513: break;
514: case INIT: strcpy(s->dvinit,c);
515: break;
516: case SEEK: strcpy(s->dvseek,c);
517: break;
518: case CNTL: strcpy(s->dvcntl,c);
519: break;
520: default: fprintf(stderr, "Internal error 1\n");
521: }
522: }
523:
524: /* cktname -- check type name for duplicates */
525:
526: cktname(symid)
527: int symid;
528: {
529: dvptr s;
530: extern dvptr ftypes;
531: char *name;
532:
533: name = symtab[symid].symname;
534: for (s=ftypes; s!=NIL ; s=s->dvnext) {
535: if (s->dvtname == name) {
536: fprintf(stderr,"Duplicate type name %s on line %d\n",
537: name,linectr);
538: exit(1);
539: }
540: }
541: return(symid);
542: }
543:
544: /* mktype -- make a node in the type list and initialize to defaults */
545:
546: mktype(deviceid)
547: int deviceid;
548: {
549: dvptr s,p;
550: char *tn,*dn;
551:
552: p = NIL;
553: tn = symtab[currtname].symname;
554: dn = symtab[deviceid].symname;
555: for (s = ftypes; s!=NIL ; s=s->dvnext) {
556: if (s->dvtname == tn && s->dvdevice==dn) {
557: fprintf(stderr,
558: "Duplicate device %s for type %s on line %d\n",
559: dn, tn, linectr);
560: exit(1);
561: }
562: p = s;
563: }
564: currtype = s = (dvptr) malloc( sizeof(struct dvtype));
565: if (ftypes != NIL) {
566: p->dvnext = s;
567: }
568: else {
569: ftypes = s;
570: }
571: initattr(s, currtname, deviceid);
572: }
573:
574: /* initialize attributes in a type declaration node to typename... */
575:
576: initattr(fstr, tnum, deviceid)
577: dvptr fstr;
578: int tnum;
579: int deviceid;
580: {
581: char *typnam;
582:
583: typnam = symtab[tnum].symname;
584: fstr->dvname = NULL;
585: fstr->dvtname = typnam;
586: fstr->dvtnum = tnum;
587: fstr->dvdevice = symtab[deviceid].symname;
588: fstr->dvcsr = 0;
589: fstr->dvivec = 0;
590: fstr->dvovec = 0;
591: strcpy(fstr->dviint,typnam);
592: strcat(fstr->dviint,"iin");
593: strcpy(fstr->dvoint,typnam);
594: strcat(fstr->dvoint,"oin");
595: strcpy(fstr->dvinit,typnam);
596: strcat(fstr->dvinit,"init");
597: strcpy(fstr->dvopen,typnam);
598: strcat(fstr->dvopen,"open");
599: strcpy(fstr->dvclose,typnam);
600: strcat(fstr->dvclose,"close");
601: strcpy(fstr->dvread,typnam);
602: strcat(fstr->dvread,"read");
603: strcpy(fstr->dvwrite,typnam);
604: strcat(fstr->dvwrite,"write");
605: strcpy(fstr->dvcntl,typnam);
606: strcat(fstr->dvcntl,"control");
607: strcpy(fstr->dvseek,typnam);
608: strcat(fstr->dvseek,"seek");
609: strcpy(fstr->dvgetc,typnam);
610: strcat(fstr->dvgetc,"getc");
611: strcpy(fstr->dvputc,typnam);
612: strcat(fstr->dvputc,"putc");
613: fstr->dvminor = 0;
614: }
615:
616: /* mkdev -- make a node on the device list */
617:
618: mkdev(nameid, typid, deviceid)
619: int nameid, typid, deviceid;
620: {
621: dvptr s;
622: char *devn,*tn,*dn;
623: int found;
624:
625: s = (dvptr) malloc(sizeof(struct dvtype));
626: s->dvnext = NIL;
627: if (devs == NIL) {
628: devs = s;
629: lastdv = s;
630: } else {
631: lastdv->dvnext = s;
632: lastdv = s;
633: }
634: ndevs++;
635: tn = symtab[typid].symname;
636: devn = symtab[nameid].symname;
637: if (deviceid >= 0)
638: dn = symtab[deviceid].symname;
639: else
640: dn = NULL;
641: found = 0;
642: for (s=ftypes ; s != NULL ; s=s->dvnext)
643: if (s->dvtname == tn && (dn==NULL || s->dvdevice==dn)) {
644: strdup(lastdv,s,sizeof(struct dvtype));
645: found=1;
646: break;
647: }
648: if (found==0) {
649: fprintf(stderr,
650: "Bad type or device name in declaration of %s on line %d\n",
651: devn, linectr);
652: exit(1);
653: }
654: lastdv->dvnext = NIL;
655: lastdv->dvname = devn;
656: }
657:
658:
659: /* chdname -- check for duplicate device name */
660:
661: ckdname(devid)
662: int devid;
663: {
664: dvptr s;
665: extern dvptr devs;
666: char *name;
667:
668: name = symtab[devid].symname;
669: for (s=devs; s!=NIL ; s=s->dvnext) {
670: if (s->dvname == name) {
671: fprintf(stderr,"Duplicate device name %s on line %d\n",
672: name,linectr);
673: exit(1);
674: }
675: }
676: return(devid);
677: }
678:
679: strdup(tostr,fromstr,len)
680: char *tostr, *fromstr;
681: int len;
682: {
683: for( ; len > 0 ; len--)
684: *tostr++ = *fromstr++;
685: }
686: -------------------------------------------------------------------------------
687:
688:
689:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.