From a2721c03c93959b39d3c63aec3ecb7fff14e21d2 Mon Sep 17 00:00:00 2001 From: Peter Kietzmann <peter.kietzmann@haw-hamburg.de> Date: Thu, 24 Aug 2017 18:25:58 +0200 Subject: [PATCH] sys/od: add ASCII representation to memory dump --- Makefile.dep | 4 ++++ makefiles/pseudomodules.inc.mk | 3 +++ sys/include/od.h | 7 ++++-- sys/od/od.c | 24 +++++++++++++++++-- tests/od/Makefile | 5 ++++ tests/od/tests/02-run.py | 44 ++++++++++++++++++++++++++++++++++ 6 files changed, 83 insertions(+), 4 deletions(-) create mode 100755 tests/od/tests/02-run.py diff --git a/Makefile.dep b/Makefile.dep index 30a08d86cb..6073e500ca 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -387,6 +387,10 @@ ifneq (,$(filter od,$(USEMODULE))) USEMODULE += fmt endif +ifneq (,$(filter od_string,$(USEMODULE))) + USEMODULE += od +endif + ifneq (,$(filter newlib_gnu_source,$(USEMODULE))) USEMODULE += newlib endif diff --git a/makefiles/pseudomodules.inc.mk b/makefiles/pseudomodules.inc.mk index 93ea8de591..ef2d821c07 100644 --- a/makefiles/pseudomodules.inc.mk +++ b/makefiles/pseudomodules.inc.mk @@ -70,6 +70,9 @@ PSEUDOMODULES += sock_ip PSEUDOMODULES += sock_tcp PSEUDOMODULES += sock_udp +# print ascii representation in function od_hex_dump() +PSEUDOMODULES += od_string + # include variants of the AT86RF2xx drivers as pseudo modules PSEUDOMODULES += at86rf23% PSEUDOMODULES += at86rf21% diff --git a/sys/include/od.h b/sys/include/od.h index 416b5e5429..1b0f84d537 100644 --- a/sys/include/od.h +++ b/sys/include/od.h @@ -9,7 +9,8 @@ /** * @defgroup sys_od Object dump * @ingroup sys - * @brief Allows to print out data dumps of memory regions + * @brief Allows to print out data dumps of memory regions in hexadecimal or/and + ASCII representation. * * @{ * @@ -34,7 +35,9 @@ extern "C" { /** * @brief Dumps memory stored at *data* byte-wise up to *data_len* in - * hexadecimal representation to stdout with + * hexadecimal representation to stdout. If the pseudomodlue `od_string` + is used (`USEMODULE += od_string`) the ASCII representation of *data* is + also displayed. * * @param[in] data Data to dump. * @param[in] data_len Length in bytes of *data* to output. diff --git a/sys/od/od.c b/sys/od/od.c index 486e6b9a66..490ccf0417 100644 --- a/sys/od/od.c +++ b/sys/od/od.c @@ -14,6 +14,7 @@ #include <stdio.h> #include <stdint.h> +#include <ctype.h> #include "fmt.h" @@ -26,13 +27,32 @@ void od_hex_dump(const void *data, size_t data_len, uint8_t width) if (width == 0) { width = OD_WIDTH_DEFAULT; } - +#if MODULE_OD_STRING + uint8_t str_pos = 0; +#endif 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)) { - puts(""); +#if MODULE_OD_STRING + /* fill in whitespace for incomplete hex lines */ + for (unsigned j = i; ((j + 1) % width) != 0; ++j) { + print_str(" "); + } + print_str(" "); + for(unsigned k = 0; k < (i % width) + 1; k++){ + if(isprint(((char *)data)[str_pos+k])){ + putchar(((char *)data)[str_pos+k]); + } + else{ + putchar('.'); + } + } + /* safe position for next iteration */ + str_pos = i + 1; +#endif + putchar('\n'); if (i != (data_len - 1)) { print_u32_hex((uint32_t)(i + 1)); diff --git a/tests/od/Makefile b/tests/od/Makefile index 1da1fdbbcb..fe4ec0d197 100644 --- a/tests/od/Makefile +++ b/tests/od/Makefile @@ -3,6 +3,7 @@ APPLICATION = od include ../Makefile.tests_common USEMODULE += od +# USEMODULE += od_string # Comment this out to disable code in RIOT that does safety checking # which is not needed in a production environment but helps in the @@ -12,4 +13,8 @@ CFLAGS += -DDEVELHELP include $(RIOTBASE)/Makefile.include test: +ifeq (,$(filter od_string,$(USEMODULE))) tests/01-run.py +else + tests/02-run.py +endif diff --git a/tests/od/tests/02-run.py b/tests/od/tests/02-run.py new file mode 100755 index 0000000000..0e2e6bef51 --- /dev/null +++ b/tests/od/tests/02-run.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2017 Hamburg University of Applied Sciences +# +# This file is subject to the terms and conditions of the GNU Lesser +# General Public License v2.1. See the file LICENSE in the top level +# directory for more details. + +import os +import sys + +sys.path.append(os.path.join(os.environ['RIOTBASE'], 'dist/tools/testrunner')) +import testrunner + +def testfunc(child): + child.expect_exact("od_hex_dump(short_str, sizeof(short_str), OD_WIDTH_DEFAULT)") + child.expect_exact("00000000 41 42 00 AB.") + child.expect_exact("od_hex_dump(long_str, sizeof(long_str), OD_WIDTH_DEFAULT)") + child.expect_exact("00000000 FF 2C 61 FF 2E 62 63 64 65 66 67 68 69 6A 6B 6C .,a..bcdefghijkl") + child.expect_exact("00000010 6D 6E 6F 70 00 mnop.") + child.expect_exact("od_hex_dump(long_str, sizeof(long_str), 4)") + child.expect_exact("00000000 FF 2C 61 FF .,a.") + child.expect_exact("00000004 2E 62 63 64 .bcd") + child.expect_exact("00000008 65 66 67 68 efgh") + child.expect_exact("0000000C 69 6A 6B 6C ijkl") + child.expect_exact("00000010 6D 6E 6F 70 mnop") + child.expect_exact("00000014 00 .") + child.expect_exact("od_hex_dump(long_str, sizeof(long_str), 3)") + child.expect_exact("00000000 FF 2C 61 .,a") + child.expect_exact("00000003 FF 2E 62 ..b") + child.expect_exact("00000006 63 64 65 cde") + child.expect_exact("00000009 66 67 68 fgh") + child.expect_exact("0000000C 69 6A 6B ijk") + child.expect_exact("0000000F 6C 6D 6E lmn") + child.expect_exact("00000012 6F 70 00 op.") + child.expect_exact("od_hex_dump(long_str, sizeof(long_str), 8)") + child.expect_exact("00000000 FF 2C 61 FF 2E 62 63 64 .,a..bcd") + child.expect_exact("00000008 65 66 67 68 69 6A 6B 6C efghijkl") + child.expect_exact("00000010 6D 6E 6F 70 00 mnop.") + + print("All tests successful") + +if __name__ == "__main__": + sys.exit(testrunner.run(testfunc, timeout=1, echo=False)) -- GitLab