util.c (1603B)
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 #define LEN(a) (sizeof(a) / sizeof(*a)) 10 11 typedef struct { 12 char *s; 13 ptrdiff_t len; 14 } s8; 15 #define s8(s) (s8){s, LEN(s) - 1} 16 17 static void __attribute__((noreturn)) 18 die(const char *fmt, ...) 19 { 20 va_list ap; 21 22 va_start(ap, fmt); 23 vfprintf(stderr, fmt, ap); 24 va_end(ap); 25 26 exit(1); 27 } 28 29 static int 30 s8cmp(s8 a, s8 b) 31 { 32 if (a.len == 0 || a.len != b.len) 33 return a.len - b.len; 34 return memcmp(a.s, b.s, a.len); 35 } 36 37 /* 38 * trim whitespace from start and end of str 39 * returns a new s8 (same memory) 40 */ 41 static s8 42 s8trim(s8 str) 43 { 44 char *p = &str.s[str.len-1]; 45 46 for (; str.len && isspace(*p); str.len--, p--); 47 for (; str.len && isspace(*str.s); str.len--, str.s++); 48 49 return str; 50 } 51 52 /* replace escaped control chars with their actual char */ 53 static s8 54 unescape(s8 str) 55 { 56 char *t = str.s; 57 ptrdiff_t rem = str.len; 58 int off; 59 60 while ((t = memchr(t, '\\', rem)) != NULL) { 61 off = 1; 62 switch (t[1]) { 63 case 'n': t[0] = '\n'; t++; break; 64 case 't': t[0] = '\t'; t++; break; 65 case 'u': t++; continue; 66 default: off++; 67 } 68 rem = str.len-- - (t - str.s) - off; 69 memmove(t, t + off, rem); 70 } 71 72 return str; 73 } 74 75 static void * 76 xreallocarray(void *o, size_t n, size_t s) 77 { 78 void *new; 79 80 if (!(new = reallocarray(o, n, s))) 81 die("reallocarray()\n"); 82 83 return new; 84 } 85 86 static s8 87 s8dup(void *src, ptrdiff_t len) 88 { 89 s8 str = {0, len}; 90 if (len < 0) 91 die("s8dup(): negative len\n"); 92 str.s = xreallocarray(NULL, 1, len); 93 memcpy(str.s, src, len); 94 return str; 95 }