mirror of
https://github.com/opnsense/src.git
synced 2026-06-08 16:22:46 -04:00
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
This commit is contained in:
parent
07181581f9
commit
da3785ef12
3 changed files with 58 additions and 19 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue