ni...@lysator.liu.se (Niels Möller) writes: > Pádraig Brady <p...@draigbrady.com> writes: >> I agree this would be useful and easy enough to add. >> I suppose the interface would be --endian=little|big > > Maybe I can have a look at what it takes.
Below is a crude patch (missing: usage message, tests cases, docs, translation). I think it should work fine for floats too. I see no obvious and more beautiful way to do it. (And I think I have copyright assignment papers for coreutils in place, since work on factor some year ago). Regards, /Niels diff --git a/src/od.c b/src/od.c index 514fe50..a71e302 100644 --- a/src/od.c +++ b/src/od.c @@ -259,13 +259,16 @@ static enum size_spec integral_type_size[MAX_INTEGRAL_TYPE_SIZE + 1]; #define MAX_FP_TYPE_SIZE sizeof (long double) static enum size_spec fp_type_size[MAX_FP_TYPE_SIZE + 1]; +bool input_swap; + static char const short_options[] = "A:aBbcDdeFfHhIij:LlN: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. */ enum { - TRADITIONAL_OPTION = CHAR_MAX + 1 + TRADITIONAL_OPTION = CHAR_MAX + 1, + ENDIAN_OPTION, }; static struct option const long_options[] = @@ -278,6 +281,7 @@ static struct option const long_options[] = {"strings", optional_argument, NULL, 'S'}, {"traditional", no_argument, NULL, TRADITIONAL_OPTION}, {"width", optional_argument, NULL, 'w'}, + {"endian", required_argument, NULL, ENDIAN_OPTION }, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, @@ -406,7 +410,21 @@ N (size_t fields, size_t blank, void const *block, \ { \ int next_pad = pad * (i - 1) / fields; \ int adjusted_width = pad_remaining - next_pad + width; \ - T x = *p++; \ + T x; \ + if (input_swap && sizeof(T) > 1) \ + { \ + int j; \ + union { \ + T x; \ + char b[sizeof(T)]; \ + } u; \ + for (j = 0; j < sizeof(T); j++) \ + u.b[j] = ((const char *) p)[sizeof(T) - 1 - j]; \ + x = u.x; \ + } \ + else \ + x = *p; \ + p++; \ ACTION; \ pad_remaining = next_pad; \ } \ @@ -1664,6 +1682,24 @@ main (int argc, char **argv) traditional = true; break; + case ENDIAN_OPTION: + if (!strcmp (optarg, "big")) + { +#if !WORDS_BIGENDIAN + input_swap = true; +#endif + } + else if (!strcmp (optarg, "little")) + { +#if WORDS_BIGENDIAN + input_swap = true; +#endif + } + else + error (EXIT_FAILURE, 0, + _("bad argument '%s' for --endian option"), optarg); + break; + /* The next several cases map the traditional format specification options to the corresponding modern format specs. GNU od accepts any combination of old- and -- Niels Möller. PGP-encrypted email is preferred. Keyid C0B98E26. Internet email is subject to wholesale government surveillance.