1 /*
2 * Copyright (c) 2023 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #ifndef ZCBOR_PRINT_H__
8 #define ZCBOR_PRINT_H__
9
10
11 #ifdef __cplusplus
12 extern "C" {
13 #endif
14
15 #ifndef ZCBOR_PRINT_FUNC
16 #include <stdio.h>
17 #define zcbor_do_print(...) printf(__VA_ARGS__)
18 #else
19 #define zcbor_do_print(...) ZCBOR_PRINT_FUNC(__VA_ARGS__)
20 #endif
21
22 #ifdef ZCBOR_VERBOSE
23 #define zcbor_trace_raw(state) (zcbor_do_print("rem: %zu, cur: 0x%x, ec: 0x%zx, err: %d",\
24 (size_t)state->payload_end - (size_t)state->payload, *state->payload, state->elem_count, \
25 state->constant_state ? state->constant_state->error : 0))
26 #define zcbor_trace(state, appendix) do { \
27 zcbor_trace_raw(state); \
28 zcbor_do_print(", %s\n", appendix); \
29 } while(0)
30 #define zcbor_trace_file(state) do { \
31 zcbor_trace_raw(state); \
32 zcbor_do_print(", %s:%d\n", __FILE__, __LINE__); \
33 } while(0)
34
35 #define zcbor_log_assert(expr, ...) \
36 do { \
37 zcbor_do_print("ASSERTION \n \"" #expr \
38 "\"\nfailed at %s:%d with message:\n ", \
39 __FILE__, __LINE__); \
40 zcbor_do_print(__VA_ARGS__);\
41 } while(0)
42 #define zcbor_log(...) zcbor_do_print(__VA_ARGS__)
43 #else
44 #define zcbor_trace(state, appendix)
45 #define zcbor_trace_file(state) ((void)state)
46 #define zcbor_log_assert(...)
47 #define zcbor_log(...)
48 #endif
49
50 #ifdef ZCBOR_ASSERTS
51 #define zcbor_assert(expr, ...) \
52 do { \
53 if (!(expr)) { \
54 zcbor_log_assert(expr, __VA_ARGS__); \
55 ZCBOR_FAIL(); \
56 } \
57 } while(0)
58 #define zcbor_assert_state(expr, ...) \
59 do { \
60 if (!(expr)) { \
61 zcbor_log_assert(expr, __VA_ARGS__); \
62 ZCBOR_ERR(ZCBOR_ERR_ASSERTION); \
63 } \
64 } while(0)
65 #else
66 #define zcbor_assert(expr, ...)
67 #define zcbor_assert_state(expr, ...)
68 #endif
69
70 __attribute__((used))
zcbor_print_compare_lines(const uint8_t * str1,const uint8_t * str2,size_t size)71 static void zcbor_print_compare_lines(const uint8_t *str1, const uint8_t *str2, size_t size)
72 {
73 for (size_t j = 0; j < size; j++) {
74 zcbor_do_print("%x ", str1[j]);
75 }
76 zcbor_do_print("\r\n");
77 for (size_t j = 0; j < size; j++) {
78 zcbor_do_print("%x ", str2[j]);
79 }
80 zcbor_do_print("\r\n");
81 for (size_t j = 0; j < size; j++) {
82 zcbor_do_print("%x ", str1[j] != str2[j]);
83 }
84 zcbor_do_print("\r\n");
85 zcbor_do_print("\r\n");
86 }
87
88 __attribute__((used))
zcbor_print_compare_strings(const uint8_t * str1,const uint8_t * str2,size_t size)89 static void zcbor_print_compare_strings(const uint8_t *str1, const uint8_t *str2, size_t size)
90 {
91 const size_t col_width = 16;
92
93 for (size_t i = 0; i <= size / col_width; i++) {
94 zcbor_do_print("line %zu (char %zu)\r\n", i, i*col_width);
95 zcbor_print_compare_lines(&str1[i*col_width], &str2[i*col_width],
96 MIN(col_width, (size - i*col_width)));
97 }
98 zcbor_do_print("\r\n");
99 }
100
101 __attribute__((used))
zcbor_print_compare_strings_diff(const uint8_t * str1,const uint8_t * str2,size_t size)102 static void zcbor_print_compare_strings_diff(const uint8_t *str1, const uint8_t *str2, size_t size)
103 {
104 const size_t col_width = 16;
105 bool printed = false;
106
107 for (size_t i = 0; i <= size / col_width; i++) {
108 if (memcmp(&str1[i*col_width], &str2[i*col_width], MIN(col_width, (size - i*col_width))) != 0) {
109 zcbor_do_print("line %zu (char %zu)\r\n", i, i*col_width);
110 zcbor_print_compare_lines(&str1[i*col_width], &str2[i*col_width],
111 MIN(col_width, (size - i*col_width)));
112 printed = true;
113 }
114 }
115 if (printed) {
116 zcbor_do_print("\r\n");
117 }
118 }
119
120 __attribute__((used))
zcbor_error_str(int error)121 static const char *zcbor_error_str(int error)
122 {
123 #define ZCBOR_ERR_CASE(err) case err: \
124 return #err; /* The literal is static per C99 6.4.5 paragraph 5. */\
125
126 switch(error) {
127 ZCBOR_ERR_CASE(ZCBOR_SUCCESS)
128 ZCBOR_ERR_CASE(ZCBOR_ERR_NO_BACKUP_MEM)
129 ZCBOR_ERR_CASE(ZCBOR_ERR_NO_BACKUP_ACTIVE)
130 ZCBOR_ERR_CASE(ZCBOR_ERR_LOW_ELEM_COUNT)
131 ZCBOR_ERR_CASE(ZCBOR_ERR_HIGH_ELEM_COUNT)
132 ZCBOR_ERR_CASE(ZCBOR_ERR_INT_SIZE)
133 ZCBOR_ERR_CASE(ZCBOR_ERR_FLOAT_SIZE)
134 ZCBOR_ERR_CASE(ZCBOR_ERR_ADDITIONAL_INVAL)
135 ZCBOR_ERR_CASE(ZCBOR_ERR_NO_PAYLOAD)
136 ZCBOR_ERR_CASE(ZCBOR_ERR_PAYLOAD_NOT_CONSUMED)
137 ZCBOR_ERR_CASE(ZCBOR_ERR_WRONG_TYPE)
138 ZCBOR_ERR_CASE(ZCBOR_ERR_WRONG_VALUE)
139 ZCBOR_ERR_CASE(ZCBOR_ERR_WRONG_RANGE)
140 ZCBOR_ERR_CASE(ZCBOR_ERR_ITERATIONS)
141 ZCBOR_ERR_CASE(ZCBOR_ERR_ASSERTION)
142 ZCBOR_ERR_CASE(ZCBOR_ERR_PAYLOAD_OUTDATED)
143 ZCBOR_ERR_CASE(ZCBOR_ERR_ELEM_NOT_FOUND)
144 ZCBOR_ERR_CASE(ZCBOR_ERR_MAP_MISALIGNED)
145 ZCBOR_ERR_CASE(ZCBOR_ERR_ELEMS_NOT_PROCESSED)
146 ZCBOR_ERR_CASE(ZCBOR_ERR_NOT_AT_END)
147 ZCBOR_ERR_CASE(ZCBOR_ERR_MAP_FLAGS_NOT_AVAILABLE)
148 ZCBOR_ERR_CASE(ZCBOR_ERR_INVALID_VALUE_ENCODING)
149 }
150 #undef ZCBOR_ERR_CASE
151
152 return "ZCBOR_ERR_UNKNOWN";
153 }
154
155 __attribute__((used))
zcbor_print_error(int error)156 static void zcbor_print_error(int error)
157 {
158 zcbor_do_print("%s\r\n", zcbor_error_str(error));
159 }
160
161 #ifdef __cplusplus
162 }
163 #endif
164
165 #endif /* ZCBOR_PRINT_H__ */
166