[PATCH] [MinGW] for Review: Add UNICODE support to MinGW libgcj (UPDATED)

Mohan Embar gnustuff@thisiscool.com
Sun Nov 23 16:25:00 GMT 2003


Hi People,

This patch supersedes this:

http://gcc.gnu.org/ml/java-patches/2003-q4/msg00430.html

...and attempts to address the outcry from those who didn't
want the UNICOWS licensing restrictions on Win9X. It adds
a configure switch for the compiler called --enable-libgcj-mingw-osapi
which can take one of three values:

ansi: Use the char and the Win32 A functions natively, translating
  to and from UNICODE when using these functions.

unicows: Use the WCHAR and Win32 W functions natively. Adds -lunicows
  to libgcj.spec to link with libunicows. unicows.dll needs to be
  deployed on Win9X machines running built executables.

unicode: Use the WCHAR and Win32 W functions natively. Does not add
  -lunicows to libgcj.spec. The built executables will only run
  on WinNT and above.

Tested on Win32 and the i686-pc-linux-gnu native compiler (just to
make sure I didn't break anything).

-- Mohan
http://www.thisiscool.com/
http://www.animalsong.org/

ChangeLog
2003-11-23  Mohan Embar  <gnustuff@thisiscool.com>

  * configure.in: Added new MinGW-specific configure flag
  --enable-libgcj-mingw-osapi.
  Added new AC_DEFINE MINGW_LIBGCJ_UNICODE.
  Add -lunicows to MinGW SYSTEMSPEC if --enable-libgcj-mingw-osapi
  is set to unicows.
  * configure: Rebuilt.
  * include/config.h.in: Rebuilt.
  * win32.cc (_Jv_Win32NewString): Implemented.
  (nativeToUnicode): New helper function defined only for
  non-UNICODE builds.
  (unicodeToNative): Likewise.
  (_Jv_Win32TempString): Implemented.
  (lots): Refactored using tchar.h macros.
  (WSAEventWrapper): Use _Jv_Win32NewString.
  (_Jv_platform_initialize): Use GetModuleFileNameA instead
  of GetModuleFileName.
  (_Jv_platform_initProperties): Use _Jv_Win32NewString.
  Use temporary stack buffer instead of a heap buffer.
  * include/win32.h
  Added defines for UNICODE and _UNICODE if MINGW_LIBGCJ_UNICODE is
  defined; added tchar.h include.
  (_Jv_Win32TempString): Declared new helper class.
  (JV_TEMP_STRING_WIN32): New helper macro.
  (_Jv_Win32NewString): Declared new helper method.
  * java/io/natFileDescriptorWin32.cc (open): Use
  JV_TEMP_STRING_WIN32 instead of JV_TEMP_UTF_STRING.
  (write): Reformatted slightly.
  * java/io/natFileWin32.cc (lots): Use tchar.h macros;
  use JV_TEMP_STRING_WIN32 instead of JV_TEMP_UTF_STRING.
  (getCanonicalPath): Use _Jv_Win32NewString instead of
  JvNewStringUTF.
  (performList): Likewise.
  * java/lang/natWin32Process.cc (ChildProcessPipe):
  Use tchar.h macros.
  (startProcess): Use tchar.h macros, JV_TEMP_STRING_WIN32,
  and UNICODE environment flag for CreateProcess.
  * java/net/natNetworkInterfaceWin32.cc
  (winsock2GetRealNetworkInterfaces): Use tchar.h macros and
  _Jv_Win32NewString.

Index: configure.in
===================================================================
RCS file: /cvs/gcc/gcc/libjava/configure.in,v
retrieving revision 1.174
diff -u -2 -r1.174 configure.in
--- configure.in	11 Nov 2003 11:49:11 -0000	1.174
+++ configure.in	23 Nov 2003 05:34:19 -0000
@@ -98,4 +98,24 @@
 AM_CONDITIONAL(ONESTEP, test "$enable_libgcj_multifile" = yes)
 
+# What is the native OS API for MinGW?
+AC_ARG_ENABLE(libgcj-mingw-osapi,
+changequote(<<,>>)dnl
+<<  --enable-libgcj-mingw-osapi=ansi, unicows or unicode
+                          native MinGW libgcj Win32 OS API [ansi]>>,
+changequote([,])
+[case "${enableval}" in
+  ansi) enable_libgcj_mingw_osapi=ansi ;;
+  unicows) enable_libgcj_mingw_osapi=unicows ;;
+  unicode) enable_libgcj_mingw_osapi=unicode ;;
+  *) AC_MSG_ERROR(bad value ${enableval} for --enable-libgcj-mingw-osapi) ;;
+esac],[enable_libgcj_mingw_osapi=ansi])
+
+case "${enable_libgcj_mingw_osapi}" in
+  unicows | unicode) 
+    AC_DEFINE(MINGW_LIBGCJ_UNICODE, 1,
+      [Define if MinGW libgcj uses the Windows UNICODE OS API.])
+    ;;
+esac
+
 dnl configure.host sets slow_pthread_self if the synchronization code should 
 dnl try to avoid pthread_self calls by caching thread IDs in a hashtable.
