strftime.c 46 KB

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