]> code.delx.au - gnu-emacs/blob - src/strftime.c
(shrink_regexp_cache): Use xrealloc.
[gnu-emacs] / src / strftime.c
1 /* Copyright (C) 1991,92,93,94,95,96,97,98,99,2000,2003
2 Free Software Foundation, Inc.
3
4 This file is part of the GNU Emacs.
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public
17 License along with the GNU C Library; see the file COPYING.LIB. If not,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
24
25 #ifdef _LIBC
26 # define HAVE_LIMITS_H 1
27 # define HAVE_MBLEN 1
28 # define HAVE_MBRLEN 1
29 # define HAVE_STRUCT_ERA_ENTRY 1
30 # define HAVE_TM_GMTOFF 1
31 # define HAVE_TM_ZONE 1
32 # define HAVE_TZNAME 1
33 # define HAVE_TZSET 1
34 # define MULTIBYTE_IS_FORMAT_SAFE 1
35 # define STDC_HEADERS 1
36 # include "../locale/localeinfo.h"
37 #endif
38
39 #if defined emacs && !defined HAVE_BCOPY
40 # define HAVE_MEMCPY 1
41 #endif
42
43 #include <ctype.h>
44 #include <sys/types.h> /* Some systems define `time_t' here. */
45
46 #ifdef TIME_WITH_SYS_TIME
47 # include <sys/time.h>
48 # include <time.h>
49 #else
50 # ifdef HAVE_SYS_TIME_H
51 # include <sys/time.h>
52 # else
53 # include <time.h>
54 # endif
55 #endif
56 #if HAVE_TZNAME
57 #ifndef USE_CRT_DLL
58 extern char *tzname[];
59 #endif
60 #endif
61
62 /* Do multibyte processing if multibytes are supported, unless
63 multibyte sequences are safe in formats. Multibyte sequences are
64 safe if they cannot contain byte sequences that look like format
65 conversion specifications. The GNU C Library uses UTF8 multibyte
66 encoding, which is safe for formats, but strftime.c can be used
67 with other C libraries that use unsafe encodings. */
68 #define DO_MULTIBYTE (HAVE_MBLEN && ! MULTIBYTE_IS_FORMAT_SAFE)
69
70 #if DO_MULTIBYTE
71 # if HAVE_MBRLEN
72 # include <wchar.h>
73 # if __hpux
74 # include <sys/_mbstate_t.h>
75 # endif
76 # if !defined (mbsinit) && !defined (HAVE_MBSINIT)
77 # define mbsinit(ps) 1
78 # endif /* !defined (mbsinit) && !defined (HAVE_MBSINIT) */
79 # else
80 /* Simulate mbrlen with mblen as best we can. */
81 # define mbstate_t int
82 # define mbrlen(s, n, ps) mblen (s, n)
83 # define mbsinit(ps) (*(ps) == 0)
84 # endif
85 static const mbstate_t mbstate_zero;
86 #endif
87
88 #ifdef HAVE_LIMITS_H
89 # include <limits.h>
90 #endif
91
92 #ifdef STDC_HEADERS
93 # include <stddef.h>
94 # include <stdlib.h>
95 #else
96 # ifndef HAVE_MEMCPY
97 # define memcpy(d, s, n) bcopy ((s), (d), (n))
98 # endif
99 #endif
100
101 #ifdef COMPILE_WIDE
102 # include <endian.h>
103 # define CHAR_T wchar_t
104 # define UCHAR_T unsigned int
105 # define L_(Str) L##Str
106 # define NLW(Sym) _NL_W##Sym
107
108 # define MEMCPY(d, s, n) __wmemcpy (d, s, n)
109 # define STRLEN(s) __wcslen (s)
110
111 #else
112 # define CHAR_T char
113 # define UCHAR_T unsigned char
114 # define L_(Str) Str
115 # define NLW(Sym) Sym
116
117 # if !defined STDC_HEADERS && !defined HAVE_MEMCPY
118 # define MEMCPY(d, s, n) bcopy ((s), (d), (n))
119 # else
120 # define MEMCPY(d, s, n) memcpy ((d), (s), (n))
121 # endif
122 # define STRLEN(s) strlen (s)
123
124 # ifdef _LIBC
125 # define MEMPCPY(d, s, n) __mempcpy (d, s, n)
126 # else
127 # ifndef HAVE_MEMPCPY
128 # define MEMPCPY(d, s, n) ((void *) ((char *) memcpy (d, s, n) + (n)))
129 # endif
130 # endif
131 #endif
132
133 #ifndef __P
134 # if defined emacs && defined PROTOTYPES
135 # define __P(args) args
136 # elif defined __GNUC__ || (defined __STDC__ && __STDC__)
137 # define __P(args) args
138 # else
139 # define __P(args) ()
140 # endif /* GCC. */
141 #endif /* Not __P. */
142
143 #ifndef PTR
144 # ifdef __STDC__
145 # define PTR void *
146 # else
147 # define PTR char *
148 # endif
149 #endif
150
151 #ifndef CHAR_BIT
152 # define CHAR_BIT 8
153 #endif
154
155 #ifndef NULL
156 # define NULL 0
157 #endif
158
159 #define TYPE_SIGNED(t) ((t) -1 < 0)
160
161 /* Bound on length of the string representing an integer value of type t.
162 Subtract one for the sign bit if t is signed;
163 302 / 1000 is log10 (2) rounded up;
164 add one for integer division truncation;
165 add one more for a minus sign if t is signed. */
166 #define INT_STRLEN_BOUND(t) \
167 ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 + 1 + TYPE_SIGNED (t))
168
169 #define TM_YEAR_BASE 1900
170
171 #ifndef __isleap
172 /* Nonzero if YEAR is a leap year (every 4 years,
173 except every 100th isn't, and every 400th is). */
174 # define __isleap(year) \
175 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
176 #endif
177
178
179 #ifdef _LIBC
180 # define my_strftime_gmtime_r __gmtime_r
181 # define my_strftime_localtime_r __localtime_r
182 # define tzname __tzname
183 # define tzset __tzset
184 #else
185
186 /* If we're a strftime substitute in a GNU program, then prefer gmtime
187 to gmtime_r, since many gmtime_r implementations are buggy.
188 Similarly for localtime_r. */
189
190 # if ! HAVE_TM_GMTOFF
191 static struct tm *my_strftime_gmtime_r __P ((const time_t *, struct tm *));
192 static struct tm *
193 my_strftime_gmtime_r (t, tp)
194 const time_t *t;
195 struct tm *tp;
196 {
197 struct tm *l = gmtime (t);
198 if (! l)
199 return 0;
200 *tp = *l;
201 return tp;
202 }
203
204 static struct tm *my_strftime_localtime_r __P ((const time_t *, struct tm *));
205 static struct tm *
206 my_strftime_localtime_r (t, tp)
207 const time_t *t;
208 struct tm *tp;
209 {
210 struct tm *l = localtime (t);
211 if (! l)
212 return 0;
213 *tp = *l;
214 return tp;
215 }
216 # endif /* ! HAVE_TM_GMTOFF */
217
218 #endif /* ! defined _LIBC */
219
220
221 #if !defined memset && !defined HAVE_MEMSET && !defined _LIBC
222 /* Some systems lack the `memset' function and we don't want to
223 introduce additional dependencies. */
224 /* The SGI compiler reportedly barfs on the trailing null
225 if we use a string constant as the initializer. 28 June 1997, rms. */
226 static const CHAR_T spaces[16] = /* " " */
227 {
228 L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),
229 L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' ')
230 };
231 static const CHAR_T zeroes[16] = /* "0000000000000000" */
232 {
233 L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),
234 L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0')
235 };
236
237 # define memset_space(P, Len) \
238 do { \
239 int _len = (Len); \
240 \
241 do \
242 { \
243 int _this = _len > 16 ? 16 : _len; \
244 (P) = MEMPCPY ((P), spaces, _this * sizeof (CHAR_T)); \
245 _len -= _this; \
246 } \
247 while (_len > 0); \
248 } while (0)
249
250 # define memset_zero(P, Len) \
251 do { \
252 int _len = (Len); \
253 \
254 do \
255 { \
256 int _this = _len > 16 ? 16 : _len; \
257 (P) = MEMPCPY ((P), zeroes, _this * sizeof (CHAR_T)); \
258 _len -= _this; \
259 } \
260 while (_len > 0); \
261 } while (0)
262 #else
263 # ifdef COMPILE_WIDE
264 # define memset_space(P, Len) (wmemset ((P), L' ', (Len)), (P) += (Len))
265 # define memset_zero(P, Len) (wmemset ((P), L'0', (Len)), (P) += (Len))
266 # else
267 # define memset_space(P, Len) (memset ((P), ' ', (Len)), (P) += (Len))
268 # define memset_zero(P, Len) (memset ((P), '0', (Len)), (P) += (Len))
269 # endif
270 #endif
271
272 #define add(n, f) \
273 do \
274 { \
275 int _n = (n); \
276 int _delta = width - _n; \
277 int _incr = _n + (_delta > 0 ? _delta : 0); \
278 if (i + _incr >= maxsize) \
279 return 0; \
280 if (p) \
281 { \
282 if (_delta > 0) \
283 { \
284 if (pad == L_('0')) \
285 memset_zero (p, _delta); \
286 else \
287 memset_space (p, _delta); \
288 } \
289 f; \
290 p += _n; \
291 } \
292 i += _incr; \
293 } while (0)
294
295 #define cpy(n, s) \
296 add ((n), \
297 if (to_lowcase) \
298 memcpy_lowcase (p, (s), _n); \
299 else if (to_uppcase) \
300 memcpy_uppcase (p, (s), _n); \
301 else \
302 MEMCPY ((PTR) p, (PTR) (s), _n))
303
304 #ifdef COMPILE_WIDE
305 # define widen(os, ws, l) \
306 { \
307 mbstate_t __st; \
308 const char *__s = os; \
309 memset (&__st, '\0', sizeof (__st)); \
310 l = __mbsrtowcs (NULL, &__s, 0, &__st); \
311 ws = alloca ((l + 1) * sizeof (wchar_t)); \
312 (void) __mbsrtowcs (ws, &__s, l, &__st); \
313 }
314 #endif
315
316
317 #ifdef COMPILE_WIDE
318 # define TOUPPER(Ch) towupper (Ch)
319 # define TOLOWER(Ch) towlower (Ch)
320 #else
321 # ifdef _LIBC
322 # define TOUPPER(Ch) toupper (Ch)
323 # define TOLOWER(Ch) tolower (Ch)
324 # else
325 # define TOUPPER(Ch) (islower (Ch) ? toupper (Ch) : (Ch))
326 # define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))
327 # endif
328 #endif
329 /* We don't use `isdigit' here since the locale dependent
330 interpretation is not what we want here. We only need to accept
331 the arabic digits in the ASCII range. One day there is perhaps a
332 more reliable way to accept other sets of digits. */
333 #define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9)
334
335 static CHAR_T *memcpy_lowcase __P ((CHAR_T *dest, const CHAR_T *src,
336 size_t len));
337
338 static CHAR_T *
339 memcpy_lowcase (dest, src, len)
340 CHAR_T *dest;
341 const CHAR_T *src;
342 size_t len;
343 {
344 while (len-- > 0)
345 dest[len] = TOLOWER ((UCHAR_T) src[len]);
346 return dest;
347 }
348
349 static CHAR_T *memcpy_uppcase __P ((CHAR_T *dest, const CHAR_T *src,
350 size_t len));
351
352 static CHAR_T *
353 memcpy_uppcase (dest, src, len)
354 CHAR_T *dest;
355 const CHAR_T *src;
356 size_t len;
357 {
358 while (len-- > 0)
359 dest[len] = TOUPPER ((UCHAR_T) src[len]);
360 return dest;
361 }
362
363
364 #if ! HAVE_TM_GMTOFF
365 /* Yield the difference between *A and *B,
366 measured in seconds, ignoring leap seconds. */
367 # define tm_diff ftime_tm_diff
368 static int tm_diff __P ((const struct tm *, const struct tm *));
369 static int
370 tm_diff (a, b)
371 const struct tm *a;
372 const struct tm *b;
373 {
374 /* Compute intervening leap days correctly even if year is negative.
375 Take care to avoid int overflow in leap day calculations,
376 but it's OK to assume that A and B are close to each other. */
377 int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
378 int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
379 int a100 = a4 / 25 - (a4 % 25 < 0);
380 int b100 = b4 / 25 - (b4 % 25 < 0);
381 int a400 = a100 >> 2;
382 int b400 = b100 >> 2;
383 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
384 int years = a->tm_year - b->tm_year;
385 int days = (365 * years + intervening_leap_days
386 + (a->tm_yday - b->tm_yday));
387 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
388 + (a->tm_min - b->tm_min))
389 + (a->tm_sec - b->tm_sec));
390 }
391 #endif /* ! HAVE_TM_GMTOFF */
392
393
394
395 /* The number of days from the first day of the first ISO week of this
396 year to the year day YDAY with week day WDAY. ISO weeks start on
397 Monday; the first ISO week has the year's first Thursday. YDAY may
398 be as small as YDAY_MINIMUM. */
399 #define ISO_WEEK_START_WDAY 1 /* Monday */
400 #define ISO_WEEK1_WDAY 4 /* Thursday */
401 #define YDAY_MINIMUM (-366)
402 static int iso_week_days __P ((int, int));
403 #ifdef __GNUC__
404 __inline__
405 #endif
406 static int
407 iso_week_days (yday, wday)
408 int yday;
409 int wday;
410 {
411 /* Add enough to the first operand of % to make it nonnegative. */
412 int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
413 return (yday
414 - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
415 + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
416 }
417
418
419 #if !(defined _NL_CURRENT || HAVE_STRFTIME)
420 static CHAR_T const weekday_name[][10] =
421 {
422 L_("Sunday"), L_("Monday"), L_("Tuesday"), L_("Wednesday"),
423 L_("Thursday"), L_("Friday"), L_("Saturday")
424 };
425 static CHAR_T const month_name[][10] =
426 {
427 L_("January"), L_("February"), L_("March"), L_("April"), L_("May"),
428 L_("June"), L_("July"), L_("August"), L_("September"), L_("October"),
429 L_("November"), L_("December")
430 };
431 #endif
432
433
434 #ifdef emacs
435 # define my_strftime emacs_strftimeu
436 # define ut_argument , ut
437 # define ut_argument_spec int ut;
438 # define ut_argument_spec_iso , int ut
439 #else
440 # ifdef COMPILE_WIDE
441 # define my_strftime wcsftime
442 # else
443 # define my_strftime strftime
444 # endif
445 # define ut_argument
446 # define ut_argument_spec
447 # define ut_argument_spec_iso
448 /* We don't have this information in general. */
449 # define ut 0
450 #endif
451
452 #if !defined _LIBC && !defined(WINDOWSNT) && HAVE_TZNAME && HAVE_TZSET
453 /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime.
454 Work around this bug by copying *tp before it might be munged. */
455 size_t _strftime_copytm __P ((char *, size_t, const char *,
456 const struct tm * ut_argument_spec_iso));
457 size_t
458 my_strftime (s, maxsize, format, tp ut_argument)
459 CHAR_T *s;
460 size_t maxsize;
461 const CHAR_T *format;
462 const struct tm *tp;
463 ut_argument_spec
464 {
465 struct tm tmcopy;
466 tmcopy = *tp;
467 return _strftime_copytm (s, maxsize, format, &tmcopy ut_argument);
468 }
469 # undef my_strftime
470 # define my_strftime _strftime_copytm
471 #endif
472
473
474 /* Write information from TP into S according to the format
475 string FORMAT, writing no more that MAXSIZE characters
476 (including the terminating '\0') and returning number of
477 characters written. If S is NULL, nothing will be written
478 anywhere, so to determine how many characters would be
479 written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */
480 size_t
481 my_strftime (s, maxsize, format, tp ut_argument)
482 CHAR_T *s;
483 size_t maxsize;
484 const CHAR_T *format;
485 const struct tm *tp;
486 ut_argument_spec
487 {
488 int hour12 = tp->tm_hour;
489 #ifdef _NL_CURRENT
490 /* We cannot make the following values variables since we must delay
491 the evaluation of these values until really needed since some
492 expressions might not be valid in every situation. The `struct tm'
493 might be generated by a strptime() call that initialized
494 only a few elements. Dereference the pointers only if the format
495 requires this. Then it is ok to fail if the pointers are invalid. */
496 # define a_wkday \
497 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))
498 # define f_wkday \
499 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))
500 # define a_month \
501 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))
502 # define f_month \
503 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))
504 # define ampm \
505 ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \
506 ? NLW(PM_STR) : NLW(AM_STR)))
507
508 # define aw_len STRLEN (a_wkday)
509 # define am_len STRLEN (a_month)
510 # define ap_len STRLEN (ampm)
511 #else
512 # if !HAVE_STRFTIME
513 # define f_wkday (weekday_name[tp->tm_wday])
514 # define f_month (month_name[tp->tm_mon])
515 # define a_wkday f_wkday
516 # define a_month f_month
517 # define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11))
518
519 size_t aw_len = 3;
520 size_t am_len = 3;
521 size_t ap_len = 2;
522 # endif
523 #endif
524 const char *zone;
525 size_t i = 0;
526 CHAR_T *p = s;
527 const CHAR_T *f;
528
529 zone = NULL;
530 #if HAVE_TM_ZONE
531 /* The POSIX test suite assumes that setting
532 the environment variable TZ to a new value before calling strftime()
533 will influence the result (the %Z format) even if the information in
534 TP is computed with a totally different time zone.
535 This is bogus: though POSIX allows bad behavior like this,
536 POSIX does not require it. Do the right thing instead. */
537 zone = (const char *) tp->tm_zone;
538 #endif
539 #if HAVE_TZNAME
540 if (ut)
541 {
542 if (! (zone && *zone))
543 zone = "UTC";
544 }
545 else
546 {
547 /* POSIX.1 8.1.1 requires that whenever strftime() is called, the
548 time zone names contained in the external variable `tzname' shall
549 be set as if the tzset() function had been called. */
550 # if HAVE_TZSET
551 tzset ();
552 # endif
553 }
554 #endif
555
556 if (hour12 > 12)
557 hour12 -= 12;
558 else
559 if (hour12 == 0)
560 hour12 = 12;
561
562 for (f = format; *f != '\0'; ++f)
563 {
564 int pad = 0; /* Padding for number ('-', '_', or 0). */
565 int modifier; /* Field modifier ('E', 'O', or 0). */
566 int digits; /* Max digits for numeric format. */
567 int number_value; /* Numeric value to be printed. */
568 int negative_number; /* 1 if the number is negative. */
569 const CHAR_T *subfmt;
570 CHAR_T *bufp;
571 CHAR_T buf[1 + (sizeof (int) < sizeof (time_t)
572 ? INT_STRLEN_BOUND (time_t)
573 : INT_STRLEN_BOUND (int))];
574 int width = -1;
575 int to_lowcase = 0;
576 int to_uppcase = 0;
577 int change_case = 0;
578 int format_char;
579
580 #if DO_MULTIBYTE && !defined COMPILE_WIDE
581 switch (*f)
582 {
583 case L_('%'):
584 break;
585
586 case L_('\b'): case L_('\t'): case L_('\n'):
587 case L_('\v'): case L_('\f'): case L_('\r'):
588 case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
589 case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
590 case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
591 case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
592 case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
593 case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
594 case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
595 case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
596 case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
597 case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
598 case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
599 case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
600 case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
601 case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
602 case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
603 case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
604 case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
605 case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
606 case L_('~'):
607 /* The C Standard requires these 97 characters (plus '%', `\a') to
608 be in the basic execution character set. None of these
609 characters can start a multibyte sequence, so they need
610 not be analyzed further. Some old compilers object to
611 `\a', so don't bother optimizing for it. */
612 add (1, *p = *f);
613 continue;
614
615 default:
616 /* Copy this multibyte sequence until we reach its end, find
617 an error, or come back to the initial shift state. */
618 {
619 mbstate_t mbstate = mbstate_zero;
620 size_t len = 0;
621
622 do
623 {
624 size_t bytes = mbrlen (f + len, (size_t) -1, &mbstate);
625
626 if (bytes == 0)
627 break;
628
629 if (bytes == (size_t) -2)
630 {
631 len += strlen (f + len);
632 break;
633 }
634
635 if (bytes == (size_t) -1)
636 {
637 len++;
638 break;
639 }
640
641 len += bytes;
642 }
643 while (! mbsinit (&mbstate));
644
645 cpy (len, f);
646 f += len - 1;
647 continue;
648 }
649 }
650
651 #else /* ! DO_MULTIBYTE */
652
653 /* Either multibyte encodings are not supported, they are
654 safe for formats, so any non-'%' byte can be copied through,
655 or this is the wide character version. */
656 if (*f != L_('%'))
657 {
658 add (1, *p = *f);
659 continue;
660 }
661
662 #endif /* ! DO_MULTIBYTE */
663
664 /* Check for flags that can modify a format. */
665 while (1)
666 {
667 switch (*++f)
668 {
669 /* This influences the number formats. */
670 case L_('_'):
671 case L_('-'):
672 case L_('0'):
673 pad = *f;
674 continue;
675
676 /* This changes textual output. */
677 case L_('^'):
678 to_uppcase = 1;
679 continue;
680 case L_('#'):
681 change_case = 1;
682 continue;
683
684 default:
685 break;
686 }
687 break;
688 }
689
690 /* As a GNU extension we allow to specify the field width. */
691 if (ISDIGIT (*f))
692 {
693 width = 0;
694 do
695 {
696 width *= 10;
697 width += *f - L_('0');
698 ++f;
699 }
700 while (ISDIGIT (*f));
701 }
702
703 /* Check for modifiers. */
704 switch (*f)
705 {
706 case L_('E'):
707 case L_('O'):
708 modifier = *f++;
709 break;
710
711 default:
712 modifier = 0;
713 break;
714 }
715
716 /* Now do the specified format. */
717 format_char = *f;
718 switch (format_char)
719 {
720 #define DO_NUMBER(d, v) \
721 digits = width == -1 ? d : width; \
722 number_value = v; goto do_number
723 #define DO_NUMBER_SPACEPAD(d, v) \
724 digits = width == -1 ? d : width; \
725 number_value = v; goto do_number_spacepad
726
727 case L_('%'):
728 if (modifier != 0)
729 goto bad_format;
730 add (1, *p = *f);
731 break;
732
733 case L_('a'):
734 if (modifier != 0)
735 goto bad_format;
736 if (change_case)
737 {
738 to_uppcase = 1;
739 to_lowcase = 0;
740 }
741 #if defined _NL_CURRENT || !HAVE_STRFTIME
742 cpy (aw_len, a_wkday);
743 break;
744 #else
745 goto underlying_strftime;
746 #endif
747
748 case 'A':
749 if (modifier != 0)
750 goto bad_format;
751 if (change_case)
752 {
753 to_uppcase = 1;
754 to_lowcase = 0;
755 }
756 #if defined _NL_CURRENT || !HAVE_STRFTIME
757 cpy (STRLEN (f_wkday), f_wkday);
758 break;
759 #else
760 goto underlying_strftime;
761 #endif
762
763 case L_('b'):
764 case L_('h'): /* POSIX.2 extension. */
765 if (change_case)
766 {
767 to_uppcase = 1;
768 to_lowcase = 0;
769 }
770 if (modifier != 0)
771 goto bad_format;
772 #if defined _NL_CURRENT || !HAVE_STRFTIME
773 cpy (am_len, a_month);
774 break;
775 #else
776 goto underlying_strftime;
777 #endif
778
779 case L_('B'):
780 if (modifier != 0)
781 goto bad_format;
782 if (change_case)
783 {
784 to_uppcase = 1;
785 to_lowcase = 0;
786 }
787 #if defined _NL_CURRENT || !HAVE_STRFTIME
788 cpy (STRLEN (f_month), f_month);
789 break;
790 #else
791 goto underlying_strftime;
792 #endif
793
794 case L_('c'):
795 if (modifier == L_('O'))
796 goto bad_format;
797 #ifdef _NL_CURRENT
798 if (! (modifier == 'E'
799 && (*(subfmt = (CHAR_T *) _NL_CURRENT (LC_TIME,
800 NLW(ERA_D_T_FMT)))
801 != '\0')))
802 subfmt = (CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT));
803 #else
804 # if HAVE_STRFTIME
805 goto underlying_strftime;
806 # else
807 subfmt = L_("%a %b %e %H:%M:%S %Y");
808 # endif
809 #endif
810
811 subformat:
812 {
813 CHAR_T *old_start = p;
814 size_t len = my_strftime (NULL, (size_t) -1, subfmt, tp, 0);
815 add (len, my_strftime (p, maxsize - i, subfmt, tp, 0));
816
817 if (to_uppcase)
818 while (old_start < p)
819 {
820 *old_start = TOUPPER ((UCHAR_T) *old_start);
821 ++old_start;
822 }
823 }
824 break;
825
826 #if HAVE_STRFTIME && ! (defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
827 underlying_strftime:
828 {
829 /* The relevant information is available only via the
830 underlying strftime implementation, so use that. */
831 char ufmt[4];
832 char *u = ufmt;
833 char ubuf[1024]; /* enough for any single format in practice */
834 size_t len;
835 /* Make sure we're calling the actual underlying strftime.
836 In some cases, config.h contains something like
837 "#define strftime rpl_strftime". */
838 # ifdef strftime
839 # undef strftime
840 size_t strftime ();
841 # endif
842
843 #ifdef STRFTIME_NO_POSIX2
844 /* Some system libraries do not support the POSIX.2 extensions.
845 In those cases, convert %h to %b, and strip modifiers. */
846 modifier = 0;
847 if (format_char == 'h')
848 format_char = 'b';
849 #endif
850 *u++ = '%';
851 if (modifier != 0)
852 *u++ = modifier;
853 *u++ = format_char;
854 *u = '\0';
855 len = strftime (ubuf, sizeof ubuf, ufmt, tp);
856 if (len == 0 && ubuf[0] != '\0')
857 return 0;
858 cpy (len, ubuf);
859 }
860 break;
861 #endif
862
863 case L_('C'): /* POSIX.2 extension. */
864 if (modifier == L_('O'))
865 goto bad_format;
866 if (modifier == L_('E'))
867 {
868 #if HAVE_STRUCT_ERA_ENTRY
869 struct era_entry *era = _nl_get_era_entry (tp);
870 if (era)
871 {
872 # ifdef COMPILE_WIDE
873 size_t len = __wcslen (era->era_wname);
874 cpy (len, era->era_wname);
875 # else
876 size_t len = strlen (era->era_name);
877 cpy (len, era->era_name);
878 # endif
879 break;
880 }
881 #else
882 # if HAVE_STRFTIME
883 goto underlying_strftime;
884 # endif
885 #endif
886 }
887
888 {
889 int year = tp->tm_year + TM_YEAR_BASE;
890 DO_NUMBER (1, year / 100 - (year % 100 < 0));
891 }
892
893 case L_('x'):
894 if (modifier == L_('O'))
895 goto bad_format;
896 #ifdef _NL_CURRENT
897 if (! (modifier == L_('E')
898 && (*(subfmt = (CHAR_T *)_NL_CURRENT (LC_TIME,
899 NLW(ERA_D_FMT)))
900 != L_('\0'))))
901 subfmt = (CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT));
902 goto subformat;
903 #else
904 # if HAVE_STRFTIME
905 goto underlying_strftime;
906 # else
907 /* Fall through. */
908 # endif
909 #endif
910 case L_('D'): /* POSIX.2 extension. */
911 if (modifier != 0)
912 goto bad_format;
913 subfmt = L_("%m/%d/%y");
914 goto subformat;
915
916 case L_('d'):
917 if (modifier == L_('E'))
918 goto bad_format;
919
920 DO_NUMBER (2, tp->tm_mday);
921
922 case L_('e'): /* POSIX.2 extension. */
923 if (modifier == L_('E'))
924 goto bad_format;
925
926 DO_NUMBER_SPACEPAD (2, tp->tm_mday);
927
928 /* All numeric formats set DIGITS and NUMBER_VALUE and then
929 jump to one of these two labels. */
930
931 do_number_spacepad:
932 /* Force `_' flag unless overwritten by `0' flag. */
933 if (pad != L_('0'))
934 pad = L_('_');
935
936 do_number:
937 /* Format the number according to the MODIFIER flag. */
938
939 if (modifier == L_('O') && 0 <= number_value)
940 {
941 #ifdef _NL_CURRENT
942 /* Get the locale specific alternate representation of
943 the number NUMBER_VALUE. If none exist NULL is returned. */
944 # ifdef COMPILE_WIDE
945 const wchar_t *cp = _nl_get_walt_digit (number_value);
946 # else
947 const char *cp = _nl_get_alt_digit (number_value);
948 # endif
949
950 if (cp != NULL)
951 {
952 size_t digitlen = STRLEN (cp);
953 if (digitlen != 0)
954 {
955 cpy (digitlen, cp);
956 break;
957 }
958 }
959 #else
960 # if HAVE_STRFTIME
961 goto underlying_strftime;
962 # endif
963 #endif
964 }
965 {
966 unsigned int u = number_value;
967
968 bufp = buf + sizeof (buf) / sizeof (buf[0]);
969 negative_number = number_value < 0;
970
971 if (negative_number)
972 u = -u;
973
974 do
975 *--bufp = u % 10 + L_('0');
976 while ((u /= 10) != 0);
977 }
978
979 do_number_sign_and_padding:
980 if (negative_number)
981 *--bufp = L_('-');
982
983 if (pad != L_('-'))
984 {
985 int padding = digits - (buf + (sizeof (buf) / sizeof (buf[0]))
986 - bufp);
987
988 if (pad == L_('_'))
989 {
990 while (0 < padding--)
991 *--bufp = L_(' ');
992 }
993 else
994 {
995 bufp += negative_number;
996 while (0 < padding--)
997 *--bufp = L_('0');
998 if (negative_number)
999 *--bufp = L_('-');
1000 }
1001 }
1002
1003 cpy (buf + sizeof (buf) / sizeof (buf[0]) - bufp, bufp);
1004 break;
1005
1006 case L_('F'):
1007 if (modifier != 0)
1008 goto bad_format;
1009 subfmt = L_("%Y-%m-%d");
1010 goto subformat;
1011
1012 case L_('H'):
1013 if (modifier == L_('E'))
1014 goto bad_format;
1015
1016 DO_NUMBER (2, tp->tm_hour);
1017
1018 case L_('I'):
1019 if (modifier == L_('E'))
1020 goto bad_format;
1021
1022 DO_NUMBER (2, hour12);
1023
1024 case L_('k'): /* GNU extension. */
1025 if (modifier == L_('E'))
1026 goto bad_format;
1027
1028 DO_NUMBER_SPACEPAD (2, tp->tm_hour);
1029
1030 case L_('l'): /* GNU extension. */
1031 if (modifier == L_('E'))
1032 goto bad_format;
1033
1034 DO_NUMBER_SPACEPAD (2, hour12);
1035
1036 case L_('j'):
1037 if (modifier == L_('E'))
1038 goto bad_format;
1039
1040 DO_NUMBER (3, 1 + tp->tm_yday);
1041
1042 case L_('M'):
1043 if (modifier == L_('E'))
1044 goto bad_format;
1045
1046 DO_NUMBER (2, tp->tm_min);
1047
1048 case L_('m'):
1049 if (modifier == L_('E'))
1050 goto bad_format;
1051
1052 DO_NUMBER (2, tp->tm_mon + 1);
1053
1054 case L_('n'): /* POSIX.2 extension. */
1055 add (1, *p = L_('\n'));
1056 break;
1057
1058 case L_('P'):
1059 to_lowcase = 1;
1060 #if !defined _NL_CURRENT && HAVE_STRFTIME
1061 format_char = L_('p');
1062 #endif
1063 /* FALLTHROUGH */
1064
1065 case L_('p'):
1066 if (change_case)
1067 {
1068 to_uppcase = 0;
1069 to_lowcase = 1;
1070 }
1071 #if defined _NL_CURRENT || !HAVE_STRFTIME
1072 cpy (ap_len, ampm);
1073 break;
1074 #else
1075 goto underlying_strftime;
1076 #endif
1077
1078 case L_('R'): /* GNU extension. */
1079 subfmt = L_("%H:%M");
1080 goto subformat;
1081
1082 case L_('r'): /* POSIX.2 extension. */
1083 #ifdef _NL_CURRENT
1084 if (*(subfmt = (CHAR_T *) _NL_CURRENT (LC_TIME,
1085 NLW(T_FMT_AMPM))) == L_('\0'))
1086 #endif
1087 subfmt = L_("%I:%M:%S %p");
1088 goto subformat;
1089
1090 case L_('S'):
1091 if (modifier == L_('E'))
1092 goto bad_format;
1093
1094 DO_NUMBER (2, tp->tm_sec);
1095
1096 case L_('s'): /* GNU extension. */
1097 {
1098 struct tm ltm;
1099 time_t t;
1100
1101 ltm = *tp;
1102 t = mktime (&ltm);
1103
1104 /* Generate string value for T using time_t arithmetic;
1105 this works even if sizeof (long) < sizeof (time_t). */
1106
1107 bufp = buf + sizeof (buf) / sizeof (buf[0]);
1108 negative_number = t < 0;
1109
1110 do
1111 {
1112 int d = t % 10;
1113 t /= 10;
1114
1115 if (negative_number)
1116 {
1117 d = -d;
1118
1119 /* Adjust if division truncates to minus infinity. */
1120 if (0 < -1 % 10 && d < 0)
1121 {
1122 t++;
1123 d += 10;
1124 }
1125 }
1126
1127 *--bufp = d + L_('0');
1128 }
1129 while (t != 0);
1130
1131 digits = 1;
1132 goto do_number_sign_and_padding;
1133 }
1134
1135 case L_('X'):
1136 if (modifier == L_('O'))
1137 goto bad_format;
1138 #ifdef _NL_CURRENT
1139 if (! (modifier == L_('E')
1140 && (*(subfmt = (CHAR_T *) _NL_CURRENT (LC_TIME,
1141 NLW(ERA_T_FMT)))
1142 != L_('\0'))))
1143 subfmt = (CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT));
1144 goto subformat;
1145 #else
1146 # if HAVE_STRFTIME
1147 goto underlying_strftime;
1148 # else
1149 /* Fall through. */
1150 # endif
1151 #endif
1152 case L_('T'): /* POSIX.2 extension. */
1153 subfmt = L_("%H:%M:%S");
1154 goto subformat;
1155
1156 case L_('t'): /* POSIX.2 extension. */
1157 add (1, *p = L_('\t'));
1158 break;
1159
1160 case L_('u'): /* POSIX.2 extension. */
1161 DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
1162
1163 case L_('U'):
1164 if (modifier == L_('E'))
1165 goto bad_format;
1166
1167 DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
1168
1169 case L_('V'):
1170 case L_('g'): /* GNU extension. */
1171 case L_('G'): /* GNU extension. */
1172 if (modifier == L_('E'))
1173 goto bad_format;
1174 {
1175 int year = tp->tm_year + TM_YEAR_BASE;
1176 int days = iso_week_days (tp->tm_yday, tp->tm_wday);
1177
1178 if (days < 0)
1179 {
1180 /* This ISO week belongs to the previous year. */
1181 year--;
1182 days = iso_week_days (tp->tm_yday + (365 + __isleap (year)),
1183 tp->tm_wday);
1184 }
1185 else
1186 {
1187 int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
1188 tp->tm_wday);
1189 if (0 <= d)
1190 {
1191 /* This ISO week belongs to the next year. */
1192 year++;
1193 days = d;
1194 }
1195 }
1196
1197 switch (*f)
1198 {
1199 case L_('g'):
1200 DO_NUMBER (2, (year % 100 + 100) % 100);
1201
1202 case L_('G'):
1203 DO_NUMBER (1, year);
1204
1205 default:
1206 DO_NUMBER (2, days / 7 + 1);
1207 }
1208 }
1209
1210 case L_('W'):
1211 if (modifier == L_('E'))
1212 goto bad_format;
1213
1214 DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
1215
1216 case L_('w'):
1217 if (modifier == L_('E'))
1218 goto bad_format;
1219
1220 DO_NUMBER (1, tp->tm_wday);
1221
1222 case L_('Y'):
1223 if (modifier == 'E')
1224 {
1225 #if HAVE_STRUCT_ERA_ENTRY
1226 struct era_entry *era = _nl_get_era_entry (tp);
1227 if (era)
1228 {
1229 # ifdef COMPILE_WIDE
1230 subfmt = era->era_wformat;
1231 # else
1232 subfmt = era->era_format;
1233 # endif
1234 goto subformat;
1235 }
1236 #else
1237 # if HAVE_STRFTIME
1238 goto underlying_strftime;
1239 # endif
1240 #endif
1241 }
1242 if (modifier == L_('O'))
1243 goto bad_format;
1244 else
1245 DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE);
1246
1247 case L_('y'):
1248 if (modifier == L_('E'))
1249 {
1250 #if HAVE_STRUCT_ERA_ENTRY
1251 struct era_entry *era = _nl_get_era_entry (tp);
1252 if (era)
1253 {
1254 int delta = tp->tm_year - era->start_date[0];
1255 DO_NUMBER (1, (era->offset
1256 + delta * era->absolute_direction));
1257 }
1258 #else
1259 # if HAVE_STRFTIME
1260 goto underlying_strftime;
1261 # endif
1262 #endif
1263 }
1264 DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100);
1265
1266 case L_('Z'):
1267 if (change_case)
1268 {
1269 to_uppcase = 0;
1270 to_lowcase = 1;
1271 }
1272
1273 #if HAVE_TZNAME
1274 /* The tzset() call might have changed the value. */
1275 if (!(zone && *zone) && tp->tm_isdst >= 0)
1276 zone = tzname[tp->tm_isdst];
1277 #endif
1278 if (! zone)
1279 zone = ""; /* POSIX.2 requires the empty string here. */
1280
1281 #ifdef COMPILE_WIDE
1282 {
1283 /* The zone string is always given in multibyte form. We have
1284 to transform it first. */
1285 wchar_t *wczone;
1286 size_t len;
1287 widen (zone, wczone, len);
1288 cpy (len, wczone);
1289 }
1290 #else
1291 cpy (strlen (zone), zone);
1292 #endif
1293 break;
1294
1295 case L_('z'): /* GNU extension. */
1296 if (tp->tm_isdst < 0)
1297 break;
1298
1299 {
1300 int diff;
1301 #if HAVE_TM_GMTOFF
1302 diff = tp->tm_gmtoff;
1303 #else
1304 if (ut)
1305 diff = 0;
1306 else
1307 {
1308 struct tm gtm;
1309 struct tm ltm;
1310 time_t lt;
1311
1312 ltm = *tp;
1313 lt = mktime (&ltm);
1314
1315 if (lt == (time_t) -1)
1316 {
1317 /* mktime returns -1 for errors, but -1 is also a
1318 valid time_t value. Check whether an error really
1319 occurred. */
1320 struct tm tm;
1321
1322 if (! my_strftime_localtime_r (&lt, &tm)
1323 || ((ltm.tm_sec ^ tm.tm_sec)
1324 | (ltm.tm_min ^ tm.tm_min)
1325 | (ltm.tm_hour ^ tm.tm_hour)
1326 | (ltm.tm_mday ^ tm.tm_mday)
1327 | (ltm.tm_mon ^ tm.tm_mon)
1328 | (ltm.tm_year ^ tm.tm_year)))
1329 break;
1330 }
1331
1332 if (! my_strftime_gmtime_r (&lt, &gtm))
1333 break;
1334
1335 diff = tm_diff (&ltm, &gtm);
1336 }
1337 #endif
1338
1339 if (diff < 0)
1340 {
1341 add (1, *p = L_('-'));
1342 diff = -diff;
1343 }
1344 else
1345 add (1, *p = L_('+'));
1346
1347 diff /= 60;
1348 DO_NUMBER (4, (diff / 60) * 100 + diff % 60);
1349 }
1350
1351 case L_('\0'): /* GNU extension: % at end of format. */
1352 --f;
1353 /* Fall through. */
1354 default:
1355 /* Unknown format; output the format, including the '%',
1356 since this is most likely the right thing to do if a
1357 multibyte string has been misparsed. */
1358 bad_format:
1359 {
1360 int flen;
1361 for (flen = 1; f[1 - flen] != L_('%'); flen++)
1362 continue;
1363 cpy (flen, &f[1 - flen]);
1364 }
1365 break;
1366 }
1367 }
1368
1369 if (p && maxsize != 0)
1370 *p = L_('\0');
1371 return i;
1372 }
1373
1374
1375 #ifdef emacs
1376 /* For Emacs we have a separate interface which corresponds to the normal
1377 strftime function and does not have the extra information whether the
1378 TP arguments comes from a `gmtime' call or not. */
1379 size_t
1380 emacs_strftime (s, maxsize, format, tp)
1381 char *s;
1382 size_t maxsize;
1383 const char *format;
1384 const struct tm *tp;
1385 {
1386 return my_strftime (s, maxsize, format, tp, 0);
1387 }
1388 #endif
1389