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: }
Defined functions
Defined variables
Defined macros