OSDN Git Service

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