diff options
author | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-06-19 01:34:11 +0000 |
---|---|---|
committer | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-06-19 01:34:11 +0000 |
commit | bb8591d1791c68abed5bebf7e2f1fe321cbc21b6 (patch) | |
tree | a1bfd4cb2906fdc982f7c85922f53309e3b05466 /gcc/cccp.c | |
parent | 7f2abdb9be0fc4d18f626d0c337e68e0b3194f20 (diff) | |
download | gcc-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.c | 413 |
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 */ |