From 9bc1f2a11671adc29b4c8a3d046ee2c6efd8e024 Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Thu, 15 Apr 2021 18:59:26 +0200 Subject: [PATCH] much more efficient caching --- src/common/format.c | 54 ++--- src/common/init.c | 1 + src/common/io.c | 422 ++++++++++++++++++++++++++++--------- src/fastfetch.c | 8 +- src/fastfetch.h | 34 ++- src/modules/battery.c | 70 +++--- src/modules/cpu.c | 76 ++++--- src/modules/custom.c | 2 +- src/modules/de.c | 18 +- src/modules/disk.c | 31 +-- src/modules/font.c | 50 ++--- src/modules/gpu.c | 87 +++----- src/modules/host.c | 61 +++--- src/modules/icons.c | 21 +- src/modules/kernel.c | 15 +- src/modules/locale.c | 41 ++-- src/modules/memory.c | 23 +- src/modules/os.c | 123 ++++++----- src/modules/packages.c | 17 +- src/modules/resolution.c | 242 ++++++++++++++------- src/modules/seperator.c | 2 +- src/modules/shell.c | 24 +-- src/modules/terminal.c | 17 +- src/modules/terminalfont.c | 25 ++- src/modules/theme.c | 25 ++- src/modules/title.c | 2 +- src/modules/uptime.c | 17 +- src/modules/wm.c | 15 +- src/modules/wmtheme.c | 17 +- src/util/FFlist.c | 36 ++++ src/util/FFlist.h | 27 +++ src/util/FFstrbuf.c | 9 +- src/util/FFstrbuf.h | 4 +- tests/performance.c | 2 +- tests/performance.sh | 1 + 35 files changed, 974 insertions(+), 645 deletions(-) create mode 100644 src/util/FFlist.c create mode 100644 src/util/FFlist.h diff --git a/src/common/format.c b/src/common/format.c index 1058c8ca2..a8d933d61 100644 --- a/src/common/format.c +++ b/src/common/format.c @@ -1,11 +1,7 @@ #include "fastfetch.h" -void ffParseFormatStringV(FFstrbuf* buffer, FFstrbuf* formatstr, uint32_t numArgs, va_list argp) +void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, const FFstrbuf* error, uint32_t numArgs, const FFformatarg* arguments) { - FFformatarg arguments[numArgs]; - for(uint32_t i = 0; i < numArgs; i++) - arguments[i] = (FFformatarg) va_arg(argp, FFformatarg); - uint32_t argCounter = 1; //First arg is 1 in fomat string for(uint32_t i = 0; i < formatstr->length; ++i) @@ -50,12 +46,24 @@ void ffParseFormatStringV(FFstrbuf* buffer, FFstrbuf* formatstr, uint32_t numArg while(formatstr->chars[i] != '}' && i < formatstr->length) ffStrbufAppendC(&argnumstr, formatstr->chars[i++]); + if( + ffStrbufIgnCaseCompS(&argnumstr, "e") == 0 || + ffStrbufIgnCaseCompS(&argnumstr, "error") == 0 || + ffStrbufIgnCaseCompS(&argnumstr, "0") == 0 + ) { + ffStrbufAppend(buffer, error); + ffStrbufDestroy(&argnumstr); + continue; + } + + //Test if argnumstr is valid if( argnumstr.length == 0 || ffStrbufGetC(&argnumstr, 0) == '-' || sscanf(argnumstr.chars, "%u", &argIndex) != 1 || argIndex > numArgs ) { + //Not valid ffStrbufAppendC(buffer, '{'); ffStrbufAppend(buffer, &argnumstr); if(formatstr->chars[i] == '}') // We dont have a closing { when ending because whole format string is over @@ -67,9 +75,6 @@ void ffParseFormatStringV(FFstrbuf* buffer, FFstrbuf* formatstr, uint32_t numArg ffStrbufDestroy(&argnumstr); } - if(argIndex == 0) - argIndex = 1; - FFformatarg arg = arguments[argIndex - 1]; if(arg.type == FF_FORMAT_ARG_TYPE_INT) @@ -77,14 +82,14 @@ void ffParseFormatStringV(FFstrbuf* buffer, FFstrbuf* formatstr, uint32_t numArg else if(arg.type == FF_FORMAT_ARG_TYPE_UINT) ffStrbufAppendF(buffer, "%u", *(uint32_t*)arg.value); else if(arg.type == FF_FORMAT_ARG_TYPE_UINT8) - ffStrbufAppendF(buffer, "%u", *(uint8_t*)arg.value); + ffStrbufAppendF(buffer, "%hhu", *(uint8_t*)arg.value); else if(arg.type == FF_FORMAT_ARG_TYPE_STRING) ffStrbufAppendF(buffer, "%s", (const char*)arg.value); else if(arg.type == FF_FORMAT_ARG_TYPE_STRBUF) ffStrbufAppend(buffer, (FFstrbuf*)arg.value); else if(arg.type == FF_FORMAT_ARG_TYPE_DOUBLE) ffStrbufAppendF(buffer, "%g", *(double*)arg.value); - else + else if(arg.type != FF_FORMAT_ARG_TYPE_NULL) { fprintf(stderr, "Error: format string \"%s\" argument is not implemented\n", formatstr->chars); ffStrbufDestroy(buffer); @@ -94,32 +99,3 @@ void ffParseFormatStringV(FFstrbuf* buffer, FFstrbuf* formatstr, uint32_t numArg ffStrbufTrimRight(buffer, ' '); } - -void ffParseFormatString(FFstrbuf* buffer, FFstrbuf* formatstr, uint32_t numArgs, ...) -{ - va_list argp; - va_start(argp, numArgs); - ffParseFormatStringV(buffer, formatstr, numArgs, argp); - va_end(argp); -} - -void ffPrintFormatString(FFinstance* instance, FFstrbuf* customKey, const char* defKey, FFstrbuf* formatstr, uint32_t numArgs, ...) -{ - FFstrbuf buffer; - ffStrbufInitA(&buffer, 256); - - va_list argp; - va_start(argp, numArgs); - - ffParseFormatStringV(&buffer, formatstr, numArgs, argp); - - va_end(argp); - - if(buffer.length > 0) - { - ffPrintLogoAndKey(instance, customKey, defKey); - ffStrbufPutTo(&buffer, stdout); - } - - ffStrbufDestroy(&buffer); -} diff --git a/src/common/init.c b/src/common/init.c index 7f10e4623..5ed413e44 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -79,6 +79,7 @@ void ffInitInstance(FFinstance* instance) { initState(&instance->state); defaultConfig(&instance->config); + ffCacheValidate(instance); } static void ffCleanup(FFinstance* instance) diff --git a/src/common/io.c b/src/common/io.c index f9ba78887..a5737bf85 100644 --- a/src/common/io.c +++ b/src/common/io.c @@ -1,44 +1,338 @@ #include "fastfetch.h" +#include #include #include #include +#include -void ffPrintKey(FFinstance* instance, FFstrbuf* customKey, const char* defKey) -{ - fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout); - ffStrbufWriteTo(&instance->config.color, stdout); - if(customKey == NULL || customKey->length == 0) - fputs(defKey, stdout); - else - ffStrbufWriteTo(customKey, stdout); - fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout); - ffStrbufWriteTo(&instance->config.seperator, stdout); -} - -void ffPrintLogoAndKey(FFinstance* instance, FFstrbuf* customKey, const char* defKey) +void ffPrintLogoAndKey(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat) { ffPrintLogoLine(instance); - ffPrintKey(instance, customKey, defKey); + + fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout); + ffStrbufWriteTo(&instance->config.color, stdout); + + FF_STRBUF_CREATE(key); + + if(customKeyFormat == NULL || customKeyFormat->length == 0) + { + ffStrbufAppendS(&key, moduleName); + + if(moduleIndex > 0) + ffStrbufAppendF(&key, " %hhu", moduleIndex); + } + else + { + ffParseFormatString(&key, customKeyFormat, NULL, 1, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_UINT8, &moduleIndex} + }); + } + + ffStrbufWriteTo(&key, stdout); + fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout); + ffStrbufWriteTo(&instance->config.seperator, stdout); + ffStrbufDestroy(&key); } -void ffPrintError(FFinstance* instance, FFstrbuf* customKey, const char* defKey, const char* message, ...) +void ffPrintError(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* formatString, uint32_t numFormatArgs, const char* message, ...) { - if(!instance->config.showErrors) - return; - - ffPrintLogoAndKey(instance, customKey, defKey); - va_list arguments; va_start(arguments, message); - printf(FASTFETCH_TEXT_MODIFIER_ERROR); - vprintf(message, arguments); - puts(FASTFETCH_TEXT_MODIFIER_RESET); + if((formatString == NULL || formatString->length == 0) && instance->config.showErrors) + { + ffPrintLogoAndKey(instance, moduleName, moduleIndex, customKeyFormat); + fputs(FASTFETCH_TEXT_MODIFIER_ERROR, stdout); + vprintf(message, arguments); + puts(FASTFETCH_TEXT_MODIFIER_ERROR); + } + else + { + FF_STRBUF_CREATE(error); + ffStrbufAppendVF(&error, message, arguments); + + FFformatarg nullArgs[numFormatArgs]; + for(uint32_t i = 0; i < numFormatArgs; i++) + { + nullArgs[i].type = FF_FORMAT_ARG_TYPE_NULL; + nullArgs[i].value = NULL; + } + + ffPrintFormatString(instance, moduleName, moduleIndex, customKeyFormat, formatString, &error, numFormatArgs, nullArgs); + + ffStrbufDestroy(&error); + } va_end(arguments); } +void ffPrintFormatString(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* formatString, const FFstrbuf* error, uint32_t numArgs, const FFformatarg* arguments) +{ + FFstrbuf buffer; + ffStrbufInitA(&buffer, 256); + + ffParseFormatString(&buffer, formatString, error, numArgs, arguments); + + if(buffer.length > 0) + { + ffPrintLogoAndKey(instance, moduleName, moduleIndex, customKeyFormat); + ffStrbufPutTo(&buffer, stdout); + } + + ffStrbufDestroy(&buffer); +} + +static void appendCacheDir(FFinstance* instance, FFstrbuf* buffer) +{ + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + + static FFstrbuf cacheDir; + static bool init = false; + + pthread_mutex_lock(&mutex); + + if(init) + { + pthread_mutex_unlock(&mutex); + ffStrbufAppend(buffer, &cacheDir); + return; + } + + ffStrbufInitA(&cacheDir, 64); + ffStrbufAppendS(&cacheDir, getenv("XDG_CACHE_HOME")); + + if(cacheDir.length == 0) + { + ffStrbufSetS(&cacheDir, instance->state.passwd->pw_dir); + ffStrbufAppendS(&cacheDir, "/.cache/"); + } + + mkdir(cacheDir.chars, S_IRWXU | S_IXGRP | S_IRGRP | S_IXOTH | S_IROTH); //I hope everybody has a cache folder but whow knews + + ffStrbufAppendS(&cacheDir, "fastfetch/"); + mkdir(cacheDir.chars, S_IRWXU | S_IRGRP | S_IROTH); + + init = true; + + pthread_mutex_unlock(&mutex); + + ffStrbufAppend(buffer, &cacheDir); +} + +static inline void getCacheFileValue(FFinstance* instance, const char* moduleName, FFstrbuf* cacheFilePath) +{ + appendCacheDir(instance, cacheFilePath); + ffStrbufAppendS(cacheFilePath, moduleName); + ffStrbufAppendS(cacheFilePath, ".ffcv"); +} + +static inline void getCacheFileSplit(FFinstance* instance, const char* moduleName, FFstrbuf* cacheFilePath) +{ + appendCacheDir(instance, cacheFilePath); + ffStrbufAppendS(cacheFilePath, moduleName); + ffStrbufAppendS(cacheFilePath, ".ffcs"); +} + +bool printCachedValue(FFinstance* instance, const char* moduleName, const FFstrbuf* customKeyFormat) +{ + FFstrbuf cacheFilePath; + ffStrbufInitA(&cacheFilePath, 64); + getCacheFileValue(instance, moduleName, &cacheFilePath); + + FFstrbuf content; + ffStrbufInitA(&content, 512); + ffAppendFileContent(cacheFilePath.chars, &content); + + ffStrbufTrimRight(&content, '\0'); //Strbuf always appends a '\0' at the end. We want the last null byte to be at the position of the length + + if(content.length == 0) + return false; + + uint8_t moduleCounter = 1; + + uint32_t lastIndex = 0; + while(lastIndex < content.length) + { + uint32_t nullByteIndex = ffStrbufFirstIndexAfterC(&content, lastIndex, '\0'); + uint8_t moduleIndex = (moduleCounter == 1 && nullByteIndex == content.length) ? 0 : moduleCounter; + ffPrintLogoAndKey(instance, moduleName, moduleIndex, customKeyFormat); + puts(content.chars + lastIndex); + lastIndex = nullByteIndex + 1; + ++moduleCounter; + } + + ffStrbufDestroy(&content); + ffStrbufDestroy(&cacheFilePath); + + return moduleCounter > 1; +} + +bool printCachedFormat(FFinstance* instance, const char* moduleName, const FFstrbuf* customKeyFormat, const FFstrbuf* formatString, uint32_t numArgs) +{ + FFstrbuf cacheFilePath; + ffStrbufInitA(&cacheFilePath, 64); + getCacheFileSplit(instance, moduleName, &cacheFilePath); + + FFstrbuf content; + ffStrbufInitA(&content, 512); + ffAppendFileContent(cacheFilePath.chars, &content); + + ffStrbufTrimRight(&content, '\0'); //Strbuf always appends a '\0' at the end. We want the last null byte to be at the position of the length + + if(content.length == 0) + return false; + + uint8_t moduleCounter = 1; + + FFformatarg arguments[numArgs]; + uint32_t argumentCounter = 0; + + uint32_t lastIndex = 0; + while(lastIndex < content.length) + { + arguments[argumentCounter].type = FF_FORMAT_ARG_TYPE_STRING; + arguments[argumentCounter].value = &content.chars[lastIndex]; + ++argumentCounter; + + uint32_t nullByteIndex = ffStrbufFirstIndexAfterC(&content, lastIndex, '\0'); + + if(argumentCounter == numArgs) + { + uint8_t moduleIndex = (moduleCounter == 1 && nullByteIndex == content.length) ? 0 : moduleCounter; + ffPrintFormatString(instance, moduleName, moduleIndex, customKeyFormat, formatString, NULL, numArgs, arguments); + ++moduleCounter; + argumentCounter = 0; + } + + lastIndex = nullByteIndex + 1; + } + + ffStrbufDestroy(&content); + ffStrbufDestroy(&cacheFilePath); + + return moduleCounter > 1; +} + +bool ffPrintFromCache(FFinstance* instance, const char* moduleName, const FFstrbuf* customKeyFormat, const FFstrbuf* formatString, uint32_t numArgs) +{ + if(instance->config.recache) + return false; + + if(formatString == NULL || formatString->length == 0) + return printCachedValue(instance, moduleName, customKeyFormat); + else + return printCachedFormat(instance, moduleName, customKeyFormat, formatString, numArgs); +} + +void ffPrintAndAppendToCache(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, FFcache* cache, const FFstrbuf* value, const FFstrbuf* formatString, uint32_t numArgs, const FFformatarg* arguments) +{ + if(formatString == NULL || formatString->length == 0) + { + ffPrintLogoAndKey(instance, moduleName, moduleIndex, customKeyFormat); + ffStrbufPutTo(value, stdout); + } + else + { + ffPrintFormatString(instance, moduleName, moduleIndex, customKeyFormat, formatString, NULL, numArgs, arguments); + } + + if(cache->value != NULL) + { + ffStrbufWriteTo(value, cache->value); + fputc('\0', cache->value); + } + + if(cache->split == NULL) + return; + + for(uint32_t i = 0; i < numArgs; i++) + { + FFformatarg arg = arguments[i]; + + if(arg.type == FF_FORMAT_ARG_TYPE_INT) + fprintf(cache->split, "%i", *(int*)arg.value); + else if(arg.type == FF_FORMAT_ARG_TYPE_UINT) + fprintf(cache->split, "%u", *(uint32_t*)arg.value); + else if(arg.type == FF_FORMAT_ARG_TYPE_UINT8) + fprintf(cache->split, "%hhu", *(uint8_t*)arg.value); + else if(arg.type == FF_FORMAT_ARG_TYPE_STRING) + fprintf(cache->split, "%s", (const char*)arg.value); + else if(arg.type == FF_FORMAT_ARG_TYPE_STRBUF) + fprintf(cache->split, "%s", ((FFstrbuf*)arg.value)->chars); + else if(arg.type == FF_FORMAT_ARG_TYPE_DOUBLE) + fprintf(cache->split, "%g", *(double*)arg.value); + + fputc('\0', cache->split); + } + + fputc('\0', cache->split); +} + +void ffPrintAndSaveToCache(FFinstance* instance, const char* moduleName, const FFstrbuf* customKeyFormat, const FFstrbuf* value, const FFstrbuf* formatString, uint32_t numArgs, const FFformatarg* arguments) +{ + FFcache cache; + ffCacheOpenWrite(instance, moduleName, &cache); + ffPrintAndAppendToCache(instance, moduleName, 0, customKeyFormat, &cache, value, formatString, numArgs, arguments); + ffCacheClose(&cache); +} + +void ffCacheValidate(FFinstance* instance) +{ + FFstrbuf cacheFilePath; + ffStrbufInitA(&cacheFilePath, 64); + appendCacheDir(instance, &cacheFilePath); + ffStrbufAppendS(&cacheFilePath, "cacheversion.ffv"); + + FFstrbuf content; + ffStrbufInit(&content); + ffAppendFileContent(cacheFilePath.chars, &content); + + if(ffStrbufCompS(&content, FASTFETCH_PROJECT_VERSION) == 0) + { + ffStrbufDestroy(&content); + ffStrbufDestroy(&cacheFilePath); + return; + } + + instance->config.recache = true; + + FILE* versionFile = fopen(cacheFilePath.chars, "w"); + if(versionFile == NULL) + return; + + fputs(FASTFETCH_PROJECT_VERSION, versionFile); + + fclose(versionFile); + + ffStrbufDestroy(&content); + ffStrbufDestroy(&cacheFilePath); +} + +void ffCacheOpenWrite(FFinstance* instance, const char* moduleName, FFcache* cache) +{ + FFstrbuf cacheFileValue; + ffStrbufInitA(&cacheFileValue, 64); + getCacheFileValue(instance, moduleName, &cacheFileValue); + cache->value = fopen(cacheFileValue.chars, "w"); + ffStrbufDestroy(&cacheFileValue); + + FFstrbuf cacheFileSplit; + ffStrbufInitA(&cacheFileSplit, 64); + getCacheFileSplit(instance, moduleName, &cacheFileSplit); + cache->split = fopen(cacheFileSplit.chars, "w"); + ffStrbufDestroy(&cacheFileSplit); +} + +void ffCacheClose(FFcache* cache) +{ + if(cache->value != NULL) + fclose(cache->value); + + if(cache->split != NULL) + fclose(cache->split); +} + void ffParsePropFile(const char* fileName, const char* regex, char* buffer) { buffer[0] = '\0'; //If an error occures, this is the indicator @@ -101,85 +395,3 @@ void ffGetFileContent(const char* fileName, FFstrbuf* buffer) ffStrbufClear(buffer); ffAppendFileContent(fileName, buffer); } - -static const FFstrbuf* getCacheDir(FFinstance* instance) -{ - static FFstrbuf cacheDir; - static bool init = false; - if(init) - return &cacheDir; - - ffStrbufInitAS(&cacheDir, 64, getenv("XDG_CACHE_HOME")); - - if(cacheDir.length == 0) - { - ffStrbufSetS(&cacheDir, instance->state.passwd->pw_dir); - ffStrbufAppendS(&cacheDir, "/.cache/"); - } - - mkdir(cacheDir.chars, S_IRWXU | S_IXGRP | S_IRGRP | S_IXOTH | S_IROTH); //I hope everybody has a cache folder but whow knews - - ffStrbufAppendS(&cacheDir, "fastfetch/"); - mkdir(cacheDir.chars, S_IRWXU | S_IRGRP | S_IROTH); - - init = true; - return &cacheDir; -} - -bool ffPrintCachedValue(FFinstance* instance, FFstrbuf* customKey, const char* defKey) -{ - if(instance->config.recache) - return false; - - FFstrbuf cacheFile; - ffStrbufInitA(&cacheFile, 128); - ffStrbufAppend(&cacheFile, getCacheDir(instance)); - ffStrbufAppendS(&cacheFile, defKey); - - FFstrbuf value; - ffStrbufInitA(&value, 128); - ffGetFileContent(cacheFile.chars, &value); - - ffStrbufDestroy(&cacheFile); - - if(value.length == 0) - { - ffStrbufDestroy(&value); - return false; - } - - ffPrintLogoAndKey(instance, customKey, defKey); - ffStrbufPutTo(&value, stdout); - ffStrbufDestroy(&value); - return true; -} - -void ffPrintAndSaveCachedValue(FFinstance* instance, FFstrbuf* customKey, const char* defKey, FFstrbuf* value) -{ - if(value->length == 0) - return; - - ffPrintLogoAndKey(instance, customKey, defKey); - ffStrbufPutTo(value, stdout); - - if(!instance->config.cacheSave) - return; - - FFstrbuf cacheFile; - ffStrbufInit(&cacheFile); - ffStrbufAppend(&cacheFile, getCacheDir(instance)); - ffStrbufAppendS(&cacheFile, defKey); - - int fd = open(cacheFile.chars, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if(fd == -1) - return; - - bool failed = write(fd, value->chars, value->length) != value->length; - - close(fd); - - if(failed) - unlink(cacheFile.chars); - - ffStrbufDestroy(&cacheFile); -} diff --git a/src/fastfetch.c b/src/fastfetch.c index ba2a47ec8..61b53a0f4 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -1,5 +1,4 @@ #include "fastfetch.h" -#include "fastfetch_config.h" #include "util/FFvaluestore.h" #include @@ -376,7 +375,7 @@ static inline void printCommandHelp(const char* command) "CPU logical core count online", "CPU logical core count configured", "CPU physical core count", - "Always set core count" + "Always set core count", "frequency bios limit", "frequency scaling max", "frequency scaling min", @@ -387,8 +386,9 @@ static inline void printCommandHelp(const char* command) } else if(strcasecmp(command, "gpu-format") == 0) { - constructAndPrintCommandHelpFormat("gpu", "{} {}", 2, + constructAndPrintCommandHelpFormat("gpu", "{2} {3}", 3, "GPU vendor", + "GPU vendor pretty" "GPU name" ); } @@ -852,7 +852,7 @@ static void parseStructureCommand(FFinstance* instance, FFdata* data, const char else if(strcasecmp(line, "colors") == 0) ffPrintColors(instance); else - ffPrintError(instance, NULL, line, ""); + ffPrintError(instance, line, 0, NULL, NULL, 0, ""); } static void run(FFinstance* instance, FFdata* data) diff --git a/src/fastfetch.h b/src/fastfetch.h index d61a863a0..4222154eb 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -13,6 +13,8 @@ #include #include +#include "fastfetch_config.h" + #include "util/FFstrbuf.h" #define UNUSED(...) (void)(__VA_ARGS__) @@ -37,7 +39,7 @@ typedef struct FFconfig FFstrbuf seperator; int16_t offsetx; FFstrbuf color; - uint8_t titleLength; + uint32_t titleLength; bool colorLogo; bool showErrors; bool recache; @@ -117,7 +119,8 @@ typedef enum FFformatargtype FF_FORMAT_ARG_TYPE_INT, FF_FORMAT_ARG_TYPE_STRING, FF_FORMAT_ARG_TYPE_STRBUF, - FF_FORMAT_ARG_TYPE_DOUBLE + FF_FORMAT_ARG_TYPE_DOUBLE, + FF_FORMAT_ARG_TYPE_NULL } FFformatargtype; typedef struct FFformatarg @@ -126,6 +129,12 @@ typedef struct FFformatarg const void* value; } FFformatarg; +typedef struct FFcache +{ + FILE* value; + FILE* split; +} FFcache; + /*************************/ /* Common util functions */ /*************************/ @@ -138,15 +147,22 @@ void ffFinish(FFinstance* instance); void ffStartCalculationThreads(FFinstance* instance); //common/io.c -void ffPrintKey(FFinstance* instance, FFstrbuf* customKey, const char* defKey); -void ffPrintLogoAndKey(FFinstance* instance, FFstrbuf* customKey, const char* defKey); -void ffPrintError(FFinstance* instance, FFstrbuf* customKey, const char* defKey, const char* message, ...); +void ffPrintLogoAndKey(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat); +void ffPrintError(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* formatString, uint32_t numFormatArgs, const char* message, ...); +void ffPrintFormatString(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* formatString, const FFstrbuf* error, uint32_t numArgs, const FFformatarg* arguments); +bool ffPrintFromCache(FFinstance* instance, const char* moduleName, const FFstrbuf* customKeyFormat, const FFstrbuf* formatString, uint32_t numArgs); +void ffPrintAndSaveToCache(FFinstance* instance, const char* moduleName, const FFstrbuf* customKeyFormat, const FFstrbuf* value, const FFstrbuf* formatString, uint32_t numArgs, const FFformatarg* arguments); +void ffPrintAndAppendToCache(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, FFcache* cache, const FFstrbuf* value, const FFstrbuf* formatString, uint32_t numArgs, const FFformatarg* arguments); + +void ffCacheValidate(FFinstance* instance); +void ffCacheOpenWrite(FFinstance* instance, const char* moduleName, FFcache* cache); +void ffCacheClose(FFcache* cache); + void ffAppendFileContent(const char* fileName, FFstrbuf* buffer); void ffGetFileContent(const char* fileName, FFstrbuf* buffer); + void ffParsePropFile(const char* file, const char* regex, char* buffer); void ffParsePropFileHome(FFinstance* instance, const char* relativeFile, const char* regex, char* buffer); -bool ffPrintCachedValue(FFinstance* instance, FFstrbuf* customKey, const char* defKey); -void ffPrintAndSaveCachedValue(FFinstance* instance, FFstrbuf* customKey, const char* defKey, FFstrbuf* value); //common/logo.c void ffLoadLogoSet(FFconfig* config, const char* logo); @@ -160,9 +176,7 @@ void ffPrintRemainingLogo(FFinstance* instance); #endif //common/format.c -void ffParseFormatStringV(FFstrbuf* buffer, FFstrbuf* formatstr, uint32_t numArgs, va_list argp); -void ffParseFormatString(FFstrbuf* buffer, FFstrbuf* formatstr, uint32_t numArgs, ...); -void ffPrintFormatString(FFinstance* instance, FFstrbuf* customKey, const char* defKey, FFstrbuf* formatstr, uint32_t numArgs, ...); +void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, const FFstrbuf* error, uint32_t numArgs, const FFformatarg* arguments); //common/parsing.c void ffGetGtkPretty(FFstrbuf* buffer, FFstrbuf* gtk2, FFstrbuf* gtk3, FFstrbuf* gtk4); diff --git a/src/modules/battery.c b/src/modules/battery.c index e1d3a0058..b322fba96 100644 --- a/src/modules/battery.c +++ b/src/modules/battery.c @@ -2,22 +2,8 @@ #include -static void getKey(FFinstance* instance, FFstrbuf* key, uint8_t counter, bool showCounter) -{ - if(instance->config.batteryKey.length == 0) - { - if(showCounter) - ffStrbufAppendF(key, "Battery %hhu", counter); - else - ffStrbufSetS(key, "Battery"); - } - else - { - ffParseFormatString(key, &instance->config.batteryKey, 1, - (FFformatarg){FF_FORMAT_ARG_TYPE_UINT8, &counter} - ); - } -} +#define FF_BATTERY_MODULE_NAME "Battery" +#define FF_BATTERY_NUM_FORMAT_ARGS 5 static void printBattery(FFinstance* instance, uint8_t index) { @@ -46,25 +32,16 @@ static void printBattery(FFinstance* instance, uint8_t index) sprintf(statusPath, "/sys/class/power_supply/BAT%hhu/status", index); ffGetFileContent(statusPath, &status); - FF_STRBUF_CREATE(key); - getKey(instance, &key, index + 1, true); - - if( - manufactor.length == 0 && - model.length == 0 && - technology.length == 0 && - capacity.length == 0 && - status.length == 0 - ) { - ffPrintError(instance, &key, NULL, "No file in /sys/class/power_supply/BAT%hhu/ could be read or all battery options are disabled", index); - ffStrbufDestroy(&key); + if(manufactor.length == 0 && model.length == 0 && technology.length == 0 && capacity.length == 0 && status.length == 0) + { + ffPrintError(instance, FF_BATTERY_MODULE_NAME, index, &instance->config.batteryKey, &instance->config.batteryFormat, FF_BATTERY_NUM_FORMAT_ARGS, "No file in /sys/class/power_supply/BAT%hhu/ could be read or all battery options are disabled", index); return; } if(instance->config.batteryFormat.length == 0) { - ffPrintLogoAndKey(instance, &key, NULL); + ffPrintLogoAndKey(instance, FF_BATTERY_MODULE_NAME, index, &instance->config.batteryKey); if(manufactor.length > 0) printf("%s ", manufactor.chars); @@ -94,13 +71,13 @@ static void printBattery(FFinstance* instance, uint8_t index) } else { - ffPrintFormatString(instance, &key, NULL, &instance->config.batteryFormat, 5, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &manufactor}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &model}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &technology}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &capacity}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &status} - ); + ffPrintFormatString(instance, FF_BATTERY_MODULE_NAME, index, &instance->config.batteryKey, &instance->config.batteryFormat, NULL, FF_BATTERY_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &manufactor}, + {FF_FORMAT_ARG_TYPE_STRBUF, &model}, + {FF_FORMAT_ARG_TYPE_STRBUF, &technology}, + {FF_FORMAT_ARG_TYPE_STRBUF, &capacity}, + {FF_FORMAT_ARG_TYPE_STRBUF, &status} + }); } ffStrbufDestroy(&manufactor); @@ -108,13 +85,16 @@ static void printBattery(FFinstance* instance, uint8_t index) ffStrbufDestroy(&technology); ffStrbufDestroy(&capacity); ffStrbufDestroy(&status); - ffStrbufDestroy(&key); } +#define FF_BATTERY_MAX_INDEX 5 + void ffPrintBattery(FFinstance* instance) { uint8_t batteryCounter = 0; - for(uint8_t i = 0; i < 5; i++) + uint8_t batteryIndicies[FF_BATTERY_MAX_INDEX]; + + for(uint8_t i = 0; i < FF_BATTERY_MAX_INDEX; i++) { char path[30]; sprintf(path, "/sys/class/power_supply/BAT%i", i); @@ -122,19 +102,19 @@ void ffPrintBattery(FFinstance* instance) DIR* dir = opendir(path); if(dir != NULL) { - printBattery(instance, batteryCounter++); + batteryIndicies[batteryCounter++] = i; closedir(dir); } } if(batteryCounter == 0) { - if(!instance->config.showErrors) - return; + ffPrintError(instance, FF_BATTERY_MODULE_NAME, 0, &instance->config.batteryKey, &instance->config.batteryFormat, FF_BATTERY_NUM_FORMAT_ARGS, "/sys/class/power_supply/ doesn't contain any BAT* folder"); + return; + } - FF_STRBUF_CREATE(key); - getKey(instance, &key, 1, false); - ffPrintError(instance, &key, NULL, "No battery found in /sys/class/power_supply/"); - ffStrbufDestroy(&key); + for(uint8_t i = 0; i < batteryCounter; i++) + { + printBattery(instance, batteryIndicies[i]); } } diff --git a/src/modules/cpu.c b/src/modules/cpu.c index 6fb522c9b..987023246 100644 --- a/src/modules/cpu.c +++ b/src/modules/cpu.c @@ -2,6 +2,9 @@ #include +#define FF_CPU_MODULE_NAME "CPU" +#define FF_CPU_NUM_FORMAT_ARGS 13 + static double getGhz(const char* file) { FF_STRBUF_CREATE(content); @@ -22,13 +25,13 @@ static double getGhz(const char* file) void ffPrintCPU(FFinstance* instance) { - if(ffPrintCachedValue(instance, &instance->config.cpuKey, "CPU")) + if(ffPrintFromCache(instance, FF_CPU_MODULE_NAME, &instance->config.cpuKey, &instance->config.cpuFormat, FF_CPU_NUM_FORMAT_ARGS)) return; FILE* cpuinfo = fopen("/proc/cpuinfo", "r"); if(cpuinfo == NULL) { - ffPrintError(instance, &instance->config.cpuKey, "CPU", "fopen(\"/proc/cpuinfo\", \"r\") == NULL"); + ffPrintError(instance, FF_CPU_MODULE_NAME, 0, &instance->config.cpuKey, &instance->config.cpuFormat, FF_CPU_NUM_FORMAT_ARGS, "fopen(\"/proc/cpuinfo\", \"r\") == NULL"); return; } @@ -87,7 +90,7 @@ void ffPrintCPU(FFinstance* instance) numProcs <= 1 && ghz <= 0 ) { - ffPrintError(instance, &instance->config.cpuKey, "CPU", "No CPU info found in /proc/cpuinfo"); + ffPrintError(instance, FF_CPU_MODULE_NAME, 0, &instance->config.cpuKey, &instance->config.cpuFormat, FF_CPU_NUM_FORMAT_ARGS, "No CPU info found in /proc/cpuinfo"); return; } @@ -103,47 +106,40 @@ void ffPrintCPU(FFinstance* instance) FFstrbuf cpu; ffStrbufInitA(&cpu, 128); - if(instance->config.cpuFormat.length == 0) + if(namePretty.length > 0) + ffStrbufAppend(&cpu, &namePretty); + else if(name[0] != '\0') + ffStrbufAppendS(&cpu, name); + else if(vendor[0] != '\0') { - - if(namePretty.length > 0) - ffStrbufAppend(&cpu, &namePretty); - else if(name[0] != '\0') - ffStrbufAppendS(&cpu, name); - else if(vendor[0] != '\0') - { - ffStrbufAppendS(&cpu, vendor); - ffStrbufAppendS(&cpu, " unknown processor"); - } - else - ffStrbufAppendS(&cpu, " unknown processor"); - - if(numProcs > 1) - ffStrbufAppendF(&cpu, " (%i)", numProcs); - - if(ghz > 0) - ffStrbufAppendF(&cpu, " @ %.9gGHz", ghz); + ffStrbufAppendS(&cpu, vendor); + ffStrbufAppendS(&cpu, " unknown processor"); } else - { - ffParseFormatString(&cpu, &instance->config.cpuFormat, 13, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, name}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &namePretty}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, vendor}, - (FFformatarg){FF_FORMAT_ARG_TYPE_INT, &numProcsOnline}, - (FFformatarg){FF_FORMAT_ARG_TYPE_INT, &numProcsAvailable}, - (FFformatarg){FF_FORMAT_ARG_TYPE_INT, &physicalCores}, - (FFformatarg){FF_FORMAT_ARG_TYPE_DOUBLE, &biosLimit}, - (FFformatarg){FF_FORMAT_ARG_TYPE_INT, &numProcs}, - (FFformatarg){FF_FORMAT_ARG_TYPE_DOUBLE, &scalingMaxFreq}, - (FFformatarg){FF_FORMAT_ARG_TYPE_DOUBLE, &scalingMinFreq}, - (FFformatarg){FF_FORMAT_ARG_TYPE_DOUBLE, &infoMaxFreq}, - (FFformatarg){FF_FORMAT_ARG_TYPE_DOUBLE, &infoMinFreq}, - (FFformatarg){FF_FORMAT_ARG_TYPE_DOUBLE, &ghz} - ); - } + ffStrbufAppendS(&cpu, " unknown processor"); + + if(numProcs > 1) + ffStrbufAppendF(&cpu, " (%i)", numProcs); + + if(ghz > 0) + ffStrbufAppendF(&cpu, " @ %.9gGHz", ghz); + + ffPrintAndSaveToCache(instance, FF_CPU_MODULE_NAME, &instance->config.cpuKey, &cpu, &instance->config.cpuFormat, FF_CPU_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRING, name}, + {FF_FORMAT_ARG_TYPE_STRBUF, &namePretty}, + {FF_FORMAT_ARG_TYPE_STRING, vendor}, + {FF_FORMAT_ARG_TYPE_INT, &numProcsOnline}, + {FF_FORMAT_ARG_TYPE_INT, &numProcsAvailable}, + {FF_FORMAT_ARG_TYPE_INT, &physicalCores}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &biosLimit}, + {FF_FORMAT_ARG_TYPE_INT, &numProcs}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &scalingMaxFreq}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &scalingMinFreq}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &infoMaxFreq}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &infoMinFreq}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &ghz} + }); - ffPrintAndSaveCachedValue(instance, &instance->config.cpuKey, "CPU", &cpu); ffStrbufDestroy(&namePretty); ffStrbufDestroy(&cpu); } diff --git a/src/modules/custom.c b/src/modules/custom.c index 225bd5418..c5c7849bf 100644 --- a/src/modules/custom.c +++ b/src/modules/custom.c @@ -2,6 +2,6 @@ void ffPrintCustom(FFinstance* instance, const char* key, const char* value) { - ffPrintLogoAndKey(instance, NULL, key); + ffPrintLogoAndKey(instance, key, 0, NULL); puts(value); } diff --git a/src/modules/de.c b/src/modules/de.c index 107ce2dfd..b06b8739e 100644 --- a/src/modules/de.c +++ b/src/modules/de.c @@ -2,6 +2,9 @@ #include +#define FF_DE_MODULE_NAME "DE" +#define FF_DE_NUM_FORMAT_ARGS 3 + static void getKDE(FFstrbuf* name, FFstrbuf* version, FFstrbuf* type) { UNUSED(type); @@ -45,7 +48,7 @@ void ffPrintDesktopEnvironment(FFinstance* instance) if(sessionDesktop.length == 0 && sessionType.length == 0) { - ffPrintError(instance, &instance->config.deKey, "DE", "No relevant XDG_SESSION_* environment variable set"); + ffPrintError(instance, FF_DE_MODULE_NAME, 0, &instance->config.deKey, &instance->config.deFormat, FF_DE_NUM_FORMAT_ARGS, "No relevant XDG_SESSION_* environment variable set"); ffStrbufDestroy(&sessionDesktop); ffStrbufDestroy(&sessionVersion); ffStrbufDestroy(&sessionType); @@ -55,7 +58,7 @@ void ffPrintDesktopEnvironment(FFinstance* instance) if(instance->config.deFormat.length == 0) { - ffPrintLogoAndKey(instance, &instance->config.deKey, "DE"); + ffPrintLogoAndKey(instance, FF_DE_MODULE_NAME, 0, &instance->config.deKey); if(sessionDesktop.length > 0) { @@ -78,12 +81,13 @@ void ffPrintDesktopEnvironment(FFinstance* instance) } else { - ffPrintFormatString(instance, &instance->config.deFormat, "DE", &instance->config.deFormat, 3, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &sessionDesktop}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &sessionVersion}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &sessionType} - ); + ffPrintFormatString(instance, FF_DE_MODULE_NAME, 0, &instance->config.deKey, &instance->config.deFormat, NULL, FF_DE_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &sessionDesktop}, + {FF_FORMAT_ARG_TYPE_STRBUF, &sessionVersion}, + {FF_FORMAT_ARG_TYPE_STRBUF, &sessionType} + }); } + ffStrbufDestroy(&sessionDesktop); ffStrbufDestroy(&sessionVersion); ffStrbufDestroy(&sessionType); diff --git a/src/modules/disk.c b/src/modules/disk.c index 148ff54db..11cf6f546 100644 --- a/src/modules/disk.c +++ b/src/modules/disk.c @@ -2,20 +2,23 @@ #include +#define FF_DISK_MODULE_NAME "Disk" +#define FF_DISK_NUM_FORMAT_ARGS 4 + static void getKey(FFinstance* instance, FFstrbuf* key, const char* folderPath, bool showFolderPath) { if(instance->config.diskKey.length == 0) { if(showFolderPath) - ffStrbufAppendF(key, "Disk (%s)", folderPath); + ffStrbufAppendF(key, FF_DISK_MODULE_NAME" (%s)", folderPath); else - ffStrbufSetS(key, "Disk"); + ffStrbufSetS(key, FF_DISK_MODULE_NAME); } else { - ffParseFormatString(key, &instance->config.diskKey, 1, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, folderPath} - ); + ffParseFormatString(key, &instance->config.diskKey, NULL, 1, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRING, folderPath} + }); } } @@ -32,17 +35,17 @@ static void printStatvfs(FFinstance* instance, FFstrbuf* key, struct statvfs* fs if(instance->config.diskFormat.length == 0) { - ffPrintLogoAndKey(instance, key, NULL); + ffPrintLogoAndKey(instance, key->chars, 0, NULL); printf("%uGB / %uGB (%u%%)\n", used, total, percentage); } else { - ffPrintFormatString(instance, key, NULL, &instance->config.diskFormat, 4, - (FFformatarg){FF_FORMAT_ARG_TYPE_UINT, &used}, - (FFformatarg){FF_FORMAT_ARG_TYPE_UINT, &total}, - (FFformatarg){FF_FORMAT_ARG_TYPE_UINT, &files}, - (FFformatarg){FF_FORMAT_ARG_TYPE_UINT8, &percentage} - ); + ffPrintFormatString(instance, key->chars, 0, NULL, &instance->config.diskFormat, NULL, FF_DISK_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_UINT, &used}, + {FF_FORMAT_ARG_TYPE_UINT, &total}, + {FF_FORMAT_ARG_TYPE_UINT, &files}, + {FF_FORMAT_ARG_TYPE_UINT8, &percentage} + }); } } @@ -63,7 +66,7 @@ static void printFolder(FFinstance* instance, const char* folderPath) int ret = statvfs(folderPath, &fs); if(ret != 0 && instance->config.diskFormat.length == 0) { - ffPrintError(instance, &key, NULL, "statvfs(\"%s\", &fs) != 0 (%i)", folderPath, ret); + ffPrintError(instance, key.chars, 0, NULL, &instance->config.diskFormat, FF_DISK_NUM_FORMAT_ARGS, "statvfs(\"%s\", &fs) != 0 (%i)", folderPath, ret); ffStrbufDestroy(&key); return; } @@ -87,7 +90,7 @@ void ffPrintDisk(FFinstance* instance) { FF_STRBUF_CREATE(key); getKey(instance, &key, "/", false); - ffPrintError(instance, &key, NULL, "statvfs failed for both / and /home"); + ffPrintError(instance, key.chars, 0, NULL, &instance->config.diskFormat, FF_DISK_NUM_FORMAT_ARGS, "statvfs failed for both / and /home"); ffStrbufDestroy(&key); return; } diff --git a/src/modules/font.c b/src/modules/font.c index b13b5e3d6..e5fa60b6b 100644 --- a/src/modules/font.c +++ b/src/modules/font.c @@ -1,5 +1,8 @@ #include "fastfetch.h" +#define FF_FONT_MODULE_NAME "Font" +#define FF_FONT_NUM_FORMAT_ARGS 17 + void ffPrintFont(FFinstance* instance) { FFstrbuf* plasma; @@ -16,7 +19,7 @@ void ffPrintFont(FFinstance* instance) if(plasma->length == 0 && gtk2->length == 0 && gtk3->length == 0 && gtk4->length == 0) { - ffPrintError(instance, &instance->config.fontKey, "Font", "No fonts found"); + ffPrintError(instance, FF_FONT_MODULE_NAME, 0, &instance->config.fontKey, &instance->config.fontFormat, FF_FONT_NUM_FORMAT_ARGS, "No fonts found"); return; } @@ -49,8 +52,7 @@ void ffPrintFont(FFinstance* instance) if(instance->config.fontFormat.length == 0) { - ffPrintLogoAndKey(instance, &instance->config.fontKey, "Font"); - + ffPrintLogoAndKey(instance, FF_FONT_MODULE_NAME, 0, &instance->config.fontKey); if(plasma->length > 0) { ffStrbufWriteTo(&plasmaPretty, stdout); @@ -63,25 +65,25 @@ void ffPrintFont(FFinstance* instance) } else { - ffPrintFormatString(instance, &instance->config.fontKey, "Font", &instance->config.fontFormat, 17, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, plasma}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &plasmaName}, - (FFformatarg){FF_FORMAT_ARG_TYPE_DOUBLE, &plasmaSize}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &plasmaPretty}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, gtk2}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, >k2Name}, - (FFformatarg){FF_FORMAT_ARG_TYPE_DOUBLE, >k2Size}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, >k2Pretty}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, gtk3}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, >k3Name}, - (FFformatarg){FF_FORMAT_ARG_TYPE_DOUBLE, >k3Size}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, >k3Pretty}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, gtk4}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, >k4Name}, - (FFformatarg){FF_FORMAT_ARG_TYPE_DOUBLE, >k4Size}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, >k4Pretty}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, >kPretty} - ); + ffPrintFormatString(instance, FF_FONT_MODULE_NAME, 0, &instance->config.fontKey, &instance->config.fontFormat, NULL, FF_FONT_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, plasma}, + {FF_FORMAT_ARG_TYPE_STRBUF, &plasmaName}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &plasmaSize}, + {FF_FORMAT_ARG_TYPE_STRBUF, &plasmaPretty}, + {FF_FORMAT_ARG_TYPE_STRBUF, gtk2}, + {FF_FORMAT_ARG_TYPE_STRBUF, >k2Name}, + {FF_FORMAT_ARG_TYPE_DOUBLE, >k2Size}, + {FF_FORMAT_ARG_TYPE_STRBUF, >k2Pretty}, + {FF_FORMAT_ARG_TYPE_STRBUF, gtk3}, + {FF_FORMAT_ARG_TYPE_STRBUF, >k3Name}, + {FF_FORMAT_ARG_TYPE_DOUBLE, >k3Size}, + {FF_FORMAT_ARG_TYPE_STRBUF, >k3Pretty}, + {FF_FORMAT_ARG_TYPE_STRBUF, gtk4}, + {FF_FORMAT_ARG_TYPE_STRBUF, >k4Name}, + {FF_FORMAT_ARG_TYPE_DOUBLE, >k4Size}, + {FF_FORMAT_ARG_TYPE_STRBUF, >k4Pretty}, + {FF_FORMAT_ARG_TYPE_STRBUF, >kPretty} + }); } ffStrbufDestroy(&plasmaName); @@ -93,8 +95,8 @@ void ffPrintFont(FFinstance* instance) ffStrbufDestroy(>k3Name); ffStrbufDestroy(>k3Pretty); - ffStrbufDestroy(>k3Name); - ffStrbufDestroy(>k3Pretty); + ffStrbufDestroy(>k4Name); + ffStrbufDestroy(>k4Pretty); ffStrbufDestroy(>kPretty); } diff --git a/src/modules/gpu.c b/src/modules/gpu.c index 4c740ef38..5faf5e4f7 100644 --- a/src/modules/gpu.c +++ b/src/modules/gpu.c @@ -4,42 +4,23 @@ #include #include -static void getKey(FFinstance* instance, FFstrbuf* key, uint8_t counter, bool showCounter) +#define FF_GPU_MODULE_NAME "GPU" +#define FF_GPU_NUM_FORMAT_ARGS 3 + +static void handleGPU(FFinstance* instance, struct pci_access* pacc, struct pci_dev* dev, FFcache* cache, uint8_t counter, char*(*ffpci_lookup_name)(struct pci_access*, char*, int, int, ...)) { - if(instance->config.gpuKey.length == 0) - { - if(showCounter) - ffStrbufAppendF(key, "GPU %hhu", counter); - else - ffStrbufSetS(key, "GPU"); - } - else - { - ffParseFormatString(key, &instance->config.gpuKey, 1, - (FFformatarg){FF_FORMAT_ARG_TYPE_UINT8, &counter} - ); - } -} - -static void handleGPU(FFinstance* instance, struct pci_access* pacc, struct pci_dev* dev, uint8_t counter, char*(*ffpci_lookup_name)(struct pci_access*, char*, int, int, ...)) -{ - char cacheKey[8]; - sprintf(cacheKey, "GPU%hhu", counter); - - FF_STRBUF_CREATE(key); - getKey(instance, &key, counter, true); - - if(ffPrintCachedValue(instance, &key, cacheKey)) - return; - char vendor[512]; ffpci_lookup_name(pacc, vendor, sizeof(vendor), PCI_LOOKUP_VENDOR, dev->vendor_id, dev->device_id); - char vendorPretty[512]; + const char* vendorPretty; if(strcasecmp(vendor, "Advanced Micro Devices, Inc. [AMD/ATI]") == 0) - strcpy(vendorPretty, "AMD ATI"); + vendorPretty = "AMD ATI"; + else if(strcasecmp(vendor, "NVIDIA Corporation") == 0) + vendorPretty = "Nvidia"; + else if(strcasecmp(vendor, "Intel Corporation") == 0) + vendorPretty = "Intel"; else - strcpy(vendorPretty, vendor); + vendorPretty = vendor; char name[512]; ffpci_lookup_name(pacc, name, sizeof(name), PCI_LOOKUP_DEVICE, dev->vendor_id, dev->device_id); @@ -47,28 +28,21 @@ static void handleGPU(FFinstance* instance, struct pci_access* pacc, struct pci_ FFstrbuf gpu; ffStrbufInitA(&gpu, 128); - if(instance->config.gpuFormat.length == 0) - { - ffStrbufSetF(&gpu, "%s %s", vendorPretty, name); - } - else - { - ffParseFormatString(&gpu, &instance->config.gpuFormat, 2, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, vendorPretty}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, name} - ); - } + ffStrbufSetF(&gpu, "%s %s", vendorPretty, name); - ffPrintAndSaveCachedValue(instance, &key, cacheKey, &gpu); + ffPrintAndAppendToCache(instance, FF_GPU_MODULE_NAME, counter, &instance->config.gpuKey, cache, &gpu, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRING, vendor}, + {FF_FORMAT_ARG_TYPE_STRING, vendorPretty}, + {FF_FORMAT_ARG_TYPE_STRING, name} + }); ffStrbufDestroy(&gpu); - ffStrbufDestroy(&key); } void ffPrintGPU(FFinstance* instance) { - FF_STRBUF_CREATE(key); - getKey(instance, &key, 1, false); + if(ffPrintFromCache(instance, FF_GPU_MODULE_NAME, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS)) + return; void* pci; if(instance->config.libPCI.length == 0) @@ -78,7 +52,7 @@ void ffPrintGPU(FFinstance* instance) if(pci == NULL) { - ffPrintError(instance, &key, NULL, "dlopen(\"libpci.so\", RTLD_LAZY) == NULL"); + ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "dlopen(\"libpci.so\", RTLD_LAZY) == NULL"); return; } @@ -86,7 +60,7 @@ void ffPrintGPU(FFinstance* instance) if(ffpci_alloc == NULL) { dlclose(pci); - ffPrintError(instance, &key, NULL, "dlsym(pci, \"pci_alloc\") == NULL"); + ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "dlsym(pci, \"pci_alloc\") == NULL"); return; } @@ -94,7 +68,7 @@ void ffPrintGPU(FFinstance* instance) if(ffpci_init == NULL) { dlclose(pci); - ffPrintError(instance, &key, NULL, "dlsym(pci, \"pci_init\") == NULL"); + ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "dlsym(pci, \"pci_init\") == NULL"); return; } @@ -102,7 +76,7 @@ void ffPrintGPU(FFinstance* instance) if(ffpci_scan_bus == NULL) { dlclose(pci); - ffPrintError(instance, &key, NULL, "dlsym(pci, \"pci_init\") == NULL"); + ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "dlsym(pci, \"pci_init\") == NULL"); return; } @@ -110,7 +84,7 @@ void ffPrintGPU(FFinstance* instance) if(ffpci_fill_info == NULL) { dlclose(pci); - ffPrintError(instance, &key, NULL, "dlsym(pci, \"pci_fill_info\") == NULL"); + ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "dlsym(pci, \"pci_fill_info\") == NULL"); return; } @@ -118,7 +92,7 @@ void ffPrintGPU(FFinstance* instance) if(ffpci_lookup_name == NULL) { dlclose(pci); - ffPrintError(instance, &key, NULL, "dlsym(pci, \"pci_lookup_name\") == NULL"); + ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "dlsym(pci, \"pci_lookup_name\") == NULL"); return; } @@ -126,12 +100,15 @@ void ffPrintGPU(FFinstance* instance) if(ffpci_cleanup == NULL) { dlclose(pci); - ffPrintError(instance, &key, NULL, "dlsym(pci, \"pci_cleanup\") == NULL"); + ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "dlsym(pci, \"pci_cleanup\") == NULL"); return; } uint8_t counter = 1; + FFcache cache; + ffCacheOpenWrite(instance, FF_GPU_MODULE_NAME, &cache); + struct pci_access *pacc; struct pci_dev *dev; @@ -148,13 +125,15 @@ void ffPrintGPU(FFinstance* instance) strcasecmp("3D controller", class) == 0 || strcasecmp("Display controller", class) == 0 ) { - handleGPU(instance, pacc, dev, counter++, ffpci_lookup_name); + handleGPU(instance, pacc, dev, &cache, counter++, ffpci_lookup_name); } } ffpci_cleanup(pacc); + ffCacheClose(&cache); + dlclose(pci); if(counter == 1) - ffPrintError(instance, &key, NULL, "No GPU found"); + ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "No GPU found"); } diff --git a/src/modules/host.c b/src/modules/host.c index be7d3dd1a..ca0a437f1 100644 --- a/src/modules/host.c +++ b/src/modules/host.c @@ -1,8 +1,11 @@ #include "fastfetch.h" +#define FF_HOST_MODULE_NAME "Host" +#define FF_HOST_NUM_FORMAT_ARGS 3 + void ffPrintHost(FFinstance* instance) { - if(ffPrintCachedValue(instance, &instance->config.hostKey, "Host")) + if(ffPrintFromCache(instance, FF_HOST_MODULE_NAME, &instance->config.hostKey, &instance->config.hostFormat, FF_HOST_NUM_FORMAT_ARGS)) return; FF_STRBUF_CREATE(family); @@ -16,49 +19,41 @@ void ffPrintHost(FFinstance* instance) if(family.length == 0 && name.length == 0) { - ffPrintError(instance, &instance->config.hostKey, "Host", "neither family nor name could be determined"); + ffPrintError(instance, FF_HOST_MODULE_NAME, 0, &instance->config.hostKey, &instance->config.hostFormat, FF_HOST_NUM_FORMAT_ARGS, "neither family nor name could be determined"); return; } FF_STRBUF_CREATE(host); - if(instance->config.hostFormat.length == 0) + if(name.length == 0) { - if(name.length == 0) - { - ffStrbufAppend(&host, &family); - } - else if(family.length == 0) - { - ffStrbufAppend(&host, &name); - } - else - { - ffStrbufAppend(&host, &family); - ffStrbufAppendC(&host, ' '); - ffStrbufAppend(&host, &name); - } - - if( - version.length > 0 && - ffStrbufIgnCaseCompS(&version, "None") != 0 && - ffStrbufIgnCaseCompS(&version, "To be filled by O.E.M.") != 0 - ) { - ffStrbufAppendC(&host, ' '); - ffStrbufAppend(&host, &version); - } + ffStrbufAppend(&host, &family); + } + else if(family.length == 0) + { + ffStrbufAppend(&host, &name); } else { - ffParseFormatString(&host, &instance->config.hostFormat, 3, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &family}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &name}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &version} - ); + ffStrbufAppend(&host, &family); + ffStrbufAppendC(&host, ' '); + ffStrbufAppend(&host, &name); } - ffPrintAndSaveCachedValue(instance, &instance->config.hostKey, "Host", &host); - ffStrbufDestroy(&host); + if( + version.length > 0 && + ffStrbufIgnCaseCompS(&version, "None") != 0 && + ffStrbufIgnCaseCompS(&version, "To be filled by O.E.M.") != 0 + ) { + ffStrbufAppendC(&host, ' '); + ffStrbufAppend(&host, &version); + } + + ffPrintAndSaveToCache(instance, FF_HOST_MODULE_NAME, &instance->config.hostKey, &host, &instance->config.hostFormat, FF_HOST_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &family}, + {FF_FORMAT_ARG_TYPE_STRBUF, &name}, + {FF_FORMAT_ARG_TYPE_STRBUF, &version} + }); ffStrbufDestroy(&family); ffStrbufDestroy(&name); diff --git a/src/modules/icons.c b/src/modules/icons.c index 02eb65810..6eeb2bda6 100644 --- a/src/modules/icons.c +++ b/src/modules/icons.c @@ -1,5 +1,8 @@ #include "fastfetch.h" +#define FF_ICONS_MODULE_NAME "Icons" +#define FF_ICONS_NUM_FORMAT_ARGS 5 + void ffPrintIcons(FFinstance* instance) { FFstrbuf* plasma; @@ -16,7 +19,7 @@ void ffPrintIcons(FFinstance* instance) if(plasma->length == 0 && gtk2->length == 0 && gtk3->length == 0 && gtk4->length == 0) { - ffPrintError(instance, &instance->config.iconsKey, "Icons", "No icons found"); + ffPrintError(instance, FF_ICONS_MODULE_NAME, 0, &instance->config.iconsKey, &instance->config.iconsFormat, FF_ICONS_NUM_FORMAT_ARGS, "No icons could be found"); return; } @@ -25,7 +28,7 @@ void ffPrintIcons(FFinstance* instance) if(instance->config.iconsFormat.length == 0) { - ffPrintLogoAndKey(instance, &instance->config.iconsKey, "Icons"); + ffPrintLogoAndKey(instance, FF_ICONS_MODULE_NAME, 0, &instance->config.iconsKey); if(plasma->length > 0) { @@ -40,13 +43,13 @@ void ffPrintIcons(FFinstance* instance) } else { - ffPrintFormatString(instance, &instance->config.iconsKey, "Icons", &instance->config.iconsFormat, 5, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, plasma}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, gtk2}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, gtk3}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, gtk4}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, >kPretty} - ); + ffPrintFormatString(instance, FF_ICONS_MODULE_NAME, 0, &instance->config.iconsKey, &instance->config.iconsFormat, NULL, FF_ICONS_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, plasma}, + {FF_FORMAT_ARG_TYPE_STRBUF, gtk2}, + {FF_FORMAT_ARG_TYPE_STRBUF, gtk3}, + {FF_FORMAT_ARG_TYPE_STRBUF, gtk4}, + {FF_FORMAT_ARG_TYPE_STRBUF, >kPretty} + }); } ffStrbufDestroy(>kPretty); diff --git a/src/modules/kernel.c b/src/modules/kernel.c index 6bb67e73f..867284690 100644 --- a/src/modules/kernel.c +++ b/src/modules/kernel.c @@ -1,18 +1,21 @@ #include "fastfetch.h" +#define FF_KERNEL_MODULE_NAME "Kernel" +#define FF_KERNEL_NUM_FORMAT_ARGS 3 + void ffPrintKernel(FFinstance* instance) { if(instance->config.kernelFormat.length == 0) { - ffPrintLogoAndKey(instance, &instance->config.kernelKey, "Kernel"); + ffPrintLogoAndKey(instance, FF_KERNEL_MODULE_NAME, 0, &instance->config.kernelKey); puts(instance->state.utsname.release); } else { - ffPrintFormatString(instance, &instance->config.kernelKey, "Kernel", &instance->config.kernelFormat, 3, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, instance->state.utsname.sysname}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, instance->state.utsname.release}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, instance->state.utsname.version} - ); + ffPrintFormatString(instance, FF_KERNEL_MODULE_NAME, 0, &instance->config.kernelKey, &instance->config.kernelFormat, NULL, FF_KERNEL_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRING, instance->state.utsname.sysname}, + {FF_FORMAT_ARG_TYPE_STRING, instance->state.utsname.release}, + {FF_FORMAT_ARG_TYPE_STRING, instance->state.utsname.version} + }); } } diff --git a/src/modules/locale.c b/src/modules/locale.c index bd3cc30ca..1c9c6f989 100644 --- a/src/modules/locale.c +++ b/src/modules/locale.c @@ -2,58 +2,47 @@ #include +#define FF_LOCALE_MODULE_NAME "Locale" +#define FF_LOCALE_NUM_FORMAT_ARGS 1 + void ffPrintLocale(FFinstance* instance) { - if(ffPrintCachedValue(instance, &instance->config.localeKey, "Locale")) - return; + if(ffPrintFromCache(instance, FF_LOCALE_MODULE_NAME, &instance->config.localeKey, &instance->config.localeFormat, FF_LOCALE_NUM_FORMAT_ARGS)) + return; char localeCode[256]; - /* Try to open /etc/locale.conf in read-only mode */ FILE *fp; fp = fopen("/etc/locale.conf", "r"); - /* File does not exist */ if (fp == NULL) { - /* Check if LANG exists */ if (getenv("LANG") != NULL) strcpy(localeCode, getenv("LANG")); - /* Check if LC_ALL exists */ else if (getenv("LC_ALL") != NULL) strcpy(localeCode, getenv("LC_ALL")); - /* Check if LC_CTYPE exists */ else if (getenv("LC_CTYPE") != NULL) strcpy(localeCode, getenv("LC_CTYPE")); - /* Check if LC_CTYPE exists */ else if (getenv("LC_CTYPE") != NULL) strcpy(localeCode, getenv("LC_CTYPE")); - /* Check if LC_MESSAGES exists */ else if (getenv("LC_MESSAGES") != NULL) strcpy(localeCode, getenv("LC_MESSAGES")); - /* User has broken system */ - else - ffPrintError(instance, &instance->config.localeKey, "Locale", "Locale not found!"); - /* /etc/locale.conf exists */ } else { ffParsePropFile("/etc/locale.conf", "LANG=%[^\n]", localeCode); - - /* Free pointer to file */ fclose(fp); } + if(localeCode[0] == '\0') + { + ffPrintError(instance, FF_LOCALE_MODULE_NAME, 0, &instance->config.localeKey, &instance->config.localeFormat, FF_LOCALE_NUM_FORMAT_ARGS, "No locale found"); + return; + } + FF_STRBUF_CREATE(locale); + ffStrbufSetS(&locale, localeCode); - if(instance->config.localeFormat.length == 0) - { - ffStrbufSetS(&locale, localeCode); - } - else - { - ffParseFormatString(&locale, &instance->config.localeFormat, 1, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, localeCode} - ); - } + ffPrintAndSaveToCache(instance, FF_LOCALE_MODULE_NAME, &instance->config.localeKey, &locale, &instance->config.localeFormat, FF_LOCALE_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRING, localeCode} + }); - ffPrintAndSaveCachedValue(instance, &instance->config.localeKey, "Locale", &locale); ffStrbufDestroy(&locale); } diff --git a/src/modules/memory.c b/src/modules/memory.c index 4c6d8dda5..dc0bc2b7f 100644 --- a/src/modules/memory.c +++ b/src/modules/memory.c @@ -1,11 +1,14 @@ #include "fastfetch.h" +#define FF_MEMORY_MODULE_NAME "Memory" +#define FF_MEMORY_NUM_FORMAT_ARGS 3 + // Impl inspired by: https://github.com/sam-barr/paleofetch/blob/b7c58a52c0de39b53c9b5f417889a5886d324bfa/paleofetch.c#L544 void ffPrintMemory(FFinstance* instance) { FILE* meminfo = fopen("/proc/meminfo", "r"); if(meminfo == NULL) { - ffPrintError(instance, &instance->config.memoryKey, "Memory", "fopen(\"/proc/meminfo\", \"r\") == NULL"); + ffPrintError(instance, FF_MEMORY_MODULE_NAME, 0, &instance->config.memoryKey, &instance->config.memoryFormat, FF_MEMORY_NUM_FORMAT_ARGS, "fopen(\"/proc/meminfo\", \"r\") == NULL"); return; } @@ -32,17 +35,23 @@ void ffPrintMemory(FFinstance* instance) uint32_t total_mem = total / 1024; uint8_t percentage = (uint8_t) ((used_mem / (double) total_mem) * 100); + if(used_mem == 0 && total_mem == 0 && percentage == 0) + { + ffPrintError(instance, FF_MEMORY_MODULE_NAME, 0, &instance->config.memoryKey, &instance->config.memoryFormat, FF_MEMORY_NUM_FORMAT_ARGS, "/proc/meminfo could't be parsed"); + return; + } + if(instance->config.memoryFormat.length == 0) { - ffPrintLogoAndKey(instance, &instance->config.memoryKey, "Memory"); + ffPrintLogoAndKey(instance, FF_MEMORY_MODULE_NAME, 0, &instance->config.memoryKey); printf("%uMiB / %uMiB (%u%%)\n", used_mem, total_mem, percentage); } else { - ffPrintFormatString(instance, &instance->config.memoryKey, "Memory", &instance->config.memoryFormat, 3, - (FFformatarg){FF_FORMAT_ARG_TYPE_UINT, &used_mem}, - (FFformatarg){FF_FORMAT_ARG_TYPE_UINT, &total_mem}, - (FFformatarg){FF_FORMAT_ARG_TYPE_UINT8, &percentage} - ); + ffPrintFormatString(instance, FF_MEMORY_MODULE_NAME, 0, &instance->config.memoryKey, &instance->config.memoryFormat, NULL, FF_MEMORY_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_UINT, &used_mem}, + {FF_FORMAT_ARG_TYPE_UINT, &total_mem}, + {FF_FORMAT_ARG_TYPE_UINT8, &percentage} + }); } } diff --git a/src/modules/os.c b/src/modules/os.c index 0d16439fd..85212e60f 100644 --- a/src/modules/os.c +++ b/src/modules/os.c @@ -1,8 +1,11 @@ #include "fastfetch.h" +#define FF_OS_MODULE_NAME "OS" +#define FF_OS_NUM_FORMAT_ARGS 12 + void ffPrintOS(FFinstance* instance) { - if(ffPrintCachedValue(instance, &instance->config.osKey, "OS")) + if(ffPrintFromCache(instance, FF_OS_MODULE_NAME, &instance->config.osKey, &instance->config.osFormat, FF_OS_NUM_FORMAT_ARGS)) return; FILE* osRelease = fopen("/etc/os-release", "r"); @@ -12,7 +15,7 @@ void ffPrintOS(FFinstance* instance) if(osRelease == NULL) { - ffPrintError(instance, &instance->config.osKey, "OS", "couldn't read /etc/os-release nor /usr/lib/os-release"); + ffPrintError(instance, FF_OS_MODULE_NAME, 0, &instance->config.osKey, &instance->config.osFormat, FF_OS_NUM_FORMAT_ARGS, "couldn't read /etc/os-release nor /usr/lib/os-release"); return; } @@ -64,72 +67,66 @@ void ffPrintOS(FFinstance* instance) FF_STRBUF_CREATE(os); - if(instance->config.osFormat.length == 0) + if(prettyName[0] != '\0') { - if(prettyName[0] != '\0') - { - ffStrbufAppendS(&os, prettyName); - } - else if(name[0] == '\0' && id[0] == '\0') - { - ffStrbufAppendS(&os, instance->state.utsname.sysname); - } - else - { - if(name[0] != '\0') - ffStrbufAppendS(&os, name); - else - ffStrbufAppendS(&os, id); - - if(version[0] != '\0') - { - ffStrbufAppendC(&os, ' '); - ffStrbufAppendS(&os, version); - } - else - { - if(versionId[0] != '\0') - { - ffStrbufAppendC(&os, ' '); - ffStrbufAppendS(&os, versionId); - } - - if(variant[0] != '\0') - { - ffStrbufAppendS(&os, " ("); - ffStrbufAppendS(&os, variant); - ffStrbufAppendC(&os, ')'); - } - else if(variantId[0] != '\0') - { - ffStrbufAppendS(&os, " ("); - ffStrbufAppendS(&os, variantId); - ffStrbufAppendC(&os, ')'); - } - } - } - - ffStrbufAppendC(&os, ' '); - ffStrbufAppendS(&os, instance->state.utsname.machine); + ffStrbufAppendS(&os, prettyName); + } + else if(name[0] == '\0' && id[0] == '\0') + { + ffStrbufAppendS(&os, instance->state.utsname.sysname); } else { - ffParseFormatString(&os, &instance->config.osFormat, 12, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, instance->state.utsname.sysname}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, name}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, prettyName}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, id}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, idLike}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, variant}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, variantId}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, version}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, versionId}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, versionCodename}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, buildId}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, instance->state.utsname.machine} - ); + if(name[0] != '\0') + ffStrbufAppendS(&os, name); + else + ffStrbufAppendS(&os, id); + + if(version[0] != '\0') + { + ffStrbufAppendC(&os, ' '); + ffStrbufAppendS(&os, version); + } + else + { + if(versionId[0] != '\0') + { + ffStrbufAppendC(&os, ' '); + ffStrbufAppendS(&os, versionId); + } + + if(variant[0] != '\0') + { + ffStrbufAppendS(&os, " ("); + ffStrbufAppendS(&os, variant); + ffStrbufAppendC(&os, ')'); + } + else if(variantId[0] != '\0') + { + ffStrbufAppendS(&os, " ("); + ffStrbufAppendS(&os, variantId); + ffStrbufAppendC(&os, ')'); + } + } } - ffPrintAndSaveCachedValue(instance, &instance->config.osKey, "OS", &os); + ffStrbufAppendC(&os, ' '); + ffStrbufAppendS(&os, instance->state.utsname.machine); + + ffPrintAndSaveToCache(instance, FF_OS_MODULE_NAME, &instance->config.osKey, &os, &instance->config.osFormat, FF_OS_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRING, instance->state.utsname.sysname}, + {FF_FORMAT_ARG_TYPE_STRING, name}, + {FF_FORMAT_ARG_TYPE_STRING, prettyName}, + {FF_FORMAT_ARG_TYPE_STRING, id}, + {FF_FORMAT_ARG_TYPE_STRING, idLike}, + {FF_FORMAT_ARG_TYPE_STRING, variant}, + {FF_FORMAT_ARG_TYPE_STRING, variantId}, + {FF_FORMAT_ARG_TYPE_STRING, version}, + {FF_FORMAT_ARG_TYPE_STRING, versionId}, + {FF_FORMAT_ARG_TYPE_STRING, versionCodename}, + {FF_FORMAT_ARG_TYPE_STRING, buildId}, + {FF_FORMAT_ARG_TYPE_STRING, instance->state.utsname.machine} + }); + ffStrbufDestroy(&os); } diff --git a/src/modules/packages.c b/src/modules/packages.c index 92c402d45..651e45a7a 100644 --- a/src/modules/packages.c +++ b/src/modules/packages.c @@ -2,6 +2,9 @@ #include +#define FF_PACKAGES_MODULE_NAME "Packages" +#define FF_PACKAGES_NUM_FORMAT_ARGS 3 + static uint32_t get_num_dirs(const char* dirname) { uint32_t num_dirs = 0; DIR * dirp; @@ -32,13 +35,13 @@ void ffPrintPackages(FFinstance* instance) if(all == 0) { - ffPrintError(instance, &instance->config.packagesKey, "Packages", "No packages from known package managers found"); + ffPrintError(instance, FF_PACKAGES_MODULE_NAME, 0, &instance->config.packagesKey, &instance->config.packagesFormat, FF_PACKAGES_NUM_FORMAT_ARGS, "No packages from known package managers found"); return; } if(instance->config.packagesFormat.length == 0) { - ffPrintLogoAndKey(instance, &instance->config.packagesKey, "Packages"); + ffPrintLogoAndKey(instance, FF_PACKAGES_MODULE_NAME, 0, &instance->config.batteryKey); #define FF_PRINT_PACKAGE(name) \ if(name > 0) \ @@ -57,10 +60,10 @@ void ffPrintPackages(FFinstance* instance) } else { - ffPrintFormatString(instance, &instance->config.packagesKey, "Packages", &instance->config.packagesFormat, 3, - (FFformatarg){FF_FORMAT_ARG_TYPE_UINT, &all}, - (FFformatarg){FF_FORMAT_ARG_TYPE_UINT, &pacman}, - (FFformatarg){FF_FORMAT_ARG_TYPE_UINT, &flatpak} - ); + ffPrintFormatString(instance, FF_PACKAGES_MODULE_NAME, 0, &instance->config.packagesKey, &instance->config.packagesFormat, NULL, FF_PACKAGES_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_UINT, &all}, + {FF_FORMAT_ARG_TYPE_UINT, &pacman}, + {FF_FORMAT_ARG_TYPE_UINT, &flatpak} + }); } } diff --git a/src/modules/resolution.c b/src/modules/resolution.c index ee9d31862..aa6ea3838 100644 --- a/src/modules/resolution.c +++ b/src/modules/resolution.c @@ -3,56 +3,57 @@ #include #include -static int getCurrentRate(FFinstance* instance, Display* display) +#define FF_RESOLUTION_MODULE_NAME "Resolution" +#define FF_RESOLUTION_NUM_FORMAT_ARGS 3 + +static void printValue(FFinstance* instance, uint8_t moduleIndex, FFcache* cache, int width, int height, int refreshRate) { - void* xrandr; - if(instance->config.libXrandr.length == 0) - xrandr = dlopen("libXrandr.so", RTLD_LAZY); - else - xrandr = dlopen(instance->config.libXrandr.chars, RTLD_LAZY); + FFstrbuf value; + ffStrbufInitA(&value, 32); + ffStrbufAppendF(&value, "%ix%i", width, height); - if(xrandr == NULL) - return 0; + if(refreshRate > 0) + ffStrbufAppendF(&value, " @ %iHz", refreshRate); - XRRScreenConfiguration*(*ffXRRGetScreenInfo)(Display*, Window) = dlsym(xrandr, "XRRGetScreenInfo"); - if(ffXRRGetScreenInfo == NULL) - { - dlclose(xrandr); - return 0; - } - - short(*ffXRRConfigCurrentRate)(XRRScreenConfiguration*) = dlsym(xrandr, "XRRConfigCurrentRate"); - if(ffXRRConfigCurrentRate == NULL) - { - dlclose(xrandr); - return 0; - } - - Window root = RootWindow(display, 0); - - XRRScreenConfiguration* xrrscreenconf = ffXRRGetScreenInfo(display, root); - if(xrrscreenconf == NULL) - { - dlclose(xrandr); - return 0; - } - - short currentRate = ffXRRConfigCurrentRate(xrrscreenconf); - - void(*ffXRRFreeScreenConfigInfo)(XRRScreenConfiguration*) = dlsym(xrandr, "XRRFreeScreenConfigInfo"); - if(ffXRRFreeScreenConfigInfo != NULL) - ffXRRFreeScreenConfigInfo(xrrscreenconf); - - dlclose(xrandr); - - return (int) currentRate; + ffPrintAndAppendToCache(instance, FF_RESOLUTION_MODULE_NAME, moduleIndex, &instance->config.resolutionKey, cache, &value, &instance->config.resolutionFormat, FF_RESOLUTION_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_INT, &width}, + {FF_FORMAT_ARG_TYPE_INT, &height}, + {FF_FORMAT_ARG_TYPE_INT, &refreshRate} + }); } -void ffPrintResolution(FFinstance* instance) +static Display* openDisplay(FFinstance* instance, void* library, bool printErrors) { - if(ffPrintCachedValue(instance, &instance->config.resolutionFormat, "Resolution")) - return; + Display*(*ffXOpenDisplay)(const char*) = dlsym(library, "XOpenDisplay"); + if(ffXOpenDisplay == NULL) + { + dlclose(library); + if(printErrors) + ffPrintError(instance, FF_RESOLUTION_MODULE_NAME, 0, &instance->config.resolutionKey, &instance->config.resolutionFormat, FF_RESOLUTION_NUM_FORMAT_ARGS, "dlsym(library, \"XOpenDisplay\") == NULL"); + return NULL; + } + Display* display = ffXOpenDisplay(NULL); + if(display == NULL) + { + dlclose(library); + if(printErrors) + ffPrintError(instance, FF_RESOLUTION_MODULE_NAME, 0, &instance->config.resolutionKey, &instance->config.resolutionFormat, FF_RESOLUTION_NUM_FORMAT_ARGS, "ffXOpenDisplay(NULL) == NULL"); + return NULL; + } + + return display; +} + +static void closeDisplay(void* library, Display* display) +{ + int(*ffXCloseDisplay)(Display*) = dlsym(library, "XCloseDisplay"); + if(ffXCloseDisplay != NULL) + ffXCloseDisplay(display); +} + +static void printResolutionX11Backend(FFinstance* instance) +{ void* x11; if(instance->config.libX11.length == 0) x11 = dlopen("libX11.so", RTLD_LAZY); @@ -61,50 +62,137 @@ void ffPrintResolution(FFinstance* instance) if(x11 == NULL) { - ffPrintError(instance, &instance->config.resolutionFormat, "Resolution", "dlopen(\"libX11.so\", RTLD_LAZY) == NULL"); + ffPrintError(instance, FF_RESOLUTION_MODULE_NAME, 0, &instance->config.resolutionKey, &instance->config.resolutionFormat, FF_RESOLUTION_NUM_FORMAT_ARGS, "dlopen(\"libX11.so\", RTLD_LAZY) == NULL"); return; } - Display*(*ffXOpenDisplay)(const char*) = dlsym(x11, "XOpenDisplay"); - if(ffXOpenDisplay == NULL) - { - dlclose(x11); - ffPrintError(instance, &instance->config.resolutionFormat, "Resolution", "dlsym(x11, \"XOpenDisplay\") == NULL"); - return; - } - - Display* display = ffXOpenDisplay(NULL); + Display* display = openDisplay(instance, x11, true); if(display == NULL) + return; + + int screenCount = ScreenCount(display); + if(screenCount < 1) { + closeDisplay(x11, display); dlclose(x11); - ffPrintError(instance, &instance->config.resolutionFormat, "Resolution", "ffXOpenDisplay(NULL) == NULL"); + ffPrintError(instance, FF_RESOLUTION_MODULE_NAME, 0, &instance->config.resolutionKey, &instance->config.resolutionFormat, FF_RESOLUTION_NUM_FORMAT_ARGS, "ScreenCount(display) < 1: %i", screenCount); return; } - Screen* screen = DefaultScreenOfDisplay(display); + FFcache cache; + ffCacheOpenWrite(instance, FF_RESOLUTION_MODULE_NAME, &cache); - int currentRate = getCurrentRate(instance, display); + for(int i = 0; i < screenCount; i++) + { + Screen* screen = ScreenOfDisplay(display, i); + uint8_t moduleIndex = screenCount == 1 ? 0 : i + 1; + printValue(instance, moduleIndex, &cache, WidthOfScreen(screen), HeightOfScreen(screen), 0); + } + ffCacheClose(&cache); + + closeDisplay(x11, display); dlclose(x11); - - FF_STRBUF_CREATE(resolution); - - if(instance->config.resolutionFormat.length == 0) - { - ffStrbufAppendF(&resolution, "%ix%i", screen->width, screen->height); - - if(currentRate > 0) - ffStrbufAppendF(&resolution, " @ %iHz", currentRate); - } - else - { - ffParseFormatString(&resolution, &instance->config.resolutionFormat, 3, - (FFformatarg){FF_FORMAT_ARG_TYPE_INT, &screen->width}, - (FFformatarg){FF_FORMAT_ARG_TYPE_INT, &screen->height}, - (FFformatarg){FF_FORMAT_ARG_TYPE_INT, ¤tRate} - ); - } - - ffPrintAndSaveCachedValue(instance, &instance->config.resolutionKey, "Resolution", &resolution); - ffStrbufDestroy(&resolution); +} + +static int getCurrentRate(void* xrandr, Display* display) +{ + XRRScreenConfiguration*(*ffXRRGetScreenInfo)(Display*, Window) = dlsym(xrandr, "XRRGetScreenInfo"); + if(ffXRRGetScreenInfo == NULL) + return 0; + + short(*ffXRRConfigCurrentRate)(XRRScreenConfiguration*) = dlsym(xrandr, "XRRConfigCurrentRate"); + if(ffXRRConfigCurrentRate == NULL) + return 0; + + XRRMonitorInfo*(*ffXRRGetMonitors)(Display*, Window, Bool, int*) = dlsym(xrandr, "XRRGetMonitors"); + if(ffXRRGetMonitors == NULL) + return 0; + + void(*ffXRRFreeMonitors)(XRRMonitorInfo*) = dlsym(xrandr, "XRRFreeMonitors"); + if(ffXRRFreeMonitors == NULL) + return 0; + + XRRScreenConfiguration* xrrscreenconf = ffXRRGetScreenInfo(display, RootWindow(display, 0)); + if(xrrscreenconf == NULL) + return 0; + + short currentRate = ffXRRConfigCurrentRate(xrrscreenconf); + + void(*ffXRRFreeScreenConfigInfo)(XRRScreenConfiguration*) = dlsym(xrandr, "XRRFreeScreenConfigInfo"); + if(ffXRRFreeScreenConfigInfo != NULL) + ffXRRFreeScreenConfigInfo(xrrscreenconf); + + return (int) currentRate; +} + +static bool printResolutionXrandrBackend(FFinstance* instance) +{ + void* xrandr; + if(instance->config.libXrandr.length == 0) + xrandr = dlopen("libXrandr.so", RTLD_LAZY); + else + xrandr = dlopen(instance->config.libXrandr.chars, RTLD_LAZY); + + if(xrandr == NULL) + return false; + + XRRMonitorInfo*(*ffXRRGetMonitors)(Display*, Window, Bool, int*) = dlsym(xrandr, "XRRGetMonitors"); + if(ffXRRGetMonitors == NULL) + { + dlclose(xrandr); + return false; + } + + Display* display = openDisplay(instance, xrandr, false); + if(display == NULL) + return false; + + int numberOfMonitors; + XRRMonitorInfo* monitors = ffXRRGetMonitors(display, RootWindow(display, 0), False, &numberOfMonitors); + if(monitors == NULL) + { + closeDisplay(xrandr, display); + dlclose(xrandr); + return false; + } + + if(numberOfMonitors < 1) + { + closeDisplay(xrandr, display); + dlclose(xrandr); + return false; + } + + int refreshRate = getCurrentRate(xrandr, display); + + FFcache cache; + ffCacheOpenWrite(instance, FF_RESOLUTION_MODULE_NAME, &cache); + + for(int i = 0; i < numberOfMonitors; i++) + { + uint8_t moduleIndex = numberOfMonitors == 1 ? 0 : i + 1; + printValue(instance, moduleIndex, &cache, monitors[i].width, monitors[i].height, refreshRate); + } + + ffCacheClose(&cache); + + void(*ffXRRFreeMonitors)(XRRMonitorInfo*) = dlsym(xrandr, "XRRFreeMonitors"); + if(ffXRRFreeMonitors != NULL) + ffXRRFreeMonitors(monitors); + + dlclose(xrandr); + + return true; +} + +void ffPrintResolution(FFinstance* instance) +{ + if(ffPrintFromCache(instance, FF_RESOLUTION_MODULE_NAME, &instance->config.resolutionKey, &instance->config.resolutionFormat, FF_RESOLUTION_NUM_FORMAT_ARGS)) + return; + + if(printResolutionXrandrBackend(instance)) + return; + + printResolutionX11Backend(instance); } diff --git a/src/modules/seperator.c b/src/modules/seperator.c index 1b6040031..75e77e43d 100644 --- a/src/modules/seperator.c +++ b/src/modules/seperator.c @@ -4,7 +4,7 @@ void ffPrintSeperator(FFinstance* instance) { ffPrintLogoLine(instance); - for(uint8_t i = 0; i < instance->config.titleLength; i++) + for(uint32_t i = 0; i < instance->config.titleLength; i++) putchar('-'); putchar('\n'); } diff --git a/src/modules/shell.c b/src/modules/shell.c index cb462972c..c7be41960 100644 --- a/src/modules/shell.c +++ b/src/modules/shell.c @@ -2,15 +2,18 @@ #include +#define FF_SHELL_MODULE_NAME "Shell" +#define FF_SHELL_NUM_FORMAT_ARGS 2 + void ffPrintShell(FFinstance* instance) { - if(ffPrintCachedValue(instance, &instance->config.shellKey, "Shell")) + if(ffPrintFromCache(instance, FF_SHELL_MODULE_NAME, &instance->config.shellKey, &instance->config.shellFormat, FF_SHELL_NUM_FORMAT_ARGS)) return; char* shellPath = getenv("SHELL"); if(shellPath == NULL) { - ffPrintError(instance, &instance->config.shellKey, "Shell", "getenv(\"SHELL\") == NULL"); + ffPrintError(instance, FF_SHELL_MODULE_NAME, 0, &instance->config.shellKey, &instance->config.shellFormat, FF_SHELL_NUM_FORMAT_ARGS, "getenv(\"SHELL\") == NULL"); return; } @@ -30,19 +33,12 @@ void ffPrintShell(FFinstance* instance) } FF_STRBUF_CREATE(shell); + ffStrbufSetS(&shell, shellName); - if(instance->config.shellFormat.length == 0) - { - ffStrbufSetS(&shell, shellName); - } - else - { - ffParseFormatString(&shell, &instance->config.shellFormat, 2, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, shellPath}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, shellName} - ); - } + ffPrintAndSaveToCache(instance, FF_SHELL_MODULE_NAME, &instance->config.shellKey, &shell, &instance->config.shellFormat, FF_SHELL_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRING, shellPath}, + {FF_FORMAT_ARG_TYPE_STRING, shellName} + }); - ffPrintAndSaveCachedValue(instance, &instance->config.shellKey, "Shell", &shell); ffStrbufDestroy(&shell); } diff --git a/src/modules/terminal.c b/src/modules/terminal.c index d102ba31a..30d590601 100644 --- a/src/modules/terminal.c +++ b/src/modules/terminal.c @@ -1,5 +1,8 @@ #include "fastfetch.h" +#define FF_TERMINAL_MODULE_NAME "Terminal" +#define FF_TERMINAL_NUM_FORMAT_ARGS 3 + void ffPrintTerminal(FFinstance* instance) { FFstrbuf* exeName; @@ -10,7 +13,7 @@ void ffPrintTerminal(FFinstance* instance) if(error->length > 0) { - ffPrintError(instance, &instance->config.terminalKey, "Terminal", error->chars); + ffPrintError(instance, FF_TERMINAL_MODULE_NAME, 0, &instance->config.terminalKey, &instance->config.terminalFormat, FF_TERMINAL_NUM_FORMAT_ARGS, error->chars); return; } @@ -23,15 +26,15 @@ void ffPrintTerminal(FFinstance* instance) if(instance->config.terminalFormat.length == 0) { - ffPrintLogoAndKey(instance, &instance->config.terminalKey, "Terminal"); + ffPrintLogoAndKey(instance, FF_TERMINAL_MODULE_NAME, 0, &instance->config.terminalKey); ffStrbufPutTo(name, stdout); } else { - ffPrintFormatString(instance, &instance->config.terminalKey, "Terminal", &instance->config.terminalFormat, 3, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, exeName}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, processName}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, name} - ); + ffPrintFormatString(instance, FF_TERMINAL_MODULE_NAME, 0, &instance->config.terminalKey, &instance->config.terminalFormat, NULL, FF_TERMINAL_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, exeName}, + {FF_FORMAT_ARG_TYPE_STRBUF, processName}, + {FF_FORMAT_ARG_TYPE_STRBUF, name} + }); } } diff --git a/src/modules/terminalfont.c b/src/modules/terminalfont.c index 6edf582a9..3fd5ab415 100644 --- a/src/modules/terminalfont.c +++ b/src/modules/terminalfont.c @@ -2,6 +2,9 @@ #include +#define FF_TERMFONT_MODULE_NAME "Terminal Font" +#define FF_TERMFONT_NUM_FORMAT_ARGS 4 + static void printTerminalFont(FFinstance* instance, const char* font) { FF_STRBUF_CREATE(name); @@ -12,17 +15,17 @@ static void printTerminalFont(FFinstance* instance, const char* font) if(instance->config.termFontFormat.length == 0) { - ffPrintLogoAndKey(instance, &instance->config.termFontKey, "Terminal font"); + ffPrintLogoAndKey(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.termFontKey); ffStrbufPutTo(&pretty, stdout); } else { - ffPrintFormatString(instance, &instance->config.termFontKey, "Terminal font", &instance->config.termFontFormat, 4, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, font}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &name}, - (FFformatarg){FF_FORMAT_ARG_TYPE_DOUBLE, &size}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &pretty} - ); + ffPrintFormatString(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.termFontKey, &instance->config.termFontFormat, NULL, FF_TERMFONT_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRING, font}, + {FF_FORMAT_ARG_TYPE_STRBUF, &name}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &size}, + {FF_FORMAT_ARG_TYPE_STRBUF, &pretty} + }); } ffStrbufDestroy(&name); @@ -35,7 +38,7 @@ static void printKonsole(FFinstance* instance) ffParsePropFileHome(instance, ".config/konsolerc", "DefaultProfile=%[^\n]", profile); if(profile[0] == '\0') { - ffPrintError(instance, &instance->config.termFontKey, "Terminal Font", "Couldn't find \"DefaultProfile=%[^\n]\" in \".config/konsolerc\""); + ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.termFontKey, &instance->config.termFontFormat, FF_TERMFONT_NUM_FORMAT_ARGS, "Couldn't find \"DefaultProfile=%[^\n]\" in \".config/konsolerc\""); return; } @@ -46,7 +49,7 @@ static void printKonsole(FFinstance* instance) ffParsePropFileHome(instance, profilePath, "Font=%[^\n]", font); if(font[0] == '\0') { - ffPrintError(instance, &instance->config.termFontKey, "Terminal Font", "Couldn't find \"Font=%%[^\\n]\" in \"%s\"", profilePath); + ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.termFontKey, &instance->config.termFontFormat, FF_TERMFONT_NUM_FORMAT_ARGS, "Couldn't find \"Font=%%[^\\n]\" in \"%s\"", profilePath); return; } @@ -70,7 +73,7 @@ void ffPrintTerminalFont(FFinstance* instance) if(terminalExeName->length == 0) { - ffPrintError(instance, &instance->config.termFontKey, "Terminal Font", "Terminal font needs successfull terminal detection"); + ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.termFontKey, &instance->config.termFontFormat, FF_TERMFONT_NUM_FORMAT_ARGS, "Terminal font needs successfull terminal detection"); return; } @@ -79,5 +82,5 @@ void ffPrintTerminalFont(FFinstance* instance) else if(ffStrbufIgnCaseCompS(terminalExeName, "login") == 0) printTTY(instance); else - ffPrintError(instance, &instance->config.termFontKey, "Terminal Font", "Unknown terminal: %s", terminalExeName->chars); + ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.termFontKey, &instance->config.termFontFormat, FF_TERMFONT_NUM_FORMAT_ARGS, "Terminal Font", "Unknown terminal: %s", terminalExeName->chars); } diff --git a/src/modules/theme.c b/src/modules/theme.c index 5bea7032c..6ce0a675c 100644 --- a/src/modules/theme.c +++ b/src/modules/theme.c @@ -1,5 +1,8 @@ #include "fastfetch.h" +#define FF_THEME_MODULE_NAME "Theme" +#define FF_THEME_NUM_FORMAT_ARGS 7 + void ffPrintTheme(FFinstance* instance) { FFstrbuf* plasmaTheme; @@ -17,7 +20,7 @@ void ffPrintTheme(FFinstance* instance) if(plasmaTheme->length == 0 && plasmaColor->length == 0 && gtk2->length == 0 && gtk3->length == 0 && gtk4->length == 0) { - ffPrintError(instance, &instance->config.themeKey, "Theme", "No themes found"); + ffPrintError(instance, FF_THEME_MODULE_NAME, 0, &instance->config.themeKey, &instance->config.themeFormat, FF_THEME_NUM_FORMAT_ARGS, "No themes found"); return; } @@ -34,7 +37,7 @@ void ffPrintTheme(FFinstance* instance) if(instance->config.themeFormat.length == 0) { - ffPrintLogoAndKey(instance, &instance->config.themeKey, "Theme"); + ffPrintLogoAndKey(instance, FF_THEME_MODULE_NAME, 0, &instance->config.themeKey); if(plasmaTheme->length > 0) { @@ -72,15 +75,15 @@ void ffPrintTheme(FFinstance* instance) } else { - ffPrintFormatString(instance, &instance->config.themeKey, "Theme", &instance->config.themeFormat, 7, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, plasmaTheme}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, plasmaColor}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &plasmaColorPretty}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, gtk2}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, gtk3}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, gtk4}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, >kPretty} - ); + ffPrintFormatString(instance, FF_THEME_MODULE_NAME, 0, &instance->config.themeKey, &instance->config.themeFormat, NULL, FF_THEME_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, plasmaTheme}, + {FF_FORMAT_ARG_TYPE_STRBUF, plasmaColor}, + {FF_FORMAT_ARG_TYPE_STRBUF, &plasmaColorPretty}, + {FF_FORMAT_ARG_TYPE_STRBUF, gtk2}, + {FF_FORMAT_ARG_TYPE_STRBUF, gtk3}, + {FF_FORMAT_ARG_TYPE_STRBUF, gtk4}, + {FF_FORMAT_ARG_TYPE_STRBUF, >kPretty} + }); } ffStrbufDestroy(&plasmaColorPretty); diff --git a/src/modules/title.c b/src/modules/title.c index 038d83ba3..b4ddcb9e9 100644 --- a/src/modules/title.c +++ b/src/modules/title.c @@ -8,7 +8,7 @@ void ffPrintTitle(FFinstance* instance) char hostname[256]; gethostname(hostname, 256); - instance->config.titleLength = strlen(instance->state.passwd->pw_name) + 1 + strlen(hostname); + instance->config.titleLength = (uint32_t) strlen(instance->state.passwd->pw_name) + 1 + strlen(hostname); ffPrintLogoLine(instance); diff --git a/src/modules/uptime.c b/src/modules/uptime.c index d41ba05ff..1018399ec 100644 --- a/src/modules/uptime.c +++ b/src/modules/uptime.c @@ -1,5 +1,8 @@ #include "fastfetch.h" +#define FF_UPTIME_MODULE_NAME "Uptime" +#define FF_UPTIME_NUM_FORMAT_ARGS 4 + void ffPrintUptime(FFinstance* instance) { uint32_t days = instance->state.sysinfo.uptime / 86400; @@ -9,7 +12,7 @@ void ffPrintUptime(FFinstance* instance) if(instance->config.uptimeFormat.length == 0) { - ffPrintLogoAndKey(instance, &instance->config.uptimeKey, "Uptime"); + ffPrintLogoAndKey(instance, FF_UPTIME_MODULE_NAME, 0, &instance->config.uptimeKey); if(days == 0 && hours == 0 && minutes == 0) { @@ -28,11 +31,11 @@ void ffPrintUptime(FFinstance* instance) } else { - ffPrintFormatString(instance, &instance->config.uptimeKey, "Uptime", &instance->config.uptimeFormat, 4, - (FFformatarg){FF_FORMAT_ARG_TYPE_UINT, &days}, - (FFformatarg){FF_FORMAT_ARG_TYPE_UINT, &hours}, - (FFformatarg){FF_FORMAT_ARG_TYPE_UINT, &minutes}, - (FFformatarg){FF_FORMAT_ARG_TYPE_UINT, &seconds} - ); + ffPrintFormatString(instance, FF_UPTIME_MODULE_NAME, 0, &instance->config.uptimeKey, &instance->config.uptimeFormat, NULL, FF_UPTIME_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_UINT, &days}, + {FF_FORMAT_ARG_TYPE_UINT, &hours}, + {FF_FORMAT_ARG_TYPE_UINT, &minutes}, + {FF_FORMAT_ARG_TYPE_UINT, &seconds} + }); } } diff --git a/src/modules/wm.c b/src/modules/wm.c index 1dea0aabd..6942f4c12 100644 --- a/src/modules/wm.c +++ b/src/modules/wm.c @@ -1,5 +1,8 @@ #include "fastfetch.h" +#define FF_WM_MODULE_NAME "WM" +#define FF_WM_NUM_FORMAT_ARGS 2 + void ffPrintWM(FFinstance* instance) { FFstrbuf* prettyName; @@ -10,20 +13,20 @@ void ffPrintWM(FFinstance* instance) if(error->length > 0) { - ffPrintError(instance, &instance->config.wmKey, "WM", error->chars); + ffPrintError(instance, FF_WM_MODULE_NAME, 0, &instance->config.wmKey, &instance->config.wmFormat, FF_WM_NUM_FORMAT_ARGS, error->chars); return; } if(instance->config.wmFormat.length == 0) { - ffPrintLogoAndKey(instance, &instance->config.wmKey, "WM"); + ffPrintLogoAndKey(instance, "WM", 0, &instance->config.wmKey); ffStrbufPutTo(prettyName, stdout); } else { - ffPrintFormatString(instance, &instance->config.wmKey, "WM", &instance->config.wmFormat, 2, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, processName}, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, prettyName} - ); + ffPrintFormatString(instance, FF_WM_MODULE_NAME, 0, &instance->config.wmKey, &instance->config.wmFormat, NULL, FF_WM_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, processName}, + {FF_FORMAT_ARG_TYPE_STRBUF, prettyName} + }); } } diff --git a/src/modules/wmtheme.c b/src/modules/wmtheme.c index 4da41119a..31165d615 100644 --- a/src/modules/wmtheme.c +++ b/src/modules/wmtheme.c @@ -1,17 +1,20 @@ #include "fastfetch.h" +#define FF_WMTHEME_MODULE_NAME "WM Theme" +#define FF_WMTHEME_NUM_FORMAT_ARGS 1 + static void printWMTheme(FFinstance* instance, const char* theme) { if(instance->config.wmThemeFormat.length == 0) { - ffPrintLogoAndKey(instance, &instance->config.wmThemeKey, "WM Theme"); + ffPrintLogoAndKey(instance, FF_WMTHEME_MODULE_NAME, 0, &instance->config.wmThemeKey); puts(theme); } else { - ffPrintFormatString(instance, &instance->config.wmThemeKey, "WM Theme", &instance->config.wmThemeFormat, 1, - (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, theme} - ); + ffPrintFormatString(instance, FF_WMTHEME_MODULE_NAME, 0, &instance->config.wmThemeKey, &instance->config.wmThemeFormat, NULL, FF_WMTHEME_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRING, theme} + }); } } @@ -23,7 +26,7 @@ static void printKWin(FFinstance* instance) if(theme[0] == '\0') { - ffPrintError(instance, &instance->config.wmThemeKey, "WM Theme", "Couldn't find \"theme=\" in \".config/kwinrc\""); + ffPrintError(instance, FF_WMTHEME_MODULE_NAME, 0, &instance->config.wmThemeKey, &instance->config.wmThemeFormat, FF_WMTHEME_NUM_FORMAT_ARGS, "Couldn't find \"theme=\" in \".config/kwinrc\""); return; } @@ -37,12 +40,12 @@ void ffPrintWMTheme(FFinstance* instance) if(wmName->length == 0) { - ffPrintError(instance, &instance->config.wmThemeKey, "WM Theme", "WM Theme needs sucessfull WM detection"); + ffPrintError(instance, FF_WMTHEME_MODULE_NAME, 0, &instance->config.wmThemeKey, &instance->config.wmThemeFormat, FF_WMTHEME_NUM_FORMAT_ARGS, "WM Theme needs sucessfull WM detection"); return; } if(ffStrbufIgnCaseCompS(wmName, "KWin") == 0) printKWin(instance); else - ffPrintError(instance, &instance->config.wmThemeKey, "WM Theme", "Unknown WM: %s", wmName->chars); + ffPrintError(instance, FF_WMTHEME_MODULE_NAME, 0, &instance->config.wmThemeKey, &instance->config.wmThemeFormat, FF_WMTHEME_NUM_FORMAT_ARGS, "Unknown WM: %s", wmName->chars); } diff --git a/src/util/FFlist.c b/src/util/FFlist.c new file mode 100644 index 000000000..c624e0711 --- /dev/null +++ b/src/util/FFlist.c @@ -0,0 +1,36 @@ +#include "FFlist.h" + +#include +#include + +void ffListInit(FFlist* list, uint32_t elementSize) +{ + ffListInitA(list, elementSize, FF_LIST_DEFAULT_ALLOC); +} + +void ffListInitA(FFlist* list, uint32_t elementSize, uint32_t capacity) +{ + list->elementSize = elementSize; + list->capacity = capacity; + list->length = 0; + list->data = malloc(list->capacity * list->elementSize); +} + +void* ffListGet(FFlist* list, uint32_t index) +{ + return list->data + (index * list->elementSize); +} + +void* ffListAdd(FFlist* list) +{ + if(list->length == list->capacity) + list->data = realloc(list->data, list->capacity * 2 * list->elementSize); + void* adress = list->data + (list->length * list->elementSize); + ++list->length; + return adress; +} + +void ffListDestroy(FFlist* list) +{ + free(list->data); +} diff --git a/src/util/FFlist.h b/src/util/FFlist.h new file mode 100644 index 000000000..cc50a9bbe --- /dev/null +++ b/src/util/FFlist.h @@ -0,0 +1,27 @@ +#pragma once + +#ifndef FF_INCLUDED_FFLIST +#define FF_INCLUDED_FFLIST + +#include + +#define FF_LIST_DEFAULT_ALLOC 16 + +typedef struct FFlist +{ + void* data; + uint32_t elementSize; + uint32_t length; + uint32_t capacity; +} FFlist; + +void ffListInit(FFlist* list, uint32_t elementSize); +void ffListInitA(FFlist* list, uint32_t elementSize, uint32_t capacity); + +void* ffListGet(FFlist* list, uint32_t index); + +void* ffListAdd(FFlist* list); + +void ffListDestroy(FFlist* list); + +#endif diff --git a/src/util/FFstrbuf.c b/src/util/FFstrbuf.c index 1df40a4a4..1746067c7 100644 --- a/src/util/FFstrbuf.c +++ b/src/util/FFstrbuf.c @@ -203,7 +203,7 @@ void ffStrbufAppendVF(FFstrbuf* strbuf, const char* format, va_list arguments) va_copy(localArguments, arguments); ffStrbufEnsureFree(strbuf, 256); - int written = vsnprintf(strbuf->chars + strbuf->length, strbuf->allocated - strbuf->length, format, localArguments); + uint32_t written = (uint32_t) vsnprintf(strbuf->chars + strbuf->length, strbuf->allocated - strbuf->length, format, localArguments); va_end(localArguments); @@ -227,12 +227,12 @@ char ffStrbufGetC(FFstrbuf* strbuf, uint32_t index) return strbuf->chars[index]; } -void ffStrbufWriteTo(FFstrbuf* strbuf, FILE* file) +void ffStrbufWriteTo(const FFstrbuf* strbuf, FILE* file) { fwrite(strbuf->chars, sizeof(char), strbuf->length, file); } -void ffStrbufPutTo(FFstrbuf* strbuf, FILE* file) +void ffStrbufPutTo(const FFstrbuf* strbuf, FILE* file) { fwrite(strbuf->chars, sizeof(char), strbuf->length, file); fputc('\n', file); @@ -462,7 +462,4 @@ void ffStrbufRecalculateLength(FFstrbuf* strbuf) void ffStrbufDestroy(FFstrbuf* strbuf) { free(strbuf->chars); - strbuf->allocated = 0; - strbuf->chars = NULL; - strbuf->length = 0; } diff --git a/src/util/FFstrbuf.h b/src/util/FFstrbuf.h index b432cea08..f45c5c02d 100644 --- a/src/util/FFstrbuf.h +++ b/src/util/FFstrbuf.h @@ -52,8 +52,8 @@ void ffStrbufAppendVF(FFstrbuf* strbuf, const char* format, va_list arguments); char ffStrbufGetC(FFstrbuf* strbuf, uint32_t index); -void ffStrbufWriteTo(FFstrbuf* strbuf, FILE* file); -void ffStrbufPutTo(FFstrbuf* strbuf, FILE* file); +void ffStrbufWriteTo(const FFstrbuf* strbuf, FILE* file); +void ffStrbufPutTo(const FFstrbuf* strbuf, FILE* file); int ffStrbufComp(FFstrbuf* strbuf, const FFstrbuf* comp); int ffStrbufCompS(FFstrbuf* strbuf, const char* comp); diff --git a/tests/performance.c b/tests/performance.c index d19a4bf42..822a08963 100644 --- a/tests/performance.c +++ b/tests/performance.c @@ -31,7 +31,7 @@ int main(int argc, char** argv) ffLoadLogoSet(&instance.config, "arch"); ffStrbufSetS(&instance.config.color, instance.config.logo.color); instance.config.showErrors = true; - instance.config.recache = true; + instance.config.recache = argc == 1; instance.config.cacheSave = false; ) diff --git a/tests/performance.sh b/tests/performance.sh index 4a175e589..365b01657 100755 --- a/tests/performance.sh +++ b/tests/performance.sh @@ -1,3 +1,4 @@ +rm -rf tests/build/ mkdir -p tests/build/ cd tests/build/ cmake ../.. -DBUILD_TESTS=ON