]> Savannah Git Hosting - gnulib.git/commitdiff
nstrftime: Add tests of all directives, also in non-trivial locales.
authorBruno Haible <bruno@clisp.org>
Wed, 7 Feb 2024 22:53:09 +0000 (23:53 +0100)
committerBruno Haible <bruno@clisp.org>
Wed, 7 Feb 2024 22:53:09 +0000 (23:53 +0100)
* tests/test-nstrftime.h (language_t): New type.
(locales_test): New function.
* tests/test-nstrftime.c: Include <locale.h>, <stdlib.h>.
(main): Invoke setlocale and locales_test.
* tests/test-nstrftime-1.sh: New file.
* tests/test-nstrftime-2.sh: New file, based on tests/test-strtod1.sh.
* modules/nstrftime-tests (Files): Add them. Add m4/locale-fr.m4,
m4/codeset.m4, m4/musl.m4.
(configure.ac): Invoke gt_LOCALE_FR, gt_LOCALE_FR_UTF8, gl_MUSL_LIBC.
(Makefile.am): Link test-nstrftime with $(SETLOCALE_LIB). Test
test-nstrftime-*.sh instead of test-nstrftime.

ChangeLog
modules/nstrftime-tests
tests/test-nstrftime-1.sh [new file with mode: 0755]
tests/test-nstrftime-2.sh [new file with mode: 0755]
tests/test-nstrftime.c
tests/test-nstrftime.h

index 00ac5424a745c7fc9449188f2344f4d34b30e8cc..ecbe0ea7b235ed159c4fa2f9ad30411eb2d2582c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2024-02-07  Bruno Haible  <bruno@clisp.org>
+
+       nstrftime: Add tests of all directives, also in non-trivial locales.
+       * tests/test-nstrftime.h (language_t): New type.
+       (locales_test): New function.
+       * tests/test-nstrftime.c: Include <locale.h>, <stdlib.h>.
+       (main): Invoke setlocale and locales_test.
+       * tests/test-nstrftime-1.sh: New file.
+       * tests/test-nstrftime-2.sh: New file, based on tests/test-strtod1.sh.
+       * modules/nstrftime-tests (Files): Add them. Add m4/locale-fr.m4,
+       m4/codeset.m4, m4/musl.m4.
+       (configure.ac): Invoke gt_LOCALE_FR, gt_LOCALE_FR_UTF8, gl_MUSL_LIBC.
+       (Makefile.am): Link test-nstrftime with $(SETLOCALE_LIB). Test
+       test-nstrftime-*.sh instead of test-nstrftime.
+
 2024-02-07  Bruno Haible  <bruno@clisp.org>
 
        nstrftime: Work around strftime bug with %r on macOS and FreeBSD.
index b30ebbbbae7f3f9a6307c41ea82d08c990870479..24212a4f84dada4f26785bc17de2d3d88fdbc22d 100644 (file)
@@ -1,7 +1,12 @@
 Files:
+tests/test-nstrftime-1.sh
+tests/test-nstrftime-2.sh
 tests/test-nstrftime.c
 tests/test-nstrftime.h
 tests/macros.h
+m4/locale-fr.m4
+m4/codeset.m4
+m4/musl.m4
 
 Depends-on:
 atoll
@@ -10,7 +15,14 @@ intprops
 strerror
 
 configure.ac:
+gt_LOCALE_FR
+gt_LOCALE_FR_UTF8
+gl_MUSL_LIBC
 
 Makefile.am:
-TESTS += test-nstrftime
+TESTS += test-nstrftime-1.sh test-nstrftime-2.sh
+TESTS_ENVIRONMENT += \
+  LOCALE_FR='@LOCALE_FR@' \
+  LOCALE_FR_UTF8='@LOCALE_FR_UTF8@'
 check_PROGRAMS += test-nstrftime
