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 
4 Copyright (c) 1993, 1994 X Consortium
5 
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12 
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15 
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 
23 Except as contained in this notice, the name of the X Consortium shall not be
24 used in advertising or otherwise to promote the sale, use or other dealings
25 in 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 
45 extern char *includedirs[ ];
46 extern char *excludedirs[ ];
47 extern char *notdotdot[ ];
48 extern bool show_where_not;
49 extern bool warn_multiple;
50 
51 // forward.
52 void remove_dotdot(char *path);
53 int isdot(register char *p);
54 int isdotdot(register char *p);
55 int issymbolic(register char *dir, register char *component);
56 void included_by(register inclist *ip, register inclist *newfile);
57 
58 inclist *inc_path(register char *file, register char *include, bool dot,
59  bool &failure_okay)
60 {
61  static char path[ BUFSIZ ];
62  register char **pp, *p;
63  register 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  register 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  }
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);
136  if (stat(path, &st) == 0) {
137  register 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  */
171 void remove_dotdot(char *path)
172 {
173  register 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 
238 int isdot(register char *p)
239 {
240  if(p && *p++ == '.' && *p++ == '\0')
241  return(true);
242  return(false);
243 }
244 
245 int isdotdot(register char *p)
246 {
247  if(p && *p++ == '.' && *p++ == '.' && *p++ == '\0')
248  return(true);
249  return(false);
250 }
251 
252 int issymbolic(register char *dir, register 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  */
276 inclist *newinclude(register char *newfile, register char *incstring)
277 {
278  register 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 
296 void included_by(register inclist *ip, register inclist *newfile)
297 {
298  register 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 
340 void inc_clean()
341 {
342  register 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
#define MAXFILES
Definition: def.h:49
char * copy(register char *str)
Definition: makedep.cpp:554
#define MAXDIRS
Definition: def.h:50
int isdot(register char *p)
Definition: include.cpp:238
int issymbolic(register char *dir, register char *component)
Definition: include.cpp:252
bool show_where_not
Definition: makedep.cpp:113
char * excludedirs[]
Definition: makedep.cpp:104
inclist * inc_path(register char *file, register char *include, bool dot, bool &failure_okay)
Definition: include.cpp:58
inclist * newinclude(register char *newfile, register char *incstring)
Definition: include.cpp:276
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
inclist inc_list[MAXFILES]
Definition: makedep.cpp:100
char * includedirs[]
Definition: makedep.cpp:103
int isdotdot(register char *p)
Definition: include.cpp:245
void included_by(register inclist *ip, register inclist *newfile)
Definition: include.cpp:296
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
string path
Definition: eml_to_txt.py:139
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