From 2db9ed11d12e558a3b8dabc819086355af77b09d Mon Sep 17 00:00:00 2001
From: Martine Lenders <m.lenders@fu-berlin.de>
Date: Tue, 31 Jan 2017 14:53:38 +0100
Subject: [PATCH] od: simplify od module to only provide od_hex_dump

To my knowledge no one was using the more complex functionalities of
this module (except for the test application and pktbuf which just used
the same flags as the `od_hex_dump()` wrapper), so why not reduce the
functionality of this module?
---
 Makefile.dep     |   4 +
 sys/include/od.h | 125 +---------------
 sys/od/od.c      | 362 ++---------------------------------------------
 3 files changed, 20 insertions(+), 471 deletions(-)

diff --git a/Makefile.dep b/Makefile.dep
index cc85b1fcef..7ef3f4f288 100644
--- a/Makefile.dep
+++ b/Makefile.dep
@@ -350,6 +350,10 @@ ifneq (,$(filter gnrc_pktdump,$(USEMODULE)))
   USEMODULE += od
 endif
 
+ifneq (,$(filter od,$(USEMODULE)))
+  USEMODULE += fmt
+endif
+
 ifneq (,$(filter newlib_nano,$(USEMODULE)))
   USEMODULE += newlib
 endif
diff --git a/sys/include/od.h b/sys/include/od.h
index 99d2fb00c1..416b5e5429 100644
--- a/sys/include/od.h
+++ b/sys/include/od.h
@@ -9,15 +9,8 @@
 /**
  * @defgroup sys_od Object dump
  * @ingroup  sys
- * @brief   Allows to print out data dumps of memory regions in a similar fashion
- *          to the UNIX's
- *          <a href="http://pubs.opengroup.org/onlinepubs/9699919799/utilities/od.html">
- *              od
- *          </a> tool
+ * @brief   Allows to print out data dumps of memory regions
  *
- * @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/utilities/od.html">
- *          od(1)
- *      </a>
  * @{
  *
  * @file
@@ -31,132 +24,24 @@
 extern "C" {
 #endif
 
+#include <stddef.h>
 #include <stdint.h>
 
 /**
- * @brief Bit-mask to extract address offset format settings from flags
- */
-#define OD_FLAGS_ADDRESS_MASK   (0xc000)
-
-/**
- * @brief Bit-mask to extract byte format settings from flags
- */
-#define OD_FLAGS_BYTES_MASK     (0x3e00)
-
-/**
- * @brief Bit-mask to extract length information for byte format from flags
- */
-#define OD_FLAGS_LENGTH_MASK    (0x00f7)
-
-/**
- * @anchor od_flags_address
- * @name Address offset format flags
- * @brief Flags to define format of the address offset
- * @{
- */
-#define OD_FLAGS_ADDRESS_OCTAL      (0x0000)    /**< octal address offset */
-#define OD_FLAGS_ADDRESS_HEX        (0x4000)    /**< hexadecimal address offset */
-#define OD_FLAGS_ADDRESS_DECIMAL    (0x8000)    /**< decimal address offset */
-#define OD_FLAGS_ADDRESS_NONE       (0xc000)    /**< no address offset */
-/** @} */
-
-/**
- * @anchor od_flags_bytes
- * @name Bytes format flags
- * @brief Flags to define format of the byte output
- * @{
- */
-/**
- * @brief Print `LENGTH` bytes as `LENGTH`-wide octal integer (`LENGTH` is defined
- *        in the lower significant byte of the flags)
- */
-#define OD_FLAGS_BYTES_OCTAL    (0x0000)
-
-/**
- * @brief Print bytes as their represented character in ASCII
- */
-#define OD_FLAGS_BYTES_CHAR     (0x2000)
-
-/**
- * @brief Print `LENGTH` bytes as `LENGTH`-wide decimal integer (`LENGTH` is
- *        defined in the lower significant byte of the flags)
- */
-#define OD_FLAGS_BYTES_INT      (0x1000)
-
-/**
- * @brief Alias for @ref OD_FLAGS_BYTES_INT
- */
-#define OD_FLAGS_BYTES_DECIMAL  (OD_FLAGS_BYTES_INT)
-
-/* XXX: No float support for now, but reserved 0x0800 for this */
-
-/**
- * @brief Print `LENGTH` bytes as `LENGTH`-wide decimal unsigned integer
- *        (`LENGTH` is defined in the lower significant byte of the flags)
- */
-#define OD_FLAGS_BYTES_UINT     (0x0400)
-
-/**
- * @brief Print `LENGTH` bytes as `LENGTH`-wide hexadecimal integer
- *        (`LENGTH` is defined in the lower significant byte of the flags)
- */
-#define OD_FLAGS_BYTES_HEX      (0x0200)
-
-/** @} */
-
-
-/**
- * @anchor od_flags_length
- * @name Bytes format length flags
- * @brief Flags to define format length of the byte output
- * @{
- */
-#define OD_FLAGS_LENGTH_1       (0x0010)    /**< 1 byte */
-#define OD_FLAGS_LENGTH_2       (0x0020)    /**< 2 byte */
-#define OD_FLAGS_LENGTH_4       (0x0000)    /**< 4 byte and default */
-/**
- * @brief   8 byte
- *
- * @warning not working with newlib-nano
- */
-#define OD_FLAGS_LENGTH_8       (0x0080)
-#define OD_FLAGS_LENGTH_CHAR    (OD_FLAGS_LENGTH_1)    /**< alias for OD_FLAGS_LENGTH_1 */
-#define OD_FLAGS_LENGTH_SHORT   (0x0002)    /**< sizeof(short) byte */
-#define OD_FLAGS_LENGTH_LONG    (0x0004)    /**< sizeof(long) byte */
-/** @} */
-
-/**
- * @brief   Default value for parameter *width* of @ref od()
+ * @brief   Default value for parameter *width* of @ref od_hex_dump()
  */
 #define OD_WIDTH_DEFAULT    (16)
 
 /**
- * @brief Dumps memory stored at *data* up to *data_len* in octal, decimal, or
- *        hexadecimal representation to stdout
- *
- * @param[in] data      Data to dump.
- * @param[in] data_len  Length in bytes of *data* to output.
- * @param[in] width     Number of bytes per line. If *width* is 0,
- *                      @ref OD_WIDTH_DEFAULT is assumed as a default value.
- * @param[in] flags     Flags as defined in @ref od_flags_address and
- *                      @ref od_flags_bytes
- */
-void od(const void *data, size_t data_len, uint8_t width, uint16_t flags);
-
-/**
- * @brief Dumps memory stored at *data* up to *data_len* in octal, decimal, or
+ * @brief Dumps memory stored at *data* byte-wise up to *data_len* in
  *        hexadecimal representation to stdout with
- *        `flags == OD_FLAGS_ADDRESS_HEX | OD_FLAGS_BYTES_HEX | OD_FLAGS_LENGTH_1`.
  *
  * @param[in] data      Data to dump.
  * @param[in] data_len  Length in bytes of *data* to output.
  * @param[in] width     Number of bytes per line. If *width* is 0,
  *                      @ref OD_WIDTH_DEFAULT is assumed as a default value.
  */
