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 static struct file_name_map *read_name_map
47 PARAMS ((cpp_reader *, const char *));
48 static char *read_filename_string PARAMS ((int, FILE *));
49 static char *remap_filename PARAMS ((cpp_reader *, char *,
50 struct file_name_list *));
51 static struct file_name_list *actual_directory
52 PARAMS ((cpp_reader *, const char *));
53 static struct include_file *find_include_file
54 PARAMS ((cpp_reader *, const char *,
55 struct file_name_list *));
56 static struct include_file *open_include_file
57 PARAMS ((cpp_reader *, const char *));
58 static int read_include_file PARAMS ((cpp_reader *, struct include_file *));
59 static ssize_t read_with_read PARAMS ((cpp_buffer *, int, ssize_t));
60 static ssize_t read_file PARAMS ((cpp_buffer *, int, ssize_t));
62 static void destroy_include_file_node PARAMS ((splay_tree_value));
63 static int close_cached_fd PARAMS ((splay_tree_node, void *));
66 static void hack_vms_include_specification PARAMS ((char *));
69 #ifndef INCLUDE_LEN_FUDGE
70 #define INCLUDE_LEN_FUDGE 0
73 /* We use a splay tree to store information about all the include
74 files seen in this compilation. The key of each tree node is the
75 physical path to the file. The value is 0 if the file does not
76 exist, or a struct include_file pointer. */
79 destroy_include_file_node (v)
82 struct include_file *f = (struct include_file *)v;
92 close_cached_fd (n, dummy)
94 void *dummy ATTRIBUTE_UNUSED;
96 struct include_file *f = (struct include_file *)n->value;
106 _cpp_init_include_table (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);
115 /* Given a filename, look it up and possibly open it. If the file
116 does not exist, return NULL. If the file does exist but doesn't
117 need to be reread, return an include_file entry with fd == -1.
118 If it needs to be (re)read, return an include_file entry with
119 fd a file descriptor open on the file. */
121 static struct include_file *
122 open_include_file (pfile, filename)
124 const char *filename;
127 struct include_file *file = 0;
130 nd = splay_tree_lookup (pfile->all_include_files,
131 (splay_tree_key) filename);
138 file = (struct include_file *)nd->value;
140 if (DO_NOT_REREAD (file))
150 /* File descriptors are cached for files that might be reread. */
153 lseek (file->fd, 0, SEEK_SET);
158 /* We used to open files in nonblocking mode, but that caused more
159 problems than it solved. Do take care not to acquire a
160 controlling terminal by mistake (this can't happen on sane
161 systems, but paranoia is a virtue).
163 Use the three-argument form of open even though we aren't
164 specifying O_CREAT, to defend against broken system headers.
166 O_BINARY tells some runtime libraries (notably DJGPP) not to do
167 newline translation; we can handle DOS line breaks just fine
170 Special case: the empty string is translated to stdin. */
173 if (filename[0] == '\0')
176 fd = open (filename, O_RDONLY|O_NOCTTY|O_BINARY, 0666);
183 cpp_error (pfile, "included file \"%s\" exists but is not readable",
196 /* Too many files open. Close all cached file descriptors and
198 splay_tree_foreach (pfile->all_include_files, close_cached_fd, 0);
202 /* Nonexistent or inaccessible file. Create a negative node for it. */
206 "node for '%s' exists, open failed, error '%s', value %lx\n",
207 filename, strerror (errno), nd->value);
208 destroy_include_file_node (nd->value);
210 splay_tree_insert (pfile->all_include_files,
211 (splay_tree_key) xstrdup (filename), 0);
215 /* If we haven't seen this file before, create a positive node for it. */
218 file = xnew (struct include_file);
220 file->include_count = 0;
223 file->name = xstrdup (filename);
224 splay_tree_insert (pfile->all_include_files,
225 (splay_tree_key) file->name,
226 (splay_tree_value) file);
230 file->date = (time_t) -1;
234 /* Return 1 if the file named by FNAME has been included before in
235 any context, 0 otherwise. */
237 cpp_included (pfile, fname)
241 struct file_name_list *path;
247 /* Just look it up. */
248 nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) fname);
249 return (nd && nd->value);
252 /* Search directory path for the file. */
253 name = (char *) alloca (strlen (fname) + pfile->max_include_len
254 + 2 + INCLUDE_LEN_FUDGE);
255 for (path = CPP_OPTION (pfile, quote_include); path; path = path->next)
257 memcpy (name, path->name, path->nlen);
258 name[path->nlen] = '/';
259 strcpy (&name[path->nlen+1], fname);
260 _cpp_simplify_pathname (name);
261 if (CPP_OPTION (pfile, remap))
262 name = remap_filename (pfile, name, path);
264 nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) name);
271 /* Search for include file FNAME in the include chain starting at
272 SEARCH_START. Return 0 if there is no such file (or it's un-openable),
273 otherwise an include_file structure, possibly with a file descriptor
276 static struct include_file *
277 find_include_file (pfile, fname, search_start)
280 struct file_name_list *search_start;
282 struct file_name_list *path;
284 struct include_file *file;
287 return open_include_file (pfile, fname);
289 /* Search directory path for the file. */
290 name = (char *) alloca (strlen (fname) + pfile->max_include_len
291 + 2 + INCLUDE_LEN_FUDGE);
292 for (path = search_start; path; path = path->next)
294 memcpy (name, path->name, path->nlen);
295 name[path->nlen] = '/';
296 strcpy (&name[path->nlen+1], fname);
297 _cpp_simplify_pathname (name);
298 if (CPP_OPTION (pfile, remap))
299 name = remap_filename (pfile, name, path);
301 file = open_include_file (pfile, name);
304 file->sysp = path->sysp;
305 file->foundhere = path;
312 /* #line uses this to save artificial file names. We have to try
313 opening the file because an all_include_files entry is always
314 either + or -, there's no 'I don't know' value. */
316 _cpp_fake_include (pfile, fname)
321 struct include_file *file;
324 file = find_include_file (pfile, fname, CPP_OPTION (pfile, quote_include));
328 name = xstrdup (fname);
329 _cpp_simplify_pathname (name);
331 /* We cannot just blindly insert a node, because there's still the
332 chance that the node already exists but isn't on the search path. */
333 nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) name);
337 return (const char *) nd->key;
340 splay_tree_insert (pfile->all_include_files, (splay_tree_key) name, 0);
341 return (const char *)name;
344 /* Not everyone who wants to set system-header-ness on a buffer can
345 see the details of struct include_file. This is an exported interface
346 because fix-header needs it. */
348 cpp_make_system_header (pfile, pbuf, flag)
353 if (flag < 0 || flag > 2)
354 cpp_ice (pfile, "cpp_make_system_header: bad flag %d\n", flag);
356 cpp_ice (pfile, "cpp_make_system_header called on non-file buffer");
358 pbuf->inc->sysp = flag;
361 #define PRINT_THIS_DEP(p, b) (CPP_PRINT_DEPS(p) > (b||p->system_include_depth))
363 _cpp_execute_include (pfile, f, len, no_reinclude, search_start, angle_brackets)
368 struct file_name_list *search_start;
371 struct include_file *inc;
377 search_start = CPP_OPTION (pfile, bracket_include);
378 else if (CPP_OPTION (pfile, ignore_srcdir))
379 search_start = CPP_OPTION (pfile, quote_include);
381 search_start = CPP_BUFFER (pfile)->actual_dir;
386 cpp_error (pfile, "No include path in which to find %s", fname);
390 fname = alloca (len + 1);
391 memcpy (fname, f, len);
394 inc = find_include_file (pfile, fname, search_start);
401 /* For -M, add the file to the dependencies on its first inclusion. */
402 if (!inc->include_count && PRINT_THIS_DEP (pfile, angle_brackets))
403 deps_add_dep (pfile->deps, inc->name);
404 inc->include_count++;
406 /* Handle -H option. */
407 if (CPP_OPTION (pfile, print_include_names))
409 cpp_buffer *fp = CPP_BUFFER (pfile);
410 while ((fp = CPP_PREV_BUFFER (fp)) != NULL)
412 fprintf (stderr, " %s\n", inc->name);
415 /* Actually process the file. */
417 inc->cmacro = NEVER_REREAD;
419 if (read_include_file (pfile, inc))
422 pfile->system_include_depth++;
427 if (CPP_OPTION (pfile, print_deps_missing_files)
428 && PRINT_THIS_DEP (pfile, angle_brackets))
431 deps_add_dep (pfile->deps, fname);
435 struct file_name_list *ptr;
436 /* If requested as a system header, assume it belongs in
437 the first system header directory. */
438 if (CPP_OPTION (pfile, bracket_include))
439 ptr = CPP_OPTION (pfile, bracket_include);
441 ptr = CPP_OPTION (pfile, quote_include);
443 p = (char *) alloca (strlen (ptr->name)
444 + strlen (fname) + 2);
445 if (*ptr->name != '\0')
447 strcpy (p, ptr->name);
451 _cpp_simplify_pathname (p);
452 deps_add_dep (pfile->deps, p);
455 /* If -M was specified, and this header file won't be added to
456 the dependency list, then don't count this as an error,
457 because we can still produce correct output. Otherwise, we
458 can't produce correct output, because there may be
459 dependencies we need inside the missing file, and we don't
460 know what directory this missing file exists in. */
461 else if (CPP_PRINT_DEPS (pfile)
462 && ! PRINT_THIS_DEP (pfile, angle_brackets))
463 cpp_warning (pfile, "No include path in which to find %s", fname);
465 cpp_error_from_errno (pfile, fname);
468 /* Locate file F, and determine whether it is newer than PFILE. Return -1,
469 if F cannot be located or dated, 1, if it is newer and 0 if older. */
472 _cpp_compare_file_date (pfile, f, len, angle_brackets)
479 struct file_name_list *search_start;
480 struct include_file *inc;
481 struct include_file *current_include = CPP_BUFFER (pfile)->inc;
484 search_start = CPP_OPTION (pfile, bracket_include);
485 else if (CPP_OPTION (pfile, ignore_srcdir))
486 search_start = CPP_OPTION (pfile, quote_include);
488 search_start = CPP_BUFFER (pfile)->actual_dir;
490 fname = alloca (len + 1);
491 memcpy (fname, f, len);
493 inc = find_include_file (pfile, fname, search_start);
501 if (fstat (inc->fd, &source) < 0)
507 inc->date = source.st_mtime;
511 if (inc->date == (time_t)-1 || current_include->date == (time_t)-1)
513 return inc->date > current_include->date;
517 /* Push an input buffer and load it up with the contents of FNAME.
518 If FNAME is "" or NULL, read standard input. */
520 cpp_read_file (pfile, fname)
524 struct include_file *f;
529 f = open_include_file (pfile, fname);
533 cpp_error_from_errno (pfile, fname);
537 return read_include_file (pfile, f);
540 /* Read the file referenced by INC into a new buffer on PFILE's stack.
541 Return 1 if successful, 0 if not. */
544 read_include_file (pfile, inc)
546 struct include_file *inc;
553 /* Ensures we dump our current line before entering an include file. */
554 if (CPP_BUFFER (pfile) && pfile->printer)
555 cpp_output_tokens (pfile, pfile->printer,
556 CPP_BUF_LINE (CPP_BUFFER (pfile)));
558 fp = cpp_push_buffer (pfile, NULL, 0);
563 if (fd < 0 || fstat (fd, &st) < 0)
566 inc->date = st.st_mtime;
568 /* If fd points to a plain file, we might be able to mmap it; we can
569 definitely allocate the buffer all at once. If fd is a pipe or
570 terminal, we can't do either. If fd is something weird, like a
571 block device or a directory, we don't want to read it at all.
573 Unfortunately, different systems use different st.st_mode values
574 for pipes: some have S_ISFIFO, some S_ISSOCK, some are buggy and
575 zero the entire struct stat except a couple fields. Hence we don't
576 even try to figure out what something is, except for plain files,
577 directories, and block devices. */
579 if (S_ISREG (st.st_mode))
583 /* off_t might have a wider range than ssize_t - in other words,
584 the max size of a file might be bigger than the address
585 space. We can't handle a file that large. (Anyone with
586 a single source file bigger than 2GB needs to rethink
587 their coding style.) Some systems (e.g. AIX 4.1) define
588 SSIZE_MAX to be much smaller than the actual range of the
589 type. Use INTTYPE_MAXIMUM unconditionally to ensure this
591 if (st.st_size > INTTYPE_MAXIMUM (ssize_t))
593 cpp_error (pfile, "%s is too large", inc->name);
596 st_size = st.st_size;
597 length = read_file (fp, fd, st_size);
600 if (length < st_size)
601 cpp_warning (pfile, "%s is shorter than expected\n", inc->name);
603 else if (S_ISBLK (st.st_mode))
605 cpp_error (pfile, "%s is a block device", inc->name);
608 else if (S_ISDIR (st.st_mode))
610 cpp_error (pfile, "%s is a directory", inc->name);
615 /* 8 kilobytes is a sensible starting size. It ought to be
616 bigger than the kernel pipe buffer, and it's definitely
617 bigger than the majority of C source files. */
618 length = read_with_read (fp, fd, 8 * 1024);
623 /* These must be set before prescan. */
625 fp->nominal_fname = inc->name;
626 pfile->include_depth++;
629 inc->cmacro = NEVER_REREAD;
631 fp->rlimit = fp->buf + length;
634 fp->line_base = fp->buf;
636 /* The ->actual_dir field is only used when ignore_srcdir is not in effect;
638 if (!CPP_OPTION (pfile, ignore_srcdir))
639 fp->actual_dir = actual_directory (pfile, inc->name);
641 pfile->input_stack_listing_current = 0;
645 cpp_error_from_errno (pfile, inc->name);
646 /* Do not try to read this file again. */
650 inc->cmacro = NEVER_REREAD;
652 cpp_pop_buffer (pfile);
658 read_file (fp, fd, size)
663 static int pagesize = -1;
669 pagesize = getpagesize ();
672 if (size / pagesize >= MMAP_THRESHOLD)
675 = (const U_CHAR *) mmap (0, size, PROT_READ, MAP_PRIVATE, fd, 0);
676 if (result != (const U_CHAR *)-1)
683 /* If mmap fails, try read. If there's really a problem, read will
687 return read_with_read (fp, fd, size);
691 read_with_read (fp, fd, size)
696 ssize_t offset, count;
699 buf = (U_CHAR *) xmalloc (size);
701 while ((count = read (fd, buf + offset, size - offset)) > 0)
705 buf = xrealloc (buf, (size *= 2));
719 buf = xrealloc (buf, offset);
725 /* The file_name_map structure holds a mapping of file names for a
726 particular directory. This mapping is read from the file named
727 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
728 map filenames on a file system with severe filename restrictions,
729 such as DOS. The format of the file name map file is just a series
730 of lines with two tokens on each line. The first token is the name
731 to map, and the second token is the actual name to use. */
735 struct file_name_map *map_next;
740 #define FILE_NAME_MAP_FILE "header.gcc"
742 /* Read a space delimited string of unlimited length from a stdio
746 read_filename_string (ch, f)
754 set = alloc = xmalloc (len + 1);
758 while ((ch = getc (f)) != EOF && ! is_space(ch))
760 if (set - alloc == len)
763 alloc = xrealloc (alloc, len + 1);
764 set = alloc + len / 2;
774 /* This structure holds a linked list of file name maps, one per directory. */
776 struct file_name_map_list
778 struct file_name_map_list *map_list_next;
780 struct file_name_map *map_list_map;
783 /* Read the file name map file for DIRNAME. */
785 static struct file_name_map *
786 read_name_map (pfile, dirname)
790 register struct file_name_map_list *map_list_ptr;
794 for (map_list_ptr = CPP_OPTION (pfile, map_list); map_list_ptr;
795 map_list_ptr = map_list_ptr->map_list_next)
796 if (! strcmp (map_list_ptr->map_list_name, dirname))
797 return map_list_ptr->map_list_map;
799 map_list_ptr = ((struct file_name_map_list *)
800 xmalloc (sizeof (struct file_name_map_list)));
801 map_list_ptr->map_list_name = xstrdup (dirname);
803 name = (char *) alloca (strlen (dirname) + strlen (FILE_NAME_MAP_FILE) + 2);
804 strcpy (name, dirname);
807 strcat (name, FILE_NAME_MAP_FILE);
808 f = fopen (name, "r");
810 map_list_ptr->map_list_map = (struct file_name_map *)-1;
814 int dirlen = strlen (dirname);
816 while ((ch = getc (f)) != EOF)
819 struct file_name_map *ptr;
823 from = read_filename_string (ch, f);
824 while ((ch = getc (f)) != EOF && is_hspace(ch))
826 to = read_filename_string (ch, f);
828 ptr = ((struct file_name_map *)
829 xmalloc (sizeof (struct file_name_map)));
830 ptr->map_from = from;
832 /* Make the real filename absolute. */
837 ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
838 strcpy (ptr->map_to, dirname);
839 ptr->map_to[dirlen] = '/';
840 strcpy (ptr->map_to + dirlen + 1, to);
844 ptr->map_next = map_list_ptr->map_list_map;
845 map_list_ptr->map_list_map = ptr;
847 while ((ch = getc (f)) != '\n')
854 map_list_ptr->map_list_next = CPP_OPTION (pfile, map_list);
855 CPP_OPTION (pfile, map_list) = map_list_ptr;
857 return map_list_ptr->map_list_map;
860 /* Remap NAME based on the file_name_map (if any) for LOC. */
863 remap_filename (pfile, name, loc)
866 struct file_name_list *loc;
868 struct file_name_map *map;
869 const char *from, *p, *dir;
872 loc->name_map = read_name_map (pfile,
876 if (loc->name_map == (struct file_name_map *)-1)
879 from = name + strlen (loc->name) + 1;
881 for (map = loc->name_map; map; map = map->map_next)
882 if (!strcmp (map->map_from, from))
885 /* Try to find a mapping file for the particular directory we are
886 looking in. Thus #include <sys/types.h> will look up sys/types.h
887 in /usr/include/header.gcc and look up types.h in
888 /usr/include/sys/header.gcc. */
889 p = strrchr (name, '/');
893 && strlen (loc->name) == (size_t) (p - name)
894 && !strncmp (loc->name, name, p - name))
895 /* FILENAME is in SEARCHPTR, which we've already checked. */
905 char * newdir = (char *) alloca (p - name + 1);
906 memcpy (newdir, name, p - name);
907 newdir[p - name] = '\0';
912 for (map = read_name_map (pfile, dir); map; map = map->map_next)
913 if (! strcmp (map->map_from, name))
919 /* Given a path FNAME, extract the directory component and place it
920 onto the actual_dirs list. Return a pointer to the allocated
921 file_name_list structure. These structures are used to implement
922 current-directory "" include searching. */
924 static struct file_name_list *
925 actual_directory (pfile, fname)
929 char *last_slash, *dir;
931 struct file_name_list *x;
933 dir = xstrdup (fname);
934 last_slash = strrchr (dir, '/');
937 if (last_slash == dir)
940 last_slash[1] = '\0';
944 dlen = last_slash - dir;
955 if (dlen > pfile->max_include_len)
956 pfile->max_include_len = dlen;
958 for (x = pfile->actual_dirs; x; x = x->alloc)
959 if (!strcmp (x->name, dir))
965 /* Not found, make a new one. */
966 x = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
969 x->next = CPP_OPTION (pfile, quote_include);
970 x->alloc = pfile->actual_dirs;
971 x->sysp = CPP_BUFFER (pfile)->inc->sysp;
974 pfile->actual_dirs = x;
978 /* Simplify a path name in place, deleting redundant components. This
979 reduces OS overhead and guarantees that equivalent paths compare
980 the same (modulo symlinks).
983 foo/bar/../quux foo/quux
987 //quux //quux (POSIX allows leading // as a namespace escape)
989 Guarantees no trailing slashes. All transforms reduce the length
993 _cpp_simplify_pathname (path)
1000 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
1001 /* Convert all backslashes to slashes. */
1002 for (from = path; *from; from++)
1003 if (*from == '\\') *from = '/';
1005 /* Skip over leading drive letter if present. */
1006 if (ISALPHA (path[0]) && path[1] == ':')
1007 from = to = &path[2];
1014 /* Remove redundant initial /s. */
1023 /* 3 or more initial /s are equivalent to 1 /. */
1024 while (*++from == '/');
1026 /* On some hosts // differs from /; Posix allows this. */
1034 while (*from == '/')
1037 if (from[0] == '.' && from[1] == '/')
1039 else if (from[0] == '.' && from[1] == '\0')
1041 else if (from[0] == '.' && from[1] == '.' && from[2] == '/')
1058 while (to > base && *to != '/') to--;
1064 else if (from[0] == '.' && from[1] == '.' && from[2] == '\0')
1077 while (to > base && *to != '/') to--;
1084 /* Copy this component and trailing /, if any. */
1085 while ((*to++ = *from++) != '/')
1097 /* Trim trailing slash */
1098 if (to[0] == '/' && (!absolute || to > path+1))
1101 /* Change the empty string to "." so that stat() on the result
1102 will always work. */
1111 /* It is not clear when this should be used if at all, so I've
1112 disabled it until someone who understands VMS can look at it. */
1115 /* Under VMS we need to fix up the "include" specification filename.
1117 Rules for possible conversions
1119 fullname tried paths
1122 ./dir/name [.dir]name
1124 /name [000000]name, name
1125 dir/name dir:[000000]name, dir:name, dir/name
1126 dir1/dir2/name dir1:[dir2]name, dir1:[000000.dir2]name
1127 path:/name path:[000000]name, path:name
1128 path:/dir/name path:[000000.dir]name, path:[dir]name
1129 path:dir/name path:[dir]name
1130 [path]:[dir]name [path.dir]name
1131 path/[dir]name [path.dir]name
1133 The path:/name input is constructed when expanding <> includes. */
1137 hack_vms_include_specification (fullname)
1140 register char *basename, *unixname, *local_ptr, *first_slash;
1141 int f, check_filename_before_returning, must_revert;
1144 check_filename_before_returning = 0;
1146 /* See if we can find a 1st slash. If not, there's no path information. */
1147 first_slash = strchr (fullname, '/');
1148 if (first_slash == 0)
1149 return 0; /* Nothing to do!!! */
1151 /* construct device spec if none given. */
1153 if (strchr (fullname, ':') == 0)
1156 /* If fullname has a slash, take it as device spec. */
1158 if (first_slash == fullname)
1160 first_slash = strchr (fullname + 1, '/'); /* 2nd slash ? */
1162 *first_slash = ':'; /* make device spec */
1163 for (basename = fullname; *basename != 0; basename++)
1164 *basename = *(basename+1); /* remove leading slash */
1166 else if ((first_slash[-1] != '.') /* keep ':/', './' */
1167 && (first_slash[-1] != ':')
1168 && (first_slash[-1] != ']')) /* or a vms path */
1172 else if ((first_slash[1] == '[') /* skip './' in './[dir' */
1173 && (first_slash[-1] == '.'))
1177 /* Get part after first ':' (basename[-1] == ':')
1178 or last '/' (basename[-1] == '/'). */
1180 basename = base_name (fullname);
1182 local_ptr = Local; /* initialize */
1184 /* We are trying to do a number of things here. First of all, we are
1185 trying to hammer the filenames into a standard format, such that later
1186 processing can handle them.
1188 If the file name contains something like [dir.], then it recognizes this
1189 as a root, and strips the ".]". Later processing will add whatever is
1190 needed to get things working properly.
1192 If no device is specified, then the first directory name is taken to be
1193 a device name (or a rooted logical). */
1195 /* Point to the UNIX filename part (which needs to be fixed!)
1196 but skip vms path information.
1197 [basename != fullname since first_slash != 0]. */
1199 if ((basename[-1] == ':') /* vms path spec. */
1200 || (basename[-1] == ']')
1201 || (basename[-1] == '>'))
1202 unixname = basename;
1204 unixname = fullname;
1206 if (*unixname == '/')
1209 /* If the directory spec is not rooted, we can just copy
1210 the UNIX filename part and we are done. */
1212 if (((basename - fullname) > 1)
1213 && ( (basename[-1] == ']')
1214 || (basename[-1] == '>')))
1216 if (basename[-2] != '.')
1219 /* The VMS part ends in a `]', and the preceding character is not a `.'.
1220 -> PATH]:/name (basename = '/name', unixname = 'name')
1221 We strip the `]', and then splice the two parts of the name in the
1222 usual way. Given the default locations for include files,
1223 we will only use this code if the user specifies alternate locations
1224 with the /include (-I) switch on the command line. */
1226 basename -= 1; /* Strip "]" */
1227 unixname--; /* backspace */
1232 /* The VMS part has a ".]" at the end, and this will not do. Later
1233 processing will add a second directory spec, and this would be a syntax
1234 error. Thus we strip the ".]", and thus merge the directory specs.
1235 We also backspace unixname, so that it points to a '/'. This inhibits the
1236 generation of the 000000 root directory spec (which does not belong here
1239 basename -= 2; /* Strip ".]" */
1240 unixname--; /* backspace */
1248 /* We drop in here if there is no VMS style directory specification yet.
1249 If there is no device specification either, we make the first dir a
1250 device and try that. If we do not do this, then we will be essentially
1251 searching the users default directory (as if they did a #include "asdf.h").
1253 Then all we need to do is to push a '[' into the output string. Later
1254 processing will fill this in, and close the bracket. */
1256 if ((unixname != fullname) /* vms path spec found. */
1257 && (basename[-1] != ':'))
1258 *local_ptr++ = ':'; /* dev not in spec. take first dir */
1260 *local_ptr++ = '['; /* Open the directory specification */
1263 if (unixname == fullname) /* no vms dir spec. */
1266 if ((first_slash != 0) /* unix dir spec. */
1267 && (*unixname != '/') /* not beginning with '/' */
1268 && (*unixname != '.')) /* or './' or '../' */
1269 *local_ptr++ = '.'; /* dir is local ! */
1272 /* at this point we assume that we have the device spec, and (at least
1273 the opening "[" for a directory specification. We may have directories
1276 If there are no other slashes then the filename will be
1277 in the "root" directory. Otherwise, we need to add
1278 directory specifications. */
1280 if (strchr (unixname, '/') == 0)
1282 /* if no directories specified yet and none are following. */
1283 if (local_ptr[-1] == '[')
1285 /* Just add "000000]" as the directory string */
1286 strcpy (local_ptr, "000000]");
1287 local_ptr += strlen (local_ptr);
1288 check_filename_before_returning = 1; /* we might need to fool with this later */
1294 /* As long as there are still subdirectories to add, do them. */
1295 while (strchr (unixname, '/') != 0)
1297 /* If this token is "." we can ignore it
1298 if it's not at the beginning of a path. */
1299 if ((unixname[0] == '.') && (unixname[1] == '/'))
1301 /* remove it at beginning of path. */
1302 if ( ((unixname == fullname) /* no device spec */
1303 && (fullname+2 != basename)) /* starts with ./ */
1305 || ((basename[-1] == ':') /* device spec */
1306 && (unixname-1 == basename))) /* and ./ afterwards */
1307 *local_ptr++ = '.'; /* make '[.' start of path. */
1312 /* Add a subdirectory spec. Do not duplicate "." */
1313 if ( local_ptr[-1] != '.'
1314 && local_ptr[-1] != '['
1315 && local_ptr[-1] != '<')
1318 /* If this is ".." then the spec becomes "-" */
1319 if ( (unixname[0] == '.')
1320 && (unixname[1] == '.')
1321 && (unixname[2] == '/'))
1323 /* Add "-" and skip the ".." */
1324 if ((local_ptr[-1] == '.')
1325 && (local_ptr[-2] == '['))
1326 local_ptr--; /* prevent [.- */
1332 /* Copy the subdirectory */
1333 while (*unixname != '/')
1334 *local_ptr++= *unixname++;
1336 unixname++; /* Skip the "/" */
1339 /* Close the directory specification */
1340 if (local_ptr[-1] == '.') /* no trailing periods */
1343 if (local_ptr[-1] == '[') /* no dir needed */
1349 /* Now add the filename. */
1352 *local_ptr++ = *unixname++;
1355 /* Now append it to the original VMS spec. */
1357 strcpy ((must_revert==1)?fullname:basename, Local);
1359 /* If we put a [000000] in the filename, try to open it first. If this fails,
1360 remove the [000000], and return that name. This provides flexibility
1361 to the user in that they can use both rooted and non-rooted logical names
1362 to point to the location of the file. */
1364 if (check_filename_before_returning)
1366 f = open (fullname, O_RDONLY|O_NONBLOCK);
1369 /* The file name is OK as it is, so return it as is. */
1374 /* The filename did not work. Try to remove the [000000] from the name,
1377 basename = strchr (fullname, '[');
1378 local_ptr = strchr (fullname, ']') + 1;
1379 strcpy (basename, local_ptr); /* this gets rid of it */