Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
R
RIOT
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
cm-projects
RIOT
Commits
3519a3d9
Commit
3519a3d9
authored
10 years ago
by
Martine Lenders
Browse files
Options
Downloads
Patches
Plain Diff
sys: Initial import of analytical object dump (od) module
parent
b7fc0df5
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
sys/Makefile
+3
-0
3 additions, 0 deletions
sys/Makefile
sys/include/od.h
+161
-0
161 additions, 0 deletions
sys/include/od.h
sys/od/Makefile
+1
-0
1 addition, 0 deletions
sys/od/Makefile
sys/od/od.c
+336
-0
336 additions, 0 deletions
sys/od/od.c
with
501 additions
and
0 deletions
sys/Makefile
+
3
−
0
View file @
3519a3d9
...
@@ -10,6 +10,9 @@ endif
...
@@ -10,6 +10,9 @@ endif
ifneq
(,$(filter lib,$(USEMODULE)))
ifneq
(,$(filter lib,$(USEMODULE)))
DIRS
+=
lib
DIRS
+=
lib
endif
endif
ifneq
(,$(filter od,$(USEMODULE)))
DIRS
+=
od
endif
ifneq
(,$(filter ping,$(USEMODULE)))
ifneq
(,$(filter ping,$(USEMODULE)))
DIRS
+=
ping
DIRS
+=
ping
endif
endif
...
...
This diff is collapsed.
Click to expand it.
sys/include/od.h
0 → 100644
+
161
−
0
View file @
3519a3d9
/*
* Copyright (C) 2014 Martin Lenders <mlenders@inf.fu-berlin.de>
*
* 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.
*/
/**
* @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
*
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/utilities/od.html">
* od(1)
* </a>
* @{
*
* @file od.h
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef __OD_H_
#define __OD_H_
#ifdef __cplusplus
extern
"C"
{
#endif
#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 */
#define OD_FLAGS_LENGTH_8 (0x0080)
/**< 8 byte */
#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()
*/
#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
(
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
* 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
(
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
);
}
#ifdef __cplusplus
}
#endif
#endif
/* __OD_H_ */
/** @} */
This diff is collapsed.
Click to expand it.
sys/od/Makefile
0 → 100644
+
1
−
0
View file @
3519a3d9
include
$(RIOTBASE)/Makefile.base
This diff is collapsed.
Click to expand it.
sys/od/od.c
0 → 100644
+
336
−
0
View file @
3519a3d9
/*
* Copyright (C) 2014 Martin Lenders <mlenders@inf.fu-berlin.de>
*
* 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.
*/
/**
* @{
*
* @file od.c
*/
#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
,
" %03"
PRIo8
,
sizeof
(
" %03"
PRIo8
));
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
;
case
OD_FLAGS_BYTES_OCTAL
|
OD_FLAGS_LENGTH_SHORT
:
sprintf
(
format
,
" %%0%dho"
,
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
;
case
OD_FLAGS_BYTES_INT
|
OD_FLAGS_LENGTH_1
:
strncpy
(
format
,
" %4"
PRId8
,
sizeof
(
" %4"
PRId8
));
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
;
case
OD_FLAGS_BYTES_INT
|
OD_FLAGS_LENGTH_SHORT
:
sprintf
(
format
,
" %%%dhd"
,
sizeof
(
short
)
*
_INT_BYTE_LENGTH
);
break
;
case
OD_FLAGS_BYTES_INT
|
OD_FLAGS_LENGTH_LONG
:
sprintf
(
format
,
" %%%dld"
,
sizeof
(
long
)
*
_INT_BYTE_LENGTH
);
break
;
case
OD_FLAGS_BYTES_UINT
|
OD_FLAGS_LENGTH_1
:
strncpy
(
format
,
" %3"
PRIu8
,
sizeof
(
" %3"
PRIu8
));
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
;
case
OD_FLAGS_BYTES_UINT
|
OD_FLAGS_LENGTH_SHORT
:
sprintf
(
format
,
" %%%dhu"
,
sizeof
(
short
)
*
_INT_BYTE_LENGTH
);
break
;
case
OD_FLAGS_BYTES_UINT
|
OD_FLAGS_LENGTH_LONG
:
sprintf
(
format
,
" %%%dlu"
,
sizeof
(
long
)
*
_INT_BYTE_LENGTH
);
break
;
case
OD_FLAGS_BYTES_HEX
|
OD_FLAGS_LENGTH_1
:
strncpy
(
format
,
" %02"
PRIx8
,
sizeof
(
" %02"
PRIx8
));
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
;
case
OD_FLAGS_BYTES_HEX
|
OD_FLAGS_LENGTH_SHORT
:
sprintf
(
format
,
" %%0%dhx"
,
sizeof
(
short
)
*
_HEX_BYTE_LENGTH
);
break
;
case
OD_FLAGS_BYTES_HEX
|
OD_FLAGS_LENGTH_LONG
:
sprintf
(
format
,
" %%0%dlx"
,
sizeof
(
long
)
*
_HEX_BYTE_LENGTH
);
break
;
default:
break
;
}
}
static
void
_print_date
(
void
*
data
,
size_t
offset
,
char
*
format
,
uint8_t
length
,
uint16_t
flags
)
{
switch
(
length
)
{
case
1
:
if
(
flags
&
OD_FLAGS_BYTES_CHAR
)
{
switch
(((
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
(((
char
*
)
data
)[
offset
]
<
0
)
{
printf
(
" %03o"
,
((
unsigned
char
*
)
data
)[
offset
]);
return
;
}
else
if
(((
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
:
if
(
flags
&
OD_FLAGS_BYTES_INT
)
{
printf
(
format
,
((
int64_t
*
)
data
)[
offset
]);
}
else
{
printf
(
format
,
((
uint64_t
*
)
data
)[
offset
]);
}
break
;
}
}
static
int
_log10
(
uint8_t
a
)
{
int
res
=
0
;
while
(
a
>
0
)
{
a
/=
10
;
++
res
;
}
return
++
res
;
}
void
od
(
void
*
data
,
size_t
data_len
,
uint8_t
width
,
uint16_t
flags
)
{
char
address_format
[
5
];
uint8_t
date_length
=
_length
(
flags
);
char
bytes_format
[
_log10
(
date_length
)
+
7
];
_address_format
(
address_format
,
flags
);
_bytes_format
(
bytes_format
,
flags
);
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
);
if
((((
i
+
1
)
%
width
)
==
0
)
||
i
==
(
data_len
-
1
))
{
printf
(
"
\n
"
);
if
(
i
!=
(
data_len
-
1
))
{
if
((
flags
&
OD_FLAGS_ADDRESS_MASK
)
!=
OD_FLAGS_ADDRESS_NONE
)
{
printf
(
address_format
,
date_length
*
(
i
+
1
));
}
}
}
}
}
/** @} */
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment