/* od -- dump files in octal and other formats                                  This is the od utility
   Copyright (C) 1992-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
                                                                                
/* Written by Jim Meyering.  */                                                 
                                                                                
#include <config.h>                                                             Provides system specific information
                                                                                
#include <stdio.h>                                                              Provides standard I/O capability
#include <assert.h>                                                             ...!includes auto-comment...
#include <getopt.h>                                                             ...!includes auto-comment...
#include <sys/types.h>                                                          Provides system data types
#include "system.h"                                                             ...!includes auto-comment...
#include "argmatch.h"                                                           ...!includes auto-comment...
#include "die.h"                                                                ...!includes auto-comment...
#include "error.h"                                                              ...!includes auto-comment...
#include "ftoastr.h"                                                            ...!includes auto-comment...
#include "quote.h"                                                              ...!includes auto-comment...
#include "stat-size.h"                                                          ...!includes auto-comment...
#include "xbinary-io.h"                                                         ...!includes auto-comment...
#include "xprintf.h"                                                            ...!includes auto-comment...
#include "xstrtol.h"                                                            ...!includes auto-comment...
                                                                                
/* The official name of this program (e.g., no 'g' prefix).  */                 
#define PROGRAM_NAME "od"                                                       Line 37
                                                                                
#define AUTHORS proper_name ("Jim Meyering")                                    Line 39
                                                                                
/* The default number of input bytes per output line.  */                       
#define DEFAULT_BYTES_PER_BLOCK 16                                              Line 42
                                                                                
#if HAVE_UNSIGNED_LONG_LONG_INT                                                 Line 44
typedef unsigned long long int unsigned_long_long_int;                          Line 45
#else                                                                           Line 46
/* This is just a place-holder to avoid a few '#if' directives.                 
   In this case, the type isn't actually used.  */                              
typedef unsigned long int unsigned_long_long_int;                               Line 49
#endif                                                                          Line 50
                                                                                
enum size_spec                                                                  Line 52
  {                                                                             
    NO_SIZE,                                                                    Line 54
    CHAR,                                                                       Line 55
    SHORT,                                                                      Line 56
    INT,                                                                        Line 57
    LONG,                                                                       Line 58
    LONG_LONG,                                                                  Line 59
    /* FIXME: add INTMAX support, too */                                        
    FLOAT_SINGLE,                                                               Line 61
    FLOAT_DOUBLE,                                                               Line 62
    FLOAT_LONG_DOUBLE,                                                          Line 63
    N_SIZE_SPECS                                                                Line 64
  };                                                                            Block 1
                                                                                
enum output_format                                                              Line 67
  {                                                                             
    SIGNED_DECIMAL,                                                             Line 69
    UNSIGNED_DECIMAL,                                                           Line 70
    OCTAL,                                                                      Line 71
    HEXADECIMAL,                                                                Line 72
    FLOATING_POINT,                                                             Line 73
    NAMED_CHARACTER,                                                            Line 74
    CHARACTER                                                                   Line 75
  };                                                                            Block 2
                                                                                
#define MAX_INTEGRAL_TYPE_SIZE sizeof (unsigned_long_long_int)                  Line 78
                                                                                
/* The maximum number of bytes needed for a format string, including            
   the trailing nul.  Each format string expects a variable amount of           
   padding (guaranteed to be at least 1 plus the field width), then an          
   element that will be formatted in the field.  */                             
enum                                                                            Line 84
  {                                                                             
    FMT_BYTES_ALLOCATED =                                                       Line 86
           (sizeof "%*.99" - 1                                                  Line 87
            + MAX (sizeof "ld",                                                 Line 88
                   MAX (sizeof PRIdMAX,                                         Line 89
                        MAX (sizeof PRIoMAX,                                    Line 90
                             MAX (sizeof PRIuMAX,                               Line 91
                                  sizeof PRIxMAX)))))                           Line 92
  };                                                                            Block 3
                                                                                
/* Ensure that our choice for FMT_BYTES_ALLOCATED is reasonable.  */            
verify (MAX_INTEGRAL_TYPE_SIZE * CHAR_BIT / 3 <= 99);                           Line 96
                                                                                
/* Each output format specification (from '-t spec' or from                     
   old-style options) is represented by one of these structures.  */            
struct tspec                                                                    Line 100
  {                                                                             
    enum output_format fmt;                                                     Line 102
    enum size_spec size; /* Type of input object.  */                           Line 103
    /* FIELDS is the number of fields per line, BLANK is the number of          
       fields to leave blank.  WIDTH is width of one field, excluding           
       leading space, and PAD is total pad to divide among FIELDS.              
       PAD is at least as large as FIELDS.  */                                  
    void (*print_function) (size_t fields, size_t blank, void const *data,      Line 108
                            char const *fmt, int width, int pad);               Line 109
    char fmt_string[FMT_BYTES_ALLOCATED]; /* Of the style "%*d".  */            Line 110
    bool hexl_mode_trailer;                                                     Line 111
    int field_width; /* Minimum width of a field, excluding leading space.  */  Line 112
    int pad_width; /* Total padding to be divided among fields.  */             Line 113
  };                                                                            Block 4
                                                                                
/* Convert the number of 8-bit bytes of a binary representation to              
   the number of characters (digits + sign if the type is signed)               
   required to represent the same quantity in the specified base/type.          
   For example, a 32-bit (4-byte) quantity may require a field width            
   as wide as the following for these types:                                    
   11 unsigned octal                                                            
   11 signed decimal                                                            
   10 unsigned decimal                                                          
   8 unsigned hexadecimal  */                                                   
                                                                                
static unsigned int const bytes_to_oct_digits[] =                               Line 126
{0, 3, 6, 8, 11, 14, 16, 19, 22, 25, 27, 30, 32, 35, 38, 41, 43};               Line 127
                                                                                
static unsigned int const bytes_to_signed_dec_digits[] =                        Line 129
{1, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 28, 30, 33, 35, 37, 40};               Line 130
                                                                                
static unsigned int const bytes_to_unsigned_dec_digits[] =                      Line 132
{0, 3, 5, 8, 10, 13, 15, 17, 20, 22, 25, 27, 29, 32, 34, 37, 39};               Line 133
                                                                                
static unsigned int const bytes_to_hex_digits[] =                               Line 135
{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32};                Line 136
                                                                                
/* It'll be a while before we see integral types wider than 16 bytes,           
   but if/when it happens, this check will catch it.  Without this check,       
   a wider type would provoke a buffer overrun.  */                             
verify (MAX_INTEGRAL_TYPE_SIZE < ARRAY_CARDINALITY (bytes_to_hex_digits));      Line 141
                                                                                
/* Make sure the other arrays have the same length.  */                         
verify (sizeof bytes_to_oct_digits == sizeof bytes_to_signed_dec_digits);       Line 144
verify (sizeof bytes_to_oct_digits == sizeof bytes_to_unsigned_dec_digits);     Line 145
verify (sizeof bytes_to_oct_digits == sizeof bytes_to_hex_digits);              Line 146
                                                                                
/* Convert enum size_spec to the size of the named type.  */                    
static const int width_bytes[] =                                                Line 149
{                                                                               
  -1,                                                                           
  sizeof (char),                                                                Line 152
  sizeof (short int),                                                           Line 153
  sizeof (int),                                                                 Line 154
  sizeof (long int),                                                            Line 155
  sizeof (unsigned_long_long_int),                                              Line 156
  sizeof (float),                                                               Line 157
  sizeof (double),                                                              Line 158
  sizeof (long double)                                                          Line 159
};                                                                              
                                                                                
/* Ensure that for each member of 'enum size_spec' there is an                  
   initializer in the width_bytes array.  */                                    
verify (ARRAY_CARDINALITY (width_bytes) == N_SIZE_SPECS);                       Line 164
                                                                                
/* Names for some non-printing characters.  */                                  
static char const charname[33][4] =                                             Line 167
{                                                                               
  "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",                       Line 169
  "bs", "ht", "nl", "vt", "ff", "cr", "so", "si",                               Line 170
  "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",                       Line 171
  "can", "em", "sub", "esc", "fs", "gs", "rs", "us",                            Line 172
  "sp"                                                                          Line 173
};                                                                              Block 10
                                                                                
/* Address base (8, 10 or 16).  */                                              
static int address_base;                                                        Line 177
                                                                                
/* The number of octal digits required to represent the largest                 
   address value.  */                                                           
#define MAX_ADDRESS_LENGTH \                                                    Line 181
  ((sizeof (uintmax_t) * CHAR_BIT + CHAR_BIT - 1) / 3)                          Line 182
                                                                                
/* Width of a normal address.  */                                               
static int address_pad_len;                                                     Line 185
                                                                                
/* Minimum length when detecting --strings.  */                                 
static size_t string_min;                                                       Line 188
                                                                                
/* True when in --strings mode.  */                                             
static bool flag_dump_strings;                                                  Line 191
                                                                                
/* True if we should recognize the older non-option arguments                   
   that specified at most one file and optional arguments specifying            
   offset and pseudo-start address.  */                                         
static bool traditional;                                                        Line 196
                                                                                
/* True if an old-style 'pseudo-address' was specified.  */                     
static bool flag_pseudo_start;                                                  Line 199
                                                                                
/* The difference between the old-style pseudo starting address and             
   the number of bytes to skip.  */                                             
static uintmax_t pseudo_offset;                                                 Line 203
                                                                                
/* Function that accepts an address and an optional following char,             
   and prints the address and char to stdout.  */                               
static void (*format_address) (uintmax_t, char);                                Line 207
                                                                                
/* The number of input bytes to skip before formatting and writing.  */         
static uintmax_t n_bytes_to_skip = 0;                                           Line 210
                                                                                
/* When false, MAX_BYTES_TO_FORMAT and END_OFFSET are ignored, and all          
   input is formatted.  */                                                      
static bool limit_bytes_to_format = false;                                      Line 214
                                                                                
/* The maximum number of bytes that will be formatted.  */                      
static uintmax_t max_bytes_to_format;                                           Line 217
                                                                                
/* The offset of the first byte after the last byte to be formatted.  */        
static uintmax_t end_offset;                                                    Line 220
                                                                                
/* When true and two or more consecutive blocks are equal, format               
   only the first block and output an asterisk alone on the following           
   line to indicate that identical blocks have been elided.  */                 
static bool abbreviate_duplicate_blocks = true;                                 Line 225
                                                                                
/* An array of specs describing how to format each input block.  */             
static struct tspec *spec;                                                      Line 228
                                                                                
/* The number of format specs.  */                                              
static size_t n_specs;                                                          Line 231
                                                                                
/* The allocated length of SPEC.  */                                            
static size_t n_specs_allocated;                                                Line 234
                                                                                
/* The number of input bytes formatted per output line.  It must be             
   a multiple of the least common multiple of the sizes associated with         
   the specified output types.  It should be as large as possible, but          
   no larger than 16 -- unless specified with the -w option.  */                
static size_t bytes_per_block;                                                  Line 240
                                                                                
/* Human-readable representation of *file_list (for error messages).            
   It differs from file_list[-1] only when file_list[-1] is "-".  */            
