Blame missing_d/strftime.c

Packit Service f629e6
/* Copyright (C) 1991-1999, 2000, 2001, 2002, 2003
Packit Service f629e6
   Free Software Foundation, Inc.
Packit Service f629e6
   This file is part of the GNU C Library.
Packit Service f629e6
Packit Service f629e6
   The GNU C Library is free software; you can redistribute it and/or
Packit Service f629e6
   modify it under the terms of the GNU Lesser General Public
Packit Service f629e6
   License as published by the Free Software Foundation; either
Packit Service f629e6
   version 2.1 of the License, or (at your option) any later version.
Packit Service f629e6
Packit Service f629e6
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service f629e6
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service f629e6
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service f629e6
   Lesser General Public License for more details.
Packit Service f629e6
Packit Service f629e6
   You should have received a copy of the GNU Lesser General Public
Packit Service f629e6
   License along with the GNU C Library; if not, write to the Free
Packit Service f629e6
   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit Service f629e6
   02110-1301 USA.  */
Packit Service f629e6
Packit Service f629e6
#ifdef HAVE_CONFIG_H
Packit Service f629e6
# include <config.h>
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
#ifdef _LIBC
Packit Service f629e6
# define HAVE_LIMITS_H 1
Packit Service f629e6
# define HAVE_MBLEN 1
Packit Service f629e6
# define HAVE_MBRLEN 1
Packit Service f629e6
# define HAVE_STRUCT_ERA_ENTRY 1
Packit Service f629e6
# define HAVE_TM_GMTOFF 1
Packit Service f629e6
# define HAVE_TM_ZONE 1
Packit Service f629e6
# define HAVE_TZNAME 1
Packit Service f629e6
# define HAVE_TZSET 1
Packit Service f629e6
# define MULTIBYTE_IS_FORMAT_SAFE 1
Packit Service f629e6
# define STDC_HEADERS 1
Packit Service f629e6
# include "../locale/localeinfo.h"
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
#if defined emacs && !defined HAVE_BCOPY
Packit Service f629e6
# define HAVE_MEMCPY 1
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
#include <ctype.h>
Packit Service f629e6
#ifdef TIME_T_IN_SYS_TYPES
Packit Service f629e6
#include <sys/types.h>		/* Some systems define `time_t' here.  */
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
#ifdef TIME_WITH_SYS_TIME
Packit Service f629e6
# include <sys/time.h>
Packit Service f629e6
# include <time.h>
Packit Service f629e6
#else
Packit Service f629e6
# ifdef HAVE_SYS_TIME_H
Packit Service f629e6
#  include <sys/time.h>
Packit Service f629e6
# else
Packit Service f629e6
#  include <time.h>
Packit Service f629e6
# endif
Packit Service f629e6
#endif
Packit Service f629e6
#if HAVE_TZNAME
Packit Service f629e6
#ifndef __MINGW32__
Packit Service f629e6
extern char *tzname[];
Packit Service f629e6
#endif
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
/* Do multibyte processing if multibytes are supported, unless
Packit Service f629e6
   multibyte sequences are safe in formats.  Multibyte sequences are
Packit Service f629e6
   safe if they cannot contain byte sequences that look like format
Packit Service f629e6
   conversion specifications.  The GNU C Library uses UTF8 multibyte
Packit Service f629e6
   encoding, which is safe for formats, but strftime.c can be used
Packit Service f629e6
   with other C libraries that use unsafe encodings.  */
Packit Service f629e6
#define DO_MULTIBYTE (HAVE_MBLEN && ! MULTIBYTE_IS_FORMAT_SAFE)
Packit Service f629e6
Packit Service f629e6
#if DO_MULTIBYTE
Packit Service f629e6
# if HAVE_MBRLEN
Packit Service f629e6
#  include <wchar.h>
Packit Service f629e6
# else
Packit Service f629e6
   /* Simulate mbrlen with mblen as best we can.  */
Packit Service f629e6
#  define mbstate_t int
Packit Service f629e6
#  define mbrlen(s, n, ps) mblen (s, n)
Packit Service f629e6
#  define mbsinit(ps) (*(ps) == 0)
Packit Service f629e6
# endif
Packit Service f629e6
  static const mbstate_t mbstate_zero;
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
#if HAVE_LIMITS_H
Packit Service f629e6
# include <limits.h>
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
#if STDC_HEADERS
Packit Service f629e6
# include <stddef.h>
Packit Service f629e6
# include <stdlib.h>
Packit Service f629e6
# include <string.h>
Packit Service f629e6
#else
Packit Service f629e6
# ifndef HAVE_MEMCPY
Packit Service f629e6
#  define memcpy(d, s, n) bcopy ((s), (d), (n))
Packit Service f629e6
# endif
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
#ifdef COMPILE_WIDE
Packit Service f629e6
# include <endian.h>
Packit Service f629e6
# define CHAR_T wchar_t
Packit Service f629e6
# define UCHAR_T unsigned int
Packit Service f629e6
# define L_(Str) L##Str
Packit Service f629e6
# define NLW(Sym) _NL_W##Sym
Packit Service f629e6
Packit Service f629e6
# define MEMCPY(d, s, n) __wmemcpy (d, s, n)
Packit Service f629e6
# define STRLEN(s) __wcslen (s)
Packit Service f629e6
Packit Service f629e6
#else
Packit Service f629e6
# define CHAR_T char
Packit Service f629e6
# define UCHAR_T unsigned char
Packit Service f629e6
# define L_(Str) Str
Packit Service f629e6
# define NLW(Sym) Sym
Packit Service f629e6
Packit Service f629e6
# if !defined STDC_HEADERS && !defined HAVE_MEMCPY
Packit Service f629e6
#  define MEMCPY(d, s, n) bcopy ((s), (d), (n))
Packit Service f629e6
# else
Packit Service f629e6
#  define MEMCPY(d, s, n) memcpy ((d), (s), (n))
Packit Service f629e6
# endif
Packit Service f629e6
# define STRLEN(s) strlen (s)
Packit Service f629e6
Packit Service f629e6
# ifdef _LIBC
Packit Service f629e6
#  define MEMPCPY(d, s, n) __mempcpy (d, s, n)
Packit Service f629e6
# else
Packit Service f629e6
#  ifndef HAVE_MEMPCPY
Packit Service f629e6
#   define MEMPCPY(d, s, n) ((void *) ((char *) memcpy (d, s, n) + (n)))
Packit Service f629e6
#  endif
Packit Service f629e6
# endif
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
#ifndef __P
Packit Service f629e6
# if defined __GNUC__ || (defined __STDC__ && __STDC__)
Packit Service f629e6
#  define __P(args) args
Packit Service f629e6
# else
Packit Service f629e6
#  define __P(args) ()
Packit Service f629e6
# endif  /* GCC.  */
Packit Service f629e6
#endif  /* Not __P.  */
Packit Service f629e6
Packit Service f629e6
#ifndef PTR
Packit Service f629e6
# ifdef __STDC__
Packit Service f629e6
#  define PTR void *
Packit Service f629e6
# else
Packit Service f629e6
#  define PTR char *
Packit Service f629e6
# endif
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
#ifndef CHAR_BIT
Packit Service f629e6
# define CHAR_BIT 8
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
#ifndef NULL
Packit Service f629e6
# define NULL 0
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
/* Test for checking whether a given type is signed or not.
Packit Service f629e6
   Some compilers issue a diagnostic about suspicious construct for
Packit Service f629e6
   a test that will always fail when comparing a value that can't be
Packit Service f629e6
   negative against 0 using `<' or `<=' operator.  */
Packit Service f629e6
/* #define TYPE_SIGNED(t) ((t) -1 < 0) */
Packit Service f629e6
#define TYPE_SIGNED(t) ((t) -1 < 1)
Packit Service f629e6
Packit Service f629e6
#ifndef INT_STRLEN_BOUND
Packit Service f629e6
/* Bound on length of the string representing an integer value of type t.
Packit Service f629e6
   Subtract one for the sign bit if t is signed;
Packit Service f629e6
   302 / 1000 is log10 (2) rounded up;
Packit Service f629e6
   add one for integer division truncation;
Packit Service f629e6
   add one more for a minus sign if t is signed.  */
Packit Service f629e6
#define INT_STRLEN_BOUND(t) \
Packit Service f629e6
 ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 + 1 + TYPE_SIGNED (t))
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
#define TM_YEAR_BASE 1900
Packit Service f629e6
Packit Service f629e6
#ifndef __isleap
Packit Service f629e6
/* Nonzero if YEAR is a leap year (every 4 years,
Packit Service f629e6
   except every 100th isn't, and every 400th is).  */
Packit Service f629e6
# define __isleap(year)	\
Packit Service f629e6
  ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
Packit Service f629e6
#ifdef _LIBC
Packit Service f629e6
# define my_strftime_gmtime_r __gmtime_r
Packit Service f629e6
# define my_strftime_localtime_r __localtime_r
Packit Service f629e6
# define tzname __tzname
Packit Service f629e6
# define tzset __tzset
Packit Service f629e6
#else
Packit Service f629e6
Packit Service f629e6
/* If we're a strftime substitute in a GNU program, then prefer gmtime
Packit Service f629e6
   to gmtime_r, since many gmtime_r implementations are buggy.
Packit Service f629e6
   Similarly for localtime_r.  */
