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