diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 26b197503..cb4355dc6 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -21,7 +21,7 @@ jobs: uses: actions/checkout@v3 - name: install required packages - run: sudo apt-get update && sudo apt-get install -y libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev rpm librpm-dev libzstd-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev libcjson-dev + run: sudo apt-get update && sudo apt-get install -y libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev rpm librpm-dev libzstd-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev libjson-c-dev - name: configure project env: @@ -53,7 +53,7 @@ jobs: uses: actions/checkout@v3 - name: install required packages - run: sudo apt-get update && sudo apt-get install -y libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev rpm librpm-dev libzstd-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev libcjson-dev + run: sudo apt-get update && sudo apt-get install -y libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev rpm librpm-dev libzstd-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev libjson-c-dev - name: Initialize CodeQL uses: github/codeql-action/init@v2 @@ -183,7 +183,7 @@ jobs: with: msystem: CLANG64 update: true - install: git zip mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-opencl-icd mingw-w64-clang-x86_64-cjson + install: git zip mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-opencl-icd mingw-w64-clang-x86_64-json-c - name: print msys version run: uname -a @@ -203,7 +203,7 @@ jobs: uses: github/codeql-action/analyze@v2 - name: copy necessary dlls - run: cp /clang64/bin/{libcjson,OpenCL,vulkan-1}.dll . + run: cp /clang64/bin/{libjson-c*,OpenCL,vulkan-1}.dll . - name: list features run: ./fastfetch --list-features @@ -244,7 +244,7 @@ jobs: with: msystem: CLANG32 update: true - install: git zip mingw-w64-clang-i686-cmake mingw-w64-clang-i686-clang mingw-w64-clang-i686-vulkan-loader mingw-w64-clang-i686-opencl-icd mingw-w64-clang-i686-cjson + install: git zip mingw-w64-clang-i686-cmake mingw-w64-clang-i686-clang mingw-w64-clang-i686-vulkan-loader mingw-w64-clang-i686-opencl-icd mingw-w64-clang-i686-json-c - name: print msys version run: uname -a @@ -264,7 +264,7 @@ jobs: uses: github/codeql-action/analyze@v2 - name: copy necessary dlls - run: cp /clang32/bin/{libcjson,OpenCL,vulkan-1}.dll . + run: cp /clang32/bin/{libjson-c*,OpenCL,vulkan-1}.dll . - name: run fastfetch run: time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b99eba1f..fb38752aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -68,6 +68,9 @@ Bugfixes: * Don't exit if libpci is failed to init (GPU, Linux, #433) * Names of most well-known gamepads are correctly printed instead of `Wireless Controller` on Windows +Changes: +* Use json-c to parse JSON strings for comments support, instead of using unmaintained cJSON + Logo: * Small update for nobara logo (#435, @regulargvy13) diff --git a/CMakeLists.txt b/CMakeLists.txt index a5ae85629..1ee8d861c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,7 +70,7 @@ cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD OR WIN32" cmake_dependent_option(ENABLE_LIBNM "Enable libnm" ON "LINUX" OFF) cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF) cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR BSD" OFF) -cmake_dependent_option(ENABLE_LIBCJSON "Enable libcjson" ON "LINUX OR WIN32" OFF) +cmake_dependent_option(ENABLE_JSONC "Enable json-c" ON "LINUX OR APPLE OR BSD OR WIN32 OR ANDROID" OFF) cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" OFF) cmake_dependent_option(ENABLE_BUFFER "Enable stdout buffer" ON "LINUX OR APPLE OR BSD OR WIN32 OR ANDROID" OFF) @@ -231,14 +231,17 @@ set(LIBFASTFETCH_SRC src/common/font.c src/common/format.c src/common/init.c + src/common/json.c + src/common/jsonconfig.c src/common/library.c + src/common/option.c src/common/parsing.c src/common/printing.c src/common/properties.c src/common/settings.c src/detection/bluetooth/bluetooth.c src/detection/cpu/cpu.c - src/detection/cpuUsage/cpuUsage.c + src/detection/cpuusage/cpuusage.c src/detection/datetime/datetime.c src/detection/disk/disk.c src/detection/displayserver/displayserver.c @@ -258,62 +261,61 @@ set(LIBFASTFETCH_SRC src/logo/image/im7.c src/logo/image/image.c src/logo/logo.c - src/modules/battery.c - src/modules/bios.c - src/modules/bluetooth.c - src/modules/board.c - src/modules/brightness.c - src/modules/break.c - src/modules/chassis.c - src/modules/colors.c - src/modules/cpu.c - src/modules/cpuUsage.c - src/modules/cursor.c - src/modules/custom.c - src/modules/command.c - src/modules/date.c - src/modules/datetime.c - src/modules/de.c - src/modules/disk.c - src/modules/font.c - src/modules/gpu.c - src/modules/host.c - src/modules/icons.c - src/modules/gamepad.c - src/modules/kernel.c - src/modules/locale.c - src/modules/localip.c - src/modules/memory.c - src/modules/opencl.c - src/modules/opengl.c - src/modules/os.c - src/modules/packages.c - src/modules/player.c - src/modules/poweradapter.c - src/modules/processes.c - src/modules/publicip.c - src/modules/display.c - src/modules/separator.c - src/modules/shell.c - src/modules/sound.c - src/modules/swap.c - src/modules/media.c - src/modules/terminal.c - src/modules/terminalfont.c - src/modules/theme.c - src/modules/time.c - src/modules/title.c - src/modules/uptime.c - src/modules/users.c - src/modules/vulkan.c - src/modules/wallpaper.c - src/modules/weather.c - src/modules/wifi.c - src/modules/wm.c - src/modules/wmtheme.c + src/logo/option.c + src/modules/battery/battery.c + src/modules/bios/bios.c + src/modules/bluetooth/bluetooth.c + src/modules/board/board.c + src/modules/brightness/brightness.c + src/modules/break/break.c + src/modules/chassis/chassis.c + src/modules/colors/colors.c + src/modules/cpu/cpu.c + src/modules/cpuusage/cpuusage.c + src/modules/cursor/cursor.c + src/modules/custom/custom.c + src/modules/command/command.c + src/modules/datetime/datetime.c + src/modules/de/de.c + src/modules/disk/disk.c + src/modules/font/font.c + src/modules/gpu/gpu.c + src/modules/host/host.c + src/modules/icons/icons.c + src/modules/gamepad/gamepad.c + src/modules/kernel/kernel.c + src/modules/locale/locale.c + src/modules/localip/localip.c + src/modules/memory/memory.c + src/modules/opencl/opencl.c + src/modules/opengl/opengl.c + src/modules/os/os.c + src/modules/packages/packages.c + src/modules/processes/processes.c + src/modules/player/player.c + src/modules/poweradapter/poweradapter.c + src/modules/publicip/publicip.c + src/modules/display/display.c + src/modules/separator/separator.c + src/modules/shell/shell.c + src/modules/sound/sound.c + src/modules/swap/swap.c + src/modules/media/media.c + src/modules/terminal/terminal.c + src/modules/terminalfont/terminalfont.c + src/modules/theme/theme.c + src/modules/title/title.c + src/modules/uptime/uptime.c + src/modules/users/users.c + src/modules/vulkan/vulkan.c + src/modules/wallpaper/wallpaper.c + src/modules/weather/weather.c + src/modules/wifi/wifi.c + src/modules/wm/wm.c + src/modules/wmtheme/wmtheme.c + src/modules/jsonconfig/jsonconfig.c src/util/FFlist.c src/util/FFstrbuf.c - src/util/FFvaluestore.c src/util/platform/FFPlatform.c src/util/stringUtils.c ) @@ -330,7 +332,7 @@ if(LINUX) src/detection/brightness/brightness_linux.c src/detection/chassis/chassis_linux.c src/detection/cpu/cpu_linux.c - src/detection/cpuUsage/cpuUsage_linux.c + src/detection/cpuusage/cpuusage_linux.c src/detection/cursor/cursor_linux.c src/detection/bluetooth/bluetooth_linux.c src/detection/disk/disk_linux.c @@ -380,7 +382,7 @@ elseif(ANDROID) src/detection/chassis/chassis_nosupport.c src/detection/cpu/cpu_linux.c src/detection/cursor/cursor_nosupport.c - src/detection/cpuUsage/cpuUsage_linux.c + src/detection/cpuusage/cpuusage_linux.c src/detection/disk/disk_linux.c src/detection/displayserver/displayserver_nosupport.c src/detection/font/font_nosupport.c @@ -423,7 +425,7 @@ elseif(BSD) src/detection/brightness/brightness_nosupport.c src/detection/chassis/chassis_nosupport.c src/detection/cpu/cpu_bsd.c - src/detection/cpuUsage/cpuUsage_bsd.c + src/detection/cpuusage/cpuusage_bsd.c src/detection/cursor/cursor_linux.c src/detection/disk/disk_bsd.c src/detection/displayserver/linux/displayserver_linux.c @@ -472,7 +474,7 @@ elseif(APPLE) src/detection/brightness/brightness_apple.c src/detection/chassis/chassis_nosupport.c src/detection/cpu/cpu_apple.c - src/detection/cpuUsage/cpuUsage_apple.c + src/detection/cpuusage/cpuusage_apple.c src/detection/cursor/cursor_apple.m src/detection/disk/disk_apple.m src/detection/disk/disk_bsd.c @@ -517,7 +519,7 @@ elseif(WIN32) src/detection/brightness/brightness_windows.cpp src/detection/chassis/chassis_nosupport.c src/detection/cpu/cpu_windows.c - src/detection/cpuUsage/cpuUsage_windows.c + src/detection/cpuusage/cpuusage_windows.c src/detection/cursor/cursor_windows.c src/detection/disk/disk_windows.c src/detection/displayserver/displayserver_windows.c @@ -700,9 +702,9 @@ ff_lib_enable(PULSE "libpulse" "Pulse" ) -ff_lib_enable(LIBCJSON - "libcjson" - "CJson" +ff_lib_enable(JSONC + "json-c" + "json-c" ) if(ENABLE_THREADS) diff --git a/README.md b/README.md index ef9536c06..a5a153ee8 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ The following libraries are used if present at runtime: * [`libXFConf`](https://gitlab.xfce.org/xfce/xfconf): Needed for XFWM theme and XFCE Terminal font. * [`libsqlite3`](https://www.sqlite.org/index.html): Needed for pkg & rpm package count. * [`librpm`](http://rpm.org/): Slower fallback for rpm package count. Needed on openSUSE. -* [`libcJSON`](https://github.com/DaveGamble/cJSON): Needed for Windows Terminal font ( WSL ). +* [`json-c`](https://github.com/json-c/json-c): Needed for Windows Terminal font ( WSL ). * [`libnm`](https://networkmanager.dev/docs/libnm/latest/): Used for Wifi detection. * [`libpulse`](https://freedesktop.org/software/pulseaudio/doxygen/): Used for Sound detection. @@ -71,7 +71,7 @@ For the image logo, iTerm with iterm image protocol should work. Apple Terminal ### Windows * [`wlanapi`](https://learn.microsoft.com/en-us/windows/win32/api/wlanapi/): A system dll which isn't supported by Windows Server by default. Used for Wifi info detection. -* [`libcJSON`](https://github.com/DaveGamble/cJSON): Used for Windows Terminal font detection. [`cjson`](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-cjson) +* [`json-c`](https://github.com/json-c/json-c): Used for Windows Terminal font detection. [`json-c`](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-json-c) * [`libvulkan`](https://www.vulkan.org/): Vulkan module. Usually has been provided by GPU drivers. [`vulkan-loader`](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-vulkan-loader) [`vulkan-headers`](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-vulkan-headers) * [`libOpenCL`](https://www.khronos.org/opencl/): OpenCL module. [`opencl-icd`](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-opencl-icd) @@ -138,7 +138,7 @@ Currently GCC or clang is required (MSVC is not supported). MSYS2 with CLANG64 s 1. Open `MSYS2 / CLANG64` (not `MSYS2 / MSYS`, which targets cygwin C runtime) 1. Install dependencies ```bash -pacman -Syu mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-pkgconf mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-cjson mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-opencl-icd +pacman -Syu mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-pkgconf mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-json-c mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-opencl-icd ``` Follow the building instructions of Linux next. diff --git a/src/common/font.c b/src/common/font.c index d789d466f..8d79907b8 100644 --- a/src/common/font.c +++ b/src/common/font.c @@ -7,7 +7,7 @@ static void fontInit(FFfont* font) { ffStrbufInit(&font->pretty); ffStrbufInit(&font->name); - ffStrbufInitA(&font->size, 4); + ffStrbufInitA(&font->size, 8); ffListInitA(&font->styles, sizeof(FFstrbuf), 4); } diff --git a/src/common/format.c b/src/common/format.c index 7394822f8..07f54f247 100644 --- a/src/common/format.c +++ b/src/common/format.c @@ -134,18 +134,14 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n continue; } - FFstrbuf placeholderValue; - ffStrbufInit(&placeholderValue); + FF_STRBUF_AUTO_DESTROY placeholderValue = ffStrbufCreate(); while(i < formatstr->length && formatstr->chars[i] != '}') ffStrbufAppendC(&placeholderValue, formatstr->chars[i++]); // test if for stop, if so break the loop if(placeholderValue.length == 1 && placeholderValue.chars[0] == '-') - { - ffStrbufDestroy(&placeholderValue); break; - } // test for end of an if, if so do nothing if(placeholderValue.length == 1 && placeholderValue.chars[0] == '?') @@ -155,7 +151,6 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n else --numOpenIfs; - ffStrbufDestroy(&placeholderValue); continue; } @@ -167,7 +162,6 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n else --numOpenNotIfs; - ffStrbufDestroy(&placeholderValue); continue; } @@ -182,7 +176,6 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n --numOpenColors; } - ffStrbufDestroy(&placeholderValue); continue; } @@ -197,7 +190,6 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n if(index > numArgs) { appendInvalidPlaceholder(buffer, "{?", &placeholderValue, i, formatstr->length); - ffStrbufDestroy(&placeholderValue); continue; } @@ -205,13 +197,11 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n if(formatArgSet(&arguments[index - 1])) { ++numOpenIfs; - ffStrbufDestroy(&placeholderValue); continue; } // fastforward to the end of the if without printing the in between i = ffStrbufNextIndexS(formatstr, i, "{?}") + 2; // 2 is the length of "{?}" - 1 because the loop will increament it again directly after continue - ffStrbufDestroy(&placeholderValue); continue; } @@ -226,7 +216,6 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n if(index > numArgs) { appendInvalidPlaceholder(buffer, "{/", &placeholderValue, i, formatstr->length); - ffStrbufDestroy(&placeholderValue); continue; } @@ -234,13 +223,11 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n if(!formatArgSet(&arguments[index - 1])) { ++numOpenNotIfs; - ffStrbufDestroy(&placeholderValue); continue; } // fastforward to the end of the if without printing the in between i = ffStrbufNextIndexS(formatstr, i, "{/}") + 2; // 2 is the length of "{/}" - 1 because the loop will increament it again directly after continue - ffStrbufDestroy(&placeholderValue); continue; } @@ -252,7 +239,6 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n ffStrbufAppendS(buffer, "\033["); ffStrbufAppend(buffer, &placeholderValue); ffStrbufAppendC(buffer, 'm'); - ffStrbufDestroy(&placeholderValue); continue; } @@ -262,13 +248,10 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n if(index > numArgs) { appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length); - ffStrbufDestroy(&placeholderValue); continue; } ffFormatAppendFormatArg(buffer, &arguments[index - 1]); - - ffStrbufDestroy(&placeholderValue); } ffStrbufTrimRight(buffer, ' '); diff --git a/src/common/init.c b/src/common/init.c index 372b2dd8f..d478d518e 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -3,6 +3,7 @@ #include "common/thread.h" #include "detection/displayserver/displayserver.h" #include "util/textModifier.h" +#include "logo/logo.h" #include #include @@ -15,47 +16,27 @@ #include #endif +#include "modules/modules.h" + static void initState(FFstate* state) { state->logoWidth = 0; state->logoHeight = 0; state->keysHeight = 0; + state->titleLength = 0; ffPlatformInit(&state->platform); } -static void initModuleArg(FFModuleArgs* args) -{ - ffStrbufInit(&args->key); - ffStrbufInit(&args->outputFormat); - ffStrbufInit(&args->errorFormat); -} - static void defaultConfig(FFinstance* instance) { - ffStrbufInitA(&instance->config.logo.source, 0); - instance->config.logo.type = FF_LOGO_TYPE_AUTO; - for(uint8_t i = 0; i < (uint8_t) FASTFETCH_LOGO_MAX_COLORS; ++i) - ffStrbufInit(&instance->config.logo.colors[i]); - instance->config.logo.width = 0; - instance->config.logo.height = 0; //preserve aspect ratio - instance->config.logo.paddingTop = 0; - instance->config.logo.paddingLeft = 0; - instance->config.logo.paddingRight = 4; - instance->config.logo.printRemaining = true; - instance->config.logo.preserveAspectRadio = false; - - instance->config.logo.chafaFgOnly = false; - ffStrbufInitS(&instance->config.logo.chafaSymbols, "block+border+space-wide-inverted"); // Chafa default - instance->config.logo.chafaCanvasMode = UINT32_MAX; - instance->config.logo.chafaColorSpace = UINT32_MAX; - instance->config.logo.chafaDitherMode = UINT32_MAX; + ffInitLogoOptions(&instance->config.logo); ffStrbufInit(&instance->config.colorKeys); ffStrbufInit(&instance->config.colorTitle); - ffStrbufInit(&instance->config.separator); - ffStrbufAppendS(&instance->config.separator, ": "); + ffStrbufInit(&instance->config.keyValueSeparator); + ffStrbufAppendS(&instance->config.keyValueSeparator, ": "); instance->config.showErrors = false; instance->config.recache = false; @@ -64,139 +45,87 @@ static void defaultConfig(FFinstance* instance) instance->config.hideCursor = true; instance->config.escapeBedrock = true; instance->config.binaryPrefixType = FF_BINARY_PREFIX_TYPE_IEC; - instance->config.glType = FF_GL_TYPE_AUTO; instance->config.pipe = false; instance->config.multithreading = true; instance->config.stat = false; - initModuleArg(&instance->config.os); - initModuleArg(&instance->config.host); - initModuleArg(&instance->config.bios); - initModuleArg(&instance->config.board); - initModuleArg(&instance->config.brightness); - initModuleArg(&instance->config.chassis); - initModuleArg(&instance->config.kernel); - initModuleArg(&instance->config.uptime); - initModuleArg(&instance->config.processes); - initModuleArg(&instance->config.packages); - initModuleArg(&instance->config.shell); - initModuleArg(&instance->config.display); - initModuleArg(&instance->config.de); - initModuleArg(&instance->config.wm); - initModuleArg(&instance->config.wmTheme); - initModuleArg(&instance->config.theme); - initModuleArg(&instance->config.icons); - initModuleArg(&instance->config.font); - initModuleArg(&instance->config.cursor); - initModuleArg(&instance->config.terminal); - initModuleArg(&instance->config.terminalFont); - initModuleArg(&instance->config.cpu); - initModuleArg(&instance->config.cpuUsage); - initModuleArg(&instance->config.gpu); - initModuleArg(&instance->config.memory); - initModuleArg(&instance->config.swap); - initModuleArg(&instance->config.disk); - initModuleArg(&instance->config.battery); - initModuleArg(&instance->config.powerAdapter); - initModuleArg(&instance->config.locale); - initModuleArg(&instance->config.localIP); - initModuleArg(&instance->config.publicIP); - initModuleArg(&instance->config.weather); - initModuleArg(&instance->config.wifi); - initModuleArg(&instance->config.player); - initModuleArg(&instance->config.media); - initModuleArg(&instance->config.dateTime); - initModuleArg(&instance->config.date); - initModuleArg(&instance->config.time); - initModuleArg(&instance->config.vulkan); - initModuleArg(&instance->config.wallpaper); - initModuleArg(&instance->config.openGL); - initModuleArg(&instance->config.openCL); - initModuleArg(&instance->config.users); - initModuleArg(&instance->config.bluetooth); - initModuleArg(&instance->config.sound); - initModuleArg(&instance->config.gamepad); + ffInitTitleOptions(&instance->config.title); + ffInitOSOptions(&instance->config.os); + ffInitHostOptions(&instance->config.host); + ffInitBiosOptions(&instance->config.bios); + ffInitBoardOptions(&instance->config.board); + ffInitBrightnessOptions(&instance->config.brightness); + ffInitChassisOptions(&instance->config.chassis); + ffInitCommandOptions(&instance->config.command); + ffInitCustomOptions(&instance->config.custom); + ffInitKernelOptions(&instance->config.kernel); + ffInitUptimeOptions(&instance->config.uptime); + ffInitProcessesOptions(&instance->config.processes); + ffInitPackagesOptions(&instance->config.packages); + ffInitShellOptions(&instance->config.shell); + ffInitDisplayOptions(&instance->config.display); + ffInitDEOptions(&instance->config.de); + ffInitWMOptions(&instance->config.wm); + ffInitWMThemeOptions(&instance->config.wmTheme); + ffInitThemeOptions(&instance->config.theme); + ffInitIconsOptions(&instance->config.icons); + ffInitFontOptions(&instance->config.font); + ffInitCursorOptions(&instance->config.cursor); + ffInitTerminalOptions(&instance->config.terminal); + ffInitTerminalFontOptions(&instance->config.terminalFont); + ffInitCPUOptions(&instance->config.cpu); + ffInitCPUUsageOptions(&instance->config.cpuUsage); + ffInitGPUOptions(&instance->config.gpu); + ffInitMemoryOptions(&instance->config.memory); + ffInitSwapOptions(&instance->config.swap); + ffInitDiskOptions(&instance->config.disk); + ffInitBatteryOptions(&instance->config.battery); + ffInitPowerAdapterOptions(&instance->config.powerAdapter); + ffInitLocaleOptions(&instance->config.locale); + ffInitLocalIpOptions(&instance->config.localIP); + ffInitPublicIpOptions(&instance->config.publicIP); + ffInitWeatherOptions(&instance->config.weather); + ffInitWifiOptions(&instance->config.wifi); + ffInitPlayerOptions(&instance->config.player); + ffInitMediaOptions(&instance->config.media); + ffInitDateTimeOptions(&instance->config.dateTime); + ffInitVulkanOptions(&instance->config.vulkan); + ffInitWallpaperOptions(&instance->config.wallpaper); + ffInitOpenGLOptions(&instance->config.openGL); + ffInitOpenCLOptions(&instance->config.openCL); + ffInitUsersOptions(&instance->config.users); + ffInitBluetoothOptions(&instance->config.bluetooth); + ffInitSoundOptions(&instance->config.sound); + ffInitSeparatorOptions(&instance->config.separator); + ffInitGamepadOptions(&instance->config.gamepad); - ffStrbufInitA(&instance->config.libPCI, 0); - ffStrbufInitA(&instance->config.libVulkan, 0); - ffStrbufInitA(&instance->config.libWayland, 0); - ffStrbufInitA(&instance->config.libXcbRandr, 0); - ffStrbufInitA(&instance->config.libXcb, 0); - ffStrbufInitA(&instance->config.libXrandr, 0); - ffStrbufInitA(&instance->config.libX11, 0); - ffStrbufInitA(&instance->config.libGIO, 0); - ffStrbufInitA(&instance->config.libDConf, 0); - ffStrbufInitA(&instance->config.libDBus, 0); - ffStrbufInitA(&instance->config.libXFConf, 0); - ffStrbufInitA(&instance->config.libSQLite3, 0); - ffStrbufInitA(&instance->config.librpm, 0); - ffStrbufInitA(&instance->config.libImageMagick, 0); - ffStrbufInitA(&instance->config.libZ, 0); - ffStrbufInitA(&instance->config.libChafa, 0); - ffStrbufInitA(&instance->config.libEGL, 0); - ffStrbufInitA(&instance->config.libGLX, 0); - ffStrbufInitA(&instance->config.libOSMesa, 0); - ffStrbufInitA(&instance->config.libOpenCL, 0); - ffStrbufInitA(&instance->config.libcJSON, 0); - ffStrbufInitA(&instance->config.libfreetype, 0); + ffStrbufInit(&instance->config.libPCI); + ffStrbufInit(&instance->config.libVulkan); + ffStrbufInit(&instance->config.libWayland); + ffStrbufInit(&instance->config.libXcbRandr); + ffStrbufInit(&instance->config.libXcb); + ffStrbufInit(&instance->config.libXrandr); + ffStrbufInit(&instance->config.libX11); + ffStrbufInit(&instance->config.libGIO); + ffStrbufInit(&instance->config.libDConf); + ffStrbufInit(&instance->config.libDBus); + ffStrbufInit(&instance->config.libXFConf); + ffStrbufInit(&instance->config.libSQLite3); + ffStrbufInit(&instance->config.librpm); + ffStrbufInit(&instance->config.libImageMagick); + ffStrbufInit(&instance->config.libZ); + ffStrbufInit(&instance->config.libChafa); + ffStrbufInit(&instance->config.libEGL); + ffStrbufInit(&instance->config.libGLX); + ffStrbufInit(&instance->config.libOSMesa); + ffStrbufInit(&instance->config.libOpenCL); + ffStrbufInit(&instance->config.libJSONC); + ffStrbufInit(&instance->config.libfreetype); ffStrbufInit(&instance->config.libPulse); ffStrbufInit(&instance->config.libwlanapi); ffStrbufInit(&instance->config.libnm); - instance->config.cpuTemp = false; - instance->config.gpuTemp = false; - instance->config.gpuForceVulkan = false; - instance->config.batteryTemp = false; - - instance->config.gpuHideIntegrated = false; - instance->config.gpuHideDiscrete = false; - - instance->config.shellVersion = true; - instance->config.terminalVersion = true; - - instance->config.titleFQDN = false; - - ffStrbufInitA(&instance->config.diskFolders, 0); - instance->config.diskShowTypes = FF_DISK_TYPE_REGULAR_BIT | FF_DISK_TYPE_EXTERNAL_BIT; - - instance->config.displayCompactType = FF_DISPLAY_COMPACT_TYPE_NONE; - instance->config.displayDetectName = false; - instance->config.displayPreciseRefreshRate = false; - - instance->config.bluetoothShowDisconnected = false; - - instance->config.soundType = FF_SOUND_TYPE_MAIN; - - ffStrbufInitA(&instance->config.batteryDir, 0); - - ffStrbufInitA(&instance->config.separatorString, 0); - - instance->config.localIpShowType = FF_LOCALIP_TYPE_IPV4_BIT; - ffStrbufInit(&instance->config.localIpNamePrefix); - - instance->config.publicIpTimeout = 0; - ffStrbufInit(&instance->config.publicIpUrl); - - instance->config.weatherTimeout = 0; - ffStrbufInitS(&instance->config.weatherOutputFormat, "%t+-+%C+(%l)"); - - ffStrbufInitA(&instance->config.osFile, 0); - - ffStrbufInitA(&instance->config.playerName, 0); - instance->config.percentType = 1; - - ffStrbufInitS(&instance->config.commandShell, - #ifdef _WIN32 - "cmd" - #elif defined(__FreeBSD__) - "csh" - #else - "bash" - #endif - ); - ffListInit(&instance->config.commandKeys, sizeof(FFstrbuf)); - ffListInit(&instance->config.commandTexts, sizeof(FFstrbuf)); } void ffInitInstance(FFinstance* instance) @@ -316,69 +245,63 @@ void ffFinish(FFinstance* instance) resetConsole(); } -static void destroyModuleArg(FFModuleArgs* args) -{ - ffStrbufDestroy(&args->key); - ffStrbufDestroy(&args->outputFormat); - ffStrbufDestroy(&args->errorFormat); -} - static void destroyConfig(FFinstance* instance) { - ffStrbufDestroy(&instance->config.logo.source); - ffStrbufDestroy(&instance->config.logo.chafaSymbols); - for(uint8_t i = 0; i < (uint8_t) FASTFETCH_LOGO_MAX_COLORS; ++i) - ffStrbufDestroy(&instance->config.logo.colors[i]); + ffDestroyLogoOptions(&instance->config.logo); + ffStrbufDestroy(&instance->config.colorKeys); ffStrbufDestroy(&instance->config.colorTitle); - ffStrbufDestroy(&instance->config.separator); + ffStrbufDestroy(&instance->config.keyValueSeparator); - destroyModuleArg(&instance->config.os); - destroyModuleArg(&instance->config.host); - destroyModuleArg(&instance->config.bios); - destroyModuleArg(&instance->config.board); - destroyModuleArg(&instance->config.chassis); - destroyModuleArg(&instance->config.kernel); - destroyModuleArg(&instance->config.uptime); - destroyModuleArg(&instance->config.processes); - destroyModuleArg(&instance->config.packages); - destroyModuleArg(&instance->config.shell); - destroyModuleArg(&instance->config.display); - destroyModuleArg(&instance->config.de); - destroyModuleArg(&instance->config.wm); - destroyModuleArg(&instance->config.wmTheme); - destroyModuleArg(&instance->config.theme); - destroyModuleArg(&instance->config.icons); - destroyModuleArg(&instance->config.font); - destroyModuleArg(&instance->config.cursor); - destroyModuleArg(&instance->config.terminal); - destroyModuleArg(&instance->config.terminalFont); - destroyModuleArg(&instance->config.cpu); - destroyModuleArg(&instance->config.cpuUsage); - destroyModuleArg(&instance->config.gpu); - destroyModuleArg(&instance->config.memory); - destroyModuleArg(&instance->config.swap); - destroyModuleArg(&instance->config.disk); - destroyModuleArg(&instance->config.battery); - destroyModuleArg(&instance->config.powerAdapter); - destroyModuleArg(&instance->config.locale); - destroyModuleArg(&instance->config.localIP); - destroyModuleArg(&instance->config.publicIP); - destroyModuleArg(&instance->config.wallpaper); - destroyModuleArg(&instance->config.weather); - destroyModuleArg(&instance->config.wifi); - destroyModuleArg(&instance->config.player); - destroyModuleArg(&instance->config.media); - destroyModuleArg(&instance->config.dateTime); - destroyModuleArg(&instance->config.date); - destroyModuleArg(&instance->config.time); - destroyModuleArg(&instance->config.vulkan); - destroyModuleArg(&instance->config.openGL); - destroyModuleArg(&instance->config.openCL); - destroyModuleArg(&instance->config.users); - destroyModuleArg(&instance->config.bluetooth); - destroyModuleArg(&instance->config.sound); - destroyModuleArg(&instance->config.gamepad); + ffDestroyTitleOptions(&instance->config.title); + ffDestroyOSOptions(&instance->config.os); + ffDestroyHostOptions(&instance->config.host); + ffDestroyBiosOptions(&instance->config.bios); + ffDestroyBoardOptions(&instance->config.board); + ffDestroyBrightnessOptions(&instance->config.brightness); + ffDestroyChassisOptions(&instance->config.chassis); + ffDestroyCommandOptions(&instance->config.command); + ffDestroyCustomOptions(&instance->config.custom); + ffDestroyKernelOptions(&instance->config.kernel); + ffDestroyUptimeOptions(&instance->config.uptime); + ffDestroyProcessesOptions(&instance->config.processes); + ffDestroyPackagesOptions(&instance->config.packages); + ffDestroyShellOptions(&instance->config.shell); + ffDestroyDisplayOptions(&instance->config.display); + ffDestroyDEOptions(&instance->config.de); + ffDestroyWMOptions(&instance->config.wm); + ffDestroyWMThemeOptions(&instance->config.wmTheme); + ffDestroyThemeOptions(&instance->config.theme); + ffDestroyIconsOptions(&instance->config.icons); + ffDestroyFontOptions(&instance->config.font); + ffDestroyCursorOptions(&instance->config.cursor); + ffDestroyTerminalOptions(&instance->config.terminal); + ffDestroyTerminalFontOptions(&instance->config.terminalFont); + ffDestroyCPUOptions(&instance->config.cpu); + ffDestroyCPUUsageOptions(&instance->config.cpuUsage); + ffDestroyGPUOptions(&instance->config.gpu); + ffDestroyMemoryOptions(&instance->config.memory); + ffDestroySwapOptions(&instance->config.swap); + ffDestroyDiskOptions(&instance->config.disk); + ffDestroyBatteryOptions(&instance->config.battery); + ffDestroyPowerAdapterOptions(&instance->config.powerAdapter); + ffDestroyLocaleOptions(&instance->config.locale); + ffDestroyLocalIpOptions(&instance->config.localIP); + ffDestroyPublicIpOptions(&instance->config.publicIP); + ffDestroyWallpaperOptions(&instance->config.wallpaper); + ffDestroyWeatherOptions(&instance->config.weather); + ffDestroyWifiOptions(&instance->config.wifi); + ffDestroyPlayerOptions(&instance->config.player); + ffDestroyMediaOptions(&instance->config.media); + ffDestroyDateTimeOptions(&instance->config.dateTime); + ffDestroyVulkanOptions(&instance->config.vulkan); + ffDestroyOpenGLOptions(&instance->config.openGL); + ffDestroyOpenCLOptions(&instance->config.openCL); + ffDestroyUsersOptions(&instance->config.users); + ffDestroyBluetoothOptions(&instance->config.bluetooth); + ffDestroySeparatorOptions(&instance->config.separator); + ffDestroySoundOptions(&instance->config.sound); + ffDestroyGamepadOptions(&instance->config.gamepad); ffStrbufDestroy(&instance->config.libPCI); ffStrbufDestroy(&instance->config.libVulkan); @@ -400,28 +323,11 @@ static void destroyConfig(FFinstance* instance) ffStrbufDestroy(&instance->config.libGLX); ffStrbufDestroy(&instance->config.libOSMesa); ffStrbufDestroy(&instance->config.libOpenCL); - ffStrbufDestroy(&instance->config.libcJSON); + ffStrbufDestroy(&instance->config.libJSONC); ffStrbufDestroy(&instance->config.libfreetype); ffStrbufDestroy(&instance->config.libPulse); ffStrbufDestroy(&instance->config.libwlanapi); ffStrbufDestroy(&instance->config.libnm); - - ffStrbufDestroy(&instance->config.diskFolders); - ffStrbufDestroy(&instance->config.batteryDir); - ffStrbufDestroy(&instance->config.separatorString); - ffStrbufDestroy(&instance->config.localIpNamePrefix); - ffStrbufDestroy(&instance->config.publicIpUrl); - ffStrbufDestroy(&instance->config.weatherOutputFormat); - ffStrbufDestroy(&instance->config.osFile); - ffStrbufDestroy(&instance->config.playerName); - - ffStrbufDestroy(&instance->config.commandShell); - FF_LIST_FOR_EACH(FFstrbuf, item, instance->config.commandKeys) - ffStrbufDestroy(item); - ffListDestroy(&instance->config.commandKeys); - FF_LIST_FOR_EACH(FFstrbuf, item, instance->config.commandTexts) - ffStrbufDestroy(item); - ffListDestroy(&instance->config.commandTexts); } static void destroyState(FFinstance* instance) @@ -505,8 +411,8 @@ void ffListFeatures() #ifdef FF_HAVE_OPENCL "opencl\n" #endif - #ifdef FF_HAVE_LIBCJSON - "libcjson\n" + #ifdef FF_HAVE_LIBJSONC + "json-c\n" #endif #ifdef FF_HAVE_FREETYPE "freetype\n" diff --git a/src/common/io/io_unix.c b/src/common/io/io_unix.c index 420e4374e..8d506b05e 100644 --- a/src/common/io/io_unix.c +++ b/src/common/io/io_unix.c @@ -8,8 +8,7 @@ static void createSubfolders(const char* fileName) { - FFstrbuf path; - ffStrbufInit(&path); + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate(); while(*fileName != '\0') { @@ -18,8 +17,6 @@ static void createSubfolders(const char* fileName) mkdir(path.chars, S_IRWXU | S_IRGRP | S_IROTH); ++fileName; } - - ffStrbufDestroy(&path); } bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data) @@ -218,9 +215,7 @@ void listFilesRecursively(FFstrbuf* folder, uint8_t indentation, const char* fol void ffListFilesRecursively(const char* path) { - FFstrbuf folder; - ffStrbufInitS(&folder, path); + FF_STRBUF_AUTO_DESTROY folder = ffStrbufCreateS(path); ffStrbufEnsureEndsWithC(&folder, '/'); listFilesRecursively(&folder, 0, NULL); - ffStrbufDestroy(&folder); } diff --git a/src/common/io/io_windows.c b/src/common/io/io_windows.c index 78cdad740..9a25a159a 100644 --- a/src/common/io/io_windows.c +++ b/src/common/io/io_windows.c @@ -2,9 +2,7 @@ static void createSubfolders(const char* fileName) { - FF_STRBUF_AUTO_DESTROY path; - ffStrbufInit(&path); - + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate(); while(*fileName != '\0') { ffStrbufAppendC(&path, *fileName); @@ -141,9 +139,7 @@ void listFilesRecursively(FFstrbuf* folder, uint8_t indentation, const char* fol void ffListFilesRecursively(const char* path) { - FFstrbuf folder; - ffStrbufInitS(&folder, path); + FF_STRBUF_AUTO_DESTROY folder = ffStrbufCreateS(path); ffStrbufEnsureEndsWithC(&folder, '/'); listFilesRecursively(&folder, 0, NULL); - ffStrbufDestroy(&folder); } diff --git a/src/common/json.c b/src/common/json.c new file mode 100644 index 000000000..8ca285d5b --- /dev/null +++ b/src/common/json.c @@ -0,0 +1,57 @@ +#include "common/json.h" + +#ifdef FF_HAVE_JSONC + +#include "common/thread.h" + +static const FFJsonLibrary* loadLibSymbols(const FFinstance* instance) +{ + assert(instance); + + static FFJsonLibrary lib; + FF_LIBRARY_LOAD(libjsonc, &instance->config.libJSONC, NULL, + #ifdef _WIN32 + "libjson-c-5" FF_LIBRARY_EXTENSION, -1 + #else + "libjson-c" FF_LIBRARY_EXTENSION, 5 + #endif + ) + FF_LIBRARY_LOAD_SYMBOL_VAR(libjsonc, lib, json_tokener_parse, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libjsonc, lib, json_object_is_type, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libjsonc, lib, json_object_get_array, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libjsonc, lib, json_object_get_boolean, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libjsonc, lib, json_object_get_double, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libjsonc, lib, json_object_get_int, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libjsonc, lib, json_object_get_string_len, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libjsonc, lib, json_object_get_string, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libjsonc, lib, json_object_get_object, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libjsonc, lib, json_object_object_del, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libjsonc, lib, json_object_object_get, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libjsonc, lib, json_object_object_length, NULL) + FF_LIBRARY_LOAD_SYMBOL_VAR(libjsonc, lib, json_object_put, NULL) + libjsonc = NULL; // don't dlclose automatically + return &lib; +} + +const FFJsonLibrary* ffJsonLib = NULL; +bool ffJsonLoadLibrary(const FFinstance* instance) +{ + static bool loaded = false; + static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; + + if (!loaded) + { + ffThreadMutexLock(&mutex); + + if(!loaded) + { + loaded = true; + ffJsonLib = loadLibSymbols(instance); + } + + ffThreadMutexUnlock(&mutex); + } + return !!ffJsonLib; +} + +#endif diff --git a/src/common/json.h b/src/common/json.h new file mode 100644 index 000000000..cf4ffe14f --- /dev/null +++ b/src/common/json.h @@ -0,0 +1,130 @@ +#pragma once + +#ifdef FF_HAVE_JSONC + +#include "fastfetch.h" +#include "common/library.h" + +#include +#include + +typedef struct FFJsonLibrary +{ + FF_LIBRARY_SYMBOL(json_tokener_parse) + FF_LIBRARY_SYMBOL(json_object_is_type) + FF_LIBRARY_SYMBOL(json_object_get_array) + FF_LIBRARY_SYMBOL(json_object_get_boolean) + FF_LIBRARY_SYMBOL(json_object_get_double) + FF_LIBRARY_SYMBOL(json_object_get_int) + FF_LIBRARY_SYMBOL(json_object_get_string_len) + FF_LIBRARY_SYMBOL(json_object_get_string) + FF_LIBRARY_SYMBOL(json_object_get_object) + FF_LIBRARY_SYMBOL(json_object_object_del) + FF_LIBRARY_SYMBOL(json_object_object_get) + FF_LIBRARY_SYMBOL(json_object_object_length) + FF_LIBRARY_SYMBOL(json_object_put) +} FFJsonLibrary; + +extern const FFJsonLibrary* ffJsonLib; + +bool ffJsonLoadLibrary(const FFinstance* instance); + +static inline void wrapJsoncFree(json_object** root) +{ + assert(root); + if (*root) + json_object_put(*root); +} + +extern inline __attribute__((__gnu_inline__, __always_inline__)) +struct json_object *json_tokener_parse(const char *str) +{ + assert(ffJsonLib); + return ffJsonLib->ffjson_tokener_parse(str); +} + +extern inline __attribute__((__gnu_inline__, __always_inline__)) +int json_object_is_type(const json_object *obj, enum json_type type) +{ + assert(ffJsonLib); + return ffJsonLib->ffjson_object_is_type(obj, type); +} + +extern inline __attribute__((__gnu_inline__, __always_inline__)) +struct array_list *json_object_get_array(const json_object *obj) +{ + assert(ffJsonLib); + return ffJsonLib->ffjson_object_get_array(obj); +} + +extern inline __attribute__((__gnu_inline__, __always_inline__)) +json_bool json_object_get_boolean(const json_object *obj) +{ + assert(ffJsonLib); + return ffJsonLib->ffjson_object_get_boolean(obj); +} + +extern inline __attribute__((__gnu_inline__, __always_inline__)) +double json_object_get_double(const json_object *obj) +{ + assert(ffJsonLib); + return ffJsonLib->ffjson_object_get_double(obj); +} + +extern inline __attribute__((__gnu_inline__, __always_inline__)) +int32_t json_object_get_int(const json_object *obj) +{ + assert(ffJsonLib); + return ffJsonLib->ffjson_object_get_int(obj); +} + +extern inline __attribute__((__gnu_inline__, __always_inline__)) +int json_object_get_string_len(const json_object *obj) +{ + assert(ffJsonLib); + return ffJsonLib->ffjson_object_get_string_len(obj); +} + +extern inline __attribute__((__gnu_inline__, __always_inline__)) +const char *json_object_get_string(json_object *obj) +{ + assert(ffJsonLib); + return ffJsonLib->ffjson_object_get_string(obj); +} + +extern inline __attribute__((__gnu_inline__, __always_inline__)) +struct lh_table *json_object_get_object(const json_object *obj) +{ + assert(ffJsonLib); + return ffJsonLib->ffjson_object_get_object(obj); +} + +extern inline __attribute__((__gnu_inline__, __always_inline__)) +void json_object_object_del(struct json_object *obj, const char *key) +{ + assert(ffJsonLib); + return ffJsonLib->ffjson_object_object_del(obj, key); +} + +extern inline __attribute__((__gnu_inline__, __always_inline__)) +struct json_object *json_object_object_get(const json_object *obj, const char *key) +{ + assert(ffJsonLib); + return ffJsonLib->ffjson_object_object_get(obj, key); +} + +extern inline __attribute__((__gnu_inline__, __always_inline__)) +int json_object_object_length(const json_object *obj) +{ + assert(ffJsonLib); + return ffJsonLib->ffjson_object_object_length(obj); +} + +extern inline __attribute__((__gnu_inline__, __always_inline__)) +int json_object_put(json_object *obj) +{ + assert(ffJsonLib); + return ffJsonLib->ffjson_object_put(obj); +} + +#endif diff --git a/src/common/jsonconfig.c b/src/common/jsonconfig.c new file mode 100644 index 000000000..151e058e5 --- /dev/null +++ b/src/common/jsonconfig.c @@ -0,0 +1,61 @@ +#include "fastfetch.h" +#include "common/jsonconfig.h" + +#ifdef FF_HAVE_JSONC + +bool ffJsonConfigParseModuleArgs(const char* key, json_object* val, FFModuleArgs* moduleArgs) +{ + if(strcasecmp(key, "key") == 0) + { + ffStrbufSetNS(&moduleArgs->key, (uint32_t) json_object_get_string_len(val), json_object_get_string(val)); + return true; + } + else if(strcasecmp(key, "format") == 0) + { + ffStrbufSetNS(&moduleArgs->outputFormat, (uint32_t) json_object_get_string_len(val), json_object_get_string(val)); + return true; + } + else if(strcasecmp(key, "error") == 0) + { + ffStrbufSetNS(&moduleArgs->errorFormat, (uint32_t) json_object_get_string_len(val), json_object_get_string(val)); + return true; + } + return false; +} + +const char* ffJsonConfigParseEnum(json_object* val, int* result, FFKeyValuePair pairs[]) +{ + if (json_object_is_type(val, json_type_int)) + { + int intVal = json_object_get_int(val); + + for (const FFKeyValuePair* pPair = pairs; pPair->key; ++pPair) + { + if (intVal == pPair->value) + { + *result = pPair->value; + return NULL; + } + } + + return "Invalid enum integer"; + } + else if (json_object_is_type(val, json_type_string)) + { + const char* strVal = json_object_get_string(val); + for (const FFKeyValuePair* pPair = pairs; pPair->key; ++pPair) + { + if (strcasecmp(strVal, pPair->key) == 0) + { + *result = pPair->value; + return NULL; + } + } + + return "Invalid enum string"; + } + else + return "Invalid enum value type; must be a string or integer"; +} + +#endif diff --git a/src/common/jsonconfig.h b/src/common/jsonconfig.h new file mode 100644 index 000000000..76a72c304 --- /dev/null +++ b/src/common/jsonconfig.h @@ -0,0 +1,10 @@ +#pragma once + +#ifdef FF_HAVE_JSONC + +#include "common/json.h" + +bool ffJsonConfigParseModuleArgs(const char* key, json_object* val, FFModuleArgs* moduleArgs); +const char* ffJsonConfigParseEnum(json_object* val, int* result, FFKeyValuePair pairs[]); + +#endif diff --git a/src/common/library.c b/src/common/library.c index e771b8d4d..7f858e966 100644 --- a/src/common/library.c +++ b/src/common/library.c @@ -32,8 +32,7 @@ static void* libraryLoad(const char* path, int maxVersion) if(result != NULL || maxVersion < 0) return result; - FFstrbuf pathbuf; - ffStrbufInitA(&pathbuf, 64); + FF_STRBUF_AUTO_DESTROY pathbuf = ffStrbufCreateA(64); ffStrbufAppendS(&pathbuf, path); ffStrbufAppendC(&pathbuf, '.'); @@ -49,8 +48,6 @@ static void* libraryLoad(const char* path, int maxVersion) ffStrbufSubstrBefore(&pathbuf, originalLength); } - ffStrbufDestroy(&pathbuf); - #endif return result; diff --git a/src/common/library.h b/src/common/library.h index a0de3d621..3f4a8f237 100644 --- a/src/common/library.h +++ b/src/common/library.h @@ -62,16 +62,16 @@ static inline void ffLibraryUnload(void** handle) __typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, ff ## symbolName, symbolName, alternateName, "dlsym " #symbolName " failed"); #define FF_LIBRARY_LOAD_SYMBOL_VAR(library, varName, symbolName, returnValue) \ - FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, varName.ff ## symbolName, symbolName, returnValue); + FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff ## symbolName, symbolName, returnValue); #define FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(library, varName, symbolName) \ - FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, varName.ff ## symbolName, symbolName, "dlsym " #symbolName " failed"); + FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff ## symbolName, symbolName, "dlsym " #symbolName " failed"); #define FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(library, varName, symbolName, alternateName) \ - FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, varName.ff ## symbolName, symbolName, alternateName, "dlsym " #symbolName " failed"); + FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, (varName).ff ## symbolName, symbolName, alternateName, "dlsym " #symbolName " failed"); #define FF_LIBRARY_LOAD_SYMBOL_PTR(library, varName, symbolName, returnValue) \ - FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, varName->ff ## symbolName, symbolName, returnValue); + FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName)->ff ## symbolName, symbolName, returnValue); void* ffLibraryLoad(const FFstrbuf* userProvidedName, ...); diff --git a/src/common/networking_windows.c b/src/common/networking_windows.c index 5814acc16..4cb0e1d1a 100644 --- a/src/common/networking_windows.c +++ b/src/common/networking_windows.c @@ -75,8 +75,7 @@ bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, con } } - FF_STRBUF_AUTO_DESTROY command; - ffStrbufInitA(&command, 64); + FF_STRBUF_AUTO_DESTROY command = ffStrbufCreateA(64); ffStrbufAppendS(&command, "GET "); ffStrbufAppendS(&command, path); ffStrbufAppendS(&command, " HTTP/1.1\nHost: "); diff --git a/src/common/option.c b/src/common/option.c new file mode 100644 index 000000000..e151788be --- /dev/null +++ b/src/common/option.c @@ -0,0 +1,154 @@ +#include "common/option.h" +#include "util/stringUtils.h" + +// 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) +{ + 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; +} + +bool ffOptionParseModuleArgs(const char* argumentKey, const char* subKey, const char* value, FFModuleArgs* result) +{ + if(strcasecmp(subKey, "key") == 0) + { + ffOptionParseString(argumentKey, value, &result->key); + return true; + } + else if(strcasecmp(subKey, "format") == 0) + { + ffOptionParseString(argumentKey, value, &result->outputFormat); + return true; + } + else if(strcasecmp(subKey, "error") == 0) + { + ffOptionParseString(argumentKey, value, &result->errorFormat); + return true; + } + return false; +} + +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; + uint32_t num = (uint32_t) strtoul(value, &end, 10); + if(*end != '\0') + { + fprintf(stderr, "Error: usage: %s \n", argumentKey); + exit(479); + } + + return 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(strcasecmp(requestedKey, pPair->key) == 0) + return pPair->value; + } + + fprintf(stderr, "Error: unknown %s value: %s\n", argumentKey, requestedKey); + exit(478); +} + +bool ffOptionParseBoolean(const char* str) +{ + return ( + !ffStrSet(str) || + strcasecmp(str, "true") == 0 || + strcasecmp(str, "yes") == 0 || + strcasecmp(str, "on") == 0 || + strcasecmp(str, "1") == 0 + ); +} + +void ffOptionParseColor(const char* key, const char* value, FFstrbuf* buffer) +{ + if(value == NULL) + { + fprintf(stderr, "Error: usage: %s \n", key); + exit(477); + } + ffStrbufEnsureFree(buffer, 63); + + while(*value != '\0') + { + #define FF_APPEND_COLOR_CODE_COND(prefix, code) \ + if(strncasecmp(value, #prefix, strlen(#prefix))) { ffStrbufAppendS(buffer, code); value += strlen(#prefix); } + + FF_APPEND_COLOR_CODE_COND(reset_, "0;") + else FF_APPEND_COLOR_CODE_COND(bright_, "1;") + else FF_APPEND_COLOR_CODE_COND(black, "30") + else FF_APPEND_COLOR_CODE_COND(red, "31") + else FF_APPEND_COLOR_CODE_COND(green, "32") + else FF_APPEND_COLOR_CODE_COND(yellow, "33") + else FF_APPEND_COLOR_CODE_COND(blue, "34") + else FF_APPEND_COLOR_CODE_COND(magenta, "35") + else FF_APPEND_COLOR_CODE_COND(cyan, "36") + else FF_APPEND_COLOR_CODE_COND(white, "37") + else + { + ffStrbufAppendC(buffer, *value); + ++value; + } + + #undef FF_APPEND_COLOR_CODE_COND + } +} + +void ffOptionInitModuleArg(FFModuleArgs* args) +{ + ffStrbufInit(&args->key); + ffStrbufInit(&args->outputFormat); + ffStrbufInit(&args->errorFormat); +} + +void ffOptionDestroyModuleArg(FFModuleArgs* args) +{ + ffStrbufDestroy(&args->key); + ffStrbufDestroy(&args->outputFormat); + ffStrbufDestroy(&args->errorFormat); +} diff --git a/src/common/option.h b/src/common/option.h new file mode 100644 index 000000000..0c8d29b1b --- /dev/null +++ b/src/common/option.h @@ -0,0 +1,26 @@ +#pragma once + +#include "util/FFstrbuf.h" + +typedef struct FFModuleArgs +{ + FFstrbuf key; + FFstrbuf outputFormat; + FFstrbuf errorFormat; +} FFModuleArgs; + +typedef struct FFKeyValuePair +{ + const char* key; + int value; +} FFKeyValuePair; + +const char* ffOptionTestPrefix(const char* argumentKey, const char* moduleName); +bool ffOptionParseModuleArgs(const char* argumentKey, const char* pkey, const char* value, FFModuleArgs* result); +void ffOptionParseString(const char* argumentKey, const char* value, FFstrbuf* buffer); +FF_C_NODISCARD uint32_t ffOptionParseUInt32(const char* argumentKey, const char* value); +FF_C_NODISCARD int ffOptionParseEnum(const char* argumentKey, const char* requestedKey, FFKeyValuePair pairs[]); +FF_C_NODISCARD bool ffOptionParseBoolean(const char* str); +void ffOptionParseColor(const char* key, const char* value, FFstrbuf* buffer); +void ffOptionInitModuleArg(FFModuleArgs* args); +void ffOptionDestroyModuleArg(FFModuleArgs* args); diff --git a/src/common/printing.c b/src/common/printing.c index f33d5cf33..7ea0ecb03 100644 --- a/src/common/printing.c +++ b/src/common/printing.c @@ -26,19 +26,17 @@ void ffPrintLogoAndKey(FFinstance* instance, const char* moduleName, uint8_t mod } else { - FFstrbuf key; - ffStrbufInit(&key); + FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate(); ffParseFormatString(&key, customKeyFormat, 1, (FFformatarg[]){ {FF_FORMAT_ARG_TYPE_UINT8, &moduleIndex} }); ffPrintUserString(key.chars); - ffStrbufDestroy(&key); } if(!instance->config.pipe) fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout); - ffStrbufWriteTo(&instance->config.separator, stdout); + ffStrbufWriteTo(&instance->config.keyValueSeparator, stdout); if(!instance->config.pipe) fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout); @@ -46,9 +44,7 @@ void ffPrintLogoAndKey(FFinstance* instance, const char* moduleName, uint8_t mod void ffPrintFormatString(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* format, uint32_t numArgs, const FFformatarg* arguments) { - FFstrbuf buffer; - ffStrbufInitA(&buffer, 256); - + FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreateA(256); ffParseFormatString(&buffer, format, numArgs, arguments); if(buffer.length > 0) @@ -57,8 +53,6 @@ void ffPrintFormatString(FFinstance* instance, const char* moduleName, uint8_t m ffPrintUserString(buffer.chars); putchar('\n'); } - - ffStrbufDestroy(&buffer); } void ffPrintFormat(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, uint32_t numArgs, const FFformatarg* arguments) @@ -74,15 +68,10 @@ static void printError(FFinstance* instance, const char* moduleName, uint8_t mod if(hasCustomErrorFormat) { - FFstrbuf error; - ffStrbufInit(&error); - ffStrbufAppendVF(&error, message, arguments); - + FF_STRBUF_AUTO_DESTROY error = ffStrbufCreateVF(message, arguments); ffPrintFormatString(instance, moduleName, moduleIndex, customKeyFormat, customErrorFormat, 1, (FFformatarg[]) { {FF_FORMAT_ARG_TYPE_STRBUF, &error} }); - - ffStrbufDestroy(&error); } else { diff --git a/src/common/processing_windows.c b/src/common/processing_windows.c index a2db719c1..580a29146 100644 --- a/src/common/processing_windows.c +++ b/src/common/processing_windows.c @@ -28,8 +28,7 @@ const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]) BOOL success; { - FF_STRBUF_AUTO_DESTROY cmdline; - ffStrbufInitF(&cmdline, "\"%s\"", argv[0]); + FF_STRBUF_AUTO_DESTROY cmdline = ffStrbufCreateF("\"%s\"", argv[0]); for(char* const* parg = &argv[1]; *parg; ++parg) { ffStrbufAppendC(&cmdline, ' '); diff --git a/src/common/properties.c b/src/common/properties.c index 48b797599..6543d14a4 100644 --- a/src/common/properties.c +++ b/src/common/properties.c @@ -146,25 +146,15 @@ done: bool ffParsePropFileHomeValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries) { - FFstrbuf absolutePath; - ffStrbufInitA(&absolutePath, 64); - ffStrbufAppend(&absolutePath, &instance->state.platform.homeDir); - ffStrbufAppendC(&absolutePath, '/'); - ffStrbufAppendS(&absolutePath, relativeFile); - - bool result = ffParsePropFileValues(absolutePath.chars, numQueries, queries); - - ffStrbufDestroy(&absolutePath); - - return result; + FF_STRBUF_AUTO_DESTROY absolutePath = ffStrbufCreateF("%s/%s", instance->state.platform.homeDir.chars, relativeFile); + return ffParsePropFileValues(absolutePath.chars, numQueries, queries); } bool ffParsePropFileListValues(const FFlist* list, const char* relativeFile, uint32_t numQueries, FFpropquery* queries) { bool foundAFile = false; - FFstrbuf baseDir; - ffStrbufInitA(&baseDir, 64); + FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(64); FF_LIST_FOR_EACH(FFstrbuf, dirPrefix, *list) { @@ -189,7 +179,5 @@ bool ffParsePropFileListValues(const FFlist* list, const char* relativeFile, uin break; } - ffStrbufDestroy(&baseDir); - return foundAFile; } diff --git a/src/data/config_user.txt b/src/data/config_user.txt index 0ade6d30b..a0b91d92f 100644 --- a/src/data/config_user.txt +++ b/src/data/config_user.txt @@ -456,6 +456,6 @@ #--lib-glx /usr/lib/libGLX.so #--lib-osmesa /usr/lib/libOSMesa.so #--lib-opencl /usr/lib/libOpenCL.so -#--lib-cjson /usr/lib/libcjson.so +#--lib-jsonc /usr/lib/libjson-c.so #--lib-freetype /data/data/com.termux/files/usr/lib #--lib-pulse /usr/lib/libpulse.so diff --git a/src/data/help.txt b/src/data/help.txt index 83428e0da..30fedcdfd 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -97,7 +97,7 @@ Library options: Set the path of a library to load --lib-glx --lib-osmesa --lib-opencl - --lib-cjson + --lib-jsonc --lib-pulse --lib-freetype diff --git a/src/detection/battery/battery_android.c b/src/detection/battery/battery_android.c index 1a783e595..0b90494fc 100644 --- a/src/detection/battery/battery_android.c +++ b/src/detection/battery/battery_android.c @@ -7,10 +7,9 @@ #define FF_TERMUX_API_PATH FASTFETCH_TARGET_DIR_ROOT "/libexec/termux-api" #define FF_TERMUX_API_PARAM "BatteryStatus" -const char* ffDetectBatteryImpl(FF_MAYBE_UNUSED FFinstance* instance, FFlist* results) +const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) { - FF_STRBUF_AUTO_DESTROY buffer; - ffStrbufInit(&buffer); + FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); if(ffProcessAppendStdOut(&buffer, (char* const[]){ FF_TERMUX_API_PATH, @@ -35,7 +34,7 @@ const char* ffDetectBatteryImpl(FF_MAYBE_UNUSED FFinstance* instance, FFlist* re ffStrbufClear(&battery->status); } - if(instance->config.batteryTemp) + if(instance->config.battery.temp) { if(ffParsePropLines(buffer.chars, "\"temperature\": ", &battery->status)) { diff --git a/src/detection/battery/battery_apple.c b/src/detection/battery/battery_apple.c index 7244a89a1..af49b9a69 100644 --- a/src/detection/battery/battery_apple.c +++ b/src/detection/battery/battery_apple.c @@ -7,8 +7,7 @@ static double detectBatteryTemp() { - FF_LIST_AUTO_DESTROY temps; - ffListInit(&temps, sizeof(FFTempValue)); + FF_LIST_AUTO_DESTROY temps = ffListCreate(sizeof(FFTempValue)); ffDetectCoreTemps(FF_TEMP_BATTERY, &temps); @@ -30,8 +29,6 @@ static double detectBatteryTemp() const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) { - FF_UNUSED(instance); - CFMutableDictionaryRef matchDict = IOServiceMatching("AppleSmartBattery"); if (matchDict == NULL) return "IOServiceMatching(\"AppleSmartBattery\") failed"; @@ -93,7 +90,7 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) else ffStrbufAppendS(&battery->status, ""); - if(instance->config.batteryTemp) + if(instance->config.battery.temp) battery->temperature = detectBatteryTemp(); else battery->temperature = FF_BATTERY_TEMP_UNSET; diff --git a/src/detection/battery/battery_linux.c b/src/detection/battery/battery_linux.c index b78a6cf7f..11da6f4e9 100644 --- a/src/detection/battery/battery_linux.c +++ b/src/detection/battery/battery_linux.c @@ -8,8 +8,7 @@ static void parseBattery(FFstrbuf* dir, FFlist* results) { uint32_t dirLength = dir->length; - FFstrbuf testBatteryBuffer; - ffStrbufInit(&testBatteryBuffer); + FF_STRBUF_AUTO_DESTROY testBatteryBuffer = ffStrbufCreate(); //type must exist and be "Battery" ffStrbufAppendS(dir, "/type"); @@ -17,10 +16,7 @@ static void parseBattery(FFstrbuf* dir, FFlist* results) ffStrbufSubstrBefore(dir, dirLength); if(ffStrbufIgnCaseCompS(&testBatteryBuffer, "Battery") != 0) - { - ffStrbufDestroy(&testBatteryBuffer); return; - } //scope may not exist or must not be "Device" ffStrbufAppendS(dir, "/scope"); @@ -28,10 +24,7 @@ static void parseBattery(FFstrbuf* dir, FFlist* results) ffStrbufSubstrBefore(dir, dirLength); if(ffStrbufIgnCaseCompS(&testBatteryBuffer, "Device") == 0) - { - ffStrbufDestroy(&testBatteryBuffer); return; - } BatteryResult* result = ffListAdd(results); @@ -41,7 +34,7 @@ static void parseBattery(FFstrbuf* dir, FFlist* results) ffStrbufSubstrBefore(dir, dirLength); if(available) result->capacity = ffStrbufToDouble(&testBatteryBuffer); - ffStrbufDestroy(&testBatteryBuffer); + if(!available) { result->capacity = 0.0/0.0; @@ -74,12 +67,13 @@ static void parseBattery(FFstrbuf* dir, FFlist* results) result->temperature = FF_BATTERY_TEMP_UNSET; } -const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) { - FFstrbuf baseDir; - ffStrbufInitA(&baseDir, 64); - if(instance->config.batteryDir.length > 0) +const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) +{ + FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(64); + + if(instance->config.battery.dir.length > 0) { - ffStrbufAppend(&baseDir, &instance->config.batteryDir); + ffStrbufAppend(&baseDir, &instance->config.battery.dir); ffStrbufEnsureEndsWithC(&baseDir, '/'); } else @@ -91,10 +85,7 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) { DIR* dirp = opendir(baseDir.chars); if(dirp == NULL) - { - ffStrbufDestroy(&baseDir); return "opendir(batteryDir) == NULL"; - } struct dirent* entry; while((entry = readdir(dirp)) != NULL) @@ -109,11 +100,8 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) { closedir(dirp); - if(results->length == 0) { - ffStrbufDestroy(&baseDir); + if(results->length == 0) return "batteryDir doesn't contain any battery folder"; - } - ffStrbufDestroy(&baseDir); return NULL; } diff --git a/src/detection/battery/battery_windows.c b/src/detection/battery/battery_windows.c index fc89a335a..9268362fd 100644 --- a/src/detection/battery/battery_windows.c +++ b/src/detection/battery/battery_windows.c @@ -111,7 +111,7 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) } battery->temperature = 0.0/0.0; - if(instance->config.batteryTemp) + if(instance->config.battery.temp) { bqi.InformationLevel = BatteryTemperature; ULONG temp; diff --git a/src/detection/brightness/brightness_linux.c b/src/detection/brightness/brightness_linux.c index 3222faeae..9c00f70e9 100644 --- a/src/detection/brightness/brightness_linux.c +++ b/src/detection/brightness/brightness_linux.c @@ -13,14 +13,12 @@ const char* ffDetectBrightness(FF_MAYBE_UNUSED FFlist* result) if(dirp == NULL) return "Failed to open `/sys/class/backlight/`"; - FF_STRBUF_AUTO_DESTROY backlightDir; - ffStrbufInitA(&backlightDir, 64); + FF_STRBUF_AUTO_DESTROY backlightDir = ffStrbufCreateA(64); ffStrbufAppendS(&backlightDir, backlightDirPath); uint32_t backlightDirLength = backlightDir.length; - FF_STRBUF_AUTO_DESTROY buffer; - ffStrbufInit(&buffer); + FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); struct dirent* entry; while((entry = readdir(dirp)) != NULL) diff --git a/src/detection/cpu/cpu_apple.c b/src/detection/cpu/cpu_apple.c index 3de61f93d..fb53b60d2 100644 --- a/src/detection/cpu/cpu_apple.c +++ b/src/detection/cpu/cpu_apple.c @@ -15,8 +15,7 @@ static double getFrequency(const char* propName) static double detectCpuTemp(const FFstrbuf* cpuName) { - FF_LIST_AUTO_DESTROY temps; - ffListInit(&temps, sizeof(FFTempValue)); + FF_LIST_AUTO_DESTROY temps = ffListCreate(sizeof(FFTempValue)); if(ffStrbufStartsWithS(cpuName, "Apple M1")) ffDetectCoreTemps(FF_TEMP_CPU_M1X, &temps); @@ -65,7 +64,7 @@ void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu) if(cpu->frequencyMax == 0.0) cpu->frequencyMax = getFrequency("hw.cpufrequency"); - if (instance->config.cpuTemp) + if (instance->config.cpu.temp) cpu->temperature = detectCpuTemp(&cpu->name); else cpu->temperature = FF_CPU_TEMP_UNSET; diff --git a/src/detection/cpu/cpu_bsd.c b/src/detection/cpu/cpu_bsd.c index 2308c8985..c3c88e440 100644 --- a/src/detection/cpu/cpu_bsd.c +++ b/src/detection/cpu/cpu_bsd.c @@ -5,10 +5,9 @@ void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu) { FF_UNUSED(instance); - if (instance->config.cpuTemp) + if (instance->config.cpu.temp) { - FFstrbuf cpuTemp; - ffStrbufInit(&cpuTemp); + FF_STRBUF_AUTO_DESTROY cpuTemp = ffStrbufCreate(); if(ffSysctlGetString("temperature", &cpuTemp)) cpu->temperature = FF_CPU_TEMP_UNSET; else diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index 202317033..bc14e2f18 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -41,12 +41,10 @@ static void parseCpuInfo(FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer, FFstrb static double getGHz(const char* file) { - FFstrbuf content; - ffStrbufInit(&content); + FF_STRBUF_AUTO_DESTROY content = ffStrbufCreate(); if(ffAppendFileBuffer(file, &content)) { double herz = ffStrbufToDouble(&content); - ffStrbufDestroy(&content); //ffStrbufToDouble failed if(herz != herz) @@ -106,22 +104,15 @@ static void parseIsa(FFstrbuf* cpuIsa) void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu) { - if(instance->config.cpuTemp) + if(instance->config.cpu.temp) cpu->temperature = detectCPUTemp(); else cpu->temperature = FF_CPU_TEMP_UNSET; - FFstrbuf physicalCoresBuffer; - ffStrbufInit(&physicalCoresBuffer); - - FFstrbuf cpuMHz; - ffStrbufInit(&cpuMHz); - - FFstrbuf cpuIsa; - ffStrbufInit(&cpuIsa); - - FFstrbuf cpuUarch; - ffStrbufInit(&cpuUarch); + FF_STRBUF_AUTO_DESTROY physicalCoresBuffer = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY cpuMHz = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY cpuIsa = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY cpuUarch = ffStrbufCreate(); parseCpuInfo(cpu, &physicalCoresBuffer, &cpuMHz, &cpuIsa, &cpuUarch); @@ -155,9 +146,4 @@ void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu) ffStrbufAppendC(&cpu->name, ' '); ffStrbufAppend(&cpu->name, &cpuIsa); } - - ffStrbufDestroy(&physicalCoresBuffer); - ffStrbufDestroy(&cpuMHz); - ffStrbufDestroy(&cpuIsa); - ffStrbufDestroy(&cpuUarch); } diff --git a/src/detection/cpu/cpu_windows.c b/src/detection/cpu/cpu_windows.c index b38d5bb63..13413bec3 100644 --- a/src/detection/cpu/cpu_windows.c +++ b/src/detection/cpu/cpu_windows.c @@ -51,6 +51,6 @@ void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu) ffRegReadStrbuf(hKey, L"ProcessorNameString", &cpu->name, NULL); ffRegReadStrbuf(hKey, L"VendorIdentifier", &cpu->vendor, NULL); - if(instance->config.cpuTemp) + if(instance->config.cpu.temp) ffDetectSmbiosTemp(&cpu->temperature, NULL); } diff --git a/src/detection/cpuUsage/cpuUsage.h b/src/detection/cpuUsage/cpuUsage.h deleted file mode 100644 index 250b30570..000000000 --- a/src/detection/cpuUsage/cpuUsage.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#ifndef FF_INCLUDED_detection_cpu_cpuUsage -#define FF_INCLUDED_detection_cpu_cpuUsage - -const char* ffGetCpuUsageResult(double* result); - -#endif diff --git a/src/detection/cpuUsage/cpuUsage.c b/src/detection/cpuusage/cpuusage.c similarity index 95% rename from src/detection/cpuUsage/cpuUsage.c rename to src/detection/cpuusage/cpuusage.c index 88355668d..7342bbc55 100644 --- a/src/detection/cpuUsage/cpuUsage.c +++ b/src/detection/cpuusage/cpuusage.c @@ -1,6 +1,5 @@ #include "fastfetch.h" -#include "cpuUsage.h" - +#include "detection/cpuusage/cpuusage.h" #include "common/time.h" #include diff --git a/src/detection/cpuusage/cpuusage.h b/src/detection/cpuusage/cpuusage.h new file mode 100644 index 000000000..fb3c81e8e --- /dev/null +++ b/src/detection/cpuusage/cpuusage.h @@ -0,0 +1,8 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_cpuusage_cpuusage +#define FF_INCLUDED_detection_cpuusage_cpuusage + +const char* ffGetCpuUsageResult(double* result); + +#endif diff --git a/src/detection/cpuUsage/cpuUsage_apple.c b/src/detection/cpuusage/cpuusage_apple.c similarity index 94% rename from src/detection/cpuUsage/cpuUsage_apple.c rename to src/detection/cpuusage/cpuusage_apple.c index d3b533f48..b94615219 100644 --- a/src/detection/cpuUsage/cpuUsage_apple.c +++ b/src/detection/cpuusage/cpuusage_apple.c @@ -1,5 +1,5 @@ #include "fastfetch.h" -#include "cpuUsage.h" +#include "detection/cpuusage/cpuusage.h" #include #include diff --git a/src/detection/cpuUsage/cpuUsage_bsd.c b/src/detection/cpuusage/cpuusage_bsd.c similarity index 93% rename from src/detection/cpuUsage/cpuUsage_bsd.c rename to src/detection/cpuusage/cpuusage_bsd.c index d96064fd4..fa1945aaa 100644 --- a/src/detection/cpuUsage/cpuUsage_bsd.c +++ b/src/detection/cpuusage/cpuusage_bsd.c @@ -1,4 +1,4 @@ -#include "cpuUsage.h" +#include "detection/cpuusage/cpuusage.h" #include #include diff --git a/src/detection/cpuUsage/cpuUsage_linux.c b/src/detection/cpuusage/cpuusage_linux.c similarity index 95% rename from src/detection/cpuUsage/cpuUsage_linux.c rename to src/detection/cpuusage/cpuusage_linux.c index 1888b2b13..78c64215e 100644 --- a/src/detection/cpuUsage/cpuUsage_linux.c +++ b/src/detection/cpuusage/cpuusage_linux.c @@ -1,5 +1,5 @@ #include "fastfetch.h" -#include "cpuUsage.h" +#include "detection/cpuusage/cpuusage.h" #include #include diff --git a/src/detection/cpuUsage/cpuUsage_windows.c b/src/detection/cpuusage/cpuusage_windows.c similarity index 97% rename from src/detection/cpuUsage/cpuUsage_windows.c rename to src/detection/cpuusage/cpuusage_windows.c index 60ebef4be..a22250d83 100644 --- a/src/detection/cpuUsage/cpuUsage_windows.c +++ b/src/detection/cpuusage/cpuusage_windows.c @@ -1,5 +1,5 @@ #include "fastfetch.h" -#include "cpuUsage.h" +#include "detection/cpuusage/cpuusage.h" #include "util/mallocHelper.h" diff --git a/src/detection/disk/disk_linux.c b/src/detection/disk/disk_linux.c index 6f4eab2bc..210417ef4 100644 --- a/src/detection/disk/disk_linux.c +++ b/src/detection/disk/disk_linux.c @@ -112,8 +112,7 @@ static void detectName(FFDisk* disk, const FFstrbuf* device) if(stat(device->chars, &deviceStat) != 0) return; - FF_STRBUF_AUTO_DESTROY basePath; - ffStrbufInit(&basePath); + FF_STRBUF_AUTO_DESTROY basePath = ffStrbufCreate(); //Try partlabel first ffStrbufSetS(&basePath, "/dev/disk/by-partlabel/"); @@ -202,8 +201,7 @@ void ffDetectDisksImpl(FFDiskResult* disks) return; } - FF_LIST_AUTO_DESTROY devices; - ffListInit(&devices, sizeof(FFstrbuf)); + FF_LIST_AUTO_DESTROY devices = ffListCreate(sizeof(FFstrbuf)); char* line = NULL; size_t len = 0; diff --git a/src/detection/displayserver/displayserver_apple.c b/src/detection/displayserver/displayserver_apple.c index f2d2447aa..e2ae57c5d 100644 --- a/src/detection/displayserver/displayserver_apple.c +++ b/src/detection/displayserver/displayserver_apple.c @@ -40,8 +40,7 @@ static void detectDisplays(FFDisplayServerResult* ds, bool detectName) } } - FF_STRBUF_AUTO_DESTROY name; - ffStrbufInit(&name); + FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate(); if(detectName && CoreDisplay_DisplayCreateInfoDictionary) { CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_DisplayCreateInfoDictionary(screen); @@ -121,5 +120,5 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* ins ffStrbufAppendS(&ds->dePrettyName, "Aqua"); ffListInitA(&ds->displays, sizeof(FFDisplayResult), 4); - detectDisplays(ds, instance->config.displayDetectName); + detectDisplays(ds, instance->config.display.detectName); } diff --git a/src/detection/displayserver/displayserver_nosupport.c b/src/detection/displayserver/displayserver_nosupport.c index 359ebc634..bef1e4554 100644 --- a/src/detection/displayserver/displayserver_nosupport.c +++ b/src/detection/displayserver/displayserver_nosupport.c @@ -4,11 +4,11 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* ins { FF_UNUSED(instance); - ffStrbufInitA(&ds->wmProcessName, 0); - ffStrbufInitA(&ds->wmPrettyName, 0); - ffStrbufInitA(&ds->wmProtocolName, 0); - ffStrbufInitA(&ds->deProcessName, 0); - ffStrbufInitA(&ds->dePrettyName, 0); - ffStrbufInitA(&ds->deVersion, 0); + ffStrbufInit(&ds->wmProcessName); + ffStrbufInit(&ds->wmPrettyName); + ffStrbufInit(&ds->wmProtocolName); + ffStrbufInit(&ds->deProcessName); + ffStrbufInit(&ds->dePrettyName); + ffStrbufInit(&ds->deVersion); ffListInitA(&ds->displays, sizeof(FFDisplayResult), 0); } diff --git a/src/detection/displayserver/displayserver_windows.c b/src/detection/displayserver/displayserver_windows.c index 5d93746f5..9b7bec99b 100644 --- a/src/detection/displayserver/displayserver_windows.c +++ b/src/detection/displayserver/displayserver_windows.c @@ -42,8 +42,7 @@ static void detectDisplays(FFDisplayServerResult* ds, bool detectName) DeleteDC(hdc); } - FF_STRBUF_AUTO_DESTROY name; - ffStrbufInit(&name); + FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate(); if (detectName) { @@ -113,7 +112,7 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* ins ffStrbufInit(&ds->deVersion); ffListInit(&ds->displays, sizeof(FFDisplayResult)); - detectDisplays(ds, instance->config.displayDetectName); + detectDisplays(ds, instance->config.display.detectName); //https://github.com/hykilpikonna/hyfetch/blob/master/neofetch#L2067 const FFOSResult* os = ffDetectOS(instance); diff --git a/src/detection/displayserver/linux/displayserver_linux.c b/src/detection/displayserver/linux/displayserver_linux.c index 257c60cc1..4d50184f4 100644 --- a/src/detection/displayserver/linux/displayserver_linux.c +++ b/src/detection/displayserver/linux/displayserver_linux.c @@ -10,8 +10,7 @@ static void parseDRM(FFDisplayServerResult* result) if(dirp == NULL) return; - FFstrbuf drmDir; - ffStrbufInitA(&drmDir, 64); + FF_STRBUF_AUTO_DESTROY drmDir = ffStrbufCreateA(64); ffStrbufAppendS(&drmDir, drmDirPath); uint32_t drmDirLength = drmDir.length; @@ -48,7 +47,6 @@ static void parseDRM(FFDisplayServerResult* result) } closedir(dirp); - ffStrbufDestroy(&drmDir); } void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* instance) diff --git a/src/detection/displayserver/linux/wayland.c b/src/detection/displayserver/linux/wayland.c index 7e7f98fb5..b4e31f77e 100644 --- a/src/detection/displayserver/linux/wayland.c +++ b/src/detection/displayserver/linux/wayland.c @@ -42,13 +42,11 @@ static void waylandDetectWM(int fd, FFDisplayServerResult* result) if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1) return; - FFstrbuf procPath; - ffStrbufInit(&procPath); + FF_STRBUF_AUTO_DESTROY procPath = ffStrbufCreate(); ffStrbufAppendF(&procPath, "/proc/%d/cmdline", ucred.pid); //We check the cmdline for the process name, because it is not trimmed. ffReadFileBuffer(procPath.chars, &result->wmProcessName); ffStrbufSubstrBeforeFirstC(&result->wmProcessName, '\0'); //Trim the arguments ffStrbufSubstrAfterLastC(&result->wmProcessName, '/'); //Trim the path - ffStrbufDestroy(&procPath); } #else static void waylandDetectWM(int fd, FFDisplayServerResult* result) @@ -225,7 +223,7 @@ bool detectWayland(const FFinstance* instance, FFDisplayServerResult* result) if(data.display == NULL) return false; - data.detectName = instance->config.displayDetectName; + data.detectName = instance->config.display.detectName; waylandDetectWM(ffwl_display_get_fd(data.display), result); diff --git a/src/detection/displayserver/linux/wmde.c b/src/detection/displayserver/linux/wmde.c index db309b92a..a9e580cbe 100644 --- a/src/detection/displayserver/linux/wmde.c +++ b/src/detection/displayserver/linux/wmde.c @@ -165,14 +165,9 @@ static void getMate(const FFinstance* instance, FFDisplayServerResult* result) ffStrbufSetS(&result->deProcessName, "mate-session"); ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_MATE); - FFstrbuf major; - ffStrbufInit(&major); - - FFstrbuf minor; - ffStrbufInit(&minor); - - FFstrbuf micro; - ffStrbufInit(µ); + FF_STRBUF_AUTO_DESTROY major = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY minor = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY micro = ffStrbufCreate(); ffParsePropFileDataValues(instance, "mate-about/mate-version.xml", 3, (FFpropquery[]) { {"", &major}, @@ -182,10 +177,6 @@ static void getMate(const FFinstance* instance, FFDisplayServerResult* result) ffParseSemver(&result->deVersion, &major, &minor, µ); - ffStrbufDestroy(&major); - ffStrbufDestroy(&minor); - ffStrbufDestroy(µ); - if(result->deVersion.length == 0 && instance->config.allowSlowOperations) { ffProcessAppendStdOut(&result->deVersion, (char* const[]){ @@ -244,13 +235,10 @@ static void getLXQt(const FFinstance* instance, FFDisplayServerResult* result) ffParsePropLines(result->deVersion.chars , "liblxqt", &result->deVersion); } - FFstrbuf wmProcessNameBuffer; - ffStrbufInit(&wmProcessNameBuffer); + FF_STRBUF_AUTO_DESTROY wmProcessNameBuffer = ffStrbufCreate(); ffParsePropFileConfig(instance, "lxqt/session.conf", "window_manager =", &wmProcessNameBuffer); applyBetterWM(result, wmProcessNameBuffer.chars); - - ffStrbufDestroy(&wmProcessNameBuffer); } static void getBudgie(const FFinstance* instance, FFDisplayServerResult* result) @@ -351,21 +339,14 @@ static void getFromProcDir(const FFinstance* instance, FFDisplayServerResult* re if(proc == NULL) return; - FFstrbuf procPath; - ffStrbufInitA(&procPath, 64); + FF_STRBUF_AUTO_DESTROY procPath = ffStrbufCreateA(64); ffStrbufAppendS(&procPath, "/proc/"); uint32_t procPathLength = procPath.length; - FFstrbuf userID; - ffStrbufInit(&userID); - ffStrbufAppendF(&userID, "%i", getuid()); - - FFstrbuf loginuid; - ffStrbufInit(&loginuid); - - FFstrbuf processName; - ffStrbufInitA(&processName, 256); //Some processes have large command lines (looking at you chrome) + FF_STRBUF_AUTO_DESTROY userID = ffStrbufCreateF("%i", getuid()); + FF_STRBUF_AUTO_DESTROY loginuid = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY processName = ffStrbufCreateA(256); //Some processes have large command lines (looking at you chrome) struct dirent* dirent; while((dirent = readdir(proc)) != NULL) @@ -407,11 +388,6 @@ static void getFromProcDir(const FFinstance* instance, FFDisplayServerResult* re } closedir(proc); - - ffStrbufDestroy(&processName); - ffStrbufDestroy(&loginuid); - ffStrbufDestroy(&userID); - ffStrbufDestroy(&procPath); } void ffdsDetectWMDE(const FFinstance* instance, FFDisplayServerResult* result) diff --git a/src/detection/gamepad/gamepad_linux.c b/src/detection/gamepad/gamepad_linux.c index ce61a5711..3da034044 100644 --- a/src/detection/gamepad/gamepad_linux.c +++ b/src/detection/gamepad/gamepad_linux.c @@ -10,8 +10,7 @@ const char* ffDetectGamepad(FF_MAYBE_UNUSED const FFinstance* instance, FFlist* if(dirp == NULL) return "opendir(\"/sys/class/input/\") == NULL"; - FF_STRBUF_AUTO_DESTROY path; - ffStrbufInitS(&path, "/sys/class/input/"); + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateS("/sys/class/input/"); uint32_t baseLen = path.length; struct dirent* entry; diff --git a/src/detection/gpu/gpu.c b/src/detection/gpu/gpu.c index b50560dfe..59ac5bf68 100644 --- a/src/detection/gpu/gpu.c +++ b/src/detection/gpu/gpu.c @@ -36,7 +36,7 @@ const FFlist* ffDetectGPU(const FFinstance* instance) { FF_DETECTION_INTERNAL_GUARD(FFlist, ffListInit(&result, sizeof(FFGPUResult)); - if(instance->config.gpuForceVulkan || ffDetectGPUImpl(&result, instance) != NULL) + if(instance->config.gpu.forceVulkan || ffDetectGPUImpl(&result, instance) != NULL) { const FFVulkanResult* vulkan = ffDetectVulkan(instance); result = vulkan->gpus; diff --git a/src/detection/gpu/gpu.h b/src/detection/gpu/gpu.h index 1d34958bf..2f04a440e 100644 --- a/src/detection/gpu/gpu.h +++ b/src/detection/gpu/gpu.h @@ -14,13 +14,6 @@ extern const char* FF_GPU_VENDOR_NAME_AMD; extern const char* FF_GPU_VENDOR_NAME_INTEL; extern const char* FF_GPU_VENDOR_NAME_NVIDIA; -typedef enum FFGpuType -{ - FF_GPU_TYPE_UNKNOWN, - FF_GPU_TYPE_INTEGRATED, - FF_GPU_TYPE_DISCRETE, -} FFGpuType; - typedef struct FFGPUMemory { uint64_t total; @@ -29,7 +22,7 @@ typedef struct FFGPUMemory typedef struct FFGPUResult { - FFGpuType type; + FFGPUType type; FFstrbuf vendor; FFstrbuf name; FFstrbuf driver; diff --git a/src/detection/gpu/gpu_apple.c b/src/detection/gpu/gpu_apple.c index 3cde517c8..2245692b5 100644 --- a/src/detection/gpu/gpu_apple.c +++ b/src/detection/gpu/gpu_apple.c @@ -9,8 +9,7 @@ static double detectGpuTemp(const FFstrbuf* gpuName) { - FF_LIST_AUTO_DESTROY temps; - ffListInit(&temps, sizeof(FFTempValue)); + FF_LIST_AUTO_DESTROY temps = ffListCreate(sizeof(FFTempValue)); if(ffStrbufStartsWithS(gpuName, "Apple M1")) ffDetectCoreTemps(FF_TEMP_GPU_M1X, &temps); @@ -99,7 +98,7 @@ const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance) if(ffCfDictGetInt(properties, CFSTR("gpu-core-count"), &gpu->coreCount)) gpu->coreCount = FF_GPU_CORE_COUNT_UNSET; - if(instance->config.gpuTemp) + if(instance->config.gpu.temp) gpu->temperature = detectGpuTemp(&gpu->name); else gpu->temperature = FF_GPU_TEMP_UNSET; diff --git a/src/detection/gpu/gpu_linux.c b/src/detection/gpu/gpu_linux.c index 63697050f..411bfd45b 100644 --- a/src/detection/gpu/gpu_linux.c +++ b/src/detection/gpu/gpu_linux.c @@ -64,14 +64,9 @@ static void drmDetectDeviceName(const FFinstance* instance, FFGPUResult* gpu, PC #endif } - FFstrbuf query; - ffStrbufInit(&query); - ffStrbufAppendF(&query, "%X, %X,", device->device_id, revId); - + FF_STRBUF_AUTO_DESTROY query = ffStrbufCreateF("%X, %X,", device->device_id, revId); ffParsePropFileData(instance, "libdrm/amdgpu.ids", query.chars, &gpu->name); - ffStrbufDestroy(&query); - const char* removeStrings[] = { "AMD ", "ATI ", " (TM)", "(TM)", @@ -116,10 +111,7 @@ static void pciDetectDriverName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* if(!ffStrSet(base)) return; - FFstrbuf path; - ffStrbufInitA(&path, 64); - ffStrbufAppendF(&path, "%s/devices/%04x:%02x:%02x.%d/driver", base, device->domain, device->bus, device->dev, device->func); - + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateF("%s/devices/%04x:%02x:%02x.%d/driver", base, device->domain, device->bus, device->dev, device->func); ffStrbufEnsureFree(&gpu->driver, 1023); ssize_t resultLength = readlink(path.chars, gpu->driver.chars, gpu->driver.allocated - 1); //-1 for null terminator if(resultLength > 0) @@ -128,8 +120,6 @@ static void pciDetectDriverName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* gpu->driver.chars[resultLength] = '\0'; ffStrbufSubstrAfterLastC(&gpu->driver, '/'); } - - ffStrbufDestroy(&path); } static void pciDetectTemperatur(FFGPUResult* gpu, struct pci_dev* device) @@ -216,7 +206,7 @@ static void pciHandleDevice(const FFinstance* instance, FFlist* results, PCIData gpu->coreCount = FF_GPU_CORE_COUNT_UNSET; gpu->temperature = FF_GPU_TEMP_UNSET; - if(instance->config.gpuTemp) + if(instance->config.gpu.temp) pciDetectTemperatur(gpu, device); } diff --git a/src/detection/gtk_qt/gtk.c b/src/detection/gtk_qt/gtk.c index e61c951aa..abd5a857e 100644 --- a/src/detection/gtk_qt/gtk.c +++ b/src/detection/gtk_qt/gtk.c @@ -162,8 +162,7 @@ static void detectGTK(const FFinstance* instance, const char* version, FFGTKResu return; //We need to do this because we use multiple threads on configDirs - FFstrbuf baseDir; - ffStrbufInitA(&baseDir, 64); + FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(64); FF_LIST_FOR_EACH(FFstrbuf, configDir, instance->state.platform.configDirs) { @@ -172,8 +171,6 @@ static void detectGTK(const FFinstance* instance, const char* version, FFGTKResu if(allPropertiesSet(result)) break; } - - ffStrbufDestroy(&baseDir); } #define FF_DETECT_GTK_IMPL(version) \ diff --git a/src/detection/gtk_qt/qt.c b/src/detection/gtk_qt/qt.c index 74b54a1df..ebf36fbb9 100644 --- a/src/detection/gtk_qt/qt.c +++ b/src/detection/gtk_qt/qt.c @@ -85,8 +85,7 @@ static void detectPlasma(const FFinstance* instance, FFQtResult* result) bool foundAFile = false; //We need to do this because we use multiple threads on configDirs - FFstrbuf baseDir; - ffStrbufInitA(&baseDir, 64); + FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(64); FF_LIST_FOR_EACH(FFstrbuf, configDir, instance->state.platform.configDirs) { @@ -97,13 +96,9 @@ static void detectPlasma(const FFinstance* instance, FFQtResult* result) foundAFile = true; if(allValuesSet(result)) - { - ffStrbufDestroy(&baseDir); return; - } } - ffStrbufDestroy(&baseDir); if(!foundAFile) return; diff --git a/src/detection/host/host_android.c b/src/detection/host/host_android.c index edeb9cb47..240a65b9d 100644 --- a/src/detection/host/host_android.c +++ b/src/detection/host/host_android.c @@ -32,6 +32,6 @@ void ffDetectHostImpl(FFHostResult* host) //Not implemented - ffStrbufInitA(&host->productVersion, 0); - ffStrbufInitA(&host->productSku, 0); + ffStrbufInit(&host->productVersion); + ffStrbufInit(&host->productSku); } diff --git a/src/detection/host/host_linux.c b/src/detection/host/host_linux.c index 04ae3aa27..766b4f47a 100644 --- a/src/detection/host/host_linux.c +++ b/src/detection/host/host_linux.c @@ -89,8 +89,7 @@ void ffDetectHostImpl(FFHostResult* host) { ffStrbufAppendS(&host->productName, "Windows Subsystem for Linux"); - FFstrbuf wslVer; //Wide charactors - ffStrbufInit(&wslVer); + FF_STRBUF_AUTO_DESTROY wslVer = ffStrbufCreate(); //Wide charactors if(!ffProcessAppendStdOut(&wslVer, (char* const[]){ "wsl.exe", "--version", @@ -106,7 +105,6 @@ void ffDetectHostImpl(FFHostResult* host) } ffStrbufAppendC(&host->productName, ')'); } - ffStrbufDestroy(&wslVer); } } } diff --git a/src/detection/icons/icons_linux.c b/src/detection/icons/icons_linux.c index 4ab35b542..5246950db 100644 --- a/src/detection/icons/icons_linux.c +++ b/src/detection/icons/icons_linux.c @@ -18,8 +18,7 @@ const char* ffDetectIcons(const FFinstance* instance, FFstrbuf* result) if(plasma->length == 0 && gtk2->length == 0 && gtk3->length == 0 && gtk4->length == 0) return "No icons could be found"; - FF_STRBUF_AUTO_DESTROY gtkPretty; - ffStrbufInit(>kPretty); + FF_STRBUF_AUTO_DESTROY gtkPretty = ffStrbufCreate(); ffParseGTK(>kPretty, gtk2, gtk3, gtk4); if(plasma->length > 0) diff --git a/src/detection/localip/localip.h b/src/detection/localip/localip.h index f90e97c26..4c9a91539 100644 --- a/src/detection/localip/localip.h +++ b/src/detection/localip/localip.h @@ -13,6 +13,6 @@ typedef struct FFLocalIpResult FFstrbuf mac; } FFLocalIpResult; -const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results); +const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results); #endif diff --git a/src/detection/localip/localip_linux.c b/src/detection/localip/localip_linux.c index b753d1447..29383c2ae 100644 --- a/src/detection/localip/localip_linux.c +++ b/src/detection/localip/localip_linux.c @@ -46,7 +46,7 @@ static void addNewIp(FFlist* list, const char* name, const char* addr, int type) } } -const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results) +const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results) { struct ifaddrs* ifAddrStruct = NULL; if(getifaddrs(&ifAddrStruct) < 0) @@ -57,15 +57,15 @@ const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results) if (!ifa->ifa_addr || !(ifa->ifa_flags & IFF_RUNNING)) continue; - if ((ifa->ifa_flags & IFF_LOOPBACK) && !(instance->config.localIpShowType & FF_LOCALIP_TYPE_LOOP_BIT)) + if ((ifa->ifa_flags & IFF_LOOPBACK) && !(options->showType & FF_LOCALIP_TYPE_LOOP_BIT)) continue; - if (instance->config.localIpNamePrefix.length && strncmp(ifa->ifa_name, instance->config.localIpNamePrefix.chars, instance->config.localIpNamePrefix.length) != 0) + if (options->namePrefix.length && strncmp(ifa->ifa_name, options->namePrefix.chars, options->namePrefix.length) != 0) continue; if (ifa->ifa_addr->sa_family == AF_INET) { - if (!(instance->config.localIpShowType & FF_LOCALIP_TYPE_IPV4_BIT)) + if (!(options->showType & FF_LOCALIP_TYPE_IPV4_BIT)) continue; struct sockaddr_in* ipv4 = (struct sockaddr_in*) ifa->ifa_addr; @@ -75,7 +75,7 @@ const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results) } else if (ifa->ifa_addr->sa_family == AF_INET6) { - if (!(instance->config.localIpShowType & FF_LOCALIP_TYPE_IPV6_BIT)) + if (!(options->showType & FF_LOCALIP_TYPE_IPV6_BIT)) continue; struct sockaddr_in6* ipv6 = (struct sockaddr_in6 *)ifa->ifa_addr; @@ -86,7 +86,7 @@ const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results) #if defined(__FreeBSD__) || defined(__APPLE__) else if (ifa->ifa_addr->sa_family == AF_LINK) { - if (!(instance->config.localIpShowType & FF_LOCALIP_TYPE_MAC_BIT)) + if (!(options->showType & FF_LOCALIP_TYPE_MAC_BIT)) continue; char addressBuffer[32]; @@ -98,7 +98,7 @@ const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results) #else else if (ifa->ifa_addr->sa_family == AF_PACKET) { - if (!(instance->config.localIpShowType & FF_LOCALIP_TYPE_MAC_BIT)) + if (!(options->showType & FF_LOCALIP_TYPE_MAC_BIT)) continue; char addressBuffer[32]; diff --git a/src/detection/localip/localip_windows.c b/src/detection/localip/localip_windows.c index aa3c1dd52..d1295afb0 100644 --- a/src/detection/localip/localip_windows.c +++ b/src/detection/localip/localip_windows.c @@ -37,7 +37,7 @@ static void addNewIp(FFlist* list, const char* name, const char* value, int type } } -const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results) +const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results) { IP_ADAPTER_ADDRESSES* FF_AUTO_FREE adapter_addresses = NULL; @@ -51,8 +51,8 @@ const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results) assert(adapter_addresses); DWORD error = GetAdaptersAddresses( - instance->config.localIpShowType & FF_LOCALIP_TYPE_IPV4_BIT - ? instance->config.localIpShowType & FF_LOCALIP_TYPE_IPV6_BIT ? AF_UNSPEC : AF_INET + options->showType & FF_LOCALIP_TYPE_IPV4_BIT + ? options->showType & FF_LOCALIP_TYPE_IPV6_BIT ? AF_UNSPEC : AF_INET : AF_INET6, GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER, NULL, @@ -71,17 +71,17 @@ const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results) for (IP_ADAPTER_ADDRESSES* adapter = adapter_addresses; adapter; adapter = adapter->Next) { bool isLoop = adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK; - if (isLoop && !(instance->config.localIpShowType & FF_LOCALIP_TYPE_LOOP_BIT)) + if (isLoop && !(options->showType & FF_LOCALIP_TYPE_LOOP_BIT)) continue; bool newIp = true; char name[128]; WideCharToMultiByte(CP_UTF8, 0, adapter->FriendlyName, -1, name, sizeof(name), NULL, NULL); - if (instance->config.localIpNamePrefix.length && strncmp(name, instance->config.localIpNamePrefix.chars, instance->config.localIpNamePrefix.length) != 0) + if (options->namePrefix.length && strncmp(name, options->namePrefix.chars, options->namePrefix.length) != 0) continue; - if (instance->config.localIpShowType & FF_LOCALIP_TYPE_MAC_BIT && adapter->PhysicalAddressLength == 6) + if (options->showType & FF_LOCALIP_TYPE_MAC_BIT && adapter->PhysicalAddressLength == 6) { char addressBuffer[32]; uint8_t* ptr = adapter->PhysicalAddress; diff --git a/src/detection/media/media.c b/src/detection/media/media.c index 5c9d2145f..7bb38d0e5 100644 --- a/src/detection/media/media.c +++ b/src/detection/media/media.c @@ -6,7 +6,7 @@ void ffDetectMediaImpl(const FFinstance* instance, FFMediaResult* media); const FFMediaResult* ffDetectMedia(const FFinstance* instance) { FF_DETECTION_INTERNAL_GUARD(FFMediaResult, - ffStrbufInitA(&result.error, 0); + ffStrbufInit(&result.error); ffStrbufInit(&result.playerId); ffStrbufInit(&result.player); ffStrbufInit(&result.song); diff --git a/src/detection/media/media_linux.c b/src/detection/media/media_linux.c index d470641f7..23564588a 100644 --- a/src/detection/media/media_linux.c +++ b/src/detection/media/media_linux.c @@ -101,18 +101,15 @@ static bool getBusProperties(FFDBusData* data, const char* busName, FFMediaResul static void getCustomBus(FFDBusData* data, const FFinstance* instance, FFMediaResult* result) { - if(ffStrbufStartsWithS(&instance->config.playerName, FF_DBUS_MPRIS_PREFIX)) + if(ffStrbufStartsWithS(&instance->config.player.name, FF_DBUS_MPRIS_PREFIX)) { - getBusProperties(data, instance->config.playerName.chars, result); + getBusProperties(data, instance->config.player.name.chars, result); return; } - FFstrbuf busName; - ffStrbufInit(&busName); - ffStrbufAppendS(&busName, FF_DBUS_MPRIS_PREFIX); - ffStrbufAppend(&busName, &instance->config.playerName); + FF_STRBUF_AUTO_DESTROY busName = ffStrbufCreateS(FF_DBUS_MPRIS_PREFIX); + ffStrbufAppend(&busName, &instance->config.player.name); getBusProperties(data, busName.chars, result); - ffStrbufDestroy(&busName); } static void getBestBus(FFDBusData* data, FFMediaResult* result) @@ -161,7 +158,7 @@ static const char* getMedia(const FFinstance* instance, FFMediaResult* result) if(error != NULL) return error; - if(instance->config.playerName.length > 0) + if(instance->config.player.name.length > 0) getCustomBus(&data, instance, result); else getBestBus(&data, result); diff --git a/src/detection/opengl/opengl_linux.c b/src/detection/opengl/opengl_linux.c index a959578f8..8a274e68f 100644 --- a/src/detection/opengl/opengl_linux.c +++ b/src/detection/opengl/opengl_linux.c @@ -315,7 +315,7 @@ const char* ffDetectOpenGL(FFinstance* instance, FFOpenGLResult* result) { #if FF_HAVE_GL - if(instance->config.glType == FF_GL_TYPE_GLX) + if(instance->config.openGL.type == FF_OPENGL_TYPE_GLX) { #ifdef FF_HAVE_GLX return glxPrint(instance, result); @@ -324,7 +324,7 @@ const char* ffDetectOpenGL(FFinstance* instance, FFOpenGLResult* result) #endif } - if(instance->config.glType == FF_GL_TYPE_EGL) + if(instance->config.openGL.type == FF_OPENGL_TYPE_EGL) { #ifdef FF_HAVE_EGL return eglPrint(instance, result); @@ -333,7 +333,7 @@ const char* ffDetectOpenGL(FFinstance* instance, FFOpenGLResult* result) #endif } - if(instance->config.glType == FF_GL_TYPE_OSMESA) + if(instance->config.openGL.type == FF_OPENGL_TYPE_OSMESA) { #ifdef FF_HAVE_OSMESA return osMesaPrint(instance, result); diff --git a/src/detection/os/os_apple.m b/src/detection/os/os_apple.m index 49a387d42..0b537d718 100644 --- a/src/detection/os/os_apple.m +++ b/src/detection/os/os_apple.m @@ -107,10 +107,10 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) ffStrbufInit(&os->prettyName); ffStrbufInit(&os->versionID); - ffStrbufInitA(&os->codename, 0); - ffStrbufInitA(&os->idLike, 0); - ffStrbufInitA(&os->variant, 0); - ffStrbufInitA(&os->variantID, 0); + ffStrbufInit(&os->codename); + ffStrbufInit(&os->idLike); + ffStrbufInit(&os->variant); + ffStrbufInit(&os->variantID); parseSystemVersion(os); diff --git a/src/detection/os/os_linux.c b/src/detection/os/os_linux.c index 063e8455b..a9db735db 100644 --- a/src/detection/os/os_linux.c +++ b/src/detection/os/os_linux.c @@ -96,9 +96,9 @@ static void getUbuntuFlavour(FFOSResult* result) static void detectOS(FFOSResult* os, const FFinstance* instance) { - if(instance->config.osFile.length > 0) + if(instance->config.os.file.length > 0) { - parseFile(instance->config.osFile.chars, os); + parseFile(instance->config.os.file.chars, os); return; } diff --git a/src/detection/packages/packages_apple.c b/src/detection/packages/packages_apple.c index eaaf5f2fa..0f7ab36e0 100644 --- a/src/detection/packages/packages_apple.c +++ b/src/detection/packages/packages_apple.c @@ -28,8 +28,7 @@ static uint32_t getNumElements(const char* dirname, unsigned char type) static void countBrewPackages(const char* dirname, FFPackagesResult* result) { - FF_STRBUF_AUTO_DESTROY baseDir; - ffStrbufInitS(&baseDir, dirname); + FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateS(dirname); uint32_t baseDirLength = baseDir.length; @@ -54,8 +53,7 @@ static void getBrewPackages(FFPackagesResult* result) static uint32_t countMacPortsPackages(const char* dirname) { - FF_STRBUF_AUTO_DESTROY baseDir; - ffStrbufInitS(&baseDir, dirname); + FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateS(dirname); ffStrbufAppendS(&baseDir, "/var/macports/software"); return getNumElements(baseDir.chars, DT_DIR); diff --git a/src/detection/packages/packages_linux.c b/src/detection/packages/packages_linux.c index b0b47f37c..4a9c483a0 100644 --- a/src/detection/packages/packages_linux.c +++ b/src/detection/packages/packages_linux.c @@ -132,12 +132,10 @@ static uint32_t getNixPackagesImpl(char* path) if(!ffPathExists(path, FF_PATHTYPE_DIRECTORY)) return 0; - FFstrbuf output; - ffStrbufInitA(&output, 128); + FF_STRBUF_AUTO_DESTROY output = ffStrbufCreateA(128); //https://github.com/LinusDierheimer/fastfetch/issues/195#issuecomment-1191748222 - FFstrbuf command; - ffStrbufInitA(&command, 255); + FF_STRBUF_AUTO_DESTROY command = ffStrbufCreateA(255); ffStrbufAppendS(&command, "for x in $(nix-store --query --requisites "); ffStrbufAppendS(&command, path); ffStrbufAppendS(&command, "); do if [ -d $x ]; then echo $x ; fi ; done | cut -d- -f2- | egrep '([0-9]{1,}\\.)+[0-9]{1,}' | egrep -v '\\-doc$|\\-man$|\\-info$|\\-dev$|\\-bin$|^nixos-system-nixos-' | uniq | wc -l"); @@ -149,12 +147,7 @@ static uint32_t getNixPackagesImpl(char* path) NULL }); - int result = (int) strtol(output.chars, NULL, 10); - - ffStrbufDestroy(&command); - ffStrbufDestroy(&output); - - return (uint32_t) result; + return (uint32_t) strtol(output.chars, NULL, 10); } static uint32_t getNixPackages(FFstrbuf* baseDir, const char* dirname) @@ -329,8 +322,7 @@ static void getPackageCountsBedrock(const FFinstance* instance, FFstrbuf* baseDi void ffDetectPackagesImpl(const FFinstance* instance, FFPackagesResult* result) { - FF_STRBUF_AUTO_DESTROY baseDir; - ffStrbufInitA(&baseDir, 512); + FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(512); ffStrbufAppendS(&baseDir, FASTFETCH_TARGET_DIR_ROOT); if(ffStrbufIgnCaseEqualS(&ffDetectOS(instance)->id, "bedrock")) diff --git a/src/detection/packages/packages_windows.c b/src/detection/packages/packages_windows.c index 086a10ea1..30870ce5d 100644 --- a/src/detection/packages/packages_windows.c +++ b/src/detection/packages/packages_windows.c @@ -34,8 +34,7 @@ static uint32_t getNumElements(const char* searchPath /* including `\*` suffix * static void detectScoop(const FFinstance* instance, FFPackagesResult* result) { - FF_STRBUF_AUTO_DESTROY scoopPath; - ffStrbufInitA(&scoopPath, MAX_PATH + 3); + FF_STRBUF_AUTO_DESTROY scoopPath = ffStrbufCreateA(MAX_PATH + 3); const char* scoopEnv = getenv("SCOOP"); if(ffStrSet(scoopEnv)) diff --git a/src/detection/poweradapter/poweradapter.h b/src/detection/poweradapter/poweradapter.h index c7f5ee7dc..1b9abd513 100644 --- a/src/detection/poweradapter/poweradapter.h +++ b/src/detection/poweradapter/poweradapter.h @@ -16,7 +16,7 @@ typedef struct PowerAdapterResult const char* ffDetectPowerAdapterImpl(FFinstance* instance, FFlist* results); -#define FF_POWER_ADAPTER_UNSET -2 -#define FF_POWER_ADAPTER_NOT_CONNECTED -1 +#define FF_POWERADAPTER_UNSET -2 +#define FF_POWERADAPTER_NOT_CONNECTED -1 #endif diff --git a/src/detection/poweradapter/poweradapter_apple.c b/src/detection/poweradapter/poweradapter_apple.c index c14ff8c4e..9c550d95d 100644 --- a/src/detection/poweradapter/poweradapter_apple.c +++ b/src/detection/poweradapter/poweradapter_apple.c @@ -32,14 +32,14 @@ const char* ffDetectPowerAdapterImpl(FFinstance* instance, FFlist* results) ffStrbufInit(&adapter->description); ffStrbufInit(&adapter->manufacturer); ffStrbufInit(&adapter->modelName); - adapter->watts = FF_POWER_ADAPTER_UNSET; + adapter->watts = FF_POWERADAPTER_UNSET; CFDictionaryRef adapterDict; if(!ffCfDictGetDict(properties, CFSTR("AdapterDetails"), &adapterDict)) { if (ffCfDictGetInt(adapterDict, CFSTR("Watts"), &adapter->watts)) { - adapter->watts = FF_POWER_ADAPTER_NOT_CONNECTED; + adapter->watts = FF_POWERADAPTER_NOT_CONNECTED; continue; } ffCfDictGetString(adapterDict, CFSTR("Name"), &adapter->name); diff --git a/src/detection/temps/temps_linux.c b/src/detection/temps/temps_linux.c index 0ade8180f..55506c384 100644 --- a/src/detection/temps/temps_linux.c +++ b/src/detection/temps/temps_linux.c @@ -11,8 +11,7 @@ static bool parseHwmonDir(FFstrbuf* dir, FFTempValue* value) //https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface uint32_t dirLength = dir->length; - FF_STRBUF_AUTO_DESTROY valueBuffer; - ffStrbufInit(&valueBuffer); + FF_STRBUF_AUTO_DESTROY valueBuffer = ffStrbufCreate(); ffStrbufAppendS(dir, "temp1_input"); if(!ffReadFileBuffer(dir->chars, &valueBuffer)) @@ -58,8 +57,7 @@ const FFTempsResult* ffDetectTemps() ffListInitA(&result.values, sizeof(FFTempValue), 16); - FFstrbuf baseDir; - ffStrbufInitA(&baseDir, 64); + FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(64); ffStrbufAppendS(&baseDir, "/sys/class/hwmon/"); uint32_t baseDirLength = baseDir.length; @@ -67,7 +65,6 @@ const FFTempsResult* ffDetectTemps() DIR* dirp = opendir(baseDir.chars); if(dirp == NULL) { - ffStrbufDestroy(&baseDir); ffThreadMutexUnlock(&mutex); return &result; } @@ -94,7 +91,6 @@ const FFTempsResult* ffDetectTemps() } closedir(dirp); - ffStrbufDestroy(&baseDir); ffThreadMutexUnlock(&mutex); return &result; diff --git a/src/detection/terminalfont/terminalfont.c b/src/detection/terminalfont/terminalfont.c index 1c2a4be9b..cd0764247 100644 --- a/src/detection/terminalfont/terminalfont.c +++ b/src/detection/terminalfont/terminalfont.c @@ -6,11 +6,8 @@ static void detectAlacritty(const FFinstance* instance, FFTerminalFontResult* terminalFont) { - FFstrbuf fontName; - ffStrbufInit(&fontName); - - FFstrbuf fontSize; - ffStrbufInit(&fontSize); + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY fontSize = ffStrbufCreate(); FFpropquery fontQuery[] = { {"family:", &fontName}, @@ -33,15 +30,11 @@ static void detectAlacritty(const FFinstance* instance, FFTerminalFontResult* te ffStrbufAppendS(&fontSize, "11"); ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars); - - ffStrbufDestroy(&fontName); - ffStrbufDestroy(&fontSize); } FF_MAYBE_UNUSED static void detectTTY(FFTerminalFontResult* terminalFont) { - FFstrbuf fontName; - ffStrbufInit(&fontName); + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); ffParsePropFile(FASTFETCH_TARGET_DIR_ETC"/vconsole.conf", "Font =", &fontName); @@ -61,116 +54,83 @@ FF_MAYBE_UNUSED static void detectTTY(FFTerminalFontResult* terminalFont) ffFontInitCopy(&terminalFont->font, fontName.chars); else ffStrbufAppendS(&terminalFont->error, "Couldn't find Font in "FASTFETCH_TARGET_DIR_ETC"/vconsole.conf"); - - ffStrbufDestroy(&fontName); } #if defined(_WIN32) || defined(__linux__) -#ifdef FF_HAVE_LIBCJSON +#ifdef FF_HAVE_JSONC #include "common/library.h" #include "common/processing.h" +#include "common/json.h" -#include #include -typedef struct CJSONData +static const char* detectWTProfile(json_object* profile, FFstrbuf* name, double* size) { - FF_LIBRARY_SYMBOL(cJSON_Parse) - FF_LIBRARY_SYMBOL(cJSON_IsObject) - FF_LIBRARY_SYMBOL(cJSON_GetObjectItemCaseSensitive) - FF_LIBRARY_SYMBOL(cJSON_IsString) - FF_LIBRARY_SYMBOL(cJSON_GetStringValue) - FF_LIBRARY_SYMBOL(cJSON_IsNumber) - FF_LIBRARY_SYMBOL(cJSON_GetNumberValue) - FF_LIBRARY_SYMBOL(cJSON_IsArray) - FF_LIBRARY_SYMBOL(cJSON_Delete) + json_object* font = json_object_object_get(profile, "font"); + if (!font) + return "json_object_object_get(profile, \"font\"); failed"; - cJSON* root; -} CJSONData; + if (!json_object_is_type(font, json_type_object)) + return "json_object_is_type(font, json_type_object) returns false"; -static const char* detectWTProfile(CJSONData* cjsonData, cJSON* profile, FFstrbuf* name, double* size) -{ - if(!cjsonData->ffcJSON_IsObject(profile)) - return "cJSON_IsObject(profile) returns false"; - - cJSON* font = cjsonData->ffcJSON_GetObjectItemCaseSensitive(profile, "font"); - if(!cjsonData->ffcJSON_IsObject(font)) - return "cJSON_IsObject(font) returns false"; - - if(name->length == 0) + if (name->length == 0) { - cJSON* pface = cjsonData->ffcJSON_GetObjectItemCaseSensitive(font, "face"); - if(cjsonData->ffcJSON_IsString(pface)) - ffStrbufAppendS(name, cjsonData->ffcJSON_GetStringValue(pface)); + json_object* pface = json_object_object_get(font, "face"); + if(json_object_is_type(pface, json_type_string)) + ffStrbufAppendNS(name, (uint32_t) json_object_get_string_len(pface), json_object_get_string(pface)); } - if(*size < 0) + + if (*size < 0) { - cJSON* psize = cjsonData->ffcJSON_GetObjectItemCaseSensitive(font, "size"); - if(cjsonData->ffcJSON_IsNumber(psize)) - *size = cjsonData->ffcJSON_GetNumberValue(psize); + json_object* psize = json_object_object_get(font, "size"); + if (json_object_is_type(psize, json_type_int) || json_object_is_type(psize, json_type_double)) + *size = json_object_get_double(psize); } return NULL; } -static inline void wrapCjsonFree(CJSONData* data) -{ - assert(data); - if (data->root) - data->ffcJSON_Delete(data->root); -} - static const char* detectFromWTImpl(const FFinstance* instance, FFstrbuf* content, FFstrbuf* name, double* size) { - FF_LIBRARY_LOAD(libcjson, &instance->config.libcJSON, "dlopen libcjson" FF_LIBRARY_EXTENSION " failed", "libcjson"FF_LIBRARY_EXTENSION, 1) - CJSONData __attribute__((__cleanup__(wrapCjsonFree))) cjsonData = {}; // Make sure cjsonData is destroyed before libcjson is dlclosed - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(libcjson, cjsonData, cJSON_Parse, cJSON_Parse@4) - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(libcjson, cjsonData, cJSON_IsObject, cJSON_IsObject@4) - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(libcjson, cjsonData, cJSON_GetObjectItemCaseSensitive, cJSON_GetObjectItemCaseSensitive@8) - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(libcjson, cjsonData, cJSON_IsString, cJSON_IsString@4) - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(libcjson, cjsonData, cJSON_GetStringValue, cJSON_GetStringValue@4) - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(libcjson, cjsonData, cJSON_IsNumber, cJSON_IsNumber@4) - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(libcjson, cjsonData, cJSON_GetNumberValue, cJSON_GetNumberValue@4) - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(libcjson, cjsonData, cJSON_IsArray, cJSON_IsArray@4) - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(libcjson, cjsonData, cJSON_Delete, cJSON_Delete@4) + if (!ffJsonLoadLibrary(instance)) + return "Failed to load json-c library"; - cJSON* root = cjsonData.root = cjsonData.ffcJSON_Parse(content->chars); - if(!cjsonData.ffcJSON_IsObject(root)) - return "cJSON_Parse() failed"; + json_object* __attribute__((__cleanup__(wrapJsoncFree))) root = json_tokener_parse(content->chars); + if (!root) + return "Failed to parse WT JSON config file"; - cJSON* profiles = cjsonData.ffcJSON_GetObjectItemCaseSensitive(root, "profiles"); - if(!cjsonData.ffcJSON_IsObject(profiles)) - return "cJSON_GetObjectItemCaseSensitive(root, \"profiles\") failed"; + json_object* profiles = json_object_object_get(root, "profiles"); + if (!profiles) + return "json_object_object_get(root, \"profiles\") failed"; - FF_STRBUF_AUTO_DESTROY wtProfileId; - ffStrbufInitS(&wtProfileId, getenv("WT_PROFILE_ID")); + FF_STRBUF_AUTO_DESTROY wtProfileId = ffStrbufCreateS(getenv("WT_PROFILE_ID")); ffStrbufTrim(&wtProfileId, '\''); - if(wtProfileId.length > 0) + if (wtProfileId.length > 0) { - cJSON* list = cjsonData.ffcJSON_GetObjectItemCaseSensitive(profiles, "list"); - if(cjsonData.ffcJSON_IsArray(list)) + array_list* list = json_object_get_array(json_object_object_get(profiles, "list")); + if (list) { - cJSON* profile; - cJSON_ArrayForEach(profile, list) + for (size_t idx = 0; idx < list->length; ++idx) { - if(!cjsonData.ffcJSON_IsObject(profile)) + json_object* profile = (json_object*) list->array[idx]; + json_object* guid = json_object_object_get(profile, "guid"); + + if (!json_object_is_type(guid, json_type_string)) continue; - cJSON* guid = cjsonData.ffcJSON_GetObjectItemCaseSensitive(profile, "guid"); - if(!cjsonData.ffcJSON_IsString(guid)) - continue; - if(ffStrbufCompS(&wtProfileId, cjsonData.ffcJSON_GetStringValue(guid)) == 0) + + if(ffStrbufEqualS(&wtProfileId, json_object_get_string(guid))) { - detectWTProfile(&cjsonData, profile, name, size); + detectWTProfile(profile, name, size); break; } } } } - cJSON* defaults = cjsonData.ffcJSON_GetObjectItemCaseSensitive(profiles, "defaults"); - if(defaults) - detectWTProfile(&cjsonData, defaults, name, size); + json_object* defaults = json_object_object_get(profiles, "defaults"); + if (defaults) + detectWTProfile(defaults, name, size); if(name->length == 0) ffStrbufSetS(name, "Cascadia Mono"); @@ -188,8 +148,7 @@ static const char* detectFromWTImpl(const FFinstance* instance, FFstrbuf* conten static void detectFromWindowsTeriminal(const FFinstance* instance, const FFstrbuf* terminalExe, FFTerminalFontResult* terminalFont) { //https://learn.microsoft.com/en-us/windows/terminal/install#settings-json-file - FF_STRBUF_AUTO_DESTROY json; - ffStrbufInit(&json); + FF_STRBUF_AUTO_DESTROY json = ffStrbufCreate(); const char* error = NULL; #ifdef _WIN32 @@ -258,8 +217,7 @@ static void detectFromWindowsTeriminal(const FFinstance* instance, const FFstrbu return; } - FF_STRBUF_AUTO_DESTROY name; - ffStrbufInit(&name); + FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate(); double size = -1; error = detectFromWTImpl(instance, &json, &name, &size); @@ -273,25 +231,22 @@ static void detectFromWindowsTeriminal(const FFinstance* instance, const FFstrbu } } -#else //FF_HAVE_CJSON +#else //FF_HAVE_JSONC static void detectFromWindowsTeriminal(const FFinstance* instance, const FFstrbuf* terminalExe, FFTerminalFontResult* terminalFont) { FF_UNUSED(instance, terminalExe, terminalFont); - ffStrbufAppendS(&terminalFont->error, "Fastfetch was built without libcJSON support"); + ffStrbufAppendS(&terminalFont->error, "Fastfetch was built without json-c support"); } -#endif //FF_HAVE_CJSON +#endif //FF_HAVE_JSONC #endif //defined(_WIN32) || defined(__linux__) FF_MAYBE_UNUSED static bool detectKitty(const FFinstance* instance, FFTerminalFontResult* result) { - FF_STRBUF_AUTO_DESTROY fontName; - ffStrbufInit(&fontName); - - FF_STRBUF_AUTO_DESTROY fontSize; - ffStrbufInit(&fontSize); + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY fontSize = ffStrbufCreate(); FFpropquery fontQuery[] = { {"font_family ", &fontName}, @@ -313,11 +268,8 @@ FF_MAYBE_UNUSED static bool detectKitty(const FFinstance* instance, FFTerminalFo static void detectTerminator(const FFinstance* instance, FFTerminalFontResult* result) { - FF_STRBUF_AUTO_DESTROY useSystemFont; - ffStrbufInit(&useSystemFont); - - FF_STRBUF_AUTO_DESTROY fontName; - ffStrbufInit(&fontName); + FF_STRBUF_AUTO_DESTROY useSystemFont = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); FFpropquery fontQuery[] = { {"use_system_font =", &useSystemFont}, @@ -344,8 +296,7 @@ static void detectTerminator(const FFinstance* instance, FFTerminalFontResult* r static bool detectWezterm(FF_MAYBE_UNUSED const FFinstance* instance, FFTerminalFontResult* result) { - FF_STRBUF_AUTO_DESTROY fontName; - ffStrbufInit(&fontName); + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); ffStrbufSetS(&result->error, ffProcessAppendStdOut(&fontName, (char* const[]){ "wezterm", @@ -372,11 +323,8 @@ static bool detectWezterm(FF_MAYBE_UNUSED const FFinstance* instance, FFTerminal static bool detectTabby(FF_MAYBE_UNUSED const FFinstance* instance, FFTerminalFontResult* result) { - FF_STRBUF_AUTO_DESTROY fontName; - ffStrbufInit(&fontName); - - FF_STRBUF_AUTO_DESTROY fontSize; - ffStrbufInit(&fontSize); + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY fontSize = ffStrbufCreate(); FFpropquery fontQuery[] = { {"font: ", &fontName}, @@ -434,7 +382,7 @@ static bool detectTerminalFontCommon(const FFinstance* instance, const FFTermina const FFTerminalFontResult* ffDetectTerminalFont(const FFinstance* instance) { FF_DETECTION_INTERNAL_GUARD(FFTerminalFontResult, - ffStrbufInitA(&result.error, 0); + ffStrbufInit(&result.error); const FFTerminalShellResult* terminalShell = ffDetectTerminalShell(instance); diff --git a/src/detection/terminalfont/terminalfont_apple.m b/src/detection/terminalfont/terminalfont_apple.m index 2dd3d03b7..f95503585 100644 --- a/src/detection/terminalfont/terminalfont_apple.m +++ b/src/detection/terminalfont/terminalfont_apple.m @@ -46,8 +46,7 @@ static void detectIterm2(const FFinstance* instance, FFTerminalFontResult* termi static void detectAppleTerminal(FFTerminalFontResult* terminalFont) { - FF_STRBUF_AUTO_DESTROY font; - ffStrbufInit(&font); + FF_STRBUF_AUTO_DESTROY font = ffStrbufCreate(); ffOsascript("tell application \"Terminal\" to font name of window frontmost & \" \" & font size of window frontmost", &font); if(font.length == 0) diff --git a/src/detection/terminalfont/terminalfont_linux.c b/src/detection/terminalfont/terminalfont_linux.c index 9742a6daa..68f096523 100644 --- a/src/detection/terminalfont/terminalfont_linux.c +++ b/src/detection/terminalfont/terminalfont_linux.c @@ -35,8 +35,7 @@ static void detectFromGSettings(const FFinstance* instance, char* profilePath, c return; } - FFstrbuf path; - ffStrbufInitA(&path, 128); + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateA(128); ffStrbufAppendS(&path, profilePath); ffStrbufAppendS(&path, defaultProfile); ffStrbufAppendC(&path, '/'); @@ -57,64 +56,47 @@ static void detectFromGSettings(const FFinstance* instance, char* profilePath, c else ffStrbufAppendS(&terminalFont->error, "Could't get system monospace font name from GSettings / DConf"); } - - ffStrbufDestroy(&path); } static void detectFromConfigFile(const FFinstance* instance, const char* configFile, const char* start, FFTerminalFontResult* terminalFont) { - FFstrbuf fontName; - ffStrbufInit(&fontName); + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); ffParsePropFileConfig(instance, configFile, start, &fontName); if(fontName.length == 0) ffStrbufAppendF(&terminalFont->error, "Couldn't find %s in .config/%s", start, configFile); else ffFontInitPango(&terminalFont->font, fontName.chars); - - ffStrbufDestroy(&fontName); } static void detectKonsole(const FFinstance* instance, FFTerminalFontResult* terminalFont) { - FFstrbuf profile; - ffStrbufInit(&profile); + FF_STRBUF_AUTO_DESTROY profile = ffStrbufCreate(); ffParsePropFileConfig(instance, "konsolerc", "DefaultProfile =", &profile); if(profile.length == 0) { ffStrbufAppendS(&terminalFont->error, "Couldn't find \"DefaultProfile=%[^\\n]\" in \".config/konsolerc\""); - ffStrbufDestroy(&profile); return; } - FFstrbuf profilePath; - ffStrbufInitA(&profilePath, 32); + FF_STRBUF_AUTO_DESTROY profilePath = ffStrbufCreateA(32); ffStrbufAppendS(&profilePath, "konsole/"); ffStrbufAppend(&profilePath, &profile); - ffStrbufDestroy(&profile); - - FFstrbuf fontName; - ffStrbufInit(&fontName); + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); ffParsePropFileData(instance, profilePath.chars, "Font =", &fontName); if(fontName.length == 0) ffStrbufAppendF(&terminalFont->error, "Couldn't find \"Font=%%[^\\n]\" in \"%s\"", profilePath.chars); else ffFontInitQt(&terminalFont->font, fontName.chars); - - ffStrbufDestroy(&fontName); - ffStrbufDestroy(&profilePath); } static void detectXFCETerminal(const FFinstance* instance, FFTerminalFontResult* terminalFont) { - FFstrbuf useSysFont; - ffStrbufInit(&useSysFont); - - FFstrbuf fontName; - ffStrbufInit(&fontName); + FF_STRBUF_AUTO_DESTROY useSysFont = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); ffParsePropFileConfigValues(instance, "xfce4/terminal/terminalrc", 2, (FFpropquery[]) { {"FontUseSystem = ", &useSysFont}, @@ -136,21 +118,14 @@ static void detectXFCETerminal(const FFinstance* instance, FFTerminalFontResult* else ffStrbufAppendS(&terminalFont->error, "Couldn't find xsettings::/Gtk/MonospaceFontName in XFConf"); } - - ffStrbufDestroy(&fontName); - ffStrbufDestroy(&useSysFont); } static void detectDeepinTerminal(const FFinstance* instance, FFTerminalFontResult* terminalFont) { - FFstrbuf fontName; - ffStrbufInit(&fontName); + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY fontSize = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY profile = ffStrbufCreate(); - FFstrbuf fontSize; - ffStrbufInit(&fontSize); - - FFstrbuf profile; - ffStrbufInit(&profile); ffStrbufAppend(&profile, &instance->state.platform.homeDir); ffStrbufAppendS(&profile, ".config/deepin/deepin-terminal/config.conf"); //TODO: Use config dirs FILE* file = fopen(profile.chars, "r"); @@ -180,23 +155,17 @@ static void detectDeepinTerminal(const FFinstance* instance, FFTerminalFontResul fclose(file); } - ffStrbufDestroy(&profile); - if(fontName.length == 0) ffStrbufAppendS(&fontName, "Noto Sans Mono"); if(fontSize.length == 0) ffStrbufAppendS(&fontSize, "11"); ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars); - - ffStrbufDestroy(&fontName); - ffStrbufDestroy(&fontSize); } static void detectFootTerminal(const FFinstance* instance, FFTerminalFontResult* terminalFont) { - FF_STRBUF_AUTO_DESTROY font; - ffStrbufInit(&font); + FF_STRBUF_AUTO_DESTROY font = ffStrbufCreate(); if (!ffParsePropFileConfig(instance, "foot/foot.ini", "font=", &font) || !ffStrSet(font.chars)) { diff --git a/src/detection/terminalfont/terminalfont_windows.c b/src/detection/terminalfont/terminalfont_windows.c index da2f0568b..3a10e1bd6 100644 --- a/src/detection/terminalfont/terminalfont_windows.c +++ b/src/detection/terminalfont/terminalfont_windows.c @@ -8,11 +8,8 @@ static void detectMintty(const FFinstance* instance, FFTerminalFontResult* terminalFont) { - FF_STRBUF_AUTO_DESTROY fontName; - ffStrbufInit(&fontName); - - FF_STRBUF_AUTO_DESTROY fontSize; - ffStrbufInit(&fontSize); + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY fontSize = ffStrbufCreate(); if(!ffParsePropFileConfigValues(instance, "mintty/config", 2, (FFpropquery[]) { {"Font=", &fontName}, @@ -54,14 +51,9 @@ static void detectConEmu(const FFinstance* instance, FFTerminalFontResult* termi FF_UNUSED(instance) //https://conemu.github.io/en/ConEmuXml.html#search-sequence - FFstrbuf path; - ffStrbufInit(&path); - - FFstrbuf fontName; - ffStrbufInit(&fontName); - - FFstrbuf fontSize; - ffStrbufInit(&fontSize); + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY fontSize = ffStrbufCreate(); const char* paths[] = { "ConEmuDir", "ConEmuBaseDir", "APPDATA" }; for (uint32_t i = 0; i < sizeof(paths) / sizeof(paths[0]); ++i) @@ -77,7 +69,6 @@ static void detectConEmu(const FFinstance* instance, FFTerminalFontResult* termi break; } } - ffStrbufDestroy(&path); if(fontName.length == 0 && fontSize.length == 0) { @@ -96,9 +87,6 @@ static void detectConEmu(const FFinstance* instance, FFTerminalFontResult* termi ffStrbufAppendS(&fontSize, "14"); ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars); - - ffStrbufDestroy(&fontName); - ffStrbufDestroy(&fontSize); } void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont) diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index 6fb5cc008..9bb488e0f 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -281,8 +281,7 @@ static void getUserShellFromEnv(const FFinstance* instance, FFTerminalShellResul static void getShellVersionGeneric(FFstrbuf* exe, const char* exeName, FFstrbuf* version) { - FFstrbuf command; - ffStrbufInit(&command); + FF_STRBUF_AUTO_DESTROY command = ffStrbufCreate(); ffStrbufAppendS(&command, "printf \"%s\" \"$"); ffStrbufAppendTransformS(&command, exeName, toupper); ffStrbufAppendS(&command, "_VERSION\""); @@ -297,8 +296,6 @@ static void getShellVersionGeneric(FFstrbuf* exe, const char* exeName, FFstrbuf* }); ffStrbufSubstrBeforeFirstC(version, '('); ffStrbufRemoveStrings(version, 2, "-release", "release"); - - ffStrbufDestroy(&command); } bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version); @@ -356,7 +353,7 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) getUserShellFromEnv(instance, &result); ffStrbufClear(&result.shellVersion); - if(instance->config.shellVersion) + if(instance->config.shell.version) { getShellVersion(&result.shellExe, result.shellExeName, &result.shellVersion); @@ -393,7 +390,7 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) ffStrbufInit(&result.terminalVersion); - if(instance->config.terminalVersion) + if(instance->config.terminal.version) fftsGetTerminalVersion(&result.terminalProcessName, &result.terminalExe, &result.terminalVersion); ffThreadMutexUnlock(&mutex); diff --git a/src/detection/terminalshell/terminalshell_windows.c b/src/detection/terminalshell/terminalshell_windows.c index 9af70f8ca..a20cfc11a 100644 --- a/src/detection/terminalshell/terminalshell_windows.c +++ b/src/detection/terminalshell/terminalshell_windows.c @@ -152,7 +152,7 @@ static uint32_t getShellInfo(const FFinstance* instance, FFTerminalShellResult* } ffStrbufClear(&result->shellVersion); - if(instance->config.shellVersion) + if(instance->config.shell.version) fftsGetShellVersion(&result->shellExe, result->shellPrettyName.chars, &result->shellVersion); result->shellPid = pid; @@ -351,7 +351,7 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) getTerminalFromEnv(&result); ffStrbufInit(&result.terminalVersion); - if(instance->config.terminalVersion) + if(instance->config.terminal.version) fftsGetTerminalVersion(&result.terminalProcessName, &result.terminalExe, &result.terminalVersion); exit: diff --git a/src/detection/theme/theme_linux.c b/src/detection/theme/theme_linux.c index bcacf89ea..d59c6d2de 100644 --- a/src/detection/theme/theme_linux.c +++ b/src/detection/theme/theme_linux.c @@ -18,8 +18,7 @@ const char* ffDetectTheme(const FFinstance* instance, FFstrbuf* result) if(plasma->widgetStyle.length == 0 && plasma->colorScheme.length == 0 && gtk2->length == 0 && gtk3->length == 0 && gtk4->length == 0) return "No themes found"; - FF_STRBUF_AUTO_DESTROY plasmaColorPretty; - ffStrbufInit(&plasmaColorPretty); + FF_STRBUF_AUTO_DESTROY plasmaColorPretty = ffStrbufCreate(); if(ffStrbufStartsWithIgnCase(&plasma->colorScheme, &plasma->widgetStyle)) ffStrbufAppendNS(&plasmaColorPretty, plasma->colorScheme.length - plasma->widgetStyle.length, &plasma->colorScheme.chars[plasma->widgetStyle.length]); else @@ -27,8 +26,7 @@ const char* ffDetectTheme(const FFinstance* instance, FFstrbuf* result) ffStrbufTrim(&plasmaColorPretty, ' '); - FF_STRBUF_AUTO_DESTROY gtkPretty; - ffStrbufInit(>kPretty); + FF_STRBUF_AUTO_DESTROY gtkPretty = ffStrbufCreate(); ffParseGTK(>kPretty, gtk2, gtk3, gtk4); if(plasma->widgetStyle.length > 0) diff --git a/src/detection/uptime/uptime.h b/src/detection/uptime/uptime.h index 6a032b47c..447b13d5b 100644 --- a/src/detection/uptime/uptime.h +++ b/src/detection/uptime/uptime.h @@ -5,6 +5,6 @@ #include "fastfetch.h" -uint64_t ffDetectUptime(); +const char* ffDetectUptime(uint64_t* result); #endif diff --git a/src/detection/uptime/uptime_bsd.c b/src/detection/uptime/uptime_bsd.c index 375065c35..4e3a707c6 100644 --- a/src/detection/uptime/uptime_bsd.c +++ b/src/detection/uptime/uptime_bsd.c @@ -4,7 +4,7 @@ #include #include -uint64_t ffDetectUptime() +const char* ffDetectUptime(uint64_t* result) { struct timeval bootTime; size_t bootTimeSize = sizeof(bootTime); @@ -12,8 +12,10 @@ uint64_t ffDetectUptime() (int[]) {CTL_KERN, KERN_BOOTTIME}, 2, &bootTime, &bootTimeSize, NULL, 0 - ) == 0) - return (uint64_t) difftime(time(NULL), bootTime.tv_sec); + ) != 0) + return "sysctl({CTL_KERN, KERN_BOOTTIME}) failed"; - return 0; + *result = (uint64_t) difftime(time(NULL), bootTime.tv_sec); + + return NULL; } diff --git a/src/detection/uptime/uptime_linux.c b/src/detection/uptime/uptime_linux.c index cf4860771..0339bc7e6 100644 --- a/src/detection/uptime/uptime_linux.c +++ b/src/detection/uptime/uptime_linux.c @@ -2,10 +2,11 @@ #include -uint64_t ffDetectUptime() +const char* ffDetectUptime(uint64_t* result) { struct sysinfo info; if(sysinfo(&info) != 0) - return 0; - return (uint32_t) info.uptime; + return "sysinfo() failed"; + *result = (uint64_t) info.uptime; + return NULL; } diff --git a/src/detection/uptime/uptime_windows.c b/src/detection/uptime/uptime_windows.c index 657af033b..55053ab24 100644 --- a/src/detection/uptime/uptime_windows.c +++ b/src/detection/uptime/uptime_windows.c @@ -2,7 +2,8 @@ #include -uint64_t ffDetectUptime() +const char* ffDetectUptime(uint64_t* result) { - return GetTickCount64() / 1000; + *result = GetTickCount64() / 1000; + return NULL; } diff --git a/src/detection/wallpaper/wallpaper_apple.c b/src/detection/wallpaper/wallpaper_apple.c index f1235ba1e..7d2fb84dc 100644 --- a/src/detection/wallpaper/wallpaper_apple.c +++ b/src/detection/wallpaper/wallpaper_apple.c @@ -8,8 +8,7 @@ const char* ffDetectWallpaper(FF_MAYBE_UNUSED const FFinstance* instance, FFstrb #ifdef FF_HAVE_SQLITE3 - FF_STRBUF_AUTO_DESTROY path; - ffStrbufInitCopy(&path, &instance->state.platform.homeDir); + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateCopy(&instance->state.platform.homeDir); ffStrbufAppendS(&path, "Library/Application Support/Dock/desktoppicture.db"); if (ffSettingsGetSQLite3String(instance, path.chars, "SELECT value\n" diff --git a/src/detection/wifi/wifi_android.c b/src/detection/wifi/wifi_android.c index 8e6e2b072..39ae35541 100644 --- a/src/detection/wifi/wifi_android.c +++ b/src/detection/wifi/wifi_android.c @@ -8,8 +8,7 @@ const char* ffDetectWifi(FF_MAYBE_UNUSED const FFinstance* instance, FFlist* result) { - FF_STRBUF_AUTO_DESTROY buffer; - ffStrbufInit(&buffer); + FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); if(ffProcessAppendStdOut(&buffer, (char* const[]){ FF_TERMUX_API_PATH, diff --git a/src/detection/wifi/wifi_linux.c b/src/detection/wifi/wifi_linux.c index d0a679fdb..a92fa8c2e 100644 --- a/src/detection/wifi/wifi_linux.c +++ b/src/detection/wifi/wifi_linux.c @@ -144,8 +144,7 @@ static const char* detectWifiWithLibnm(const FFinstance* instance, FFlist* resul if(instance->config.allowSlowOperations) { - FF_STRBUF_AUTO_DESTROY output; - ffStrbufInit(&output); + FF_STRBUF_AUTO_DESTROY output = ffStrbufCreate(); if(!ffProcessAppendStdOut(&output, (char* const[]){ "iw", "dev", @@ -216,8 +215,7 @@ static const char* detectWifiWithIoctls(FF_MAYBE_UNUSED const FFinstance* instan if(!infs) return "if_nameindex() failed"; - FFstrbuf path; - ffStrbufInit(&path); + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate(); for(struct if_nameindex* i = infs; !(i->if_index == 0 && i->if_name == NULL); ++i) { @@ -307,7 +305,6 @@ static const char* detectWifiWithIoctls(FF_MAYBE_UNUSED const FFinstance* instan close(sock); } if_freenameindex(infs); - ffStrbufDestroy(&path); return NULL; } diff --git a/src/detection/wmtheme/wmtheme_linux.c b/src/detection/wmtheme/wmtheme_linux.c index e325e0bce..2099a3a2c 100644 --- a/src/detection/wmtheme/wmtheme_linux.c +++ b/src/detection/wmtheme/wmtheme_linux.c @@ -10,7 +10,7 @@ static bool detectWMThemeFromConfigFile(FFinstance* instance, const char* config { if(!ffParsePropFileConfig(instance, configFile, themeRegex, themeOrError)) { - ffStrbufInitF(themeOrError, "Config file %s doesn't exist", configFile); + ffStrbufAppendF(themeOrError, "Config file %s doesn't exist", configFile); return false; } @@ -131,8 +131,7 @@ static bool detectXFWM4(FFinstance* instance, FFstrbuf* themeOrError) static bool detectOpenbox(FFinstance* instance, const FFstrbuf* dePrettyName, FFstrbuf* themeOrError) { - FFstrbuf absolutePath; - ffStrbufInitA(&absolutePath, 64); + FF_STRBUF_AUTO_DESTROY absolutePath = ffStrbufCreateA(64); ffStrbufAppend(&absolutePath, &instance->state.platform.homeDir); //TODO: use config dirs @@ -150,7 +149,6 @@ static bool detectOpenbox(FFinstance* instance, const FFstrbuf* dePrettyName, FF if(file == NULL) { ffStrbufAppendF(themeOrError, "Couldn't open \"%s\"", absolutePath.chars); - ffStrbufDestroy(&absolutePath); return false; } @@ -184,11 +182,9 @@ static bool detectOpenbox(FFinstance* instance, const FFstrbuf* dePrettyName, FF if(themeOrError->length == 0) { ffStrbufAppendF(themeOrError, "Couldn't find theme name in \"%s\"", absolutePath.chars); - ffStrbufDestroy(&absolutePath); return false; } - ffStrbufDestroy(&absolutePath); return true; } diff --git a/src/detection/wmtheme/wmtheme_windows.c b/src/detection/wmtheme/wmtheme_windows.c index 0522b933b..67ea08f83 100644 --- a/src/detection/wmtheme/wmtheme_windows.c +++ b/src/detection/wmtheme/wmtheme_windows.c @@ -66,8 +66,7 @@ bool ffDetectWmTheme(FF_MAYBE_UNUSED FFinstance* instance, FFstrbuf* themeOrErro FF_HKEY_AUTO_DESTROY hKey = NULL; if(ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes", &hKey, NULL)) { - FF_STRBUF_AUTO_DESTROY theme; - ffStrbufInit(&theme); + FF_STRBUF_AUTO_DESTROY theme = ffStrbufCreate(); if(ffRegReadStrbuf(hKey, L"CurrentTheme", &theme, NULL)) { ffStrbufSubstrBeforeLastC(&theme, '.'); diff --git a/src/fastfetch.c b/src/fastfetch.c index 63480f514..66c5ae5b5 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -3,8 +3,8 @@ #include "common/parsing.h" #include "common/io/io.h" #include "common/time.h" -#include "util/FFvaluestore.h" #include "util/stringUtils.h" +#include "logo/logo.h" #include #include @@ -17,6 +17,9 @@ #pragma GCC diagnostic ignored "-Wsign-conversion" +#include "common/jsonconfig.h" +#include "modules/modules.h" + typedef struct CustomValue { bool printKey; @@ -26,7 +29,6 @@ typedef struct CustomValue // Things only needed by fastfetch typedef struct FFdata { - FFvaluestore customValues; FFstrbuf structure; bool loadUserConfig; } FFdata; @@ -610,8 +612,7 @@ static void optionParseConfigFile(FFinstance* instance, FFdata* data, const char //Try to load as a relative path - FFstrbuf absolutePath; - ffStrbufInitA(&absolutePath, 128); + FF_STRBUF_AUTO_DESTROY absolutePath = ffStrbufCreateA(128); FF_LIST_FOR_EACH(FFstrbuf, path, instance->state.platform.dataDirs) { @@ -626,8 +627,6 @@ static void optionParseConfigFile(FFinstance* instance, FFdata* data, const char return; } - ffStrbufDestroy(&absolutePath); - //File not found fprintf(stderr, "Error: couldn't find config: %s\n", value); @@ -714,32 +713,6 @@ static uint32_t optionParseUInt32(const char* key, const char* value) return num; } -static void optionParseCustomValue(FFdata* data, const char* key, const char* value, bool printKey) -{ - if(value == NULL) - { - fprintf(stderr, "Error: usage: %s \n", key); - exit(411); - } - - char* separator = strchr(value, '='); - - if(separator == NULL) - { - fprintf(stderr, "Error: usage: %s , '=' missing\n", key); - exit(412); - } - - *separator = '\0'; - - bool created; - CustomValue* customValue = ffValuestoreSet(&data->customValues, value, &created); - if(created) - ffStrbufInit(&customValue->value); - ffStrbufSetS(&customValue->value, separator + 1); - customValue->printKey = printKey; -} - static void optionParseEnum(const char* argumentKey, const char* requestedKey, void* result, ...) { if(requestedKey == NULL) @@ -773,40 +746,6 @@ static void optionParseEnum(const char* argumentKey, const char* requestedKey, v exit(478); } -static bool optionParseModuleArgs(const char* argumentKey, const char* value, const char* moduleName, struct FFModuleArgs* result) -{ - const char* pkey = argumentKey; - if(!(pkey[0] == '-' && pkey[1] == '-')) - return false; - - pkey += 2; - uint32_t moduleNameLen = (uint32_t)strlen(moduleName); - if(strncasecmp(pkey, moduleName, moduleNameLen) != 0) - return false; - - pkey += moduleNameLen; - if(pkey[0] != '-') - return false; - - pkey += 1; - if(strcasecmp(pkey, "key") == 0) - { - optionParseString(argumentKey, value, &result->key); - return true; - } - else if(strcasecmp(pkey, "format") == 0) - { - optionParseString(argumentKey, value, &result->outputFormat); - return true; - } - else if(strcasecmp(pkey, "error") == 0) - { - optionParseString(argumentKey, value, &result->errorFormat); - return true; - } - return false; -} - static void parseOption(FFinstance* instance, FFdata* data, const char* key, const char* value) { /////////////////////// @@ -961,132 +900,7 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con //Logo options// //////////////// - else if(strcasecmp(key, "-l") == 0 || strcasecmp(key, "--logo") == 0) - { - optionParseString(key, value, &instance->config.logo.source); - - //this is usally wanted when using the none logo - if(strcasecmp(value, "none") == 0) - { - instance->config.logo.paddingTop = 0; - instance->config.logo.paddingRight = 0; - instance->config.logo.paddingLeft = 0; - instance->config.logo.type = FF_LOGO_TYPE_NONE; - } - } - else if(startsWith(key, "--logo")) - { - const char* subkey = key + strlen("--logo"); - if(strcasecmp(subkey, "-type") == 0) - { - optionParseEnum(key, value, &instance->config.logo.type, - "auto", FF_LOGO_TYPE_AUTO, - "builtin", FF_LOGO_TYPE_BUILTIN, - "file", FF_LOGO_TYPE_FILE, - "file-raw", FF_LOGO_TYPE_FILE_RAW, - "data", FF_LOGO_TYPE_DATA, - "data-raw", FF_LOGO_TYPE_DATA_RAW, - "sixel", FF_LOGO_TYPE_IMAGE_SIXEL, - "kitty", FF_LOGO_TYPE_IMAGE_KITTY, - "iterm", FF_LOGO_TYPE_IMAGE_ITERM, - "chafa", FF_LOGO_TYPE_IMAGE_CHAFA, - "raw", FF_LOGO_TYPE_IMAGE_RAW, - "none", FF_LOGO_TYPE_NONE, - NULL - ); - } - else if(startsWith(subkey, "-color-") && key[13] != '\0' && key[14] == '\0') // matches "--logo-color-*" - { - //Map the number to an array index, so that '1' -> 0, '2' -> 1, etc. - int index = (int)key[13] - 49; - - //Match only --logo-color-[1-9] - if(index < 0 || index >= FASTFETCH_LOGO_MAX_COLORS) - { - fprintf(stderr, "Error: invalid --color-[1-9] index: %c\n", key[13]); - exit(472); - } - - optionParseColor(key, value, &instance->config.logo.colors[index]); - } - else if(strcasecmp(subkey, "-width") == 0) - instance->config.logo.width = optionParseUInt32(key, value); - else if(strcasecmp(subkey, "-height") == 0) - instance->config.logo.height = optionParseUInt32(key, value); - else if(strcasecmp(subkey, "-padding") == 0) - { - uint32_t padding = optionParseUInt32(key, value); - instance->config.logo.paddingLeft = padding; - instance->config.logo.paddingRight = padding; - } - else if(strcasecmp(subkey, "-padding-top") == 0) - instance->config.logo.paddingTop = optionParseUInt32(key, value); - else if(strcasecmp(subkey, "-padding-left") == 0) - instance->config.logo.paddingLeft = optionParseUInt32(key, value); - else if(strcasecmp(subkey, "-padding-right") == 0) - instance->config.logo.paddingRight = optionParseUInt32(key, value); - else if(strcasecmp(subkey, "-print-remaining") == 0) - instance->config.logo.printRemaining = optionParseBoolean(value); - else if(strcasecmp(subkey, "-preserve-aspect-radio") == 0) - instance->config.logo.preserveAspectRadio = optionParseBoolean(value); - else - goto error; - } - else if(strcasecmp(key, "--file") == 0) - { - optionParseString(key, value, &instance->config.logo.source); - instance->config.logo.type = FF_LOGO_TYPE_FILE; - } - else if(strcasecmp(key, "--file-raw") == 0) - { - optionParseString(key, value, &instance->config.logo.source); - instance->config.logo.type = FF_LOGO_TYPE_FILE_RAW; - } - else if(strcasecmp(key, "--data") == 0) - { - optionParseString(key, value, &instance->config.logo.source); - instance->config.logo.type = FF_LOGO_TYPE_DATA; - } - else if(strcasecmp(key, "--data-raw") == 0) - { - optionParseString(key, value, &instance->config.logo.source); - instance->config.logo.type = FF_LOGO_TYPE_DATA_RAW; - } - else if(strcasecmp(key, "--sixel") == 0) - { - optionParseString(key, value, &instance->config.logo.source); - instance->config.logo.type = FF_LOGO_TYPE_IMAGE_SIXEL; - } - else if(strcasecmp(key, "--kitty") == 0) - { - optionParseString(key, value, &instance->config.logo.source); - instance->config.logo.type = FF_LOGO_TYPE_IMAGE_KITTY; - } - else if(strcasecmp(key, "--chafa") == 0) - { - optionParseString(key, value, &instance->config.logo.source); - instance->config.logo.type = FF_LOGO_TYPE_IMAGE_CHAFA; - } - else if(strcasecmp(key, "--iterm") == 0) - { - optionParseString(key, value, &instance->config.logo.source); - instance->config.logo.type = FF_LOGO_TYPE_IMAGE_ITERM; - } - else if(strcasecmp(key, "--raw") == 0) - { - optionParseString(key, value, &instance->config.logo.source); - instance->config.logo.type = FF_LOGO_TYPE_IMAGE_RAW; - } - else if(strcasecmp(key, "--chafa-fg-only") == 0) - instance->config.logo.chafaFgOnly = optionParseBoolean(value); - else if(strcasecmp(key, "--chafa-symbols") == 0) - optionParseString(key, value, &instance->config.logo.chafaSymbols); - else if(strcasecmp(key, "--chafa-canvas-mode") == 0) - instance->config.logo.chafaCanvasMode = optionParseUInt32(key, value); - else if(strcasecmp(key, "--chafa-color-space") == 0) - instance->config.logo.chafaColorSpace = optionParseUInt32(key, value); - else if(strcasecmp(key, "--chafa-dither-mode") == 0) - instance->config.logo.chafaDitherMode = optionParseUInt32(key, value); + else if(ffParseLogoCommandOptions(&instance->config.logo, key, value)) {} /////////////////// //Display options// @@ -1101,7 +915,7 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con else if(strcasecmp(key, "-s") == 0 || strcasecmp(key, "--structure") == 0) optionParseString(key, value, &data->structure); else if(strcasecmp(key, "--separator") == 0) - optionParseString(key, value, &instance->config.separator); + optionParseString(key, value, &instance->config.keyValueSeparator); else if(strcasecmp(key, "--color-keys") == 0) optionParseColor(key, value, &instance->config.colorKeys); else if(strcasecmp(key, "--color-title") == 0) @@ -1111,10 +925,6 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con optionParseColor(key, value, &instance->config.colorKeys); ffStrbufSet(&instance->config.colorTitle, &instance->config.colorKeys); } - else if(strcasecmp(key, "--set") == 0) - optionParseCustomValue(data, key, value, true); - else if(strcasecmp(key, "--set-keyless") == 0) - optionParseCustomValue(data, key, value, false); else if(strcasecmp(key, "--binary-prefix") == 0) { optionParseEnum(key, value, &instance->config.binaryPrefixType, @@ -1129,53 +939,55 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con //Module args options// /////////////////////// - else if(optionParseModuleArgs(key, value, "os", &instance->config.os)) {} - else if(optionParseModuleArgs(key, value, "host", &instance->config.host)) {} - else if(optionParseModuleArgs(key, value, "bios", &instance->config.bios)) {} - else if(optionParseModuleArgs(key, value, "board", &instance->config.board)) {} - else if(optionParseModuleArgs(key, value, "chassis", &instance->config.chassis)) {} - else if(optionParseModuleArgs(key, value, "kernel", &instance->config.kernel)) {} - else if(optionParseModuleArgs(key, value, "uptime", &instance->config.uptime)) {} - else if(optionParseModuleArgs(key, value, "processes", &instance->config.processes)) {} - else if(optionParseModuleArgs(key, value, "packages", &instance->config.packages)) {} - else if(optionParseModuleArgs(key, value, "shell", &instance->config.shell)) {} - else if(optionParseModuleArgs(key, value, "display", &instance->config.display)) {} - else if(optionParseModuleArgs(key, value, "brightness", &instance->config.brightness)) {} - else if(optionParseModuleArgs(key, value, "de", &instance->config.de)) {} - else if(optionParseModuleArgs(key, value, "wifi", &instance->config.wifi)) {} - else if(optionParseModuleArgs(key, value, "wm", &instance->config.wm)) {} - else if(optionParseModuleArgs(key, value, "wm-theme", &instance->config.wmTheme)) {} - else if(optionParseModuleArgs(key, value, "theme", &instance->config.theme)) {} - else if(optionParseModuleArgs(key, value, "icons", &instance->config.icons)) {} - else if(optionParseModuleArgs(key, value, "wallpaper", &instance->config.wallpaper)) {} - else if(optionParseModuleArgs(key, value, "font", &instance->config.font)) {} - else if(optionParseModuleArgs(key, value, "cursor", &instance->config.cursor)) {} - else if(optionParseModuleArgs(key, value, "terminal", &instance->config.terminal)) {} - else if(optionParseModuleArgs(key, value, "terminal-font", &instance->config.terminalFont)) {} - else if(optionParseModuleArgs(key, value, "cpu", &instance->config.cpu)) {} - else if(optionParseModuleArgs(key, value, "cpu-usage", &instance->config.cpuUsage)) {} - else if(optionParseModuleArgs(key, value, "gpu", &instance->config.gpu)) {} - else if(optionParseModuleArgs(key, value, "memory", &instance->config.memory)) {} - else if(optionParseModuleArgs(key, value, "swap", &instance->config.swap)) {} - else if(optionParseModuleArgs(key, value, "disk", &instance->config.disk)) {} - else if(optionParseModuleArgs(key, value, "battery", &instance->config.battery)) {} - else if(optionParseModuleArgs(key, value, "poweradapter", &instance->config.powerAdapter)) {} - else if(optionParseModuleArgs(key, value, "locale", &instance->config.locale)) {} - else if(optionParseModuleArgs(key, value, "localip", &instance->config.localIP)) {} - else if(optionParseModuleArgs(key, value, "publicip", &instance->config.publicIP)) {} - else if(optionParseModuleArgs(key, value, "weather", &instance->config.weather)) {} - else if(optionParseModuleArgs(key, value, "player", &instance->config.player)) {} - else if(optionParseModuleArgs(key, value, "media", &instance->config.media)) {} - else if(optionParseModuleArgs(key, value, "datetime", &instance->config.dateTime)) {} - else if(optionParseModuleArgs(key, value, "date", &instance->config.date)) {} - else if(optionParseModuleArgs(key, value, "time", &instance->config.time)) {} - else if(optionParseModuleArgs(key, value, "vulkan", &instance->config.vulkan)) {} - else if(optionParseModuleArgs(key, value, "opengl", &instance->config.openGL)) {} - else if(optionParseModuleArgs(key, value, "opencl", &instance->config.openCL)) {} - else if(optionParseModuleArgs(key, value, "users", &instance->config.users)) {} - else if(optionParseModuleArgs(key, value, "bluetooth", &instance->config.bluetooth)) {} - else if(optionParseModuleArgs(key, value, "sound", &instance->config.sound)) {} - else if(optionParseModuleArgs(key, value, "gamepad", &instance->config.gamepad)) {} + else if(ffParseOSCommandOptions(&instance->config.os, key, value)) {} + else if(ffParseHostCommandOptions(&instance->config.host, key, value)) {} + else if(ffParseOSCommandOptions(&instance->config.os, key, value)) {} + else if(ffParseBiosCommandOptions(&instance->config.bios, key, value)) {} + else if(ffParseBoardCommandOptions(&instance->config.board, key, value)) {} + else if(ffParseChassisCommandOptions(&instance->config.chassis, key, value)) {} + else if(ffParseCommandCommandOptions(&instance->config.command, key, value)) {} + else if(ffParseCustomCommandOptions(&instance->config.custom, key, value)) {} + else if(ffParseKernelCommandOptions(&instance->config.kernel, key, value)) {} + else if(ffParseUptimeCommandOptions(&instance->config.uptime, key, value)) {} + else if(ffParseProcessesCommandOptions(&instance->config.processes, key, value)) {} + else if(ffParsePackagesCommandOptions(&instance->config.packages, key, value)) {} + else if(ffParseShellCommandOptions(&instance->config.shell, key, value)) {} + else if(ffParseDisplayCommandOptions(&instance->config.display, key, value)) {} + else if(ffParseBrightnessCommandOptions(&instance->config.brightness, key, value)) {} + else if(ffParseDECommandOptions(&instance->config.de, key, value)) {} + else if(ffParseWifiCommandOptions(&instance->config.wifi, key, value)) {} + else if(ffParseWMCommandOptions(&instance->config.wm, key, value)) {} + else if(ffParseWMThemeCommandOptions(&instance->config.wmTheme, key, value)) {} + else if(ffParseThemeCommandOptions(&instance->config.theme, key, value)) {} + else if(ffParseIconsCommandOptions(&instance->config.icons, key, value)) {} + else if(ffParseWallpaperCommandOptions(&instance->config.wallpaper, key, value)) {} + else if(ffParseFontCommandOptions(&instance->config.font, key, value)) {} + else if(ffParseCursorCommandOptions(&instance->config.cursor, key, value)) {} + else if(ffParseTerminalCommandOptions(&instance->config.terminal, key, value)) {} + else if(ffParseTerminalFontCommandOptions(&instance->config.terminalFont, key, value)) {} + else if(ffParseCPUCommandOptions(&instance->config.cpu, key, value)) {} + else if(ffParseCPUUsageCommandOptions(&instance->config.cpuUsage, key, value)) {} + else if(ffParseGPUCommandOptions(&instance->config.gpu, key, value)) {} + else if(ffParseMemoryCommandOptions(&instance->config.memory, key, value)) {} + else if(ffParseSwapCommandOptions(&instance->config.swap, key, value)) {} + else if(ffParseDiskCommandOptions(&instance->config.disk, key, value)) {} + else if(ffParseBatteryCommandOptions(&instance->config.battery, key, value)) {} + else if(ffParsePowerAdapterCommandOptions(&instance->config.powerAdapter, key, value)) {} + else if(ffParseLocaleCommandOptions(&instance->config.locale, key, value)) {} + else if(ffParseLocalIpCommandOptions(&instance->config.localIP, key, value)) {} + else if(ffParsePublicIpCommandOptions(&instance->config.publicIP, key, value)) {} + else if(ffParseWeatherCommandOptions(&instance->config.weather, key, value)) {} + else if(ffParsePlayerCommandOptions(&instance->config.player, key, value)) {} + else if(ffParseMediaCommandOptions(&instance->config.media, key, value)) {} + else if(ffParseDateTimeCommandOptions(&instance->config.dateTime, key, value)) {} + else if(ffParseVulkanCommandOptions(&instance->config.vulkan, key, value)) {} + else if(ffParseOpenGLCommandOptions(&instance->config.openGL, key, value)) {} + else if(ffParseOpenCLCommandOptions(&instance->config.openCL, key, value)) {} + else if(ffParseUsersCommandOptions(&instance->config.users, key, value)) {} + else if(ffParseBluetoothCommandOptions(&instance->config.bluetooth, key, value)) {} + else if(ffParseSeparatorCommandOptions(&instance->config.separator, key, value)) {} + else if(ffParseSoundCommandOptions(&instance->config.sound, key, value)) {} + else if(ffParseGamepadCommandOptions(&instance->config.gamepad, key, value)) {} /////////////////// //Library options// @@ -1226,8 +1038,8 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con optionParseString(key, value, &instance->config.libOSMesa); else if(strcasecmp(subkey, "-opencl") == 0) optionParseString(key, value, &instance->config.libOpenCL); - else if(strcasecmp(subkey, "-cjson") == 0) - optionParseString(key, value, &instance->config.libcJSON); + else if(strcasecmp(subkey, "-jsonc") == 0) + optionParseString(key, value, &instance->config.libJSONC); else if(strcasecmp(subkey, "-wlanapi") == 0) optionParseString(key, value, &instance->config.libwlanapi); else if(strcasecmp(key, "-pulse") == 0) @@ -1242,113 +1054,8 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con //Module options// ////////////////// - else if(strcasecmp(key, "--cpu-temp") == 0) - instance->config.cpuTemp = optionParseBoolean(value); - else if(strcasecmp(key, "--gpu-temp") == 0) - instance->config.gpuTemp = optionParseBoolean(value); - else if(strcasecmp(key, "--gpu-force-vulkan") == 0) - instance->config.gpuForceVulkan = optionParseBoolean(value); - else if(strcasecmp(key, "--battery-temp") == 0) - instance->config.batteryTemp = optionParseBoolean(value); - else if(strcasecmp(key, "--gpu-hide-integrated") == 0) - instance->config.gpuHideIntegrated = optionParseBoolean(value); - else if(strcasecmp(key, "--gpu-hide-discrete") == 0) - instance->config.gpuHideDiscrete = optionParseBoolean(value); - else if(strcasecmp(key, "--title-fqdn") == 0) - instance->config.titleFQDN = optionParseBoolean(value); - else if(strcasecmp(key, "--shell-version") == 0) - instance->config.shellVersion = optionParseBoolean(value); - else if(strcasecmp(key, "--terminal-version") == 0) - instance->config.terminalVersion = optionParseBoolean(value); - else if(strcasecmp(key, "--disk-folders") == 0) - optionParseString(key, value, &instance->config.diskFolders); - else if(strcasecmp(key, "--disk-show-regular") == 0) - optionParseBoolean(value) ? (instance->config.diskShowTypes |= FF_DISK_TYPE_REGULAR_BIT) : (instance->config.diskShowTypes &= ~FF_DISK_TYPE_REGULAR_BIT); - else if(strcasecmp(key, "--disk-show-removable") == 0) - optionParseBoolean(value) ? (instance->config.diskShowTypes |= FF_DISK_TYPE_EXTERNAL_BIT) : (instance->config.diskShowTypes &= ~FF_DISK_TYPE_EXTERNAL_BIT); - else if(strcasecmp(key, "--disk-show-hidden") == 0) - optionParseBoolean(value) ? (instance->config.diskShowTypes |= FF_DISK_TYPE_HIDDEN_BIT) : (instance->config.diskShowTypes &= ~FF_DISK_TYPE_HIDDEN_BIT); - else if(strcasecmp(key, "--disk-show-subvolumes") == 0) - optionParseBoolean(value) ? (instance->config.diskShowTypes |= FF_DISK_TYPE_SUBVOLUME_BIT) : (instance->config.diskShowTypes &= ~FF_DISK_TYPE_SUBVOLUME_BIT); - else if(strcasecmp(key, "--disk-show-unknown") == 0) - optionParseBoolean(value) ? (instance->config.diskShowTypes |= FF_DISK_TYPE_UNKNOWN_BIT) : (instance->config.diskShowTypes &= ~FF_DISK_TYPE_UNKNOWN_BIT); - else if(strcasecmp(key, "--display-compact-type") == 0) - { - optionParseEnum(key, value, &instance->config.displayCompactType, - "none", FF_DISPLAY_COMPACT_TYPE_NONE, - "original", FF_DISPLAY_COMPACT_TYPE_ORIGINAL_BIT, - "scaled", FF_DISPLAY_COMPACT_TYPE_SCALED_BIT, - NULL); - } - else if(strcasecmp(key, "--display-precise-refresh-rate") == 0) - instance->config.displayPreciseRefreshRate = optionParseBoolean(value); - else if(strcasecmp(key, "--display-detect-name") == 0) - instance->config.displayDetectName = optionParseBoolean(value); - else if(strcasecmp(key, "--bluetooth-show-disconnected") == 0) - instance->config.bluetoothShowDisconnected = optionParseBoolean(value); - else if(strcasecmp(key, "--sound-type") == 0) - { - optionParseEnum(key, value, &instance->config.soundType, - "main", FF_SOUND_TYPE_MAIN, - "active", FF_SOUND_TYPE_ACTIVE, - "all", FF_SOUND_TYPE_ALL, - NULL - ); - } - else if(strcasecmp(key, "--battery-dir") == 0) - optionParseString(key, value, &instance->config.batteryDir); - else if(strcasecmp(key, "--separator-string") == 0) - optionParseString(key, value, &instance->config.separatorString); - else if(strcasecmp(key, "--localip-show-ipv4") == 0) - optionParseBoolean(value) ? (instance->config.localIpShowType |= FF_LOCALIP_TYPE_IPV4_BIT) : (instance->config.localIpShowType &= ~FF_LOCALIP_TYPE_IPV4_BIT); - else if(strcasecmp(key, "--localip-show-ipv6") == 0) - optionParseBoolean(value) ? (instance->config.localIpShowType |= FF_LOCALIP_TYPE_IPV6_BIT) : (instance->config.localIpShowType &= ~FF_LOCALIP_TYPE_IPV6_BIT); - else if(strcasecmp(key, "--localip-show-mac") == 0) - optionParseBoolean(value) ? (instance->config.localIpShowType |= FF_LOCALIP_TYPE_MAC_BIT) : (instance->config.localIpShowType &= ~FF_LOCALIP_TYPE_MAC_BIT); - else if(strcasecmp(key, "--localip-show-loop") == 0) - optionParseBoolean(value) ? (instance->config.localIpShowType |= FF_LOCALIP_TYPE_LOOP_BIT) : (instance->config.localIpShowType &= ~FF_LOCALIP_TYPE_LOOP_BIT); - else if(strcasecmp(key, "--localip-compact") == 0) - optionParseBoolean(value) ? (instance->config.localIpShowType |= FF_LOCALIP_TYPE_COMPACT_BIT) : (instance->config.localIpShowType &= ~FF_LOCALIP_TYPE_COMPACT_BIT); - else if(strcasecmp(key, "--localip-name-prefix") == 0) - optionParseString(key, value, &instance->config.localIpNamePrefix); - else if(strcasecmp(key, "--os-file") == 0) - optionParseString(key, value, &instance->config.osFile); - else if(strcasecmp(key, "--player-name") == 0) - optionParseString(key, value, &instance->config.playerName); - else if(strcasecmp(key, "--publicip-url") == 0) - optionParseString(key, value, &instance->config.publicIpUrl); - else if(strcasecmp(key, "--publicip-timeout") == 0) - instance->config.publicIpTimeout = optionParseUInt32(key, value); - else if(strcasecmp(key, "--weather-output-format") == 0) - optionParseString(key, value, &instance->config.weatherOutputFormat); - else if(strcasecmp(key, "--weather-timeout") == 0) - instance->config.weatherTimeout = optionParseUInt32(key, value); - else if(strcasecmp(key, "--gl") == 0) - { - optionParseEnum(key, value, &instance->config.glType, - "auto", FF_GL_TYPE_AUTO, - "egl", FF_GL_TYPE_EGL, - "glx", FF_GL_TYPE_GLX, - "osmesa", FF_GL_TYPE_OSMESA, - NULL - ); - } else if(strcasecmp(key, "--percent-type") == 0) instance->config.percentType = optionParseUInt32(key, value); - else if(strcasecmp(key, "--command-shell") == 0) - optionParseString(key, value, &instance->config.commandShell); - else if(strcasecmp(key, "--command-key") == 0) - { - FFstrbuf* result = (FFstrbuf*) ffListAdd(&instance->config.commandKeys); - ffStrbufInit(result); - optionParseString(key, value, result); - } - else if(strcasecmp(key, "--command-text") == 0) - { - FFstrbuf* result = (FFstrbuf*) ffListAdd(&instance->config.commandTexts); - ffStrbufInit(result); - optionParseString(key, value, result); - } ////////////////// //Unknown option// @@ -1399,119 +1106,112 @@ static void parseArguments(FFinstance* instance, FFdata* data, int argc, const c } } -static void parseStructureCommand(FFinstance* instance, FFdata* data, const char* line) +static void parseStructureCommand(FFinstance* instance, const char* line) { - CustomValue* customValue = ffValuestoreGet(&data->customValues, line); - if(customValue != NULL) - { - ffPrintCustom(instance, customValue->printKey ? line : NULL, customValue->value.chars); - return; - } - - if(strcasecmp(line, "break") == 0) + if(strcasecmp(line, FF_BREAK_MODULE_NAME) == 0) ffPrintBreak(instance); - else if(strcasecmp(line, "title") == 0) - ffPrintTitle(instance); - else if(strcasecmp(line, "separator") == 0) - ffPrintSeparator(instance); - else if(strcasecmp(line, "os") == 0) - ffPrintOS(instance); - else if(strcasecmp(line, "host") == 0) - ffPrintHost(instance); - else if(strcasecmp(line, "bios") == 0) - ffPrintBios(instance); - else if(strcasecmp(line, "board") == 0) - ffPrintBoard(instance); - else if(strcasecmp(line, "brightness") == 0) - ffPrintBrightness(instance); - else if(strcasecmp(line, "chassis") == 0) - ffPrintChassis(instance); - else if(strcasecmp(line, "kernel") == 0) - ffPrintKernel(instance); - else if(strcasecmp(line, "uptime") == 0) - ffPrintUptime(instance); - else if(strcasecmp(line, "processes") == 0) - ffPrintProcesses(instance); - else if(strcasecmp(line, "packages") == 0) - ffPrintPackages(instance); - else if(strcasecmp(line, "shell") == 0) - ffPrintShell(instance); - else if(strcasecmp(line, "display") == 0) - ffPrintDisplay(instance); - else if(strcasecmp(line, "desktopenvironment") == 0 || strcasecmp(line, "de") == 0) - ffPrintDesktopEnvironment(instance); - else if(strcasecmp(line, "windowmanager") == 0 || strcasecmp(line, "wm") == 0) - ffPrintWM(instance); - else if(strcasecmp(line, "theme") == 0) - ffPrintTheme(instance); - else if(strcasecmp(line, "wmtheme") == 0) - ffPrintWMTheme(instance); - else if(strcasecmp(line, "icons") == 0) - ffPrintIcons(instance); - else if(strcasecmp(line, "wallpaper") == 0) - ffPrintWallpaper(instance); - else if(strcasecmp(line, "font") == 0) - ffPrintFont(instance); - else if(strcasecmp(line, "cursor") == 0) - ffPrintCursor(instance); - else if(strcasecmp(line, "terminal") == 0) - ffPrintTerminal(instance); - else if(strcasecmp(line, "terminalfont") == 0) - ffPrintTerminalFont(instance); - else if(strcasecmp(line, "cpu") == 0) - ffPrintCPU(instance); - else if(strcasecmp(line, "cpuusage") == 0) - ffPrintCPUUsage(instance); - else if(strcasecmp(line, "gpu") == 0) - ffPrintGPU(instance); - else if(strcasecmp(line, "memory") == 0) - ffPrintMemory(instance); - else if(strcasecmp(line, "swap") == 0) - ffPrintSwap(instance); - else if(strcasecmp(line, "disk") == 0) - ffPrintDisk(instance); - else if(strcasecmp(line, "battery") == 0) - ffPrintBattery(instance); - else if(strcasecmp(line, "poweradapter") == 0) - ffPrintPowerAdapter(instance); - else if(strcasecmp(line, "locale") == 0) - ffPrintLocale(instance); + else if(strcasecmp(line, FF_TITLE_MODULE_NAME) == 0) + ffPrintTitle(instance, &instance->config.title); + else if(strcasecmp(line, FF_SEPARATOR_MODULE_NAME) == 0) + ffPrintSeparator(instance, &instance->config.separator); + else if(strcasecmp(line, FF_OS_MODULE_NAME) == 0) + ffPrintOS(instance, &instance->config.os); + else if(strcasecmp(line, FF_HOST_MODULE_NAME) == 0) + ffPrintHost(instance, &instance->config.host); + else if(strcasecmp(line, FF_BIOS_MODULE_NAME) == 0) + ffPrintBios(instance, &instance->config.bios); + else if(strcasecmp(line, FF_BOARD_MODULE_NAME) == 0) + ffPrintBoard(instance, &instance->config.board); + else if(strcasecmp(line, FF_BRIGHTNESS_MODULE_NAME) == 0) + ffPrintBrightness(instance, &instance->config.brightness); + else if(strcasecmp(line, FF_CHASSIS_MODULE_NAME) == 0) + ffPrintChassis(instance, &instance->config.chassis); + else if(strcasecmp(line, FF_KERNEL_MODULE_NAME) == 0) + ffPrintKernel(instance, &instance->config.kernel); + else if(strcasecmp(line, FF_PROCESSES_MODULE_NAME) == 0) + ffPrintProcesses(instance, &instance->config.processes); + else if(strcasecmp(line, FF_UPTIME_MODULE_NAME) == 0) + ffPrintUptime(instance, &instance->config.uptime); + else if(strcasecmp(line, FF_PACKAGES_MODULE_NAME) == 0) + ffPrintPackages(instance, &instance->config.packages); + else if(strcasecmp(line, FF_SHELL_MODULE_NAME) == 0) + ffPrintShell(instance, &instance->config.shell); + else if(strcasecmp(line, FF_DISPLAY_MODULE_NAME) == 0) + ffPrintDisplay(instance, &instance->config.display); + else if(strcasecmp(line, FF_DE_MODULE_NAME) == 0) + ffPrintDE(instance, &instance->config.de); + else if(strcasecmp(line, FF_WM_MODULE_NAME) == 0) + ffPrintWM(instance, &instance->config.wm); + else if(strcasecmp(line, FF_THEME_MODULE_NAME) == 0) + ffPrintTheme(instance, &instance->config.theme); + else if(strcasecmp(line, FF_WMTHEME_MODULE_NAME) == 0) + ffPrintWMTheme(instance, &instance->config.wmTheme); + else if(strcasecmp(line, FF_ICONS_MODULE_NAME) == 0) + ffPrintIcons(instance, &instance->config.icons); + else if(strcasecmp(line, FF_WALLPAPER_MODULE_NAME) == 0) + ffPrintWallpaper(instance, &instance->config.wallpaper); + else if(strcasecmp(line, FF_FONT_MODULE_NAME) == 0) + ffPrintFont(instance, &instance->config.font); + else if(strcasecmp(line, FF_CURSOR_MODULE_NAME) == 0) + ffPrintCursor(instance, &instance->config.cursor); + else if(strcasecmp(line, FF_TERMINAL_MODULE_NAME) == 0) + ffPrintTerminal(instance, &instance->config.terminal); + else if(strcasecmp(line, FF_TERMINALFONT_MODULE_NAME) == 0) + ffPrintTerminalFont(instance, &instance->config.terminalFont); + else if(strcasecmp(line, FF_CPU_MODULE_NAME) == 0) + ffPrintCPU(instance, &instance->config.cpu); + else if(strcasecmp(line, FF_CPUUSAGE_MODULE_NAME) == 0) + ffPrintCPUUsage(instance, &instance->config.cpuUsage); + else if(strcasecmp(line, FF_CUSTOM_MODULE_NAME) == 0) + ffPrintCustom(instance, &instance->config.custom); + else if(strcasecmp(line, FF_GPU_MODULE_NAME) == 0) + ffPrintGPU(instance, &instance->config.gpu); + else if(strcasecmp(line, FF_MEMORY_MODULE_NAME) == 0) + ffPrintMemory(instance, &instance->config.memory); + else if(strcasecmp(line, FF_SWAP_MODULE_NAME) == 0) + ffPrintSwap(instance, &instance->config.swap); + else if(strcasecmp(line, FF_DISK_MODULE_NAME) == 0) + ffPrintDisk(instance, &instance->config.disk); + else if(strcasecmp(line, FF_BATTERY_MODULE_NAME) == 0) + ffPrintBattery(instance, &instance->config.battery); + else if(strcasecmp(line, FF_POWERADAPTER_MODULE_NAME) == 0) + ffPrintPowerAdapter(instance, &instance->config.powerAdapter); + else if(strcasecmp(line, FF_LOCALE_MODULE_NAME) == 0) + ffPrintLocale(instance, &instance->config.locale); else if(strcasecmp(line, "localip") == 0) - ffPrintLocalIp(instance); - else if(strcasecmp(line, "publicip") == 0) - ffPrintPublicIp(instance); - else if(strcasecmp(line, "wifi") == 0) - ffPrintWifi(instance); - else if(strcasecmp(line, "weather") == 0) - ffPrintWeather(instance); - else if(strcasecmp(line, "player") == 0) - ffPrintPlayer(instance); - else if(strcasecmp(line, "media") == 0) - ffPrintMedia(instance); - else if(strcasecmp(line, "datetime") == 0) - ffPrintDateTime(instance); - else if(strcasecmp(line, "date") == 0) - ffPrintDate(instance); - else if(strcasecmp(line, "time") == 0) - ffPrintTime(instance); - else if(strcasecmp(line, "colors") == 0) + ffPrintLocalIp(instance, &instance->config.localIP); + else if(strcasecmp(line, FF_PUBLICIP_MODULE_NAME) == 0) + ffPrintPublicIp(instance, &instance->config.publicIP); + else if(strcasecmp(line, FF_WIFI_MODULE_NAME) == 0) + ffPrintWifi(instance, &instance->config.wifi); + else if(strcasecmp(line, FF_WEATHER_MODULE_NAME) == 0) + ffPrintWeather(instance, &instance->config.weather); + else if(strcasecmp(line, FF_PLAYER_MODULE_NAME) == 0) + ffPrintPlayer(instance, &instance->config.player); + else if(strcasecmp(line, FF_MEDIA_MODULE_NAME) == 0) + ffPrintMedia(instance, &instance->config.media); + else if(strcasecmp(line, FF_DATETIME_MODULE_NAME) == 0) + ffPrintDateTime(instance, &instance->config.dateTime); + else if(strcasecmp(line, FF_COLORS_MODULE_NAME) == 0) ffPrintColors(instance); - else if(strcasecmp(line, "vulkan") == 0) - ffPrintVulkan(instance); - else if(strcasecmp(line, "opengl") == 0) - ffPrintOpenGL(instance); - else if(strcasecmp(line, "opencl") == 0) - ffPrintOpenCL(instance); - else if(strcasecmp(line, "users") == 0) - ffPrintUsers(instance); - else if(strcasecmp(line, "command") == 0) - ffPrintCommand(instance); - else if(strcasecmp(line, "bluetooth") == 0) - ffPrintBluetooth(instance); - else if(strcasecmp(line, "sound") == 0) - ffPrintSound(instance); - else if(strcasecmp(line, "gamepad") == 0) - ffPrintGamepad(instance); + else if(strcasecmp(line, FF_VULKAN_MODULE_NAME) == 0) + ffPrintVulkan(instance, &instance->config.vulkan); + else if(strcasecmp(line, FF_OPENGL_MODULE_NAME) == 0) + ffPrintOpenGL(instance, &instance->config.openGL); + else if(strcasecmp(line, FF_OPENCL_MODULE_NAME) == 0) + ffPrintOpenCL(instance, &instance->config.openCL); + else if(strcasecmp(line, FF_USERS_MODULE_NAME) == 0) + ffPrintUsers(instance, &instance->config.users); + else if(strcasecmp(line, FF_COMMAND_MODULE_NAME) == 0) + ffPrintCommand(instance, &instance->config.command); + else if(strcasecmp(line, FF_BLUETOOTH_MODULE_NAME) == 0) + ffPrintBluetooth(instance, &instance->config.bluetooth); + else if(strcasecmp(line, FF_SOUND_MODULE_NAME) == 0) + ffPrintSound(instance, &instance->config.sound); + else if(strcasecmp(line, FF_GAMEPAD_MODULE_NAME) == 0) + ffPrintGamepad(instance, &instance->config.gamepad); + else if(strcasecmp(line, FF_JSONCONFIG_MODULE_NAME) == 0) + ffPrintJsonConfig(instance); else ffPrintErrorString(instance, line, 0, NULL, NULL, ""); } @@ -1523,7 +1223,6 @@ int main(int argc, const char** argv) //Data stores things only needed for the configuration of fastfetch FFdata data; - ffValuestoreInit(&data.customValues, sizeof(CustomValue)); ffStrbufInitA(&data.structure, 256); data.loadUserConfig = true; @@ -1535,16 +1234,16 @@ int main(int argc, const char** argv) if(data.structure.length == 0) ffStrbufAppendS(&data.structure, FASTFETCH_DATATEXT_STRUCTURE); - if(ffStrbufContainIgnCaseS(&data.structure, "CPUUsage")) + if(ffStrbufContainIgnCaseS(&data.structure, FF_CPUUSAGE_MODULE_NAME)) ffPrepareCPUUsage(); if(instance.config.multithreading) { - if(ffStrbufContainIgnCaseS(&data.structure, "PublicIp")) - ffPreparePublicIp(&instance); + if(ffStrbufContainIgnCaseS(&data.structure, FF_PUBLICIP_MODULE_NAME)) + ffPreparePublicIp(&instance.config.publicIP); - if(ffStrbufContainIgnCaseS(&data.structure, "Weather")) - ffPrepareWeather(&instance); + if(ffStrbufContainIgnCaseS(&data.structure, FF_WEATHER_MODULE_NAME)) + ffPrepareWeather(&instance.config.weather); } ffStart(&instance); @@ -1564,7 +1263,7 @@ int main(int argc, const char** argv) if(__builtin_expect(instance.config.stat, false)) ms = ffTimeGetTick(); - parseStructureCommand(&instance, &data, data.structure.chars + startIndex); + parseStructureCommand(&instance, data.structure.chars + startIndex); if(__builtin_expect(instance.config.stat, false)) { @@ -1586,7 +1285,6 @@ int main(int argc, const char** argv) ffFinish(&instance); ffStrbufDestroy(&data.structure); - ffValuestoreDestroy(&data.customValues); ffDestroyInstance(&instance); } diff --git a/src/fastfetch.h b/src/fastfetch.h index 8c1114cef..68506ede7 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -16,54 +16,8 @@ static inline void ffUnused(int dummy, ...) { (void) dummy; } #define FF_UNUSED(...) ffUnused(0, __VA_ARGS__); #define FF_MAYBE_UNUSED __attribute__ ((__unused__)) -#define FASTFETCH_LOGO_MAX_COLORS 9 //two digits would make parsing much more complicated (index 1 - 9) - -typedef enum FFLogoType -{ - FF_LOGO_TYPE_AUTO, //if something is given, first try builtin, then file. Otherwise detect logo - FF_LOGO_TYPE_BUILTIN, //builtin ascii art - FF_LOGO_TYPE_FILE, //text file, printed with color code replacement - FF_LOGO_TYPE_FILE_RAW, //text file, printed as is - FF_LOGO_TYPE_DATA, //text data, printed with color code replacement - FF_LOGO_TYPE_DATA_RAW, //text data, printed as is - FF_LOGO_TYPE_IMAGE_SIXEL, //image file, printed as sixel codes. - FF_LOGO_TYPE_IMAGE_KITTY, //image file, printed as kitty graphics protocol - FF_LOGO_TYPE_IMAGE_ITERM, //image file, printed as iterm graphics protocol - FF_LOGO_TYPE_IMAGE_CHAFA, //image file, printed as ascii art using libchafa - FF_LOGO_TYPE_IMAGE_RAW, //image file, printed as raw binary string - FF_LOGO_TYPE_NONE, //--logo none -} FFLogoType; - -typedef enum FFSoundType -{ - FF_SOUND_TYPE_MAIN, - FF_SOUND_TYPE_ACTIVE, - FF_SOUND_TYPE_ALL, -} FFSoundType; - -typedef enum FFDisplayCompactType -{ - FF_DISPLAY_COMPACT_TYPE_NONE = 0, - FF_DISPLAY_COMPACT_TYPE_ORIGINAL_BIT = 1 << 0, - FF_DISPLAY_COMPACT_TYPE_SCALED_BIT = 1 << 1, -} FFDisplayCompactType; - -typedef enum FFLocalIpCompactType -{ - FF_LOCALIP_COMPACT_TYPE_NONE, - FF_LOCALIP_COMPACT_TYPE_MULTILINE, - FF_LOCALIP_COMPACT_TYPE_ONELINE, -} FFLocalIpCompactType; - -typedef enum FFDiskType -{ - FF_DISK_TYPE_NONE = 0, - FF_DISK_TYPE_REGULAR_BIT = 1 << 0, - FF_DISK_TYPE_HIDDEN_BIT = 1 << 1, - FF_DISK_TYPE_EXTERNAL_BIT = 1 << 2, - FF_DISK_TYPE_SUBVOLUME_BIT = 1 << 3, - FF_DISK_TYPE_UNKNOWN_BIT = 1 << 4, -} FFDiskType; +#include "modules/options.h" +#include "logo/option.h" typedef enum FFBinaryPrefixType { @@ -72,59 +26,15 @@ typedef enum FFBinaryPrefixType FF_BINARY_PREFIX_TYPE_JEDEC, // 1024 Bytes = 1 kB, 1024 K = 1 MB, ... } FFBinaryPrefixType; -typedef enum FFGLType -{ - FF_GL_TYPE_AUTO, - FF_GL_TYPE_EGL, - FF_GL_TYPE_GLX, - FF_GL_TYPE_OSMESA -} FFGLType; - -typedef struct FFModuleArgs -{ - FFstrbuf key; - FFstrbuf outputFormat; - FFstrbuf errorFormat; -} FFModuleArgs; - -typedef enum FFLocalIpType -{ - FF_LOCALIP_TYPE_NONE, - FF_LOCALIP_TYPE_LOOP_BIT = 1 << 0, - FF_LOCALIP_TYPE_IPV4_BIT = 1 << 1, - FF_LOCALIP_TYPE_IPV6_BIT = 1 << 2, - FF_LOCALIP_TYPE_MAC_BIT = 1 << 3, - - FF_LOCALIP_TYPE_COMPACT_BIT = 1 << 10, -} FFLocalIpType; - typedef struct FFconfig { - struct - { - FFstrbuf source; - FFLogoType type; - FFstrbuf colors[FASTFETCH_LOGO_MAX_COLORS]; - uint32_t width; - uint32_t height; - uint32_t paddingTop; - uint32_t paddingLeft; - uint32_t paddingRight; - bool printRemaining; - bool preserveAspectRadio; - - bool chafaFgOnly; - FFstrbuf chafaSymbols; - uint32_t chafaCanvasMode; - uint32_t chafaColorSpace; - uint32_t chafaDitherMode; - } logo; + FFLogoOptions logo; //If one of those is empty, ffLogoPrint will set them FFstrbuf colorKeys; FFstrbuf colorTitle; - FFstrbuf separator; + FFstrbuf keyValueSeparator; bool showErrors; bool recache; @@ -133,58 +43,59 @@ typedef struct FFconfig bool hideCursor; bool escapeBedrock; FFBinaryPrefixType binaryPrefixType; - FFGLType glType; bool pipe; //disables logo and all escape sequences bool multithreading; bool stat; - FFModuleArgs os; - FFModuleArgs host; - FFModuleArgs bios; - FFModuleArgs board; - FFModuleArgs brightness; - FFModuleArgs chassis; - FFModuleArgs kernel; - FFModuleArgs uptime; - FFModuleArgs processes; - FFModuleArgs packages; - FFModuleArgs shell; - FFModuleArgs display; - FFModuleArgs de; - FFModuleArgs wallpaper; - FFModuleArgs wifi; - FFModuleArgs wm; - FFModuleArgs wmTheme; - FFModuleArgs theme; - FFModuleArgs icons; - FFModuleArgs font; - FFModuleArgs cursor; - FFModuleArgs terminal; - FFModuleArgs terminalFont; - FFModuleArgs cpu; - FFModuleArgs cpuUsage; - FFModuleArgs gpu; - FFModuleArgs memory; - FFModuleArgs swap; - FFModuleArgs disk; - FFModuleArgs battery; - FFModuleArgs powerAdapter; - FFModuleArgs locale; - FFModuleArgs localIP; - FFModuleArgs publicIP; - FFModuleArgs weather; - FFModuleArgs player; - FFModuleArgs media; - FFModuleArgs dateTime; - FFModuleArgs date; - FFModuleArgs time; - FFModuleArgs vulkan; - FFModuleArgs openGL; - FFModuleArgs openCL; - FFModuleArgs users; - FFModuleArgs bluetooth; - FFModuleArgs sound; - FFModuleArgs gamepad; + FFTitleOptions title; + FFOSOptions os; + FFHostOptions host; + FFBiosOptions bios; + FFBoardOptions board; + FFBrightnessOptions brightness; + FFChassisOptions chassis; + FFCommandOptions command; + FFKernelOptions kernel; + FFUptimeOptions uptime; + FFProcessesOptions processes; + FFPackagesOptions packages; + FFShellOptions shell; + FFDisplayOptions display; + FFDEOptions de; + FFWallpaperOptions wallpaper; + FFWifiOptions wifi; + FFWMOptions wm; + FFWMThemeOptions wmTheme; + FFThemeOptions theme; + FFIconsOptions icons; + FFFontOptions font; + FFCursorOptions cursor; + FFTerminalOptions terminal; + FFTerminalFontOptions terminalFont; + FFCPUOptions cpu; + FFCPUUsageOptions cpuUsage; + FFCustomOptions custom; + FFGPUOptions gpu; + FFMemoryOptions memory; + FFSwapOptions swap; + FFDiskOptions disk; + FFBatteryOptions battery; + FFPowerAdapterOptions powerAdapter; + FFLocaleOptions locale; + FFLocalIpOptions localIP; + FFPublicIpOptions publicIP; + FFWeatherOptions weather; + FFPlayerOptions player; + FFMediaOptions media; + FFDateTimeOptions dateTime; + FFVulkanOptions vulkan; + FFOpenGLOptions openGL; + FFOpenCLOptions openCL; + FFUsersOptions users; + FFBluetoothOptions bluetooth; + FFSeparatorOptions separator; + FFSoundOptions sound; + FFGamepadOptions gamepad; FFstrbuf libPCI; FFstrbuf libVulkan; @@ -206,58 +117,15 @@ typedef struct FFconfig FFstrbuf libGLX; FFstrbuf libOSMesa; FFstrbuf libOpenCL; - FFstrbuf libcJSON; + FFstrbuf libJSONC; FFstrbuf libfreetype; FFstrbuf libPulse; FFstrbuf libwlanapi; FFstrbuf libnm; - bool cpuTemp; - bool gpuTemp; - bool gpuForceVulkan; - bool batteryTemp; - - bool gpuHideIntegrated; - bool gpuHideDiscrete; - - bool titleFQDN; - - bool shellVersion; - bool terminalVersion; - - FFstrbuf diskFolders; - FFDiskType diskShowTypes; - - FFDisplayCompactType displayCompactType; - bool displayDetectName; - bool displayPreciseRefreshRate; - - bool bluetoothShowDisconnected; - - FFstrbuf batteryDir; - - FFstrbuf separatorString; - - FFstrbuf localIpNamePrefix; - FFLocalIpType localIpShowType; - - FFstrbuf publicIpUrl; - uint32_t publicIpTimeout; - - FFstrbuf weatherOutputFormat; - uint32_t weatherTimeout; - - FFSoundType soundType; - - FFstrbuf osFile; - - FFstrbuf playerName; - uint32_t percentType; - FFstrbuf commandShell; - FFlist commandKeys; - FFlist commandTexts; + bool jsonConfig; } FFconfig; typedef struct FFstate @@ -265,6 +133,7 @@ typedef struct FFstate uint32_t logoWidth; uint32_t logoHeight; uint32_t keysHeight; + uint32_t titleLength; FFPlatform platform; } FFstate; @@ -299,71 +168,4 @@ void ffLogoBuiltinPrint(FFinstance* instance); void ffLogoBuiltinList(); void ffLogoBuiltinListAutocompletion(); -////////////////////// -// Module functions // -////////////////////// - -//Common - -void ffPrintDateTimeFormat(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs); -void ffPrepareCPUUsage(); -void ffPreparePublicIp(FFinstance* instance); -void ffPrepareWeather(FFinstance* instance); - -//Printing - -void ffPrintCustom(FFinstance* instance, const char* key, const char* value); -void ffPrintBreak(FFinstance* instance); -void ffPrintTitle(FFinstance* instance); -void ffPrintSeparator(FFinstance* instance); -void ffPrintOS(FFinstance* instance); -void ffPrintHost(FFinstance* instance); -void ffPrintBios(FFinstance* instance); -void ffPrintBoard(FFinstance* instance); -void ffPrintChassis(FFinstance* instance); -void ffPrintKernel(FFinstance* instance); -void ffPrintUptime(FFinstance* instance); -void ffPrintProcesses(FFinstance* instance); -void ffPrintPackages(FFinstance* instance); -void ffPrintShell(FFinstance* instance); -void ffPrintDisplay(FFinstance* instance); -void ffPrintBrightness(FFinstance* instance); -void ffPrintDesktopEnvironment(FFinstance* instance); -void ffPrintWM(FFinstance* instance); -void ffPrintWMTheme(FFinstance* instance); -void ffPrintTheme(FFinstance* instance); -void ffPrintIcons(FFinstance* instance); -void ffPrintWallpaper(FFinstance* instance); -void ffPrintFont(FFinstance* instance); -void ffPrintCursor(FFinstance* instance); -void ffPrintTerminal(FFinstance* instance); -void ffPrintTerminalFont(FFinstance* instance); -void ffPrintCPU(FFinstance* instance); -void ffPrintCPUUsage(FFinstance* instance); -void ffPrintGPU(FFinstance* instance); -void ffPrintMemory(FFinstance* instance); -void ffPrintSwap(FFinstance* instance); -void ffPrintDisk(FFinstance* instance); -void ffPrintBattery(FFinstance* instance); -void ffPrintPowerAdapter(FFinstance* instance); -void ffPrintLocale(FFinstance* instance); -void ffPrintPlayer(FFinstance* instance); -void ffPrintMedia(FFinstance* instance); -void ffPrintDateTime(FFinstance* instance); -void ffPrintDate(FFinstance* instance); -void ffPrintTime(FFinstance* instance); -void ffPrintLocalIp(FFinstance* instance); -void ffPrintPublicIp(FFinstance* instance); -void ffPrintWeather(FFinstance* instance); -void ffPrintWifi(FFinstance* instance); -void ffPrintColors(FFinstance* instance); -void ffPrintVulkan(FFinstance* instance); -void ffPrintOpenGL(FFinstance* instance); -void ffPrintOpenCL(FFinstance* instance); -void ffPrintUsers(FFinstance* instance); -void ffPrintCommand(FFinstance* instance); -void ffPrintBluetooth(FFinstance* instance); -void ffPrintSound(FFinstance* instance); -void ffPrintGamepad(FFinstance* instance); - #endif diff --git a/src/flashfetch.c b/src/flashfetch.c index 8737c8fcf..d09a7c2f4 100644 --- a/src/flashfetch.c +++ b/src/flashfetch.c @@ -1,5 +1,7 @@ #include "fastfetch.h" +#include "modules/modules.h" + int main(int argc, char** argv) { //Disable compiler warnings @@ -11,60 +13,60 @@ int main(int argc, char** argv) //Modify instance.config here // ffPrepareCPUUsage(); - // ffPreparePublicIp(&instance); + // ffPreparePublicIp(&instance.config.publicIP); // ffPrepareWeather(&instance); //Does things like starting detection threads, disabling line wrap, etc ffStart(&instance); //Printing - ffPrintTitle(&instance); - ffPrintSeparator(&instance); - ffPrintOS(&instance); - ffPrintHost(&instance); - //ffPrintBios(&instance); - //ffPrintBoard(&instance); - //ffPrintChassis(&instance); - ffPrintKernel(&instance); - ffPrintUptime(&instance); - //ffPrintProcesses(&instance); - ffPrintPackages(&instance); - ffPrintShell(&instance); - ffPrintDisplay(&instance); + ffPrintTitle(&instance, &instance.config.title); + ffPrintSeparator(&instance, &instance.config.separator); + ffPrintOS(&instance, &instance.config.os); + ffPrintHost(&instance, &instance.config.host); + //ffPrintBios(&instance, &instance.config.bios); + //ffPrintBoard(&instance, &instance.config.board); + //ffPrintChassis(&instance, &instance.config.chassis); + ffPrintKernel(&instance, &instance.config.kernel); + //ffPrintProcesses(&instance, &instance.config.processes); + ffPrintUptime(&instance, &instance.config.uptime); + ffPrintPackages(&instance, &instance.config.packages); + ffPrintShell(&instance, &instance.config.shell); + ffPrintDisplay(&instance, &instance.config.display); // ffPrintBrightness(&instance); - ffPrintDesktopEnvironment(&instance); - ffPrintWM(&instance); - ffPrintWMTheme(&instance); - ffPrintTheme(&instance); - ffPrintIcons(&instance); - ffPrintFont(&instance); - ffPrintCursor(&instance); - ffPrintTerminal(&instance); - ffPrintTerminalFont(&instance); - ffPrintCPU(&instance); - ffPrintGPU(&instance); - ffPrintMemory(&instance); - //ffPrintSwap(&instance); - ffPrintDisk(&instance); - ffPrintBattery(&instance); - ffPrintPowerAdapter(&instance); - //ffPrintPlayer(&instance); - //ffPrintMedia(&instance); + ffPrintDE(&instance, &instance.config.de); + ffPrintWM(&instance, &instance.config.wm); + ffPrintWMTheme(&instance, &instance.config.wmTheme); + ffPrintTheme(&instance, &instance.config.theme); + ffPrintIcons(&instance, &instance.config.icons); + ffPrintFont(&instance, &instance.config.font); + ffPrintCursor(&instance, &instance.config.cursor); + ffPrintTerminal(&instance, &instance.config.terminal); + ffPrintTerminalFont(&instance, &instance.config.terminalFont); + ffPrintCPU(&instance, &instance.config.cpu); + ffPrintGPU(&instance, &instance.config.gpu); + ffPrintMemory(&instance, &instance.config.memory); + ffPrintSwap(&instance, &instance.config.swap); + ffPrintDisk(&instance, &instance.config.disk); + ffPrintBattery(&instance, &instance.config.battery); + ffPrintPowerAdapter(&instance, &instance.config.powerAdapter); + //ffPrintPlayer(&instance, &instance.config.player); + //ffPrintMedia(&instance, &instance.config.media); //ffPrintLocalIp(&instance); - //ffPrintPublicIp(&instance); + //ffPrintPublicIp(&instance, &instance.config.publicIp); //ffPrintWifi(&instance); - //ffPrintCPUUsage(&instance); - ffPrintLocale(&instance); + //ffPrintCPUUsage(&instance, &instance.config.cpuUsage); + ffPrintLocale(&instance, &instance.config.locale); //ffPrintDateTime(&instance); //ffPrintDate(&instance); //ffPrintTime(&instance); - //ffPrintVulkan(&instance); - //ffPrintOpenGL(&instance); - //ffPrintOpenCL(&instance); - //ffPrintUsers(&instance); - //ffPrintWeather(&instance); + //ffPrintVulkan(&instance, &instance.config.vulkan); + //ffPrintOpenGL(&instance, &instance.config.openGL); + //ffPrintOpenCL(&instance, &instance.config.openCL); + //ffPrintUsers(&instance, &instance.config.users); + //ffPrintWeather(&instance, &instance.config.weather); //ffPrintBluetooth(&instance); - //ffPrintSound(&instance); + //ffPrintSound(&instance, &instance.config.sound); //ffPrintGamepad(&instance); ffPrintBreak(&instance); ffPrintColors(&instance); diff --git a/src/logo/image/image.c b/src/logo/image/image.c index 9da6584fc..4a033c2b4 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -12,8 +12,7 @@ static FFstrbuf base64Encode(FFstrbuf* in) { const char* base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - FFstrbuf out; - ffStrbufInitA(&out, 8 * (1 + in->length / 6)); + FFstrbuf out = ffStrbufCreateA(8 * (1 + in->length / 6)); unsigned val = 0; int valb = -6; @@ -41,8 +40,7 @@ static bool printImageIterm(FFinstance* instance) return false; } - FFstrbuf buf; - ffStrbufInit(&buf); + FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate(); if(!ffAppendFileBuffer(instance->config.logo.source.chars, &buf)) { fputs("Logo: Failed to load image file\n", stderr); @@ -51,7 +49,8 @@ static bool printImageIterm(FFinstance* instance) ffPrintCharTimes(' ', instance->config.logo.paddingLeft); ffPrintCharTimes('\n', instance->config.logo.paddingTop); - FFstrbuf base64 = base64Encode(&buf); + + FF_STRBUF_AUTO_DESTROY base64 = base64Encode(&buf); instance->state.logoWidth = instance->config.logo.width + instance->config.logo.paddingLeft + instance->config.logo.paddingRight; instance->state.logoHeight = instance->config.logo.paddingTop + instance->config.logo.height; printf("\033]1337;File=inline=1;width=%u;height=%u;preserveAspectRatio=%u:%s\a\033[9999999D\n\033[%uA", @@ -62,9 +61,6 @@ static bool printImageIterm(FFinstance* instance) (unsigned) instance->state.logoHeight ); - ffStrbufDestroy(&buf); - ffStrbufDestroy(&base64); - return true; } @@ -289,8 +285,7 @@ static bool printImageKitty(FFinstance* instance, FFLogoRequestData* requestData if(!checkAllocationResult(chars, length)) return false; - FFstrbuf result; - ffStrbufInitA(&result, (uint32_t) (length + 1024)); + FF_STRBUF_AUTO_DESTROY result = ffStrbufCreateA((uint32_t) (length + 1024)); const char* currentPos = chars; size_t remainingLength = length; @@ -304,7 +299,6 @@ static bool printImageKitty(FFinstance* instance, FFLogoRequestData* requestData printImagePixels(instance, requestData, &result, isCompressed ? FF_CACHE_FILE_KITTY_COMPRESSED : FF_CACHE_FILE_KITTY_UNCOMPRESSED); - ffStrbufDestroy(&result); free(chars); return true; } @@ -532,8 +526,7 @@ static void readCachedStrbuf(FFLogoRequestData* requestData, FFstrbuf* result, c static uint32_t readCachedUint32(FFLogoRequestData* requestData, const char* cacheFileName) { - FFstrbuf content; - ffStrbufInit(&content); + FF_STRBUF_AUTO_DESTROY content = ffStrbufCreate(); readCachedStrbuf(requestData, &content, cacheFileName); uint32_t result = 0; @@ -546,27 +539,20 @@ static uint32_t readCachedUint32(FFLogoRequestData* requestData, const char* cac memcpy(&result, content.chars, sizeof(result)); - ffStrbufDestroy(&content); - return result; } static bool printCachedChars(FFinstance* instance, FFLogoRequestData* requestData) { - FFstrbuf content; - ffStrbufInitA(&content, 32768); + FF_STRBUF_AUTO_DESTROY content = ffStrbufCreateA(32768); if(requestData->type == FF_LOGO_TYPE_IMAGE_CHAFA) readCachedStrbuf(requestData, &content, FF_CACHE_FILE_CHAFA); if(content.length == 0) - { - ffStrbufDestroy(&content); return false; - } ffLogoPrintChars(instance, content.chars, false); - ffStrbufDestroy(&content); return true; } diff --git a/src/logo/logo.c b/src/logo/logo.c index 43d39bc97..2e2e54f8f 100644 --- a/src/logo/logo.c +++ b/src/logo/logo.c @@ -1,4 +1,4 @@ -#include "logo.h" +#include "logo/logo.h" #include "common/io/io.h" #include "common/printing.h" #include "detection/os/os.h" @@ -10,35 +10,38 @@ static void ffLogoPrintCharsRaw(FFinstance* instance, const char* data, size_t length) { + FFLogoOptions* options = &instance->config.logo; fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout); - ffPrintCharTimes('\n', instance->config.logo.paddingTop); - ffPrintCharTimes(' ', instance->config.logo.paddingLeft); + ffPrintCharTimes('\n', options->paddingTop); + ffPrintCharTimes(' ', options->paddingLeft); fwrite(data, length, 1, stdout); - instance->state.logoHeight = instance->config.logo.paddingTop + instance->config.logo.height; - instance->state.logoWidth = instance->config.logo.paddingLeft + instance->config.logo.width + instance->config.logo.paddingRight; + instance->state.logoHeight = options->paddingTop + options->height; + instance->state.logoWidth = options->paddingLeft + options->width + options->paddingRight; printf("\033[9999999D\n\033[%uA", instance->state.logoHeight); } void ffLogoPrintChars(FFinstance* instance, const char* data, bool doColorReplacement) { + FFLogoOptions* options = &instance->config.logo; + uint32_t currentlineLength = 0; fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout); - ffPrintCharTimes('\n', instance->config.logo.paddingTop); - ffPrintCharTimes(' ', instance->config.logo.paddingLeft); + ffPrintCharTimes('\n', options->paddingTop); + ffPrintCharTimes(' ', options->paddingLeft); - instance->state.logoHeight = instance->config.logo.paddingTop; + instance->state.logoHeight = options->paddingTop; //Use logoColor[0] as the default color if(doColorReplacement) - ffPrintColor(&instance->config.logo.colors[0]); + ffPrintColor(&options->colors[0]); while(*data != '\0') { //We are at the end of a line. Print paddings and update max line length if(*data == '\n' || (*data == '\r' && *(data + 1) == '\n')) { - ffPrintCharTimes(' ', instance->config.logo.paddingRight); + ffPrintCharTimes(' ', options->paddingRight); //We have \r\n, skip the \r if(*data == '\r') @@ -47,7 +50,7 @@ void ffLogoPrintChars(FFinstance* instance, const char* data, bool doColorReplac putchar('\n'); ++data; - ffPrintCharTimes(' ', instance->config.logo.paddingLeft); + ffPrintCharTimes(' ', options->paddingLeft); if(currentlineLength > instance->state.logoWidth) instance->state.logoWidth = currentlineLength; @@ -115,7 +118,7 @@ void ffLogoPrintChars(FFinstance* instance, const char* data, bool doColorReplac } else { - ffPrintColor(&instance->config.logo.colors[index]); + ffPrintColor(&options->colors[index]); ++data; continue; } @@ -148,14 +151,14 @@ void ffLogoPrintChars(FFinstance* instance, const char* data, bool doColorReplac } } - ffPrintCharTimes(' ', instance->config.logo.paddingRight); + ffPrintCharTimes(' ', options->paddingRight); fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout); //Happens if the last line is the longest if(currentlineLength > instance->state.logoWidth) instance->state.logoWidth = currentlineLength; - instance->state.logoWidth += instance->config.logo.paddingLeft + instance->config.logo.paddingRight; + instance->state.logoWidth += options->paddingLeft + options->paddingRight; //Go to the leftmost position fputs("\033[9999999D", stdout); @@ -241,11 +244,13 @@ static void logoPrintStruct(FFinstance* instance, const FFlogo* logo) { logoApplyColors(instance, logo); + FFLogoOptions* options = &instance->config.logo; + const char** colors = logo->builtinColors; for(int i = 0; *colors != NULL && i < FASTFETCH_LOGO_MAX_COLORS; i++, colors++) { - if(instance->config.logo.colors[i].length == 0) - ffStrbufAppendS(&instance->config.logo.colors[i], *colors); + if(options->colors[i].length == 0) + ffStrbufAppendS(&options->colors[i], *colors); } ffLogoPrintChars(instance, logo->data, true); @@ -281,47 +286,47 @@ static inline void logoPrintDetected(FFinstance* instance) } static bool logoPrintData(FFinstance* instance, bool doColorReplacement) { - if(instance->config.logo.source.length == 0) + FFLogoOptions* options = &instance->config.logo; + if(options->source.length == 0) return false; - ffLogoPrintChars(instance, instance->config.logo.source.chars, doColorReplacement); + ffLogoPrintChars(instance, options->source.chars, doColorReplacement); logoApplyColorsDetected(instance); return true; } static void updateLogoPath(FFinstance* instance) { - if(ffPathExists(instance->config.logo.source.chars, FF_PATHTYPE_FILE)) + FFLogoOptions* options = &instance->config.logo; + + if(ffPathExists(options->source.chars, FF_PATHTYPE_FILE)) return; - FFstrbuf fullPath; - ffStrbufInit(&fullPath); + FF_STRBUF_AUTO_DESTROY fullPath = ffStrbufCreate(); FF_LIST_FOR_EACH(FFstrbuf, dataDir, instance->state.platform.dataDirs) { //We need to copy it, because multiple threads might be using dataDirs at the same time ffStrbufSet(&fullPath, dataDir); ffStrbufAppendS(&fullPath, "fastfetch/logos/"); - ffStrbufAppend(&fullPath, &instance->config.logo.source); + ffStrbufAppend(&fullPath, &options->source); if(ffPathExists(fullPath.chars, FF_PATHTYPE_FILE)) { - ffStrbufSet(&instance->config.logo.source, &fullPath); + ffStrbufSet(&options->source, &fullPath); break; } } - - ffStrbufDestroy(&fullPath); } static bool logoPrintFileIfExists(FFinstance* instance, bool doColorReplacement, bool raw) { - FFstrbuf content; - ffStrbufInit(&content); + FFLogoOptions* options = &instance->config.logo; - if(!ffAppendFileBuffer(instance->config.logo.source.chars, &content)) + FF_STRBUF_AUTO_DESTROY content = ffStrbufCreate(); + + if(!ffAppendFileBuffer(options->source.chars, &content)) { - ffStrbufDestroy(&content); fputs("Logo: Failed to load file content from logo source\n", stderr); return false; } @@ -331,7 +336,7 @@ static bool logoPrintFileIfExists(FFinstance* instance, bool doColorReplacement, ffLogoPrintCharsRaw(instance, content.chars, content.length); else ffLogoPrintChars(instance, content.chars, doColorReplacement); - ffStrbufDestroy(&content); + return true; } @@ -346,32 +351,34 @@ static bool logoPrintImageIfExists(FFinstance* instance, FFLogoType logo, bool p static bool logoTryKnownType(FFinstance* instance) { - if(instance->config.logo.type == FF_LOGO_TYPE_NONE) + FFLogoOptions* options = &instance->config.logo; + + if(options->type == FF_LOGO_TYPE_NONE) { logoApplyColorsDetected(instance); return true; } - if(instance->config.logo.type == FF_LOGO_TYPE_BUILTIN) - return logoPrintBuiltinIfExists(instance, instance->config.logo.source.chars); + if(options->type == FF_LOGO_TYPE_BUILTIN) + return logoPrintBuiltinIfExists(instance, options->source.chars); - if(instance->config.logo.type == FF_LOGO_TYPE_DATA) + if(options->type == FF_LOGO_TYPE_DATA) return logoPrintData(instance, true); - if(instance->config.logo.type == FF_LOGO_TYPE_DATA_RAW) + if(options->type == FF_LOGO_TYPE_DATA_RAW) return logoPrintData(instance, false); updateLogoPath(instance); //We sure have a file, resolve relative paths - if(instance->config.logo.type == FF_LOGO_TYPE_FILE) + if(options->type == FF_LOGO_TYPE_FILE) return logoPrintFileIfExists(instance, true, false); - if(instance->config.logo.type == FF_LOGO_TYPE_FILE_RAW) + if(options->type == FF_LOGO_TYPE_FILE_RAW) return logoPrintFileIfExists(instance, false, false); - if(instance->config.logo.type == FF_LOGO_TYPE_IMAGE_RAW) + if(options->type == FF_LOGO_TYPE_IMAGE_RAW) { - if(instance->config.logo.width == 0 || instance->config.logo.height == 0) + if(options->width == 0 || options->height == 0) { fputs("both `--logo-width` and `--logo-height` must be specified\n", stderr); return false; @@ -380,7 +387,7 @@ static bool logoTryKnownType(FFinstance* instance) return logoPrintFileIfExists(instance, false, true); } - return logoPrintImageIfExists(instance, instance->config.logo.type, true); + return logoPrintImageIfExists(instance, options->type, true); } static void logoPrintKnownType(FFinstance* instance) @@ -401,22 +408,24 @@ void ffLogoPrint(FFinstance* instance) return; } + const FFLogoOptions* options = &instance->config.logo; + //If the source is not set, we can directly print the detected logo. - if(instance->config.logo.source.length == 0) + if(options->source.length == 0) { logoPrintDetected(instance); return; } //If the source and source type is set to something else than auto, always print with the set type. - if(instance->config.logo.source.length > 0 && instance->config.logo.type != FF_LOGO_TYPE_AUTO) + if(options->source.length > 0 && options->type != FF_LOGO_TYPE_AUTO) { logoPrintKnownType(instance); return; } //If source matches the name of a builtin logo, print it and return. - if(logoPrintBuiltinIfExists(instance, instance->config.logo.source.chars)) + if(logoPrintBuiltinIfExists(instance, options->source.chars)) return; //Make sure the logo path is set correctly. @@ -462,6 +471,7 @@ void ffLogoPrintRemaining(FFinstance* instance) void ffLogoBuiltinPrint(FFinstance* instance) { GetLogoMethod* methods = ffLogoBuiltinGetAll(); + FFLogoOptions* options = &instance->config.logo; while(*methods != NULL) { @@ -474,7 +484,7 @@ void ffLogoBuiltinPrint(FFinstance* instance) instance->state.logoHeight = 0; instance->state.keysHeight = 0; for(uint8_t i = 0; i < FASTFETCH_LOGO_MAX_COLORS; i++) - ffStrbufClear(&instance->config.logo.colors[i]); + ffStrbufClear(&options->colors[i]); puts("\n"); ++methods; diff --git a/src/logo/logo.h b/src/logo/logo.h index 0664f6f98..9d3878c66 100644 --- a/src/logo/logo.h +++ b/src/logo/logo.h @@ -26,4 +26,9 @@ GetLogoMethod* ffLogoBuiltinGetAll(); //image/image.c bool ffLogoPrintImageIfExists(FFinstance* instance, FFLogoType type, bool printError); +//option.c +void ffInitLogoOptions(FFLogoOptions* options); +bool ffParseLogoCommandOptions(FFLogoOptions* options, const char* key, const char* value); +void ffDestroyLogoOptions(FFLogoOptions* options); + #endif diff --git a/src/logo/option.c b/src/logo/option.c new file mode 100644 index 000000000..033885635 --- /dev/null +++ b/src/logo/option.c @@ -0,0 +1,183 @@ +#include "logo/logo.h" + +void ffInitLogoOptions(FFLogoOptions* options) +{ + ffStrbufInit(&options->source); + options->type = FF_LOGO_TYPE_AUTO; + for(uint8_t i = 0; i < (uint8_t) FASTFETCH_LOGO_MAX_COLORS; ++i) + ffStrbufInit(&options->colors[i]); + options->width = 0; + options->height = 0; //preserve aspect ratio + options->paddingTop = 0; + options->paddingLeft = 0; + options->paddingRight = 4; + options->printRemaining = true; + options->preserveAspectRadio = false; + + options->chafaFgOnly = false; + ffStrbufInitS(&options->chafaSymbols, "block+border+space-wide-inverted"); // Chafa default + options->chafaCanvasMode = UINT32_MAX; + options->chafaColorSpace = UINT32_MAX; + options->chafaDitherMode = UINT32_MAX; +} + +bool ffParseLogoCommandOptions(FFLogoOptions* options, const char* key, const char* value) +{ + if (strcasecmp(key, "-l") == 0) + goto logoType; + + const char* subKey = ffOptionTestPrefix(key, "logo"); + if(subKey) + { + if (subKey[0] == '\0') + { +logoType: + ffOptionParseString(key, value, &options->source); + + //this is usally wanted when using the none logo + if(strcasecmp(value, "none") == 0) + { + options->paddingTop = 0; + options->paddingRight = 0; + options->paddingLeft = 0; + options->type = FF_LOGO_TYPE_NONE; + } + } + else if(strcasecmp(subKey, "type") == 0) + { + options->type = (FFLogoType) ffOptionParseEnum(key, value, (FFKeyValuePair[]) { + { "auto", FF_LOGO_TYPE_AUTO }, + { "builtin", FF_LOGO_TYPE_BUILTIN }, + { "file", FF_LOGO_TYPE_FILE }, + { "file-raw", FF_LOGO_TYPE_FILE_RAW }, + { "data", FF_LOGO_TYPE_DATA }, + { "data-raw", FF_LOGO_TYPE_DATA_RAW }, + { "sixel", FF_LOGO_TYPE_IMAGE_SIXEL }, + { "kitty", FF_LOGO_TYPE_IMAGE_KITTY }, + { "iterm", FF_LOGO_TYPE_IMAGE_ITERM }, + { "chafa", FF_LOGO_TYPE_IMAGE_CHAFA }, + { "raw", FF_LOGO_TYPE_IMAGE_RAW }, + { "none", FF_LOGO_TYPE_NONE }, + {}, + }); + } + else if(strncasecmp(subKey, "color-", strlen("color-")) && key[13] != '\0' && key[14] == '\0') // matches "--logo-color-*" + { + //Map the number to an array index, so that '1' -> 0, '2' -> 1, etc. + int index = (int)key[13] - 49; + + //Match only --logo-color-[1-9] + if(index < 0 || index >= FASTFETCH_LOGO_MAX_COLORS) + { + fprintf(stderr, "Error: invalid --color-[1-9] index: %c\n", key[13]); + exit(472); + } + + ffOptionParseColor(key, value, &options->colors[index]); + } + else if(strcasecmp(subKey, "width") == 0) + options->width = ffOptionParseUInt32(key, value); + else if(strcasecmp(subKey, "height") == 0) + options->height = ffOptionParseUInt32(key, value); + else if(strcasecmp(subKey, "padding") == 0) + { + uint32_t padding = ffOptionParseUInt32(key, value); + options->paddingLeft = padding; + options->paddingRight = padding; + } + else if(strcasecmp(subKey, "padding-top") == 0) + options->paddingTop = ffOptionParseUInt32(key, value); + else if(strcasecmp(subKey, "padding-left") == 0) + options->paddingLeft = ffOptionParseUInt32(key, value); + else if(strcasecmp(subKey, "padding-right") == 0) + options->paddingRight = ffOptionParseUInt32(key, value); + else if(strcasecmp(subKey, "print-remaining") == 0) + options->printRemaining = ffOptionParseBoolean(value); + else if(strcasecmp(subKey, "preserve-aspect-radio") == 0) + options->preserveAspectRadio = ffOptionParseBoolean(value); + else + return false; + } + else if((subKey = ffOptionTestPrefix(key, "file"))) + { + if(subKey[0] == '\0') + { + ffOptionParseString(key, value, &options->source); + options->type = FF_LOGO_TYPE_FILE; + } + else if(strcasecmp(key, "raw") == 0) + { + ffOptionParseString(key, value, &options->source); + options->type = FF_LOGO_TYPE_FILE_RAW; + } + else + return false; + } + else if((subKey = ffOptionTestPrefix(key, "data"))) + { + if(subKey[0] == '\0') + { + ffOptionParseString(key, value, &options->source); + options->type = FF_LOGO_TYPE_DATA; + } + else if(strcasecmp(subKey, "raw") == 0) + { + ffOptionParseString(key, value, &options->source); + options->type = FF_LOGO_TYPE_DATA_RAW; + } + else + return false; + } + else if(strcasecmp(key, "--sixel") == 0) + { + ffOptionParseString(key, value, &options->source); + options->type = FF_LOGO_TYPE_IMAGE_SIXEL; + } + else if(strcasecmp(key, "--kitty") == 0) + { + ffOptionParseString(key, value, &options->source); + options->type = FF_LOGO_TYPE_IMAGE_KITTY; + } + else if(strcasecmp(key, "--iterm") == 0) + { + ffOptionParseString(key, value, &options->source); + options->type = FF_LOGO_TYPE_IMAGE_ITERM; + } + else if(strcasecmp(key, "--raw") == 0) + { + ffOptionParseString(key, value, &options->source); + options->type = FF_LOGO_TYPE_IMAGE_RAW; + } + else if((subKey = ffOptionTestPrefix(key, "chafa"))) + { + if(subKey[0] == '\0') + { + ffOptionParseString(key, value, &options->source); + options->type = FF_LOGO_TYPE_IMAGE_CHAFA; + } + else if(strcasecmp(subKey, "fg-only") == 0) + options->chafaFgOnly = ffOptionParseBoolean(value); + else if(strcasecmp(subKey, "symbols") == 0) + ffOptionParseString(key, value, &options->chafaSymbols); + else if(strcasecmp(subKey, "canvas-mode") == 0) + options->chafaCanvasMode = ffOptionParseUInt32(key, value); + else if(strcasecmp(subKey, "color-space") == 0) + options->chafaColorSpace = ffOptionParseUInt32(key, value); + else if(strcasecmp(subKey, "dither-mode") == 0) + options->chafaDitherMode = ffOptionParseUInt32(key, value); + else + return false; + } + else + return false; + + return true; +} + +void ffDestroyLogoOptions(FFLogoOptions* options) +{ + ffStrbufDestroy(&options->source); + ffStrbufDestroy(&options->chafaSymbols); + for(uint8_t i = 0; i < (uint8_t) FASTFETCH_LOGO_MAX_COLORS; ++i) + ffStrbufDestroy(&options->colors[i]); +} diff --git a/src/logo/option.h b/src/logo/option.h new file mode 100644 index 000000000..09f7822d1 --- /dev/null +++ b/src/logo/option.h @@ -0,0 +1,41 @@ +#pragma once + +#include "util/FFstrbuf.h" + +#define FASTFETCH_LOGO_MAX_COLORS 9 //two digits would make parsing much more complicated (index 1 - 9) + +typedef enum FFLogoType +{ + FF_LOGO_TYPE_AUTO, //if something is given, first try builtin, then file. Otherwise detect logo + FF_LOGO_TYPE_BUILTIN, //builtin ascii art + FF_LOGO_TYPE_FILE, //text file, printed with color code replacement + FF_LOGO_TYPE_FILE_RAW, //text file, printed as is + FF_LOGO_TYPE_DATA, //text data, printed with color code replacement + FF_LOGO_TYPE_DATA_RAW, //text data, printed as is + FF_LOGO_TYPE_IMAGE_SIXEL, //image file, printed as sixel codes. + FF_LOGO_TYPE_IMAGE_KITTY, //image file, printed as kitty graphics protocol + FF_LOGO_TYPE_IMAGE_ITERM, //image file, printed as iterm graphics protocol + FF_LOGO_TYPE_IMAGE_CHAFA, //image file, printed as ascii art using libchafa + FF_LOGO_TYPE_IMAGE_RAW, //image file, printed as raw binary string + FF_LOGO_TYPE_NONE, //--logo none +} FFLogoType; + +typedef struct FFLogoOptions +{ + FFstrbuf source; + FFLogoType type; + FFstrbuf colors[FASTFETCH_LOGO_MAX_COLORS]; + uint32_t width; + uint32_t height; + uint32_t paddingTop; + uint32_t paddingLeft; + uint32_t paddingRight; + bool printRemaining; + bool preserveAspectRadio; + + bool chafaFgOnly; + FFstrbuf chafaSymbols; + uint32_t chafaCanvasMode; + uint32_t chafaColorSpace; + uint32_t chafaDitherMode; +} FFLogoOptions; diff --git a/src/modules/battery.c b/src/modules/battery/battery.c similarity index 51% rename from src/modules/battery.c rename to src/modules/battery/battery.c index 6bafb0ee7..92f5dea6f 100644 --- a/src/modules/battery.c +++ b/src/modules/battery/battery.c @@ -2,23 +2,22 @@ #include "common/printing.h" #include "common/bar.h" #include "detection/battery/battery.h" +#include "modules/battery/battery.h" -#define FF_BATTERY_MODULE_NAME "Battery" #define FF_BATTERY_NUM_FORMAT_ARGS 5 -static void printBattery(FFinstance* instance, BatteryResult* result, uint8_t index) +static void printBattery(FFinstance* instance, FFBatteryOptions* options, BatteryResult* result, uint8_t index) { - if(instance->config.battery.outputFormat.length == 0) + if(instance->config.battery.moduleArgs.outputFormat.length == 0) { - ffPrintLogoAndKey(instance, FF_BATTERY_MODULE_NAME, index, &instance->config.battery.key); + ffPrintLogoAndKey(instance, FF_BATTERY_MODULE_NAME, index, &options->moduleArgs.key); bool showStatus = !(instance->config.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT) && result->status.length > 0 && ffStrbufIgnCaseCompS(&result->status, "Unknown") != 0; - FFstrbuf str; - ffStrbufInit(&str); + FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate(); if(result->capacity >= 0) { @@ -58,11 +57,10 @@ static void printBattery(FFinstance* instance, BatteryResult* result, uint8_t in } ffStrbufPutTo(&str, stdout); - ffStrbufDestroy(&str); } else { - ffPrintFormat(instance, FF_BATTERY_MODULE_NAME, index, &instance->config.battery, FF_BATTERY_NUM_FORMAT_ARGS, (FFformatarg[]){ + ffPrintFormat(instance, FF_BATTERY_MODULE_NAME, index, &options->moduleArgs, FF_BATTERY_NUM_FORMAT_ARGS, (FFformatarg[]){ {FF_FORMAT_ARG_TYPE_STRBUF, &result->manufacturer}, {FF_FORMAT_ARG_TYPE_STRBUF, &result->modelName}, {FF_FORMAT_ARG_TYPE_STRBUF, &result->technology}, @@ -73,7 +71,7 @@ static void printBattery(FFinstance* instance, BatteryResult* result, uint8_t in } } -void ffPrintBattery(FFinstance* instance) +void ffPrintBattery(FFinstance* instance, FFBatteryOptions* options) { FFlist results; ffListInitA(&results, sizeof(BatteryResult), 0); @@ -82,14 +80,14 @@ void ffPrintBattery(FFinstance* instance) if (error) { - ffPrintError(instance, FF_BATTERY_MODULE_NAME, 0, &instance->config.battery, "%s", error); + ffPrintError(instance, FF_BATTERY_MODULE_NAME, 0, &options->moduleArgs, "%s", error); } else { for(uint8_t i = 0; i < (uint8_t) results.length; i++) { BatteryResult* result = ffListGet(&results, i); - printBattery(instance, result, i); + printBattery(instance, options, result, i); ffStrbufDestroy(&result->manufacturer); ffStrbufDestroy(&result->modelName); @@ -97,8 +95,86 @@ void ffPrintBattery(FFinstance* instance) ffStrbufDestroy(&result->status); } if(results.length == 0) - ffPrintError(instance, FF_BATTERY_MODULE_NAME, 0, &instance->config.battery, "No batteries found"); + ffPrintError(instance, FF_BATTERY_MODULE_NAME, 0, &options->moduleArgs, "No batteries found"); } ffListDestroy(&results); } + +void ffInitBatteryOptions(FFBatteryOptions* options) +{ + options->moduleName = FF_BATTERY_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + options->temp = false; + + #ifdef __linux__ + ffStrbufInit(&options->dir); + #endif +} + +bool ffParseBatteryCommandOptions(FFBatteryOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_BATTERY_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (strcasecmp(subKey, "temp") == 0) + { + options->temp = ffOptionParseBoolean(value); + return true; + } + + #ifdef __linux__ + if (strcasecmp(subKey, "dir") == 0) + { + ffOptionParseString(key, value, &options->dir); + return true; + } + #endif + + return false; +} + +void ffDestroyBatteryOptions(FFBatteryOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); + #ifdef __linux__ + ffStrbufDestroy(&options->dir); + #endif +} + +#ifdef FF_HAVE_JSONC +void ffParseBatteryJsonObject(FFinstance* instance, json_object* module) +{ + FFBatteryOptions __attribute__((__cleanup__(ffDestroyBatteryOptions))) options; + ffInitBatteryOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + #ifdef __linux__ + if (strcasecmp(key, "dir") == 0) + { + ffStrbufSetS(&options.dir, json_object_get_string(val)); + continue; + } + #endif + + if (strcasecmp(key, "temp") == 0) + { + options.temp = (bool) json_object_get_boolean(val); + continue; + } + + ffPrintError(instance, FF_BATTERY_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintBattery(instance, &options); +} +#endif diff --git a/src/modules/battery/battery.h b/src/modules/battery/battery.h new file mode 100644 index 000000000..efe7f9132 --- /dev/null +++ b/src/modules/battery/battery.h @@ -0,0 +1,16 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_BATTERY_MODULE_NAME "Battery" + +void ffPrintBattery(FFinstance* instance, FFBatteryOptions* options); + +void ffInitBatteryOptions(FFBatteryOptions* options); +bool ffParseBatteryCommandOptions(FFBatteryOptions* options, const char* key, const char* value); +void ffDestroyBatteryOptions(FFBatteryOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseBatteryJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/battery/option.h b/src/modules/battery/option.h new file mode 100644 index 000000000..73632b9c6 --- /dev/null +++ b/src/modules/battery/option.h @@ -0,0 +1,17 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFBatteryOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + bool temp; + + #ifdef __linux__ + FFstrbuf dir; + #endif +} FFBatteryOptions; diff --git a/src/modules/bios.c b/src/modules/bios.c deleted file mode 100644 index 7b3853355..000000000 --- a/src/modules/bios.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/bios/bios.h" - -#define FF_BIOS_MODULE_NAME "Bios" -#define FF_BIOS_NUM_FORMAT_ARGS 4 - -void ffPrintBios(FFinstance* instance) -{ - FFBiosResult result; - ffDetectBios(&result); - - if(result.error.length > 0) - { - ffPrintError(instance, FF_BIOS_MODULE_NAME, 0, &instance->config.bios, "%*s", result.error.length, result.error.chars); - goto exit; - } - - if(result.biosRelease.length == 0) - { - ffPrintError(instance, FF_BIOS_MODULE_NAME, 0, &instance->config.bios, "bios_release is not set."); - goto exit; - } - - if(instance->config.bios.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_BIOS_MODULE_NAME, 0, &instance->config.bios.key); - puts(result.biosRelease.chars); - } - else - { - ffPrintFormat(instance, FF_BIOS_MODULE_NAME, 0, &instance->config.bios, FF_BIOS_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &result.biosDate}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.biosRelease}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.biosVendor}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.biosVersion}, - }); - } - -exit: - ffStrbufDestroy(&result.biosDate); - ffStrbufDestroy(&result.biosRelease); - ffStrbufDestroy(&result.biosVendor); - ffStrbufDestroy(&result.biosVersion); - ffStrbufDestroy(&result.error); -} diff --git a/src/modules/bios/bios.c b/src/modules/bios/bios.c new file mode 100644 index 000000000..12e79e048 --- /dev/null +++ b/src/modules/bios/bios.c @@ -0,0 +1,88 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/bios/bios.h" +#include "modules/bios/bios.h" + +#define FF_BIOS_NUM_FORMAT_ARGS 4 + +void ffPrintBios(FFinstance* instance, FFBiosOptions* options) +{ + FFBiosResult result; + ffDetectBios(&result); + + if(result.error.length > 0) + { + ffPrintError(instance, FF_BIOS_MODULE_NAME, 0, &options->moduleArgs, "%*s", result.error.length, result.error.chars); + goto exit; + } + + if(result.biosRelease.length == 0) + { + ffPrintError(instance, FF_BIOS_MODULE_NAME, 0, &options->moduleArgs, "bios_release is not set."); + goto exit; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_BIOS_MODULE_NAME, 0, &options->moduleArgs.key); + puts(result.biosRelease.chars); + } + else + { + ffPrintFormat(instance, FF_BIOS_MODULE_NAME, 0, &options->moduleArgs, FF_BIOS_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &result.biosDate}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.biosRelease}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.biosVendor}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.biosVersion}, + }); + } + +exit: + ffStrbufDestroy(&result.biosDate); + ffStrbufDestroy(&result.biosRelease); + ffStrbufDestroy(&result.biosVendor); + ffStrbufDestroy(&result.biosVersion); + ffStrbufDestroy(&result.error); +} + +void ffInitBiosOptions(FFBiosOptions* options) +{ + options->moduleName = FF_BIOS_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseBiosCommandOptions(FFBiosOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_BIOS_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyBiosOptions(FFBiosOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseBiosJsonObject(FFinstance* instance, json_object* module) +{ + FFBiosOptions __attribute__((__cleanup__(ffDestroyBiosOptions))) options; + ffInitBiosOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_BIOS_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintBios(instance, &options); +} +#endif diff --git a/src/modules/bios/bios.h b/src/modules/bios/bios.h new file mode 100644 index 000000000..8ff5c7837 --- /dev/null +++ b/src/modules/bios/bios.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_BIOS_MODULE_NAME "Bios" + +void ffPrintBios(FFinstance* instance, FFBiosOptions* options); +void ffInitBiosOptions(FFBiosOptions* options); +bool ffParseBiosCommandOptions(FFBiosOptions* options, const char* key, const char* value); +void ffDestroyBiosOptions(FFBiosOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseBiosJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/bios/option.h b/src/modules/bios/option.h new file mode 100644 index 000000000..6c0f67420 --- /dev/null +++ b/src/modules/bios/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFBiosOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFBiosOptions; diff --git a/src/modules/bluetooth.c b/src/modules/bluetooth.c deleted file mode 100644 index 6038acf01..000000000 --- a/src/modules/bluetooth.c +++ /dev/null @@ -1,64 +0,0 @@ -#include "common/printing.h" -#include "detection/bluetooth/bluetooth.h" - -#define FF_BLUETOOTH_MODULE_NAME "Bluetooth" -#define FF_BLUETOOTH_NUM_FORMAT_ARGS 4 - -static void printDevice(FFinstance* instance, const FFBluetoothDevice* device, uint8_t index) -{ - if(instance->config.bluetooth.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_BLUETOOTH_MODULE_NAME, index, &instance->config.bluetooth.key); - ffStrbufWriteTo(&device->name, stdout); - - if(device->battery > 0) - printf(" (%d%%)", device->battery); - - putchar('\n'); - } - else - { - ffPrintFormat(instance, FF_BLUETOOTH_MODULE_NAME, index, &instance->config.bluetooth, FF_BLUETOOTH_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &device->name}, - {FF_FORMAT_ARG_TYPE_STRBUF, &device->address}, - {FF_FORMAT_ARG_TYPE_STRBUF, &device->type}, - {FF_FORMAT_ARG_TYPE_UINT8, &device->battery} - }); - } -} - -void ffPrintBluetooth(FFinstance* instance) -{ - const FFBluetoothResult* bluetooth = ffDetectBluetooth(instance); - - if(bluetooth->error.length > 0) - { - ffPrintError(instance, FF_BLUETOOTH_MODULE_NAME, 0, &instance->config.bluetooth, "%s", bluetooth->error.chars); - return; - } - - FFlist filtered; - ffListInit(&filtered, sizeof(FFBluetoothDevice*)); - - FF_LIST_FOR_EACH(FFBluetoothDevice, device, bluetooth->devices) - { - if(!device->connected && !instance->config.bluetoothShowDisconnected) - continue; - - *(FFBluetoothDevice**)ffListAdd(&filtered) = device; - } - - if(filtered.length == 0) - { - ffPrintError(instance, FF_BLUETOOTH_MODULE_NAME, 0, &instance->config.bluetooth, "No bluetooth devices found"); - return; - } - - for(uint32_t i = 0; i < filtered.length; i++) - { - uint8_t index = (uint8_t) (filtered.length == 1 ? 0 : i + 1); - printDevice(instance, *(FFBluetoothDevice**)ffListGet(&filtered, i), index); - } - - ffListDestroy(&filtered); -} diff --git a/src/modules/bluetooth/bluetooth.c b/src/modules/bluetooth/bluetooth.c new file mode 100644 index 000000000..2318336b5 --- /dev/null +++ b/src/modules/bluetooth/bluetooth.c @@ -0,0 +1,112 @@ +#include "common/printing.h" +#include "detection/bluetooth/bluetooth.h" +#include "modules/bluetooth/bluetooth.h" + +#define FF_BLUETOOTH_NUM_FORMAT_ARGS 4 + +static void printDevice(FFinstance* instance, FFBluetoothOptions* options, const FFBluetoothDevice* device, uint8_t index) +{ + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_BLUETOOTH_MODULE_NAME, index, &options->moduleArgs.key); + ffStrbufWriteTo(&device->name, stdout); + + if(device->battery > 0) + printf(" (%d%%)", device->battery); + + putchar('\n'); + } + else + { + ffPrintFormat(instance, FF_BLUETOOTH_MODULE_NAME, index, &options->moduleArgs, FF_BLUETOOTH_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &device->name}, + {FF_FORMAT_ARG_TYPE_STRBUF, &device->address}, + {FF_FORMAT_ARG_TYPE_STRBUF, &device->type}, + {FF_FORMAT_ARG_TYPE_UINT8, &device->battery} + }); + } +} + +void ffPrintBluetooth(FFinstance* instance, FFBluetoothOptions* options) +{ + const FFBluetoothResult* bluetooth = ffDetectBluetooth(instance); + + if(bluetooth->error.length > 0) + { + ffPrintError(instance, FF_BLUETOOTH_MODULE_NAME, 0, &options->moduleArgs, "%s", bluetooth->error.chars); + return; + } + + FF_LIST_AUTO_DESTROY filtered = ffListCreate(sizeof(FFBluetoothDevice*)); + + FF_LIST_FOR_EACH(FFBluetoothDevice, device, bluetooth->devices) + { + if(!device->connected && !options->showDisconnected) + continue; + + *(FFBluetoothDevice**)ffListAdd(&filtered) = device; + } + + if(filtered.length == 0) + { + ffPrintError(instance, FF_BLUETOOTH_MODULE_NAME, 0, &options->moduleArgs, "No bluetooth devices found"); + return; + } + + for(uint32_t i = 0; i < filtered.length; i++) + { + uint8_t index = (uint8_t) (filtered.length == 1 ? 0 : i + 1); + printDevice(instance, options, *(FFBluetoothDevice**)ffListGet(&filtered, i), index); + } +} + +void ffInitBluetoothOptions(FFBluetoothOptions* options) +{ + options->moduleName = FF_BLUETOOTH_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + options->showDisconnected = false; +} + +bool ffParseBluetoothCommandOptions(FFBluetoothOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_BLUETOOTH_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (strcasecmp(subKey, "show-disconnected") == 0) + options->showDisconnected = ffOptionParseBoolean(value); + return false; +} + +void ffDestroyBluetoothOptions(FFBluetoothOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseBluetoothJsonObject(FFinstance* instance, json_object* module) +{ + FFBluetoothOptions __attribute__((__cleanup__(ffDestroyBluetoothOptions))) options; + ffInitBluetoothOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + if (strcasecmp(key, "showConnected") == 0) + { + options.showDisconnected = json_object_get_boolean(val); + continue; + } + + ffPrintError(instance, FF_BLUETOOTH_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintBluetooth(instance, &options); +} +#endif diff --git a/src/modules/bluetooth/bluetooth.h b/src/modules/bluetooth/bluetooth.h new file mode 100644 index 000000000..5c72b0ec7 --- /dev/null +++ b/src/modules/bluetooth/bluetooth.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_BLUETOOTH_MODULE_NAME "Bluetooth" + +void ffPrintBluetooth(FFinstance* instance, FFBluetoothOptions* options); +void ffInitBluetoothOptions(FFBluetoothOptions* options); +bool ffParseBluetoothCommandOptions(FFBluetoothOptions* options, const char* key, const char* value); +void ffDestroyBluetoothOptions(FFBluetoothOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseBluetoothJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/bluetooth/option.h b/src/modules/bluetooth/option.h new file mode 100644 index 000000000..b347dc466 --- /dev/null +++ b/src/modules/bluetooth/option.h @@ -0,0 +1,13 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFBluetoothOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + bool showDisconnected; +} FFBluetoothOptions; diff --git a/src/modules/board.c b/src/modules/board.c deleted file mode 100644 index 558653892..000000000 --- a/src/modules/board.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/board/board.h" - -#define FF_BOARD_MODULE_NAME "Board" -#define FF_BOARD_NUM_FORMAT_ARGS 3 - -void ffPrintBoard(FFinstance* instance) -{ - FFBoardResult result; - ffDetectBoard(&result); - - if(result.error.length > 0) - { - ffPrintError(instance, FF_BOARD_MODULE_NAME, 0, &instance->config.board, "%*s", result.error.length, result.error.chars); - goto exit; - } - - if(result.boardName.length == 0) - { - ffPrintError(instance, FF_BOARD_MODULE_NAME, 0, &instance->config.board, "board_name is not set."); - goto exit; - } - - if(instance->config.board.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_BOARD_MODULE_NAME, 0, &instance->config.board.key); - puts(result.boardName.chars); - } - else - { - ffPrintFormat(instance, FF_BOARD_MODULE_NAME, 0, &instance->config.board, FF_BOARD_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &result.boardName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.boardVendor}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.boardVersion}, - }); - } - -exit: - ffStrbufDestroy(&result.boardName); - ffStrbufDestroy(&result.boardVendor); - ffStrbufDestroy(&result.boardVersion); - ffStrbufDestroy(&result.error); -} diff --git a/src/modules/board/board.c b/src/modules/board/board.c new file mode 100644 index 000000000..39c1fab01 --- /dev/null +++ b/src/modules/board/board.c @@ -0,0 +1,86 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/board/board.h" +#include "modules/board/board.h" + +#define FF_BOARD_NUM_FORMAT_ARGS 3 + +void ffPrintBoard(FFinstance* instance, FFBoardOptions* options) +{ + FFBoardResult result; + ffDetectBoard(&result); + + if(result.error.length > 0) + { + ffPrintError(instance, FF_BOARD_MODULE_NAME, 0, &options->moduleArgs, "%*s", result.error.length, result.error.chars); + goto exit; + } + + if(result.boardName.length == 0) + { + ffPrintError(instance, FF_BOARD_MODULE_NAME, 0, &options->moduleArgs, "board_name is not set."); + goto exit; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_BOARD_MODULE_NAME, 0, &options->moduleArgs.key); + puts(result.boardName.chars); + } + else + { + ffPrintFormat(instance, FF_BOARD_MODULE_NAME, 0, &options->moduleArgs, FF_BOARD_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &result.boardName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.boardVendor}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.boardVersion}, + }); + } + +exit: + ffStrbufDestroy(&result.boardName); + ffStrbufDestroy(&result.boardVendor); + ffStrbufDestroy(&result.boardVersion); + ffStrbufDestroy(&result.error); +} + +void ffInitBoardOptions(FFBoardOptions* options) +{ + options->moduleName = FF_BOARD_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseBoardCommandOptions(FFBoardOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_BOARD_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyBoardOptions(FFBoardOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseBoardJsonObject(FFinstance* instance, json_object* module) +{ + FFBoardOptions __attribute__((__cleanup__(ffDestroyBoardOptions))) options; + ffInitBoardOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_BOARD_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintBoard(instance, &options); +} +#endif diff --git a/src/modules/board/board.h b/src/modules/board/board.h new file mode 100644 index 000000000..10b9c6f5c --- /dev/null +++ b/src/modules/board/board.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_BOARD_MODULE_NAME "Board" + +void ffPrintBoard(FFinstance* instance, FFBoardOptions* options); +void ffInitBoardOptions(FFBoardOptions* options); +bool ffParseBoardCommandOptions(FFBoardOptions* options, const char* key, const char* value); +void ffDestroyBoardOptions(FFBoardOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseBoardJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/board/option.h b/src/modules/board/option.h new file mode 100644 index 000000000..582854d23 --- /dev/null +++ b/src/modules/board/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFBoardOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFBoardOptions; diff --git a/src/modules/break.c b/src/modules/break.c deleted file mode 100644 index 45b09e5fd..000000000 --- a/src/modules/break.c +++ /dev/null @@ -1,8 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" - -void ffPrintBreak(FFinstance* instance) -{ - ffLogoPrintLine(instance); - putchar('\n'); -} diff --git a/src/modules/break/break.c b/src/modules/break/break.c new file mode 100644 index 000000000..59d205210 --- /dev/null +++ b/src/modules/break/break.c @@ -0,0 +1,16 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "modules/break/break.h" + +void ffPrintBreak(FFinstance* instance) +{ + ffLogoPrintLine(instance); + putchar('\n'); +} + +#ifdef FF_HAVE_JSONC +void ffParseBreakJsonObject(FFinstance* instance, FF_MAYBE_UNUSED json_object* module) +{ + return ffPrintBreak(instance); +} +#endif diff --git a/src/modules/break/break.h b/src/modules/break/break.h new file mode 100644 index 000000000..a7b34957d --- /dev/null +++ b/src/modules/break/break.h @@ -0,0 +1,12 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_BREAK_MODULE_NAME "Break" + +void ffPrintBreak(FFinstance* instance); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseBreakJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/brightness.c b/src/modules/brightness.c deleted file mode 100644 index 9c1cde499..000000000 --- a/src/modules/brightness.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/brightness/brightness.h" - -#define FF_BRIGHTNESS_MODULE_NAME "Brightness" -#define FF_BRIGHTNESS_NUM_FORMAT_ARGS 2 - -void ffPrintBrightness(FFinstance* instance) -{ - FF_LIST_AUTO_DESTROY result; - ffListInit(&result, sizeof(FFBrightnessResult)); - const char* error = ffDetectBrightness(&result); - - if(error) - { - ffPrintError(instance, FF_BRIGHTNESS_MODULE_NAME, 0, &instance->config.brightness, "%s", error); - return; - } - - if(result.length == 0) - { - ffPrintError(instance, FF_BRIGHTNESS_MODULE_NAME, 0, &instance->config.brightness, "No result is detected."); - return; - } - - FF_STRBUF_AUTO_DESTROY key; - ffStrbufInit(&key); - - FF_LIST_FOR_EACH(FFBrightnessResult, item, result) - { - if(instance->config.brightness.key.length == 0) - { - ffStrbufAppendF(&key, "%s (%s)", FF_BRIGHTNESS_MODULE_NAME, item->name.chars); - } - else - { - ffParseFormatString(&key, &instance->config.brightness.key, 1, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &item->name} - }); - } - - if(instance->config.brightness.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, key.chars, 0, NULL); - printf("%.0f%%\n", item->value); - } - else - { - ffPrintFormatString(instance, key.chars, 0, NULL, &instance->config.brightness.outputFormat, FF_BRIGHTNESS_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &item->value}, - {FF_FORMAT_ARG_TYPE_FLOAT, &item->name} - }); - } - - ffStrbufClear(&key); - ffStrbufDestroy(&item->name); - } -} diff --git a/src/modules/brightness/brightness.c b/src/modules/brightness/brightness.c new file mode 100644 index 000000000..34ae9f8f1 --- /dev/null +++ b/src/modules/brightness/brightness.c @@ -0,0 +1,99 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/brightness/brightness.h" +#include "modules/brightness/brightness.h" + +#define FF_BRIGHTNESS_NUM_FORMAT_ARGS 2 + +void ffPrintBrightness(FFinstance* instance, FFBrightnessOptions* options) +{ + FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFBrightnessResult)); + + const char* error = ffDetectBrightness(&result); + + if(error) + { + ffPrintError(instance, FF_BRIGHTNESS_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + if(result.length == 0) + { + ffPrintError(instance, FF_BRIGHTNESS_MODULE_NAME, 0, &options->moduleArgs, "No result is detected."); + return; + } + + FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate(); + + FF_LIST_FOR_EACH(FFBrightnessResult, item, result) + { + if(options->moduleArgs.key.length == 0) + { + ffStrbufAppendF(&key, "%s (%s)", FF_BRIGHTNESS_MODULE_NAME, item->name.chars); + } + else + { + ffParseFormatString(&key, &options->moduleArgs.key, 1, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &item->name} + }); + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, key.chars, 0, NULL); + printf("%.0f%%\n", item->value); + } + else + { + ffPrintFormatString(instance, key.chars, 0, NULL, &options->moduleArgs.outputFormat, FF_BRIGHTNESS_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &item->value}, + {FF_FORMAT_ARG_TYPE_FLOAT, &item->name} + }); + } + + ffStrbufClear(&key); + ffStrbufDestroy(&item->name); + } +} + +void ffInitBrightnessOptions(FFBrightnessOptions* options) +{ + options->moduleName = FF_BRIGHTNESS_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseBrightnessCommandOptions(FFBrightnessOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_BRIGHTNESS_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyBrightnessOptions(FFBrightnessOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseBrightnessJsonObject(FFinstance* instance, json_object* module) +{ + FFBrightnessOptions __attribute__((__cleanup__(ffDestroyBrightnessOptions))) options; + ffInitBrightnessOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_BRIGHTNESS_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintBrightness(instance, &options); +} +#endif diff --git a/src/modules/brightness/brightness.h b/src/modules/brightness/brightness.h new file mode 100644 index 000000000..58fbbf302 --- /dev/null +++ b/src/modules/brightness/brightness.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_BRIGHTNESS_MODULE_NAME "Brightness" + +void ffPrintBrightness(FFinstance* instance, FFBrightnessOptions* options); +void ffInitBrightnessOptions(FFBrightnessOptions* options); +bool ffParseBrightnessCommandOptions(FFBrightnessOptions* options, const char* key, const char* value); +void ffDestroyBrightnessOptions(FFBrightnessOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseBrightnessJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/brightness/option.h b/src/modules/brightness/option.h new file mode 100644 index 000000000..803ea4792 --- /dev/null +++ b/src/modules/brightness/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFBrightnessOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFBrightnessOptions; diff --git a/src/modules/chassis.c b/src/modules/chassis.c deleted file mode 100644 index 997242d65..000000000 --- a/src/modules/chassis.c +++ /dev/null @@ -1,53 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/chassis/chassis.h" - -#define FF_CHASSIS_MODULE_NAME "Chassis" -#define FF_CHASSIS_NUM_FORMAT_ARGS 3 - -void ffPrintChassis(FFinstance* instance) -{ - FFChassisResult result; - ffDetectChassis(&result); - - if(result.error.length > 0) - { - ffPrintError(instance, FF_CHASSIS_MODULE_NAME, 0, &instance->config.chassis, "%*s", result.error.length, result.error.chars); - goto exit; - } - - if(result.chassisType.length == 0) - { - ffPrintError(instance, FF_CHASSIS_MODULE_NAME, 0, &instance->config.chassis, "chassis_type is not set by O.E.M."); - return; - } - - if(instance->config.chassis.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_CHASSIS_MODULE_NAME, 0, &instance->config.chassis.key); - - FFstrbuf output; - ffStrbufInitCopy(&output, &result.chassisType); - - if(result.chassisVersion.length > 0) - ffStrbufAppendF(&output, " (%s)", result.chassisVersion.chars); - - ffStrbufPutTo(&output, stdout); - - ffStrbufDestroy(&output); - } - else - { - ffPrintFormat(instance, FF_CHASSIS_MODULE_NAME, 0, &instance->config.chassis, FF_CHASSIS_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &result.chassisType}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.chassisVendor}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.chassisVersion}, - }); - } - -exit: - ffStrbufDestroy(&result.chassisType); - ffStrbufDestroy(&result.chassisVendor); - ffStrbufDestroy(&result.chassisVersion); - ffStrbufDestroy(&result.error); -} diff --git a/src/modules/chassis/chassis.c b/src/modules/chassis/chassis.c new file mode 100644 index 000000000..72beac3c0 --- /dev/null +++ b/src/modules/chassis/chassis.c @@ -0,0 +1,92 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/chassis/chassis.h" +#include "modules/chassis/chassis.h" + +#define FF_CHASSIS_NUM_FORMAT_ARGS 3 + +void ffPrintChassis(FFinstance* instance, FFChassisOptions* options) +{ + FFChassisResult result; + ffDetectChassis(&result); + + if(result.error.length > 0) + { + ffPrintError(instance, FF_CHASSIS_MODULE_NAME, 0, &options->moduleArgs, "%*s", result.error.length, result.error.chars); + goto exit; + } + + if(result.chassisType.length == 0) + { + ffPrintError(instance, FF_CHASSIS_MODULE_NAME, 0, &options->moduleArgs, "chassis_type is not set by O.E.M."); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_CHASSIS_MODULE_NAME, 0, &options->moduleArgs.key); + + FF_STRBUF_AUTO_DESTROY output = ffStrbufCreateCopy(&result.chassisType); + + if(result.chassisVersion.length > 0) + ffStrbufAppendF(&output, " (%s)", result.chassisVersion.chars); + + ffStrbufPutTo(&output, stdout); + } + else + { + ffPrintFormat(instance, FF_CHASSIS_MODULE_NAME, 0, &options->moduleArgs, FF_CHASSIS_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &result.chassisType}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.chassisVendor}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.chassisVersion}, + }); + } + +exit: + ffStrbufDestroy(&result.chassisType); + ffStrbufDestroy(&result.chassisVendor); + ffStrbufDestroy(&result.chassisVersion); + ffStrbufDestroy(&result.error); +} + +void ffInitChassisOptions(FFChassisOptions* options) +{ + options->moduleName = FF_CHASSIS_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseChassisCommandOptions(FFChassisOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_CHASSIS_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyChassisOptions(FFChassisOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseChassisJsonObject(FFinstance* instance, json_object* module) +{ + FFChassisOptions __attribute__((__cleanup__(ffDestroyChassisOptions))) options; + ffInitChassisOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_CHASSIS_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintChassis(instance, &options); +} +#endif diff --git a/src/modules/chassis/chassis.h b/src/modules/chassis/chassis.h new file mode 100644 index 000000000..2eb9af900 --- /dev/null +++ b/src/modules/chassis/chassis.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_CHASSIS_MODULE_NAME "Chassis" + +void ffPrintChassis(FFinstance* instance, FFChassisOptions* options); +void ffInitChassisOptions(FFChassisOptions* options); +bool ffParseChassisCommandOptions(FFChassisOptions* options, const char* key, const char* value); +void ffDestroyChassisOptions(FFChassisOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseChassisJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/chassis/option.h b/src/modules/chassis/option.h new file mode 100644 index 000000000..939fd165d --- /dev/null +++ b/src/modules/chassis/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFChassisOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFChassisOptions; diff --git a/src/modules/colors.c b/src/modules/colors/colors.c similarity index 82% rename from src/modules/colors.c rename to src/modules/colors/colors.c index 186a225cf..a355844c5 100644 --- a/src/modules/colors.c +++ b/src/modules/colors/colors.c @@ -1,6 +1,7 @@ #include "fastfetch.h" #include "common/printing.h" #include "util/textModifier.h" +#include "modules/colors/colors.h" void ffPrintColors(FFinstance* instance) { @@ -28,3 +29,10 @@ void ffPrintColors(FFinstance* instance) puts(FASTFETCH_TEXT_MODIFIER_RESET); } + +#ifdef FF_HAVE_JSONC +void ffParseColorsJsonObject(FFinstance* instance, FF_MAYBE_UNUSED json_object* module) +{ + return ffPrintColors(instance); +} +#endif diff --git a/src/modules/colors/colors.h b/src/modules/colors/colors.h new file mode 100644 index 000000000..11887735d --- /dev/null +++ b/src/modules/colors/colors.h @@ -0,0 +1,12 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_COLORS_MODULE_NAME "Colors" + +void ffPrintColors(FFinstance* instance); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseColorsJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/command.c b/src/modules/command.c deleted file mode 100644 index 1b767013b..000000000 --- a/src/modules/command.c +++ /dev/null @@ -1,67 +0,0 @@ -#include "fastfetch.h" - -#include "common/printing.h" -#include "common/processing.h" -#include "util/textModifier.h" - -#define FF_COMMAND_MODULE_NAME "Command" - -static void printError(FFinstance* instance, const char* key, const char* error) -{ - ffPrintLogoAndKey(instance, key, 0, NULL); - - if(instance->config.pipe) - fputs(FASTFETCH_TEXT_MODIFIER_ERROR, stdout); - - fputs(error, stdout); - - if(!instance->config.pipe) - fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout); - - putchar('\n'); -} - -void ffPrintCommand(FFinstance* instance) -{ - FF_STRBUF_AUTO_DESTROY key; - ffStrbufInit(&key); - - if(!ffListShift(&instance->config.commandKeys, &key)) - ffStrbufInitS(&key, FF_COMMAND_MODULE_NAME); - - FF_STRBUF_AUTO_DESTROY text; - ffStrbufInit(&text); - if(!ffListShift(&instance->config.commandTexts, &text)) - { - printError(instance, key.chars, "No command text left"); - return; - } - - FF_STRBUF_AUTO_DESTROY result; - ffStrbufInit(&result); - const char* error = ffProcessAppendStdOut(&result, (char* const[]){ - instance->config.commandShell.chars, - #ifdef _WIN32 - "/c", - #else - "-c", - #endif - text.chars, - NULL - }); - - if(error) - { - printError(instance, key.chars, error); - return; - } - - if(!result.length) - { - printError(instance, key.chars, "No result printed"); - return; - } - - ffPrintLogoAndKey(instance, key.chars, 0, NULL); - puts(result.chars); -} diff --git a/src/modules/command/command.c b/src/modules/command/command.c new file mode 100644 index 000000000..49177119d --- /dev/null +++ b/src/modules/command/command.c @@ -0,0 +1,115 @@ +#include "fastfetch.h" + +#include "common/printing.h" +#include "common/processing.h" +#include "modules/command/command.h" + +void ffPrintCommand(FFinstance* instance, FFCommandOptions* options) +{ + FF_STRBUF_AUTO_DESTROY result = ffStrbufCreate(); + const char* error = ffProcessAppendStdOut(&result, (char* const[]){ + options->shell.chars, + #ifdef _WIN32 + "/c", + #else + "-c", + #endif + options->text.chars, + NULL + }); + + if(error) + { + ffPrintError(instance, FF_COMMAND_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + if(!result.length) + { + ffPrintError(instance, FF_COMMAND_MODULE_NAME, 0, &options->moduleArgs, "No result printed"); + return; + } + + ffPrintLogoAndKey(instance, FF_COMMAND_MODULE_NAME, 0, &options->moduleArgs.key); + ffStrbufPutTo(&result, stdout); +} + +void ffInitCommandOptions(FFCommandOptions* options) +{ + options->moduleName = FF_COMMAND_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + + ffStrbufInitS(&options->shell, + #ifdef _WIN32 + "cmd" + #elif defined(__FreeBSD__) + "csh" + #else + "bash" + #endif + ); + + ffStrbufInit(&options->text); +} + +bool ffParseCommandCommandOptions(FFCommandOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_COMMAND_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if(strcasecmp(subKey, "shell") == 0) + { + ffOptionParseString(key, value, &options->shell); + return true; + } + + if(strcasecmp(subKey, "text") == 0) + { + ffOptionParseString(key, value, &options->text); + return true; + } + + return false; +} + +void ffDestroyCommandOptions(FFCommandOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); + ffStrbufDestroy(&options->shell); + ffStrbufDestroy(&options->text); +} + +#ifdef FF_HAVE_JSONC +void ffParseCommandJsonObject(FFinstance* instance, json_object* module) +{ + FFCommandOptions __attribute__((__cleanup__(ffDestroyCommandOptions))) options; + ffInitCommandOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + if (strcasecmp(key, "shell") == 0) + { + ffStrbufSetS(&options.shell, json_object_get_string(val)); + continue; + } + + if (strcasecmp(key, "text") == 0) + { + ffStrbufSetS(&options.text, json_object_get_string(val)); + continue; + } + + ffPrintError(instance, FF_COMMAND_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintCommand(instance, &options); +} +#endif diff --git a/src/modules/command/command.h b/src/modules/command/command.h new file mode 100644 index 000000000..9944b9bd7 --- /dev/null +++ b/src/modules/command/command.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_COMMAND_MODULE_NAME "Command" + +void ffPrintCommand(FFinstance* instance, FFCommandOptions* options); +void ffInitCommandOptions(FFCommandOptions* options); +bool ffParseCommandCommandOptions(FFCommandOptions* options, const char* key, const char* value); +void ffDestroyCommandOptions(FFCommandOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseCommandJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/command/option.h b/src/modules/command/option.h new file mode 100644 index 000000000..41d3408a4 --- /dev/null +++ b/src/modules/command/option.h @@ -0,0 +1,14 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFCommandOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + FFstrbuf shell; + FFstrbuf text; +} FFCommandOptions; diff --git a/src/modules/cpu.c b/src/modules/cpu.c deleted file mode 100644 index eb38a9805..000000000 --- a/src/modules/cpu.c +++ /dev/null @@ -1,56 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/cpu/cpu.h" - -#define FF_CPU_MODULE_NAME "CPU" -#define FF_CPU_NUM_FORMAT_ARGS 8 - -void ffPrintCPU(FFinstance* instance) -{ - const FFCPUResult* cpu = ffDetectCPU(instance); - - if(cpu->vendor.length == 0 && cpu->name.length == 0 && cpu->coresOnline <= 1) - { - ffPrintError(instance, FF_CPU_MODULE_NAME, 0, &instance->config.cpu, "No CPU detected"); - return; - } - - if(instance->config.cpu.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_CPU_MODULE_NAME, 0, &instance->config.cpu.key); - - if(cpu->name.length > 0) - ffStrbufWriteTo(&cpu->name, stdout); - else if(cpu->vendor.length > 0) - { - ffStrbufWriteTo(&cpu->vendor, stdout); - fputs(" CPU", stdout); - } - else - fputs("CPU", stdout); - - if(cpu->coresOnline > 1) - printf(" (%u)", cpu->coresOnline); - - if(cpu->frequencyMax > 0.0) - printf(" @ %.9g GHz", cpu->frequencyMax); - - if(cpu->temperature == cpu->temperature) //FF_CPU_TEMP_UNSET - printf(" - %.1f°C", cpu->temperature); - - putchar('\n'); - } - else - { - ffPrintFormat(instance, FF_CPU_MODULE_NAME, 0, &instance->config.cpu, FF_CPU_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &cpu->name}, - {FF_FORMAT_ARG_TYPE_STRBUF, &cpu->vendor}, - {FF_FORMAT_ARG_TYPE_UINT16, &cpu->coresPhysical}, - {FF_FORMAT_ARG_TYPE_UINT16, &cpu->coresLogical}, - {FF_FORMAT_ARG_TYPE_UINT16, &cpu->coresOnline}, - {FF_FORMAT_ARG_TYPE_DOUBLE, &cpu->frequencyMin}, - {FF_FORMAT_ARG_TYPE_DOUBLE, &cpu->frequencyMax}, - {FF_FORMAT_ARG_TYPE_DOUBLE, &cpu->temperature} - }); - } -} diff --git a/src/modules/cpu/cpu.c b/src/modules/cpu/cpu.c new file mode 100644 index 000000000..07c16c28a --- /dev/null +++ b/src/modules/cpu/cpu.c @@ -0,0 +1,111 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/cpu/cpu.h" +#include "modules/cpu/cpu.h" + +#define FF_CPU_NUM_FORMAT_ARGS 8 + +void ffPrintCPU(FFinstance* instance, FFCPUOptions* options) +{ + const FFCPUResult* cpu = ffDetectCPU(instance); + + if(cpu->vendor.length == 0 && cpu->name.length == 0 && cpu->coresOnline <= 1) + { + ffPrintError(instance, FF_CPU_MODULE_NAME, 0, &options->moduleArgs, "No CPU detected"); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_CPU_MODULE_NAME, 0, &options->moduleArgs.key); + + if(cpu->name.length > 0) + ffStrbufWriteTo(&cpu->name, stdout); + else if(cpu->vendor.length > 0) + { + ffStrbufWriteTo(&cpu->vendor, stdout); + fputs(" CPU", stdout); + } + else + fputs("CPU", stdout); + + if(cpu->coresOnline > 1) + printf(" (%u)", cpu->coresOnline); + + if(cpu->frequencyMax > 0.0) + printf(" @ %.9g GHz", cpu->frequencyMax); + + if(cpu->temperature == cpu->temperature) //FF_CPU_TEMP_UNSET + printf(" - %.1f°C", cpu->temperature); + + putchar('\n'); + } + else + { + ffPrintFormat(instance, FF_CPU_MODULE_NAME, 0, &options->moduleArgs, FF_CPU_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &cpu->name}, + {FF_FORMAT_ARG_TYPE_STRBUF, &cpu->vendor}, + {FF_FORMAT_ARG_TYPE_UINT16, &cpu->coresPhysical}, + {FF_FORMAT_ARG_TYPE_UINT16, &cpu->coresLogical}, + {FF_FORMAT_ARG_TYPE_UINT16, &cpu->coresOnline}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &cpu->frequencyMin}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &cpu->frequencyMax}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &cpu->temperature} + }); + } +} + +void ffInitCPUOptions(FFCPUOptions* options) +{ + options->moduleName = FF_CPU_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + options->temp = false; +} + +bool ffParseCPUCommandOptions(FFCPUOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_CPU_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (strcasecmp(subKey, "temp") == 0) + { + options->temp = ffOptionParseBoolean(value); + return true; + } + + return false; +} + +void ffDestroyCPUOptions(FFCPUOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseCPUJsonObject(FFinstance* instance, json_object* module) +{ + FFCPUOptions __attribute__((__cleanup__(ffDestroyCPUOptions))) options; + ffInitCPUOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + if (strcasecmp(key, "temp") == 0) + { + options.temp = (bool) json_object_get_boolean(val); + continue; + } + + ffPrintError(instance, FF_CPU_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintCPU(instance, &options); +} +#endif diff --git a/src/modules/cpu/cpu.h b/src/modules/cpu/cpu.h new file mode 100644 index 000000000..04c5c6f7a --- /dev/null +++ b/src/modules/cpu/cpu.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_CPU_MODULE_NAME "CPU" + +void ffPrintCPU(FFinstance* instance, FFCPUOptions* options); +void ffInitCPUOptions(FFCPUOptions* options); +bool ffParseCPUCommandOptions(FFCPUOptions* options, const char* key, const char* value); +void ffDestroyCPUOptions(FFCPUOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseCPUJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/cpu/option.h b/src/modules/cpu/option.h new file mode 100644 index 000000000..9e54bfeaf --- /dev/null +++ b/src/modules/cpu/option.h @@ -0,0 +1,13 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFCPUOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + bool temp; +} FFCPUOptions; diff --git a/src/modules/cpuUsage.c b/src/modules/cpuUsage.c deleted file mode 100644 index cb952a06a..000000000 --- a/src/modules/cpuUsage.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "common/bar.h" -#include "detection/cpuUsage/cpuUsage.h" - -#define FF_CPU_USAGE_MODULE_NAME "CPU Usage" -#define FF_CPU_USAGE_NUM_FORMAT_ARGS 1 - -void ffPrintCPUUsage(FFinstance* instance) -{ - double percentage = 0.0/0.0; - const char* error = ffGetCpuUsageResult(&percentage); - - if(error) - { - ffPrintError(instance, FF_CPU_USAGE_MODULE_NAME, 0, &instance->config.cpu, "%s", error); - return; - } - - if(instance->config.cpuUsage.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_CPU_USAGE_MODULE_NAME, 0, &instance->config.cpuUsage.key); - - FF_STRBUF_AUTO_DESTROY str; - ffStrbufInit(&str); - if(instance->config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) - ffAppendPercentBar(instance, &str, (uint8_t)percentage, 0, 5, 8); - if(instance->config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) - { - if(str.length > 0) - ffStrbufAppendC(&str, ' '); - ffAppendPercentNum(instance, &str, (uint8_t) percentage, 50, 80, str.length > 0); - } - ffStrbufPutTo(&str, stdout); - } - else - { - ffPrintFormat(instance, FF_CPU_USAGE_MODULE_NAME, 0, &instance->config.cpuUsage, FF_CPU_USAGE_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_DOUBLE, &percentage} - }); - } -} diff --git a/src/modules/cpuusage/cpuusage.c b/src/modules/cpuusage/cpuusage.c new file mode 100644 index 000000000..74a078d34 --- /dev/null +++ b/src/modules/cpuusage/cpuusage.c @@ -0,0 +1,84 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "common/bar.h" +#include "detection/cpuusage/cpuusage.h" +#include "modules/cpuusage/cpuusage.h" + +#define FF_CPUUSAGE_DISPLAY_NAME "CPU Usage" +#define FF_CPUUSAGE_NUM_FORMAT_ARGS 1 + +void ffPrintCPUUsage(FFinstance* instance, FFCPUUsageOptions* options) +{ + double percentage = 0.0/0.0; + const char* error = ffGetCpuUsageResult(&percentage); + + if(error) + { + ffPrintError(instance, FF_CPUUSAGE_DISPLAY_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_CPUUSAGE_DISPLAY_NAME, 0, &options->moduleArgs.key); + + FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate(); + if(instance->config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + ffAppendPercentBar(instance, &str, (uint8_t)percentage, 0, 5, 8); + if(instance->config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + { + if(str.length > 0) + ffStrbufAppendC(&str, ' '); + ffAppendPercentNum(instance, &str, (uint8_t) percentage, 50, 80, str.length > 0); + } + ffStrbufPutTo(&str, stdout); + } + else + { + ffPrintFormat(instance, FF_CPUUSAGE_DISPLAY_NAME, 0, &options->moduleArgs, FF_CPUUSAGE_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_DOUBLE, &percentage} + }); + } +} + +void ffInitCPUUsageOptions(FFCPUUsageOptions* options) +{ + options->moduleName = FF_CPUUSAGE_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseCPUUsageCommandOptions(FFCPUUsageOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_CPUUSAGE_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyCPUUsageOptions(FFCPUUsageOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseCPUUsageJsonObject(FFinstance* instance, json_object* module) +{ + FFCPUUsageOptions __attribute__((__cleanup__(ffDestroyCPUUsageOptions))) options; + ffInitCPUUsageOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_CPUUSAGE_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintCPUUsage(instance, &options); +} +#endif diff --git a/src/modules/cpuusage/cpuusage.h b/src/modules/cpuusage/cpuusage.h new file mode 100644 index 000000000..941c7ab84 --- /dev/null +++ b/src/modules/cpuusage/cpuusage.h @@ -0,0 +1,15 @@ +#pragma once + +#define FF_CPUUSAGE_MODULE_NAME "CPUUsage" + +void ffPrepareCPUUsage(); + +void ffPrintCPUUsage(FFinstance* instance, FFCPUUsageOptions* options); +void ffInitCPUUsageOptions(FFCPUUsageOptions* options); +bool ffParseCPUUsageCommandOptions(FFCPUUsageOptions* options, const char* key, const char* value); +void ffDestroyCPUUsageOptions(FFCPUUsageOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseCPUUsageJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/cpuusage/option.h b/src/modules/cpuusage/option.h new file mode 100644 index 000000000..c779b6c5a --- /dev/null +++ b/src/modules/cpuusage/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFCPUUsageOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFCPUUsageOptions; diff --git a/src/modules/cursor.c b/src/modules/cursor.c deleted file mode 100644 index a5ddc90be..000000000 --- a/src/modules/cursor.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "fastfetch.h" - -#include "common/printing.h" -#include "detection/cursor/cursor.h" - -#define FF_CURSOR_MODULE_NAME "Cursor" -#define FF_CURSOR_NUM_FORMAT_ARGS 2 - -static void printCursor(FFinstance* instance, FFCursorResult* cursor) -{ - ffStrbufRemoveIgnCaseEndS(&cursor->theme, "cursors"); - ffStrbufRemoveIgnCaseEndS(&cursor->theme, "cursor"); - ffStrbufTrimRight(&cursor->theme, '_'); - ffStrbufTrimRight(&cursor->theme, '-'); - if(cursor->theme.length == 0) - ffStrbufAppendS(&cursor->theme, "default"); - - if(instance->config.cursor.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor.key); - ffStrbufWriteTo(&cursor->theme, stdout); - - if(cursor->size.length > 0) - printf(" (%spx)", cursor->size.chars); - - putchar('\n'); - } - else - { - ffPrintFormat(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor, FF_CURSOR_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &cursor->theme}, - {FF_FORMAT_ARG_TYPE_STRBUF, &cursor->size} - }); - } -} - - -void ffPrintCursor(FFinstance* instance) -{ - FFCursorResult result; - ffStrbufInit(&result.error); - ffStrbufInit(&result.theme); - ffStrbufInit(&result.size); - - ffDetectCursor(instance, &result); - - if(result.error.length) - ffPrintError(instance, FF_CURSOR_MODULE_NAME, 0, &instance->config.cursor, "%s", result.error.chars); - else - printCursor(instance, &result); - - ffStrbufDestroy(&result.error); - ffStrbufDestroy(&result.theme); - ffStrbufDestroy(&result.size); -} diff --git a/src/modules/cursor/cursor.c b/src/modules/cursor/cursor.c new file mode 100644 index 000000000..1845fac3b --- /dev/null +++ b/src/modules/cursor/cursor.c @@ -0,0 +1,93 @@ +#include "fastfetch.h" + +#include "common/printing.h" +#include "detection/cursor/cursor.h" +#include "modules/cursor/cursor.h" + +#define FF_CURSOR_NUM_FORMAT_ARGS 2 + +void ffPrintCursor(FFinstance* instance, FFCursorOptions* options) +{ + FFCursorResult result; + ffStrbufInit(&result.error); + ffStrbufInit(&result.theme); + ffStrbufInit(&result.size); + + ffDetectCursor(instance, &result); + + if(result.error.length) + ffPrintError(instance, FF_CURSOR_MODULE_NAME, 0, &options->moduleArgs, "%s", result.error.chars); + else + { + ffStrbufRemoveIgnCaseEndS(&result.theme, "cursors"); + ffStrbufRemoveIgnCaseEndS(&result.theme, "cursor"); + ffStrbufTrimRight(&result.theme, '_'); + ffStrbufTrimRight(&result.theme, '-'); + if(result.theme.length == 0) + ffStrbufAppendS(&result.theme, "default"); + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_CURSOR_MODULE_NAME, 0, &options->moduleArgs.key); + ffStrbufWriteTo(&result.theme, stdout); + + if(result.size.length > 0) + printf(" (%spx)", result.size.chars); + + putchar('\n'); + } + else + { + ffPrintFormat(instance, FF_CURSOR_MODULE_NAME, 0, &options->moduleArgs, FF_CURSOR_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &result.theme}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.size} + }); + } + } + + ffStrbufDestroy(&result.error); + ffStrbufDestroy(&result.theme); + ffStrbufDestroy(&result.size); +} + +void ffInitCursorOptions(FFCursorOptions* options) +{ + options->moduleName = FF_CURSOR_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseCursorCommandOptions(FFCursorOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_CURSOR_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyCursorOptions(FFCursorOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseCursorJsonObject(FFinstance* instance, json_object* module) +{ + FFCursorOptions __attribute__((__cleanup__(ffDestroyCursorOptions))) options; + ffInitCursorOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_CURSOR_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintCursor(instance, &options); +} +#endif diff --git a/src/modules/cursor/cursor.h b/src/modules/cursor/cursor.h new file mode 100644 index 000000000..913e0668e --- /dev/null +++ b/src/modules/cursor/cursor.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_CURSOR_MODULE_NAME "Cursor" + +void ffPrintCursor(FFinstance* instance, FFCursorOptions* options); +void ffInitCursorOptions(FFCursorOptions* options); +bool ffParseCursorCommandOptions(FFCursorOptions* options, const char* key, const char* value); +void ffDestroyCursorOptions(FFCursorOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseCursorJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/cursor/option.h b/src/modules/cursor/option.h new file mode 100644 index 000000000..9a648c844 --- /dev/null +++ b/src/modules/cursor/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFCursorOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFCursorOptions; diff --git a/src/modules/custom.c b/src/modules/custom.c deleted file mode 100644 index f91a5b69e..000000000 --- a/src/modules/custom.c +++ /dev/null @@ -1,10 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "util/textModifier.h" - -void ffPrintCustom(FFinstance* instance, const char* key, const char* value) -{ - ffPrintLogoAndKey(instance, key, 0, NULL); - ffPrintUserString(value); - puts(FASTFETCH_TEXT_MODIFIER_RESET); -} diff --git a/src/modules/custom/custom.c b/src/modules/custom/custom.c new file mode 100644 index 000000000..b90f96be4 --- /dev/null +++ b/src/modules/custom/custom.c @@ -0,0 +1,59 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "modules/custom/custom.h" +#include "util/textModifier.h" + +void ffPrintCustom(FFinstance* instance, FFCustomOptions* options) +{ + if (options->moduleArgs.outputFormat.length == 0) + { + ffPrintError(instance, FF_CUSTOM_MODULE_NAME, 0, &options->moduleArgs, "output format must be set for custom module"); + return; + } + + ffPrintLogoAndKey(instance, options->moduleArgs.key.length == 0 ? NULL : FF_CUSTOM_MODULE_NAME, 0, &options->moduleArgs.key); + ffPrintUserString(options->moduleArgs.outputFormat.chars); + puts(FASTFETCH_TEXT_MODIFIER_RESET); +} + +void ffInitCustomOptions(FFCustomOptions* options) +{ + options->moduleName = FF_CUSTOM_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseCustomCommandOptions(FFCustomOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_CUSTOM_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyCustomOptions(FFCustomOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseCustomJsonObject(FFinstance* instance, json_object* module) +{ + FFCustomOptions __attribute__((__cleanup__(ffDestroyCustomOptions))) options; + ffInitCustomOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_CUSTOM_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintCustom(instance, &options); +} +#endif diff --git a/src/modules/custom/custom.h b/src/modules/custom/custom.h new file mode 100644 index 000000000..ab3873549 --- /dev/null +++ b/src/modules/custom/custom.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_CUSTOM_MODULE_NAME "Custom" + +void ffPrintCustom(FFinstance* instance, FFCustomOptions* options); +void ffInitCustomOptions(FFCustomOptions* options); +bool ffParseCustomCommandOptions(FFCustomOptions* options, const char* key, const char* value); +void ffDestroyCustomOptions(FFCustomOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseCustomJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/custom/option.h b/src/modules/custom/option.h new file mode 100644 index 000000000..f2b238831 --- /dev/null +++ b/src/modules/custom/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFCustomOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFCustomOptions; diff --git a/src/modules/date.c b/src/modules/date.c deleted file mode 100644 index a92209ed0..000000000 --- a/src/modules/date.c +++ /dev/null @@ -1,20 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/datetime/datetime.h" - -#define FF_DATE_MODULE_NAME "Date" - -void ffPrintDate(FFinstance* instance) -{ - if(instance->config.date.outputFormat.length > 0) - { - ffPrintDateTimeFormat(instance, FF_DATE_MODULE_NAME, &instance->config.date); - return; - } - - const FFDateTimeResult* datetime = ffDetectDateTime(instance); - ffPrintLogoAndKey(instance, FF_DATE_MODULE_NAME, 0, &instance->config.date.key); - - //yyyy-mm-dd - printf("%u-%s-%u\n", datetime->year, datetime->monthPretty.chars, datetime->dayInMonth); -} diff --git a/src/modules/datetime.c b/src/modules/datetime.c deleted file mode 100644 index 968d17725..000000000 --- a/src/modules/datetime.c +++ /dev/null @@ -1,48 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/datetime/datetime.h" - -#define FF_DATETIME_MODULE_NAME "Date & Time" -#define FF_DATETIME_NUM_FORMAT_ARGS 20 - -void ffPrintDateTimeFormat(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs) -{ - const FFDateTimeResult* result = ffDetectDateTime(instance); - ffPrintFormat(instance, moduleName, 0, moduleArgs, FF_DATETIME_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_UINT16, &result->year}, - {FF_FORMAT_ARG_TYPE_UINT8, &result->yearShort}, - {FF_FORMAT_ARG_TYPE_UINT8, &result->month}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->monthPretty}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->monthName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->monthNameShort}, - {FF_FORMAT_ARG_TYPE_UINT8, &result->week}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->weekday}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->weekdayShort}, - {FF_FORMAT_ARG_TYPE_UINT16, &result->dayInYear}, - {FF_FORMAT_ARG_TYPE_UINT8, &result->dayInMonth}, - {FF_FORMAT_ARG_TYPE_UINT8, &result->dayInWeek}, - {FF_FORMAT_ARG_TYPE_UINT8, &result->hour}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->hourPretty}, - {FF_FORMAT_ARG_TYPE_UINT8, &result->hour12}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->hour12Pretty}, - {FF_FORMAT_ARG_TYPE_UINT8, &result->minute}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->minutePretty}, - {FF_FORMAT_ARG_TYPE_UINT8, &result->second}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->secondPretty} - }); -} - -void ffPrintDateTime(FFinstance* instance) -{ - if(instance->config.dateTime.outputFormat.length > 0) - { - ffPrintDateTimeFormat(instance, FF_DATETIME_MODULE_NAME, &instance->config.dateTime); - return; - } - - const FFDateTimeResult* datetime = ffDetectDateTime(instance); - ffPrintLogoAndKey(instance, FF_DATETIME_MODULE_NAME, 0, &instance->config.dateTime.key); - - //yyyy-MM-dd HH:mm:ss - printf("%u-%s-%02u %s:%s:%s\n", datetime->year, datetime->monthPretty.chars, datetime->dayInMonth, datetime->hourPretty.chars, datetime->minutePretty.chars, datetime->secondPretty.chars); -} diff --git a/src/modules/datetime/datetime.c b/src/modules/datetime/datetime.c new file mode 100644 index 000000000..654060f77 --- /dev/null +++ b/src/modules/datetime/datetime.c @@ -0,0 +1,91 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/datetime/datetime.h" +#include "modules/datetime/datetime.h" + +#define FF_DATETIME_DISPLAY_NAME "Date & Time" +#define FF_DATETIME_NUM_FORMAT_ARGS 20 + +void ffPrintDateTimeFormat(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs) +{ + const FFDateTimeResult* result = ffDetectDateTime(instance); + ffPrintFormat(instance, moduleName, 0, moduleArgs, FF_DATETIME_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_UINT16, &result->year}, // 1 + {FF_FORMAT_ARG_TYPE_UINT8, &result->yearShort}, // 2 + {FF_FORMAT_ARG_TYPE_UINT8, &result->month}, // 3 + {FF_FORMAT_ARG_TYPE_STRBUF, &result->monthPretty}, // 4 + {FF_FORMAT_ARG_TYPE_STRBUF, &result->monthName}, // 5 + {FF_FORMAT_ARG_TYPE_STRBUF, &result->monthNameShort}, // 6 + {FF_FORMAT_ARG_TYPE_UINT8, &result->week}, // 7 + {FF_FORMAT_ARG_TYPE_STRBUF, &result->weekday}, // 8 + {FF_FORMAT_ARG_TYPE_STRBUF, &result->weekdayShort}, // 9 + {FF_FORMAT_ARG_TYPE_UINT16, &result->dayInYear}, // 10 + {FF_FORMAT_ARG_TYPE_UINT8, &result->dayInMonth}, // 11 + {FF_FORMAT_ARG_TYPE_UINT8, &result->dayInWeek}, // 12 + {FF_FORMAT_ARG_TYPE_UINT8, &result->hour}, // 13 + {FF_FORMAT_ARG_TYPE_STRBUF, &result->hourPretty}, // 14 + {FF_FORMAT_ARG_TYPE_UINT8, &result->hour12}, // 15 + {FF_FORMAT_ARG_TYPE_STRBUF, &result->hour12Pretty}, // 16 + {FF_FORMAT_ARG_TYPE_UINT8, &result->minute}, // 17 + {FF_FORMAT_ARG_TYPE_STRBUF, &result->minutePretty}, // 18 + {FF_FORMAT_ARG_TYPE_UINT8, &result->second}, // 19 + {FF_FORMAT_ARG_TYPE_STRBUF, &result->secondPretty} // 20 + }); +} + +void ffPrintDateTime(FFinstance* instance, FFDateTimeOptions* options) +{ + if(options->moduleArgs.outputFormat.length > 0) + { + ffPrintDateTimeFormat(instance, FF_DATETIME_DISPLAY_NAME, &options->moduleArgs); + return; + } + + const FFDateTimeResult* datetime = ffDetectDateTime(instance); + ffPrintLogoAndKey(instance, FF_DATETIME_DISPLAY_NAME, 0, &options->moduleArgs.key); + + //yyyy-MM-dd HH:mm:ss + printf("%u-%s-%02u %s:%s:%s\n", datetime->year, datetime->monthPretty.chars, datetime->dayInMonth, datetime->hourPretty.chars, datetime->minutePretty.chars, datetime->secondPretty.chars); +} + +void ffInitDateTimeOptions(FFDateTimeOptions* options) +{ + options->moduleName = FF_DATETIME_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseDateTimeCommandOptions(FFDateTimeOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_DATETIME_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyDateTimeOptions(FFDateTimeOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseDateTimeJsonObject(FFinstance* instance, json_object* module) +{ + FFDateTimeOptions __attribute__((__cleanup__(ffDestroyDateTimeOptions))) options; + ffInitDateTimeOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_DATETIME_DISPLAY_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintDateTime(instance, &options); +} +#endif diff --git a/src/modules/datetime/datetime.h b/src/modules/datetime/datetime.h new file mode 100644 index 000000000..737646611 --- /dev/null +++ b/src/modules/datetime/datetime.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_DATETIME_MODULE_NAME "DateTime" + +void ffPrintDateTime(FFinstance* instance, FFDateTimeOptions* options); +void ffInitDateTimeOptions(FFDateTimeOptions* options); +bool ffParseDateTimeCommandOptions(FFDateTimeOptions* options, const char* key, const char* value); +void ffDestroyDateTimeOptions(FFDateTimeOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseDateTimeJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/datetime/option.h b/src/modules/datetime/option.h new file mode 100644 index 000000000..1c32501e6 --- /dev/null +++ b/src/modules/datetime/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFDateTimeOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFDateTimeOptions; diff --git a/src/modules/de.c b/src/modules/de.c deleted file mode 100644 index eb2cb5062..000000000 --- a/src/modules/de.c +++ /dev/null @@ -1,45 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/displayserver/displayserver.h" - -#define FF_DE_MODULE_NAME "DE" -#define FF_DE_NUM_FORMAT_ARGS 3 - -void ffPrintDesktopEnvironment(FFinstance* instance) -{ - #ifdef __ANDROID__ - ffPrintError(instance, FF_DE_MODULE_NAME, 0, &instance->config.de, "DE detection is not supported on Android"); - return; - #endif - - const FFDisplayServerResult* result = ffConnectDisplayServer(instance); - - if(result->dePrettyName.length == 0) - { - ffPrintError(instance, FF_DE_MODULE_NAME, 0, &instance->config.de, "No DE found"); - return; - } - - if(instance->config.de.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_DE_MODULE_NAME, 0, &instance->config.de.key); - - ffStrbufWriteTo(&result->dePrettyName, stdout); - - if(result->deVersion.length > 0) - { - putchar(' '); - ffStrbufWriteTo(&result->deVersion, stdout); - } - - putchar('\n'); - } - else - { - ffPrintFormat(instance, FF_DE_MODULE_NAME, 0, &instance->config.de, FF_DE_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &result->deProcessName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->dePrettyName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->deVersion} - }); - } -} diff --git a/src/modules/de/de.c b/src/modules/de/de.c new file mode 100644 index 000000000..1a0310a33 --- /dev/null +++ b/src/modules/de/de.c @@ -0,0 +1,82 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/displayserver/displayserver.h" +#include "modules/de/de.h" + +#define FF_DE_NUM_FORMAT_ARGS 3 + +void ffPrintDE(FFinstance* instance, FFDEOptions* options) +{ + const FFDisplayServerResult* result = ffConnectDisplayServer(instance); + + if(result->dePrettyName.length == 0) + { + ffPrintError(instance, FF_DE_MODULE_NAME, 0, &options->moduleArgs, "No DE found"); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_DE_MODULE_NAME, 0, &options->moduleArgs.key); + + ffStrbufWriteTo(&result->dePrettyName, stdout); + + if(result->deVersion.length > 0) + { + putchar(' '); + ffStrbufWriteTo(&result->deVersion, stdout); + } + + putchar('\n'); + } + else + { + ffPrintFormat(instance, FF_DE_MODULE_NAME, 0, &options->moduleArgs, FF_DE_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &result->deProcessName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->dePrettyName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->deVersion} + }); + } +} + +void ffInitDEOptions(FFDEOptions* options) +{ + options->moduleName = FF_DE_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseDECommandOptions(FFDEOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_DE_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyDEOptions(FFDEOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseDEJsonObject(FFinstance* instance, json_object* module) +{ + FFDEOptions __attribute__((__cleanup__(ffDestroyDEOptions))) options; + ffInitDEOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_DE_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintDE(instance, &options); +} +#endif diff --git a/src/modules/de/de.h b/src/modules/de/de.h new file mode 100644 index 000000000..ee393e225 --- /dev/null +++ b/src/modules/de/de.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_DE_MODULE_NAME "DE" + +void ffPrintDE(FFinstance* instance, FFDEOptions* options); +void ffInitDEOptions(FFDEOptions* options); +bool ffParseDECommandOptions(FFDEOptions* options, const char* key, const char* value); +void ffDestroyDEOptions(FFDEOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseDEJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/de/option.h b/src/modules/de/option.h new file mode 100644 index 000000000..52b8954e7 --- /dev/null +++ b/src/modules/de/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFDEOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFDEOptions; diff --git a/src/modules/disk.c b/src/modules/disk.c deleted file mode 100644 index dd2064d73..000000000 --- a/src/modules/disk.c +++ /dev/null @@ -1,157 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "common/parsing.h" -#include "common/bar.h" -#include "detection/disk/disk.h" - -#define FF_DISK_MODULE_NAME "Disk" -#define FF_DISK_NUM_FORMAT_ARGS 10 - -static void printDisk(FFinstance* instance, const FFDisk* disk) -{ - FF_STRBUF_AUTO_DESTROY key; - ffStrbufInit(&key); - - if(instance->config.disk.key.length == 0) - { - ffStrbufAppendF(&key, "%s (%s)", FF_DISK_MODULE_NAME, disk->mountpoint.chars); - } - else - { - ffParseFormatString(&key, &instance->config.disk.key, 1, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &disk->mountpoint} - }); - } - - FF_STRBUF_AUTO_DESTROY usedPretty; - ffStrbufInit(&usedPretty); - ffParseSize(disk->bytesUsed, instance->config.binaryPrefixType, &usedPretty); - - FF_STRBUF_AUTO_DESTROY totalPretty; - ffStrbufInit(&totalPretty); - ffParseSize(disk->bytesTotal, instance->config.binaryPrefixType, &totalPretty); - - uint8_t bytesPercentage = disk->bytesTotal > 0 ? (uint8_t) (((long double) disk->bytesUsed / (long double) disk->bytesTotal) * 100.0) : 0; - - if(instance->config.disk.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, key.chars, 0, NULL); - - FF_STRBUF_AUTO_DESTROY str; - ffStrbufInit(&str); - - if(disk->bytesTotal > 0) - { - if(instance->config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) - { - ffAppendPercentBar(instance, &str, bytesPercentage, 0, 5, 8); - ffStrbufAppendC(&str, ' '); - } - - if(!(instance->config.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) - ffStrbufAppendF(&str, "%s / %s ", usedPretty.chars, totalPretty.chars); - - if(instance->config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) - { - ffAppendPercentNum(instance, &str, (uint8_t) bytesPercentage, 50, 80, str.length > 0); - ffStrbufAppendC(&str, ' '); - } - } - else - ffStrbufAppendS(&str, "Unknown "); - - if(disk->type & FF_DISK_TYPE_EXTERNAL_BIT && !(instance->config.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) - ffStrbufAppendS(&str, "[Removable]"); - - ffStrbufTrimRight(&str, ' '); - ffStrbufPutTo(&str, stdout); - } - else - { - uint8_t filesPercentage = disk->filesTotal > 0 ? (uint8_t) (((double) disk->filesUsed / (double) disk->filesTotal) * 100.0) : 0; - - ffPrintFormatString(instance, key.chars, 0, NULL, &instance->config.disk.outputFormat, FF_DISK_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty}, - {FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty}, - {FF_FORMAT_ARG_TYPE_UINT8, &bytesPercentage}, - {FF_FORMAT_ARG_TYPE_UINT, &disk->filesUsed}, - {FF_FORMAT_ARG_TYPE_UINT, &disk->filesTotal}, - {FF_FORMAT_ARG_TYPE_UINT8, &filesPercentage}, - {FF_FORMAT_ARG_TYPE_BOOL, FF_FORMAT_ARG_VALUE_BOOL(disk->type & FF_DISK_TYPE_EXTERNAL_BIT)}, - {FF_FORMAT_ARG_TYPE_BOOL, FF_FORMAT_ARG_VALUE_BOOL(disk->type & FF_DISK_TYPE_HIDDEN_BIT)}, - {FF_FORMAT_ARG_TYPE_STRBUF, &disk->filesystem}, - {FF_FORMAT_ARG_TYPE_STRBUF, &disk->name} - }); - } -} - -static void printMountpoint(FFinstance* instance, const FFlist* disks, const char* mountpoint) -{ - for(uint32_t i = disks->length; i > 0; i--) - { - FFDisk* disk = ffListGet(disks, i - 1); - if(strncmp(mountpoint, disk->mountpoint.chars, disk->mountpoint.length) == 0) - { - printDisk(instance, disk); - return; - } - } - - ffPrintError(instance, FF_DISK_MODULE_NAME, 0, &instance->config.disk, "No disk found for mountpoint: %s", mountpoint); -} - -static void printMountpoints(FFinstance* instance, const FFlist* disks) -{ - #ifdef _WIN32 - const char separator = ';'; - #else - const char separator = ':'; - #endif - - FF_STRBUF_AUTO_DESTROY mountpoints; - ffStrbufInitCopy(&mountpoints, &instance->config.diskFolders); - ffStrbufTrim(&mountpoints, separator); - - uint32_t startIndex = 0; - while(startIndex < mountpoints.length) - { - uint32_t colonIndex = ffStrbufNextIndexC(&mountpoints, startIndex, separator); - mountpoints.chars[colonIndex] = '\0'; - - printMountpoint(instance, disks, mountpoints.chars + startIndex); - - startIndex = colonIndex + 1; - } -} - -static void printAutodetected(FFinstance* instance, const FFlist* disks) -{ - bool found = false; - - FF_LIST_FOR_EACH(FFDisk, disk, *disks) - { - if(!(disk->type & instance->config.diskShowTypes)) - continue; - - printDisk(instance, disk); - found = true; - } - - if (!found) - ffPrintError(instance, FF_DISK_MODULE_NAME, 0, &instance->config.disk, "No disk found"); -} - -void ffPrintDisk(FFinstance* instance) -{ - const FFDiskResult* disks = ffDetectDisks(); - if(disks->error.length > 0) - { - ffPrintError(instance, FF_DISK_MODULE_NAME, 0, &instance->config.disk, "%s", disks->error.chars); - return; - } - - if(instance->config.diskFolders.length == 0) - printAutodetected(instance, &disks->disks); - else - printMountpoints(instance, &disks->disks); -} diff --git a/src/modules/disk/disk.c b/src/modules/disk/disk.c new file mode 100644 index 000000000..eb4c90da1 --- /dev/null +++ b/src/modules/disk/disk.c @@ -0,0 +1,286 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "common/parsing.h" +#include "common/bar.h" +#include "detection/disk/disk.h" +#include "modules/disk/disk.h" + +#define FF_DISK_NUM_FORMAT_ARGS 10 +#pragma GCC diagnostic ignored "-Wsign-conversion" + +static void printDisk(FFinstance* instance, FFDiskOptions* options, const FFDisk* disk) +{ + FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate(); + + if(options->moduleArgs.key.length == 0) + { + ffStrbufAppendF(&key, "%s (%s)", FF_DISK_MODULE_NAME, disk->mountpoint.chars); + } + else + { + ffParseFormatString(&key, &options->moduleArgs.key, 1, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &disk->mountpoint} + }); + } + + FF_STRBUF_AUTO_DESTROY usedPretty = ffStrbufCreate(); + ffParseSize(disk->bytesUsed, instance->config.binaryPrefixType, &usedPretty); + + FF_STRBUF_AUTO_DESTROY totalPretty = ffStrbufCreate(); + ffParseSize(disk->bytesTotal, instance->config.binaryPrefixType, &totalPretty); + + uint8_t bytesPercentage = disk->bytesTotal > 0 ? (uint8_t) (((long double) disk->bytesUsed / (long double) disk->bytesTotal) * 100.0) : 0; + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, key.chars, 0, NULL); + + FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate(); + + if(disk->bytesTotal > 0) + { + if(instance->config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + { + ffAppendPercentBar(instance, &str, bytesPercentage, 0, 5, 8); + ffStrbufAppendC(&str, ' '); + } + + if(!(instance->config.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) + ffStrbufAppendF(&str, "%s / %s ", usedPretty.chars, totalPretty.chars); + + if(instance->config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + { + ffAppendPercentNum(instance, &str, (uint8_t) bytesPercentage, 50, 80, str.length > 0); + ffStrbufAppendC(&str, ' '); + } + } + else + ffStrbufAppendS(&str, "Unknown "); + + if((disk->type & FF_DISK_TYPE_EXTERNAL_BIT) && !(instance->config.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) + ffStrbufAppendS(&str, "[Removable]"); + + ffStrbufTrimRight(&str, ' '); + ffStrbufPutTo(&str, stdout); + } + else + { + uint8_t filesPercentage = disk->filesTotal > 0 ? (uint8_t) (((double) disk->filesUsed / (double) disk->filesTotal) * 100.0) : 0; + + ffPrintFormatString(instance, key.chars, 0, NULL, &options->moduleArgs.outputFormat, FF_DISK_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty}, + {FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty}, + {FF_FORMAT_ARG_TYPE_UINT8, &bytesPercentage}, + {FF_FORMAT_ARG_TYPE_UINT, &disk->filesUsed}, + {FF_FORMAT_ARG_TYPE_UINT, &disk->filesTotal}, + {FF_FORMAT_ARG_TYPE_UINT8, &filesPercentage}, + {FF_FORMAT_ARG_TYPE_BOOL, FF_FORMAT_ARG_VALUE_BOOL(disk->type & FF_DISK_TYPE_EXTERNAL_BIT)}, + {FF_FORMAT_ARG_TYPE_BOOL, FF_FORMAT_ARG_VALUE_BOOL(disk->type & FF_DISK_TYPE_HIDDEN_BIT)}, + {FF_FORMAT_ARG_TYPE_STRBUF, &disk->filesystem}, + {FF_FORMAT_ARG_TYPE_STRBUF, &disk->name} + }); + } +} + +static void printMountpoint(FFinstance* instance, FFDiskOptions* options, const FFlist* disks, const char* mountpoint) +{ + for(uint32_t i = disks->length; i > 0; i--) + { + FFDisk* disk = ffListGet(disks, i - 1); + if(strncmp(mountpoint, disk->mountpoint.chars, disk->mountpoint.length) == 0) + { + printDisk(instance, options, disk); + return; + } + } + + ffPrintError(instance, FF_DISK_MODULE_NAME, 0, &options->moduleArgs, "No disk found for mountpoint: %s", mountpoint); +} + +static void printMountpoints(FFinstance* instance, FFDiskOptions* options, const FFlist* disks) +{ + #ifdef _WIN32 + const char separator = ';'; + #else + const char separator = ':'; + #endif + + FF_STRBUF_AUTO_DESTROY mountpoints = ffStrbufCreateCopy(&options->folders); + ffStrbufTrim(&mountpoints, separator); + + uint32_t startIndex = 0; + while(startIndex < mountpoints.length) + { + uint32_t colonIndex = ffStrbufNextIndexC(&mountpoints, startIndex, separator); + mountpoints.chars[colonIndex] = '\0'; + + printMountpoint(instance, options, disks, mountpoints.chars + startIndex); + + startIndex = colonIndex + 1; + } +} + +static void printAutodetected(FFinstance* instance, FFDiskOptions* options, const FFlist* disks) +{ + FF_LIST_FOR_EACH(FFDisk, disk, *disks) + { + if(!(disk->type & options->showTypes)) + continue; + + printDisk(instance, options, disk); + } +} + +void ffPrintDisk(FFinstance* instance, FFDiskOptions* options) +{ + const FFDiskResult* disks = ffDetectDisks(); + if(disks->error.length > 0) + { + ffPrintError(instance, FF_DISK_MODULE_NAME, 0, &options->moduleArgs, "%s", disks->error.chars); + return; + } + + if(options->folders.length == 0) + printAutodetected(instance, options, &disks->disks); + else + printMountpoints(instance, options, &disks->disks); +} + + +void ffInitDiskOptions(FFDiskOptions* options) +{ + options->moduleName = FF_DISK_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + + ffStrbufInit(&options->folders); + options->showTypes = FF_DISK_TYPE_REGULAR_BIT | FF_DISK_TYPE_EXTERNAL_BIT; +} + +bool ffParseDiskCommandOptions(FFDiskOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_DISK_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (strcasecmp(subKey, "folders") == 0) + { + ffOptionParseString(key, value, &options->folders); + return true; + } + + if (strcasecmp(subKey, "show-regular") == 0) + { + if (ffOptionParseBoolean(value)) + options->showTypes |= FF_DISK_TYPE_REGULAR_BIT; + else + options->showTypes &= ~FF_DISK_TYPE_REGULAR_BIT; + return true; + } + + if (strcasecmp(subKey, "show-removable") == 0) + { + if (ffOptionParseBoolean(value)) + options->showTypes |= FF_DISK_TYPE_EXTERNAL_BIT; + else + options->showTypes &= ~FF_DISK_TYPE_EXTERNAL_BIT; + return true; + } + + if (strcasecmp(subKey, "show-hidden") == 0) + { + if (ffOptionParseBoolean(value)) + options->showTypes |= FF_DISK_TYPE_HIDDEN_BIT; + else + options->showTypes &= ~FF_DISK_TYPE_HIDDEN_BIT; + return true; + } + + if (strcasecmp(subKey, "show-subvolumes") == 0) + { + if (ffOptionParseBoolean(value)) + options->showTypes |= FF_DISK_TYPE_SUBVOLUME_BIT; + else + options->showTypes &= ~FF_DISK_TYPE_SUBVOLUME_BIT; + return true; + } + + if (strcasecmp(subKey, "show-unknown") == 0) + { + if (ffOptionParseBoolean(value)) + options->showTypes |= FF_DISK_TYPE_UNKNOWN_BIT; + else + options->showTypes &= ~FF_DISK_TYPE_UNKNOWN_BIT; + return true; + } + + return false; +} + +void ffDestroyDiskOptions(FFDiskOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseDiskJsonObject(FFinstance* instance, json_object* module) +{ + FFDiskOptions __attribute__((__cleanup__(ffDestroyDiskOptions))) options; + ffInitDiskOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + if (strcasecmp(key, "folders") == 0) + { + ffStrbufSetS(&options.folders, json_object_get_string(val)); + continue; + } + + if (strcasecmp(key, "showRemovable") == 0) + { + if (json_object_get_boolean(val)) + options.showTypes |= FF_DISK_TYPE_EXTERNAL_BIT; + else + options.showTypes &= ~FF_DISK_TYPE_EXTERNAL_BIT; + continue; + } + + if (strcasecmp(key, "showHidden") == 0) + { + if (json_object_get_boolean(val)) + options.showTypes |= FF_DISK_TYPE_HIDDEN_BIT; + else + options.showTypes &= ~FF_DISK_TYPE_HIDDEN_BIT; + continue; + } + + if (strcasecmp(key, "showSubvolumes") == 0) + { + if (json_object_get_boolean(val)) + options.showTypes |= FF_DISK_TYPE_SUBVOLUME_BIT; + else + options.showTypes &= ~FF_DISK_TYPE_SUBVOLUME_BIT; + continue; + } + + if (strcasecmp(key, "show-unknown") == 0) + { + if (json_object_get_boolean(val)) + options.showTypes |= FF_DISK_TYPE_UNKNOWN_BIT; + else + options.showTypes &= ~FF_DISK_TYPE_UNKNOWN_BIT; + continue; + } + + ffPrintError(instance, FF_DISK_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintDisk(instance, &options); +} +#endif diff --git a/src/modules/disk/disk.h b/src/modules/disk/disk.h new file mode 100644 index 000000000..5d3fc05ba --- /dev/null +++ b/src/modules/disk/disk.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_DISK_MODULE_NAME "Disk" + +void ffPrintDisk(FFinstance* instance, FFDiskOptions* options); +void ffInitDiskOptions(FFDiskOptions* options); +bool ffParseDiskCommandOptions(FFDiskOptions* options, const char* key, const char* value); +void ffDestroyDiskOptions(FFDiskOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseDiskJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/disk/option.h b/src/modules/disk/option.h new file mode 100644 index 000000000..702e5bcbf --- /dev/null +++ b/src/modules/disk/option.h @@ -0,0 +1,24 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef enum FFDiskType +{ + FF_DISK_TYPE_NONE = 0, + FF_DISK_TYPE_REGULAR_BIT = 1 << 0, + FF_DISK_TYPE_HIDDEN_BIT = 1 << 1, + FF_DISK_TYPE_EXTERNAL_BIT = 1 << 2, + FF_DISK_TYPE_SUBVOLUME_BIT = 1 << 3, + FF_DISK_TYPE_UNKNOWN_BIT = 1 << 4, +} FFDiskType; + +typedef struct FFDiskOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + FFstrbuf folders; + FFDiskType showTypes; +} FFDiskOptions; diff --git a/src/modules/display.c b/src/modules/display.c deleted file mode 100644 index f4dddbe1f..000000000 --- a/src/modules/display.c +++ /dev/null @@ -1,108 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/displayserver/displayserver.h" - -#define FF_DISPLAY_MODULE_NAME "Display" -#define FF_DISPLAY_NUM_FORMAT_ARGS 7 - -void ffPrintDisplay(FFinstance* instance) -{ - #ifdef __ANDROID__ - ffPrintError(instance, FF_DISPLAY_MODULE_NAME, 0, &instance->config.display, "Display detection is not supported on Android"); - return; - #endif - - const FFDisplayServerResult* dsResult = ffConnectDisplayServer(instance); - - if (instance->config.displayCompactType != FF_DISPLAY_COMPACT_TYPE_NONE) - { - ffPrintLogoAndKey(instance, FF_DISPLAY_MODULE_NAME, 0, &instance->config.display.key); - - int index = 0; - FF_LIST_FOR_EACH(FFDisplayResult, result, dsResult->displays) - { - if (instance->config.displayCompactType & FF_DISPLAY_COMPACT_TYPE_ORIGINAL_BIT) - { - if (index++) putchar(' '); - printf("%ix%i", result->width, result->height); - } - if (instance->config.displayCompactType & FF_DISPLAY_COMPACT_TYPE_SCALED_BIT) - { - if (index++) putchar(' '); - printf("%ix%i", result->scaledWidth, result->scaledHeight); - } - ffStrbufDestroy(&result->name); - } - putchar('\n'); - return; - } - - FF_STRBUF_AUTO_DESTROY key; - ffStrbufInit(&key); - - for(uint32_t i = 0; i < dsResult->displays.length; i++) - { - FFDisplayResult* result = ffListGet(&dsResult->displays, i); - uint8_t moduleIndex = dsResult->displays.length == 1 ? 0 : (uint8_t) (i + 1); - const char* displayType = result->type == FF_DISPLAY_TYPE_UNKNOWN ? NULL : result->type == FF_DISPLAY_TYPE_BUILTIN ? "built-in" : "external"; - - if(instance->config.display.outputFormat.length == 0) - { - if(result->name.length || (moduleIndex > 0 && displayType)) - { - ffStrbufClear(&key); - if(instance->config.display.key.length == 0) - { - ffStrbufAppendF(&key, "%s (%s)", FF_DISPLAY_MODULE_NAME, result->name.length ? result->name.chars : displayType); - } - else - { - ffParseFormatString(&key, &instance->config.display.key, 1, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_UINT, &i}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->name}, - {FF_FORMAT_ARG_TYPE_STRING, displayType}, - }); - } - ffPrintLogoAndKey(instance, key.chars, 0, NULL); - } - else - { - ffPrintLogoAndKey(instance, FF_DISPLAY_MODULE_NAME, moduleIndex, &instance->config.display.key); - } - - printf("%ix%i", result->width, result->height); - - if(result->refreshRate > 0) - { - if(instance->config.displayPreciseRefreshRate) - printf(" @ %gHz", ((int) (result->refreshRate * 1000 + 0.5)) / 1000.0); - else - printf(" @ %iHz", (uint32_t) (result->refreshRate + 0.5)); - } - - if( - result->scaledWidth > 0 && result->scaledWidth != result->width && - result->scaledHeight > 0 && result->scaledHeight != result->height) - printf(" (as %ix%i)", result->scaledWidth, result->scaledHeight); - - putchar('\n'); - } - else - { - ffPrintFormat(instance, FF_DISPLAY_MODULE_NAME, moduleIndex, &instance->config.display, FF_DISPLAY_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_UINT, &result->width}, - {FF_FORMAT_ARG_TYPE_UINT, &result->height}, - {FF_FORMAT_ARG_TYPE_DOUBLE, &result->refreshRate}, - {FF_FORMAT_ARG_TYPE_UINT, &result->scaledWidth}, - {FF_FORMAT_ARG_TYPE_UINT, &result->scaledHeight}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->name}, - {FF_FORMAT_ARG_TYPE_STRING, displayType}, - }); - } - - ffStrbufDestroy(&result->name); - } - - if(dsResult->displays.length == 0) - ffPrintError(instance, FF_DISPLAY_MODULE_NAME, 0, &instance->config.display, "Couldn't detect display"); -} diff --git a/src/modules/display/display.c b/src/modules/display/display.c new file mode 100644 index 000000000..40045c6e5 --- /dev/null +++ b/src/modules/display/display.c @@ -0,0 +1,206 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/displayserver/displayserver.h" +#include "modules/display/display.h" + +#define FF_DISPLAY_NUM_FORMAT_ARGS 7 + +void ffPrintDisplay(FFinstance* instance, FFDisplayOptions* options) +{ + #ifdef __ANDROID__ + ffPrintError(instance, FF_DISPLAY_MODULE_NAME, 0, &instance->config.display.moduleArgs, "Display detection is not supported on Android"); + return; + #endif + + const FFDisplayServerResult* dsResult = ffConnectDisplayServer(instance); + + if(dsResult->displays.length == 0) + { + ffPrintError(instance, FF_DISPLAY_MODULE_NAME, 0, &instance->config.display.moduleArgs, "Couldn't detect display"); + return; + } + + if (options->compactType != FF_DISPLAY_COMPACT_TYPE_NONE) + { + ffPrintLogoAndKey(instance, FF_DISPLAY_MODULE_NAME, 0, &options->moduleArgs.key); + + int index = 0; + FF_LIST_FOR_EACH(FFDisplayResult, result, dsResult->displays) + { + if (options->compactType & FF_DISPLAY_COMPACT_TYPE_ORIGINAL_BIT) + { + if (index++) putchar(' '); + printf("%ix%i", result->width, result->height); + } + if (options->compactType & FF_DISPLAY_COMPACT_TYPE_SCALED_BIT) + { + if (index++) putchar(' '); + printf("%ix%i", result->scaledWidth, result->scaledHeight); + } + ffStrbufDestroy(&result->name); + } + putchar('\n'); + return; + } + + FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate(); + + for(uint32_t i = 0; i < dsResult->displays.length; i++) + { + FFDisplayResult* result = ffListGet(&dsResult->displays, i); + uint8_t moduleIndex = dsResult->displays.length == 1 ? 0 : (uint8_t) (i + 1); + const char* displayType = result->type == FF_DISPLAY_TYPE_UNKNOWN ? NULL : result->type == FF_DISPLAY_TYPE_BUILTIN ? "built-in" : "external"; + + if(options->moduleArgs.outputFormat.length == 0) + { + if(result->name.length || (moduleIndex > 0 && displayType)) + { + ffStrbufClear(&key); + if(options->moduleArgs.key.length == 0) + { + ffStrbufAppendF(&key, "%s (%s)", FF_DISPLAY_MODULE_NAME, result->name.length ? result->name.chars : displayType); + } + else + { + ffParseFormatString(&key, &options->moduleArgs.key, 1, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_UINT, &i}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->name}, + {FF_FORMAT_ARG_TYPE_STRING, displayType}, + }); + } + ffPrintLogoAndKey(instance, key.chars, 0, NULL); + } + else + { + ffPrintLogoAndKey(instance, FF_DISPLAY_MODULE_NAME, moduleIndex, &options->moduleArgs.key); + } + + printf("%ix%i", result->width, result->height); + + if(result->refreshRate > 0) + { + if(options->preciseRefreshRate) + printf(" @ %gHz", ((int) (result->refreshRate * 1000 + 0.5)) / 1000.0); + else + printf(" @ %iHz", (uint32_t) (result->refreshRate + 0.5)); + } + + if( + result->scaledWidth > 0 && result->scaledWidth != result->width && + result->scaledHeight > 0 && result->scaledHeight != result->height) + printf(" (as %ix%i)", result->scaledWidth, result->scaledHeight); + + putchar('\n'); + } + else + { + ffPrintFormat(instance, FF_DISPLAY_MODULE_NAME, moduleIndex, &options->moduleArgs, FF_DISPLAY_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_UINT, &result->width}, + {FF_FORMAT_ARG_TYPE_UINT, &result->height}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &result->refreshRate}, + {FF_FORMAT_ARG_TYPE_UINT, &result->scaledWidth}, + {FF_FORMAT_ARG_TYPE_UINT, &result->scaledHeight}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->name}, + {FF_FORMAT_ARG_TYPE_STRING, displayType}, + }); + } + + ffStrbufDestroy(&result->name); + } +} + +void ffInitDisplayOptions(FFDisplayOptions* options) +{ + options->moduleName = FF_DISPLAY_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + options->compactType = FF_DISPLAY_COMPACT_TYPE_NONE; + options->detectName = false; + options->preciseRefreshRate = false; +} + +bool ffParseDisplayCommandOptions(FFDisplayOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_DISPLAY_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (strcasecmp(subKey, "compact-type") == 0) + { + options->compactType = (FFDisplayCompactType) ffOptionParseEnum(key, value, (FFKeyValuePair[]) { + { "none", FF_DISPLAY_COMPACT_TYPE_NONE }, + { "original", FF_DISPLAY_COMPACT_TYPE_ORIGINAL_BIT }, + { "scaled", FF_DISPLAY_COMPACT_TYPE_SCALED_BIT }, + {}, + }); + return true; + } + + if (strcasecmp(subKey, "detect-name") == 0) + { + options->detectName = ffOptionParseBoolean(value); + return true; + } + + if (strcasecmp(subKey, "precise-refresh-rate") == 0) + { + options->preciseRefreshRate = ffOptionParseBoolean(value); + return true; + } + + return false; +} + +void ffDestroyDisplayOptions(FFDisplayOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseDisplayJsonObject(FFinstance* instance, json_object* module) +{ + FFDisplayOptions __attribute__((__cleanup__(ffDestroyDisplayOptions))) options; + ffInitDisplayOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + if (strcasecmp(key, "compactType") == 0) + { + int value; + const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) { + { "none", FF_DISPLAY_COMPACT_TYPE_NONE }, + { "original", FF_DISPLAY_COMPACT_TYPE_ORIGINAL_BIT }, + { "scaled", FF_DISPLAY_COMPACT_TYPE_SCALED_BIT }, + {}, + }); + if (error) + ffPrintError(instance, FF_DISPLAY_MODULE_NAME, 0, &options.moduleArgs, "Invalid %s value: %s", key, error); + else + options.compactType = (FFDisplayCompactType) value; + continue; + } + + if (strcasecmp(key, "detectName") == 0) + { + options.detectName = json_object_get_boolean(val); + continue; + } + + if (strcasecmp(key, "preciseRefreshRate") == 0) + { + options.preciseRefreshRate = json_object_get_boolean(val); + continue; + } + + ffPrintError(instance, FF_DISPLAY_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintDisplay(instance, &options); +} +#endif diff --git a/src/modules/display/display.h b/src/modules/display/display.h new file mode 100644 index 000000000..f5f31627c --- /dev/null +++ b/src/modules/display/display.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_DISPLAY_MODULE_NAME "Display" + +void ffPrintDisplay(FFinstance* instance, FFDisplayOptions* options); +void ffInitDisplayOptions(FFDisplayOptions* options); +bool ffParseDisplayCommandOptions(FFDisplayOptions* options, const char* key, const char* value); +void ffDestroyDisplayOptions(FFDisplayOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseDisplayJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/display/option.h b/src/modules/display/option.h new file mode 100644 index 000000000..4e47b1bee --- /dev/null +++ b/src/modules/display/option.h @@ -0,0 +1,22 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef enum FFDisplayCompactType +{ + FF_DISPLAY_COMPACT_TYPE_NONE = 0, + FF_DISPLAY_COMPACT_TYPE_ORIGINAL_BIT = 1 << 0, + FF_DISPLAY_COMPACT_TYPE_SCALED_BIT = 1 << 1, +} FFDisplayCompactType; + +typedef struct FFDisplayOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + FFDisplayCompactType compactType; + bool detectName; + bool preciseRefreshRate; +} FFDisplayOptions; diff --git a/src/modules/font.c b/src/modules/font.c deleted file mode 100644 index c33d144fe..000000000 --- a/src/modules/font.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/font/font.h" -#include "detection/displayserver/displayserver.h" - -#define FF_FONT_MODULE_NAME "Font" -#define FF_FONT_NUM_FORMAT_ARGS (FF_DETECT_FONT_NUM_FONTS + 1) - -void ffPrintFont(FFinstance* instance) -{ - const FFFontResult* font = ffDetectFont(instance); - - if(font->error.length > 0) - { - ffPrintError(instance, FF_FONT_MODULE_NAME, 0, &instance->config.font, "%s", font->error.chars); - return; - } - - if(instance->config.font.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_FONT_MODULE_NAME, 0, &instance->config.font.key); - ffStrbufPutTo(&font->display, stdout); - } - else - { - ffPrintFormat(instance, FF_FONT_MODULE_NAME, 0, &instance->config.font, FF_FONT_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &font->fonts[0]}, - {FF_FORMAT_ARG_TYPE_STRBUF, &font->fonts[1]}, - {FF_FORMAT_ARG_TYPE_STRBUF, &font->fonts[2]}, - {FF_FORMAT_ARG_TYPE_STRBUF, &font->fonts[3]}, - {FF_FORMAT_ARG_TYPE_STRBUF, &font->display}, - }); - } -} diff --git a/src/modules/font/font.c b/src/modules/font/font.c new file mode 100644 index 000000000..be9159c6f --- /dev/null +++ b/src/modules/font/font.c @@ -0,0 +1,75 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/font/font.h" +#include "modules/font/font.h" + +#define FF_FONT_NUM_FORMAT_ARGS (FF_DETECT_FONT_NUM_FONTS + 1) + +void ffPrintFont(FFinstance* instance, FFFontOptions* options) +{ + const FFFontResult* font = ffDetectFont(instance); + + if(font->error.length > 0) + { + ffPrintError(instance, FF_FONT_MODULE_NAME, 0, &options->moduleArgs, "%s", font->error.chars); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_FONT_MODULE_NAME, 0, &options->moduleArgs.key); + ffStrbufPutTo(&font->display, stdout); + } + else + { + ffPrintFormat(instance, FF_FONT_MODULE_NAME, 0, &options->moduleArgs, FF_FONT_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &font->fonts[0]}, + {FF_FORMAT_ARG_TYPE_STRBUF, &font->fonts[1]}, + {FF_FORMAT_ARG_TYPE_STRBUF, &font->fonts[2]}, + {FF_FORMAT_ARG_TYPE_STRBUF, &font->fonts[3]}, + {FF_FORMAT_ARG_TYPE_STRBUF, &font->display}, + }); + } +} + +void ffInitFontOptions(FFFontOptions* options) +{ + options->moduleName = FF_FONT_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseFontCommandOptions(FFFontOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_FONT_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyFontOptions(FFFontOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseFontJsonObject(FFinstance* instance, json_object* module) +{ + FFFontOptions __attribute__((__cleanup__(ffDestroyFontOptions))) options; + ffInitFontOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_FONT_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintFont(instance, &options); +} +#endif diff --git a/src/modules/font/font.h b/src/modules/font/font.h new file mode 100644 index 000000000..36627b72f --- /dev/null +++ b/src/modules/font/font.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_FONT_MODULE_NAME "Font" + +void ffPrintFont(FFinstance* instance, FFFontOptions* options); +void ffInitFontOptions(FFFontOptions* options); +bool ffParseFontCommandOptions(FFFontOptions* options, const char* key, const char* value); +void ffDestroyFontOptions(FFFontOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseFontJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/font/option.h b/src/modules/font/option.h new file mode 100644 index 000000000..9318bac4b --- /dev/null +++ b/src/modules/font/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFFontOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFFontOptions; diff --git a/src/modules/gamepad.c b/src/modules/gamepad.c deleted file mode 100644 index 6bcb332f8..000000000 --- a/src/modules/gamepad.c +++ /dev/null @@ -1,48 +0,0 @@ -#include "common/printing.h" -#include "detection/gamepad/gamepad.h" - -#define FF_GAMEPAD_MODULE_NAME "Gamepad" -#define FF_GAMEPAD_NUM_FORMAT_ARGS 2 - -static void printDevice(FFinstance* instance, const FFGamepadDevice* device, uint8_t index) -{ - if(instance->config.gamepad.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_GAMEPAD_MODULE_NAME, index, &instance->config.gamepad.key); - ffStrbufPutTo(&device->name, stdout); - } - else - { - ffPrintFormat(instance, FF_GAMEPAD_MODULE_NAME, index, &instance->config.gamepad, FF_GAMEPAD_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &device->name}, - {FF_FORMAT_ARG_TYPE_STRBUF, &device->identifier}, - }); - } -} - -void ffPrintGamepad(FFinstance* instance) -{ - FF_LIST_AUTO_DESTROY result; - ffListInit(&result, sizeof(FFGamepadDevice)); - const char* error = ffDetectGamepad(instance, &result); - - if(error) - { - ffPrintError(instance, FF_GAMEPAD_MODULE_NAME, 0, &instance->config.gamepad, "%s", error); - return; - } - - if(!result.length) - { - ffPrintError(instance, FF_GAMEPAD_MODULE_NAME, 0, &instance->config.gamepad, "No devices detected"); - return; - } - - uint8_t index = 0; - FF_LIST_FOR_EACH(FFGamepadDevice, device, result) - { - printDevice(instance, device, result.length > 1 ? ++index : 0); - ffStrbufDestroy(&device->identifier); - ffStrbufDestroy(&device->name); - } -} diff --git a/src/modules/gamepad/gamepad.c b/src/modules/gamepad/gamepad.c new file mode 100644 index 000000000..6d4b37c53 --- /dev/null +++ b/src/modules/gamepad/gamepad.c @@ -0,0 +1,90 @@ +#include "common/printing.h" +#include "detection/gamepad/gamepad.h" +#include "modules/gamepad/gamepad.h" + +#define FF_GAMEPAD_NUM_FORMAT_ARGS 2 + +static void printDevice(FFinstance* instance, FFGamepadOptions* options, const FFGamepadDevice* device, uint8_t index) +{ + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_GAMEPAD_MODULE_NAME, index, &options->moduleArgs.key); + ffStrbufPutTo(&device->name, stdout); + } + else + { + ffPrintFormat(instance, FF_GAMEPAD_MODULE_NAME, index, &options->moduleArgs, FF_GAMEPAD_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &device->name}, + {FF_FORMAT_ARG_TYPE_STRBUF, &device->identifier}, + }); + } +} + +void ffPrintGamepad(FFinstance* instance, FFGamepadOptions* options) +{ + FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFGamepadDevice)); + + const char* error = ffDetectGamepad(instance, &result); + + if(error) + { + ffPrintError(instance, FF_GAMEPAD_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + if(!result.length) + { + ffPrintError(instance, FF_GAMEPAD_MODULE_NAME, 0, &options->moduleArgs, "No devices detected"); + return; + } + + uint8_t index = 0; + FF_LIST_FOR_EACH(FFGamepadDevice, device, result) + { + printDevice(instance, options, device, result.length > 1 ? ++index : 0); + ffStrbufDestroy(&device->identifier); + ffStrbufDestroy(&device->name); + } +} + +void ffInitGamepadOptions(FFGamepadOptions* options) +{ + options->moduleName = FF_GAMEPAD_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseGamepadCommandOptions(FFGamepadOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_GAMEPAD_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyGamepadOptions(FFGamepadOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseGamepadJsonObject(FFinstance* instance, json_object* module) +{ + FFGamepadOptions __attribute__((__cleanup__(ffDestroyGamepadOptions))) options; + ffInitGamepadOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_GAMEPAD_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintGamepad(instance, &options); +} +#endif diff --git a/src/modules/gamepad/gamepad.h b/src/modules/gamepad/gamepad.h new file mode 100644 index 000000000..2ada4ad2f --- /dev/null +++ b/src/modules/gamepad/gamepad.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_GAMEPAD_MODULE_NAME "Gamepad" + +void ffPrintGamepad(FFinstance* instance, FFGamepadOptions* options); +void ffInitGamepadOptions(FFGamepadOptions* options); +bool ffParseGamepadCommandOptions(FFGamepadOptions* options, const char* key, const char* value); +void ffDestroyGamepadOptions(FFGamepadOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseGamepadJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/gamepad/option.h b/src/modules/gamepad/option.h new file mode 100644 index 000000000..6cca7f2fd --- /dev/null +++ b/src/modules/gamepad/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFGamepadOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFGamepadOptions; diff --git a/src/modules/gpu.c b/src/modules/gpu.c deleted file mode 100644 index 0033d33be..000000000 --- a/src/modules/gpu.c +++ /dev/null @@ -1,104 +0,0 @@ -#include "fastfetch.h" -#include "common/bar.h" -#include "common/parsing.h" -#include "common/printing.h" -#include "detection/host/host.h" -#include "detection/gpu/gpu.h" - -#include - -#define FF_GPU_MODULE_NAME "GPU" -#define FF_GPU_NUM_FORMAT_ARGS 6 - -static void printGPUResult(FFinstance* instance, uint8_t index, const FFGPUResult* gpu) -{ - if(instance->config.gpu.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_GPU_MODULE_NAME, index, &instance->config.gpu.key); - - FF_STRBUF_AUTO_DESTROY output; - ffStrbufInitA(&output, gpu->vendor.length + 1 + gpu->name.length); - - if(gpu->vendor.length > 0 && !ffStrbufStartsWith(&gpu->name, &gpu->vendor)) - { - ffStrbufAppend(&output, &gpu->vendor); - ffStrbufAppendC(&output, ' '); - } - - ffStrbufAppend(&output, &gpu->name); - - if(gpu->coreCount != FF_GPU_CORE_COUNT_UNSET) - ffStrbufAppendF(&output, " (%d)", gpu->coreCount); - - if(gpu->temperature == gpu->temperature) //FF_GPU_TEMP_UNSET - ffStrbufAppendF(&output, " - %.1f°C", gpu->temperature); - - if(gpu->dedicated.total != FF_GPU_VMEM_SIZE_UNSET && gpu->dedicated.total != 0) - { - ffStrbufAppendS(&output, " ("); - - if(gpu->dedicated.used != FF_GPU_VMEM_SIZE_UNSET) - { - ffParseSize(gpu->dedicated.used, instance->config.binaryPrefixType, &output); - ffStrbufAppendS(&output, " / "); - } - ffParseSize(gpu->dedicated.total, instance->config.binaryPrefixType, &output); - if(gpu->dedicated.used != FF_GPU_VMEM_SIZE_UNSET) - { - ffStrbufAppendS(&output, ", "); - ffAppendPercentNum(instance, &output, (uint8_t) (gpu->dedicated.used * 100 / gpu->dedicated.total), 50, 80, false); - } - ffStrbufAppendC(&output, ')'); - } - - ffStrbufPutTo(&output, stdout); - } - else - { - const char* type; - if(gpu->type == FF_GPU_TYPE_INTEGRATED) - type = "Integrated"; - else if(gpu->type == FF_GPU_TYPE_DISCRETE) - type = "Discrete"; - else - type = "Unknown"; - - ffPrintFormat(instance, FF_GPU_MODULE_NAME, index, &instance->config.gpu, FF_GPU_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &gpu->vendor}, - {FF_FORMAT_ARG_TYPE_STRBUF, &gpu->name}, - {FF_FORMAT_ARG_TYPE_STRBUF, &gpu->driver}, - {FF_FORMAT_ARG_TYPE_DOUBLE, &gpu->temperature}, - {FF_FORMAT_ARG_TYPE_INT, &gpu->coreCount}, - {FF_FORMAT_ARG_TYPE_STRING, type}, - }); - } -} - -void ffPrintGPU(FFinstance* instance) -{ - const FFlist* gpus = ffDetectGPU(instance); - - FFlist selectedGpus; - ffListInitA(&selectedGpus, sizeof(const FFGPUResult*), gpus->length); - - for(uint32_t i = 0; i < gpus->length; i++) - { - const FFGPUResult* gpu = ffListGet(gpus, i); - - if(gpu->type == FF_GPU_TYPE_INTEGRATED && instance->config.gpuHideIntegrated) - continue; - - if(gpu->type == FF_GPU_TYPE_DISCRETE && instance->config.gpuHideDiscrete) - continue; - - * (const FFGPUResult**) ffListAdd(&selectedGpus) = gpu; - } - - for(uint32_t i = 0; i < selectedGpus.length; i++) - printGPUResult(instance, selectedGpus.length == 1 ? 0 : (uint8_t) (i + 1), * (const FFGPUResult**) ffListGet(&selectedGpus, i)); - - if(selectedGpus.length == 0) - ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpu, "No GPUs found"); - - ffListDestroy(&selectedGpus); -} diff --git a/src/modules/gpu/gpu.c b/src/modules/gpu/gpu.c new file mode 100644 index 000000000..1e3fd17ee --- /dev/null +++ b/src/modules/gpu/gpu.c @@ -0,0 +1,195 @@ +#include "fastfetch.h" +#include "common/bar.h" +#include "common/parsing.h" +#include "common/printing.h" +#include "detection/host/host.h" +#include "detection/gpu/gpu.h" +#include "modules/gpu/gpu.h" + +#include + +#define FF_GPU_NUM_FORMAT_ARGS 6 + +static void printGPUResult(FFinstance* instance, FFGPUOptions* options, uint8_t index, const FFGPUResult* gpu) +{ + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_GPU_MODULE_NAME, index, &options->moduleArgs.key); + + FF_STRBUF_AUTO_DESTROY output = ffStrbufCreateA(gpu->vendor.length + 1 + gpu->name.length); + + if(gpu->vendor.length > 0 && !ffStrbufStartsWith(&gpu->name, &gpu->vendor)) + { + ffStrbufAppend(&output, &gpu->vendor); + ffStrbufAppendC(&output, ' '); + } + + ffStrbufAppend(&output, &gpu->name); + + if(gpu->coreCount != FF_GPU_CORE_COUNT_UNSET) + ffStrbufAppendF(&output, " (%d)", gpu->coreCount); + + if(gpu->temperature == gpu->temperature) //FF_GPU_TEMP_UNSET + ffStrbufAppendF(&output, " - %.1f°C", gpu->temperature); + + if(gpu->dedicated.total != FF_GPU_VMEM_SIZE_UNSET && gpu->dedicated.total != 0) + { + ffStrbufAppendS(&output, " ("); + + if(gpu->dedicated.used != FF_GPU_VMEM_SIZE_UNSET) + { + ffParseSize(gpu->dedicated.used, instance->config.binaryPrefixType, &output); + ffStrbufAppendS(&output, " / "); + } + ffParseSize(gpu->dedicated.total, instance->config.binaryPrefixType, &output); + if(gpu->dedicated.used != FF_GPU_VMEM_SIZE_UNSET) + { + ffStrbufAppendS(&output, ", "); + ffAppendPercentNum(instance, &output, (uint8_t) (gpu->dedicated.used * 100 / gpu->dedicated.total), 50, 80, false); + } + ffStrbufAppendC(&output, ')'); + } + + ffStrbufPutTo(&output, stdout); + } + else + { + const char* type; + if(gpu->type == FF_GPU_TYPE_INTEGRATED) + type = "Integrated"; + else if(gpu->type == FF_GPU_TYPE_DISCRETE) + type = "Discrete"; + else + type = "Unknown"; + + ffPrintFormat(instance, FF_GPU_MODULE_NAME, index, &options->moduleArgs, FF_GPU_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &gpu->vendor}, + {FF_FORMAT_ARG_TYPE_STRBUF, &gpu->name}, + {FF_FORMAT_ARG_TYPE_STRBUF, &gpu->driver}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &gpu->temperature}, + {FF_FORMAT_ARG_TYPE_INT, &gpu->coreCount}, + {FF_FORMAT_ARG_TYPE_STRING, type}, + }); + } +} + +void ffPrintGPU(FFinstance* instance, FFGPUOptions* options) +{ + const FFlist* gpus = ffDetectGPU(instance); + + FF_LIST_AUTO_DESTROY selectedGPUs; + ffListInitA(&selectedGPUs, sizeof(const FFGPUResult*), gpus->length); + + FF_LIST_FOR_EACH(FFGPUResult, gpu, *gpus) + { + if(gpu->type == FF_GPU_TYPE_INTEGRATED && options->hideType == FF_GPU_TYPE_INTEGRATED) + continue; + + if(gpu->type == FF_GPU_TYPE_DISCRETE && options->hideType == FF_GPU_TYPE_DISCRETE) + continue; + + * (const FFGPUResult**) ffListAdd(&selectedGPUs) = gpu; + } + + for(uint32_t i = 0; i < selectedGPUs.length; i++) + printGPUResult(instance, options, selectedGPUs.length == 1 ? 0 : (uint8_t) (i + 1), * (const FFGPUResult**) ffListGet(&selectedGPUs, i)); + + if(selectedGPUs.length == 0) + ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &options->moduleArgs, "No GPUs found"); +} + +void ffInitGPUOptions(FFGPUOptions* options) +{ + options->moduleName = FF_GPU_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + + options->forceVulkan = false; + options->temp = false; + options->hideType = FF_GPU_TYPE_UNKNOWN; +} + +bool ffParseGPUCommandOptions(FFGPUOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_GPU_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (strcasecmp(subKey, "force-vulkan") == 0) + { + options->forceVulkan = ffOptionParseBoolean(value); + return true; + } + + if (strcasecmp(subKey, "temp") == 0) + { + options->temp = ffOptionParseBoolean(value); + return true; + } + + if (strcasecmp(subKey, "hide-type") == 0) + { + options->hideType = (FFGPUType) ffOptionParseEnum(key, value, (FFKeyValuePair[]) { + { "none", FF_GPU_TYPE_UNKNOWN }, + { "intergrated", FF_GPU_TYPE_INTEGRATED }, + { "discrete", FF_GPU_TYPE_DISCRETE }, + {}, + }); + } + + return false; +} + +void ffDestroyGPUOptions(FFGPUOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseGPUJsonObject(FFinstance* instance, json_object* module) +{ + FFGPUOptions __attribute__((__cleanup__(ffDestroyGPUOptions))) options; + ffInitGPUOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + if (strcasecmp(key, "temp") == 0) + { + options.temp = (bool) json_object_get_boolean(val); + continue; + } + + if (strcasecmp(key, "forceVulkan") == 0) + { + options.forceVulkan = (bool) json_object_get_boolean(val); + continue; + } + + if (strcasecmp(key, "hideType") == 0) + { + int value; + const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) { + { "none", FF_GPU_TYPE_UNKNOWN }, + { "intergrated", FF_GPU_TYPE_INTEGRATED }, + { "discrete", FF_GPU_TYPE_DISCRETE }, + {}, + }); + if (error) + ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &options.moduleArgs, "Invalid %s value: %s", key, error); + else + options.hideType = (FFGPUType) value; + continue; + } + + ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintGPU(instance, &options); +} +#endif diff --git a/src/modules/gpu/gpu.h b/src/modules/gpu/gpu.h new file mode 100644 index 000000000..156e6ba89 --- /dev/null +++ b/src/modules/gpu/gpu.h @@ -0,0 +1,13 @@ +#pragma once + +#define FF_GPU_MODULE_NAME "GPU" + +void ffPrintGPU(FFinstance* instance, FFGPUOptions* options); +void ffInitGPUOptions(FFGPUOptions* options); +bool ffParseGPUCommandOptions(FFGPUOptions* options, const char* key, const char* value); +void ffDestroyGPUOptions(FFGPUOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseGPUJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/gpu/option.h b/src/modules/gpu/option.h new file mode 100644 index 000000000..0aaa6a6f7 --- /dev/null +++ b/src/modules/gpu/option.h @@ -0,0 +1,22 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef enum FFGPUType +{ + FF_GPU_TYPE_UNKNOWN, + FF_GPU_TYPE_INTEGRATED, + FF_GPU_TYPE_DISCRETE, +} FFGPUType; + +typedef struct FFGPUOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + FFGPUType hideType; + bool temp; + bool forceVulkan; +} FFGPUOptions; diff --git a/src/modules/host.c b/src/modules/host.c deleted file mode 100644 index 9fa3bafee..000000000 --- a/src/modules/host.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/host/host.h" - -#define FF_HOST_MODULE_NAME "Host" -#define FF_HOST_NUM_FORMAT_ARGS 5 - -void ffPrintHost(FFinstance* instance) -{ - const FFHostResult* host = ffDetectHost(); - - if(host->error.length > 0) - { - ffPrintError(instance, FF_HOST_MODULE_NAME, 0, &instance->config.host, "%*s", host->error.length, host->error.chars); - return; - } - - if(host->productFamily.length == 0 && host->productName.length == 0) - { - ffPrintError(instance, FF_HOST_MODULE_NAME, 0, &instance->config.host, "neither product_family nor product_name is set by O.E.M."); - return; - } - - if(instance->config.host.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_HOST_MODULE_NAME, 0, &instance->config.host.key); - - FFstrbuf output; - ffStrbufInit(&output); - - if(host->productName.length > 0) - ffStrbufAppend(&output, &host->productName); - else - ffStrbufAppend(&output, &host->productFamily); - - if(host->productVersion.length > 0 && !ffStrbufIgnCaseEqualS(&host->productVersion, "none")) - { - ffStrbufAppendF(&output, " (%s)", host->productVersion.chars); - } - - ffStrbufPutTo(&output, stdout); - - ffStrbufDestroy(&output); - } - else - { - ffPrintFormat(instance, FF_HOST_MODULE_NAME, 0, &instance->config.host, FF_HOST_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &host->productFamily}, - {FF_FORMAT_ARG_TYPE_STRBUF, &host->productName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &host->productVersion}, - {FF_FORMAT_ARG_TYPE_STRBUF, &host->productSku}, - {FF_FORMAT_ARG_TYPE_STRBUF, &host->sysVendor} - }); - } -} diff --git a/src/modules/host/host.c b/src/modules/host/host.c new file mode 100644 index 000000000..e6d18874e --- /dev/null +++ b/src/modules/host/host.c @@ -0,0 +1,94 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/host/host.h" +#include "modules/host/host.h" + +#define FF_HOST_NUM_FORMAT_ARGS 5 + +void ffPrintHost(FFinstance* instance, FFHostOptions* options) +{ + const FFHostResult* host = ffDetectHost(); + + if(host->error.length > 0) + { + ffPrintError(instance, FF_HOST_MODULE_NAME, 0, &options->moduleArgs, "%*s", host->error.length, host->error.chars); + return; + } + + if(host->productFamily.length == 0 && host->productName.length == 0) + { + ffPrintError(instance, FF_HOST_MODULE_NAME, 0, &options->moduleArgs, "neither product_family nor product_name is set by O.E.M."); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_HOST_MODULE_NAME, 0, &options->moduleArgs.key); + + FF_STRBUF_AUTO_DESTROY output = ffStrbufCreate(); + + if(host->productName.length > 0) + ffStrbufAppend(&output, &host->productName); + else + ffStrbufAppend(&output, &host->productFamily); + + if(host->productVersion.length > 0 && !ffStrbufIgnCaseEqualS(&host->productVersion, "none")) + { + ffStrbufAppendF(&output, " (%s)", host->productVersion.chars); + } + + ffStrbufPutTo(&output, stdout); + } + else + { + ffPrintFormat(instance, FF_HOST_MODULE_NAME, 0, &options->moduleArgs, FF_HOST_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &host->productFamily}, + {FF_FORMAT_ARG_TYPE_STRBUF, &host->productName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &host->productVersion}, + {FF_FORMAT_ARG_TYPE_STRBUF, &host->productSku}, + {FF_FORMAT_ARG_TYPE_STRBUF, &host->sysVendor} + }); + } +} + +void ffInitHostOptions(FFHostOptions* options) +{ + options->moduleName = FF_HOST_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseHostCommandOptions(FFHostOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_HOST_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyHostOptions(FFHostOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseHostJsonObject(FFinstance* instance, json_object* module) +{ + FFHostOptions __attribute__((__cleanup__(ffDestroyHostOptions))) options; + ffInitHostOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_HOST_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintHost(instance, &options); +} +#endif diff --git a/src/modules/host/host.h b/src/modules/host/host.h new file mode 100644 index 000000000..9801d8010 --- /dev/null +++ b/src/modules/host/host.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_HOST_MODULE_NAME "Host" + +void ffPrintHost(FFinstance* instance, FFHostOptions* options); +void ffInitHostOptions(FFHostOptions* options); +bool ffParseHostCommandOptions(FFHostOptions* options, const char* key, const char* value); +void ffDestroyHostOptions(FFHostOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseHostJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/host/option.h b/src/modules/host/option.h new file mode 100644 index 000000000..59073e934 --- /dev/null +++ b/src/modules/host/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFHostOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFHostOptions; diff --git a/src/modules/icons.c b/src/modules/icons.c deleted file mode 100644 index d6851b973..000000000 --- a/src/modules/icons.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/icons/icons.h" - -#define FF_ICONS_MODULE_NAME "Icons" -#define FF_ICONS_NUM_FORMAT_ARGS 1 - -void ffPrintIcons(FFinstance* instance) -{ - FF_STRBUF_AUTO_DESTROY icons; - ffStrbufInit(&icons); - const char* error = ffDetectIcons(instance, &icons); - - if(error) - { - ffPrintError(instance, FF_ICONS_MODULE_NAME, 0, &instance->config.icons, "%s", error); - return; - } - - if(instance->config.icons.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_ICONS_MODULE_NAME, 0, &instance->config.icons.key); - ffStrbufPutTo(&icons, stdout); - } - else - { - ffPrintFormat(instance, FF_ICONS_MODULE_NAME, 0, &instance->config.icons, FF_ICONS_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &icons} - }); - } -} diff --git a/src/modules/icons/icons.c b/src/modules/icons/icons.c new file mode 100644 index 000000000..e6ebbb8e2 --- /dev/null +++ b/src/modules/icons/icons.c @@ -0,0 +1,72 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/icons/icons.h" +#include "modules/icons/icons.h" + +#define FF_ICONS_NUM_FORMAT_ARGS 1 + +void ffPrintIcons(FFinstance* instance, FFIconsOptions* options) +{ + FF_STRBUF_AUTO_DESTROY icons = ffStrbufCreate(); + const char* error = ffDetectIcons(instance, &icons); + + if(error) + { + ffPrintError(instance, FF_ICONS_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_ICONS_MODULE_NAME, 0, &options->moduleArgs.key); + ffStrbufPutTo(&icons, stdout); + } + else + { + ffPrintFormat(instance, FF_ICONS_MODULE_NAME, 0, &options->moduleArgs, FF_ICONS_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &icons} + }); + } +} + +void ffInitIconsOptions(FFIconsOptions* options) +{ + options->moduleName = FF_ICONS_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseIconsCommandOptions(FFIconsOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_ICONS_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyIconsOptions(FFIconsOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseIconsJsonObject(FFinstance* instance, json_object* module) +{ + FFIconsOptions __attribute__((__cleanup__(ffDestroyIconsOptions))) options; + ffInitIconsOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_ICONS_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintIcons(instance, &options); +} +#endif diff --git a/src/modules/icons/icons.h b/src/modules/icons/icons.h new file mode 100644 index 000000000..780f9c352 --- /dev/null +++ b/src/modules/icons/icons.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_ICONS_MODULE_NAME "Icons" + +void ffPrintIcons(FFinstance* instance, FFIconsOptions* options); +void ffInitIconsOptions(FFIconsOptions* options); +bool ffParseIconsCommandOptions(FFIconsOptions* options, const char* key, const char* value); +void ffDestroyIconsOptions(FFIconsOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseIconsJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/icons/option.h b/src/modules/icons/option.h new file mode 100644 index 000000000..fc6427aa4 --- /dev/null +++ b/src/modules/icons/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFIconsOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFIconsOptions; diff --git a/src/modules/jsonconfig/jsonconfig.c b/src/modules/jsonconfig/jsonconfig.c new file mode 100644 index 000000000..c9f4b6efc --- /dev/null +++ b/src/modules/jsonconfig/jsonconfig.c @@ -0,0 +1,257 @@ +#include "modules/jsonconfig/jsonconfig.h" +#include "common/jsonconfig.h" +#include "common/printing.h" + +#ifdef FF_HAVE_JSONC + +#include "common/io/io.h" +#include "common/json.h" +#include "modules/modules.h" + +#include +#include + +static inline bool tryModule(FFinstance* instance, const char* type, json_object* module, const char* moduleName, void (*const f)(FFinstance *instance, json_object *module)) +{ + if (strcasecmp(type, moduleName) == 0) + { + if (module) json_object_object_del(module, "type"); // this line frees `type` + f(instance, module); + return true; + } + return false; +} + +static bool parseModuleJsonObject(FFinstance* instance, const char* type, json_object* module) +{ + switch (toupper(type[0])) + { + case 'B': { + return + tryModule(instance, type, module, FF_BATTERY_MODULE_NAME, ffParseBatteryJsonObject) || + tryModule(instance, type, module, FF_BIOS_MODULE_NAME, ffParseBiosJsonObject) || + tryModule(instance, type, module, FF_BLUETOOTH_MODULE_NAME, ffParseBluetoothJsonObject) || + tryModule(instance, type, module, FF_BOARD_MODULE_NAME, ffParseBoardJsonObject) || + tryModule(instance, type, module, FF_BREAK_MODULE_NAME, ffParseBreakJsonObject) || + tryModule(instance, type, module, FF_BRIGHTNESS_MODULE_NAME, ffParseBrightnessJsonObject) || + false; + } + + case 'C': { + return + tryModule(instance, type, module, FF_CHASSIS_MODULE_NAME, ffParseChassisJsonObject) || + tryModule(instance, type, module, FF_CPU_MODULE_NAME, ffParseCPUJsonObject) || + tryModule(instance, type, module, FF_CPUUSAGE_MODULE_NAME, ffParseCPUUsageJsonObject) || + tryModule(instance, type, module, FF_COMMAND_MODULE_NAME, ffParseCommandJsonObject) || + tryModule(instance, type, module, FF_COLORS_MODULE_NAME, ffParseColorsJsonObject) || + tryModule(instance, type, module, FF_CURSOR_MODULE_NAME, ffParseCursorJsonObject) || + tryModule(instance, type, module, FF_CUSTOM_MODULE_NAME, ffParseCustomJsonObject) || + false; + } + + case 'D': { + return + tryModule(instance, type, module, FF_DATETIME_MODULE_NAME, ffParseDateTimeJsonObject) || + tryModule(instance, type, module, FF_DISPLAY_MODULE_NAME, ffParseDisplayJsonObject) || + tryModule(instance, type, module, FF_DISK_MODULE_NAME, ffParseDiskJsonObject) || + tryModule(instance, type, module, FF_DE_MODULE_NAME, ffParseDEJsonObject) || + false; + } + + case 'F': { + return + tryModule(instance, type, module, FF_FONT_MODULE_NAME, ffParseFontJsonObject) || + false; + } + + case 'G': { + return + tryModule(instance, type, module, FF_GAMEPAD_MODULE_NAME, ffParseGamepadJsonObject) || + tryModule(instance, type, module, FF_GPU_MODULE_NAME, ffParseGPUJsonObject) || + false; + } + + case 'H': { + return + tryModule(instance, type, module, FF_HOST_MODULE_NAME, ffParseHostJsonObject) || + false; + } + + case 'I': { + return + tryModule(instance, type, module, FF_ICONS_MODULE_NAME, ffParseIconsJsonObject) || + false; + } + + case 'K': { + return + tryModule(instance, type, module, FF_KERNEL_MODULE_NAME, ffParseKernelJsonObject) || + false; + } + + case 'L': { + return + tryModule(instance, type, module, FF_LOCALE_MODULE_NAME, ffParseLocaleJsonObject) || + tryModule(instance, type, module, FF_LOCALIP_MODULE_NAME, ffParseLocalIpJsonObject) || + false; + } + + case 'M': { + return + tryModule(instance, type, module, FF_MEDIA_MODULE_NAME, ffParseMediaJsonObject) || + tryModule(instance, type, module, FF_MEMORY_MODULE_NAME, ffParseMemoryJsonObject) || + false; + } + + case 'O': { + return + tryModule(instance, type, module, FF_OPENCL_MODULE_NAME, ffParseOpenCLJsonObject) || + tryModule(instance, type, module, FF_OPENGL_MODULE_NAME, ffParseOpenGLJsonObject) || + tryModule(instance, type, module, FF_OS_MODULE_NAME, ffParseOSJsonObject) || + false; + } + + case 'P': { + return + tryModule(instance, type, module, FF_PACKAGES_MODULE_NAME, ffParsePackagesJsonObject) || + tryModule(instance, type, module, FF_PLAYER_MODULE_NAME, ffParsePlayerJsonObject) || + tryModule(instance, type, module, FF_POWERADAPTER_MODULE_NAME, ffParsePowerAdapterJsonObject) || + tryModule(instance, type, module, FF_PROCESSES_MODULE_NAME, ffParseProcessesJsonObject) || + tryModule(instance, type, module, FF_PUBLICIP_MODULE_NAME, ffParsePublicIpJsonObject) || + false; + } + + case 'S': { + return + tryModule(instance, type, module, FF_SEPARATOR_MODULE_NAME, ffParseSeparatorJsonObject) || + tryModule(instance, type, module, FF_SHELL_MODULE_NAME, ffParseShellJsonObject) || + tryModule(instance, type, module, FF_SOUND_MODULE_NAME, ffParseSoundJsonObject) || + tryModule(instance, type, module, FF_SWAP_MODULE_NAME, ffParseSwapJsonObject) || + false; + } + + case 'T': { + return + tryModule(instance, type, module, FF_TERMINAL_MODULE_NAME, ffParseTerminalJsonObject) || + tryModule(instance, type, module, FF_TERMINALFONT_MODULE_NAME, ffParseTerminalFontJsonObject) || + tryModule(instance, type, module, FF_TITLE_MODULE_NAME, ffParseTitleJsonObject) || + tryModule(instance, type, module, FF_THEME_MODULE_NAME, ffParseThemeJsonObject) || + false; + } + + case 'U': { + return + tryModule(instance, type, module, FF_UPTIME_MODULE_NAME, ffParseUptimeJsonObject) || + tryModule(instance, type, module, FF_USERS_MODULE_NAME, ffParseUsersJsonObject) || + false; + } + + case 'V': { + return + tryModule(instance, type, module, FF_VULKAN_MODULE_NAME, ffParseVulkanJsonObject) || + false; + } + + case 'W': { + return + tryModule(instance, type, module, FF_WALLPAPER_MODULE_NAME, ffParseWallpaperJsonObject) || + tryModule(instance, type, module, FF_WEATHER_MODULE_NAME, ffParseWeatherJsonObject) || + tryModule(instance, type, module, FF_WM_MODULE_NAME, ffParseWMJsonObject) || + tryModule(instance, type, module, FF_WIFI_MODULE_NAME, ffParseWifiJsonObject) || + tryModule(instance, type, module, FF_WMTHEME_MODULE_NAME, ffParseWMThemeJsonObject) || + false; + } + + default: + return false; + } +} + +static const char* parseModules(FFinstance* instance, json_object* modules) +{ + array_list* list = json_object_get_array(modules); + if (!list) return "modules must be an array of strings or objects"; + + for (size_t idx = 0; idx < list->length; ++idx) + { + json_object* module = (json_object*) list->array[idx]; + const char* type = NULL; + if (json_object_is_type(module, json_type_string)) + { + type = json_object_get_string(module); + module = NULL; + } + else if (json_object_is_type(module, json_type_object)) + { + json_object* object = json_object_object_get(module, "type"); + type = json_object_get_string(object); + if (!type) return "module object must contain a \"type\" key ( case sensitive )"; + if (json_object_object_length(module) == 1) // contains only Property type + module = NULL; + } + else + return "modules must be an array of strings or objects"; + + if(!parseModuleJsonObject(instance, type, module)) + return "Unknown module type"; + } + + return NULL; +} + +static const char* printJsonConfig(FFinstance* instance) +{ + if (!ffJsonLoadLibrary(instance)) + return "Failed to load json-c library"; + + FF_STRBUF_AUTO_DESTROY content = ffStrbufCreate(); + FF_LIST_FOR_EACH(FFstrbuf, filename, instance->state.platform.configDirs) + { + uint32_t oldLength = filename->length; + ffStrbufAppendS(filename, "fastfetch/config.jsonc"); + bool success = ffAppendFileBuffer(filename->chars, &content); + ffStrbufSubstrBefore(filename, oldLength); + if (success) break; + } + + json_object* __attribute__((__cleanup__(wrapJsoncFree))) root = json_tokener_parse(content.chars); + if (!root) + return "Failed to parse JSON config file"; + + lh_table* rootObject = json_object_get_object(root); + if (!rootObject) + return "Invalid JSON config format. Root value must be an object"; + + struct lh_entry* entry; + lh_foreach(rootObject, entry) + { + const char* key = (const char *)lh_entry_k(entry); + json_object* val = (json_object *)lh_entry_v(entry); + + if (strcmp(key, "modules") == 0) + { + const char* error = parseModules(instance, val); + if (error) return error; + } + else + return "Unknown JSON config key in root object"; + } + + return NULL; +} + +#else + +static const char* printJsonConfig(FF_MAYBE_UNUSED FFinstance* instance) +{ + return "Fastfetch was compiled without json-c support"; +} + +#endif + +void ffPrintJsonConfig(FFinstance* instance) +{ + const char* error = printJsonConfig(instance); + if (error) + ffPrintErrorString(instance, "JsonConfig", 0, NULL, NULL, "%s", error); +} diff --git a/src/modules/jsonconfig/jsonconfig.h b/src/modules/jsonconfig/jsonconfig.h new file mode 100644 index 000000000..fe0b7e43a --- /dev/null +++ b/src/modules/jsonconfig/jsonconfig.h @@ -0,0 +1,7 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_JSONCONFIG_MODULE_NAME "JsonConfig" + +void ffPrintJsonConfig(FFinstance* instance); diff --git a/src/modules/kernel.c b/src/modules/kernel.c deleted file mode 100644 index bc1139833..000000000 --- a/src/modules/kernel.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" - -#define FF_KERNEL_MODULE_NAME "Kernel" -#define FF_KERNEL_NUM_FORMAT_ARGS 4 - -void ffPrintKernel(FFinstance* instance) -{ - if(instance->config.kernel.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_KERNEL_MODULE_NAME, 0, &instance->config.kernel.key); - ffStrbufWriteTo(&instance->state.platform.systemRelease, stdout); - - #ifdef _WIN32 - if(instance->state.platform.systemVersion.length > 0) - printf(" (%s)", instance->state.platform.systemVersion.chars); - #endif - - putchar('\n'); - } - else - { - ffPrintFormat(instance, FF_KERNEL_MODULE_NAME, 0, &instance->config.kernel, FF_KERNEL_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &instance->state.platform.systemName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &instance->state.platform.systemRelease}, - {FF_FORMAT_ARG_TYPE_STRBUF, &instance->state.platform.systemVersion}, - {FF_FORMAT_ARG_TYPE_STRBUF, &instance->state.platform.systemArchitecture} - }); - } -} diff --git a/src/modules/kernel/kernel.c b/src/modules/kernel/kernel.c new file mode 100644 index 000000000..36b5e8545 --- /dev/null +++ b/src/modules/kernel/kernel.c @@ -0,0 +1,72 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "modules/kernel/kernel.h" + +#define FF_KERNEL_NUM_FORMAT_ARGS 4 + +void ffPrintKernel(FFinstance* instance, FFKernelOptions* options) +{ + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_KERNEL_MODULE_NAME, 0, &options->moduleArgs.key); + ffStrbufWriteTo(&instance->state.platform.systemRelease, stdout); + + #ifdef _WIN32 + if(instance->state.platform.systemVersion.length > 0) + printf(" (%s)", instance->state.platform.systemVersion.chars); + #endif + + putchar('\n'); + } + else + { + ffPrintFormat(instance, FF_KERNEL_MODULE_NAME, 0, &options->moduleArgs, FF_KERNEL_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &instance->state.platform.systemName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &instance->state.platform.systemRelease}, + {FF_FORMAT_ARG_TYPE_STRBUF, &instance->state.platform.systemVersion}, + {FF_FORMAT_ARG_TYPE_STRBUF, &instance->state.platform.systemArchitecture} + }); + } +} + +void ffInitKernelOptions(FFKernelOptions* options) +{ + options->moduleName = FF_KERNEL_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseKernelCommandOptions(FFKernelOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_KERNEL_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyKernelOptions(FFKernelOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseKernelJsonObject(FFinstance* instance, json_object* module) +{ + FFKernelOptions __attribute__((__cleanup__(ffDestroyKernelOptions))) options; + ffInitKernelOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_KERNEL_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintKernel(instance, &options); +} +#endif diff --git a/src/modules/kernel/kernel.h b/src/modules/kernel/kernel.h new file mode 100644 index 000000000..ee0d78300 --- /dev/null +++ b/src/modules/kernel/kernel.h @@ -0,0 +1,16 @@ +#pragma once + +#include "fastfetch.h" +#include "modules/kernel/option.h" + +#define FF_KERNEL_MODULE_NAME "Kernel" + +void ffPrintKernel(FFinstance* instance, FFKernelOptions* options); +void ffInitKernelOptions(FFKernelOptions* options); +bool ffParseKernelCommandOptions(FFKernelOptions* options, const char* key, const char* value); +void ffDestroyKernelOptions(FFKernelOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseKernelJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/kernel/option.h b/src/modules/kernel/option.h new file mode 100644 index 000000000..434c3069d --- /dev/null +++ b/src/modules/kernel/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFKernelOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFKernelOptions; diff --git a/src/modules/locale.c b/src/modules/locale.c deleted file mode 100644 index 8c56b0638..000000000 --- a/src/modules/locale.c +++ /dev/null @@ -1,33 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/locale/locale.h" - -#define FF_LOCALE_MODULE_NAME "Locale" -#define FF_LOCALE_NUM_FORMAT_ARGS 1 - -void ffPrintLocale(FFinstance* instance) -{ - FFstrbuf locale; - ffStrbufInit(&locale); - - ffDetectLocale(&locale); - if(locale.length == 0) - { - ffPrintError(instance, FF_LOCALE_MODULE_NAME, 0, &instance->config.locale, "No locale found"); - return; - } - - if(instance->config.locale.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_LOCALE_MODULE_NAME, 0, &instance->config.locale.key); - ffStrbufPutTo(&locale, stdout); - } - else - { - ffPrintFormat(instance, FF_LOCALE_MODULE_NAME, 0, &instance->config.locale, FF_LOCALE_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &locale} - }); - } - - ffStrbufDestroy(&locale); -} diff --git a/src/modules/locale/locale.c b/src/modules/locale/locale.c new file mode 100644 index 000000000..9a2f99f6d --- /dev/null +++ b/src/modules/locale/locale.c @@ -0,0 +1,72 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/locale/locale.h" +#include "modules/locale/locale.h" + +#define FF_LOCALE_NUM_FORMAT_ARGS 1 + +void ffPrintLocale(FFinstance* instance, FFLocaleOptions* options) +{ + FF_STRBUF_AUTO_DESTROY locale = ffStrbufCreate(); + + ffDetectLocale(&locale); + if(locale.length == 0) + { + ffPrintError(instance, FF_LOCALE_MODULE_NAME, 0, &options->moduleArgs, "No locale found"); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_LOCALE_MODULE_NAME, 0, &options->moduleArgs.key); + ffStrbufPutTo(&locale, stdout); + } + else + { + ffPrintFormat(instance, FF_LOCALE_MODULE_NAME, 0, &options->moduleArgs, FF_LOCALE_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &locale} + }); + } +} + +void ffInitLocaleOptions(FFLocaleOptions* options) +{ + options->moduleName = FF_LOCALE_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseLocaleCommandOptions(FFLocaleOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_LOCALE_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyLocaleOptions(FFLocaleOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseLocaleJsonObject(FFinstance* instance, json_object* module) +{ + FFLocaleOptions __attribute__((__cleanup__(ffDestroyLocaleOptions))) options; + ffInitLocaleOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_LOCALE_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintLocale(instance, &options); +} +#endif diff --git a/src/modules/locale/locale.h b/src/modules/locale/locale.h new file mode 100644 index 000000000..e02f91154 --- /dev/null +++ b/src/modules/locale/locale.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_LOCALE_MODULE_NAME "Locale" + +void ffPrintLocale(FFinstance* instance, FFLocaleOptions* options); +void ffInitLocaleOptions(FFLocaleOptions* options); +bool ffParseLocaleCommandOptions(FFLocaleOptions* options, const char* key, const char* value); +void ffDestroyLocaleOptions(FFLocaleOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseLocaleJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/locale/option.h b/src/modules/locale/option.h new file mode 100644 index 000000000..3e3253037 --- /dev/null +++ b/src/modules/locale/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFLocaleOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFLocaleOptions; diff --git a/src/modules/localip.c b/src/modules/localip.c deleted file mode 100644 index 5d6de0bad..000000000 --- a/src/modules/localip.c +++ /dev/null @@ -1,119 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/localip/localip.h" - -#define FF_LOCALIP_MODULE_NAME "Local IP" -#define FF_LOCALIP_NUM_FORMAT_ARGS 2 - -static int sortIps(const FFLocalIpResult* left, const FFLocalIpResult* right) -{ - return ffStrbufComp(&left->name, &right->name); -} - -static void formatKey(const FFinstance* instance, const FFLocalIpResult* ip, FFstrbuf* key) -{ - if(instance->config.localIP.key.length == 0) - { - if(ip->name.length) - ffStrbufSetF(key, FF_LOCALIP_MODULE_NAME " (%*s)", ip->name.length, ip->name.chars); - else - ffStrbufSetS(key, FF_LOCALIP_MODULE_NAME); - } - else - { - ffStrbufClear(key); - ffParseFormatString(key, &instance->config.localIP.key, 1, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &ip->name} - }); - } -} - -static void printIp(FFLocalIpResult* ip) -{ - bool flag = false; - if (ip->ipv4.length) - { - ffStrbufWriteTo(&ip->ipv4, stdout); - flag = true; - } - if (ip->ipv6.length) - { - if (flag) putchar(' '); - ffStrbufWriteTo(&ip->ipv6, stdout); - flag = true; - } - if (ip->mac.length) - { - if (flag) - printf(" (%s)", ip->mac.chars); - else - ffStrbufWriteTo(&ip->mac, stdout); - } -} - -void ffPrintLocalIp(FFinstance* instance) -{ - FF_LIST_AUTO_DESTROY results; - ffListInit(&results, sizeof(FFLocalIpResult)); - - const char* error = ffDetectLocalIps(instance, &results); - - if(error) - { - ffPrintError(instance, FF_LOCALIP_MODULE_NAME, 0, &instance->config.localIP, "%s", error); - return; - } - - if(results.length == 0) - { - ffPrintError(instance, FF_LOCALIP_MODULE_NAME, 0, &instance->config.localIP, "Failed to detect any IPs"); - return; - } - - ffListSort(&results, (void*) sortIps); - - if (instance->config.localIpShowType & FF_LOCALIP_TYPE_COMPACT_BIT) - { - ffPrintLogoAndKey(instance, FF_LOCALIP_MODULE_NAME, 0, &instance->config.localIP.key); - - FF_LIST_FOR_EACH(FFLocalIpResult, ip, results) - { - if ((void*) ip != (void*) results.data) - fputs(" - ", stdout); - printIp(ip); - } - } - else - { - FF_STRBUF_AUTO_DESTROY key; - ffStrbufInit(&key); - - FF_LIST_FOR_EACH(FFLocalIpResult, ip, results) - { - formatKey(instance, ip, &key); - if(instance->config.localIP.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, key.chars, 0, NULL); - printIp(ip); - putchar('\n'); - } - else - { - ffPrintFormatString(instance, key.chars, 0, NULL, &instance->config.localIP.outputFormat, FF_LOCALIP_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &ip->ipv4}, - {FF_FORMAT_ARG_TYPE_STRBUF, &ip->ipv6}, - {FF_FORMAT_ARG_TYPE_STRBUF, &ip->mac}, - {FF_FORMAT_ARG_TYPE_STRBUF, &ip->name}, - }); - } - } - } - - FF_LIST_FOR_EACH(FFLocalIpResult, ip, results) - { - ffStrbufDestroy(&ip->name); - ffStrbufDestroy(&ip->ipv4); - ffStrbufDestroy(&ip->ipv6); - ffStrbufDestroy(&ip->mac); - } -} diff --git a/src/modules/localip/localip.c b/src/modules/localip/localip.c new file mode 100644 index 000000000..9b27da159 --- /dev/null +++ b/src/modules/localip/localip.c @@ -0,0 +1,267 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/localip/localip.h" +#include "modules/localip/localip.h" + +#define FF_LOCALIP_DISPLAY_NAME "Local IP" +#define FF_LOCALIP_NUM_FORMAT_ARGS 2 +#pragma GCC diagnostic ignored "-Wsign-conversion" + +static int sortIps(const FFLocalIpResult* left, const FFLocalIpResult* right) +{ + return ffStrbufComp(&left->name, &right->name); +} + +static void formatKey(const FFLocalIpOptions* options, const FFLocalIpResult* ip, FFstrbuf* key) +{ + if(options->moduleArgs.key.length == 0) + { + if(ip->name.length) + ffStrbufSetF(key, FF_LOCALIP_DISPLAY_NAME " (%s)", ip->name.chars); + else + ffStrbufSetS(key, FF_LOCALIP_DISPLAY_NAME); + } + else + { + ffStrbufClear(key); + ffParseFormatString(key, &options->moduleArgs.key, 2, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &ip->name}, + }); + } +} + +static void printIp(FFLocalIpResult* ip) +{ + bool flag = false; + if (ip->ipv4.length) + { + ffStrbufWriteTo(&ip->ipv4, stdout); + flag = true; + } + if (ip->ipv6.length) + { + if (flag) putchar(' '); + ffStrbufWriteTo(&ip->ipv6, stdout); + flag = true; + } + if (ip->mac.length) + { + if (flag) + printf(" (%s)", ip->mac.chars); + else + ffStrbufWriteTo(&ip->mac, stdout); + } +} + +void ffPrintLocalIp(FFinstance* instance, FFLocalIpOptions* options) +{ + FF_LIST_AUTO_DESTROY results = ffListCreate(sizeof(FFLocalIpResult)); + + const char* error = ffDetectLocalIps(options, &results); + + if(error) + { + ffPrintError(instance, FF_LOCALIP_DISPLAY_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + if(results.length == 0) + { + ffPrintError(instance, FF_LOCALIP_DISPLAY_NAME, 0, &options->moduleArgs, "Failed to detect any IPs"); + return; + } + + ffListSort(&results, (const void*) sortIps); + + if (options->showType & FF_LOCALIP_TYPE_COMPACT_BIT) + { + ffPrintLogoAndKey(instance, FF_LOCALIP_DISPLAY_NAME, 0, &options->moduleArgs.key); + + FF_LIST_FOR_EACH(FFLocalIpResult, ip, results) + { + if ((void*) ip != (void*) results.data) + fputs(" - ", stdout); + printIp(ip); + } + } + else + { + FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate(); + + FF_LIST_FOR_EACH(FFLocalIpResult, ip, results) + { + formatKey(options, ip, &key); + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, key.chars, 0, NULL); + printIp(ip); + putchar('\n'); + } + else + { + ffPrintFormatString(instance, key.chars, 0, NULL, &options->moduleArgs.outputFormat, FF_LOCALIP_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &ip->ipv4}, + {FF_FORMAT_ARG_TYPE_STRBUF, &ip->ipv6}, + {FF_FORMAT_ARG_TYPE_STRBUF, &ip->mac}, + {FF_FORMAT_ARG_TYPE_STRBUF, &ip->name}, + }); + } + } + } + + FF_LIST_FOR_EACH(FFLocalIpResult, ip, results) + { + ffStrbufDestroy(&ip->name); + ffStrbufDestroy(&ip->ipv4); + ffStrbufDestroy(&ip->ipv6); + ffStrbufDestroy(&ip->mac); + } +} + +void ffInitLocalIpOptions(FFLocalIpOptions* options) +{ + options->moduleName = FF_LOCALIP_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + + options->showType = FF_LOCALIP_TYPE_IPV4_BIT; + ffStrbufInit(&options->namePrefix); +} + +bool ffParseLocalIpCommandOptions(FFLocalIpOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_LOCALIP_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (strcasecmp(subKey, "show-ipv4") == 0) + { + if (ffOptionParseBoolean(value)) + options->showType |= FF_LOCALIP_TYPE_IPV4_BIT; + else + options->showType &= ~FF_LOCALIP_TYPE_IPV4_BIT; + return true; + } + + if (strcasecmp(subKey, "show-ipv6") == 0) + { + if (ffOptionParseBoolean(value)) + options->showType |= FF_LOCALIP_TYPE_IPV6_BIT; + else + options->showType &= ~FF_LOCALIP_TYPE_IPV6_BIT; + return true; + } + + if (strcasecmp(subKey, "show-mac") == 0) + { + if (ffOptionParseBoolean(value)) + options->showType |= FF_LOCALIP_TYPE_MAC_BIT; + else + options->showType &= ~FF_LOCALIP_TYPE_MAC_BIT; + return true; + } + + if (strcasecmp(subKey, "show-loop") == 0) + { + if (ffOptionParseBoolean(value)) + options->showType |= FF_LOCALIP_TYPE_LOOP_BIT; + else + options->showType &= ~FF_LOCALIP_TYPE_LOOP_BIT; + return true; + } + + if(strcasecmp(subKey, "compact") == 0) + { + if (ffOptionParseBoolean(value)) + options->showType |= FF_LOCALIP_TYPE_COMPACT_BIT; + else + options->showType &= ~FF_LOCALIP_TYPE_COMPACT_BIT; + return true; + } + + if (strcasecmp(subKey, "name-prefix") == 0) + { + ffOptionParseString(key, value, &options->namePrefix); + return true; + } + + return false; +} + +void ffDestroyLocalIpOptions(FFLocalIpOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); + ffStrbufDestroy(&options->namePrefix); +} + +#ifdef FF_HAVE_JSONC +void ffParseLocalIpJsonObject(FFinstance* instance, json_object* module) +{ + FFLocalIpOptions __attribute__((__cleanup__(ffDestroyLocalIpOptions))) options; + ffInitLocalIpOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + if (strcasecmp(key, "showIpv4") == 0) + { + if (json_object_get_boolean(val)) + options.showType |= FF_LOCALIP_TYPE_IPV4_BIT; + else + options.showType &= ~FF_LOCALIP_TYPE_IPV4_BIT; + continue; + } + + if (strcasecmp(key, "showIpv6") == 0) + { + if (json_object_get_boolean(val)) + options.showType |= FF_LOCALIP_TYPE_IPV6_BIT; + else + options.showType &= ~FF_LOCALIP_TYPE_IPV6_BIT; + continue; + } + + if (strcasecmp(key, "showMac") == 0) + { + if (json_object_get_boolean(val)) + options.showType |= FF_LOCALIP_TYPE_MAC_BIT; + else + options.showType &= ~FF_LOCALIP_TYPE_MAC_BIT; + continue; + } + + if (strcasecmp(key, "showLoop") == 0) + { + if (json_object_get_boolean(val)) + options.showType |= FF_LOCALIP_TYPE_LOOP_BIT; + else + options.showType &= ~FF_LOCALIP_TYPE_LOOP_BIT; + continue; + } + + if (strcasecmp(key, "compact") == 0) + { + if (json_object_get_boolean(val)) + options.showType |= FF_LOCALIP_TYPE_COMPACT_BIT; + else + options.showType &= ~FF_LOCALIP_TYPE_COMPACT_BIT; + continue; + } + + if (strcasecmp(key, "namePrefix") == 0) + { + ffStrbufSetS(&options.namePrefix, json_object_get_string(val)); + continue; + } + + ffPrintError(instance, FF_LOCALIP_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintLocalIp(instance, &options); +} +#endif diff --git a/src/modules/localip/localip.h b/src/modules/localip/localip.h new file mode 100644 index 000000000..e27babe41 --- /dev/null +++ b/src/modules/localip/localip.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_LOCALIP_MODULE_NAME "LocalIp" + +void ffPrintLocalIp(FFinstance* instance, FFLocalIpOptions* options); +void ffInitLocalIpOptions(FFLocalIpOptions* options); +bool ffParseLocalIpCommandOptions(FFLocalIpOptions* options, const char* key, const char* value); +void ffDestroyLocalIpOptions(FFLocalIpOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseLocalIpJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/localip/option.h b/src/modules/localip/option.h new file mode 100644 index 000000000..65dcfc60d --- /dev/null +++ b/src/modules/localip/option.h @@ -0,0 +1,25 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef enum FFLocalIpType +{ + FF_LOCALIP_TYPE_NONE, + FF_LOCALIP_TYPE_LOOP_BIT = 1 << 0, + FF_LOCALIP_TYPE_IPV4_BIT = 1 << 1, + FF_LOCALIP_TYPE_IPV6_BIT = 1 << 2, + FF_LOCALIP_TYPE_MAC_BIT = 1 << 3, + + FF_LOCALIP_TYPE_COMPACT_BIT = 1 << 10, +} FFLocalIpType; + +typedef struct FFLocalIpOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + FFLocalIpType showType; + FFstrbuf namePrefix; +} FFLocalIpOptions; diff --git a/src/modules/media.c b/src/modules/media/media.c similarity index 58% rename from src/modules/media.c rename to src/modules/media/media.c index eb0eaeeb2..9021aaf7c 100644 --- a/src/modules/media.c +++ b/src/modules/media/media.c @@ -1,13 +1,13 @@ #include "fastfetch.h" #include "common/printing.h" #include "detection/media/media.h" +#include "modules/media/media.h" #include -#define FF_MEDIA_MODULE_NAME "Media" #define FF_MEDIA_NUM_FORMAT_ARGS 5 -static bool shouldIgoreChar(char c) +static inline bool shouldIgnoreChar(char c) { return isblank(c) || c == '-' || c == '.'; } @@ -19,10 +19,10 @@ static bool artistInSongTitle(const FFstrbuf* song, const FFstrbuf* artist) while(true) { - while(shouldIgoreChar(song->chars[songIndex])) + while(shouldIgnoreChar(song->chars[songIndex])) ++songIndex; - while(shouldIgoreChar(artist->chars[artistIndex])) + while(shouldIgnoreChar(artist->chars[artistIndex])) ++artistIndex; if(artist->chars[artistIndex] == '\0') @@ -42,18 +42,17 @@ static bool artistInSongTitle(const FFstrbuf* song, const FFstrbuf* artist) return false; } -void ffPrintMedia(FFinstance* instance) +void ffPrintMedia(FFinstance* instance, FFMediaOptions* options) { const FFMediaResult* media = ffDetectMedia(instance); if(media->error.length > 0) { - ffPrintError(instance, FF_MEDIA_MODULE_NAME, 0, &instance->config.media, "%s", media->error.chars); + ffPrintError(instance, FF_MEDIA_MODULE_NAME, 0, &options->moduleArgs, "%s", media->error.chars); return; } - FFstrbuf songPretty; - ffStrbufInitCopy(&songPretty, &media->song); + FF_STRBUF_AUTO_DESTROY songPretty = ffStrbufCreateCopy(&media->song); const char* removeStrings[] = { "(Official Music Video)", "(Official Video)", "(Music Video)", "(Official HD Video)", "[Official Music Video]", "[Official Video]", "[Music Video]", "[Official HD Video]", @@ -69,11 +68,10 @@ void ffPrintMedia(FFinstance* instance) if(songPretty.length == 0) ffStrbufAppend(&songPretty, &media->song); - if(instance->config.media.outputFormat.length == 0) + if(options->moduleArgs.outputFormat.length == 0) { //We don't expose artistPretty to the format, as it might be empty (when the think that the artist is already in the song title) - FFstrbuf artistPretty; - ffStrbufInitCopy(&artistPretty, &media->artist); + FF_STRBUF_AUTO_DESTROY artistPretty = ffStrbufCreateCopy(&media->artist); ffStrbufRemoveIgnCaseEndS(&artistPretty, " - Topic"); ffStrbufRemoveIgnCaseEndS(&artistPretty, "VEVO"); ffStrbufTrimRight(&artistPretty, ' '); @@ -81,7 +79,7 @@ void ffPrintMedia(FFinstance* instance) if(artistInSongTitle(&songPretty, &artistPretty)) ffStrbufClear(&artistPretty); - ffPrintLogoAndKey(instance, FF_MEDIA_MODULE_NAME, 0, &instance->config.media.key); + ffPrintLogoAndKey(instance, FF_MEDIA_MODULE_NAME, 0, &options->moduleArgs.key); if(artistPretty.length > 0) { @@ -93,12 +91,10 @@ void ffPrintMedia(FFinstance* instance) ffStrbufAppendF(&songPretty, " (%s)", media->status.chars); ffStrbufPutTo(&songPretty, stdout); - - ffStrbufDestroy(&artistPretty); } else { - ffPrintFormat(instance, FF_MEDIA_MODULE_NAME, 0, &instance->config.media, FF_MEDIA_NUM_FORMAT_ARGS, (FFformatarg[]){ + ffPrintFormat(instance, FF_MEDIA_MODULE_NAME, 0, &options->moduleArgs, FF_MEDIA_NUM_FORMAT_ARGS, (FFformatarg[]){ {FF_FORMAT_ARG_TYPE_STRBUF, &songPretty}, {FF_FORMAT_ARG_TYPE_STRBUF, &media->song}, {FF_FORMAT_ARG_TYPE_STRBUF, &media->artist}, @@ -106,6 +102,46 @@ void ffPrintMedia(FFinstance* instance) {FF_FORMAT_ARG_TYPE_STRBUF, &media->status} }); } - - ffStrbufDestroy(&songPretty); } + +void ffInitMediaOptions(FFMediaOptions* options) +{ + options->moduleName = FF_MEDIA_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseMediaCommandOptions(FFMediaOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_MEDIA_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyMediaOptions(FFMediaOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseMediaJsonObject(FFinstance* instance, json_object* module) +{ + FFMediaOptions __attribute__((__cleanup__(ffDestroyMediaOptions))) options; + ffInitMediaOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_MEDIA_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintMedia(instance, &options); +} +#endif diff --git a/src/modules/media/media.h b/src/modules/media/media.h new file mode 100644 index 000000000..59c6cbb42 --- /dev/null +++ b/src/modules/media/media.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_MEDIA_MODULE_NAME "Media" + +void ffPrintMedia(FFinstance* instance, FFMediaOptions* options); +void ffInitMediaOptions(FFMediaOptions* options); +bool ffParseMediaCommandOptions(FFMediaOptions* options, const char* key, const char* value); +void ffDestroyMediaOptions(FFMediaOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseMediaJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/media/option.h b/src/modules/media/option.h new file mode 100644 index 000000000..8498c6e9b --- /dev/null +++ b/src/modules/media/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFMediaOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFMediaOptions; diff --git a/src/modules/memory.c b/src/modules/memory.c deleted file mode 100644 index 3c82b1a7b..000000000 --- a/src/modules/memory.c +++ /dev/null @@ -1,67 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "common/parsing.h" -#include "common/bar.h" -#include "detection/memory/memory.h" - -#define FF_MEMORY_MODULE_NAME "Memory" -#define FF_MEMORY_NUM_FORMAT_ARGS 3 - -void ffPrintMemory(FFinstance* instance) -{ - FFMemoryResult storage; - const char* error = ffDetectMemory(&storage); - - if(error) - { - ffPrintError(instance, FF_MEMORY_MODULE_NAME, 0, &instance->config.memory, "%s", error); - return; - } - - FF_STRBUF_AUTO_DESTROY usedPretty; - ffStrbufInit(&usedPretty); - ffParseSize(storage.bytesUsed, instance->config.binaryPrefixType, &usedPretty); - - FF_STRBUF_AUTO_DESTROY totalPretty; - ffStrbufInit(&totalPretty); - ffParseSize(storage.bytesTotal, instance->config.binaryPrefixType, &totalPretty); - - uint8_t percentage = storage.bytesTotal == 0 - ? 0 - : (uint8_t) (((long double) storage.bytesUsed / (long double) storage.bytesTotal) * 100.0); - - if(instance->config.memory.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_MEMORY_MODULE_NAME, 0, &instance->config.memory.key); - if (storage.bytesTotal == 0) - puts("Disabled"); - else - { - FF_STRBUF_AUTO_DESTROY str; - ffStrbufInit(&str); - - if(instance->config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) - { - ffAppendPercentBar(instance, &str, percentage, 0, 5, 8); - ffStrbufAppendC(&str, ' '); - } - - if(!(instance->config.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) - ffStrbufAppendF(&str, "%s / %s ", usedPretty.chars, totalPretty.chars); - - if(instance->config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) - ffAppendPercentNum(instance, &str, (uint8_t) percentage, 50, 80, str.length > 0); - - ffStrbufTrimRight(&str, ' '); - ffStrbufPutTo(&str, stdout); - } - } - else - { - ffPrintFormat(instance, FF_MEMORY_MODULE_NAME, 0, &instance->config.memory, FF_MEMORY_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty}, - {FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty}, - {FF_FORMAT_ARG_TYPE_UINT8, &percentage}, - }); - } -} diff --git a/src/modules/memory/memory.c b/src/modules/memory/memory.c new file mode 100644 index 000000000..552a0dc44 --- /dev/null +++ b/src/modules/memory/memory.c @@ -0,0 +1,106 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "common/parsing.h" +#include "common/bar.h" +#include "detection/memory/memory.h" +#include "modules/memory/memory.h" + +#define FF_MEMORY_NUM_FORMAT_ARGS 3 + +void ffPrintMemory(FFinstance* instance, FFMemoryOptions* options) +{ + FFMemoryResult storage; + const char* error = ffDetectMemory(&storage); + + if(error) + { + ffPrintError(instance, FF_MEMORY_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + FF_STRBUF_AUTO_DESTROY usedPretty = ffStrbufCreate(); + ffParseSize(storage.bytesUsed, instance->config.binaryPrefixType, &usedPretty); + + FF_STRBUF_AUTO_DESTROY totalPretty = ffStrbufCreate(); + ffParseSize(storage.bytesTotal, instance->config.binaryPrefixType, &totalPretty); + + uint8_t percentage = storage.bytesTotal == 0 + ? 0 + : (uint8_t) (((long double) storage.bytesUsed / (long double) storage.bytesTotal) * 100.0); + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_MEMORY_MODULE_NAME, 0, &options->moduleArgs.key); + if (storage.bytesTotal == 0) + puts("Disabled"); + else + { + FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate(); + + if(instance->config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + { + ffAppendPercentBar(instance, &str, percentage, 0, 5, 8); + ffStrbufAppendC(&str, ' '); + } + + if(!(instance->config.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) + ffStrbufAppendF(&str, "%s / %s ", usedPretty.chars, totalPretty.chars); + + if(instance->config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffAppendPercentNum(instance, &str, (uint8_t) percentage, 50, 80, str.length > 0); + + ffStrbufTrimRight(&str, ' '); + ffStrbufPutTo(&str, stdout); + } + } + else + { + ffPrintFormat(instance, FF_MEMORY_MODULE_NAME, 0, &options->moduleArgs, FF_MEMORY_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty}, + {FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty}, + {FF_FORMAT_ARG_TYPE_UINT8, &percentage}, + }); + } +} + +void ffInitMemoryOptions(FFMemoryOptions* options) +{ + options->moduleName = FF_MEMORY_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseMemoryCommandOptions(FFMemoryOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_MEMORY_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyMemoryOptions(FFMemoryOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseMemoryJsonObject(FFinstance* instance, json_object* module) +{ + FFMemoryOptions __attribute__((__cleanup__(ffDestroyMemoryOptions))) options; + ffInitMemoryOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_MEMORY_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintMemory(instance, &options); +} +#endif diff --git a/src/modules/memory/memory.h b/src/modules/memory/memory.h new file mode 100644 index 000000000..e500d8532 --- /dev/null +++ b/src/modules/memory/memory.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_MEMORY_MODULE_NAME "Memory" + +void ffPrintMemory(FFinstance* instance, FFMemoryOptions* options); +void ffInitMemoryOptions(FFMemoryOptions* options); +bool ffParseMemoryCommandOptions(FFMemoryOptions* options, const char* key, const char* value); +void ffDestroyMemoryOptions(FFMemoryOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseMemoryJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/memory/option.h b/src/modules/memory/option.h new file mode 100644 index 000000000..1f8b30bf1 --- /dev/null +++ b/src/modules/memory/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFMemoryOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFMemoryOptions; diff --git a/src/modules/modules.h b/src/modules/modules.h new file mode 100644 index 000000000..99a2130e3 --- /dev/null +++ b/src/modules/modules.h @@ -0,0 +1,56 @@ +#pragma once + +// For "fastfetch.c" and "flashfetch.c" + +#include "modules/battery/battery.h" +#include "modules/bios/bios.h" +#include "modules/bluetooth/bluetooth.h" +#include "modules/brightness/brightness.h" +#include "modules/board/board.h" +#include "modules/break/break.h" +#include "modules/chassis/chassis.h" +#include "modules/cpu/cpu.h" +#include "modules/cpuusage/cpuusage.h" +#include "modules/command/command.h" +#include "modules/colors/colors.h" +#include "modules/cursor/cursor.h" +#include "modules/custom/custom.h" +#include "modules/datetime/datetime.h" +#include "modules/disk/disk.h" +#include "modules/display/display.h" +#include "modules/de/de.h" +#include "modules/font/font.h" +#include "modules/gamepad/gamepad.h" +#include "modules/gpu/gpu.h" +#include "modules/host/host.h" +#include "modules/icons/icons.h" +#include "modules/kernel/kernel.h" +#include "modules/locale/locale.h" +#include "modules/localip/localip.h" +#include "modules/media/media.h" +#include "modules/memory/memory.h" +#include "modules/opengl/opengl.h" +#include "modules/opencl/opencl.h" +#include "modules/os/os.h" +#include "modules/packages/packages.h" +#include "modules/player/player.h" +#include "modules/poweradapter/poweradapter.h" +#include "modules/processes/processes.h" +#include "modules/publicip/publicip.h" +#include "modules/separator/separator.h" +#include "modules/shell/shell.h" +#include "modules/sound/sound.h" +#include "modules/swap/swap.h" +#include "modules/terminal/terminal.h" +#include "modules/terminalfont/terminalfont.h" +#include "modules/theme/theme.h" +#include "modules/title/title.h" +#include "modules/jsonconfig/jsonconfig.h" +#include "modules/uptime/uptime.h" +#include "modules/users/users.h" +#include "modules/vulkan/vulkan.h" +#include "modules/wallpaper/wallpaper.h" +#include "modules/weather/weather.h" +#include "modules/wifi/wifi.h" +#include "modules/wm/wm.h" +#include "modules/wmtheme/wmtheme.h" diff --git a/src/modules/opencl.c b/src/modules/opencl.c deleted file mode 100644 index c9d33b10d..000000000 --- a/src/modules/opencl.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/opencl/opencl.h" - -#define FF_OPENCL_MODULE_NAME "OpenCL" -#define FF_OPENCL_NUM_FORMAT_ARGS 3 - -void ffPrintOpenCL(FFinstance* instance) -{ - FFOpenCLResult opencl; - ffStrbufInit(&opencl.version); - ffStrbufInit(&opencl.device); - ffStrbufInit(&opencl.vendor); - - const char* error = ffDetectOpenCL(instance, &opencl); - - if(error != NULL) - ffPrintError(instance, FF_OPENCL_MODULE_NAME, 0, &instance->config.openCL, "%s", error); - else - { - if(instance->config.openCL.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_OPENCL_MODULE_NAME, 0, &instance->config.openCL.key); - ffStrbufPutTo(&opencl.version, stdout); - } - else - { - ffPrintFormat(instance, FF_OPENCL_MODULE_NAME, 0, &instance->config.openCL, FF_OPENCL_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &opencl.version}, - {FF_FORMAT_ARG_TYPE_STRBUF, &opencl.device}, - {FF_FORMAT_ARG_TYPE_STRBUF, &opencl.vendor}, - }); - } - } - - ffStrbufDestroy(&opencl.version); - ffStrbufDestroy(&opencl.device); - ffStrbufDestroy(&opencl.vendor); -} diff --git a/src/modules/opencl/opencl.c b/src/modules/opencl/opencl.c new file mode 100644 index 000000000..169aaec7f --- /dev/null +++ b/src/modules/opencl/opencl.c @@ -0,0 +1,81 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/opencl/opencl.h" +#include "modules/opencl/opencl.h" + +#define FF_OPENCL_NUM_FORMAT_ARGS 3 + +void ffPrintOpenCL(FFinstance* instance, FFOpenCLOptions* options) +{ + FFOpenCLResult opencl; + ffStrbufInit(&opencl.version); + ffStrbufInit(&opencl.device); + ffStrbufInit(&opencl.vendor); + + const char* error = ffDetectOpenCL(instance, &opencl); + + if(error != NULL) + ffPrintError(instance, FF_OPENCL_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + else + { + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_OPENCL_MODULE_NAME, 0, &options->moduleArgs.key); + ffStrbufPutTo(&opencl.version, stdout); + } + else + { + ffPrintFormat(instance, FF_OPENCL_MODULE_NAME, 0, &options->moduleArgs, FF_OPENCL_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &opencl.version}, + {FF_FORMAT_ARG_TYPE_STRBUF, &opencl.device}, + {FF_FORMAT_ARG_TYPE_STRBUF, &opencl.vendor}, + }); + } + } + + ffStrbufDestroy(&opencl.version); + ffStrbufDestroy(&opencl.device); + ffStrbufDestroy(&opencl.vendor); +} + +void ffInitOpenCLOptions(FFOpenCLOptions* options) +{ + options->moduleName = FF_OPENCL_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseOpenCLCommandOptions(FFOpenCLOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_OPENCL_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyOpenCLOptions(FFOpenCLOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseOpenCLJsonObject(FFinstance* instance, json_object* module) +{ + FFOpenCLOptions __attribute__((__cleanup__(ffDestroyOpenCLOptions))) options; + ffInitOpenCLOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_OPENCL_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintOpenCL(instance, &options); +} +#endif diff --git a/src/modules/opencl/opencl.h b/src/modules/opencl/opencl.h new file mode 100644 index 000000000..21843c41d --- /dev/null +++ b/src/modules/opencl/opencl.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_OPENCL_MODULE_NAME "OpenCL" + +void ffPrintOpenCL(FFinstance* instance, FFOpenCLOptions* options); +void ffInitOpenCLOptions(FFOpenCLOptions* options); +bool ffParseOpenCLCommandOptions(FFOpenCLOptions* options, const char* key, const char* value); +void ffDestroyOpenCLOptions(FFOpenCLOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseOpenCLJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/opencl/option.h b/src/modules/opencl/option.h new file mode 100644 index 000000000..addac5245 --- /dev/null +++ b/src/modules/opencl/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFOpenCLOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFOpenCLOptions; diff --git a/src/modules/opengl.c b/src/modules/opengl.c deleted file mode 100644 index 61e78451b..000000000 --- a/src/modules/opengl.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/opengl/opengl.h" - -#define FF_OPENGL_MODULE_NAME "OpenGL" -#define FF_OPENGL_NUM_FORMAT_ARGS 4 - -void ffPrintOpenGL(FFinstance* instance) -{ - FFOpenGLResult result; - ffStrbufInit(&result.version); - ffStrbufInit(&result.renderer); - ffStrbufInit(&result.vendor); - ffStrbufInit(&result.slv); - - const char* error = ffDetectOpenGL(instance, &result); - if(error) - { - ffPrintError(instance, FF_OPENGL_MODULE_NAME, 0, &instance->config.openGL, "%s", error); - return; - } - - if(instance->config.openGL.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_OPENGL_MODULE_NAME, 0, &instance->config.openGL.key); - puts(result.version.chars); - } - else - { - ffPrintFormat(instance, FF_OPENGL_MODULE_NAME, 0, &instance->config.openGL, FF_OPENGL_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &result.version}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.renderer}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.vendor}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result.slv} - }); - } - - ffStrbufDestroy(&result.version); - ffStrbufDestroy(&result.renderer); - ffStrbufDestroy(&result.vendor); - ffStrbufDestroy(&result.slv); -} diff --git a/src/modules/opengl/opengl.c b/src/modules/opengl/opengl.c new file mode 100644 index 000000000..ae551fb35 --- /dev/null +++ b/src/modules/opengl/opengl.c @@ -0,0 +1,117 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/opengl/opengl.h" +#include "modules/opengl/opengl.h" + +#define FF_OPENGL_NUM_FORMAT_ARGS 4 + +void ffPrintOpenGL(FFinstance* instance, FFOpenGLOptions* options) +{ + FFOpenGLResult result; + ffStrbufInit(&result.version); + ffStrbufInit(&result.renderer); + ffStrbufInit(&result.vendor); + ffStrbufInit(&result.slv); + + const char* error = ffDetectOpenGL(instance, &result); + if(error) + { + ffPrintError(instance, FF_OPENGL_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_OPENGL_MODULE_NAME, 0, &options->moduleArgs.key); + puts(result.version.chars); + } + else + { + ffPrintFormat(instance, FF_OPENGL_MODULE_NAME, 0, &options->moduleArgs, FF_OPENGL_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &result.version}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.renderer}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.vendor}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.slv} + }); + } + + ffStrbufDestroy(&result.version); + ffStrbufDestroy(&result.renderer); + ffStrbufDestroy(&result.vendor); + ffStrbufDestroy(&result.slv); +} + +void ffInitOpenGLOptions(FFOpenGLOptions* options) +{ + options->moduleName = FF_OPENGL_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + + #if defined(__linux__) || defined(__FreeBSD__) + options->type = FF_OPENGL_TYPE_AUTO; + #endif +} + +bool ffParseOpenGLCommandOptions(FFOpenGLOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_OPENGL_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + #if defined(__linux__) || defined(__FreeBSD__) + options->type = (FFOpenGLType) ffOptionParseEnum(key, value, (FFKeyValuePair[]) { + { "auto", FF_OPENGL_TYPE_AUTO }, + { "egl", FF_OPENGL_TYPE_EGL }, + { "glx", FF_OPENGL_TYPE_GLX }, + { "osmesa", FF_OPENGL_TYPE_OSMESA }, + {} + }); + #endif + + return false; +} + +void ffDestroyOpenGLOptions(FFOpenGLOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseOpenGLJsonObject(FFinstance* instance, json_object* module) +{ + FFOpenGLOptions __attribute__((__cleanup__(ffDestroyOpenGLOptions))) options; + ffInitOpenGLOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + #if defined(__linux__) || defined(__FreeBSD__) + if (strcasecmp(key, "type") == 0) + { + int value; + const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) { + { "auto", FF_OPENGL_TYPE_AUTO }, + { "egl", FF_OPENGL_TYPE_EGL }, + { "glx", FF_OPENGL_TYPE_GLX }, + { "osmesa", FF_OPENGL_TYPE_OSMESA }, + {}, + }); + if (error) + ffPrintError(instance, FF_OPENGL_MODULE_NAME, 0, &options.moduleArgs, "Invalid %s value: %s", key, error); + else + options.type = (FFOpenGLType) value; + continue; + } + #endif + + ffPrintError(instance, FF_OPENGL_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintOpenGL(instance, &options); +} +#endif diff --git a/src/modules/opengl/opengl.h b/src/modules/opengl/opengl.h new file mode 100644 index 000000000..d2322addf --- /dev/null +++ b/src/modules/opengl/opengl.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_OPENGL_MODULE_NAME "OpenGL" + +void ffPrintOpenGL(FFinstance* instance, FFOpenGLOptions* options); +void ffInitOpenGLOptions(FFOpenGLOptions* options); +bool ffParseOpenGLCommandOptions(FFOpenGLOptions* options, const char* key, const char* value); +void ffDestroyOpenGLOptions(FFOpenGLOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseOpenGLJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/opengl/option.h b/src/modules/opengl/option.h new file mode 100644 index 000000000..72e29c980 --- /dev/null +++ b/src/modules/opengl/option.h @@ -0,0 +1,25 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +#if defined(__linux__) || defined(__FreeBSD__) +typedef enum FFOpenGLType +{ + FF_OPENGL_TYPE_AUTO, + FF_OPENGL_TYPE_EGL, + FF_OPENGL_TYPE_GLX, + FF_OPENGL_TYPE_OSMESA +} FFOpenGLType; +#endif + +typedef struct FFOpenGLOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + #if defined(__linux__) || defined(__FreeBSD__) + FFOpenGLType type; + #endif +} FFOpenGLOptions; diff --git a/src/modules/options.h b/src/modules/options.h new file mode 100644 index 000000000..f9ae625b9 --- /dev/null +++ b/src/modules/options.h @@ -0,0 +1,53 @@ +#pragma once + +// For "fastfetch.h" + +#include "modules/battery/option.h" +#include "modules/bios/option.h" +#include "modules/bluetooth/option.h" +#include "modules/board/option.h" +#include "modules/brightness/option.h" +#include "modules/chassis/option.h" +#include "modules/cpu/option.h" +#include "modules/cpuusage/option.h" +#include "modules/cursor/option.h" +#include "modules/custom/option.h" +#include "modules/command/option.h" +#include "modules/datetime/option.h" +#include "modules/de/option.h" +#include "modules/disk/option.h" +#include "modules/display/option.h" +#include "modules/font/option.h" +#include "modules/host/option.h" +#include "modules/gamepad/option.h" +#include "modules/gpu/option.h" +#include "modules/icons/option.h" +#include "modules/kernel/option.h" +#include "modules/locale/option.h" +#include "modules/localip/option.h" +#include "modules/media/option.h" +#include "modules/memory/option.h" +#include "modules/opengl/option.h" +#include "modules/opencl/option.h" +#include "modules/os/option.h" +#include "modules/packages/option.h" +#include "modules/player/option.h" +#include "modules/poweradapter/option.h" +#include "modules/processes/option.h" +#include "modules/publicip/option.h" +#include "modules/separator/option.h" +#include "modules/shell/option.h" +#include "modules/sound/option.h" +#include "modules/swap/option.h" +#include "modules/terminal/option.h" +#include "modules/terminalfont/option.h" +#include "modules/theme/option.h" +#include "modules/title/option.h" +#include "modules/uptime/option.h" +#include "modules/users/option.h" +#include "modules/vulkan/option.h" +#include "modules/wallpaper/option.h" +#include "modules/weather/option.h" +#include "modules/wifi/option.h" +#include "modules/wm/option.h" +#include "modules/wmtheme/option.h" diff --git a/src/modules/os/option.h b/src/modules/os/option.h new file mode 100644 index 000000000..7d6b4d082 --- /dev/null +++ b/src/modules/os/option.h @@ -0,0 +1,15 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFOSOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + #if defined(__linux__) || defined(__FreeBSD__) + FFstrbuf file; + #endif +} FFOSOptions; diff --git a/src/modules/os.c b/src/modules/os/os.c similarity index 63% rename from src/modules/os.c rename to src/modules/os/os.c index 140cfdbbe..55a0552e8 100644 --- a/src/modules/os.c +++ b/src/modules/os/os.c @@ -1,10 +1,11 @@ #include "fastfetch.h" #include "common/printing.h" +#include "common/option.h" #include "detection/os/os.h" +#include "modules/os/os.h" #include -#define FF_OS_MODULE_NAME "OS" #define FF_OS_NUM_FORMAT_ARGS 12 static void buildOutputDefault(const FFinstance* instance, const FFOSResult* os, FFstrbuf* result) @@ -94,33 +95,31 @@ static void buildOutputNixOS(const FFinstance* instance, const FFOSResult* os, F } } -void ffPrintOS(FFinstance* instance) +void ffPrintOS(FFinstance* instance, FFOSOptions* options) { const FFOSResult* os = ffDetectOS(instance); if(os->name.length == 0 && os->prettyName.length == 0 && os->id.length == 0) { - ffPrintError(instance, FF_OS_MODULE_NAME, 0, &instance->config.os, "Could not detect OS"); + ffPrintError(instance, FF_OS_MODULE_NAME, 0, &options->moduleArgs, "Could not detect OS"); return; } - if(instance->config.os.outputFormat.length == 0) + if(options->moduleArgs.outputFormat.length == 0) { - FFstrbuf result; - ffStrbufInit(&result); + FF_STRBUF_AUTO_DESTROY result = ffStrbufCreate(); if(ffStrbufIgnCaseCompS(&os->id, "nixos") == 0) buildOutputNixOS(instance, os, &result); else buildOutputDefault(instance, os, &result); - ffPrintLogoAndKey(instance, FF_OS_MODULE_NAME, 0, &instance->config.os.key); + ffPrintLogoAndKey(instance, FF_OS_MODULE_NAME, 0, &options->moduleArgs.key); ffStrbufPutTo(&result, stdout); - ffStrbufDestroy(&result); } else { - ffPrintFormat(instance, FF_OS_MODULE_NAME, 0, &instance->config.os, FF_OS_NUM_FORMAT_ARGS, (FFformatarg[]){ + ffPrintFormat(instance, FF_OS_MODULE_NAME, 0, &options->moduleArgs, FF_OS_NUM_FORMAT_ARGS, (FFformatarg[]){ {FF_FORMAT_ARG_TYPE_STRBUF, &instance->state.platform.systemName}, {FF_FORMAT_ARG_TYPE_STRBUF, &os->name}, {FF_FORMAT_ARG_TYPE_STRBUF, &os->prettyName}, @@ -136,3 +135,68 @@ void ffPrintOS(FFinstance* instance) }); } } + +void ffInitOSOptions(FFOSOptions* options) +{ + options->moduleName = FF_OS_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + + #if defined(__linux__) || defined(__FreeBSD__) + ffStrbufInit(&options->file); + #endif +} + +bool ffParseOSCommandOptions(FFOSOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_OS_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + #if defined(__linux__) || defined(__FreeBSD__) + if (strcasecmp(subKey, "file") == 0) + { + ffOptionParseString(key, value, &options->file); + return true; + } + #endif + + return false; +} + +void ffDestroyOSOptions(FFOSOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); + #if defined(__linux__) || defined(__FreeBSD__) + ffStrbufDestroy(&options->file); + #endif +} + +#ifdef FF_HAVE_JSONC +void ffParseOSJsonObject(FFinstance* instance, json_object* module) +{ + FFOSOptions __attribute__((__cleanup__(ffDestroyOSOptions))) options; + ffInitOSOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + #if defined(__linux__) || defined(__FreeBSD__) + if (strcasecmp(key, "file") == 0) + { + ffStrbufSetS(&options.file, json_object_get_string(val)); + continue; + } + #endif + + ffPrintError(instance, FF_OS_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintOS(instance, &options); +} +#endif diff --git a/src/modules/os/os.h b/src/modules/os/os.h new file mode 100644 index 000000000..90e9c5981 --- /dev/null +++ b/src/modules/os/os.h @@ -0,0 +1,16 @@ +#pragma once + +#include "fastfetch.h" +#include "modules/os/option.h" + +#define FF_OS_MODULE_NAME "OS" + +void ffPrintOS(FFinstance* instance, FFOSOptions* options); +void ffInitOSOptions(FFOSOptions* options); +bool ffParseOSCommandOptions(FFOSOptions* options, const char* key, const char* value); +void ffDestroyOSOptions(FFOSOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseOSJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/packages/option.h b/src/modules/packages/option.h new file mode 100644 index 000000000..e06b8403b --- /dev/null +++ b/src/modules/packages/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFPackagesOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFPackagesOptions; diff --git a/src/modules/packages.c b/src/modules/packages/packages.c similarity index 65% rename from src/modules/packages.c rename to src/modules/packages/packages.c index a869fa678..dfcaf8249 100644 --- a/src/modules/packages.c +++ b/src/modules/packages/packages.c @@ -1,24 +1,24 @@ #include "fastfetch.h" #include "common/printing.h" #include "detection/packages/packages.h" +#include "modules/packages/packages.h" -#define FF_PACKAGES_MODULE_NAME "Packages" #define FF_PACKAGES_NUM_FORMAT_ARGS 21 -void ffPrintPackages(FFinstance* instance) +void ffPrintPackages(FFinstance* instance, FFPackagesOptions* options) { const FFPackagesResult* counts = ffDetectPackages(instance); uint32_t all = counts->all; //Copy it, so we can substract from it in FF_PRINT_PACKAGE if(all == 0) { - ffPrintError(instance, FF_PACKAGES_MODULE_NAME, 0, &instance->config.packages, "No packages from known package managers found"); + ffPrintError(instance, FF_PACKAGES_MODULE_NAME, 0, &options->moduleArgs, "No packages from known package managers found"); return; } - if(instance->config.packages.outputFormat.length == 0) + if(options->moduleArgs.outputFormat.length == 0) { - ffPrintLogoAndKey(instance, FF_PACKAGES_MODULE_NAME, 0, &instance->config.packages.key); + ffPrintLogoAndKey(instance, FF_PACKAGES_MODULE_NAME, 0, &options->moduleArgs.key); #define FF_PRINT_PACKAGE_NAME(var, name) \ if(counts->var > 0) \ @@ -65,7 +65,7 @@ void ffPrintPackages(FFinstance* instance) } else { - ffPrintFormat(instance, FF_PACKAGES_MODULE_NAME, 0, &instance->config.packages, FF_PACKAGES_NUM_FORMAT_ARGS, (FFformatarg[]){ + ffPrintFormat(instance, FF_PACKAGES_MODULE_NAME, 0, &options->moduleArgs, FF_PACKAGES_NUM_FORMAT_ARGS, (FFformatarg[]){ {FF_FORMAT_ARG_TYPE_UINT, &all}, {FF_FORMAT_ARG_TYPE_UINT, &counts->pacman}, {FF_FORMAT_ARG_TYPE_STRBUF, &counts->pacmanBranch}, @@ -90,3 +90,45 @@ void ffPrintPackages(FFinstance* instance) }); } } + +void ffInitPackagesOptions(FFPackagesOptions* options) +{ + options->moduleName = FF_PACKAGES_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParsePackagesCommandOptions(FFPackagesOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_PACKAGES_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyPackagesOptions(FFPackagesOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParsePackagesJsonObject(FFinstance* instance, json_object* module) +{ + FFPackagesOptions __attribute__((__cleanup__(ffDestroyPackagesOptions))) options; + ffInitPackagesOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_PACKAGES_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintPackages(instance, &options); +} +#endif diff --git a/src/modules/packages/packages.h b/src/modules/packages/packages.h new file mode 100644 index 000000000..5557da0b3 --- /dev/null +++ b/src/modules/packages/packages.h @@ -0,0 +1,16 @@ +#pragma once + +#include "fastfetch.h" +#include "modules/packages/option.h" + +#define FF_PACKAGES_MODULE_NAME "Packages" + +void ffPrintPackages(FFinstance* instance, FFPackagesOptions* options); +void ffInitPackagesOptions(FFPackagesOptions* options); +bool ffParsePackagesCommandOptions(FFPackagesOptions* options, const char* key, const char* value); +void ffDestroyPackagesOptions(FFPackagesOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParsePackagesJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/player/option.h b/src/modules/player/option.h new file mode 100644 index 000000000..8fa057a47 --- /dev/null +++ b/src/modules/player/option.h @@ -0,0 +1,13 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFPlayerOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + FFstrbuf name; +} FFPlayerOptions; diff --git a/src/modules/player.c b/src/modules/player/player.c similarity index 54% rename from src/modules/player.c rename to src/modules/player/player.c index 32eecde0f..f461044a1 100644 --- a/src/modules/player.c +++ b/src/modules/player/player.c @@ -1,24 +1,24 @@ #include "fastfetch.h" #include "common/printing.h" #include "detection/media/media.h" +#include "modules/player/player.h" #include -#define FF_PLAYER_MODULE_NAME "Media Player" +#define FF_PLAYER_DISPLAY_NAME "Media Player" #define FF_PLAYER_NUM_FORMAT_ARGS 4 -void ffPrintPlayer(FFinstance* instance) +void ffPrintPlayer(FFinstance* instance, FFPlayerOptions* options) { const FFMediaResult* media = ffDetectMedia(instance); if(media->error.length > 0) { - ffPrintError(instance, FF_PLAYER_MODULE_NAME, 0, &instance->config.player, "%s", media->error.chars); + ffPrintError(instance, FF_PLAYER_DISPLAY_NAME, 0, &options->moduleArgs, "%s", media->error.chars); return; } - FFstrbuf playerPretty; - ffStrbufInit(&playerPretty); + FF_STRBUF_AUTO_DESTROY playerPretty = ffStrbufCreate(); //If we are on a website, prepend the website name if( @@ -56,20 +56,64 @@ void ffPrintPlayer(FFinstance* instance) if(playerPrettyIsCustom) ffStrbufAppendC(&playerPretty, ')'); - if(instance->config.player.outputFormat.length == 0) + if(options->moduleArgs.outputFormat.length == 0) { - ffPrintLogoAndKey(instance, FF_PLAYER_MODULE_NAME, 0, &instance->config.player.key); + ffPrintLogoAndKey(instance, FF_PLAYER_DISPLAY_NAME, 0, &options->moduleArgs.key); ffStrbufPutTo(&playerPretty, stdout); } else { - ffPrintFormat(instance, FF_PLAYER_MODULE_NAME, 0, &instance->config.player, FF_PLAYER_NUM_FORMAT_ARGS, (FFformatarg[]){ + ffPrintFormat(instance, FF_PLAYER_DISPLAY_NAME, 0, &options->moduleArgs, FF_PLAYER_NUM_FORMAT_ARGS, (FFformatarg[]){ {FF_FORMAT_ARG_TYPE_STRBUF, &playerPretty}, {FF_FORMAT_ARG_TYPE_STRBUF, &media->player}, {FF_FORMAT_ARG_TYPE_STRBUF, &media->playerId}, {FF_FORMAT_ARG_TYPE_STRBUF, &media->url} }); } - - ffStrbufDestroy(&playerPretty); } + +void ffInitPlayerOptions(FFPlayerOptions* options) +{ + options->moduleName = FF_PLAYER_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + + ffStrbufInit(&options->name); +} + +bool ffParsePlayerCommandOptions(FFPlayerOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_PLAYER_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyPlayerOptions(FFPlayerOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); + + ffStrbufDestroy(&options->name); +} + +#ifdef FF_HAVE_JSONC +void ffParsePlayerJsonObject(FFinstance* instance, json_object* module) +{ + FFPlayerOptions __attribute__((__cleanup__(ffDestroyPlayerOptions))) options; + ffInitPlayerOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_PLAYER_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintPlayer(instance, &options); +} +#endif diff --git a/src/modules/player/player.h b/src/modules/player/player.h new file mode 100644 index 000000000..9b19d67cd --- /dev/null +++ b/src/modules/player/player.h @@ -0,0 +1,16 @@ + +#pragma once + +#include "fastfetch.h" + +#define FF_PLAYER_MODULE_NAME "Player" + +void ffPrintPlayer(FFinstance* instance, FFPlayerOptions* options); +void ffInitPlayerOptions(FFPlayerOptions* options); +bool ffParsePlayerCommandOptions(FFPlayerOptions* options, const char* key, const char* value); +void ffDestroyPlayerOptions(FFPlayerOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParsePlayerJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/poweradapter.c b/src/modules/poweradapter.c deleted file mode 100644 index c2cd7550d..000000000 --- a/src/modules/poweradapter.c +++ /dev/null @@ -1,66 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/poweradapter/poweradapter.h" - -#define FF_POWER_ADAPTER_MODULE_NAME "Power Adapter" -#define FF_POWER_ADAPTER_MODULE_ARGS 5 - -static void printPowerAdapter(FFinstance* instance, const PowerAdapterResult* result, uint8_t index) -{ - if(result->watts != FF_POWER_ADAPTER_UNSET) - { - if(instance->config.powerAdapter.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_POWER_ADAPTER_MODULE_NAME, index, &instance->config.powerAdapter.key); - - if(result->name.length > 0) - puts(result->name.chars); - else if(result->watts == FF_POWER_ADAPTER_NOT_CONNECTED) - puts("not connected"); - else - printf("%dW\n", result->watts); - } - else - { - ffPrintFormat(instance, FF_POWER_ADAPTER_MODULE_NAME, index, &instance->config.powerAdapter, FF_POWER_ADAPTER_MODULE_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_INT, &result->watts}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->name}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->manufacturer}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->modelName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->description}, - }); - } - } -} - -void ffPrintPowerAdapter(FFinstance* instance) -{ - FFlist results; - ffListInitA(&results, sizeof(PowerAdapterResult), 0); - - const char* error = ffDetectPowerAdapterImpl(instance, &results); - - if (error) - { - ffPrintError(instance, FF_POWER_ADAPTER_MODULE_NAME, 0, &instance->config.powerAdapter, "%s", error); - } - else if(results.length == 0) - { - ffPrintError(instance, FF_POWER_ADAPTER_MODULE_NAME, 0, &instance->config.powerAdapter, "No power adapters found"); - } - else - { - for(uint8_t i = 0; i < (uint8_t) results.length; i++) - { - PowerAdapterResult* result = ffListGet(&results, i); - printPowerAdapter(instance, result, i); - - ffStrbufDestroy(&result->manufacturer); - ffStrbufDestroy(&result->description); - ffStrbufDestroy(&result->modelName); - ffStrbufDestroy(&result->name); - } - } - - ffListDestroy(&results); -} diff --git a/src/modules/poweradapter/option.h b/src/modules/poweradapter/option.h new file mode 100644 index 000000000..7acaf29ee --- /dev/null +++ b/src/modules/poweradapter/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFPowerAdapterOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFPowerAdapterOptions; diff --git a/src/modules/poweradapter/poweradapter.c b/src/modules/poweradapter/poweradapter.c new file mode 100644 index 000000000..12e78395b --- /dev/null +++ b/src/modules/poweradapter/poweradapter.c @@ -0,0 +1,105 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/poweradapter/poweradapter.h" +#include "modules/poweradapter/poweradapter.h" + +#define FF_POWERADAPTER_DISPLAY_NAME "Power Adapter" +#define FF_POWERADAPTER_MODULE_ARGS 5 + +void ffPrintPowerAdapter(FFinstance* instance, FFPowerAdapterOptions* options) +{ + FFlist results; + ffListInit(&results, sizeof(PowerAdapterResult)); + + const char* error = ffDetectPowerAdapterImpl(instance, &results); + + if (error) + { + ffPrintError(instance, FF_POWERADAPTER_DISPLAY_NAME, 0, &options->moduleArgs, "%s", error); + } + else if(results.length == 0) + { + ffPrintError(instance, FF_POWERADAPTER_DISPLAY_NAME, 0, &options->moduleArgs, "No power adapters found"); + } + else + { + for(uint8_t i = 0; i < (uint8_t) results.length; i++) + { + PowerAdapterResult* result = ffListGet(&results, i); + + if(result->watts != FF_POWERADAPTER_UNSET) + { + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_POWERADAPTER_DISPLAY_NAME, i, &options->moduleArgs.key); + + if(result->name.length > 0) + puts(result->name.chars); + else if(result->watts == FF_POWERADAPTER_NOT_CONNECTED) + puts("not connected"); + else + printf("%dW\n", result->watts); + } + else + { + ffPrintFormat(instance, FF_POWERADAPTER_DISPLAY_NAME, i, &options->moduleArgs, FF_POWERADAPTER_MODULE_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_INT, &result->watts}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->name}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->manufacturer}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->modelName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->description}, + }); + } + } + + ffStrbufDestroy(&result->manufacturer); + ffStrbufDestroy(&result->description); + ffStrbufDestroy(&result->modelName); + ffStrbufDestroy(&result->name); + } + } + + ffListDestroy(&results); +} + +void ffInitPowerAdapterOptions(FFPowerAdapterOptions* options) +{ + options->moduleName = FF_POWERADAPTER_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParsePowerAdapterCommandOptions(FFPowerAdapterOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_POWERADAPTER_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyPowerAdapterOptions(FFPowerAdapterOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParsePowerAdapterJsonObject(FFinstance* instance, json_object* module) +{ + FFPowerAdapterOptions __attribute__((__cleanup__(ffDestroyPowerAdapterOptions))) options; + ffInitPowerAdapterOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_POWERADAPTER_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintPowerAdapter(instance, &options); +} +#endif diff --git a/src/modules/poweradapter/poweradapter.h b/src/modules/poweradapter/poweradapter.h new file mode 100644 index 000000000..4c11d1976 --- /dev/null +++ b/src/modules/poweradapter/poweradapter.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_POWERADAPTER_MODULE_NAME "PowerAdapter" + +void ffPrintPowerAdapter(FFinstance* instance, FFPowerAdapterOptions* options); +void ffInitPowerAdapterOptions(FFPowerAdapterOptions* options); +bool ffParsePowerAdapterCommandOptions(FFPowerAdapterOptions* options, const char* key, const char* value); +void ffDestroyPowerAdapterOptions(FFPowerAdapterOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParsePowerAdapterJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/processes.c b/src/modules/processes.c deleted file mode 100644 index 70a64ad83..000000000 --- a/src/modules/processes.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/processes/processes.h" - -#define FF_PROCESSES_MODULE_NAME "Processes" -#define FF_PROCESSES_NUM_FORMAT_ARGS 1 - -void ffPrintProcesses(FFinstance* instance) -{ - uint32_t numProcesses = 0; - const char* error = ffDetectProcesses(&numProcesses); - - if(error) - { - ffPrintError(instance, FF_PROCESSES_MODULE_NAME, 0, &instance->config.processes, "%s", error); - return; - } - - if(instance->config.processes.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_PROCESSES_MODULE_NAME, 0, &instance->config.processes.key); - - printf("%u\n", numProcesses); - } - else - { - ffPrintFormat(instance, FF_PROCESSES_MODULE_NAME, 0, &instance->config.processes, FF_PROCESSES_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_UINT, &numProcesses} - }); - } -} diff --git a/src/modules/processes/option.h b/src/modules/processes/option.h new file mode 100644 index 000000000..9d2cd8086 --- /dev/null +++ b/src/modules/processes/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFProcessesOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFProcessesOptions; diff --git a/src/modules/processes/processes.c b/src/modules/processes/processes.c new file mode 100644 index 000000000..719bb45f5 --- /dev/null +++ b/src/modules/processes/processes.c @@ -0,0 +1,73 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/processes/processes.h" +#include "modules/processes/processes.h" + +#define FF_PROCESSES_NUM_FORMAT_ARGS 1 + +void ffPrintProcesses(FFinstance* instance, FFProcessesOptions* options) +{ + uint32_t numProcesses = 0; + const char* error = ffDetectProcesses(&numProcesses); + + if(error) + { + ffPrintError(instance, FF_PROCESSES_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_PROCESSES_MODULE_NAME, 0, &options->moduleArgs.key); + + printf("%u\n", numProcesses); + } + else + { + ffPrintFormat(instance, FF_PROCESSES_MODULE_NAME, 0, &options->moduleArgs, FF_PROCESSES_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_UINT, &numProcesses} + }); + } +} + +void ffInitProcessesOptions(FFProcessesOptions* options) +{ + options->moduleName = FF_PROCESSES_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseProcessesCommandOptions(FFProcessesOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_PROCESSES_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyProcessesOptions(FFProcessesOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseProcessesJsonObject(FFinstance* instance, json_object* module) +{ + FFProcessesOptions __attribute__((__cleanup__(ffDestroyProcessesOptions))) options; + ffInitProcessesOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_PROCESSES_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintProcesses(instance, &options); +} +#endif diff --git a/src/modules/processes/processes.h b/src/modules/processes/processes.h new file mode 100644 index 000000000..34abb7ef8 --- /dev/null +++ b/src/modules/processes/processes.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_PROCESSES_MODULE_NAME "Processes" + +void ffPrintProcesses(FFinstance* instance, FFProcessesOptions* options); +void ffInitProcessesOptions(FFProcessesOptions* options); +bool ffParseProcessesCommandOptions(FFProcessesOptions* options, const char* key, const char* value); +void ffDestroyProcessesOptions(FFProcessesOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseProcessesJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/publicip.c b/src/modules/publicip.c deleted file mode 100644 index 61c85698e..000000000 --- a/src/modules/publicip.c +++ /dev/null @@ -1,74 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "common/networking.h" - -#define FF_PUBLICIP_MODULE_NAME "Public IP" -#define FF_PUBLICIP_NUM_FORMAT_ARGS 1 - -static FFNetworkingState state; -static int status = -1; - -void ffPreparePublicIp(FFinstance* instance) -{ - if(instance->config.publicIpUrl.length == 0) - status = ffNetworkingSendHttpRequest(&state, "ipinfo.io", "/ip", NULL); - else - { - FFstrbuf host; - ffStrbufInitCopy(&host, &instance->config.publicIpUrl); - ffStrbufSubstrAfterFirstS(&host, "://"); - uint32_t pathStartIndex = ffStrbufFirstIndexC(&host, '/'); - - FFstrbuf path; - ffStrbufInit(&path); - if(pathStartIndex != host.length) - { - ffStrbufAppendNS(&path, pathStartIndex, host.chars + (host.length - pathStartIndex)); - host.length = pathStartIndex; - host.chars[pathStartIndex] = '\0'; - } - - status = ffNetworkingSendHttpRequest(&state, host.chars, path.length == 0 ? "/" : path.chars, NULL); - - ffStrbufDestroy(&path); - ffStrbufDestroy(&host); - } -} - -void ffPrintPublicIp(FFinstance* instance) -{ - if(status == -1) - ffPreparePublicIp(instance); - - if(status == 0) - { - ffPrintError(instance, FF_PUBLICIP_MODULE_NAME, 0, &instance->config.publicIP, "Failed to connect to an IP detection server"); - return; - } - - FFstrbuf result; - ffStrbufInitA(&result, 4096); - bool success = ffNetworkingRecvHttpResponse(&state, &result, instance->config.publicIpTimeout); - if(success) ffStrbufSubstrAfterFirstS(&result, "\r\n\r\n"); - - if(!success || result.length == 0) - { - ffPrintError(instance, FF_PUBLICIP_MODULE_NAME, 0, &instance->config.publicIP, "Failed to receive the server response"); - ffStrbufDestroy(&result); - return; - } - - if(instance->config.publicIP.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_PUBLICIP_MODULE_NAME, 0, &instance->config.publicIP.key); - ffStrbufPutTo(&result, stdout); - } - else - { - ffPrintFormat(instance, FF_PUBLICIP_MODULE_NAME, 0, &instance->config.publicIP, FF_PUBLICIP_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &result} - }); - } - - ffStrbufDestroy(&result); -} diff --git a/src/modules/publicip/option.h b/src/modules/publicip/option.h new file mode 100644 index 000000000..aef383fc5 --- /dev/null +++ b/src/modules/publicip/option.h @@ -0,0 +1,14 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFPublicIpOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + FFstrbuf url; + uint32_t timeout; +} FFPublicIpOptions; diff --git a/src/modules/publicip/publicip.c b/src/modules/publicip/publicip.c new file mode 100644 index 000000000..a1ebc8819 --- /dev/null +++ b/src/modules/publicip/publicip.c @@ -0,0 +1,137 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "common/networking.h" +#include "modules/publicip/publicip.h" + +#define FF_PUBLICIP_DISPLAY_NAME "Public IP" +#define FF_PUBLICIP_NUM_FORMAT_ARGS 1 + +static FFNetworkingState state; +static int status = -1; + +void ffPreparePublicIp(FFPublicIpOptions* options) +{ + if (options->url.length == 0) + status = ffNetworkingSendHttpRequest(&state, "ipinfo.io", "/ip", NULL); + else + { + FF_STRBUF_AUTO_DESTROY host = ffStrbufCreateCopy(&options->url); + ffStrbufSubstrAfterFirstS(&host, "://"); + uint32_t pathStartIndex = ffStrbufFirstIndexC(&host, '/'); + + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate(); + if(pathStartIndex != host.length) + { + ffStrbufAppendNS(&path, pathStartIndex, host.chars + (host.length - pathStartIndex)); + host.length = pathStartIndex; + host.chars[pathStartIndex] = '\0'; + } + + status = ffNetworkingSendHttpRequest(&state, host.chars, path.length == 0 ? "/" : path.chars, NULL); + } +} + +void ffPrintPublicIp(FFinstance* instance, FFPublicIpOptions* options) +{ + if (status == -1) + ffPreparePublicIp(options); + + if (status == 0) + { + ffPrintError(instance, FF_PUBLICIP_DISPLAY_NAME, 0, &options->moduleArgs, "Failed to connect to an IP detection server"); + return; + } + + FF_STRBUF_AUTO_DESTROY result = ffStrbufCreateA(4096); + bool success = ffNetworkingRecvHttpResponse(&state, &result, options->timeout); + if (success) ffStrbufSubstrAfterFirstS(&result, "\r\n\r\n"); + + if (!success || result.length == 0) + { + ffPrintError(instance, FF_PUBLICIP_DISPLAY_NAME, 0, &options->moduleArgs, "Failed to receive the server response"); + return; + } + + if (options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_PUBLICIP_DISPLAY_NAME, 0, &options->moduleArgs.key); + ffStrbufPutTo(&result, stdout); + } + else + { + ffPrintFormat(instance, FF_PUBLICIP_DISPLAY_NAME, 0, &options->moduleArgs, FF_PUBLICIP_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &result} + }); + } +} + +void ffInitPublicIpOptions(FFPublicIpOptions* options) +{ + options->moduleName = FF_PUBLICIP_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + + ffStrbufInit(&options->url); + options->timeout = 0; +} + +bool ffParsePublicIpCommandOptions(FFPublicIpOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_PUBLICIP_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (strcasecmp(subKey, "url") == 0) + { + ffOptionParseString(key, value, &options->url); + return true; + } + + if (strcasecmp(subKey, "timeout") == 0) + { + options->timeout = ffOptionParseUInt32(key, value); + return true; + } + + return false; +} + +void ffDestroyPublicIpOptions(FFPublicIpOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); + + ffStrbufDestroy(&options->url); +} + +#ifdef FF_HAVE_JSONC +void ffParsePublicIpJsonObject(FFinstance* instance, json_object* module) +{ + FFPublicIpOptions __attribute__((__cleanup__(ffDestroyPublicIpOptions))) options; + ffInitPublicIpOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + if (strcasecmp(key, "url") == 0) + { + ffStrbufSetS(&options.url, json_object_get_string(val)); + continue; + } + + if (strcasecmp(key, "timeout") == 0) + { + options.timeout = (uint32_t) json_object_get_int(val); + continue; + } + + ffPrintError(instance, FF_PUBLICIP_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintPublicIp(instance, &options); +} +#endif diff --git a/src/modules/publicip/publicip.h b/src/modules/publicip/publicip.h new file mode 100644 index 000000000..2306ddcf4 --- /dev/null +++ b/src/modules/publicip/publicip.h @@ -0,0 +1,17 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_PUBLICIP_MODULE_NAME "PublicIp" + +void ffPreparePublicIp(FFPublicIpOptions* options); + +void ffPrintPublicIp(FFinstance* instance, FFPublicIpOptions* options); +void ffInitPublicIpOptions(FFPublicIpOptions* options); +bool ffParsePublicIpCommandOptions(FFPublicIpOptions* options, const char* key, const char* value); +void ffDestroyPublicIpOptions(FFPublicIpOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParsePublicIpJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/separator.c b/src/modules/separator.c deleted file mode 100644 index 879bc5bb8..000000000 --- a/src/modules/separator.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" - -void ffPrintSeparator(FFinstance* instance) -{ - uint32_t titleLength = instance->state.platform.userName.length + 1 + (instance->config.titleFQDN ? - instance->state.platform.domainName.length : - instance->state.platform.hostName.length - ); - - ffLogoPrintLine(instance); - - if(instance->config.separatorString.length == 0) - { - for(uint32_t i = 0; i < titleLength; i++) - putchar('-'); - } - else - { - //Write the whole separator as often as it fits fully into titleLength - for(uint32_t i = 0; i < titleLength / instance->config.separatorString.length; i++) - ffStrbufWriteTo(&instance->config.separatorString, stdout); - - //Write as much of the separator as needed to fill titleLength - for(uint32_t i = 0; i < titleLength % instance->config.separatorString.length; i++) - putchar(instance->config.separatorString.chars[i]); - } - putchar('\n'); -} diff --git a/src/modules/separator/option.h b/src/modules/separator/option.h new file mode 100644 index 000000000..10f5effdf --- /dev/null +++ b/src/modules/separator/option.h @@ -0,0 +1,12 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFSeparatorOptions +{ + const char* moduleName; + + FFstrbuf string; +} FFSeparatorOptions; diff --git a/src/modules/separator/separator.c b/src/modules/separator/separator.c new file mode 100644 index 000000000..d693dc398 --- /dev/null +++ b/src/modules/separator/separator.c @@ -0,0 +1,83 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "modules/separator/separator.h" + +void ffPrintSeparator(FFinstance* instance, FFSeparatorOptions* options) +{ + uint32_t titleLength = instance->state.titleLength; + if (titleLength == 0) + { + // Title was not printed, should we support this case? + titleLength = instance->state.platform.userName.length + 1 + (instance->config.title.fdqn ? + instance->state.platform.domainName.length : + instance->state.platform.hostName.length + ); + } + + ffLogoPrintLine(instance); + + if(options->string.length == 0) + { + ffPrintCharTimes('-', titleLength); + } + else + { + //Write the whole separator as often as it fits fully into titleLength + for(uint32_t i = 0; i < titleLength / options->string.length; i++) + ffStrbufWriteTo(&options->string, stdout); + + //Write as much of the separator as needed to fill titleLength + for(uint32_t i = 0; i < titleLength % options->string.length; i++) + putchar(options->string.chars[i]); + } + putchar('\n'); +} + +void ffInitSeparatorOptions(FFSeparatorOptions* options) +{ + options->moduleName = FF_SEPARATOR_MODULE_NAME; + ffStrbufInit(&options->string); +} + +bool ffParseSeparatorCommandOptions(FFSeparatorOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_SEPARATOR_MODULE_NAME); + if (!subKey) return false; + + if (strcasecmp(subKey, "string") == 0) + { + ffOptionParseString(key, value, &options->string); + return true; + } + + return false; +} + +void ffDestroySeparatorOptions(FFSeparatorOptions* options) +{ + ffStrbufDestroy(&options->string); +} + +#ifdef FF_HAVE_JSONC +void ffParseSeparatorJsonObject(FFinstance* instance, json_object* module) +{ + FFSeparatorOptions __attribute__((__cleanup__(ffDestroySeparatorOptions))) options; + ffInitSeparatorOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (strcasecmp(key, "string") == 0) + { + ffStrbufSetS(&options.string, json_object_get_string(val)); + continue; + } + + ffPrintErrorString(instance, FF_SEPARATOR_MODULE_NAME, 0, NULL, NULL, "Unknown JSON key %s", key); + } + } + + ffPrintSeparator(instance, &options); +} +#endif diff --git a/src/modules/separator/separator.h b/src/modules/separator/separator.h new file mode 100644 index 000000000..de26799bc --- /dev/null +++ b/src/modules/separator/separator.h @@ -0,0 +1,16 @@ +#pragma once + +#include "fastfetch.h" +#include "modules/separator/option.h" + +#define FF_SEPARATOR_MODULE_NAME "Separator" + +void ffPrintSeparator(FFinstance* instance, FFSeparatorOptions* options); +void ffInitSeparatorOptions(FFSeparatorOptions* options); +bool ffParseSeparatorCommandOptions(FFSeparatorOptions* options, const char* key, const char* value); +void ffDestroySeparatorOptions(FFSeparatorOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseSeparatorJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/shell.c b/src/modules/shell.c deleted file mode 100644 index 607f5ec69..000000000 --- a/src/modules/shell.c +++ /dev/null @@ -1,43 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/terminalshell/terminalshell.h" - -#define FF_SHELL_MODULE_NAME "Shell" -#define FF_SHELL_NUM_FORMAT_ARGS 7 - -void ffPrintShell(FFinstance* instance) -{ - const FFTerminalShellResult* result = ffDetectTerminalShell(instance); - - if(result->shellProcessName.length == 0) - { - ffPrintError(instance, FF_SHELL_MODULE_NAME, 0, &instance->config.shell, "Couldn't detect shell"); - return; - } - - if(instance->config.shell.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_SHELL_MODULE_NAME, 0, &instance->config.shell.key); - ffStrbufWriteTo(&result->shellPrettyName, stdout); - - if(result->shellVersion.length > 0) - { - putchar(' '); - ffStrbufWriteTo(&result->shellVersion, stdout); - } - - putchar('\n'); - } - else - { - ffPrintFormat(instance, FF_SHELL_MODULE_NAME, 0, &instance->config.shell, FF_SHELL_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &result->shellProcessName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->shellExe}, - {FF_FORMAT_ARG_TYPE_STRING, result->shellExeName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->shellVersion}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->userShellExe}, - {FF_FORMAT_ARG_TYPE_STRING, result->userShellExeName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->userShellVersion} - }); - } -} diff --git a/src/modules/shell/option.h b/src/modules/shell/option.h new file mode 100644 index 000000000..dd6223a36 --- /dev/null +++ b/src/modules/shell/option.h @@ -0,0 +1,13 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFShellOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + bool version; +} FFShellOptions; diff --git a/src/modules/shell/shell.c b/src/modules/shell/shell.c new file mode 100644 index 000000000..ca5a22cab --- /dev/null +++ b/src/modules/shell/shell.c @@ -0,0 +1,99 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/terminalshell/terminalshell.h" +#include "modules/shell/shell.h" + +#define FF_SHELL_NUM_FORMAT_ARGS 7 + +void ffPrintShell(FFinstance* instance, FFShellOptions* options) +{ + const FFTerminalShellResult* result = ffDetectTerminalShell(instance); + + if(result->shellProcessName.length == 0) + { + ffPrintError(instance, FF_SHELL_MODULE_NAME, 0, &options->moduleArgs, "Couldn't detect shell"); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_SHELL_MODULE_NAME, 0, &options->moduleArgs.key); + ffStrbufWriteTo(&result->shellPrettyName, stdout); + + if(result->shellVersion.length > 0) + { + putchar(' '); + ffStrbufWriteTo(&result->shellVersion, stdout); + } + + putchar('\n'); + } + else + { + ffPrintFormat(instance, FF_SHELL_MODULE_NAME, 0, &options->moduleArgs, FF_SHELL_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &result->shellProcessName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->shellExe}, + {FF_FORMAT_ARG_TYPE_STRING, result->shellExeName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->shellVersion}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->userShellExe}, + {FF_FORMAT_ARG_TYPE_STRING, result->userShellExeName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->userShellVersion} + }); + } +} + +void ffInitShellOptions(FFShellOptions* options) +{ + options->moduleName = FF_SHELL_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + + options->version = true; +} + +bool ffParseShellCommandOptions(FFShellOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_SHELL_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (strcasecmp(subKey, "version") == 0) + { + options->version = ffOptionParseBoolean(value); + return true; + } + + return false; +} + +void ffDestroyShellOptions(FFShellOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseShellJsonObject(FFinstance* instance, json_object* module) +{ + FFShellOptions __attribute__((__cleanup__(ffDestroyShellOptions))) options; + ffInitShellOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + if (strcasecmp(key, "version") == 0) + { + options.version = (bool) json_object_get_boolean(val); + continue; + } + + ffPrintError(instance, FF_SHELL_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintShell(instance, &options); +} +#endif diff --git a/src/modules/shell/shell.h b/src/modules/shell/shell.h new file mode 100644 index 000000000..210d17dbf --- /dev/null +++ b/src/modules/shell/shell.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_SHELL_MODULE_NAME "Shell" + +void ffPrintShell(FFinstance* instance, FFShellOptions* options); +void ffInitShellOptions(FFShellOptions* options); +bool ffParseShellCommandOptions(FFShellOptions* options, const char* key, const char* value); +void ffDestroyShellOptions(FFShellOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseShellJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/sound.c b/src/modules/sound.c deleted file mode 100644 index ffc4aee76..000000000 --- a/src/modules/sound.c +++ /dev/null @@ -1,85 +0,0 @@ -#include "common/printing.h" -#include "detection/sound/sound.h" - -#define FF_SOUND_MODULE_NAME "Sound" -#define FF_SOUND_NUM_FORMAT_ARGS 4 - -static void printDevice(FFinstance* instance, const FFSoundDevice* device, uint8_t index) -{ - if(instance->config.sound.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_SOUND_MODULE_NAME, index, &instance->config.sound.key); - ffStrbufWriteTo(&device->name, stdout); - - if(device->volume != FF_SOUND_VOLUME_UNKNOWN) - { - if(device->volume > 0) - printf(" (%d%%)", device->volume); - else - fputs(" (muted)", stdout); - } - - if(device->main && index > 0) - fputs(" (*)", stdout); - - putchar('\n'); - } - else - { - ffPrintFormat(instance, FF_SOUND_MODULE_NAME, index, &instance->config.sound, FF_SOUND_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_BOOL, &device->main}, - {FF_FORMAT_ARG_TYPE_STRBUF, &device->name}, - {FF_FORMAT_ARG_TYPE_UINT8, &device->volume}, - {FF_FORMAT_ARG_TYPE_STRBUF, &device->identifier} - }); - } -} - -static void printSound(FFinstance* instance, FFlist* devices) -{ - FF_LIST_AUTO_DESTROY filtered; - ffListInit(&filtered, sizeof(FFSoundDevice*)); - - FF_LIST_FOR_EACH(FFSoundDevice, device, *devices) - { - switch (instance->config.soundType) - { - case FF_SOUND_TYPE_MAIN: if (!device->main) continue; break; - case FF_SOUND_TYPE_ACTIVE: if (!device->active) continue; break; - case FF_SOUND_TYPE_ALL: break; - } - - *(FFSoundDevice**)ffListAdd(&filtered) = device; - } - - if(filtered.length == 0) - { - ffPrintError(instance, FF_SOUND_MODULE_NAME, 0, &instance->config.sound, "No active sound devices found"); - return; - } - - uint8_t index = 1; - FF_LIST_FOR_EACH(FFSoundDevice*, device, filtered) - printDevice(instance, *device, filtered.length == 1 ? 0 : index++); -} - -void ffPrintSound(FFinstance* instance) -{ - FF_LIST_AUTO_DESTROY result; - ffListInit(&result, sizeof(FFSoundDevice)); - const char* error = ffDetectSound(instance, &result); - - if(error) - { - ffPrintError(instance, FF_SOUND_MODULE_NAME, 0, &instance->config.sound, "%s", error); - return; - } - - printSound(instance, &result); - - FF_LIST_FOR_EACH(FFSoundDevice, device, result) - { - ffStrbufDestroy(&device->identifier); - ffStrbufDestroy(&device->name); - } -} diff --git a/src/modules/sound/option.h b/src/modules/sound/option.h new file mode 100644 index 000000000..b0586036b --- /dev/null +++ b/src/modules/sound/option.h @@ -0,0 +1,20 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef enum FFSoundType +{ + FF_SOUND_TYPE_MAIN, + FF_SOUND_TYPE_ACTIVE, + FF_SOUND_TYPE_ALL, +} FFSoundType; + +typedef struct FFSoundOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + FFSoundType soundType; +} FFSoundOptions; diff --git a/src/modules/sound/sound.c b/src/modules/sound/sound.c new file mode 100644 index 000000000..9f5e1c5a4 --- /dev/null +++ b/src/modules/sound/sound.c @@ -0,0 +1,153 @@ +#include "common/printing.h" +#include "detection/sound/sound.h" +#include "modules/sound/sound.h" + +#define FF_SOUND_NUM_FORMAT_ARGS 4 + +static void printDevice(FFinstance* instance, FFSoundOptions* options, const FFSoundDevice* device, uint8_t index) +{ + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_SOUND_MODULE_NAME, index, &options->moduleArgs.key); + ffStrbufWriteTo(&device->name, stdout); + + if(device->volume != FF_SOUND_VOLUME_UNKNOWN) + { + if(device->volume > 0) + printf(" (%d%%)", device->volume); + else + fputs(" (muted)", stdout); + } + + if(device->main && index > 0) + fputs(" (*)", stdout); + + putchar('\n'); + } + else + { + ffPrintFormat(instance, FF_SOUND_MODULE_NAME, index, &options->moduleArgs, FF_SOUND_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_BOOL, &device->main}, + {FF_FORMAT_ARG_TYPE_STRBUF, &device->name}, + {FF_FORMAT_ARG_TYPE_UINT8, &device->volume}, + {FF_FORMAT_ARG_TYPE_STRBUF, &device->identifier} + }); + } +} + +void ffPrintSound(FFinstance* instance, FFSoundOptions* options) +{ + FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFSoundDevice)); + + const char* error = ffDetectSound(instance, &result); + + if(error) + { + ffPrintError(instance, FF_SOUND_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + FF_LIST_AUTO_DESTROY filtered = ffListCreate(sizeof(FFSoundDevice*)); + + FF_LIST_FOR_EACH(FFSoundDevice, device, result) + { + switch (options->soundType) + { + case FF_SOUND_TYPE_MAIN: if (!device->main) continue; break; + case FF_SOUND_TYPE_ACTIVE: if (!device->active) continue; break; + case FF_SOUND_TYPE_ALL: break; + } + + *(FFSoundDevice**)ffListAdd(&filtered) = device; + } + + if(filtered.length == 0) + { + ffPrintError(instance, FF_SOUND_MODULE_NAME, 0, &options->moduleArgs, "No active sound devices found"); + return; + } + + uint8_t index = 1; + FF_LIST_FOR_EACH(FFSoundDevice*, device, filtered) + { + printDevice(instance, options, *device, filtered.length == 1 ? 0 : index++); + } + + FF_LIST_FOR_EACH(FFSoundDevice, device, result) + { + ffStrbufDestroy(&device->identifier); + ffStrbufDestroy(&device->name); + } +} + + +void ffInitSoundOptions(FFSoundOptions* options) +{ + options->moduleName = FF_SOUND_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + + options->soundType = FF_SOUND_TYPE_MAIN; +} + +bool ffParseSoundCommandOptions(FFSoundOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_SOUND_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (strcasecmp(subKey, "sound-type") == 0) + { + options->soundType = (FFSoundType) ffOptionParseEnum(key, value, (FFKeyValuePair[]) { + { "main", FF_SOUND_TYPE_MAIN }, + { "active", FF_SOUND_TYPE_ACTIVE }, + { "all", FF_SOUND_TYPE_ALL }, + {}, + }); + return true; + } + + return false; +} + +void ffDestroySoundOptions(FFSoundOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseSoundJsonObject(FFinstance* instance, json_object* module) +{ + FFSoundOptions __attribute__((__cleanup__(ffDestroySoundOptions))) options; + ffInitSoundOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + if (strcasecmp(key, "soundType") == 0) + { + int value; + const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) { + { "main", FF_SOUND_TYPE_MAIN }, + { "active", FF_SOUND_TYPE_ACTIVE }, + { "all", FF_SOUND_TYPE_ALL }, + {}, + }); + if (error) + ffPrintError(instance, FF_SOUND_MODULE_NAME, 0, &options.moduleArgs, "Invalid %s value: %s", key, error); + else + options.soundType = (FFSoundType) value; + continue; + } + + ffPrintError(instance, FF_SOUND_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintSound(instance, &options); +} +#endif diff --git a/src/modules/sound/sound.h b/src/modules/sound/sound.h new file mode 100644 index 000000000..fa9d8dc87 --- /dev/null +++ b/src/modules/sound/sound.h @@ -0,0 +1,16 @@ +#pragma once + +#include "fastfetch.h" +#include "modules/title/option.h" + +#define FF_SOUND_MODULE_NAME "Sound" + +void ffPrintSound(FFinstance* instance, FFSoundOptions* options); +void ffInitSoundOptions(FFSoundOptions* options); +bool ffParseSoundCommandOptions(FFSoundOptions* options, const char* key, const char* value); +void ffDestroySoundOptions(FFSoundOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseSoundJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/swap.c b/src/modules/swap.c deleted file mode 100644 index 1f6175b15..000000000 --- a/src/modules/swap.c +++ /dev/null @@ -1,67 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "common/parsing.h" -#include "common/bar.h" -#include "detection/swap/swap.h" - -#define FF_SWAP_MODULE_NAME "Swap" -#define FF_SWAP_NUM_FORMAT_ARGS 3 - -void ffPrintSwap(FFinstance* instance) -{ - FFSwapResult storage; - const char* error = ffDetectSwap(&storage); - - if(error) - { - ffPrintError(instance, FF_SWAP_MODULE_NAME, 0, &instance->config.swap, "%s", error); - return; - } - - FF_STRBUF_AUTO_DESTROY usedPretty; - ffStrbufInit(&usedPretty); - ffParseSize(storage.bytesUsed, instance->config.binaryPrefixType, &usedPretty); - - FF_STRBUF_AUTO_DESTROY totalPretty; - ffStrbufInit(&totalPretty); - ffParseSize(storage.bytesTotal, instance->config.binaryPrefixType, &totalPretty); - - uint8_t percentage = storage.bytesTotal == 0 - ? 0 - : (uint8_t) (((long double) storage.bytesUsed / (long double) storage.bytesTotal) * 100.0); - - if(instance->config.swap.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_SWAP_MODULE_NAME, 0, &instance->config.swap.key); - if (storage.bytesTotal == 0) - puts("Disabled"); - else - { - FF_STRBUF_AUTO_DESTROY str; - ffStrbufInit(&str); - - if(instance->config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) - { - ffAppendPercentBar(instance, &str, percentage, 0, 5, 8); - ffStrbufAppendC(&str, ' '); - } - - if(!(instance->config.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) - ffStrbufAppendF(&str, "%s / %s ", usedPretty.chars, totalPretty.chars); - - if(instance->config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) - ffAppendPercentNum(instance, &str, (uint8_t) percentage, 50, 80, str.length > 0); - - ffStrbufTrimRight(&str, ' '); - ffStrbufPutTo(&str, stdout); - } - } - else - { - ffPrintFormat(instance, FF_SWAP_MODULE_NAME, 0, &instance->config.swap, FF_SWAP_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty}, - {FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty}, - {FF_FORMAT_ARG_TYPE_UINT8, &percentage}, - }); - } -} diff --git a/src/modules/swap/option.h b/src/modules/swap/option.h new file mode 100644 index 000000000..4053cfbe1 --- /dev/null +++ b/src/modules/swap/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFSwapOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFSwapOptions; diff --git a/src/modules/swap/swap.c b/src/modules/swap/swap.c new file mode 100644 index 000000000..d3029878e --- /dev/null +++ b/src/modules/swap/swap.c @@ -0,0 +1,106 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "common/parsing.h" +#include "common/bar.h" +#include "detection/swap/swap.h" +#include "modules/swap/swap.h" + +#define FF_SWAP_NUM_FORMAT_ARGS 3 + +void ffPrintSwap(FFinstance* instance, FFSwapOptions* options) +{ + FFSwapResult storage; + const char* error = ffDetectSwap(&storage); + + if(error) + { + ffPrintError(instance, FF_SWAP_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + FF_STRBUF_AUTO_DESTROY usedPretty = ffStrbufCreate(); + ffParseSize(storage.bytesUsed, instance->config.binaryPrefixType, &usedPretty); + + FF_STRBUF_AUTO_DESTROY totalPretty = ffStrbufCreate(); + ffParseSize(storage.bytesTotal, instance->config.binaryPrefixType, &totalPretty); + + uint8_t percentage = storage.bytesTotal == 0 + ? 0 + : (uint8_t) (((long double) storage.bytesUsed / (long double) storage.bytesTotal) * 100.0); + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_SWAP_MODULE_NAME, 0, &options->moduleArgs.key); + if (storage.bytesTotal == 0) + puts("Disabled"); + else + { + FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate(); + + if(instance->config.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + { + ffAppendPercentBar(instance, &str, percentage, 0, 5, 8); + ffStrbufAppendC(&str, ' '); + } + + if(!(instance->config.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) + ffStrbufAppendF(&str, "%s / %s ", usedPretty.chars, totalPretty.chars); + + if(instance->config.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffAppendPercentNum(instance, &str, (uint8_t) percentage, 50, 80, str.length > 0); + + ffStrbufTrimRight(&str, ' '); + ffStrbufPutTo(&str, stdout); + } + } + else + { + ffPrintFormat(instance, FF_SWAP_MODULE_NAME, 0, &options->moduleArgs, FF_SWAP_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty}, + {FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty}, + {FF_FORMAT_ARG_TYPE_UINT8, &percentage}, + }); + } +} + +void ffInitSwapOptions(FFSwapOptions* options) +{ + options->moduleName = FF_SWAP_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseSwapCommandOptions(FFSwapOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_SWAP_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroySwapOptions(FFSwapOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseSwapJsonObject(FFinstance* instance, json_object* module) +{ + FFSwapOptions __attribute__((__cleanup__(ffDestroySwapOptions))) options; + ffInitSwapOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_SWAP_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintSwap(instance, &options); +} +#endif diff --git a/src/modules/swap/swap.h b/src/modules/swap/swap.h new file mode 100644 index 000000000..7326d14da --- /dev/null +++ b/src/modules/swap/swap.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_SWAP_MODULE_NAME "Swap" + +void ffPrintSwap(FFinstance* instance, FFSwapOptions* options); +void ffInitSwapOptions(FFSwapOptions* options); +bool ffParseSwapCommandOptions(FFSwapOptions* options, const char* key, const char* value); +void ffDestroySwapOptions(FFSwapOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseSwapJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/terminal.c b/src/modules/terminal.c deleted file mode 100644 index 28e8d14a5..000000000 --- a/src/modules/terminal.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/terminalshell/terminalshell.h" - -#include - -#define FF_TERMINAL_MODULE_NAME "Terminal" -#define FF_TERMINAL_NUM_FORMAT_ARGS 10 - -void ffPrintTerminal(FFinstance* instance) -{ - const FFTerminalShellResult* result = ffDetectTerminalShell(instance); - - if(result->terminalProcessName.length == 0) - { - ffPrintError(instance, FF_TERMINAL_MODULE_NAME, 0, &instance->config.terminal, "Couldn't detect terminal"); - return; - } - - if(instance->config.terminal.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_TERMINAL_MODULE_NAME, 0, &instance->config.terminal.key); - - if(result->terminalVersion.length) - printf("%s %s\n", result->terminalPrettyName.chars, result->terminalVersion.chars); - else - ffStrbufPutTo(&result->terminalPrettyName, stdout); - } - else - { - ffPrintFormat(instance, FF_TERMINAL_MODULE_NAME, 0, &instance->config.terminal, FF_TERMINAL_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &result->terminalProcessName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->terminalExe}, - {FF_FORMAT_ARG_TYPE_STRING, result->terminalExeName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->shellProcessName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->shellExe}, - {FF_FORMAT_ARG_TYPE_STRING, result->shellExeName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->shellVersion}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->userShellExe}, - {FF_FORMAT_ARG_TYPE_STRING, result->userShellExeName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->userShellVersion} - }); - } -} diff --git a/src/modules/terminal/option.h b/src/modules/terminal/option.h new file mode 100644 index 000000000..46c9c96fa --- /dev/null +++ b/src/modules/terminal/option.h @@ -0,0 +1,13 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFTerminalOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + bool version; +} FFTerminalOptions; diff --git a/src/modules/terminal/terminal.c b/src/modules/terminal/terminal.c new file mode 100644 index 000000000..23c2f8460 --- /dev/null +++ b/src/modules/terminal/terminal.c @@ -0,0 +1,100 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/terminalshell/terminalshell.h" +#include "modules/terminal/terminal.h" + +#include + +#define FF_TERMINAL_NUM_FORMAT_ARGS 10 + +void ffPrintTerminal(FFinstance* instance, FFTerminalOptions* options) +{ + const FFTerminalShellResult* result = ffDetectTerminalShell(instance); + + if(result->terminalProcessName.length == 0) + { + ffPrintError(instance, FF_TERMINAL_MODULE_NAME, 0, &options->moduleArgs, "Couldn't detect terminal"); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_TERMINAL_MODULE_NAME, 0, &options->moduleArgs.key); + + if(result->terminalVersion.length) + printf("%s %s\n", result->terminalPrettyName.chars, result->terminalVersion.chars); + else + ffStrbufPutTo(&result->terminalPrettyName, stdout); + } + else + { + ffPrintFormat(instance, FF_TERMINAL_MODULE_NAME, 0, &options->moduleArgs, FF_TERMINAL_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &result->terminalProcessName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->terminalExe}, + {FF_FORMAT_ARG_TYPE_STRING, result->terminalExeName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->shellProcessName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->shellExe}, + {FF_FORMAT_ARG_TYPE_STRING, result->shellExeName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->shellVersion}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->userShellExe}, + {FF_FORMAT_ARG_TYPE_STRING, result->userShellExeName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->userShellVersion} + }); + } +} + +void ffInitTerminalOptions(FFTerminalOptions* options) +{ + options->moduleName = FF_TERMINAL_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + + options->version = true; +} + +bool ffParseTerminalCommandOptions(FFTerminalOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_TERMINAL_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (strcasecmp(subKey, "version") == 0) + { + options->version = ffOptionParseBoolean(value); + return true; + } + + return false; +} + +void ffDestroyTerminalOptions(FFTerminalOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseTerminalJsonObject(FFinstance* instance, json_object* module) +{ + FFTerminalOptions __attribute__((__cleanup__(ffDestroyTerminalOptions))) options; + ffInitTerminalOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + if (strcasecmp(key, "version") == 0) + { + options.version = (bool) json_object_get_boolean(val); + continue; + } + + ffPrintError(instance, FF_TERMINAL_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintTerminal(instance, &options); +} +#endif diff --git a/src/modules/terminal/terminal.h b/src/modules/terminal/terminal.h new file mode 100644 index 000000000..56a7dc0be --- /dev/null +++ b/src/modules/terminal/terminal.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_TERMINAL_MODULE_NAME "Terminal" + +void ffPrintTerminal(FFinstance* instance, FFTerminalOptions* options); +void ffInitTerminalOptions(FFTerminalOptions* options); +bool ffParseTerminalCommandOptions(FFTerminalOptions* options, const char* key, const char* value); +void ffDestroyTerminalOptions(FFTerminalOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseTerminalJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/terminalfont.c b/src/modules/terminalfont.c deleted file mode 100644 index 1809c4f39..000000000 --- a/src/modules/terminalfont.c +++ /dev/null @@ -1,32 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/terminalfont/terminalfont.h" - -#define FF_TERMFONT_MODULE_NAME "Terminal Font" -#define FF_TERMFONT_NUM_FORMAT_ARGS 4 - -void ffPrintTerminalFont(FFinstance* instance) -{ - const FFTerminalFontResult* terminalFont = ffDetectTerminalFont(instance); - - if(terminalFont->error.length > 0) - { - ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont, "%s", terminalFont->error.chars); - return; - } - - if(instance->config.terminalFont.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont.key); - ffStrbufPutTo(&terminalFont->font.pretty, stdout); - } - else - { - ffPrintFormat(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.terminalFont, FF_TERMFONT_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &terminalFont->font.pretty}, - {FF_FORMAT_ARG_TYPE_STRBUF, &terminalFont->font.name}, - {FF_FORMAT_ARG_TYPE_STRBUF, &terminalFont->font.size}, - {FF_FORMAT_ARG_TYPE_LIST, &terminalFont->font.styles} - }); - } -} diff --git a/src/modules/terminalfont/option.h b/src/modules/terminalfont/option.h new file mode 100644 index 000000000..ba62efbb5 --- /dev/null +++ b/src/modules/terminalfont/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFTerminalFontOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFTerminalFontOptions; diff --git a/src/modules/terminalfont/terminalfont.c b/src/modules/terminalfont/terminalfont.c new file mode 100644 index 000000000..afeb46919 --- /dev/null +++ b/src/modules/terminalfont/terminalfont.c @@ -0,0 +1,75 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/terminalfont/terminalfont.h" +#include "modules/terminalfont/terminalfont.h" + +#define FF_TERMINALFONT_DISPLAY_NAME "Terminal Font" +#define FF_TERMINALFONT_NUM_FORMAT_ARGS 4 + +void ffPrintTerminalFont(FFinstance* instance, FFTerminalFontOptions* options) +{ + const FFTerminalFontResult* terminalFont = ffDetectTerminalFont(instance); + + if(terminalFont->error.length > 0) + { + ffPrintError(instance, FF_TERMINALFONT_DISPLAY_NAME, 0, &options->moduleArgs, "%s", terminalFont->error.chars); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_TERMINALFONT_DISPLAY_NAME, 0, &options->moduleArgs.key); + ffStrbufPutTo(&terminalFont->font.pretty, stdout); + } + else + { + ffPrintFormat(instance, FF_TERMINALFONT_DISPLAY_NAME, 0, &options->moduleArgs, FF_TERMINALFONT_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &terminalFont->font.pretty}, + {FF_FORMAT_ARG_TYPE_STRBUF, &terminalFont->font.name}, + {FF_FORMAT_ARG_TYPE_STRBUF, &terminalFont->font.size}, + {FF_FORMAT_ARG_TYPE_LIST, &terminalFont->font.styles} + }); + } +} + +void ffInitTerminalFontOptions(FFTerminalFontOptions* options) +{ + options->moduleName = FF_TERMINALFONT_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseTerminalFontCommandOptions(FFTerminalFontOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_TERMINALFONT_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyTerminalFontOptions(FFTerminalFontOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseTerminalFontJsonObject(FFinstance* instance, json_object* module) +{ + FFTerminalFontOptions __attribute__((__cleanup__(ffDestroyTerminalFontOptions))) options; + ffInitTerminalFontOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_TERMINALFONT_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintTerminalFont(instance, &options); +} +#endif diff --git a/src/modules/terminalfont/terminalfont.h b/src/modules/terminalfont/terminalfont.h new file mode 100644 index 000000000..336732917 --- /dev/null +++ b/src/modules/terminalfont/terminalfont.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_TERMINALFONT_MODULE_NAME "TerminalFont" + +void ffPrintTerminalFont(FFinstance* instance, FFTerminalFontOptions* options); +void ffInitTerminalFontOptions(FFTerminalFontOptions* options); +bool ffParseTerminalFontCommandOptions(FFTerminalFontOptions* options, const char* key, const char* value); +void ffDestroyTerminalFontOptions(FFTerminalFontOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseTerminalFontJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/theme.c b/src/modules/theme.c deleted file mode 100644 index b89f093d4..000000000 --- a/src/modules/theme.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/theme/theme.h" - -#define FF_THEME_MODULE_NAME "Theme" -#define FF_THEME_NUM_FORMAT_ARGS 1 - -void ffPrintTheme(FFinstance* instance) -{ - FF_STRBUF_AUTO_DESTROY theme; - ffStrbufInit(&theme); - const char* error = ffDetectTheme(instance, &theme); - if (error) - { - ffPrintError(instance, FF_THEME_MODULE_NAME, 0, &instance->config.theme, "%s", error); - return; - } - - if(instance->config.theme.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_THEME_MODULE_NAME, 0, &instance->config.theme.key); - ffStrbufPutTo(&theme, stdout); - } - else - { - ffPrintFormat(instance, FF_THEME_MODULE_NAME, 0, &instance->config.theme, FF_THEME_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &theme} - }); - } -} diff --git a/src/modules/theme/option.h b/src/modules/theme/option.h new file mode 100644 index 000000000..f322c3a62 --- /dev/null +++ b/src/modules/theme/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFThemeOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFThemeOptions; diff --git a/src/modules/theme/theme.c b/src/modules/theme/theme.c new file mode 100644 index 000000000..bb348e10e --- /dev/null +++ b/src/modules/theme/theme.c @@ -0,0 +1,72 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/theme/theme.h" +#include "modules/theme/theme.h" + +#define FF_THEME_NUM_FORMAT_ARGS 1 + +void ffPrintTheme(FFinstance* instance, FFThemeOptions* options) +{ + FF_STRBUF_AUTO_DESTROY theme = ffStrbufCreate(); + const char* error = ffDetectTheme(instance, &theme); + + if(error) + { + ffPrintError(instance, FF_THEME_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_THEME_MODULE_NAME, 0, &options->moduleArgs.key); + ffStrbufPutTo(&theme, stdout); + } + else + { + ffPrintFormat(instance, FF_THEME_MODULE_NAME, 0, &options->moduleArgs, FF_THEME_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &theme} + }); + } +} + +void ffInitThemeOptions(FFThemeOptions* options) +{ + options->moduleName = FF_THEME_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseThemeCommandOptions(FFThemeOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_THEME_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyThemeOptions(FFThemeOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseThemeJsonObject(FFinstance* instance, json_object* module) +{ + FFThemeOptions __attribute__((__cleanup__(ffDestroyThemeOptions))) options; + ffInitThemeOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_THEME_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintTheme(instance, &options); +} +#endif diff --git a/src/modules/theme/theme.h b/src/modules/theme/theme.h new file mode 100644 index 000000000..3c13ca467 --- /dev/null +++ b/src/modules/theme/theme.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_THEME_MODULE_NAME "Theme" + +void ffPrintTheme(FFinstance* instance, FFThemeOptions* options); +void ffInitThemeOptions(FFThemeOptions* options); +bool ffParseThemeCommandOptions(FFThemeOptions* options, const char* key, const char* value); +void ffDestroyThemeOptions(FFThemeOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseThemeJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/time.c b/src/modules/time.c deleted file mode 100644 index 523e4fa19..000000000 --- a/src/modules/time.c +++ /dev/null @@ -1,20 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/datetime/datetime.h" - -#define FF_TIME_MODULE_NAME "Time" - -void ffPrintTime(FFinstance* instance) -{ - if(instance->config.time.outputFormat.length > 0) - { - ffPrintDateTimeFormat(instance, FF_TIME_MODULE_NAME, &instance->config.time); - return; - } - - const FFDateTimeResult* datetime = ffDetectDateTime(instance); - ffPrintLogoAndKey(instance, FF_TIME_MODULE_NAME, 0, &instance->config.time.key); - - //hh:mm:ss - printf("%s:%s:%s\n", datetime->hourPretty.chars, datetime->minutePretty.chars, datetime->secondPretty.chars); -} diff --git a/src/modules/title.c b/src/modules/title.c deleted file mode 100644 index 4e509fbe5..000000000 --- a/src/modules/title.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "util/textModifier.h" - -static inline void printTitlePart(FFinstance* instance, const FFstrbuf* content) -{ - if(!instance->config.pipe) - { - fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout); - ffPrintColor(&instance->config.colorTitle); - } - - ffStrbufWriteTo(content, stdout); - - if(!instance->config.pipe) - fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout); -} - -void ffPrintTitle(FFinstance* instance) -{ - ffLogoPrintLine(instance); - - printTitlePart(instance, &instance->state.platform.userName); - putchar('@'); - printTitlePart(instance, instance->config.titleFQDN ? - &instance->state.platform.domainName : - &instance->state.platform.hostName - ); - putchar('\n'); -} diff --git a/src/modules/title/option.h b/src/modules/title/option.h new file mode 100644 index 000000000..1faa59ea4 --- /dev/null +++ b/src/modules/title/option.h @@ -0,0 +1,12 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFTitleOptions +{ + const char* moduleName; + + bool fdqn; +} FFTitleOptions; diff --git a/src/modules/title/title.c b/src/modules/title/title.c new file mode 100644 index 000000000..fcdcdd3a1 --- /dev/null +++ b/src/modules/title/title.c @@ -0,0 +1,83 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "util/textModifier.h" +#include "modules/title/title.h" + +static inline void printTitlePart(FFinstance* instance, const FFstrbuf* content) +{ + if(!instance->config.pipe) + { + fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout); + ffPrintColor(&instance->config.colorTitle); + } + + ffStrbufWriteTo(content, stdout); + + if(!instance->config.pipe) + fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout); +} + +void ffPrintTitle(FFinstance* instance, FFTitleOptions* options) +{ + ffLogoPrintLine(instance); + + printTitlePart(instance, &instance->state.platform.userName); + putchar('@'); + FFstrbuf* host = options->fdqn ? + &instance->state.platform.domainName : + &instance->state.platform.hostName; + printTitlePart(instance, host); + + instance->state.titleLength = instance->state.platform.userName.length + host->length + 1; + + putchar('\n'); +} + +void ffInitTitleOptions(FFTitleOptions* options) +{ + options->moduleName = FF_TITLE_MODULE_NAME; + options->fdqn = false; +} + +bool ffParseTitleCommandOptions(FFTitleOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_TITLE_MODULE_NAME); + if (!subKey) return false; + + if (strcasecmp(subKey, "fdqn") == 0) + { + options->fdqn = ffOptionParseBoolean(value); + return true; + } + + return false; +} + +void ffDestroyTitleOptions(FFTitleOptions* options) +{ + FF_UNUSED(options); +} + +#ifdef FF_HAVE_JSONC +void ffParseTitleJsonObject(FFinstance* instance, json_object* module) +{ + FFTitleOptions __attribute__((__cleanup__(ffDestroyTitleOptions))) options; + ffInitTitleOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (strcasecmp(key, "fdqn") == 0) + { + options.fdqn = json_object_get_boolean(val); + continue; + } + + ffPrintErrorString(instance, FF_TITLE_MODULE_NAME, 0, NULL, NULL, "Unknown JSON key %s", key); + } + } + + ffPrintTitle(instance, &options); +} +#endif diff --git a/src/modules/title/title.h b/src/modules/title/title.h new file mode 100644 index 000000000..ab6e07eae --- /dev/null +++ b/src/modules/title/title.h @@ -0,0 +1,16 @@ +#pragma once + +#include "fastfetch.h" +#include "modules/title/option.h" + +#define FF_TITLE_MODULE_NAME "Title" + +void ffPrintTitle(FFinstance* instance, FFTitleOptions* options); +void ffInitTitleOptions(FFTitleOptions* options); +bool ffParseTitleCommandOptions(FFTitleOptions* options, const char* key, const char* value); +void ffDestroyTitleOptions(FFTitleOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseTitleJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/uptime.c b/src/modules/uptime.c deleted file mode 100644 index 48d2b4f4a..000000000 --- a/src/modules/uptime.c +++ /dev/null @@ -1,77 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/uptime/uptime.h" - -#define FF_UPTIME_MODULE_NAME "Uptime" -#define FF_UPTIME_NUM_FORMAT_ARGS 4 - -void ffPrintUptime(FFinstance* instance) -{ - uint64_t uptime = ffDetectUptime(); - - if(uptime == 0) - { - ffPrintError(instance, FF_UPTIME_MODULE_NAME, 0, &instance->config.uptime, "Uptime could't be detected"); - return; - } - - uint32_t days = (uint32_t) uptime / 86400; - uint32_t hours = (uint32_t) (uptime - (days * 86400)) / 3600; - uint32_t minutes = (uint32_t) (uptime - (days * 86400) - (hours * 3600)) / 60; - uint32_t seconds = (uint32_t) uptime - (days * 86400) - (hours * 3600) - (minutes * 60); - - if(instance->config.uptime.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_UPTIME_MODULE_NAME, 0, &instance->config.uptime.key); - - if(days == 0 && hours == 0 && minutes == 0) - { - printf("%u seconds\n", seconds); - return; - } - - if(days > 0) - { - printf("%u day", days); - - if(days > 1) - putchar('s'); - - if(days >= 100) - fputs("(!)", stdout); - - if(hours > 0 || minutes > 0) - fputs(", ", stdout); - } - - if(hours > 0) - { - printf("%u hour", hours); - - if(hours > 1) - putchar('s'); - - if(minutes > 0) - fputs(", ", stdout); - } - - if(minutes > 0) - { - printf("%u min", minutes); - - if(minutes > 1) - putchar('s'); - } - - putchar('\n'); - } - else - { - ffPrintFormat(instance, FF_UPTIME_MODULE_NAME, 0, &instance->config.uptime, 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/uptime/option.h b/src/modules/uptime/option.h new file mode 100644 index 000000000..722d236d3 --- /dev/null +++ b/src/modules/uptime/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFUptimeOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFUptimeOptions; diff --git a/src/modules/uptime/uptime.c b/src/modules/uptime/uptime.c new file mode 100644 index 000000000..f7fd7959c --- /dev/null +++ b/src/modules/uptime/uptime.c @@ -0,0 +1,121 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/uptime/uptime.h" +#include "modules/uptime/uptime.h" + +#define FF_UPTIME_NUM_FORMAT_ARGS 4 + +void ffPrintUptime(FFinstance* instance, FFUptimeOptions* options) +{ + uint64_t uptime; + + const char* error = ffDetectUptime(&uptime); + + if(error) + { + ffPrintError(instance, FF_UPTIME_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + uint32_t days = (uint32_t) uptime / 86400; + uint32_t hours = (uint32_t) (uptime - (days * 86400)) / 3600; + uint32_t minutes = (uint32_t) (uptime - (days * 86400) - (hours * 3600)) / 60; + uint32_t seconds = (uint32_t) uptime - (days * 86400) - (hours * 3600) - (minutes * 60); + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_UPTIME_MODULE_NAME, 0, &options->moduleArgs.key); + + if(days == 0 && hours == 0 && minutes == 0) + { + printf("%u seconds\n", seconds); + return; + } + + if(days > 0) + { + printf("%u day", days); + + if(days > 1) + putchar('s'); + + if(days >= 100) + fputs("(!)", stdout); + + if(hours > 0 || minutes > 0) + fputs(", ", stdout); + } + + if(hours > 0) + { + printf("%u hour", hours); + + if(hours > 1) + putchar('s'); + + if(minutes > 0) + fputs(", ", stdout); + } + + if(minutes > 0) + { + printf("%u min", minutes); + + if(minutes > 1) + putchar('s'); + } + + putchar('\n'); + } + else + { + ffPrintFormat(instance, FF_UPTIME_MODULE_NAME, 0, &options->moduleArgs, 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} + }); + } +} + +void ffInitUptimeOptions(FFUptimeOptions* options) +{ + options->moduleName = FF_UPTIME_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseUptimeCommandOptions(FFUptimeOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_UPTIME_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyUptimeOptions(FFUptimeOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseUptimeJsonObject(FFinstance* instance, json_object* module) +{ + FFUptimeOptions __attribute__((__cleanup__(ffDestroyUptimeOptions))) options; + ffInitUptimeOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_UPTIME_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintUptime(instance, &options); +} +#endif diff --git a/src/modules/uptime/uptime.h b/src/modules/uptime/uptime.h new file mode 100644 index 000000000..35cc0365a --- /dev/null +++ b/src/modules/uptime/uptime.h @@ -0,0 +1,16 @@ +#pragma once + +#include "fastfetch.h" +#include "modules/title/option.h" + +#define FF_UPTIME_MODULE_NAME "Uptime" + +void ffPrintUptime(FFinstance* instance, FFUptimeOptions* options); +void ffInitUptimeOptions(FFUptimeOptions* options); +bool ffParseUptimeCommandOptions(FFUptimeOptions* options, const char* key, const char* value); +void ffDestroyUptimeOptions(FFUptimeOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseUptimeJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/users.c b/src/modules/users.c deleted file mode 100644 index 1c78571b2..000000000 --- a/src/modules/users.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/users/users.h" - -#define FF_USERS_MODULE_NAME "Users" -#define FF_USERS_NUM_FORMAT_ARGS 1 - -void ffPrintUsers(FFinstance* instance) -{ - FFlist users; - ffListInit(&users, sizeof(FFstrbuf)); - - FFstrbuf error; - ffStrbufInit(&error); - - ffDetectUsers(&users, &error); - - if(error.length > 0) - { - ffPrintError(instance, FF_USERS_MODULE_NAME, 0, &instance->config.users, "%*s", error.length, error.chars); - ffListDestroy(&users); - ffStrbufDestroy(&error); - return; - } - - FFstrbuf result; - ffStrbufInit(&result); - for(uint32_t i = 0; i < users.length; ++i) - { - if(i > 0) - ffStrbufAppendS(&result, ", "); - FFstrbuf* user = (FFstrbuf*)ffListGet(&users, i); - ffStrbufAppend(&result, user); - ffStrbufDestroy(user); - } - - ffListDestroy(&users); - - if(instance->config.users.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_USERS_MODULE_NAME, 0, &instance->config.users.key); - puts(result.chars); - } - else - { - ffPrintFormat(instance, FF_USERS_MODULE_NAME, 0, &instance->config.users, FF_USERS_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &result}, - }); - } - - ffStrbufDestroy(&result); -} diff --git a/src/modules/users/option.h b/src/modules/users/option.h new file mode 100644 index 000000000..f7f0b099e --- /dev/null +++ b/src/modules/users/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFUsersOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFUsersOptions; diff --git a/src/modules/users/users.c b/src/modules/users/users.c new file mode 100644 index 000000000..82698d6a8 --- /dev/null +++ b/src/modules/users/users.c @@ -0,0 +1,85 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/users/users.h" +#include "modules/users/users.h" + +#define FF_USERS_NUM_FORMAT_ARGS 1 + +void ffPrintUsers(FFinstance* instance, FFUsersOptions* options) +{ + FF_LIST_AUTO_DESTROY users = ffListCreate(sizeof(FFstrbuf)); + + FF_STRBUF_AUTO_DESTROY error = ffStrbufCreate(); + + ffDetectUsers(&users, &error); + + if(error.length > 0) + { + ffPrintError(instance, FF_USERS_MODULE_NAME, 0, &options->moduleArgs, "%*s", error.length, error.chars); + return; + } + + FF_STRBUF_AUTO_DESTROY result = ffStrbufCreate(); + for(uint32_t i = 0; i < users.length; ++i) + { + if(i > 0) + ffStrbufAppendS(&result, ", "); + FFstrbuf* user = (FFstrbuf*)ffListGet(&users, i); + ffStrbufAppend(&result, user); + ffStrbufDestroy(user); + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_USERS_MODULE_NAME, 0, &options->moduleArgs.key); + puts(result.chars); + } + else + { + ffPrintFormat(instance, FF_USERS_MODULE_NAME, 0, &options->moduleArgs, FF_USERS_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &result}, + }); + } +} + +void ffInitUsersOptions(FFUsersOptions* options) +{ + options->moduleName = FF_USERS_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseUsersCommandOptions(FFUsersOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_USERS_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyUsersOptions(FFUsersOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseUsersJsonObject(FFinstance* instance, json_object* module) +{ + FFUsersOptions __attribute__((__cleanup__(ffDestroyUsersOptions))) options; + ffInitUsersOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_USERS_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintUsers(instance, &options); +} +#endif diff --git a/src/modules/users/users.h b/src/modules/users/users.h new file mode 100644 index 000000000..233391f17 --- /dev/null +++ b/src/modules/users/users.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_USERS_MODULE_NAME "Users" + +void ffPrintUsers(FFinstance* instance, FFUsersOptions* options); +void ffInitUsersOptions(FFUsersOptions* options); +bool ffParseUsersCommandOptions(FFUsersOptions* options, const char* key, const char* value); +void ffDestroyUsersOptions(FFUsersOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseUsersJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/vulkan.c b/src/modules/vulkan.c deleted file mode 100644 index 23c6f60df..000000000 --- a/src/modules/vulkan.c +++ /dev/null @@ -1,43 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/vulkan/vulkan.h" - -#define FF_VULKAN_MODULE_NAME "Vulkan" -#define FF_VULKAN_NUM_FORMAT_ARGS 3 - -void ffPrintVulkan(FFinstance* instance) -{ - const FFVulkanResult* vulkan = ffDetectVulkan(instance); - - if(vulkan->error) - { - ffPrintError(instance, FF_VULKAN_MODULE_NAME, 0, &instance->config.vulkan, "%s", vulkan->error); - return; - } - - if(instance->config.vulkan.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_VULKAN_MODULE_NAME, 0, &instance->config.vulkan.key); - - if(vulkan->apiVersion.length > 0) - { - ffStrbufWriteTo(&vulkan->apiVersion, stdout); - - if(vulkan->driver.length > 0) - fputs(" - ", stdout); - } - - if(vulkan->driver.length > 0) - ffStrbufWriteTo(&vulkan->driver, stdout); - - putchar('\n'); - } - else - { - ffPrintFormat(instance, FF_VULKAN_MODULE_NAME, 0, &instance->config.vulkan, FF_VULKAN_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &vulkan->driver}, - {FF_FORMAT_ARG_TYPE_STRBUF, &vulkan->apiVersion}, - {FF_FORMAT_ARG_TYPE_STRBUF, &vulkan->conformanceVersion} - }); - } -} diff --git a/src/modules/vulkan/option.h b/src/modules/vulkan/option.h new file mode 100644 index 000000000..c5efd077b --- /dev/null +++ b/src/modules/vulkan/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFVulkanOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFVulkanOptions; diff --git a/src/modules/vulkan/vulkan.c b/src/modules/vulkan/vulkan.c new file mode 100644 index 000000000..a33c40553 --- /dev/null +++ b/src/modules/vulkan/vulkan.c @@ -0,0 +1,85 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/vulkan/vulkan.h" +#include "modules/vulkan/vulkan.h" + +#define FF_VULKAN_NUM_FORMAT_ARGS 3 + +void ffPrintVulkan(FFinstance* instance, FFVulkanOptions* options) +{ + const FFVulkanResult* vulkan = ffDetectVulkan(instance); + + if(vulkan->error) + { + ffPrintError(instance, FF_VULKAN_MODULE_NAME, 0, &options->moduleArgs, "%s", vulkan->error); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_VULKAN_MODULE_NAME, 0, &options->moduleArgs.key); + + if(vulkan->apiVersion.length > 0) + { + ffStrbufWriteTo(&vulkan->apiVersion, stdout); + + if(vulkan->driver.length > 0) + fputs(" - ", stdout); + } + + if(vulkan->driver.length > 0) + ffStrbufWriteTo(&vulkan->driver, stdout); + + putchar('\n'); + } + else + { + ffPrintFormat(instance, FF_VULKAN_MODULE_NAME, 0, &options->moduleArgs, FF_VULKAN_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &vulkan->driver}, + {FF_FORMAT_ARG_TYPE_STRBUF, &vulkan->apiVersion}, + {FF_FORMAT_ARG_TYPE_STRBUF, &vulkan->conformanceVersion} + }); + } +} + +void ffInitVulkanOptions(FFVulkanOptions* options) +{ + options->moduleName = FF_VULKAN_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseVulkanCommandOptions(FFVulkanOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_VULKAN_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyVulkanOptions(FFVulkanOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseVulkanJsonObject(FFinstance* instance, json_object* module) +{ + FFVulkanOptions __attribute__((__cleanup__(ffDestroyVulkanOptions))) options; + ffInitVulkanOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_VULKAN_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintVulkan(instance, &options); +} +#endif diff --git a/src/modules/vulkan/vulkan.h b/src/modules/vulkan/vulkan.h new file mode 100644 index 000000000..04145d678 --- /dev/null +++ b/src/modules/vulkan/vulkan.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_VULKAN_MODULE_NAME "Vulkan" + +void ffPrintVulkan(FFinstance* instance, FFVulkanOptions* options); +void ffInitVulkanOptions(FFVulkanOptions* options); +bool ffParseVulkanCommandOptions(FFVulkanOptions* options, const char* key, const char* value); +void ffDestroyVulkanOptions(FFVulkanOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseVulkanJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/wallpaper.c b/src/modules/wallpaper.c deleted file mode 100644 index 75caa5471..000000000 --- a/src/modules/wallpaper.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/wallpaper/wallpaper.h" - -#define FF_WALLPAPER_MODULE_NAME "Wallpaper" -#define FF_WALLPAPER_NUM_FORMAT_ARGS 1 - -void ffPrintWallpaper(FFinstance* instance) -{ - FF_STRBUF_AUTO_DESTROY wallpaper; - ffStrbufInit(&wallpaper); - const char* error = ffDetectWallpaper(instance, &wallpaper); - - if(error) - { - ffPrintError(instance, FF_WALLPAPER_MODULE_NAME, 0, &instance->config.wallpaper, "%s", error); - return; - } - - if(instance->config.wallpaper.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_WALLPAPER_MODULE_NAME, 0, &instance->config.wallpaper.key); - ffStrbufPutTo(&wallpaper, stdout); - } - else - { - ffPrintFormat(instance, FF_WALLPAPER_MODULE_NAME, 0, &instance->config.wallpaper, FF_WALLPAPER_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &wallpaper} - }); - } -} diff --git a/src/modules/wallpaper/option.h b/src/modules/wallpaper/option.h new file mode 100644 index 000000000..ff7aa55fe --- /dev/null +++ b/src/modules/wallpaper/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFWallpaperOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFWallpaperOptions; diff --git a/src/modules/wallpaper/wallpaper.c b/src/modules/wallpaper/wallpaper.c new file mode 100644 index 000000000..aeff9eb30 --- /dev/null +++ b/src/modules/wallpaper/wallpaper.c @@ -0,0 +1,72 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/wallpaper/wallpaper.h" +#include "modules/wallpaper/wallpaper.h" + +#define FF_WALLPAPER_NUM_FORMAT_ARGS 1 + +void ffPrintWallpaper(FFinstance* instance, FFWallpaperOptions* options) +{ + FF_STRBUF_AUTO_DESTROY wallpaper = ffStrbufCreate(); + const char* error = ffDetectWallpaper(instance, &wallpaper); + + if(error) + { + ffPrintError(instance, FF_WALLPAPER_MODULE_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_WALLPAPER_MODULE_NAME, 0, &options->moduleArgs.key); + ffStrbufPutTo(&wallpaper, stdout); + } + else + { + ffPrintFormat(instance, FF_WALLPAPER_MODULE_NAME, 0, &options->moduleArgs, FF_WALLPAPER_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &wallpaper} + }); + } +} + +void ffInitWallpaperOptions(FFWallpaperOptions* options) +{ + options->moduleName = FF_WALLPAPER_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseWallpaperCommandOptions(FFWallpaperOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_WALLPAPER_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyWallpaperOptions(FFWallpaperOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseWallpaperJsonObject(FFinstance* instance, json_object* module) +{ + FFWallpaperOptions __attribute__((__cleanup__(ffDestroyWallpaperOptions))) options; + ffInitWallpaperOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_WALLPAPER_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintWallpaper(instance, &options); +} +#endif diff --git a/src/modules/wallpaper/wallpaper.h b/src/modules/wallpaper/wallpaper.h new file mode 100644 index 000000000..efb0f17c0 --- /dev/null +++ b/src/modules/wallpaper/wallpaper.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_WALLPAPER_MODULE_NAME "Wallpaper" + +void ffPrintWallpaper(FFinstance* instance, FFWallpaperOptions* options); +void ffInitWallpaperOptions(FFWallpaperOptions* options); +bool ffParseWallpaperCommandOptions(FFWallpaperOptions* options, const char* key, const char* value); +void ffDestroyWallpaperOptions(FFWallpaperOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseWallpaperJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/weather.c b/src/modules/weather.c deleted file mode 100644 index a6bc63ce9..000000000 --- a/src/modules/weather.c +++ /dev/null @@ -1,56 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "common/networking.h" - -#define FF_WEATHER_MODULE_NAME "Weather" -#define FF_WEATHER_NUM_FORMAT_ARGS 1 - -static FFNetworkingState state; -static int status = -1; - -void ffPrepareWeather(FFinstance* instance) -{ - FFstrbuf path; - ffStrbufInitS(&path, "/?format="); - ffStrbufAppend(&path, &instance->config.weatherOutputFormat); - status = ffNetworkingSendHttpRequest(&state, "wttr.in", path.chars, "User-Agent: curl/0.0.0\r\n"); - ffStrbufDestroy(&path); -} - -void ffPrintWeather(FFinstance* instance) -{ - if(status == -1) - ffPrepareWeather(instance); - - if(status == 0) - { - ffPrintError(instance, FF_WEATHER_MODULE_NAME, 0, &instance->config.weather, "Failed to connect to 'wttr.in'"); - return; - } - - FFstrbuf result; - ffStrbufInitA(&result, 4096); - bool success = ffNetworkingRecvHttpResponse(&state, &result, instance->config.weatherTimeout); - if (success) ffStrbufSubstrAfterFirstS(&result, "\r\n\r\n"); - - if(!success || result.length == 0) - { - ffPrintError(instance, FF_WEATHER_MODULE_NAME, 0, &instance->config.weather, "Failed to receive the server response"); - ffStrbufDestroy(&result); - return; - } - - if(instance->config.weather.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_WEATHER_MODULE_NAME, 0, &instance->config.weather.key); - ffStrbufPutTo(&result, stdout); - } - else - { - ffPrintFormat(instance, FF_WEATHER_MODULE_NAME, 0, &instance->config.weather, FF_WEATHER_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &result} - }); - } - - ffStrbufDestroy(&result); -} diff --git a/src/modules/weather/option.h b/src/modules/weather/option.h new file mode 100644 index 000000000..d481fb6b7 --- /dev/null +++ b/src/modules/weather/option.h @@ -0,0 +1,14 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFWeatherOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + FFstrbuf outputFormat; + uint32_t timeout; +} FFWeatherOptions; diff --git a/src/modules/weather/weather.c b/src/modules/weather/weather.c new file mode 100644 index 000000000..579cdf1cb --- /dev/null +++ b/src/modules/weather/weather.c @@ -0,0 +1,122 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "common/networking.h" +#include "modules/weather/weather.h" + +#define FF_WEATHER_MODULE_NAME "Weather" +#define FF_WEATHER_NUM_FORMAT_ARGS 1 + +static FFNetworkingState state; +static int status = -1; + +void ffPrepareWeather(FFWeatherOptions* options) +{ + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateS("/?format="); + ffStrbufAppend(&path, &options->outputFormat); + status = ffNetworkingSendHttpRequest(&state, "wttr.in", path.chars, "User-Agent: curl/0.0.0\r\n"); +} + +void ffPrintWeather(FFinstance* instance, FFWeatherOptions* options) +{ + if(status == -1) + ffPrepareWeather(options); + + if(status == 0) + { + ffPrintError(instance, FF_WEATHER_MODULE_NAME, 0, &options->moduleArgs, "Failed to connect to 'wttr.in'"); + return; + } + + FF_STRBUF_AUTO_DESTROY result = ffStrbufCreateA(4096); + bool success = ffNetworkingRecvHttpResponse(&state, &result, options->timeout); + if (success) ffStrbufSubstrAfterFirstS(&result, "\r\n\r\n"); + + if(!success || result.length == 0) + { + ffPrintError(instance, FF_WEATHER_MODULE_NAME, 0, &options->moduleArgs, "Failed to receive the server response"); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_WEATHER_MODULE_NAME, 0, &options->moduleArgs.key); + ffStrbufPutTo(&result, stdout); + } + else + { + ffPrintFormat(instance, FF_WEATHER_MODULE_NAME, 0, &options->moduleArgs, FF_WEATHER_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &result} + }); + } +} + +void ffInitWeatherOptions(FFWeatherOptions* options) +{ + options->moduleName = FF_WEATHER_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + + ffStrbufInitS(&options->outputFormat, "%t+-+%C+(%l)"); + options->timeout = 0; +} + +bool ffParseWeatherCommandOptions(FFWeatherOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_WEATHER_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (strcasecmp(subKey, "output-format") == 0) + { + ffOptionParseString(key, value, &options->outputFormat); + return true; + } + + if (strcasecmp(subKey, "timeout") == 0) + { + options->timeout = ffOptionParseUInt32(key, value); + return true; + } + + return false; +} + +void ffDestroyWeatherOptions(FFWeatherOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); + + ffStrbufDestroy(&options->outputFormat); +} + +#ifdef FF_HAVE_JSONC +void ffParseWeatherJsonObject(FFinstance* instance, json_object* module) +{ + FFWeatherOptions __attribute__((__cleanup__(ffDestroyWeatherOptions))) options; + ffInitWeatherOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + if (strcasecmp(key, "outputFormat") == 0) + { + ffStrbufSetS(&options.outputFormat, json_object_get_string(val)); + continue; + } + + if (strcasecmp(key, "timeout") == 0) + { + options.timeout = (uint32_t) json_object_get_int(val); + continue; + } + + ffPrintError(instance, FF_WEATHER_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintWeather(instance, &options); +} +#endif diff --git a/src/modules/weather/weather.h b/src/modules/weather/weather.h new file mode 100644 index 000000000..476a1586d --- /dev/null +++ b/src/modules/weather/weather.h @@ -0,0 +1,17 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_WEATHER_MODULE_NAME "Weather" + +void ffPrepareWeather(FFWeatherOptions* options); + +void ffPrintWeather(FFinstance* instance, FFWeatherOptions* options); +void ffInitWeatherOptions(FFWeatherOptions* options); +bool ffParseWeatherCommandOptions(FFWeatherOptions* options, const char* key, const char* value); +void ffDestroyWeatherOptions(FFWeatherOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseWeatherJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/wifi/option.h b/src/modules/wifi/option.h new file mode 100644 index 000000000..4d713b5d8 --- /dev/null +++ b/src/modules/wifi/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFWifiOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFWifiOptions; diff --git a/src/modules/wifi.c b/src/modules/wifi/wifi.c similarity index 56% rename from src/modules/wifi.c rename to src/modules/wifi/wifi.c index 06c3768fc..cd35eb5f9 100644 --- a/src/modules/wifi.c +++ b/src/modules/wifi/wifi.c @@ -1,24 +1,23 @@ #include "fastfetch.h" #include "common/printing.h" #include "detection/wifi/wifi.h" +#include "modules/wifi/wifi.h" -#define FF_WIFI_MODULE_NAME "Wifi" #define FF_WIFI_NUM_FORMAT_ARGS 10 -void ffPrintWifi(FFinstance* instance) +void ffPrintWifi(FFinstance* instance, FFWifiOptions* options) { - FF_LIST_AUTO_DESTROY result; - ffListInit(&result, sizeof(FFWifiResult)); + FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFWifiResult)); const char* error = ffDetectWifi(instance, &result); if(error) { - ffPrintError(instance, FF_WIFI_MODULE_NAME, 0, &instance->config.wifi, "%s", error); + ffPrintError(instance, FF_WIFI_MODULE_NAME, 0, &options->moduleArgs, "%s", error); return; } if(!result.length) { - ffPrintError(instance, FF_WIFI_MODULE_NAME, 0, &instance->config.wifi, "No Wifi interfaces found"); + ffPrintError(instance, FF_WIFI_MODULE_NAME, 0, &options->moduleArgs, "No Wifi interfaces found"); return; } @@ -27,9 +26,9 @@ void ffPrintWifi(FFinstance* instance) FFWifiResult* item = (FFWifiResult*)ffListGet(&result, index); uint8_t moduleIndex = result.length == 1 ? 0 : (uint8_t)(index + 1); - if(instance->config.wifi.outputFormat.length == 0) + if(options->moduleArgs.outputFormat.length == 0) { - ffPrintLogoAndKey(instance, FF_WIFI_MODULE_NAME, moduleIndex, &instance->config.wifi.key); + ffPrintLogoAndKey(instance, FF_WIFI_MODULE_NAME, moduleIndex, &options->moduleArgs.key); if(item->conn.ssid.length) { ffStrbufWriteTo(&item->conn.ssid, stdout); @@ -46,7 +45,7 @@ void ffPrintWifi(FFinstance* instance) } else { - ffPrintFormat(instance, FF_WIFI_MODULE_NAME, moduleIndex, &instance->config.wifi, FF_WIFI_NUM_FORMAT_ARGS, (FFformatarg[]){ + ffPrintFormat(instance, FF_WIFI_MODULE_NAME, moduleIndex, &options->moduleArgs, FF_WIFI_NUM_FORMAT_ARGS, (FFformatarg[]){ {FF_FORMAT_ARG_TYPE_STRBUF, &item->inf.description}, {FF_FORMAT_ARG_TYPE_STRBUF, &item->inf.status}, {FF_FORMAT_ARG_TYPE_STRBUF, &item->conn.status}, @@ -69,3 +68,45 @@ void ffPrintWifi(FFinstance* instance) ffStrbufDestroy(&item->conn.security); } } + +void ffInitWifiOptions(FFWifiOptions* options) +{ + options->moduleName = FF_WIFI_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseWifiCommandOptions(FFWifiOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_WIFI_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyWifiOptions(FFWifiOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseWifiJsonObject(FFinstance* instance, json_object* module) +{ + FFWifiOptions __attribute__((__cleanup__(ffDestroyWifiOptions))) options; + ffInitWifiOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_WIFI_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintWifi(instance, &options); +} +#endif diff --git a/src/modules/wifi/wifi.h b/src/modules/wifi/wifi.h new file mode 100644 index 000000000..bb6aa1884 --- /dev/null +++ b/src/modules/wifi/wifi.h @@ -0,0 +1,16 @@ +#pragma once + +#include "fastfetch.h" +#include "modules/wifi/option.h" + +#define FF_WIFI_MODULE_NAME "Wifi" + +void ffPrintWifi(FFinstance* instance, FFWifiOptions* options); +void ffInitWifiOptions(FFWifiOptions* options); +bool ffParseWifiCommandOptions(FFWifiOptions* options, const char* key, const char* value); +void ffDestroyWifiOptions(FFWifiOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseWifiJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/wm.c b/src/modules/wm.c deleted file mode 100644 index 38cf9f5a3..000000000 --- a/src/modules/wm.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/displayserver/displayserver.h" - -#define FF_WM_MODULE_NAME "WM" -#define FF_WM_NUM_FORMAT_ARGS 3 - -void ffPrintWM(FFinstance* instance) -{ - #ifdef __ANDROID__ - ffPrintError(instance, FF_WM_MODULE_NAME, 0, &instance->config.wm, "WM detection is not supported on Android"); - return; - #endif - - const FFDisplayServerResult* result = ffConnectDisplayServer(instance); - - if(result->wmPrettyName.length == 0) - { - ffPrintError(instance, FF_WM_MODULE_NAME, 0, &instance->config.wm, "No WM found"); - return; - } - - if(instance->config.wm.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_WM_MODULE_NAME, 0, &instance->config.wm.key); - - ffStrbufWriteTo(&result->wmPrettyName, stdout); - - if(result->wmProtocolName.length > 0) - { - fputs(" (", stdout); - ffStrbufWriteTo(&result->wmProtocolName, stdout); - putchar(')'); - } - - putchar('\n'); - } - else - { - ffPrintFormat(instance, FF_WM_MODULE_NAME, 0, &instance->config.wm, FF_WM_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &result->wmProcessName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->wmPrettyName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->wmProtocolName} - }); - } -} diff --git a/src/modules/wm/option.h b/src/modules/wm/option.h new file mode 100644 index 000000000..fcc7b0231 --- /dev/null +++ b/src/modules/wm/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFWMOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFWMOptions; diff --git a/src/modules/wm/wm.c b/src/modules/wm/wm.c new file mode 100644 index 000000000..172066fe8 --- /dev/null +++ b/src/modules/wm/wm.c @@ -0,0 +1,83 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/displayserver/displayserver.h" +#include "modules/wm/wm.h" + +#define FF_WM_NUM_FORMAT_ARGS 3 + +void ffPrintWM(FFinstance* instance, FFWMOptions* options) +{ + const FFDisplayServerResult* result = ffConnectDisplayServer(instance); + + if(result->wmPrettyName.length == 0) + { + ffPrintError(instance, FF_WM_MODULE_NAME, 0, &options->moduleArgs, "No WM found"); + return; + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_WM_MODULE_NAME, 0, &options->moduleArgs.key); + + ffStrbufWriteTo(&result->wmPrettyName, stdout); + + if(result->wmProtocolName.length > 0) + { + fputs(" (", stdout); + ffStrbufWriteTo(&result->wmProtocolName, stdout); + putchar(')'); + } + + putchar('\n'); + } + else + { + ffPrintFormat(instance, FF_WM_MODULE_NAME, 0, &options->moduleArgs, FF_WM_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &result->wmProcessName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->wmPrettyName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->wmProtocolName} + }); + } +} + +void ffInitWMOptions(FFWMOptions* options) +{ + options->moduleName = FF_WM_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseWMCommandOptions(FFWMOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_WM_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyWMOptions(FFWMOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseWMJsonObject(FFinstance* instance, json_object* module) +{ + FFWMOptions __attribute__((__cleanup__(ffDestroyWMOptions))) options; + ffInitWMOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_WM_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintWM(instance, &options); +} +#endif diff --git a/src/modules/wm/wm.h b/src/modules/wm/wm.h new file mode 100644 index 000000000..86214a3dc --- /dev/null +++ b/src/modules/wm/wm.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_WM_MODULE_NAME "WM" + +void ffPrintWM(FFinstance* instance, FFWMOptions* options); +void ffInitWMOptions(FFWMOptions* options); +bool ffParseWMCommandOptions(FFWMOptions* options, const char* key, const char* value); +void ffDestroyWMOptions(FFWMOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseWMJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/modules/wmtheme.c b/src/modules/wmtheme.c deleted file mode 100644 index 4112d8321..000000000 --- a/src/modules/wmtheme.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/wmtheme/wmtheme.h" - -#define FF_WMTHEME_MODULE_NAME "WM Theme" -#define FF_WMTHEME_NUM_FORMAT_ARGS 1 - -void ffPrintWMTheme(FFinstance* instance) -{ - FFstrbuf themeOrError; - ffStrbufInit(&themeOrError); - if(ffDetectWmTheme(instance, &themeOrError)) - { - if(instance->config.wmTheme.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_WMTHEME_MODULE_NAME, 0, &instance->config.wmTheme.key); - puts(themeOrError.chars); - } - else - { - ffPrintFormat(instance, FF_WMTHEME_MODULE_NAME, 0, &instance->config.wmTheme, FF_WMTHEME_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &themeOrError} - }); - } - } - else - { - ffPrintError(instance, FF_WMTHEME_MODULE_NAME, 0, &instance->config.wmTheme, "%*s", themeOrError.length, themeOrError.chars); - } - ffStrbufDestroy(&themeOrError); -} diff --git a/src/modules/wmtheme/option.h b/src/modules/wmtheme/option.h new file mode 100644 index 000000000..11b14458b --- /dev/null +++ b/src/modules/wmtheme/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFWMThemeOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFWMThemeOptions; diff --git a/src/modules/wmtheme/wmtheme.c b/src/modules/wmtheme/wmtheme.c new file mode 100644 index 000000000..4a2ffbcd2 --- /dev/null +++ b/src/modules/wmtheme/wmtheme.c @@ -0,0 +1,72 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/wmtheme/wmtheme.h" +#include "modules/wmtheme/wmtheme.h" + +#define FF_WMTHEME_DISPLAY_NAME "WM Theme" +#define FF_WMTHEME_NUM_FORMAT_ARGS 1 + +void ffPrintWMTheme(FFinstance* instance, FFWMThemeOptions* options) +{ + FF_STRBUF_AUTO_DESTROY themeOrError = ffStrbufCreate(); + if(ffDetectWmTheme(instance, &themeOrError)) + { + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_WMTHEME_DISPLAY_NAME, 0, &options->moduleArgs.key); + puts(themeOrError.chars); + } + else + { + ffPrintFormat(instance, FF_WMTHEME_DISPLAY_NAME, 0, &options->moduleArgs, FF_WMTHEME_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &themeOrError} + }); + } + } + else + { + ffPrintError(instance, FF_WMTHEME_DISPLAY_NAME, 0, &options->moduleArgs, "%*s", themeOrError.length, themeOrError.chars); + } +} + +void ffInitWMThemeOptions(FFWMThemeOptions* options) +{ + options->moduleName = FF_WMTHEME_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseWMThemeCommandOptions(FFWMThemeOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_WMTHEME_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyWMThemeOptions(FFWMThemeOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +void ffParseWMThemeJsonObject(FFinstance* instance, json_object* module) +{ + FFWMThemeOptions __attribute__((__cleanup__(ffDestroyWMThemeOptions))) options; + ffInitWMThemeOptions(&options); + + if (module) + { + json_object_object_foreach(module, key, val) + { + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(instance, FF_WMTHEME_DISPLAY_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintWMTheme(instance, &options); +} +#endif diff --git a/src/modules/wmtheme/wmtheme.h b/src/modules/wmtheme/wmtheme.h new file mode 100644 index 000000000..c1f95312d --- /dev/null +++ b/src/modules/wmtheme/wmtheme.h @@ -0,0 +1,16 @@ +#pragma once + +#include "fastfetch.h" +#include "modules/wmtheme/option.h" + +#define FF_WMTHEME_MODULE_NAME "WMTheme" + +void ffPrintWMTheme(FFinstance* instance, FFWMThemeOptions* options); +void ffInitWMThemeOptions(FFWMThemeOptions* options); +bool ffParseWMThemeCommandOptions(FFWMThemeOptions* options, const char* key, const char* value); +void ffDestroyWMThemeOptions(FFWMThemeOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/jsonconfig.h" +void ffParseWMThemeJsonObject(FFinstance* instance, json_object* module); +#endif diff --git a/src/util/FFlist.c b/src/util/FFlist.c index bd643014a..59f5a8b56 100644 --- a/src/util/FFlist.c +++ b/src/util/FFlist.c @@ -55,11 +55,3 @@ bool ffListPop(FFlist* list, void* result) --list->length; return result; } - -void ffListDestroy(FFlist* list) -{ - //Avoid free-after-use. These 3 assignments are cheap so don't remove them - list->capacity = list->length = 0; - free(list->data); - list->data = NULL; -} diff --git a/src/util/FFlist.h b/src/util/FFlist.h index 58612e347..eccd30b55 100644 --- a/src/util/FFlist.h +++ b/src/util/FFlist.h @@ -31,12 +31,20 @@ bool ffListShift(FFlist* list, void* result); // Removes the last element, and copy its value to `*result` bool ffListPop(FFlist* list, void* result); -void ffListDestroy(FFlist* list); - static inline void ffListInit(FFlist* list, uint32_t elementSize) { assert(elementSize > 0); - ffListInitA(list, elementSize, 0); + list->elementSize = elementSize; + list->capacity = 0; + list->length = 0; + list->data = NULL; +} + +static inline FFlist ffListCreate(uint32_t elementSize) +{ + FFlist result; + ffListInit(&result, elementSize); + return result; } static inline void* ffListGet(const FFlist* list, uint32_t index) @@ -50,6 +58,16 @@ static inline void ffListSort(FFlist* list, int(*compar)(const void*, const void qsort(list->data, list->length, list->elementSize, compar); } +static inline void ffListDestroy(FFlist* list) +{ + if (!list->data) return; + + //Avoid free-after-use. These 3 assignments are cheap so don't remove them + list->capacity = list->length = 0; + free(list->data); + list->data = NULL; +} + #define FF_LIST_FOR_EACH(itemType, itemVarName, listVar) \ assert(sizeof(itemType) == (listVar).elementSize); \ for(itemType* itemVarName = (itemType*)(listVar).data; \ diff --git a/src/util/FFstrbuf.c b/src/util/FFstrbuf.c index bcf946071..eccea2341 100644 --- a/src/util/FFstrbuf.c +++ b/src/util/FFstrbuf.c @@ -35,16 +35,6 @@ void ffStrbufInitMove(FFstrbuf* strbuf, FFstrbuf* src) ffStrbufInit(strbuf); } -void ffStrbufInitF(FFstrbuf* strbuf, const char* format, ...) -{ - assert(format != NULL); - - va_list arguments; - va_start(arguments, format); - ffStrbufInitVF(strbuf, format, arguments); - va_end(arguments); -} - void ffStrbufInitVF(FFstrbuf* strbuf, const char* format, va_list arguments) { assert(format != NULL); @@ -458,13 +448,3 @@ uint16_t ffStrbufToUInt16(const FFstrbuf* strbuf, uint16_t defaultValue) unsigned long result = strtoul(strbuf->chars, &str_end, 10); return str_end == strbuf->chars || result > UINT16_MAX ? defaultValue : (uint16_t)result; } - -void ffStrbufDestroy(FFstrbuf* strbuf) -{ - if(strbuf->allocated == 0) return; - - //Avoid free-after-use. These 3 assignments are cheap so don't remove them - strbuf->allocated = strbuf->length = 0; - free(strbuf->chars); - strbuf->chars = CHAR_NULL_PTR; -} diff --git a/src/util/FFstrbuf.h b/src/util/FFstrbuf.h index d80a99483..32eb3da8c 100644 --- a/src/util/FFstrbuf.h +++ b/src/util/FFstrbuf.h @@ -29,9 +29,8 @@ typedef struct FFstrbuf } FFstrbuf; void ffStrbufInitA(FFstrbuf* strbuf, uint32_t allocate); -void ffStrbufInitCopy(FFstrbuf* strbuf, const FFstrbuf* src); +void ffStrbufInitCopy(FFstrbuf* __restrict strbuf, const FFstrbuf* __restrict src); void ffStrbufInitMove(FFstrbuf* strbuf, FFstrbuf* src); -void ffStrbufInitF(FFstrbuf* strbuf, const char* format, ...); void ffStrbufInitVF(FFstrbuf* strbuf, const char* format, va_list arguments); void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free); @@ -91,7 +90,55 @@ void ffStrbufPutTo(const FFstrbuf* strbuf, FILE* file); FF_C_NODISCARD double ffStrbufToDouble(const FFstrbuf* strbuf); FF_C_NODISCARD uint16_t ffStrbufToUInt16(const FFstrbuf* strbuf, uint16_t defaultValue); -void ffStrbufDestroy(FFstrbuf* strbuf); +FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateA(uint32_t allocate) +{ + FFstrbuf strbuf; + ffStrbufInitA(&strbuf, allocate); + return strbuf; +} + +FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateCopy(const FFstrbuf* src) +{ + FFstrbuf strbuf; + ffStrbufInitCopy(&strbuf, src); + return strbuf; +} + +FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateMove(FFstrbuf* src) +{ + FFstrbuf strbuf; + ffStrbufInitMove(&strbuf, src); + return strbuf; +} + +FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateVF(const char* format, va_list arguments) +{ + FFstrbuf strbuf; + ffStrbufInitVF(&strbuf, format, arguments); + return strbuf; +} + +FF_C_PRINTF(2, 3) +static inline void ffStrbufInitF(FFstrbuf* strbuf, const char* format, ...) +{ + va_list arguments; + va_start(arguments, format); + ffStrbufInitVF(strbuf, format, arguments); + va_end(arguments); +} + +FF_C_PRINTF(1, 2) +FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateF(const char* format, ...) +{ + FFstrbuf strbuf; + + va_list arguments; + va_start(arguments, format); + ffStrbufInitVF(&strbuf, format, arguments); + va_end(arguments); + + return strbuf; +} static inline void ffStrbufRecalculateLength(FFstrbuf* strbuf) { @@ -121,19 +168,40 @@ static inline void ffStrbufInit(FFstrbuf* strbuf) strbuf->chars = CHAR_NULL_PTR; } +FF_C_NODISCARD static inline FFstrbuf ffStrbufCreate() +{ + FFstrbuf strbuf; + ffStrbufInit(&strbuf); + return strbuf; +} + static inline void ffStrbufInitNS(FFstrbuf* strbuf, uint32_t length, const char* str) { ffStrbufInit(strbuf); ffStrbufAppendNS(strbuf, length, str); } +FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateNS(uint32_t length, const char* str) +{ + FFstrbuf strbuf; + ffStrbufInitNS(&strbuf, length, str); + return strbuf; +} + static inline void ffStrbufInitS(FFstrbuf* strbuf, const char* str) { ffStrbufInit(strbuf); ffStrbufAppendS(strbuf, str); } -static inline void ffStrbufAppend(FFstrbuf* strbuf, const FFstrbuf* value) +FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateS(const char* str) +{ + FFstrbuf strbuf; + ffStrbufInitS(&strbuf, str); + return strbuf; +} + +static inline void ffStrbufAppend(FFstrbuf* __restrict strbuf, const FFstrbuf* __restrict value) { assert(value != strbuf); if(value == NULL) @@ -323,6 +391,17 @@ static inline FF_C_NODISCARD bool ffStrbufEndsWithIgnCase(const FFstrbuf* strbuf return ffStrbufEndsWithIgnCaseNS(strbuf, end->length, end->chars); } +static inline void ffStrbufDestroy(FFstrbuf* strbuf) +{ + if(strbuf->allocated == 0) return; + + extern char* CHAR_NULL_PTR; + //Avoid free-after-use. These 3 assignments are cheap so don't remove them + strbuf->allocated = strbuf->length = 0; + free(strbuf->chars); + strbuf->chars = CHAR_NULL_PTR; +} + #define FF_STRBUF_AUTO_DESTROY FFstrbuf __attribute__((__cleanup__(ffStrbufDestroy))) #endif diff --git a/src/util/FFvaluestore.c b/src/util/FFvaluestore.c deleted file mode 100644 index 68040045b..000000000 --- a/src/util/FFvaluestore.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "FFvaluestore.h" - -#include - -typedef char KeyType[32]; //31 byte key + \0 - -void ffValuestoreInit(FFvaluestore* vs, uint32_t valueSize) -{ - ffListInit(vs, (uint32_t) (sizeof(KeyType) + valueSize)); -} - -void* ffValuestoreGet(FFvaluestore* vs, const char* key) -{ - for(uint32_t i = 0; i < vs->length; i++) - { - char* element = ffListGet(vs, i); - if(strcmp(element, key) == 0) - return element + sizeof(KeyType); - } - - return NULL; -} - -void* ffValuestoreSet(FFvaluestore* vs, const char* key, bool* created) -{ - char* element = ffValuestoreGet(vs, key); - if(element != NULL) - { - if(created != NULL) - *created = false; - return element; - } - - element = ffListAdd(vs); - strncpy(element, key, sizeof(KeyType) - 1); - element[sizeof(KeyType) - 1] = '\0'; - - if(created != NULL) - *created = true; - return element + sizeof(KeyType); -} - -void ffValuestoreDestroy(FFvaluestore* vs) -{ - ffListDestroy(vs); -} diff --git a/src/util/FFvaluestore.h b/src/util/FFvaluestore.h deleted file mode 100644 index 4d966837c..000000000 --- a/src/util/FFvaluestore.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#ifndef FASTFETCH_INCLUDED_FFVALUESTORE -#define FASTFETCH_INCLUDED_FFVALUESTORE - -#include "FFlist.h" -#include "FFcheckmacros.h" - -typedef FFlist FFvaluestore; - -void ffValuestoreInit(FFvaluestore* vs, uint32_t valueSize); -FF_C_NODISCARD void* ffValuestoreGet(FFvaluestore* vs, const char* key); -FF_C_NODISCARD void* ffValuestoreSet(FFvaluestore* vs, const char* key, bool* created); //created may be NULL -void ffValuestoreDestroy(FFvaluestore* vs); - -#endif diff --git a/tests/list.c b/tests/list.c index db4db544a..4ba879097 100644 --- a/tests/list.c +++ b/tests/list.c @@ -108,6 +108,13 @@ int main(void) VERIFY(list.capacity == 0); VERIFY(list.length == 0); + { + FF_LIST_AUTO_DESTROY test = ffListCreate(1); + VERIFY(test.elementSize = 1); + VERIFY(test.capacity == 0); + VERIFY(test.length == 0); + } + //Success puts("\033[32mAll tests passed!"FASTFETCH_TEXT_MODIFIER_RESET); } diff --git a/tests/strbuf.c b/tests/strbuf.c index 3d8d3d057..3df30af23 100644 --- a/tests/strbuf.c +++ b/tests/strbuf.c @@ -28,12 +28,12 @@ int main(void) FFstrbuf strbuf; //destroy 0 - ffStrbufInitA(&strbuf, 0); + ffStrbufInit(&strbuf); ffStrbufDestroy(&strbuf); //initA - ffStrbufInitA(&strbuf, 0); + ffStrbufInit(&strbuf); VERIFY(strbuf.chars[0] == 0); VERIFY(strbuf.allocated == 0); @@ -216,6 +216,11 @@ int main(void) ffStrbufDestroy(&strbuf); + { + FF_STRBUF_AUTO_DESTROY testCreate = ffStrbufCreateS("TEST"); + VERIFY(ffStrbufEqualS(&testCreate, "TEST")); + } + //Success puts("\033[32mAll tests passed!"FASTFETCH_TEXT_MODIFIER_RESET); }