Packit Service f629e6
Packit Service f629e6
# if ! HAVE_TM_GMTOFF
Packit Service f629e6
static struct tm *my_strftime_gmtime_r __P ((const time_t *, struct tm *));
Packit Service f629e6
static struct tm *
Packit Service f629e6
my_strftime_gmtime_r (t, tp)
Packit Service f629e6
     const time_t *t;
Packit Service f629e6
     struct tm *tp;
Packit Service f629e6
{
Packit Service f629e6
  struct tm *l = gmtime (t);
Packit Service f629e6
  if (! l)
Packit Service f629e6
    return 0;
Packit Service f629e6
  *tp = *l;
Packit Service f629e6
  return tp;
Packit Service f629e6
}
Packit Service f629e6
# endif /* ! HAVE_TM_GMTOFF */
Packit Service f629e6
Packit Service f629e6
static struct tm *my_strftime_localtime_r __P ((const time_t *, struct tm *));
Packit Service f629e6
static struct tm *
Packit Service f629e6
my_strftime_localtime_r (t, tp)
Packit Service f629e6
     const time_t *t;
Packit Service f629e6
     struct tm *tp;
Packit Service f629e6
{
Packit Service f629e6
  struct tm *l = localtime (t);
Packit Service f629e6
  if (! l)
Packit Service f629e6
    return 0;
Packit Service f629e6
  *tp = *l;
Packit Service f629e6
  return tp;
Packit Service f629e6
}
Packit Service f629e6
#endif /* ! defined _LIBC */
Packit Service f629e6
Packit Service f629e6
Packit Service f629e6
#if !defined memset && !defined HAVE_MEMSET && !defined _LIBC
Packit Service f629e6
/* Some systems lack the `memset' function and we don't want to
Packit Service f629e6
   introduce additional dependencies.  */
Packit Service f629e6
/* The SGI compiler reportedly barfs on the trailing null
Packit Service f629e6
   if we use a string constant as the initializer.  28 June 1997, rms.  */
Packit Service f629e6
static const CHAR_T spaces[16] = /* "                " */
Packit Service f629e6
{
Packit Service f629e6
  L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),
Packit Service f629e6
  L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' ')
Packit Service f629e6
};
Packit Service f629e6
static const CHAR_T zeroes[16] = /* "0000000000000000" */
Packit Service f629e6
{
Packit Service f629e6
  L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),
Packit Service f629e6
  L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0')
Packit Service f629e6
};
Packit Service f629e6
Packit Service f629e6
# define memset_space(P, Len) \
Packit Service f629e6
  do {									      \
Packit Service f629e6
    int _len = (Len);							      \
Packit Service f629e6
									      \
Packit Service f629e6
    do									      \
Packit Service f629e6
      {									      \
Packit Service f629e6
	int _this = _len > 16 ? 16 : _len;				      \
Packit Service f629e6
	(P) = MEMPCPY ((P), spaces, _this * sizeof (CHAR_T));		      \
Packit Service f629e6
	_len -= _this;							      \
Packit Service f629e6
      }									      \
Packit Service f629e6
    while (_len > 0);							      \
Packit Service f629e6
  } while (0)
Packit Service f629e6
Packit Service f629e6
# define memset_zero(P, Len) \
Packit Service f629e6
  do {									      \
Packit Service f629e6
    int _len = (Len);							      \
Packit Service f629e6
									      \
Packit Service f629e6
    do									      \
Packit Service f629e6
      {									      \
Packit Service f629e6
	int _this = _len > 16 ? 16 : _len;				      \
Packit Service f629e6
	(P) = MEMPCPY ((P), zeroes, _this * sizeof (CHAR_T));		      \
Packit Service f629e6
	_len -= _this;							      \
Packit Service f629e6
      }									      \
Packit Service f629e6
    while (_len > 0);							      \
Packit Service f629e6
  } while (0)
Packit Service f629e6
#else
Packit Service f629e6
# ifdef COMPILE_WIDE
Packit Service f629e6
#  define memset_space(P, Len) (wmemset ((P), L' ', (Len)), (P) += (Len))
Packit Service f629e6
#  define memset_zero(P, Len) (wmemset ((P), L'0', (Len)), (P) += (Len))
Packit Service f629e6
# else
Packit Service f629e6
#  define memset_space(P, Len) (memset ((P), ' ', (Len)), (P) += (Len))
Packit Service f629e6
#  define memset_zero(P, Len) (memset ((P), '0', (Len)), (P) += (Len))
Packit Service f629e6
# endif
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
#define add(n, f)							      \
Packit Service f629e6
  do									      \
Packit Service f629e6
    {									      \
Packit Service f629e6
      int _n = (n);							      \
Packit Service f629e6
      int _delta = width - _n;						      \
Packit Service f629e6
      int _incr = _n + (_delta > 0 ? _delta : 0);			      \
Packit Service f629e6
      if ((size_t) _incr >= maxsize - i)				      \
Packit Service f629e6
	return 0;							      \
Packit Service f629e6
      if (p)								      \
Packit Service f629e6
	{								      \
Packit Service f629e6
	  if (_delta > 0)						      \
Packit Service f629e6
	    {								      \
Packit Service f629e6
	      if (pad == L_('0'))					      \
Packit Service f629e6
		memset_zero (p, _delta);				      \
Packit Service f629e6
	      else							      \
Packit Service f629e6
		memset_space (p, _delta);				      \
Packit Service f629e6
	    }								      \
Packit Service f629e6
	  f;								      \
Packit Service f629e6
	  p += _n;							      \
Packit Service f629e6
	}								      \
Packit Service f629e6
      i += _incr;							      \
Packit Service f629e6
    } while (0)
Packit Service f629e6
Packit Service f629e6
#define cpy(n, s) \
Packit Service f629e6
    add ((n),								      \
Packit Service f629e6
	 if (to_lowcase)						      \
Packit Service f629e6
	   memcpy_lowcase (p, (s), _n LOCALE_ARG);			      \
Packit Service f629e6
	 else if (to_uppcase)						      \
Packit Service f629e6
	   memcpy_uppcase (p, (s), _n LOCALE_ARG);			      \
Packit Service f629e6
	 else								      \
Packit Service f629e6
	   MEMCPY ((PTR) p, (const PTR) (s), _n))
Packit Service f629e6
Packit Service f629e6
#ifdef COMPILE_WIDE
Packit Service f629e6
# ifndef USE_IN_EXTENDED_LOCALE_MODEL
Packit Service f629e6
#  undef __mbsrtowcs_l
Packit Service f629e6
#  define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st)
Packit Service f629e6
# endif
Packit Service f629e6
# define widen(os, ws, l) \
Packit Service f629e6
  {									      \
Packit Service f629e6
    mbstate_t __st;							      \
Packit Service f629e6
    const char *__s = os;						      \
Packit Service f629e6
    memset (&__st, '\0', sizeof (__st));				      \
Packit Service f629e6
    l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc);			      \
Packit Service f629e6
    ws = alloca ((l + 1) * sizeof (wchar_t));				      \
Packit Service f629e6
    (void) __mbsrtowcs_l (ws, &__s, l, &__st, loc);			      \
Packit Service f629e6
  }
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
/* For gawk */
Packit Service f629e6
#undef TOLOWER
Packit Service f629e6
#undef TOUPPER
Packit Service f629e6
#undef ISDIGIT
Packit Service f629e6
Packit Service f629e6
#if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
Packit Service f629e6
/* We use this code also for the extended locale handling where the
Packit Service f629e6
   function gets as an additional argument the locale which has to be
Packit Service f629e6
   used.  To access the values we have to redefine the _NL_CURRENT
Packit Service f629e6
   macro.  */
Packit Service f629e6
# define strftime		__strftime_l
Packit Service f629e6
# define wcsftime		__wcsftime_l
Packit Service f629e6
# undef _NL_CURRENT
Packit Service f629e6
# define _NL_CURRENT(category, item) \
Packit Service f629e6
  (current->values[_NL_ITEM_INDEX (item)].string)
