|
|
1.1 ! root 1: /* $Header: dlist.c,v 1.1 85/04/23 13:56:29 nicklin Exp $ */ ! 2: ! 3: /* ! 4: * Author: Peter J. Nicklin ! 5: */ ! 6: #include <stdio.h> ! 7: #include "Mkmf.h" ! 8: #include "dlist.h" ! 9: #include "hash.h" ! 10: #include "null.h" ! 11: #include "slist.h" ! 12: #include "yesno.h" ! 13: ! 14: static HASHBLK *printtag = NULL; /* include files already printed */ ! 15: static int COLUMN; /* last column printed */ ! 16: ! 17: /* ! 18: * dlappend() adds a dependency chain block to the end of a list of ! 19: * dependency chain blocks. Each dependency chain block consists of a pointer ! 20: * to a source file name block contained in a singly-linked list, and a pointer ! 21: * to the head of the dependent list of included files. Returns a pointer to ! 22: * the dependency chain block, or a null pointer if out of memory. ! 23: */ ! 24: DLBLK * ! 25: dlappend(srctyp, srcblk, incblk, dlist) ! 26: int srctyp; /* source file type */ ! 27: SLBLK *srcblk; /* pointer to the source file block */ ! 28: INCBLK *incblk; /* included file dependency chain */ ! 29: DLIST *dlist; /* pointer to list head block */ ! 30: { ! 31: char *malloc(); /* memory allocator */ ! 32: DLBLK *dblk; /* pointer to dependency list block */ ! 33: ! 34: if (dlist == NULL) ! 35: return(NULL); ! 36: if ((dblk = (DLBLK *) malloc(sizeof(DLBLK))) == NULL) ! 37: { ! 38: warn("out of memory"); ! 39: return(NULL); ! 40: } ! 41: dblk->d_src = srcblk; ! 42: dblk->d_type = srctyp; ! 43: dblk->d_incl = incblk; ! 44: dblk->d_next = NULL; ! 45: if (dlist->d_tail == NULL) ! 46: { ! 47: dlist->d_head = dlist->d_tail = dblk; ! 48: } ! 49: else { ! 50: dlist->d_tail = dlist->d_tail->d_next = dblk; ! 51: } ! 52: return(dblk); ! 53: } ! 54: ! 55: ! 56: ! 57: /* ! 58: * dlinit() returns a pointer to the head block of a dependency list, or ! 59: * null pointer if out of memory. ! 60: */ ! 61: DLIST * ! 62: dlinit() ! 63: { ! 64: char *malloc(); /* memory allocator */ ! 65: DLIST *dlist; /* pointer to list head block */ ! 66: ! 67: if ((dlist = (DLIST *) malloc(sizeof(DLIST))) == NULL) ! 68: { ! 69: warn("out of memory"); ! 70: return(NULL); ! 71: } ! 72: dlist->d_head = dlist->d_tail = NULL; ! 73: return(dlist); ! 74: } ! 75: ! 76: ! 77: ! 78: /* ! 79: * dlprint() appends the object-include file dependencies to the end of ! 80: * a makefile. Transitive closure is checked by making suring that an ! 81: * object-include file dependency is not generated if the source file is ! 82: * included in another file. ! 83: */ ! 84: void ! 85: dlprint(dlist, ofp) ! 86: DLIST *dlist; /* dependency list */ ! 87: FILE *ofp; /* output stream */ ! 88: { ! 89: DLBLK *dblk; /* pointer to dependency list block */ ! 90: HASHBLK *lookupinclude(); /* look up include name in hash table */ ! 91: INCBLK *iblk; /* cur. include file hash table blk */ ! 92: void putinchain(); /* output nested subinclude filenames */ ! 93: void putobjd(); /* output object file name */ ! 94: void rmprinttag(); /* remove "already printed" tags */ ! 95: ! 96: fprintf(ofp, "%s\n", DEPENDMARK); ! 97: for (dblk=dlist->d_head; dblk != NULL; dblk=dblk->d_next) ! 98: { ! 99: if (lookupinclude(dblk->d_src->key, dblk->d_type) == NULL) ! 100: { ! 101: putobjd(dblk->d_src, ofp); ! 102: for (iblk=dblk->d_incl; iblk != NULL; iblk=iblk->i_next) ! 103: { ! 104: putinchain(iblk->i_hblk, ofp); ! 105: } ! 106: fprintf(ofp, "\n"); ! 107: rmprinttag(); ! 108: } ! 109: } ! 110: } ! 111: ! 112: ! 113: ! 114: /* ! 115: * putinchain() outputs a chain of nested include file names. It changes ! 116: * the sign of each chain block h_val field as it traverses the chain to ! 117: * detect looping. ! 118: */ ! 119: static void ! 120: putinchain(htb, ofp) ! 121: HASHBLK *htb; /* hash table blk including chain */ ! 122: FILE *ofp; /* output stream */ ! 123: { ! 124: INCBLK *iblk; /* cur. include file hash table blk */ ! 125: void putinclude(); /* output include file pathname */ ! 126: void putinchain(); /* output nested subinclude file names*/ ! 127: ! 128: putinclude(htb, ofp); ! 129: htb->h_val = -htb->h_val; ! 130: for (iblk=htb->h_sub; iblk != NULL; iblk=iblk->i_next) ! 131: { ! 132: if (iblk->i_hblk->h_val < 0) ! 133: { ! 134: if (iblk->i_loop == NO) ! 135: { ! 136: warn2("recursive include nesting of \"%s\" in \"%s\"", ! 137: iblk->i_hblk->h_def, htb->h_def); ! 138: iblk->i_loop = YES; ! 139: } ! 140: continue; ! 141: } ! 142: putinchain(iblk->i_hblk, ofp); ! 143: } ! 144: htb->h_val = -htb->h_val; ! 145: } ! 146: ! 147: ! 148: ! 149: #define MAXLINE 80 ! 150: #define TABSIZE 8 ! 151: ! 152: /* ! 153: * putinclude() writes an include file pathname to stream ofp if ! 154: * if it has not already been written on the current dependency line. ! 155: * and adds the hash block containing the file pathname to the ! 156: * "already printed" printtag list. The last block on the list ! 157: * points back onto itself rather than at NULL so that the non-NULL ! 158: * tag will indicate that the filename has already been seen. ! 159: */ ! 160: static void ! 161: putinclude(htb, ofp) ! 162: HASHBLK *htb; /* include file hash block */ ! 163: FILE *ofp; /* output stream */ ! 164: { ! 165: if (htb->h_tag == NULL) ! 166: { ! 167: COLUMN += htb->h_val + 1; ! 168: if (COLUMN >= (MAXLINE - 2)) ! 169: { ! 170: fprintf(ofp, " \\\n\t%s", htb->h_def); ! 171: COLUMN = htb->h_val + TABSIZE; ! 172: } ! 173: else { ! 174: fprintf(ofp, " %s", htb->h_def); ! 175: } ! 176: /* add to "already printed" filenames */ ! 177: htb->h_tag = (printtag == NULL) ? htb :printtag; ! 178: printtag = htb; ! 179: } ! 180: } ! 181: ! 182: ! 183: ! 184: /* ! 185: * putobjd() writes an object file dependency name. ! 186: */ ! 187: static void ! 188: putobjd(srcblk, ofp) ! 189: SLBLK *srcblk; /* source file name list block */ ! 190: FILE *ofp; /* output stream */ ! 191: { ! 192: extern char OBJSFX[]; /* object file name suffix */ ! 193: int strlen(); /* string length */ ! 194: void putobj(); /* output object file name */ ! 195: ! 196: COLUMN = strlen(srcblk->key) + strlen(OBJSFX) + 1; ! 197: putobj(srcblk->key, ofp); ! 198: fprintf(ofp, ":"); ! 199: } ! 200: ! 201: ! 202: ! 203: /* ! 204: * rmprinttag() removes the chain of tags indicating that an include ! 205: * file dependency has already been printed for the current source file. ! 206: */ ! 207: static void ! 208: rmprinttag() ! 209: { ! 210: register HASHBLK *curhtb; /* current hash table block */ ! 211: register HASHBLK *nxthtb; /* next hash table block */ ! 212: ! 213: for (curhtb = printtag; curhtb != NULL; curhtb = nxthtb) ! 214: { ! 215: nxthtb = curhtb->h_tag; ! 216: curhtb->h_tag = NULL; ! 217: } ! 218: printtag = NULL; ! 219: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.