Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Print overhaul #373

Merged
merged 5 commits into from
Jan 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ If using zcbor with Zephyr, use the [Kconfig options](https://github.com/zephyrp
Name | Description
------------------------- | -----------
`ZCBOR_CANONICAL` | Assume canonical encoding (AKA "deterministically encoded CBOR"). When encoding lists and maps, do not use indefinite length encoding. Enabling `ZCBOR_CANONICAL` increases code size and makes the encoding library more often use state backups. When decoding, ensure that the incoming data conforms to canonical encoding, i.e. no indefinite length encoding, and always using minimal length encoding (e.g. not using 16 bits to encode a value < 256). Note: the map ordering constraint in canonical encoding is not checked.
`ZCBOR_VERBOSE` | Print messages on encoding/decoding errors (`zcbor_print()`), and also a trace message (`zcbor_trace()`) for each decoded value, and in each generated function (when using code generation). Requires `printk` as found in Zephyr.
`ZCBOR_VERBOSE` | Print log messages on encoding/decoding errors (`zcbor_log()`), and also a trace message (`zcbor_trace()`) for each decoded value, and in each generated function (when using code generation).
`ZCBOR_ASSERTS` | Enable asserts (`zcbor_assert()`). When they fail, the assert statements instruct the current function to return a `ZCBOR_ERR_ASSERTION` error. If `ZCBOR_VERBOSE` is enabled, a message is printed.
`ZCBOR_STOP_ON_ERROR` | Enable the `stop_on_error` functionality. This makes all functions abort their execution if called when an error has already happened.
`ZCBOR_BIG_ENDIAN` | All decoded values are returned as big-endian. The default is little-endian.
Expand Down
46 changes: 5 additions & 41 deletions include/zcbor_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,46 +40,6 @@ struct zcbor_string_fragment {
/** Size to use in struct zcbor_string_fragment when the real size is unknown. */
#define ZCBOR_STRING_FRAGMENT_UNKNOWN_LENGTH SIZE_MAX

#ifdef ZCBOR_VERBOSE
#include <zephyr/sys/printk.h>
#define zcbor_trace() (printk("bytes left: %zu, byte: 0x%x, elem_count: 0x%x, err: %d, %s:%d\n",\
(size_t)state->payload_end - (size_t)state->payload, *state->payload, state->elem_count, \
state->constant_state ? state->constant_state->error : 0, __FILE__, __LINE__))

#define zcbor_print_assert(expr, ...) \
do { \
printk("ASSERTION \n \"" #expr \
"\"\nfailed at %s:%d with message:\n ", \
__FILE__, __LINE__); \
printk(__VA_ARGS__);\
} while(0)
#define zcbor_print(...) printk(__VA_ARGS__)
#else
#define zcbor_trace() ((void)state)
#define zcbor_print_assert(...)
#define zcbor_print(...)
#endif

#ifdef ZCBOR_ASSERTS
#define zcbor_assert(expr, ...) \
do { \
if (!(expr)) { \
zcbor_print_assert(expr, __VA_ARGS__); \
ZCBOR_FAIL(); \
} \
} while(0)
#define zcbor_assert_state(expr, ...) \
do { \
if (!(expr)) { \
zcbor_print_assert(expr, __VA_ARGS__); \
ZCBOR_ERR(ZCBOR_ERR_ASSERTION); \
} \
} while(0)
#else
#define zcbor_assert(expr, ...)
#define zcbor_assert_state(expr, ...)
#endif

#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
Expand Down Expand Up @@ -209,26 +169,30 @@ typedef enum
*/
#define ZCBOR_FAIL() \
do {\
zcbor_trace(); \
zcbor_log("ZCBOR_FAIL "); \
zcbor_trace_file(state); \
return false; \
} while(0)

