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