|
|
1.1 ! root 1: %token DEFBRK COLON OCTAL INTEGER IDENT CSR IVEC OVEC IINT OINT ! 2: INIT OPEN CLOSE READ WRITE SEEK CNTL IS ON GETC PUTC ! 3: %{ ! 4: #include <stdio.h> ! 5: ! 6: #define NIL (dvptr)0 ! 7: ! 8: #define CONFIGC "../sys/conf.c" /* name of .c output */ ! 9: #define CONFIGH "../h/conf.h" /* name of .h output */ ! 10: #define DISPCONF "../h/dispconf.h" /* name of dispatcher .h*/ ! 11: #define IODISP "../h/iodisp.h" /* name of dispat loc .h*/ ! 12: #define CONFHREF "<conf.h>" /* how conf.h referenced*/ ! 13: #define CONFIGIN "Configuration" /* name of input file */ ! 14: ! 15: FILE *confc; ! 16: FILE *confh; ! 17: FILE *dispconf; ! 18: FILE *iodisp; ! 19: ! 20: char *dbstr; ! 21: extern char *malloc(); ! 22: int ndevs = 0; ! 23: int currname = -1; ! 24: int currtname = -1; ! 25: int currdname = -1; ! 26: int brkcount = 0; ! 27: ! 28: struct syment { /* symbol table */ ! 29: char *symname; ! 30: int symoccurs; ! 31: } symtab[250]; ! 32: ! 33: int nsym = 0; ! 34: int lookup(); ! 35: int linectr = 1; ! 36: char *doing = "device type declaration"; ! 37: char *s; ! 38: struct dvtype { ! 39: char *dvname; /* device name (not used in types)*/ ! 40: char *dvtname; /* type name */ ! 41: int dvtnum; /* symbol table index of type */ ! 42: char *dvdevice; /* device name */ ! 43: int dvcsr; /* Control Status Register addr */ ! 44: int dvivec; /* input interrupt vector */ ! 45: int dvovec; /* Output interrupt vector */ ! 46: char dviint[20]; /* input interrupt routine */ ! 47: char dvoint[20]; /* output interrupt routine */ ! 48: char dvinit[20]; /* init routine name */ ! 49: char dvopen[20]; /* open routine name */ ! 50: char dvclose[20]; /* close routine name */ ! 51: char dvread[20]; /* read routine name */ ! 52: char dvwrite[20]; /* write routine name */ ! 53: char dvcntl[20]; /* control routine name */ ! 54: char dvseek[20]; /* seek routine name */ ! 55: char dvgetc[20]; /* getc routine name */ ! 56: char dvputc[20]; /* putc routine name */ ! 57: int dvminor; /* device number 0,1,... */ ! 58: struct dvtype *dvnext; /* next node on the list */ ! 59: }; ! 60: typedef struct dvtype *dvptr; ! 61: dvptr ftypes = NIL; /* linked list of device types */ ! 62: dvptr devs = NIL; /* linked list of device decls. */ ! 63: dvptr lastdv = NIL; ! 64: dvptr currtype = NIL; ! 65: ! 66: char *ftout[] = ! 67: {"#ifndef\tASM\n", ! 68: "struct\tdevsw\t{\t\t\t/* device table entry */\n", ! 69: "\tint\tdvnum;\n", ! 70: "\tchar\t*dvname;\n", ! 71: "\tint\t(*dvinit)();\n", ! 72: "\tint\t(*dvopen)();\n", ! 73: "\tint\t(*dvclose)();\n", ! 74: "\tint\t(*dvread)();\n", ! 75: "\tint\t(*dvwrite)();\n", ! 76: "\tint\t(*dvseek)();\n", ! 77: "\tint\t(*dvgetc)();\n", ! 78: "\tint\t(*dvputc)();\n", ! 79: "\tint\t(*dvcntl)();\n", ! 80: "\tint\tdvcsr;\n", ! 81: "\tint\tdvivec;\n", ! 82: "\tint\tdvovec;\n", ! 83: "\tint\t(*dviint)();\n", ! 84: "\tint\t(*dvoint)();\n", ! 85: "\tchar\t*dvioblk;\n", ! 86: "\tint\tdvminor;\n", ! 87: "\t};\n\n", ! 88: "extern\tstruct\tdevsw devtab[];", ! 89: "\t\t/* one entry per device */\n", ! 90: "#endif\n\n", ! 91: NULL}; ! 92: %} ! 93: %% ! 94: config.input : devicetypes devicedescriptors ! 95: ; ! 96: devicetypes : ftypes DEFBRK ! 97: {doing = "device definitions";} ! 98: ; ! 99: ftypes : /**/ ! 100: | ftypes ftype ! 101: ; ! 102: ftype : tname device.list ! 103: ; ! 104: device.list : devheader attribute.list ! 105: | device.list devheader attribute.list ! 106: ; ! 107: devheader : ON id ! 108: {mktype($2);} ! 109: ; ! 110: tname : id COLON ! 111: {$$ = currtname = cktname($1);} ! 112: ; ! 113: id : IDENT ! 114: {$$ = currname = ! 115: lookup(yytext,yyleng); ! 116: } ! 117: ; ! 118: attribute.list : /**/ ! 119: | attribute.list attribute ! 120: ; ! 121: attribute : CSR number ! 122: {newattr(CSR,$2);} ! 123: | IVEC number ! 124: {newattr(IVEC,$2);} ! 125: | OVEC number ! 126: {newattr(OVEC,$2);} ! 127: | IINT id ! 128: {newattr(IINT,$2);} ! 129: | OINT id ! 130: {newattr(OINT,$2);} ! 131: | OPEN id ! 132: {newattr(OPEN,$2);} ! 133: | CLOSE id ! 134: {newattr(CLOSE,$2);} ! 135: | INIT id ! 136: {newattr(INIT,$2);} ! 137: | GETC id ! 138: {newattr(GETC,$2);} ! 139: | PUTC id ! 140: {newattr(PUTC,$2);} ! 141: | READ id ! 142: {newattr(READ,$2);} ! 143: | WRITE id ! 144: {newattr(WRITE,$2);} ! 145: | SEEK id ! 146: {newattr(SEEK,$2);} ! 147: | CNTL id ! 148: {newattr(CNTL,$2);} ! 149: ; ! 150: number : INTEGER ! 151: /* Assume all input is octal */ ! 152: /* for now; distinction is */ ! 153: /* made in lexical routines */ ! 154: /* just in case of change */ ! 155: ! 156: {$$ = otoi(yytext,yyleng);} ! 157: | OCTAL ! 158: {$$ = otoi(yytext,yyleng);} ! 159: ; ! 160: devicedescriptors : /**/ ! 161: | devicedescriptors descriptor ! 162: ; ! 163: descriptor : fspec attribute.list ! 164: ; ! 165: fspec : dname IS id optional.on ! 166: {mkdev($1,$3,$4);} ! 167: ; ! 168: dname : id ! 169: {$$ = currdname = ckdname($1);} ! 170: ; ! 171: optional.on : /**/ ! 172: {$$ = 0;} ! 173: | ON id ! 174: {$$ = $2;} ! 175: ; ! 176: %% ! 177: #include "lex.yy.c" ! 178: main(argc, argv) ! 179: int argc; ! 180: char *argv[]; ! 181: { ! 182: int n, i, j, l, fcount; ! 183: dvptr s; ! 184: int verbose = 0; ! 185: char *p; ! 186: char c; ! 187: ! 188: if (argc>1 && (strcmp("-v",argv[1])==0)) { ! 189: argc--; ! 190: argv++; ! 191: verbose++; ! 192: } ! 193: if (argc>2) { ! 194: fprintf(stderr,"use: config [-v] [file]\n"); ! 195: exit(1); ! 196: } ! 197: if (verbose) ! 198: printf("Opening input file...\n"); ! 199: if (argc == 2) { ! 200: if (freopen(argv[1], "r", stdin) == NULL) { ! 201: fprintf(stderr,"Can't open %s\n",argv[1]); ! 202: exit(1); ! 203: } ! 204: } else { /* try to open Configuration file */ ! 205: if (freopen(CONFIGIN, "r", stdin) == NULL) { ! 206: fprintf(stderr,"Can't open %s\n", CONFIGIN); ! 207: exit(1); ! 208: } ! 209: } ! 210: ! 211: /* Parse the Configuration file */ ! 212: ! 213: if (verbose) ! 214: printf("Parsing configuration specs...\n"); ! 215: if ((n=yyparse()) != 0) ! 216: exit(n); ! 217: ! 218: /* write config.h and config.c */ ! 219: ! 220: if (verbose) ! 221: printf("Opening output files...\n"); ! 222: if ( (confc=fopen(CONFIGC,"w") ) == NULL) { ! 223: fprintf(stderr, "Can't write on %s\n", CONFIGC); ! 224: exit(1); ! 225: } ! 226: ! 227: if ( (confh=fopen(CONFIGH,"w") ) == NULL) { ! 228: fprintf(stderr, "Can't write on %s\n", CONFIGH); ! 229: exit(1); ! 230: } ! 231: if ( (dispconf=fopen(DISPCONF,"w") ) == NULL) { ! 232: fprintf(stderr, "Can't write on %s\n",DISPCONF); ! 233: exit(1); ! 234: } ! 235: if ( (iodisp=fopen(IODISP,"w") ) == NULL) { ! 236: fprintf(stderr, "Can't write on %s\n",IODISP); ! 237: exit(1); ! 238: } ! 239: fprintf(confh, ! 240: "/* conf.h (GENERATED FILE; DO NOT EDIT) */\n"); ! 241: fprintf(confc, ! 242: "/* conf.c (GENERATED FILE; DO NOT EDIT) */\n"); ! 243: fprintf(dispconf, ! 244: "/* dispconf.h (GENERATED FILE; DO NOT EDIT) */\n"); ! 245: fprintf(iodisp, ! 246: "/* iodisp.h (GENERATED FILE; DO NOT EDIT) */\n"); ! 247: fprintf(confc, "\n#include %s\n", CONFHREF); ! 248: fprintf(confh, "\n#define\tNULLPTR\t(char *)0\n"); ! 249: ! 250: ! 251: if (verbose) ! 252: printf("Writing output...\n"); ! 253: fprintf(confh,"\n/* Device table declarations */\n"); ! 254: for (i=0 ; (p=ftout[i])!=NULL ; i++) ! 255: fprintf(confh, "%s", p); ! 256: fprintf(dispconf,"\n/* vector-to points for each device */\n\n"); ! 257: fprintf(iodisp,"\n/* i/o dispatch vector-to location externs */\n\n"); ! 258: /* write device declarations and definitions; count type refs. */ ! 259: ! 260: fprintf(confh, "\n/* Device name definitions */\n\n"); ! 261: for (i=0,s=devs; s!=NIL ; s=s->dvnext,i++) { ! 262: fprintf(confh, "#define\t%-12s%d\t\t\t/* type %-8s */\n", ! 263: s->dvname, i, s->dvtname); ! 264: s->dvminor = symtab[s->dvtnum].symoccurs++; ! 265: } ! 266: ! 267: /* write count of device types */ ! 268: ! 269: fprintf(confh,"\n/* Control block sizes */\n\n"); ! 270: for (i=0 ; i<nsym ; i++) ! 271: if (symtab[i].symoccurs > 0) { ! 272: fprintf(confh, "#define\tN%s\t%d\n", ! 273: symtab[i].symname, symtab[i].symoccurs); ! 274: } ! 275: if (ndevs > 0) ! 276: fprintf(confh, "\n#define\tNDEVS\t%d\n\n", ndevs); ! 277: ! 278: /* empty symbol table, collect, and write names of all I/O routines */ ! 279: ! 280: nsym = 0; ! 281: for (s=devs; s!=NIL ; s=s->dvnext) { ! 282: lookup(s->dvinit,strlen(s->dvinit)); ! 283: lookup(s->dvopen,strlen(s->dvopen)); ! 284: lookup(s->dvclose,strlen(s->dvclose)); ! 285: lookup(s->dvread,strlen(s->dvread)); ! 286: lookup(s->dvwrite,strlen(s->dvwrite)); ! 287: lookup(s->dvseek,strlen(s->dvseek)); ! 288: lookup(s->dvcntl,strlen(s->dvcntl)); ! 289: lookup(s->dvgetc,strlen(s->dvgetc)); ! 290: lookup(s->dvputc,strlen(s->dvputc)); ! 291: lookup(s->dviint,strlen(s->dviint)); ! 292: lookup(s->dvoint,strlen(s->dvoint)); ! 293: ! 294: } ! 295: fprintf(confh, ! 296: "/* Declarations of I/O routines referenced */\n\n"); ! 297: fprintf(confh, "#ifndef\tASM\n"); ! 298: for (i=0 ; i<nsym ; i++) ! 299: fprintf(confh, "extern\tint\t%s();\n", symtab[i].symname); ! 300: fprintf(confh, "#endif\n"); ! 301: ! 302: ! 303: /* produce devtab (giant I/O switch table) */ ! 304: ! 305: fprintf(confc, "\n/* device independent I/O switch */\n\n"); ! 306: if (ndevs > 0) { ! 307: fprintf(confc, "struct\tdevsw\tdevtab[NDEVS] = {\n"); ! 308: fprintf(confc, "\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", ! 309: "/* Format of entries is:", ! 310: "device-number, device-name,", ! 311: "init, open, close,", ! 312: "read, write, seek,", ! 313: "getc, putc, cntl,", ! 314: "device-csr-address, input-vector, output-vector,", ! 315: "iint-handler, oint-handler, control-block, minor-device,", ! 316: "*/"); ! 317: } ! 318: for (fcount=0,s=devs ; s!=NIL ; s=s->dvnext,fcount++) { ! 319: fprintf(confc, "\n/* %s is %s */\n\n",s->dvname,s->dvtname); ! 320: fprintf(confc, "%d, \"%s\",\n", fcount, s->dvname); ! 321: fprintf(confc, "%s, %s, %s,\n", ! 322: s->dvinit, s->dvopen, s->dvclose); ! 323: fprintf(confc, "%s, %s, %s,\n", ! 324: s->dvread, s->dvwrite, s->dvseek); ! 325: fprintf(confc, "%s, %s, %s,\n", ! 326: s->dvgetc, s->dvputc, s->dvcntl); ! 327: fprintf(confc, "0%06o, 0%03o, 0%03o,\n", ! 328: s->dvcsr, s->dvivec, s->dvovec); ! 329: fprintf(confc, "%s, %s, NULLPTR, %d", ! 330: s->dviint, s->dvoint, s->dvminor); ! 331: if ( s->dvnext != NIL ) ! 332: fprintf(confc, ",\n"); ! 333: else ! 334: fprintf(confc, "\n\t};"); ! 335: } ! 336: for (i=0; i<ndevs; i++) { ! 337: fprintf(dispconf,"\t.globl\t_devveci%-1d\n",i); ! 338: fprintf(dispconf,"\t.globl\t_devveco%-1d\n",i); ! 339: fprintf(dispconf,"\t.align\t2\n"); ! 340: fprintf(dispconf,"_devveci%-1d:\n",i); ! 341: fprintf(dispconf,"\tmtpr\t$DISABLE, $IPL\n"); ! 342: fprintf(dispconf,"\tbsbw\tioint\n"); ! 343: fprintf(dispconf,"\t.align\t2\n"); ! 344: fprintf(dispconf,"_devveco%-1d:\n",i); ! 345: fprintf(dispconf,"\tmtpr\t$DISABLE, $IPL\n"); ! 346: fprintf(dispconf,"\tbsbw\tioint\n\n",i); ! 347: fprintf(iodisp, "extern\tint\tdevveci%-1d();\n",i); ! 348: fprintf(iodisp, "extern\tint\tdevveco%-1d();\n",i); ! 349: } ! 350: ! 351: /* Copy definitions to output */ ! 352: ! 353: if (brkcount == 2 && verbose) ! 354: printf("Copying definitions to %s...\n", CONFIGH); ! 355: if (brkcount == 2 ) ! 356: while ( (c=input()) != 0) /* lex input routine */ ! 357: putc(c, confh); ! 358: ! 359: /* guarantee conf.c written later than conf.c for make */ ! 360: ! 361: fclose(confh); ! 362: fprintf(confc, "\n"); ! 363: fclose(confc); ! 364: fclose(dispconf); ! 365: fclose(iodisp); ! 366: ! 367: /* finish up and write report for user if requested */ ! 368: ! 369: if (verbose) { ! 370: printf("\nConfiguration complete. Number of devs=%d:\n\n",ndevs); ! 371: for (s=devs; s!=NIL ; s=s->dvnext) ! 372: printf( ! 373: "Device %s (on %s) csr=0%-7o, ivec=0%-3o, ovec=0%-3o, minor=%d\n", ! 374: s->dvname, s->dvdevice, s->dvcsr, s->dvivec, s->dvovec, ! 375: s->dvminor); ! 376: } ! 377: ! 378: ! 379: } ! 380: ! 381: ! 382: yyerror(s) ! 383: char *s; ! 384: { ! 385: fprintf(stderr,"Syntax error in %s on line %d\n", ! 386: doing,linectr); ! 387: } ! 388: ! 389: ! 390: /* lookup -- lookup a name in the symbol table; return position */ ! 391: ! 392: lookup(str,len) ! 393: char *str; ! 394: int len; ! 395: { ! 396: int i; ! 397: char *s; ! 398: ! 399: if (len >= 20) { ! 400: len = 19; ! 401: fprintf(stderr,"warning: name %s truncated\n",str); ! 402: } ! 403: s = malloc(len+1); ! 404: strncpy(s,str,len); ! 405: s[len] = '\000'; ! 406: for (i=0 ; i<nsym ; i++) ! 407: if (strcmp(s,symtab[i].symname) == 0){ ! 408: return(i); ! 409: } ! 410: symtab[nsym].symname = s; ! 411: symtab[nsym].symoccurs = 0; ! 412: return(nsym++); ! 413: } ! 414: ! 415: atoi(str,len) ! 416: char *str; ! 417: int len; ! 418: { ! 419: int i; ! 420: char c; ! 421: ! 422: for (i=0; len > 0 ; len--) { ! 423: c = *str++; ! 424: i = 10*i + (c - '0'); ! 425: } ! 426: } ! 427: otoi(str,len) ! 428: char *str; ! 429: int len; ! 430: { ! 431: int i; ! 432: char c; ! 433: ! 434: for (i=0; len > 0 ; len--) { ! 435: c = *str++; ! 436: if (c > '7') ! 437: fprintf(stderr,"invalid octal digit on line %d\n", ! 438: linectr); ! 439: else ! 440: i = 8*i + (c - '0'); ! 441: } ! 442: } ! 443: ! 444: /* newattr -- add a new attribute spec to current type/device description */ ! 445: ! 446: newattr(tok,val) ! 447: int tok; /* token type (attribute type) */ ! 448: int val; /* symbol number of value */ ! 449: { ! 450: char *c; ! 451: dvptr s; ! 452: ! 453: if (devs == NIL) /* doing types */ ! 454: s = currtype; ! 455: else ! 456: s = lastdv; ! 457: if (val>=0 && val<nsym) { ! 458: c = symtab[val].symname; ! 459: if (strlen(c) > 20 ) { ! 460: fprintf(stderr,"Internal overflow\n"); ! 461: exit(1); ! 462: } ! 463: } else ! 464: c = NULL; ! 465: ! 466: switch (tok) { ! 467: ! 468: case CSR: s->dvcsr = val; ! 469: break; ! 470: case IVEC: s->dvivec = val; ! 471: break; ! 472: case OVEC: s->dvovec = val; ! 473: break; ! 474: case IINT: strcpy(s->dviint,c); ! 475: break; ! 476: case OINT: strcpy(s->dvoint,c); ! 477: break; ! 478: case READ: strcpy(s->dvread,c); ! 479: break; ! 480: case WRITE: strcpy(s->dvwrite,c); ! 481: break; ! 482: case GETC: strcpy(s->dvgetc,c); ! 483: break; ! 484: case PUTC: strcpy(s->dvputc,c); ! 485: break; ! 486: case OPEN: strcpy(s->dvopen,c); ! 487: break; ! 488: case CLOSE: strcpy(s->dvclose,c); ! 489: break; ! 490: case INIT: strcpy(s->dvinit,c); ! 491: break; ! 492: case SEEK: strcpy(s->dvseek,c); ! 493: break; ! 494: case CNTL: strcpy(s->dvcntl,c); ! 495: break; ! 496: default: fprintf(stderr, "Internal error 1\n"); ! 497: } ! 498: } ! 499: ! 500: /* cktname -- check type name for duplicates */ ! 501: ! 502: cktname(symid) ! 503: int symid; ! 504: { ! 505: dvptr s; ! 506: extern dvptr ftypes; ! 507: char *name; ! 508: ! 509: name = symtab[symid].symname; ! 510: for (s=ftypes; s!=NIL ; s=s->dvnext) { ! 511: if (s->dvtname == name) { ! 512: fprintf(stderr,"Duplicate type name %s on line %d\n", ! 513: name,linectr); ! 514: exit(1); ! 515: } ! 516: } ! 517: return(symid); ! 518: } ! 519: ! 520: /* mktype -- make a node in the type list and initialize to defaults */ ! 521: ! 522: mktype(deviceid) ! 523: int deviceid; ! 524: { ! 525: dvptr s,p; ! 526: char *tn,*dn; ! 527: ! 528: p = NIL; ! 529: tn = symtab[currtname].symname; ! 530: dn = symtab[deviceid].symname; ! 531: for (s = ftypes; s!=NIL ; s=s->dvnext) { ! 532: if (s->dvtname == tn && s->dvdevice==dn) { ! 533: fprintf(stderr, ! 534: "Duplicate device %s for type %s on line %d\n", ! 535: dn, tn, linectr); ! 536: exit(1); ! 537: } ! 538: p = s; ! 539: } ! 540: currtype = s = (dvptr) malloc( sizeof(struct dvtype)); ! 541: if (ftypes != NIL) { ! 542: p->dvnext = s; ! 543: } ! 544: else { ! 545: ftypes = s; ! 546: } ! 547: initattr(s, currtname, deviceid); ! 548: } ! 549: ! 550: /* initialize attributes in a type declaration node to typename... */ ! 551: ! 552: initattr(fstr, tnum, deviceid) ! 553: dvptr fstr; ! 554: int tnum; ! 555: int deviceid; ! 556: { ! 557: char *typnam; ! 558: ! 559: typnam = symtab[tnum].symname; ! 560: fstr->dvname = NULL; ! 561: fstr->dvtname = typnam; ! 562: fstr->dvtnum = tnum; ! 563: fstr->dvdevice = symtab[deviceid].symname; ! 564: fstr->dvcsr = 0; ! 565: fstr->dvivec = 0; ! 566: fstr->dvovec = 0; ! 567: strcpy(fstr->dviint,typnam); ! 568: strcat(fstr->dviint,"iin"); ! 569: strcpy(fstr->dvoint,typnam); ! 570: strcat(fstr->dvoint,"oin"); ! 571: strcpy(fstr->dvinit,typnam); ! 572: strcat(fstr->dvinit,"init"); ! 573: strcpy(fstr->dvopen,typnam); ! 574: strcat(fstr->dvopen,"open"); ! 575: strcpy(fstr->dvclose,typnam); ! 576: strcat(fstr->dvclose,"close"); ! 577: strcpy(fstr->dvread,typnam); ! 578: strcat(fstr->dvread,"read"); ! 579: strcpy(fstr->dvwrite,typnam); ! 580: strcat(fstr->dvwrite,"write"); ! 581: strcpy(fstr->dvcntl,typnam); ! 582: strcat(fstr->dvcntl,"control"); ! 583: strcpy(fstr->dvseek,typnam); ! 584: strcat(fstr->dvseek,"seek"); ! 585: strcpy(fstr->dvgetc,typnam); ! 586: strcat(fstr->dvgetc,"getc"); ! 587: strcpy(fstr->dvputc,typnam); ! 588: strcat(fstr->dvputc,"putc"); ! 589: fstr->dvminor = 0; ! 590: } ! 591: ! 592: /* mkdev -- make a node on the device list */ ! 593: ! 594: mkdev(nameid, typid, deviceid) ! 595: int nameid, typid, deviceid; ! 596: { ! 597: dvptr s; ! 598: char *devn,*tn,*dn; ! 599: int found; ! 600: ! 601: s = (dvptr) malloc(sizeof(struct dvtype)); ! 602: s->dvnext = NIL; ! 603: if (devs == NIL) { ! 604: devs = s; ! 605: lastdv = s; ! 606: } else { ! 607: lastdv->dvnext = s; ! 608: lastdv = s; ! 609: } ! 610: ndevs++; ! 611: tn = symtab[typid].symname; ! 612: devn = symtab[nameid].symname; ! 613: if (deviceid >= 0) ! 614: dn = symtab[deviceid].symname; ! 615: else ! 616: dn = NULL; ! 617: found = 0; ! 618: for (s=ftypes ; s != NULL ; s=s->dvnext) ! 619: if (s->dvtname == tn && (dn==NULL || s->dvdevice==dn)) { ! 620: strdup(lastdv,s,sizeof(struct dvtype)); ! 621: found=1; ! 622: break; ! 623: } ! 624: if (found==0) { ! 625: fprintf(stderr, ! 626: "Bad type or device name in declaration of %s on line %d\n", ! 627: devn, linectr); ! 628: exit(1); ! 629: } ! 630: lastdv->dvnext = NIL; ! 631: lastdv->dvname = devn; ! 632: } ! 633: ! 634: ! 635: /* chdname -- check for duplicate device name */ ! 636: ! 637: ckdname(devid) ! 638: int devid; ! 639: { ! 640: dvptr s; ! 641: extern dvptr devs; ! 642: char *name; ! 643: ! 644: name = symtab[devid].symname; ! 645: for (s=devs; s!=NIL ; s=s->dvnext) { ! 646: if (s->dvname == name) { ! 647: fprintf(stderr,"Duplicate device name %s on line %d\n", ! 648: name,linectr); ! 649: exit(1); ! 650: } ! 651: } ! 652: return(devid); ! 653: } ! 654: ! 655: strdup(tostr,fromstr,len) ! 656: char *tostr, *fromstr; ! 657: int len; ! 658: { ! 659: for( ; len > 0 ; len--) ! 660: *tostr++ = *fromstr++; ! 661: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.