Hello, It's well-known that "od" displays different output depending on whether your CPU is big-endian or little-endian. With this simple patch, "od -I" is little-endian on all CPUs, and "od -M" is big-endian. (Think "Intel" and "Motorola").
This patch is very useful for reading files with the "wrong" byte order. "dd conv=swab" only works with shorts, not ints, floats, or doubles. "od" with neither option uses CPU byte order (same as before), while "od -I -M" uses the opposite of CPU order. Dave Coffin 11/27/2005 --- od.c 2005-09-23 16:13:49.000000000 -0400 +++ od.c 2005-11-27 02:41:12.000000000 -0500 @@ -222,6 +222,9 @@ input is formatted. */ static bool limit_bytes_to_format = false; +/* When true, reverse the byte order of numeric data. */ +static bool byte_swap = false; + /* The maximum number of bytes that will be formatted. */ static uintmax_t max_bytes_to_format; @@ -271,7 +274,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:LlMN:OoS: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. */ @@ -285,6 +288,8 @@ {"skip-bytes", required_argument, NULL, 'j'}, {"address-radix", required_argument, NULL, 'A'}, {"read-bytes", required_argument, NULL, 'N'}, + {"little-endian", no_argument, NULL, 'I'}, + {"big-endian", no_argument, NULL, 'M'}, {"format", required_argument, NULL, 't'}, {"output-duplicates", no_argument, NULL, 'v'}, {"strings", optional_argument, NULL, 'S'}, @@ -327,6 +332,8 @@ fputs (_("\ -N, --read-bytes=BYTES limit dump to BYTES input bytes\n\ -S, --strings[=BYTES] output strings of at least BYTES graphic chars\n\ + -I, --little-endian force Intel (little-endian) byte order\n\ + -M, --big-endian force Motorola (big-endian) byte order\n\ -t, --format=TYPE select output format or formats\n\ -v, --output-duplicates do not use * to mark line suppression\n\ -w, --width[=BYTES] output BYTES bytes per output line\n\ @@ -1194,7 +1201,8 @@ } else { - size_t i; + size_t i, j, width; + char *disp_block; prev_pair_equal = false; for (i = 0; i < n_specs; i++) @@ -1203,7 +1211,14 @@ format_address (current_offset, '\0'); else printf ("%*s", address_pad_len, ""); - (*spec[i].print_function) (n_bytes, curr_block, spec[i].fmt_string); + if (byte_swap && (disp_block = xmalloc (n_bytes))) { + width = width_bytes[spec[i].size]; + for (j=0; j < n_bytes; j++) + disp_block[j] = curr_block[j + width-1 - j % width * 2]; + (*spec[i].print_function) (n_bytes, disp_block, spec[i].fmt_string); + free (disp_block); + } 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 */ @@ -1682,6 +1697,18 @@ flag_dump_strings = true; break; + case 'I': +#ifdef WORDS_BIGENDIAN + byte_swap = true; +#endif + break; + + case 'M': +#ifndef WORDS_BIGENDIAN + byte_swap = true; +#endif + break; + case 't': modern = true; ok &= decode_format_string (optarg); @@ -1719,7 +1746,7 @@ case 'X': /* obsolescent and undocumented alias */ CASE_OLD_ARG ('H', "x4"); /* obsolescent and undocumented */ CASE_OLD_ARG ('i', "dI"); - case 'I': case 'L': /* obsolescent and undocumented aliases */ + case 'L': /* obsolescent and undocumented alias */ CASE_OLD_ARG ('l', "dL"); CASE_OLD_ARG ('O', "o4"); /* obsolesent and undocumented */ case 'B': /* obsolescent and undocumented alias */ _______________________________________________ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils