提交 1e4cca65 编写于 作者: N naoto

4700857: RFE: separating user locale and user interface locale

Reviewed-by: okutsu
上级 8bc5d2d9
......@@ -443,7 +443,7 @@ public abstract class DateFormat extends Format {
*/
public final static DateFormat getTimeInstance()
{
return get(DEFAULT, 0, 1, Locale.getDefault());
return get(DEFAULT, 0, 1, Locale.getDefault(Locale.Category.FORMAT));
}
/**
......@@ -455,7 +455,7 @@ public abstract class DateFormat extends Format {
*/
public final static DateFormat getTimeInstance(int style)
{
return get(style, 0, 1, Locale.getDefault());
return get(style, 0, 1, Locale.getDefault(Locale.Category.FORMAT));
}
/**
......@@ -479,7 +479,7 @@ public abstract class DateFormat extends Format {
*/
public final static DateFormat getDateInstance()
{
return get(0, DEFAULT, 2, Locale.getDefault());
return get(0, DEFAULT, 2, Locale.getDefault(Locale.Category.FORMAT));
}
/**
......@@ -491,7 +491,7 @@ public abstract class DateFormat extends Format {
*/
public final static DateFormat getDateInstance(int style)
{
return get(0, style, 2, Locale.getDefault());
return get(0, style, 2, Locale.getDefault(Locale.Category.FORMAT));
}
/**
......@@ -515,7 +515,7 @@ public abstract class DateFormat extends Format {
*/
public final static DateFormat getDateTimeInstance()
{
return get(DEFAULT, DEFAULT, 3, Locale.getDefault());
return get(DEFAULT, DEFAULT, 3, Locale.getDefault(Locale.Category.FORMAT));
}
/**
......@@ -530,7 +530,7 @@ public abstract class DateFormat extends Format {
public final static DateFormat getDateTimeInstance(int dateStyle,
int timeStyle)
{
return get(timeStyle, dateStyle, 3, Locale.getDefault());
return get(timeStyle, dateStyle, 3, Locale.getDefault(Locale.Category.FORMAT));
}
/**
......
......@@ -118,7 +118,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
*/
public DateFormatSymbols()
{
initializeData(Locale.getDefault());
initializeData(Locale.getDefault(Locale.Category.FORMAT));
}
/**
......@@ -282,7 +282,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
* @since 1.6
*/
public static final DateFormatSymbols getInstance() {
return getInstance(Locale.getDefault());
return getInstance(Locale.getDefault(Locale.Category.FORMAT));
}
/**
......
......@@ -392,7 +392,7 @@ public class DecimalFormat extends NumberFormat {
* @see java.text.NumberFormat#getPercentInstance
*/
public DecimalFormat() {
Locale def = Locale.getDefault();
Locale def = Locale.getDefault(Locale.Category.FORMAT);
// try to get the pattern from the cache
String pattern = (String) cachedLocaleData.get(def);
if (pattern == null) { /* cache miss */
......@@ -430,7 +430,7 @@ public class DecimalFormat extends NumberFormat {
*/
public DecimalFormat(String pattern) {
// Always applyPattern after the symbols are set
this.symbols = new DecimalFormatSymbols(Locale.getDefault());
this.symbols = new DecimalFormatSymbols(Locale.getDefault(Locale.Category.FORMAT));
applyPattern(pattern, false);
}
......
......@@ -76,7 +76,7 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
* {@link #getInstance(Locale) getInstance} method.
*/
public DecimalFormatSymbols() {
initialize( Locale.getDefault() );
initialize( Locale.getDefault(Locale.Category.FORMAT) );
}
/**
......@@ -125,7 +125,7 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
* @since 1.6
*/
public static final DecimalFormatSymbols getInstance() {
return getInstance(Locale.getDefault());
return getInstance(Locale.getDefault(Locale.Category.FORMAT));
}
/**
......
......@@ -363,7 +363,7 @@ public class MessageFormat extends Format {
* @exception IllegalArgumentException if the pattern is invalid
*/
public MessageFormat(String pattern) {
this.locale = Locale.getDefault();
this.locale = Locale.getDefault(Locale.Category.FORMAT);
applyPattern(pattern);
}
......
......@@ -381,7 +381,7 @@ public abstract class NumberFormat extends Format {
* {@link #getNumberInstance() getNumberInstance()}.
*/
public final static NumberFormat getInstance() {
return getInstance(Locale.getDefault(), NUMBERSTYLE);
return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE);
}
/**
......@@ -397,7 +397,7 @@ public abstract class NumberFormat extends Format {
* Returns a general-purpose number format for the current default locale.
*/
public final static NumberFormat getNumberInstance() {
return getInstance(Locale.getDefault(), NUMBERSTYLE);
return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE);
}
/**
......@@ -420,7 +420,7 @@ public abstract class NumberFormat extends Format {
* @since 1.4
*/
public final static NumberFormat getIntegerInstance() {
return getInstance(Locale.getDefault(), INTEGERSTYLE);
return getInstance(Locale.getDefault(Locale.Category.FORMAT), INTEGERSTYLE);
}
/**
......@@ -443,7 +443,7 @@ public abstract class NumberFormat extends Format {
* Returns a currency format for the current default locale.
*/
public final static NumberFormat getCurrencyInstance() {
return getInstance(Locale.getDefault(), CURRENCYSTYLE);
return getInstance(Locale.getDefault(Locale.Category.FORMAT), CURRENCYSTYLE);
}
/**
......@@ -457,7 +457,7 @@ public abstract class NumberFormat extends Format {
* Returns a percentage format for the current default locale.
*/
public final static NumberFormat getPercentInstance() {
return getInstance(Locale.getDefault(), PERCENTSTYLE);
return getInstance(Locale.getDefault(Locale.Category.FORMAT), PERCENTSTYLE);
}
/**
......@@ -471,7 +471,7 @@ public abstract class NumberFormat extends Format {
* Returns a scientific format for the current default locale.
*/
/*public*/ final static NumberFormat getScientificInstance() {
return getInstance(Locale.getDefault(), SCIENTIFICSTYLE);
return getInstance(Locale.getDefault(Locale.Category.FORMAT), SCIENTIFICSTYLE);
}
/**
......
......@@ -474,7 +474,7 @@ public class SimpleDateFormat extends DateFormat {
* class.
*/
public SimpleDateFormat() {
this(SHORT, SHORT, Locale.getDefault());
this(SHORT, SHORT, Locale.getDefault(Locale.Category.FORMAT));
}
/**
......@@ -490,7 +490,7 @@ public class SimpleDateFormat extends DateFormat {
*/
public SimpleDateFormat(String pattern)
{
this(pattern, Locale.getDefault());
this(pattern, Locale.getDefault(Locale.Category.FORMAT));
}
/**
......@@ -535,7 +535,7 @@ public class SimpleDateFormat extends DateFormat {
this.pattern = pattern;
this.formatData = (DateFormatSymbols) formatSymbols.clone();
this.locale = Locale.getDefault();
this.locale = Locale.getDefault(Locale.Category.FORMAT);
initializeCalendar(this.locale);
initialize(this.locale);
useDateFormatSymbols = true;
......
......@@ -933,7 +933,7 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
*/
protected Calendar()
{
this(TimeZone.getDefaultRef(), Locale.getDefault());
this(TimeZone.getDefaultRef(), Locale.getDefault(Locale.Category.FORMAT));
sharedZone = true;
}
......@@ -962,7 +962,7 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
*/
public static Calendar getInstance()
{
Calendar cal = createCalendar(TimeZone.getDefaultRef(), Locale.getDefault());
Calendar cal = createCalendar(TimeZone.getDefaultRef(), Locale.getDefault(Locale.Category.FORMAT));
cal.sharedZone = true;
return cal;
}
......@@ -977,7 +977,7 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
*/
public static Calendar getInstance(TimeZone zone)
{
return createCalendar(zone, Locale.getDefault());
return createCalendar(zone, Locale.getDefault(Locale.Category.FORMAT));
}
/**
......
......@@ -452,7 +452,7 @@ public final class Currency implements Serializable {
* @return the symbol of this currency for the default locale
*/
public String getSymbol() {
return getSymbol(Locale.getDefault());
return getSymbol(Locale.getDefault(Locale.Category.DISPLAY));
}
/**
......@@ -528,7 +528,7 @@ public final class Currency implements Serializable {
* @since 1.7
*/
public String getDisplayName() {
return getDisplayName(Locale.getDefault());
return getDisplayName(Locale.getDefault(Locale.Category.DISPLAY));
}
/**
......
......@@ -1866,7 +1866,7 @@ public final class Formatter implements Closeable, Flushable {
* virtual machine.
*/
public Formatter() {
init(new StringBuilder(), Locale.getDefault());
init(new StringBuilder(), Locale.getDefault(Locale.Category.FORMAT));
}
/**
......@@ -1882,7 +1882,7 @@ public final class Formatter implements Closeable, Flushable {
public Formatter(Appendable a) {
if (a == null)
a = new StringBuilder();
init(a, Locale.getDefault());
init(a, Locale.getDefault(Locale.Category.FORMAT));
}
/**
......@@ -1949,7 +1949,7 @@ public final class Formatter implements Closeable, Flushable {
*/
public Formatter(String fileName) throws FileNotFoundException {
init(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))),
Locale.getDefault());
Locale.getDefault(Locale.Category.FORMAT));
}
/**
......@@ -1985,7 +1985,7 @@ public final class Formatter implements Closeable, Flushable {
public Formatter(String fileName, String csn)
throws FileNotFoundException, UnsupportedEncodingException
{
this(fileName, csn, Locale.getDefault());
this(fileName, csn, Locale.getDefault(Locale.Category.FORMAT));
}
/**
......@@ -2057,7 +2057,7 @@ public final class Formatter implements Closeable, Flushable {
*/
public Formatter(File file) throws FileNotFoundException {
init(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file))),
Locale.getDefault());
Locale.getDefault(Locale.Category.FORMAT));
}
/**
......@@ -2093,7 +2093,7 @@ public final class Formatter implements Closeable, Flushable {
public Formatter(File file, String csn)
throws FileNotFoundException, UnsupportedEncodingException
{
this(file, csn, Locale.getDefault());
this(file, csn, Locale.getDefault(Locale.Category.FORMAT));
}
/**
......@@ -2152,7 +2152,7 @@ public final class Formatter implements Closeable, Flushable {
public Formatter(PrintStream ps) {
if (ps == null)
throw new NullPointerException();
init((Appendable)ps, Locale.getDefault());
init((Appendable)ps, Locale.getDefault(Locale.Category.FORMAT));
}
/**
......@@ -2171,7 +2171,7 @@ public final class Formatter implements Closeable, Flushable {
*/
public Formatter(OutputStream os) {
init(new BufferedWriter(new OutputStreamWriter(os)),
Locale.getDefault());
Locale.getDefault(Locale.Category.FORMAT));
}
/**
......@@ -2195,7 +2195,7 @@ public final class Formatter implements Closeable, Flushable {
public Formatter(OutputStream os, String csn)
throws UnsupportedEncodingException
{
this(os, csn, Locale.getDefault());
this(os, csn, Locale.getDefault(Locale.Category.FORMAT));
}
/**
......
......@@ -555,7 +555,7 @@ public class GregorianCalendar extends Calendar {
* in the default time zone with the default locale.
*/
public GregorianCalendar() {
this(TimeZone.getDefaultRef(), Locale.getDefault());
this(TimeZone.getDefaultRef(), Locale.getDefault(Locale.Category.FORMAT));
setZoneShared(true);
}
......@@ -566,7 +566,7 @@ public class GregorianCalendar extends Calendar {
* @param zone the given time zone.
*/
public GregorianCalendar(TimeZone zone) {
this(zone, Locale.getDefault());
this(zone, Locale.getDefault(Locale.Category.FORMAT));
}
/**
......
......@@ -395,31 +395,103 @@ public final class Locale implements Cloneable, Serializable {
// do not synchronize this method - see 4071298
// it's OK if more than one default locale happens to be created
if (defaultLocale == null) {
String language, region, country, variant;
initDefault();
}
return defaultLocale;
}
/**
* Gets the current value of the default locale for the specified Category
* for this instance of the Java Virtual Machine.
* <p>
* The Java Virtual Machine sets the default locale during startup based
* on the host environment. It is used by many locale-sensitive methods
* if no locale is explicitly specified. It can be changed using the
* setDefault(Locale.Category, Locale) method.
*
* @param category - the specified category to get the default locale
* @throws NullPointerException - if category is null
* @return the default locale for the specified Category for this instance
* of the Java Virtual Machine
* @see #setDefault(Locale.Category, Locale)
* @since 1.7
*/
public static Locale getDefault(Locale.Category category) {
// do not synchronize this method - see 4071298
// it's OK if more than one default locale happens to be created
switch (category) {
case DISPLAY:
if (defaultDisplayLocale == null) {
initDefault(category);
}
return defaultDisplayLocale;
case FORMAT:
if (defaultFormatLocale == null) {
initDefault(category);
}
return defaultFormatLocale;
default:
assert false: "Unknown Category";
}
return getDefault();
}
private static void initDefault() {
String language, region, country, variant;
language = AccessController.doPrivileged(
new GetPropertyAction("user.language", "en"));
// for compatibility, check for old user.region property
region = AccessController.doPrivileged(
new GetPropertyAction("user.region"));
if (region != null) {
// region can be of form country, country_variant, or _variant
int i = region.indexOf('_');
if (i >= 0) {
country = region.substring(0, i);
variant = region.substring(i + 1);
} else {
country = region;
variant = "";
}
} else {
country = AccessController.doPrivileged(
new GetPropertyAction("user.country", ""));
variant = AccessController.doPrivileged(
new GetPropertyAction("user.variant", ""));
}
defaultLocale = getInstance(language, country, variant);
}
private static void initDefault(Locale.Category category) {
String language, region, country, variant;
switch (category) {
case DISPLAY:
language = AccessController.doPrivileged(
new GetPropertyAction("user.language", "en"));
// for compatibility, check for old user.region property
region = AccessController.doPrivileged(
new GetPropertyAction("user.region"));
if (region != null) {
// region can be of form country, country_variant, or _variant
int i = region.indexOf('_');
if (i >= 0) {
country = region.substring(0, i);
variant = region.substring(i + 1);
} else {
country = region;
variant = "";
}
new GetPropertyAction("user.language.display", ""));
if ("".equals(language)) {
defaultDisplayLocale = getDefault();
} else {
country = AccessController.doPrivileged(
new GetPropertyAction("user.country", ""));
new GetPropertyAction("user.country.display", ""));
variant = AccessController.doPrivileged(
new GetPropertyAction("user.variant", ""));
new GetPropertyAction("user.variant.display", ""));
defaultDisplayLocale = getInstance(language, country, variant);
}
defaultLocale = getInstance(language, country, variant);
break;
case FORMAT:
language = AccessController.doPrivileged(
new GetPropertyAction("user.language.format", ""));
if ("".equals(language)) {
defaultFormatLocale = getDefault();
} else {
country = AccessController.doPrivileged(
new GetPropertyAction("user.country.format", ""));
variant = AccessController.doPrivileged(
new GetPropertyAction("user.variant.format", ""));
defaultFormatLocale = getInstance(language, country, variant);
}
break;
}
return defaultLocale;
}
/**
......@@ -438,6 +510,9 @@ public final class Locale implements Cloneable, Serializable {
* of functionality, this method should only be used if the caller
* is prepared to reinitialize locale-sensitive code running
* within the same Java Virtual Machine.
* <p>
* By setting the default locale with this method, all of the default
* locales for each Category are also set to the specified default locale.
*
* @throws SecurityException
* if a security manager exists and its
......@@ -448,13 +523,59 @@ public final class Locale implements Cloneable, Serializable {
* @see java.util.PropertyPermission
*/
public static synchronized void setDefault(Locale newLocale) {
setDefault(Category.DISPLAY, newLocale);
setDefault(Category.FORMAT, newLocale);
defaultLocale = newLocale;
}
/**
* Sets the default locale for the specified Category for this instance
* of the Java Virtual Machine. This does not affect the host locale.
* <p>
* If there is a security manager, its checkPermission method is called
* with a PropertyPermission("user.language", "write") permission before
* the default locale is changed.
* <p>
* The Java Virtual Machine sets the default locale during startup based
* on the host environment. It is used by many locale-sensitive methods
* if no locale is explicitly specified.
* <p>
* Since changing the default locale may affect many different areas of
* functionality, this method should only be used if the caller is
* prepared to reinitialize locale-sensitive code running within the
* same Java Virtual Machine.
* <p>
*
* @param category - the specified category to set the default locale
* @param newLocale - the new default locale
* @throws SecurityException - if a security manager exists and its
* checkPermission method doesn't allow the operation.
* @throws NullPointerException - if category and/or newLocale is null
* @see SecurityManager.checkPermission(java.security.Permission)
* @see PropertyPermission
* @see #getDefault(Locale.Category)
* @since 1.7
*/
public static synchronized void setDefault(Locale.Category category,
Locale newLocale) {
if (category == null)
throw new NullPointerException("Category cannot be NULL");
if (newLocale == null)
throw new NullPointerException("Can't set default locale to NULL");
SecurityManager sm = System.getSecurityManager();
if (sm != null) sm.checkPermission(new PropertyPermission
("user.language", "write"));
defaultLocale = newLocale;
switch (category) {
case DISPLAY:
defaultDisplayLocale = newLocale;
break;
case FORMAT:
defaultFormatLocale = newLocale;
break;
default:
assert false: "Unknown Category";
}
}
/**
......@@ -642,7 +763,7 @@ public final class Locale implements Cloneable, Serializable {
* value. If the locale doesn't specify a language, this function returns the empty string.
*/
public final String getDisplayLanguage() {
return getDisplayLanguage(getDefault());
return getDisplayLanguage(getDefault(Category.DISPLAY));
}
/**
......@@ -677,7 +798,7 @@ public final class Locale implements Cloneable, Serializable {
* value. If the locale doesn't specify a country, this function returns the empty string.
*/
public final String getDisplayCountry() {
return getDisplayCountry(getDefault());
return getDisplayCountry(getDefault(Category.DISPLAY));
}
/**
......@@ -744,7 +865,7 @@ public final class Locale implements Cloneable, Serializable {
* doesn't specify a variant code, this function returns the empty string.
*/
public final String getDisplayVariant() {
return getDisplayVariant(getDefault());
return getDisplayVariant(getDefault(Category.DISPLAY));
}
/**
......@@ -790,7 +911,7 @@ public final class Locale implements Cloneable, Serializable {
* and variant fields are all empty, this function returns the empty string.
*/
public final String getDisplayName() {
return getDisplayName(getDefault());
return getDisplayName(getDefault(Category.DISPLAY));
}
/**
......@@ -970,6 +1091,8 @@ public final class Locale implements Cloneable, Serializable {
private transient volatile int hashCodeValue = 0;
private static Locale defaultLocale = null;
private static Locale defaultDisplayLocale = null;
private static Locale defaultFormatLocale = null;
/**
* Return an array of the display names of the variant.
......@@ -1140,4 +1263,28 @@ public final class Locale implements Cloneable, Serializable {
return null;
}
}
/**
* Enum for locale categories. These locale categories are used to get/set
* the default locale for the specific functionality represented by the
* category.
*
* @see #getDefault(Locale.Category)
* @see #setDefault(Locale.Category, Locale)
* @since 1.7
*/
public enum Category {
/**
* Category used to represent the default locale for
* displaying user interfaces.
*/
DISPLAY,
/**
* Category used to represent the default locale for
* formatting dates, numbers, and/or currencies.
*/
FORMAT,
}
}
......@@ -582,7 +582,7 @@ public final class Scanner implements Iterator<String>, Closeable {
matcher = delimPattern.matcher(buf);
matcher.useTransparentBounds(true);
matcher.useAnchoringBounds(false);
useLocale(Locale.getDefault());
useLocale(Locale.getDefault(Locale.Category.FORMAT));
}
/**
......@@ -2642,7 +2642,7 @@ public final class Scanner implements Iterator<String>, Closeable {
*/
public Scanner reset() {
delimPattern = WHITESPACE_PATTERN;
useLocale(Locale.getDefault());
useLocale(Locale.getDefault(Locale.Category.FORMAT));
useRadix(10);
clearCaches();
return this;
......
......@@ -312,7 +312,7 @@ abstract public class TimeZone implements Serializable, Cloneable {
* @since 1.2
*/
public final String getDisplayName() {
return getDisplayName(false, LONG, Locale.getDefault());
return getDisplayName(false, LONG, Locale.getDefault(Locale.Category.DISPLAY));
}
/**
......@@ -342,7 +342,7 @@ abstract public class TimeZone implements Serializable, Cloneable {
* @since 1.2
*/
public final String getDisplayName(boolean daylight, int style) {
return getDisplayName(daylight, style, Locale.getDefault());
return getDisplayName(daylight, style, Locale.getDefault(Locale.Category.DISPLAY));
}
/**
......
......@@ -80,6 +80,21 @@ Java_java_lang_System_identityHashCode(JNIEnv *env, jobject this, jobject x)
(*env)->DeleteLocalRef(env, jval); \
(*env)->DeleteLocalRef(env, r); \
} else ((void) 0)
#define REMOVEPROP(props, key) \
if (1) { \
jstring jkey = JNU_NewStringPlatform(env, key); \
jobject r = (*env)->CallObjectMethod(env, props, removeID, jkey); \
if ((*env)->ExceptionOccurred(env)) return NULL; \
(*env)->DeleteLocalRef(env, jkey); \
(*env)->DeleteLocalRef(env, r); \
} else ((void) 0)
#define GETPROP(props, key, jret) \
if (1) { \
jstring jkey = JNU_NewStringPlatform(env, key); \
jret = (*env)->CallObjectMethod(env, props, getPropID, jkey); \
if ((*env)->ExceptionOccurred(env)) return NULL; \
(*env)->DeleteLocalRef(env, jkey); \
} else ((void) 0)
#ifndef VENDOR /* Third party may overwrite this. */
#define VENDOR "Sun Microsystems Inc."
......@@ -90,6 +105,60 @@ Java_java_lang_System_identityHashCode(JNIEnv *env, jobject this, jobject x)
#define JAVA_MAX_SUPPORTED_VERSION 51
#define JAVA_MAX_SUPPORTED_MINOR_VERSION 0
static int fmtdefault; // boolean value
jobject fillI18nProps(JNIEnv *env, jobject props, char *baseKey,
char *platformDispVal, char *platformFmtVal,
jmethodID putID, jmethodID getPropID) {
jstring jVMBaseVal = NULL;
GETPROP(props, baseKey, jVMBaseVal);
if (jVMBaseVal) {
// user specified the base property. there's nothing to do here.
(*env)->DeleteLocalRef(env, jVMBaseVal);
} else {
char buf[64];
jstring jVMVal = NULL;
const char *baseVal = "";
/* user.xxx base property */
if (fmtdefault) {
if (platformFmtVal) {
PUTPROP(props, baseKey, platformFmtVal);
baseVal = platformFmtVal;
}
} else {
if (platformDispVal) {
PUTPROP(props, baseKey, platformDispVal);
baseVal = platformDispVal;
}
}
/* user.xxx.display property */
jio_snprintf(buf, sizeof(buf), "%s.display", baseKey);
GETPROP(props, buf, jVMVal);
if (jVMVal == NULL) {
if (platformDispVal && (strcmp(baseVal, platformDispVal) != 0)) {
PUTPROP(props, buf, platformDispVal);
}
} else {
(*env)->DeleteLocalRef(env, jVMVal);
}
/* user.xxx.format property */
jio_snprintf(buf, sizeof(buf), "%s.format", baseKey);
GETPROP(props, buf, jVMVal);
if (jVMVal == NULL) {
if (platformFmtVal && (strcmp(baseVal, platformFmtVal) != 0)) {
PUTPROP(props, buf, platformFmtVal);
}
} else {
(*env)->DeleteLocalRef(env, jVMVal);
}
}
return NULL;
}
JNIEXPORT jobject JNICALL
Java_java_lang_System_initProperties(JNIEnv *env, jclass cla, jobject props)
{
......@@ -99,6 +168,16 @@ Java_java_lang_System_initProperties(JNIEnv *env, jclass cla, jobject props)
(*env)->GetObjectClass(env, props),
"put",
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
jmethodID removeID = (*env)->GetMethodID(env,
(*env)->GetObjectClass(env, props),
"remove",
"(Ljava/lang/Object;)Ljava/lang/Object;");
jmethodID getPropID = (*env)->GetMethodID(env,
(*env)->GetObjectClass(env, props),
"getProperty",
"(Ljava/lang/String;)Ljava/lang/String;");
jobject ret = NULL;
jstring jVMVal = NULL;
if (sprops == NULL || putID == NULL ) return NULL;
......@@ -218,7 +297,46 @@ Java_java_lang_System_initProperties(JNIEnv *env, jclass cla, jobject props)
PUTPROP(props, "sun.desktop", sprops->desktop);
}
return JVM_InitProperties(env, props);
/*
* unset "user.language", "user.country", and "user.variant"
* in order to tell whether the command line option "-DXXXX=YYYY" is
* specified or not. They will be reset in fillI18nProps() below.
*/
REMOVEPROP(props, "user.language");
REMOVEPROP(props, "user.country");
REMOVEPROP(props, "user.variant");
REMOVEPROP(props, "file.encoding");
ret = JVM_InitProperties(env, props);
/* Check the compatibility flag */
GETPROP(props, "sun.locale.formatasdefault", jVMVal);
if (jVMVal) {
const char * val = (*env)->GetStringUTFChars(env, jVMVal, 0);
fmtdefault = !strcmp(val, "true");
(*env)->ReleaseStringUTFChars(env, jVMVal, val);
(*env)->DeleteLocalRef(env, jVMVal);
}
/* reconstruct i18n related properties */
fillI18nProps(env, props, "user.language", sprops->display_language,
sprops->format_language, putID, getPropID);
fillI18nProps(env, props, "user.country",
sprops->display_country, sprops->format_country, putID, getPropID);
fillI18nProps(env, props, "user.variant",
sprops->display_variant, sprops->format_variant, putID, getPropID);
GETPROP(props, "file.encoding", jVMVal);
if (jVMVal == NULL) {
if (fmtdefault) {
PUTPROP(props, "file.encoding", sprops->encoding);
} else {
PUTPROP(props, "file.encoding", sprops->sun_jnu_encoding);
}
} else {
(*env)->DeleteLocalRef(env, jVMVal);
}
return ret;
}
/*
......
......@@ -53,8 +53,14 @@ typedef struct {
nchar *user_home;
char *language;
char *format_language;
char *display_language;
char *country;
char *format_country;
char *display_country;
char *variant;
char *format_variant;
char *display_variant;
char *encoding;
char *sun_jnu_encoding;
char *timezone;
......
......@@ -115,6 +115,174 @@ setPathEnvironment(char *envstring)
#define P_tmpdir "/var/tmp"
#endif
static int ParseLocale(int cat, char ** std_language, char ** std_country, char ** std_variant, char ** std_encoding) {
char temp[64];
char *language = NULL, *country = NULL, *variant = NULL,
*encoding = NULL;
char *p, encoding_variant[64];
char *lc;
/* Query the locale set for the category */
lc = setlocale(cat, NULL);
#ifndef __linux__
if (lc == NULL) {
return 0;
}
if (cat == LC_CTYPE) {
/*
* Workaround for Solaris bug 4201684: Xlib doesn't like @euro
* locales. Since we don't depend on the libc @euro behavior,
* we just remove the qualifier.
* On Linux, the bug doesn't occur; on the other hand, @euro
* is needed there because it's a shortcut that also determines
* the encoding - without it, we wouldn't get ISO-8859-15.
* Therefore, this code section is Solaris-specific.
*/
lc = strdup(lc); /* keep a copy, setlocale trashes original. */
strcpy(temp, lc);
p = strstr(temp, "@euro");
if (p != NULL) {
*p = '\0';
setlocale(LC_ALL, temp);
}
}
#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>
* <country name>, <encoding name>, and <variant name> are optional.
*/
strcpy(temp, 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 language_country.encoding@variant, and must be
* preceded by their delimiter (except for language).
*
* If the locale name (without .encoding@variant, 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) {
p[encoding++ - p] = '\0';
p = encoding;
}
if ((variant = strchr(p, '@')) != NULL) {
p[variant++ - p] = '\0';
}
/* Normalize the language name */
if (std_language != NULL) {
*std_language = "en";
if (language != NULL) {
mapLookup(language_names, language, std_language);
}
}
/* Normalize the country name */
if (std_country != NULL && country != NULL) {
*std_country = country;
mapLookup(country_names, country, std_country);
}
/* Normalize the variant name. Note that we only use
* variants listed in the mapping array; others are ignored. */
if (std_variant != NULL && variant != NULL) {
mapLookup(variant_names, variant, std_variant);
}
/* Normalize the encoding name. Note that we IGNORE the string
* 'encoding' extracted from the locale name above. Instead, we use the
* more reliable method of calling nl_langinfo(CODESET). This function
* returns an empty string if no encoding is set for the given locale
* (e.g., the C or POSIX locales); we use the default ISO 8859-1
* converter for such locales.
*/
if (std_encoding != NULL) {
/* OK, not so reliable - nl_langinfo() gives wrong answers on
* Euro locales, in particular. */
if (strcmp(p, "ISO8859-15") == 0)
p = "ISO8859-15";
else
p = nl_langinfo(CODESET);
/* Convert the bare "646" used on Solaris to a proper IANA name */
if (strcmp(p, "646") == 0)
p = "ISO646-US";
/* return same result nl_langinfo would return for en_UK,
* in order to use optimizations. */
*std_encoding = (*p != '\0') ? p : "ISO8859-1";
#ifdef __linux__
/*
* Remap the encoding string to a different value for japanese
* locales on linux so that customized converters are used instead
* of the default converter for "EUC-JP". The customized converters
* omit support for the JIS0212 encoding which is not supported by
* the variant of "EUC-JP" encoding used on linux
*/
if (strcmp(p, "EUC-JP") == 0) {
*std_encoding = "EUC-JP-LINUX";
}
#else
if (strcmp(p,"eucJP") == 0) {
/* For Solaris use customized vendor defined character
* customized EUC-JP converter
*/
*std_encoding = "eucJP-open";
} else if (strcmp(p, "Big5") == 0 || strcmp(p, "BIG5") == 0) {
/*
* Remap the encoding string to Big5_Solaris which augments
* the default converter for Solaris Big5 locales to include
* seven additional ideographic characters beyond those included
* in the Java "Big5" converter.
*/
*std_encoding = "Big5_Solaris";
} else if (strcmp(p, "Big5-HKSCS") == 0) {
/*
* Solaris uses HKSCS2001
*/
*std_encoding = "Big5-HKSCS-2001";
}
#endif
}
return 1;
}
/* This function gets called very early, before VM_CALLS are setup.
* Do not use any of the VM_CALLS entries!!!
*/
......@@ -185,182 +353,25 @@ GetJavaProperties(JNIEnv *env)
/* Determine the language, country, variant, and encoding from the host,
* 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";
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>
* <country name>, <encoding name>, and <variant name> are optional.
*/
char temp[64];
char *language = NULL, *country = NULL, *variant = NULL,
*encoding = NULL;
char *std_language = NULL, *std_country = NULL, *std_variant = NULL,
*std_encoding = NULL;
char *p, encoding_variant[64];
int i, found;
#ifndef __linux__
/*
* Workaround for Solaris bug 4201684: Xlib doesn't like @euro
* locales. Since we don't depend on the libc @euro behavior,
* we just remove the qualifier.
* On Linux, the bug doesn't occur; on the other hand, @euro
* is needed there because it's a shortcut that also determines
* the encoding - without it, we wouldn't get ISO-8859-15.
* Therefore, this code section is Solaris-specific.
*/
lc = strdup(lc); /* keep a copy, setlocale trashes original. */
strcpy(temp, lc);
p = strstr(temp, "@euro");
if (p != NULL)
*p = '\0';
setlocale(LC_ALL, temp);
#endif
strcpy(temp, 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 language_country.encoding@variant, and must be
* preceded by their delimiter (except for language).
*
* If the locale name (without .encoding@variant, 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) {
p[encoding++ - p] = '\0';
p = encoding;
}
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. */
if (variant != NULL) {
mapLookup(variant_names, variant, &std_variant);
sprops.variant = std_variant;
}
/* Normalize the encoding name. Note that we IGNORE the string
* 'encoding' extracted from the locale name above. Instead, we use the
* more reliable method of calling nl_langinfo(CODESET). This function
* returns an empty string if no encoding is set for the given locale
* (e.g., the C or POSIX locales); we use the default ISO 8859-1
* converter for such locales.
*/
/* OK, not so reliable - nl_langinfo() gives wrong answers on
* Euro locales, in particular. */
if (strcmp(p, "ISO8859-15") == 0)
p = "ISO8859-15";
else
p = nl_langinfo(CODESET);
/* Convert the bare "646" used on Solaris to a proper IANA name */
if (strcmp(p, "646") == 0)
p = "ISO646-US";
/* return same result nl_langinfo would return for en_UK,
* in order to use optimizations. */
std_encoding = (*p != '\0') ? p : "ISO8859-1";
#ifdef __linux__
/*
* Remap the encoding string to a different value for japanese
* locales on linux so that customized converters are used instead
* of the default converter for "EUC-JP". The customized converters
* omit support for the JIS0212 encoding which is not supported by
* the variant of "EUC-JP" encoding used on linux
*/
if (strcmp(p, "EUC-JP") == 0) {
std_encoding = "EUC-JP-LINUX";
}
#else
if (strcmp(p,"eucJP") == 0) {
/* For Solaris use customized vendor defined character
* customized EUC-JP converter
*/
std_encoding = "eucJP-open";
} else if (strcmp(p, "Big5") == 0 || strcmp(p, "BIG5") == 0) {
/*
* Remap the encoding string to Big5_Solaris which augments
* the default converter for Solaris Big5 locales to include
* seven additional ideographic characters beyond those included
* in the Java "Big5" converter.
*/
std_encoding = "Big5_Solaris";
} else if (strcmp(p, "Big5-HKSCS") == 0) {
/*
* Solaris uses HKSCS2001
*/
std_encoding = "Big5-HKSCS-2001";
}
#endif
sprops.encoding = std_encoding;
sprops.sun_jnu_encoding = sprops.encoding;
}
setlocale(LC_ALL, "");
if (ParseLocale(LC_CTYPE,
&(sprops.format_language),
&(sprops.format_country),
&(sprops.format_variant),
&(sprops.encoding))) {
ParseLocale(LC_MESSAGES,
&(sprops.language),
&(sprops.country),
&(sprops.variant),
NULL);
} else {
sprops.language = "en";
sprops.encoding = "ISO8859-1";
}
sprops.display_language = sprops.language;
sprops.display_country = sprops.country;
sprops.display_variant = sprops.variant;
sprops.sun_jnu_encoding = sprops.encoding;
#ifdef __linux__
#if __BYTE_ORDER == __LITTLE_ENDIAN
......
......@@ -201,6 +201,7 @@ AwtDataTransferer::LCIDToTextEncoding(JNIEnv *env, LCID lcid) {
throw std::bad_alloc();
}
env->SetByteArrayRegion(retval, 0, length, (jbyte *)encoding);
free((void *)encoding);
return retval;
}
......
......@@ -296,7 +296,9 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_WInputMethod_getNativeLocale
// so we can reset this flag.
g_bUserHasChangedInputLang = FALSE;
return CreateLocaleObject(env, javaLocaleName);
jobject ret = CreateLocaleObject(env, javaLocaleName);
free((void *)javaLocaleName);
return ret;
} else {
return NULL;
}
......@@ -323,6 +325,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WInputMethod_setNativeLocale
const char * requested = env->GetStringUTFChars(localeString, &isCopy);
if ((current != NULL) && (strcmp(current, requested) == 0)) {
env->ReleaseStringUTFChars(localeString, requested);
free((void *)current);
return JNI_TRUE;
}
......@@ -352,6 +355,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WInputMethod_setNativeLocale
env->ReleaseStringUTFChars(localeString, requested);
free(hKLList);
free((void *)current);
return retValue;
CATCH_BAD_ALLOC_RET(JNI_FALSE);
......@@ -480,6 +484,7 @@ JNIEXPORT jobjectArray JNICALL Java_sun_awt_windows_WInputMethodDescriptor_getNa
env->SetObjectArrayElement(locales,
current,
CreateLocaleObject(env, javaLocaleNames[current]));
free((void *)javaLocaleNames[current]);
}
DASSERT(!safe_ExceptionOccurred(env));
......
......@@ -58,7 +58,7 @@ public class Constructors {
}
static void locale(Formatter f) {
locale(f, Locale.getDefault());
locale(f, Locale.getDefault(Locale.Category.FORMAT));
}
static void locale(Formatter f, Locale l) {
......
#!/bin/sh
#
# @test
# @bug 4700857
# @summary tests for Locale.getDefault(Locale.Category) and
# Locale.setDefault(Locale.Category, Locale)
# @build LocaleCategory
# @run shell/timeout=600 LocaleCategory.sh
if [ "${TESTSRC}" = "" ]
then
echo "TESTSRC not set. Test cannot execute. Failed."
exit 1
fi
echo "TESTSRC=${TESTSRC}"
if [ "${TESTJAVA}" = "" ]
then
echo "TESTJAVA not set. Test cannot execute. Failed."
exit 1
fi
echo "TESTJAVA=${TESTJAVA}"
if [ "${TESTCLASSES}" = "" ]
then
echo "TESTCLASSES not set. Test cannot execute. Failed."
exit 1
fi
echo "TESTCLASSES=${TESTCLASSES}"
echo "CLASSPATH=${CLASSPATH}"
# set platform-dependent variables
OS=`uname -s`
case "$OS" in
SunOS | Linux )
PS=":"
FS="/"
;;
Windows* )
PS=";"
FS="\\"
;;
* )
echo "Unrecognized system!"
exit 1;
;;
esac
# test user.xxx.display user.xxx.format properties
# run
RUNCMD="${TESTJAVA}${FS}bin${FS}java -classpath ${TESTCLASSES} -Duser.language.display=ja -Duser.language.format=zh LocaleCategory"
echo ${RUNCMD}
${RUNCMD}
result=$?
if [ $result -eq 0 ]
then
echo "Execution successful"
else
echo "Execution of the test case failed."
fi
# test user.xxx properties overriding user.xxx.display/format
# run
RUNCMD="${TESTJAVA}${FS}bin${FS}java -classpath ${TESTCLASSES} -Duser.language=en -Duser.language.display=ja -Duser.language.format=zh LocaleCategory"
echo ${RUNCMD}
${RUNCMD}
result=$?
if [ $result -eq 0 ]
then
echo "Execution successful"
else
echo "Execution of the test case failed."
fi
exit $result
......@@ -231,8 +231,15 @@ import java.util.Locale;
public class PrintDefaultLocale {
public static void main(String[] args) {
System.out.println(Locale.getDefault().toString());
System.out.println(Locale.getDefault().getDisplayName(Locale.US));
System.out.println(Charset.defaultCharset());
System.out.printf("default locale: ID: %s, Name: %s\n",
Locale.getDefault().toString(),
Locale.getDefault().getDisplayName(Locale.US));
System.out.printf("display locale: ID: %s, Name: %s\n",
Locale.getDefault(Locale.Category.DISPLAY).toString(),
Locale.getDefault(Locale.Category.DISPLAY).getDisplayName(Locale.US));
System.out.printf("format locale: ID: %s, Name: %s\n",
Locale.getDefault(Locale.Category.FORMAT).toString(),
Locale.getDefault(Locale.Category.FORMAT).getDisplayName(Locale.US));
System.out.printf("default charset: %s\n", Charset.defaultCharset());
}
}
......@@ -29,100 +29,233 @@
* WARNING: This tool directly modifies the locale info in the Windows registry.
* It may not work with the Windows versions after Windows XP SP2. Also,
* if the test did not complete or was manually killed, you will need to reset
* the user default locale in the Control Panel manually.
* the user default locale in the Control Panel manually. This executable has
* to be run with the "Administrator" privilege.
*
* Usage: "deflocale.exe <java launcher> PrintDefaultLocale
*
* How to compile: "cl deflocale.c advapi32.lib"
* How to compile: "cl -DUNICODE -D_UNICODE deflocale.c user32.lib advapi32.lib"
*/
#include <windows.h>
#include <stdio.h>
#include <memory.h>
char* launcher;
char szBuffer[MAX_PATH];
wchar_t* launcher;
wchar_t szBuffer[MAX_PATH];
LCID LCIDArray[1024];
int numLCIDs = 0;
BOOL isWin7orUp = FALSE;
void testLCID(int anLCID) {
// for Windows 7
BOOL (WINAPI * pfnEnumSystemLocalesEx)(LPVOID, DWORD, LPARAM, LPVOID);
BOOL (WINAPI * pfnEnumUILanguages)(LPVOID, DWORD, LPARAM);
LCID (WINAPI * pfnLocaleNameToLCID)(LPCWSTR, DWORD);
int (WINAPI * pfnLCIDToLocaleName)(LCID, LPWSTR, int, DWORD);
wchar_t* LocaleNamesArray[1024];
wchar_t* UILangNamesArray[1024];
int numLocaleNames = 0;
int numUILangNames = 0;
void launchAndWait() {
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
if (CreateProcess(NULL, launcher, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)==0) {
wprintf(L"CreateProcess failed with the error code: %x\n", GetLastError());
}
WaitForSingleObject( pi.hProcess, INFINITE );
}
void testLocale(int anLCID, wchar_t* pName) {
HKEY hk;
printf("\n");
printf("OS Locale (lcid: %x): ", anLCID);
if (pName != NULL && wcslen(pName) == 2) {
// ignore language only locale.
return;
}
wprintf(L"\n");
wprintf(L"OS Locale (lcid: %x", anLCID);
if (pName != NULL) {
wprintf(L", name: %s", pName);
}
GetLocaleInfo(anLCID, LOCALE_SENGLANGUAGE, szBuffer, MAX_PATH);
printf("%s (", szBuffer);
wprintf(L"): %s (", szBuffer);
GetLocaleInfo(anLCID, LOCALE_SENGCOUNTRY, szBuffer, MAX_PATH);
printf("%s) - ", szBuffer);
wprintf(L"%s) - ", szBuffer);
GetLocaleInfo(anLCID, LOCALE_IDEFAULTANSICODEPAGE, szBuffer, MAX_PATH);
printf("%s\n", szBuffer);
wprintf(L"%s\n", szBuffer);
fflush(0);
if (RegOpenKeyEx(HKEY_CURRENT_USER, "Control Panel\\International", 0, KEY_READ | KEY_WRITE, &hk) == ERROR_SUCCESS) {
BYTE original[16];
BYTE test[16];
DWORD cb = 16;
STARTUPINFO si;
PROCESS_INFORMATION pi;
RegQueryValueEx(hk, "Locale", 0, 0, original, &cb);
sprintf(test, "%08x", anLCID);
RegSetValueEx(hk, "Locale", 0, REG_SZ, test, cb);
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
if (CreateProcess(NULL, launcher, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)==0) {
printf("CreateProcess failed with the error code: %x\n", GetLastError());
if (RegOpenKeyEx(HKEY_CURRENT_USER, L"Control Panel\\International", 0, KEY_READ | KEY_WRITE, &hk) == ERROR_SUCCESS) {
wchar_t originalLocale[16];
wchar_t testLocale[16];
wchar_t* pKeyName;
DWORD cb = sizeof(originalLocale);
DWORD cbTest;
if (isWin7orUp) {
pKeyName = L"LocaleName";
wcscpy(testLocale, pName);
cbTest = wcslen(pName) * sizeof(wchar_t);
} else {
pKeyName = L"Locale";
swprintf(testLocale, L"%08x", anLCID);
cbTest = sizeof(wchar_t) * 8;
}
WaitForSingleObject( pi.hProcess, INFINITE );
RegQueryValueEx(hk, pKeyName, 0, 0, (LPBYTE)originalLocale, &cb);
RegSetValueEx(hk, pKeyName, 0, REG_SZ, (LPBYTE)testLocale, cbTest );
launchAndWait();
RegSetValueEx(hk, pKeyName, 0, REG_SZ, (LPBYTE)originalLocale, cb);
RegCloseKey(hk);
}
}
void testUILang(wchar_t* pName) {
HKEY hk;
wprintf(L"\n");
wprintf(L"OS UI Language (name: %s)\n", pName);
fflush(0);
if (RegOpenKeyEx(HKEY_CURRENT_USER, L"Control Panel\\Desktop", 0, KEY_READ | KEY_WRITE, &hk) == ERROR_SUCCESS) {
wchar_t originalUILang[16];
wchar_t testUILang[16];
wchar_t* pKeyName;
DWORD cb = sizeof(originalUILang);
DWORD cbTest = wcslen(pName) * sizeof(wchar_t);
RegSetValueEx(hk, "Locale", 0, REG_SZ, original, cb);
pKeyName = L"PreferredUILanguages";
wcscpy(testUILang, pName);
cbTest = wcslen(pName) * sizeof(wchar_t);
RegQueryValueEx(hk, pKeyName, 0, 0, (LPBYTE)originalUILang, &cb);
RegSetValueEx(hk, pKeyName, 0, REG_SZ, (LPBYTE)testUILang, cbTest);
launchAndWait();
RegSetValueEx(hk, pKeyName, 0, REG_SZ, (LPBYTE)originalUILang, cb);
RegCloseKey(hk);
}
}
BOOL CALLBACK EnumLocaleProc(LPTSTR lpLocaleStr) {
sscanf(lpLocaleStr, "%08x", &LCIDArray[numLCIDs]);
BOOL CALLBACK EnumLocalesProc(LPWSTR lpLocaleStr) {
swscanf(lpLocaleStr, L"%08x", &LCIDArray[numLCIDs]);
numLCIDs ++;
return TRUE;
}
BOOL CALLBACK EnumLocalesProcEx(LPWSTR lpLocaleStr, DWORD flags, LPARAM lp) {
wchar_t* pName = malloc((wcslen(lpLocaleStr) + 1) * sizeof(wchar_t *));
wcscpy(pName, lpLocaleStr);
LocaleNamesArray[numLocaleNames] = pName;
numLocaleNames ++;
return TRUE;
}
BOOL CALLBACK EnumUILanguagesProc(LPWSTR lpUILangStr, LPARAM lp) {
wchar_t* pName = malloc((wcslen(lpUILangStr) + 1) * sizeof(wchar_t *));
wcscpy(pName, lpUILangStr);
UILangNamesArray[numUILangNames] = pName;
numUILangNames ++;
return TRUE;
}
int sortLCIDs(LCID * pLCID1, LCID * pLCID2) {
if (*pLCID1 < *pLCID2) return (-1);
if (*pLCID1 == *pLCID2) return 0;
if (*pLCID1 > *pLCID2) return 1;
return 1;
}
int sortLocaleNames(wchar_t** ppName1, wchar_t** ppName2) {
LCID l1 = pfnLocaleNameToLCID(*ppName1, 0);
LCID l2 = pfnLocaleNameToLCID(*ppName2, 0);
return sortLCIDs(&l1, &l2);
}
int main(int argc, char** argv) {
OSVERSIONINFO osvi;
LPTSTR commandline = GetCommandLine();
LPWSTR commandline = GetCommandLine();
int i;
osvi.dwOSVersionInfoSize = sizeof(osvi);
GetVersionEx(&osvi);
printf("# OSVersionInfo\n");
printf("# MajorVersion: %d\n", osvi.dwMajorVersion);
printf("# MinorVersion: %d\n", osvi.dwMinorVersion);
printf("# BuildNumber: %d\n", osvi.dwBuildNumber);
printf("# CSDVersion: %s\n", osvi.szCSDVersion);
printf("\n");
wprintf(L"# OSVersionInfo\n");
wprintf(L"# MajorVersion: %d\n", osvi.dwMajorVersion);
wprintf(L"# MinorVersion: %d\n", osvi.dwMinorVersion);
wprintf(L"# BuildNumber: %d\n", osvi.dwBuildNumber);
wprintf(L"# CSDVersion: %s\n", osvi.szCSDVersion);
wprintf(L"\n");
fflush(0);
launcher = strchr(commandline, ' ')+1;
while (*launcher == ' ') {
launcher = wcschr(commandline, L' ')+1;
while (*launcher == L' ') {
launcher++;
}
// Enumerate locales
EnumSystemLocales(EnumLocaleProc, LCID_INSTALLED);
isWin7orUp = (osvi.dwMajorVersion > 6) ||
(osvi.dwMajorVersion == 6 && osvi.dwMinorVersion >= 1);
// Sort LCIDs
qsort(LCIDArray, numLCIDs, sizeof(LCID), (void *)sortLCIDs);
if (!isWin7orUp) {
// Enumerate locales
EnumSystemLocales(EnumLocalesProc, LCID_INSTALLED);
// Sort LCIDs
qsort(LCIDArray, numLCIDs, sizeof(LCID), (void *)sortLCIDs);
} else {
// For Windows 7, use "LocaleName" registry key for the user locale
// as they seem to switch from "Locale".
HMODULE hmod = GetModuleHandle(L"kernel32");
*(FARPROC*)&pfnEnumSystemLocalesEx =
GetProcAddress(hmod, "EnumSystemLocalesEx");
*(FARPROC*)&pfnEnumUILanguages =
GetProcAddress(hmod, "EnumUILanguagesW");
*(FARPROC*)&pfnLocaleNameToLCID =
GetProcAddress(hmod, "LocaleNameToLCID");
*(FARPROC*)&pfnLCIDToLocaleName =
GetProcAddress(hmod, "LCIDToLocaleName");
if (pfnEnumSystemLocalesEx != NULL &&
pfnEnumUILanguages != NULL &&
pfnLocaleNameToLCID != NULL &&
pfnLCIDToLocaleName != NULL) {
// Enumerate locales
pfnEnumSystemLocalesEx(EnumLocalesProcEx,
1, // LOCALE_WINDOWS
(LPARAM)NULL, NULL);
// Enumerate UI Languages.
pfnEnumUILanguages(EnumUILanguagesProc,
0x8, // MUI_LANGUAGE_NAME
(LPARAM)NULL);
} else {
wprintf(L"Could not get needed entry points. quitting.\n");
exit(-1);
}
// Sort LocaleNames
qsort(LocaleNamesArray, numLocaleNames,
sizeof(wchar_t*), (void *)sortLocaleNames);
qsort(UILangNamesArray, numUILangNames,
sizeof(wchar_t*), (void *)sortLocaleNames);
}
// Execute enumeration of Java default locales
for (i = 0; i < numLCIDs; i ++) {
testLCID(LCIDArray[i]);
if (isWin7orUp) {
for (i = 0; i < numLocaleNames; i ++) {
testLocale(pfnLocaleNameToLCID(LocaleNamesArray[i], 0),
LocaleNamesArray[i]);
}
for (i = 0; i < numUILangNames; i ++) {
testUILang(UILangNamesArray[i]);
}
} else {
for (i = 0; i < numLCIDs; i ++) {
testLocale(LCIDArray[i], NULL);
}
}
}
# data file for deflocale.sh. Each line must have two locales in the following order.
#
# LC_CTYPE LC_MESSAGES
ja_JP.UTF-8 zh_CN.UTF-8
zh_CN.UTF-8 en_US.UTF-8
C zh_CN.UTF-8
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -31,8 +31,21 @@
#
cat /etc/*release
uname -a
env LC_COLLATE=C ls /usr/lib/locale | while read line; do
echo "Testing all available locales"
/usr/bin/locale -a | while read line; do
echo ""
echo "OS Locale: " $line
env LANG=$line LC_ALL=$line $1 PrintDefaultLocale
env LC_ALL= LC_CTYPE= LC_MESSAGES= LANG=$line $1 $2 $3 $4 $5 $6 $7 $8 $9 PrintDefaultLocale
done
echo ""
echo "Testing some typical combinations"
echo ""
while read lcctype lcmessages; do
if [ "$lcctype" = "#" -o "$lcctype" = "" ]; then
continue
fi
echo ""
echo "OS Locale (LC_CTYPE: "$lcctype", LC_MESSAGES: "$lcmessages")"
env LC_ALL= LC_CTYPE=$lcctype LC_MESSAGES=$lcmessages $1 $2 $3 $4 $5 $6 $7 $8 $9 PrintDefaultLocale
done < deflocale.input
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
# OSVersionInfo
# MajorVersion: 5
# MinorVersion: 1
# BuildNumber: 2600
# CSDVersion: Service Pack 2
OS Locale (lcid: 401): Arabic (Saudi Arabia) - 1256
ar_SA
Arabic (Saudi Arabia)
windows-1256
OS Locale (lcid: 402): Bulgarian (Bulgaria) - 1251
bg_BG
Bulgarian (Bulgaria)
windows-1251
OS Locale (lcid: 403): Catalan (Spain) - 1252
ca_ES
Catalan (Spain)
windows-1252
OS Locale (lcid: 404): Chinese (Taiwan) - 950
zh_TW
Chinese (Taiwan)
x-windows-950
OS Locale (lcid: 405): Czech (Czech Republic) - 1250
cs_CZ
Czech (Czech Republic)
windows-1250
OS Locale (lcid: 406): Danish (Denmark) - 1252
da_DK
Danish (Denmark)
windows-1252
OS Locale (lcid: 407): German (Germany) - 1252
de_DE
German (Germany)
windows-1252
OS Locale (lcid: 408): Greek (Greece) - 1253
el_GR
Greek (Greece)
windows-1253
OS Locale (lcid: 409): English (United States) - 1252
en_US
English (United States)
windows-1252
OS Locale (lcid: 40a): Spanish (Spain) - 1252
es_ES
Spanish (Spain)
windows-1252
OS Locale (lcid: 40b): Finnish (Finland) - 1252
fi_FI
Finnish (Finland)
windows-1252
OS Locale (lcid: 40c): French (France) - 1252
fr_FR
French (France)
windows-1252
OS Locale (lcid: 40d): Hebrew (Israel) - 1255
iw_IL
Hebrew (Israel)
windows-1255
OS Locale (lcid: 40e): Hungarian (Hungary) - 1250
hu_HU
Hungarian (Hungary)
windows-1250
OS Locale (lcid: 40f): Icelandic (Iceland) - 1252
is_IS
Icelandic (Iceland)
windows-1252
OS Locale (lcid: 410): Italian (Italy) - 1252
it_IT
Italian (Italy)
windows-1252
OS Locale (lcid: 411): Japanese (Japan) - 932
ja_JP
Japanese (Japan)
windows-31j
OS Locale (lcid: 412): Korean (Korea) - 949
ko_KR
Korean (South Korea)
x-windows-949
OS Locale (lcid: 413): Dutch (Netherlands) - 1252
nl_NL
Dutch (Netherlands)
windows-1252
OS Locale (lcid: 414): Norwegian (Bokml) (Norway) - 1252
no_NO
Norwegian (Norway)
windows-1252
OS Locale (lcid: 415): Polish (Poland) - 1250
pl_PL
Polish (Poland)
windows-1250
OS Locale (lcid: 416): Portuguese (Brazil) - 1252
pt_BR
Portuguese (Brazil)
windows-1252
OS Locale (lcid: 417): Romansh (Switzerland) - 1252
rm_CH
Raeto-Romance (Switzerland)
windows-1252
OS Locale (lcid: 418): Romanian (Romania) - 1250
ro_RO
Romanian (Romania)
windows-1250
OS Locale (lcid: 419): Russian (Russia) - 1251
ru_RU
Russian (Russia)
windows-1251
OS Locale (lcid: 41a): Croatian (Croatia) - 1250
hr_HR
Croatian (Croatia)
windows-1250
OS Locale (lcid: 41b): Slovak (Slovakia) - 1250
sk_SK
Slovak (Slovakia)
windows-1250
OS Locale (lcid: 41c): Albanian (Albania) - 1250
sq_AL
Albanian (Albania)
windows-1250
OS Locale (lcid: 41d): Swedish (Sweden) - 1252
sv_SE
Swedish (Sweden)
windows-1252
OS Locale (lcid: 41e): Thai (Thailand) - 874
th_TH
Thai (Thailand)
x-windows-874
OS Locale (lcid: 41f): Turkish (Turkey) - 1254
tr_TR
Turkish (Turkey)
windows-1254
OS Locale (lcid: 420): Urdu (Islamic Republic of Pakistan) - 1256
ur_PK
Urdu (Pakistan)
windows-1256
OS Locale (lcid: 421): Indonesian (Indonesia) - 1252
in_ID
Indonesian (Indonesia)
windows-1252
OS Locale (lcid: 422): Ukrainian (Ukraine) - 1251
uk_UA
Ukrainian (Ukraine)
windows-1251
OS Locale (lcid: 423): Belarusian (Belarus) - 1251
be_BY
Belarusian (Belarus)
windows-1251
OS Locale (lcid: 424): Slovenian (Slovenia) - 1250
sl_SI
Slovenian (Slovenia)
windows-1250
OS Locale (lcid: 425): Estonian (Estonia) - 1257
et_EE
Estonian (Estonia)
windows-1257
OS Locale (lcid: 426): Latvian (Latvia) - 1257
lv_LV
Latvian (Latvia)
windows-1257
OS Locale (lcid: 427): Lithuanian (Lithuania) - 1257
lt_LT
Lithuanian (Lithuania)
windows-1257
OS Locale (lcid: 429): Farsi (Iran) - 1256
fa_IR
Persian (Iran)
windows-1256
OS Locale (lcid: 42a): Vietnamese (Viet Nam) - 1258
vi_VN
Vietnamese (Vietnam)
windows-1258
OS Locale (lcid: 42b): Armenian (Armenia) - 0
hy_AM
Armenian (Armenia)
UTF-8
OS Locale (lcid: 42c): Azeri (Latin) (Azerbaijan) - 1254
az_AZ
Azerbaijani (Azerbaijan)
windows-1254
OS Locale (lcid: 42d): Basque (Spain) - 1252
eu_ES
Basque (Spain)
windows-1252
OS Locale (lcid: 42f): FYRO Macedonian (Former Yugoslav Republic of Macedonia) - 1251
mk_MK
Macedonian (Macedonia)
windows-1251
OS Locale (lcid: 432): Tswana (South Africa) - 1252
tn_ZA
Tswana (South Africa)
windows-1252
OS Locale (lcid: 434): Xhosa (South Africa) - 1252
xh_ZA
Xhosa (South Africa)
windows-1252
OS Locale (lcid: 435): Zulu (South Africa) - 1252
zu_ZA
Zulu (South Africa)
windows-1252
OS Locale (lcid: 436): Afrikaans (South Africa) - 1252
af_ZA
Afrikaans (South Africa)
windows-1252
OS Locale (lcid: 437): Georgian (Georgia) - 0
ka_GE
Georgian (Georgia)
UTF-8
OS Locale (lcid: 438): Faroese (Faroe Islands) - 1252
fo_FO
Faroese (Faroe Islands)
windows-1252
OS Locale (lcid: 439): Hindi (India) - 0
hi_IN
Hindi (India)
UTF-8
OS Locale (lcid: 43a): Maltese (Malta) - 0
mt_MT
Maltese (Malta)
UTF-8
OS Locale (lcid: 43b): Sami (Northern) (Norway) - 1252
se_NO
Northern Sami (Norway)
windows-1252
OS Locale (lcid: 43e): Malay (Malaysia) - 1252
ms_MY
Malay (Malaysia)
windows-1252
OS Locale (lcid: 43f): Kazakh (Kazakhstan) - 1251
kk_KZ
Kazakh (Kazakhstan)
windows-1251
OS Locale (lcid: 440): Kyrgyz (Kyrgyzstan) - 1251
ky_KG
Kirghiz (Kyrgyzstan)
windows-1251
OS Locale (lcid: 441): Swahili (Kenya) - 1252
sw_KE
Swahili (Kenya)
windows-1252
OS Locale (lcid: 443): Uzbek (Latin) (Uzbekistan) - 1254
uz_UZ
Uzbek (Uzbekistan)
windows-1254
OS Locale (lcid: 444): Tatar (Russia) - 1251
tt_RU
Tatar (Russia)
windows-1251
OS Locale (lcid: 445): Bengali (India) - 0
bn_IN
Bengali (India)
UTF-8
OS Locale (lcid: 446): Punjabi (India) - 0
pa_IN
Panjabi (India)
UTF-8
OS Locale (lcid: 447): Gujarati (India) - 0
gu_IN
Gujarati (India)
UTF-8
OS Locale (lcid: 449): Tamil (India) - 0
ta_IN
Tamil (India)
UTF-8
OS Locale (lcid: 44a): Telugu (India) - 0
te_IN
Telugu (India)
UTF-8
OS Locale (lcid: 44b): Kannada (India) - 0
kn_IN
Kannada (India)
UTF-8
OS Locale (lcid: 44c): Malayalam (India) - 0
ml_IN
Malayalam (India)
UTF-8
OS Locale (lcid: 44e): Marathi (India) - 0
mr_IN
Marathi (India)
UTF-8
OS Locale (lcid: 44f): Sanskrit (India) - 0
sa_IN
Sanskrit (India)
UTF-8
OS Locale (lcid: 450): Mongolian (Mongolia) - 1251
mn_MN
Mongolian (Mongolia)
windows-1251
OS Locale (lcid: 452): Welsh (United Kingdom) - 1252
cy_GB
Welsh (United Kingdom)
windows-1252
OS Locale (lcid: 456): Galician (Spain) - 1252
gl_ES
Gallegan (Spain)
windows-1252
OS Locale (lcid: 457): Konkani (India) - 0
en_US
English (United States)
windows-1252
OS Locale (lcid: 45a): Syriac (Syria) - 0
en_US
English (United States)
windows-1252
OS Locale (lcid: 461): Nepali (Nepal) - 0
ne_NP
Nepali (Nepal)
UTF-8
OS Locale (lcid: 462): Frisian (Netherlands) - 1252
fy_NL
Frisian (Netherlands)
windows-1252
OS Locale (lcid: 463): Pashto (Afghanistan) - 1256
ps_AF
Pushto (Afghanistan)
windows-1256
OS Locale (lcid: 464): Filipino (Philippines) - 1252
en_US
English (United States)
windows-1252
OS Locale (lcid: 465): Divehi (Maldives) - 0
dv_MV
Divehi (Maldives)
UTF-8
OS Locale (lcid: 46b): Quechua (Bolivia) - 1252
qu_BO
Quechua (Bolivia)
windows-1252
OS Locale (lcid: 46c): Northern Sotho (South Africa) - 1252
en_US
English (United States)
windows-1252
OS Locale (lcid: 46e): Luxembourgish (Luxembourg) - 1252
lb_LU
Luxembourgish (Luxembourg)
windows-1252
OS Locale (lcid: 47a): Mapudungun (Chile) - 1252
en_US
English (United States)
windows-1252
OS Locale (lcid: 47c): Mohawk (Canada) - 1252
en_US
English (United States)
windows-1252
OS Locale (lcid: 481): Maori (New Zealand) - 0
mi_NZ
Maori (New Zealand)
UTF-8
OS Locale (lcid: 801): Arabic (Iraq) - 1256
ar_IQ
Arabic (Iraq)
windows-1256
OS Locale (lcid: 804): Chinese (People's Republic of China) - 936
zh_CN
Chinese (China)
GBK
OS Locale (lcid: 807): German (Switzerland) - 1252
de_CH
German (Switzerland)
windows-1252
OS Locale (lcid: 809): English (United Kingdom) - 1252
en_GB
English (United Kingdom)
windows-1252
OS Locale (lcid: 80a): Spanish (Mexico) - 1252
es_MX
Spanish (Mexico)
windows-1252
OS Locale (lcid: 80c): French (Belgium) - 1252
fr_BE
French (Belgium)
windows-1252
OS Locale (lcid: 810): Italian (Switzerland) - 1252
it_CH
Italian (Switzerland)
windows-1252
OS Locale (lcid: 813): Dutch (Belgium) - 1252
nl_BE
Dutch (Belgium)
windows-1252
OS Locale (lcid: 814): Norwegian (Nynorsk) (Norway) - 1252
no_NO_NY
Norwegian (Norway,Nynorsk)
windows-1252
OS Locale (lcid: 816): Portuguese (Portugal) - 1252
pt_PT
Portuguese (Portugal)
windows-1252
OS Locale (lcid: 81a): Serbian (Latin) (Serbia and Montenegro) - 1250
sr_CS
Serbian (Serbia and Montenegro)
windows-1250
OS Locale (lcid: 81d): Swedish (Finland) - 1252
sv_FI
Swedish (Finland)
windows-1252
OS Locale (lcid: 82c): Azeri (Cyrillic) (Azerbaijan) - 1251
az_AZ
Azerbaijani (Azerbaijan)
windows-1251
OS Locale (lcid: 83b): Sami (Northern) (Sweden) - 1252
se_SE
Northern Sami (Sweden)
windows-1252
OS Locale (lcid: 83c): Irish (Ireland) - 1252
ga_IE
Irish (Ireland)
windows-1252
OS Locale (lcid: 83e): Malay (Brunei Darussalam) - 1252
ms_BN
Malay (Brunei)
windows-1252
OS Locale (lcid: 843): Uzbek (Cyrillic) (Uzbekistan) - 1251
uz_UZ
Uzbek (Uzbekistan)
windows-1251
OS Locale (lcid: 85d): Inuktitut (Latin) (Canada) - 1252
iu_CA
Inuktitut (Canada)
windows-1252
OS Locale (lcid: 86b): Quechua (Ecuador) - 1252
qu_EC
Quechua (Ecuador)
windows-1252
OS Locale (lcid: c01): Arabic (Egypt) - 1256
ar_EG
Arabic (Egypt)
windows-1256
OS Locale (lcid: c04): Chinese (Hong Kong S.A.R.) - 950
zh_HK
Chinese (Hong Kong)
x-windows-950
OS Locale (lcid: c07): German (Austria) - 1252
de_AT
German (Austria)
windows-1252
OS Locale (lcid: c09): English (Australia) - 1252
en_AU
English (Australia)
windows-1252
OS Locale (lcid: c0a): Spanish (Spain) - 1252
es_ES
Spanish (Spain)
windows-1252
OS Locale (lcid: c0c): French (Canada) - 1252
fr_CA
French (Canada)
windows-1252
OS Locale (lcid: c1a): Serbian (Cyrillic) (Serbia and Montenegro) - 1251
sr_CS
Serbian (Serbia and Montenegro)
windows-1251
OS Locale (lcid: c3b): Sami (Northern) (Finland) - 1252
se_FI
Northern Sami (Finland)
windows-1252
OS Locale (lcid: c6b): Quechua (Peru) - 1252
qu_PE
Quechua (Peru)
windows-1252
OS Locale (lcid: 1001): Arabic (Libya) - 1256
ar_LY
Arabic (Libya)
windows-1256
OS Locale (lcid: 1004): Chinese (Singapore) - 936
zh_SG
Chinese (Singapore)
GBK
OS Locale (lcid: 1007): German (Luxembourg) - 1252
de_LU
German (Luxembourg)
windows-1252
OS Locale (lcid: 1009): English (Canada) - 1252
en_CA
English (Canada)
windows-1252
OS Locale (lcid: 100a): Spanish (Guatemala) - 1252
es_GT
Spanish (Guatemala)
windows-1252
OS Locale (lcid: 100c): French (Switzerland) - 1252
fr_CH
French (Switzerland)
windows-1252
OS Locale (lcid: 101a): Croatian (Bosnia and Herzegovina) - 1250
hr_BA
Croatian (Bosnia and Herzegovina)
windows-1250
OS Locale (lcid: 103b): Sami (Lule) (Norway) - 1252
se
Northern Sami
windows-1252
OS Locale (lcid: 1401): Arabic (Algeria) - 1256
ar_DZ
Arabic (Algeria)
windows-1256
OS Locale (lcid: 1404): Chinese (Macau S.A.R.) - 950
zh_MO
Chinese (Macao)
x-windows-950
OS Locale (lcid: 1407): German (Liechtenstein) - 1252
de_LI
German (Liechtenstein)
windows-1252
OS Locale (lcid: 1409): English (New Zealand) - 1252
en_NZ
English (New Zealand)
windows-1252
OS Locale (lcid: 140a): Spanish (Costa Rica) - 1252
es_CR
Spanish (Costa Rica)
windows-1252
OS Locale (lcid: 140c): French (Luxembourg) - 1252
fr_LU
French (Luxembourg)
windows-1252
OS Locale (lcid: 141a): Bosnian (Bosnia and Herzegovina) - 1250
bs_BA
Bosnian (Bosnia and Herzegovina)
windows-1250
OS Locale (lcid: 143b): Sami (Lule) (Sweden) - 1252
se
Northern Sami
windows-1252
OS Locale (lcid: 1801): Arabic (Morocco) - 1256
ar_MA
Arabic (Morocco)
windows-1256
OS Locale (lcid: 1809): English (Ireland) - 1252
en_IE
English (Ireland)
windows-1252
OS Locale (lcid: 180a): Spanish (Panama) - 1252
es_PA
Spanish (Panama)
windows-1252
OS Locale (lcid: 180c): French (Principality of Monaco) - 1252
fr_MC
French (Monaco)
windows-1252
OS Locale (lcid: 181a): Serbian (Latin) (Bosnia and Herzegovina) - 1250
sr_BA
Serbian (Bosnia and Herzegovina)
windows-1250
OS Locale (lcid: 183b): Sami (Southern) (Norway) - 1252
se
Northern Sami
windows-1252
OS Locale (lcid: 1c01): Arabic (Tunisia) - 1256
ar_TN
Arabic (Tunisia)
windows-1256
OS Locale (lcid: 1c09): English (South Africa) - 1252
en_ZA
English (South Africa)
windows-1252
OS Locale (lcid: 1c0a): Spanish (Dominican Republic) - 1252
es_DO
Spanish (Dominican Republic)
windows-1252
OS Locale (lcid: 1c1a): Serbian (Cyrillic) (Bosnia and Herzegovina) - 1251
sr_BA
Serbian (Bosnia and Herzegovina)
windows-1251
OS Locale (lcid: 1c3b): Sami (Southern) (Sweden) - 1252
se
Northern Sami
windows-1252
OS Locale (lcid: 2001): Arabic (Oman) - 1256
ar_OM
Arabic (Oman)
windows-1256
OS Locale (lcid: 2009): English (Jamaica) - 1252
en_JM
English (Jamaica)
windows-1252
OS Locale (lcid: 200a): Spanish (Venezuela) - 1252
es_VE
Spanish (Venezuela)
windows-1252
OS Locale (lcid: 201a): Bosnian (Cyrillic) (Bosnia and Herzegovina) - 1250
bs_BA
Bosnian (Bosnia and Herzegovina)
windows-1250
OS Locale (lcid: 203b): Sami (Skolt) (Finland) - 1252
se
Northern Sami
windows-1252
OS Locale (lcid: 2401): Arabic (Yemen) - 1256
ar_YE
Arabic (Yemen)
windows-1256
OS Locale (lcid: 2409): English (Caribbean) - 1252
en
English
windows-1252
OS Locale (lcid: 240a): Spanish (Colombia) - 1252
es_CO
Spanish (Colombia)
windows-1252
OS Locale (lcid: 243b): Sami (Inari) (Finland) - 1252
se
Northern Sami
windows-1252
OS Locale (lcid: 2801): Arabic (Syria) - 1256
ar_SY
Arabic (Syria)
windows-1256
OS Locale (lcid: 2809): English (Belize) - 1252
en_BZ
English (Belize)
windows-1252
OS Locale (lcid: 280a): Spanish (Peru) - 1252
es_PE
Spanish (Peru)
windows-1252
OS Locale (lcid: 2c01): Arabic (Jordan) - 1256
ar_JO
Arabic (Jordan)
windows-1256
OS Locale (lcid: 2c09): English (Trinidad and Tobago) - 1252
en_TT
English (Trinidad and Tobago)
windows-1252
OS Locale (lcid: 2c0a): Spanish (Argentina) - 1252
es_AR
Spanish (Argentina)
windows-1252
OS Locale (lcid: 3001): Arabic (Lebanon) - 1256
ar_LB
Arabic (Lebanon)
windows-1256
OS Locale (lcid: 3009): English (Zimbabwe) - 1252
en_ZW
English (Zimbabwe)
windows-1252
OS Locale (lcid: 300a): Spanish (Ecuador) - 1252
es_EC
Spanish (Ecuador)
windows-1252
OS Locale (lcid: 3401): Arabic (Kuwait) - 1256
ar_KW
Arabic (Kuwait)
windows-1256
OS Locale (lcid: 3409): English (Republic of the Philippines) - 1252
en_PH
English (Philippines)
windows-1252
OS Locale (lcid: 340a): Spanish (Chile) - 1252
es_CL
Spanish (Chile)
windows-1252
OS Locale (lcid: 3801): Arabic (U.A.E.) - 1256
ar_AE
Arabic (United Arab Emirates)
windows-1256
OS Locale (lcid: 380a): Spanish (Uruguay) - 1252
es_UY
Spanish (Uruguay)
windows-1252
OS Locale (lcid: 3c01): Arabic (Bahrain) - 1256
ar_BH
Arabic (Bahrain)
windows-1256
OS Locale (lcid: 3c0a): Spanish (Paraguay) - 1252
es_PY
Spanish (Paraguay)
windows-1252
OS Locale (lcid: 4001): Arabic (Qatar) - 1256
ar_QA
Arabic (Qatar)
windows-1256
OS Locale (lcid: 400a): Spanish (Bolivia) - 1252
es_BO
Spanish (Bolivia)
windows-1252
OS Locale (lcid: 440a): Spanish (El Salvador) - 1252
es_SV
Spanish (El Salvador)
windows-1252
OS Locale (lcid: 480a): Spanish (Honduras) - 1252
es_HN
Spanish (Honduras)
windows-1252
OS Locale (lcid: 4c0a): Spanish (Nicaragua) - 1252
es_NI
Spanish (Nicaragua)
windows-1252
OS Locale (lcid: 500a): Spanish (Puerto Rico) - 1252
es_PR
Spanish (Puerto Rico)
windows-1252
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册