Version 4.0.2.1, tag libreoffice-4.0.2.1
[LibreOffice.git] / soltools / mkdepend / include.c
blobdbdd1cffeb322fb0db18cb2ef8982f56bf754520
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* $XConsortium: include.c,v 1.17 94/12/05 19:33:08 gildea Exp $ */
3 /*
5 Copyright (c) 1993, 1994 X Consortium
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 Except as contained in this notice, the name of the X Consortium shall not be
25 used in advertising or otherwise to promote the sale, use or other dealings
26 in this Software without prior written authorization from the X Consortium.
31 #include "def.h"
32 #include <string.h>
34 void remove_dotdot( char * );
35 int isdot( char * );
36 int isdotdot( char * );
37 int issymbolic(char * dir, char * component);
38 int exists_path(struct IncludesCollection*, char*);
41 extern struct inclist inclist[ MAXFILES ],
42 *inclistp;
43 extern char *includedirs[ ];
44 extern char *notdotdot[ ];
45 extern boolean show_where_not;
46 extern boolean warn_multiple;
48 struct inclist *inc_path(register char *file, register char *include, boolean dot, struct IncludesCollection* incCollection)
50 static char path[ BUFSIZ ];
51 register char **pp, *p;
52 register struct inclist *ip;
53 struct stat st;
54 boolean found = FALSE;
55 (void)dot;
58 * Check all previously found include files for a path that
59 * has already been expanded.
61 for (ip = inclist; ip->i_file; ip++)
62 if ((strcmp(ip->i_incstring, include) == 0) && !ip->i_included_sym)
64 found = TRUE;
65 break;
69 * If the path was surrounded by "" or is an absolute path,
70 * then check the exact path provided.
72 // FIXME: creates duplicates in the dependency files if absolute paths are
73 // given, which certainly is not the intended behavior. Also it slows down
74 // makedepend performance considerably.
75 // if (!found && (dot || *include == '/')) {
77 // if ((exists_path(incCollection, include)) && stat(include, &st) == 0 && !( st.st_mode & S_IFDIR)) {
78 // ip = newinclude(include, include);
79 // found = TRUE;
80 // }
81 // else if (show_where_not)
82 // warning1("\tnot in %s\n", include);
83 // }
86 * See if this include file is in the directory of the
87 * file being compiled.
89 if (!found) {
90 for (p=file+strlen(file); p>file; p--)
91 if (*p == '/')
92 break;
93 if (p == file)
94 strcpy(path, include);
95 else {
96 strncpy(path, file, (p-file) + 1);
97 path[ (p-file) + 1 ] = '\0';
98 strcpy(path + (p-file) + 1, include);
100 remove_dotdot(path);
101 if ((exists_path(incCollection, path)) && stat(path, &st) == 0 && !( st.st_mode & S_IFDIR)) {
102 ip = newinclude(path, include);
103 found = TRUE;
105 else if (show_where_not)
106 warning1("\tnot in %s\n", path);
110 * Check the include directories specified. (standard include dir
111 * should be at the end.)
113 if (!found)
114 for (pp = includedirs; *pp; pp++) {
115 sprintf(path, "%s/%s", *pp, include);
116 remove_dotdot(path);
117 if ((exists_path(incCollection, path)) && stat(path, &st) == 0 && !(st.st_mode & S_IFDIR)) {
118 ip = newinclude(path, include);
119 found = TRUE;
120 break;
122 else if (show_where_not)
123 warning1("\tnot in %s\n", path);
126 if (!found)
127 ip = NULL;
128 return(ip);
131 int exists_path(incCollection, path)
132 struct IncludesCollection* incCollection;
133 char* path;
135 convert_slashes(path);
136 return call_IncludesCollection_exists(incCollection, path);
140 * Occasionally, pathnames are created that look like .../x/../y
141 * Any of the 'x/..' sequences within the name can be eliminated.
142 * (but only if 'x' is not a symbolic link!!)
144 void remove_dotdot(path)
145 char *path;
147 register char *end, *from, *to, **cp;
148 char *components[ MAXFILES ],
149 newpath[ BUFSIZ ];
150 boolean component_copied;
153 * slice path up into components.
155 to = newpath;
156 if (*path == '/')
157 *to++ = '/';
158 *to = '\0';
159 cp = components;
160 for (from=end=path; *end; end++)
161 if (*end == '/') {
162 while (*end == '/')
163 *end++ = '\0';
164 if (*from)
165 *cp++ = from;
166 from = end;
168 *cp++ = from;
169 *cp = NULL;
172 * Recursively remove all 'x/..' component pairs.
174 cp = components;
175 while(*cp) {
176 if (!isdot(*cp) && !isdotdot(*cp) && isdotdot(*(cp+1))
177 && !issymbolic(newpath, *cp))
179 char **fp = cp + 2;
180 char **tp = cp;
183 *tp++ = *fp; /* move all the pointers down */
184 while (*fp++);
185 if (cp != components)
186 cp--; /* go back and check for nested ".." */
187 } else {
188 cp++;
192 * Concatenate the remaining path elements.
194 cp = components;
195 component_copied = FALSE;
196 while(*cp) {
197 if (component_copied)
198 *to++ = '/';
199 component_copied = TRUE;
200 for (from = *cp; *from; )
201 *to++ = *from++;
202 *to = '\0';
203 cp++;
205 *to++ = '\0';
208 * copy the reconstituted path back to our pointer.
210 strcpy(path, newpath);
213 int isdot(p)
214 register char *p;
216 if(p && p[0] == '.' && p[1] == '\0')
217 return(TRUE);
218 return(FALSE);
221 int isdotdot(p)
222 register char *p;
224 if(p && p[0] == '.' && p[1] == '.' && p[2] == '\0')
225 return(TRUE);
226 return(FALSE);
229 int issymbolic(dir, component)
230 register char *dir, *component;
232 #ifdef S_IFLNK
233 struct stat st;
234 char buf[ BUFSIZ ], **pp;
236 sprintf(buf, "%s%s%s", dir, *dir ? "/" : "", component);
237 for (pp=notdotdot; *pp; pp++)
238 if (strcmp(*pp, buf) == 0)
239 return (TRUE);
240 if (lstat(buf, &st) == 0
241 && (st.st_mode & S_IFMT) == S_IFLNK) {
242 *pp++ = copy(buf);
243 if (pp >= &notdotdot[ MAXDIRS ])
244 fatalerr("out of .. dirs, increase MAXDIRS\n");
245 return(TRUE);
247 #endif
248 return(FALSE);
252 * Add an include file to the list of those included by 'file'.
254 struct inclist *newinclude(newfile, incstring)
255 register char *newfile, *incstring;
257 register struct inclist *ip;
260 * First, put this file on the global list of include files.
262 ip = inclistp++;
263 if (inclistp == inclist + MAXFILES - 1)
264 fatalerr("out of space: increase MAXFILES\n");
265 ip->i_file = copy(newfile);
266 ip->i_included_sym = FALSE;
267 if (incstring == NULL)
268 ip->i_incstring = ip->i_file;
269 else
270 ip->i_incstring = copy(incstring);
272 return(ip);
275 void included_by(ip, newfile)
276 register struct inclist *ip, *newfile;
278 register int i;
280 if (ip == NULL)
281 return;
283 * Put this include file (newfile) on the list of files included
284 * by 'file'. If 'file' is NULL, then it is not an include
285 * file itself (i.e. was probably mentioned on the command line).
286 * If it is already on the list, don't stick it on again.
288 if (ip->i_list == NULL)
289 ip->i_list = (struct inclist **)
290 malloc(sizeof(struct inclist *) * ++ip->i_listlen);
291 else {
292 for (i=0; i<ip->i_listlen; i++)
293 if (ip->i_list[ i ] == newfile) {
294 i = (int)strlen(newfile->i_file);
295 if (!ip->i_included_sym &&
296 !(i > 2 &&
297 newfile->i_file[i-1] == 'c' &&
298 newfile->i_file[i-2] == '.'))
300 /* only complain if ip has */
301 /* no #include SYMBOL lines */
302 /* and is not a .c file */
303 if (warn_multiple)
305 warning("%s includes %s more than once!\n",
306 ip->i_file, newfile->i_file);
307 warning1("Already have\n");
308 for (i=0; i<ip->i_listlen; i++)
309 warning1("\t%s\n", ip->i_list[i]->i_file);
312 return;
314 ip->i_list = (struct inclist **) realloc(ip->i_list,
315 sizeof(struct inclist *) * ++ip->i_listlen);
317 ip->i_list[ ip->i_listlen-1 ] = newfile;
320 void inc_clean ()
322 register struct inclist *ip;
324 for (ip = inclist; ip < inclistp; ip++) {
325 ip->i_marked = FALSE;
329 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */