1 /* Reformat numbers like 11505426432 to the more human-readable 11G
2 Copyright (C) 2012-2023 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 <https://www.gnu.org/licenses/>. */
21 #include <sys/types.h>
33 #include "set-fields.h"
39 /* The official name of this program (e.g., no 'g' prefix). */
40 #define PROGRAM_NAME "numfmt"
42 #define AUTHORS proper_name ("Assaf Gordon")
44 /* Exit code when some numbers fail to convert. */
45 enum { TIMEOUT_FAILURE
= 1, EXIT_CONVERSION_WARNINGS
= 2 };
49 FROM_OPTION
= CHAR_MAX
+ 1,
67 scale_none
, /* the default: no scaling. */
68 scale_auto
, /* --from only. */
71 scale_IEC_I
/* 'i' suffix is required. */
74 static char const *const scale_from_args
[] =
76 "none", "auto", "si", "iec", "iec-i", NULL
79 static enum scale_type
const scale_from_types
[] =
81 scale_none
, scale_auto
, scale_SI
, scale_IEC
, scale_IEC_I
84 static char const *const scale_to_args
[] =
86 "none", "si", "iec", "iec-i", NULL
89 static enum scale_type
const scale_to_types
[] =
91 scale_none
, scale_SI
, scale_IEC
, scale_IEC_I
104 static char const *const round_args
[] =
106 "up", "down", "from-zero", "towards-zero", "nearest", NULL
109 static enum round_type
const round_types
[] =
111 round_ceiling
, round_floor
, round_from_zero
, round_to_zero
, round_nearest
123 static char const *const inval_args
[] =
125 "abort", "fail", "warn", "ignore", NULL
128 static enum inval_type
const inval_types
[] =
130 inval_abort
, inval_fail
, inval_warn
, inval_ignore
133 static struct option
const longopts
[] =
135 {"from", required_argument
, NULL
, FROM_OPTION
},
136 {"from-unit", required_argument
, NULL
, FROM_UNIT_OPTION
},
137 {"to", required_argument
, NULL
, TO_OPTION
},
138 {"to-unit", required_argument
, NULL
, TO_UNIT_OPTION
},
139 {"round", required_argument
, NULL
, ROUND_OPTION
},
140 {"padding", required_argument
, NULL
, PADDING_OPTION
},
141 {"suffix", required_argument
, NULL
, SUFFIX_OPTION
},
142 {"grouping", no_argument
, NULL
, GROUPING_OPTION
},
143 {"delimiter", required_argument
, NULL
, 'd'},
144 {"field", required_argument
, NULL
, FIELD_OPTION
},
145 {"debug", no_argument
, NULL
, DEBUG_OPTION
},
146 {"-debug", no_argument
, NULL
, DEV_DEBUG_OPTION
},
147 {"header", optional_argument
, NULL
, HEADER_OPTION
},
148 {"format", required_argument
, NULL
, FORMAT_OPTION
},
149 {"invalid", required_argument
, NULL
, INVALID_OPTION
},
150 {"zero-terminated", no_argument
, NULL
, 'z'},
151 {GETOPT_HELP_OPTION_DECL
},
152 {GETOPT_VERSION_OPTION_DECL
},
156 /* If delimiter has this value, blanks separate fields. */
157 enum { DELIMITER_DEFAULT
= CHAR_MAX
+ 1 };
159 /* Maximum number of digits we can safely handle
160 without precision loss, if scaling is 'none'. */
161 enum { MAX_UNSCALED_DIGITS
= LDBL_DIG
};
163 /* Maximum number of digits we can work with.
164 This is equivalent to 999Q.
165 NOTE: 'long double' can handle more than that, but there's
166 no official suffix assigned beyond Quetta (1000^10). */
167 enum { MAX_ACCEPTABLE_DIGITS
= 33 };
169 static enum scale_type scale_from
= scale_none
;
170 static enum scale_type scale_to
= scale_none
;
171 static enum round_type round_style
= round_from_zero
;
172 static enum inval_type inval_style
= inval_abort
;
173 static char const *suffix
= NULL
;
174 static uintmax_t from_unit_size
= 1;
175 static uintmax_t to_unit_size
= 1;
176 static int grouping
= 0;
177 static char *padding_buffer
= NULL
;
178 static size_t padding_buffer_size
= 0;
179 static long int padding_width
= 0;
180 static long int zero_padding_width
= 0;
181 static long int user_precision
= -1;
182 static char const *format_str
= NULL
;
183 static char *format_str_prefix
= NULL
;
184 static char *format_str_suffix
= NULL
;
186 /* By default, any conversion error will terminate the program. */
187 static int conv_exit_code
= EXIT_CONVERSION_WARNINGS
;
190 /* auto-pad each line based on skipped whitespace. */
191 static int auto_padding
= 0;
192 static mbs_align_t padding_alignment
= MBS_ALIGN_RIGHT
;
194 /* field delimiter */
195 static int delimiter
= DELIMITER_DEFAULT
;
197 /* line delimiter. */
198 static unsigned char line_delim
= '\n';
200 /* if non-zero, the first 'header' lines from STDIN are skipped. */
201 static uintmax_t header
= 0;
203 /* Debug for users: print warnings to STDERR about possible
204 error (similar to sort's debug). */
207 /* will be set according to the current locale. */
208 static char const *decimal_point
;
209 static int decimal_point_length
;
211 /* debugging for developers. Enables devmsg(). */
212 static bool dev_debug
= false;
216 default_scale_base (enum scale_type scale
)
232 static char const zero_and_valid_suffixes
[] = "0KMGTPEZYRQ";
233 static char const *valid_suffixes
= 1 + zero_and_valid_suffixes
;
236 valid_suffix (const char suf
)
238 return strchr (valid_suffixes
, suf
) != NULL
;
242 suffix_power (const char suf
)
246 case 'K': /* kilo or kibi. */
249 case 'M': /* mega or mebi. */
252 case 'G': /* giga or gibi. */
255 case 'T': /* tera or tebi. */
258 case 'P': /* peta or pebi. */
261 case 'E': /* exa or exbi. */
264 case 'Z': /* zetta or 2**70. */
267 case 'Y': /* yotta or 2**80. */
270 case 'R': /* ronna or 2**90. */
273 case 'Q': /* quetta or 2**100. */
276 default: /* should never happen. assert? */
281 static inline char const *
282 suffix_power_char (unsigned int power
)
324 /* Similar to 'powl(3)' but without requiring 'libm'. */
326 powerld (long double base
, unsigned int x
)
328 long double result
= base
;
330 return 1; /* note for test coverage: this is never
331 reached, as 'powerld' won't be called if
332 there's no suffix, hence, no "power". */
334 /* TODO: check for overflow, inf? */
340 /* Similar to 'fabs(3)' but without requiring 'libm'. */
341 static inline long double
342 absld (long double val
)
344 return val
< 0 ? -val
: val
;
347 /* Scale down 'val', returns 'updated val' and 'x', such that
348 val*base^X = original val
349 Similar to "frexpl(3)" but without requiring 'libm',
350 allowing only integer scale, limited functionality and error checking. */
352 expld (long double val
, unsigned int base
, unsigned int /*output */ *x
)
354 unsigned int power
= 0;
356 if (val
>= -LDBL_MAX
&& val
<= LDBL_MAX
)
358 while (absld (val
) >= base
)
369 /* EXTREMELY limited 'ceil' - without 'libm'.
370 Assumes values that fit in intmax_t. */
371 static inline intmax_t
372 simple_round_ceiling (long double val
)
374 intmax_t intval
= val
;
380 /* EXTREMELY limited 'floor' - without 'libm'.
381 Assumes values that fit in intmax_t. */
382 static inline intmax_t
383 simple_round_floor (long double val
)
385 return -simple_round_ceiling (-val
);
388 /* EXTREMELY limited 'round away from zero'.
389 Assumes values that fit in intmax_t. */
390 static inline intmax_t
391 simple_round_from_zero (long double val
)
393 return val
< 0 ? simple_round_floor (val
) : simple_round_ceiling (val
);
396 /* EXTREMELY limited 'round away to zero'.
397 Assumes values that fit in intmax_t. */
398 static inline intmax_t
399 simple_round_to_zero (long double val
)
404 /* EXTREMELY limited 'round' - without 'libm'.
405 Assumes values that fit in intmax_t. */
406 static inline intmax_t
407 simple_round_nearest (long double val
)
409 return val
< 0 ? val
- 0.5 : val
+ 0.5;
413 static inline long double
414 simple_round (long double val
, enum round_type t
)
417 intmax_t intmax_mul
= val
/ INTMAX_MAX
;
418 val
-= (long double) INTMAX_MAX
* intmax_mul
;
423 rval
= simple_round_ceiling (val
);
427 rval
= simple_round_floor (val
);
430 case round_from_zero
:
431 rval
= simple_round_from_zero (val
);
435 rval
= simple_round_to_zero (val
);
439 rval
= simple_round_nearest (val
);
443 /* to silence the compiler - this should never happen. */
447 return (long double) INTMAX_MAX
* intmax_mul
+ rval
;
450 enum simple_strtod_error
453 SSE_OK_PRECISION_LOSS
,
457 /* the following are returned by 'simple_strtod_human'. */
458 SSE_VALID_BUT_FORBIDDEN_SUFFIX
,
463 /* Read an *integer* INPUT_STR,
464 but return the integer value in a 'long double' VALUE
465 hence, no UINTMAX_MAX limitation.
466 NEGATIVE is updated, and is stored separately from the VALUE
467 so that signbit() isn't required to determine the sign of -0..
468 ENDPTR is required (unlike strtod) and is used to store a pointer
469 to the character after the last character used in the conversion.
471 Note locale'd grouping is not supported,
472 nor is skipping of white-space supported.
475 SSE_OK - valid number.
476 SSE_OK_PRECISION_LOSS - if more than 18 digits were used.
477 SSE_OVERFLOW - if more than 33 digits (999Q) were used.
478 SSE_INVALID_NUMBER - if no digits were found. */
479 static enum simple_strtod_error
480 simple_strtod_int (char const *input_str
,
481 char **endptr
, long double *value
, bool *negative
)
483 enum simple_strtod_error e
= SSE_OK
;
486 unsigned int digits
= 0;
487 bool found_digit
= false;
489 if (*input_str
== '-')
497 *endptr
= (char *) input_str
;
498 while (c_isdigit (**endptr
))
500 int digit
= (**endptr
) - '0';
507 if (digits
> MAX_UNSCALED_DIGITS
)
508 e
= SSE_OK_PRECISION_LOSS
;
510 if (digits
> MAX_ACCEPTABLE_DIGITS
)
519 && ! STREQ_LEN (*endptr
, decimal_point
, decimal_point_length
))
520 return SSE_INVALID_NUMBER
;
530 /* Read a floating-point INPUT_STR represented as "NNNN[.NNNNN]",
531 and return the value in a 'long double' VALUE.
532 ENDPTR is required (unlike strtod) and is used to store a pointer
533 to the character after the last character used in the conversion.
534 PRECISION is optional and used to indicate fractions are present.
536 Note locale'd grouping is not supported,
537 nor is skipping of white-space supported.
540 SSE_OK - valid number.
541 SSE_OK_PRECISION_LOSS - if more than 18 digits were used.
542 SSE_OVERFLOW - if more than 33 digits (999Q) were used.
543 SSE_INVALID_NUMBER - if no digits were found. */
544 static enum simple_strtod_error
545 simple_strtod_float (char const *input_str
,
551 enum simple_strtod_error e
= SSE_OK
;
556 /* TODO: accept locale'd grouped values for the integral part. */
557 e
= simple_strtod_int (input_str
, endptr
, value
, &negative
);
558 if (e
!= SSE_OK
&& e
!= SSE_OK_PRECISION_LOSS
)
561 /* optional decimal point + fraction. */
562 if (STREQ_LEN (*endptr
, decimal_point
, decimal_point_length
))
565 long double val_frac
= 0;
568 (*endptr
) += decimal_point_length
;
569 enum simple_strtod_error e2
=
570 simple_strtod_int (*endptr
, &ptr2
, &val_frac
, &neg_frac
);
571 if (e2
!= SSE_OK
&& e2
!= SSE_OK_PRECISION_LOSS
)
573 if (e2
== SSE_OK_PRECISION_LOSS
)
574 e
= e2
; /* propagate warning. */
576 return SSE_INVALID_NUMBER
;
578 /* number of digits in the fractions. */
579 size_t exponent
= ptr2
- *endptr
;
581 val_frac
= ((long double) val_frac
) / powerld (10, exponent
);
583 /* TODO: detect loss of precision (only really 18 digits
584 of precision across all digits (before and after '.')). */
594 *precision
= exponent
;
601 /* Read a 'human' INPUT_STR represented as "NNNN[.NNNNN] + suffix",
602 and return the value in a 'long double' VALUE,
603 with the precision of the input returned in PRECISION.
604 ENDPTR is required (unlike strtod) and is used to store a pointer
605 to the character after the last character used in the conversion.
606 ALLOWED_SCALING determines the scaling supported.
609 support locale'd grouping
610 accept scentific and hex floats (probably use strtold directly)
613 SSE_OK - valid number.
614 SSE_OK_PRECISION_LOSS - if more than LDBL_DIG digits were used.
615 SSE_OVERFLOW - if more than 33 digits (999Q) were used.
616 SSE_INVALID_NUMBER - if no digits were found.
617 SSE_VALID_BUT_FORBIDDEN_SUFFIX
619 SSE_MISSING_I_SUFFIX */
620 static enum simple_strtod_error
621 simple_strtod_human (char const *input_str
,
622 char **endptr
, long double *value
, size_t *precision
,
623 enum scale_type allowed_scaling
)
626 /* 'scale_auto' is checked below. */
627 int scale_base
= default_scale_base (allowed_scaling
);
629 devmsg ("simple_strtod_human:\n input string: %s\n"
630 " locale decimal-point: %s\n"
631 " MAX_UNSCALED_DIGITS: %d\n",
632 quote_n (0, input_str
),
633 quote_n (1, decimal_point
),
634 MAX_UNSCALED_DIGITS
);
636 enum simple_strtod_error e
=
637 simple_strtod_float (input_str
, endptr
, value
, precision
);
638 if (e
!= SSE_OK
&& e
!= SSE_OK_PRECISION_LOSS
)
641 devmsg (" parsed numeric value: %Lf\n"
642 " input precision = %d\n", *value
, (int)*precision
);
644 if (**endptr
!= '\0')
646 /* process suffix. */
648 /* Skip any blanks between the number and suffix. */
649 while (isblank (to_uchar (**endptr
)))
652 if (!valid_suffix (**endptr
))
653 return SSE_INVALID_SUFFIX
;
655 if (allowed_scaling
== scale_none
)
656 return SSE_VALID_BUT_FORBIDDEN_SUFFIX
;
658 power
= suffix_power (**endptr
);
659 (*endptr
)++; /* skip first suffix character. */
661 if (allowed_scaling
== scale_auto
&& **endptr
== 'i')
663 /* auto-scaling enabled, and the first suffix character
664 is followed by an 'i' (e.g. Ki, Mi, Gi). */
666 (*endptr
)++; /* skip second ('i') suffix character. */
667 devmsg (" Auto-scaling, found 'i', switching to base %d\n",
671 *precision
= 0; /* Reset, to select precision based on scale. */
674 if (allowed_scaling
== scale_IEC_I
)
679 return SSE_MISSING_I_SUFFIX
;
682 long double multiplier
= powerld (scale_base
, power
);
684 devmsg (" suffix power=%d^%d = %Lf\n", scale_base
, power
, multiplier
);
686 /* TODO: detect loss of precision and overflows. */
687 (*value
) = (*value
) * multiplier
;
689 devmsg (" returning value: %Lf (%LG)\n", *value
, *value
);
696 simple_strtod_fatal (enum simple_strtod_error err
, char const *input_str
)
698 char const *msgid
= NULL
;
702 case SSE_OK_PRECISION_LOSS
:
704 /* should never happen - this function isn't called when OK. */
708 msgid
= N_("value too large to be converted: %s");
711 case SSE_INVALID_NUMBER
:
712 msgid
= N_("invalid number: %s");
715 case SSE_VALID_BUT_FORBIDDEN_SUFFIX
:
716 msgid
= N_("rejecting suffix in input: %s (consider using --from)");
719 case SSE_INVALID_SUFFIX
:
720 msgid
= N_("invalid suffix in input: %s");
723 case SSE_MISSING_I_SUFFIX
:
724 msgid
= N_("missing 'i' suffix in input: %s (e.g Ki/Mi/Gi)");
729 if (inval_style
!= inval_ignore
)
730 error (conv_exit_code
, 0, gettext (msgid
), quote (input_str
));
733 /* Convert VAL to a human format string in BUF. */
735 double_to_human (long double val
, int precision
,
736 char *buf
, size_t buf_size
,
737 enum scale_type scale
, int group
, enum round_type round
)
741 static_assert ((INT_BUFSIZE_BOUND (zero_padding_width
)
742 + INT_BUFSIZE_BOUND (precision
)
743 + 10 /* for %.Lf etc. */)
752 if (zero_padding_width
)
753 pfmt
+= snprintf (pfmt
, sizeof (fmt
) - 2, "0%ld", zero_padding_width
);
755 devmsg ("double_to_human:\n");
757 if (scale
== scale_none
)
759 val
*= powerld (10, precision
);
760 val
= simple_round (val
, round
);
761 val
/= powerld (10, precision
);
764 " no scaling, returning (grouped) value: %'.*Lf\n" :
765 " no scaling, returning value: %.*Lf\n", precision
, val
);
767 stpcpy (pfmt
, ".*Lf");
769 num_size
= snprintf (buf
, buf_size
, fmt
, precision
, val
);
770 if (num_size
< 0 || num_size
>= (int) buf_size
)
771 die (EXIT_FAILURE
, 0,
772 _("failed to prepare value '%Lf' for printing"), val
);
776 /* Scaling requested by user. */
777 double scale_base
= default_scale_base (scale
);
779 /* Normalize val to scale. */
780 unsigned int power
= 0;
781 val
= expld (val
, scale_base
, &power
);
782 devmsg (" scaled value to %Lf * %0.f ^ %u\n", val
, scale_base
, power
);
784 /* Perform rounding. */
785 unsigned int power_adjust
= 0;
786 if (user_precision
!= -1)
787 power_adjust
= MIN (power
* 3, user_precision
);
788 else if (absld (val
) < 10)
790 /* for values less than 10, we allow one decimal-point digit,
791 so adjust before rounding. */
795 val
*= powerld (10, power_adjust
);
796 val
= simple_round (val
, round
);
797 val
/= powerld (10, power_adjust
);
799 /* two special cases after rounding:
800 1. a "999.99" can turn into 1000 - so scale down
801 2. a "9.99" can turn into 10 - so don't display decimal-point. */
802 if (absld (val
) >= scale_base
)
808 /* should "7.0" be printed as "7" ?
809 if removing the ".0" is preferred, enable the fourth condition. */
810 int show_decimal_point
= (val
!= 0) && (absld (val
) < 10) && (power
> 0);
811 /* && (absld (val) > simple_round_floor (val))) */
813 devmsg (" after rounding, value=%Lf * %0.f ^ %u\n", val
, scale_base
, power
);
815 stpcpy (pfmt
, ".*Lf%s");
817 int prec
= user_precision
== -1 ? show_decimal_point
: user_precision
;
819 /* buf_size - 1 used here to ensure place for possible scale_IEC_I suffix. */
820 num_size
= snprintf (buf
, buf_size
- 1, fmt
, prec
, val
,
821 suffix_power_char (power
));
822 if (num_size
< 0 || num_size
>= (int) buf_size
- 1)
823 die (EXIT_FAILURE
, 0,
824 _("failed to prepare value '%Lf' for printing"), val
);
826 if (scale
== scale_IEC_I
&& power
> 0)
827 strncat (buf
, "i", buf_size
- num_size
- 1);
829 devmsg (" returning value: %s\n", quote (buf
));
834 /* Convert a string of decimal digits, N_STRING, with an optional suffix
835 to an integral value. Suffixes are handled as with --from=auto.
836 Upon successful conversion, return that value.
837 If it cannot be converted, give a diagnostic and exit. */
839 unit_to_umax (char const *n_string
)
842 char const *c_string
= n_string
;
843 char *t_string
= NULL
;
844 size_t n_len
= strlen (n_string
);
847 char const *suffixes
= valid_suffixes
;
849 /* Adjust suffixes so K=1000, Ki=1024, KiB=invalid. */
850 if (n_len
&& ! c_isdigit (n_string
[n_len
- 1]))
852 t_string
= xmalloc (n_len
+ 2);
853 end
= t_string
+ n_len
- 1;
854 memcpy (t_string
, n_string
, n_len
);
856 if (*end
== 'i' && 2 <= n_len
&& ! c_isdigit (*(end
- 1)))
862 suffixes
= zero_and_valid_suffixes
;
868 s_err
= xstrtoumax (c_string
, &end
, 10, &n
, suffixes
);
870 if (s_err
!= LONGINT_OK
|| *end
|| n
== 0)
873 die (EXIT_FAILURE
, 0, _("invalid unit size: %s"), quote (n_string
));
883 setup_padding_buffer (size_t min_size
)
885 if (padding_buffer_size
> min_size
)
888 padding_buffer_size
= min_size
+ 1;
889 padding_buffer
= xrealloc (padding_buffer
, padding_buffer_size
);
895 if (status
!= EXIT_SUCCESS
)
900 Usage: %s [OPTION]... [NUMBER]...\n\
903 Reformat NUMBER(s), or the numbers from standard input if none are specified.\n\
905 emit_mandatory_arg_note ();
907 --debug print warnings about invalid input\n\
910 -d, --delimiter=X use X instead of whitespace for field delimiter\n\
913 --field=FIELDS replace the numbers in these input fields (default=1);\n\
917 --format=FORMAT use printf style floating-point FORMAT;\n\
918 see FORMAT below for details\n\
921 --from=UNIT auto-scale input numbers to UNITs; default is 'none';\n\
925 --from-unit=N specify the input unit size (instead of the default 1)\n\
928 --grouping use locale-defined grouping of digits, e.g. 1,000,000\n\
929 (which means it has no effect in the C/POSIX locale)\n\
932 --header[=N] print (without converting) the first N header lines;\n\
933 N defaults to 1 if not specified\n\
936 --invalid=MODE failure mode for invalid numbers: MODE can be:\n\
937 abort (default), fail, warn, ignore\n\
940 --padding=N pad the output to N characters; positive N will\n\
941 right-align; negative N will left-align;\n\
942 padding is ignored if the output is wider than N;\n\
943 the default is to automatically pad if a whitespace\n\
947 --round=METHOD use METHOD for rounding when scaling; METHOD can be:\n\
948 up, down, from-zero (default), towards-zero, nearest\n\
951 --suffix=SUFFIX add SUFFIX to output numbers, and accept optional\n\
952 SUFFIX in input numbers\n\
955 --to=UNIT auto-scale output numbers to UNITs; see UNIT below\n\
958 --to-unit=N the output unit size (instead of the default 1)\n\
961 -z, --zero-terminated line delimiter is NUL, not newline\n\
963 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
964 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
968 UNIT options:\n"), stdout
);
970 none no auto-scaling is done; suffixes will trigger an error\n\
973 auto accept optional single/two letter suffix:\n\
977 1Mi = 1048576,\n"), stdout
);
979 si accept optional single letter suffix:\n\
984 iec accept optional single letter suffix:\n\
989 iec-i accept optional two-letter suffix:\n\
995 FIELDS supports cut(1) style field ranges:\n\
996 N N'th field, counted from 1\n\
997 N- from N'th field, to end of line\n\
998 N-M from N'th to M'th field (inclusive)\n\
999 -M from first to M'th field (inclusive)\n\
1001 Multiple fields/ranges can be separated with commas\n\
1005 FORMAT must be suitable for printing one floating-point argument '%f'.\n\
1006 Optional quote (%'f) will enable --grouping (if supported by current locale).\n\
1007 Optional width value (%10f) will pad output. Optional zero (%010f) width\n\
1008 will zero pad the number. Optional negative values (%-10f) will left align.\n\
1009 Optional precision (%.1f) will override the input determined precision.\n\
1013 Exit status is 0 if all input numbers were successfully converted.\n\
1014 By default, %s will stop at the first conversion error with exit status 2.\n\
1015 With --invalid='fail' a warning is printed for each conversion error\n\
1016 and the exit status is 2. With --invalid='warn' each conversion error is\n\
1017 diagnosed, but the exit status is 0. With --invalid='ignore' conversion\n\
1018 errors are not diagnosed and the exit status is 0.\n\
1023 $ %s --to=si 1000\n\
1025 $ %s --to=iec 2048\n\
1027 $ %s --to=iec-i 4096\n\
1029 $ echo 1K | %s --from=si\n\
1031 $ echo 1K | %s --from=iec\n\
1033 $ df -B1 | %s --header --field 2-4 --to=si\n\
1034 $ ls -l | %s --header --field 5 --to=iec\n\
1035 $ ls -lh | %s --header --field 5 --from=iec --padding=10\n\
1036 $ ls -lh | %s --header --field 5 --from=iec --format %%10f\n"),
1037 program_name
, program_name
, program_name
,
1038 program_name
, program_name
, program_name
,
1039 program_name
, program_name
, program_name
);
1040 emit_ancillary_info (PROGRAM_NAME
);
1045 /* Given 'fmt' (a printf(3) compatible format string), extracts the following:
1046 1. padding (e.g. %20f)
1047 2. alignment (e.g. %-20f)
1048 3. grouping (e.g. %'f)
1050 Only a limited subset of printf(3) syntax is supported.
1053 support %e %g etc. rather than just %f
1056 1. This function sets the global variables:
1057 padding_width, padding_alignment, grouping,
1058 format_str_prefix, format_str_suffix
1059 2. The function aborts on any errors. */
1061 parse_format_string (char const *fmt
)
1064 size_t prefix_len
= 0;
1067 char *endptr
= NULL
;
1068 bool zero_padding
= false;
1070 for (i
= 0; !(fmt
[i
] == '%' && fmt
[i
+ 1] != '%'); i
+= (fmt
[i
] == '%') + 1)
1073 die (EXIT_FAILURE
, 0,
1074 _("format %s has no %% directive"), quote (fmt
));
1081 size_t skip
= strspn (fmt
+ i
, " ");
1088 else if (fmt
[i
] == '0')
1090 zero_padding
= true;
1098 pad
= strtol (fmt
+ i
, &endptr
, 10);
1099 if (errno
== ERANGE
|| pad
< -LONG_MAX
)
1100 die (EXIT_FAILURE
, 0,
1101 _("invalid format %s (width overflow)"), quote (fmt
));
1103 if (endptr
!= (fmt
+ i
) && pad
!= 0)
1105 if (debug
&& padding_width
&& !(zero_padding
&& pad
> 0))
1106 error (0, 0, _("--format padding overriding --padding"));
1110 padding_alignment
= MBS_ALIGN_LEFT
;
1111 padding_width
= -pad
;
1116 zero_padding_width
= pad
;
1118 padding_width
= pad
;
1125 die (EXIT_FAILURE
, 0, _("format %s ends in %%"), quote (fmt
));
1131 user_precision
= strtol (fmt
+ i
, &endptr
, 10);
1132 if (errno
== ERANGE
|| user_precision
< 0 || SIZE_MAX
< user_precision
1133 || isblank (fmt
[i
]) || fmt
[i
] == '+')
1135 /* Note we disallow negative user_precision to be
1136 consistent with printf(1). POSIX states that
1137 negative precision is only supported (and ignored)
1138 when used with '.*f'. glibc at least will malform
1139 output when passed a direct negative precision. */
1140 die (EXIT_FAILURE
, 0,
1141 _("invalid precision in format %s"), quote (fmt
));
1147 die (EXIT_FAILURE
, 0, _("invalid format %s,"
1148 " directive must be %%[0]['][-][N][.][N]f"),
1153 for (; fmt
[i
] != '\0'; i
+= (fmt
[i
] == '%') + 1)
1154 if (fmt
[i
] == '%' && fmt
[i
+ 1] != '%')
1155 die (EXIT_FAILURE
, 0, _("format %s has too many %% directives"),
1159 format_str_prefix
= ximemdup0 (fmt
, prefix_len
);
1160 if (fmt
[suffix_pos
] != '\0')
1161 format_str_suffix
= xstrdup (fmt
+ suffix_pos
);
1163 devmsg ("format String:\n input: %s\n grouping: %s\n"
1164 " padding width: %ld\n alignment: %s\n"
1165 " prefix: %s\n suffix: %s\n",
1166 quote_n (0, fmt
), (grouping
) ? "yes" : "no",
1168 (padding_alignment
== MBS_ALIGN_LEFT
) ? "Left" : "Right",
1169 quote_n (1, format_str_prefix
? format_str_prefix
: ""),
1170 quote_n (2, format_str_suffix
? format_str_suffix
: ""));
1173 /* Parse a numeric value (with optional suffix) from a string.
1174 Returns a long double value, with input precision.
1176 If there's an error converting the string to value - exits with
1179 If there are any trailing characters after the number
1180 (besides a valid suffix) - exits with an error. */
1181 static enum simple_strtod_error
1182 parse_human_number (char const *str
, long double /*output */ *value
,
1187 enum simple_strtod_error e
=
1188 simple_strtod_human (str
, &ptr
, value
, precision
, scale_from
);
1189 if (e
!= SSE_OK
&& e
!= SSE_OK_PRECISION_LOSS
)
1191 simple_strtod_fatal (e
, str
);
1195 if (ptr
&& *ptr
!= '\0')
1197 if (inval_style
!= inval_ignore
)
1198 error (conv_exit_code
, 0, _("invalid suffix in input %s: %s"),
1199 quote_n (0, str
), quote_n (1, ptr
));
1200 e
= SSE_INVALID_SUFFIX
;
1206 /* Print the given VAL, using the requested representation.
1207 The number is printed to STDOUT, with padding and alignment. */
1209 prepare_padded_number (const long double val
, size_t precision
)
1211 /* Generate Output. */
1214 size_t precision_used
= user_precision
== -1 ? precision
: user_precision
;
1216 /* Can't reliably print too-large values without auto-scaling. */
1218 expld (val
, 10, &x
);
1220 if (scale_to
== scale_none
1221 && x
+ precision_used
> MAX_UNSCALED_DIGITS
)
1223 if (inval_style
!= inval_ignore
)
1226 error (conv_exit_code
, 0,
1227 _("value/precision too large to be printed: '%Lg/%"PRIuMAX
"'"
1228 " (consider using --to)"), val
, (uintmax_t)precision_used
);
1230 error (conv_exit_code
, 0,
1231 _("value too large to be printed: '%Lg'"
1232 " (consider using --to)"), val
);
1237 if (x
> MAX_ACCEPTABLE_DIGITS
- 1)
1239 if (inval_style
!= inval_ignore
)
1240 error (conv_exit_code
, 0, _("value too large to be printed: '%Lg'"
1241 " (cannot handle values > 999Q)"), val
);
1245 double_to_human (val
, precision_used
, buf
, sizeof (buf
),
1246 scale_to
, grouping
, round_style
);
1248 strncat (buf
, suffix
, sizeof (buf
) - strlen (buf
) -1);
1250 devmsg ("formatting output:\n value: %Lf\n humanized: %s\n",
1253 if (padding_width
&& strlen (buf
) < padding_width
)
1255 size_t w
= padding_width
;
1256 mbsalign (buf
, padding_buffer
, padding_buffer_size
, &w
,
1257 padding_alignment
, MBA_UNIBYTE_ONLY
);
1259 devmsg (" After padding: %s\n", quote (padding_buffer
));
1263 setup_padding_buffer (strlen (buf
) + 1);
1264 strcpy (padding_buffer
, buf
);
1271 print_padded_number (void)
1273 if (format_str_prefix
)
1274 fputs (format_str_prefix
, stdout
);
1276 fputs (padding_buffer
, stdout
);
1278 if (format_str_suffix
)
1279 fputs (format_str_suffix
, stdout
);
1282 /* Converts the TEXT number string to the requested representation,
1283 and handles automatic suffix addition. */
1285 process_suffixed_number (char *text
, long double *result
,
1286 size_t *precision
, long int field
)
1288 if (suffix
&& strlen (text
) > strlen (suffix
))
1290 char *possible_suffix
= text
+ strlen (text
) - strlen (suffix
);
1292 if (STREQ (suffix
, possible_suffix
))
1294 /* trim suffix, ONLY if it's at the end of the text. */
1295 *possible_suffix
= '\0';
1296 devmsg ("trimming suffix %s\n", quote (suffix
));
1299 devmsg ("no valid suffix found\n");
1302 /* Skip white space - always. */
1304 while (*p
&& isblank (to_uchar (*p
)))
1306 const unsigned int skip_count
= text
- p
;
1308 /* setup auto-padding. */
1311 if (skip_count
> 0 || field
> 1)
1313 padding_width
= strlen (text
);
1314 setup_padding_buffer (padding_width
);
1320 devmsg ("setting Auto-Padding to %ld characters\n", padding_width
);
1323 long double val
= 0;
1324 enum simple_strtod_error e
= parse_human_number (p
, &val
, precision
);
1325 if (e
== SSE_OK_PRECISION_LOSS
&& debug
)
1326 error (0, 0, _("large input value %s: possible precision loss"),
1329 if (from_unit_size
!= 1 || to_unit_size
!= 1)
1330 val
= (val
* from_unit_size
) / to_unit_size
;
1334 return (e
== SSE_OK
|| e
== SSE_OK_PRECISION_LOSS
);
1337 /* Return a pointer to the beginning of the next field in line.
1338 The line pointer is moved to the end of the next field. */
1340 next_field (char **line
)
1342 char *field_start
= *line
;
1343 char *field_end
= field_start
;
1345 if (delimiter
!= DELIMITER_DEFAULT
)
1347 if (*field_start
!= delimiter
)
1349 while (*field_end
&& *field_end
!= delimiter
)
1352 /* else empty field */
1356 /* keep any space prefix in the returned field */
1357 while (*field_end
&& field_sep (*field_end
))
1360 while (*field_end
&& ! field_sep (*field_end
))
1370 include_field (uintmax_t field
)
1372 struct field_range_pair
*p
= frp
;
1376 while (p
->lo
!= UINTMAX_MAX
)
1378 if (p
->lo
<= field
&& p
->hi
>= field
)
1385 /* Convert and output the given field. If it is not included in the set
1386 of fields to process just output the original */
1388 process_field (char *text
, uintmax_t field
)
1390 long double val
= 0;
1391 size_t precision
= 0;
1392 bool valid_number
= true;
1394 if (include_field (field
))
1397 process_suffixed_number (text
, &val
, &precision
, field
);
1400 valid_number
= prepare_padded_number (val
, precision
);
1403 print_padded_number ();
1405 fputs (text
, stdout
);
1408 fputs (text
, stdout
);
1410 return valid_number
;
1413 /* Convert number in a given line of text.
1414 NEWLINE specifies whether to output a '\n' for this "line". */
1416 process_line (char *line
, bool newline
)
1419 uintmax_t field
= 0;
1420 bool valid_number
= true;
1424 next
= next_field (&line
);
1428 /* nul terminate the current field string and process */
1431 if (! process_field (next
, field
))
1432 valid_number
= false;
1434 fputc ((delimiter
== DELIMITER_DEFAULT
) ?
1435 ' ' : delimiter
, stdout
);
1440 /* end of the line, process the last field and finish */
1441 if (! process_field (next
, field
))
1442 valid_number
= false;
1449 putchar (line_delim
);
1451 return valid_number
;
1455 main (int argc
, char **argv
)
1457 int valid_numbers
= 1;
1460 initialize_main (&argc
, &argv
);
1461 set_program_name (argv
[0]);
1462 locale_ok
= !!setlocale (LC_ALL
, "");
1463 bindtextdomain (PACKAGE
, LOCALEDIR
);
1464 textdomain (PACKAGE
);
1467 /* Enabled extended precision if needed. */
1471 decimal_point
= nl_langinfo (RADIXCHAR
);
1472 if (decimal_point
== NULL
|| strlen (decimal_point
) == 0)
1473 decimal_point
= ".";
1474 decimal_point_length
= strlen (decimal_point
);
1476 initialize_exit_failure (TIMEOUT_FAILURE
);
1477 atexit (close_stdout
);
1481 int c
= getopt_long (argc
, argv
, "d:z", longopts
, NULL
);
1489 scale_from
= XARGMATCH ("--from", optarg
,
1490 scale_from_args
, scale_from_types
);
1493 case FROM_UNIT_OPTION
:
1494 from_unit_size
= unit_to_umax (optarg
);
1499 XARGMATCH ("--to", optarg
, scale_to_args
, scale_to_types
);
1502 case TO_UNIT_OPTION
:
1503 to_unit_size
= unit_to_umax (optarg
);
1507 round_style
= XARGMATCH ("--round", optarg
, round_args
, round_types
);
1510 case GROUPING_OPTION
:
1514 case PADDING_OPTION
:
1515 if (xstrtol (optarg
, NULL
, 10, &padding_width
, "") != LONGINT_OK
1516 || padding_width
== 0 || padding_width
< -LONG_MAX
)
1517 die (EXIT_FAILURE
, 0, _("invalid padding value %s"),
1519 if (padding_width
< 0)
1521 padding_alignment
= MBS_ALIGN_LEFT
;
1522 padding_width
= -padding_width
;
1524 /* TODO: We probably want to apply a specific --padding
1525 to --header lines too. */
1530 die (EXIT_FAILURE
, 0, _("multiple field specifications"));
1531 set_fields (optarg
, SETFLD_ALLOW_DASH
);
1535 /* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */
1536 if (optarg
[0] != '\0' && optarg
[1] != '\0')
1537 die (EXIT_FAILURE
, 0,
1538 _("the delimiter must be a single character"));
1539 delimiter
= optarg
[0];
1554 case DEV_DEBUG_OPTION
:
1562 if (xstrtoumax (optarg
, NULL
, 10, &header
, "") != LONGINT_OK
1564 die (EXIT_FAILURE
, 0, _("invalid header value %s"),
1574 format_str
= optarg
;
1577 case INVALID_OPTION
:
1578 inval_style
= XARGMATCH ("--invalid", optarg
,
1579 inval_args
, inval_types
);
1582 case_GETOPT_HELP_CHAR
;
1583 case_GETOPT_VERSION_CHAR (PROGRAM_NAME
, AUTHORS
);
1586 usage (EXIT_FAILURE
);
1590 if (format_str
!= NULL
&& grouping
)
1591 die (EXIT_FAILURE
, 0, _("--grouping cannot be combined with --format"));
1593 if (debug
&& ! locale_ok
)
1594 error (0, 0, _("failed to set locale"));
1596 /* Warn about no-op. */
1597 if (debug
&& scale_from
== scale_none
&& scale_to
== scale_none
1598 && !grouping
&& (padding_width
== 0) && (format_str
== NULL
))
1599 error (0, 0, _("no conversion option specified"));
1602 parse_format_string (format_str
);
1606 if (scale_to
!= scale_none
)
1607 die (EXIT_FAILURE
, 0, _("grouping cannot be combined with --to"));
1608 if (debug
&& (strlen (nl_langinfo (THOUSEP
)) == 0))
1609 error (0, 0, _("grouping has no effect in this locale"));
1613 setup_padding_buffer (padding_width
);
1614 auto_padding
= (padding_width
== 0 && delimiter
== DELIMITER_DEFAULT
);
1616 if (inval_style
!= inval_abort
)
1621 if (debug
&& header
)
1622 error (0, 0, _("--header ignored with command-line input"));
1624 for (; optind
< argc
; optind
++)
1625 valid_numbers
&= process_line (argv
[optind
], true);
1630 size_t line_allocated
= 0;
1633 while (header
-- && getdelim (&line
, &line_allocated
,
1634 line_delim
, stdin
) > 0)
1635 fputs (line
, stdout
);
1637 while ((len
= getdelim (&line
, &line_allocated
,
1638 line_delim
, stdin
)) > 0)
1640 bool newline
= line
[len
- 1] == line_delim
;
1642 line
[len
- 1] = '\0';
1643 valid_numbers
&= process_line (line
, newline
);
1647 error (0, errno
, _("error reading input"));
1650 if (debug
&& !valid_numbers
)
1651 error (0, 0, _("failed to convert some of the input numbers"));
1653 int exit_status
= EXIT_SUCCESS
;
1655 && inval_style
!= inval_warn
&& inval_style
!= inval_ignore
)
1656 exit_status
= EXIT_CONVERSION_WARNINGS
;
1658 main_exit (exit_status
);