/* Reformat numbers like 11505426432 to the more human-readable 11G             This is the numfmt utility
   Copyright (C) 2012-2018 Free Software Foundation, Inc.                       
                                                                                
   This program is free software: you can redistribute it and/or modify         
   it under the terms of the GNU General Public License as published by         
   the Free Software Foundation, either version 3 of the License, or            
   (at your option) any later version.                                          
                                                                                
   This program is distributed in the hope that it will be useful,              
   but WITHOUT ANY WARRANTY; without even the implied warranty of               
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                
   GNU General Public License for more details.                                 
                                                                                
   You should have received a copy of the GNU General Public License            
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */   The GNUv3 license
                                                                                
#include <config.h>                                                             Provides system specific information
#include <float.h>                                                              ...!includes auto-comment...
#include <getopt.h>                                                             ...!includes auto-comment...
#include <stdio.h>                                                              Provides standard I/O capability
#include <sys/types.h>                                                          Provides system data types
#include <langinfo.h>                                                           ...!includes auto-comment...
                                                                                
#include "mbsalign.h"                                                           ...!includes auto-comment...
#include "argmatch.h"                                                           ...!includes auto-comment...
#include "c-ctype.h"                                                            ...!includes auto-comment...
#include "die.h"                                                                ...!includes auto-comment...
#include "error.h"                                                              ...!includes auto-comment...
#include "quote.h"                                                              ...!includes auto-comment...
#include "system.h"                                                             ...!includes auto-comment...
#include "xstrtol.h"                                                            ...!includes auto-comment...
#include "xstrndup.h"                                                           ...!includes auto-comment...
                                                                                
#include "set-fields.h"                                                         ...!includes auto-comment...
                                                                                
#if HAVE_FPSETPREC                                                              Line 36
# include <ieeefp.h>                                                            Line 37
#endif                                                                          Line 38
                                                                                
/* The official name of this program (e.g., no 'g' prefix).  */                 
#define PROGRAM_NAME "numfmt"                                                   Line 41
                                                                                
#define AUTHORS proper_name ("Assaf Gordon")                                    Line 43
                                                                                
/* Exit code when some numbers fail to convert.  */                             
enum { EXIT_CONVERSION_WARNINGS = 2 };                                          Line 46
                                                                                
enum                                                                            Line 48
{                                                                               
  FROM_OPTION = CHAR_MAX + 1,                                                   Line 50
  FROM_UNIT_OPTION,                                                             Line 51
  TO_OPTION,                                                                    Line 52
  TO_UNIT_OPTION,                                                               Line 53
  ROUND_OPTION,                                                                 Line 54
  SUFFIX_OPTION,                                                                Line 55
  GROUPING_OPTION,                                                              Line 56
  PADDING_OPTION,                                                               Line 57
  FIELD_OPTION,                                                                 Line 58
  DEBUG_OPTION,                                                                 Line 59
  DEV_DEBUG_OPTION,                                                             Line 60
  HEADER_OPTION,                                                                Line 61
  FORMAT_OPTION,                                                                Line 62
  INVALID_OPTION                                                                Line 63
};                                                                              Block 2
                                                                                
enum scale_type                                                                 Line 66
{                                                                               
  scale_none,                   /* the default: no scaling.  */                 Line 68
  scale_auto,                   /* --from only.  */                             Line 69
  scale_SI,                                                                     Line 70
  scale_IEC,                                                                    Line 71
  scale_IEC_I                   /* 'i' suffix is required.  */                  Line 72
};                                                                              Block 3
                                                                                
static char const *const scale_from_args[] =                                    Line 75
{                                                                               
  "none", "auto", "si", "iec", "iec-i", NULL                                    Line 77
};                                                                              Block 4
                                                                                
static enum scale_type const scale_from_types[] =                               Line 80
{                                                                               
  scale_none, scale_auto, scale_SI, scale_IEC, scale_IEC_I                      Line 82
};                                                                              Block 5
                                                                                
static char const *const scale_to_args[] =                                      Line 85
{                                                                               
  "none", "si", "iec", "iec-i", NULL                                            Line 87
};                                                                              Block 6
                                                                                
static enum scale_type const scale_to_types[] =                                 Line 90
{                                                                               
  scale_none, scale_SI, scale_IEC, scale_IEC_I                                  Line 92
};                                                                              Block 7
                                                                                
                                                                                
enum round_type                                                                 Line 96
{                                                                               
  round_ceiling,                                                                Line 98
  round_floor,                                                                  Line 99
  round_from_zero,                                                              Line 100
  round_to_zero,                                                                Line 101
  round_nearest,                                                                Line 102
};                                                                              Block 8
                                                                                
static char const *const round_args[] =                                         Line 105
{                                                                               
  "up", "down", "from-zero", "towards-zero", "nearest", NULL                    Line 107
};                                                                              Block 9
                                                                                
static enum round_type const round_types[] =                                    Line 110
{                                                                               
  round_ceiling, round_floor, round_from_zero, round_to_zero, round_nearest     Line 112
};                                                                              Block 10
                                                                                
                                                                                
enum inval_type                                                                 Line 116
{                                                                               
  inval_abort,                                                                  ...!common auto-comment...
  inval_fail,                                                                   Line 119
  inval_warn,                                                                   Line 120
  inval_ignore                                                                  Line 121
};                                                                              
                                                                                
static char const *const inval_args[] =                                         Line 124
{                                                                               
  "abort", "fail", "warn", "ignore", NULL                                       ...!common auto-comment...
};                                                                              
                                                                                
static enum inval_type const inval_types[] =                                    Line 129
{                                                                               
  inval_abort, inval_fail, inval_warn, inval_ignore                             ...!common auto-comment...
};                                                                              
                                                                                
static struct option const longopts[] =                                         Line 134
{                                                                               
  {"from", required_argument, NULL, FROM_OPTION},                               Line 136
  {"from-unit", required_argument, NULL, FROM_UNIT_OPTION},                     Line 137
  {"to", required_argument, NULL, TO_OPTION},                                   Line 138
  {"to-unit", required_argument, NULL, TO_UNIT_OPTION},                         Line 139
  {"round", required_argument, NULL, ROUND_OPTION},                             Line 140
  {"padding", required_argument, NULL, PADDING_OPTION},                         Line 141
  {"suffix", required_argument, NULL, SUFFIX_OPTION},                           Line 142
  {"grouping", no_argument, NULL, GROUPING_OPTION},                             Line 143
  {"delimiter", required_argument, NULL, 'd'},                                  Line 144
  {"field", required_argument, NULL, FIELD_OPTION},                             Line 145
  {"debug", no_argument, NULL, DEBUG_OPTION},                                   Line 146
  {"-debug", no_argument, NULL, DEV_DEBUG_OPTION},                              Line 147
  {"header", optional_argument, NULL, HEADER_OPTION},                           Line 148
  {"format", required_argument, NULL, FORMAT_OPTION},                           Line 149
  {"invalid", required_argument, NULL, INVALID_OPTION},                         Line 150
  {"zero-terminated", no_argument, NULL, 'z'},                                  Line 151
  {GETOPT_HELP_OPTION_DECL},                                                    Line 152
  {GETOPT_VERSION_OPTION_DECL},                                                 Line 153
  {NULL, 0, NULL, 0}                                                            Line 154
};                                                                              Block 14
                                                                                
/* If delimiter has this value, blanks separate fields.  */                     
enum { DELIMITER_DEFAULT = CHAR_MAX + 1 };                                      Line 158
                                                                                
/* Maximum number of digits we can safely handle                                
   without precision loss, if scaling is 'none'.  */                            
enum { MAX_UNSCALED_DIGITS = LDBL_DIG };                                        Line 162
                                                                                
/* Maximum number of digits we can work with.                                   
   This is equivalent to 999Y.                                                  
   NOTE: 'long double' can handle more than that, but there's                   
         no official suffix assigned beyond Yotta (1000^8).  */                 
enum { MAX_ACCEPTABLE_DIGITS = 27 };                                            Line 168
                                                                                
static enum scale_type scale_from = scale_none;                                 Line 170
static enum scale_type scale_to = scale_none;                                   Line 171
static enum round_type round_style = round_from_zero;                           Line 172
static enum inval_type inval_style = inval_abort;                               ...!common auto-comment...
static const char *suffix = NULL;                                               Line 174
static uintmax_t from_unit_size = 1;                                            Line 175
static uintmax_t to_unit_size = 1;                                              Line 176
static int grouping = 0;                                                        Line 177
static char *padding_buffer = NULL;                                             Line 178
static size_t padding_buffer_size = 0;                                          Line 179
static long int padding_width = 0;                                              Line 180
static long int zero_padding_width = 0;                                         Line 181
static long int user_precision = -1;                                            Line 182
static const char *format_str = NULL;                                           Line 183
static char *format_str_prefix = NULL;                                          Line 184
static char *format_str_suffix = NULL;                                          Line 185
                                                                                
/* By default, any conversion error will terminate the program.  */             
static int conv_exit_code = EXIT_CONVERSION_WARNINGS;                           Line 188
                                                                                
                                                                                
/* auto-pad each line based on skipped whitespace.  */                          
static int auto_padding = 0;                                                    Line 192
static mbs_align_t padding_alignment = MBS_ALIGN_RIGHT;                         Line 193
                                                                                