@@ -314,4 +334,7 @@
     *mingw*)
       SYSTEMSPEC="-lgdi32 -lwsock32 -lws2_32"
+      if test "${enable_libgcj_mingw_osapi}" = "unicows"; then
+        SYSTEMSPEC="-lunicows $SYSTEMSPEC"
+      fi
     ;;
     *)
Index: win32.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/win32.cc,v
retrieving revision 1.19
diff -u -2 -r1.19 win32.cc
--- win32.cc	7 Nov 2003 03:13:55 -0000	1.19
+++ win32.cc	23 Nov 2003 05:34:20 -0000
@@ -43,4 +43,104 @@
 // Helper classes and methods implementation
   
+#ifdef MINGW_LIBGCJ_UNICODE
+
+// We're using the OS W (UNICODE) API, which means that we're speaking
+// the same language....
+jstring
+_Jv_Win32NewString (LPCTSTR pcsz)
+{
+  return JvNewString ((jchar*) pcsz, _tcslen (pcsz));
+}
+
+#else
+
+// We're using the OS A functions, which means we need to translate between
+// UNICODE and the native character set.
+
+// First, let's set up some helper translation functions....
+
+// Converts the native string to any specified jstring, returning the
+// length of the jstring. If the specified jstring is null, we simply
+// compute and return the length.
+static int nativeToUnicode(LPCSTR pcsz, jstring jstr = 0)
+{
+  jchar* buf = 0;
+  int len = 0;
+  if (jstr)
+    {
+      len = jstr->length();
+      buf = JvGetStringChars(jstr);
+    }
+  return ::MultiByteToWideChar(GetACP(), 0, pcsz,
+    strlen(pcsz), (LPWSTR) buf, len);
+}
+
+// Does the inverse of nativeToUnicode, with the same calling semantics.
+static int unicodeToNative(jstring jstr, LPSTR buf, int buflen)
+{
+  return ::WideCharToMultiByte(GetACP(), 0, (LPWSTR) JvGetStringChars(jstr),
+    jstr->length(), buf, buflen, NULL, NULL);
+}
+
+// Convenience function when the caller only wants to compute the length
+// of the native string.
+static int unicodeToNative(jstring jstr)
+{
+  return unicodeToNative(jstr, 0, 0);
+}
+
+jstring
+_Jv_Win32NewString (LPCTSTR pcsz)
+{
+  // Compute the length, allocate the jstring, then perform the conversion.
+  int len = nativeToUnicode(pcsz);
+  jstring jstr = JvAllocString(len);
+  nativeToUnicode(pcsz, jstr);
+  return jstr;
+}
+
+#endif // MINGW_LIBGCJ_UNICODE
+
+// class _Jv_Win32TempString
+_Jv_Win32TempString::_Jv_Win32TempString(jstring jstr):
+  buf_(0)
+{
+  if (jstr == 0)
+    return;
+    
+  // We need space for the string length plus a null terminator.
+  // Determine whether to use our stack-allocated buffer or a heap-
+  // allocated one.
+#ifdef MINGW_LIBGCJ_UNICODE
+  // A UNICODE character is a UNICODE character is a UNICODE character....
+  int len = jstr->length();
+#else
+  // Compute the length of the native character string.
+  int len = unicodeToNative(jstr);
+#endif // MINGW_LIBGCJ_UNICODE
+
+  int bytesNeeded = (len + 1) * sizeof(TCHAR);
+  if (bytesNeeded <= (int) sizeof(stackbuf_))
+    buf_ = stackbuf_;
+  else
+    buf_ = (LPTSTR) _Jv_Malloc(bytesNeeded);
+    
+#ifdef MINGW_LIBGCJ_UNICODE
+  // Copy the UNICODE characters to our buffer.
+  _tcsncpy(buf_, (LPCTSTR) JvGetStringChars (jstr), len);
+#else
+  // Convert the UNICODE string to a native one.
+  unicodeToNative(jstr, buf_, len);
+#endif // MINGW_LIBGCJ_UNICODE
+
+  buf_[len] = 0;
+}
+
+_Jv_Win32TempString::~_Jv_Win32TempString()
+{
+  if (buf_ && buf_ != stackbuf_)
+    _Jv_Free (buf_);
+}
+
 // class WSAEventWrapper
 WSAEventWrapper::WSAEventWrapper (int fd, DWORD dwSelFlags):