static char const *input_filename;                                              Line 244
                                                                                
/* A NULL-terminated list of the file-arguments from the command line.  */      
static char const *const *file_list;                                            Line 247
                                                                                
/* Initializer for file_list if no file-arguments                               
   were specified on the command line.  */                                      
static char const *const default_file_list[] = {"-", NULL};                     Line 251
                                                                                
/* The input stream associated with the current file.  */                       
static FILE *in_stream;                                                         Line 254
                                                                                
/* If true, at least one of the files we read was standard input.  */           
static bool have_read_stdin;                                                    Line 257
                                                                                
/* Map the size in bytes to a type identifier.  */                              
static enum size_spec integral_type_size[MAX_INTEGRAL_TYPE_SIZE + 1];           Line 260
                                                                                
#define MAX_FP_TYPE_SIZE sizeof (long double)                                   Line 262
static enum size_spec fp_type_size[MAX_FP_TYPE_SIZE + 1];                       Line 263
                                                                                
#ifndef WORDS_BIGENDIAN                                                         Line 265
# define WORDS_BIGENDIAN 0                                                      Line 266
#endif                                                                          Line 267
                                                                                
/* Use native endianess by default.  */                                         
static bool input_swap;                                                         Line 270
                                                                                
static char const short_options[] = "A:aBbcDdeFfHhIij:LlN:OoS:st:vw::Xx";       Line 272
                                                                                
/* For long options that have no equivalent short option, use a                 
   non-character as a pseudo short option, starting with CHAR_MAX + 1.  */      
enum                                                                            Line 276
{                                                                               
  TRADITIONAL_OPTION = CHAR_MAX + 1,                                            Line 278
  ENDIAN_OPTION,                                                                Line 279
};                                                                              Block 12
                                                                                
enum endian_type                                                                Line 282
{                                                                               
  endian_little,                                                                Line 284
  endian_big                                                                    Line 285
};                                                                              Block 13
                                                                                
static char const *const endian_args[] =                                        Line 288
{                                                                               
  "little", "big", NULL                                                         Line 290
};                                                                              Block 14
                                                                                
static enum endian_type const endian_types[] =                                  Line 293
{                                                                               
  endian_little, endian_big                                                     Line 295
};                                                                              Block 15
                                                                                
static struct option const long_options[] =                                     Line 298
{                                                                               
  {"skip-bytes", required_argument, NULL, 'j'},                                 Line 300
  {"address-radix", required_argument, NULL, 'A'},                              Line 301
  {"read-bytes", required_argument, NULL, 'N'},                                 Line 302
  {"format", required_argument, NULL, 't'},                                     Line 303
  {"output-duplicates", no_argument, NULL, 'v'},                                Line 304
  {"strings", optional_argument, NULL, 'S'},                                    Line 305
  {"traditional", no_argument, NULL, TRADITIONAL_OPTION},                       Line 306
  {"width", optional_argument, NULL, 'w'},                                      Line 307
  {"endian", required_argument, NULL, ENDIAN_OPTION },                          Line 308
                                                                                
  {GETOPT_HELP_OPTION_DECL},                                                    Line 310
  {GETOPT_VERSION_OPTION_DECL},                                                 Line 311
  {NULL, 0, NULL, 0}                                                            Line 312
};                                                                              Block 16
                                                                                