Packit Service f629e6
# define LOCALE_PARAM , loc
Packit Service f629e6
# define LOCALE_ARG , loc
Packit Service f629e6
# define LOCALE_PARAM_DECL  __locale_t loc;
Packit Service f629e6
# define LOCALE_PARAM_PROTO , __locale_t loc
Packit Service f629e6
# define HELPER_LOCALE_ARG  , current
Packit Service f629e6
#else
Packit Service f629e6
# define LOCALE_PARAM
Packit Service f629e6
# define LOCALE_PARAM_PROTO
Packit Service f629e6
# define LOCALE_ARG
Packit Service f629e6
# define LOCALE_PARAM_DECL
Packit Service f629e6
# ifdef _LIBC
Packit Service f629e6
#  define HELPER_LOCALE_ARG , _NL_CURRENT_DATA (LC_TIME)
Packit Service f629e6
# else
Packit Service f629e6
#  define HELPER_LOCALE_ARG
Packit Service f629e6
# endif
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
#ifdef COMPILE_WIDE
Packit Service f629e6
# ifdef USE_IN_EXTENDED_LOCALE_MODEL
Packit Service f629e6
#  define TOUPPER(Ch, L) __towupper_l (Ch, L)
Packit Service f629e6
#  define TOLOWER(Ch, L) __towlower_l (Ch, L)
Packit Service f629e6
# else
Packit Service f629e6
#  define TOUPPER(Ch, L) towupper (Ch)
Packit Service f629e6
#  define TOLOWER(Ch, L) towlower (Ch)
Packit Service f629e6
# endif
Packit Service f629e6
#else
Packit Service f629e6
# ifdef _LIBC
Packit Service f629e6
#  ifdef USE_IN_EXTENDED_LOCALE_MODEL
Packit Service f629e6
#   define TOUPPER(Ch, L) __toupper_l (Ch, L)
Packit Service f629e6
#   define TOLOWER(Ch, L) __tolower_l (Ch, L)
Packit Service f629e6
#  else
Packit Service f629e6
#   define TOUPPER(Ch, L) toupper (Ch)
Packit Service f629e6
#   define TOLOWER(Ch, L) tolower (Ch)
Packit Service f629e6
#  endif
Packit Service f629e6
# else
Packit Service f629e6
#  define TOUPPER(Ch, L) (islower (Ch) ? toupper (Ch) : (Ch))
Packit Service f629e6
#  define TOLOWER(Ch, L) (isupper (Ch) ? tolower (Ch) : (Ch))
Packit Service f629e6
# endif
Packit Service f629e6
#endif
Packit Service f629e6
/* We don't use `isdigit' here since the locale dependent
Packit Service f629e6
   interpretation is not what we want here.  We only need to accept
Packit Service f629e6
   the arabic digits in the ASCII range.  One day there is perhaps a
Packit Service f629e6
   more reliable way to accept other sets of digits.  */
Packit Service f629e6
#define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9)
Packit Service f629e6
Packit Service f629e6
static CHAR_T *memcpy_lowcase __P ((CHAR_T *dest, const CHAR_T *src,
Packit Service f629e6
				    size_t len LOCALE_PARAM_PROTO));
Packit Service f629e6
Packit Service f629e6
static CHAR_T *
Packit Service f629e6
memcpy_lowcase (dest, src, len LOCALE_PARAM)
Packit Service f629e6
     CHAR_T *dest;
Packit Service f629e6
     const CHAR_T *src;
Packit Service f629e6
     size_t len;
Packit Service f629e6
     LOCALE_PARAM_DECL
Packit Service f629e6
{
Packit Service f629e6
  while (len-- > 0)
Packit Service f629e6
    dest[len] = TOLOWER ((UCHAR_T) src[len], loc);
Packit Service f629e6
  return dest;
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
static CHAR_T *memcpy_uppcase __P ((CHAR_T *dest, const CHAR_T *src,
Packit Service f629e6
				    size_t len LOCALE_PARAM_PROTO));
Packit Service f629e6
Packit Service f629e6
static CHAR_T *
Packit Service f629e6
memcpy_uppcase (dest, src, len LOCALE_PARAM)
Packit Service f629e6
     CHAR_T *dest;
Packit Service f629e6
     const CHAR_T *src;
Packit Service f629e6
     size_t len;
Packit Service f629e6
     LOCALE_PARAM_DECL
Packit Service f629e6
{
Packit Service f629e6
  while (len-- > 0)
Packit Service f629e6
    dest[len] = TOUPPER ((UCHAR_T) src[len], loc);
Packit Service f629e6
  return dest;
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
Packit Service f629e6
#if ! HAVE_TM_GMTOFF
Packit Service f629e6
/* Yield the difference between *A and *B,
Packit Service f629e6
   measured in seconds, ignoring leap seconds.  */
Packit Service f629e6
# define tm_diff ftime_tm_diff
Packit Service f629e6
static int tm_diff __P ((const struct tm *, const struct tm *));
Packit Service f629e6
static int
Packit Service f629e6
tm_diff (a, b)
Packit Service f629e6
     const struct tm *a;
Packit Service f629e6
     const struct tm *b;
Packit Service f629e6
{
Packit Service f629e6
  /* Compute intervening leap days correctly even if year is negative.
Packit Service f629e6
     Take care to avoid int overflow in leap day calculations,
Packit Service f629e6
     but it's OK to assume that A and B are close to each other.  */
Packit Service f629e6
  int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
Packit Service f629e6
  int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
Packit Service f629e6
  int a100 = a4 / 25 - (a4 % 25 < 0);
Packit Service f629e6
  int b100 = b4 / 25 - (b4 % 25 < 0);
Packit Service f629e6
  int a400 = a100 >> 2;
Packit Service f629e6
  int b400 = b100 >> 2;
Packit Service f629e6
  int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
Packit Service f629e6
  int years = a->tm_year - b->tm_year;
Packit Service f629e6
  int days = (365 * years + intervening_leap_days
Packit Service f629e6
	      + (a->tm_yday - b->tm_yday));
Packit Service f629e6
  return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
Packit Service f629e6
		+ (a->tm_min - b->tm_min))
Packit Service f629e6
	  + (a->tm_sec - b->tm_sec));
Packit Service f629e6
}
Packit Service f629e6
#endif /* ! HAVE_TM_GMTOFF */
Packit Service f629e6
Packit Service f629e6
Packit Service f629e6
Packit Service f629e6
/* The number of days from the first day of the first ISO week of this
Packit Service f629e6
   year to the year day YDAY with week day WDAY.  ISO weeks start on
Packit Service f629e6
   Monday; the first ISO week has the year's first Thursday.  YDAY may
Packit Service f629e6
   be as small as YDAY_MINIMUM.  */
Packit Service f629e6
#define ISO_WEEK_START_WDAY 1 /* Monday */
Packit Service f629e6
#define ISO_WEEK1_WDAY 4 /* Thursday */
Packit Service f629e6
#define YDAY_MINIMUM (-366)
Packit Service f629e6
static int iso_week_days __P ((int, int));
Packit Service f629e6
#ifdef __GNUC__
Packit Service f629e6
__inline__
Packit Service f629e6
#endif
Packit Service f629e6
static int
Packit Service f629e6
iso_week_days (yday, wday)
Packit Service f629e6
     int yday;
Packit Service f629e6
     int wday;
Packit Service f629e6
{
Packit Service f629e6
  /* Add enough to the first operand of % to make it nonnegative.  */
Packit Service f629e6
  int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
Packit Service f629e6
  return (yday
Packit Service f629e6
	  - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
Packit Service f629e6
	  + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
Packit Service f629e6
#if !(defined _NL_CURRENT || HAVE_STRFTIME)
Packit Service f629e6
static CHAR_T const weekday_name[][10] =
Packit Service f629e6
  {
Packit Service f629e6
    L_("Sunday"), L_("Monday"), L_("Tuesday"), L_("Wednesday"),
Packit Service f629e6
    L_("Thursday"), L_("Friday"), L_("Saturday")
Packit Service f629e6
  };
Packit Service f629e6
static CHAR_T const month_name[][10] =
Packit Service f629e6
  {
Packit Service f629e6
    L_("January"), L_("February"), L_("March"), L_("April"), L_("May"),
Packit Service f629e6
    L_("June"), L_("July"), L_("August"), L_("September"), L_("October"),
Packit Service f629e6
    L_("November"), L_("December")
Packit Service f629e6
  };
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
Packit Service f629e6
#ifdef emacs
Packit Service f629e6
# define my_strftime emacs_strftimeu
Packit Service f629e6
# define ut_argument , ut
Packit Service f629e6
# define ut_argument_spec int ut;
Packit Service f629e6
# define ut_argument_spec_iso , int ut
Packit Service f629e6
#else
Packit Service f629e6
# ifdef COMPILE_WIDE
Packit Service f629e6
#  define my_strftime wcsftime
Packit Service f629e6
#  define nl_get_alt_digit _nl_get_walt_digit
Packit Service f629e6
# else
Packit Service f629e6
#  define my_strftime strftime
Packit Service f629e6
#  define nl_get_alt_digit _nl_get_alt_digit
Packit Service f629e6
# endif
Packit Service f629e6
# define ut_argument
Packit Service f629e6
# define ut_argument_spec
Packit Service f629e6
# define ut_argument_spec_iso
Packit Service f629e6
/* We don't have this information in general.  */
Packit Service f629e6
# define ut 0
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
#if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET
Packit Service f629e6
  /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime.
Packit Service f629e6
     Work around this bug by copying *tp before it might be munged.  */
Packit Service f629e6
  size_t _strftime_copytm __P ((char *, size_t, const char *,
Packit Service f629e6
			        const struct tm * ut_argument_spec_iso));
Packit Service f629e6
  size_t
Packit Service f629e6
  my_strftime (s, maxsize, format, tp ut_argument)
Packit Service f629e6
      CHAR_T *s;
Packit Service f629e6
      size_t maxsize;
Packit Service f629e6
      const CHAR_T *format;
Packit Service f629e6
      const struct tm *tp;
Packit Service f629e6
      ut_argument_spec
Packit Service f629e6
  {
Packit Service f629e6
    struct tm tmcopy;
Packit Service f629e6
    tmcopy = *tp;
Packit Service f629e6
    return _strftime_copytm (s, maxsize, format, &tmcopy ut_argument);
Packit Service f629e6
  }
Packit Service f629e6
# undef my_strftime
Packit Service f629e6
# define my_strftime _strftime_copytm
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
Packit Service f629e6
/* Write information from TP into S according to the format
Packit Service f629e6
   string FORMAT, writing no more that MAXSIZE characters
Packit Service f629e6
   (including the terminating '\0') and returning number of
Packit Service f629e6
   characters written.  If S is NULL, nothing will be written
Packit Service f629e6
   anywhere, so to determine how many characters would be
Packit Service f629e6
   written, use NULL for S and (size_t) UINT_MAX for MAXSIZE.  */
Packit Service f629e6
size_t
Packit Service f629e6
my_strftime (s, maxsize, format, tp ut_argument LOCALE_PARAM)
Packit Service f629e6
      CHAR_T *s;
Packit Service f629e6
      size_t maxsize;
Packit Service f629e6
      const CHAR_T *format;
Packit Service f629e6
      const struct tm *tp;
Packit Service f629e6
      ut_argument_spec
Packit Service f629e6
      LOCALE_PARAM_DECL
Packit Service f629e6
{
Packit Service f629e6
#if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
Packit Service f629e6
  struct locale_data *const current = loc->__locales[LC_TIME];
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
  int hour12 = tp->tm_hour;
Packit Service f629e6
#ifdef _NL_CURRENT
Packit Service f629e6
  /* We cannot make the following values variables since we must delay
Packit Service f629e6
     the evaluation of these values until really needed since some
Packit Service f629e6
     expressions might not be valid in every situation.  The `struct tm'
Packit Service f629e6
     might be generated by a strptime() call that initialized
Packit Service f629e6
     only a few elements.  Dereference the pointers only if the format
Packit Service f629e6
     requires this.  Then it is ok to fail if the pointers are invalid.  */
Packit Service f629e6
# define a_wkday \
Packit Service f629e6
  ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))
Packit Service f629e6
# define f_wkday \
Packit Service f629e6
  ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))