@@ -93,14 +193,15 @@
     {
       LPTSTR lpszTemp =
-        (LPTSTR) _Jv_Malloc (strlen (lpszPrologue) +
-          strlen (lpMsgBuf) + 3);
-      strcpy (lpszTemp, lpszPrologue);
-      strcat (lpszTemp, ": ");
-      strcat (lpszTemp, lpMsgBuf);
-      ret = JvNewStringLatin1 (lpszTemp);
+        (LPTSTR) _Jv_Malloc ((_tcslen (lpszPrologue) +
+          _tcslen (lpMsgBuf) + 3) * sizeof(TCHAR) );
+      _tcscpy (lpszTemp, lpszPrologue);
+      _tcscat (lpszTemp, _T(": "));
+      _tcscat (lpszTemp, lpMsgBuf);
+      ret = _Jv_Win32NewString (lpszTemp);
+      _Jv_Free (lpszTemp);
     } 
   else
     {
-      ret = JvNewStringLatin1 (lpMsgBuf);
+      ret = _Jv_Win32NewString (lpMsgBuf);
     }
 
@@ -144,5 +245,5 @@
   WSADATA data;
   if (WSAStartup (MAKEWORD (1, 1), &data))
-    MessageBox (NULL, "Error initialising winsock library.", "Error",
+    MessageBox (NULL, _T("Error initialising winsock library."), _T("Error"),
     MB_OK | MB_ICONEXCLAMATION);
 
@@ -150,6 +251,9 @@
   SetUnhandledExceptionFilter (win32_exception_handler);
 
-  // Initialize our executable name
-  GetModuleFileName(NULL, exec_name, sizeof(exec_name));
+  // Initialize our executable name.
+  // FIXME: We unconditionally use the ANSI function because
+  // _Jv_ThisExecutable returns a const char*. We should really
+  // change _Jv_ThisExecutable to return a jstring.
+  GetModuleFileNameA(NULL, exec_name, sizeof(exec_name));
 }
 
@@ -178,5 +282,5 @@
 }
 
-static bool dirExists (const char* dir)
+static bool dirExists (LPCTSTR dir)
 {
   DWORD dwAttrs = ::GetFileAttributes (dir);
@@ -185,10 +289,10 @@
 }
 
