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