ACPI AML decompiler w/ CFG recovery and structured pseudocode
1#include "str.h"
2
3#include "mem.h"
4
5#include <stdarg.h>
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9
10static void need(tobi_sb *sb, size_t add) {
11 size_t req = tobi_xadd_size(tobi_xadd_size(sb->len, add), 1u);
12 if (req <= sb->cap) {
13 return;
14 }
15 size_t cap = tobi_xgrow_cap(sb->cap, req, 64u);
16 sb->buf = tobi_xrealloc(sb->buf, cap);
17 sb->cap = cap;
18}
19
20void tobi_sb_init(tobi_sb *sb) {
21 sb->buf = NULL;
22 sb->len = 0;
23 sb->cap = 0;
24 need(sb, 0);
25 sb->buf[0] = '\0';
26}
27
28void tobi_sb_free(tobi_sb *sb) {
29 free(sb->buf);
30 sb->buf = NULL;
31 sb->len = 0;
32 sb->cap = 0;
33}
34
35void tobi_sb_add(tobi_sb *sb, const char *s) {
36 tobi_sb_addn(sb, s, strlen(s));
37}
38
39void tobi_sb_addn(tobi_sb *sb, const char *s, size_t n) {
40 need(sb, n);
41 memcpy(sb->buf + sb->len, s, n);
42 sb->len += n;
43 sb->buf[sb->len] = '\0';
44}
45
46void tobi_sb_ch(tobi_sb *sb, char c) {
47 need(sb, 1);
48 sb->buf[sb->len++] = c;
49 sb->buf[sb->len] = '\0';
50}
51
52void tobi_sb_printf(tobi_sb *sb, const char *fmt, ...) {
53 va_list ap;
54 va_start(ap, fmt);
55 va_list cp;
56 va_copy(cp, ap);
57 int n = vsnprintf(NULL, 0, fmt, cp);
58 va_end(cp);
59 if (n < 0) {
60 va_end(ap);
61 return;
62 }
63 need(sb, (size_t)n);
64 (void)vsnprintf(sb->buf + sb->len, sb->cap - sb->len, fmt, ap);
65 va_end(ap);
66 sb->len += (size_t)n;
67}
68
69char *tobi_sb_take(tobi_sb *sb) {
70 char *out = sb->buf;
71 sb->buf = NULL;
72 sb->len = 0;
73 sb->cap = 0;
74 return out;
75}
76
77void tobi_json_string(tobi_sb *sb, const char *s) {
78 tobi_sb_ch(sb, '"');
79 for (const unsigned char *p = (const unsigned char *)s; *p; p++) {
80 unsigned char c = *p;
81 switch (c) {
82 case '"': tobi_sb_add(sb, "\\\""); break;
83 case '\\': tobi_sb_add(sb, "\\\\"); break;
84 case '\b': tobi_sb_add(sb, "\\b"); break;
85 case '\f': tobi_sb_add(sb, "\\f"); break;
86 case '\n': tobi_sb_add(sb, "\\n"); break;
87 case '\r': tobi_sb_add(sb, "\\r"); break;
88 case '\t': tobi_sb_add(sb, "\\t"); break;
89 default:
90 if (c < 0x20) {
91 char e[7];
92 (void)snprintf(e, sizeof(e), "\\u%04x", (unsigned)c);
93 tobi_sb_add(sb, e);
94 } else {
95 tobi_sb_ch(sb, (char)c);
96 }
97 break;
98 }
99 }
100 tobi_sb_ch(sb, '"');
101}
102
103void tobi_hex(tobi_sb *sb, const uint8_t *data, size_t len) {
104 static const char hex[] = "0123456789abcdef";
105 for (size_t i = 0; i < len; i++) {
106 char b[2] = {hex[data[i] >> 4], hex[data[i] & 15]};
107 tobi_sb_addn(sb, b, 2);
108 }
109}