On 01/31/2014 09:44 AM, Niels Möller wrote: > 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
That looks good. I'll adjust slightly to use XARGMATCH and add some docs/tests. I'm travelling at the moment but merge this soon. thanks! Pádraig.