1
/* Reformat numbers like 11505426432 to the more human-readable 11G
2
Copyright (C) 2012 Free Software Foundation, Inc.
4
This program is free software: you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation, either version 3 of the License, or
7
(at your option) any later version.
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
14
You should have received a copy of the GNU General Public License
15
along with this program. If not, see <http://www.gnu.org/licenses/>. */
21
#include <sys/types.h>
32
/* The official name of this program (e.g., no 'g' prefix). */
33
#define PROGRAM_NAME "numfmt"
35
#define AUTHORS proper_name ("Assaf Gordon")
37
/* Exit code when some numbers fail to convert. */
38
enum { EXIT_CONVERSION_WARNINGS = 2 };
42
FROM_OPTION = CHAR_MAX + 1,
60
scale_none, /* the default: no scaling. */
61
scale_auto, /* --from only. */
64
scale_IEC_I /* 'i' suffix is required. */
67
static char const *const scale_from_args[] =
69
"none", "auto", "si", "iec", "iec-i", NULL
72
static enum scale_type const scale_from_types[] =
74
scale_none, scale_auto, scale_SI, scale_IEC, scale_IEC_I
77
static char const *const scale_to_args[] =
79
"none", "si", "iec", "iec-i", NULL
82
static enum scale_type const scale_to_types[] =
84
scale_none, scale_SI, scale_IEC, scale_IEC_I
97
static char const *const round_args[] =
99
"up", "down", "from-zero", "towards-zero", "nearest", NULL
102
static enum round_type const round_types[] =
104
round_ceiling, round_floor, round_from_zero, round_to_zero, round_nearest
116
static char const *const inval_args[] =
118
"abort", "fail", "warn", "ignore", NULL
121
static enum inval_type const inval_types[] =
123
inval_abort, inval_fail, inval_warn, inval_ignore
126
static struct option const longopts[] =
128
{"from", required_argument, NULL, FROM_OPTION},
129
{"from-unit", required_argument, NULL, FROM_UNIT_OPTION},
130
{"to", required_argument, NULL, TO_OPTION},
131
{"to-unit", required_argument, NULL, TO_UNIT_OPTION},
132
{"round", required_argument, NULL, ROUND_OPTION},
133
{"padding", required_argument, NULL, PADDING_OPTION},
134
{"suffix", required_argument, NULL, SUFFIX_OPTION},
135
{"grouping", no_argument, NULL, GROUPING_OPTION},
136
{"delimiter", required_argument, NULL, 'd'},
137
{"field", required_argument, NULL, FIELD_OPTION},
138
{"debug", no_argument, NULL, DEBUG_OPTION},
139
{"-debug", no_argument, NULL, DEV_DEBUG_OPTION},
140
{"header", optional_argument, NULL, HEADER_OPTION},
141
{"format", required_argument, NULL, FORMAT_OPTION},
142
{"invalid", required_argument, NULL, INVALID_OPTION},
143
{GETOPT_HELP_OPTION_DECL},
144
{GETOPT_VERSION_OPTION_DECL},
148
/* If delimiter has this value, blanks separate fields. */
149
enum { DELIMITER_DEFAULT = CHAR_MAX + 1 };
151
/* Maximum number of digits we can safely handle
152
without precision loss, if scaling is 'none'. */
153
enum { MAX_UNSCALED_DIGITS = 18 };
155
/* Maximum number of digits we can work with.
156
This is equivalent to 999Y.
157
NOTE: 'long double' can handle more than that, but there's
158
no official suffix assigned beyond Yotta (1000^8). */
159
enum { MAX_ACCEPTABLE_DIGITS = 27 };
161
static enum scale_type scale_from = scale_none;
162
static enum scale_type scale_to = scale_none;
163
static enum round_type _round = round_from_zero;
164
static enum inval_type _invalid = inval_abort;
165
static const char *suffix = NULL;
166
static uintmax_t from_unit_size = 1;
167
static uintmax_t to_unit_size = 1;
168
static int grouping = 0;
169
static char *padding_buffer = NULL;
170
static size_t padding_buffer_size = 0;
171
static long int padding_width = 0;
172
static const char *format_str = NULL;
173
static char *format_str_prefix = NULL;
174
static char *format_str_suffix = NULL;
176
/* By default, any conversion error will terminate the program. */
177
static int conv_exit_code = EXIT_CONVERSION_WARNINGS;
180
/* auto-pad each line based on skipped whitespace. */
181
static int auto_padding = 0;
182
static mbs_align_t padding_alignment = MBS_ALIGN_RIGHT;
183
static long int field = 1;
184
static int delimiter = DELIMITER_DEFAULT;
186
/* if non-zero, the first 'header' lines from STDIN are skipped. */
187
static uintmax_t header = 0;
189
/* Debug for users: print warnings to STDERR about possible
190
error (similar to sort's debug). */
193
/* will be set according to the current locale. */
194
static const char *decimal_point;
195
static int decimal_point_length;
197
/* debugging for developers. Enables devmsg(). */
198
static bool dev_debug = false;
200
/* Like error(0, 0, ...), but without an implicit newline.
201
Also a noop unless the global DEV_DEBUG is set.
202
TODO: Replace with variadic macro in system.h or
203
move to a separate module. */
205
devmsg (char const *fmt, ...)
211
vfprintf (stderr, fmt, ap);
217
default_scale_base (enum scale_type scale)
234
valid_suffix (const char suf)
236
static const char *valid_suffixes = "KMGTPEZY";
237
return (strchr (valid_suffixes, suf) != NULL);
241
suffix_power (const char suf)
245
case 'K': /* kilo or kibi. */
248
case 'M': /* mega or mebi. */
251
case 'G': /* giga or gibi. */
254
case 'T': /* tera or tebi. */
257
case 'P': /* peta or pebi. */
260
case 'E': /* exa or exbi. */
263
case 'Z': /* zetta or 2**70. */
266
case 'Y': /* yotta or 2**80. */
269
default: /* should never happen. assert? */
274
static inline const char *
275
suffix_power_character (unsigned int power)
311
/* Similar to 'powl(3)' but without requiring 'libm'. */
313
powerld (long double base, unsigned int x)
315
long double result = base;
317
return 1; /* note for test coverage: this is never
318
reached, as 'powerld' won't be called if
319
there's no suffix, hence, no "power". */
321
/* TODO: check for overflow, inf? */
327
/* Similar to 'fabs(3)' but without requiring 'libm'. */
328
static inline long double
329
absld (long double val)
331
return val < 0 ? -val : val;
334
/* Scale down 'val', returns 'updated val' and 'x', such that
335
val*base^X = original val
336
Similar to "frexpl(3)" but without requiring 'libm',
337
allowing only integer scale, limited functionality and error checking. */
339
expld (long double val, unsigned int base, unsigned int /*output */ *x)
341
unsigned int power = 0;
343
if (val >= -LDBL_MAX && val <= LDBL_MAX)
345
while (absld (val) >= base)
356
/* EXTREMELY limited 'ceil' - without 'libm'.
357
Assumes values that fit in intmax_t. */
358
static inline intmax_t
359
simple_round_ceiling (long double val)
361
intmax_t intval = val;
367
/* EXTREMELY limited 'floor' - without 'libm'.
368
Assumes values that fit in intmax_t. */
369
static inline intmax_t
370
simple_round_floor (long double val)
372
return -simple_round_ceiling (-val);
375
/* EXTREMELY limited 'round away from zero'.
376
Assumes values that fit in intmax_t. */
377
static inline intmax_t
378
simple_round_from_zero (long double val)
380
return val < 0 ? simple_round_floor (val) : simple_round_ceiling (val);
383
/* EXTREMELY limited 'round away to zero'.
384
Assumes values that fit in intmax_t. */
385
static inline intmax_t
386
simple_round_to_zero (long double val)
391
/* EXTREMELY limited 'round' - without 'libm'.
392
Assumes values that fit in intmax_t. */
393
static inline intmax_t
394
simple_round_nearest (long double val)
396
return val < 0 ? val - 0.5 : val + 0.5;
399
static inline intmax_t
400
simple_round (long double val, enum round_type t)
405
return simple_round_ceiling (val);
408
return simple_round_floor (val);
410
case round_from_zero:
411
return simple_round_from_zero (val);
414
return simple_round_to_zero (val);
417
return simple_round_nearest (val);
420
/* to silence the compiler - this should never happen. */
425
enum simple_strtod_error
428
SSE_OK_PRECISION_LOSS,
432
/* the following are returned by 'simple_strtod_human'. */
433
SSE_VALID_BUT_FORBIDDEN_SUFFIX,
438
/* Read an *integer* INPUT_STR,
439
but return the integer value in a 'long double' VALUE
440
hence, no UINTMAX_MAX limitation.
441
NEGATIVE is updated, and is stored separately from the VALUE
442
so that signbit() isn't required to determine the sign of -0..
443
ENDPTR is required (unlike strtod) and is used to store a pointer
444
to the character after the last character used in the conversion.
446
Note locale'd grouping is not supported,
447
nor is skipping of white-space supported.
450
SSE_OK - valid number.
451
SSE_OK_PRECISION_LOSS - if more than 18 digits were used.
452
SSE_OVERFLOW - if more than 27 digits (999Y) were used.
453
SSE_INVALID_NUMBER - if no digits were found. */
454
static enum simple_strtod_error
455
simple_strtod_int (const char *input_str,
456
char **endptr, long double *value, bool *negative)
458
enum simple_strtod_error e = SSE_OK;
461
unsigned int digits = 0;
463
if (*input_str == '-')
471
*endptr = (char *) input_str;
472
while (*endptr && isdigit (**endptr))
474
int digit = (**endptr) - '0';
476
/* can this happen in some strange locale? */
477
if (digit < 0 || digit > 9)
478
return SSE_INVALID_NUMBER;
480
if (digits > MAX_UNSCALED_DIGITS)
481
e = SSE_OK_PRECISION_LOSS;
484
if (digits > MAX_ACCEPTABLE_DIGITS)
493
return SSE_INVALID_NUMBER;
503
/* Read a floating-point INPUT_STR represented as "NNNN[.NNNNN]",
504
and return the value in a 'long double' VALUE.
505
ENDPTR is required (unlike strtod) and is used to store a pointer
506
to the character after the last character used in the conversion.
507
PRECISION is optional and used to indicate fractions are present.
509
Note locale'd grouping is not supported,
510
nor is skipping of white-space supported.
513
SSE_OK - valid number.
514
SSE_OK_PRECISION_LOSS - if more than 18 digits were used.
515
SSE_OVERFLOW - if more than 27 digits (999Y) were used.
516
SSE_INVALID_NUMBER - if no digits were found. */
517
static enum simple_strtod_error
518
simple_strtod_float (const char *input_str,
524
enum simple_strtod_error e = SSE_OK;
529
/* TODO: accept locale'd grouped values for the integral part. */
530
e = simple_strtod_int (input_str, endptr, value, &negative);
531
if (e != SSE_OK && e != SSE_OK_PRECISION_LOSS)
535
/* optional decimal point + fraction. */
536
if (STREQ_LEN (*endptr, decimal_point, decimal_point_length))
539
long double val_frac = 0;
542
(*endptr) += decimal_point_length;
543
enum simple_strtod_error e2 =
544
simple_strtod_int (*endptr, &ptr2, &val_frac, &neg_frac);
545
if (e2 != SSE_OK && e2 != SSE_OK_PRECISION_LOSS)
547
if (e2 == SSE_OK_PRECISION_LOSS)
548
e = e2; /* propagate warning. */
550
return SSE_INVALID_NUMBER;
552
/* number of digits in the fractions. */
553
size_t exponent = ptr2 - *endptr;
555
val_frac = ((long double) val_frac) / powerld (10, exponent);
566
*precision = exponent;
573
/* Read a 'human' INPUT_STR represented as "NNNN[.NNNNN] + suffix",
574
and return the value in a 'long double' VALUE,
575
with the precision of the input returned in PRECISION.
576
ENDPTR is required (unlike strtod) and is used to store a pointer
577
to the character after the last character used in the conversion.
578
ALLOWED_SCALING determines the scaling supported.
581
support locale'd grouping
582
accept scentific and hex floats (probably use strtold directly)
585
SSE_OK - valid number.
586
SSE_OK_PRECISION_LOSS - if more than 18 digits were used.
587
SSE_OVERFLOW - if more than 27 digits (999Y) were used.
588
SSE_INVALID_NUMBER - if no digits were found.
589
SSE_VALID_BUT_FORBIDDEN_SUFFIX
591
SSE_MISSING_I_SUFFIX */
592
static enum simple_strtod_error
593
simple_strtod_human (const char *input_str,
594
char **endptr, long double *value, size_t *precision,
595
enum scale_type allowed_scaling)
598
/* 'scale_auto' is checked below. */
599
int scale_base = default_scale_base (allowed_scaling);
601
devmsg ("simple_strtod_human:\n input string: '%s'\n "
602
"locale decimal-point: '%s'\n", input_str, decimal_point);
604
enum simple_strtod_error e =
605
simple_strtod_float (input_str, endptr, value, precision);
606
if (e != SSE_OK && e != SSE_OK_PRECISION_LOSS)
609
devmsg (" parsed numeric value: %Lf\n"
610
" input precision = %d\n", *value, (int)*precision);
612
if (**endptr != '\0')
614
/* process suffix. */
616
/* Skip any blanks between the number and suffix. */
617
while (isblank (**endptr))
620
if (!valid_suffix (**endptr))
621
return SSE_INVALID_SUFFIX;
623
if (allowed_scaling == scale_none)
624
return SSE_VALID_BUT_FORBIDDEN_SUFFIX;
626
power = suffix_power (**endptr);
627
(*endptr)++; /* skip first suffix character. */
629
if (allowed_scaling == scale_auto && **endptr == 'i')
631
/* auto-scaling enabled, and the first suffix character
632
is followed by an 'i' (e.g. Ki, Mi, Gi). */
634
(*endptr)++; /* skip second ('i') suffix character. */
635
devmsg (" Auto-scaling, found 'i', switching to base %d\n",
639
*precision = 0; /* Reset, to select precision based on scale. */
642
if (allowed_scaling == scale_IEC_I)
647
return SSE_MISSING_I_SUFFIX;
650
long double multiplier = powerld (scale_base, power);
652
devmsg (" suffix power=%d^%d = %Lf\n", scale_base, power, multiplier);
654
/* TODO: detect loss of precision and overflows. */
655
(*value) = (*value) * multiplier;
657
devmsg (" returning value: %Lf (%LG)\n", *value, *value);
664
simple_strtod_fatal (enum simple_strtod_error err, char const *input_str)
666
char const *msgid = NULL;
670
case SSE_OK_PRECISION_LOSS:
672
/* should never happen - this function isn't called when OK. */
676
msgid = N_("value too large to be converted: '%s'");
679
case SSE_INVALID_NUMBER:
680
msgid = N_("invalid number: '%s'");
683
case SSE_VALID_BUT_FORBIDDEN_SUFFIX:
684
msgid = N_("rejecting suffix in input: '%s' (consider using --from)");
687
case SSE_INVALID_SUFFIX:
688
msgid = N_("invalid suffix in input: '%s'");
691
case SSE_MISSING_I_SUFFIX:
692
msgid = N_("missing 'i' suffix in input: '%s' (e.g Ki/Mi/Gi)");
697
if (_invalid != inval_ignore)
698
error (conv_exit_code, 0, gettext (msgid), input_str);
701
/* Convert VAL to a human format string in BUF. */
703
double_to_human (long double val, int precision,
704
char *buf, size_t buf_size,
705
enum scale_type scale, int group, enum round_type round)
707
devmsg ("double_to_human:\n");
709
if (scale == scale_none)
711
val *= powerld (10, precision);
712
val = simple_round (val, round);
713
val /= powerld (10, precision);
716
" no scaling, returning (grouped) value: %'.*Lf\n" :
717
" no scaling, returning value: %.*Lf\n", precision, val);
719
int i = snprintf (buf, buf_size, (group) ? "%'.*Lf" : "%.*Lf",
721
if (i < 0 || i >= (int) buf_size)
722
error (EXIT_FAILURE, 0,
723
_("failed to prepare value '%Lf' for printing"), val);
727
/* Scaling requested by user. */
728
double scale_base = default_scale_base (scale);
730
/* Normalize val to scale. */
731
unsigned int power = 0;
732
val = expld (val, scale_base, &power);
733
devmsg (" scaled value to %Lf * %0.f ^ %d\n", val, scale_base, power);
735
/* Perform rounding. */
737
if (absld (val) < 10)
739
/* for values less than 10, we allow one decimal-point digit,
740
so adjust before rounding. */
744
val = simple_round (val, round);
745
/* two special cases after rounding:
746
1. a "999.99" can turn into 1000 - so scale down
747
2. a "9.99" can turn into 10 - so don't display decimal-point. */
748
if (absld (val) >= scale_base)
756
/* should "7.0" be printed as "7" ?
757
if removing the ".0" is preferred, enable the fourth condition. */
758
int show_decimal_point = (val != 0) && (absld (val) < 10) && (power > 0);
759
/* && (absld (val) > simple_round_floor (val))) */
761
devmsg (" after rounding, value=%Lf * %0.f ^ %d\n", val, scale_base, power);
763
snprintf (buf, buf_size, (show_decimal_point) ? "%.1Lf%s" : "%.0Lf%s",
764
val, suffix_power_character (power));
766
if (scale == scale_IEC_I && power > 0)
767
strncat (buf, "i", buf_size - strlen (buf) - 1);
769
devmsg (" returning value: '%s'\n", buf);
774
/* Convert a string of decimal digits, N_STRING, with an optional suffix
775
to an integral value. Upon successful conversion, return that value.
776
If it cannot be converted, give a diagnostic and exit. */
778
unit_to_umax (const char *n_string)
784
s_err = xstrtoumax (n_string, &end, 10, &n, "KMGTPEZY");
786
if (s_err != LONGINT_OK || *end || n == 0)
787
error (EXIT_FAILURE, 0, _("invalid unit size: '%s'"), n_string);
794
setup_padding_buffer (size_t min_size)
796
if (padding_buffer_size > min_size)
799
padding_buffer_size = min_size + 1;
800
padding_buffer = realloc (padding_buffer, padding_buffer_size);
802
error (EXIT_FAILURE, 0, _("out of memory (requested %zu bytes)"),
803
padding_buffer_size);
809
if (status != EXIT_SUCCESS)
814
Usage: %s [OPTION]... [NUMBER]...\n\
817
Reformat NUMBER(s), or the numbers from standard input if none are specified.\n\
819
emit_mandatory_arg_note ();
821
--debug print warnings about invalid input\n\
824
-d, --delimiter=X use X instead of whitespace for field delimiter\n\
827
--field=N replace the number in input field N (default is 1)\n\
830
--format=FORMAT use printf style floating-point FORMAT;\n\
831
see FORMAT below for details\n\
834
--from=UNIT auto-scale input numbers to UNITs; default is 'none';\n\
838
--from-unit=N specify the input unit size (instead of the default 1)\n\
841
--grouping use locale-defined grouping of digits, e.g. 1,000,000\n\
842
(which means it has no effect in the C/POSIX locale)\n\
845
--header[=N] print (without converting) the first N header lines;\n\
846
N defaults to 1 if not specified\n\
849
--invalid=MODE failure mode for invalid numbers: MODE can be:\n\
850
abort (default), fail, warn, ignore\n\
853
--padding=N pad the output to N characters; positive N will\n\
854
right-align; negative N will left-align;\n\
855
padding is ignored if the output is wider than N;\n\
856
the default is to automatically pad if a whitespace\n\
860
--round=METHOD use METHOD for rounding when scaling; METHOD can be:\n\
861
up, down, from-zero (default), towards-zero, nearest\n\
864
--suffix=SUFFIX add SUFFIX to output numbers, and accept optional\n\
865
SUFFIX in input numbers\n\
868
--to=UNIT auto-scale output numbers to UNITs; see UNIT below\n\
871
--to-unit=N the output unit size (instead of the default 1)\n\
874
fputs (HELP_OPTION_DESCRIPTION, stdout);
875
fputs (VERSION_OPTION_DESCRIPTION, stdout);
879
UNIT options:\n"), stdout);
881
none no auto-scaling is done; suffixes will trigger an error\n\
884
auto accept optional single/two letter suffix:\n\
888
1Mi = 1048576,\n"), stdout);
890
si accept optional single letter suffix:\n\
895
iec accept optional single letter suffix:\n\
900
iec-i accept optional two-letter suffix:\n\
906
FORMAT must be suitable for printing one floating-point argument '%f'.\n\
907
Optional quote (%'f) will enable --grouping (if supported by current locale).\n\
908
Optional width value (%10f) will pad output. Optional negative width values\n\
909
(%-10f) will left-pad output.\n\
913
Exit status is 0 if all input numbers were successfully converted.\n\
914
By default, %s will stop at the first conversion error with exit status 2.\n\
915
With --invalid='fail' a warning is printed for each conversion error\n\
916
and the exit status is 2. With --invalid='warn' each conversion error is\n\
917
diagnosed, but the exit status is 0. With --invalid='ignore' conversion\n\
918
errors are not diagnosed and the exit status is 0.\n\
925
$ %s --to=iec 2048\n\
927
$ %s --to=iec-i 4096\n\
929
$ echo 1K | %s --from=si\n\
931
$ echo 1K | %s --from=iec\n\
933
$ df | %s --header --field 2 --to=si\n\
934
$ ls -l | %s --header --field 5 --to=iec\n\
935
$ ls -lh | %s --header --field 5 --from=iec --padding=10\n\
936
$ ls -lh | %s --header --field 5 --from=iec --format %%10f\n"),
937
program_name, program_name, program_name,
938
program_name, program_name, program_name,
939
program_name, program_name, program_name);
940
emit_ancillary_info ();
945
/* Given 'fmt' (a printf(3) compatible format string), extracts the following:
946
1. padding (e.g. %20f)
947
2. alignment (e.g. %-20f)
948
3. grouping (e.g. %'f)
950
Only a limited subset of printf(3) syntax is supported.
954
support %e %g etc. rather than just %f
957
1. This function sets the global variables:
958
padding_width, padding_alignment, grouping,
959
format_str_prefix, format_str_suffix
960
2. The function aborts on any errors. */
962
parse_format_string (char const *fmt)
965
size_t prefix_len = 0;
970
for (i = 0; !(fmt[i] == '%' && fmt[i + 1] != '%'); i += (fmt[i] == '%') + 1)
973
error (EXIT_FAILURE, 0,
974
_("format %s has no %% directive"), quote (fmt));
979
i += strspn (fmt + i, " ");
985
i += strspn (fmt + i, " ");
987
pad = strtol (fmt + i, &endptr, 10);
989
error (EXIT_FAILURE, 0,
990
_("invalid format %s (width overflow)"), quote (fmt));
992
if (endptr != (fmt + i) && pad != 0)
996
padding_alignment = MBS_ALIGN_LEFT;
997
padding_width = -pad;
1001
padding_width = pad;
1007
error (EXIT_FAILURE, 0, _("format %s ends in %%"), quote (fmt));
1010
error (EXIT_FAILURE, 0, _("invalid format %s,"
1011
" directive must be %%['][-][N]f"),
1016
for (; fmt[i] != '\0'; i += (fmt[i] == '%') + 1)
1017
if (fmt[i] == '%' && fmt[i + 1] != '%')
1018
error (EXIT_FAILURE, 0, _("format %s has too many %% directives"),
1023
format_str_prefix = xstrndup (fmt, prefix_len);
1024
if (!format_str_prefix)
1025
error (EXIT_FAILURE, 0, _("out of memory (requested %zu bytes)"),
1028
if (fmt[suffix_pos] != '\0')
1030
format_str_suffix = strdup (fmt + suffix_pos);
1031
if (!format_str_suffix)
1032
error (EXIT_FAILURE, 0, _("out of memory (requested %zu bytes)"),
1033
strlen (fmt + suffix_pos));
1036
devmsg ("format String:\n input: %s\n grouping: %s\n"
1037
" padding width: %ld\n alignment: %s\n"
1038
" prefix: '%s'\n suffix: '%s'\n",
1039
quote (fmt), (grouping) ? "yes" : "no",
1041
(padding_alignment == MBS_ALIGN_LEFT) ? "Left" : "Right",
1042
format_str_prefix, format_str_suffix);
1045
/* Parse a numeric value (with optional suffix) from a string.
1046
Returns a long double value, with input precision.
1048
If there's an error converting the string to value - exits with
1051
If there are any trailing characters after the number
1052
(besides a valid suffix) - exits with an error. */
1053
static enum simple_strtod_error
1054
parse_human_number (const char *str, long double /*output */ *value,
1059
enum simple_strtod_error e =
1060
simple_strtod_human (str, &ptr, value, precision, scale_from);
1061
if (e != SSE_OK && e != SSE_OK_PRECISION_LOSS)
1063
simple_strtod_fatal (e, str);
1067
if (ptr && *ptr != '\0')
1069
if (_invalid != inval_ignore)
1070
error (conv_exit_code, 0, _("invalid suffix in input '%s': '%s'"),
1072
e = SSE_INVALID_SUFFIX;
1078
/* Print the given VAL, using the requested representation.
1079
The number is printed to STDOUT, with padding and alignment. */
1081
prepare_padded_number (const long double val, size_t precision)
1083
/* Generate Output. */
1086
/* Can't reliably print too-large values without auto-scaling. */
1088
expld (val, 10, &x);
1089
if (scale_to == scale_none && x > MAX_UNSCALED_DIGITS)
1091
if (_invalid != inval_ignore)
1092
error (conv_exit_code, 0, _("value too large to be printed: '%Lg'"
1093
" (consider using --to)"), val);
1097
if (x > MAX_ACCEPTABLE_DIGITS - 1)
1099
if (_invalid != inval_ignore)
1100
error (conv_exit_code, 0, _("value too large to be printed: '%Lg'"
1101
" (cannot handle values > 999Y)"), val);
1105
double_to_human (val, precision, buf, sizeof (buf), scale_to, grouping,
1108
strncat (buf, suffix, sizeof (buf) - strlen (buf) -1);
1110
devmsg ("formatting output:\n value: %Lf\n humanized: '%s'\n", val, buf);
1112
if (padding_width && strlen (buf) < padding_width)
1114
size_t w = padding_width;
1115
mbsalign (buf, padding_buffer, padding_buffer_size, &w,
1116
padding_alignment, MBA_UNIBYTE_ONLY);
1118
devmsg (" After padding: '%s'\n", padding_buffer);
1122
setup_padding_buffer (strlen (buf) + 1);
1123
strcpy (padding_buffer, buf);
1130
print_padded_number (void)
1132
if (format_str_prefix)
1133
fputs (format_str_prefix, stdout);
1135
fputs (padding_buffer, stdout);
1137
if (format_str_suffix)
1138
fputs (format_str_suffix, stdout);
1141
/* Converts the TEXT number string to the requested representation,
1142
and handles automatic suffix addition. */
1144
process_suffixed_number (char *text, long double *result, size_t *precision)
1146
if (suffix && strlen (text) > strlen (suffix))
1148
char *possible_suffix = text + strlen (text) - strlen (suffix);
1150
if (STREQ (suffix, possible_suffix))
1152
/* trim suffix, ONLY if it's at the end of the text. */
1153
*possible_suffix = '\0';
1154
devmsg ("trimming suffix '%s'\n", suffix);
1157
devmsg ("no valid suffix found\n");
1160
/* Skip white space - always. */
1162
while (*p && isblank (*p))
1164
const unsigned int skip_count = text - p;
1166
/* setup auto-padding. */
1169
if (skip_count > 0 || field > 1)
1171
padding_width = strlen (text);
1172
setup_padding_buffer (padding_width);
1178
devmsg ("setting Auto-Padding to %ld characters\n", padding_width);
1181
long double val = 0;
1182
enum simple_strtod_error e = parse_human_number (p, &val, precision);
1183
if (e == SSE_OK_PRECISION_LOSS && debug)
1184
error (0, 0, _("large input value '%s': possible precision loss"), p);
1186
if (from_unit_size != 1 || to_unit_size != 1)
1187
val = (val * from_unit_size) / to_unit_size;
1191
return (e == SSE_OK || e == SSE_OK_PRECISION_LOSS);
1194
/* Skip the requested number of fields in the input string.
1195
Returns a pointer to the *delimiter* of the requested field,
1196
or a pointer to NUL (if reached the end of the string). */
1197
static inline char *
1198
__attribute ((pure))
1199
skip_fields (char *buf, int fields)
1202
if (delimiter != DELIMITER_DEFAULT)
1204
if (*ptr == delimiter)
1206
while (*ptr && fields--)
1208
while (*ptr && *ptr == delimiter)
1210
while (*ptr && *ptr != delimiter)
1215
while (*ptr && fields--)
1217
while (*ptr && isblank (*ptr))
1219
while (*ptr && !isblank (*ptr))
1225
/* Parse a delimited string, and extracts the requested field.
1226
NOTE: the input buffer is modified.
1229
Maybe support multiple fields, though can always pipe output
1230
into another numfmt to process other fields.
1231
Maybe default to processing all fields rather than just first?
1234
_PREFIX, _DATA, _SUFFIX will point to the relevant positions
1235
in the input string, or be NULL if such a part doesn't exist. */
1237
extract_fields (char *line, int _field,
1238
char ** _prefix, char ** _data, char ** _suffix)
1245
devmsg ("extracting Fields:\n input: '%s'\n field: %d\n", line, _field);
1249
/* skip the requested number of fields. */
1251
ptr = skip_fields (line, field - 1);
1254
/* not enough fields in the input - print warning? */
1255
devmsg (" TOO FEW FIELDS!\n prefix: '%s'\n", *_prefix);
1264
*_suffix = skip_fields (*_data, 1);
1267
/* there is a suffix (i.e. the field is not the last on the line),
1268
so null-terminate the _data before it. */
1275
devmsg (" prefix: '%s'\n number: '%s'\n suffix: '%s'\n",
1276
*_prefix, *_data, *_suffix);
1280
/* Convert a number in a given line of text.
1281
NEWLINE specifies whether to output a '\n' for this "line". */
1283
process_line (char *line, bool newline)
1285
char *pre, *num, *suf;
1286
long double val = 0;
1287
size_t precision = 0;
1288
int valid_number = 0;
1290
extract_fields (line, field, &pre, &num, &suf);
1292
if (_invalid != inval_ignore)
1293
error (conv_exit_code, 0, _("input line is too short, "
1294
"no numbers found to convert in field %ld"),
1299
valid_number = process_suffixed_number (num, &val, &precision);
1301
valid_number = prepare_padded_number (val, precision);
1305
fputs (pre, stdout);
1308
fputc ((delimiter == DELIMITER_DEFAULT) ? ' ' : delimiter, stdout);
1312
print_padded_number ();
1317
fputs (num, stdout);
1322
fputc ((delimiter == DELIMITER_DEFAULT) ? ' ' : delimiter, stdout);
1323
fputs (suf, stdout);
1329
return valid_number;
1333
main (int argc, char **argv)
1335
int valid_numbers = 1;
1337
initialize_main (&argc, &argv);
1338
set_program_name (argv[0]);
1339
setlocale (LC_ALL, "");
1340
bindtextdomain (PACKAGE, LOCALEDIR);
1341
textdomain (PACKAGE);
1343
decimal_point = nl_langinfo (RADIXCHAR);
1344
if (decimal_point == NULL || strlen (decimal_point) == 0)
1345
decimal_point = ".";
1346
decimal_point_length = strlen (decimal_point);
1348
atexit (close_stdout);
1352
int c = getopt_long (argc, argv, "d:", longopts, NULL);
1360
scale_from = XARGMATCH ("--from", optarg,
1361
scale_from_args, scale_from_types);
1364
case FROM_UNIT_OPTION:
1365
from_unit_size = unit_to_umax (optarg);
1370
XARGMATCH ("--to", optarg, scale_to_args, scale_to_types);
1373
case TO_UNIT_OPTION:
1374
to_unit_size = unit_to_umax (optarg);
1378
_round = XARGMATCH ("--round", optarg, round_args, round_types);
1381
case GROUPING_OPTION:
1385
case PADDING_OPTION:
1386
if (xstrtol (optarg, NULL, 10, &padding_width, "") != LONGINT_OK
1387
|| padding_width == 0)
1388
error (EXIT_FAILURE, 0, _("invalid padding value '%s'"), optarg);
1389
if (padding_width < 0)
1391
padding_alignment = MBS_ALIGN_LEFT;
1392
padding_width = -padding_width;
1394
/* TODO: We probably want to apply a specific --padding
1395
to --header lines too. */
1399
if (xstrtol (optarg, NULL, 10, &field, "") != LONGINT_OK
1401
error (EXIT_FAILURE, 0, _("invalid field value '%s'"), optarg);
1405
/* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */
1406
if (optarg[0] != '\0' && optarg[1] != '\0')
1407
error (EXIT_FAILURE, 0,
1408
_("the delimiter must be a single character"));
1409
delimiter = optarg[0];
1420
case DEV_DEBUG_OPTION:
1428
if (xstrtoumax (optarg, NULL, 10, &header, "") != LONGINT_OK
1430
error (EXIT_FAILURE, 0, _("invalid header value '%s'"),
1440
format_str = optarg;
1443
case INVALID_OPTION:
1444
_invalid = XARGMATCH ("--invalid", optarg, inval_args, inval_types);
1447
case_GETOPT_HELP_CHAR;
1448
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
1451
usage (EXIT_FAILURE);
1455
if (format_str != NULL && grouping)
1456
error (EXIT_FAILURE, 0, _("--grouping cannot be combined with --format"));
1457
if (format_str != NULL && padding_width > 0)
1458
error (EXIT_FAILURE, 0, _("--padding cannot be combined with --format"));
1460
/* Warn about no-op. */
1461
if (debug && scale_from == scale_none && scale_to == scale_none
1462
&& !grouping && (padding_width == 0) && (format_str == NULL))
1463
error (0, 0, _("no conversion option specified"));
1466
parse_format_string (format_str);
1470
if (scale_to != scale_none)
1471
error (EXIT_FAILURE, 0, _("grouping cannot be combined with --to"));
1472
if (debug && (strlen (nl_langinfo (THOUSEP)) == 0))
1473
error (0, 0, _("grouping has no effect in this locale"));
1477
setup_padding_buffer (padding_width);
1478
auto_padding = (padding_width == 0 && delimiter == DELIMITER_DEFAULT);
1480
if (_invalid != inval_abort)
1485
if (debug && header)
1486
error (0, 0, _("--header ignored with command-line input"));
1488
for (; optind < argc; optind++)
1489
valid_numbers &= process_line (argv[optind], true);
1494
size_t line_allocated = 0;
1497
while (header-- && getline (&line, &line_allocated, stdin) > 0)
1498
fputs (line, stdout);
1500
while ((len = getline (&line, &line_allocated, stdin)) > 0)
1502
bool newline = line[len - 1] == '\n';
1504
line[len - 1] = '\0';
1505
valid_numbers &= process_line (line, newline);
1508
IF_LINT (free (line));
1511
error (0, errno, _("error reading input"));
1514
free (padding_buffer);
1515
free (format_str_prefix);
1516
free (format_str_suffix);
1519
if (debug && !valid_numbers)
1520
error (0, 0, _("failed to convert some of the input numbers"));
1522
int exit_status = EXIT_SUCCESS;
1523
if (!valid_numbers && _invalid != inval_warn && _invalid != inval_ignore)
1524
exit_status = EXIT_CONVERSION_WARNINGS;