aboutsummaryrefslogtreecommitdiff
path: root/lib/cstr/cstr.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/cstr/cstr.c')
-rw-r--r--lib/cstr/cstr.c353
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;
+}