Packit Service f629e6
# define a_month \
Packit Service f629e6
  ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))
Packit Service f629e6
# define f_month \
Packit Service f629e6
  ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))
Packit Service f629e6
# define ampm \
Packit Service f629e6
  ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11		      \
Packit Service f629e6
				 ? NLW(PM_STR) : NLW(AM_STR)))
Packit Service f629e6
Packit Service f629e6
# define aw_len STRLEN (a_wkday)
Packit Service f629e6
# define am_len STRLEN (a_month)
Packit Service f629e6
# define ap_len STRLEN (ampm)
Packit Service f629e6
#else
Packit Service f629e6
# if !HAVE_STRFTIME
Packit Service f629e6
#  define f_wkday (weekday_name[tp->tm_wday])
Packit Service f629e6
#  define f_month (month_name[tp->tm_mon])
Packit Service f629e6
#  define a_wkday f_wkday
Packit Service f629e6
#  define a_month f_month
Packit Service f629e6
#  define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11))
Packit Service f629e6
Packit Service f629e6
  size_t aw_len = 3;
Packit Service f629e6
  size_t am_len = 3;
Packit Service f629e6
  size_t ap_len = 2;
Packit Service f629e6
# endif
Packit Service f629e6
#endif
Packit Service f629e6
  const char *zone;
Packit Service f629e6
  size_t i = 0;
Packit Service f629e6
  CHAR_T *p = s;
Packit Service f629e6
  const CHAR_T *f;
Packit Service f629e6
#if DO_MULTIBYTE && !defined COMPILE_WIDE
Packit Service f629e6
  const char *format_end = NULL;
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
  zone = NULL;
Packit Service f629e6
#if HAVE_TM_ZONE
Packit Service f629e6
  /* The POSIX test suite assumes that setting
Packit Service f629e6
     the environment variable TZ to a new value before calling strftime()
Packit Service f629e6
     will influence the result (the %Z format) even if the information in
Packit Service f629e6
     TP is computed with a totally different time zone.
Packit Service f629e6
     This is bogus: though POSIX allows bad behavior like this,
Packit Service f629e6
     POSIX does not require it.  Do the right thing instead.  */
Packit Service f629e6
  zone = (const char *) tp->tm_zone;
Packit Service f629e6
#endif
Packit Service f629e6
#if HAVE_TZNAME
Packit Service f629e6
  if (ut)
Packit Service f629e6
    {
Packit Service f629e6
      if (! (zone && *zone))
Packit Service f629e6
	zone = "GMT";
Packit Service f629e6
    }
Packit Service f629e6
  else
Packit Service f629e6
    {
Packit Service f629e6
      /* POSIX.1 requires that local time zone information is used as
Packit Service f629e6
	 though strftime called tzset.  */
Packit Service f629e6
# if HAVE_TZSET
Packit Service f629e6
      tzset ();
Packit Service f629e6
# endif
Packit Service f629e6
    }
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
  if (hour12 > 12)
Packit Service f629e6
    hour12 -= 12;
Packit Service f629e6
  else
Packit Service f629e6
    if (hour12 == 0)
Packit Service f629e6
      hour12 = 12;
Packit Service f629e6
Packit Service f629e6
  for (f = format; *f != '\0'; ++f)
