bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: sleep with LANG="address@hidden"


From: Paul Eggert
Subject: Re: sleep with LANG="address@hidden"
Date: 24 Nov 2003 01:09:07 -0800
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3

Jim Meyering <address@hidden> writes:

> Sleep should accept numbers in the locale specified by the user.

I'm dubious about this.  I searched POSIX for examples of standard
programs accepting command-line options or operands containing
floating-point values, and both examples that I found (namely, awk and
printf) require that the values must be parsed in the C locale, not in
the user-specified locale.

Clearly coreutils printf is nonconforming now, since it doesn't do
that.  I vote that other utilities be consistent with POSIX.  Here's a
proposed patch.

2003-11-24  Paul Eggert  <address@hidden>

        Parse floating-point operands and options in the C locale.
        POSIX requires this for printf, and we might as well be
        consistent elsewhere.

        * doc/coreutils.texi (tail invocation, printf invocation,
        sleep invocation, seq invocation): Document this.
        * lib/Makefile.am (libfetish_a_SOURCES): Add c-strtod.c, c-strtod.h.
        * lib/c-strtod.c, lib/c-strtod.h: New files.
        * lib/xstrtod.h (xstrtod): Accept an extra arg, specifying the
        conversion function.
        * lib/xstrtod.c (xstrtod): Likewise.  All callers changed to
        include c-strtod.h and use c_strtod.  Don't include stdlib.h; no
        longer needed.
        * src/printf.c: Remove decls of strtod, strtol, strtoul; no longer
        needed now that we assume C89.  Include "c-strtod.h".
        (xstrtod): Call c_strtod, not strtod.

        * lib/xnanosleep.c: Don't include xstrtod.h; it's not needed.

--- ./doc/coreutils.texi.~1.138.~       Tue Nov 11 12:42:02 2003
+++ ./doc/coreutils.texi        Mon Nov 24 08:43:58 2003
@@ -2229,7 +2229,8 @@ During one iteration, every specified fi
 changed size.
 Historical implementations of @command{tail} have required that
 @var{number} be an integer.  However, GNU @command{tail} accepts
-an arbitrary floating point number.
+an arbitrary floating point number (using a period before any
+fractional digits).
 
 @itemx address@hidden
 @opindex --pid
@@ -8590,6 +8591,13 @@ directives and @samp{\} escapes in the s
 function.  The @var{format} argument is re-used as necessary to convert
 all of the given @var{argument}s.
 
address@hidden LC_NUMERIC
+A floating-point argument must use a period before any fractional
+digits, but is printed according to the LC_NUMERIC category of the
+current locale.  For example, in a locale whose radix character is a
+comma, the command @samp{printf %g 3.14} outputs @samp{3,14} whereas
+the command @samp{printf %g 3,14} is an error.
+
 @command{printf} has one additional directive, @samp{%b}, which prints its
 argument string with @samp{\} escapes interpreted in the same way as in
 the @var{format} string, except that octal escapes are of the form
@@ -11813,7 +11821,8 @@ days
 
 Historical implementations of @command{sleep} have required that
 @var{number} be an integer.  However, GNU @command{sleep} accepts
-arbitrary floating point numbers.
+arbitrary floating point numbers (using a period before any fractional
+digits).
 
 The only options are @option{--help} and @option{--version}.  @xref{Common
 options}.