-static void getUserHome(char* userHome, const char* userId)
+static void getUserHome(LPTSTR userHome, LPCTSTR userId)
 {
-  char* uh = ::getenv ("USERPROFILE");
+  LPTSTR uh = _tgetenv (_T("USERPROFILE"));
   if (uh)
     {
-      strcpy(userHome, uh);
+      _tcscpy(userHome, uh);
     }
   else
@@ -203,13 +307,13 @@
       // Windows version, but if we did that, then this attempt
       // wouldn't be half-hearted.
-      char userHomePath[MAX_PATH], winHome[MAX_PATH];
+      TCHAR userHomePath[MAX_PATH], winHome[MAX_PATH];
       ::GetWindowsDirectory(winHome, MAX_PATH);
         // assume this call always succeeds
 
-      sprintf(userHomePath, "%s\\Profiles\\%s", winHome, userId);
+      _stprintf(userHomePath, _T("%s\\Profiles\\%s"), winHome, userId);
       if (dirExists (userHomePath))
-        strcpy(userHome, userHomePath);
+        _tcscpy(userHome, userHomePath);
       else
-        strcpy(userHome, winHome);
+        _tcscpy(userHome, winHome);
     }
 }
@@ -221,13 +325,13 @@
   // A convenience define.
 #define SET(Prop,Val) \
-  newprops->put(JvNewStringLatin1 (Prop), JvNewStringLatin1 (Val))
+  newprops->put(JvNewStringLatin1 (Prop), _Jv_Win32NewString (Val))
 
-  SET ("file.separator", "\\");
-  SET ("path.separator", ";");
-  SET ("line.separator", "\r\n");
+  SET ("file.separator", _T("\\"));
+  SET ("path.separator", _T(";"));
+  SET ("line.separator", _T("\r\n"));
 
   // Use GetCurrentDirectory to set 'user.dir'.
   DWORD buflen = MAX_PATH;
-  char *buffer = (char *) _Jv_MallocUnchecked (buflen);
+  TCHAR buffer[buflen];
   if (buffer != NULL)
     {
@@ -237,16 +341,14 @@
       if (GetTempPath (buflen, buffer))
   SET ("java.io.tmpdir", buffer);
-
-      _Jv_Free (buffer);
     }
 
   // Use GetUserName to set 'user.name'.
   buflen = 257;  // UNLEN + 1
-  char userName[buflen];
+  TCHAR userName[buflen];
   if (GetUserName (userName, &buflen))
     SET ("user.name", userName);
 
   // Set user.home
-  char userHome[MAX_PATH];
+  TCHAR userHome[MAX_PATH];
   getUserHome(userHome, userName);
   SET ("user.home", userHome);
@@ -258,11 +360,9 @@
   if (GetVersionEx (&osvi))
     {
-      char *buffer = (char *) _Jv_MallocUnchecked (30);
       if (buffer != NULL)
         {
-          sprintf (buffer, "%d.%d", (int) osvi.dwMajorVersion,
+          _stprintf (buffer, _T("%d.%d"), (int) osvi.dwMajorVersion,
            (int) osvi.dwMinorVersion);
           SET ("os.version", buffer);
-          _Jv_Free (buffer);
         }
 
@@ -271,26 +371,26 @@
           case VER_PLATFORM_WIN32_WINDOWS:
             if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
-              SET ("os.name", "Windows 95");
+              SET ("os.name", _T("Windows 95"));
             else if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)
-              SET ("os.name", "Windows 98");
+              SET ("os.name", _T("Windows 98"));
             else if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)
-              SET ("os.name", "Windows Me");
+              SET ("os.name", _T("Windows Me"));
             else
-              SET ("os.name", "Windows ??");
+              SET ("os.name", _T("Windows ??"));
             break;
 
           case VER_PLATFORM_WIN32_NT:
             if (osvi.dwMajorVersion <= 4 )
-              SET ("os.name", "Windows NT");
+              SET ("os.name", _T("Windows NT"));
             else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
-              SET ("os.name", "Windows 2000");
+              SET ("os.name", _T("Windows 2000"));
             else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
-              SET ("os.name", "Windows XP");
+              SET ("os.name", _T("Windows XP"));
             else
-              SET ("os.name", "Windows NT ??");
+              SET ("os.name", _T("Windows NT ??"));
             break;
 
           default:
