util.c (1952B)
1 /* See LICENSE for license details. */ 2 #include <ctype.h> 3 #include <stdarg.h> 4 #include <stddef.h> 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <string.h> 8 9 #include <stdint.h> 10 #include <stddef.h> 11 typedef uint8_t u8; 12 typedef int64_t i64; 13 typedef uint64_t u64; 14 typedef int32_t i32; 15 typedef uint32_t u32; 16 typedef ptrdiff_t size; 17 18 #define ARRAY_COUNT(a) (sizeof(a) / sizeof(*a)) 19 20 typedef struct { 21 size len; 22 u8 *s; 23 } s8; 24 #define s8(cstr) (s8){.len = ARRAY_COUNT(cstr) - 1, .s = (u8 *)cstr} 25 26 static void __attribute__((noreturn)) 27 die(const char *fmt, ...) 28 { 29 va_list ap; 30 31 va_start(ap, fmt); 32 vfprintf(stderr, fmt, ap); 33 va_end(ap); 34 35 exit(1); 36 } 37 38 static int 39 s8cmp(s8 a, s8 b) 40 { 41 if (a.len == 0 || a.len != b.len) 42 return a.len - b.len; 43 return memcmp(a.s, b.s, a.len); 44 } 45 46 /* 47 * trim whitespace from start and end of str 48 * returns a new s8 (same memory) 49 */ 50 static s8 51 s8trim(s8 str) 52 { 53 u8 *p = str.s + str.len - 1; 54 55 for (; str.len && isspace(*p); str.len--, p--); 56 for (; str.len && isspace(*str.s); str.len--, str.s++); 57 58 return str; 59 } 60 61 /* replace escaped control chars with their actual char */ 62 static s8 63 unescape(s8 str) 64 { 65 u8 *t = str.s; 66 size rem = str.len; 67 int off; 68 69 while ((t = memchr(t, '\\', rem)) != NULL) { 70 off = 1; 71 switch (t[1]) { 72 case 'n': t[0] = '\n'; t++; break; 73 case 't': t[0] = '\t'; t++; break; 74 case 'u': t++; continue; 75 default: off++; 76 } 77 rem = str.len-- - (t - str.s) - off; 78 memmove(t, t + off, rem); 79 } 80 81 return str; 82 } 83 84 static void * 85 xreallocarray(void *o, size_t n, size_t s) 86 { 87 void *new; 88 89 if (!(new = reallocarray(o, n, s))) 90 die("reallocarray()\n"); 91 92 return new; 93 } 94 95 static s8 96 s8dup(void *src, size len) 97 { 98 s8 str = {.len = len}; 99 if (len < 0) 100 die("s8dup(): negative len\n"); 101 str.s = xreallocarray(NULL, 1, len); 102 memcpy(str.s, src, len); 103 return str; 104 } 105 106 static s8 107 cstr_to_s8(char *cstr) 108 { 109 s8 result = {.s = (u8 *)cstr}; 110 if (cstr) while (*cstr) { result.len++; cstr++; } 111 return result; 112 }