#define ZCBOR_FAIL_IF(expr) \
do {\
if (expr) { \
zcbor_log("ZCBOR_FAIL_IF(" #expr ") "); \
ZCBOR_FAIL(); \
} \
} while(0)

#define ZCBOR_ERR(err) \
do { \
zcbor_log("ZCBOR_ERR(%d) ", err); \
zcbor_error(state, err); \
ZCBOR_FAIL(); \
} while(0)

#define ZCBOR_ERR_IF(expr, err) \
do {\
if (expr) { \
zcbor_log("ZCBOR_ERR_IF(" #expr ", %d) ", err); \
ZCBOR_ERR(err); \
} \
} while(0)
Expand Down
103 changes: 0 additions & 103 deletions include/zcbor_debug.h

This file was deleted.

154 changes: 154 additions & 0 deletions include/zcbor_print.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef ZCBOR_PRINT_H__
#define ZCBOR_PRINT_H__


#ifdef __cplusplus
extern "C" {
#endif

#ifndef ZCBOR_PRINT_FUNC
#include <stdio.h>
#define zcbor_do_print(...) printf(__VA_ARGS__)
#else
#define zcbor_do_print(...) ZCBOR_PRINT_FUNC(__VA_ARGS__)
#endif

#ifdef ZCBOR_VERBOSE
#define zcbor_trace_raw(state) (zcbor_do_print("rem: %zu, cur: 0x%x, ec: 0x%zx, err: %d",\
(size_t)state->payload_end - (size_t)state->payload, *state->payload, state->elem_count, \
state->constant_state ? state->constant_state->error : 0))
#define zcbor_trace(state, appendix) do { \
zcbor_trace_raw(state); \
zcbor_do_print(", %s\n", appendix); \
} while(0)
#define zcbor_trace_file(state) do { \
zcbor_trace_raw(state); \
zcbor_do_print(", %s:%d\n", __FILE__, __LINE__); \
} while(0)

#define zcbor_log_assert(expr, ...) \
do { \
zcbor_do_print("ASSERTION \n \"" #expr \
"\"\nfailed at %s:%d with message:\n ", \
__FILE__, __LINE__); \
zcbor_do_print(__VA_ARGS__);\
} while(0)
#define zcbor_log(...) zcbor_do_print(__VA_ARGS__)
#else
#define zcbor_trace(state, appendix)
#define zcbor_trace_file(state) ((void)state)
#define zcbor_log_assert(...)
#define zcbor_log(...)
#endif

#ifdef ZCBOR_ASSERTS
#define zcbor_assert(expr, ...) \
do { \
if (!(expr)) { \
zcbor_log_assert(expr, __VA_ARGS__); \
ZCBOR_FAIL(); \
} \
} while(0)
#define zcbor_assert_state(expr, ...) \
do { \
if (!(expr)) { \
zcbor_log_assert(expr, __VA_ARGS__); \
ZCBOR_ERR(ZCBOR_ERR_ASSERTION); \
} \
} while(0)
#else
#define zcbor_assert(expr, ...)
#define zcbor_assert_state(expr, ...)
#endif

__attribute__((used))
static void zcbor_print_compare_lines(const uint8_t *str1, const uint8_t *str2, uint32_t size)
{
for (uint32_t j = 0; j < size; j++) {
zcbor_do_print("%x ", str1[j]);
}
zcbor_do_print("\r\n");
for (uint32_t j = 0; j < size; j++) {
zcbor_do_print("%x ", str2[j]);
}
zcbor_do_print("\r\n");
for (uint32_t j = 0; j < size; j++) {
zcbor_do_print("%x ", str1[j] != str2[j]);
}
zcbor_do_print("\r\n");
zcbor_do_print("\r\n");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it intentionally print "\r\n" twice?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, to make it visually separate from the next thing to be printed.

}

__attribute__((used))
static void zcbor_print_compare_strings(const uint8_t *str1, const uint8_t *str2, uint32_t size)
{
for (uint32_t i = 0; i <= size / 16; i++) {
zcbor_do_print("line %d (char %d)\r\n", i, i*16);
zcbor_print_compare_lines(&str1[i*16], &str2[i*16],
MIN(16, (size - i*16)));
}
zcbor_do_print("\r\n");
}

__attribute__((used))
static void zcbor_print_compare_strings_diff(const uint8_t *str1, const uint8_t *str2, uint32_t size)
{
bool printed = false;
for (uint32_t i = 0; i <= size / 16; i++) {
if (memcmp(&str1[i*16], &str2[i*16], MIN(16, (size - i*16)) != 0)) {
zcbor_do_print("line %d (char %d)\r\n", i, i*16);
zcbor_print_compare_lines(&str1[i*16], &str2[i*16],
MIN(16, (size - i*16)));
printed = true;
}
}
if (printed) {
zcbor_do_print("\r\n");
}
}

