commit a33b249a441d7f3a7fd1adbb1cd887ca2e3adcfd
parent 2d0b7a1fec7fdcd2161b64300260cf0b7c7c457d
Author: Christos Margiolis <christos@margiolis.net>
Date: Thu, 1 Oct 2020 18:46:46 +0300
inlined some functions, simplified append & prepend functions, pending push_back bug fix
Diffstat:
6 files changed, 148 insertions(+), 155 deletions(-)
diff --git a/cstring.3 b/cstring.3
@@ -15,15 +15,15 @@ Deallocate string.
.BR void\ cstring_assign(cstring\ *cs,\ const\ char\ *s)
Assign a new string to current string.
.TP
+.BR void\ cstring_insert(cstring\ *cs,\ const\ char\ *s,\ size_t\ i)
+Insert at a specific index.
+.TP
.BR void\ cstring_append(cstring\ *cs,\ const\ char\ *s)
Append to end of string.
.TP
.BR void\ cstring_prepend(cstring\ *cs,\ const\ char\ *s)
Prepend to beginning of string.
.TP
-.BR void\ cstring_insert(cstring\ *cs,\ const\ char\ *s,\ size_t\ i)
-Insert at a specific index.
-.TP
.BR void\ cstring_erase(cstring\ *cs,\ size_t\ pos,\ size_t\ len)
Erase a portion of the string.
.TP
@@ -63,6 +63,9 @@ Erase the whole string.
.BR size_t\ cstring_find(const\ cstring\ *cs,\ const\ char\ *s)
Find first occurence of a pattern in string.
.TP
+.BR size_t\ cstring_rfind(const\ cstring\ *cs,\ const\ char\ *s)
+Find last occurence of a pattern in string.
+.TP
.BR size_t\ cstring_find_first_of(const\ cstring\ *cs,\ const\ char\ *s)
Find first occurence of specified characters in string.
.TP
diff --git a/cstring.c b/cstring.c
@@ -21,10 +21,8 @@ cstring_create(const char *s)
{
cstring cs;
cs.len = strlen(s);
- cs.capacity = cs.len << 1;
- cs.str = (char *)malloc(cs.capacity + 1);
- memcpy(cs.str, s, cs.len + 1);
- cs.str[cs.len] = '\0';
+ cs.str = cstring_copy(s);
+ cstring_resize(&cs, cs.len << 1);
return cs;
}
@@ -32,8 +30,8 @@ void
cstring_delete(cstring *cs)
{
if (!cstring_empty(cs)) free(cs->str);
- cs->str = NULL;
- cs->len = 0;
+ cs->str = NULL;
+ cs->len = 0;
cs->capacity = 0;
}
@@ -49,37 +47,15 @@ cstring_assign(cstring *cs, const char *s)
}
void
-cstring_append(cstring *cs, const char *s)
-{
- if (!cstring_empty(cs)) {
- size_t newlen = cs->len + strlen(s);
- if (CSTRING_EXCEEDS_CAPACITY(newlen, cs->capacity))
- cstring_resize(cs, newlen << 1);
- strcat(cs->str, s);
- cs->len = newlen;
- }
- else cstring_assign(cs, s);
-}
-
-void
-cstring_prepend(cstring *cs, const char *s)
-{
- cstring_insert(cs, s, 0);
-}
-
-void
cstring_insert(cstring *cs, const char *s, size_t i)
{
- if (!CSTRING_OUT_OF_BOUNDS(cs, i)
- && !cstring_empty(cs) // useless check?
- && s != NULL)
- {
+ if (!CSTRING_OUT_OF_BOUNDS(cs, i) && s != NULL) {
size_t slen = strlen(s);
size_t newlen = cs->len + slen;
char *tmp = (char *)malloc(newlen + 1);
memcpy(tmp, cs->str, i);
memcpy(tmp + i, s, slen);
- memcpy(tmp + i + slen, cs->str + i, cs->len);
+ memcpy(tmp + slen + i, cs->str + i , newlen - slen - i);
if (CSTRING_EXCEEDS_CAPACITY(newlen, cs->capacity))
cstring_resize(cs, newlen << 1);
free(cs->str);
@@ -136,8 +112,8 @@ cstring_trim(cstring *cs, const char *s)
void
cstring_push_back(cstring *cs, char c)
{
- if (CSTRING_EXCEEDS_CAPACITY(cs->len + 1, cs->capacity))
- cstring_resize(cs, (cs->len + 1) << 1);
+ if (CSTRING_EXCEEDS_CAPACITY(cs->len, cs->capacity))
+ cstring_resize(cs, cs->len << 1);
cs->str[cs->len] = c;
cs->str[++cs->len] = '\0';
}
@@ -196,12 +172,6 @@ cstring_swap(cstring *lhs, cstring *rhs)
}
void
-cstring_shrink_to_fit(cstring *cs)
-{
- cstring_resize(cs, cs->len);
-}
-
-void
cstring_clear(cstring *cs)
{
if (!cstring_empty(cs)) free(cs->str);
@@ -211,11 +181,14 @@ cstring_clear(cstring *cs)
cs->capacity = 0;
}
+#define CSTRING_CHECK(cs, s) \
+ if (cstring_empty(cs) || !*s) \
+ return CSTRING_NPOS
+
size_t
cstring_find(const cstring *cs, const char *s)
{
- if (cstring_empty(cs) || !*s)
- return CSTRING_NPOS;
+ CSTRING_CHECK(cs, s);
CSTRING_FIND_OCCURENCE(cs, s, strstr);
return CSTRING_NPOS;
}
@@ -223,17 +196,29 @@ cstring_find(const cstring *cs, const char *s)
size_t
cstring_rfind(const cstring *cs, const char *s)
{
- if (cstring_empty(cs) || !*s)
- return CSTRING_NPOS;
- /* IMPLEMENT */
- return CSTRING_NPOS;
+ CSTRING_CHECK(cs, s);
+ /* SIMPLIFY */
+ int found;
+ size_t idx = -1;
+ size_t slen = strlen(s);
+ size_t i = 0, j;
+ for (; i <= cs->len - slen; i++) {
+ found = 1;
+ for (j = 0; j < slen; j++) {
+ if (cs->str[i + j] != s[j]) {
+ found = 0;
+ break;
+ }
+ }
+ if (found) idx = i;
+ }
+ return (idx == -1 ? CSTRING_NPOS : idx);
}
size_t
cstring_find_first_of(const cstring *cs, const char *s)
{
- if (cstring_empty(cs) || !*s)
- return CSTRING_NPOS;
+ CSTRING_CHECK(cs, s);
for (; *s; s++) {
CSTRING_FIND_OCCURENCE(cs, *s, strchr);
}
@@ -243,8 +228,7 @@ cstring_find_first_of(const cstring *cs, const char *s)
size_t
cstring_find_first_not_of(const cstring *cs, const char *s)
{
- if (cstring_empty(cs) || !*s)
- return CSTRING_NPOS;
+ CSTRING_CHECK(cs, s);
size_t i = 0;
for (; i < cs->len; i++)
if (!cstring_is_one_of(cs->str[i], s))
@@ -255,8 +239,7 @@ cstring_find_first_not_of(const cstring *cs, const char *s)
size_t
cstring_find_last_of(const cstring *cs, const char *s)
{
- if (cstring_empty(cs) || !*s)
- return CSTRING_NPOS;
+ CSTRING_CHECK(cs, s);
size_t i = *(s + strlen(s));
for (; i >= 0; i--) {
CSTRING_FIND_OCCURENCE(cs, s[i], strrchr);
@@ -267,8 +250,7 @@ cstring_find_last_of(const cstring *cs, const char *s)
size_t
cstring_find_last_not_of(const cstring *cs, const char *s)
{
- if (cstring_empty(cs) || !*s)
- return CSTRING_NPOS;
+ CSTRING_CHECK(cs, s);
size_t i = cs->len;
for (; i >= 0; i--)
if (!cstring_is_one_of(cs->str[i], s))
@@ -276,47 +258,7 @@ cstring_find_last_not_of(const cstring *cs, const char *s)
return CSTRING_NPOS;
}
-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->str == NULL && cs->len == 0);
-}
-
-int
-cstring_starts_with_str(const cstring *cs, const char *s)
-{
- return (cstring_find(cs, s) == 0);
-}
-
-int
-cstring_ends_with_str(const cstring *cs, const char *s)
-{
- return (cstring_find(cs, s) == cs->len - strlen(s));
-}
-
-int
-cstring_starts_with_char(const cstring *cs, char c)
-{
- return (cs->str[0] == c);
-}
-
-int
-cstring_ends_with_char(const cstring *cs, char c)
-{
- return (cs->str[cs->len] = c);
-}
+#undef CSTR_CHECK
char *
cstring_copy(const char *s)
@@ -331,11 +273,8 @@ cstring_copy(const char *s)
void
cstring_resize(cstring *cs, size_t newcapacity)
{
- if (!cstring_empty(cs)) {
- cs->capacity = newcapacity;
- cs->str = (char *)realloc(cs->str, cs->capacity + 1);
- cs->str[cs->len] = '\0';
- }
+ cs->str = (char *)realloc(cs->str, newcapacity);
+ cs->capacity = newcapacity;
}
cstring *
@@ -349,33 +288,3 @@ cstring_getline(FILE *fd, cstring *cs, char delim)
}
return (c == EOF) ? NULL : 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
@@ -5,6 +5,10 @@
#include <stdlib.h>
#include <string.h>
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
#define CSTRING_NPOS -1
#define CSTRING_OUT_OF_BOUNDS(cs, pos) ((pos) > cs->len)
@@ -17,8 +21,6 @@ typedef struct cstring {
extern cstring cstring_create(const char *);
extern void cstring_delete(cstring *);
extern void cstring_assign(cstring *, const char *);
-extern void cstring_append(cstring *, const char *);
-extern void cstring_prepend(cstring *, const char *);
extern void cstring_insert(cstring *, const char *, size_t);
extern void cstring_erase(cstring *, size_t, size_t);
extern void cstring_erase_matching(cstring *, const char *);
@@ -30,31 +32,110 @@ extern void cstring_replace_char(cstring *, size_t, char);
extern void cstring_replace_str(cstring *, const char *, size_t, size_t);
extern cstring cstring_substr(const cstring *, size_t, size_t);
extern void cstring_swap(cstring *, cstring *);
-extern void cstring_shrink_to_fit(cstring *);
extern void cstring_clear(cstring *);
extern size_t cstring_find(const cstring *, const char *);
-extern size_t cstring_rfind(const cstring *, const char *); /* implement */
+extern size_t cstring_rfind(const cstring *, const char *);
extern size_t cstring_find_first_of(const cstring *, const char *);
extern size_t cstring_find_first_not_of(const cstring *,const char *);
extern size_t cstring_find_last_of(const cstring *, const char *);
extern size_t cstring_find_last_not_of(const cstring *, const char *);
-extern char cstring_front(const cstring *);
-extern char cstring_back(const cstring *);
-extern int cstring_empty(const cstring *);
-extern int cstring_starts_with_str(const cstring *, const char *);
-extern int cstring_ends_with_str(const cstring *, const char *);
-extern int cstring_starts_with_char(const cstring *, char);
-extern int cstring_ends_with_char(const cstring *, char);
extern char *cstring_copy(const char *);
extern void cstring_resize(cstring *, size_t);
extern cstring *cstring_getline(FILE *, cstring *, char);
-/* might be useless */
-extern int cstring_equal(const cstring *, const cstring *);
-extern int cstring_not_equal(const cstring *, const cstring *);
-extern int cstring_greater(const cstring *, const cstring *);
-extern int cstring_greater_or_equal(const cstring *, const cstring *);
-extern int cstring_less(const cstring *, const cstring *);
-extern int cstring_less_or_equal(const cstring *, const cstring *);
+/* inlines */
+static inline void
+cstring_prepend(cstring *cs, const char *s)
+{
+ cstring_insert(cs, s, 0);
+}
+
+static inline void
+cstring_append(cstring *cs, const char *s)
+{
+ cstring_insert(cs, s, cs->len);
+}
+
+static inline void
+cstring_shrink_to_fit(cstring *cs)
+{
+ cstring_resize(cs, cs->len);
+}
+
+static inline int
+cstring_empty(const cstring *cs)
+{
+ return (cs->str == NULL && cs->len == 0);
+}
+
+static inline char
+cstring_front(const cstring *cs)
+{
+ return cs->str[0];
+}
+
+static inline char
+cstring_back(const cstring *cs)
+{
+ return (!cstring_empty(cs) ? cs->str[cs->len - 1] : cs->str[0]);
+}
+
+static inline int
+cstring_starts_with_str(const cstring *cs, const char *s)
+{
+ return (cstring_find(cs, s) == 0);
+}
+
+static inline int
+cstring_ends_with_str(const cstring *cs, const char *s)
+{
+ return (cstring_find(cs, s) == cs->len - strlen(s));
+}
+
+static inline int
+cstring_starts_with_char(const cstring *cs, char c)
+{
+ return (cs->str[0] == c);
+}
+
+static inline int
+cstring_ends_with_char(const cstring *cs, char c)
+{
+ return (cs->str[cs->len] = c);
+}
+
+static inline int
+cstring_equal(const cstring *lhs, const cstring *rhs)
+{
+ return (strcmp(lhs->str, rhs->str) == 0);
+}
+
+static inline int
+cstring_greater(const cstring *lhs, const cstring *rhs)
+{
+ return (strcmp(lhs->str, rhs->str) > 0);
+}
+
+static inline int
+cstring_greater_or_equal(const cstring *lhs, const cstring *rhs)
+{
+ return (strcmp(lhs->str, rhs->str) >= 0);
+}
+
+static inline int
+cstring_less(const cstring *lhs, const cstring *rhs)
+{
+ return (strcmp(lhs->str, rhs->str) < 0);
+}
+
+static inline int
+cstring_less_or_equal(const cstring *lhs, const cstring *rhs)
+{
+ return (strcmp(lhs->str, rhs->str) <= 0);
+}
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
#endif /* CSTRING_H */
diff --git a/cstring.o b/cstring.o
Binary files differ.
diff --git a/libcstring.a b/libcstring.a
Binary files differ.
diff --git a/tests/test.c b/tests/test.c
@@ -8,12 +8,15 @@ main(int argc, char **argv)
cstring s = cstring_create("Hello world");
printf("cstring_create: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
- cstring_append(&s, "Append");
- printf("cstring_append: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
-
cstring_assign(&s, "New string");
printf("cstring_assign: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
+ cstring_append(&s, "Appended text");
+ printf("cstring_append: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
+
+ cstring_prepend(&s, "OK");
+ printf("cstring_prepend: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
+
cstring_push_back(&s, 'c');
printf("cstring_push_back: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
@@ -50,9 +53,6 @@ main(int argc, char **argv)
cstring_insert(&s, "New text", 2);
printf("cstring_insert: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
- cstring_prepend(&s, "OK");
- printf("cstring_prepend: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
-
cstring_delete(&s);
if (cstring_empty(&s)) printf("cstring_delete: Deleted string.\n");