Hi,

The attached patch changes the code that currently parses LC_CTYPE to
set encoding, encoding variants, language and country to use LC_CTYPE
just to set the encoding, and instead uses LC_MESSAGES to set country
and language.

The reason for this change si that in a system where LC_MESSAGES is set
to English, you'd expect Java to answer in English, rather than Italian
by default (this is true for both JDK's commands and for Java-based
interfaces).

The patch is probably rough, so I'd be happy to hear comments on what
to improve of it.

-- 
Diego "Flameeyes" Pettenò
http://farragut.flameeyes.is-a-geek.org/
Index: openjdk-b13/j2se/src/solaris/native/java/lang/java_props_md.c
===================================================================
--- openjdk-b13.orig/j2se/src/solaris/native/java/lang/java_props_md.c
+++ openjdk-b13/j2se/src/solaris/native/java/lang/java_props_md.c
@@ -115,6 +115,60 @@ setPathEnvironment(char *envstring)
 #define P_tmpdir "/var/tmp"
 #endif
 
+static char *
+setlocale_with_fallback(int category, const char *locale)
+{
+  char *lc = setlocale(category, locale);
+#ifndef __linux__
+  if (lc == NULL) {
+    /*
+     * 'lc == null' means system doesn't support user's environment
+     * variable's locale.
+     */
+    setlocale(LC_ALL, "C");
+  }
+#else
+  if (lc == NULL || !strcmp(lc, "C") || !strcmp(lc, "POSIX")) {
+    return "en_US";
+  }
+#endif
+
+  return lc;
+}
+
+/* Parse the language, country, encoding, and variant from the
+ * locale.  Any of the elements may be missing, but they must occur
+ * in the order [EMAIL PROTECTED], and must be
+ * preceded by their delimiter (except for language).
+ *
+ * If the locale name (without [EMAIL PROTECTED], if any) matches
+ * any of the names in the locale_aliases list, map it to the
+ * corresponding full locale name.  Most of the entries in the
+ * locale_aliases list are locales that include a language name but
+ * no country name, and this facility is used to map each language
+ * to a default country if that's possible.  It's also used to map
+ * the Solaris locale aliases to their proper Java locale IDs.
+ */
+static char *
+normalise_locale_name(char *locale)
+{
+  char *p = NULL, *ret = NULL;
+
+  if ((p = strchr(locale, '.')) != NULL) {
+    ret = strdup(p); /* Copy the leading '.' */
+    *p = '\0';
+  } else if ((p = strchr(locale, '@')) != NULL) {
+    ret = strdup(p); /* Copy the leading '@' */
+    *p = '\0';
+  }
+
+  if (mapLookup(locale_aliases, locale, &p)) {
+    strcpy(locale, p);
+  }
+
+  return ret;
+}
+
 /* This function gets called very early, before VM_CALLS are setup.
  * Do not use any of the VM_CALLS entries!!!
  */
