|
|
1.1 ! root 1: /* $Header: depend.c,v 1.14 86/05/15 09:01:04 lepreau Exp $ */ ! 2: ! 3: /* ! 4: * Author: Peter J. Nicklin ! 5: */ ! 6: #include <ctype.h> ! 7: #include <stdio.h> ! 8: #include "Mkmf.h" ! 9: #include "dlist.h" ! 10: #include "hash.h" ! 11: #include "macro.h" ! 12: #include "null.h" ! 13: #include "path.h" ! 14: #include "slist.h" ! 15: #include "system.h" ! 16: #include "yesno.h" ! 17: ! 18: #define USRINCLUDE "/usr/include/" ! 19: #define CURINCLUDE "./" ! 20: #define TOLOWER(c) (isupper(c) ? tolower(c) : (c)) ! 21: #define SKIPWHITESPACE(c, f) while ((c = getc(f))==' ' || c=='\t'); ungetc(c,f); ! 22: ! 23: /* ! 24: * Include file state ! 25: */ ! 26: #define NOTFOUND 0 /* not found anywhere */ ! 27: #define EXTERNAL 1 /* not found in current directory */ ! 28: #define INTERNAL 2 /* found in current directory */ ! 29: #define FROMRULE 3 /* derived from tranformation rule */ ! 30: ! 31: /* ! 32: * Include files are stored in hash tables by direct chaining (See ! 33: * p. 134 in `The C Programming Language' by Kernighan and Ritchie). ! 34: * Included include files are also added to a singly-linked list ! 35: * attached to the hash table entry for the include file. ! 36: */ ! 37: static HASH *C_INCLUDETABLE = NULL; /* C include file hash table */ ! 38: static HASH *F_INCLUDETABLE = NULL; /* Fortran include file hash table */ ! 39: static HASH *P_INCLUDETABLE = NULL; /* Pascal include file hash table */ ! 40: /* ! 41: * Additional include directories are specified via the -I compiler ! 42: * command line option. These directories are stored in singly-linked lists. ! 43: * We also assume that the last look-up directory is "/usr/include". ! 44: */ ! 45: static SLIST *C_INCDIR; /* C include directories */ ! 46: static SLIST *F_INCDIR; /* Fortran include directories */ ! 47: static SLIST *P_INCDIR; /* Pascal include directories */ ! 48: ! 49: SLIST *EXTLIST; /* external header file name list */ ! 50: ! 51: extern char *PGN; /* program name */ ! 52: ! 53: /* ! 54: * addincdir() adds directories containing include files to the ! 55: * appropriate singly-linked list. The pathnames to the directories ! 56: * are derived from makefile macro definitions. ! 57: */ ! 58: void ! 59: addincdir() ! 60: { ! 61: extern HASH *MDEFTABLE; /* macro definition table */ ! 62: char *slappend(); /* append to singly-linked list */ ! 63: HASHBLK *htb; /* hash table entry block */ ! 64: HASHBLK *htlookup(); /* find hash table entry */ ! 65: int cleanup(); /* remove temporary makefile and exit */ ! 66: void getI(); /* get include directory pathnames */ ! 67: ! 68: /* C files */ ! 69: if ((htb = htlookup(MCFLAGS, MDEFTABLE)) != NULL) ! 70: getI(htb->h_key, htb->h_def, C_INCDIR); ! 71: if (slappend(USRINCLUDE, C_INCDIR) == NULL) ! 72: cleanup(); ! 73: ! 74: /* Fortran files */ ! 75: if ((htb = htlookup(MFFLAGS, MDEFTABLE)) != NULL) ! 76: getI(htb->h_key, htb->h_def, F_INCDIR); ! 77: if (slappend(USRINCLUDE, F_INCDIR) == NULL) ! 78: cleanup(); ! 79: ! 80: /* Pascal files */ ! 81: if ((htb = htlookup(MPFLAGS, MDEFTABLE)) != NULL) ! 82: getI(htb->h_key, htb->h_def, P_INCDIR); ! 83: if (slappend(USRINCLUDE, P_INCDIR) == NULL) ! 84: cleanup(); ! 85: } ! 86: ! 87: ! 88: ! 89: /* ! 90: * findinclude() tries to find the pathname of an include file. Returns ! 91: * integer INTERNAL if found in the current directory, EXTERNAL if found ! 92: * somewhere else, FROMRULE if derived from a transformation rule, ! 93: * otherwise NOTFOUND. The pathname is copied into incpath. ! 94: */ ! 95: #define LOCALDIR(f) (index(f, _PSC) == NULL) ! 96: #define INCLUDETYPE(f) ((index(f, _PSC) == NULL) ? INTERNAL : EXTERNAL) ! 97: ! 98: findinclude(incpath, incname, lastname, type) ! 99: char *incpath; /* pathname receiving buffer */ ! 100: register char *incname; /* include file name */ ! 101: char *lastname; /* file that includes incname */ ! 102: int type; /* file type */ ! 103: { ! 104: register char *pp; /* include file path pointer */ ! 105: char *index(); /* find occurrence of character */ ! 106: char *optpath(); /* optimize pathname */ ! 107: char *pathcat(); /* pathname concatenation */ ! 108: char *pathhead(); /* remove pathname tail */ ! 109: char *strcpy(); /* string copy */ ! 110: char *strpcpy(); /* string copy and update pointer */ ! 111: int lookuprule(); /* look up transformation rules */ ! 112: SLBLK *slb; /* singly-linked list block */ ! 113: SLIST *slist; /* include directory list pointer */ ! 114: ! 115: /* ! 116: * look in /usr/include only ! 117: */ ! 118: if (*incname == '<') ! 119: { ! 120: pp = strpcpy(incpath, USRINCLUDE); ! 121: for (incname++; *incname != '>'; incname++, pp++) ! 122: *pp = *incname; ! 123: *pp = '\0'; ! 124: return(FILEXIST(incpath) ? EXTERNAL : NOTFOUND); ! 125: } ! 126: ! 127: /* ! 128: * look for an absolute include file name ! 129: */ ! 130: if (*incname == '/') ! 131: { ! 132: strcpy(incpath, incname); ! 133: return(FILEXIST(incpath) ? EXTERNAL : NOTFOUND); ! 134: } ! 135: ! 136: /* ! 137: * look in current include directory to see if the file exists, ! 138: * or can be generated by a transformation rule in the current ! 139: * working directory. ! 140: */ ! 141: if (LOCALDIR(lastname)) ! 142: { ! 143: if (LOCALDIR(incname)) ! 144: { ! 145: if (lookuprule(incname, incpath) == YES) ! 146: return(FROMRULE); ! 147: } ! 148: strcpy(incpath, incname); ! 149: if (FILEXIST(incpath)) ! 150: return(INCLUDETYPE(incpath)); ! 151: } ! 152: else { ! 153: strcpy(incpath, lastname); ! 154: pathcat(incpath, pathhead(incpath), incname); ! 155: optpath(incpath); ! 156: if (FILEXIST(incpath)) ! 157: return(INCLUDETYPE(incpath)); ! 158: } ! 159: ! 160: /* ! 161: * search directory list ! 162: */ ! 163: switch (type) ! 164: { ! 165: case INCLUDE_C: ! 166: slist = C_INCDIR; ! 167: break; ! 168: case INCLUDE_FORTRAN: ! 169: slist = F_INCDIR; ! 170: break; ! 171: case INCLUDE_PASCAL: ! 172: slist = P_INCDIR; ! 173: break; ! 174: } ! 175: for (slb = slist->head; slb != NULL; slb = slb->next) ! 176: { ! 177: pp = strpcpy(incpath, slb->key); ! 178: strcpy(pp, incname); ! 179: optpath(incpath); ! 180: if (FILEXIST(incpath)) ! 181: return(INCLUDETYPE(incpath)); ! 182: } ! 183: return(NOTFOUND); ! 184: } ! 185: ! 186: ! 187: ! 188: /* ! 189: * getI() appends include directories found via the -I compiler option to ! 190: * a singly linked list. ! 191: */ ! 192: void ! 193: getI(mnam, mdef, slist) ! 194: char *mnam; /* compiler options macro name */ ! 195: char *mdef; /* compiler options macro definition */ ! 196: SLIST *slist; /* singly-linked list */ ! 197: { ! 198: char *gettoken(); /* get next token */ ! 199: char incpath[PATHSIZE]; /* include directory pathname buffer */ ! 200: char *slappend(); /* append to singly-linked list */ ! 201: char *strcat(); /* string concatenation */ ! 202: int cleanup(); /* remove temporary makefile and exit */ ! 203: ! 204: while ((mdef = gettoken(incpath, mdef)) != NULL) ! 205: if (incpath[0] == '-' && incpath[1] == 'I') ! 206: if (incpath[2] == '\0') /* -I dir option */ ! 207: { ! 208: if ((mdef = gettoken(incpath, mdef)) != NULL) ! 209: { ! 210: strcat(incpath, PATHSEP); ! 211: if (slappend(incpath, slist) == NULL) ! 212: cleanup(); ! 213: } ! 214: else { ! 215: warn2("missing include directory in %s %s", ! 216: mnam, "macro definition"); ! 217: break; ! 218: } ! 219: } ! 220: else { /* -Idir option */ ! 221: strcat(incpath+2, PATHSEP); ! 222: if (slappend(incpath+2, slist) == NULL) ! 223: cleanup(); ! 224: } ! 225: } ! 226: ! 227: ! 228: ! 229: /* ! 230: * getinclude() fetchs an include file name from a line of source code. ! 231: * /usr/include '<' and '>' delimiters remain with the filename to ! 232: * distinguish it from an include file in a local directory. Returns ! 233: * NO if syntax error, otherwise YES. ! 234: */ ! 235: getinclude(incname, curname, lineno, ifp) ! 236: char *curname; /* current file name */ ! 237: char *incname; /* include file name receiving buffer */ ! 238: int lineno; /* current line number */ ! 239: register FILE *ifp; /* input stream */ ! 240: { ! 241: register char *ip; /* include file name buffer pointer */ ! 242: register int c; /* current character */ ! 243: ! 244: SKIPWHITESPACE(c, ifp); ! 245: for (ip = incname; (c = getc(ifp)) != EOF; ip++) ! 246: { ! 247: *ip = c; ! 248: if (c == '\n' || c == '\t' || c == ' ' || c == ';' || c == ',') ! 249: { ! 250: ungetc(c, ifp); ! 251: break; ! 252: } ! 253: } ! 254: *ip = '\0'; ! 255: if ((*incname == '<' && ip[-1] != '>') || ! 256: (*incname == '\"' && ip[-1] != '\"') || ! 257: (*incname == '\'' && ip[-1] != '\'') || ! 258: (*incname == '(' && ip[-1] != ')')) ! 259: { ! 260: fprintf(stderr, ! 261: "%s: \"%s\", line %d: bad include syntax for %s\n", ! 262: PGN, curname, lineno, incname); ! 263: return(NO); ! 264: } ! 265: if (*incname == '\"' || *incname == '\'' || *incname == '(') ! 266: { ! 267: ip[-1] = '\0'; ! 268: ip = incname + 1; ! 269: while (*incname++ = *ip++) ! 270: continue; ! 271: } ! 272: return(YES); ! 273: } ! 274: ! 275: ! 276: ! 277: /* ! 278: * inclink() stores a pointer to a hash table block (which contains ! 279: * include file information) somewhere. Returns a pointer to the somewhere, ! 280: * or calls cleanup() if out of memory. ! 281: */ ! 282: INCBLK * ! 283: inclink(htb) ! 284: HASHBLK *htb; /* hash table block pointer to save */ ! 285: { ! 286: char *malloc(); /* memory allocator */ ! 287: INCBLK *iblk; /* pointer to new include chain block */ ! 288: int cleanup(); /* remove temporary makefile and exit */ ! 289: ! 290: if ((iblk = (INCBLK *) malloc(sizeof(INCBLK))) == NULL) ! 291: { ! 292: warn("out of memory"); ! 293: cleanup(); ! 294: } ! 295: iblk->i_loop = NO; ! 296: iblk->i_hblk = htb; ! 297: iblk->i_next = NULL; ! 298: return(iblk); ! 299: } ! 300: ! 301: ! 302: ! 303: /* ! 304: * instalinclude() adds an include file name to the appropriate include ! 305: * file hash table. Returns a pointer to the hash table block, or calls ! 306: * cleanup() if out of memory. ! 307: */ ! 308: HASHBLK * ! 309: instalinclude(incname, incpath, type) ! 310: char *incname; /* name of include file */ ! 311: char *incpath; /* path to include file */ ! 312: int type; /* type of source file */ ! 313: { ! 314: HASH *htinit(); /* initialize hash table */ ! 315: HASHBLK *htb = NULL; /* hash table block */ ! 316: HASHBLK *htinstall(); /* install hash table entry */ ! 317: int cleanup(); /* remove temporary makefile and exit */ ! 318: int ilen; /* include path length */ ! 319: int strlen(); /* string length */ ! 320: ! 321: ilen = strlen(incpath); ! 322: switch (type) ! 323: { ! 324: case INCLUDE_C: ! 325: if (C_INCLUDETABLE == NULL) ! 326: { ! 327: C_INCLUDETABLE = htinit(INCLUDETABLESIZE); ! 328: } ! 329: htb = htinstall(incname, incpath, ilen, C_INCLUDETABLE); ! 330: break; ! 331: case INCLUDE_FORTRAN: ! 332: if (F_INCLUDETABLE == NULL) ! 333: { ! 334: F_INCLUDETABLE = htinit(INCLUDETABLESIZE); ! 335: } ! 336: htb = htinstall(incname, incpath, ilen, F_INCLUDETABLE); ! 337: break; ! 338: case INCLUDE_PASCAL: ! 339: if (P_INCLUDETABLE == NULL) ! 340: { ! 341: P_INCLUDETABLE = htinit(INCLUDETABLESIZE); ! 342: } ! 343: htb = htinstall(incname, incpath, ilen, P_INCLUDETABLE); ! 344: break; ! 345: } ! 346: if (htb == NULL) ! 347: cleanup(); ! 348: return(htb); ! 349: } ! 350: ! 351: ! 352: ! 353: /* ! 354: * lookupinclude() returns a pointer to an include hash table block ! 355: * corresponding to incname and type. Returns null if not found. ! 356: */ ! 357: HASHBLK * ! 358: lookupinclude(incname, type) ! 359: char *incname; /* name of include file */ ! 360: int type; /* type of source file */ ! 361: { ! 362: HASH *includetable = NULL; /* include file hash table */ ! 363: HASHBLK *htlookup(); /* find hash table entry */ ! 364: ! 365: switch (type) ! 366: { ! 367: case INCLUDE_C: ! 368: includetable = C_INCLUDETABLE; ! 369: break; ! 370: case INCLUDE_FORTRAN: ! 371: includetable = F_INCLUDETABLE; ! 372: break; ! 373: case INCLUDE_PASCAL: ! 374: includetable = P_INCLUDETABLE; ! 375: break; ! 376: } ! 377: return((includetable == NULL) ? NULL : htlookup(incname, includetable)); ! 378: } ! 379: ! 380: ! 381: ! 382: /* ! 383: * mkdepend() creates include file dependencies for object files and installs ! 384: * them to dependency list dlp. Returns a pointer to the dependency list. ! 385: */ ! 386: DLIST * ! 387: mkdepend() ! 388: { ! 389: extern SLIST *SRCLIST; /* source file name list */ ! 390: char *rindex(); /* find last occurrence of character */ ! 391: char *suffix; /* suffix pointer */ ! 392: DLBLK *dlappend(); /* append dependency list */ ! 393: DLIST *dlinit(); /* initialize dependency list */ ! 394: DLIST *dlist; /* dependency list */ ! 395: INCBLK *ibp; /* pointer to chain of include files */ ! 396: INCBLK *readC(); /* read C include-style files */ ! 397: INCBLK *readF(); /* read Fortran include-style files */ ! 398: INCBLK *readP(); /* read Pascal include-style files */ ! 399: int cleanup(); /* remove temporary makefile and exit */ ! 400: int lookuptypeofinclude(); /* look up the brand of include */ ! 401: int slsort(); /* sort singly-linked list */ ! 402: int strcmp(); /* string comparison */ ! 403: int type; /* source file type */ ! 404: SLBLK *lbp; /* list block pointer */ ! 405: SLIST *slinit(); /* initialize singly-linked list */ ! 406: void addincdir(); /* add to list of include directories */ ! 407: void rmprinttag(); /* remove "already printed" tags */ ! 408: ! 409: /* initialize include file look-up lists */ ! 410: C_INCDIR = slinit(); ! 411: F_INCDIR = slinit(); ! 412: P_INCDIR = slinit(); ! 413: ! 414: /* add additional include directories */ ! 415: addincdir(); ! 416: ! 417: /* initialize external header file name list */ ! 418: EXTLIST = slinit(); ! 419: ! 420: /* initialize dependency list */ ! 421: dlist = dlinit(); ! 422: ! 423: for (lbp = SRCLIST->head; lbp != NULL; lbp = lbp->next) ! 424: { ! 425: suffix = rindex(lbp->key, '.'); ! 426: type = lookuptypeofinclude(++suffix); ! 427: switch (type) ! 428: { ! 429: case INCLUDE_C: ! 430: ibp = readC(lbp->key, 0, lbp->key); ! 431: break; ! 432: case INCLUDE_FORTRAN: ! 433: ibp = readF(lbp->key, 0, lbp->key); ! 434: break; ! 435: case INCLUDE_PASCAL: ! 436: ibp = readP(lbp->key, 0, lbp->key); ! 437: break; ! 438: case INCLUDE_NONE: ! 439: ibp = NULL; ! 440: break; ! 441: } ! 442: if (ibp != NULL) ! 443: { ! 444: if (dlappend(type, lbp, ibp, dlist) == NULL) ! 445: cleanup(); ! 446: } ! 447: } ! 448: if (slsort(strcmp, EXTLIST) == NO) ! 449: cleanup(); ! 450: return(dlist); ! 451: } ! 452: ! 453: ! 454: ! 455: /* ! 456: * notfound() prints a "can't find" filename error message. ! 457: */ ! 458: void ! 459: notfound(curname, lineno, incname) ! 460: char *curname; /* current file name */ ! 461: char *incname; /* name of include file */ ! 462: int lineno; /* current line number */ ! 463: { ! 464: if (PGN != NULL && *PGN != '\0') ! 465: { ! 466: fprintf(stderr, "%s: ", PGN); ! 467: } ! 468: if (*incname == '<') ! 469: { ! 470: fprintf(stderr, "\"%s\", line %d: can't find %s\n", ! 471: curname, lineno, incname); ! 472: } ! 473: else { ! 474: fprintf(stderr, "\"%s\", line %d: can't find \"%s\"\n", ! 475: curname, lineno, incname); ! 476: } ! 477: } ! 478: ! 479: ! 480: ! 481: /* ! 482: * readC() searches C files for included files. Returns a pointer to ! 483: * the chain of include files installed or found in the include file ! 484: * hash table, or null if no include files found. ! 485: */ ! 486: INCBLK * ! 487: readC(lastfile, lastline, curname) ! 488: char *lastfile; /* parent file name */ ! 489: int lastline; /* current line in parent file */ ! 490: char *curname; /* current file name */ ! 491: { ! 492: register char *p; /* include string pointer */ ! 493: register FILE *ifp; /* input file stream */ ! 494: register int c; /* current character */ ! 495: char incname[PATHSIZE]; /* name of include file */ ! 496: char incpath[PATHSIZE]; /* path to include file */ ! 497: char *slappend(); /* append pathname to list */ ! 498: FILE *fopen(); /* open file */ ! 499: HASHBLK *ftb; /* fromrule hash table entry block */ ! 500: HASHBLK *htb = NULL; /* hash table entry block */ ! 501: HASHBLK *instalinclude(); /* install include name in hash table */ ! 502: HASHBLK *lookupinclude(); /* look up include in hash table */ ! 503: INCBLK *i_head = NULL; /* head of include chain */ ! 504: INCBLK *i_tail = NULL; /* tail of include chain */ ! 505: INCBLK *inclink(); /* link include file hash blocks */ ! 506: int cleanup(); /* remove temporary makefile and exit */ ! 507: int findinclude(); /* locate include file */ ! 508: int getinclude(); /* get include name from input line */ ! 509: int inctype; /* origin of include file */ ! 510: int lineno = 1; /* current line number */ ! 511: int strlen(); /* string length */ ! 512: int type; /* file type */ ! 513: void notfound(); /* print "can't find" filename msg */ ! 514: ! 515: type = INCLUDE_C; ! 516: ! 517: if ((ifp = fopen(curname, "r")) == NULL) ! 518: { ! 519: if (lastline > 0) ! 520: fprintf(stderr, "%s: \"%s\", line %d: ", PGN, ! 521: lastfile, lastline); ! 522: else ! 523: fprintf(stderr, "%s: ", PGN); ! 524: perror(curname); ! 525: return(NULL); ! 526: } ! 527: while ((c = getc(ifp)) != EOF) ! 528: { ! 529: if (c != '#') ! 530: goto nextline; ! 531: SKIPWHITESPACE(c, ifp); ! 532: for (p = "include"; (c = getc(ifp)) == *p && *p != '\0' ; p++) ! 533: continue; ! 534: if (*p != '\0') ! 535: goto nextline; ! 536: if (getinclude(incname, curname, lineno, ifp) == NO) ! 537: goto nextline; ! 538: if ((htb = lookupinclude(incname, type)) == NULL) ! 539: { ! 540: inctype = findinclude(incpath, incname, curname, type); ! 541: if (inctype == INTERNAL) ! 542: { ! 543: htb = instalinclude(incname, incpath, type); ! 544: } ! 545: else if (inctype == EXTERNAL) ! 546: { ! 547: htb = instalinclude(incname, incpath, type); ! 548: if (slappend(incpath, EXTLIST) == NULL) ! 549: cleanup(); ! 550: } ! 551: else if (inctype == FROMRULE) ! 552: { ! 553: htb = instalinclude(incname, incname, type); ! 554: ftb = instalinclude(incpath, incpath, type); ! 555: } ! 556: else { ! 557: notfound(curname, lineno, incname); ! 558: goto nextline; ! 559: } ! 560: ! 561: /* look for nested include files */ ! 562: htb->h_sub = readC(curname, lineno, incpath); ! 563: ! 564: if (inctype == FROMRULE) ! 565: ftb->h_sub = htb->h_sub; ! 566: } ! 567: if (i_tail == NULL) ! 568: { ! 569: i_head = i_tail = inclink(htb); ! 570: } ! 571: else { ! 572: i_tail = i_tail->i_next = inclink(htb); ! 573: } ! 574: nextline: while (c != '\n' && c != EOF) ! 575: c = getc(ifp); ! 576: lineno++; ! 577: } ! 578: fclose(ifp); ! 579: return(i_head); ! 580: } ! 581: ! 582: ! 583: ! 584: /* ! 585: * readF() searches Fortran files for included files. Returns a pointer ! 586: * to the chain of include files installed or found in the include file ! 587: * hash table, or null if no include files found. ! 588: */ ! 589: INCBLK * ! 590: readF(lastfile, lastline, curname) ! 591: char *lastfile; /* parent file name */ ! 592: int lastline; /* current line in parent file */ ! 593: char *curname; /* current file name */ ! 594: { ! 595: register char *p; /* include string pointer */ ! 596: register FILE *ifp; /* input file stream */ ! 597: register int c; /* current character */ ! 598: char incname[PATHSIZE]; /* name of include file */ ! 599: char incpath[PATHSIZE]; /* path to include file */ ! 600: char *slappend(); /* append pathname to list */ ! 601: FILE *fopen(); /* open file */ ! 602: HASHBLK *ftb; /* fromrule hash table entry block */ ! 603: HASHBLK *htb = NULL; /* hash table entry block */ ! 604: HASHBLK *instalinclude(); /* install include name in hash table */ ! 605: HASHBLK *lookupinclude(); /* look up include in hash table */ ! 606: INCBLK *i_head = NULL; /* head of include chain */ ! 607: INCBLK *i_tail = NULL; /* tail of include chain */ ! 608: INCBLK *inclink(); /* link include file hash blocks */ ! 609: int cleanup(); /* remove temporary makefile and exit */ ! 610: int findinclude(); /* locate include file */ ! 611: int getinclude(); /* get include name from input line */ ! 612: int inctype; /* origin of include file */ ! 613: int lineno = 1; /* current line number */ ! 614: int strlen(); /* string length */ ! 615: int type; /* file type */ ! 616: void notfound(); /* print "can't find" filename msg */ ! 617: ! 618: type = INCLUDE_FORTRAN; ! 619: ! 620: if ((ifp = fopen(curname, "r")) == NULL) ! 621: { ! 622: if (lastline > 0) ! 623: fprintf(stderr, "%s: \"%s\", line %d: ", PGN, ! 624: lastfile, lastline); ! 625: else ! 626: fprintf(stderr, "%s: ", PGN); ! 627: perror(curname); ! 628: return(NULL); ! 629: } ! 630: while ((c = getc(ifp)) != EOF) ! 631: { ! 632: if (c == 'c' || c == 'C' || c == '*' || c == '\n') ! 633: goto nextline; ! 634: while ((c = getc(ifp)) == ' ' || c == '\t') ! 635: continue; ! 636: for (p = "include"; *p == TOLOWER(c) && *p != '\0'; p++) ! 637: c = getc(ifp); ! 638: if (*p != '\0') ! 639: goto nextline; ! 640: if (getinclude(incname, curname, lineno, ifp) == NO) ! 641: goto nextline; ! 642: if ((htb = lookupinclude(incname, type)) == NULL) ! 643: { ! 644: inctype = findinclude(incpath, incname, curname, type); ! 645: if (inctype == INTERNAL) ! 646: { ! 647: htb = instalinclude(incname, incpath, type); ! 648: } ! 649: else if (inctype == EXTERNAL) ! 650: { ! 651: htb = instalinclude(incname, incpath, type); ! 652: if (slappend(incpath, EXTLIST) == NULL) ! 653: cleanup(); ! 654: } ! 655: else if (inctype == FROMRULE) ! 656: { ! 657: htb = instalinclude(incname, incname, type); ! 658: ftb = instalinclude(incpath, incpath, type); ! 659: } ! 660: else { ! 661: notfound(curname, lineno, incname); ! 662: goto nextline; ! 663: } ! 664: ! 665: /* look for nested include files */ ! 666: htb->h_sub = readF(curname, lineno, incpath); ! 667: ! 668: if (inctype == FROMRULE) ! 669: ftb->h_sub = htb->h_sub; ! 670: } ! 671: if (i_tail == NULL) ! 672: { ! 673: i_head = i_tail = inclink(htb); ! 674: } ! 675: else { ! 676: i_tail = i_tail->i_next = inclink(htb); ! 677: } ! 678: nextline: while (c != '\n' && c != EOF) ! 679: c = getc(ifp); ! 680: lineno++; ! 681: } ! 682: fclose(ifp); ! 683: return(i_head); ! 684: } ! 685: ! 686: ! 687: ! 688: /* ! 689: * readP() searches Pascal files for included files. Returns a pointer ! 690: * to the chain of include files installed or found in the include file ! 691: * hash table, or null if no include files found. ! 692: */ ! 693: INCBLK * ! 694: readP(lastfile, lastline, curname) ! 695: char *lastfile; /* parent file name */ ! 696: int lastline; /* current line in parent file */ ! 697: char *curname; /* current file name */ ! 698: { ! 699: register char *p; /* include string pointer */ ! 700: register FILE *ifp; /* input file stream */ ! 701: register int c; /* current character */ ! 702: char incname[PATHSIZE]; /* name of include file */ ! 703: char incpath[PATHSIZE]; /* path to include file */ ! 704: char *slappend(); /* append pathname to list */ ! 705: FILE *fopen(); /* open file */ ! 706: HASHBLK *ftb; /* fromrule hash table entry block */ ! 707: HASHBLK *htb = NULL; /* hash table entry block */ ! 708: HASHBLK *instalinclude(); /* install include name in hash table */ ! 709: HASHBLK *lookupinclude(); /* look up include in hash table */ ! 710: INCBLK *i_head = NULL; /* head of include chain */ ! 711: INCBLK *i_tail = NULL; /* tail of include chain */ ! 712: INCBLK *inclink(); /* link include file hash blocks */ ! 713: int cleanup(); /* remove temporary makefile and exit */ ! 714: int findinclude(); /* locate include file */ ! 715: int getinclude(); /* get include name from input line */ ! 716: int inctype; /* origin of include file */ ! 717: int lineno = 1; /* current line number */ ! 718: int strlen(); /* string length */ ! 719: int type; /* file type */ ! 720: void notfound(); /* print "can't find" filename msg */ ! 721: ! 722: type = INCLUDE_PASCAL; ! 723: ! 724: if ((ifp = fopen(curname, "r")) == NULL) ! 725: { ! 726: if (lastline > 0) ! 727: fprintf(stderr, "%s: \"%s\", line %d: ", PGN, ! 728: lastfile, lastline); ! 729: else ! 730: fprintf(stderr, "%s: ", PGN); ! 731: perror(curname); ! 732: return(NULL); ! 733: } ! 734: while ((c = getc(ifp)) != EOF) ! 735: { ! 736: if (c != '#') ! 737: goto nextline; ! 738: while ((c = getc(ifp)) == ' ' || c == '\t') ! 739: continue; ! 740: for (p = "include"; *p == TOLOWER(c) && *p != '\0'; p++) ! 741: c = getc(ifp); ! 742: if (*p != '\0') ! 743: goto nextline; ! 744: if (getinclude(incname, curname, lineno, ifp) == NO) ! 745: goto nextline; ! 746: if ((htb = lookupinclude(incname, type)) == NULL) ! 747: { ! 748: inctype = findinclude(incpath, incname, curname, type); ! 749: if (inctype == INTERNAL) ! 750: { ! 751: htb = instalinclude(incname, incpath, type); ! 752: } ! 753: else if (inctype == EXTERNAL) ! 754: { ! 755: htb = instalinclude(incname, incpath, type); ! 756: if (slappend(incpath, EXTLIST) == NULL) ! 757: cleanup(); ! 758: } ! 759: else if (inctype == FROMRULE) ! 760: { ! 761: htb = instalinclude(incname, incname, type); ! 762: ftb = instalinclude(incpath, incpath, type); ! 763: } ! 764: else { ! 765: notfound(curname, lineno, incname); ! 766: goto nextline; ! 767: } ! 768: ! 769: /* look for nested include files */ ! 770: htb->h_sub = readP(curname, lineno, incpath); ! 771: ! 772: if (inctype == FROMRULE) ! 773: ftb->h_sub = htb->h_sub; ! 774: } ! 775: if (i_tail == NULL) ! 776: { ! 777: i_head = i_tail = inclink(htb); ! 778: } ! 779: else { ! 780: i_tail = i_tail->i_next = inclink(htb); ! 781: } ! 782: nextline: while (c != '\n' && c != EOF) ! 783: c = getc(ifp); ! 784: lineno++; ! 785: } ! 786: fclose(ifp); ! 787: return(i_head); ! 788: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.