[hackers] [sbase] Add -e and -E flags to od(1) and properly handle endianness || FRIGN

From: <git_AT_suckless.org>
Date: Mon, 26 Oct 2015 12:55:51 +0100 (CET)

commit d03baf1697443dd71b01aeeb6b7ef5b1ac070cf5
Author: FRIGN <dev_AT_frign.de>
AuthorDate: Sun Oct 25 23:26:49 2015 +0100
Commit: sin <sin_AT_2f30.org>
CommitDate: Mon Oct 26 11:55:41 2015 +0000

    Add -e and -E flags to od(1) and properly handle endianness
    
    The -e and -E flags allow the user to override the host endianness
    and force od(1) to handle input according to a little (-e) or big (-E)
    endian environment.
    The previous handling was broken as bitshifts alone are already
    endian-independent.

diff --git a/od.1 b/od.1
index c453b09..bd74ad4 100644
--- a/od.1
+++ b/od.1
_AT_@ -1,4 +1,4 @@
-.Dd 2015-10-09
+.Dd 2015-10-25
 .Dt OD 1
 .Os sbase
 .Sh NAME
_AT_@ -7,6 +7,7 @@
 .Sh SYNOPSIS
 .Nm
 .Op Fl A Ar addrformat
+.Op Fl E | e
 .Op Fl t Ar outputformat...
 .Op Fl v
 .Op Ar file ...
_AT_@ -26,6 +27,12 @@ reads from stdin.
 is one of d|o|x|n and sets the address to be
 either in \fId\fRecimal, \fIo\fRctal, he\fIx\fRadecimal or \fIn\fRot
 printed at all. The default is octal.
+.It Fl E | e
+Force Little Endian
+.Fl ( e )
+or Big Endian
+.Fl ( E )
+system-independently.
 .It Fl t Ar outputformat
 .Ar outputformat
 is a list of a|c|d|o|u|x followed by a digit or C|S|I|L and sets
_AT_@ -49,3 +56,7 @@ The
 flag is enabled by default and the 'd' parameter for the
 .Op Fl t
 flag is interpreted as 'u'.
+.Pp
+The
+.Op Ee
+flags are an extension to that specification.
diff --git a/od.c b/od.c
index 4c9f02a..8061c86 100644
--- a/od.c
+++ b/od.c
_AT_@ -1,5 +1,4 @@
 /* See LICENSE file for copyright and license details. */
-#include <endian.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
_AT_@ -8,6 +7,8 @@
 #include "queue.h"
 #include "util.h"
 
+#define HOST_BIG_ENDIAN (*(uint16_t *)"\0\xff" == 0xff)
+
 struct type {
         unsigned char format;
         unsigned int len;
_AT_@ -19,6 +20,7 @@ static unsigned char addr_format = 'o';
 static off_t skip = 0;
 static off_t max = -1;
 static size_t linelen = 1;
+static int big_endian;
 
 static void
 printaddress(off_t addr)
_AT_@ -37,7 +39,7 @@ static void
 printchunk(unsigned char *s, unsigned char format, size_t len) {
         long long res, basefac;
         size_t i;
- char fmt[] = " %0*ll#";
+ char fmt[] = " %#*ll#";
 
         const char *namedict[] = {
                 "nul", "soh", "stx", "etx", "eot", "enq", "ack",
_AT_@ -70,17 +72,18 @@ printchunk(unsigned char *s, unsigned char format, size_t len) {
                 }
                 break;
         default:
- res = 0;
- basefac = 1;
-#if __BYTE_ORDER == __BIG_ENDIAN
- for (i = len; i; i--) {
- res += s[i - 1] * basefac;
-#else
- for (i = 0; i < len; i++) {
- res += s[i] * basefac;
-#endif
- basefac <<= 8;
+ if (big_endian == HOST_BIG_ENDIAN) {
+ for (res = 0, basefac = 1, i = 0; i < len; i++) {
+ res += s[i] * basefac;
+ basefac <<= 8;
+ }
+ } else {
+ for (res = 0, basefac = 1, i = len; i; i--) {
+ res += s[i - 1] * basefac;
+ basefac <<= 8;
+ }
                 }
+ fmt[2] = big_endian ? '-' : '+';
                 fmt[6] = format;
                 printf(fmt, (int)(3 * len + len - 1), res);
         }
_AT_@ -165,7 +168,7 @@ lcm(unsigned int a, unsigned int b)
 static void
 usage(void)
 {
- eprintf("usage: %s [-A addressformat] [-t outputformat] "
+ eprintf("usage: %s [-A addressformat] [-E | -e] [-t outputformat] "
                 "[-v] [file ...]\n", argv0);
 }
 
_AT_@ -177,6 +180,8 @@ main(int argc, char *argv[])
         int ret = 0;
         char *s;
 
+ big_endian = HOST_BIG_ENDIAN;
+
         ARGBEGIN {
         case 'A':
                 s = EARGF(usage());
_AT_@ -184,6 +189,10 @@ main(int argc, char *argv[])
                         usage();
                 addr_format = s[0];
                 break;
+ case 'E':
+ case 'e':
+ big_endian = (ARGC() == 'E');
+ break;
         case 'j':
                 if ((skip = parseoffset(EARGF(usage()))) < 0)
                         usage();
Received on Mon Oct 26 2015 - 12:55:51 CET

This archive was generated by hypermail 2.3.0 : Mon Oct 26 2015 - 13:00:20 CET