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