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