Packit Service f629e6
    {
Packit Service f629e6
      int pad = 0;		/* Padding for number ('-', '_', or 0).  */
Packit Service f629e6
      int modifier;		/* Field modifier ('E', 'O', or 0).  */
Packit Service f629e6
      int digits;		/* Max digits for numeric format.  */
Packit Service f629e6
      int number_value; 	/* Numeric value to be printed.  */
Packit Service f629e6
      int negative_number;	/* 1 if the number is negative.  */
Packit Service f629e6
      const CHAR_T *subfmt;
Packit Service f629e6
      CHAR_T *bufp;
Packit Service f629e6
      CHAR_T buf[1 + (sizeof (int) < sizeof (time_t)
Packit Service f629e6
		      ? INT_STRLEN_BOUND (time_t)
Packit Service f629e6
		      : INT_STRLEN_BOUND (int))];
Packit Service f629e6
      int width = -1;
Packit Service f629e6
      int to_lowcase = 0;
Packit Service f629e6
      int to_uppcase = 0;
Packit Service f629e6
      int change_case = 0;
Packit Service f629e6
      int format_char;
Packit Service f629e6
Packit Service f629e6
#if DO_MULTIBYTE && !defined COMPILE_WIDE
Packit Service f629e6
      switch (*f)
Packit Service f629e6
	{
Packit Service f629e6
	case L_('%'):
Packit Service f629e6
	  break;
Packit Service f629e6
Packit Service f629e6
	case L_('\b'): case L_('\t'): case L_('\n'):
Packit Service f629e6
	case L_('\v'): case L_('\f'): case L_('\r'):
Packit Service f629e6
	case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
Packit Service f629e6
	case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
Packit Service f629e6
	case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
Packit Service f629e6
	case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
Packit Service f629e6
	case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
Packit Service f629e6
	case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
Packit Service f629e6
	case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
Packit Service f629e6
	case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
Packit Service f629e6
	case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
Packit Service f629e6
	case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
Packit Service f629e6
	case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
Packit Service f629e6
	case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
Packit Service f629e6
	case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
Packit Service f629e6
	case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
Packit Service f629e6
	case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
Packit Service f629e6
	case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
Packit Service f629e6
	case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
Packit Service f629e6
	case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
Packit Service f629e6
	case L_('~'):
Packit Service f629e6
	  /* The C Standard requires these 98 characters (plus '%') to
Packit Service f629e6
	     be in the basic execution character set.  None of these
Packit Service f629e6
	     characters can start a multibyte sequence, so they need
Packit Service f629e6
	     not be analyzed further.  */
Packit Service f629e6
	  add (1, *p = *f);
Packit Service f629e6
	  continue;
Packit Service f629e6
Packit Service f629e6
	default:
Packit Service f629e6
	  /* Copy this multibyte sequence until we reach its end, find
Packit Service f629e6
	     an error, or come back to the initial shift state.  */
Packit Service f629e6
	  {
Packit Service f629e6
	    mbstate_t mbstate = mbstate_zero;
Packit Service f629e6
	    size_t len = 0;
Packit Service f629e6
	    size_t fsize;
Packit Service f629e6
Packit Service f629e6
	    if (! format_end)
Packit Service f629e6
	      format_end = f + strlen (f) + 1;
Packit Service f629e6
	    fsize = format_end - f;
Packit Service f629e6
Packit Service f629e6
	    do
Packit Service f629e6
	      {
Packit Service f629e6
		size_t bytes = mbrlen (f + len, fsize - len, &mbstate);
Packit Service f629e6
Packit Service f629e6
		if (bytes == 0)
Packit Service f629e6
		  break;
Packit Service f629e6
Packit Service f629e6
		if (bytes == (size_t) -2)
Packit Service f629e6
		  {
Packit Service f629e6
		    len += strlen (f + len);
Packit Service f629e6
		    break;
Packit Service f629e6
		  }
Packit Service f629e6
Packit Service f629e6
		if (bytes == (size_t) -1)
Packit Service f629e6
		  {
Packit Service f629e6
		    len++;
Packit Service f629e6
		    break;
Packit Service f629e6
		  }
Packit Service f629e6
Packit Service f629e6
		len += bytes;
Packit Service f629e6
	      }
Packit Service f629e6
	    while (! mbsinit (&mbstate));
Packit Service f629e6
Packit Service f629e6
	    cpy (len, f);
Packit Service f629e6
	    f += len - 1;
Packit Service f629e6
	    continue;
Packit Service f629e6
	  }
Packit Service f629e6
	}
Packit Service f629e6
Packit Service f629e6
#else /* ! DO_MULTIBYTE */
Packit Service f629e6
Packit Service f629e6
      /* Either multibyte encodings are not supported, they are
Packit Service f629e6
	 safe for formats, so any non-'%' byte can be copied through,
Packit Service f629e6
	 or this is the wide character version.  */
Packit Service f629e6
      if (*f != L_('%'))
Packit Service f629e6
	{
Packit Service f629e6
	  add (1, *p = *f);
Packit Service f629e6
	  continue;
Packit Service f629e6
	}
Packit Service f629e6
Packit Service f629e6
#endif /* ! DO_MULTIBYTE */
Packit Service f629e6
Packit Service f629e6
      /* Check for flags that can modify a format.  */
Packit Service f629e6
      while (1)
Packit Service f629e6
	{
Packit Service f629e6
	  switch (*++f)
Packit Service f629e6
	    {
Packit Service f629e6
	      /* This influences the number formats.  */
Packit Service f629e6
	    case L_('_'):
Packit Service f629e6
	    case L_('-'):
Packit Service f629e6
	    case L_('0'):
Packit Service f629e6
	      pad = *f;
Packit Service f629e6
	      continue;
Packit Service f629e6
Packit Service f629e6
	      /* This changes textual output.  */
Packit Service f629e6
	    case L_('^'):
Packit Service f629e6
	      to_uppcase = 1;
Packit Service f629e6
	      continue;
Packit Service f629e6
	    case L_('#'):
Packit Service f629e6
	      change_case = 1;
Packit Service f629e6
	      continue;
Packit Service f629e6
Packit Service f629e6
	    default:
Packit Service f629e6
	      break;
Packit Service f629e6
	    }
Packit Service f629e6
	  break;
Packit Service f629e6
	}
Packit Service f629e6
Packit Service f629e6
      /* As a GNU extension we allow to specify the field width.  */
Packit Service f629e6
      if (ISDIGIT (*f))
Packit Service f629e6
	{
Packit Service f629e6
	  width = 0;
Packit Service f629e6
	  do
Packit Service f629e6
	    {
Packit Service f629e6
	      if (width > INT_MAX / 10
Packit Service f629e6
		  || (width == INT_MAX / 10 && *f - L_('0') > INT_MAX % 10))
Packit Service f629e6
		/* Avoid overflow.  */
Packit Service f629e6
		width = INT_MAX;
Packit Service f629e6
	      else
Packit Service f629e6
		{
Packit Service f629e6
		  width *= 10;
Packit Service f629e6
		  width += *f - L_('0');
Packit Service f629e6
		}
Packit Service f629e6
	      ++f;
Packit Service f629e6
	    }
Packit Service f629e6
	  while (ISDIGIT (*f));
Packit Service f629e6
	}
Packit Service f629e6
Packit Service f629e6
      /* Check for modifiers.  */
Packit Service f629e6
      switch (*f)
Packit Service f629e6
	{
Packit Service f629e6
	case L_('E'):
Packit Service f629e6
	case L_('O'):
Packit Service f629e6
	  modifier = *f++;
Packit Service f629e6
	  break;
Packit Service f629e6
Packit Service f629e6
	default:
Packit Service f629e6
	  modifier = 0;
Packit Service f629e6
	  break;
Packit Service f629e6
	}
Packit Service f629e6
Packit Service f629e6
      /* Now do the specified format.  */
Packit Service f629e6
      format_char = *f;
Packit Service f629e6
      switch (format_char)
Packit Service f629e6
	{
Packit Service f629e6
#define DO_NUMBER(d, v) \
Packit Service f629e6
	  digits = d > width ? d : width;				      \
Packit Service f629e6
	  number_value = v; goto do_number
Packit Service f629e6
#define DO_NUMBER_SPACEPAD(d, v) \
Packit Service f629e6
	  digits = d > width ? d : width;				      \
Packit Service f629e6
	  number_value = v; goto do_number_spacepad
Packit Service f629e6
Packit Service f629e6
	case L_('%'):
Packit Service f629e6
	  if (modifier != 0)
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
	  add (1, *p = *f);
Packit Service f629e6
	  break;
Packit Service f629e6
Packit Service f629e6
	case L_('a'):
Packit Service f629e6
	  if (modifier != 0)
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
	  if (change_case)
Packit Service f629e6
	    {
Packit Service f629e6
	      to_uppcase = 1;
Packit Service f629e6
	      to_lowcase = 0;
Packit Service f629e6
	    }
Packit Service f629e6
#if defined _NL_CURRENT || !HAVE_STRFTIME
Packit Service f629e6
	  cpy (aw_len, a_wkday);
Packit Service f629e6
	  break;
Packit Service f629e6
#else
Packit Service f629e6
	  goto underlying_strftime;
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
	case 'A':
Packit Service f629e6
	  if (modifier != 0)
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
	  if (change_case)
Packit Service f629e6
	    {
Packit Service f629e6
	      to_uppcase = 1;
Packit Service f629e6
	      to_lowcase = 0;
Packit Service f629e6
	    }
Packit Service f629e6
#if defined _NL_CURRENT || !HAVE_STRFTIME
Packit Service f629e6
	  cpy (STRLEN (f_wkday), f_wkday);
Packit Service f629e6
	  break;
Packit Service f629e6
#else
Packit Service f629e6
	  goto underlying_strftime;
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
	case L_('b'):
Packit Service f629e6
	case L_('h'):
Packit Service f629e6
	  if (change_case)
Packit Service f629e6
	    {
Packit Service f629e6
	      to_uppcase = 1;
Packit Service f629e6
	      to_lowcase = 0;
Packit Service f629e6
	    }
Packit Service f629e6
	  if (modifier != 0)
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
#if defined _NL_CURRENT || !HAVE_STRFTIME
Packit Service f629e6
	  cpy (am_len, a_month);
Packit Service f629e6
	  break;
Packit Service f629e6
#else
Packit Service f629e6
	  goto underlying_strftime;
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
	case L_('B'):
Packit Service f629e6
	  if (modifier != 0)
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
	  if (change_case)
Packit Service f629e6
	    {
Packit Service f629e6
	      to_uppcase = 1;
Packit Service f629e6
	      to_lowcase = 0;
Packit Service f629e6
	    }
Packit Service f629e6
#if defined _NL_CURRENT || !HAVE_STRFTIME
Packit Service f629e6
	  cpy (STRLEN (f_month), f_month);
Packit Service f629e6
	  break;
Packit Service f629e6
#else
Packit Service f629e6
	  goto underlying_strftime;
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
	case L_('c'):
Packit Service f629e6
	  if (modifier == L_('O'))
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
#ifdef _NL_CURRENT
Packit Service f629e6
	  if (! (modifier == 'E'
Packit Service f629e6
		 && (*(subfmt =
Packit Service f629e6
		       (const CHAR_T *) _NL_CURRENT (LC_TIME,
Packit Service f629e6
						     NLW(ERA_D_T_FMT)))
Packit Service f629e6
		     != '\0')))
Packit Service f629e6
	    subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT));
Packit Service f629e6
#else
Packit Service f629e6
# if HAVE_STRFTIME
Packit Service f629e6
	  goto underlying_strftime;
Packit Service f629e6
# else
Packit Service f629e6
	  subfmt = L_("%a %b %e %H:%M:%S %Y");
Packit Service f629e6
# endif
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
	subformat:
Packit Service f629e6
	  {
Packit Service f629e6
	    CHAR_T *old_start = p;
Packit Service f629e6
	    size_t len = my_strftime (NULL, (size_t) -1, subfmt,
Packit Service f629e6
				      tp ut_argument LOCALE_ARG);
Packit Service f629e6
	    add (len, my_strftime (p, maxsize - i, subfmt,
Packit Service f629e6
				   tp ut_argument LOCALE_ARG));
Packit Service f629e6
Packit Service f629e6
	    if (to_uppcase)
Packit Service f629e6
	      while (old_start < p)
Packit Service f629e6
		{
Packit Service f629e6
		  *old_start = TOUPPER ((UCHAR_T) *old_start, loc);
Packit Service f629e6
		  ++old_start;
Packit Service f629e6
		}
Packit Service f629e6
	  }
