diff --git a/CMakeLists.txt b/CMakeLists.txt index 081507a1e..dc5987647 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,6 +75,10 @@ add_library(libfastfetch STATIC src/common/init.c src/common/threading.c src/common/io.c + src/common/printing.c + src/common/caching.c + src/common/properties.c + src/common/font.c src/common/processing.c src/common/format.c src/common/parsing.c diff --git a/src/common/caching.c b/src/common/caching.c new file mode 100644 index 000000000..e5e95ba8d --- /dev/null +++ b/src/common/caching.c @@ -0,0 +1,200 @@ +#include "fastfetch.h" + +#define FF_CACHE_VALUE_EXTENSION "ffcv" +#define FF_CACHE_SPLIT_EXTENSION "ffcs" + +static void getCacheFilePath(FFinstance* instance, const char* moduleName, const char* extension, FFstrbuf* buffer) +{ + ffStrbufAppend(buffer, &instance->state.cacheDir); + ffStrbufAppendS(buffer, moduleName); + + if(extension != NULL) + { + ffStrbufAppendC(buffer, '.'); + ffStrbufAppendS(buffer, extension); + } +} + +static void readCacheFile(FFinstance* instance, const char* moduleName, const char* extension, FFstrbuf* buffer) +{ + FFstrbuf path; + ffStrbufInitA(&path, 64); + getCacheFilePath(instance, moduleName, extension, &path); + ffAppendFileContent(path.chars, buffer); + ffStrbufDestroy(&path); +} + +static void writeCacheFile(FFinstance* instance, const char* moduleName, const char* extension, FFstrbuf* content) +{ + FFstrbuf path; + ffStrbufInitA(&path, 64); + getCacheFilePath(instance, moduleName, extension, &path); + ffWriteFileContent(path.chars, content); + ffStrbufDestroy(&path); +} + +void ffCacheValidate(FFinstance* instance) +{ + FFstrbuf content; + ffStrbufInit(&content); + readCacheFile(instance, "cacheversion", "ffv", &content); + + bool isSameVersion = ffStrbufCompS(&content, FASTFETCH_PROJECT_VERSION) == 0; + ffStrbufDestroy(&content); + if(isSameVersion) + return; + + instance->config.recache = true; + + FFstrbuf version; + ffStrbufInitA(&version, sizeof(FASTFETCH_PROJECT_VERSION)); + ffStrbufAppendS(&version, FASTFETCH_PROJECT_VERSION); + writeCacheFile(instance, "cacheversion", "ffv", &version); + ffStrbufDestroy(&version); +} + +void ffCacheOpenWrite(FFinstance* instance, const char* moduleName, FFcache* cache) +{ + FFstrbuf cacheFileValue; + ffStrbufInitA(&cacheFileValue, 64); + getCacheFilePath(instance, moduleName, FF_CACHE_VALUE_EXTENSION, &cacheFileValue); + cache->value = fopen(cacheFileValue.chars, "w"); + ffStrbufDestroy(&cacheFileValue); + + FFstrbuf cacheFileSplit; + ffStrbufInitA(&cacheFileSplit, 64); + getCacheFilePath(instance, moduleName, FF_CACHE_SPLIT_EXTENSION, &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); +} + +static bool printCachedValue(FFinstance* instance, const char* moduleName, const FFstrbuf* customKeyFormat) +{ + FFstrbuf content; + ffStrbufInitA(&content, 512); + readCacheFile(instance, moduleName, FF_CACHE_VALUE_EXTENSION, &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 startIndex = 0; + while(startIndex < content.length) + { + uint32_t nullByteIndex = ffStrbufNextIndexC(&content, startIndex, '\0'); + uint8_t moduleIndex = (moduleCounter == 1 && nullByteIndex == content.length) ? 0 : moduleCounter; + ffPrintLogoAndKey(instance, moduleName, moduleIndex, customKeyFormat); + puts(content.chars + startIndex); + startIndex = nullByteIndex + 1; + ++moduleCounter; + } + + ffStrbufDestroy(&content); + + return moduleCounter > 1; +} + +static bool printCachedFormat(FFinstance* instance, const char* moduleName, const FFstrbuf* customKeyFormat, const FFstrbuf* formatString, uint32_t numArgs) +{ + FFstrbuf content; + ffStrbufInitA(&content, 512); + readCacheFile(instance, moduleName, FF_CACHE_SPLIT_EXTENSION, &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 = calloc(numArgs, sizeof(FFformatarg)); + uint32_t argumentCounter = 0; + + uint32_t startIndex = 0; + while(startIndex < content.length) + { + arguments[argumentCounter].type = FF_FORMAT_ARG_TYPE_STRING; + arguments[argumentCounter].value = &content.chars[startIndex]; + ++argumentCounter; + + uint32_t nullByteIndex = ffStrbufNextIndexC(&content, startIndex, '\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; + } + + startIndex = nullByteIndex + 1; + } + + free(arguments); + ffStrbufDestroy(&content); + + 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++) + { + FFstrbuf buffer; + ffStrbufInitA(&buffer, 64); + ffFormatAppendFormatArg(&buffer, &arguments[i]); + ffStrbufWriteTo(&buffer, cache->split); + ffStrbufDestroy(&buffer); + fputc('\0', cache->split); + } +} + +void ffPrintAndWriteToCache(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); +} diff --git a/src/common/font.c b/src/common/font.c new file mode 100644 index 000000000..e2b13ba46 --- /dev/null +++ b/src/common/font.c @@ -0,0 +1,207 @@ +#include "fastfetch.h" + +#include + +static void fontInit(FFfont* font) +{ + ffStrbufInit(&font->pretty); + ffStrbufInit(&font->name); + ffStrbufInitA(&font->size, 4); + ffListInitA(&font->styles, sizeof(FFstrbuf), 4); +} + +static void fontInitPretty(FFfont* font) +{ + ffStrbufAppend(&font->pretty, &font->name); + + if(font->size.length == 0 && font->styles.length == 0) + return; + else if(font->pretty.length == 0) + ffStrbufAppendS(&font->pretty, "default"); + + ffStrbufAppendS(&font->pretty, " ("); + + if(font->size.length > 0) + { + ffStrbufAppend(&font->pretty, &font->size); + ffStrbufAppendS(&font->pretty, "pt"); + + if(font->styles.length > 0) + ffStrbufAppendS(&font->pretty, ", "); + } + + for(uint32_t i = 0; i < font->styles.length; i++) + { + ffStrbufAppend(&font->pretty, ffListGet(&font->styles, i)); + + if(i < font->styles.length - 1) + ffStrbufAppendS(&font->pretty, ", "); + } + + ffStrbufAppendC(&font->pretty, ')'); +} + +void ffFontInitQt(FFfont* font, const char* data) +{ + fontInit(font); + + //See https://doc.qt.io/qt-5/qfont.html#toString + + //Family + while(*data != ',' && *data != '\0') + { + ffStrbufAppendC(&font->name, *data); + ++data; + } + if(*data != '\0') + ++data; + ffStrbufTrim(&font->name, ' '); + + //Size + while(*data != ',' && *data != '\0') + { + ffStrbufAppendC(&font->size, *data); + ++data; + } + if(*data != '\0') + ++data; + ffStrbufTrim(&font->size, ' '); + + #define FF_FONT_QT_SKIP_VALUE \ + while(*data != ',' && *data != '\0') \ + ++data; \ + if(*data != '\0') \ + ++data; + + FF_FONT_QT_SKIP_VALUE //Pixel size + FF_FONT_QT_SKIP_VALUE //Style hint + FF_FONT_QT_SKIP_VALUE //Font weight + FF_FONT_QT_SKIP_VALUE //Font style + FF_FONT_QT_SKIP_VALUE //Underline + FF_FONT_QT_SKIP_VALUE //Strike out + FF_FONT_QT_SKIP_VALUE //Fixed pitch + FF_FONT_QT_SKIP_VALUE //Always 0 + + #undef FF_FONT_QT_SKIP_VALUE + + while(*data != '\0') + { + while(*data == ' ') + ++data; + + if(*data == '\0') + break; + + FFstrbuf* style = ffListAdd(&font->styles); + ffStrbufInit(style); + while(*data != ' ' && *data != '\0') + { + ffStrbufAppendC(style, *data); + ++data; + } + } + + fontInitPretty(font); +} + +static void fontPangoParseWord(const char** data, FFfont* font, FFstrbuf* alternativeBuffer) +{ + while(**data == ' ' || **data == '\t' || **data == ',') + ++(*data); + + const char* wordStart = *data; + + while(**data != ' ' && **data != '\t' && **data != ',' && **data != '\0' && **data != '`' && **data != '\\') + ++(*data); + + uint32_t wordLength = (uint32_t) (*data - wordStart); + if(wordLength == 0) + return; + + if(**data == '\0' || **data == '`' || **data == '\\') + { + ffStrbufAppendNS(&font->size, wordLength, wordStart); + if(ffStrbufEndsWithS(&font->size, "px")) + ffStrbufSubstrBefore(&font->size, font->size.length - 2); + + double dummy; + if(sscanf(font->size.chars, "%lf", &dummy) == 1) + return; + + ffStrbufClear(&font->size); + } + + if( + strncasecmp(wordStart, "Ultra", 5) == 0 || + strncasecmp(wordStart, "Extra", 5) == 0 || + strncasecmp(wordStart, "Semi", 4) == 0 || + strncasecmp(wordStart, "Demi", 4) == 0 || + strncasecmp(wordStart, "Normal", wordLength) == 0 || + strncasecmp(wordStart, "Roman", wordLength) == 0 || + strncasecmp(wordStart, "Oblique", wordLength) == 0 || + strncasecmp(wordStart, "Italic", wordLength) == 0 || + strncasecmp(wordStart, "Thin", wordLength) == 0 || + strncasecmp(wordStart, "Light", wordLength) == 0 || + strncasecmp(wordStart, "Bold", wordLength) == 0 || + strncasecmp(wordStart, "Black", wordLength) == 0 || + strncasecmp(wordStart, "Condensed", wordLength) == 0 || + strncasecmp(wordStart, "Expanded", wordLength) == 0 + ) { + if(alternativeBuffer == NULL) + { + alternativeBuffer = ffListAdd(&font->styles); + ffStrbufInit(alternativeBuffer); + } + + ffStrbufAppendNSExludingC(alternativeBuffer, wordLength, wordStart, '-'); + + if( + strncasecmp(wordStart, "Ultra ", 6) == 0 || + strncasecmp(wordStart, "Extra ", 6) == 0 || + strncasecmp(wordStart, "Semi ", 5) == 0 || + strncasecmp(wordStart, "Demi ", 5) == 0 + ) { + fontPangoParseWord(data, font, alternativeBuffer); + } + + return; + } + + if(alternativeBuffer != NULL) + { + ffStrbufAppendNSExludingC(alternativeBuffer, wordLength, wordStart, '-'); + return; + } + + if(font->name.length > 0) + ffStrbufAppendC(&font->name, ' '); + ffStrbufAppendNS(&font->name, wordLength, wordStart); +} + +void ffFontInitPango(FFfont* font, const char* data) +{ + fontInit(font); + + while(*data != '\0' && *data != '`' && *data != '\\') + fontPangoParseWord(&data, font, NULL); + + fontInitPretty(font); +} + +void ffFontInitCopy(FFfont* font, const char* name) +{ + fontInit(font); + ffStrbufAppendS(&font->name, name); + fontInitPretty(font); +} + +void ffFontDestroy(FFfont* font) +{ + ffStrbufDestroy(&font->pretty); + ffStrbufDestroy(&font->name); + ffStrbufDestroy(&font->size); + + for(uint32_t i = 0; i < font->styles.length; i++) + ffStrbufDestroy(ffListGet(&font->styles, i)); + ffListDestroy(&font->styles); +} diff --git a/src/common/format.c b/src/common/format.c index b251ca393..dd1d39038 100644 --- a/src/common/format.c +++ b/src/common/format.c @@ -173,7 +173,7 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, const FFst appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length); else { - ffStrbufAppendS(buffer, "\033[0m"); + ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET); --numOpenColors; } @@ -284,6 +284,5 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, const FFst ffStrbufTrimRight(buffer, ' '); - if(numOpenColors > 0) - ffStrbufAppendS(buffer, "\033[0m"); + ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET); } diff --git a/src/common/io.c b/src/common/io.c index 60cb34f0e..2c4950a0b 100644 --- a/src/common/io.c +++ b/src/common/io.c @@ -4,381 +4,6 @@ #include #include -#define FF_IO_CACHE_VALUE_EXTENSION "ffcv" -#define FF_IO_CACHE_SPLIT_EXTENSION "ffcs" - -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; - - va_list arguments; - va_start(arguments, message); - - if(formatString == NULL || formatString->length == 0) - { - ffPrintLogoAndKey(instance, moduleName, moduleIndex, customKeyFormat); - fputs(FASTFETCH_TEXT_MODIFIER_ERROR, stdout); - vprintf(message, arguments); - puts(FASTFETCH_TEXT_MODIFIER_RESET); - } - else - { - FF_STRBUF_CREATE(error); - ffStrbufAppendVF(&error, message, arguments); - - // calloc sets all to 0 and FF_FORMAT_ARG_TYPE_NULL also has value 0 so we don't need to explictly set it - FFformatarg* nullArgs = calloc(numFormatArgs, sizeof(FFformatarg)); - - ffPrintFormatString(instance, moduleName, moduleIndex, customKeyFormat, formatString, &error, numFormatArgs, nullArgs); - - free(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); -} - -void ffGetCacheFilePath(FFinstance* instance, const char* moduleName, const char* extension, FFstrbuf* buffer) -{ - ffStrbufAppend(buffer, &instance->state.cacheDir); - ffStrbufAppendS(buffer, moduleName); - - if(extension != NULL) - { - ffStrbufAppendC(buffer, '.'); - ffStrbufAppendS(buffer, extension); - } -} - -void ffReadCacheFile(FFinstance* instance, const char* moduleName, const char* extension, FFstrbuf* buffer) -{ - FFstrbuf path; - ffStrbufInitA(&path, 64); - ffGetCacheFilePath(instance, moduleName, extension, &path); - ffAppendFileContent(path.chars, buffer); - ffStrbufDestroy(&path); -} - -void ffWriteCacheFile(FFinstance* instance, const char* moduleName, const char* extension, FFstrbuf* content) -{ - FFstrbuf path; - ffStrbufInitA(&path, 64); - ffGetCacheFilePath(instance, moduleName, extension, &path); - ffWriteFileContent(path.chars, content); - ffStrbufDestroy(&path); -} - -static bool printCachedValue(FFinstance* instance, const char* moduleName, const FFstrbuf* customKeyFormat) -{ - FFstrbuf content; - ffStrbufInitA(&content, 512); - ffReadCacheFile(instance, moduleName, FF_IO_CACHE_VALUE_EXTENSION, &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 startIndex = 0; - while(startIndex < content.length) - { - uint32_t nullByteIndex = ffStrbufNextIndexC(&content, startIndex, '\0'); - uint8_t moduleIndex = (moduleCounter == 1 && nullByteIndex == content.length) ? 0 : moduleCounter; - ffPrintLogoAndKey(instance, moduleName, moduleIndex, customKeyFormat); - puts(content.chars + startIndex); - startIndex = nullByteIndex + 1; - ++moduleCounter; - } - - ffStrbufDestroy(&content); - - return moduleCounter > 1; -} - -static bool printCachedFormat(FFinstance* instance, const char* moduleName, const FFstrbuf* customKeyFormat, const FFstrbuf* formatString, uint32_t numArgs) -{ - FFstrbuf content; - ffStrbufInitA(&content, 512); - ffReadCacheFile(instance, moduleName, FF_IO_CACHE_SPLIT_EXTENSION, &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 = calloc(numArgs, sizeof(FFformatarg)); - uint32_t argumentCounter = 0; - - uint32_t startIndex = 0; - while(startIndex < content.length) - { - arguments[argumentCounter].type = FF_FORMAT_ARG_TYPE_STRING; - arguments[argumentCounter].value = &content.chars[startIndex]; - ++argumentCounter; - - uint32_t nullByteIndex = ffStrbufNextIndexC(&content, startIndex, '\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; - } - - startIndex = nullByteIndex + 1; - } - - free(arguments); - ffStrbufDestroy(&content); - - 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++) - { - FFstrbuf buffer; - ffStrbufInitA(&buffer, 64); - ffFormatAppendFormatArg(&buffer, &arguments[i]); - ffStrbufWriteTo(&buffer, cache->split); - ffStrbufDestroy(&buffer); - 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 path; - ffStrbufInitA(&path, 64); - ffGetCacheFilePath(instance, "cacheversion", "ffv", &path); - - FFstrbuf content; - ffStrbufInit(&content); - ffAppendFileContent(path.chars, &content); - - bool isSameVersion = ffStrbufCompS(&content, FASTFETCH_PROJECT_VERSION) == 0; - ffStrbufDestroy(&content); - if(isSameVersion) - { - ffStrbufDestroy(&path); - return; - } - - instance->config.recache = true; - - FFstrbuf version; - ffStrbufInit(&version); - ffStrbufAppendS(&version, FASTFETCH_PROJECT_VERSION); - ffWriteFileContent(path.chars, &version); - ffStrbufDestroy(&version); - - ffStrbufDestroy(&path); -} - -void ffCacheOpenWrite(FFinstance* instance, const char* moduleName, FFcache* cache) -{ - FFstrbuf cacheFileValue; - ffStrbufInitA(&cacheFileValue, 64); - ffGetCacheFilePath(instance, moduleName, FF_IO_CACHE_VALUE_EXTENSION, &cacheFileValue); - cache->value = fopen(cacheFileValue.chars, "w"); - ffStrbufDestroy(&cacheFileValue); - - FFstrbuf cacheFileSplit; - ffStrbufInitA(&cacheFileSplit, 64); - ffGetCacheFilePath(instance, moduleName, FF_IO_CACHE_SPLIT_EXTENSION, &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); -} - -bool ffParsePropFileValues(const char* filename, uint32_t numQueries, FFpropquery* queries) -{ - bool* searchedValues = malloc(sizeof(bool) * numQueries); - bool allSet = true; - for(uint32_t i = 0; i < numQueries; i++) - { - if((searchedValues[i] = queries[i].buffer->length == 0)) - allSet = false; - } - - if(allSet) - { - free(searchedValues); - return true; - } - - FILE* file = fopen(filename, "r"); - if(file == NULL) - return false; - - char* line = NULL; - size_t len = 0; - - while (getline(&line, &len, file) != -1) - { - for(uint32_t i = 0; i < numQueries; i++) - { - if(!searchedValues[i]) - continue; - - uint32_t currentLength = queries[i].buffer->length; - queries[i].buffer->length = 0; - if(!ffGetPropValue(line, queries[i].start, queries[i].buffer)) - queries[i].buffer->length = currentLength; - } - } - - free(searchedValues); - - if(line != NULL) - free(line); - - fclose(file); - - return true; -} - -void ffPrintChar(char c, uint32_t times) -{ - for(uint32_t i = 0; i < times; i++) - putchar(c); -} - -bool ffParsePropFile(const char* filename, const char* start, FFstrbuf* buffer) -{ - return ffParsePropFileValues(filename, 1, (FFpropquery[]){{start, buffer}}); -} - -bool ffParsePropFileHomeValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries) -{ - FFstrbuf absolutePath; - ffStrbufInitA(&absolutePath, 64); - ffStrbufAppendS(&absolutePath, instance->state.passwd->pw_dir); - ffStrbufAppendC(&absolutePath, '/'); - ffStrbufAppendS(&absolutePath, relativeFile); - - bool result = ffParsePropFileValues(absolutePath.chars, numQueries, queries); - - ffStrbufDestroy(&absolutePath); - - return result; -} - -bool ffParsePropFileHome(const FFinstance* instance, const char* relativeFile, const char* start, FFstrbuf* buffer) -{ - return ffParsePropFileHomeValues(instance, relativeFile, 1, (FFpropquery[]){{start, buffer}}); -} - -bool ffParsePropFileConfigValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries) -{ - bool foundAFile = false; - - for(uint32_t i = 0; i < instance->state.configDirs.length; i++) - { - FFstrbuf* baseDir = (FFstrbuf*) ffListGet(&instance->state.configDirs, i); - uint32_t baseDirLength = baseDir->length; - - if(*relativeFile != '/') - ffStrbufAppendC(baseDir, '/'); - - ffStrbufAppendS(baseDir, relativeFile); - - if(ffParsePropFileValues(baseDir->chars, numQueries, queries)) - foundAFile = true; - - ffStrbufSubstrBefore(baseDir, baseDirLength); - - bool allSet = true; - for(uint32_t k = 0; k < numQueries; k++) - { - if(queries[k].buffer->length == 0) - { - allSet = false; - break; - } - } - - if(allSet) - break; - } - - return foundAFile; -} - -bool ffParsePropFileConfig(const FFinstance* instance, const char* relativeFile, const char* start, FFstrbuf* buffer) -{ - return ffParsePropFileConfigValues(instance, relativeFile, 1, (FFpropquery[]){{start, buffer}}); -} - bool ffWriteFDContent(int fd, const FFstrbuf* content) { return write(fd, content->chars, content->length) != -1; @@ -468,13 +93,6 @@ void ffSuppressIO(bool suppress) dup2(suppress ? nullFile : origErr, STDERR_FILENO); } -void ffPrintColor(const FFstrbuf* colorValue) -{ - fputs("\033[", stdout); - ffStrbufWriteTo(colorValue, stdout); - fputc('m', stdout); -} - bool ffFileExists(const char* fileName, mode_t mode) { struct stat fileStat; diff --git a/src/common/parsing.c b/src/common/parsing.c index e887f9092..416d80cc9 100644 --- a/src/common/parsing.c +++ b/src/common/parsing.c @@ -1,8 +1,45 @@ #include "fastfetch.h" -#include +bool ffStrSet(const char* str) +{ + if(str == NULL) + return false; -void ffGetGtkPretty(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, const FFstrbuf* gtk4) + while(*str != '\0') + { + if(*str != ' ' && *str != '\t' && *str != '\n' && *str != '\r') + return true; + } + + return false; +} + +void ffParseSemver(FFstrbuf* buffer, const FFstrbuf* major, const FFstrbuf* minor, const FFstrbuf* patch) +{ + if(major->length > 0) + ffStrbufAppend(buffer, major); + else if(minor->length > 0 || patch->length > 0) + ffStrbufAppendC(buffer, '1'); + + if(minor->length == 0 && patch->length == 0) + return; + + ffStrbufAppendC(buffer, '.'); + + if(minor->length > 0) + ffStrbufAppend(buffer, minor); + else if(patch->length > 0) + ffStrbufAppendC(buffer, '0'); + + if(patch->length == 0) + return; + + ffStrbufAppendC(buffer, '.'); + + ffStrbufAppend(buffer, patch); +} + +void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, const FFstrbuf* gtk4) { if(gtk2->length > 0 && gtk3->length > 0 && gtk4->length > 0) { @@ -81,329 +118,3 @@ void ffGetGtkPretty(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3 ffStrbufAppendS(buffer, " [GTK4]"); } } - -static void fontInit(FFfont* font) -{ - ffStrbufInit(&font->pretty); - ffStrbufInit(&font->name); - ffStrbufInitA(&font->size, 4); - ffListInitA(&font->styles, sizeof(FFstrbuf), 4); -} - -static void fontInitPretty(FFfont* font) -{ - ffStrbufAppend(&font->pretty, &font->name); - - if(font->size.length == 0 && font->styles.length == 0) - return; - else if(font->pretty.length == 0) - ffStrbufAppendS(&font->pretty, "default"); - - ffStrbufAppendS(&font->pretty, " ("); - - if(font->size.length > 0) - { - ffStrbufAppend(&font->pretty, &font->size); - ffStrbufAppendS(&font->pretty, "pt"); - - if(font->styles.length > 0) - ffStrbufAppendS(&font->pretty, ", "); - } - - for(uint32_t i = 0; i < font->styles.length; i++) - { - ffStrbufAppend(&font->pretty, ffListGet(&font->styles, i)); - - if(i < font->styles.length - 1) - ffStrbufAppendS(&font->pretty, ", "); - } - - ffStrbufAppendC(&font->pretty, ')'); -} - -void ffFontInitQt(FFfont* font, const char* data) -{ - fontInit(font); - - //See https://doc.qt.io/qt-5/qfont.html#toString - - //Family - while(*data != ',' && *data != '\0') - { - ffStrbufAppendC(&font->name, *data); - ++data; - } - if(*data != '\0') - ++data; - ffStrbufTrim(&font->name, ' '); - - //Size - while(*data != ',' && *data != '\0') - { - ffStrbufAppendC(&font->size, *data); - ++data; - } - if(*data != '\0') - ++data; - ffStrbufTrim(&font->size, ' '); - - #define FF_FONT_QT_SKIP_VALUE \ - while(*data != ',' && *data != '\0') \ - ++data; \ - if(*data != '\0') \ - ++data; - - FF_FONT_QT_SKIP_VALUE //Pixel size - FF_FONT_QT_SKIP_VALUE //Style hint - FF_FONT_QT_SKIP_VALUE //Font weight - FF_FONT_QT_SKIP_VALUE //Font style - FF_FONT_QT_SKIP_VALUE //Underline - FF_FONT_QT_SKIP_VALUE //Strike out - FF_FONT_QT_SKIP_VALUE //Fixed pitch - FF_FONT_QT_SKIP_VALUE //Always 0 - - #undef FF_FONT_QT_SKIP_VALUE - - while(*data != '\0') - { - while(*data == ' ') - ++data; - - if(*data == '\0') - break; - - FFstrbuf* style = ffListAdd(&font->styles); - ffStrbufInit(style); - while(*data != ' ' && *data != '\0') - { - ffStrbufAppendC(style, *data); - ++data; - } - } - - fontInitPretty(font); -} - -static void fontPangoParseWord(const char** data, FFfont* font, FFstrbuf* alternativeBuffer) -{ - while(**data == ' ' || **data == '\t' || **data == ',') - ++(*data); - - const char* wordStart = *data; - - while(**data != ' ' && **data != '\t' && **data != ',' && **data != '\0' && **data != '`' && **data != '\\') - ++(*data); - - uint32_t wordLength = (uint32_t) (*data - wordStart); - if(wordLength == 0) - return; - - if(**data == '\0' || **data == '`' || **data == '\\') - { - ffStrbufAppendNS(&font->size, wordLength, wordStart); - if(ffStrbufEndsWithS(&font->size, "px")) - ffStrbufSubstrBefore(&font->size, font->size.length - 2); - - double dummy; - if(sscanf(font->size.chars, "%lf", &dummy) == 1) - return; - - ffStrbufClear(&font->size); - } - - if( - strncasecmp(wordStart, "Ultra", 5) == 0 || - strncasecmp(wordStart, "Extra", 5) == 0 || - strncasecmp(wordStart, "Semi", 4) == 0 || - strncasecmp(wordStart, "Demi", 4) == 0 || - strncasecmp(wordStart, "Normal", wordLength) == 0 || - strncasecmp(wordStart, "Roman", wordLength) == 0 || - strncasecmp(wordStart, "Oblique", wordLength) == 0 || - strncasecmp(wordStart, "Italic", wordLength) == 0 || - strncasecmp(wordStart, "Thin", wordLength) == 0 || - strncasecmp(wordStart, "Light", wordLength) == 0 || - strncasecmp(wordStart, "Bold", wordLength) == 0 || - strncasecmp(wordStart, "Black", wordLength) == 0 || - strncasecmp(wordStart, "Condensed", wordLength) == 0 || - strncasecmp(wordStart, "Expanded", wordLength) == 0 - ) { - if(alternativeBuffer == NULL) - { - alternativeBuffer = ffListAdd(&font->styles); - ffStrbufInit(alternativeBuffer); - } - - ffStrbufAppendNSExludingC(alternativeBuffer, wordLength, wordStart, '-'); - - if( - strncasecmp(wordStart, "Ultra ", 6) == 0 || - strncasecmp(wordStart, "Extra ", 6) == 0 || - strncasecmp(wordStart, "Semi ", 5) == 0 || - strncasecmp(wordStart, "Demi ", 5) == 0 - ) { - fontPangoParseWord(data, font, alternativeBuffer); - } - - return; - } - - if(alternativeBuffer != NULL) - { - ffStrbufAppendNSExludingC(alternativeBuffer, wordLength, wordStart, '-'); - return; - } - - if(font->name.length > 0) - ffStrbufAppendC(&font->name, ' '); - ffStrbufAppendNS(&font->name, wordLength, wordStart); -} - -void ffFontInitPango(FFfont* font, const char* data) -{ - fontInit(font); - - while(*data != '\0' && *data != '`' && *data != '\\') - fontPangoParseWord(&data, font, NULL); - - fontInitPretty(font); -} - -void ffFontInitCopy(FFfont* font, const char* name) -{ - fontInit(font); - ffStrbufAppendS(&font->name, name); - fontInitPretty(font); -} - -void ffFontDestroy(FFfont* font) -{ - ffStrbufDestroy(&font->pretty); - ffStrbufDestroy(&font->name); - ffStrbufDestroy(&font->size); - - for(uint32_t i = 0; i < font->styles.length; i++) - ffStrbufDestroy(ffListGet(&font->styles, i)); - ffListDestroy(&font->styles); -} - -static bool getPropValueLine(const char** line, const char* start, FFstrbuf* buffer) -{ - if(**line == '\0') - return false; - - //Skip any amount of whitespace at the begin of line - while(**line == ' ' || **line == '\t') - ++(*line); - - while(*start != '\0') - { - // Any amount of whitespace in the format string matches any amount of whitespace in the line, even none - if(*start == ' ' || *start == '\t') - { - while(*start == ' ' || *start == '\t') - ++start; - - while(**line == ' ' || **line == '\t') - ++(*line); - - continue; - } - - //Line doesn't match start, skip it - if(**line != *start || **line == '\0') - return false; - - //Line and start match, continue testing - ++(*line); - ++start; - } - - char valueEnd = '\n'; - - //Allow faster parsing of XML - if(*(*line - 1) == '>') - valueEnd = '<'; - - //Skip any amount of whitespace at the begin of the value - while(**line == ' ' || **line == '\t') - ++(*line); - - //Allow faster parsing of quotet values - if(**line == '"' || **line == '\'') - { - valueEnd = **line; - ++(*line); - } - - //Copy the value to the buffer - while(**line != valueEnd && **line != '\n' && **line != '\0') - { - ffStrbufAppendC(buffer, **line); - ++(*line); - } - - ffStrbufTrimRight(buffer, ' '); - - return true; -} - -bool ffGetPropValue(const char* line, const char* start, FFstrbuf* buffer) -{ - return getPropValueLine(&line, start, buffer); -} - -bool ffGetPropValueFromLines(const char* lines, const char* start, FFstrbuf* buffer) -{ - while(!getPropValueLine(&lines, start, buffer)) - { - while(*lines != '\0' && *lines != '\n') - ++lines; - - if(*lines == '\0') - return false; - - //Skip '\n' - ++lines; - } - - return true; -} - -void ffParseSemver(FFstrbuf* buffer, const FFstrbuf* major, const FFstrbuf* minor, const FFstrbuf* patch) -{ - if(major->length > 0) - ffStrbufAppend(buffer, major); - else if(minor->length > 0 || patch->length > 0) - ffStrbufAppendC(buffer, '1'); - - if(minor->length == 0 && patch->length == 0) - return; - - ffStrbufAppendC(buffer, '.'); - - if(minor->length > 0) - ffStrbufAppend(buffer, minor); - else if(patch->length > 0) - ffStrbufAppendC(buffer, '0'); - - if(patch->length == 0) - return; - - ffStrbufAppendC(buffer, '.'); - - ffStrbufAppend(buffer, patch); -} - -bool ffStrSet(const char* str) -{ - if(str == NULL) - return false; - - while(*str != '\0') - { - if(*str != ' ' && *str != '\t' && *str != '\n' && *str != '\r') - return true; - } - - return false; -} diff --git a/src/common/printing.c b/src/common/printing.c new file mode 100644 index 000000000..9441781ea --- /dev/null +++ b/src/common/printing.c @@ -0,0 +1,62 @@ +#include "fastfetch.h" + +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; + + va_list arguments; + va_start(arguments, message); + + if(formatString == NULL || formatString->length == 0) + { + ffPrintLogoAndKey(instance, moduleName, moduleIndex, customKeyFormat); + fputs(FASTFETCH_TEXT_MODIFIER_ERROR, stdout); + vprintf(message, arguments); + puts(FASTFETCH_TEXT_MODIFIER_RESET); + } + else + { + FF_STRBUF_CREATE(error); + ffStrbufAppendVF(&error, message, arguments); + + // calloc sets all to 0 and FF_FORMAT_ARG_TYPE_NULL also has value 0 so we don't need to explictly set it + FFformatarg* nullArgs = calloc(numFormatArgs, sizeof(FFformatarg)); + + ffPrintFormatString(instance, moduleName, moduleIndex, customKeyFormat, formatString, &error, numFormatArgs, nullArgs); + + free(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); +} + +void ffPrintColor(const FFstrbuf* colorValue) +{ + fputs("\033[", stdout); + ffStrbufWriteTo(colorValue, stdout); + fputc('m', stdout); +} + +void ffPrintCharTimes(char c, uint32_t times) +{ + for(uint32_t i = 0; i < times; i++) + putchar(c); +} diff --git a/src/common/properties.c b/src/common/properties.c new file mode 100644 index 000000000..c62c1a201 --- /dev/null +++ b/src/common/properties.c @@ -0,0 +1,202 @@ +#include "fastfetch.h" + +static bool parsePropLinePointer(const char** line, const char* start, FFstrbuf* buffer) +{ + if(**line == '\0') + return false; + + //Skip any amount of whitespace at the begin of line + while(**line == ' ' || **line == '\t') + ++(*line); + + while(*start != '\0') + { + // Any amount of whitespace in the format string matches any amount of whitespace in the line, even none + if(*start == ' ' || *start == '\t') + { + while(*start == ' ' || *start == '\t') + ++start; + + while(**line == ' ' || **line == '\t') + ++(*line); + + continue; + } + + //Line doesn't match start, skip it + if(**line != *start || **line == '\0') + return false; + + //Line and start match, continue testing + ++(*line); + ++start; + } + + char valueEnd = '\n'; + + //Allow faster parsing of XML + if(*(*line - 1) == '>') + valueEnd = '<'; + + //Skip any amount of whitespace at the begin of the value + while(**line == ' ' || **line == '\t') + ++(*line); + + //Allow faster parsing of quotet values + if(**line == '"' || **line == '\'') + { + valueEnd = **line; + ++(*line); + } + + //Copy the value to the buffer + while(**line != valueEnd && **line != '\n' && **line != '\0') + { + ffStrbufAppendC(buffer, **line); + ++(*line); + } + + ffStrbufTrimRight(buffer, ' '); + + return true; +} + +bool ffParsePropLine(const char* line, const char* start, FFstrbuf* buffer) +{ + return parsePropLinePointer(&line, start, buffer); +} + +bool ffParsePropLines(const char* lines, const char* start, FFstrbuf* buffer) +{ + while(!parsePropLinePointer(&lines, start, buffer)) + { + while(*lines != '\0' && *lines != '\n') + ++lines; + + if(*lines == '\0') + return false; + + //Skip '\n' + ++lines; + } + + return true; +} + +// The following functions return true if the file was found, independently if start was found +// Buffers which already contain content are not overwritten +// The last occurence of start in the first file will be the one used +// The *Values methods always return true, if all properties were already found before, without testing if the file exists + +bool ffParsePropFileValues(const char* filename, uint32_t numQueries, FFpropquery* queries) +{ + bool* searchedValues = malloc(sizeof(bool) * numQueries); + bool allSet = true; + for(uint32_t i = 0; i < numQueries; i++) + { + if((searchedValues[i] = queries[i].buffer->length == 0)) + allSet = false; + } + + if(allSet) + { + free(searchedValues); + return true; + } + + FILE* file = fopen(filename, "r"); + if(file == NULL) + return false; + + char* line = NULL; + size_t len = 0; + + while (getline(&line, &len, file) != -1) + { + for(uint32_t i = 0; i < numQueries; i++) + { + if(!searchedValues[i]) + continue; + + uint32_t currentLength = queries[i].buffer->length; + queries[i].buffer->length = 0; + if(!ffParsePropLine(line, queries[i].start, queries[i].buffer)) + queries[i].buffer->length = currentLength; + } + } + + free(searchedValues); + + if(line != NULL) + free(line); + + fclose(file); + + return true; +} + +bool ffParsePropFile(const char* filename, const char* start, FFstrbuf* buffer) +{ + return ffParsePropFileValues(filename, 1, (FFpropquery[]){{start, buffer}}); +} + +bool ffParsePropFileHomeValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries) +{ + FFstrbuf absolutePath; + ffStrbufInitA(&absolutePath, 64); + ffStrbufAppendS(&absolutePath, instance->state.passwd->pw_dir); + ffStrbufAppendC(&absolutePath, '/'); + ffStrbufAppendS(&absolutePath, relativeFile); + + bool result = ffParsePropFileValues(absolutePath.chars, numQueries, queries); + + ffStrbufDestroy(&absolutePath); + + return result; +} + +bool ffParsePropFileHome(const FFinstance* instance, const char* relativeFile, const char* start, FFstrbuf* buffer) +{ + return ffParsePropFileHomeValues(instance, relativeFile, 1, (FFpropquery[]){{start, buffer}}); +} + +bool ffParsePropFileConfigValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries) +{ + bool foundAFile = false; + + for(uint32_t i = 0; i < instance->state.configDirs.length; i++) + { + FFstrbuf* baseDir = (FFstrbuf*) ffListGet(&instance->state.configDirs, i); + uint32_t baseDirLength = baseDir->length; + + if(*relativeFile != '/') + ffStrbufAppendC(baseDir, '/'); + + ffStrbufAppendS(baseDir, relativeFile); + + if(ffParsePropFileValues(baseDir->chars, numQueries, queries)) + foundAFile = true; + + ffStrbufSubstrBefore(baseDir, baseDirLength); + + bool allSet = true; + for(uint32_t k = 0; k < numQueries; k++) + { + if(queries[k].buffer->length == 0) + { + allSet = false; + break; + } + } + + if(allSet) + break; + } + + return foundAFile; +} + +bool ffParsePropFileConfig(const FFinstance* instance, const char* relativeFile, const char* start, FFstrbuf* buffer) +{ + return ffParsePropFileConfigValues(instance, relativeFile, 1, (FFpropquery[]){{start, buffer}}); +} diff --git a/src/detection/displayserver/wmde.c b/src/detection/displayserver/wmde.c index 5f13dc255..8c3f77dec 100644 --- a/src/detection/displayserver/wmde.c +++ b/src/detection/displayserver/wmde.c @@ -197,7 +197,7 @@ static void getLXQt(const FFinstance* instance, FFDisplayServerResult* result) }); result->deVersion.length = 0; //don't set '\0' byte - ffGetPropValueFromLines(result->deVersion.chars , "liblxqt", &result->deVersion); + ffParsePropLines(result->deVersion.chars , "liblxqt", &result->deVersion); } FFstrbuf wmProcessNameBuffer; diff --git a/src/detection/plasma.c b/src/detection/plasma.c index e339fe588..fa5d91c3b 100644 --- a/src/detection/plasma.c +++ b/src/detection/plasma.c @@ -42,20 +42,20 @@ static bool detectFromConfigFile(const FFstrbuf* filename, FFPlasmaResult* resul } if(category == PLASMA_CATEGORY_KDE && result->widgetStyle.length == 0) - ffGetPropValue(line, "widgetStyle =", &result->widgetStyle); + ffParsePropLine(line, "widgetStyle =", &result->widgetStyle); else if(category == PLASMA_CATEGORY_ICONS && result->icons.length == 0) - ffGetPropValue(line, "Theme =", &result->icons); + ffParsePropLine(line, "Theme =", &result->icons); else if(category == PLASMA_CATEGORY_GENERAL) { if(result->colorScheme.length == 0) - ffGetPropValue(line, "ColorScheme =", &result->colorScheme); + ffParsePropLine(line, "ColorScheme =", &result->colorScheme); if(result->font.length == 0) - ffGetPropValue(line, "font =", &result->font); + ffParsePropLine(line, "font =", &result->font); //Before plasma 5.23, "Font" was the key instead of "font". Since a lot of distros ship older versions, we test for both. if(result->font.length == 0) - ffGetPropValue(line, "Font =", &result->font); + ffParsePropLine(line, "Font =", &result->font); } } diff --git a/src/fastfetch.h b/src/fastfetch.h index 3e4a2f4bc..7b80a14e4 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -394,21 +394,6 @@ void ffListFeatures(); void ffStartDetectionThreads(FFinstance* instance); //common/io.c -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); -void ffGetCacheFilePath(FFinstance* instance, const char* moduleName, const char* extension, FFstrbuf* buffer); -void ffReadCacheFile(FFinstance* instance, const char* moduleName, const char* extension, FFstrbuf* buffer); -void ffWriteCacheFile(FFinstance* instance, const char* moduleName, const char* extension, FFstrbuf* content); -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 ffPrintChar(char c, uint32_t times); - -void ffCacheValidate(FFinstance* instance); -void ffCacheOpenWrite(FFinstance* instance, const char* moduleName, FFcache* cache); -void ffCacheClose(FFcache* cache); - void ffAppendFDContent(int fd, FFstrbuf* buffer); bool ffAppendFileContent(const char* fileName, FFstrbuf* buffer); //returns true if open() succeeds. This is used to differentiate between and bool ffGetFileContent(const char* fileName, FFstrbuf* buffer); @@ -416,16 +401,27 @@ bool ffWriteFDContent(int fd, const FFstrbuf* content); void ffWriteFileContent(const char* fileName, const FFstrbuf* buffer); bool ffFileExists(const char* fileName, mode_t mode); +void ffSuppressIO(bool suppress); // Not thread safe! -// Not thread safe! -void ffSuppressIO(bool suppress); - +//common/printing.c +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); void ffPrintColor(const FFstrbuf* colorValue); +void ffPrintCharTimes(char c, uint32_t times); -// They return true if the file was found, independently if start was found -// Buffers which already contain content are not overwritten -// The last occurence of start in the first file will be the one used -// The *Values methods always return true, if all properties were already found before, without testing if the file exists +//common/caching.c +void ffCacheValidate(FFinstance* instance); + +void ffCacheOpenWrite(FFinstance* instance, const char* moduleName, FFcache* cache); +void ffCacheClose(FFcache* cache); + +bool ffPrintFromCache(FFinstance* instance, const char* moduleName, const FFstrbuf* customKeyFormat, const FFstrbuf* formatString, uint32_t 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); +void ffPrintAndWriteToCache(FFinstance* instance, const char* moduleName, const FFstrbuf* customKeyFormat, const FFstrbuf* value, const FFstrbuf* formatString, uint32_t numArgs, const FFformatarg* arguments); + +//common/properties.c +bool ffParsePropLine(const char* line, const char* start, FFstrbuf* buffer); +bool ffParsePropLines(const char* lines, const char* start, FFstrbuf* buffer); bool ffParsePropFileValues(const char* filename, uint32_t numQueries, FFpropquery* queries); bool ffParsePropFile(const char* filename, const char* start, FFstrbuf* buffer); bool ffParsePropFileHomeValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries); @@ -433,6 +429,21 @@ bool ffParsePropFileHome(const FFinstance* instance, const char* relativeFile, c bool ffParsePropFileConfigValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries); bool ffParsePropFileConfig(const FFinstance* instance, const char* relativeFile, const char* start, FFstrbuf* buffer); +//common/font.c +void ffFontInitQt(FFfont* font, const char* data); +void ffFontInitPango(FFfont* font, const char* data); +void ffFontInitCopy(FFfont* font, const char* name); +void ffFontDestroy(FFfont* font); + +//common/format.c +void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg); +void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, const FFstrbuf* error, uint32_t numArgs, const FFformatarg* arguments); + +//common/parsing.c +bool ffStrSet(const char* str); +void ffParseSemver(FFstrbuf* buffer, const FFstrbuf* major, const FFstrbuf* minor, const FFstrbuf* patch); +void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, const FFstrbuf* gtk4); + //common/processing.c void ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]); @@ -442,25 +453,6 @@ void* ffLibraryLoad(const FFstrbuf* userProvidedName, ...); //common/networking.c void ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, FFstrbuf* buffer); -//common/format.c -void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg); -void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, const FFstrbuf* error, uint32_t numArgs, const FFformatarg* arguments); - -//common/parsing.c -void ffGetGtkPretty(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, const FFstrbuf* gtk4); - -void ffFontInitQt(FFfont* font, const char* data); -void ffFontInitPango(FFfont* font, const char* data); -void ffFontInitCopy(FFfont* font, const char* name); -void ffFontDestroy(FFfont* font); - -bool ffGetPropValue(const char* line, const char* start, FFstrbuf* buffer); -bool ffGetPropValueFromLines(const char* lines, const char* start, FFstrbuf* buffer); - -void ffParseSemver(FFstrbuf* buffer, const FFstrbuf* major, const FFstrbuf* minor, const FFstrbuf* patch); - -bool ffStrSet(const char* str); - //common/settings.c FFvariant ffSettingsGetDConf(FFinstance* instance, const char* key, FFvarianttype type); FFvariant ffSettingsGetGSettings(FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type); diff --git a/src/logo/image.c b/src/logo/image.c index 43241832e..8647ef046 100644 --- a/src/logo/image.c +++ b/src/logo/image.c @@ -74,7 +74,7 @@ static bool printSixel(FFinstance* instance) return false; } - ffPrintChar(' ', instance->config.logoPaddingLeft); + ffPrintCharTimes(' ', instance->config.logoPaddingLeft); imageInfoOut->file = stdout; ffCopyMagickString(imageInfoOut->magick, "SIXEL", 6); diff --git a/src/logo/logo.c b/src/logo/logo.c index 1385f77c1..e2b652834 100644 --- a/src/logo/logo.c +++ b/src/logo/logo.c @@ -7,7 +7,7 @@ void ffLogoPrint(FFinstance* instance, const char* data, bool doColorReplacement uint32_t currentlineLength = 0; fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout); - ffPrintChar(' ', instance->config.logoPaddingLeft); + ffPrintCharTimes(' ', instance->config.logoPaddingLeft); //Use logoColor[0] as the default color if(doColorReplacement) @@ -18,7 +18,7 @@ void ffLogoPrint(FFinstance* instance, const char* data, bool doColorReplacement //We are at the end of a line. Print paddings and update max line length if(*data == '\n' || (*data == '\r' && *(data + 1) == '\n')) { - ffPrintChar(' ', instance->config.logoPaddingRight); + ffPrintCharTimes(' ', instance->config.logoPaddingRight); //We have \r\n, skip the \r if(*data == '\r') @@ -27,7 +27,7 @@ void ffLogoPrint(FFinstance* instance, const char* data, bool doColorReplacement putchar('\n'); ++data; - ffPrintChar(' ', instance->config.logoPaddingLeft); + ffPrintCharTimes(' ', instance->config.logoPaddingLeft); if(currentlineLength > instance->state.logoWidth) instance->state.logoWidth = currentlineLength; @@ -40,7 +40,7 @@ void ffLogoPrint(FFinstance* instance, const char* data, bool doColorReplacement //Always print tabs as 4 spaces, to have consistent spacing if(*data == '\t') { - ffPrintChar(' ', 4); + ffPrintCharTimes(' ', 4); ++data; continue; } @@ -128,7 +128,7 @@ void ffLogoPrint(FFinstance* instance, const char* data, bool doColorReplacement } } - ffPrintChar(' ', instance->config.logoPaddingRight); + ffPrintCharTimes(' ', instance->config.logoPaddingRight); fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout); //Happens if the last line is the longest diff --git a/src/modules/cpu.c b/src/modules/cpu.c index d9515459d..b17d23e52 100644 --- a/src/modules/cpu.c +++ b/src/modules/cpu.c @@ -68,11 +68,11 @@ void ffPrintCPU(FFinstance* instance) break; (void)( - ffGetPropValue(line, "model name :", &name) || - ffGetPropValue(line, "vendor_id :", &vendor) || - ffGetPropValue(line, "cpu cores :", &physicalCoresString) || - ffGetPropValue(line, "cpu MHz :", &procGhzString) || - (name.length == 0 && ffGetPropValue(line, "Hardware :", &name)) //For Android devices + ffParsePropLine(line, "model name :", &name) || + ffParsePropLine(line, "vendor_id :", &vendor) || + ffParsePropLine(line, "cpu cores :", &physicalCoresString) || + ffParsePropLine(line, "cpu MHz :", &procGhzString) || + (name.length == 0 && ffParsePropLine(line, "Hardware :", &name)) //For Android devices ); } @@ -164,7 +164,7 @@ void ffPrintCPU(FFinstance* instance) 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[]){ + ffPrintAndWriteToCache(instance, FF_CPU_MODULE_NAME, &instance->config.cpuKey, &cpu, &instance->config.cpuFormat, FF_CPU_NUM_FORMAT_ARGS, (FFformatarg[]){ {FF_FORMAT_ARG_TYPE_STRBUF, &name}, {FF_FORMAT_ARG_TYPE_STRBUF, &namePretty}, {FF_FORMAT_ARG_TYPE_STRBUF, &vendor}, diff --git a/src/modules/font.c b/src/modules/font.c index 27c721488..28b54f8c3 100644 --- a/src/modules/font.c +++ b/src/modules/font.c @@ -43,7 +43,7 @@ void ffPrintFont(FFinstance* instance) FFstrbuf gtk; ffStrbufInitA(>k, 64); - ffGetGtkPretty(>k, >k2.pretty, >k3.pretty, >k4.pretty); + ffParseGTK(>k, >k2.pretty, >k3.pretty, >k4.pretty); if(instance->config.fontFormat.length == 0) { diff --git a/src/modules/host.c b/src/modules/host.c index c6d0930df..50dc7219e 100644 --- a/src/modules/host.c +++ b/src/modules/host.c @@ -119,7 +119,7 @@ void ffPrintHost(FFinstance* instance) ffStrbufAppend(&host, &version); } - ffPrintAndSaveToCache(instance, FF_HOST_MODULE_NAME, &instance->config.hostKey, &host, &instance->config.hostFormat, FF_HOST_NUM_FORMAT_ARGS, (FFformatarg[]) { + ffPrintAndWriteToCache(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} diff --git a/src/modules/icons.c b/src/modules/icons.c index 940fd72d3..fd299f8a0 100644 --- a/src/modules/icons.c +++ b/src/modules/icons.c @@ -30,7 +30,7 @@ void ffPrintIcons(FFinstance* instance) } FF_STRBUF_CREATE(gtkPretty); - ffGetGtkPretty(>kPretty, gtk2, gtk3, gtk4); + ffParseGTK(>kPretty, gtk2, gtk3, gtk4); if(instance->config.iconsFormat.length == 0) { diff --git a/src/modules/locale.c b/src/modules/locale.c index ce00a1319..530e9b46d 100644 --- a/src/modules/locale.c +++ b/src/modules/locale.c @@ -39,7 +39,7 @@ void ffPrintLocale(FFinstance* instance) return; } - ffPrintAndSaveToCache(instance, FF_LOCALE_MODULE_NAME, &instance->config.localeKey, &locale, &instance->config.localeFormat, FF_LOCALE_NUM_FORMAT_ARGS, (FFformatarg[]){ + ffPrintAndWriteToCache(instance, FF_LOCALE_MODULE_NAME, &instance->config.localeKey, &locale, &instance->config.localeFormat, FF_LOCALE_NUM_FORMAT_ARGS, (FFformatarg[]){ {FF_FORMAT_ARG_TYPE_STRBUF, &locale} }); diff --git a/src/modules/os.c b/src/modules/os.c index ae68ed126..bf57b3973 100644 --- a/src/modules/os.c +++ b/src/modules/os.c @@ -69,7 +69,7 @@ void ffPrintOS(FFinstance* instance) ffStrbufAppendC(&os, ']'); } - ffPrintAndSaveToCache(instance, FF_OS_MODULE_NAME, &instance->config.osKey, &os, &instance->config.osFormat, FF_OS_NUM_FORMAT_ARGS, (FFformatarg[]){ + ffPrintAndWriteToCache(instance, FF_OS_MODULE_NAME, &instance->config.osKey, &os, &instance->config.osFormat, FF_OS_NUM_FORMAT_ARGS, (FFformatarg[]){ {FF_FORMAT_ARG_TYPE_STRBUF, &result->systemName}, {FF_FORMAT_ARG_TYPE_STRBUF, &result->name}, {FF_FORMAT_ARG_TYPE_STRBUF, &result->prettyName}, diff --git a/src/modules/theme.c b/src/modules/theme.c index 40d4cd7ff..3d59535c8 100644 --- a/src/modules/theme.c +++ b/src/modules/theme.c @@ -38,7 +38,7 @@ void ffPrintTheme(FFinstance* instance) ffStrbufTrim(&plasmaColorPretty, ' '); FF_STRBUF_CREATE(gtkPretty); - ffGetGtkPretty(>kPretty, gtk2, gtk3, gtk4); + ffParseGTK(>kPretty, gtk2, gtk3, gtk4); if(instance->config.themeFormat.length == 0) {