/* field delimiter */                                                           
static int delimiter = DELIMITER_DEFAULT;                                       Line 196
                                                                                
/* line delimiter.  */                                                          
static unsigned char line_delim = '\n';                                         Line 199
                                                                                
/* if non-zero, the first 'header' lines from STDIN are skipped.  */            
static uintmax_t header = 0;                                                    Line 202
                                                                                
/* Debug for users: print warnings to STDERR about possible                     
   error (similar to sort's debug).  */                                         
static bool debug;                                                              Line 206
                                                                                
/* will be set according to the current locale.  */                             
static const char *decimal_point;                                               Line 209
static int decimal_point_length;                                                Line 210
                                                                                
/* debugging for developers.  Enables devmsg().  */                             
static bool dev_debug = false;                                                  Line 213
                                                                                
                                                                                
static inline int                                                               Line 216
default_scale_base (enum scale_type scale)                                      Line 217
{                                                                               
  switch (scale)                                                                Line 219
    {                                                                           
    case scale_IEC:                                                             Line 221
    case scale_IEC_I:                                                           Line 222
      return 1024;                                                              Line 223
                                                                                
    case scale_none:                                                            Line 225
    case scale_auto:                                                            Line 226
    case scale_SI:                                                              Line 227
    default:                                                                    Line 228
      return 1000;                                                              Line 229
    }                                                                           
}                                                                               Block 18
                                                                                
static inline int                                                               Line 233
valid_suffix (const char suf)                                                   Line 234
{                                                                               
  static const char *valid_suffixes = "KMGTPEZY";                               Line 236
  return (strchr (valid_suffixes, suf) != NULL);                                Line 237
}                                                                               Block 19
                                                                                
static inline int                                                               Line 240
suffix_power (const char suf)                                                   Line 241
{                                                                               
  switch (suf)                                                                  Line 243
    {                                                                           
    case 'K':                  /* kilo or kibi.  */                             Line 245
      return 1;                                                                 Line 246
                                                                                
    case 'M':                  /* mega or mebi.  */                             Line 248
      return 2;                                                                 Line 249
                                                                                
    case 'G':                  /* giga or gibi.  */                             Line 251
      return 3;                                                                 Line 252
                                                                                
    case 'T':                  /* tera or tebi.  */                             Line 254
      return 4;                                                                 Line 255
                                                                                
    case 'P':                  /* peta or pebi.  */                             Line 257
      return 5;                                                                 Line 258
                                                                                
    case 'E':                  /* exa or exbi.  */                              Line 260
      return 6;                                                                 Line 261
                                                                                
    case 'Z':                  /* zetta or 2**70.  */                           Line 263
      return 7;                                                                 Line 264
                                                                                
    case 'Y':                  /* yotta or 2**80.  */                           Line 266
      return 8;                                                                 Line 267
                                                                                
    default:                   /* should never happen. assert?  */              Line 269
      return 0;                                                                 Line 270
    }                                                                           
}                                                                               Block 20
                                                                                
static inline const char *                                                      Line 274
suffix_power_char (unsigned int power)                                          Line 275
{                                                                               
  switch (power)                                                                Line 277
    {                                                                           
    case 0:                                                                     Line 279
      return "";                                                                Line 280
                                                                                
    case 1:                                                                     Line 282
      return "K";                                                               Line 283
                                                                                
    case 2:                                                                     Line 285
      return "M";                                                               Line 286
                                                                                
    case 3:                                                                     Line 288
      return "G";                                                               Line 289
                                                                                
    case 4:                                                                     Line 291
      return "T";                                                               Line 292
                                                                                
    case 5:                                                                     Line 294
      return "P";                                                               Line 295
                                                                                
    case 6:                                                                     Line 297
      return "E";                                                               Line 298
                                                                                
    case 7:                                                                     Line 300
      return "Z";                                                               Line 301
                                                                                
    case 8:                                                                     Line 303
      return "Y";                                                               Line 304
                                                                                
    default:                                                                    Line 306
      return "(error)";                                                         Line 307
    }                                                                           
}                                                                               Block 21
                                                                                
/* Similar to 'powl(3)' but without requiring 'libm'.  */                       
static long double                                                              Line 312
powerld (long double base, unsigned int x)                                      Line 313
{                                                                               
  long double result = base;                                                    Line 315
  if (x == 0)                                                                   Line 316
    return 1;                   /* note for test coverage: this is never        Line 317
                                   reached, as 'powerld' won't be called if     
                                   there's no suffix, hence, no "power".  */    
                                                                                
  /* TODO: check for overflow, inf?  */                                         
  while (--x)                                                                   Line 322
    result *= base;                                                             Line 323
  return result;                                                                Line 324
}                                                                               Block 22
                                                                                
/* Similar to 'fabs(3)' but without requiring 'libm'.  */                       
static inline long double                                                       Line 328
absld (long double val)                                                         Line 329
{                                                                               
  return val < 0 ? -val : val;                                                  Line 331
}                                                                               Block 23
                                                                                
/* Scale down 'val', returns 'updated val' and 'x', such that                   
     val*base^X = original val                                                  
     Similar to "frexpl(3)" but without requiring 'libm',                       
     allowing only integer scale, limited functionality and error checking.  */ 
static long double                                                              Line 338
expld (long double val, unsigned int base, unsigned int /*output */ *x)         Line 339
{                                                                               
  unsigned int power = 0;                                                       Line 341
                                                                                
  if (val >= -LDBL_MAX && val <= LDBL_MAX)                                      Line 343
    {                                                                           
      while (absld (val) >= base)                                               Line 345
        {                                                                       
          ++power;                                                              Line 347
          val /= base;                                                          Line 348
        }                                                                       
    }                                                                           
  if (x)                                                                        Line 351
    *x = power;                                                                 Line 352
  return val;                                                                   Line 353
}                                                                               Block 24
                                                                                
/* EXTREMELY limited 'ceil' - without 'libm'.                                   
   Assumes values that fit in intmax_t.  */                                     
static inline intmax_t                                                          Line 358
simple_round_ceiling (long double val)                                          Line 359
{                                                                               
  intmax_t intval = val;                                                        Line 361
  if (intval < val)                                                             Line 362
    intval++;                                                                   Line 363
  return intval;                                                                Line 364
}                                                                               Block 25
                                                                                
/* EXTREMELY limited 'floor' - without 'libm'.                                  
   Assumes values that fit in intmax_t.  */                                     
static inline intmax_t                                                          Line 369
simple_round_floor (long double val)                                            Line 370
{                                                                               
  return -simple_round_ceiling (-val);                                          Line 372
}                                                                               Block 26
                                                                                
/* EXTREMELY limited 'round away from zero'.                                    
   Assumes values that fit in intmax_t.  */                                     
static inline intmax_t                                                          Line 377
simple_round_from_zero (long double val)                                        Line 378
{                                                                               
  return val < 0 ? simple_round_floor (val) : simple_round_ceiling (val);       Line 380
}                                                                               Block 27
                                                                                
/* EXTREMELY limited 'round away to zero'.                                      
   Assumes values that fit in intmax_t.  */                                     
static inline intmax_t                                                          Line 385
simple_round_to_zero (long double val)                                          Line 386
{                                                                               
  return val;                                                                   Line 388
}                                                                               Block 28
                                                                                
/* EXTREMELY limited 'round' - without 'libm'.                                  
   Assumes values that fit in intmax_t.  */                                     
static inline intmax_t                                                          Line 393
simple_round_nearest (long double val)                                          Line 394
{                                                                               
  return val < 0 ? val - 0.5 : val + 0.5;                                       Line 396
}                                                                               Block 29
                                                                                
static inline long double _GL_ATTRIBUTE_CONST                                   Line 399
simple_round (long double val, enum round_type t)                               Line 400
{                                                                               
  intmax_t rval;                                                                Line 402
  intmax_t intmax_mul = val / INTMAX_MAX;                                       Line 403
  val -= (long double) INTMAX_MAX * intmax_mul;                                 Line 404
                                                                                
  switch (t)                                                                    Line 406
    {                                                                           
    case round_ceiling:                                                         Line 408
      rval = simple_round_ceiling (val);                                        Line 409
      break;                                                                    Line 410
                                                                                
    case round_floor:                                                           Line 412
      rval = simple_round_floor (val);                                          Line 413
      break;                                                                    Line 414
                                                                                
    case round_from_zero:                                                       Line 416
      rval = simple_round_from_zero (val);                                      Line 417
      break;                                                                    Line 418
                                                                                
    case round_to_zero:                                                         Line 420
      rval = simple_round_to_zero (val);                                        Line 421
      break;                                                                    Line 422
                                                                                
    case round_nearest:                                                         Line 424
      rval = simple_round_nearest (val);                                        Line 425
      break;                                                                    Line 426
                                                                                
    default:                                                                    Line 428
      /* to silence the compiler - this should never happen.  */                
      return 0;                                                                 Line 430
    }                                                                           
                                                                                
  return (long double) INTMAX_MAX * intmax_mul + rval;                          Line 433
}                                                                               Block 30
                                                                                
enum simple_strtod_error                                                        Line 436
{                                                                               
  SSE_OK = 0,                                                                   Line 438
  SSE_OK_PRECISION_LOSS,                                                        Line 439
  SSE_OVERFLOW,                                                                 Line 440
  SSE_INVALID_NUMBER,                                                           Line 441
                                                                                
