strftime.c 46 KB

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