Line data Source code
1 : /* SPDX-License-Identifier: GPL-2.0-only */
2 : /*
3 : * Copyright (c) 2022 Meta Platforms, Inc. and affiliates.
4 : */
5 :
6 : #include "dump.h"
7 :
8 : #include <stddef.h>
9 : #include <stdio.h>
10 : #include <string.h>
11 :
12 : #define BF_DUMP_HEXDUMP_LEN 8
13 : #define BF_DUMP_TOKEN_LEN 5
14 :
15 1 : void bf_dump_prefix_push(prefix_t *prefix)
16 : {
17 : char *_prefix = *prefix;
18 1 : size_t len = strlen(_prefix);
19 :
20 1 : if (len) {
21 : /* If the prefix string is not empty, then we need to either
22 : * continue the previous branch (with a pipe), or remove
23 : * it altogether if it stopped. */
24 0 : strncpy(&_prefix[len - 4], _prefix[len - 4] == '`' ? " " : "| ",
25 : BF_DUMP_TOKEN_LEN);
26 : }
27 :
28 0 : if (len + BF_DUMP_TOKEN_LEN > DUMP_PREFIX_LEN)
29 : return;
30 :
31 1 : strncpy(&_prefix[len], "|-- ", BF_DUMP_TOKEN_LEN);
32 : }
33 :
34 1 : prefix_t *bf_dump_prefix_last(prefix_t *prefix)
35 : {
36 : char *_prefix = *prefix;
37 1 : size_t len = strlen(_prefix);
38 :
39 1 : if (len)
40 1 : strncpy(&_prefix[len - 4], "`-- ", BF_DUMP_TOKEN_LEN);
41 :
42 1 : return prefix;
43 : }
44 :
45 1 : void bf_dump_prefix_pop(prefix_t *prefix)
46 : {
47 : char *_prefix = *prefix;
48 1 : size_t len = strlen(_prefix);
49 :
50 1 : if (!len)
51 : return;
52 :
53 1 : _prefix[len - 4] = '\0';
54 :
55 : // Ensure we have a branch to the next item.
56 1 : if (len - 4)
57 0 : strncpy(&_prefix[len - 8], "|-- ", BF_DUMP_TOKEN_LEN);
58 : }
59 :
60 0 : void bf_dump_hex(prefix_t *prefix, const void *data, size_t len)
61 : {
62 : // 5 characters per byte (0x%02x) + 1 for the null terminator.
63 : char buf[(BF_DUMP_HEXDUMP_LEN * BF_DUMP_TOKEN_LEN) + 1];
64 0 : const void *end = data + len;
65 :
66 0 : while (data < end) {
67 : char *line = buf;
68 0 : for (size_t i = 0; i < BF_DUMP_HEXDUMP_LEN && data < end; ++i, ++data)
69 0 : line += sprintf(line, "0x%02x ", *(unsigned char *)data);
70 :
71 0 : DUMP((data == end ? bf_dump_prefix_last(prefix) : prefix), "%s", buf);
72 : }
73 0 : }
|