cstring

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

commit 276def19cd965d9881e633906d2eec73dcb41d3e
parent bfce9e85b2603b71e57ee3c78ee942355385410f
Author: Christos Margiolis <christos@margiolis.net>
Date:   Tue, 10 Nov 2020 13:48:39 +0200

removed enum and organized flags as defines; fixed sort_chars cmp functions

Diffstat:
MMakefile | 2+-
Mconfig.mk | 5-----
Mcstring.3 | 45+++++++++++++++++++--------------------------
Mcstring.c | 61++++++++++++++++++++++++++-----------------------------------
Mcstring.h | 51++++++++++++++++++---------------------------------
5 files changed, 64 insertions(+), 100 deletions(-)

diff --git a/Makefile b/Makefile @@ -26,7 +26,7 @@ ${LIB}: ${OBJ} ${AR} ${ARFLAGS} lib${LIB}.a ${OBJ} .${EXT}.o: - ${CC} ${CFLAGS} -c $< + ${CC} -c ${CFLAGS} $< dist: clean ${MKDIR} ${DIST} diff --git a/config.mk b/config.mk @@ -4,9 +4,6 @@ VERSION = 0.1 # paths PREFIX = /usr/local -#MAN_DIR = ${PREFIX}/man/man1 -BIN_DIR = ${PREFIX}/bin -# uncomment if you're making a library MAN_DIR = ${PREFIX}/man/man3 INC_DIR = ${PREFIX}/include LIB_DIR = ${PREFIX}/lib @@ -21,7 +18,6 @@ CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L \ CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations \ -O3 ${INCS} ${CPPFLAGS} LDFLAGS = ${LIBS} -# uncomment if you're making a library ARFLAGS = rs # utils @@ -36,5 +32,4 @@ GZIP = gzip # compiler CC = gcc -# uncomment if you're making a library AR = ar diff --git a/cstring.3 b/cstring.3 @@ -23,26 +23,24 @@ In case you want to run the program in debug mode, compile it with the .Ar \-DCSTRING_DBG option. -.Sh STRUCTURES AND ENUMS +.Sh STRUCTURES .Bl -tag -width Ds -.It cstring -struct cstring { - size_t len; /* string length */ - size_t capacity; /* string capacity */ - char *str; /* contents of string */ +typedef struct _cstring { + size_t len; /* string length */ + size_t capacity; /* string capacity */ + char *str; /* contents of string */ + +CSTRING_SORT_ASCENDING 0x01 /* sort in ascending order */ +.br +CSTRING_SORT_DESCENDING 0x02 /* sort in descending order */ .br -}; -.It cstring_sort_flags -enum cstring_sort_flags { - CSTRING_SORT_ASCENDING = 1 << 0, /* sort in ascending order */ - CSTRING_SORT_DESCENDING = 1 << 1, /* sort in descending order */ - CSTRING_SORT_CALLBACK = 1 << 2, /* use your own sort function */ - CSTRING_SORT_REST = 1 << 3 /* sort the rest of the array */ +CSTRING_SORT_CALLBACK 0x04 /* sort using a callback function */ .br -}; +CSTRING_SORT_REST 0x10 /* sort the rest of the array */ +.br +} cstring; .Sh TYPEDEFS .Bl -tag -width Ds -.It typedef\ struct\ cstring\ cstring; Short typedef for the cstring structure. .It typedef\ int\ (*cstring_sort_callback)(const void *, const void *); Used in sort functions. @@ -102,7 +100,7 @@ Extract a substring from current string. .It void Fn cstring_swap "cstring *lhs" "cstring *rhs" Swap contents of two strings. -.It void Fn cstring_sort "cstring *cs" "size_t len" "enum cstring_sort_flags flags" "cstring_sort_callback callback" +.It void Fn cstring_sort "cstring *cs" "size_t len" "int flags" "cstring_sort_callback callback" Sort an array of cstrings. If you want to use the builtin comparison pass .Ar NULL in the last argument. In case you want to use your own callback use the @@ -110,12 +108,12 @@ in the last argument. In case you want to use your own callback use the flag and pass your own callback function in the last argument. You can also combine flags using the bitwise OR operator. -.It void Fn cstring_sort_partial "cstring *cs" "size_t pos" "size_t len" "enum cstring_sort_flags flags" "cstring_sort_callback callback" +.It void Fn cstring_sort_partial "cstring *cs" "size_t pos" "size_t len" "int flags" "cstring_sort_callback callback" Like .Fn cstring_sort but for specified part of an array. -.It void Fn cstring_sort_chars "cstring *cs" "enum cstring_sort_flags flags" "cstring_sort_callback callback" +.It void Fn cstring_sort_chars "cstring *cs" "int flags" "cstring_sort_callback callback" Sort a cstring's contents. If you want to use the builtin comparison pass .Ar NULL in the last argument. In case you want to use your own callback use the @@ -123,7 +121,7 @@ in the last argument. In case you want to use your own callback use the flag and pass your own callback function in the last argument. You can also combine flags using the bitwise OR operator. -.It void Fn cstring_sort_chars_partial "cstring *cs" "size_t pos" "size_t len" "enum cstring_sort_flags flags" "cstring_sort_callback callback" +.It void Fn cstring_sort_chars_partial "cstring *cs" "size_t pos" "size_t len" "int flags" "cstring_sort_callback callback" Like .Fn cstring_sort_chars but for specified part of string. @@ -214,20 +212,15 @@ Check if lhs <= rhs .Sh MACROS .Bl -tag -width Ds -.It Fn CSTRING_OUT_OF_BOUNDS "cs" "pos" +.It Fn CSTRING_OUT_OF_BOUNDS "len" "pos" Check if .Ar pos -is out of bounds. +is out of bounds (pos > len). .It Fn CSTRING_ARR_LEN "arr" Determine an array's length. The macro must be called in the same function the array is declared. -.It Fn CSTRING_FLAG_CHECK "flag" "bit" -Check if a flag is on. This macro is used for checking -.Ar cstring_sort_flags -in the implementation, but it can be used everywhere. - .It Fn CSTRING_MALLOC "ptr" "size" Allocate memory with error cheking. diff --git a/cstring.c b/cstring.c @@ -1,5 +1,4 @@ /* See LICENSE file for copyright and license details. */ - #include "cstring.h" #define CSTRING_EXCEEDS_CAPACITY(len, cap) ((len) >= (cap)) @@ -54,13 +53,13 @@ cstring_cmp_less(const void *lhs, const void *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 */ @@ -107,7 +106,7 @@ cstring_insert(cstring *cs, const char *s, size_t i) size_t slen, newlen; char *tmp; - if (!CSTRING_OUT_OF_BOUNDS(cs, i) && s != NULL) { + if (!CSTRING_OUT_OF_BOUNDS(cs->len, i) && s != NULL) { slen = strlen(s); newlen = cs->len + slen; CSTRING_MALLOC(tmp, newlen + 1); @@ -150,8 +149,8 @@ cstring_erase(cstring *cs, size_t pos, size_t len) char *tmp; if (!cstring_empty(cs) - && (!CSTRING_OUT_OF_BOUNDS(cs, pos) - || !CSTRING_OUT_OF_BOUNDS(cs, len))) { + && (!CSTRING_OUT_OF_BOUNDS(cs->len, pos) + || !CSTRING_OUT_OF_BOUNDS(cs->len, len))) { #ifdef CSTRING_DBG CSTRING_DBG_LOG("STR: %s | INDEX: %ld | LEN: %ld\n", cs->str, pos, len); @@ -229,15 +228,15 @@ cstring_pop_back(cstring *cs) void cstring_replace_char(cstring *cs, size_t i, char c) { - if (!CSTRING_OUT_OF_BOUNDS(cs, i)) + if (!CSTRING_OUT_OF_BOUNDS(cs->len, 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)) { + if (!CSTRING_OUT_OF_BOUNDS(cs->len, pos) + && !CSTRING_OUT_OF_BOUNDS(cs->len, olen)) { cstring_erase(cs, pos, olen); cstring_insert(cs, s, pos); } @@ -246,8 +245,8 @@ cstring_replace_str(cstring *cs, const char *s, size_t pos, size_t olen) 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)) + if (CSTRING_OUT_OF_BOUNDS(cs->len, pos) + || CSTRING_OUT_OF_BOUNDS(cs->len, len)) return cstring_create(""); cstring substr = cstring_create(&cs->str[pos]); substr.len = len; @@ -265,41 +264,33 @@ cstring_swap(cstring *lhs, cstring *rhs) } void -cstring_sort_partial(cstring *cs, - size_t pos, - size_t len, - 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) +cstring_sort_partial(cstring *cs, size_t pos, size_t len, int flags, + cstring_sort_callback cb) +{ + if (flags & CSTRING_SORT_REST || CSTRING_OUT_OF_BOUNDS(len, pos + len)) len -= pos; - if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_ASCENDING)) + if (flags & CSTRING_SORT_ASCENDING) qsort(cs + pos, len, sizeof(cstring), cstring_cmp_greater); - else if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_DESCENDING)) + else if (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); + else if (flags & CSTRING_SORT_CALLBACK) + qsort(cs + pos, len, sizeof(cstring), cb); } void -cstring_sort_chars_partial(cstring *cs, - size_t pos, - size_t len, - enum cstring_sort_flags flags, - cstring_sort_callback callback) -{ - if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_REST) - || CSTRING_OUT_OF_BOUNDS(cs, pos + len)) +cstring_sort_chars_partial(cstring *cs, size_t pos, size_t len, int flags, + cstring_sort_callback cb) +{ + if (flags & CSTRING_SORT_REST || CSTRING_OUT_OF_BOUNDS(cs->len, pos + len)) len = cs->len - pos; - if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_ASCENDING)) + if (flags & CSTRING_SORT_ASCENDING) qsort(cs->str + pos, len, sizeof(char), cstring_cmp_char_greater); - else if (CSTRING_FLAG_CHECK(flags, CSTRING_SORT_DESCENDING)) + else if (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); + else if (flags & CSTRING_SORT_CALLBACK) + qsort(cs->str + pos, len, sizeof(char), cb); } void diff --git a/cstring.h b/cstring.h @@ -1,5 +1,4 @@ /* See LICENSE file for copyright and license details. */ - #ifndef CSTRING_H #define CSTRING_H @@ -13,9 +12,8 @@ extern "C" { #define CSTRING_NPOS -1 #define CSTRING_INIT_EMPTY "" -#define CSTRING_OUT_OF_BOUNDS(cs, val) ((val) > cs->len) +#define CSTRING_OUT_OF_BOUNDS(len, pos) ((pos) > (len)) #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 = malloc((size)); \ @@ -40,20 +38,17 @@ extern "C" { CSTRING_DBG_LOG("S: %s | LEN: %ld\n", (s), (len)) #endif /* CSTRING_DBG */ -struct cstring { - size_t len; - size_t capacity; - char *str; -}; +typedef struct _cstring { + size_t len; /* strlen of str */ + size_t capacity; /* total capacity of the array */ + char *str; /* the string */ -enum cstring_sort_flags { - CSTRING_SORT_ASCENDING = 1 << 0, - CSTRING_SORT_DESCENDING = 1 << 1, - CSTRING_SORT_CALLBACK = 1 << 2, - CSTRING_SORT_REST = 1 << 3 -}; +#define CSTRING_SORT_ASCENDING 0x01 /* sort in ascending order */ +#define CSTRING_SORT_DESCENDING 0x02 /* sort in descending order */ +#define CSTRING_SORT_CALLBACK 0x04 /* sort using a callback function */ +#define CSTRING_SORT_REST 0x10 /* sort the rest of the array */ +} cstring; -typedef struct cstring cstring; typedef int (*cstring_sort_callback)(const void *, const void *); extern cstring cstring_create(const char *); @@ -70,11 +65,9 @@ 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_partial(cstring *, size_t, size_t, - enum cstring_sort_flags, +extern void cstring_sort_partial(cstring *, size_t, size_t, int, cstring_sort_callback); -extern void cstring_sort_chars_partial(cstring *cs, size_t, size_t, - enum cstring_sort_flags, +extern void cstring_sort_chars_partial(cstring *cs, size_t, size_t, int, cstring_sort_callback); extern void cstring_clear(cstring *); extern size_t cstring_find(const cstring *, const char *); @@ -88,14 +81,11 @@ 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_sort(cstring *, size_t, enum cstring_sort_flags, - cstring_sort_callback); -static inline void cstring_sort_chars(cstring *, enum cstring_sort_flags, - cstring_sort_callback); +static inline void cstring_sort(cstring *, size_t, int, cstring_sort_callback); +static inline void cstring_sort_chars(cstring *, int, cstring_sort_callback); static inline void cstring_shrink_to_fit(cstring *); static inline int cstring_empty(const cstring *); static inline char cstring_front(const cstring *); @@ -123,20 +113,15 @@ cstring_append(cstring *cs, const char *s) } static inline void -cstring_sort(cstring *cs, - size_t len, - enum cstring_sort_flags flags, - cstring_sort_callback callback) +cstring_sort(cstring *cs, size_t len, int flags, cstring_sort_callback cb) { - cstring_sort_partial(cs, 0, len, flags, callback); + cstring_sort_partial(cs, 0, len, flags, cb); } static inline void -cstring_sort_chars(cstring *cs, - enum cstring_sort_flags flags, - cstring_sort_callback callback) +cstring_sort_chars(cstring *cs, int flags, cstring_sort_callback cb) { - cstring_sort_chars_partial(cs, 0, cs->len, flags, callback); + cstring_sort_chars_partial(cs, 0, cs->len, flags, cb); } static inline void