mann@Navajo.ARPA (10/06/84)
#! /bin/sh : This is a shar archive. Extract with sh, not csh. echo x - makedep.1 cat > makedep.1 << '965!Funky!Stuff!' .TH MAKEDEP 1 "2 April 1984" .SU .SH NAME makedep \- construct dependency lines for makefiles .SH SYNOPSIS .B makedep [ options .B ] [ source files .B ] .SH DESCRIPTION .I Makedep constructs a makefile-style dependency list showing which header files the object files constructed from the given source files depend upon. The dependency of the object file upon the source file is not indicated in the output; this dependency can normally be inferred by the .I make program. .PP .I Makedep handles nested includes properly, propagating dependencies of one header file upon another back to each object file whose source file includes the dependent header file. .PP The following options are accepted. In options that take an argument, the space between the option letter and the argument is optional. .IP "-o file" 1i Output file name. The default is "dependencies". The name "-" indicates standard output. .IP "-I dir" 1i Add .I dir to the include file search list. Multiple -I options accumulate, building the search list from left to right, with the system include directories added at the end. Directory names are interpreted relative to the directory from which .I makedep is invoked. .IP "-U" 1i Use the standard Unix header directories as the system search list. Equivalent to specifying -I/usr/include after all other -I options. .IP "-V" 1i Use the standard V-System header directories as the system search list. Equivalent to specifying the options -I/usr/sun/include -I/usr/local/include -I/usr/include after all other -I options. .IP "-xV" 1i Use the experimental V-System header directories as the system search list. Equivalent to specifying the options -I/usr/sun/xinclude -I/usr/sun/include -I/usr/local/include -I/usr/include after all other -I options. .IP "-N" 1i Use no system search list. Suppresses the warning message ordinarily printed when a header file cannot be found. This option is useful when you are not interested in dependencies on system include files. .IP "-e ext" 1i Object files have extension ".ext". Defaults to .b if -V or -xV is specified, .o otherwise. .IP "-d" 1i Turn on debug output. Useful only to the maintainers. .PP If the source files depend on any header files in standard system include directories, one of the options -U, -V, -xV, or -N should normally be specified. These four options are mutually exclusive. If none of these options is given, only the directories specified in -I options are included in the search list (as with the -N flag), but warning messages are still printed for any header files that cannot be found. .SH "SEE ALSO" make(1) .SH DIAGNOSTICS A warning is printed for each included file that cannot be found. Other errors are fatal; the messages should be self-explanatory. .SH BUGS Pathnames that are excessively long may be silently truncated or cause crashes. .PP .I Makedep does not know that the same file can have two different names, for example "bar.h" and "foo/../bar.h". This means it will fail to detect loops in the dependency graph if the pathnames grow in this way while it is following the loop. The loop will eventually terminate due to the previous bug, and garbage output will result. .SH AUTHORS Marvin Theimer and Tim Mann, Stanford. 965!Funky!Stuff! echo x - buildfile cat > buildfile << '965!Funky!Stuff!' # Buildfile for makedep OBJS = makedep.o gen.o getincl.o print.o list.o CFLAGS = -O .c.o: cc $(CFLAGS) -c $< makedep: $(OBJS) cc -o makedep $(OBJS) #include dependencies install: install -q -s makedep ${DESTDIR}/bin/makedep install -q -c makedep.1 /usr/man/man1/makedep.1 clean: rm -f *BAK *CKP *.o makedep cleanbak: rm -f *BAK *CKP build: makedep -U *.c buildmake xbuild: makedep -U *.c buildmake -DX=1 965!Funky!Stuff! echo x - gen.c cat > gen.c << '965!Funky!Stuff!' /* * Module which generates the list of source files and which generates * the include file dependencies. */ #include "makedep.h" /* External and forward fcn declarations */ extern StringList *GetIncludeFileList(); StringList *FindIListLocation(); /* * GenIncludeFileDependencies: * Generate all include file dependencies. * Starting with an empty list of include files, each source file * on SrcFiles is examined * to extract all include file references it contains. These file names * are placed on an include file list, IList. Also, each source file gets * a linked list of (immediate) dependencies associated with it. * Each include file on IList * is examined to extract its include file dependencies; which are added to * the list. Also, each include file gets a linked list of (immediate) * dependencies associated with it. * The IList is kept in sorted order in order to remove duplicates * and processed list entries are marked as such to prevent reprocessing. */ GenIncludeFileDependencies() { StringList *p; int done; if (Debug) { printf("\nGenIncludeFileDependencies:\n"); } IList = MakeList(); /* Create an empty IList. */ /* Run through the source files, generating each one's immediate dependency list. */ for (p = SrcFiles->next; p != NULL; p = p->next) { GenDependencies(p); } /* Repeatedly iterate over IList until all elements have been processed. */ done = FALSE; while (!done) { done = TRUE; /* Assume we're done until proven otherwise. */ for (p = IList->next; p != NULL; p = p->next) { if (p->state == UNPROCESSED) { done = FALSE; GenDependencies(p); } } } } /* * GenDependencies: * Generate the immediate dependency list for p and mark it as processed. * Adds newly encountered include files to IList. IList is kept in sorted * order so that duplicates can be removed. */ GenDependencies(p) StringList *p; { StringList *il, *pil, *pIList; DepList *dil; p->state = PROCESSED; /* Generate a list of include files referenced directly in p. */ il = GetIncludeFileList(p); /* Create a list of corresponding dependency records for p. */ for (pil = il->next; pil != NULL; pil = pil->next) { AddDepList(pil, p); } if (Debug) { printf("%s ", p->str); PrintDepList(p, "dependency list"); } /* Merge the list of include files into IList, discarding duplicates. Make the pointers in p's dependency list point at the records in IList rather than the il list. This is simpler to program than attempting to extract the non-duplicated records from il and selectively updating things. */ for (dil = p->dep; dil != NULL; dil = dil->next) { pIList = FindIListLocation(dil->inclFile); /* pIList now points either to a record in IList for this include file or to the record in IList after which the include file should be inserted. */ if ((pIList == IList) || (!Equal(pIList->str, dil->inclFile->str))) { /* No duplicate - insert a new record into IList. */ InsertList(dil->inclFile->str, pIList); pIList = pIList->next; /* Make pIList point at the new record. */ } dil->inclFile = pIList; /* pIList at this point points at the correct record in IList. */ } /* Get rid of the il list of include files. All references are now to the records in IList. */ DestroyList(il); } /* * FindIListLocation: * Search the (sorted) IList for a record corresponding to p. If one is * found then return a pointer to it. Otherwise return a pointer to the * record in IList after which such a record would appear. */ StringList *FindIListLocation(p) StringList *p; { StringList *ptr; int order; for (ptr = IList; ptr->next != NULL; ptr = ptr->next) { order = strcmp(p->str, ptr->next->str); if (order == 0) { /* Found a corresponding record. Return a ptr to it. */ return(ptr->next); } else if (order < 0) { /* ptr->next->str is lexically greater than p->str. p should go before it but after ptr. */ return(ptr); } } /* p goes at the end of the list. */ return(ptr); } 965!Funky!Stuff! echo x - getincl.c cat > getincl.c << '965!Funky!Stuff!' /* * Module which finds all include file references in a specified file. */ #include "makedep.h" #define MaxLine 200 /* Maximum line size allowed for a file. */ extern FILE *fopen(); extern char *rindex(); /* * GetIncludeFileList: * Scan the file corresponding to p and extract all include file references * from it. */ StringList *GetIncludeFileList(p) StringList *p; { FILE *pf; char *linePtr; char line[MaxLine]; char dirName[MaxLine]; StringList *iList; char *p1; /* Open the file corresponding to p for reading. */ pf = fopen(p->str, "r"); if (pf == NULL) { perror(p->str); exit(errno); } /* Determine the correct path prefix for the * local directory. */ strcpy(dirName, p->str); p1 = rindex(dirName, '/'); if (p1 != NULL) *p1 = '\0'; /* chop off the last component */ else *dirName = '\0'; /* no path prefix */ /* Scan each line of the file in search of include file references. */ iList = MakeList(); linePtr = fgets(line, MaxLine, pf); while (linePtr != NULL) { ProcessLine(linePtr, iList, dirName); linePtr = fgets(line, MaxLine, pf); } /* Close p's file. */ fclose(pf); return(iList); } /* * ProcessLine: * Process a line from a file, looking for include file references. * Create a list of records, one per include file reference. * Each include file record contains the correctly expanded include file, * i.e. the include file name is prepended with the appropriate directory * prefix, as determined from InclDirs directory search list. */ ProcessLine(linePtr, iList, dirName) char *linePtr; StringList *iList; char *dirName; /* Local directory name. */ { char *p = linePtr; int relLocal; char name[MaxLine], dname[MaxLine]; char *p1; StringList *dp; if (*p != '#') { /* Couldn't find the # in col. 1. */ return; } p++; /* Skip over any blanks or tabs between the # and the include. */ while ((*p == ' ') || (*p == '\t')) { p++; } /* Parse the include string. */ if (strcmpn(p, "include", 7) != 0) { /* Didn't find the include string. */ return; } p += 7; /* Skip over any blanks or tabs between the include and the " or < . */ while ((*p == ' ') || (*p == '\t')) { p++; } /* Determine whether the include is relative to the local dir or not. */ if (*p == '"') { relLocal = TRUE; } else if (*p == '<') { relLocal = FALSE; } else { return; /* It's neither - so this isn't an include file refernence. */ } p++; /* p now points at the include file's name. */ /* Extract the include file's name. */ p1 = name; while ((*p != '"') && (*p != '>') && (*p != '\0')) { *p1++ = *p++; } if (*p == '\0') { return; /* Abrupt end-of-line encountered. This isn't an include file ref. after all. */ } *p1 = '\0'; /* Now determine which directory the include file is actually in and prepend the file's name with the appropriate directory name. */ if (*name == '/') { /* Dealing with an absolute path name. */ if (TryToAddIncl(name, iList)) { return; } else { if (!NFlag) { fprintf(stderr,"%s: Warning - include file '%s' not found.\n", MyName, name); } return; } } if (relLocal) { /* Look in the local directory first. */ if (*dirName != '\0') { strcpy(dname, dirName); strcat(dname, "/"); strcat(dname, name); } else { strcpy(dname, name); } if (TryToAddIncl(dname, iList)) { return; } } for (dp = InclDirs->next; dp != NULL; dp = dp->next) { strcpy(dname, dp->str); strcat(dname, "/"); strcat(dname, name); if (TryToAddIncl(dname, iList)) { return; } } /* We couldn't find the include file */ if (!NFlag) { fprintf(stderr, "%s: Warning - include file '%s' not found.\n", MyName, name); } } /* * TryToAddIncl: * Tries to open the file name and if successful adds name to iList. * Returns whether name was added to iList or not. */ int TryToAddIncl(name, iList) char *name; StringList *iList; { FILE *inclF; inclF = fopen(name, "r"); if (inclF != NULL) { /* Add the include file to the iList */ AddList(name, iList); fclose(inclF); return(TRUE); } return(FALSE); } 965!Funky!Stuff! echo x - list.c cat > list.c << '965!Funky!Stuff!' /* * String List Package */ #include "makedep.h" extern char *malloc(); /* * GetMem: * malloc with error exit. */ char *GetMem(n) int n; { char *p; p = malloc(n); if (p == NULL) { fprintf(stderr, "%s: Ran out of memory!\n", MyName); exit(1); } return(p); } /* * MakeList: * Create an empty list. */ StringList *MakeList() { StringList *ptr; ptr = (StringList *) GetMem(sizeof(StringList)); ptr->str = NULL; ptr->state = HEADER; ptr->dep = NULL; ptr->next = NULL; return(ptr); } /* * AddList: * Add a string to a list. */ AddList(s, l) char *s; StringList *l; { StringList *ptr; ptr = (StringList *) GetMem(sizeof(StringList)); ptr->str = GetMem(strlen(s)+1); strcpy(ptr->str, s); ptr->state = UNPROCESSED; ptr->dep = NULL; ptr->next = l->next; l->next = ptr; } /* * InsertList: * Insert a string to a list after the designated record. * The same implementation as for AddList can be used. */ InsertList(s, l) char *s; StringList *l; { AddList(s, l); } /* * DeleteList: * Delete a string from a list. */ DeleteList(s, l) char *s; StringList *l; { StringList *ptr, *ptr1; if (l->next == NULL) { return; } for (ptr = l; ptr->next != NULL; ptr = ptr->next) { if (Equal(s, ptr->next->str)) { ptr1 = ptr->next; ptr->next = ptr->next->next; free(ptr1->str); free(ptr1); return; } } } /* * MemberOfList: * Determines whether s is a member of l. */ int MemberOfList(s, l) char *s; StringList *l; { StringList *ptr; for (ptr = l->next; ptr != NULL; ptr = ptr->next) { if (Equal(s, ptr->str)) { return(TRUE); } } return(FALSE); } /* * DestroyList: * Deallocates a list and all its members. */ DestroyList(l) StringList *l; { StringList *ptr; while (l->next != NULL) { ptr = l->next; l->next = ptr->next; free(ptr->str); free(ptr); } free(l); } /* * MergeLists: * Merges list l1 onto the front of list l2. * l1 is NOT destroyed in the process. */ MergeLists(l1, l2) StringList *l1; StringList *l2; { StringList *p; p = l1->next; while (p != NULL) { AddList(p->str, l2); p = p->next; } } /* * PrintList: * Prints a list preceded by a banner. * Intended for diagnostic purposes. */ PrintList(l, banner) StringList *l; char *banner; { printf("%s:\n", banner); for (l = l->next; l != NULL; l = l->next) { printf(" %s, state: %d\n", l->str, l->state); } } /* * AddDepList: * Add a dependency record for pi to the dependency list for p. */ AddDepList(pi, p) StringList *pi, *p; { DepList *ptr; ptr = (DepList *) GetMem(sizeof(DepList)); ptr->inclFile = pi; ptr->next = p->dep; p->dep = ptr; } /* * PrintDepList: * Print a dependency list preceded by a banner. * Intended for diagnostic purposes. */ PrintDepList(l, banner) StringList *l; char *banner; { DepList *p; printf("%s:\n", banner); for (p = l->dep; p != NULL; p = p->next) { printf(" %s\n", p->inclFile->str); } } /* * CheckDepList: * Checks to ensure that all dependency records actually point at a record * which is on the IList. */ CheckDepList(p) StringList *p; { DepList *ptr; StringList *p1; int ok; for (ptr = p->dep; ptr != NULL; ptr = ptr->next) { ok = FALSE; for (p1 = IList->next; p1 != NULL; p1 = p1->next) { if (p1 == ptr->inclFile) { ok = TRUE; break; } } if (!ok) { fprintf(stderr, "\n%s: dependency %s doesn't point into IList.\n", MyName, ptr->inclFile->str); } } } 965!Funky!Stuff! echo x - makedep.c cat > makedep.c << '965!Funky!Stuff!' /* * Program to construct dependency lines for makefiles. * * Marvin Theimer and Tim Mann, 3/18/84. * * Synopsis * makedep [options] [source files] * * Discussion * Makedep constructs a makefile-style dependency list * showing which header files the object files constructed * from the given source files depend * upon. The dependency of the object file upon the source * file is not indicated in the output; this dependency can * usually be inferred by the make program. * * Makedep handles nested includes properly, propagating * dependencies of one header file upon another back to * each object file whose source file includes the dependent * header file. * * Options * -o outfile * Output file name. The default is "dependencies". The name "-" * indicates standard output. * * -I dir * Add "dir" to the include file search list. Multiple * -I options accumulate, building the search list from * left to right, with the system include directories * added at the end. The space separating the directory * name from the -I may be omitted. Directory names * may be given relative to the directory from which * makedep is invoked. * * -U * Use the standard Unix header directories as the system * search list. Equivalent to specifying -I/usr/include after * all other -I options. * * -V * Use the standard V-System header directories as the * system search list. Equivalent to specifying the options * -I/usr/sun/include -I/usr/local/include -I/usr/include after * all other -I options. * * -xV * Use the experimental V-System header directories as the * system search list. Equivalent to specifying the options * -I/usr/sun/xinclude -I/usr/sun/include -I/usr/local/include * -I/usr/include after all other -I options. * * -N * Use no system search list. Suppresses the warning message * ordinarily printed when a header file cannot be found. This * option is useful when you are not interested in dependencies * on system include files. * * -e ext * Object files have extension ".ext". Defaults to .b if -V or -xV * is specified, .o otherwise. * * -d * Turn on debug output. Useful only to the maintainers. * * If the source files depend on any header files in standard system * include directories, one of the options -U, -V, -xV, or -N should * normally be specified. These four options are mutually exclusive. * If none of these options is given, only the directories specified * in -I options are included in the search list (as with the -N flag), * but warning messages are still printed for any header files that * cannot be found. */ #include "makedep.h" extern FILE *freopen(); main(argc, argv) int argc; char **argv; { Debug = 0; Initialize(); ProcessCommandLine(argc, argv); /* Redirect stdout to the output file. */ if (strcmp(OutputFileName, "-") != 0) { if (freopen(OutputFileName, "w", stdout) == NULL) { fprintf(stderr, "%s: can't open %s for writing.\n", MyName, OutputFileName); perror(OutputFileName); exit(errno); } } GenIncludeFileDependencies(); PrintDependencies(); exit(0); } /* * Initialize various program data structures and variables. */ Initialize() { /* Set up default option flag settings. */ NFlag = FALSE; UFlag = FALSE; VFlag = FALSE; xVFlag = FALSE; eFlag = FALSE; /* Set up default source and object extensions. */ strcpy(ObjExt, DefaultObjExt); /* Set up default output filename. */ strcpy(OutputFileName, DefaultOutputFileName); /* Set up default search list for include files. */ InclDirs = MakeList(); UserInclDirs = MakeList(); /* Empty to begin with. */ /* Set up default source directory list. */ SrcFiles = MakeList(); } /* * ProcessCommandLine: * Process user's command line. */ ProcessCommandLine(argc, argv) int argc; char **argv; { int nArg = 1; char *p; MyName = argv[0]; /* Parse command line options. */ while (nArg < argc) { if ( argv[nArg][0] == '-' ) { switch (argv[nArg][1] ) { case 'o': if (argv[nArg][2] == '\0') { p = argv[nArg+1]; /* Name is a separate input arg. */ nArg++; /* Incr. over the input arg. */ } else { p = &(argv[nArg][2]); /* Name is tacked onto the -o directly. */ } strcpy(OutputFileName, p); break; case 'I': if (argv[nArg][2] == '\0') { AddList(argv[nArg+1], UserInclDirs); /* Name is a separate input arg. */ nArg++; /* Incr. over the input arg. */ } else { AddList(&(argv[nArg][2]), UserInclDirs); /* Name is tacked onto the -I directly. */ } break; case 'N': NFlag = TRUE; break; case 'U': UFlag = TRUE; AddDefaultDirectoryLists(DefaultUnixInclDirs, InclDirs); break; case 'V': VFlag = TRUE; AddDefaultDirectoryLists(DefaultVInclDirs, InclDirs); if (!eFlag) strcpy(ObjExt, DefaultVObjExt); break; case 'x': /* xV */ if (argv[nArg][2] != 'V') goto badswitch; /* sorry, Edsger */ xVFlag = TRUE; AddDefaultDirectoryLists(DefaultXVInclDirs, InclDirs); if (!eFlag) strcpy(ObjExt, DefaultVObjExt); break; case 'e': eFlag = TRUE; if (argv[nArg][2] == '\0') { p = argv[nArg+1]; /* Name is a separate input arg. */ nArg++; /* Incr. over the input arg. */ } else { p = &(argv[nArg][2]); /* Name is tacked onto the -e directly. */ } strcpy(ObjExt, p); break; case 'd': Debug = TRUE; break; default: badswitch: fprintf(stderr, "%s: Unknown switch: %s\n", MyName, argv[nArg]); exit(1); } } else /* No more options */ { break; } nArg++; } if (NFlag + UFlag + VFlag + xVFlag > 1) { fprintf(stderr, "%s: -N, -U, -V, and -xV are mutually exclusive.\n", MyName); exit(1); } /* Add source files for which dependencies are to be found. */ while (nArg < argc) { AddList(argv[nArg], SrcFiles); nArg++; } /* Merge the list of user include directories with the list of "regular" include directories to get the final search path. */ MergeLists(UserInclDirs, InclDirs); if (Debug) { printf("NFlag: %d, UFlag: %d, VFlag: %d, xVFlag", NFlag, UFlag, VFlag, xVFlag); printf(" ObjExt: %s\n", ObjExt); printf("output filename: %s\n", OutputFileName); PrintList(SrcFiles, "SrcFiles"); PrintList(InclDirs, "InclDirs"); PrintList(UserInclDirs, "UserInclDirs"); } } /* * AddDefaultDirectoryLists: * Adds the directory names in dirs to the list l. * The names in dirs are separated by blanks. */ AddDefaultDirectoryLists(dirs, l) char *dirs; StringList l; { char *p, *p1; p = dirs; while (*p != '\0') { for (p1 = p; ((*p1 != ' ') && (*p1 != '\0')); p1++) ; while (*p1 == ' ') { *p1++ = '\0'; } AddList(p, l); p = p1; } } 965!Funky!Stuff! echo x - print.c cat > print.c << '965!Funky!Stuff!' /* * Module which prints out the dependencies of each source file to the * file OutputFileName. */ #include "makedep.h" extern char *rindex(); int CurrentMarkValue; /* This variable is used to keep track of which marking cycle is currently going on. Each source file's dependency graph is traversed using a new value of this variable. Dependency records are marked to avoid infinite recursions through a possibly cyclic dependency graph. */ /* * PrintDependencies: * Prints out the dependencies of each file on the source file list SrcFiles. * This is done by recursively printing the dependency list of each file. * I.e. each source file's dependency list is traversed and the print * routine is called to print the dependency list of each file on the list. * Since there may be cycles in the graph of dependencies, a marking scheme * is employed. */ PrintDependencies() { StringList *p; if (Debug) { printf("\nPrintDependencies:\n"); PrintList(IList, "IList"); for (p = SrcFiles->next; p != NULL; p = p->next) { CheckDepList(p); } } /* Mark all include file records' state with the same starting value. */ for (p = IList->next; p != NULL; p = p->next) { p->state = START_MARK_VALUE; } CurrentMarkValue = START_MARK_VALUE; /* Traverse the list source files and print the dependencies of each. */ for (p = SrcFiles->next; p != NULL; p = p->next) { if (p->dep != NULL) /* Don't print anything if there are no dependencies! */ { CurrentMarkValue++; PrintSrcObjFile(p); PrintDeps(p); printf("\n"); } } } /* * PrintSrcObjFile: * Print the source file name with its source extension replaced by its * object extension. Only the base name is printed. */ PrintSrcObjFile(p) StringList *p; { char name[80]; char *ptr; /* Replace the source file's extension with its object extension. */ strcpy(name, p->str); ptr = name + strlen(name); while ((ptr != name) && (*ptr != '.')) { ptr--; } if (ptr == name) { fprintf(stderr, "%s: malformed source file name: %s\n", MyName, p->str); exit(1); } ptr++; /* Get over the '.' */ strcpy(ptr, ObjExt); /* Find the start of the base name. */ ptr = rindex(name, '/'); if (ptr != NULL) { ptr++; } else { ptr = name; } /* Print out the first part of the appropriate makefile-style dependency line. */ printf("%s:", ptr); } /* * PrintDeps: * Recursive routine which prints out the dependencies for p and invokes * itself for all dependencies of dependencies of p. Uses a marking scheme * to avoid cycles in the dependency graph. */ PrintDeps(p) StringList *p; { DepList *ptr; StringList *p1; /* Traverse the list of immediate dependencies. */ for (ptr = p->dep; ptr != NULL; ptr = ptr->next) { p1 = ptr->inclFile; if (p1->state < CurrentMarkValue) { /* We've haven't yet seen this dependency. */ printf(" \\\n\t%s", p1->str); /* Print out the immediate dependency. */ p1->state = CurrentMarkValue; /* Mark the include file as already seen. */ PrintDeps(p1); /* Print out the dependency's dependencies. */ } } } 965!Funky!Stuff!
djhawley@wateng.UUCP (David J. Hawley) (10/16/84)
I think there is something wrong with the distribution. Where is "makedep.h" and why does the buildfile (/* you need buildmake */) include a non-existent file called "dependencies". David Hawley University of Waterloo
mann@CSL-Vax.ARPA (Tim Mann) (10/26/84)
> I think there is something wrong with the distribution. Where is "makedep.h" > and why does the buildfile (/* you need buildmake */) include a non-existent > file called "dependencies". > > David Hawley > University of Waterloo The missing "dependencies" is due to a circularity: makedep's buildfile uses makedep to build its own dependencies. You can start out with an empty "dependencies" file to make the initial makefile. I'm sorry if makedep.h got left out. I don't have the original shar archive anymore so I have no way of guessing what went wrong. At any rate, here it is: /* * Primary include file for makedep */ #include <stdio.h> #include <errno.h> #define FALSE 0 #define TRUE 1 extern int errno; int Debug; char *MyName; /* name by which makedep was invoked */ /* * List definitions */ /* StringList record states. */ #define HEADER 1 #define UNPROCESSED 2 #define PROCESSED 3 #define START_MARK_VALUE 4 typedef struct StringListType { char *str; int state; struct DepListType *dep; struct StringListType *next; } StringList; typedef struct DepListType { struct StringListType *inclFile; struct DepListType *next; } DepList; extern StringList *MakeList(); /* * Various string objects and their default defns. */ /* Extensions for object. */ #define DefaultObjExt "o" #define DefaultVObjExt "b" char ObjExt[16]; /* Source file list. */ StringList *SrcFiles; /* Search lists for include files. */ #define DefaultVInclDirs "/usr/sun/include /usr/local/include /usr/include" #define DefaultXVInclDirs "/usr/sun/xinclude /usr/sun/include /usr/local/include /usr/include" #define DefaultUnixInclDirs "/usr/include" StringList *InclDirs; StringList *UserInclDirs; /* Output file name. */ #define DefaultOutputFileName "dependencies" char OutputFileName[128]; /* Command line option flags */ int NFlag, UFlag, VFlag, xVFlag, eFlag; /* List of include files that have been encountered. */ StringList *IList; #define Equal(a,b) (strcmp(a,b) == 0)