-static inline void od_hex_dump(const void *data, size_t data_len, uint8_t width)
-{
-    od(data, data_len, width, OD_FLAGS_ADDRESS_HEX | OD_FLAGS_BYTES_HEX | OD_FLAGS_LENGTH_1);
-}
+void od_hex_dump(const void *data, size_t data_len, uint8_t width);
 
 #ifdef __cplusplus
 }
diff --git a/sys/od/od.c b/sys/od/od.c
index 36c851a1fd..486e6b9a66 100644
--- a/sys/od/od.c
+++ b/sys/od/od.c
@@ -11,371 +11,31 @@
  *
  * @file
  */
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-
-#include "od.h"
-
-#define _OCTAL_BYTE_LENGTH  (3)
-#define _INT_BYTE_LENGTH    (3)
-#define _HEX_BYTE_LENGTH    (2)
-
-static inline void _address_format(char *format, uint16_t flags)
-{
-    switch (flags & OD_FLAGS_ADDRESS_MASK) {
-        case OD_FLAGS_ADDRESS_OCTAL:
-            strncpy(format, "%09o", sizeof("%09o"));
-            break;
-
-        case OD_FLAGS_ADDRESS_HEX:
-            strncpy(format, "%06x", sizeof("%06x"));
-            break;
-
-        case OD_FLAGS_ADDRESS_DECIMAL:
-            strncpy(format, "%07d", sizeof("%07d"));
-            break;
-
-        default:
-            break;
-    }
-}
-
-static inline uint8_t _length(uint16_t flags)
-{
-    if (flags & OD_FLAGS_BYTES_CHAR) {
-        return 1;
-    }
-
-    switch (flags & OD_FLAGS_LENGTH_MASK) {
-        case OD_FLAGS_LENGTH_1:
-            return 1;
-
-        case OD_FLAGS_LENGTH_SHORT:
-            return sizeof(short);
-
-        case OD_FLAGS_LENGTH_2:
-            return 2;
-
-        case OD_FLAGS_LENGTH_LONG:
-            return sizeof(long);
-
-        case OD_FLAGS_LENGTH_8:
-            return 8;
-
-        case OD_FLAGS_LENGTH_4:
-        default:
-            return 4;
-    }
-}
-
-static inline void _bytes_format(char *format, uint16_t flags)
-{
-    if (flags & OD_FLAGS_BYTES_CHAR) {
-        strncpy(format, "    %c", sizeof("    %c"));
-        return;
-    }
-
-    switch (flags & (OD_FLAGS_BYTES_MASK | OD_FLAGS_LENGTH_MASK)) {
-        case OD_FLAGS_BYTES_OCTAL | OD_FLAGS_LENGTH_1:
-            strncpy(format, " %03o", sizeof(" %03o"));
-            break;
-
-        case OD_FLAGS_BYTES_OCTAL | OD_FLAGS_LENGTH_2:
-            strncpy(format, " %06" PRIo16, sizeof(" %06" PRIo16));
-            break;
-
-        case OD_FLAGS_BYTES_OCTAL | OD_FLAGS_LENGTH_4:
-            strncpy(format, " %012" PRIo32, sizeof(" %012" PRIo32));
-            break;
-
-        case OD_FLAGS_BYTES_OCTAL | OD_FLAGS_LENGTH_8:
-            strncpy(format, " %024" PRIo64, sizeof(" %024" PRIo64));
-            break;
-
-#if !defined(__MACH__) && !defined(__mips__)
-        case OD_FLAGS_BYTES_OCTAL | OD_FLAGS_LENGTH_SHORT:
-            sprintf(format, " %%0%do", sizeof(short) * _OCTAL_BYTE_LENGTH);
-            break;
-
-        case OD_FLAGS_BYTES_OCTAL | OD_FLAGS_LENGTH_LONG:
-            sprintf(format, " %%0%dlo", sizeof(long) * _OCTAL_BYTE_LENGTH);
-            break;
-#else   /* !defined(__MACH__) && !defined(__mips__) */
-        case OD_FLAGS_BYTES_OCTAL | OD_FLAGS_LENGTH_SHORT:
-            sprintf(format, " %lu", sizeof(short) * _OCTAL_BYTE_LENGTH);
-            break;
-
-        case OD_FLAGS_BYTES_OCTAL | OD_FLAGS_LENGTH_LONG:
-            sprintf(format, " %lu", sizeof(long) * _OCTAL_BYTE_LENGTH);
-            break;
-#endif  /* !defined(__MACH__) && !defined(__mips__) */
-
-        case OD_FLAGS_BYTES_INT | OD_FLAGS_LENGTH_1:
-            strncpy(format, " %4d", sizeof(" %4d"));
-            break;
-
-        case OD_FLAGS_BYTES_INT | OD_FLAGS_LENGTH_2:
-            strncpy(format, " %6" PRId16, sizeof(" %6" PRId16));
-            break;
-
-        case OD_FLAGS_BYTES_INT | OD_FLAGS_LENGTH_4:
-            strncpy(format, " %12" PRId32, sizeof(" %12" PRId32));
-            break;
-
-        case OD_FLAGS_BYTES_INT | OD_FLAGS_LENGTH_8:
-            strncpy(format, " %24" PRId64, sizeof(" %24" PRId64));
-            break;
-
-#if !defined(__MACH__) && !defined(__mips__)
-        case OD_FLAGS_BYTES_INT | OD_FLAGS_LENGTH_SHORT:
-            sprintf(format, " %%%dd", sizeof(short) * _INT_BYTE_LENGTH);
-            break;
-
-        case OD_FLAGS_BYTES_INT | OD_FLAGS_LENGTH_LONG:
-            sprintf(format, " %%%dld", sizeof(long) * _INT_BYTE_LENGTH);
-            break;
-#else   /* !defined(__MACH__) && !defined(__mips__) */
-        case OD_FLAGS_BYTES_INT | OD_FLAGS_LENGTH_SHORT:
-            sprintf(format, " %%%ld", sizeof(short) * _INT_BYTE_LENGTH);
-            break;
-
-        case OD_FLAGS_BYTES_INT | OD_FLAGS_LENGTH_LONG:
-            sprintf(format, " %%%ld", sizeof(long) * _INT_BYTE_LENGTH);
-            break;
-#endif  /* !defined(__MACH__)  && !defined(__mips__) */
-
-        case OD_FLAGS_BYTES_UINT | OD_FLAGS_LENGTH_1:
-            strncpy(format, " %3u", sizeof(" %3u"));
-            break;
-
-        case OD_FLAGS_BYTES_UINT | OD_FLAGS_LENGTH_2:
-            strncpy(format, " %6" PRIu16, sizeof(" %6" PRIu16));
-            break;
-
-        case OD_FLAGS_BYTES_UINT | OD_FLAGS_LENGTH_4:
-            strncpy(format, " %12" PRIu32, sizeof(" %12" PRIu32));
-            break;
-
-        case OD_FLAGS_BYTES_UINT | OD_FLAGS_LENGTH_8:
-            strncpy(format, " %24" PRIu64, sizeof(" %24" PRIu64));
-            break;
-
-#if !defined(__MACH__) && !defined(__mips__)
-        case OD_FLAGS_BYTES_UINT | OD_FLAGS_LENGTH_SHORT:
-            sprintf(format, " %%%uu", (unsigned)sizeof(short) * _INT_BYTE_LENGTH);
-            break;
-
-        case OD_FLAGS_BYTES_UINT | OD_FLAGS_LENGTH_LONG:
-            sprintf(format, " %%%ulu", sizeof(long) * _INT_BYTE_LENGTH);
-            break;
-#else   /* !defined(__MACH__) && !defined(__mips__) */
-        case OD_FLAGS_BYTES_UINT | OD_FLAGS_LENGTH_SHORT:
-            sprintf(format, " %%%lu", sizeof(short) * _INT_BYTE_LENGTH);
-            break;
-
-        case OD_FLAGS_BYTES_UINT | OD_FLAGS_LENGTH_LONG:
-            sprintf(format, " %%%lu", sizeof(long) * _INT_BYTE_LENGTH);
-            break;
-#endif  /* !defined(__MACH__)  && !defined(__mips__) */
-
-        case OD_FLAGS_BYTES_HEX | OD_FLAGS_LENGTH_1:
-            strncpy(format, " %02x", sizeof(" %02x"));
-            break;
-
-        case OD_FLAGS_BYTES_HEX | OD_FLAGS_LENGTH_2:
-            strncpy(format, " %04" PRIx16, sizeof(" %04" PRIx16));
-            break;
-
-        case OD_FLAGS_BYTES_HEX | OD_FLAGS_LENGTH_4:
-            strncpy(format, " %08" PRIx32, sizeof(" %08" PRIx32));
-            break;
-
-        case OD_FLAGS_BYTES_HEX | OD_FLAGS_LENGTH_8:
-            strncpy(format, " %016" PRIx64, sizeof(" %016" PRIx64));
-            break;
-
-#if !defined(__MACH__) && !defined(__mips__)
-        case OD_FLAGS_BYTES_HEX | OD_FLAGS_LENGTH_SHORT:
-            sprintf(format, " %%0%ux", (unsigned)sizeof(short) * _HEX_BYTE_LENGTH);
-            break;
-
-        case OD_FLAGS_BYTES_HEX | OD_FLAGS_LENGTH_LONG:
-            sprintf(format, " %%0%ulx", (unsigned)sizeof(long) * _HEX_BYTE_LENGTH);
-            break;
-#else   /* !defined(__MACH__) && !defined(__mips__) */
-        case OD_FLAGS_BYTES_HEX | OD_FLAGS_LENGTH_SHORT:
-            sprintf(format, " %%0%lx", sizeof(short) * _HEX_BYTE_LENGTH);
-            break;
 
-        case OD_FLAGS_BYTES_HEX | OD_FLAGS_LENGTH_LONG:
-            sprintf(format, " %%0%lx", sizeof(long) * _HEX_BYTE_LENGTH);
-            break;
-#endif  /* !defined(__MACH__) && !defined(__mips__) */
-
-        default:
-            break;
-    }
-}
-
-static void _print_date(const void *data, size_t offset, char *format, uint8_t length,
-                        uint16_t flags)
-{
-    switch (length) {
-        case 1:
-            if (flags & OD_FLAGS_BYTES_CHAR) {
-                switch (((signed char *)data)[offset]) {
-                    case '\0':
-                        printf("   \\0");
-                        return;
-
-                    case '\a':
-                        printf("   \\a");
-                        return;
-
-                    case '\b':
-                        printf("   \\b");
-                        return;
-
-                    case '\f':
-                        printf("   \\f");
-                        return;
-
-                    case '\n':
-                        printf("   \\n");
-                        return;
-
-                    case '\r':
-                        printf("   \\r");
-                        return;
-
-                    case '\t':
-                        printf("   \\t");
-                        return;
-
-                    case '\v':
-                        printf("   \\v");
-                        return;
-
-                    default:
-                        if (((signed char *)data)[offset] < 0) {
-                            printf("  %03o", ((unsigned char *)data)[offset]);
-                            return;
-                        }
-                        else if (((signed char *)data)[offset] < 32) {
-                            printf("  %03o", ((char *)data)[offset]);
-                            return;
-                        }
-
-                        break;
-                }
-
-            }
-
-            if (flags & OD_FLAGS_BYTES_INT) {
-                printf(format, ((int8_t *)data)[offset]);
-            }
-            else {
-                printf(format, ((uint8_t *)data)[offset]);
-            }
-
-            break;
-
-        case 2:
-            if (flags & OD_FLAGS_BYTES_INT) {
-                printf(format, ((int16_t *)data)[offset]);
-            }
-            else {
-                printf(format, ((uint16_t *)data)[offset]);
-            }
-
-            break;
-
-        case 4:
-        default:
-            if (flags & OD_FLAGS_BYTES_INT) {
-                printf(format, ((int32_t *)data)[offset]);
-            }
-            else {
-                printf(format, ((uint32_t *)data)[offset]);
-            }
-
-            break;
-
-        case 8:
-#ifndef MODULE_NEWLIB
-            if (flags & OD_FLAGS_BYTES_INT) {
-                printf(format, ((int64_t *)data)[offset]);
-            }
-            else {
-                printf(format, ((uint64_t *)data)[offset]);
-            }
-#else
-            printf("%s", format);
-#endif
-
-            break;
-
-    }
-}
-
-static int _log10(uint8_t a)
-{
-    int res = 0;
+#include <stdio.h>
+#include <stdint.h>
 
-    while (a > 0) {
-        a /= 10;
-        ++res;
-    }
+#include "fmt.h"
 
-    return ++res;
-}
+#include "od.h"
 
