#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <limits.h>
#include <ctype.h>
#include <assert.h>
#include <err.h>
#include "utils.h"
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
#define DIV_ROUND_UP(a, b) (1 + ((a - 1) / b))
#define MAX(x, y) ((x) > (y) ? (x) : (y))
#define MIN(x, y) ((x) < (y) ? (x) : (y))
static const int INDSTP = 3;
static size_t
to_hex(const uint8_t *buf, const size_t buf_sz, char *out, const size_t out_sz, const bool reverse)
{
assert(out);
const char nibble[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
const uint8_t nbs = sizeof(nibble) - 1;
size_t w = 0, last_non_zero = w;
for (size_t i = 0; i < buf_sz && out_sz > 2 && w < out_sz - 2; ++i) {
for (uint8_t c = 0; c < CHAR_BIT / 8 && w < out_sz; ++c) {
const size_t idx = (reverse ? (buf_sz - 1) - i : i);
const uint8_t hi = (buf[idx] >> (4 * (c + 1))) & nbs;
const uint8_t lo = (buf[idx] >> (8 * c)) & nbs;
if (w || hi || lo) {
out[w++] = nibble[hi];
out[w++] = nibble[lo];
last_non_zero = (hi || lo ? w : last_non_zero);
}
}
}
if (!w) {
out[w++] = nibble[0];
out[w++] = nibble[0];
} else {
w = last_non_zero;
}
assert(w < out_sz);
out[w] = 0;
return w;
}
static void
print_dec(const uint8_t *buf, const size_t size, const bool is_signed)
{
char hex[2 * sizeof(uint64_t) + 1];
to_hex(buf, size, hex, sizeof(hex), true);
if (is_signed) {
printf("%ld", (int64_t)strtoll(hex, NULL, 16));
} else {
printf("%lu", (uint64_t)strtoull(hex, NULL, 16));
}
}
static void
print_udec(const uint8_t *buf, const size_t size)
{
print_dec(buf, size, false);
}
static void
print_sdec(const uint8_t *buf, const size_t size)
{
print_dec(buf, size, true);
}
static void
print_hex(const uint8_t *buf, const size_t size)
{
char hex[2 * sizeof(uint64_t) + 1];
to_hex(buf, size, hex, sizeof(hex), true);
printf("0x%s", hex);
}
static void
print_array(const uint8_t *buf, const size_t size, const size_t nmemb, void (*fun)(const uint8_t *buf, const size_t size), const int sindent)
{
const int indent = sindent + INDSTP;
if (nmemb > 8) {
printf("{\n%*s", indent, "");
} else if (nmemb > 1) {
|