summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdtime/timelocal.c
diff options
context:
space:
mode:
authordt <dt@FreeBSD.org>1999-09-11 21:35:21 +0000
committerdt <dt@FreeBSD.org>1999-09-11 21:35:21 +0000
commit563a7a9ae192e9ef2ca5ca45263f32cdb350cd74 (patch)
tree3cb7079ddfd2c249ce7d44e9fea5f7864f17f9ad /lib/libc/stdtime/timelocal.c
parent61e17cfe0ebde91fdd82ad1508f6ea5dd721ebd8 (diff)
downloadFreeBSD-src-563a7a9ae192e9ef2ca5ca45263f32cdb350cd74.zip
FreeBSD-src-563a7a9ae192e9ef2ca5ca45263f32cdb350cd74.tar.gz
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
Diffstat (limited to 'lib/libc/stdtime/timelocal.c')
-rw-r--r--lib/libc/stdtime/timelocal.c68
1 files changed, 51 insertions, 17 deletions
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 <sys/syslimits.h>
#include <fcntl.h>
#include <locale.h>
+#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#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];
+}
OpenPOWER on IntegriCloud