bug 313956: expand installer .exe contents to make complete mar. r=ted.
[gecko.git] / config / mkdepend / include.c
blob3b89f2630665e75775c16fbbbd701504b3f2a21d
1 /* $Xorg: include.c,v 1.4 2001/02/09 02:03:16 xorgcvs Exp $ */
2 /*
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
10 documentation.
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 $ */
30 #include "def.h"
32 #ifdef _MSC_VER
33 #include <windows.h>
34 static int
35 does_file_exist(char *file)
37 WIN32_FILE_ATTRIBUTE_DATA data;
38 BOOL b = GetFileAttributesExA(file, GetFileExInfoStandard, &data);
39 if (!b)
40 return 0;
41 return (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0;
43 #else
44 static int
45 does_file_exist(char *file)
47 struct stat sb;
48 return stat(file, &sb) == 0 && !S_ISDIR(sb.st_mode);
50 #endif
52 extern struct inclist inclist[ MAXFILES ],
53 *inclistp, *inclistnext;
54 extern char *includedirs[ ],
55 **includedirsnext;
56 extern char *notdotdot[ ];
57 extern boolean show_where_not;
58 extern boolean warn_multiple;
60 static boolean
61 isdot(char *p)
63 if(p && *p++ == '.' && *p++ == '\0')
64 return(TRUE);
65 return(FALSE);
68 static boolean
69 isdotdot(char *p)
71 if(p && *p++ == '.' && *p++ == '.' && *p++ == '\0')
72 return(TRUE);
73 return(FALSE);
76 static boolean
77 issymbolic(char *dir, char *component)
79 #ifdef S_IFLNK
80 struct stat st;
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)
86 return (TRUE);
87 if (lstat(buf, &st) == 0
88 && (st.st_mode & S_IFMT) == S_IFLNK) {
89 *pp++ = copy(buf);
90 if (pp >= &notdotdot[ MAXDIRS ])
91 fatalerr("out of .. dirs, increase MAXDIRS\n");
92 return(TRUE);
94 #endif
95 return(FALSE);
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!!)
103 static void
104 remove_dotdot(char *path)
106 register char *end, *from, *to, **cp;
107 char *components[ MAXFILES ],
108 newpath[ BUFSIZ ];
109 boolean component_copied;
112 * slice path up into components.
114 to = newpath;
115 if (*path == '/')
116 *to++ = '/';
117 *to = '\0';
118 cp = components;
119 for (from=end=path; *end; end++)
120 if (*end == '/') {
121 while (*end == '/')
122 *end++ = '\0';
123 if (*from)
124 *cp++ = from;
125 from = end;
127 *cp++ = from;
128 *cp = NULL;
131 * Recursively remove all 'x/..' component pairs.
133 cp = components;
134 while(*cp) {
135 if (!isdot(*cp) && !isdotdot(*cp) && isdotdot(*(cp+1))
136 && !issymbolic(newpath, *cp))
138 char **fp = cp + 2;
139 char **tp = cp;
142 *tp++ = *fp; /* move all the pointers down */
143 while (*fp++);
144 if (cp != components)
145 cp--; /* go back and check for nested ".." */
146 } else {
147 cp++;
151 * Concatenate the remaining path elements.
153 cp = components;
154 component_copied = FALSE;
155 while(*cp) {
156 if (component_copied)
157 *to++ = '/';
158 component_copied = TRUE;
159 for (from = *cp; *from; )
160 *to++ = *from++;
161 *to = '\0';
162 cp++;
164 *to++ = '\0';
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'.
175 struct inclist *
176 newinclude(char *newfile, char *incstring)
178 register struct inclist *ip;
181 * First, put this file on the global list of include files.
183 ip = inclistp++;
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;
190 else
191 ip->i_incstring = copy(incstring);
193 inclistnext = inclistp;
194 return(ip);
197 void
198 included_by(struct inclist *ip, struct inclist *newfile)
200 register int i;
202 if (ip == NULL)
203 return;
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);
215 } else {
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) &&
220 !(i > 2 &&
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 */
227 if (warn_multiple)
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);
236 return;
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;
247 void
248 inc_clean (void)
250 register struct inclist *ip;
252 for (ip = inclist; ip < inclistp; ip++) {
253 ip->i_flags &= ~MARKED;
257 struct inclist *
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;
270 ip = inclistnext;
272 for (; ip->i_file; ip++) {
273 if ((strcmp(ip->i_incstring, include) == 0) &&
274 !(ip->i_flags & INCLUDED_SYM)) {
275 inclistnext = ip + 1;
276 return ip;
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) ||
287 (*include == '/')) {
288 if (does_file_exist(include))
289 return newinclude(include, include);
290 if (show_where_not)
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--)
300 if (*p == '/')
301 break;
302 if (p == file) {
303 strcpy(path, include);
304 } else {
305 strncpy(path, file, (p-file) + 1);
306 path[ (p-file) + 1 ] = '\0';
307 strcpy(path + (p-file) + 1, include);
309 remove_dotdot(path);
310 if (does_file_exist(path))
311 return newinclude(path, include);
312 if (show_where_not)
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;
325 for (; *pp; pp++) {
326 sprintf(path, "%s/%s", *pp, include);
327 remove_dotdot(path);
328 if (does_file_exist(path)) {
329 includedirsnext = pp + 1;
330 return newinclude(path, include);
332 if (show_where_not)
333 warning1("\tnot in %s\n", path);
336 return NULL;