Compare commits

..

33 Commits

Author SHA1 Message Date
Carter Li 636126c57d Merge pull request #1239 from fastfetch-cli/dev
Release: v2.23.0
2024-09-03 10:34:07 +08:00
李通洲 2e475d590f JsonSchema: update zpool 2024-09-03 10:08:23 +08:00
李通洲 0cf45c1dcd Release: v2.23.0 2024-09-03 09:31:25 +08:00
李通洲 435516373d Logo (Image): better Windows support 2024-09-02 20:57:47 +08:00
李通洲 64735245e7 Presets: use string padding syntax
Fix #1237
2024-09-02 16:02:05 +08:00
李通洲 85d89395a9 Format: support syntax of padded string
Ref: #1237
2024-09-02 16:01:25 +08:00
李通洲 093940e504 Logo (Builtin): add Huawei Cloud EulerOS
Fix #1236
2024-09-02 09:36:57 +08:00
李通洲 e427a5112b Logo (Builtin): add small Steam Deck
Fix #1232
2024-09-02 09:31:14 +08:00
李通洲 1ab86a8ab9 TerminalTheme: fix hanging on screen 5.0 2024-09-02 09:26:54 +08:00
李通洲 99e0dc9aaa Zpool: don't break -DBINARY_LINK_TYPE=dynamic
Fix #1233
2024-08-31 12:44:35 +08:00
Carter Li 73e9db5b6e Zpool (SunOS): fix the dlsym error 2024-08-31 12:43:03 +08:00
Linus adc03bd792 Logo (Builtin): Add Steam Deck Logo (#1229)
* Logo (Builtin): Add Steam Deck Logo

* accidentally removed newline after steam deck oled block

* Update builtin.c

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2024-08-30 22:06:10 +08:00
李通洲 10fdc8e4a7 Logo (Builtin): make ubuntu logo colorable 2024-08-30 12:13:33 +08:00
李通洲 d75803794e Terminal: improve performance of xfce4-terminal version 2024-08-30 12:13:33 +08:00
AIT MEDDOUR Fouad-Eddine d25ac86283 Logo (Builtin): Add Magix (#1228)
* Add Magix (Correctly this time)

* Update magix.txt

* Update builtin.c

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2024-08-30 11:24:50 +08:00
李通洲 de8bbc9a5c Camera (FreeBSD): fix module was incorrectly disabled (v2) 2024-08-29 15:57:05 +08:00
Md. Iftakhar Awal Chowdhury 66977de5c7 Completion (Zsh): add completion for --logo-color-{1..9} (#1222) 2024-08-29 15:55:12 +08:00
李通洲 f828d3a9b9 Camera (FreeBSD): fix module was incorrectly disabled 2024-08-28 21:33:17 +08:00
李通洲 f0bc08e006 CI: run all modules on FreeBSD and SunOS 2024-08-28 21:14:54 +08:00
李通洲 e0f8e39a47 CI: add zpool 2024-08-28 20:56:59 +08:00
李通洲 8b9f787095 Zpool: fix build on SunOS 2024-08-28 20:56:23 +08:00
Carter Li d946cf27fe Zpool: add new module 2024-08-28 16:45:26 +08:00
Carter Li 5842ad1d56 Battery: print model name in key 2024-08-28 16:00:06 +08:00
Md. Iftakhar Awal Chowdhury 201047251d Completion: add optional completion support for certain flags (#1219) 2024-08-28 10:18:38 +08:00
李通洲 5c8e771939 Binary (Linux): fix building without libelf enabled 2024-08-28 09:41:08 +08:00
李通洲 b22e28b548 NetIO: don't print * if defaultRouteOnly is set 2024-08-27 21:36:57 +08:00
李通洲 8c51836a47 Logo (Builtin): update amogos 2024-08-27 21:18:25 +08:00
李通洲 df729938c5 Binary: improve performance 2024-08-27 16:41:23 +08:00
Carter Li 67d0dfcef0 DE (Linux): support unity version detection 2024-08-27 14:31:05 +08:00
李通洲 03c95e5cad Shell: improve performance of bash and zsh version detection 2024-08-27 14:06:45 +08:00
Md. Iftakhar Awal Chowdhury c0a07002f2 Completion: update zsh-completion to reflect latest upstream changes (#1217) 2024-08-26 17:39:49 +08:00
李通洲 5a9c3154fa IO (Unix): fix isDir condition checking; skip hidden files
Fix #1216
2024-08-26 16:10:44 +08:00
Carter Li e35aed761b Packaging: update debian stuff [ci skip] 2024-08-26 10:58:52 +08:00
54 changed files with 1108 additions and 216 deletions
+4 -4
View File
@@ -388,8 +388,8 @@ jobs:
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch
time ./fastfetch --format json
time ./fastfetch -c presets/ci.jsonc --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
ctest
@@ -426,8 +426,8 @@ jobs:
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch
time ./fastfetch --format json
time ./fastfetch -c presets/ci.jsonc --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
ctest
+28
View File
@@ -1,3 +1,31 @@
# 2.23.0
Features:
* Support unity version detection (DE, Linux)
* Print model name in Battery keys if available (Battery)
* Add module `Zpool`
* Improve performance (Shell / Terminal, Linux)
* Support syntax of padded strings in `--<module>-format`. `{variable<padlength}` and `{variable>padlength}` are supported.
* If pad length is greater than the length of the variable, the variable will be padded with spaces.
* `fastfetch -l none -s command --command-text 'echo 12345' --command-format 'output({1<20})'` prints `Command: output(12345 )`
* `fastfetch -l none -s command --command-text 'echo 12345' --command-format 'output({1>20})'` prints `Command: output( 12345)`
* If pad length is less than the length of the variable, the variable will be truncated.
Bugfixes:
* Fix broken `--list-presets`
* Update zsh completion script
* Don't print `*` if `defaultRouteOnly` is set (NetIO)
* Fix Camera module incorrectly disabled on FreeBSD (Camera, FreeBSD)
* Fix hanging on screen 5.0 (Terminal)
* Improve image logo support on Windows (Logo, Windows)
Logos:
* Update AmogOS
* Add Magix
* Make ubuntu logo colorable
* Add Steam Deck Logo
* add Huawei Cloud EulerOS
# 2.22.0
Features:
+44 -2
View File
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
project(fastfetch
VERSION 2.22.0
VERSION 2.23.0
LANGUAGES C
DESCRIPTION "Fast neofetch-like system information tool"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
@@ -71,6 +71,7 @@ cmake_dependent_option(ENABLE_DDCUTIL "Enable ddcutil" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_DIRECTX_HEADERS "Enable DirectX headers for WSL" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_ELF "Enable libelf" ON "LINUX OR FreeBSD OR ANDROID" OFF)
cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" OFF)
cmake_dependent_option(ENABLE_LIBZFS "Enable libzfs" ON "LINUX OR FreeBSD OR SunOS" OFF)
option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embedded) yyjson library" OFF)
option(ENABLE_ASAN "Build fastfetch with ASAN (address sanitizer)" OFF)
@@ -392,6 +393,7 @@ set(LIBFASTFETCH_SRC
src/modules/wifi/wifi.c
src/modules/wm/wm.c
src/modules/wmtheme/wmtheme.c
src/modules/zpool/zpool.c
src/options/display.c
src/options/modules.c
src/options/logo.c
@@ -481,6 +483,7 @@ if(LINUX)
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/detection/camera/camera_linux.c
src/detection/zpool/zpool_linux.c
src/util/platform/FFPlatform_unix.c
src/util/binary_linux.c
)
@@ -543,6 +546,7 @@ elseif(ANDROID)
src/detection/de/de_nosupport.c
src/detection/wmtheme/wmtheme_nosupport.c
src/detection/camera/camera_android.c
src/detection/zpool/zpool_nosupport.c
src/util/platform/FFPlatform_unix.c
src/util/binary_linux.c
)
@@ -622,6 +626,7 @@ elseif(FreeBSD)
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/detection/camera/camera_linux.c
src/detection/zpool/zpool_linux.c
src/util/platform/FFPlatform_unix.c
src/util/binary_linux.c
)
@@ -686,6 +691,7 @@ elseif(APPLE)
src/detection/de/de_nosupport.c
src/detection/wmtheme/wmtheme_apple.m
src/detection/camera/camera_apple.m
src/detection/zpool/zpool_nosupport.c
src/util/apple/cf_helpers.c
src/util/apple/osascript.m
src/util/platform/FFPlatform_unix.c
@@ -750,6 +756,7 @@ elseif(WIN32)
src/detection/de/de_nosupport.c
src/detection/wmtheme/wmtheme_windows.c
src/detection/camera/camera_windows.cpp
src/detection/zpool/zpool_nosupport.c
src/util/windows/getline.c
src/util/windows/com.cpp
src/util/windows/registry.c
@@ -832,6 +839,7 @@ elseif(SunOS)
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/detection/camera/camera_nosupport.c
src/detection/zpool/zpool_linux.c
src/util/platform/FFPlatform_unix.c
src/util/binary_linux.c
)
@@ -1091,6 +1099,25 @@ ff_lib_enable(DIRECTX_HEADERS
"DirectX-Headers"
"DirectX-Headers"
)
# The system <libzfs.h> is only usable on SunOS. We provide our local copy of it so it's always available.
if(ENABLE_LIBZFS)
if(BINARY_LINK_TYPE STREQUAL "dlopen")
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LIBZFS=1)
else()
set(CMAKE_REQUIRED_LIBRARIES_BACKUP ${CMAKE_REQUIRED_LIBRARIES})
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} zfs)
check_function_exists("libzfs_init" LIBZFS_FOUND)
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES_BACKUP})
if(NOT LIBZFS_FOUND)
message(STATUS "Library: missing: LIBZFS")
else()
message(STATUS "Library: found LIBZFS")
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LIBZFS=1)
target_link_libraries(libfastfetch PRIVATE zfs)
endif()
endif()
endif()
if(ENABLE_THREADS)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_THREADS)
@@ -1153,6 +1180,8 @@ elseif(SunOS)
PRIVATE "socket"
PRIVATE "kstat"
PRIVATE "proc"
PRIVATE "zfs"
PRIVATE "nvpair"
)
elseif(ANDROID)
CHECK_LIBRARY_EXISTS(-l:libandroid-wordexp.a wordexp "" HAVE_LIBANDROID_WORDEXP_STATIC)
@@ -1196,11 +1225,16 @@ if(WIN32)
endif()
set(CMAKE_CXX_STANDARD 17)
endif()
if(LINUX)
if(FreeBSD)
set(CMAKE_REQUIRED_INCLUDES "/usr/local/include" "/usr/include")
endif()
if(LINUX OR FreeBSD)
CHECK_INCLUDE_FILE("linux/videodev2.h" HAVE_LINUX_VIDEODEV2)
if(HAVE_LINUX_VIDEODEV2)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LINUX_VIDEODEV2=1)
endif()
endif()
if(LINUX)
CHECK_INCLUDE_FILE("linux/wireless.h" HAVE_LINUX_WIRELESS)
if(HAVE_LINUX_WIRELESS)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LINUX_WIRELESS=1)
@@ -1308,9 +1342,17 @@ if (BUILD_TESTS)
PRIVATE libfastfetch
)
add_executable(fastfetch-test-format
tests/format.c
)
target_link_libraries(fastfetch-test-format
PRIVATE libfastfetch
)
enable_testing()
add_test(NAME test-strbuf COMMAND fastfetch-test-strbuf)
add_test(NAME test-list COMMAND fastfetch-test-list)
add_test(NAME test-format COMMAND fastfetch-test-format)
endif()
##################
+32 -23
View File
@@ -3,9 +3,8 @@
function _fastfetch() {
local state
local -a opts
opts=(${(f)"$(
python <<EOF
local -a opts=("${(f)$(
python3 <<EOF
import json
import subprocess
import sys
@@ -18,15 +17,21 @@ def main():
for key in data:
for flag in data[key]:
if flag["long"] == "logo-color-[1-9]":
for i in range(1, 10):
command_prefix = f"--logo-color-{i}[{flag["desc"]} ({i})]"
print_command(command_prefix, flag)
continue
if flag.get("pseudo", False):
continue
if "short" in flag:
command_prefix = f"""-{flag["short"]}[{flag["desc"]}]"""
command_prefix = f"-{flag["short"]}[{flag["desc"]}]"
print_command(command_prefix, flag)
if "long" in flag:
command_prefix = f"""--{flag["long"]}[{flag["desc"]}]"""
command_prefix = f"--{flag["long"]}[{flag["desc"]}]"
print_command(command_prefix, flag)
@@ -34,22 +39,22 @@ def print_command(command_prefix: str, flag: dict):
if "arg" in flag:
type: str = flag["arg"]["type"]
if type == "bool":
print(f"{command_prefix}:bool:(true false)")
print(f"{command_prefix}::bool:(true false)")
elif type == "color":
print(f"{command_prefix}:color:(black red green yellow blue magenta cyan white default)")
print(f"{command_prefix}:color:->colors")
elif type == "command":
print(f"{command_prefix}:module:->modules")
print(f"{command_prefix}::module:->modules")
elif type == "config":
print(f"{command_prefix}:presets:->presets")
print(f"{command_prefix}:preset:->presets")
elif type == "enum":
temp: str = " ".join(flag["arg"]["enum"])
print(f'{command_prefix}:type:( {temp} )')
print(f'{command_prefix}:type:({temp})')
elif type == "logo":
print(f"{command_prefix}:logo:->logo")
print(f"{command_prefix}:logo:->logos")
elif type == "structure":
print(f"{command_prefix}:structure:->structure")
print(f"{command_prefix}:structure:->structures")
elif type == "path":
print(f"{command_prefix}:path:_files -/")
print(f"{command_prefix}::path:_files")
else:
print(f"{command_prefix}:")
else:
@@ -62,30 +67,34 @@ if __name__ == "__main__":
except Exception:
sys.exit(1)
EOF
)"})
)}")
_arguments -C "$opts[@]"
_arguments "$opts[@]"
case $state in
colors)
local -a colors=(black red green yellow blue magenta cyan white default)
_describe 'color' colors
;;
modules)
local -a modules=( ${(f)"$(fastfetch --list-modules autocompletion)"} )
modules=( ${(L)^modules%%:*}-format format color )
local -a modules=("${(f)$(fastfetch --list-modules autocompletion)}")
modules=(${(L)^modules[@]%%:*}-format format color)
_describe 'module' modules
;;
presets)
local -a presets=(
${$(fastfetch --list-presets autocompletion):#.*}
"${(f)$(fastfetch --list-presets autocompletion)}"
"none:Disable loading config file"
)
_describe 'preset' presets
_describe 'preset' presets || _files
;;
structure)
local -a structures=( ${(f)"$(fastfetch --list-modules autocompletion)"} )
structures)
local -a structures=("${(f)$(fastfetch --list-modules autocompletion)}")
_describe 'structure' structures
;;
logo)
logos)
local -a logos=(
$(fastfetch --list-logos autocompletion)
"${(f)$(fastfetch --list-logos autocompletion)}"
"none:Don't print logo"
"small:Print small ascii logo if available"
)
+6
View File
@@ -1,3 +1,9 @@
fastfetch (2.22.0) jammy; urgency=medium
* Update to 2.22.0
-- Carter Li <zhangsongcui@live.cn> Mon, 26 Aug 2024 18:53:35 +0800
fastfetch (2.21.3) jammy; urgency=medium
* Update to 2.21.3
+1 -1
View File
@@ -1 +1 @@
fastfetch_2.21.3_source.buildinfo universe/utils optional
fastfetch_2.22.0_source.buildinfo universe/utils optional
+6 -1
View File
@@ -820,7 +820,8 @@
"weather",
"wm",
"wifi",
"wmtheme"
"wmtheme",
"zpool"
]
},
{
@@ -993,6 +994,10 @@
{
"const": "wmtheme",
"description": "Print current theme of window manager"
},
{
"const": "zpool",
"description": "Print ZFS storage pools"
}
]
},
+1
View File
@@ -54,6 +54,7 @@
"physicalmemory",
"swap",
"disk",
"zpool",
"battery",
"poweradapter",
"player",
+1
View File
@@ -56,6 +56,7 @@
"physicalmemory",
"swap",
"disk",
"zpool",
"battery",
"poweradapter",
"player",
+1 -2
View File
@@ -111,8 +111,7 @@
{
"type": "loadavg",
"compact": false,
// {duration} is not fixed length, hack it
"key": "│ LOAD \u001b[s{duration}m\u001b[u\u001b[6C│{$1}"
"key": "│ LOAD {duration>2}m │{$1}" // pad duration to 2 chars
},
{
"type": "custom",
+58 -13
View File
@@ -265,18 +265,34 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
continue;
}
int32_t truncLength = INT32_MAX;
char* pColon = memchr(placeholderValue.chars, ':', placeholderValue.length);
if (pColon != NULL)
int32_t truncLength = 0;
char align = '\0';
char* pSep = memchr(placeholderValue.chars, ':', placeholderValue.length);
if (pSep)
align = ':';
else
{
pSep = memchr(placeholderValue.chars, '<', placeholderValue.length);
if (pSep)
align = '<';
else
{
pSep = memchr(placeholderValue.chars, '>', placeholderValue.length);
if (pSep)
align = '>';
}
}
if (pSep)
{
char* pEnd = NULL;
truncLength = (int32_t) strtol(pColon + 1, &pEnd, 10);
truncLength = (int32_t) strtol(pSep + 1, &pEnd, 10);
if (*pEnd != '\0')
{
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
continue;
}
*pColon = '\0';
*pSep = '\0';
}
uint32_t index = getArgumentIndex(placeholderValue.chars, numArgs, arguments);
@@ -287,7 +303,7 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
if (index > numArgs)
{
if (pColon) *pColon = ':';
if (pSep) *pSep = align;
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
continue;
}
@@ -299,14 +315,43 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
truncLength = -truncLength;
}
uint32_t oldLength = buffer->length;
ffFormatAppendFormatArg(buffer, &arguments[index - 1]);
if (buffer->length - oldLength > (uint32_t) truncLength)
if (!align)
ffFormatAppendFormatArg(buffer, &arguments[index - 1]);
else
{
ffStrbufSubstrBefore(buffer, oldLength + (uint32_t) truncLength);
ffStrbufTrimRightSpace(buffer);
if (ellipsis)
ffStrbufAppendS(buffer, "");
ffStrbufClear(&placeholderValue);
ffFormatAppendFormatArg(&placeholderValue, &arguments[index - 1]);
if (placeholderValue.length == (uint32_t) truncLength)
ffStrbufAppend(buffer, &placeholderValue);
else if (placeholderValue.length > (uint32_t) truncLength)
{
if (align == ':')
{
ffStrbufSubstrBefore(&placeholderValue, (uint32_t) truncLength);
ffStrbufTrimRightSpace(&placeholderValue);
}
else
ffStrbufSubstrBefore(&placeholderValue, (uint32_t) (!ellipsis? truncLength : truncLength - 1));
ffStrbufAppend(buffer, &placeholderValue);
if (ellipsis)
ffStrbufAppendS(buffer, "");
}
else if (align == ':')
ffStrbufAppend(buffer, &placeholderValue);
else
{
if (align == '<')
{
ffStrbufAppend(buffer, &placeholderValue);
ffStrbufAppendNC(buffer, (uint32_t) truncLength - placeholderValue.length, ' ');
}
else
{
ffStrbufAppendNC(buffer, (uint32_t) truncLength - placeholderValue.length, ' ');
ffStrbufAppend(buffer, &placeholderValue);
}
}
}
}
+3
View File
@@ -247,6 +247,9 @@ void ffListFeatures(void)
#if FF_HAVE_ELF
"libelf\n"
#endif
#if FF_HAVE_LIBZFS
"libzfs\n"
#endif
#if FF_HAVE_DIRECTX_HEADERS
"Directx Headers\n"
#endif
+6 -7
View File
@@ -144,7 +144,7 @@ const char* ffGetTerminalResponse(const char* request, const char* format, ...)
{
if (ftty < 0)
{
ftty = open("/dev/tty", O_RDWR | O_NOCTTY | O_CLOEXEC);
ftty = open("/dev/tty", O_RDWR | O_NOCTTY | O_CLOEXEC | O_NONBLOCK);
if (ftty < 0)
return "open(\"/dev/tty\", O_RDWR | O_NOCTTY | O_CLOEXEC) failed";
@@ -232,12 +232,15 @@ void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indenta
while((entry = readdir(dir)) != NULL)
{
if(entry->d_name[0] == '.') // skip hidden files
continue;
bool isDir = false;
#ifdef _DIRENT_HAVE_D_TYPE
#ifndef __sun
if(entry->d_type != DT_UNKNOWN && entry->d_type != DT_LNK)
isDir = entry->d_type == DT_DIR;
else
#else
#endif
{
struct stat stbuf;
if (fstatat(dfd, entry->d_name, &stbuf, 0) < 0)
@@ -245,12 +248,8 @@ void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indenta
else
isDir = S_ISDIR(stbuf.st_mode);
}
#endif
if (isDir)
{
if(ffStrEquals(entry->d_name, ".") || ffStrEquals(entry->d_name, ".."))
continue;
ffStrbufAppendS(folder, entry->d_name);
ffStrbufAppendC(folder, '/');
listFilesRecursively(baseLength, folder, (uint8_t) (indentation + 1), entry->d_name, pretty);
+1
View File
@@ -169,6 +169,7 @@ static FFModuleBaseInfo* Y[] = {
};
static FFModuleBaseInfo* Z[] = {
(void*) &instance.config.modules.zpool,
NULL,
};
+4
View File
@@ -13,6 +13,10 @@ For example: "--title-format '{user-name:5}'" will truncate user name into 5-len
If '<trunc-length>' is negative, an ellipsis … will be appended at the end when the original string is truncated.
Note: The string length is counted in raw bytes. Multi-byte unicode characters and ANSI escape codes are not taken into account.
In 2.23.0 or newer, `<` or `>` can be specified instead of `:` to set a left or right padding.
For example: "--title-format '{user-name<20}'" will generate `<user-name> `;
"--title-format '{user-name>20}'" will generate ` <user-name>`
If the value index is missing, meaning the placeholder is "{}", an internal counter sets the value index.
This means that the format string "Values: {1} ({2})" is equivalent to "Values: {} ({})".
Note that this counter only counts empty placeholders, so the format string "{2} {} {}" will contain the second value, then the first, and then the second again.
+8
View File
@@ -178,6 +178,12 @@ static void getBudgie(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
ffParsePropFileData("budgie/budgie-version.xml", "<str>", result);
}
static void getUnity(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
{
if (ffParsePropFile("/usr/bin/unity", "parser = OptionParser(version= \"%prog ", result))
ffStrbufSubstrBeforeFirstC(result, '"');
}
const char* ffDetectDEVersion(const FFstrbuf* deName, FFstrbuf* result, FFDEOptions* options)
{
if (!instance.config.general.detectVersion) return "Disabled by config";
@@ -196,6 +202,8 @@ const char* ffDetectDEVersion(const FFstrbuf* deName, FFstrbuf* result, FFDEOpti
getLXQt(result, options);
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_BUDGIE))
getBudgie(result, options);
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_UNITY))
getUnity(result, options);
else
return "Unsupported DE";
return NULL;
+7
View File
@@ -238,6 +238,13 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
ffStrbufSetS(&result->deProcessName, "ukui-session");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_UKUI);
}
else if(
ffStrStartsWithIgnCase(name, "Unity:Unity")
) {
ffStrbufSetS(&result->deProcessName, "unity-session");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_UNITY);
}
}
+6 -9
View File
@@ -14,26 +14,23 @@ static inline char* realpath(const char* restrict file_name, char* restrict reso
}
#endif
static bool extractNvimVersionFromBinary(const char* str, uint32_t len, void* userdata)
static bool extractNvimVersionFromBinary(const char* str, FF_MAYBE_UNUSED uint32_t len, void* userdata)
{
if (len < strlen("NVIM v0.0.0")) return true;
if (!ffStrStartsWith(str, "NVIM v")) return true;
ffStrbufSetS((FFstrbuf*) userdata, str + strlen("NVIM v"));
return false;
}
static bool extractVimVersionFromBinary(const char* str, uint32_t len, void* userdata)
static bool extractVimVersionFromBinary(const char* str, FF_MAYBE_UNUSED uint32_t len, void* userdata)
{
if (len < strlen("VIM - Vi IMproved 0.0")) return true;
if (!ffStrStartsWith(str, "VIM - Vi IMproved ")) return true;
ffStrbufSetS((FFstrbuf*) userdata, str + strlen("VIM - Vi IMproved "));
ffStrbufSubstrBeforeFirstC(userdata, ' ');
return false;
}
static bool extractNanoVersionFromBinary(const char* str, uint32_t len, void* userdata)
static bool extractNanoVersionFromBinary(const char* str, FF_MAYBE_UNUSED uint32_t len, void* userdata)
{
if (len < strlen("GNU nano 0.0")) return true;
if (!ffStrStartsWith(str, "GNU nano ")) return true;
ffStrbufSetS((FFstrbuf*) userdata, str + strlen("GNU nano "));
return false;
@@ -97,11 +94,11 @@ const char* ffDetectEditor(FFEditorResult* result)
if (!instance.config.general.detectVersion) return NULL;
if (ffStrbufEqualS(&result->exe, "nvim"))
ffBinaryExtractStrings(result->path.chars, extractNvimVersionFromBinary, &result->version);
ffBinaryExtractStrings(result->path.chars, extractNvimVersionFromBinary, &result->version, (uint32_t) strlen("NVIM v0.0.0"));
else if (ffStrbufEqualS(&result->exe, "vim"))
ffBinaryExtractStrings(result->path.chars, extractVimVersionFromBinary, &result->version);
ffBinaryExtractStrings(result->path.chars, extractVimVersionFromBinary, &result->version, (uint32_t) strlen("VIM - Vi IMproved 0.0"));
else if (ffStrbufEqualS(&result->exe, "nano"))
ffBinaryExtractStrings(result->path.chars, extractNanoVersionFromBinary, &result->version);
ffBinaryExtractStrings(result->path.chars, extractNanoVersionFromBinary, &result->version, (uint32_t) strlen("GNU nano 0.0"));
if (result->version.length > 0) return NULL;
+10 -12
View File
@@ -1,20 +1,18 @@
#include "initsystem.h"
#include "common/processing.h"
#include "util/binary.h"
#include "util/stringUtils.h"
#include <unistd.h>
FF_MAYBE_UNUSED static bool elfExtractStringsCallBack(const char* str, uint32_t len, void* data)
FF_MAYBE_UNUSED static bool extractSystemdVersion(const char* str, uint32_t len, void* userdata)
{
if (len > strlen("systemd 0.0 running in ") && memcmp(str, "systemd ", strlen("systemd ")) == 0)
{
const char* pend = memmem(str + strlen("systemd "), len - strlen("systemd "), " running in ", strlen(" running in "));
if (pend)
{
ffStrbufSetNS((FFstrbuf*) data, (uint32_t) (pend - str) - (uint32_t) strlen("systemd "), str + strlen("systemd "));
return false;
}
}
return true;
if (!ffStrStartsWith(str, "systemd ")) return true;
const char* pstart = str + strlen("systemd ");
const char* pend = memmem(pstart, len - strlen("systemd "), " running in ", strlen(" running in "));
if (!pend) return true;
ffStrbufSetNS((FFstrbuf*) userdata, (uint32_t) (pend - pstart), pstart);
return false;
}
const char* ffDetectInitSystem(FFInitSystemResult* result)
@@ -49,7 +47,7 @@ const char* ffDetectInitSystem(FFInitSystemResult* result)
#if __linux__ && !__ANDROID__
if (ffStrbufEqualS(&result->name, "systemd"))
{
ffBinaryExtractStrings(result->exe.chars, elfExtractStringsCallBack, &result->version);
ffBinaryExtractStrings(result->exe.chars, extractSystemdVersion, &result->version, (uint32_t) strlen("systemd 0.0 running in x"));
if (result->version.length == 0)
{
if (ffProcessAppendStdOut(&result->version, (char* const[]) {
@@ -287,10 +287,10 @@ static void detectXterm(FFTerminalFontResult* terminalFont)
ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars);
}
static bool elfExtractStringsCallBack(const char* str, uint32_t len, void* userData)
static bool extractStTermFont(const char* str, FF_MAYBE_UNUSED uint32_t len, void* userdata)
{
if (!ffStrContains(str, "size=")) return true;
ffStrbufSetNS((FFstrbuf*) userData, len, str);
ffStrbufSetNS((FFstrbuf*) userdata, len, str);
return false;
}
@@ -315,7 +315,7 @@ static void detectSt(FFTerminalFontResult* terminalFont, const FFTerminalResult*
{
ffStrbufClear(&font);
const char* error = ffBinaryExtractStrings(terminal->exePath.chars, elfExtractStringsCallBack, &font);
const char* error = ffBinaryExtractStrings(terminal->exePath.chars, extractStTermFont, &font, (uint32_t) strlen("size=0"));
if (error)
{
ffStrbufAppendS(&terminalFont->error, error);
+58 -11
View File
@@ -64,16 +64,29 @@ static bool getExeVersionGeneral(FFstrbuf* exe, FFstrbuf* version)
return true;
}
static bool getShellVersionBash(FFstrbuf* exe, FFstrbuf* version)
static bool extractBashVersion(const char* line, FF_MAYBE_UNUSED uint32_t len, void *userdata)
{
if (!ffStrStartsWith(line, "@(#)Bash version ")) return true;
const char* start = line + strlen("@(#)Bash version ");
const char* end = strchr(start, '(');
if (!end) return true;
ffStrbufSetNS((FFstrbuf*) userdata, (uint32_t) (end - start), start);
return false;
}
static bool getShellVersionBash(FFstrbuf* exe, FFstrbuf* exePath, FFstrbuf* version)
{
const char* path = exePath->chars;
if (*path == '\0')
path = exe->chars;
ffBinaryExtractStrings(path, extractBashVersion, version, (uint32_t) strlen("@(#)Bash version 0.0.0(0) release GNU"));
if(!getExeVersionRaw(exe, version))
return false;
// GNU bash, version 5.1.16(1)-release (x86_64-pc-msys)\nCopyright...
ffStrbufSubstrBeforeFirstC(version, '\n'); // GNU bash, version 5.1.16(1)-release (x86_64-pc-msys)
ffStrbufSubstrBeforeLastC(version, ' '); // GNU bash, version 5.1.16(1)-release
ffStrbufSubstrAfterLastC(version, ' '); // 5.1.16(1)-release
ffStrbufSubstrBeforeFirstC(version, '('); // 5.1.16
ffStrbufSubstrBeforeFirstC(version, '('); // GNU bash, version 5.1.16
ffStrbufSubstrAfterLastC(version, ' '); // 5.1.16
return true;
}
@@ -189,6 +202,29 @@ static bool getShellVersionXonsh(FFstrbuf* exe, FFstrbuf* version)
return true;
}
static bool extractZshVersion(const char* line, FF_MAYBE_UNUSED uint32_t len, void *userdata)
{
if (!ffStrStartsWith(line, "zsh-")) return true;
const char* start = line + strlen("zsh-");
const char* end = strchr(start, '-');
if (!end) return true;
ffStrbufSetNS((FFstrbuf*) userdata, (uint32_t) (end - start), start);
return false;
}
static bool getShellVersionZsh(FFstrbuf* exe, FFstrbuf* exePath, FFstrbuf* version)
{
const char* path = exePath->chars;
if (*path == '\0')
path = exe->chars;
ffBinaryExtractStrings(path, extractZshVersion, version, (uint32_t) strlen("zsh-0.0-0"));
if (version->length) return true;
return getExeVersionGeneral(exe, version); //zsh 5.9 (arm-apple-darwin21.3.0)
}
#ifdef _WIN32
static bool getShellVersionWinPowerShell(FFstrbuf* exe, FFstrbuf* version)
{
@@ -203,7 +239,7 @@ static bool getShellVersionWinPowerShell(FFstrbuf* exe, FFstrbuf* version)
}
#endif
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* exePath, FFstrbuf* version)
{
if (!instance.config.general.detectVersion) return false;
@@ -211,9 +247,9 @@ bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
return false;
if(ffStrEqualsIgnCase(exeName, "bash"))
return getShellVersionBash(exe, version);
return getShellVersionBash(exe, exePath, version);
if(ffStrEqualsIgnCase(exeName, "zsh"))
return getExeVersionGeneral(exe, version); //zsh 5.9 (arm-apple-darwin21.3.0)
return getShellVersionZsh(exe, exePath, version);
if(ffStrEqualsIgnCase(exeName, "fish"))
return getShellVersionFish(exe, version);
if(ffStrEqualsIgnCase(exeName, "pwsh"))
@@ -251,7 +287,7 @@ FF_MAYBE_UNUSED static bool getTerminalVersionTermux(FFstrbuf* version)
return version->length > 0;
}
static bool extractGnomeTerminalVersion(const char *str, FF_MAYBE_UNUSED uint32_t len, void *userdata)
static bool extractGeneralVersion(const char *str, FF_MAYBE_UNUSED uint32_t len, void *userdata)
{
if (!ffCharIsDigit(str[0])) return true;
int count = 0;
@@ -265,7 +301,7 @@ FF_MAYBE_UNUSED static bool getTerminalVersionGnome(FFstrbuf* exe, FFstrbuf* ver
{
if (exe->chars[0] == '/')
{
ffBinaryExtractStrings(exe->chars, extractGnomeTerminalVersion, version);
ffBinaryExtractStrings(exe->chars, extractGeneralVersion, version, (uint32_t) strlen("0.0.0"));
if (version->length) return true;
}
@@ -281,6 +317,17 @@ FF_MAYBE_UNUSED static bool getTerminalVersionGnome(FFstrbuf* exe, FFstrbuf* ver
return true;
}
FF_MAYBE_UNUSED static bool getTerminalVersionXfce4Terminal(FFstrbuf* exe, FFstrbuf* version)
{
if (exe->chars[0] == '/')
{
ffBinaryExtractStrings(exe->chars, extractGeneralVersion, version, (uint32_t) strlen("0.0.0"));
if (version->length) return true;
}
return getExeVersionGeneral(exe, version);//xfce4-terminal 1.0.4 (Xfce 4.18)...
}
FF_MAYBE_UNUSED static bool getTerminalVersionKgx(FFstrbuf* version)
{
if(ffProcessAppendStdOut(version, (char* const[]){
@@ -616,7 +663,7 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe
return getExeVersionGeneral(exe, version);//yakuake 22.12.3
if(ffStrbufIgnCaseEqualS(processName, "xfce4-terminal"))
return getExeVersionGeneral(exe, version);//xfce4-terminal 1.0.4 (Xfce 4.18)...
return getTerminalVersionXfce4Terminal(exe, version);
if(ffStrbufIgnCaseEqualS(processName, "terminator"))
return getExeVersionGeneral(exe, version);//terminator 2.1.3
@@ -274,14 +274,14 @@ static void getUserShellFromEnv(FFShellResult* result)
}
}
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version);
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* exePath, FFstrbuf* version);
bool fftsGetTerminalVersion(FFstrbuf* processName, FFstrbuf* exe, FFstrbuf* version);
static void setShellInfoDetails(FFShellResult* result)
{
ffStrbufClear(&result->version);
fftsGetShellVersion(&result->exe, result->exeName, &result->version);
fftsGetShellVersion(&result->exe, result->exeName, &result->exePath, &result->version);
if(ffStrbufEqualS(&result->processName, "pwsh"))
ffStrbufInitStatic(&result->prettyName, "PowerShell");
@@ -38,7 +38,7 @@ static bool getProductVersion(const wchar_t* filePath, FFstrbuf* version)
return false;
}
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version);
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, const FFstrbuf* exePath, FFstrbuf* version);
static uint32_t getShellInfo(FFShellResult* result, uint32_t pid)
{
@@ -359,7 +359,7 @@ const FFShellResult* ffDetectShell(void)
strcpy(tmp, result.exeName);
char* ext = strrchr(tmp, '.');
if (ext) *ext = '\0';
fftsGetShellVersion(&result.exe, tmp, &result.version);
fftsGetShellVersion(&result.exe, tmp, &result.exePath, &result.version);
}
return &result;
+89
View File
@@ -0,0 +1,89 @@
#pragma once
#include "fastfetch.h"
// From https://github.com/openzfs/zfs/blob/master/include/libzfs.h
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
typedef enum {
ZPOOL_PROP_INVAL = -1,
ZPOOL_PROP_NAME,
ZPOOL_PROP_SIZE,
ZPOOL_PROP_CAPACITY,
ZPOOL_PROP_ALTROOT,
ZPOOL_PROP_HEALTH,
ZPOOL_PROP_GUID,
ZPOOL_PROP_VERSION,
ZPOOL_PROP_BOOTFS,
ZPOOL_PROP_DELEGATION,
ZPOOL_PROP_AUTOREPLACE,
ZPOOL_PROP_CACHEFILE,
ZPOOL_PROP_FAILUREMODE,
ZPOOL_PROP_LISTSNAPS,
ZPOOL_PROP_AUTOEXPAND,
ZPOOL_PROP_DEDUPDITTO,
ZPOOL_PROP_DEDUPRATIO,
ZPOOL_PROP_FREE,
ZPOOL_PROP_ALLOCATED,
ZPOOL_PROP_READONLY,
ZPOOL_PROP_ASHIFT,
ZPOOL_PROP_COMMENT,
ZPOOL_PROP_EXPANDSZ,
ZPOOL_PROP_FREEING,
ZPOOL_PROP_FRAGMENTATION,
ZPOOL_PROP_LEAKED,
ZPOOL_PROP_MAXBLOCKSIZE,
ZPOOL_PROP_TNAME,
ZPOOL_PROP_MAXDNODESIZE,
ZPOOL_PROP_MULTIHOST,
ZPOOL_PROP_CHECKPOINT,
ZPOOL_PROP_LOAD_GUID,
ZPOOL_PROP_AUTOTRIM,
ZPOOL_PROP_COMPATIBILITY,
ZPOOL_PROP_BCLONEUSED,
ZPOOL_PROP_BCLONESAVED,
ZPOOL_PROP_BCLONERATIO,
ZPOOL_NUM_PROPS
} zpool_prop_t;
typedef enum {
ZPROP_SRC_NONE = 0x1,
ZPROP_SRC_DEFAULT = 0x2,
ZPROP_SRC_TEMPORARY = 0x4,
ZPROP_SRC_LOCAL = 0x8,
ZPROP_SRC_INHERITED = 0x10,
ZPROP_SRC_RECEIVED = 0x20
} zprop_source_t;
typedef bool boolean_t;
typedef struct libzfs_handle libzfs_handle_t;
typedef struct zpool_handle zpool_handle_t;
typedef int (*zpool_iter_f)(zpool_handle_t *, void *);
extern int zpool_iter(libzfs_handle_t *, zpool_iter_f, void *);
extern libzfs_handle_t *libzfs_init(void);
extern void libzfs_fini(libzfs_handle_t *);
extern uint64_t zpool_get_prop_int(zpool_handle_t *, zpool_prop_t, zprop_source_t *);
extern const char *zpool_get_name(zpool_handle_t *);
extern const char *zpool_get_state_str(zpool_handle_t *);
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include "fastfetch.h"
typedef struct FFZpoolResult
{
FFstrbuf name;
FFstrbuf state;
uint64_t used;
uint64_t total;
uint64_t version;
uint64_t fragmentation;
} FFZpoolResult;
const char* ffDetectZpool(FFlist* result /* list of FFZpoolResult */);
+111
View File
@@ -0,0 +1,111 @@
#include "zpool.h"
#ifdef FF_HAVE_LIBZFS
#ifdef __sun
#define FF_DISABLE_DLOPEN
#include <libzfs.h>
const char* zpool_get_state_str(zpool_handle_t* zpool)
{
if (zpool_get_state(zpool) == POOL_STATE_UNAVAIL)
return "FAULTED";
else
{
const char *str;
zpool_errata_t errata;
zpool_status_t status = zpool_get_status(zpool, (char**) &str, &errata);
if (status == ZPOOL_STATUS_IO_FAILURE_WAIT ||
status == ZPOOL_STATUS_IO_FAILURE_CONTINUE ||
status == ZPOOL_STATUS_IO_FAILURE_MMP)
return "SUSPENDED";
else
{
nvlist_t *nvroot = fnvlist_lookup_nvlist(zpool_get_config(zpool, NULL), ZPOOL_CONFIG_VDEV_TREE);
uint_t vsc;
vdev_stat_t *vs;
#ifdef __x86_64__
if (nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS, (uint64_t**) &vs, &vsc) != 0)
#else
if (nvlist_lookup_uint32_array(nvroot, ZPOOL_CONFIG_VDEV_STATS, (uint32_t**) &vs, &vsc) != 0)
#endif
return "UNKNOWN";
else
return zpool_state_to_name(vs->vs_state, vs->vs_aux);
}
}
}
#else
#include "libzfs_simplified.h"
#endif
#include "common/library.h"
typedef struct FFZfsData
{
FF_LIBRARY_SYMBOL(libzfs_fini)
FF_LIBRARY_SYMBOL(zpool_iter)
FF_LIBRARY_SYMBOL(zpool_get_prop_int)
FF_LIBRARY_SYMBOL(zpool_get_name)
FF_LIBRARY_SYMBOL(zpool_get_state_str)
libzfs_handle_t* handle;
FFlist* result;
} FFZfsData;
static inline void cleanLibzfs(FFZfsData* data)
{
if (data->fflibzfs_fini && data->handle)
{
data->fflibzfs_fini(data->handle);
data->handle = NULL;
}
}
static int enumZpoolCallback(zpool_handle_t* zpool, void* param)
{
FFZfsData* data = (FFZfsData*) param;
zprop_source_t source;
FFZpoolResult* item = ffListAdd(data->result);
ffStrbufInitS(&item->name, data->ffzpool_get_name(zpool));
ffStrbufInitS(&item->state, data->ffzpool_get_state_str(zpool));
item->version = data->ffzpool_get_prop_int(zpool, ZPOOL_PROP_VERSION, &source);
item->total = data->ffzpool_get_prop_int(zpool, ZPOOL_PROP_SIZE, &source);
item->used = item->total - data->ffzpool_get_prop_int(zpool, ZPOOL_PROP_FREE, &source);
item->fragmentation = data->ffzpool_get_prop_int(zpool, ZPOOL_PROP_FRAGMENTATION, &source);
return 0;
}
const char* ffDetectZpool(FFlist* result /* list of FFZpoolResult */)
{
FF_LIBRARY_LOAD(libzfs, NULL, "dlopen libzfs" FF_LIBRARY_EXTENSION " failed", "libzfs" FF_LIBRARY_EXTENSION, 4);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libzfs, libzfs_init);
libzfs_handle_t* handle = fflibzfs_init();
if (!handle) return "libzfs_init() failed";
__attribute__((__cleanup__(cleanLibzfs))) FFZfsData data = {
.handle = handle,
.result = result,
};
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libzfs, zpool_iter);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, libzfs_fini);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, zpool_get_prop_int);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, zpool_get_name);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, zpool_get_state_str);
if (ffzpool_iter(handle, enumZpoolCallback, &data) < 0)
return "zpool_iter() failed";
return NULL;
}
#else
const char* ffDetectZpool(FF_MAYBE_UNUSED FFlist* result)
{
return "Fastfetch was compiled without libzfs support";
}
#endif
+6
View File
@@ -0,0 +1,6 @@
#include "zpool.h"
const char* ffDetectZpool(FF_MAYBE_UNUSED FFlist* result /* list of FFZpoolResult */)
{
return "Not supported on this platform";
}
+19 -19
View File
@@ -1,19 +1,19 @@
${c1} ___________
/ \
/ ${c2}______${c1} \
/ ${c2}/ \${c1} \
| ${c2}( )${c1} \
/ ${c2}\______/${c1} |
| |
/ \
| |
| |
/ |
| |
| _______ |
____/ / \ |
/ | | |
| / ____/ |
\_________/ / |
\ __/
\_______/
___________
/ \
/ ${c2}______${c1} \
/ ${c2}/ \${c1} \
| ${c2}( )${c1} \
/ ${c2}\______/${c1} |
| |
/ \
| |
| |
/ |
| |
| _______ |
____/ / \ |
/ | | |
| / ____/ |
\_________/ / |
\ __/
\_______/
+24
View File
@@ -0,0 +1,24 @@
ti
jGGGGj
tGGGGGGt
,LGGLGGGGGGGG,
jGGGGjGGGGGGGGGj
GGGGGGGGGGGGGGGGGGGG
iGGGGGGt tLLLLLLi
,GGGGGi iGGGGG,
,jGGGG LGGGG,
,LjGGj LLLL,
,LLGG. iiii.
,LLj
,LLj jLL,
,LLLL. GGLL,
,LLLLt GGLL,
,LGGGG LGGGj,
,GGGGGi iGGGGG,
iGGGGGGj tGGGGGG,
GGGGGGGGGGGGGGGGGGGG
jGGGGGGGGGjGGGGj
,LGGGGGGGGGGG,
tGGGGGGt
jGGGGj
it
+19
View File
@@ -0,0 +1,19 @@
${c2}@
@@--=====@@
@@--==@@ @@====+@
@-@@ @==@
@=@
@=@${c1} @=@ @-==== @=@${c2}
@=@${c1} @-===@==++@===+@${c2}
@=@${c1} @--====@@=====+@${c2}
-=@${c1} @--==========++@${c2}
==${c1} @--==========++@${c2} @=@
@==${c1} @--=======@==++@${c2} @=+@
@==${c1} @-==========++${c2} @=@
@==${c1} @-=======@=%${c2} @=@
@==${c1} @@@@@@${c2} @=@
@====@@@ @@===+%
@@=====@@==++++@@
=#@=@
@==@++@
@@@
+24
View File
@@ -0,0 +1,24 @@
$2 .xXK0kdc'..
.OMMMMWNK0Odc'.
.OMMMMMMMMMMWNOl'.
.OMMMMMMMMMMMMMWXx;.
.:ddk0XWMMMMMMMMMMNx'
..;oxONMMMMMMMWKc.
$1 ..,;::::;,'.$2 .;xXMMMMMMMNo.
$1 .':looooooooool:,..$2 .;OWMMMMMMNl.
$1 .:oooooooooooooooooc'$2 .xWMMMMMMK:
$1 'coooooooooooooooooool,$2 'OMMMMMMWx.
$1.coooooooooooooooooooool.$2 cNMMMMMM0,
$1'loooooooooooooooooooooo,$2 ,KMMMMMMX:
$1'loooooooooooooooooooooo,$2 ,KMMMMMMX:
$1.:oooooooooooooooooooooc.$2 lNMMMMMM0,
$1 .coooooooooooooooooool'$2 ,0MMMMMMWd.
$1 .:looooooooooooooolc.$2 'OWMMMMMMK;
$1 ..;cloooooooooc;'..$2 .c0WMMMMMMXc.
$1 ..',;;;;,'..$2 ..cONMMMMMMMXc.
..,cxOKWMMMMMMMW0;.
.cxk0KNWMMMMMMMMMWXo.
.OMMMMMMMMMMMMMWKo'
.OMMMMMMMMMMWKx:.
.OMMMWNX0Oxl;.
.o0Oxoc,..
+5
View File
@@ -0,0 +1,5 @@
$2__
\
$1## $2\
$1## $2/
__/
+20 -20
View File
@@ -1,20 +1,20 @@
....
.',:clooo: .:looooo:.
.;looooooooc .oooooooooo'
.;looooool:,''. :ooooooooooc
;looool;. 'oooooooooo,
;clool' .cooooooc. ,,
... ...... .:oo,
.;clol:,. .loooo'
:ooooooooo, 'ooool
'ooooooooooo. loooo.
'ooooooooool coooo.
,loooooooc. .loooo.
.,;;;'. ;ooooc
... ,ooool.
.cooooc. ..',,'. .cooo.
;ooooo:. ;oooooooc. :l.
.coooooc,.. coooooooooo.
.:ooooooolc:. .ooooooooooo'
.':loooooo; ,oooooooooc
..';::c' .;loooo:'
....
$2.',:clooo: $1.:looooo:.
$2.;looooooooc $1.oooooooooo'
$2.;looooool:,''. $1:ooooooooooc
$2;looool;. $1'oooooooooo,
$2;clool' $1.cooooooc. $2,,
$2... $1...... $2.:oo,
$1.;clol:,. $2.loooo'
$1:ooooooooo, $2'ooool
$1'ooooooooooo. $2loooo.
$1'ooooooooool $2coooo.
$1,loooooooc. $2.loooo.
$1.,;;;'. $2;ooooc
$2... $2,ooool.
$2.cooooc. $1..',,'. $2.cooo.
$2;ooooo:. $1;oooooooc. $2:l.
$2.coooooc,.. $1coooooooooo.
$2.:ooooooolc:. $1.ooooooooooo'
$2.':loooooo; $1,oooooooooc
$2..';::c' $1.;loooo:'
-11
View File
@@ -1,11 +0,0 @@
..;,; .,;,.
.,lool: .ooooo,
;oo;: .coool.
.... ''' ,l;
:oooo, 'oo.
looooc :oo'
'::' ,oo:
,., .... co,
lo:;. :oooo; .
':ooo; cooooc
''' ''''
+5 -5
View File
@@ -3,16 +3,16 @@
-+ssssssssssssssssssyyssss+-
.ossssssssssssssssssd$2MMMNy$1sssso.
/sssssssssss$2hdmmNNmmyNMMMMh$1ssssss/
+sssssssss$2hmydMMMMMMMNddddy$1ssssssss+
/ssssssss$2hNMMMyhhyyyyhmNMMMNh$1ssssssss/
+sssssssss$2hm$1yd$2MMMMMMMNddddy$1ssssssss+
/ssssssss$2hNMMM$1yh$2hyyyyhmNMMMNh$1ssssssss/
.ssssssss$2dMMMNh$1ssssssssss$2hNMMMd$1ssssssss.
+ssss$2hhhyNMMNy$1ssssssssssss$2yNMMMy$1sssssss+
oss$2yNMMMNyMMh$1ssssssssssssss$2hmmmh$1ssssssso
oss$2yNMMMNyMMh$1ssssssssssssss$2hmmmh$1ssssssso
oss$2yNMMMNyMMh$1sssssssssssssshmmmhssssssso
+ssss$2hhhyNMMNy$1ssssssssssss$2yNMMMy$1sssssss+
.ssssssss$2dMMMNh$1ssssssssss$2hNMMMd$1ssssssss.
/ssssssss$2hNMMMyhhyyyyhdNMMMNh$1ssssssss/
+sssssssss$2dmydMMMMMMMMddddy$1ssssssss+
/ssssssss$2hNMMM$1yh$2hyyyyhdNMMMNh$1ssssssss/
+sssssssss$2dm$1yd$2MMMMMMMMddddy$1ssssssss+
/sssssssssss$2hdmNNNNmyNMMMMh$1ssssss/
.ossssssssssssssssss$2dMMMNy$1sssso.
-+sssssssssssssssss$2yyy$1ssss+-
+6
View File
@@ -0,0 +1,6 @@
_
---(_)
_/ --- \
(_) | |
\ --- _/
---(_)
+11 -6
View File
@@ -1,6 +1,11 @@
_
---(_)
_/ --- \
(_) | |
\ --- _/
---(_)
$2..;,; $1.,;,.
$2.,lool: $1.ooooo,
$2;oo;: $1.coool.
$1.... $1''' $2,l;
$1:oooo, $2'oo.
$1looooc $2:oo'
$1'::' $2,oo:
$2,., $1.... $2co,
$2lo:;. $1:oooo; $2.
$2':ooo; $1cooooc
$2''' $1''''
+99 -46
View File
@@ -1987,6 +1987,16 @@ static const FFlogo H[] = {
FF_COLOR_FG_256 "123",
},
},
// Huawei Cloud EulerOS
{
.names = {"Huawei Cloud EulerOS", "hce"},
.lines = FASTFETCH_DATATEXT_LOGO_HCE,
.colors = {
FF_COLOR_FG_RED,
},
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// Huayra
{
.names = {"Huayra"},
@@ -2623,6 +2633,17 @@ static const FFlogo M[] = {
.colorKeys = FF_COLOR_FG_CYAN,
.colorTitle = FF_COLOR_FG_WHITE,
},
// Magix
{
.names = {"Magix","MagixOS"},
.lines = FASTFETCH_DATATEXT_LOGO_MAGIX,
.colors = {
FF_COLOR_FG_LIGHT_MAGENTA,
FF_COLOR_FG_CYAN,
},
.colorKeys = FF_COLOR_FG_CYAN,
.colorTitle = FF_COLOR_FG_LIGHT_MAGENTA,
},
// MagpieOS
{
.names = {"MagpieOS", "Magpie"},
@@ -4127,7 +4148,7 @@ static const FFlogo S[] = {
},
// SteamOS
{
.names = {"steamos"},
.names = {"SteamOS"},
.lines = FASTFETCH_DATATEXT_LOGO_STEAMOS,
.colors = {
FF_COLOR_FG_BLUE,
@@ -4136,6 +4157,39 @@ static const FFlogo S[] = {
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE,
},
// Steam Deck
{
.names = {"SteamDeck"},
.lines = FASTFETCH_DATATEXT_LOGO_STEAMDECK,
.colors = {
FF_COLOR_FG_BLUE,
FF_COLOR_FG_WHITE
},
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE,
},
// Steam Deck Small
{
.names = {"SteamDeck_small"},
.lines = FASTFETCH_DATATEXT_LOGO_STEAMDECK_SMALL,
.colors = {
FF_COLOR_FG_BLUE,
FF_COLOR_FG_WHITE
},
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE,
},
// Steam Deck OLED
{
.names = {"SteamDeckOled"},
.lines = FASTFETCH_DATATEXT_LOGO_STEAMDECK,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_WHITE
},
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// Sulin
{
.names = {"Sulin"},
@@ -4273,6 +4327,26 @@ static const FFlogo U[] = {
{
.names = {"ubuntu", "ubuntu-linux"},
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_RED,
},
},
// UbuntuSmall
{
.names = {"ubuntu_small", "ubuntu-linux-small"},
.type = FF_LOGO_LINE_TYPE_SMALL_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_SMALL,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_RED,
},
},
// UbuntuOld
{
.names = {"ubuntu_old", "ubuntu-linux_old"},
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_OLD,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_WHITE,
@@ -4280,6 +4354,30 @@ static const FFlogo U[] = {
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// UbuntuOld2
{
.names = {"ubuntu_old2"},
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_OLD2,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_WHITE,
FF_COLOR_FG_YELLOW,
},
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// UbuntuOld2Small
{
.names = {"ubuntu_old2_small", "ubuntu_old2-small"},
.type = FF_LOGO_LINE_TYPE_SMALL_BIT | FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_OLD2_SMALL,
.colors = {
FF_COLOR_FG_RED,
},
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// UbuntuBudgie
{
.names = {"ubuntu budgie", "ubuntu-budgie"},
@@ -4337,18 +4435,6 @@ static const FFlogo U[] = {
.colorKeys = FF_COLOR_FG_GREEN,
.colorTitle = FF_COLOR_FG_WHITE,
},
// UbuntuOld
{
.names = {"ubuntu_old", "ubuntu-linux_old"},
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_OLD,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_WHITE,
},
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// UbuntuKde
{
.names = {"ubuntu kde", "ubuntu-kde", "ubuntu-plasma"},
@@ -4360,17 +4446,6 @@ static const FFlogo U[] = {
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE,
},
// UbuntuSmall
{
.names = {"ubuntu_small", "ubuntu-linux-small"},
.type = FF_LOGO_LINE_TYPE_SMALL_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_SMALL,
.colors = {
FF_COLOR_FG_RED,
},
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// UbuntuStudio
{
.names = {"ubuntu studio", "ubuntu-studio"},
@@ -4407,28 +4482,6 @@ static const FFlogo U[] = {
FF_COLOR_FG_WHITE,
},
},
// Ubuntu2Small
{
.names = {"ubuntu2_small", "ubuntu2-small"},
.type = FF_LOGO_LINE_TYPE_SMALL_BIT | FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU2_SMALL,
.colors = {
FF_COLOR_FG_RED,
},
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// Ubuntu2Old
{
.names = {"ubuntu2_old"},
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU2_OLD,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_WHITE,
FF_COLOR_FG_YELLOW,
},
},
// Ultramarine
{
.names = {"Ultramarine", "Ultramarine Linux"},
+4
View File
@@ -83,6 +83,8 @@ static bool printImageIterm(bool printError)
fprintf(stderr, "\nLogo (iterm): fail to query cursor position: %s\n", error);
return true; // We already printed image logo, don't print ascii logo then
}
if (X < options->paddingLeft + options->width)
X = (uint16_t) (options->paddingLeft + options->width);
if (options->position == FF_LOGO_POSITION_LEFT)
instance.state.logoWidth = X + options->paddingRight - 1;
instance.state.logoHeight = Y;
@@ -207,6 +209,8 @@ static bool printImageKittyDirect(bool printError)
fprintf(stderr, "\nLogo (kitty-direct): fail to query cursor position: %s\n", error);
return true; // We already printed image logo, don't print ascii logo then
}
if (X < options->paddingLeft + options->width)
X = (uint16_t) (options->paddingLeft + options->width);
if (options->position == FF_LOGO_POSITION_LEFT)
instance.state.logoWidth = X + options->paddingRight - 1;
instance.state.logoHeight = Y;
+19 -2
View File
@@ -11,9 +11,26 @@
static void printBattery(FFBatteryOptions* options, FFBatteryResult* result, uint8_t index)
{
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
if (options->moduleArgs.key.length == 0)
{
if (result->modelName.length > 0)
ffStrbufSetF(&key, "%s (%s)", FF_BATTERY_MODULE_NAME, result->modelName.chars);
else
ffStrbufSetS(&key, FF_BATTERY_MODULE_NAME);
}
else
{
ffStrbufClear(&key);
FF_PARSE_FORMAT_STRING_CHECKED(&key, &options->moduleArgs.key, 2, ((FFformatarg[]){
{FF_FORMAT_ARG_TYPE_UINT8, &index, "index"},
{FF_FORMAT_ARG_TYPE_STRBUF, &result->modelName, "name"},
}));
}
if(options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(FF_BATTERY_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
ffPrintLogoAndKey(key.chars, index, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY);
FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate();
bool showStatus =
@@ -63,7 +80,7 @@ static void printBattery(FFBatteryOptions* options, FFBatteryResult* result, uin
ffPercentAppendBar(&capacityBar, result->capacity, options->percent, &options->moduleArgs);
FF_STRBUF_AUTO_DESTROY tempStr = ffStrbufCreate();
ffTempsAppendNum(result->temperature, &tempStr, options->tempConfig, &options->moduleArgs);
FF_PRINT_FORMAT_CHECKED(FF_BATTERY_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_BATTERY_NUM_FORMAT_ARGS, ((FFformatarg[]) {
FF_PRINT_FORMAT_CHECKED(key.chars, index, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_BATTERY_NUM_FORMAT_ARGS, ((FFformatarg[]) {
{FF_FORMAT_ARG_TYPE_STRBUF, &result->manufacturer, "manufacturer"},
{FF_FORMAT_ARG_TYPE_STRBUF, &result->modelName, "model-name"},
{FF_FORMAT_ARG_TYPE_STRBUF, &result->technology, "technology"},
+1
View File
@@ -70,3 +70,4 @@
#include "modules/wifi/wifi.h"
#include "modules/wm/wm.h"
#include "modules/wmtheme/wmtheme.h"
#include "modules/zpool/zpool.h"
+1 -1
View File
@@ -68,7 +68,7 @@ void ffPrintNetIO(FFNetIOOptions* options)
if (!options->detectTotal) ffStrbufAppendS(&buffer, "/s");
ffStrbufAppendS(&buffer, " (OUT)");
if (inf->defaultRoute)
if (inf->defaultRoute && !options->defaultRouteOnly)
ffStrbufAppendS(&buffer, " *");
ffStrbufPutTo(&buffer, stdout);
}
+1
View File
@@ -70,3 +70,4 @@
#include "modules/wifi/option.h"
#include "modules/wm/option.h"
#include "modules/wmtheme/option.h"
#include "modules/zpool/option.h"
+14
View File
@@ -0,0 +1,14 @@
#pragma once
// This file will be included in "fastfetch.h", do NOT put unnecessary things here
#include "common/option.h"
#include "common/percent.h"
typedef struct FFZpoolOptions
{
FFModuleBaseInfo moduleInfo;
FFModuleArgs moduleArgs;
FFColorRangeConfig percent;
} FFZpoolOptions;
+214
View File
@@ -0,0 +1,214 @@
#include "common/printing.h"
#include "common/jsonconfig.h"
#include "common/percent.h"
#include "detection/zpool/zpool.h"
#include "modules/zpool/zpool.h"
#include "util/stringUtils.h"
#define FF_ZPOOL_NUM_FORMAT_ARGS 8
static void printZpool(FFZpoolOptions* options, FFZpoolResult* result, uint8_t index)
{
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
if (options->moduleArgs.key.length == 0)
{
if (result->name.length > 0)
ffStrbufSetF(&buffer, "%s (%s)", FF_ZPOOL_MODULE_NAME, result->name.chars);
else
ffStrbufSetS(&buffer, FF_ZPOOL_MODULE_NAME);
}
else
{
ffStrbufClear(&buffer);
FF_PARSE_FORMAT_STRING_CHECKED(&buffer, &options->moduleArgs.key, 2, ((FFformatarg[]){
{FF_FORMAT_ARG_TYPE_UINT8, &index, "index"},
{FF_FORMAT_ARG_TYPE_STRBUF, &result->name, "name"},
}));
}
FF_STRBUF_AUTO_DESTROY usedPretty = ffStrbufCreate();
ffParseSize(result->used, &usedPretty);
FF_STRBUF_AUTO_DESTROY totalPretty = ffStrbufCreate();
ffParseSize(result->total, &totalPretty);
double bytesPercentage = result->total > 0 ? (double) result->used / (double) result->total * 100.0 : 0;
double fragPercentage = (double) result->fragmentation;
if(options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(buffer.chars, index, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY);
ffStrbufClear(&buffer);
ffStrbufSetF(&buffer, "%s / %s (", usedPretty.chars, totalPretty.chars);
ffPercentAppendNum(&buffer, bytesPercentage, options->percent, false, &options->moduleArgs);
ffStrbufAppendS(&buffer, ", ");
ffPercentAppendNum(&buffer, fragPercentage, options->percent, false, &options->moduleArgs);
ffStrbufAppendF(&buffer, " frag) - %s", result->state.chars);
ffStrbufPutTo(&buffer, stdout);
}
else
{
FF_STRBUF_AUTO_DESTROY bytesPercentageNum = ffStrbufCreate();
ffPercentAppendNum(&bytesPercentageNum, bytesPercentage, options->percent, false, &options->moduleArgs);
FF_STRBUF_AUTO_DESTROY bytesPercentageBar = ffStrbufCreate();
ffPercentAppendBar(&bytesPercentageBar, bytesPercentage, options->percent, &options->moduleArgs);
FF_STRBUF_AUTO_DESTROY fragPercentageNum = ffStrbufCreate();
ffPercentAppendNum(&fragPercentageNum, fragPercentage, options->percent, false, &options->moduleArgs);
FF_STRBUF_AUTO_DESTROY fragPercentageBar = ffStrbufCreate();
ffPercentAppendBar(&fragPercentageBar, fragPercentage, options->percent, &options->moduleArgs);
FF_PRINT_FORMAT_CHECKED(buffer.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_ZPOOL_NUM_FORMAT_ARGS, ((FFformatarg[]) {
{FF_FORMAT_ARG_TYPE_STRBUF, &result->name, "name"},
{FF_FORMAT_ARG_TYPE_STRBUF, &result->state, "state"},
{FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty, "size-used"},
{FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty, "size-total"},
{FF_FORMAT_ARG_TYPE_STRBUF, &bytesPercentageNum, "size-percentage"},
{FF_FORMAT_ARG_TYPE_STRBUF, &fragPercentage, "frag-percentage"},
{FF_FORMAT_ARG_TYPE_STRBUF, &bytesPercentageBar, "size-percentage-bar"},
{FF_FORMAT_ARG_TYPE_STRBUF, &fragPercentageBar, "frag-percentage-bar"},
}));
}
}
void ffPrintZpool(FFZpoolOptions* options)
{
FF_LIST_AUTO_DESTROY results = ffListCreate(sizeof(FFZpoolResult));
const char* error = ffDetectZpool(&results);
if (error)
{
ffPrintError(FF_ZPOOL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", error);
return;
}
if(results.length == 0)
{
ffPrintError(FF_ZPOOL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", "No zpool found");
return;
}
for(uint32_t i = 0; i < results.length; i++)
{
FFZpoolResult* result = FF_LIST_GET(FFZpoolResult, results, i);
uint8_t index = results.length == 1 ? 0 : (uint8_t) (i + 1);
printZpool(options, result, index);
}
FF_LIST_FOR_EACH(FFZpoolResult, result, results)
{
ffStrbufDestroy(&result->name);
ffStrbufDestroy(&result->state);
}
}
bool ffParseZpoolCommandOptions(FFZpoolOptions* options, const char* key, const char* value)
{
const char* subKey = ffOptionTestPrefix(key, FF_ZPOOL_MODULE_NAME);
if (!subKey) return false;
if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs))
return true;
if (ffPercentParseCommandOptions(key, subKey, value, &options->percent))
return true;
return false;
}
void ffParseZpoolJsonObject(FFZpoolOptions* options, yyjson_val* module)
{
yyjson_val *key_, *val;
size_t idx, max;
yyjson_obj_foreach(module, idx, max, key_, val)
{
const char* key = yyjson_get_str(key_);
if(ffStrEqualsIgnCase(key, "type"))
continue;
if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs))
continue;
if (ffPercentParseJsonObject(key, val, &options->percent))
continue;
ffPrintError(FF_ZPOOL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Unknown JSON key %s", key);
}
}
void ffGenerateZpoolJsonConfig(FFZpoolOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
__attribute__((__cleanup__(ffDestroyZpoolOptions))) FFZpoolOptions defaultOptions;
ffInitZpoolOptions(&defaultOptions);
ffJsonConfigGenerateModuleArgsConfig(doc, module, &defaultOptions.moduleArgs, &options->moduleArgs);
ffPercentGenerateJsonConfig(doc, module, defaultOptions.percent, options->percent);
}
void ffGenerateZpoolJsonResult(FF_MAYBE_UNUSED FFZpoolOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
FF_LIST_AUTO_DESTROY results = ffListCreate(sizeof(FFZpoolResult));
const char* error = ffDetectZpool(&results);
if (error)
{
yyjson_mut_obj_add_str(doc, module, "error", error);
return;
}
yyjson_mut_val* arr = yyjson_mut_obj_add_arr(doc, module, "result");
FF_LIST_FOR_EACH(FFZpoolResult, zpool, results)
{
yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr);
yyjson_mut_obj_add_strbuf(doc, obj, "name", &zpool->name);
yyjson_mut_obj_add_strbuf(doc, obj, "state", &zpool->state);
yyjson_mut_obj_add_uint(doc, obj, "used", zpool->used);
yyjson_mut_obj_add_uint(doc, obj, "total", zpool->total);
yyjson_mut_obj_add_uint(doc, obj, "version", zpool->version);
yyjson_mut_obj_add_uint(doc, obj, "fragmentation", zpool->fragmentation);
}
FF_LIST_FOR_EACH(FFZpoolResult, battery, results)
{
ffStrbufDestroy(&battery->name);
ffStrbufDestroy(&battery->state);
}
}
void ffPrintZpoolHelpFormat(void)
{
FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_ZPOOL_MODULE_NAME, "{3} / {4} ({5}, {6} frag)", FF_ZPOOL_NUM_FORMAT_ARGS, ((const char* []) {
"Zpool name - name",
"Zpool state - state",
"Size used - size-used",
"Size total - size-total",
"Size percentage num - size-percentage",
"Fragmentation percentage num - frag-percentage",
"Size percentage bar - size-percentage-bar",
"Fragmentation percentage bar - frag-percentage-bar",
}));
}
void ffInitZpoolOptions(FFZpoolOptions* options)
{
ffOptionInitModuleBaseInfo(
&options->moduleInfo,
FF_ZPOOL_MODULE_NAME,
"Print ZFS storage pools",
ffParseZpoolCommandOptions,
ffParseZpoolJsonObject,
ffPrintZpool,
ffGenerateZpoolJsonResult,
ffPrintZpoolHelpFormat,
ffGenerateZpoolJsonConfig
);
ffOptionInitModuleArg(&options->moduleArgs, "󱑛");
options->percent = (FFColorRangeConfig) { 50, 80 };
}
void ffDestroyZpoolOptions(FFZpoolOptions* options)
{
ffOptionDestroyModuleArg(&options->moduleArgs);
}
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#include "fastfetch.h"
#define FF_ZPOOL_MODULE_NAME "Zpool"
void ffPrintZpool(FFZpoolOptions* options);
void ffInitZpoolOptions(FFZpoolOptions* options);
void ffDestroyZpoolOptions(FFZpoolOptions* options);
+2
View File
@@ -71,6 +71,7 @@ void ffOptionsInitModules(FFOptionsModules* options)
ffInitWallpaperOptions(&options->wallpaper);
ffInitWeatherOptions(&options->weather);
ffInitWifiOptions(&options->wifi);
ffInitZpoolOptions(&options->zpool);
}
void ffOptionsDestroyModules(FFOptionsModules* options)
@@ -143,4 +144,5 @@ void ffOptionsDestroyModules(FFOptionsModules* options)
ffDestroyWallpaperOptions(&options->wallpaper);
ffDestroyWeatherOptions(&options->weather);
ffDestroyWifiOptions(&options->wifi);
ffDestroyZpoolOptions(&options->zpool);
}
+1
View File
@@ -72,6 +72,7 @@ typedef struct FFOptionsModules
FFWallpaperOptions wallpaper;
FFWeatherOptions weather;
FFWifiOptions wifi;
FFZpoolOptions zpool;
} FFOptionsModules;
void ffOptionsInitModules(FFOptionsModules* options);
+1 -1
View File
@@ -2,4 +2,4 @@
#include "fastfetch.h"
const char* ffBinaryExtractStrings(const char* file, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata);
const char* ffBinaryExtractStrings(const char* file, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata, uint32_t minLength);
+10 -9
View File
@@ -20,7 +20,7 @@ static inline bool readData(FILE *objFile, void *buf, size_t size, off_t offset)
return fread(buf, 1, size, objFile) == size;
}
static bool handleMachSection(FILE *objFile, const char *name, off_t offset, size_t size, bool (*cb)(const char *str, uint32_t len, void *userdata), void *userdata)
static bool handleMachSection(FILE *objFile, const char *name, off_t offset, size_t size, bool (*cb)(const char *str, uint32_t len, void *userdata), void *userdata, uint32_t minLength)
{
if (!ffStrEquals(name, "__cstring")) return true;
@@ -33,6 +33,7 @@ static bool handleMachSection(FILE *objFile, const char *name, off_t offset, siz
const char* p = (const char*) data + off;
if (*p == '\0') continue;
uint32_t len = (uint32_t) strlen(p);
if (len < minLength) continue;
if (*p >= ' ' && *p <= '~') // Ignore control characters
{
if (!cb(p, len, userdata)) return false;
@@ -42,7 +43,7 @@ static bool handleMachSection(FILE *objFile, const char *name, off_t offset, siz
return true;
}
static const char* dumpMachHeader(FILE *objFile, off_t offset, bool is_64, bool (*cb)(const char *str, uint32_t len, void *userdata), void *userdata)
static const char* dumpMachHeader(FILE *objFile, off_t offset, bool is_64, bool (*cb)(const char *str, uint32_t len, void *userdata), void *userdata, uint32_t minLength)
{
uint32_t ncmds;
off_t loadCommandsOffset = offset;
@@ -87,7 +88,7 @@ static const char* dumpMachHeader(FILE *objFile, off_t offset, bool is_64, bool
if (!readData(objFile, &section, sizeof(section), (off_t) ((size_t) commandOffset + sizeof(segment) + j * sizeof(section))))
continue;
if (!handleMachSection(objFile, section.sectname, section.offset, section.size, cb, userdata))
if (!handleMachSection(objFile, section.sectname, section.offset, section.size, cb, userdata, minLength))
return NULL;
}
}
@@ -105,7 +106,7 @@ static const char* dumpMachHeader(FILE *objFile, off_t offset, bool is_64, bool
if (!readData(objFile, &section, sizeof(section), (off_t) ((size_t) commandOffset + sizeof(segment) + j * sizeof(section))))
continue;
if (!handleMachSection(objFile, section.sectname, section.offset, section.size, cb, userdata))
if (!handleMachSection(objFile, section.sectname, section.offset, section.size, cb, userdata, minLength))
return NULL;
}
}
@@ -116,7 +117,7 @@ static const char* dumpMachHeader(FILE *objFile, off_t offset, bool is_64, bool
return NULL;
}
static const char* dumpFatHeader(FILE *objFile, bool (*cb)(const char *str, uint32_t len, void *userdata), void *userdata)
static const char* dumpFatHeader(FILE *objFile, bool (*cb)(const char *str, uint32_t len, void *userdata), void *userdata, uint32_t minLength)
{
struct fat_header header;
if (!readData(objFile, &header, sizeof(header), 0))
@@ -157,14 +158,14 @@ static const char* dumpFatHeader(FILE *objFile, bool (*cb)(const char *str, uint
if (magic == MH_MAGIC_64 || magic == MH_MAGIC)
{
dumpMachHeader(objFile, machHeaderOffset, magic == MH_MAGIC_64, cb, userdata);
dumpMachHeader(objFile, machHeaderOffset, magic == MH_MAGIC_64, cb, userdata, minLength);
return NULL;
}
}
return "Unsupported fat header";
}
const char *ffBinaryExtractStrings(const char *machoFile, bool (*cb)(const char *str, uint32_t len, void *userdata), void *userdata)
const char *ffBinaryExtractStrings(const char *machoFile, bool (*cb)(const char *str, uint32_t len, void *userdata), void *userdata, uint32_t minLength)
{
FF_AUTO_CLOSE_FILE FILE *objFile = fopen(machoFile, "rb");
if (objFile == NULL)
@@ -180,7 +181,7 @@ const char *ffBinaryExtractStrings(const char *machoFile, bool (*cb)(const char
return "Unsupported format or big endian mach-o file";
if (magic == FAT_MAGIC || magic == FAT_MAGIC_64 || magic == FAT_CIGAM || magic == FAT_CIGAM_64)
return dumpFatHeader(objFile, cb, userdata);
return dumpFatHeader(objFile, cb, userdata, minLength);
else
return dumpMachHeader(objFile, 0, magic == MH_MAGIC_64, cb, userdata);
return dumpMachHeader(objFile, 0, magic == MH_MAGIC_64, cb, userdata, minLength);
}
+4 -3
View File
@@ -23,7 +23,7 @@ struct FFElfData {
bool inited;
} elfData;
const char* ffBinaryExtractStrings(const char* elfFile, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata)
const char* ffBinaryExtractStrings(const char* elfFile, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata, uint32_t minLength)
{
if (!elfData.inited)
{
@@ -82,6 +82,7 @@ const char* ffBinaryExtractStrings(const char* elfFile, bool (*cb)(const char* s
const char* p = (const char*) data->d_buf + off;
if (*p == '\0') continue;
uint32_t len = (uint32_t) strlen(p);
if (len < minLength) continue;
if (*p >= ' ' && *p <= '~') // Ignore control characters
{
if (!cb(p, len, userdata)) break;
@@ -98,9 +99,9 @@ const char* ffBinaryExtractStrings(const char* elfFile, bool (*cb)(const char* s
#else
const char* ffBinaryExtractStrings(const char* file, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata)
const char* ffBinaryExtractStrings(const char* file, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata, uint32_t minLength)
{
FF_UNUSED(file, cb, userdata);
FF_UNUSED(file, cb, userdata, minLength);
return "Fastfetch was built without libelf support";
}
+2 -1
View File
@@ -8,7 +8,7 @@
#include <stdlib.h>
#include <string.h>
const char* ffBinaryExtractStrings(const char *peFile, bool (*cb)(const char *str, uint32_t len, void *userdata), void *userdata)
const char* ffBinaryExtractStrings(const char *peFile, bool (*cb)(const char *str, uint32_t len, void *userdata), void *userdata, uint32_t minLength)
{
__attribute__((__cleanup__(UnMapAndLoad))) LOADED_IMAGE loadedImage = {};
if (!MapAndLoad(peFile, NULL, &loadedImage, FALSE, TRUE))
@@ -26,6 +26,7 @@ const char* ffBinaryExtractStrings(const char *peFile, bool (*cb)(const char *st
const char* p = (const char*) data + off;
if (*p == '\0') continue;
uint32_t len = (uint32_t) strlen(p);
if (len < minLength) continue;
if (*p >= ' ' && *p <= '~') // Ignore control characters
{
if (!cb(p, len, userdata)) break;
+80
View File
@@ -0,0 +1,80 @@
#include "common/format.h"
#include "util/textModifier.h"
#include "fastfetch.h"
static void verify(const char* format, const char* arg, const char* expected, int lineNo)
{
FF_STRBUF_AUTO_DESTROY result = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY formatter = ffStrbufCreateStatic(format);
const FFformatarg arguments[] = {
{ .type = FF_FORMAT_ARG_TYPE_STRING, arg }
};
ffParseFormatString(&result, &formatter, 1, arguments);
if (!ffStrbufEqualS(&result, expected))
{
fprintf(stderr, FASTFETCH_TEXT_MODIFIER_ERROR "[%d] %s: expected \"%s\", got \"%s\"\n" FASTFETCH_TEXT_MODIFIER_RESET, lineNo, format, expected, result.chars);
exit(1);
}
}
#define VERIFY(format, argument, expected) verify((format), (argument), (expected), __LINE__)
int main(void)
{
instance.config.display.pipe = true;
{
VERIFY("output({})", "12345 67890", "output(12345 67890)");
VERIFY("output({1})", "12345 67890", "output(12345 67890)");
VERIFY("output({})", "", "output()");
VERIFY("output({1})", "", "output()");
}
{
VERIFY("output({1:20})", "12345 67890", "output(12345 67890)");
VERIFY("output({1:11})", "12345 67890", "output(12345 67890)");
VERIFY("output({1:-11})", "12345 67890", "output(12345 67890)");
VERIFY("output({1:6})", "12345 67890", "output(12345)");
VERIFY("output({:6})", "12345 67890", "output(12345)");
VERIFY("output({:-6})", "12345 67890", "output(12345…)");
VERIFY("output({:0})", "12345 67890", "output()");
VERIFY("output({:})", "12345 67890", "output()");
}
{
VERIFY("output({1<20})", "12345 67890", "output(12345 67890 )");
VERIFY("output({1<-20})", "12345 67890", "output(12345 67890 )");
VERIFY("output({1<11})", "12345 67890", "output(12345 67890)");
VERIFY("output({1<-11})", "12345 67890", "output(12345 67890)");
VERIFY("output({1<6})", "12345 67890", "output(12345 )");
VERIFY("output({<6})", "12345 67890", "output(12345 )");
VERIFY("output({<-6})", "12345 67890", "output(12345…)");
VERIFY("output({<0})", "12345 67890", "output()");
VERIFY("output({<})", "12345 67890", "output()");
}
{
VERIFY("output({1>20})", "12345 67890", "output( 12345 67890)");
VERIFY("output({1>-20})", "12345 67890", "output( 12345 67890)");
VERIFY("output({1>11})", "12345 67890", "output(12345 67890)");
VERIFY("output({1>-11})", "12345 67890", "output(12345 67890)");
VERIFY("output({1>6})", "12345 67890", "output(12345 )");
VERIFY("output({>6})", "12345 67890", "output(12345 )");
VERIFY("output({>-6})", "12345 67890", "output(12345…)");
VERIFY("output({>0})", "12345 67890", "output()");
VERIFY("output({>})", "12345 67890", "output()");
}
{
VERIFY("output({1n>20})", "12345 67890", "output({1n>20})");
VERIFY("output({120})", "12345 67890", "output({120})");
VERIFY("output({1:11})", "", "output()");
}
{
VERIFY("output({1:20}{1<20}{1>20})", "12345 67890", "output(12345 6789012345 67890 12345 67890)");
}
//Success
puts("\033[32mAll tests passed!" FASTFETCH_TEXT_MODIFIER_RESET);
}