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 9efa55da332eb26071bfa474b5422ccb64f6eb8a
parent 1f0e478b035fcef8a231cbd3eb1caed5ea8a097a
Author: Remy Noulin <loader2x@gmail.com>
Date:   Fri,  9 Oct 2020 21:46:27 +0200

add remove and removeElem generics to remove elements from smallArray, smallDict and smallJson without freeing the element

This is useful to avoid double free when the objects are shared between multiple containers

README.md                              |   1 +
completion.txt                         |  13 +
documentation.md                       | 769 +++++++++++++++++++++++++++++++--
example/README.template                |   1 +
release/json/libsheepyCSmallArray.h    |  40 ++
release/json/libsheepyCSmallDict.h     |  29 ++
release/json/libsheepyCSmallJson.h     |  65 +++
release/libsheepy.c                    | 141 ++++++
release/libsheepy.h                    |  31 +-
release/libsheepyObject.h              |  62 +++
src/json/libsheepyCSmallArray.c        |  79 ++++
src/json/libsheepyCSmallArray.h        |  40 ++
src/json/libsheepyCSmallDict.c         |  47 ++
src/json/libsheepyCSmallDict.h         |  29 ++
src/json/libsheepyCSmallJson.c         | 168 +++++++
src/json/libsheepyCSmallJson.h         |  65 +++
src/json/libsheepyCSmallJsonInternal.h |   3 +
src/libsheepy.c                        | 169 +++++++-
src/libsheepy.h                        |  31 +-
src/libsheepyObject.h                  |  62 +++
20 files changed, 1793 insertions(+), 52 deletions(-)

Diffstat:
MREADME.md | 1+
Mcompletion.txt | 13+++++++++++++
Mdocumentation.md | 769+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Mexample/README.template | 1+
Mrelease/json/libsheepyCSmallArray.h | 40++++++++++++++++++++++++++++++++++++++++
Mrelease/json/libsheepyCSmallDict.h | 29+++++++++++++++++++++++++++++
Mrelease/json/libsheepyCSmallJson.h | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mrelease/libsheepy.c | 141+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mrelease/libsheepy.h | 31+++++++++++++++++++++++++++++--
Mrelease/libsheepyObject.h | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/json/libsheepyCSmallArray.c | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/json/libsheepyCSmallArray.h | 40++++++++++++++++++++++++++++++++++++++++
Msrc/json/libsheepyCSmallDict.c | 47+++++++++++++++++++++++++++++++++++++++++++++++
Msrc/json/libsheepyCSmallDict.h | 29+++++++++++++++++++++++++++++
Msrc/json/libsheepyCSmallJson.c | 168+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/json/libsheepyCSmallJson.h | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/json/libsheepyCSmallJsonInternal.h | 3+++
Msrc/libsheepy.c | 169++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Msrc/libsheepy.h | 31+++++++++++++++++++++++++++++--
Msrc/libsheepyObject.h | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
20 files changed, 1793 insertions(+), 52 deletions(-)

