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:
Klaus Kaempf 1998-06-19 01:34:11 +00:00 committed by Jeff Law
parent de3eb7b70b
commit 94fb3933c4
2 changed files with 303 additions and 117 deletions

View File

@ -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.

View File

@ -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 */