+test_nstrftime_LDADD = $(LDADD) $(SETLOCALE_LIB)
diff --git a/tests/test-nstrftime-1.sh b/tests/test-nstrftime-1.sh
new file mode 100755 (executable)
index 0000000..c0c4665
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+LC_ALL=C ${CHECKER} ./test-nstrftime${EXEEXT} || exit 1
+
+exit 0
diff --git a/tests/test-nstrftime-2.sh b/tests/test-nstrftime-2.sh
new file mode 100755 (executable)
index 0000000..c0ce75c
--- /dev/null
@@ -0,0 +1,41 @@
+#!/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
+
+final_rc=0
+
+if test $LOCALE_FR != none; then
+  LC_ALL=$LOCALE_FR      ${CHECKER} ./test-nstrftime${EXEEXT}
+  rc=$?
+  if test $rc = 77; then
+    final_rc=77
+  else
+    if test $rc != 0; then
+      exit 1
+    fi
+  fi
+fi
+
+if test $LOCALE_FR_UTF8 != none; then
+  LC_ALL=$LOCALE_FR_UTF8 ${CHECKER} ./test-nstrftime${EXEEXT}
+  rc=$?
+  if test $rc = 77; then
+    final_rc=77
+  else
+    if test $rc != 0; then
+      exit 1
+    fi
+  fi
+fi
+
+exit $final_rc
index 3a76298f5e77d3b245d16f19e1b01ee0b60e7676..4074874366b62d08fb756a79241804a1d71db08e 100644 (file)
 
 #include <config.h>
 
+/* Specification.  */
 #include "strftime.h"
 
+#include <locale.h>
+#include <stdlib.h>
+
 #include "intprops.h"
 
 #include <errno.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;
+
+  bool is_C_locale = STREQ (getenv ("LC_ALL"), "C");
+
   int fail = 0;
   fail |= posixtm_test ();
   fail |= tzalloc_test ();
   fail |= quarter_test ();
   fail |= errno_test ();
+  if (is_C_locale)
+    fail |= locales_test (english);
+  else
+    {
+#if MUSL_LIBC
+      if (fail == 0)
+        {
+          fputs ("Skipping test: musl libc does not come with localizations\n",
+                 stderr);
+          return 77;
+        }
+#else
+      fail |= locales_test (french);
+#endif
+    }
   return fail;
 }
index 97190a66541a89262fcccdfa33726558e02eb41c..5c54266043ae9b4526fcb2a46fd2f1601f7757c9 100644 (file)
@@ -1,4 +1,4 @@
-/* Test of nstrftime-like functions in the "C" locale.
+/* Test of nstrftime-like functions.
    Copyright (C) 2011-2024 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
@@ -327,6 +327,341 @@ errno_test (void)
 
 /* -------------------------------------------------------------------------- */
 