  /* the following are returned by 'simple_strtod_human'.  */                   
  SSE_VALID_BUT_FORBIDDEN_SUFFIX,                                               Line 444
  SSE_INVALID_SUFFIX,                                                           Line 445
  SSE_MISSING_I_SUFFIX                                                          Line 446
};                                                                              Block 31
                                                                                
/* Read an *integer* INPUT_STR,                                                 
   but return the integer value in a 'long double' VALUE                        
   hence, no UINTMAX_MAX limitation.                                            
   NEGATIVE is updated, and is stored separately from the VALUE                 
   so that signbit() isn't required to determine the sign of -0..               
   ENDPTR is required (unlike strtod) and is used to store a pointer            
   to the character after the last character used in the conversion.            
                                                                                
   Note locale'd grouping is not supported,                                     
   nor is skipping of white-space supported.                                    
                                                                                
   Returns:                                                                     
      SSE_OK - valid number.                                                    
      SSE_OK_PRECISION_LOSS - if more than 18 digits were used.                 
      SSE_OVERFLOW          - if more than 27 digits (999Y) were used.          
      SSE_INVALID_NUMBER    - if no digits were found.  */                      
static enum simple_strtod_error                                                 Line 465
simple_strtod_int (const char *input_str,                                       Line 466
                   char **endptr, long double *value, bool *negative)           Line 467
{                                                                               
  enum simple_strtod_error e = SSE_OK;                                          Line 469
                                                                                
  long double val = 0;                                                          Line 471
  unsigned int digits = 0;                                                      Line 472
  bool found_digit = false;                                                     Line 473
                                                                                
  if (*input_str == '-')                                                        Line 475
    {                                                                           
      input_str++;                                                              Line 477
      *negative = true;                                                         Line 478
    }                                                                           
  else                                                                          Line 480
    *negative = false;                                                          Line 481
                                                                                
  *endptr = (char *) input_str;                                                 Line 483
  while (*endptr && c_isdigit (**endptr))                                       Line 484
    {                                                                           
      int digit = (**endptr) - '0';                                             Line 486
                                                                                
      found_digit = true;                                                       Line 488
                                                                                
      if (val || digit)                                                         Line 490
        digits++;                                                               Line 491
                                                                                
      if (digits > MAX_UNSCALED_DIGITS)                                         Line 493
        e = SSE_OK_PRECISION_LOSS;                                              Line 494
                                                                                
      if (digits > MAX_ACCEPTABLE_DIGITS)                                       Line 496
        return SSE_OVERFLOW;                                                    Line 497
                                                                                
      val *= 10;                                                                Line 499
      val += digit;                                                             Line 500
                                                                                
      ++(*endptr);                                                              Line 502
    }                                                                           
  if (! found_digit                                                             Line 504
      && ! STREQ_LEN (*endptr, decimal_point, decimal_point_length))            Line 505
    return SSE_INVALID_NUMBER;                                                  Line 506
  if (*negative)                                                                Line 507
    val = -val;                                                                 Line 508
                                                                                
  if (value)                                                                    Line 510
    *value = val;                                                               Line 511
                                                                                
  return e;                                                                     Line 513
}                                                                               Block 32
                                                                                
/* Read a floating-point INPUT_STR represented as "NNNN[.NNNNN]",               
   and return the value in a 'long double' VALUE.                               
   ENDPTR is required (unlike strtod) and is used to store a pointer            
   to the character after the last character used in the conversion.            
   PRECISION is optional and used to indicate fractions are present.            
                                                                                
   Note locale'd grouping is not supported,                                     
   nor is skipping of white-space supported.                                    
                                                                                
   Returns:                                                                     
      SSE_OK - valid number.                                                    
      SSE_OK_PRECISION_LOSS - if more than 18 digits were used.                 
      SSE_OVERFLOW          - if more than 27 digits (999Y) were used.          
      SSE_INVALID_NUMBER    - if no digits were found.  */                      
static enum simple_strtod_error                                                 Line 530
simple_strtod_float (const char *input_str,                                     Line 531
                     char **endptr,                                             Line 532
                     long double *value,                                        Line 533
                     size_t *precision)                                         Line 534
{                                                                               
  bool negative;                                                                Line 536
  enum simple_strtod_error e = SSE_OK;                                          Line 537
                                                                                
  if (precision)                                                                Line 539
    *precision = 0;                                                             Line 540
                                                                                
  /* TODO: accept locale'd grouped values for the integral part.  */            
  e = simple_strtod_int (input_str, endptr, value, &negative);                  Line 543
  if (e != SSE_OK && e != SSE_OK_PRECISION_LOSS)                                Line 544
    return e;                                                                   Line 545
                                                                                
  /* optional decimal point + fraction.  */                                     
  if (STREQ_LEN (*endptr, decimal_point, decimal_point_length))                 Line 548
    {                                                                           
      char *ptr2;                                                               Line 550
      long double val_frac = 0;                                                 Line 551
      bool neg_frac;                                                            Line 552
                                                                                
      (*endptr) += decimal_point_length;                                        Line 554
      enum simple_strtod_error e2 =                                             Line 555
        simple_strtod_int (*endptr, &ptr2, &val_frac, &neg_frac);               Line 556
      if (e2 != SSE_OK && e2 != SSE_OK_PRECISION_LOSS)                          Line 557
        return e2;                                                              Line 558
      if (e2 == SSE_OK_PRECISION_LOSS)                                          Line 559
        e = e2;                       /* propagate warning.  */                 Line 560
      if (neg_frac)                                                             Line 561
        return SSE_INVALID_NUMBER;                                              Line 562
                                                                                
      /* number of digits in the fractions.  */                                 
      size_t exponent = ptr2 - *endptr;                                         Line 565
                                                                                
      val_frac = ((long double) val_frac) / powerld (10, exponent);             Line 567
                                                                                
      /* TODO: detect loss of precision (only really 18 digits                  
         of precision across all digits (before and after '.')).  */            
      if (value)                                                                Line 571
        {                                                                       
          if (negative)                                                         Line 573
            *value -= val_frac;                                                 Line 574
          else                                                                  Line 575
            *value += val_frac;                                                 Line 576
        }                                                                       
                                                                                
      if (precision)                                                            Line 579
        *precision = exponent;                                                  Line 580
                                                                                
      *endptr = ptr2;                                                           Line 582
    }                                                                           
  return e;                                                                     Line 584
}                                                                               Block 33
                                                                                
/* Read a 'human' INPUT_STR represented as "NNNN[.NNNNN] + suffix",             
   and return the value in a 'long double' VALUE,                               
   with the precision of the input returned in PRECISION.                       
   ENDPTR is required (unlike strtod) and is used to store a pointer            
   to the character after the last character used in the conversion.            
   ALLOWED_SCALING determines the scaling supported.                            
                                                                                
   TODO:                                                                        
     support locale'd grouping                                                  
     accept scentific and hex floats (probably use strtold directly)            
                                                                                
   Returns:                                                                     
      SSE_OK - valid number.                                                    
      SSE_OK_PRECISION_LOSS - if more than LDBL_DIG digits were used.           
      SSE_OVERFLOW          - if more than 27 digits (999Y) were used.          
      SSE_INVALID_NUMBER    - if no digits were found.                          
      SSE_VALID_BUT_FORBIDDEN_SUFFIX                                            
      SSE_INVALID_SUFFIX                                                        
      SSE_MISSING_I_SUFFIX  */                                                  
static enum simple_strtod_error                                                 Line 606
simple_strtod_human (const char *input_str,                                     Line 607
                     char **endptr, long double *value, size_t *precision,      Line 608
                     enum scale_type allowed_scaling)                           Line 609
{                                                                               
  int power = 0;                                                                Line 611
  /* 'scale_auto' is checked below.  */                                         
  int scale_base = default_scale_base (allowed_scaling);                        Line 613
                                                                                
  devmsg ("simple_strtod_human:\n  input string: %s\n"                          Line 615
          "  locale decimal-point: %s\n"                                        Line 616
          "  MAX_UNSCALED_DIGITS: %d\n",                                        Line 617
          quote_n (0, input_str),                                               Line 618
          quote_n (1, decimal_point),                                           Line 619
          MAX_UNSCALED_DIGITS);                                                 Line 620
                                                                                
  enum simple_strtod_error e =                                                  Line 622
    simple_strtod_float (input_str, endptr, value, precision);                  Line 623
  if (e != SSE_OK && e != SSE_OK_PRECISION_LOSS)                                Line 624
    return e;                                                                   Line 625
                                                                                
  devmsg ("  parsed numeric value: %Lf\n"                                       Line 627
          "  input precision = %d\n", *value, (int)*precision);                 Line 628
                                                                                
  if (**endptr != '\0')                                                         Line 630
    {                                                                           
      /* process suffix.  */                                                    
                                                                                
      /* Skip any blanks between the number and suffix.  */                     
      while (isblank (to_uchar (**endptr)))                                     Line 635
        (*endptr)++;                                                            Line 636
                                                                                
      if (!valid_suffix (**endptr))                                             Line 638
        return SSE_INVALID_SUFFIX;                                              Line 639
                                                                                
      if (allowed_scaling == scale_none)                                        Line 641
        return SSE_VALID_BUT_FORBIDDEN_SUFFIX;                                  Line 642
                                                                                
      power = suffix_power (**endptr);                                          Line 644
      (*endptr)++;                     /* skip first suffix character.  */      Line 645
                                                                                
      if (allowed_scaling == scale_auto && **endptr == 'i')                     Line 647
        {                                                                       
          /* auto-scaling enabled, and the first suffix character               
              is followed by an 'i' (e.g. Ki, Mi, Gi).  */                      
          scale_base = 1024;                                                    Line 651
          (*endptr)++;              /* skip second  ('i') suffix character.  */ Line 652
          devmsg ("  Auto-scaling, found 'i', switching to base %d\n",          Line 653
                  scale_base);                                                  Line 654
        }                                                                       
                                                                                
      *precision = 0;  /* Reset, to select precision based on scale.  */        Line 657
    }                                                                           
                                                                                