@@ -11884,8 +11893,8 @@ seq address@hidden@dots{} address@hidden [
 
 @command{seq} prints the numbers from @var{first} to @var{last} by
 @var{increment}.  By default, @var{first} and @var{increment} are both 1,
-and each number is printed on its own line.  All numbers can be reals,
-not just integers.
+and each number is printed on its own line.  Any floating-point number
+may be specified (using a period before any fractional digits).
 
 The program accepts the following options.  Also see @ref{Common options}.
 
--- ./lib/Makefile.am.~1.175.~  Sun Nov  9 21:16:01 2003
+++ ./lib/Makefile.am   Mon Nov 24 08:16:06 2003
@@ -42,6 +42,7 @@ libfetish_a_SOURCES = \
   argmatch.c argmatch.h \
   backupfile.c backupfile.h \
   basename.c \
+  c-strtod.c c-strtod.h \
   canon-host.c \
   canonicalize.h \
   closeout.c closeout.h \
--- /dev/null   Tue Mar 18 21:55:57 2003
+++ lib/c-strtod.h      Mon Nov 24 08:15:24 2003
@@ -0,0 +1 @@
+double c_strtod (char const *, char **);
--- /dev/null   Tue Mar 18 21:55:57 2003
+++ lib/c-strtod.c      Mon Nov 24 08:14:58 2003
@@ -0,0 +1,34 @@
+/* Convert string to double, using the C locale.
+
+   Copyright (C) 2003 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 2, 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, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* Written by Paul Eggert.  */
+
+#include "c-strtod.h"
+
+#include <locale.h>
+#include <stdlib.h>
+
+double
+c_strtod (char const *nptr, char **endptr)
+{
+  double r;
+  setlocale (LC_NUMERIC, "C");
+  r = strtod (nptr, endptr);
+  setlocale (LC_NUMERIC, "");
+  return r;
+}
--- ./lib/xnanosleep.c.~1.7.~   Thu May  8 09:26:34 2003
+++ ./lib/xnanosleep.c  Mon Nov 24 08:20:21 2003
@@ -47,7 +47,6 @@
 #include "timespec.h"
 #include "xalloc.h"
 #include "xnanosleep.h"
-#include "xstrtod.h"
 
 /* Subtract the `struct timespec' values X and Y by computing X - Y.
    If the difference is negative or zero, return 0.
--- ./lib/xstrtod.h.~1.8.~      Wed Jun 18 08:03:45 2003
+++ ./lib/xstrtod.h     Mon Nov 24 08:19:54 2003
@@ -1,4 +1,4 @@
-/* Error-checking interface to strtod.
+/* Error-checking interface to strtod-like functions.
 
    Copyright (C) 1996, 1998, 2003 Free Software Foundation, Inc.
 
@@ -21,6 +21,7 @@
 #ifndef XSTRTOD_H
 # define XSTRTOD_H 1
 
-int xstrtod (const char *str, const char **ptr, double *result);
+int xstrtod (const char *str, const char **ptr, double *result,
+            double (*convert) (char const *, char **));
 
 #endif /* not XSTRTOD_H */
--- ./lib/xstrtod.c.~1.8.~      Sat Sep 13 19:54:00 2003
+++ ./lib/xstrtod.c     Mon Nov 24 08:19:44 2003
@@ -1,4 +1,4 @@
-/* xstrtod.c - error-checking interface to strtod
+/* error-checking interface to strtod-like functions
    Copyright (C) 1996, 1999, 2000, 2003 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
@@ -26,7 +26,6 @@
 #include <errno.h>
 #include <limits.h>
 #include <stdio.h>
-#include <stdlib.h>
 
 /* Tell the compiler that non-default rounding modes are used.  */
 #if 199901 <= __STDC_VERSION__
@@ -36,10 +35,12 @@
 /* An interface to strtod that encapsulates all the error checking
    one should usually perform.  Like strtod, but upon successful
    conversion put the result in *RESULT and return zero.  Return
-   non-zero and don't modify *RESULT upon any failure.  */
+   non-zero and don't modify *RESULT upon any failure.  CONVERT
+   specifies the conversion function, e.g., strtod itself.  */
 
 int
-xstrtod (char const *str, char const **ptr, double *result)
+xstrtod (char const *str, char const **ptr, double *result,
+        double (*convert) (char const *, char **))
 {
   double val;
   char *terminator;
@@ -47,7 +48,7 @@ xstrtod (char const *str, char const **p
 
   fail = 0;
   errno = 0;
-  val = strtod (str, &terminator);
+  val = convert (str, &terminator);
 
   /* Having a non-zero terminator is an error only when PTR is NULL. */
   if (terminator == str || (ptr == NULL && *terminator != '\0'))
--- ./src/printf.c.~1.85.~      Wed Nov  5 03:53:19 2003
+++ ./src/printf.c      Mon Nov 24 08:25:38 2003
@@ -52,6 +52,7 @@
 #include <getopt.h>
 
 #include "system.h"
+#include "c-strtod.h"
 #include "long-options.h"
 #include "error.h"
 #include "unicodeio.h"
@@ -61,12 +62,6 @@
 
 #define AUTHORS "David MacKenzie"
 
-#ifndef STDC_HEADERS
-double strtod ();
-long int strtol ();
-unsigned long int strtoul ();
-#endif
-
 #define isodigit(c) ((c) >= '0' && (c) <= '7')
 #define hextobin(c) ((c) >= 'a' && (c) <= 'f' ? (c) - 'a' + 10 : \
                     (c) >= 'A' && (c) <= 'F' ? (c) - 'A' + 10 : (c) - '0')
@@ -194,7 +189,7 @@ FUNC_NAME (s)                                               
                 \
 
 STRTOX (unsigned long int, xstrtoul, (strtoul (s, &end, 0)))
 STRTOX (long int,          xstrtol,  (strtol  (s, &end, 0)))
-STRTOX (double,            xstrtod,  (strtod  (s, &end)))
+STRTOX (double,            xstrtod,  (c_strtod (s, &end)))
 
 /* Output a single-character \ escape.  */
 
--- ./src/seq.c.~1.75.~ Sat Oct 18 10:05:47 2003
+++ ./src/seq.c Mon Nov 24 08:21:20 2003
@@ -24,6 +24,7 @@
 #include <sys/types.h>
 
 #include "system.h"
+#include "c-strtod.h"
 #include "error.h"
 #include "xstrtol.h"
 #include "xstrtod.h"
@@ -113,7 +114,7 @@ scan_double_arg (const char *arg)
 {
   double ret_val;
 
-  if (xstrtod (arg, NULL, &ret_val))
+  if (xstrtod (arg, NULL, &ret_val, c_strtod))
     {
       error (0, 0, _("invalid floating point argument: %s"), arg);
       usage (EXIT_FAILURE);
--- ./src/sleep.c.~1.82.~       Wed Nov  5 03:53:19 2003
+++ ./src/sleep.c       Mon Nov 24 08:21:53 2003
@@ -22,6 +22,7 @@
 #include <getopt.h>
 
 #include "system.h"
+#include "c-strtod.h"
 #include "error.h"
 #include "long-options.h"
 #include "xnanosleep.h"
@@ -144,7 +145,7 @@ main (int argc, char **argv)
     {
       double s;
       const char *p;
-      if (xstrtod (argv[i], &p, &s)
+      if (xstrtod (argv[i], &p, &s, c_strtod)
          /* Nonnegative interval.  */
          || ! (0 <= s)
          /* No extra chars after the number and an optional s,m,h,d char.  */
--- ./src/tail.c.~1.217.~       Sat Oct 18 10:05:47 2003
+++ ./src/tail.c        Mon Nov 24 08:22:19 2003
@@ -33,6 +33,7 @@
 
 #include "system.h"
 #include "argmatch.h"
+#include "c-strtod.h"
 #include "error.h"
 #include "inttostr.h"
 #include "posixver.h"
@@ -1610,7 +1611,7 @@ parse_options (int argc, char **argv,
        case 's':
          {
            double s;
-           if (xstrtod (optarg, NULL, &s) || ! (0 <= s))
+           if (xstrtod (optarg, NULL, &s, c_strtod) || ! (0 <= s))
              error (EXIT_FAILURE, 0,
                     _("%s: invalid number of seconds"), optarg);
            *sleep_interval = s;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]