ACPI AML decompiler w/ CFG recovery and structured pseudocode
29

Configure Feed

Select the types of activity you want to include in your feed.

tobi / src / str.c
2.6 kB 112 lines
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}