PageRenderTime 33ms CodeModel.GetById 12ms app.highlight 17ms RepoModel.GetById 1ms app.codeStats 0ms

/security/coreconf/mkdepend/include.c

http://github.com/zpao/v8monkey
C | 337 lines | 233 code | 29 blank | 75 comment | 94 complexity | e10a43ab109c84f60281a2c6f28668b9 MD5 | raw file
  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.7 2001/12/14 19:53:20 dawes Exp $ */
 28
 29
 30#include "def.h"
 31
 32#ifdef _MSC_VER
 33#include <windows.h>
 34static int
 35does_file_exist(char *file)
 36{
 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;
 42}
 43#else
 44static int
 45does_file_exist(char *file)
 46{
 47  struct stat sb;
 48  return stat(file, &sb) == 0 && !S_ISDIR(sb.st_mode);
 49}
 50#endif
 51
 52extern struct	inclist	inclist[ MAXFILES ],
 53			*inclistp, *inclistnext;
 54extern char	*includedirs[ ],
 55		**includedirsnext;
 56extern char	*notdotdot[ ];
 57extern boolean show_where_not;
 58extern boolean warn_multiple;
 59
 60static boolean
 61isdot(char *p)
 62{
 63	if(p && *p++ == '.' && *p++ == '\0')
 64		return(TRUE);
 65	return(FALSE);
 66}
 67
 68static boolean
 69isdotdot(char *p)
 70{
 71	if(p && *p++ == '.' && *p++ == '.' && *p++ == '\0')
 72		return(TRUE);
 73	return(FALSE);
 74}
 75
 76static boolean
 77issymbolic(char *dir, char *component)
 78{
 79#ifdef S_IFLNK
 80	struct stat	st;
 81	char	buf[ BUFSIZ ], **pp;
 82
 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);
 93	}
 94#endif
 95	return(FALSE);
 96}
 97
 98/*
 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!!)
102 */
103static void
104remove_dotdot(char *path)
105{
106	register char	*end, *from, *to, **cp;
107	char		*components[ MAXFILES ],
108			newpath[ BUFSIZ ];
109	boolean		component_copied;
110
111	/*
112	 * slice path up into components.
113	 */
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;
126		}
127	*cp++ = from;
128	*cp = NULL;
129
130	/*
131	 * Recursively remove all 'x/..' component pairs.
132	 */
133	cp = components;
134	while(*cp) {
135		if (!isdot(*cp) && !isdotdot(*cp) && isdotdot(*(cp+1))
136		    && !issymbolic(newpath, *cp))
137		{
138		    char **fp = cp + 2;
139		    char **tp = cp;
140
141		    do 
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++;
148		}
149	}
150	/*
151	 * Concatenate the remaining path elements.
152	 */
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++;
163	}
164	*to++ = '\0';
165
166	/*
167	 * copy the reconstituted path back to our pointer.
168	 */
169	strcpy(path, newpath);
170}
171
172/*
173 * Add an include file to the list of those included by 'file'.
174 */
175struct inclist *
176newinclude(char *newfile, char *incstring)
177{
178	register struct inclist	*ip;
179
180	/*
181	 * First, put this file on the global list of include files.
182	 */
183	ip = inclistp++;
184	if (inclistp == inclist + MAXFILES - 1)
185		fatalerr("out of space: increase MAXFILES\n");
186	ip->i_file = copy(newfile);
187
188	if (incstring == NULL)
189		ip->i_incstring = ip->i_file;
190	else
191		ip->i_incstring = copy(incstring);
192
193	inclistnext = inclistp;
194	return(ip);
195}
196
197void
198included_by(struct inclist *ip, struct inclist *newfile)
199{
200	register int i;
201
202	if (ip == NULL)
203		return;
204	/*
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.
209	 */
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] == '.'))
223			    {
224				/* only bitch if ip has */
225				/* no #include SYMBOL lines  */
226				/* and is not a .c file */
227				if (warn_multiple)
228				{
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);
234				}
235			    }
236			    return;
237			}
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);
242	}
243	ip->i_list[ ip->i_listlen-1 ] = newfile;
244	ip->i_merged[ ip->i_listlen-1 ] = FALSE;
245}
246
247void
248inc_clean (void)
249{
250	register struct inclist *ip;
251
252	for (ip = inclist; ip < inclistp; ip++) {
253		ip->i_flags &= ~MARKED;
254	}
255}
256
257struct inclist *
258inc_path(char *file, char *include, int type)
259{
260	static char		path[ BUFSIZ ];
261	register char		**pp, *p;
262	register struct inclist	*ip;
263
264	/*
265	 * Check all previously found include files for a path that
266	 * has already been expanded.
267	 */
268	if ((type == INCLUDE) || (type == INCLUDEDOT))
269		inclistnext = inclist;
270	ip = inclistnext;
271
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;
277		}
278	}
279
280	if (inclistnext == inclist) {
281		/*
282		 * If the path was surrounded by "" or is an absolute path,
283		 * then check the exact path provided.
284		 */
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);
292		}
293
294		/*
295		 * If the path was surrounded by "" see if this include file is
296		 * in the directory of the file being parsed.
297		 */
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);
308			}
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);
314		}
315	}
316
317	/*
318	 * Check the include directories specified.  Standard include dirs
319	 * should be at the end.
320	 */
321	if ((type == INCLUDE) || (type == INCLUDEDOT))
322		includedirsnext = includedirs;
323	pp = includedirsnext;
324
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);
331		}
332		if (show_where_not)
333			warning1("\tnot in %s\n", path);
334	}
335
336	return NULL;
337}