libsheepy

C lib for handling text files, strings and json like data structure with an object oriented system
git clone https://spartatek.se/git/libsheepy.git
Log | Files | Refs | README | LICENSE

commit d1da7a37b447c6730ca95e18aaf78e9a0bdbd110
parent f3e6eba1bbc7acf9c85000cee78b7d185113a82d
Author: Remy Noulin <loader2x@gmail.com>
Date:   Fri,  4 Apr 2025 10:02:11 +0200

Add btt functions: toCharB, bInsertBB, copyRngB, bCropB

release/libsheepy.h   |   2 +-
release/libsheepyBt.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++
release/libsheepyBt.h |  21 ++++++++-
src/libsheepy.h       |   2 +-
src/libsheepyBt.c     | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++
src/libsheepyBt.h     |  21 ++++++++-
6 files changed, 294 insertions(+), 4 deletions(-)

Diffstat:
Mrelease/libsheepy.h | 2+-
Mrelease/libsheepyBt.c | 126+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mrelease/libsheepyBt.h | 21++++++++++++++++++++-
Msrc/libsheepy.h | 2+-
Msrc/libsheepyBt.c | 126+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/libsheepyBt.h | 21++++++++++++++++++++-
6 files changed, 294 insertions(+), 4 deletions(-)

diff --git a/release/libsheepy.h b/release/libsheepy.h @@ -98,7 +98,7 @@ // version accoring to the version package: Release.Major.minor.patch // https://noulin.net/version/file/README.md.html -#define LIBSHEEPY_VERSION "2.2.17" +#define LIBSHEEPY_VERSION "2.2.18" #ifndef SH_PREFIX #define SH_PREFIX(NAME) NAME diff --git a/release/libsheepyBt.c b/release/libsheepyBt.c @@ -229,6 +229,16 @@ void cleanUpFinishB(btt **val) { finishB(val); } +// convert btt to char* allocated on heap +char *toCharB(btt *b) { + if (not b or not b->b) ret null; + char *r = malloc(b->len+1); + if (not r) ret null; + if (b->len) memcpy(r, b->b, b->len); + r[b->len] = 0; + ret r; +} + /** * return a btt object with s appended to b * b doesn't need to have a heap allocated buffer @@ -457,6 +467,72 @@ btt *bInsertB(btt *b, int64_t index, const char *toInsert) { } /** + * buffer insert btt string in string at index + * + * return string with toInsert at index + * negative indexes are allowed + * index -1 is the end of the array and is equivalent to index len + * + * \param + * string + * \param + * index in string + * \param + * toInsert string + * \return + * modified string + * NULL unchanged string when string is NULL or invalid index + */ +btt *bInsertBB(btt *b, int64_t index, const btt *toInsert) { + if (!b or !b->b or !toInsert or !toInsert->b) return NULL; + if (b->alloc == 0 and b->len > 0) { + // string is not allocated so it is readonly + return(NULL); + } + int64_t blen = (int64_t)b->len; + + if (!blen && index == -1) { + // empty string, index -1 is equal to 0 + index = 0; + } + bool neg = false; + if (index < 0) { + neg = true; + } + + if (index > blen) { + return(NULL); + } + if (neg) { + index++; + } + if (index < -blen) { + return(NULL); + } + if (neg) { + index = blen + index; + } + + size_t len = toInsert->len; + u32 newsize = makeRoom(b->len, b->alloc, len); + // check if there is enough space + if (newsize > b->alloc) { + u8 *tmp = realloc(b->b, newsize); + if (!tmp) return NULL; + b->b = tmp; + b->alloc = newsize; + } + // when index == b->len, just add toInsert at the end + if (index < b->len) { + memmove(b->b+index+len, b->b+index, b->len - index); + } + // copy toInsert at index in b + memcpy(b->b+index, toInsert->b, len); + b->len += len; + return b; +} + +/** * buffer delete string * * return string without the string between start and end @@ -1048,6 +1124,56 @@ btt slicePB(const btt *b, int64_t start, int64_t end) { ret sliceB(*b, start, end); } +btt copyRngB(const btt b, int64_t start, int64_t end) { + btt s = sliceB(b, start, end); + if (not s.b) ret s; // error return {0} + else ret copyB(s); +} + +// cropB copy and remove +btt bCropB(btt *b, int64_t start, int64_t end) { + + // sanity checks + if (!b or !b->b) { + ret emptybt; + } + if (b->alloc == 0 and b->len > 0) { + // b is not allocated so it is readonly + ret emptybt; + } + + checkRange(*b, emptybt); + + // slice to s + btt s = {0}; + s.b = b->b + start; + if (start == end) { + // empty string + s.len = 0; + ret s; // nothing to delete in b + } + else { + // start < end < len + s.len = end - start; + } + + // copy s to r and allocate on heap + btt r; + r.len = s.len; + r.b = malloc(r.len); + r.alloc = r.len; + memcpy(r.b, s.b, r.len); + + // delete string between start and end in b + // copy range to a new string + int64_t n; + n = end - start; + memmove(b->b+start, b->b+start+n, (size_t)(len-n-start)); + b->len -= n; + + ret r; +} + /** * return a btt object without the leading and trailing spaces */ diff --git a/release/libsheepyBt.h b/release/libsheepyBt.h @@ -25,6 +25,10 @@ * } btt; * ``` * The btt structure is managed by the *B functions. + * The *B (not b*B) functions don't modify the first btt parameter. + * The functions named b*B modify the first bbt pointer parameter and return a btt pointer. + * The functions named *PB take a btt pointer whereas *B function take a btt struct as parameter. + * *BB functions take btt struct in all string parameters * * - Disadvantage 1: btt doesn't work with standard C string functions * @@ -391,7 +395,7 @@ btt *dupPB(btt *b); // splitLenB // listFreeB // join -// toCharB convert to char* +// ..toCharB convert to char* // getB setB setBB set .b getBB get .b // // extra sds splitargs @@ -442,6 +446,9 @@ void cleanUpFreeB(btt **val); // finish val when it is out of scope void cleanUpFinishB(btt **val); +// convert btt to char* allocated on heap +char *toCharB(btt *b); + // return a btt object with s appended to b // b doesn't need to have a heap allocated buffer #define appendB pushB @@ -507,6 +514,7 @@ btt pushPBPB(const btt *b, const btt *s); // insert string in string btt *bInsertB(btt *b, int64_t index, const char *s); +btt *bInsertBB(btt *b, int64_t index, const btt *s); // delete range in string btt *bDelB(btt *string, int64_t start, int64_t end); @@ -827,6 +835,17 @@ btt slicePB(const btt *b, int64_t start, int64_t end); const btt*: slicePB\ )(b, start, end); +// copyRngB +// return a btt object with a heap allocated copy of b.b from start to end +btt copyRngB(const btt b, int64_t start, int64_t end); + +// copyRngPB +// return a btt object with a heap allocated copy of b.b from start to end +// TODO btt copyRngPB(btt *b, int64_t start, int64_t end); + +// cropB copy and remove +btt bCropB(btt *b, int64_t start, int64_t end); + // return a btt object without the leading and trailing spaces btt trimB(const btt b); diff --git a/src/libsheepy.h b/src/libsheepy.h @@ -98,7 +98,7 @@ // version accoring to the version package: Release.Major.minor.patch // https://noulin.net/version/file/README.md.html -#define LIBSHEEPY_VERSION "2.2.17" +#define LIBSHEEPY_VERSION "2.2.18" #ifndef SH_PREFIX #define SH_PREFIX(NAME) NAME diff --git a/src/libsheepyBt.c b/src/libsheepyBt.c @@ -229,6 +229,16 @@ void cleanUpFinishB(btt **val) { finishB(val); } +// convert btt to char* allocated on heap +char *toCharB(btt *b) { + if (not b or not b->b) ret null; + char *r = malloc(b->len+1); + if (not r) ret null; + if (b->len) memcpy(r, b->b, b->len); + r[b->len] = 0; + ret r; +} + /** * return a btt object with s appended to b * b doesn't need to have a heap allocated buffer @@ -457,6 +467,72 @@ btt *bInsertB(btt *b, int64_t index, const char *toInsert) { } /** + * buffer insert btt string in string at index + * + * return string with toInsert at index + * negative indexes are allowed + * index -1 is the end of the array and is equivalent to index len + * + * \param + * string + * \param + * index in string + * \param + * toInsert string + * \return + * modified string + * NULL unchanged string when string is NULL or invalid index + */ +btt *bInsertBB(btt *b, int64_t index, const btt *toInsert) { + if (!b or !b->b or !toInsert or !toInsert->b) return NULL; + if (b->alloc == 0 and b->len > 0) { + // string is not allocated so it is readonly + return(NULL); + } + int64_t blen = (int64_t)b->len; + + if (!blen && index == -1) { + // empty string, index -1 is equal to 0 + index = 0; + } + bool neg = false; + if (index < 0) { + neg = true; + } + + if (index > blen) { + return(NULL); + } + if (neg) { + index++; + } + if (index < -blen) { + return(NULL); + } + if (neg) { + index = blen + index; + } + + size_t len = toInsert->len; + u32 newsize = makeRoom(b->len, b->alloc, len); + // check if there is enough space + if (newsize > b->alloc) { + u8 *tmp = realloc(b->b, newsize); + if (!tmp) return NULL; + b->b = tmp; + b->alloc = newsize; + } + // when index == b->len, just add toInsert at the end + if (index < b->len) { + memmove(b->b+index+len, b->b+index, b->len - index); + } + // copy toInsert at index in b + memcpy(b->b+index, toInsert->b, len); + b->len += len; + return b; +} + +/** * buffer delete string * * return string without the string between start and end @@ -1048,6 +1124,56 @@ btt slicePB(const btt *b, int64_t start, int64_t end) { ret sliceB(*b, start, end); } +btt copyRngB(const btt b, int64_t start, int64_t end) { + btt s = sliceB(b, start, end); + if (not s.b) ret s; // error return {0} + else ret copyB(s); +} + +// cropB copy and remove +btt bCropB(btt *b, int64_t start, int64_t end) { + + // sanity checks + if (!b or !b->b) { + ret emptybt; + } + if (b->alloc == 0 and b->len > 0) { + // b is not allocated so it is readonly + ret emptybt; + } + + checkRange(*b, emptybt); + + // slice to s + btt s = {0}; + s.b = b->b + start; + if (start == end) { + // empty string + s.len = 0; + ret s; // nothing to delete in b + } + else { + // start < end < len + s.len = end - start; + } + + // copy s to r and allocate on heap + btt r; + r.len = s.len; + r.b = malloc(r.len); + r.alloc = r.len; + memcpy(r.b, s.b, r.len); + + // delete string between start and end in b + // copy range to a new string + int64_t n; + n = end - start; + memmove(b->b+start, b->b+start+n, (size_t)(len-n-start)); + b->len -= n; + + ret r; +} + /** * return a btt object without the leading and trailing spaces */ diff --git a/src/libsheepyBt.h b/src/libsheepyBt.h @@ -25,6 +25,10 @@ * } btt; * ``` * The btt structure is managed by the *B functions. + * The *B (not b*B) functions don't modify the first btt parameter. + * The functions named b*B modify the first bbt pointer parameter and return a btt pointer. + * The functions named *PB take a btt pointer whereas *B function take a btt struct as parameter. + * *BB functions take btt struct in all string parameters * * - Disadvantage 1: btt doesn't work with standard C string functions * @@ -391,7 +395,7 @@ btt *dupPB(btt *b); // splitLenB // listFreeB // join -// toCharB convert to char* +// ..toCharB convert to char* // getB setB setBB set .b getBB get .b // // extra sds splitargs @@ -442,6 +446,9 @@ void cleanUpFreeB(btt **val); // finish val when it is out of scope void cleanUpFinishB(btt **val); +// convert btt to char* allocated on heap +char *toCharB(btt *b); + // return a btt object with s appended to b // b doesn't need to have a heap allocated buffer #define appendB pushB @@ -507,6 +514,7 @@ btt pushPBPB(const btt *b, const btt *s); // insert string in string btt *bInsertB(btt *b, int64_t index, const char *s); +btt *bInsertBB(btt *b, int64_t index, const btt *s); // delete range in string btt *bDelB(btt *string, int64_t start, int64_t end); @@ -827,6 +835,17 @@ btt slicePB(const btt *b, int64_t start, int64_t end); const btt*: slicePB\ )(b, start, end); +// copyRngB +// return a btt object with a heap allocated copy of b.b from start to end +btt copyRngB(const btt b, int64_t start, int64_t end); + +// copyRngPB +// return a btt object with a heap allocated copy of b.b from start to end +// TODO btt copyRngPB(btt *b, int64_t start, int64_t end); + +// cropB copy and remove +btt bCropB(btt *b, int64_t start, int64_t end); + // return a btt object without the leading and trailing spaces btt trimB(const btt b);