This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] | |
Hi GCC Patch People,
I had originally submitted this just to java-patches, but Andrew Haley
asked me to submit it to gcc-patches and CC to java-patches.
This proposed patch aims to resolve gcj compilation glitches due
to the Win32 case-insensitive filesystem. For my native MingW
build, I initially had a hacked up jcf-io.c which simulated checking
the exact case of the .java or .class file to open. This is an attempt
at the real deal. It also attempts to open the door at accomodating
other case-insensitive filesystems.
Here are some links that describe this bug:
http://gcc.gnu.org/ml/java/2002-09/msg00073.html
http://gcc.gnu.org/ml/java/2003-02/msg00276.html (end of message)
I would have liked to do something like an AC_LINK_FILES and AC_DEFINE
and avoid the ugly #ifdef-ing in the source files themselves. However, I
was thwarted in this by not having a configure.in at the gcc/java level.
Could this be done better?
Here is my defense of this patch: Andrew had mentioned that he was
worried about introducing platform-specific stuff in the front end and argued
that such functionality might better be moved to the runtime library. However,
in this case, it isn't a question of enforcing strict case checking throughout
the entire compilation process. In fact, Ranjit even has patches which do
exactly the opposite for certain file types. However, public Java classes
must exist in same-named, same-case source files and therefore (cringe),
I believe that it's the compiler's job (and not the runtime's job) to enforce
case-strictness for these specific instances on case-insensitive filesystems.
Since there is no portable way of doing this, it stands to reason that
platform-specific code must trickle into the front end. Does this make sense
or am I full of it?
I've attached a test case which fails on MingW before the patch and tests
favorably on both MingW and i686-pc-linux-gnu after the patch.
-- Mohan
http://www.thisiscool.com/
http://www.animalsong.org/
ChangeLog
2003-03-11 Mohan Embar <gnustuff at thisiscool dot com>
* Make-lang.in: added jcf-win32.c
* jcf.h: defined macro JCF_OPEN_EXACT_CASE which
resolves to open() on non-Win32 platforms and
Win32-specific jcf_open_exact_case() on Win32
* jcf-io.c: use JCF_OPEN_EXACT_CASE when trying
.java and .class files
* jcf-win32.c: added to repository. Defines
Win32-specific jcf_open_exact_case()
Index: Make-lang.in
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/java/Make-lang.in,v
retrieving revision 1.91.12.3
diff -u -2 -r1.91.12.3 Make-lang.in
--- Make-lang.in 26 Jan 2003 11:31:19 -0000 1.91.12.3
+++ Make-lang.in 11 Mar 2003 04:06:29 -0000
@@ -107,16 +107,16 @@
JAVA_OBJS = java/parse.o java/class.o java/decl.o java/expr.o \
java/constants.o java/lang.o java/typeck.o java/except.o java/verify.o \
- java/zextract.o java/jcf-io.o java/jcf-parse.o java/mangle.o \
- java/mangle_name.o java/builtins.o \
+ java/zextract.o java/jcf-io.o java/jcf-win32.o java/jcf-parse.o \
+ java/mangle.o java/mangle_name.o java/builtins.o \
java/jcf-write.o java/buffer.o java/check-init.o java/jcf-depend.o \
java/jcf-path.o java/xref.o java/boehm.o java/java-tree-inline.o mkdeps.o
-GCJH_OBJS = java/gjavah.o java/jcf-io.o java/jcf-depend.o java/jcf-path.o \
- java/zextract.o version.o mkdeps.o errors.o
+GCJH_OBJS = java/gjavah.o java/jcf-io.o java/jcf-win32.o java/jcf-depend.o \
+ java/jcf-path.o java/zextract.o version.o mkdeps.o errors.o
JVSCAN_OBJS = java/parse-scan.o java/jv-scan.o version.o
-JCFDUMP_OBJS = java/jcf-dump.o java/jcf-io.o java/jcf-depend.o java/jcf-path.o \
- java/zextract.o errors.o version.o mkdeps.o
+JCFDUMP_OBJS = java/jcf-dump.o java/jcf-io.o java/jcf-win32.o java/jcf-depend.o \
+ java/jcf-path.o java/zextract.o errors.o version.o mkdeps.o
JVGENMAIN_OBJS = java/jvgenmain.o java/mangle_name.o errors.o
@@ -302,4 +302,5 @@
input.h java/java-except.h $(SYSTEM_H) toplev.h java/parse.h $(GGC_H) \
debug.h real.h gt-java-jcf-parse.h
+java/jcf-win32.o: java/jcf-win32.c $(CONFIG_H) $(SYSTEM_H) java/jcf.h
java/jcf-write.o: java/jcf-write.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h \
$(RTL_H) java/java-opcodes.h java/parse.h java/buffer.h $(SYSTEM_H) \
Index: jcf-io.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/java/jcf-io.c,v
retrieving revision 1.36.2.2
diff -u -2 -r1.36.2.2 jcf-io.c
--- jcf-io.c 10 Mar 2003 19:32:23 -0000 1.36.2.2
+++ jcf-io.c 11 Mar 2003 04:06:30 -0000
@@ -554,5 +554,5 @@
(classname_length <= 30 ?
classname_length : 30)));
- fd = open (buffer, O_RDONLY | O_BINARY);
+ fd = JCF_OPEN_EXACT_CASE (buffer, O_RDONLY | O_BINARY);
if (fd >= 0)
goto found;
@@ -566,5 +566,5 @@
(classname_length <= 30 ?
classname_length : 30)));
- fd = open (buffer, O_RDONLY);
+ fd = JCF_OPEN_EXACT_CASE (buffer, O_RDONLY);
if (fd >= 0)
{
Index: jcf.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/java/jcf.h,v
retrieving revision 1.31.20.1
diff -u -2 -r1.31.20.1 jcf.h
--- jcf.h 7 Mar 2003 04:39:46 -0000 1.31.20.1
+++ jcf.h 11 Mar 2003 04:06:31 -0000
@@ -82,4 +82,21 @@
#endif
+/* On case-insensitive file systems, we need to ensure that a request
+ to open a .java or .class file is honored only if the file to be
+ opened is of the exact case we are asking for. In other words, we
+ want to override the inherent case insensitivity of the underlying
+ file system. On other platforms, this macro becomes the vanilla
+ open() call.
+
+ If you want to add another OS, add your define to the list below
+ (i.e. defined(WIN32) || defined(YOUR_OS)) and add an OS-specific
+ .c file to Make-lang.in similar to jcf-win32.c */
+#if defined(WIN32)
+ extern int jcf_open_exact_case(const char* filename, int oflag);
+ #define JCF_OPEN_EXACT_CASE(x,y) jcf_open_exact_case(x, y)
+#else
+ #define JCF_OPEN_EXACT_CASE open
+#endif
+
struct JCF;
typedef int (*jcf_filbuf_t) PARAMS ((struct JCF*, int needed));
Index: jcf-win32.c
===================================================================
--- jcf-win32.c 2003-03-11 21:40:00.000000000 -0600
+++ jcf-win32.c 2003-03-11 21:42:52.000000000 -0600
@@ -0,0 +1,77 @@
+/* Platform-Specific Win32 Functions
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+
+Java and all Java-based marks are trademarks or registered trademarks
+of Sun Microsystems, Inc. in the United States and other countries.
+The Free Software Foundation is independent of Sun Microsystems, Inc. */
+
+/* Written by Mohan Embar <gnustuff at thisiscool dot com>, March 2003. */
+
+#ifdef WIN32
+
+#include "config.h"
+#include "system.h"
+
+#include "jcf.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+static int file_not_found(void);
+
+static int file_not_found(void)
+{
+ /* simulate an open() failure with ENOENT */
+ errno = ENOENT;
+ return -1;
+}
+
+int jcf_open_exact_case(const char* filename, int oflag)
+{
+ int nFileLenIn = strlen(filename);
+ int nFileLenFound;
+
+ /* See if we can find this file. */
+ WIN32_FIND_DATA fd;
+ HANDLE hFile = FindFirstFile(filename, &fd);
+ FindClose(hFile);
+ if (hFile == INVALID_HANDLE_VALUE)
+ return file_not_found();
+
+ nFileLenFound = strlen(fd.cFileName);
+ if (nFileLenFound > nFileLenIn)
+ return file_not_found();
+ /* this should never happen */
+
+ /* Here, we're only actually comparing the filename and not
+ checking the case of any containing directory components.
+ Although we're not fully obeying our contract, checking
+ all directory components would be tedious and time-consuming
+ and it's a pretty safe assumption that mixed-case package
+ names are a fringe case.... */
+ if (strcmp(filename+nFileLenIn-nFileLenFound, fd.cFileName)) {
+ /* printf("************\nRejected:\n%s\n%s\n************\n\n", filename, fd.cFileName); */
+ return file_not_found();
+ }
+ else {
+ return open(filename, oflag);
+ }
+}
+
+#endif /* WIN32 */
Attachment:
ExactCase.zip
Description: Zip archive
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |