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