diff options
Diffstat (limited to 'lib/cstr/cstr.c')
| -rw-r--r-- | lib/cstr/cstr.c | 353 |
1 files changed, 353 insertions, 0 deletions
diff --git a/lib/cstr/cstr.c b/lib/cstr/cstr.c new file mode 100644 index 0000000..fcb91f4 --- /dev/null +++ b/lib/cstr/cstr.c @@ -0,0 +1,353 @@ +#include "cstr.h" + +/** DOC + * @type function + * @name string_length + * + * @param char *str + * @return u64 + * + * @description + * Computes the length of an `ASCII` cstr. + */ +u64 cstr_length(const char *str) +{ + const char *p = str; + while (*p) ++p; + return p - str; +} + + +/** DOC + * @type function + * @name cstr_compare + * + * @param const char *a + * @param const char *b + * @return u8 + * + * @description + * Compares two strings. + * Returns 1 if a has a higher alphabethical value. + * Returns -1 if a has a lower alphabethical value. + * Returns 0 if strings are equal. + */ +i8 cstr_compare(const char *a, const char *b) +{ + while (*a && *b) { + if (*a < *b) + return -1; + if (*a > *b) + return 1; + + ++a; + ++b; + } + + if (*a < *b) + return -1; + if (*a > *b) + return 1; + + return 0; +} + + +/** DOC + * @type function + * @name cstr_split + * + * @param char *cstr + * @param char split + * @return u64 + * + * @description + * Splits a string on every `split` char. + * Returns the number of splits. + * ``WARNING`` This function does replace all `split` char with `0`. + * The old string does not exist after calling this function. + */ +u64 cstr_split(char *cstr, char split) +{ + u64 splits = 1; + + while (*cstr) { + if (*cstr == split) { + *cstr = 0; + ++splits; + } + + ++cstr; + } + + return splits; +} + + +/** DOC + * @type function + * @name next_split + * + * @param const char *previous; + * @return const char* + * + * @description + * Returns the next split of a `split list` created by `cstr_split`. + */ +const char *next_split(const char *previous) +{ + while (*previous) ++previous; + return previous + 1; +} + + +/** DOC + * @type function + * @name strip_front + * + * @param char *cstr + * @param char strip + * @return u64 + * + * @description + * Remove `strip` from front. + */ +u64 strip_front(char *cstr, char strip) +{ + char *front = cstr; + + while (*front && *front == strip) ++front; + + while (*front) { + *cstr = *front; + ++cstr; + ++front; + } + + while (*cstr) { + *cstr = 0; + ++cstr; + } + + return front - cstr; +} + + +/** DOC + * @type function + * @name strip_back + * + * @param char *cstr + * @param char stip + * @return u64 + * + * @description + * Removes `strip` char from back of the cstr. + */ +u64 strip_back(char *cstr, char strip) +{ + u64 diff = 0; + + while (*cstr) ++cstr; + --cstr; + + while (*cstr == strip) { + *cstr = 0; + ++diff; + } + + return diff; +} + +/** DOC + * @type function + * @name strip_cstr + * + * @param char *cstr + * @param char strip + * @return u64 + * + * @description + * Strips `strip` char from start and end of the string. + */ +u64 strip_cstr(char *cstr, char strip) +{ + return strip_front(cstr, strip) + strip_back(cstr, strip); +} + +/* DOC + * @type function + * @name string_utf8_length + * + * @param char *str + * @return u64 + * + * @description + * Computes the length of a `UTF-8` cstr. + */ +u64 cstr_utf8_length(const char * str) +{ + const char *p = str; + u64 length = 0; + int a = 0; + + while (*p) { + next_utf8(&p); + ++length; + } + + return length; +} + + +/** DOC + * @type function + * @name next_utf8 + * + * @param char **c + * @return u8 + * + * @description + * Set `c` to the next `UTF-8` char. + * Returns the difference relative to `ASCII` chars. + */ +u8 next_utf8(const char **c) +{ + int a; + + switch (**c & 0xf0) { + case 0xf0: a = 4; break; + case 0xe0: a = 3; break; + case 0xc0: a = 2; break; + default: a = 1; break; + } + + *c += a; + return a; +} + +/** DOC + * @type function + * @name previous_utf8 + * + * @param char **c + * @return u8 + * + * @description + * Set `c` to the previous `UTF-8` char. + * Returns the difference relative to `ASCII` chars. + */ +u8 previous_utf8(const char **c) +{ + int a = 1; + --(*c); + + while ((**c & 0xc0) == 0x80) { + --(*c); + ++a; + } + + return a; +} + +/** DOC + * @type function + * @name u64_to_cstr + * + * @param u64 n + * @param char *cstr + * @param u64 length + * + * @description + * Writes the string representation of `n` to the `cstr`. + */ +void u64_to_cstr(u64 n, char *cstr, u64 length) +{ + char *p = cstr + length - 1; + u64 d; + int i = 0; + + for (;n && i < length; ++i) { + *(p--) = (n % 10) + '0'; + n /= 10; + } + + d = p - cstr; + + for (i = 0; i < length - d; ++i) + cstr[i] = cstr[i + d]; +} + +/** DOC + * @type function + * @name i64_to_cstr + * + * @param i64 n + * @param char *cstr + * @param u64 length + * + * @description + * Writes the string representation of `n` to the `cstr`. + */ +void i64_to_cstr(i64 n, char *cstr, u64 length) +{ + if (n < 0) { + *cstr = '-'; + n = -n; + u64_to_cstr((u64)n, cstr + 1, length - 1); + } else { + u64_to_cstr((u64)n, cstr, length); + } +} + +/** DOC + * @type function + * @name cstr_to_u64 + * + * @param const char *cstr + * @return u64 + * + * @description + * Parses an `u64` to cstr. + */ +u64 cstr_to_u64(const char *cstr) +{ + u64 n = 0; + u64 e = 1; + const char *p = cstr; + + while (*p) { + if ((const unsigned char)(*p - '0') > 9) + return 0; + ++p; + } + + --p; + + while (p >= cstr) { + n += (*p - '0') * e; + e *= 10; + --p; + } + + return n; +} + + +/** DOC + * @type function + * @name cstr_to_i64 + */ +i64 cstr_to_i64(const char *cstr) +{ + i64 n = 0; + + if (*cstr == '-') { + n = (i64)cstr_to_u64(cstr + 1); + n = -n; + } else { + n = (i64)cstr_to_u64(cstr); + } + + return n; +} |