__attribute__((used))
static const char *zcbor_error_str(int error)
{
#define ZCBOR_ERR_CASE(err) case err: \
return #err; /* The literal is static per C99 6.4.5 paragraph 5. */\

switch(error) {
ZCBOR_ERR_CASE(ZCBOR_SUCCESS)
ZCBOR_ERR_CASE(ZCBOR_ERR_NO_BACKUP_MEM)
ZCBOR_ERR_CASE(ZCBOR_ERR_NO_BACKUP_ACTIVE)
ZCBOR_ERR_CASE(ZCBOR_ERR_LOW_ELEM_COUNT)
ZCBOR_ERR_CASE(ZCBOR_ERR_HIGH_ELEM_COUNT)
ZCBOR_ERR_CASE(ZCBOR_ERR_INT_SIZE)
ZCBOR_ERR_CASE(ZCBOR_ERR_FLOAT_SIZE)
ZCBOR_ERR_CASE(ZCBOR_ERR_ADDITIONAL_INVAL)
ZCBOR_ERR_CASE(ZCBOR_ERR_NO_PAYLOAD)
ZCBOR_ERR_CASE(ZCBOR_ERR_PAYLOAD_NOT_CONSUMED)
ZCBOR_ERR_CASE(ZCBOR_ERR_WRONG_TYPE)
ZCBOR_ERR_CASE(ZCBOR_ERR_WRONG_VALUE)
ZCBOR_ERR_CASE(ZCBOR_ERR_WRONG_RANGE)
ZCBOR_ERR_CASE(ZCBOR_ERR_ITERATIONS)
ZCBOR_ERR_CASE(ZCBOR_ERR_ASSERTION)
}
#undef ZCBOR_ERR_CASE

return "ZCBOR_ERR_UNKNOWN";
}

__attribute__((used))
static void zcbor_print_error(int error)
{
zcbor_do_print("%s\r\n", zcbor_error_str(error));
}

#ifdef __cplusplus
}
#endif

#endif /* ZCBOR_PRINT_H__ */
11 changes: 8 additions & 3 deletions samples/pet/src/pet_decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <string.h>
#include "zcbor_decode.h"
#include "pet_decode.h"
#include "zcbor_print.h"

#if DEFAULT_MAX_QTY != 3
#error "The type file was generated with a different default_max_qty than this file"
Expand All @@ -25,7 +26,7 @@ static bool decode_Pet(zcbor_state_t *state, struct Pet *result);
static bool decode_Pet(
zcbor_state_t *state, struct Pet *result)
{
zcbor_print("%s\r\n", __func__);
zcbor_log("%s\r\n", __func__);

bool tmp_result = (((zcbor_list_start_decode(state) && ((((zcbor_list_start_decode(state) && ((zcbor_multi_decode(1, 3, &(*result).names_count, (zcbor_decoder_t *)zcbor_tstr_decode, state, (&(*result).names), sizeof(struct zcbor_string))) || (zcbor_list_map_end_force_decode(state), false)) && zcbor_list_end_decode(state)))
&& ((zcbor_bstr_decode(state, (&(*result).birthday)))
Expand All @@ -35,8 +36,12 @@ static bool decode_Pet(
|| (((*result).species_choice == Pet_species_dog_c) && ((1)))
|| (((*result).species_choice == Pet_species_other_c) && ((1)))) || (zcbor_error(state, ZCBOR_ERR_WRONG_VALUE), false)))))) || (zcbor_list_map_end_force_decode(state), false)) && zcbor_list_end_decode(state))));

if (!tmp_result)
zcbor_trace();
if (!tmp_result) {
zcbor_trace_file(state);
zcbor_log("%s error: %s\r\n", __func__, zcbor_error_str(zcbor_peek_error(state)));
} else {
zcbor_log("%s success\r\n", __func__);
}

return tmp_result;
}
Expand Down
Loading