1 /* Part of CPP library. (include file handling)
2 Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1998,
3 1999, 2000 Free Software Foundation, Inc.
4 Written by Per Bothner, 1994.
5 Based on CCCP program by Paul Rubin, June 1986
6 Adapted to ANSI C, Richard Stallman, Jan 1987
7 Split out of cpplib.c, Zack Weinberg, Oct 1998
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
29 #include "splay-tree.h"
32 # include <sys/mman.h>
33 # ifndef MMAP_THRESHOLD
34 # define MMAP_THRESHOLD 3 /* Minimum page count to mmap the file. */
37 #else /* No MMAP_FILE */
38 # undef MMAP_THRESHOLD
39 # define MMAP_THRESHOLD 0
46 #ifndef INCLUDE_LEN_FUDGE
47 # define INCLUDE_LEN_FUDGE 0
50 /* If errno is inspected immediately after a system call fails, it will be
51 nonzero, and no error number will ever be zero. */
62 /* Suppress warning about function macros used w/o arguments in traditional
63 C. It is unlikely that glibc's strcmp macro helps this file at all. */
66 static struct file_name_map *read_name_map
67 PARAMS ((cpp_reader *, const char *));
68 static char *read_filename_string PARAMS ((int, FILE *));
69 static char *remap_filename PARAMS ((cpp_reader *, char *,
70 struct file_name_list *));
71 static struct file_name_list *actual_directory
72 PARAMS ((cpp_reader *, const char *));
73 static struct include_file *find_include_file
74 PARAMS ((cpp_reader *, const char *,
75 struct file_name_list *));
76 static struct include_file *lookup_include_file
77 PARAMS ((cpp_reader *, const char *));
78 static int read_include_file PARAMS ((cpp_reader *, struct include_file *));
79 static int stack_include_file PARAMS ((cpp_reader *, struct include_file *));
80 static void purge_cache PARAMS ((struct include_file *));
81 static void destroy_include_file_node PARAMS ((splay_tree_value));
82 static int report_missing_guard PARAMS ((splay_tree_node, void *));
85 static void hack_vms_include_specification PARAMS ((char *));
88 /* We use a splay tree to store information about all the include
89 files seen in this compilation. The key of each tree node is the
90 physical path to the file. The value is 0 if the file does not
91 exist, or a struct include_file pointer. */
94 destroy_include_file_node (v)
97 struct include_file *f = (struct include_file *)v;
106 _cpp_init_includes (pfile)
109 pfile->all_include_files
110 = splay_tree_new ((splay_tree_compare_fn) strcmp,
111 (splay_tree_delete_key_fn) free,
112 destroy_include_file_node);
116 _cpp_cleanup_includes (pfile)
119 splay_tree_delete (pfile->all_include_files);
122 /* Given a file name, look it up in the cache; if there is no entry,
123 create one. Returns 0 if the file doesn't exist or is
124 inaccessible, otherwise the cache entry. */
126 static struct include_file *
127 lookup_include_file (pfile, filename)
129 const char *filename;
132 struct include_file *file = 0;
136 nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) filename);
139 return (struct include_file *)nd->value;
141 /* We used to open files in nonblocking mode, but that caused more
142 problems than it solved. Do take care not to acquire a
143 controlling terminal by mistake (this can't happen on sane
144 systems, but paranoia is a virtue).
146 Use the three-argument form of open even though we aren't
147 specifying O_CREAT, to defend against broken system headers.
149 O_BINARY tells some runtime libraries (notably DJGPP) not to do
150 newline translation; we can handle DOS line breaks just fine
153 Special case: the empty string is translated to stdin. */
155 if (filename[0] == '\0')
158 fd = open (filename, O_RDONLY|O_NOCTTY|O_BINARY, 0666);
162 if (fstat (fd, &st) < 0)
165 file = xcnew (struct include_file);
166 file->name = xstrdup (filename);
170 /* If the file is plain and zero length, mark it never-reread now. */
171 if (S_ISREG (st.st_mode) && st.st_size == 0)
172 file->cmacro = NEVER_REREAD;
174 splay_tree_insert (pfile->all_include_files,
175 (splay_tree_key) file->name, (splay_tree_value) file);
180 /* Don't issue an error message if the file doesn't exist. */
181 if (errno != ENOENT && errno != ENOTDIR)
182 cpp_error_from_errno (pfile, filename);
184 /* Create a negative node for this path. */
185 splay_tree_insert (pfile->all_include_files,
186 (splay_tree_key) xstrdup (filename), 0);
190 /* Place the file referenced by INC into a new buffer on PFILE's stack.
191 Return 1 if successful, 0 if not. */
194 stack_include_file (pfile, inc)
196 struct include_file *inc;
200 if (DO_NOT_REREAD (inc))
203 if (inc->buffer == NULL)
204 if (read_include_file (pfile, inc) == 0)
207 fp = cpp_push_buffer (pfile, NULL, 0);
212 fp->nominal_fname = inc->name;
213 fp->buf = inc->buffer;
214 fp->rlimit = fp->buf + inc->st.st_size;
217 fp->line_base = fp->buf;
219 /* The ->actual_dir field is only used when ignore_srcdir is not in effect;
221 if (!CPP_OPTION (pfile, ignore_srcdir))
222 fp->actual_dir = actual_directory (pfile, inc->name);
225 pfile->include_depth++;
226 pfile->input_stack_listing_current = 0;
227 if (pfile->cb.enter_file)
228 (*pfile->cb.enter_file) (pfile);
232 /* Read the file referenced by INC into the file cache.
234 If fd points to a plain file, we might be able to mmap it; we can
235 definitely allocate the buffer all at once. If fd is a pipe or
236 terminal, we can't do either. If fd is something weird, like a
237 block device or a directory, we don't want to read it at all.
239 Unfortunately, different systems use different st.st_mode values
240 for pipes: some have S_ISFIFO, some S_ISSOCK, some are buggy and
241 zero the entire struct stat except a couple fields. Hence we don't
242 even try to figure out what something is, except for plain files,
243 directories, and block devices.
245 FIXME: Flush file cache and try again if we run out of memory. */
248 read_include_file (pfile, inc)
250 struct include_file *inc;
252 ssize_t size, offset, count;
255 static int pagesize = -1;
258 if (S_ISREG (inc->st.st_mode))
260 /* off_t might have a wider range than ssize_t - in other words,
261 the max size of a file might be bigger than the address
262 space. We can't handle a file that large. (Anyone with
263 a single source file bigger than 2GB needs to rethink
264 their coding style.) Some systems (e.g. AIX 4.1) define
265 SSIZE_MAX to be much smaller than the actual range of the
266 type. Use INTTYPE_MAXIMUM unconditionally to ensure this
268 if (inc->st.st_size > INTTYPE_MAXIMUM (ssize_t))
270 cpp_error (pfile, "%s is too large", inc->name);
273 size = inc->st.st_size;
278 pagesize = getpagesize ();
280 if (size / pagesize >= MMAP_THRESHOLD)
282 buf = (U_CHAR *) mmap (0, size, PROT_READ, MAP_PRIVATE, inc->fd, 0);
283 if (buf == (U_CHAR *)-1)
290 buf = (U_CHAR *) xmalloc (size);
292 while (offset < size)
294 count = read (inc->fd, buf + offset, size - offset);
299 cpp_warning (pfile, "%s is shorter than expected", inc->name);
306 else if (S_ISBLK (inc->st.st_mode))
308 cpp_error (pfile, "%s is a block device", inc->name);
311 else if (S_ISDIR (inc->st.st_mode))
313 cpp_error (pfile, "%s is a directory", inc->name);
318 /* 8 kilobytes is a sensible starting size. It ought to be
319 bigger than the kernel pipe buffer, and it's definitely
320 bigger than the majority of C source files. */
323 buf = (U_CHAR *) xmalloc (size);
325 while ((count = read (inc->fd, buf + offset, size - offset)) > 0)
329 buf = xrealloc (buf, (size *= 2));
335 buf = xrealloc (buf, offset);
336 inc->st.st_size = offset;
345 cpp_error_from_errno (pfile, inc->name);
347 /* Do not try to read this file again. */
350 inc->cmacro = NEVER_REREAD;
356 struct include_file *inc;
362 munmap ((PTR) inc->buffer, inc->st.st_size);
365 free ((PTR) inc->buffer);
370 /* Return 1 if the file named by FNAME has been included before in
371 any context, 0 otherwise. */
373 cpp_included (pfile, fname)
377 struct file_name_list *path;
383 /* Just look it up. */
384 nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) fname);
385 return (nd && nd->value);
388 /* Search directory path for the file. */
389 name = (char *) alloca (strlen (fname) + pfile->max_include_len
390 + 2 + INCLUDE_LEN_FUDGE);
391 for (path = CPP_OPTION (pfile, quote_include); path; path = path->next)
393 memcpy (name, path->name, path->nlen);
394 name[path->nlen] = '/';
395 strcpy (&name[path->nlen+1], fname);
396 _cpp_simplify_pathname (name);
397 if (CPP_OPTION (pfile, remap))
398 name = remap_filename (pfile, name, path);
400 nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) name);
407 /* Search for include file FNAME in the include chain starting at
408 SEARCH_START. Return 0 if there is no such file (or it's un-openable),
409 otherwise an include_file structure. */
411 static struct include_file *
412 find_include_file (pfile, fname, search_start)
415 struct file_name_list *search_start;
417 struct file_name_list *path;
419 struct include_file *file;
422 return lookup_include_file (pfile, fname);
424 /* Search directory path for the file. */
425 name = (char *) alloca (strlen (fname) + pfile->max_include_len
426 + 2 + INCLUDE_LEN_FUDGE);
427 for (path = search_start; path; path = path->next)
429 memcpy (name, path->name, path->nlen);
430 name[path->nlen] = '/';
431 strcpy (&name[path->nlen+1], fname);
432 _cpp_simplify_pathname (name);
433 if (CPP_OPTION (pfile, remap))
434 name = remap_filename (pfile, name, path);
436 file = lookup_include_file (pfile, name);
439 file->sysp = path->sysp;
440 file->foundhere = path;
447 /* #line uses this to save artificial file names. We have to stat the
448 file because an all_include_files entry is always either + or -,
449 there's no 'I don't know' value. */
451 _cpp_fake_include (pfile, fname)
456 struct include_file *file;
459 file = find_include_file (pfile, fname, CPP_OPTION (pfile, quote_include));
470 name = xstrdup (fname);
471 _cpp_simplify_pathname (name);
473 /* We cannot just blindly insert a node, because there's still the
474 chance that the node already exists but isn't on the search path. */
475 nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) name);
479 return (const char *) nd->key;
482 splay_tree_insert (pfile->all_include_files, (splay_tree_key) name, 0);
483 return (const char *)name;
486 /* Not everyone who wants to set system-header-ness on a buffer can
487 see the details of struct include_file. This is an exported interface
488 because fix-header needs it. */
490 cpp_make_system_header (pfile, pbuf, flag)
495 if (flag < 0 || flag > 2)
496 cpp_ice (pfile, "cpp_make_system_header: bad flag %d\n", flag);
498 cpp_ice (pfile, "cpp_make_system_header called on non-file buffer");
500 pbuf->inc->sysp = flag;
504 cpp_syshdr_flags (pfile, pbuf)
505 cpp_reader *pfile ATTRIBUTE_UNUSED;
508 #ifndef NO_IMPLICIT_EXTERN_C
509 if (CPP_OPTION (pfile, cplusplus) && pbuf->inc->sysp == 2)
517 /* Report on all files that might benefit from a multiple include guard.
520 _cpp_report_missing_guards (pfile)
524 splay_tree_foreach (pfile->all_include_files, report_missing_guard,
529 report_missing_guard (n, b)
533 struct include_file *f = (struct include_file *) n->value;
534 int *bannerp = (int *)b;
536 if (f && f->cmacro == 0 && f->include_count == 1)
540 fputs (_("Multiple include guards may be useful for:\n"), stderr);
543 fputs (f->name, stderr);
549 #define PRINT_THIS_DEP(p, b) (CPP_PRINT_DEPS(p) > (b||p->system_include_depth))
551 _cpp_execute_include (pfile, f, len, no_reinclude, search_start, angle_brackets)
556 struct file_name_list *search_start;
559 struct include_file *inc;
565 search_start = CPP_OPTION (pfile, bracket_include);
566 else if (CPP_OPTION (pfile, ignore_srcdir))
567 search_start = CPP_OPTION (pfile, quote_include);
569 search_start = CPP_BUFFER (pfile)->actual_dir;
574 cpp_error (pfile, "No include path in which to find %s", f);
578 fname = alloca (len + 1);
579 memcpy (fname, f, len);
582 inc = find_include_file (pfile, fname, search_start);
586 /* For -M, add the file to the dependencies on its first inclusion. */
587 if (!inc->include_count && PRINT_THIS_DEP (pfile, angle_brackets))
588 deps_add_dep (pfile->deps, inc->name);
589 inc->include_count++;
591 /* Actually process the file. */
592 if (stack_include_file (pfile, inc))
595 pfile->system_include_depth++;
598 inc->cmacro = NEVER_REREAD;
600 /* Handle -H option. */
601 if (CPP_OPTION (pfile, print_include_names))
603 cpp_buffer *fp = CPP_BUFFER (pfile);
604 while ((fp = CPP_PREV_BUFFER (fp)) != NULL)
606 fprintf (stderr, " %s\n", inc->name);
612 if (CPP_OPTION (pfile, print_deps_missing_files)
613 && PRINT_THIS_DEP (pfile, angle_brackets))
616 deps_add_dep (pfile->deps, fname);
620 struct file_name_list *ptr;
621 /* If requested as a system header, assume it belongs in
622 the first system header directory. */
623 if (CPP_OPTION (pfile, bracket_include))
624 ptr = CPP_OPTION (pfile, bracket_include);
626 ptr = CPP_OPTION (pfile, quote_include);
628 p = (char *) alloca (strlen (ptr->name)
629 + strlen (fname) + 2);
630 if (*ptr->name != '\0')
632 strcpy (p, ptr->name);
636 _cpp_simplify_pathname (p);
637 deps_add_dep (pfile->deps, p);
640 /* If -M was specified, and this header file won't be added to
641 the dependency list, then don't count this as an error,
642 because we can still produce correct output. Otherwise, we
643 can't produce correct output, because there may be
644 dependencies we need inside the missing file, and we don't
645 know what directory this missing file exists in. */
646 else if (CPP_PRINT_DEPS (pfile)
647 && ! PRINT_THIS_DEP (pfile, angle_brackets))
648 cpp_warning (pfile, "No include path in which to find %s", fname);
650 cpp_error_from_errno (pfile, fname);
653 /* Locate file F, and determine whether it is newer than PFILE. Return -1,
654 if F cannot be located or dated, 1, if it is newer and 0 if older. */
657 _cpp_compare_file_date (pfile, f, len, angle_brackets)
664 struct file_name_list *search_start;
665 struct include_file *inc;
666 struct include_file *current_include = CPP_BUFFER (pfile)->inc;
669 search_start = CPP_OPTION (pfile, bracket_include);
670 else if (CPP_OPTION (pfile, ignore_srcdir))
671 search_start = CPP_OPTION (pfile, quote_include);
673 search_start = CPP_BUFFER (pfile)->actual_dir;
675 fname = alloca (len + 1);
676 memcpy (fname, f, len);
678 inc = find_include_file (pfile, fname, search_start);
688 return inc->st.st_mtime > current_include->st.st_mtime;
692 /* Push an input buffer and load it up with the contents of FNAME.
693 If FNAME is "" or NULL, read standard input. */
695 cpp_read_file (pfile, fname)
699 struct include_file *f;
704 f = lookup_include_file (pfile, fname);
708 cpp_error_from_errno (pfile, fname);
712 return stack_include_file (pfile, f);
715 /* Do appropriate cleanup when a file buffer is popped off the input
718 _cpp_pop_file_buffer (pfile, buf)
722 struct include_file *inc = buf->inc;
724 if (pfile->system_include_depth)
725 pfile->system_include_depth--;
726 if (pfile->include_depth)
727 pfile->include_depth--;
728 if (pfile->potential_control_macro)
730 if (inc->cmacro != NEVER_REREAD)
731 inc->cmacro = pfile->potential_control_macro;
732 pfile->potential_control_macro = 0;
734 pfile->input_stack_listing_current = 0;
737 if (inc->refcnt == 0 && DO_NOT_REREAD (inc))
741 /* The file_name_map structure holds a mapping of file names for a
742 particular directory. This mapping is read from the file named
743 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
744 map filenames on a file system with severe filename restrictions,
745 such as DOS. The format of the file name map file is just a series
746 of lines with two tokens on each line. The first token is the name
747 to map, and the second token is the actual name to use. */
751 struct file_name_map *map_next;
756 #define FILE_NAME_MAP_FILE "header.gcc"
758 /* Read a space delimited string of unlimited length from a stdio
762 read_filename_string (ch, f)
770 set = alloc = xmalloc (len + 1);
774 while ((ch = getc (f)) != EOF && ! is_space(ch))
776 if (set - alloc == len)
779 alloc = xrealloc (alloc, len + 1);
780 set = alloc + len / 2;
790 /* This structure holds a linked list of file name maps, one per directory. */
792 struct file_name_map_list
794 struct file_name_map_list *map_list_next;
796 struct file_name_map *map_list_map;
799 /* Read the file name map file for DIRNAME. */
801 static struct file_name_map *
802 read_name_map (pfile, dirname)
806 register struct file_name_map_list *map_list_ptr;
810 for (map_list_ptr = CPP_OPTION (pfile, map_list); map_list_ptr;
811 map_list_ptr = map_list_ptr->map_list_next)
812 if (! strcmp (map_list_ptr->map_list_name, dirname))
813 return map_list_ptr->map_list_map;
815 map_list_ptr = ((struct file_name_map_list *)
816 xmalloc (sizeof (struct file_name_map_list)));
817 map_list_ptr->map_list_name = xstrdup (dirname);
818 map_list_ptr->map_list_map = NULL;
820 name = (char *) alloca (strlen (dirname) + strlen (FILE_NAME_MAP_FILE) + 2);
821 strcpy (name, dirname);
824 strcat (name, FILE_NAME_MAP_FILE);
825 f = fopen (name, "r");
827 map_list_ptr->map_list_map = (struct file_name_map *)-1;
831 int dirlen = strlen (dirname);
833 while ((ch = getc (f)) != EOF)
836 struct file_name_map *ptr;
840 from = read_filename_string (ch, f);
841 while ((ch = getc (f)) != EOF && is_hspace(ch))
843 to = read_filename_string (ch, f);
845 ptr = ((struct file_name_map *)
846 xmalloc (sizeof (struct file_name_map)));
847 ptr->map_from = from;
849 /* Make the real filename absolute. */
854 ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
855 strcpy (ptr->map_to, dirname);
856 ptr->map_to[dirlen] = '/';
857 strcpy (ptr->map_to + dirlen + 1, to);
861 ptr->map_next = map_list_ptr->map_list_map;
862 map_list_ptr->map_list_map = ptr;
864 while ((ch = getc (f)) != '\n')
871 map_list_ptr->map_list_next = CPP_OPTION (pfile, map_list);
872 CPP_OPTION (pfile, map_list) = map_list_ptr;
874 return map_list_ptr->map_list_map;
877 /* Remap NAME based on the file_name_map (if any) for LOC. */
880 remap_filename (pfile, name, loc)
883 struct file_name_list *loc;
885 struct file_name_map *map;
886 const char *from, *p, *dir;
889 loc->name_map = read_name_map (pfile,
893 if (loc->name_map == (struct file_name_map *)-1)
896 from = name + strlen (loc->name) + 1;
898 for (map = loc->name_map; map; map = map->map_next)
899 if (!strcmp (map->map_from, from))
902 /* Try to find a mapping file for the particular directory we are
903 looking in. Thus #include <sys/types.h> will look up sys/types.h
904 in /usr/include/header.gcc and look up types.h in
905 /usr/include/sys/header.gcc. */
906 p = strrchr (name, '/');
910 && strlen (loc->name) == (size_t) (p - name)
911 && !strncmp (loc->name, name, p - name))
912 /* FILENAME is in SEARCHPTR, which we've already checked. */
922 char * newdir = (char *) alloca (p - name + 1);
923 memcpy (newdir, name, p - name);
924 newdir[p - name] = '\0';
929 for (map = read_name_map (pfile, dir); map; map = map->map_next)
930 if (! strcmp (map->map_from, name))
936 /* Given a path FNAME, extract the directory component and place it
937 onto the actual_dirs list. Return a pointer to the allocated
938 file_name_list structure. These structures are used to implement
939 current-directory "" include searching. */
941 static struct file_name_list *
942 actual_directory (pfile, fname)
946 char *last_slash, *dir;
948 struct file_name_list *x;
950 dir = xstrdup (fname);
951 last_slash = strrchr (dir, '/');
954 if (last_slash == dir)
957 last_slash[1] = '\0';
961 dlen = last_slash - dir;
972 if (dlen > pfile->max_include_len)
973 pfile->max_include_len = dlen;
975 for (x = pfile->actual_dirs; x; x = x->alloc)
976 if (!strcmp (x->name, dir))
982 /* Not found, make a new one. */
983 x = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
986 x->next = CPP_OPTION (pfile, quote_include);
987 x->alloc = pfile->actual_dirs;
988 x->sysp = CPP_BUFFER (pfile)->inc->sysp;
991 pfile->actual_dirs = x;
995 /* Simplify a path name in place, deleting redundant components. This
996 reduces OS overhead and guarantees that equivalent paths compare
997 the same (modulo symlinks).
1000 foo/bar/../quux foo/quux
1004 //quux //quux (POSIX allows leading // as a namespace escape)
1006 Guarantees no trailing slashes. All transforms reduce the length
1010 _cpp_simplify_pathname (path)
1017 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
1018 /* Convert all backslashes to slashes. */
1019 for (from = path; *from; from++)
1020 if (*from == '\\') *from = '/';
1022 /* Skip over leading drive letter if present. */
1023 if (ISALPHA (path[0]) && path[1] == ':')
1024 from = to = &path[2];
1031 /* Remove redundant initial /s. */
1040 /* 3 or more initial /s are equivalent to 1 /. */
1041 while (*++from == '/');
1043 /* On some hosts // differs from /; Posix allows this. */
1051 while (*from == '/')
1054 if (from[0] == '.' && from[1] == '/')
1056 else if (from[0] == '.' && from[1] == '\0')
1058 else if (from[0] == '.' && from[1] == '.' && from[2] == '/')
1075 while (to > base && *to != '/') to--;
1081 else if (from[0] == '.' && from[1] == '.' && from[2] == '\0')
1094 while (to > base && *to != '/') to--;
1101 /* Copy this component and trailing /, if any. */
1102 while ((*to++ = *from++) != '/')
1114 /* Trim trailing slash */
1115 if (to[0] == '/' && (!absolute || to > path+1))
1118 /* Change the empty string to "." so that stat() on the result
1119 will always work. */
1128 /* It is not clear when this should be used if at all, so I've
1129 disabled it until someone who understands VMS can look at it. */
1132 /* Under VMS we need to fix up the "include" specification filename.
1134 Rules for possible conversions
1136 fullname tried paths
1139 ./dir/name [.dir]name
1141 /name [000000]name, name
1142 dir/name dir:[000000]name, dir:name, dir/name
1143 dir1/dir2/name dir1:[dir2]name, dir1:[000000.dir2]name
1144 path:/name path:[000000]name, path:name
1145 path:/dir/name path:[000000.dir]name, path:[dir]name
1146 path:dir/name path:[dir]name
1147 [path]:[dir]name [path.dir]name
1148 path/[dir]name [path.dir]name
1150 The path:/name input is constructed when expanding <> includes. */
1154 hack_vms_include_specification (fullname)
1157 register char *basename, *unixname, *local_ptr, *first_slash;
1158 int f, check_filename_before_returning, must_revert;
1161 check_filename_before_returning = 0;
1163 /* See if we can find a 1st slash. If not, there's no path information. */
1164 first_slash = strchr (fullname, '/');
1165 if (first_slash == 0)
1166 return 0; /* Nothing to do!!! */
1168 /* construct device spec if none given. */
1170 if (strchr (fullname, ':') == 0)
1173 /* If fullname has a slash, take it as device spec. */
1175 if (first_slash == fullname)
1177 first_slash = strchr (fullname + 1, '/'); /* 2nd slash ? */
1179 *first_slash = ':'; /* make device spec */
1180 for (basename = fullname; *basename != 0; basename++)
1181 *basename = *(basename+1); /* remove leading slash */
1183 else if ((first_slash[-1] != '.') /* keep ':/', './' */
1184 && (first_slash[-1] != ':')
1185 && (first_slash[-1] != ']')) /* or a vms path */
1189 else if ((first_slash[1] == '[') /* skip './' in './[dir' */
1190 && (first_slash[-1] == '.'))
1194 /* Get part after first ':' (basename[-1] == ':')
1195 or last '/' (basename[-1] == '/'). */
1197 basename = base_name (fullname);
1199 local_ptr = Local; /* initialize */
1201 /* We are trying to do a number of things here. First of all, we are
1202 trying to hammer the filenames into a standard format, such that later
1203 processing can handle them.
1205 If the file name contains something like [dir.], then it recognizes this
1206 as a root, and strips the ".]". Later processing will add whatever is
1207 needed to get things working properly.
1209 If no device is specified, then the first directory name is taken to be
1210 a device name (or a rooted logical). */
1212 /* Point to the UNIX filename part (which needs to be fixed!)
1213 but skip vms path information.
1214 [basename != fullname since first_slash != 0]. */
1216 if ((basename[-1] == ':') /* vms path spec. */
1217 || (basename[-1] == ']')
1218 || (basename[-1] == '>'))
1219 unixname = basename;
1221 unixname = fullname;
1223 if (*unixname == '/')
1226 /* If the directory spec is not rooted, we can just copy
1227 the UNIX filename part and we are done. */
1229 if (((basename - fullname) > 1)
1230 && ( (basename[-1] == ']')
1231 || (basename[-1] == '>')))
1233 if (basename[-2] != '.')
1236 /* The VMS part ends in a `]', and the preceding character is not a `.'.
1237 -> PATH]:/name (basename = '/name', unixname = 'name')
1238 We strip the `]', and then splice the two parts of the name in the
1239 usual way. Given the default locations for include files,
1240 we will only use this code if the user specifies alternate locations
1241 with the /include (-I) switch on the command line. */
1243 basename -= 1; /* Strip "]" */
1244 unixname--; /* backspace */
1249 /* The VMS part has a ".]" at the end, and this will not do. Later
1250 processing will add a second directory spec, and this would be a syntax
1251 error. Thus we strip the ".]", and thus merge the directory specs.
1252 We also backspace unixname, so that it points to a '/'. This inhibits the
1253 generation of the 000000 root directory spec (which does not belong here
1256 basename -= 2; /* Strip ".]" */
1257 unixname--; /* backspace */
1265 /* We drop in here if there is no VMS style directory specification yet.
1266 If there is no device specification either, we make the first dir a
1267 device and try that. If we do not do this, then we will be essentially
1268 searching the users default directory (as if they did a #include "asdf.h").
1270 Then all we need to do is to push a '[' into the output string. Later
1271 processing will fill this in, and close the bracket. */
1273 if ((unixname != fullname) /* vms path spec found. */
1274 && (basename[-1] != ':'))
1275 *local_ptr++ = ':'; /* dev not in spec. take first dir */
1277 *local_ptr++ = '['; /* Open the directory specification */
1280 if (unixname == fullname) /* no vms dir spec. */
1283 if ((first_slash != 0) /* unix dir spec. */
1284 && (*unixname != '/') /* not beginning with '/' */
1285 && (*unixname != '.')) /* or './' or '../' */
1286 *local_ptr++ = '.'; /* dir is local ! */
1289 /* at this point we assume that we have the device spec, and (at least
1290 the opening "[" for a directory specification. We may have directories
1293 If there are no other slashes then the filename will be
1294 in the "root" directory. Otherwise, we need to add
1295 directory specifications. */
1297 if (strchr (unixname, '/') == 0)
1299 /* if no directories specified yet and none are following. */
1300 if (local_ptr[-1] == '[')
1302 /* Just add "000000]" as the directory string */
1303 strcpy (local_ptr, "000000]");
1304 local_ptr += strlen (local_ptr);
1305 check_filename_before_returning = 1; /* we might need to fool with this later */
1311 /* As long as there are still subdirectories to add, do them. */
1312 while (strchr (unixname, '/') != 0)
1314 /* If this token is "." we can ignore it
1315 if it's not at the beginning of a path. */
1316 if ((unixname[0] == '.') && (unixname[1] == '/'))
1318 /* remove it at beginning of path. */
1319 if ( ((unixname == fullname) /* no device spec */
1320 && (fullname+2 != basename)) /* starts with ./ */
1322 || ((basename[-1] == ':') /* device spec */
1323 && (unixname-1 == basename))) /* and ./ afterwards */
1324 *local_ptr++ = '.'; /* make '[.' start of path. */
1329 /* Add a subdirectory spec. Do not duplicate "." */
1330 if ( local_ptr[-1] != '.'
1331 && local_ptr[-1] != '['
1332 && local_ptr[-1] != '<')
1335 /* If this is ".." then the spec becomes "-" */
1336 if ( (unixname[0] == '.')
1337 && (unixname[1] == '.')
1338 && (unixname[2] == '/'))
1340 /* Add "-" and skip the ".." */
1341 if ((local_ptr[-1] == '.')
1342 && (local_ptr[-2] == '['))
1343 local_ptr--; /* prevent [.- */
1349 /* Copy the subdirectory */
1350 while (*unixname != '/')
1351 *local_ptr++= *unixname++;
1353 unixname++; /* Skip the "/" */
1356 /* Close the directory specification */
1357 if (local_ptr[-1] == '.') /* no trailing periods */
1360 if (local_ptr[-1] == '[') /* no dir needed */
1366 /* Now add the filename. */
1369 *local_ptr++ = *unixname++;
1372 /* Now append it to the original VMS spec. */
1374 strcpy ((must_revert==1)?fullname:basename, Local);
1376 /* If we put a [000000] in the filename, try to open it first. If this fails,
1377 remove the [000000], and return that name. This provides flexibility
1378 to the user in that they can use both rooted and non-rooted logical names
1379 to point to the location of the file. */
1381 if (check_filename_before_returning)
1383 f = open (fullname, O_RDONLY|O_NONBLOCK);
1386 /* The file name is OK as it is, so return it as is. */
1391 /* The filename did not work. Try to remove the [000000] from the name,
1394 basename = strchr (fullname, '[');
1395 local_ptr = strchr (fullname, ']') + 1;
1396 strcpy (basename, local_ptr); /* this gets rid of it */