107
81
# define L_(Str) Str
108
82
# define NLW(Sym) Sym
110
# if !defined STDC_HEADERS && !defined HAVE_MEMCPY
111
# define MEMCPY(d, s, n) bcopy ((s), (d), (n))
113
# define MEMCPY(d, s, n) memcpy ((d), (s), (n))
84
# define MEMCPY(d, s, n) memcpy (d, s, n)
115
85
# define STRLEN(s) strlen (s)
118
# define MEMPCPY(d, s, n) __mempcpy (d, s, n)
120
# ifndef HAVE_MEMPCPY
121
# define MEMPCPY(d, s, n) ((void *) ((char *) memcpy (d, s, n) + (n)))
127
# if defined __GNUC__ || (defined __STDC__ && __STDC__)
128
# define __P(args) args
130
# define __P(args) ()
132
#endif /* Not __P. */
150
#define TYPE_SIGNED(t) ((t) -1 < 0)
152
/* Bound on length of the string representing an integer value of type t.
153
Subtract one for the sign bit if t is signed;
154
302 / 1000 is log10 (2) rounded up;
155
add one for integer division truncation;
156
add one more for a minus sign if t is signed. */
89
/* Shift A right by B bits portably, by dividing A by 2**B and
90
truncating towards minus infinity. A and B should be free of side
91
effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
92
INT_BITS is the number of useful bits in an int. GNU code can
93
assume that INT_BITS is at least 32.
95
ISO C99 says that A >> B is implementation-defined if A < 0. Some
96
implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
97
right in the usual way when A < 0, so SHR falls back on division if
98
ordinary A >> B doesn't seem to be the usual signed shift. */
102
: (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
104
/* Bound on length of the string representing an integer type or expression T.
105
Subtract 1 for the sign bit if t is signed; log10 (2.0) < 146/485;
106
add 1 for integer division truncation; add 1 more for a minus sign
157
108
#define INT_STRLEN_BOUND(t) \
158
((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 + 1 + TYPE_SIGNED (t))
109
((sizeof (t) * CHAR_BIT - 1) * 146 / 485 + 2)
160
111
#define TM_YEAR_BASE 1900
163
114
/* Nonzero if YEAR is a leap year (every 4 years,
164
115
except every 100th isn't, and every 400th is). */
165
# define __isleap(year) \
116
# define __isleap(year) \
166
117
((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
171
# define my_strftime_gmtime_r __gmtime_r
172
# define my_strftime_localtime_r __localtime_r
173
122
# define tzname __tzname
174
123
# define tzset __tzset
177
/* If we're a strftime substitute in a GNU program, then prefer gmtime
178
to gmtime_r, since many gmtime_r implementations are buggy.
179
Similarly for localtime_r. */
181
# if ! HAVE_TM_GMTOFF
182
static struct tm *my_strftime_gmtime_r __P ((const time_t *, struct tm *));
184
my_strftime_gmtime_r (t, tp)
188
struct tm *l = gmtime (t);
195
static struct tm *my_strftime_localtime_r __P ((const time_t *, struct tm *));
197
my_strftime_localtime_r (t, tp)
201
struct tm *l = localtime (t);
207
# endif /* ! HAVE_TM_GMTOFF */
208
#endif /* ! defined _LIBC */
211
#if !defined memset && !defined HAVE_MEMSET && !defined _LIBC
212
/* Some systems lack the `memset' function and we don't want to
213
introduce additional dependencies. */
214
/* The SGI compiler reportedly barfs on the trailing null
215
if we use a string constant as the initializer. 28 June 1997, rms. */
216
static const CHAR_T spaces[16] = /* " " */
218
L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),
219
L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' ')
221
static const CHAR_T zeroes[16] = /* "0000000000000000" */
223
L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),
224
L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0')
227
# define memset_space(P, Len) \
233
int _this = _len > 16 ? 16 : _len; \
234
(P) = MEMPCPY ((P), spaces, _this * sizeof (CHAR_T)); \
240
# define memset_zero(P, Len) \
246
int _this = _len > 16 ? 16 : _len; \
247
(P) = MEMPCPY ((P), zeroes, _this * sizeof (CHAR_T)); \
254
# define memset_space(P, Len) (wmemset ((P), L' ', (Len)), (P) += (Len))
255
# define memset_zero(P, Len) (wmemset ((P), L'0', (Len)), (P) += (Len))
257
# define memset_space(P, Len) (memset ((P), ' ', (Len)), (P) += (Len))
258
# define memset_zero(P, Len) (memset ((P), '0', (Len)), (P) += (Len))
266
int _delta = width - _n; \
267
int _incr = _n + (_delta > 0 ? _delta : 0); \
268
if (i + _incr >= maxsize) \
274
if (pad == L_('0')) \
275
memset_zero (p, _delta); \
277
memset_space (p, _delta); \
127
/* Portable standalone applications should supply a "time.h" that
128
declares a POSIX-compliant localtime_r, for the benefit of older
129
implementations that lack localtime_r or have a nonstandard one.
130
See the gnulib time_r module for one way to implement this. */
132
# undef __localtime_r
133
# define __gmtime_r gmtime_r
134
# define __localtime_r localtime_r
139
# define FPRINTFTIME 0
143
# define STREAM_OR_CHAR_T FILE
144
# define STRFTIME_ARG(x) /* empty */
146
# define STREAM_OR_CHAR_T CHAR_T
147
# define STRFTIME_ARG(x) x,
151
# define memset_byte(P, Len, Byte) \
152
do { size_t _i; for (_i = 0; _i < Len; _i++) fputc (Byte, P); } while (0)
153
# define memset_space(P, Len) memset_byte (P, Len, ' ')
154
# define memset_zero(P, Len) memset_byte (P, Len, '0')
155
#elif defined COMPILE_WIDE
156
# define memset_space(P, Len) (wmemset (P, L' ', Len), (P) += (Len))
157
# define memset_zero(P, Len) (wmemset (P, L'0', Len), (P) += (Len))
159
# define memset_space(P, Len) (memset (P, ' ', Len), (P) += (Len))
160
# define memset_zero(P, Len) (memset (P, '0', Len), (P) += (Len))
164
# define advance(P, N)
166
# define advance(P, N) ((P) += (N))
173
int _delta = width - _n; \
174
int _incr = _n + (_delta > 0 ? _delta : 0); \
175
if ((size_t) _incr >= maxsize - i) \
179
if (digits == 0 && _delta > 0) \
181
if (pad == L_('0')) \
182
memset_zero (p, _delta); \
184
memset_space (p, _delta); \
288
memcpy_lowcase (p, (s), _n); \
289
else if (to_uppcase) \
290
memcpy_uppcase (p, (s), _n); \
292
MEMCPY ((PTR) p, (const PTR) (s), _n))
193
# define add1(C) add (1, fputc (C, p))
195
# define add1(C) add (1, *p = C)
204
fwrite_lowcase (p, (s), _n); \
205
else if (to_uppcase) \
206
fwrite_uppcase (p, (s), _n); \
209
/* We are ignoring the value of fwrite here, in spite of the \
210
fact that technically, that may not be valid: the fwrite \
211
specification in POSIX 2008 defers to that of fputc, which \
212
is intended to be consistent with the one from ISO C, \
213
which permits failure due to ENOMEM *without* setting the \
214
stream's error indicator. */ \
215
ignore_value (fwrite ((s), _n, 1, p)); \
224
memcpy_lowcase (p, (s), _n LOCALE_ARG); \
225
else if (to_uppcase) \
226
memcpy_uppcase (p, (s), _n LOCALE_ARG); \
228
MEMCPY ((void *) p, (void const *) (s), _n))
294
231
#ifdef COMPILE_WIDE
232
# ifndef USE_IN_EXTENDED_LOCALE_MODEL
233
# undef __mbsrtowcs_l
234
# define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st)
295
236
# define widen(os, ws, l) \
298
const char *__s = os; \
299
memset (&__st, '\0', sizeof (__st)); \
300
l = __mbsrtowcs (NULL, &__s, 0, &__st); \
301
ws = alloca ((l + 1) * sizeof (wchar_t)); \
302
(void) __mbsrtowcs (ws, &__s, l, &__st); \
239
const char *__s = os; \
240
memset (&__st, '\0', sizeof (__st)); \
241
l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc); \
242
ws = (wchar_t *) alloca ((l + 1) * sizeof (wchar_t)); \
243
(void) __mbsrtowcs_l (ws, &__s, l, &__st, loc); \
248
#if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
249
/* We use this code also for the extended locale handling where the
250
function gets as an additional argument the locale which has to be
251
used. To access the values we have to redefine the _NL_CURRENT
253
# define strftime __strftime_l
254
# define wcsftime __wcsftime_l
256
# define _NL_CURRENT(category, item) \
257
(current->values[_NL_ITEM_INDEX (item)].string)
258
# define LOCALE_ARG , loc
259
# define LOCALE_PARAM_PROTO , __locale_t loc
260
# define HELPER_LOCALE_ARG , current
262
# define LOCALE_PARAM_PROTO
265
# define HELPER_LOCALE_ARG , _NL_CURRENT_DATA (LC_TIME)
267
# define HELPER_LOCALE_ARG
307
271
#ifdef COMPILE_WIDE
308
# define TOUPPER(Ch) towupper (Ch)
309
# define TOLOWER(Ch) towlower (Ch)
272
# ifdef USE_IN_EXTENDED_LOCALE_MODEL
273
# define TOUPPER(Ch, L) __towupper_l (Ch, L)
274
# define TOLOWER(Ch, L) __towlower_l (Ch, L)
276
# define TOUPPER(Ch, L) towupper (Ch)
277
# define TOLOWER(Ch, L) towlower (Ch)
312
# define TOUPPER(Ch) toupper (Ch)
313
# define TOLOWER(Ch) tolower (Ch)
280
# ifdef USE_IN_EXTENDED_LOCALE_MODEL
281
# define TOUPPER(Ch, L) __toupper_l (Ch, L)
282
# define TOLOWER(Ch, L) __tolower_l (Ch, L)
315
# define TOUPPER(Ch) (islower (Ch) ? toupper (Ch) : (Ch))
316
# define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))
284
# define TOUPPER(Ch, L) toupper (Ch)
285
# define TOLOWER(Ch, L) tolower (Ch)
319
288
/* We don't use `isdigit' here since the locale dependent
564
505
for (f = format; *f != '\0'; ++f)
566
int pad = 0; /* Padding for number ('-', '_', or 0). */
567
int modifier; /* Field modifier ('E', 'O', or 0). */
568
int digits; /* Max digits for numeric format. */
569
int number_value; /* Numeric value to be printed. */
570
int negative_number; /* 1 if the number is negative. */
507
int pad = 0; /* Padding for number ('-', '_', or 0). */
508
int modifier; /* Field modifier ('E', 'O', or 0). */
509
int digits = 0; /* Max digits for numeric format. */
510
int number_value; /* Numeric value to be printed. */
511
unsigned int u_number_value; /* (unsigned int) number_value. */
512
bool negative_number; /* The number is negative. */
513
bool always_output_a_sign; /* +/- should always be output. */
514
int tz_colon_mask; /* Bitmask of where ':' should appear. */
571
515
const CHAR_T *subfmt;
573
CHAR_T buf[1 + (sizeof (int) < sizeof (time_t)
574
? INT_STRLEN_BOUND (time_t)
575
: INT_STRLEN_BOUND (int))];
519
+ 2 /* for the two colons in a %::z or %:::z time zone */
520
+ (sizeof (int) < sizeof (time_t)
521
? INT_STRLEN_BOUND (time_t)
522
: INT_STRLEN_BOUND (int))];
524
bool to_lowcase = false;
525
bool to_uppcase = upcase;
527
bool change_case = false;
582
530
#if DO_MULTIBYTE && !defined COMPILE_WIDE
588
case L_('\b'): case L_('\t'): case L_('\n'):
589
case L_('\v'): case L_('\f'): case L_('\r'):
590
case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
591
case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
592
case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
593
case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
594
case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
595
case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
596
case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
597
case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
598
case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
599
case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
600
case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
601
case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
602
case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
603
case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
604
case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
605
case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
606
case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
607
case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
609
/* The C Standard requires these 98 characters (plus '%') to
610
be in the basic execution character set. None of these
611
characters can start a multibyte sequence, so they need
612
not be analyzed further. */
617
/* Copy this multibyte sequence until we reach its end, find
618
an error, or come back to the initial shift state. */
620
mbstate_t mbstate = mbstate_zero;
625
format_end = f + strlen (f) + 1;
626
fsize = format_end - f;
630
size_t bytes = mbrlen (f + len, fsize - len, &mbstate);
635
if (bytes == (size_t) -2)
637
len += strlen (f + len);
641
if (bytes == (size_t) -1)
649
while (! mbsinit (&mbstate));
536
case L_('\b'): case L_('\t'): case L_('\n'):
537
case L_('\v'): case L_('\f'): case L_('\r'):
538
case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
539
case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
540
case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
541
case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
542
case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
543
case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
544
case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
545
case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
546
case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
547
case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
548
case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
549
case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
550
case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
551
case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
552
case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
553
case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
554
case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
555
case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
557
/* The C Standard requires these 98 characters (plus '%') to
558
be in the basic execution character set. None of these
559
characters can start a multibyte sequence, so they need
560
not be analyzed further. */
565
/* Copy this multibyte sequence until we reach its end, find
566
an error, or come back to the initial shift state. */
568
mbstate_t mbstate = mbstate_zero;
573
format_end = f + strlen (f) + 1;
574
fsize = format_end - f;
578
size_t bytes = mbrlen (f + len, fsize - len, &mbstate);
583
if (bytes == (size_t) -2)
585
len += strlen (f + len);
589
if (bytes == (size_t) -1)
597
while (! mbsinit (&mbstate));
657
605
#else /* ! DO_MULTIBYTE */
659
607
/* Either multibyte encodings are not supported, they are
660
safe for formats, so any non-'%' byte can be copied through,
661
or this is the wide character version. */
608
safe for formats, so any non-'%' byte can be copied through,
609
or this is the wide character version. */
662
610
if (*f != L_('%'))
668
616
#endif /* ! DO_MULTIBYTE */
670
618
/* Check for flags that can modify a format. */
675
/* This influences the number formats. */
682
/* This changes textual output. */
623
/* This influences the number formats. */
630
/* This changes textual output. */
696
644
/* As a GNU extension we allow to specify the field width. */
697
645
if (ISDIGIT (*f))
703
width += *f - L_('0');
706
while (ISDIGIT (*f));
650
if (width > INT_MAX / 10
651
|| (width == INT_MAX / 10 && *f - L_('0') > INT_MAX % 10))
652
/* Avoid overflow. */
657
width += *f - L_('0');
661
while (ISDIGIT (*f));
709
664
/* Check for modifiers. */
722
677
/* Now do the specified format. */
723
678
format_char = *f;
724
679
switch (format_char)
726
681
#define DO_NUMBER(d, v) \
727
digits = width == -1 ? d : width; \
728
number_value = v; goto do_number
683
number_value = v; goto do_number
684
#define DO_SIGNED_NUMBER(d, negative, v) \
686
negative_number = negative; \
687
u_number_value = v; goto do_signed_number
689
/* The mask is not what you might think.
690
When the ordinal i'th bit is set, insert a colon
691
before the i'th digit of the time zone representation. */
692
#define DO_TZ_OFFSET(d, negative, mask, v) \
694
negative_number = negative; \
695
tz_colon_mask = mask; \
696
u_number_value = v; goto do_tz_offset
729
697
#define DO_NUMBER_SPACEPAD(d, v) \
730
digits = width == -1 ? d : width; \
731
number_value = v; goto do_number_spacepad
747
#if defined _NL_CURRENT || !HAVE_STRFTIME
748
cpy (aw_len, a_wkday);
751
goto underlying_strftime;
762
#if defined _NL_CURRENT || !HAVE_STRFTIME
763
cpy (STRLEN (f_wkday), f_wkday);
766
goto underlying_strftime;
770
case L_('h'): /* POSIX.2 extension. */
778
#if defined _NL_CURRENT || !HAVE_STRFTIME
779
cpy (am_len, a_month);
782
goto underlying_strftime;
793
#if defined _NL_CURRENT || !HAVE_STRFTIME
794
cpy (STRLEN (f_month), f_month);
797
goto underlying_strftime;
801
if (modifier == L_('O'))
804
if (! (modifier == 'E'
806
(const CHAR_T *) _NL_CURRENT (LC_TIME,
809
subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT));
812
goto underlying_strftime;
814
subfmt = L_("%a %b %e %H:%M:%S %Y");
820
CHAR_T *old_start = p;
821
size_t len = my_strftime (NULL, (size_t) -1, subfmt,
823
add (len, my_strftime (p, maxsize - i, subfmt,
827
while (old_start < p)
829
*old_start = TOUPPER ((UCHAR_T) *old_start);
835
#if HAVE_STRFTIME && ! (defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
838
/* The relevant information is available only via the
839
underlying strftime implementation, so use that. */
842
char ubuf[1024]; /* enough for any single format in practice */
844
/* Make sure we're calling the actual underlying strftime.
845
In some cases, config.h contains something like
846
"#define strftime rpl_strftime". */
699
number_value = v; goto do_number_spacepad
716
cpy (aw_len, a_wkday);
719
goto underlying_strftime;
731
cpy (STRLEN (f_wkday), f_wkday);
734
goto underlying_strftime;
747
cpy (am_len, a_month);
750
goto underlying_strftime;
762
cpy (STRLEN (f_month), f_month);
765
goto underlying_strftime;
769
if (modifier == L_('O'))
772
if (! (modifier == 'E'
774
(const CHAR_T *) _NL_CURRENT (LC_TIME,
777
subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT));
779
goto underlying_strftime;
784
size_t len = strftime_case_ (to_uppcase,
785
NULL, STRFTIME_ARG ((size_t) -1)
787
tp extra_args LOCALE_ARG);
788
add (len, strftime_case_ (to_uppcase, p,
789
STRFTIME_ARG (maxsize - i)
791
tp extra_args LOCALE_ARG));
795
#if !(defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
798
/* The relevant information is available only via the
799
underlying strftime implementation, so use that. */
802
char ubuf[1024]; /* enough for any single format in practice */
804
/* Make sure we're calling the actual underlying strftime.
805
In some cases, config.h contains something like
806
"#define strftime rpl_strftime". */
857
len = strftime (ubuf, sizeof ubuf, ufmt, tp);
858
if (len == 0 && ubuf[0] != '\0')
865
case L_('C'): /* POSIX.2 extension. */
866
if (modifier == L_('O'))
868
if (modifier == L_('E'))
870
#if HAVE_STRUCT_ERA_ENTRY
871
struct era_entry *era = _nl_get_era_entry (tp);
875
size_t len = __wcslen (era->era_wname);
876
cpy (len, era->era_wname);
878
size_t len = strlen (era->era_name);
879
cpy (len, era->era_name);
885
goto underlying_strftime;
891
int year = tp->tm_year + TM_YEAR_BASE;
892
DO_NUMBER (1, year / 100 - (year % 100 < 0));
896
if (modifier == L_('O'))
899
if (! (modifier == L_('E')
901
(const CHAR_T *)_NL_CURRENT (LC_TIME, NLW(ERA_D_FMT)))
903
subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT));
907
goto underlying_strftime;
912
case L_('D'): /* POSIX.2 extension. */
915
subfmt = L_("%m/%d/%y");
919
if (modifier == L_('E'))
922
DO_NUMBER (2, tp->tm_mday);
924
case L_('e'): /* POSIX.2 extension. */
925
if (modifier == L_('E'))
928
DO_NUMBER_SPACEPAD (2, tp->tm_mday);
930
/* All numeric formats set DIGITS and NUMBER_VALUE and then
931
jump to one of these two labels. */
934
/* Force `_' flag unless overwritten by `0' flag. */
939
/* Format the number according to the MODIFIER flag. */
941
if (modifier == L_('O') && 0 <= number_value)
944
/* Get the locale specific alternate representation of
945
the number NUMBER_VALUE. If none exist NULL is returned. */
947
const wchar_t *cp = _nl_get_walt_digit (number_value);
949
const char *cp = _nl_get_alt_digit (number_value);
954
size_t digitlen = STRLEN (cp);
963
goto underlying_strftime;
968
unsigned int u = number_value;
970
bufp = buf + sizeof (buf) / sizeof (buf[0]);
971
negative_number = number_value < 0;
977
*--bufp = u % 10 + L_('0');
978
while ((u /= 10) != 0);
981
do_number_sign_and_padding:
987
int padding = digits - (buf + (sizeof (buf) / sizeof (buf[0]))
992
while (0 < padding--)
997
bufp += negative_number;
998
while (0 < padding--)
1000
if (negative_number)
1005
cpy (buf + sizeof (buf) / sizeof (buf[0]) - bufp, bufp);
1011
subfmt = L_("%Y-%m-%d");
1015
if (modifier == L_('E'))
1018
DO_NUMBER (2, tp->tm_hour);
1021
if (modifier == L_('E'))
1024
DO_NUMBER (2, hour12);
1026
case L_('k'): /* GNU extension. */
1027
if (modifier == L_('E'))
1030
DO_NUMBER_SPACEPAD (2, tp->tm_hour);
1032
case L_('l'): /* GNU extension. */
1033
if (modifier == L_('E'))
1036
DO_NUMBER_SPACEPAD (2, hour12);
1039
if (modifier == L_('E'))
1042
DO_NUMBER (3, 1 + tp->tm_yday);
1045
if (modifier == L_('E'))
1048
DO_NUMBER (2, tp->tm_min);
1051
if (modifier == L_('E'))
1054
DO_NUMBER (2, tp->tm_mon + 1);
1056
case L_('N'): /* GNU extension. */
1057
if (modifier == L_('E'))
1063
/* Take an explicit width less than 9 as a precision. */
1065
for (j = width; j < 9; j++)
1069
DO_NUMBER (9, number_value);
1071
case L_('n'): /* POSIX.2 extension. */
1072
add (1, *p = L_('\n'));
1077
#if !defined _NL_CURRENT && HAVE_STRFTIME
1078
format_char = L_('p');
1088
#if defined _NL_CURRENT || !HAVE_STRFTIME
1092
goto underlying_strftime;
1095
case L_('R'): /* ISO C99 extension. */
1096
subfmt = L_("%H:%M");
1099
case L_('r'): /* POSIX.2 extension. */
1101
if (*(subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME,
1105
subfmt = L_("%I:%M:%S %p");
1109
if (modifier == L_('E'))
1112
DO_NUMBER (2, tp->tm_sec);
1114
case L_('s'): /* GNU extension. */
1122
/* Generate string value for T using time_t arithmetic;
1123
this works even if sizeof (long) < sizeof (time_t). */
1125
bufp = buf + sizeof (buf) / sizeof (buf[0]);
1126
negative_number = t < 0;
1133
if (negative_number)
1137
/* Adjust if division truncates to minus infinity. */
1138
if (0 < -1 % 10 && d < 0)
1145
*--bufp = d + L_('0');
1150
goto do_number_sign_and_padding;
1154
if (modifier == L_('O'))
1157
if (! (modifier == L_('E')
1159
(const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ERA_T_FMT)))
1161
subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT));
1165
goto underlying_strftime;
1170
case L_('T'): /* POSIX.2 extension. */
1171
subfmt = L_("%H:%M:%S");
1174
case L_('t'): /* POSIX.2 extension. */
1175
add (1, *p = L_('\t'));
1178
case L_('u'): /* POSIX.2 extension. */
1179
DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
1182
if (modifier == L_('E'))
1185
DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
1188
case L_('g'): /* ISO C99 extension. */
1189
case L_('G'): /* ISO C99 extension. */
1190
if (modifier == L_('E'))
1193
int year = tp->tm_year + TM_YEAR_BASE;
1194
int days = iso_week_days (tp->tm_yday, tp->tm_wday);
1198
/* This ISO week belongs to the previous year. */
1200
days = iso_week_days (tp->tm_yday + (365 + __isleap (year)),
1205
int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
1209
/* This ISO week belongs to the next year. */
1218
DO_NUMBER (2, (year % 100 + 100) % 100);
1221
DO_NUMBER (1, year);
1224
DO_NUMBER (2, days / 7 + 1);
1229
if (modifier == L_('E'))
1232
DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
1235
if (modifier == L_('E'))
1238
DO_NUMBER (1, tp->tm_wday);
1241
if (modifier == 'E')
1243
#if HAVE_STRUCT_ERA_ENTRY
1244
struct era_entry *era = _nl_get_era_entry (tp);
1247
# ifdef COMPILE_WIDE
1248
subfmt = era->era_wformat;
1250
subfmt = era->era_format;
1256
goto underlying_strftime;
1260
if (modifier == L_('O'))
1263
DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE);
1266
if (modifier == L_('E'))
1268
#if HAVE_STRUCT_ERA_ENTRY
1269
struct era_entry *era = _nl_get_era_entry (tp);
1272
int delta = tp->tm_year - era->start_date[0];
1273
DO_NUMBER (1, (era->offset
1274
+ delta * era->absolute_direction));
1278
goto underlying_strftime;
1282
DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100);
812
/* The space helps distinguish strftime failure from empty
820
len = strftime (ubuf, sizeof ubuf, ufmt, tp);
822
cpy (len - 1, ubuf + 1);
828
if (modifier == L_('O'))
830
if (modifier == L_('E'))
832
#if HAVE_STRUCT_ERA_ENTRY
833
struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
837
size_t len = __wcslen (era->era_wname);
838
cpy (len, era->era_wname);
840
size_t len = strlen (era->era_name);
841
cpy (len, era->era_name);
846
goto underlying_strftime;
851
int century = tp->tm_year / 100 + TM_YEAR_BASE / 100;
852
century -= tp->tm_year % 100 < 0 && 0 < century;
853
DO_SIGNED_NUMBER (2, tp->tm_year < - TM_YEAR_BASE, century);
857
if (modifier == L_('O'))
860
if (! (modifier == L_('E')
862
(const CHAR_T *)_NL_CURRENT (LC_TIME, NLW(ERA_D_FMT)))
864
subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT));
867
goto underlying_strftime;
872
subfmt = L_("%m/%d/%y");
876
if (modifier == L_('E'))
879
DO_NUMBER (2, tp->tm_mday);
882
if (modifier == L_('E'))
885
DO_NUMBER_SPACEPAD (2, tp->tm_mday);
887
/* All numeric formats set DIGITS and NUMBER_VALUE (or U_NUMBER_VALUE)
888
and then jump to one of these labels. */
891
always_output_a_sign = true;
895
/* Force `_' flag unless overridden by `0' or `-' flag. */
896
if (pad != L_('0') && pad != L_('-'))
900
/* Format NUMBER_VALUE according to the MODIFIER flag. */
901
negative_number = number_value < 0;
902
u_number_value = number_value;
905
always_output_a_sign = false;
909
/* Format U_NUMBER_VALUE according to the MODIFIER flag.
910
NEGATIVE_NUMBER is nonzero if the original number was
911
negative; in this case it was converted directly to
912
unsigned int (i.e., modulo (UINT_MAX + 1)) without
914
if (modifier == L_('O') && !negative_number)
917
/* Get the locale specific alternate representation of
918
the number. If none exist NULL is returned. */
919
const CHAR_T *cp = nl_get_alt_digit (u_number_value
924
size_t digitlen = STRLEN (cp);
932
goto underlying_strftime;
936
bufp = buf + sizeof (buf) / sizeof (buf[0]);
939
u_number_value = - u_number_value;
943
if (tz_colon_mask & 1)
946
*--bufp = u_number_value % 10 + L_('0');
947
u_number_value /= 10;
949
while (u_number_value != 0 || tz_colon_mask != 0);
951
do_number_sign_and_padding:
955
sign_char = (negative_number ? L_('-')
956
: always_output_a_sign ? L_('+')
966
int padding = digits - (buf + (sizeof (buf) / sizeof (buf[0]))
967
- bufp) - !!sign_char;
973
if ((size_t) padding >= maxsize - i)
977
memset_space (p, padding);
979
width = width > padding ? width - padding : 0;
985
if ((size_t) digits >= maxsize - i)
992
memset_zero (p, padding);
1004
cpy (buf + sizeof (buf) / sizeof (buf[0]) - bufp, bufp);
1010
subfmt = L_("%Y-%m-%d");
1014
if (modifier == L_('E'))
1017
DO_NUMBER (2, tp->tm_hour);
1020
if (modifier == L_('E'))
1023
DO_NUMBER (2, hour12);
1025
case L_('k'): /* GNU extension. */
1026
if (modifier == L_('E'))
1029
DO_NUMBER_SPACEPAD (2, tp->tm_hour);
1031
case L_('l'): /* GNU extension. */
1032
if (modifier == L_('E'))
1035
DO_NUMBER_SPACEPAD (2, hour12);
1038
if (modifier == L_('E'))
1041
DO_SIGNED_NUMBER (3, tp->tm_yday < -1, tp->tm_yday + 1U);
1044
if (modifier == L_('E'))
1047
DO_NUMBER (2, tp->tm_min);
1050
if (modifier == L_('E'))
1053
DO_SIGNED_NUMBER (2, tp->tm_mon < -1, tp->tm_mon + 1U);
1056
case L_('N'): /* GNU extension. */
1057
if (modifier == L_('E'))
1065
/* Take an explicit width less than 9 as a precision. */
1067
for (j = width; j < 9; j++)
1071
DO_NUMBER (width, number_value);
1081
format_char = L_('p');
1095
goto underlying_strftime;
1099
subfmt = L_("%H:%M");
1104
if (*(subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME,
1107
subfmt = L_("%I:%M:%S %p");
1110
goto underlying_strftime;
1114
if (modifier == L_('E'))
1117
DO_NUMBER (2, tp->tm_sec);
1119
case L_('s'): /* GNU extension. */
1127
/* Generate string value for T using time_t arithmetic;
1128
this works even if sizeof (long) < sizeof (time_t). */
1130
bufp = buf + sizeof (buf) / sizeof (buf[0]);
1131
negative_number = t < 0;
1137
*--bufp = (negative_number ? -d : d) + L_('0');
1142
always_output_a_sign = false;
1143
goto do_number_sign_and_padding;
1147
if (modifier == L_('O'))
1150
if (! (modifier == L_('E')
1152
(const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ERA_T_FMT)))
1154
subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT));
1157
goto underlying_strftime;
1160
subfmt = L_("%H:%M:%S");
1168
DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
1171
if (modifier == L_('E'))
1174
DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
1179
if (modifier == L_('E'))
1182
/* YEAR is a leap year if and only if (tp->tm_year + TM_YEAR_BASE)
1183
is a leap year, except that YEAR and YEAR - 1 both work
1184
correctly even when (tp->tm_year + TM_YEAR_BASE) would
1186
int year = (tp->tm_year
1188
? TM_YEAR_BASE % 400
1189
: TM_YEAR_BASE % 400 - 400));
1190
int year_adjust = 0;
1191
int days = iso_week_days (tp->tm_yday, tp->tm_wday);
1195
/* This ISO week belongs to the previous year. */
1197
days = iso_week_days (tp->tm_yday + (365 + __isleap (year - 1)),
1202
int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
1206
/* This ISO week belongs to the next year. */
1216
int yy = (tp->tm_year % 100 + year_adjust) % 100;
1217
DO_NUMBER (2, (0 <= yy
1219
: tp->tm_year < -TM_YEAR_BASE - year_adjust
1225
DO_SIGNED_NUMBER (4, tp->tm_year < -TM_YEAR_BASE - year_adjust,
1226
(tp->tm_year + (unsigned int) TM_YEAR_BASE
1230
DO_NUMBER (2, days / 7 + 1);
1235
if (modifier == L_('E'))
1238
DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
1241
if (modifier == L_('E'))
1244
DO_NUMBER (1, tp->tm_wday);
1247
if (modifier == 'E')
1249
#if HAVE_STRUCT_ERA_ENTRY
1250
struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1253
# ifdef COMPILE_WIDE
1254
subfmt = era->era_wformat;
1256
subfmt = era->era_format;
1261
goto underlying_strftime;
1264
if (modifier == L_('O'))
1267
DO_SIGNED_NUMBER (4, tp->tm_year < -TM_YEAR_BASE,
1268
tp->tm_year + (unsigned int) TM_YEAR_BASE);
1271
if (modifier == L_('E'))
1273
#if HAVE_STRUCT_ERA_ENTRY
1274
struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1277
int delta = tp->tm_year - era->start_date[0];
1278
DO_NUMBER (1, (era->offset
1279
+ delta * era->absolute_direction));
1282
goto underlying_strftime;
1287
int yy = tp->tm_year % 100;
1289
yy = tp->tm_year < - TM_YEAR_BASE ? -yy : yy + 100;
1291
1300
#if HAVE_TZNAME
1292
/* The tzset() call might have changed the value. */
1293
if (!(zone && *zone) && tp->tm_isdst >= 0)
1294
zone = tzname[tp->tm_isdst];
1301
/* The tzset() call might have changed the value. */
1302
if (!(zone && *zone) && tp->tm_isdst >= 0)
1303
zone = tzname[tp->tm_isdst != 0];
1297
zone = ""; /* POSIX.2 requires the empty string here. */
1299
1308
#ifdef COMPILE_WIDE
1301
/* The zone string is always given in multibyte form. We have
1302
to transform it first. */
1305
widen (zone, wczone, len);
1310
/* The zone string is always given in multibyte form. We have
1311
to transform it first. */
1314
widen (zone, wczone, len);
1309
cpy (strlen (zone), zone);
1318
cpy (strlen (zone), zone);
1313
case L_('z'): /* ISO C99 extension. */
1314
if (tp->tm_isdst < 0)
1323
/* :, ::, and ::: are valid only just before 'z'.
1324
:::: etc. are rejected later. */
1325
for (colons = 1; f[colons] == L_(':'); colons++)
1327
if (f[colons] != L_('z'))
1330
goto do_z_conversion;
1336
if (tp->tm_isdst < 0)
1319
1344
#if HAVE_TM_GMTOFF
1320
diff = tp->tm_gmtoff;
1345
diff = tp->tm_gmtoff;
1333
if (lt == (time_t) -1)
1335
/* mktime returns -1 for errors, but -1 is also a
1336
valid time_t value. Check whether an error really
1340
if (! my_strftime_localtime_r (<, &tm)
1341
|| ((ltm.tm_sec ^ tm.tm_sec)
1342
| (ltm.tm_min ^ tm.tm_min)
1343
| (ltm.tm_hour ^ tm.tm_hour)
1344
| (ltm.tm_mday ^ tm.tm_mday)
1345
| (ltm.tm_mon ^ tm.tm_mon)
1346
| (ltm.tm_year ^ tm.tm_year)))
1350
if (! my_strftime_gmtime_r (<, >m))
1353
diff = tm_diff (<m, >m);
1358
if (lt == (time_t) -1)
1360
/* mktime returns -1 for errors, but -1 is also a
1361
valid time_t value. Check whether an error really
1365
if (! __localtime_r (<, &tm)
1366
|| ((ltm.tm_sec ^ tm.tm_sec)
1367
| (ltm.tm_min ^ tm.tm_min)
1368
| (ltm.tm_hour ^ tm.tm_hour)
1369
| (ltm.tm_mday ^ tm.tm_mday)
1370
| (ltm.tm_mon ^ tm.tm_mon)
1371
| (ltm.tm_year ^ tm.tm_year)))
1375
if (! __gmtime_r (<, >m))
1378
diff = tm_diff (<m, >m);
1359
add (1, *p = L_('-'));
1363
add (1, *p = L_('+'));
1366
DO_NUMBER (4, (diff / 60) * 100 + diff % 60);
1369
case L_('\0'): /* GNU extension: % at end of format. */
1373
/* Unknown format; output the format, including the '%',
1374
since this is most likely the right thing to do if a
1375
multibyte string has been misparsed. */
1379
for (flen = 1; f[1 - flen] != L_('%'); flen++)
1381
cpy (flen, &f[1 - flen]);
1382
hour_diff = diff / 60 / 60;
1383
min_diff = diff / 60 % 60;
1384
sec_diff = diff % 60;
1389
DO_TZ_OFFSET (5, diff < 0, 0, hour_diff * 100 + min_diff);
1391
case 1: tz_hh_mm: /* +hh:mm */
1392
DO_TZ_OFFSET (6, diff < 0, 04, hour_diff * 100 + min_diff);
1394
case 2: tz_hh_mm_ss: /* +hh:mm:ss */
1395
DO_TZ_OFFSET (9, diff < 0, 024,
1396
hour_diff * 10000 + min_diff * 100 + sec_diff);
1398
case 3: /* +hh if possible, else +hh:mm, else +hh:mm:ss */
1403
DO_TZ_OFFSET (3, diff < 0, 0, hour_diff);
1410
case L_('\0'): /* GNU extension: % at end of format. */
1414
/* Unknown format; output the format, including the '%',
1415
since this is most likely the right thing to do if a
1416
multibyte string has been misparsed. */
1420
for (flen = 1; f[1 - flen] != L_('%'); flen++)
1422
cpy (flen, &f[1 - flen]);
1387
1429
if (p && maxsize != 0)
1436
/* Write information from TP into S according to the format
1437
string FORMAT, writing no more that MAXSIZE characters
1438
(including the terminating '\0') and returning number of
1439
characters written. If S is NULL, nothing will be written
1440
anywhere, so to determine how many characters would be
1441
written, use NULL for S and (size_t) -1 for MAXSIZE. */
1443
my_strftime (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
1444
const CHAR_T *format,
1445
const struct tm *tp extra_args_spec LOCALE_PARAM_PROTO)
1447
return strftime_case_ (false, s, STRFTIME_ARG (maxsize)
1448
format, tp extra_args LOCALE_ARG);
1451
#if defined _LIBC && ! FPRINTFTIME
1452
libc_hidden_def (my_strftime)
1456
#if defined emacs && ! FPRINTFTIME
1394
1457
/* For Emacs we have a separate interface which corresponds to the normal
1395
1458
strftime function plus the ut argument, but without the ns argument. */
1397
emacs_strftimeu (s, maxsize, format, tp, ut)
1401
const struct tm *tp;
1460
emacs_strftimeu (char *s, size_t maxsize, const char *format,
1461
const struct tm *tp, int ut)
1404
1463
return my_strftime (s, maxsize, format, tp, ut, 0);