]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
seq: output decimal points consistently with invalid locales
authorPádraig Brady <P@draigBrady.com>
Sun, 3 Feb 2019 03:16:02 +0000 (19:16 -0800)
committerPádraig Brady <P@draigBrady.com>
Mon, 4 Feb 2019 01:18:08 +0000 (17:18 -0800)
* src/seq.c (print_numbers): Only reset the locale if it
was successfully set originally.
* tests/misc/seq-locale.sh: Add a new test.
* tests/local.mk: Reference the new test.
* NEWS: Mention the fix.

NEWS
src/seq.c
tests/local.mk
tests/misc/seq-locale.sh [new file with mode: 0755]

diff --git a/NEWS b/NEWS
index e6ccb19495852fea34d925dd158adb35b2895c55..fdde47593b2979f3a548b2ed073be66fa3911ded 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,10 @@ GNU coreutils NEWS                                    -*- outline -*-
   df no longer corrupts displayed multibyte characters on macOS.
   [bug introduced with coreutils-8.18]
 
+  seq no longer outputs inconsistent decimal point characters
+  for the last number, when locales are misconfigured.
+  [bug introduced in coreutils-7.0]
+
   shred, sort, and split no longer falsely report ftruncate errors
   when outputting to less-common file types.  For example, the shell
   command 'sort /dev/null -o /dev/stdout | cat' no longer fails with
index 61d20fe628f57db3b7bed1533cf9ec704b4b847c..b5913368a965885faddecbf2af6ae2c11b93b1b4 100644 (file)
--- a/src/seq.c
+++ b/src/seq.c
@@ -42,6 +42,9 @@
 
 #define AUTHORS proper_name ("Ulrich Drepper")
 
+/* True if the locale settings were honored.  */
+static bool locale_ok;
+
 /* If true print all number with equal width.  */
 static bool equal_width;
 
@@ -324,9 +327,11 @@ print_numbers (char const *fmt, struct layout layout,
               long double x_val;
               char *x_str;
               int x_strlen;
-              setlocale (LC_NUMERIC, "C");
+              if (locale_ok)
+                setlocale (LC_NUMERIC, "C");
               x_strlen = asprintf (&x_str, fmt, x);
-              setlocale (LC_NUMERIC, "");
+              if (locale_ok)
+                setlocale (LC_NUMERIC, "");
               if (x_strlen < 0)
                 xalloc_die ();
               x_str[x_strlen - layout.suffix_len] = '\0';
@@ -559,7 +564,7 @@ main (int argc, char **argv)
 
   initialize_main (&argc, &argv);
   set_program_name (argv[0]);
-  setlocale (LC_ALL, "");
+  locale_ok = !!setlocale (LC_ALL, "");
   bindtextdomain (PACKAGE, LOCALEDIR);
   textdomain (PACKAGE);
 
index 290e30f6296c7ab39f02ba1e5d278aa5d44b4b44..4751886b2a318880534df329cf1162b5ccb8b819 100644 (file)
@@ -244,6 +244,7 @@ all_tests =                                 \
   tests/misc/seq.pl                            \
   tests/misc/seq-epipe.sh                      \
   tests/misc/seq-io-errors.sh                  \
+  tests/misc/seq-locale.sh                     \
   tests/misc/seq-long-double.sh                        \
   tests/misc/seq-precision.sh                  \
   tests/misc/head.pl                           \
diff --git a/tests/misc/seq-locale.sh b/tests/misc/seq-locale.sh
new file mode 100755 (executable)
index 0000000..8a46ab7
--- /dev/null
@@ -0,0 +1,28 @@
+#!/bin/sh
+# Test for output with appropriate precision
+
+# Copyright (C) 2019 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/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ seq
+
+# With coreutils-8.30 and earlier, the last decimal point would be ','
+# when setlocale(LC_ALL, "") failed, but setlocale(LC_NUMERIC, "") succeeded.
+LC_ALL= LANG=invalid LC_NUMERIC=$LOCALE_FR_UTF8 seq 0.1 0.2 0.7 > out || fail=1
+uniq -w2 out > out-merge || framework_failure_
+test "$(wc -l < out-merge)" = 1 || { fail=1; cat out; }
+
+Exit $fail