-            SET ("os.name", "Windows UNKNOWN");
+            SET ("os.name", _T("Windows UNKNOWN"));
             break;
        }
@@ -303,21 +403,21 @@
     {
       case PROCESSOR_ARCHITECTURE_INTEL:
-        SET ("os.arch", "x86");
+        SET ("os.arch", _T("x86"));
         break;
       case PROCESSOR_ARCHITECTURE_MIPS:
-        SET ("os.arch", "mips");
+        SET ("os.arch", _T("mips"));
         break;
       case PROCESSOR_ARCHITECTURE_ALPHA:
-        SET ("os.arch", "alpha");
+        SET ("os.arch", _T("alpha"));
         break;
-      case PROCESSOR_ARCHITECTURE_PPC:	
-        SET ("os.arch", "ppc");
+      case PROCESSOR_ARCHITECTURE_PPC:  
+        SET ("os.arch", _T("ppc"));
         break;
       case PROCESSOR_ARCHITECTURE_IA64:
-        SET ("os.arch", "ia64");
+        SET ("os.arch", _T("ia64"));
         break;
       case PROCESSOR_ARCHITECTURE_UNKNOWN:
       default:
-        SET ("os.arch", "unknown");
+        SET ("os.arch", _T("unknown"));
         break;
     }
Index: include/win32.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/include/win32.h,v
retrieving revision 1.24
diff -u -2 -r1.24 win32.h
--- include/win32.h	7 Nov 2003 03:13:55 -0000	1.24
+++ include/win32.h	23 Nov 2003 05:34:23 -0000
@@ -12,4 +12,14 @@
 #define __JV_WIN32_H__
 
+// Enable UNICODE Support.?
+
+#ifdef MINGW_LIBGCJ_UNICODE
+#define UNICODE
+#define _UNICODE
+#endif // MINGW_LIBGCJ_UNICODE
+
+#include <tchar.h>
+
+// Includes
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -23,4 +33,41 @@
 
 #include <io.h>
+
+/* Begin UNICODE Support Classes and Functions */
+
+/* Helper class which creates a temporary, null-terminated,
+   wide-character C string. */
+class _Jv_Win32TempString
+{
+public:
+  _Jv_Win32TempString(jstring jstr);
+  ~_Jv_Win32TempString();
+
+// Accessors
+  operator LPCTSTR() const
+  {
+    return buf_;
+  }
+  LPCTSTR buf() const
+  {
+    return buf_;
+  }
+  LPTSTR buf()
+  {
+    return buf_;
+  }
+
+private:
+  TCHAR stackbuf_[500];
+  LPTSTR buf_;
+};
+
+// Mimics the JV_TEMP_STRING_UTF macro in jvm.h
+#define JV_TEMP_STRING_WIN32(x,y) _Jv_Win32TempString x(y);
+
+// Creates a jstring from a LPCTSTR
+extern jstring _Jv_Win32NewString (LPCTSTR pcsz);
+
+/* End UNICODE Helpers */
 
 // Prefix and suffix for shared libraries.
Index: java/io/natFileDescriptorWin32.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/io/natFileDescriptorWin32.cc,v
retrieving revision 1.16
diff -u -2 -r1.16 natFileDescriptorWin32.cc
--- java/io/natFileDescriptorWin32.cc	7 Nov 2003 03:13:56 -0000	1.16
+++ java/io/natFileDescriptorWin32.cc	23 Nov 2003 05:34:26 -0000
@@ -88,5 +88,5 @@
   DWORD create = OPEN_EXISTING;
   
-  JV_TEMP_UTF_STRING(cpath, path)
+  JV_TEMP_STRING_WIN32(cpath, path)
 
   JvAssert((jflags & READ) || (jflags & WRITE));
@@ -116,5 +116,6 @@
     }
 
-  handle = CreateFile(cpath, access, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, create, 0, NULL);
+  handle = CreateFile(cpath, access, FILE_SHARE_READ | FILE_SHARE_WRITE,
+    NULL, create, 0, NULL);
 
   if (handle == INVALID_HANDLE_VALUE)
