bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Endian options for "od"


From: dcoffin
Subject: Endian options for "od"
Date: Sun, 27 Nov 2005 02:57:59 -0500
User-agent: Mutt/1.5.9i

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 */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]