cccp.c (hack_vms_include_specification): rewrite to handle '#include <dir/file.h>' correctly.
* cccp.c (hack_vms_include_specification): rewrite to handle '#include <dir/file.h>' correctly. From-SVN: r20577
This commit is contained in:
parent
de3eb7b70b
commit
94fb3933c4
2 changed files with 303 additions and 117 deletions
|
@ -1,3 +1,8 @@
|
|||
Fri Jun 19 02:31:16 1998 Klaus Kaempf (kkaempf@progis.de)
|
||||
|
||||
* cccp.c (hack_vms_include_specification): rewrite to handle
|
||||
'#include <dir/file.h>' correctly.
|
||||
|
||||
Fri Jun 19 02:24:11 1998 H.J. Lu (hjl@gnu.org)
|
||||
|
||||
* config/i386/linux.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Defined.
|
||||
|
|
415
gcc/cccp.c
415
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) {
|
||||
|
@ -4687,6 +4712,9 @@ absolute_filename (filename)
|
|||
#if defined (__CYGWIN32__)
|
||||
/* 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
|
||||
|
@ -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!!! */
|
||||
|
||||
cp = base_name (fname);
|
||||
/* construct device spec if none given. */
|
||||
|
||||
if (index (fullname, ':') == 0)
|
||||
{
|
||||
|
||||
/* 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;
|
||||
/* 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 {
|
||||
/* Point to the UNIX filename part (which needs to be fixed!)
|
||||
but skip vms path information.
|
||||
[basename != fullname since first_slash != 0]. */
|
||||
|
||||
/* 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[-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 (((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 */
|
||||
}
|
||||
}
|
||||
/* Close the directory specification */
|
||||
if (cp2[-1] == '.') /* no trailing periods */
|
||||
cp2--;
|
||||
*cp2++ = ']';
|
||||
}
|
||||
/* Now add the filename */
|
||||
while (*cp1) *cp2++ = *cp1++;
|
||||
*cp2 = 0;
|
||||
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++ = ']';
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue