feisty meow concerns codebase 2.140
include.cpp
Go to the documentation of this file.
1/* $XConsortium: include.c,v 1.17 94/12/05 19:33:08 gildea Exp $ */
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#ifdef __WIN32__
30 #pragma warning(disable : 4996)
31#endif
32
33#include "def.h"
34
35#include <string.h>
36
37//#ifdef _MSC_VER
38// #undef strcasecmp
39// #undef strncasecmp
40// #define strcasecmp strcmpi
41// #define strncasecmp strnicmp
42//#endif
43
45extern char *includedirs[ ];
46extern char *excludedirs[ ];
47extern char *notdotdot[ ];
48extern bool show_where_not;
49extern bool warn_multiple;
50
51// forward.
52void remove_dotdot(char *path);
53int isdot(char *p);
54int isdotdot(char *p);
55int issymbolic(char *dir, char *component);
56void included_by(inclist *ip, inclist *newfile);
57
58inclist *inc_path(char *file, char *include, bool dot,
59 bool &failure_okay)
60{
61 static char path[ BUFSIZ ];
62 char **pp, *p;
63 inclist *ip;
64 struct stat st;
65 bool found = false;
66
67//fprintf(stderr, "file=%s include=%s\n", file, include);
68 const size_t inclen = strlen(include);
69 if (inclen >= 4) {
70 char *cpp_point = include + inclen - 4;
71 if (!strcasecmp(".cpp", cpp_point)) {
72 // this is a CPP file include, which we skip.
73//fprintf(stderr, "!found match at point: %s\n", cpp_point);
74//hold failure_okay = true;
75//hold return NULL;
76 }
77 }
78
80
81 /*
82 * Check all previously found include files for a path that
83 * has already been expanded.
84 */
85 for (ip = inc_list; ip->i_file; ip++)
86 if ((strcmp(ip->i_incstring, include) == 0) && !ip->i_included_sym) {
87 found = true;
88 break;
89 }
90
91 /*
92 * If the path was surrounded by "" or is an absolute path,
93 * then check the exact path provided.
94 */
95 if (!found && (dot || *include == '/' || *include == '\\')) {
96 if (stat(include, &st) == 0) {
97 ip = newinclude(include, include);
98 found = true;
99 }
100 else if (show_where_not)
101 warning1("\tnot in %s\n", include);
102 }
103
104 /*
105 * See if this include file is in the directory of the
106 * file being compiled.
107 */
108 if (!found) {
109 for (p=file+strlen(file); p>file; p--)
110 if (*p == '/' || *p == '\\')
111 break;
112 if (p == file)
113 strcpy(path, include);
114 else {
115 strncpy(path, file, (p-file) + 1);
116 path[ (p-file) + 1 ] = '\0';
117 strcpy(path + (p-file) + 1, include);
118 }
119 remove_dotdot(path);
120 if (stat(path, &st) == 0) {
121 ip = newinclude(path, include);
122 found = true;
123 }
124 else if (show_where_not)
125 warning1("\tnot in %s\n", path);
126 }
127
128 /*
129 * Check the include directories specified. (standard include dir
130 * should be at the end.)
131 */
132 if (!found)
133 for (pp = includedirs; *pp; pp++) {
134 sprintf(path, "%s/%s", *pp, include);
135 remove_dotdot(path);
136 if (stat(path, &st) == 0) {
137 char **pp2;
138 bool exclude_it = false;
139 for (pp2 = excludedirs; *pp2; pp2++) {
141 if (!strncmp(*pp, *pp2, strlen(*pp2))) {
142 // this file is supposed to be excluded.
143 exclude_it = true;
144 break;
145 }
146 }
148 if (exclude_it) {
149 failure_okay = true;
150 found = false;
151 } else {
152 ip = newinclude(path, include);
153 found = true;
154 }
155 break;
156 }
157 else if (show_where_not)
158 warning1("\tnot in %s\n", path);
159 }
160
161 if (!found)
162 ip = NULL;
163 return(ip);
164}
165
166/*
167 * Occasionally, pathnames are created that look like .../x/../y
168 * Any of the 'x/..' sequences within the name can be eliminated.
169 * (but only if 'x' is not a symbolic link!!)
170 */
171void remove_dotdot(char *path)
172{
173 char *end, *from, *to, **cp;
174 char *components[ MAXFILES ], newpath[ BUFSIZ ];
175 bool component_copied;
176
177 /*
178 * slice path up into components.
179 */
180 to = newpath;
181 if (*path == '/' || *path == '\\')
182 *to++ = '/';
183 *to = '\0';
184 cp = components;
185 for (from=end=path; *end; end++)
186 if (*end == '/' || *end == '\\') {
187 while (*end == '/' || *end == '\\')
188 *end++ = '\0';
189 if (*from)
190 *cp++ = from;
191 from = end;
192 }
193 *cp++ = from;
194 *cp = NULL;
195
196 /*
197 * Recursively remove all 'x/..' component pairs.
198 */
199 cp = components;
200 while(*cp) {
201 if (!isdot(*cp) && !isdotdot(*cp) && isdotdot(*(cp+1))
202 && !issymbolic(newpath, *cp))
203 {
204 char **fp = cp + 2;
205 char **tp = cp;
206
207 do
208 *tp++ = *fp; /* move all the pointers down */
209 while (*fp++);
210 if (cp != components)
211 cp--; /* go back and check for nested ".." */
212 } else {
213 cp++;
214 }
215 }
216 /*
217 * Concatenate the remaining path elements.
218 */
219 cp = components;
220 component_copied = false;
221 while(*cp) {
222 if (component_copied)
223 *to++ = '/';
224 component_copied = true;
225 for (from = *cp; *from; )
226 *to++ = *from++;
227 *to = '\0';
228 cp++;
229 }
230 *to++ = '\0';
231
232 /*
233 * copy the reconstituted path back to our pointer.
234 */
235 strcpy(path, newpath);
236}
237
238int isdot(char *p)
239{
240 if(p && *p++ == '.' && *p++ == '\0')
241 return(true);
242 return(false);
243}
244
245int isdotdot(char *p)
246{
247 if(p && *p++ == '.' && *p++ == '.' && *p++ == '\0')
248 return(true);
249 return(false);
250}
251
252int issymbolic(char *dir, char *component)
253{
254#ifdef S_IFLNK
255 struct stat st;
256 char buf[ BUFSIZ ], **pp;
257
258 sprintf(buf, "%s%s%s", dir, *dir ? "/" : "", component);
259 for (pp=notdotdot; *pp; pp++)
260 if (strcmp(*pp, buf) == 0)
261 return (true);
262 if (lstat(buf, &st) == 0
263 && (st.st_mode & S_IFMT) == S_IFLNK) {
264 *pp++ = copy(buf);
265 if (pp >= &notdotdot[ MAXDIRS ])
266 fatalerr("out of .. dirs, increase MAXDIRS\n");
267 return(true);
268 }
269#endif
270 return(false);
271}
272
273/*
274 * Add an include file to the list of those included by 'file'.
275 */
276inclist *newinclude(char *newfile, char *incstring)
277{
278 inclist *ip;
279
280 /*
281 * First, put this file on the global list of include files.
282 */
283 ip = inclistp++;
284 if (inclistp == inc_list + MAXFILES - 1)
285 fatalerr("out of space: increase MAXFILES\n");
286 ip->i_file = copy(newfile);
287 ip->i_included_sym = false;
288 if (incstring == NULL)
289 ip->i_incstring = ip->i_file;
290 else
291 ip->i_incstring = copy(incstring);
292
293 return(ip);
294}
295
296void included_by(inclist *ip, inclist *newfile)
297{
298 int i;
299
300 if (ip == NULL)
301 return;
302 /*
303 * Put this include file (newfile) on the list of files included
304 * by 'file'. If 'file' is NULL, then it is not an include
305 * file itself (i.e. was probably mentioned on the command line).
306 * If it is already on the list, don't stick it on again.
307 */
308 if (ip->i_list == NULL)
309 ip->i_list = (inclist **)
310 malloc(sizeof(inclist *) * ++ip->i_listlen);
311 else {
312 for (i=0; i<ip->i_listlen; i++)
313 if (ip->i_list[ i ] == newfile) {
314 i = int(strlen(newfile->i_file));
315 if (!ip->i_included_sym &&
316 !(i > 2 &&
317 newfile->i_file[i-1] == 'c' &&
318 newfile->i_file[i-2] == '.'))
319 {
320 /* only complain if ip has */
321 /* no #include SYMBOL lines */
322 /* and is not a .c file */
323 if (warn_multiple)
324 {
325 warning("%s includes %s more than once!\n",
326 ip->i_file, newfile->i_file);
327 warning1("Already have\n");
328 for (i=0; i<ip->i_listlen; i++)
329 warning1("\t%s\n", ip->i_list[i]->i_file);
330 }
331 }
332 return;
333 }
334 ip->i_list = (inclist **) realloc(ip->i_list,
335 sizeof(inclist *) * ++ip->i_listlen);
336 }
337 ip->i_list[ ip->i_listlen-1 ] = newfile;
338}
339
341{
342 inclist *ip;
343
344 for (ip = inc_list; ip < inclistp; ip++) {
345 ip->i_marked = false;
346 }
347}
348
#define stat
Definition Xos2defs.h:41
#define S_IFMT
Definition Xw32defs.h:59
char * copy(char *str)
Definition makedep.cpp:554
#define MAXFILES
Definition def.h:49
#define MAXDIRS
Definition def.h:50
bool show_where_not
Definition makedep.cpp:113
char * excludedirs[]
Definition makedep.cpp:104
int isdot(char *p)
Definition include.cpp:238
void remove_dotdot(char *path)
Definition include.cpp:171
char * notdotdot[]
Definition makedep.cpp:105
inclist * inclistp
Definition include.cpp:44
bool warn_multiple
Definition makedep.cpp:114
void inc_clean()
Definition include.cpp:340
void included_by(inclist *ip, inclist *newfile)
Definition include.cpp:296
inclist inc_list[MAXFILES]
Definition makedep.cpp:100
char * includedirs[]
Definition makedep.cpp:103
int issymbolic(char *dir, char *component)
Definition include.cpp:252
inclist * newinclude(char *newfile, char *incstring)
Definition include.cpp:276
inclist * inc_path(char *file, char *include, bool dot, bool &failure_okay)
Definition include.cpp:58
int isdotdot(char *p)
Definition include.cpp:245
void warning1(const char *msg, x1, x2, x3, x4, x5, x6, x7, x8, x9)
Definition makedep.cpp:790
void fatalerr(char *msg, x1, x2, x3, x4, x5, x6, x7, x8, x9)
Definition makedep.cpp:749
void warning(const char *msg, x1, x2, x3, x4, x5, x6, x7, x8, x9)
Definition makedep.cpp:770
Definition def.h:101
bool i_included_sym
Definition def.h:113
int i_listlen
Definition def.h:105
bool i_marked
Definition def.h:111
char * i_incstring
Definition def.h:102
char * i_file
Definition def.h:103
inclist ** i_list
Definition def.h:104