string.h (1899B)
1 #pragma once 2 3 #include <stdarg.h> 4 #include <stdbool.h> 5 #include <string.h> 6 7 #include "debug.h" 8 #include "def.h" 9 #include "utf8.h" 10 11 /* TODO: Before next usage of this module, document each function and 12 * add r_/R_/R prefixes. */ 13 14 /* Usage: printf("...%.*s...", STR_FMT(s)) */ 15 #define STR_FMT(s) (ASSERT(str_len(s) <= INT_MAX), (int)str_len(s)), str_bytes(s) 16 17 typedef struct str Str; 18 19 struct str { 20 usize len; 21 u8 *data; 22 }; 23 24 #define str_stack(s) (Str){ \ 25 .len = sizeof(s) - 1, \ 26 .data = (u8[MAX(sizeof(s) - 1, 1)]){s} \ 27 } 28 29 #define str_static(s) (Str){ \ 30 .len = sizeof(s) - 1, \ 31 .data = (u8 *)s \ 32 } 33 34 static inline usize 35 str_len(Str s) { 36 return s.len; 37 } 38 39 static inline u8 * 40 str_bytes(Str s) { 41 return s.data; 42 } 43 44 static inline int 45 str_cmp(Str s, Str t) { 46 int d = memcmp(s.data, t.data, MIN(s.len, t.len)); 47 if (d != 0 || s.len == t.len) return d; 48 else if (s.len < t.len) return -1; 49 else return 1; 50 } 51 52 static inline bool 53 str_eq(Str s, Str t) { 54 return s.len == t.len && !memcmp(s.data, t.data, s.len); 55 } 56 57 static inline isize 58 str_find_byte(Str s, u8 b) { 59 u8 *match = memchr(s.data, b, s.len); 60 return match ? match - s.data : -1; 61 } 62 63 static inline usize 64 str_utf8_decode(rune *c, Str s) { 65 return r_utf8_decode(c, (char *)s.data, s.len); 66 } 67 68 static inline Str 69 str_slice(Str s, isize l, isize u) { 70 if (l < 0) l += s.len; 71 ASSERT(0 <= l && l <= s.len, "str_slice: lower index out of bounds"); 72 73 if (u < 0) u += s.len; 74 ASSERT(0 <= u && u <= s.len, "str_slice: upper index out of bounds"); 75 76 return (Str){ 77 .len = l < u ? u - l : 0, 78 .data = s.data + l, 79 }; 80 } 81 82 static inline Str 83 str_slice_to_end(Str s, isize l) { 84 return str_slice(s, l, str_len(s)); 85 } 86 87 /* Like sprintf and vsprintf, but for Str's. The result must be freed with 88 * free(str_bytes(*str)). */ 89 int str_alloc_printf(Str *str, char *fmt, ...); 90 int str_alloc_vprintf(Str *str, char *fmt, va_list args); 91 92 char *str_alloc_cstr(Str s);