summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2024-05-31 12:47:19 -0300
committerEuAndreh <eu@euandre.org>2024-05-31 14:51:12 -0300
commit04e8cadf6f67b5658b3363dbfcecfc46494fed68 (patch)
tree98bfcf6f82e2cb66cd59540297d01a085383ebc1 /src
parentsrc/math.h: Add "add_size()" (diff)
downloadpindaiba-04e8cadf6f67b5658b3363dbfcecfc46494fed68.tar.gz
pindaiba-04e8cadf6f67b5658b3363dbfcecfc46494fed68.tar.xz
src/string.h: Add implementation for some basic functions
Diffstat (limited to 'src')
-rw-r--r--src/string.c149
-rw-r--r--src/string.h22
2 files changed, 169 insertions, 2 deletions
diff --git a/src/string.c b/src/string.c
index 6e1ba40..dce00f3 100644
--- a/src/string.c
+++ b/src/string.c
@@ -1,11 +1,156 @@
#include "config.h"
+#include <assert.h>
+#include <errno.h>
#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "logerr.h"
+#include "math.h"
+#include "util.h"
#include "string.h"
+
struct String {
- char *bytes;
- size_t length;
+ const size_t length;
+ const uint8_t *const bytes;
};
+
+
+
+int
+string_new_with(
+ const char *const string,
+ const size_t length,
+ const struct String **const out
+) {
+ int rc = -1;
+
+ const struct String *ret = NULL;
+ const uint8_t *bytes = NULL;
+
+ ret = malloc(sizeof(*ret));
+ if (ret == NULL) {
+ logerr("malloc(): %s", strerror(errno));
+ goto out;
+ }
+
+ bytes = malloc(length + NULL_TERMINATOR);
+ if (bytes == NULL) {
+ logerr("malloc(): %s", strerror(errno));
+ goto out;
+ }
+
+ memcpy((void *)bytes, string, length);
+ memcpy((void *)(bytes + length), "", NULL_TERMINATOR);
+ memcpy((void *)ret, &(struct String) {
+ .length = length,
+ .bytes = bytes,
+ }, sizeof(*ret));
+ *out = ret;
+ rc = 0;
+out:
+ if (rc) {
+ if (bytes != NULL) {
+ free((void *)bytes);
+ ret = NULL;
+ }
+ if (ret != NULL) {
+ free((void *)ret);
+ ret = NULL;
+ }
+ }
+ return rc;
+}
+
+int
+string_new(const char *const string, const struct String **const out) {
+ return string_new_with(string, strlen(string), out);
+}
+
+void
+string_free(const struct String **const s) {
+ free((void *)(*s)->bytes);
+ free((void *)(*s));
+ *s = NULL;
+}
+
+const char *
+cstr(const struct String *s) {
+ return (const char *)s->bytes;
+}
+
+enum Comparison
+string_equal(const struct String *const s1, const struct String *const s2) {
+ if (s1->length < s2->length) {
+ return Comparison_LT;
+ } else if (s1->length > s2->length) {
+ return Comparison_GT;
+ } else {
+ const int ret = strcmp((const char *)s1->bytes, (const char *)s2->bytes);
+ if (ret < 0) {
+ return Comparison_LT;
+ } else if (ret > 0) {
+ return Comparison_GT;
+ } else {
+ return Comparison_EQ;
+ }
+ }
+}
+
+int
+string_append(
+ const struct String *const s1,
+ const struct String *const s2,
+ const struct String **const out
+) {
+ int rc = -1;
+
+ const struct String *ret = NULL;
+ const uint8_t *bytes = NULL;
+
+ size_t length;
+ if (add_size(s1->length, s2->length, &length)) {
+ logerr("add_size()");
+ goto out;
+ }
+
+ ret = malloc(sizeof(*ret));
+ if (ret == NULL) {
+ logerr("malloc(): %s", strerror(errno));
+ goto out;
+ }
+
+ bytes = malloc(length + NULL_TERMINATOR);
+ if (bytes == NULL) {
+ logerr("malloc(): %s", strerror(errno));
+ goto out;
+ }
+
+ memcpy((void *)bytes, s1->bytes, s1->length);
+ memcpy((void *)(bytes + s1->length), s2->bytes, s2->length);
+ memcpy((void *)(bytes + length), "", NULL_TERMINATOR);
+ memcpy((void *)ret, &(struct String) {
+ .length = length,
+ .bytes = bytes,
+ }, sizeof(*ret));
+ *out = ret;
+ rc = 0;
+out:
+ if (rc) {
+ if (bytes != NULL) {
+ free((void *)bytes);
+ bytes = NULL;
+ }
+ if (ret != NULL) {
+ free((void *)ret);
+ ret = NULL;
+ }
+ }
+ return rc;
+}
diff --git a/src/string.h b/src/string.h
index 2a60e26..e945b40 100644
--- a/src/string.h
+++ b/src/string.h
@@ -1 +1,23 @@
struct String;
+
+enum Comparison {
+ Comparison_LT,
+ Comparison_EQ,
+ Comparison_GT,
+};
+
+int
+string_new(const char *const string, const struct String **out);
+
+void
+string_free(const struct String **const s);
+
+enum Comparison
+string_equal(const struct String *const s1, const struct String *const s2);
+
+int
+string_append(
+ const struct String *const s1,
+ const struct String *const s2,
+ const struct String **const out
+);