VirtualBox

source: kBuild/trunk/src/makedep/include.c@ 171

Last change on this file since 171 was 168, checked in by bird, 20 years ago

Merged in mozilla changes and config.

  • Property svn:eol-style set to native
File size: 7.8 KB
Line 
1/* $Xorg: include.c,v 1.4 2001/02/09 02:03:16 xorgcvs Exp $ */
2/*
3
4Copyright (c) 1993, 1994, 1998 The Open Group
5
6Permission to use, copy, modify, distribute, and sell this software and its
7documentation for any purpose is hereby granted without fee, provided that
8the above copyright notice appear in all copies and that both that
9copyright notice and this permission notice appear in supporting
10documentation.
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall not be
23used in advertising or otherwise to promote the sale, use or other dealings
24in this Software without prior written authorization from The Open Group.
25
26*/
27/* $XFree86: xc/config/makedepend/include.c,v 3.6 2001/04/29 23:25:02 tsi Exp $ */
28
29
30#include "def.h"
31
32/* mozilla: */
33#ifdef _MSC_VER
34#define S_ISDIR(m) (((m) & _S_IFDIR) == _S_IFDIR)
35#endif
36
37extern struct inclist inclist[ MAXFILES ],
38 *inclistp, *inclistnext;
39extern char *includedirs[ ],
40 **includedirsnext;
41extern char *notdotdot[ ];
42extern boolean show_where_not;
43extern boolean warn_multiple;
44
45static boolean
46isdot(char *p)
47{
48 if(p && *p++ == '.' && *p++ == '\0')
49 return(TRUE);
50 return(FALSE);
51}
52
53static boolean
54isdotdot(char *p)
55{
56 if(p && *p++ == '.' && *p++ == '.' && *p++ == '\0')
57 return(TRUE);
58 return(FALSE);
59}
60
61static boolean
62issymbolic(char *dir, char *component)
63{
64#ifdef S_IFLNK
65 struct stat st;
66 char buf[ BUFSIZ ], **pp;
67
68 sprintf(buf, "%s%s%s", dir, *dir ? "/" : "", component);
69 for (pp=notdotdot; *pp; pp++)
70 if (strcmp(*pp, buf) == 0)
71 return (TRUE);
72 if (lstat(buf, &st) == 0
73 && (st.st_mode & S_IFMT) == S_IFLNK) {
74 *pp++ = copy(buf);
75 if (pp >= &notdotdot[ MAXDIRS ])
76 fatalerr("out of .. dirs, increase MAXDIRS\n");
77 return(TRUE);
78 }
79#endif
80 return(FALSE);
81}
82
83/*
84 * Occasionally, pathnames are created that look like .../x/../y
85 * Any of the 'x/..' sequences within the name can be eliminated.
86 * (but only if 'x' is not a symbolic link!!)
87 */
88static void
89remove_dotdot(char *path)
90{
91 register char *end, *from, *to, **cp;
92 char *components[ MAXFILES ],
93 newpath[ BUFSIZ ];
94 boolean component_copied;
95
96 /*
97 * slice path up into components.
98 */
99 to = newpath;
100 if (*path == '/')
101 *to++ = '/';
102 *to = '\0';
103 cp = components;
104 for (from=end=path; *end; end++)
105 if (*end == '/') {
106 while (*end == '/')
107 *end++ = '\0';
108 if (*from)
109 *cp++ = from;
110 from = end;
111 }
112 *cp++ = from;
113 *cp = NULL;
114
115 /*
116 * Recursively remove all 'x/..' component pairs.
117 */
118 cp = components;
119 while(*cp) {
120 if (!isdot(*cp) && !isdotdot(*cp) && isdotdot(*(cp+1))
121 && !issymbolic(newpath, *cp))
122 {
123 char **fp = cp + 2;
124 char **tp = cp;
125
126 do
127 *tp++ = *fp; /* move all the pointers down */
128 while (*fp++);
129 if (cp != components)
130 cp--; /* go back and check for nested ".." */
131 } else {
132 cp++;
133 }
134 }
135 /*
136 * Concatenate the remaining path elements.
137 */
138 cp = components;
139 component_copied = FALSE;
140 while(*cp) {
141 if (component_copied)
142 *to++ = '/';
143 component_copied = TRUE;
144 for (from = *cp; *from; )
145 *to++ = *from++;
146 *to = '\0';
147 cp++;
148 }
149 *to++ = '\0';
150
151 /*
152 * copy the reconstituted path back to our pointer.
153 */
154 strcpy(path, newpath);
155}
156
157/*
158 * Add an include file to the list of those included by 'file'.
159 */
160struct inclist *
161newinclude(char *newfile, char *incstring)
162{
163 register struct inclist *ip;
164
165 /*
166 * First, put this file on the global list of include files.
167 */
168 ip = inclistp++;
169 if (inclistp == inclist + MAXFILES - 1)
170 fatalerr("out of space: increase MAXFILES\n");
171 ip->i_file = copy(newfile);
172
173 if (incstring == NULL)
174 ip->i_incstring = ip->i_file;
175 else
176 ip->i_incstring = copy(incstring);
177
178 inclistnext = inclistp;
179 return(ip);
180}
181
182void
183included_by(struct inclist *ip, struct inclist *newfile)
184{
185 register int i;
186
187 if (ip == NULL)
188 return;
189 /*
190 * Put this include file (newfile) on the list of files included
191 * by 'file'. If 'file' is NULL, then it is not an include
192 * file itself (i.e. was probably mentioned on the command line).
193 * If it is already on the list, don't stick it on again.
194 */
195 if (ip->i_list == NULL) {
196 ip->i_list = (struct inclist **)
197 malloc(sizeof(struct inclist *) * ++ip->i_listlen);
198 ip->i_merged = (boolean *)
199 malloc(sizeof(boolean) * ip->i_listlen);
200 } else {
201 for (i=0; i<ip->i_listlen; i++)
202 if (ip->i_list[ i ] == newfile) {
203 i = strlen(newfile->i_file);
204 if (!(ip->i_flags & INCLUDED_SYM) &&
205 !(i > 2 &&
206 newfile->i_file[i-1] == 'c' &&
207 newfile->i_file[i-2] == '.'))
208 {
209 /* only bitch if ip has */
210 /* no #include SYMBOL lines */
211 /* and is not a .c file */
212 if (warn_multiple)
213 {
214 warning("%s includes %s more than once!\n",
215 ip->i_file, newfile->i_file);
216 warning1("Already have\n");
217 for (i=0; i<ip->i_listlen; i++)
218 warning1("\t%s\n", ip->i_list[i]->i_file);
219 }
220 }
221 return;
222 }
223 ip->i_list = (struct inclist **) realloc(ip->i_list,
224 sizeof(struct inclist *) * ++ip->i_listlen);
225 ip->i_merged = (boolean *)
226 realloc(ip->i_merged, sizeof(boolean) * ip->i_listlen);
227 }
228 ip->i_list[ ip->i_listlen-1 ] = newfile;
229 ip->i_merged[ ip->i_listlen-1 ] = FALSE;
230}
231
232void
233inc_clean (void)
234{
235 register struct inclist *ip;
236
237 for (ip = inclist; ip < inclistp; ip++) {
238 ip->i_flags &= ~MARKED;
239 }
240}
241
242struct inclist *
243inc_path(char *file, char *include, int type)
244{
245 static char path[ BUFSIZ ];
246 register char **pp, *p;
247 register struct inclist *ip;
248 struct stat st;
249
250 /*
251 * Check all previously found include files for a path that
252 * has already been expanded.
253 */
254 if ((type == INCLUDE) || (type == INCLUDEDOT))
255 inclistnext = inclist;
256 ip = inclistnext;
257
258 for (; ip->i_file; ip++) {
259 if ((strcmp(ip->i_incstring, include) == 0) &&
260 !(ip->i_flags & INCLUDED_SYM)) {
261 inclistnext = ip + 1;
262 return ip;
263 }
264 }
265
266 if (inclistnext == inclist) {
267 /*
268 * If the path was surrounded by "" or is an absolute path,
269 * then check the exact path provided.
270 */
271 if ((type == INCLUDEDOT) ||
272 (type == INCLUDENEXTDOT) ||
273 (*include == '/')) {
274 if (stat(include, &st) == 0 && !S_ISDIR(st.st_mode)) /* mozilla */
275 return newinclude(include, include);
276 if (show_where_not)
277 warning1("\tnot in %s\n", include);
278 }
279
280 /*
281 * If the path was surrounded by "" see if this include file is
282 * in the directory of the file being parsed.
283 */
284 if ((type == INCLUDEDOT) || (type == INCLUDENEXTDOT)) {
285 for (p=file+strlen(file); p>file; p--)
286 if (*p == '/')
287 break;
288 if (p == file) {
289 strcpy(path, include);
290 } else {
291 strncpy(path, file, (p-file) + 1);
292 path[ (p-file) + 1 ] = '\0';
293 strcpy(path + (p-file) + 1, include);
294 }
295 remove_dotdot(path);
296 if (stat(path, &st) == 0 && !S_ISDIR(st.st_mode)) /* mozilla */
297 return newinclude(path, include);
298 if (show_where_not)
299 warning1("\tnot in %s\n", path);
300 }
301 }
302
303 /*
304 * Check the include directories specified. Standard include dirs
305 * should be at the end.
306 */
307 if ((type == INCLUDE) || (type == INCLUDEDOT))
308 includedirsnext = includedirs;
309 pp = includedirsnext;
310
311 for (; *pp; pp++) {
312 sprintf(path, "%s/%s", *pp, include);
313 remove_dotdot(path);
314 if (stat(path, &st) == 0 && !S_ISDIR(st.st_mode)) { /* mozilla */
315 includedirsnext = pp + 1;
316 return newinclude(path, include);
317 }
318 if (show_where_not)
319 warning1("\tnot in %s\n", path);
320 }
321
322 return NULL;
323}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette