rcx

miscellaneous C library
git clone git://git.rr3.xyz/rcx
Log | Files | Refs | README | LICENSE

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);