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