summaryrefslogtreecommitdiff
path: root/src/seq.c
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2015-06-23 22:51:24 +0100
committerPádraig Brady <P@draigBrady.com>2015-06-24 17:04:01 +0100
commit32c97093db85c827ccbbf4cd4255190718863232 (patch)
treec0fc83e1aeb1ef93ae4327d48beb1637177c22a5 /src/seq.c
parent60c8e31d9201f10295cfdcfd2d15893f9682083b (diff)
downloadcoreutils-32c97093db85c827ccbbf4cd4255190718863232.tar.xz
seq: handle exponents more consistently
src/seq.c (scan_arg): Set precision and width _after_ exponentiation. For example, this will make '1.1e1 12' and '11 1.2e1' equivalent. One can still set the precision by specifying extra precision on the start value, or more naturally with a precision on a step value. * tests/misc/seq-precision.sh: Add new cases.
Diffstat (limited to 'src/seq.c')
-rw-r--r--src/seq.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/src/seq.c b/src/seq.c
index 95e6cd639..2426c4de3 100644
--- a/src/seq.c
+++ b/src/seq.c
@@ -147,20 +147,24 @@ scan_arg (const char *arg)
while (isspace (to_uchar (*arg)) || *arg == '+')
arg++;
+ /* Default to auto width and precision. */
ret.width = 0;
ret.precision = INT_MAX;
+ /* Use no precision (and possibly fast generation) for integers. */
char const *decimal_point = strchr (arg, '.');
if (! decimal_point && ! strchr (arg, 'p') /* not a hex float */)
ret.precision = 0;
+ /* auto set width and precision for decimal inputs. */
if (! arg[strcspn (arg, "xX")] && isfinite (ret.value))
{
+ size_t fraction_len = 0;
ret.width = strlen (arg);
if (decimal_point)
{
- size_t fraction_len = strcspn (decimal_point + 1, "eE");
+ fraction_len = strcspn (decimal_point + 1, "eE");
if (fraction_len <= INT_MAX)
ret.precision = fraction_len;
ret.width += (fraction_len == 0 /* #. -> # */
@@ -174,7 +178,8 @@ scan_arg (const char *arg)
if (e)
{
long exponent = strtol (e + 1, NULL, 10);
- ret.precision += exponent < 0 ? -exponent : 0;
+ ret.precision += exponent < 0 ? -exponent
+ : - MIN (ret.precision, exponent);
/* Don't account for e.... in the width since this is not output. */
ret.width -= strlen (arg) - (e - arg);
/* Adjust the width as per the exponent. */
@@ -189,6 +194,12 @@ scan_arg (const char *arg)
ret.width++;
exponent = -exponent;
}
+ else
+ {
+ if (decimal_point && ret.precision == 0 && fraction_len)
+ ret.width--; /* discount space for '.' */
+ exponent -= MIN (fraction_len, exponent);
+ }
ret.width += exponent;
}
}