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 a971a17d08f3ed3543a2240ffe771704730c4957
parent 2d94f506763c425a3ae41a6bd7c3ff3e72dffedf
Author: Remy Noulin <loader2x@gmail.com>
Date:   Wed, 26 Jan 2022 14:24:14 +0200

add makeRoom macro and optimize readText function

release/libsheepy.c | 33 +++++++++++++++++++++++++--------
release/libsheepy.h | 24 +++++++++++++++++++++++-
src/libsheepy.c     | 33 +++++++++++++++++++++++++--------
src/libsheepy.h     | 24 +++++++++++++++++++++++-
4 files changed, 96 insertions(+), 18 deletions(-)

Diffstat:
Mrelease/libsheepy.c | 33+++++++++++++++++++++++++--------
Mrelease/libsheepy.h | 24+++++++++++++++++++++++-
Msrc/libsheepy.c | 33+++++++++++++++++++++++++--------
Msrc/libsheepy.h | 24+++++++++++++++++++++++-
4 files changed, 96 insertions(+), 18 deletions(-)

diff --git a/release/libsheepy.c b/release/libsheepy.c @@ -9734,7 +9734,7 @@ char *intToS(int64_t n) { char s[50]; char *r = NULL; - sprintf(s, "%" PRIiMAX, n); + sprintf(s, "%" PRIi64, n); r = strdup(s); return(r); } @@ -9754,7 +9754,7 @@ char *bIntToS(char *s, int64_t n) { if (!s) { return(NULL); } - sprintf(s, "%" PRIiMAX, n); + sprintf(s, "%" PRIi64, n); return(s); } @@ -49199,6 +49199,7 @@ char **listFromArrayS(char **array, size_t size) { return(r); } + // TODO allocate array size r for z to avoid reallocs and remove listPushS // copy array content for (size_t i = 0 ; i < size ; i++) { if (array[i]) { @@ -52889,7 +52890,7 @@ char **readText(const char *filePath) { char **list = NULL; // sanity checks - if (!filePath) { + if (!filePath || isBlankS(filePath)) { return(NULL); } fp = fopen(filePath, "r"); @@ -52900,6 +52901,13 @@ char **readText(const char *filePath) { } // read all lines read = getline(&line, &len, fp); + size_t index = 0; + size_t alloc = sizeof(*list); + list = MALLOC(alloc); + if (!list) { + goto end; + } + *list = NULL; while (read != -1) { { char* pos = NULL; @@ -52907,15 +52915,24 @@ char **readText(const char *filePath) { if (pos != NULL) *pos = '\0'; } - pErrorNULL(listPushS(&list, line)); + size_t newsize = makeRoom((index+1) * sizeof(*list), alloc, sizeof(*list)); + if (newsize != alloc) { + char **tmp = REALLOC(list, newsize); + if (!tmp) { + listFreeS(list); + list = NULL; + goto end; + } + alloc = newsize; + list = tmp; + } + list[index] = strdup(line); + list[++index] = NULL; read = getline(&line, &len, fp); } + end: fclose(fp); free(line); - if (!list) { - // nothing was read - listEmptyS(list); - } return(list); } 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.8" +#define LIBSHEEPY_VERSION "2.2.8.1" #ifndef SH_PREFIX #define SH_PREFIX(NAME) NAME @@ -1554,6 +1554,28 @@ extern uint64_t logMask; // BINARY SEARCH END +// makeRoom is dynamic memory allocation algorithm +// given a length, an allocated size and the additionnal length, +// makeRoom returns the new allocated size for realloc +// when the new allocated size equals alloc value, there is no need to realloc the memory, enough space is already available +#define libsheepyPrealloc (1024*1024) +#define makeRoom(length, alloc, addlength) funcbegin\ + typeof(alloc) r;\ + typeof(alloc) newlen = (length) + (addlength);\ + if (newlen < (alloc)) {\ + r = alloc;\ + } \ + else {\ + if (newlen < libsheepyPrealloc) {\ + r = newlen * 2;\ + }\ + else {\ + r = newlen + libsheepyPrealloc;\ + }\ + }\ + r;\ + funcend + // initialize libsheepy (optional, for debug) typedef void(*initLibsheepyObjectP)(void); void initLibsheepyF(const char *progPath, initLibsheepyObjectP initF); diff --git a/src/libsheepy.c b/src/libsheepy.c @@ -9790,7 +9790,7 @@ char *intToS(int64_t n) { char s[50]; char *r = NULL; - sprintf(s, "%" PRIiMAX, n); + sprintf(s, "%" PRIi64, n); r = strdup(s); return(r); } @@ -9810,7 +9810,7 @@ char *bIntToS(char *s, int64_t n) { if (!s) { return(NULL); } - sprintf(s, "%" PRIiMAX, n); + sprintf(s, "%" PRIi64, n); return(s); } @@ -49255,6 +49255,7 @@ char **listFromArrayS(char **array, size_t size) { return(r); } + // TODO allocate array size r for z to avoid reallocs and remove listPushS // copy array content for (size_t i = 0 ; i < size ; i++) { if (array[i]) { @@ -52945,7 +52946,7 @@ char **readText(const char *filePath) { char **list = NULL; // sanity checks - if (!filePath) { + if (!filePath || isBlankS(filePath)) { return(NULL); } fp = fopen(filePath, "r"); @@ -52956,6 +52957,13 @@ char **readText(const char *filePath) { } // read all lines read = getline(&line, &len, fp); + size_t index = 0; + size_t alloc = sizeof(*list); + list = MALLOC(alloc); + if (!list) { + goto end; + } + *list = NULL; while (read != -1) { { char* pos = NULL; @@ -52963,15 +52971,24 @@ char **readText(const char *filePath) { if (pos != NULL) *pos = '\0'; } - pErrorNULL(listPushS(&list, line)); + size_t newsize = makeRoom((index+1) * sizeof(*list), alloc, sizeof(*list)); + if (newsize != alloc) { + char **tmp = REALLOC(list, newsize); + if (!tmp) { + listFreeS(list); + list = NULL; + goto end; + } + alloc = newsize; + list = tmp; + } + list[index] = strdup(line); + list[++index] = NULL; read = getline(&line, &len, fp); } + end: fclose(fp); free(line); - if (!list) { - // nothing was read - listEmptyS(list); - } return(list); } 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.8" +#define LIBSHEEPY_VERSION "2.2.8.1" #ifndef SH_PREFIX #define SH_PREFIX(NAME) NAME @@ -1554,6 +1554,28 @@ extern uint64_t logMask; // BINARY SEARCH END +// makeRoom is dynamic memory allocation algorithm +// given a length, an allocated size and the additionnal length, +// makeRoom returns the new allocated size for realloc +// when the new allocated size equals alloc value, there is no need to realloc the memory, enough space is already available +#define libsheepyPrealloc (1024*1024) +#define makeRoom(length, alloc, addlength) funcbegin\ + typeof(alloc) r;\ + typeof(alloc) newlen = (length) + (addlength);\ + if (newlen < (alloc)) {\ + r = alloc;\ + } \ + else {\ + if (newlen < libsheepyPrealloc) {\ + r = newlen * 2;\ + }\ + else {\ + r = newlen + libsheepyPrealloc;\ + }\ + }\ + r;\ + funcend + // initialize libsheepy (optional, for debug) typedef void(*initLibsheepyObjectP)(void); void initLibsheepyF(const char *progPath, initLibsheepyObjectP initF);