fix typo
[official-gcc.git] / gcc / cppfiles.c
blob71bb657c685b90d71a715d0b342c02326c86501a
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
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.
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.
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. */
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"
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
37 #else /* No MMAP_FILE */
38 # undef MMAP_THRESHOLD
39 # define MMAP_THRESHOLD 0
40 #endif
42 #ifndef O_BINARY
43 # define O_BINARY 0
44 #endif
46 static IHASH *redundant_include_p PARAMS ((IHASH *, struct file_name_list *));
47 static IHASH *make_IHASH PARAMS ((const char *, const char *,
48 struct file_name_list *,
49 unsigned int, IHASH **));
50 static struct file_name_map *read_name_map
51 PARAMS ((cpp_reader *, const char *));
52 static char *read_filename_string PARAMS ((int, FILE *));
53 static char *remap_filename PARAMS ((cpp_reader *, char *,
54 struct file_name_list *));
55 static struct file_name_list *actual_directory
56 PARAMS ((cpp_reader *, const char *));
57 static unsigned int hash_IHASH PARAMS ((const void *));
58 static int eq_IHASH PARAMS ((const void *, const void *));
59 static int find_include_file PARAMS ((cpp_reader *, const char *,
60 struct file_name_list *,
61 IHASH **, int *));
62 static inline int open_include_file PARAMS ((cpp_reader *, const char *));
63 static int read_include_file PARAMS ((cpp_reader *, int, IHASH *));
64 static ssize_t read_with_read PARAMS ((cpp_buffer *, int, ssize_t));
65 static ssize_t read_file PARAMS ((cpp_buffer *, int, ssize_t));
67 #if 0
68 static void hack_vms_include_specification PARAMS ((char *));
69 #endif
71 /* Initial size of include hash table. */
72 #define IHASHSIZE 50
74 #ifndef INCLUDE_LEN_FUDGE
75 #define INCLUDE_LEN_FUDGE 0
76 #endif
78 /* Calculate hash of an IHASH entry. */
79 static unsigned int
80 hash_IHASH (x)
81 const void *x;
83 const IHASH *i = (const IHASH *)x;
84 return i->hash;
87 /* Compare an existing IHASH structure with a potential one. */
88 static int
89 eq_IHASH (x, y)
90 const void *x;
91 const void *y;
93 const char *a = ((const IHASH *)x)->nshort;
94 const char *b = ((const IHASH *)y)->nshort;
95 return !strcmp (a, b);
98 /* Init the hash table. In here so it can see the hash and eq functions. */
99 void
100 _cpp_init_include_hash (pfile)
101 cpp_reader *pfile;
103 pfile->all_include_files
104 = htab_create (IHASHSIZE, hash_IHASH, eq_IHASH, free);
107 /* Return 0 if the file pointed to by IHASH has never been included before,
108 -1 if it has been included before and need not be again,
109 or a pointer to an IHASH entry which is the file to be reread.
110 "Never before" is with respect to the position in ILIST.
112 This will not detect redundancies involving odd uses of the
113 `current directory' rule for "" includes. They aren't quite
114 pathological, but I think they are rare enough not to worry about.
115 The simplest example is:
117 top.c:
118 #include "a/a.h"
119 #include "b/b.h"
121 a/a.h:
122 #include "../b/b.h"
124 and the problem is that for `current directory' includes,
125 ihash->foundhere is not on any of the global include chains,
126 so the test below (i->foundhere == l) may be false even when
127 the directories are in fact the same. */
129 static IHASH *
130 redundant_include_p (ihash, ilist)
131 IHASH *ihash;
132 struct file_name_list *ilist;
134 struct file_name_list *l;
135 IHASH *i;
137 if (! ihash->foundhere)
138 return 0;
140 for (i = ihash; i; i = i->next_this_file)
141 for (l = ilist; l; l = l->next)
142 if (i->foundhere == l)
143 /* The cmacro works like this: If it's NULL, the file is to
144 be included again. If it's NEVER_REINCLUDE, the file is
145 never to be included again. Otherwise it is a macro
146 hashnode, and the file is to be included again if the
147 macro is not defined. */
148 return (i->cmacro
149 && (i->cmacro == NEVER_REINCLUDE
150 || i->cmacro->type != T_VOID))
151 ? (IHASH *)-1 : i;
153 return 0;
156 /* Return 1 if the file named by FNAME has been included before in
157 any context, 0 otherwise. */
159 cpp_included (pfile, fname)
160 cpp_reader *pfile;
161 const char *fname;
163 IHASH dummy, *ptr;
164 dummy.nshort = fname;
165 dummy.hash = _cpp_calc_hash ((const U_CHAR *)fname, strlen (fname));
166 ptr = htab_find_with_hash (pfile->all_include_files,
167 (const void *)&dummy, dummy.hash);
168 return (ptr != NULL);
171 /* Create an IHASH entry and insert it in SLOT. */
172 static IHASH *
173 make_IHASH (name, fname, path, hash, slot)
174 const char *name, *fname;
175 struct file_name_list *path;
176 unsigned int hash;
177 IHASH **slot;
179 IHASH *ih;
180 if (path == ABSOLUTE_PATH)
182 ih = (IHASH *) xmalloc (sizeof (IHASH) + strlen (name));
183 ih->nshort = ih->name;
185 else
187 char *s;
189 if ((s = strstr (name, fname)) != NULL)
191 ih = (IHASH *) xmalloc (sizeof (IHASH) + strlen (name));
192 ih->nshort = ih->name + (s - name);
194 else
196 ih = (IHASH *) xmalloc (sizeof (IHASH) + strlen (name)
197 + strlen (fname) + 1);
198 ih->nshort = ih->name + strlen (name) + 1;
199 strcpy ((char *)ih->nshort, fname);
202 strcpy ((char *)ih->name, name);
203 ih->foundhere = path;
204 ih->cmacro = NULL;
205 ih->hash = hash;
206 ih->next_this_file = *slot;
207 *slot = ih;
208 return ih;
211 /* Centralize calls to open(2) here. This provides a hook for future
212 changes which might, e.g. look for and open a precompiled version
213 of the header. It also means all the magic currently associated
214 with calling open is in one place, and if we ever need more, it'll
215 be in one place too.
217 We used to open files in nonblocking mode, but that caused more
218 problems than it solved. Do take care not to acquire a controlling
219 terminal by mistake (this can't happen on sane systems, but
220 paranoia is a virtue).
222 Use the three-argument form of open even though we aren't
223 specifying O_CREAT, to defend against broken system headers.
225 O_BINARY tells some runtime libraries (notably DJGPP) not to do
226 newline translation; we can handle DOS line breaks just fine
227 ourselves. */
229 static inline int
230 open_include_file (pfile, filename)
231 cpp_reader *pfile ATTRIBUTE_UNUSED;
232 const char *filename;
234 return open (filename, O_RDONLY|O_NOCTTY|O_BINARY, 0666);
237 /* Search for include file FNAME in the include chain starting at
238 SEARCH_START. Return -2 if this file doesn't need to be included
239 (because it was included already and it's marked idempotent),
240 -1 if an error occurred, or a file descriptor open on the file.
241 *IHASH is set to point to the include hash entry for this file, and
242 *BEFORE is set to 1 if the file was included before (but needs to be read
243 again). */
244 static int
245 find_include_file (pfile, fname, search_start, ihash, before)
246 cpp_reader *pfile;
247 const char *fname;
248 struct file_name_list *search_start;
249 IHASH **ihash;
250 int *before;
252 struct file_name_list *path;
253 IHASH *ih, **slot;
254 IHASH dummy;
255 int f;
256 char *name;
258 dummy.nshort = fname;
259 dummy.hash = _cpp_calc_hash ((const U_CHAR *)fname, strlen (fname));
260 path = (fname[0] == '/') ? ABSOLUTE_PATH : search_start;
261 slot = (IHASH **) htab_find_slot_with_hash (pfile->all_include_files,
262 (const void *) &dummy,
263 dummy.hash, INSERT);
265 if (*slot && (ih = redundant_include_p (*slot, path)))
267 if (ih == (IHASH *)-1)
268 return -2;
270 *before = 1;
271 *ihash = ih;
272 return open_include_file (pfile, ih->name);
275 if (path == ABSOLUTE_PATH)
277 name = (char *) fname;
278 f = open_include_file (pfile, name);
280 else
282 /* Search directory path, trying to open the file. */
283 name = (char *) alloca (strlen (fname) + pfile->max_include_len
284 + 2 + INCLUDE_LEN_FUDGE);
287 memcpy (name, path->name, path->nlen);
288 name[path->nlen] = '/';
289 strcpy (&name[path->nlen+1], fname);
290 _cpp_simplify_pathname (name);
291 if (CPP_OPTION (pfile, remap))
292 name = remap_filename (pfile, name, path);
294 f = open_include_file (pfile, name);
295 #ifdef EACCES
296 if (f == -1 && errno == EACCES)
298 cpp_error (pfile,
299 "included file `%s' exists but is not readable",
300 name);
301 return -1;
303 #endif
304 if (f >= 0)
305 break;
306 path = path->next;
308 while (path);
310 if (f == -1)
311 return -1;
313 ih = make_IHASH (name, fname, path, dummy.hash, slot);
314 *before = 0;
315 *ihash = ih;
316 return f;
319 /* Create a dummy IHASH entry for FNAME, and return its name pointer.
320 This is used by #line. */
321 const char *
322 _cpp_fake_ihash (pfile, fname)
323 cpp_reader *pfile;
324 const char *fname;
326 IHASH *ih, **slot;
327 IHASH dummy;
329 dummy.nshort = fname;
330 dummy.hash = _cpp_calc_hash ((const U_CHAR *)fname, strlen (fname));
331 slot = (IHASH **) htab_find_slot_with_hash (pfile->all_include_files,
332 (const void *) &dummy,
333 dummy.hash, INSERT);
334 if (*slot)
335 return (*slot)->name;
336 ih = make_IHASH (fname, 0, ABSOLUTE_PATH, dummy.hash, slot);
337 return ih->name;
341 /* The file_name_map structure holds a mapping of file names for a
342 particular directory. This mapping is read from the file named
343 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
344 map filenames on a file system with severe filename restrictions,
345 such as DOS. The format of the file name map file is just a series
346 of lines with two tokens on each line. The first token is the name
347 to map, and the second token is the actual name to use. */
349 struct file_name_map
351 struct file_name_map *map_next;
352 char *map_from;
353 char *map_to;
356 #define FILE_NAME_MAP_FILE "header.gcc"
358 /* Read a space delimited string of unlimited length from a stdio
359 file. */
361 static char *
362 read_filename_string (ch, f)
363 int ch;
364 FILE *f;
366 char *alloc, *set;
367 int len;
369 len = 20;
370 set = alloc = xmalloc (len + 1);
371 if (! is_space(ch))
373 *set++ = ch;
374 while ((ch = getc (f)) != EOF && ! is_space(ch))
376 if (set - alloc == len)
378 len *= 2;
379 alloc = xrealloc (alloc, len + 1);
380 set = alloc + len / 2;
382 *set++ = ch;
385 *set = '\0';
386 ungetc (ch, f);
387 return alloc;
390 /* This structure holds a linked list of file name maps, one per directory. */
392 struct file_name_map_list
394 struct file_name_map_list *map_list_next;
395 char *map_list_name;
396 struct file_name_map *map_list_map;
399 /* Read the file name map file for DIRNAME. */
401 static struct file_name_map *
402 read_name_map (pfile, dirname)
403 cpp_reader *pfile;
404 const char *dirname;
406 register struct file_name_map_list *map_list_ptr;
407 char *name;
408 FILE *f;
410 for (map_list_ptr = CPP_OPTION (pfile, map_list); map_list_ptr;
411 map_list_ptr = map_list_ptr->map_list_next)
412 if (! strcmp (map_list_ptr->map_list_name, dirname))
413 return map_list_ptr->map_list_map;
415 map_list_ptr = ((struct file_name_map_list *)
416 xmalloc (sizeof (struct file_name_map_list)));
417 map_list_ptr->map_list_name = xstrdup (dirname);
419 name = (char *) alloca (strlen (dirname) + strlen (FILE_NAME_MAP_FILE) + 2);
420 strcpy (name, dirname);
421 if (*dirname)
422 strcat (name, "/");
423 strcat (name, FILE_NAME_MAP_FILE);
424 f = fopen (name, "r");
425 if (!f)
426 map_list_ptr->map_list_map = (struct file_name_map *)-1;
427 else
429 int ch;
430 int dirlen = strlen (dirname);
432 while ((ch = getc (f)) != EOF)
434 char *from, *to;
435 struct file_name_map *ptr;
437 if (is_space(ch))
438 continue;
439 from = read_filename_string (ch, f);
440 while ((ch = getc (f)) != EOF && is_hspace(ch))
442 to = read_filename_string (ch, f);
444 ptr = ((struct file_name_map *)
445 xmalloc (sizeof (struct file_name_map)));
446 ptr->map_from = from;
448 /* Make the real filename absolute. */
449 if (*to == '/')
450 ptr->map_to = to;
451 else
453 ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
454 strcpy (ptr->map_to, dirname);
455 ptr->map_to[dirlen] = '/';
456 strcpy (ptr->map_to + dirlen + 1, to);
457 free (to);
460 ptr->map_next = map_list_ptr->map_list_map;
461 map_list_ptr->map_list_map = ptr;
463 while ((ch = getc (f)) != '\n')
464 if (ch == EOF)
465 break;
467 fclose (f);
470 map_list_ptr->map_list_next = CPP_OPTION (pfile, map_list);
471 CPP_OPTION (pfile, map_list) = map_list_ptr;
473 return map_list_ptr->map_list_map;
476 /* Remap NAME based on the file_name_map (if any) for LOC. */
478 static char *
479 remap_filename (pfile, name, loc)
480 cpp_reader *pfile;
481 char *name;
482 struct file_name_list *loc;
484 struct file_name_map *map;
485 const char *from, *p, *dir;
487 if (! loc->name_map)
488 loc->name_map = read_name_map (pfile,
489 loc->name
490 ? loc->name : ".");
492 if (loc->name_map == (struct file_name_map *)-1)
493 return name;
495 from = name + strlen (loc->name) + 1;
497 for (map = loc->name_map; map; map = map->map_next)
498 if (!strcmp (map->map_from, from))
499 return map->map_to;
501 /* Try to find a mapping file for the particular directory we are
502 looking in. Thus #include <sys/types.h> will look up sys/types.h
503 in /usr/include/header.gcc and look up types.h in
504 /usr/include/sys/header.gcc. */
505 p = strrchr (name, '/');
506 if (!p)
507 p = name;
508 if (loc && loc->name
509 && strlen (loc->name) == (size_t) (p - name)
510 && !strncmp (loc->name, name, p - name))
511 /* FILENAME is in SEARCHPTR, which we've already checked. */
512 return name;
514 if (p == name)
516 dir = ".";
517 from = name;
519 else
521 char * newdir = (char *) alloca (p - name + 1);
522 memcpy (newdir, name, p - name);
523 newdir[p - name] = '\0';
524 dir = newdir;
525 from = p + 1;
528 for (map = read_name_map (pfile, dir); map; map = map->map_next)
529 if (! strcmp (map->map_from, name))
530 return map->map_to;
532 return name;
536 void
537 _cpp_execute_include (pfile, f, len, no_reinclude, search_start)
538 cpp_reader *pfile;
539 U_CHAR *f;
540 unsigned int len;
541 int no_reinclude;
542 struct file_name_list *search_start;
544 IHASH *ihash;
545 char *fname = (char *)f;
546 int fd;
547 int angle_brackets = fname[0] == '<';
548 int before;
550 if (!search_start)
552 if (angle_brackets)
553 search_start = CPP_OPTION (pfile, bracket_include);
554 else if (CPP_OPTION (pfile, ignore_srcdir))
555 search_start = CPP_OPTION (pfile, quote_include);
556 else
557 search_start = CPP_BUFFER (pfile)->actual_dir;
560 if (!search_start)
562 cpp_error (pfile, "No include path in which to find %s", fname);
563 return;
566 /* Remove quote marks. */
567 fname++;
568 len -= 2;
569 fname[len] = '\0';
571 fd = find_include_file (pfile, fname, search_start, &ihash, &before);
573 if (fd == -2)
574 return;
576 if (fd == -1)
578 if (CPP_OPTION (pfile, print_deps_missing_files)
579 && CPP_PRINT_DEPS (pfile) > (angle_brackets ||
580 (pfile->system_include_depth > 0)))
582 if (!angle_brackets)
583 deps_add_dep (pfile->deps, fname);
584 else
586 char *p;
587 struct file_name_list *ptr;
588 /* If requested as a system header, assume it belongs in
589 the first system header directory. */
590 if (CPP_OPTION (pfile, bracket_include))
591 ptr = CPP_OPTION (pfile, bracket_include);
592 else
593 ptr = CPP_OPTION (pfile, quote_include);
595 p = (char *) alloca (strlen (ptr->name)
596 + strlen (fname) + 2);
597 if (*ptr->name != '\0')
599 strcpy (p, ptr->name);
600 strcat (p, "/");
602 strcat (p, fname);
603 deps_add_dep (pfile->deps, p);
606 /* If -M was specified, and this header file won't be added to
607 the dependency list, then don't count this as an error,
608 because we can still produce correct output. Otherwise, we
609 can't produce correct output, because there may be
610 dependencies we need inside the missing file, and we don't
611 know what directory this missing file exists in. */
612 else if (CPP_PRINT_DEPS (pfile)
613 && (CPP_PRINT_DEPS (pfile)
614 <= (angle_brackets || (pfile->system_include_depth > 0))))
615 cpp_warning (pfile, "No include path in which to find %s", fname);
616 else
617 cpp_error_from_errno (pfile, fname);
619 return;
622 /* For -M, add the file to the dependencies on its first inclusion. */
623 if (!before && (CPP_PRINT_DEPS (pfile)
624 > (angle_brackets || (pfile->system_include_depth > 0))))
625 deps_add_dep (pfile->deps, ihash->name);
627 /* Handle -H option. */
628 if (CPP_OPTION (pfile, print_include_names))
630 cpp_buffer *fp = CPP_BUFFER (pfile);
631 while ((fp = CPP_PREV_BUFFER (fp)) != NULL)
632 putc ('.', stderr);
633 fprintf (stderr, " %s\n", ihash->name);
636 /* Actually process the file. */
637 if (no_reinclude)
638 ihash->cmacro = NEVER_REINCLUDE;
640 if (read_include_file (pfile, fd, ihash))
642 if (angle_brackets)
643 pfile->system_include_depth++;
648 /* Push an input buffer and load it up with the contents of FNAME.
649 If FNAME is "" or NULL, read standard input. */
651 cpp_read_file (pfile, fname)
652 cpp_reader *pfile;
653 const char *fname;
655 IHASH *ih, **slot;
656 IHASH dummy;
657 int f;
659 if (fname == NULL)
660 fname = "";
662 dummy.nshort = fname;
663 /* _cpp_calc_hash doesn't like zero-length strings. */
664 if (*fname == 0)
665 dummy.hash = 0;
666 else
667 dummy.hash = _cpp_calc_hash ((const U_CHAR *)fname, strlen (fname));
668 slot = (IHASH **) htab_find_slot_with_hash (pfile->all_include_files,
669 (const void *) &dummy,
670 dummy.hash, INSERT);
671 if (*slot && (ih = redundant_include_p (*slot, ABSOLUTE_PATH)))
673 if (ih == (IHASH *) -1)
674 return 1; /* Already included. */
676 else
677 ih = make_IHASH (fname, 0, ABSOLUTE_PATH, dummy.hash, slot);
679 if (*fname == '\0')
680 f = 0;
681 else
682 f = open_include_file (pfile, fname);
684 return read_include_file (pfile, f, ih);
687 /* Read the contents of FD into the buffer on the top of PFILE's stack.
688 IHASH points to the include hash entry for the file associated with
691 The caller is responsible for the cpp_push_buffer. */
693 static int
694 read_include_file (pfile, fd, ihash)
695 cpp_reader *pfile;
696 int fd;
697 IHASH *ihash;
699 struct stat st;
700 ssize_t length;
701 cpp_buffer *fp;
703 fp = cpp_push_buffer (pfile, NULL, 0);
705 if (fp == 0)
706 goto push_fail;
708 if (fstat (fd, &st) < 0)
709 goto perror_fail;
711 /* If fd points to a plain file, we might be able to mmap it; we can
712 definitely allocate the buffer all at once. If fd is a pipe or
713 terminal, we can't do either. If fd is something weird, like a
714 block device or a directory, we don't want to read it at all.
716 Unfortunately, different systems use different st.st_mode values
717 for pipes: some have S_ISFIFO, some S_ISSOCK, some are buggy and
718 zero the entire struct stat except a couple fields. Hence we don't
719 even try to figure out what something is, except for plain files,
720 directories, and block devices. */
722 if (S_ISREG (st.st_mode))
724 ssize_t st_size;
726 /* off_t might have a wider range than ssize_t - in other words,
727 the max size of a file might be bigger than the address
728 space. We can't handle a file that large. (Anyone with
729 a single source file bigger than 2GB needs to rethink
730 their coding style.) */
731 if (st.st_size > SSIZE_MAX)
733 cpp_error (pfile, "%s is too large", ihash->name);
734 goto fail;
736 st_size = st.st_size;
737 length = read_file (fp, fd, st_size);
738 if (length == -1)
739 goto perror_fail;
740 if (length < st_size)
741 cpp_warning (pfile, "%s is shorter than expected\n", ihash->name);
743 else if (S_ISBLK (st.st_mode))
745 cpp_error (pfile, "%s is a block device", ihash->name);
746 goto fail;
748 else if (S_ISDIR (st.st_mode))
750 cpp_error (pfile, "%s is a directory", ihash->name);
751 goto fail;
753 else
755 /* 8 kilobytes is a sensible starting size. It ought to be
756 bigger than the kernel pipe buffer, and it's definitely
757 bigger than the majority of C source files. */
758 length = read_with_read (fp, fd, 8 * 1024);
759 if (length == -1)
760 goto perror_fail;
763 /* These must be set before prescan. */
764 fp->ihash = ihash;
765 fp->nominal_fname = ihash->name;
767 if (length == 0)
768 ihash->cmacro = NEVER_REINCLUDE;
769 else
770 /* Temporary - I hope. */
771 length = _cpp_prescan (pfile, fp, length);
773 fp->rlimit = fp->buf + length;
774 fp->cur = fp->buf;
775 if (ihash->foundhere != ABSOLUTE_PATH)
776 fp->system_header_p = ihash->foundhere->sysp;
777 fp->lineno = 1;
778 fp->line_base = fp->buf;
780 /* The ->actual_dir field is only used when ignore_srcdir is not in effect;
781 see do_include */
782 if (!CPP_OPTION (pfile, ignore_srcdir))
783 fp->actual_dir = actual_directory (pfile, ihash->name);
785 pfile->input_stack_listing_current = 0;
786 pfile->only_seen_white = 2;
787 close (fd);
788 return 1;
790 perror_fail:
791 cpp_error_from_errno (pfile, ihash->name);
792 fail:
793 cpp_pop_buffer (pfile);
794 push_fail:
795 close (fd);
796 return 0;
799 static ssize_t
800 read_file (fp, fd, size)
801 cpp_buffer *fp;
802 int fd;
803 ssize_t size;
805 static int pagesize = -1;
807 if (size == 0)
808 return 0;
810 if (pagesize == -1)
811 pagesize = getpagesize ();
813 #if MMAP_THRESHOLD
814 if (size / pagesize >= MMAP_THRESHOLD)
816 const U_CHAR *result
817 = (const U_CHAR *) mmap (0, size, PROT_READ, MAP_PRIVATE, fd, 0);
818 if (result != (const U_CHAR *)-1)
820 fp->buf = result;
821 fp->mapped = 1;
822 return size;
825 /* If mmap fails, try read. If there's really a problem, read will
826 fail too. */
827 #endif
829 return read_with_read (fp, fd, size);
832 static ssize_t
833 read_with_read (fp, fd, size)
834 cpp_buffer *fp;
835 int fd;
836 ssize_t size;
838 ssize_t offset, count;
839 U_CHAR *buf;
841 buf = (U_CHAR *) xmalloc (size);
842 offset = 0;
843 while ((count = read (fd, buf + offset, size - offset)) > 0)
845 offset += count;
846 if (offset == size)
847 buf = xrealloc (buf, (size *= 2));
849 if (count < 0)
851 free (buf);
852 return -1;
854 if (offset == 0)
856 free (buf);
857 return 0;
860 if (offset < size)
861 buf = xrealloc (buf, offset);
862 fp->buf = buf;
863 fp->mapped = 0;
864 return offset;
867 /* Given a path FNAME, extract the directory component and place it
868 onto the actual_dirs list. Return a pointer to the allocated
869 file_name_list structure. These structures are used to implement
870 current-directory "" include searching. */
872 static struct file_name_list *
873 actual_directory (pfile, fname)
874 cpp_reader *pfile;
875 const char *fname;
877 char *last_slash, *dir;
878 size_t dlen;
879 struct file_name_list *x;
881 dir = xstrdup (fname);
882 last_slash = strrchr (dir, '/');
883 if (last_slash)
885 if (last_slash == dir)
887 dlen = 1;
888 last_slash[1] = '\0';
890 else
892 dlen = last_slash - dir;
893 *last_slash = '\0';
896 else
898 dir[0] = '.';
899 dir[1] = '\0';
900 dlen = 1;
903 if (dlen > pfile->max_include_len)
904 pfile->max_include_len = dlen;
906 for (x = pfile->actual_dirs; x; x = x->alloc)
907 if (!strcmp (x->name, dir))
909 free (dir);
910 return x;
913 /* Not found, make a new one. */
914 x = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
915 x->name = dir;
916 x->nlen = dlen;
917 x->next = CPP_OPTION (pfile, quote_include);
918 x->alloc = pfile->actual_dirs;
919 x->sysp = CPP_BUFFER (pfile)->system_header_p;
920 x->name_map = NULL;
922 pfile->actual_dirs = x;
923 return x;
926 /* Simplify a path name in place, deleting redundant components. This
927 reduces OS overhead and guarantees that equivalent paths compare
928 the same (modulo symlinks).
930 Transforms made:
931 foo/bar/../quux foo/quux
932 foo/./bar foo/bar
933 foo//bar foo/bar
934 /../quux /quux
935 //quux //quux (POSIX allows leading // as a namespace escape)
937 Guarantees no trailing slashes. All transforms reduce the length
938 of the string.
940 void
941 _cpp_simplify_pathname (path)
942 char *path;
944 char *from, *to;
945 char *base;
946 int absolute = 0;
948 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
949 /* Convert all backslashes to slashes. */
950 for (from = path; *from; from++)
951 if (*from == '\\') *from = '/';
953 /* Skip over leading drive letter if present. */
954 if (ISALPHA (path[0]) && path[1] == ':')
955 from = to = &path[2];
956 else
957 from = to = path;
958 #else
959 from = to = path;
960 #endif
962 /* Remove redundant initial /s. */
963 if (*from == '/')
965 absolute = 1;
966 to++;
967 from++;
968 if (*from == '/')
970 if (*++from == '/')
971 /* 3 or more initial /s are equivalent to 1 /. */
972 while (*++from == '/');
973 else
974 /* On some hosts // differs from /; Posix allows this. */
975 to++;
978 base = to;
980 for (;;)
982 while (*from == '/')
983 from++;
985 if (from[0] == '.' && from[1] == '/')
986 from += 2;
987 else if (from[0] == '.' && from[1] == '\0')
988 goto done;
989 else if (from[0] == '.' && from[1] == '.' && from[2] == '/')
991 if (base == to)
993 if (absolute)
994 from += 3;
995 else
997 *to++ = *from++;
998 *to++ = *from++;
999 *to++ = *from++;
1000 base = to;
1003 else
1005 to -= 2;
1006 while (to > base && *to != '/') to--;
1007 if (*to == '/')
1008 to++;
1009 from += 3;
1012 else if (from[0] == '.' && from[1] == '.' && from[2] == '\0')
1014 if (base == to)
1016 if (!absolute)
1018 *to++ = *from++;
1019 *to++ = *from++;
1022 else
1024 to -= 2;
1025 while (to > base && *to != '/') to--;
1026 if (*to == '/')
1027 to++;
1029 goto done;
1031 else
1032 /* Copy this component and trailing /, if any. */
1033 while ((*to++ = *from++) != '/')
1035 if (!to[-1])
1037 to--;
1038 goto done;
1044 done:
1045 /* Trim trailing slash */
1046 if (to[0] == '/' && (!absolute || to > path+1))
1047 to--;
1049 /* Change the empty string to "." so that stat() on the result
1050 will always work. */
1051 if (to == path)
1052 *to++ = '.';
1054 *to = '\0';
1056 return;
1059 /* It is not clear when this should be used if at all, so I've
1060 disabled it until someone who understands VMS can look at it. */
1061 #if 0
1063 /* Under VMS we need to fix up the "include" specification filename.
1065 Rules for possible conversions
1067 fullname tried paths
1069 name name
1070 ./dir/name [.dir]name
1071 /dir/name dir:name
1072 /name [000000]name, name
1073 dir/name dir:[000000]name, dir:name, dir/name
1074 dir1/dir2/name dir1:[dir2]name, dir1:[000000.dir2]name
1075 path:/name path:[000000]name, path:name
1076 path:/dir/name path:[000000.dir]name, path:[dir]name
1077 path:dir/name path:[dir]name
1078 [path]:[dir]name [path.dir]name
1079 path/[dir]name [path.dir]name
1081 The path:/name input is constructed when expanding <> includes. */
1084 static void
1085 hack_vms_include_specification (fullname)
1086 char *fullname;
1088 register char *basename, *unixname, *local_ptr, *first_slash;
1089 int f, check_filename_before_returning, must_revert;
1090 char Local[512];
1092 check_filename_before_returning = 0;
1093 must_revert = 0;
1094 /* See if we can find a 1st slash. If not, there's no path information. */
1095 first_slash = strchr (fullname, '/');
1096 if (first_slash == 0)
1097 return 0; /* Nothing to do!!! */
1099 /* construct device spec if none given. */
1101 if (strchr (fullname, ':') == 0)
1104 /* If fullname has a slash, take it as device spec. */
1106 if (first_slash == fullname)
1108 first_slash = strchr (fullname + 1, '/'); /* 2nd slash ? */
1109 if (first_slash)
1110 *first_slash = ':'; /* make device spec */
1111 for (basename = fullname; *basename != 0; basename++)
1112 *basename = *(basename+1); /* remove leading slash */
1114 else if ((first_slash[-1] != '.') /* keep ':/', './' */
1115 && (first_slash[-1] != ':')
1116 && (first_slash[-1] != ']')) /* or a vms path */
1118 *first_slash = ':';
1120 else if ((first_slash[1] == '[') /* skip './' in './[dir' */
1121 && (first_slash[-1] == '.'))
1122 fullname += 2;
1125 /* Get part after first ':' (basename[-1] == ':')
1126 or last '/' (basename[-1] == '/'). */
1128 basename = base_name (fullname);
1130 local_ptr = Local; /* initialize */
1132 /* We are trying to do a number of things here. First of all, we are
1133 trying to hammer the filenames into a standard format, such that later
1134 processing can handle them.
1136 If the file name contains something like [dir.], then it recognizes this
1137 as a root, and strips the ".]". Later processing will add whatever is
1138 needed to get things working properly.
1140 If no device is specified, then the first directory name is taken to be
1141 a device name (or a rooted logical). */
1143 /* Point to the UNIX filename part (which needs to be fixed!)
1144 but skip vms path information.
1145 [basename != fullname since first_slash != 0]. */
1147 if ((basename[-1] == ':') /* vms path spec. */
1148 || (basename[-1] == ']')
1149 || (basename[-1] == '>'))
1150 unixname = basename;
1151 else
1152 unixname = fullname;
1154 if (*unixname == '/')
1155 unixname++;
1157 /* If the directory spec is not rooted, we can just copy
1158 the UNIX filename part and we are done. */
1160 if (((basename - fullname) > 1)
1161 && ( (basename[-1] == ']')
1162 || (basename[-1] == '>')))
1164 if (basename[-2] != '.')
1167 /* The VMS part ends in a `]', and the preceding character is not a `.'.
1168 -> PATH]:/name (basename = '/name', unixname = 'name')
1169 We strip the `]', and then splice the two parts of the name in the
1170 usual way. Given the default locations for include files,
1171 we will only use this code if the user specifies alternate locations
1172 with the /include (-I) switch on the command line. */
1174 basename -= 1; /* Strip "]" */
1175 unixname--; /* backspace */
1177 else
1180 /* The VMS part has a ".]" at the end, and this will not do. Later
1181 processing will add a second directory spec, and this would be a syntax
1182 error. Thus we strip the ".]", and thus merge the directory specs.
1183 We also backspace unixname, so that it points to a '/'. This inhibits the
1184 generation of the 000000 root directory spec (which does not belong here
1185 in this case). */
1187 basename -= 2; /* Strip ".]" */
1188 unixname--; /* backspace */
1192 else
1196 /* We drop in here if there is no VMS style directory specification yet.
1197 If there is no device specification either, we make the first dir a
1198 device and try that. If we do not do this, then we will be essentially
1199 searching the users default directory (as if they did a #include "asdf.h").
1201 Then all we need to do is to push a '[' into the output string. Later
1202 processing will fill this in, and close the bracket. */
1204 if ((unixname != fullname) /* vms path spec found. */
1205 && (basename[-1] != ':'))
1206 *local_ptr++ = ':'; /* dev not in spec. take first dir */
1208 *local_ptr++ = '['; /* Open the directory specification */
1211 if (unixname == fullname) /* no vms dir spec. */
1213 must_revert = 1;
1214 if ((first_slash != 0) /* unix dir spec. */
1215 && (*unixname != '/') /* not beginning with '/' */
1216 && (*unixname != '.')) /* or './' or '../' */
1217 *local_ptr++ = '.'; /* dir is local ! */
1220 /* at this point we assume that we have the device spec, and (at least
1221 the opening "[" for a directory specification. We may have directories
1222 specified already.
1224 If there are no other slashes then the filename will be
1225 in the "root" directory. Otherwise, we need to add
1226 directory specifications. */
1228 if (strchr (unixname, '/') == 0)
1230 /* if no directories specified yet and none are following. */
1231 if (local_ptr[-1] == '[')
1233 /* Just add "000000]" as the directory string */
1234 strcpy (local_ptr, "000000]");
1235 local_ptr += strlen (local_ptr);
1236 check_filename_before_returning = 1; /* we might need to fool with this later */
1239 else
1242 /* As long as there are still subdirectories to add, do them. */
1243 while (strchr (unixname, '/') != 0)
1245 /* If this token is "." we can ignore it
1246 if it's not at the beginning of a path. */
1247 if ((unixname[0] == '.') && (unixname[1] == '/'))
1249 /* remove it at beginning of path. */
1250 if ( ((unixname == fullname) /* no device spec */
1251 && (fullname+2 != basename)) /* starts with ./ */
1252 /* or */
1253 || ((basename[-1] == ':') /* device spec */
1254 && (unixname-1 == basename))) /* and ./ afterwards */
1255 *local_ptr++ = '.'; /* make '[.' start of path. */
1256 unixname += 2;
1257 continue;
1260 /* Add a subdirectory spec. Do not duplicate "." */
1261 if ( local_ptr[-1] != '.'
1262 && local_ptr[-1] != '['
1263 && local_ptr[-1] != '<')
1264 *local_ptr++ = '.';
1266 /* If this is ".." then the spec becomes "-" */
1267 if ( (unixname[0] == '.')
1268 && (unixname[1] == '.')
1269 && (unixname[2] == '/'))
1271 /* Add "-" and skip the ".." */
1272 if ((local_ptr[-1] == '.')
1273 && (local_ptr[-2] == '['))
1274 local_ptr--; /* prevent [.- */
1275 *local_ptr++ = '-';
1276 unixname += 3;
1277 continue;
1280 /* Copy the subdirectory */
1281 while (*unixname != '/')
1282 *local_ptr++= *unixname++;
1284 unixname++; /* Skip the "/" */
1287 /* Close the directory specification */
1288 if (local_ptr[-1] == '.') /* no trailing periods */
1289 local_ptr--;
1291 if (local_ptr[-1] == '[') /* no dir needed */
1292 local_ptr--;
1293 else
1294 *local_ptr++ = ']';
1297 /* Now add the filename. */
1299 while (*unixname)
1300 *local_ptr++ = *unixname++;
1301 *local_ptr = 0;
1303 /* Now append it to the original VMS spec. */
1305 strcpy ((must_revert==1)?fullname:basename, Local);
1307 /* If we put a [000000] in the filename, try to open it first. If this fails,
1308 remove the [000000], and return that name. This provides flexibility
1309 to the user in that they can use both rooted and non-rooted logical names
1310 to point to the location of the file. */
1312 if (check_filename_before_returning)
1314 f = open (fullname, O_RDONLY|O_NONBLOCK);
1315 if (f >= 0)
1317 /* The file name is OK as it is, so return it as is. */
1318 close (f);
1319 return 1;
1322 /* The filename did not work. Try to remove the [000000] from the name,
1323 and return it. */
1325 basename = strchr (fullname, '[');
1326 local_ptr = strchr (fullname, ']') + 1;
1327 strcpy (basename, local_ptr); /* this gets rid of it */
1331 return 1;
1333 #endif /* VMS */