Packit Service f629e6
	  break;
Packit Service f629e6
Packit Service f629e6
#if HAVE_STRFTIME && ! (defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
Packit Service f629e6
	underlying_strftime:
Packit Service f629e6
	  {
Packit Service f629e6
	    /* The relevant information is available only via the
Packit Service f629e6
	       underlying strftime implementation, so use that.  */
Packit Service f629e6
	    char ufmt[4];
Packit Service f629e6
	    char *u = ufmt;
Packit Service f629e6
	    char ubuf[1024]; /* enough for any single format in practice */
Packit Service f629e6
	    size_t len;
Packit Service f629e6
	    /* Make sure we're calling the actual underlying strftime.
Packit Service f629e6
	       In some cases, config.h contains something like
Packit Service f629e6
	       "#define strftime rpl_strftime".  */
Packit Service f629e6
# ifdef strftime
Packit Service f629e6
#  undef strftime
Packit Service f629e6
	    size_t strftime ();
Packit Service f629e6
# endif
Packit Service f629e6
Packit Service f629e6
	    *u++ = '%';
Packit Service f629e6
	    if (modifier != 0)
Packit Service f629e6
	      *u++ = modifier;
Packit Service f629e6
	    *u++ = format_char;
Packit Service f629e6
	    *u = '\0';
Packit Service f629e6
	    len = strftime (ubuf, sizeof ubuf, ufmt, tp);
Packit Service f629e6
	    if (len == 0 && ubuf[0] != '\0')
Packit Service f629e6
	      return 0;
Packit Service f629e6
	    cpy (len, ubuf);
Packit Service f629e6
	  }
Packit Service f629e6
	  break;
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
	case L_('C'):
Packit Service f629e6
	  if (modifier == L_('O'))
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
	  if (modifier == L_('E'))
Packit Service f629e6
	    {
Packit Service f629e6
#if HAVE_STRUCT_ERA_ENTRY
Packit Service f629e6
	      struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
Packit Service f629e6
	      if (era)
Packit Service f629e6
		{
Packit Service f629e6
# ifdef COMPILE_WIDE
Packit Service f629e6
		  size_t len = __wcslen (era->era_wname);
Packit Service f629e6
		  cpy (len, era->era_wname);
Packit Service f629e6
# else
Packit Service f629e6
		  size_t len = strlen (era->era_name);
Packit Service f629e6
		  cpy (len, era->era_name);
Packit Service f629e6
# endif
Packit Service f629e6
		  break;
Packit Service f629e6
		}
Packit Service f629e6
#else
Packit Service f629e6
# if HAVE_STRFTIME
Packit Service f629e6
	      goto underlying_strftime;
Packit Service f629e6
# endif
Packit Service f629e6
#endif
Packit Service f629e6
	    }
Packit Service f629e6
Packit Service f629e6
	  {
Packit Service f629e6
	    int year = tp->tm_year + TM_YEAR_BASE;
Packit Service f629e6
	    DO_NUMBER (1, year / 100 - (year % 100 < 0));
Packit Service f629e6
	  }
Packit Service f629e6
Packit Service f629e6
	case L_('x'):
Packit Service f629e6
	  if (modifier == L_('O'))
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
#ifdef _NL_CURRENT
Packit Service f629e6
	  if (! (modifier == L_('E')
Packit Service f629e6
		 && (*(subfmt =
Packit Service f629e6
		       (const CHAR_T *)_NL_CURRENT (LC_TIME, NLW(ERA_D_FMT)))
Packit Service f629e6
		     != L_('\0'))))
Packit Service f629e6
	    subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT));
Packit Service f629e6
	  goto subformat;
Packit Service f629e6
#else
Packit Service f629e6
# if HAVE_STRFTIME
Packit Service f629e6
	  goto underlying_strftime;
Packit Service f629e6
# else
Packit Service f629e6
	  /* Fall through.  */
Packit Service f629e6
# endif
Packit Service f629e6
#endif
Packit Service f629e6
	case L_('D'):
Packit Service f629e6
	  if (modifier != 0)
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
	  subfmt = L_("%m/%d/%y");
Packit Service f629e6
	  goto subformat;
Packit Service f629e6
Packit Service f629e6
	case L_('d'):
Packit Service f629e6
	  if (modifier == L_('E'))
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
Packit Service f629e6
	  DO_NUMBER (2, tp->tm_mday);
Packit Service f629e6
Packit Service f629e6
	case L_('e'):
Packit Service f629e6
	  if (modifier == L_('E'))
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
Packit Service f629e6
	  DO_NUMBER_SPACEPAD (2, tp->tm_mday);
Packit Service f629e6
Packit Service f629e6
	  /* All numeric formats set DIGITS and NUMBER_VALUE and then
Packit Service f629e6
	     jump to one of these two labels.  */
Packit Service f629e6
Packit Service f629e6
	do_number_spacepad:
Packit Service f629e6
	  /* Force `_' flag unless overwritten by `0' flag.  */
Packit Service f629e6
	  if (pad != L_('0'))
Packit Service f629e6
	    pad = L_('_');
Packit Service f629e6
Packit Service f629e6
	do_number:
Packit Service f629e6
	  /* Format the number according to the MODIFIER flag.  */
Packit Service f629e6
Packit Service f629e6
	  if (modifier == L_('O') && 0 <= number_value)
Packit Service f629e6
	    {
Packit Service f629e6
#ifdef _NL_CURRENT
Packit Service f629e6
	      /* Get the locale specific alternate representation of
Packit Service f629e6
		 the number NUMBER_VALUE.  If none exist NULL is returned.  */
Packit Service f629e6
	      const CHAR_T *cp = nl_get_alt_digit (number_value
Packit Service f629e6
						   HELPER_LOCALE_ARG);
Packit Service f629e6
Packit Service f629e6
	      if (cp != NULL)
Packit Service f629e6
		{
Packit Service f629e6
		  size_t digitlen = STRLEN (cp);
Packit Service f629e6
		  if (digitlen != 0)
Packit Service f629e6
		    {
Packit Service f629e6
		      cpy (digitlen, cp);
Packit Service f629e6
		      break;
Packit Service f629e6
		    }
Packit Service f629e6
		}
Packit Service f629e6
#else
Packit Service f629e6
# if HAVE_STRFTIME
Packit Service f629e6
	      goto underlying_strftime;
Packit Service f629e6
# endif
Packit Service f629e6
#endif
Packit Service f629e6
	    }
Packit Service f629e6
	  {
Packit Service f629e6
	    unsigned int u = number_value;
Packit Service f629e6
Packit Service f629e6
	    bufp = buf + sizeof (buf) / sizeof (buf[0]);
Packit Service f629e6
	    negative_number = number_value < 0;
Packit Service f629e6
Packit Service f629e6
	    if (negative_number)
Packit Service f629e6
	      u = -u;
Packit Service f629e6
Packit Service f629e6
	    do
Packit Service f629e6
	      *--bufp = u % 10 + L_('0');
Packit Service f629e6
	    while ((u /= 10) != 0);
Packit Service f629e6
  	  }
Packit Service f629e6
Packit Service f629e6
	do_number_sign_and_padding:
Packit Service f629e6
	  if (negative_number)
Packit Service f629e6
	    *--bufp = L_('-');
Packit Service f629e6
Packit Service f629e6
	  if (pad != L_('-'))
Packit Service f629e6
	    {
Packit Service f629e6
	      int padding = digits - (buf + (sizeof (buf) / sizeof (buf[0]))
Packit Service f629e6
				      - bufp);
Packit Service f629e6
Packit Service f629e6
	      if (padding > 0)
Packit Service f629e6
		{
Packit Service f629e6
		  if (pad == L_('_'))
Packit Service f629e6
		    {
Packit Service f629e6
		      if ((size_t) padding >= maxsize - i)
Packit Service f629e6
			return 0;
Packit Service f629e6
Packit Service f629e6
		      if (p)
Packit Service f629e6
			memset_space (p, padding);
Packit Service f629e6
		      i += padding;
Packit Service f629e6
		      width = width > padding ? width - padding : 0;
Packit Service f629e6
		    }
Packit Service f629e6
		  else
Packit Service f629e6
		    {
Packit Service f629e6
		      if ((size_t) digits >= maxsize - i)
Packit Service f629e6
			return 0;
Packit Service f629e6
Packit Service f629e6
		      if (negative_number)
Packit Service f629e6
			{
Packit Service f629e6
			  ++bufp;
Packit Service f629e6
Packit Service f629e6
			  if (p)
Packit Service f629e6
			    *p++ = L_('-');
Packit Service f629e6
			  ++i;
Packit Service f629e6
			}
Packit Service f629e6
Packit Service f629e6
		      if (p)
Packit Service f629e6
			memset_zero (p, padding);
Packit Service f629e6
		      i += padding;
Packit Service f629e6
		      width = 0;
Packit Service f629e6
		    }
Packit Service f629e6
		}
Packit Service f629e6
	    }
