--- od.c-original 2007-03-18 14:36:43.000000000 -0700 +++ od.c 2008-01-12 18:47:48.000000000 -0700 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "system.h" #include "error.h" @@ -222,6 +223,9 @@ input is formatted. */ static bool limit_bytes_to_format = false; +/* When true, execute end-to-end byte swap on each output block. */ +static bool need_byte_swap = false; + /* The maximum number of bytes that will be formatted. */ static uintmax_t max_bytes_to_format; @@ -271,7 +275,7 @@ #define MAX_FP_TYPE_SIZE sizeof (LONG_DOUBLE) static enum size_spec fp_type_size[MAX_FP_TYPE_SIZE + 1]; -static char const short_options[] = "A:aBbcDdeFfHhIij:LlN:OoS:st:vw::Xx"; +static char const short_options[] = "A:aBbcDdeFfHhIij:LlN:OPoS:st:vw::Xx"; /* For long options that have no equivalent short option, use a non-character as a pseudo short option, starting with CHAR_MAX + 1. */ @@ -284,6 +288,8 @@ { {"skip-bytes", required_argument, NULL, 'j'}, {"address-radix", required_argument, NULL, 'A'}, + {"source-byte-order", required_argument, NULL, 'O'}, + {"force-byte-swap", no_argument, NULL, 'P'}, {"read-bytes", required_argument, NULL, 'N'}, {"format", required_argument, NULL, 't'}, {"output-duplicates", no_argument, NULL, 'v'}, @@ -326,6 +332,8 @@ "), stdout); fputs (_("\ -N, --read-bytes=BYTES limit dump to BYTES input bytes\n\ + -O, --source-byte-order=[msb|lsb] specify source byte order\n\ + -P, --force-byte-swap ignore source byte order, always swap bytes\n\ -S, --strings[=BYTES] output strings of at least BYTES graphic chars\n\ -t, --format=TYPE select output format or formats\n\ -v, --output-duplicates do not use * to mark line suppression\n\ @@ -1196,7 +1204,11 @@ } else { - size_t i; + size_t i, j, width; + char *swapped_block = 0; + + if (need_byte_swap) + swapped_block = xmalloc (n_bytes); prev_pair_equal = false; for (i = 0; i < n_specs; i++) @@ -1205,7 +1217,15 @@ format_address (current_offset, '\0'); else printf ("%*s", address_pad_len, ""); - (*spec[i].print_function) (n_bytes, curr_block, spec[i].fmt_string); + if (need_byte_swap && swapped_block) + { + width = width_bytes[spec[i].size]; + for (j=0; j < n_bytes; j++) + swapped_block[j] = curr_block[j + width - 1 - (j % width) * 2]; + (*spec[i].print_function) (n_bytes, swapped_block, spec[i].fmt_string); + } + else + (*spec[i].print_function) (n_bytes, curr_block, spec[i].fmt_string); if (spec[i].hexl_mode_trailer) { /* space-pad out to full line width, then dump the trailer */ @@ -1217,6 +1237,8 @@ } putchar ('\n'); } + if (swapped_block) + free (swapped_block); } first = false; } @@ -1664,6 +1686,27 @@ STRTOL_FATAL_ERROR (optarg, _("limit argument"), s_err); break; + case 'O': + if (strcmp (optarg, "msb") == 0) + { +#if __BYTE_ORDER == __LITTLE_ENDIAN + need_byte_swap = true; +#endif + } + else if (strcmp (optarg, "lsb") == 0) + { +#if __BYTE_ORDER == __BIG_ENDIAN + need_byte_swap = true; +#endif + } + else + error (EXIT_FAILURE, 0, _("unrecognized byte order specification ``%s''"), optarg); + break; + + case 'P': + need_byte_swap = true; + break; + case 'S': modern = true; if (optarg == NULL) @@ -1723,7 +1766,6 @@ CASE_OLD_ARG ('i', "dI"); case 'I': case 'L': /* obsolescent and undocumented aliases */ CASE_OLD_ARG ('l', "dL"); - CASE_OLD_ARG ('O', "o4"); /* obsolesent and undocumented */ case 'B': /* obsolescent and undocumented alias */ CASE_OLD_ARG ('o', "o2"); CASE_OLD_ARG ('s', "d2");