wint_t ungetwc_l(wint_t wc, FILE *fp, locale_t loc) { wint_t r; NORMALIZE_LOCALE(loc); FLOCKFILE(fp); ORIENT(fp, 1); r = __ungetwc(wc, fp, loc); FUNLOCKFILE(fp); return (r); }
int mblen_l(const char *s, size_t n, locale_t loc) { static const mbstate_t initial; size_t rval; NORMALIZE_LOCALE(loc); if (s == NULL) { /* No support for state dependent encodings. */ loc->__mbs_mblen = initial; return (0); } rval = loc->__lc_ctype->__mbrtowc(NULL, s, n, &loc->__mbs_mblen, loc); if (rval == (size_t)-1 || rval == (size_t)-2) return (-1); return ((int)rval); }
wint_t towctrans_l(wint_t wc, wctrans_t desc, locale_t loc) { NORMALIZE_LOCALE(loc); switch (desc) { case _WCT_TOLOWER: wc = towlower_l(wc, loc); break; case _WCT_TOUPPER: wc = towupper_l(wc, loc); break; case _WCT_ERROR: default: errno = EINVAL; break; } return (wc); }
int strcoll_l(const char *s, const char *s2, locale_t loc) { int ret; const wchar_t *t = NULL, *t2 = NULL; int sverrno; NORMALIZE_LOCALE(loc); if (loc->__collate_load_error || (t = __collate_mbstowcs(s, loc)) == NULL || (t2 = __collate_mbstowcs(s2, loc)) == NULL) { sverrno = errno; free((void *)t); free((void *)t2); errno = sverrno; return strcmp(s, s2); } ret = wcscoll_l(t, t2, loc); sverrno = errno; free((void *)t); free((void *)t2); errno = sverrno; return ret; }
int wcscoll_l(const wchar_t *ws1, const wchar_t *ws2, locale_t loc) { int sverrno; int len, len2, prim, prim2, sec, sec2, ret, ret2; const wchar_t *t, *t2; wchar_t *tt = NULL, *tt2 = NULL; wchar_t *tr = NULL, *tr2 = NULL; wchar_t w, w2; struct __collate_st_info *info; NORMALIZE_LOCALE(loc); if (loc->__collate_load_error) /* * Locale has no special collating order or could not be * loaded, do a fast binary comparison. */ return (wcscmp(ws1, ws2)); info = &loc->__lc_collate->__info; len = len2 = 1; ret = ret2 = 0; if ((info->directive[0] & NOTFORWARD) || (info->directive[1] & NOTFORWARD) || (!(info->flags && COLLATE_SUBST_DUP) && (info->subst_count[0] > 0 || info->subst_count[1] > 0))) { int direc, pass; for(pass = 0; pass < info->directive_count; pass++) { direc = info->directive[pass]; if (pass == 0 || !(info->flags & COLLATE_SUBST_DUP)) { free(tt); tt = __collate_substitute(ws1, pass, loc); free(tt2); tt2 = tt ? __collate_substitute(ws2, pass, loc) : NULL; } if (direc & DIRECTIVE_BACKWARD) { wchar_t *bp, *fp, c; tr = __collate_wcsdup(tt ? tt : ws1); bp = tr; fp = tr + wcslen(tr) - 1; while(bp < fp) { c = *bp; *bp++ = *fp; *fp-- = c; } tr2 = __collate_wcsdup(tt2 ? tt2 : ws2); bp = tr2; fp = tr2 + wcslen(tr2) - 1; while(bp < fp) { c = *bp; *bp++ = *fp; *fp-- = c; } t = (const wchar_t *)tr; t2 = (const wchar_t *)tr2; } else if (tt) { t = (const wchar_t *)tt; t2 = (const wchar_t *)tt2; } else { t = (const wchar_t *)ws1; t2 = (const wchar_t *)ws2; } if(direc & DIRECTIVE_POSITION) { while(*t && *t2) { prim = prim2 = 0; __collate_lookup_which(t, &len, &prim, pass, loc); if (prim <= 0) { if (prim < 0) { errno = EINVAL; ret = -1; goto end; } prim = COLLATE_MAX_PRIORITY; } __collate_lookup_which(t2, &len2, &prim2, pass, loc); if (prim2 <= 0) { if (prim2 < 0) { errno = EINVAL; ret = -1; goto end; } prim2 = COLLATE_MAX_PRIORITY; } if(prim != prim2) { ret = prim - prim2; goto end; } t += len; t2 += len2; } } else { while(*t && *t2) { prim = prim2 = 0; while(*t) { __collate_lookup_which(t, &len, &prim, pass, loc); if(prim > 0) break; if (prim < 0) { errno = EINVAL; ret = -1; goto end; } t += len; } while(*t2) { __collate_lookup_which(t2, &len2, &prim2, pass, loc); if(prim2 > 0) break; if (prim2 < 0) { errno = EINVAL; ret = -1; goto end; } t2 += len2; } if(!prim || !prim2) break; if(prim != prim2) { ret = prim - prim2; goto end; } t += len; t2 += len2; } } if(!*t) { if(*t2) { ret = -(int)*t2; goto end; } } else { ret = *t; goto end; } } ret = 0; goto end; } /* optimized common case: order_start forward;forward and duplicate * (or no) substitute tables */ tt = __collate_substitute(ws1, 0, loc); if (tt == NULL) { tt2 = NULL; t = (const wchar_t *)ws1; t2 = (const wchar_t *)ws2; } else { tt2 = __collate_substitute(ws2, 0, loc); t = (const wchar_t *)tt; t2 = (const wchar_t *)tt2; } while(*t && *t2) { prim = prim2 = 0; while(*t) { __collate_lookup_l(t, &len, &prim, &sec, loc); if (prim > 0) break; if (prim < 0) { errno = EINVAL; ret = -1; goto end; } t += len; } while(*t2) { __collate_lookup_l(t2, &len2, &prim2, &sec2, loc); if (prim2 > 0) break; if (prim2 < 0) { errno = EINVAL; ret = -1; goto end; } t2 += len2; } if(!prim || !prim2) break; if(prim != prim2) { ret = prim - prim2; goto end; } if(!ret2) ret2 = sec - sec2; t += len; t2 += len2; } if(!*t && *t2) ret = -(int)*t2; else if(*t && !*t2) ret = *t; else if(!*t && !*t2) ret = ret2; end: sverrno = errno; free(tt); free(tt2); free(tr); free(tr2); errno = sverrno; return ret; }
/* * Return the current locale conversion. */ struct lconv * localeconv_l(locale_t loc) { struct lconv *lc; NORMALIZE_LOCALE(loc); if (loc->__mlocale_changed) { XL_LOCK(loc); if (loc->__mlocale_changed) { /* LC_MONETARY part */ struct lc_monetary_T * mptr; struct lconv *lc = &loc->__lc_localeconv; #define M_ASSIGN_STR(NAME) (lc->NAME = (char*)mptr->NAME) #define M_ASSIGN_CHAR(NAME) (lc->NAME = mptr->NAME[0]) mptr = __get_current_monetary_locale(loc); M_ASSIGN_STR(int_curr_symbol); M_ASSIGN_STR(currency_symbol); M_ASSIGN_STR(mon_decimal_point); M_ASSIGN_STR(mon_thousands_sep); M_ASSIGN_STR(mon_grouping); M_ASSIGN_STR(positive_sign); M_ASSIGN_STR(negative_sign); M_ASSIGN_CHAR(int_frac_digits); M_ASSIGN_CHAR(frac_digits); M_ASSIGN_CHAR(p_cs_precedes); M_ASSIGN_CHAR(p_sep_by_space); M_ASSIGN_CHAR(n_cs_precedes); M_ASSIGN_CHAR(n_sep_by_space); M_ASSIGN_CHAR(p_sign_posn); M_ASSIGN_CHAR(n_sign_posn); M_ASSIGN_CHAR(int_p_cs_precedes); M_ASSIGN_CHAR(int_n_cs_precedes); M_ASSIGN_CHAR(int_p_sep_by_space); M_ASSIGN_CHAR(int_n_sep_by_space); M_ASSIGN_CHAR(int_p_sign_posn); M_ASSIGN_CHAR(int_n_sign_posn); loc->__mlocale_changed = 0; } XL_UNLOCK(loc); } if (loc->__nlocale_changed) { XL_LOCK(loc); if (loc->__nlocale_changed) { /* LC_NUMERIC part */ struct lc_numeric_T * nptr; struct lconv *lc = &loc->__lc_localeconv; #define N_ASSIGN_STR(NAME) (lc->NAME = (char*)nptr->NAME) nptr = __get_current_numeric_locale(loc); N_ASSIGN_STR(decimal_point); N_ASSIGN_STR(thousands_sep); N_ASSIGN_STR(grouping); loc->__nlocale_changed = 0; } XL_UNLOCK(loc); } return &loc->__lc_localeconv; }