1 /* $Xorg: include.c,v 1.4 2001/02/09 02:03:16 xorgcvs Exp $ */
4 Copyright (c) 1993, 1994, 1998 The Open Group
6 Permission to use, copy, modify, distribute, and sell this software and its
7 documentation for any purpose is hereby granted without fee, provided that
8 the above copyright notice appear in all copies and that both that
9 copyright notice and this permission notice appear in supporting
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 Except as contained in this notice, the name of The Open Group shall not be
23 used in advertising or otherwise to promote the sale, use or other dealings
24 in this Software without prior written authorization from The Open Group.
27 /* $XFree86: xc/config/makedepend/include.c,v 3.7 2001/12/14 19:53:20 dawes Exp $ */
35 does_file_exist(char *file)
37 WIN32_FILE_ATTRIBUTE_DATA data;
38 BOOL b = GetFileAttributesExA(file, GetFileExInfoStandard, &data);
41 return (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0;
45 does_file_exist(char *file)
48 return stat(file, &sb) == 0 && !S_ISDIR(sb.st_mode);
52 extern struct inclist inclist[ MAXFILES ],
53 *inclistp, *inclistnext;
54 extern char *includedirs[ ],
56 extern char *notdotdot[ ];
57 extern boolean show_where_not;
58 extern boolean warn_multiple;
63 if(p && *p++ == '.' && *p++ == '\0')
71 if(p && *p++ == '.' && *p++ == '.' && *p++ == '\0')
77 issymbolic(char *dir, char *component)
81 char buf[ BUFSIZ ], **pp;
83 sprintf(buf, "%s%s%s", dir, *dir ? "/" : "", component);
84 for (pp=notdotdot; *pp; pp++)
85 if (strcmp(*pp, buf) == 0)
87 if (lstat(buf, &st) == 0
88 && (st.st_mode & S_IFMT) == S_IFLNK) {
90 if (pp >= ¬dotdot[ MAXDIRS ])
91 fatalerr("out of .. dirs, increase MAXDIRS\n");
99 * Occasionally, pathnames are created that look like .../x/../y
100 * Any of the 'x/..' sequences within the name can be eliminated.
101 * (but only if 'x' is not a symbolic link!!)
104 remove_dotdot(char *path)
106 register char *end, *from, *to, **cp;
107 char *components[ MAXFILES ],
109 boolean component_copied;
112 * slice path up into components.
119 for (from=end=path; *end; end++)
131 * Recursively remove all 'x/..' component pairs.
135 if (!isdot(*cp) && !isdotdot(*cp) && isdotdot(*(cp+1))
136 && !issymbolic(newpath, *cp))
142 *tp++ = *fp; /* move all the pointers down */
144 if (cp != components)
145 cp--; /* go back and check for nested ".." */
151 * Concatenate the remaining path elements.
154 component_copied = FALSE;
156 if (component_copied)
158 component_copied = TRUE;
159 for (from = *cp; *from; )
167 * copy the reconstituted path back to our pointer.
169 strcpy(path, newpath);
173 * Add an include file to the list of those included by 'file'.
176 newinclude(char *newfile, char *incstring)
178 register struct inclist *ip;
181 * First, put this file on the global list of include files.
184 if (inclistp == inclist + MAXFILES - 1)
185 fatalerr("out of space: increase MAXFILES\n");
186 ip->i_file = copy(newfile);
188 if (incstring == NULL)
189 ip->i_incstring = ip->i_file;
191 ip->i_incstring = copy(incstring);
193 inclistnext = inclistp;
198 included_by(struct inclist *ip, struct inclist *newfile)
205 * Put this include file (newfile) on the list of files included
206 * by 'file'. If 'file' is NULL, then it is not an include
207 * file itself (i.e. was probably mentioned on the command line).
208 * If it is already on the list, don't stick it on again.
210 if (ip->i_list == NULL) {
211 ip->i_list = (struct inclist **)
212 malloc(sizeof(struct inclist *) * ++ip->i_listlen);
213 ip->i_merged = (boolean *)
214 malloc(sizeof(boolean) * ip->i_listlen);
216 for (i=0; i<ip->i_listlen; i++)
217 if (ip->i_list[ i ] == newfile) {
218 i = strlen(newfile->i_file);
219 if (!(ip->i_flags & INCLUDED_SYM) &&
221 newfile->i_file[i-1] == 'c' &&
222 newfile->i_file[i-2] == '.'))
224 /* only bitch if ip has */
225 /* no #include SYMBOL lines */
226 /* and is not a .c file */
229 warning("%s includes %s more than once!\n",
230 ip->i_file, newfile->i_file);
231 warning1("Already have\n");
232 for (i=0; i<ip->i_listlen; i++)
233 warning1("\t%s\n", ip->i_list[i]->i_file);
238 ip->i_list = (struct inclist **) realloc(ip->i_list,
239 sizeof(struct inclist *) * ++ip->i_listlen);
240 ip->i_merged = (boolean *)
241 realloc(ip->i_merged, sizeof(boolean) * ip->i_listlen);
243 ip->i_list[ ip->i_listlen-1 ] = newfile;
244 ip->i_merged[ ip->i_listlen-1 ] = FALSE;
250 register struct inclist *ip;
252 for (ip = inclist; ip < inclistp; ip++) {
253 ip->i_flags &= ~MARKED;
258 inc_path(char *file, char *include, int type)
260 static char path[ BUFSIZ ];
261 register char **pp, *p;
262 register struct inclist *ip;
265 * Check all previously found include files for a path that
266 * has already been expanded.
268 if ((type == INCLUDE) || (type == INCLUDEDOT))
269 inclistnext = inclist;
272 for (; ip->i_file; ip++) {
273 if ((strcmp(ip->i_incstring, include) == 0) &&
274 !(ip->i_flags & INCLUDED_SYM)) {
275 inclistnext = ip + 1;
280 if (inclistnext == inclist) {
282 * If the path was surrounded by "" or is an absolute path,
283 * then check the exact path provided.
285 if ((type == INCLUDEDOT) ||
286 (type == INCLUDENEXTDOT) ||
288 if (does_file_exist(include))
289 return newinclude(include, include);
291 warning1("\tnot in %s\n", include);
295 * If the path was surrounded by "" see if this include file is
296 * in the directory of the file being parsed.
298 if ((type == INCLUDEDOT) || (type == INCLUDENEXTDOT)) {
299 for (p=file+strlen(file); p>file; p--)
303 strcpy(path, include);
305 strncpy(path, file, (p-file) + 1);
306 path[ (p-file) + 1 ] = '\0';
307 strcpy(path + (p-file) + 1, include);
310 if (does_file_exist(path))
311 return newinclude(path, include);
313 warning1("\tnot in %s\n", path);
318 * Check the include directories specified. Standard include dirs
319 * should be at the end.
321 if ((type == INCLUDE) || (type == INCLUDEDOT))
322 includedirsnext = includedirs;
323 pp = includedirsnext;
326 sprintf(path, "%s/%s", *pp, include);
328 if (does_file_exist(path)) {
329 includedirsnext = pp + 1;
330 return newinclude(path, include);
333 warning1("\tnot in %s\n", path);