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 *));
64 static int report_missing_guard PARAMS ((splay_tree_node, void *));
67 static void hack_vms_include_specification PARAMS ((char *));
70 #ifndef INCLUDE_LEN_FUDGE
71 #define INCLUDE_LEN_FUDGE 0
74 /* We use a splay tree to store information about all the include
75 files seen in this compilation. The key of each tree node is the
76 physical path to the file. The value is 0 if the file does not
77 exist, or a struct include_file pointer. */
80 destroy_include_file_node (v)
83 struct include_file *f = (struct include_file *)v;
93 close_cached_fd (n, dummy)
95 void *dummy ATTRIBUTE_UNUSED;
97 struct include_file *f = (struct include_file *)n->value;
107 _cpp_init_includes (pfile)
110 pfile->all_include_files
111 = splay_tree_new ((splay_tree_compare_fn) strcmp,
112 (splay_tree_delete_key_fn) free,
113 destroy_include_file_node);
117 _cpp_cleanup_includes (pfile)
120 splay_tree_delete (pfile->all_include_files);
123 /* Given a filename, look it up and possibly open it. If the file
124 does not exist, return NULL. If the file does exist but doesn't
125 need to be reread, return an include_file entry with fd == -1.
126 If it needs to be (re)read, return an include_file entry with
127 fd a file descriptor open on the file. */
129 static struct include_file *
130 open_include_file (pfile, filename)
132 const char *filename;
135 struct include_file *file = 0;
138 nd = splay_tree_lookup (pfile->all_include_files,
139 (splay_tree_key) filename);
146 file = (struct include_file *)nd->value;
148 if (DO_NOT_REREAD (file))
158 /* File descriptors are cached for files that might be reread. */
161 lseek (file->fd, 0, SEEK_SET);
166 /* We used to open files in nonblocking mode, but that caused more
167 problems than it solved. Do take care not to acquire a
168 controlling terminal by mistake (this can't happen on sane
169 systems, but paranoia is a virtue).
171 Use the three-argument form of open even though we aren't
172 specifying O_CREAT, to defend against broken system headers.
174 O_BINARY tells some runtime libraries (notably DJGPP) not to do
175 newline translation; we can handle DOS line breaks just fine
178 Special case: the empty string is translated to stdin. */
181 if (filename[0] == '\0')
184 fd = open (filename, O_RDONLY|O_NOCTTY|O_BINARY, 0666);
191 cpp_error (pfile, "included file \"%s\" exists but is not readable",
204 /* Too many files open. Close all cached file descriptors and
206 splay_tree_foreach (pfile->all_include_files, close_cached_fd, 0);
210 /* Nonexistent or inaccessible file. Create a negative node for it. */
214 "node for '%s' exists, open failed, error '%s', value %lx\n",
215 filename, strerror (errno), nd->value);
216 destroy_include_file_node (nd->value);
218 splay_tree_insert (pfile->all_include_files,
219 (splay_tree_key) xstrdup (filename), 0);
223 /* If we haven't seen this file before, create a positive node for it. */
226 file = xnew (struct include_file);
228 file->include_count = 0;
231 file->name = xstrdup (filename);
232 splay_tree_insert (pfile->all_include_files,
233 (splay_tree_key) file->name,
234 (splay_tree_value) file);
238 file->date = (time_t) -1;
242 /* Return 1 if the file named by FNAME has been included before in
243 any context, 0 otherwise. */
245 cpp_included (pfile, fname)
249 struct file_name_list *path;
255 /* Just look it up. */
256 nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) fname);
257 return (nd && nd->value);
260 /* Search directory path for the file. */
261 name = (char *) alloca (strlen (fname) + pfile->max_include_len
262 + 2 + INCLUDE_LEN_FUDGE);
263 for (path = CPP_OPTION (pfile, quote_include); path; path = path->next)
265 memcpy (name, path->name, path->nlen);
266 name[path->nlen] = '/';
267 strcpy (&name[path->nlen+1], fname);
268 _cpp_simplify_pathname (name);
269 if (CPP_OPTION (pfile, remap))
270 name = remap_filename (pfile, name, path);
272 nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) name);
279 /* Search for include file FNAME in the include chain starting at
280 SEARCH_START. Return 0 if there is no such file (or it's un-openable),
281 otherwise an include_file structure, possibly with a file descriptor
284 static struct include_file *
285 find_include_file (pfile, fname, search_start)
288 struct file_name_list *search_start;
290 struct file_name_list *path;
292 struct include_file *file;
295 return open_include_file (pfile, fname);
297 /* Search directory path for the file. */
298 name = (char *) alloca (strlen (fname) + pfile->max_include_len
299 + 2 + INCLUDE_LEN_FUDGE);
300 for (path = search_start; path; path = path->next)
302 memcpy (name, path->name, path->nlen);
303 name[path->nlen] = '/';
304 strcpy (&name[path->nlen+1], fname);
305 _cpp_simplify_pathname (name);
306 if (CPP_OPTION (pfile, remap))
307 name = remap_filename (pfile, name, path);
309 file = open_include_file (pfile, name);
312 file->sysp = path->sysp;
313 file->foundhere = path;
320 /* #line uses this to save artificial file names. We have to try
321 opening the file because an all_include_files entry is always
322 either + or -, there's no 'I don't know' value. */
324 _cpp_fake_include (pfile, fname)
329 struct include_file *file;
332 file = find_include_file (pfile, fname, CPP_OPTION (pfile, quote_include));
336 name = xstrdup (fname);
337 _cpp_simplify_pathname (name);
339 /* We cannot just blindly insert a node, because there's still the
340 chance that the node already exists but isn't on the search path. */
341 nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) name);
345 return (const char *) nd->key;
348 splay_tree_insert (pfile->all_include_files, (splay_tree_key) name, 0);
349 return (const char *)name;
352 /* Not everyone who wants to set system-header-ness on a buffer can
353 see the details of struct include_file. This is an exported interface
354 because fix-header needs it. */
356 cpp_make_system_header (pfile, pbuf, flag)
361 if (flag < 0 || flag > 2)
362 cpp_ice (pfile, "cpp_make_system_header: bad flag %d\n", flag);
364 cpp_ice (pfile, "cpp_make_system_header called on non-file buffer");
366 pbuf->inc->sysp = flag;
369 /* Report on all files that might benefit from a multiple include guard.
372 _cpp_report_missing_guards (pfile)
376 splay_tree_foreach (pfile->all_include_files, report_missing_guard,
381 report_missing_guard (n, b)
385 struct include_file *f = (struct include_file *) n->value;
386 int *bannerp = (int *)b;
388 if (f && f->cmacro == 0 && f->include_count == 1)
392 fputs (_("Multiple include guards may be useful for:\n"), stderr);
395 fputs (f->name, stderr);
401 #define PRINT_THIS_DEP(p, b) (CPP_PRINT_DEPS(p) > (b||p->system_include_depth))
403 _cpp_execute_include (pfile, f, len, no_reinclude, search_start, angle_brackets)
408 struct file_name_list *search_start;
411 struct include_file *inc;
417 search_start = CPP_OPTION (pfile, bracket_include);
418 else if (CPP_OPTION (pfile, ignore_srcdir))
419 search_start = CPP_OPTION (pfile, quote_include);
421 search_start = CPP_BUFFER (pfile)->actual_dir;
426 cpp_error (pfile, "No include path in which to find %s", fname);
430 fname = alloca (len + 1);
431 memcpy (fname, f, len);
434 inc = find_include_file (pfile, fname, search_start);
441 /* For -M, add the file to the dependencies on its first inclusion. */
442 if (!inc->include_count && PRINT_THIS_DEP (pfile, angle_brackets))
443 deps_add_dep (pfile->deps, inc->name);
444 inc->include_count++;
446 /* Handle -H option. */
447 if (CPP_OPTION (pfile, print_include_names))
449 cpp_buffer *fp = CPP_BUFFER (pfile);
450 while ((fp = CPP_PREV_BUFFER (fp)) != NULL)
452 fprintf (stderr, " %s\n", inc->name);
455 /* Actually process the file. */
457 inc->cmacro = NEVER_REREAD;
459 if (read_include_file (pfile, inc))
462 pfile->system_include_depth++;
467 if (CPP_OPTION (pfile, print_deps_missing_files)
468 && PRINT_THIS_DEP (pfile, angle_brackets))
471 deps_add_dep (pfile->deps, fname);
475 struct file_name_list *ptr;
476 /* If requested as a system header, assume it belongs in
477 the first system header directory. */
478 if (CPP_OPTION (pfile, bracket_include))
479 ptr = CPP_OPTION (pfile, bracket_include);
481 ptr = CPP_OPTION (pfile, quote_include);
483 p = (char *) alloca (strlen (ptr->name)
484 + strlen (fname) + 2);
485 if (*ptr->name != '\0')
487 strcpy (p, ptr->name);
491 _cpp_simplify_pathname (p);
492 deps_add_dep (pfile->deps, p);
495 /* If -M was specified, and this header file won't be added to
496 the dependency list, then don't count this as an error,
497 because we can still produce correct output. Otherwise, we
498 can't produce correct output, because there may be
499 dependencies we need inside the missing file, and we don't
500 know what directory this missing file exists in. */
501 else if (CPP_PRINT_DEPS (pfile)
502 && ! PRINT_THIS_DEP (pfile, angle_brackets))
503 cpp_warning (pfile, "No include path in which to find %s", fname);
505 cpp_error_from_errno (pfile, fname);
508 /* Locate file F, and determine whether it is newer than PFILE. Return -1,
509 if F cannot be located or dated, 1, if it is newer and 0 if older. */
512 _cpp_compare_file_date (pfile, f, len, angle_brackets)
519 struct file_name_list *search_start;
520 struct include_file *inc;
521 struct include_file *current_include = CPP_BUFFER (pfile)->inc;
524 search_start = CPP_OPTION (pfile, bracket_include);
525 else if (CPP_OPTION (pfile, ignore_srcdir))
526 search_start = CPP_OPTION (pfile, quote_include);
528 search_start = CPP_BUFFER (pfile)->actual_dir;
530 fname = alloca (len + 1);
531 memcpy (fname, f, len);
533 inc = find_include_file (pfile, fname, search_start);
541 if (fstat (inc->fd, &source) < 0)
547 inc->date = source.st_mtime;
551 if (inc->date == (time_t)-1 || current_include->date == (time_t)-1)
553 return inc->date > current_include->date;
557 /* Push an input buffer and load it up with the contents of FNAME.
558 If FNAME is "" or NULL, read standard input. */
560 cpp_read_file (pfile, fname)
564 struct include_file *f;
569 f = open_include_file (pfile, fname);
573 cpp_error_from_errno (pfile, fname);
577 return read_include_file (pfile, f);
580 /* Read the file referenced by INC into a new buffer on PFILE's stack.
581 Return 1 if successful, 0 if not. */
584 read_include_file (pfile, inc)
586 struct include_file *inc;
593 /* Ensures we dump our current line before entering an include file. */
594 if (CPP_BUFFER (pfile) && pfile->printer)
595 cpp_output_tokens (pfile, pfile->printer,
596 CPP_BUF_LINE (CPP_BUFFER (pfile)));
598 fp = cpp_push_buffer (pfile, NULL, 0);
603 if (fd < 0 || fstat (fd, &st) < 0)
606 inc->date = st.st_mtime;
608 /* If fd points to a plain file, we might be able to mmap it; we can
609 definitely allocate the buffer all at once. If fd is a pipe or
610 terminal, we can't do either. If fd is something weird, like a
611 block device or a directory, we don't want to read it at all.
613 Unfortunately, different systems use different st.st_mode values
614 for pipes: some have S_ISFIFO, some S_ISSOCK, some are buggy and
615 zero the entire struct stat except a couple fields. Hence we don't
616 even try to figure out what something is, except for plain files,
617 directories, and block devices. */
619 if (S_ISREG (st.st_mode))
623 /* off_t might have a wider range than ssize_t - in other words,
624 the max size of a file might be bigger than the address
625 space. We can't handle a file that large. (Anyone with
626 a single source file bigger than 2GB needs to rethink
627 their coding style.) Some systems (e.g. AIX 4.1) define
628 SSIZE_MAX to be much smaller than the actual range of the
629 type. Use INTTYPE_MAXIMUM unconditionally to ensure this
631 if (st.st_size > INTTYPE_MAXIMUM (ssize_t))
633 cpp_error (pfile, "%s is too large", inc->name);
636 st_size = st.st_size;
637 length = read_file (fp, fd, st_size);
640 if (length < st_size)
641 cpp_warning (pfile, "%s is shorter than expected\n", inc->name);
643 else if (S_ISBLK (st.st_mode))
645 cpp_error (pfile, "%s is a block device", inc->name);
648 else if (S_ISDIR (st.st_mode))
650 cpp_error (pfile, "%s is a directory", inc->name);
655 /* 8 kilobytes is a sensible starting size. It ought to be
656 bigger than the kernel pipe buffer, and it's definitely
657 bigger than the majority of C source files. */
658 length = read_with_read (fp, fd, 8 * 1024);
663 /* These must be set before prescan. */
665 fp->nominal_fname = inc->name;
666 pfile->include_depth++;
669 inc->cmacro = NEVER_REREAD;
671 fp->rlimit = fp->buf + length;
674 fp->line_base = fp->buf;
676 /* The ->actual_dir field is only used when ignore_srcdir is not in effect;
678 if (!CPP_OPTION (pfile, ignore_srcdir))
679 fp->actual_dir = actual_directory (pfile, inc->name);
681 pfile->input_stack_listing_current = 0;
685 cpp_error_from_errno (pfile, inc->name);
686 /* Do not try to read this file again. */
690 inc->cmacro = NEVER_REREAD;
692 cpp_pop_buffer (pfile);
698 read_file (fp, fd, size)
703 static int pagesize = -1;
709 pagesize = getpagesize ();
712 if (size / pagesize >= MMAP_THRESHOLD)
715 = (const U_CHAR *) mmap (0, size, PROT_READ, MAP_PRIVATE, fd, 0);
716 if (result != (const U_CHAR *)-1)
723 /* If mmap fails, try read. If there's really a problem, read will
727 return read_with_read (fp, fd, size);
731 read_with_read (fp, fd, size)
736 ssize_t offset, count;
739 buf = (U_CHAR *) xmalloc (size);
741 while ((count = read (fd, buf + offset, size - offset)) > 0)
745 buf = xrealloc (buf, (size *= 2));
759 buf = xrealloc (buf, offset);
765 /* The file_name_map structure holds a mapping of file names for a
766 particular directory. This mapping is read from the file named
767 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
768 map filenames on a file system with severe filename restrictions,
769 such as DOS. The format of the file name map file is just a series
770 of lines with two tokens on each line. The first token is the name
771 to map, and the second token is the actual name to use. */
775 struct file_name_map *map_next;
780 #define FILE_NAME_MAP_FILE "header.gcc"
782 /* Read a space delimited string of unlimited length from a stdio
786 read_filename_string (ch, f)
794 set = alloc = xmalloc (len + 1);
798 while ((ch = getc (f)) != EOF && ! is_space(ch))
800 if (set - alloc == len)
803 alloc = xrealloc (alloc, len + 1);
804 set = alloc + len / 2;
814 /* This structure holds a linked list of file name maps, one per directory. */
816 struct file_name_map_list
818 struct file_name_map_list *map_list_next;
820 struct file_name_map *map_list_map;
823 /* Read the file name map file for DIRNAME. */
825 static struct file_name_map *
826 read_name_map (pfile, dirname)
830 register struct file_name_map_list *map_list_ptr;
834 for (map_list_ptr = CPP_OPTION (pfile, map_list); map_list_ptr;
835 map_list_ptr = map_list_ptr->map_list_next)
836 if (! strcmp (map_list_ptr->map_list_name, dirname))
837 return map_list_ptr->map_list_map;
839 map_list_ptr = ((struct file_name_map_list *)
840 xmalloc (sizeof (struct file_name_map_list)));
841 map_list_ptr->map_list_name = xstrdup (dirname);
843 name = (char *) alloca (strlen (dirname) + strlen (FILE_NAME_MAP_FILE) + 2);
844 strcpy (name, dirname);
847 strcat (name, FILE_NAME_MAP_FILE);
848 f = fopen (name, "r");
850 map_list_ptr->map_list_map = (struct file_name_map *)-1;
854 int dirlen = strlen (dirname);
856 while ((ch = getc (f)) != EOF)
859 struct file_name_map *ptr;
863 from = read_filename_string (ch, f);
864 while ((ch = getc (f)) != EOF && is_hspace(ch))
866 to = read_filename_string (ch, f);
868 ptr = ((struct file_name_map *)
869 xmalloc (sizeof (struct file_name_map)));
870 ptr->map_from = from;
872 /* Make the real filename absolute. */
877 ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
878 strcpy (ptr->map_to, dirname);
879 ptr->map_to[dirlen] = '/';
880 strcpy (ptr->map_to + dirlen + 1, to);
884 ptr->map_next = map_list_ptr->map_list_map;
885 map_list_ptr->map_list_map = ptr;
887 while ((ch = getc (f)) != '\n')
894 map_list_ptr->map_list_next = CPP_OPTION (pfile, map_list);
895 CPP_OPTION (pfile, map_list) = map_list_ptr;
897 return map_list_ptr->map_list_map;
900 /* Remap NAME based on the file_name_map (if any) for LOC. */
903 remap_filename (pfile, name, loc)
906 struct file_name_list *loc;
908 struct file_name_map *map;
909 const char *from, *p, *dir;
912 loc->name_map = read_name_map (pfile,
916 if (loc->name_map == (struct file_name_map *)-1)
919 from = name + strlen (loc->name) + 1;
921 for (map = loc->name_map; map; map = map->map_next)
922 if (!strcmp (map->map_from, from))
925 /* Try to find a mapping file for the particular directory we are
926 looking in. Thus #include <sys/types.h> will look up sys/types.h
927 in /usr/include/header.gcc and look up types.h in
928 /usr/include/sys/header.gcc. */
929 p = strrchr (name, '/');
933 && strlen (loc->name) == (size_t) (p - name)
934 && !strncmp (loc->name, name, p - name))
935 /* FILENAME is in SEARCHPTR, which we've already checked. */
945 char * newdir = (char *) alloca (p - name + 1);
946 memcpy (newdir, name, p - name);
947 newdir[p - name] = '\0';
952 for (map = read_name_map (pfile, dir); map; map = map->map_next)
953 if (! strcmp (map->map_from, name))
959 /* Given a path FNAME, extract the directory component and place it
960 onto the actual_dirs list. Return a pointer to the allocated
961 file_name_list structure. These structures are used to implement
962 current-directory "" include searching. */
964 static struct file_name_list *
965 actual_directory (pfile, fname)
969 char *last_slash, *dir;
971 struct file_name_list *x;
973 dir = xstrdup (fname);
974 last_slash = strrchr (dir, '/');
977 if (last_slash == dir)
980 last_slash[1] = '\0';
984 dlen = last_slash - dir;
995 if (dlen > pfile->max_include_len)
996 pfile->max_include_len = dlen;
998 for (x = pfile->actual_dirs; x; x = x->alloc)
999 if (!strcmp (x->name, dir))
1005 /* Not found, make a new one. */
1006 x = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
1009 x->next = CPP_OPTION (pfile, quote_include);
1010 x->alloc = pfile->actual_dirs;
1011 x->sysp = CPP_BUFFER (pfile)->inc->sysp;
1014 pfile->actual_dirs = x;
1018 /* Simplify a path name in place, deleting redundant components. This
1019 reduces OS overhead and guarantees that equivalent paths compare
1020 the same (modulo symlinks).
1023 foo/bar/../quux foo/quux
1027 //quux //quux (POSIX allows leading // as a namespace escape)
1029 Guarantees no trailing slashes. All transforms reduce the length
1033 _cpp_simplify_pathname (path)
1040 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
1041 /* Convert all backslashes to slashes. */
1042 for (from = path; *from; from++)
1043 if (*from == '\\') *from = '/';
1045 /* Skip over leading drive letter if present. */
1046 if (ISALPHA (path[0]) && path[1] == ':')
1047 from = to = &path[2];
1054 /* Remove redundant initial /s. */
1063 /* 3 or more initial /s are equivalent to 1 /. */
1064 while (*++from == '/');
1066 /* On some hosts // differs from /; Posix allows this. */
1074 while (*from == '/')
1077 if (from[0] == '.' && from[1] == '/')
1079 else if (from[0] == '.' && from[1] == '\0')
1081 else if (from[0] == '.' && from[1] == '.' && from[2] == '/')
1098 while (to > base && *to != '/') to--;
1104 else if (from[0] == '.' && from[1] == '.' && from[2] == '\0')
1117 while (to > base && *to != '/') to--;
1124 /* Copy this component and trailing /, if any. */
1125 while ((*to++ = *from++) != '/')
1137 /* Trim trailing slash */
1138 if (to[0] == '/' && (!absolute || to > path+1))
1141 /* Change the empty string to "." so that stat() on the result
1142 will always work. */
1151 /* It is not clear when this should be used if at all, so I've
1152 disabled it until someone who understands VMS can look at it. */
1155 /* Under VMS we need to fix up the "include" specification filename.
1157 Rules for possible conversions
1159 fullname tried paths
1162 ./dir/name [.dir]name
1164 /name [000000]name, name
1165 dir/name dir:[000000]name, dir:name, dir/name
1166 dir1/dir2/name dir1:[dir2]name, dir1:[000000.dir2]name
1167 path:/name path:[000000]name, path:name
1168 path:/dir/name path:[000000.dir]name, path:[dir]name
1169 path:dir/name path:[dir]name
1170 [path]:[dir]name [path.dir]name
1171 path/[dir]name [path.dir]name
1173 The path:/name input is constructed when expanding <> includes. */
1177 hack_vms_include_specification (fullname)
1180 register char *basename, *unixname, *local_ptr, *first_slash;
1181 int f, check_filename_before_returning, must_revert;
1184 check_filename_before_returning = 0;
1186 /* See if we can find a 1st slash. If not, there's no path information. */
1187 first_slash = strchr (fullname, '/');
1188 if (first_slash == 0)
1189 return 0; /* Nothing to do!!! */
1191 /* construct device spec if none given. */
1193 if (strchr (fullname, ':') == 0)
1196 /* If fullname has a slash, take it as device spec. */
1198 if (first_slash == fullname)
1200 first_slash = strchr (fullname + 1, '/'); /* 2nd slash ? */
1202 *first_slash = ':'; /* make device spec */
1203 for (basename = fullname; *basename != 0; basename++)
1204 *basename = *(basename+1); /* remove leading slash */
1206 else if ((first_slash[-1] != '.') /* keep ':/', './' */
1207 && (first_slash[-1] != ':')
1208 && (first_slash[-1] != ']')) /* or a vms path */
1212 else if ((first_slash[1] == '[') /* skip './' in './[dir' */
1213 && (first_slash[-1] == '.'))
1217 /* Get part after first ':' (basename[-1] == ':')
1218 or last '/' (basename[-1] == '/'). */
1220 basename = base_name (fullname);
1222 local_ptr = Local; /* initialize */
1224 /* We are trying to do a number of things here. First of all, we are
1225 trying to hammer the filenames into a standard format, such that later
1226 processing can handle them.
1228 If the file name contains something like [dir.], then it recognizes this
1229 as a root, and strips the ".]". Later processing will add whatever is
1230 needed to get things working properly.
1232 If no device is specified, then the first directory name is taken to be
1233 a device name (or a rooted logical). */
1235 /* Point to the UNIX filename part (which needs to be fixed!)
1236 but skip vms path information.
1237 [basename != fullname since first_slash != 0]. */
1239 if ((basename[-1] == ':') /* vms path spec. */
1240 || (basename[-1] == ']')
1241 || (basename[-1] == '>'))
1242 unixname = basename;
1244 unixname = fullname;
1246 if (*unixname == '/')
1249 /* If the directory spec is not rooted, we can just copy
1250 the UNIX filename part and we are done. */
1252 if (((basename - fullname) > 1)
1253 && ( (basename[-1] == ']')
1254 || (basename[-1] == '>')))
1256 if (basename[-2] != '.')
1259 /* The VMS part ends in a `]', and the preceding character is not a `.'.
1260 -> PATH]:/name (basename = '/name', unixname = 'name')
1261 We strip the `]', and then splice the two parts of the name in the
1262 usual way. Given the default locations for include files,
1263 we will only use this code if the user specifies alternate locations
1264 with the /include (-I) switch on the command line. */
1266 basename -= 1; /* Strip "]" */
1267 unixname--; /* backspace */
1272 /* The VMS part has a ".]" at the end, and this will not do. Later
1273 processing will add a second directory spec, and this would be a syntax
1274 error. Thus we strip the ".]", and thus merge the directory specs.
1275 We also backspace unixname, so that it points to a '/'. This inhibits the
1276 generation of the 000000 root directory spec (which does not belong here
1279 basename -= 2; /* Strip ".]" */
1280 unixname--; /* backspace */
1288 /* We drop in here if there is no VMS style directory specification yet.
1289 If there is no device specification either, we make the first dir a
1290 device and try that. If we do not do this, then we will be essentially
1291 searching the users default directory (as if they did a #include "asdf.h").
1293 Then all we need to do is to push a '[' into the output string. Later
1294 processing will fill this in, and close the bracket. */
1296 if ((unixname != fullname) /* vms path spec found. */
1297 && (basename[-1] != ':'))
1298 *local_ptr++ = ':'; /* dev not in spec. take first dir */
1300 *local_ptr++ = '['; /* Open the directory specification */
1303 if (unixname == fullname) /* no vms dir spec. */
1306 if ((first_slash != 0) /* unix dir spec. */
1307 && (*unixname != '/') /* not beginning with '/' */
1308 && (*unixname != '.')) /* or './' or '../' */
1309 *local_ptr++ = '.'; /* dir is local ! */
1312 /* at this point we assume that we have the device spec, and (at least
1313 the opening "[" for a directory specification. We may have directories
1316 If there are no other slashes then the filename will be
1317 in the "root" directory. Otherwise, we need to add
1318 directory specifications. */
1320 if (strchr (unixname, '/') == 0)
1322 /* if no directories specified yet and none are following. */
1323 if (local_ptr[-1] == '[')
1325 /* Just add "000000]" as the directory string */
1326 strcpy (local_ptr, "000000]");
1327 local_ptr += strlen (local_ptr);
1328 check_filename_before_returning = 1; /* we might need to fool with this later */
1334 /* As long as there are still subdirectories to add, do them. */
1335 while (strchr (unixname, '/') != 0)
1337 /* If this token is "." we can ignore it
1338 if it's not at the beginning of a path. */
1339 if ((unixname[0] == '.') && (unixname[1] == '/'))
1341 /* remove it at beginning of path. */
1342 if ( ((unixname == fullname) /* no device spec */
1343 && (fullname+2 != basename)) /* starts with ./ */
1345 || ((basename[-1] == ':') /* device spec */
1346 && (unixname-1 == basename))) /* and ./ afterwards */
1347 *local_ptr++ = '.'; /* make '[.' start of path. */
1352 /* Add a subdirectory spec. Do not duplicate "." */
1353 if ( local_ptr[-1] != '.'
1354 && local_ptr[-1] != '['
1355 && local_ptr[-1] != '<')
1358 /* If this is ".." then the spec becomes "-" */
1359 if ( (unixname[0] == '.')
1360 && (unixname[1] == '.')
1361 && (unixname[2] == '/'))
1363 /* Add "-" and skip the ".." */
1364 if ((local_ptr[-1] == '.')
1365 && (local_ptr[-2] == '['))
1366 local_ptr--; /* prevent [.- */
1372 /* Copy the subdirectory */
1373 while (*unixname != '/')
1374 *local_ptr++= *unixname++;
1376 unixname++; /* Skip the "/" */
1379 /* Close the directory specification */
1380 if (local_ptr[-1] == '.') /* no trailing periods */
1383 if (local_ptr[-1] == '[') /* no dir needed */
1389 /* Now add the filename. */
1392 *local_ptr++ = *unixname++;
1395 /* Now append it to the original VMS spec. */
1397 strcpy ((must_revert==1)?fullname:basename, Local);
1399 /* If we put a [000000] in the filename, try to open it first. If this fails,
1400 remove the [000000], and return that name. This provides flexibility
1401 to the user in that they can use both rooted and non-rooted logical names
1402 to point to the location of the file. */
1404 if (check_filename_before_returning)
1406 f = open (fullname, O_RDONLY|O_NONBLOCK);
1409 /* The file name is OK as it is, so return it as is. */
1414 /* The filename did not work. Try to remove the [000000] from the name,
1417 basename = strchr (fullname, '[');
1418 local_ptr = strchr (fullname, ']') + 1;
1419 strcpy (basename, local_ptr); /* this gets rid of it */