infix
A JIT-Powered FFI Library for C
Loading...
Searching...
No Matches
utility.c
Go to the documentation of this file.
1
31#if defined(INFIX_DEBUG_ENABLED) && INFIX_DEBUG_ENABLED
32
33/*
34 * This section conditionally includes and defines the `note()` macro.
35 * If the double_tap test harness is fully implemented (`DBLTAP_IMPLEMENTATION` is defined),
36 * we use its `note()` macro for integrated test logging. Otherwise, we define a simple
37 * `printf`-based fallback. This allows debug builds to function even outside the
38 * test suite.
39 */
40#if defined(DBLTAP_ENABLE) && defined(DBLTAP_IMPLEMENTATION)
41#include "common/double_tap.h"
42#else
43// Otherwise, define a simple printf-based fallback for note().
44#include <stdio.h>
45#ifndef note
46#define note(...) \
47 do { \
48 printf("# " __VA_ARGS__); \
49 printf("\n"); \
50 } while (0)
51#endif
52#endif
53#include "common/utility.h"
54#include <inttypes.h>
55
71void infix_dump_hex(const void * data, size_t size, const char * title) {
72 const uint8_t * byte = (const uint8_t *)data;
73 char line_buf[256];
74 char * buf_ptr;
75 size_t remaining_len;
76 int written;
77
78 // Print header with title and size.
79 note("%s (size: %llu bytes)", title, (unsigned long long)size);
80
81 for (size_t i = 0; i < size; i += 16) {
82 buf_ptr = line_buf;
83 remaining_len = sizeof(line_buf);
84
85 // Print the current offset within the data block.
86 written = snprintf(buf_ptr, remaining_len, "0x%04llx: ", (unsigned long long)i);
87 // The `goto` is used here as a simple error-handling mechanism. If `snprintf`
88 // fails or indicates the buffer is full, we jump to the `print_line` label
89 // to output whatever portion of the line has been formatted so far.
90 if (written < 0 || (size_t)written >= remaining_len)
91 goto print_line;
92 buf_ptr += written;
93 remaining_len -= written;
94
95 // Print 16 bytes in hexadecimal representation.
96 for (size_t j = 0; j < 16; ++j) {
97 if (i + j < size)
98 written = snprintf(buf_ptr, remaining_len, "%02x ", byte[i + j]);
99 else
100 written = snprintf(buf_ptr, remaining_len, " "); // Pad if at the end.
101 if (written < 0 || (size_t)written >= remaining_len)
102 goto print_line;
103 buf_ptr += written;
104 remaining_len -= written;
105
106 if (j == 7) { // Add extra space in the middle for readability.
107 written = snprintf(buf_ptr, remaining_len, " ");
108 if (written < 0 || (size_t)written >= remaining_len)
109 goto print_line;
110 buf_ptr += written;
111 remaining_len -= written;
112 }
113 }
114
115 written = snprintf(buf_ptr, remaining_len, "| ");
116 if (written < 0 || (size_t)written >= remaining_len)
117 goto print_line;
118 buf_ptr += written;
119 remaining_len -= written;
120
121 // Print the ASCII representation of the 16 bytes.
122 for (size_t j = 0; j < 16; ++j) {
123 if (i + j < size) {
124 // Use a '.' for non-printable characters.
125 if (byte[i + j] >= 32 && byte[i + j] <= 126)
126 written = snprintf(buf_ptr, remaining_len, "%c", byte[i + j]);
127 else
128 written = snprintf(buf_ptr, remaining_len, ".");
129 if (written < 0 || (size_t)written >= remaining_len)
130 goto print_line;
131 buf_ptr += written;
132 remaining_len -= written;
133 }
134 }
135
136print_line:
137 // Output the fully formatted (or partially formatted, if truncated) line.
138 // `snprintf` guarantees null-termination if the buffer size is > 0.
139 note(" %s", line_buf);
140 }
141 note("End of %s", title);
142}
143
144#endif // INFIX_DEBUG_ENABLED
A simple, header-only TAP14-compatible testing framework for C.
#define note(...)
Definition double_tap.h:150
A header for conditionally compiled debugging utilities.
static void infix_dump_hex(c23_maybe_unused const void *data, c23_maybe_unused size_t size, c23_maybe_unused const char *title)
Definition utility.h:115