diff options
Diffstat (limited to 'src/string.h')
| -rw-r--r-- | src/string.h | 97 |
1 files changed, 91 insertions, 6 deletions
diff --git a/src/string.h b/src/string.h index a2e69c9..14e3c8a 100644 --- a/src/string.h +++ b/src/string.h @@ -33,7 +33,10 @@ strng_t * strng_dup(smrt_arena_t *arena, strng_t const *src); #define STRNG_TO(s) (char *)((u8*)(s)+STRNG_BASE_POS) #define STRNG_FMT(s) (i32)s->len, (char *)((u8*)(s)+STRNG_BASE_POS) -static inline strng_view_t sv_from(strng_t *string) { +#define SV_TO(sv) (char *)((u8*)((sv).string) + (sv).start) +#define SV_FMT(sv) (i32)(sv_len(&(sv))), SV_TO((sv)) + +static inline strng_view_t sv_from(strng_t const *string) { return (strng_view_t){ .string=(char*)((u8*)string+STRNG_BASE_POS), .start=0, @@ -41,12 +44,94 @@ static inline strng_view_t sv_from(strng_t *string) { .max=string->len, }; } + +static inline u64 sv_len(strng_view_t const *sv) { + return (sv->start <= sv->end) ? (sv->end - sv->start + 1) : 0; +} + +static inline strng_view_t sv_dup(strng_view_t const *src) { return *src; } +static inline strng_view_t sv_orig(strng_view_t const *src) { return (strng_view_t){ + .string=src->string, + .start=0, + .end=src->max, + .max=src->max }; } +static inline strng_view_t sv_subv(strng_view_t const *src, + u64 start_off, u64 max_len) { + u64 src_len = sv_len(src); + u64 new_start = src->start + MIN(start_off, src_len); + u64 available_len = (src->start + src_len) - new_start; + u64 actual_len = MIN(available_len, max_len); + + return (strng_view_t){ + .string = src->string, + .start = new_start, + .end = actual_len == 0 ? new_start - 1 : new_start + actual_len - 1, + .max = src->max + }; +} +static inline strng_view_t sv_drop_left(strng_view_t const *src, u64 n) { + u64 src_len = sv_len(src); + u64 m = MIN(src_len, n); + return sv_subv(src, m, src_len - m); +} +static inline strng_view_t sv_drop_right(strng_view_t const *src, u64 n) { + u64 src_len = sv_len(src); + u64 m = MIN(src_len, n); + return sv_subv(src, 0, src_len - m); +} + strng_view_t sv_from_chars(char const* c); -void sv_trim_left(strng_view_t *sv); -void sv_trim_right(strng_view_t *sv); -void sv_trim(strng_view_t *sv); -void sv_reset(strng_view_t *sv); +void sv_trimws_left (strng_view_t *sv); +void sv_trimws_right(strng_view_t *sv); +void sv_trimws (strng_view_t *sv); + +void sv_trim_pastc_left (strng_view_t *sv, char n); +void sv_trim_pastc_right(strng_view_t *sv, char n); + +// Starts from start and sets end to the next char n. +// Does nothing if there is no next char n +void sv_trim_end_nextc(strng_view_t *sv, char n); +// Starts from end and sets start to the prev char n. +// Does nothing if there is no prev char n +void sv_trim_strt_prvc(strng_view_t *sv, char n); + +// Sets length keeping start +void sv_set_len_left (strng_view_t *sv, u64 n); +// Sets length keeping end +void sv_set_len_right(strng_view_t *sv, u64 n); + + +static inline void sv_pop_left (strng_view_t *sv) { if (sv->start <= sv->end) sv->start++; } +static inline void sv_pop_right(strng_view_t *sv) { if (sv->end >= sv->start) sv->end--; } +static inline void sv_popn_left (strng_view_t *sv, u64 n) { for (u64 i = 0; i < n; i++) sv_pop_left(sv); } +static inline void sv_popn_right(strng_view_t *sv, u64 n) { for (u64 i = 0; i < n; i++) sv_pop_right(sv); } + +static inline void sv_reset(strng_view_t *sv) { + sv->start=0; + sv->end = sv->max; +} +static inline void sv_reset_right(strng_view_t *sv) { sv->end = sv->max; } +static inline void sv_reset_left(strng_view_t *sv) { sv->start = 0; } + +// Returns -1 if not found, otherwise distance from sv->start to beginning of needle +i32 sv_contains_simd(strng_view_t const *sv, char const *needle); +// Returns -1 if not found, otherwise distance from sv->start +i32 sv_contains_c_simd(strng_view_t const *sv, char n); + +b32 sv_starts_with(strng_view_t const *sv, char const *prefix); +b32 sv_ends_with(strng_view_t const *sv, char const *suffix); +static inline b32 sv_starts_with_c(strng_view_t sv, char c) { return + (sv_len(&sv) > 0) && (*SV_TO(sv) == c); } +static inline b32 sv_ends_with_c(strng_view_t sv, char c) { return + (sv_len(&sv) > 0) && (*(sv.string + sv.end) == c); } + +b32 sv_eq_case_insensitive(strng_view_t const *sv1, strng_view_t const *sv2); -#define SV_FMT(sv) (i32)((sv)->end - (sv)->start), (char *)((u8*)((sv)->string) + (sv)->start) +strng_view_t sv_split_once(strng_view_t *sv, char const *needle); +strng_view_t sv_split_once_c(strng_view_t *sv, char n); +// Returns chars read on succes, -1 if couldn't read +// Creates its own SV and skips whitespace. +// Fails if first char after trim isnt +/- or 0-9 +i32 sv_to_i64(strng_view_t const *sv, i64 *value_o); |