]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/cppfiles.c
295590203963237a65857239adcd000f91d338a8
[thirdparty/gcc.git] / gcc / cppfiles.c
1 /* Part of CPP library. (include file handling)
2 Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1998,
3 1999, 2000 Free Software Foundation, Inc.
4 Written by Per Bothner, 1994.
5 Based on CCCP program by Paul Rubin, June 1986
6 Adapted to ANSI C, Richard Stallman, Jan 1987
7 Split out of cpplib.c, Zack Weinberg, Oct 1998
8
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
12 later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22
23 #include "config.h"
24 #include "system.h"
25 #include "hashtab.h"
26 #include "cpplib.h"
27 #include "cpphash.h"
28 #include "intl.h"
29 #include "mkdeps.h"
30
31 #ifdef HAVE_MMAP_FILE
32 # include <sys/mman.h>
33 # ifndef MMAP_THRESHOLD
34 # define MMAP_THRESHOLD 3 /* Minimum page count to mmap the file. */
35 # endif
36
37 #else /* No MMAP_FILE */
38 # undef MMAP_THRESHOLD
39 # define MMAP_THRESHOLD 0
40 #endif
41
42 static IHASH *redundant_include_p PARAMS ((cpp_reader *, IHASH *,
43 struct file_name_list *));
44 static IHASH *make_IHASH PARAMS ((const char *, const char *,
45 struct file_name_list *,
46 unsigned int, IHASH **));
47 static struct file_name_map *read_name_map
48 PARAMS ((cpp_reader *, const char *));
49 static char *read_filename_string PARAMS ((int, FILE *));
50 static char *remap_filename PARAMS ((cpp_reader *, char *,
51 struct file_name_list *));
52 static struct file_name_list *actual_directory
53 PARAMS ((cpp_reader *, const char *));
54 static unsigned int hash_IHASH PARAMS ((const void *));
55 static int eq_IHASH PARAMS ((const void *, const void *));
56 static int find_include_file PARAMS ((cpp_reader *, const char *,
57 struct file_name_list *,
58 IHASH **, int *));
59 static inline int open_include_file PARAMS ((cpp_reader *, const char *));
60 static int read_include_file PARAMS ((cpp_reader *, int, IHASH *));
61 static ssize_t read_with_read PARAMS ((cpp_buffer *, int, ssize_t));
62 static ssize_t read_file PARAMS ((cpp_buffer *, int, ssize_t));
63
64 #if 0
65 static void hack_vms_include_specification PARAMS ((char *));
66 #endif
67
68 /* Initial size of include hash table. */
69 #define IHASHSIZE 50
70
71 #ifndef INCLUDE_LEN_FUDGE
72 #define INCLUDE_LEN_FUDGE 0
73 #endif
74
75 /* Calculate hash of an IHASH entry. */
76 static unsigned int
77 hash_IHASH (x)
78 const void *x;
79 {
80 const IHASH *i = (const IHASH *)x;
81 return i->hash;
82 }
83
84 /* Compare an existing IHASH structure with a potential one. */
85 static int
86 eq_IHASH (x, y)
87 const void *x;
88 const void *y;
89 {
90 const char *a = ((const IHASH *)x)->nshort;
91 const char *b = ((const IHASH *)y)->nshort;
92 return !strcmp (a, b);
93 }
94
95 /* Init the hash table. In here so it can see the hash and eq functions. */
96 void
97 _cpp_init_include_hash (pfile)
98 cpp_reader *pfile;
99 {
100 pfile->all_include_files
101 = htab_create (IHASHSIZE, hash_IHASH, eq_IHASH, free);
102 }
103
104 /* Return 0 if the file pointed to by IHASH has never been included before,
105 -1 if it has been included before and need not be again,
106 or a pointer to an IHASH entry which is the file to be reread.
107 "Never before" is with respect to the position in ILIST.
108
109 This will not detect redundancies involving odd uses of the
110 `current directory' rule for "" includes. They aren't quite
111 pathological, but I think they are rare enough not to worry about.
112 The simplest example is:
113
114 top.c:
115 #include "a/a.h"
116 #include "b/b.h"
117
118 a/a.h:
119 #include "../b/b.h"
120
121 and the problem is that for `current directory' includes,
122 ihash->foundhere is not on any of the global include chains,
123 so the test below (i->foundhere == l) may be false even when
124 the directories are in fact the same. */
125
126 static IHASH *
127 redundant_include_p (pfile, ihash, ilist)
128 cpp_reader *pfile;
129 IHASH *ihash;
130 struct file_name_list *ilist;
131 {
132 struct file_name_list *l;
133 IHASH *i;
134
135 if (! ihash->foundhere)
136 return 0;
137
138 for (i = ihash; i; i = i->next_this_file)
139 for (l = ilist; l; l = l->next)
140 if (i->foundhere == l)
141 /* The control_macro works like this: If it's NULL, the file
142 is to be included again. If it's "", the file is never to
143 be included again. If it's a string, the file is not to be
144 included again if the string is the name of a defined macro. */
145 return (i->control_macro
146 && (i->control_macro[0] == '\0'
147 || cpp_defined (pfile, i->control_macro,
148 ustrlen (i->control_macro))))
149 ? (IHASH *)-1 : i;
150
151 return 0;
152 }
153
154 /* Return 1 if the file named by FNAME has been included before in
155 any context, 0 otherwise. */
156 int
157 cpp_included (pfile, fname)
158 cpp_reader *pfile;
159 const char *fname;
160 {
161 IHASH dummy, *ptr;
162 dummy.nshort = fname;
163 dummy.hash = _cpp_calc_hash ((const U_CHAR *)fname, strlen (fname));
164 ptr = htab_find_with_hash (pfile->all_include_files,
165 (const void *)&dummy, dummy.hash);
166 return (ptr != NULL);
167 }
168
169 /* Create an IHASH entry and insert it in SLOT. */
170 static IHASH *
171 make_IHASH (name, fname, path, hash, slot)
172 const char *name, *fname;
173 struct file_name_list *path;
174 unsigned int hash;
175 IHASH **slot;
176 {
177 IHASH *ih;
178 if (path == ABSOLUTE_PATH)
179 {
180 ih = (IHASH *) xmalloc (sizeof (IHASH) + strlen (name));
181 ih->nshort = ih->name;
182 }
183 else
184 {
185 char *s;
186
187 if ((s = strstr (name, fname)) != NULL)
188 {
189 ih = (IHASH *) xmalloc (sizeof (IHASH) + strlen (name));
190 ih->nshort = ih->name + (s - name);
191 }
192 else
193 {
194 ih = (IHASH *) xmalloc (sizeof (IHASH) + strlen (name)
195 + strlen (fname) + 1);
196 ih->nshort = ih->name + strlen (name) + 1;
197 strcpy ((char *)ih->nshort, fname);
198 }
199 }
200 strcpy ((char *)ih->name, name);
201 ih->foundhere = path;
202 ih->control_macro = NULL;
203 ih->hash = hash;
204 ih->next_this_file = *slot;
205 *slot = ih;
206 return ih;
207 }
208
209 /* Centralize calls to open(2) here. This provides a hook for future
210 changes which might, e.g. look for and open a precompiled version
211 of the header. It also means all the magic currently associated
212 with calling open is in one place, and if we ever need more, it'll
213 be in one place too.
214
215 We used to open files in nonblocking mode, but that caused more
216 problems than it solved. Do take care not to acquire a controlling
217 terminal by mistake (this can't happen on sane systems, but
218 paranoia is a virtue).
219
220 Use the three-argument form of open even though we aren't
221 specifying O_CREAT, to defend against broken system headers. */
222
223 static inline int
224 open_include_file (pfile, filename)
225 cpp_reader *pfile ATTRIBUTE_UNUSED;
226 const char *filename;
227 {
228 return open (filename, O_RDONLY|O_NOCTTY, 0666);
229 }
230
231 /* Search for include file FNAME in the include chain starting at
232 SEARCH_START. Return -2 if this file doesn't need to be included
233 (because it was included already and it's marked idempotent),
234 -1 if an error occurred, or a file descriptor open on the file.
235 *IHASH is set to point to the include hash entry for this file, and
236 *BEFORE is set to 1 if the file was included before (but needs to be read
237 again). */
238 static int
239 find_include_file (pfile, fname, search_start, ihash, before)
240 cpp_reader *pfile;
241 const char *fname;
242 struct file_name_list *search_start;
243 IHASH **ihash;
244 int *before;
245 {
246 struct file_name_list *path;
247 IHASH *ih, **slot;
248 IHASH dummy;
249 int f;
250 char *name;
251
252 dummy.nshort = fname;
253 dummy.hash = _cpp_calc_hash ((const U_CHAR *)fname, strlen (fname));
254 path = (fname[0] == '/') ? ABSOLUTE_PATH : search_start;
255 slot = (IHASH **) htab_find_slot_with_hash (pfile->all_include_files,
256 (const void *) &dummy,
257 dummy.hash, INSERT);
258
259 if (*slot && (ih = redundant_include_p (pfile, *slot, path)))
260 {
261 if (ih == (IHASH *)-1)
262 return -2;
263
264 *before = 1;
265 *ihash = ih;
266 return open_include_file (pfile, ih->name);
267 }
268
269 if (path == ABSOLUTE_PATH)
270 {
271 name = (char *) fname;
272 f = open_include_file (pfile, name);
273 }
274 else
275 {
276 /* Search directory path, trying to open the file. */
277 name = (char *) alloca (strlen (fname) + pfile->max_include_len
278 + 2 + INCLUDE_LEN_FUDGE);
279 do
280 {
281 memcpy (name, path->name, path->nlen);
282 name[path->nlen] = '/';
283 strcpy (&name[path->nlen+1], fname);
284 _cpp_simplify_pathname (name);
285 if (CPP_OPTION (pfile, remap))
286 name = remap_filename (pfile, name, path);
287
288 f = open_include_file (pfile, name);
289 #ifdef EACCES
290 if (f == -1 && errno == EACCES)
291 {
292 cpp_error (pfile,
293 "included file `%s' exists but is not readable",
294 name);
295 return -1;
296 }
297 #endif
298 if (f >= 0)
299 break;
300 path = path->next;
301 }
302 while (path);
303 }
304 if (f == -1)
305 return -1;
306
307 ih = make_IHASH (name, fname, path, dummy.hash, slot);
308 *before = 0;
309 *ihash = ih;
310 return f;
311 }
312
313 /* Create a dummy IHASH entry for FNAME, and return its name pointer.
314 This is used by #line. */
315 const char *
316 _cpp_fake_ihash (pfile, fname)
317 cpp_reader *pfile;
318 const char *fname;
319 {
320 IHASH *ih, **slot;
321 IHASH dummy;
322
323 dummy.nshort = fname;
324 dummy.hash = _cpp_calc_hash ((const U_CHAR *)fname, strlen (fname));
325 slot = (IHASH **) htab_find_slot_with_hash (pfile->all_include_files,
326 (const void *) &dummy,
327 dummy.hash, INSERT);
328 if (*slot)
329 return (*slot)->name;
330 ih = make_IHASH (fname, 0, ABSOLUTE_PATH, dummy.hash, slot);
331 return ih->name;
332 }
333
334
335 /* The file_name_map structure holds a mapping of file names for a
336 particular directory. This mapping is read from the file named
337 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
338 map filenames on a file system with severe filename restrictions,
339 such as DOS. The format of the file name map file is just a series
340 of lines with two tokens on each line. The first token is the name
341 to map, and the second token is the actual name to use. */
342
343 struct file_name_map
344 {
345 struct file_name_map *map_next;
346 char *map_from;
347 char *map_to;
348 };
349
350 #define FILE_NAME_MAP_FILE "header.gcc"
351
352 /* Read a space delimited string of unlimited length from a stdio
353 file. */
354
355 static char *
356 read_filename_string (ch, f)
357 int ch;
358 FILE *f;
359 {
360 char *alloc, *set;
361 int len;
362
363 len = 20;
364 set = alloc = xmalloc (len + 1);
365 if (! is_space(ch))
366 {
367 *set++ = ch;
368 while ((ch = getc (f)) != EOF && ! is_space(ch))
369 {
370 if (set - alloc == len)
371 {
372 len *= 2;
373 alloc = xrealloc (alloc, len + 1);
374 set = alloc + len / 2;
375 }
376 *set++ = ch;
377 }
378 }
379 *set = '\0';
380 ungetc (ch, f);
381 return alloc;
382 }
383
384 /* This structure holds a linked list of file name maps, one per directory. */
385
386 struct file_name_map_list
387 {
388 struct file_name_map_list *map_list_next;
389 char *map_list_name;
390 struct file_name_map *map_list_map;
391 };
392
393 /* Read the file name map file for DIRNAME. */
394
395 static struct file_name_map *
396 read_name_map (pfile, dirname)
397 cpp_reader *pfile;
398 const char *dirname;
399 {
400 register struct file_name_map_list *map_list_ptr;
401 char *name;
402 FILE *f;
403
404 for (map_list_ptr = CPP_OPTION (pfile, map_list); map_list_ptr;
405 map_list_ptr = map_list_ptr->map_list_next)
406 if (! strcmp (map_list_ptr->map_list_name, dirname))
407 return map_list_ptr->map_list_map;
408
409 map_list_ptr = ((struct file_name_map_list *)
410 xmalloc (sizeof (struct file_name_map_list)));
411 map_list_ptr->map_list_name = xstrdup (dirname);
412
413 name = (char *) alloca (strlen (dirname) + strlen (FILE_NAME_MAP_FILE) + 2);
414 strcpy (name, dirname);
415 if (*dirname)
416 strcat (name, "/");
417 strcat (name, FILE_NAME_MAP_FILE);
418 f = fopen (name, "r");
419 if (!f)
420 map_list_ptr->map_list_map = (struct file_name_map *)-1;
421 else
422 {
423 int ch;
424 int dirlen = strlen (dirname);
425
426 while ((ch = getc (f)) != EOF)
427 {
428 char *from, *to;
429 struct file_name_map *ptr;
430
431 if (is_space(ch))
432 continue;
433 from = read_filename_string (ch, f);
434 while ((ch = getc (f)) != EOF && is_hspace(ch))
435 ;
436 to = read_filename_string (ch, f);
437
438 ptr = ((struct file_name_map *)
439 xmalloc (sizeof (struct file_name_map)));
440 ptr->map_from = from;
441
442 /* Make the real filename absolute. */
443 if (*to == '/')
444 ptr->map_to = to;
445 else
446 {
447 ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
448 strcpy (ptr->map_to, dirname);
449 ptr->map_to[dirlen] = '/';
450 strcpy (ptr->map_to + dirlen + 1, to);
451 free (to);
452 }
453
454 ptr->map_next = map_list_ptr->map_list_map;
455 map_list_ptr->map_list_map = ptr;
456
457 while ((ch = getc (f)) != '\n')
458 if (ch == EOF)
459 break;
460 }
461 fclose (f);
462 }
463
464 map_list_ptr->map_list_next = CPP_OPTION (pfile, map_list);
465 CPP_OPTION (pfile, map_list) = map_list_ptr;
466
467 return map_list_ptr->map_list_map;
468 }
469
470 /* Remap NAME based on the file_name_map (if any) for LOC. */
471
472 static char *
473 remap_filename (pfile, name, loc)
474 cpp_reader *pfile;
475 char *name;
476 struct file_name_list *loc;
477 {
478 struct file_name_map *map;
479 const char *from, *p, *dir;
480
481 if (! loc->name_map)
482 loc->name_map = read_name_map (pfile,
483 loc->name
484 ? loc->name : ".");
485
486 if (loc->name_map == (struct file_name_map *)-1)
487 return name;
488
489 from = name + strlen (loc->name) + 1;
490
491 for (map = loc->name_map; map; map = map->map_next)
492 if (!strcmp (map->map_from, from))
493 return map->map_to;
494
495 /* Try to find a mapping file for the particular directory we are
496 looking in. Thus #include <sys/types.h> will look up sys/types.h
497 in /usr/include/header.gcc and look up types.h in
498 /usr/include/sys/header.gcc. */
499 p = strrchr (name, '/');
500 if (!p)
501 p = name;
502 if (loc && loc->name
503 && strlen (loc->name) == (size_t) (p - name)
504 && !strncmp (loc->name, name, p - name))
505 /* FILENAME is in SEARCHPTR, which we've already checked. */
506 return name;
507
508 if (p == name)
509 {
510 dir = ".";
511 from = name;
512 }
513 else
514 {
515 char * newdir = (char *) alloca (p - name + 1);
516 memcpy (newdir, name, p - name);
517 newdir[p - name] = '\0';
518 dir = newdir;
519 from = p + 1;
520 }
521
522 for (map = read_name_map (pfile, dir); map; map = map->map_next)
523 if (! strcmp (map->map_from, name))
524 return map->map_to;
525
526 return name;
527 }
528
529
530 void
531 _cpp_execute_include (pfile, f, len, no_reinclude, search_start)
532 cpp_reader *pfile;
533 U_CHAR *f;
534 unsigned int len;
535 int no_reinclude;
536 struct file_name_list *search_start;
537 {
538 IHASH *ihash;
539 char *fname = (char *)f;
540 int fd;
541 int angle_brackets = fname[0] == '<';
542 int before;
543
544 if (!search_start)
545 {
546 if (angle_brackets)
547 search_start = CPP_OPTION (pfile, bracket_include);
548 else if (CPP_OPTION (pfile, ignore_srcdir))
549 search_start = CPP_OPTION (pfile, quote_include);
550 else
551 search_start = CPP_BUFFER (pfile)->actual_dir;
552 }
553
554 if (!search_start)
555 {
556 cpp_error (pfile, "No include path in which to find %s", fname);
557 return;
558 }
559
560 /* Remove quote marks. */
561 fname++;
562 len -= 2;
563 fname[len] = '\0';
564
565 fd = find_include_file (pfile, fname, search_start, &ihash, &before);
566
567 if (fd == -2)
568 return;
569
570 if (fd == -1)
571 {
572 if (CPP_OPTION (pfile, print_deps_missing_files)
573 && CPP_PRINT_DEPS (pfile) > (angle_brackets ||
574 (pfile->system_include_depth > 0)))
575 {
576 if (!angle_brackets)
577 deps_add_dep (pfile->deps, fname);
578 else
579 {
580 char *p;
581 struct file_name_list *ptr;
582 /* If requested as a system header, assume it belongs in
583 the first system header directory. */
584 if (CPP_OPTION (pfile, bracket_include))
585 ptr = CPP_OPTION (pfile, bracket_include);
586 else
587 ptr = CPP_OPTION (pfile, quote_include);
588
589 p = (char *) alloca (strlen (ptr->name)
590 + strlen (fname) + 2);
591 if (*ptr->name != '\0')
592 {
593 strcpy (p, ptr->name);
594 strcat (p, "/");
595 }
596 strcat (p, fname);
597 deps_add_dep (pfile->deps, p);
598 }
599 }
600 /* If -M was specified, and this header file won't be added to
601 the dependency list, then don't count this as an error,
602 because we can still produce correct output. Otherwise, we
603 can't produce correct output, because there may be
604 dependencies we need inside the missing file, and we don't
605 know what directory this missing file exists in. */
606 else if (CPP_PRINT_DEPS (pfile)
607 && (CPP_PRINT_DEPS (pfile)
608 <= (angle_brackets || (pfile->system_include_depth > 0))))
609 cpp_warning (pfile, "No include path in which to find %s", fname);
610 else
611 cpp_error_from_errno (pfile, fname);
612
613 return;
614 }
615
616 /* For -M, add the file to the dependencies on its first inclusion. */
617 if (!before && (CPP_PRINT_DEPS (pfile)
618 > (angle_brackets || (pfile->system_include_depth > 0))))
619 deps_add_dep (pfile->deps, ihash->name);
620
621 /* Handle -H option. */
622 if (CPP_OPTION (pfile, print_include_names))
623 {
624 cpp_buffer *fp = CPP_BUFFER (pfile);
625 while ((fp = CPP_PREV_BUFFER (fp)) != NULL)
626 putc ('.', stderr);
627 fprintf (stderr, " %s\n", ihash->name);
628 }
629
630 /* Actually process the file. */
631 if (no_reinclude)
632 ihash->control_macro = U"";
633
634 if (read_include_file (pfile, fd, ihash))
635 {
636 if (angle_brackets)
637 pfile->system_include_depth++;
638 }
639 }
640
641
642 /* Push an input buffer and load it up with the contents of FNAME.
643 If FNAME is "" or NULL, read standard input. */
644 int
645 cpp_read_file (pfile, fname)
646 cpp_reader *pfile;
647 const char *fname;
648 {
649 IHASH *ih, **slot;
650 IHASH dummy;
651 int f;
652
653 if (fname == NULL)
654 fname = "";
655
656 dummy.nshort = fname;
657 /* _cpp_calc_hash doesn't like zero-length strings. */
658 if (*fname == 0)
659 dummy.hash = 0;
660 else
661 dummy.hash = _cpp_calc_hash ((const U_CHAR *)fname, strlen (fname));
662 slot = (IHASH **) htab_find_slot_with_hash (pfile->all_include_files,
663 (const void *) &dummy,
664 dummy.hash, INSERT);
665 if (*slot && (ih = redundant_include_p (pfile, *slot, ABSOLUTE_PATH)))
666 {
667 if (ih == (IHASH *) -1)
668 return 1; /* Already included. */
669 }
670 else
671 ih = make_IHASH (fname, 0, ABSOLUTE_PATH, dummy.hash, slot);
672
673 if (*fname == '\0')
674 f = 0;
675 else
676 f = open_include_file (pfile, fname);
677
678 return read_include_file (pfile, f, ih);
679 }
680
681 /* Read the contents of FD into the buffer on the top of PFILE's stack.
682 IHASH points to the include hash entry for the file associated with
683 FD.
684
685 The caller is responsible for the cpp_push_buffer. */
686
687 static int
688 read_include_file (pfile, fd, ihash)
689 cpp_reader *pfile;
690 int fd;
691 IHASH *ihash;
692 {
693 struct stat st;
694 ssize_t length;
695 cpp_buffer *fp;
696
697 fp = cpp_push_buffer (pfile, NULL, 0);
698
699 if (fp == 0)
700 goto push_fail;
701
702 if (fstat (fd, &st) < 0)
703 goto perror_fail;
704
705 /* If fd points to a plain file, we might be able to mmap it; we can
706 definitely allocate the buffer all at once. If fd is a pipe or
707 terminal, we can't do either. If fd is something weird, like a
708 block device or a directory, we don't want to read it at all.
709
710 Unfortunately, different systems use different st.st_mode values
711 for pipes: some have S_ISFIFO, some S_ISSOCK, some are buggy and
712 zero the entire struct stat except a couple fields. Hence we don't
713 even try to figure out what something is, except for plain files,
714 directories, and block devices. */
715
716 if (S_ISREG (st.st_mode))
717 {
718 ssize_t st_size;
719
720 /* off_t might have a wider range than ssize_t - in other words,
721 the max size of a file might be bigger than the address
722 space. We can't handle a file that large. (Anyone with
723 a single source file bigger than 2GB needs to rethink
724 their coding style.) */
725 if (st.st_size > SSIZE_MAX)
726 {
727 cpp_error (pfile, "%s is too large", ihash->name);
728 goto fail;
729 }
730 st_size = st.st_size;
731 length = read_file (fp, fd, st_size);
732 if (length == -1)
733 goto perror_fail;
734 if (length < st_size)
735 cpp_warning (pfile, "%s is shorter than expected\n", ihash->name);
736 }
737 else if (S_ISBLK (st.st_mode))
738 {
739 cpp_error (pfile, "%s is a block device", ihash->name);
740 goto fail;
741 }
742 else if (S_ISDIR (st.st_mode))
743 {
744 cpp_error (pfile, "%s is a directory", ihash->name);
745 goto fail;
746 }
747 else
748 {
749 /* 8 kilobytes is a sensible starting size. It ought to be
750 bigger than the kernel pipe buffer, and it's definitely
751 bigger than the majority of C source files. */
752 length = read_with_read (fp, fd, 8 * 1024);
753 if (length == -1)
754 goto perror_fail;
755 }
756
757 /* These must be set before prescan. */
758 fp->ihash = ihash;
759 fp->nominal_fname = ihash->name;
760
761 if (length == 0)
762 ihash->control_macro = U""; /* never re-include */
763 else
764 /* Temporary - I hope. */
765 length = _cpp_prescan (pfile, fp, length);
766
767 fp->rlimit = fp->buf + length;
768 fp->cur = fp->buf;
769 if (ihash->foundhere != ABSOLUTE_PATH)
770 fp->system_header_p = ihash->foundhere->sysp;
771 fp->lineno = 1;
772 fp->line_base = fp->buf;
773
774 /* The ->actual_dir field is only used when ignore_srcdir is not in effect;
775 see do_include */
776 if (!CPP_OPTION (pfile, ignore_srcdir))
777 fp->actual_dir = actual_directory (pfile, ihash->name);
778
779 pfile->input_stack_listing_current = 0;
780 pfile->only_seen_white = 2;
781 close (fd);
782 return 1;
783
784 perror_fail:
785 cpp_error_from_errno (pfile, ihash->name);
786 fail:
787 cpp_pop_buffer (pfile);
788 push_fail:
789 close (fd);
790 return 0;
791 }
792
793 static ssize_t
794 read_file (fp, fd, size)
795 cpp_buffer *fp;
796 int fd;
797 ssize_t size;
798 {
799 static int pagesize = -1;
800
801 if (size == 0)
802 return 0;
803
804 if (pagesize == -1)
805 pagesize = getpagesize ();
806
807 #if MMAP_THRESHOLD
808 if (size / pagesize >= MMAP_THRESHOLD)
809 {
810 const U_CHAR *result
811 = (const U_CHAR *) mmap (0, size, PROT_READ, MAP_PRIVATE, fd, 0);
812 if (result != (const U_CHAR *)-1)
813 {
814 fp->buf = result;
815 fp->mapped = 1;
816 return size;
817 }
818 }
819 /* If mmap fails, try read. If there's really a problem, read will
820 fail too. */
821 #endif
822
823 return read_with_read (fp, fd, size);
824 }
825
826 static ssize_t
827 read_with_read (fp, fd, size)
828 cpp_buffer *fp;
829 int fd;
830 ssize_t size;
831 {
832 ssize_t offset, count;
833 U_CHAR *buf;
834
835 buf = (U_CHAR *) xmalloc (size);
836 offset = 0;
837 while ((count = read (fd, buf + offset, size - offset)) > 0)
838 {
839 offset += count;
840 if (offset == size)
841 buf = xrealloc (buf, (size *= 2));
842 }
843 if (count < 0)
844 {
845 free (buf);
846 return -1;
847 }
848 if (offset == 0)
849 {
850 free (buf);
851 return 0;
852 }
853
854 if (offset < size)
855 buf = xrealloc (buf, offset);
856 fp->buf = buf;
857 fp->mapped = 0;
858 return offset;
859 }
860
861 /* Given a path FNAME, extract the directory component and place it
862 onto the actual_dirs list. Return a pointer to the allocated
863 file_name_list structure. These structures are used to implement
864 current-directory "" include searching. */
865
866 static struct file_name_list *
867 actual_directory (pfile, fname)
868 cpp_reader *pfile;
869 const char *fname;
870 {
871 char *last_slash, *dir;
872 size_t dlen;
873 struct file_name_list *x;
874
875 dir = xstrdup (fname);
876 last_slash = strrchr (dir, '/');
877 if (last_slash)
878 {
879 if (last_slash == dir)
880 {
881 dlen = 1;
882 last_slash[1] = '\0';
883 }
884 else
885 {
886 dlen = last_slash - dir;
887 *last_slash = '\0';
888 }
889 }
890 else
891 {
892 dir[0] = '.';
893 dir[1] = '\0';
894 dlen = 1;
895 }
896
897 if (dlen > pfile->max_include_len)
898 pfile->max_include_len = dlen;
899
900 for (x = pfile->actual_dirs; x; x = x->alloc)
901 if (!strcmp (x->name, dir))
902 {
903 free (dir);
904 return x;
905 }
906
907 /* Not found, make a new one. */
908 x = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
909 x->name = dir;
910 x->nlen = dlen;
911 x->next = CPP_OPTION (pfile, quote_include);
912 x->alloc = pfile->actual_dirs;
913 x->sysp = CPP_BUFFER (pfile)->system_header_p;
914 x->name_map = NULL;
915
916 pfile->actual_dirs = x;
917 return x;
918 }
919
920 /* Simplify a path name in place, deleting redundant components. This
921 reduces OS overhead and guarantees that equivalent paths compare
922 the same (modulo symlinks).
923
924 Transforms made:
925 foo/bar/../quux foo/quux
926 foo/./bar foo/bar
927 foo//bar foo/bar
928 /../quux /quux
929 //quux //quux (POSIX allows leading // as a namespace escape)
930
931 Guarantees no trailing slashes. All transforms reduce the length
932 of the string.
933 */
934 void
935 _cpp_simplify_pathname (path)
936 char *path;
937 {
938 char *from, *to;
939 char *base;
940 int absolute = 0;
941
942 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
943 /* Convert all backslashes to slashes. */
944 for (from = path; *from; from++)
945 if (*from == '\\') *from = '/';
946
947 /* Skip over leading drive letter if present. */
948 if (ISALPHA (path[0]) && path[1] == ':')
949 from = to = &path[2];
950 else
951 from = to = path;
952 #else
953 from = to = path;
954 #endif
955
956 /* Remove redundant initial /s. */
957 if (*from == '/')
958 {
959 absolute = 1;
960 to++;
961 from++;
962 if (*from == '/')
963 {
964 if (*++from == '/')
965 /* 3 or more initial /s are equivalent to 1 /. */
966 while (*++from == '/');
967 else
968 /* On some hosts // differs from /; Posix allows this. */
969 to++;
970 }
971 }
972 base = to;
973
974 for (;;)
975 {
976 while (*from == '/')
977 from++;
978
979 if (from[0] == '.' && from[1] == '/')
980 from += 2;
981 else if (from[0] == '.' && from[1] == '\0')
982 goto done;
983 else if (from[0] == '.' && from[1] == '.' && from[2] == '/')
984 {
985 if (base == to)
986 {
987 if (absolute)
988 from += 3;
989 else
990 {
991 *to++ = *from++;
992 *to++ = *from++;
993 *to++ = *from++;
994 base = to;
995 }
996 }
997 else
998 {
999 to -= 2;
1000 while (to > base && *to != '/') to--;
1001 if (*to == '/')
1002 to++;
1003 from += 3;
1004 }
1005 }
1006 else if (from[0] == '.' && from[1] == '.' && from[2] == '\0')
1007 {
1008 if (base == to)
1009 {
1010 if (!absolute)
1011 {
1012 *to++ = *from++;
1013 *to++ = *from++;
1014 }
1015 }
1016 else
1017 {
1018 to -= 2;
1019 while (to > base && *to != '/') to--;
1020 if (*to == '/')
1021 to++;
1022 }
1023 goto done;
1024 }
1025 else
1026 /* Copy this component and trailing /, if any. */
1027 while ((*to++ = *from++) != '/')
1028 {
1029 if (!to[-1])
1030 {
1031 to--;
1032 goto done;
1033 }
1034 }
1035
1036 }
1037
1038 done:
1039 /* Trim trailing slash */
1040 if (to[0] == '/' && (!absolute || to > path+1))
1041 to--;
1042
1043 /* Change the empty string to "." so that stat() on the result
1044 will always work. */
1045 if (to == path)
1046 *to++ = '.';
1047
1048 *to = '\0';
1049
1050 return;
1051 }
1052
1053 /* It is not clear when this should be used if at all, so I've
1054 disabled it until someone who understands VMS can look at it. */
1055 #if 0
1056
1057 /* Under VMS we need to fix up the "include" specification filename.
1058
1059 Rules for possible conversions
1060
1061 fullname tried paths
1062
1063 name name
1064 ./dir/name [.dir]name
1065 /dir/name dir:name
1066 /name [000000]name, name
1067 dir/name dir:[000000]name, dir:name, dir/name
1068 dir1/dir2/name dir1:[dir2]name, dir1:[000000.dir2]name
1069 path:/name path:[000000]name, path:name
1070 path:/dir/name path:[000000.dir]name, path:[dir]name
1071 path:dir/name path:[dir]name
1072 [path]:[dir]name [path.dir]name
1073 path/[dir]name [path.dir]name
1074
1075 The path:/name input is constructed when expanding <> includes. */
1076
1077
1078 static void
1079 hack_vms_include_specification (fullname)
1080 char *fullname;
1081 {
1082 register char *basename, *unixname, *local_ptr, *first_slash;
1083 int f, check_filename_before_returning, must_revert;
1084 char Local[512];
1085
1086 check_filename_before_returning = 0;
1087 must_revert = 0;
1088 /* See if we can find a 1st slash. If not, there's no path information. */
1089 first_slash = strchr (fullname, '/');
1090 if (first_slash == 0)
1091 return 0; /* Nothing to do!!! */
1092
1093 /* construct device spec if none given. */
1094
1095 if (strchr (fullname, ':') == 0)
1096 {
1097
1098 /* If fullname has a slash, take it as device spec. */
1099
1100 if (first_slash == fullname)
1101 {
1102 first_slash = strchr (fullname + 1, '/'); /* 2nd slash ? */
1103 if (first_slash)
1104 *first_slash = ':'; /* make device spec */
1105 for (basename = fullname; *basename != 0; basename++)
1106 *basename = *(basename+1); /* remove leading slash */
1107 }
1108 else if ((first_slash[-1] != '.') /* keep ':/', './' */
1109 && (first_slash[-1] != ':')
1110 && (first_slash[-1] != ']')) /* or a vms path */
1111 {
1112 *first_slash = ':';
1113 }
1114 else if ((first_slash[1] == '[') /* skip './' in './[dir' */
1115 && (first_slash[-1] == '.'))
1116 fullname += 2;
1117 }
1118
1119 /* Get part after first ':' (basename[-1] == ':')
1120 or last '/' (basename[-1] == '/'). */
1121
1122 basename = base_name (fullname);
1123
1124 local_ptr = Local; /* initialize */
1125
1126 /* We are trying to do a number of things here. First of all, we are
1127 trying to hammer the filenames into a standard format, such that later
1128 processing can handle them.
1129
1130 If the file name contains something like [dir.], then it recognizes this
1131 as a root, and strips the ".]". Later processing will add whatever is
1132 needed to get things working properly.
1133
1134 If no device is specified, then the first directory name is taken to be
1135 a device name (or a rooted logical). */
1136
1137 /* Point to the UNIX filename part (which needs to be fixed!)
1138 but skip vms path information.
1139 [basename != fullname since first_slash != 0]. */
1140
1141 if ((basename[-1] == ':') /* vms path spec. */
1142 || (basename[-1] == ']')
1143 || (basename[-1] == '>'))
1144 unixname = basename;
1145 else
1146 unixname = fullname;
1147
1148 if (*unixname == '/')
1149 unixname++;
1150
1151 /* If the directory spec is not rooted, we can just copy
1152 the UNIX filename part and we are done. */
1153
1154 if (((basename - fullname) > 1)
1155 && ( (basename[-1] == ']')
1156 || (basename[-1] == '>')))
1157 {
1158 if (basename[-2] != '.')
1159 {
1160
1161 /* The VMS part ends in a `]', and the preceding character is not a `.'.
1162 -> PATH]:/name (basename = '/name', unixname = 'name')
1163 We strip the `]', and then splice the two parts of the name in the
1164 usual way. Given the default locations for include files,
1165 we will only use this code if the user specifies alternate locations
1166 with the /include (-I) switch on the command line. */
1167
1168 basename -= 1; /* Strip "]" */
1169 unixname--; /* backspace */
1170 }
1171 else
1172 {
1173
1174 /* The VMS part has a ".]" at the end, and this will not do. Later
1175 processing will add a second directory spec, and this would be a syntax
1176 error. Thus we strip the ".]", and thus merge the directory specs.
1177 We also backspace unixname, so that it points to a '/'. This inhibits the
1178 generation of the 000000 root directory spec (which does not belong here
1179 in this case). */
1180
1181 basename -= 2; /* Strip ".]" */
1182 unixname--; /* backspace */
1183 }
1184 }
1185
1186 else
1187
1188 {
1189
1190 /* We drop in here if there is no VMS style directory specification yet.
1191 If there is no device specification either, we make the first dir a
1192 device and try that. If we do not do this, then we will be essentially
1193 searching the users default directory (as if they did a #include "asdf.h").
1194
1195 Then all we need to do is to push a '[' into the output string. Later
1196 processing will fill this in, and close the bracket. */
1197
1198 if ((unixname != fullname) /* vms path spec found. */
1199 && (basename[-1] != ':'))
1200 *local_ptr++ = ':'; /* dev not in spec. take first dir */
1201
1202 *local_ptr++ = '['; /* Open the directory specification */
1203 }
1204
1205 if (unixname == fullname) /* no vms dir spec. */
1206 {
1207 must_revert = 1;
1208 if ((first_slash != 0) /* unix dir spec. */
1209 && (*unixname != '/') /* not beginning with '/' */
1210 && (*unixname != '.')) /* or './' or '../' */
1211 *local_ptr++ = '.'; /* dir is local ! */
1212 }
1213
1214 /* at this point we assume that we have the device spec, and (at least
1215 the opening "[" for a directory specification. We may have directories
1216 specified already.
1217
1218 If there are no other slashes then the filename will be
1219 in the "root" directory. Otherwise, we need to add
1220 directory specifications. */
1221
1222 if (strchr (unixname, '/') == 0)
1223 {
1224 /* if no directories specified yet and none are following. */
1225 if (local_ptr[-1] == '[')
1226 {
1227 /* Just add "000000]" as the directory string */
1228 strcpy (local_ptr, "000000]");
1229 local_ptr += strlen (local_ptr);
1230 check_filename_before_returning = 1; /* we might need to fool with this later */
1231 }
1232 }
1233 else
1234 {
1235
1236 /* As long as there are still subdirectories to add, do them. */
1237 while (strchr (unixname, '/') != 0)
1238 {
1239 /* If this token is "." we can ignore it
1240 if it's not at the beginning of a path. */
1241 if ((unixname[0] == '.') && (unixname[1] == '/'))
1242 {
1243 /* remove it at beginning of path. */
1244 if ( ((unixname == fullname) /* no device spec */
1245 && (fullname+2 != basename)) /* starts with ./ */
1246 /* or */
1247 || ((basename[-1] == ':') /* device spec */
1248 && (unixname-1 == basename))) /* and ./ afterwards */
1249 *local_ptr++ = '.'; /* make '[.' start of path. */
1250 unixname += 2;
1251 continue;
1252 }
1253
1254 /* Add a subdirectory spec. Do not duplicate "." */
1255 if ( local_ptr[-1] != '.'
1256 && local_ptr[-1] != '['
1257 && local_ptr[-1] != '<')
1258 *local_ptr++ = '.';
1259
1260 /* If this is ".." then the spec becomes "-" */
1261 if ( (unixname[0] == '.')
1262 && (unixname[1] == '.')
1263 && (unixname[2] == '/'))
1264 {
1265 /* Add "-" and skip the ".." */
1266 if ((local_ptr[-1] == '.')
1267 && (local_ptr[-2] == '['))
1268 local_ptr--; /* prevent [.- */
1269 *local_ptr++ = '-';
1270 unixname += 3;
1271 continue;
1272 }
1273
1274 /* Copy the subdirectory */
1275 while (*unixname != '/')
1276 *local_ptr++= *unixname++;
1277
1278 unixname++; /* Skip the "/" */
1279 }
1280
1281 /* Close the directory specification */
1282 if (local_ptr[-1] == '.') /* no trailing periods */
1283 local_ptr--;
1284
1285 if (local_ptr[-1] == '[') /* no dir needed */
1286 local_ptr--;
1287 else
1288 *local_ptr++ = ']';
1289 }
1290
1291 /* Now add the filename. */
1292
1293 while (*unixname)
1294 *local_ptr++ = *unixname++;
1295 *local_ptr = 0;
1296
1297 /* Now append it to the original VMS spec. */
1298
1299 strcpy ((must_revert==1)?fullname:basename, Local);
1300
1301 /* If we put a [000000] in the filename, try to open it first. If this fails,
1302 remove the [000000], and return that name. This provides flexibility
1303 to the user in that they can use both rooted and non-rooted logical names
1304 to point to the location of the file. */
1305
1306 if (check_filename_before_returning)
1307 {
1308 f = open (fullname, O_RDONLY|O_NONBLOCK);
1309 if (f >= 0)
1310 {
1311 /* The file name is OK as it is, so return it as is. */
1312 close (f);
1313 return 1;
1314 }
1315
1316 /* The filename did not work. Try to remove the [000000] from the name,
1317 and return it. */
1318
1319 basename = strchr (fullname, '[');
1320 local_ptr = strchr (fullname, ']') + 1;
1321 strcpy (basename, local_ptr); /* this gets rid of it */
1322
1323 }
1324
1325 return 1;
1326 }
1327 #endif /* VMS */