forgotten commit. disabled until egl is adapted.
[AROS-Contrib.git] / development / build / makedepend / include.c
blob62eb495db1dad5de98a3958f0992a022e1750d30
1 /* $Xorg: include.c,v 1.3 2000/08/17 19:41:51 cpqbld Exp $ */
2 /*
4 Copyright (c) 1993, 1994, 1998 The Open Group
6 All Rights Reserved.
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 $ */
26 #include "def.h"
28 extern struct inclist inclist[ MAXFILES ],
29 *inclistp, *inclistnext;
30 extern char *includedirs[ ],
31 **includedirsnext;
32 extern char *notdotdot[ ];
33 extern boolean show_where_not;
34 extern boolean warn_multiple;
36 static boolean
37 isdot(char *p)
39 if(p && *p++ == '.' && *p++ == '\0')
40 return(TRUE);
41 return(FALSE);
44 static boolean
45 isdotdot(char *p)
47 if(p && *p++ == '.' && *p++ == '.' && *p++ == '\0')
48 return(TRUE);
49 return(FALSE);
52 static boolean
53 issymbolic(char *dir, char *component)
55 #ifdef S_IFLNK
56 struct stat st;
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)
62 return (TRUE);
63 if (lstat(buf, &st) == 0
64 && (st.st_mode & S_IFMT) == S_IFLNK) {
65 *pp++ = copy(buf);
66 if (pp >= &notdotdot[ MAXDIRS ])
67 fatalerr("out of .. dirs, increase MAXDIRS\n");
68 return(TRUE);
70 #endif
71 return(FALSE);
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!!)
79 static void
80 remove_dotdot(char *path)
82 register char *end, *from, *to, **cp;
83 char *components[ MAXFILES ],
84 newpath[ BUFSIZ ];
85 boolean component_copied;
88 * slice path up into components.
90 to = newpath;
91 if (*path == '/')
92 *to++ = '/';
93 *to = '\0';
94 cp = components;
95 for (from=end=path; *end; end++)
96 if (*end == '/') {
97 while (*end == '/')
98 *end++ = '\0';
99 if (*from)
100 *cp++ = from;
101 from = end;
103 *cp++ = from;
104 *cp = NULL;
107 * Recursively remove all 'x/..' component pairs.
109 cp = components;
110 while(*cp) {
111 if (!isdot(*cp) && !isdotdot(*cp) && isdotdot(*(cp+1))
112 && !issymbolic(newpath, *cp))
114 char **fp = cp + 2;
115 char **tp = cp;
118 *tp++ = *fp; /* move all the pointers down */
119 while (*fp++);
120 if (cp != components)
121 cp--; /* go back and check for nested ".." */
122 } else {
123 cp++;
127 * Concatenate the remaining path elements.
129 cp = components;
130 component_copied = FALSE;
131 while(*cp) {
132 if (component_copied)
133 *to++ = '/';
134 component_copied = TRUE;
135 for (from = *cp; *from; )
136 *to++ = *from++;
137 *to = '\0';
138 cp++;
140 *to++ = '\0';
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'.
151 struct inclist *
152 newinclude(char *newfile, char *incstring)
154 register struct inclist *ip;
157 * First, put this file on the global list of include files.
159 ip = inclistp++;
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;
166 else
167 ip->i_incstring = copy(incstring);
169 inclistnext = inclistp;
170 return(ip);
173 void
174 included_by(struct inclist *ip, struct inclist *newfile)
176 register int i;
178 if (ip == NULL)
179 return;
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);
191 } else {
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) &&
196 !(i > 2 &&
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 */
203 if (warn_multiple)
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);
212 return;
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;
223 void
224 inc_clean (void)
226 register struct inclist *ip;
228 for (ip = inclist; ip < inclistp; ip++) {
229 ip->i_flags &= ~MARKED;
233 struct inclist *
234 inc_path(char *file, char *include, int type)
236 static char path[ BUFSIZ ];
237 register char **pp, *p;
238 register struct inclist *ip;
239 struct stat st;
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;
247 ip = inclistnext;
249 for (; ip->i_file; ip++) {
250 if ((strcmp(ip->i_incstring, include) == 0) &&
251 !(ip->i_flags & INCLUDED_SYM)) {
252 inclistnext = ip + 1;
253 return ip;
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) ||
264 (*include == '/')) {
265 if (stat(include, &st) == 0)
266 return newinclude(include, include);
267 if (show_where_not)
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--)
277 if (*p == '/')
278 break;
279 if (p == file) {
280 strcpy(path, include);
281 } else {
282 strncpy(path, file, (p-file) + 1);
283 path[ (p-file) + 1 ] = '\0';
284 strcpy(path + (p-file) + 1, include);
286 remove_dotdot(path);
287 if (stat(path, &st) == 0)
288 return newinclude(path, include);
289 if (show_where_not)
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;
302 for (; *pp; pp++) {
303 sprintf(path, "%s/%s", *pp, include);
304 remove_dotdot(path);
305 if (stat(path, &st) == 0) {
306 includedirsnext = pp + 1;
307 return newinclude(path, include);
309 if (show_where_not)
310 warning1("\tnot in %s\n", path);
313 return NULL;