[Top][All Lists]
[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;