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