@@ -175,4 +176,5 @@
   jbyte *buf = elements (b) + offset;
   DWORD bytesWritten;
+
   if (WriteFile ((HANDLE)fd, buf, len, &bytesWritten, NULL))
     {
@@ -181,5 +183,5 @@
           InterruptedIOException *iioe = new InterruptedIOException (JvNewStringLatin1 ("write interrupted"));
           iioe->bytesTransferred = bytesWritten;
-    throw iioe;
+          throw iioe;
         }
     }
Index: java/io/natFileWin32.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/io/natFileWin32.cc,v
retrieving revision 1.18
diff -u -2 -r1.18 natFileWin32.cc
--- java/io/natFileWin32.cc	31 Oct 2003 03:02:47 -0000	1.18
+++ java/io/natFileWin32.cc	23 Nov 2003 05:34:26 -0000
@@ -41,5 +41,5 @@
 java::io::File::_access (jint query)
 {
-  JV_TEMP_UTF_STRING (canon, getCanonicalPath());
+  JV_TEMP_STRING_WIN32 (canon, getCanonicalPath());
   if (!canon)
     return false;
@@ -55,5 +55,6 @@
     return (attributes == 0xffffffff) ? false : true;
   else
-    return ((attributes != 0xffffffff) && ((attributes & FILE_ATTRIBUTE_READONLY) == 0)) ? true : false;
+    return ((attributes != 0xffffffff) &&
+      ((attributes & FILE_ATTRIBUTE_READONLY) == 0)) ? true : false;
 }
 
