cstring

Lightweight string library for C
git clone git://git.christosmarg.xyz/cstring.git
Log | Files | Refs | README | LICENSE

commit 84348c13c16f391e9f9595d7c786e6de05ce8f08
parent d2a6d689d0f34b7ccc60a1ac7515212a345a2a4a
Author: Christos Margiolis <christos@margiolis.net>
Date:   Mon, 12 Oct 2020 03:09:28 +0300

added data function, added static inline declarations, still pending erase fix

Diffstat:
Mcstring.3 | 3+++
Mcstring.c | 84++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Mcstring.h | 89++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Mtests/test.c | 3++-
4 files changed, 112 insertions(+), 67 deletions(-)

diff --git a/cstring.3 b/cstring.3 @@ -154,6 +154,9 @@ Check to see if string starts with Check to see if string ends with .I c .TP +.BR void\ *cstring_data(const\ cstring\ *cs) +Get raw bytes of string's content. +.TP .BR char\ *cstring_copy(const\ char\ *s) Make a copy of a given .I const\ char\ * diff --git a/cstring.c b/cstring.c @@ -2,39 +2,32 @@ #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) - -/* Might move above erase functions */ -#define CSTRING_EXPECTED_ERASE_STR(cs, pos, len) do { \ - CSTRING_DBG_LOG("%s", "CSTRING_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_EXPECTED_ERASE_LEN(cs, len) \ - CSTRING_DBG_LOG("CSTRING_EXPECTED_ERASE_LEN: %ld\n", cs->len - len) -#else -#define CSTRING_FREE(cs) do { \ - if (!cstring_empty(cs)) \ - free(cs->str); \ +#else /* !CSTRING_DBG */ +#define CSTRING_FREE(cs) do { \ + if (!cstring_empty(cs)) \ + free(cs->str); \ } while (0) #endif /* CSTRING_DBG */ +/* statics */ +static int cstring_is_one_of(char, const char *); +static inline int cstring_cmp_greater(const void *, const void *); +static inline int cstring_cmp_less(const void *, const void *); +static inline int cstring_cmp_char_greater(const void *, const void *); +static inline int cstring_cmp_char_less(const void *, const void *); + static int cstring_is_one_of(char c, const char *s) { @@ -68,6 +61,7 @@ cstring_cmp_char_less(const void *lhs, const void *rhs) return (*(char *)lhs < *(char *)rhs); } +/* externs */ cstring cstring_create(const char *s) { @@ -129,6 +123,21 @@ cstring_insert(cstring *cs, const char *s, size_t i) } } +#ifdef CSTRING_DBG +#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"); \ +} while (0) + +#define CSTRING_DBG_EXPECTED_ERASE_LEN(cs, 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) { @@ -138,8 +147,8 @@ cstring_erase(cstring *cs, size_t pos, size_t len) { #ifdef CSTRING_DBG CSTRING_DBG_LOG("STR: %s | INDEX: %ld | LEN: %ld\n", cs->str, pos, len); - CSTRING_EXPECTED_ERASE_STR(cs, pos, len); - CSTRING_EXPECTED_ERASE_LEN(cs, 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; @@ -182,6 +191,11 @@ cstring_trim(cstring *cs, const char *s) cstring_erase(cs, i, 1); } +#ifdef CSTRING_DBG +#undef CSTRING_DBG_EXPECTED_ERASE_STR +#undef CSTRING_DBG_EXPECTED_ERASE_LEN +#endif /* CSTRING_DBG */ + void cstring_push_back(cstring *cs, char c) { @@ -308,7 +322,8 @@ cstring_rfind(const cstring *cs, const char *s) break; } } - if (found) idx = i; + if (found) + idx = i; } return (idx == -1 ? CSTRING_NPOS : idx); } @@ -377,10 +392,11 @@ cstring_resize(cstring *cs, size_t newcapacity) cs->capacity, newcapacity); #endif /* CSTRING_DBG */ char *tmp; - CSTRING_MALLOC(tmp, newcapacity); - memcpy(tmp, cs->str, cs->len + 1); /* copy \0 too */ + 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); @@ -393,8 +409,10 @@ 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); + if (c == delim) + break; + else + cstring_push_back(cs, c); } return (c == EOF) ? NULL : cs; } diff --git a/cstring.h b/cstring.h @@ -36,9 +36,9 @@ extern "C" { #endif /* CSTRING_DBG */ typedef struct cstring { - char *str; - size_t len; - size_t capacity; + char *str; + size_t len; + size_t capacity; } cstring; enum cstring_flags { @@ -47,36 +47,53 @@ enum cstring_flags { CSTRING_CALLBACK }; -extern cstring cstring_create(const char *); -extern void cstring_delete(cstring *); -extern void cstring_assign(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 *); -extern void cstring_erase_all_matching(cstring *, const char *); -extern void cstring_trim(cstring *, const char *); -extern void cstring_push_back(cstring *, char); -extern void cstring_pop_back(cstring *); -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_sort(cstring **, size_t, enum cstring_flags, - int (*)(const void *, const void *)); -extern void cstring_sort_chars(cstring *cs, enum cstring_flags, - int (*)(const void *, const void *)); -extern void cstring_clear(cstring *); -extern size_t cstring_find(const cstring *, const char *); -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_copy(const char *); -extern void cstring_resize(cstring *, size_t); -extern cstring *cstring_getline(FILE *, cstring *, char); - -/* inlines */ +extern cstring cstring_create(const char *); +extern void cstring_delete(cstring *); +extern void cstring_assign(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 *); +extern void cstring_erase_all_matching(cstring *, const char *); +extern void cstring_trim(cstring *, const char *); +extern void cstring_push_back(cstring *, char); +extern void cstring_pop_back(cstring *); +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_sort(cstring **, size_t, enum cstring_flags, + int (*)(const void *, const void *)); +extern void cstring_sort_chars(cstring *cs, enum cstring_flags, + int (*)(const void *, const void *)); +extern void cstring_clear(cstring *); +extern size_t cstring_find(const cstring *, const char *); +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_copy(const char *); +extern void cstring_resize(cstring *, size_t); +extern cstring *cstring_getline(FILE *, cstring *, char); + +/* static inlines */ +static inline void cstring_prepend(cstring *, const char *); +static inline void cstring_append(cstring *, const char *); +static inline void cstring_shrink_to_fit(cstring *); +static inline int cstring_empty(const cstring *); +static inline char cstring_front(const cstring *); +static inline char cstring_back(const cstring *); +static inline int cstring_starts_with_str(const cstring *, const char *); +static inline int cstring_ends_with_str(const cstring *, const char *); +static inline int cstring_starts_with_char(const cstring *, char); +static inline int cstring_ends_with_char(const cstring *, char); +static inline void *cstring_data(const cstring *); +static inline int cstring_equal(const cstring *, const cstring *); +static inline int cstring_greater(const cstring *, const cstring *); +static inline int cstring_greater_or_equal(const cstring *, const cstring *); +static inline int cstring_less(const cstring *, const cstring *); +static inline int cstring_less_or_equal(const cstring *, const cstring *); + static inline void cstring_prepend(cstring *cs, const char *s) { @@ -137,6 +154,12 @@ cstring_ends_with_char(const cstring *cs, char c) return (cs->str[cs->len] = c); } +static inline void * +cstring_data(const cstring *cs) +{ + return (void *)cs->str; +} + static inline int cstring_equal(const cstring *lhs, const cstring *rhs) { diff --git a/tests/test.c b/tests/test.c @@ -53,7 +53,8 @@ main(int argc, char **argv) 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."); + if (cstring_empty(&s)) + puts("cstring_delete: Deleted string."); return 0; }