|
|
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.