* libc/locale/locale.c: Add Cygwin's /usr/share/locale/locale.alias

support to documentation.
	(__set_locale_from_locale_alias): Declare when build for Cygwin.
	(loadlocale): On Cygwin, if locale can't be recognized, call
	__set_locale_from_locale_alias to check for locale alias.
	Define FAIL macro to replace `return NULL' statements.  Replace
	throughout.
This commit is contained in:
Corinna Vinschen 2010-02-07 13:52:34 +00:00
parent 8803e713c7
commit 9ac5e663e8
2 changed files with 55 additions and 26 deletions

View File

@ -1,3 +1,13 @@
2010-02-07 Corinna Vinschen <corinna@vinschen.de>
* libc/locale/locale.c: Add Cygwin's /usr/share/locale/locale.alias
support to documentation.
(__set_locale_from_locale_alias): Declare when build for Cygwin.
(loadlocale): On Cygwin, if locale can't be recognized, call
__set_locale_from_locale_alias to check for locale alias.
Define FAIL macro to replace `return NULL' statements. Replace
throughout.
2010-02-07 Corinna Vinschen <corinna@vinschen.de> 2010-02-07 Corinna Vinschen <corinna@vinschen.de>
* libc/locale/locale.c: Fix typo in documentation. Remove useless * libc/locale/locale.c: Fix typo in documentation. Remove useless

View File

