From 563a7a9ae192e9ef2ca5ca45263f32cdb350cd74 Mon Sep 17 00:00:00 2001 From: dt Date: Sat, 11 Sep 1999 21:35:21 +0000 Subject: Implement new format specifier for strftime: %OB, alternative national representation of the full month name. In the Russian locale, this alternative will be "nominative case", useful when the date designate month as a whole. E.g. month heading in a calendar. I hope it can be useful for some other locales too. Discussed with: wollman, ache --- lib/libc/stdtime/strftime.c | 8 ++++-- lib/libc/stdtime/timelocal.c | 68 +++++++++++++++++++++++++++++++++----------- lib/libc/stdtime/timelocal.h | 1 + 3 files changed, 58 insertions(+), 19 deletions(-) (limited to 'lib/libc/stdtime') diff --git a/lib/libc/stdtime/strftime.c b/lib/libc/stdtime/strftime.c index b70b216..5800fe8 100644 --- a/lib/libc/stdtime/strftime.c +++ b/lib/libc/stdtime/strftime.c @@ -75,8 +75,10 @@ _fmt(format, t, pt, ptlim) char *pt; const char *const ptlim; { + int alternative; for ( ; *format; ++format) { if (*format == '%') { + alternative = 0; label: switch (*++format) { case '\0': @@ -93,8 +95,9 @@ label: pt, ptlim); continue; case 'B': - pt = _add((t->tm_mon < 0 || t->tm_mon > 11) ? - "?" : Locale->month[t->tm_mon], + pt = _add((t->tm_mon < 0 || t->tm_mon > 11) ? + "?" : (alternative ? Locale->alt_month : + Locale->month)[t->tm_mon], pt, ptlim); continue; case 'b': @@ -136,6 +139,7 @@ label: ** representations. ** (ado, 5/24/93) */ + alternative = 1; goto label; case 'e': pt = _conv(t->tm_mday, "%2d", pt, ptlim); diff --git a/lib/libc/stdtime/timelocal.c b/lib/libc/stdtime/timelocal.c index b46c20d..f58488a 100644 --- a/lib/libc/stdtime/timelocal.c +++ b/lib/libc/stdtime/timelocal.c @@ -31,14 +31,22 @@ #include #include #include +#include #include #include #include "setlocale.h" #include "timelocal.h" +static int split_lines(char *, const char *); +static void set_from_buf(const char *, int); + struct lc_time_T _time_localebuf; int _time_using_locale; +#define LCTIME_SIZE_FULL (sizeof(struct lc_time_T) / sizeof(char *)) +#define LCTIME_SIZE_1 \ + (offsetof(struct lc_time_T, alt_month[0]) / sizeof(char *)) + const struct lc_time_T _C_time_locale = { { "Jan", "Feb", "Mar", "Apr", "May", "Jun", @@ -81,7 +89,12 @@ const struct lc_time_T _C_time_locale = { "PM", /* date_fmt */ - "%a %b %e %X %Z %Y" + "%a %b %e %X %Z %Y", + + { + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" + } }; @@ -90,11 +103,11 @@ __time_load_locale(const char *name) { static char * locale_buf; static char locale_buf_C[] = "C"; + static int num_lines; int fd; char * lbuf; char * p; - const char ** ap; const char * plim; char filename[PATH_MAX]; struct stat st; @@ -116,11 +129,7 @@ __time_load_locale(const char *name) */ lbuf = locale_buf; if (lbuf != NULL && strcmp(name, lbuf) == 0) { - p = lbuf; - for (ap = (const char **) &_time_localebuf; - ap < (const char **) (&_time_localebuf + 1); - ++ap) - *ap = p += strlen(p) + 1; + set_from_buf(lbuf, num_lines); _time_using_locale = 1; return 0; } @@ -161,16 +170,14 @@ __time_load_locale(const char *name) */ if (plim[-1] != '\n') goto bad_lbuf; - for (ap = (const char **) &_time_localebuf; - ap < (const char **) (&_time_localebuf + 1); - ++ap) { - if (p == plim) - goto reset_locale; - *ap = p; - while (*p != '\n') - ++p; - *p++ = '\0'; - } + num_lines = split_lines(p, plim); + if (num_lines >= LCTIME_SIZE_FULL) + num_lines = LCTIME_SIZE_FULL; + else if (num_lines >= LCTIME_SIZE_1) + num_lines = LCTIME_SIZE_1; + else + goto reset_locale; + set_from_buf(lbuf, num_lines); /* ** Record the successful parse in the cache. */ @@ -195,3 +202,30 @@ no_locale: _time_using_locale = save_using_locale; return -1; } + +static int +split_lines(char *p, const char *plim) +{ + int i; + + for (i = 0; p < plim; i++) { + p = strchr(p, '\n'); + *p++ = '\0'; + } + return i; +} + +static void +set_from_buf(const char *p, int num_lines) +{ + const char **ap; + int i; + + for (ap = (const char **) &_time_localebuf, i = 0; + i < num_lines; ++ap, ++i) + *ap = p += strlen(p) + 1; + if (num_lines == LCTIME_SIZE_FULL) + return; + for (i = 0; i < 12; i++) + _time_localebuf.alt_month[i] = _time_localebuf.month[i]; +} diff --git a/lib/libc/stdtime/timelocal.h b/lib/libc/stdtime/timelocal.h index 314c48c..9a19175 100644 --- a/lib/libc/stdtime/timelocal.h +++ b/lib/libc/stdtime/timelocal.h @@ -41,6 +41,7 @@ struct lc_time_T { const char * am; const char * pm; const char * date_fmt; + const char * alt_month[12]; }; extern struct lc_time_T _time_localebuf; -- cgit v1.1