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:
M | LICENSE | | | 41 | ++++++++++++++++------------------------- |
M | Makefile | | | 15 | +++++++-------- |
A | README | | | 134 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
D | README.md | | | 139 | ------------------------------------------------------------------------------- |
M | config.mk | | | 9 | ++++----- |
M | cstring.3 | | | 14 | +++++++------- |
M | cstring.c | | | 464 | ++++++++++++++++++++++++++++++++++++++++---------------------------------------- |
M | cstring.h | | | 141 | +++++++++++++++++++++++++++++++++++++++---------------------------------------- |
M | tests/Makefile | | | 6 | +++--- |
M | tests/test_basic.c | | | 76 | ++++++++++++++++++++++++++++++++++++++-------------------------------------- |
M | tests/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;
}