/home/ntakagi/work/STLport-5.1.5/src/c_locale_glibc/c_locale_glibc.c

Go 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  doxygen 1.5.1