OSDN Git Service

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