diff options
author | theraven <theraven@FreeBSD.org> | 2011-11-20 14:45:42 +0000 |
---|---|---|
committer | theraven <theraven@FreeBSD.org> | 2011-11-20 14:45:42 +0000 |
commit | 0f6ef690b3118882121ed67561c7ce2660cfebe1 (patch) | |
tree | 909189922493cddbeeac84af2e316dc897661311 /lib/libc/stdtime | |
parent | 18b29f3fb8abee5d57ed8f4a44f806bec7e0eeff (diff) | |
download | FreeBSD-src-0f6ef690b3118882121ed67561c7ce2660cfebe1.zip FreeBSD-src-0f6ef690b3118882121ed67561c7ce2660cfebe1.tar.gz |
Implement xlocale APIs from Darwin, mainly for use by libc++. This adds a
load of _l suffixed versions of various standard library functions that use
the global locale, making them take an explicit locale parameter. Also
adds support for per-thread locales. This work was funded by the FreeBSD
Foundation.
Please test any code you have that uses the C standard locale functions!
Reviewed by: das (gdtoa changes)
Approved by: dim (mentor)
Diffstat (limited to 'lib/libc/stdtime')
-rw-r--r-- | lib/libc/stdtime/strftime.c | 62 | ||||
-rw-r--r-- | lib/libc/stdtime/strptime.c | 170 | ||||
-rw-r--r-- | lib/libc/stdtime/timelocal.c | 57 | ||||
-rw-r--r-- | lib/libc/stdtime/timelocal.h | 8 |
4 files changed, 197 insertions, 100 deletions
diff --git a/lib/libc/stdtime/strftime.c b/lib/libc/stdtime/strftime.c index dac910b..d3571ad 100644 --- a/lib/libc/stdtime/strftime.c +++ b/lib/libc/stdtime/strftime.c @@ -2,6 +2,11 @@ * Copyright (c) 1989 The Regents of the University of California. * All rights reserved. * + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * Portions of this software were developed by David Chisnall + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, @@ -43,7 +48,7 @@ __FBSDID("$FreeBSD$"); static char * _add(const char *, char *, const char *); static char * _conv(int, const char *, char *, const char *); static char * _fmt(const char *, const struct tm *, char *, const char *, - int *); + int *, locale_t); static char * _yconv(int, int, int, int, char *, const char *); extern char * tzname[]; @@ -82,29 +87,30 @@ static const char* fmt_padding[][4] = { }; size_t -strftime(char * __restrict s, size_t maxsize, const char * __restrict format, - const struct tm * __restrict t) +strftime_l(char * __restrict s, size_t maxsize, const char * __restrict format, + const struct tm * __restrict t, locale_t loc) { char * p; int warn; + FIX_LOCALE(loc); tzset(); warn = IN_NONE; - p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn); + p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn, loc); #ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU if (warn != IN_NONE && getenv(YEAR_2000_NAME) != NULL) { - (void) fprintf(stderr, "\n"); + (void) fprintf_l(stderr, loc, "\n"); if (format == NULL) - (void) fprintf(stderr, "NULL strftime format "); - else (void) fprintf(stderr, "strftime format \"%s\" ", + (void) fprintf_l(stderr, loc, "NULL strftime format "); + else (void) fprintf_l(stderr, loc, "strftime format \"%s\" ", format); - (void) fprintf(stderr, "yields only two digits of years in "); + (void) fprintf_l(stderr, loc, "yields only two digits of years in "); if (warn == IN_SOME) - (void) fprintf(stderr, "some locales"); + (void) fprintf_l(stderr, loc, "some locales"); else if (warn == IN_THIS) - (void) fprintf(stderr, "the current locale"); - else (void) fprintf(stderr, "all locales"); - (void) fprintf(stderr, "\n"); + (void) fprintf_l(stderr, loc, "the current locale"); + else (void) fprintf_l(stderr, loc, "all locales"); + (void) fprintf_l(stderr, loc, "\n"); } #endif /* !defined NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU */ if (p == s + maxsize) @@ -113,16 +119,24 @@ strftime(char * __restrict s, size_t maxsize, const char * __restrict format, return p - s; } +size_t +strftime(char * __restrict s, size_t maxsize, const char * __restrict format, + const struct tm * __restrict t) +{ + return strftime_l(s, maxsize, format, t, __get_locale()); +} + static char * -_fmt(format, t, pt, ptlim, warnp) +_fmt(format, t, pt, ptlim, warnp, loc) const char * format; const struct tm * const t; char * pt; const char * const ptlim; int * warnp; +locale_t loc; { int Ealternative, Oalternative, PadIndex; - struct lc_time_T *tptr = __get_current_time_locale(); + struct lc_time_T *tptr = __get_current_time_locale(loc); for ( ; *format; ++format) { if (*format == '%') { @@ -175,7 +189,7 @@ label: { int warn2 = IN_SOME; - pt = _fmt(tptr->c_fmt, t, pt, ptlim, &warn2); + pt = _fmt(tptr->c_fmt, t, pt, ptlim, &warn2, loc); if (warn2 == IN_ALL) warn2 = IN_THIS; if (warn2 > *warnp) @@ -183,7 +197,7 @@ label: } continue; case 'D': - pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp); + pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp, loc); continue; case 'd': pt = _conv(t->tm_mday, fmt_padding[PAD_FMT_DAYOFMONTH][PadIndex], @@ -216,7 +230,7 @@ label: fmt_padding[PAD_FMT_SDAYOFMONTH][PadIndex], pt, ptlim); continue; case 'F': - pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp); + pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp, loc); continue; case 'H': pt = _conv(t->tm_hour, fmt_padding[PAD_FMT_HMS][PadIndex], @@ -285,11 +299,11 @@ label: pt, ptlim); continue; case 'R': - pt = _fmt("%H:%M", t, pt, ptlim, warnp); + pt = _fmt("%H:%M", t, pt, ptlim, warnp, loc); continue; case 'r': pt = _fmt(tptr->ampm_fmt, t, pt, ptlim, - warnp); + warnp, loc); continue; case 'S': pt = _conv(t->tm_sec, fmt_padding[PAD_FMT_HMS][PadIndex], @@ -313,7 +327,7 @@ label: } continue; case 'T': - pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp); + pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp, loc); continue; case 't': pt = _add("\t", pt, ptlim); @@ -428,7 +442,7 @@ label: ** "date as dd-bbb-YYYY" ** (ado, 1993-05-24) */ - pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp); + pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp, loc); continue; case 'W': pt = _conv((t->tm_yday + DAYSPERWEEK - @@ -441,13 +455,13 @@ label: pt = _conv(t->tm_wday, "%d", pt, ptlim); continue; case 'X': - pt = _fmt(tptr->X_fmt, t, pt, ptlim, warnp); + pt = _fmt(tptr->X_fmt, t, pt, ptlim, warnp, loc); continue; case 'x': { int warn2 = IN_SOME; - pt = _fmt(tptr->x_fmt, t, pt, ptlim, &warn2); + pt = _fmt(tptr->x_fmt, t, pt, ptlim, &warn2, loc); if (warn2 == IN_ALL) warn2 = IN_THIS; if (warn2 > *warnp) @@ -534,7 +548,7 @@ label: continue; case '+': pt = _fmt(tptr->date_fmt, t, pt, ptlim, - warnp); + warnp, loc); continue; case '-': if (PadIndex != PAD_DEFAULT) diff --git a/lib/libc/stdtime/strptime.c b/lib/libc/stdtime/strptime.c index 401350e..fb94dcd 100644 --- a/lib/libc/stdtime/strptime.c +++ b/lib/libc/stdtime/strptime.c @@ -22,6 +22,11 @@ /* * Copyright (c) 1994 Powerdog Industries. All rights reserved. * + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * Portions of this software were developed by David Chisnall + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -72,19 +77,20 @@ __FBSDID("$FreeBSD$"); #include "libc_private.h" #include "timelocal.h" -static char * _strptime(const char *, const char *, struct tm *, int *); +static char * _strptime(const char *, const char *, struct tm *, int *, locale_t); #define asizeof(a) (sizeof (a) / sizeof ((a)[0])) static char * -_strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp) +_strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp, + locale_t locale) { char c; const char *ptr; int i, len; int Ealternative, Oalternative; - struct lc_time_T *tptr = __get_current_time_locale(); + struct lc_time_T *tptr = __get_current_time_locale(locale); ptr = fmt; while (*ptr != 0) { @@ -94,8 +100,9 @@ _strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp) c = *ptr++; if (c != '%') { - if (isspace((unsigned char)c)) - while (*buf != 0 && isspace((unsigned char)*buf)) + if (isspace_l((unsigned char)c, locale)) + while (*buf != 0 && + isspace_l((unsigned char)*buf, locale)) buf++; else if (c != *buf++) return 0; @@ -114,18 +121,19 @@ label: break; case '+': - buf = _strptime(buf, tptr->date_fmt, tm, GMTp); + buf = _strptime(buf, tptr->date_fmt, tm, GMTp, locale); if (buf == 0) return 0; break; case 'C': - if (!isdigit((unsigned char)*buf)) + if (!isdigit_l((unsigned char)*buf, locale)) return 0; /* XXX This will break for 3-digit centuries. */ len = 2; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { + for (i = 0; len && *buf != 0 && + isdigit_l((unsigned char)*buf, locale); buf++) { i *= 10; i += *buf - '0'; len--; @@ -137,13 +145,13 @@ label: break; case 'c': - buf = _strptime(buf, tptr->c_fmt, tm, GMTp); + buf = _strptime(buf, tptr->c_fmt, tm, GMTp, locale); if (buf == 0) return 0; break; case 'D': - buf = _strptime(buf, "%m/%d/%y", tm, GMTp); + buf = _strptime(buf, "%m/%d/%y", tm, GMTp, locale); if (buf == 0) return 0; break; @@ -161,47 +169,48 @@ label: goto label; case 'F': - buf = _strptime(buf, "%Y-%m-%d", tm, GMTp); + buf = _strptime(buf, "%Y-%m-%d", tm, GMTp, locale); if (buf == 0) return 0; break; case 'R': - buf = _strptime(buf, "%H:%M", tm, GMTp); + buf = _strptime(buf, "%H:%M", tm, GMTp, locale); if (buf == 0) return 0; break; case 'r': - buf = _strptime(buf, tptr->ampm_fmt, tm, GMTp); + buf = _strptime(buf, tptr->ampm_fmt, tm, GMTp, locale); if (buf == 0) return 0; break; case 'T': - buf = _strptime(buf, "%H:%M:%S", tm, GMTp); + buf = _strptime(buf, "%H:%M:%S", tm, GMTp, locale); if (buf == 0) return 0; break; case 'X': - buf = _strptime(buf, tptr->X_fmt, tm, GMTp); + buf = _strptime(buf, tptr->X_fmt, tm, GMTp, locale); if (buf == 0) return 0; break; case 'x': - buf = _strptime(buf, tptr->x_fmt, tm, GMTp); + buf = _strptime(buf, tptr->x_fmt, tm, GMTp, locale); if (buf == 0) return 0; break; case 'j': - if (!isdigit((unsigned char)*buf)) + if (!isdigit_l((unsigned char)*buf, locale)) return 0; len = 3; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { + for (i = 0; len && *buf != 0 && + isdigit_l((unsigned char)*buf, locale); buf++){ i *= 10; i += *buf - '0'; len--; @@ -214,14 +223,16 @@ label: case 'M': case 'S': - if (*buf == 0 || isspace((unsigned char)*buf)) + if (*buf == 0 || + isspace_l((unsigned char)*buf, locale)) break; - if (!isdigit((unsigned char)*buf)) + if (!isdigit_l((unsigned char)*buf, locale)) return 0; len = 2; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { + for (i = 0; len && *buf != 0 && + isdigit_l((unsigned char)*buf, locale); buf++){ i *= 10; i += *buf - '0'; len--; @@ -237,8 +248,10 @@ label: tm->tm_sec = i; } - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) + if (*buf != 0 && + isspace_l((unsigned char)*buf, locale)) + while (*ptr != 0 && + !isspace_l((unsigned char)*ptr, locale)) ptr++; break; @@ -254,11 +267,12 @@ label: * XXX The %l specifier may gobble one too many * digits if used incorrectly. */ - if (!isdigit((unsigned char)*buf)) + if (!isdigit_l((unsigned char)*buf, locale)) return 0; len = 2; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { + for (i = 0; len && *buf != 0 && + isdigit_l((unsigned char)*buf, locale); buf++) { i *= 10; i += *buf - '0'; len--; @@ -271,8 +285,10 @@ label: tm->tm_hour = i; - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) + if (*buf != 0 && + isspace_l((unsigned char)*buf, locale)) + while (*ptr != 0 && + !isspace_l((unsigned char)*ptr, locale)) ptr++; break; @@ -282,7 +298,7 @@ label: * specifiers. */ len = strlen(tptr->am); - if (strncasecmp(buf, tptr->am, len) == 0) { + if (strncasecmp_l(buf, tptr->am, len, locale) == 0) { if (tm->tm_hour > 12) return 0; if (tm->tm_hour == 12) @@ -292,7 +308,7 @@ label: } len = strlen(tptr->pm); - if (strncasecmp(buf, tptr->pm, len) == 0) { + if (strncasecmp_l(buf, tptr->pm, len, locale) == 0) { if (tm->tm_hour > 12) return 0; if (tm->tm_hour != 12) @@ -307,12 +323,12 @@ label: case 'a': for (i = 0; i < asizeof(tptr->weekday); i++) { len = strlen(tptr->weekday[i]); - if (strncasecmp(buf, tptr->weekday[i], - len) == 0) + if (strncasecmp_l(buf, tptr->weekday[i], + len, locale) == 0) break; len = strlen(tptr->wday[i]); - if (strncasecmp(buf, tptr->wday[i], - len) == 0) + if (strncasecmp_l(buf, tptr->wday[i], + len, locale) == 0) break; } if (i == asizeof(tptr->weekday)) @@ -330,11 +346,12 @@ label: * point to calculate a real value, so just check the * range for now. */ - if (!isdigit((unsigned char)*buf)) + if (!isdigit_l((unsigned char)*buf, locale)) return 0; len = 2; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { + for (i = 0; len && *buf != 0 && + isdigit_l((unsigned char)*buf, locale); buf++) { i *= 10; i += *buf - '0'; len--; @@ -342,13 +359,15 @@ label: if (i > 53) return 0; - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) + if (*buf != 0 && + isspace_l((unsigned char)*buf, locale)) + while (*ptr != 0 && + !isspace_l((unsigned char)*ptr, locale)) ptr++; break; case 'w': - if (!isdigit((unsigned char)*buf)) + if (!isdigit_l((unsigned char)*buf, locale)) return 0; i = *buf - '0'; @@ -357,8 +376,10 @@ label: tm->tm_wday = i; - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) + if (*buf != 0 && + isspace_l((unsigned char)*buf, locale)) + while (*ptr != 0 && + !isspace_l((unsigned char)*ptr, locale)) ptr++; break; @@ -372,11 +393,12 @@ label: * XXX The %e specifier may gobble one too many * digits if used incorrectly. */ - if (!isdigit((unsigned char)*buf)) + if (!isdigit_l((unsigned char)*buf, locale)) return 0; len = 2; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { + for (i = 0; len && *buf != 0 && + isdigit_l((unsigned char)*buf, locale); buf++) { i *= 10; i += *buf - '0'; len--; @@ -386,8 +408,10 @@ label: tm->tm_mday = i; - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) + if (*buf != 0 && + isspace_l((unsigned char)*buf, locale)) + while (*ptr != 0 && + !isspace_l((unsigned char)*ptr, locale)) ptr++; break; @@ -398,15 +422,15 @@ label: if (Oalternative) { if (c == 'B') { len = strlen(tptr->alt_month[i]); - if (strncasecmp(buf, + if (strncasecmp_l(buf, tptr->alt_month[i], - len) == 0) + len, locale) == 0) break; } } else { len = strlen(tptr->month[i]); - if (strncasecmp(buf, tptr->month[i], - len) == 0) + if (strncasecmp_l(buf, tptr->month[i], + len, locale) == 0) break; } } @@ -417,8 +441,8 @@ label: if (i == asizeof(tptr->month) && !Oalternative) { for (i = 0; i < asizeof(tptr->month); i++) { len = strlen(tptr->mon[i]); - if (strncasecmp(buf, tptr->mon[i], - len) == 0) + if (strncasecmp_l(buf, tptr->mon[i], + len, locale) == 0) break; } } @@ -430,11 +454,12 @@ label: break; case 'm': - if (!isdigit((unsigned char)*buf)) + if (!isdigit_l((unsigned char)*buf, locale)) return 0; len = 2; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { + for (i = 0; len && *buf != 0 && + isdigit_l((unsigned char)*buf, locale); buf++) { i *= 10; i += *buf - '0'; len--; @@ -444,8 +469,10 @@ label: tm->tm_mon = i - 1; - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) + if (*buf != 0 && + isspace_l((unsigned char)*buf, locale)) + while (*ptr != 0 && + !isspace_l((unsigned char)*ptr, locale)) ptr++; break; @@ -458,7 +485,7 @@ label: sverrno = errno; errno = 0; - n = strtol(buf, &cp, 10); + n = strtol_l(buf, &cp, 10, locale); if (errno == ERANGE || (long)(t = n) != n) { errno = sverrno; return 0; @@ -472,14 +499,16 @@ label: case 'Y': case 'y': - if (*buf == 0 || isspace((unsigned char)*buf)) + if (*buf == 0 || + isspace_l((unsigned char)*buf, locale)) break; - if (!isdigit((unsigned char)*buf)) + if (!isdigit_l((unsigned char)*buf, locale)) return 0; len = (c == 'Y') ? 4 : 2; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { + for (i = 0; len && *buf != 0 && + isdigit_l((unsigned char)*buf, locale); buf++) { i *= 10; i += *buf - '0'; len--; @@ -493,8 +522,10 @@ label: tm->tm_year = i; - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) + if (*buf != 0 && + isspace_l((unsigned char)*buf, locale)) + while (*ptr != 0 && + !isspace_l((unsigned char)*ptr, locale)) ptr++; break; @@ -503,7 +534,9 @@ label: const char *cp; char *zonestr; - for (cp = buf; *cp && isupper((unsigned char)*cp); ++cp) {/*empty*/} + for (cp = buf; *cp && + isupper_l((unsigned char)*cp, locale); ++cp) { + /*empty*/} if (cp - buf) { zonestr = alloca(cp - buf + 1); strncpy(zonestr, buf, cp - buf); @@ -537,7 +570,7 @@ label: buf++; i = 0; for (len = 4; len > 0; len--) { - if (isdigit((unsigned char)*buf)) { + if (isdigit_l((unsigned char)*buf, locale)) { i *= 10; i += *buf - '0'; buf++; @@ -557,14 +590,15 @@ label: char * -strptime(const char * __restrict buf, const char * __restrict fmt, - struct tm * __restrict tm) +strptime_l(const char * __restrict buf, const char * __restrict fmt, + struct tm * __restrict tm, locale_t loc) { char *ret; int gmt; + FIX_LOCALE(loc); gmt = 0; - ret = _strptime(buf, fmt, tm, &gmt); + ret = _strptime(buf, fmt, tm, &gmt, loc); if (ret && gmt) { time_t t = timegm(tm); localtime_r(&t, tm); @@ -572,3 +606,9 @@ strptime(const char * __restrict buf, const char * __restrict fmt, return (ret); } +char * +strptime(const char * __restrict buf, const char * __restrict fmt, + struct tm * __restrict tm) +{ + return strptime_l(buf, fmt, tm, __get_locale()); +} diff --git a/lib/libc/stdtime/timelocal.c b/lib/libc/stdtime/timelocal.c index 6917e6b..3d9d096 100644 --- a/lib/libc/stdtime/timelocal.c +++ b/lib/libc/stdtime/timelocal.c @@ -3,6 +3,11 @@ * Copyright (c) 1997 FreeBSD Inc. * All rights reserved. * + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * Portions of this software were developed by David Chisnall + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -33,9 +38,13 @@ __FBSDID("$FreeBSD$"); #include "ldpart.h" #include "timelocal.h" -static struct lc_time_T _time_locale; -static int _time_using_locale; -static char *time_locale_buf; +struct xlocale_time { + struct xlocale_component header; + char *buffer; + struct lc_time_T locale; +}; + +struct xlocale_time __xlocale_global_time; #define LCTIME_SIZE (sizeof(struct lc_time_T) / sizeof(char *)) @@ -99,19 +108,47 @@ static const struct lc_time_T _C_time_locale = { "%I:%M:%S %p" }; +static void destruct_time(void *v) +{ + struct xlocale_time *l = v; + if (l->buffer) + free(l->buffer); + free(l); +} + +#include <stdio.h> struct lc_time_T * -__get_current_time_locale(void) +__get_current_time_locale(locale_t loc) { - return (_time_using_locale - ? &_time_locale + return (loc->using_time_locale + ? &((struct xlocale_time *)loc->components[XLC_TIME])->locale : (struct lc_time_T *)&_C_time_locale); } +static int +time_load_locale(struct xlocale_time *l, int *using_locale, const char *name) +{ + struct lc_time_T *time_locale = &l->locale; + return (__part_load_locale(name, using_locale, + &l->buffer, "LC_TIME", + LCTIME_SIZE, LCTIME_SIZE, + (const char **)time_locale)); +} int __time_load_locale(const char *name) { - return (__part_load_locale(name, &_time_using_locale, - &time_locale_buf, "LC_TIME", - LCTIME_SIZE, LCTIME_SIZE, - (const char **)&_time_locale)); + return time_load_locale(&__xlocale_global_time, + &__xlocale_global_locale.using_time_locale, name); } +void* __time_load(const char* name, locale_t loc) +{ + struct xlocale_time *new = calloc(sizeof(struct xlocale_time), 1); + new->header.header.destructor = destruct_time; + if (time_load_locale(new, &loc->using_time_locale, name) == _LDP_ERROR) + { + xlocale_release(new); + return NULL; + } + return new; +} + diff --git a/lib/libc/stdtime/timelocal.h b/lib/libc/stdtime/timelocal.h index 5d26bf9..2e44415 100644 --- a/lib/libc/stdtime/timelocal.h +++ b/lib/libc/stdtime/timelocal.h @@ -2,6 +2,11 @@ * Copyright (c) 1997-2002 FreeBSD Project. * All rights reserved. * + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * Portions of this software were developed by David Chisnall + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -28,6 +33,7 @@ #ifndef _TIMELOCAL_H_ #define _TIMELOCAL_H_ +#include "xlocale_private.h" /* * Private header file for the strftime and strptime localization @@ -49,7 +55,7 @@ struct lc_time_T { const char *ampm_fmt; }; -struct lc_time_T *__get_current_time_locale(void); +struct lc_time_T *__get_current_time_locale(locale_t); int __time_load_locale(const char *); #endif /* !_TIMELOCAL_H_ */ |