strftime_l.c 35 KB

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