1 /* Reformat numbers like 11505426432 to the more human-readable 11G
2    Copyright (C) 2012-2023 Free Software Foundation, Inc.
3 
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.
8 
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.
13 
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/>.  */
16 
17 #include <config.h>
18 #include <float.h>
19 #include <getopt.h>
20 #include <stdckdint.h>
21 #include <stdio.h>
22 #include <sys/types.h>
23 #include <langinfo.h>
24 
25 #include "argmatch.h"
26 #include "c-ctype.h"
27 #include "mbswidth.h"
28 #include "quote.h"
29 #include "system.h"
30 #include "xstrtol.h"
31 
32 #include "set-fields.h"
33 
34 #if HAVE_FPSETPREC
35 # include <ieeefp.h>
36 #endif
37 
38 /* The official name of this program (e.g., no 'g' prefix).  */
39 #define PROGRAM_NAME "numfmt"
40 
41 #define AUTHORS proper_name ("Assaf Gordon")
42 
43 /* Exit code when some numbers fail to convert.  */
44 enum { EXIT_CONVERSION_WARNINGS = 2 };
45 
46 enum
47 {
48   FROM_OPTION = CHAR_MAX + 1,
49   FROM_UNIT_OPTION,
50   TO_OPTION,
51   TO_UNIT_OPTION,
52   ROUND_OPTION,
53   SUFFIX_OPTION,
54   GROUPING_OPTION,
55   PADDING_OPTION,
56   FIELD_OPTION,
57   DEBUG_OPTION,
58   DEV_DEBUG_OPTION,
59   HEADER_OPTION,
60   FORMAT_OPTION,
61   INVALID_OPTION
62 };
63 
64 enum scale_type
65 {
66   scale_none,                   /* the default: no scaling.  */
67   scale_auto,                   /* --from only.  */
68   scale_SI,
69   scale_IEC,
70   scale_IEC_I                   /* 'i' suffix is required.  */
71 };
72 
73 static char const *const scale_from_args[] =
74 {
75   "none", "auto", "si", "iec", "iec-i", nullptr
76 };
77 
78 static enum scale_type const scale_from_types[] =
79 {
80   scale_none, scale_auto, scale_SI, scale_IEC, scale_IEC_I
81 };
82 
83 static char const *const scale_to_args[] =
84 {
85   "none", "si", "iec", "iec-i", nullptr
86 };
87 
88 static enum scale_type const scale_to_types[] =
89 {
90   scale_none, scale_SI, scale_IEC, scale_IEC_I
91 };
92 
93 
94 enum round_type
95 {
96   round_ceiling,
97   round_floor,
98   round_from_zero,
99   round_to_zero,
100   round_nearest,
101 };
102 
103 static char const *const round_args[] =
104 {
105   "up", "down", "from-zero", "towards-zero", "nearest", nullptr
106 };
107 
108 static enum round_type const round_types[] =
109 {
110   round_ceiling, round_floor, round_from_zero, round_to_zero, round_nearest
111 };
112 
113 
114 enum inval_type
115 {
116   inval_abort,
117   inval_fail,
118   inval_warn,
119   inval_ignore
120 };
121 
122 static char const *const inval_args[] =
123 {
124   "abort", "fail", "warn", "ignore", nullptr
125 };
126 
127 static enum inval_type const inval_types[] =
128 {
129   inval_abort, inval_fail, inval_warn, inval_ignore
130 };
131 
132 static struct option const longopts[] =
133 {
134   {"from", required_argument, nullptr, FROM_OPTION},
135   {"from-unit", required_argument, nullptr, FROM_UNIT_OPTION},
136   {"to", required_argument, nullptr, TO_OPTION},
137   {"to-unit", required_argument, nullptr, TO_UNIT_OPTION},
138   {"round", required_argument, nullptr, ROUND_OPTION},
139   {"padding", required_argument, nullptr, PADDING_OPTION},
140   {"suffix", required_argument, nullptr, SUFFIX_OPTION},
141   {"grouping", no_argument, nullptr, GROUPING_OPTION},
142   {"delimiter", required_argument, nullptr, 'd'},
143   {"field", required_argument, nullptr, FIELD_OPTION},
144   {"debug", no_argument, nullptr, DEBUG_OPTION},
145   {"-debug", no_argument, nullptr, DEV_DEBUG_OPTION},
146   {"header", optional_argument, nullptr, HEADER_OPTION},
147   {"format", required_argument, nullptr, FORMAT_OPTION},
148   {"invalid", required_argument, nullptr, INVALID_OPTION},
149   {"zero-terminated", no_argument, nullptr, 'z'},
150   {GETOPT_HELP_OPTION_DECL},
151   {GETOPT_VERSION_OPTION_DECL},
152   {nullptr, 0, nullptr, 0}
153 };
154 
155 /* If delimiter has this value, blanks separate fields.  */
156 enum { DELIMITER_DEFAULT = CHAR_MAX + 1 };
157 
158 /* Maximum number of digits we can safely handle
159    without precision loss, if scaling is 'none'.  */
160 enum { MAX_UNSCALED_DIGITS = LDBL_DIG };
161 
162 /* Maximum number of digits we can work with.
163    This is equivalent to 999Q.
164    NOTE: 'long double' can handle more than that, but there's
165          no official suffix assigned beyond Quetta (1000^10).  */
166 enum { MAX_ACCEPTABLE_DIGITS = 33 };
167 
168 static enum scale_type scale_from = scale_none;
169 static enum scale_type scale_to = scale_none;
170 static enum round_type round_style = round_from_zero;
171 static enum inval_type inval_style = inval_abort;
172 static char const *suffix = nullptr;
173 static uintmax_t from_unit_size = 1;
174 static uintmax_t to_unit_size = 1;
175 static int grouping = 0;
176 static char *padding_buffer = nullptr;
177 static idx_t padding_buffer_size = 0;
178 static intmax_t padding_width = 0;
179 static int zero_padding_width = 0;
180 static long int user_precision = -1;
181 static char const *format_str = nullptr;
182 static char *format_str_prefix = nullptr;
183 static char *format_str_suffix = nullptr;
184 
185 /* By default, any conversion error will terminate the program.  */
186 static int conv_exit_code = EXIT_CONVERSION_WARNINGS;
187 
188 
189 /* auto-pad each line based on skipped whitespace.  */
190 static int auto_padding = 0;
191 
192 /* field delimiter */
193 static int delimiter = DELIMITER_DEFAULT;
194 
195 /* line delimiter.  */
196 static unsigned char line_delim = '\n';
197 
198 /* if non-zero, the first 'header' lines from STDIN are skipped.  */
199 static uintmax_t header = 0;
200 
201 /* Debug for users: print warnings to STDERR about possible
202    error (similar to sort's debug).  */
203 static bool debug;
204 
205 /* will be set according to the current locale.  */
206 static char const *decimal_point;
207 static int decimal_point_length;
208 
209 /* debugging for developers.  Enables devmsg().  */
210 static bool dev_debug = false;
211 
212 
213 static inline int
default_scale_base(enum scale_type scale)214 default_scale_base (enum scale_type scale)
215 {
216   switch (scale)
217     {
218     case scale_IEC:
219     case scale_IEC_I:
220       return 1024;
221 
222     case scale_none:
223     case scale_auto:
224     case scale_SI:
225     default:
226       return 1000;
227     }
228 }
229 
230 static char const zero_and_valid_suffixes[] = "0KMGTPEZYRQ";
231 static char const *valid_suffixes = 1 + zero_and_valid_suffixes;
232 
233 static inline bool
valid_suffix(const char suf)234 valid_suffix (const char suf)
235 {
236   return strchr (valid_suffixes, suf) != nullptr;
237 }
238 
239 static inline int
suffix_power(const char suf)240 suffix_power (const char suf)
241 {
242   switch (suf)
243     {
244     case 'K':                  /* kilo or kibi.  */
245       return 1;
246 
247     case 'M':                  /* mega or mebi.  */
248       return 2;
249 
250     case 'G':                  /* giga or gibi.  */
251       return 3;
252 
253     case 'T':                  /* tera or tebi.  */
254       return 4;
255 
256     case 'P':                  /* peta or pebi.  */
257       return 5;
258 
259     case 'E':                  /* exa or exbi.  */
260       return 6;
261 
262     case 'Z':                  /* zetta or 2**70.  */
263       return 7;
264 
265     case 'Y':                  /* yotta or 2**80.  */
266       return 8;
267 
268     case 'R':                  /* ronna or 2**90.  */
269       return 9;
270 
271     case 'Q':                  /* quetta or 2**100.  */
272       return 10;
273 
274     default:                   /* should never happen. assert?  */
275       return 0;
276     }
277 }
278 
279 static inline char const *
suffix_power_char(int power)280 suffix_power_char (int power)
281 {
282   switch (power)
283     {
284     case 0:
285       return "";
286 
287     case 1:
288       return "K";
289 
290     case 2:
291       return "M";
292 
293     case 3:
294       return "G";
295 
296     case 4:
297       return "T";
298 
299     case 5:
300       return "P";
301 
302     case 6:
303       return "E";
304 
305     case 7:
306       return "Z";
307 
308     case 8:
309       return "Y";
310 
311     case 9:
312       return "R";
313 
314     case 10:
315       return "Q";
316 
317     default:
318       return "(error)";
319     }
320 }
321 
322 /* Similar to 'powl(3)' but without requiring 'libm'.  */
323 static long double
powerld(long double base,int x)324 powerld (long double base, int x)
325 {
326   long double result = base;
327   if (x == 0)
328     return 1;                   /* note for test coverage: this is never
329                                    reached, as 'powerld' won't be called if
330                                    there's no suffix, hence, no "power".  */
331 
332   /* TODO: check for overflow, inf?  */
333   while (--x)
334     result *= base;
335   return result;
336 }
337 
338 /* Similar to 'fabs(3)' but without requiring 'libm'.  */
339 static inline long double
absld(long double val)340 absld (long double val)
341 {
342   return val < 0 ? -val : val;
343 }
344 
345 /* Scale down 'val', returns 'updated val' and 'x', such that
346      val*base^X = original val
347      Similar to "frexpl(3)" but without requiring 'libm',
348      allowing only integer scale, limited functionality and error checking.  */
349 static long double
expld(long double val,int base,int * x)350 expld (long double val, int base, int /*output */ *x)
351 {
352   int power = 0;
353 
354   if (val >= -LDBL_MAX && val <= LDBL_MAX)
355     {
356       while (absld (val) >= base)
357         {
358           ++power;
359           val /= base;
360         }
361     }
362   if (x)
363     *x = power;
364   return val;
365 }
366 
367 /* EXTREMELY limited 'ceil' - without 'libm'.
368    Assumes values that fit in intmax_t.  */
369 static inline intmax_t
simple_round_ceiling(long double val)370 simple_round_ceiling (long double val)
371 {
372   intmax_t intval = val;
373   if (intval < val)
374     intval++;
375   return intval;
376 }
377 
378 /* EXTREMELY limited 'floor' - without 'libm'.
379    Assumes values that fit in intmax_t.  */
380 static inline intmax_t
simple_round_floor(long double val)381 simple_round_floor (long double val)
382 {
383   return -simple_round_ceiling (-val);
384 }
385 
386 /* EXTREMELY limited 'round away from zero'.
387    Assumes values that fit in intmax_t.  */
388 static inline intmax_t
simple_round_from_zero(long double val)389 simple_round_from_zero (long double val)
390 {
391   return val < 0 ? simple_round_floor (val) : simple_round_ceiling (val);
392 }
393 
394 /* EXTREMELY limited 'round away to zero'.
395    Assumes values that fit in intmax_t.  */
396 static inline intmax_t
simple_round_to_zero(long double val)397 simple_round_to_zero (long double val)
398 {
399   return val;
400 }
401 
402 /* EXTREMELY limited 'round' - without 'libm'.
403    Assumes values that fit in intmax_t.  */
404 static inline intmax_t
simple_round_nearest(long double val)405 simple_round_nearest (long double val)
406 {
407   return val < 0 ? val - 0.5 : val + 0.5;
408 }
409 
410 ATTRIBUTE_CONST
411 static inline long double
simple_round(long double val,enum round_type t)412 simple_round (long double val, enum round_type t)
413 {
414   intmax_t rval;
415   intmax_t intmax_mul = val / INTMAX_MAX;
416   val -= (long double) INTMAX_MAX * intmax_mul;
417 
418   switch (t)
419     {
420     case round_ceiling:
421       rval = simple_round_ceiling (val);
422       break;
423 
424     case round_floor:
425       rval = simple_round_floor (val);
426       break;
427 
428     case round_from_zero:
429       rval = simple_round_from_zero (val);
430       break;
431 
432     case round_to_zero:
433       rval = simple_round_to_zero (val);
434       break;
435 
436     case round_nearest:
437       rval = simple_round_nearest (val);
438       break;
439 
440     default:
441       /* to silence the compiler - this should never happen.  */
442       return 0;
443     }
444 
445   return (long double) INTMAX_MAX * intmax_mul + rval;
446 }
447 
448 enum simple_strtod_error
449 {
450   SSE_OK = 0,
451   SSE_OK_PRECISION_LOSS,
452   SSE_OVERFLOW,
453   SSE_INVALID_NUMBER,
454 
455   /* the following are returned by 'simple_strtod_human'.  */
456   SSE_VALID_BUT_FORBIDDEN_SUFFIX,
457   SSE_INVALID_SUFFIX,
458   SSE_MISSING_I_SUFFIX
459 };
460 
461 /* Read an *integer* INPUT_STR,
462    but return the integer value in a 'long double' VALUE
463    hence, no UINTMAX_MAX limitation.
464    NEGATIVE is updated, and is stored separately from the VALUE
465    so that signbit() isn't required to determine the sign of -0..
466    ENDPTR is required (unlike strtod) and is used to store a pointer
467    to the character after the last character used in the conversion.
468 
469    Note locale'd grouping is not supported,
470    nor is skipping of white-space supported.
471 
472    Returns:
473       SSE_OK - valid number.
474       SSE_OK_PRECISION_LOSS - if more than 18 digits were used.
475       SSE_OVERFLOW          - if more than 33 digits (999Q) were used.
476       SSE_INVALID_NUMBER    - if no digits were found.  */
477 static enum simple_strtod_error
simple_strtod_int(char const * input_str,char ** endptr,long double * value,bool * negative)478 simple_strtod_int (char const *input_str,
479                    char **endptr, long double *value, bool *negative)
480 {
481   enum simple_strtod_error e = SSE_OK;
482 
483   long double val = 0;
484   int digits = 0;
485   bool found_digit = false;
486 
487   if (*input_str == '-')
488     {
489       input_str++;
490       *negative = true;
491     }
492   else
493     *negative = false;
494 
495   *endptr = (char *) input_str;
496   while (c_isdigit (**endptr))
497     {
498       int digit = (**endptr) - '0';
499 
500       found_digit = true;
501 
502       if (val || digit)
503         digits++;
504 
505       if (digits > MAX_UNSCALED_DIGITS)
506         e = SSE_OK_PRECISION_LOSS;
507 
508       if (digits > MAX_ACCEPTABLE_DIGITS)
509         return SSE_OVERFLOW;
510 
511       val *= 10;
512       val += digit;
513 
514       ++(*endptr);
515     }
516   if (! found_digit
517       && ! STREQ_LEN (*endptr, decimal_point, decimal_point_length))
518     return SSE_INVALID_NUMBER;
519   if (*negative)
520     val = -val;
521 
522   if (value)
523     *value = val;
524 
525   return e;
526 }
527 
528 /* Read a floating-point INPUT_STR represented as "NNNN[.NNNNN]",
529    and return the value in a 'long double' VALUE.
530    ENDPTR is required (unlike strtod) and is used to store a pointer
531    to the character after the last character used in the conversion.
532    PRECISION is optional and used to indicate fractions are present.
533 
534    Note locale'd grouping is not supported,
535    nor is skipping of white-space supported.
536 
537    Returns:
538       SSE_OK - valid number.
539       SSE_OK_PRECISION_LOSS - if more than 18 digits were used.
540       SSE_OVERFLOW          - if more than 33 digits (999Q) were used.
541       SSE_INVALID_NUMBER    - if no digits were found.  */
542 static enum simple_strtod_error
simple_strtod_float(char const * input_str,char ** endptr,long double * value,size_t * precision)543 simple_strtod_float (char const *input_str,
544                      char **endptr,
545                      long double *value,
546                      size_t *precision)
547 {
548   bool negative;
549   enum simple_strtod_error e = SSE_OK;
550 
551   if (precision)
552     *precision = 0;
553 
554   /* TODO: accept locale'd grouped values for the integral part.  */
555   e = simple_strtod_int (input_str, endptr, value, &negative);
556   if (e != SSE_OK && e != SSE_OK_PRECISION_LOSS)
557     return e;
558 
559   /* optional decimal point + fraction.  */
560   if (STREQ_LEN (*endptr, decimal_point, decimal_point_length))
561     {
562       char *ptr2;
563       long double val_frac = 0;
564       bool neg_frac;
565 
566       (*endptr) += decimal_point_length;
567       enum simple_strtod_error e2 =
568         simple_strtod_int (*endptr, &ptr2, &val_frac, &neg_frac);
569       if (e2 != SSE_OK && e2 != SSE_OK_PRECISION_LOSS)
570         return e2;
571       if (e2 == SSE_OK_PRECISION_LOSS)
572         e = e2;                       /* propagate warning.  */
573       if (neg_frac)
574         return SSE_INVALID_NUMBER;
575 
576       /* number of digits in the fractions.  */
577       size_t exponent = ptr2 - *endptr;
578 
579       val_frac = ((long double) val_frac) / powerld (10, exponent);
580 
581       /* TODO: detect loss of precision (only really 18 digits
582          of precision across all digits (before and after '.')).  */
583       if (value)
584         {
585           if (negative)
586             *value -= val_frac;
587           else
588             *value += val_frac;
589         }
590 
591       if (precision)
592         *precision = exponent;
593 
594       *endptr = ptr2;
595     }
596   return e;
597 }
598 
599 /* Read a 'human' INPUT_STR represented as "NNNN[.NNNNN] + suffix",
600    and return the value in a 'long double' VALUE,
601    with the precision of the input returned in PRECISION.
602    ENDPTR is required (unlike strtod) and is used to store a pointer
603    to the character after the last character used in the conversion.
604    ALLOWED_SCALING determines the scaling supported.
605 
606    TODO:
607      support locale'd grouping
608      accept scientific and hex floats (probably use strtold directly)
609 
610    Returns:
611       SSE_OK - valid number.
612       SSE_OK_PRECISION_LOSS - if more than LDBL_DIG digits were used.
613       SSE_OVERFLOW          - if more than 33 digits (999Q) were used.
614       SSE_INVALID_NUMBER    - if no digits were found.
615       SSE_VALID_BUT_FORBIDDEN_SUFFIX
616       SSE_INVALID_SUFFIX
617       SSE_MISSING_I_SUFFIX  */
618 static enum simple_strtod_error
simple_strtod_human(char const * input_str,char ** endptr,long double * value,size_t * precision,enum scale_type allowed_scaling)619 simple_strtod_human (char const *input_str,
620                      char **endptr, long double *value, size_t *precision,
621                      enum scale_type allowed_scaling)
622 {
623   int power = 0;
624   /* 'scale_auto' is checked below.  */
625   int scale_base = default_scale_base (allowed_scaling);
626 
627   devmsg ("simple_strtod_human:\n  input string: %s\n"
628           "  locale decimal-point: %s\n"
629           "  MAX_UNSCALED_DIGITS: %d\n",
630           quote_n (0, input_str),
631           quote_n (1, decimal_point),
632           MAX_UNSCALED_DIGITS);
633 
634   enum simple_strtod_error e =
635     simple_strtod_float (input_str, endptr, value, precision);
636   if (e != SSE_OK && e != SSE_OK_PRECISION_LOSS)
637     return e;
638 
639   devmsg ("  parsed numeric value: %Lf\n"
640           "  input precision = %d\n", *value, (int)*precision);
641 
642   if (**endptr != '\0')
643     {
644       /* process suffix.  */
645 
646       /* Skip any blanks between the number and suffix.  */
647       while (isblank (to_uchar (**endptr)))
648         (*endptr)++;
649 
650       if (!valid_suffix (**endptr))
651         return SSE_INVALID_SUFFIX;
652 
653       if (allowed_scaling == scale_none)
654         return SSE_VALID_BUT_FORBIDDEN_SUFFIX;
655 
656       power = suffix_power (**endptr);
657       (*endptr)++;                     /* skip first suffix character.  */
658 
659       if (allowed_scaling == scale_auto && **endptr == 'i')
660         {
661           /* auto-scaling enabled, and the first suffix character
662               is followed by an 'i' (e.g. Ki, Mi, Gi).  */
663           scale_base = 1024;
664           (*endptr)++;              /* skip second  ('i') suffix character.  */
665           devmsg ("  Auto-scaling, found 'i', switching to base %d\n",
666                   scale_base);
667         }
668 
669       *precision = 0;  /* Reset, to select precision based on scale.  */
670     }
671 
672   if (allowed_scaling == scale_IEC_I)
673     {
674       if (**endptr == 'i')
675         (*endptr)++;
676       else
677         return SSE_MISSING_I_SUFFIX;
678     }
679 
680   long double multiplier = powerld (scale_base, power);
681 
682   devmsg ("  suffix power=%d^%d = %Lf\n", scale_base, power, multiplier);
683 
684   /* TODO: detect loss of precision and overflows.  */
685   (*value) = (*value) * multiplier;
686 
687   devmsg ("  returning value: %Lf (%LG)\n", *value, *value);
688 
689   return e;
690 }
691 
692 
693 static void
simple_strtod_fatal(enum simple_strtod_error err,char const * input_str)694 simple_strtod_fatal (enum simple_strtod_error err, char const *input_str)
695 {
696   char const *msgid = nullptr;
697 
698   switch (err)
699     {
700     case SSE_OK_PRECISION_LOSS:
701     case SSE_OK:
702       /* should never happen - this function isn't called when OK.  */
703       unreachable ();
704 
705     case SSE_OVERFLOW:
706       msgid = N_("value too large to be converted: %s");
707       break;
708 
709     case SSE_INVALID_NUMBER:
710       msgid = N_("invalid number: %s");
711       break;
712 
713     case SSE_VALID_BUT_FORBIDDEN_SUFFIX:
714       msgid = N_("rejecting suffix in input: %s (consider using --from)");
715       break;
716 
717     case SSE_INVALID_SUFFIX:
718       msgid = N_("invalid suffix in input: %s");
719       break;
720 
721     case SSE_MISSING_I_SUFFIX:
722       msgid = N_("missing 'i' suffix in input: %s (e.g Ki/Mi/Gi)");
723       break;
724 
725     }
726 
727   if (inval_style != inval_ignore)
728     error (conv_exit_code, 0, gettext (msgid), quote (input_str));
729 }
730 
731 /* Convert VAL to a human format string using PRECISION in BUF of size
732    BUF_SIZE.  Use SCALE, GROUP, and ROUND to format.  Return
733    the number of bytes needed to represent VAL.  If this number is not
734    less than BUF_SIZE, the buffer is too small; if it is negative, the
735    formatting failed for some reason.  */
736 static int
double_to_human(long double val,int precision,char * buf,idx_t buf_size,enum scale_type scale,int group,enum round_type round)737 double_to_human (long double val, int precision,
738                  char *buf, idx_t buf_size,
739                  enum scale_type scale, int group, enum round_type round)
740 {
741   char fmt[sizeof "%'0.*Lfi%s%s%s" + INT_STRLEN_BOUND (zero_padding_width)];
742   char *pfmt = fmt;
743   *pfmt++ = '%';
744 
745   if (group)
746     *pfmt++ = '\'';
747 
748   if (zero_padding_width)
749     pfmt += sprintf (pfmt, "0%d", zero_padding_width);
750 
751   devmsg ("double_to_human:\n");
752 
753   if (scale == scale_none)
754     {
755       val *= powerld (10, precision);
756       val = simple_round (val, round);
757       val /= powerld (10, precision);
758 
759       devmsg ((group) ?
760               "  no scaling, returning (grouped) value: %'.*Lf\n" :
761               "  no scaling, returning value: %.*Lf\n", precision, val);
762 
763       strcpy (pfmt, ".*Lf%s");
764 
765       return snprintf (buf, buf_size, fmt, precision, val,
766                        suffix ? suffix : "");
767     }
768 
769   /* Scaling requested by user. */
770   double scale_base = default_scale_base (scale);
771 
772   /* Normalize val to scale. */
773   int power = 0;
774   val = expld (val, scale_base, &power);
775   devmsg ("  scaled value to %Lf * %0.f ^ %d\n", val, scale_base, power);
776 
777   /* Perform rounding. */
778   int power_adjust = 0;
779   if (user_precision != -1)
780     power_adjust = MIN (power * 3, user_precision);
781   else if (absld (val) < 10)
782     {
783       /* for values less than 10, we allow one decimal-point digit,
784          so adjust before rounding. */
785       power_adjust = 1;
786     }
787 
788   val *= powerld (10, power_adjust);
789   val = simple_round (val, round);
790   val /= powerld (10, power_adjust);
791 
792   /* two special cases after rounding:
793      1. a "999.99" can turn into 1000 - so scale down
794      2. a "9.99" can turn into 10 - so don't display decimal-point.  */
795   if (absld (val) >= scale_base)
796     {
797       val /= scale_base;
798       power++;
799     }
800 
801   /* should "7.0" be printed as "7" ?
802      if removing the ".0" is preferred, enable the fourth condition.  */
803   int show_decimal_point = (val != 0) && (absld (val) < 10) && (power > 0);
804   /* && (absld (val) > simple_round_floor (val))) */
805 
806   devmsg ("  after rounding, value=%Lf * %0.f ^ %d\n", val, scale_base, power);
807 
808   strcpy (pfmt, ".*Lf%s%s%s");
809 
810   int prec = user_precision == -1 ? show_decimal_point : user_precision;
811 
812   return snprintf (buf, buf_size, fmt, prec, val,
813                    suffix_power_char (power),
814                    &"i"[! (scale == scale_IEC_I && 0 < power)],
815                    suffix ? suffix : "");
816 }
817 
818 /* Convert a string of decimal digits, N_STRING, with an optional suffix
819    to an integral value.  Suffixes are handled as with --from=auto.
820    Upon successful conversion, return that value.
821    If it cannot be converted, give a diagnostic and exit.  */
822 static uintmax_t
unit_to_umax(char const * n_string)823 unit_to_umax (char const *n_string)
824 {
825   strtol_error s_err;
826   char const *c_string = n_string;
827   char *t_string = nullptr;
828   size_t n_len = strlen (n_string);
829   char *end = nullptr;
830   uintmax_t n;
831   char const *suffixes = valid_suffixes;
832 
833   /* Adjust suffixes so K=1000, Ki=1024, KiB=invalid.  */
834   if (n_len && ! c_isdigit (n_string[n_len - 1]))
835     {
836       t_string = xmalloc (n_len + 2);
837       end = t_string + n_len - 1;
838       memcpy (t_string, n_string, n_len);
839 
840       if (*end == 'i' && 2 <= n_len && ! c_isdigit (*(end - 1)))
841         *end = '\0';
842       else
843         {
844           *++end = 'B';
845           *++end = '\0';
846           suffixes = zero_and_valid_suffixes;
847         }
848 
849       c_string = t_string;
850     }
851 
852   s_err = xstrtoumax (c_string, &end, 10, &n, suffixes);
853 
854   if (s_err != LONGINT_OK || *end || n == 0)
855     {
856       free (t_string);
857       error (EXIT_FAILURE, 0, _("invalid unit size: %s"), quote (n_string));
858     }
859 
860   free (t_string);
861 
862   return n;
863 }
864 
865 void
usage(int status)866 usage (int status)
867 {
868   if (status != EXIT_SUCCESS)
869     emit_try_help ();
870   else
871     {
872       printf (_("\
873 Usage: %s [OPTION]... [NUMBER]...\n\
874 "), program_name);
875       fputs (_("\
876 Reformat NUMBER(s), or the numbers from standard input if none are specified.\n\
877 "), stdout);
878       emit_mandatory_arg_note ();
879       fputs (_("\
880       --debug          print warnings about invalid input\n\
881 "), stdout);
882       fputs (_("\
883   -d, --delimiter=X    use X instead of whitespace for field delimiter\n\
884 "), stdout);
885       fputs (_("\
886       --field=FIELDS   replace the numbers in these input fields (default=1);\n\
887                          see FIELDS below\n\
888 "), stdout);
889       fputs (_("\
890       --format=FORMAT  use printf style floating-point FORMAT;\n\
891                          see FORMAT below for details\n\
892 "), stdout);
893       fputs (_("\
894       --from=UNIT      auto-scale input numbers to UNITs; default is 'none';\n\
895                          see UNIT below\n\
896 "), stdout);
897       fputs (_("\
898       --from-unit=N    specify the input unit size (instead of the default 1)\n\
899 "), stdout);
900       fputs (_("\
901       --grouping       use locale-defined grouping of digits, e.g. 1,000,000\n\
902                          (which means it has no effect in the C/POSIX locale)\n\
903 "), stdout);
904       fputs (_("\
905       --header[=N]     print (without converting) the first N header lines;\n\
906                          N defaults to 1 if not specified\n\
907 "), stdout);
908       fputs (_("\
909       --invalid=MODE   failure mode for invalid numbers: MODE can be:\n\
910                          abort (default), fail, warn, ignore\n\
911 "), stdout);
912       fputs (_("\
913       --padding=N      pad the output to N characters; positive N will\n\
914                          right-align; negative N will left-align;\n\
915                          padding is ignored if the output is wider than N;\n\
916                          the default is to automatically pad if a whitespace\n\
917                          is found\n\
918 "), stdout);
919       fputs (_("\
920       --round=METHOD   use METHOD for rounding when scaling; METHOD can be:\n\
921                          up, down, from-zero (default), towards-zero, nearest\n\
922 "), stdout);
923       fputs (_("\
924       --suffix=SUFFIX  add SUFFIX to output numbers, and accept optional\n\
925                          SUFFIX in input numbers\n\
926 "), stdout);
927       fputs (_("\
928       --to=UNIT        auto-scale output numbers to UNITs; see UNIT below\n\
929 "), stdout);
930       fputs (_("\
931       --to-unit=N      the output unit size (instead of the default 1)\n\
932 "), stdout);
933       fputs (_("\
934   -z, --zero-terminated    line delimiter is NUL, not newline\n\
935 "), stdout);
936       fputs (HELP_OPTION_DESCRIPTION, stdout);
937       fputs (VERSION_OPTION_DESCRIPTION, stdout);
938 
939       fputs (_("\
940 \n\
941 UNIT options:\n"), stdout);
942       fputs (_("\
943   none       no auto-scaling is done; suffixes will trigger an error\n\
944 "), stdout);
945       fputs (_("\
946   auto       accept optional single/two letter suffix:\n\
947                1K = 1000,\n\
948                1Ki = 1024,\n\
949                1M = 1000000,\n\
950                1Mi = 1048576,\n"), stdout);
951       fputs (_("\
952   si         accept optional single letter suffix:\n\
953                1K = 1000,\n\
954                1M = 1000000,\n\
955                ...\n"), stdout);
956       fputs (_("\
957   iec        accept optional single letter suffix:\n\
958                1K = 1024,\n\
959                1M = 1048576,\n\
960                ...\n"), stdout);
961       fputs (_("\
962   iec-i      accept optional two-letter suffix:\n\
963                1Ki = 1024,\n\
964                1Mi = 1048576,\n\
965                ...\n"), stdout);
966 
967       fputs (_("\n\
968 FIELDS supports cut(1) style field ranges:\n\
969   N    N'th field, counted from 1\n\
970   N-   from N'th field, to end of line\n\
971   N-M  from N'th to M'th field (inclusive)\n\
972   -M   from first to M'th field (inclusive)\n\
973   -    all fields\n\
974 Multiple fields/ranges can be separated with commas\n\
975 "), stdout);
976 
977       fputs (_("\n\
978 FORMAT must be suitable for printing one floating-point argument '%f'.\n\
979 Optional quote (%'f) will enable --grouping (if supported by current locale).\n\
980 Optional width value (%10f) will pad output. Optional zero (%010f) width\n\
981 will zero pad the number. Optional negative values (%-10f) will left align.\n\
982 Optional precision (%.1f) will override the input determined precision.\n\
983 "), stdout);
984 
985       printf (_("\n\
986 Exit status is 0 if all input numbers were successfully converted.\n\
987 By default, %s will stop at the first conversion error with exit status 2.\n\
988 With --invalid='fail' a warning is printed for each conversion error\n\
989 and the exit status is 2.  With --invalid='warn' each conversion error is\n\
990 diagnosed, but the exit status is 0.  With --invalid='ignore' conversion\n\
991 errors are not diagnosed and the exit status is 0.\n\
992 "), program_name);
993 
994       printf (_("\n\
995 Examples:\n\
996   $ %s --to=si 1000\n\
997             -> \"1.0K\"\n\
998   $ %s --to=iec 2048\n\
999            -> \"2.0K\"\n\
1000   $ %s --to=iec-i 4096\n\
1001            -> \"4.0Ki\"\n\
1002   $ echo 1K | %s --from=si\n\
1003            -> \"1000\"\n\
1004   $ echo 1K | %s --from=iec\n\
1005            -> \"1024\"\n\
1006   $ df -B1 | %s --header --field 2-4 --to=si\n\
1007   $ ls -l  | %s --header --field 5 --to=iec\n\
1008   $ ls -lh | %s --header --field 5 --from=iec --padding=10\n\
1009   $ ls -lh | %s --header --field 5 --from=iec --format %%10f\n"),
1010               program_name, program_name, program_name,
1011               program_name, program_name, program_name,
1012               program_name, program_name, program_name);
1013       emit_ancillary_info (PROGRAM_NAME);
1014     }
1015   exit (status);
1016 }
1017 
1018 /* Given 'fmt' (a printf(3) compatible format string), extracts the following:
1019     1. padding (e.g. %20f)
1020     2. alignment (e.g. %-20f)
1021     3. grouping (e.g. %'f)
1022 
1023    Only a limited subset of printf(3) syntax is supported.
1024 
1025    TODO:
1026      support %e %g etc. rather than just %f
1027 
1028    NOTES:
1029    1. This function sets the global variables:
1030        padding_width, grouping,
1031        format_str_prefix, format_str_suffix
1032    2. The function aborts on any errors.  */
1033 static void
parse_format_string(char const * fmt)1034 parse_format_string (char const *fmt)
1035 {
1036   size_t i;
1037   size_t prefix_len = 0;
1038   size_t suffix_pos;
1039   char *endptr = nullptr;
1040   bool zero_padding = false;
1041 
1042   for (i = 0; !(fmt[i] == '%' && fmt[i + 1] != '%'); i += (fmt[i] == '%') + 1)
1043     {
1044       if (!fmt[i])
1045         error (EXIT_FAILURE, 0,
1046                _("format %s has no %% directive"), quote (fmt));
1047       prefix_len++;
1048     }
1049 
1050   i++;
1051   while (true)
1052     {
1053       size_t skip = strspn (fmt + i, " ");
1054       i += skip;
1055       if (fmt[i] == '\'')
1056         {
1057           grouping = 1;
1058           i++;
1059         }
1060       else if (fmt[i] == '0')
1061         {
1062           zero_padding = true;
1063           i++;
1064         }
1065       else if (! skip)
1066         break;
1067     }
1068 
1069   intmax_t pad = strtoimax (fmt + i, &endptr, 10);
1070 
1071   if (pad != 0)
1072     {
1073       if (debug && padding_width && !(zero_padding && pad > 0))
1074         error (0, 0, _("--format padding overriding --padding"));
1075 
1076       /* Set padding width and alignment.  On overflow, set widths to
1077          large values that cause later code to avoid undefined behavior
1078          and fail at a reasonable point.  */
1079       if (pad < 0)
1080         padding_width = pad;
1081       else
1082         {
1083           if (zero_padding)
1084             zero_padding_width = MIN (pad, INT_MAX);
1085           else
1086             padding_width = pad;
1087         }
1088     }
1089   i = endptr - fmt;
1090 
1091   if (fmt[i] == '\0')
1092     error (EXIT_FAILURE, 0, _("format %s ends in %%"), quote (fmt));
1093 
1094   if (fmt[i] == '.')
1095     {
1096       i++;
1097       errno = 0;
1098       user_precision = strtol (fmt + i, &endptr, 10);
1099       if (errno == ERANGE || user_precision < 0 || SIZE_MAX < user_precision
1100           || isblank (fmt[i]) || fmt[i] == '+')
1101         {
1102           /* Note we disallow negative user_precision to be
1103              consistent with printf(1).  POSIX states that
1104              negative precision is only supported (and ignored)
1105              when used with '.*f'.  glibc at least will malform
1106              output when passed a direct negative precision.  */
1107           error (EXIT_FAILURE, 0,
1108                  _("invalid precision in format %s"), quote (fmt));
1109         }
1110       i = endptr - fmt;
1111     }
1112 
1113   if (fmt[i] != 'f')
1114     error (EXIT_FAILURE, 0, _("invalid format %s,"
1115                               " directive must be %%[0]['][-][N][.][N]f"),
1116          quote (fmt));
1117   i++;
1118   suffix_pos = i;
1119 
1120   for (; fmt[i] != '\0'; i += (fmt[i] == '%') + 1)
1121     if (fmt[i] == '%' && fmt[i + 1] != '%')
1122       error (EXIT_FAILURE, 0, _("format %s has too many %% directives"),
1123              quote (fmt));
1124 
1125   if (prefix_len)
1126     format_str_prefix = ximemdup0 (fmt, prefix_len);
1127   if (fmt[suffix_pos] != '\0')
1128     format_str_suffix = xstrdup (fmt + suffix_pos);
1129 
1130   devmsg ("format String:\n  input: %s\n  grouping: %s\n"
1131                    "  padding width: %jd\n"
1132                    "  prefix: %s\n  suffix: %s\n",
1133           quote_n (0, fmt), (grouping) ? "yes" : "no",
1134           padding_width,
1135           quote_n (1, format_str_prefix ? format_str_prefix : ""),
1136           quote_n (2, format_str_suffix ? format_str_suffix : ""));
1137 }
1138 
1139 /* Parse a numeric value (with optional suffix) from a string.
1140    Returns a long double value, with input precision.
1141 
1142    If there's an error converting the string to value - exits with
1143    an error.
1144 
1145    If there are any trailing characters after the number
1146    (besides a valid suffix) - exits with an error.  */
1147 static enum simple_strtod_error
parse_human_number(char const * str,long double * value,size_t * precision)1148 parse_human_number (char const *str, long double /*output */ *value,
1149                     size_t *precision)
1150 {
1151   char *ptr = nullptr;
1152 
1153   enum simple_strtod_error e =
1154     simple_strtod_human (str, &ptr, value, precision, scale_from);
1155   if (e != SSE_OK && e != SSE_OK_PRECISION_LOSS)
1156     {
1157       simple_strtod_fatal (e, str);
1158       return e;
1159     }
1160 
1161   if (ptr && *ptr != '\0')
1162     {
1163       if (inval_style != inval_ignore)
1164         error (conv_exit_code, 0, _("invalid suffix in input %s: %s"),
1165                quote_n (0, str), quote_n (1, ptr));
1166       e = SSE_INVALID_SUFFIX;
1167     }
1168   return e;
1169 }
1170 
1171 
1172 /* Print the given VAL, using the requested representation.
1173    The number is printed to STDOUT, with padding and alignment.  */
1174 static bool
prepare_padded_number(const long double val,size_t precision,intmax_t * padding)1175 prepare_padded_number (const long double val, size_t precision,
1176                        intmax_t *padding)
1177 {
1178   /* Generate Output. */
1179   size_t precision_used = user_precision == -1 ? precision : user_precision;
1180 
1181   /* Can't reliably print too-large values without auto-scaling. */
1182   int x;
1183   expld (val, 10, &x);
1184 
1185   if (scale_to == scale_none
1186       && x + precision_used > MAX_UNSCALED_DIGITS)
1187     {
1188       if (inval_style != inval_ignore)
1189         {
1190           if (precision_used)
1191             error (conv_exit_code, 0,
1192                    _("value/precision too large to be printed: '%Lg/%zu'"
1193                      " (consider using --to)"), val, precision_used);
1194           else
1195             error (conv_exit_code, 0,
1196                    _("value too large to be printed: '%Lg'"
1197                      " (consider using --to)"), val);
1198         }
1199       return false;
1200     }
1201 
1202   if (x > MAX_ACCEPTABLE_DIGITS - 1)
1203     {
1204       if (inval_style != inval_ignore)
1205         error (conv_exit_code, 0, _("value too large to be printed: '%Lg'"
1206                                     " (cannot handle values > 999Q)"), val);
1207       return false;
1208     }
1209 
1210   while (true)
1211     {
1212       int numlen = double_to_human (val, precision_used,
1213                                     padding_buffer, padding_buffer_size,
1214                                     scale_to, grouping, round_style);
1215       ptrdiff_t growth;
1216       if (numlen < 0 || ckd_sub (&growth, numlen, padding_buffer_size - 1))
1217         error (EXIT_FAILURE, 0,
1218                _("failed to prepare value '%Lf' for printing"), val);
1219       if (growth <= 0)
1220         break;
1221       padding_buffer = xpalloc (padding_buffer, &padding_buffer_size,
1222                                 growth, -1, 1);
1223     }
1224 
1225   devmsg ("formatting output:\n  value: %Lf\n  humanized: %s\n",
1226           val, quote (padding_buffer));
1227 
1228   intmax_t pad = 0;
1229   if (padding_width)
1230     {
1231       int buf_width = mbswidth (padding_buffer,
1232                                 MBSW_REJECT_INVALID | MBSW_REJECT_UNPRINTABLE);
1233       if (0 <= buf_width)
1234         {
1235           if (padding_width < 0)
1236             {
1237               if (padding_width < -buf_width)
1238                 pad = padding_width + buf_width;
1239             }
1240           else
1241             {
1242               if (buf_width < padding_width)
1243                 pad = padding_width - buf_width;
1244             }
1245         }
1246     }
1247 
1248   *padding = pad;
1249   return true;
1250 }
1251 
1252 static void
print_padded_number(intmax_t padding)1253 print_padded_number (intmax_t padding)
1254 {
1255   if (format_str_prefix)
1256     fputs (format_str_prefix, stdout);
1257 
1258   for (intmax_t p = padding; 0 < p; p--)
1259     putchar (' ');
1260 
1261   fputs (padding_buffer, stdout);
1262 
1263   for (intmax_t p = padding; p < 0; p++)
1264     putchar (' ');
1265 
1266   if (format_str_suffix)
1267     fputs (format_str_suffix, stdout);
1268 }
1269 
1270 /* Converts the TEXT number string to the requested representation,
1271    and handles automatic suffix addition.  */
1272 static int
process_suffixed_number(char * text,long double * result,size_t * precision,long int field)1273 process_suffixed_number (char *text, long double *result,
1274                          size_t *precision, long int field)
1275 {
1276   if (suffix && strlen (text) > strlen (suffix))
1277     {
1278       char *possible_suffix = text + strlen (text) - strlen (suffix);
1279 
1280       if (STREQ (suffix, possible_suffix))
1281         {
1282           /* trim suffix, ONLY if it's at the end of the text.  */
1283           *possible_suffix = '\0';
1284           devmsg ("trimming suffix %s\n", quote (suffix));
1285         }
1286       else
1287         devmsg ("no valid suffix found\n");
1288     }
1289 
1290   /* Skip white space - always.  */
1291   char *p = text;
1292   while (*p && isblank (to_uchar (*p)))
1293     ++p;
1294 
1295   /* setup auto-padding.  */
1296   if (auto_padding)
1297     {
1298       padding_width = text < p || 1 < field ? strlen (text) : 0;
1299       devmsg ("setting Auto-Padding to %jd characters\n", padding_width);
1300     }
1301 
1302   long double val = 0;
1303   enum simple_strtod_error e = parse_human_number (p, &val, precision);
1304   if (e == SSE_OK_PRECISION_LOSS && debug)
1305     error (0, 0, _("large input value %s: possible precision loss"),
1306            quote (p));
1307 
1308   if (from_unit_size != 1 || to_unit_size != 1)
1309     val = (val * from_unit_size) / to_unit_size;
1310 
1311   *result = val;
1312 
1313   return (e == SSE_OK || e == SSE_OK_PRECISION_LOSS);
1314 }
1315 
1316 /* Return a pointer to the beginning of the next field in line.
1317    The line pointer is moved to the end of the next field. */
1318 static char*
next_field(char ** line)1319 next_field (char **line)
1320 {
1321   char *field_start = *line;
1322   char *field_end   = field_start;
1323 
1324   if (delimiter != DELIMITER_DEFAULT)
1325     {
1326       if (*field_start != delimiter)
1327         {
1328           while (*field_end && *field_end != delimiter)
1329             ++field_end;
1330         }
1331       /* else empty field */
1332     }
1333   else
1334     {
1335       /* keep any space prefix in the returned field */
1336       while (*field_end && field_sep (*field_end))
1337         ++field_end;
1338 
1339       while (*field_end && ! field_sep (*field_end))
1340         ++field_end;
1341     }
1342 
1343   *line = field_end;
1344   return field_start;
1345 }
1346 
1347 ATTRIBUTE_PURE
1348 static bool
include_field(uintmax_t field)1349 include_field (uintmax_t field)
1350 {
1351   struct field_range_pair *p = frp;
1352   if (!p)
1353     return field == 1;
1354 
1355   while (p->lo != UINTMAX_MAX)
1356     {
1357       if (p->lo <= field && p->hi >= field)
1358         return true;
1359       ++p;
1360     }
1361   return false;
1362 }
1363 
1364 /* Convert and output the given field. If it is not included in the set
1365    of fields to process just output the original */
1366 static bool
process_field(char * text,uintmax_t field)1367 process_field (char *text, uintmax_t field)
1368 {
1369   long double val = 0;
1370   size_t precision = 0;
1371   bool valid_number = true;
1372 
1373   if (include_field (field))
1374     {
1375       valid_number =
1376         process_suffixed_number (text, &val, &precision, field);
1377 
1378       intmax_t padding;
1379       if (valid_number)
1380         valid_number = prepare_padded_number (val, precision, &padding);
1381 
1382       if (valid_number)
1383         print_padded_number (padding);
1384       else
1385         fputs (text, stdout);
1386     }
1387   else
1388     fputs (text, stdout);
1389 
1390   return valid_number;
1391 }
1392 
1393 /* Convert number in a given line of text.
1394    NEWLINE specifies whether to output a '\n' for this "line".  */
1395 static int
process_line(char * line,bool newline)1396 process_line (char *line, bool newline)
1397 {
1398   char *next;
1399   uintmax_t field = 0;
1400   bool valid_number = true;
1401 
1402   while (true) {
1403     ++field;
1404     next = next_field (&line);
1405 
1406     if (*line != '\0')
1407       {
1408         /* nul terminate the current field string and process */
1409         *line = '\0';
1410 
1411         if (! process_field (next, field))
1412           valid_number = false;
1413 
1414         fputc ((delimiter == DELIMITER_DEFAULT) ?
1415                ' ' : delimiter, stdout);
1416         ++line;
1417       }
1418     else
1419       {
1420         /* end of the line, process the last field and finish */
1421         if (! process_field (next, field))
1422           valid_number = false;
1423 
1424         break;
1425       }
1426   }
1427 
1428   if (newline)
1429     putchar (line_delim);
1430 
1431   return valid_number;
1432 }
1433 
1434 int
main(int argc,char ** argv)1435 main (int argc, char **argv)
1436 {
1437   int valid_numbers = 1;
1438   bool locale_ok;
1439 
1440   initialize_main (&argc, &argv);
1441   set_program_name (argv[0]);
1442   locale_ok = !!setlocale (LC_ALL, "");
1443   bindtextdomain (PACKAGE, LOCALEDIR);
1444   textdomain (PACKAGE);
1445 
1446 #if HAVE_FPSETPREC
1447   /* Enabled extended precision if needed.  */
1448   fpsetprec (FP_PE);
1449 #endif
1450 
1451   decimal_point = nl_langinfo (RADIXCHAR);
1452   if (decimal_point == nullptr || strlen (decimal_point) == 0)
1453     decimal_point = ".";
1454   decimal_point_length = strlen (decimal_point);
1455 
1456   atexit (close_stdout);
1457 
1458   while (true)
1459     {
1460       int c = getopt_long (argc, argv, "d:z", longopts, nullptr);
1461 
1462       if (c == -1)
1463         break;
1464 
1465       switch (c)
1466         {
1467         case FROM_OPTION:
1468           scale_from = XARGMATCH ("--from", optarg,
1469                                   scale_from_args, scale_from_types);
1470           break;
1471 
1472         case FROM_UNIT_OPTION:
1473           from_unit_size = unit_to_umax (optarg);
1474           break;
1475 
1476         case TO_OPTION:
1477           scale_to =
1478             XARGMATCH ("--to", optarg, scale_to_args, scale_to_types);
1479           break;
1480 
1481         case TO_UNIT_OPTION:
1482           to_unit_size = unit_to_umax (optarg);
1483           break;
1484 
1485         case ROUND_OPTION:
1486           round_style = XARGMATCH ("--round", optarg, round_args, round_types);
1487           break;
1488 
1489         case GROUPING_OPTION:
1490           grouping = 1;
1491           break;
1492 
1493         case PADDING_OPTION:
1494           if (((xstrtoimax (optarg, nullptr, 10, &padding_width, "")
1495                 & ~LONGINT_OVERFLOW)
1496                != LONGINT_OK)
1497               || padding_width == 0)
1498             error (EXIT_FAILURE, 0, _("invalid padding value %s"),
1499                    quote (optarg));
1500           /* TODO: We probably want to apply a specific --padding
1501              to --header lines too.  */
1502           break;
1503 
1504         case FIELD_OPTION:
1505           if (n_frp)
1506             error (EXIT_FAILURE, 0, _("multiple field specifications"));
1507           set_fields (optarg, SETFLD_ALLOW_DASH);
1508           break;
1509 
1510         case 'd':
1511           /* Interpret -d '' to mean 'use the NUL byte as the delimiter.'  */
1512           if (optarg[0] != '\0' && optarg[1] != '\0')
1513             error (EXIT_FAILURE, 0,
1514                    _("the delimiter must be a single character"));
1515           delimiter = optarg[0];
1516           break;
1517 
1518         case 'z':
1519           line_delim = '\0';
1520           break;
1521 
1522         case SUFFIX_OPTION:
1523           suffix = optarg;
1524           break;
1525 
1526         case DEBUG_OPTION:
1527           debug = true;
1528           break;
1529 
1530         case DEV_DEBUG_OPTION:
1531           dev_debug = true;
1532           debug = true;
1533           break;
1534 
1535         case HEADER_OPTION:
1536           if (optarg)
1537             {
1538               if (xstrtoumax (optarg, nullptr, 10, &header, "") != LONGINT_OK
1539                   || header == 0)
1540                 error (EXIT_FAILURE, 0, _("invalid header value %s"),
1541                        quote (optarg));
1542             }
1543           else
1544             {
1545               header = 1;
1546             }
1547           break;
1548 
1549         case FORMAT_OPTION:
1550           format_str = optarg;
1551           break;
1552 
1553         case INVALID_OPTION:
1554           inval_style = XARGMATCH ("--invalid", optarg,
1555                                    inval_args, inval_types);
1556           break;
1557 
1558           case_GETOPT_HELP_CHAR;
1559           case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
1560 
1561         default:
1562           usage (EXIT_FAILURE);
1563         }
1564     }
1565 
1566   if (format_str != nullptr && grouping)
1567     error (EXIT_FAILURE, 0, _("--grouping cannot be combined with --format"));
1568 
1569   if (debug && ! locale_ok)
1570     error (0, 0, _("failed to set locale"));
1571 
1572   /* Warn about no-op.  */
1573   if (debug && scale_from == scale_none && scale_to == scale_none
1574       && !grouping && (padding_width == 0) && (format_str == nullptr))
1575     error (0, 0, _("no conversion option specified"));
1576 
1577   if (format_str)
1578     parse_format_string (format_str);
1579 
1580   if (grouping)
1581     {
1582       if (scale_to != scale_none)
1583         error (EXIT_FAILURE, 0, _("grouping cannot be combined with --to"));
1584       if (debug && (strlen (nl_langinfo (THOUSEP)) == 0))
1585         error (0, 0, _("grouping has no effect in this locale"));
1586     }
1587 
1588   auto_padding = (padding_width == 0 && delimiter == DELIMITER_DEFAULT);
1589 
1590   if (inval_style != inval_abort)
1591     conv_exit_code = 0;
1592 
1593   if (argc > optind)
1594     {
1595       if (debug && header)
1596         error (0, 0, _("--header ignored with command-line input"));
1597 
1598       for (; optind < argc; optind++)
1599         valid_numbers &= process_line (argv[optind], true);
1600     }
1601   else
1602     {
1603       char *line = nullptr;
1604       size_t line_allocated = 0;
1605       ssize_t len;
1606 
1607       while (header-- && getdelim (&line, &line_allocated,
1608                                    line_delim, stdin) > 0)
1609         fputs (line, stdout);
1610 
1611       while ((len = getdelim (&line, &line_allocated,
1612                               line_delim, stdin)) > 0)
1613         {
1614           bool newline = line[len - 1] == line_delim;
1615           if (newline)
1616             line[len - 1] = '\0';
1617           valid_numbers &= process_line (line, newline);
1618         }
1619 
1620       if (ferror (stdin))
1621         error (EXIT_FAILURE, errno, _("error reading input"));
1622     }
1623 
1624   if (debug && !valid_numbers)
1625     error (0, 0, _("failed to convert some of the input numbers"));
1626 
1627   int exit_status = EXIT_SUCCESS;
1628   if (!valid_numbers
1629       && inval_style != inval_warn && inval_style != inval_ignore)
1630     exit_status = EXIT_CONVERSION_WARNINGS;
1631 
1632   main_exit (exit_status);
1633 }
1634