commit 3cac34409d90fffc98ef2639a2af4c24616c814f
Author: Christos Margiolis <christos@margiolis.net>
Date: Sat, 15 Aug 2020 21:09:58 +0300
initial commit
Diffstat:
A | Makefile | | | 32 | ++++++++++++++++++++++++++++++++ |
A | README.md | | | 53 | +++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | cstring.c | | | 183 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | cstring.h | | | 37 | +++++++++++++++++++++++++++++++++++++ |
A | test.c | | | 43 | +++++++++++++++++++++++++++++++++++++++++++ |
5 files changed, 348 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -0,0 +1,32 @@
+TARGET = cstring
+
+SRC = $(wildcard *.c)
+OBJ = $(SRC:%.c=%.o)
+
+CC = gcc
+CPPFLAGS += -Iinclude -pedantic
+CFLAGS += -Wall -std=c99 -O3
+LDFLAGS += -Llib
+#LDLIBS +=
+
+MOVE = mv
+MKDIR_P = mkdir -p
+
+.PHONY: all clean
+
+all: $(TARGET)
+
+$(TARGET): $(OBJ)
+ $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
+
+%.o: %.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
+
+run:
+ ./$(TARGET)
+
+install: $(TARGET)
+ cp $(TARGET) $(INSTALL_PATH)
+
+clean:
+ $(RM) $(OBJ) $(TARGET)
diff --git a/README.md b/README.md
@@ -0,0 +1,53 @@
+# cstring
+
+## Usage
+
+Simply include the source files in your projects and compile them
+along with your other files.
+
+## Functions
+
+* `cstring_init`: Initiliazes string
+* `cstring_delete`: Deallocates string
+* `cstring_assign`: Assigns a new string to the current string
+* `cstring_append`: Appends a string to the current string
+* `cstring_insert`: Inserts a string at a specific index
+* `cstring_push_back`: Adds a character at the end of the string
+* `cstring_pop_back`: Removes the last character in the string
+* `cstring_replace`: Replaces a character at a specific index
+* `cstring_clear`: Erases the whole string
+* `cstring_exists`: Checks to see if a (sub)string exists in the string
+* `cstring_front`: Returns the first character of the string
+* `cstring_back`: Returns the last character of the string
+* `cstring_empty`: Checks if the string is empty
+* `cstring_len`: Returns the length of the string
+* `cstring_copy`: Makes a copy of a given `const char *`
+* `cstring_resize`: Resizes the array stored inside the string `struct`
+* `cstring_equals`: True if the strings are equal
+* `cstring_not_equals`: True if the strings are not equal
+* `cstring_greater`: True if the left hand string is greater than the right hand one
+* `cstring_greater_or_equals`: True if the left hand string is greater than or equal to the right hand one
+* `cstring_less`: True if the left hand string is less than the right hand one
+* `cstring_less_or_equals`: True if the left hand string is less than or equal to the right hand one
+
+## Example
+
+A recommended way of using this string is to **always** call the `cstring_delete` function when you're done
+working with it, in order not to cause any memory leaks, as there's no *destructor* to do it for you.
+Open `test.c` for more.
+
+```c
+#include <stdio.h>
+#include "cstring.h"
+
+int
+main(int argc, char **argv)
+{
+ cstring s = cstring_init("Example string");
+ cstring_append(&s, "more text...");
+ printf("%s\n", s.str);
+ cstring_delete(&s);
+
+ return 0;
+}
+```
diff --git a/cstring.c b/cstring.c
@@ -0,0 +1,183 @@
+#include "cstring.h"
+
+cstring
+cstring_init(const char *s)
+{
+ cstring cs;
+ cs.str = cstring_copy(s);
+ cs.len = cstring_len(&cs);
+ return cs;
+}
+
+void
+cstring_delete(cstring *cs)
+{
+ if (!cstring_empty(cs))
+ {
+ free(cs->str);
+ cs->str = NULL;
+ cs->len = 0;
+ }
+}
+
+void
+cstring_assign(cstring *cs, const char *s)
+{
+ if (!cstring_empty(cs)) free(cs->str);
+ cs->str = cstring_copy(s);
+ cs->len = cstring_len(cs);
+}
+
+void
+cstring_append(cstring *cs, const char *s)
+{
+ if (!cstring_empty(cs))
+ {
+ cstring_resize(cs, strlen(s));
+ strcat(cs->str, s);
+ }
+ cs->len = cstring_len(cs);
+}
+
+void
+cstring_insert(cstring *cs, const char *s, size_t i)
+{
+ if (!cstring_empty(cs) && i < cs->len)
+ {
+ char *tmp1 = (char *)malloc(i + 1);
+ char *tmp2 = (char *)malloc(cs->len - i + 1);
+ memcpy(tmp1, cs->str, i + 1);
+ memcpy(tmp2, cs->str + i, cs->len + 1);
+ cstring_resize(cs, strlen(s));
+ memcpy(cs->str, tmp1, i + 1);
+ memcpy(cs->str + i, s, strlen(s) + 1);
+ memcpy(cs->str + strlen(s) + i, tmp2, cs->len - i + 1);
+ cs->len = cstring_len(cs);
+ cs->str[cs->len] = '\0';
+ free(tmp1);
+ free(tmp2);
+ }
+}
+
+void
+cstring_push_back(cstring *cs, char c)
+{
+ cstring_resize(cs, 1);
+ cs->str[cs->len] = c;
+ cs->str[cs->len + 1] = '\0';
+ cs->len = cstring_len(cs);
+}
+
+void
+cstring_pop_back(cstring *cs)
+{
+ if (cs->len - 1 > 0)
+ {
+ char *tmp = (char *)malloc(cs->len);
+ memcpy(tmp, cs->str, cs->len);
+ free(cs->str);
+ tmp[cs->len - 1] = '\0';
+ cs->str = tmp;
+ cs->len--;
+ }
+}
+
+void
+cstring_replace(cstring *cs, size_t i, char c)
+{
+ if (i < cs->len) cs->str[i] = c;
+}
+
+void
+cstring_clear(cstring *cs)
+{
+ if (!cstring_empty(cs)) free(cs->str);
+ cs->str = (char *)malloc(1);
+ cs->str[0] = '\0';
+ cs->len = 0;
+}
+
+int
+cstring_exists(const cstring *cs, const char *s)
+{
+ return (strstr(cs->str, s) != NULL);
+}
+
+char
+cstring_front(const cstring *cs)
+{
+ return cs->str[0];
+}
+
+char
+cstring_back(const cstring *cs)
+{
+ return (!cstring_empty(cs) ? cs->str[cs->len -1] : cs->str[0]);
+}
+
+int
+cstring_empty(const cstring *cs)
+{
+ return (cs->len == 0 || cs->str == NULL);
+}
+
+size_t
+cstring_len(const cstring *cs)
+{
+ return strlen(cs->str);
+}
+
+char *
+cstring_copy(const char *s)
+{
+ size_t l = strlen(s);
+ char *tmp = (char *)malloc(l + 1);
+ memcpy(tmp, s, l + 1);
+ tmp[l] = '\0';
+ return tmp;
+}
+
+void
+cstring_resize(cstring *cs, size_t n)
+{
+ if (cstring_empty(cs))
+ {
+ size_t l = cs->len + n;
+ char *tmp = (char *)malloc(l + 1);
+ memcpy(tmp, cs->str, cs->len + 1);
+ free(cs->str);
+ tmp[l] = '\0';
+ cs->str = tmp;
+ cs->len = cstring_len(cs);
+ }
+}
+
+int
+cstring_equals(const cstring *lhs, const cstring *rhs)
+{
+ return (strcmp(lhs->str, rhs->str) == 0);
+}
+
+int
+cstring_greater(const cstring *lhs, const cstring *rhs)
+{
+ return (strcmp(lhs->str, rhs->str) > 0);
+}
+
+int
+cstring_greater_or_equals(const cstring *lhs, const cstring *rhs)
+{
+ return (strcmp(lhs->str, rhs->str) >= 0);
+}
+
+int
+cstring_less(const cstring *lhs, const cstring *rhs)
+{
+ return (strcmp(lhs->str, rhs->str) < 0);
+}
+
+int
+cstring_less_or_equals(const cstring *lhs, const cstring *rhs)
+{
+ return (strcmp(lhs->str, rhs->str) <= 0);
+}
diff --git a/cstring.h b/cstring.h
@@ -0,0 +1,37 @@
+#ifndef CSTRING_H
+#define CSTRING_H
+
+#include <stdlib.h>
+#include <string.h>
+
+typedef struct {
+ char *str;
+ size_t len;
+} cstring;
+
+extern cstring cstring_init(const char *s);
+extern void cstring_delete(cstring *cs);
+extern void cstring_assign(cstring *cs, const char *s);
+extern void cstring_append(cstring *cs, const char *s);
+extern void cstring_insert(cstring *cs, const char *s, size_t i);
+extern void cstring_push_back(cstring *cs, char c);
+extern void cstring_pop_back(cstring *cs);
+extern void cstring_replace(cstring *cs, size_t i, char c);
+extern void cstring_clear(cstring *cs);
+extern int cstring_exists(const cstring *cs, const char *s);
+extern char cstring_front(const cstring *cs);
+extern char cstring_back(const cstring *cs);
+extern int cstring_empty(const cstring *cs);
+extern size_t cstring_len(const cstring *cs);
+extern char *cstring_copy(const char *s);
+extern void cstring_resize(cstring *cs, size_t n);
+
+/* might be useless */
+extern int cstring_equals(const cstring *lhs, const cstring *rhs);
+extern int cstring_not_equals(const cstring *lhs, const cstring *rhs);
+extern int cstring_greater(const cstring *lhs, const cstring *rhs);
+extern int cstring_greater_or_equals(const cstring *lhs, const cstring *rhs);
+extern int cstring_less(const cstring *lhs, const cstring *rhs);
+extern int cstring_less_or_equals(const cstring *lhs, const cstring *rhs);
+
+#endif /* CSTRING_H */
diff --git a/test.c b/test.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+#include "cstring.h"
+
+int
+main(int argc, char **argv)
+{
+ cstring s = cstring_init("Hello world");
+ printf("cstring_init: %s (%ld)\n", s.str, s.len);
+
+ cstring_append(&s, "Append");
+ printf("cstring_append: %s (%ld)\n", s.str, s.len);
+
+ cstring_assign(&s, "New string");
+ printf("cstring_assign: %s (%ld)\n", s.str, s.len);
+
+ if (cstring_exists(&s, "string"))
+ printf("cstring_exists: \"string\" exists!\n");
+
+ cstring_push_back(&s, 'c');
+ printf("cstring_push_back: %s (%ld)\n", s.str, s.len);
+
+ cstring_insert(&s, "Inserted text", 4);
+ printf("cstring_insert: %s (%ld)\n", s.str, s.len);
+
+ cstring_pop_back(&s);
+ printf("cstring_pop_back: %s (%ld)\n", s.str, s.len);
+
+ cstring_clear(&s);
+ printf("cstring_clear: %s (%ld)\n", s.str, s.len);
+
+ cstring_assign(&s, "CSTRING");
+ printf("cstring_assign: %s (%ld)\n", s.str, s.len);
+ printf("cstring_front: %c\n", cstring_front(&s));
+ printf("cstring_back: %c\n", cstring_back(&s));
+
+ cstring_replace(&s, 3, 'x');
+ printf("cstring_replace: %s (%ld)\n", s.str, s.len);
+
+ cstring_delete(&s);
+ if (cstring_empty(&s)) printf("cstring_delete: Deleted string.\n");
+
+ return 0;
+}