static __inline int convert_wstring(FILE *fp, wchar_t *wcp, int width, locale_t locale) { mbstate_t mbs; wint_t wi; int n, nread; mbs = initial_mbs; n = 0; if (wcp == SUPPRESS_PTR) { while ((wi = __fgetwc_mbs(fp, &mbs, &nread, locale)) != WEOF && width-- != 0 && !iswspace(wi)) n += nread; if (wi != WEOF) __ungetwc(wi, fp, __get_locale()); } else { while ((wi = __fgetwc_mbs(fp, &mbs, &nread, locale)) != WEOF && width-- != 0 && !iswspace(wi)) { *wcp++ = (wchar_t)wi; n += nread; } if (wi != WEOF) __ungetwc(wi, fp, __get_locale()); *wcp = '\0'; } return (n); }
static __inline int convert_wccl(FILE *fp, wchar_t *wcp, int width, const char *ccltab, locale_t locale) { mbstate_t mbs; wint_t wi; int n, nread; mbs = initial_mbs; n = 0; if (wcp == SUPPRESS_PTR) { while ((wi = __fgetwc_mbs(fp, &mbs, &nread, locale)) != WEOF && width-- != 0 && ccltab[wctob(wi)]) n += nread; if (wi != WEOF) __ungetwc(wi, fp, __get_locale()); } else { while ((wi = __fgetwc_mbs(fp, &mbs, &nread, locale)) != WEOF && width-- != 0 && ccltab[wctob(wi)]) { *wcp++ = (wchar_t)wi; n += nread; } if (wi != WEOF) __ungetwc(wi, fp, __get_locale()); if (n == 0) return (0); *wcp = 0; } return (n); }
locale_t __newlocale(int mask, const char* name, locale_t loc) { int i, j; struct __locale_struct tmp; const struct __locale_map* lm; /* For locales with allocated storage, modify in-place. */ if (__loc_is_allocated(loc)) { for (i = 0; i < LC_ALL; i++) if (mask & (1 << i)) loc->cat[i] = __get_locale(i, name); return loc; } /* Otherwise, build a temporary locale object, which will only * be instantiated in allocated storage if it does not match * one of the built-in static locales. This makes the common * usage case for newlocale, getting a C locale with predictable * behavior, very fast, and more importantly, fail-safe. */ for (j = i = 0; i < LC_ALL; i++) { if (loc && !(mask & (1 << i))) lm = loc->cat[i]; else lm = __get_locale(i, mask & (1 << i) ? name : ""); if (lm) j++; tmp.cat[i] = lm; } if (!j) return C_LOCALE; if (j == 1 && tmp.cat[LC_CTYPE] == &__c_dot_utf8) return UTF8_LOCALE; if ((loc = malloc(sizeof *loc))) *loc = tmp; return loc; }
char * nl_langinfo(nl_item item) { return nl_langinfo_l(item, __get_locale()); }
wint_t fputwc(wchar_t wc, FILE *fp) { return fputwc_l(wc, fp, __get_locale()); }
int vasprintf(char **str, const char *fmt, __va_list ap) { return vasprintf_l(str, __get_locale(), fmt, ap); }
wint_t btowc(int c) { return btowc_l(c, __get_locale()); }
#endif /* LIBC_SCCS and not lint */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); #include <stdio.h> #include <stdarg.h> #include "xlocale_private.h" int fprintf(FILE * __restrict fp, const char * __restrict fmt, ...) { int ret; va_list ap; va_start(ap, fmt); ret = vfprintf_l(fp, __get_locale(), fmt, ap); va_end(ap); return (ret); } int fprintf_l(FILE * __restrict fp, locale_t locale, const char * __restrict fmt, ...) { int ret; va_list ap; FIX_LOCALE(locale); va_start(ap, fmt); ret = vfprintf_l(fp, locale, fmt, ap); va_end(ap); return (ret); }
strtof(CONST char *s, char **sp) #endif { return strtof_l(s, sp, __get_locale()); }
int strcasecmp(const char *s1, const char *s2) { return strcasecmp_l(s1, s2, __get_locale()); }
wint_t fgetwc(FILE *fp) { return fgetwc_l(fp, __get_locale()); }
int wcswidth(const wchar_t *s, size_t n) { return (wcswidth_l(s, n, __get_locale())); }
static char * _fmt(const char *format, const struct tm *t, char *pt, const char *ptlim) { int Ealternative, Oalternative, PadIndex; #ifdef __ORCAC__ #define tptr (&_C_time_locale) #else struct lc_time_T *tptr = __get_current_time_locale(__get_locale()); #endif for ( ; *format; ++format) { if (*format == '%') { Ealternative = 0; Oalternative = 0; PadIndex = PAD_DEFAULT; label: switch (*++format) { case '\0': --format; break; case 'A': pt = _add((t->tm_wday < 0 || t->tm_wday >= DAYSPERWEEK) ? "?" : tptr->weekday[t->tm_wday], pt, ptlim); continue; case 'a': pt = _add((t->tm_wday < 0 || t->tm_wday >= DAYSPERWEEK) ? "?" : tptr->wday[t->tm_wday], pt, ptlim); continue; case 'B': pt = _add((t->tm_mon < 0 || t->tm_mon >= MONSPERYEAR) ? "?" : (Oalternative ? tptr->alt_month : tptr->month)[t->tm_mon], pt, ptlim); continue; continue; case 'b': case 'h': pt = _add((t->tm_mon < 0 || t->tm_mon >= MONSPERYEAR) ? "?" : tptr->mon[t->tm_mon], pt, ptlim); continue; case 'C': /* * %C used to do a... * _fmt("%a %b %e %X %Y", t); * ...whereas now POSIX 1003.2 calls for * something completely different. * (ado, 1993-05-24) */ pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 0, pt, ptlim); continue; case 'c': pt = _fmt(tptr->c_fmt, t, pt, ptlim); continue; case 'D': pt = _fmt("%m/%d/%y", t, pt, ptlim); continue; case 'd': pt = _conv(t->tm_mday, fmt_padding[PAD_FMT_DAYOFMONTH][PadIndex], pt, ptlim); continue; case 'E': if (Ealternative || Oalternative) break; Ealternative++; goto label; case 'O': /* * C99 locale modifiers. * The sequences * %Ec %EC %Ex %EX %Ey %EY * %Od %oe %OH %OI %Om %OM * %OS %Ou %OU %OV %Ow %OW %Oy * are supposed to provide alternate * representations. * * FreeBSD extension * %OB */ if (Ealternative || Oalternative) break; Oalternative++; goto label; case 'e': pt = _conv(t->tm_mday, fmt_padding[PAD_FMT_SDAYOFMONTH][PadIndex], pt, ptlim); continue; case 'F': pt = _fmt("%Y-%m-%d", t, pt, ptlim); continue; case 'H': pt = _conv(t->tm_hour, fmt_padding[PAD_FMT_HMS][PadIndex], pt, ptlim); continue; case 'I': pt = _conv((t->tm_hour % 12) ? (t->tm_hour % 12) : 12, fmt_padding[PAD_FMT_HMS][PadIndex], pt, ptlim); continue; case 'j': pt = _conv(t->tm_yday + 1, fmt_padding[PAD_FMT_DAYOFYEAR][PadIndex], pt, ptlim); continue; case 'k': /* * This used to be... * _conv(t->tm_hour % 12 ? * t->tm_hour % 12 : 12, 2, ' '); * ...and has been changed to the below to * match SunOS 4.1.1 and Arnold Robbins' * strftime version 3.0. That is, "%k" and * "%l" have been swapped. * (ado, 1993-05-24) */ pt = _conv(t->tm_hour, fmt_padding[PAD_FMT_SHMS][PadIndex], pt, ptlim); continue; #ifdef KITCHEN_SINK case 'K': /* ** After all this time, still unclaimed! */ pt = _add("kitchen sink", pt, ptlim); continue; #endif /* defined KITCHEN_SINK */ case 'l': /* * This used to be... * _conv(t->tm_hour, 2, ' '); * ...and has been changed to the below to * match SunOS 4.1.1 and Arnold Robbin's * strftime version 3.0. That is, "%k" and * "%l" have been swapped. * (ado, 1993-05-24) */ pt = _conv((t->tm_hour % 12) ? (t->tm_hour % 12) : 12, fmt_padding[PAD_FMT_SHMS][PadIndex], pt, ptlim); continue; case 'M': pt = _conv(t->tm_min, fmt_padding[PAD_FMT_HMS][PadIndex], pt, ptlim); continue; case 'm': pt = _conv(t->tm_mon + 1, fmt_padding[PAD_FMT_MONTH][PadIndex], pt, ptlim); continue; case 'n': pt = _add("\n", pt, ptlim); continue; case 'p': pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ? tptr->pm : tptr->am, pt, ptlim); continue; case 'R': pt = _fmt("%H:%M", t, pt, ptlim); continue; case 'r': pt = _fmt(tptr->ampm_fmt, t, pt, ptlim); continue; case 'S': pt = _conv(t->tm_sec, fmt_padding[PAD_FMT_HMS][PadIndex], pt, ptlim); continue; case 's': pt = _secs(t, pt, ptlim); continue; case 'T': pt = _fmt("%H:%M:%S", t, pt, ptlim); continue; case 't': pt = _add("\t", pt, ptlim); continue; case 'U': pt = _conv((t->tm_yday + DAYSPERWEEK - t->tm_wday) / DAYSPERWEEK, fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], pt, ptlim); continue; case 'u': /* * From Arnold Robbins' strftime version 3.0: * "ISO 8601: Weekday as a decimal number * [1 (Monday) - 7]" * (ado, 1993-05-24) */ pt = _conv((t->tm_wday == 0) ? DAYSPERWEEK : t->tm_wday, "%d", pt, ptlim); continue; case 'V': /* ISO 8601 week number */ case 'G': /* ISO 8601 year (four digits) */ case 'g': /* ISO 8601 year (two digits) */ /* * From Arnold Robbins' strftime version 3.0: "the week number of the * year (the first Monday as the first day of week 1) as a decimal number * (01-53)." * (ado, 1993-05-24) * * From "http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html" by Markus Kuhn: * "Week 01 of a year is per definition the first week which has the * Thursday in this year, which is equivalent to the week which contains * the fourth day of January. In other words, the first week of a new year * is the week which has the majority of its days in the new year. Week 01 * might also contain days from the previous year and the week before week * 01 of a year is the last week (52 or 53) of the previous year even if * it contains days from the new year. A week starts with Monday (day 1) * and ends with Sunday (day 7). For example, the first week of the year * 1997 lasts from 1996-12-30 to 1997-01-05..." * (ado, 1996-01-02) */ { int year; int base; int yday; int wday; int w; year = t->tm_year; base = TM_YEAR_BASE; yday = t->tm_yday; wday = t->tm_wday; for ( ; ; ) { int len; int bot; int top; len = isleap_sum(year, base) ? DAYSPERLYEAR : DAYSPERNYEAR; /* * What yday (-3 ... 3) does * the ISO year begin on? */ bot = ((yday + 11 - wday) % DAYSPERWEEK) - 3; /* * What yday does the NEXT * ISO year begin on? */ top = bot - (len % DAYSPERWEEK); if (top < -3) top += DAYSPERWEEK; top += len; if (yday >= top) { ++base; w = 1; break; } if (yday >= bot) { w = 1 + ((yday - bot) / DAYSPERWEEK); break; } --base; yday += isleap_sum(year, base) ? DAYSPERLYEAR : DAYSPERNYEAR; } #ifdef XPG4_1994_04_09 if ((w == 52 && t->tm_mon == TM_JANUARY) || (w == 1 && t->tm_mon == TM_DECEMBER)) w = 53; #endif /* defined XPG4_1994_04_09 */ if (*format == 'V') pt = _conv(w, fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], pt, ptlim); else if (*format == 'g') { pt = _yconv(year, base, 0, 1, pt, ptlim); } else pt = _yconv(year, base, 1, 1, pt, ptlim); } continue; case 'v': /* * From Arnold Robbins' strftime version 3.0: * "date as dd-bbb-YYYY" * (ado, 1993-05-24) */ pt = _fmt("%e-%b-%Y", t, pt, ptlim); continue; case 'W': pt = _conv((t->tm_yday + DAYSPERWEEK - (t->tm_wday ? (t->tm_wday - 1) : (DAYSPERWEEK - 1))) / DAYSPERWEEK, fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], pt, ptlim); continue; case 'w': pt = _conv(t->tm_wday, "%d", pt, ptlim); continue; case 'X': pt = _fmt(tptr->X_fmt, t, pt, ptlim); continue; case 'x': pt = _fmt(tptr->x_fmt, t, pt, ptlim); continue; case 'y': pt = _yconv(t->tm_year, TM_YEAR_BASE, 0, 1, pt, ptlim); continue; case 'Y': pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 1, pt, ptlim); continue; case 'Z': #ifdef TM_ZONE if (t->TM_ZONE != NULL) pt = _add(t->TM_ZONE, pt, ptlim); else #endif /* defined TM_ZONE */ if (t->tm_isdst >= 0) pt = _add(tzname[t->tm_isdst != 0], pt, ptlim); /* * C99 says that %Z must be replaced by the * empty string if the time zone is not * determinable. */ continue; case 'z': { int diff; char const * sign; if (t->tm_isdst < 0) continue; #ifdef TM_GMTOFF diff = t->TM_GMTOFF; #else /* !defined TM_GMTOFF */ /* * C99 says that the UTC offset must * be computed by looking only at * tm_isdst. This requirement is * incorrect, since it means the code * must rely on magic (in this case * altzone and timezone), and the * magic might not have the correct * offset. Doing things correctly is * tricky and requires disobeying C99; * see GNU C strftime for details. * For now, punt and conform to the * standard, even though it's incorrect. * * C99 says that %z must be replaced by the * empty string if the time zone is not * determinable, so output nothing if the * appropriate variables are not available. */ if (t->tm_isdst == 0) #ifdef USG_COMPAT diff = -timezone; #else /* !defined USG_COMPAT */ continue; #endif /* !defined USG_COMPAT */ else #ifdef ALTZONE diff = -altzone; #else /* !defined ALTZONE */ continue; #endif /* !defined ALTZONE */ #endif /* !defined TM_GMTOFF */ if (diff < 0) { sign = "-"; diff = -diff; } else sign = "+"; pt = _add(sign, pt, ptlim); diff /= SECSPERMIN; diff = (diff / MINSPERHOUR) * 100 + (diff % MINSPERHOUR); pt = _conv(diff, fmt_padding[PAD_FMT_YEAR][PadIndex], pt, ptlim); } continue; case '+': pt = _fmt(tptr->date_fmt, t, pt, ptlim); continue; case '-': if (PadIndex != PAD_DEFAULT) break; PadIndex = PAD_LESS; goto label; case '_': if (PadIndex != PAD_DEFAULT) break; PadIndex = PAD_SPACE; goto label; case '0': if (PadIndex != PAD_DEFAULT) break; PadIndex = PAD_ZERO; goto label; case '%': /* * X311J/88-090 (4.12.3.5): if conversion char is * undefined, behavior is undefined. Print out the * character itself as printf(3) also does. */ default: break; } }
#include <stdio.h> #include <stdarg.h> #include "un-namespace.h" #include "libc_private.h" #include "local.h" #include "xlocale_private.h" int fscanf(FILE * __restrict fp, char const * __restrict fmt, ...) { int ret; va_list ap; va_start(ap, fmt); FLOCKFILE(fp); ret = __svfscanf(fp, __get_locale(), fmt, ap); va_end(ap); FUNLOCKFILE(fp); return (ret); } int fscanf_l(FILE * __restrict fp, locale_t locale, char const * __restrict fmt, ...) { int ret; va_list ap; FIX_LOCALE(locale); va_start(ap, fmt); FLOCKFILE(fp); ret = __svfscanf(fp, locale, fmt, ap); va_end(ap);
wint_t getwchar() { return (getwchar_l(__get_locale())); }
int wctob(wint_t c) { return wctob_l(c, __get_locale()); }
char * strcasestr(const char *s, const char *find) { return strcasestr_l(s, find, __get_locale()); }
int strncasecmp(const char *s1, const char *s2, size_t n) { return strncasecmp_l(s1, s2, n, __get_locale()); }
const _RuneLocale * __getCurrentRuneLocale(void) { return XLOCALE_CTYPE(__get_locale())->runes; }
wint_t ungetwc(wint_t wc, FILE *fp) { return ungetwc_l(wc, fp, __get_locale()); }
int strcoll(const char *s, const char *s2) { return strcoll_l(s, s2, __get_locale()); }
wint_t towctrans(wint_t wc, wctrans_t desc) { return towctrans_l(wc, desc, __get_locale()); }
int wcswidth(const wchar_t *pwcs, size_t n) { return wcswidth_l(pwcs, n, __get_locale()); }
int vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap) { return vfwprintf_l(fp, __get_locale(), fmt0, ap); }
struct lconv * localeconv(void) { return localeconv_l(__get_locale()); }
int mbsinit(const mbstate_t *ps) { return mbsinit_l(ps, __get_locale()); }
int wcscoll(const wchar_t *ws1, const wchar_t *ws2) { return wcscoll_l(ws1, ws2, __get_locale()); }
int vfprintf(FILE *fp, const char *fmt0, __va_list ap) { return vfprintf_l(fp, __get_locale(), fmt0, ap); }
static int rangematch(const char *pattern, wchar_t test, int flags, char **newp, mbstate_t *patmbs) { int negate, ok; wchar_t c, c2; size_t pclen; const char *origpat; #ifndef __CYGWIN__ struct xlocale_collate *table = (struct xlocale_collate*)__get_locale()->components[XLC_COLLATE]; #endif /* * A bracket expression starting with an unquoted circumflex * character produces unspecified results (IEEE 1003.2-1992, * 3.13.2). This implementation treats it like '!', for * consistency with the regular expression syntax. * J.T. Conklin ([email protected]) */ if ( (negate = (*pattern == '!' || *pattern == '^')) ) ++pattern; if (flags & FNM_CASEFOLD) test = towlower(test); /* * A right bracket shall lose its special meaning and represent * itself in a bracket expression if it occurs first in the list. * -- POSIX.2 2.8.3.2 */ ok = 0; origpat = pattern; for (;;) { if (*pattern == ']' && pattern > origpat) { pattern++; break; } else if (*pattern == '\0') { return (RANGE_ERROR); } else if (*pattern == '/' && (flags & FNM_PATHNAME)) { return (RANGE_NOMATCH); } else if (*pattern == '\\' && !(flags & FNM_NOESCAPE)) pattern++; pclen = mbrtowc(&c, pattern, MB_LEN_MAX, patmbs); if (pclen == (size_t)-1 || pclen == (size_t)-2) return (RANGE_NOMATCH); pattern += pclen; if (flags & FNM_CASEFOLD) c = towlower(c); if (*pattern == '-' && *(pattern + 1) != EOS && *(pattern + 1) != ']') { if (*++pattern == '\\' && !(flags & FNM_NOESCAPE)) if (*pattern != EOS) pattern++; pclen = mbrtowc(&c2, pattern, MB_LEN_MAX, patmbs); if (pclen == (size_t)-1 || pclen == (size_t)-2) return (RANGE_NOMATCH); pattern += pclen; if (c2 == EOS) return (RANGE_ERROR); if (flags & FNM_CASEFOLD) c2 = towlower(c2); #ifdef __CYGWIN__ if (__collate_load_error ? c <= test && test <= c2 : __collate_range_cmp(c, test) <= 0 && __collate_range_cmp(test, c2) <= 0 ) #else if (table->__collate_load_error ? c <= test && test <= c2 : __collate_range_cmp(table, c, test) <= 0 && __collate_range_cmp(table, test, c2) <= 0 ) #endif ok = 1; } else if (c == test) ok = 1; } *newp = (char *)pattern; return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH); }
int wctomb(char *s, wchar_t wchar) { return wctomb_l(s, wchar, __get_locale()); }