commit 9cac873acc706b2a683ed1541c367e38768cb999
parent 9ce134335486b3b6a7337be22a3d00e35c235729
Author: Christos Margiolis <christos@margiolis.net>
Date: Mon, 19 Oct 2020 04:44:30 +0300
improved style, made indentation 8 spaces
Diffstat:
9 files changed, 367 insertions(+), 343 deletions(-)
diff --git a/LICENSE b/LICENSE
diff --git a/Makefile b/Makefile
@@ -1,3 +1,5 @@
+# See LICENSE file for copyright and license details.
+
LIB = cstring
VERSION = 0.1
DIST = ${LIB}-${VERSION}
@@ -31,40 +33,40 @@ GZIP = gzip
all: options ${LIB}
options:
- @echo ${LIB} build options:
- @echo "CFLAGS = ${CFLAGS}"
- @echo "LDFLAGS = ${LDFLAGS}"
- @echo "CC = ${CC}"
+ @echo ${LIB} build options:
+ @echo "CFLAGS = ${CFLAGS}"
+ @echo "LDFLAGS = ${LDFLAGS}"
+ @echo "CC = ${CC}"
${LIB}: ${OBJ}
- ${AR} ${ARFLAGS} lib${LIB}.a ${OBJ}
+ ${AR} ${ARFLAGS} lib${LIB}.a ${OBJ}
-%.o: %.${EXT}
- ${CC} ${CFLAGS} -c $< -o $@
+${OBJ}: ${SRC}
+ ${CC} ${CFLAGS} -c $< -o $@
dist: clean
- ${MKDIR} ${DIST}
- ${CP} -R tests ${SRC} ${MAN3} LICENSE Makefile README.md ${DIST}
- ${TAR} ${DIST}.tar ${DIST}
- ${GZIP} ${DIST}.tar
- ${RM_DIR} ${DIST}
+ ${MKDIR} ${DIST}
+ ${CP} -R tests ${SRC} ${MAN3} LICENSE Makefile README.md ${DIST}
+ ${TAR} ${DIST}.tar ${DIST}
+ ${GZIP} ${DIST}.tar
+ ${RM_DIR} ${DIST}
install: all
- ${MKDIR} ${DESTDIR}${LIB_DIR} ${DESTDIR}${INC_DIR} ${DESTDIR}${MAN_DIR}
- ${CP} ${LIB}.h ${DESTDIR}${INC_DIR}
- ${CP} lib${LIB}.a ${DESTDIR}${LIB_DIR}
- ${CP} ${MAN3} ${DESTDIR}${MAN_DIR}
- sed "s/VERSION/${VERSION}/g" < ${MAN3} > ${DESTDIR}${MAN_DIR}/${MAN3}
- chmod 755 ${DESTDIR}${INC_DIR}/${LIB}.h
- chmod 644 ${DESTDIR}${LIB_DIR}/lib${LIB}.a
- chmod 644 ${DESTDIR}${MAN_DIR}/${MAN3}
+ ${MKDIR} ${DESTDIR}${LIB_DIR} ${DESTDIR}${INC_DIR} ${DESTDIR}${MAN_DIR}
+ ${CP} ${LIB}.h ${DESTDIR}${INC_DIR}
+ ${CP} lib${LIB}.a ${DESTDIR}${LIB_DIR}
+ ${CP} ${MAN3} ${DESTDIR}${MAN_DIR}
+ sed "s/VERSION/${VERSION}/g" < ${MAN3} > ${DESTDIR}${MAN_DIR}/${MAN3}
+ chmod 755 ${DESTDIR}${INC_DIR}/${LIB}.h
+ chmod 644 ${DESTDIR}${LIB_DIR}/lib${LIB}.a
+ chmod 644 ${DESTDIR}${MAN_DIR}/${MAN3}
uninstall:
- ${RM} ${DESTDIR}${INC_DIR}/${LIB}.h
- ${RM} ${DESTDIR}${LIB_DIR}/lib${LIB}.a
- ${RM} ${DESTDIR}${MAN_DIR}/${MAN3}
+ ${RM} ${DESTDIR}${INC_DIR}/${LIB}.h
+ ${RM} ${DESTDIR}${LIB_DIR}/lib${LIB}.a
+ ${RM} ${DESTDIR}${MAN_DIR}/${MAN3}
clean:
- ${RM} ${LIB} ${OBJ} lib${LIB}.a ${DIST}.tar.gz
+ ${RM} ${LIB} ${OBJ} lib${LIB}.a ${DIST}.tar.gz
.PHONY: all options clean dist install uninstall
diff --git a/README.md b/README.md
@@ -1,7 +1,7 @@
# cstring
A simple and lightweight string library for C inspired by C++'s STL `string` class,
-but with a lot of additions.
+but with a many additions.
## Building
@@ -30,7 +30,9 @@ When using this library, you must **always** call the `cstring_create` and `cstr
functions whenever you want to make a new instance of `cstring` and stop using it respectively,
in order not to cause any memory leaks, as there's no *constructor* and *destructor* to do it for you.
-The recommended way of initializing an empty string is by doing `cstring foo = cstring_create(CSTRING_INIT_EMPTY)`.
+The recommended way of initializing an empty string is by doing `cstring foo = cstring_create(CSTRING_INIT_EMPTY)`.
+
+Read the `man` page for more detailed info.
## Functions
@@ -104,7 +106,6 @@ The following macros can only be used in debug mode
See the test programs in `tests` for more.
```c
-#include <stdio.h>
#include <cstring.h>
/* outputs "Foobar" to the screen */
diff --git a/cstring.3 b/cstring.3
diff --git a/cstring.c b/cstring.c
@@ -1,23 +1,25 @@
+/* See LICENSE file for copyright and license details. */
+
#include "cstring.h"
#define CSTRING_EXCEEDS_CAPACITY(len, cap) ((len) >= (cap))
-#define CSTRING_FIND_OCCURENCE(cs, s, func) do { \
- char *_found; \
- if ((_found = func(cs->str, (s))) != NULL) \
- return (_found - cs->str); \
+#define CSTRING_FIND_OCCURENCE(cs, s, func) do { \
+ char *_found; \
+ if ((_found = func(cs->str, (s))) != NULL) \
+ return (_found - cs->str); \
} while (0)
#ifdef CSTRING_DBG
-#define CSTRING_FREE(cs) do { \
- CSTRING_DBG_LOG("Before CSTRING_FREE: %s\n", cs->str); \
- if (!cstring_empty(cs)) \
- free(cs->str); \
+#define CSTRING_FREE(cs) do { \
+ CSTRING_DBG_LOG("Before CSTRING_FREE: %s\n", cs->str); \
+ if (!cstring_empty(cs)) \
+ free(cs->str); \
} while (0)
#else /* !CSTRING_DBG */
-#define CSTRING_FREE(cs) do { \
- if (!cstring_empty(cs)) \
- free(cs->str); \
+#define CSTRING_FREE(cs) do { \
+ if (!cstring_empty(cs)) \
+ free(cs->str); \
} while (0)
#endif /* CSTRING_DBG */
@@ -31,165 +33,173 @@ static inline int cstring_cmp_char_less(const void *, const void *);
static int
cstring_is_one_of(char c, const char *s)
{
- for (; *s; s++)
- if (*s == c)
- return 1;
- return 0;
+ for (; *s; s++)
+ if (*s == c)
+ return 1;
+ return 0;
}
static inline int
cstring_cmp_greater(const void *lhs, const void *rhs)
{
- return cstring_greater((cstring *)lhs, (cstring *)rhs);
+ return cstring_greater((cstring *)lhs, (cstring *)rhs);
}
static inline int
cstring_cmp_less(const void *lhs, const void *rhs)
{
- return cstring_less((cstring *)lhs, (cstring *)rhs);
+ return cstring_less((cstring *)lhs, (cstring *)rhs);
}
static inline int
cstring_cmp_char_greater(const void *lhs, const void *rhs)
{
- return (*(char *)lhs > *(char *)rhs);
+ return (*(char *)lhs > *(char *)rhs);
}
static inline int
cstring_cmp_char_less(const void *lhs, const void *rhs)
{
- return (*(char *)lhs < *(char *)rhs);
+ return (*(char *)lhs < *(char *)rhs);
}
/* externs */
cstring
cstring_create(const char *s)
{
- cstring cs;
- cs.len = strlen(s);
- cs.str = cstring_copy(s);
- cstring_resize(&cs, cs.len << 1);
+ cstring cs;
+ cs.len = strlen(s);
+ cs.str = cstring_copy(s);
+ cstring_resize(&cs, cs.len << 1);
#ifdef CSTRING_DBG
- CSTRING_DBG_LOG_STR_INFO(s, cs.len);
- CSTRING_DBG_LOG_CSTR_INFO_NPTR(cs);
+ CSTRING_DBG_LOG_STR_INFO(s, cs.len);
+ CSTRING_DBG_LOG_CSTR_INFO_NPTR(cs);
#endif /* CSTRING_DBG */
- return cs;
+ return cs;
}
void
cstring_delete(cstring *cs)
{
- CSTRING_FREE(cs);
- cs->str = NULL;
- cs->len = 0;
- cs->capacity = 0;
+ CSTRING_FREE(cs);
+ cs->str = NULL;
+ cs->len = 0;
+ cs->capacity = 0;
}
void
cstring_assign(cstring *cs, const char *s)
{
- CSTRING_FREE(cs);
- cs->str = cstring_copy(s);
- cs->len = strlen(s);
- if (CSTRING_EXCEEDS_CAPACITY(cs->len, cs->capacity))
- cstring_resize(cs, cs->len << 1);
+ CSTRING_FREE(cs);
+ cs->str = cstring_copy(s);
+ cs->len = strlen(s);
+ if (CSTRING_EXCEEDS_CAPACITY(cs->len, cs->capacity))
+ cstring_resize(cs, cs->len << 1);
#ifdef CSTRING_DBG
- CSTRING_DBG_LOG_STR_INFO(s, cs->len);
- CSTRING_DBG_LOG_CSTR_INFO(cs);
+ CSTRING_DBG_LOG_STR_INFO(s, cs->len);
+ CSTRING_DBG_LOG_CSTR_INFO(cs);
#endif /* CSTRING_DBG */
}
void
cstring_insert(cstring *cs, const char *s, size_t i)
{
- if (!CSTRING_OUT_OF_BOUNDS(cs, i) && s != NULL) {
- size_t slen = strlen(s);
- size_t newlen = cs->len + slen;
+ size_t slen, newlen;
char *tmp;
- CSTRING_MALLOC(tmp, newlen + 1);
- memcpy(tmp, cs->str, i);
- memcpy(tmp + i, s, slen);
- memcpy(tmp + i + slen, cs->str + i, newlen - slen - i + 1);
- CSTRING_FREE(cs);
- cs->len = newlen;
- cs->str = tmp;
- cs->str[cs->len] = '\0';
- if (CSTRING_EXCEEDS_CAPACITY(newlen, cs->capacity))
- cstring_resize(cs, newlen << 1);
+
+ if (!CSTRING_OUT_OF_BOUNDS(cs, i) && s != NULL) {
+ slen = strlen(s);
+ newlen = cs->len + slen;
+ CSTRING_MALLOC(tmp, newlen + 1);
+ memcpy(tmp, cs->str, i);
+ memcpy(tmp + i, s, slen);
+ memcpy(tmp + i + slen, cs->str + i, newlen - slen - i + 1);
+ CSTRING_FREE(cs);
+ cs->len = newlen;
+ cs->str = tmp;
+ cs->str[cs->len] = '\0';
+ if (CSTRING_EXCEEDS_CAPACITY(newlen, cs->capacity))
+ cstring_resize(cs, newlen << 1);
#ifdef CSTRING_DBG
- CSTRING_DBG_LOG_STR_INFO(s, slen);
- CSTRING_DBG_LOG_CSTR_INFO(cs);
+ CSTRING_DBG_LOG_STR_INFO(s, slen);
+ CSTRING_DBG_LOG_CSTR_INFO(cs);
#endif /* CSTRING_DBG */
- }
+ }
}
#ifdef CSTRING_DBG
// FIX IT
#define CSTRING_DBG_EXPECTED_ERASE_STR(cs, pos, len) do { \
- CSTRING_DBG_LOG("%s", "CSTRING_DBG_EXPECTED_ERASE_STR: "); \
- size_t _i; \
- for (_i = 0; _i < (pos); _i++) \
- printf("%c", cs->str[_i]); \
- for (_i = (pos) + (len); _i < cs->len; _i++) \
- printf("%c", cs->str[_i]); \
- printf("\n"); \
+ CSTRING_DBG_LOG("%s", "CSTRING_DBG_EXPECTED_ERASE_STR: "); \
+ size_t _i; \
+ for (_i = 0; _i < (pos); _i++) \
+ printf("%c", cs->str[_i]); \
+ for (_i = (pos) + (len); _i < cs->len; _i++) \
+ printf("%c", cs->str[_i]); \
+ printf("\n"); \
} while (0)
#define CSTRING_DBG_EXPECTED_ERASE_LEN(cs, len) \
- CSTRING_DBG_LOG("CSTRING_DBG_EXPECTED_ERASE_LEN: %ld\n", cs->len - len)
+ CSTRING_DBG_LOG("CSTRING_DBG_EXPECTED_ERASE_LEN: %ld\n", cs->len - len)
#endif /* CSTRING_DBG */
void
cstring_erase(cstring *cs, size_t pos, size_t len)
{
- if (!cstring_empty(cs)
- && (!CSTRING_OUT_OF_BOUNDS(cs, pos)
- || !CSTRING_OUT_OF_BOUNDS(cs, len)))
- {
+ size_t newlen;
+ char *tmp;
+
+ if (!cstring_empty(cs)
+ && (!CSTRING_OUT_OF_BOUNDS(cs, pos)
+ || !CSTRING_OUT_OF_BOUNDS(cs, len))) {
#ifdef CSTRING_DBG
- CSTRING_DBG_LOG("STR: %s | INDEX: %ld | LEN: %ld\n", cs->str, pos, len);
- CSTRING_DBG_EXPECTED_ERASE_STR(cs, pos, len);
- CSTRING_DBG_EXPECTED_ERASE_LEN(cs, len);
+ CSTRING_DBG_LOG("STR: %s | INDEX: %ld | LEN: %ld\n",
+ cs->str, pos, len);
+ CSTRING_DBG_EXPECTED_ERASE_STR(cs, pos, len);
+ CSTRING_DBG_EXPECTED_ERASE_LEN(cs, len);
#endif /* CSTRING_DBG */
- size_t newlen = cs->len - len;
- char *tmp;
- CSTRING_MALLOC(tmp, newlen + 1);
- memcpy(tmp, cs->str, pos);
- memcpy(tmp + pos, cs->str + pos + len, cs->len - pos - len);
- CSTRING_FREE(cs); /* Useless check but keep it for consistency */
- cs->len = newlen;
- cs->str = tmp;
- cs->str[cs->len] = '\0';
+ newlen = cs->len - len;
+ CSTRING_MALLOC(tmp, newlen + 1);
+ memcpy(tmp, cs->str, pos);
+ memcpy(tmp + pos, cs->str + pos + len, cs->len - pos - len);
+ CSTRING_FREE(cs); /* Useless check but keep it for consistency */
+ cs->len = newlen;
+ cs->str = tmp;
+ cs->str[cs->len] = '\0';
#ifdef CSTRING_DBG
- CSTRING_DBG_LOG_CSTR_INFO(cs);
+ CSTRING_DBG_LOG_CSTR_INFO(cs);
#endif /* CSTRING_DBG */
- }
+ }
}
void
cstring_erase_matching(cstring *cs, const char *s)
{
- if (s != NULL)
- cstring_erase(cs, cstring_find(cs, s), strlen(s));
+ if (s != NULL)
+ cstring_erase(cs, cstring_find(cs, s), strlen(s));
}
void
cstring_erase_all_matching(cstring *cs, const char *s)
{
- if (s != NULL) {
- size_t len = strlen(s);
- size_t i = cstring_find(cs, s);
- for (; i != CSTRING_NPOS; i = cstring_find(cs, s))
- cstring_erase(cs, i, len);
- }
+ size_t len, i;
+
+ if (s != NULL) {
+ len = strlen(s);
+ i = cstring_find(cs, s);
+ for (; i != CSTRING_NPOS; i = cstring_find(cs, s))
+ cstring_erase(cs, i, len);
+ }
}
void
cstring_trim(cstring *cs, const char *s)
{
- size_t i = cstring_find_first_of(cs, s);
- for (; i != CSTRING_NPOS; i = cstring_find_first_of(cs, s))
- cstring_erase(cs, i, 1);
+ size_t i;
+
+ i = cstring_find_first_of(cs, s);
+ for (; i != CSTRING_NPOS; i = cstring_find_first_of(cs, s))
+ cstring_erase(cs, i, 1);
}
#ifdef CSTRING_DBG
@@ -200,59 +210,58 @@ cstring_trim(cstring *cs, const char *s)
void
cstring_push_back(cstring *cs, char c)
{
- if (CSTRING_EXCEEDS_CAPACITY(cs->len, cs->capacity))
- cstring_resize(cs, cs->len << 1);
- cs->str[cs->len] = c;
- cs->str[++cs->len] = '\0';
+ if (CSTRING_EXCEEDS_CAPACITY(cs->len, cs->capacity))
+ cstring_resize(cs, cs->len << 1);
+ cs->str[cs->len] = c;
+ cs->str[++cs->len] = '\0';
#ifdef CSTRING_DBG
- CSTRING_DBG_LOG_CSTR_INFO(cs);
+ CSTRING_DBG_LOG_CSTR_INFO(cs);
#endif /* CSTRING_DBG */
}
void
cstring_pop_back(cstring *cs)
{
- if (cs->len > 0)
- cs->str[--cs->len] = '\0';
+ if (cs->len > 0)
+ cs->str[--cs->len] = '\0';
}
void
cstring_replace_char(cstring *cs, size_t i, char c)
{
- if (!CSTRING_OUT_OF_BOUNDS(cs, i))
- cs->str[i] = c;
+ if (!CSTRING_OUT_OF_BOUNDS(cs, i))
+ cs->str[i] = c;
}
void
cstring_replace_str(cstring *cs, const char *s, size_t pos, size_t olen)
{
- if (!CSTRING_OUT_OF_BOUNDS(cs, pos)
- && !CSTRING_OUT_OF_BOUNDS(cs, olen))
- {
- cstring_erase(cs, pos, olen);
- cstring_insert(cs, s, pos);
- }
+ if (!CSTRING_OUT_OF_BOUNDS(cs, pos)
+ && !CSTRING_OUT_OF_BOUNDS(cs, olen)) {
+ cstring_erase(cs, pos, olen);
+ cstring_insert(cs, s, pos);
+ }
}
cstring
cstring_substr(const cstring *cs, size_t pos, size_t len)
{
- if (CSTRING_OUT_OF_BOUNDS(cs, pos)
- || CSTRING_OUT_OF_BOUNDS(cs, len))
- return cstring_create("");
- cstring substr = cstring_create(&cs->str[pos]);
- substr.len = len;
- substr.str[len] = '\0';
- cstring_shrink_to_fit(&substr);
- return substr;
+ if (CSTRING_OUT_OF_BOUNDS(cs, pos)
+ || CSTRING_OUT_OF_BOUNDS(cs, len))
+ return cstring_create("");
+ cstring substr = cstring_create(&cs->str[pos]);
+ substr.len = len;
+ substr.str[len] = '\0';
+ cstring_shrink_to_fit(&substr);
+ return substr;
}
void
cstring_swap(cstring *lhs, cstring *rhs)
{
- cstring tmp = *lhs;
- *lhs = *rhs;
- *rhs = tmp;
+ cstring tmp = *lhs;
+ *lhs = *rhs;
+ *rhs = tmp;
}
void
@@ -262,16 +271,16 @@ cstring_sort_partial(cstring *cs,
enum cstring_sort_flags flags,
cstring_sort_callback callback)
{
- /* maybe chanage out of bounds macro */
- if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_REST) || pos + len > len)
- len -= pos;
-
- if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_ASCENDING))
- qsort(cs + pos, len, sizeof(cstring), cstring_cmp_greater);
- else if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_DESCENDING))
- qsort(cs + pos, len, sizeof(cstring), cstring_cmp_less);
- else if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_CALLBACK))
- qsort(cs + pos, len, sizeof(cstring), callback);
+ /* maybe chanage out of bounds macro */
+ if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_REST) || pos + len > len)
+ len -= pos;
+
+ if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_ASCENDING))
+ qsort(cs + pos, len, sizeof(cstring), cstring_cmp_greater);
+ else if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_DESCENDING))
+ qsort(cs + pos, len, sizeof(cstring), cstring_cmp_less);
+ else if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_CALLBACK))
+ qsort(cs + pos, len, sizeof(cstring), callback);
}
void
@@ -281,104 +290,109 @@ cstring_sort_chars_partial(cstring *cs,
enum cstring_sort_flags flags,
cstring_sort_callback callback)
{
- if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_REST)
- || CSTRING_OUT_OF_BOUNDS(cs, pos + len))
- len = cs->len - pos;
-
- if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_ASCENDING))
- qsort(cs->str + pos, len, sizeof(char), cstring_cmp_char_greater);
- else if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_DESCENDING))
- qsort(cs->str + pos, len, sizeof(char), cstring_cmp_char_less);
- else if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_CALLBACK))
- qsort(cs->str + pos, len, sizeof(char), callback);
+ if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_REST)
+ || CSTRING_OUT_OF_BOUNDS(cs, pos + len))
+ len = cs->len - pos;
+
+ if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_ASCENDING))
+ qsort(cs->str + pos, len, sizeof(char), cstring_cmp_char_greater);
+ else if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_DESCENDING))
+ qsort(cs->str + pos, len, sizeof(char), cstring_cmp_char_less);
+ else if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_CALLBACK))
+ qsort(cs->str + pos, len, sizeof(char), callback);
}
void
cstring_clear(cstring *cs)
{
- CSTRING_FREE(cs);
- CSTRING_MALLOC(cs->str, 1);
- cs->str[0] = '\0';
- cs->len = 0;
- cs->capacity = 0;
+ CSTRING_FREE(cs);
+ CSTRING_MALLOC(cs->str, 1);
+ cs->str[0] = '\0';
+ cs->len = 0;
+ cs->capacity = 0;
}
-#define CSTRING_CHECK(cs, s) \
- if (cstring_empty(cs) || !*(s)) \
- return CSTRING_NPOS
+#define CSTRING_CHECK(cs, s) \
+ if (cstring_empty(cs) || !*(s)) \
+ return CSTRING_NPOS
size_t
cstring_find(const cstring *cs, const char *s)
{
- CSTRING_CHECK(cs, s);
- CSTRING_FIND_OCCURENCE(cs, s, strstr);
- return CSTRING_NPOS;
+ CSTRING_CHECK(cs, s);
+ CSTRING_FIND_OCCURENCE(cs, s, strstr);
+ return CSTRING_NPOS;
}
+/*SIMPLIFY */
size_t
cstring_rfind(const cstring *cs, const char *s)
{
- CSTRING_CHECK(cs, s);
- /*SIMPLIFY */
- int found;
- size_t idx = -1;
- size_t slen = strlen(s);
- size_t i, j;
- for (i = 0; i <= cs->len - slen; i++) {
- found = 1;
- for (j = 0; j < slen; j++) {
- if (cs->str[i + j] != s[j]) {
- found = 0;
- break;
- }
+ size_t idx, slen, i, j;
+ int found;
+
+ CSTRING_CHECK(cs, s);
+ idx = -1;
+ slen = strlen(s);
+ for (i = 0; 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;
}
- if (found)
- idx = i;
- }
- return (idx == -1 ? CSTRING_NPOS : idx);
+ return (idx == -1 ? CSTRING_NPOS : idx);
}
size_t
cstring_find_first_of(const cstring *cs, const char *s)
{
- CSTRING_CHECK(cs, s);
- for (; *s; s++) {
- CSTRING_FIND_OCCURENCE(cs, *s, strchr);
- }
- return CSTRING_NPOS;
+ CSTRING_CHECK(cs, s);
+ for (; *s; s++) {
+ CSTRING_FIND_OCCURENCE(cs, *s, strchr);
+ }
+ return CSTRING_NPOS;
}
size_t
cstring_find_first_not_of(const cstring *cs, const char *s)
{
- CSTRING_CHECK(cs, s);
- size_t i = 0;
- for (; i < cs->len; i++)
- if (!cstring_is_one_of(cs->str[i], s))
- return i;
- return CSTRING_NPOS;
+ size_t i = 0;
+
+ CSTRING_CHECK(cs, s);
+ for (; i < cs->len; i++)
+ if (!cstring_is_one_of(cs->str[i], s))
+ return i;
+ return CSTRING_NPOS;
}
size_t
cstring_find_last_of(const cstring *cs, const char *s)
{
- CSTRING_CHECK(cs, s);
- size_t i = *(s + strlen(s));
- for (; i >= 0; i--) {
- CSTRING_FIND_OCCURENCE(cs, s[i], strrchr);
- }
- return CSTRING_NPOS;
+ size_t i;
+
+ CSTRING_CHECK(cs, s);
+ i = *(s + strlen(s));
+ for (; i >= 0; i--) {
+ CSTRING_FIND_OCCURENCE(cs, s[i], strrchr);
+ }
+ return CSTRING_NPOS;
}
size_t
cstring_find_last_not_of(const cstring *cs, const char *s)
{
- CSTRING_CHECK(cs, s);
- size_t i = cs->len;
- for (; i >= 0; i--)
- if (!cstring_is_one_of(cs->str[i], s))
- return i;
- return CSTRING_NPOS;
+ size_t i = cs->len;
+
+ CSTRING_CHECK(cs, s);
+ for (; i >= 0; i--)
+ if (!cstring_is_one_of(cs->str[i], s))
+ return i;
+ return CSTRING_NPOS;
}
#undef CSTR_CHECK
@@ -386,43 +400,47 @@ cstring_find_last_not_of(const cstring *cs, const char *s)
char *
cstring_copy(const char *s)
{
- size_t len = strlen(s);
- char *tmp;
- CSTRING_MALLOC(tmp, len + 1);
- memcpy(tmp, s, len + 1);
- tmp[len] = '\0'; /* Add \0 in case s didn't have it */
- return tmp;
+ size_t len;
+ char *tmp;
+
+ len = strlen(s);
+ CSTRING_MALLOC(tmp, len + 1);
+ memcpy(tmp, s, len + 1);
+ tmp[len] = '\0'; /* Add \0 in case s didn't have it */
+ return tmp;
}
void
cstring_resize(cstring *cs, size_t newcapacity)
{
+ char *tmp;
+
#ifdef CSTRING_DBG
- CSTRING_DBG_LOG("Old capacity: %ld | New capacity: %ld\n",
- cs->capacity, newcapacity);
+ CSTRING_DBG_LOG("Old capacity: %ld | New capacity: %ld\n",
+ cs->capacity, newcapacity);
#endif /* CSTRING_DBG */
- char *tmp;
- CSTRING_MALLOC(tmp, newcapacity + 1); /* no +1? */
- memcpy(tmp, cs->str, cs->len + 1); /* copy \0 too */
- CSTRING_FREE(cs);
- cs->str = tmp;
- cs->str[cs->len] = '\0';
- cs->capacity = newcapacity;
+ CSTRING_MALLOC(tmp, newcapacity + 1); /* no +1? */
+ memcpy(tmp, cs->str, cs->len + 1); /* copy \0 too */
+ CSTRING_FREE(cs);
+ cs->str = tmp;
+ cs->str[cs->len] = '\0';
+ cs->capacity = newcapacity;
#ifdef CSTRING_DBG
- CSTRING_DBG_LOG_CSTR_INFO(cs);
+ CSTRING_DBG_LOG_CSTR_INFO(cs);
#endif /* CSTRING_DBG */
}
cstring *
cstring_getline(FILE *fd, cstring *cs, char delim)
{
- char c;
- cstring_clear(cs);
- while ((c = fgetc(fd)) != EOF && c != '\n') {
- if (c == delim)
- break;
- else
- cstring_push_back(cs, c);
- }
- return (c == EOF) ? NULL : cs;
+ char c;
+
+ cstring_clear(cs);
+ while ((c = fgetc(fd)) != EOF && c != '\n') {
+ if (c == delim)
+ break;
+ else
+ cstring_push_back(cs, c);
+ }
+ return (c == EOF) ? NULL : cs;
}
diff --git a/cstring.h b/cstring.h
@@ -1,3 +1,5 @@
+/* See LICENSE file for copyright and license details. */
+
#ifndef CSTRING_H
#define CSTRING_H
@@ -15,40 +17,40 @@ extern "C" {
#define CSTRING_ARR_LEN(arr) ((size_t)sizeof((arr)) / sizeof((arr)[0]))
#define CSTRING_FLAG_CHECK(flag, bit) (((flag) & (int)(bit)) == (int)(bit))
-#define CSTRING_MALLOC(ptr, size) do { \
- ptr = (char *)malloc((size)); \
- if (ptr == NULL) \
- fputs("CSTRING_MALLOC(): cannot allocate memory\n", stderr); \
+#define CSTRING_MALLOC(ptr, size) do { \
+ ptr = (char *)malloc((size)); \
+ if (ptr == NULL) \
+ fputs("CSTRING_MALLOC(): cannot allocate memory\n", stderr); \
} while (0)
#ifdef CSTRING_DBG
-#define CSTRING_DBG_LOG(fmt, ...) \
- fprintf(stderr, "DEBUG: %s:%d:%s(): " fmt, \
- __FILE__, __LINE__, __func__, __VA_ARGS__)
+#define CSTRING_DBG_LOG(fmt, ...) \
+ fprintf(stderr, "DEBUG: %s:%d:%s(): " fmt, \
+ __FILE__, __LINE__, __func__, __VA_ARGS__)
-#define CSTRING_DBG_LOG_CSTR_INFO(cs) \
- CSTRING_DBG_LOG("STR: %s | LEN: %ld | CAP: %ld\n", \
- cs->str, cs->len, cs->capacity)
+#define CSTRING_DBG_LOG_CSTR_INFO(cs) \
+ CSTRING_DBG_LOG("STR: %s | LEN: %ld | CAP: %ld\n", \
+ cs->str, cs->len, cs->capacity)
-#define CSTRING_DBG_LOG_CSTR_INFO_NPTR(cs) \
- CSTRING_DBG_LOG("STR: %s | LEN: %ld | CAP: %ld\n", \
- cs.str, cs.len, cs.capacity)
+#define CSTRING_DBG_LOG_CSTR_INFO_NPTR(cs) \
+ CSTRING_DBG_LOG("STR: %s | LEN: %ld | CAP: %ld\n", \
+ cs.str, cs.len, cs.capacity)
-#define CSTRING_DBG_LOG_STR_INFO(s, len) \
- CSTRING_DBG_LOG("S: %s | LEN: %ld\n", (s), (len))
+#define CSTRING_DBG_LOG_STR_INFO(s, len) \
+ CSTRING_DBG_LOG("S: %s | LEN: %ld\n", (s), (len))
#endif /* CSTRING_DBG */
struct cstring {
- char *str;
- size_t len;
- size_t capacity;
+ char *str;
+ size_t len;
+ size_t capacity;
};
enum cstring_sort_flags {
- CSTRING_SORT_ASCENDING = 1 << 0,
- CSTRING_SORT_DESCENDING = 1 << 1,
- CSTRING_SORT_CALLBACK = 1 << 2,
- CSTRING_SORT_REST = 1 << 3
+ CSTRING_SORT_ASCENDING = 1 << 0,
+ CSTRING_SORT_DESCENDING = 1 << 1,
+ CSTRING_SORT_CALLBACK = 1 << 2,
+ CSTRING_SORT_REST = 1 << 3
};
typedef struct cstring cstring;
@@ -111,13 +113,13 @@ static inline int cstring_less_or_equal(const cstring *, const cstring *);
static inline void
cstring_prepend(cstring *cs, const char *s)
{
- cstring_insert(cs, s, 0);
+ cstring_insert(cs, s, 0);
}
static inline void
cstring_append(cstring *cs, const char *s)
{
- cstring_insert(cs, s, cs->len);
+ cstring_insert(cs, s, cs->len);
}
static inline void
@@ -126,7 +128,7 @@ cstring_sort(cstring *cs,
enum cstring_sort_flags flags,
cstring_sort_callback callback)
{
- cstring_sort_partial(cs, 0, len, flags, callback);
+ cstring_sort_partial(cs, 0, len, flags, callback);
}
static inline void
@@ -134,91 +136,91 @@ cstring_sort_chars(cstring *cs,
enum cstring_sort_flags flags,
cstring_sort_callback callback)
{
- cstring_sort_chars_partial(cs, 0, cs->len, flags, callback);
+ cstring_sort_chars_partial(cs, 0, cs->len, flags, callback);
}
static inline void
cstring_shrink_to_fit(cstring *cs)
{
- cstring_resize(cs, cs->len);
+ cstring_resize(cs, cs->len);
}
static inline int
cstring_empty(const cstring *cs)
{
- return (cs->str == NULL && cs->len == 0);
+ return (cs->str == NULL && cs->len == 0);
}
static inline char
cstring_front(const cstring *cs)
{
- return cs->str[0];
+ return cs->str[0];
}
static inline char
cstring_back(const cstring *cs)
{
- return (!cstring_empty(cs) ? cs->str[cs->len - 1] : cs->str[0]);
+ 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);
+ 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));
+ 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);
+ return (cs->str[0] == c);
}
static inline int
cstring_ends_with_char(const cstring *cs, char c)
{
- return (cs->str[cs->len] = c);
+ return (cs->str[cs->len] = c);
}
static inline void *
cstring_data(const cstring *cs)
{
- return (void *)cs->str;
+ return (void *)cs->str;
}
static inline int
cstring_equal(const cstring *lhs, const cstring *rhs)
{
- return (strcmp(lhs->str, rhs->str) == 0);
+ 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);
+ 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);
+ 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);
+ 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);
+ return (strcmp(lhs->str, rhs->str) <= 0);
}
#ifdef __cplusplus
diff --git a/tests/Makefile b/tests/Makefile
@@ -6,33 +6,33 @@ LDFLAGS = -Llib -lcstring
all: options ${BINS}
options:
- @echo "build options:"
- @echo "CFLAGS = ${CFLAGS}"
- @echo "LDFLAGS = ${LDFLAGS}"
- @echo "CC = ${CC}"
+ @echo "build options:"
+ @echo "CFLAGS = ${CFLAGS}"
+ @echo "LDFLAGS = ${LDFLAGS}"
+ @echo "CC = ${CC}"
run:
- @echo "---------------------------"
- @echo "---------------------------"
- @echo "RUNNING: test_basic"
- @echo "---------------------------"
- @echo "---------------------------"
- ./test_basic
-
- @echo "---------------------------"
- @echo "---------------------------"
- @echo "RUNNING: test_insert"
- @echo "---------------------------"
- @echo "---------------------------"
- ./test_insert
+ @echo "---------------------------"
+ @echo "---------------------------"
+ @echo "RUNNING: test_basic"
+ @echo "---------------------------"
+ @echo "---------------------------"
+ ./test_basic
+
+ @echo "---------------------------"
+ @echo "---------------------------"
+ @echo "RUNNING: test_insert"
+ @echo "---------------------------"
+ @echo "---------------------------"
+ ./test_insert
clean:
- rm -f ${BINS} *.o
+ rm -f ${BINS} *.o
test_basic: test_basic.c
- ${CC} test_basic.c ${CFLAGS} -o test_basic ${LDFLAGS}
+ ${CC} test_basic.c ${CFLAGS} -o test_basic ${LDFLAGS}
test_insert: test_insert.c
- ${CC} test_insert.c ${CFLAGS} -o test_insert ${LDFLAGS}
+ ${CC} test_insert.c ${CFLAGS} -o test_insert ${LDFLAGS}
.PHONY: all options run clean
diff --git a/tests/test_basic.c b/tests/test_basic.c
@@ -1,61 +1,61 @@
-#include "cstring.h"
+#include <cstring.h>
// Compilation: gcc test_basic.c -lcstring
int
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 s = cstring_create("Hello world");
+ printf("cstring_create: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
- cstring_sort_chars(&s, CSTRING_SORT_ASCENDING, NULL);
- printf("cstring_sort_chars: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
+ cstring_sort_chars(&s, CSTRING_SORT_ASCENDING, NULL);
+ printf("cstring_sort_chars: %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_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_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_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);
+ cstring_push_back(&s, 'c');
+ printf("cstring_push_back: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
- cstring_insert(&s, "Inserted text", 4);
- printf("cstring_insert: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
-
- cstring_pop_back(&s);
- printf("cstring_pop_back: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
+ cstring_insert(&s, "Inserted text", 4);
+ printf("cstring_insert: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
+
+ cstring_pop_back(&s);
+ printf("cstring_pop_back: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
- cstring_clear(&s);
- printf("cstring_clear: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
+ cstring_clear(&s);
+ printf("cstring_clear: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
- cstring_assign(&s, "CSTRING");
- printf("cstring_assign: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
- printf("cstring_front: %c\n", cstring_front(&s));
- printf("cstring_back: %c\n", cstring_back(&s));
+ cstring_assign(&s, "CSTRING");
+ printf("cstring_assign: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
+ printf("cstring_front: %c\n", cstring_front(&s));
+ printf("cstring_back: %c\n", cstring_back(&s));
- cstring_replace_char(&s, 3, 'x');
- printf("cstring_replace_char: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
+ cstring_replace_char(&s, 3, 'x');
+ printf("cstring_replace_char: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
- cstring_replace_str(&s, "hell", 0, strlen("hell"));
- printf("cstring_replace_str: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
+ cstring_replace_str(&s, "hell", 0, strlen("hell"));
+ printf("cstring_replace_str: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
- cstring_erase(&s, 1, 4);
- printf("cstring_erase: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
+ cstring_erase(&s, 1, 4);
+ printf("cstring_erase: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
- cstring_assign(&s, "hello aaaa hello abbb helo hello");
- cstring_erase_all_matching(&s, "hello");
- printf("cstring_erase_all_matching: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
+ cstring_assign(&s, "hello aaaa hello abbb helo hello");
+ cstring_erase_all_matching(&s, "hello");
+ printf("cstring_erase_all_matching: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
- cstring_trim(&s, " ");
- printf("cstring_trim: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
+ cstring_trim(&s, " ");
+ printf("cstring_trim: %s (Len: %ld, Capacity: %ld)\n", s.str, s.len, s.capacity);
- cstring_delete(&s);
- if (cstring_empty(&s))
- puts("cstring_delete: Deleted string.");
+ cstring_delete(&s);
+ if (cstring_empty(&s))
+ puts("cstring_delete: Deleted string.");
- return 0;
+ return 0;
}
diff --git a/tests/test_insert.c b/tests/test_insert.c
@@ -1,11 +1,12 @@
-#include <stdio.h>
#include <cstring.h>
+// Compilation: gcc test_insert.c -lcstring
+
int
main(int argc, char **argv)
{
- cstring s = cstring_create("HHHHHHEEEEEEEEEEEEEEEEEEEEEYYYYYYYYYYYYYY");
- printf("%s\n", s.str);
- cstring_delete(&s);
- return 0;
+ cstring s = cstring_create("HHHHHHEEEEEEEEEEEEEEEEEEEEEYYYYYYYYYYYYYY");
+ printf("%s\n", s.str);
+ cstring_delete(&s);
+ return 0;
}