diff options
Diffstat (limited to 'libc/misc/locale/locale.c')
| -rw-r--r-- | libc/misc/locale/locale.c | 177 |
1 files changed, 77 insertions, 100 deletions
diff --git a/libc/misc/locale/locale.c b/libc/misc/locale/locale.c index 858a02c33..68e54413e 100644 --- a/libc/misc/locale/locale.c +++ b/libc/misc/locale/locale.c @@ -11,8 +11,8 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see + * <http://www.gnu.org/licenses/>. */ /* Nov. 1, 2002 @@ -58,20 +58,6 @@ #include <ctype.h> #include <stdio.h> -/* Experimentally off - libc_hidden_proto(memcpy) */ -/* Experimentally off - libc_hidden_proto(memset) */ -/* Experimentally off - libc_hidden_proto(strtok_r) */ -/* Experimentally off - libc_hidden_proto(strlen) */ -/* Experimentally off - libc_hidden_proto(strcmp) */ -/* Experimentally off - libc_hidden_proto(strcpy) */ -/* Experimentally off - libc_hidden_proto(strncmp) */ -/* Experimentally off - libc_hidden_proto(strchr) */ -libc_hidden_proto(getenv) -#ifdef __UCLIBC_HAS_CTYPE_TABLES__ -libc_hidden_proto(__C_ctype_toupper) -#endif -/*libc_hidden_proto(fflush)*/ - #ifdef __UCLIBC_MJN3_ONLY__ #ifdef L_setlocale #warning TODO: Make the link_warning()s a config option? @@ -99,19 +85,17 @@ libc_hidden_proto(__C_ctype_toupper) #endif #endif -/* Need to include this before locale.h and xlocale.h! */ +/* Need to include this before locale.h! */ #include <bits/uClibc_locale.h> #undef CODESET_LIST #define CODESET_LIST (__locale_mmap->codeset_list) #ifdef __UCLIBC_HAS_XLOCALE__ -#include <xlocale.h> #include <locale.h> -#else /* __UCLIBC_HAS_XLOCALE__ */ +#else /* __UCLIBC_HAS_XLOCALE__ */ /* We need this internally... */ #define __UCLIBC_HAS_XLOCALE__ 1 -#include <xlocale.h> #include <locale.h> #undef __UCLIBC_HAS_XLOCALE__ #endif /* __UCLIBC_HAS_XLOCALE__ */ @@ -120,14 +104,14 @@ libc_hidden_proto(__C_ctype_toupper) #define LOCALE_NAMES (__locale_mmap->locale_names5) #define LOCALES (__locale_mmap->locales) -#define LOCALE_AT_MODIFIERS (__locale_mmap->locale_at_modifiers) +#define LOCALE_AT_MODIFIERS (__locale_mmap->locale_at_modifiers) #define CATEGORY_NAMES (__locale_mmap->lc_names) #ifdef __UCLIBC_MJN3_ONLY__ #warning REMINDER: redo the MAX_LOCALE_STR stuff... #endif -#define MAX_LOCALE_STR 256 /* TODO: Only sufficient for current case. */ -#define MAX_LOCALE_CATEGORY_STR 32 /* TODO: Only sufficient for current case. */ +#define MAX_LOCALE_STR 256 /* TODO: Only sufficient for current case. */ +#define MAX_LOCALE_CATEGORY_STR 32 /* TODO: Only sufficient for current case. */ /* Note: Best if MAX_LOCALE_CATEGORY_STR is a power of 2. */ extern int _locale_set_l(const unsigned char *p, __locale_t base) attribute_hidden; @@ -169,7 +153,7 @@ char *setlocale(int category, register const char *locale) : NULL; } -#else /* ---------------------------------------------- __LOCALE_C_ONLY */ +#else /* ---------------------------------------------- __LOCALE_C_ONLY */ #ifdef __UCLIBC_HAS_THREADS__ link_warning(setlocale,"REMINDER: The 'setlocale' function is _not_ threadsafe except for simple queries.") @@ -193,8 +177,6 @@ static const char utf8[] = "UTF-8"; */ static char hr_locale[(MAX_LOCALE_CATEGORY_STR * LC_ALL) + MAX_LOCALE_STR]; -/* Experimentally off - libc_hidden_proto(stpcpy) */ -libc_hidden_proto(newlocale) static void update_hr_locale(const unsigned char *spec) { @@ -230,7 +212,8 @@ static void update_hr_locale(const unsigned char *spec) + __LOCALE_DATA_WIDTH_LOCALES * ((((int)(*s & 0x7f)) << 7) + (s[1] & 0x7f)); if (category == LC_ALL) { - n = stpcpy(n, CATEGORY_NAMES + (int) CATEGORY_NAMES[i]); + /* CATEGORY_NAMES is unsigned char* */ + n = stpcpy(n, (char*) CATEGORY_NAMES + (int) CATEGORY_NAMES[i]); *n++ = '='; } if (*loc == 0) { @@ -248,12 +231,12 @@ static void update_hr_locale(const unsigned char *spec) if (loc[2] == 2) { n = stpcpy(n, utf8); } else if (loc[2] >= 3) { - n = stpcpy(n, CODESET_LIST + (int)(CODESET_LIST[loc[2] - 3])); + n = stpcpy(n, (char*) CODESET_LIST + (int)(CODESET_LIST[loc[2] - 3])); } if (at) { const char *q; *n++ = '@'; - q = LOCALE_AT_MODIFIERS; + q = (char*) LOCALE_AT_MODIFIERS; do { if (q[1] == at) { n = stpcpy(n, q+2); @@ -267,7 +250,7 @@ static void update_hr_locale(const unsigned char *spec) } s += 2; } while (++i < category); - *--n = 0; /* Remove trailing ';' and nul-terminate. */ + *--n = 0; /* Remove trailing ';' and nul-terminate. */ ++category; } while (!done); @@ -303,7 +286,6 @@ char *setlocale(int category, const char *locale) * placement of the fields in the struct. If necessary, we could ensure * this usings an array of offsets but at some size cost. */ -libc_hidden_proto(localeconv) #ifdef __LOCALE_C_ONLY @@ -332,14 +314,14 @@ struct lconv *localeconv(void) return &the_lconv; } -#else /* __LOCALE_C_ONLY */ +#else /* __LOCALE_C_ONLY */ static struct lconv the_lconv; struct lconv *localeconv(void) { register char *p = (char *) &the_lconv; - register char **q = (char **) &(__UCLIBC_CURLOCALE_DATA).decimal_point; + register char **q = (char **) &(__UCLIBC_CURLOCALE->decimal_point); do { *((char **)p) = *q; @@ -364,15 +346,7 @@ libc_hidden_def(localeconv) /**********************************************************************/ #if defined(L__locale_init) && !defined(__LOCALE_C_ONLY) -libc_hidden_proto(__C_ctype_b) -libc_hidden_proto(__C_ctype_tolower) -#ifndef __UCLIBC_HAS_XLOCALE__ -libc_hidden_proto(__ctype_b) -libc_hidden_proto(__ctype_tolower) -libc_hidden_proto(__ctype_toupper) -#endif - -__uclibc_locale_t __global_locale_data; +struct __uclibc_locale_struct __global_locale_data; __locale_t __global_locale = &__global_locale_data; @@ -609,7 +583,7 @@ int attribute_hidden _locale_set_l(const unsigned char *p, __locale_t base) if ((p[2*LC_COLLATE] != s[2*LC_COLLATE]) || (p[2*LC_COLLATE + 1] != s[2*LC_COLLATE + 1]) ) { - row = (((int)(*p & 0x7f)) << 7) + (p[1] & 0x7f); + row = (((int)(*p & 0x7f)) << 7) + (p[1] & 0x7f); assert(row < __LOCALE_DATA_NUM_LOCALES); if (!init_cur_collate(__locale_mmap->locales[ __LOCALE_DATA_WIDTH_LOCALES * row + 3 + LC_COLLATE ], @@ -623,7 +597,7 @@ int attribute_hidden _locale_set_l(const unsigned char *p, __locale_t base) do { if ((*p != *s) || (p[1] != s[1])) { - row = (((int)(*p & 0x7f)) << 7) + (p[1] & 0x7f); + row = (((int)(*p & 0x7f)) << 7) + (p[1] & 0x7f); assert(row < __LOCALE_DATA_NUM_LOCALES); *s = *p; @@ -644,8 +618,8 @@ int attribute_hidden _locale_set_l(const unsigned char *p, __locale_t base) io = (const uint16_t *)( ((char *)__locale_mmap) + *++stp ); ii = (const uint16_t *)( ((char *)__locale_mmap) + *++stp ); d = (const unsigned char *)( ((char *)__locale_mmap) + *++stp ); - for (c=0 ; c < len ; c++) { - *(x + c) = d + ii[ r[crow + c] + io[c] ]; + for (c = 0; c < len; c++) { + x[c] = (char*)(d + ii[r[crow + c] + io[c]]); } } if (i == LC_CTYPE) { @@ -658,7 +632,7 @@ int attribute_hidden _locale_set_l(const unsigned char *p, __locale_t base) /* TODO - fix for bcc */ base->mb_cur_max = 6; } else { - assert(c==1); + assert(c == 1); base->codeset = ascii; base->encoding = __ctype_encoding_7_bit; base->mb_cur_max = 1; @@ -666,7 +640,8 @@ int attribute_hidden _locale_set_l(const unsigned char *p, __locale_t base) } else { const __codeset_8_bit_t *c8b; r = CODESET_LIST; - base->codeset = r + r[c -= 3]; + c -= 3; + base->codeset = (char *) (r + r[c]); base->encoding = __ctype_encoding_8_bit; #ifdef __UCLIBC_MJN3_ONLY__ #warning REMINDER: update 8 bit mb_cur_max when translit implemented! @@ -789,7 +764,7 @@ int attribute_hidden _locale_set_l(const unsigned char *p, __locale_t base) + __UCLIBC_CTYPE_TO_TBL_OFFSET; base->__ctype_toupper = base->__ctype_toupper_data + __UCLIBC_CTYPE_TO_TBL_OFFSET; -#else /* __UCLIBC_HAS_XLOCALE__ */ +#else /* __UCLIBC_HAS_XLOCALE__ */ __ctype_b = base->__ctype_b_data + __UCLIBC_CTYPE_B_TBL_OFFSET; __ctype_tolower = base->__ctype_tolower_data @@ -879,17 +854,17 @@ void attribute_hidden _locale_init_l(__locale_t base) LC_ALL); ++base->category_item_count[0]; /* Increment for codeset entry. */ - base->category_offsets[0] = offsetof(__uclibc_locale_t, outdigit0_mb); - base->category_offsets[1] = offsetof(__uclibc_locale_t, decimal_point); - base->category_offsets[2] = offsetof(__uclibc_locale_t, int_curr_symbol); - base->category_offsets[3] = offsetof(__uclibc_locale_t, abday_1); -/* base->category_offsets[4] = offsetof(__uclibc_locale_t, collate???); */ - base->category_offsets[5] = offsetof(__uclibc_locale_t, yesexpr); + base->category_offsets[0] = offsetof(struct __uclibc_locale_struct, outdigit0_mb); + base->category_offsets[1] = offsetof(struct __uclibc_locale_struct, decimal_point); + base->category_offsets[2] = offsetof(struct __uclibc_locale_struct, int_curr_symbol); + base->category_offsets[3] = offsetof(struct __uclibc_locale_struct, abday_1); +/* base->category_offsets[4] = offsetof(struct __uclibc_locale_struct, collate???); */ + base->category_offsets[5] = offsetof(struct __uclibc_locale_struct, yesexpr); #ifdef __CTYPE_HAS_8_BIT_LOCALES base->tbl8ctype = (const unsigned char *) &__locale_mmap->tbl8ctype; - base->tbl8uplow + base->tbl8uplow = (const unsigned char *) &__locale_mmap->tbl8uplow; #ifdef __UCLIBC_HAS_WCHAR__ base->tbl8c2wc @@ -905,7 +880,7 @@ void attribute_hidden _locale_init_l(__locale_t base) base->tblwuplow = (const unsigned char *) &__locale_mmap->tblwuplow; base->tblwuplow_diff - = (const uint16_t *) &__locale_mmap->tblwuplow_diff; + = (const int16_t *) &__locale_mmap->tblwuplow_diff; /* base->tblwcomb */ /* = (const unsigned char *) &__locale_mmap->tblwcomb; */ /* width?? */ @@ -917,7 +892,7 @@ void attribute_hidden _locale_init_l(__locale_t base) base->__ctype_b = __C_ctype_b; base->__ctype_tolower = __C_ctype_tolower; base->__ctype_toupper = __C_ctype_toupper; -#else /* __UCLIBC_HAS_XLOCALE__ */ +#else /* __UCLIBC_HAS_XLOCALE__ */ __ctype_b = __C_ctype_b; __ctype_tolower = __C_ctype_tolower; __ctype_toupper = __C_ctype_toupper; @@ -928,11 +903,9 @@ void attribute_hidden _locale_init_l(__locale_t base) #endif base->code2flag = __code2flag; - - _locale_set_l(C_LOCALE_SELECTOR, base); + _locale_set_l((unsigned char*) C_LOCALE_SELECTOR, base); } -void _locale_init(void) attribute_hidden; void _locale_init(void) { /* TODO: mmap the locale file */ @@ -967,7 +940,7 @@ void _locale_init(void) static const unsigned char nl_data[C_LC_ALL + 1 + 90 + 320] = { /* static const char cat_start[LC_ALL + 1] = { */ - '\x00', '\x0b', '\x0e', '\x24', '\x56', '\x56', '\x5a', + '\x00', '\x0b', '\x0e', '\x24', '\x56', '\x56', '\x5a', /* }; */ /* static const char item_offset[90] = { */ '\x00', '\x02', '\x04', '\x06', '\x08', '\x0a', '\x0c', '\x0e', @@ -1026,7 +999,6 @@ static const unsigned char nl_data[C_LC_ALL + 1 + 90 + 320] = { ']', '\x00', '^', '[', 'n', 'N', ']', '\x00', }; -libc_hidden_proto(nl_langinfo) char *nl_langinfo(nl_item item) { unsigned int c; @@ -1042,13 +1014,11 @@ char *nl_langinfo(nl_item item) } libc_hidden_def(nl_langinfo) -#else /* __LOCALE_C_ONLY */ +#else /* __LOCALE_C_ONLY */ #if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) -libc_hidden_proto(nl_langinfo) -libc_hidden_proto(nl_langinfo_l) char *nl_langinfo(nl_item item) { @@ -1056,13 +1026,13 @@ char *nl_langinfo(nl_item item) } libc_hidden_def(nl_langinfo) -#else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */ +#else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */ libc_hidden_proto(__XL_NPP(nl_langinfo)) static const char empty[] = ""; -char *__XL_NPP(nl_langinfo)(nl_item item __LOCALE_PARAM ) +char *__XL_NPP(nl_langinfo)(nl_item item __LOCALE_PARAM ) { unsigned int c = _NL_ITEM_CATEGORY(item); unsigned int i = _NL_ITEM_INDEX(item); @@ -1084,8 +1054,7 @@ libc_hidden_def(__XL_NPP(nl_langinfo)) /**********************************************************************/ #ifdef L_newlocale -/* Experimentally off - libc_hidden_proto(stpcpy) */ -libc_hidden_proto(newlocale) +#warning mask defines for extra locale categories #ifdef __UCLIBC_MJN3_ONLY__ #warning TODO: Move posix and utf8 strings. @@ -1117,7 +1086,7 @@ static int find_locale(int category_mask, const char *p, /* locale name at least 5 chars long and 3rd char is '_' */ s = LOCALE_AT_MODIFIERS; do { - if (!strcmp(s+2, q+1)) { + if (!strcmp((char*) (s + 2), q + 1)) { break; } s += 2 + *s; /* TODO - fix this throughout */ @@ -1142,11 +1111,11 @@ static int find_locale(int category_mask, const char *p, /* TODO: maybe CODESET_LIST + *s ??? */ /* 7bit is 1, UTF-8 is 2, 8-bit is >= 3 */ codeset = 2; - if (strcasecmp(utf8,p+6) != 0) {/* TODO - fix! */ + if (strcasecmp(utf8, p + 6) != 0) {/* TODO - fix! */ s = CODESET_LIST; do { ++codeset; /* Increment codeset first. */ - if (!strcmp(CODESET_LIST+*s, p+6)) { + if (!strcmp((char*) CODESET_LIST + *s, p + 6)) { goto FIND_LANG_CULT; } } while (*++s); @@ -1159,7 +1128,7 @@ static int find_locale(int category_mask, const char *p, do { /* TODO -- do a binary search? */ /* TODO -- fix gen_mmap!*/ ++lang_cult; /* Increment first since C/POSIX is 0. */ - if (!strncmp(s,p,5)) { /* Found a matching locale name; */ + if (!strncmp((char*) s, p, 5)) { /* Found a matching locale name; */ goto FIND_LOCALE; } s += 5; @@ -1217,7 +1186,8 @@ static unsigned char *composite_locale(int category_mask, const char *locale, t = strtok_r(buf, "=", &e); /* This can't fail because of strchr test above. */ do { c = 0; - while (strcmp(CATEGORY_NAMES + (int) CATEGORY_NAMES[c], t)) { + /* CATEGORY_NAMES is unsigned char* */ + while (strcmp((char*) CATEGORY_NAMES + (int) CATEGORY_NAMES[c], t)) { if (++c == LC_ALL) { /* Unknown category name! */ return NULL; } @@ -1242,7 +1212,7 @@ static unsigned char *composite_locale(int category_mask, const char *locale, __locale_t newlocale(int category_mask, const char *locale, __locale_t base) { - const unsigned char *p; + const char *p; int i, j, k; unsigned char new_selector[LOCALE_SELECTOR_SIZE]; @@ -1250,10 +1220,10 @@ __locale_t newlocale(int category_mask, const char *locale, __locale_t base) category_mask = LC_ALL_MASK; } - if (!locale || (((unsigned int)(category_mask)) > LC_ALL_MASK)) { - INVALID: + if (!locale || ((unsigned)(category_mask) > LC_ALL_MASK)) { + INVALID: __set_errno(EINVAL); - return NULL; /* No locale or illegal/unsupported category. */ + return NULL; /* No locale or illegal/unsupported category. */ } #ifdef __UCLIBC_MJN3_ONLY__ @@ -1262,11 +1232,13 @@ __locale_t newlocale(int category_mask, const char *locale, __locale_t base) strcpy((char *) new_selector, (base ? (char *) base->cur_locale : C_LOCALE_SELECTOR)); - if (!*locale) { /* locale == "", so check environment. */ -#ifndef __UCLIBC_HAS_THREADS__ - static /* If no threads, then envstr can be static. */ -#endif /* __UCLIBC_HAS_THREADS__ */ - const char *envstr[4] = { "LC_ALL", NULL, "LANG", posix }; + if (!locale[0]) { /* locale == "", so check environment. */ + const char *envstr[4]; + + envstr[0] = "LC_ALL"; + envstr[1] = NULL; + envstr[2] = "LANG"; + envstr[3] = posix; i = 1; k = 0; @@ -1275,12 +1247,16 @@ __locale_t newlocale(int category_mask, const char *locale, __locale_t base) /* Note: SUSv3 doesn't define a fallback mechanism here. * So, if LC_ALL is invalid, we do _not_ continue trying * the other environment vars. */ - envstr[1] = CATEGORY_NAMES + CATEGORY_NAMES[k]; + envstr[1] = (char*) CATEGORY_NAMES + CATEGORY_NAMES[k]; j = 0; - do { + while (1) { p = envstr[j]; - } while ((++j < 4) && (!(p = getenv(p)) || !*p)); - + if (++j >= 4) + break; /* now p == "POSIX" */ + p = getenv(p); + if (p && p[0]) + break; + }; /* The user set something... is it valid? */ /* Note: Since we don't support user-supplied locales and @@ -1313,9 +1289,9 @@ __locale_t newlocale(int category_mask, const char *locale, __locale_t base) } #else if (!base) { - if ((base = malloc(sizeof(__uclibc_locale_t))) == NULL) { + base = calloc(1, sizeof(struct __uclibc_locale_struct)); + if (base == NULL) return base; - } _locale_init_l(base); } @@ -1324,13 +1300,14 @@ __locale_t newlocale(int category_mask, const char *locale, __locale_t base) return base; } +#ifdef __UCLIBC_HAS_XLOCALE__ libc_hidden_def(newlocale) +#endif #endif /**********************************************************************/ #ifdef L_duplocale -libc_hidden_proto(duplocale) #ifdef __UCLIBC_MJN3_ONLY__ #warning REMINDER: When we allocate ctype tables, remember to dup them. @@ -1344,12 +1321,12 @@ __locale_t duplocale(__locale_t dataset) assert(dataset != LC_GLOBAL_LOCALE); - if ((r = malloc(sizeof(__uclibc_locale_t))) != NULL) { - n = 2*dataset->collate.max_col_index+2; - if ((i2w = calloc(n, sizeof(uint16_t))) - != NULL - ) { - memcpy(r, dataset, sizeof(__uclibc_locale_t)); + r = malloc(sizeof(struct __uclibc_locale_struct)); + if (r != NULL) { + n = 2 * dataset->collate.max_col_index + 2; + i2w = calloc(n, sizeof(uint16_t)); + if (i2w != NULL) { + memcpy(r, dataset, sizeof(struct __uclibc_locale_struct)); r->collate.index2weight = i2w; memcpy(i2w, dataset->collate.index2weight, n * sizeof(uint16_t)); } else { @@ -1359,7 +1336,6 @@ __locale_t duplocale(__locale_t dataset) } return r; } -libc_hidden_def(duplocale) #endif /**********************************************************************/ @@ -1382,7 +1358,6 @@ void freelocale(__locale_t dataset) /**********************************************************************/ #ifdef L_uselocale -libc_hidden_proto(uselocale) __locale_t uselocale(__locale_t dataset) { __locale_t old; @@ -1416,8 +1391,9 @@ libc_hidden_def(uselocale) __locale_t weak_const_function __curlocale(void) { - return __curlocale_var; /* This is overriden by the thread version. */ + return __curlocale_var; /* This is overriden by the thread version. */ } +libc_hidden_weak(__curlocale) __locale_t weak_function __curlocale_set(__locale_t newloc) { @@ -1426,6 +1402,7 @@ __locale_t weak_function __curlocale_set(__locale_t newloc) __curlocale_var = newloc; return oldloc; } +libc_hidden_weak(__curlocale_set) #endif |