@@ -61,5 +62,5 @@
 java::io::File::_stat (jint query)
 {
-  JV_TEMP_UTF_STRING (canon, getCanonicalPath());
+  JV_TEMP_STRING_WIN32 (canon, getCanonicalPath());
   if (!canon)
     return false;
@@ -80,5 +81,5 @@
 java::io::File::attr (jint query)
 {
-  JV_TEMP_UTF_STRING (canon, getCanonicalPath());
+  JV_TEMP_STRING_WIN32 (canon, getCanonicalPath());
   if (!canon)
     return false;
@@ -109,19 +110,17 @@
 java::io::File::getCanonicalPath (void)
 {
-  JV_TEMP_UTF_STRING (cpath, path);
+  JV_TEMP_STRING_WIN32 (cpath, path);
   
   // If the filename is blank, use the current directory.
-  const char* thepath = cpath.buf();
-  if (*thepath == '\0')
-    thepath = ".";
+  LPCTSTR thepath = cpath.buf();
+  if (*thepath == 0)
+    thepath = _T(".");
 
   LPTSTR unused;
-  char buf2[MAX_PATH];
+  TCHAR buf2[MAX_PATH];
   if(!GetFullPathName(thepath, MAX_PATH, buf2, &unused))
     throw new IOException (JvNewStringLatin1 ("GetFullPathName failed"));
 
-  // FIXME: what encoding to assume for file names?  This affects many
-  // calls.
-  return JvNewStringUTF(buf2);
+  return _Jv_Win32NewString (buf2);
 }
 
@@ -162,10 +161,15 @@
   if (! canon)
     return NULL;
-  char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (canon) + 5);
-  jsize total = JvGetStringUTFRegion (canon, 0, canon->length(), buf);
-  if (buf[total-1] == '\\')
-    strcpy (&buf[total], "*.*");
+
+  int len = canon->length();
+  TCHAR buf[len + 5];
+  
+  JV_TEMP_STRING_WIN32(canonstr, canon);
+  
+  _tcscpy(buf, canonstr);
+  if (buf[len - 1] == _T('\\'))
+    _tcscpy (&buf[len], _T("*.*"));
   else
-    strcpy (&buf[total], "\\*.*");
+    _tcscpy (&buf[len], _T("\\*.*"));
 
   WIN32_FIND_DATA data;
@@ -178,19 +182,20 @@
   do
     {
-      if (strcmp (data.cFileName, ".") && strcmp (data.cFileName, ".."))
+      if (_tcscmp (data.cFileName, _T(".")) &&
+        _tcscmp (data.cFileName, _T("..")))
         {
-          jstring name = JvNewStringUTF (data.cFileName);
+          jstring name = _Jv_Win32NewString (data.cFileName);
 
           if (filter && !filter->accept(this, name))
-      continue;
+            continue;
           if (clazz == &java::io::File::class$)
-      {
+            {
               java::io::File *file = new java::io::File (this, name);
               if (fileFilter && !fileFilter->accept(file))
-    continue;
-        vec->addElement (file);
-      }
-    else
-      vec->addElement (name);
+                continue;
+              vec->addElement (file);
+            }
+          else
+            vec->addElement (name);
         }
     }
@@ -210,5 +215,5 @@
 java::io::File::performMkdir (void)
 {
-  JV_TEMP_UTF_STRING (cpath, path);
+  JV_TEMP_STRING_WIN32 (cpath, path);
   return (CreateDirectory(cpath, NULL)) ? true : false;
 }
@@ -217,6 +222,6 @@
 java::io::File::performRenameTo (File *dest)
 {
-  JV_TEMP_UTF_STRING (pathFrom, path);
-  JV_TEMP_UTF_STRING (pathTo, dest->path);
+  JV_TEMP_STRING_WIN32 (pathFrom, path);
+  JV_TEMP_STRING_WIN32 (pathTo, dest->path);
   return (MoveFile(pathFrom, pathTo)) ? true : false;
 }
@@ -225,5 +230,5 @@
 java::io::File::performDelete ()
 {
-  JV_TEMP_UTF_STRING (canon, getCanonicalPath());
+  JV_TEMP_STRING_WIN32 (canon, getCanonicalPath());
   if (!canon)
     return false;
@@ -241,5 +246,5 @@
 jboolean java::io::File::performCreate (void) 
 {
-  JV_TEMP_UTF_STRING (canon, getCanonicalPath());
+  JV_TEMP_STRING_WIN32 (canon, getCanonicalPath());
   if (!canon)
     return false;
@@ -263,5 +268,5 @@
 jboolean java::io::File::performSetReadOnly ()
 {
-  JV_TEMP_UTF_STRING (canon, getCanonicalPath());
+  JV_TEMP_STRING_WIN32 (canon, getCanonicalPath());
   if (!canon)
     return false;
@@ -281,5 +286,5 @@
 jboolean java::io::File::performSetLastModified (jlong time)
 {
-  JV_TEMP_UTF_STRING (canon, getCanonicalPath());
+  JV_TEMP_STRING_WIN32 (canon, getCanonicalPath());
   if (!canon)
     return false;
Index: java/lang/natWin32Process.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natWin32Process.cc,v
retrieving revision 1.8
diff -u -2 -r1.8 natWin32Process.cc
--- java/lang/natWin32Process.cc	14 Nov 2003 01:48:30 -0000	1.8
+++ java/lang/natWin32Process.cc	23 Nov 2003 05:34:27 -0000
@@ -174,5 +174,5 @@
       DWORD dwErrorCode = GetLastError ();
       throw new java::io::IOException (
-        _Jv_WinStrError ("Error creating pipe", dwErrorCode));
+        _Jv_WinStrError (_T("Error creating pipe"), dwErrorCode));
     }
 
@@ -221,21 +221,23 @@
 
   for (int i = 0; i < progarray->length; ++i)
-    cmdLineLen += (_Jv_GetStringUTFLength (elts[i]) + 1);
+    cmdLineLen += (elts[i]->length() + 1);
 
-  char *cmdLine = (char *) _Jv_Malloc (cmdLineLen + 1);
-  char *cmdLineCurPos = cmdLine;
+  LPTSTR cmdLine = (LPTSTR) _Jv_Malloc ((cmdLineLen + 1) * sizeof(TCHAR));
+  LPTSTR cmdLineCurPos = cmdLine;
 
   for (int i = 0; i < progarray->length; ++i)
     {
       if (i > 0)
-        *cmdLineCurPos++ = ' ';
-      jsize s = _Jv_GetStringUTFLength (elts[i]);
-      _Jv_GetStringUTFRegion (elts[i], 0, elts[i]->length(), cmdLineCurPos);
-      cmdLineCurPos += s;
+        *cmdLineCurPos++ = _T(' ');
+        
+      jint len = elts[i]->length();
+      JV_TEMP_STRING_WIN32(thiselt, elts[i]);
+      _tcscpy(cmdLineCurPos, thiselt);
+      cmdLineCurPos += len;
     }
-  *cmdLineCurPos = '\0';
+  *cmdLineCurPos = _T('\0');
 
   // Get the environment, if any.
-  char *env = NULL;
+  LPTSTR env = NULL;
   if (envp)
     {
@@ -244,23 +246,26 @@
       int envLen = 0;
       for (int i = 0; i < envp->length; ++i)
-        envLen += (_Jv_GetStringUTFLength (elts[i]) + 1);
+        envLen += (elts[i]->length() + 1);
 
-      env = (char *) _Jv_Malloc (envLen + 1);
+      env = (LPTSTR) _Jv_Malloc ((envLen + 1) * sizeof(TCHAR));
 
       int j = 0;
       for (int i = 0; i < envp->length; ++i)
         {
-          jsize s = _Jv_GetStringUTFLength (elts[i]);
-          _Jv_GetStringUTFRegion (elts[i], 0, elts[i]->length(), (env + j));
-
-          j += s;
-          *(env + j) = '\0';
+          jint len = elts[i]->length();
+          
+          JV_TEMP_STRING_WIN32(thiselt, elts[i]);
+          _tcscpy(env + j, thiselt);
+          
+          j += len;
+          
+          // Skip past the null terminator that _tcscpy just inserted.
           j++;
         }
-      *(env + j) = '\0';
+      *(env + j) = _T('\0');
     }
 
   // Get the working directory path, if specified.
-  JV_TEMP_UTF_STRING (wdir, dir ? dir->getPath () : 0);
+  JV_TEMP_STRING_WIN32 (wdir, dir ? dir->getPath () : 0);
 
   errorStream = NULL;
@@ -305,4 +310,5 @@
       // creation of a console window. This flag is ignored on
       // Win9X.
+      
       if (CreateProcess (NULL,
                          cmdLine,
@@ -310,5 +316,5 @@
                          NULL,
                          1,
-                         CREATE_NO_WINDOW,
+                         CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,
                          env,
                          wdir,
@@ -318,5 +324,5 @@
           DWORD dwErrorCode = GetLastError ();
           throw new IOException (
-            _Jv_WinStrError ("Error creating child process", dwErrorCode));
+            _Jv_WinStrError (_T("Error creating child process"), dwErrorCode));
         }
 
Index: java/net/natNetworkInterfaceWin32.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/net/natNetworkInterfaceWin32.cc,v
retrieving revision 1.4
diff -u -2 -r1.4 natNetworkInterfaceWin32.cc
--- java/net/natNetworkInterfaceWin32.cc	29 Aug 2003 04:21:01 -0000	1.4
+++ java/net/natNetworkInterfaceWin32.cc	23 Nov 2003 05:34:31 -0000
@@ -71,16 +71,16 @@
       // "lo" for the loopback interface and ethX for the
       // real ones.
-      char szName[30];
+      TCHAR szName[30];
       u_long lFlags = arInterfaceInfo[i].iiFlags;
 
       if (lFlags & IFF_LOOPBACK)
-        strcpy (szName, "lo");
+        _tcscpy (szName, _T("lo"));
       else
         {
-          strcpy (szName, "eth");
-          wsprintf(szName+3, "%d", nCurETHInterface++);
+          _tcscpy (szName, _T("eth"));
+          wsprintf(szName+3, _T("%d"), nCurETHInterface++);
         }
 
-      jstring if_name = JvNewStringLatin1 (szName);
+      jstring if_name = _Jv_Win32NewString (szName);
       java::net::Inet4Address* address =
         new java::net::Inet4Address (baddr, JvNewStringLatin1 (""));





More information about the Java mailing list