cstring

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

commit fb54a79b85158d77c21d18220c33226aaa78f48d
parent b54a14818959358d44bfe8d68643017f0243c702
Author: Christos Margiolis <christos@margiolis.net>
Date:   Wed, 28 Apr 2021 17:46:23 +0300

changes in README and minor stylistic changes

Diffstat:
MLICENSE | 41++++++++++++++++-------------------------
MMakefile | 15+++++++--------
AREADME | 134+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DREADME.md | 139-------------------------------------------------------------------------------
Mconfig.mk | 9++++-----
Mcstring.3 | 14+++++++-------
Mcstring.c | 464++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mcstring.h | 141+++++++++++++++++++++++++++++++++++++++----------------------------------------
Mtests/Makefile | 6+++---
Mtests/test_basic.c | 76++++++++++++++++++++++++++++++++++++++--------------------------------------
Mtests/test_insert.c | 8++++----
11 files changed, 515 insertions(+), 532 deletions(-)

diff --git a/LICENSE b/LICENSE @@ -1,29 +1,20 @@ -BSD 3-Clause License +MIT License -Copyright (c) 2020-present, Christos Margiolis. -All rights reserved. +(c) 2020-Present Christos Margiolis <christos@christosmarg.xyz> -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the “Software”), to deal in +the Software without restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of images.weserv.nl nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Makefile b/Makefile @@ -8,24 +8,23 @@ LIB = cstring DIST = ${LIB}-${VERSION} MAN3 = ${LIB}.3 -EXT = c SRC = cstring.c -OBJ = ${SRC:.${EXT}=.o} +OBJ = ${SRC:.c=.o} all: options ${LIB} options: @echo ${LIB} build options: - @echo "CFLAGS = ${CFLAGS}" - @echo "LDFLAGS = ${LDFLAGS}" - @echo "ARFLAGS = ${ARFLAGS}" - @echo "CC = ${CC}" - @echo "AR = ${AR}" + @echo "CFLAGS = ${CFLAGS}" + @echo "LDFLAGS = ${LDFLAGS}" + @echo "ARFLAGS = ${ARFLAGS}" + @echo "CC = ${CC}" + @echo "AR = ${AR}" ${LIB}: ${OBJ} ${AR} ${ARFLAGS} lib${LIB}.a ${OBJ} -.${EXT}.o: +.c.o: ${CC} -c ${CFLAGS} $< dist: clean diff --git a/README b/README @@ -0,0 +1,134 @@ +cstring +======= +A simple and lightweight string library for C inspired by C++'s STL +`std::string` (don't laugh) class, but with a few additions/improvements. + +Building +-------- +`cstring` is a static library. The header file is installed in +`/usr/local/include` and the library file in `/usr/local/lib`: + + # make install clean + +You can also run a few tests after you've installed `cstring`: + + $ cd cstring/tests + $ make && make run clean + +In order to make a distribution do: + + $ make dist + +If you want to uninstall the library do: + + # sudo make uninstall + +A file using `cstring` has to be linked using the `-lcstring` linker flag. +In case you want to run your project in debug mode, compile the library using +the `-DCSTRING_DBG` option. + +Usage +----- +When using this library, you must always call the `cstring_create` and +`cstring_delete` 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) + +Read the `man` page for more detailed info. + +Functions +--------- +- `cstring_create`: Initiliaze string. +- `cstring_delete`: Deallocate string. +- `cstring_assign`: Assign new string. +- `cstring_insert`: Insert at a specific index. +- `cstring_append`: Append to end of string. +- `cstring_prepend`: Prepend to beginning of string. +- `cstring_erase`: Erase portion of string. +- `cstring_erase_matching`: Erase first match. +- `cstring_erase_all_matching`: Erase all matches. +- `cstring_trim`: Trim character. +- `cstring_push_back`: Add character to end of string. +- `cstring_pop_back`: Remove the last character from string. +- `cstring_replace_char`: Replace character at a specific index. +- `cstring_replace_str`: Replace portion of string. +- `cstring_substr`: Extract a substring. +- `cstring_swap`: Swap contents of two strings. +- `cstring_sort`: Sort an array of `cstring` objects. +- `cstring_sort_partial`: Like `cstring_sort` but for part of the array. +- `cstring_sort_chars`: Sort `cstring`'s contents. +- `cstring_sort_chars_partial`: Like `cstring_sort_chars` but for part of the string. +- `cstring_shrink_to_fit`: Shrink string's capacity to fit its size. +- `cstring_clear`: Clear contents of string +- `cstring_find`: Find first occurence of a pattern in string. +- `cstring_rfind`: Fnid last occurence of a pattern in string. +- `cstring_find_first_of`: Find first occurence of specified characters in string. +- `cstring_find_first_not_of`: Find the first character that does not match any of the specified characters. +- `cstring_find_last_of`: Find last occurence of specified characters in string. +- `cstring_find_last_not_of`: Find the last character that does not match any of the specified characters. +- `cstring_front`: Get first character in string. +- `cstring_back`: Get last character in string. +- `cstring_empty`: Check if string is empty. +- `cstring_starts_with_str`: Check if string starts with specified `char *`. +- `cstring_ends_with_str`: Check if string ends with specified `char *`. +- `cstring_starts_with_char`: Check if string starts with specified `char`. +- `cstring_ends_with_char`: Check if string ends with specified `char`. +- `cstring_data`: Get string's content in raw bytes. +- `cstring_copy`: Copy contents of a `char *`. +- `cstring_resize`: Resize string. +- `cstring_getline`: Read a line from a `FILE` stream. +- `cstring_equal`: Check if `lhs == rhs`. +- `cstring_greater`: Check if `lhs > rhs`. +- `cstring_greater_or_equal`: Check if `lhs >= rhs`. +- `cstring_less`: Check if `lhs < rhs`. +- `cstring_less_or_equal`: Check if `lhs <= rhs`. + +`lhs`: Left hand side +`rhs`: Right hand side + +Macros +------ +- `CSTRING_OUT_OF_BOUNDS`: Check if value is out of bounds. +- `CSTRING_ARR_LEN`: Determine an array's length. The macro must be called in the same function the array is declared. +- `CSTRING_MALLOC`: Allocate memory with error checking. + +The following macros can only be used in debug mode: + +- `CSTIRNG_DBG_LOG`: Prints a message in the format of `DEBUG: file:line:func(): msg`. +- `CSTRING_DBG_LOG_CSTR_INFO`: Prints all the contents of a `cstring` struct. The argument *has* to be a pointer. +- `CSTRING_DBG_LOG_CSTR_INFO_NPTR`: Like `CSTRING_DBG_LOG_CSTR_INFO` but the argument has to be a non-pointer. +- `CSTRING_DBG_LOG_STR_INFO`: Print contents of a normal string. + +Constants +--------- +- `CSTRING_NPOS`: Signifies that a pattern hasn't been found inside the string. Its value is -1. +- `CSTRING_INIT_EMPTY`: Used with `cstring_create` in case the string is to be initiliazed as empty. + +Flags +----- +- `CSTRING_SORT_ASCENDING`: Sort in ascending order. +- `CSTRING_SORT_DESCENDING`: Sort in descending order. +- `CSTRING_SORT_CALLBACK`: Sort using a callback function. +- `CSTRING_SORT_REST`: Sort the rest of the array. + +Example +------- +See the test programs in `tests` for more. + + #include <cstring.h> + + /* outputs "Foobar" to the screen */ + int + main(int argc, char **argv) + { + cstring s = cstring_create("Foo"); + cstring_append(&s, "bar"); + printf("%s\n", s.str); + cstring_delete(&s); + + return 0; + } diff --git a/README.md b/README.md @@ -1,139 +0,0 @@ -# cstring - -A simple and lightweight string library for C inspired by C++'s STL `string` class, -but with a many additions. - -## Building - -`cstring` is a static library. The header file is installed in `/usr/local/include` and -the library file in `/usr/local/lib`. - -In order to install it do the following -```shell -$ cd /path/to/cstring -$ sudo make install clean -``` - -You can also run a few tests -```shell -$ cd /path/to/cstring/tests -$ make && make run clean -``` - -In order to make a distribution do -```shell -$ cd /path/to/cstring -$ make dist -``` - -If you want to uninstall the library do the following -```shell -$ cd /path/to/cstring -$ sudo make uninstall -``` - -A file using `cstring` has to be linked using the `-lcstring` linker flag. -In case you want to run your project in debug mode, compile the library using the `-DCSTRING_DBG` option. - -## Usage - -When using this library, you must **always** call the `cstring_create` and `cstring_delete` -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)`. - -Read the `man` page for more detailed info. - -## Functions - -* `cstring_create`: Initiliaze string. -* `cstring_delete`: Deallocate string. -* `cstring_assign`: Assign new string. -* `cstring_insert`: Insert at a specific index. -* `cstring_append`: Append to end of string. -* `cstring_prepend`: Prepend to beginning of string. -* `cstring_erase`: Erase portion of string. -* `cstring_erase_matching`: Erase first match. -* `cstring_erase_all_matching`: Erase all matches. -* `cstring_trim`: Trim character. -* `cstring_push_back`: Add character to end of string. -* `cstring_pop_back`: Remove the last character from string. -* `cstring_replace_char`: Replace character at a specific index. -* `cstring_replace_str`: Replace portion of string. -* `cstring_substr`: Extract a substring. -* `cstring_swap`: Swap contents of two strings. -* `cstring_sort`: Sort an array of `cstring` objects. -* `cstring_sort_partial`: Like `cstring_sort` but for part of the array. -* `cstring_sort_chars`: Sort `cstring`'s contents. -* `cstring_sort_chars_partial`: Like `cstring_sort_chars` but for part of the string. -* `cstring_shrink_to_fit`: Shrink string's capacity to fit its size. -* `cstring_clear`: Clear contents of string -* `cstring_find`: Find first occurence of a pattern in string. -* `cstring_rfind`: Fnid last occurence of a pattern in string. -* `cstring_find_first_of`: Find first occurence of specified characters in string. -* `cstring_find_first_not_of`: Find the first character that does not match any of the specified characters. -* `cstring_find_last_of`: Find last occurence of specified characters in string. -* `cstring_find_last_not_of`: Find the last character that does not match any of the specified characters. -* `cstring_front`: Get first character in string. -* `cstring_back`: Get last character in string. -* `cstring_empty`: Check if string is empty. -* `cstring_starts_with_str`: Check if string starts with specified `char *`. -* `cstring_ends_with_str`: Check if string ends with specified `char *`. -* `cstring_starts_with_char`: Check if string starts with specified `char`. -* `cstring_ends_with_char`: Check if string ends with specified `char`. -* `cstring_data`: Get string's content in raw bytes. -* `cstring_copy`: Copy contents of a `char *`. -* `cstring_resize`: Resize string. -* `cstring_getline`: Read a line from a `FILE` stream. -* `cstring_equal`: Check if `lhs == rhs`. -* `cstring_greater`: Check if `lhs > rhs`. -* `cstring_greater_or_equal`: Check if `lhs >= rhs`. -* `cstring_less`: Check if `lhs < rhs`. -* `cstring_less_or_equal`: Check if `lhs <= rhs`. - -`lhs`: Left hand side -`rhs`: Right hand side - -## Macros - -* `CSTRING_OUT_OF_BOUNDS`: Check if value is out of bounds. -* `CSTRING_ARR_LEN`: Determine an array's length. The macro must be called in the same function the array is declared. -* `CSTRING_MALLOC`: Allocate memory with error checking. -The following macros can only be used in debug mode -* `CSTIRNG_DBG_LOG`: Prints a message in the format of `DEBUG: file:line:func(): msg`. -* `CSTRING_DBG_LOG_CSTR_INFO`: Prints all the contents of a `cstring` struct. The argument *has* to be a pointer. -* `CSTRING_DBG_LOG_CSTR_INFO_NPTR`: Like `CSTRING_DBG_LOG_CSTR_INFO` but the argument has to be a non-pointer. -* `CSTRING_DBG_LOG_STR_INFO`: Print contents of a normal string. - -## Constants - -* `CSTRING_NPOS`: Signifies that a pattern hasn't been found inside the string. Its value is -1. -* `CSTRING_INIT_EMPTY`: Used with `cstring_create` in case the string is to be initiliazed as empty. - -## Flags - -* `CSTRING_SORT_ASCENDING`: Sort in ascending order. -* `CSTRING_SORT_DESCENDING`: Sort in descending order. -* `CSTRING_SORT_CALLBACK`: Sort using a callback function. -* `CSTRING_SORT_REST`: Sort the rest of the array. - -## Example - -See the test programs in `tests` for more. - -```c -#include <cstring.h> - -/* outputs "Foobar" to the screen */ -int -main(int argc, char **argv) -{ - cstring s = cstring_create("Foo"); - cstring_append(&s, "bar"); - printf("%s\n", s.str); - cstring_delete(&s); - - return 0; -} -``` diff --git a/config.mk b/config.mk @@ -4,7 +4,7 @@ VERSION = 0.1 # paths PREFIX = /usr/local -MAN_DIR = ${PREFIX}/man/man3 +MAN_DIR = ${PREFIX}/share/man/man3 INC_DIR = ${PREFIX}/include LIB_DIR = ${PREFIX}/lib @@ -14,9 +14,8 @@ LIBS = -Llib # flags CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L \ - -DVERSION=\"${VERSION}\" -CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations \ - -O3 ${INCS} ${CPPFLAGS} + -D_XOPEN_SOURCE=700 -DVERSION=\"${VERSION}\" +CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} LDFLAGS = ${LIBS} ARFLAGS = rs @@ -31,5 +30,5 @@ TAR = tar -cf GZIP = gzip # compiler -CC = gcc +CC = cc AR = ar diff --git a/cstring.3 b/cstring.3 @@ -26,17 +26,17 @@ option. .Sh STRUCTURES .Bl -tag -width Ds typedef struct _cstring { - size_t len; /* string length */ - size_t capacity; /* string capacity */ - char *str; /* contents of string */ + size_t len; /* string length */ + size_t capacity; /* string capacity */ + char *str; /* contents of string */ -CSTRING_SORT_ASCENDING 0x01 /* sort in ascending order */ +CSTRING_SORT_ASCENDING 0x01 /* sort in ascending order */ .br -CSTRING_SORT_DESCENDING 0x02 /* sort in descending order */ +CSTRING_SORT_DESCENDING 0x02 /* sort in descending order */ .br -CSTRING_SORT_CALLBACK 0x04 /* sort using a callback function */ +CSTRING_SORT_CALLBACK 0x04 /* sort using a callback function */ .br -CSTRING_SORT_REST 0x10 /* sort the rest of the array */ +CSTRING_SORT_REST 0x10 /* sort the rest of the array */ .br } cstring; .Sh TYPEDEFS diff --git a/cstring.c b/cstring.c @@ -1,24 +1,24 @@ /* See LICENSE file for copyright and license details. */ #include "cstring.h" -#define CSTRING_EXCEEDS_CAPACITY(len, cap) ((len) >= (cap)) +#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 */ @@ -32,173 +32,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) { - size_t slen, newlen; - char *tmp; - - if (!CSTRING_OUT_OF_BOUNDS(cs->len, 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); + size_t slen, newlen; + char *tmp; + + if (!CSTRING_OUT_OF_BOUNDS(cs->len, 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"); \ +// FIXME +#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) +#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) { - size_t newlen; - char *tmp; + size_t newlen; + char *tmp; - if (!cstring_empty(cs) - && (!CSTRING_OUT_OF_BOUNDS(cs->len, pos) - || !CSTRING_OUT_OF_BOUNDS(cs->len, len))) { + if (!cstring_empty(cs) + && (!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); - 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 */ - 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'; + 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) { - size_t len, i; + 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); - } + 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; - - 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 @@ -209,181 +209,181 @@ 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->len, i)) - cs->str[i] = c; + 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->len, pos) - && !CSTRING_OUT_OF_BOUNDS(cs->len, olen)) { - cstring_erase(cs, pos, olen); - cstring_insert(cs, s, pos); - } + 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); + } } cstring cstring_substr(const cstring *cs, size_t pos, size_t 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; - substr.str[len] = '\0'; - cstring_shrink_to_fit(&substr); - return substr; + 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; + 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 cstring_sort_partial(cstring *cs, size_t pos, size_t len, int flags, - cstring_sort_callback cb) + cstring_sort_callback cb) { - if (flags & CSTRING_SORT_REST || CSTRING_OUT_OF_BOUNDS(len, pos + len)) - len -= pos; + if (flags & CSTRING_SORT_REST || CSTRING_OUT_OF_BOUNDS(len, pos + len)) + len -= pos; - if (flags & CSTRING_SORT_ASCENDING) - qsort(cs + pos, len, sizeof(cstring), cstring_cmp_greater); - else if (flags & CSTRING_SORT_DESCENDING) - qsort(cs + pos, len, sizeof(cstring), cstring_cmp_less); - else if (flags & CSTRING_SORT_CALLBACK) - qsort(cs + pos, len, sizeof(cstring), cb); + if (flags & CSTRING_SORT_ASCENDING) + qsort(cs + pos, len, sizeof(cstring), cstring_cmp_greater); + else if (flags & CSTRING_SORT_DESCENDING) + qsort(cs + pos, len, sizeof(cstring), cstring_cmp_less); + 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, int flags, - cstring_sort_callback cb) + cstring_sort_callback cb) { - if (flags & CSTRING_SORT_REST || CSTRING_OUT_OF_BOUNDS(cs->len, pos + len)) - len = cs->len - pos; + if (flags & CSTRING_SORT_REST || CSTRING_OUT_OF_BOUNDS(cs->len, pos + len)) + len = cs->len - pos; - if (flags & CSTRING_SORT_ASCENDING) - qsort(cs->str + pos, len, sizeof(char), cstring_cmp_char_greater); - else if (flags & CSTRING_SORT_DESCENDING) - qsort(cs->str + pos, len, sizeof(char), cstring_cmp_char_less); - else if (flags & CSTRING_SORT_CALLBACK) - qsort(cs->str + pos, len, sizeof(char), cb); + if (flags & CSTRING_SORT_ASCENDING) + qsort(cs->str + pos, len, sizeof(char), cstring_cmp_char_greater); + else if (flags & CSTRING_SORT_DESCENDING) + qsort(cs->str + pos, len, sizeof(char), cstring_cmp_char_less); + else if (flags & CSTRING_SORT_CALLBACK) + qsort(cs->str + pos, len, sizeof(char), cb); } 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) { - 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; - } - return (idx == -1 ? CSTRING_NPOS : idx); + 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; + } + 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) { - size_t i = 0; + 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; + 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) { - size_t i; + 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; + 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) { - size_t i = cs->len; + 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; + 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 @@ -391,62 +391,62 @@ cstring_find_last_not_of(const cstring *cs, const char *s) int cstring_ends_with_str(const cstring *cs, const char *s) { - /* avoid cstring_substr */ - cstring sub; - size_t slen; - int found; + /* avoid cstring_substr */ + cstring sub; + size_t slen; + int found; - slen = strlen(s); - sub = cstring_substr(cs, cs->len - slen, slen); - found = !strcmp(sub.str, s); - cstring_delete(&sub); - return found; + slen = strlen(s); + sub = cstring_substr(cs, cs->len - slen, slen); + found = !strcmp(sub.str, s); + cstring_delete(&sub); + return found; } char * cstring_copy(const char *s) { - size_t len; - char *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; + 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; + 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 */ - 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; + 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; + 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 @@ -13,73 +13,73 @@ extern "C" { #define CSTRING_NPOS -1 #define CSTRING_INIT_EMPTY "" #define CSTRING_OUT_OF_BOUNDS(len, pos) ((pos) > (len)) -#define CSTRING_ARR_LEN(arr) ((size_t)sizeof((arr)) / sizeof((arr)[0])) +#define CSTRING_ARR_LEN(arr) ((size_t)sizeof((arr)) / sizeof((arr)[0])) -#define CSTRING_MALLOC(ptr, size) do { \ - ptr = malloc((size)); \ - if (ptr == NULL) \ - fputs("CSTRING_MALLOC(): cannot allocate memory\n", stderr); \ +#define CSTRING_MALLOC(ptr, size) do { \ + ptr = 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 */ typedef struct _cstring { - size_t len; /* strlen of str */ - size_t capacity; /* total capacity of the array */ - char *str; /* the string */ - -#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 */ + size_t len; /* strlen of str */ + size_t capacity; /* total capacity of the array */ + char *str; /* the string */ + +#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 int (*cstring_sort_callback)(const void *, const void *); -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_partial(cstring *, size_t, size_t, int, - cstring_sort_callback); -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 *); -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 int cstring_ends_with_str(const cstring *, const char *); -extern char *cstring_copy(const char *); -extern void cstring_resize(cstring *, size_t); -extern cstring *cstring_getline(FILE *, cstring *, char); +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_partial(cstring *, size_t, size_t, int, + cstring_sort_callback); +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 *); +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 int cstring_ends_with_str(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 *); @@ -103,103 +103,102 @@ 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 cstring_sort(cstring *cs, size_t len, int flags, cstring_sort_callback cb) { - cstring_sort_partial(cs, 0, len, flags, cb); + cstring_sort_partial(cs, 0, len, flags, cb); } static inline void cstring_sort_chars(cstring *cs, int flags, cstring_sort_callback cb) { - cstring_sort_chars_partial(cs, 0, cs->len, flags, cb); + cstring_sort_chars_partial(cs, 0, cs->len, flags, cb); } 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_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 @@ -11,9 +11,9 @@ all: options ${BINS} options: @echo "build options:" - @echo "CFLAGS = ${CFLAGS}" - @echo "LDFLAGS = ${LDFLAGS}" - @echo "CC = ${CC}" + @echo "CFLAGS = ${CFLAGS}" + @echo "LDFLAGS = ${LDFLAGS}" + @echo "CC = ${CC}" run: for bin in ${BINS}; do \ diff --git a/tests/test_basic.c b/tests/test_basic.c @@ -5,57 +5,57 @@ 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 @@ -5,8 +5,8 @@ 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; }