[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#16578: Wish: Support for non-native endianness in od
From: |
Niels Möller |
Subject: |
bug#16578: Wish: Support for non-native endianness in od |
Date: |
Fri, 31 Jan 2014 09:44:54 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.3 (usg-unix-v) |
address@hidden (Niels Möller) writes:
> Pádraig Brady <address@hidden> 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.