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