  if (allowed_scaling == scale_IEC_I)                                           Line 660
    {                                                                           
      if (**endptr == 'i')                                                      Line 662
        (*endptr)++;                                                            Line 663
      else                                                                      Line 664
        return SSE_MISSING_I_SUFFIX;                                            Line 665
    }                                                                           
                                                                                
  long double multiplier = powerld (scale_base, power);                         Line 668
                                                                                
  devmsg ("  suffix power=%d^%d = %Lf\n", scale_base, power, multiplier);       Line 670
                                                                                
  /* TODO: detect loss of precision and overflows.  */                          
  (*value) = (*value) * multiplier;                                             Line 673
                                                                                
  devmsg ("  returning value: %Lf (%LG)\n", *value, *value);                    Line 675
                                                                                
  return e;                                                                     Line 677
}                                                                               Block 34
                                                                                
                                                                                
static void                                                                     Line 681
simple_strtod_fatal (enum simple_strtod_error err, char const *input_str)       Line 682
{                                                                               
  char const *msgid = NULL;                                                     Line 684
                                                                                
  switch (err)                                                                  Line 686
    {                                                                           
    case SSE_OK_PRECISION_LOSS:                                                 Line 688
    case SSE_OK:                                                                Line 689
      /* should never happen - this function isn't called when OK.  */          
      abort ();                                                                 ...!common auto-comment...
                                                                                
    case SSE_OVERFLOW:                                                          Line 693
      msgid = N_("value too large to be converted: %s");                        Line 694
      break;                                                                    Line 695
                                                                                
    case SSE_INVALID_NUMBER:                                                    Line 697
      msgid = N_("invalid number: %s");                                         Line 698
      break;                                                                    Line 699
                                                                                
    case SSE_VALID_BUT_FORBIDDEN_SUFFIX:                                        Line 701
      msgid = N_("rejecting suffix in input: %s (consider using --from)");      Line 702
      break;                                                                    Line 703
                                                                                
    case SSE_INVALID_SUFFIX:                                                    Line 705
      msgid = N_("invalid suffix in input: %s");                                Line 706
      break;                                                                    Line 707
                                                                                
    case SSE_MISSING_I_SUFFIX:                                                  Line 709
      msgid = N_("missing 'i' suffix in input: %s (e.g Ki/Mi/Gi)");             Line 710
      break;                                                                    Line 711
                                                                                
    }                                                                           
                                                                                
  if (inval_style != inval_ignore)                                              Line 715
    error (conv_exit_code, 0, gettext (msgid), quote (input_str));              Line 716
}                                                                               Block 35
                                                                                
/* Convert VAL to a human format string in BUF.  */                             
static void                                                                     Line 720
double_to_human (long double val, int precision,                                Line 721
                 char *buf, size_t buf_size,                                    Line 722
                 enum scale_type scale, int group, enum round_type round)       Line 723
{                                                                               
  int num_size;                                                                 Line 725
  char fmt[64];                                                                 Line 726
  verify (sizeof (fmt) > (INT_BUFSIZE_BOUND (zero_padding_width)                Line 727
                          + INT_BUFSIZE_BOUND (precision)                       Line 728
                          + 10 /* for %.Lf  etc.  */));                         Line 729
                                                                                
  char *pfmt = fmt;                                                             Line 731
  *pfmt++ = '%';                                                                Line 732
                                                                                
  if (group)                                                                    Line 734
    *pfmt++ = '\'';                                                             Line 735
                                                                                
  if (zero_padding_width)                                                       Line 737
    pfmt += snprintf (pfmt, sizeof (fmt) - 2, "0%ld", zero_padding_width);      Line 738
                                                                                
  devmsg ("double_to_human:\n");                                                Line 740
                                                                                
  if (scale == scale_none)                                                      Line 742
    {                                                                           
      val *= powerld (10, precision);                                           Line 744
      val = simple_round (val, round);                                          Line 745
      val /= powerld (10, precision);                                           Line 746
                                                                                
      devmsg ((group) ?                                                         Line 748
              "  no scaling, returning (grouped) value: %'.*Lf\n" :             Line 749
              "  no scaling, returning value: %.*Lf\n", precision, val);        Line 750
                                                                                
      stpcpy (pfmt, ".*Lf");                                                    Line 752
                                                                                
      num_size = snprintf (buf, buf_size, fmt, precision, val);                 Line 754
      if (num_size < 0 || num_size >= (int) buf_size)                           Line 755
        die (EXIT_FAILURE, 0,                                                   Line 756
             _("failed to prepare value '%Lf' for printing"), val);             Line 757
      return;                                                                   Line 758
    }                                                                           
                                                                                
  /* Scaling requested by user. */                                              
  double scale_base = default_scale_base (scale);                               Line 762
                                                                                
  /* Normalize val to scale. */                                                 
  unsigned int power = 0;                                                       Line 765
  val = expld (val, scale_base, &power);                                        Line 766
  devmsg ("  scaled value to %Lf * %0.f ^ %u\n", val, scale_base, power);       Line 767
                                                                                
  /* Perform rounding. */                                                       
  unsigned int power_adjust = 0;                                                Line 770
  if (user_precision != -1)                                                     Line 771
    power_adjust = MIN (power * 3, user_precision);                             Line 772
  else if (absld (val) < 10)                                                    Line 773
    {                                                                           
      /* for values less than 10, we allow one decimal-point digit,             
         so adjust before rounding. */                                          
      power_adjust = 1;                                                         Line 777
    }                                                                           
                                                                                
  val *= powerld (10, power_adjust);                                            Line 780
  val = simple_round (val, round);                                              Line 781
  val /= powerld (10, power_adjust);                                            Line 782
                                                                                
  /* two special cases after rounding:                                          
     1. a "999.99" can turn into 1000 - so scale down                           
     2. a "9.99" can turn into 10 - so don't display decimal-point.  */         
  if (absld (val) >= scale_base)                                                Line 787
    {                                                                           
      val /= scale_base;                                                        Line 789
      power++;                                                                  Line 790
    }                                                                           
                                                                                
  /* should "7.0" be printed as "7" ?                                           
     if removing the ".0" is preferred, enable the fourth condition.  */        
  int show_decimal_point = (val != 0) && (absld (val) < 10) && (power > 0);     Line 795
  /* && (absld (val) > simple_round_floor (val))) */                            
                                                                                
  devmsg ("  after rounding, value=%Lf * %0.f ^ %u\n", val, scale_base, power); Line 798
                                                                                
  stpcpy (pfmt, ".*Lf%s");                                                      Line 800
                                                                                
  int prec = user_precision == -1 ? show_decimal_point : user_precision;        Line 802
                                                                                
  /* buf_size - 1 used here to ensure place for possible scale_IEC_I suffix.  */
  num_size = snprintf (buf, buf_size - 1, fmt, prec, val,                       Line 805
                       suffix_power_char (power));                              Line 806
  if (num_size < 0 || num_size >= (int) buf_size - 1)                           Line 807
    die (EXIT_FAILURE, 0,                                                       Line 808
         _("failed to prepare value '%Lf' for printing"), val);                 Line 809
                                                                                
  if (scale == scale_IEC_I && power > 0)                                        Line 811
    strncat (buf, "i", buf_size - num_size - 1);                                Line 812
                                                                                
  devmsg ("  returning value: %s\n", quote (buf));                              Line 814
                                                                                
  return;                                                                       Line 816
}                                                                               Block 36
                                                                                
/* Convert a string of decimal digits, N_STRING, with an optional suffix        
   to an integral value.  Suffixes are handled as with --from=auto.             
   Upon successful conversion, return that value.                               
   If it cannot be converted, give a diagnostic and exit.  */                   
