1 /* $Xorg: include.c,v 1.3 2000/08/17 19:41:51 cpqbld Exp $ */
4 Copyright (c) 1993, 1994, 1998 The Open Group
8 The above copyright notice and this permission notice shall be included in
9 all copies or substantial portions of the Software.
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
15 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18 Except as contained in this notice, the name of The Open Group shall not be
19 used in advertising or otherwise to promote the sale, use or other dealings
20 in this Software without prior written authorization from The Open Group.
23 /* $XFree86: xc/config/makedepend/include.c,v 3.6 2001/04/29 23:25:02 tsi Exp $ */
28 extern struct inclist inclist
[ MAXFILES
],
29 *inclistp
, *inclistnext
;
30 extern char *includedirs
[ ],
32 extern char *notdotdot
[ ];
33 extern boolean show_where_not
;
34 extern boolean warn_multiple
;
39 if(p
&& *p
++ == '.' && *p
++ == '\0')
47 if(p
&& *p
++ == '.' && *p
++ == '.' && *p
++ == '\0')
53 issymbolic(char *dir
, char *component
)
57 char buf
[ BUFSIZ
], **pp
;
59 sprintf(buf
, "%s%s%s", dir
, *dir
? "/" : "", component
);
60 for (pp
=notdotdot
; *pp
; pp
++)
61 if (strcmp(*pp
, buf
) == 0)
63 if (lstat(buf
, &st
) == 0
64 && (st
.st_mode
& S_IFMT
) == S_IFLNK
) {
66 if (pp
>= ¬dotdot
[ MAXDIRS
])
67 fatalerr("out of .. dirs, increase MAXDIRS\n");
75 * Occasionally, pathnames are created that look like .../x/../y
76 * Any of the 'x/..' sequences within the name can be eliminated.
77 * (but only if 'x' is not a symbolic link!!)
80 remove_dotdot(char *path
)
82 register char *end
, *from
, *to
, **cp
;
83 char *components
[ MAXFILES
],
85 boolean component_copied
;
88 * slice path up into components.
95 for (from
=end
=path
; *end
; end
++)
107 * Recursively remove all 'x/..' component pairs.
111 if (!isdot(*cp
) && !isdotdot(*cp
) && isdotdot(*(cp
+1))
112 && !issymbolic(newpath
, *cp
))
118 *tp
++ = *fp
; /* move all the pointers down */
120 if (cp
!= components
)
121 cp
--; /* go back and check for nested ".." */
127 * Concatenate the remaining path elements.
130 component_copied
= FALSE
;
132 if (component_copied
)
134 component_copied
= TRUE
;
135 for (from
= *cp
; *from
; )
143 * copy the reconstituted path back to our pointer.
145 strcpy(path
, newpath
);
149 * Add an include file to the list of those included by 'file'.
152 newinclude(char *newfile
, char *incstring
)
154 register struct inclist
*ip
;
157 * First, put this file on the global list of include files.
160 if (inclistp
== inclist
+ MAXFILES
- 1)
161 fatalerr("out of space: increase MAXFILES\n");
162 ip
->i_file
= copy(newfile
);
164 if (incstring
== NULL
)
165 ip
->i_incstring
= ip
->i_file
;
167 ip
->i_incstring
= copy(incstring
);
169 inclistnext
= inclistp
;
174 included_by(struct inclist
*ip
, struct inclist
*newfile
)
181 * Put this include file (newfile) on the list of files included
182 * by 'file'. If 'file' is NULL, then it is not an include
183 * file itself (i.e. was probably mentioned on the command line).
184 * If it is already on the list, don't stick it on again.
186 if (ip
->i_list
== NULL
) {
187 ip
->i_list
= (struct inclist
**)
188 malloc(sizeof(struct inclist
*) * ++ip
->i_listlen
);
189 ip
->i_merged
= (boolean
*)
190 malloc(sizeof(boolean
) * ip
->i_listlen
);
192 for (i
=0; i
<ip
->i_listlen
; i
++)
193 if (ip
->i_list
[ i
] == newfile
) {
194 i
= strlen(newfile
->i_file
);
195 if (!(ip
->i_flags
& INCLUDED_SYM
) &&
197 newfile
->i_file
[i
-1] == 'c' &&
198 newfile
->i_file
[i
-2] == '.'))
200 /* only bitch if ip has */
201 /* no #include SYMBOL lines */
202 /* and is not a .c file */
205 warning("%s includes %s more than once!\n",
206 ip
->i_file
, newfile
->i_file
);
207 warning1("Already have\n");
208 for (i
=0; i
<ip
->i_listlen
; i
++)
209 warning1("\t%s\n", ip
->i_list
[i
]->i_file
);
214 ip
->i_list
= (struct inclist
**) realloc(ip
->i_list
,
215 sizeof(struct inclist
*) * ++ip
->i_listlen
);
216 ip
->i_merged
= (boolean
*)
217 realloc(ip
->i_merged
, sizeof(boolean
) * ip
->i_listlen
);
219 ip
->i_list
[ ip
->i_listlen
-1 ] = newfile
;
220 ip
->i_merged
[ ip
->i_listlen
-1 ] = FALSE
;
226 register struct inclist
*ip
;
228 for (ip
= inclist
; ip
< inclistp
; ip
++) {
229 ip
->i_flags
&= ~MARKED
;
234 inc_path(char *file
, char *include
, int type
)
236 static char path
[ BUFSIZ
];
237 register char **pp
, *p
;
238 register struct inclist
*ip
;
242 * Check all previously found include files for a path that
243 * has already been expanded.
245 if ((type
== INCLUDE
) || (type
== INCLUDEDOT
))
246 inclistnext
= inclist
;
249 for (; ip
->i_file
; ip
++) {
250 if ((strcmp(ip
->i_incstring
, include
) == 0) &&
251 !(ip
->i_flags
& INCLUDED_SYM
)) {
252 inclistnext
= ip
+ 1;
257 if (inclistnext
== inclist
) {
259 * If the path was surrounded by "" or is an absolute path,
260 * then check the exact path provided.
262 if ((type
== INCLUDEDOT
) ||
263 (type
== INCLUDENEXTDOT
) ||
265 if (stat(include
, &st
) == 0)
266 return newinclude(include
, include
);
268 warning1("\tnot in %s\n", include
);
272 * If the path was surrounded by "" see if this include file is
273 * in the directory of the file being parsed.
275 if ((type
== INCLUDEDOT
) || (type
== INCLUDENEXTDOT
)) {
276 for (p
=file
+strlen(file
); p
>file
; p
--)
280 strcpy(path
, include
);
282 strncpy(path
, file
, (p
-file
) + 1);
283 path
[ (p
-file
) + 1 ] = '\0';
284 strcpy(path
+ (p
-file
) + 1, include
);
287 if (stat(path
, &st
) == 0)
288 return newinclude(path
, include
);
290 warning1("\tnot in %s\n", path
);
295 * Check the include directories specified. Standard include dirs
296 * should be at the end.
298 if ((type
== INCLUDE
) || (type
== INCLUDEDOT
))
299 includedirsnext
= includedirs
;
300 pp
= includedirsnext
;
303 sprintf(path
, "%s/%s", *pp
, include
);
305 if (stat(path
, &st
) == 0) {
306 includedirsnext
= pp
+ 1;
307 return newinclude(path
, include
);
310 warning1("\tnot in %s\n", path
);