-void od(const void *data, size_t data_len, uint8_t width, uint16_t flags)
+void od_hex_dump(const void *data, size_t data_len, uint8_t width)
 {
-    char address_format[5];
-    uint8_t date_length = _length(flags);
-    char bytes_format[_log10(date_length) + 7];
-
-    if (data_len == 0) {
-        return;
-    }
-
-    _address_format(address_format, flags);
-    _bytes_format(bytes_format, flags);
+    print_str("00000000");
 
     if (width == 0) {
         width = OD_WIDTH_DEFAULT;
     }
 
-    if (width < date_length) {
-        width = 1;
-    }
-    else {
-        width = (width / date_length);
-    }
-
-    if (data_len % date_length) {
-        data_len = (data_len / date_length) + 1;
-    }
-    else {
-        data_len = data_len / date_length;
-    }
-
-    if ((flags & OD_FLAGS_ADDRESS_MASK) != OD_FLAGS_ADDRESS_NONE) {
-        printf(address_format, 0);
-    }
-
-    for (size_t i = 0; i < data_len; i++) {
-        _print_date(data, i, bytes_format, date_length, flags);
+    for (unsigned int i = 0; i < data_len; i++) {
+        print_str("  ");
+        print_byte_hex(((uint8_t *)data)[i]);
 
         if ((((i + 1) % width) == 0) || i == (data_len - 1)) {
-            printf("\n");
+            puts("");
 
             if (i != (data_len - 1)) {
-                if ((flags & OD_FLAGS_ADDRESS_MASK) != OD_FLAGS_ADDRESS_NONE) {
-                    printf(address_format, date_length * (i + 1));
-                }
+                print_u32_hex((uint32_t)(i + 1));
             }
         }
     }
-- 
GitLab