@@ -186,26 +240,11 @@ GetJavaProperties(JNIEnv *env)
      * and store these in the user.language, user.country, user.variant and
      * file.encoding system properties. */
     {
-        char *lc;
-        lc = setlocale(LC_CTYPE, "");
-#ifndef __linux__
-        if (lc == NULL) {
-            /*
-             * 'lc == null' means system doesn't support user's environment
-             * variable's locale.
-             */
-          setlocale(LC_ALL, "C");
-          sprops.language = "en";
+      char *lc = setlocale_with_fallback(LC_CTYPE, "");
+      if ( lc == NULL ) {
           sprops.encoding = "ISO8859-1";
           sprops.sun_jnu_encoding = sprops.encoding;
         } else {
-#else
-        if (lc == NULL || !strcmp(lc, "C") || !strcmp(lc, "POSIX")) {
-            lc = "en_US";
-        }
-        {
-#endif
-
             /*
              * locale string format in Solaris is
              * <language name>_<country name>.<encoding name>@<variant name>
@@ -216,7 +255,7 @@ GetJavaProperties(JNIEnv *env)
                  *encoding = NULL;
             char *std_language = NULL, *std_country = NULL, *std_variant = NULL,
                  *std_encoding = NULL;
-            char *p, encoding_variant[64];
+            char *p, *encoding_variant = NULL;
             int i, found;
 
 #ifndef __linux__
@@ -238,61 +277,45 @@ GetJavaProperties(JNIEnv *env)
 #endif
 
             strcpy(temp, lc);
+            encoding_variant = normalise_locale_name(temp);
 
-            /* Parse the language, country, encoding, and variant from the
-             * locale.  Any of the elements may be missing, but they must occur
-             * in the order [EMAIL PROTECTED], and must be
-             * preceded by their delimiter (except for language).
-             *
-             * If the locale name (without [EMAIL PROTECTED], if any) matches
-             * any of the names in the locale_aliases list, map it to the
-             * corresponding full locale name.  Most of the entries in the
-             * locale_aliases list are locales that include a language name but
-             * no country name, and this facility is used to map each language
-             * to a default country if that's possible.  It's also used to map
-             * the Solaris locale aliases to their proper Java locale IDs.
-             */
-            if ((p = strchr(temp, '.')) != NULL) {
-                strcpy(encoding_variant, p); /* Copy the leading '.' */
-                *p = '\0';
-            } else if ((p = strchr(temp, '@')) != NULL) {
-                 strcpy(encoding_variant, p); /* Copy the leading '@' */
-                 *p = '\0';
-            } else {
-                *encoding_variant = '\0';
-            }
-            
-            if (mapLookup(locale_aliases, temp, &p)) {
-                strcpy(temp, p);
-            }
-            
-            language = temp;
-            if ((country = strchr(temp, '_')) != NULL) {
-                *country++ = '\0';
-            }
-            
-            p = encoding_variant;
-            if ((encoding = strchr(p, '.')) != NULL) {
+	    {
+	      language = setlocale_with_fallback(LC_MESSAGES, "");
+	      /* We don't care about the encoding variant of this. */
+	      free(normalise_locale_name(language));
+
+	      if ( ! language ) {
+		sprops.language = "en";
+	      } else {
+		language = strdup(language);
+		if ((country = strchr(language, '_')) != NULL) {
+		  *country++ = '\0';
+		  if ((p = strchr(country, '.')) != NULL )
+		    *p = '\0';
+
+		  std_country = country;
+		  mapLookup(country_names, country, &std_country);
+		  sprops.country = strdup(std_country);
+		}
+
+		/* Normalize the language name */
+		std_language = "en";
+		mapLookup(language_names, language, &std_language);
+		
+		sprops.language = std_language;
+	      }
+	    }
+
+	    if (encoding_variant != NULL) {
+	      p = encoding_variant;
+	      if ((encoding = strchr(p, '.')) != NULL) {
                 p[encoding++ - p] = '\0';
                 p = encoding;
-            }
-            if ((variant = strchr(p, '@')) != NULL) {
+	      }
+	      if ((variant = strchr(p, '@')) != NULL) {
                 p[variant++ - p] = '\0';
-            }
-
-            /* Normalize the language name */
-            std_language = "en";
-            if (language != NULL) {
-                mapLookup(language_names, language, &std_language);
-            }
-            sprops.language = std_language;
-
-            /* Normalize the country name */
-            if (country != NULL) {
-                std_country = country;
-                mapLookup(country_names, country, &std_country);
-                sprops.country = strdup(std_country);
-            }
+	      }
+	    }
 
             /* Normalize the variant name.  Note that we only use
              * variants listed in the mapping array; others are ignored. */
@@ -311,7 +334,7 @@ GetJavaProperties(JNIEnv *env)
 
 	    /* OK, not so reliable - nl_langinfo() gives wrong answers on
 	     * Euro locales, in particular. */
-	    if (strcmp(p, "ISO8859-15") == 0)
+	    if (p != NULL && strcmp(p, "ISO8859-15") == 0)
 		p = "ISO8859-15";
 	    else		
                 p = nl_langinfo(CODESET);

Attachment: signature.asc
Description: PGP signature

Reply via email to