OSDN Git Service

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