You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
+/* If FPRINTFTIME is set to 1, this file defines a function with a
+ 'FILE *fp' parameter instead of two 'char *s, size_t max' parameters. */
#ifndef FPRINTFTIME
# define FPRINTFTIME 0
#endif
+/* If USE_C_LOCALE is set to 1, this file defines a function that uses the
+ "C" locale, regardless of the current locale. */
#ifndef USE_C_LOCALE
# define USE_C_LOCALE 0
#endif
# include "time-internal.h"
#endif
+/* Whether the system supports no localized output at all, that is, whether
+ strftime's output does not depend on the current locale. */
+#if defined __ANDROID__
+# define HAVE_ONLY_C_LOCALE 1
+#else
+# define HAVE_ONLY_C_LOCALE 0
+#endif
+
/* Whether to require GNU behavior for AM and PM indicators, even on
other platforms. This matters only in non-C locales.
The default is to require it; you can override this via
#ifndef REQUIRE_GNUISH_STRFTIME_AM_PM
# define REQUIRE_GNUISH_STRFTIME_AM_PM true
#endif
-#if USE_C_LOCALE
+#if HAVE_ONLY_C_LOCALE || USE_C_LOCALE
# undef REQUIRE_GNUISH_STRFTIME_AM_PM
# define REQUIRE_GNUISH_STRFTIME_AM_PM false
#endif
-#if USE_C_LOCALE
+#if HAVE_ONLY_C_LOCALE || USE_C_LOCALE
# include "c-ctype.h"
#else
# include <ctype.h>
# define TOUPPER(Ch, L) __toupper_l (Ch, L)
# define TOLOWER(Ch, L) __tolower_l (Ch, L)
# else
-# if USE_C_LOCALE
+# if HAVE_ONLY_C_LOCALE || USE_C_LOCALE
# define TOUPPER(Ch, L) c_toupper (Ch)
# define TOLOWER(Ch, L) c_tolower (Ch)
# else
#define HAVE_NATIVE_TIME_Z \
(USE_C_LOCALE && HAVE_STRFTIME_L ? HAVE_STRFTIME_LZ : HAVE_STRFTIME_Z)
-#if USE_C_LOCALE && HAVE_STRFTIME_L
+#if (!HAVE_ONLY_C_LOCALE || !HAVE_STRUCT_TM_TM_ZONE) \
+ && USE_C_LOCALE && HAVE_STRFTIME_L
/* Cache for the C locale object.
Marked volatile so that different threads see the same value
#endif
-#if HAVE_NATIVE_TIME_Z
+#if !defined _LIBC \
+ && (!(HAVE_ONLY_C_LOCALE || (USE_C_LOCALE && !HAVE_STRFTIME_L)) \
+ || !HAVE_STRUCT_TM_TM_ZONE) \
+ && HAVE_NATIVE_TIME_Z
/* On NetBSD a null tz has undefined behavior, so use a non-null tz.
Cache the UTC time zone object in a volatile variable for improved
}
-#if !defined _NL_CURRENT && (USE_C_LOCALE && !HAVE_STRFTIME_L)
+#if !defined _NL_CURRENT && (HAVE_ONLY_C_LOCALE || (USE_C_LOCALE && !HAVE_STRFTIME_L))
static CHAR_T const c_weekday_names[][sizeof "Wednesday"] =
{
L_("Sunday"), L_("Monday"), L_("Tuesday"), L_("Wednesday"),
extra_args_spec LOCALE_PARAM);
#if !defined _LIBC \
- && (!(USE_C_LOCALE && !HAVE_STRFTIME_L) || !HAVE_STRUCT_TM_TM_ZONE)
+ && (!(HAVE_ONLY_C_LOCALE || (USE_C_LOCALE && !HAVE_STRFTIME_L)) \
+ || !HAVE_STRUCT_TM_TM_ZONE)
/* Make sure we're calling the actual underlying strftime.
In some cases, time.h contains something like
*TP is computed with a totally different time zone.
This is bogus: though POSIX allows bad behavior like this,
POSIX does not require it. Do the right thing instead. */
- return tp->tm_zone;
+ const char *ret = tp->tm_zone;
+# if defined __ANDROID__
+ if (!ret)
+ ret = "";
+# endif
+ return ret;
#else
if (!tz)
return "UTC";
# define am_len STRLEN (a_month)
# define aam_len STRLEN (a_altmonth)
# define ap_len STRLEN (ampm)
-#elif USE_C_LOCALE && !HAVE_STRFTIME_L
+#elif HAVE_ONLY_C_LOCALE || (USE_C_LOCALE && !HAVE_STRFTIME_L)
/* The English abbreviated weekday names are just the first 3 characters of the
English full weekday names. */
# define a_wkday \
to_uppcase = true;
to_lowcase = false;
}
-#if defined _NL_CURRENT || (USE_C_LOCALE && !HAVE_STRFTIME_L)
+#if defined _NL_CURRENT || HAVE_ONLY_C_LOCALE || (USE_C_LOCALE && !HAVE_STRFTIME_L)
cpy (aw_len, a_wkday);
break;
#else
to_uppcase = true;
to_lowcase = false;
}
-#if defined _NL_CURRENT || (USE_C_LOCALE && !HAVE_STRFTIME_L)
+#if defined _NL_CURRENT || HAVE_ONLY_C_LOCALE || (USE_C_LOCALE && !HAVE_STRFTIME_L)
cpy (STRLEN (f_wkday), f_wkday);
break;
#else
else
cpy (am_len, a_month);
break;
-#elif USE_C_LOCALE && !HAVE_STRFTIME_L
+#elif HAVE_ONLY_C_LOCALE || (USE_C_LOCALE && !HAVE_STRFTIME_L)
cpy (am_len, a_month);
break;
#else
else
cpy (STRLEN (f_month), f_month);
break;
-#elif USE_C_LOCALE && !HAVE_STRFTIME_L
+#elif HAVE_ONLY_C_LOCALE || (USE_C_LOCALE && !HAVE_STRFTIME_L)
cpy (STRLEN (f_month), f_month);
break;
#else
NLW(ERA_D_T_FMT)))
!= '\0')))
subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT));
-#elif USE_C_LOCALE && !HAVE_STRFTIME_L
+#elif HAVE_ONLY_C_LOCALE || (USE_C_LOCALE && !HAVE_STRFTIME_L)
subfmt = L_("%a %b %e %H:%M:%S %Y");
#elif defined _WIN32 && !defined __CYGWIN__
/* On native Windows, "%c" is "%d/%m/%Y %H:%M:%S" by default. */
}
break;
-#if !defined _LIBC && !(USE_C_LOCALE && !HAVE_STRFTIME_L)
+#if !defined _LIBC && !(HAVE_ONLY_C_LOCALE || (USE_C_LOCALE && !HAVE_STRFTIME_L))
underlying_strftime:
{
char ubuf[1024]; /* enough for any single format in practice */
# endif
break;
}
-#elif USE_C_LOCALE && !HAVE_STRFTIME_L
+#elif HAVE_ONLY_C_LOCALE || (USE_C_LOCALE && !HAVE_STRFTIME_L)
#else
goto underlying_strftime;
#endif
!= L_('\0'))))
subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT));
goto subformat;
-#elif USE_C_LOCALE && !HAVE_STRFTIME_L
+#elif HAVE_ONLY_C_LOCALE || (USE_C_LOCALE && !HAVE_STRFTIME_L)
subfmt = L_("%m/%d/%y");
goto subformat;
#else
break;
}
}
-#elif USE_C_LOCALE && !HAVE_STRFTIME_L
+#elif HAVE_ONLY_C_LOCALE || (USE_C_LOCALE && !HAVE_STRFTIME_L)
#else
goto underlying_strftime;
#endif
to_uppcase = false;
to_lowcase = true;
}
-#if defined _NL_CURRENT || (USE_C_LOCALE && !HAVE_STRFTIME_L)
+#if defined _NL_CURRENT || HAVE_ONLY_C_LOCALE || (USE_C_LOCALE && !HAVE_STRFTIME_L)
cpy (ap_len, ampm);
break;
#else
== L_('\0'))
subfmt = L_("%I:%M:%S %p");
goto subformat;
-#elif USE_C_LOCALE && !HAVE_STRFTIME_L
+#elif HAVE_ONLY_C_LOCALE || (USE_C_LOCALE && !HAVE_STRFTIME_L)
subfmt = L_("%I:%M:%S %p");
goto subformat;
#elif ((defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ \
!= L_('\0'))))
subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT));
goto subformat;
-#elif USE_C_LOCALE && !HAVE_STRFTIME_L
+#elif HAVE_ONLY_C_LOCALE || (USE_C_LOCALE && !HAVE_STRFTIME_L)
subfmt = L_("%H:%M:%S");
goto subformat;
#else
pad = yr_spec;
goto subformat;
}
-#elif USE_C_LOCALE && !HAVE_STRFTIME_L
+#elif HAVE_ONLY_C_LOCALE || (USE_C_LOCALE && !HAVE_STRFTIME_L)
#else
goto underlying_strftime;
#endif
DO_NUMBER (2, (era->offset
+ delta * era->absolute_direction));
}
-#elif USE_C_LOCALE && !HAVE_STRFTIME_L
+#elif HAVE_ONLY_C_LOCALE || (USE_C_LOCALE && !HAVE_STRFTIME_L)
#else
goto underlying_strftime;
#endif