This is the mail archive of the
java@gcc.gnu.org
mailing list for the Java project.
For Review: Sanitise Use of DIR_SEPARATOR in the Front-End
- From: Ranjit Mathew <rmathew at hotmail dot com>
- To: java at gcc dot gnu dot org
- Date: Wed, 29 Jan 2003 00:13:01 +0530
- Subject: For Review: Sanitise Use of DIR_SEPARATOR in the Front-End
Hi,
As I had pointed out in an earlier mail to this list, the Java
front-end assumes that there's only a single DIR_SEPARATOR for a
host. As a result, class files are being generated in the wrong
folder if '\' is used instead of '/' to separate folders on Win32.
(MinGW defines DIR_SEPARATOR to be '/' and DIR_SEPARATOR_2 to be '\'.)
I have tried to track down and fix some of these issues (in the 3.3
front-end) and present the proposed changes below - if these changes
are acceptable, I'll resubmit them as a patch to the java-patches
(as well as the gcc-patches) list. (Yes Andrew, I'll use the
"diff -c2p" form there. ;-))
If any of this looks pathetic to you, do be nice enough to point
out a better way of achieving the same. (The strcasecmp( ) thing
makes the code look ugly - perhaps we can use a function pointer
there?)
And yes, it does fix the class file destination problem noted above.
In addition, I found a small issue with assuming a case-sensitive
filesystem while scanning the classpath for ZIP or JAR files,
and have included the fix for the same.
The rules I followed are:
1. Do not assume just DIR_SEPARATOR, be prepared for a *possible*
DIR_SEPARATOR_2.
2. Just use the IS_DIR_SEPARATOR( ) macro instead of directly
comparing against DIR_SEPARATOR, as it correctly handles both
DIR_SEPARATOR and DIR_SEPARATOR_2.
3. When comparing file names or name components, check if we have
a case-insensitive filesystem (HAVE_DOS_BASED_FILESYSTEM) and
strcasecmp( ) (HAVE_STRCASECMP) to do the comparison.
Short Descriptions:
jcf-io.c (cached_stat): Check additionally for DIR_SEPARATOR_2
while determining the folder of a file from its name.
Remember which separator is used in the name of the file.
Correct minor typos.
jcf-path.c (add_entry): If on a case-insensitive filesystem
and have strcasecmp( ), check for ZIP and JAR extensions in
file names case-insensitively.
(add_entry): Just use IS_DIR_SEPARATOR instead of explicitly
checking against '/' and then DIR_SEPARATOR.
jcf-write.c (make_class_file_name): Check additionally for
DIR_SEPARATOR_2 while finding the folder of a file.
Remember which separator is used and use it instead of DIR_SEPARATOR.
-------------------------------- 8< --------------------------------
--- jcf-io.c 2003-01-27 21:33:40.000000000 +0530
+++ jcf-io.c 2003-01-27 21:44:30.000000000 +0530
@@ -344,4 +344,5 @@
#if JCF_USE_SCANDIR
char *sep;
+ char origsep;
char *base;
memoized_dirlist_entry *dent;
@@ -357,6 +358,11 @@
/* Get the name of the directory. */
sep = strrchr (filename, DIR_SEPARATOR);
+#ifdef DIR_SEPARATOR_2
+ if (! sep)
+ sep = strrchr (filename, DIR_SEPARATOR_2);
+#endif
if (sep)
{
+ origsep = *sep;
*sep = '\0';
base = sep + 1;
@@ -365,5 +371,5 @@
base = filename;
- /* Obtain the entry for this directory form the hash table. */
+ /* Obtain the entry for this directory from the hash table. */
slot = htab_find_slot (memoized_dirlists, filename, INSERT);
if (!*slot)
@@ -386,7 +392,7 @@
dent = *((memoized_dirlist_entry **) slot);
- /* Put the spearator back. */
+ /* Put the separator back. */
if (sep)
- *sep = DIR_SEPARATOR;
+ *sep = origsep;
/* If the file is not in the list, there is no need to stat it; it
--- jcf-path.c 2003-01-27 21:43:44.000000000 +0530
+++ jcf-path.c 2003-01-28 20:28:07.000000000 +0530
@@ -149,6 +149,12 @@
len = strlen (filename);
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM) && defined (HAVE_STRCASECMP)
+ if (len > 4 && (strcasecmp (filename + len - 4, ".zip") == 0
+ || strcasecmp (filename + len - 4, ".jar") == 0))
+#else
if (len > 4 && (strcmp (filename + len - 4, ".zip") == 0
|| strcmp (filename + len - 4, ".jar") == 0))
+#endif
{
n->flags |= FLAG_ZIP;
@@ -157,5 +163,9 @@
way. Symlinks will fool this test. This is only used for
-MM and -MMD, so it probably isn't terribly important. */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM) && defined (HAVE_STRCASECMP)
+ if (! strcasecmp (filename, LIBGCJ_ZIP_FILE))
+#else
if (! strcmp (filename, LIBGCJ_ZIP_FILE))
+#endif
n->flags |= FLAG_SYSTEM;
}
@@ -164,5 +174,5 @@
This is a little hack that lets the searching code in jcf-io.c
work more easily. Eww. */
- if (filename[len - 1] != '/' && filename[len - 1] != DIR_SEPARATOR)
+ if (! IS_DIR_SEPARATOR (filename[len - 1]))
{
char *f2 = alloca (len + 2);
@@ -379,5 +389,5 @@
+ strlen (direntp->d_name) + 2);
strcpy (name, buf);
- if (name[dirname_length-1] != DIR_SEPARATOR)
+ if (! IS_DIR_SEPARATOR (name[dirname_length-1]))
{
name[dirname_length] = DIR_SEPARATOR;
--- jcf-write.c 2003-01-27 21:46:11.000000000 +0530
+++ jcf-write.c 2003-01-28 22:59:04.000000000 +0530
@@ -3338,4 +3338,5 @@
char *r;
struct stat sb;
+ char sep;
cname = IDENTIFIER_POINTER (identifier_subst (DECL_NAME (TYPE_NAME (clas)),
@@ -3349,9 +3350,17 @@
dname = DECL_SOURCE_FILE (TYPE_NAME (clas));
slash = strrchr (dname, DIR_SEPARATOR);
+#ifdef DIR_SEPARATOR_2
+ if (! slash)
+ slash = strrchr (dname, DIR_SEPARATOR_2);
+#endif
if (! slash)
{
- dname = ".";
- slash = dname + 1;
+ dname = ".";
+ slash = dname + 1;
+ sep = DIR_SEPARATOR;
}
+ else
+ sep = *slash;
+
t = strrchr (cname, DIR_SEPARATOR);
if (t)
@@ -3360,5 +3369,18 @@
else
{
+ char *s;
+
dname = jcf_write_base_directory;
+
+ s = strrchr (dname, DIR_SEPARATOR);
+#ifdef DIR_SEPARATOR_2
+ if (! s)
+ s = strrchr (dname, DIR_SEPARATOR_2);
+#endif
+ if (s)
+ sep = *s;
+ else
+ sep = DIR_SEPARATOR;
+
slash = dname + strlen (dname);
}
@@ -3366,5 +3388,5 @@
r = xmalloc (slash - dname + strlen (cname) + 2);
strncpy (r, dname, slash - dname);
- r[slash - dname] = DIR_SEPARATOR;
+ r[slash - dname] = sep;
strcpy (&r[slash - dname + 1], cname);
@@ -3378,5 +3400,5 @@
while (1)
{
- char *s = strchr (dname, DIR_SEPARATOR);
+ char *s = strchr (dname, sep);
if (s == NULL)
break;
@@ -3387,7 +3409,7 @@
fatal_io_error ("can't create directory %s", r);
- *s = DIR_SEPARATOR;
+ *s = sep;
/* Skip consecutive separators. */
- for (dname = s + 1; *dname && *dname == DIR_SEPARATOR; ++dname)
+ for (dname = s + 1; *dname && *dname == sep; ++dname)
;
}
-------------------------------- 8< --------------------------------
Sincerely Yours,
Ranjit
--
Ranjit Mathew Email: rmathew AT hotmail DOT com
Bangalore,
INDIA. Web: http://ranjitmathew.tripod.com/