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.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding! */
35 static IHASH *redundant_include_p PARAMS ((cpp_reader *, IHASH *,
36 struct file_name_list *));
37 static struct file_name_map *read_name_map
38 PARAMS ((cpp_reader *, const char *));
39 static char *read_filename_string PARAMS ((int, FILE *));
40 static char *remap_filename PARAMS ((cpp_reader *, char *,
41 struct file_name_list *));
42 static struct file_name_list *actual_directory
43 PARAMS ((cpp_reader *, const char *));
44 static unsigned int hash_IHASH PARAMS ((const void *));
45 static int eq_IHASH PARAMS ((const void *, const void *));
46 static int file_cleanup PARAMS ((cpp_buffer *, cpp_reader *));
47 static int find_include_file PARAMS ((cpp_reader *, const char *,
48 struct file_name_list *,
50 static int read_include_file PARAMS ((cpp_reader *, int, IHASH *));
51 static inline int open_include_file PARAMS ((cpp_reader *, const char *));
54 static void hack_vms_include_specification PARAMS ((char *));
57 /* Initial size of include hash table. */
60 #ifndef INCLUDE_LEN_FUDGE
61 #define INCLUDE_LEN_FUDGE 0
64 /* Calculate hash of an IHASH entry. */
69 const IHASH *i = (const IHASH *)x;
73 /* Compare an existing IHASH structure with a potential one. */
79 const U_CHAR *a = ((const IHASH *)x)->nshort;
80 const U_CHAR *b = ((const IHASH *)y)->nshort;
81 return !strcmp (a, b);
84 /* Init the hash table. In here so it can see the hash and eq functions. */
86 _cpp_init_include_hash (pfile)
89 pfile->all_include_files
90 = htab_create (IHASHSIZE, hash_IHASH, eq_IHASH, free);
93 /* Return 0 if the file pointed to by IHASH has never been included before,
94 -1 if it has been included before and need not be again,
95 or a pointer to an IHASH entry which is the file to be reread.
96 "Never before" is with respect to the position in ILIST.
98 This will not detect redundancies involving odd uses of the
99 `current directory' rule for "" includes. They aren't quite
100 pathological, but I think they are rare enough not to worry about.
101 The simplest example is:
110 and the problem is that for `current directory' includes,
111 ihash->foundhere is not on any of the global include chains,
112 so the test below (i->foundhere == l) may be false even when
113 the directories are in fact the same. */
116 redundant_include_p (pfile, ihash, ilist)
119 struct file_name_list *ilist;
121 struct file_name_list *l;
124 if (! ihash->foundhere)
127 for (i = ihash; i; i = i->next_this_file)
128 for (l = ilist; l; l = l->next)
129 if (i->foundhere == l)
130 /* The control_macro works like this: If it's NULL, the file
131 is to be included again. If it's "", the file is never to
132 be included again. If it's a string, the file is not to be
133 included again if the string is the name of a defined macro. */
134 return (i->control_macro
135 && (i->control_macro[0] == '\0'
136 || cpp_defined (pfile, i->control_macro, -1)))
142 /* Return 1 if the file named by FNAME has been included before in
143 any context, 0 otherwise. */
145 cpp_included (pfile, fname)
150 dummy.nshort = fname;
151 dummy.hash = _cpp_calc_hash (fname, strlen (fname));
152 ptr = htab_find_with_hash (pfile->all_include_files,
153 (const void *)&dummy, dummy.hash);
154 return (ptr != NULL);
158 file_cleanup (pbuf, pfile)
163 free ((PTR) pbuf->buf);
164 if (pfile->system_include_depth)
165 pfile->system_include_depth--;
169 /* Centralize calls to open(2) here. This provides a hook for future
170 changes which might, e.g. look for and open a precompiled version
171 of the header. It also means all the magic currently associated
172 with calling open is in one place, and if we ever need more, it'll
175 Open files in nonblocking mode, so we don't get stuck if someone
176 clever has asked cpp to process /dev/rmt0. read_include_file
177 will check that we have a real file to work with. Also take care
178 not to acquire a controlling terminal by mistake (this can't happen
179 on sane systems, but paranoia is a virtue).
181 Use the three-argument form of open even though we aren't
182 specifying O_CREAT, to defend against broken system headers. */
185 open_include_file (pfile, filename)
186 cpp_reader *pfile ATTRIBUTE_UNUSED;
187 const char *filename;
189 return open (filename, O_RDONLY|O_NONBLOCK|O_NOCTTY, 0666);
192 /* Search for include file FNAME in the include chain starting at
193 SEARCH_START. Return -2 if this file doesn't need to be included
194 (because it was included already and it's marked idempotent),
195 -1 if an error occurred, or a file descriptor open on the file.
196 *IHASH is set to point to the include hash entry for this file, and
197 *BEFORE is set to 1 if the file was included before (but needs to be read
200 find_include_file (pfile, fname, search_start, ihash, before)
203 struct file_name_list *search_start;
207 struct file_name_list *path;
213 dummy.nshort = fname;
214 dummy.hash = _cpp_calc_hash (fname, strlen (fname));
215 path = (fname[0] == '/') ? ABSOLUTE_PATH : search_start;
216 slot = (IHASH **) htab_find_slot_with_hash (pfile->all_include_files,
217 (const void *)&dummy,
220 if (*slot && (ih = redundant_include_p (pfile, *slot, path)))
222 if (ih == (IHASH *)-1)
227 return open_include_file (pfile, ih->name);
230 if (path == ABSOLUTE_PATH)
232 name = (char *) fname;
233 f = open_include_file (pfile, name);
237 /* Search directory path, trying to open the file. */
238 name = alloca (strlen (fname) + pfile->max_include_len
239 + 2 + INCLUDE_LEN_FUDGE);
242 memcpy (name, path->name, path->nlen);
243 name[path->nlen] = '/';
244 strcpy (&name[path->nlen+1], fname);
245 _cpp_simplify_pathname (name);
246 if (CPP_OPTION (pfile, remap))
247 name = remap_filename (pfile, name, path);
249 f = open_include_file (pfile, name);
251 if (f == -1 && errno == EACCES)
254 "included file `%s' exists but is not readable",
268 if (path == ABSOLUTE_PATH)
270 ih = (IHASH *) xmalloc (sizeof (IHASH) + strlen (name));
271 ih->nshort = ih->name;
277 if ((s = strstr (name, fname)) != NULL)
279 ih = (IHASH *) xmalloc (sizeof (IHASH) + strlen (name));
280 ih->nshort = ih->name + (s - name);
284 ih = (IHASH *) xmalloc (sizeof (IHASH) + strlen (name)
285 + strlen (fname) + 1);
286 ih->nshort = ih->name + strlen (name) + 1;
287 strcpy ((char *)ih->nshort, fname);
290 strcpy ((char *)ih->name, name);
291 ih->foundhere = path;
292 ih->control_macro = NULL;
293 ih->hash = dummy.hash;
295 ih->next_this_file = *slot;
303 /* The file_name_map structure holds a mapping of file names for a
304 particular directory. This mapping is read from the file named
305 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
306 map filenames on a file system with severe filename restrictions,
307 such as DOS. The format of the file name map file is just a series
308 of lines with two tokens on each line. The first token is the name
309 to map, and the second token is the actual name to use. */
313 struct file_name_map *map_next;
318 #define FILE_NAME_MAP_FILE "header.gcc"
320 /* Read a space delimited string of unlimited length from a stdio
324 read_filename_string (ch, f)
332 set = alloc = xmalloc (len + 1);
336 while ((ch = getc (f)) != EOF && ! is_space(ch))
338 if (set - alloc == len)
341 alloc = xrealloc (alloc, len + 1);
342 set = alloc + len / 2;
352 /* This structure holds a linked list of file name maps, one per directory. */
354 struct file_name_map_list
356 struct file_name_map_list *map_list_next;
358 struct file_name_map *map_list_map;
361 /* Read the file name map file for DIRNAME. */
363 static struct file_name_map *
364 read_name_map (pfile, dirname)
368 register struct file_name_map_list *map_list_ptr;
372 for (map_list_ptr = CPP_OPTION (pfile, map_list); map_list_ptr;
373 map_list_ptr = map_list_ptr->map_list_next)
374 if (! strcmp (map_list_ptr->map_list_name, dirname))
375 return map_list_ptr->map_list_map;
377 map_list_ptr = ((struct file_name_map_list *)
378 xmalloc (sizeof (struct file_name_map_list)));
379 map_list_ptr->map_list_name = xstrdup (dirname);
381 name = (char *) alloca (strlen (dirname) + strlen (FILE_NAME_MAP_FILE) + 2);
382 strcpy (name, dirname);
385 strcat (name, FILE_NAME_MAP_FILE);
386 f = fopen (name, "r");
388 map_list_ptr->map_list_map = (struct file_name_map *)-1;
392 int dirlen = strlen (dirname);
394 while ((ch = getc (f)) != EOF)
397 struct file_name_map *ptr;
401 from = read_filename_string (ch, f);
402 while ((ch = getc (f)) != EOF && is_hspace(ch))
404 to = read_filename_string (ch, f);
406 ptr = ((struct file_name_map *)
407 xmalloc (sizeof (struct file_name_map)));
408 ptr->map_from = from;
410 /* Make the real filename absolute. */
415 ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
416 strcpy (ptr->map_to, dirname);
417 ptr->map_to[dirlen] = '/';
418 strcpy (ptr->map_to + dirlen + 1, to);
422 ptr->map_next = map_list_ptr->map_list_map;
423 map_list_ptr->map_list_map = ptr;
425 while ((ch = getc (f)) != '\n')
432 map_list_ptr->map_list_next = CPP_OPTION (pfile, map_list);
433 CPP_OPTION (pfile, map_list) = map_list_ptr;
435 return map_list_ptr->map_list_map;
438 /* Remap NAME based on the file_name_map (if any) for LOC. */
441 remap_filename (pfile, name, loc)
444 struct file_name_list *loc;
446 struct file_name_map *map;
447 const char *from, *p, *dir;
450 loc->name_map = read_name_map (pfile,
454 if (loc->name_map == (struct file_name_map *)-1)
457 from = name + strlen (loc->name) + 1;
459 for (map = loc->name_map; map; map = map->map_next)
460 if (!strcmp (map->map_from, from))
463 /* Try to find a mapping file for the particular directory we are
464 looking in. Thus #include <sys/types.h> will look up sys/types.h
465 in /usr/include/header.gcc and look up types.h in
466 /usr/include/sys/header.gcc. */
467 p = strrchr (name, '/');
471 && strlen (loc->name) == (size_t) (p - name)
472 && !strncmp (loc->name, name, p - name))
473 /* FILENAME is in SEARCHPTR, which we've already checked. */
483 char * newdir = (char *) alloca (p - name + 1);
484 memcpy (newdir, name, p - name);
485 newdir[p - name] = '\0';
490 for (map = read_name_map (pfile, dir); map; map = map->map_next)
491 if (! strcmp (map->map_from, name))
499 _cpp_execute_include (pfile, fname, len, no_reinclude, search_start)
504 struct file_name_list *search_start;
508 int angle_brackets = fname[0] == '<';
514 search_start = CPP_OPTION (pfile, bracket_include);
515 else if (CPP_OPTION (pfile, ignore_srcdir))
516 search_start = CPP_OPTION (pfile, quote_include);
518 search_start = CPP_BUFFER (pfile)->actual_dir;
523 cpp_error (pfile, "No include path in which to find %s", fname);
527 /* Remove quote marks. */
532 fd = find_include_file (pfile, fname, search_start, &ihash, &before);
539 if (CPP_OPTION (pfile, print_deps_missing_files)
540 && CPP_PRINT_DEPS (pfile) > (angle_brackets ||
541 (pfile->system_include_depth > 0)))
544 deps_add_dep (pfile->deps, fname);
548 struct file_name_list *ptr;
549 /* If requested as a system header, assume it belongs in
550 the first system header directory. */
551 if (CPP_OPTION (pfile, bracket_include))
552 ptr = CPP_OPTION (pfile, bracket_include);
554 ptr = CPP_OPTION (pfile, quote_include);
556 p = (char *) alloca (strlen (ptr->name)
557 + strlen (fname) + 2);
558 if (*ptr->name != '\0')
560 strcpy (p, ptr->name);
564 deps_add_dep (pfile->deps, p);
567 /* If -M was specified, and this header file won't be added to
568 the dependency list, then don't count this as an error,
569 because we can still produce correct output. Otherwise, we
570 can't produce correct output, because there may be
571 dependencies we need inside the missing file, and we don't
572 know what directory this missing file exists in. */
573 else if (CPP_PRINT_DEPS (pfile)
574 && (CPP_PRINT_DEPS (pfile)
575 <= (angle_brackets || (pfile->system_include_depth > 0))))
576 cpp_warning (pfile, "No include path in which to find %s", fname);
578 cpp_error_from_errno (pfile, fname);
583 /* For -M, add the file to the dependencies on its first inclusion. */
584 if (!before && (CPP_PRINT_DEPS (pfile)
585 > (angle_brackets || (pfile->system_include_depth > 0))))
586 deps_add_dep (pfile->deps, ihash->name);
588 /* Handle -H option. */
589 if (CPP_OPTION (pfile, print_include_names))
591 cpp_buffer *fp = CPP_BUFFER (pfile);
592 while ((fp = CPP_PREV_BUFFER (fp)) != NULL)
594 fprintf (stderr, " %s\n", ihash->name);
597 /* Actually process the file */
600 ihash->control_macro = (const U_CHAR *) "";
602 if (read_include_file (pfile, fd, ihash))
604 _cpp_output_line_command (pfile, enter_file);
606 pfile->system_include_depth++; /* Decremented in file_cleanup. */
611 /* Push an input buffer and load it up with the contents of FNAME.
612 If FNAME is "" or NULL, read standard input. */
614 cpp_read_file (pfile, fname)
625 dummy.nshort = fname;
626 /* _cpp_calc_hash doesn't like zero-length strings. */
630 dummy.hash = _cpp_calc_hash (fname, strlen (fname));
631 slot = (IHASH **) htab_find_slot_with_hash (pfile->all_include_files,
632 (const void *) &dummy,
634 if (*slot && (ih = redundant_include_p (pfile, *slot, ABSOLUTE_PATH)))
636 if (ih == (IHASH *)-1)
637 return 1; /* Already included. */
641 ih = (IHASH *) xmalloc (sizeof (IHASH) + strlen (fname));
642 ih->control_macro = 0;
643 ih->foundhere = ABSOLUTE_PATH; /* well sort of ... */
644 ih->hash = dummy.hash;
645 strcpy ((char *)ih->name, fname);
646 ih->nshort = ih->name;
648 ih->next_this_file = *slot;
655 f = open_include_file (pfile, fname);
657 return read_include_file (pfile, f, ih);
660 /* Read the contents of FD into the buffer on the top of PFILE's stack.
661 IHASH points to the include hash entry for the file associated with
664 The caller is responsible for the cpp_push_buffer. */
667 read_include_file (pfile, fd, ihash)
677 fp = cpp_push_buffer (pfile, NULL, 0);
682 if (fstat (fd, &st) < 0)
684 if (fcntl (fd, F_SETFL, 0) == -1) /* turn off nonblocking mode */
687 /* If fd points to a plain file, we know how big it is, so we can
688 allocate the buffer all at once. If fd is a pipe or terminal, we
689 can't. Most C source files are 4k or less, so we guess that. If
690 fd is something weird, like a block device or a directory, we
691 don't want to read it at all.
693 Unfortunately, different systems use different st.st_mode values
694 for pipes: some have S_ISFIFO, some S_ISSOCK, some are buggy and
695 zero the entire struct stat except a couple fields. Hence the
698 In all cases, read_and_prescan will resize the buffer if it
699 turns out there's more data than we thought. */
701 if (S_ISREG (st.st_mode))
703 /* off_t might have a wider range than size_t - in other words,
704 the max size of a file might be bigger than the address
705 space. We can't handle a file that large. (Anyone with
706 a single source file bigger than 4GB needs to rethink
707 their coding style.) */
708 st_size = (size_t) st.st_size;
709 if ((unsigned HOST_WIDEST_INT) st_size
710 != (unsigned HOST_WIDEST_INT) st.st_size)
712 cpp_error (pfile, "file `%s' is too large", ihash->name);
716 else if (S_ISFIFO (st.st_mode) || S_ISSOCK (st.st_mode)
717 /* Permit any kind of character device: the sensible ones are
718 ttys and /dev/null, but weeding out the others is too hard. */
719 || S_ISCHR (st.st_mode)
720 /* Some 4.x (x<4) derivatives have a bug that makes fstat() of a
721 socket or pipe return a stat struct with most fields zeroed. */
722 || (st.st_mode == 0 && st.st_nlink == 0 && st.st_size == 0))
724 /* Cannot get its file size before reading. 4k is a decent
730 cpp_error (pfile, "`%s' is not a file, pipe, or tty", ihash->name);
734 /* Read the file, converting end-of-line characters and trigraphs
737 fp->nominal_fname = ihash->name;
738 length = _cpp_read_and_prescan (pfile, fp, fd, st_size);
742 ihash->control_macro = (const U_CHAR *) ""; /* never re-include */
745 fp->rlimit = fp->alimit = fp->buf + length;
747 if (ihash->foundhere != ABSOLUTE_PATH)
748 fp->system_header_p = ihash->foundhere->sysp;
751 fp->line_base = fp->buf;
752 fp->cleanup = file_cleanup;
754 /* The ->actual_dir field is only used when ignore_srcdir is not in effect;
756 if (!CPP_OPTION (pfile, ignore_srcdir))
757 fp->actual_dir = actual_directory (pfile, ihash->name);
759 pfile->input_stack_listing_current = 0;
760 pfile->only_seen_white = 2;
764 cpp_error_from_errno (pfile, ihash->name);
766 cpp_pop_buffer (pfile);
772 /* Given a path FNAME, extract the directory component and place it
773 onto the actual_dirs list. Return a pointer to the allocated
774 file_name_list structure. These structures are used to implement
775 current-directory "" include searching. */
777 static struct file_name_list *
778 actual_directory (pfile, fname)
782 char *last_slash, *dir;
784 struct file_name_list *x;
786 dir = xstrdup (fname);
787 last_slash = strrchr (dir, '/');
790 if (last_slash == dir)
793 last_slash[1] = '\0';
797 dlen = last_slash - dir;
808 if (dlen > pfile->max_include_len)
809 pfile->max_include_len = dlen;
811 for (x = pfile->actual_dirs; x; x = x->alloc)
812 if (!strcmp (x->name, dir))
818 /* Not found, make a new one. */
819 x = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
822 x->next = CPP_OPTION (pfile, quote_include);
823 x->alloc = pfile->actual_dirs;
824 x->sysp = CPP_BUFFER (pfile)->system_header_p;
827 pfile->actual_dirs = x;
831 /* Simplify a path name in place, deleting redundant components. This
832 reduces OS overhead and guarantees that equivalent paths compare
833 the same (modulo symlinks).
836 foo/bar/../quux foo/quux
840 //quux //quux (POSIX allows leading // as a namespace escape)
842 Guarantees no trailing slashes. All transforms reduce the length
846 _cpp_simplify_pathname (path)
853 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
854 /* Convert all backslashes to slashes. */
855 for (from = path; *from; from++)
856 if (*from == '\\') *from = '/';
858 /* Skip over leading drive letter if present. */
859 if (ISALPHA (path[0]) && path[1] == ':')
860 from = to = &path[2];
867 /* Remove redundant initial /s. */
876 /* 3 or more initial /s are equivalent to 1 /. */
877 while (*++from == '/');
879 /* On some hosts // differs from /; Posix allows this. */
890 if (from[0] == '.' && from[1] == '/')
892 else if (from[0] == '.' && from[1] == '\0')
894 else if (from[0] == '.' && from[1] == '.' && from[2] == '/')
911 while (to > base && *to != '/') to--;
917 else if (from[0] == '.' && from[1] == '.' && from[2] == '\0')
930 while (to > base && *to != '/') to--;
937 /* Copy this component and trailing /, if any. */
938 while ((*to++ = *from++) != '/')
950 /* Trim trailing slash */
951 if (to[0] == '/' && (!absolute || to > path+1))
954 /* Change the empty string to "." so that stat() on the result
964 /* It is not clear when this should be used if at all, so I've
965 disabled it until someone who understands VMS can look at it. */
968 /* Under VMS we need to fix up the "include" specification filename.
970 Rules for possible conversions
975 ./dir/name [.dir]name
977 /name [000000]name, name
978 dir/name dir:[000000]name, dir:name, dir/name
979 dir1/dir2/name dir1:[dir2]name, dir1:[000000.dir2]name
980 path:/name path:[000000]name, path:name
981 path:/dir/name path:[000000.dir]name, path:[dir]name
982 path:dir/name path:[dir]name
983 [path]:[dir]name [path.dir]name
984 path/[dir]name [path.dir]name
986 The path:/name input is constructed when expanding <> includes. */
990 hack_vms_include_specification (fullname)
993 register char *basename, *unixname, *local_ptr, *first_slash;
994 int f, check_filename_before_returning, must_revert;
997 check_filename_before_returning = 0;
999 /* See if we can find a 1st slash. If not, there's no path information. */
1000 first_slash = strchr (fullname, '/');
1001 if (first_slash == 0)
1002 return 0; /* Nothing to do!!! */
1004 /* construct device spec if none given. */
1006 if (strchr (fullname, ':') == 0)
1009 /* If fullname has a slash, take it as device spec. */
1011 if (first_slash == fullname)
1013 first_slash = strchr (fullname + 1, '/'); /* 2nd slash ? */
1015 *first_slash = ':'; /* make device spec */
1016 for (basename = fullname; *basename != 0; basename++)
1017 *basename = *(basename+1); /* remove leading slash */
1019 else if ((first_slash[-1] != '.') /* keep ':/', './' */
1020 && (first_slash[-1] != ':')
1021 && (first_slash[-1] != ']')) /* or a vms path */
1025 else if ((first_slash[1] == '[') /* skip './' in './[dir' */
1026 && (first_slash[-1] == '.'))
1030 /* Get part after first ':' (basename[-1] == ':')
1031 or last '/' (basename[-1] == '/'). */
1033 basename = base_name (fullname);
1035 local_ptr = Local; /* initialize */
1037 /* We are trying to do a number of things here. First of all, we are
1038 trying to hammer the filenames into a standard format, such that later
1039 processing can handle them.
1041 If the file name contains something like [dir.], then it recognizes this
1042 as a root, and strips the ".]". Later processing will add whatever is
1043 needed to get things working properly.
1045 If no device is specified, then the first directory name is taken to be
1046 a device name (or a rooted logical). */
1048 /* Point to the UNIX filename part (which needs to be fixed!)
1049 but skip vms path information.
1050 [basename != fullname since first_slash != 0]. */
1052 if ((basename[-1] == ':') /* vms path spec. */
1053 || (basename[-1] == ']')
1054 || (basename[-1] == '>'))
1055 unixname = basename;
1057 unixname = fullname;
1059 if (*unixname == '/')
1062 /* If the directory spec is not rooted, we can just copy
1063 the UNIX filename part and we are done. */
1065 if (((basename - fullname) > 1)
1066 && ( (basename[-1] == ']')
1067 || (basename[-1] == '>')))
1069 if (basename[-2] != '.')
1072 /* The VMS part ends in a `]', and the preceding character is not a `.'.
1073 -> PATH]:/name (basename = '/name', unixname = 'name')
1074 We strip the `]', and then splice the two parts of the name in the
1075 usual way. Given the default locations for include files in cccp.c,
1076 we will only use this code if the user specifies alternate locations
1077 with the /include (-I) switch on the command line. */
1079 basename -= 1; /* Strip "]" */
1080 unixname--; /* backspace */
1085 /* The VMS part has a ".]" at the end, and this will not do. Later
1086 processing will add a second directory spec, and this would be a syntax
1087 error. Thus we strip the ".]", and thus merge the directory specs.
1088 We also backspace unixname, so that it points to a '/'. This inhibits the
1089 generation of the 000000 root directory spec (which does not belong here
1092 basename -= 2; /* Strip ".]" */
1093 unixname--; /* backspace */
1101 /* We drop in here if there is no VMS style directory specification yet.
1102 If there is no device specification either, we make the first dir a
1103 device and try that. If we do not do this, then we will be essentially
1104 searching the users default directory (as if they did a #include "asdf.h").
1106 Then all we need to do is to push a '[' into the output string. Later
1107 processing will fill this in, and close the bracket. */
1109 if ((unixname != fullname) /* vms path spec found. */
1110 && (basename[-1] != ':'))
1111 *local_ptr++ = ':'; /* dev not in spec. take first dir */
1113 *local_ptr++ = '['; /* Open the directory specification */
1116 if (unixname == fullname) /* no vms dir spec. */
1119 if ((first_slash != 0) /* unix dir spec. */
1120 && (*unixname != '/') /* not beginning with '/' */
1121 && (*unixname != '.')) /* or './' or '../' */
1122 *local_ptr++ = '.'; /* dir is local ! */
1125 /* at this point we assume that we have the device spec, and (at least
1126 the opening "[" for a directory specification. We may have directories
1129 If there are no other slashes then the filename will be
1130 in the "root" directory. Otherwise, we need to add
1131 directory specifications. */
1133 if (strchr (unixname, '/') == 0)
1135 /* if no directories specified yet and none are following. */
1136 if (local_ptr[-1] == '[')
1138 /* Just add "000000]" as the directory string */
1139 strcpy (local_ptr, "000000]");
1140 local_ptr += strlen (local_ptr);
1141 check_filename_before_returning = 1; /* we might need to fool with this later */
1147 /* As long as there are still subdirectories to add, do them. */
1148 while (strchr (unixname, '/') != 0)
1150 /* If this token is "." we can ignore it
1151 if it's not at the beginning of a path. */
1152 if ((unixname[0] == '.') && (unixname[1] == '/'))
1154 /* remove it at beginning of path. */
1155 if ( ((unixname == fullname) /* no device spec */
1156 && (fullname+2 != basename)) /* starts with ./ */
1158 || ((basename[-1] == ':') /* device spec */
1159 && (unixname-1 == basename))) /* and ./ afterwards */
1160 *local_ptr++ = '.'; /* make '[.' start of path. */
1165 /* Add a subdirectory spec. Do not duplicate "." */
1166 if ( local_ptr[-1] != '.'
1167 && local_ptr[-1] != '['
1168 && local_ptr[-1] != '<')
1171 /* If this is ".." then the spec becomes "-" */
1172 if ( (unixname[0] == '.')
1173 && (unixname[1] == '.')
1174 && (unixname[2] == '/'))
1176 /* Add "-" and skip the ".." */
1177 if ((local_ptr[-1] == '.')
1178 && (local_ptr[-2] == '['))
1179 local_ptr--; /* prevent [.- */
1185 /* Copy the subdirectory */
1186 while (*unixname != '/')
1187 *local_ptr++= *unixname++;
1189 unixname++; /* Skip the "/" */
1192 /* Close the directory specification */
1193 if (local_ptr[-1] == '.') /* no trailing periods */
1196 if (local_ptr[-1] == '[') /* no dir needed */
1202 /* Now add the filename. */
1205 *local_ptr++ = *unixname++;
1208 /* Now append it to the original VMS spec. */
1210 strcpy ((must_revert==1)?fullname:basename, Local);
1212 /* If we put a [000000] in the filename, try to open it first. If this fails,
1213 remove the [000000], and return that name. This provides flexibility
1214 to the user in that they can use both rooted and non-rooted logical names
1215 to point to the location of the file. */
1217 if (check_filename_before_returning)
1219 f = open (fullname, O_RDONLY|O_NONBLOCK);
1222 /* The file name is OK as it is, so return it as is. */
1227 /* The filename did not work. Try to remove the [000000] from the name,
1230 basename = strchr (fullname, '[');
1231 local_ptr = strchr (fullname, ']') + 1;
1232 strcpy (basename, local_ptr); /* this gets rid of it */