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