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 $ */
32
extern struct inclist inclist[ MAXFILES ],
33
*inclistp, *inclistnext;
34
extern char *includedirs[ ],
36
extern char *notdotdot[ ];
37
extern boolean show_where_not;
38
extern boolean warn_multiple;
43
if(p && *p++ == '.' && *p++ == '\0')
51
if(p && *p++ == '.' && *p++ == '.' && *p++ == '\0')
57
issymbolic(char *dir, char *component)
61
char buf[ BUFSIZ ], **pp;
63
sprintf(buf, "%s%s%s", dir, *dir ? "/" : "", component);
64
for (pp=notdotdot; *pp; pp++)
65
if (strcmp(*pp, buf) == 0)
67
if (lstat(buf, &st) == 0
68
&& (st.st_mode & S_IFMT) == S_IFLNK) {
70
if (pp >= ¬dotdot[ MAXDIRS ])
71
fatalerr("out of .. dirs, increase MAXDIRS\n");
79
* Occasionally, pathnames are created that look like .../x/../y
80
* Any of the 'x/..' sequences within the name can be eliminated.
81
* (but only if 'x' is not a symbolic link!!)
84
remove_dotdot(char *path)
86
register char *end, *from, *to, **cp;
87
char *components[ MAXFILES ],
89
boolean component_copied;
92
* slice path up into components.
99
for (from=end=path; *end; end++)
111
* Recursively remove all 'x/..' component pairs.
115
if (!isdot(*cp) && !isdotdot(*cp) && isdotdot(*(cp+1))
116
&& !issymbolic(newpath, *cp))
122
*tp++ = *fp; /* move all the pointers down */
124
if (cp != components)
125
cp--; /* go back and check for nested ".." */
131
* Concatenate the remaining path elements.
134
component_copied = FALSE;
136
if (component_copied)
138
component_copied = TRUE;
139
for (from = *cp; *from; )
147
* copy the reconstituted path back to our pointer.
149
strcpy(path, newpath);
153
* Add an include file to the list of those included by 'file'.
156
newinclude(char *newfile, char *incstring)
158
register struct inclist *ip;
161
* First, put this file on the global list of include files.
164
if (inclistp == inclist + MAXFILES - 1)
165
fatalerr("out of space: increase MAXFILES\n");
166
ip->i_file = copy(newfile);
168
if (incstring == NULL)
169
ip->i_incstring = ip->i_file;
171
ip->i_incstring = copy(incstring);
173
inclistnext = inclistp;
178
included_by(struct inclist *ip, struct inclist *newfile)
185
* Put this include file (newfile) on the list of files included
186
* by 'file'. If 'file' is NULL, then it is not an include
187
* file itself (i.e. was probably mentioned on the command line).
188
* If it is already on the list, don't stick it on again.
190
if (ip->i_list == NULL) {
191
ip->i_list = (struct inclist **)
192
malloc(sizeof(struct inclist *) * ++ip->i_listlen);
193
ip->i_merged = (boolean *)
194
malloc(sizeof(boolean) * ip->i_listlen);
196
for (i=0; i<ip->i_listlen; i++)
197
if (ip->i_list[ i ] == newfile) {
198
i = strlen(newfile->i_file);
199
if (!(ip->i_flags & INCLUDED_SYM) &&
201
newfile->i_file[i-1] == 'c' &&
202
newfile->i_file[i-2] == '.'))
204
/* only bitch if ip has */
205
/* no #include SYMBOL lines */
206
/* and is not a .c file */
209
warning("%s includes %s more than once!\n",
210
ip->i_file, newfile->i_file);
211
warning1("Already have\n");
212
for (i=0; i<ip->i_listlen; i++)
213
warning1("\t%s\n", ip->i_list[i]->i_file);
218
ip->i_list = (struct inclist **) realloc(ip->i_list,
219
sizeof(struct inclist *) * ++ip->i_listlen);
220
ip->i_merged = (boolean *)
221
realloc(ip->i_merged, sizeof(boolean) * ip->i_listlen);
223
ip->i_list[ ip->i_listlen-1 ] = newfile;
224
ip->i_merged[ ip->i_listlen-1 ] = FALSE;
230
register struct inclist *ip;
232
for (ip = inclist; ip < inclistp; ip++) {
233
ip->i_flags &= ~MARKED;
238
inc_path(char *file, char *include, int type)
240
static char path[ BUFSIZ ];
241
register char **pp, *p;
242
register struct inclist *ip;
246
* Check all previously found include files for a path that
247
* has already been expanded.
249
if ((type == INCLUDE) || (type == INCLUDEDOT))
250
inclistnext = inclist;
253
for (; ip->i_file; ip++) {
254
if ((strcmp(ip->i_incstring, include) == 0) &&
255
!(ip->i_flags & INCLUDED_SYM)) {
256
inclistnext = ip + 1;
261
if (inclistnext == inclist) {
263
* If the path was surrounded by "" or is an absolute path,
264
* then check the exact path provided.
266
if ((type == INCLUDEDOT) ||
267
(type == INCLUDENEXTDOT) ||
269
if (stat(include, &st) == 0)
270
return newinclude(include, include);
272
warning1("\tnot in %s\n", include);
276
* If the path was surrounded by "" see if this include file is
277
* in the directory of the file being parsed.
279
if ((type == INCLUDEDOT) || (type == INCLUDENEXTDOT)) {
280
for (p=file+strlen(file); p>file; p--)
284
strcpy(path, include);
286
strncpy(path, file, (p-file) + 1);
287
path[ (p-file) + 1 ] = '\0';
288
strcpy(path + (p-file) + 1, include);
291
if (stat(path, &st) == 0)
292
return newinclude(path, include);
294
warning1("\tnot in %s\n", path);
299
* Check the include directories specified. Standard include dirs
300
* should be at the end.
302
if ((type == INCLUDE) || (type == INCLUDEDOT))
303
includedirsnext = includedirs;
304
pp = includedirsnext;
307
sprintf(path, "%s/%s", *pp, include);
309
if (stat(path, &st) == 0) {
310
includedirsnext = pp + 1;
311
return newinclude(path, include);
314
warning1("\tnot in %s\n", path);