diff --git a/README.md b/README.md @@ -71,6 +71,7 @@ __Status__: (libsheepy.h and libsheepy.c) # Features +- stability: libsheepy releases identical MAJOR version are backward compatible, in future MAJOR version the API will be backward compatible as much as possible - few generics to handle all types (for example: eqG(a,b) true when the a and b values are equal, a can be an int and b can be a string representing an int) - error reporting - setjmp, longjmp macros diff --git a/completion.txt b/completion.txt @@ -16,7 +16,10 @@ XSuccess XFAILURE XFailure logXSuccess(string) +logXSuccessf(format, ...) +- * log string with logC and exit with failure logXFailure(string) +logXFailuref(format, ...) logExit(exitCode, string) exitFailure(cond) procbegin @@ -817,8 +820,10 @@ char **iListInjectS(char ***list, intmax_t index, char *toInject) char **iListInjectCharS(char ***list, intmax_t index, char toInject) char **listDelS(char **list, intmax_t start, intmax_t end) char **iListDelS(char ***list, intmax_t start, intmax_t end) +char **iListRemoveS(char ***list, intmax_t start, intmax_t end) char **listDelElemS(char **list, intmax_t index) char **iListDelElemS(char ***list, intmax_t index) +char **iListRemoveElemS(char ***list, intmax_t index) int listPrintS(char **list) forever range(index, maxCount) @@ -1545,6 +1550,10 @@ delO(self, start, end) delG(self, start, end) delElemO(self, index) delElemG(self, index) +removeO(self, start, end) +removeG(self, start, end) +removeElemO(self, index) +removeElemG(self, index) popO(self) popG(self, returnType) dequeueO(self) @@ -2414,6 +2423,8 @@ getNDupSmallContainerKCharO(self, key) getNDupSmallContainerKCharG delKCharO(self, key) delKCharG +removeKCharO(self, key) +removeKCharG hasKCharO(self, key) hasKCharG keyByUndefinedO(self, undefined) @@ -2910,6 +2921,8 @@ getNumAtO(self, index) getNumAtG delElemIndexO(self, index) delElemIndexG +removeElemIndexO(self, index) +removeElemIndexG stringifyO(self, indent) stringifyG stringifySmallStringO(self, indent) diff --git a/documentation.md b/documentation.md @@ -47,7 +47,10 @@ XSuccess XFAILURE XFailure logXSuccess(string) +logXSuccessf(format, ...) +- * log string with logC and exit with failure logXFailure(string) +logXFailuref(format, ...) logExit(exitCode, string) exitFailure(cond) procbegin @@ -848,8 +851,10 @@ char **iListInjectS(char ***list, intmax_t index, char *toInject) char **iListInjectCharS(char ***list, intmax_t index, char toInject) char **listDelS(char **list, intmax_t start, intmax_t end) char **iListDelS(char ***list, intmax_t start, intmax_t end) +char **iListRemoveS(char ***list, intmax_t start, intmax_t end) char **listDelElemS(char **list, intmax_t index) char **iListDelElemS(char ***list, intmax_t index) +char **iListRemoveElemS(char ***list, intmax_t index) int listPrintS(char **list) forever range(index, maxCount) @@ -1499,12 +1504,24 @@ extern const bool FALSE; */ #define logXSuccess(string) MACRO(\ /* - * log string with logC and exit with failure + * log formated string with logP and exit with success * * This is useful to know at which line a program exits + * The format string is printed as given, "Success" is not added unlike + * logXSuccess */ +#define logXSuccessf(format, ...) MACRO(\ +- * log string with logC and exit with failure #define logXFailure(string) MACRO(\ /* + * log formated string with logC and exit with failure + * + * This is useful to know at which line a program exits + * The format string is printed as given, "Failed" is not added unlike + * logXFailure + */ +#define logXFailuref(format, ...) MACRO(\ +/* * log string with logI and exit with exitCode * * This is useful to know at which line a program exits @@ -3279,9 +3296,11 @@ char **iListInjectCharS(char ***list, intmax_t index, char toInject); // del - python style indexes 0..len-1 -1..-len+1 char **listDelS(char **list, intmax_t start, intmax_t end); char **iListDelS(char ***list, intmax_t start, intmax_t end); +char **iListRemoveS(char ***list, intmax_t start, intmax_t end); // del element in list char **listDelElemS(char **list, intmax_t index); char **iListDelElemS(char ***list, intmax_t index); +char **iListRemoveElemS(char ***list, intmax_t index); // print list int listPrintS(char **list); /* @@ -3648,6 +3667,7 @@ void **iListInsert(void ***list, intmax_t index, void **toInsert); // del - python style indexes 0..len-1 -1..-len+1 void **listDel(void **list, intmax_t start, intmax_t end); void **iListDel(void ***list, intmax_t start, intmax_t end); +//NOT NEEDED same as iListDel - void **iListRemove(void ***list, intmax_t start, intmax_t end); // duplicate and sort //TODO void **listSort(void **list); //TODO void iListSort(void ***list); @@ -14317,6 +14337,28 @@ char **iListDelS(char ***list, intmax_t start, intmax_t end) /* + * list Remove String + * return list without elements from start and end in list + * the elements are removed without being freed + * negative indexes are allowed + * + * \param + * list (this parameter is reallocated) + * \param + * start index, must be in the list + * \param + * end index, must be in the list + * \return + * sliced list (you must free the pointer with listFreeS or free) + * list copy when start=end or when start and end are not set correctly + * NULL when list is empty + * NULL when list is NULL or when end is under start + * NULL error + */ +char **iListRemoveS(char ***list, intmax_t start, intmax_t end) + + +/* * list Delete Element String * return new list without the element at index * negative indexes are allowed @@ -14352,6 +14394,25 @@ char **iListDelElemS(char ***list, intmax_t index) /* + * list Remove Element String + * return list without the element at index + * the element is removed without being freed + * negative indexes are allowed + * + * \param + * list (this parameter is reallocated) + * \param + * index must be in the list + * \return + * new list without the element at index (you must free the pointer with listFreeS) + * NULL when list is empty + * NULL when list is NULL + * NULL error + */ +char **iListRemoveElemS(char ***list, intmax_t index) + + +/* * print list elements * to stdout * @@ -15779,6 +15840,10 @@ delO(self, start, end) delG(self, start, end) delElemO(self, index) delElemG(self, index) +removeO(self, start, end) +removeG(self, start, end) +removeElemO(self, index) +removeElemG(self, index) popO(self) popG(self, returnType) dequeueO(self) @@ -16648,6 +16713,8 @@ getNDupSmallContainerKCharO(self, key) getNDupSmallContainerKCharG delKCharO(self, key) delKCharG +removeKCharO(self, key) +removeKCharG hasKCharO(self, key) hasKCharG keyByUndefinedO(self, undefined) @@ -17144,6 +17211,8 @@ getNumAtO(self, index) getNumAtG delElemIndexO(self, index) delElemIndexG +removeElemIndexO(self, index) +removeElemIndexG stringifyO(self, indent) stringifyG stringifySmallStringO(self, indent) @@ -18025,6 +18094,8 @@ void* cropElemVoid (smallDictt *self, char* key); smallContainert* cropElemSmallContainer (smallDictt *self, char* key); smallDictt* del (smallDictt *self, const char *key); smallDictt* delKChar (smallDictt *self, char key); +smallDictt* remove (smallDictt *self, const char *key); +smallDictt* removeKChar (smallDictt *self, char key); bool has (smallDictt *self, const char *key); bool hasKChar (smallDictt *self, char key); char* keyBy (smallDictt *self, baset *value); @@ -18318,6 +18389,8 @@ smallArrayt* injectNFreeSmallString (smallArrayt *self, intmax_t index, smallStr smallArrayt* injectNFreeSmallContainer(smallArrayt *self, intmax_t index, smallContainert *toInject); smallArrayt* del (smallArrayt *self, intmax_t start, intmax_t end); smallArrayt* delElem (smallArrayt *self, intmax_t index); +smallArrayt* remove (smallArrayt *self, intmax_t start, intmax_t end); +smallArrayt* removeElem (smallArrayt *self, intmax_t index); smallArrayt* sort (smallArrayt *self); * int shCmp)(const void * a, const void * b); smallArrayt* sortF (smallArrayt *self, shCmpt compareFunction); @@ -18816,6 +18889,9 @@ double getNumAt (smallJsont *self, intmax_t index); smallJsont* delElem (smallJsont *self, const char *key); smallJsont* del (smallJsont *self, intmax_t start, intmax_t end); smallJsont* delElemIndex (smallJsont *self, intmax_t index); +smallJsont* removeElem (smallJsont *self, const char *key); +smallJsont* remove (smallJsont *self, intmax_t start, intmax_t end); +smallJsont* removeElemIndex (smallJsont *self, intmax_t index); smallJsont* push (smallJsont *self, baset *value); smallJsont* pushUndefined(smallJsont *self); smallJsont* pushBool (smallJsont *self, bool value); @@ -21766,7 +21842,7 @@ smallArrayt* pushSmallContainerSmallArrayG(smallArrayt *self, smallContainert *c smallArrayt* pushUndefinedSmallArray (smallArrayt *self); smallArrayt* pushUndefinedSmallArrayG(smallArrayt *self, void *value UNUSED); smallArrayt* pushVoidSmallArrayG (smallArrayt *self, void *value); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -21783,7 +21859,7 @@ smallArrayt* pushVoidSmallArrayG (smallArrayt *self, void *value); * */ smallJsont* pushSmallJson (smallJsont *self, baset *value); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -21801,7 +21877,7 @@ smallJsont* pushSmallJson (smallJsont *self, baset *value); */ smallJsont* pushSmallJsonSmallJson (smallJsont *self, smallJsont *value); smallJsont* pushSmallJsonG (smallJsont *self, baset *value); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -21819,7 +21895,7 @@ smallJsont* pushSmallJsonG (smallJsont *self, baset *value); */ smallJsont* pushBoolSmallJson (smallJsont *self, bool value); smallJsont* pushBoolSmallJsonG (smallJsont *self, bool value); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -21837,7 +21913,7 @@ smallJsont* pushBoolSmallJsonG (smallJsont *self, bool value); */ smallJsont* pushDoubleSmallJson (smallJsont *self, double value); smallJsont* pushDoubleSmallJsonG (smallJsont *self, double value); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -21855,7 +21931,7 @@ smallJsont* pushDoubleSmallJsonG (smallJsont *self, double value); */ smallJsont* pushIntSmallJson (smallJsont *self, int64_t value); smallJsont* pushIntSmallJsonG (smallJsont *self, int64_t value); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -21873,7 +21949,7 @@ smallJsont* pushIntSmallJsonG (smallJsont *self, int64_t value); */ smallJsont* pushIntSmallJson (smallJsont *self, int64_t value); smallJsont* pushIntSmallJsonG (smallJsont *self, int64_t value); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -21891,7 +21967,7 @@ smallJsont* pushIntSmallJsonG (smallJsont *self, int64_t value); */ smallJsont* pushIntSmallJson (smallJsont *self, int64_t value); smallJsont* pushIntSmallJsonG (smallJsont *self, int64_t value); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -21909,7 +21985,7 @@ smallJsont* pushIntSmallJsonG (smallJsont *self, int64_t value); */ smallJsont* pushIntSmallJson (smallJsont *self, int64_t value); smallJsont* pushIntSmallJsonG (smallJsont *self, int64_t value); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -21927,7 +22003,7 @@ smallJsont* pushIntSmallJsonG (smallJsont *self, int64_t value); */ smallJsont* pushSSmallJson (smallJsont *self, const char *string); smallJsont* pushSSmallJsonG (smallJsont *self, const char *string); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -21945,7 +22021,7 @@ smallJsont* pushSSmallJsonG (smallJsont *self, const char *string); */ smallJsont* pushCharSmallJson (smallJsont *self, char c); smallJsont* pushCharSmallJsonG (smallJsont *self, char c); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -21963,7 +22039,7 @@ smallJsont* pushCharSmallJsonG (smallJsont *self, char c); */ smallJsont* pushSSmallJson (smallJsont *self, const char *string); smallJsont* pushSSmallJsonG (smallJsont *self, const char *string); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -21981,7 +22057,7 @@ smallJsont* pushSSmallJsonG (smallJsont *self, const char *string); */ smallJsont* pushDictSmallJson (smallJsont *self, smallDictt *dict); smallJsont* pushDictSmallJsonG (smallJsont *self, smallDictt *dict); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -21999,7 +22075,7 @@ smallJsont* pushDictSmallJsonG (smallJsont *self, smallDictt *dict); */ smallJsont* pushArraySmallJson (smallJsont *self, smallArrayt *array); smallJsont* pushArraySmallJsonG (smallJsont *self, smallArrayt *array); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -22018,7 +22094,7 @@ smallJsont* pushArraySmallJsonG (smallJsont *self, smallArrayt *array); smallJsont* pushArraycSmallJson (smallJsont *self, char **array); smallJsont* pushArraycSmallJsonG (smallJsont *self, char **array); smallJsont* pushCArraycSmallJsonG (smallJsont *self, const char **array); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -22036,7 +22112,7 @@ smallJsont* pushCArraycSmallJsonG (smallJsont *self, const char **array); */ smallJsont* pushSmallBoolSmallJson (smallJsont *self, smallBoolt *value); smallJsont* pushSmallBoolSmallJsonG (smallJsont *self, smallBoolt *value); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -22054,7 +22130,7 @@ smallJsont* pushSmallBoolSmallJsonG (smallJsont *self, smallBoolt *value); */ smallJsont* pushSmallBytesSmallJson (smallJsont *self, smallBytest *value); smallJsont* pushSmallBytesSmallJsonG (smallJsont *self, smallBytest *value); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -22072,7 +22148,7 @@ smallJsont* pushSmallBytesSmallJsonG (smallJsont *self, smallBytest *value); */ smallJsont* pushSmallDoubleSmallJson (smallJsont *self, smallDoublet *value); smallJsont* pushSmallDoubleSmallJsonG (smallJsont *self, smallDoublet *value); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -22090,7 +22166,7 @@ smallJsont* pushSmallDoubleSmallJsonG (smallJsont *self, smallDoublet *value); */ smallJsont* pushSmallIntSmallJson (smallJsont *self, smallIntt *value); smallJsont* pushSmallIntSmallJsonG (smallJsont *self, smallIntt *value); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -22108,7 +22184,7 @@ smallJsont* pushSmallIntSmallJsonG (smallJsont *self, smallIntt *value); */ smallJsont* pushSmallJsonSmallJson (smallJsont *self, smallJsont *value); smallJsont* pushSmallJsonSmallJsonG (smallJsont *self, smallJsont *value); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -22126,7 +22202,7 @@ smallJsont* pushSmallJsonSmallJsonG (smallJsont *self, smallJsont *value); */ smallJsont* pushSmallStringSmallJson (smallJsont *self, smallStringt *string); smallJsont* pushSmallStringSmallJsonG (smallJsont *self, smallStringt *string); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -22144,7 +22220,7 @@ smallJsont* pushSmallStringSmallJsonG (smallJsont *self, smallStringt *string); */ smallJsont* pushSmallContainerSmallJson(smallJsont *self, smallContainert *container); smallJsont* pushSmallContainerSmallJsonG(smallJsont *self, smallContainert *container); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -22590,7 +22666,7 @@ smallJsont* pushNFreeSmallJson (smallJsont *self, baset *value); */ smallJsont* pushNFreeSmallJsonSmallJson (smallJsont *self, smallJsont *value); smallJsont* pushNFreeSmallJsonG (smallJsont *self, baset *value); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -22608,7 +22684,7 @@ smallJsont* pushNFreeSmallJsonG (smallJsont *self, baset *value); */ smallJsont* pushBoolSmallJson (smallJsont *self, bool value); smallJsont* pushBoolSmallJsonG (smallJsont *self, bool value); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -22626,7 +22702,7 @@ smallJsont* pushBoolSmallJsonG (smallJsont *self, bool value); */ smallJsont* pushDoubleSmallJson (smallJsont *self, double value); smallJsont* pushDoubleSmallJsonG (smallJsont *self, double value); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -22644,7 +22720,7 @@ smallJsont* pushDoubleSmallJsonG (smallJsont *self, double value); */ smallJsont* pushIntSmallJson (smallJsont *self, int64_t value); smallJsont* pushIntSmallJsonG (smallJsont *self, int64_t value); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -22662,7 +22738,7 @@ smallJsont* pushIntSmallJsonG (smallJsont *self, int64_t value); */ smallJsont* pushIntSmallJson (smallJsont *self, int64_t value); smallJsont* pushIntSmallJsonG (smallJsont *self, int64_t value); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -22680,7 +22756,7 @@ smallJsont* pushIntSmallJsonG (smallJsont *self, int64_t value); */ smallJsont* pushIntSmallJson (smallJsont *self, int64_t value); smallJsont* pushIntSmallJsonG (smallJsont *self, int64_t value); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -22709,7 +22785,7 @@ smallJsont* pushIntSmallJsonG (smallJsont *self, int64_t value); */ smallJsont* pushNFreeSSmallJson (smallJsont *self, char *string); smallJsont* pushNFreeSSmallJsonG (smallJsont *self, char *string); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -52285,6 +52361,570 @@ smallArrayt* delElemSmallArrayG (smallArrayt *self, intmax_t index); */ smallStringt* delElemSmallString (smallStringt *self, intmax_t index); smallStringt* delElemSmallStringG (smallStringt *self, intmax_t index); +#define removeO(self, start, end) (self)->f->remove(self, start, end) +#define removeG(self, start, end) +/* + * remove without freeing element + * + * remove element sObject for given key + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallDict(d); + * // set an object shared with another container in the dict d + * // "sString object" is in both container S and d + * setG(d, "key1" ,S); + * setG(d, "key2", "another string"); + * // the program deletes the element for "key1" + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(d, "key1"); + * + * \param + * key smallDictionary key + */ +smallDictt* removeSmallDict (smallDictt *self, const char *key); +smallDictt* removeSmallDictG (smallDictt *self, const char *key, int unused UNUSED); +/* + * remove without freeing element + * + * remove element sObject for given key + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallDict(d); + * // set an object shared with another container in the dict d + * // "sString object" is in both container S and d + * setG(d, "key1" ,S); + * setG(d, "key2", "another string"); + * // the program deletes the element for "key1" + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(d, "key1"); + * + * \param + * key smallDictionary key + */ +smallDictt* removeSmallDict (smallDictt *self, const char *key); +smallDictt* removeSmallDictG (smallDictt *self, const char *key, int unused UNUSED); +/* + * remove without freeing element + * + * remove element sObject for given key + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallDict(d); + * // set an object shared with another container in the dict d + * // "sString object" is in both container S and d + * setG(d, "key1" ,S); + * setG(d, "key2", "another string"); + * // the program deletes the element for "key1" + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(d, "key1"); + * + * \param + * key smallDictionary key + */ +smallDictt* removeKCharSmallDict (smallDictt *self, char key); +smallDictt* removeKCharSmallDictG (smallDictt *self, char key, int unused UNUSED); +/* + * remove without freeing element + * + * remove element sObject for given key + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallDict(d); + * // set an object shared with another container in the dict d + * // "sString object" is in both container S and d + * setG(d, "key1" ,S); + * setG(d, "key2", "another string"); + * // the program deletes the element for "key1" + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(d, "key1"); + * + * \param + * key smallDictionary key + */ +smallDictt* removeKCharSmallDict (smallDictt *self, char key); +smallDictt* removeKCharSmallDictG (smallDictt *self, char key, int unused UNUSED); +/* + * remove without freeing element + * + * remove element sObject for given key + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallDict(d); + * // set an object shared with another container in the dict d + * // "sString object" is in both container S and d + * setG(d, "key1" ,S); + * setG(d, "key2", "another string"); + * // the program deletes the element for "key1" + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(d, "key1"); + * + * \param + * key smallDictionary key + */ +smallDictt* removeSmallDict (smallDictt *self, const char *key); +smallDictt* removeSmallDictG (smallDictt *self, const char *key, int unused UNUSED); +smallJsont* removeKeySmallJsonG (smallJsont *self, const char *key, int unused UNUSED); +smallJsont* removeKeySmallJsonG (smallJsont *self, const char *key, int unused UNUSED); +/* + * remove without freeing elements from start and end in self + * negative indexes are allowed + * + * \param + * start index, must be in the array + * end index, must be in the array + * \return + * sliced array + * array copy when start=end or when start and end are not set correctly + * NULL when array is empty + * NULL when array is NULL or when end is under start + * 0 success + * -1 error + */ +smallJsont* removeSmallJson (smallJsont *self, intmax_t start, intmax_t end); +smallJsont* removeSmallJsonG (smallJsont *self, intmax_t start, intmax_t end); +/* + * remove without freeing elements from start and end in self + * negative indexes are allowed + * + * \param + * start index, must be in the array + * end index, must be in the array + * \return + * sliced array + * array copy when start=end or when start and end are not set correctly + * NULL when array is empty + * NULL when array is NULL or when end is under start + * 0 success + * -1 error + */ +smallJsont* removeSmallJson (smallJsont *self, intmax_t start, intmax_t end); +smallJsont* removeSmallJsonG (smallJsont *self, intmax_t start, intmax_t end); +/* + * remove without freeing elements from start and end in self + * negative indexes are allowed + * + * \param + * start index, must be in the array + * end index, must be in the array + * \return + * sliced array + * array copy when start=end or when start and end are not set correctly + * NULL when array is empty + * NULL when array is NULL or when end is under start + * 0 success + * -1 error + */ +smallJsont* removeSmallJson (smallJsont *self, intmax_t start, intmax_t end); +smallJsont* removeSmallJsonG (smallJsont *self, intmax_t start, intmax_t end); +/* + * remove without freeing elements from start and end in self + * negative indexes are allowed + * + * \param + * start index, must be in the array + * end index, must be in the array + * \return + * sliced array + * array copy when start=end or when start and end are not set correctly + * NULL when array is empty + * NULL when array is NULL or when end is under start + * 0 success + * -1 error + */ +smallJsont* removeSmallJson (smallJsont *self, intmax_t start, intmax_t end); +smallJsont* removeSmallJsonG (smallJsont *self, intmax_t start, intmax_t end); +/* + * remove without freeing elements from start and end in self + * negative indexes are allowed + * + * \param + * start index, must be in the array + * end index, must be in the array + * \return + * sliced array + * array copy when start=end or when start and end are not set correctly + * NULL when array is empty + * NULL when array is NULL or when end is under start + * 0 success + * -1 error + */ +smallJsont* removeSmallJson (smallJsont *self, intmax_t start, intmax_t end); +smallJsont* removeSmallJsonG (smallJsont *self, intmax_t start, intmax_t end); +/* + * remove without freeing elements from start and end in self + * negative indexes are allowed + * + * \param + * start index, must be in the array + * end index, must be in the array + * \return + * sliced array + * array copy when start=end or when start and end are not set correctly + * NULL when array is empty + * NULL when array is NULL or when end is under start + * 0 success + * -1 error + */ +smallJsont* removeSmallJson (smallJsont *self, intmax_t start, intmax_t end); +smallJsont* removeSmallJsonG (smallJsont *self, intmax_t start, intmax_t end); +/* + * remove without freeing elements from start and end in self + * negative indexes are allowed + * + * \param + * start index, must be in the array + * end index, must be in the array + * \return + * sliced array + * array copy when start=end or when start and end are not set correctly + * NULL when array is empty + * NULL when array is NULL or when end is under start + * 0 success + * -1 error + */ +smallJsont* removeSmallJson (smallJsont *self, intmax_t start, intmax_t end); +smallJsont* removeSmallJsonG (smallJsont *self, intmax_t start, intmax_t end); +/* + * remove without freeing elements from start and end in self + * negative indexes are allowed + * + * \param + * start index, must be in the array + * end index, must be in the array + * \return + * sliced array + * array copy when start=end or when start and end are not set correctly + * NULL when array is empty + * NULL when array is NULL or when end is under start + * 0 success + * -1 error + */ +smallJsont* removeSmallJson (smallJsont *self, intmax_t start, intmax_t end); +smallJsont* removeSmallJsonG (smallJsont *self, intmax_t start, intmax_t end); +/* + * remove without freeing elements from start and end in self + * negative indexes are allowed + * + * \param + * start index, must be in the array + * end index, must be in the array + * \return + * sliced array + * array copy when start=end or when start and end are not set correctly + * NULL when array is empty + * NULL when array is NULL or when end is under start + * 0 success + * -1 error + */ +smallJsont* removeSmallJson (smallJsont *self, intmax_t start, intmax_t end); +smallJsont* removeSmallJsonG (smallJsont *self, intmax_t start, intmax_t end); +/* + * remove without freeing elements from start and end in self + * negative indexes are allowed + * + * \param + * start index, must be in the array + * end index, must be in the array + * \return + * sliced array + * array copy when start=end or when start and end are not set correctly + * NULL when array is empty + * NULL when array is NULL or when end is under start + * 0 success + * -1 error + */ +smallArrayt* removeSmallArray (smallArrayt *self, intmax_t start, intmax_t end); +smallArrayt* removeSmallArrayG (smallArrayt *self, intmax_t start, intmax_t end); +/* + * delete smallString + * + * delete the smallString between start and end in self + * negative indexes are allowed + * + * \param + * start: start index, must be in the smallString + * \param + * end: end index, must be in the smallString after start + * \return + * 0 sliced smallString + * unchanged smallString when start=end + * -1 when start and end are not set correctly + * or when input smallString is NULL or when malloc failed or when end is under start + */ +smallStringt* delSmallString (smallStringt *self, intmax_t start, intmax_t end); +smallStringt* delSmallStringG (smallStringt *self, intmax_t start, intmax_t end); +#define removeElemO(self, index) (self)->f->removeElem(self, index) +#define removeElemG(self, index) +smallDictt* removeElemSmallDictG (smallDictt *self, const char *key); +smallDictt* removeElemSmallDictG (smallDictt *self, const char *key); +smallDictt* removeElemKCharSmallDictG(smallDictt *self, char key); +smallDictt* removeElemKCharSmallDictG(smallDictt *self, char key); +smallDictt* removeElemSmallDictG (smallDictt *self, const char *key); +/* + * remove without freeing element + * + * remove element sObject for given key + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallJson(d); + * // set an object shared with another container in the json d + * // "sString object" is in both container S and d + * setG(d, "key1" ,S); + * setG(d, "key2", "another string"); + * // the program deletes the element for "key1" + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(d, "key1"); + * + * \param + * key smallDictionary key + */ +smallJsont* removeElemSmallJson (smallJsont *self, const char *key); +smallJsont* removeElemSmallJsonG (smallJsont *self, const char *key); +/* + * remove without freeing element + * + * remove element sObject for given key + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallJson(d); + * // set an object shared with another container in the json d + * // "sString object" is in both container S and d + * setG(d, "key1" ,S); + * setG(d, "key2", "another string"); + * // the program deletes the element for "key1" + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(d, "key1"); + * + * \param + * key smallDictionary key + */ +smallJsont* removeElemSmallJson (smallJsont *self, const char *key); +smallJsont* removeElemSmallJsonG (smallJsont *self, const char *key); +/* + * remove without freeing element + * + * remove element sObject at index + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallJson(a); + * // set an object shared with another container in the json a + * // "sString object" is in both container S and a + * pushG(a, S); + * pushG(a, "another string"); + * // the program deletes element 0 in json a + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(a, 0); + */ +smallJsont* removeElemIndexSmallJson (smallJsont *self, intmax_t index); +smallJsont* removeElemIndexSmallJsonG (smallJsont *self, intmax_t index); +/* + * remove without freeing element + * + * remove element sObject at index + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallJson(a); + * // set an object shared with another container in the json a + * // "sString object" is in both container S and a + * pushG(a, S); + * pushG(a, "another string"); + * // the program deletes element 0 in json a + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(a, 0); + */ +smallJsont* removeElemIndexSmallJson (smallJsont *self, intmax_t index); +smallJsont* removeElemIndexSmallJsonG (smallJsont *self, intmax_t index); +/* + * remove without freeing element + * + * remove element sObject at index + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallJson(a); + * // set an object shared with another container in the json a + * // "sString object" is in both container S and a + * pushG(a, S); + * pushG(a, "another string"); + * // the program deletes element 0 in json a + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(a, 0); + */ +smallJsont* removeElemIndexSmallJson (smallJsont *self, intmax_t index); +smallJsont* removeElemIndexSmallJsonG (smallJsont *self, intmax_t index); +/* + * remove without freeing element + * + * remove element sObject at index + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallJson(a); + * // set an object shared with another container in the json a + * // "sString object" is in both container S and a + * pushG(a, S); + * pushG(a, "another string"); + * // the program deletes element 0 in json a + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(a, 0); + */ +smallJsont* removeElemIndexSmallJson (smallJsont *self, intmax_t index); +smallJsont* removeElemIndexSmallJsonG (smallJsont *self, intmax_t index); +/* + * remove without freeing element + * + * remove element sObject at index + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallJson(a); + * // set an object shared with another container in the json a + * // "sString object" is in both container S and a + * pushG(a, S); + * pushG(a, "another string"); + * // the program deletes element 0 in json a + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(a, 0); + */ +smallJsont* removeElemIndexSmallJson (smallJsont *self, intmax_t index); +smallJsont* removeElemIndexSmallJsonG (smallJsont *self, intmax_t index); +/* + * remove without freeing element + * + * remove element sObject at index + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallJson(a); + * // set an object shared with another container in the json a + * // "sString object" is in both container S and a + * pushG(a, S); + * pushG(a, "another string"); + * // the program deletes element 0 in json a + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(a, 0); + */ +smallJsont* removeElemIndexSmallJson (smallJsont *self, intmax_t index); +smallJsont* removeElemIndexSmallJsonG (smallJsont *self, intmax_t index); +/* + * remove without freeing element + * + * remove element sObject at index + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallJson(a); + * // set an object shared with another container in the json a + * // "sString object" is in both container S and a + * pushG(a, S); + * pushG(a, "another string"); + * // the program deletes element 0 in json a + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(a, 0); + */ +smallJsont* removeElemIndexSmallJson (smallJsont *self, intmax_t index); +smallJsont* removeElemIndexSmallJsonG (smallJsont *self, intmax_t index); +/* + * remove without freeing element + * + * remove element sObject at index + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallJson(a); + * // set an object shared with another container in the json a + * // "sString object" is in both container S and a + * pushG(a, S); + * pushG(a, "another string"); + * // the program deletes element 0 in json a + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(a, 0); + */ +smallJsont* removeElemIndexSmallJson (smallJsont *self, intmax_t index); +smallJsont* removeElemIndexSmallJsonG (smallJsont *self, intmax_t index); +/* + * remove without freeing element + * + * remove element sObject for given key + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallJson(d); + * // set an object shared with another container in the json d + * // "sString object" is in both container S and d + * setG(d, "key1" ,S); + * setG(d, "key2", "another string"); + * // the program deletes the element for "key1" + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(d, "key1"); + * + * \param + * key smallDictionary key + */ +smallJsont* removeElemSmallJson (smallJsont *self, const char *key); +smallJsont* removeElemSmallJsonG (smallJsont *self, const char *key); +/* + * remove without freeing element + * + * remove without freeing element sObject at index + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallArray(a); + * // set an object shared with another container in the array a + * // "sString object" is in both container S and a + * pushG(a, S); + * pushG(a, "another string"); + * // the program deletes element 0 in array a + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(a, 0); + */ +smallArrayt* removeElemSmallArray (smallArrayt *self, intmax_t index); +smallArrayt* removeElemSmallArrayG (smallArrayt *self, intmax_t index); +/* + * delete smallString + * + * delete the smallString between start and end in self + * negative indexes are allowed + * + * \param + * start: start index, must be in the smallString + * \param + * end: end index, must be in the smallString after start + * \return + * 0 sliced smallString + * unchanged smallString when start=end + * -1 when start and end are not set correctly + * or when input smallString is NULL or when malloc failed or when end is under start + */ +smallStringt* delElemSmallString (smallStringt *self, intmax_t index); +smallStringt* delElemSmallStringG (smallStringt *self, intmax_t index); #define popO(self) (self)->f->pop(self) #define popG(self, returnType) /* @@ -60413,7 +61053,7 @@ smallArrayt* pushCharSmallArray (smallArrayt *self, char c); * NULL error */ smallArrayt* pushCharSmallArray (smallArrayt *self, char c); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -60430,7 +61070,7 @@ smallArrayt* pushCharSmallArray (smallArrayt *self, char c); * */ smallJsont* pushCharSmallJson (smallJsont *self, char c); -/* + /* * push value to json * //:pushHelp @@ -60495,7 +61135,7 @@ smallArrayt* pushArraycSmallArray (smallArrayt *self, char **array); * NULL error */ smallArrayt* pushArraycSmallArray (smallArrayt *self, char **array); -/* + /* * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -60512,7 +61152,7 @@ smallArrayt* pushArraycSmallArray (smallArrayt *self, char **array); * */ smallJsont* pushArraycSmallJson (smallJsont *self, char **array); -/* + /* * push value to json * //:pushHelp @@ -74233,6 +74873,29 @@ smallContainert* getNDupSmallContainerKCharSmallDict(smallDictt *self, char key) * key smallDictionary key */ smallDictt* delKCharSmallDict (smallDictt *self, char key); +#define removeKCharO(self, key) (self)->f->removeKChar(self, key) +#define removeKCharG removeKCharO +/* + * remove without freeing element + * + * remove element sObject for given key + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallDict(d); + * // set an object shared with another container in the dict d + * // "sString object" is in both container S and d + * setG(d, "key1" ,S); + * setG(d, "key2", "another string"); + * // the program deletes the element for "key1" + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(d, "key1"); + * + * \param + * key smallDictionary key + */ +smallDictt* removeKCharSmallDict (smallDictt *self, char key); #define hasKCharO(self, key) (self)->f->hasKChar(self, key) #define hasKCharG hasKCharO /* @@ -81709,6 +82372,44 @@ smallJsont* delElemIndexSmallJson (smallJsont *self, intmax_t index); * The sObject at index 1 and in s are identical, so the element 1 is freed when s is freed */ smallJsont* delElemIndexSmallJson (smallJsont *self, intmax_t index); +#define removeElemIndexO(self, index) (self)->f->removeElemIndex(self, index) +#define removeElemIndexG removeElemIndexO +/* + * remove without freeing element + * + * remove element sObject at index + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallJson(a); + * // set an object shared with another container in the json a + * // "sString object" is in both container S and a + * pushG(a, S); + * pushG(a, "another string"); + * // the program deletes element 0 in json a + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(a, 0); + */ +smallJsont* removeElemIndexSmallJson (smallJsont *self, intmax_t index); +/* + * remove without freeing element + * + * remove element sObject at index + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallJson(a); + * // set an object shared with another container in the json a + * // "sString object" is in both container S and a + * pushG(a, S); + * pushG(a, "another string"); + * // the program deletes element 0 in json a + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(a, 0); + */ +smallJsont* removeElemIndexSmallJson (smallJsont *self, intmax_t index); #define stringifyO(self, indent) (self)->f->stringify(self, indent) #define stringifyG stringifyO /* diff --git a/example/README.template b/example/README.template @@ -71,6 +71,7 @@ __Status__: (libsheepy.h and libsheepy.c) # Features +- stability: libsheepy releases identical MAJOR version are backward compatible, in future MAJOR version the API will be backward compatible as much as possible - few generics to handle all types (for example: eqG(a,b) true when the a and b values are equal, a can be an int and b can be a string representing an int) - error reporting - setjmp, longjmp macros diff --git a/release/json/libsheepyCSmallArray.h b/release/json/libsheepyCSmallArray.h @@ -623,6 +623,42 @@ typedef smallArrayt* (*delSmallArrayFt) (smallArrayt *self, intma typedef smallArrayt* (*delElemSmallArrayFt) (smallArrayt *self, intmax_t index); /** + * remove without freeing elements from start and end in self + * negative indexes are allowed + * + * \param + * start index, must be in the array + * end index, must be in the array + * \return + * sliced array + * array copy when start=end or when start and end are not set correctly + * NULL when array is empty + * NULL when array is NULL or when end is under start + * 0 success + * -1 error + */ +typedef smallArrayt* (*removeSmallArrayFt) (smallArrayt *self, intmax_t start, intmax_t end); + +/** + * remove without freeing element + * + * remove without freeing element sObject at index + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallArray(a); + * // set an object shared with another container in the array a + * // "sString object" is in both container S and a + * pushG(a, S); + * pushG(a, "another string"); + * // the program deletes element 0 in array a + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(a, 0); + */ +typedef smallArrayt* (*removeElemSmallArrayFt) (smallArrayt *self, intmax_t index); + +/** * sort self in alphabetic order * * \return @@ -1544,6 +1580,8 @@ typedef bool (*areAllEBytesSmallArrayFt) (smallArrayt *self); injectNFreeSmallContainerSmallArrayFt injectNFreeSmallContainer;\ delSmallArrayFt del;\ delElemSmallArrayFt delElem;\ + removeSmallArrayFt remove;\ + removeElemSmallArrayFt removeElem;\ sortSmallArrayFt sort;\ sortFSmallArrayFt sortF;\ icSortSmallArrayFt icSort;\ @@ -2193,6 +2231,8 @@ smallArrayt* injectNFreeSmallContainerSmallArrayG(smallArrayt *self, intmax_t in smallArrayt* delSmallArrayG (smallArrayt *self, intmax_t start, intmax_t end); smallArrayt* delElemSmallArrayG (smallArrayt *self, intmax_t index); +smallArrayt* removeSmallArrayG (smallArrayt *self, intmax_t start, intmax_t end); +smallArrayt* removeElemSmallArrayG (smallArrayt *self, intmax_t index); smallArrayt* sortSmallArrayG (smallArrayt *self); smallArrayt* sortFSmallArrayG (smallArrayt *self, shCmpt compareFunction); smallArrayt* icSortSmallArrayG (smallArrayt *self); diff --git a/release/json/libsheepyCSmallDict.h b/release/json/libsheepyCSmallDict.h @@ -402,6 +402,29 @@ typedef smallContainert* (*cropElemSmallContainerSmallDictFt) (smallDictt *self, typedef smallDictt* (*delSmallDictFt) (smallDictt *self, const char *key); typedef smallDictt* (*delKCharSmallDictFt) (smallDictt *self, char key); +/** + * remove without freeing element + * + * remove element sObject for given key + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallDict(d); + * // set an object shared with another container in the dict d + * // "sString object" is in both container S and d + * setG(d, "key1" ,S); + * setG(d, "key2", "another string"); + * // the program deletes the element for "key1" + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(d, "key1"); + * + * \param + * key smallDictionary key + */ +typedef smallDictt* (*removeSmallDictFt) (smallDictt *self, const char *key); +typedef smallDictt* (*removeKCharSmallDictFt) (smallDictt *self, char key); + /** * check if self has 'key' @@ -901,6 +924,8 @@ typedef bool (*areAllEBytesSmallDictFt) (smallDictt *self); cropElemSmallContainerSmallDictFt cropElemSmallContainer;\ delSmallDictFt del;\ delKCharSmallDictFt delKChar;\ + removeSmallDictFt remove;\ + removeKCharSmallDictFt removeKChar;\ hasSmallDictFt has;\ hasKCharSmallDictFt hasKChar;\ keyBySmallDictFt keyBy;\ @@ -1345,6 +1370,10 @@ smallDictt* delSmallDictG (smallDictt *self, const char *key, int unused smallDictt* delKCharSmallDictG (smallDictt *self, char key, int unused UNUSED); smallDictt* delElemSmallDictG (smallDictt *self, const char *key); smallDictt* delElemKCharSmallDictG(smallDictt *self, char key); +smallDictt* removeSmallDictG (smallDictt *self, const char *key, int unused UNUSED); +smallDictt* removeKCharSmallDictG (smallDictt *self, char key, int unused UNUSED); +smallDictt* removeElemSmallDictG (smallDictt *self, const char *key); +smallDictt* removeElemKCharSmallDictG(smallDictt *self, char key); bool hasSmallDictG (smallDictt *self, const char *key); bool hasKCharSmallDictG (smallDictt *self, char key); char* keyBySmallDictG(smallDictt *self, baset *value); diff --git a/release/json/libsheepyCSmallJson.h b/release/json/libsheepyCSmallJson.h @@ -717,6 +717,64 @@ typedef smallJsont* (*delSmallJsonFt) (smallJsont *self, i typedef smallJsont* (*delElemIndexSmallJsonFt) (smallJsont *self, intmax_t index); /** + * remove without freeing element + * + * remove element sObject for given key + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallJson(d); + * // set an object shared with another container in the json d + * // "sString object" is in both container S and d + * setG(d, "key1" ,S); + * setG(d, "key2", "another string"); + * // the program deletes the element for "key1" + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(d, "key1"); + * + * \param + * key smallDictionary key + */ +typedef smallJsont* (*removeElemSmallJsonFt) (smallJsont *self, const char *key); + +/** + * remove without freeing elements from start and end in self + * negative indexes are allowed + * + * \param + * start index, must be in the array + * end index, must be in the array + * \return + * sliced array + * array copy when start=end or when start and end are not set correctly + * NULL when array is empty + * NULL when array is NULL or when end is under start + * 0 success + * -1 error + */ +typedef smallJsont* (*removeSmallJsonFt) (smallJsont *self, intmax_t start, intmax_t end); + +/** + * remove without freeing element + * + * remove element sObject at index + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallJson(a); + * // set an object shared with another container in the json a + * // "sString object" is in both container S and a + * pushG(a, S); + * pushG(a, "another string"); + * // the program deletes element 0 in json a + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(a, 0); + */ +typedef smallJsont* (*removeElemIndexSmallJsonFt) (smallJsont *self, intmax_t index); + + /** * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -2771,6 +2829,9 @@ typedef bool (*areAllEBytesSmallJsonFt) (smallJsont *self); delElemSmallJsonFt delElem;\ delSmallJsonFt del;\ delElemIndexSmallJsonFt delElemIndex;\ + removeElemSmallJsonFt removeElem;\ + removeSmallJsonFt remove;\ + removeElemIndexSmallJsonFt removeElemIndex;\ pushSmallJsonFt push;\ pushUndefinedSmallJsonFt pushUndefined;\ pushBoolSmallJsonFt pushBool;\ @@ -3780,6 +3841,10 @@ smallJsont* delKeySmallJsonG (smallJsont *self, const char *k smallJsont* delElemSmallJsonG (smallJsont *self, const char *key); smallJsont* delSmallJsonG (smallJsont *self, intmax_t start, intmax_t end); smallJsont* delElemIndexSmallJsonG (smallJsont *self, intmax_t index); +smallJsont* removeKeySmallJsonG (smallJsont *self, const char *key, int unused UNUSED); +smallJsont* removeElemSmallJsonG (smallJsont *self, const char *key); +smallJsont* removeSmallJsonG (smallJsont *self, intmax_t start, intmax_t end); +smallJsont* removeElemIndexSmallJsonG (smallJsont *self, intmax_t index); smallJsont* prependSmallJsonG (smallJsont *self, baset *value); smallJsont* prependUndefinedSmallJsonG(smallJsont *self, void *value UNUSED); diff --git a/release/libsheepy.c b/release/libsheepy.c @@ -658,8 +658,10 @@ char **iListInjectS(char ***list, intmax_t index, char *toInject); char **iListInjectCharS(char ***list, intmax_t index, char toInject); char **listDelS(char **list, intmax_t start, intmax_t end); char **iListDelS(char ***list, intmax_t start, intmax_t end); +char **iListRemoveS(char ***list, intmax_t start, intmax_t end); char **listDelElemS(char **list, intmax_t index); char **iListDelElemS(char ***list, intmax_t index); +char **iListRemoveElemS(char ***list, intmax_t index); int listPrintS(char **list); internal int listSortSCmp(const void * a, const void * b); char **listSortS(char **list); @@ -51754,6 +51756,86 @@ char **iListDelS(char ***list, intmax_t start, intmax_t end) { } /** + * list Remove String + * return list without elements from start and end in list + * the elements are removed without being freed + * negative indexes are allowed + * + * \param + * list (this parameter is reallocated) + * \param + * start index, must be in the list + * \param + * end index, must be in the list + * \return + * sliced list (you must free the pointer with listFreeS or free) + * list copy when start=end or when start and end are not set correctly + * NULL when list is empty + * NULL when list is NULL or when end is under start + * NULL error + */ +char **iListRemoveS(char ***list, intmax_t start, intmax_t end) { + char **l = NULL; + intmax_t len; + + // sanity checks + if (!list || !*list) { + return(NULL); + } + + len = listLengthS(*list); + + if (len == 0) { + return(NULL); + } + + if (start >= len) { + start = len; + } + if (end > len) { + end = len; + } + if (start <= -len) { + start = -len; + } + if (end <= -len) { + end = -len; + } + if (start < 0) { + start = len + start; + } + if (end <= 0) { + end = len + end; + } + if (end < start) { + return(NULL); + } + + if (start == end) { + return(*list); + } + + // start < end < len + intmax_t n; + n = end - start; + l = MALLOC((len-n+1) * sizeof(char *)); + if (!l) { + return(NULL); + } + for (intmax_t i=0;i < start;i++) { + l[i] = *((*list)+i); + } + for (intmax_t i=start ; i < len-n ; i++) { + l[i] = *((*list)+n+i); + } + l[len-n] = NULL; + + free(*list); + *list = l; + return(l); +} + +/** * list Delete Element String * return new list without the element at index * negative indexes are allowed @@ -51867,6 +51949,65 @@ char **iListDelElemS(char ***list, intmax_t index) { /** + * list Remove Element String + * return list without the element at index + * the element is removed without being freed + * negative indexes are allowed + * + * \param + * list (this parameter is reallocated) + * \param + * index must be in the list + * \return + * new list without the element at index (you must free the pointer with listFreeS) + * NULL when list is empty + * NULL when list is NULL + * NULL error + */ +char **iListRemoveElemS(char ***list, intmax_t index) { + char **l = NULL; + intmax_t len; + + // sanity checks + if (!list || !*list) { + return(NULL); + } + + len = listLengthS(*list); + + if (len == 0) { + return(NULL); + } + + if (index >= len) { + return(NULL); + } + if (index < -len) { + return(NULL); + } + if (index < 0) { + index = len + index; + } + + l = MALLOC((len-1+1) * sizeof(char *)); + if (!l) { + return(NULL); + } + for (intmax_t i=0;i < index;i++) { + l[i] = *((*list)+i); + } + for (intmax_t i=index ; i < len-1 ; i++) { + l[i] = *((*list)+1+i); + } + l[len-1] = NULL; + + free(*list); + *list = l; + return(l); +} + + +/** * print list elements * to stdout * 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 "1.2.4" +#define LIBSHEEPY_VERSION "1.2.5" #ifndef SH_PREFIX #define SH_PREFIX(NAME) NAME @@ -155,12 +155,36 @@ extern const bool FALSE; ) /** - * log string with logC and exit with failure + * log formated string with logP and exit with success * * This is useful to know at which line a program exits + * The format string is printed as given, "Success" is not added unlike + * logXSuccess */ +#define logXSuccessf(format, ...) MACRO(\ + logP(format, __VA_ARGS__);\ + XSuccess;\ + ) + + /** +- * log string with logC and exit with failure + * + * This is useful to know at which line a program exits + */ #define logXFailure(string) MACRO(\ logC("Failed: %s", string);\ + XFailure;\ + ) + +/** + * log formated string with logC and exit with failure + * + * This is useful to know at which line a program exits + * The format string is printed as given, "Failed" is not added unlike + * logXFailure + */ +#define logXFailuref(format, ...) MACRO(\ + logC(format, __VA_ARGS__);\ XFailure;\ ) @@ -2599,10 +2623,12 @@ char **iListInjectCharS(char ***list, intmax_t index, char toInject); // del - python style indexes 0..len-1 -1..-len+1 char **listDelS(char **list, intmax_t start, intmax_t end); char **iListDelS(char ***list, intmax_t start, intmax_t end); +char **iListRemoveS(char ***list, intmax_t start, intmax_t end); // del element in list char **listDelElemS(char **list, intmax_t index); char **iListDelElemS(char ***list, intmax_t index); +char **iListRemoveElemS(char ***list, intmax_t index); // print list int listPrintS(char **list); @@ -3135,6 +3161,7 @@ void **iListInsert(void ***list, intmax_t index, void **toInsert); // del - python style indexes 0..len-1 -1..-len+1 void **listDel(void **list, intmax_t start, intmax_t end); void **iListDel(void ***list, intmax_t start, intmax_t end); +//NOT NEEDED same as iListDel - void **iListRemove(void ***list, intmax_t start, intmax_t end); // duplicate and sort //TODO void **listSort(void **list); diff --git a/release/libsheepyObject.h b/release/libsheepyObject.h @@ -2912,6 +2912,62 @@ void finishManyOF(void *paramType, ...); char ***: iListDelElemS \ )(self, index) +#define removeO(self, start, end) (self)->f->remove(self, start, end) +#define removeG(self, start, end) _Generic((self), \ + smallDictt*: _Generic(start, \ + char *: removeSmallDictG, \ + const char *: removeSmallDictG, \ + char: removeKCharSmallDictG, \ + int: removeKCharSmallDictG, \ + default: removeSmallDictG \ + ), \ + smallJsont*: _Generic(start, \ + char *: removeKeySmallJsonG, \ + const char *: removeKeySmallJsonG, \ + int64_t: removeSmallJsonG, \ + int32_t: removeSmallJsonG, \ + int16_t: removeSmallJsonG, \ + int8_t: removeSmallJsonG, \ + uint64_t: removeSmallJsonG, \ + uint32_t: removeSmallJsonG, \ + uint16_t: removeSmallJsonG, \ + uint8_t: removeSmallJsonG, \ + default: removeSmallJsonG \ + ), \ + smallArrayt*: removeSmallArrayG, \ + smallStringt*: delSmallStringG, \ + char **: iDelS, \ + char ***: iListRemoveS \ + )(self, start, end) + +#define removeElemO(self, index) (self)->f->removeElem(self, index) +#define removeElemG(self, index) _Generic((self), \ + smallDictt*: _Generic(index, \ + char *: removeElemSmallDictG, \ + const char *: removeElemSmallDictG, \ + char: removeElemKCharSmallDictG, \ + int: removeElemKCharSmallDictG, \ + default: removeElemSmallDictG \ + ), \ + smallJsont*: _Generic(index, \ + char *: removeElemSmallJsonG, \ + const char *: removeElemSmallJsonG, \ + int64_t: removeElemIndexSmallJsonG, \ + int32_t: removeElemIndexSmallJsonG, \ + int16_t: removeElemIndexSmallJsonG, \ + int8_t: removeElemIndexSmallJsonG, \ + uint64_t: removeElemIndexSmallJsonG, \ + uint32_t: removeElemIndexSmallJsonG, \ + uint16_t: removeElemIndexSmallJsonG, \ + uint8_t: removeElemIndexSmallJsonG, \ + default: removeElemSmallJsonG \ + ), \ + smallArrayt*: removeElemSmallArrayG, \ + smallStringt*: delElemSmallStringG, \ + char **: iDelElemS, \ + char ***: iListRemoveElemS \ + )(self, index) + #define popO(self) (self)->f->pop(self) #define popG(self, returnType) _Generic((self), \ smallArrayt*: _Generic((returnType), \ @@ -8367,6 +8423,9 @@ void finishManyOF(void *paramType, ...); #define delKCharO(self, key) (self)->f->delKChar(self, key) #define delKCharG delKCharO +#define removeKCharO(self, key) (self)->f->removeKChar(self, key) +#define removeKCharG removeKCharO + #define hasKCharO(self, key) (self)->f->hasKChar(self, key) #define hasKCharG hasKCharO @@ -9111,6 +9170,9 @@ void finishManyOF(void *paramType, ...); #define delElemIndexO(self, index) (self)->f->delElemIndex(self, index) #define delElemIndexG delElemIndexO +#define removeElemIndexO(self, index) (self)->f->removeElemIndex(self, index) +#define removeElemIndexG removeElemIndexO + #define stringifyO(self, indent) (self)->f->stringify(self, indent) #define stringifyG stringifyO diff --git a/src/json/libsheepyCSmallArray.c b/src/json/libsheepyCSmallArray.c @@ -242,6 +242,8 @@ internal smallArrayt* injectNFreeSmallStringSmallArray(smallArrayt *self, intmax internal smallArrayt* injectNFreeSmallContainerSmallArray(smallArrayt *self, intmax_t index, smallContainert *toInject); internal smallArrayt* delSmallArray(smallArrayt *self, intmax_t start, intmax_t end); internal smallArrayt* delElemSmallArray(smallArrayt *self, intmax_t index); +internal smallArrayt* removeSmallArray(smallArrayt *self, intmax_t start, intmax_t end); +internal smallArrayt* removeElemSmallArray(smallArrayt *self, intmax_t index); internal int sortSCmp(const void * a, const void * b); internal smallArrayt* sortSmallArray(smallArrayt *self); #if (__APPLE__ || __FreeBSD__ || __DragonFly__) @@ -762,6 +764,8 @@ smallArrayt* injectNFreeSmallStringSmallArrayG (smallArrayt *self, intmax_t in smallArrayt* injectNFreeSmallContainerSmallArrayG(smallArrayt *self, intmax_t index, smallContainert *container); smallArrayt* delSmallArrayG (smallArrayt *self, intmax_t start, intmax_t end); smallArrayt* delElemSmallArrayG (smallArrayt *self, intmax_t index); +smallArrayt* removeSmallArrayG (smallArrayt *self, intmax_t start, intmax_t end); +smallArrayt* removeElemSmallArrayG (smallArrayt *self, intmax_t index); smallArrayt* sortSmallArrayG (smallArrayt *self); smallArrayt* sortFSmallArrayG(smallArrayt *self, shCmpt compareFunction); smallArrayt* icSortSmallArrayG (smallArrayt *self); @@ -1155,6 +1159,8 @@ void registerMethodsSmallArray(smallArrayFunctionst *f) { f->injectNFreeSmallContainer = injectNFreeSmallContainerSmallArray; f->del = delSmallArray; f->delElem = delElemSmallArray; + f->remove = removeSmallArray; + f->removeElem = removeElemSmallArray; f->sort = sortSmallArray; f->sortF = sortFSmallArray; f->icSort = icSortSmallArray; @@ -5611,6 +5617,69 @@ internal smallArrayt* delElemSmallArray(smallArrayt *self, intmax_t index) { return(self); } +internal smallArrayt* removeSmallArray(smallArrayt *self, intmax_t start, intmax_t end) { + size_t len;; + + len = lenSmallArray(self); + + // sanity checks + if (len == 0) { + return(NULL); + } + + if (start >= (intmax_t)len) { + start = len; + } + if (end > (intmax_t)len) { + end = len; + } + if (start <= -(intmax_t)len) { + start = -len; + } + if (end <= -(intmax_t)len) { + end = -len; + } + if (start < 0) { + start = len + start; + } + if (end <= 0) { + end = len + end; + } + if (end < start) { + return(NULL); + } + + if (start == end) { + return(self); + } + + // start < end < len + for (uint32_t i = start ; i < end ; i++) { + sArraySetShortTiny(self->a, i, NULL); + } + + return(self); +} + +internal smallArrayt* removeElemSmallArray(smallArrayt *self, intmax_t index) { + size_t len;; + + len = lenSmallArray(self); + + if (index >= (intmax_t)len) { + return(NULL); + } + if (index < -(intmax_t)len) { + return(NULL); + } + if (index < 0) { + index = len + index; + } + + sArraySetShortTiny(self->a, index, NULL); + return(self); +} + internal int sortSCmp(const void * a, const void * b) { // sanity checks @@ -12423,6 +12492,16 @@ smallArrayt* delElemSmallArrayG (smallArrayt *self, intmax_t index) { return(self->f->delElem(self, index)); } +smallArrayt* removeSmallArrayG (smallArrayt *self, intmax_t start, intmax_t end) { + + return(self->f->remove(self, start, end)); +} + +smallArrayt* removeElemSmallArrayG (smallArrayt *self, intmax_t index) { + + return(self->f->removeElem(self, index)); +} + smallArrayt* sortSmallArrayG (smallArrayt *self) { return(self->f->sort(self)); diff --git a/src/json/libsheepyCSmallArray.h b/src/json/libsheepyCSmallArray.h @@ -623,6 +623,42 @@ typedef smallArrayt* (*delSmallArrayFt) (smallArrayt *self, intma typedef smallArrayt* (*delElemSmallArrayFt) (smallArrayt *self, intmax_t index); /** + * remove without freeing elements from start and end in self + * negative indexes are allowed + * + * \param + * start index, must be in the array + * end index, must be in the array + * \return + * sliced array + * array copy when start=end or when start and end are not set correctly + * NULL when array is empty + * NULL when array is NULL or when end is under start + * 0 success + * -1 error + */ +typedef smallArrayt* (*removeSmallArrayFt) (smallArrayt *self, intmax_t start, intmax_t end); + +/** + * remove without freeing element + * + * remove without freeing element sObject at index + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallArray(a); + * // set an object shared with another container in the array a + * // "sString object" is in both container S and a + * pushG(a, S); + * pushG(a, "another string"); + * // the program deletes element 0 in array a + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(a, 0); + */ +typedef smallArrayt* (*removeElemSmallArrayFt) (smallArrayt *self, intmax_t index); + +/** * sort self in alphabetic order * * \return @@ -1544,6 +1580,8 @@ typedef bool (*areAllEBytesSmallArrayFt) (smallArrayt *self); injectNFreeSmallContainerSmallArrayFt injectNFreeSmallContainer;\ delSmallArrayFt del;\ delElemSmallArrayFt delElem;\ + removeSmallArrayFt remove;\ + removeElemSmallArrayFt removeElem;\ sortSmallArrayFt sort;\ sortFSmallArrayFt sortF;\ icSortSmallArrayFt icSort;\ @@ -2193,6 +2231,8 @@ smallArrayt* injectNFreeSmallContainerSmallArrayG(smallArrayt *self, intmax_t in smallArrayt* delSmallArrayG (smallArrayt *self, intmax_t start, intmax_t end); smallArrayt* delElemSmallArrayG (smallArrayt *self, intmax_t index); +smallArrayt* removeSmallArrayG (smallArrayt *self, intmax_t start, intmax_t end); +smallArrayt* removeElemSmallArrayG (smallArrayt *self, intmax_t index); smallArrayt* sortSmallArrayG (smallArrayt *self); smallArrayt* sortFSmallArrayG (smallArrayt *self, shCmpt compareFunction); smallArrayt* icSortSmallArrayG (smallArrayt *self); diff --git a/src/json/libsheepyCSmallDict.c b/src/json/libsheepyCSmallDict.c @@ -247,6 +247,8 @@ internal void* cropElemVoidSmallDict(smallDictt *self, char* key); internal smallContainert* cropElemSmallContainerSmallDict(smallDictt *self, char* key); internal smallDictt* delSmallDict(smallDictt *self, const char *key); internal smallDictt* delKCharSmallDict(smallDictt *self, char key); +internal smallDictt* removeSmallDict(smallDictt *self, const char *key); +internal smallDictt* removeKCharSmallDict(smallDictt *self, char key); internal bool hasSmallDict(smallDictt *self, const char *key); internal bool hasKCharSmallDict(smallDictt *self, char key); internal char* keyBySmallDict(smallDictt *self, baset *value); @@ -551,6 +553,10 @@ smallDictt* delSmallDictG (smallDictt *self, const char *key, int unused smallDictt* delKCharSmallDictG (smallDictt *self, char key, int unused UNUSED); smallDictt* delElemSmallDictG (smallDictt *self, const char *key); smallDictt* delElemKCharSmallDictG(smallDictt *self, char key); +smallDictt* removeSmallDictG (smallDictt *self, const char *key, int unused UNUSED); +smallDictt* removeKCharSmallDictG (smallDictt *self, char key, int unused UNUSED); +smallDictt* removeElemSmallDictG (smallDictt *self, const char *key); +smallDictt* removeElemKCharSmallDictG(smallDictt *self, char key); bool hasSmallDictG (smallDictt *self, const char *key); bool hasKCharSmallDictG (smallDictt *self, char key); char* keyBySmallDictG(smallDictt *self, baset *value); @@ -830,6 +836,8 @@ void registerMethodsSmallDict(smallDictFunctionst *f) { f->cropElemSmallContainer = cropElemSmallContainerSmallDict; f->del = delSmallDict; f->delKChar = delKCharSmallDict; + f->remove = removeSmallDict; + f->removeKChar = removeKCharSmallDict; f->has = hasSmallDict; f->hasKChar = hasKCharSmallDict; f->keyBy = keyBySmallDict; @@ -3418,6 +3426,25 @@ internal smallDictt* delKCharSmallDict(smallDictt *self, char key) { return(delSmallDict(self, s)); } +internal smallDictt* removeSmallDict(smallDictt *self, const char *key) { + + if (key && self->d) { + forEachSDict(self->d, e) { + if (e->key && eqS(key, e->key)) { + e->key = NULL; + break; + } + } + } + return(self); +} + +internal smallDictt* removeKCharSmallDict(smallDictt *self, char key) { + + charToS(s, key); + return(removeSmallDict(self, s)); +} + internal bool hasSmallDict(smallDictt *self, const char *key) { if (!key) { @@ -6377,6 +6404,26 @@ smallDictt* delElemKCharSmallDictG(smallDictt *self, char key) { return(self->f->delKChar(self, key)); } +smallDictt* removeSmallDictG (smallDictt *self, const char *key, int unused UNUSED) { + + return(self->f->remove(self,key)); +} + +smallDictt* removeKCharSmallDictG (smallDictt *self, char key, int unused UNUSED) { + + return(self->f->removeKChar(self, key)); +} + +smallDictt* removeElemSmallDictG (smallDictt *self, const char *key) { + + return(self->f->remove(self,key)); +} + +smallDictt* removeElemKCharSmallDictG(smallDictt *self, char key) { + + return(self->f->removeKChar(self, key)); +} + bool hasSmallDictG (smallDictt *self, const char *key) { return(self->f->has(self, key)); diff --git a/src/json/libsheepyCSmallDict.h b/src/json/libsheepyCSmallDict.h @@ -402,6 +402,29 @@ typedef smallContainert* (*cropElemSmallContainerSmallDictFt) (smallDictt *self, typedef smallDictt* (*delSmallDictFt) (smallDictt *self, const char *key); typedef smallDictt* (*delKCharSmallDictFt) (smallDictt *self, char key); +/** + * remove without freeing element + * + * remove element sObject for given key + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallDict(d); + * // set an object shared with another container in the dict d + * // "sString object" is in both container S and d + * setG(d, "key1" ,S); + * setG(d, "key2", "another string"); + * // the program deletes the element for "key1" + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(d, "key1"); + * + * \param + * key smallDictionary key + */ +typedef smallDictt* (*removeSmallDictFt) (smallDictt *self, const char *key); +typedef smallDictt* (*removeKCharSmallDictFt) (smallDictt *self, char key); + /** * check if self has 'key' @@ -901,6 +924,8 @@ typedef bool (*areAllEBytesSmallDictFt) (smallDictt *self); cropElemSmallContainerSmallDictFt cropElemSmallContainer;\ delSmallDictFt del;\ delKCharSmallDictFt delKChar;\ + removeSmallDictFt remove;\ + removeKCharSmallDictFt removeKChar;\ hasSmallDictFt has;\ hasKCharSmallDictFt hasKChar;\ keyBySmallDictFt keyBy;\ @@ -1345,6 +1370,10 @@ smallDictt* delSmallDictG (smallDictt *self, const char *key, int unused smallDictt* delKCharSmallDictG (smallDictt *self, char key, int unused UNUSED); smallDictt* delElemSmallDictG (smallDictt *self, const char *key); smallDictt* delElemKCharSmallDictG(smallDictt *self, char key); +smallDictt* removeSmallDictG (smallDictt *self, const char *key, int unused UNUSED); +smallDictt* removeKCharSmallDictG (smallDictt *self, char key, int unused UNUSED); +smallDictt* removeElemSmallDictG (smallDictt *self, const char *key); +smallDictt* removeElemKCharSmallDictG(smallDictt *self, char key); bool hasSmallDictG (smallDictt *self, const char *key); bool hasKCharSmallDictG (smallDictt *self, char key); char* keyBySmallDictG(smallDictt *self, baset *value); diff --git a/src/json/libsheepyCSmallJson.c b/src/json/libsheepyCSmallJson.c @@ -819,6 +819,9 @@ internal double getNumAtSmallJson(smallJsont *self, intmax_t index); internal smallJsont* delElemSmallJson(smallJsont *self, const char *key); internal smallJsont* delSmallJson(smallJsont *self, intmax_t start, intmax_t end); internal smallJsont* delElemIndexSmallJson(smallJsont *self, intmax_t index); +internal smallJsont* removeElemSmallJson(smallJsont *self, const char *key); +internal smallJsont* removeSmallJson(smallJsont *self, intmax_t start, intmax_t end); +internal smallJsont* removeElemIndexSmallJson(smallJsont *self, intmax_t index); internal char** sDictStringifyForeach(sDictElemt *e, char *indentS2, int indent, int level); internal char** sDictStringify(sDictt *dict, int indent, int level); internal char** sArrayStringify(sArrayt *array, int indent, int level); @@ -1949,6 +1952,9 @@ void registerMethodsSmallJson(smallJsonFunctionst *f) { f->delElem = delElemSmallJson; f->del = delSmallJson; f->delElemIndex = delElemIndexSmallJson; + f->removeElem = removeElemSmallJson; + f->remove = removeSmallJson; + f->removeElemIndex = removeElemIndexSmallJson; f->push = pushSmallJson; f->pushUndefined = pushUndefinedSmallJson; f->pushBool = pushBoolSmallJson; @@ -20337,6 +20343,168 @@ internal smallJsont* delElemIndexSmallJson(smallJsont *self, intmax_t index) { return(self); } +internal smallJsont* removeElemSmallJson(smallJsont *self, const char *key) { + + removeJsonPath; + return(self); +} + +internal smallJsont* removeSmallJson(smallJsont *self, intmax_t start, intmax_t end) { + size_t len; + + switch(self->topIsA) { + case TOP_IS_STRING: + ;char *s; + + len = lenSmallJson(self); + + // sanity checks + if (!self->topS || !len) { + return(NULL); + } + + if (start >= (intmax_t)len) { + start = len; + } + if (end > (intmax_t)len) { + end = len; + } + if (start <= -(intmax_t)len) { + start = -len; + } + if (end <= -(intmax_t)len) { + end = -len; + } + if (start < 0) { + start = len + start; + } + if (end <= 0) { + end = len + end; + } + if (end < start) { + return(NULL); + } + + if (start == end) { + return(self); + } + + // start < end < len + // copy range to a new smallString + intmax_t n; + n = end - start; + // +2 for sType at the beginning + s = malloc(len - n +2); + if (!s) { + return(NULL); + } + // +1 for sType + strncpy(s, (char *)self->topS, start+1); + strncpy(s+start+1, (char *)self->topS + end +1, len - end); + s[len - n +1] = 0; + + free(self->topS); + self->topS = (sStringt *)s; + return(self); + case TOP_IS_ARRAY: + len = lenSmallJson(self); + + // sanity checks + if (len == 0) { + return(NULL); + } + + if (start >= (intmax_t)len) { + start = len; + } + if (end > (intmax_t)len) { + end = len; + } + if (start <= -(intmax_t)len) { + start = -len; + } + if (end <= -(intmax_t)len) { + end = -len; + } + if (start < 0) { + start = len + start; + } + if (end <= 0) { + end = len + end; + } + if (end < start) { + return(NULL); + } + + if (start == end) { + return(self); + } + + // start < end < len + for (uint32_t i = start ; i < end ; i++) { + sArraySetShortTiny(self->topA, i, NULL); + } + return(self); + default: + return(self); + } + return(self); +} + +internal smallJsont* removeElemIndexSmallJson(smallJsont *self, intmax_t index) { + size_t len; + + switch(self->topIsA) { + case TOP_IS_STRING: + ;char *s; + + len = lenSmallJson(self); + + if (index >= (intmax_t)len) { + return(NULL); + } + if (index < -(intmax_t)len) { + return(NULL); + } + if (index < 0) { + index = len + index; + } + + // copy range to a new smallString + // +2 for sType at the beginning + s = malloc(len - 1 +2); + if (!s) { + return(NULL); + } + // +1 for sType + strncpy(s, (char *)self->topS, index+1); + strncpy(s+index+1, (char *)self->topS + index+1 +1, len - (index+1)); + s[len - 1 +1] = 0; + + free(self->topS); + self->topS = (sStringt *)s; + return(self); + case TOP_IS_ARRAY: + len = lenSmallJson(self); + + if (index >= (intmax_t)len) { + return(NULL); + } + if (index < -(intmax_t)len) { + return(NULL); + } + if (index < 0) { + index = len + index; + } + + sArraySetShortTiny(self->topA, index, NULL); + return(self); + default: + return(self); + } + return(self); +} + internal char** sDictStringifyForeach(sDictElemt *e, char *indentS2, int indent, int level) { char *line = NULL; diff --git a/src/json/libsheepyCSmallJson.h b/src/json/libsheepyCSmallJson.h @@ -717,6 +717,64 @@ typedef smallJsont* (*delSmallJsonFt) (smallJsont *self, i typedef smallJsont* (*delElemIndexSmallJsonFt) (smallJsont *self, intmax_t index); /** + * remove without freeing element + * + * remove element sObject for given key + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallJson(d); + * // set an object shared with another container in the json d + * // "sString object" is in both container S and d + * setG(d, "key1" ,S); + * setG(d, "key2", "another string"); + * // the program deletes the element for "key1" + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(d, "key1"); + * + * \param + * key smallDictionary key + */ +typedef smallJsont* (*removeElemSmallJsonFt) (smallJsont *self, const char *key); + +/** + * remove without freeing elements from start and end in self + * negative indexes are allowed + * + * \param + * start index, must be in the array + * end index, must be in the array + * \return + * sliced array + * array copy when start=end or when start and end are not set correctly + * NULL when array is empty + * NULL when array is NULL or when end is under start + * 0 success + * -1 error + */ +typedef smallJsont* (*removeSmallJsonFt) (smallJsont *self, intmax_t start, intmax_t end); + +/** + * remove without freeing element + * + * remove element sObject at index + * + * Example: + * cleanAllocateSmallString(S); + * setValG(S, "sString object"); + * cleanAllocateSmallJson(a); + * // set an object shared with another container in the json a + * // "sString object" is in both container S and a + * pushG(a, S); + * pushG(a, "another string"); + * // the program deletes element 0 in json a + * // to do so, it uses removeElemG since S will free the sString object + * removeElemG(a, 0); + */ +typedef smallJsont* (*removeElemIndexSmallJsonFt) (smallJsont *self, intmax_t index); + + /** * push value to json * * When the sObject pointer is updated by realloc, the sObject @@ -2771,6 +2829,9 @@ typedef bool (*areAllEBytesSmallJsonFt) (smallJsont *self); delElemSmallJsonFt delElem;\ delSmallJsonFt del;\ delElemIndexSmallJsonFt delElemIndex;\ + removeElemSmallJsonFt removeElem;\ + removeSmallJsonFt remove;\ + removeElemIndexSmallJsonFt removeElemIndex;\ pushSmallJsonFt push;\ pushUndefinedSmallJsonFt pushUndefined;\ pushBoolSmallJsonFt pushBool;\ @@ -3780,6 +3841,10 @@ smallJsont* delKeySmallJsonG (smallJsont *self, const char *k smallJsont* delElemSmallJsonG (smallJsont *self, const char *key); smallJsont* delSmallJsonG (smallJsont *self, intmax_t start, intmax_t end); smallJsont* delElemIndexSmallJsonG (smallJsont *self, intmax_t index); +smallJsont* removeKeySmallJsonG (smallJsont *self, const char *key, int unused UNUSED); +smallJsont* removeElemSmallJsonG (smallJsont *self, const char *key); +smallJsont* removeSmallJsonG (smallJsont *self, intmax_t start, intmax_t end); +smallJsont* removeElemIndexSmallJsonG (smallJsont *self, intmax_t index); smallJsont* prependSmallJsonG (smallJsont *self, baset *value); smallJsont* prependUndefinedSmallJsonG(smallJsont *self, void *value UNUSED); diff --git a/src/json/libsheepyCSmallJsonInternal.h b/src/json/libsheepyCSmallJsonInternal.h @@ -142,6 +142,9 @@ declareRecycle(smallJsont); #define delJsonPath\ walkJsonPath(if (!oo) {free(keyInPath);return NULL;}/*getSmallObj*/, if (!*a) {free(keyInPath);return NULL;} sArrayDelTiny(*a, idx)/*arrayCode*/, if (!*d) {free(keyInPath);return NULL;} sDictDelTiny(*d, keyInPath)/*dictCode*/, if (!self->top) return NULL/*returnFail*/, sDictDelTiny(self->top, key) ; return self/*directHit*/, return NULL/*keyErrorReturn*/) +#define removeJsonPath\ + walkJsonPath(if (!oo) {free(keyInPath);return NULL;}/*getSmallObj*/, if (!*a) {free(keyInPath);return NULL;} sArraySetShortTiny(*a, idx, NULL)/*arrayCode*/, if (!*d) {free(keyInPath);return NULL;} forEachSDict(*d, e) {if (e->key && eqS(keyInPath, e->key)) { e->key = NULL; break;} }/*dictCode*/, if (!self->top) return NULL/*returnFail*/, forEachSDict(self->top, e) {if (e->key && eqS(key, e->key)) { e->key = NULL; break;} } ; return self/*directHit*/, return NULL/*keyErrorReturn*/) + #define typeStringJsonPath\ walkJsonPath(if (!oo) {free(keyInPath);return NULL;}/*getSmallObj*/, if (!*a) {free(keyInPath);return NULL;} o = sArrayGetTiny(*a, idx)/*arrayCode*/, if (!*d) {free(keyInPath);return NULL;} o = sDictGetTiny(*d, keyInPath)/*dictCode*/, if (!self->top) return NULL/*returnFail*/, o = sDictGet(self->top, key) ; if (!o) return NULL; return SMALL_TYPE_NAMES[(size_t)o->type]/*directHit*/, return NULL/*keyErrorReturn*/) diff --git a/src/libsheepy.c b/src/libsheepy.c @@ -660,8 +660,10 @@ char **iListInjectS(char ***list, intmax_t index, char *toInject); char **iListInjectCharS(char ***list, intmax_t index, char toInject); char **listDelS(char **list, intmax_t start, intmax_t end); char **iListDelS(char ***list, intmax_t start, intmax_t end); +char **iListRemoveS(char ***list, intmax_t start, intmax_t end); char **listDelElemS(char **list, intmax_t index); char **iListDelElemS(char ***list, intmax_t index); +char **iListRemoveElemS(char ***list, intmax_t index); int listPrintS(char **list); internal int listSortSCmp(const void * a, const void * b); char **listSortS(char **list); @@ -51810,6 +51812,86 @@ char **iListDelS(char ***list, intmax_t start, intmax_t end) { } /** + * list Remove String + * return list without elements from start and end in list + * the elements are removed without being freed + * negative indexes are allowed + * + * \param + * list (this parameter is reallocated) + * \param + * start index, must be in the list + * \param + * end index, must be in the list + * \return + * sliced list (you must free the pointer with listFreeS or free) + * list copy when start=end or when start and end are not set correctly + * NULL when list is empty + * NULL when list is NULL or when end is under start + * NULL error + */ +char **iListRemoveS(char ***list, intmax_t start, intmax_t end) { + char **l = NULL; + intmax_t len; + + // sanity checks + if (!list || !*list) { + return(NULL); + } + + len = listLengthS(*list); + + if (len == 0) { + return(NULL); + } + + if (start >= len) { + start = len; + } + if (end > len) { + end = len; + } + if (start <= -len) { + start = -len; + } + if (end <= -len) { + end = -len; + } + if (start < 0) { + start = len + start; + } + if (end <= 0) { + end = len + end; + } + if (end < start) { + return(NULL); + } + + if (start == end) { + return(*list); + } + + // start < end < len + intmax_t n; + n = end - start; + l = MALLOC((len-n+1) * sizeof(char *)); + if (!l) { + return(NULL); + } + for (intmax_t i=0;i < start;i++) { + l[i] = *((*list)+i); + } + for (intmax_t i=start ; i < len-n ; i++) { + l[i] = *((*list)+n+i); + } + l[len-n] = NULL; + + free(*list); + *list = l; + return(l); +} + +/** * list Delete Element String * return new list without the element at index * negative indexes are allowed @@ -51923,6 +52005,65 @@ char **iListDelElemS(char ***list, intmax_t index) { /** + * list Remove Element String + * return list without the element at index + * the element is removed without being freed + * negative indexes are allowed + * + * \param + * list (this parameter is reallocated) + * \param + * index must be in the list + * \return + * new list without the element at index (you must free the pointer with listFreeS) + * NULL when list is empty + * NULL when list is NULL + * NULL error + */ +char **iListRemoveElemS(char ***list, intmax_t index) { + char **l = NULL; + intmax_t len; + + // sanity checks + if (!list || !*list) { + return(NULL); + } + + len = listLengthS(*list); + + if (len == 0) { + return(NULL); + } + + if (index >= len) { + return(NULL); + } + if (index < -len) { + return(NULL); + } + if (index < 0) { + index = len + index; + } + + l = MALLOC((len-1+1) * sizeof(char *)); + if (!l) { + return(NULL); + } + for (intmax_t i=0;i < index;i++) { + l[i] = *((*list)+i); + } + for (intmax_t i=index ; i < len-1 ; i++) { + l[i] = *((*list)+1+i); + } + l[len-1] = NULL; + + free(*list); + *list = l; + return(l); +} + + +/** * print list elements * to stdout * @@ -55290,7 +55431,7 @@ int MAIN(int ARGC, char** ARGV) { sliceEnumerate(&slc, i, elm) { elm->a = 0;; elm->b = 0;; - printf("sliceEnumerate %d\n", i); + printf("sliceEnumerate %zd\n", i); } sliceFree(&slc); @@ -55394,8 +55535,8 @@ int MAIN(int ARGC, char** ARGV) { sslicet sslce; staticSliceInit(&sslce); staticSlicePush(&sslce); - staticSliceForEach(&sslce, S) S = NULL;; - staticSliceEnumerate(&sslce, iS, S) S = NULL;; + //staticSliceForEach(&sslce, S UNUSED) S = NULL; + //staticSliceEnumerate(&sslce, iS, S UNUSED) S = NULL; //staticSliceElemType(&sslce) sslEl; @@ -55416,8 +55557,8 @@ int MAIN(int ARGC, char** ARGV) { vectorAppend(&vec, "qwe"); vectorAppend(&vec, "2345"); - vectorForEach(&vec, S) S = NULL;; - vectorEnumerate(&vec, iv, S) S = NULL;; + //vectorForEach(&vec, S UNUSED) S = NULL; + //vectorEnumerate(&vec, iv, S) S = NULL; logVar(vectorMaxCount(&vec), "zu"); logVar(vectorCount(&vec), "zu"); @@ -55469,8 +55610,8 @@ int MAIN(int ARGC, char** ARGV) { dVectorInit(&dvec); //dVectorElemType(&dvec) dvecE; - dVectorForEach(&dvec, S) S = NULL;; - dVectorEnumerate(&dvec, idv, S) S = NULL;; + //dVectorForEach(&dvec, S UNUSED) S = NULL; + //dVectorEnumerate(&dvec, idv, S UNUSED) S = NULL; XSUCCESS @@ -55652,8 +55793,8 @@ int MAIN(int ARGC, char** ARGV) { staticArrayLast($) = i;; } - staticArrayForEach($, S) S = 0;; - staticArrayEnumerate($, isa, S) S = 0;; + //staticArrayForEach($, S UNUSED) S = 0; + //staticArrayEnumerate($, isa, S UNUSED) S = 0; rangeInf(i) { puts("infinity"); @@ -55709,8 +55850,8 @@ int MAIN(int ARGC, char** ARGV) { slabAppend(&b, 1); slabAppend(&b, 2); - slabForEach(&b, S) S = 0;; - slabEnumerate(&b, isl, S) S = 0;; + //slabForEach(&b, S UNUSED) S = 0; + //slabEnumerate(&b, isl, S UNUSED) S = 0; printf("size %d\n", slabSz); @@ -55753,9 +55894,9 @@ int MAIN(int ARGC, char** ARGV) { timeUs(loghex(a, 10)); - intDynt bbb; - dArrayForEach(&bbb, S) S = 0;; - dArrayEnumerate(&bbb, ida, S) S = 0;; + intDynt bbb UNUSED; + //dArrayForEach(&bbb, S UNUSED) S = 0; + //dArrayEnumerate(&bbb, ida, S UNUSED) S = 0; //dArrayElemType(&bbb) bbbE; /* intDynt 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 "1.2.4" +#define LIBSHEEPY_VERSION "1.2.5" #ifndef SH_PREFIX #define SH_PREFIX(NAME) NAME @@ -155,12 +155,36 @@ extern const bool FALSE; ) /** - * log string with logC and exit with failure + * log formated string with logP and exit with success * * This is useful to know at which line a program exits + * The format string is printed as given, "Success" is not added unlike + * logXSuccess */ +#define logXSuccessf(format, ...) MACRO(\ + logP(format, __VA_ARGS__);\ + XSuccess;\ + ) + + /** +- * log string with logC and exit with failure + * + * This is useful to know at which line a program exits + */ #define logXFailure(string) MACRO(\ logC("Failed: %s", string);\ + XFailure;\ + ) + +/** + * log formated string with logC and exit with failure + * + * This is useful to know at which line a program exits + * The format string is printed as given, "Failed" is not added unlike + * logXFailure + */ +#define logXFailuref(format, ...) MACRO(\ + logC(format, __VA_ARGS__);\ XFailure;\ ) @@ -2599,10 +2623,12 @@ char **iListInjectCharS(char ***list, intmax_t index, char toInject); // del - python style indexes 0..len-1 -1..-len+1 char **listDelS(char **list, intmax_t start, intmax_t end); char **iListDelS(char ***list, intmax_t start, intmax_t end); +char **iListRemoveS(char ***list, intmax_t start, intmax_t end); // del element in list char **listDelElemS(char **list, intmax_t index); char **iListDelElemS(char ***list, intmax_t index); +char **iListRemoveElemS(char ***list, intmax_t index); // print list int listPrintS(char **list); @@ -3135,6 +3161,7 @@ void **iListInsert(void ***list, intmax_t index, void **toInsert); // del - python style indexes 0..len-1 -1..-len+1 void **listDel(void **list, intmax_t start, intmax_t end); void **iListDel(void ***list, intmax_t start, intmax_t end); +//NOT NEEDED same as iListDel - void **iListRemove(void ***list, intmax_t start, intmax_t end); // duplicate and sort //TODO void **listSort(void **list); diff --git a/src/libsheepyObject.h b/src/libsheepyObject.h @@ -2912,6 +2912,62 @@ void finishManyOF(void *paramType, ...); char ***: iListDelElemS \ )(self, index) +#define removeO(self, start, end) (self)->f->remove(self, start, end) +#define removeG(self, start, end) _Generic((self), \ + smallDictt*: _Generic(start, \ + char *: removeSmallDictG, \ + const char *: removeSmallDictG, \ + char: removeKCharSmallDictG, \ + int: removeKCharSmallDictG, \ + default: removeSmallDictG \ + ), \ + smallJsont*: _Generic(start, \ + char *: removeKeySmallJsonG, \ + const char *: removeKeySmallJsonG, \ + int64_t: removeSmallJsonG, \ + int32_t: removeSmallJsonG, \ + int16_t: removeSmallJsonG, \ + int8_t: removeSmallJsonG, \ + uint64_t: removeSmallJsonG, \ + uint32_t: removeSmallJsonG, \ + uint16_t: removeSmallJsonG, \ + uint8_t: removeSmallJsonG, \ + default: removeSmallJsonG \ + ), \ + smallArrayt*: removeSmallArrayG, \ + smallStringt*: delSmallStringG, \ + char **: iDelS, \ + char ***: iListRemoveS \ + )(self, start, end) + +#define removeElemO(self, index) (self)->f->removeElem(self, index) +#define removeElemG(self, index) _Generic((self), \ + smallDictt*: _Generic(index, \ + char *: removeElemSmallDictG, \ + const char *: removeElemSmallDictG, \ + char: removeElemKCharSmallDictG, \ + int: removeElemKCharSmallDictG, \ + default: removeElemSmallDictG \ + ), \ + smallJsont*: _Generic(index, \ + char *: removeElemSmallJsonG, \ + const char *: removeElemSmallJsonG, \ + int64_t: removeElemIndexSmallJsonG, \ + int32_t: removeElemIndexSmallJsonG, \ + int16_t: removeElemIndexSmallJsonG, \ + int8_t: removeElemIndexSmallJsonG, \ + uint64_t: removeElemIndexSmallJsonG, \ + uint32_t: removeElemIndexSmallJsonG, \ + uint16_t: removeElemIndexSmallJsonG, \ + uint8_t: removeElemIndexSmallJsonG, \ + default: removeElemSmallJsonG \ + ), \ + smallArrayt*: removeElemSmallArrayG, \ + smallStringt*: delElemSmallStringG, \ + char **: iDelElemS, \ + char ***: iListRemoveElemS \ + )(self, index) + #define popO(self) (self)->f->pop(self) #define popG(self, returnType) _Generic((self), \ smallArrayt*: _Generic((returnType), \ @@ -8367,6 +8423,9 @@ void finishManyOF(void *paramType, ...); #define delKCharO(self, key) (self)->f->delKChar(self, key) #define delKCharG delKCharO +#define removeKCharO(self, key) (self)->f->removeKChar(self, key) +#define removeKCharG removeKCharO + #define hasKCharO(self, key) (self)->f->hasKChar(self, key) #define hasKCharG hasKCharO @@ -9111,6 +9170,9 @@ void finishManyOF(void *paramType, ...); #define delElemIndexO(self, index) (self)->f->delElemIndex(self, index) #define delElemIndexG delElemIndexO +#define removeElemIndexO(self, index) (self)->f->removeElemIndex(self, index) +#define removeElemIndexG removeElemIndexO + #define stringifyO(self, indent) (self)->f->stringify(self, indent) #define stringifyG stringifyO