@ -83,6 +83,9 @@ only newlib for Cygwin is built with full charset support by default.
Under Cygwin, this implementation additionally supports the charsets Under Cygwin, this implementation additionally supports the charsets
<<"GBK">>, <<"eucKR">>, and <<"Big5">>. Cygwin does not support <<"JIS">>. <<"GBK">>, <<"eucKR">>, and <<"Big5">>. Cygwin does not support <<"JIS">>.
Cygwin additionally supports locales from the file
/usr/share/locale/locale.alias.
(<<"">> is also accepted; if given, the settings are read from the (<<"">> is also accepted; if given, the settings are read from the
corresponding LC_* environment variables and $LANG according to POSIX rules. corresponding LC_* environment variables and $LANG according to POSIX rules.
@ -430,6 +433,7 @@ currentlocale()
#ifdef _MB_CAPABLE #ifdef _MB_CAPABLE
#ifdef __CYGWIN__ #ifdef __CYGWIN__
extern void __set_charset_from_locale (const char *locale, char *charset); extern void __set_charset_from_locale (const char *locale, char *charset);
extern int __set_locale_from_locale_alias (const char *, char *);
extern int __collate_load_locale (const char *, void *, const char *); extern int __collate_load_locale (const char *, void *, const char *);
#endif /* __CYGWIN__ */ #endif /* __CYGWIN__ */
@ -446,7 +450,7 @@ loadlocale(struct _reent *p, int category)
backward compatibility. If the local string is correct, the charset backward compatibility. If the local string is correct, the charset
is extracted and stored in lc_ctype_charset or lc_message_charset is extracted and stored in lc_ctype_charset or lc_message_charset
dependent on the cateogry. */ dependent on the cateogry. */
char *locale = new_categories[category]; char *locale = NULL;
char charset[ENCODING_LEN + 1]; char charset[ENCODING_LEN + 1];
unsigned long val; unsigned long val;
char *end, *c; char *end, *c;
@ -456,7 +460,22 @@ loadlocale(struct _reent *p, int category)
const char *, mbstate_t *); const char *, mbstate_t *);
int cjknarrow = 0; int cjknarrow = 0;
#ifdef __CYGWIN__ #ifdef __CYGWIN__
char tmp_locale[ENCODING_LEN + 1];
int ret = 0; int ret = 0;
restart:
if (!locale)
locale = new_categories[category];
else if (locale != tmp_locale)
{
locale = __set_locale_from_locale_alias (locale, tmp_locale);
if (!locale)
return NULL;
}
# define FAIL goto restart
#else
locale = new_categories[category];
# define FAIL return NULL
#endif #endif
/* "POSIX" is translated to "C", as on Linux. */ /* "POSIX" is translated to "C", as on Linux. */
@ -484,7 +503,7 @@ loadlocale(struct _reent *p, int category)
/* Language */ /* Language */
if (c[0] < 'a' || c[0] > 'z' if (c[0] < 'a' || c[0] > 'z'
|| c[1] < 'a' || c[1] > 'z') || c[1] < 'a' || c[1] > 'z')
return NULL; FAIL;
c += 2; c += 2;
/* Allow three character Language per ISO 639-3 */ /* Allow three character Language per ISO 639-3 */
if (c[0] >= 'a' && c[0] <= 'z') if (c[0] >= 'a' && c[0] <= 'z')
@ -495,7 +514,7 @@ loadlocale(struct _reent *p, int category)
++c; ++c;
if (c[0] < 'A' || c[0] > 'Z' if (c[0] < 'A' || c[0] > 'Z'
|| c[1] < 'A' || c[1] > 'Z') || c[1] < 'A' || c[1] > 'Z')
return NULL; FAIL;
c += 2; c += 2;
} }
if (c[0] == '.') if (c[0] == '.')
@ -519,7 +538,7 @@ loadlocale(struct _reent *p, int category)
#endif #endif
else else
/* Invalid string */ /* Invalid string */
return NULL; FAIL;
if (c[0] == '@') if (c[0] == '@')
{ {
/* Modifier */ /* Modifier */
@ -536,7 +555,7 @@ loadlocale(struct _reent *p, int category)
case 'U': case 'U':
case 'u': case 'u':
if (strcasecmp (charset, "UTF-8") && strcasecmp (charset, "UTF8")) if (strcasecmp (charset, "UTF-8") && strcasecmp (charset, "UTF8"))
return NULL; FAIL;
strcpy (charset, "UTF-8"); strcpy (charset, "UTF-8");
mbc_max = 6; mbc_max = 6;
l_wctomb = __utf8_wctomb; l_wctomb = __utf8_wctomb;
@ -546,7 +565,7 @@ loadlocale(struct _reent *p, int category)
case 'J': case 'J':
case 'j': case 'j':
if (strcasecmp (charset, "JIS")) if (strcasecmp (charset, "JIS"))
return NULL; FAIL;
strcpy (charset, "JIS"); strcpy (charset, "JIS");
mbc_max = 8; mbc_max = 8;
l_wctomb = __jis_wctomb; l_wctomb = __jis_wctomb;
@ -573,12 +592,12 @@ loadlocale(struct _reent *p, int category)
} }
#endif /* __CYGWIN__ */ #endif /* __CYGWIN__ */
else else
return NULL; FAIL;
break; break;
case 'S': case 'S':
case 's': case 's':
if (strcasecmp (charset, "SJIS")) if (strcasecmp (charset, "SJIS"))
return NULL; FAIL;
strcpy (charset, "SJIS"); strcpy (charset, "SJIS");
mbc_max = 2; mbc_max = 2;
l_wctomb = __sjis_wctomb; l_wctomb = __sjis_wctomb;
@ -589,18 +608,18 @@ loadlocale(struct _reent *p, int category)
/* Must be exactly one of ISO-8859-1, [...] ISO-8859-16, except for /* Must be exactly one of ISO-8859-1, [...] ISO-8859-16, except for
ISO-8859-12. This code also recognizes the aliases without dashes. */ ISO-8859-12. This code also recognizes the aliases without dashes. */
if (strncasecmp (charset, "ISO", 3)) if (strncasecmp (charset, "ISO", 3))
return NULL; FAIL;
c = charset + 3; c = charset + 3;
if (*c == '-') if (*c == '-')
++c; ++c;
if (strncasecmp (c, "8859", 4)) if (strncasecmp (c, "8859", 4))
return NULL; FAIL;
c += 4; c += 4;
if (*c == '-') if (*c == '-')
++c; ++c;
val = _strtol_r (p, c, &end, 10); val = _strtol_r (p, c, &end, 10);
if (val < 1 || val > 16 || val == 12 || *end) if (val < 1 || val > 16 || val == 12 || *end)
return NULL; FAIL;
strcpy (charset, "ISO-8859-"); strcpy (charset, "ISO-8859-");
c = charset + 9; c = charset + 9;
if (val > 10) if (val > 10)
@ -619,11 +638,11 @@ loadlocale(struct _reent *p, int category)
case 'C': case 'C':
case 'c': case 'c':
if (charset[1] != 'P' && charset[1] != 'p') if (charset[1] != 'P' && charset[1] != 'p')
return NULL; FAIL;
strncpy (charset, "CP", 2); strncpy (charset, "CP", 2);
val = _strtol_r (p, charset + 2, &end, 10); val = _strtol_r (p, charset + 2, &end, 10);
if (*end) if (*end)
return NULL; FAIL;
switch (val) switch (val)
{ {
case 437: case 437:
@ -663,14 +682,14 @@ loadlocale(struct _reent *p, int category)
l_mbtowc = __sjis_mbtowc; l_mbtowc = __sjis_mbtowc;
break; break;
default: default:
return NULL; FAIL;
} }
break; break;
case 'K': case 'K':
case 'k': case 'k':
/* KOI8-R, KOI8-U and the aliases without dash */ /* KOI8-R, KOI8-U and the aliases without dash */
if (strncasecmp (charset, "KOI8", 4)) if (strncasecmp (charset, "KOI8", 4))
return NULL; FAIL;
c = charset + 4; c = charset + 4;
if (*c == '-') if (*c == '-')
++c; ++c;
@ -679,7 +698,7 @@ loadlocale(struct _reent *p, int category)
else if (*c == 'U' || *c == 'u') else if (*c == 'U' || *c == 'u')
strcpy (charset, "CP21866"); strcpy (charset, "CP21866");
else else
return NULL; FAIL;
mbc_max = 1; mbc_max = 1;
#ifdef _MB_EXTENDED_CHARSETS_WINDOWS #ifdef _MB_EXTENDED_CHARSETS_WINDOWS
l_wctomb = __cp_wctomb; l_wctomb = __cp_wctomb;
@ -692,7 +711,7 @@ loadlocale(struct _reent *p, int category)
case 'A': case 'A':
case 'a': case 'a':
if (strcasecmp (charset, "ASCII")) if (strcasecmp (charset, "ASCII"))
return NULL; FAIL;
strcpy (charset, "ASCII"); strcpy (charset, "ASCII");
mbc_max = 1; mbc_max = 1;
l_wctomb = __ascii_wctomb; l_wctomb = __ascii_wctomb;
@ -717,7 +736,7 @@ loadlocale(struct _reent *p, int category)
if (*c == '-') if (*c == '-')
++c; ++c;
if (strcasecmp (c, "PS")) if (strcasecmp (c, "PS"))
return NULL; FAIL;
strcpy (charset, "CP101"); strcpy (charset, "CP101");
mbc_max = 1; mbc_max = 1;
#ifdef _MB_EXTENDED_CHARSETS_WINDOWS #ifdef _MB_EXTENDED_CHARSETS_WINDOWS
@ -729,13 +748,13 @@ loadlocale(struct _reent *p, int category)
#endif /* _MB_EXTENDED_CHARSETS_WINDOWS */ #endif /* _MB_EXTENDED_CHARSETS_WINDOWS */
} }
else else
return NULL; FAIL;
break; break;
case 'P': case 'P':
case 'p': case 'p':
/* PT154 */ /* PT154 */
if (strcasecmp (charset, "PT154")) if (strcasecmp (charset, "PT154"))
return NULL; FAIL;
strcpy (charset, "CP102"); strcpy (charset, "CP102");
mbc_max = 1; mbc_max = 1;
#ifdef _MB_EXTENDED_CHARSETS_WINDOWS #ifdef _MB_EXTENDED_CHARSETS_WINDOWS
@ -749,12 +768,12 @@ loadlocale(struct _reent *p, int category)
case 'T': case 'T':
case 't': case 't':
if (strncasecmp (charset, "TIS", 3)) if (strncasecmp (charset, "TIS", 3))
return NULL; FAIL;
c = charset + 3; c = charset + 3;
if (*c == '-') if (*c == '-')
++c; ++c;
if (strcasecmp (c, "620")) if (strcasecmp (c, "620"))
return NULL; FAIL;
strcpy (charset, "CP874"); strcpy (charset, "CP874");
mbc_max = 1; mbc_max = 1;
#ifdef _MB_EXTENDED_CHARSETS_WINDOWS #ifdef _MB_EXTENDED_CHARSETS_WINDOWS
@ -769,7 +788,7 @@ loadlocale(struct _reent *p, int category)
case 'B': case 'B':
case 'b': case 'b':
if (strcasecmp (charset, "BIG5")) if (strcasecmp (charset, "BIG5"))
return NULL; FAIL;
strcpy (charset, "BIG5"); strcpy (charset, "BIG5");
mbc_max = 2; mbc_max = 2;
l_wctomb = __big5_wctomb; l_wctomb = __big5_wctomb;
@ -777,7 +796,7 @@ loadlocale(struct _reent *p, int category)
break; break;
#endif /* __CYGWIN__ */ #endif /* __CYGWIN__ */
default: default:
return NULL; FAIL;
} }
if (category == LC_CTYPE) if (category == LC_CTYPE)
{ {
@ -809,7 +828,7 @@ loadlocale(struct _reent *p, int category)
else if (category == LC_TIME) else if (category == LC_TIME)
ret = __time_load_locale (locale, (void *) l_wctomb, charset); ret = __time_load_locale (locale, (void *) l_wctomb, charset);
if (ret) if (ret)
return NULL; FAIL;
#endif /* __CYGWIN__ */ #endif /* __CYGWIN__ */
return strcpy(current_categories[category], new_categories[category]); return strcpy(current_categories[category], new_categories[category]);
} }