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