OSDN Git Service

* cppfiles.c: Move all default-#defines to top of file.
[pf3gnuchains/gcc-fork.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 #if MMAP_THRESHOLD
276       if (pagesize == -1)
277         pagesize = getpagesize ();
278
279       if (size / pagesize >= MMAP_THRESHOLD)
280         {
281           buf = (U_CHAR *) mmap (0, size, PROT_READ, MAP_PRIVATE, inc->fd, 0);
282           if (buf == (U_CHAR *)-1)
283             goto perror_fail;
284           inc->mapped = 1;
285         }
286       else
287 #endif
288         {
289           buf = (U_CHAR *) xmalloc (size);
290           offset = 0;
291           while (offset < size)
292             {
293               count = read (inc->fd, buf + offset, size - offset);
294               if (count < 0)
295                 goto perror_fail;
296               if (count == 0)
297                 {
298                   cpp_warning (pfile, "%s is shorter than expected", inc->name);
299                   break;
300                 }
301               offset += count;
302             }
303           inc->mapped = 0;
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 (inc->mapped)
367         munmap ((caddr_t) inc->buffer, inc->st.st_size);
368       else
369         free ((PTR) inc->buffer);
370       inc->buffer = NULL;
371     }
372 }
373
374 /* Return 1 if the file named by FNAME has been included before in
375    any context, 0 otherwise.  */
376 int
377 cpp_included (pfile, fname)
378      cpp_reader *pfile;
379      const char *fname;
380 {
381   struct file_name_list *path;
382   char *name;
383   splay_tree_node nd;
384
385   if (fname[0] == '/')
386     {
387       /* Just look it up.  */
388       nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) fname);
389       return (nd && nd->value);
390     }
391       
392   /* Search directory path for the file.  */
393   name = (char *) alloca (strlen (fname) + pfile->max_include_len
394                           + 2 + INCLUDE_LEN_FUDGE);
395   for (path = CPP_OPTION (pfile, quote_include); path; path = path->next)
396     {
397       memcpy (name, path->name, path->nlen);
398       name[path->nlen] = '/';
399       strcpy (&name[path->nlen+1], fname);
400       _cpp_simplify_pathname (name);
401       if (CPP_OPTION (pfile, remap))
402         name = remap_filename (pfile, name, path);
403
404       nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) name);
405       if (nd && nd->value)
406         return 1;
407     }
408   return 0;
409 }
410
411 /* Search for include file FNAME in the include chain starting at
412    SEARCH_START.  Return 0 if there is no such file (or it's un-openable),
413    otherwise an include_file structure.  */
414
415 static struct include_file *
416 find_include_file (pfile, fname, search_start)
417      cpp_reader *pfile;
418      const char *fname;
419      struct file_name_list *search_start;
420 {
421   struct file_name_list *path;
422   char *name;
423   struct include_file *file;
424
425   if (fname[0] == '/')
426     return lookup_include_file (pfile, fname);
427       
428   /* Search directory path for the file.  */
429   name = (char *) alloca (strlen (fname) + pfile->max_include_len
430                           + 2 + INCLUDE_LEN_FUDGE);
431   for (path = search_start; path; path = path->next)
432     {
433       memcpy (name, path->name, path->nlen);
434       name[path->nlen] = '/';
435       strcpy (&name[path->nlen+1], fname);
436       _cpp_simplify_pathname (name);
437       if (CPP_OPTION (pfile, remap))
438         name = remap_filename (pfile, name, path);
439
440       file = lookup_include_file (pfile, name);
441       if (file)
442         {
443           file->sysp = path->sysp;
444           file->foundhere = path;
445           return file;
446         }
447     }
448   return 0;
449 }
450
451 /* #line uses this to save artificial file names.  We have to stat the
452    file because an all_include_files entry is always either + or -,
453    there's no 'I don't know' value.  */
454 const char *
455 _cpp_fake_include (pfile, fname)
456      cpp_reader *pfile;
457      const char *fname;
458 {
459   splay_tree_node nd;
460   struct include_file *file;
461   char *name;
462
463   file = find_include_file (pfile, fname, CPP_OPTION (pfile, quote_include));
464   if (file)
465     {
466       if (file->fd > 0)
467         {
468           close (file->fd);
469           file->fd = -1;
470         }
471       return file->name;
472     }
473
474   name = xstrdup (fname);
475   _cpp_simplify_pathname (name);
476
477   /* We cannot just blindly insert a node, because there's still the
478      chance that the node already exists but isn't on the search path.  */
479   nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) name);
480   if (nd)
481     {
482       free (name);
483       return (const char *) nd->key;
484     }
485
486   splay_tree_insert (pfile->all_include_files, (splay_tree_key) name, 0);
487   return (const char *)name;
488 }
489
490 /* Not everyone who wants to set system-header-ness on a buffer can
491    see the details of struct include_file.  This is an exported interface
492    because fix-header needs it.  */
493 void
494 cpp_make_system_header (pfile, pbuf, flag)
495      cpp_reader *pfile;
496      cpp_buffer *pbuf;
497      int flag;
498 {
499   if (flag < 0 || flag > 2)
500     cpp_ice (pfile, "cpp_make_system_header: bad flag %d\n", flag);
501   else if (!pbuf->inc)
502     cpp_ice (pfile, "cpp_make_system_header called on non-file buffer");
503   else
504     pbuf->inc->sysp = flag;
505 }
506
507 const char *
508 cpp_syshdr_flags (pfile, pbuf)
509      cpp_reader *pfile ATTRIBUTE_UNUSED;
510      cpp_buffer *pbuf;
511 {
512 #ifndef NO_IMPLICIT_EXTERN_C
513   if (CPP_OPTION (pfile, cplusplus) && pbuf->inc->sysp == 2)
514     return " 3 4";
515 #endif
516   if (pbuf->inc->sysp)
517     return " 3";
518   return "";
519 }
520
521 /* Report on all files that might benefit from a multiple include guard.
522    Triggered by -H.  */
523 void
524 _cpp_report_missing_guards (pfile)
525      cpp_reader *pfile;
526 {
527   int banner = 0;
528   splay_tree_foreach (pfile->all_include_files, report_missing_guard,
529                       (PTR) &banner);
530 }
531
532 static int
533 report_missing_guard (n, b)
534      splay_tree_node n;
535      void *b;
536 {
537   struct include_file *f = (struct include_file *) n->value;
538   int *bannerp = (int *)b;
539
540   if (f && f->cmacro == 0 && f->include_count == 1)
541     {
542       if (*bannerp == 0)
543         {
544           fputs (_("Multiple include guards may be useful for:\n"), stderr);
545           *bannerp = 1;
546         }
547       fputs (f->name, stderr);
548       putc ('\n', stderr);
549     }
550   return 0;
551 }
552
553 #define PRINT_THIS_DEP(p, b) (CPP_PRINT_DEPS(p) > (b||p->system_include_depth))
554 void
555 _cpp_execute_include (pfile, f, len, no_reinclude, search_start, angle_brackets)
556      cpp_reader *pfile;
557      const U_CHAR *f;
558      unsigned int len;
559      int no_reinclude;
560      struct file_name_list *search_start;
561      int angle_brackets;
562 {
563   struct include_file *inc;
564   char *fname;
565
566   if (!search_start)
567     {
568       if (angle_brackets)
569         search_start = CPP_OPTION (pfile, bracket_include);
570       else if (CPP_OPTION (pfile, ignore_srcdir))
571         search_start = CPP_OPTION (pfile, quote_include);
572       else
573         search_start = CPP_BUFFER (pfile)->actual_dir;
574     }
575
576   if (!search_start)
577     {
578       cpp_error (pfile, "No include path in which to find %s", f);
579       return;
580     }
581
582   fname = alloca (len + 1);
583   memcpy (fname, f, len);
584   fname[len] = '\0';
585
586   inc = find_include_file (pfile, fname, search_start);
587
588   if (inc)
589     {
590       /* For -M, add the file to the dependencies on its first inclusion. */
591       if (!inc->include_count && PRINT_THIS_DEP (pfile, angle_brackets))
592         deps_add_dep (pfile->deps, inc->name);
593       inc->include_count++;
594
595       /* Actually process the file.  */
596       if (stack_include_file (pfile, inc))
597         {
598           if (angle_brackets)
599             pfile->system_include_depth++;
600
601           if (no_reinclude)
602             inc->cmacro = NEVER_REREAD;
603
604           /* Handle -H option.  */
605           if (CPP_OPTION (pfile, print_include_names))
606             {
607               cpp_buffer *fp = CPP_BUFFER (pfile);
608               while ((fp = CPP_PREV_BUFFER (fp)) != NULL)
609                 putc ('.', stderr);
610               fprintf (stderr, " %s\n", inc->name);
611             }
612         }
613       return;
614     }
615       
616   if (CPP_OPTION (pfile, print_deps_missing_files)
617       && PRINT_THIS_DEP (pfile, angle_brackets))
618     {
619       if (!angle_brackets)
620         deps_add_dep (pfile->deps, fname);
621       else
622         {
623           char *p;
624           struct file_name_list *ptr;
625           /* If requested as a system header, assume it belongs in
626              the first system header directory. */
627           if (CPP_OPTION (pfile, bracket_include))
628             ptr = CPP_OPTION (pfile, bracket_include);
629           else
630             ptr = CPP_OPTION (pfile, quote_include);
631
632           p = (char *) alloca (strlen (ptr->name)
633                                + strlen (fname) + 2);
634           if (*ptr->name != '\0')
635             {
636               strcpy (p, ptr->name);
637               strcat (p, "/");
638             }
639           strcat (p, fname);
640           _cpp_simplify_pathname (p);
641           deps_add_dep (pfile->deps, p);
642         }
643     }
644   /* If -M was specified, and this header file won't be added to
645      the dependency list, then don't count this as an error,
646      because we can still produce correct output.  Otherwise, we
647      can't produce correct output, because there may be
648      dependencies we need inside the missing file, and we don't
649      know what directory this missing file exists in. */
650   else if (CPP_PRINT_DEPS (pfile)
651            && ! PRINT_THIS_DEP (pfile, angle_brackets))
652     cpp_warning (pfile, "No include path in which to find %s", fname);
653   else
654     cpp_error_from_errno (pfile, fname);
655 }
656
657 /* Locate file F, and determine whether it is newer than PFILE. Return -1,
658    if F cannot be located or dated, 1, if it is newer and 0 if older.  */
659
660 int
661 _cpp_compare_file_date (pfile, f, len, angle_brackets)
662      cpp_reader *pfile;
663      const U_CHAR *f;
664      unsigned int len;
665      int angle_brackets;
666 {
667   char *fname;
668   struct file_name_list *search_start;
669   struct include_file *inc;
670   struct include_file *current_include = CPP_BUFFER (pfile)->inc;
671
672   if (angle_brackets)
673     search_start = CPP_OPTION (pfile, bracket_include);
674   else if (CPP_OPTION (pfile, ignore_srcdir))
675     search_start = CPP_OPTION (pfile, quote_include);
676   else
677     search_start = CPP_BUFFER (pfile)->actual_dir;
678
679   fname = alloca (len + 1);
680   memcpy (fname, f, len);
681   fname[len] = '\0';
682   inc = find_include_file (pfile, fname, search_start);
683   
684   if (!inc)
685     return -1;
686   if (inc->fd > 0)
687     {
688       close (inc->fd);
689       inc->fd = -1;
690     }
691     
692   return inc->st.st_mtime > current_include->st.st_mtime;
693 }
694
695
696 /* Push an input buffer and load it up with the contents of FNAME.
697    If FNAME is "" or NULL, read standard input.  */
698 int
699 cpp_read_file (pfile, fname)
700      cpp_reader *pfile;
701      const char *fname;
702 {
703   struct include_file *f;
704
705   if (fname == NULL)
706     fname = "";
707
708   f = lookup_include_file (pfile, fname);
709
710   if (f == NULL)
711     {
712       cpp_error_from_errno (pfile, fname);
713       return 0;
714     }
715
716   return stack_include_file (pfile, f);
717 }
718
719 /* Do appropriate cleanup when a file buffer is popped off the input
720    stack.  */
721 void
722 _cpp_pop_file_buffer (pfile, buf)
723      cpp_reader *pfile;
724      cpp_buffer *buf;
725 {
726   struct include_file *inc = buf->inc;
727
728   if (pfile->system_include_depth)
729     pfile->system_include_depth--;
730   if (pfile->include_depth)
731     pfile->include_depth--;
732   if (pfile->potential_control_macro)
733     {
734       if (inc->cmacro != NEVER_REREAD)
735         inc->cmacro = pfile->potential_control_macro;
736       pfile->potential_control_macro = 0;
737     }
738   pfile->input_stack_listing_current = 0;
739
740   inc->refcnt--;
741   if (inc->refcnt == 0 && DO_NOT_REREAD (inc))
742     purge_cache (inc);
743 }
744
745 /* The file_name_map structure holds a mapping of file names for a
746    particular directory.  This mapping is read from the file named
747    FILE_NAME_MAP_FILE in that directory.  Such a file can be used to
748    map filenames on a file system with severe filename restrictions,
749    such as DOS.  The format of the file name map file is just a series
750    of lines with two tokens on each line.  The first token is the name
751    to map, and the second token is the actual name to use.  */
752
753 struct file_name_map
754 {
755   struct file_name_map *map_next;
756   char *map_from;
757   char *map_to;
758 };
759
760 #define FILE_NAME_MAP_FILE "header.gcc"
761
762 /* Read a space delimited string of unlimited length from a stdio
763    file.  */
764
765 static char *
766 read_filename_string (ch, f)
767      int ch;
768      FILE *f;
769 {
770   char *alloc, *set;
771   int len;
772
773   len = 20;
774   set = alloc = xmalloc (len + 1);
775   if (! is_space(ch))
776     {
777       *set++ = ch;
778       while ((ch = getc (f)) != EOF && ! is_space(ch))
779         {
780           if (set - alloc == len)
781             {
782               len *= 2;
783               alloc = xrealloc (alloc, len + 1);
784               set = alloc + len / 2;
785             }
786           *set++ = ch;
787         }
788     }
789   *set = '\0';
790   ungetc (ch, f);
791   return alloc;
792 }
793
794 /* This structure holds a linked list of file name maps, one per directory.  */
795
796 struct file_name_map_list
797 {
798   struct file_name_map_list *map_list_next;
799   char *map_list_name;
800   struct file_name_map *map_list_map;
801 };
802
803 /* Read the file name map file for DIRNAME.  */
804
805 static struct file_name_map *
806 read_name_map (pfile, dirname)
807      cpp_reader *pfile;
808      const char *dirname;
809 {
810   register struct file_name_map_list *map_list_ptr;
811   char *name;
812   FILE *f;
813
814   for (map_list_ptr = CPP_OPTION (pfile, map_list); map_list_ptr;
815        map_list_ptr = map_list_ptr->map_list_next)
816     if (! strcmp (map_list_ptr->map_list_name, dirname))
817       return map_list_ptr->map_list_map;
818
819   map_list_ptr = ((struct file_name_map_list *)
820                   xmalloc (sizeof (struct file_name_map_list)));
821   map_list_ptr->map_list_name = xstrdup (dirname);
822   map_list_ptr->map_list_map = NULL;
823
824   name = (char *) alloca (strlen (dirname) + strlen (FILE_NAME_MAP_FILE) + 2);
825   strcpy (name, dirname);
826   if (*dirname)
827     strcat (name, "/");
828   strcat (name, FILE_NAME_MAP_FILE);
829   f = fopen (name, "r");
830   if (!f)
831     map_list_ptr->map_list_map = (struct file_name_map *)-1;
832   else
833     {
834       int ch;
835       int dirlen = strlen (dirname);
836
837       while ((ch = getc (f)) != EOF)
838         {
839           char *from, *to;
840           struct file_name_map *ptr;
841
842           if (is_space(ch))
843             continue;
844           from = read_filename_string (ch, f);
845           while ((ch = getc (f)) != EOF && is_hspace(ch))
846             ;
847           to = read_filename_string (ch, f);
848
849           ptr = ((struct file_name_map *)
850                  xmalloc (sizeof (struct file_name_map)));
851           ptr->map_from = from;
852
853           /* Make the real filename absolute.  */
854           if (*to == '/')
855             ptr->map_to = to;
856           else
857             {
858               ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
859               strcpy (ptr->map_to, dirname);
860               ptr->map_to[dirlen] = '/';
861               strcpy (ptr->map_to + dirlen + 1, to);
862               free (to);
863             }         
864
865           ptr->map_next = map_list_ptr->map_list_map;
866           map_list_ptr->map_list_map = ptr;
867
868           while ((ch = getc (f)) != '\n')
869             if (ch == EOF)
870               break;
871         }
872       fclose (f);
873     }
874   
875   map_list_ptr->map_list_next = CPP_OPTION (pfile, map_list);
876   CPP_OPTION (pfile, map_list) = map_list_ptr;
877
878   return map_list_ptr->map_list_map;
879 }  
880
881 /* Remap NAME based on the file_name_map (if any) for LOC. */
882
883 static char *
884 remap_filename (pfile, name, loc)
885      cpp_reader *pfile;
886      char *name;
887      struct file_name_list *loc;
888 {
889   struct file_name_map *map;
890   const char *from, *p, *dir;
891
892   if (! loc->name_map)
893     loc->name_map = read_name_map (pfile,
894                                    loc->name
895                                    ? loc->name : ".");
896
897   if (loc->name_map == (struct file_name_map *)-1)
898     return name;
899   
900   from = name + strlen (loc->name) + 1;
901   
902   for (map = loc->name_map; map; map = map->map_next)
903     if (!strcmp (map->map_from, from))
904       return map->map_to;
905
906   /* Try to find a mapping file for the particular directory we are
907      looking in.  Thus #include <sys/types.h> will look up sys/types.h
908      in /usr/include/header.gcc and look up types.h in
909      /usr/include/sys/header.gcc.  */
910   p = strrchr (name, '/');
911   if (!p)
912     p = name;
913   if (loc && loc->name
914       && strlen (loc->name) == (size_t) (p - name)
915       && !strncmp (loc->name, name, p - name))
916     /* FILENAME is in SEARCHPTR, which we've already checked.  */
917     return name;
918
919   if (p == name)
920     {
921       dir = ".";
922       from = name;
923     }
924   else
925     {
926       char * newdir = (char *) alloca (p - name + 1);
927       memcpy (newdir, name, p - name);
928       newdir[p - name] = '\0';
929       dir = newdir;
930       from = p + 1;
931     }
932   
933   for (map = read_name_map (pfile, dir); map; map = map->map_next)
934     if (! strcmp (map->map_from, name))
935       return map->map_to;
936
937   return name;
938 }
939
940 /* Given a path FNAME, extract the directory component and place it
941    onto the actual_dirs list.  Return a pointer to the allocated
942    file_name_list structure.  These structures are used to implement
943    current-directory "" include searching. */
944
945 static struct file_name_list *
946 actual_directory (pfile, fname)
947      cpp_reader *pfile;
948      const char *fname;
949 {
950   char *last_slash, *dir;
951   size_t dlen;
952   struct file_name_list *x;
953   
954   dir = xstrdup (fname);
955   last_slash = strrchr (dir, '/');
956   if (last_slash)
957     {
958       if (last_slash == dir)
959         {
960           dlen = 1;
961           last_slash[1] = '\0';
962         }
963       else
964         {
965           dlen = last_slash - dir;
966           *last_slash = '\0';
967         }
968     }
969   else
970     {
971       free (dir);
972       dir = xstrdup (".");
973       dlen = 1;
974     }
975
976   if (dlen > pfile->max_include_len)
977     pfile->max_include_len = dlen;
978
979   for (x = pfile->actual_dirs; x; x = x->alloc)
980     if (!strcmp (x->name, dir))
981       {
982         free (dir);
983         return x;
984       }
985
986   /* Not found, make a new one. */
987   x = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
988   x->name = dir;
989   x->nlen = dlen;
990   x->next = CPP_OPTION (pfile, quote_include);
991   x->alloc = pfile->actual_dirs;
992   x->sysp = CPP_BUFFER (pfile)->inc->sysp;
993   x->name_map = NULL;
994
995   pfile->actual_dirs = x;
996   return x;
997 }
998
999 /* Simplify a path name in place, deleting redundant components.  This
1000    reduces OS overhead and guarantees that equivalent paths compare
1001    the same (modulo symlinks).
1002
1003    Transforms made:
1004    foo/bar/../quux      foo/quux
1005    foo/./bar            foo/bar
1006    foo//bar             foo/bar
1007    /../quux             /quux
1008    //quux               //quux  (POSIX allows leading // as a namespace escape)
1009
1010    Guarantees no trailing slashes. All transforms reduce the length
1011    of the string.
1012  */
1013 void
1014 _cpp_simplify_pathname (path)
1015     char *path;
1016 {
1017     char *from, *to;
1018     char *base;
1019     int absolute = 0;
1020
1021 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
1022     /* Convert all backslashes to slashes. */
1023     for (from = path; *from; from++)
1024         if (*from == '\\') *from = '/';
1025     
1026     /* Skip over leading drive letter if present. */
1027     if (ISALPHA (path[0]) && path[1] == ':')
1028         from = to = &path[2];
1029     else
1030         from = to = path;
1031 #else
1032     from = to = path;
1033 #endif
1034     
1035     /* Remove redundant initial /s.  */
1036     if (*from == '/')
1037     {
1038         absolute = 1;
1039         to++;
1040         from++;
1041         if (*from == '/')
1042         {
1043             if (*++from == '/')
1044                 /* 3 or more initial /s are equivalent to 1 /.  */
1045                 while (*++from == '/');
1046             else
1047                 /* On some hosts // differs from /; Posix allows this.  */
1048                 to++;
1049         }
1050     }
1051     base = to;
1052     
1053     for (;;)
1054     {
1055         while (*from == '/')
1056             from++;
1057
1058         if (from[0] == '.' && from[1] == '/')
1059             from += 2;
1060         else if (from[0] == '.' && from[1] == '\0')
1061             goto done;
1062         else if (from[0] == '.' && from[1] == '.' && from[2] == '/')
1063         {
1064             if (base == to)
1065             {
1066                 if (absolute)
1067                     from += 3;
1068                 else
1069                 {
1070                     *to++ = *from++;
1071                     *to++ = *from++;
1072                     *to++ = *from++;
1073                     base = to;
1074                 }
1075             }
1076             else
1077             {
1078                 to -= 2;
1079                 while (to > base && *to != '/') to--;
1080                 if (*to == '/')
1081                     to++;
1082                 from += 3;
1083             }
1084         }
1085         else if (from[0] == '.' && from[1] == '.' && from[2] == '\0')
1086         {
1087             if (base == to)
1088             {
1089                 if (!absolute)
1090                 {
1091                     *to++ = *from++;
1092                     *to++ = *from++;
1093                 }
1094             }
1095             else
1096             {
1097                 to -= 2;
1098                 while (to > base && *to != '/') to--;
1099                 if (*to == '/')
1100                     to++;
1101             }
1102             goto done;
1103         }
1104         else
1105             /* Copy this component and trailing /, if any.  */
1106             while ((*to++ = *from++) != '/')
1107             {
1108                 if (!to[-1])
1109                 {
1110                     to--;
1111                     goto done;
1112                 }
1113             }
1114         
1115     }
1116     
1117  done:
1118     /* Trim trailing slash */
1119     if (to[0] == '/' && (!absolute || to > path+1))
1120         to--;
1121
1122     /* Change the empty string to "." so that stat() on the result
1123        will always work. */
1124     if (to == path)
1125       *to++ = '.';
1126     
1127     *to = '\0';
1128
1129     return;
1130 }
1131
1132 /* It is not clear when this should be used if at all, so I've
1133    disabled it until someone who understands VMS can look at it. */
1134 #if 0
1135
1136 /* Under VMS we need to fix up the "include" specification filename.
1137
1138    Rules for possible conversions
1139
1140         fullname                tried paths
1141
1142         name                    name
1143         ./dir/name              [.dir]name
1144         /dir/name               dir:name
1145         /name                   [000000]name, name
1146         dir/name                dir:[000000]name, dir:name, dir/name
1147         dir1/dir2/name          dir1:[dir2]name, dir1:[000000.dir2]name
1148         path:/name              path:[000000]name, path:name
1149         path:/dir/name          path:[000000.dir]name, path:[dir]name
1150         path:dir/name           path:[dir]name
1151         [path]:[dir]name        [path.dir]name
1152         path/[dir]name          [path.dir]name
1153
1154    The path:/name input is constructed when expanding <> includes. */
1155
1156
1157 static void
1158 hack_vms_include_specification (fullname)
1159      char *fullname;
1160 {
1161   register char *basename, *unixname, *local_ptr, *first_slash;
1162   int f, check_filename_before_returning, must_revert;
1163   char Local[512];
1164
1165   check_filename_before_returning = 0;
1166   must_revert = 0;
1167   /* See if we can find a 1st slash. If not, there's no path information.  */
1168   first_slash = strchr (fullname, '/');
1169   if (first_slash == 0)
1170     return 0;                           /* Nothing to do!!! */
1171
1172   /* construct device spec if none given.  */
1173
1174   if (strchr (fullname, ':') == 0)
1175     {
1176
1177       /* If fullname has a slash, take it as device spec.  */
1178
1179       if (first_slash == fullname)
1180         {
1181           first_slash = strchr (fullname + 1, '/');     /* 2nd slash ? */
1182           if (first_slash)
1183             *first_slash = ':';                         /* make device spec  */
1184           for (basename = fullname; *basename != 0; basename++)
1185             *basename = *(basename+1);                  /* remove leading slash  */
1186         }
1187       else if ((first_slash[-1] != '.')         /* keep ':/', './' */
1188             && (first_slash[-1] != ':')
1189             && (first_slash[-1] != ']'))        /* or a vms path  */
1190         {
1191           *first_slash = ':';
1192         }
1193       else if ((first_slash[1] == '[')          /* skip './' in './[dir'  */
1194             && (first_slash[-1] == '.'))
1195         fullname += 2;
1196     }
1197
1198   /* Get part after first ':' (basename[-1] == ':')
1199      or last '/' (basename[-1] == '/').  */
1200
1201   basename = base_name (fullname);
1202
1203   local_ptr = Local;                    /* initialize */
1204
1205   /* We are trying to do a number of things here.  First of all, we are
1206      trying to hammer the filenames into a standard format, such that later
1207      processing can handle them.
1208      
1209      If the file name contains something like [dir.], then it recognizes this
1210      as a root, and strips the ".]".  Later processing will add whatever is
1211      needed to get things working properly.
1212      
1213      If no device is specified, then the first directory name is taken to be
1214      a device name (or a rooted logical).  */
1215
1216   /* Point to the UNIX filename part (which needs to be fixed!)
1217      but skip vms path information.
1218      [basename != fullname since first_slash != 0].  */
1219
1220   if ((basename[-1] == ':')             /* vms path spec.  */
1221       || (basename[-1] == ']')
1222       || (basename[-1] == '>'))
1223     unixname = basename;
1224   else
1225     unixname = fullname;
1226
1227   if (*unixname == '/')
1228     unixname++;
1229
1230   /* If the directory spec is not rooted, we can just copy
1231      the UNIX filename part and we are done.  */
1232
1233   if (((basename - fullname) > 1)
1234      && (  (basename[-1] == ']')
1235         || (basename[-1] == '>')))
1236     {
1237       if (basename[-2] != '.')
1238         {
1239
1240         /* The VMS part ends in a `]', and the preceding character is not a `.'.
1241            -> PATH]:/name (basename = '/name', unixname = 'name')
1242            We strip the `]', and then splice the two parts of the name in the
1243            usual way.  Given the default locations for include files,
1244            we will only use this code if the user specifies alternate locations
1245            with the /include (-I) switch on the command line.  */
1246
1247           basename -= 1;        /* Strip "]" */
1248           unixname--;           /* backspace */
1249         }
1250       else
1251         {
1252
1253         /* The VMS part has a ".]" at the end, and this will not do.  Later
1254            processing will add a second directory spec, and this would be a syntax
1255            error.  Thus we strip the ".]", and thus merge the directory specs.
1256            We also backspace unixname, so that it points to a '/'.  This inhibits the
1257            generation of the 000000 root directory spec (which does not belong here
1258            in this case).  */
1259
1260           basename -= 2;        /* Strip ".]" */
1261           unixname--;           /* backspace */
1262         }
1263     }
1264
1265   else
1266
1267     {
1268
1269       /* We drop in here if there is no VMS style directory specification yet.
1270          If there is no device specification either, we make the first dir a
1271          device and try that.  If we do not do this, then we will be essentially
1272          searching the users default directory (as if they did a #include "asdf.h").
1273         
1274          Then all we need to do is to push a '[' into the output string. Later
1275          processing will fill this in, and close the bracket.  */
1276
1277       if ((unixname != fullname)        /* vms path spec found.  */
1278          && (basename[-1] != ':'))
1279         *local_ptr++ = ':';             /* dev not in spec.  take first dir */
1280
1281       *local_ptr++ = '[';               /* Open the directory specification */
1282     }
1283
1284     if (unixname == fullname)           /* no vms dir spec.  */
1285       {
1286         must_revert = 1;
1287         if ((first_slash != 0)          /* unix dir spec.  */
1288             && (*unixname != '/')       /* not beginning with '/'  */
1289             && (*unixname != '.'))      /* or './' or '../'  */
1290           *local_ptr++ = '.';           /* dir is local !  */
1291       }
1292
1293   /* at this point we assume that we have the device spec, and (at least
1294      the opening "[" for a directory specification.  We may have directories
1295      specified already.
1296
1297      If there are no other slashes then the filename will be
1298      in the "root" directory.  Otherwise, we need to add
1299      directory specifications.  */
1300
1301   if (strchr (unixname, '/') == 0)
1302     {
1303       /* if no directories specified yet and none are following.  */
1304       if (local_ptr[-1] == '[')
1305         {
1306           /* Just add "000000]" as the directory string */
1307           strcpy (local_ptr, "000000]");
1308           local_ptr += strlen (local_ptr);
1309           check_filename_before_returning = 1; /* we might need to fool with this later */
1310         }
1311     }
1312   else
1313     {
1314
1315       /* As long as there are still subdirectories to add, do them.  */
1316       while (strchr (unixname, '/') != 0)
1317         {
1318           /* If this token is "." we can ignore it
1319                if it's not at the beginning of a path.  */
1320           if ((unixname[0] == '.') && (unixname[1] == '/'))
1321             {
1322               /* remove it at beginning of path.  */
1323               if (  ((unixname == fullname)             /* no device spec  */
1324                     && (fullname+2 != basename))        /* starts with ./ */
1325                                                         /* or  */
1326                  || ((basename[-1] == ':')              /* device spec  */
1327                     && (unixname-1 == basename)))       /* and ./ afterwards  */
1328                 *local_ptr++ = '.';                     /* make '[.' start of path.  */
1329               unixname += 2;
1330               continue;
1331             }
1332
1333           /* Add a subdirectory spec. Do not duplicate "." */
1334           if (  local_ptr[-1] != '.'
1335              && local_ptr[-1] != '['
1336              && local_ptr[-1] != '<')
1337             *local_ptr++ = '.';
1338
1339           /* If this is ".." then the spec becomes "-" */
1340           if (  (unixname[0] == '.')
1341              && (unixname[1] == '.')
1342              && (unixname[2] == '/'))
1343             {
1344               /* Add "-" and skip the ".." */
1345               if ((local_ptr[-1] == '.')
1346                   && (local_ptr[-2] == '['))
1347                 local_ptr--;                    /* prevent [.-  */
1348               *local_ptr++ = '-';
1349               unixname += 3;
1350               continue;
1351             }
1352
1353           /* Copy the subdirectory */
1354           while (*unixname != '/')
1355             *local_ptr++= *unixname++;
1356
1357           unixname++;                   /* Skip the "/" */
1358         }
1359
1360       /* Close the directory specification */
1361       if (local_ptr[-1] == '.')         /* no trailing periods */
1362         local_ptr--;
1363
1364       if (local_ptr[-1] == '[')         /* no dir needed */
1365         local_ptr--;
1366       else
1367         *local_ptr++ = ']';
1368     }
1369
1370   /* Now add the filename.  */
1371
1372   while (*unixname)
1373     *local_ptr++ = *unixname++;
1374   *local_ptr = 0;
1375
1376   /* Now append it to the original VMS spec.  */
1377
1378   strcpy ((must_revert==1)?fullname:basename, Local);
1379
1380   /* If we put a [000000] in the filename, try to open it first. If this fails,
1381      remove the [000000], and return that name.  This provides flexibility
1382      to the user in that they can use both rooted and non-rooted logical names
1383      to point to the location of the file.  */
1384
1385   if (check_filename_before_returning)
1386     {
1387       f = open (fullname, O_RDONLY|O_NONBLOCK);
1388       if (f >= 0)
1389         {
1390           /* The file name is OK as it is, so return it as is.  */
1391           close (f);
1392           return 1;
1393         }
1394
1395       /* The filename did not work.  Try to remove the [000000] from the name,
1396          and return it.  */
1397
1398       basename = strchr (fullname, '[');
1399       local_ptr = strchr (fullname, ']') + 1;
1400       strcpy (basename, local_ptr);             /* this gets rid of it */
1401
1402     }
1403
1404   return 1;
1405 }
1406 #endif  /* VMS */