This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
cccp.c fix for VMS
- To: egcs-patches at cygnus dot com
- Subject: cccp.c fix for VMS
- From: "Klaus Kaempf" <kkaempf at progis dot de>
- Date: Mon, 8 Jun 1998 15:56:49 +0200 (MET DST)
The current include file handling on vms fails in files are
in sub-directories and accessed with 'include <subdir/file.h>'.
The following patch fixes this and cleans up hack_vms_include_specification().
Mon Jun 8 15:42:27 1998 Klaus Kaempf (kkaempf@progis.de)
* cccp.c (hack_vms_include_specification): rewrite to handle
'#include <dir/file.h>' correctly.
===================================================================
RCS file: RCS/cccp.c,v
retrieving revision 1.1
diff -c -r1.1 cccp.c
*** cccp.c 1998/06/08 12:06:28 1.1
--- cccp.c 1998/06/08 13:12:15
***************
*** 78,84 ****
static int VMS_open ();
static FILE *VMS_fopen ();
static FILE *VMS_freopen ();
! static void 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 */
--- 78,84 ----
static int VMS_open ();
static FILE *VMS_fopen ();
static FILE *VMS_freopen ();
! 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,4332 ****
--- 4327,4342 ----
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,4506 ****
}
}
- 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");
}
! }
#endif /* VMS */
f = open_include_file (fname, searchptr, importing, &inc);
if (f != -1) {
--- 4495,4531 ----
}
}
#ifdef VMS
/* Change this 1/2 Unix 1/2 VMS file specification into a
full VMS file specification */
! 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,4693 ****
--- 4713,4721 ----
/* 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,4745 ****
to0 = to;
for (;;) {
if (from[0] == '.' && from[1] == '/')
from += 2;
! else {
/* Copy this component and trailing /, if any. */
while ((*to++ = *from++) != '/') {
if (!to[-1]) {
--- 4765,4776 ----
to0 = to;
for (;;) {
+ #ifndef VMS
if (from[0] == '.' && from[1] == '/')
from += 2;
! else
! #endif
! {
/* Copy this component and trailing /, if any. */
while ((*to++ = *from++) != '/') {
if (!to[-1]) {
***************
*** 4937,4943 ****
fd = open (fname, O_RDONLY, 0);
if (fd < 0)
! return fd;
if (!inc) {
/* FNAME was not in include_hashtab; insert a new entry. */
--- 4968,4983 ----
fd = open (fname, O_RDONLY, 0);
if (fd < 0)
! {
! #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,9982 ****
--- 10016,10027 ----
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,10311 ****
#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. */
! static void
! hack_vms_include_specification (fname, vaxc_include)
! char *fname;
int vaxc_include;
{
! register char *cp, *cp1, *cp2;
! int f, check_filename_before_returning;
char Local[512];
check_filename_before_returning = 0;
! cp = base_name (fname);
/*
* 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 */
/* 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
--- 10326,10409 ----
#ifdef VMS
! /* Under VMS we need to fix up the "include" specification filename.
! 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 *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)
+ {
+
+ /* 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 (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,10429 ****
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 {
! /* 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 */
! }
/* 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 */
! /* 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 "/" */
! }
! /* Close the directory specification */
! if (cp2[-1] == '.') /* no trailing periods */
! cp2--;
! *cp2++ = ']';
! }
! /* Now add the filename */
! while (*cp1) *cp2++ = *cp1++;
! *cp2 = 0;
/* Now append it to the original VMS spec. */
! strcpy (cp, 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;
}
! /* 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;
}
#endif /* VMS */
--- 10416,10610 ----
If no device is specified, then the first directory name is taken to be
a device name (or a rooted logical). */
! /* 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 (((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.
! If there are no other slashes then the filename will be
in the "root" directory. Otherwise, we need to add
directory specifications. */
!
! 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++ = ']';
! }
!
! /* Now add the filename. */
!
! while (*unixname)
! *local_ptr++ = *unixname++;
! *local_ptr = 0;
!
/* Now append it to the original VMS spec. */
!
! 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 (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 */
!
}
!
! return 1;
}
#endif /* VMS */
--
proGIS Software E-Mail: kkaempf@progis.de
Dipl.-Inform. Klaus K"ampf Fax: 0241-47067-29
Jakobstr. 117 Voice: 0241-47067-11
D-52064 Aachen WWW: http://www.progis.de