OSDN Git Service

* cppfiles.c: Include mkdeps.h.
[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  In other words, you are welcome to use, share and improve this program.
24  You are forbidden to forbid anyone else to use, share and improve
25  what you give them.   Help stamp out software-hoarding!  */
26
27 #include "config.h"
28 #include "system.h"
29 #include "cpplib.h"
30 #include "cpphash.h"
31 #include "hashtab.h"
32 #include "intl.h"
33 #include "mkdeps.h"
34
35 static IHASH *redundant_include_p PARAMS ((cpp_reader *, IHASH *,
36                                            struct file_name_list *));
37 static struct file_name_map *read_name_map
38                                 PARAMS ((cpp_reader *, const char *));
39 static char *read_filename_string PARAMS ((int, FILE *));
40 static char *remap_filename     PARAMS ((cpp_reader *, char *,
41                                          struct file_name_list *));
42 static struct file_name_list *actual_directory
43                                 PARAMS ((cpp_reader *, const char *));
44 static unsigned int hash_IHASH  PARAMS ((const void *));
45 static int eq_IHASH             PARAMS ((const void *, const void *));
46 static int file_cleanup         PARAMS ((cpp_buffer *, cpp_reader *));
47 static int find_include_file    PARAMS ((cpp_reader *, const char *,
48                                         struct file_name_list *,
49                                         IHASH **, int *));
50 static int read_include_file    PARAMS ((cpp_reader *, int, IHASH *));
51
52
53 #if 0
54 static void hack_vms_include_specification PARAMS ((char *));
55 #endif
56
57 /* Initial size of include hash table.  */
58 #define IHASHSIZE 50
59
60 #ifndef INCLUDE_LEN_FUDGE
61 #define INCLUDE_LEN_FUDGE 0
62 #endif
63
64 /* Open files in nonblocking mode, so we don't get stuck if someone
65    clever has asked cpp to process /dev/rmt0.  read_include_file
66    will check that we have a real file to work with.  Also take care
67    not to acquire a controlling terminal by mistake (this can't happen
68    on sane systems, but paranoia is a virtue).  */
69 #define OMODES O_RDONLY|O_NONBLOCK|O_NOCTTY
70
71 /* Calculate hash of an IHASH entry.  */
72 static unsigned int
73 hash_IHASH (x)
74      const void *x;
75 {
76   IHASH *i = (IHASH *)x;
77   unsigned int r = 0, len = 0;
78   const U_CHAR *s = i->nshort;
79
80   if (i->hash != (unsigned long)-1)
81     return i->hash;
82
83   do
84     len++, r = r * 67 + (*s++ - 113);
85   while (*s && *s != '.');
86   i->hash = r + len;
87   return r + len;
88 }
89
90 /* Compare an existing IHASH structure with a potential one.  */
91 static int
92 eq_IHASH (x, y)
93      const void *x;
94      const void *y;
95 {
96   const U_CHAR *a = ((const IHASH *)x)->nshort;
97   const U_CHAR *b = ((const IHASH *)y)->nshort;
98   return !strcmp (a, b);
99 }
100
101 /* Init the hash table.  In here so it can see the hash and eq functions.  */
102 void
103 _cpp_init_include_hash (pfile)
104      cpp_reader *pfile;
105 {
106   pfile->all_include_files
107     = htab_create (IHASHSIZE, hash_IHASH, eq_IHASH, free);
108 }
109
110 /* Return 0 if the file pointed to by IHASH has never been included before,
111          -1 if it has been included before and need not be again,
112          or a pointer to an IHASH entry which is the file to be reread.
113    "Never before" is with respect to the position in ILIST.
114
115    This will not detect redundancies involving odd uses of the
116    `current directory' rule for "" includes.  They aren't quite
117    pathological, but I think they are rare enough not to worry about.
118    The simplest example is:
119
120    top.c:
121    #include "a/a.h"
122    #include "b/b.h"
123
124    a/a.h:
125    #include "../b/b.h"
126
127    and the problem is that for `current directory' includes,
128    ihash->foundhere is not on any of the global include chains,
129    so the test below (i->foundhere == l) may be false even when
130    the directories are in fact the same.  */
131
132 static IHASH *
133 redundant_include_p (pfile, ihash, ilist)
134      cpp_reader *pfile;
135      IHASH *ihash;
136      struct file_name_list *ilist;
137 {
138   struct file_name_list *l;
139   IHASH *i;
140
141   if (! ihash->foundhere)
142     return 0;
143
144   for (i = ihash; i; i = i->next_this_file)
145     for (l = ilist; l; l = l->next)
146        if (i->foundhere == l)
147          /* The control_macro works like this: If it's NULL, the file
148             is to be included again.  If it's "", the file is never to
149             be included again.  If it's a string, the file is not to be
150             included again if the string is the name of a defined macro. */
151          return (i->control_macro
152                  && (i->control_macro[0] == '\0'
153                      || cpp_defined (pfile, i->control_macro, -1)))
154              ? (IHASH *)-1 : i;
155
156   return 0;
157 }
158
159 /* Return 1 if the file named by FNAME has been included before in
160    any context, 0 otherwise.  */
161 int
162 cpp_included (pfile, fname)
163      cpp_reader *pfile;
164      const char *fname;
165 {
166   IHASH dummy, *ptr;
167   dummy.nshort = fname;
168   dummy.hash = -1;
169   ptr = htab_find (pfile->all_include_files, (const void *)&dummy);
170   return (ptr != NULL);
171 }
172
173 static int
174 file_cleanup (pbuf, pfile)
175      cpp_buffer *pbuf;
176      cpp_reader *pfile;
177 {
178   if (pbuf->buf)
179     free ((PTR) pbuf->buf);
180   if (pfile->system_include_depth)
181     pfile->system_include_depth--;
182   return 0;
183 }
184
185 /* Search for include file FNAME in the include chain starting at
186    SEARCH_START.  Return -2 if this file doesn't need to be included
187    (because it was included already and it's marked idempotent),
188    -1 if an error occurred, or a file descriptor open on the file.
189    *IHASH is set to point to the include hash entry for this file, and
190    *BEFORE is set to 1 if the file was included before (but needs to be read
191    again). */
192 static int
193 find_include_file (pfile, fname, search_start, ihash, before)
194      cpp_reader *pfile;
195      const char *fname;
196      struct file_name_list *search_start;
197      IHASH **ihash;
198      int *before;
199 {
200   struct file_name_list *path;
201   IHASH *ih, **slot;
202   IHASH dummy;
203   int f;
204   char *name;
205
206   dummy.hash = -1;
207   dummy.nshort = fname;
208   path = (fname[0] == '/') ? ABSOLUTE_PATH : search_start;
209   slot = (IHASH **) htab_find_slot (pfile->all_include_files,
210                                     (const void *)&dummy, 1);
211
212   if (*slot && (ih = redundant_include_p (pfile, *slot, path)))
213     {
214       if (ih == (IHASH *)-1)
215         return -2;
216
217       *before = 1;
218       *ihash = ih;
219       return open (ih->name, OMODES);
220     }
221
222   if (path == ABSOLUTE_PATH)
223     {
224       name = (char *) fname;
225       f = open (name, OMODES);
226     }
227   else
228     {
229       /* Search directory path, trying to open the file.  */
230       name = alloca (strlen (fname) + pfile->max_include_len
231                      + 2 + INCLUDE_LEN_FUDGE);
232       do
233         {
234           memcpy (name, path->name, path->nlen);
235           name[path->nlen] = '/';
236           strcpy (&name[path->nlen+1], fname);
237           _cpp_simplify_pathname (name);
238           if (CPP_OPTIONS (pfile)->remap)
239             name = remap_filename (pfile, name, path);
240
241           f = open (name, OMODES);
242 #ifdef EACCES
243           if (f == -1 && errno == EACCES)
244             {
245               cpp_error (pfile,
246                          "included file `%s' exists but is not readable",
247                          name);
248               return -1;
249             }
250 #endif
251           if (f >= 0)
252             break;
253           path = path->next;
254         }
255       while (path);
256     }
257   if (f == -1)
258     return -1;
259
260   ih = (IHASH *) xmalloc (sizeof (IHASH) + strlen (name));
261   strcpy ((char *)ih->name, name);
262   ih->foundhere = path;
263   if (path == ABSOLUTE_PATH)
264     ih->nshort = ih->name;
265   else
266     ih->nshort = strstr (ih->name, fname);
267   ih->control_macro = NULL;
268   ih->hash = dummy.hash;
269
270   ih->next_this_file = *slot;
271   *slot = ih;
272
273   *before = 0;
274   *ihash = ih;
275   return f;
276 }
277
278 /* The file_name_map structure holds a mapping of file names for a
279    particular directory.  This mapping is read from the file named
280    FILE_NAME_MAP_FILE in that directory.  Such a file can be used to
281    map filenames on a file system with severe filename restrictions,
282    such as DOS.  The format of the file name map file is just a series
283    of lines with two tokens on each line.  The first token is the name
284    to map, and the second token is the actual name to use.  */
285
286 struct file_name_map
287 {
288   struct file_name_map *map_next;
289   char *map_from;
290   char *map_to;
291 };
292
293 #define FILE_NAME_MAP_FILE "header.gcc"
294
295 /* Read a space delimited string of unlimited length from a stdio
296    file.  */
297
298 static char *
299 read_filename_string (ch, f)
300      int ch;
301      FILE *f;
302 {
303   char *alloc, *set;
304   int len;
305
306   len = 20;
307   set = alloc = xmalloc (len + 1);
308   if (! is_space(ch))
309     {
310       *set++ = ch;
311       while ((ch = getc (f)) != EOF && ! is_space(ch))
312         {
313           if (set - alloc == len)
314             {
315               len *= 2;
316               alloc = xrealloc (alloc, len + 1);
317               set = alloc + len / 2;
318             }
319           *set++ = ch;
320         }
321     }
322   *set = '\0';
323   ungetc (ch, f);
324   return alloc;
325 }
326
327 /* This structure holds a linked list of file name maps, one per directory.  */
328
329 struct file_name_map_list
330 {
331   struct file_name_map_list *map_list_next;
332   char *map_list_name;
333   struct file_name_map *map_list_map;
334 };
335
336 /* Read the file name map file for DIRNAME.  */
337
338 static struct file_name_map *
339 read_name_map (pfile, dirname)
340      cpp_reader *pfile;
341      const char *dirname;
342 {
343   register struct file_name_map_list *map_list_ptr;
344   char *name;
345   FILE *f;
346
347   for (map_list_ptr = CPP_OPTIONS (pfile)->map_list; map_list_ptr;
348        map_list_ptr = map_list_ptr->map_list_next)
349     if (! strcmp (map_list_ptr->map_list_name, dirname))
350       return map_list_ptr->map_list_map;
351
352   map_list_ptr = ((struct file_name_map_list *)
353                   xmalloc (sizeof (struct file_name_map_list)));
354   map_list_ptr->map_list_name = xstrdup (dirname);
355
356   name = (char *) alloca (strlen (dirname) + strlen (FILE_NAME_MAP_FILE) + 2);
357   strcpy (name, dirname);
358   if (*dirname)
359     strcat (name, "/");
360   strcat (name, FILE_NAME_MAP_FILE);
361   f = fopen (name, "r");
362   if (!f)
363     map_list_ptr->map_list_map = (struct file_name_map *)-1;
364   else
365     {
366       int ch;
367       int dirlen = strlen (dirname);
368
369       while ((ch = getc (f)) != EOF)
370         {
371           char *from, *to;
372           struct file_name_map *ptr;
373
374           if (is_space(ch))
375             continue;
376           from = read_filename_string (ch, f);
377           while ((ch = getc (f)) != EOF && is_hspace(ch))
378             ;
379           to = read_filename_string (ch, f);
380
381           ptr = ((struct file_name_map *)
382                  xmalloc (sizeof (struct file_name_map)));
383           ptr->map_from = from;
384
385           /* Make the real filename absolute.  */
386           if (*to == '/')
387             ptr->map_to = to;
388           else
389             {
390               ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
391               strcpy (ptr->map_to, dirname);
392               ptr->map_to[dirlen] = '/';
393               strcpy (ptr->map_to + dirlen + 1, to);
394               free (to);
395             }         
396
397           ptr->map_next = map_list_ptr->map_list_map;
398           map_list_ptr->map_list_map = ptr;
399
400           while ((ch = getc (f)) != '\n')
401             if (ch == EOF)
402               break;
403         }
404       fclose (f);
405     }
406   
407   map_list_ptr->map_list_next = CPP_OPTIONS (pfile)->map_list;
408   CPP_OPTIONS (pfile)->map_list = map_list_ptr;
409
410   return map_list_ptr->map_list_map;
411 }  
412
413 /* Remap NAME based on the file_name_map (if any) for LOC. */
414
415 static char *
416 remap_filename (pfile, name, loc)
417      cpp_reader *pfile;
418      char *name;
419      struct file_name_list *loc;
420 {
421   struct file_name_map *map;
422   const char *from, *p, *dir;
423
424   if (! loc->name_map)
425     loc->name_map = read_name_map (pfile,
426                                    loc->name
427                                    ? loc->name : ".");
428
429   if (loc->name_map == (struct file_name_map *)-1)
430     return name;
431   
432   from = name + strlen (loc->name) + 1;
433   
434   for (map = loc->name_map; map; map = map->map_next)
435     if (!strcmp (map->map_from, from))
436       return map->map_to;
437
438   /* Try to find a mapping file for the particular directory we are
439      looking in.  Thus #include <sys/types.h> will look up sys/types.h
440      in /usr/include/header.gcc and look up types.h in
441      /usr/include/sys/header.gcc.  */
442   p = strrchr (name, '/');
443   if (!p)
444     p = name;
445   if (loc && loc->name
446       && strlen (loc->name) == (size_t) (p - name)
447       && !strncmp (loc->name, name, p - name))
448     /* FILENAME is in SEARCHPTR, which we've already checked.  */
449     return name;
450
451   if (p == name)
452     {
453       dir = ".";
454       from = name;
455     }
456   else
457     {
458       char * newdir = (char *) alloca (p - name + 1);
459       memcpy (newdir, name, p - name);
460       newdir[p - name] = '\0';
461       dir = newdir;
462       from = p + 1;
463     }
464   
465   for (map = read_name_map (pfile, dir); map; map = map->map_next)
466     if (! strcmp (map->map_from, name))
467       return map->map_to;
468
469   return name;
470 }
471
472
473 void
474 _cpp_execute_include (pfile, fname, len, no_reinclude, search_start)
475      cpp_reader *pfile;
476      char *fname;
477      unsigned int len;
478      int no_reinclude;
479      struct file_name_list *search_start;
480 {
481   IHASH *ihash;
482   int fd;
483   int angle_brackets = fname[0] == '<';
484   int before;
485
486   if (!search_start)
487     {
488       if (angle_brackets)
489         search_start = CPP_OPTIONS (pfile)->bracket_include;
490       else if (CPP_OPTIONS (pfile)->ignore_srcdir)
491         search_start = CPP_OPTIONS (pfile)->quote_include;
492       else
493         search_start = CPP_BUFFER (pfile)->actual_dir;
494     }
495
496   if (!search_start)
497     {
498       cpp_error (pfile, "No include path in which to find %s", fname);
499       return;
500     }
501
502   /* Remove quote marks.  */
503   fname++;
504   len -= 2;
505   fname[len] = '\0';
506
507   fd = find_include_file (pfile, fname, search_start, &ihash, &before);
508
509   if (fd == -2)
510     return;
511   
512   if (fd == -1)
513     {
514       if (CPP_OPTIONS (pfile)->print_deps_missing_files
515           && CPP_PRINT_DEPS (pfile) > (angle_brackets ||
516                                        (pfile->system_include_depth > 0)))
517         {
518           if (!angle_brackets)
519             deps_add_dep (pfile->deps, fname);
520           else
521             {
522               char *p;
523               struct file_name_list *ptr;
524               /* If requested as a system header, assume it belongs in
525                  the first system header directory. */
526               if (CPP_OPTIONS (pfile)->bracket_include)
527                 ptr = CPP_OPTIONS (pfile)->bracket_include;
528               else
529                 ptr = CPP_OPTIONS (pfile)->quote_include;
530
531               p = (char *) alloca (strlen (ptr->name)
532                                    + strlen (fname) + 2);
533               if (*ptr->name != '\0')
534                 {
535                   strcpy (p, ptr->name);
536                   strcat (p, "/");
537                 }
538               strcat (p, fname);
539               deps_add_dep (pfile->deps, p);
540             }
541         }
542       /* If -M was specified, and this header file won't be added to
543          the dependency list, then don't count this as an error,
544          because we can still produce correct output.  Otherwise, we
545          can't produce correct output, because there may be
546          dependencies we need inside the missing file, and we don't
547          know what directory this missing file exists in. */
548       else if (CPP_PRINT_DEPS (pfile)
549                && (CPP_PRINT_DEPS (pfile)
550                    <= (angle_brackets || (pfile->system_include_depth > 0))))
551         cpp_warning (pfile, "No include path in which to find %s", fname);
552       else
553         cpp_error_from_errno (pfile, fname);
554
555       return;
556     }
557
558   /* For -M, add the file to the dependencies on its first inclusion. */
559   if (!before && (CPP_PRINT_DEPS (pfile)
560                   > (angle_brackets || (pfile->system_include_depth > 0))))
561     deps_add_dep (pfile->deps, ihash->name);
562
563   /* Handle -H option.  */
564   if (CPP_OPTIONS(pfile)->print_include_names)
565     {
566       cpp_buffer *fp = CPP_BUFFER (pfile);
567       while ((fp = CPP_PREV_BUFFER (fp)) != NULL)
568         putc ('.', stderr);
569       fprintf (stderr, " %s\n", ihash->name);
570     }
571
572   /* Actually process the file */
573
574   if (no_reinclude)
575     ihash->control_macro = (const U_CHAR *) "";
576   
577   if (read_include_file (pfile, fd, ihash))
578     {
579       _cpp_output_line_command (pfile, enter_file);
580       if (angle_brackets)
581         pfile->system_include_depth++;   /* Decremented in file_cleanup. */
582     }
583 }
584
585
586 /* Push an input buffer and load it up with the contents of FNAME.
587    If FNAME is "" or NULL, read standard input.  */
588 int
589 cpp_read_file (pfile, fname)
590      cpp_reader *pfile;
591      const char *fname;
592 {
593   IHASH *ih, **slot;
594   IHASH dummy;
595   int f;
596
597   if (fname == NULL)
598     fname = "";
599
600   dummy.hash = -1;
601   dummy.nshort = fname;
602   slot = (IHASH **) htab_find_slot (pfile->all_include_files,
603                                     (const void *) &dummy, 1);
604   if (*slot && (ih = redundant_include_p (pfile, *slot, ABSOLUTE_PATH)))
605     {
606       if (ih == (IHASH *)-1)
607         return 1;  /* Already included.  */
608     }
609   else
610     {
611       ih = (IHASH *) xmalloc (sizeof (IHASH) + strlen (fname));
612       ih->control_macro = 0;
613       ih->foundhere = ABSOLUTE_PATH;  /* well sort of ... */
614       ih->hash = dummy.hash;
615       strcpy ((char *)ih->name, fname);
616       ih->nshort = ih->name;
617
618       ih->next_this_file = *slot;
619       *slot = ih;
620     }
621
622   if (*fname == '\0')
623     f = 0;
624   else
625     f = open (fname, OMODES);
626
627   return read_include_file (pfile, f, ih);
628 }
629
630 /* Read the contents of FD into the buffer on the top of PFILE's stack.
631    IHASH points to the include hash entry for the file associated with
632    FD.
633
634    The caller is responsible for the cpp_push_buffer.  */
635
636 static int
637 read_include_file (pfile, fd, ihash)
638      cpp_reader *pfile;
639      int fd;
640      IHASH *ihash;
641 {
642   struct stat st;
643   size_t st_size;
644   long length;
645   cpp_buffer *fp;
646
647   fp = cpp_push_buffer (pfile, NULL, 0);
648
649   if (fp == 0)
650     goto push_fail;
651
652   if (fstat (fd, &st) < 0)
653     goto perror_fail;
654   if (fcntl (fd, F_SETFL, 0) == -1)  /* turn off nonblocking mode */
655     goto perror_fail;
656
657   /* If fd points to a plain file, we know how big it is, so we can
658      allocate the buffer all at once.  If fd is a pipe or terminal, we
659      can't.  Most C source files are 4k or less, so we guess that.  If
660      fd is something weird, like a block device or a directory, we
661      don't want to read it at all.
662
663      Unfortunately, different systems use different st.st_mode values
664      for pipes: some have S_ISFIFO, some S_ISSOCK, some are buggy and
665      zero the entire struct stat except a couple fields.  Hence the
666      mess below.
667
668      In all cases, read_and_prescan will resize the buffer if it
669      turns out there's more data than we thought.  */
670
671   if (S_ISREG (st.st_mode))
672     {
673       /* off_t might have a wider range than size_t - in other words,
674          the max size of a file might be bigger than the address
675          space.  We can't handle a file that large.  (Anyone with
676          a single source file bigger than 4GB needs to rethink
677          their coding style.)  */
678       st_size = (size_t) st.st_size;
679       if ((unsigned HOST_WIDEST_INT) st_size
680           != (unsigned HOST_WIDEST_INT) st.st_size)
681         {
682           cpp_error (pfile, "file `%s' is too large", ihash->name);
683           goto fail;
684         }
685     }
686   else if (S_ISFIFO (st.st_mode) || S_ISSOCK (st.st_mode)
687            /* Permit any kind of character device: the sensible ones are
688               ttys and /dev/null, but weeding out the others is too hard.  */
689            || S_ISCHR (st.st_mode)
690            /* Some 4.x (x<4) derivatives have a bug that makes fstat() of a
691               socket or pipe return a stat struct with most fields zeroed.  */
692            || (st.st_mode == 0 && st.st_nlink == 0 && st.st_size == 0))
693     {
694       /* Cannot get its file size before reading.  4k is a decent
695          first guess. */
696       st_size = 4096;
697     }
698   else
699     {
700       cpp_error (pfile, "`%s' is not a file, pipe, or tty", ihash->name);
701       goto fail;
702     }
703
704   /* Read the file, converting end-of-line characters and trigraphs
705      (if enabled). */
706   fp->ihash = ihash;
707   fp->nominal_fname = ihash->name;
708   length = _cpp_read_and_prescan (pfile, fp, fd, st_size);
709   if (length < 0)
710     goto fail;
711   if (length == 0)
712     ihash->control_macro = (const U_CHAR *) "";  /* never re-include */
713
714   close (fd);
715   fp->rlimit = fp->alimit = fp->buf + length;
716   fp->cur = fp->buf;
717   if (ihash->foundhere != ABSOLUTE_PATH)
718       fp->system_header_p = ihash->foundhere->sysp;
719   fp->lineno = 1;
720   fp->colno = 1;
721   fp->line_base = fp->buf;
722   fp->cleanup = file_cleanup;
723
724   /* The ->actual_dir field is only used when ignore_srcdir is not in effect;
725      see do_include */
726   if (!CPP_OPTIONS (pfile)->ignore_srcdir)
727     fp->actual_dir = actual_directory (pfile, ihash->name);
728
729   pfile->input_stack_listing_current = 0;
730   pfile->only_seen_white = 2;
731   return 1;
732
733  perror_fail:
734   cpp_error_from_errno (pfile, ihash->name);
735  fail:
736   cpp_pop_buffer (pfile);
737  push_fail:
738   close (fd);
739   return 0;
740 }
741
742 /* Given a path FNAME, extract the directory component and place it
743    onto the actual_dirs list.  Return a pointer to the allocated
744    file_name_list structure.  These structures are used to implement
745    current-directory "" include searching. */
746
747 static struct file_name_list *
748 actual_directory (pfile, fname)
749      cpp_reader *pfile;
750      const char *fname;
751 {
752   char *last_slash, *dir;
753   size_t dlen;
754   struct file_name_list *x;
755   
756   dir = xstrdup (fname);
757   last_slash = strrchr (dir, '/');
758   if (last_slash)
759     {
760       if (last_slash == dir)
761         {
762           dlen = 1;
763           last_slash[1] = '\0';
764         }
765       else
766         {
767           dlen = last_slash - dir;
768           *last_slash = '\0';
769         }
770     }
771   else
772     {
773       dir[0] = '.';
774       dir[1] = '\0';
775       dlen = 1;
776     }
777
778   if (dlen > pfile->max_include_len)
779     pfile->max_include_len = dlen;
780
781   for (x = pfile->actual_dirs; x; x = x->alloc)
782     if (!strcmp (x->name, dir))
783       {
784         free (dir);
785         return x;
786       }
787
788   /* Not found, make a new one. */
789   x = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
790   x->name = dir;
791   x->nlen = dlen;
792   x->next = CPP_OPTIONS (pfile)->quote_include;
793   x->alloc = pfile->actual_dirs;
794   x->sysp = CPP_BUFFER (pfile)->system_header_p;
795   x->name_map = NULL;
796
797   pfile->actual_dirs = x;
798   return x;
799 }
800
801 /* Simplify a path name in place, deleting redundant components.  This
802    reduces OS overhead and guarantees that equivalent paths compare
803    the same (modulo symlinks).
804
805    Transforms made:
806    foo/bar/../quux      foo/quux
807    foo/./bar            foo/bar
808    foo//bar             foo/bar
809    /../quux             /quux
810    //quux               //quux  (POSIX allows leading // as a namespace escape)
811
812    Guarantees no trailing slashes. All transforms reduce the length
813    of the string.
814  */
815 void
816 _cpp_simplify_pathname (path)
817     char *path;
818 {
819     char *from, *to;
820     char *base;
821     int absolute = 0;
822
823 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
824     /* Convert all backslashes to slashes. */
825     for (from = path; *from; from++)
826         if (*from == '\\') *from = '/';
827     
828     /* Skip over leading drive letter if present. */
829     if (ISALPHA (path[0]) && path[1] == ':')
830         from = to = &path[2];
831     else
832         from = to = path;
833 #else
834     from = to = path;
835 #endif
836     
837     /* Remove redundant initial /s.  */
838     if (*from == '/')
839     {
840         absolute = 1;
841         to++;
842         from++;
843         if (*from == '/')
844         {
845             if (*++from == '/')
846                 /* 3 or more initial /s are equivalent to 1 /.  */
847                 while (*++from == '/');
848             else
849                 /* On some hosts // differs from /; Posix allows this.  */
850                 to++;
851         }
852     }
853     base = to;
854     
855     for (;;)
856     {
857         while (*from == '/')
858             from++;
859
860         if (from[0] == '.' && from[1] == '/')
861             from += 2;
862         else if (from[0] == '.' && from[1] == '\0')
863             goto done;
864         else if (from[0] == '.' && from[1] == '.' && from[2] == '/')
865         {
866             if (base == to)
867             {
868                 if (absolute)
869                     from += 3;
870                 else
871                 {
872                     *to++ = *from++;
873                     *to++ = *from++;
874                     *to++ = *from++;
875                     base = to;
876                 }
877             }
878             else
879             {
880                 to -= 2;
881                 while (to > base && *to != '/') to--;
882                 if (*to == '/')
883                     to++;
884                 from += 3;
885             }
886         }
887         else if (from[0] == '.' && from[1] == '.' && from[2] == '\0')
888         {
889             if (base == to)
890             {
891                 if (!absolute)
892                 {
893                     *to++ = *from++;
894                     *to++ = *from++;
895                 }
896             }
897             else
898             {
899                 to -= 2;
900                 while (to > base && *to != '/') to--;
901                 if (*to == '/')
902                     to++;
903             }
904             goto done;
905         }
906         else
907             /* Copy this component and trailing /, if any.  */
908             while ((*to++ = *from++) != '/')
909             {
910                 if (!to[-1])
911                 {
912                     to--;
913                     goto done;
914                 }
915             }
916         
917     }
918     
919  done:
920     /* Trim trailing slash */
921     if (to[0] == '/' && (!absolute || to > path+1))
922         to--;
923
924     /* Change the empty string to "." so that stat() on the result
925        will always work. */
926     if (to == path)
927       *to++ = '.';
928     
929     *to = '\0';
930
931     return;
932 }
933
934 /* It is not clear when this should be used if at all, so I've
935    disabled it until someone who understands VMS can look at it. */
936 #if 0
937
938 /* Under VMS we need to fix up the "include" specification filename.
939
940    Rules for possible conversions
941
942         fullname                tried paths
943
944         name                    name
945         ./dir/name              [.dir]name
946         /dir/name               dir:name
947         /name                   [000000]name, name
948         dir/name                dir:[000000]name, dir:name, dir/name
949         dir1/dir2/name          dir1:[dir2]name, dir1:[000000.dir2]name
950         path:/name              path:[000000]name, path:name
951         path:/dir/name          path:[000000.dir]name, path:[dir]name
952         path:dir/name           path:[dir]name
953         [path]:[dir]name        [path.dir]name
954         path/[dir]name          [path.dir]name
955
956    The path:/name input is constructed when expanding <> includes. */
957
958
959 static void
960 hack_vms_include_specification (fullname)
961      char *fullname;
962 {
963   register char *basename, *unixname, *local_ptr, *first_slash;
964   int f, check_filename_before_returning, must_revert;
965   char Local[512];
966
967   check_filename_before_returning = 0;
968   must_revert = 0;
969   /* See if we can find a 1st slash. If not, there's no path information.  */
970   first_slash = strchr (fullname, '/');
971   if (first_slash == 0)
972     return 0;                           /* Nothing to do!!! */
973
974   /* construct device spec if none given.  */
975
976   if (strchr (fullname, ':') == 0)
977     {
978
979       /* If fullname has a slash, take it as device spec.  */
980
981       if (first_slash == fullname)
982         {
983           first_slash = strchr (fullname + 1, '/');     /* 2nd slash ? */
984           if (first_slash)
985             *first_slash = ':';                         /* make device spec  */
986           for (basename = fullname; *basename != 0; basename++)
987             *basename = *(basename+1);                  /* remove leading slash  */
988         }
989       else if ((first_slash[-1] != '.')         /* keep ':/', './' */
990             && (first_slash[-1] != ':')
991             && (first_slash[-1] != ']'))        /* or a vms path  */
992         {
993           *first_slash = ':';
994         }
995       else if ((first_slash[1] == '[')          /* skip './' in './[dir'  */
996             && (first_slash[-1] == '.'))
997         fullname += 2;
998     }
999
1000   /* Get part after first ':' (basename[-1] == ':')
1001      or last '/' (basename[-1] == '/').  */
1002
1003   basename = base_name (fullname);
1004
1005   local_ptr = Local;                    /* initialize */
1006
1007   /* We are trying to do a number of things here.  First of all, we are
1008      trying to hammer the filenames into a standard format, such that later
1009      processing can handle them.
1010      
1011      If the file name contains something like [dir.], then it recognizes this
1012      as a root, and strips the ".]".  Later processing will add whatever is
1013      needed to get things working properly.
1014      
1015      If no device is specified, then the first directory name is taken to be
1016      a device name (or a rooted logical).  */
1017
1018   /* Point to the UNIX filename part (which needs to be fixed!)
1019      but skip vms path information.
1020      [basename != fullname since first_slash != 0].  */
1021
1022   if ((basename[-1] == ':')             /* vms path spec.  */
1023       || (basename[-1] == ']')
1024       || (basename[-1] == '>'))
1025     unixname = basename;
1026   else
1027     unixname = fullname;
1028
1029   if (*unixname == '/')
1030     unixname++;
1031
1032   /* If the directory spec is not rooted, we can just copy
1033      the UNIX filename part and we are done.  */
1034
1035   if (((basename - fullname) > 1)
1036      && (  (basename[-1] == ']')
1037         || (basename[-1] == '>')))
1038     {
1039       if (basename[-2] != '.')
1040         {
1041
1042         /* The VMS part ends in a `]', and the preceding character is not a `.'.
1043            -> PATH]:/name (basename = '/name', unixname = 'name')
1044            We strip the `]', and then splice the two parts of the name in the
1045            usual way.  Given the default locations for include files in cccp.c,
1046            we will only use this code if the user specifies alternate locations
1047            with the /include (-I) switch on the command line.  */
1048
1049           basename -= 1;        /* Strip "]" */
1050           unixname--;           /* backspace */
1051         }
1052       else
1053         {
1054
1055         /* The VMS part has a ".]" at the end, and this will not do.  Later
1056            processing will add a second directory spec, and this would be a syntax
1057            error.  Thus we strip the ".]", and thus merge the directory specs.
1058            We also backspace unixname, so that it points to a '/'.  This inhibits the
1059            generation of the 000000 root directory spec (which does not belong here
1060            in this case).  */
1061
1062           basename -= 2;        /* Strip ".]" */
1063           unixname--;           /* backspace */
1064         }
1065     }
1066
1067   else
1068
1069     {
1070
1071       /* We drop in here if there is no VMS style directory specification yet.
1072          If there is no device specification either, we make the first dir a
1073          device and try that.  If we do not do this, then we will be essentially
1074          searching the users default directory (as if they did a #include "asdf.h").
1075         
1076          Then all we need to do is to push a '[' into the output string. Later
1077          processing will fill this in, and close the bracket.  */
1078
1079       if ((unixname != fullname)        /* vms path spec found.  */
1080          && (basename[-1] != ':'))
1081         *local_ptr++ = ':';             /* dev not in spec.  take first dir */
1082
1083       *local_ptr++ = '[';               /* Open the directory specification */
1084     }
1085
1086     if (unixname == fullname)           /* no vms dir spec.  */
1087       {
1088         must_revert = 1;
1089         if ((first_slash != 0)          /* unix dir spec.  */
1090             && (*unixname != '/')       /* not beginning with '/'  */
1091             && (*unixname != '.'))      /* or './' or '../'  */
1092           *local_ptr++ = '.';           /* dir is local !  */
1093       }
1094
1095   /* at this point we assume that we have the device spec, and (at least
1096      the opening "[" for a directory specification.  We may have directories
1097      specified already.
1098
1099      If there are no other slashes then the filename will be
1100      in the "root" directory.  Otherwise, we need to add
1101      directory specifications.  */
1102
1103   if (strchr (unixname, '/') == 0)
1104     {
1105       /* if no directories specified yet and none are following.  */
1106       if (local_ptr[-1] == '[')
1107         {
1108           /* Just add "000000]" as the directory string */
1109           strcpy (local_ptr, "000000]");
1110           local_ptr += strlen (local_ptr);
1111           check_filename_before_returning = 1; /* we might need to fool with this later */
1112         }
1113     }
1114   else
1115     {
1116
1117       /* As long as there are still subdirectories to add, do them.  */
1118       while (strchr (unixname, '/') != 0)
1119         {
1120           /* If this token is "." we can ignore it
1121                if it's not at the beginning of a path.  */
1122           if ((unixname[0] == '.') && (unixname[1] == '/'))
1123             {
1124               /* remove it at beginning of path.  */
1125               if (  ((unixname == fullname)             /* no device spec  */
1126                     && (fullname+2 != basename))        /* starts with ./ */
1127                                                         /* or  */
1128                  || ((basename[-1] == ':')              /* device spec  */
1129                     && (unixname-1 == basename)))       /* and ./ afterwards  */
1130                 *local_ptr++ = '.';                     /* make '[.' start of path.  */
1131               unixname += 2;
1132               continue;
1133             }
1134
1135           /* Add a subdirectory spec. Do not duplicate "." */
1136           if (  local_ptr[-1] != '.'
1137              && local_ptr[-1] != '['
1138              && local_ptr[-1] != '<')
1139             *local_ptr++ = '.';
1140
1141           /* If this is ".." then the spec becomes "-" */
1142           if (  (unixname[0] == '.')
1143              && (unixname[1] == '.')
1144              && (unixname[2] == '/'))
1145             {
1146               /* Add "-" and skip the ".." */
1147               if ((local_ptr[-1] == '.')
1148                   && (local_ptr[-2] == '['))
1149                 local_ptr--;                    /* prevent [.-  */
1150               *local_ptr++ = '-';
1151               unixname += 3;
1152               continue;
1153             }
1154
1155           /* Copy the subdirectory */
1156           while (*unixname != '/')
1157             *local_ptr++= *unixname++;
1158
1159           unixname++;                   /* Skip the "/" */
1160         }
1161
1162       /* Close the directory specification */
1163       if (local_ptr[-1] == '.')         /* no trailing periods */
1164         local_ptr--;
1165
1166       if (local_ptr[-1] == '[')         /* no dir needed */
1167         local_ptr--;
1168       else
1169         *local_ptr++ = ']';
1170     }
1171
1172   /* Now add the filename.  */
1173
1174   while (*unixname)
1175     *local_ptr++ = *unixname++;
1176   *local_ptr = 0;
1177
1178   /* Now append it to the original VMS spec.  */
1179
1180   strcpy ((must_revert==1)?fullname:basename, Local);
1181
1182   /* If we put a [000000] in the filename, try to open it first. If this fails,
1183      remove the [000000], and return that name.  This provides flexibility
1184      to the user in that they can use both rooted and non-rooted logical names
1185      to point to the location of the file.  */
1186
1187   if (check_filename_before_returning)
1188     {
1189       f = open (fullname, OMODES);
1190       if (f >= 0)
1191         {
1192           /* The file name is OK as it is, so return it as is.  */
1193           close (f);
1194           return 1;
1195         }
1196
1197       /* The filename did not work.  Try to remove the [000000] from the name,
1198          and return it.  */
1199
1200       basename = strchr (fullname, '[');
1201       local_ptr = strchr (fullname, ']') + 1;
1202       strcpy (basename, local_ptr);             /* this gets rid of it */
1203
1204     }
1205
1206   return 1;
1207 }
1208 #endif  /* VMS */