aboutsummaryrefslogtreecommitdiff
path: root/str.c
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2026-03-25 09:57:02 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2026-03-25 09:57:02 -0400
commitd79588bdf85b8c1514019e679c7eefbc9014edd9 (patch)
tree8bbdbc65d04ed8399e55ff0e836d9a9cc70c9396 /str.c
parent72d760a527c38d2e481f7b3204924ab53741e3a8 (diff)
downloaddo-d79588bdf85b8c1514019e679c7eefbc9014edd9.tar.gz
Initial commit
Diffstat (limited to 'str.c')
-rw-r--r--str.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/str.c b/str.c
new file mode 100644
index 0000000..5469e73
--- /dev/null
+++ b/str.c
@@ -0,0 +1,99 @@
+//
+// Created by jhunk on 3/21/26.
+//
+
+#include "str.h"
+
+int num_chars(const char *sptr, int ch) {
+ int result = 0;
+ for (int i = 0; sptr[i] != '\0'; i++) {
+ if (sptr[i] == ch) {
+ result++;
+ }
+ }
+ return result;
+}
+
+char** split(char *_sptr, const char* delim, size_t max, size_t *num)
+{
+ // Zero the number of elements in the result
+ int have_num = num != NULL;
+ if (have_num) {
+ *num = 0;
+ }
+
+ if (_sptr == NULL || delim == NULL) {
+ return NULL;
+ }
+ size_t split_alloc = 0;
+ // Duplicate the input string and save a copy of the pointer to be freed later
+ char *orig = _sptr;
+ char *sptr = strdup(orig);
+
+ if (!sptr) {
+ return NULL;
+ }
+
+ // Determine how many delimiters are present
+ for (size_t i = 0; i < strlen(delim); i++) {
+ if (max && i > max) {
+ break;
+ }
+ split_alloc += num_chars(sptr, delim[i]);
+ }
+
+ // Preallocate enough records based on the number of delimiters
+ char **result = calloc(split_alloc + 2, sizeof(result[0]));
+ if (!result) {
+ free(sptr);
+ sptr = NULL;
+ return NULL;
+ }
+
+ // No delimiter, but the string was not NULL, so return the original string
+ if (split_alloc == 0) {
+ result[0] = sptr;
+ return result;
+ }
+
+ // Separate the string into individual parts and store them in the result array
+ char *token = NULL;
+ char *sptr_tmp = sptr;
+ size_t pos = 0;
+ size_t i;
+ for (i = 0; (token = strsep(&sptr_tmp, delim)) != NULL; i++) {
+ // When max is zero, record all tokens
+ if (max > 0 && i == max) {
+ // Maximum number of splits occurred.
+ // Record position in string
+ pos = token - sptr;
+ break;
+ }
+ result[i] = calloc(BUFSIZ, sizeof(char));
+ if (!result[i]) {
+ return NULL;
+ }
+ strcpy(result[i], token);
+ }
+
+ // pos is non-zero when maximum split is reached
+ if (pos) {
+ // append the remaining string contents to array
+ result[i] = calloc(BUFSIZ, sizeof(char));
+ if (!result[i]) {
+ return NULL;
+ }
+ strcpy(result[i], &orig[pos]);
+ i++;
+ }
+
+ if (have_num) {
+ // Count of elements in the array
+ *num = i;
+ }
+
+ free(sptr);
+ sptr = NULL;
+ return result;
+}
+