diff --git a/src/fastfetch.h b/src/fastfetch.h index 90d6aa47c..645bc20d0 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -12,10 +12,7 @@ #include "util/FFstrbuf.h" #include "util/FFlist.h" #include "util/platform/FFPlatform.h" - -static inline void ffUnused(int dummy, ...) { (void) dummy; } -#define FF_UNUSED(...) ffUnused(0, __VA_ARGS__); -#define FF_MAYBE_UNUSED __attribute__ ((__unused__)) +#include "util/unused.h" #include "modules/options.h" #include "logo/option.h" diff --git a/src/util/FFstrbuf.c b/src/util/FFstrbuf.c index 305c28dbb..d714622a4 100644 --- a/src/util/FFstrbuf.c +++ b/src/util/FFstrbuf.c @@ -16,12 +16,6 @@ void ffStrbufInitA(FFstrbuf* strbuf, uint32_t allocate) ffStrbufClear(strbuf); } -void ffStrbufInitCopy(FFstrbuf* strbuf, const FFstrbuf* src) -{ - ffStrbufInitA(strbuf, src->allocated); - ffStrbufAppend(strbuf, src); -} - void ffStrbufInitVF(FFstrbuf* strbuf, const char* format, va_list arguments) { assert(format != NULL); @@ -33,18 +27,9 @@ void ffStrbufInitVF(FFstrbuf* strbuf, const char* format, va_list arguments) strbuf->length = (uint32_t)len; } -uint32_t ffStrbufGetFree(const FFstrbuf* strbuf) -{ - assert(strbuf != NULL); - if(strbuf->allocated == 0) - return 0; - - return strbuf->allocated - strbuf->length - 1; // - 1 for the null byte -} - void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free) { - if(ffStrbufGetFree(strbuf) >= free) + if(ffStrbufGetFree(strbuf) >= free && !(strbuf->allocated == 0 && strbuf->length > 0)) return; uint32_t allocate = strbuf->allocated; @@ -56,8 +41,12 @@ void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free) if(strbuf->allocated == 0) { - strbuf->chars = malloc(sizeof(*strbuf->chars) * allocate); - strbuf->chars[0] = '\0'; + char* newbuf = malloc(sizeof(*strbuf->chars) * allocate); + if(strbuf->length == 0) + *newbuf = '\0'; + else + memcpy(newbuf, strbuf->chars, strbuf->length + 1); + strbuf->chars = newbuf; } else strbuf->chars = realloc(strbuf->chars, sizeof(*strbuf->chars) * allocate); @@ -213,7 +202,7 @@ void ffStrbufSet(FFstrbuf* strbuf, const FFstrbuf* value) void ffStrbufTrimLeft(FFstrbuf* strbuf, char c) { - if(strbuf->length == 0) //`allocated == 0` implies `length == 0` + if(strbuf->length == 0) return; uint32_t index = 0; @@ -223,6 +212,14 @@ void ffStrbufTrimLeft(FFstrbuf* strbuf, char c) if(index == 0) return; + if(strbuf->allocated == 0) + { + //static string + strbuf->length -= index; + strbuf->chars += index; + return; + } + memmove(strbuf->chars, strbuf->chars + index, strbuf->length - index); strbuf->length -= index; strbuf->chars[strbuf->length] = '\0'; @@ -236,13 +233,14 @@ void ffStrbufTrimRight(FFstrbuf* strbuf, char c) while(ffStrbufEndsWithC(strbuf, c)) --strbuf->length; - strbuf->chars[strbuf->length] = '\0'; -} + if(strbuf->allocated == 0) + { + //static string + ffStrbufInitNS(strbuf, strbuf->length, strbuf->chars); + return; + } -void ffStrbufTrim(FFstrbuf* strbuf, char c) -{ - ffStrbufTrimRight(strbuf, c); - ffStrbufTrimLeft(strbuf, c); + strbuf->chars[strbuf->length] = '\0'; } void ffStrbufRemoveSubstr(FFstrbuf* strbuf, uint32_t startIndex, uint32_t endIndex) @@ -256,6 +254,7 @@ void ffStrbufRemoveSubstr(FFstrbuf* strbuf, uint32_t startIndex, uint32_t endInd return; } + ffStrbufEnsureFree(strbuf, 0); memmove(strbuf->chars + startIndex, strbuf->chars + endIndex, strbuf->length - endIndex); strbuf->length -= (endIndex - startIndex); strbuf->chars[strbuf->length] = '\0'; @@ -306,6 +305,10 @@ uint32_t ffStrbufPreviousIndexC(const FFstrbuf* strbuf, uint32_t start, char c) void ffStrbufReplaceAllC(FFstrbuf* strbuf, char find, char replace) { + if (strbuf->length == 0) + return; + + ffStrbufEnsureFree(strbuf, 0); for (char *current_pos = strchr(strbuf->chars, find); current_pos; current_pos = strchr(current_pos + 1, find)) *current_pos = replace; } @@ -315,20 +318,17 @@ void ffStrbufSubstrBefore(FFstrbuf* strbuf, uint32_t index) if(strbuf->length <= index) return; + if(strbuf->allocated == 0) + { + //static string + ffStrbufInitNS(strbuf, strbuf->length, strbuf->chars); + return; + } + strbuf->length = index; strbuf->chars[strbuf->length] = '\0'; } -void ffStrbufSubstrBeforeFirstC(FFstrbuf* strbuf, char c) -{ - ffStrbufSubstrBefore(strbuf, ffStrbufFirstIndexC(strbuf, c)); -} - -void ffStrbufSubstrBeforeLastC(FFstrbuf* strbuf, char c) -{ - ffStrbufSubstrBefore(strbuf, ffStrbufLastIndexC(strbuf, c)); -} - void ffStrbufSubstrAfter(FFstrbuf* strbuf, uint32_t index) { if(index >= strbuf->length) @@ -337,6 +337,14 @@ void ffStrbufSubstrAfter(FFstrbuf* strbuf, uint32_t index) return; } + if(strbuf->allocated == 0) + { + //static string + strbuf->length -= index; + strbuf->chars += index; + return; + } + memmove(strbuf->chars, strbuf->chars + index + 1, strbuf->length - index - 1); strbuf->length -= (index + 1); strbuf->chars[strbuf->length] = '\0'; diff --git a/src/util/FFstrbuf.h b/src/util/FFstrbuf.h index e8d723f9d..d87cad305 100644 --- a/src/util/FFstrbuf.h +++ b/src/util/FFstrbuf.h @@ -30,15 +30,13 @@ typedef struct FFstrbuf static inline void ffStrbufInit(FFstrbuf* strbuf); void ffStrbufInitA(FFstrbuf* strbuf, uint32_t allocate); -void ffStrbufInitCopy(FFstrbuf* __restrict strbuf, const FFstrbuf* __restrict src); void ffStrbufInitVF(FFstrbuf* strbuf, const char* format, va_list arguments); void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free); -FF_C_NODISCARD uint32_t ffStrbufGetFree(const FFstrbuf* strbuf); - void ffStrbufClear(FFstrbuf* strbuf); +static inline void ffStrbufAppend(FFstrbuf* __restrict strbuf, const FFstrbuf* __restrict value); void ffStrbufAppendC(FFstrbuf* strbuf, char c); void ffStrbufAppendNS(FFstrbuf* strbuf, uint32_t length, const char* value); void ffStrbufAppendNSExludingC(FFstrbuf* strbuf, uint32_t length, const char* value, char exclude); @@ -55,7 +53,6 @@ void ffStrbufSetF(FFstrbuf* strbuf, const char* format, ...); void ffStrbufTrimLeft(FFstrbuf* strbuf, char c); void ffStrbufTrimRight(FFstrbuf* strbuf, char c); -void ffStrbufTrim(FFstrbuf* strbuf, char c); void ffStrbufRemoveSubstr(FFstrbuf* strbuf, uint32_t startIndex, uint32_t endIndex); void ffStrbufRemoveS(FFstrbuf* strbuf, const char* str); @@ -69,8 +66,6 @@ FF_C_NODISCARD uint32_t ffStrbufPreviousIndexC(const FFstrbuf* strbuf, uint32_t void ffStrbufReplaceAllC(FFstrbuf* strbuf, char find, char replace); void ffStrbufSubstrBefore(FFstrbuf* strbuf, uint32_t index); -void ffStrbufSubstrBeforeFirstC(FFstrbuf* strbuf, char c); -void ffStrbufSubstrBeforeLastC(FFstrbuf* strbuf, char c); void ffStrbufSubstrAfter(FFstrbuf* strbuf, uint32_t index); void ffStrbufSubstrAfterFirstC(FFstrbuf* strbuf, char c); void ffStrbufSubstrAfterFirstS(FFstrbuf* strbuf, const char* str); @@ -95,6 +90,12 @@ FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateA(uint32_t allocate) return strbuf; } +static inline void ffStrbufInitCopy(FFstrbuf* __restrict strbuf, const FFstrbuf* __restrict src) +{ + ffStrbufInitA(strbuf, src->allocated); + ffStrbufAppend(strbuf, src); +} + FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateCopy(const FFstrbuf* src) { FFstrbuf strbuf; @@ -152,6 +153,32 @@ FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateF(const char* format, ...) return strbuf; } +static inline void ffStrbufDestroy(FFstrbuf* strbuf) +{ + extern char* CHAR_NULL_PTR; + + if(strbuf->allocated == 0) + { + strbuf->length = 0; + strbuf->chars = CHAR_NULL_PTR; + return; + } + + //Avoid free-after-use. These 3 assignments are cheap so don't remove them + strbuf->allocated = strbuf->length = 0; + free(strbuf->chars); + strbuf->chars = CHAR_NULL_PTR; +} + +FF_C_NODISCARD static inline uint32_t ffStrbufGetFree(const FFstrbuf* strbuf) +{ + assert(strbuf != NULL); + if(strbuf->allocated == 0) + return 0; + + return strbuf->allocated - strbuf->length - 1; // - 1 for the null byte +} + static inline void ffStrbufRecalculateLength(FFstrbuf* strbuf) { strbuf->length = (uint32_t) strlen(strbuf->chars); @@ -187,6 +214,30 @@ FF_C_NODISCARD static inline FFstrbuf ffStrbufCreate() return strbuf; } +static inline void ffStrbufInitStatic(FFstrbuf* strbuf, const char* str) +{ + ffStrbufInit(strbuf); + strbuf->allocated = 0; + strbuf->length = (uint32_t) strlen(str); + strbuf->chars = (char*) str; +} + +FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateStatic(const char* str) +{ + FFstrbuf strbuf; + ffStrbufInitStatic(&strbuf, str); + return strbuf; +} + +static inline void ffStrbufSetStatic(FFstrbuf* strbuf, const char* value) +{ + if(strbuf->allocated > 0) + ffStrbufDestroy(strbuf); + + if(value != NULL) + ffStrbufInitStatic(strbuf, value); +} + static inline void ffStrbufInitNS(FFstrbuf* strbuf, uint32_t length, const char* str) { ffStrbufInit(strbuf); @@ -322,6 +373,16 @@ static inline FF_C_NODISCARD uint32_t ffStrbufLastIndexC(const FFstrbuf* strbuf, return ffStrbufPreviousIndexC(strbuf, strbuf->length - 1, c); } +static inline void ffStrbufSubstrBeforeFirstC(FFstrbuf* strbuf, char c) +{ + ffStrbufSubstrBefore(strbuf, ffStrbufFirstIndexC(strbuf, c)); +} + +static inline void ffStrbufSubstrBeforeLastC(FFstrbuf* strbuf, char c) +{ + ffStrbufSubstrBefore(strbuf, ffStrbufLastIndexC(strbuf, c)); +} + static inline FF_C_NODISCARD bool ffStrbufStartsWithC(const FFstrbuf* strbuf, char c) { return strbuf->chars[0] == c; @@ -403,15 +464,10 @@ static inline FF_C_NODISCARD bool ffStrbufEndsWithIgnCase(const FFstrbuf* strbuf return ffStrbufEndsWithIgnCaseNS(strbuf, end->length, end->chars); } -static inline void ffStrbufDestroy(FFstrbuf* strbuf) +static inline void ffStrbufTrim(FFstrbuf* strbuf, char c) { - if(strbuf->allocated == 0) return; - - extern char* CHAR_NULL_PTR; - //Avoid free-after-use. These 3 assignments are cheap so don't remove them - strbuf->allocated = strbuf->length = 0; - free(strbuf->chars); - strbuf->chars = CHAR_NULL_PTR; + ffStrbufTrimRight(strbuf, c); + ffStrbufTrimLeft(strbuf, c); } #define FF_STRBUF_AUTO_DESTROY FFstrbuf __attribute__((__cleanup__(ffStrbufDestroy))) diff --git a/src/util/unused.h b/src/util/unused.h new file mode 100644 index 000000000..fbc0e93e3 --- /dev/null +++ b/src/util/unused.h @@ -0,0 +1,10 @@ +#pragma once + +#ifndef FASTFETCH_INCLUDED_UNUSED +#define FASTFETCH_INCLUDED_UNUSED + +static inline void ffUnused(int dummy, ...) { (void) dummy; } +#define FF_UNUSED(...) ffUnused(0, __VA_ARGS__); +#define FF_MAYBE_UNUSED __attribute__ ((__unused__)) + +#endif diff --git a/tests/strbuf.c b/tests/strbuf.c index 027cf2415..d35c93e2f 100644 --- a/tests/strbuf.c +++ b/tests/strbuf.c @@ -214,13 +214,116 @@ int main(void) ffStrbufReplaceAllC(&strbuf, '1', '-'); VERIFY(ffStrbufEqualS(&strbuf, "-234567890-234567890-234567890-")); + //trim + ffStrbufTrim(&strbuf, '-'); + VERIFY(ffStrbufEqualS(&strbuf, "234567890-234567890-234567890")); + ffStrbufDestroy(&strbuf); + //ffStrbufCreateS { FF_STRBUF_AUTO_DESTROY testCreate = ffStrbufCreateS("TEST"); VERIFY(ffStrbufEqualS(&testCreate, "TEST")); } + //ffStrbufCreateStatic + ffStrbufInitStatic(&strbuf, "TEST"); + VERIFY(ffStrbufEqualS(&strbuf, "TEST")); + VERIFY(strbuf.length == 4); + VERIFY(strbuf.allocated == 0); + + ffStrbufDestroy(&strbuf); + VERIFY(strbuf.length == 0); + VERIFY(strbuf.allocated == 0); + + //ffStrbufCreateStatic / Allocate + ffStrbufInitStatic(&strbuf, "TEST"); + ffStrbufEnsureFree(&strbuf, 0); + VERIFY(ffStrbufEqualS(&strbuf, "TEST")); + VERIFY(strbuf.length == 4); + VERIFY(strbuf.allocated > 0); + + //ffStrbufCreateStatic / Append + ffStrbufInitStatic(&strbuf, "TEST"); + ffStrbufAppendS(&strbuf, "_TEST"); + VERIFY(ffStrbufEqualS(&strbuf, "TEST_TEST")); + VERIFY(strbuf.length == 9); + VERIFY(strbuf.allocated >= 10); + ffStrbufDestroy(&strbuf); + VERIFY(strbuf.length == 0); + VERIFY(strbuf.allocated == 0); + + //ffStrbufCreateStatic / Clear + ffStrbufInitStatic(&strbuf, "TEST"); + ffStrbufClear(&strbuf); + VERIFY(strbuf.length == 0); + VERIFY(strbuf.allocated == 0); + ffStrbufDestroy(&strbuf); + + //ffStrbufCreateStatic / Set + ffStrbufInitStatic(&strbuf, "TEST"); // static + ffStrbufSetStatic(&strbuf, "test"); + VERIFY(ffStrbufEqualS(&strbuf, "test")); + VERIFY(strbuf.length == 4); + VERIFY(strbuf.allocated == 0); + ffStrbufDestroy(&strbuf); + + //ffStrbufCreateStatic / Set + ffStrbufInitS(&strbuf, "TEST"); // allocated + ffStrbufSetStatic(&strbuf, "test"); + VERIFY(ffStrbufEqualS(&strbuf, "test")); + VERIFY(strbuf.length == 4); + VERIFY(strbuf.allocated == 0); + ffStrbufDestroy(&strbuf); + + //ffStrbufCreateStatic / TrimL + ffStrbufInitStatic(&strbuf, "_TEST_"); + ffStrbufTrimLeft(&strbuf, '_'); + VERIFY(ffStrbufEqualS(&strbuf, "TEST_")); + VERIFY(strbuf.length == 5); + VERIFY(strbuf.allocated == 0); + ffStrbufDestroy(&strbuf); + + //ffStrbufCreateStatic / TrimR + ffStrbufInitStatic(&strbuf, "_TEST_"); + ffStrbufTrimRight(&strbuf, '_'); + VERIFY(ffStrbufEqualS(&strbuf, "_TEST")); + VERIFY(strbuf.length == 5); + VERIFY(strbuf.allocated > 0); + ffStrbufDestroy(&strbuf); + + //ffStrbufCreateStatic / Substr + ffStrbufInitStatic(&strbuf, "__TEST__"); + ffStrbufRemoveSubstr(&strbuf, 0, 6); + VERIFY(ffStrbufEqualS(&strbuf, "__")); + VERIFY(strbuf.length == 2); + VERIFY(strbuf.allocated > 0); + ffStrbufDestroy(&strbuf); + + //ffStrbufCreateStatic / Substr + ffStrbufInitStatic(&strbuf, "__TEST__"); + ffStrbufRemoveSubstr(&strbuf, 2, 8); + VERIFY(ffStrbufEqualS(&strbuf, "__")); + VERIFY(strbuf.length == 2); + VERIFY(strbuf.allocated > 0); + ffStrbufDestroy(&strbuf); + + //ffStrbufCreateStatic / Substr + ffStrbufInitStatic(&strbuf, "__TEST__"); + ffStrbufRemoveSubstr(&strbuf, 2, 6); + VERIFY(ffStrbufEqualS(&strbuf, "____")); + VERIFY(strbuf.length == 4); + VERIFY(strbuf.allocated > 0); + ffStrbufDestroy(&strbuf); + + //ffStrbufCreateStatic / Substr + ffStrbufInitStatic(&strbuf, "__TEST__"); + ffStrbufReplaceAllC(&strbuf, '_', '-'); + VERIFY(ffStrbufEqualS(&strbuf, "--TEST--")); + VERIFY(strbuf.length == 8); + VERIFY(strbuf.allocated > 0); + ffStrbufDestroy(&strbuf); + //Success - puts("\033[32mAll tests passed!"FASTFETCH_TEXT_MODIFIER_RESET); + puts("\033[32mAll tests passed!" FASTFETCH_TEXT_MODIFIER_RESET); }