mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 18:32:10 +02:00
Compare commits
142 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 215029ea27 | |||
| 533f54fb73 | |||
| a6212c5b01 | |||
| ba76b18367 | |||
| 4290efb49d | |||
| 30b85fc169 | |||
| dc94ac8d0c | |||
| 1d9e612262 | |||
| be1791e386 | |||
| 3b8c2d6ee6 | |||
| c661e55053 | |||
| 56403bab5c | |||
| caef317ade | |||
| 131e01f35b | |||
| c8e3c6882a | |||
| c985bdbbfd | |||
| b80eb47ecd | |||
| 68942c1d3f | |||
| b36b74448f | |||
| 217bb6657e | |||
| df2862996b | |||
| df6ab6427e | |||
| 82d848727c | |||
| d0d6323b1f | |||
| 6439921f85 | |||
| d28907ee9d | |||
| 41f0971570 | |||
| ab0bd79bb8 | |||
| 07747aa819 | |||
| 68efcdd0dd | |||
| fef3100fd7 | |||
| 08a940bfd4 | |||
| d6a99c631e | |||
| 3d4077c2d0 | |||
| ce6b595421 | |||
| 7d8c085254 | |||
| ec0af17fb5 | |||
| 2accfbc894 | |||
| 01d2fa1228 | |||
| f16843d60f | |||
| acc77ebddd | |||
| 7eb145fb7f | |||
| 34a6eb13c6 | |||
| 0f5e746fe2 | |||
| b62ad16aa6 | |||
| f79498e4b5 | |||
| 31c433b353 | |||
| 852c6abf2e | |||
| df3fa6f8a8 | |||
| 738daa1c77 | |||
| 4204cfc500 | |||
| 9cb08d115a | |||
| 459f159b1b | |||
| 2880536513 | |||
| 64cb1bfdfd | |||
| b80c30ace3 | |||
| 19b8849bfc | |||
| 8f457f047c | |||
| 299bc7468f | |||
| c213b0769b | |||
| 260c883d07 | |||
| da0db042fa | |||
| ae5732e2a8 | |||
| 1f05a33807 | |||
| f090951abc | |||
| 855fd6edee | |||
| d4bd4401a8 | |||
| 689feb39a4 | |||
| 0f64e2830a | |||
| 3e24cdc752 | |||
| dc9c285a0b | |||
| 1d03c9c85e | |||
| 4eae11df64 | |||
| eba13d5485 | |||
| 16b875ef5a | |||
| 366138e1bd | |||
| 7fe18a5b7c | |||
| 39cd8cfb4c | |||
| 8b441c85e5 | |||
| f66e901c44 | |||
| 3815823a20 | |||
| 33ff4870dc | |||
| 479731f076 | |||
| d2f3f47457 | |||
| 5ea89ecba5 | |||
| 865f57bd76 | |||
| e98e2a3d52 | |||
| 6bb748869e | |||
| 654721b8c5 | |||
| 0542eac1b9 | |||
| b9faf8d77f | |||
| 61f848146a | |||
| 4175dfdc3a | |||
| 861d9006d7 | |||
| 7ba07bd2e0 | |||
| 9fee36a286 | |||
| 2fc9230b29 | |||
| 5fb1286e15 | |||
| a4cace4765 | |||
| c6d2467a83 | |||
| db0d38202e | |||
| 9fbb23b135 | |||
| 3a990e495b | |||
| 648530ee8f | |||
| b12a59cdaf | |||
| 83c1fe26e6 | |||
| 217f98a36c | |||
| 1011e21ba8 | |||
| 08c6a6e4cb | |||
| 5e9fcaf7ca | |||
| 8b838cef61 | |||
| 22d9d8e196 | |||
| a789b8330a | |||
| 903ecf37f7 | |||
| c4a876f6aa | |||
| 82285ebeb4 | |||
| 36dadcdc7f | |||
| 030c05429a | |||
| a462a12370 | |||
| b386365d95 | |||
| 158db9d7c7 | |||
| 407bfa8c95 | |||
| 1449290e9e | |||
| 4c0ea7354d | |||
| 71cba2451a | |||
| ef3b5df048 | |||
| 3e98034e55 | |||
| 1c89101522 | |||
| 757e6271ff | |||
| c5c846aa22 | |||
| 23a59a15ec | |||
| 4798c619d0 | |||
| 023e767237 | |||
| 688d9b00ab | |||
| c2fe2f70dc | |||
| 3430c10ec2 | |||
| 9afcc00201 | |||
| cd783d1267 | |||
| 81480532e2 | |||
| 982e8a0117 | |||
| 8af88a3376 | |||
| 9ed2f13c78 |
@@ -11,7 +11,7 @@ Tip: A logo can be displayed by fastfetch without getting into fastfetch's offic
|
||||
|
||||
# OS
|
||||
```
|
||||
Paste content of /etc/os-release here. If this file doesn't exist, describe a way to identify the distro.
|
||||
Paste content of /etc/os-release and /etc/lsb-release here. If none of these files exist, describe a way to identify the distro
|
||||
```
|
||||
|
||||
# Ascii
|
||||
|
||||
@@ -158,6 +158,45 @@ jobs:
|
||||
name: fastfetch-linux-aarch64
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
linux-armv7:
|
||||
name: Linux-armv7
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: run VM
|
||||
uses: uraimo/run-on-arch-action@v2
|
||||
id: runcmd
|
||||
with:
|
||||
arch: armv7
|
||||
distro: ubuntu20.04
|
||||
githubToken: ${{ github.token }}
|
||||
run: |
|
||||
uname -a
|
||||
apt-get update && apt-get install -y wget
|
||||
# CMake installed by apt has bug `list sub-command REMOVE_ITEM requires two or more arguments`
|
||||
wget --no-check-certificate https://apt.kitware.com/ubuntu/pool/main/c/cmake/{cmake_3.29.2-0kitware1ubuntu20.04.1_armhf.deb,cmake-data_3.29.2-0kitware1ubuntu20.04.1_all.deb}
|
||||
dpkg -i *.deb
|
||||
apt-get install -y make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev libdrm-dev directx-headers-dev rpm
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||
cmake --build . --target package --verbose -j4
|
||||
./fastfetch --list-features
|
||||
time ./fastfetch -c presets/ci.jsonc
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
ctest
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: fastfetch-linux-armv7
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
musl-amd64:
|
||||
name: Musl-amd64
|
||||
runs-on: ubuntu-latest
|
||||
@@ -501,6 +540,7 @@ jobs:
|
||||
needs:
|
||||
- linux-amd64
|
||||
- linux-aarch64
|
||||
- linux-armv7
|
||||
- musl-amd64
|
||||
- musl-aarch64
|
||||
- macos-universal
|
||||
|
||||
+116
@@ -1,3 +1,119 @@
|
||||
# 2.12.0
|
||||
|
||||
Changes:
|
||||
* The long deprecated flag based config files are removed.
|
||||
* They can still be used with `xargs fastfetch < /path/to/config.conf`
|
||||
* `--gen-config` can be used to migrate them to json based config files
|
||||
* The long deprecated options `--set` and `--set-keyless` are removed.
|
||||
* `Kernel` module now prints kernel name by default
|
||||
|
||||
Features:
|
||||
* Support `st` terminal font detection for font configuration compiled in `st` binary (TerminalFont, Linux)
|
||||
* Add option `--color-output` to change output color of all modules except `Title`, `Separator`
|
||||
* `display.color.output` in JSONC config file
|
||||
* Add option `--<module>-output-color` to change output color of one specified module, which overrides the global option `--color-output`
|
||||
* Add option `--publicip-ipv6` to print IPv6 address (PublicIP)
|
||||
* Add new module `Loadavg` to print load averages (Loadavg)
|
||||
* Add new module `PhysicalMemory` to print information of physical memory devices (PhysicalMemory)
|
||||
* Requires root permission to work on Linux and FreeBSD
|
||||
* Support specifying `--logo-width` only for `--kitty-direct` and `--iterm` (Logo)
|
||||
* Add option `--localip-show-all-ips` to show all IPs assigned to the same interface (LocalIP)
|
||||
* Default to `false`
|
||||
* Improve compatibility with `(*term)` (#909, Terminal, macOS)
|
||||
|
||||
Bugfixes:
|
||||
* Rename option `--temperature-unit` to `--temp-unit` as documented in help messages
|
||||
* Fix alternate logo doesn't work with `{ "type": "builtin" }` (#914, Logo)
|
||||
|
||||
Logos:
|
||||
* Fix DahliaOS detection
|
||||
* Add openSUSE Slowroll
|
||||
* Add macOS3
|
||||
* Add Quirinux
|
||||
|
||||
# 2.11.5
|
||||
|
||||
Bugfix:
|
||||
* Fix logo printing for OpenMandriva (#896)
|
||||
* Remove `--os-file` in help messages
|
||||
|
||||
# 2.11.4
|
||||
|
||||
Changes:
|
||||
* Fastfetch will print a colorless ascii logo in `--pipe` mode for better `lolcat` compatibility. `fastfetch | lolcat` should work and no `--pipe false` needed.
|
||||
* Previously the logo would be disabled in `--pipe` mode.
|
||||
* Use `--pipe -l none` to get the old beheavior
|
||||
* `--os-file` was removed and CMake option `-DCUSTOM_OS_RELEASE_PATH=/path/to/os-release` was introduced for configuring at compile time by package managers if needed. This option should not used in most cases.
|
||||
|
||||
Bugfixes:
|
||||
* Fix possible out-of-bound memory access (#868)
|
||||
* Fix Apple Terminal detection (#878, macOS, Terminal)
|
||||
* Fix deprecation warning for macOS 14.0 hopefully (#860, macOS, Camera)
|
||||
* Fix memory leaks when passing informative options (#888)
|
||||
* Fix JSON config `size.ndigits` doesn't work
|
||||
|
||||
Features:
|
||||
* Enable `--pipe` mode if environment variable `$NO_COLOR` is set
|
||||
* Support Armbian and Proxmox distro detection (OS, Linux)
|
||||
|
||||
Logo:
|
||||
* Add Armbian
|
||||
|
||||
# 2.11.3
|
||||
|
||||
Hotfix for nix (https://github.com/NixOS/nixpkgs/issues/308849#issuecomment-2093962376)
|
||||
|
||||
Features:
|
||||
* Add cmake option `CUSTOM_AMDGPU_IDS_PATH` for specifying custom path of `amdgpu.ids`
|
||||
|
||||
Bugfixes:
|
||||
* Fix hanging when detecting disconnected network drive (Disk, Windows)
|
||||
* Ensure line ending is printed when printing image logo errors (Logo)
|
||||
* Revert image logo limitation change in 2.11.2; allow image logo in SSH session and tmux again (#861, Logo)
|
||||
* Fix doubled output in custom formation (PhysicalDisk, Windows)
|
||||
|
||||
# 2.11.2
|
||||
|
||||
Hotfix for Debian 11
|
||||
|
||||
Changes:
|
||||
* Error messages when trying to print image logo will only be printed with `--show-errors`
|
||||
* When generating JSON output, fastfetch will generate an empty array when no result is detected, instead of an error.
|
||||
|
||||
Bugfixes:
|
||||
* Fix segfault in Debian 11 and some old kernels. Regression introduced in 2.11.0 (#845, GPU, Linux)
|
||||
* Don't try detecting version of raw `sh` shell (#849, Shell, Linux)
|
||||
* Trim `\r` on Windows
|
||||
|
||||
Features:
|
||||
* Check xdg state home for nix user packages (#837, Packages, Linux)
|
||||
* Disable image logos in ssh and tmux sessions (#839)
|
||||
* Support MX Linux distro detection (#847, OS, Linux)
|
||||
|
||||
Logo:
|
||||
* Add KernelOS
|
||||
* Fix name of DraugerOS
|
||||
* Add missing `FF_LOGO_LINE_TYPE_SMALL_BIT` flags
|
||||
* Add MX2
|
||||
|
||||
# 2.11.1
|
||||
|
||||
Hotfix for Android
|
||||
|
||||
Bugfixes:
|
||||
* Fix uninitialized variables which can cause crashes (#760 #838, Battery, Android)
|
||||
* Don't detect hyfetch as shell when used as backend of [hyfetch](https://github.com/hykilpikonna/hyfetch)
|
||||
* Fix incorrect information in man page (#828)
|
||||
|
||||
Features:
|
||||
* Support sorcery package manager detection (Packages, Linux)
|
||||
* Make `--custom-format` optional (Custom)
|
||||
* Make `/` an alias of `C:\` for `--disk-folders` (Disk, Windows)
|
||||
* Build for Linux armv7
|
||||
|
||||
Logo:
|
||||
* Fix colors of Source Mage logo
|
||||
|
||||
# 2.11.0
|
||||
|
||||
Changes:
|
||||
|
||||
+35
-4
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
||||
|
||||
project(fastfetch
|
||||
VERSION 2.11.0
|
||||
VERSION 2.12.0
|
||||
LANGUAGES C
|
||||
DESCRIPTION "Fast neofetch-like system information tool"
|
||||
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
|
||||
@@ -79,6 +79,8 @@ option(IS_MUSL "Build with musl libc" OFF) # Used by Github Actions
|
||||
|
||||
if (LINUX)
|
||||
set(CUSTOM_PCI_IDS_PATH "" CACHE STRING "Custom path to file pci.ids, defaults to `/usr/share/hwdata/pci.ids`")
|
||||
set(CUSTOM_AMDGPU_IDS_PATH "" CACHE STRING "Custom path to file amdgpu.ids, defaults to `/usr/share/libdrm/amdgpu.ids`")
|
||||
set(CUSTOM_OS_RELEASE_PATH "" CACHE STRING "Custom path to file os-release, defaults to `/etc/os-release`")
|
||||
endif()
|
||||
|
||||
####################
|
||||
@@ -295,6 +297,7 @@ set(LIBFASTFETCH_SRC
|
||||
src/detection/opencl/opencl.c
|
||||
src/detection/os/os.c
|
||||
src/detection/packages/packages.c
|
||||
src/detection/physicalmemory/physicalmemory.c
|
||||
src/detection/publicip/publicip.c
|
||||
src/detection/terminaltheme/terminaltheme.c
|
||||
src/detection/terminalfont/terminalfont.c
|
||||
@@ -332,6 +335,7 @@ set(LIBFASTFETCH_SRC
|
||||
src/modules/gamepad/gamepad.c
|
||||
src/modules/kernel/kernel.c
|
||||
src/modules/lm/lm.c
|
||||
src/modules/loadavg/loadavg.c
|
||||
src/modules/locale/locale.c
|
||||
src/modules/localip/localip.c
|
||||
src/modules/memory/memory.c
|
||||
@@ -342,6 +346,7 @@ set(LIBFASTFETCH_SRC
|
||||
src/modules/os/os.c
|
||||
src/modules/packages/packages.c
|
||||
src/modules/physicaldisk/physicaldisk.c
|
||||
src/modules/physicalmemory/physicalmemory.c
|
||||
src/modules/processes/processes.c
|
||||
src/modules/player/player.c
|
||||
src/modules/poweradapter/poweradapter.c
|
||||
@@ -397,6 +402,7 @@ if(LINUX)
|
||||
src/detection/bluetooth/bluetooth_linux.c
|
||||
src/detection/disk/disk_linux.c
|
||||
src/detection/physicaldisk/physicaldisk_linux.c
|
||||
src/detection/physicalmemory/physicalmemory_linux.c
|
||||
src/detection/diskio/diskio_linux.c
|
||||
src/detection/displayserver/linux/displayserver_linux.c
|
||||
src/detection/displayserver/linux/drm.c
|
||||
@@ -415,6 +421,7 @@ if(LINUX)
|
||||
src/detection/icons/icons_linux.c
|
||||
src/detection/libc/libc_linux.c
|
||||
src/detection/lm/lm_linux.c
|
||||
src/detection/loadavg/loadavg_linux.c
|
||||
src/detection/locale/locale_linux.c
|
||||
src/detection/localip/localip_linux.c
|
||||
src/detection/gamepad/gamepad_linux.c
|
||||
@@ -462,6 +469,7 @@ elseif(ANDROID)
|
||||
src/detection/cpuusage/cpuusage_linux.c
|
||||
src/detection/disk/disk_linux.c
|
||||
src/detection/physicaldisk/physicaldisk_linux.c
|
||||
src/detection/physicalmemory/physicalmemory_nosupport.c
|
||||
src/detection/diskio/diskio_linux.c
|
||||
src/detection/displayserver/displayserver_android.c
|
||||
src/detection/font/font_nosupport.c
|
||||
@@ -470,6 +478,7 @@ elseif(ANDROID)
|
||||
src/detection/icons/icons_nosupport.c
|
||||
src/detection/libc/libc_android.c
|
||||
src/detection/lm/lm_nosupport.c
|
||||
src/detection/loadavg/loadavg_linux.c
|
||||
src/detection/locale/locale_linux.c
|
||||
src/detection/localip/localip_linux.c
|
||||
src/detection/gamepad/gamepad_nosupport.c
|
||||
@@ -518,6 +527,7 @@ elseif(BSD)
|
||||
src/detection/cursor/cursor_linux.c
|
||||
src/detection/disk/disk_bsd.c
|
||||
src/detection/physicaldisk/physicaldisk_bsd.c
|
||||
src/detection/physicalmemory/physicalmemory_linux.c
|
||||
src/detection/diskio/diskio_bsd.c
|
||||
src/detection/displayserver/linux/displayserver_linux.c
|
||||
src/detection/displayserver/linux/drm.c
|
||||
@@ -536,6 +546,7 @@ elseif(BSD)
|
||||
src/detection/lm/lm_linux.c
|
||||
src/detection/icons/icons_linux.c
|
||||
src/detection/libc/libc_bsd.c
|
||||
src/detection/loadavg/loadavg_bsd.c
|
||||
src/detection/locale/locale_linux.c
|
||||
src/detection/localip/localip_linux.c
|
||||
src/detection/gamepad/gamepad_bsd.c
|
||||
@@ -584,14 +595,16 @@ elseif(APPLE)
|
||||
src/detection/cursor/cursor_apple.m
|
||||
src/detection/disk/disk_bsd.c
|
||||
src/detection/physicaldisk/physicaldisk_apple.c
|
||||
src/detection/physicalmemory/physicalmemory_apple.m
|
||||
src/detection/diskio/diskio_apple.c
|
||||
src/detection/displayserver/displayserver_apple.c
|
||||
src/detection/font/font_apple.m
|
||||
src/detection/gpu/gpu_apple.c
|
||||
src/detection/gpu/gpu_apple.m
|
||||
src/detection/host/host_apple.c
|
||||
src/detection/lm/lm_nosupport.c
|
||||
src/detection/icons/icons_nosupport.c
|
||||
src/detection/lm/lm_nosupport.c
|
||||
src/detection/loadavg/loadavg_bsd.c
|
||||
src/detection/libc/libc_apple.c
|
||||
src/detection/locale/locale_linux.c
|
||||
src/detection/localip/localip_linux.c
|
||||
@@ -649,11 +662,13 @@ elseif(WIN32)
|
||||
src/detection/icons/icons_windows.c
|
||||
src/detection/libc/libc_windows.cpp
|
||||
src/detection/lm/lm_nosupport.c
|
||||
src/detection/loadavg/loadavg_nosupport.c
|
||||
src/detection/locale/locale_windows.c
|
||||
src/detection/localip/localip_windows.c
|
||||
src/detection/gamepad/gamepad_windows.c
|
||||
src/detection/media/media_nosupport.c
|
||||
src/detection/memory/memory_windows.c
|
||||
src/detection/physicalmemory/physicalmemory_linux.c
|
||||
src/detection/monitor/monitor_windows.c
|
||||
src/detection/netio/netio_windows.c
|
||||
src/detection/opengl/opengl_windows.c
|
||||
@@ -765,7 +780,7 @@ if(BSD AND EXISTS "/usr/local/bin/objdump")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE __STDC_WANT_LIB_EXT1__=1)
|
||||
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE __STDC_WANT_LIB_EXT1__=1 _FILE_OFFSET_BITS=64)
|
||||
if(WIN32)
|
||||
target_compile_definitions(libfastfetch PUBLIC WIN32_LEAN_AND_MEAN=1)
|
||||
elseif(APPLE)
|
||||
@@ -784,6 +799,14 @@ if(NOT "${CUSTOM_PCI_IDS_PATH}" STREQUAL "")
|
||||
message(STATUS "Custom file path of pci.ids: ${CUSTOM_PCI_IDS_PATH}")
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_CUSTOM_PCI_IDS_PATH=${CUSTOM_PCI_IDS_PATH})
|
||||
endif()
|
||||
if(NOT "${CUSTOM_AMDGPU_IDS_PATH}" STREQUAL "")
|
||||
message(STATUS "Custom file path of amdgpu.ids: ${CUSTOM_AMDGPU_IDS_PATH}")
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_CUSTOM_AMDGPU_IDS_PATH=${CUSTOM_AMDGPU_IDS_PATH})
|
||||
endif()
|
||||
if(NOT "${CUSTOM_OS_RELEASE_PATH}" STREQUAL "")
|
||||
message(STATUS "Custom file path of os_release: ${CUSTOM_OS_RELEASE_PATH}")
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_CUSTOM_OS_RELEASE_PATH=${CUSTOM_OS_RELEASE_PATH})
|
||||
endif()
|
||||
|
||||
function(ff_lib_enable VARNAME PKGCONFIG_NAMES CMAKE_NAME)
|
||||
if(NOT ENABLE_${VARNAME})
|
||||
@@ -1148,7 +1171,15 @@ if(LINUX)
|
||||
|
||||
set(CPACK_DEBIAN_PACKAGE_SECTION, "utils")
|
||||
set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6")
|
||||
|
||||
if(NOT IS_MUSL)
|
||||
EXECUTE_PROCESS (
|
||||
COMMAND getconf GNU_LIBC_VERSION
|
||||
OUTPUT_VARIABLE GLIBC_VERSION
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
STRING (REPLACE "glibc " "" GLIBC_VERSION ${GLIBC_VERSION})
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= ${GLIBC_VERSION})")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_program(HAVE_RPMBUILD "rpmbuild")
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
# Development help
|
||||
|
||||
This file is not an official documentation!
|
||||
Here i just add things that are easy to forget.
|
||||
|
||||
## Features i am planning to implement
|
||||
|
||||
### Specific
|
||||
|
||||
- [ ] Split the project in different libs / executables, all linking static by default:
|
||||
- `libffdetect`: contains all the detection stuff. To be used by anything that needs system information
|
||||
- `libffprint`: contains the printing functions, logos, format etc
|
||||
- `fastfetch` and `flashfetch`: Executables, that initialize the config of libffprint. Fist one at runtime, second one at compile time
|
||||
- [ ] Make LocalIP module more configurable
|
||||
- [ ] Automatic migrate old config files to newer versions
|
||||
- [ ] ZSH completions
|
||||
- [ ] Fish completions
|
||||
- [ ] Make CPU usage detection much faster and more accurate
|
||||
- [ ] Detect CPU usage in a common detection method and expose it both to the cpuUsage module and the cpu format string
|
||||
- [ ] Per session caching
|
||||
|
||||
### General
|
||||
- More presets
|
||||
- More logos
|
||||
- More package managers
|
||||
- More DE detections
|
||||
- More WM theme detections
|
||||
- More terminal font detections
|
||||
- Performance optimizations
|
||||
- More module specific options
|
||||
- Better error handling, especially the messages shown when using --show-errors
|
||||
- Using package managers libraries for package count detection instead own. E.g. using libalpm instead of counting files in /var/lib/pacman/local
|
||||
- Better documentation (especially default config file and the various --help options. Colored output?)
|
||||
- General feature parity with neofetch, to demonstrate supremity of c
|
||||
@@ -30,7 +30,7 @@ There are [screenshots on different platforms](https://github.com/fastfetch-cli/
|
||||
Some distros packaged an outdated fastfetch version. Older version is not supported, please always ensure that the latest version is used.
|
||||
|
||||
* Ubuntu: [`ppa:zhangsongcui3371/fastfetch`](https://launchpad.net/~zhangsongcui3371/+archive/ubuntu/fastfetch) (for Ubuntu 22.04 or newer)
|
||||
* Debian / Ubuntu: Download `fastfetch-<version>-Linux.deb` from [Github release page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and `dpkg -i fastfetch-<version>-Linux.deb` (for Ubuntu 20.04 or newer and Debian 11 or newer).
|
||||
* Debian / Ubuntu: Download `fastfetch-linux-<proper architecture>.deb` from [Github release page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and double-click it (for Ubuntu 20.04 or newer and Debian 11 or newer).
|
||||
* Arch Linux: `sudo pacman -S fastfetch`
|
||||
* Fedora: `sudo dnf install fastfetch`
|
||||
* Gentoo: `sudo emerge --ask app-misc/fastfetch`
|
||||
|
||||
@@ -191,7 +191,6 @@ __fastfetch_completion()
|
||||
"--escape-bedrock"
|
||||
"--pipe"
|
||||
"--title-fqdn"
|
||||
"--escape-bedrock"
|
||||
"--disk-folders"
|
||||
"--disk-show-external"
|
||||
"--disk-show-hidden"
|
||||
@@ -227,8 +226,6 @@ __fastfetch_completion()
|
||||
"--separator"
|
||||
"-s"
|
||||
"--structure"
|
||||
"--set"
|
||||
"--set-keyless"
|
||||
"--player-name"
|
||||
"--percent-type"
|
||||
"--publicip-url"
|
||||
@@ -360,7 +357,6 @@ __fastfetch_completion()
|
||||
local FF_OPTIONS_PATH=(
|
||||
"-c"
|
||||
"--config"
|
||||
"--os-file"
|
||||
"--lib-pci"
|
||||
"--lib-vulkan"
|
||||
"--lib-wayland"
|
||||
|
||||
+5
-8
@@ -107,12 +107,12 @@ To list all available modules, use \fB \-\-list\-modules \fR
|
||||
|
||||
.SS "Config Files"
|
||||
|
||||
fastfetch supports two types of config files. The legacy
|
||||
configuration files and a JSONC based format.
|
||||
Fastfetch uses JSONC based format for configuration. Fastfetch doesn't generate
|
||||
config file automatically; it should be generated manually by \fB \-\-gen\-config\fR.
|
||||
The config file will be saved in \fB~/.config/fastfetch/config.jsonc\fR by default.
|
||||
|
||||
A JSONC config file is a JSON file that also supports comments with (//). Those
|
||||
files must have the extension '.jsonc'. You can migrate a legacy config
|
||||
file to the JSONC format by using \fB\-\-gen\-config\fR.
|
||||
files must have the extension '.jsonc'.
|
||||
|
||||
The specified configuration/preset files are searched in the following order:
|
||||
|
||||
@@ -122,10 +122,7 @@ The specified configuration/preset files are searched in the following order:
|
||||
|
||||
3. relative to /usr/share/fastfetch/presets/
|
||||
|
||||
When both a '.jsonc' and a '.conf' file with the same name is found,
|
||||
the '.jsonc' file is preferred.
|
||||
|
||||
Fastfetch provides some default presets. List them with \fB \-\-print\-available\-presets\fR.
|
||||
Fastfetch provides some default presets. List them with \fB\-\-list\-presets\fR.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR neofetch (1)
|
||||
|
||||
+153
-13
@@ -4,9 +4,8 @@
|
||||
"colors": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"reset_", "bright_", "dim_",
|
||||
"black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", "default",
|
||||
"bright_black", "bright_red", "bright_green", "bright_yellow", "bright_blue", "bright_magenta", "bright_cyan", "bright_white"
|
||||
"reset_", "bright_", "dim_", "italic_", "underline_", "blink_", "inverse_", "hidden_", "strike_", "light_",
|
||||
"black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", "default"
|
||||
]
|
||||
},
|
||||
"key": {
|
||||
@@ -24,9 +23,13 @@
|
||||
"default": 0
|
||||
},
|
||||
"format": {
|
||||
"description": "Output format of the module",
|
||||
"description": "Output format of the module. See `-h <module>-format` for detail",
|
||||
"type": "string"
|
||||
},
|
||||
"outputColor": {
|
||||
"description": "Output color of the module. Left empty to use `display.color.output`",
|
||||
"$ref": "#/$defs/colors"
|
||||
},
|
||||
"percent": {
|
||||
"description": "Threshold of percentage colors",
|
||||
"type": "object",
|
||||
@@ -294,10 +297,6 @@
|
||||
"type": "string",
|
||||
"description": "The name of the player to use for module Media and Player. Linux only"
|
||||
},
|
||||
"osFile": {
|
||||
"type": "string",
|
||||
"description": "Set the path to the file containing OS information. Linux only"
|
||||
},
|
||||
"dsForceDrm": {
|
||||
"description": "Force display detection to use DRM. Linux only",
|
||||
"oneOf": [
|
||||
@@ -384,6 +383,10 @@
|
||||
"title": {
|
||||
"description": "Set the color of the title",
|
||||
"$ref": "#/$defs/colors"
|
||||
},
|
||||
"output": {
|
||||
"description": "Set the color of the module output",
|
||||
"$ref": "#/$defs/colors"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -698,6 +701,7 @@
|
||||
"icons",
|
||||
"kernel",
|
||||
"lm",
|
||||
"loadavg",
|
||||
"locale",
|
||||
"localip",
|
||||
"media",
|
||||
@@ -897,6 +901,9 @@
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
@@ -931,6 +938,9 @@
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
@@ -962,6 +972,9 @@
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
@@ -988,6 +1001,21 @@
|
||||
"minimum": 0,
|
||||
"maximum": 400,
|
||||
"default": 10
|
||||
},
|
||||
"key": {
|
||||
"$ref": "#/$defs/key"
|
||||
},
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
"format": {
|
||||
"$ref": "#/$defs/format"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1006,6 +1034,9 @@
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
@@ -1039,6 +1070,9 @@
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
@@ -1117,6 +1151,9 @@
|
||||
"maxItems": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"key": {
|
||||
"$ref": "#/$defs/key"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1143,6 +1180,9 @@
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
@@ -1167,6 +1207,9 @@
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
@@ -1174,10 +1217,7 @@
|
||||
"description": "Text to print",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"format"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "Display",
|
||||
@@ -1219,6 +1259,9 @@
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
@@ -1238,7 +1281,7 @@
|
||||
},
|
||||
"folders": {
|
||||
"type": "string",
|
||||
"description": "A colon (semicolon on Windows) separated list of folder paths for the disk output\nDefault: auto detection using mount-points"
|
||||
"description": "A colon (semicolon on Windows) separated list of folder paths for the disk output\nDefault: auto detection using mount-points\nThis option overrides other `show*` options"
|
||||
},
|
||||
"showExternal": {
|
||||
"type": "boolean",
|
||||
@@ -1279,6 +1322,9 @@
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
@@ -1311,6 +1357,9 @@
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
@@ -1339,6 +1388,9 @@
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
@@ -1365,6 +1417,9 @@
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
@@ -1410,6 +1465,9 @@
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
@@ -1452,6 +1510,11 @@
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"showAllIps": {
|
||||
"description": "Show all IPs bound to the same interface.\nBy default only the first IP is shown",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"compact": {
|
||||
"description": "Show all IPs in one line",
|
||||
"type": "boolean",
|
||||
@@ -1472,6 +1535,9 @@
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
@@ -1498,6 +1564,42 @@
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
"format": {
|
||||
"$ref": "#/$defs/format"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "Loadavg",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "loadavg",
|
||||
"description": "Print system load averages"
|
||||
},
|
||||
"ndigits": {
|
||||
"type": "integer",
|
||||
"description": "Set the number of digits to keep after the decimal point",
|
||||
"minimum": 0,
|
||||
"maximum": 9,
|
||||
"default": 2
|
||||
},
|
||||
"key": {
|
||||
"$ref": "#/$defs/key"
|
||||
},
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
@@ -1535,6 +1637,9 @@
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
@@ -1568,6 +1673,9 @@
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
@@ -1622,6 +1730,9 @@
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
@@ -1652,6 +1763,9 @@
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
@@ -1681,12 +1795,20 @@
|
||||
"minimum": 0,
|
||||
"default": "disabled (0)"
|
||||
},
|
||||
"ipv6": {
|
||||
"description": "Whether to use IPv6 for public IP detection server",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"key": {
|
||||
"$ref": "#/$defs/key"
|
||||
},
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
@@ -1708,6 +1830,9 @@
|
||||
"description": "Set the string to be printed",
|
||||
"type": "string",
|
||||
"default": "-"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1739,6 +1864,9 @@
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
@@ -1765,6 +1893,9 @@
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
@@ -1812,6 +1943,9 @@
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
@@ -1850,6 +1984,9 @@
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
@@ -1878,6 +2015,9 @@
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
"chassis",
|
||||
"kernel",
|
||||
"uptime",
|
||||
"loadavg",
|
||||
"processes",
|
||||
"packages",
|
||||
"shell",
|
||||
@@ -33,6 +34,7 @@
|
||||
"cpuusage",
|
||||
"gpu",
|
||||
"memory",
|
||||
"physicalmemory",
|
||||
"swap",
|
||||
"disk",
|
||||
"battery",
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"modules": [
|
||||
{
|
||||
"type": "title",
|
||||
"key": "User",
|
||||
"format": "{1}"
|
||||
},
|
||||
{
|
||||
"type": "title",
|
||||
"key": "Hostname",
|
||||
"format": "{2}"
|
||||
},
|
||||
{
|
||||
"type": "host",
|
||||
"key": "Model"
|
||||
},
|
||||
{
|
||||
"type": "os",
|
||||
"format": "{3} {9} {12}"
|
||||
},
|
||||
"kernel",
|
||||
"uptime",
|
||||
{
|
||||
"type": "loadavg",
|
||||
"key": "Load Average"
|
||||
},
|
||||
"processes",
|
||||
{
|
||||
"type": "wm",
|
||||
"key": "Window Manager"
|
||||
},
|
||||
{
|
||||
"type": "de",
|
||||
"key": "Desktop Environment"
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"format": "{7}"
|
||||
},
|
||||
{
|
||||
"type": "terminal",
|
||||
"format": "{5} {6} \u001b[37m█\u001b[97m█ \u001b[36m█\u001b[96m█ \u001b[35m█\u001b[95m█ \u001b[34m█\u001b[94m█ \u001b[33m█\u001b[93m█ \u001b[32m█\u001b[92m█ \u001b[31m█\u001b[91m█ \u001b[30m█\u001b[90m█"
|
||||
},
|
||||
{
|
||||
"type": "packages",
|
||||
"format": "{1}"
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"key": "Temperature",
|
||||
"temp": true,
|
||||
"format": "{8}"
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"key": "CPU",
|
||||
"format": "{4} x {1}"
|
||||
},
|
||||
{
|
||||
"type": "gpu",
|
||||
"format": "{2}"
|
||||
},
|
||||
{
|
||||
"type": "memory",
|
||||
"key": "RAM"
|
||||
},
|
||||
{
|
||||
"type": "disk",
|
||||
"key": "Disk",
|
||||
"folders": "/"
|
||||
},
|
||||
{
|
||||
"type": "localip",
|
||||
"key": "LAN IP",
|
||||
"showIpv6": true,
|
||||
"showPrefixLen": false
|
||||
},
|
||||
{
|
||||
"type": "publicip",
|
||||
"key": "WAN IP"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -6,6 +6,7 @@
|
||||
"showErrors": true,
|
||||
"noBuffer": true
|
||||
},
|
||||
"logo": null,
|
||||
"modules": [
|
||||
"title",
|
||||
"separator",
|
||||
@@ -16,6 +17,7 @@
|
||||
"chassis",
|
||||
"kernel",
|
||||
"uptime",
|
||||
"loadavg",
|
||||
"processes",
|
||||
"packages",
|
||||
"shell",
|
||||
@@ -39,6 +41,7 @@
|
||||
"cpuusage",
|
||||
"gpu",
|
||||
"memory",
|
||||
"physicalmemory",
|
||||
"swap",
|
||||
"disk",
|
||||
"battery",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"$schema": "file:///C:/msys64/home/zhang/fastfetch/doc/json_schema.json",
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": {
|
||||
"type": "small"
|
||||
},
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": {
|
||||
"type": "small",
|
||||
"padding": {
|
||||
"top": 1
|
||||
}
|
||||
},
|
||||
"display": {
|
||||
"separator": "",
|
||||
"keyWidth": 15
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"key": "╭───────────╮",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
// draw borders first to make colors of left and right border consistant
|
||||
"key": "│ │\u001b[11D\u001b[31m user",
|
||||
"type": "title",
|
||||
"format": "{1}"
|
||||
},
|
||||
{
|
||||
"key": "│ │\u001b[11D\u001b[32m hname",
|
||||
"type": "title",
|
||||
"format": "{2}"
|
||||
},
|
||||
{
|
||||
"key": "│ │\u001b[11D\u001b[33m uptime",
|
||||
"type": "uptime"
|
||||
},
|
||||
{
|
||||
"key": "│ │\u001b[11D\u001b[34m distro",
|
||||
"type": "os"
|
||||
},
|
||||
{
|
||||
"key": "│ │\u001b[11D\u001b[35m kernel",
|
||||
"type": "kernel"
|
||||
},
|
||||
{
|
||||
"key": "│ │\u001b[11D\u001b[36m desktop",
|
||||
"type": "de"
|
||||
},
|
||||
{
|
||||
"key": "│ │\u001b[11D\u001b[31m term",
|
||||
"type": "terminal"
|
||||
},
|
||||
{
|
||||
"key": "│ │\u001b[11D\u001b[32m shell",
|
||||
"type": "shell"
|
||||
},
|
||||
{
|
||||
"key": "│ │\u001b[11D\u001b[33m cpu",
|
||||
"type": "cpu"
|
||||
},
|
||||
{
|
||||
"key": "│ │\u001b[11D\u001b[34m disk",
|
||||
"type": "disk",
|
||||
"folders": "/"
|
||||
},
|
||||
{
|
||||
"key": "│ │\u001b[11D\u001b[35m memory",
|
||||
"type": "memory"
|
||||
},
|
||||
{
|
||||
"key": "│ │\u001b[11D\u001b[36m network",
|
||||
"type": "localip",
|
||||
"format": "{1} ({4})"
|
||||
},
|
||||
{
|
||||
"key": "├───────────┤",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"key": "│ │\u001b[11D\u001b[m colors",
|
||||
"type": "colors",
|
||||
"symbol": "circle"
|
||||
},
|
||||
{
|
||||
"key": "╰───────────╯",
|
||||
"type": "custom"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -9,8 +9,7 @@
|
||||
"modules": [
|
||||
{
|
||||
"type": "theme",
|
||||
"key": "T",
|
||||
"format": "{7}"
|
||||
"key": "T"
|
||||
},
|
||||
{
|
||||
"type": "icons",
|
||||
|
||||
+25
-13
@@ -1,25 +1,37 @@
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": {
|
||||
"type": "builtin",
|
||||
"source": "arch"
|
||||
},
|
||||
"modules": [
|
||||
"host",
|
||||
"display",
|
||||
{
|
||||
"type": "host",
|
||||
"format": "{?2}{2}{?}{?5} ({5}){?}"
|
||||
},
|
||||
"chassis",
|
||||
{
|
||||
"type": "board",
|
||||
"format": "{?1}{1}{?}{?2} ({2}){?}"
|
||||
},
|
||||
"cpu",
|
||||
"gpu",
|
||||
{
|
||||
"type": "memory",
|
||||
"format": "{?2}{2}{?}"
|
||||
},
|
||||
{
|
||||
"type": "disk",
|
||||
"format": "{?2}{2}{?}"
|
||||
},
|
||||
"physicaldisk",
|
||||
"gpu",
|
||||
"display",
|
||||
"monitor",
|
||||
{
|
||||
"type": "wifi",
|
||||
"format": "{?1}{1}{?}{?6} - {6}{?}"
|
||||
},
|
||||
{
|
||||
"type": "sound",
|
||||
"format": "{?2}{2}{?}"
|
||||
},
|
||||
"camera",
|
||||
{
|
||||
"type": "battery",
|
||||
"format": "{?1}{1} {?}{?2}{2} {?}{?3}({3}){?}"
|
||||
}
|
||||
"format": "{?1}{1}{?}{?2} {2}{?}{?3} ({3}){?}"
|
||||
},
|
||||
"poweradapter"
|
||||
]
|
||||
}
|
||||
|
||||
+9
-12
@@ -1,16 +1,16 @@
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"display": {
|
||||
"size": {
|
||||
"maxPrefix": "MB",
|
||||
"ndigits": 0
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
"title",
|
||||
"separator",
|
||||
{
|
||||
"type": "os",
|
||||
"format": "{3} {12}"
|
||||
},
|
||||
{
|
||||
"type": "host",
|
||||
"format": "{/2}{-}{/}{2}{?3} {3}{?}"
|
||||
},
|
||||
"os",
|
||||
"host",
|
||||
"kernel",
|
||||
"uptime",
|
||||
"packages",
|
||||
@@ -23,10 +23,7 @@
|
||||
"de",
|
||||
"wm",
|
||||
"wmtheme",
|
||||
{
|
||||
"type": "theme",
|
||||
"format": "{?1}{1}{?3} {3}{?} [Plasma], {?}{7}"
|
||||
},
|
||||
"theme",
|
||||
"icons",
|
||||
"terminal",
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
bool ffParseModuleOptions(const char* key, const char* value)
|
||||
{
|
||||
if (!ffStrStartsWith(key, "--") || !isalpha(key[2])) return false;
|
||||
if (!ffStrStartsWith(key, "--") || !ffCharIsEnglishAlphabet(key[2])) return false;
|
||||
|
||||
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(key[2]) - 'A']; *modules; ++modules)
|
||||
{
|
||||
@@ -79,30 +79,11 @@ static void genJsonResult(FFModuleBaseInfo* baseInfo, yyjson_mut_doc* doc)
|
||||
|
||||
static void parseStructureCommand(
|
||||
const char* line,
|
||||
FFlist* customValues,
|
||||
void (*fn)(FFModuleBaseInfo *baseInfo, yyjson_mut_doc* jsonDoc),
|
||||
yyjson_mut_doc* jsonDoc
|
||||
)
|
||||
{
|
||||
// handle `--set` and `--set-keyless`
|
||||
FF_LIST_FOR_EACH(FFCustomValue, customValue, *customValues)
|
||||
{
|
||||
if (ffStrbufEqualS(&customValue->key, line))
|
||||
{
|
||||
__attribute__((__cleanup__(ffDestroyCustomOptions))) FFCustomOptions options;
|
||||
ffInitCustomOptions(&options);
|
||||
if (customValue->printKey)
|
||||
ffStrbufAppend(&options.moduleArgs.key, &customValue->key);
|
||||
ffStrbufAppend(&options.moduleArgs.outputFormat, &customValue->value);
|
||||
if (__builtin_expect(jsonDoc != NULL, false))
|
||||
fn((FFModuleBaseInfo*) &options, jsonDoc);
|
||||
else
|
||||
ffPrintCustom(&options);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(isalpha(line[0]))
|
||||
if(ffCharIsEnglishAlphabet(line[0]))
|
||||
{
|
||||
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(line[0]) - 'A']; *modules; ++modules)
|
||||
{
|
||||
@@ -134,7 +115,7 @@ void ffPrintCommandOption(FFdata* data, yyjson_mut_doc* jsonDoc)
|
||||
if(instance.config.display.stat)
|
||||
ms = ffTimeGetTick();
|
||||
|
||||
parseStructureCommand(data->structure.chars + startIndex, &data->customValues, genJsonResult, jsonDoc);
|
||||
parseStructureCommand(data->structure.chars + startIndex, genJsonResult, jsonDoc);
|
||||
|
||||
if(instance.config.display.stat)
|
||||
{
|
||||
@@ -177,7 +158,7 @@ void ffMigrateCommandOptionToJsonc(FFdata* data, yyjson_mut_doc* jsonDoc)
|
||||
uint32_t colonIndex = ffStrbufNextIndexC(&data->structure, startIndex, ':');
|
||||
data->structure.chars[colonIndex] = '\0';
|
||||
|
||||
parseStructureCommand(data->structure.chars + startIndex, &data->customValues, genJsonConfig, jsonDoc);
|
||||
parseStructureCommand(data->structure.chars + startIndex, genJsonConfig, jsonDoc);
|
||||
|
||||
startIndex = colonIndex + 1;
|
||||
}
|
||||
|
||||
@@ -2,18 +2,10 @@
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFCustomValue
|
||||
{
|
||||
bool printKey;
|
||||
FFstrbuf key;
|
||||
FFstrbuf value;
|
||||
} FFCustomValue;
|
||||
|
||||
// Things only needed by fastfetch
|
||||
typedef struct FFdata
|
||||
{
|
||||
FFstrbuf structure;
|
||||
FFlist customValues; // List of FFCustomValue
|
||||
bool configLoaded;
|
||||
} FFdata;
|
||||
|
||||
|
||||
@@ -22,6 +22,11 @@ bool ffJsonConfigParseModuleArgs(const char* key, yyjson_val* val, FFModuleArgs*
|
||||
ffStrbufSetNS(&moduleArgs->outputFormat, (uint32_t) yyjson_get_len(val), yyjson_get_str(val));
|
||||
return true;
|
||||
}
|
||||
else if(ffStrEqualsIgnCase(key, "outputColor"))
|
||||
{
|
||||
ffOptionParseColor(yyjson_get_str(val), &moduleArgs->outputColor);
|
||||
return true;
|
||||
}
|
||||
else if(ffStrEqualsIgnCase(key, "keyColor"))
|
||||
{
|
||||
ffOptionParseColor(yyjson_get_str(val), &moduleArgs->keyColor);
|
||||
@@ -94,7 +99,7 @@ static inline void genJsonResult(FFModuleBaseInfo* baseInfo, yyjson_mut_doc* doc
|
||||
|
||||
static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal, yyjson_mut_doc* jsonDoc)
|
||||
{
|
||||
if(!isalpha(type[0])) return false;
|
||||
if(!ffCharIsEnglishAlphabet(type[0])) return false;
|
||||
|
||||
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(type[0]) - 'A']; *modules; ++modules)
|
||||
{
|
||||
|
||||
@@ -71,6 +71,7 @@ static FFModuleBaseInfo* K[] = {
|
||||
|
||||
static FFModuleBaseInfo* L[] = {
|
||||
(void*) &instance.config.modules.lm,
|
||||
(void*) &instance.config.modules.loadavg,
|
||||
(void*) &instance.config.modules.locale,
|
||||
(void*) &instance.config.modules.localIP,
|
||||
NULL,
|
||||
@@ -98,6 +99,7 @@ static FFModuleBaseInfo* O[] = {
|
||||
static FFModuleBaseInfo* P[] = {
|
||||
(void*) &instance.config.modules.packages,
|
||||
(void*) &instance.config.modules.physicalDisk,
|
||||
(void*) &instance.config.modules.physicalMemory,
|
||||
(void*) &instance.config.modules.player,
|
||||
(void*) &instance.config.modules.powerAdapter,
|
||||
(void*) &instance.config.modules.processes,
|
||||
|
||||
@@ -22,6 +22,7 @@ typedef struct FFNetworkingState {
|
||||
#endif
|
||||
|
||||
uint32_t timeout;
|
||||
bool ipv6;
|
||||
} FFNetworkingState;
|
||||
|
||||
const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers);
|
||||
|
||||
@@ -14,7 +14,7 @@ static const char* connectAndSend(FFNetworkingState* state)
|
||||
struct addrinfo* addr;
|
||||
|
||||
if(getaddrinfo(state->host.chars, "80", &(struct addrinfo) {
|
||||
.ai_family = AF_INET,
|
||||
.ai_family = state->ipv6 ? AF_INET6 : AF_INET,
|
||||
.ai_socktype = SOCK_STREAM,
|
||||
}, &addr) != 0)
|
||||
{
|
||||
|
||||
@@ -51,7 +51,7 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
|
||||
struct addrinfo* addr;
|
||||
|
||||
if(getaddrinfo(host, "80", &(struct addrinfo) {
|
||||
.ai_family = AF_INET,
|
||||
.ai_family = state->ipv6 ? AF_INET6 : AF_INET,
|
||||
.ai_socktype = SOCK_STREAM,
|
||||
}, &addr) != 0)
|
||||
return "getaddrinfo() failed";
|
||||
|
||||
@@ -39,6 +39,16 @@ bool ffOptionParseModuleArgs(const char* argumentKey, const char* subKey, const
|
||||
ffOptionParseString(argumentKey, value, &result->outputFormat);
|
||||
return true;
|
||||
}
|
||||
else if(ffStrEqualsIgnCase(subKey, "output-color"))
|
||||
{
|
||||
if(value == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error: usage: %s <str>\n", argumentKey);
|
||||
exit(477);
|
||||
}
|
||||
ffOptionParseColor(value, &result->outputColor);
|
||||
return true;
|
||||
}
|
||||
else if(ffStrEqualsIgnCase(subKey, "key-color"))
|
||||
{
|
||||
if(value == NULL)
|
||||
@@ -148,6 +158,12 @@ void ffOptionParseColor(const char* value, FFstrbuf* buffer)
|
||||
FF_APPEND_COLOR_CODE_COND(reset_, FF_COLOR_MODE_RESET)
|
||||
else FF_APPEND_COLOR_CODE_COND(bright_, FF_COLOR_MODE_BOLD)
|
||||
else FF_APPEND_COLOR_CODE_COND(dim_, FF_COLOR_MODE_DIM)
|
||||
else FF_APPEND_COLOR_CODE_COND(italic_, FF_COLOR_MODE_ITALIC)
|
||||
else FF_APPEND_COLOR_CODE_COND(underline_, FF_COLOR_MODE_UNDERLINE)
|
||||
else FF_APPEND_COLOR_CODE_COND(blink_, FF_COLOR_MODE_BLINK)
|
||||
else FF_APPEND_COLOR_CODE_COND(inverse_, FF_COLOR_MODE_INVERSE)
|
||||
else FF_APPEND_COLOR_CODE_COND(hidden_, FF_COLOR_MODE_HIDDEN)
|
||||
else FF_APPEND_COLOR_CODE_COND(strike_, FF_COLOR_MODE_STRIKETHROUGH)
|
||||
else FF_APPEND_COLOR_CODE_COND(black, FF_COLOR_FG_BLACK)
|
||||
else FF_APPEND_COLOR_CODE_COND(red, FF_COLOR_FG_RED)
|
||||
else FF_APPEND_COLOR_CODE_COND(green, FF_COLOR_FG_GREEN)
|
||||
@@ -180,6 +196,7 @@ void ffOptionInitModuleArg(FFModuleArgs* args)
|
||||
ffStrbufInit(&args->key);
|
||||
ffStrbufInit(&args->keyColor);
|
||||
ffStrbufInit(&args->outputFormat);
|
||||
ffStrbufInit(&args->outputColor);
|
||||
args->keyWidth = 0;
|
||||
}
|
||||
|
||||
@@ -188,4 +205,5 @@ void ffOptionDestroyModuleArg(FFModuleArgs* args)
|
||||
ffStrbufDestroy(&args->key);
|
||||
ffStrbufDestroy(&args->keyColor);
|
||||
ffStrbufDestroy(&args->outputFormat);
|
||||
ffStrbufDestroy(&args->outputColor);
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ typedef struct FFModuleArgs
|
||||
FFstrbuf key;
|
||||
FFstrbuf keyColor;
|
||||
FFstrbuf outputFormat;
|
||||
FFstrbuf outputColor;
|
||||
uint32_t keyWidth;
|
||||
} FFModuleArgs;
|
||||
|
||||
|
||||
+15
-3
@@ -6,7 +6,15 @@
|
||||
#include "util/textModifier.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig config)
|
||||
static void appendOutputColor(FFstrbuf* buffer, const FFModuleArgs* module)
|
||||
{
|
||||
if (module->outputColor.length)
|
||||
ffStrbufAppendF(buffer, "\e[%sm", module->outputColor.chars);
|
||||
else if (instance.config.display.colorOutput.length)
|
||||
ffStrbufAppendF(buffer, "\e[%sm", instance.config.display.colorOutput.chars);
|
||||
}
|
||||
|
||||
void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig config, const FFModuleArgs* module)
|
||||
{
|
||||
uint8_t green = config.green, yellow = config.yellow;
|
||||
assert(green <= 100 && yellow <= 100);
|
||||
@@ -66,16 +74,19 @@ void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig con
|
||||
if(options->barBorder)
|
||||
{
|
||||
if(!options->pipe)
|
||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_WHITE "m ]");
|
||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_WHITE "m ]");\
|
||||
else
|
||||
ffStrbufAppendS(buffer, " ]");
|
||||
}
|
||||
|
||||
if(!options->pipe)
|
||||
{
|
||||
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
appendOutputColor(buffer, module);
|
||||
}
|
||||
}
|
||||
|
||||
void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFColorRangeConfig config, bool parentheses)
|
||||
void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFColorRangeConfig config, bool parentheses, const FFModuleArgs* module)
|
||||
{
|
||||
uint8_t green = config.green, yellow = config.yellow;
|
||||
assert(green <= 100 && yellow <= 100);
|
||||
@@ -120,6 +131,7 @@ void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFColorRangeConfig con
|
||||
if (colored && !options->pipe)
|
||||
{
|
||||
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
appendOutputColor(buffer, module);
|
||||
}
|
||||
|
||||
if (parentheses)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "util/FFstrbuf.h"
|
||||
#include "common/parsing.h"
|
||||
#include "common/option.h"
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -21,8 +22,8 @@ enum
|
||||
// [yellow, green): print yellow
|
||||
// [0, yellow): print red
|
||||
|
||||
void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig config);
|
||||
void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFColorRangeConfig config, bool parentheses);
|
||||
void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig config, const FFModuleArgs* module);
|
||||
void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFColorRangeConfig config, bool parentheses, const FFModuleArgs* module);
|
||||
|
||||
typedef struct yyjson_val yyjson_val;
|
||||
typedef struct yyjson_mut_doc yyjson_mut_doc;
|
||||
|
||||
@@ -49,8 +49,13 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
|
||||
ffStrbufWriteTo(&instance.config.display.keyValueSeparator, stdout);
|
||||
|
||||
if(!instance.config.display.pipe)
|
||||
{
|
||||
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
|
||||
|
||||
if (moduleArgs->outputColor.length)
|
||||
ffPrintColor(&moduleArgs->outputColor);
|
||||
else if (instance.config.display.colorOutput.length)
|
||||
ffPrintColor(&instance.config.display.colorOutput);
|
||||
}
|
||||
|
||||
if (!instance.config.display.pipe && !(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_WIDTH))
|
||||
{
|
||||
|
||||
@@ -8,10 +8,7 @@ static inline const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const ar
|
||||
{
|
||||
const char* error = ffProcessAppendOutput(buffer, argv, false);
|
||||
if (!error)
|
||||
{
|
||||
ffStrbufTrimRight(buffer, '\n');
|
||||
ffStrbufTrimRight(buffer, ' ');
|
||||
}
|
||||
ffStrbufTrimRightSpace(buffer);
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -19,9 +16,6 @@ static inline const char* ffProcessAppendStdErr(FFstrbuf* buffer, char* const ar
|
||||
{
|
||||
const char* error = ffProcessAppendOutput(buffer, argv, true);
|
||||
if (!error)
|
||||
{
|
||||
ffStrbufTrimRight(buffer, '\n');
|
||||
ffStrbufTrimRight(buffer, ' ');
|
||||
}
|
||||
ffStrbufTrimRightSpace(buffer);
|
||||
return error;
|
||||
}
|
||||
|
||||
+25
-29
@@ -1,5 +1,7 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/properties.h"
|
||||
#include "common/io/io.h"
|
||||
#include "util/mallocHelper.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#ifdef _WIN32
|
||||
@@ -95,50 +97,44 @@ bool ffParsePropLines(const char* lines, const char* start, FFstrbuf* buffer)
|
||||
|
||||
bool ffParsePropFileValues(const char* filename, uint32_t numQueries, FFpropquery* queries)
|
||||
{
|
||||
FILE* file = fopen(filename, "r");
|
||||
if(file == NULL)
|
||||
FF_AUTO_CLOSE_FILE FILE* file = fopen(filename, "r");
|
||||
if (file == NULL)
|
||||
return false;
|
||||
|
||||
bool valueStorage[4];
|
||||
bool* unsetValues;
|
||||
bool valueStorage[32];
|
||||
bool* unsetValues = valueStorage;
|
||||
|
||||
if(numQueries > sizeof(valueStorage) / sizeof(valueStorage[0]))
|
||||
if (numQueries > sizeof(valueStorage) / sizeof(valueStorage[0]))
|
||||
unsetValues = malloc(sizeof(bool) * numQueries);
|
||||
else
|
||||
unsetValues = valueStorage;
|
||||
|
||||
bool allSet = true;
|
||||
for(uint32_t i = 0; i < numQueries; i++)
|
||||
for (uint32_t i = 0; i < numQueries; i++)
|
||||
{
|
||||
if((unsetValues[i] = queries[i].buffer->length == 0))
|
||||
unsetValues[i] = queries[i].buffer->length == 0;
|
||||
if (unsetValues[i])
|
||||
allSet = false;
|
||||
}
|
||||
|
||||
if(allSet)
|
||||
goto done;
|
||||
|
||||
char* line = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
while (getline(&line, &len, file) != -1)
|
||||
if (!allSet)
|
||||
{
|
||||
for(uint32_t i = 0; i < numQueries; i++)
|
||||
{
|
||||
if(!unsetValues[i])
|
||||
continue;
|
||||
FF_AUTO_FREE char* line = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
uint32_t currentLength = queries[i].buffer->length;
|
||||
queries[i].buffer->length = 0;
|
||||
if(!ffParsePropLine(line, queries[i].start, queries[i].buffer))
|
||||
queries[i].buffer->length = currentLength;
|
||||
while (getline(&line, &len, file) != -1)
|
||||
{
|
||||
for(uint32_t i = 0; i < numQueries; i++)
|
||||
{
|
||||
if(!unsetValues[i])
|
||||
continue;
|
||||
|
||||
uint32_t currentLength = queries[i].buffer->length;
|
||||
queries[i].buffer->length = 0;
|
||||
if(!ffParsePropLine(line, queries[i].start, queries[i].buffer))
|
||||
queries[i].buffer->length = currentLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(line != NULL)
|
||||
free(line);
|
||||
|
||||
done:
|
||||
fclose(file);
|
||||
if(unsetValues != valueStorage)
|
||||
free(unsetValues);
|
||||
return true;
|
||||
|
||||
+8
-2
@@ -3,7 +3,7 @@
|
||||
#include "util/textModifier.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
void ffTempsAppendNum(double celsius, FFstrbuf* buffer, FFColorRangeConfig config)
|
||||
void ffTempsAppendNum(double celsius, FFstrbuf* buffer, FFColorRangeConfig config, const FFModuleArgs* module)
|
||||
{
|
||||
if (celsius != celsius) // ignores NaN
|
||||
return;
|
||||
@@ -37,7 +37,7 @@ void ffTempsAppendNum(double celsius, FFstrbuf* buffer, FFColorRangeConfig confi
|
||||
}
|
||||
}
|
||||
|
||||
switch (options->temperatureUnit)
|
||||
switch (options->tempUnit)
|
||||
{
|
||||
case FF_TEMPERATURE_UNIT_CELSIUS:
|
||||
ffStrbufAppendF(buffer, "%.*f°C", options->tempNdigits, celsius);
|
||||
@@ -51,7 +51,13 @@ void ffTempsAppendNum(double celsius, FFstrbuf* buffer, FFColorRangeConfig confi
|
||||
}
|
||||
|
||||
if (!options->pipe)
|
||||
{
|
||||
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
if (module->outputColor.length)
|
||||
ffStrbufAppendF(buffer, "\e[%sm", module->outputColor.chars);
|
||||
else if (instance.config.display.colorOutput.length)
|
||||
ffStrbufAppendF(buffer, "\e[%sm", instance.config.display.colorOutput.chars);
|
||||
}
|
||||
}
|
||||
|
||||
bool ffTempsParseCommandOptions(const char* key, const char* subkey, const char* value, bool* useTemp, FFColorRangeConfig* config)
|
||||
|
||||
+2
-1
@@ -1,8 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "common/parsing.h"
|
||||
#include "common/option.h"
|
||||
|
||||
void ffTempsAppendNum(double celsius, FFstrbuf* buffer, FFColorRangeConfig config);
|
||||
void ffTempsAppendNum(double celsius, FFstrbuf* buffer, FFColorRangeConfig config, const FFModuleArgs* module);
|
||||
bool ffTempsParseCommandOptions(const char* key, const char* subkey, const char* value, bool* useTemp, FFColorRangeConfig* config);
|
||||
bool ffTempsParseJsonObject(const char* key, yyjson_val* value, bool* useTemp, FFColorRangeConfig* config);
|
||||
void ffTempsGenerateJsonConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FF_MAYBE_UNUSED bool defaultTemp, FFColorRangeConfig defaultConfig, bool temp, FFColorRangeConfig config);
|
||||
|
||||
+49
-23
@@ -436,7 +436,7 @@
|
||||
{
|
||||
"long": "color-keys",
|
||||
"desc": "Set the color of the keys",
|
||||
"remark": "See `-h color` for the list of available colors",
|
||||
"remark": "Doesn't affect module Title, Separator and Colors. See `-h color` for the list of available colors",
|
||||
"arg": {
|
||||
"type": "color"
|
||||
}
|
||||
@@ -449,6 +449,14 @@
|
||||
"type": "color"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "color-output",
|
||||
"desc": "Set the color of module output",
|
||||
"remark": "See `-h color` for the list of available colors",
|
||||
"arg": {
|
||||
"type": "color"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "color",
|
||||
"desc": "Set the color of both the keys and title",
|
||||
@@ -481,22 +489,6 @@
|
||||
"default": ": "
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "set",
|
||||
"desc": "Hard set the value of a key",
|
||||
"remark": "Deprecated. Use \"Custom\" module instead",
|
||||
"arg": {
|
||||
"type": "key=value"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "set-keyless",
|
||||
"desc": "Hard set the value of a key, but don't print the key or the separator",
|
||||
"remark": "Deprecated. Use \"Custom\" module instead",
|
||||
"arg": {
|
||||
"type": "key=value"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "show-errors",
|
||||
"desc": "Print occurring errors",
|
||||
@@ -521,7 +513,7 @@
|
||||
"arg": {
|
||||
"type": "bool",
|
||||
"optional": true,
|
||||
"default": true
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -938,16 +930,17 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "os-file",
|
||||
"desc": "Set the additional file path which containing OS information",
|
||||
"remark": "Linux only",
|
||||
"long": "separator-output-color",
|
||||
"desc": "Set the color of the separator module",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
"type": "color",
|
||||
"default": "default"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "disk-folders",
|
||||
"desc": "A colon (semicolon on Windows) separated list of folder paths for the disk output",
|
||||
"desc": "A colon (semicolon on Windows) separated list of folder paths to be detected",
|
||||
"remark": "On Windows, a drive latter must be upper cased and end with \"\\\". \"/\" is used as an alias of the system drive. This option overrides other disk-show-* options",
|
||||
"arg": {
|
||||
"type": "path",
|
||||
"default": "Auto detection using mount-points"
|
||||
@@ -1235,6 +1228,14 @@
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "loadavg-ndigits",
|
||||
"desc": "Set the number of digits to keep after the decimal point when printing load average",
|
||||
"arg": {
|
||||
"type": "num",
|
||||
"default": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "localip-show-ipv4",
|
||||
"desc": "Show IPv4 addresses in local ip module",
|
||||
@@ -1297,6 +1298,15 @@
|
||||
"default": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "localip-show-all-ips",
|
||||
"desc": "Show all IPs bound to the same interface. By default only the first IP is shown",
|
||||
"arg": {
|
||||
"type": "bool",
|
||||
"optional": true,
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "localip-compact",
|
||||
"desc": "Show all IPs in one line",
|
||||
@@ -1347,6 +1357,14 @@
|
||||
"type": "str"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "publicip-ipv6",
|
||||
"desc": "Whether to use IPv6 for public IP detection server",
|
||||
"arg": {
|
||||
"type": "bool",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "weather-location",
|
||||
"desc": "Set the location to be used",
|
||||
@@ -1521,6 +1539,14 @@
|
||||
},
|
||||
"pseudo": true
|
||||
},
|
||||
{
|
||||
"long": "<module>-output-color",
|
||||
"desc": "Override the global \"--color-output\" option for each specific module",
|
||||
"arg": {
|
||||
"type": "color"
|
||||
},
|
||||
"pseudo": true
|
||||
},
|
||||
{
|
||||
"long": "<module>-key-width",
|
||||
"desc": "Override the global \"--key-width\" option for each specific module",
|
||||
|
||||
@@ -3,7 +3,8 @@ Usage: fastfetch --color <color>
|
||||
<color> must be a color encoding as ANSI escape sequences. It is inserted between "ESC[" and "m".
|
||||
Infos about them can be found here: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters.
|
||||
Examples:
|
||||
--color 35: sets the color to magenta. `--color magenta` is also supported
|
||||
--color 4;92: sets the color to bright Green with underline
|
||||
--color 5;104: blinking text on a blue background
|
||||
--color 35: sets the color to magenta. `--color magenta` is also supported
|
||||
--color 38;5;38: sets the color to 38th color of ANSI 256 colors
|
||||
--color 4;92: sets the color to bright Green with underline. `--color underline_green` is also supported
|
||||
--color 5;104: blinking text on a blue background
|
||||
If no color is set, the main color of the logo will be used.
|
||||
|
||||
@@ -40,6 +40,7 @@ static const char* parseTermuxApi(FFBatteryOptions* options, FFlist* results)
|
||||
ffStrbufInit(&battery->modelName);
|
||||
ffStrbufInit(&battery->status);
|
||||
ffStrbufInit(&battery->technology);
|
||||
ffStrbufInit(&battery->serial);
|
||||
ffStrbufInit(&battery->manufactureDate);
|
||||
|
||||
battery->capacity = yyjson_get_num(yyjson_obj_get(root, "percentage"));
|
||||
@@ -77,6 +78,8 @@ static const char* parseDumpsys(FFBatteryOptions* options, FFlist* results)
|
||||
ffStrbufInit(&battery->modelName);
|
||||
ffStrbufInit(&battery->status);
|
||||
ffStrbufInit(&battery->technology);
|
||||
ffStrbufInit(&battery->serial);
|
||||
ffStrbufInit(&battery->manufactureDate);
|
||||
|
||||
if (ffParsePropLines(start, "AC powered: ", &temp) && ffStrbufEqualS(&temp, "true"))
|
||||
ffStrbufAppendS(&battery->status, "AC powered");
|
||||
|
||||
@@ -170,8 +170,5 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
|
||||
ffStrbufSubstrBefore(&baseDir, baseDirLength);
|
||||
}
|
||||
|
||||
if(results->length == 0)
|
||||
return "\"/sys/class/power_supply/\" doesn't contain any battery folder";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
#include "battery.h"
|
||||
|
||||
#include "common/io/io.h"
|
||||
#include "util/windows/unicode.h"
|
||||
#include "util/mallocHelper.h"
|
||||
#include "util/smbiosHelper.h"
|
||||
@@ -20,11 +22,6 @@ NtPowerInformation(
|
||||
OUT PVOID OutputBuffer OPTIONAL,
|
||||
IN ULONG OutputBufferLength);
|
||||
|
||||
static inline void wrapCloseHandle(HANDLE* handle)
|
||||
{
|
||||
if(*handle)
|
||||
CloseHandle(*handle);
|
||||
}
|
||||
static inline void wrapSetupDiDestroyDeviceInfoList(HDEVINFO* hdev)
|
||||
{
|
||||
if(*hdev)
|
||||
@@ -52,7 +49,7 @@ static const char* detectWithSetupApi(FFBatteryOptions* options, FFlist* results
|
||||
if(!SetupDiGetDeviceInterfaceDetailW(hdev, &did, pdidd, cbRequired, &cbRequired, NULL))
|
||||
continue;
|
||||
|
||||
HANDLE __attribute__((__cleanup__(wrapCloseHandle))) hBattery =
|
||||
HANDLE FF_AUTO_CLOSE_FD hBattery =
|
||||
CreateFileW(pdidd->DevicePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if(hBattery == INVALID_HANDLE_VALUE)
|
||||
@@ -157,8 +154,6 @@ static const char* detectWithSetupApi(FFBatteryOptions* options, FFlist* results
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef struct FFSmbiosPortableBattery
|
||||
{
|
||||
FFSmbiosHeader Header;
|
||||
@@ -181,11 +176,18 @@ typedef struct FFSmbiosPortableBattery
|
||||
uint8_t SbdsDeviceChemistry; // string
|
||||
uint8_t DesignCapacityMultiplier; // varies
|
||||
uint16_t OEMSpecific; // varies
|
||||
} FFSmbiosPortableBattery;
|
||||
} __attribute__((__packed__)) FFSmbiosPortableBattery;
|
||||
|
||||
static_assert(offsetof(FFSmbiosPortableBattery, OEMSpecific) == 0x16,
|
||||
"FFSmbiosPortableBattery: Wrong struct alignment");
|
||||
|
||||
const char* detectBySmbios(FFBatteryResult* battery)
|
||||
{
|
||||
const FFSmbiosPortableBattery* data = (const FFSmbiosPortableBattery*) (*ffGetSmbiosHeaderTable())[FF_SMBIOS_TYPE_PORTABLE_BATTERY];
|
||||
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
|
||||
if (!smbiosTable)
|
||||
return "Failed to get SMBIOS data";
|
||||
|
||||
const FFSmbiosPortableBattery* data = (const FFSmbiosPortableBattery*) (*smbiosTable)[FF_SMBIOS_TYPE_PORTABLE_BATTERY];
|
||||
if (!data)
|
||||
return "Portable battery section is not found in SMBIOS data";
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ typedef struct FFSmbiosBios
|
||||
uint16_t BiosStartingAddressSegment; // varies
|
||||
uint8_t BiosReleaseDate; // string
|
||||
uint8_t BiosRomSize; // string
|
||||
uint32_t BiosCharacteristics; // bit field
|
||||
uint64_t BiosCharacteristics; // bit field
|
||||
|
||||
// 2.4+
|
||||
uint8_t BiosCharacteristicsExtensionBytes[2]; // bit field
|
||||
@@ -46,11 +46,18 @@ typedef struct FFSmbiosBios
|
||||
|
||||
// 3.1+
|
||||
uint16_t ExtendedBiosRomSize; // bit field
|
||||
} FFSmbiosBios;
|
||||
} __attribute__((__packed__)) FFSmbiosBios;
|
||||
|
||||
static_assert(offsetof(FFSmbiosBios, ExtendedBiosRomSize) == 0x18,
|
||||
"FFSmbiosBios: Wrong struct alignment");
|
||||
|
||||
const char* ffDetectBios(FFBiosResult* bios)
|
||||
{
|
||||
const FFSmbiosBios* data = (const FFSmbiosBios*) (*ffGetSmbiosHeaderTable())[FF_SMBIOS_TYPE_BIOS];
|
||||
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
|
||||
if (!smbiosTable)
|
||||
return "Failed to get SMBIOS data";
|
||||
|
||||
const FFSmbiosBios* data = (const FFSmbiosBios*) (*smbiosTable)[FF_SMBIOS_TYPE_BIOS];
|
||||
if (!data)
|
||||
return "BIOS section is not found in SMBIOS data";
|
||||
|
||||
|
||||
@@ -14,13 +14,20 @@ typedef struct FFSmbiosBaseboard
|
||||
uint8_t LocationInChassis; // string
|
||||
uint16_t ChassisHandle; // varies
|
||||
uint8_t BoardType; // enum
|
||||
uint8_t NumberOfContainedObjectHandle; // varies
|
||||
uint16_t ContainedObjectHandle[]; // varies
|
||||
} FFSmbiosBaseboard;
|
||||
uint8_t NumberOfContainedObjectHandles; // varies
|
||||
uint16_t ContainedObjectHandles[]; // varies
|
||||
} __attribute__((__packed__)) FFSmbiosBaseboard;
|
||||
|
||||
static_assert(offsetof(FFSmbiosBaseboard, ContainedObjectHandles) == 0x0F,
|
||||
"FFSmbiosBaseboard: Wrong struct alignment");
|
||||
|
||||
const char* ffDetectBoard(FFBoardResult* board)
|
||||
{
|
||||
const FFSmbiosBaseboard* data = (const FFSmbiosBaseboard*) (*ffGetSmbiosHeaderTable())[FF_SMBIOS_TYPE_BASEBOARD_INFO];
|
||||
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
|
||||
if (!smbiosTable)
|
||||
return "Failed to get SMBIOS data";
|
||||
|
||||
const FFSmbiosBaseboard* data = (const FFSmbiosBaseboard*) (*smbiosTable)[FF_SMBIOS_TYPE_BASEBOARD_INFO];
|
||||
if (!data)
|
||||
return "Baseboard information section is not found in SMBIOS data";
|
||||
|
||||
|
||||
@@ -3,10 +3,27 @@
|
||||
|
||||
#import <AVFoundation/AVCaptureDevice.h>
|
||||
|
||||
// warning: 'AVCaptureDeviceTypeExternalUnknown' is deprecated
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
||||
const char* ffDetectCamera(FFlist* result)
|
||||
{
|
||||
FF_SUPPRESS_IO(); // #822
|
||||
AVCaptureDeviceDiscoverySession* session = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInWideAngleCamera, AVCaptureDeviceTypeExternalUnknown]
|
||||
|
||||
AVCaptureDeviceType deviceType;
|
||||
|
||||
#ifdef MAC_OS_VERSION_14_0
|
||||
if (@available(macOS 14.0, *))
|
||||
{
|
||||
deviceType = AVCaptureDeviceTypeExternal;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
deviceType = AVCaptureDeviceTypeExternalUnknown;
|
||||
}
|
||||
|
||||
AVCaptureDeviceDiscoverySession* session = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInWideAngleCamera, deviceType]
|
||||
mediaType:AVMediaTypeVideo
|
||||
position:AVCaptureDevicePositionUnspecified];
|
||||
if (!session)
|
||||
|
||||
@@ -25,11 +25,18 @@ typedef struct FFSmbiosSystemEnclosure
|
||||
uint8_t ContainedElementCount; // varies
|
||||
uint8_t ContainedRecordLength; // varies
|
||||
uint8_t ContainedElements[]; // varies
|
||||
} FFSmbiosSystemEnclosure;
|
||||
} __attribute__((__packed__)) FFSmbiosSystemEnclosure;
|
||||
|
||||
static_assert(offsetof(FFSmbiosSystemEnclosure, ContainedElements) == 0x15,
|
||||
"FFSmbiosSystemEnclosure: Wrong struct alignment");
|
||||
|
||||
const char* ffDetectChassis(FFChassisResult* result)
|
||||
{
|
||||
const FFSmbiosSystemEnclosure* data = (const FFSmbiosSystemEnclosure*) (*ffGetSmbiosHeaderTable())[FF_SMBIOS_TYPE_SYSTEM_ENCLOSURE];
|
||||
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
|
||||
if (!smbiosTable)
|
||||
return "Failed to get SMBIOS data";
|
||||
|
||||
const FFSmbiosSystemEnclosure* data = (const FFSmbiosSystemEnclosure*) (*smbiosTable)[FF_SMBIOS_TYPE_SYSTEM_ENCLOSURE];
|
||||
if (!data)
|
||||
return "System enclosure is not found in SMBIOS data";
|
||||
|
||||
|
||||
@@ -48,7 +48,10 @@ typedef struct FFSmbiosProcessorInfo
|
||||
|
||||
// 3.6+
|
||||
uint16_t ThreadEnabled; // varies
|
||||
} FFSmbiosProcessorInfo;
|
||||
} __attribute__((__packed__)) FFSmbiosProcessorInfo;
|
||||
|
||||
static_assert(offsetof(FFSmbiosProcessorInfo, ThreadEnabled) == 0x30,
|
||||
"FFSmbiosProcessorInfo: Wrong struct alignment");
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
|
||||
@@ -77,7 +80,11 @@ inline static const char* detectSpeedByCpuid(FF_MAYBE_UNUSED FFCPUResult* cpu)
|
||||
|
||||
static const char* detectMaxSpeedBySmbios(FFCPUResult* cpu)
|
||||
{
|
||||
const FFSmbiosProcessorInfo* data = (const FFSmbiosProcessorInfo*) (*ffGetSmbiosHeaderTable())[FF_SMBIOS_TYPE_PROCESSOR_INFO];
|
||||
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
|
||||
if (!smbiosTable)
|
||||
return "Failed to get SMBIOS data";
|
||||
|
||||
const FFSmbiosProcessorInfo* data = (const FFSmbiosProcessorInfo*) (*smbiosTable)[FF_SMBIOS_TYPE_PROCESSOR_INFO];
|
||||
|
||||
if (!data)
|
||||
return "Processor information is not found in SMBIOS data";
|
||||
|
||||
@@ -1,10 +1,23 @@
|
||||
#include "disk.h"
|
||||
#include "common/io/io.h"
|
||||
#include "common/thread.h"
|
||||
#include "util/windows/unicode.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <winioctl.h>
|
||||
#include <assert.h>
|
||||
|
||||
static unsigned __stdcall testRemoteVolumeAccessable(void* mountpoint)
|
||||
{
|
||||
FF_AUTO_CLOSE_FD HANDLE handle = CreateFileW(
|
||||
(wchar_t*) mountpoint,
|
||||
READ_CONTROL,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS,
|
||||
NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||
{
|
||||
@@ -15,6 +28,14 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||
|
||||
// For cross-platform portability; used by `presets/examples/13.jsonc`
|
||||
if (__builtin_expect(options->folders.length == 1 && options->folders.chars[0] == '/', 0))
|
||||
{
|
||||
wchar_t path[MAX_PATH + 1];
|
||||
GetSystemWindowsDirectoryW(path, sizeof(path) / sizeof(*path));
|
||||
ffStrbufSetF(&options->folders, "%c:\\", (char) path[0]);
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < length; i++)
|
||||
{
|
||||
wchar_t* mountpoint = buf + i;
|
||||
@@ -34,28 +55,48 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||
|
||||
FFDisk* disk = ffListAdd(disks);
|
||||
|
||||
if(!GetDiskFreeSpaceExW(
|
||||
disk->filesUsed = 0;
|
||||
disk->filesTotal = 0;
|
||||
disk->bytesTotal = 0;
|
||||
disk->bytesFree = 0;
|
||||
disk->bytesUsed = 0; // To be filled in ./disk.c
|
||||
disk->bytesAvailable = 0;
|
||||
disk->createTime = 0;
|
||||
ffStrbufInit(&disk->filesystem);
|
||||
ffStrbufInit(&disk->name);
|
||||
ffStrbufInitMove(&disk->mountpoint, &buffer);
|
||||
ffStrbufInit(&disk->mountFrom);
|
||||
disk->type = driveType == DRIVE_REMOVABLE || driveType == DRIVE_REMOTE || driveType == DRIVE_CDROM
|
||||
? FF_DISK_VOLUME_TYPE_EXTERNAL_BIT
|
||||
: driveType == DRIVE_FIXED
|
||||
? FF_DISK_VOLUME_TYPE_REGULAR_BIT
|
||||
: FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
|
||||
|
||||
if (mountpoint[2] == L'\\' && mountpoint[3] == L'\0')
|
||||
{
|
||||
wchar_t volumeName[MAX_PATH + 1];
|
||||
mountpoint[2] = L'\0';
|
||||
if(QueryDosDeviceW(mountpoint, volumeName, sizeof(volumeName) / sizeof(*volumeName)))
|
||||
ffStrbufSetWS(&disk->mountFrom, volumeName);
|
||||
mountpoint[2] = L'\\';
|
||||
}
|
||||
|
||||
#ifdef FF_HAVE_THREADS
|
||||
if (driveType == DRIVE_REMOTE)
|
||||
{
|
||||
FFThreadType thread = ffThreadCreate(testRemoteVolumeAccessable, mountpoint);
|
||||
if (!ffThreadJoin(thread, 500))
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
GetDiskFreeSpaceExW(
|
||||
mountpoint,
|
||||
(PULARGE_INTEGER)&disk->bytesAvailable,
|
||||
(PULARGE_INTEGER)&disk->bytesTotal,
|
||||
(PULARGE_INTEGER)&disk->bytesFree
|
||||
))
|
||||
{
|
||||
disk->bytesTotal = 0;
|
||||
disk->bytesFree = 0;
|
||||
disk->bytesAvailable = 0;
|
||||
}
|
||||
disk->bytesUsed = 0; // To be filled in ./disk.c
|
||||
);
|
||||
|
||||
if(driveType == DRIVE_REMOVABLE || driveType == DRIVE_REMOTE || driveType == DRIVE_CDROM)
|
||||
disk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
|
||||
else if(driveType == DRIVE_FIXED)
|
||||
disk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
|
||||
else
|
||||
disk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
|
||||
|
||||
ffStrbufInit(&disk->filesystem);
|
||||
ffStrbufInit(&disk->name);
|
||||
wchar_t diskName[MAX_PATH + 1], diskFileSystem[MAX_PATH + 1];
|
||||
|
||||
//https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getvolumeinformationa#remarks
|
||||
@@ -82,23 +123,6 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||
WIN32_FILE_ATTRIBUTE_DATA data;
|
||||
if(GetFileAttributesExW(mountpoint, GetFileExInfoStandard, &data) && data.ftCreationTime.dwHighDateTime > 0)
|
||||
disk->createTime = (*(uint64_t*) &data.ftCreationTime - 116444736000000000ull) / 10000ull;
|
||||
else
|
||||
disk->createTime = 0;
|
||||
|
||||
ffStrbufInitMove(&disk->mountpoint, &buffer);
|
||||
if (mountpoint[2] == L'\\' && mountpoint[3] == L'\0')
|
||||
{
|
||||
wchar_t volumeName[MAX_PATH + 1];
|
||||
mountpoint[2] = L'\0';
|
||||
if(QueryDosDeviceW(mountpoint, volumeName, sizeof(volumeName) / sizeof(*volumeName)))
|
||||
ffStrbufInitWS(&disk->mountFrom, volumeName);
|
||||
else
|
||||
ffStrbufInit(&disk->mountFrom);
|
||||
}
|
||||
|
||||
//Unsupported
|
||||
disk->filesUsed = 0;
|
||||
disk->filesTotal = 0;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
static void waylandZwlrTransformListener(void* data, FF_MAYBE_UNUSED struct zwlr_output_head_v1 *zwlr_output_head_v1, int32_t transform)
|
||||
{
|
||||
WaylandDisplay* wldata = (WaylandDisplay*) data;
|
||||
wldata->transform = transform;
|
||||
wldata->transform = (enum wl_output_transform) transform;
|
||||
}
|
||||
|
||||
static void waylandZwlrScaleListener(void* data, FF_MAYBE_UNUSED struct zwlr_output_head_v1 *zwlr_output_head_v1, wl_fixed_t scale)
|
||||
|
||||
+15
-33
@@ -14,42 +14,24 @@ const char* FF_GPU_VENDOR_NAME_MICROSOFT = "Microsoft";
|
||||
const char* FF_GPU_VENDOR_NAME_REDHAT = "RedHat";
|
||||
const char* FF_GPU_VENDOR_NAME_ORACLE = "Oracle";
|
||||
|
||||
static inline bool arrayContains(const unsigned arr[], unsigned vendorId, unsigned length)
|
||||
{
|
||||
for (unsigned i = 0; i < length; ++i)
|
||||
{
|
||||
if (arr[i] == vendorId)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* ffGetGPUVendorString(unsigned vendorId)
|
||||
{
|
||||
// https://devicehunt.com/all-pci-vendors
|
||||
if(vendorId == 0x106b)
|
||||
return FF_GPU_VENDOR_NAME_APPLE;
|
||||
if(arrayContains((const unsigned[]) {0x1002, 0x1022}, vendorId, 2))
|
||||
return FF_GPU_VENDOR_NAME_AMD;
|
||||
else if(arrayContains((const unsigned[]) {0x03e7, 0x8086, 0x8087}, vendorId, 3))
|
||||
return FF_GPU_VENDOR_NAME_INTEL;
|
||||
else if(arrayContains((const unsigned[]) {0x0955, 0x10de, 0x12d2}, vendorId, 3))
|
||||
return FF_GPU_VENDOR_NAME_NVIDIA;
|
||||
else if(arrayContains((const unsigned[]) {0x5143}, vendorId, 1))
|
||||
return FF_GPU_VENDOR_NAME_QUALCOMM;
|
||||
else if(arrayContains((const unsigned[]) {0x14c3}, vendorId, 1))
|
||||
return FF_GPU_VENDOR_NAME_MTK;
|
||||
else if(arrayContains((const unsigned[]) {0x15ad}, vendorId, 1))
|
||||
return FF_GPU_VENDOR_NAME_VMWARE;
|
||||
else if(arrayContains((const unsigned[]) {0x1af4}, vendorId, 1))
|
||||
return FF_GPU_VENDOR_NAME_REDHAT;
|
||||
else if(arrayContains((const unsigned[]) {0x1ab8}, vendorId, 1))
|
||||
return FF_GPU_VENDOR_NAME_PARALLEL;
|
||||
else if(arrayContains((const unsigned[]) {0x1414}, vendorId, 1))
|
||||
return FF_GPU_VENDOR_NAME_MICROSOFT;
|
||||
else if(arrayContains((const unsigned[]) {0x108e}, vendorId, 1))
|
||||
return FF_GPU_VENDOR_NAME_ORACLE;
|
||||
return NULL;
|
||||
switch (vendorId)
|
||||
{
|
||||
case 0x106b: return FF_GPU_VENDOR_NAME_APPLE;
|
||||
case 0x1002: case 0x1022: return FF_GPU_VENDOR_NAME_AMD;
|
||||
case 0x8086: case 0x8087: case 0x03e7: return FF_GPU_VENDOR_NAME_INTEL;
|
||||
case 0x0955: case 0x10de: case 0x12d2: return FF_GPU_VENDOR_NAME_NVIDIA;
|
||||
case 0x5143: return FF_GPU_VENDOR_NAME_QUALCOMM;
|
||||
case 0x14c3: return FF_GPU_VENDOR_NAME_MTK;
|
||||
case 0x15ad: return FF_GPU_VENDOR_NAME_VMWARE;
|
||||
case 0x1af4: return FF_GPU_VENDOR_NAME_REDHAT;
|
||||
case 0x1ab8: return FF_GPU_VENDOR_NAME_PARALLEL;
|
||||
case 0x1414: return FF_GPU_VENDOR_NAME_MICROSOFT;
|
||||
case 0x108e: return FF_GPU_VENDOR_NAME_ORACLE;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const char* detectByOpenGL(FFlist* gpus)
|
||||
|
||||
@@ -46,6 +46,8 @@ static void pciDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu,
|
||||
|
||||
ffStrbufAppendS(pciDir, "/hwmon/");
|
||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(pciDir->chars);
|
||||
if (!dirp) return;
|
||||
|
||||
struct dirent* entry;
|
||||
while ((entry = readdir(dirp)) != NULL)
|
||||
{
|
||||
@@ -121,9 +123,11 @@ static void pciDetectIntelSpecific(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf*
|
||||
static bool loadPciIds(FFstrbuf* pciids)
|
||||
{
|
||||
#ifdef FF_CUSTOM_PCI_IDS_PATH
|
||||
|
||||
ffReadFileBuffer(FF_STR(FF_CUSTOM_PCI_IDS_PATH), pciids);
|
||||
if (pciids->length > 0) return true;
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/share/hwdata/pci.ids", pciids);
|
||||
if (pciids->length > 0) return true;
|
||||
@@ -134,6 +138,8 @@ static bool loadPciIds(FFstrbuf* pciids)
|
||||
ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/local/share/hwdata/pci.ids", pciids);
|
||||
if (pciids->length > 0) return true;
|
||||
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -186,7 +192,11 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
|
||||
{
|
||||
char query[32];
|
||||
snprintf(query, sizeof(query), "%X,\t%X,", (unsigned) deviceId, (unsigned) revision);
|
||||
#ifdef FF_CUSTOM_AMDGPU_IDS_PATH
|
||||
ffParsePropFile(FF_STR(FF_CUSTOM_AMDGPU_IDS_PATH), query, &gpu->name);
|
||||
#else
|
||||
ffParsePropFileData("libdrm/amdgpu.ids", query, &gpu->name);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
ffStrbufSubstrBefore(drmDir, drmDirPathLength);
|
||||
@@ -200,8 +210,7 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
|
||||
ffStrbufInit(&pciids);
|
||||
loadPciIds(&pciids);
|
||||
}
|
||||
if (pciids.length)
|
||||
ffGPUParsePciIds(&pciids, subclassId, (uint16_t) vendorId, (uint16_t) deviceId, gpu);
|
||||
ffGPUParsePciIds(&pciids, subclassId, (uint16_t) vendorId, (uint16_t) deviceId, gpu);
|
||||
}
|
||||
|
||||
pciDetectDriver(gpu, drmDir, buffer);
|
||||
@@ -256,7 +265,7 @@ FF_MAYBE_UNUSED static const char* detectAsahi(FFlist* gpus, FFstrbuf* buffer, F
|
||||
{
|
||||
uint32_t index = ffStrbufFirstIndexS(buffer, "apple,agx-t");
|
||||
if (index == buffer->length) return "display-subsystem?";
|
||||
index += strlen("apple,agx-t");
|
||||
index += (uint32_t) strlen("apple,agx-t");
|
||||
|
||||
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
|
||||
gpu->deviceId = strtoul(buffer->chars + index, NULL, 10);
|
||||
|
||||
@@ -18,17 +18,24 @@ typedef struct FFSmbiosSystemInfo
|
||||
uint8_t ClockSeqHiAndReserved;
|
||||
uint8_t ClockSeqLow;
|
||||
uint8_t Node[6];
|
||||
} UUID; // varies
|
||||
} __attribute__((__packed__)) UUID; // varies
|
||||
uint8_t WakeUpType; // enum
|
||||
|
||||
// 2.4+
|
||||
uint8_t SKUNumber; // string
|
||||
uint8_t Family; // string
|
||||
} FFSmbiosSystemInfo;
|
||||
} __attribute__((__packed__)) FFSmbiosSystemInfo;
|
||||
|
||||
static_assert(offsetof(FFSmbiosSystemInfo, Family) == 0x1A,
|
||||
"FFSmbiosSystemInfo: Wrong struct alignment");
|
||||
|
||||
const char* ffDetectHost(FFHostResult* host)
|
||||
{
|
||||
const FFSmbiosSystemInfo* data = (const FFSmbiosSystemInfo*) (*ffGetSmbiosHeaderTable())[FF_SMBIOS_TYPE_SYSTEM_INFO];
|
||||
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
|
||||
if (!smbiosTable)
|
||||
return "Failed to get SMBIOS data";
|
||||
|
||||
const FFSmbiosSystemInfo* data = (const FFSmbiosSystemInfo*) (*smbiosTable)[FF_SMBIOS_TYPE_SYSTEM_INFO];
|
||||
if (!data)
|
||||
return "System information is not found in SMBIOS data";
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
const char* ffDetectLoadavg(double result[3]);
|
||||
@@ -0,0 +1,20 @@
|
||||
#include "detection/loadavg/loadavg.h"
|
||||
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/types.h>
|
||||
#include <sys/resource.h>
|
||||
#include <vm/vm_param.h>
|
||||
#endif
|
||||
|
||||
const char* ffDetectLoadavg(double result[3])
|
||||
{
|
||||
struct loadavg load;
|
||||
size_t size = sizeof(load);
|
||||
if (sysctl((int []) { CTL_VM, VM_LOADAVG }, 2, &load, &size, NULL, 0) < 0)
|
||||
return "sysctl({CTL_VM, VM_LOADAVG}) failed";
|
||||
for (int i = 0; i < 3; i++)
|
||||
result[i] = (double) load.ldavg[i] / (double) load.fscale;
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#include "detection/loadavg/loadavg.h"
|
||||
#include "common/io/io.h"
|
||||
|
||||
#include <sys/sysinfo.h>
|
||||
|
||||
const char* ffDetectLoadavg(double result[3])
|
||||
{
|
||||
#ifndef __ANDROID__ // cat: /proc/loadavg: Permission denied
|
||||
|
||||
// Don't use syscall for container compatibility. #620
|
||||
char buf[64];
|
||||
ssize_t nRead = ffReadFileData("/proc/uptime", sizeof(buf) - 1, buf);
|
||||
if (nRead > 0)
|
||||
{
|
||||
buf[nRead] = '\0';
|
||||
|
||||
if (sscanf(buf, "%lf %lf %lf", &result[0], &result[1], &result[2]) == 3)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// getloadavg requires higher ANDROID_API version
|
||||
struct sysinfo si;
|
||||
if (sysinfo(&si) < 0)
|
||||
return "sysinfo() failed";
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
result[i] = (double) si.loads[i] / (1 << SI_LOAD_SHIFT);
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "detection/loadavg/loadavg.h"
|
||||
|
||||
const char* ffDetectLoadavg(FF_MAYBE_UNUSED double result[3])
|
||||
{
|
||||
return "Not supported on this platform";
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
#include <netpacket/packet.h>
|
||||
#endif
|
||||
|
||||
static void addNewIp(FFlist* list, const char* name, const char* addr, int type, bool defaultRoute)
|
||||
static void addNewIp(FFlist* list, const char* name, const char* addr, int type, bool defaultRoute, bool firstOnly)
|
||||
{
|
||||
FFLocalIpResult* ip = NULL;
|
||||
|
||||
@@ -40,11 +40,19 @@ static void addNewIp(FFlist* list, const char* name, const char* addr, int type,
|
||||
switch (type)
|
||||
{
|
||||
case AF_INET:
|
||||
if (ip->ipv4.length) ffStrbufAppendC(&ip->ipv4, ',');
|
||||
if (ip->ipv4.length)
|
||||
{
|
||||
if (firstOnly) return;
|
||||
ffStrbufAppendC(&ip->ipv4, ',');
|
||||
}
|
||||
ffStrbufAppendS(&ip->ipv4, addr);
|
||||
break;
|
||||
case AF_INET6:
|
||||
if (ip->ipv6.length) ffStrbufAppendC(&ip->ipv6, ',');
|
||||
if (ip->ipv6.length)
|
||||
{
|
||||
if (firstOnly) return;
|
||||
ffStrbufAppendC(&ip->ipv6, ',');
|
||||
}
|
||||
ffStrbufAppendS(&ip->ipv6, addr);
|
||||
break;
|
||||
case -1:
|
||||
@@ -67,7 +75,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
continue;
|
||||
|
||||
bool isDefaultRoute = ffStrEquals(defaultRouteIfName, ifa->ifa_name);
|
||||
if (options->defaultRouteOnly && !isDefaultRoute)
|
||||
if ((options->showType & FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT) && !isDefaultRoute)
|
||||
continue;
|
||||
|
||||
if ((ifa->ifa_flags & IFF_LOOPBACK) && !(options->showType & FF_LOCALIP_TYPE_LOOP_BIT))
|
||||
@@ -96,7 +104,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
}
|
||||
}
|
||||
|
||||
addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET, isDefaultRoute);
|
||||
addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET, isDefaultRoute, !(options->showType & FF_LOCALIP_TYPE_ALL_IPS_BIT));
|
||||
}
|
||||
else if (ifa->ifa_addr->sa_family == AF_INET6)
|
||||
{
|
||||
@@ -121,7 +129,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
}
|
||||
}
|
||||
|
||||
addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET6, isDefaultRoute);
|
||||
addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET6, isDefaultRoute, !(options->showType & FF_LOCALIP_TYPE_ALL_IPS_BIT));
|
||||
}
|
||||
#if defined(__FreeBSD__) || defined(__APPLE__)
|
||||
else if (ifa->ifa_addr->sa_family == AF_LINK)
|
||||
@@ -133,7 +141,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
uint8_t* ptr = (uint8_t*) LLADDR((struct sockaddr_dl *)ifa->ifa_addr);
|
||||
snprintf(addressBuffer, sizeof(addressBuffer), "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
|
||||
addNewIp(results, ifa->ifa_name, addressBuffer, -1, isDefaultRoute);
|
||||
addNewIp(results, ifa->ifa_name, addressBuffer, -1, isDefaultRoute, false);
|
||||
}
|
||||
#else
|
||||
else if (ifa->ifa_addr->sa_family == AF_PACKET)
|
||||
@@ -145,7 +153,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
uint8_t* ptr = ((struct sockaddr_ll *)ifa->ifa_addr)->sll_addr;
|
||||
snprintf(addressBuffer, sizeof(addressBuffer), "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
|
||||
addNewIp(results, ifa->ifa_name, addressBuffer, -1, isDefaultRoute);
|
||||
addNewIp(results, ifa->ifa_name, addressBuffer, -1, isDefaultRoute, false);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
for (IP_ADAPTER_ADDRESSES* adapter = adapter_addresses; adapter; adapter = adapter->Next)
|
||||
{
|
||||
bool isDefaultRoute = adapter->IfIndex == defaultRouteIfIndex;
|
||||
if (options->defaultRouteOnly && !isDefaultRoute)
|
||||
if ((options->showType & FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT) && !isDefaultRoute)
|
||||
continue;
|
||||
|
||||
bool isLoop = adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK;
|
||||
@@ -102,10 +102,14 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
newIp = false;
|
||||
}
|
||||
|
||||
uint32_t typesToAdd = options->showType & (FF_LOCALIP_TYPE_IPV4_BIT | FF_LOCALIP_TYPE_IPV6_BIT | FF_LOCALIP_TYPE_ALL_IPS_BIT);
|
||||
|
||||
for (IP_ADAPTER_UNICAST_ADDRESS* ifa = adapter->FirstUnicastAddress; ifa; ifa = ifa->Next)
|
||||
{
|
||||
if (ifa->Address.lpSockaddr->sa_family == AF_INET)
|
||||
{
|
||||
if (!(typesToAdd & (FF_LOCALIP_TYPE_IPV4_BIT | FF_LOCALIP_TYPE_ALL_IPS_BIT))) continue;
|
||||
|
||||
SOCKADDR_IN* ipv4 = (SOCKADDR_IN*) ifa->Address.lpSockaddr;
|
||||
char addressBuffer[INET_ADDRSTRLEN + 4];
|
||||
inet_ntop(AF_INET, &ipv4->sin_addr, addressBuffer, INET_ADDRSTRLEN);
|
||||
@@ -118,9 +122,14 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
|
||||
addNewIp(results, name, addressBuffer, AF_INET, newIp, isDefaultRoute);
|
||||
newIp = false;
|
||||
|
||||
typesToAdd &= ~(unsigned) FF_LOCALIP_TYPE_IPV4_BIT;
|
||||
if (typesToAdd == 0) break;
|
||||
}
|
||||
else if (ifa->Address.lpSockaddr->sa_family == AF_INET6)
|
||||
{
|
||||
if (!(typesToAdd & (FF_LOCALIP_TYPE_IPV6_BIT | FF_LOCALIP_TYPE_ALL_IPS_BIT))) continue;
|
||||
|
||||
SOCKADDR_IN6* ipv6 = (SOCKADDR_IN6*) ifa->Address.lpSockaddr;
|
||||
char addressBuffer[INET6_ADDRSTRLEN + 4];
|
||||
inet_ntop(AF_INET6, &ipv6->sin6_addr, addressBuffer, INET6_ADDRSTRLEN);
|
||||
@@ -133,6 +142,9 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
|
||||
addNewIp(results, name, addressBuffer, AF_INET6, newIp, isDefaultRoute);
|
||||
newIp = false;
|
||||
|
||||
typesToAdd &= ~(unsigned) FF_LOCALIP_TYPE_IPV6_BIT;
|
||||
if (typesToAdd == 0) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+80
-23
@@ -2,11 +2,15 @@
|
||||
#include "common/properties.h"
|
||||
#include "common/parsing.h"
|
||||
#include "common/io/io.h"
|
||||
#include "common/processing.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define FF_STR_INDIR(x) #x
|
||||
#define FF_STR(x) FF_STR_INDIR(x)
|
||||
|
||||
static inline bool allRelevantValuesSet(const FFOSResult* result)
|
||||
{
|
||||
return result->id.length > 0
|
||||
@@ -15,18 +19,25 @@ static inline bool allRelevantValuesSet(const FFOSResult* result)
|
||||
;
|
||||
}
|
||||
|
||||
static bool parseFile(const char* fileName, FFOSResult* result)
|
||||
static bool parseLsbRelease(const char* fileName, FFOSResult* result)
|
||||
{
|
||||
return ffParsePropFileValues(fileName, 13, (FFpropquery[]) {
|
||||
{"NAME =", &result->name},
|
||||
{"DISTRIB_DESCRIPTION =", &result->prettyName},
|
||||
{"PRETTY_NAME =", &result->prettyName},
|
||||
return ffParsePropFileValues(fileName, 4, (FFpropquery[]) {
|
||||
{"DISTRIB_ID =", &result->id},
|
||||
{"DISTRIB_DESCRIPTION =", &result->prettyName},
|
||||
{"DISTRIB_RELEASE =", &result->version},
|
||||
{"DISTRIB_CODENAME =", &result->codename},
|
||||
});
|
||||
}
|
||||
|
||||
static bool parseOsRelease(const char* fileName, FFOSResult* result)
|
||||
{
|
||||
return ffParsePropFileValues(fileName, 10, (FFpropquery[]) {
|
||||
{"PRETTY_NAME =", &result->prettyName},
|
||||
{"NAME =", &result->name},
|
||||
{"ID =", &result->id},
|
||||
{"ID_LIKE =", &result->idLike},
|
||||
{"VARIANT =", &result->variant},
|
||||
{"VARIANT_ID =", &result->variantID},
|
||||
{"DISTRIB_RELEASE =", &result->version},
|
||||
{"VERSION =", &result->version},
|
||||
{"VERSION_ID =", &result->versionID},
|
||||
{"VERSION_CODENAME =", &result->codename},
|
||||
@@ -132,15 +143,48 @@ static void getDebianVersion(FFOSResult* result)
|
||||
ffStrbufSet(&result->versionID, &debianVersion);
|
||||
}
|
||||
|
||||
static bool detectDebianDerived(FFOSResult* result)
|
||||
{
|
||||
if (ffStrbufStartsWithS(&result->prettyName, "Armbian ")) // Armbian 24.2.1 bookworm
|
||||
{
|
||||
ffStrbufSetS(&result->name, "Armbian");
|
||||
ffStrbufSetS(&result->id, "armbian");
|
||||
ffStrbufSetS(&result->idLike, "debian");
|
||||
ffStrbufClear(&result->versionID);
|
||||
uint32_t versionStart = ffStrbufFirstIndexC(&result->prettyName, ' ') + 1;
|
||||
uint32_t versionEnd = ffStrbufNextIndexC(&result->prettyName, versionStart, ' ');
|
||||
ffStrbufSetNS(&result->versionID, versionEnd - versionStart, result->prettyName.chars + versionStart);
|
||||
return true;
|
||||
}
|
||||
else if (ffPathExists("/usr/bin/pveversion", FF_PATHTYPE_FILE))
|
||||
{
|
||||
ffStrbufSetS(&result->id, "pve");
|
||||
ffStrbufSetS(&result->idLike, "debian");
|
||||
ffStrbufSetS(&result->name, "Proxmox VE");
|
||||
ffStrbufClear(&result->versionID);
|
||||
if (ffProcessAppendStdOut(&result->versionID, (char* const[]) {
|
||||
"/usr/bin/pveversion",
|
||||
NULL,
|
||||
}) == NULL) // pve-manager/8.2.2/9355359cd7afbae4 (running kernel: 6.8.4-2-pve)
|
||||
{
|
||||
ffStrbufSubstrBeforeLastC(&result->versionID, '/');
|
||||
ffStrbufSubstrAfterFirstC(&result->versionID, '/');
|
||||
}
|
||||
ffStrbufSetF(&result->prettyName, "Proxmox VE %s", result->versionID.chars);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void detectOS(FFOSResult* os)
|
||||
{
|
||||
if(instance.config.general.osFile.length > 0)
|
||||
{
|
||||
parseFile(instance.config.general.osFile.chars, os);
|
||||
return;
|
||||
}
|
||||
#ifdef FF_CUSTOM_OS_RELEASE_PATH
|
||||
parseOsRelease(FF_STR(FF_CUSTOM_OS_RELEASE_PATH), os);
|
||||
parseLsbRelease(FF_STR(FF_CUSTOM_OS_RELEASE_PATH), os);
|
||||
return;
|
||||
#endif
|
||||
|
||||
if(instance.config.general.escapeBedrock && parseFile(FASTFETCH_TARGET_DIR_ROOT"/bedrock"FASTFETCH_TARGET_DIR_ETC"/bedrock-release", os))
|
||||
if(instance.config.general.escapeBedrock && parseOsRelease(FASTFETCH_TARGET_DIR_ROOT "/bedrock" FASTFETCH_TARGET_DIR_ETC "/bedrock-release", os))
|
||||
{
|
||||
if(os->id.length == 0)
|
||||
ffStrbufAppendS(&os->id, "bedrock");
|
||||
@@ -150,22 +194,32 @@ static void detectOS(FFOSResult* os)
|
||||
|
||||
if(os->prettyName.length == 0)
|
||||
ffStrbufAppendS(&os->prettyName, "Bedrock Linux");
|
||||
|
||||
parseFile("/bedrock"FASTFETCH_TARGET_DIR_ETC"/os-release", os);
|
||||
|
||||
if(allRelevantValuesSet(os))
|
||||
if(parseOsRelease("/bedrock" FASTFETCH_TARGET_DIR_ETC "/os-release", os) && allRelevantValuesSet(os))
|
||||
return;
|
||||
}
|
||||
|
||||
parseFile(FASTFETCH_TARGET_DIR_ETC"/os-release", os);
|
||||
if(allRelevantValuesSet(os))
|
||||
// Refer: https://gist.github.com/natefoo/814c5bf936922dad97ff
|
||||
|
||||
// Hack for MX Linux. See #847
|
||||
if(parseLsbRelease(FASTFETCH_TARGET_DIR_ETC "/lsb-release", os))
|
||||
{
|
||||
if (ffStrbufEqualS(&os->id, "MX"))
|
||||
{
|
||||
ffStrbufSetStatic(&os->name, "MX");
|
||||
ffStrbufSetStatic(&os->idLike, "debian");
|
||||
return;
|
||||
}
|
||||
|
||||
// For archlinux
|
||||
if (ffStrbufEqualS(&os->version, "rolling"))
|
||||
ffStrbufClear(&os->version);
|
||||
}
|
||||
|
||||
if(parseOsRelease(FASTFETCH_TARGET_DIR_ETC "/os-release", os) && allRelevantValuesSet(os))
|
||||
return;
|
||||
|
||||
parseFile(FASTFETCH_TARGET_DIR_USR"/lib/os-release", os);
|
||||
if(allRelevantValuesSet(os))
|
||||
return;
|
||||
|
||||
parseFile(FASTFETCH_TARGET_DIR_ETC"/lsb-release", os);
|
||||
parseOsRelease(FASTFETCH_TARGET_DIR_USR "/lib/os-release", os);
|
||||
}
|
||||
|
||||
void ffDetectOSImpl(FFOSResult* os)
|
||||
@@ -175,5 +229,8 @@ void ffDetectOSImpl(FFOSResult* os)
|
||||
if(ffStrbufIgnCaseEqualS(&os->id, "ubuntu"))
|
||||
getUbuntuFlavour(os);
|
||||
else if(ffStrbufIgnCaseEqualS(&os->id, "debian"))
|
||||
getDebianVersion(os);
|
||||
{
|
||||
if (!detectDebianDerived(os))
|
||||
getDebianVersion(os);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ typedef struct FFPackagesResult
|
||||
uint32_t rpm;
|
||||
uint32_t scoop;
|
||||
uint32_t snap;
|
||||
uint32_t sorcery;
|
||||
uint32_t winget;
|
||||
uint32_t xbps;
|
||||
|
||||
|
||||
@@ -433,6 +433,7 @@ static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts,
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_PALUDIS_BIT)) packageCounts->paludis += countFilesRecursive(baseDir, "/var/db/paludis/repositories", "environment.bz2");
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_OPKG_BIT)) packageCounts->opkg += getNumStrings(baseDir, "/usr/lib/opkg/status", "Package:"); // openwrt
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_AM_BIT)) packageCounts->am = getAM(baseDir);
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_SORCERY_BIT)) packageCounts->sorcery += getNumStrings(baseDir, "/var/state/sorcery/packages", ":installed:");
|
||||
}
|
||||
|
||||
static void getPackageCountsRegular(FFstrbuf* baseDir, FFPackagesResult* packageCounts, FFPackagesOptions* options)
|
||||
@@ -501,7 +502,36 @@ void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options)
|
||||
|
||||
ffStrbufSet(&baseDir, &instance.state.platform.homeDir);
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_NIX_BIT))
|
||||
result->nixUser = getNixPackages(&baseDir, "/.nix-profile");
|
||||
{
|
||||
// check if ~/.nix-profile exists
|
||||
FF_STRBUF_AUTO_DESTROY profilePath = ffStrbufCreateCopy(&baseDir);
|
||||
ffStrbufAppendS(&profilePath, ".nix-profile");
|
||||
if (ffPathExists(profilePath.chars, FF_PATHTYPE_DIRECTORY))
|
||||
{
|
||||
result->nixUser = getNixPackages(&baseDir, ".nix-profile");
|
||||
}
|
||||
// check if $XDG_STATE_HOME/nix/profile exists
|
||||
else
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY stateDir = ffStrbufCreate();
|
||||
const char* stateHome = getenv("XDG_STATE_HOME");
|
||||
if(ffStrSet(stateHome))
|
||||
{
|
||||
ffStrbufSetS(&stateDir, stateHome);
|
||||
ffStrbufEnsureEndsWithC(&stateDir, '/');
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufSet(&stateDir, &instance.state.platform.homeDir);
|
||||
ffStrbufAppendS(&stateDir, ".local/state/");
|
||||
}
|
||||
|
||||
ffStrbufSet(&profilePath, &stateDir);
|
||||
ffStrbufAppendS(&profilePath, "nix/profile");
|
||||
result->nixUser = getNixPackages(&stateDir, "nix/profile");
|
||||
}
|
||||
}
|
||||
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_FLATPAK_BIT))
|
||||
result->flatpakUser = getFlatpak(&baseDir, "/.local/share/flatpak");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
#include "physicalmemory.h"
|
||||
|
||||
static inline const char* getVendorString(unsigned vendorId)
|
||||
{
|
||||
switch (vendorId)
|
||||
{
|
||||
case 0x017A: return "Apacer";
|
||||
case 0x0198: return "Kingston";
|
||||
case 0x029E: return "Corsair";
|
||||
case 0x04CB: return "A-DATA";
|
||||
case 0x04CD: return "G-Skill";
|
||||
case 0x059B: case 0x859B: return "Crucial";
|
||||
case 0x00CE: case 0x80CE: case 0xCE00: return "Samsung";
|
||||
case 0x014F: return "Transcend";
|
||||
case 0x2C00: case 0x802C: return "Micron";
|
||||
case 0xAD00: case 0x80AD: return "SK Hynix";
|
||||
case 0x5105: case 0x8551: return "Qimonda";
|
||||
case 0x02FE: return "Elpida";
|
||||
case 0x0467: return "Ramaxel";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void FFPhysicalMemoryUpdateVendorString(FFPhysicalMemoryResult* device)
|
||||
{
|
||||
char vendorIdStr[5];
|
||||
if (ffStrbufStartsWithS(&device->vendor, "0x"))
|
||||
{
|
||||
if (device->vendor.length < 6) return;
|
||||
memcpy(vendorIdStr, device->vendor.chars + 2, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (device->vendor.length < 4) return;
|
||||
memcpy(vendorIdStr, device->vendor.chars, 4);
|
||||
}
|
||||
vendorIdStr[4] = '\0';
|
||||
char* pEnd = NULL;
|
||||
uint32_t vendorId = (uint32_t) strtoul(vendorIdStr, &pEnd, 16);
|
||||
if (*pEnd != '\0') return;
|
||||
const char* vendorStr = getVendorString(vendorId);
|
||||
if (vendorStr) ffStrbufSetStatic(&device->vendor, vendorStr);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFPhysicalMemoryResult
|
||||
{
|
||||
uint64_t size; // B
|
||||
uint32_t maxSpeed; // MT/s
|
||||
uint32_t runningSpeed; // MT/s
|
||||
FFstrbuf type;
|
||||
FFstrbuf formFactor;
|
||||
FFstrbuf locator;
|
||||
FFstrbuf partNumber;
|
||||
FFstrbuf vendor;
|
||||
FFstrbuf serial;
|
||||
bool ecc;
|
||||
} FFPhysicalMemoryResult;
|
||||
|
||||
const char* ffDetectPhysicalMemory(FFlist* result); // list of FFPhysicalMemoryResult
|
||||
|
||||
void FFPhysicalMemoryUpdateVendorString(FFPhysicalMemoryResult* device);
|
||||
@@ -0,0 +1,121 @@
|
||||
#include "physicalmemory.h"
|
||||
#include "common/processing.h"
|
||||
#include "util/smbiosHelper.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
static void appendDevice(
|
||||
FFlist* result,
|
||||
NSString* type,
|
||||
NSString* vendor,
|
||||
NSString* size,
|
||||
|
||||
// Intel only
|
||||
NSString* locator,
|
||||
NSString* serial,
|
||||
NSString* partNumber,
|
||||
NSString* speed,
|
||||
bool ecc)
|
||||
{
|
||||
FFPhysicalMemoryResult* device = ffListAdd(result);
|
||||
ffStrbufInitS(&device->type, type.UTF8String);
|
||||
ffStrbufInit(&device->formFactor);
|
||||
ffStrbufInitS(&device->locator, locator.UTF8String);
|
||||
ffStrbufInitS(&device->vendor, vendor.UTF8String);
|
||||
FFPhysicalMemoryUpdateVendorString(device);
|
||||
ffStrbufInitS(&device->serial, serial.UTF8String);
|
||||
ffCleanUpSmbiosValue(&device->serial);
|
||||
ffStrbufInitS(&device->partNumber, partNumber.UTF8String);
|
||||
ffCleanUpSmbiosValue(&device->partNumber);
|
||||
device->size = 0;
|
||||
device->maxSpeed = 0;
|
||||
device->runningSpeed = 0;
|
||||
device->ecc = ecc;
|
||||
|
||||
if (size)
|
||||
{
|
||||
char* unit = NULL;
|
||||
device->size = strtoul(size.UTF8String, &unit, 10);
|
||||
if (*unit == ' ') ++unit;
|
||||
|
||||
switch (*unit)
|
||||
{
|
||||
case 'G': device->size *= 1024ULL * 1024 * 1024; break;
|
||||
case 'M': device->size *= 1024ULL * 1024; break;
|
||||
case 'K': device->size *= 1024ULL; break;
|
||||
case 'T': device->size *= 1024ULL * 1024 * 1024 * 1024; break;
|
||||
}
|
||||
}
|
||||
|
||||
if (speed)
|
||||
{
|
||||
char* unit = NULL;
|
||||
device->maxSpeed = (uint32_t) strtoul(speed.UTF8String, &unit, 10);
|
||||
if (*unit == ' ') ++unit;
|
||||
|
||||
switch (*unit)
|
||||
{
|
||||
case 'T': device->maxSpeed *= 1000 * 1000; break;
|
||||
case 'G': device->maxSpeed *= 1000; break;
|
||||
case 'K': device->maxSpeed /= 1000; break;
|
||||
}
|
||||
device->runningSpeed = device->maxSpeed;
|
||||
}
|
||||
}
|
||||
|
||||
const char* ffDetectPhysicalMemory(FFlist* result)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||
if (ffProcessAppendStdOut(&buffer, (char* const[]) {
|
||||
"system_profiler",
|
||||
"SPMemoryDataType",
|
||||
"-xml",
|
||||
"-detailLevel",
|
||||
"full",
|
||||
NULL
|
||||
}) != NULL)
|
||||
return "Starting `system_profiler SPMemoryDataType -xml -detailLevel full` failed";
|
||||
|
||||
NSArray* arr = [NSPropertyListSerialization propertyListWithData:[NSData dataWithBytes:buffer.chars length:buffer.length]
|
||||
options:NSPropertyListImmutable
|
||||
format:nil
|
||||
error:nil];
|
||||
if (!arr || !arr.count)
|
||||
return "system_profiler SPMemoryDataType returned an empty array";
|
||||
|
||||
for (NSDictionary* data in arr[0][@"_items"])
|
||||
{
|
||||
if (data[@"_items"])
|
||||
{
|
||||
// for Intel
|
||||
for (NSDictionary* item in data[@"_items"])
|
||||
{
|
||||
appendDevice(result,
|
||||
item[@"dimm_type"],
|
||||
item[@"dimm_manufacturer"],
|
||||
item[@"dimm_size"],
|
||||
item[@"_name"],
|
||||
item[@"dimm_serial_number"],
|
||||
item[@"dimm_part_number"],
|
||||
item[@"dimm_speed"],
|
||||
!![data[@"global_ecc_state"] isEqualToString:@"ecc_enabled"]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// for Apple Silicon
|
||||
appendDevice(result,
|
||||
data[@"dimm_type"],
|
||||
data[@"dimm_manufacturer"],
|
||||
data[@"SPMemoryDataType"],
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
#include "physicalmemory.h"
|
||||
#include "util/smbiosHelper.h"
|
||||
|
||||
// 7.18
|
||||
typedef struct FFSmbiosMemoryDevice
|
||||
{
|
||||
FFSmbiosHeader Header;
|
||||
|
||||
// 2.1+
|
||||
uint16_t PhysicalMemoryArrayHandle; // varies
|
||||
uint16_t MemoryErrorInformationHandle; //varies
|
||||
uint16_t TotalWidth; // varies
|
||||
uint16_t DataWidth; // varies
|
||||
uint16_t Size; // varies
|
||||
uint8_t FormFactor; // enum
|
||||
uint8_t DeviceSet; // varies
|
||||
uint8_t DeviceLocator; // string
|
||||
uint8_t BankLocator; // string
|
||||
uint8_t MemoryType; // enum
|
||||
uint16_t TypeDetail; // bit field
|
||||
|
||||
// 2.3+
|
||||
uint16_t Speed; // varies
|
||||
uint8_t Manufacturer; // string
|
||||
uint8_t SerialNumber; // string
|
||||
uint8_t AssetTag; // string
|
||||
uint8_t PartNumber; // string
|
||||
|
||||
// 2.6+
|
||||
uint8_t Attributes; // varies
|
||||
|
||||
// 2.7+
|
||||
uint32_t ExtendedSize; // varies
|
||||
uint16_t ConfiguredMemorySpeed; // varies
|
||||
|
||||
// 2.8+
|
||||
uint16_t MinimumVoltage; // varies
|
||||
uint16_t MaximumVoltage; // varies
|
||||
uint16_t ConfiguredVoltage; // varies
|
||||
|
||||
// 3.2+
|
||||
uint8_t MemoryTechnology; // varies
|
||||
uint16_t MemoryOperatingMode; // bit field
|
||||
uint8_t FirmwareVersion; // string
|
||||
uint16_t ModuleManufacturerID; // varies
|
||||
uint16_t ModuleProductID; // varies
|
||||
uint16_t MemorySubsystemControllerManufacturerID; // vaies
|
||||
uint16_t MemorySubsystemControllerProductID; // varies
|
||||
uint64_t NonVolatileSize; // varies
|
||||
uint64_t VolatileSize; // varies
|
||||
uint64_t CacheSize; // varies
|
||||
uint64_t LogicalSize; // varies
|
||||
|
||||
// 3.3+
|
||||
uint32_t ExtendedSpeed; // varies
|
||||
uint32_t ExtendedConfiguredSpeed; // varies
|
||||
|
||||
// 3.7+
|
||||
uint16_t Pmic0ManufacturerID; // varies
|
||||
uint16_t Pmic0RevisionNumber; // varies
|
||||
uint16_t RcdManufacturerID; // varies
|
||||
uint16_t RcdRevisionNumber; // varies
|
||||
} __attribute__((__packed__)) FFSmbiosMemoryDevice;
|
||||
|
||||
static_assert(offsetof(FFSmbiosMemoryDevice, RcdRevisionNumber) == 0x62,
|
||||
"FFSmbiosMemoryDevice: Wrong struct alignment");
|
||||
|
||||
const char* ffDetectPhysicalMemory(FFlist* result)
|
||||
{
|
||||
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
|
||||
if (!smbiosTable)
|
||||
return "Failed to get SMBIOS data";
|
||||
|
||||
const FFSmbiosMemoryDevice* data = (const FFSmbiosMemoryDevice*) (*smbiosTable)[FF_SMBIOS_TYPE_MEMORY_DEVICE];
|
||||
if (!data)
|
||||
return "Memory device is not found in SMBIOS data";
|
||||
|
||||
for (; data->Header.Type == FF_SMBIOS_TYPE_MEMORY_DEVICE;
|
||||
data = (const FFSmbiosMemoryDevice*) ffSmbiosNextEntry(&data->Header))
|
||||
{
|
||||
if (data->Size == 0) continue;
|
||||
|
||||
const char* strings = (const char*) data + data->Header.Length;
|
||||
|
||||
FFPhysicalMemoryResult* device = ffListAdd(result);
|
||||
ffStrbufInit(&device->type);
|
||||
ffStrbufInit(&device->formFactor);
|
||||
ffStrbufInit(&device->locator);
|
||||
ffStrbufInit(&device->vendor);
|
||||
ffStrbufInit(&device->serial);
|
||||
ffStrbufInit(&device->partNumber);
|
||||
device->size = 0;
|
||||
device->maxSpeed = 0;
|
||||
device->runningSpeed = 0;
|
||||
device->ecc = false;
|
||||
|
||||
if (data->TotalWidth != 0xFFFF && data->DataWidth != 0xFFFF)
|
||||
device->ecc = data->TotalWidth > data->DataWidth;
|
||||
|
||||
if (data->Size != 0xFFFF)
|
||||
{
|
||||
if (data->Size == 0x7FFF)
|
||||
device->size = (data->ExtendedSize & ~(1 << 31)) * 1024 * 1024;
|
||||
else if (data->Size & (1 << 15))
|
||||
{
|
||||
// in kB
|
||||
device->size = (data->Size & ~(1u << 15)) * 1024ULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// in MB
|
||||
device->size = data->Size * 1024ULL * 1024ULL;
|
||||
}
|
||||
}
|
||||
|
||||
ffStrbufSetF(&device->locator, "%s/%s", ffSmbiosLocateString(strings, data->BankLocator), ffSmbiosLocateString(strings, data->DeviceLocator));
|
||||
|
||||
switch (data->FormFactor)
|
||||
{
|
||||
case 0x01: ffStrbufSetStatic(&device->formFactor, "Other"); break;
|
||||
case 0x02: ffStrbufSetStatic(&device->formFactor, "Unknown"); break;
|
||||
case 0x03: ffStrbufSetStatic(&device->formFactor, "SIMM"); break;
|
||||
case 0x04: ffStrbufSetStatic(&device->formFactor, "SIP"); break;
|
||||
case 0x05: ffStrbufSetStatic(&device->formFactor, "Chip"); break;
|
||||
case 0x06: ffStrbufSetStatic(&device->formFactor, "DIP"); break;
|
||||
case 0x07: ffStrbufSetStatic(&device->formFactor, "ZIP"); break;
|
||||
case 0x08: ffStrbufSetStatic(&device->formFactor, "Proprietary Card"); break;
|
||||
case 0x09: ffStrbufSetStatic(&device->formFactor, "DIMM"); break;
|
||||
case 0x0A: ffStrbufSetStatic(&device->formFactor, "TSOP"); break;
|
||||
case 0x0B: ffStrbufSetStatic(&device->formFactor, "Row of chips"); break;
|
||||
case 0x0C: ffStrbufSetStatic(&device->formFactor, "RIMM"); break;
|
||||
case 0x0D: ffStrbufSetStatic(&device->formFactor, "SODIMM"); break;
|
||||
case 0x0E: ffStrbufSetStatic(&device->formFactor, "SRIMM"); break;
|
||||
case 0x0F: ffStrbufSetStatic(&device->formFactor, "FBDIMM"); break;
|
||||
case 0x10: ffStrbufSetStatic(&device->formFactor, "Die"); break;
|
||||
default: ffStrbufSetF(&device->formFactor, "Unknown (%d)", (int) data->FormFactor); break;
|
||||
}
|
||||
|
||||
switch (data->MemoryType)
|
||||
{
|
||||
case 0x01: ffStrbufSetStatic(&device->type, "Other"); break;
|
||||
case 0x02: ffStrbufSetStatic(&device->type, "Unknown"); break;
|
||||
case 0x03: ffStrbufSetStatic(&device->type, "DRAM"); break;
|
||||
case 0x04: ffStrbufSetStatic(&device->type, "EDRAM"); break;
|
||||
case 0x05: ffStrbufSetStatic(&device->type, "VRAM"); break;
|
||||
case 0x06: ffStrbufSetStatic(&device->type, "SRAM"); break;
|
||||
case 0x07: ffStrbufSetStatic(&device->type, "RAM"); break;
|
||||
case 0x08: ffStrbufSetStatic(&device->type, "ROM"); break;
|
||||
case 0x09: ffStrbufSetStatic(&device->type, "FLASH"); break;
|
||||
case 0x0A: ffStrbufSetStatic(&device->type, "EEPROM"); break;
|
||||
case 0x0B: ffStrbufSetStatic(&device->type, "FEPROM"); break;
|
||||
case 0x0C: ffStrbufSetStatic(&device->type, "EPROM"); break;
|
||||
case 0x0D: ffStrbufSetStatic(&device->type, "CDRAM"); break;
|
||||
case 0x0E: ffStrbufSetStatic(&device->type, "3DRAM"); break;
|
||||
case 0x0F: ffStrbufSetStatic(&device->type, "SDRAM"); break;
|
||||
case 0x10: ffStrbufSetStatic(&device->type, "SGRAM"); break;
|
||||
case 0x11: ffStrbufSetStatic(&device->type, "RDRAM"); break;
|
||||
case 0x12: ffStrbufSetStatic(&device->type, "DDR"); break;
|
||||
case 0x13: ffStrbufSetStatic(&device->type, "DDR2"); break;
|
||||
case 0x14: ffStrbufSetStatic(&device->type, "DDR2 FB-DIMM"); break;
|
||||
case 0x15:
|
||||
case 0x16:
|
||||
case 0x17: ffStrbufSetStatic(&device->type, "Reserved"); break;
|
||||
case 0x18: ffStrbufSetStatic(&device->type, "DDR3"); break;
|
||||
case 0x19: ffStrbufSetStatic(&device->type, "FBD2"); break;
|
||||
case 0x1A: ffStrbufSetStatic(&device->type, "DDR4"); break;
|
||||
case 0x1B: ffStrbufSetStatic(&device->type, "LPDDR"); break;
|
||||
case 0x1C: ffStrbufSetStatic(&device->type, "LPDDR2"); break;
|
||||
case 0x1D: ffStrbufSetStatic(&device->type, "LPDDR3"); break;
|
||||
case 0x1E: ffStrbufSetStatic(&device->type, "LPDDR4"); break;
|
||||
case 0x1F: ffStrbufSetStatic(&device->type, "Logical non-volatile device"); break;
|
||||
case 0x20: ffStrbufSetStatic(&device->type, "HBM"); break;
|
||||
case 0x21: ffStrbufSetStatic(&device->type, "HBM2"); break;
|
||||
case 0x22: ffStrbufSetStatic(&device->type, "DDR5"); break;
|
||||
case 0x23: ffStrbufSetStatic(&device->type, "LPDDR5"); break;
|
||||
case 0x24: ffStrbufSetStatic(&device->type, "HBM3"); break;
|
||||
default: ffStrbufSetF(&device->type, "Unknown (%d)", (int) data->MemoryType); break;
|
||||
}
|
||||
|
||||
if (data->Header.Length > offsetof(FFSmbiosMemoryDevice, Speed)) // 2.3+
|
||||
{
|
||||
if (data->Speed)
|
||||
device->maxSpeed = data->Speed == 0xFFFF ? data->ExtendedSpeed : data->Speed;
|
||||
|
||||
ffStrbufSetStatic(&device->vendor, ffSmbiosLocateString(strings, data->Manufacturer));
|
||||
FFPhysicalMemoryUpdateVendorString(device);
|
||||
|
||||
ffStrbufSetStatic(&device->serial, ffSmbiosLocateString(strings, data->SerialNumber));
|
||||
ffCleanUpSmbiosValue(&device->serial);
|
||||
|
||||
ffStrbufSetStatic(&device->partNumber, ffSmbiosLocateString(strings, data->PartNumber));
|
||||
ffCleanUpSmbiosValue(&device->partNumber);
|
||||
}
|
||||
|
||||
if (data->Header.Length > offsetof(FFSmbiosMemoryDevice, ConfiguredMemorySpeed)) // 2.7+
|
||||
{
|
||||
if (data->ConfiguredMemorySpeed)
|
||||
device->runningSpeed = data->ConfiguredMemorySpeed == 0xFFFF
|
||||
? data->ExtendedConfiguredSpeed : data->ConfiguredMemorySpeed;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "physicalmemory.h"
|
||||
|
||||
const char* ffDetectPhysicalMemory(FF_MAYBE_UNUSED FFlist* result)
|
||||
{
|
||||
return "Not supported on this platform";
|
||||
}
|
||||
@@ -2,21 +2,24 @@
|
||||
#include "common/networking.h"
|
||||
|
||||
#define FF_UNITIALIZED ((const char*)(uintptr_t) -1)
|
||||
static FFNetworkingState state;
|
||||
static const char* status = FF_UNITIALIZED;
|
||||
static FFNetworkingState states[2];
|
||||
static const char* statuses[2] = { FF_UNITIALIZED, FF_UNITIALIZED };
|
||||
|
||||
void ffPreparePublicIp(FFPublicIpOptions* options)
|
||||
{
|
||||
if (status != FF_UNITIALIZED)
|
||||
FFNetworkingState* state = &states[options->ipv6];
|
||||
const char** status = &statuses[options->ipv6];
|
||||
if (*status != FF_UNITIALIZED)
|
||||
{
|
||||
fputs("Error: this module can only be used once due to internal limitations\n", stderr);
|
||||
fputs("Error: PublicIp module can only be used once due to internal limitations\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
state.timeout = options->timeout;
|
||||
state->timeout = options->timeout;
|
||||
state->ipv6 = options->ipv6;
|
||||
|
||||
if (options->url.length == 0)
|
||||
status = ffNetworkingSendHttpRequest(&state, "ipinfo.io", "/json", NULL);
|
||||
*status = ffNetworkingSendHttpRequest(state, options->ipv6 ? "v6.ipinfo.io" : "ipinfo.io", "/json", NULL);
|
||||
else
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY host = ffStrbufCreateCopy(&options->url);
|
||||
@@ -28,7 +31,7 @@ void ffPreparePublicIp(FFPublicIpOptions* options)
|
||||
fputs("Error: only http: protocol is supported. Use `Command` module with `curl` if needed\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
ffStrbufSubstrAfter(&host, hostStartIndex + (strlen("://") - 1));
|
||||
ffStrbufSubstrAfter(&host, hostStartIndex + (uint32_t) (strlen("://") - 1));
|
||||
}
|
||||
uint32_t pathStartIndex = ffStrbufFirstIndexC(&host, '/');
|
||||
|
||||
@@ -40,7 +43,7 @@ void ffPreparePublicIp(FFPublicIpOptions* options)
|
||||
host.chars[pathStartIndex] = '\0';
|
||||
}
|
||||
|
||||
status = ffNetworkingSendHttpRequest(&state, host.chars, path.length == 0 ? "/" : path.chars, NULL);
|
||||
*status = ffNetworkingSendHttpRequest(state, host.chars, path.length == 0 ? "/" : path.chars, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,14 +56,16 @@ static inline void wrapYyjsonFree(yyjson_doc** doc)
|
||||
|
||||
const char* ffDetectPublicIp(FFPublicIpOptions* options, FFPublicIpResult* result)
|
||||
{
|
||||
if (status == FF_UNITIALIZED)
|
||||
FFNetworkingState* state = &states[options->ipv6];
|
||||
const char** status = &statuses[options->ipv6];
|
||||
if (*status == FF_UNITIALIZED)
|
||||
ffPreparePublicIp(options);
|
||||
|
||||
if (status != NULL)
|
||||
return status;
|
||||
if (*status != NULL)
|
||||
return *status;
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY response = ffStrbufCreateA(4096);
|
||||
const char* error = ffNetworkingRecvHttpResponse(&state, &response);
|
||||
const char* error = ffNetworkingRecvHttpResponse(state, &response);
|
||||
if (error == NULL)
|
||||
ffStrbufSubstrAfterFirstS(&response, "\r\n\r\n");
|
||||
else
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "common/properties.h"
|
||||
#include "common/parsing.h"
|
||||
#include "common/io/io.h"
|
||||
#include "common/processing.h"
|
||||
#include "detection/terminalshell/terminalshell.h"
|
||||
#include "detection/displayserver/displayserver.h"
|
||||
#include "util/mallocHelper.h"
|
||||
@@ -265,9 +266,9 @@ static void detectXterm(FFTerminalFontResult* terminalFont)
|
||||
ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars);
|
||||
}
|
||||
|
||||
static void detectSt(FFTerminalFontResult* terminalFont, uint32_t pid)
|
||||
static void detectSt(FFTerminalFontResult* terminalFont, const FFTerminalResult* terminal)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY size = ffStrbufCreateF("/proc/%u/cmdline", pid);
|
||||
FF_STRBUF_AUTO_DESTROY size = ffStrbufCreateF("/proc/%u/cmdline", terminal->pid);
|
||||
FF_STRBUF_AUTO_DESTROY font = ffStrbufCreate();
|
||||
if (!ffAppendFileBuffer(size.chars, &font))
|
||||
{
|
||||
@@ -276,20 +277,53 @@ static void detectSt(FFTerminalFontResult* terminalFont, uint32_t pid)
|
||||
}
|
||||
|
||||
const char* p = memmem(font.chars, font.length, "\0-f", sizeof("\0-f")); // find parameter of `-f`
|
||||
if (!p)
|
||||
if (p)
|
||||
{
|
||||
ffStrbufAppendF(&terminalFont->error, "st was not executed with `-f` parameter");
|
||||
return;
|
||||
// st was executed with `-f` parameter
|
||||
ffStrbufSubstrAfter(&font, (uint32_t) (p + (sizeof("\0-f") - 1) - font.chars));
|
||||
ffStrbufRecalculateLength(&font);
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufClear(&font);
|
||||
if (ffProcessAppendStdOut(&font, (char* const[]) {
|
||||
"strings",
|
||||
terminal->exePath.chars,
|
||||
NULL,
|
||||
}) != NULL || font.length == 0)
|
||||
{
|
||||
ffStrbufAppendS(&terminalFont->error, "Failed to run `strings st`");
|
||||
return;
|
||||
}
|
||||
|
||||
// Search font config string in st binary
|
||||
uint32_t middleIndex = ffStrbufFirstIndexS(&font, "size=");
|
||||
if (middleIndex == font.length)
|
||||
{
|
||||
ffStrbufAppendS(&terminalFont->error, "No font config found in st binary");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t startIndex = ffStrbufPreviousIndexC(&font, middleIndex, '\n');
|
||||
if (startIndex == font.length) startIndex = 0;
|
||||
uint32_t endIndex = ffStrbufNextIndexC(&font, middleIndex, '\n');
|
||||
|
||||
ffStrbufSubstrBefore(&font, endIndex);
|
||||
ffStrbufSubstrAfter(&font, startIndex);
|
||||
}
|
||||
|
||||
ffStrbufSubstrAfter(&font, (uint32_t) (p + (sizeof("\0-f") - 1) - font.chars));
|
||||
ffStrbufRecalculateLength(&font);
|
||||
// JetBrainsMono Nerd Font Mono:pixelsize=12:antialias=true:autohint=true
|
||||
|
||||
// `monospace:size=15` || `monospace` || `:size=15`
|
||||
uint32_t index = ffStrbufFirstIndexS(&font, ":size=");
|
||||
uint32_t index = ffStrbufFirstIndexC(&font, ':');
|
||||
if (index != font.length)
|
||||
{
|
||||
ffStrbufSetS(&size, font.chars + index + strlen(":size="));
|
||||
uint32_t sIndex = ffStrbufNextIndexS(&font, index + 1, "size=");
|
||||
if (sIndex != font.length)
|
||||
{
|
||||
sIndex += strlen("size=");
|
||||
uint32_t sIndexEnd = ffStrbufNextIndexC(&font, sIndex, ':');
|
||||
ffStrbufSetNS(&size, sIndexEnd - sIndex, font.chars + sIndex);
|
||||
}
|
||||
ffStrbufSubstrBefore(&font, index);
|
||||
}
|
||||
else
|
||||
@@ -365,7 +399,7 @@ void ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFo
|
||||
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "xterm"))
|
||||
detectXterm(terminalFont);
|
||||
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "st"))
|
||||
detectSt(terminalFont, terminal->pid);
|
||||
detectSt(terminalFont, terminal);
|
||||
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "warp"))
|
||||
detectWarp(terminalFont);
|
||||
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "weston-terminal"))
|
||||
|
||||
@@ -228,7 +228,10 @@ bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
|
||||
{
|
||||
if (!instance.config.display.tsVersion) return false;
|
||||
|
||||
if(strcasecmp(exeName, "bash") == 0 || strcasecmp(exeName, "sh") == 0)
|
||||
if(ffStrEqualsIgnCase(exeName, "sh")) // #849
|
||||
return false;
|
||||
|
||||
if(strcasecmp(exeName, "bash") == 0)
|
||||
return getShellVersionBash(exe, version);
|
||||
if(strcasecmp(exeName, "zsh") == 0)
|
||||
return getExeVersionGeneral(exe, version); //zsh 5.9 (arm-apple-darwin21.3.0)
|
||||
|
||||
@@ -46,7 +46,7 @@ static void getProcessInformation(pid_t pid, FFstrbuf* processName, FFstrbuf* ex
|
||||
ssize_t length = readlink(filePath, exePath->chars, exePath->allocated - 1);
|
||||
if (length > 0) // doesn't contain trailing NUL
|
||||
{
|
||||
exePath->chars[length + 1] = '\0';
|
||||
exePath->chars[length] = '\0';
|
||||
exePath->length = (uint32_t) length;
|
||||
}
|
||||
|
||||
@@ -243,6 +243,7 @@ static pid_t getShellInfo(FFShellResult* result, pid_t pid)
|
||||
ffStrEquals(name, "perf") ||
|
||||
ffStrEquals(name, "guake-wrapped") ||
|
||||
ffStrEquals(name, "time") ||
|
||||
ffStrEquals(name, "hyfetch") || //when hyfetch uses fastfetch as backend
|
||||
ffStrContainsIgnCase(name, "debug") ||
|
||||
ffStrContainsIgnCase(name, "not-found") ||
|
||||
ffStrEndsWith(name, ".sh")
|
||||
@@ -306,10 +307,19 @@ static pid_t getTerminalInfo(FFTerminalResult* result, pid_t pid)
|
||||
|
||||
#ifdef __APPLE__
|
||||
// https://github.com/fastfetch-cli/fastfetch/discussions/501
|
||||
if (ffStrEndsWith(name, " (figterm)") || ffStrEndsWith(name, " (cwterm)"))
|
||||
const char* pLeft = strstr(name, " (");
|
||||
if (pLeft)
|
||||
{
|
||||
if (__builtin_expect(getProcessNameAndPpid(ppid, name, &ppid, NULL) != NULL, false))
|
||||
return 0;
|
||||
pLeft += 2;
|
||||
const char* pRight = strstr(pLeft, "term)");
|
||||
if (pRight && pRight[5] == '\0')
|
||||
{
|
||||
for (; pLeft < pRight; ++pLeft)
|
||||
if (*pLeft < 'a' || *pLeft > 'z')
|
||||
break;
|
||||
if (pLeft == pRight && getProcessNameAndPpid(ppid, name, &ppid, NULL) != NULL)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -518,6 +528,11 @@ static void setTerminalInfoDetails(FFTerminalResult* result)
|
||||
|
||||
else if(ffStrbufEqualS(&result->processName, "iTerm.app") || ffStrbufStartsWithS(&result->processName, "iTermServer-"))
|
||||
ffStrbufInitStatic(&result->prettyName, "iTerm");
|
||||
else if(ffStrbufEndsWithS(&result->exePath, "Terminal.app/Contents/MacOS/Terminal"))
|
||||
{
|
||||
ffStrbufSetStatic(&result->processName, "Apple_Terminal"); // for terminal font detection
|
||||
ffStrbufInitStatic(&result->prettyName, "Apple Terminal");
|
||||
}
|
||||
else if(ffStrbufEqualS(&result->processName, "Apple_Terminal"))
|
||||
ffStrbufInitStatic(&result->prettyName, "Apple Terminal");
|
||||
else if(ffStrbufEqualS(&result->processName, "WarpTerminal"))
|
||||
|
||||
@@ -104,6 +104,7 @@ static uint32_t getShellInfo(FFShellResult* result, uint32_t pid)
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "python") || // python on windows generates shim executables
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "fastfetch") || // scoop warps the real binaries with a "shim" exe
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "flashfetch") ||
|
||||
ffStrbufIgnCaseEqualS(&result->prettyName, "hyfetch") || // uses fastfetch as backend
|
||||
ffStrbufContainIgnCaseS(&result->prettyName, "debug") ||
|
||||
ffStrbufContainIgnCaseS(&result->prettyName, "time") ||
|
||||
ffStrbufStartsWithIgnCaseS(&result->prettyName, "ConEmu") // https://github.com/fastfetch-cli/fastfetch/issues/488#issuecomment-1619982014
|
||||
|
||||
@@ -8,7 +8,7 @@ void ffPrepareWeather(FFWeatherOptions* options)
|
||||
{
|
||||
if (status != FF_UNITIALIZED)
|
||||
{
|
||||
fputs("Error: this module can only be used once due to internal limitations\n", stderr);
|
||||
fputs("Error: Weather module can only be used once due to internal limitations\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
+58
-175
@@ -249,7 +249,7 @@ static void printCommandHelp(const char* command)
|
||||
puts(FASTFETCH_DATATEXT_HELP_COLOR);
|
||||
else if(ffStrEqualsIgnCase(command, "format"))
|
||||
puts(FASTFETCH_DATATEXT_HELP_FORMAT);
|
||||
else if(isalpha(command[0]) && ffStrEndsWithIgnCase(command, "-format")) // <module>-format
|
||||
else if(ffCharIsEnglishAlphabet(command[0]) && ffStrEndsWithIgnCase(command, "-format")) // <module>-format
|
||||
printCommandFormatHelp(command);
|
||||
else if(!printSpecificCommandHelp(command))
|
||||
fprintf(stderr, "Error: No specific help for command '%s' provided\n", command);
|
||||
@@ -317,7 +317,43 @@ static void listModules(bool pretty)
|
||||
}
|
||||
}
|
||||
|
||||
static void parseOption(FFdata* data, const char* key, const char* value);
|
||||
// Temporary copy before new release of yyjson
|
||||
static bool ffyyjson_locate_pos(const char *str, size_t len, size_t pos,
|
||||
size_t *line, size_t *col, size_t *chr) {
|
||||
size_t line_sum = 0, line_pos = 0, chr_sum = 0;
|
||||
const uint8_t *cur = (const uint8_t *)str;
|
||||
const uint8_t *end = cur + pos;
|
||||
|
||||
if (!str || pos > len) {
|
||||
if (line) *line = 0;
|
||||
if (col) *col = 0;
|
||||
if (chr) *chr = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
while (cur < end) {
|
||||
uint8_t c = *cur;
|
||||
chr_sum += 1;
|
||||
if (__builtin_expect(c < 0x80, true)) { /* 0xxxxxxx (0x00-0x7F) ASCII */
|
||||
if (c == '\n') {
|
||||
line_sum += 1;
|
||||
line_pos = chr_sum;
|
||||
}
|
||||
cur += 1;
|
||||
}
|
||||
else if (c < 0xC0) cur += 1; /* 10xxxxxx (0x80-0xBF) Invalid */
|
||||
else if (c < 0xE0) cur += 2; /* 110xxxxx (0xC0-0xDF) 2-byte UTF-8 */
|
||||
else if (c < 0xF0) cur += 3; /* 1110xxxx (0xE0-0xEF) 3-byte UTF-8 */
|
||||
else if (c < 0xF8) cur += 4; /* 11110xxx (0xF0-0xF7) 4-byte UTF-8 */
|
||||
else cur += 1; /* 11111xxx (0xF8-0xFF) Invalid */
|
||||
}
|
||||
|
||||
if (line) *line = line_sum + 1;
|
||||
if (col) *col = chr_sum - line_pos + 1;
|
||||
if (chr) *chr = chr_sum;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool parseJsoncFile(const char* path)
|
||||
{
|
||||
@@ -325,12 +361,16 @@ static bool parseJsoncFile(const char* path)
|
||||
|
||||
{
|
||||
yyjson_read_err error;
|
||||
instance.state.configDoc = yyjson_read_file(path, YYJSON_READ_ALLOW_COMMENTS | YYJSON_READ_ALLOW_TRAILING_COMMAS | YYJSON_READ_ALLOW_INF_AND_NAN, NULL, &error);
|
||||
instance.state.configDoc = yyjson_read_file(path, YYJSON_READ_ALLOW_COMMENTS | YYJSON_READ_ALLOW_TRAILING_COMMAS, NULL, &error);
|
||||
if (!instance.state.configDoc)
|
||||
{
|
||||
if (error.code != YYJSON_READ_ERROR_FILE_OPEN)
|
||||
{
|
||||
fprintf(stderr, "Error: failed to parse JSON config file `%s` at pos %zu: %s\n", path, error.pos, error.msg);
|
||||
size_t row = 0, col = error.pos;
|
||||
FF_STRBUF_AUTO_DESTROY content = ffStrbufCreate();
|
||||
if (ffAppendFileBuffer(path, &content))
|
||||
ffyyjson_locate_pos(content.chars, content.length, error.pos, &row, &col, NULL);
|
||||
fprintf(stderr, "Error: failed to parse JSON config file `%s` at (%zu, %zu): %s\n", path, row, col, error.msg);
|
||||
exit(477);
|
||||
}
|
||||
return false;
|
||||
@@ -360,104 +400,6 @@ static bool parseJsoncFile(const char* path)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parseConfigFile(FFdata* data, const char* path)
|
||||
{
|
||||
FF_AUTO_CLOSE_FILE FILE* file = fopen(path, "r");
|
||||
if(file == NULL)
|
||||
return false;
|
||||
|
||||
char* line = NULL;
|
||||
size_t len = 0;
|
||||
ssize_t read;
|
||||
FF_STRBUF_AUTO_DESTROY unescaped = ffStrbufCreate();
|
||||
|
||||
while ((read = getline(&line, &len, file)) != -1)
|
||||
{
|
||||
char* lineStart = line;
|
||||
char* lineEnd = line + read - 1;
|
||||
|
||||
//Trim line left
|
||||
while(isspace(*lineStart))
|
||||
++lineStart;
|
||||
|
||||
//Continue if line is empty or a comment
|
||||
if(*lineStart == '\0' || *lineStart == '#')
|
||||
continue;
|
||||
|
||||
//Trim line right
|
||||
while(lineEnd > lineStart && isspace(*lineEnd))
|
||||
--lineEnd;
|
||||
*(lineEnd + 1) = '\0';
|
||||
|
||||
char* valueStart = strchr(lineStart, ' ');
|
||||
|
||||
//If the line has no white space, it is only a key
|
||||
if(valueStart == NULL)
|
||||
{
|
||||
parseOption(data, lineStart, NULL);
|
||||
continue;
|
||||
}
|
||||
|
||||
//separate the key from the value
|
||||
*valueStart = '\0';
|
||||
++valueStart;
|
||||
|
||||
//Trim space of value left
|
||||
while(isspace(*valueStart))
|
||||
++valueStart;
|
||||
|
||||
//If we want whitespace in values, we need to quote it. This is done to keep consistency with shell.
|
||||
if((*valueStart == '"' || *valueStart == '\'') && *valueStart == *lineEnd && lineEnd > valueStart)
|
||||
{
|
||||
++valueStart;
|
||||
*lineEnd = '\0';
|
||||
--lineEnd;
|
||||
}
|
||||
|
||||
if (strchr(valueStart, '\\'))
|
||||
{
|
||||
// Unescape all `\x`s
|
||||
const char* value = valueStart;
|
||||
while(*value != '\0')
|
||||
{
|
||||
if(*value != '\\')
|
||||
{
|
||||
ffStrbufAppendC(&unescaped, *value);
|
||||
++value;
|
||||
continue;
|
||||
}
|
||||
|
||||
++value;
|
||||
|
||||
switch(*value)
|
||||
{
|
||||
case 'n': ffStrbufAppendC(&unescaped, '\n'); break;
|
||||
case 't': ffStrbufAppendC(&unescaped, '\t'); break;
|
||||
case 'e': ffStrbufAppendC(&unescaped, '\e'); break;
|
||||
case '\\': ffStrbufAppendC(&unescaped, '\\'); break;
|
||||
default:
|
||||
ffStrbufAppendC(&unescaped, '\\');
|
||||
ffStrbufAppendC(&unescaped, *value);
|
||||
break;
|
||||
}
|
||||
|
||||
++value;
|
||||
}
|
||||
parseOption(data, lineStart, unescaped.chars);
|
||||
ffStrbufClear(&unescaped);
|
||||
}
|
||||
else
|
||||
{
|
||||
parseOption(data, lineStart, valueStart);
|
||||
}
|
||||
}
|
||||
|
||||
if(line != NULL)
|
||||
free(line);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void generateConfigFile(bool force, const char* filePath)
|
||||
{
|
||||
if (!filePath)
|
||||
@@ -467,11 +409,6 @@ static void generateConfigFile(bool force, const char* filePath)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ffStrEqualsIgnCase(filePath, "conf") || ffStrEqualsIgnCase(filePath, "jsonc"))
|
||||
{
|
||||
fputs("Error: specifying file type is no longer supported\n", stderr);
|
||||
exit(477);
|
||||
}
|
||||
ffStrbufSetS(&instance.state.genConfigPath, filePath);
|
||||
}
|
||||
|
||||
@@ -507,19 +444,15 @@ static void optionParseConfigFile(FFdata* data, const char* key, const char* val
|
||||
if (ffStrEqualsIgnCase(value, "none"))
|
||||
return;
|
||||
|
||||
bool isJsonConfig = fileNameLen > strlen(".jsonc") && strcasecmp(value + fileNameLen - strlen(".jsonc"), ".jsonc") == 0;
|
||||
if (ffStrEndsWithIgnCase(value, ".conf"))
|
||||
{
|
||||
fprintf(stderr, "Error: flag based config files are no longer not supported: %s\n", value);
|
||||
exit(414);
|
||||
}
|
||||
|
||||
//Try to load as an absolute path
|
||||
|
||||
if(isJsonConfig ? parseJsoncFile(value) : parseConfigFile(data, value))
|
||||
return;
|
||||
|
||||
{
|
||||
bool success = isJsonConfig ? parseJsoncFile(value) : parseConfigFile(data, value);
|
||||
|
||||
if(success)
|
||||
return;
|
||||
}
|
||||
if (parseJsoncFile(value)) return;
|
||||
|
||||
//Try to load as a relative path
|
||||
|
||||
@@ -531,15 +464,14 @@ static void optionParseConfigFile(FFdata* data, const char* key, const char* val
|
||||
ffStrbufAppendS(&absolutePath, "fastfetch/presets/");
|
||||
ffStrbufAppendS(&absolutePath, value);
|
||||
|
||||
bool success = isJsonConfig ? parseJsoncFile(absolutePath.chars) : parseConfigFile(data, absolutePath.chars);
|
||||
bool success = parseJsoncFile(absolutePath.chars);
|
||||
if (!success)
|
||||
{
|
||||
ffStrbufAppendS(&absolutePath, ".jsonc");
|
||||
success = parseJsoncFile(absolutePath.chars);
|
||||
}
|
||||
|
||||
if(success)
|
||||
return;
|
||||
if (success) return;
|
||||
}
|
||||
|
||||
{
|
||||
@@ -549,15 +481,14 @@ static void optionParseConfigFile(FFdata* data, const char* key, const char* val
|
||||
ffStrbufAppendS(&absolutePath, "/presets/");
|
||||
ffStrbufAppendS(&absolutePath, value);
|
||||
|
||||
bool success = isJsonConfig ? parseJsoncFile(absolutePath.chars) : parseConfigFile(data, absolutePath.chars);
|
||||
bool success = parseJsoncFile(absolutePath.chars);
|
||||
if (!success)
|
||||
{
|
||||
ffStrbufAppendS(&absolutePath, ".jsonc");
|
||||
success = parseJsoncFile(absolutePath.chars);
|
||||
}
|
||||
|
||||
if(success)
|
||||
return;
|
||||
if (success) return;
|
||||
}
|
||||
|
||||
//File not found
|
||||
@@ -695,38 +626,7 @@ static void parseCommand(FFdata* data, char* key, char* value)
|
||||
|
||||
static void parseOption(FFdata* data, const char* key, const char* value)
|
||||
{
|
||||
if(ffStrEqualsIgnCase(key, "--set") || ffStrEqualsIgnCase(key, "--set-keyless"))
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY customValueStr = ffStrbufCreate();
|
||||
ffOptionParseString(key, value, &customValueStr);
|
||||
uint32_t index = ffStrbufFirstIndexC(&customValueStr, '=');
|
||||
if(index == 0 || index == customValueStr.length)
|
||||
{
|
||||
fprintf(stderr, "Error: usage: %s <key>=<str>\n", key);
|
||||
exit(477);
|
||||
}
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY customKey = ffStrbufCreateNS(index, customValueStr.chars);
|
||||
|
||||
FFCustomValue* customValue = NULL;
|
||||
FF_LIST_FOR_EACH(FFCustomValue, x, data->customValues)
|
||||
{
|
||||
if(ffStrbufEqual(&x->key, &customKey))
|
||||
{
|
||||
ffStrbufDestroy(&x->key);
|
||||
ffStrbufDestroy(&x->value);
|
||||
customValue = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!customValue) customValue = (FFCustomValue*) ffListAdd(&data->customValues);
|
||||
ffStrbufInitMove(&customValue->key, &customKey);
|
||||
ffStrbufSubstrAfter(&customValueStr, index);
|
||||
ffStrbufInitMove(&customValue->value, &customValueStr);
|
||||
customValue->printKey = key[5] == '\0';
|
||||
}
|
||||
|
||||
else if(ffStrEqualsIgnCase(key, "-s") || ffStrEqualsIgnCase(key, "--structure"))
|
||||
if(ffStrEqualsIgnCase(key, "-s") || ffStrEqualsIgnCase(key, "--structure"))
|
||||
ffOptionParseString(key, value, &data->structure);
|
||||
|
||||
else if(
|
||||
@@ -744,7 +644,7 @@ static void parseOption(FFdata* data, const char* key, const char* value)
|
||||
}
|
||||
}
|
||||
|
||||
static void parseConfigFiles(FFdata* data)
|
||||
static void parseConfigFiles(void)
|
||||
{
|
||||
if (__builtin_expect(instance.state.genConfigPath.length == 0, true))
|
||||
{
|
||||
@@ -758,15 +658,6 @@ static void parseConfigFiles(FFdata* data)
|
||||
if (success) return;
|
||||
}
|
||||
}
|
||||
FF_LIST_FOR_EACH(FFstrbuf, dir, instance.state.platform.configDirs)
|
||||
{
|
||||
uint32_t dirLength = dir->length;
|
||||
|
||||
ffStrbufAppendS(dir, "fastfetch/config.conf");
|
||||
bool success = parseConfigFile(data, dir->chars);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
if (success) return;
|
||||
}
|
||||
}
|
||||
|
||||
static void parseArguments(FFdata* data, int argc, char** argv, void (*parser)(FFdata* data, char* key, char* value))
|
||||
@@ -863,17 +754,17 @@ static void writeConfigFile(FFdata* data, const FFstrbuf* filename)
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
ffInitInstance();
|
||||
atexit(ffDestroyInstance);
|
||||
|
||||
//Data stores things only needed for the configuration of fastfetch
|
||||
FFdata data = {
|
||||
.structure = ffStrbufCreate(),
|
||||
.customValues = ffListCreate(sizeof(FFCustomValue)),
|
||||
.configLoaded = false,
|
||||
};
|
||||
|
||||
parseArguments(&data, argc, argv, parseCommand);
|
||||
if(!data.configLoaded && !getenv("NO_CONFIG"))
|
||||
parseConfigFiles(&data);
|
||||
parseConfigFiles();
|
||||
parseArguments(&data, argc, argv, (void*) parseOption);
|
||||
|
||||
if (__builtin_expect(instance.state.genConfigPath.length == 0, true))
|
||||
@@ -882,12 +773,4 @@ int main(int argc, char** argv)
|
||||
writeConfigFile(&data, &instance.state.genConfigPath);
|
||||
|
||||
ffStrbufDestroy(&data.structure);
|
||||
FF_LIST_FOR_EACH(FFCustomValue, customValue, data.customValues)
|
||||
{
|
||||
ffStrbufDestroy(&customValue->key);
|
||||
ffStrbufDestroy(&customValue->value);
|
||||
}
|
||||
ffListDestroy(&data.customValues);
|
||||
|
||||
ffDestroyInstance();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
..
|
||||
`:]x**j-,'
|
||||
.,+t***********z\<"
|
||||
?******************;
|
||||
'*n` .'`^,;;,^`'. ,cc.
|
||||
-<. .[l
|
||||
// ^^ ^^ \\
|
||||
!^ $2^^$1 ":
|
||||
'tt}` $2!~]rj_$1 ")t/.
|
||||
Itttt?' $2~~]rr]$1 `{tttt,
|
||||
\tttttt!""I$2_]r($1"""~tttttt1
|
||||
'_tttttttttttt$2)f$1tttttttttttti.
|
||||
\*ztttttttttttttttttttttttttf**[
|
||||
l**c)tttttttttttttttttttttttt(z**,
|
||||
.z*x.`tttttttttttttttttttttttt.`u*n
|
||||
>` (tttttttttttttttttttttt] "I
|
||||
,tttttttttttttttttttttt`
|
||||
./ttttt$2f$1tttttttt$2f$1ttttt(
|
||||
'I)$2))(\()($1tt$2))|\()($1{;'
|
||||
$2.~~~~~~~|)~~~~~~~<$1
|
||||
'$2[)))))1$1|($2)))))))$1?
|
||||
$2",,," ",,,^
|
||||
@@ -0,0 +1,14 @@
|
||||
█ █ █ █ █ █ █ █ █ █ █
|
||||
███████████████████████
|
||||
▄▄██ ██▄▄
|
||||
▄▄██ ███████████ ██▄▄
|
||||
▄▄██ ██ ██ ██▄▄
|
||||
▄▄██ ██ ██ ██▄▄
|
||||
▄▄██ ██ ██ ██▄▄
|
||||
▄▄██ █████████████ ██▄▄
|
||||
▄▄██ ██ ██ ██▄▄
|
||||
▄▄██ ██ ██ ██▄▄
|
||||
▄▄██ ██ ██ ██▄▄
|
||||
▄▄██ ██▄▄
|
||||
███████████████████████
|
||||
█ █ █ █ █ █ █ █ █ █ █
|
||||
@@ -0,0 +1,19 @@
|
||||
.''''....''''.
|
||||
.''... ...''.
|
||||
''.. ..''
|
||||
'.. ..''
|
||||
.'. .,,'.. .',,,' ..'.
|
||||
.'. .,,,,' .,,,,,' .'.
|
||||
.'. .,,,,' .,,,,,. .'.
|
||||
'.. .,,,,'',,,,;. .''
|
||||
.'. .,,,,,,,;;. ..'
|
||||
.'. .,,,,;;;;;${c2}, ${c1}..'.
|
||||
'.. .,;;;,${c2}';;;;;, ${c1}..'
|
||||
.'. .;;${c2};;' .;;:::: ${c1}.,.
|
||||
'.. ${c2}.;;;;' .::::::. ${c1}.,'
|
||||
'.. ${c2}.;;;;' .::::::. ${c1}.,${c2}'${c1}
|
||||
.'.. ${c2}.',.
|
||||
${c1}',.. ${c2}.','
|
||||
${c1}.,,... ${c2}..',,.
|
||||
..,,''........',,,.
|
||||
......
|
||||
@@ -0,0 +1,16 @@
|
||||
${c1} -:+:.
|
||||
${c1} :++++.
|
||||
${c1} /+++/.
|
||||
${c1} .:-::- .+/:-\`\`.::-
|
||||
${c1} .:/++++++/::::/++++++/::`
|
||||
${c2} .:///////////////////////::`
|
||||
${c2} /////////////////////////`
|
||||
${c3}+++++++++++++++++++++++++`
|
||||
${c3}++++++++++++++++++++++++
|
||||
${c4}ssssssssssssssssssssssss.
|
||||
${c4}:ssssssssssssssssssssssss-
|
||||
${c5} osssssssssssssssssssssssss`
|
||||
${c5} `syyyyyyyyyyyyyyyyyyyyyyyyys`
|
||||
${c6} `ossssssssssssssssssssssss
|
||||
${c6} :ooooooooooooooooooo+.
|
||||
${c6} `:++oo+/:- -:/+o+/-
|
||||
@@ -0,0 +1,18 @@
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@@@@@@@@@@@%*+--:------=+*%@@@@@@@@@@@@
|
||||
@@@@@@@@@#=. .-+#%@@@@@%#*+--=#@@@@@@@@@
|
||||
@@@@@@@+. .=%@@@@@@@@@@@@@@@@*-:+@@@@@@@
|
||||
@@@@@*. *@@@@@@@@@@@@@@@@@@@@@%-.*@@@@@
|
||||
@@@@- -@@@@@@@@@@@@@@@@@@@@@@@#: -@@@@
|
||||
@@@: -@@@@@@@=.*@@@@@@@@@@@@%- = :@@@
|
||||
@@= .@@@@@@@@%- :%@@@@@@@@@+ -%@# =@@
|
||||
@% +@@@@@@@@@@#. =@@@@@@*. .*@@@@. %@
|
||||
@+ *@@@@@@*..*@@+ *@@%- =@@@@@@- +@
|
||||
@= *@@@@%- -%@@- := -%@@@@@@@: +@
|
||||
@+ :@@@= +@@= .#@@@@@@@@% *@
|
||||
@% +*. .: *@@#: +@@: @@
|
||||
@@+ :%@- :- :: +@@
|
||||
@@@- .=@@= -@@@
|
||||
@@+. . +@@
|
||||
%=..:.................::...........:..-%
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@@ -0,0 +1,20 @@
|
||||
_,......,_
|
||||
_aaQQQQQQWQQQQQQQaa.
|
||||
ajQQQ??^' '^??QQQw.
|
||||
,aQQP^ ?4QQa
|
||||
wQQP ^4QQa
|
||||
,QQP' ,aaaaa. ^$Q6,
|
||||
,QQP ajQQQWWWWQQQw. 4QQ
|
||||
QQP aQQP? ?$QQ. 4Q6
|
||||
jQQ jQQ' ?WQr 'QQb
|
||||
QQf ]QQ' ]QQ QQ6
|
||||
QQf ]QQ ]QQ) QQQ
|
||||
QQ6 'QQ6 ]QQ QQf
|
||||
]QQ. ^4QQaa .QQP ,QQ'
|
||||
$QQ. ^?QQQQf _yQP ,QQP
|
||||
^WQQ6. aQQ? _QQP
|
||||
^4QQQ6a. ajQQP' aQQP
|
||||
?QQQQQWQaaaaaaajQWQP? aQQP'
|
||||
?QQQQP????????^' saWQP?
|
||||
^?QQQgaaa._ __aaaQQQP?'
|
||||
'^?QWQQQQQQQQ@??^'
|
||||
@@ -0,0 +1,17 @@
|
||||
$2 @=++++++++++=@
|
||||
$2 =++++++++++++++++++=
|
||||
$2 *++++++++++++++++++++++*
|
||||
$2 =++++++++++++++++++++++++++=
|
||||
$2 *++++++++$1-..........-$2++++++++*
|
||||
$2 =++++++++$1..............$2++++++++=
|
||||
$2@++++++++$1:.....$2:++$1:.....:$2++++++++@
|
||||
$2=++++++++$1:.....$2++++$1.....:$2++++++++=
|
||||
$2=++++++++$1:.....$2++++$1.....:$2++++++++=
|
||||
$2#++++++++$1:.....$2++++$1.....:$2++++++++#
|
||||
$2 +++++++++$1......$2--$1......$2+++++++++
|
||||
$2 @++++++++$1:............:$2++++++++@
|
||||
$2 @+++++++++++$1-....-$2+++++++++++@
|
||||
$2 *++++++++++$1::::$2++++++++++*
|
||||
$2 *++++++++++++++++++++*
|
||||
$2 @*++++++++++++++*@
|
||||
$2 @#====#@
|
||||
@@ -18,4 +18,3 @@
|
||||
.:ooooooolc:. .ooooooooooo'
|
||||
.':loooooo; ,oooooooooc
|
||||
..';::c' .;loooo:'
|
||||
.
|
||||
+93
-13
@@ -209,6 +209,7 @@ static const FFlogo A[] = {
|
||||
// AoscOsRetro_small
|
||||
{
|
||||
.names = {"Aosc OS/Retro_small", "aoscosretro_small"},
|
||||
.type = FF_LOGO_LINE_TYPE_SMALL_BIT,
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_AOSCOSRETRO_SMALL,
|
||||
.colors = {
|
||||
FF_COLOR_FG_BLUE,
|
||||
@@ -375,6 +376,24 @@ static const FFlogo A[] = {
|
||||
.colorKeys = FF_COLOR_FG_CYAN,
|
||||
.colorTitle = FF_COLOR_FG_CYAN,
|
||||
},
|
||||
// Armbian
|
||||
{
|
||||
.names = {"Armbian"},
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_ARMBIAN,
|
||||
.colors = {
|
||||
FF_COLOR_FG_WHITE,
|
||||
FF_COLOR_FG_RED,
|
||||
},
|
||||
},
|
||||
// Armbian2
|
||||
{
|
||||
.names = {"Armbian2"},
|
||||
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_ARMBIAN2,
|
||||
.colors = {
|
||||
FF_COLOR_FG_RED,
|
||||
},
|
||||
},
|
||||
// Artix
|
||||
{
|
||||
.names = {"artix", "artixlinux", "artix-linux"},
|
||||
@@ -764,6 +783,7 @@ static const FFlogo C[] = {
|
||||
// CalinixOSSmall
|
||||
{
|
||||
.names = {"Calinix_small", "calinixos_small"},
|
||||
.type = FF_LOGO_LINE_TYPE_SMALL_BIT,
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_CALINIXOS_SMALL,
|
||||
.colors = {
|
||||
FF_COLOR_FG_MAGENTA,
|
||||
@@ -875,7 +895,7 @@ static const FFlogo C[] = {
|
||||
// Chimera Linux
|
||||
{
|
||||
.names = {"Chimera Linux"},
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_CHIMERALINUX,
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_CHIMERA_LINUX,
|
||||
.colors = {
|
||||
FF_COLOR_FG_RED,
|
||||
FF_COLOR_FG_MAGENTA,
|
||||
@@ -1095,9 +1115,9 @@ static const FFlogo C[] = {
|
||||
};
|
||||
|
||||
static const FFlogo D[] = {
|
||||
// Dahlia
|
||||
// DahliaOS
|
||||
{
|
||||
.names = {"dahlia"},
|
||||
.names = {"dahliaOS"},
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_DAHLIA,
|
||||
.colors = {
|
||||
FF_COLOR_FG_RED,
|
||||
@@ -1241,9 +1261,9 @@ static const FFlogo D[] = {
|
||||
.colorKeys = FF_COLOR_FG_RED,
|
||||
.colorTitle = FF_COLOR_FG_WHITE,
|
||||
},
|
||||
// Drauger
|
||||
// DraugerOS
|
||||
{
|
||||
.names = {"Drauger"},
|
||||
.names = {"DraugerOS", "Drauger"},
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_DRAUGER,
|
||||
.colors = {
|
||||
FF_COLOR_FG_RED,
|
||||
@@ -1336,8 +1356,8 @@ static const FFlogo E[] = {
|
||||
// EndeavourSmall
|
||||
{
|
||||
.names = {"Endeavour_small", "endeavour-linux_small", "endeavouros_small", "endeavouros-linux_small"},
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_ENDEAVOUR_SMALL,
|
||||
.type = FF_LOGO_LINE_TYPE_SMALL_BIT,
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_ENDEAVOUR_SMALL,
|
||||
.colors = {
|
||||
FF_COLOR_FG_RED,
|
||||
FF_COLOR_FG_MAGENTA,
|
||||
@@ -1823,6 +1843,7 @@ static const FFlogo G[] = {
|
||||
// GuixSmall
|
||||
{
|
||||
.names = {"Guix_small"},
|
||||
.type = FF_LOGO_LINE_TYPE_SMALL_BIT,
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_GUIX_SMALL,
|
||||
.colors = {
|
||||
FF_COLOR_FG_YELLOW,
|
||||
@@ -2089,6 +2110,15 @@ static const FFlogo K[] = {
|
||||
.colorKeys = FF_COLOR_FG_BLUE,
|
||||
.colorTitle = FF_COLOR_FG_WHITE,
|
||||
},
|
||||
// KernelOS
|
||||
{
|
||||
.names = {"KernelOS"},
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_KERNELOS,
|
||||
.colors = {
|
||||
FF_COLOR_FG_RED,
|
||||
FF_COLOR_FG_MAGENTA,
|
||||
}
|
||||
},
|
||||
// KDENeon
|
||||
{
|
||||
.names = {"KDE", "kde-neon"},
|
||||
@@ -2431,6 +2461,21 @@ static const FFlogo M[] = {
|
||||
.colorKeys = FF_COLOR_FG_YELLOW,
|
||||
.colorTitle = FF_COLOR_FG_GREEN,
|
||||
},
|
||||
// MacOS3
|
||||
{
|
||||
.names = {"macos3", "mac3"},
|
||||
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_MACOS3,
|
||||
.colors = {
|
||||
FF_COLOR_FG_GREEN,
|
||||
FF_COLOR_FG_YELLOW,
|
||||
FF_COLOR_FG_RED,
|
||||
FF_COLOR_FG_MAGENTA,
|
||||
FF_COLOR_FG_BLUE,
|
||||
},
|
||||
.colorKeys = FF_COLOR_FG_YELLOW,
|
||||
.colorTitle = FF_COLOR_FG_GREEN,
|
||||
},
|
||||
// MainsailOS
|
||||
{
|
||||
.names = {"MainsailOS"},
|
||||
@@ -2462,6 +2507,7 @@ static const FFlogo M[] = {
|
||||
// MageiaSmall
|
||||
{
|
||||
.names = {"Mageia_small"},
|
||||
.type = FF_LOGO_LINE_TYPE_SMALL_BIT,
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_MAGEIA_SMALL,
|
||||
.colors = {
|
||||
FF_COLOR_FG_CYAN,
|
||||
@@ -2649,7 +2695,7 @@ static const FFlogo M[] = {
|
||||
},
|
||||
// MX
|
||||
{
|
||||
.names = {"MX"},
|
||||
.names = {"MX", "MX Linux"},
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_MX,
|
||||
.colors = {
|
||||
FF_COLOR_FG_WHITE,
|
||||
@@ -2659,7 +2705,8 @@ static const FFlogo M[] = {
|
||||
},
|
||||
// MXSmall
|
||||
{
|
||||
.names = {"MX_small", "mx-small"},
|
||||
.names = {"MX_small", "mx linux_small"},
|
||||
.type = FF_LOGO_LINE_TYPE_SMALL_BIT,
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_MX_SMALL,
|
||||
.colors = {
|
||||
FF_COLOR_FG_WHITE,
|
||||
@@ -2667,6 +2714,17 @@ static const FFlogo M[] = {
|
||||
.colorKeys = FF_COLOR_FG_BLUE,
|
||||
.colorTitle = FF_COLOR_FG_CYAN,
|
||||
},
|
||||
// MX2
|
||||
{
|
||||
.names = {"MX2"},
|
||||
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_MX2,
|
||||
.colors = {
|
||||
FF_COLOR_FG_WHITE,
|
||||
},
|
||||
.colorKeys = FF_COLOR_FG_BLUE,
|
||||
.colorTitle = FF_COLOR_FG_CYAN,
|
||||
},
|
||||
// LAST
|
||||
{},
|
||||
};
|
||||
@@ -2730,6 +2788,7 @@ static const FFlogo N[] = {
|
||||
// NixOSSmall
|
||||
{
|
||||
.names = {"NixOS_small", "nix_small", "nixos-linux-small", "nix-linux-small"},
|
||||
.type = FF_LOGO_LINE_TYPE_SMALL_BIT,
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_NIXOS_SMALL,
|
||||
.colors = {
|
||||
FF_COLOR_FG_BLUE,
|
||||
@@ -2960,9 +3019,19 @@ static const FFlogo O[] = {
|
||||
.colorKeys = FF_COLOR_FG_GREEN,
|
||||
.colorTitle = FF_COLOR_FG_GREEN,
|
||||
},
|
||||
// openSUSESlowroll
|
||||
{
|
||||
.names = {"opensuse_slowroll", "opensuse-slowroll", "opensuse-tumbleweed-slowroll"},
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_OPENSUSE_SLOWROLL,
|
||||
.colors = {
|
||||
FF_COLOR_FG_WHITE,
|
||||
},
|
||||
.colorKeys = FF_COLOR_FG_GREEN,
|
||||
.colorTitle = FF_COLOR_FG_GREEN,
|
||||
},
|
||||
// OpenMandriva
|
||||
{
|
||||
.names = {"openmandriva", "open-mandriva", "open_mandriva"},
|
||||
.names = {"openmandriva", "open-mandriva", "open_mandriva", "openmandriva lx"},
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_OPENMANDRIVA,
|
||||
.colors = {
|
||||
FF_COLOR_FG_BLUE,
|
||||
@@ -3301,6 +3370,7 @@ static const FFlogo P[] = {
|
||||
// PostMarketOSSmall
|
||||
{
|
||||
.names = {"PostMarketOS_small"},
|
||||
.type = FF_LOGO_LINE_TYPE_SMALL_BIT,
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_POSTMARKETOS_SMALL,
|
||||
.colors = {
|
||||
FF_COLOR_FG_GREEN,
|
||||
@@ -3309,7 +3379,7 @@ static const FFlogo P[] = {
|
||||
},
|
||||
// Proxmox
|
||||
{
|
||||
.names = {"proxmox"},
|
||||
.names = {"Proxmox", "pve"},
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_PROXMOX,
|
||||
.colors = {
|
||||
FF_COLOR_FG_WHITE,
|
||||
@@ -3397,6 +3467,15 @@ static const FFlogo Q[] = {
|
||||
FF_COLOR_FG_WHITE,
|
||||
},
|
||||
},
|
||||
// Quirinux
|
||||
{
|
||||
.names = {"Quirinux"},
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_QUIRINUX,
|
||||
.colors = {
|
||||
FF_COLOR_FG_WHITE,
|
||||
FF_COLOR_FG_MAGENTA,
|
||||
},
|
||||
},
|
||||
// LAST
|
||||
{},
|
||||
};
|
||||
@@ -3560,6 +3639,7 @@ static const FFlogo R[] = {
|
||||
// RockyLinuxSmall
|
||||
{
|
||||
.names = {"rocky_small", "rocky-linux_small", "rockylinux_small"},
|
||||
.type = FF_LOGO_LINE_TYPE_SMALL_BIT,
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_ROCKY_SMALL,
|
||||
.colors = {
|
||||
FF_COLOR_FG_GREEN,
|
||||
@@ -3791,14 +3871,14 @@ static const FFlogo S[] = {
|
||||
FF_COLOR_FG_WHITE,
|
||||
},
|
||||
},
|
||||
// SourceMage
|
||||
// Source Mage
|
||||
{
|
||||
.names = {"Source Mage", "source_mage"},
|
||||
.names = {"Source Mage", "Source Mage GNU/Linux", "source_mage", "sourcemage"},
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_SOURCE_MAGE,
|
||||
.colors = {
|
||||
FF_COLOR_FG_WHITE,
|
||||
},
|
||||
.colorKeys = FF_COLOR_FG_BLUE,
|
||||
.colorKeys = FF_COLOR_FG_RED,
|
||||
.colorTitle = FF_COLOR_FG_WHITE,
|
||||
},
|
||||
// Solaris
|
||||
|
||||
+41
-11
@@ -1,6 +1,7 @@
|
||||
#include "image.h"
|
||||
#include "common/io/io.h"
|
||||
#include "common/printing.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
@@ -53,13 +54,14 @@ static FFstrbuf base64Encode(const FFstrbuf* in)
|
||||
return out;
|
||||
}
|
||||
|
||||
static bool printImageIterm(void)
|
||||
static bool printImageIterm(bool printError)
|
||||
{
|
||||
const FFOptionsLogo* options = &instance.config.logo;
|
||||
FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
|
||||
if(!ffAppendFileBuffer(options->source.chars, &buf))
|
||||
{
|
||||
fputs("Logo: Failed to load image file\n", stderr);
|
||||
if (printError)
|
||||
fputs("Logo (iterm): Failed to load image file\n", stderr);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -82,9 +84,10 @@ static bool printImageIterm(void)
|
||||
ffStrbufAppendNC(&buf, options->paddingTop, '\n');
|
||||
ffStrbufAppendNC(&buf, options->paddingLeft, ' ');
|
||||
}
|
||||
ffStrbufAppendF(&buf, "\e]1337;File=inline=1:%s\a",
|
||||
base64.chars
|
||||
);
|
||||
if (options->width)
|
||||
ffStrbufAppendF(&buf, "\e]1337;File=inline=1;width=%u:%s\a", (unsigned) options->width, base64.chars);
|
||||
else
|
||||
ffStrbufAppendF(&buf, "\e]1337;File=inline=1:%s\a", base64.chars);
|
||||
ffWriteFDBuffer(FFUnixFD2NativeFD(STDOUT_FILENO), &buf);
|
||||
|
||||
if (!options->separate)
|
||||
@@ -134,9 +137,17 @@ static bool printImageIterm(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool printImageKittyDirect(void)
|
||||
static bool printImageKittyDirect(bool printError)
|
||||
{
|
||||
const FFOptionsLogo* options = &instance.config.logo;
|
||||
|
||||
if (!ffPathExists(options->source.chars, FF_PATHTYPE_FILE))
|
||||
{
|
||||
if (printError)
|
||||
fputs("Logo (kitty-direct): Failed to load image file\n", stderr);
|
||||
return false;
|
||||
}
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY base64 = base64Encode(&options->source);
|
||||
|
||||
if (!options->width || !options->height)
|
||||
@@ -154,7 +165,11 @@ static bool printImageKittyDirect(void)
|
||||
ffPrintCharTimes('\n', options->paddingTop);
|
||||
ffPrintCharTimes(' ', options->paddingLeft);
|
||||
}
|
||||
printf("\e_Ga=T,f=100,t=f;%s\e\\", base64.chars);
|
||||
|
||||
if (options->width)
|
||||
printf("\e_Ga=T,f=100,t=f,c=%u;%s\e\\", (unsigned) options->width, base64.chars);
|
||||
else
|
||||
printf("\e_Ga=T,f=100,t=f;%s\e\\", base64.chars);
|
||||
fflush(stdout);
|
||||
if (!options->separate)
|
||||
{
|
||||
@@ -771,7 +786,7 @@ static bool printImageIfExistsSlowPath(FFLogoType type, bool printError)
|
||||
if(!getCharacterPixelDimensions(&requestData))
|
||||
{
|
||||
if(printError)
|
||||
fputs("Logo: getCharacterPixelDimensions() failed", stderr);
|
||||
fputs("Logo: getCharacterPixelDimensions() failed\n", stderr);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -788,7 +803,7 @@ static bool printImageIfExistsSlowPath(FFLogoType type, bool printError)
|
||||
//We can safely return here, because if realpath failed, we surely won't be able to read the file
|
||||
ffStrbufDestroy(&requestData.cacheDir);
|
||||
if(printError)
|
||||
fputs("Logo: Querying realpath of the image source failed", stderr);
|
||||
fputs("Logo: Querying realpath of the image source failed\n", stderr);
|
||||
return false;
|
||||
}
|
||||
ffStrbufRecalculateLength(&requestData.cacheDir);
|
||||
@@ -832,6 +847,13 @@ static bool printImageIfExistsSlowPath(FFLogoType type, bool printError)
|
||||
|
||||
bool ffLogoPrintImageIfExists(FFLogoType type, bool printError)
|
||||
{
|
||||
if(instance.config.display.pipe)
|
||||
{
|
||||
if(printError)
|
||||
fputs("Logo: Image logo is not supported in pipe mode\n", stderr);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!ffPathExists(instance.config.logo.source.chars, FF_PATHTYPE_FILE))
|
||||
{
|
||||
if(printError)
|
||||
@@ -839,11 +861,19 @@ bool ffLogoPrintImageIfExists(FFLogoType type, bool printError)
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* term = getenv("TERM");
|
||||
if((term && ffStrEquals(term, "screen")) || getenv("ZELLIJ"))
|
||||
{
|
||||
if(printError)
|
||||
fputs("Logo: Image logo is not supported in terminal multiplexers\n", stderr);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(type == FF_LOGO_TYPE_IMAGE_ITERM)
|
||||
return printImageIterm();
|
||||
return printImageIterm(printError);
|
||||
|
||||
if(type == FF_LOGO_TYPE_IMAGE_KITTY_DIRECT)
|
||||
return printImageKittyDirect();
|
||||
return printImageKittyDirect(printError);
|
||||
|
||||
#if !defined(FF_HAVE_CHAFA)
|
||||
if(type == FF_LOGO_TYPE_IMAGE_CHAFA)
|
||||
|
||||
+38
-24
@@ -61,7 +61,7 @@ void ffLogoPrintChars(const char* data, bool doColorReplacement)
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY result = ffStrbufCreateA(2048);
|
||||
|
||||
if (instance.config.display.brightColor)
|
||||
if (!instance.config.display.pipe && instance.config.display.brightColor)
|
||||
ffStrbufAppendS(&result, FASTFETCH_TEXT_MODIFIER_BOLT);
|
||||
|
||||
ffStrbufAppendNC(&result, options->paddingTop, '\n');
|
||||
@@ -70,7 +70,7 @@ void ffLogoPrintChars(const char* data, bool doColorReplacement)
|
||||
instance.state.logoHeight = options->paddingTop;
|
||||
|
||||
//Use logoColor[0] as the default color
|
||||
if(doColorReplacement)
|
||||
if(doColorReplacement && !instance.config.display.pipe)
|
||||
ffStrbufAppendF(&result, "\e[%sm", options->colors[0].chars);
|
||||
|
||||
while(*data != '\0')
|
||||
@@ -143,19 +143,27 @@ void ffLogoPrintChars(const char* data, bool doColorReplacement)
|
||||
continue;
|
||||
}
|
||||
|
||||
//Map the number to an array index, so that '1' -> 0, '2' -> 1, etc.
|
||||
int index = ((int) *data) - 49;
|
||||
|
||||
//If the index is valid, print the color. Otherwise continue as normal
|
||||
if(index < 0 || index >= FASTFETCH_LOGO_MAX_COLORS)
|
||||
if(!instance.config.display.pipe)
|
||||
{
|
||||
ffStrbufAppendC(&result, '$');
|
||||
++currentlineLength;
|
||||
//Don't continue here, we want to print the current char as unicode
|
||||
//Map the number to an array index, so that '1' -> 0, '2' -> 1, etc.
|
||||
int index = ((int) *data) - 49;
|
||||
|
||||
//If the index is valid, print the color. Otherwise continue as normal
|
||||
if(index < 0 || index >= FASTFETCH_LOGO_MAX_COLORS)
|
||||
{
|
||||
ffStrbufAppendC(&result, '$');
|
||||
++currentlineLength;
|
||||
//Don't continue here, we want to print the current char as unicode
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufAppendF(&result, "\e[%sm", options->colors[index].chars);
|
||||
++data;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufAppendF(&result, "\e[%sm", options->colors[index].chars);
|
||||
++data;
|
||||
continue;
|
||||
}
|
||||
@@ -188,7 +196,8 @@ void ffLogoPrintChars(const char* data, bool doColorReplacement)
|
||||
}
|
||||
}
|
||||
|
||||
ffStrbufAppendS(&result, FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
if(!instance.config.display.pipe)
|
||||
ffStrbufAppendS(&result, FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
|
||||
if(!options->separate)
|
||||
{
|
||||
@@ -393,7 +402,8 @@ static bool logoPrintFileIfExists(bool doColorReplacement, bool raw)
|
||||
: !ffAppendFileBuffer(options->source.chars, &content)
|
||||
)
|
||||
{
|
||||
fprintf(stderr, "Logo: Failed to load file content from logo source: %s \n", options->source.chars);
|
||||
if (instance.config.display.showErrors)
|
||||
fprintf(stderr, "Logo: Failed to load file content from logo source: %s \n", options->source.chars);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -426,7 +436,7 @@ static bool logoTryKnownType(void)
|
||||
}
|
||||
|
||||
if(options->type == FF_LOGO_TYPE_BUILTIN)
|
||||
return logoPrintBuiltinIfExists(&options->source, FF_LOGO_SIZE_NORMAL);
|
||||
return logoPrintBuiltinIfExists(&options->source, FF_LOGO_SIZE_UNKNOWN);
|
||||
|
||||
if(options->type == FF_LOGO_TYPE_SMALL)
|
||||
return logoPrintBuiltinIfExists(&options->source, FF_LOGO_SIZE_SMALL);
|
||||
@@ -448,21 +458,15 @@ static bool logoTryKnownType(void)
|
||||
if(options->type == FF_LOGO_TYPE_IMAGE_RAW)
|
||||
return logoPrintFileIfExists(false, true);
|
||||
|
||||
return logoPrintImageIfExists(options->type, true);
|
||||
}
|
||||
|
||||
static void logoPrintKnownType(void)
|
||||
{
|
||||
if(!logoTryKnownType())
|
||||
logoPrintDetected(FF_LOGO_SIZE_UNKNOWN);
|
||||
return logoPrintImageIfExists(options->type, instance.config.display.showErrors);
|
||||
}
|
||||
|
||||
void ffLogoPrint(void)
|
||||
{
|
||||
//In pipe mode, we don't have a logo or padding.
|
||||
//When generate JSON result, we don't have a logo or padding.
|
||||
//We also don't need to set main color, because it won't be printed anyway.
|
||||
//So we can return quickly here.
|
||||
if(instance.config.display.pipe || instance.state.resultDoc)
|
||||
if(instance.state.resultDoc)
|
||||
{
|
||||
instance.state.logoHeight = 0;
|
||||
instance.state.logoWidth = 0;
|
||||
@@ -487,7 +491,17 @@ void ffLogoPrint(void)
|
||||
//If the source and source type is set to something else than auto, always print with the set type.
|
||||
if(options->source.length > 0 && options->type != FF_LOGO_TYPE_AUTO)
|
||||
{
|
||||
logoPrintKnownType();
|
||||
if(!logoTryKnownType())
|
||||
{
|
||||
if (instance.config.display.showErrors)
|
||||
{
|
||||
// Image logo should have been handled
|
||||
if(options->type == FF_LOGO_TYPE_BUILTIN || options->type == FF_LOGO_TYPE_SMALL)
|
||||
fprintf(stderr, "Logo: Failed to load %s logo: %s \n", options->type == FF_LOGO_TYPE_BUILTIN ? "builtin" : "builtin small", options->source.chars);
|
||||
}
|
||||
|
||||
logoPrintDetected(FF_LOGO_SIZE_UNKNOWN);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ static void printBattery(FFBatteryOptions* options, FFBatteryResult* result, uin
|
||||
{
|
||||
if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_BAR_BIT)
|
||||
{
|
||||
ffPercentAppendBar(&str, result->capacity, options->percent);
|
||||
ffPercentAppendBar(&str, result->capacity, options->percent, &options->moduleArgs);
|
||||
}
|
||||
|
||||
if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_NUM_BIT)
|
||||
@@ -33,7 +33,7 @@ static void printBattery(FFBatteryOptions* options, FFBatteryResult* result, uin
|
||||
if(str.length > 0)
|
||||
ffStrbufAppendC(&str, ' ');
|
||||
|
||||
ffPercentAppendNum(&str, result->capacity, options->percent, str.length > 0);
|
||||
ffPercentAppendNum(&str, result->capacity, options->percent, str.length > 0, &options->moduleArgs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ static void printBattery(FFBatteryOptions* options, FFBatteryResult* result, uin
|
||||
if(str.length > 0)
|
||||
ffStrbufAppendS(&str, " - ");
|
||||
|
||||
ffTempsAppendNum(result->temperature, &str, options->tempConfig);
|
||||
ffTempsAppendNum(result->temperature, &str, options->tempConfig, &options->moduleArgs);
|
||||
}
|
||||
|
||||
ffStrbufPutTo(&str, stdout);
|
||||
@@ -58,9 +58,9 @@ static void printBattery(FFBatteryOptions* options, FFBatteryResult* result, uin
|
||||
else
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY capacityStr = ffStrbufCreate();
|
||||
ffPercentAppendNum(&capacityStr, result->capacity, options->percent, false);
|
||||
ffPercentAppendNum(&capacityStr, result->capacity, options->percent, false, &options->moduleArgs);
|
||||
FF_STRBUF_AUTO_DESTROY tempStr = ffStrbufCreate();
|
||||
ffTempsAppendNum(result->temperature, &tempStr, options->tempConfig);
|
||||
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_FORMAT_ARG_TYPE_STRBUF, &result->manufacturer},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->modelName},
|
||||
@@ -84,23 +84,28 @@ void ffPrintBattery(FFBatteryOptions* options)
|
||||
if (error)
|
||||
{
|
||||
ffPrintError(FF_BATTERY_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", error);
|
||||
return;
|
||||
}
|
||||
else
|
||||
if(results.length == 0)
|
||||
{
|
||||
for(uint8_t i = 0; i < (uint8_t) results.length; i++)
|
||||
{
|
||||
FFBatteryResult* result = ffListGet(&results, i);
|
||||
printBattery(options, result, i);
|
||||
ffPrintError(FF_BATTERY_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", "No batteries found");
|
||||
return;
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&result->manufacturer);
|
||||
ffStrbufDestroy(&result->modelName);
|
||||
ffStrbufDestroy(&result->technology);
|
||||
ffStrbufDestroy(&result->status);
|
||||
ffStrbufDestroy(&result->serial);
|
||||
ffStrbufDestroy(&result->manufactureDate);
|
||||
}
|
||||
if(results.length == 0)
|
||||
ffPrintError(FF_BATTERY_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "No batteries found");
|
||||
for(uint32_t i = 0; i < results.length; i++)
|
||||
{
|
||||
FFBatteryResult* result = ffListGet(&results, i);
|
||||
printBattery(options, result, (uint8_t) i);
|
||||
}
|
||||
|
||||
FF_LIST_FOR_EACH(FFBatteryResult, result, results)
|
||||
{
|
||||
ffStrbufDestroy(&result->manufacturer);
|
||||
ffStrbufDestroy(&result->modelName);
|
||||
ffStrbufDestroy(&result->technology);
|
||||
ffStrbufDestroy(&result->status);
|
||||
ffStrbufDestroy(&result->serial);
|
||||
ffStrbufDestroy(&result->manufactureDate);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ static void printDevice(FFBluetoothOptions* options, const FFBluetoothResult* de
|
||||
{
|
||||
if (buffer.length)
|
||||
ffStrbufAppendC(&buffer, ' ');
|
||||
ffPercentAppendNum(&buffer, device->battery, options->percent, buffer.length > 0);
|
||||
ffPercentAppendNum(&buffer, device->battery, options->percent, buffer.length > 0, &options->moduleArgs);
|
||||
}
|
||||
|
||||
if (!device->connected)
|
||||
@@ -30,7 +30,7 @@ static void printDevice(FFBluetoothOptions* options, const FFBluetoothResult* de
|
||||
else
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY percentageStr = ffStrbufCreate();
|
||||
ffPercentAppendNum(&percentageStr, device->battery, options->percent, false);
|
||||
ffPercentAppendNum(&percentageStr, device->battery, options->percent, false, &options->moduleArgs);
|
||||
|
||||
FF_PRINT_FORMAT_CHECKED(FF_BLUETOOTH_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_BLUETOOTH_NUM_FORMAT_ARGS, ((FFformatarg[]) {
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &device->name},
|
||||
@@ -150,19 +150,17 @@ void ffGenerateBluetoothJsonResult(FF_MAYBE_UNUSED FFBluetoothOptions* options,
|
||||
yyjson_mut_obj_add_str(doc, module, "error", error);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
yyjson_mut_val* arr = yyjson_mut_obj_add_arr(doc, module, "result");
|
||||
|
||||
FF_LIST_FOR_EACH(FFBluetoothResult, item, results)
|
||||
{
|
||||
yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "address", &item->address);
|
||||
yyjson_mut_obj_add_uint(doc, obj, "battery", item->battery);
|
||||
yyjson_mut_obj_add_bool(doc, obj, "connected", item->connected);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "name", &item->name);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "type", &item->type);
|
||||
}
|
||||
yyjson_mut_val* arr = yyjson_mut_obj_add_arr(doc, module, "result");
|
||||
|
||||
FF_LIST_FOR_EACH(FFBluetoothResult, item, results)
|
||||
{
|
||||
yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "address", &item->address);
|
||||
yyjson_mut_obj_add_uint(doc, obj, "battery", item->battery);
|
||||
yyjson_mut_obj_add_bool(doc, obj, "connected", item->connected);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "name", &item->name);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "type", &item->type);
|
||||
}
|
||||
|
||||
FF_LIST_FOR_EACH(FFBluetoothResult, device, results)
|
||||
|
||||
@@ -52,7 +52,7 @@ void ffPrintBrightness(FFBrightnessOptions* options)
|
||||
|
||||
if (instance.config.display.percentType & FF_PERCENTAGE_TYPE_BAR_BIT)
|
||||
{
|
||||
ffPercentAppendBar(&str, percent, options->percent);
|
||||
ffPercentAppendBar(&str, percent, options->percent, &options->moduleArgs);
|
||||
}
|
||||
|
||||
if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_NUM_BIT)
|
||||
@@ -60,7 +60,7 @@ void ffPrintBrightness(FFBrightnessOptions* options)
|
||||
if(str.length > 0)
|
||||
ffStrbufAppendC(&str, ' ');
|
||||
|
||||
ffPercentAppendNum(&str, percent, options->percent, str.length > 0);
|
||||
ffPercentAppendNum(&str, percent, options->percent, str.length > 0, &options->moduleArgs);
|
||||
}
|
||||
|
||||
ffStrbufPutTo(&str, stdout);
|
||||
@@ -68,7 +68,7 @@ void ffPrintBrightness(FFBrightnessOptions* options)
|
||||
else
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY valueStr = ffStrbufCreate();
|
||||
ffPercentAppendNum(&valueStr, percent, options->percent, false);
|
||||
ffPercentAppendNum(&valueStr, percent, options->percent, false, &options->moduleArgs);
|
||||
FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_BRIGHTNESS_NUM_FORMAT_ARGS, ((FFformatarg[]) {
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &valueStr},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &item->name},
|
||||
@@ -154,12 +154,6 @@ void ffGenerateBrightnessJsonResult(FF_MAYBE_UNUSED FFBrightnessOptions* options
|
||||
return;
|
||||
}
|
||||
|
||||
if(result.length == 0)
|
||||
{
|
||||
yyjson_mut_obj_add_str(doc, module, "error", "No result is detected.");
|
||||
return;
|
||||
}
|
||||
|
||||
yyjson_mut_val* arr = yyjson_mut_arr(doc);
|
||||
yyjson_mut_obj_add_val(doc, module, "result", arr);
|
||||
|
||||
|
||||
@@ -16,9 +16,6 @@ static inline uint8_t max(uint8_t a, uint8_t b)
|
||||
|
||||
void ffPrintColors(FFColorsOptions* options)
|
||||
{
|
||||
if(instance.config.display.pipe)
|
||||
return;
|
||||
|
||||
bool flag = false;
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY result = ffStrbufCreateA(128);
|
||||
@@ -28,7 +25,8 @@ void ffPrintColors(FFColorsOptions* options)
|
||||
// 3%d: Set the foreground color
|
||||
for(uint8_t i = options->block.range[0]; i <= min(options->block.range[1], 7); i++)
|
||||
{
|
||||
ffStrbufAppendF(&result, "\e[3%dm", i);
|
||||
if(!instance.config.display.pipe)
|
||||
ffStrbufAppendF(&result, "\e[3%dm", i);
|
||||
for (uint8_t j = 0; j < options->block.width; j++)
|
||||
ffStrbufAppendS(&result, "█");
|
||||
}
|
||||
@@ -40,7 +38,8 @@ void ffPrintColors(FFColorsOptions* options)
|
||||
if(options->paddingLeft > 0)
|
||||
ffPrintCharTimes(' ', options->paddingLeft);
|
||||
|
||||
ffStrbufAppendS(&result, FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
if(!instance.config.display.pipe)
|
||||
ffStrbufAppendS(&result, FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
ffStrbufPutTo(&result, stdout);
|
||||
ffStrbufClear(&result);
|
||||
}
|
||||
@@ -49,7 +48,8 @@ void ffPrintColors(FFColorsOptions* options)
|
||||
// 9%d: Set the foreground to the bright color
|
||||
for(uint8_t i = max(options->block.range[0], 8); i <= options->block.range[1]; i++)
|
||||
{
|
||||
ffStrbufAppendF(&result, "\e[1;9%dm", i - 8);
|
||||
if(!instance.config.display.pipe)
|
||||
ffStrbufAppendF(&result, "\e[1;9%dm", i - 8);
|
||||
for (uint8_t j = 0; j < options->block.width; j++)
|
||||
ffStrbufAppendS(&result, "█");
|
||||
}
|
||||
@@ -82,7 +82,8 @@ void ffPrintColors(FFColorsOptions* options)
|
||||
|
||||
if(options->paddingLeft > 0)
|
||||
ffPrintCharTimes(' ', options->paddingLeft);
|
||||
ffStrbufAppendS(&result, FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
if(!instance.config.display.pipe)
|
||||
ffStrbufAppendS(&result, FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
ffStrbufPutTo(&result, stdout);
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ void ffPrintCPU(FFCPUOptions* options)
|
||||
if(cpu.temperature == cpu.temperature) //FF_CPU_TEMP_UNSET
|
||||
{
|
||||
ffStrbufAppendS(&str, " - ");
|
||||
ffTempsAppendNum(cpu.temperature, &str, options->tempConfig);
|
||||
ffTempsAppendNum(cpu.temperature, &str, options->tempConfig, &options->moduleArgs);
|
||||
}
|
||||
|
||||
ffStrbufPutTo(&str, stdout);
|
||||
@@ -65,7 +65,7 @@ void ffPrintCPU(FFCPUOptions* options)
|
||||
else
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY tempStr = ffStrbufCreate();
|
||||
ffTempsAppendNum(cpu.temperature, &tempStr, options->tempConfig);
|
||||
ffTempsAppendNum(cpu.temperature, &tempStr, options->tempConfig, &options->moduleArgs);
|
||||
FF_PRINT_FORMAT_CHECKED(FF_CPU_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_CPU_NUM_FORMAT_ARGS, ((FFformatarg[]){
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &cpu.name},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &cpu.vendor},
|
||||
|
||||
@@ -52,12 +52,12 @@ void ffPrintCPUUsage(FFCPUUsageOptions* options)
|
||||
if (!options->separate)
|
||||
{
|
||||
if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_BAR_BIT)
|
||||
ffPercentAppendBar(&str, avgValue, options->percent);
|
||||
ffPercentAppendBar(&str, avgValue, options->percent, &options->moduleArgs);
|
||||
if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_NUM_BIT)
|
||||
{
|
||||
if(str.length > 0)
|
||||
ffStrbufAppendC(&str, ' ');
|
||||
ffPercentAppendNum(&str, avgValue, options->percent, str.length > 0);
|
||||
ffPercentAppendNum(&str, avgValue, options->percent, str.length > 0, &options->moduleArgs);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -66,7 +66,7 @@ void ffPrintCPUUsage(FFCPUUsageOptions* options)
|
||||
{
|
||||
if(str.length > 0)
|
||||
ffStrbufAppendC(&str, ' ');
|
||||
ffPercentAppendNum(&str, *percent, options->percent, false);
|
||||
ffPercentAppendNum(&str, *percent, options->percent, false, &options->moduleArgs);
|
||||
}
|
||||
}
|
||||
ffStrbufPutTo(&str, stdout);
|
||||
@@ -74,11 +74,11 @@ void ffPrintCPUUsage(FFCPUUsageOptions* options)
|
||||
else
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY avgStr = ffStrbufCreate();
|
||||
ffPercentAppendNum(&avgStr, avgValue, options->percent, false);
|
||||
ffPercentAppendNum(&avgStr, avgValue, options->percent, false, &options->moduleArgs);
|
||||
FF_STRBUF_AUTO_DESTROY minStr = ffStrbufCreate();
|
||||
ffPercentAppendNum(&minStr, minValue, options->percent, false);
|
||||
ffPercentAppendNum(&minStr, minValue, options->percent, false, &options->moduleArgs);
|
||||
FF_STRBUF_AUTO_DESTROY maxStr = ffStrbufCreate();
|
||||
ffPercentAppendNum(&maxStr, maxValue, options->percent, false);
|
||||
ffPercentAppendNum(&maxStr, maxValue, options->percent, false, &options->moduleArgs);
|
||||
FF_PRINT_FORMAT_CHECKED(FF_CPUUSAGE_DISPLAY_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_CPUUSAGE_NUM_FORMAT_ARGS, ((FFformatarg[]){
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &avgStr},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &maxStr},
|
||||
|
||||
@@ -6,15 +6,10 @@
|
||||
|
||||
void ffPrintCustom(FFCustomOptions* options)
|
||||
{
|
||||
if (options->moduleArgs.outputFormat.length == 0)
|
||||
{
|
||||
ffPrintError(FF_CUSTOM_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "output format must be set for custom module");
|
||||
return;
|
||||
}
|
||||
|
||||
ffPrintLogoAndKey(FF_CUSTOM_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
|
||||
ffStrbufWriteTo(&options->moduleArgs.outputFormat, stdout);
|
||||
puts(FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
if(!instance.config.display.pipe)
|
||||
puts(FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
}
|
||||
|
||||
bool ffParseCustomCommandOptions(FFCustomOptions* options, const char* key, const char* value)
|
||||
|
||||
@@ -152,7 +152,7 @@ void ffGenerateDateTimeJsonConfig(FFDateTimeOptions* options, yyjson_mut_doc* do
|
||||
|
||||
void ffGenerateDateTimeJsonResult(FF_MAYBE_UNUSED FFDateTimeOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
|
||||
{
|
||||
yyjson_mut_obj_add_uint(doc, module, "result", ffTimeGetNow());
|
||||
yyjson_mut_obj_add_strcpy(doc, module, "result", ffTimeToFullStr(ffTimeGetNow()));
|
||||
}
|
||||
|
||||
void ffPrintDateTimeHelpFormat(void)
|
||||
|
||||
@@ -60,7 +60,7 @@ static void printDisk(FFDiskOptions* options, const FFDisk* disk)
|
||||
{
|
||||
if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_BAR_BIT)
|
||||
{
|
||||
ffPercentAppendBar(&str, bytesPercentage, options->percent);
|
||||
ffPercentAppendBar(&str, bytesPercentage, options->percent, &options->moduleArgs);
|
||||
ffStrbufAppendC(&str, ' ');
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ static void printDisk(FFDiskOptions* options, const FFDisk* disk)
|
||||
|
||||
if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_NUM_BIT)
|
||||
{
|
||||
ffPercentAppendNum(&str, bytesPercentage, options->percent, str.length > 0);
|
||||
ffPercentAppendNum(&str, bytesPercentage, options->percent, str.length > 0, &options->moduleArgs);
|
||||
ffStrbufAppendC(&str, ' ');
|
||||
}
|
||||
}
|
||||
@@ -105,10 +105,10 @@ static void printDisk(FFDiskOptions* options, const FFDisk* disk)
|
||||
else
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY bytesPercentageStr = ffStrbufCreate();
|
||||
ffPercentAppendNum(&bytesPercentageStr, bytesPercentage, options->percent, false);
|
||||
ffPercentAppendNum(&bytesPercentageStr, bytesPercentage, options->percent, false, &options->moduleArgs);
|
||||
FF_STRBUF_AUTO_DESTROY filesPercentageStr = ffStrbufCreate();
|
||||
double filesPercentage = disk->filesTotal > 0 ? ((double) disk->filesUsed / (double) disk->filesTotal) * 100.0 : 0;
|
||||
ffPercentAppendNum(&filesPercentageStr, filesPercentage, options->percent, false);
|
||||
ffPercentAppendNum(&filesPercentageStr, filesPercentage, options->percent, false, &options->moduleArgs);
|
||||
|
||||
bool isExternal = !!(disk->type & FF_DISK_VOLUME_TYPE_EXTERNAL_BIT);
|
||||
bool isHidden = !!(disk->type & FF_DISK_VOLUME_TYPE_HIDDEN_BIT);
|
||||
@@ -406,6 +406,8 @@ void ffGenerateDiskJsonResult(FFDiskOptions* options, yyjson_mut_doc* doc, yyjso
|
||||
yyjson_mut_arr_add_str(doc, typeArr, "Hidden");
|
||||
if(item->type & FF_DISK_VOLUME_TYPE_READONLY_BIT)
|
||||
yyjson_mut_arr_add_str(doc, typeArr, "Read-only");
|
||||
if(item->type & FF_DISK_VOLUME_TYPE_UNKNOWN_BIT)
|
||||
yyjson_mut_arr_add_str(doc, typeArr, "Unknown");
|
||||
|
||||
const char* pstr = ffTimeToFullStr(item->createTime);
|
||||
if (*pstr)
|
||||
|
||||
@@ -279,6 +279,7 @@ void ffGenerateDisplayJsonResult(FF_MAYBE_UNUSED FFDisplayOptions* options, yyjs
|
||||
yyjson_mut_obj_add_str(doc, module, "error", "Couldn't detect display");
|
||||
return;
|
||||
}
|
||||
|
||||
yyjson_mut_val* arr = yyjson_mut_obj_add_arr(doc, module, "result");
|
||||
FF_LIST_FOR_EACH(FFDisplayResult, item, dsResult->displays)
|
||||
{
|
||||
|
||||
@@ -19,14 +19,14 @@ static void printDevice(FFGamepadOptions* options, const FFGamepadDevice* device
|
||||
{
|
||||
if (buffer.length)
|
||||
ffStrbufAppendC(&buffer, ' ');
|
||||
ffPercentAppendNum(&buffer, device->battery, options->percent, buffer.length > 0);
|
||||
ffPercentAppendNum(&buffer, device->battery, options->percent, buffer.length > 0, &options->moduleArgs);
|
||||
}
|
||||
ffStrbufPutTo(&buffer, stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY percentageStr = ffStrbufCreate();
|
||||
ffPercentAppendNum(&percentageStr, device->battery, options->percent, false);
|
||||
ffPercentAppendNum(&percentageStr, device->battery, options->percent, false, &options->moduleArgs);
|
||||
|
||||
FF_PRINT_FORMAT_CHECKED(FF_GAMEPAD_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_GAMEPAD_NUM_FORMAT_ARGS, ((FFformatarg[]) {
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &device->name},
|
||||
@@ -118,12 +118,6 @@ void ffGenerateGamepadJsonResult(FF_MAYBE_UNUSED FFGamepadOptions* options, yyjs
|
||||
return;
|
||||
}
|
||||
|
||||
if(!result.length)
|
||||
{
|
||||
yyjson_mut_obj_add_str(doc, module, "error", "No devices detected");
|
||||
return;
|
||||
}
|
||||
|
||||
yyjson_mut_val* arr = yyjson_mut_obj_add_arr(doc, module, "result");
|
||||
FF_LIST_FOR_EACH(FFGamepadDevice, device, result)
|
||||
{
|
||||
|
||||
@@ -45,7 +45,7 @@ static void printGPUResult(FFGPUOptions* options, uint8_t index, const FFGPUResu
|
||||
if(gpu->temperature == gpu->temperature) //FF_GPU_TEMP_UNSET
|
||||
{
|
||||
ffStrbufAppendS(&output, " - ");
|
||||
ffTempsAppendNum(gpu->temperature, &output, options->tempConfig);
|
||||
ffTempsAppendNum(gpu->temperature, &output, options->tempConfig, &options->moduleArgs);
|
||||
}
|
||||
|
||||
if(gpu->dedicated.total != FF_GPU_VMEM_SIZE_UNSET && gpu->dedicated.total != 0)
|
||||
@@ -61,7 +61,7 @@ static void printGPUResult(FFGPUOptions* options, uint8_t index, const FFGPUResu
|
||||
if(gpu->dedicated.used != FF_GPU_VMEM_SIZE_UNSET)
|
||||
{
|
||||
ffStrbufAppendS(&output, ", ");
|
||||
ffPercentAppendNum(&output, (double) gpu->dedicated.used / (double) gpu->dedicated.total * 100.0, options->percent, false);
|
||||
ffPercentAppendNum(&output, (double) gpu->dedicated.used / (double) gpu->dedicated.total * 100.0, options->percent, false, &options->moduleArgs);
|
||||
}
|
||||
ffStrbufAppendC(&output, ')');
|
||||
}
|
||||
@@ -74,7 +74,7 @@ static void printGPUResult(FFGPUOptions* options, uint8_t index, const FFGPUResu
|
||||
else
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY tempStr = ffStrbufCreate();
|
||||
ffTempsAppendNum(gpu->temperature, &tempStr, options->tempConfig);
|
||||
ffTempsAppendNum(gpu->temperature, &tempStr, options->tempConfig, &options->moduleArgs);
|
||||
FF_PRINT_FORMAT_CHECKED(FF_GPU_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_GPU_NUM_FORMAT_ARGS, ((FFformatarg[]) {
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &gpu->vendor},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &gpu->name},
|
||||
|
||||
@@ -11,7 +11,7 @@ void ffPrintKernel(FFKernelOptions* options)
|
||||
if(options->moduleArgs.outputFormat.length == 0)
|
||||
{
|
||||
ffPrintLogoAndKey(FF_KERNEL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
|
||||
ffStrbufWriteTo(&platform->systemRelease, stdout);
|
||||
printf("%s %s", platform->systemName.chars, platform->systemRelease.chars);
|
||||
|
||||
if(platform->systemDisplayVersion.length > 0)
|
||||
printf(" (%s)\n", platform->systemDisplayVersion.chars);
|
||||
@@ -77,7 +77,7 @@ void ffGenerateKernelJsonResult(FF_MAYBE_UNUSED FFKernelOptions* options, yyjson
|
||||
|
||||
void ffPrintKernelHelpFormat(void)
|
||||
{
|
||||
FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_KERNEL_MODULE_NAME, "{2}", FF_KERNEL_NUM_FORMAT_ARGS, ((const char* []) {
|
||||
FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_KERNEL_MODULE_NAME, "{1} {2}", FF_KERNEL_NUM_FORMAT_ARGS, ((const char* []) {
|
||||
"Sysname",
|
||||
"Release",
|
||||
"Version",
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
#include "common/printing.h"
|
||||
#include "common/jsonconfig.h"
|
||||
#include "detection/loadavg/loadavg.h"
|
||||
#include "modules/loadavg/loadavg.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#define FF_LOADAVG_NUM_FORMAT_ARGS 3
|
||||
|
||||
void ffPrintLoadavg(FFLoadavgOptions* options)
|
||||
{
|
||||
double result[3] = { 0.0 / 0.0, 0.0 / 0.0, 0.0 / 0.0 };
|
||||
|
||||
const char* error = ffDetectLoadavg(result);
|
||||
if(error)
|
||||
{
|
||||
ffPrintError(FF_LOADAVG_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", error);
|
||||
return;
|
||||
}
|
||||
|
||||
if(options->moduleArgs.outputFormat.length == 0)
|
||||
{
|
||||
ffPrintLogoAndKey(FF_LOADAVG_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
|
||||
printf("%.*f, %.*f, %.*f\n", options->ndigits, result[0], options->ndigits, result[1], options->ndigits, result[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_PRINT_FORMAT_CHECKED(FF_LOADAVG_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_LOADAVG_NUM_FORMAT_ARGS, ((FFformatarg[]){
|
||||
{FF_FORMAT_ARG_TYPE_DOUBLE, &result[0]},
|
||||
{FF_FORMAT_ARG_TYPE_DOUBLE, &result[1]},
|
||||
{FF_FORMAT_ARG_TYPE_DOUBLE, &result[2]},
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
bool ffParseLoadavgCommandOptions(FFLoadavgOptions* options, const char* key, const char* value)
|
||||
{
|
||||
const char* subKey = ffOptionTestPrefix(key, FF_LOADAVG_MODULE_NAME);
|
||||
if (!subKey) return false;
|
||||
if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs))
|
||||
return true;
|
||||
|
||||
if (ffStrEqualsIgnCase(subKey, "ndigits"))
|
||||
{
|
||||
options->ndigits = (uint8_t) ffOptionParseUInt32(key, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ffParseLoadavgJsonObject(FFLoadavgOptions* 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 (ffStrEqualsIgnCase(key, "ndigits"))
|
||||
{
|
||||
options->ndigits = (uint8_t) yyjson_get_uint(val);
|
||||
continue;
|
||||
}
|
||||
|
||||
ffPrintError(FF_LOADAVG_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Unknown JSON key %s", key);
|
||||
}
|
||||
}
|
||||
|
||||
void ffGenerateLoadavgJsonConfig(FFLoadavgOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
|
||||
{
|
||||
__attribute__((__cleanup__(ffDestroyLoadavgOptions))) FFLoadavgOptions defaultOptions;
|
||||
ffInitLoadavgOptions(&defaultOptions);
|
||||
|
||||
ffJsonConfigGenerateModuleArgsConfig(doc, module, &defaultOptions.moduleArgs, &options->moduleArgs);
|
||||
|
||||
if (defaultOptions.ndigits != options->ndigits)
|
||||
yyjson_mut_obj_add_uint(doc, module, "ndigits", options->ndigits);
|
||||
}
|
||||
|
||||
void ffGenerateLoadavgJsonResult(FF_MAYBE_UNUSED FFLoadavgOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
|
||||
{
|
||||
double result[3] = { 0.0 / 0.0, 0.0 / 0.0, 0.0 / 0.0 };
|
||||
|
||||
const char* error = ffDetectLoadavg(result);
|
||||
if(error)
|
||||
{
|
||||
yyjson_mut_obj_add_str(doc, module, "error", error);
|
||||
return;
|
||||
}
|
||||
|
||||
yyjson_mut_val* arr = yyjson_mut_obj_add_arr(doc, module, "result");
|
||||
for (size_t i = 0; i < 3; i++)
|
||||
yyjson_mut_arr_add_real(doc, arr, result[i]);
|
||||
}
|
||||
|
||||
void ffPrintLoadavgHelpFormat(void)
|
||||
{
|
||||
FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_LOADAVG_MODULE_NAME, "{1}, {2}, {3}", FF_LOADAVG_NUM_FORMAT_ARGS, ((const char* []) {
|
||||
"Load average over 1min",
|
||||
"Load average over 5min",
|
||||
"Load average over 15min",
|
||||
}));
|
||||
}
|
||||
|
||||
void ffInitLoadavgOptions(FFLoadavgOptions* options)
|
||||
{
|
||||
ffOptionInitModuleBaseInfo(
|
||||
&options->moduleInfo,
|
||||
FF_LOADAVG_MODULE_NAME,
|
||||
"Print system load averages",
|
||||
ffParseLoadavgCommandOptions,
|
||||
ffParseLoadavgJsonObject,
|
||||
ffPrintLoadavg,
|
||||
ffGenerateLoadavgJsonResult,
|
||||
ffPrintLoadavgHelpFormat,
|
||||
ffGenerateLoadavgJsonConfig
|
||||
);
|
||||
ffOptionInitModuleArg(&options->moduleArgs);
|
||||
|
||||
options->ndigits = 2;
|
||||
}
|
||||
|
||||
void ffDestroyLoadavgOptions(FFLoadavgOptions* options)
|
||||
{
|
||||
ffOptionDestroyModuleArg(&options->moduleArgs);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
#define FF_LOADAVG_MODULE_NAME "Loadavg"
|
||||
|
||||
void ffPrintLoadavg(FFLoadavgOptions* options);
|
||||
void ffInitLoadavgOptions(FFLoadavgOptions* options);
|
||||
void ffDestroyLoadavgOptions(FFLoadavgOptions* options);
|
||||
@@ -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 FFLoadavgOptions
|
||||
{
|
||||
FFModuleBaseInfo moduleInfo;
|
||||
FFModuleArgs moduleArgs;
|
||||
|
||||
uint8_t ndigits;
|
||||
} FFLoadavgOptions;
|
||||
@@ -192,15 +192,27 @@ bool ffParseLocalIpCommandOptions(FFLocalIpOptions* options, const char* key, co
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ffStrEqualsIgnCase(subKey, "name-prefix"))
|
||||
if (ffStrEqualsIgnCase(subKey, "default-route-only"))
|
||||
{
|
||||
ffOptionParseString(key, value, &options->namePrefix);
|
||||
if (ffOptionParseBoolean(value))
|
||||
options->showType |= FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT;
|
||||
else
|
||||
options->showType &= ~FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ffStrEqualsIgnCase(subKey, "default-route-only"))
|
||||
if (ffStrEqualsIgnCase(subKey, "show-all-ips"))
|
||||
{
|
||||
options->defaultRouteOnly = ffOptionParseBoolean(value);
|
||||
if (ffOptionParseBoolean(value))
|
||||
options->showType |= FF_LOCALIP_TYPE_ALL_IPS_BIT;
|
||||
else
|
||||
options->showType &= ~FF_LOCALIP_TYPE_ALL_IPS_BIT;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ffStrEqualsIgnCase(subKey, "name-prefix"))
|
||||
{
|
||||
ffOptionParseString(key, value, &options->namePrefix);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -274,15 +286,27 @@ void ffParseLocalIpJsonObject(FFLocalIpOptions* options, yyjson_val* module)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ffStrEqualsIgnCase(key, "namePrefix"))
|
||||
if (ffStrEqualsIgnCase(key, "defaultRouteOnly"))
|
||||
{
|
||||
ffStrbufSetS(&options->namePrefix, yyjson_get_str(val));
|
||||
if (yyjson_get_bool(val))
|
||||
options->showType |= FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT;
|
||||
else
|
||||
options->showType &= ~FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ffStrEqualsIgnCase(key, "defaultRouteOnly"))
|
||||
if (ffStrEqualsIgnCase(key, "showAllIps"))
|
||||
{
|
||||
options->defaultRouteOnly = yyjson_get_bool(val);
|
||||
if (yyjson_get_bool(val))
|
||||
options->showType |= FF_LOCALIP_TYPE_ALL_IPS_BIT;
|
||||
else
|
||||
options->showType &= ~FF_LOCALIP_TYPE_ALL_IPS_BIT;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ffStrEqualsIgnCase(key, "namePrefix"))
|
||||
{
|
||||
ffStrbufSetS(&options->namePrefix, yyjson_get_str(val));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -316,13 +340,16 @@ void ffGenerateLocalIpJsonConfig(FFLocalIpOptions* options, yyjson_mut_doc* doc,
|
||||
|
||||
if (options->showType & FF_LOCALIP_TYPE_COMPACT_BIT)
|
||||
yyjson_mut_obj_add_bool(doc, module, "compact", true);
|
||||
|
||||
if (options->showType & FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT)
|
||||
yyjson_mut_obj_add_bool(doc, module, "defaultRouteOnly", true);
|
||||
|
||||
if (options->showType & FF_LOCALIP_TYPE_ALL_IPS_BIT)
|
||||
yyjson_mut_obj_add_bool(doc, module, "showAllIps", true);
|
||||
}
|
||||
|
||||
if (!ffStrbufEqual(&options->namePrefix, &defaultOptions.namePrefix))
|
||||
yyjson_mut_obj_add_strbuf(doc, module, "namePrefix", &options->namePrefix);
|
||||
|
||||
if (options->defaultRouteOnly != defaultOptions.defaultRouteOnly)
|
||||
yyjson_mut_obj_add_bool(doc, module, "defaultRouteOnly", options->defaultRouteOnly);
|
||||
}
|
||||
|
||||
void ffGenerateLocalIpJsonResult(FF_MAYBE_UNUSED FFLocalIpOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
|
||||
@@ -334,13 +361,7 @@ void ffGenerateLocalIpJsonResult(FF_MAYBE_UNUSED FFLocalIpOptions* options, yyjs
|
||||
if(error)
|
||||
{
|
||||
yyjson_mut_obj_add_str(doc, module, "error", error);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if(results.length == 0)
|
||||
{
|
||||
yyjson_mut_obj_add_str(doc, module, "error", "Failed to detect any IPs");
|
||||
goto exit;
|
||||
return;
|
||||
}
|
||||
|
||||
yyjson_mut_val* arr = yyjson_mut_obj_add_arr(doc, module, "result");
|
||||
@@ -354,7 +375,6 @@ void ffGenerateLocalIpJsonResult(FF_MAYBE_UNUSED FFLocalIpOptions* options, yyjs
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "name", &ip->name);
|
||||
}
|
||||
|
||||
exit:
|
||||
FF_LIST_FOR_EACH(FFLocalIpResult, ip, results)
|
||||
{
|
||||
ffStrbufDestroy(&ip->name);
|
||||
@@ -390,15 +410,12 @@ void ffInitLocalIpOptions(FFLocalIpOptions* options)
|
||||
);
|
||||
ffOptionInitModuleArg(&options->moduleArgs);
|
||||
|
||||
options->showType = FF_LOCALIP_TYPE_IPV4_BIT | FF_LOCALIP_TYPE_PREFIX_LEN_BIT;
|
||||
ffStrbufInit(&options->namePrefix);
|
||||
options->defaultRouteOnly =
|
||||
#ifdef __ANDROID__
|
||||
false
|
||||
#else
|
||||
true
|
||||
options->showType = FF_LOCALIP_TYPE_IPV4_BIT | FF_LOCALIP_TYPE_PREFIX_LEN_BIT
|
||||
#ifndef __ANDROID__
|
||||
| FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT
|
||||
#endif
|
||||
;
|
||||
ffStrbufInit(&options->namePrefix);
|
||||
}
|
||||
|
||||
void ffDestroyLocalIpOptions(FFLocalIpOptions* options)
|
||||
|
||||
@@ -13,7 +13,9 @@ typedef enum FFLocalIpType
|
||||
FF_LOCALIP_TYPE_MAC_BIT = 1 << 3,
|
||||
FF_LOCALIP_TYPE_PREFIX_LEN_BIT = 1 << 4,
|
||||
|
||||
FF_LOCALIP_TYPE_COMPACT_BIT = 1 << 10,
|
||||
FF_LOCALIP_TYPE_COMPACT_BIT = 1 << 10,
|
||||
FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT = 1 << 11,
|
||||
FF_LOCALIP_TYPE_ALL_IPS_BIT = 1 << 12,
|
||||
} FFLocalIpType;
|
||||
|
||||
typedef struct FFLocalIpOptions
|
||||
@@ -23,5 +25,4 @@ typedef struct FFLocalIpOptions
|
||||
|
||||
FFLocalIpType showType;
|
||||
FFstrbuf namePrefix;
|
||||
bool defaultRouteOnly;
|
||||
} FFLocalIpOptions;
|
||||
|
||||
@@ -40,7 +40,7 @@ void ffPrintMemory(FFMemoryOptions* options)
|
||||
|
||||
if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_BAR_BIT)
|
||||
{
|
||||
ffPercentAppendBar(&str, percentage, options->percent);
|
||||
ffPercentAppendBar(&str, percentage, options->percent, &options->moduleArgs);
|
||||
ffStrbufAppendC(&str, ' ');
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ void ffPrintMemory(FFMemoryOptions* options)
|
||||
ffStrbufAppendF(&str, "%s / %s ", usedPretty.chars, totalPretty.chars);
|
||||
|
||||
if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_NUM_BIT)
|
||||
ffPercentAppendNum(&str, percentage, options->percent, str.length > 0);
|
||||
ffPercentAppendNum(&str, percentage, options->percent, str.length > 0, &options->moduleArgs);
|
||||
|
||||
ffStrbufTrimRight(&str, ' ');
|
||||
ffStrbufPutTo(&str, stdout);
|
||||
@@ -57,7 +57,7 @@ void ffPrintMemory(FFMemoryOptions* options)
|
||||
else
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY percentageStr = ffStrbufCreate();
|
||||
ffPercentAppendNum(&percentageStr, percentage, options->percent, false);
|
||||
ffPercentAppendNum(&percentageStr, percentage, options->percent, false, &options->moduleArgs);
|
||||
FF_PRINT_FORMAT_CHECKED(FF_MEMORY_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_MEMORY_NUM_FORMAT_ARGS, ((FFformatarg[]){
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty},
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user