|
|
1.1 root 1: /*
2: * mkconf.c 1.10 85/01/03
3: * Functions in this file build conf.c from the devices list
4: */
5:
6: #include <stdio.h>
7: #include <ctype.h>
8: #include "y.tab.h"
9: #include "config.h"
10:
11: #define next_word(fp, wd)\
12: { register char *word = get_word(fp);\
13: if (word == WEOF) return EOF; \
14: else wd = word; }
15:
16: #define max(a,b) ((a) > (b) ? (a) : (b))
17: #define bit(n) (1L << (n))
18:
19: static struct dev_list *dcur;
20:
21: struct routine {
22: char *rt_name;
23: char *rt_type;
24: int rt_class;
25: char *rt_default;
26: char *rt_empty;
27: };
28:
29: #define FUNC 1
30: #define POINTER 2
31: #define LITERAL 3
32:
33: struct routine block_routines[] = {
34: {"open", "int", FUNC, "nulldev", "nodev"},
35: {"close", "int", FUNC, "nulldev", "nodev"},
36: {"strategy", "int", FUNC, "nodev"},
37: {"dump", "int", FUNC, "nodev"},
38: {"B_TAPE", NULL, LITERAL, "0"},
39: {NULL}
40: };
41: struct routine char_routines[] = {
42: {"open", "int", FUNC, "nulldev", "nodev"},
43: {"close", "int", FUNC, "nulldev", "nodev"},
44: {"read", "int", FUNC, "nodev"},
45: {"write", "int", FUNC, "nodev"},
46: {"ioctl", "int", FUNC, "nodev"},
47: {"reset", "int", FUNC, "nulldev"},
48: {"", NULL, NULL, "NULL"},
49: {NULL}
50: };
51: struct routine stream_routines[] = {
52: {"", NULL, NULL, "nodev"},
53: {"", NULL, NULL, "nodev"},
54: {"", NULL, NULL, "nodev"},
55: {"", NULL, NULL, "nodev"},
56: {"", NULL, NULL, "nodev"},
57: {"reset", "int", FUNC, "nulldev"},
58: {"info", "struct streamtab", POINTER, "NULL"},
59: {NULL}
60: };
61: struct routine fs_routines[] = {
62: {"put", "int", FUNC, "0"},
63: {"get", "struct inode *", FUNC, "0"},
64: {"free", "int", FUNC, "0"},
65: {"updat", "int", FUNC, "0"},
66: {"read", "int", FUNC, "0"},
67: {"write", "int", FUNC, "0"},
68: {"trunc", "int", FUNC, "0"},
69: {"stat", "int", FUNC, "0"},
70: {"nami", "int", FUNC, "0"},
71: {"mount", "int", FUNC, "0"},
72: {"ioctl", "int", FUNC, "0"},
73: {NULL}
74: };
75: struct routine ld_routines[] = {
76: {"info", "struct streamtab", POINTER, "NULL"},
77: {NULL}
78: };
79:
80: /*
81: * dev_lookup
82: * look up a device name
83: */
84:
85: struct dev_list *dev_lookup(type, num)
86: register int type, num;
87: {
88: register struct dev_list *devp;
89:
90: for (devp = devtab ; devp != NULL; devp = devp->dev_next)
91: {
92: if (devp->dev_type == type && devp->dev_num == num)
93: return devp;
94: }
95: return NULL;
96: }
97:
98: /*
99: * new_dent
100: * Make a new device list entry
101: */
102:
103: struct dev_list *new_dent()
104: {
105: register struct dev_list *devp;
106:
107: devp = (struct dev_list *) malloc(sizeof *devp);
108: devp->dev_next = NULL;
109: if (dcur == NULL)
110: dcur = devtab = devp;
111: else
112: dcur->dev_next = devp;
113: dcur = devp;
114: return devp;
115: }
116:
117:
118: /*
119: * devices:
120: * Read in the "devices" file.
121: * Store it in the devtab linked list
122: */
123:
124: read_devices()
125: {
126:
127: devtab = NULL;
128: read_devices_file(GLOBAL("devices"), TRUE);
129: read_devices_file(LOCAL("devices"), FALSE);
130: }
131:
132: static struct litlst *litlast;
133:
134: read_devices_file(filename, must_exist)
135: char *filename;
136: {
137: FILE *fp;
138: register struct dev_list *tp;
139: register struct litlst *litp;
140: register char *wd, *cond;
141: int standard, type, num;
142: char *index();
143:
144: fp = fopen(filename, "r");
145: if (fp == NULL) {
146: if (must_exist) {
147: perror(filename);
148: exit(1);
149: } else
150: return;
151: }
152: while((wd = get_word(fp)) != WEOF)
153: {
154: if (wd == NULL)
155: continue;
156: if (eq(wd, ":")) {
157: char line[100];
158: fgets(line, 100, fp);
159: if (!isspace(line[0]))
160: continue;
161: if (wd = index(line, '\n'))
162: *wd = '\0';
163: litp = (struct litlst *)malloc(sizeof(*litp) + strlen(line));
164: if (litp == NULL) {
165: fprintf(stderr, "Out of memory\n");
166: exit(10);
167: }
168: strcpy(litp->line = (char *)(litp + 1), line + 1);
169: litp->lit_next = NULL;
170: if (littab == NULL)
171: littab = litlast = litp;
172: else
173: litlast = litlast->lit_next = litp;
174: continue;
175: }
176: standard = FALSE;
177: cond = NULL;
178: if (eq(wd, "standard")) {
179: next_word(fp, wd);
180: standard = TRUE;
181: } else if (eq(wd, "if")) {
182: next_word(fp, wd);
183: cond = ns(wd);
184: next_word(fp, wd);
185: }
186: if (eq(wd, "stream-device"))
187: type = STREAM_DEVICE;
188: else if (eq(wd, "block-device"))
189: type = BLOCK_DEVICE;
190: else if (eq(wd, "device"))
191: type = CHAR_DEVICE;
192: else if (eq(wd, "line-discipline"))
193: type = LINE_DISC;
194: else if (eq(wd, "file-system"))
195: type = FILE_SYS;
196: else {
197: fprintf(stderr, "Unrecognized device type %d.\n", type);
198: exit(10);
199: }
200:
201: next_word(fp, wd);
202: if (wd == NULL) {
203: fprintf(stderr, "No device number.\n");
204: exit(10);
205: }
206: num = atoi(wd);
207:
208: next_word(fp, wd);
209: if (wd == NULL) {
210: fprintf(stderr, "Huh, no name for device.\n");
211: exit(10);
212: }
213: if ((tp = dev_lookup(type, num)) == NULL)
214: tp = new_dent();
215: tp->dev_name = ns(wd);
216: tp->dev_type = type;
217: tp->dev_num = num;
218: tp->dev_standard = standard;
219: tp->dev_if = cond;
220: if (num > max_num[type])
221: max_num[type] = num;
222:
223: next_word(fp, wd);
224: if (wd == NULL) {
225: tp->dev_mask = 0L;
226: continue;
227: }
228: tp->dev_prefix = ns(wd);
229:
230: switch (type) {
231: case STREAM_DEVICE:
232: device_params(fp, tp, stream_routines);
233: break;
234: case BLOCK_DEVICE:
235: device_params(fp, tp, block_routines);
236: break;
237: case CHAR_DEVICE:
238: device_params(fp, tp, char_routines);
239: break;
240: case LINE_DISC:
241: device_params(fp, tp, ld_routines);
242: break;
243: case FILE_SYS:
244: device_params(fp, tp, fs_routines);
245: break;
246: }
247: }
248: fclose(fp);
249: }
250:
251:
252: /*
253: * device_params:
254: * read in a list of device parameters
255: *
256: */
257:
258: device_params(fp, dp, routines)
259: FILE *fp;
260: struct dev_list *dp;
261: struct routine *routines;
262: {
263: register struct routine *rp;
264: char *wd;
265:
266: dp->dev_mask = 0L;
267: for (;;) {
268: next_word(fp, wd);
269: if (wd == NULL)
270: break;
271: for (rp = routines; rp->rt_name != NULL; ++rp)
272: if (eq(wd, rp->rt_name))
273: break;
274: if (rp->rt_name == NULL) {
275: fprintf(stderr, "Unknown entry point name '%s' for device %s.\n",
276: wd, dp->dev_name);
277: exit(10);
278: }
279: dp->dev_mask |= bit(rp - routines);
280: }
281: }
282:
283:
284: conf()
285: {
286: FILE *fp;
287: register struct dev_list *dp;
288:
289: read_devices();
290:
291: fp = fopen(LOCAL("conf.c"), "w");
292: if (fp == NULL) {
293: perror(LOCAL("conf.c"));
294: exit(1);
295: }
296: fprintf(fp, "\t/* conf.c built automatically by config */\n\n");
297: fprintf(fp, "#include \"../h/param.h\"\n");
298: fprintf(fp, "#include \"../h/systm.h\"\n");
299: fprintf(fp, "#include \"../h/conf.h\"\n");
300: fprintf(fp, "#include \"../h/inode.h\"\n");
301: fprintf(fp, "#include \"../h/stream.h\"\n");
302: fprintf(fp, "#include \"../h/buf.h\"\n");
303: fprintf(fp, "int nulldev(), nodev();\n\n");
304:
305: for (dp = devtab; dp; dp = dp->dev_next) {
306: if (dp->dev_mask == 0L)
307: continue;
308: switch (dp->dev_type) {
309: case CHAR_DEVICE:
310: do_declare(fp, dp, char_routines);
311: break;
312: case BLOCK_DEVICE:
313: do_declare(fp, dp, block_routines);
314: break;
315: case STREAM_DEVICE:
316: do_declare(fp, dp, stream_routines);
317: break;
318: case LINE_DISC:
319: do_declare(fp, dp, ld_routines);
320: break;
321: case FILE_SYS:
322: decl_list(fp, dp, fs_routines);
323: break;
324: }
325: putc('\n', fp);
326: }
327:
328: fprintf(fp, "struct bdevsw bdevsw[] = {\n");
329: do_table(fp, block_routines, BLOCK_DEVICE, NULL, NULL);
330: fprintf(fp, " 0\n};\n\n");
331:
332: fprintf(fp, "struct cdevsw cdevsw[] = {\n");
333: do_table(fp, char_routines, CHAR_DEVICE, stream_routines, STREAM_DEVICE);
334: fprintf(fp, " 0\n};\n");
335: fprintf(fp, "int nchrdev = sizeof(cdevsw) / sizeof(cdevsw[0]) - 1;\n\n");
336:
337: fprintf(fp, "struct fstypsw fstypsw[] = {\n");
338: do_table(fp, fs_routines, FILE_SYS, NULL, NULL);
339: fprintf(fp, "};\n");
340: fprintf(fp, "int nfstyp = sizeof(fstypsw) / sizeof(fstypsw[0]);\n\n");
341:
342: fprintf(fp, "struct streamtab *streamtab[] = {\n");
343: do_table(fp, ld_routines, LINE_DISC, NULL, NULL);
344: fprintf(fp, "};\n");
345: fprintf(fp, "int nstream = sizeof(streamtab) / sizeof(streamtab[0]);\n\n");
346:
347: while (littab != NULL) {
348: fprintf(fp, "%s\n", littab->line);
349: littab = littab->lit_next;
350: }
351:
352: fclose(fp);
353: }
354:
355:
356: char *toentry(dp, routine)
357: struct dev_list *dp;
358: char *routine;
359: {
360: static char entry[40];
361:
362: sprintf(entry, "%s%s", dp->dev_prefix, routine);
363: return entry;
364: }
365:
366: do_declare(fp, dp, routines)
367: FILE *fp;
368: struct dev_list *dp;
369: struct routine *routines;
370: {
371: char *tomacro();
372:
373: if (dp->dev_if)
374: fprintf(fp, "#if %s\n", dp->dev_if);
375: else if (!dp->dev_standard) {
376: include(fp, dp->dev_name);
377: fprintf(fp, "#if %s > 0\n", tomacro(dp->dev_name));
378: }
379:
380: decl_list(fp, dp, routines);
381:
382: if (!dp->dev_standard) {
383: fprintf(fp, "#else\n");
384: define_list(fp, dp, routines);
385: fprintf(fp, "#endif\n");
386: }
387: }
388:
389: decl_list(fp, dp, routines)
390: FILE *fp;
391: struct dev_list *dp;
392: struct routine *routines;
393: {
394: register struct routine *rp, *rp2;
395: register long mask;
396: register int ndone;
397: char *entry;
398:
399: for (rp = routines, mask = dp->dev_mask; rp->rt_name != NULL; ++rp) {
400: for (rp2 = rp, ndone = 0; rp2->rt_name != NULL; ++rp2) {
401: if (rp2->rt_type == NULL || (mask & bit(rp2 - routines)) == 0)
402: continue;
403: entry = toentry(dp, rp2->rt_name);
404: if (eq(rp2->rt_type, rp->rt_type) && !declared(entry, FALSE)) {
405: mask &= ~bit(rp2 - routines);
406: if (++ndone == 1)
407: fprintf(fp, " extern %s ", rp->rt_type);
408: else
409: putc(',', fp);
410: fprintf(fp, "%s%s", entry, rp2->rt_class == FUNC ? "()" : "");
411: }
412: }
413: if (ndone > 0)
414: fprintf(fp, ";\n");
415: }
416: }
417:
418:
419: define_list(fp, dp, routines)
420: FILE *fp;
421: struct dev_list *dp;
422: struct routine *routines;
423: {
424: register struct routine *rp;
425: char *entry;
426:
427: for (rp = routines; rp->rt_name != NULL; ++rp) {
428: if (rp->rt_type != NULL && (dp->dev_mask & bit(rp - routines))) {
429: entry = toentry(dp, rp->rt_name);
430: if (!declared(entry, FALSE)) {
431: fprintf(fp, "# define %s\t", entry);
432: if (rp->rt_class == POINTER)
433: fprintf(fp, "*(%s *)", rp->rt_type);
434: fprintf(fp, "%s\n", rp->rt_empty? rp->rt_empty
435: : rp->rt_default);
436: }
437: }
438: }
439: }
440:
441: static struct idlst *decs;
442:
443: declared(str, declare)
444: char *str;
445: {
446: register struct idlst *dec;
447:
448: for (dec = decs; dec; dec = dec->id_next)
449: if (eq(dec->id, str))
450: return TRUE;
451:
452: if (declare) {
453: if ((dec = (struct idlst *)malloc(sizeof(*dec))) == NULL) {
454: fprintf(stderr, "Out of memory\n");
455: exit(10);
456: }
457: dec->id = str;
458: dec->id_next = decs;
459: decs = dec;
460: }
461:
462: return FALSE;
463: }
464:
465: do_table(fp, rt1, devtype1, rt2, devtype2)
466: FILE *fp;
467: struct routine *rt1, *rt2;
468: {
469: register struct dev_list *dp;
470: register int n, maxn;
471:
472: maxn = rt2 ? max(max_num[devtype1],max_num[devtype2]) : max_num[devtype1];
473: for (n = 0; n <= maxn; ++n) {
474: for (dp = devtab; dp; dp = dp->dev_next) {
475: if (dp->dev_num != n)
476: continue;
477: if (dp->dev_type == devtype1) {
478: fprintf(fp, "/*%s*/\t", dp->dev_name);
479: filled_list(fp, dp, dp->dev_mask, rt1);
480: fprintf(fp, "\t/* %d */\n", n);
481: break;
482: } else if (dp->dev_type == devtype2) {
483: fprintf(fp, "/*%s*/\t", dp->dev_name);
484: filled_list(fp, dp, dp->dev_mask, rt2);
485: fprintf(fp, "\t/* %d */\n", n);
486: break;
487: }
488: }
489: if (dp == NULL) {
490: fprintf(fp, "/*xx*/\t");
491: filled_list(fp, NULL, 0L, rt1);
492: fprintf(fp, "\t/* %d */\n", n);
493: }
494: }
495: }
496:
497: filled_list(fp, dp, mask, routines)
498: FILE *fp;
499: struct dev_list *dp;
500: long mask;
501: struct routine *routines;
502: {
503: register struct routine *rp;
504:
505: for (rp = routines; rp->rt_name != NULL; ++rp) {
506: if (mask & bit(rp - routines)) {
507: if (rp->rt_class == POINTER)
508: putc('&', fp);
509: if (rp->rt_class == LITERAL)
510: fprintf(fp, "%s, ", rp->rt_name);
511: else
512: fprintf(fp, "%s, ", toentry(dp, rp->rt_name));
513: } else if (dp == NULL && rp->rt_empty)
514: fprintf(fp, "%s, ", rp->rt_empty);
515: else
516: fprintf(fp, "%s, ", rp->rt_default);
517: }
518: }
519:
520: static struct idlst *incs;
521:
522: include(fp, name)
523: FILE *fp;
524: char *name;
525: {
526: register struct idlst *inc;
527:
528: for (inc = incs; inc; inc = inc->id_next)
529: if (eq(inc->id, name))
530: return;
531:
532: fprintf(fp, "#include \"%s.h\"\n", name);
533: if ((inc = (struct idlst *)malloc(sizeof(*inc))) == NULL) {
534: fprintf(stderr, "Out of memory\n");
535: exit(10);
536: }
537: inc->id = name;
538: inc->id_next = incs;
539: incs = inc;
540: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.