diff options
Diffstat (limited to 'source/kit/string_ref.h')
-rw-r--r-- | source/kit/string_ref.h | 71 |
1 files changed, 69 insertions, 2 deletions
diff --git a/source/kit/string_ref.h b/source/kit/string_ref.h index 38ade80..8e76d06 100644 --- a/source/kit/string_ref.h +++ b/source/kit/string_ref.h @@ -3,6 +3,7 @@ #include "array_ref.h" +#include <assert.h> #include <string.h> #ifdef __cplusplus @@ -24,6 +25,68 @@ static kit_str_t kit_str(i64 size, char const *static_string) { return s; } +enum { + KIT_STR_NOT_FOUND = -1, +}; + +static i64 kit_str_find(kit_str_t a, kit_str_t b) { + assert(a.size >= 0 && (a.size == 0 || a.values != NULL) && + b.size >= 0 && (b.size == 0 || b.values != NULL)); + if (a.size < 0 || (a.size != 0 && a.values == NULL) || b.size < 0 || + (b.size != 0 && b.values == NULL)) + return -1; + for (i64 index = 0; index + b.size <= a.size; index++) + if (KIT_AR_EQUAL(kit_str(b.size, a.values + index), b)) + return index; + return -1; +} + +static i64 kit_str_find_back(kit_str_t a, kit_str_t b) { + assert(a.size >= 0 && (a.size == 0 || a.values != NULL) && + b.size >= 0 && (b.size == 0 || b.values != NULL)); + if (a.size < 0 || (a.size != 0 && a.values == NULL) || b.size < 0 || + (b.size != 0 && b.values == NULL)) + return -1; + for (i64 index = a.size - b.size; index >= 0; index--) + if (KIT_AR_EQUAL(kit_str(b.size, a.values + index), b)) + return index; + return -1; +} + +static i64 kit_str_find_n(kit_str_t a, kit_str_t b, i64 n) { + assert(a.size >= 0 && (a.size == 0 || a.values != NULL) && + b.size >= 0 && (b.size == 0 || b.values != NULL)); + if (a.size < 0 || (a.size != 0 && a.values == NULL) || b.size < 0 || + (b.size != 0 && b.values == NULL)) + return -1; + i64 count = 0; + for (i64 index = 0; index + b.size <= a.size; index++) + if (KIT_AR_EQUAL(kit_str(b.size, a.values + index), b)) { + if (count == n) + return index; + else + count++; + } + return -1; +} + +static i64 kit_str_find_back_n(kit_str_t a, kit_str_t b, i64 n) { + assert(a.size >= 0 && (a.size == 0 || a.values != NULL) && + b.size >= 0 && (b.size == 0 || b.values != NULL)); + if (a.size < 0 || (a.size != 0 && a.values == NULL) || b.size < 0 || + (b.size != 0 && b.values == NULL)) + return -1; + i64 count = 0; + for (i64 index = a.size - b.size; index >= 0; index--) + if (KIT_AR_EQUAL(kit_str(b.size, a.values + index), b)) { + if (count == n) + return index; + else + count++; + } + return -1; +} + // Make a barbarian string for C standard library functions. // Not thread safe. // Use with caution. @@ -57,9 +120,13 @@ static char *kit_make_bs(kit_str_t s) { #ifndef KIT_DISABLE_SHORT_NAMES # define BS(...) kit_make_bs(KIT_WRAP_STR(__VA_ARGS__)) - # define str_t kit_str_t - +# define str kit_str +# define str_find kit_str_find +# define str_find_back kit_str_find_back +# define str_find_n kit_str_find_n +# define str_find_back_n kit_str_find_back_n +# define STR_NOT_FOUND KIT_STR_NOT_FOUND # define SZ KIT_SZ # define WRAP_BS KIT_WRAP_BS # define WRAP_STR KIT_WRAP_STR |