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 109 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 = 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}