From 76424950e373d3b04ac3dd13019151bfba3e8423 Mon Sep 17 00:00:00 2001 From: sumuel Date: Mon, 17 Aug 2026 20:44:55 +0000 Subject: Add the files --- src/common/impl/option.c | 185 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 src/common/impl/option.c (limited to 'src/common/impl/option.c') diff --git a/src/common/impl/option.c b/src/common/impl/option.c new file mode 100644 index 0000000..3d592d0 --- /dev/null +++ b/src/common/impl/option.c @@ -0,0 +1,185 @@ +#include "fastfetch.h" +#include "common/option.h" +#include "common/color.h" +#include "common/strutil.h" + +#include + +// Return start position of the inner key if the argument key belongs to the module specified, NULL otherwise +const char* ffOptionTestPrefix(const char* argumentKey, const char* moduleName) { + assert(argumentKey && moduleName); + + const char* subKey = argumentKey; + if (!(subKey[0] == '-' && subKey[1] == '-')) { + return NULL; + } + + subKey += 2; + uint32_t moduleNameLen = (uint32_t) strlen(moduleName); + if (strncasecmp(subKey, moduleName, moduleNameLen) != 0) { + return NULL; + } + + subKey += moduleNameLen; + + if (subKey[0] == '\0') { + return subKey; + } + + if (subKey[0] != '-') { + return NULL; + } + + subKey += 1; + + return subKey; +} + +void ffOptionParseString(const char* argumentKey, const char* value, FFstrbuf* buffer) { + if (value == NULL) { + fprintf(stderr, "Error: usage: %s \n", argumentKey); + exit(477); + } + + ffStrbufSetS(buffer, value); +} + +uint32_t ffOptionParseUInt32(const char* argumentKey, const char* value) { + if (value == NULL) { + fprintf(stderr, "Error: usage: %s \n", argumentKey); + exit(480); + } + + char* end; + unsigned long num = strtoul(value, &end, 10); + if (value[0] == '-' || *end != '\0' || num > UINT32_MAX) { + fprintf(stderr, "Error: usage: %s \n", argumentKey); + exit(479); + } + + return (uint32_t) num; +} + +int32_t ffOptionParseInt32(const char* argumentKey, const char* value) { + if (value == NULL) { + fprintf(stderr, "Error: usage: %s \n", argumentKey); + exit(480); + } + + char* end; + long num = strtol(value, &end, 10); + if (*end != '\0' || num < INT32_MIN || num > INT32_MAX) { + fprintf(stderr, "Error: usage: %s \n", argumentKey); + exit(479); + } + + return (int32_t) num; +} + +int ffOptionParseEnum(const char* argumentKey, const char* requestedKey, FFKeyValuePair pairs[]) { + if (requestedKey == NULL) { + fprintf(stderr, "Error: usage: %s \n", argumentKey); + exit(476); + } + + for (const FFKeyValuePair* pPair = pairs; pPair->key; ++pPair) { + if (ffStrEqualsIgnCase(requestedKey, pPair->key)) { + return pPair->value; + } + } + + fprintf(stderr, "Error: unknown %s value: %s\n", argumentKey, requestedKey); + exit(478); +} + +bool ffOptionParseBoolean(const char* str) { + return ( + !ffStrSet(str) || + ffStrEqualsIgnCase(str, "true") || + ffStrEqualsIgnCase(str, "yes") || + ffStrEqualsIgnCase(str, "on") || + ffStrEqualsIgnCase(str, "1")); +} + +void ffOptionParseColorNoClear(const char* value, FFstrbuf* buffer) { + if (!value || value[0] == '\0') { + return; + } + + // If value is already an ANSI escape code, use it + if (value[0] == '\e' && value[1] == '[') { + ffStrbufAppendS(buffer, value + 2); + ffStrbufTrimRight(buffer, 'm'); + return; + } + + ffStrbufEnsureFree(buffer, 63); + + while (*value != '\0') { +#define FF_APPEND_COLOR_CODE_COND(prefix, code) \ + if (ffStrStartsWithIgnCase(value, #prefix)) { \ + ffStrbufAppendS(buffer, code); \ + value += strlen(#prefix); \ + continue; \ + } +#define FF_APPEND_COLOR_PROP_COND(prefix, prop) \ + if (ffStrStartsWithIgnCase(value, #prefix)) { \ + if (instance.config.display.prop.length) ffStrbufAppend(buffer, &instance.config.display.prop); \ + else ffStrbufAppendS(buffer, FF_COLOR_FG_DEFAULT); \ + value += strlen(#prefix); \ + continue; \ + } + + if (ffCharIsEnglishAlphabet(value[0])) { + FF_APPEND_COLOR_CODE_COND(reset_, FF_COLOR_MODE_RESET) + else FF_APPEND_COLOR_CODE_COND(bold_, FF_COLOR_MODE_BOLD) else FF_APPEND_COLOR_CODE_COND(bright_, FF_COLOR_MODE_BOLD) else FF_APPEND_COLOR_CODE_COND(dim_, FF_COLOR_MODE_DIM) else FF_APPEND_COLOR_CODE_COND(italic_, FF_COLOR_MODE_ITALIC) else FF_APPEND_COLOR_CODE_COND(underline_, FF_COLOR_MODE_UNDERLINE) else FF_APPEND_COLOR_CODE_COND(blink_, FF_COLOR_MODE_BLINK) else FF_APPEND_COLOR_CODE_COND(inverse_, FF_COLOR_MODE_INVERSE) else FF_APPEND_COLOR_CODE_COND(hidden_, FF_COLOR_MODE_HIDDEN) else FF_APPEND_COLOR_CODE_COND(strike_, FF_COLOR_MODE_STRIKETHROUGH) else FF_APPEND_COLOR_CODE_COND(black, FF_COLOR_FG_BLACK) else FF_APPEND_COLOR_CODE_COND(red, FF_COLOR_FG_RED) else FF_APPEND_COLOR_CODE_COND(green, FF_COLOR_FG_GREEN) else FF_APPEND_COLOR_CODE_COND(yellow, FF_COLOR_FG_YELLOW) else FF_APPEND_COLOR_CODE_COND(blue, FF_COLOR_FG_BLUE) else FF_APPEND_COLOR_CODE_COND(magenta, FF_COLOR_FG_MAGENTA) else FF_APPEND_COLOR_CODE_COND(cyan, FF_COLOR_FG_CYAN) else FF_APPEND_COLOR_CODE_COND(white, FF_COLOR_FG_WHITE) else FF_APPEND_COLOR_CODE_COND(default, FF_COLOR_FG_DEFAULT) else FF_APPEND_COLOR_CODE_COND(light_black, FF_COLOR_FG_LIGHT_BLACK) else FF_APPEND_COLOR_CODE_COND(light_red, FF_COLOR_FG_LIGHT_RED) else FF_APPEND_COLOR_CODE_COND(light_green, FF_COLOR_FG_LIGHT_GREEN) else FF_APPEND_COLOR_CODE_COND(light_yellow, FF_COLOR_FG_LIGHT_YELLOW) else FF_APPEND_COLOR_CODE_COND(light_blue, FF_COLOR_FG_LIGHT_BLUE) else FF_APPEND_COLOR_CODE_COND(light_magenta, FF_COLOR_FG_LIGHT_MAGENTA) else FF_APPEND_COLOR_CODE_COND(light_cyan, FF_COLOR_FG_LIGHT_CYAN) else FF_APPEND_COLOR_CODE_COND(light_white, FF_COLOR_FG_LIGHT_WHITE) else FF_APPEND_COLOR_PROP_COND(keys, colorKeys) else FF_APPEND_COLOR_PROP_COND(title, colorTitle) else FF_APPEND_COLOR_PROP_COND(output, colorOutput) else FF_APPEND_COLOR_PROP_COND(separator, colorSeparator) else { + fprintf(stderr, "Error: invalid color code found: %s\n", value); + exit(479); + } + } else if (value[0] == '@') { + // Xterm 256 color + ++value; + char* pend = NULL; + uint32_t color = (uint32_t) strtoul(value, &pend, 10); + if (pend == value || color > 255) { + fprintf(stderr, "Error: invalid 256 color code found: %s\n", value); + exit(479); + } + + ffStrbufAppendS(buffer, FF_COLOR_FG_256); + ffStrbufAppendUInt(buffer, color); + value = pend; + continue; + } else if (value[0] == '#') { + // RGB color + ++value; + char* pend = NULL; + uint32_t rgb = (uint32_t) strtoul(value, &pend, 16); + if (pend == value) { + fprintf(stderr, "Error: invalid RGB color code found: %s\n", value); + exit(479); + } + if (pend - value > 6) { + fprintf(stderr, "Error: RGB color code too long: %s\n", value); + exit(479); + } else if (pend - value == 3) { + rgb = ((rgb & 0xF00) >> 8) * 0x110000 + + ((rgb & 0x0F0) >> 4) * 0x001100 + + ((rgb & 0x00F) >> 0) * 0x000011; + } else if (pend - value != 6) { + fprintf(stderr, "Error: invalid RGB color code length: %s\n", value); + exit(479); + } + + uint32_t r = rgb >> 16, g = (rgb >> 8) & 0xFF, b = rgb & 0xFF; + ffStrbufAppendF(buffer, FF_COLOR_FG_RGB "%u;%u;%u", r, g, b); + value = pend; + continue; + } + ffStrbufAppendC(buffer, *value); + ++value; + +#undef FF_APPEND_COLOR_CODE_COND +#undef FF_APPEND_COLOR_PROP_COND + } +} -- cgit v1.2.3