Reformat with GNU indent-1.7.
[platform/upstream/coreutils.git] / src / od.c
1 /* od -- dump files in octal and other formats
2    Copyright (C) 1992 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
17
18 /* Written by Jim Meyering.  */
19
20 /* AIX requires this to be the first thing in the file.  */
21 #ifdef __GNUC__
22 #define alloca __builtin_alloca
23 #else /* not __GNUC__ */
24 #if HAVE_ALLOCA_H
25 #include <alloca.h>
26 #else /* not HAVE_ALLOCA_H */
27 #ifdef _AIX
28  #pragma alloca
29 #else /* not _AIX */
30 char *alloca ();
31 #endif /* not _AIX */
32 #endif /* not HAVE_ALLOCA_H */
33 #endif /* not __GNUC__ */
34
35 #include <stdio.h>
36 #include <assert.h>
37 #include <getopt.h>
38 #include <sys/types.h>
39 #include "system.h"
40
41 #if defined(__GNUC__) || defined(STDC_HEADERS)
42 #include <float.h>
43 #endif
44
45 #ifdef __STDC__
46 typedef long double LONG_DOUBLE;
47 #else
48 typedef double LONG_DOUBLE;
49 #endif
50
51 #if HAVE_LIMITS_H
52 #include <limits.h>
53 #endif
54 #ifndef SCHAR_MAX
55 #define SCHAR_MAX 127
56 #endif
57 #ifndef SHRT_MAX
58 #define SHRT_MAX 32767
59 #endif
60 #ifndef ULONG_MAX
61 #define ULONG_MAX ((unsigned long) ~(unsigned long) 0)
62 #endif
63
64 #define STREQ(a,b) (strcmp((a), (b)) == 0)
65
66 #ifndef MAX
67 #define MAX(a, b) ((a) > (b) ? (a) : (b))
68 #endif
69
70 #ifndef MIN
71 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
72 #endif
73
74 /* The default number of input bytes per output line.  */
75 #define DEFAULT_BYTES_PER_BLOCK 16
76
77 /* The number of decimal digits of precision in a float.  */
78 #ifndef FLT_DIG
79 #define FLT_DIG 7
80 #endif
81
82 /* The number of decimal digits of precision in a double.  */
83 #ifndef DBL_DIG
84 #define DBL_DIG 15
85 #endif
86
87 /* The number of decimal digits of precision in a long double.  */
88 #ifndef LDBL_DIG
89 #define LDBL_DIG DBL_DIG
90 #endif
91
92 char *xmalloc ();
93 char *xrealloc ();
94 void error ();
95
96 enum size_spec
97   {
98     NO_SIZE,
99     CHAR,
100     SHORT,
101     INT,
102     LONG,
103     FP_SINGLE,
104     FP_DOUBLE,
105     FP_LONG_DOUBLE
106   };
107
108 enum output_format
109   {
110     SIGNED_DECIMAL,
111     UNSIGNED_DECIMAL,
112     OCTAL,
113     HEXADECIMAL,
114     FLOATING_POINT,
115     NAMED_CHARACTER,
116     CHARACTER
117   };
118
119 enum strtoul_error
120   {
121     UINT_OK, UINT_INVALID, UINT_INVALID_SUFFIX_CHAR, UINT_OVERFLOW
122   };
123 typedef enum strtoul_error strtoul_error;
124
125 /* Each output format specification (from POSIX `-t spec' or from
126    old-style options) is represented by one of these structures.  */
127 struct tspec
128   {
129     enum output_format fmt;
130     enum size_spec size;
131     void (*print_function) ();
132     char *fmt_string;
133   };
134
135 /* Convert the number of 8-bit bytes of a binary representation to
136    the number of characters (digits + sign if the type is signed)
137    required to represent the same quantity in the specified base/type.
138    For example, a 32-bit (4-byte) quantity may require a field width
139    as wide as the following for these types:
140    11   unsigned octal
141    11   signed decimal
142    10   unsigned decimal
143    8    unsigned hexadecimal  */
144
145 static const unsigned int bytes_to_oct_digits[] =
146 {0, 3, 6, 8, 11, 14, 16, 19, 22, 25, 27, 30, 32, 35, 38, 41, 43};
147
148 static const unsigned int bytes_to_signed_dec_digits[] =
149 {1, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 28, 30, 33, 35, 37, 40};
150
151 static const unsigned int bytes_to_unsigned_dec_digits[] =
152 {0, 3, 5, 8, 10, 13, 15, 17, 20, 22, 25, 27, 29, 32, 34, 37, 39};
153
154 static const unsigned int bytes_to_hex_digits[] =
155 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32};
156
157 /* Convert enum size_spec to the size of the named type.  */
158 static const int width_bytes[] =
159 {
160   -1,
161   sizeof (char),
162   sizeof (short int),
163   sizeof (int),
164   sizeof (long int),
165   sizeof (float),
166   sizeof (double),
167   sizeof (LONG_DOUBLE)
168 };
169
170 /* Names for some non-printing characters.  */
171 static const char *const charname[33] =
172 {
173   "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
174   "bs", "ht", "nl", "vt", "ff", "cr", "so", "si",
175   "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",
176   "can", "em", "sub", "esc", "fs", "gs", "rs", "us",
177   "sp"
178 };
179
180 /* A printf control string for printing a file offset.  */
181 static const char *output_address_fmt_string;
182
183 /* FIXME: make this the number of octal digits in an unsigned long.  */
184 #define MAX_ADDRESS_LENGTH 13
185 static char address_fmt_buffer[MAX_ADDRESS_LENGTH + 1];
186 static char address_pad[MAX_ADDRESS_LENGTH + 1];
187
188 static unsigned long int string_min;
189 static unsigned long int flag_dump_strings;
190
191 /* The number of input bytes to skip before formatting and writing.  */
192 static unsigned long int n_bytes_to_skip = 0;
193
194 /* When non-zero, MAX_BYTES_TO_FORMAT is the maximum number of bytes
195    to be read and formatted.  Otherwise all input is formatted.  */
196 static int limit_bytes_to_format = 0;
197
198 /* The maximum number of bytes that will be formatted.  This
199    value is used only when LIMIT_BYTES_TO_FORMAT is non-zero.  */
200 static unsigned long int max_bytes_to_format;
201
202 /* When non-zero and two or more consecutive blocks are equal, format
203    only the first block and output an asterisk alone on the following
204    line to indicate that identical blocks have been elided.  */
205 static int abbreviate_duplicate_blocks = 1;
206
207 /* An array of specs describing how to format each input block.  */
208 static struct tspec *spec;
209
210 /* The number of format specs.  */
211 static unsigned int n_specs;
212
213 /* The allocated length of SPEC.  */
214 static unsigned int n_specs_allocated;
215
216 /* The number of input bytes formatted per output line.  It must be
217    a multiple of the least common multiple of the sizes associated with
218    the specified output types.  It should be as large as possible, but
219    no larger than 16 -- unless specified with the -w option.  */
220 static unsigned int bytes_per_block;
221
222 /* Human-readable representation of *file_list (for error messages).
223    It differs from *file_list only when *file_list is "-".  */
224 static char const *input_filename;
225
226 /* A NULL-terminated list of the file-arguments from the command line.
227    If no file-arguments were specified, this variable is initialized
228    to { "-", NULL }.  */
229 static char const *const *file_list;
230
231 /* The input stream associated with the current file.  */
232 static FILE *in_stream;
233
234 /* If non-zero, at least one of the files we read was standard input.  */
235 static int have_read_stdin;
236
237 #define LONGEST_INTEGRAL_TYPE long int
238
239 #define MAX_INTEGRAL_TYPE_SIZE sizeof(LONGEST_INTEGRAL_TYPE)
240 static enum size_spec integral_type_size[MAX_INTEGRAL_TYPE_SIZE + 1];
241
242 #define MAX_FP_TYPE_SIZE sizeof(LONG_DOUBLE)
243 static enum size_spec fp_type_size[MAX_FP_TYPE_SIZE + 1];
244
245 static struct option const long_options[] =
246 {
247   /* POSIX options.  */
248   {"skip-bytes", required_argument, NULL, 'j'},
249   {"address-radix", required_argument, NULL, 'A'},
250   {"read-bytes", required_argument, NULL, 'N'},
251   {"format", required_argument, NULL, 't'},
252   {"output-duplicates", no_argument, NULL, 'v'},
253
254   /* non-POSIX options.  */
255   {"strings", optional_argument, NULL, 's'},
256   {"width", optional_argument, NULL, 'w'},
257   {NULL, 0, NULL, 0}
258 };
259
260 /* The name this program was run with.  */
261 char *program_name;
262
263 static void
264 usage ()
265 {
266   fprintf (stderr, "\
267 Usage: %s [-abcdfhiloxv] [-s[bytes]] [-w[bytes]] [-A radix] [-j bytes]\n\
268        [-N bytes] [-t type] [--skip-bytes=bytes] [--address-radix=radix]\n\
269        [--read-bytes=bytes] [--format=type] [--output-duplicates]\n\
270        [--strings[=bytes]] [--width[=bytes]] [file...]\n",
271            program_name);
272   exit (1);
273 }
274
275 /* Compute the greatest common denominator of U and V
276    using Euclid's algorithm.  */
277
278 static unsigned int
279 gcd (u, v)
280      unsigned int u;
281      unsigned int v;
282 {
283   unsigned int t;
284   while (v != 0)
285     {
286       t = u % v;
287       u = v;
288       v = t;
289     }
290   return u;
291 }
292
293 /* Compute the least common multiple of U and V.  */
294
295 static unsigned int
296 lcm (u, v)
297      unsigned int u;
298      unsigned int v;
299 {
300   unsigned int t = gcd (u, v);
301   if (t == 0)
302     return 0;
303   return u * v / t;
304 }
305
306 static strtoul_error
307 my_strtoul (s, base, val, allow_bkm_suffix)
308      const char *s;
309      int base;
310      long unsigned int *val;
311      int allow_bkm_suffix;
312 {
313   char *p;
314   unsigned long int tmp;
315
316   assert (0 <= base && base <= 36);
317
318   tmp = strtoul (s, &p, base);
319   if (errno != 0)
320     return UINT_OVERFLOW;
321   if (p == s)
322     return UINT_INVALID;
323   if (!allow_bkm_suffix)
324     {
325       if (*p == '\0')
326         {
327           *val = tmp;
328           return UINT_OK;
329         }
330       else
331         return UINT_INVALID_SUFFIX_CHAR;
332     }
333
334   switch (*p)
335     {
336     case '\0':
337       break;
338
339 #define BKM_SCALE(x,scale_factor)                       \
340       do                                                \
341         {                                               \
342           if (x > (double) ULONG_MAX / scale_factor)    \
343             return UINT_OVERFLOW;                       \
344           x *= scale_factor;                            \
345         }                                               \
346       while (0)
347
348     case 'b':
349       BKM_SCALE (tmp, 512);
350       break;
351
352     case 'k':
353       BKM_SCALE (tmp, 1024);
354       break;
355
356     case 'm':
357       BKM_SCALE (tmp, 1024 * 1024);
358       break;
359
360     default:
361       return UINT_INVALID_SUFFIX_CHAR;
362       break;
363     }
364
365   *val = tmp;
366   return UINT_OK;
367 }
368
369 static void
370 uint_fatal_error (str, argument_type_string, err)
371      const char *str;
372      const char *argument_type_string;
373      strtoul_error err;
374 {
375   switch (err)
376     {
377     case UINT_OK:
378       abort ();
379
380     case UINT_INVALID:
381       error (2, 0, "invalid %s `%s'", argument_type_string, str);
382       break;
383
384     case UINT_INVALID_SUFFIX_CHAR:
385       error (2, 0, "invalid character following %s `%s'",
386              argument_type_string, str);
387       break;
388
389     case UINT_OVERFLOW:
390       error (2, 0, "%s `%s' larger than maximum unsigned long",
391              argument_type_string, str);
392       break;
393     }
394 }
395
396 static void
397 print_s_char (n_bytes, block, fmt_string)
398      long unsigned int n_bytes;
399      const char *block;
400      const char *fmt_string;
401 {
402   int i;
403   for (i = n_bytes; i > 0; i--)
404     {
405       int tmp = (unsigned) *(const signed char *) block;
406       printf (fmt_string, tmp, (i == 1 ? '\n' : ' '));
407       block += sizeof (unsigned char);
408     }
409 }
410
411 static void
412 print_char (n_bytes, block, fmt_string)
413      long unsigned int n_bytes;
414      const char *block;
415      const char *fmt_string;
416 {
417   int i;
418   for (i = n_bytes; i > 0; i--)
419     {
420       unsigned int tmp = *(const unsigned char *) block;
421       printf (fmt_string, tmp, (i == 1 ? '\n' : ' '));
422       block += sizeof (unsigned char);
423     }
424 }
425
426 static void
427 print_s_short (n_bytes, block, fmt_string)
428      long unsigned int n_bytes;
429      const char *block;
430      const char *fmt_string;
431 {
432   int i;
433   for (i = n_bytes / sizeof (unsigned short); i > 0; i--)
434     {
435       int tmp = (unsigned) *(const signed short *) block;
436       printf (fmt_string, tmp, (i == 1 ? '\n' : ' '));
437       block += sizeof (unsigned short);
438     }
439 }
440
441 static void
442 print_short (n_bytes, block, fmt_string)
443      long unsigned int n_bytes;
444      const char *block;
445      const char *fmt_string;
446 {
447   int i;
448   for (i = n_bytes / sizeof (unsigned short); i > 0; i--)
449     {
450       unsigned int tmp = *(const unsigned short *) block;
451       printf (fmt_string, tmp, (i == 1 ? '\n' : ' '));
452       block += sizeof (unsigned short);
453     }
454 }
455
456 static void
457 print_int (n_bytes, block, fmt_string)
458      long unsigned int n_bytes;
459      const char *block;
460      const char *fmt_string;
461 {
462   int i;
463   for (i = n_bytes / sizeof (unsigned int); i > 0; i--)
464     {
465       unsigned int tmp = *(const unsigned int *) block;
466       printf (fmt_string, tmp, (i == 1 ? '\n' : ' '));
467       block += sizeof (unsigned int);
468     }
469 }
470
471 static void
472 print_long (n_bytes, block, fmt_string)
473      long unsigned int n_bytes;
474      const char *block;
475      const char *fmt_string;
476 {
477   int i;
478   for (i = n_bytes / sizeof (unsigned long); i > 0; i--)
479     {
480       unsigned long tmp = *(const unsigned long *) block;
481       printf (fmt_string, tmp, (i == 1 ? '\n' : ' '));
482       block += sizeof (unsigned long);
483     }
484 }
485
486 static void
487 print_float (n_bytes, block, fmt_string)
488      long unsigned int n_bytes;
489      const char *block;
490      const char *fmt_string;
491 {
492   int i;
493   for (i = n_bytes / sizeof (float); i > 0; i--)
494     {
495       float tmp = *(const float *) block;
496       printf (fmt_string, tmp, (i == 1 ? '\n' : ' '));
497       block += sizeof (float);
498     }
499 }
500
501 static void
502 print_double (n_bytes, block, fmt_string)
503      long unsigned int n_bytes;
504      const char *block;
505      const char *fmt_string;
506 {
507   int i;
508   for (i = n_bytes / sizeof (double); i > 0; i--)
509     {
510       double tmp = *(const double *) block;
511       printf (fmt_string, tmp, (i == 1 ? '\n' : ' '));
512       block += sizeof (double);
513     }
514 }
515
516 #ifdef __STDC__
517 static void
518 print_long_double (n_bytes, block, fmt_string)
519      long unsigned int n_bytes;
520      const char *block;
521      const char *fmt_string;
522 {
523   int i;
524   for (i = n_bytes / sizeof (LONG_DOUBLE); i > 0; i--)
525     {
526       LONG_DOUBLE tmp = *(const LONG_DOUBLE *) block;
527       printf (fmt_string, tmp, (i == 1 ? '\n' : ' '));
528       block += sizeof (LONG_DOUBLE);
529     }
530 }
531
532 #endif
533
534 static void
535 print_named_ascii (n_bytes, block, unused_fmt_string)
536      long unsigned int n_bytes;
537      const char *block;
538      const char *unused_fmt_string;
539 {
540   int i;
541   for (i = n_bytes; i > 0; i--)
542     {
543       unsigned int c = *(const unsigned char *) block;
544       unsigned int masked_c = (0x7f & c);
545       const char *s;
546       char buf[5];
547
548       if (masked_c == 127)
549         s = "del";
550       else if (masked_c <= 040)
551         s = charname[masked_c];
552       else
553         {
554           sprintf (buf, "  %c", masked_c);
555           s = buf;
556         }
557
558       printf ("%3s%c", s, (i == 1 ? '\n' : ' '));
559       block += sizeof (unsigned char);
560     }
561 }
562
563 static void
564 print_ascii (n_bytes, block, unused_fmt_string)
565      long unsigned int n_bytes;
566      const char *block;
567      const char *unused_fmt_string;
568 {
569   int i;
570   for (i = n_bytes; i > 0; i--)
571     {
572       unsigned int c = *(const unsigned char *) block;
573       const char *s;
574       char buf[5];
575
576       switch (c)
577         {
578         case '\0':
579           s = " \\0";
580           break;
581
582         case '\007':
583           s = " \\a";
584           break;
585
586         case '\b':
587           s = " \\b";
588           break;
589
590         case '\f':
591           s = " \\f";
592           break;
593
594         case '\n':
595           s = " \\n";
596           break;
597
598         case '\r':
599           s = " \\r";
600           break;
601
602         case '\t':
603           s = " \\t";
604           break;
605
606         case '\v':
607           s = " \\v";
608           break;
609
610         default:
611           sprintf (buf, (ISPRINT (c) ? "  %c" : "%03o"), c);
612           s = (const char *) buf;
613         }
614
615       printf ("%3s%c", s, (i == 1 ? '\n' : ' '));
616       block += sizeof (unsigned char);
617     }
618 }
619
620 /* Convert a null-terminated (possibly zero-length) string S to an
621    unsigned long integer value.  If S points to a non-digit set *P to S,
622    *VAL to 0, and return 0.  Otherwise, accumulate the integer value of
623    the string of digits.  If the string of digits represents a value
624    larger than ULONG_MAX, don't modify *VAL or *P and return non-zero.
625    Otherwise, advance *P to the first non-digit after S, set *VAL to
626    the result of the conversion and return zero.  */
627
628 static int
629 simple_strtoul (s, p, val)
630      const char *s;
631      const char **p;
632      long unsigned int *val;
633 {
634   unsigned long int sum;
635
636   sum = 0;
637   while (ISDIGIT (*s))
638     {
639       unsigned int c = *s++ - '0';
640       if (sum > (ULONG_MAX - c) / 10)
641         return 1;
642       sum = sum * 10 + c;
643     }
644   *p = s;
645   *val = sum;
646   return 0;
647 }
648
649 /* If S points to a single valid POSIX-style od format string, put a
650    description of that format in *TSPEC, make *NEXT point at the character
651    following the just-decoded format (if *NEXT is non-NULL), and return
652    zero.  If S is not valid, don't modify *NEXT or *TSPEC and return
653    non-zero.  For example, if S were "d4afL" *NEXT would be set to "afL"
654    and *TSPEC would be
655      {
656        fmt = SIGNED_DECIMAL;
657        size = INT or LONG; (whichever integral_type_size[4] resolves to)
658        print_function = print_int; (assuming size == INT)
659        fmt_string = "%011d%c";
660       }
661    */
662
663 static int
664 decode_one_format (s, next, tspec)
665      const char *s;
666      const char **next;
667      struct tspec *tspec;
668 {
669   enum size_spec size_spec;
670   unsigned long int size;
671   enum output_format fmt;
672   const char *pre_fmt_string;
673   char *fmt_string;
674   void (*print_function) ();
675   const char *p;
676   unsigned int c;
677
678   assert (tspec != NULL);
679
680   switch (*s)
681     {
682     case 'd':
683     case 'o':
684     case 'u':
685     case 'x':
686       c = *s;
687       ++s;
688       switch (*s)
689         {
690         case 'C':
691           ++s;
692           size = sizeof (char);
693           break;
694
695         case 'S':
696           ++s;
697           size = sizeof (short);
698           break;
699
700         case 'I':
701           ++s;
702           size = sizeof (int);
703           break;
704
705         case 'L':
706           ++s;
707           size = sizeof (long int);
708           break;
709
710         default:
711           if (simple_strtoul (s, &p, &size) != 0)
712             return 1;
713           if (p == s)
714             size = sizeof (int);
715           else
716             {
717               if (size > MAX_INTEGRAL_TYPE_SIZE
718                   || integral_type_size[size] == NO_SIZE)
719                 return 1;
720               s = p;
721             }
722           break;
723         }
724
725 #define FMT_BYTES_ALLOCATED 9
726       fmt_string = xmalloc (FMT_BYTES_ALLOCATED);
727
728       size_spec = integral_type_size[size];
729
730       switch (c)
731         {
732         case 'd':
733           fmt = SIGNED_DECIMAL;
734           sprintf (fmt_string, "%%0%u%sd%%c",
735                    bytes_to_signed_dec_digits[size],
736                    (size_spec == LONG ? "l" : ""));
737           break;
738
739         case 'o':
740           fmt = OCTAL;
741           sprintf (fmt_string, "%%0%u%so%%c",
742                    bytes_to_oct_digits[size],
743                    (size_spec == LONG ? "l" : ""));
744           break;
745
746         case 'u':
747           fmt = UNSIGNED_DECIMAL;
748           sprintf (fmt_string, "%%0%u%su%%c",
749                    bytes_to_unsigned_dec_digits[size],
750                    (size_spec == LONG ? "l" : ""));
751           break;
752
753         case 'x':
754           fmt = HEXADECIMAL;
755           sprintf (fmt_string, "%%0%u%sx%%c",
756                    bytes_to_hex_digits[size],
757                    (size_spec == LONG ? "l" : ""));
758           break;
759
760         default:
761           abort ();
762         }
763
764       assert (strlen (fmt_string) < FMT_BYTES_ALLOCATED);
765
766       switch (size_spec)
767         {
768         case CHAR:
769           print_function = (fmt == SIGNED_DECIMAL
770                             ? print_s_char
771                             : print_char);
772           break;
773
774         case SHORT:
775           print_function = (fmt == SIGNED_DECIMAL
776                             ? print_s_short
777                             : print_short);;
778           break;
779
780         case INT:
781           print_function = print_int;
782           break;
783
784         case LONG:
785           print_function = print_long;
786           break;
787
788         default:
789           abort ();
790         }
791       break;
792
793     case 'f':
794       fmt = FLOATING_POINT;
795       ++s;
796       switch (*s)
797         {
798         case 'F':
799           ++s;
800           size = sizeof (float);
801           break;
802
803         case 'D':
804           ++s;
805           size = sizeof (double);
806           break;
807
808         case 'L':
809           ++s;
810           size = sizeof (LONG_DOUBLE);
811           break;
812
813         default:
814           if (simple_strtoul (s, &p, &size) != 0)
815             return 1;
816           if (p == s)
817             size = sizeof (double);
818           else
819             {
820               if (size > MAX_FP_TYPE_SIZE
821                   || fp_type_size[size] == NO_SIZE)
822                 return 1;
823               s = p;
824             }
825           break;
826         }
827       size_spec = fp_type_size[size];
828
829       switch (size_spec)
830         {
831         case FP_SINGLE:
832           print_function = print_float;
833           /* Don't use %#e; not all systems support it.  */
834           pre_fmt_string = "%%%d.%de%%c";
835           fmt_string = xmalloc (strlen (pre_fmt_string));
836           sprintf (fmt_string, pre_fmt_string,
837                    FLT_DIG + 8, FLT_DIG);
838           break;
839
840         case FP_DOUBLE:
841           print_function = print_double;
842           pre_fmt_string = "%%%d.%de%%c";
843           fmt_string = xmalloc (strlen (pre_fmt_string));
844           sprintf (fmt_string, pre_fmt_string,
845                    DBL_DIG + 8, DBL_DIG);
846           break;
847
848 #ifdef __STDC__
849         case FP_LONG_DOUBLE:
850           print_function = print_long_double;
851           pre_fmt_string = "%%%d.%dle%%c";
852           fmt_string = xmalloc (strlen (pre_fmt_string));
853           sprintf (fmt_string, pre_fmt_string,
854                    LDBL_DIG + 8, LDBL_DIG);
855           break;
856 #endif
857
858         default:
859           abort ();
860         }
861       break;
862
863     case 'a':
864       ++s;
865       fmt = NAMED_CHARACTER;
866       size_spec = CHAR;
867       fmt_string = NULL;
868       print_function = print_named_ascii;
869       break;
870
871     case 'c':
872       ++s;
873       fmt = CHARACTER;
874       size_spec = CHAR;
875       fmt_string = NULL;
876       print_function = print_ascii;
877       break;
878
879     default:
880       return 1;
881     }
882
883   tspec->size = size_spec;
884   tspec->fmt = fmt;
885   tspec->print_function = print_function;
886   tspec->fmt_string = fmt_string;
887
888   if (next != NULL)
889     *next = s;
890
891   return 0;
892 }
893
894 /* Decode the POSIX-style od format string S.  Append the decoded
895    representation to the global array SPEC, reallocating SPEC if
896    necessary.  Return zero if S is valid, non-zero otherwise.  */
897
898 static int
899 decode_format_string (s)
900      const char *s;
901 {
902   assert (s != NULL);
903
904   while (*s != '\0')
905     {
906       struct tspec tspec;
907       const char *next;
908
909       if (decode_one_format (s, &next, &tspec))
910         return 1;
911
912       assert (s != next);
913       s = next;
914
915       if (n_specs >= n_specs_allocated)
916         {
917           n_specs_allocated = 1 + (3 * n_specs_allocated) / 2;
918           spec = (struct tspec *) xrealloc (spec, (n_specs_allocated
919                                                    * sizeof (struct tspec)));
920         }
921
922       bcopy ((char *) &tspec, (char *) &spec[n_specs], sizeof (struct tspec));
923       ++n_specs;
924     }
925
926   return 0;
927 }
928
929 /* Given a list of one or more input filenames FILE_LIST, set the global
930    file pointer IN_STREAM to position N_SKIP in the concatenation of
931    those files.  If any file operation fails or if there are fewer than
932    N_SKIP bytes in the combined input, give an error message and exit.
933    When possible, use seek- rather than read operations to advance
934    IN_STREAM.  A file name of "-" is interpreted as standard input.  */
935
936 static int
937 skip (n_skip)
938      long unsigned int n_skip;
939 {
940   int err;
941
942   err = 0;
943   for ( /* empty */ ; *file_list != NULL; ++file_list)
944     {
945       struct stat file_stats;
946       int j;
947
948       if (STREQ (*file_list, "-"))
949         {
950           input_filename = "standard input";
951           in_stream = stdin;
952           have_read_stdin = 1;
953         }
954       else
955         {
956           input_filename = *file_list;
957           in_stream = fopen (input_filename, "r");
958           if (in_stream == NULL)
959             {
960               error (0, errno, "%s", input_filename);
961               err = 1;
962               continue;
963             }
964         }
965
966       if (n_skip == 0)
967         break;
968
969       /* First try using fseek.  For large offsets, this extra work is
970          worthwhile.  If the offset is below some threshold it may be
971          more efficient to move the pointer by reading.  There are two
972          issues when trying to use fseek:
973            - the file must be seekable.
974            - before seeking to the specified position, make sure
975              that the new position is in the current file.
976              Try to do that by getting file's size using stat().
977              But that will work only for regular files and dirs.  */
978
979       if (fstat (fileno (in_stream), &file_stats))
980         {
981           error (0, errno, "%s", input_filename);
982           err = 1;
983           continue;
984         }
985
986       /* The st_size field is valid only for regular files and
987          directories.  FIXME: is the preceding true?
988          If the number of bytes left to skip is at least as large as
989          the size of the current file, we can decrement
990          n_skip and go on to the next file.  */
991       if (S_ISREG (file_stats.st_mode) || S_ISDIR (file_stats.st_mode))
992         {
993           if (n_skip >= file_stats.st_size)
994             {
995               n_skip -= file_stats.st_size;
996               if (in_stream != stdin && fclose (in_stream))
997                 {
998                   error (0, errno, "%s", input_filename);
999                   err = 1;
1000                 }
1001               continue;
1002             }
1003           else
1004             {
1005               if (fseek (in_stream, n_skip, SEEK_SET) == 0)
1006                 {
1007                   n_skip = 0;
1008                   break;
1009                 }
1010             }
1011         }
1012
1013       /* fseek didn't work or wasn't attempted; do it the slow way.  */
1014
1015       for (j = n_skip / BUFSIZ; j >= 0; j--)
1016         {
1017           char buf[BUFSIZ];
1018           size_t n_bytes_to_read = (j > 0
1019                                     ? BUFSIZ
1020                                     : n_skip % BUFSIZ);
1021           size_t n_bytes_read;
1022           n_bytes_read = fread (buf, 1, n_bytes_to_read, in_stream);
1023           n_skip -= n_bytes_read;
1024           if (n_bytes_read != n_bytes_to_read)
1025             break;
1026         }
1027
1028       if (n_skip == 0)
1029         break;
1030     }
1031
1032   if (n_skip != 0)
1033     error (2, 0, "cannot skip past end of combined input");
1034
1035   return err;
1036 }
1037
1038 static const char *
1039 format_address (address)
1040      long unsigned int address;
1041 {
1042   const char *address_string;
1043
1044   if (output_address_fmt_string == NULL)
1045     address_string = "";
1046   else
1047     {
1048       sprintf (address_fmt_buffer, output_address_fmt_string, address);
1049       address_string = address_fmt_buffer;
1050     }
1051   return address_string;
1052 }
1053
1054 /* Write N_BYTES bytes from CURR_BLOCK to standard output once for each
1055    of the N_SPEC format specs.  CURRENT_OFFSET is the byte address of
1056    CURR_BLOCK in the concatenation of input files, and it is printed
1057    (optionally) only before the output line associated with the first
1058    format spec.  When duplicate blocks are being abbreviated, the output
1059    for a sequence of identical input blocks is the output for the first
1060    block followed by an asterisk alone on a line.  It is valid to compare
1061    the blocks PREV_BLOCK and CURR_BLOCK only when N_BYTES == BYTES_PER_BLOCK.
1062    That condition may be false only for the last input block -- and then
1063    only when it has not been padded to length BYTES_PER_BLOCK.  */
1064
1065 static void
1066 write_block (current_offset, n_bytes, prev_block, curr_block)
1067      long unsigned int current_offset;
1068      long unsigned int n_bytes;
1069      const char *prev_block;
1070      const char *curr_block;
1071 {
1072   static int first = 1;
1073   static int prev_pair_equal = 0;
1074
1075 #define EQUAL_BLOCKS(b1, b2) (bcmp ((b1), (b2), bytes_per_block) == 0)
1076
1077   if (abbreviate_duplicate_blocks
1078       && !first && n_bytes == bytes_per_block
1079       && EQUAL_BLOCKS (prev_block, curr_block))
1080     {
1081       if (prev_pair_equal)
1082         {
1083           /* The two preceding blocks were equal, and the current
1084              block is the same as the last one, so print nothing.  */
1085         }
1086       else
1087         {
1088           printf ("*\n");
1089           prev_pair_equal = 1;
1090         }
1091     }
1092   else
1093     {
1094       int i;
1095
1096       prev_pair_equal = 0;
1097       for (i = 0; i < n_specs; i++)
1098         {
1099           printf ("%s ", (i == 0
1100                           ? format_address (current_offset)
1101                           : address_pad));
1102           (*spec[i].print_function) (n_bytes, curr_block, spec[i].fmt_string);
1103         }
1104     }
1105   first = 0;
1106 }
1107
1108 /* Test whether there have been errors on in_stream, and close it if
1109    it is not standard input.  Return non-zero if there has been an error
1110    on in_stream or stdout; return zero otherwise.  This function will
1111    report more than one error only if both a read and a write error
1112    have occurred.  */
1113
1114 static int
1115 check_and_close ()
1116 {
1117   int err;
1118
1119   err = 0;
1120   if (ferror (in_stream))
1121     {
1122       error (0, errno, "%s", input_filename);
1123       if (in_stream != stdin)
1124         fclose (in_stream);
1125       err = 1;
1126     }
1127   else if (in_stream != stdin && fclose (in_stream) == EOF)
1128     {
1129       error (0, errno, "%s", input_filename);
1130       err = 1;
1131     }
1132
1133   if (ferror (stdout))
1134     {
1135       error (0, errno, "standard output");
1136       err = 1;
1137     }
1138
1139   return err;
1140 }
1141
1142 /* Read a single byte into *C from the concatenation of the input files
1143    named in the global array FILE_LIST.  On the first call to this
1144    function, the global variable IN_STREAM is expected to be an open
1145    stream associated with the input file *FILE_LIST.  If IN_STREAM is
1146    at end-of-file, close it and update the global variables IN_STREAM,
1147    FILE_LIST, and INPUT_FILENAME so they correspond to the next file in
1148    the list.  Then try to read a byte from the newly opened file.
1149    Repeat if necessary until *FILE_LIST is NULL.  When EOF is reached
1150    for the last file in FILE_LIST, set *C to EOF and return.  Subsequent
1151    calls do likewise.  The return value is non-zero if any errors
1152    occured, zero otherwise.  */
1153
1154 static int
1155 read_char (c)
1156      int *c;
1157 {
1158   int err;
1159
1160   if (*file_list == NULL)
1161     {
1162       *c = EOF;
1163       return 0;
1164     }
1165
1166   err = 0;
1167   while (1)
1168     {
1169       *c = fgetc (in_stream);
1170
1171       if (*c != EOF)
1172         return err;
1173
1174       err |= check_and_close ();
1175
1176       do
1177         {
1178           ++file_list;
1179           if (*file_list == NULL)
1180             return err;
1181
1182           if (STREQ (*file_list, "-"))
1183             {
1184               input_filename = "standard input";
1185               in_stream = stdin;
1186               have_read_stdin = 1;
1187             }
1188           else
1189             {
1190               input_filename = *file_list;
1191               in_stream = fopen (input_filename, "r");
1192               if (in_stream == NULL)
1193                 {
1194                   error (0, errno, "%s", input_filename);
1195                   err = 1;
1196                 }
1197             }
1198         }
1199       while (in_stream == NULL);
1200     }
1201 }
1202
1203 /* Read N bytes into BLOCK from the concatenation of the input files
1204    named in the global array FILE_LIST.  On the first call to this
1205    function, the global variable IN_STREAM is expected to be an open
1206    stream associated with the input file *FILE_LIST.  On subsequent
1207    calls, if *FILE_LIST is NULL, don't modify BLOCK and return zero.
1208    If all N bytes cannot be read from IN_STREAM, close IN_STREAM and
1209    update the global variables IN_STREAM, FILE_LIST, and INPUT_FILENAME.
1210    Then try to read the remaining bytes from the newly opened file.
1211    Repeat if necessary until *FILE_LIST is NULL.  Set *N_BYTES_IN_BUFFER
1212    to the number of bytes read.  If an error occurs, it will be detected
1213    through ferror when the stream is about to be closed.  If there is an
1214    error, give a message but continue reading as usual and return non-zero.
1215    Otherwise return zero.  */
1216
1217 static int
1218 read_block (n, block, n_bytes_in_buffer)
1219      size_t n;
1220      char *block;
1221      size_t *n_bytes_in_buffer;
1222 {
1223   int err;
1224
1225   assert (n > 0 && n <= bytes_per_block);
1226
1227   *n_bytes_in_buffer = 0;
1228
1229   if (n == 0)
1230     return 0;
1231
1232   if (*file_list == NULL)
1233     return 0;                   /* EOF.  */
1234
1235   err = 0;
1236   while (1)
1237     {
1238       size_t n_needed;
1239       size_t n_read;
1240
1241       n_needed = n - *n_bytes_in_buffer;
1242       n_read = fread (block + *n_bytes_in_buffer, 1, n_needed, in_stream);
1243
1244       *n_bytes_in_buffer += n_read;
1245
1246       if (n_read == n_needed)
1247         return err;
1248
1249       err |= check_and_close ();
1250
1251       do
1252         {
1253           ++file_list;
1254           if (*file_list == NULL)
1255             return err;
1256
1257           if (STREQ (*file_list, "-"))
1258             {
1259               input_filename = "standard input";
1260               in_stream = stdin;
1261               have_read_stdin = 1;
1262             }
1263           else
1264             {
1265               input_filename = *file_list;
1266               in_stream = fopen (input_filename, "r");
1267               if (in_stream == NULL)
1268                 {
1269                   error (0, errno, "%s", input_filename);
1270                   err = 1;
1271                 }
1272             }
1273         }
1274       while (in_stream == NULL);
1275     }
1276 }
1277
1278 /* Return the least common multiple of the sizes associated
1279    with the format specs.  */
1280
1281 static int
1282 get_lcm ()
1283 {
1284   int i;
1285   int l_c_m = 1;
1286
1287   for (i = 0; i < n_specs; i++)
1288     l_c_m = lcm (l_c_m, width_bytes[(int) spec[i].size]);
1289   return l_c_m;
1290 }
1291
1292 /* Read a chunk of size BYTES_PER_BLOCK from the input files, write the
1293    formatted block to standard output, and repeat until the specified
1294    maximum number of bytes has been read or until all input has been
1295    processed.  If the last block read is smaller than BYTES_PER_BLOCK
1296    and its size is not a multiple of the size associated with a format
1297    spec, extend the input block with zero bytes until its length is a
1298    multiple of all format spec sizes.  Write the final block.  Finally,
1299    write on a line by itself the offset of the byte after the last byte
1300    read.  Accumulate return values from calls to read_block and
1301    check_and_close, and if any was non-zero, return non-zero.
1302    Otherwise, return zero.  */
1303
1304 static int
1305 dump ()
1306 {
1307   char *block[2];
1308   unsigned long int current_offset;
1309   int idx;
1310   int err;
1311   size_t n_bytes_read;
1312   size_t end_offset;
1313
1314   block[0] = (char *) alloca (bytes_per_block);
1315   block[1] = (char *) alloca (bytes_per_block);
1316
1317   current_offset = n_bytes_to_skip;
1318
1319   idx = 0;
1320   err = 0;
1321   if (limit_bytes_to_format)
1322     {
1323       end_offset = n_bytes_to_skip + max_bytes_to_format;
1324
1325       n_bytes_read = 0;
1326       while (current_offset < end_offset)
1327         {
1328           size_t n_needed;
1329           n_needed = MIN (end_offset - current_offset, bytes_per_block);
1330           err |= read_block (n_needed, block[idx], &n_bytes_read);
1331           if (n_bytes_read < bytes_per_block)
1332             break;
1333           assert (n_bytes_read == bytes_per_block);
1334           write_block (current_offset, n_bytes_read,
1335                        block[!idx], block[idx]);
1336           current_offset += n_bytes_read;
1337           idx = !idx;
1338         }
1339     }
1340   else
1341     {
1342       while (1)
1343         {
1344           err |= read_block (bytes_per_block, block[idx], &n_bytes_read);
1345           if (n_bytes_read < bytes_per_block)
1346             break;
1347           assert (n_bytes_read == bytes_per_block);
1348           write_block (current_offset, n_bytes_read,
1349                        block[!idx], block[idx]);
1350           current_offset += n_bytes_read;
1351           idx = !idx;
1352         }
1353     }
1354
1355   if (n_bytes_read > 0)
1356     {
1357       int l_c_m;
1358       size_t bytes_to_write;
1359
1360       l_c_m = get_lcm ();
1361
1362       /* Make bytes_to_write the smallest multiple of l_c_m that
1363          is at least as large as n_bytes_read.  */
1364       bytes_to_write = l_c_m * (int) ((n_bytes_read + l_c_m - 1) / l_c_m);
1365
1366       bzero (block[idx] + n_bytes_read, bytes_to_write - n_bytes_read);
1367       write_block (current_offset, bytes_to_write,
1368                    block[!idx], block[idx]);
1369       current_offset += n_bytes_read;
1370     }
1371
1372   if (output_address_fmt_string != NULL)
1373     printf ("%s\n", format_address (current_offset));
1374
1375   if (limit_bytes_to_format && current_offset > end_offset)
1376     err |= check_and_close ();
1377
1378   return err;
1379 }
1380
1381 /* STRINGS mode.  Find each "string constant" in the input.
1382    A string constant is a run of at least `string_min' ASCII
1383    graphic (or formatting) characters terminated by a null.
1384    Based on a function written by Richard Stallman for a
1385    pre-POSIX version of od.  Return non-zero if an error
1386    occurs.  Otherwise, return zero.  */
1387
1388 static int
1389 dump_strings ()
1390 {
1391   int bufsize = MAX (100, string_min);
1392   char *buf = xmalloc (bufsize);
1393   unsigned long address = n_bytes_to_skip;
1394   int err;
1395
1396   err = 0;
1397   while (1)
1398     {
1399       int i;
1400       int c;
1401
1402       /* See if the next `string_min' chars are all printing chars.  */
1403     tryline:
1404
1405       if (limit_bytes_to_format
1406           && address >= (n_bytes_to_skip + max_bytes_to_format - string_min))
1407         break;
1408
1409       for (i = 0; i < string_min; i++)
1410         {
1411           err |= read_char (&c);
1412           address++;
1413           if (c < 0)
1414             {
1415               free (buf);
1416               return err;
1417             }
1418           if (!ISPRINT (c))
1419             /* Found a non-printing.  Try again starting with next char.  */
1420             goto tryline;
1421           buf[i] = c;
1422         }
1423
1424       /* We found a run of `string_min' printable characters.
1425          Now see if it is terminated with a null byte.  */
1426       while (!limit_bytes_to_format
1427              || address < n_bytes_to_skip + max_bytes_to_format)
1428         {
1429           if (i == bufsize)
1430             {
1431               bufsize = 1 + 3 * bufsize / 2;
1432               buf = xrealloc (buf, bufsize);
1433             }
1434           err |= read_char (&c);
1435           address++;
1436           if (c < 0)
1437             {
1438               free (buf);
1439               return err;
1440             }
1441           if (c == '\0')
1442             break;              /* It is; print this string.  */
1443           if (!ISPRINT (c))
1444             goto tryline;       /* It isn't; give up on this string.  */
1445           buf[i++] = c;         /* String continues; store it all.  */
1446         }
1447
1448       /* If we get here, the string is all printable and null-terminated,
1449          so print it.  It is all in `buf' and `i' is its length.  */
1450       buf[i] = 0;
1451       if (output_address_fmt_string != NULL)
1452         {
1453           printf ("%s ", format_address (address - i - 1));
1454         }
1455       for (i = 0; (c = buf[i]); i++)
1456         {
1457           switch (c)
1458             {
1459             case '\007':
1460               fputs ("\\a", stdout);
1461               break;
1462
1463             case '\b':
1464               fputs ("\\b", stdout);
1465               break;
1466
1467             case '\f':
1468               fputs ("\\f", stdout);
1469               break;
1470
1471             case '\n':
1472               fputs ("\\n", stdout);
1473               break;
1474
1475             case '\r':
1476               fputs ("\\r", stdout);
1477               break;
1478
1479             case '\t':
1480               fputs ("\\t", stdout);
1481               break;
1482
1483             case '\v':
1484               fputs ("\\v", stdout);
1485               break;
1486
1487             default:
1488               putc (c, stdout);
1489             }
1490         }
1491       putchar ('\n');
1492     }
1493
1494   /* We reach this point only if we search through
1495      (max_bytes_to_format - string_min) bytes before reachine EOF.  */
1496
1497   free (buf);
1498
1499   err |= check_and_close ();
1500   return err;
1501 }
1502
1503 int
1504 main (argc, argv)
1505      int argc;
1506      char **argv;
1507 {
1508   int c;
1509   int n_files;
1510   int i;
1511   unsigned int l_c_m;
1512   unsigned int address_pad_len;
1513   unsigned long int desired_width;
1514   int width_specified = 0;
1515   int err;
1516
1517   program_name = argv[0];
1518   err = 0;
1519
1520   for (i = 0; i <= MAX_INTEGRAL_TYPE_SIZE; i++)
1521     integral_type_size[i] = NO_SIZE;
1522
1523   integral_type_size[sizeof (char)] = CHAR;
1524   integral_type_size[sizeof (short int)] = SHORT;
1525   integral_type_size[sizeof (int)] = INT;
1526   integral_type_size[sizeof (long int)] = LONG;
1527
1528   for (i = 0; i <= MAX_FP_TYPE_SIZE; i++)
1529     fp_type_size[i] = NO_SIZE;
1530
1531   fp_type_size[sizeof (float)] = FP_SINGLE;
1532   /* The array entry for `double' is filled in after that for LONG_DOUBLE
1533      so that if `long double' is the same type or if long double isn't
1534      supported FP_LONG_DOUBLE will never be used.  */
1535   fp_type_size[sizeof (LONG_DOUBLE)] = FP_LONG_DOUBLE;
1536   fp_type_size[sizeof (double)] = FP_DOUBLE;
1537
1538   n_specs = 0;
1539   n_specs_allocated = 5;
1540   spec = (struct tspec *) xmalloc (n_specs_allocated * sizeof (struct tspec));
1541
1542   output_address_fmt_string = "%07o";
1543   address_pad_len = 7;
1544   flag_dump_strings = 0;
1545
1546   while ((c = getopt_long (argc, argv, "abcdfhilos::xw::A:j:N:t:v",
1547                            long_options, (int *) 0))
1548          != EOF)
1549     {
1550       strtoul_error s_err;
1551
1552       switch (c)
1553         {
1554         case 'A':
1555           switch (optarg[0])
1556             {
1557             case 'd':
1558               output_address_fmt_string = "%07d";
1559               address_pad_len = 7;
1560               break;
1561             case 'o':
1562               output_address_fmt_string = "%07o";
1563               address_pad_len = 7;
1564               break;
1565             case 'x':
1566               output_address_fmt_string = "%06x";
1567               address_pad_len = 6;
1568               break;
1569             case 'n':
1570               output_address_fmt_string = NULL;
1571               address_pad_len = 0;
1572               break;
1573             default:
1574               error (2, 0,
1575                      "invalid output address radix `%c'; it must be one character from [doxn]",
1576                      optarg[0]);
1577               break;
1578             }
1579           break;
1580
1581         case 'j':
1582           s_err = my_strtoul (optarg, 0, &n_bytes_to_skip, 1);
1583           if (s_err != UINT_OK)
1584             uint_fatal_error (optarg, "skip argument", s_err);
1585           break;
1586
1587         case 'N':
1588           limit_bytes_to_format = 1;
1589
1590           s_err = my_strtoul (optarg, 0, &max_bytes_to_format, 1);
1591           if (s_err != UINT_OK)
1592             uint_fatal_error (optarg, "limit argument", s_err);
1593           break;
1594
1595         case 's':
1596           if (optarg == NULL)
1597             string_min = 3;
1598           else
1599             {
1600               s_err = my_strtoul (optarg, 0, &string_min, 1);
1601               if (s_err != UINT_OK)
1602                 uint_fatal_error (optarg, "minimum string length", s_err);
1603             }
1604           ++flag_dump_strings;
1605           break;
1606
1607         case 't':
1608           if (decode_format_string (optarg))
1609             error (2, 0, "invalid type string `%s'", optarg);
1610           break;
1611
1612         case 'v':
1613           abbreviate_duplicate_blocks = 0;
1614           break;
1615
1616           /* The next several cases map the old, pre-POSIX format
1617              specification options to the corresponding POSIX format
1618              specs.  GNU od accepts any combination of old- and
1619              new-style options.  Format specification options accumulate.  */
1620
1621 #define CASE_OLD_ARG(old_char,new_string)               \
1622         case old_char:                                  \
1623           {                                             \
1624             int tmp;                                    \
1625             tmp = decode_format_string (new_string);    \
1626             assert (tmp == 0);                          \
1627           }                                             \
1628           break
1629
1630           CASE_OLD_ARG ('a', "a");
1631           CASE_OLD_ARG ('b', "oC");
1632           CASE_OLD_ARG ('c', "c");
1633           CASE_OLD_ARG ('d', "u2");
1634           CASE_OLD_ARG ('f', "fF");
1635           CASE_OLD_ARG ('h', "x2");
1636           CASE_OLD_ARG ('i', "d2");
1637           CASE_OLD_ARG ('l', "d4");
1638           CASE_OLD_ARG ('o', "o2");
1639           CASE_OLD_ARG ('x', "x2");
1640
1641 #undef CASE_OLD_ARG
1642
1643         case 'w':
1644           width_specified = 1;
1645           if (optarg == NULL)
1646             {
1647               desired_width = 32;
1648             }
1649           else
1650             {
1651               s_err = my_strtoul (optarg, 10, &desired_width, 0);
1652               if (s_err != UINT_OK)
1653                 error (2, 0, "invalid width specification `%s'", optarg);
1654             }
1655           break;
1656
1657         default:
1658           usage ();
1659           break;
1660         }
1661     }
1662
1663   if (flag_dump_strings && n_specs > 0)
1664     error (2, 0, "no type may be specified when dumping strings");
1665
1666   assert (address_pad_len <= MAX_ADDRESS_LENGTH);
1667   for (i = 0; i < address_pad_len; i++)
1668     address_pad[i] = ' ';
1669   address_pad[address_pad_len] = '\0';
1670
1671   if (n_specs == 0)
1672     {
1673       int d_err = decode_one_format ("o2", NULL, &(spec[0]));
1674
1675       assert (d_err == 0);
1676       n_specs = 1;
1677     }
1678
1679   n_files = argc - optind;
1680   if (n_files > 0)
1681     file_list = (char const *const *) &argv[optind];
1682   else
1683     {
1684       /* If no files were listed on the command line, set up the
1685          global array FILE_LIST so that it contains the null-terminated
1686          list of one name: "-".  */
1687       static char const *const default_file_list[] = {"-", NULL};
1688
1689       file_list = default_file_list;
1690     }
1691
1692   err |= skip (n_bytes_to_skip);
1693
1694   /* Compute output block length.  */
1695   l_c_m = get_lcm ();
1696
1697   if (width_specified)
1698     {
1699       if (desired_width != 0 && desired_width % l_c_m == 0)
1700         bytes_per_block = desired_width;
1701       else
1702         {
1703           error (0, 0, "warning: invalid width %d; using %d instead",
1704                  desired_width, l_c_m);
1705           bytes_per_block = l_c_m;
1706         }
1707     }
1708   else
1709     {
1710       if (l_c_m < DEFAULT_BYTES_PER_BLOCK)
1711         bytes_per_block = l_c_m * (int) (DEFAULT_BYTES_PER_BLOCK / l_c_m);
1712       else
1713         bytes_per_block = l_c_m;
1714     }
1715
1716 #ifdef DEBUG
1717   for (i = 0; i < n_specs; i++)
1718     {
1719       printf ("%d: fmt=\"%s\" width=%d\n",
1720               i, spec[i].fmt_string, width_bytes[spec[i].size]);
1721     }
1722 #endif
1723
1724   err |= (flag_dump_strings ? dump_strings () : dump ());
1725
1726   if (have_read_stdin && fclose (stdin) == EOF)
1727     error (2, errno, "standard input");
1728
1729   if (fclose (stdout) == EOF)
1730     error (2, errno, "write error");
1731
1732   exit (err);
1733 }