Packit Service f629e6
Packit Service f629e6
	  cpy (buf + sizeof (buf) / sizeof (buf[0]) - bufp, bufp);
Packit Service f629e6
	  break;
Packit Service f629e6
Packit Service f629e6
	case L_('F'):
Packit Service f629e6
	  if (modifier != 0)
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
	  subfmt = L_("%Y-%m-%d");
Packit Service f629e6
	  goto subformat;
Packit Service f629e6
Packit Service f629e6
	case L_('H'):
Packit Service f629e6
	  if (modifier == L_('E'))
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
Packit Service f629e6
	  DO_NUMBER (2, tp->tm_hour);
Packit Service f629e6
Packit Service f629e6
	case L_('I'):
Packit Service f629e6
	  if (modifier == L_('E'))
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
Packit Service f629e6
	  DO_NUMBER (2, hour12);
Packit Service f629e6
Packit Service f629e6
	case L_('k'):		/* GNU extension.  */
Packit Service f629e6
	  if (modifier == L_('E'))
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
Packit Service f629e6
	  DO_NUMBER_SPACEPAD (2, tp->tm_hour);
Packit Service f629e6
Packit Service f629e6
	case L_('l'):		/* GNU extension.  */
Packit Service f629e6
	  if (modifier == L_('E'))
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
Packit Service f629e6
	  DO_NUMBER_SPACEPAD (2, hour12);
Packit Service f629e6
Packit Service f629e6
	case L_('j'):
Packit Service f629e6
	  if (modifier == L_('E'))
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
Packit Service f629e6
	  DO_NUMBER (3, 1 + tp->tm_yday);
Packit Service f629e6
Packit Service f629e6
	case L_('M'):
Packit Service f629e6
	  if (modifier == L_('E'))
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
Packit Service f629e6
	  DO_NUMBER (2, tp->tm_min);
Packit Service f629e6
Packit Service f629e6
	case L_('m'):
Packit Service f629e6
	  if (modifier == L_('E'))
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
Packit Service f629e6
	  DO_NUMBER (2, tp->tm_mon + 1);
Packit Service f629e6
Packit Service f629e6
	case L_('n'):
Packit Service f629e6
	  add (1, *p = L_('\n'));
Packit Service f629e6
	  break;
Packit Service f629e6
Packit Service f629e6
	case L_('P'):
Packit Service f629e6
	  to_lowcase = 1;
Packit Service f629e6
#if !defined _NL_CURRENT && HAVE_STRFTIME
Packit Service f629e6
	  format_char = L_('p');
Packit Service f629e6
#endif
Packit Service f629e6
	  /* FALLTHROUGH */
Packit Service f629e6
Packit Service f629e6
	case L_('p'):
Packit Service f629e6
	  if (change_case)
Packit Service f629e6
	    {
Packit Service f629e6
	      to_uppcase = 0;
Packit Service f629e6
	      to_lowcase = 1;
Packit Service f629e6
	    }
Packit Service f629e6
#if defined _NL_CURRENT || !HAVE_STRFTIME
Packit Service f629e6
	  cpy (ap_len, ampm);
Packit Service f629e6
	  break;
Packit Service f629e6
#else
Packit Service f629e6
	  goto underlying_strftime;
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
	case L_('R'):
Packit Service f629e6
	  subfmt = L_("%H:%M");
Packit Service f629e6
	  goto subformat;
Packit Service f629e6
Packit Service f629e6
	case L_('r'):
Packit Service f629e6
#ifdef _NL_CURRENT
Packit Service f629e6
	  if (*(subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME,
Packit Service f629e6
						       NLW(T_FMT_AMPM)))
Packit Service f629e6
	      == L_('\0'))
Packit Service f629e6
#endif
Packit Service f629e6
	    subfmt = L_("%I:%M:%S %p");
Packit Service f629e6
	  goto subformat;
Packit Service f629e6
Packit Service f629e6
	case L_('S'):
Packit Service f629e6
	  if (modifier == L_('E'))
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
Packit Service f629e6
	  DO_NUMBER (2, tp->tm_sec);
Packit Service f629e6
Packit Service f629e6
	case L_('s'):		/* GNU extension.  */
Packit Service f629e6
  	  {
Packit Service f629e6
	    struct tm ltm;
Packit Service f629e6
	    time_t t;
Packit Service f629e6
Packit Service f629e6
	    ltm = *tp;
Packit Service f629e6
	    t = mktime (<m;;
Packit Service f629e6
Packit Service f629e6
	    /* Generate string value for T using time_t arithmetic;
Packit Service f629e6
	       this works even if sizeof (long) < sizeof (time_t).  */
Packit Service f629e6
Packit Service f629e6
	    bufp = buf + sizeof (buf) / sizeof (buf[0]);
Packit Service f629e6
#ifndef TIME_T_UNSIGNED
Packit Service f629e6
	    negative_number = t < 0;
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
	    do
Packit Service f629e6
	      {
Packit Service f629e6
		int d = t % 10;
Packit Service f629e6
		t /= 10;
Packit Service f629e6
Packit Service f629e6
#ifndef TIME_T_UNSIGNED
Packit Service f629e6
		if (negative_number)
Packit Service f629e6
		  {
Packit Service f629e6
		    d = -d;
Packit Service f629e6
Packit Service f629e6
		    /* Adjust if division truncates to minus infinity.  */
Packit Service f629e6
		    if (0 < -1 % 10 && d < 0)
Packit Service f629e6
		      {
Packit Service f629e6
			t++;
Packit Service f629e6
			d += 10;
Packit Service f629e6
		      }
Packit Service f629e6
		  }
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
		*--bufp = d + L_('0');
Packit Service f629e6
	      }
Packit Service f629e6
	    while (t != 0);
Packit Service f629e6
Packit Service f629e6
	    digits = 1;
Packit Service f629e6
	    goto do_number_sign_and_padding;
Packit Service f629e6
	  }
Packit Service f629e6
Packit Service f629e6
	case L_('X'):
Packit Service f629e6
	  if (modifier == L_('O'))
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
#ifdef _NL_CURRENT
Packit Service f629e6
	  if (! (modifier == L_('E')
Packit Service f629e6
		 && (*(subfmt =
Packit Service f629e6
		       (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ERA_T_FMT)))
Packit Service f629e6
		     != L_('\0'))))
Packit Service f629e6
	    subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT));
Packit Service f629e6
	  goto subformat;
Packit Service f629e6
#else
Packit Service f629e6
# if HAVE_STRFTIME
Packit Service f629e6
	  goto underlying_strftime;
Packit Service f629e6
# else
Packit Service f629e6
	  /* Fall through.  */
Packit Service f629e6
# endif
Packit Service f629e6
#endif
Packit Service f629e6
	case L_('T'):
Packit Service f629e6
	  subfmt = L_("%H:%M:%S");
Packit Service f629e6
	  goto subformat;
Packit Service f629e6
Packit Service f629e6
	case L_('t'):
Packit Service f629e6
	  add (1, *p = L_('\t'));
Packit Service f629e6
	  break;
Packit Service f629e6
Packit Service f629e6
	case L_('u'):
Packit Service f629e6
	  DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
Packit Service f629e6
Packit Service f629e6
	case L_('U'):
Packit Service f629e6
	  if (modifier == L_('E'))
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
Packit Service f629e6
	  DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
Packit Service f629e6
Packit Service f629e6
	case L_('V'):
Packit Service f629e6
	case L_('g'):
Packit Service f629e6
	case L_('G'):
Packit Service f629e6
	  if (modifier == L_('E'))
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
	  {
Packit Service f629e6
	    int year = tp->tm_year + TM_YEAR_BASE;
Packit Service f629e6
	    int days = iso_week_days (tp->tm_yday, tp->tm_wday);
Packit Service f629e6
Packit Service f629e6
	    if (days < 0)
Packit Service f629e6
	      {
Packit Service f629e6
		/* This ISO week belongs to the previous year.  */
Packit Service f629e6
		year--;
Packit Service f629e6
		days = iso_week_days (tp->tm_yday + (365 + __isleap (year)),
Packit Service f629e6
				      tp->tm_wday);
Packit Service f629e6
	      }
Packit Service f629e6
	    else
Packit Service f629e6
	      {
Packit Service f629e6
		int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
Packit Service f629e6
				       tp->tm_wday);
Packit Service f629e6
		if (0 <= d)
Packit Service f629e6
		  {
Packit Service f629e6
		    /* This ISO week belongs to the next year.  */
Packit Service f629e6
		    year++;
Packit Service f629e6
		    days = d;
Packit Service f629e6
		  }
Packit Service f629e6
	      }
Packit Service f629e6
Packit Service f629e6
	    switch (*f)
