summaryrefslogtreecommitdiff
path: root/gcc/cccp.c
diff options
context:
space:
mode:
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>1998-06-19 01:34:11 +0000
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>1998-06-19 01:34:11 +0000
commitbb8591d1791c68abed5bebf7e2f1fe321cbc21b6 (patch)
treea1bfd4cb2906fdc982f7c85922f53309e3b05466 /gcc/cccp.c
parent7f2abdb9be0fc4d18f626d0c337e68e0b3194f20 (diff)
downloadgcc-bb8591d1791c68abed5bebf7e2f1fe321cbc21b6.tar.gz
* cccp.c (hack_vms_include_specification): rewrite to handle
'#include <dir/file.h>' correctly. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@20577 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cccp.c')
-rw-r--r--gcc/cccp.c413
1 files changed, 297 insertions, 116 deletions
diff --git a/gcc/cccp.c b/gcc/cccp.c
index 3a0cf0db520..59799de313d 100644
--- a/gcc/cccp.c
+++ b/gcc/cccp.c
@@ -78,7 +78,7 @@ static int VMS_fstat (), VMS_stat ();
static int VMS_open ();
static FILE *VMS_fopen ();
static FILE *VMS_freopen ();
-static void hack_vms_include_specification ();
+static int hack_vms_include_specification ();
#define INO_T_EQ(a, b) (!bcmp((char *) &(a), (char *) &(b), sizeof (a)))
#define INO_T_HASH(a) 0
#define INCLUDE_LEN_FUDGE 12 /* leave room for VMS syntax conversion */
@@ -4327,6 +4327,16 @@ get_filename:
simplify_filename (dsp->fname);
nam = base_name (dsp->fname);
*nam = 0;
+#ifdef VMS
+ /* for hack_vms_include_specification(), a local
+ dir specification must start with "./" on VMS. */
+ if (nam == dsp->fname)
+ {
+ *nam++ = '.';
+ *nam++ = '/';
+ *nam = 0;
+ }
+#endif
/* But for efficiency's sake, do not insert the dir
if it matches the search list's first dir. */
dsp->next = search_start;
@@ -4485,22 +4495,37 @@ get_filename:
}
}
- strcpy (fname, searchptr->fname);
- strcat (fname, fbeg);
#ifdef VMS
/* Change this 1/2 Unix 1/2 VMS file specification into a
full VMS file specification */
- if (searchptr->fname[0]) {
- /* Fix up the filename */
- hack_vms_include_specification (fname, vaxc_include);
- } else {
- /* This is a normal VMS filespec, so use it unchanged. */
- strcpy (fname, fbeg);
- /* if it's '#include filename', add the missing .h */
- if (vaxc_include && index(fname,'.')==NULL) {
- strcat (fname, ".h");
+ if (searchptr->fname[0])
+ {
+ strcpy (fname, searchptr->fname);
+ if (fname[strlen (fname) - 1] == ':')
+ {
+ char *slashp;
+ slashp = strchr (fbeg, '/');
+
+ /* start at root-dir of logical device if no path given. */
+ if (slashp == 0)
+ strcat (fname, "[000000]");
+ }
+ strcat (fname, fbeg);
+
+ /* Fix up the filename */
+ hack_vms_include_specification (fname, vaxc_include);
}
- }
+ else
+ {
+ /* This is a normal VMS filespec, so use it unchanged. */
+ strcpy (fname, fbeg);
+ /* if it's '#include filename', add the missing .h */
+ if (vaxc_include && index(fname,'.')==NULL)
+ strcat (fname, ".h");
+ }
+#else
+ strcpy (fname, searchptr->fname);
+ strcat (fname, fbeg);
#endif /* VMS */
f = open_include_file (fname, searchptr, importing, &inc);
if (f != -1) {
@@ -4688,6 +4713,9 @@ absolute_filename (filename)
/* At present, any path that begins with a drive spec is absolute. */
if (ISALPHA (filename[0]) && filename[1] == ':') return 1;
#endif
+#ifdef VMS
+ if (index (filename, ':') != 0) return 1;
+#endif
if (filename[0] == '/') return 1;
#ifdef DIR_SEPARATOR
if (filename[0] == DIR_SEPARATOR) return 1;
@@ -4737,9 +4765,12 @@ simplify_filename (filename)
to0 = to;
for (;;) {
+#ifndef VMS
if (from[0] == '.' && from[1] == '/')
from += 2;
- else {
+ else
+#endif
+ {
/* Copy this component and trailing /, if any. */
while ((*to++ = *from++) != '/') {
if (!to[-1]) {
@@ -4937,7 +4968,16 @@ open_include_file (filename, searchptr, importing, pinc)
fd = open (fname, O_RDONLY, 0);
if (fd < 0)
- return fd;
+ {
+#ifdef VMS
+ /* if #include <dir/file> fails, try again with hacked spec. */
+ if (!hack_vms_include_specification (fname, 0))
+ return fd;
+ fd = open (fname, O_RDONLY, 0);
+ if (fd < 0)
+#endif
+ return fd;
+ }
if (!inc) {
/* FNAME was not in include_hashtab; insert a new entry. */
@@ -9976,7 +10016,12 @@ new_include_prefix (prev_file_name, component, prefix, name)
if (len == 1 && dir->fname[len - 1] == '.')
len = 0;
else
+#ifdef VMS
+ /* must be '/', hack_vms_include_specification triggers on it. */
+ dir->fname[len++] = '/';
+#else
dir->fname[len++] = DIR_SEPARATOR;
+#endif
dir->fname[len] = 0;
}
@@ -10281,31 +10326,84 @@ savestring (input)
#ifdef VMS
-/* Under VMS we need to fix up the "include" specification filename so
- that everything following the 1st slash is changed into its correct
- VMS file specification. */
+/* Under VMS we need to fix up the "include" specification filename.
-static void
-hack_vms_include_specification (fname, vaxc_include)
- char *fname;
+ Rules for possible conversions
+
+ fullname tried paths
+
+ name name
+ ./dir/name [.dir]name
+ /dir/name dir:name
+ /name [000000]name, name
+ dir/name dir:[000000]name, dir:name, dir/name
+ dir1/dir2/name dir1:[dir2]name, dir1:[000000.dir2]name
+ path:/name path:[000000]name, path:name
+ path:/dir/name path:[000000.dir]name, path:[dir]name
+ path:dir/name path:[dir]name
+ [path]:[dir]name [path.dir]name
+ path/[dir]name [path.dir]name
+
+ The path:/name input is constructed when expanding <> includes.
+
+ return 1 if name was changed, 0 else. */
+
+static int
+hack_vms_include_specification (fullname, vaxc_include)
+ char *fullname;
int vaxc_include;
{
- register char *cp, *cp1, *cp2;
- int f, check_filename_before_returning;
+ register char *basename, *unixname, *local_ptr, *first_slash;
+ int f, check_filename_before_returning, must_revert;
char Local[512];
check_filename_before_returning = 0;
+ must_revert = 0;
+ /* See if we can find a 1st slash. If not, there's no path information. */
+ first_slash = index (fullname, '/');
+ if (first_slash == 0)
+ return 0; /* Nothing to do!!! */
+
+ /* construct device spec if none given. */
+
+ if (index (fullname, ':') == 0)
+ {
- cp = base_name (fname);
+ /* If fullname has a slash, take it as device spec. */
+
+ if (first_slash == fullname)
+ {
+ first_slash = index (fullname+1, '/'); /* 2nd slash ? */
+ if (first_slash)
+ *first_slash = ':'; /* make device spec */
+ for (basename = fullname; *basename != 0; basename++)
+ *basename = *(basename+1); /* remove leading slash */
+ }
+ else if ((first_slash[-1] != '.') /* keep ':/', './' */
+ && (first_slash[-1] != ':')
+ && (first_slash[-1] != ']')) /* or a vms path */
+ {
+ *first_slash = ':';
+ }
+ else if ((first_slash[1] == '[') /* skip './' in './[dir' */
+ && (first_slash[-1] == '.'))
+ fullname += 2;
+ }
+
+ /* Get part after first ':' (basename[-1] == ':')
+ or last '/' (basename[-1] == '/'). */
+
+ basename = base_name (fullname);
/*
* Check if we have a vax-c style '#include filename'
* and add the missing .h
*/
- if (vaxc_include && !index (cp,'.'))
- strcat (cp, ".h");
- cp2 = Local; /* initialize */
+ if (vaxc_include && !index (basename,'.'))
+ strcat (basename, ".h");
+
+ local_ptr = Local; /* initialize */
/* We are trying to do a number of things here. First of all, we are
trying to hammer the filenames into a standard format, such that later
@@ -10318,112 +10416,195 @@ hack_vms_include_specification (fname, vaxc_include)
If no device is specified, then the first directory name is taken to be
a device name (or a rooted logical). */
- /* See if we found that 1st slash */
- if (cp == 0) return; /* Nothing to do!!! */
- if (*cp != '/') return; /* Nothing to do!!! */
- /* Point to the UNIX filename part (which needs to be fixed!) */
- cp1 = cp+1;
+ /* Point to the UNIX filename part (which needs to be fixed!)
+ but skip vms path information.
+ [basename != fullname since first_slash != 0]. */
+
+ if ((basename[-1] == ':') /* vms path spec. */
+ || (basename[-1] == ']')
+ || (basename[-1] == '>'))
+ unixname = basename;
+ else
+ unixname = fullname;
+
+ if (*unixname == '/')
+ unixname++;
+
/* If the directory spec is not rooted, we can just copy
- the UNIX filename part and we are done */
- if (((cp - fname) > 1) && ((cp[-1] == ']') || (cp[-1] == '>'))) {
- if (cp[-2] != '.') {
- /*
- * The VMS part ends in a `]', and the preceding character is not a `.'.
- * We strip the `]', and then splice the two parts of the name in the
- * usual way. Given the default locations for include files in cccp.c,
- * we will only use this code if the user specifies alternate locations
- * with the /include (-I) switch on the command line. */
- cp -= 1; /* Strip "]" */
- cp1--; /* backspace */
- } else {
- /*
- * The VMS part has a ".]" at the end, and this will not do. Later
- * processing will add a second directory spec, and this would be a syntax
- * error. Thus we strip the ".]", and thus merge the directory specs.
- * We also backspace cp1, so that it points to a '/'. This inhibits the
- * generation of the 000000 root directory spec (which does not belong here
- * in this case).
- */
- cp -= 2; /* Strip ".]" */
- cp1--; }; /* backspace */
- } else {
+ the UNIX filename part and we are done. */
- /* We drop in here if there is no VMS style directory specification yet.
- * If there is no device specification either, we make the first dir a
- * device and try that. If we do not do this, then we will be essentially
- * searching the users default directory (as if they did a #include "asdf.h").
- *
- * Then all we need to do is to push a '[' into the output string. Later
- * processing will fill this in, and close the bracket.
- */
- if (cp[-1] != ':') *cp2++ = ':'; /* dev not in spec. take first dir */
- *cp2++ = '['; /* Open the directory specification */
- }
+ if (((basename - fullname) > 1)
+ && ( (basename[-1] == ']')
+ || (basename[-1] == '>')))
+ {
+ if (basename[-2] != '.')
+ {
+
+ /* The VMS part ends in a `]', and the preceding character is not a `.'.
+ -> PATH]:/name (basename = '/name', unixname = 'name')
+ We strip the `]', and then splice the two parts of the name in the
+ usual way. Given the default locations for include files in cccp.c,
+ we will only use this code if the user specifies alternate locations
+ with the /include (-I) switch on the command line. */
+
+ basename -= 1; /* Strip "]" */
+ unixname--; /* backspace */
+ }
+ else
+ {
+
+ /* The VMS part has a ".]" at the end, and this will not do. Later
+ processing will add a second directory spec, and this would be a syntax
+ error. Thus we strip the ".]", and thus merge the directory specs.
+ We also backspace unixname, so that it points to a '/'. This inhibits the
+ generation of the 000000 root directory spec (which does not belong here
+ in this case). */
+
+ basename -= 2; /* Strip ".]" */
+ unixname--; /* backspace */
+ }
+ }
+
+ else
+
+ {
+
+ /* We drop in here if there is no VMS style directory specification yet.
+ If there is no device specification either, we make the first dir a
+ device and try that. If we do not do this, then we will be essentially
+ searching the users default directory (as if they did a #include "asdf.h").
+
+ Then all we need to do is to push a '[' into the output string. Later
+ processing will fill this in, and close the bracket. */
+
+ if ((unixname != fullname) /* vms path spec found. */
+ && (basename[-1] != ':'))
+ *local_ptr++ = ':'; /* dev not in spec. take first dir */
+
+ *local_ptr++ = '['; /* Open the directory specification */
+ }
+
+ if (unixname == fullname) /* no vms dir spec. */
+ {
+ must_revert = 1;
+ if ((first_slash != 0) /* unix dir spec. */
+ && (*unixname != '/') /* not beginning with '/' */
+ && (*unixname != '.')) /* or './' or '../' */
+ *local_ptr++ = '.'; /* dir is local ! */
+ }
/* at this point we assume that we have the device spec, and (at least
the opening "[" for a directory specification. We may have directories
- specified already */
+ specified already.
- /* If there are no other slashes then the filename will be
+ If there are no other slashes then the filename will be
in the "root" directory. Otherwise, we need to add
directory specifications. */
- if (index (cp1, '/') == 0) {
- /* Just add "000000]" as the directory string */
- strcpy (cp2, "000000]");
- cp2 += strlen (cp2);
- check_filename_before_returning = 1; /* we might need to fool with this later */
- } else {
- /* As long as there are still subdirectories to add, do them. */
- while (index (cp1, '/') != 0) {
- /* If this token is "." we can ignore it */
- if ((cp1[0] == '.') && (cp1[1] == '/')) {
- cp1 += 2;
- continue;
- }
- /* Add a subdirectory spec. Do not duplicate "." */
- if (cp2[-1] != '.' && cp2[-1] != '[' && cp2[-1] != '<')
- *cp2++ = '.';
- /* If this is ".." then the spec becomes "-" */
- if ((cp1[0] == '.') && (cp1[1] == '.') && (cp[2] == '/')) {
- /* Add "-" and skip the ".." */
- *cp2++ = '-';
- cp1 += 3;
- continue;
- }
- /* Copy the subdirectory */
- while (*cp1 != '/') *cp2++= *cp1++;
- cp1++; /* Skip the "/" */
+
+ if (index (unixname, '/') == 0)
+ {
+ /* if no directories specified yet and none are following. */
+ if (local_ptr[-1] == '[')
+ {
+ /* Just add "000000]" as the directory string */
+ strcpy (local_ptr, "000000]");
+ local_ptr += strlen (local_ptr);
+ check_filename_before_returning = 1; /* we might need to fool with this later */
+ }
+ }
+ else
+ {
+
+ /* As long as there are still subdirectories to add, do them. */
+ while (index (unixname, '/') != 0)
+ {
+ /* If this token is "." we can ignore it
+ if it's not at the beginning of a path. */
+ if ((unixname[0] == '.') && (unixname[1] == '/'))
+ {
+ /* remove it at beginning of path. */
+ if ( ((unixname == fullname) /* no device spec */
+ && (fullname+2 != basename)) /* starts with ./ */
+ /* or */
+ || ((basename[-1] == ':') /* device spec */
+ && (unixname-1 == basename))) /* and ./ afterwards */
+ *local_ptr++ = '.'; /* make '[.' start of path. */
+ unixname += 2;
+ continue;
+ }
+
+ /* Add a subdirectory spec. Do not duplicate "." */
+ if ( local_ptr[-1] != '.'
+ && local_ptr[-1] != '['
+ && local_ptr[-1] != '<')
+ *local_ptr++ = '.';
+
+ /* If this is ".." then the spec becomes "-" */
+ if ( (unixname[0] == '.')
+ && (unixname[1] == '.')
+ && (unixname[2] == '/'))
+ {
+ /* Add "-" and skip the ".." */
+ if ((local_ptr[-1] == '.')
+ && (local_ptr[-2] == '['))
+ local_ptr--; /* prevent [.- */
+ *local_ptr++ = '-';
+ unixname += 3;
+ continue;
+ }
+
+ /* Copy the subdirectory */
+ while (*unixname != '/')
+ *local_ptr++= *unixname++;
+
+ unixname++; /* Skip the "/" */
+ }
+
+ /* Close the directory specification */
+ if (local_ptr[-1] == '.') /* no trailing periods */
+ local_ptr--;
+
+ if (local_ptr[-1] == '[') /* no dir needed */
+ local_ptr--;
+ else
+ *local_ptr++ = ']';
}
- /* Close the directory specification */
- if (cp2[-1] == '.') /* no trailing periods */
- cp2--;
- *cp2++ = ']';
- }
- /* Now add the filename */
- while (*cp1) *cp2++ = *cp1++;
- *cp2 = 0;
+
+ /* Now add the filename. */
+
+ while (*unixname)
+ *local_ptr++ = *unixname++;
+ *local_ptr = 0;
+
/* Now append it to the original VMS spec. */
- strcpy (cp, Local);
+
+ strcpy ((must_revert==1)?fullname:basename, Local);
/* If we put a [000000] in the filename, try to open it first. If this fails,
remove the [000000], and return that name. This provides flexibility
to the user in that they can use both rooted and non-rooted logical names
to point to the location of the file. */
- if (check_filename_before_returning) {
- f = open (fname, O_RDONLY, 0666);
- if (f >= 0) {
- /* The file name is OK as it is, so return it as is. */
- close (f);
- return;
+ if (check_filename_before_returning)
+ {
+ f = open (fullname, O_RDONLY, 0666);
+ if (f >= 0)
+ {
+ /* The file name is OK as it is, so return it as is. */
+ close (f);
+ return 1;
+ }
+
+ /* The filename did not work. Try to remove the [000000] from the name,
+ and return it. */
+
+ basename = index (fullname, '[');
+ local_ptr = index (fullname, ']') + 1;
+ strcpy (basename, local_ptr); /* this gets rid of it */
+
}
- /* The filename did not work. Try to remove the [000000] from the name,
- and return it. */
- cp = index (fname, '[');
- cp2 = index (fname, ']') + 1;
- strcpy (cp, cp2); /* this gets rid of it */
- }
- return;
+
+ return 1;
}
#endif /* VMS */