static uintmax_t                                                                Line 823
unit_to_umax (const char *n_string)                                             Line 824
{                                                                               
  strtol_error s_err;                                                           Line 826
  const char *c_string = n_string;                                              Line 827
  char *t_string = NULL;                                                        Line 828
  size_t n_len = strlen (n_string);                                             Line 829
  char *end = NULL;                                                             Line 830
  uintmax_t n;                                                                  Line 831
  const char *suffixes = "KMGTPEZY";                                            Line 832
                                                                                
  /* Adjust suffixes so K=1000, Ki=1024, KiB=invalid.  */                       
  if (n_len && ! c_isdigit (n_string[n_len - 1]))                               Line 835
    {                                                                           
      t_string = xmalloc (n_len + 2);                                           Line 837
      end = t_string + n_len - 1;                                               Line 838
      memcpy (t_string, n_string, n_len);                                       Line 839
                                                                                
      if (*end == 'i' && 2 <= n_len && ! c_isdigit (*(end - 1)))                Line 841
        *end = '\0';                                                            Line 842
      else                                                                      Line 843
        {                                                                       
          *++end = 'B';                                                         Line 845
          *++end = '\0';                                                        Line 846
          suffixes = "KMGTPEZY0";                                               Line 847
        }                                                                       
                                                                                
      c_string = t_string;                                                      Line 850
    }                                                                           
                                                                                
  s_err = xstrtoumax (c_string, &end, 10, &n, suffixes);                        Line 853
                                                                                
  if (s_err != LONGINT_OK || *end || n == 0)                                    Line 855
    {                                                                           
      free (t_string);                                                          Line 857
      die (EXIT_FAILURE, 0, _("invalid unit size: %s"), quote (n_string));      Line 858
    }                                                                           
                                                                                
  free (t_string);                                                              Line 861
                                                                                
  return n;                                                                     Line 863
}                                                                               Block 37
                                                                                
                                                                                
static void                                                                     Line 867
setup_padding_buffer (size_t min_size)                                          Line 868
{                                                                               
  if (padding_buffer_size > min_size)                                           Line 870
    return;                                                                     Line 871
                                                                                
  padding_buffer_size = min_size + 1;                                           Line 873
  padding_buffer = xrealloc (padding_buffer, padding_buffer_size);              Line 874
}                                                                               Block 38
                                                                                