void                                                                            Line 315
usage (int status)                                                              Line 316
{                                                                               
  if (status != EXIT_SUCCESS)                                                   Line 318
    emit_try_help ();                                                           ...!common auto-comment...
  else                                                                          Line 320
    {                                                                           
      printf (_("\                                                              Line 322
Usage: %s [OPTION]... [FILE]...\n\                                              Line 323
  or:  %s [-abcdfilosx]... [FILE] [[+]OFFSET[.][b]]\n\                          Line 324
  or:  %s --traditional [OPTION]... [FILE] [[+]OFFSET[.][b] [+][LABEL][.][b]]\n\Line 325
"),                                                                             Line 326
              program_name, program_name, program_name);                        Line 327
      fputs (_("\n\                                                             Line 328
Write an unambiguous representation, octal bytes by default,\n\                 Line 329
of FILE to standard output.  With more than one FILE argument,\n\               Line 330
concatenate them in the listed order to form the input.\n\                      Line 331
"), stdout);                                                                    Line 332
                                                                                
      emit_stdin_note ();                                                       ...!common auto-comment...
                                                                                
      fputs (_("\                                                               Line 336
\n\                                                                             
If first and second call formats both apply, the second format is assumed\n\    Line 338
if the last operand begins with + or (if there are 2 operands) a digit.\n\      Line 339
An OFFSET operand means -j OFFSET.  LABEL is the pseudo-address\n\              Line 340
at first byte printed, incremented when dump is progressing.\n\                 Line 341
For OFFSET and LABEL, a 0x or 0X prefix indicates hexadecimal;\n\               Line 342
suffixes may be . for octal and b for multiply by 512.\n\                       Line 343
"), stdout);                                                                    Line 344
                                                                                
      emit_mandatory_arg_note ();                                               ...!common auto-comment...
                                                                                
      fputs (_("\                                                               Line 348
  -A, --address-radix=RADIX   output format for file offsets; RADIX is one\n\   Line 349
                                of [doxn], for Decimal, Octal, Hex or None\n\   Line 350
      --endian={big|little}   swap input bytes according the specified order\n\ Line 351
  -j, --skip-bytes=BYTES      skip BYTES input bytes first\n\                   Line 352
"), stdout);                                                                    Line 353
      fputs (_("\                                                               Line 354
  -N, --read-bytes=BYTES      limit dump to BYTES input bytes\n\                Line 355
  -S BYTES, --strings[=BYTES]  output strings of at least BYTES graphic chars;\ Line 356
\n\                                                                             
                                3 is implied when BYTES is not specified\n\     Line 358
  -t, --format=TYPE           select output format or formats\n\                Line 359
  -v, --output-duplicates     do not use * to mark line suppression\n\          Line 360
  -w[BYTES], --width[=BYTES]  output BYTES bytes per output line;\n\            Line 361
                                32 is implied when BYTES is not specified\n\    Line 362
      --traditional           accept arguments in third form above\n\           Line 363
"), stdout);                                                                    Line 364
      fputs (HELP_OPTION_DESCRIPTION, stdout);                                  Line 365
      fputs (VERSION_OPTION_DESCRIPTION, stdout);                               Line 366
      fputs (_("\                                                               Line 367
\n\                                                                             
\n\                                                                             
Traditional format specifications may be intermixed; they accumulate:\n\        Line 370
  -a   same as -t a,  select named characters, ignoring high-order bit\n\       Line 371
  -b   same as -t o1, select octal bytes\n\                                     Line 372
  -c   same as -t c,  select printable characters or backslash escapes\n\       Line 373
  -d   same as -t u2, select unsigned decimal 2-byte units\n\                   Line 374
"), stdout);                                                                    Line 375
      fputs (_("\                                                               Line 376
  -f   same as -t fF, select floats\n\                                          Line 377
  -i   same as -t dI, select decimal ints\n\                                    Line 378
  -l   same as -t dL, select decimal longs\n\                                   Line 379
  -o   same as -t o2, select octal 2-byte units\n\                              Line 380
  -s   same as -t d2, select decimal 2-byte units\n\                            Line 381
  -x   same as -t x2, select hexadecimal 2-byte units\n\                        Line 382
"), stdout);                                                                    Line 383
      fputs (_("\                                                               Line 384
\n\                                                                             
\n\                                                                             
TYPE is made up of one or more of these specifications:\n\                      Line 387
  a          named character, ignoring high-order bit\n\                        Line 388
  c          printable character or backslash escape\n\                         Line 389
"), stdout);                                                                    Line 390
      fputs (_("\                                                               Line 391
  d[SIZE]    signed decimal, SIZE bytes per integer\n\                          Line 392
  f[SIZE]    floating point, SIZE bytes per float\n\                            Line 393
  o[SIZE]    octal, SIZE bytes per integer\n\                                   Line 394
  u[SIZE]    unsigned decimal, SIZE bytes per integer\n\                        Line 395
  x[SIZE]    hexadecimal, SIZE bytes per integer\n\                             Line 396
"), stdout);                                                                    Line 397
      fputs (_("\                                                               Line 398
\n\                                                                             
SIZE is a number.  For TYPE in [doux], SIZE may also be C for\n\                Line 400
sizeof(char), S for sizeof(short), I for sizeof(int) or L for\n\                Line 401
sizeof(long).  If TYPE is f, SIZE may also be F for sizeof(float), D\n\         Line 402
for sizeof(double) or L for sizeof(long double).\n\                             Line 403
"), stdout);                                                                    Line 404
      fputs (_("\                                                               Line 405
\n\                                                                             
Adding a z suffix to any type displays printable characters at the end of\n\    Line 407
each output line.\n\                                                            Line 408
"), stdout);                                                                    Line 409
      fputs (_("\                                                               Line 410
\n\                                                                             
\n\                                                                             
BYTES is hex with 0x or 0X prefix, and may have a multiplier suffix:\n\         Line 413
  b    512\n\                                                                   Line 414
  KB   1000\n\                                                                  Line 415
  K    1024\n\                                                                  Line 416
  MB   1000*1000\n\                                                             Line 417
  M    1024*1024\n\                                                             Line 418
and so on for G, T, P, E, Z, Y.\n\                                              Line 419
Binary prefixes can be used, too: KiB=K, MiB=M, and so on.\n\                   Line 420
"), stdout);                                                                    Line 421
      emit_ancillary_info (PROGRAM_NAME);                                       Line 422
    }                                                                           
  exit (status);                                                                Line 424
}                                                                               Block 17
                                                                                
/* Define the print functions.  */                                              
                                                                                
#define PRINT_FIELDS(N, T, FMT_STRING, ACTION)                          \       Line 429
static void                                                             \       Line 430
N (size_t fields, size_t blank, void const *block,                      \       Line 431
   char const *FMT_STRING, int width, int pad)                          \       Line 432
{                                                                       \       Line 433
  T const *p = block;                                                   \       Line 434
  uintmax_t i;                                                          \       Line 435
  int pad_remaining = pad;                                              \       Line 436
  for (i = fields; blank < i; i--)                                      \       Line 437
    {                                                                   \       Line 438
      int next_pad = pad * (i - 1) / fields;                            \       Line 439
      int adjusted_width = pad_remaining - next_pad + width;            \       Line 440
      T x;                                                              \       Line 441
      if (input_swap && sizeof (T) > 1)                                 \       Line 442
        {                                                               \       Line 443
          size_t j;                                                     \       Line 444
          union {                                                       \       Line 445
            T x;                                                        \       Line 446
            char b[sizeof (T)];                                         \       Line 447
          } u;                                                          \       Line 448
          for (j = 0; j < sizeof (T); j++)                              \       Line 449
            u.b[j] = ((const char *) p)[sizeof (T) - 1 - j];            \       Line 450
          x = u.x;                                                      \       Line 451
        }                                                               \       Line 452
      else                                                              \       Line 453
        x = *p;                                                         \       Line 454
      p++;                                                              \       Line 455
      ACTION;                                                           \       Line 456
      pad_remaining = next_pad;                                         \       Line 457
    }                                                                   \       Line 458
}                                                                               Block 18
                                                                                
#define PRINT_TYPE(N, T)                                                \       Line 461
  PRINT_FIELDS (N, T, fmt_string, xprintf (fmt_string, adjusted_width, x))      Line 462
                                                                                
#define PRINT_FLOATTYPE(N, T, FTOASTR, BUFSIZE)                         \       Line 464
  PRINT_FIELDS (N, T, fmt_string _GL_UNUSED,                      \             Line 465
                char buf[BUFSIZE];                                      \       Line 466
                FTOASTR (buf, sizeof buf, 0, 0, x);                     \       Line 467
                xprintf ("%*s", adjusted_width, buf))                           Line 468
                                                                                
PRINT_TYPE (print_s_char, signed char)                                          Line 470
PRINT_TYPE (print_char, unsigned char)                                          Line 471
PRINT_TYPE (print_s_short, short int)                                           Line 472
PRINT_TYPE (print_short, unsigned short int)                                    Line 473
PRINT_TYPE (print_int, unsigned int)                                            Line 474
PRINT_TYPE (print_long, unsigned long int)                                      Line 475
PRINT_TYPE (print_long_long, unsigned_long_long_int)                            Line 476
                                                                                
PRINT_FLOATTYPE (print_float, float, ftoastr, FLT_BUFSIZE_BOUND)                Line 478
PRINT_FLOATTYPE (print_double, double, dtoastr, DBL_BUFSIZE_BOUND)              Line 479
PRINT_FLOATTYPE (print_long_double, long double, ldtoastr, LDBL_BUFSIZE_BOUND)  Line 480
                                                                                
#undef PRINT_TYPE                                                               Line 482
#undef PRINT_FLOATTYPE                                                          Line 483
                                                                                
static void                                                                     Line 485
dump_hexl_mode_trailer (size_t n_bytes, const char *block)                      Line 486
{                                                                               
  fputs ("  >", stdout);                                                        Line 488
  for (size_t i = n_bytes; i > 0; i--)                                          Line 489
    {                                                                           
      unsigned char c = *block++;                                               Line 491
      unsigned char c2 = (isprint (c) ? c : '.');                               Line 492
      putchar (c2);                                                             Line 493
    }                                                                           
  putchar ('<');                                                                Line 495
}                                                                               Block 19
                                                                                
static void                                                                     Line 498
print_named_ascii (size_t fields, size_t blank, void const *block,              Line 499
                   const char *unused_fmt_string _GL_UNUSED,                    Line 500
                   int width, int pad)                                          Line 501
{                                                                               
  unsigned char const *p = block;                                               Line 503
  uintmax_t i;                                                                  Line 504
  int pad_remaining = pad;                                                      Line 505
  for (i = fields; blank < i; i--)                                              Line 506
    {                                                                           
      int next_pad = pad * (i - 1) / fields;                                    Line 508
      int masked_c = *p++ & 0x7f;                                               Line 509
      const char *s;                                                            Line 510
      char buf[2];                                                              Line 511
                                                                                
      if (masked_c == 127)                                                      Line 513
        s = "del";                                                              Line 514
      else if (masked_c <= 040)                                                 Line 515
        s = charname[masked_c];                                                 Line 516
      else                                                                      Line 517
        {                                                                       
          buf[0] = masked_c;                                                    Line 519
          buf[1] = 0;                                                           Line 520
          s = buf;                                                              Line 521
        }                                                                       
                                                                                
      xprintf ("%*s", pad_remaining - next_pad + width, s);                     Line 524
      pad_remaining = next_pad;                                                 Line 525
    }                                                                           
}                                                                               Block 20
                                                                                
static void                                                                     Line 529
print_ascii (size_t fields, size_t blank, void const *block,                    Line 530
             const char *unused_fmt_string _GL_UNUSED, int width,               Line 531
             int pad)                                                           Line 532
{                                                                               
  unsigned char const *p = block;                                               Line 534
  uintmax_t i;                                                                  Line 535
  int pad_remaining = pad;                                                      Line 536
  for (i = fields; blank < i; i--)                                              Line 537
    {                                                                           
      int next_pad = pad * (i - 1) / fields;                                    Line 539
      unsigned char c = *p++;                                                   Line 540
      const char *s;                                                            Line 541
      char buf[4];                                                              Line 542
                                                                                
      switch (c)                                                                Line 544
        {                                                                       
        case '\0':                                                              Line 546
          s = "\\0";                                                            Line 547
          break;                                                                Line 548
                                                                                
        case '\a':                                                              Line 550
          s = "\\a";                                                            Line 551
          break;                                                                Line 552
                                                                                
        case '\b':                                                              Line 554
          s = "\\b";                                                            Line 555
          break;                                                                Line 556
                                                                                
        case '\f':                                                              Line 558
          s = "\\f";                                                            Line 559
          break;                                                                Line 560
                                                                                
        case '\n':                                                              Line 562
          s = "\\n";                                                            Line 563
          break;                                                                Line 564
                                                                                
        case '\r':                                                              Line 566
          s = "\\r";                                                            Line 567
          break;                                                                Line 568
                                                                                
        case '\t':                                                              Line 570
          s = "\\t";                                                            Line 571
          break;                                                                Line 572
                                                                                
        case '\v':                                                              Line 574
          s = "\\v";                                                            Line 575
          break;                                                                Line 576
                                                                                
        default:                                                                Line 578
          sprintf (buf, (isprint (c) ? "%c" : "%03o"), c);                      Line 579
          s = buf;                                                              Line 580
        }                                                                       
                                                                                
      xprintf ("%*s", pad_remaining - next_pad + width, s);                     Line 583
      pad_remaining = next_pad;                                                 Line 584
    }                                                                           
}                                                                               Block 21
                                                                                
/* Convert a null-terminated (possibly zero-length) string S to an              
   unsigned long integer value.  If S points to a non-digit set *P to S,        
   *VAL to 0, and return true.  Otherwise, accumulate the integer value of      
   the string of digits.  If the string of digits represents a value            
   larger than ULONG_MAX, don't modify *VAL or *P and return false.             
   Otherwise, advance *P to the first non-digit after S, set *VAL to            
   the result of the conversion and return true.  */                            
                                                                                
static bool                                                                     Line 596
simple_strtoul (const char *s, const char **p, unsigned long int *val)          Line 597
{                                                                               
  unsigned long int sum;                                                        Line 599
                                                                                
  sum = 0;                                                                      Line 601
  while (ISDIGIT (*s))                                                          Line 602
    {                                                                           
      int c = *s++ - '0';                                                       Line 604
      if (sum > (ULONG_MAX - c) / 10)                                           Line 605
        return false;                                                           Line 606
      sum = sum * 10 + c;                                                       Line 607
    }                                                                           
  *p = s;                                                                       Line 609
  *val = sum;                                                                   Line 610
  return true;                                                                  Line 611
}                                                                               Block 22
                                                                                
/* If S points to a single valid modern od format string, put                   
   a description of that format in *TSPEC, make *NEXT point at the              
   character following the just-decoded format (if *NEXT is non-NULL),          
   and return true.  If S is not valid, don't modify *NEXT or *TSPEC,           
   give a diagnostic, and return false.  For example, if S were                 
   "d4afL" *NEXT would be set to "afL" and *TSPEC would be                      
     {                                                                          
       fmt = SIGNED_DECIMAL;                                                    
       size = INT or LONG; (whichever integral_type_size[4] resolves to)        
       print_function = print_int; (assuming size == INT)                       
       field_width = 11;                                                        
       fmt_string = "%*d";                                                      
      }                                                                         
   pad_width is determined later, but is at least as large as the               
   number of fields printed per row.                                            
   S_ORIG is solely for reporting errors.  It should be the full format         
   string argument.                                                             
   */                                                                           
                                                                                
static bool                                                                     Line 633
decode_one_format (const char *s_orig, const char *s, const char **next,        Line 634
                   struct tspec *tspec)                                         Line 635
{                                                                               
  enum size_spec size_spec;                                                     Line 637
  unsigned long int size;                                                       Line 638
  enum output_format fmt;                                                       Line 639
  void (*print_function) (size_t, size_t, void const *, char const *,           Line 640
                          int, int);                                            Line 641
  const char *p;                                                                Line 642
  char c;                                                                       Line 643
  int field_width;                                                              Line 644
                                                                                
  assert (tspec != NULL);                                                       Line 646
                                                                                
  switch (*s)                                                                   Line 648
    {                                                                           
    case 'd':                                                                   Line 650
    case 'o':                                                                   Line 651
    case 'u':                                                                   Line 652
    case 'x':                                                                   Line 653
      c = *s;                                                                   Line 654
      ++s;                                                                      Line 655
      switch (*s)                                                               Line 656
        {                                                                       
        case 'C':                                                               Line 658
          ++s;                                                                  Line 659
          size = sizeof (char);                                                 Line 660
          break;                                                                Line 661
                                                                                
        case 'S':                                                               Line 663
          ++s;                                                                  Line 664
          size = sizeof (short int);                                            Line 665
          break;                                                                Line 666
                                                                                
        case 'I':                                                               Line 668
          ++s;                                                                  Line 669
          size = sizeof (int);                                                  Line 670
          break;                                                                Line 671
                                                                                
        case 'L':                                                               Line 673
          ++s;                                                                  Line 674
          size = sizeof (long int);                                             Line 675
          break;                                                                Line 676
                                                                                
        default:                                                                Line 678
          if (! simple_strtoul (s, &p, &size))                                  Line 679
            {                                                                   
              /* The integer at P in S would overflow an unsigned long int.     
                 A digit string that long is sufficiently odd looking           
                 that the following diagnostic is sufficient.  */               
              error (0, 0, _("invalid type string %s"), quote (s_orig));        Line 684
              return false;                                                     Line 685
            }                                                                   
          if (p == s)                                                           Line 687
            size = sizeof (int);                                                Line 688
          else                                                                  Line 689
            {                                                                   
              if (MAX_INTEGRAL_TYPE_SIZE < size                                 Line 691
                  || integral_type_size[size] == NO_SIZE)                       Line 692
                {                                                               
                  error (0, 0, _("invalid type string %s;\nthis system"         Line 694
                                 " doesn't provide a %lu-byte integral type"),  Line 695
                         quote (s_orig), size);                                 Line 696
                  return false;                                                 Line 697
                }                                                               
              s = p;                                                            Line 699
            }                                                                   
          break;                                                                Line 701
        }                                                                       
                                                                                
#define ISPEC_TO_FORMAT(Spec, Min_format, Long_format, Max_format) \            Line 704
  ((Spec) == LONG_LONG ? (Max_format)     \                                     Line 705
   : ((Spec) == LONG ? (Long_format)     \                                      Line 706
      : (Min_format)))       \                                                  Line 707
                                                                                
      size_spec = integral_type_size[size];                                     Line 709
                                                                                
      switch (c)                                                                Line 711
        {                                                                       
        case 'd':                                                               Line 713
          fmt = SIGNED_DECIMAL;                                                 Line 714
          field_width = bytes_to_signed_dec_digits[size];                       Line 715
          sprintf (tspec->fmt_string, "%%*%s",                                  Line 716
                   ISPEC_TO_FORMAT (size_spec, "d", "ld", PRIdMAX));            Line 717
          break;                                                                Line 718
                                                                                
        case 'o':                                                               Line 720
          fmt = OCTAL;                                                          Line 721
          sprintf (tspec->fmt_string, "%%*.%d%s",                               Line 722
                   (field_width = bytes_to_oct_digits[size]),                   Line 723
                   ISPEC_TO_FORMAT (size_spec, "o", "lo", PRIoMAX));            Line 724
          break;                                                                Line 725
                                                                                
        case 'u':                                                               Line 727
          fmt = UNSIGNED_DECIMAL;                                               Line 728
          field_width = bytes_to_unsigned_dec_digits[size];                     Line 729
          sprintf (tspec->fmt_string, "%%*%s",                                  Line 730
                   ISPEC_TO_FORMAT (size_spec, "u", "lu", PRIuMAX));            Line 731
          break;                                                                Line 732
                                                                                
        case 'x':                                                               Line 734
          fmt = HEXADECIMAL;                                                    Line 735
          sprintf (tspec->fmt_string, "%%*.%d%s",                               Line 736
                   (field_width = bytes_to_hex_digits[size]),                   Line 737
                   ISPEC_TO_FORMAT (size_spec, "x", "lx", PRIxMAX));            Line 738
          break;                                                                Line 739
                                                                                
        default:                                                                Line 741
          abort ();                                                             ...!common auto-comment...
        }                                                                       
                                                                                
      assert (strlen (tspec->fmt_string) < FMT_BYTES_ALLOCATED);                Line 745
                                                                                
      switch (size_spec)                                                        Line 747
        {                                                                       
        case CHAR:                                                              Line 749
          print_function = (fmt == SIGNED_DECIMAL                               Line 750
                            ? print_s_char                                      Line 751
                            : print_char);                                      Line 752
          break;                                                                Line 753
                                                                                
        case SHORT:                                                             Line 755
          print_function = (fmt == SIGNED_DECIMAL                               Line 756
                            ? print_s_short                                     Line 757
                            : print_short);                                     Line 758
          break;                                                                Line 759
                                                                                
        case INT:                                                               Line 761
          print_function = print_int;                                           Line 762
          break;                                                                Line 763
                                                                                
        case LONG:                                                              Line 765
          print_function = print_long;                                          Line 766
          break;                                                                Line 767
                                                                                
        case LONG_LONG:                                                         Line 769
          print_function = print_long_long;                                     Line 770
          break;                                                                Line 771
                                                                                
        default:                                                                Line 773
          abort ();                                                             ...!common auto-comment...
        }                                                                       
      break;                                                                    Line 776
                                                                                
    case 'f':                                                                   Line 778
      fmt = FLOATING_POINT;                                                     Line 779
      ++s;                                                                      Line 780
      switch (*s)                                                               Line 781
        {                                                                       
        case 'F':                                                               Line 783
          ++s;                                                                  Line 784
          size = sizeof (float);                                                Line 785
          break;                                                                Line 786
                                                                                
        case 'D':                                                               Line 788
          ++s;                                                                  Line 789
          size = sizeof (double);                                               Line 790
          break;                                                                Line 791
                                                                                
        case 'L':                                                               Line 793
          ++s;                                                                  Line 794
          size = sizeof (long double);                                          Line 795
          break;                                                                Line 796
                                                                                
        default:                                                                Line 798
          if (! simple_strtoul (s, &p, &size))                                  Line 799
            {                                                                   
              /* The integer at P in S would overflow an unsigned long int.     
                 A digit string that long is sufficiently odd looking           
                 that the following diagnostic is sufficient.  */               
              error (0, 0, _("invalid type string %s"), quote (s_orig));        Line 804
              return false;                                                     Line 805
            }                                                                   
          if (p == s)                                                           Line 807
            size = sizeof (double);                                             Line 808
          else                                                                  Line 809
            {                                                                   
              if (size > MAX_FP_TYPE_SIZE                                       Line 811
                  || fp_type_size[size] == NO_SIZE)                             Line 812
                {                                                               
                  error (0, 0,                                                  Line 814
                         _("invalid type string %s;\n"                          Line 815
                           "this system doesn't provide a %lu-byte"             Line 816
                           " floating point type"),                             Line 817
                         quote (s_orig), size);                                 Line 818
                  return false;                                                 Line 819
                }                                                               
              s = p;                                                            Line 821
            }                                                                   
          break;                                                                Line 823
        }                                                                       
      size_spec = fp_type_size[size];                                           Line 825
                                                                                
      {                                                                         
        struct lconv const *locale = localeconv ();                             Line 828
        size_t decimal_point_len =                                              Line 829
          (locale->decimal_point[0] ? strlen (locale->decimal_point) : 1);      Line 830
                                                                                
        switch (size_spec)                                                      Line 832
          {                                                                     
          case FLOAT_SINGLE:                                                    Line 834
            print_function = print_float;                                       Line 835
            field_width = FLT_STRLEN_BOUND_L (decimal_point_len);               Line 836
            break;                                                              Line 837
                                                                                
          case FLOAT_DOUBLE:                                                    Line 839
            print_function = print_double;                                      Line 840
            field_width = DBL_STRLEN_BOUND_L (decimal_point_len);               Line 841
            break;                                                              Line 842
                                                                                
          case FLOAT_LONG_DOUBLE:                                               Line 844
            print_function = print_long_double;                                 Line 845
            field_width = LDBL_STRLEN_BOUND_L (decimal_point_len);              Line 846
            break;                                                              Line 847
                                                                                
          default:                                                              Line 849
            abort ();                                                           ...!common auto-comment...
          }                                                                     
                                                                                
        break;                                                                  Line 853
      }                                                                         
                                                                                
    case 'a':                                                                   Line 856
      ++s;                                                                      Line 857
      fmt = NAMED_CHARACTER;                                                    Line 858
      size_spec = CHAR;                                                         Line 859
      print_function = print_named_ascii;                                       Line 860
      field_width = 3;                                                          Line 861
      break;                                                                    Line 862
                                                                                
    case 'c':                                                                   Line 864
      ++s;                                                                      Line 865
      fmt = CHARACTER;                                                          Line 866
      size_spec = CHAR;                                                         Line 867
      print_function = print_ascii;                                             Line 868
      field_width = 3;                                                          Line 869
      break;                                                                    Line 870
                                                                                
    default:                                                                    Line 872
      error (0, 0, _("invalid character '%c' in type string %s"),               Line 873
             *s, quote (s_orig));                                               Line 874
      return false;                                                             Line 875
    }                                                                           
                                                                                
  tspec->size = size_spec;                                                      Line 878
  tspec->fmt = fmt;                                                             Line 879
  tspec->print_function = print_function;                                       Line 880
                                                                                
  tspec->field_width = field_width;                                             Line 882
  tspec->hexl_mode_trailer = (*s == 'z');                                       Line 883
  if (tspec->hexl_mode_trailer)                                                 Line 884
    s++;                                                                        Line 885
                                                                                
  if (next != NULL)                                                             Line 887
    *next = s;                                                                  Line 888
                                                                                
  return true;                                                                  Line 890
}                                                                               Block 23
                                                                                
/* Given a list of one or more input filenames FILE_LIST, set the global        
   file pointer IN_STREAM and the global string INPUT_FILENAME to the           
   first one that can be successfully opened. Modify FILE_LIST to               
   reference the next filename in the list.  A file name of "-" is              
   interpreted as standard input.  If any file open fails, give an error        
   message and return false.  */                                                
                                                                                
static bool                                                                     Line 900
open_next_file (void)                                                           Line 901
{                                                                               
  bool ok = true;                                                               Line 903
                                                                                
  do                                                                            
    {                                                                           
      input_filename = *file_list;                                              Line 907
      if (input_filename == NULL)                                               Line 908
        return ok;                                                              Line 909
      ++file_list;                                                              Line 910
                                                                                
      if (STREQ (input_filename, "-"))                                          Line 912
        {                                                                       
          input_filename = _("standard input");                                 Line 914
          in_stream = stdin;                                                    Line 915
          have_read_stdin = true;                                               Line 916
          xset_binary_mode (STDIN_FILENO, O_BINARY);                            Line 917
        }                                                                       
      else                                                                      Line 919
        {                                                                       
          in_stream = fopen (input_filename, (O_BINARY ? "rb" : "r"));          Line 921...!syscalls auto-comment...
          if (in_stream == NULL)                                                Line 922
            {                                                                   
              error (0, errno, "%s", quotef (input_filename));                  Line 924
              ok = false;                                                       Line 925
            }                                                                   
        }                                                                       
    }                                                                           
  while (in_stream == NULL);                                                    Line 929
                                                                                
  if (limit_bytes_to_format && !flag_dump_strings)                              Line 931
    setvbuf (in_stream, NULL, _IONBF, 0);                                       Line 932
                                                                                
  return ok;                                                                    Line 934
}                                                                               Block 24
                                                                                
/* Test whether there have been errors on in_stream, and close it if            
   it is not standard input.  Return false if there has been an error           
   on in_stream or stdout; return true otherwise.  This function will           
   report more than one error only if both a read and a write error             
   have occurred.  IN_ERRNO, if nonzero, is the error number                    
   corresponding to the most recent action for IN_STREAM.  */                   
                                                                                
static bool                                                                     Line 944
check_and_close (int in_errno)                                                  Line 945...!syscalls auto-comment...
{                                                                               
  bool ok = true;                                                               Line 947
                                                                                
  if (in_stream != NULL)                                                        Line 949
    {                                                                           
      if (ferror (in_stream))                                                   Line 951
        {                                                                       
          error (0, in_errno, _("%s: read error"), quotef (input_filename));    Line 953
          if (! STREQ (file_list[-1], "-"))                                     Line 954
            fclose (in_stream);                                                 Line 955...!syscalls auto-comment...
          ok = false;                                                           Line 956
        }                                                                       
      else if (! STREQ (file_list[-1], "-") && fclose (in_stream) != 0)         Line 958...!syscalls auto-comment...
        {                                                                       
          error (0, errno, "%s", quotef (input_filename));                      Line 960
          ok = false;                                                           Line 961
        }                                                                       
                                                                                
      in_stream = NULL;                                                         Line 964
    }                                                                           
                                                                                
  if (ferror (stdout))                                                          Line 967
    {                                                                           
      error (0, 0, _("write error"));                                           Line 969
      ok = false;                                                               Line 970
    }                                                                           
                                                                                
  return ok;                                                                    Line 973
}                                                                               Block 25
                                                                                
/* Decode the modern od format string S.  Append the decoded                    
   representation to the global array SPEC, reallocating SPEC if                
   necessary.  Return true if S is valid.  */                                   
                                                                                
static bool                                                                     Line 980
decode_format_string (const char *s)                                            Line 981
{                                                                               
  const char *s_orig = s;                                                       Line 983
  assert (s != NULL);                                                           Line 984
                                                                                
  while (*s != '\0')                                                            Line 986
    {                                                                           
      const char *next;                                                         Line 988
                                                                                
      if (n_specs_allocated <= n_specs)                                         Line 990
        spec = X2NREALLOC (spec, &n_specs_allocated);                           Line 991
                                                                                
      if (! decode_one_format (s_orig, s, &next, &spec[n_specs]))               Line 993
        return false;                                                           Line 994
                                                                                
      assert (s != next);                                                       Line 996
      s = next;                                                                 Line 997
      ++n_specs;                                                                Line 998
    }                                                                           
                                                                                
  return true;                                                                  Line 1001
}                                                                               Block 26
                                                                                
/* Given a list of one or more input filenames FILE_LIST, set the global        
   file pointer IN_STREAM to position N_SKIP in the concatenation of            
   those files.  If any file operation fails or if there are fewer than         
   N_SKIP bytes in the combined input, give an error message and return         
   false.  When possible, use seek rather than read operations to               
   advance IN_STREAM.  */                                                       
                                                                                
static bool                                                                     Line 1011
skip (uintmax_t n_skip)                                                         Line 1012
{                                                                               
  bool ok = true;                                                               Line 1014
  int in_errno = 0;                                                             Line 1015
                                                                                
  if (n_skip == 0)                                                              Line 1017
    return true;                                                                Line 1018
                                                                                
  while (in_stream != NULL) /* EOF.  */                                         Line 1020
    {                                                                           
      struct stat file_stats;                                                   Line 1022
                                                                                
      /* First try seeking.  For large offsets, this extra work is              
         worthwhile.  If the offset is below some threshold it may be           
         more efficient to move the pointer by reading.  There are two          
         issues when trying to seek:                                            
           - the file must be seekable.                                         
           - before seeking to the specified position, make sure                
             that the new position is in the current file.                      
             Try to do that by getting file's size using fstat.                 
             But that will work only for regular files.  */                     
                                                                                
      if (fstat (fileno (in_stream), &file_stats) == 0)                         Line 1034...!syscalls auto-comment......!syscalls auto-comment...
        {                                                                       
          /* The st_size field is valid for regular files.                      
             If the number of bytes left to skip is larger than                 
             the size of the current file, we can decrement n_skip              
             and go on to the next file.  Skip this optimization also           
             when st_size is no greater than the block size, because            
             some kernels report nonsense small file sizes for                  
             proc-like file systems.  */                                        
          if (usable_st_size (&file_stats)                                      Line 1043
              && ST_BLKSIZE (file_stats) < file_stats.st_size)                  Line 1044
            {                                                                   
              if ((uintmax_t) file_stats.st_size < n_skip)                      Line 1046
                n_skip -= file_stats.st_size;                                   Line 1047
              else                                                              Line 1048
                {                                                               
                  if (fseeko (in_stream, n_skip, SEEK_CUR) != 0)                Line 1050
                    {                                                           
                      in_errno = errno;                                         Line 1052
                      ok = false;                                               Line 1053
                    }                                                           
                  n_skip = 0;                                                   Line 1055
                }                                                               
            }                                                                   
                                                                                
          /* If it's not a regular file with nonnegative size,                  
             or if it's so small that it might be in a proc-like file system,   
             position the file pointer by reading.  */                          
                                                                                
          else                                                                  Line 1063
            {                                                                   
              char buf[BUFSIZ];                                                 Line 1065
              size_t n_bytes_read, n_bytes_to_read = BUFSIZ;                    Line 1066
                                                                                
              while (0 < n_skip)                                                Line 1068
                {                                                               
                  if (n_skip < n_bytes_to_read)                                 Line 1070
                    n_bytes_to_read = n_skip;                                   Line 1071
                  n_bytes_read = fread (buf, 1, n_bytes_to_read, in_stream);    Line 1072...!syscalls auto-comment...
                  n_skip -= n_bytes_read;                                       Line 1073
                  if (n_bytes_read != n_bytes_to_read)                          Line 1074
                    {                                                           
                      if (ferror (in_stream))                                   Line 1076
                        {                                                       
                          in_errno = errno;                                     Line 1078
                          ok = false;                                           Line 1079
                          n_skip = 0;                                           Line 1080
                          break;                                                Line 1081
                        }                                                       
                      if (feof (in_stream))                                     Line 1083
                        break;                                                  Line 1084
                    }                                                           
                }                                                               
            }                                                                   
                                                                                
          if (n_skip == 0)                                                      Line 1089
            break;                                                              Line 1090
        }                                                                       
                                                                                
      else   /* cannot fstat() file */                                          Line 1093
        {                                                                       
          error (0, errno, "%s", quotef (input_filename));                      Line 1095
          ok = false;                                                           Line 1096
        }                                                                       
                                                                                
      ok &= check_and_close (in_errno);                                         Line 1099...!syscalls auto-comment...
                                                                                
      ok &= open_next_file ();                                                  Line 1101
    }                                                                           
                                                                                
  if (n_skip != 0)                                                              Line 1104
    die (EXIT_FAILURE, 0, _("cannot skip past end of combined input"));         Line 1105
                                                                                
  return ok;                                                                    Line 1107
}                                                                               Block 27
                                                                                
static void                                                                     Line 1110
format_address_none (uintmax_t address _GL_UNUSED,                              Line 1111
                     char c _GL_UNUSED)                                         Line 1112
{                                                                               
}                                                                               
                                                                                
static void                                                                     Line 1116
format_address_std (uintmax_t address, char c)                                  Line 1117
{                                                                               
  char buf[MAX_ADDRESS_LENGTH + 2];                                             Line 1119
  char *p = buf + sizeof buf;                                                   Line 1120
  char const *pbound;                                                           Line 1121
                                                                                
  *--p = '\0';                                                                  Line 1123
  *--p = c;                                                                     Line 1124
  pbound = p - address_pad_len;                                                 Line 1125
                                                                                
  /* Use a special case of the code for each base.  This is measurably          
     faster than generic code.  */                                              
  switch (address_base)                                                         Line 1129
    {                                                                           
    case 8:                                                                     Line 1131
      do                                                                        
        *--p = '0' + (address & 7);                                             Line 1133
      while ((address >>= 3) != 0);                                             Line 1134
      break;                                                                    Line 1135
                                                                                
    case 10:                                                                    Line 1137
      do                                                                        
        *--p = '0' + (address % 10);                                            Line 1139
      while ((address /= 10) != 0);                                             Line 1140
      break;                                                                    Line 1141
                                                                                
    case 16:                                                                    Line 1143
      do                                                                        
        *--p = "0123456789abcdef"[address & 15];                                Line 1145
      while ((address >>= 4) != 0);                                             Line 1146
      break;                                                                    Line 1147
    }                                                                           
                                                                                
  while (pbound < p)                                                            Line 1150
    *--p = '0';                                                                 Line 1151
                                                                                
  fputs (p, stdout);                                                            Line 1153
}                                                                               Block 29
                                                                                
static void                                                                     Line 1156
format_address_paren (uintmax_t address, char c)                                Line 1157
{                                                                               
  putchar ('(');                                                                Line 1159
  format_address_std (address, ')');                                            Line 1160
  if (c)                                                                        Line 1161
    putchar (c);                                                                Line 1162
}                                                                               Block 30
                                                                                
static void                                                                     Line 1165
format_address_label (uintmax_t address, char c)                                Line 1166
{                                                                               
  format_address_std (address, ' ');                                            Line 1168
  format_address_paren (address + pseudo_offset, c);                            Line 1169
}                                                                               Block 31
                                                                                
/* Write N_BYTES bytes from CURR_BLOCK to standard output once for each         
   of the N_SPEC format specs.  CURRENT_OFFSET is the byte address of           
   CURR_BLOCK in the concatenation of input files, and it is printed            
   (optionally) only before the output line associated with the first           
   format spec.  When duplicate blocks are being abbreviated, the output        
   for a sequence of identical input blocks is the output for the first         
   block followed by an asterisk alone on a line.  It is valid to compare       
   the blocks PREV_BLOCK and CURR_BLOCK only when N_BYTES == BYTES_PER_BLOCK.   
   That condition may be false only for the last input block.  */               
                                                                                
static void                                                                     Line 1182
write_block (uintmax_t current_offset, size_t n_bytes,                          Line 1183
             const char *prev_block, const char *curr_block)                    Line 1184
{                                                                               
  static bool first = true;                                                     Line 1186
  static bool prev_pair_equal = false;                                          Line 1187
                                                                                
#define EQUAL_BLOCKS(b1, b2) (memcmp (b1, b2, bytes_per_block) == 0)            Line 1189
                                                                                
  if (abbreviate_duplicate_blocks                                               Line 1191
      && !first && n_bytes == bytes_per_block                                   Line 1192
      && EQUAL_BLOCKS (prev_block, curr_block))                                 Line 1193
    {                                                                           
      if (prev_pair_equal)                                                      Line 1195
        {                                                                       
          /* The two preceding blocks were equal, and the current               
             block is the same as the last one, so print nothing.  */           
        }                                                                       
      else                                                                      Line 1200
        {                                                                       
          printf ("*\n");                                                       Line 1202
          prev_pair_equal = true;                                               Line 1203
        }                                                                       
    }                                                                           
  else                                                                          Line 1206
    {                                                                           
      prev_pair_equal = false;                                                  Line 1208
      for (size_t i = 0; i < n_specs; i++)                                      Line 1209
        {                                                                       
          int datum_width = width_bytes[spec[i].size];                          Line 1211
          int fields_per_block = bytes_per_block / datum_width;                 Line 1212
          int blank_fields = (bytes_per_block - n_bytes) / datum_width;         Line 1213
          if (i == 0)                                                           Line 1214
            format_address (current_offset, '\0');                              Line 1215
          else                                                                  Line 1216
            printf ("%*s", address_pad_len, "");                                Line 1217
          (*spec[i].print_function) (fields_per_block, blank_fields,            Line 1218
                                     curr_block, spec[i].fmt_string,            Line 1219
                                     spec[i].field_width, spec[i].pad_width);   Line 1220
          if (spec[i].hexl_mode_trailer)                                        Line 1221
            {                                                                   
              /* space-pad out to full line width, then dump the trailer */     
              int field_width = spec[i].field_width;                            Line 1224
              int pad_width = (spec[i].pad_width * blank_fields                 Line 1225
                               / fields_per_block);                             Line 1226
              printf ("%*s", blank_fields * field_width + pad_width, "");       Line 1227
              dump_hexl_mode_trailer (n_bytes, curr_block);                     Line 1228
            }                                                                   
          putchar ('\n');                                                       Line 1230
        }                                                                       
    }                                                                           
  first = false;                                                                Line 1233
}                                                                               Block 32
                                                                                
/* Read a single byte into *C from the concatenation of the input files         
   named in the global array FILE_LIST.  On the first call to this              
   function, the global variable IN_STREAM is expected to be an open            
   stream associated with the input file INPUT_FILENAME.  If IN_STREAM          
   is at end-of-file, close it and update the global variables IN_STREAM        
   and INPUT_FILENAME so they correspond to the next file in the list.          
   Then try to read a byte from the newly opened file.  Repeat if               
   necessary until EOF is reached for the last file in FILE_LIST, then          
   set *C to EOF and return.  Subsequent calls do likewise.  Return             
   true if successful.  */                                                      
                                                                                
static bool                                                                     Line 1247
read_char (int *c)                                                              Line 1248
{                                                                               
  bool ok = true;                                                               Line 1250
                                                                                
  *c = EOF;                                                                     Line 1252
                                                                                
  while (in_stream != NULL) /* EOF.  */                                         Line 1254
    {                                                                           
      *c = fgetc (in_stream);                                                   Line 1256
                                                                                
      if (*c != EOF)                                                            Line 1258
        break;                                                                  Line 1259
                                                                                
      ok &= check_and_close (errno);                                            Line 1261...!syscalls auto-comment...
                                                                                
      ok &= open_next_file ();                                                  Line 1263
    }                                                                           
                                                                                
  return ok;                                                                    Line 1266
}                                                                               Block 33
                                                                                
/* Read N bytes into BLOCK from the concatenation of the input files            
   named in the global array FILE_LIST.  On the first call to this              
   function, the global variable IN_STREAM is expected to be an open            
   stream associated with the input file INPUT_FILENAME.  If all N              
   bytes cannot be read from IN_STREAM, close IN_STREAM and update              
   the global variables IN_STREAM and INPUT_FILENAME.  Then try to              
   read the remaining bytes from the newly opened file.  Repeat if              
   necessary until EOF is reached for the last file in FILE_LIST.               
   On subsequent calls, don't modify BLOCK and return true.  Set                
   *N_BYTES_IN_BUFFER to the number of bytes read.  If an error occurs,         
   it will be detected through ferror when the stream is about to be            
   closed.  If there is an error, give a message but continue reading           
   as usual and return false.  Otherwise return true.  */                       
                                                                                
static bool                                                                     Line 1283
read_block (size_t n, char *block, size_t *n_bytes_in_buffer)                   Line 1284
{                                                                               
  bool ok = true;                                                               Line 1286
                                                                                
  assert (0 < n && n <= bytes_per_block);                                       Line 1288
                                                                                
  *n_bytes_in_buffer = 0;                                                       Line 1290
                                                                                
  while (in_stream != NULL) /* EOF.  */                                         Line 1292
    {                                                                           
      size_t n_needed;                                                          Line 1294
      size_t n_read;                                                            Line 1295
                                                                                
      n_needed = n - *n_bytes_in_buffer;                                        Line 1297
      n_read = fread (block + *n_bytes_in_buffer, 1, n_needed, in_stream);      Line 1298...!syscalls auto-comment...
                                                                                
      *n_bytes_in_buffer += n_read;                                             Line 1300
                                                                                
      if (n_read == n_needed)                                                   Line 1302
        break;                                                                  Line 1303
                                                                                
      ok &= check_and_close (errno);                                            Line 1305...!syscalls auto-comment...
                                                                                
      ok &= open_next_file ();                                                  Line 1307
    }                                                                           
                                                                                
  return ok;                                                                    Line 1310
}                                                                               Block 34
                                                                                
/* Return the least common multiple of the sizes associated                     
   with the format specs.  */                                                   
                                                                                
static int _GL_ATTRIBUTE_PURE                                                   Line 1316
get_lcm (void)                                                                  Line 1317
{                                                                               
  int l_c_m = 1;                                                                Line 1319
                                                                                
  for (size_t i = 0; i < n_specs; i++)                                          Line 1321
    l_c_m = lcm (l_c_m, width_bytes[spec[i].size]);                             Line 1322
  return l_c_m;                                                                 Line 1323
}                                                                               Block 35
                                                                                
/* If S is a valid traditional offset specification with an optional            
   leading '+' return true and set *OFFSET to the offset it denotes.  */        
                                                                                
static bool                                                                     Line 1329
parse_old_offset (const char *s, uintmax_t *offset)                             Line 1330
{                                                                               
  int radix;                                                                    Line 1332
                                                                                
  if (*s == '\0')                                                               Line 1334
    return false;                                                               Line 1335
                                                                                
  /* Skip over any leading '+'. */                                              
  if (s[0] == '+')                                                              Line 1338
    ++s;                                                                        Line 1339
                                                                                
  /* Determine the radix we'll use to interpret S.  If there is a '.',          
     it's decimal, otherwise, if the string begins with '0X'or '0x',            
     it's hexadecimal, else octal.  */                                          
  if (strchr (s, '.') != NULL)                                                  Line 1344
    radix = 10;                                                                 Line 1345
  else                                                                          Line 1346
    {                                                                           
      if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))                          Line 1348
        radix = 16;                                                             Line 1349
      else                                                                      Line 1350
        radix = 8;                                                              Line 1351
    }                                                                           
                                                                                
  return xstrtoumax (s, NULL, radix, offset, "Bb") == LONGINT_OK;               Line 1354
}                                                                               Block 36
                                                                                
/* Read a chunk of size BYTES_PER_BLOCK from the input files, write the         
   formatted block to standard output, and repeat until the specified           
   maximum number of bytes has been read or until all input has been            
   processed.  If the last block read is smaller than BYTES_PER_BLOCK           
   and its size is not a multiple of the size associated with a format          
   spec, extend the input block with zero bytes until its length is a           
   multiple of all format spec sizes.  Write the final block.  Finally,         
   write on a line by itself the offset of the byte after the last byte         
   read.  Accumulate return values from calls to read_block and                 
   check_and_close, and if any was false, return false.                         
   Otherwise, return true.  */                                                  
                                                                                
static bool                                                                     Line 1369
dump (void)                                                                     Line 1370
{                                                                               
  char *block[2];                                                               Line 1372
  uintmax_t current_offset;                                                     Line 1373
  bool idx = false;                                                             Line 1374
  bool ok = true;                                                               Line 1375
  size_t n_bytes_read;                                                          Line 1376
                                                                                
  block[0] = xnmalloc (2, bytes_per_block);                                     Line 1378
  block[1] = block[0] + bytes_per_block;                                        Line 1379
                                                                                
  current_offset = n_bytes_to_skip;                                             Line 1381
                                                                                
  if (limit_bytes_to_format)                                                    Line 1383
    {                                                                           
      while (1)                                                                 Line 1385
        {                                                                       
          size_t n_needed;                                                      Line 1387
          if (current_offset >= end_offset)                                     Line 1388
            {                                                                   
              n_bytes_read = 0;                                                 Line 1390
              break;                                                            Line 1391
            }                                                                   
          n_needed = MIN (end_offset - current_offset,                          Line 1393
                          (uintmax_t) bytes_per_block);                         Line 1394
          ok &= read_block (n_needed, block[idx], &n_bytes_read);               Line 1395
          if (n_bytes_read < bytes_per_block)                                   Line 1396
            break;                                                              Line 1397
          assert (n_bytes_read == bytes_per_block);                             Line 1398
          write_block (current_offset, n_bytes_read,                            Line 1399
                       block[!idx], block[idx]);                                Line 1400
          current_offset += n_bytes_read;                                       Line 1401
          idx = !idx;                                                           Line 1402
        }                                                                       
    }                                                                           
  else                                                                          Line 1405
    {                                                                           
      while (1)                                                                 Line 1407
        {                                                                       
          ok &= read_block (bytes_per_block, block[idx], &n_bytes_read);        Line 1409
          if (n_bytes_read < bytes_per_block)                                   Line 1410
            break;                                                              Line 1411
          assert (n_bytes_read == bytes_per_block);                             Line 1412
          write_block (current_offset, n_bytes_read,                            Line 1413
                       block[!idx], block[idx]);                                Line 1414
          current_offset += n_bytes_read;                                       Line 1415
          idx = !idx;                                                           Line 1416
        }                                                                       
    }                                                                           
                                                                                
  if (n_bytes_read > 0)                                                         Line 1420
    {                                                                           
      int l_c_m;                                                                Line 1422
      size_t bytes_to_write;                                                    Line 1423
                                                                                
      l_c_m = get_lcm ();                                                       Line 1425
                                                                                
      /* Ensure zero-byte padding up to the smallest multiple of l_c_m that     
         is at least as large as n_bytes_read.  */                              
      bytes_to_write = l_c_m * ((n_bytes_read + l_c_m - 1) / l_c_m);            Line 1429
                                                                                
      memset (block[idx] + n_bytes_read, 0, bytes_to_write - n_bytes_read);     Line 1431
      write_block (current_offset, n_bytes_read, block[!idx], block[idx]);      Line 1432
      current_offset += n_bytes_read;                                           Line 1433
    }                                                                           
                                                                                
  format_address (current_offset, '\n');                                        Line 1436
                                                                                
  if (limit_bytes_to_format && current_offset >= end_offset)                    Line 1438
    ok &= check_and_close (0);                                                  Line 1439...!syscalls auto-comment...
                                                                                
  free (block[0]);                                                              Line 1441
                                                                                
  return ok;                                                                    Line 1443
}                                                                               Block 37
                                                                                
/* STRINGS mode.  Find each "string constant" in the input.                     
   A string constant is a run of at least 'string_min' ASCII                    
   graphic (or formatting) characters terminated by a null.                     
   Based on a function written by Richard Stallman for a                        
   traditional version of od.  Return true if successful.  */                   
                                                                                
static bool                                                                     Line 1452
dump_strings (void)                                                             Line 1453
{                                                                               
  size_t bufsize = MAX (100, string_min);                                       Line 1455
  char *buf = xmalloc (bufsize);                                                Line 1456
  uintmax_t address = n_bytes_to_skip;                                          Line 1457
  bool ok = true;                                                               Line 1458
                                                                                
  while (1)                                                                     Line 1460
    {                                                                           
      size_t i;                                                                 Line 1462
      int c;                                                                    Line 1463
                                                                                
      /* See if the next 'string_min' chars are all printing chars.  */         
    tryline:                                                                    Line 1466
                                                                                
      if (limit_bytes_to_format                                                 Line 1468
          && (end_offset < string_min || end_offset - string_min <= address))   Line 1469
        break;                                                                  Line 1470
                                                                                
      for (i = 0; i < string_min; i++)                                          Line 1472
        {                                                                       
          ok &= read_char (&c);                                                 Line 1474
          address++;                                                            Line 1475
          if (c < 0)                                                            Line 1476
            {                                                                   
              free (buf);                                                       Line 1478
              return ok;                                                        Line 1479
            }                                                                   
          if (! isprint (c))                                                    Line 1481
            /* Found a non-printing.  Try again starting with next char.  */    
            goto tryline;                                                       Line 1483
          buf[i] = c;                                                           Line 1484
        }                                                                       
                                                                                
      /* We found a run of 'string_min' printable characters.                   
         Now see if it is terminated with a null byte.  */                      
      while (!limit_bytes_to_format || address < end_offset)                    Line 1489
        {                                                                       
          if (i == bufsize)                                                     Line 1491
            {                                                                   
              buf = X2REALLOC (buf, &bufsize);                                  Line 1493
            }                                                                   
          ok &= read_char (&c);                                                 Line 1495
          address++;                                                            Line 1496
          if (c < 0)                                                            Line 1497
            {                                                                   
              free (buf);                                                       Line 1499
              return ok;                                                        Line 1500
            }                                                                   
          if (c == '\0')                                                        Line 1502
            break;  /* It is; print this string.  */                            Line 1503
          if (! isprint (c))                                                    Line 1504
            goto tryline; /* It isn't; give up on this string.  */              Line 1505
          buf[i++] = c;  /* String continues; store it all.  */                 Line 1506
        }                                                                       
                                                                                
      /* If we get here, the string is all printable and null-terminated,       
         so print it.  It is all in 'buf' and 'i' is its length.  */            
      buf[i] = 0;                                                               Line 1511
      format_address (address - i - 1, ' ');                                    Line 1512
                                                                                
      for (i = 0; (c = buf[i]); i++)                                            Line 1514
        {                                                                       
          switch (c)                                                            Line 1516
            {                                                                   
            case '\a':                                                          Line 1518
              fputs ("\\a", stdout);                                            Line 1519
              break;                                                            Line 1520
                                                                                
            case '\b':                                                          Line 1522
              fputs ("\\b", stdout);                                            Line 1523
              break;                                                            Line 1524
                                                                                
            case '\f':                                                          Line 1526
              fputs ("\\f", stdout);                                            Line 1527
              break;                                                            Line 1528
                                                                                
            case '\n':                                                          Line 1530
              fputs ("\\n", stdout);                                            Line 1531
              break;                                                            Line 1532
                                                                                
            case '\r':                                                          Line 1534
              fputs ("\\r", stdout);                                            Line 1535
              break;                                                            Line 1536
                                                                                
            case '\t':                                                          Line 1538
              fputs ("\\t", stdout);                                            Line 1539
              break;                                                            Line 1540
                                                                                
            case '\v':                                                          Line 1542
              fputs ("\\v", stdout);                                            Line 1543
              break;                                                            Line 1544
                                                                                
            default:                                                            Line 1546
              putc (c, stdout);                                                 Line 1547
            }                                                                   
        }                                                                       
      putchar ('\n');                                                           Line 1550
    }                                                                           
                                                                                
  /* We reach this point only if we search through                              
     (max_bytes_to_format - string_min) bytes before reaching EOF.  */          
                                                                                
  free (buf);                                                                   Line 1556
                                                                                
  ok &= check_and_close (0);                                                    Line 1558...!syscalls auto-comment...
  return ok;                                                                    Line 1559
}                                                                               Block 38
                                                                                
int                                                                             
main (int argc, char **argv)                                                    Line 1563
{                                                                               
  int n_files;                                                                  Line 1565
  size_t i;                                                                     Line 1566
  int l_c_m;                                                                    Line 1567
  size_t desired_width IF_LINT ( = 0);                                          Line 1568
  bool modern = false;                                                          Line 1569
  bool width_specified = false;                                                 Line 1570
  bool ok = true;                                                               Line 1571
  size_t width_per_block = 0;                                                   Line 1572
  static char const multipliers[] = "bEGKkMmPTYZ0";                             Line 1573
                                                                                
  /* The old-style 'pseudo starting address' to be printed in parentheses       
     after any true address.  */                                                
  uintmax_t pseudo_start IF_LINT ( = 0);                                        Line 1577
                                                                                
  initialize_main (&argc, &argv);                                               VMS-specific entry point handling wildcard expansion
  set_program_name (argv[0]);                                                   Retains program name and discards path
  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
                                                                                
  atexit (close_stdout);                                                        Close stdout on exit (see gnulib)
                                                                                
  for (i = 0; i <= MAX_INTEGRAL_TYPE_SIZE; i++)                                 Line 1587
    integral_type_size[i] = NO_SIZE;                                            Line 1588
                                                                                
  integral_type_size[sizeof (char)] = CHAR;                                     Line 1590
  integral_type_size[sizeof (short int)] = SHORT;                               Line 1591
  integral_type_size[sizeof (int)] = INT;                                       Line 1592
  integral_type_size[sizeof (long int)] = LONG;                                 Line 1593
#if HAVE_UNSIGNED_LONG_LONG_INT                                                 Line 1594
  /* If 'long int' and 'long long int' have the same size, it's fine            
     to overwrite the entry for 'long' with this one.  */                       
  integral_type_size[sizeof (unsigned_long_long_int)] = LONG_LONG;              Line 1597
#endif                                                                          Line 1598
                                                                                
  for (i = 0; i <= MAX_FP_TYPE_SIZE; i++)                                       Line 1600
    fp_type_size[i] = NO_SIZE;                                                  Line 1601
                                                                                
  fp_type_size[sizeof (float)] = FLOAT_SINGLE;                                  Line 1603
  /* The array entry for 'double' is filled in after that for 'long double'     
     so that if they are the same size, we avoid any overhead of                
     long double computation in libc.  */                                       
  fp_type_size[sizeof (long double)] = FLOAT_LONG_DOUBLE;                       Line 1607
  fp_type_size[sizeof (double)] = FLOAT_DOUBLE;                                 Line 1608
                                                                                
  n_specs = 0;                                                                  Line 1610
  n_specs_allocated = 0;                                                        Line 1611
  spec = NULL;                                                                  Line 1612
                                                                                
  format_address = format_address_std;                                          Line 1614
  address_base = 8;                                                             Line 1615
  address_pad_len = 7;                                                          Line 1616
  flag_dump_strings = false;                                                    Line 1617
                                                                                
  while (true)                                                                  Line 1619
    {                                                                           
      uintmax_t tmp;                                                            Line 1621
      enum strtol_error s_err;                                                  Line 1622
      int oi = -1;                                                              Line 1623
      int c = getopt_long (argc, argv, short_options, long_options, &oi);       Line 1624
      if (c == -1)                                                              Line 1625
        break;                                                                  Line 1626
                                                                                
      switch (c)                                                                Line 1628
        {                                                                       
        case 'A':                                                               Line 1630
          modern = true;                                                        Line 1631
          switch (optarg[0])                                                    Line 1632
            {                                                                   
            case 'd':                                                           Line 1634
              format_address = format_address_std;                              Line 1635
              address_base = 10;                                                Line 1636
              address_pad_len = 7;                                              Line 1637
              break;                                                            Line 1638
            case 'o':                                                           Line 1639
              format_address = format_address_std;                              Line 1640
              address_base = 8;                                                 Line 1641
              address_pad_len = 7;                                              Line 1642
              break;                                                            Line 1643
            case 'x':                                                           Line 1644
              format_address = format_address_std;                              Line 1645
              address_base = 16;                                                Line 1646
              address_pad_len = 6;                                              Line 1647
              break;                                                            Line 1648
            case 'n':                                                           Line 1649
              format_address = format_address_none;                             Line 1650
              address_pad_len = 0;                                              Line 1651
              break;                                                            Line 1652
            default:                                                            Line 1653
              die (EXIT_FAILURE, 0,                                             Line 1654
                   _("invalid output address radix '%c';\                       Line 1655
 it must be one character from [doxn]"),                                        Line 1656
                   optarg[0]);                                                  Line 1657
              break;                                                            Line 1658
            }                                                                   
          break;                                                                Line 1660
                                                                                
        case 'j':                                                               Line 1662
          modern = true;                                                        Line 1663
          s_err = xstrtoumax (optarg, NULL, 0, &n_bytes_to_skip, multipliers);  Line 1664
          if (s_err != LONGINT_OK)                                              Line 1665
            xstrtol_fatal (s_err, oi, c, long_options, optarg);                 Line 1666
          break;                                                                Line 1667
                                                                                
        case 'N':                                                               Line 1669
          modern = true;                                                        Line 1670
          limit_bytes_to_format = true;                                         Line 1671
                                                                                
          s_err = xstrtoumax (optarg, NULL, 0, &max_bytes_to_format,            Line 1673
                              multipliers);                                     Line 1674
          if (s_err != LONGINT_OK)                                              Line 1675
            xstrtol_fatal (s_err, oi, c, long_options, optarg);                 Line 1676
          break;                                                                Line 1677
                                                                                
        case 'S':                                                               Line 1679
          modern = true;                                                        Line 1680
          if (optarg == NULL)                                                   Line 1681
            string_min = 3;                                                     Line 1682
          else                                                                  Line 1683
            {                                                                   
              s_err = xstrtoumax (optarg, NULL, 0, &tmp, multipliers);          Line 1685
              if (s_err != LONGINT_OK)                                          Line 1686
                xstrtol_fatal (s_err, oi, c, long_options, optarg);             Line 1687
                                                                                
              /* The minimum string length may be no larger than SIZE_MAX,      
                 since we may allocate a buffer of this size.  */               
              if (SIZE_MAX < tmp)                                               Line 1691
                die (EXIT_FAILURE, 0, _("%s is too large"), quote (optarg));    Line 1692
                                                                                
              string_min = tmp;                                                 Line 1694
            }                                                                   
          flag_dump_strings = true;                                             Line 1696
          break;                                                                Line 1697
                                                                                
        case 't':                                                               Line 1699
          modern = true;                                                        Line 1700
          ok &= decode_format_string (optarg);                                  Line 1701
          break;                                                                Line 1702
                                                                                
        case 'v':                                                               Line 1704
          modern = true;                                                        Line 1705
          abbreviate_duplicate_blocks = false;                                  Line 1706
          break;                                                                Line 1707
                                                                                
        case TRADITIONAL_OPTION:                                                Line 1709
          traditional = true;                                                   Line 1710
          break;                                                                Line 1711
                                                                                
        case ENDIAN_OPTION:                                                     Line 1713
          switch (XARGMATCH ("--endian", optarg, endian_args, endian_types))    Line 1714
            {                                                                   
              case endian_big:                                                  Line 1716
                  input_swap = ! WORDS_BIGENDIAN;                               Line 1717
                  break;                                                        Line 1718
              case endian_little:                                               Line 1719
                  input_swap = WORDS_BIGENDIAN;                                 Line 1720
                  break;                                                        Line 1721
            }                                                                   
          break;                                                                Line 1723
                                                                                
          /* The next several cases map the traditional format                  
             specification options to the corresponding modern format           
             specs.  GNU od accepts any combination of old- and                 
             new-style options.  Format specification options accumulate.       
             The obsolescent and undocumented formats are compatible            
             with FreeBSD 4.10 od.  */                                          
                                                                                
#define CASE_OLD_ARG(old_char,new_string)  \                                    Line 1732
        case old_char:     \                                                    Line 1733
          ok &= decode_format_string (new_string); \                            Line 1734
          break                                                                 Line 1735
                                                                                
          CASE_OLD_ARG ('a', "a");                                              Line 1737
          CASE_OLD_ARG ('b', "o1");                                             Line 1738
          CASE_OLD_ARG ('c', "c");                                              Line 1739
          CASE_OLD_ARG ('D', "u4"); /* obsolescent and undocumented */          Line 1740
          CASE_OLD_ARG ('d', "u2");                                             Line 1741
        case 'F': /* obsolescent and undocumented alias */                      Line 1742
          CASE_OLD_ARG ('e', "fD"); /* obsolescent and undocumented */          Line 1743
          CASE_OLD_ARG ('f', "fF");                                             Line 1744
        case 'X': /* obsolescent and undocumented alias */                      Line 1745
          CASE_OLD_ARG ('H', "x4"); /* obsolescent and undocumented */          Line 1746
          CASE_OLD_ARG ('i', "dI");                                             Line 1747
        case 'I': case 'L': /* obsolescent and undocumented aliases */          Line 1748
          CASE_OLD_ARG ('l', "dL");                                             Line 1749
          CASE_OLD_ARG ('O', "o4"); /* obsolesent and undocumented */           Line 1750
        case 'B': /* obsolescent and undocumented alias */                      Line 1751
          CASE_OLD_ARG ('o', "o2");                                             Line 1752
          CASE_OLD_ARG ('s', "d2");                                             Line 1753
        case 'h': /* obsolescent and undocumented alias */                      Line 1754
          CASE_OLD_ARG ('x', "x2");                                             Line 1755
                                                                                
#undef CASE_OLD_ARG                                                             Line 1757
                                                                                
        case 'w':                                                               Line 1759
          modern = true;                                                        Line 1760
          width_specified = true;                                               Line 1761
          if (optarg == NULL)                                                   Line 1762
            {                                                                   
              desired_width = 32;                                               Line 1764
            }                                                                   
          else                                                                  Line 1766
            {                                                                   
              uintmax_t w_tmp;                                                  Line 1768
              s_err = xstrtoumax (optarg, NULL, 10, &w_tmp, "");                Line 1769
              if (s_err != LONGINT_OK)                                          Line 1770
                xstrtol_fatal (s_err, oi, c, long_options, optarg);             Line 1771
              if (SIZE_MAX < w_tmp)                                             Line 1772
                die (EXIT_FAILURE, 0, _("%s is too large"), quote (optarg));    Line 1773
              desired_width = w_tmp;                                            Line 1774
            }                                                                   
          break;                                                                Line 1776
                                                                                
        case_GETOPT_HELP_CHAR;                                                  Line 1778
                                                                                
        case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);                       Line 1780
                                                                                
        default:                                                                Line 1782
          usage (EXIT_FAILURE);                                                 Line 1783
          break;                                                                Line 1784
        }                                                                       
    }                                                                           
                                                                                
  if (!ok)                                                                      Line 1788
    return EXIT_FAILURE;                                                        Line 1789
                                                                                
  if (flag_dump_strings && n_specs > 0)                                         Line 1791
    die (EXIT_FAILURE, 0,                                                       Line 1792
         _("no type may be specified when dumping strings"));                   Line 1793
                                                                                
  n_files = argc - optind;                                                      Line 1795
                                                                                
  /* If the --traditional option is used, there may be from                     
     0 to 3 remaining command line arguments;  handle each case                 
     separately.                                                                
        od [file] [[+]offset[.][b] [[+]label[.][b]]]                            
     The offset and label have the same syntax.                                 
                                                                                
     If --traditional is not given, and if no modern options are                
     given, and if the offset begins with + or (if there are two                
     operands) a digit, accept only this form, as per POSIX:                    
        od [file] [[+]offset[.][b]]                                             
  */                                                                            
                                                                                
  if (!modern || traditional)                                                   Line 1809
    {                                                                           
      uintmax_t o1;                                                             Line 1811
      uintmax_t o2;                                                             Line 1812
                                                                                
      switch (n_files)                                                          Line 1814
        {                                                                       
        case 1:                                                                 Line 1816
          if ((traditional || argv[optind][0] == '+')                           Line 1817
              && parse_old_offset (argv[optind], &o1))                          Line 1818
            {                                                                   
              n_bytes_to_skip = o1;                                             Line 1820
              --n_files;                                                        Line 1821
              ++argv;                                                           Line 1822
            }                                                                   
          break;                                                                Line 1824
                                                                                
        case 2:                                                                 Line 1826
          if ((traditional || argv[optind + 1][0] == '+'                        Line 1827
               || ISDIGIT (argv[optind + 1][0]))                                Line 1828
              && parse_old_offset (argv[optind + 1], &o2))                      Line 1829
            {                                                                   
              if (traditional && parse_old_offset (argv[optind], &o1))          Line 1831
                {                                                               
                  n_bytes_to_skip = o1;                                         Line 1833
                  flag_pseudo_start = true;                                     Line 1834
                  pseudo_start = o2;                                            Line 1835
                  argv += 2;                                                    Line 1836
                  n_files -= 2;                                                 Line 1837
                }                                                               
              else                                                              Line 1839
                {                                                               
                  n_bytes_to_skip = o2;                                         Line 1841
                  --n_files;                                                    Line 1842
                  argv[optind + 1] = argv[optind];                              Line 1843
                  ++argv;                                                       Line 1844
                }                                                               
            }                                                                   
          break;                                                                Line 1847
                                                                                
        case 3:                                                                 Line 1849
          if (traditional                                                       Line 1850
              && parse_old_offset (argv[optind + 1], &o1)                       Line 1851
              && parse_old_offset (argv[optind + 2], &o2))                      Line 1852
            {                                                                   
              n_bytes_to_skip = o1;                                             Line 1854
              flag_pseudo_start = true;                                         Line 1855
              pseudo_start = o2;                                                Line 1856
              argv[optind + 2] = argv[optind];                                  Line 1857
              argv += 2;                                                        Line 1858
              n_files -= 2;                                                     Line 1859
            }                                                                   
          break;                                                                Line 1861
        }                                                                       
                                                                                
      if (traditional && 1 < n_files)                                           Line 1864
        {                                                                       
          error (0, 0, _("extra operand %s"), quote (argv[optind + 1]));        Line 1866
          error (0, 0, "%s",                                                    Line 1867
                 _("compatibility mode supports at most one file"));            Line 1868
          usage (EXIT_FAILURE);                                                 Line 1869
        }                                                                       
    }                                                                           
                                                                                
  if (flag_pseudo_start)                                                        Line 1873
    {                                                                           
      if (format_address == format_address_none)                                Line 1875
        {                                                                       
          address_base = 8;                                                     Line 1877
          address_pad_len = 7;                                                  Line 1878
          format_address = format_address_paren;                                Line 1879
        }                                                                       
      else                                                                      Line 1881
        format_address = format_address_label;                                  Line 1882
    }                                                                           
                                                                                
  if (limit_bytes_to_format)                                                    Line 1885
    {                                                                           
      end_offset = n_bytes_to_skip + max_bytes_to_format;                       Line 1887
      if (end_offset < n_bytes_to_skip)                                         Line 1888
        die (EXIT_FAILURE, 0, _("skip-bytes + read-bytes is too large"));       Line 1889
    }                                                                           
                                                                                
  if (n_specs == 0)                                                             Line 1892
    decode_format_string ("oS");                                                Line 1893
                                                                                
  if (n_files > 0)                                                              Line 1895
    {                                                                           
      /* Set the global pointer FILE_LIST so that it                            
         references the first file-argument on the command-line.  */            
                                                                                
      file_list = (char const *const *) &argv[optind];                          Line 1900
    }                                                                           
  else                                                                          Line 1902
    {                                                                           
      /* No files were listed on the command line.                              
         Set the global pointer FILE_LIST so that it                            
         references the null-terminated list of one name: "-".  */              
                                                                                
      file_list = default_file_list;                                            Line 1908
    }                                                                           
                                                                                
  /* open the first input file */                                               
  ok = open_next_file ();                                                       Line 1912
  if (in_stream == NULL)                                                        Line 1913
    goto cleanup;                                                               Line 1914
                                                                                
  /* skip over any unwanted header bytes */                                     
  ok &= skip (n_bytes_to_skip);                                                 Line 1917
  if (in_stream == NULL)                                                        Line 1918
    goto cleanup;                                                               Line 1919
                                                                                
  pseudo_offset = (flag_pseudo_start ? pseudo_start - n_bytes_to_skip : 0);     Line 1921
                                                                                
  /* Compute output block length.  */                                           
  l_c_m = get_lcm ();                                                           Line 1924
                                                                                
  if (width_specified)                                                          Line 1926
    {                                                                           
      if (desired_width != 0 && desired_width % l_c_m == 0)                     Line 1928
        bytes_per_block = desired_width;                                        Line 1929
      else                                                                      Line 1930
        {                                                                       
          error (0, 0, _("warning: invalid width %lu; using %d instead"),       Line 1932
                 (unsigned long int) desired_width, l_c_m);                     Line 1933
          bytes_per_block = l_c_m;                                              Line 1934
        }                                                                       
    }                                                                           
  else                                                                          Line 1937
    {                                                                           
      if (l_c_m < DEFAULT_BYTES_PER_BLOCK)                                      Line 1939
        bytes_per_block = l_c_m * (DEFAULT_BYTES_PER_BLOCK / l_c_m);            Line 1940
      else                                                                      Line 1941
        bytes_per_block = l_c_m;                                                Line 1942
    }                                                                           
                                                                                
  /* Compute padding necessary to align output block.  */                       
  for (i = 0; i < n_specs; i++)                                                 Line 1946
    {                                                                           
      int fields_per_block = bytes_per_block / width_bytes[spec[i].size];       Line 1948
      int block_width = (spec[i].field_width + 1) * fields_per_block;           Line 1949
      if (width_per_block < block_width)                                        Line 1950
        width_per_block = block_width;                                          Line 1951
    }                                                                           
  for (i = 0; i < n_specs; i++)                                                 Line 1953
    {                                                                           
      int fields_per_block = bytes_per_block / width_bytes[spec[i].size];       Line 1955
      int block_width = spec[i].field_width * fields_per_block;                 Line 1956
      spec[i].pad_width = width_per_block - block_width;                        Line 1957
    }                                                                           
                                                                                
#ifdef DEBUG                                                                    Line 1960
  printf ("lcm=%d, width_per_block=%"PRIuMAX"\n", l_c_m,                        Line 1961
          (uintmax_t) width_per_block);                                         Line 1962
  for (i = 0; i < n_specs; i++)                                                 Line 1963
    {                                                                           
      int fields_per_block = bytes_per_block / width_bytes[spec[i].size];       Line 1965
      assert (bytes_per_block % width_bytes[spec[i].size] == 0);                Line 1966
      assert (1 <= spec[i].pad_width / fields_per_block);                       Line 1967
      printf ("%d: fmt=\"%s\" in_width=%d out_width=%d pad=%d\n",               Line 1968
              i, spec[i].fmt_string, width_bytes[spec[i].size],                 Line 1969
              spec[i].field_width, spec[i].pad_width);                          Line 1970
    }                                                                           
#endif                                                                          Line 1972
                                                                                
  ok &= (flag_dump_strings ? dump_strings () : dump ());                        Line 1974
                                                                                
cleanup:                                                                        Line 1976
                                                                                
  if (have_read_stdin && fclose (stdin) == EOF)                                 Line 1978...!syscalls auto-comment...
    die (EXIT_FAILURE, errno, _("standard input"));                             Line 1979
                                                                                
  return ok ? EXIT_SUCCESS : EXIT_FAILURE;                                      Line 1981
}                                                                               Block 39