Packit Service f629e6
	      {
Packit Service f629e6
	      case L_('g'):
Packit Service f629e6
		DO_NUMBER (2, (year % 100 + 100) % 100);
Packit Service f629e6
Packit Service f629e6
	      case L_('G'):
Packit Service f629e6
		DO_NUMBER (1, year);
Packit Service f629e6
Packit Service f629e6
	      default:
Packit Service f629e6
		DO_NUMBER (2, days / 7 + 1);
Packit Service f629e6
	      }
Packit Service f629e6
	  }
Packit Service f629e6
Packit Service f629e6
	case L_('W'):
Packit Service f629e6
	  if (modifier == L_('E'))
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
Packit Service f629e6
	  DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
Packit Service f629e6
Packit Service f629e6
	case L_('w'):
Packit Service f629e6
	  if (modifier == L_('E'))
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
Packit Service f629e6
	  DO_NUMBER (1, tp->tm_wday);
Packit Service f629e6
Packit Service f629e6
	case L_('Y'):
Packit Service f629e6
	  if (modifier == 'E')
Packit Service f629e6
	    {
Packit Service f629e6
#if HAVE_STRUCT_ERA_ENTRY
Packit Service f629e6
	      struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
Packit Service f629e6
	      if (era)
Packit Service f629e6
		{
Packit Service f629e6
# ifdef COMPILE_WIDE
Packit Service f629e6
		  subfmt = era->era_wformat;
Packit Service f629e6
# else
Packit Service f629e6
		  subfmt = era->era_format;
Packit Service f629e6
# endif
Packit Service f629e6
		  goto subformat;
Packit Service f629e6
		}
Packit Service f629e6
#else
Packit Service f629e6
# if HAVE_STRFTIME
Packit Service f629e6
	      goto underlying_strftime;
Packit Service f629e6
# endif
Packit Service f629e6
#endif
Packit Service f629e6
	    }
Packit Service f629e6
	  if (modifier == L_('O'))
Packit Service f629e6
	    goto bad_format;
Packit Service f629e6
	  else
Packit Service f629e6
	    DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE);
Packit Service f629e6
Packit Service f629e6
	case L_('y'):
Packit Service f629e6
	  if (modifier == L_('E'))
Packit Service f629e6
	    {
Packit Service f629e6
#if HAVE_STRUCT_ERA_ENTRY
Packit Service f629e6
	      struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
Packit Service f629e6
	      if (era)
Packit Service f629e6
		{
Packit Service f629e6
		  int delta = tp->tm_year - era->start_date[0];
Packit Service f629e6
		  DO_NUMBER (1, (era->offset
Packit Service f629e6
				 + delta * era->absolute_direction));
Packit Service f629e6
		}
Packit Service f629e6
#else
Packit Service f629e6
# if HAVE_STRFTIME
Packit Service f629e6
	      goto underlying_strftime;
Packit Service f629e6
# endif
Packit Service f629e6
#endif
Packit Service f629e6
	    }
Packit Service f629e6
	  DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100);
Packit Service f629e6
Packit Service f629e6
	case L_('Z'):
Packit Service f629e6
	  if (change_case)
Packit Service f629e6
	    {
Packit Service f629e6
	      to_uppcase = 0;
Packit Service f629e6
	      to_lowcase = 1;
Packit Service f629e6
	    }
Packit Service f629e6
Packit Service f629e6
#if HAVE_TZNAME
Packit Service f629e6
	  /* The tzset() call might have changed the value.  */
Packit Service f629e6
	  if (!(zone && *zone) && tp->tm_isdst >= 0)
Packit Service f629e6
	    zone = tzname[tp->tm_isdst];
Packit Service f629e6
#endif
Packit Service f629e6
	  if (! zone)
Packit Service f629e6
	    zone = "";
Packit Service f629e6
Packit Service f629e6
#ifdef COMPILE_WIDE
Packit Service f629e6
	  {
Packit Service f629e6
	    /* The zone string is always given in multibyte form.  We have
Packit Service f629e6
	       to transform it first.  */
Packit Service f629e6
	    wchar_t *wczone;
Packit Service f629e6
	    size_t len;
Packit Service f629e6
	    widen (zone, wczone, len);
Packit Service f629e6
	    cpy (len, wczone);
Packit Service f629e6
	  }
Packit Service f629e6
#else
Packit Service f629e6
	  cpy (strlen (zone), zone);
Packit Service f629e6
#endif
Packit Service f629e6
	  break;
Packit Service f629e6
Packit Service f629e6
	case L_('z'):
Packit Service f629e6
	  if (tp->tm_isdst < 0)
Packit Service f629e6
	    break;
Packit Service f629e6
Packit Service f629e6
	  {
Packit Service f629e6
	    int diff;
Packit Service f629e6
#if HAVE_TM_GMTOFF
Packit Service f629e6
	    diff = tp->tm_gmtoff;
Packit Service f629e6
#else
Packit Service f629e6
	    if (ut)
Packit Service f629e6
	      diff = 0;
Packit Service f629e6
	    else
Packit Service f629e6
	      {
Packit Service f629e6
		struct tm gtm;
Packit Service f629e6
		struct tm ltm;
Packit Service f629e6
		time_t lt;
Packit Service f629e6
Packit Service f629e6
		ltm = *tp;
Packit Service f629e6
		lt = mktime (<m;;
Packit Service f629e6
Packit Service f629e6
		if (lt == (time_t) -1)
Packit Service f629e6
		  {
Packit Service f629e6
		    /* mktime returns -1 for errors, but -1 is also a
Packit Service f629e6
		       valid time_t value.  Check whether an error really
Packit Service f629e6
		       occurred.  */
Packit Service f629e6
		    struct tm tm;
Packit Service f629e6
Packit Service f629e6
		    if (! my_strftime_localtime_r (&lt, &tm)
Packit Service f629e6
			|| ((ltm.tm_sec ^ tm.tm_sec)
Packit Service f629e6
			    | (ltm.tm_min ^ tm.tm_min)
Packit Service f629e6
			    | (ltm.tm_hour ^ tm.tm_hour)
Packit Service f629e6
			    | (ltm.tm_mday ^ tm.tm_mday)
Packit Service f629e6
			    | (ltm.tm_mon ^ tm.tm_mon)
Packit Service f629e6
			    | (ltm.tm_year ^ tm.tm_year)))
Packit Service f629e6
		      break;
Packit Service f629e6
		  }
Packit Service f629e6
Packit Service f629e6
		if (! my_strftime_gmtime_r (&lt, &gtm))
Packit Service f629e6
		  break;
Packit Service f629e6
Packit Service f629e6
		diff = tm_diff (&ltm, >m;;
Packit Service f629e6
	      }
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
	    if (diff < 0)
Packit Service f629e6
	      {
Packit Service f629e6
		add (1, *p = L_('-'));
Packit Service f629e6
		diff = -diff;
Packit Service f629e6
	      }
Packit Service f629e6
	    else
Packit Service f629e6
	      add (1, *p = L_('+'));
Packit Service f629e6
Packit Service f629e6
	    diff /= 60;
Packit Service f629e6
	    DO_NUMBER (4, (diff / 60) * 100 + diff % 60);
Packit Service f629e6
	  }
Packit Service f629e6
Packit Service f629e6
	case L_('\0'):		/* GNU extension: % at end of format.  */
Packit Service f629e6
	    --f;
Packit Service f629e6
	    /* Fall through.  */
Packit Service f629e6
	default:
Packit Service f629e6
	  /* Unknown format; output the format, including the '%',
Packit Service f629e6
	     since this is most likely the right thing to do if a
Packit Service f629e6
	     multibyte string has been misparsed.  */
Packit Service f629e6
	bad_format:
Packit Service f629e6
	  {
Packit Service f629e6
	    int flen;
Packit Service f629e6
	    for (flen = 1; f[1 - flen] != L_('%'); flen++)
Packit Service f629e6
	      continue;
Packit Service f629e6
	    cpy (flen, &f[1 - flen]);
Packit Service f629e6
	  }
Packit Service f629e6
	  break;
Packit Service f629e6
	}
Packit Service f629e6
    }
Packit Service f629e6
Packit Service f629e6
  if (p && maxsize != 0)
Packit Service f629e6
    *p = L_('\0');
Packit Service f629e6
  return i;
Packit Service f629e6
}
Packit Service f629e6
#ifdef _LIBC
Packit Service f629e6
libc_hidden_def (my_strftime)
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
Packit Service f629e6
#ifdef emacs
Packit Service f629e6
/* For Emacs we have a separate interface which corresponds to the normal
Packit Service f629e6
   strftime function and does not have the extra information whether the
Packit Service f629e6
   TP arguments comes from a `gmtime' call or not.  */
Packit Service f629e6
size_t
Packit Service f629e6
emacs_strftime (s, maxsize, format, tp)
Packit Service f629e6
      char *s;
Packit Service f629e6
      size_t maxsize;
Packit Service f629e6
      const char *format;
Packit Service f629e6
      const struct tm *tp;
Packit Service f629e6
{
Packit Service f629e6
  return my_strftime (s, maxsize, format, tp, 0);
Packit Service f629e6
}
Packit Service f629e6
#endif