c_locale_glibc.c

来自「symbian 上的stl_port进过编译的。」· C语言 代码 · 共 832 行 · 第 1/2 页

C
832
字号
/****** Messages Category ******/void* _Locale_messages_create(const char * name, struct _Locale_name_hint* hint) {  L_messages_t*  lmsg = (L_messages_t*)malloc(sizeof(L_messages_t));  lmsg->gcc_data = _Category_create(name, LC_MESSAGES);  return lmsg;}char const* _Locale_messages_name(const void* lmsg, char* buf) {  return _Locale_name(((struct _Locale_messages*)lmsg)->gcc_data, buf);}void _Locale_messages_destroy(void* lmsg) {  _Remove_locale(LC_MESSAGES, (struct locale_data *)((struct _Locale_messages*)lmsg)->gcc_data);  free(lmsg);}char const* _Locale_extract_messages_name(const char* cname, char* buf, struct _Locale_name_hint* hint) {  return _Locale_extract_name(cname, buf, LC_MESSAGES);}/*  Could not find support for locale specific messages in glibc  Also, this C locale interface should use a typedef for the catalog  instead of just an int. Currently I'm casting a void* (nl_catd)  back and forth to and int.  -JGS */int _Locale_catopen(struct _Locale_messages*l, const char* cat_name) {  return (int)catopen(cat_name, 0); /*  JGS, don't know about the flag */}void _Locale_catclose(struct _Locale_messages*l, int catalog) {  catclose((nl_catd)catalog);}const char* _Locale_catgets(struct _Locale_messages*l, int catalog,                                       int set_num, int msg_num,                                       const char *dfault){  return catgets((nl_catd)catalog, set_num, msg_num, dfault);}/****** ctype Category ******//*  gcc uses a different set of masks for wide characters than for  normal characters. However, the C++ standard requires there  to be only one set of masks for both. Therefore we must  translate the mask values from the wide characters to the  mask values for the normal characters.  -JGS */static _Locale_mask_t _Map_wchar_mask_to_char_mask(wctype_t m) {  _Locale_mask_t ret = 0;  if (m & _ISwcntrl)  ret |= _Locale_CNTRL;  if (m & _ISwupper)  ret |= _Locale_UPPER;  if (m & _ISwlower)  ret |= _Locale_LOWER;  if (m & _ISwdigit)  ret |= _Locale_DIGIT;  if (m & _ISwxdigit) ret |= _Locale_XDIGIT;  if (m & _ISwpunct)  ret |= _Locale_PUNCT;  if (m & _ISwspace)  ret |= _Locale_SPACE;  if (m & _ISwprint)  ret |= _Locale_PRINT;  if (m & _ISwalpha)  ret |= _Locale_ALPHA;  return ret;}void* _Locale_ctype_create(const char * name, struct _Locale_name_hint* hint) {  const union locale_data_value *ctypes;  L_ctype_t* lctype;  lctype = (L_ctype_t*)malloc(sizeof(L_ctype_t));  lctype->gcc_data = _Category_create(name, LC_CTYPE);  ctypes = lctype->gcc_data->values;  lctype->__class = (_Locale_mask_t *)    (ctypes[_NL_ITEM_INDEX (_NL_CTYPE_CLASS)] .string) + 128;#ifdef _STLP_GLIBC_LOCALE_2  lctype->__tolower = (const int *)    (ctypes[_NL_ITEM_INDEX (_NL_CTYPE_TOLOWER)].string) + 128;  lctype->__toupper = (const int *)    (ctypes[_NL_ITEM_INDEX (_NL_CTYPE_TOUPPER)].string) + 128;#else# if BYTE_ORDER == BIG_ENDIAN  lctype->__tolower = (const int *)    (ctypes[_NL_ITEM_INDEX (_NL_CTYPE_TOLOWER_EB)].string) + 128;  lctype->__toupper = (const int *)    (ctypes[_NL_ITEM_INDEX (_NL_CTYPE_TOUPPER_EB)].string) + 128;# elif BYTE_ORDER == LITTLE_ENDIAN  lctype->__tolower = (const int *)    (ctypes[_NL_ITEM_INDEX (_NL_CTYPE_TOLOWER_EL)].string) + 128;  lctype->__toupper = (const int *)    (ctypes[_NL_ITEM_INDEX (_NL_CTYPE_TOUPPER_EL)].string) + 128;# else#  error bizarre byte order# endif#endif /* _STLP_GLIBC_LOCALE_2 */  return lctype;}char const* _Locale_ctype_name(const void* lctype,       char* buf) {  return _Locale_name(((struct _Locale_ctype*)lctype)->gcc_data, buf);}void _Locale_ctype_destroy(void* lctype) {  _Remove_locale(LC_CTYPE, (struct locale_data *)((struct _Locale_ctype*)lctype)->gcc_data);  free(lctype);}char const* _Locale_extract_ctype_name(const char* cname, char* buf, struct _Locale_name_hint* hint) {  return _Locale_extract_name(cname, buf, LC_CTYPE);}const _Locale_mask_t* _Locale_ctype_table(struct _Locale_ctype* lctype) {  return lctype->__class;}int _Locale_toupper(struct _Locale_ctype* lctype, int c) {  return lctype->__toupper[c];}int _Locale_tolower(struct _Locale_ctype* lctype, int c) {  return lctype->__tolower[c];}/* Wide Character Functions */static inline size_tcname_lookup (wint_t wc, const struct locale_data* loc){#ifdef _STLP_GLIBC_LOCALE_2  printf( "******** Fix me: %s:%d", __FILE__, __LINE__ );  return ~((size_t) 0);#else  unsigned int *__nl_ctype_names;  unsigned int hash_size, hash_layers;  size_t result, cnt;# if BYTE_ORDER == BIG_ENDIAN  __nl_ctype_names = (unsigned int*)loc->values[_NL_ITEM_INDEX(_NL_CTYPE_NAMES_EB)].string;# elif BYTE_ORDER == LITTLE_ENDIAN  __nl_ctype_names = (unsigned int*)loc->values[_NL_ITEM_INDEX(_NL_CTYPE_NAMES_EL)].string;# else#  error bizarre byte order# endif  hash_size = loc->values[_NL_ITEM_INDEX(_NL_CTYPE_HASH_SIZE)].word;  hash_layers = loc->values[_NL_ITEM_INDEX(_NL_CTYPE_HASH_LAYERS)].word;  result = wc % hash_size;  for (cnt = 0; cnt < hash_layers; ++cnt) {    if (__nl_ctype_names[result] == wc)      break;    result += hash_size;  }  return cnt < hash_layers ? result : ~((size_t) 0);#endif}_Locale_mask_t _Locale_wchar_ctype(struct _Locale_ctype* loc, wint_t wc,  _Locale_mask_t which_bits) {  const struct locale_data* locale = loc->gcc_data;  const unsigned int *class32_b;  size_t idx;  idx = cname_lookup (wc, locale);  if (idx == ~((size_t) 0))    return 0;  class32_b = (u_int32_t *)    locale->values[_NL_ITEM_INDEX (_NL_CTYPE_CLASS32)].string;  return _Map_wchar_mask_to_char_mask( class32_b[idx] ) & which_bits;}wint_t__towctrans_ld (wint_t wc, wctrans_t desc, const struct locale_data* locale){  size_t idx;  idx = cname_lookup (wc, locale);  if (idx == ~((size_t) 0))    /* Character is not known.  Default action is to simply return it.  */    return wc;  return (wint_t) desc[idx];}wint_t _Locale_wchar_tolower(struct _Locale_ctype* locale, wint_t wc) {  return __towctrans_ld (wc, (const unsigned int *)locale->__tolower, locale->gcc_data);}wint_t _Locale_wchar_toupper(struct _Locale_ctype* locale, wint_t wc) {  return __towctrans_ld (wc, (const unsigned int *)locale->__toupper, locale->gcc_data);}int _Locale_mb_cur_max (struct _Locale_ctype *lctype) {  return lctype->gcc_data->values[_NL_ITEM_INDEX(_NL_CTYPE_MB_CUR_MAX)].word;}int _Locale_mb_cur_min (struct _Locale_ctype *l) {  return 1;  /* JGS just a guess */}int _Locale_is_stateless (struct _Locale_ctype *l) { return 1; }wint_t _Locale_btowc(struct _Locale_ctype *l, int c) {  return btowc(c);}/*  glibc currently doesn't support locale dependent conversion,  which affects the following functions. When it does, then  these functions will need to change. Hopeully, the  just the calls to the glibc functions will need to be  replaced.  -JGS */int _Locale_wctob(struct _Locale_ctype *l, wint_t c) {  return wctob(c);}size_t _Locale_mbtowc(struct _Locale_ctype *l,                                 wchar_t *to,                                 const char *from, size_t n,                                 mbstate_t *shift_state){  int ret;  if (to)    ret = mbrtowc(to, from, n, shift_state);  else    ret = mbrlen(from, n, shift_state);  return ret;}size_t _Locale_wctomb(struct _Locale_ctype *l,          char *to, size_t n,          const wchar_t c,          mbstate_t *shift_state){  char buf [MB_LEN_MAX];  int ret;  char* mb = buf;  ret = wcrtomb(mb, c, shift_state);  if (ret > n)    return (size_t)-2;  else if (ret <= 0)    return ret;  n = ret;  while (n--)    *to++ = *mb++;  return ret;}size_t _Locale_unshift(struct _Locale_ctype *l,           mbstate_t * st,           char *buf, size_t n, char **next) {  *next = buf; /* JGS stateless, so don't need to do anything? */  return 0;}/****** Collate Category ******/void* _Locale_collate_create(const char * name, struct _Locale_name_hint* hint) {  L_collate_t*  lcollate = (L_collate_t*)malloc(sizeof(L_collate_t));  lcollate->gcc_data = _Category_create(name, LC_COLLATE);  return lcollate;}char const* _Locale_collate_name(const void* lcollate, char* buf) {  return _Locale_name(((struct _Locale_collate*)lcollate)->gcc_data, buf);}void _Locale_collate_destroy(void* lcollate) {  _Remove_locale(LC_COLLATE, (struct locale_data *)((struct _Locale_collate*)lcollate)->gcc_data);  free(lcollate);}char const* _Locale_extract_collate_name(const char* cname, char* buf, struct _Locale_name_hint* hint) {  return _Locale_extract_name(cname, buf, LC_COLLATE);}/* copied from the IRIX version -JGS */char const* _Locale_compose_name(char* buf,         const char* ctype, const char* numeric,         const char* time, const char* collate,         const char* monetary, const char* messages,         const char *default_name){   (void) default_name;    if ( !strcmp ( ctype, numeric ) &&   !strcmp ( ctype, time ) &&   !strcmp ( ctype, collate ) &&   !strcmp ( ctype, monetary ) &&   !strcmp ( ctype, messages ) )  return strcpy ( buf, ctype );    strcpy ( buf, "/" );    strcat ( buf, ctype );    strcat ( buf, "/" );    strcat ( buf, numeric );    strcat ( buf, "/" );    strcat ( buf, time );    strcat ( buf, "/" );    strcat ( buf, collate );    strcat ( buf, "/" );    strcat ( buf, monetary );    strcat ( buf, "/" );    strcat ( buf, messages );    return buf;}/*  glibc doesn't have a locale specific strcmp  This doesn't ignore null chars the way it should */int_Locale_strcmp(struct _Locale_collate * l,         const char *s1, size_t n1,         const char *s2, size_t n2){  int ret;  int minN = n1 < n2 ? n1 : n2;  ret = strncmp(s1, s2, minN);  if (ret == 0) {    if (n1 < n2) return -1;    else if (n1 > n2) return 1;    else return 0;  } else    return ret;}int _Locale_strwcmp(struct _Locale_collate*l,        const wchar_t*s1, size_t n1,        const wchar_t*s2, size_t n2){  int ret;  int minN = n1 < n2 ? n1 : n2;  ret = wcsncmp(s1, s2, minN);  if (ret == 0) {    if (n1 < n2) return -1;    else if (n1 > n2) return 1;    else return 0;  } else    return ret;}size_t _Locale_strxfrm(struct _Locale_collate *lcollate,                       char *dest, size_t dest_n,                       const char *src, size_t src_n ){  if (src_n == 0)  {    if (dest != NULL) dest[0] = 0;    return 0;  }  const char *real_src;  char *buf = NULL;  if (src[src_n] != 0) {    buf = malloc(src_n + 1);    strncpy(buf, src, src_n);    buf[src_n] = 0;    real_src = buf;  }  else    real_src = src;  size_t result = strxfrm(dest, real_src, dest_n);  if (buf != NULL) free(buf);  return result;}# ifndef _STLP_NO_WCHAR_Tsize_t _Locale_strwxfrm(struct _Locale_collate *lcollate,                        wchar_t *dest, size_t dest_n,                        const wchar_t *src, size_t src_n){  if (src_n == 0)  {    if (dest != NULL) dest[0] = 0;    return 0;  }  const wchar_t *real_src;  wchar_t *buf = NULL;  if (src[src_n] != 0) {    buf = malloc((src_n + 1) * sizeof(wchar_t));    wcsncpy(buf, src, src_n);    buf[src_n] = 0;    real_src = buf;  }  else    real_src = src;  size_t result = wcsxfrm(dest, real_src, dest_n, (__c_locale)__loc);  if (buf != NULL) free(buf);  return result;}#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?