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