summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2004-08-03 14:38:53 +0000
committerPaul Eggert <eggert@cs.ucla.edu>2004-08-03 14:38:53 +0000
commit224059ad65e3d89abdb01150a1e7796fdf461ad5 (patch)
tree8543a8bb6598273aa03222976d4a9f8b3a836742
parent77f4620b240f1fdf6dd76b1422e4fb556d4e6ce8 (diff)
downloadcoreutils-224059ad65e3d89abdb01150a1e7796fdf461ad5.tar.xz
(FMT_BYTES_ALLOCATED): Now an enum, not a decimal
constant. Do not assume PRIdMAX etc. are strings of length 3 or less. (struct tspec): Use it. fmt_string is now an array, not a pointer, as there's little point to the indirection here. (struct tspec, flag_dump_strings, traditional, flag_pseudo_start, limit_bytes_to_format, abbreviate_duplicate_blocks, have_read_stdin, simple_strtoul, decode_one_format, open_next_file, check_and_close, decode_format_string, skip, write_block, read_char, read_block, parse_old_offset, dump, dump_strings, main): Use bool for booleans. (struct tspec): Use void *, not char *, for generic pointers. (bytes_to_oct_digits, bytes_to_signed_dec_digits, bytes_to_unsigned_dec_digits, bytes_to_hex_digits): Use char, not unsigned int, since char suffices. (print_s_char, print_char, print_s_short, print_short, print_int, print_long, print_long_long, print_float, print_double, print_long_double): Rewrite to avoid casts. These now take void * arguments, instead of char *. Use the same body for all functions, except for the choice of type. Assume C89 to simplify handling of signed char. (dump_hexl_mode_trailer, print_named_ascii, print_ascii): Rewrite to avoid casts. (print_named_ascii, print_ascii): Now takes void *, not char *. (decode_one_format): Use int for printf field widths, not unsigned int. Pass void * to subsidiary printers, not char *. Simplify handling of floating-point formats by factoring out common code dealing with precision and field width. (decode_format_string): Avoid need for temporary copy of each decoded struct tspec. (get_lcm): Remove unnecessary cast. (main): Fix bug where more than INT_MAX failed decodes were ignored.
-rw-r--r--src/od.c486
1 files changed, 220 insertions, 266 deletions
diff --git a/src/od.c b/src/od.c
index 452e16b90..9f68bd4e1 100644
--- a/src/od.c
+++ b/src/od.c
@@ -63,7 +63,7 @@ typedef double LONG_DOUBLE;
#endif
#if HAVE_UNSIGNED_LONG_LONG
-typedef unsigned long long ulonglong_t;
+typedef unsigned long long int ulonglong_t;
#else
/* This is just a place-holder to avoid a few `#if' directives.
In this case, the type isn't actually used. */
@@ -96,15 +96,29 @@ enum output_format
CHARACTER
};
+/* The maximum number of bytes needed for a format string,
+ including the trailing null. */
+enum
+ {
+ FMT_BYTES_ALLOCATED =
+ MAX ((sizeof " %0" - 1 + INT_STRLEN_BOUND (int)
+ + MAX (sizeof "ld",
+ MAX (sizeof PRIdMAX,
+ MAX (sizeof PRIoMAX,
+ MAX (sizeof PRIuMAX,
+ sizeof PRIxMAX))))),
+ sizeof " %.Le" + 2 * INT_STRLEN_BOUND (int))
+ };
+
/* Each output format specification (from `-t spec' or from
old-style options) is represented by one of these structures. */
struct tspec
{
enum output_format fmt;
enum size_spec size;
- void (*print_function) (size_t, const char *, const char *);
- char *fmt_string;
- int hexl_mode_trailer;
+ void (*print_function) (size_t, void const *, char const *);
+ char fmt_string[FMT_BYTES_ALLOCATED];
+ bool hexl_mode_trailer;
int field_width;
};
@@ -121,16 +135,16 @@ char *program_name;
10 unsigned decimal
8 unsigned hexadecimal */
-static const unsigned int bytes_to_oct_digits[] =
+static char const bytes_to_oct_digits[] =
{0, 3, 6, 8, 11, 14, 16, 19, 22, 25, 27, 30, 32, 35, 38, 41, 43};
-static const unsigned int bytes_to_signed_dec_digits[] =
+static char const bytes_to_signed_dec_digits[] =
{1, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 28, 30, 33, 35, 37, 40};
-static const unsigned int bytes_to_unsigned_dec_digits[] =
+static char const bytes_to_unsigned_dec_digits[] =
{0, 3, 5, 8, 10, 13, 15, 17, 20, 22, 25, 27, 29, 32, 34, 37, 39};
-static const unsigned int bytes_to_hex_digits[] =
+static char const bytes_to_hex_digits[] =
{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32};
/* Convert enum size_spec to the size of the named type. */
@@ -177,15 +191,15 @@ static int address_base;
static int address_pad_len;
static size_t string_min;
-static int flag_dump_strings;
+static bool flag_dump_strings;
-/* Non-zero if we should recognize the older non-option arguments
+/* True if we should recognize the older non-option arguments
that specified at most one file and optional arguments specifying
offset and pseudo-start address. */
-static int traditional;
+static bool traditional;
-/* Non-zero if an old-style `pseudo-address' was specified. */
-static int flag_pseudo_start;
+/* True if an old-style `pseudo-address' was specified. */
+static bool flag_pseudo_start;
/* The difference between the old-style pseudo starting address and
the number of bytes to skip. */
@@ -198,9 +212,9 @@ static void (*format_address) (uintmax_t, char);
/* The number of input bytes to skip before formatting and writing. */
static uintmax_t n_bytes_to_skip = 0;
-/* When zero, MAX_BYTES_TO_FORMAT and END_OFFSET are ignored, and all
+/* When false, MAX_BYTES_TO_FORMAT and END_OFFSET are ignored, and all
input is formatted. */
-static int limit_bytes_to_format = 0;
+static bool limit_bytes_to_format = false;
/* The maximum number of bytes that will be formatted. */
static uintmax_t max_bytes_to_format;
@@ -208,10 +222,10 @@ static uintmax_t max_bytes_to_format;
/* The offset of the first byte after the last byte to be formatted. */
static uintmax_t end_offset;
-/* When nonzero and two or more consecutive blocks are equal, format
+/* When true and two or more consecutive blocks are equal, format
only the first block and output an asterisk alone on the following
line to indicate that identical blocks have been elided. */
-static int abbreviate_duplicate_blocks = 1;
+static bool abbreviate_duplicate_blocks = true;
/* An array of specs describing how to format each input block. */
static struct tspec *spec;
@@ -242,13 +256,13 @@ static char const *const default_file_list[] = {"-", NULL};
/* The input stream associated with the current file. */
static FILE *in_stream;
-/* If nonzero, at least one of the files we read was standard input. */
-static int have_read_stdin;
+/* If true, at least one of the files we read was standard input. */
+static bool have_read_stdin;
#define MAX_INTEGRAL_TYPE_SIZE sizeof (ulonglong_t)
static enum size_spec integral_type_size[MAX_INTEGRAL_TYPE_SIZE + 1];
-#define MAX_FP_TYPE_SIZE sizeof(LONG_DOUBLE)
+#define MAX_FP_TYPE_SIZE sizeof (LONG_DOUBLE)
static enum size_spec fp_type_size[MAX_FP_TYPE_SIZE + 1];
#define COMMON_SHORT_OPTIONS "A:N:abcdfhij:lot:vx"
@@ -372,133 +386,98 @@ implies 32. By default, od uses -A o -t d2 -w 16.\n\
exit (status);
}
+/* Define the print functions. */
+
static void
-print_s_char (size_t n_bytes, const char *block, const char *fmt_string)
+print_s_char (size_t n_bytes, void const *block, char const *fmt_string)
{
+ signed char const *p = block;
size_t i;
- for (i = n_bytes; i > 0; i--)
- {
- int tmp = (unsigned) *(const unsigned char *) block;
- if (tmp > SCHAR_MAX)
- tmp -= SCHAR_MAX - SCHAR_MIN + 1;
- assert (tmp <= SCHAR_MAX);
- printf (fmt_string, tmp);
- block += sizeof (unsigned char);
- }
+ for (i = n_bytes / sizeof *p; i != 0; i--)
+ printf (fmt_string, *p++);
}
static void
-print_char (size_t n_bytes, const char *block, const char *fmt_string)
+print_char (size_t n_bytes, void const *block, char const *fmt_string)
{
+ unsigned char const *p = block;
size_t i;
- for (i = n_bytes; i > 0; i--)
- {
- unsigned int tmp = *(const unsigned char *) block;
- printf (fmt_string, tmp);
- block += sizeof (unsigned char);
- }
+ for (i = n_bytes / sizeof *p; i != 0; i--)
+ printf (fmt_string, *p++);
}
static void
-print_s_short (size_t n_bytes, const char *block, const char *fmt_string)
+print_s_short (size_t n_bytes, void const *block, char const *fmt_string)
{
+ short int const *p = block;
size_t i;
- for (i = n_bytes / sizeof (unsigned short); i > 0; i--)
- {
- int tmp = (unsigned) *(const unsigned short *) block;
- if (tmp > SHRT_MAX)
- tmp -= SHRT_MAX - SHRT_MIN + 1;
- assert (tmp <= SHRT_MAX);
- printf (fmt_string, tmp);
- block += sizeof (unsigned short);
- }
+ for (i = n_bytes / sizeof *p; i != 0; i--)
+ printf (fmt_string, *p++);
}
static void
-print_short (size_t n_bytes, const char *block, const char *fmt_string)
+print_short (size_t n_bytes, void const *block, char const *fmt_string)
{
+ unsigned short int const *p = block;
size_t i;
- for (i = n_bytes / sizeof (unsigned short); i > 0; i--)
- {
- unsigned int tmp = *(const unsigned short *) block;
- printf (fmt_string, tmp);
- block += sizeof (unsigned short);
- }
+ for (i = n_bytes / sizeof *p; i != 0; i--)
+ printf (fmt_string, *p++);
}
static void
-print_int (size_t n_bytes, const char *block, const char *fmt_string)
+print_int (size_t n_bytes, void const *block, char const *fmt_string)
{
+ unsigned int const *p = block;
size_t i;
- for (i = n_bytes / sizeof (unsigned int); i > 0; i--)
- {
- unsigned int tmp = *(const unsigned int *) block;
- printf (fmt_string, tmp);
- block += sizeof (unsigned int);
- }
+ for (i = n_bytes / sizeof *p; i != 0; i--)
+ printf (fmt_string, *p++);
}
static void
-print_long (size_t n_bytes, const char *block, const char *fmt_string)
+print_long (size_t n_bytes, void const *block, char const *fmt_string)
{
+ unsigned long int const *p = block;
size_t i;
- for (i = n_bytes / sizeof (unsigned long); i > 0; i--)
- {
- unsigned long tmp = *(const unsigned long *) block;
- printf (fmt_string, tmp);
- block += sizeof (unsigned long);
- }
+ for (i = n_bytes / sizeof *p; i != 0; i--)
+ printf (fmt_string, *p++);
}
static void
-print_long_long (size_t n_bytes, const char *block, const char *fmt_string)
+print_long_long (size_t n_bytes, void const *block, char const *fmt_string)
{
+ ulonglong_t const *p = block;
size_t i;
- for (i = n_bytes / sizeof (ulonglong_t); i > 0; i--)
- {
- ulonglong_t tmp = *(const ulonglong_t *) block;
- printf (fmt_string, tmp);
- block += sizeof (ulonglong_t);
- }
+ for (i = n_bytes / sizeof *p; i != 0; i--)
+ printf (fmt_string, *p++);
}
static void
-print_float (size_t n_bytes, const char *block, const char *fmt_string)
+print_float (size_t n_bytes, void const *block, char const *fmt_string)
{
+ float const *p = block;
size_t i;
- for (i = n_bytes / sizeof (float); i > 0; i--)
- {
- float tmp = *(const float *) block;
- printf (fmt_string, tmp);
- block += sizeof (float);
- }
+ for (i = n_bytes / sizeof *p; i != 0; i--)
+ printf (fmt_string, *p++);
}
static void
-print_double (size_t n_bytes, const char *block, const char *fmt_string)
+print_double (size_t n_bytes, void const *block, char const *fmt_string)
{
+ double const *p = block;
size_t i;
- for (i = n_bytes / sizeof (double); i > 0; i--)
- {
- double tmp = *(const double *) block;
- printf (fmt_string, tmp);
- block += sizeof (double);
- }
+ for (i = n_bytes / sizeof *p; i != 0; i--)
+ printf (fmt_string, *p++);
}
#ifdef HAVE_LONG_DOUBLE
static void
-print_long_double (size_t n_bytes, const char *block, const char *fmt_string)
+print_long_double (size_t n_bytes, void const *block, char const *fmt_string)
{
+ long double const *p = block;
size_t i;
- for (i = n_bytes / sizeof (LONG_DOUBLE); i > 0; i--)
- {
- LONG_DOUBLE tmp = *(const LONG_DOUBLE *) block;
- printf (fmt_string, tmp);
- block += sizeof (LONG_DOUBLE);
- }
+ for (i = n_bytes / sizeof *p; i != 0; i--)
+ printf (fmt_string, *p++);
}
-
#endif
static void
@@ -508,23 +487,22 @@ dump_hexl_mode_trailer (size_t n_bytes, const char *block)
fputs (" >", stdout);
for (i = n_bytes; i > 0; i--)
{
- unsigned int c = *(const unsigned char *) block;
- unsigned int c2 = (ISPRINT(c) ? c : '.');
+ unsigned char c = *block++;
+ unsigned char c2 = (ISPRINT(c) ? c : '.');
putchar (c2);
- block += sizeof (unsigned char);
}
putchar ('<');
}
static void
-print_named_ascii (size_t n_bytes, const char *block,
+print_named_ascii (size_t n_bytes, void const *block,
const char *unused_fmt_string ATTRIBUTE_UNUSED)
{
+ unsigned char const *p = block;
size_t i;
for (i = n_bytes; i > 0; i--)
{
- unsigned int c = *(const unsigned char *) block;
- unsigned int masked_c = (0x7f & c);
+ int masked_c = *p++ & 0x7f;
const char *s;
char buf[5];
@@ -539,18 +517,18 @@ print_named_ascii (size_t n_bytes, const char *block,
}
printf (" %3s", s);
- block += sizeof (unsigned char);
}
}
static void
-print_ascii (size_t n_bytes, const char *block,
+print_ascii (size_t n_bytes, void const *block,
const char *unused_fmt_string ATTRIBUTE_UNUSED)
{
+ unsigned char const *p = block;
size_t i;
for (i = n_bytes; i > 0; i--)
{
- unsigned int c = *(const unsigned char *) block;
+ unsigned char c = *p++;
const char *s;
char buf[5];
@@ -590,45 +568,44 @@ print_ascii (size_t n_bytes, const char *block,
default:
sprintf (buf, (ISPRINT (c) ? " %c" : "%03o"), c);
- s = (const char *) buf;
+ s = buf;
}
printf (" %3s", s);
- block += sizeof (unsigned char);
}
}
/* Convert a null-terminated (possibly zero-length) string S to an
unsigned long integer value. If S points to a non-digit set *P to S,
- *VAL to 0, and return 0. Otherwise, accumulate the integer value of
+ *VAL to 0, and return true. Otherwise, accumulate the integer value of
the string of digits. If the string of digits represents a value
- larger than ULONG_MAX, don't modify *VAL or *P and return nonzero.
+ larger than ULONG_MAX, don't modify *VAL or *P and return false.
Otherwise, advance *P to the first non-digit after S, set *VAL to
- the result of the conversion and return zero. */
+ the result of the conversion and return true. */
-static int
-simple_strtoul (const char *s, const char **p, long unsigned int *val)
+static bool
+simple_strtoul (const char *s, const char **p, unsigned long int *val)
{
unsigned long int sum;
sum = 0;
while (ISDIGIT (*s))
{
- unsigned int c = *s++ - '0';
+ int c = *s++ - '0';
if (sum > (ULONG_MAX - c) / 10)
- return 1;
+ return false;
sum = sum * 10 + c;
}
*p = s;
*val = sum;
- return 0;
+ return true;
}
/* If S points to a single valid modern od format string, put
a description of that format in *TSPEC, make *NEXT point at the
character following the just-decoded format (if *NEXT is non-NULL),
- and return zero. If S is not valid, don't modify *NEXT or *TSPEC,
- give a diagnostic, and return nonzero. For example, if S were
+ and return true. If S is not valid, don't modify *NEXT or *TSPEC,
+ give a diagnostic, and return false. For example, if S were
"d4afL" *NEXT would be set to "afL" and *TSPEC would be
{
fmt = SIGNED_DECIMAL;
@@ -640,7 +617,7 @@ simple_strtoul (const char *s, const char **p, long unsigned int *val)
string argument.
*/
-static int
+static bool
decode_one_format (const char *s_orig, const char *s, const char **next,
struct tspec *tspec)
{
@@ -648,11 +625,11 @@ decode_one_format (const char *s_orig, const char *s, const char **next,
unsigned long int size;
enum output_format fmt;
const char *pre_fmt_string;
- char *fmt_string;
- void (*print_function) (size_t, const char *, const char *);
+ void (*print_function) (size_t, void const *, char const *);
const char *p;
- unsigned int c;
- unsigned int field_width = 0;
+ char c;
+ int field_width;
+ int precision;
assert (tspec != NULL);
@@ -673,7 +650,7 @@ decode_one_format (const char *s_orig, const char *s, const char **next,
case 'S':
++s;
- size = sizeof (short);
+ size = sizeof (short int);
break;
case 'I':
@@ -687,13 +664,13 @@ decode_one_format (const char *s_orig, const char *s, const char **next,
break;
default:
- if (simple_strtoul (s, &p, &size) != 0)
+ if (! simple_strtoul (s, &p, &size))
{
- /* The integer at P in S would overflow an unsigned long.
+ /* The integer at P in S would overflow an unsigned long int.
A digit string that long is sufficiently odd looking
that the following diagnostic is sufficient. */
error (0, 0, _("invalid type string `%s'"), s_orig);
- return 1;
+ return false;
}
if (p == s)
size = sizeof (int);
@@ -704,7 +681,7 @@ decode_one_format (const char *s_orig, const char *s, const char **next,
{
error (0, 0, _("invalid type string `%s';\n\
this system doesn't provide a %lu-byte integral type"), s_orig, size);
- return 1;
+ return false;
}
s = p;
}
@@ -716,37 +693,34 @@ this system doesn't provide a %lu-byte integral type"), s_orig, size);
: ((Spec) == LONG ? (Long_format) \
: (Min_format))) \
-#define FMT_BYTES_ALLOCATED 9
- fmt_string = xmalloc (FMT_BYTES_ALLOCATED);
-
size_spec = integral_type_size[size];
switch (c)
{
case 'd':
fmt = SIGNED_DECIMAL;
- sprintf (fmt_string, " %%%u%s",
+ sprintf (tspec->fmt_string, " %%%d%s",
(field_width = bytes_to_signed_dec_digits[size]),
ISPEC_TO_FORMAT (size_spec, "d", "ld", PRIdMAX));
break;
case 'o':
fmt = OCTAL;
- sprintf (fmt_string, " %%0%u%s",
+ sprintf (tspec->fmt_string, " %%0%d%s",
(field_width = bytes_to_oct_digits[size]),
ISPEC_TO_FORMAT (size_spec, "o", "lo", PRIoMAX));
break;
case 'u':
fmt = UNSIGNED_DECIMAL;
- sprintf (fmt_string, " %%%u%s",
+ sprintf (tspec->fmt_string, " %%%d%s",
(field_width = bytes_to_unsigned_dec_digits[size]),
ISPEC_TO_FORMAT (size_spec, "u", "lu", PRIuMAX));
break;
case 'x':
fmt = HEXADECIMAL;
- sprintf (fmt_string, " %%0%u%s",
+ sprintf (tspec->fmt_string, " %%0%d%s",
(field_width = bytes_to_hex_digits[size]),
ISPEC_TO_FORMAT (size_spec, "x", "lx", PRIxMAX));
break;
@@ -755,7 +729,7 @@ this system doesn't provide a %lu-byte integral type"), s_orig, size);
abort ();
}
- assert (strlen (fmt_string) < FMT_BYTES_ALLOCATED);
+ assert (strlen (tspec->fmt_string) < FMT_BYTES_ALLOCATED);
switch (size_spec)
{
@@ -809,13 +783,13 @@ this system doesn't provide a %lu-byte integral type"), s_orig, size);
break;
default:
- if (simple_strtoul (s, &p, &size) != 0)
+ if (! simple_strtoul (s, &p, &size))
{
- /* The integer at P in S would overflow an unsigned long.
+ /* The integer at P in S would overflow an unsigned long int.
A digit string that long is sufficiently odd looking
that the following diagnostic is sufficient. */
error (0, 0, _("invalid type string `%s'"), s_orig);
- return 1;
+ return false;
}
if (p == s)
size = sizeof (double);
@@ -826,7 +800,7 @@ this system doesn't provide a %lu-byte integral type"), s_orig, size);
{
error (0, 0, _("invalid type string `%s';\n\
this system doesn't provide a %lu-byte floating point type"), s_orig, size);
- return 1;
+ return false;
}
s = p;
}
@@ -840,39 +814,35 @@ this system doesn't provide a %lu-byte floating point type"), s_orig, size);
print_function = print_float;
/* Don't use %#e; not all systems support it. */
pre_fmt_string = " %%%d.%de";
- fmt_string = xmalloc (strlen (pre_fmt_string));
- sprintf (fmt_string, pre_fmt_string,
- (field_width = FLT_DIG + 8), FLT_DIG);
+ precision = FLT_DIG;
break;
case FLOAT_DOUBLE:
print_function = print_double;
pre_fmt_string = " %%%d.%de";
- fmt_string = xmalloc (strlen (pre_fmt_string));
- sprintf (fmt_string, pre_fmt_string,
- (field_width = DBL_DIG + 8), DBL_DIG);
+ precision = DBL_DIG;
break;
#ifdef HAVE_LONG_DOUBLE
case FLOAT_LONG_DOUBLE:
print_function = print_long_double;
pre_fmt_string = " %%%d.%dLe";
- fmt_string = xmalloc (strlen (pre_fmt_string));
- sprintf (fmt_string, pre_fmt_string,
- (field_width = LDBL_DIG + 8), LDBL_DIG);
+ precision = LDBL_DIG;
break;
#endif
default:
abort ();
}
+
+ field_width = precision + 8;
+ sprintf (tspec->fmt_string, pre_fmt_string, field_width, precision);
break;
case 'a':
++s;
fmt = NAMED_CHARACTER;
size_spec = CHAR;
- fmt_string = NULL;
print_function = print_named_ascii;
field_width = 3;
break;
@@ -881,7 +851,6 @@ this system doesn't provide a %lu-byte floating point type"), s_orig, size);
++s;
fmt = CHARACTER;
size_spec = CHAR;
- fmt_string = NULL;
print_function = print_ascii;
field_width = 3;
break;
@@ -889,13 +858,12 @@ this system doesn't provide a %lu-byte floating point type"), s_orig, size);
default:
error (0, 0, _("invalid character `%c' in type string `%s'"),
*s, s_orig);
- return 1;
+ return false;
}
tspec->size = size_spec;
tspec->fmt = fmt;
tspec->print_function = print_function;
- tspec->fmt_string = fmt_string;
tspec->field_width = field_width;
tspec->hexl_mode_trailer = (*s == 'z');
@@ -905,7 +873,7 @@ this system doesn't provide a %lu-byte floating point type"), s_orig, size);
if (next != NULL)
*next = s;
- return 0;
+ return true;
}
/* Given a list of one or more input filenames FILE_LIST, set the global
@@ -913,25 +881,25 @@ this system doesn't provide a %lu-byte floating point type"), s_orig, size);
first one that can be successfully opened. Modify FILE_LIST to
reference the next filename in the list. A file name of "-" is
interpreted as standard input. If any file open fails, give an error
- message and return nonzero. */
+ message and return false. */
-static int
+static bool
open_next_file (void)
{
- int err = 0;
+ bool ok = true;
do
{
input_filename = *file_list;
if (input_filename == NULL)
- return err;
+ return ok;
++file_list;
if (STREQ (input_filename, "-"))
{
input_filename = _("standard input");
in_stream = stdin;
- have_read_stdin = 1;
+ have_read_stdin = true;
}
else
{
@@ -939,30 +907,30 @@ open_next_file (void)
if (in_stream == NULL)
{
error (0, errno, "%s", input_filename);
- err = 1;
+ ok = false;
}
}
}
while (in_stream == NULL);
- if (limit_bytes_to_format && !flag_dump_strings)
+ if (limit_bytes_to_format & !flag_dump_strings)
SETVBUF (in_stream, NULL, _IONBF, 0);
SET_BINARY (fileno (in_stream));
- return err;
+ return ok;
}
/* Test whether there have been errors on in_stream, and close it if
- it is not standard input. Return nonzero if there has been an error
- on in_stream or stdout; return zero otherwise. This function will
+ it is not standard input. Return false if there has been an error
+ on in_stream or stdout; return true otherwise. This function will
report more than one error only if both a read and a write error
have occurred. IN_ERRNO, if nonzero, is the error number
corresponding to the most recent action for IN_STREAM. */
-static int
+static bool
check_and_close (int in_errno)
{
- int err = 0;
+ bool ok = true;
if (in_stream != NULL)
{
@@ -971,12 +939,12 @@ check_and_close (int in_errno)
error (0, in_errno, _("%s: read error"), input_filename);
if (in_stream != stdin)
fclose (in_stream);
- err = 1;
+ ok = false;
}
else if (in_stream != stdin && fclose (in_stream) == EOF)
{
error (0, errno, "%s", input_filename);
- err = 1;
+ ok = false;
}
in_stream = NULL;
@@ -985,17 +953,17 @@ check_and_close (int in_errno)
if (ferror (stdout))
{
error (0, 0, _("write error"));
- err = 1;
+ ok = false;
}
- return err;
+ return ok;
}
/* Decode the modern od format string S. Append the decoded
representation to the global array SPEC, reallocating SPEC if
- necessary. Return zero if S is valid, nonzero otherwise. */
+ necessary. Return true if S is valid. */
-static int
+static bool
decode_format_string (const char *s)
{
const char *s_orig = s;
@@ -1003,40 +971,37 @@ decode_format_string (const char *s)
while (*s != '\0')
{
- struct tspec tspec;
const char *next;
- if (decode_one_format (s_orig, s, &next, &tspec))
- return 1;
-
- assert (s != next);
- s = next;
-
if (n_specs_allocated <= n_specs)
spec = x2nrealloc (spec, &n_specs_allocated, sizeof *spec);
- memcpy (&spec[n_specs], &tspec, sizeof *spec);
+ if (! decode_one_format (s_orig, s, &next, &spec[n_specs]))
+ return false;
+
+ assert (s != next);
+ s = next;
++n_specs;
}
- return 0;
+ return true;
}
/* Given a list of one or more input filenames FILE_LIST, set the global
file pointer IN_STREAM to position N_SKIP in the concatenation of
those files. If any file operation fails or if there are fewer than
N_SKIP bytes in the combined input, give an error message and return
- nonzero. When possible, use seek rather than read operations to
+ false. When possible, use seek rather than read operations to
advance IN_STREAM. */
-static int
+static bool
skip (uintmax_t n_skip)
{
- int err = 0;
+ bool ok = true;
int in_errno = 0;
if (n_skip == 0)
- return 0;
+ return true;
while (in_stream != NULL) /* EOF. */
{
@@ -1069,7 +1034,7 @@ skip (uintmax_t n_skip)
if (fseeko (in_stream, n_skip, SEEK_CUR) != 0)
{
in_errno = errno;
- err = 1;
+ ok = false;
}
n_skip = 0;
}
@@ -1092,7 +1057,7 @@ skip (uintmax_t n_skip)
if (n_bytes_read != n_bytes_to_read)
{
in_errno = errno;
- err = 1;
+ ok = false;
n_skip = 0;
break;
}
@@ -1106,18 +1071,18 @@ skip (uintmax_t n_skip)
else /* cannot fstat() file */
{
error (0, errno, "%s", input_filename);
- err = 1;
+ ok = false;
}
- err |= check_and_close (in_errno);
+ ok &= check_and_close (in_errno);
- err |= open_next_file ();
+ ok &= open_next_file ();
}
if (n_skip != 0)
error (EXIT_FAILURE, 0, _("cannot skip past end of combined input"));
- return err;
+ return ok;
}
static void
@@ -1195,8 +1160,8 @@ static void
write_block (uintmax_t current_offset, size_t n_bytes,
const char *prev_block, const char *curr_block)
{
- static int first = 1;
- static int prev_pair_equal = 0;
+ static bool first = true;
+ static bool prev_pair_equal = false;
#define EQUAL_BLOCKS(b1, b2) (memcmp ((b1), (b2), bytes_per_block) == 0)
@@ -1212,14 +1177,14 @@ write_block (uintmax_t current_offset, size_t n_bytes,
else
{
printf ("*\n");
- prev_pair_equal = 1;
+ prev_pair_equal = true;
}
}
else
{
size_t i;
- prev_pair_equal = 0;
+ prev_pair_equal = false;
for (i = 0; i < n_specs; i++)
{
if (i == 0)
@@ -1239,7 +1204,7 @@ write_block (uintmax_t current_offset, size_t n_bytes,
putchar ('\n');
}
}
- first = 0;
+ first = false;
}
/* Read a single byte into *C from the concatenation of the input files
@@ -1250,13 +1215,13 @@ write_block (uintmax_t current_offset, size_t n_bytes,
and INPUT_FILENAME so they correspond to the next file in the list.
Then try to read a byte from the newly opened file. Repeat if
necessary until EOF is reached for the last file in FILE_LIST, then
- set *C to EOF and return. Subsequent calls do likewise. The return
- value is nonzero if any errors occured, zero otherwise. */
+ set *C to EOF and return. Subsequent calls do likewise. Return
+ true if successful. */
-static int
+static bool
read_char (int *c)
{
- int err = 0;
+ bool ok = true;
*c = EOF;
@@ -1267,12 +1232,12 @@ read_char (int *c)
if (*c != EOF)
break;
- err |= check_and_close (errno);
+ ok &= check_and_close (errno);
- err |= open_next_file ();
+ ok &= open_next_file ();
}
- return err;
+ return ok;
}
/* Read N bytes into BLOCK from the concatenation of the input files
@@ -1283,23 +1248,23 @@ read_char (int *c)
the global variables IN_STREAM and INPUT_FILENAME. Then try to
read the remaining bytes from the newly opened file. Repeat if
necessary until EOF is reached for the last file in FILE_LIST.
- On subsequent calls, don't modify BLOCK and return zero. Set
+ On subsequent calls, don't modify BLOCK and return true. Set
*N_BYTES_IN_BUFFER to the number of bytes read. If an error occurs,
it will be detected through ferror when the stream is about to be
closed. If there is an error, give a message but continue reading
- as usual and return nonzero. Otherwise return zero. */
+ as usual and return false. Otherwise return true. */
-static int
+static bool
read_block (size_t n, char *block, size_t *n_bytes_in_buffer)
{
- int err = 0;
+ bool ok = true;
assert (0 < n && n <= bytes_per_block);
*n_bytes_in_buffer = 0;
if (n == 0)
- return 0;
+ return true;
while (in_stream != NULL) /* EOF. */
{
@@ -1314,12 +1279,12 @@ read_block (size_t n, char *block, size_t *n_bytes_in_buffer)
if (n_read == n_needed)
break;
- err |= check_and_close (errno);
+ ok &= check_and_close (errno);
- err |= open_next_file ();
+ ok &= open_next_file ();
}
- return err;
+ return ok;
}
/* Return the least common multiple of the sizes associated
@@ -1332,21 +1297,21 @@ get_lcm (void)
int l_c_m = 1;
for (i = 0; i < n_specs; i++)
- l_c_m = lcm (l_c_m, width_bytes[(int) spec[i].size]);
+ l_c_m = lcm (l_c_m, width_bytes[spec[i].size]);
return l_c_m;
}
/* If S is a valid traditional offset specification with an optional
- leading '+' return nonzero and set *OFFSET to the offset it denotes. */
+ leading '+' return true and set *OFFSET to the offset it denotes. */
-static int
+static bool
parse_old_offset (const char *s, uintmax_t *offset)
{
int radix;
enum strtol_error s_err;
if (*s == '\0')
- return 0;
+ return false;
/* Skip over any leading '+'. */
if (s[0] == '+')
@@ -1369,9 +1334,9 @@ parse_old_offset (const char *s, uintmax_t *offset)
if (s_err != LONGINT_OK)
{
STRTOL_FAIL_WARN (s, _("old-style offset"), s_err);
- return 0;
+ return false;
}
- return 1;
+ return true;
}
/* Read a chunk of size BYTES_PER_BLOCK from the input files, write the
@@ -1383,16 +1348,16 @@ parse_old_offset (const char *s, uintmax_t *offset)
multiple of all format spec sizes. Write the final block. Finally,
write on a line by itself the offset of the byte after the last byte
read. Accumulate return values from calls to read_block and
- check_and_close, and if any was nonzero, return nonzero.
- Otherwise, return zero. */
+ check_and_close, and if any was false, return false.
+ Otherwise, return true. */
-static int
+static bool
dump (void)
{
char *block[2];
uintmax_t current_offset;
- int idx;
- int err;
+ bool idx = false;
+ bool ok = true;
size_t n_bytes_read;
block[0] = xnmalloc (2, bytes_per_block);
@@ -1400,8 +1365,6 @@ dump (void)
current_offset = n_bytes_to_skip;
- idx = 0;
- err = 0;
if (limit_bytes_to_format)
{
while (1)
@@ -1414,7 +1377,7 @@ dump (void)
}
n_needed = MIN (end_offset - current_offset,
(uintmax_t) bytes_per_block);
- err |= read_block (n_needed, block[idx], &n_bytes_read);
+ ok &= read_block (n_needed, block[idx], &n_bytes_read);
if (n_bytes_read < bytes_per_block)
break;
assert (n_bytes_read == bytes_per_block);
@@ -1428,7 +1391,7 @@ dump (void)
{
while (1)
{
- err |= read_block (bytes_per_block, block[idx], &n_bytes_read);
+ ok &= read_block (bytes_per_block, block[idx], &n_bytes_read);
if (n_bytes_read < bytes_per_block)
break;
assert (n_bytes_read == bytes_per_block);
@@ -1459,29 +1422,27 @@ dump (void)
format_address (current_offset, '\n');
if (limit_bytes_to_format && current_offset >= end_offset)
- err |= check_and_close (0);
+ ok &= check_and_close (0);
free (block[0]);
- return err;
+ return ok;
}
/* STRINGS mode. Find each "string constant" in the input.
A string constant is a run of at least `string_min' ASCII
graphic (or formatting) characters terminated by a null.
Based on a function written by Richard Stallman for a
- traditional version of od. Return nonzero if an error
- occurs. Otherwise, return zero. */
+ traditional version of od. Return true if successful. */
-static int
+static bool
dump_strings (void)
{
size_t bufsize = MAX (100, string_min);
char *buf = xmalloc (bufsize);
uintmax_t address = n_bytes_to_skip;
- int err;
+ bool ok = true;
- err = 0;
while (1)
{
size_t i;
@@ -1496,12 +1457,12 @@ dump_strings (void)
for (i = 0; i < string_min; i++)
{
- err |= read_char (&c);
+ ok &= read_char (&c);
address++;
if (c < 0)
{
free (buf);
- return err;
+ return ok;
}
if (!ISPRINT (c))
/* Found a non-printing. Try again starting with next char. */
@@ -1517,12 +1478,12 @@ dump_strings (void)
{
buf = x2nrealloc (buf, &bufsize, sizeof *buf);
}
- err |= read_char (&c);
+ ok &= read_char (&c);
address++;
if (c < 0)
{
free (buf);
- return err;
+ return ok;
}
if (c == '\0')
break; /* It is; print this string. */
@@ -1580,8 +1541,8 @@ dump_strings (void)
free (buf);
- err |= check_and_close (0);
- return err;
+ ok &= check_and_close (0);
+ return ok;
}
int
@@ -1592,9 +1553,8 @@ main (int argc, char **argv)
size_t i;
int l_c_m;
size_t desired_width IF_LINT (= 0);
- int width_specified = 0;
- int n_failed_decodes = 0;
- int err;
+ bool width_specified = false;
+ bool ok = true;
char const *short_options = (posix2_version () < 200112
? COMMON_SHORT_OPTIONS "s::w::"
: COMMON_SHORT_OPTIONS "s:w:");
@@ -1611,8 +1571,6 @@ main (int argc, char **argv)
atexit (close_stdout);
- err = 0;
-
for (i = 0; i <= MAX_INTEGRAL_TYPE_SIZE; i++)
integral_type_size[i] = NO_SIZE;
@@ -1621,7 +1579,7 @@ main (int argc, char **argv)
integral_type_size[sizeof (int)] = INT;
integral_type_size[sizeof (long int)] = LONG;
#if HAVE_UNSIGNED_LONG_LONG
- /* If `long' and `long long' have the same size, it's fine
+ /* If `long int' and `long long int' have the same size, it's fine
to overwrite the entry for `long' with this one. */
integral_type_size[sizeof (ulonglong_t)] = LONG_LONG;
#endif
@@ -1643,7 +1601,7 @@ main (int argc, char **argv)
format_address = format_address_std;
address_base = 8;
address_pad_len = 7;
- flag_dump_strings = 0;
+ flag_dump_strings = false;
while ((c = getopt_long (argc, argv, short_options, long_options, NULL))
!= -1)
@@ -1694,7 +1652,7 @@ it must be one character from [doxn]"),
break;
case 'N':
- limit_bytes_to_format = 1;
+ limit_bytes_to_format = true;
s_err = xstrtoumax (optarg, NULL, 0, &max_bytes_to_format, "bkm");
if (s_err != LONGINT_OK)
@@ -1717,20 +1675,19 @@ it must be one character from [doxn]"),
string_min = tmp;
}
- flag_dump_strings = 1;
+ flag_dump_strings = true;
break;
case 't':
- if (decode_format_string (optarg))
- ++n_failed_decodes;
+ ok &= decode_format_string (optarg);
break;
case 'v':
- abbreviate_duplicate_blocks = 0;
+ abbreviate_duplicate_blocks = false;
break;
case TRADITIONAL_OPTION:
- traditional = 1;
+ traditional = true;
break;
/* The next several cases map the traditional format
@@ -1740,10 +1697,7 @@ it must be one character from [doxn]"),
#define CASE_OLD_ARG(old_char,new_string) \
case old_char: \
- { \
- if (decode_format_string (new_string)) \
- ++n_failed_decodes; \
- } \
+ ok &= decode_format_string (new_string); \
break
CASE_OLD_ARG ('a', "a");
@@ -1767,7 +1721,7 @@ it must be one character from [doxn]"),
#undef CASE_OLD_ARG
case 'w':
- width_specified = 1;
+ width_specified = true;
if (optarg == NULL)
{
desired_width = 32;
@@ -1794,7 +1748,7 @@ it must be one character from [doxn]"),
}
}
- if (n_failed_decodes > 0)
+ if (!ok)
exit (EXIT_FAILURE);
if (flag_dump_strings && n_specs > 0)
@@ -1832,7 +1786,7 @@ it must be one character from [doxn]"),
&& parse_old_offset (argv[optind + 1], &o2))
{
n_bytes_to_skip = o1;
- flag_pseudo_start = 1;
+ flag_pseudo_start = true;
pseudo_start = o2;
argv += 2;
n_files -= 2;
@@ -1859,7 +1813,7 @@ it must be one character from [doxn]"),
&& parse_old_offset (argv[optind + 2], &o2))
{
n_bytes_to_skip = o1;
- flag_pseudo_start = 1;
+ flag_pseudo_start = true;
pseudo_start = o2;
argv[optind + 2] = argv[optind];
argv += 2;
@@ -1902,7 +1856,7 @@ it must be one character from [doxn]"),
if (n_specs == 0)
{
- if (decode_format_string ("o2"))
+ if (! decode_format_string ("o2"))
{
/* This happens on Cray systems that don't have a 2-byte
integral type. */
@@ -1929,12 +1883,12 @@ it must be one character from [doxn]"),
}
/* open the first input file */
- err |= open_next_file ();
+ ok = open_next_file ();
if (in_stream == NULL)
goto cleanup;
/* skip over any unwanted header bytes */
- err |= skip (n_bytes_to_skip);
+ ok &= skip (n_bytes_to_skip);
if (in_stream == NULL)
goto cleanup;
@@ -1950,7 +1904,7 @@ it must be one character from [doxn]"),
else
{
error (0, 0, _("warning: invalid width %lu; using %d instead"),
- (unsigned long) desired_width, l_c_m);
+ (unsigned long int) desired_width, l_c_m);
bytes_per_block = l_c_m;
}
}
@@ -1970,12 +1924,12 @@ it must be one character from [doxn]"),
}
#endif
- err |= (flag_dump_strings ? dump_strings () : dump ());
+ ok &= (flag_dump_strings ? dump_strings () : dump ());
cleanup:;
if (have_read_stdin && fclose (stdin) == EOF)
error (EXIT_FAILURE, errno, _("standard input"));
- exit (err == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
+ exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
}