+/* Test various format directives.  */
+
+typedef enum { english, french } language_t;
+
+static int
+locales_test (language_t language)
+{
+  int fail = 0;
+
+  time_t t = 1509000003;
+  struct tm *tm = gmtime (&t);
+  int ns = 123456789;
+  char buf[100];
+  size_t n;
+
+  n = FUNC (buf, sizeof buf, "%+4Y-%m-%d %H:%M:%S.%N", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("Format as ISO 8601: %s\n", buf);
+  ASSERT (STREQ (buf, "2017-10-26 06:40:03.123456789"));
+
+  /* Exercise various POSIX format directives.  */
+
+  n = FUNC (buf, sizeof buf, "%a", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%a directive: %s\n", buf);
+  switch (language)
+    {
+    case english:
+      ASSERT (STREQ (buf, "Thu"));
+      break;
+    case french:
+      ASSERT (STREQ (buf, "jeu.") /* glibc, FreeBSD, NetBSD, Solaris, Cygwin */
+              || STREQ (buf, "Jeu") /* macOS, older FreeBSD */);
+      break;
+    }
+
+  n = FUNC (buf, sizeof buf, "%A", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%A directive: %s\n", buf);
+  switch (language)
+    {
+    case english:
+      ASSERT (STREQ (buf, "Thursday"));
+      break;
+    case french:
+      ASSERT (STREQ (buf, "jeudi") /* glibc, FreeBSD, NetBSD, Solaris, Cygwin */
+              || STREQ (buf, "Jeudi") /* macOS, older FreeBSD */);
+      break;
+    }
+
+  n = FUNC (buf, sizeof buf, "%b", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%b directive: %s\n", buf);
+  switch (language)
+    {
+    case english:
+      ASSERT (STREQ (buf, "Oct"));
+      break;
+    case french:
+      ASSERT (STREQ (buf, "oct.") /* glibc, FreeBSD, NetBSD, Solaris, Cygwin */
+              || STREQ (buf, "oct") /* macOS, older FreeBSD */);
+      break;
+    }
+
+  n = FUNC (buf, sizeof buf, "%B", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%B directive: %s\n", buf);
+  switch (language)
+    {
+    case english:
+      ASSERT (STREQ (buf, "October"));
+      break;
+    case french:
+      ASSERT (STREQ (buf, "octobre"));
+      break;
+    }
+
+  n = FUNC (buf, sizeof buf, "%c", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%c directive: %s\n", buf);
+  switch (language)
+    {
+    case english:
+      ASSERT (STREQ (buf, "Thu Oct 26 06:40:03 2017"));
+      break;
+    case french:
+      ASSERT (STREQ (buf, "jeu. 26 oct. 2017 06:40:03") /* glibc, Cygwin */
+              || STREQ (buf, "jeu. 26 oct. 06:40:03 2017") /* FreeBSD */
+              || STREQ (buf, "Jeu 26 oct 06:40:03 2017") /* macOS, older FreeBSD */
+              || STREQ (buf, "26 octobre 2017 06:40:03") /* NetBSD */
+              || STREQ (buf, "26 octobre 2017 à 06:40:03") /* Solaris (UTF-8) */
+              || STREQ (buf, "26 octobre 2017 \340 06:40:03") /* Solaris (ISO-8859-1) */);
+      break;
+    }
+
+  n = FUNC (buf, sizeof buf, "%C", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%C directive: %s\n", buf);
+  ASSERT (STREQ (buf, "20"));
+
+  n = FUNC (buf, sizeof buf, "%d", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%d directive: %s\n", buf);
+  ASSERT (STREQ (buf, "26"));
+
+  n = FUNC (buf, sizeof buf, "%D", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%D directive: %s\n", buf);
+  ASSERT (STREQ (buf, "10/26/17"));
+
+  n = FUNC (buf, sizeof buf, "%e", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%e directive: %s\n", buf);
+  ASSERT (STREQ (buf, "26"));
+
+  n = FUNC (buf, sizeof buf, "%F", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%F directive: %s\n", buf);
+  ASSERT (STREQ (buf, "2017-10-26"));
+
+  n = FUNC (buf, sizeof buf, "%g", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%g directive: %s\n", buf);
+  ASSERT (STREQ (buf, "17"));
+
+  n = FUNC (buf, sizeof buf, "%G", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%G directive: %s\n", buf);
+  ASSERT (STREQ (buf, "2017"));
+
+  n = FUNC (buf, sizeof buf, "%h", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%h directive: %s\n", buf);
+  switch (language)
+    {
+    case english:
+      ASSERT (STREQ (buf, "Oct"));
+      break;
+    case french:
+      ASSERT (STREQ (buf, "oct.") /* glibc, FreeBSD, NetBSD, Solaris, Cygwin */
+              || STREQ (buf, "oct") /* macOS, older FreeBSD */);
+      break;
+    }
+
+  n = FUNC (buf, sizeof buf, "%H", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%H directive: %s\n", buf);
+  ASSERT (STREQ (buf, "06"));
+
+  n = FUNC (buf, sizeof buf, "%I", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%I directive: %s\n", buf);
+  ASSERT (STREQ (buf, "06"));
+
+  n = FUNC (buf, sizeof buf, "%j", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%j directive: %s\n", buf);
+  ASSERT (STREQ (buf, "299"));
+
+  n = FUNC (buf, sizeof buf, "%m", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%m directive: %s\n", buf);
+  ASSERT (STREQ (buf, "10"));
+
+  n = FUNC (buf, sizeof buf, "%M", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%M directive: %s\n", buf);
+  ASSERT (STREQ (buf, "40"));
+
+  n = FUNC (buf, sizeof buf, "%n", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%n directive: %s\n", buf);
+  ASSERT (STREQ (buf, "\n"));
+
+  n = FUNC (buf, sizeof buf, "%p", tm, 0, ns);
+  switch (language)
+    {
+    case english:
+      ASSERT (n > 0);
+      printf ("%%p directive: %s\n", buf);
+      ASSERT (STREQ (buf, "AM"));
+      break;
+    case french:
+      ASSERT (n == 0);
+      break;
+    }
+
+  n = FUNC (buf, sizeof buf, "%r", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%r directive: %s\n", buf);
+  switch (language)
+    {
+    case english:
+      ASSERT (STREQ (buf, "06:40:03 AM"));
+      break;
+    case french:
+      ASSERT (STREQ (buf, "06:40:03 ") /* glibc */
+              || STREQ (buf, "06:40:03") /* Cygwin */
+              || STREQ (buf, "06:40:03 AM") /* NetBSD */
+              || STREQ (buf, " 6:40:03 AM") /* Solaris */);
+      break;
+    }
+
+  n = FUNC (buf, sizeof buf, "%R", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%R directive: %s\n", buf);
+  ASSERT (STREQ (buf, "06:40"));
+
+  n = FUNC (buf, sizeof buf, "%S", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%S directive: %s\n", buf);
+  ASSERT (STREQ (buf, "03"));
+
+  n = FUNC (buf, sizeof buf, "%t", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%t directive: %s\n", buf);
+  ASSERT (STREQ (buf, "\t"));
+
+  n = FUNC (buf, sizeof buf, "%T", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%T directive: %s\n", buf);
+  ASSERT (STREQ (buf, "06:40:03"));
+
+  n = FUNC (buf, sizeof buf, "%u", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%u directive: %s\n", buf);
+  ASSERT (STREQ (buf, "4"));
+
+  n = FUNC (buf, sizeof buf, "%U", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%U directive: %s\n", buf);
+  ASSERT (STREQ (buf, "43"));
+
+  n = FUNC (buf, sizeof buf, "%V", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%V directive: %s\n", buf);
+  ASSERT (STREQ (buf, "43"));
+
+  n = FUNC (buf, sizeof buf, "%w", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%w directive: %s\n", buf);
+  ASSERT (STREQ (buf, "4"));
+
+  n = FUNC (buf, sizeof buf, "%W", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%W directive: %s\n", buf);
+  ASSERT (STREQ (buf, "43"));
+
+  n = FUNC (buf, sizeof buf, "%x", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%x directive: %s\n", buf);
+  switch (language)
+    {
+    case english:
+      ASSERT (STREQ (buf, "10/26/17"));
+      break;
+    case french:
+      ASSERT (STREQ (buf, "26/10/2017") /* glibc, NetBSD, Solaris, Cygwin */
+              || STREQ (buf, "26.10.2017") /* FreeBSD, macOS */);
+      break;
+    }
+
+  n = FUNC (buf, sizeof buf, "%X", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%X directive: %s\n", buf);
+  ASSERT (STREQ (buf, "06:40:03"));
+
+  n = FUNC (buf, sizeof buf, "%y", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%y directive: %s\n", buf);
+  ASSERT (STREQ (buf, "17"));
+
+  n = FUNC (buf, sizeof buf, "%Y", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%Y directive: %s\n", buf);
+  ASSERT (STREQ (buf, "2017"));
+
+  n = FUNC (buf, sizeof buf, "%z", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%z directive: %s\n", buf);
+  ASSERT (STREQ (buf, "+0000"));
+
+  n = FUNC (buf, sizeof buf, "%Z", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%Z directive: %s\n", buf);
+  ASSERT (STREQ (buf, "GMT") /* glibc, NetBSD, OpenBSD, AIX, Solaris, Cygwin, Android */
+          || STREQ (buf, "UTC") /* musl, macOS, FreeBSD */);
+
+  n = FUNC (buf, sizeof buf, "%%", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%%% directive: %s\n", buf);
+  ASSERT (STREQ (buf, "%"));
+
+  /* Exercise various GNU extensions from glibc.  */
+
+  n = FUNC (buf, sizeof buf, "%k", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%k directive: %s\n", buf);
+  ASSERT (STREQ (buf, " 6"));
+
+  n = FUNC (buf, sizeof buf, "%l", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%l directive: %s\n", buf);
+  ASSERT (STREQ (buf, " 6"));
+
+  n = FUNC (buf, sizeof buf, "%P", tm, 0, ns);
+  switch (language)
+    {
+    case english:
+      ASSERT (n > 0);
+      printf ("%%P directive: %s\n", buf);
+      ASSERT (STREQ (buf, "am"));
+      break;
+    case french:
+      ASSERT (n == 0);
+      break;
+    }
+
+  n = FUNC (buf, sizeof buf, "%s", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%s directive: %s\n", buf);
+  ASSERT (STREQ (buf, "1509000003"));
+
+  /* Exercise various GNU extensions from gnulib.  */
+
+  n = FUNC (buf, sizeof buf, "%N", tm, 0, ns);
+  ASSERT (n > 0);
+  printf ("%%N directive: %s\n", buf);
+  ASSERT (STREQ (buf, "123456789"));
+
+  return fail;
+}
+
+/* -------------------------------------------------------------------------- */
+
 /*
 Local Variables:
 indent-tabs-mode: nil