/home/ntakagi/work/STLport-5.1.5/src/c_locale_glibc/c_locale_glibc.cGo to the documentation of this file.00001 /* 00002 * Copyright (c) 1999 00003 * Silicon Graphics Computer Systems, Inc. 00004 * 00005 * Permission to use, copy, modify, distribute and sell this software 00006 * and its documentation for any purpose is hereby granted without fee, 00007 * provided that the above copyright notice appear in all copies and 00008 * that both that copyright notice and this permission notice appear 00009 * in supporting documentation. Silicon Graphics makes no 00010 * representations about the suitability of this software for any 00011 * purpose. It is provided "as is" without express or implied warranty. 00012 */ 00013 00014 00015 #include <stdlib.h> 00016 #include <string.h> 00017 #include <unistd.h> 00018 #ifdef _POSIX_MAPPED_FILES 00019 # include <sys/mman.h> 00020 #endif 00021 00022 #include <stl/c_locale.h> 00023 #include <limits.h> 00024 #include <wctype.h> 00025 /* #include <libc-lock.h> */ 00026 00027 #include <locale.h> 00028 #include <argz.h> 00029 #include "gcc_localeinfo.h" 00030 00031 wint_t btowc(int c); 00032 int wctob (wint_t c); 00033 00034 size_t mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps); 00035 size_t wcrtomb (char *s, wchar_t wc, mbstate_t *ps); 00036 size_t mbrlen (const char* s, size_t n, mbstate_t *ps); 00037 00038 #include <nl_types.h> 00039 00040 void _Locale_init() 00041 {} 00042 00043 void _Locale_final() 00044 {} 00045 00046 typedef struct _Locale_ctype { 00047 const struct locale_data* gcc_data; 00048 const int* __tolower; 00049 const int* __toupper; 00050 _Locale_mask_t* __class; 00051 } L_ctype_t; 00052 00053 typedef struct _Locale_numeric { 00054 const struct locale_data* gcc_data; 00055 } L_numeric_t; 00056 00057 typedef struct _Locale_time { 00058 const struct locale_data* gcc_data; 00059 } L_time_t; 00060 00061 typedef struct _Locale_collate { 00062 const struct locale_data* gcc_data; 00063 } L_collate_t; 00064 00065 typedef struct _Locale_monetary { 00066 const struct locale_data* gcc_data; 00067 } L_monetary_t; 00068 00069 typedef struct _Locale_messages { 00070 const struct locale_data* gcc_data; 00071 } L_messages_t; 00072 00073 struct _Locale_name_hint* _Locale_get_ctype_hint(struct _Locale_ctype* ctype) 00074 { return 0; } 00075 struct _Locale_name_hint* _Locale_get_numeric_hint(struct _Locale_numeric* numeric) 00076 { return 0; } 00077 struct _Locale_name_hint* _Locale_get_time_hint(struct _Locale_time* time) 00078 { return 0; } 00079 struct _Locale_name_hint* _Locale_get_collate_hint(struct _Locale_collate* collate) 00080 { return 0; } 00081 struct _Locale_name_hint* _Locale_get_monetary_hint(struct _Locale_monetary* monetary) 00082 { return 0; } 00083 struct _Locale_name_hint* _Locale_get_messages_hint(struct _Locale_messages* messages) 00084 { return 0; } 00085 00086 static char const* 00087 _Locale_extract_name ( const char *cname, char *into, int category ) 00088 { 00089 int i = 0; 00090 const char * end; 00091 00092 if ( cname[0] != '/' ) 00093 return strcpy(into, cname); /* simple locale name */ 00094 00095 for ( i = 0; i <= category; i ++ ) { 00096 while ( *cname != '\0' && *cname != '/' ) 00097 cname++; 00098 if ( *cname == '\0' ) 00099 return into; 00100 cname++; 00101 } 00102 00103 if ( *cname == '\0' ) 00104 return into; 00105 00106 end = cname; 00107 while ( *end != '\0' && *end != '/' ) 00108 end++; 00109 00110 strncpy ( into, cname, end - cname ); 00111 into [ end - cname ] = '\0'; 00112 00113 return into; 00114 } 00115 00116 char const* _Locale_name(const struct locale_data* gcc_data, 00117 char* buf) 00118 { 00119 if (!(gcc_data && gcc_data->name)) return 0; 00120 strncpy(buf, gcc_data->name, _Locale_MAX_SIMPLE_NAME); 00121 buf [ _Locale_MAX_SIMPLE_NAME - 1 ] = '\0'; 00122 return buf; 00123 } 00124 00125 00126 /* calls _nl_find_locale which is a function internal to the glibc 00127 locale implementation that loads locale data in from the data 00128 files. The locale_data struct has information for all categories. 00129 In the following implementation we use a locale_data struct for 00130 each category for simplicity, though there is an obvious waste in 00131 doing that. */ 00132 const struct locale_data * 00133 _Find_locale (char *locale_path, size_t locale_path_len, 00134 int category, char **name) 00135 { 00136 return __nl_find_locale(locale_path, locale_path_len, category, name); 00137 } 00138 00139 00140 static void 00141 _Remove_locale (int locale, struct locale_data *data) 00142 { 00143 /* this should eventually call _nl_remove_locale() in glibc 2.1 */ 00144 /* _nl_remove_locale( locale, data ); */ 00145 } 00146 00147 /* couldn't find where LOCALE_PATH was defined in glibc, 00148 but this is the directory it is defined to -JGS */ 00149 #define __LOCALE_PATH "/usr/share/locale" 00150 00151 const struct locale_data* 00152 _Category_create(const char * name, int category) 00153 { 00154 /* JGS, where should this path come from? */ 00155 char* locpath_var; 00156 char* locale_path = NULL; 00157 size_t locale_path_len = 0; 00158 00159 locpath_var = __secure_getenv("LOCPATH"); 00160 00161 if (locpath_var != NULL && locpath_var[0] != '\0') 00162 if (argz_create_sep (locpath_var, ':', 00163 &locale_path, &locale_path_len) != 0) 00164 return NULL; 00165 00166 if (argz_add_sep (&locale_path, &locale_path_len, __LOCALE_PATH, ':') != 0) 00167 return NULL; 00168 00169 return _Find_locale(locale_path, locale_path_len, 00170 category, (char**)&name); 00171 } 00172 00173 00174 00175 static const char* get_default_locale(char* buf) { 00176 char* lang = getenv("LANG"); 00177 if (lang == NULL || lang[0] == '\0') { 00178 buf[0] = '\0'; 00179 return NULL; 00180 } 00181 else { 00182 strcpy(buf, lang); 00183 return buf; 00184 } 00185 } 00186 00187 const char* _Locale_ctype_default(char* buf) { 00188 char fullname[_Locale_MAX_COMPOSITE_NAME]; 00189 if (get_default_locale(fullname) == NULL) 00190 return NULL; 00191 else 00192 return _Locale_extract_ctype_name(fullname, buf, 0); 00193 } 00194 00195 const char* _Locale_numeric_default(char* buf) { 00196 char fullname[_Locale_MAX_COMPOSITE_NAME]; 00197 if (get_default_locale(fullname) == NULL) 00198 return NULL; 00199 else 00200 return _Locale_extract_numeric_name(fullname, buf, 0); 00201 } 00202 00203 const char* _Locale_time_default(char* buf) { 00204 char fullname[_Locale_MAX_COMPOSITE_NAME]; 00205 if (get_default_locale(fullname) == NULL) 00206 return NULL; 00207 else 00208 return _Locale_extract_time_name(fullname, buf, 0); 00209 } 00210 00211 const char* _Locale_collate_default(char* buf) { 00212 char fullname[_Locale_MAX_COMPOSITE_NAME]; 00213 if (get_default_locale(fullname) == NULL) 00214 return NULL; 00215 else 00216 return _Locale_extract_collate_name(fullname, buf, 0); 00217 } 00218 00219 const char* _Locale_monetary_default(char* buf) { 00220 char fullname[_Locale_MAX_COMPOSITE_NAME]; 00221 if (get_default_locale(fullname) == NULL) 00222 return NULL; 00223 else 00224 return _Locale_extract_monetary_name(fullname, buf, 0); 00225 } 00226 00227 const char* _Locale_messages_default(char* buf) { 00228 char fullname[_Locale_MAX_COMPOSITE_NAME]; 00229 if (get_default_locale(fullname) == NULL) 00230 return NULL; 00231 else 00232 return _Locale_extract_messages_name(fullname, buf, 0); 00233 } 00234 00235 00236 /****** Numeric Category ******/ 00237 00238 void* 00239 _Locale_numeric_create(const char * name, struct _Locale_name_hint* hint) { 00240 L_numeric_t* lnum = (L_numeric_t*)malloc(sizeof(L_numeric_t)); 00241 lnum->gcc_data = _Category_create(name, LC_NUMERIC); 00242 return (void*)lnum; 00243 } 00244 00245 00246 char const* _Locale_numeric_name(const void* lnum, 00247 char* buf) { 00248 return _Locale_name(((struct _Locale_ctype*)lnum)->gcc_data, buf); 00249 } 00250 void _Locale_numeric_destroy(void* lnum) 00251 { 00252 _Remove_locale(LC_NUMERIC, (struct locale_data *)((struct _Locale_ctype*)lnum)->gcc_data); 00253 free(lnum); 00254 } 00255 char const* _Locale_extract_numeric_name(const char* cname, char* buf, struct _Locale_name_hint* hint) 00256 { 00257 return _Locale_extract_name(cname, buf, LC_NUMERIC); 00258 } 00259 char _Locale_decimal_point(struct _Locale_numeric* lnum) 00260 { 00261 return lnum->gcc_data->values[_NL_ITEM_INDEX(DECIMAL_POINT)].string[0]; 00262 } 00263 char _Locale_thousands_sep(struct _Locale_numeric* lnum) 00264 { 00265 return lnum->gcc_data->values[_NL_ITEM_INDEX(THOUSANDS_SEP)].string[0]; 00266 } 00267 const char* _Locale_grouping(struct _Locale_numeric * lnum) 00268 { 00269 return lnum->gcc_data->values[_NL_ITEM_INDEX(GROUPING)].string; 00270 } 00271 00272 /* JGS: gcc/linux does not provide true/false names in their 00273 * locale data files 00274 */ 00275 00276 static const char* __true_name = "true"; 00277 static const char* __false_name = "false"; 00278 00279 const char * _Locale_true(struct _Locale_numeric *l) 00280 { return __true_name; } 00281 const char * _Locale_false(struct _Locale_numeric *l) 00282 { return __false_name; } 00283 00284 00285 /****** Monetary Category ******/ 00286 00287 void* _Locale_monetary_create(const char* name, struct _Locale_name_hint* hint) { 00288 L_monetary_t* lmon = (L_monetary_t*)malloc(sizeof(L_monetary_t)); 00289 lmon->gcc_data = _Category_create(name, LC_MONETARY); 00290 return lmon; 00291 } 00292 00293 char const* _Locale_monetary_name(const void* lmon, 00294 char* buf) { 00295 return _Locale_name(((struct _Locale_monetary*)lmon)->gcc_data, buf); 00296 } 00297 00298 void _Locale_monetary_destroy(void*lmon) { 00299 _Remove_locale(LC_MONETARY, (struct locale_data *)((struct _Locale_monetary*)lmon)->gcc_data); 00300 free(lmon); 00301 } 00302 00303 char const* _Locale_extract_monetary_name(const char* cname, char* buf, struct _Locale_name_hint* hint) { 00304 return _Locale_extract_name(cname, buf, LC_MONETARY); 00305 } 00306 00307 const char* _Locale_int_curr_symbol(struct _Locale_monetary* lmon) { 00308 return lmon->gcc_data->values[_NL_ITEM_INDEX(INT_CURR_SYMBOL)].string; 00309 } 00310 const char* _Locale_currency_symbol(struct _Locale_monetary* lmon) { 00311 return lmon->gcc_data->values[_NL_ITEM_INDEX(CURRENCY_SYMBOL)].string; 00312 } 00313 char _Locale_mon_decimal_point(struct _Locale_monetary* lmon) { 00314 return lmon->gcc_data->values[_NL_ITEM_INDEX(MON_DECIMAL_POINT)].string[0]; 00315 } 00316 char _Locale_mon_thousands_sep(struct _Locale_monetary* lmon) { 00317 return lmon->gcc_data->values[_NL_ITEM_INDEX(MON_THOUSANDS_SEP)].string[0]; 00318 } 00319 const char* _Locale_mon_grouping(struct _Locale_monetary* lmon) { 00320 return lmon->gcc_data->values[_NL_ITEM_INDEX(MON_GROUPING)].string; 00321 } 00322 const char* _Locale_positive_sign(struct _Locale_monetary* lmon) { 00323 return lmon->gcc_data->values[_NL_ITEM_INDEX(POSITIVE_SIGN)].string; 00324 } 00325 const char* _Locale_negative_sign(struct _Locale_monetary* lmon) { 00326 return lmon->gcc_data->values[_NL_ITEM_INDEX(NEGATIVE_SIGN)].string; 00327 } 00328 char _Locale_int_frac_digits(struct _Locale_monetary* lmon) { 00329 return lmon->gcc_data->values[_NL_ITEM_INDEX(INT_FRAC_DIGITS)].string[0]; 00330 } 00331 char _Locale_frac_digits(struct _Locale_monetary* lmon) { 00332 return lmon->gcc_data->values[_NL_ITEM_INDEX(FRAC_DIGITS)].string[0]; 00333 } 00334 int _Locale_p_cs_precedes(struct _Locale_monetary* lmon) { 00335 return lmon->gcc_data->values[_NL_ITEM_INDEX(P_CS_PRECEDES)].word; 00336 } 00337 int _Locale_p_sep_by_space(struct _Locale_monetary* lmon) { 00338 return lmon->gcc_data->values[_NL_ITEM_INDEX(P_SEP_BY_SPACE)].word; 00339 } 00340 int _Locale_p_sign_posn(struct _Locale_monetary* lmon) { 00341 return lmon->gcc_data->values[_NL_ITEM_INDEX(P_SIGN_POSN)].word; 00342 } 00343 int _Locale_n_cs_precedes(struct _Locale_monetary* lmon) { 00344 return lmon->gcc_data->values[_NL_ITEM_INDEX(N_CS_PRECEDES)].word; 00345 } 00346 int _Locale_n_sep_by_space(struct _Locale_monetary* lmon) { 00347 return lmon->gcc_data->values[_NL_ITEM_INDEX(N_SEP_BY_SPACE)].word; 00348 } 00349 int _Locale_n_sign_posn(struct _Locale_monetary* lmon) { 00350 return lmon->gcc_data->values[_NL_ITEM_INDEX(N_SIGN_POSN)].word; 00351 } 00352 00353 /****** Time Category ******/ 00354 00355 void* _Locale_time_create(const char * name, struct _Locale_name_hint* hint) { 00356 L_time_t* ltime = (L_time_t*)malloc(sizeof(L_time_t)); 00357 ltime->gcc_data = _Category_create(name, LC_TIME); 00358 return ltime; 00359 } 00360 00361 char const* _Locale_time_name(const void* ltime, 00362 char* buf) { 00363 return _Locale_name(((struct _Locale_time*)ltime)->gcc_data, buf); 00364 } 00365 char const* _Locale_extract_time_name(const char* cname, char* buf, struct _Locale_name_hint* hint) { 00366 return _Locale_extract_name(cname, buf, LC_TIME); 00367 } 00368 void _Locale_time_destroy(void* ltime) { 00369 _Remove_locale(LC_TIME, (struct locale_data *)((struct _Locale_time*)ltime)->gcc_data); 00370 free(ltime); 00371 } 00372 const char * _Locale_full_monthname(struct _Locale_time *ltime, int month) { 00373 const char **names = (const char **)&(ltime->gcc_data->values[_NL_ITEM_INDEX(MON_1)]); 00374 return names[month]; 00375 } 00376 const char * _Locale_abbrev_monthname(struct _Locale_time *ltime, int month) { 00377 const char **names = (const char **)&(ltime->gcc_data->values[_NL_ITEM_INDEX(ABMON_1)]); 00378 return names[month]; 00379 } 00380 const char * _Locale_full_dayofweek(struct _Locale_time *ltime, int day) { 00381 const char **names = (const char **)&(ltime->gcc_data->values[_NL_ITEM_INDEX(DAY_1)]); 00382 return names[day]; 00383 } 00384 const char * _Locale_abbrev_dayofweek(struct _Locale_time *ltime, int day) { 00385 const char **names = (const char **)&(ltime->gcc_data->values[_NL_ITEM_INDEX(ABDAY_1)]); 00386 return names[day]; 00387 } 00388 const char* _Locale_d_t_fmt(struct _Locale_time* ltime) { 00389 return ltime->gcc_data->values[_NL_ITEM_INDEX(D_T_FMT)].string; 00390 } 00391 const char* _Locale_long_d_t_fmt(struct _Locale_time* ltime) { 00392 return ltime->gcc_data->values[_NL_ITEM_INDEX(D_T_FMT)].string; 00393 } 00394 const char* _Locale_d_fmt(struct _Locale_time* ltime) 00395 { 00396 return ltime->gcc_data->values[_NL_ITEM_INDEX(D_FMT)].string; 00397 } 00398 const char* _Locale_long_d_fmt(struct _Locale_time* ltime) 00399 { 00400 return ltime->gcc_data->values[_NL_ITEM_INDEX(D_FMT)].string; 00401 } 00402 const char* _Locale_t_fmt(struct _Locale_time* ltime) { 00403 return ltime->gcc_data->values[_NL_ITEM_INDEX(T_FMT)].string; 00404 } 00405 const char* _Locale_am_str(struct _Locale_time* ltime) { 00406 return ltime->gcc_data->values[_NL_ITEM_INDEX(AM_STR)].string; 00407 } 00408 const char* _Locale_pm_str(struct _Locale_time* ltime) { 00409 return ltime->gcc_data->values[_NL_ITEM_INDEX(PM_STR)].string; 00410 } 00411 const char* _Locale_t_fmt_ampm(struct _Locale_time* ltime) 00412 { 00413 return ltime->gcc_data->values[_NL_ITEM_INDEX(T_FMT_AMPM)].string; 00414 } 00415 00416 00417 /****** Messages Category ******/ 00418 00419 void* _Locale_messages_create(const char * name, struct _Locale_name_hint* hint) { 00420 L_messages_t* lmsg = (L_messages_t*)malloc(sizeof(L_messages_t)); 00421 lmsg->gcc_data = _Category_create(name, LC_MESSAGES); 00422 return lmsg; 00423 } 00424 00425 char const* _Locale_messages_name(const void* lmsg, char* buf) { 00426 return _Locale_name(((struct _Locale_messages*)lmsg)->gcc_data, buf); 00427 } 00428 00429 void _Locale_messages_destroy(void* lmsg) { 00430 _Remove_locale(LC_MESSAGES, (struct locale_data *)((struct _Locale_messages*)lmsg)->gcc_data); 00431 free(lmsg); 00432 } 00433 00434 char const* _Locale_extract_messages_name(const char* cname, char* buf, struct _Locale_name_hint* hint) { 00435 return _Locale_extract_name(cname, buf, LC_MESSAGES); 00436 } 00437 00438 00439 /* 00440 Could not find support for locale specific messages in glibc 00441 00442 Also, this C locale interface should use a typedef for the catalog 00443 instead of just an int. Currently I'm casting a void* (nl_catd) 00444 back and forth to and int. 00445 00446 -JGS 00447 */ 00448 00449 int _Locale_catopen(struct _Locale_messages*l, const char* cat_name) { 00450 return (int)catopen(cat_name, 0); /* JGS, don't know about the flag */ 00451 } 00452 void _Locale_catclose(struct _Locale_messages*l, int catalog) { 00453 catclose((nl_catd)catalog); 00454 } 00455 const char* _Locale_catgets(struct _Locale_messages*l, int catalog, 00456 int set_num, int msg_num, 00457 const char *dfault){ 00458 return catgets((nl_catd)catalog, set_num, msg_num, dfault); 00459 } 00460 00461 00462 /****** ctype Category ******/ 00463 00464 00465 /* 00466 gcc uses a different set of masks for wide characters than for 00467 normal characters. However, the C++ standard requires there 00468 to be only one set of masks for both. Therefore we must 00469 translate the mask values from the wide characters to the 00470 mask values for the normal characters. -JGS 00471 */ 00472 static _Locale_mask_t _Map_wchar_mask_to_char_mask(wctype_t m) { 00473 _Locale_mask_t ret = 0; 00474 if (m & _ISwcntrl) ret |= _Locale_CNTRL; 00475 if (m & _ISwupper) ret |= _Locale_UPPER; 00476 if (m & _ISwlower) ret |= _Locale_LOWER; 00477 if (m & _ISwdigit) ret |= _Locale_DIGIT; 00478 if (m & _ISwxdigit) ret |= _Locale_XDIGIT; 00479 if (m & _ISwpunct) ret |= _Locale_PUNCT; 00480 if (m & _ISwspace) ret |= _Locale_SPACE; 00481 if (m & _ISwprint) ret |= _Locale_PRINT; 00482 if (m & _ISwalpha) ret |= _Locale_ALPHA; 00483 return ret; 00484 } 00485 00486 00487 void* _Locale_ctype_create(const char * name, struct _Locale_name_hint* hint) { 00488 const union locale_data_value *ctypes; 00489 L_ctype_t* lctype; 00490 00491 lctype = (L_ctype_t*)malloc(sizeof(L_ctype_t)); 00492 lctype->gcc_data = _Category_create(name, LC_CTYPE); 00493 ctypes = lctype->gcc_data->values; 00494 00495 lctype->__class = (_Locale_mask_t *) 00496 (ctypes[_NL_ITEM_INDEX (_NL_CTYPE_CLASS)] .string) + 128; 00497 #ifdef _STLP_GLIBC_LOCALE_2 00498 lctype->__tolower = (const int *) 00499 (ctypes[_NL_ITEM_INDEX (_NL_CTYPE_TOLOWER)].string) + 128; 00500 lctype->__toupper = (const int *) 00501 (ctypes[_NL_ITEM_INDEX (_NL_CTYPE_TOUPPER)].string) + 128; 00502 #else 00503 # if BYTE_ORDER == BIG_ENDIAN 00504 lctype->__tolower = (const int *) 00505 (ctypes[_NL_ITEM_INDEX (_NL_CTYPE_TOLOWER_EB)].string) + 128; 00506 lctype->__toupper = (const int *) 00507 (ctypes[_NL_ITEM_INDEX (_NL_CTYPE_TOUPPER_EB)].string) + 128; 00508 # elif BYTE_ORDER == LITTLE_ENDIAN 00509 lctype->__tolower = (const int *) 00510 (ctypes[_NL_ITEM_INDEX (_NL_CTYPE_TOLOWER_EL)].string) + 128; 00511 lctype->__toupper = (const int *) 00512 (ctypes[_NL_ITEM_INDEX (_NL_CTYPE_TOUPPER_EL)].string) + 128; 00513 # else 00514 # error bizarre byte order 00515 # endif 00516 #endif /* _STLP_GLIBC_LOCALE_2 */ 00517 return lctype; 00518 } 00519 char const* _Locale_ctype_name(const void* lctype, 00520 char* buf) { 00521 return _Locale_name(((struct _Locale_ctype*)lctype)->gcc_data, buf); 00522 } 00523 void _Locale_ctype_destroy(void* lctype) { 00524 _Remove_locale(LC_CTYPE, (struct locale_data *)((struct _Locale_ctype*)lctype)->gcc_data); 00525 free(lctype); 00526 } 00527 char const* _Locale_extract_ctype_name(const char* cname, char* buf, struct _Locale_name_hint* hint) { 00528 return _Locale_extract_name(cname, buf, LC_CTYPE); 00529 } 00530 const _Locale_mask_t* _Locale_ctype_table(struct _Locale_ctype* lctype) { 00531 return lctype->__class; 00532 } 00533 int _Locale_toupper(struct _Locale_ctype* lctype, int c) { 00534 return lctype->__toupper[c]; 00535 } 00536 int _Locale_tolower(struct _Locale_ctype* lctype, int c) { 00537 return lctype->__tolower[c]; 00538 } 00539 00540 /* Wide Character Functions */ 00541 00542 static inline size_t 00543 cname_lookup (wint_t wc, const struct locale_data* loc) 00544 { 00545 #ifdef _STLP_GLIBC_LOCALE_2 00546 printf( "******** Fix me: %s:%d", __FILE__, __LINE__ ); 00547 return ~((size_t) 0); 00548 #else 00549 unsigned int *__nl_ctype_names; 00550 unsigned int hash_size, hash_layers; 00551 size_t result, cnt; 00552 00553 # if BYTE_ORDER == BIG_ENDIAN 00554 __nl_ctype_names = (unsigned int*)loc->values[_NL_ITEM_INDEX(_NL_CTYPE_NAMES_EB)].string; 00555 # elif BYTE_ORDER == LITTLE_ENDIAN 00556 __nl_ctype_names = (unsigned int*)loc->values[_NL_ITEM_INDEX(_NL_CTYPE_NAMES_EL)].string; 00557 # else 00558 # error bizarre byte order 00559 # endif 00560 00561 hash_size = loc->values[_NL_ITEM_INDEX(_NL_CTYPE_HASH_SIZE)].word; 00562 hash_layers = loc->values[_NL_ITEM_INDEX(_NL_CTYPE_HASH_LAYERS)].word; 00563 00564 result = wc % hash_size; 00565 for (cnt = 0; cnt < hash_layers; ++cnt) { 00566 if (__nl_ctype_names[result] == wc) 00567 break; 00568 result += hash_size; 00569 } 00570 return cnt < hash_layers ? result : ~((size_t) 0); 00571 #endif 00572 } 00573 00574 00575 00576 00577 _Locale_mask_t _Locale_wchar_ctype(struct _Locale_ctype* loc, wint_t wc, 00578 _Locale_mask_t which_bits) { 00579 const struct locale_data* locale = loc->gcc_data; 00580 const unsigned int *class32_b; 00581 size_t idx; 00582 00583 idx = cname_lookup (wc, locale); 00584 if (idx == ~((size_t) 0)) 00585 return 0; 00586 00587 class32_b = (u_int32_t *) 00588 locale->values[_NL_ITEM_INDEX (_NL_CTYPE_CLASS32)].string; 00589 00590 return _Map_wchar_mask_to_char_mask( class32_b[idx] ) & which_bits; 00591 } 00592 00593 00594 00595 wint_t 00596 __towctrans_ld (wint_t wc, wctrans_t desc, const struct locale_data* locale) 00597 { 00598 size_t idx; 00599 00600 idx = cname_lookup (wc, locale); 00601 if (idx == ~((size_t) 0)) 00602 /* Character is not known. Default action is to simply return it. */ 00603 return wc; 00604 00605 return (wint_t) desc[idx]; 00606 } 00607 00608 wint_t _Locale_wchar_tolower(struct _Locale_ctype* locale, wint_t wc) { 00609 return __towctrans_ld (wc, (const unsigned int *)locale->__tolower, locale->gcc_data); 00610 } 00611 wint_t _Locale_wchar_toupper(struct _Locale_ctype* locale, wint_t wc) { 00612 return __towctrans_ld (wc, (const unsigned int *)locale->__toupper, locale->gcc_data); 00613 } 00614 00615 00616 int _Locale_mb_cur_max (struct _Locale_ctype *lctype) { 00617 return lctype->gcc_data->values[_NL_ITEM_INDEX(_NL_CTYPE_MB_CUR_MAX)].word; 00618 } 00619 00620 int _Locale_mb_cur_min (struct _Locale_ctype *l) { 00621 return 1; /* JGS just a guess */ 00622 } 00623 00624 int _Locale_is_stateless (struct _Locale_ctype *l) { return 1; } 00625 00626 wint_t _Locale_btowc(struct _Locale_ctype *l, int c) { 00627 return btowc(c); 00628 } 00629 00630 /* 00631 glibc currently doesn't support locale dependent conversion, 00632 which affects the following functions. When it does, then 00633 these functions will need to change. Hopeully, the 00634 just the calls to the glibc functions will need to be 00635 replaced. 00636 -JGS 00637 */ 00638 00639 int _Locale_wctob(struct _Locale_ctype *l, wint_t c) { 00640 return wctob(c); 00641 } 00642 00643 size_t _Locale_mbtowc(struct _Locale_ctype *l, 00644 wchar_t *to, 00645 const char *from, size_t n, 00646 mbstate_t *shift_state) 00647 { 00648 int ret; 00649 if (to) 00650 ret = mbrtowc(to, from, n, shift_state); 00651 else 00652 ret = mbrlen(from, n, shift_state); 00653 return ret; 00654 } 00655 00656 size_t _Locale_wctomb(struct _Locale_ctype *l, 00657 char *to, size_t n, 00658 const wchar_t c, 00659 mbstate_t *shift_state) 00660 { 00661 char buf [MB_LEN_MAX]; 00662 int ret; 00663 char* mb = buf; 00664 ret = wcrtomb(mb, c, shift_state); 00665 00666 if (ret > n) 00667 return (size_t)-2; 00668 else if (ret <= 0) 00669 return ret; 00670 00671 n = ret; 00672 while (n--) 00673 *to++ = *mb++; 00674 00675 return ret; 00676 } 00677 00678 size_t _Locale_unshift(struct _Locale_ctype *l, 00679 mbstate_t * st, 00680 char *buf, size_t n, char **next) { 00681 *next = buf; /* JGS stateless, so don't need to do anything? */ 00682 return 0; 00683 } 00684 00685 00686 /****** Collate Category ******/ 00687 00688 void* _Locale_collate_create(const char * name, struct _Locale_name_hint* hint) { 00689 L_collate_t* lcollate = (L_collate_t*)malloc(sizeof(L_collate_t)); 00690 lcollate->gcc_data = _Category_create(name, LC_COLLATE); 00691 return lcollate; 00692 } 00693 00694 char const* _Locale_collate_name(const void* lcollate, char* buf) { 00695 return _Locale_name(((struct _Locale_collate*)lcollate)->gcc_data, buf); 00696 } 00697 00698 void _Locale_collate_destroy(void* lcollate) { 00699 _Remove_locale(LC_COLLATE, (struct locale_data *)((struct _Locale_collate*)lcollate)->gcc_data); 00700 free(lcollate); 00701 } 00702 00703 char const* _Locale_extract_collate_name(const char* cname, char* buf, struct _Locale_name_hint* hint) { 00704 return _Locale_extract_name(cname, buf, LC_COLLATE); 00705 } 00706 00707 /* copied from the IRIX version -JGS */ 00708 char const* _Locale_compose_name(char* buf, 00709 const char* ctype, const char* numeric, 00710 const char* time, const char* collate, 00711 const char* monetary, const char* messages, 00712 const char *default_name) 00713 { 00714 (void) default_name; 00715 00716 if ( !strcmp ( ctype, numeric ) && 00717 !strcmp ( ctype, time ) && 00718 !strcmp ( ctype, collate ) && 00719 !strcmp ( ctype, monetary ) && 00720 !strcmp ( ctype, messages ) ) 00721 return strcpy ( buf, ctype ); 00722 00723 strcpy ( buf, "/" ); 00724 strcat ( buf, ctype ); 00725 00726 strcat ( buf, "/" ); 00727 strcat ( buf, numeric ); 00728 00729 strcat ( buf, "/" ); 00730 strcat ( buf, time ); 00731 00732 strcat ( buf, "/" ); 00733 strcat ( buf, collate ); 00734 00735 strcat ( buf, "/" ); 00736 strcat ( buf, monetary ); 00737 00738 strcat ( buf, "/" ); 00739 strcat ( buf, messages ); 00740 00741 return buf; 00742 } 00743 00744 00745 00746 /* 00747 glibc doesn't have a locale specific strcmp 00748 This doesn't ignore null chars the way it should 00749 */ 00750 int 00751 _Locale_strcmp(struct _Locale_collate * l, 00752 const char *s1, size_t n1, 00753 const char *s2, size_t n2) 00754 { 00755 int ret; 00756 int minN = n1 < n2 ? n1 : n2; 00757 ret = strncmp(s1, s2, minN); 00758 if (ret == 0) { 00759 if (n1 < n2) return -1; 00760 else if (n1 > n2) return 1; 00761 else return 0; 00762 } else 00763 return ret; 00764 } 00765 00766 00767 int _Locale_strwcmp(struct _Locale_collate*l, 00768 const wchar_t*s1, size_t n1, 00769 const wchar_t*s2, size_t n2) 00770 { 00771 int ret; 00772 int minN = n1 < n2 ? n1 : n2; 00773 ret = wcsncmp(s1, s2, minN); 00774 if (ret == 0) { 00775 if (n1 < n2) return -1; 00776 else if (n1 > n2) return 1; 00777 else return 0; 00778 } else 00779 return ret; 00780 } 00781 size_t _Locale_strxfrm(struct _Locale_collate *lcollate, 00782 char *dest, size_t dest_n, 00783 const char *src, size_t src_n ) 00784 { 00785 if (src_n == 0) 00786 { 00787 if (dest != NULL) dest[0] = 0; 00788 return 0; 00789 } 00790 const char *real_src; 00791 char *buf = NULL; 00792 if (src[src_n] != 0) { 00793 buf = malloc(src_n + 1); 00794 strncpy(buf, src, src_n); 00795 buf[src_n] = 0; 00796 real_src = buf; 00797 } 00798 else 00799 real_src = src; 00800 size_t result = strxfrm(dest, real_src, dest_n); 00801 if (buf != NULL) free(buf); 00802 return result; 00803 } 00804 00805 # ifndef _STLP_NO_WCHAR_T 00806 00807 size_t _Locale_strwxfrm(struct _Locale_collate *lcollate, 00808 wchar_t *dest, size_t dest_n, 00809 const wchar_t *src, size_t src_n) 00810 { 00811 if (src_n == 0) 00812 { 00813 if (dest != NULL) dest[0] = 0; 00814 return 0; 00815 } 00816 const wchar_t *real_src; 00817 wchar_t *buf = NULL; 00818 if (src[src_n] != 0) { 00819 buf = malloc((src_n + 1) * sizeof(wchar_t)); 00820 wcsncpy(buf, src, src_n); 00821 buf[src_n] = 0; 00822 real_src = buf; 00823 } 00824 else 00825 real_src = src; 00826 size_t result = wcsxfrm(dest, real_src, dest_n, (__c_locale)__loc); 00827 if (buf != NULL) free(buf); 00828 return result; 00829 } 00830 00831 #endif
Generated on Mon Mar 10 15:32:15 2008 by ![]() |