OSDN Git Service

* cpplib.c (if_directive_nameo): Add static prototype.
[pf3gnuchains/gcc-fork.git] / gcc / cppfiles.c
1 /* Part of CPP library.  (include file handling)
2    Copyright (C) 1986, 87, 89, 92 - 95, 98, 1999 Free Software Foundation, Inc.
3    Written by Per Bothner, 1994.
4    Based on CCCP program by Paul Rubin, June 1986
5    Adapted to ANSI C, Richard Stallman, Jan 1987
6    Split out of cpplib.c, Zack Weinberg, Oct 1998
7
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
11 later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22  In other words, you are welcome to use, share and improve this program.
23  You are forbidden to forbid anyone else to use, share and improve
24  what you give them.   Help stamp out software-hoarding!  */
25
26 #include "config.h"
27 #include "system.h"
28 #include "cpplib.h"
29
30 /* The entry points to this file are: find_include_file, finclude,
31    include_hash, append_include_chain, deps_output, and file_cleanup.
32    file_cleanup is only called through CPP_BUFFER(pfile)->cleanup,
33    so it's static anyway. */
34
35 static struct include_hash *redundant_include_p
36                                         PROTO ((cpp_reader *,
37                                                 struct include_hash *,
38                                                 struct file_name_list *));
39 static struct file_name_map *read_name_map      PROTO ((cpp_reader *,
40                                                         const char *));
41 static char *read_filename_string       PROTO ((int, FILE *));
42 static char *remap_filename             PROTO ((cpp_reader *, char *,
43                                                 struct file_name_list *));
44 static long read_and_prescan            PROTO ((cpp_reader *, cpp_buffer *,
45                                                 int, size_t));
46 static struct file_name_list *actual_directory PROTO ((cpp_reader *,
47                                                        const char *));
48 static void initialize_input_buffer     PROTO ((cpp_reader *, int,
49                                                 struct stat *));
50 static int file_cleanup                 PROTO ((cpp_buffer *, cpp_reader *));
51 static void find_position               PROTO ((U_CHAR *, U_CHAR *,
52                                                 unsigned long *,
53                                                 unsigned long *));
54
55 #if 0
56 static void hack_vms_include_specification PROTO ((char *));
57 #endif
58
59 /* Windows does not natively support inodes, and neither does MSDOS.
60    VMS has non-numeric inodes. */
61 #ifdef VMS
62 #define INO_T_EQ(a, b) (!bcmp((char *) &(a), (char *) &(b), sizeof (a)))
63 #elif (defined _WIN32 && !defined CYGWIN && ! defined (_UWIN)) \
64        || defined __MSDOS__
65 #define INO_T_EQ(a, b) 0
66 #else
67 #define INO_T_EQ(a, b) ((a) == (b))
68 #endif
69
70 /* Merge the four include chains together in the order quote, bracket,
71    system, after.  Remove duplicate dirs (as determined by
72    INO_T_EQ()).  The system_include and after_include chains are never
73    referred to again after this function; all access is through the
74    bracket_include path.
75
76    For the future: Check if the directory is empty (but
77    how?) and possibly preload the include hash. */
78
79 void
80 merge_include_chains (opts)
81      struct cpp_options *opts;
82 {
83   struct file_name_list *prev, *cur, *other;
84   struct file_name_list *quote, *brack, *systm, *after;
85   struct file_name_list *qtail, *btail, *stail, *atail;
86
87   qtail = opts->pending->quote_tail;
88   btail = opts->pending->brack_tail;
89   stail = opts->pending->systm_tail;
90   atail = opts->pending->after_tail;
91
92   quote = opts->pending->quote_head;
93   brack = opts->pending->brack_head;
94   systm = opts->pending->systm_head;
95   after = opts->pending->after_head;
96
97   /* Paste together bracket, system, and after include chains. */
98   if (stail)
99     stail->next = after;
100   else
101     systm = after;
102   if (btail)
103     btail->next = systm;
104   else
105     brack = systm;
106
107   /* This is a bit tricky.
108      First we drop dupes from the quote-include list.
109      Then we drop dupes from the bracket-include list.
110      Finally, if qtail and brack are the same directory,
111      we cut out qtail.
112
113      We can't just merge the lists and then uniquify them because
114      then we may lose directories from the <> search path that should
115      be there; consider -Ifoo -Ibar -I- -Ifoo -Iquux. It is however
116      safe to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written
117      -Ibar -I- -Ifoo -Iquux.
118
119      Note that this algorithm is quadratic in the number of -I switches,
120      which is acceptable since there aren't usually that many of them.  */
121
122   for (cur = quote, prev = NULL; cur; cur = cur->next)
123     {
124       for (other = quote; other != cur; other = other->next)
125         if (INO_T_EQ (cur->ino, other->ino)
126             && cur->dev == other->dev)
127           {
128             if (opts->verbose)
129               cpp_notice ("ignoring duplicate directory `%s'\n", cur->name);
130
131             prev->next = cur->next;
132             free (cur->name);
133             free (cur);
134             cur = prev;
135             break;
136           }
137       prev = cur;
138     }
139   qtail = prev;
140
141   for (cur = brack; cur; cur = cur->next)
142     {
143       for (other = brack; other != cur; other = other->next)
144         if (INO_T_EQ (cur->ino, other->ino)
145             && cur->dev == other->dev)
146           {
147             if (opts->verbose)
148               cpp_notice ("ignoring duplicate directory `%s'\n", cur->name);
149
150             prev->next = cur->next;
151             free (cur->name);
152             free (cur);
153             cur = prev;
154             break;
155           }
156       prev = cur;
157     }
158
159   if (quote)
160     {
161       if (INO_T_EQ (qtail->ino, brack->ino) && qtail->dev == brack->dev)
162         {
163           if (quote == qtail)
164             {
165               if (opts->verbose)
166                 cpp_notice ("ignoring duplicate directory `%s'\n",
167                             quote->name);
168
169               free (quote->name);
170               free (quote);
171               quote = brack;
172             }
173           else
174             {
175               cur = quote;
176               while (cur->next != qtail)
177                   cur = cur->next;
178               cur->next = brack;
179               if (opts->verbose)
180                 cpp_notice ("ignoring duplicate directory `%s'\n",
181                             qtail->name);
182
183               free (qtail->name);
184               free (qtail);
185             }
186         }
187       else
188           qtail->next = brack;
189     }
190   else
191       quote = brack;
192
193   opts->quote_include = quote;
194   opts->bracket_include = brack;
195 }
196
197 /* Look up or add an entry to the table of all includes.  This table
198  is indexed by the name as it appears in the #include line.  The
199  ->next_this_file chain stores all different files with the same
200  #include name (there are at least three ways this can happen).  The
201  hash function could probably be improved a bit. */
202
203 struct include_hash *
204 include_hash (pfile, fname, add)
205      cpp_reader *pfile;
206      const char *fname;
207      int add;
208 {
209   unsigned int hash = 0;
210   struct include_hash *l, *m;
211   const char *f = fname;
212
213   while (*f)
214     hash += *f++;
215
216   l = pfile->all_include_files[hash % ALL_INCLUDE_HASHSIZE];
217   m = 0;
218   for (; l; m = l, l = l->next)
219     if (!strcmp (l->nshort, fname))
220       return l;
221
222   if (!add)
223     return 0;
224   
225   l = (struct include_hash *) xmalloc (sizeof (struct include_hash));
226   l->next = NULL;
227   l->next_this_file = NULL;
228   l->foundhere = NULL;
229   l->buf = NULL;
230   l->limit = NULL;
231   if (m)
232     m->next = l;
233   else
234     pfile->all_include_files[hash % ALL_INCLUDE_HASHSIZE] = l;
235   
236   return l;
237 }
238
239 /* Return 0 if the file pointed to by IHASH has never been included before,
240          -1 if it has been included before and need not be again,
241          or a pointer to an IHASH entry which is the file to be reread.
242    "Never before" is with respect to the position in ILIST.
243
244    This will not detect redundancies involving odd uses of the
245    `current directory' rule for "" includes.  They aren't quite
246    pathological, but I think they are rare enough not to worry about.
247    The simplest example is:
248
249    top.c:
250    #include "a/a.h"
251    #include "b/b.h"
252
253    a/a.h:
254    #include "../b/b.h"
255
256    and the problem is that for `current directory' includes,
257    ihash->foundhere is not on any of the global include chains,
258    so the test below (i->foundhere == l) may be false even when
259    the directories are in fact the same.  */
260
261 static struct include_hash *
262 redundant_include_p (pfile, ihash, ilist)
263      cpp_reader *pfile;
264      struct include_hash *ihash;
265      struct file_name_list *ilist;
266 {
267   struct file_name_list *l;
268   struct include_hash *i;
269
270   if (! ihash->foundhere)
271     return 0;
272
273   for (i = ihash; i; i = i->next_this_file)
274     for (l = ilist; l; l = l->next)
275        if (i->foundhere == l)
276          /* The control_macro works like this: If it's NULL, the file
277             is to be included again.  If it's "", the file is never to
278             be included again.  If it's a string, the file is not to be
279             included again if the string is the name of a defined macro. */
280          return (i->control_macro
281                  && (i->control_macro[0] == '\0'
282                      || cpp_lookup (pfile, i->control_macro, -1, -1)))
283              ? (struct include_hash *)-1 : i;
284
285   return 0;
286 }
287
288 static int
289 file_cleanup (pbuf, pfile)
290      cpp_buffer *pbuf;
291      cpp_reader *pfile;
292 {
293   if (pbuf->buf)
294     {
295       free (pbuf->buf);
296       pbuf->buf = 0;
297     }
298   if (pfile->system_include_depth)
299     pfile->system_include_depth--;
300   return 0;
301 }
302
303 /* Search for include file FNAME in the include chain starting at
304    SEARCH_START.  Return -2 if this file doesn't need to be included
305    (because it was included already and it's marked idempotent),
306    -1 if an error occurred, or a file descriptor open on the file.
307    *IHASH is set to point to the include hash entry for this file, and
308    *BEFORE is 1 if the file was included before (but needs to be read
309    again). */
310 int
311 find_include_file (pfile, fname, search_start, ihash, before)
312      cpp_reader *pfile;
313      const char *fname;
314      struct file_name_list *search_start;
315      struct include_hash **ihash;
316      int *before;
317 {
318   struct file_name_list *l;
319   struct include_hash *ih, *jh;
320   int f, len;
321   char *name;
322   
323   ih = include_hash (pfile, fname, 1);
324   jh = redundant_include_p (pfile, ih,
325                             fname[0] == '/' ? ABSOLUTE_PATH : search_start);
326
327   if (jh != 0)
328     {
329       *before = 1;
330       *ihash = jh;
331
332       if (jh == (struct include_hash *)-1)
333         return -2;
334       else
335         return open (jh->name, O_RDONLY, 0666);
336     }
337
338   if (ih->foundhere)
339     /* A file is already known by this name, but it's not the same file.
340        Allocate another include_hash block and add it to the next_this_file
341        chain. */
342     {
343       jh = (struct include_hash *)xmalloc (sizeof (struct include_hash));
344       while (ih->next_this_file) ih = ih->next_this_file;
345
346       ih->next_this_file = jh;
347       jh = ih;
348       ih = ih->next_this_file;
349
350       ih->next = NULL;
351       ih->next_this_file = NULL;
352       ih->buf = NULL;
353       ih->limit = NULL;
354     }
355   *before = 0;
356   *ihash = ih;
357   ih->nshort = xstrdup (fname);
358   ih->control_macro = NULL;
359   
360   /* If the pathname is absolute, just open it. */ 
361   if (fname[0] == '/')
362     {
363       ih->foundhere = ABSOLUTE_PATH;
364       ih->name = ih->nshort;
365       return open (ih->name, O_RDONLY, 0666);
366     }
367
368   /* Search directory path, trying to open the file. */
369
370   len = strlen (fname);
371   name = xmalloc (len + pfile->max_include_len + 2 + INCLUDE_LEN_FUDGE);
372
373   for (l = search_start; l; l = l->next)
374     {
375       bcopy (l->name, name, l->nlen);
376       name[l->nlen] = '/';
377       strcpy (&name[l->nlen+1], fname);
378       simplify_pathname (name);
379       if (CPP_OPTIONS (pfile)->remap)
380         name = remap_filename (pfile, name, l);
381
382       f = open (name, O_RDONLY|O_NONBLOCK|O_NOCTTY, 0666);
383 #ifdef EACCES
384       if (f == -1 && errno == EACCES)
385         {
386           cpp_error(pfile, "included file `%s' exists but is not readable",
387                     name);
388           return -1;
389         }
390 #endif
391
392       if (f >= 0)
393         {
394           ih->foundhere = l;
395           ih->name = xrealloc (name, strlen (name)+1);
396           return f;
397         }
398     }
399   
400     if (jh)
401       {
402         jh->next_this_file = NULL;
403         free (ih);
404       }
405     free (name);
406     *ihash = (struct include_hash *)-1;
407     return -1;
408 }
409
410 /* The file_name_map structure holds a mapping of file names for a
411    particular directory.  This mapping is read from the file named
412    FILE_NAME_MAP_FILE in that directory.  Such a file can be used to
413    map filenames on a file system with severe filename restrictions,
414    such as DOS.  The format of the file name map file is just a series
415    of lines with two tokens on each line.  The first token is the name
416    to map, and the second token is the actual name to use.  */
417
418 struct file_name_map
419 {
420   struct file_name_map *map_next;
421   char *map_from;
422   char *map_to;
423 };
424
425 #define FILE_NAME_MAP_FILE "header.gcc"
426
427 /* Read a space delimited string of unlimited length from a stdio
428    file.  */
429
430 static char *
431 read_filename_string (ch, f)
432      int ch;
433      FILE *f;
434 {
435   char *alloc, *set;
436   int len;
437
438   len = 20;
439   set = alloc = xmalloc (len + 1);
440   if (! is_space[ch])
441     {
442       *set++ = ch;
443       while ((ch = getc (f)) != EOF && ! is_space[ch])
444         {
445           if (set - alloc == len)
446             {
447               len *= 2;
448               alloc = xrealloc (alloc, len + 1);
449               set = alloc + len / 2;
450             }
451           *set++ = ch;
452         }
453     }
454   *set = '\0';
455   ungetc (ch, f);
456   return alloc;
457 }
458
459 /* This structure holds a linked list of file name maps, one per directory.  */
460
461 struct file_name_map_list
462 {
463   struct file_name_map_list *map_list_next;
464   char *map_list_name;
465   struct file_name_map *map_list_map;
466 };
467
468 /* Read the file name map file for DIRNAME.  */
469
470 static struct file_name_map *
471 read_name_map (pfile, dirname)
472      cpp_reader *pfile;
473      const char *dirname;
474 {
475   register struct file_name_map_list *map_list_ptr;
476   char *name;
477   FILE *f;
478
479   for (map_list_ptr = CPP_OPTIONS (pfile)->map_list; map_list_ptr;
480        map_list_ptr = map_list_ptr->map_list_next)
481     if (! strcmp (map_list_ptr->map_list_name, dirname))
482       return map_list_ptr->map_list_map;
483
484   map_list_ptr = ((struct file_name_map_list *)
485                   xmalloc (sizeof (struct file_name_map_list)));
486   map_list_ptr->map_list_name = xstrdup (dirname);
487
488   name = (char *) alloca (strlen (dirname) + strlen (FILE_NAME_MAP_FILE) + 2);
489   strcpy (name, dirname);
490   if (*dirname)
491     strcat (name, "/");
492   strcat (name, FILE_NAME_MAP_FILE);
493   f = fopen (name, "r");
494   if (!f)
495     map_list_ptr->map_list_map = (struct file_name_map *)-1;
496   else
497     {
498       int ch;
499       int dirlen = strlen (dirname);
500
501       while ((ch = getc (f)) != EOF)
502         {
503           char *from, *to;
504           struct file_name_map *ptr;
505
506           if (is_space[ch])
507             continue;
508           from = read_filename_string (ch, f);
509           while ((ch = getc (f)) != EOF && is_hor_space[ch])
510             ;
511           to = read_filename_string (ch, f);
512
513           ptr = ((struct file_name_map *)
514                  xmalloc (sizeof (struct file_name_map)));
515           ptr->map_from = from;
516
517           /* Make the real filename absolute.  */
518           if (*to == '/')
519             ptr->map_to = to;
520           else
521             {
522               ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
523               strcpy (ptr->map_to, dirname);
524               ptr->map_to[dirlen] = '/';
525               strcpy (ptr->map_to + dirlen + 1, to);
526               free (to);
527             }         
528
529           ptr->map_next = map_list_ptr->map_list_map;
530           map_list_ptr->map_list_map = ptr;
531
532           while ((ch = getc (f)) != '\n')
533             if (ch == EOF)
534               break;
535         }
536       fclose (f);
537     }
538   
539   map_list_ptr->map_list_next = CPP_OPTIONS (pfile)->map_list;
540   CPP_OPTIONS (pfile)->map_list = map_list_ptr;
541
542   return map_list_ptr->map_list_map;
543 }  
544
545 /* Remap NAME based on the file_name_map (if any) for LOC. */
546
547 static char *
548 remap_filename (pfile, name, loc)
549      cpp_reader *pfile;
550      char *name;
551      struct file_name_list *loc;
552 {
553   struct file_name_map *map;
554   const char *from, *p, *dir;
555
556   if (! loc->name_map)
557     loc->name_map = read_name_map (pfile,
558                                    loc->name
559                                    ? loc->name : ".");
560
561   if (loc->name_map == (struct file_name_map *)-1)
562     return name;
563   
564   from = name + strlen (loc->name) + 1;
565   
566   for (map = loc->name_map; map; map = map->map_next)
567     if (!strcmp (map->map_from, from))
568       return map->map_to;
569
570   /* Try to find a mapping file for the particular directory we are
571      looking in.  Thus #include <sys/types.h> will look up sys/types.h
572      in /usr/include/header.gcc and look up types.h in
573      /usr/include/sys/header.gcc.  */
574   p = rindex (name, '/');
575   if (!p)
576     p = name;
577   if (loc && loc->name
578       && strlen (loc->name) == (size_t) (p - name)
579       && !strncmp (loc->name, name, p - name))
580     /* FILENAME is in SEARCHPTR, which we've already checked.  */
581     return name;
582
583   if (p == name)
584     {
585       dir = ".";
586       from = name;
587     }
588   else
589     {
590       char * newdir = (char *) alloca (p - name + 1);
591       bcopy (name, newdir, p - name);
592       newdir[p - name] = '\0';
593       dir = newdir;
594       from = p + 1;
595     }
596   
597   for (map = read_name_map (pfile, dir); map; map = map->map_next)
598     if (! strcmp (map->map_from, name))
599       return map->map_to;
600
601   return name;
602 }
603
604 /* Read the contents of FD into the buffer on the top of PFILE's stack.
605    IHASH points to the include hash entry for the file associated with
606    FD.
607
608    The caller is responsible for the cpp_push_buffer.  */
609
610 int
611 finclude (pfile, fd, ihash)
612      cpp_reader *pfile;
613      int fd;
614      struct include_hash *ihash;
615 {
616   struct stat st;
617   size_t st_size;
618   long length;
619   cpp_buffer *fp;
620
621   if (fstat (fd, &st) < 0)
622     goto perror_fail;
623   if (fcntl (fd, F_SETFL, 0) == -1)  /* turn off nonblocking mode */
624     goto perror_fail;
625
626   fp = CPP_BUFFER (pfile);
627
628   /* If fd points to a plain file, we know how big it is, so we can
629      allocate the buffer all at once.  If fd is a pipe or terminal, we
630      can't.  Most C source files are 4k or less, so we guess that.  If
631      fd is something weird, like a block device or a directory, we
632      don't want to read it at all.
633
634      Unfortunately, different systems use different st.st_mode values
635      for pipes: some have S_ISFIFO, some S_ISSOCK, some are buggy and
636      zero the entire struct stat except a couple fields.  Hence the
637      mess below.
638
639      In all cases, read_and_prescan will resize the buffer if it
640      turns out there's more data than we thought.  */
641
642   if (S_ISREG (st.st_mode))
643     {
644       /* off_t might have a wider range than size_t - in other words,
645          the max size of a file might be bigger than the address
646          space.  We can't handle a file that large.  (Anyone with
647          a single source file bigger than 4GB needs to rethink
648          their coding style.)  */
649       st_size = (size_t) st.st_size;
650       if ((unsigned HOST_WIDEST_INT) st_size
651           != (unsigned HOST_WIDEST_INT) st.st_size)
652         {
653           cpp_error (pfile, "file `%s' is too large", ihash->name);
654           goto fail;
655         }
656     }
657   else if (S_ISFIFO (st.st_mode) || S_ISSOCK (st.st_mode)
658            /* Permit any kind of character device: the sensible ones are
659               ttys and /dev/null, but weeding out the others is too hard.  */
660            || S_ISCHR (st.st_mode)
661            /* Some 4.x (x<4) derivatives have a bug that makes fstat() of a
662               socket or pipe return a stat struct with most fields zeroed.  */
663            || (st.st_mode == 0 && st.st_nlink == 0 && st.st_size == 0))
664     {
665       /* Cannot get its file size before reading.  4k is a decent
666          first guess. */
667       st_size = 4096;
668     }
669   else
670     {
671       cpp_error (pfile, "`%s' is not a file, pipe, or tty", ihash->name);
672       goto fail;
673     }
674
675   if (pfile->input_buffer == NULL)
676     initialize_input_buffer (pfile, fd, &st);
677
678   /* Read the file, converting end-of-line characters and trigraphs
679      (if enabled). */
680   fp->ihash = ihash;
681   fp->nominal_fname = fp->fname = ihash->name;
682   length = read_and_prescan (pfile, fp, fd, st_size);
683   if (length < 0)
684     goto fail;
685   if (length == 0)
686     ihash->control_macro = "";  /* never re-include */
687
688   close (fd);
689   fp->rlimit = fp->alimit = fp->buf + length;
690   fp->cur = fp->buf;
691   if (ihash->foundhere != ABSOLUTE_PATH)
692       fp->system_header_p = ihash->foundhere->sysp;
693   fp->lineno = 1;
694   fp->colno = 1;
695   fp->line_base = fp->buf;
696   fp->cleanup = file_cleanup;
697
698   /* The ->actual_dir field is only used when ignore_srcdir is not in effect;
699      see do_include */
700   if (!CPP_OPTIONS (pfile)->ignore_srcdir)
701     fp->actual_dir = actual_directory (pfile, fp->fname);
702
703   pfile->input_stack_listing_current = 0;
704   return 1;
705
706  perror_fail:
707   cpp_error_from_errno (pfile, ihash->name);
708  fail:
709   cpp_pop_buffer (pfile);
710   close (fd);
711   return 0;
712 }
713
714 /* Given a path FNAME, extract the directory component and place it
715    onto the actual_dirs list.  Return a pointer to the allocated
716    file_name_list structure.  These structures are used to implement
717    current-directory "" include searching. */
718
719 static struct file_name_list *
720 actual_directory (pfile, fname)
721      cpp_reader *pfile;
722      const char *fname;
723 {
724   char *last_slash, *dir;
725   size_t dlen;
726   struct file_name_list *x;
727   
728   dir = xstrdup (fname);
729   last_slash = rindex (dir, '/');
730   if (last_slash)
731     {
732       if (last_slash == dir)
733         {
734           dlen = 1;
735           last_slash[1] = '\0';
736         }
737       else
738         {
739           dlen = last_slash - dir;
740           *last_slash = '\0';
741         }
742     }
743   else
744     {
745       dir[0] = '.';
746       dir[1] = '\0';
747       dlen = 1;
748     }
749
750   if (dlen > pfile->max_include_len)
751     pfile->max_include_len = dlen;
752
753   for (x = pfile->actual_dirs; x; x = x->alloc)
754     if (!strcmp (x->name, dir))
755       {
756         free (dir);
757         return x;
758       }
759
760   /* Not found, make a new one. */
761   x = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
762   x->name = dir;
763   x->nlen = dlen;
764   x->next = CPP_OPTIONS (pfile)->quote_include;
765   x->alloc = pfile->actual_dirs;
766   x->sysp = CPP_BUFFER (pfile)->system_header_p;
767   x->name_map = NULL;
768
769   pfile->actual_dirs = x;
770   return x;
771 }
772
773 /* Determine the current line and column.  Used only by read_and_prescan. */
774 static void
775 find_position (start, limit, linep, colp)
776      U_CHAR *start;
777      U_CHAR *limit;
778      unsigned long *linep;
779      unsigned long *colp;
780 {
781   unsigned long line = *linep, col = 0;
782   while (start < limit)
783     {
784       U_CHAR ch = *start++;
785       if (ch == '\n' || ch == '\r')
786         line++, col = 1;
787       else
788         col++;
789     }
790   *linep = line, *colp = col;
791 }
792
793 /* Read the entire contents of file DESC into buffer BUF.  LEN is how
794    much memory to allocate initially; more will be allocated if
795    necessary.  Convert end-of-line markers (\n, \r, \r\n, \n\r) to
796    canonical form (\n).  If enabled, convert and/or warn about
797    trigraphs.  Convert backslash-newline to a one-character escape
798    (\r) and remove it from "embarrassing" places (i.e. the middle of a
799    token).  If there is no newline at the end of the file, add one and
800    warn.  Returns -1 on failure, or the actual length of the data to
801    be scanned.
802
803    This function does a lot of work, and can be a serious performance
804    bottleneck.  It has been tuned heavily; make sure you understand it
805    before hacking.  The common case - no trigraphs, Unix style line
806    breaks, backslash-newline set off by whitespace, newline at EOF -
807    has been optimized at the expense of the others.  The performance
808    penalty for DOS style line breaks (\r\n) is about 15%.
809    
810    Warnings lose particularly heavily since we have to determine the
811    line number, which involves scanning from the beginning of the file
812    or from the last warning.  The penalty for the absence of a newline
813    at the end of reload1.c is about 60%.  (reload1.c is 329k.)
814
815    If your file has more than one kind of end-of-line marker, you
816    will get messed-up line numbering.  */
817
818 /* Table of characters that can't be handled in the inner loop.
819    Keep these contiguous to optimize the performance of the code generated
820    for the switch that uses them.  */
821 #define SPECCASE_EMPTY     0
822 #define SPECCASE_NUL       1
823 #define SPECCASE_CR        2
824 #define SPECCASE_BACKSLASH 3
825 #define SPECCASE_QUESTION  4
826
827 static long
828 read_and_prescan (pfile, fp, desc, len)
829      cpp_reader *pfile;
830      cpp_buffer *fp;
831      int desc;
832      size_t len;
833 {
834   U_CHAR *buf = (U_CHAR *) xmalloc (len);
835   U_CHAR *ip, *op, *line_base;
836   U_CHAR *ibase;
837   U_CHAR *speccase = pfile->input_speccase;
838   unsigned long line;
839   unsigned int deferred_newlines;
840   int count;
841   size_t offset;
842
843   offset = 0;
844   op = buf;
845   line_base = buf;
846   line = 1;
847   ibase = pfile->input_buffer + 2;
848   deferred_newlines = 0;
849
850   for (;;)
851     {
852     read_next:
853
854       count = read (desc, pfile->input_buffer + 2, pfile->input_buffer_len);
855       if (count < 0)
856         goto error;
857       else if (count == 0)
858         break;
859
860       offset += count;
861       ip = ibase;
862       ibase = pfile->input_buffer + 2;
863       ibase[count] = ibase[count+1] = '\0';
864
865       if (offset > len)
866         {
867           size_t delta_op;
868           size_t delta_line_base;
869           len *= 2;
870           if (offset > len)
871             /* len overflowed.
872                This could happen if the file is larger than half the
873                maximum address space of the machine. */
874             goto too_big;
875
876           delta_op = op - buf;
877           delta_line_base = line_base - buf;
878           buf = (U_CHAR *) xrealloc (buf, len);
879           op = buf + delta_op;
880           line_base = buf + delta_line_base;
881         }
882
883       for (;;)
884         {
885           unsigned int span = 0;
886
887           /* Deal with \-newline in the middle of a token. */
888           if (deferred_newlines)
889             {
890               while (speccase[ip[span]] == SPECCASE_EMPTY
891                      && ip[span] != '\n'
892                      && ip[span] != '\t'
893                      && ip[span] != ' ')
894                 span++;
895               memcpy (op, ip, span);
896               op += span;
897               ip += span;
898               if (*ip == '\n' || *ip == '\t'
899                   || *ip == ' ' || *ip == ' ')
900                 while (deferred_newlines)
901                   deferred_newlines--, *op++ = '\r';
902               span = 0;
903             }
904
905           /* Copy as much as we can without special treatment. */
906           while (speccase[ip[span]] == SPECCASE_EMPTY) span++;
907           memcpy (op, ip, span);
908           op += span;
909           ip += span;
910
911           switch (speccase[*ip++])
912             {
913             case SPECCASE_NUL:  /* \0 */
914               ibase[-1] = op[-1];
915               goto read_next;
916
917             case SPECCASE_CR:  /* \r */
918               if (*ip == '\n')
919                 ip++;
920               else if (*ip == '\0')
921                 {
922                   *--ibase = '\r';
923                   goto read_next;
924                 }
925               else if (ip[-2] == '\n')
926                 continue;
927               *op++ = '\n';
928               break;
929
930             case SPECCASE_BACKSLASH:  /* \ */
931             backslash:
932             {
933               /* If we're at the end of the intermediate buffer,
934                  we have to shift the backslash down to the start
935                  and come back next pass. */
936               if (*ip == '\0')
937                 {
938                   *--ibase = '\\';
939                   goto read_next;
940                 }
941               else if (*ip == '\n')
942                 {
943                   ip++;
944                   if (*ip == '\r') ip++;
945                   if (*ip == '\n' || *ip == '\t' || *ip == ' ')
946                     *op++ = '\r';
947                   else if (op[-1] == '\t' || op[-1] == ' '
948                            || op[-1] == '\r' || op[-1] == '\n')
949                     *op++ = '\r';
950                   else
951                     deferred_newlines++;
952                   line++;
953                   line_base = op;
954                 }
955               else if (*ip == '\r')
956                 {
957                   ip++;
958                   if (*ip == '\n') ip++;
959                   else if (*ip == '\0')
960                     {
961                       *--ibase = '\r';
962                       *--ibase = '\\';
963                       goto read_next;
964                     }
965                   else if (*ip == '\r' || *ip == '\t' || *ip == ' ')
966                     *op++ = '\r';
967                   else
968                     deferred_newlines++;
969                   line++;
970                   line_base = op;
971                 }
972               else
973                 *op++ = '\\';
974             }
975             break;
976
977             case SPECCASE_QUESTION: /* ? */
978               {
979                 unsigned int d;
980                 /* If we're at the end of the intermediate buffer,
981                    we have to shift the ?'s down to the start and
982                    come back next pass. */
983                 d = ip[0];
984                 if (d == '\0')
985                   {
986                     *--ibase = '?';
987                     goto read_next;
988                   }
989                 if (d != '?')
990                   {
991                     *op++ = '?';
992                     break;
993                   }
994                 d = ip[1];
995                 if (d == '\0')
996                   {
997                     *--ibase = '?';
998                     *--ibase = '?';
999                     goto read_next;
1000                   }
1001                 if (!trigraph_table[d])
1002                   {
1003                     *op++ = '?';
1004                     break;
1005                   }
1006
1007                 if (CPP_OPTIONS (pfile)->warn_trigraphs)
1008                   {
1009                     unsigned long col;
1010                     find_position (line_base, op, &line, &col);
1011                     line_base = op - col;
1012                     cpp_warning_with_line (pfile, line, col,
1013                                            "trigraph ??%c encountered", d);
1014                   }
1015                 if (CPP_OPTIONS (pfile)->trigraphs)
1016                   {
1017                     if (trigraph_table[d] == '\\')
1018                       goto backslash;
1019                     else
1020                       *op++ = trigraph_table[d];
1021                   }
1022                 else
1023                   {
1024                     *op++ = '?';
1025                     *op++ = '?';
1026                     *op++ = d;
1027                   }
1028                 ip += 2;
1029               }
1030             }
1031         }
1032     }
1033
1034   if (offset == 0)
1035     return 0;
1036
1037   /* Deal with pushed-back chars at true EOF.
1038      This may be any of:  ?? ? \ \r \n \\r \\n.
1039      \r must become \n, \\r or \\n must become \r.
1040      We know we have space already. */
1041   if (ibase == pfile->input_buffer)
1042     {
1043       if (*ibase == '?')
1044         {
1045           *op++ = '?';
1046           *op++ = '?';
1047         }
1048       else
1049         *op++ = '\r';
1050     }
1051   else if (ibase == pfile->input_buffer + 1)
1052     {
1053       if (*ibase == '\r')
1054         *op++ = '\n';
1055       else
1056         *op++ = *ibase;
1057     }
1058
1059   if (op[-1] != '\n')
1060     {
1061       unsigned long col;
1062       find_position (line_base, op, &line, &col);
1063       cpp_warning_with_line (pfile, line, col, "no newline at end of file\n");
1064       if (offset + 1 > len)
1065         {
1066           len += 1;
1067           if (offset + 1 > len)
1068             goto too_big;
1069           buf = (U_CHAR *) xrealloc (buf, len);
1070           op = buf + offset;
1071         }
1072       *op++ = '\n';
1073     }
1074
1075   fp->buf = ((len - offset < 20) ? buf : (U_CHAR *)xrealloc (buf, op - buf));
1076   return op - buf;
1077
1078  too_big:
1079   cpp_error (pfile, "file is too large (>%lu bytes)\n", (unsigned long)offset);
1080   free (buf);
1081   return -1;
1082
1083  error:
1084   cpp_error_from_errno (pfile, fp->fname);
1085   free (buf);
1086   return -1;
1087 }
1088
1089 /* Initialize the `input_buffer' and `input_speccase' tables.
1090    These are only used by read_and_prescan, but they're large and
1091    somewhat expensive to set up, so we want them allocated once for
1092    the duration of the cpp run.  */
1093
1094 static void
1095 initialize_input_buffer (pfile, fd, st)
1096      cpp_reader *pfile;
1097      int fd;
1098      struct stat *st;
1099 {
1100   long pipe_buf;
1101   U_CHAR *tmp;
1102
1103   /* Table of characters that cannot be handled by the
1104      read_and_prescan inner loop.  The number of non-EMPTY entries
1105      should be as small as humanly possible.  */
1106
1107   tmp = (U_CHAR *) xmalloc (1 << CHAR_BIT);
1108   memset (tmp, SPECCASE_EMPTY, 1 << CHAR_BIT);
1109   tmp['\0'] = SPECCASE_NUL;
1110   tmp['\r'] = SPECCASE_CR;
1111   tmp['\\'] = SPECCASE_BACKSLASH;
1112   if (CPP_OPTIONS (pfile)->trigraphs || CPP_OPTIONS (pfile)->warn_trigraphs)
1113     tmp['?'] = SPECCASE_QUESTION;
1114
1115   pfile->input_speccase = tmp;
1116
1117   /* Determine the appropriate size for the input buffer.  Normal C
1118      source files are smaller than eight K.  If we are reading a pipe,
1119      we want to make sure the input buffer is bigger than the kernel's
1120      pipe buffer.  */
1121   pipe_buf = -1;
1122
1123   if (! S_ISREG (st->st_mode))
1124     {
1125 #ifdef _PC_PIPE_BUF
1126       pipe_buf = fpathconf (fd, _PC_PIPE_BUF);
1127 #endif
1128       if (pipe_buf == -1)
1129         {
1130 #ifdef PIPE_BUF
1131           pipe_buf = PIPE_BUF;
1132 #else
1133           pipe_buf = 8192;
1134 #endif
1135         }
1136     }
1137
1138   if (pipe_buf < 8192)
1139     pipe_buf = 8192;
1140   /* PIPE_BUF bytes of buffer proper, 2 to detect running off the end
1141      without address arithmetic all the time, and 2 for pushback in
1142      the case there's a potential trigraph or end-of-line digraph at
1143      the end of a block. */
1144
1145   tmp = (U_CHAR *) xmalloc (pipe_buf + 2 + 2);
1146   pfile->input_buffer = tmp;
1147   pfile->input_buffer_len = pipe_buf;
1148 }
1149
1150 /* Add output to `deps_buffer' for the -M switch.
1151    STRING points to the text to be output.
1152    SPACER is ':' for targets, ' ' for dependencies, zero for text
1153    to be inserted literally.  */
1154
1155 void
1156 deps_output (pfile, string, spacer)
1157      cpp_reader *pfile;
1158      const char *string;
1159      int spacer;
1160 {
1161   int size;
1162   int cr = 0;
1163
1164   if (!*string)
1165     return;
1166
1167   size = strlen (string);
1168
1169 #ifndef MAX_OUTPUT_COLUMNS
1170 #define MAX_OUTPUT_COLUMNS 72
1171 #endif
1172   if (pfile->deps_column > 0
1173       && (pfile->deps_column + size) > MAX_OUTPUT_COLUMNS)
1174     {
1175       cr = 5;
1176       pfile->deps_column = 0;
1177     }
1178
1179   if (pfile->deps_size + size + cr + 8 > pfile->deps_allocated_size)
1180     {
1181       pfile->deps_allocated_size = (pfile->deps_size + size + 50) * 2;
1182       pfile->deps_buffer = (char *) xrealloc (pfile->deps_buffer,
1183                                               pfile->deps_allocated_size);
1184     }
1185
1186   if (cr)
1187     {
1188       bcopy (" \\\n  ", &pfile->deps_buffer[pfile->deps_size], 5);
1189       pfile->deps_size += 5;
1190     }
1191   
1192   if (spacer == ' ' && pfile->deps_column > 0)
1193     pfile->deps_buffer[pfile->deps_size++] = ' ';
1194   bcopy (string, &pfile->deps_buffer[pfile->deps_size], size);
1195   pfile->deps_size += size;
1196   pfile->deps_column += size;
1197   if (spacer == ':')
1198     pfile->deps_buffer[pfile->deps_size++] = ':';
1199   pfile->deps_buffer[pfile->deps_size] = 0;
1200 }
1201
1202 /* Simplify a path name in place, deleting redundant components.  This
1203    reduces OS overhead and guarantees that equivalent paths compare
1204    the same (modulo symlinks).
1205
1206    Transforms made:
1207    foo/bar/../quux      foo/quux
1208    foo/./bar            foo/bar
1209    foo//bar             foo/bar
1210    /../quux             /quux
1211    //quux               //quux  (POSIX allows leading // as a namespace escape)
1212
1213    Guarantees no trailing slashes. All transforms reduce the length
1214    of the string.
1215  */
1216 void
1217 simplify_pathname (path)
1218     char *path;
1219 {
1220     char *from, *to;
1221     char *base;
1222     int absolute = 0;
1223
1224 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
1225     /* Convert all backslashes to slashes. */
1226     for (from = path; *from; from++)
1227         if (*from == '\\') *from = '/';
1228     
1229     /* Skip over leading drive letter if present. */
1230     if (ISALPHA (path[0]) && path[1] == ':')
1231         from = to = &path[2];
1232     else
1233         from = to = path;
1234 #else
1235     from = to = path;
1236 #endif
1237     
1238     /* Remove redundant initial /s.  */
1239     if (*from == '/')
1240     {
1241         absolute = 1;
1242         to++;
1243         from++;
1244         if (*from == '/')
1245         {
1246             if (*++from == '/')
1247                 /* 3 or more initial /s are equivalent to 1 /.  */
1248                 while (*++from == '/');
1249             else
1250                 /* On some hosts // differs from /; Posix allows this.  */
1251                 to++;
1252         }
1253     }
1254     base = to;
1255     
1256     for (;;)
1257     {
1258         while (*from == '/')
1259             from++;
1260
1261         if (from[0] == '.' && from[1] == '/')
1262             from += 2;
1263         else if (from[0] == '.' && from[1] == '\0')
1264             goto done;
1265         else if (from[0] == '.' && from[1] == '.' && from[2] == '/')
1266         {
1267             if (base == to)
1268             {
1269                 if (absolute)
1270                     from += 3;
1271                 else
1272                 {
1273                     *to++ = *from++;
1274                     *to++ = *from++;
1275                     *to++ = *from++;
1276                     base = to;
1277                 }
1278             }
1279             else
1280             {
1281                 to -= 2;
1282                 while (to > base && *to != '/') to--;
1283                 if (*to == '/')
1284                     to++;
1285                 from += 3;
1286             }
1287         }
1288         else if (from[0] == '.' && from[1] == '.' && from[2] == '\0')
1289         {
1290             if (base == to)
1291             {
1292                 if (!absolute)
1293                 {
1294                     *to++ = *from++;
1295                     *to++ = *from++;
1296                 }
1297             }
1298             else
1299             {
1300                 to -= 2;
1301                 while (to > base && *to != '/') to--;
1302                 if (*to == '/')
1303                     to++;
1304             }
1305             goto done;
1306         }
1307         else
1308             /* Copy this component and trailing /, if any.  */
1309             while ((*to++ = *from++) != '/')
1310             {
1311                 if (!to[-1])
1312                 {
1313                     to--;
1314                     goto done;
1315                 }
1316             }
1317         
1318     }
1319     
1320  done:
1321     /* Trim trailing slash */
1322     if (to[0] == '/' && (!absolute || to > path+1))
1323         to--;
1324
1325     /* Change the empty string to "." so that stat() on the result
1326        will always work. */
1327     if (to == path)
1328       *to++ = '.';
1329     
1330     *to = '\0';
1331
1332     return;
1333 }
1334
1335 /* It is not clear when this should be used if at all, so I've
1336    disabled it until someone who understands VMS can look at it. */
1337 #if 0
1338
1339 /* Under VMS we need to fix up the "include" specification filename.
1340
1341    Rules for possible conversions
1342
1343         fullname                tried paths
1344
1345         name                    name
1346         ./dir/name              [.dir]name
1347         /dir/name               dir:name
1348         /name                   [000000]name, name
1349         dir/name                dir:[000000]name, dir:name, dir/name
1350         dir1/dir2/name          dir1:[dir2]name, dir1:[000000.dir2]name
1351         path:/name              path:[000000]name, path:name
1352         path:/dir/name          path:[000000.dir]name, path:[dir]name
1353         path:dir/name           path:[dir]name
1354         [path]:[dir]name        [path.dir]name
1355         path/[dir]name          [path.dir]name
1356
1357    The path:/name input is constructed when expanding <> includes. */
1358
1359
1360 static void
1361 hack_vms_include_specification (fullname)
1362      char *fullname;
1363 {
1364   register char *basename, *unixname, *local_ptr, *first_slash;
1365   int f, check_filename_before_returning, must_revert;
1366   char Local[512];
1367
1368   check_filename_before_returning = 0;
1369   must_revert = 0;
1370   /* See if we can find a 1st slash. If not, there's no path information.  */
1371   first_slash = index (fullname, '/');
1372   if (first_slash == 0)
1373     return 0;                           /* Nothing to do!!! */
1374
1375   /* construct device spec if none given.  */
1376
1377   if (index (fullname, ':') == 0)
1378     {
1379
1380       /* If fullname has a slash, take it as device spec.  */
1381
1382       if (first_slash == fullname)
1383         {
1384           first_slash = index (fullname+1, '/');        /* 2nd slash ? */
1385           if (first_slash)
1386             *first_slash = ':';                         /* make device spec  */
1387           for (basename = fullname; *basename != 0; basename++)
1388             *basename = *(basename+1);                  /* remove leading slash  */
1389         }
1390       else if ((first_slash[-1] != '.')         /* keep ':/', './' */
1391             && (first_slash[-1] != ':')
1392             && (first_slash[-1] != ']'))        /* or a vms path  */
1393         {
1394           *first_slash = ':';
1395         }
1396       else if ((first_slash[1] == '[')          /* skip './' in './[dir'  */
1397             && (first_slash[-1] == '.'))
1398         fullname += 2;
1399     }
1400
1401   /* Get part after first ':' (basename[-1] == ':')
1402      or last '/' (basename[-1] == '/').  */
1403
1404   basename = base_name (fullname);
1405
1406   local_ptr = Local;                    /* initialize */
1407
1408   /* We are trying to do a number of things here.  First of all, we are
1409      trying to hammer the filenames into a standard format, such that later
1410      processing can handle them.
1411      
1412      If the file name contains something like [dir.], then it recognizes this
1413      as a root, and strips the ".]".  Later processing will add whatever is
1414      needed to get things working properly.
1415      
1416      If no device is specified, then the first directory name is taken to be
1417      a device name (or a rooted logical).  */
1418
1419   /* Point to the UNIX filename part (which needs to be fixed!)
1420      but skip vms path information.
1421      [basename != fullname since first_slash != 0].  */
1422
1423   if ((basename[-1] == ':')             /* vms path spec.  */
1424       || (basename[-1] == ']')
1425       || (basename[-1] == '>'))
1426     unixname = basename;
1427   else
1428     unixname = fullname;
1429
1430   if (*unixname == '/')
1431     unixname++;
1432
1433   /* If the directory spec is not rooted, we can just copy
1434      the UNIX filename part and we are done.  */
1435
1436   if (((basename - fullname) > 1)
1437      && (  (basename[-1] == ']')
1438         || (basename[-1] == '>')))
1439     {
1440       if (basename[-2] != '.')
1441         {
1442
1443         /* The VMS part ends in a `]', and the preceding character is not a `.'.
1444            -> PATH]:/name (basename = '/name', unixname = 'name')
1445            We strip the `]', and then splice the two parts of the name in the
1446            usual way.  Given the default locations for include files in cccp.c,
1447            we will only use this code if the user specifies alternate locations
1448            with the /include (-I) switch on the command line.  */
1449
1450           basename -= 1;        /* Strip "]" */
1451           unixname--;           /* backspace */
1452         }
1453       else
1454         {
1455
1456         /* The VMS part has a ".]" at the end, and this will not do.  Later
1457            processing will add a second directory spec, and this would be a syntax
1458            error.  Thus we strip the ".]", and thus merge the directory specs.
1459            We also backspace unixname, so that it points to a '/'.  This inhibits the
1460            generation of the 000000 root directory spec (which does not belong here
1461            in this case).  */
1462
1463           basename -= 2;        /* Strip ".]" */
1464           unixname--;           /* backspace */
1465         }
1466     }
1467
1468   else
1469
1470     {
1471
1472       /* We drop in here if there is no VMS style directory specification yet.
1473          If there is no device specification either, we make the first dir a
1474          device and try that.  If we do not do this, then we will be essentially
1475          searching the users default directory (as if they did a #include "asdf.h").
1476         
1477          Then all we need to do is to push a '[' into the output string. Later
1478          processing will fill this in, and close the bracket.  */
1479
1480       if ((unixname != fullname)        /* vms path spec found.  */
1481          && (basename[-1] != ':'))
1482         *local_ptr++ = ':';             /* dev not in spec.  take first dir */
1483
1484       *local_ptr++ = '[';               /* Open the directory specification */
1485     }
1486
1487     if (unixname == fullname)           /* no vms dir spec.  */
1488       {
1489         must_revert = 1;
1490         if ((first_slash != 0)          /* unix dir spec.  */
1491             && (*unixname != '/')       /* not beginning with '/'  */
1492             && (*unixname != '.'))      /* or './' or '../'  */
1493           *local_ptr++ = '.';           /* dir is local !  */
1494       }
1495
1496   /* at this point we assume that we have the device spec, and (at least
1497      the opening "[" for a directory specification.  We may have directories
1498      specified already.
1499
1500      If there are no other slashes then the filename will be
1501      in the "root" directory.  Otherwise, we need to add
1502      directory specifications.  */
1503
1504   if (index (unixname, '/') == 0)
1505     {
1506       /* if no directories specified yet and none are following.  */
1507       if (local_ptr[-1] == '[')
1508         {
1509           /* Just add "000000]" as the directory string */
1510           strcpy (local_ptr, "000000]");
1511           local_ptr += strlen (local_ptr);
1512           check_filename_before_returning = 1; /* we might need to fool with this later */
1513         }
1514     }
1515   else
1516     {
1517
1518       /* As long as there are still subdirectories to add, do them.  */
1519       while (index (unixname, '/') != 0)
1520         {
1521           /* If this token is "." we can ignore it
1522                if it's not at the beginning of a path.  */
1523           if ((unixname[0] == '.') && (unixname[1] == '/'))
1524             {
1525               /* remove it at beginning of path.  */
1526               if (  ((unixname == fullname)             /* no device spec  */
1527                     && (fullname+2 != basename))        /* starts with ./ */
1528                                                         /* or  */
1529                  || ((basename[-1] == ':')              /* device spec  */
1530                     && (unixname-1 == basename)))       /* and ./ afterwards  */
1531                 *local_ptr++ = '.';                     /* make '[.' start of path.  */
1532               unixname += 2;
1533               continue;
1534             }
1535
1536           /* Add a subdirectory spec. Do not duplicate "." */
1537           if (  local_ptr[-1] != '.'
1538              && local_ptr[-1] != '['
1539              && local_ptr[-1] != '<')
1540             *local_ptr++ = '.';
1541
1542           /* If this is ".." then the spec becomes "-" */
1543           if (  (unixname[0] == '.')
1544              && (unixname[1] == '.')
1545              && (unixname[2] == '/'))
1546             {
1547               /* Add "-" and skip the ".." */
1548               if ((local_ptr[-1] == '.')
1549                   && (local_ptr[-2] == '['))
1550                 local_ptr--;                    /* prevent [.-  */
1551               *local_ptr++ = '-';
1552               unixname += 3;
1553               continue;
1554             }
1555
1556           /* Copy the subdirectory */
1557           while (*unixname != '/')
1558             *local_ptr++= *unixname++;
1559
1560           unixname++;                   /* Skip the "/" */
1561         }
1562
1563       /* Close the directory specification */
1564       if (local_ptr[-1] == '.')         /* no trailing periods */
1565         local_ptr--;
1566
1567       if (local_ptr[-1] == '[')         /* no dir needed */
1568         local_ptr--;
1569       else
1570         *local_ptr++ = ']';
1571     }
1572
1573   /* Now add the filename.  */
1574
1575   while (*unixname)
1576     *local_ptr++ = *unixname++;
1577   *local_ptr = 0;
1578
1579   /* Now append it to the original VMS spec.  */
1580
1581   strcpy ((must_revert==1)?fullname:basename, Local);
1582
1583   /* If we put a [000000] in the filename, try to open it first. If this fails,
1584      remove the [000000], and return that name.  This provides flexibility
1585      to the user in that they can use both rooted and non-rooted logical names
1586      to point to the location of the file.  */
1587
1588   if (check_filename_before_returning)
1589     {
1590       f = open (fullname, O_RDONLY, 0666);
1591       if (f >= 0)
1592         {
1593           /* The file name is OK as it is, so return it as is.  */
1594           close (f);
1595           return 1;
1596         }
1597
1598       /* The filename did not work.  Try to remove the [000000] from the name,
1599          and return it.  */
1600
1601       basename = index (fullname, '[');
1602       local_ptr = index (fullname, ']') + 1;
1603       strcpy (basename, local_ptr);             /* this gets rid of it */
1604
1605     }
1606
1607   return 1;
1608 }
1609 #endif  /* VMS */