OSDN Git Service

Fix copyright dates.
[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 safe_read                   PROTO ((int, char *, int));
45 static void simplify_pathname           PROTO ((char *));
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 __MSDOS__
57 #define INO_T_EQ(a, b) 0
58 #else
59 #define INO_T_EQ(a, b) ((a) == (b))
60 #endif
61
62 /* Append an entry for dir DIR to list LIST, simplifying it if
63    possible.  SYS says whether this is a system include directory.
64    *** DIR is modified in place.  It must be writable and permanently
65    allocated. LIST is a pointer to the head pointer, because we actually
66    *prepend* the dir, and reverse the list later (in merge_include_chains). */
67 void
68 append_include_chain (pfile, list, dir, sysp)
69      cpp_reader *pfile;
70      struct file_name_list **list;
71      const char *dir;
72      int sysp;
73 {
74   struct file_name_list *new;
75   struct stat st;
76   unsigned int len;
77   char * newdir = xstrdup (dir);
78
79   simplify_pathname (newdir);
80   if (stat (newdir, &st))
81     {
82       /* Dirs that don't exist are silently ignored. */
83       if (errno != ENOENT)
84         cpp_perror_with_name (pfile, newdir);
85       return;
86     }
87
88   if (!S_ISDIR (st.st_mode))
89     {
90       cpp_message (pfile, 1, "%s: %s: Not a directory", progname, newdir);
91       return;
92     }
93
94   len = strlen(newdir);
95   if (len > pfile->max_include_len)
96     pfile->max_include_len = len;
97   
98   new = (struct file_name_list *)xmalloc (sizeof (struct file_name_list));
99   new->name = newdir;
100   new->nlen = len;
101   new->next = *list;
102   new->ino  = st.st_ino;
103   new->dev  = st.st_dev;
104   new->sysp = sysp;
105   new->name_map = NULL;
106
107   *list = new;
108 }
109
110 /* Merge the four include chains together in the order quote, bracket,
111    system, after.  Remove duplicate dirs (as determined by
112    INO_T_EQ()).  The system_include and after_include chains are never
113    referred to again after this function; all access is through the
114    bracket_include path.
115
116    For the future: Check if the directory is empty (but
117    how?) and possibly preload the include hash. */
118
119 void
120 merge_include_chains (opts)
121      struct cpp_options *opts;
122 {
123   struct file_name_list *prev, *next, *cur, *other;
124   struct file_name_list *quote, *brack, *systm, *after;
125   struct file_name_list *qtail, *btail, *stail, *atail;
126
127   qtail = opts->quote_include;
128   btail = opts->bracket_include;
129   stail = opts->system_include;
130   atail = opts->after_include;
131
132   /* Nreverse the four lists. */
133   prev = 0;
134   for (cur = qtail; cur; cur = next)
135     {
136       next = cur->next;
137       cur->next = prev;
138       prev = cur;
139     }
140   quote = prev;
141
142   prev = 0;
143   for (cur = btail; cur; cur = next)
144     {
145       next = cur->next;
146       cur->next = prev;
147       prev = cur;
148     }
149   brack = prev;
150
151   prev = 0;
152   for (cur = stail; cur; cur = next)
153     {
154       next = cur->next;
155       cur->next = prev;
156       prev = cur;
157     }
158   systm = prev;
159
160   prev = 0;
161   for (cur = atail; cur; cur = next)
162     {
163       next = cur->next;
164       cur->next = prev;
165       prev = cur;
166     }
167   after = prev;
168
169   /* Paste together bracket, system, and after include chains. */
170   if (stail)
171     stail->next = after;
172   else
173     systm = after;
174   if (btail)
175     btail->next = systm;
176   else
177     brack = systm;
178
179   /* This is a bit tricky.
180      First we drop dupes from the quote-include list.
181      Then we drop dupes from the bracket-include list.
182      Finally, if qtail and brack are the same directory,
183      we cut out qtail.
184
185      We can't just merge the lists and then uniquify them because
186      then we may lose directories from the <> search path that should
187      be there; consider -Ifoo -Ibar -I- -Ifoo -Iquux. It is however
188      safe to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written
189      -Ibar -I- -Ifoo -Iquux. */
190
191   for (cur = quote; cur; cur = cur->next)
192     {
193       for (other = quote; other != cur; other = other->next)
194         if (INO_T_EQ (cur->ino, other->ino)
195             && cur->dev == other->dev)
196           {
197             prev->next = cur->next;
198             free (cur->name);
199             free (cur);
200             cur = prev;
201             break;
202           }
203       prev = cur;
204     }
205   qtail = prev;
206
207   for (cur = brack; cur; cur = cur->next)
208     {
209       for (other = brack; other != cur; other = other->next)
210         if (INO_T_EQ (cur->ino, other->ino)
211             && cur->dev == other->dev)
212           {
213             prev->next = cur->next;
214             free (cur->name);
215             free (cur);
216             cur = prev;
217             break;
218           }
219       prev = cur;
220     }
221
222   if (quote)
223     {
224       if (INO_T_EQ (qtail->ino, brack->ino) && qtail->dev == brack->dev)
225         {
226           if (quote == qtail)
227             {
228               free (quote->name);
229               free (quote);
230               quote = brack;
231             }
232           else
233             {
234               cur = quote;
235               while (cur->next != qtail)
236                   cur = cur->next;
237               cur->next = brack;
238               free (qtail->name);
239               free (qtail);
240             }
241         }
242       else
243           qtail->next = brack;
244     }
245   else
246       quote = brack;
247
248   opts->quote_include = quote;
249   opts->bracket_include = brack;
250   opts->system_include = NULL;
251   opts->after_include = NULL;
252 }
253
254 /* Look up or add an entry to the table of all includes.  This table
255  is indexed by the name as it appears in the #include line.  The
256  ->next_this_file chain stores all different files with the same
257  #include name (there are at least three ways this can happen).  The
258  hash function could probably be improved a bit. */
259
260 struct include_hash *
261 include_hash (pfile, fname, add)
262      cpp_reader *pfile;
263      char *fname;
264      int add;
265 {
266   unsigned int hash = 0;
267   struct include_hash *l, *m;
268   char *f = fname;
269
270   while (*f)
271     hash += *f++;
272
273   l = pfile->all_include_files[hash % ALL_INCLUDE_HASHSIZE];
274   m = 0;
275   for (; l; m = l, l = l->next)
276     if (!strcmp (l->nshort, fname))
277       return l;
278
279   if (!add)
280     return 0;
281   
282   l = (struct include_hash *) xmalloc (sizeof (struct include_hash));
283   l->next = NULL;
284   l->next_this_file = NULL;
285   l->foundhere = NULL;
286   l->buf = NULL;
287   l->limit = NULL;
288   if (m)
289     m->next = l;
290   else
291     pfile->all_include_files[hash % ALL_INCLUDE_HASHSIZE] = l;
292   
293   return l;
294 }
295
296 /* Return 0 if the file pointed to by IHASH has never been included before,
297          -1 if it has been included before and need not be again,
298          or a pointer to an IHASH entry which is the file to be reread.
299    "Never before" is with respect to the position in ILIST.
300
301    This will not detect redundancies involving odd uses of the
302    `current directory' rule for "" includes.  They aren't quite
303    pathological, but I think they are rare enough not to worry about.
304    The simplest example is:
305
306    top.c:
307    #include "a/a.h"
308    #include "b/b.h"
309
310    a/a.h:
311    #include "../b/b.h"
312
313    and the problem is that for `current directory' includes,
314    ihash->foundhere is not on any of the global include chains,
315    so the test below (i->foundhere == l) may be false even when
316    the directories are in fact the same.  */
317
318 static struct include_hash *
319 redundant_include_p (pfile, ihash, ilist)
320      cpp_reader *pfile;
321      struct include_hash *ihash;
322      struct file_name_list *ilist;
323 {
324   struct file_name_list *l;
325   struct include_hash *i;
326
327   if (! ihash->foundhere)
328     return 0;
329
330   for (i = ihash; i; i = i->next_this_file)
331     for (l = ilist; l; l = l->next)
332        if (i->foundhere == l)
333          /* The control_macro works like this: If it's NULL, the file
334             is to be included again.  If it's "", the file is never to
335             be included again.  If it's a string, the file is not to be
336             included again if the string is the name of a defined macro. */
337          return (i->control_macro
338                  && (i->control_macro[0] == '\0'
339                      || cpp_lookup (pfile, i->control_macro, -1, -1)))
340              ? (struct include_hash *)-1 : i;
341
342   return 0;
343 }
344
345 static int
346 file_cleanup (pbuf, pfile)
347      cpp_buffer *pbuf;
348      cpp_reader *pfile;
349 {
350   if (pbuf->buf)
351     {
352       free (pbuf->buf);
353       pbuf->buf = 0;
354     }
355   if (pfile->system_include_depth)
356     pfile->system_include_depth--;
357   return 0;
358 }
359
360 /* Search for include file FNAME in the include chain starting at
361    SEARCH_START.  Return -2 if this file doesn't need to be included
362    (because it was included already and it's marked idempotent),
363    -1 if an error occurred, or a file descriptor open on the file.
364    *IHASH is set to point to the include hash entry for this file, and
365    *BEFORE is 1 if the file was included before (but needs to be read
366    again). */
367 int
368 find_include_file (pfile, fname, search_start, ihash, before)
369      cpp_reader *pfile;
370      char *fname;
371      struct file_name_list *search_start;
372      struct include_hash **ihash;
373      int *before;
374 {
375   struct file_name_list *l;
376   struct include_hash *ih, *jh;
377   int f, len;
378   char *name;
379   
380   ih = include_hash (pfile, fname, 1);
381   jh = redundant_include_p (pfile, ih,
382                             fname[0] == '/' ? ABSOLUTE_PATH : search_start);
383
384   if (jh != 0)
385     {
386       *before = 1;
387       *ihash = jh;
388
389       if (jh == (struct include_hash *)-1)
390         return -2;
391       else
392         return open (jh->name, O_RDONLY, 0666);
393     }
394
395   if (ih->foundhere)
396     /* A file is already known by this name, but it's not the same file.
397        Allocate another include_hash block and add it to the next_this_file
398        chain. */
399     {
400       jh = (struct include_hash *)xmalloc (sizeof (struct include_hash));
401       while (ih->next_this_file) ih = ih->next_this_file;
402
403       ih->next_this_file = jh;
404       jh = ih;
405       ih = ih->next_this_file;
406
407       ih->next = NULL;
408       ih->next_this_file = NULL;
409       ih->buf = NULL;
410       ih->limit = NULL;
411     }
412   *before = 0;
413   *ihash = ih;
414   ih->nshort = xstrdup (fname);
415   ih->control_macro = NULL;
416   
417   /* If the pathname is absolute, just open it. */ 
418   if (fname[0] == '/')
419     {
420       ih->foundhere = ABSOLUTE_PATH;
421       ih->name = ih->nshort;
422       return open (ih->name, O_RDONLY, 0666);
423     }
424
425   /* Search directory path, trying to open the file. */
426
427   len = strlen (fname);
428   name = xmalloc (len + pfile->max_include_len + 2 + INCLUDE_LEN_FUDGE);
429
430   for (l = search_start; l; l = l->next)
431     {
432       bcopy (l->name, name, l->nlen);
433       name[l->nlen] = '/';
434       strcpy (&name[l->nlen+1], fname);
435       simplify_pathname (name);
436       if (CPP_OPTIONS (pfile)->remap)
437         name = remap_filename (pfile, name, l);
438       
439       f = open (name, O_RDONLY, 0666);
440 #ifdef EACCES
441       if (f == -1 && errno == EACCES)
442         {
443           cpp_error(pfile, "included file `%s' exists but is not readable",
444                     name);
445           return -1;
446         }
447 #endif
448
449       if (f >= 0)
450         {
451           ih->foundhere = l;
452           ih->name = xrealloc (name, strlen (name)+1);
453           return f;
454         }
455     }
456   
457     if (jh)
458       {
459         jh->next_this_file = NULL;
460         free (ih);
461       }
462     free (name);
463     *ihash = (struct include_hash *)-1;
464     return -1;
465 }
466
467 /* The file_name_map structure holds a mapping of file names for a
468    particular directory.  This mapping is read from the file named
469    FILE_NAME_MAP_FILE in that directory.  Such a file can be used to
470    map filenames on a file system with severe filename restrictions,
471    such as DOS.  The format of the file name map file is just a series
472    of lines with two tokens on each line.  The first token is the name
473    to map, and the second token is the actual name to use.  */
474
475 struct file_name_map
476 {
477   struct file_name_map *map_next;
478   char *map_from;
479   char *map_to;
480 };
481
482 #define FILE_NAME_MAP_FILE "header.gcc"
483
484 /* Read a space delimited string of unlimited length from a stdio
485    file.  */
486
487 static char *
488 read_filename_string (ch, f)
489      int ch;
490      FILE *f;
491 {
492   char *alloc, *set;
493   int len;
494
495   len = 20;
496   set = alloc = xmalloc (len + 1);
497   if (! is_space[ch])
498     {
499       *set++ = ch;
500       while ((ch = getc (f)) != EOF && ! is_space[ch])
501         {
502           if (set - alloc == len)
503             {
504               len *= 2;
505               alloc = xrealloc (alloc, len + 1);
506               set = alloc + len / 2;
507             }
508           *set++ = ch;
509         }
510     }
511   *set = '\0';
512   ungetc (ch, f);
513   return alloc;
514 }
515
516 /* This structure holds a linked list of file name maps, one per directory.  */
517
518 struct file_name_map_list
519 {
520   struct file_name_map_list *map_list_next;
521   char *map_list_name;
522   struct file_name_map *map_list_map;
523 };
524
525 /* Read the file name map file for DIRNAME.  */
526
527 static struct file_name_map *
528 read_name_map (pfile, dirname)
529      cpp_reader *pfile;
530      const char *dirname;
531 {
532   register struct file_name_map_list *map_list_ptr;
533   char *name;
534   FILE *f;
535
536   for (map_list_ptr = CPP_OPTIONS (pfile)->map_list; map_list_ptr;
537        map_list_ptr = map_list_ptr->map_list_next)
538     if (! strcmp (map_list_ptr->map_list_name, dirname))
539       return map_list_ptr->map_list_map;
540
541   map_list_ptr = ((struct file_name_map_list *)
542                   xmalloc (sizeof (struct file_name_map_list)));
543   map_list_ptr->map_list_name = xstrdup (dirname);
544
545   name = (char *) alloca (strlen (dirname) + strlen (FILE_NAME_MAP_FILE) + 2);
546   strcpy (name, dirname);
547   if (*dirname)
548     strcat (name, "/");
549   strcat (name, FILE_NAME_MAP_FILE);
550   f = fopen (name, "r");
551   if (!f)
552     map_list_ptr->map_list_map = (struct file_name_map *)-1;
553   else
554     {
555       int ch;
556       int dirlen = strlen (dirname);
557
558       while ((ch = getc (f)) != EOF)
559         {
560           char *from, *to;
561           struct file_name_map *ptr;
562
563           if (is_space[ch])
564             continue;
565           from = read_filename_string (ch, f);
566           while ((ch = getc (f)) != EOF && is_hor_space[ch])
567             ;
568           to = read_filename_string (ch, f);
569
570           ptr = ((struct file_name_map *)
571                  xmalloc (sizeof (struct file_name_map)));
572           ptr->map_from = from;
573
574           /* Make the real filename absolute.  */
575           if (*to == '/')
576             ptr->map_to = to;
577           else
578             {
579               ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
580               strcpy (ptr->map_to, dirname);
581               ptr->map_to[dirlen] = '/';
582               strcpy (ptr->map_to + dirlen + 1, to);
583               free (to);
584             }         
585
586           ptr->map_next = map_list_ptr->map_list_map;
587           map_list_ptr->map_list_map = ptr;
588
589           while ((ch = getc (f)) != '\n')
590             if (ch == EOF)
591               break;
592         }
593       fclose (f);
594     }
595   
596   map_list_ptr->map_list_next = CPP_OPTIONS (pfile)->map_list;
597   CPP_OPTIONS (pfile)->map_list = map_list_ptr;
598
599   return map_list_ptr->map_list_map;
600 }  
601
602 /* Remap NAME based on the file_name_map (if any) for LOC. */
603
604 static char *
605 remap_filename (pfile, name, loc)
606      cpp_reader *pfile;
607      char *name;
608      struct file_name_list *loc;
609 {
610   struct file_name_map *map;
611   const char *from, *p, *dir;
612
613   if (! loc->name_map)
614     loc->name_map = read_name_map (pfile,
615                                    loc->name
616                                    ? loc->name : ".");
617
618   if (loc->name_map == (struct file_name_map *)-1)
619     return name;
620   
621   from = name + strlen (loc->name) + 1;
622   
623   for (map = loc->name_map; map; map = map->map_next)
624     if (!strcmp (map->map_from, from))
625       return map->map_to;
626
627   /* Try to find a mapping file for the particular directory we are
628      looking in.  Thus #include <sys/types.h> will look up sys/types.h
629      in /usr/include/header.gcc and look up types.h in
630      /usr/include/sys/header.gcc.  */
631   p = rindex (name, '/');
632   if (!p)
633     p = name;
634   if (loc && loc->name
635       && strlen (loc->name) == (size_t) (p - name)
636       && !strncmp (loc->name, name, p - name))
637     /* FILENAME is in SEARCHPTR, which we've already checked.  */
638     return name;
639
640   if (p == name)
641     {
642       dir = ".";
643       from = name;
644     }
645   else
646     {
647       char * newdir = (char *) alloca (p - name + 1);
648       bcopy (name, newdir, p - name);
649       newdir[p - name] = '\0';
650       dir = newdir;
651       from = p + 1;
652     }
653   
654   for (map = read_name_map (pfile, dir); map; map = map->map_next)
655     if (! strcmp (map->map_from, name))
656       return map->map_to;
657
658   return name;
659 }
660
661 /* Read the contents of FD into the buffer on the top of PFILE's stack.
662    IHASH points to the include hash entry for the file associated with
663    FD.
664
665    The caller is responsible for the cpp_push_buffer.  */
666
667 int
668 finclude (pfile, fd, ihash)
669      cpp_reader *pfile;
670      int fd;
671      struct include_hash *ihash;
672 {
673   struct stat st;
674   size_t st_size;
675   long i, length;
676   cpp_buffer *fp;
677
678   if (fstat (fd, &st) < 0)
679     goto perror_fail;
680   
681   fp = CPP_BUFFER (pfile);
682   fp->nominal_fname = fp->fname = ihash->name;
683   fp->ihash = ihash;
684   fp->system_header_p = (ihash->foundhere != ABSOLUTE_PATH
685                          && ihash->foundhere->sysp);
686   fp->lineno = 1;
687   fp->colno = 1;
688   fp->cleanup = file_cleanup;
689
690   /* The ->actual_dir field is only used when ignore_srcdir is not in effect;
691      see do_include */
692   if (!CPP_OPTIONS (pfile)->ignore_srcdir)
693     fp->actual_dir = actual_directory (pfile, fp->fname);
694         
695   if (S_ISREG (st.st_mode))
696     {
697       st_size = (size_t) st.st_size;
698       if (st_size != st.st_size || st_size + 2 < st_size)
699       {
700         cpp_error (pfile, "file `%s' too large", ihash->name);
701         goto fail;
702       }
703       fp->buf = (U_CHAR *) xmalloc (st_size + 2);
704       fp->alimit = fp->buf + st_size + 2;
705       fp->cur = fp->buf;
706       
707       /* Read the file contents, knowing that st_size is an upper bound
708          on the number of bytes we can read.  */
709       length = safe_read (fd, fp->buf, st_size);
710       fp->rlimit = fp->buf + length;
711       if (length < 0)
712           goto perror_fail;
713     }
714   else if (S_ISDIR (st.st_mode))
715     {
716       cpp_pop_buffer (pfile);
717       cpp_error (pfile, "directory `%s' specified in #include", ihash->name);
718       goto fail;
719     }
720   else
721     {
722       /* Cannot count its file size before reading.
723          First read the entire file into heap and
724          copy them into buffer on stack.  */
725
726       size_t bsize = 2000;
727
728       st_size = 0;
729       fp->buf = (U_CHAR *) xmalloc (bsize + 2);
730
731       for (;;)
732         {
733           i = safe_read (fd, fp->buf + st_size, bsize - st_size);
734           if (i < 0)
735             goto perror_fail;
736           st_size += i;
737           if (st_size != bsize)
738             break;      /* End of file */
739           bsize *= 2;
740           fp->buf = (U_CHAR *) xrealloc (fp->buf, bsize + 2);
741         }
742       fp->cur = fp->buf;
743       length = st_size;
744     }
745
746   /* FIXME: Broken in presence of trigraphs (consider ??/<EOF>)
747      and doesn't warn about a missing newline. */
748   if ((length > 0 && fp->buf[length - 1] != '\n')
749       || (length > 1 && fp->buf[length - 2] == '\\'))
750     fp->buf[length++] = '\n';
751
752   fp->buf[length] = '\0';
753   fp->rlimit = fp->buf + length;
754
755   close (fd);
756   pfile->input_stack_listing_current = 0;
757   return 1;
758
759  perror_fail:
760   cpp_pop_buffer (pfile);
761   cpp_error_from_errno (pfile, ihash->name);
762  fail:
763   close (fd);
764   return 0;
765 }
766
767 static struct file_name_list *
768 actual_directory (pfile, fname)
769      cpp_reader *pfile;
770      char *fname;
771 {
772   char *last_slash, *dir;
773   size_t dlen;
774   struct file_name_list *x;
775   
776   dir = xstrdup (fname);
777   last_slash = rindex (dir, '/');
778   if (last_slash)
779     {
780       if (last_slash == dir)
781         {
782           dlen = 1;
783           last_slash[1] = '\0';
784         }
785       else
786         {
787           dlen = last_slash - dir;
788           *last_slash = '\0';
789         }
790     }
791   else
792     {
793       dir[0] = '.';
794       dir[1] = '\0';
795       dlen = 1;
796     }
797
798   if (dlen > pfile->max_include_len)
799     pfile->max_include_len = dlen;
800
801   for (x = pfile->actual_dirs; x; x = x->alloc)
802     if (!strcmp (x->name, dir))
803       {
804         free (dir);
805         return x;
806       }
807
808   /* Not found, make a new one. */
809   x = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
810   x->name = dir;
811   x->nlen = dlen;
812   x->next = CPP_OPTIONS (pfile)->quote_include;
813   x->alloc = pfile->actual_dirs;
814   x->sysp = 0;
815   x->name_map = NULL;
816
817   pfile->actual_dirs = x;
818   return x;
819 }
820
821 /* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
822    retrying if necessary.  If MAX_READ_LEN is defined, read at most
823    that bytes at a time.  Return a negative value if an error occurs,
824    otherwise return the actual number of bytes read,
825    which must be LEN unless end-of-file was reached.  */
826
827 static long
828 safe_read (desc, ptr, len)
829      int desc;
830      char *ptr;
831      int len;
832 {
833   int left, rcount, nchars;
834
835   left = len;
836   while (left > 0) {
837     rcount = left;
838 #ifdef MAX_READ_LEN
839     if (rcount > MAX_READ_LEN)
840       rcount = MAX_READ_LEN;
841 #endif
842     nchars = read (desc, ptr, rcount);
843     if (nchars < 0)
844       {
845 #ifdef EINTR
846         if (errno == EINTR)
847           continue;
848 #endif
849         return nchars;
850       }
851     if (nchars == 0)
852       break;
853     ptr += nchars;
854     left -= nchars;
855   }
856   return len - left;
857 }
858
859 /* Add output to `deps_buffer' for the -M switch.
860    STRING points to the text to be output.
861    SPACER is ':' for targets, ' ' for dependencies, zero for text
862    to be inserted literally.  */
863
864 void
865 deps_output (pfile, string, spacer)
866      cpp_reader *pfile;
867      char *string;
868      int spacer;
869 {
870   int size;
871   int cr = 0;
872
873   if (!*string)
874     return;
875
876   size = strlen (string);
877
878 #ifndef MAX_OUTPUT_COLUMNS
879 #define MAX_OUTPUT_COLUMNS 72
880 #endif
881   if (pfile->deps_column > 0
882       && (pfile->deps_column + size) > MAX_OUTPUT_COLUMNS)
883     {
884       size += 5;
885       cr = 1;
886       pfile->deps_column = 0;
887     }
888
889   if (pfile->deps_size + size + 8 > pfile->deps_allocated_size)
890     {
891       pfile->deps_allocated_size = (pfile->deps_size + size + 50) * 2;
892       pfile->deps_buffer = (char *) xrealloc (pfile->deps_buffer,
893                                               pfile->deps_allocated_size);
894     }
895
896   if (cr)
897     {
898       bcopy (" \\\n  ", &pfile->deps_buffer[pfile->deps_size], 5);
899       pfile->deps_size += 5;
900     }
901   
902   if (spacer == ' ' && pfile->deps_column > 0)
903     pfile->deps_buffer[pfile->deps_size++] = ' ';
904   bcopy (string, &pfile->deps_buffer[pfile->deps_size], size);
905   pfile->deps_size += size;
906   pfile->deps_column += size;
907   if (spacer == ':')
908     pfile->deps_buffer[pfile->deps_size++] = ':';
909   pfile->deps_buffer[pfile->deps_size] = 0;
910 }
911
912 /* Simplify a path name in place, deleting redundant components.  This
913    reduces OS overhead and guarantees that equivalent paths compare
914    the same (modulo symlinks).
915
916    Transforms made:
917    foo/bar/../quux      foo/quux
918    foo/./bar            foo/bar
919    foo//bar             foo/bar
920    /../quux             /quux
921    //quux               //quux  (POSIX allows leading // as a namespace escape)
922
923    Guarantees no trailing slashes. All transforms reduce the length
924    of the string.
925  */
926 static void
927 simplify_pathname (path)
928     char *path;
929 {
930     char *from, *to;
931     char *base;
932     int absolute = 0;
933
934 #if defined _WIN32 || defined __MSDOS__
935     /* Convert all backslashes to slashes. */
936     for (from = path; *from; from++)
937         if (*from == '\\') *from = '/';
938     
939     /* Skip over leading drive letter if present. */
940     if (ISALPHA (path[0]) && path[1] == ':')
941         from = to = &path[2];
942     else
943         from = to = path;
944 #else
945     from = to = path;
946 #endif
947     
948     /* Remove redundant initial /s.  */
949     if (*from == '/')
950     {
951         absolute = 1;
952         to++;
953         from++;
954         if (*from == '/')
955         {
956             if (*++from == '/')
957                 /* 3 or more initial /s are equivalent to 1 /.  */
958                 while (*++from == '/');
959             else
960                 /* On some hosts // differs from /; Posix allows this.  */
961                 to++;
962         }
963     }
964     base = to;
965     
966     for (;;)
967     {
968         while (*from == '/')
969             from++;
970
971         if (from[0] == '.' && from[1] == '/')
972             from += 2;
973         else if (from[0] == '.' && from[1] == '\0')
974             goto done;
975         else if (from[0] == '.' && from[1] == '.' && from[2] == '/')
976         {
977             if (base == to)
978             {
979                 if (absolute)
980                     from += 3;
981                 else
982                 {
983                     *to++ = *from++;
984                     *to++ = *from++;
985                     *to++ = *from++;
986                     base = to;
987                 }
988             }
989             else
990             {
991                 to -= 2;
992                 while (to > base && *to != '/') to--;
993                 if (*to == '/')
994                     to++;
995                 from += 3;
996             }
997         }
998         else if (from[0] == '.' && from[1] == '.' && from[2] == '\0')
999         {
1000             if (base == to)
1001             {
1002                 if (!absolute)
1003                 {
1004                     *to++ = *from++;
1005                     *to++ = *from++;
1006                 }
1007             }
1008             else
1009             {
1010                 to -= 2;
1011                 while (to > base && *to != '/') to--;
1012                 if (*to == '/')
1013                     to++;
1014             }
1015             goto done;
1016         }
1017         else
1018             /* Copy this component and trailing /, if any.  */
1019             while ((*to++ = *from++) != '/')
1020             {
1021                 if (!to[-1])
1022                 {
1023                     to--;
1024                     goto done;
1025                 }
1026             }
1027         
1028     }
1029     
1030  done:
1031     /* Trim trailing slash */
1032     if (to[0] == '/' && (!absolute || to > path+1))
1033         to--;
1034
1035     /* Change the empty string to "." so that stat() on the result
1036        will always work. */
1037     if (to == path)
1038       *to++ = '.';
1039     
1040     *to = '\0';
1041
1042     return;
1043 }
1044
1045 /* It is not clear when this should be used if at all, so I've
1046    disabled it until someone who understands VMS can look at it. */
1047 #if 0
1048
1049 /* Under VMS we need to fix up the "include" specification filename.
1050
1051    Rules for possible conversions
1052
1053         fullname                tried paths
1054
1055         name                    name
1056         ./dir/name              [.dir]name
1057         /dir/name               dir:name
1058         /name                   [000000]name, name
1059         dir/name                dir:[000000]name, dir:name, dir/name
1060         dir1/dir2/name          dir1:[dir2]name, dir1:[000000.dir2]name
1061         path:/name              path:[000000]name, path:name
1062         path:/dir/name          path:[000000.dir]name, path:[dir]name
1063         path:dir/name           path:[dir]name
1064         [path]:[dir]name        [path.dir]name
1065         path/[dir]name          [path.dir]name
1066
1067    The path:/name input is constructed when expanding <> includes. */
1068
1069
1070 static void
1071 hack_vms_include_specification (fullname)
1072      char *fullname;
1073 {
1074   register char *basename, *unixname, *local_ptr, *first_slash;
1075   int f, check_filename_before_returning, must_revert;
1076   char Local[512];
1077
1078   check_filename_before_returning = 0;
1079   must_revert = 0;
1080   /* See if we can find a 1st slash. If not, there's no path information.  */
1081   first_slash = index (fullname, '/');
1082   if (first_slash == 0)
1083     return 0;                           /* Nothing to do!!! */
1084
1085   /* construct device spec if none given.  */
1086
1087   if (index (fullname, ':') == 0)
1088     {
1089
1090       /* If fullname has a slash, take it as device spec.  */
1091
1092       if (first_slash == fullname)
1093         {
1094           first_slash = index (fullname+1, '/');        /* 2nd slash ? */
1095           if (first_slash)
1096             *first_slash = ':';                         /* make device spec  */
1097           for (basename = fullname; *basename != 0; basename++)
1098             *basename = *(basename+1);                  /* remove leading slash  */
1099         }
1100       else if ((first_slash[-1] != '.')         /* keep ':/', './' */
1101             && (first_slash[-1] != ':')
1102             && (first_slash[-1] != ']'))        /* or a vms path  */
1103         {
1104           *first_slash = ':';
1105         }
1106       else if ((first_slash[1] == '[')          /* skip './' in './[dir'  */
1107             && (first_slash[-1] == '.'))
1108         fullname += 2;
1109     }
1110
1111   /* Get part after first ':' (basename[-1] == ':')
1112      or last '/' (basename[-1] == '/').  */
1113
1114   basename = base_name (fullname);
1115
1116   local_ptr = Local;                    /* initialize */
1117
1118   /* We are trying to do a number of things here.  First of all, we are
1119      trying to hammer the filenames into a standard format, such that later
1120      processing can handle them.
1121      
1122      If the file name contains something like [dir.], then it recognizes this
1123      as a root, and strips the ".]".  Later processing will add whatever is
1124      needed to get things working properly.
1125      
1126      If no device is specified, then the first directory name is taken to be
1127      a device name (or a rooted logical).  */
1128
1129   /* Point to the UNIX filename part (which needs to be fixed!)
1130      but skip vms path information.
1131      [basename != fullname since first_slash != 0].  */
1132
1133   if ((basename[-1] == ':')             /* vms path spec.  */
1134       || (basename[-1] == ']')
1135       || (basename[-1] == '>'))
1136     unixname = basename;
1137   else
1138     unixname = fullname;
1139
1140   if (*unixname == '/')
1141     unixname++;
1142
1143   /* If the directory spec is not rooted, we can just copy
1144      the UNIX filename part and we are done.  */
1145
1146   if (((basename - fullname) > 1)
1147      && (  (basename[-1] == ']')
1148         || (basename[-1] == '>')))
1149     {
1150       if (basename[-2] != '.')
1151         {
1152
1153         /* The VMS part ends in a `]', and the preceding character is not a `.'.
1154            -> PATH]:/name (basename = '/name', unixname = 'name')
1155            We strip the `]', and then splice the two parts of the name in the
1156            usual way.  Given the default locations for include files in cccp.c,
1157            we will only use this code if the user specifies alternate locations
1158            with the /include (-I) switch on the command line.  */
1159
1160           basename -= 1;        /* Strip "]" */
1161           unixname--;           /* backspace */
1162         }
1163       else
1164         {
1165
1166         /* The VMS part has a ".]" at the end, and this will not do.  Later
1167            processing will add a second directory spec, and this would be a syntax
1168            error.  Thus we strip the ".]", and thus merge the directory specs.
1169            We also backspace unixname, so that it points to a '/'.  This inhibits the
1170            generation of the 000000 root directory spec (which does not belong here
1171            in this case).  */
1172
1173           basename -= 2;        /* Strip ".]" */
1174           unixname--;           /* backspace */
1175         }
1176     }
1177
1178   else
1179
1180     {
1181
1182       /* We drop in here if there is no VMS style directory specification yet.
1183          If there is no device specification either, we make the first dir a
1184          device and try that.  If we do not do this, then we will be essentially
1185          searching the users default directory (as if they did a #include "asdf.h").
1186         
1187          Then all we need to do is to push a '[' into the output string. Later
1188          processing will fill this in, and close the bracket.  */
1189
1190       if ((unixname != fullname)        /* vms path spec found.  */
1191          && (basename[-1] != ':'))
1192         *local_ptr++ = ':';             /* dev not in spec.  take first dir */
1193
1194       *local_ptr++ = '[';               /* Open the directory specification */
1195     }
1196
1197     if (unixname == fullname)           /* no vms dir spec.  */
1198       {
1199         must_revert = 1;
1200         if ((first_slash != 0)          /* unix dir spec.  */
1201             && (*unixname != '/')       /* not beginning with '/'  */
1202             && (*unixname != '.'))      /* or './' or '../'  */
1203           *local_ptr++ = '.';           /* dir is local !  */
1204       }
1205
1206   /* at this point we assume that we have the device spec, and (at least
1207      the opening "[" for a directory specification.  We may have directories
1208      specified already.
1209
1210      If there are no other slashes then the filename will be
1211      in the "root" directory.  Otherwise, we need to add
1212      directory specifications.  */
1213
1214   if (index (unixname, '/') == 0)
1215     {
1216       /* if no directories specified yet and none are following.  */
1217       if (local_ptr[-1] == '[')
1218         {
1219           /* Just add "000000]" as the directory string */
1220           strcpy (local_ptr, "000000]");
1221           local_ptr += strlen (local_ptr);
1222           check_filename_before_returning = 1; /* we might need to fool with this later */
1223         }
1224     }
1225   else
1226     {
1227
1228       /* As long as there are still subdirectories to add, do them.  */
1229       while (index (unixname, '/') != 0)
1230         {
1231           /* If this token is "." we can ignore it
1232                if it's not at the beginning of a path.  */
1233           if ((unixname[0] == '.') && (unixname[1] == '/'))
1234             {
1235               /* remove it at beginning of path.  */
1236               if (  ((unixname == fullname)             /* no device spec  */
1237                     && (fullname+2 != basename))        /* starts with ./ */
1238                                                         /* or  */
1239                  || ((basename[-1] == ':')              /* device spec  */
1240                     && (unixname-1 == basename)))       /* and ./ afterwards  */
1241                 *local_ptr++ = '.';                     /* make '[.' start of path.  */
1242               unixname += 2;
1243               continue;
1244             }
1245
1246           /* Add a subdirectory spec. Do not duplicate "." */
1247           if (  local_ptr[-1] != '.'
1248              && local_ptr[-1] != '['
1249              && local_ptr[-1] != '<')
1250             *local_ptr++ = '.';
1251
1252           /* If this is ".." then the spec becomes "-" */
1253           if (  (unixname[0] == '.')
1254              && (unixname[1] == '.')
1255              && (unixname[2] == '/'))
1256             {
1257               /* Add "-" and skip the ".." */
1258               if ((local_ptr[-1] == '.')
1259                   && (local_ptr[-2] == '['))
1260                 local_ptr--;                    /* prevent [.-  */
1261               *local_ptr++ = '-';
1262               unixname += 3;
1263               continue;
1264             }
1265
1266           /* Copy the subdirectory */
1267           while (*unixname != '/')
1268             *local_ptr++= *unixname++;
1269
1270           unixname++;                   /* Skip the "/" */
1271         }
1272
1273       /* Close the directory specification */
1274       if (local_ptr[-1] == '.')         /* no trailing periods */
1275         local_ptr--;
1276
1277       if (local_ptr[-1] == '[')         /* no dir needed */
1278         local_ptr--;
1279       else
1280         *local_ptr++ = ']';
1281     }
1282
1283   /* Now add the filename.  */
1284
1285   while (*unixname)
1286     *local_ptr++ = *unixname++;
1287   *local_ptr = 0;
1288
1289   /* Now append it to the original VMS spec.  */
1290
1291   strcpy ((must_revert==1)?fullname:basename, Local);
1292
1293   /* If we put a [000000] in the filename, try to open it first. If this fails,
1294      remove the [000000], and return that name.  This provides flexibility
1295      to the user in that they can use both rooted and non-rooted logical names
1296      to point to the location of the file.  */
1297
1298   if (check_filename_before_returning)
1299     {
1300       f = open (fullname, O_RDONLY, 0666);
1301       if (f >= 0)
1302         {
1303           /* The file name is OK as it is, so return it as is.  */
1304           close (f);
1305           return 1;
1306         }
1307
1308       /* The filename did not work.  Try to remove the [000000] from the name,
1309          and return it.  */
1310
1311       basename = index (fullname, '[');
1312       local_ptr = index (fullname, ']') + 1;
1313       strcpy (basename, local_ptr);             /* this gets rid of it */
1314
1315     }
1316
1317   return 1;
1318 }
1319 #endif  /* VMS */