void                                                                            Line 877
usage (int status)                                                              Line 878
{                                                                               
  if (status != EXIT_SUCCESS)                                                   Line 880
    emit_try_help ();                                                           ...!common auto-comment...
  else                                                                          Line 882
    {                                                                           
      printf (_("\                                                              Line 884
Usage: %s [OPTION]... [NUMBER]...\n\                                            Line 885
"), program_name);                                                              Line 886
      fputs (_("\                                                               Line 887
Reformat NUMBER(s), or the numbers from standard input if none are specified.\n\Line 888
"), stdout);                                                                    Line 889
      emit_mandatory_arg_note ();                                               ...!common auto-comment...
      fputs (_("\                                                               Line 891
      --debug          print warnings about invalid input\n\                    Line 892
"), stdout);                                                                    Line 893
      fputs (_("\                                                               Line 894
  -d, --delimiter=X    use X instead of whitespace for field delimiter\n\       Line 895
"), stdout);                                                                    Line 896
      fputs (_("\                                                               Line 897
      --field=FIELDS   replace the numbers in these input fields (default=1)\n\ Line 898
                         see FIELDS below\n\                                    Line 899
"), stdout);                                                                    Line 900
      fputs (_("\                                                               Line 901
      --format=FORMAT  use printf style floating-point FORMAT;\n\               Line 902
                         see FORMAT below for details\n\                        Line 903
"), stdout);                                                                    Line 904
      fputs (_("\                                                               Line 905
      --from=UNIT      auto-scale input numbers to UNITs; default is 'none';\n\ Line 906
                         see UNIT below\n\                                      Line 907
"), stdout);                                                                    Line 908
      fputs (_("\                                                               Line 909
      --from-unit=N    specify the input unit size (instead of the default 1)\n\Line 910
"), stdout);                                                                    Line 911
      fputs (_("\                                                               Line 912
      --grouping       use locale-defined grouping of digits, e.g. 1,000,000\n\ Line 913
                         (which means it has no effect in the C/POSIX locale)\n\Line 914
"), stdout);                                                                    Line 915
      fputs (_("\                                                               Line 916
      --header[=N]     print (without converting) the first N header lines;\n\  Line 917
                         N defaults to 1 if not specified\n\                    Line 918
"), stdout);                                                                    Line 919
      fputs (_("\                                                               Line 920
      --invalid=MODE   failure mode for invalid numbers: MODE can be:\n\        Line 921
                         abort (default), fail, warn, ignore\n\                 ...!common auto-comment...
"), stdout);                                                                    Line 923
      fputs (_("\                                                               Line 924
      --padding=N      pad the output to N characters; positive N will\n\       Line 925
                         right-align; negative N will left-align;\n\            Line 926
                         padding is ignored if the output is wider than N;\n\   Line 927
                         the default is to automatically pad if a whitespace\n\ Line 928
                         is found\n\                                            Line 929
"), stdout);                                                                    Line 930
      fputs (_("\                                                               Line 931
      --round=METHOD   use METHOD for rounding when scaling; METHOD can be:\n\  Line 932
                         up, down, from-zero (default), towards-zero, nearest\n\Line 933
"), stdout);                                                                    Line 934
      fputs (_("\                                                               Line 935
      --suffix=SUFFIX  add SUFFIX to output numbers, and accept optional\n\     Line 936
                         SUFFIX in input numbers\n\                             Line 937
"), stdout);                                                                    Line 938
      fputs (_("\                                                               Line 939
      --to=UNIT        auto-scale output numbers to UNITs; see UNIT below\n\    Line 940
"), stdout);                                                                    Line 941
      fputs (_("\                                                               Line 942
      --to-unit=N      the output unit size (instead of the default 1)\n\       Line 943
"), stdout);                                                                    Line 944
      fputs (_("\                                                               Line 945
  -z, --zero-terminated    line delimiter is NUL, not newline\n\                Line 946
"), stdout);                                                                    Line 947
      fputs (HELP_OPTION_DESCRIPTION, stdout);                                  Line 948
      fputs (VERSION_OPTION_DESCRIPTION, stdout);                               Line 949
                                                                                
      fputs (_("\                                                               Line 951
\n\                                                                             
UNIT options:\n"), stdout);                                                     Line 953
      fputs (_("\                                                               Line 954
  none       no auto-scaling is done; suffixes will trigger an error\n\         Line 955
"), stdout);                                                                    Line 956
      fputs (_("\                                                               Line 957
  auto       accept optional single/two letter suffix:\n\                       Line 958
               1K = 1000,\n\                                                    Line 959
               1Ki = 1024,\n\                                                   Line 960
               1M = 1000000,\n\                                                 Line 961
               1Mi = 1048576,\n"), stdout);                                     Line 962
      fputs (_("\                                                               Line 963
  si         accept optional single letter suffix:\n\                           Line 964
               1K = 1000,\n\                                                    Line 965
               1M = 1000000,\n\                                                 Line 966
               ...\n"), stdout);                                                Line 967
      fputs (_("\                                                               Line 968
  iec        accept optional single letter suffix:\n\                           Line 969
               1K = 1024,\n\                                                    Line 970
               1M = 1048576,\n\                                                 Line 971
               ...\n"), stdout);                                                Line 972
      fputs (_("\                                                               Line 973
  iec-i      accept optional two-letter suffix:\n\                              Line 974
               1Ki = 1024,\n\                                                   Line 975
               1Mi = 1048576,\n\                                                Line 976
               ...\n"), stdout);                                                Line 977
                                                                                
      fputs (_("\n\                                                             Line 979
FIELDS supports cut(1) style field ranges:\n\                                   Line 980
  N    N'th field, counted from 1\n\                                            Line 981
  N-   from N'th field, to end of line\n\                                       Line 982
  N-M  from N'th to M'th field (inclusive)\n\                                   Line 983
  -M   from first to M'th field (inclusive)\n\                                  Line 984
  -    all fields\n\                                                            Line 985
Multiple fields/ranges can be separated with commas\n\                          Line 986
"), stdout);                                                                    Line 987
                                                                                
      fputs (_("\n\                                                             Line 989
FORMAT must be suitable for printing one floating-point argument '%f'.\n\       Line 990
Optional quote (%'f) will enable --grouping (if supported by current locale).\n\Line 991
Optional width value (%10f) will pad output. Optional zero (%010f) width\n\     Line 992
will zero pad the number. Optional negative values (%-10f) will left align.\n\  Line 993
Optional precision (%.1f) will override the input determined precision.\n\      Line 994
"), stdout);                                                                    Line 995
                                                                                
      printf (_("\n\                                                            Line 997
Exit status is 0 if all input numbers were successfully converted.\n\           Line 998
By default, %s will stop at the first conversion error with exit status 2.\n\   Line 999
With --invalid='fail' a warning is printed for each conversion error\n\         Line 1000
and the exit status is 2.  With --invalid='warn' each conversion error is\n\    Line 1001
diagnosed, but the exit status is 0.  With --invalid='ignore' conversion\n\     Line 1002
errors are not diagnosed and the exit status is 0.\n\                           Line 1003
"), program_name);                                                              Line 1004
                                                                                
      printf (_("\n\                                                            Line 1006
Examples:\n\                                                                    Line 1007
  $ %s --to=si 1000\n\                                                          Line 1008
            -> \"1.0K\"\n\                                                      Line 1009
  $ %s --to=iec 2048\n\                                                         Line 1010
           -> \"2.0K\"\n\                                                       Line 1011
  $ %s --to=iec-i 4096\n\                                                       Line 1012
           -> \"4.0Ki\"\n\                                                      Line 1013
  $ echo 1K | %s --from=si\n\                                                   Line 1014
           -> \"1000\"\n\                                                       Line 1015
  $ echo 1K | %s --from=iec\n\                                                  Line 1016
           -> \"1024\"\n\                                                       Line 1017
  $ df -B1 | %s --header --field 2-4 --to=si\n\                                 Line 1018
  $ ls -l  | %s --header --field 5 --to=iec\n\                                  Line 1019
  $ ls -lh | %s --header --field 5 --from=iec --padding=10\n\                   Line 1020
  $ ls -lh | %s --header --field 5 --from=iec --format %%10f\n"),               Line 1021
              program_name, program_name, program_name,                         Line 1022
              program_name, program_name, program_name,                         Line 1023
              program_name, program_name, program_name);                        Line 1024
      emit_ancillary_info (PROGRAM_NAME);                                       Line 1025
    }                                                                           
  exit (status);                                                                Line 1027
}                                                                               Block 39
                                                                                
/* Given 'fmt' (a printf(3) compatible format string), extracts the following:  
    1. padding (e.g. %20f)                                                      
    2. alignment (e.g. %-20f)                                                   
    3. grouping (e.g. %'f)                                                      
                                                                                
   Only a limited subset of printf(3) syntax is supported.                      
                                                                                
   TODO:                                                                        
     support %e %g etc. rather than just %f                                     
                                                                                
   NOTES:                                                                       
   1. This function sets the global variables:                                  
       padding_width, padding_alignment, grouping,                              
       format_str_prefix, format_str_suffix                                     
   2. The function aborts on any errors.  */                                    
static void                                                                     Line 1045
parse_format_string (char const *fmt)                                           Line 1046
{                                                                               
  size_t i;                                                                     Line 1048
  size_t prefix_len = 0;                                                        Line 1049
  size_t suffix_pos;                                                            Line 1050
  long int pad = 0;                                                             Line 1051
  char *endptr = NULL;                                                          Line 1052
  bool zero_padding = false;                                                    Line 1053
                                                                                
  for (i = 0; !(fmt[i] == '%' && fmt[i + 1] != '%'); i += (fmt[i] == '%') + 1)  Line 1055
    {                                                                           
      if (!fmt[i])                                                              Line 1057
        die (EXIT_FAILURE, 0,                                                   Line 1058
             _("format %s has no %% directive"), quote (fmt));                  Line 1059
      prefix_len++;                                                             Line 1060
    }                                                                           
                                                                                
  i++;                                                                          Line 1063
  while (true)                                                                  Line 1064
    {                                                                           
      size_t skip = strspn (fmt + i, " ");                                      Line 1066
      i += skip;                                                                Line 1067
      if (fmt[i] == '\'')                                                       Line 1068
        {                                                                       
          grouping = 1;                                                         Line 1070
          i++;                                                                  Line 1071
        }                                                                       
      else if (fmt[i] == '0')                                                   Line 1073
        {                                                                       
          zero_padding = true;                                                  Line 1075
          i++;                                                                  Line 1076
        }                                                                       
      else if (! skip)                                                          Line 1078
        break;                                                                  Line 1079
    }                                                                           
                                                                                
  errno = 0;                                                                    Line 1082
  pad = strtol (fmt + i, &endptr, 10);                                          Line 1083
  if (errno == ERANGE)                                                          Line 1084
    die (EXIT_FAILURE, 0,                                                       Line 1085
         _("invalid format %s (width overflow)"), quote (fmt));                 Line 1086
                                                                                
  if (endptr != (fmt + i) && pad != 0)                                          Line 1088
    {                                                                           
      if (debug && padding_width && !(zero_padding && pad > 0))                 Line 1090
        error (0, 0, _("--format padding overriding --padding"));               Line 1091
                                                                                
      if (pad < 0)                                                              Line 1093
        {                                                                       
          padding_alignment = MBS_ALIGN_LEFT;                                   Line 1095
          padding_width = -pad;                                                 Line 1096
        }                                                                       
      else                                                                      Line 1098
        {                                                                       
          if (zero_padding)                                                     Line 1100
            zero_padding_width = pad;                                           Line 1101
          else                                                                  Line 1102
            padding_width = pad;                                                Line 1103
        }                                                                       
                                                                                
    }                                                                           
  i = endptr - fmt;                                                             Line 1107
                                                                                
  if (fmt[i] == '\0')                                                           Line 1109
    die (EXIT_FAILURE, 0, _("format %s ends in %%"), quote (fmt));              Line 1110
                                                                                
  if (fmt[i] == '.')                                                            Line 1112
    {                                                                           
      i++;                                                                      Line 1114
      errno = 0;                                                                Line 1115
      user_precision = strtol (fmt + i, &endptr, 10);                           Line 1116
      if (errno == ERANGE || user_precision < 0 || SIZE_MAX < user_precision    Line 1117
          || isblank (fmt[i]) || fmt[i] == '+')                                 Line 1118
        {                                                                       
          /* Note we disallow negative user_precision to be                     
             consistent with printf(1).  POSIX states that                      
             negative precision is only supported (and ignored)                 
             when used with '.*f'.  glibc at least will malform                 
             output when passed a direct negative precision.  */                
          die (EXIT_FAILURE, 0,                                                 Line 1125
               _("invalid precision in format %s"), quote (fmt));               Line 1126
        }                                                                       
      i = endptr - fmt;                                                         Line 1128
    }                                                                           
                                                                                
  if (fmt[i] != 'f')                                                            Line 1131
    die (EXIT_FAILURE, 0, _("invalid format %s,"                                Line 1132
                            " directive must be %%[0]['][-][N][.][N]f"),        Line 1133
         quote (fmt));                                                          Line 1134
  i++;                                                                          Line 1135
  suffix_pos = i;                                                               Line 1136
                                                                                
  for (; fmt[i] != '\0'; i += (fmt[i] == '%') + 1)                              Line 1138
    if (fmt[i] == '%' && fmt[i + 1] != '%')                                     Line 1139
      die (EXIT_FAILURE, 0, _("format %s has too many %% directives"),          Line 1140
           quote (fmt));                                                        Line 1141
                                                                                
  if (prefix_len)                                                               Line 1143
    format_str_prefix = xstrndup (fmt, prefix_len);                             Line 1144
  if (fmt[suffix_pos] != '\0')                                                  Line 1145
    format_str_suffix = xstrdup (fmt + suffix_pos);                             Line 1146
                                                                                
  devmsg ("format String:\n  input: %s\n  grouping: %s\n"                       Line 1148
                   "  padding width: %ld\n  alignment: %s\n"                    Line 1149
                   "  prefix: %s\n  suffix: %s\n",                              Line 1150
          quote_n (0, fmt), (grouping) ? "yes" : "no",                          Line 1151
          padding_width,                                                        Line 1152
          (padding_alignment == MBS_ALIGN_LEFT) ? "Left" : "Right",             Line 1153
          quote_n (1, format_str_prefix ? format_str_prefix : ""),              Line 1154
          quote_n (2, format_str_suffix ? format_str_suffix : ""));             Line 1155
}                                                                               Block 40
                                                                                
/* Parse a numeric value (with optional suffix) from a string.                  
   Returns a long double value, with input precision.                           
                                                                                
   If there's an error converting the string to value - exits with              
   an error.                                                                    
                                                                                
   If there are any trailing characters after the number                        
   (besides a valid suffix) - exits with an error.  */                          
static enum simple_strtod_error                                                 Line 1166
parse_human_number (const char *str, long double /*output */ *value,            Line 1167
                    size_t *precision)                                          Line 1168
{                                                                               
  char *ptr = NULL;                                                             Line 1170
                                                                                
  enum simple_strtod_error e =                                                  Line 1172
    simple_strtod_human (str, &ptr, value, precision, scale_from);              Line 1173
  if (e != SSE_OK && e != SSE_OK_PRECISION_LOSS)                                Line 1174
    {                                                                           
      simple_strtod_fatal (e, str);                                             Line 1176
      return e;                                                                 Line 1177
    }                                                                           
                                                                                
  if (ptr && *ptr != '\0')                                                      Line 1180
    {                                                                           
      if (inval_style != inval_ignore)                                          Line 1182
        error (conv_exit_code, 0, _("invalid suffix in input %s: %s"),          Line 1183
               quote_n (0, str), quote_n (1, ptr));                             Line 1184
      e = SSE_INVALID_SUFFIX;                                                   Line 1185
    }                                                                           
  return e;                                                                     Line 1187
}                                                                               Block 41
                                                                                
                                                                                
/* Print the given VAL, using the requested representation.                     
   The number is printed to STDOUT, with padding and alignment.  */             
static int                                                                      Line 1193
prepare_padded_number (const long double val, size_t precision)                 Line 1194
{                                                                               
  /* Generate Output. */                                                        
  char buf[128];                                                                Line 1197
                                                                                
  size_t precision_used = user_precision == -1 ? precision : user_precision;    Line 1199
                                                                                
  /* Can't reliably print too-large values without auto-scaling. */             
  unsigned int x;                                                               Line 1202
  expld (val, 10, &x);                                                          Line 1203
                                                                                
  if (scale_to == scale_none                                                    Line 1205
      && x + precision_used > MAX_UNSCALED_DIGITS)                              Line 1206
    {                                                                           
      if (inval_style != inval_ignore)                                          Line 1208
        {                                                                       
          if (precision_used)                                                   Line 1210
            error (conv_exit_code, 0,                                           Line 1211
                   _("value/precision too large to be printed: '%Lg/%"PRIuMAX"'"Line 1212
                     " (consider using --to)"), val, (uintmax_t)precision_used);Line 1213
          else                                                                  Line 1214
            error (conv_exit_code, 0,                                           Line 1215
                   _("value too large to be printed: '%Lg'"                     Line 1216
                     " (consider using --to)"), val);                           Line 1217
        }                                                                       
      return 0;                                                                 Line 1219
    }                                                                           
                                                                                
  if (x > MAX_ACCEPTABLE_DIGITS - 1)                                            Line 1222
    {                                                                           
      if (inval_style != inval_ignore)                                          Line 1224
        error (conv_exit_code, 0, _("value too large to be printed: '%Lg'"      Line 1225
                                    " (cannot handle values > 999Y)"), val);    Line 1226
      return 0;                                                                 Line 1227
    }                                                                           
                                                                                
  double_to_human (val, precision_used, buf, sizeof (buf),                      Line 1230
                   scale_to, grouping, round_style);                            Line 1231
  if (suffix)                                                                   Line 1232
    strncat (buf, suffix, sizeof (buf) - strlen (buf) -1);                      Line 1233
                                                                                
  devmsg ("formatting output:\n  value: %Lf\n  humanized: %s\n",                Line 1235
          val, quote (buf));                                                    Line 1236
                                                                                
  if (padding_width && strlen (buf) < padding_width)                            Line 1238
    {                                                                           
      size_t w = padding_width;                                                 Line 1240
      mbsalign (buf, padding_buffer, padding_buffer_size, &w,                   Line 1241
                padding_alignment, MBA_UNIBYTE_ONLY);                           Line 1242
                                                                                
      devmsg ("  After padding: %s\n", quote (padding_buffer));                 Line 1244
    }                                                                           
  else                                                                          Line 1246
    {                                                                           
      setup_padding_buffer (strlen (buf) + 1);                                  Line 1248
      strcpy (padding_buffer, buf);                                             Line 1249
    }                                                                           
                                                                                
  return 1;                                                                     Line 1252
}                                                                               
                                                                                
static void                                                                     Line 1255
print_padded_number (void)                                                      Line 1256
{                                                                               
  if (format_str_prefix)                                                        Line 1258
    fputs (format_str_prefix, stdout);                                          Line 1259
                                                                                
  fputs (padding_buffer, stdout);                                               Line 1261
                                                                                
  if (format_str_suffix)                                                        Line 1263
    fputs (format_str_suffix, stdout);                                          Line 1264
}                                                                               Block 43
                                                                                
/* Converts the TEXT number string to the requested representation,             
   and handles automatic suffix addition.  */                                   
static int                                                                      Line 1269
process_suffixed_number (char *text, long double *result,                       Line 1270
                         size_t *precision, long int field)                     Line 1271
{                                                                               
  if (suffix && strlen (text) > strlen (suffix))                                Line 1273
    {                                                                           
      char *possible_suffix = text + strlen (text) - strlen (suffix);           Line 1275
                                                                                
      if (STREQ (suffix, possible_suffix))                                      Line 1277
        {                                                                       
          /* trim suffix, ONLY if it's at the end of the text.  */              
          *possible_suffix = '\0';                                              Line 1280
          devmsg ("trimming suffix %s\n", quote (suffix));                      Line 1281
        }                                                                       
      else                                                                      Line 1283
        devmsg ("no valid suffix found\n");                                     Line 1284
    }                                                                           
                                                                                
  /* Skip white space - always.  */                                             
  char *p = text;                                                               Line 1288
  while (*p && isblank (to_uchar (*p)))                                         Line 1289
    ++p;                                                                        Line 1290
  const unsigned int skip_count = text - p;                                     Line 1291
                                                                                
  /* setup auto-padding.  */                                                    
  if (auto_padding)                                                             Line 1294
    {                                                                           
      if (skip_count > 0 || field > 1)                                          Line 1296
        {                                                                       
          padding_width = strlen (text);                                        Line 1298
          setup_padding_buffer (padding_width);                                 Line 1299
        }                                                                       
      else                                                                      Line 1301
        {                                                                       
          padding_width = 0;                                                    Line 1303
        }                                                                       
     devmsg ("setting Auto-Padding to %ld characters\n", padding_width);        Line 1305
    }                                                                           
                                                                                
  long double val = 0;                                                          Line 1308
  enum simple_strtod_error e = parse_human_number (p, &val, precision);         Line 1309
  if (e == SSE_OK_PRECISION_LOSS && debug)                                      Line 1310
    error (0, 0, _("large input value %s: possible precision loss"),            Line 1311
           quote (p));                                                          Line 1312
                                                                                
  if (from_unit_size != 1 || to_unit_size != 1)                                 Line 1314
    val = (val * from_unit_size) / to_unit_size;                                Line 1315
                                                                                
  *result = val;                                                                Line 1317
                                                                                
  return (e == SSE_OK || e == SSE_OK_PRECISION_LOSS);                           Line 1319
}                                                                               Block 44
                                                                                
/* Return a pointer to the beginning of the next field in line.                 
   The line pointer is moved to the end of the next field. */                   
static char*                                                                    Line 1324
next_field (char **line)                                                        Line 1325
{                                                                               
  char *field_start = *line;                                                    Line 1327
  char *field_end   = field_start;                                              Line 1328
                                                                                
  if (delimiter != DELIMITER_DEFAULT)                                           Line 1330
    {                                                                           
      if (*field_start != delimiter)                                            Line 1332
        {                                                                       
          while (*field_end && *field_end != delimiter)                         Line 1334
            ++field_end;                                                        Line 1335
        }                                                                       
      /* else empty field */                                                    
    }                                                                           
  else                                                                          Line 1339
    {                                                                           
      /* keep any space prefix in the returned field */                         
      while (*field_end && field_sep (*field_end))                              Line 1342
        ++field_end;                                                            Line 1343
                                                                                
      while (*field_end && ! field_sep (*field_end))                            Line 1345
        ++field_end;                                                            Line 1346
    }                                                                           
                                                                                
  *line = field_end;                                                            Line 1349
  return field_start;                                                           Line 1350
}                                                                               Block 45
                                                                                
static bool _GL_ATTRIBUTE_PURE                                                  Line 1353
include_field (uintmax_t field)                                                 Line 1354
{                                                                               
  struct field_range_pair *p = frp;                                             Line 1356
  if (!p)                                                                       Line 1357
    return field == 1;                                                          Line 1358
                                                                                
  while (p->lo != UINTMAX_MAX)                                                  Line 1360
    {                                                                           
      if (p->lo <= field && p->hi >= field)                                     Line 1362
        return true;                                                            Line 1363
      ++p;                                                                      Line 1364
    }                                                                           
  return false;                                                                 Line 1366
}                                                                               Block 46
                                                                                
/* Convert and output the given field. If it is not included in the set         
   of fields to process just output the original */                             
static bool                                                                     Line 1371
process_field (char *text, uintmax_t field)                                     Line 1372
{                                                                               
  long double val = 0;                                                          Line 1374
  size_t precision = 0;                                                         Line 1375
  bool valid_number = true;                                                     Line 1376
                                                                                
  if (include_field (field))                                                    Line 1378
    {                                                                           
      valid_number =                                                            Line 1380
        process_suffixed_number (text, &val, &precision, field);                Line 1381
                                                                                
      if (valid_number)                                                         Line 1383
        valid_number = prepare_padded_number (val, precision);                  Line 1384
                                                                                
      if (valid_number)                                                         Line 1386
        print_padded_number ();                                                 Line 1387
      else                                                                      Line 1388
        fputs (text, stdout);                                                   Line 1389
    }                                                                           
  else                                                                          Line 1391
    fputs (text, stdout);                                                       Line 1392
                                                                                
  return valid_number;                                                          Line 1394
}                                                                               Block 47
                                                                                
/* Convert number in a given line of text.                                      
   NEWLINE specifies whether to output a '\n' for this "line".  */              
static int                                                                      Line 1399
process_line (char *line, bool newline)                                         Line 1400
{                                                                               
  char *next;                                                                   Line 1402
  uintmax_t field = 0;                                                          Line 1403
  bool valid_number = true;                                                     Line 1404
                                                                                
  while (true) {                                                                Line 1406
    ++field;                                                                    Line 1407
    next = next_field (&line);                                                  Line 1408
                                                                                
    if (*line != '\0')                                                          Line 1410
      {                                                                         
        /* nul terminate the current field string and process */                
        *line = '\0';                                                           Line 1413
                                                                                
        if (! process_field (next, field))                                      Line 1415
          valid_number = false;                                                 Line 1416
                                                                                
        fputc ((delimiter == DELIMITER_DEFAULT) ?                               Line 1418
               ' ' : delimiter, stdout);                                        Line 1419
        ++line;                                                                 Line 1420
      }                                                                         
    else                                                                        Line 1422
      {                                                                         
        /* end of the line, process the last field and finish */                
        if (! process_field (next, field))                                      Line 1425
          valid_number = false;                                                 Line 1426
                                                                                
        break;                                                                  Line 1428
      }                                                                         
  }                                                                             
                                                                                
  if (newline)                                                                  Line 1432
    putchar (line_delim);                                                       Line 1433
                                                                                
  return valid_number;                                                          Line 1435
}                                                                               Block 48
                                                                                
int                                                                             
main (int argc, char **argv)                                                    Line 1439
{                                                                               
  int valid_numbers = 1;                                                        Line 1441
  bool locale_ok;                                                               Line 1442
                                                                                
  initialize_main (&argc, &argv);                                               VMS-specific entry point handling wildcard expansion
  set_program_name (argv[0]);                                                   Retains program name and discards path
  locale_ok = !!setlocale (LC_ALL, "");                                         Sets up internationalization (i18n)
  bindtextdomain (PACKAGE, LOCALEDIR);                                          Assigns i18n directorySets text domain for _() [gettext()] function
  textdomain (PACKAGE);                                                         Sets text domain for _() [gettext()] function
                                                                                
#if HAVE_FPSETPREC                                                              Line 1450
  /* Enabled extended precision if needed.  */                                  
  fpsetprec (FP_PE);                                                            Line 1452
#endif                                                                          Line 1453
                                                                                
  decimal_point = nl_langinfo (RADIXCHAR);                                      Line 1455
  if (decimal_point == NULL || strlen (decimal_point) == 0)                     Line 1456
    decimal_point = ".";                                                        Line 1457
  decimal_point_length = strlen (decimal_point);                                Line 1458
                                                                                
  atexit (close_stdout);                                                        Close stdout on exit (see gnulib)
                                                                                
  while (true)                                                                  Line 1462
    {                                                                           
      int c = getopt_long (argc, argv, "d:z", longopts, NULL);                  Line 1464
                                                                                
      if (c == -1)                                                              Line 1466
        break;                                                                  Line 1467
                                                                                
      switch (c)                                                                Line 1469
        {                                                                       
        case FROM_OPTION:                                                       Line 1471
          scale_from = XARGMATCH ("--from", optarg,                             Line 1472
                                  scale_from_args, scale_from_types);           Line 1473
          break;                                                                Line 1474
                                                                                
        case FROM_UNIT_OPTION:                                                  Line 1476
          from_unit_size = unit_to_umax (optarg);                               Line 1477
          break;                                                                Line 1478
                                                                                
        case TO_OPTION:                                                         Line 1480
          scale_to =                                                            Line 1481
            XARGMATCH ("--to", optarg, scale_to_args, scale_to_types);          Line 1482
          break;                                                                Line 1483
                                                                                
        case TO_UNIT_OPTION:                                                    Line 1485
          to_unit_size = unit_to_umax (optarg);                                 Line 1486
          break;                                                                Line 1487
                                                                                
        case ROUND_OPTION:                                                      Line 1489
          round_style = XARGMATCH ("--round", optarg, round_args, round_types); Line 1490
          break;                                                                Line 1491
                                                                                
        case GROUPING_OPTION:                                                   Line 1493
          grouping = 1;                                                         Line 1494
          break;                                                                Line 1495
                                                                                
        case PADDING_OPTION:                                                    Line 1497
          if (xstrtol (optarg, NULL, 10, &padding_width, "") != LONGINT_OK      Line 1498
              || padding_width == 0)                                            Line 1499
            die (EXIT_FAILURE, 0, _("invalid padding value %s"),                Line 1500
                 quote (optarg));                                               Line 1501
          if (padding_width < 0)                                                Line 1502
            {                                                                   
              padding_alignment = MBS_ALIGN_LEFT;                               Line 1504
              padding_width = -padding_width;                                   Line 1505
            }                                                                   
          /* TODO: We probably want to apply a specific --padding               
             to --header lines too.  */                                         
          break;                                                                Line 1509
                                                                                
        case FIELD_OPTION:                                                      Line 1511
          if (n_frp)                                                            Line 1512
            die (EXIT_FAILURE, 0, _("multiple field specifications"));          Line 1513
          set_fields (optarg, SETFLD_ALLOW_DASH);                               Line 1514
          break;                                                                Line 1515
                                                                                
        case 'd':                                                               Line 1517
          /* Interpret -d '' to mean 'use the NUL byte as the delimiter.'  */   
          if (optarg[0] != '\0' && optarg[1] != '\0')                           Line 1519
            die (EXIT_FAILURE, 0,                                               Line 1520
                 _("the delimiter must be a single character"));                Line 1521
          delimiter = optarg[0];                                                Line 1522
          break;                                                                Line 1523
                                                                                
        case 'z':                                                               Line 1525
          line_delim = '\0';                                                    Line 1526
          break;                                                                Line 1527
                                                                                
        case SUFFIX_OPTION:                                                     Line 1529
          suffix = optarg;                                                      Line 1530
          break;                                                                Line 1531
                                                                                
        case DEBUG_OPTION:                                                      Line 1533
          debug = true;                                                         Line 1534
          break;                                                                Line 1535
                                                                                
        case DEV_DEBUG_OPTION:                                                  Line 1537
          dev_debug = true;                                                     Line 1538
          debug = true;                                                         Line 1539
          break;                                                                Line 1540
                                                                                
        case HEADER_OPTION:                                                     Line 1542
          if (optarg)                                                           Line 1543
            {                                                                   
              if (xstrtoumax (optarg, NULL, 10, &header, "") != LONGINT_OK      Line 1545
                  || header == 0)                                               Line 1546
                die (EXIT_FAILURE, 0, _("invalid header value %s"),             Line 1547
                     quote (optarg));                                           Line 1548
            }                                                                   
          else                                                                  Line 1550
            {                                                                   
              header = 1;                                                       Line 1552
            }                                                                   
          break;                                                                Line 1554
                                                                                
        case FORMAT_OPTION:                                                     Line 1556
          format_str = optarg;                                                  Line 1557
          break;                                                                Line 1558
                                                                                
        case INVALID_OPTION:                                                    Line 1560
          inval_style = XARGMATCH ("--invalid", optarg,                         Line 1561
                                   inval_args, inval_types);                    Line 1562
          break;                                                                Line 1563
                                                                                
          case_GETOPT_HELP_CHAR;                                                Line 1565
          case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);                     Line 1566
                                                                                
        default:                                                                Line 1568
          usage (EXIT_FAILURE);                                                 Line 1569
        }                                                                       
    }                                                                           
                                                                                
  if (format_str != NULL && grouping)                                           Line 1573
    die (EXIT_FAILURE, 0, _("--grouping cannot be combined with --format"));    Line 1574
                                                                                
  if (debug && ! locale_ok)                                                     Line 1576
    error (0, 0, _("failed to set locale"));                                    Line 1577
                                                                                
  /* Warn about no-op.  */                                                      
  if (debug && scale_from == scale_none && scale_to == scale_none               Line 1580
      && !grouping && (padding_width == 0) && (format_str == NULL))             Line 1581
    error (0, 0, _("no conversion option specified"));                          Line 1582
                                                                                
  if (format_str)                                                               Line 1584
    parse_format_string (format_str);                                           Line 1585
                                                                                
  if (grouping)                                                                 Line 1587
    {                                                                           
      if (scale_to != scale_none)                                               Line 1589
        die (EXIT_FAILURE, 0, _("grouping cannot be combined with --to"));      Line 1590
      if (debug && (strlen (nl_langinfo (THOUSEP)) == 0))                       Line 1591
        error (0, 0, _("grouping has no effect in this locale"));               Line 1592
    }                                                                           
                                                                                
                                                                                
  setup_padding_buffer (padding_width);                                         Line 1596
  auto_padding = (padding_width == 0 && delimiter == DELIMITER_DEFAULT);        Line 1597
                                                                                
  if (inval_style != inval_abort)                                               ...!common auto-comment...
    conv_exit_code = 0;                                                         Line 1600
                                                                                
  if (argc > optind)                                                            Line 1602
    {                                                                           
      if (debug && header)                                                      Line 1604
        error (0, 0, _("--header ignored with command-line input"));            Line 1605
                                                                                
      for (; optind < argc; optind++)                                           Line 1607
        valid_numbers &= process_line (argv[optind], true);                     Line 1608
    }                                                                           
  else                                                                          Line 1610
    {                                                                           
      char *line = NULL;                                                        Line 1612
      size_t line_allocated = 0;                                                Line 1613
      ssize_t len;                                                              Line 1614
                                                                                
      while (header-- && getdelim (&line, &line_allocated,                      Line 1616
                                   line_delim, stdin) > 0)                      Line 1617
        fputs (line, stdout);                                                   Line 1618
                                                                                
      while ((len = getdelim (&line, &line_allocated,                           Line 1620
                              line_delim, stdin)) > 0)                          Line 1621
        {                                                                       
          bool newline = line[len - 1] == line_delim;                           Line 1623
          if (newline)                                                          Line 1624
            line[len - 1] = '\0';                                               Line 1625
          valid_numbers &= process_line (line, newline);                        Line 1626
        }                                                                       
                                                                                
      IF_LINT (free (line));                                                    Line 1629
                                                                                
      if (ferror (stdin))                                                       Line 1631
        error (0, errno, _("error reading input"));                             Line 1632
    }                                                                           
                                                                                
#ifdef lint                                                                     Line 1635
  free (padding_buffer);                                                        Line 1636
  free (format_str_prefix);                                                     Line 1637
  free (format_str_suffix);                                                     Line 1638
  reset_fields ();                                                              Line 1639
#endif                                                                          Line 1640
                                                                                
  if (debug && !valid_numbers)                                                  Line 1642
    error (0, 0, _("failed to convert some of the input numbers"));             Line 1643
                                                                                
  int exit_status = EXIT_SUCCESS;                                               Line 1645
  if (!valid_numbers                                                            Line 1646
      && inval_style != inval_warn && inval_style != inval_ignore)              Line 1647
    exit_status = EXIT_CONVERSION_WARNINGS;                                     Line 1648
                                                                                
  return exit_status;                                                           Line 1650
}                                                                               Block 49