2 * $XConsortium: include.c,v 1.6 88/09/22 13:52:38 jim Exp $
6 extern struct inclist inclist[ MAXFILES ],
8 extern char *includedirs[ ];
9 extern char *notdotdot[ ];
10 extern boolean show_where_not;
12 struct inclist *inc_path(file, include, dot)
17 static char path[ BUFSIZ ];
18 register char **pp, *p;
19 register struct inclist *ip;
21 boolean found = FALSE;
24 * Check all previously found include files for a path that
25 * has already been expanded.
27 for (ip = inclist; ip->i_file; ip++)
28 if ((strcmp(ip->i_incstring, include) == 0) && !ip->i_included_sym)
35 * If the path was surrounded by "", then check the absolute
39 if (stat(include, &st) == 0) {
40 ip = newinclude(include, include);
43 else if (show_where_not)
44 log("\tnot in %s\n", include);
48 * See if this include file is in the directory of the
49 * file being compiled.
52 for (p=file+strlen(file); p>file; p--)
56 strcpy(path, include);
58 strncpy(path, file, (p-file) + 1);
59 path[ (p-file) + 1 ] = '\0';
60 strcpy(path + (p-file) + 1, include);
63 if (stat(path, &st) == 0) {
64 ip = newinclude(path, include);
67 else if (show_where_not)
68 log("\tnot in %s\n", path);
72 * Check the include directories specified. (standard include dir
73 * should be at the end.)
76 for (pp = includedirs; *pp; pp++) {
77 sprintf(path, "%s/%s", *pp, include);
79 if (stat(path, &st) == 0) {
80 ip = newinclude(path, include);
84 else if (show_where_not)
85 log("\tnot in %s\n", path);
90 * If we've announced where it's not include it anyway so
91 * it gets on the dependency list.
94 ip = newinclude(include, include);
102 * Ocaisionally, pathnames are created that look like ../x/../y
103 * Any of the 'x/..' sequences within the name can be eliminated.
104 * (but only if 'x' is not a symbolic link!!)
109 register char *end, *from, *to, **cp;
110 char *components[ MAXFILES ],
112 boolean component_copied;
115 * slice path up into components.
122 for (from=end=path; *end; end++)
134 * Now copy the path, removing all 'x/..' components.
137 component_copied = FALSE;
139 if (!isdot(*cp) && !isdotdot(*cp) && isdotdot(*(cp+1))) {
140 if (issymbolic(newpath, *cp))
145 if (component_copied)
147 component_copied = TRUE;
148 for (from = *cp; *from; )
157 * copy the reconstituted path back to our pointer.
159 strcpy(path, newpath);
165 if(p && *p++ == '.' && *p++ == '\0')
173 if(p && *p++ == '.' && *p++ == '.' && *p++ == '\0')
178 issymbolic(dir, component)
179 register char *dir, *component;
182 char buf[ BUFSIZ ], **pp;
184 sprintf(buf, "%s%s%s", dir, *dir ? "/" : "", component);
185 for (pp=notdotdot; *pp; pp++)
186 if (strcmp(*pp, buf) == 0)
188 if (lstat(buf, &st) == 0
189 && (st.st_mode & S_IFMT) == S_IFLNK) {
191 if (pp >= ¬dotdot[ MAXDIRS ])
192 log_fatal("out of .. dirs, increase MAXDIRS\n");
199 * Add an include file to the list of those included by 'file'.
201 struct inclist *newinclude(newfile, incstring)
202 register char *newfile, *incstring;
204 register struct inclist *ip;
207 * First, put this file on the global list of include files.
210 if (inclistp == inclist + MAXFILES - 1)
211 log_fatal("out of space: increase MAXFILES\n");
212 ip->i_file = copy(newfile);
213 ip->i_included_sym = FALSE;
214 if (incstring == NULL)
215 ip->i_incstring = ip->i_file;
217 ip->i_incstring = copy(incstring);
222 included_by(ip, newfile)
223 register struct inclist *ip, *newfile;
230 * Put this include file (newfile) on the list of files included
231 * by 'file'. If 'file' is NULL, then it is not an include
232 * file itself (i.e. was probably mentioned on the command line).
233 * If it is already on the list, don't stick it on again.
235 if (ip->i_list == NULL)
236 ip->i_list = (struct inclist **)
237 malloc(sizeof(struct inclist *) * ++ip->i_listlen);
239 for (i=0; i<ip->i_listlen; i++)
240 if (ip->i_list[ i ] == newfile) {
241 if (!ip->i_included_sym)
243 /* only bitch if ip has */
244 /* no #include SYMBOL lines */
245 log("%s includes %s more than once!\n",
246 ip->i_file, newfile->i_file);
247 log("Already have\n");
248 for (i=0; i<ip->i_listlen; i++)
249 log("\t%s\n", ip->i_list[i]->i_file);
253 ip->i_list = (struct inclist **) realloc(ip->i_list,
254 sizeof(struct inclist *) * ++ip->i_listlen);
256 ip->i_list[ ip->i_listlen-1 ] = newfile;
261 register struct inclist *ip;
263 for (ip = inclist; ip < inclistp; ip++) {
264 ip->i_marked = FALSE;