* new module 'c-nstrftime'
@ 2024-02-08 0:29 Bruno Haible
0 siblings, 0 replies; only message in thread
From: Bruno Haible @ 2024-02-08 0:29 UTC (permalink / raw)
To: bug-gnulib
[-- Attachment #1: Type: text/plain, Size: 1470 bytes --]
Paul Eggert suggested a new module 'c-nstrftime', as the base for the
migration away from function 'ctime'.
These two patches implement it.
2024-02-07 Bruno Haible <bruno@clisp.org>
c-nstrftime: Add tests.
* tests/test-c-nstrftime.c: New file, based on tests/test-nstrftime.c.
* tests/test-c-nstrftime-1.sh: New file, based on
tests/test-nstrftime-1.sh.
* tests/test-c-nstrftime-2.sh: New file, based on
tests/test-nstrftime-2.sh.
* modules/c-nstrftime-tests: New file.
c-nstrftime: New module.
Suggested by Paul Eggert.
* lib/strftime.h (c_nstrftime): New declaration.
* lib/c-nstrftime.c: New file.
* lib/strftime.c (FPRINTFTIME): Move fallback definition before its
first use.
(USE_C_LOCALE): Add fallback definition.
If USE_C_LOCALE is set, include c-ctype.h instead of <ctype.h>.
Conditionally include <locale.h>.
(TOUPPER, TOLOWER): Define differently if USE_C_LOCALE is set.
(c_locale_cache, c_locale): New definitions, copied from lib/c-strtod.c.
(c_weekday_names, c_month_names): New variables, based on
glibc/time/strftime_l.c.
(__strftime_internal): Define a_wkday, aw_len, f_wkday, a_month, am_len,
f_month, ampm, ap_len differently for USE_C_LOCALE. Avoid a
'goto underlying_strftime' if USE_C_LOCALE && !HAVE_STRFTIME_L. If
USE_C_LOCALE, use strftime_l() with the C locale object instead of
strftime().
* m4/c-nstrftime.m4: New file, based on m4/nstrftime.m4.
* modules/c-nstrftime: New file, based on modules/nstrftime.
[-- Attachment #2: 0001-c-nstrftime-New-module.patch --]
[-- Type: text/x-patch, Size: 15674 bytes --]
From 2e665106444eb32b81e8e94df4b5d8e67723837f Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Thu, 8 Feb 2024 01:09:08 +0100
Subject: [PATCH 1/2] c-nstrftime: New module.
Suggested by Paul Eggert.
* lib/strftime.h (c_nstrftime): New declaration.
* lib/c-nstrftime.c: New file.
* lib/strftime.c (FPRINTFTIME): Move fallback definition before its
first use.
(USE_C_LOCALE): Add fallback definition.
If USE_C_LOCALE is set, include c-ctype.h instead of <ctype.h>.
Conditionally include <locale.h>.
(TOUPPER, TOLOWER): Define differently if USE_C_LOCALE is set.
(c_locale_cache, c_locale): New definitions, copied from lib/c-strtod.c.
(c_weekday_names, c_month_names): New variables, based on
glibc/time/strftime_l.c.
(__strftime_internal): Define a_wkday, aw_len, f_wkday, a_month, am_len,
f_month, ampm, ap_len differently for USE_C_LOCALE. Avoid a
'goto underlying_strftime' if USE_C_LOCALE && !HAVE_STRFTIME_L. Make the
strftime fallback declaration ISO C 23 compliant. If USE_C_LOCALE, use
strftime_l() with the C locale object instead of strftime().
* m4/c-nstrftime.m4: New file, based on m4/nstrftime.m4.
* modules/c-nstrftime: New file, based on modules/nstrftime.
---
ChangeLog | 23 +++++++++
lib/c-nstrftime.c | 20 ++++++++
lib/strftime.c | 121 ++++++++++++++++++++++++++++++++++++++++----
lib/strftime.h | 6 +++
m4/c-nstrftime.m4 | 21 ++++++++
modules/c-nstrftime | 37 ++++++++++++++
6 files changed, 217 insertions(+), 11 deletions(-)
create mode 100644 lib/c-nstrftime.c
create mode 100644 m4/c-nstrftime.m4
create mode 100644 modules/c-nstrftime
diff --git a/ChangeLog b/ChangeLog
index ecbe0ea7b2..0d9b82b1e9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2024-02-07 Bruno Haible <bruno@clisp.org>
+
+ c-nstrftime: New module.
+ Suggested by Paul Eggert.
+ * lib/strftime.h (c_nstrftime): New declaration.
+ * lib/c-nstrftime.c: New file.
+ * lib/strftime.c (FPRINTFTIME): Move fallback definition before its
+ first use.
+ (USE_C_LOCALE): Add fallback definition.
+ If USE_C_LOCALE is set, include c-ctype.h instead of <ctype.h>.
+ Conditionally include <locale.h>.
+ (TOUPPER, TOLOWER): Define differently if USE_C_LOCALE is set.
+ (c_locale_cache, c_locale): New definitions, copied from lib/c-strtod.c.
+ (c_weekday_names, c_month_names): New variables, based on
+ glibc/time/strftime_l.c.
+ (__strftime_internal): Define a_wkday, aw_len, f_wkday, a_month, am_len,
+ f_month, ampm, ap_len differently for USE_C_LOCALE. Avoid a
+ 'goto underlying_strftime' if USE_C_LOCALE && !HAVE_STRFTIME_L. If
+ USE_C_LOCALE, use strftime_l() with the C locale object instead of
+ strftime().
+ * m4/c-nstrftime.m4: New file, based on m4/nstrftime.m4.
+ * modules/c-nstrftime: New file, based on modules/nstrftime.
+
2024-02-07 Bruno Haible <bruno@clisp.org>
nstrftime: Add tests of all directives, also in non-trivial locales.
diff --git a/lib/c-nstrftime.c b/lib/c-nstrftime.c
new file mode 100644
index 0000000000..cee7437e10
--- /dev/null
+++ b/lib/c-nstrftime.c
@@ -0,0 +1,20 @@
+/* Generate time strings in the "C" locale.
+
+ Copyright (C) 2024 Free Software Foundation, Inc.
+
+ This file is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ 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/>. */
+
+#define USE_C_LOCALE 1
+#define my_strftime c_nstrftime
+#include "strftime.c"
diff --git a/lib/strftime.c b/lib/strftime.c
index d81c7eddfa..f6714524bd 100644
--- a/lib/strftime.c
+++ b/lib/strftime.c
@@ -14,6 +14,14 @@
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/>. */
+#ifndef FPRINTFTIME
+# define FPRINTFTIME 0
+#endif
+
+#ifndef USE_C_LOCALE
+# define USE_C_LOCALE 0
+#endif
+
#ifdef _LIBC
# define USE_IN_EXTENDED_LOCALE_MODEL 1
# define HAVE_STRUCT_ERA_ENTRY 1
@@ -31,7 +39,11 @@
# include "time-internal.h"
#endif
-#include <ctype.h>
+#if USE_C_LOCALE
+# include "c-ctype.h"
+#else
+# include <ctype.h>
+#endif
#include <errno.h>
#include <time.h>
@@ -67,6 +79,10 @@ extern char *tzname[];
#include <stdlib.h>
#include <string.h>
+#if USE_C_LOCALE && HAVE_STRFTIME_L
+# include <locale.h>
+#endif
+
#include "attribute.h"
#include <intprops.h>
@@ -127,10 +143,6 @@ extern char *tzname[];
# define mktime(tp) __mktime64 (tp)
#endif
-#ifndef FPRINTFTIME
-# define FPRINTFTIME 0
-#endif
-
#if FPRINTFTIME
# define STREAM_OR_CHAR_T FILE
# define STRFTIME_ARG(x) /* empty */
@@ -270,8 +282,13 @@ extern char *tzname[];
# define TOUPPER(Ch, L) __toupper_l (Ch, L)
# define TOLOWER(Ch, L) __tolower_l (Ch, L)
# else
-# define TOUPPER(Ch, L) toupper (Ch)
-# define TOLOWER(Ch, L) tolower (Ch)
+# if USE_C_LOCALE
+# define TOUPPER(Ch, L) c_toupper (Ch)
+# define TOLOWER(Ch, L) c_tolower (Ch)
+# else
+# define TOUPPER(Ch, L) toupper (Ch)
+# define TOLOWER(Ch, L) tolower (Ch)
+# endif
# endif
#endif
/* We don't use 'isdigit' here since the locale dependent
@@ -333,6 +350,26 @@ memcpy_uppcase (CHAR_T *dest, const CHAR_T *src, size_t len LOCALE_PARAM)
#endif
+#if USE_C_LOCALE && HAVE_STRFTIME_L
+
+/* Cache for the C locale object.
+ Marked volatile so that different threads see the same value
+ (avoids locking). */
+static volatile locale_t c_locale_cache;
+
+/* Return the C locale object, or (locale_t) 0 with errno set
+ if it cannot be created. */
+static locale_t
+c_locale (void)
+{
+ if (!c_locale_cache)
+ c_locale_cache = newlocale (LC_ALL_MASK, "C", (locale_t) 0);
+ return c_locale_cache;
+}
+
+#endif
+
+
#if ! HAVE_TM_GMTOFF
/* Yield the difference between *A and *B,
measured in seconds, ignoring leap seconds. */
@@ -381,6 +418,21 @@ iso_week_days (int yday, int wday)
}
+#if !defined _NL_CURRENT && (USE_C_LOCALE && !HAVE_STRFTIME_L)
+static CHAR_T const c_weekday_names[][sizeof "Wednesday"] =
+ {
+ L_("Sunday"), L_("Monday"), L_("Tuesday"), L_("Wednesday"),
+ L_("Thursday"), L_("Friday"), L_("Saturday")
+ };
+static CHAR_T const c_month_names[][sizeof "September"] =
+ {
+ L_("January"), L_("February"), L_("March"), L_("April"), L_("May"),
+ L_("June"), L_("July"), L_("August"), L_("September"), L_("October"),
+ L_("November"), L_("December")
+ };
+#endif
+
+
/* When compiling this file, GNU applications can #define my_strftime
to a symbol (typically nstrftime) to get an extended strftime with
extra arguments TZ and NS. */
@@ -478,6 +530,24 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
# define am_len STRLEN (a_month)
# define aam_len STRLEN (a_altmonth)
# define ap_len STRLEN (ampm)
+#elif 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 \
+ (tp->tm_wday < 0 || tp->tm_wday > 6 ? L_("?") : c_weekday_names[tp->tm_wday])
+# define aw_len 3
+# define f_wkday \
+ (tp->tm_wday < 0 || tp->tm_wday > 6 ? L_("?") : c_weekday_names[tp->tm_wday])
+/* The English abbreviated month names are just the first 3 characters of the
+ English full month names. */
+# define a_month \
+ (tp->tm_mon < 0 || tp->tm_mon > 11 ? L_("?") : c_month_names[tp->tm_mon])
+# define am_len 3
+# define f_month \
+ (tp->tm_mon < 0 || tp->tm_mon > 11 ? L_("?") : c_month_names[tp->tm_mon])
+/* The English AM/PM strings happen to have the same length, namely 2. */
+# define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11))
+# define ap_len 2
#endif
#if HAVE_TZNAME
char **tzname_vec = tzname;
@@ -765,7 +835,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
to_uppcase = true;
to_lowcase = false;
}
-#ifdef _NL_CURRENT
+#if defined _NL_CURRENT || (USE_C_LOCALE && !HAVE_STRFTIME_L)
cpy (aw_len, a_wkday);
break;
#else
@@ -780,7 +850,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
to_uppcase = true;
to_lowcase = false;
}
-#ifdef _NL_CURRENT
+#if defined _NL_CURRENT || (USE_C_LOCALE && !HAVE_STRFTIME_L)
cpy (STRLEN (f_wkday), f_wkday);
break;
#else
@@ -802,6 +872,9 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
else
cpy (am_len, a_month);
break;
+#elif USE_C_LOCALE && !HAVE_STRFTIME_L
+ cpy (am_len, a_month);
+ break;
#else
goto underlying_strftime;
#endif
@@ -820,6 +893,9 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
else
cpy (STRLEN (f_month), f_month);
break;
+#elif USE_C_LOCALE && !HAVE_STRFTIME_L
+ cpy (STRLEN (f_month), f_month);
+ break;
#else
goto underlying_strftime;
#endif
@@ -834,6 +910,8 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
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
+ subfmt = L_("%a %b %e %H:%M:%S %Y");
#else
goto underlying_strftime;
#endif
@@ -854,7 +932,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
}
break;
-#if !(defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
+#if !((defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY) || (USE_C_LOCALE && !HAVE_STRFTIME_L))
underlying_strftime:
{
/* The relevant information is available only via the
@@ -879,7 +957,15 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
*u++ = modifier;
*u++ = format_char;
*u = '\0';
+
+# if USE_C_LOCALE /* implies HAVE_STRFTIME_L */
+ locale_t locale = c_locale ();
+ if (!locale)
+ return 0; /* errno is set here */
+ len = strftime_l (ubuf, sizeof ubuf, ufmt, tp, locale);
+# else
len = strftime (ubuf, sizeof ubuf, ufmt, tp);
+# endif
if (len != 0)
cpy (len - 1, ubuf + 1);
}
@@ -902,6 +988,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
# endif
break;
}
+#elif USE_C_LOCALE && !HAVE_STRFTIME_L
#else
goto underlying_strftime;
#endif
@@ -925,6 +1012,9 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
!= L_('\0'))))
subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT));
goto subformat;
+#elif USE_C_LOCALE && !HAVE_STRFTIME_L
+ subfmt = L_("%m/%d/%y");
+ goto subformat;
#else
goto underlying_strftime;
#endif
@@ -1000,6 +1090,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
break;
}
}
+#elif USE_C_LOCALE && !HAVE_STRFTIME_L
#else
goto underlying_strftime;
#endif
@@ -1147,7 +1238,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
to_uppcase = false;
to_lowcase = true;
}
-#ifdef _NL_CURRENT
+#if defined _NL_CURRENT || (USE_C_LOCALE && !HAVE_STRFTIME_L)
cpy (ap_len, ampm);
break;
#else
@@ -1168,6 +1259,9 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
== L_('\0'))
subfmt = L_("%I:%M:%S %p");
goto subformat;
+#elif USE_C_LOCALE && !HAVE_STRFTIME_L
+ subfmt = L_("%I:%M:%S %p");
+ goto subformat;
#elif (defined __APPLE__ && defined __MACH__) || defined __FreeBSD__
/* macOS, FreeBSD strftime() may produce empty output for "%r". */
subfmt = L_("%I:%M:%S %p");
@@ -1225,6 +1319,9 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
!= L_('\0'))))
subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT));
goto subformat;
+#elif USE_C_LOCALE && !HAVE_STRFTIME_L
+ subfmt = L_("%H:%M:%S");
+ goto subformat;
#else
goto underlying_strftime;
#endif
@@ -1332,6 +1429,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
pad = yr_spec;
goto subformat;
}
+#elif USE_C_LOCALE && !HAVE_STRFTIME_L
#else
goto underlying_strftime;
#endif
@@ -1355,6 +1453,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
DO_NUMBER (2, (era->offset
+ delta * era->absolute_direction));
}
+#elif USE_C_LOCALE && !HAVE_STRFTIME_L
#else
goto underlying_strftime;
#endif
diff --git a/lib/strftime.h b/lib/strftime.h
index 6e3dbf834c..8ce62cdb6d 100644
--- a/lib/strftime.h
+++ b/lib/strftime.h
@@ -78,6 +78,12 @@ size_t nstrftime (char *restrict __s, size_t __maxsize,
char const *__format,
struct tm const *__tp, timezone_t __tz, int __ns);
+/* Like nstrftime, except that it uses the "C" locale instead of the
+ current locale. */
+size_t c_nstrftime (char *restrict __s, size_t __maxsize,
+ char const *__format,
+ struct tm const *__tp, timezone_t __tz, int __ns);
+
#ifdef __cplusplus
}
#endif
diff --git a/m4/c-nstrftime.m4 b/m4/c-nstrftime.m4
new file mode 100644
index 0000000000..9c8268b557
--- /dev/null
+++ b/m4/c-nstrftime.m4
@@ -0,0 +1,21 @@
+# c-nstrftime.m4 serial 1
+dnl Copyright (C) 1996-2024 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_C_GNU_STRFTIME],
+[
+ AC_REQUIRE([AC_C_RESTRICT])
+
+ # This defines (or not) HAVE_TZNAME and HAVE_STRUCT_TM_TM_ZONE.
+ AC_REQUIRE([AC_STRUCT_TIMEZONE])
+
+ AC_REQUIRE([gl_TM_GMTOFF])
+
+ dnl Test for strftime_l. It exists in
+ dnl glibc >= 2.3, musl libc,
+ dnl macOS >= 10.4, FreeBSD >= 9.0, NetBSD >= 8.0, OpenBSD >= 6.2, Minix >= 3.3,
+ dnl AIX >= 7.2, Solaris >= 11.4, Cygwin >= 2.6, Android API level >= 21.
+ gl_CHECK_FUNCS_ANDROID([strftime_l], [[#include <time.h>]])
+])
diff --git a/modules/c-nstrftime b/modules/c-nstrftime
new file mode 100644
index 0000000000..8b2348c227
--- /dev/null
+++ b/modules/c-nstrftime
@@ -0,0 +1,37 @@
+Description:
+c_nstrftime() function: convert date and time to string, with GNU extensions, in "C" locale.
+
+Files:
+lib/strftime.h
+lib/c-nstrftime.c
+lib/strftime.c
+m4/tm_gmtoff.m4
+m4/c-nstrftime.m4
+
+Depends-on:
+attribute
+c-ctype
+c99
+errno
+extensions
+intprops
+libc-config
+locale
+stdbool
+stdckdint
+time_rz
+
+configure.ac:
+gl_C_GNU_STRFTIME
+
+Makefile.am:
+lib_SOURCES += c-nstrftime.c
+
+Include:
+"strftime.h"
+
+License:
+LGPL
+
+Maintainer:
+Jim Meyering, glibc
--
2.34.1
[-- Attachment #3: 0002-c-nstrftime-Add-tests.patch --]
[-- Type: text/x-patch, Size: 4973 bytes --]
From e9ae614c441e32027f5a0280f091ddc0c702a3ca Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Thu, 8 Feb 2024 01:24:12 +0100
Subject: [PATCH 2/2] c-nstrftime: Add tests.
* tests/test-c-nstrftime.c: New file, based on tests/test-nstrftime.c.
* tests/test-c-nstrftime-1.sh: New file, based on
tests/test-nstrftime-1.sh.
* tests/test-c-nstrftime-2.sh: New file, based on
tests/test-nstrftime-2.sh.
* modules/c-nstrftime-tests: New file.
---
ChangeLog | 8 ++++++
modules/c-nstrftime-tests | 26 +++++++++++++++++
tests/test-c-nstrftime-1.sh | 5 ++++
tests/test-c-nstrftime-2.sh | 23 +++++++++++++++
tests/test-c-nstrftime.c | 56 +++++++++++++++++++++++++++++++++++++
5 files changed, 118 insertions(+)
create mode 100644 modules/c-nstrftime-tests
create mode 100755 tests/test-c-nstrftime-1.sh
create mode 100755 tests/test-c-nstrftime-2.sh
create mode 100644 tests/test-c-nstrftime.c
diff --git a/ChangeLog b/ChangeLog
index 0d9b82b1e9..53f6cb1765 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
2024-02-07 Bruno Haible <bruno@clisp.org>
+ c-nstrftime: Add tests.
+ * tests/test-c-nstrftime.c: New file, based on tests/test-nstrftime.c.
+ * tests/test-c-nstrftime-1.sh: New file, based on
+ tests/test-nstrftime-1.sh.
+ * tests/test-c-nstrftime-2.sh: New file, based on
+ tests/test-nstrftime-2.sh.
+ * modules/c-nstrftime-tests: New file.
+
c-nstrftime: New module.
Suggested by Paul Eggert.
* lib/strftime.h (c_nstrftime): New declaration.
diff --git a/modules/c-nstrftime-tests b/modules/c-nstrftime-tests
new file mode 100644
index 0000000000..fda810d09b
--- /dev/null
+++ b/modules/c-nstrftime-tests
@@ -0,0 +1,26 @@
+Files:
+tests/test-c-nstrftime-1.sh
+tests/test-c-nstrftime-2.sh
+tests/test-c-nstrftime.c
+tests/test-nstrftime.h
+tests/macros.h
+m4/locale-fr.m4
+m4/codeset.m4
+
+Depends-on:
+atoll
+c99
+intprops
+strerror
+
+configure.ac:
+gt_LOCALE_FR
+gt_LOCALE_FR_UTF8
+
+Makefile.am:
+TESTS += test-c-nstrftime-1.sh test-c-nstrftime-2.sh
+TESTS_ENVIRONMENT += \
+ LOCALE_FR='@LOCALE_FR@' \
+ LOCALE_FR_UTF8='@LOCALE_FR_UTF8@'
+check_PROGRAMS += test-c-nstrftime
+test_c_nstrftime_LDADD = $(LDADD) $(SETLOCALE_LIB)
diff --git a/tests/test-c-nstrftime-1.sh b/tests/test-c-nstrftime-1.sh
new file mode 100755
index 0000000000..34b70effd3
--- /dev/null
+++ b/tests/test-c-nstrftime-1.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+LC_ALL=C ${CHECKER} ./test-c-nstrftime${EXEEXT} || exit 1
+
+exit 0
diff --git a/tests/test-c-nstrftime-2.sh b/tests/test-c-nstrftime-2.sh
new file mode 100755
index 0000000000..e2bf1fae60
--- /dev/null
+++ b/tests/test-c-nstrftime-2.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+: "${LOCALE_FR=fr_FR}"
+: "${LOCALE_FR_UTF8=fr_FR.UTF-8}"
+
+if test $LOCALE_FR = none && test $LOCALE_FR_UTF8 = none; then
+ if test -f /usr/bin/localedef; then
+ echo "Skipping test: no locale for testing is installed"
+ else
+ echo "Skipping test: no locale for testing is supported"
+ fi
+ exit 77
+fi
+
+if test $LOCALE_FR != none; then
+ LC_ALL=$LOCALE_FR ${CHECKER} ./test-c-nstrftime${EXEEXT} || exit 1
+fi
+
+if test $LOCALE_FR_UTF8 != none; then
+ LC_ALL=$LOCALE_FR_UTF8 ${CHECKER} ./test-c-nstrftime${EXEEXT} || exit 1
+fi
+
+exit 0
diff --git a/tests/test-c-nstrftime.c b/tests/test-c-nstrftime.c
new file mode 100644
index 0000000000..46ab58c92b
--- /dev/null
+++ b/tests/test-c-nstrftime.c
@@ -0,0 +1,56 @@
+/* Test that c_nstrftime works as required.
+ Copyright (C) 2011-2024 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Jim Meyering. */
+
+#include <config.h>
+
+/* Specification. */
+#include "strftime.h"
+
+#include <locale.h>
+
+#include "intprops.h"
+
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "macros.h"
+
+#define FUNC c_nstrftime
+#include "test-nstrftime.h"
+
+int
+main (void)
+{
+ /* Try to set the locale by implicitly looking at the LC_ALL environment
+ variable.
+ configure should already have checked that the locale is supported. */
+ if (setlocale (LC_ALL, "") == NULL)
+ return 1;
+
+ int fail = 0;
+ fail |= posixtm_test ();
+ fail |= tzalloc_test ();
+ fail |= quarter_test ();
+ fail |= errno_test ();
+ fail |= locales_test (english);
+ return fail;
+}
--
2.34.1
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2024-02-08 0:30 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-02-08 0:29 new module 'c-nstrftime' Bruno Haible
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).