|
|
1.1 root 1: /*
2: * $Header: include.c,v 1.3 87/08/14 18:14:41 toddb Exp $
3: *
4: * $Log: include.c,v $
5: * Revision 1.3 87/08/14 18:14:41 toddb
6: * Add the routine inc_clean(). This will "un-mark" all nodes after traversal,
7: * so that during traversal, no node is printed more than once.
8: *
9: * Revision 1.2 87/08/06 17:40:34 toddb
10: * Bug in removing .. (removedotdot).
11: *
12: * Revision 1.1 87/08/06 17:34:55 toddb
13: * Initial revision
14: *
15: * Revision 1.1 87/04/08 16:40:43 rich
16: * Initial revision
17: *
18: * Revision 1.1 86/04/15 08:34:26 toddb
19: * Initial revision
20: *
21: */
22: #include "def.h"
23:
24: extern struct inclist inclist[ MAXFILES ],
25: *inclistp;
26: extern char *includedirs[ ];
27: extern char *notdotdot[ ];
28: extern boolean show_where_not;
29:
30: struct inclist *inc_path(file, include, dot)
31: register char *file,
32: *include;
33: boolean dot;
34: {
35: static char path[ BUFSIZ ];
36: register char **pp, *p;
37: register struct inclist *ip;
38: struct stat st;
39: boolean found = FALSE;
40:
41: /*
42: * Check all previously found include files for a path that
43: * has already been expanded.
44: */
45: for (ip = inclist; ip->i_file; ip++)
46: if (strcmp(ip->i_incstring, include) == 0) {
47: found = TRUE;
48: break;
49: }
50:
51: /*
52: * If the path was surrounded by "", then check the absolute
53: * path provided.
54: */
55: if (!found && dot) {
56: if (stat(include, &st) == 0) {
57: ip = newinclude(include, include);
58: found = TRUE;
59: }
60: else if (show_where_not)
61: log("\tnot in %s\n", include);
62: }
63:
64: /*
65: * See if this include file is in the directory of the
66: * file being compiled.
67: */
68: if (!found) {
69: for (p=file+strlen(file); p>file; p--)
70: if (*p == '/')
71: break;
72: if (p == file)
73: strcpy(path, include);
74: else {
75: strncpy(path, file, (p-file) + 1);
76: path[ (p-file) + 1 ] = '\0';
77: strcpy(path + (p-file) + 1, include);
78: }
79: remove_dotdot(path);
80: if (stat(path, &st) == 0) {
81: ip = newinclude(path, include);
82: found = TRUE;
83: }
84: else if (show_where_not)
85: log("\tnot in %s\n", path);
86: }
87:
88: /*
89: * Check the include directories specified. (standard include dir
90: * should be at the end.)
91: */
92: if (!found)
93: for (pp = includedirs; *pp; pp++) {
94: sprintf(path, "%s/%s", *pp, include);
95: remove_dotdot(path);
96: if (stat(path, &st) == 0) {
97: ip = newinclude(path, include);
98: found = TRUE;
99: break;
100: }
101: else if (show_where_not)
102: log("\tnot in %s\n", path);
103: }
104:
105: if (!found) {
106: /*
107: * If we've announced where it's not include it anyway so
108: * it gets on the dependency list.
109: */
110: if (show_where_not)
111: ip = newinclude(include, include);
112: else
113: ip = NULL;
114: }
115: return(ip);
116: }
117:
118: /*
119: * Ocaisionally, pathnames are created that look like ../x/../y
120: * Any of the 'x/..' sequences within the name can be eliminated.
121: * (but only if 'x' is not a symbolic link!!)
122: */
123: remove_dotdot(path)
124: char *path;
125: {
126: register char *end, *from, *to, **cp;
127: char *components[ MAXFILES ],
128: newpath[ BUFSIZ ];
129: boolean component_copied;
130:
131: /*
132: * slice path up into components.
133: */
134: to = newpath;
135: if (*path == '/')
136: *to++ = '/';
137: *to = '\0';
138: cp = components;
139: for (from=end=path; *end; end++)
140: if (*end == '/') {
141: while (*end == '/')
142: *end++ = '\0';
143: if (*from)
144: *cp++ = from;
145: from = end;
146: }
147: *cp++ = from;
148: *cp = NULL;
149:
150: /*
151: * Now copy the path, removing all 'x/..' components.
152: */
153: cp = components;
154: component_copied = FALSE;
155: while(*cp) {
156: if (!isdot(*cp) && !isdotdot(*cp) && isdotdot(*(cp+1))) {
157: if (issymbolic(newpath, *cp))
158: goto dont_remove;
159: cp++;
160: } else {
161: dont_remove:
162: if (component_copied)
163: *to++ = '/';
164: component_copied = TRUE;
165: for (from = *cp; *from; )
166: *to++ = *from++;
167: *to = '\0';
168: }
169: cp++;
170: }
171: *to++ = '\0';
172:
173: /*
174: * copy the reconstituted path back to our pointer.
175: */
176: strcpy(path, newpath);
177: }
178:
179: isdot(p)
180: register char *p;
181: {
182: if(p && *p++ == '.' && *p++ == '\0')
183: return(TRUE);
184: return(FALSE);
185: }
186:
187: isdotdot(p)
188: register char *p;
189: {
190: if(p && *p++ == '.' && *p++ == '.' && *p++ == '\0')
191: return(TRUE);
192: return(FALSE);
193: }
194:
195: issymbolic(dir, component)
196: register char *dir, *component;
197: {
198: struct stat st;
199: char buf[ BUFSIZ ], **pp;
200:
201: sprintf(buf, "%s%s%s", dir, *dir ? "/" : "", component);
202: for (pp=notdotdot; *pp; pp++)
203: if (strcmp(*pp, buf) == 0)
204: return (TRUE);
205: if (lstat(buf, &st) == 0
206: && (st.st_mode & S_IFMT) == S_IFLNK) {
207: *pp++ = copy(buf);
208: if (pp >= ¬dotdot[ MAXDIRS ])
209: log_fatal("out of .. dirs, increase MAXDIRS\n");
210: return(TRUE);
211: }
212: return(FALSE);
213: }
214:
215: /*
216: * Add an include file to the list of those included by 'file'.
217: */
218: struct inclist *newinclude(newfile, incstring)
219: register char *newfile, *incstring;
220: {
221: register struct inclist *ip;
222:
223: /*
224: * First, put this file on the global list of include files.
225: */
226: ip = inclistp++;
227: if (inclistp == inclist + MAXFILES - 1)
228: log_fatal("out of space: increase MAXFILES\n");
229: ip->i_file = copy(newfile);
230: if (incstring == NULL)
231: ip->i_incstring = ip->i_file;
232: else
233: ip->i_incstring = copy(incstring);
234:
235: return(ip);
236: }
237:
238: included_by(ip, newfile)
239: register struct inclist *ip, *newfile;
240: {
241: register i;
242:
243: if (ip == NULL)
244: return;
245: /*
246: * Put this include file (newfile) on the list of files included
247: * by 'file'. If 'file' is NULL, then it is not an include
248: * file itself (i.e. was probably mentioned on the command line).
249: * If it is already on the list, don't stick it on again.
250: */
251: if (ip->i_list == NULL)
252: ip->i_list = (struct inclist **)
253: malloc(sizeof(struct inclist *) * ++ip->i_listlen);
254: else {
255: for (i=0; i<ip->i_listlen; i++)
256: if (ip->i_list[ i ] == newfile) {
257: log("%s includes %s more than once!\n",
258: ip->i_file, newfile->i_file);
259: log("Already have\n");
260: for (i=0; i<ip->i_listlen; i++)
261: log("\t%s\n", ip->i_list[i]->i_file);
262: return;
263: }
264: ip->i_list = (struct inclist **) realloc(ip->i_list,
265: sizeof(struct inclist *) * ++ip->i_listlen);
266: }
267: ip->i_list[ ip->i_listlen-1 ] = newfile;
268: }
269:
270: inc_clean ()
271: {
272: register struct inclist *ip;
273:
274: for (ip = inclist; ip < inclistp; ip++) {
275: ip->i_marked = FALSE;
276: }
277: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.