Compare commits

...

609 Commits

Author SHA1 Message Date
Carter Li 06ecc9c480 Merge pull request #2217 from fastfetch-cli/dev
Release: v2.60.0
2026-03-06 21:08:19 -06:00
李通洲 50288d91e4 Doc: updates changelog [ci skip] 2026-03-07 10:43:16 +08:00
李通洲 499b4ff445 Kmod (Windows): don't specify maybe_unused on used params 2026-03-07 10:43:01 +08:00
李通洲 dd0021cd5e GPU (Windows): adds kernel version check before D3DKMT syscall 2026-03-07 10:34:21 +08:00
李通洲 f5b70dd8b7 Doc: updates changelog 2026-03-07 09:31:26 +08:00
李通洲 8f8ca11203 Kernel (Windows): simplifies kernel version detection 2026-03-07 09:26:13 +08:00
李通洲 121d399641 CPUUsage (Windows): simplifies Win10 detection 2026-03-07 09:24:38 +08:00
李通洲 26ae4eb21b Chore (Windows): removes unnecessary headers 2026-03-07 01:18:07 +08:00
李通洲 52a81dbdc4 Disk (Windows): reads SystemWindowsDirectory directly from SharedUserData 2026-03-07 00:35:07 +08:00
李通洲 f924a8bf06 Uptime: reads (System|Interrupt)Time directly from SharedUserData 2026-03-07 00:09:08 +08:00
李通洲 c7363f904a Common (Windows): adds definition of KUSER_SHARED_DATA 2026-03-06 23:59:19 +08:00
李通洲 53ffe8459f Global: applies Copilot's suggestions 2026-03-06 18:33:29 +08:00
李通洲 1b702e123e Release: v2.60.0 2026-03-06 15:27:55 +08:00
李通洲 14dccce393 CI (Linux): builds fastfetch with chafa support 2026-03-06 15:27:55 +08:00
李通洲 d040cc810f SMBIOS (Windows): fixes issues raised by Copilot 2026-03-06 14:46:51 +08:00
李通洲 224bea2559 WM (Windows): fixes issues raised by Copilot 2026-03-06 14:36:40 +08:00
李通洲 777d3e599d WM (macOS): fixes issues raised by Copilot 2026-03-06 14:09:13 +08:00
李通洲 7c47bc2656 WM: honors general.detectVersion 2026-03-06 11:10:35 +08:00
李通洲 e4d31381d8 WM (macOS): fetches WM plugin version 2026-03-06 11:08:41 +08:00
Dariqq abf8d75454 Chore (Windows): adds missing header (#2215) 2026-03-05 18:39:03 -06:00
李通洲 2ce152beaf SmbiosHelper (Windows): prefers NtQuerySystemInformation 2026-03-05 10:18:18 +08:00
李通洲 766ed07999 Refactor: prefers ffStr* 2026-03-05 10:16:24 +08:00
李通洲 ddc2131343 Chore (Windows): adds comments 2026-03-05 10:16:11 +08:00
Carter Li b64d8a013d DisplayServer (Linux): check if RANDR is running in Emulation mode 2026-03-05 10:12:38 +08:00
Carter Li e6db59fdde WM (Linux): fix niri version detection logic 2026-03-05 08:45:56 +08:00
李通洲 7ea0bbfb21 CPU / CPUCache (Windows): prefers NtQuerySystemInformation(Ex) 2026-03-03 16:01:36 +08:00
李通洲 ab041e0ad2 JsonSchema: update [ci skip] 2026-03-03 14:34:45 +08:00
李通洲 207f742624 TerminalFont (Windows): hardens the Windows Terminal font detection logic 2026-03-03 14:21:19 +08:00
李通洲 68f0b11b6f WM (Windows): loads wintrust lazily 2026-03-03 11:00:41 +08:00
李通洲 b86c0880b9 Bluetooth (Windows): adds a string variant helper; removes propsys dependency 2026-03-03 11:00:37 +08:00
李通洲 75f4a3d92d Platform (Windows): don't error out on i686 2026-03-03 08:47:34 +08:00
李通洲 70fa1341a8 Bootmgr (Windows): prefers NT API 2026-03-03 08:47:21 +08:00
李通洲 0a55314d37 WM (Windows): uses WinVerifyTrustEx consistantly 2026-03-03 00:27:28 +08:00
李通洲 2198e6123e DisplayServer (Windows): uses the standard GetDpiForMonitor to query scale factors 2026-03-03 00:23:36 +08:00
李通洲 dd37ee0e50 Doc: updates README [ci skip] 2026-03-01 19:27:33 +08:00
李通洲 7006ae0420 CMake (Windows): disable ENABLE_WIN7_COMPAT by default 2026-03-01 19:12:35 +08:00
李通洲 86458ab32a Kmod (SunOS): adds support 2026-03-01 14:44:29 +08:00
李通洲 67ca907e38 Kmod (Windows): adds support 2026-03-01 14:06:54 +08:00
李通洲 e15d06bbad Chore (Windows): move NT stuff to common 2026-03-01 13:58:38 +08:00
zamhedonia eb53797174 Logo (Builtin): adds support for Emmabuntüs (#2207)
* Logo (Builtin): adds Emmabuntüs Logo

* Add Detection for Emmabuntüs

* Update ASCII art in emmabuntus.txt

* Remove duplicate name for Emmabuntus logo

* Update emmabuntus.txt

* Update colors for Emmabuntus logo

---------

Co-authored-by: zamhedonia <zamhedonia@gmx.de>
Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2026-03-01 00:13:16 +08:00
李通洲 c8c32a78b0 Presets: adds examples/32 2026-02-28 18:51:36 +08:00
李通洲 1c032624ac Title: adds {cwd-tilde} support 2026-02-28 18:44:13 +08:00
Carter Li 5087ea77b4 Presets: replaces outer single-line border with double-lines in examples/25 2026-02-28 17:48:36 +08:00
李通洲 b6b42e69c3 DisplayServer (Windows): reduce system dependencies 2026-02-28 10:37:03 +08:00
李通洲 000a688bb6 TerminalShell (Windows): improves logic of GUI program check 2026-02-28 10:06:13 +08:00
李通洲 3e25b213b1 WM (Windows): supports komorebi detection 2026-02-28 10:03:27 +08:00
李通洲 a69cf456ea Binary (Windows): removes imagehlp dep 2026-02-27 22:59:46 +08:00
李通洲 072b76cb12 WM: defaults detectPlugin to true 2026-02-27 18:26:53 +08:00
Carter Li ca8f54d331 CI: forwards envs & upgrades deps 2026-02-27 15:44:09 +08:00
李通洲 6423feaa94 Revert "OS (Windows): restores compatibility with WINE"
Seems WINE now has winbrand.dll

This reverts commit 554184ec72.
2026-02-27 15:41:55 +08:00
李通洲 92ada88ea7 WM (Windows): detect FancyWM & GlazeWM and their versions 2026-02-27 15:35:32 +08:00
李通洲 1789ef85d7 Processing (Windows): tidy 2026-02-27 15:04:43 +08:00
李通洲 42509f115c Common (Windows): always uses en_US when fetching exe version 2026-02-27 15:04:28 +08:00
李通洲 340a58bda1 Shell (Windows): ignore lldb-dap 2026-02-27 15:03:15 +08:00
李通洲 08dfd1321c Platform (macOS): use _NSGetExecutablePath to query current exe path
Unlike proc_pidpath which uses syscall
2026-02-26 15:12:53 +08:00
Carter Li 45d324a8c6 OpenGL: releases EGL context to avoid memleaks 2026-02-26 10:11:23 +08:00
Carter Li afa986efd4 Global (Linux): unrefs dbus replies to avoid memleaks 2026-02-26 10:11:12 +08:00
Carter Li bc6e8c7813 Global (Linux): unrefs dbus connection to avoid memleaks 2026-02-26 09:47:18 +08:00
Carter Li 627fee23d1 Chore: adds assertions 2026-02-26 09:00:24 +08:00
Carter Li 27b474f205 CPU: ensures tempSensor accepts string only
Fixes #2202
2026-02-26 08:55:53 +08:00
李通洲 418c7eecc7 Logo (Builtin): updates secureblue 2026-02-25 13:51:46 +08:00
李通洲 350250d640 Doc: updates json schema [ci skip] 2026-02-25 13:24:33 +08:00
Alxhr0 3cc21905af Editor: adds Zed version detection support (#2200) 2026-02-25 10:56:28 +08:00
underscorejoser c698eb8eb5 Logo (Builtin): fixes Fedora secureblue (#2201)
* fix: colored inside shackle

* Update ASCII art in secureblue.txt

* Fix formatting in secureblue.txt

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2026-02-25 10:55:47 +08:00
Carter Li 463c24beb8 WM (Linux): for LXQt, only query wm settings when wm was not detected
Fixes #2199
2026-02-25 10:37:18 +08:00
李通洲 a5d1b96ecc Logo (Builtin): update ArcoLinux entries to reflect discontinuation and simplify name list 2026-02-24 13:16:58 +08:00
李通洲 63106ebdc1 Logo (Builtin): simplify name entries for Artix and its variants 2026-02-24 12:59:52 +08:00
李通洲 fd36783adb Logo (Builtin): removes redundant name entry for Exherbo 2026-02-24 12:49:02 +08:00
李通洲 3b5186da53 Logo (Builtin): rename ExodiaPredator to ExodiaOS and simplify name entries 2026-02-24 12:48:31 +08:00
李通洲 0140a46090 Logo (Builtin): corrects name casing for Deepin and removes redundant entry 2026-02-24 12:18:04 +08:00
李通洲 9c38e1255f Logo (Builtin): remove redundant names for Debian and DebianSmall 2026-02-24 12:17:56 +08:00
李通洲 663f9d69ff Logo (Builtin): corrects spelling of LinuxLight to LinuxLite 2026-02-24 12:05:52 +08:00
李通洲 d12e5ab801 Logo (Builtin): tidy 2026-02-24 11:56:25 +08:00
李通洲 1d770d85f6 Logo (Builtin): simplifies MassOS name entry 2026-02-24 11:56:06 +08:00
李通洲 5b00afe45d Logo (Builtin): simplifies MiracleLinux name entry 2026-02-24 11:55:41 +08:00
李通洲 5b276567ac Logo (Builtin): simplifies MX and MXSmall name entries 2026-02-24 11:55:22 +08:00
李通洲 56566916e3 Logo (Builtin): simplifies Nobara name entries 2026-02-24 11:54:48 +08:00
李通洲 2c0b4ca3a2 Logo (Builtin): simplifies Raspbian name entries 2026-02-24 11:45:29 +08:00
李通洲 54ffdd32dc Logo (Builtin): simplifies RedOS name entries 2026-02-24 11:45:14 +08:00
李通洲 64f24bdee9 Logo (Builtin): renames Refracted Devuan to Refracta
Ref: https://github.com/dylanaraps/neofetch/issues/2338
2026-02-24 11:41:21 +08:00
李通洲 4706f97bf0 Logo (Builtin): simplifies Rocky Linux 2026-02-24 11:38:01 +08:00
李通洲 0bdb198d52 Logo (Builtin): updates RengeOS entry to remove redundant name 2026-02-24 11:02:11 +08:00
s0s fc7710821e Common: fixes segmentation fault triggered by dereferencing value at negative index (#2198) 2026-02-24 11:00:25 +08:00
thealio e22a9990ec Logo (Builtin): Aritx logos improvements (#2157)
* Create artix4.txt

* Rename artix4.txt to artix2.txt

* Rename artix_small.txt to artix1_small.txt

* Rename artix2_small.txt to artix_small.txt

* Rename artix1_small.txt to artix2_small.txt
2026-02-24 10:59:47 +08:00
Crystal_ForceIX fc7f3a1650 Logo (Builtin): adds RengeOS Logo (#2170) 2026-02-24 10:52:39 +08:00
Carter Li 915af9546d Keyboard (Linux): supports more keyboard events 2026-02-22 22:48:17 +08:00
Carter Li 54a68640ef Packages (Linux): supports moss
Fixes #2191
2026-02-22 22:33:27 +08:00
李通洲 ec1af7c92b Platform (OpenBSD): improves executable path retrieval method
Fixes #2195
2026-02-22 18:14:36 +08:00
Carter Li a1e20270ad Platform: add current working directory (cwd) to FFPlatform structure and initialization 2026-02-21 00:29:02 +08:00
Chiron 4996986ce6 Logo (Builtin): updates Linux Mint ASCII Logo (#2186) 2026-02-19 02:56:56 +08:00
李通洲 e6de2d4fd9 Doc: update issue template [ci skip] 2026-02-19 00:50:43 +08:00
李通洲 5347e74a1b Logo (Builtin): adds linuxmint2
Ref: #2186
2026-02-18 23:58:39 +08:00
李通洲 0ea5639a22 Platform (Windows): prefers Nt* APIs 2026-02-18 20:13:33 +08:00
Carter Li aa3a916d5a Merge pull request #2183 from fastfetch-cli/dev
Release: v2.59.0
2026-02-14 00:15:11 +08:00
Carter Li 6e64b758bf Chore: silences a compiler warning 2026-02-13 23:37:40 +08:00
李通洲 49ef7fc51f Packages (Windows): code cleanups 2026-02-13 20:50:45 +08:00
李通洲 0e9a5acdbd Platform (Windows): adds init / destroy of field sid 2026-02-13 20:42:35 +08:00
李通洲 4f6e80e940 Release: v2.59.0 2026-02-13 19:39:33 +08:00
李通洲 df87cdfa6e Windows: defines NtCurrentProcess and uses it 2026-02-13 19:38:22 +08:00
李通洲 dee4b36a46 Bluetooth (Windows): use modern dlls 2026-02-13 19:25:06 +08:00
李通洲 d04a26337a Swap (Windows): removes unused code 2026-02-13 19:25:06 +08:00
Dark Knightz 2afe8d11d1 Common: fixes discarded-qualifiers warnings (#2181) 2026-02-13 18:05:07 +08:00
李通洲 f31d3b8b21 Doc: update changelog 2026-02-13 10:04:54 +08:00
李通洲 8a20af9917 Doc: update JSON schema 2026-02-13 10:02:28 +08:00
李通洲 fc5c2f6213 Title: adds {user-id} in custom format 2026-02-13 09:38:22 +08:00
Carter Li 6c314e148a Logo (Builtin): updates nixos_small too
Ref #2180
2026-02-13 09:09:05 +08:00
Konnor Klercke a86d0017a9 Logo (Builtin): adds 6-color support to nixos logo (#2180)
Co-authored-by: Konnor Klercke <kklercke@brite.com>
2026-02-13 08:58:48 +08:00
李通洲 4038ed2656 GPU: adds debug logs
Thanks Github Copilot
2026-02-12 18:56:42 +08:00
李通洲 0f4bb47c2f Global: fixes compiler warnings 2026-02-12 16:25:33 +08:00
李通洲 19f7c67ede Platform: adds pid field and use it 2026-02-12 14:29:49 +08:00
李通洲 ff7e81ed81 Memory (Windows): adds comments [ci skip] 2026-02-11 21:47:20 +08:00
李通洲 681a102a2b Processing (Windows): adds TODO [ci skip] 2026-02-11 21:47:09 +08:00
李通洲 ba27f4f2ef CI: adds Solaris 2026-02-11 15:50:58 +08:00
李通洲 cbe33a4860 CI (DragonFly): disables packaging .pkg file to fix a weird CI error 2026-02-11 15:50:58 +08:00
李通洲 5847e3f269 FFPlatform (Windows): fixes memory corruption 2026-02-11 10:03:29 +08:00
李通洲 b248dfa01c Platform: prefers system API to retreive user name 2026-02-10 23:42:57 +08:00
李通洲 357aa77e21 Media (Solaris): fixes another compiling error
Fixes #2173
2026-02-10 22:42:36 +08:00
李通洲 a44bde6f94 Platform: adds UID / SID detection 2026-02-10 20:33:28 +08:00
李通洲 5825bce57d Disk (Windows): replaces most Kernel32 calls to ntdll calls
* Improves accurancy of detection of drive create time
* Improves performance slightly
* Removes remove drive check, `hideFolders` should be used instead
2026-02-10 18:50:35 +08:00
李通洲 996cdd3155 Refactor: moves memrchr to global impl for potential future use 2026-02-10 18:16:58 +08:00
李通洲 61cdfcabf8 Windows: uses SHGetKnownFolderPath instead of the unreliable getenv 2026-02-10 17:32:34 +08:00
李通洲 359a77097c Terminal (Windows): uses NtQueryInformationProcess to retrieve information of conhost.exe 2026-02-10 17:32:34 +08:00
李通洲 1323d007d3 Global: uses alignas where applicable 2026-02-10 17:32:34 +08:00
李通洲 d2215f26ac Processing (Windows): uses NtQueryInformationProcess instead of its wrapper 2026-02-10 17:32:34 +08:00
李通洲 958e7dbd8f Bluetooth (Windows): simplifies code 2026-02-10 17:32:34 +08:00
Verdgil 5b10cde59f Global: Add support for Oracle Solaris (#2176)
* Fix Oracle Solaris zpool build

* Add memrchr fallback

* Change to include fron extern

* add new line

* remove ; in zpool.c

* Change wrapper to macro

Also change README.md

* Tweaks

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2026-02-10 17:32:20 +08:00
李通洲 e8f2b9a1c7 Common: uses _Countof in ARRAY_SIZE definition when available 2026-02-02 11:08:26 +08:00
Carter Li 0686d1db4a GPU (Hurd): uses native API; removes libpciaccess dep 2026-01-30 20:34:47 +08:00
李通洲 7c284f9ee8 CMake (macOS): disable ENABLE_APPLE_MEMSIZE_USABLE by default 2026-01-29 13:11:48 +08:00
李通洲 dc04273bd7 Memory (macOS): updates algorithm in order not to use hw.memsize_usable which is available on newer macOS version
Adds a new CMake option to use usable memory size at the same time

Fixes #2171
2026-01-29 09:34:50 +08:00
李通洲 d698be6239 CPU (ARM): removes duplicated cases 2026-01-27 14:48:05 +08:00
李通洲 e44df27c96 Memory (macOS): adds debug info
Usage: `fastfetch -s memory:swap -l none --dynamic-interval 1000 --debug --no-buffer`
See https://github.com/fastfetch-cli/fastfetch/issues/2171#issuecomment-3803309478
2026-01-27 14:24:38 +08:00
李通洲 b365d4cca1 CPU (ARM): adds more ARM parts 2026-01-26 10:17:28 +08:00
李通洲 19d3c948ad DE (Android): clarifies that Google Pixel and other OSes also report ro.build.display.id 2026-01-26 10:17:28 +08:00
李通洲 4a581039d5 CI: fixes building 2026-01-24 09:17:13 +08:00
李通洲 79849fb2b5 CI: updates dependencies 2026-01-23 10:26:04 +08:00
李通洲 c116a5abdf Chore: uses elvis operators where applicatable 2026-01-22 15:36:42 +08:00
Carter Li 8f082730a8 Packaging: update debian stuff [ci skip] 2026-01-22 15:35:44 +08:00
Carter Li b81c4a04db Merge pull request #2164 from fastfetch-cli/dev
Release: v2.58.0
2026-01-21 15:03:51 +08:00
李通洲 e26a05e3ac DE (Linux): ensures process returns successfully before using its output 2026-01-21 14:28:40 +08:00
李通洲 f08a1fb0b4 Release: v2.58.0 2026-01-21 14:12:53 +08:00
李通洲 2a82009ffe WM (macOS): checks the version of WindowServer instead of WindowManager 2026-01-21 09:39:31 +08:00
李通洲 e851f3a7ed Packages (Linux): optimises pacman detection code 2026-01-20 10:06:02 +08:00
Sean Will 3a865df09e Packages (Linux): Auto detect the DBPath directory for pacman on archlinux (#2154)
Fixes #2068
2026-01-19 19:44:30 -06:00
berezka bae80e2932 Add new KISS Linux logo based off favicon 2026-01-20 09:42:28 +08:00
berezka 4445e1e78d Fix Bedrock Linux version detection & futureproof for 0.8 2026-01-20 09:42:28 +08:00
Carter Li f0e3d3d8e1 Host (Linux): uses /sys/firmware/devicetree/base/smbios if available 2026-01-20 09:20:48 +08:00
Carter Li a313fd1572 Linux: uses the standard /sys/firmware/devicetree/base instead of the outdated /proc/device-tree 2026-01-20 09:11:47 +08:00
Carter Li 927d44d919 Chassis (Linux): uses /proc/device-tree/smbios if available 2026-01-20 08:59:22 +08:00
Carter Li 3b9a91e8af DE (Linux): silences compiler warnings [ci skip] 2026-01-20 08:34:46 +08:00
李通洲 70b4582bb6 DE (Linux): removes option slowVersionDetection
It's always true now

Fixes #2149
2026-01-19 10:55:30 +08:00
李通洲 461552b8d0 DynamicInterval: reruns prepare code before next interval
Fixes #2152
2026-01-16 20:02:03 +08:00
Carter Li 0f3db37199 Chassis (Linux): supports arm devices 2026-01-16 16:47:51 +08:00
Carter Li 67f16b269a DisplayServer (Linux): regenerates wlr-output-management-unstable-v1*
NOOP
2026-01-16 10:40:53 +08:00
李通洲 25671fa4b4 DisplayServer (Linux): fixes crashes on KDE beta
Fixes #2150
2026-01-16 10:13:50 +08:00
Kirill Rekhov 4eaa04d4a4 Presets: update examples to replace deprecated --load-config with --config 2026-01-16 00:43:03 +08:00
李通洲 7592885b9f GPU (Windows): ensures devId is uppercase for consistent parsing 2026-01-15 15:46:21 +08:00
李通洲 508a3fde36 Windows: fixes building 2026-01-15 15:43:05 +08:00
李通洲 f0273224e0 JsonSchema: update [ci skip] 2026-01-15 15:24:54 +08:00
李通洲 31e833c02e Colors: updates module description
Fixes #2147
2026-01-15 15:20:38 +08:00
李通洲 a20d915412 JsonConfig: supports --structure-disabled 2026-01-15 15:11:08 +08:00
李通洲 d3453de73c Global: puts more fastfetch-only properties into FFdata 2026-01-15 15:06:23 +08:00
李通洲 79a11c4728 CommandOption: adds a new option --structure-disabled (WIP)
To disable modules temporarily
2026-01-15 10:35:21 +08:00
李通洲 24591417ce FFstrbuf: clarify usage requirements for ffStrbufGetdelim and friends 2026-01-15 10:30:40 +08:00
李通洲 de6d066fc9 LICENSE: update copyright year to 2026 [ci skip] 2026-01-14 16:33:51 +08:00
Carter Li 6362c896f8 Packaging: updates debian stuff [ci skip] 2026-01-14 14:10:46 +08:00
Carter Li 0418e9ca5e Merge pull request #2145 from fastfetch-cli/dev
Release: v2.57.1
2026-01-13 23:58:22 -06:00
李通洲 ba0eeab18c DisplayServer (Linux): cleanup code 2026-01-14 13:47:40 +08:00
李通洲 5ef630cbc8 Release: v2.57.1 2026-01-14 13:20:55 +08:00
李通洲 1699d14984 Common: ensures thread safety of ffTimeInitQpcMultiplier 2026-01-14 10:03:51 +08:00
Carter Li 501746a270 Logo: removes unneeded #includes
Fixes #2143
2026-01-14 08:50:56 +08:00
李通洲 e6bd1c340f Common: add on_scope_exit utility for scope-based resource management 2026-01-13 18:33:02 +08:00
李通洲 49fc95689d Platform (Windows): improves hostname retrieval by adding fallback to NetBIOS name 2026-01-13 10:44:52 +08:00
李通洲 3d84ad19be macOS: uses MACH_PORT_NULL to maintain compatibility with older SDKs
Fixes #2140
2026-01-13 10:12:31 +08:00
Rain Xelelo 57aa0cf499 Logo (Builtin): updates PrismLinux and adds a small variant (#2141)
* Add files via upload

* Update builtin.c

* Update builtin.c

* Update builtin.c

* PrismLinux logo update + small variant

* Update ASCII art in prismlinux.txt

* Revise ASCII art in prismlinux_small.txt

Updated ASCII art in prismlinux_small.txt

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2026-01-13 10:04:38 +08:00
Carter Li 6496dcd7d0 DisplayServer (Linux): refactors property handling in xcb and xlib 2026-01-13 09:24:27 +08:00
李通洲 1c066bc69a Common: updates ffTimeSleep to return true on success 2026-01-12 15:16:03 +08:00
李通洲 2f1e37bb7c Common (Windows): improves performance of ffTimeGetTick 2026-01-12 15:16:02 +08:00
李通洲 fd3c87abe7 Github: adds pull_request_template.md [ci skip] 2026-01-12 11:04:04 +08:00
李通洲 af075b8ef8 Github: update logo_request.yml [ci skip] 2026-01-12 11:04:04 +08:00
Carter Li 71d461266e Packaging: updates debian stuff [ci skip] 2026-01-12 10:19:39 +08:00
Carter Li 163781557f Merge pull request #2134 from fastfetch-cli/dev
Release: v2.57.0
2026-01-11 20:02:57 -06:00
Carter Li 16e6decebf Logo: general fixes
1. updates JSON schema
2. removes unused fields
3. runs tests in CI
2026-01-12 09:34:25 +08:00
Carter Li e10c9cc164 Doc: updates changelog 2026-01-12 09:06:43 +08:00
Carter Li 7ef994d0cf Logo (Builtin): update macOS variants 2026-01-12 09:00:57 +08:00
ctb unit 248 019c9f0f77 Logo (Builtin): macOS large Apple logo: add missing warm band using ANSI LIGHT_RED (#2138)
Co-authored-by: ctb248 <ctb248@pm.me>
2026-01-10 09:44:27 +08:00
李通洲 5fec607ebe Doc: updates changelog 2026-01-09 20:14:00 +08:00
李通洲 b065b3da51 Global: optimises usage of FFstrbuf and FFlist 2026-01-09 20:14:00 +08:00
李通洲 1337525eb5 Shell: fixes xonsh version detection 2026-01-09 20:14:00 +08:00
李通洲 30ea52938e Processing (SunOS): tidy 2026-01-09 20:14:00 +08:00
李通洲 d43ed33661 Shell (macOS): fixes exePath not reports absolute paths 2026-01-09 20:14:00 +08:00
李通洲 03aab33507 Shell (Linux): supports version detection for deleted binaries
Fixes #2136
2026-01-09 20:14:00 +08:00
李通洲 420d1cf804 FFstrbuf: updates ffStrbufSet* that they won't reserve extra space 2026-01-09 20:13:59 +08:00
Ezozbek 5d901da81b Logo (Builtin): adds Xinux logo (#2135)
* Logo (Builtin): adds Xinux logo

* Fix formatting in xinux.txt ASCII art

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2026-01-08 18:57:28 -06:00
李通洲 5c783e64c0 Logo: adds new module for querying raw builtin logo data
Fixes #2124
2026-01-08 16:39:52 +08:00
李通洲 2efa5a1869 Logo: code refactor for future use 2026-01-08 15:56:44 +08:00
李通洲 5bfabe7a52 Presets: adds a new example 2026-01-08 14:13:19 +08:00
李通洲 c9c9a58f59 Colors: supports @<color-index> 2026-01-08 14:10:47 +08:00
李通洲 546908fc29 Release: v2.57.0 2026-01-08 10:02:31 +08:00
李通洲 0a17da2da0 CI (Windows): build win7-compat artifacts 2026-01-08 09:40:11 +08:00
李通洲 bc6fd025cb Common: silences compiler warnings 2026-01-07 20:11:41 +08:00
李通洲 9e49451340 Display (Windows): supports dpi scale factor detection on Win 7 2026-01-07 20:04:54 +08:00
李通洲 4d185e64ac SunOS: silences compiler warnings 2026-01-07 18:38:44 +08:00
李通洲 1fa9a61b3f CMake (Windows): fixes option ENABLE_WIN7_COMPAT 2026-01-07 18:32:58 +08:00
李通洲 234552fbf2 CI (OpenBSD): uses clang-21 2026-01-07 16:22:28 +08:00
李通洲 8423efb686 CMake (Windows): introduces a flag to remove Win7 compat mode 2026-01-07 11:05:12 +08:00
李通洲 cd8c15d01e OS (Windows): acquires OS name from registry 2026-01-07 10:36:28 +08:00
李通洲 3163cfb1b6 Common (Windows): improves performance a littile 2026-01-07 10:35:48 +08:00
李通洲 7ae007a1d0 CI (OpenBSD): upgrades OS version 2026-01-07 08:58:20 +08:00
李通洲 0b52d75415 GPU (Windows): assumes Win10+ on WoA 2026-01-07 08:58:03 +08:00
李通洲 3a7f4f5848 Uptime (Windows): silences a compiler warning 2026-01-07 08:56:00 +08:00
李通洲 072f67988f Networking: prefers WSA* functions
No functional change.
2026-01-06 22:57:27 +08:00
李通洲 c640ddbff7 Uptime (Windows): uses QueryInterruptTime on WoA unconditionally 2026-01-06 22:41:00 +08:00
李通洲 981ae6bdd1 GPU: improves error handling and add case-insensitive PCI ID parsing 2026-01-06 20:21:03 +08:00
李通洲 977e3f317e Uptime (Windows): improves accurancy on Windows 10 and later 2026-01-06 19:59:02 +08:00
Carter Li e2ee24598c Zpool: add "Is read-only" option to module info 2026-01-06 18:49:52 +08:00
李通洲 1be90084ab Networking: fixes some issues and memory leaks 2026-01-06 16:44:36 +08:00
李通洲 6ded0f9bb0 CMake: fixes building 2026-01-06 10:25:41 +08:00
Carter Li d60b25e424 Refactor: renames src/util to src/common 2026-01-06 09:48:38 +08:00
Carter Li 874f3918b7 Util: moves util/*.c to util/impl/ 2026-01-06 09:42:54 +08:00
Carter Li 61690a1804 Util: moves util/io/io.h to util/io.h 2026-01-06 09:13:40 +08:00
李通洲 1e43e35857 Chore: merges common/* into util/* 2026-01-05 17:54:41 +08:00
李通洲 8c86003220 Common: introduces FF_LIBRARY_LOAD_MESSAGE to simplify library-loading 2026-01-05 17:54:41 +08:00
Carter Li 18c3cd2e66 CPU (Linux): fixes speed detection on s390x
Fixes #2129
2026-01-05 10:50:55 +08:00
Carter Li b21f35e914 CMake (Hurd): defines O_PATH=0 2026-01-05 10:45:19 +08:00
李通洲 32e3ed1fda SMC: optimises code 2026-01-04 16:45:02 +08:00
李通洲 6f87026b0c Host (macOS): uses IORegistryEntryFromPath if applicatable 2026-01-04 15:38:25 +08:00
李通洲 e23edae917 Board (macOS): removes an unused #include 2026-01-04 15:37:11 +08:00
Carter Li bdc867031a TerminalFont (Linux): check xterm.vt100.faceName for xterm font detection 2026-01-04 10:41:24 +08:00
李通洲 e96b0f7a73 Netif (Linux): skips local/loopback routes
Fixes #2127
2026-01-01 23:35:14 +08:00
Carter Li 37fe446a58 TerminalFont (Linux): supports cosmic-term 2026-01-01 22:52:03 +08:00
Carter Li f03a0bc202 Terminal (Linux): supports cosmic-term version detection 2026-01-01 22:32:32 +08:00
Carter Li bcbc5a4bff DE (Linux): fix COSMIC version detection 2026-01-01 22:29:11 +08:00
qaqland 0b1e2faba1 Logo (Builtin): fix colors of UOS 2025-12-31 08:03:19 +08:00
qaqland 4708a5e59c Logo (Builtin): fix colors of deepin 2025-12-31 08:03:19 +08:00
Carter Li 7925469e2f DE (Linux): detect COSMIC version 2025-12-28 23:16:58 +08:00
Carter Li 53116d65f1 WM (Linux): supports niri version detection
Fixes #2121
2025-12-28 23:16:45 +08:00
李通洲 01917b781b Bootmgr (macOS): supports secure boot detection on Intel 2025-12-27 18:12:23 +08:00
李通洲 d01fc56ea2 Bootmgr (macOS): supports secure boot detection 2025-12-27 16:11:16 +08:00
李通洲 9c870a57f0 PhysicalMemory (macOS): improves performance on Apple Silicon 2025-12-27 15:58:56 +08:00
3ventic 7e557a06b3 JsonSchema: correct references for keyboard, mouse items (#2119) [ci skip] 2025-12-27 10:15:04 +08:00
Joe_ fa63038862 Logo (Builtin): renames HydraPWK to NetHydra 2025-12-26 20:38:12 +08:00
Carter Li 8439204cef DisplayServer (Linux): upgrades kde-output-device-v2 wayland protocol files (again) 2025-12-23 16:17:01 +08:00
李通洲 710df0b87b TerminalFont (Linux): improves rxvt detection
Ref #2105
2025-12-23 16:03:04 +08:00
李通洲 302f0fc85f TerminalFont (Linux): supports urxvt
Fixes #2105
2025-12-23 11:05:54 +08:00
Carter Li 241aa3a02c GPU (Linux): silences a strict-aliasing warning
Fixes #2106
2025-12-22 10:28:56 +08:00
李通洲 a17f3dc3f8 Util: fixes building on DragonFly BSD 2025-12-22 08:44:00 +08:00
李通洲 34c0bf58cb Logo (Builtin): adds Tumbleweed braille logo 2025-12-21 18:07:07 +08:00
Carter Li b64b93fc4a Util (mallocHelper): implements ffMallocUsableSize and uses it 2025-12-20 09:26:37 +08:00
Carter Li a9f43ff466 Packaging: update debian stuff 2025-12-18 15:00:51 +08:00
Carter Li 924d78d3c4 Release: v2.56.1 (#2097)
* Logo (Builtin): drop opak

Ref: #1070

* Swap (Windows): adds `K32GetPerformanceInfo` fallback

* Platform (Windows): fixes if checks

* Platform (Windows): adds a null check

* Packages (Windows): improves performance for directory enumeration

* Util (Windows): fixes / adds a new Unicode conversion function

* Packaging: update debian stuff [ci skip]

* IO (Windows): enhances `openat`

* CPU: adds option `tempSensor`

* CPU (macOS): supports `tempSensor`

* CPU (Windows): supports `tempSensor`

* CPU (Linux): supports `tempSensor`

* CPU (FreeBSD): supports `tempSensor`

* CPU (NetBSD): supports `tempSensor`

* CPU (OpenBSD): supports `tempSensor`

* CPU (Linux): prevents variables from integer overflow

* GPU (Linux): add comments

* CPU (SunOS): supports `tempSensor`

* Doc: clarifies that we supports illumos only

* JsonSchema: documents `cpu.tempSensor`

Fixes #2073

* CPUCache (macOS): fixes cache line size detection

* CPU(Linux): Fix build on GNU.

* Chore: refines usage of `PATH_MAX`

* DisplayServer (Linux): upgrades kde-output-device-v2 wayland protocol files (again)

Fixes #2093

* Logo (Builtin): adds gxde logo (#2094)

* add gxde-logo

* add gxdeos

* add gxdeos

* add gxdeos

* Release: v2.56.1

* Memory (macOS): uses `hw.memsize_usable`

* Chore (Windows): Standardize windows header casing. (#2096) [ci skip]

Followup to 0b6ca158ea.

Co-authored-by: Dariqq <dariqq@noreply.codeberg.org>

* IO (Windows): removes unneeded null terminator appending

* CPU (SunOS): adds `const` for consistancy

* Host (macOS): prefers `hw.product` than `hw.model`

... because `HW_MODEL` is deprecated

* Doc: update changelog

* Memory (macOS): Refines Memory usage detection on macOS to match Activity Monitor more closely

* Packages (Windows): fixes possible UB

Reported by Github Copilot

* JsonSchema: refines comments [ci skip]

---------

Co-authored-by: Yelninei <yelninei@tutamail.com>
Co-authored-by: gitee-zeqi <a202128502@163.com>
Co-authored-by: Dariqq <77271900+Dariqq@users.noreply.github.com>
Co-authored-by: Dariqq <dariqq@noreply.codeberg.org>
2025-12-18 14:46:24 +08:00
李通洲 fa92bb84ae JsonSchema: refines comments [ci skip] 2025-12-18 14:35:21 +08:00
李通洲 288d25e17c Packages (Windows): fixes possible UB
Reported by Github Copilot
2025-12-18 14:21:55 +08:00
李通洲 610fc2ea36 Memory (macOS): Refines Memory usage detection on macOS to match Activity Monitor more closely 2025-12-18 13:36:38 +08:00
李通洲 716c0e2b5c Doc: update changelog 2025-12-18 10:00:05 +08:00
李通洲 945aed7160 Host (macOS): prefers hw.product than hw.model
... because `HW_MODEL` is deprecated
2025-12-18 10:00:05 +08:00
李通洲 1d4d68f6e0 CPU (SunOS): adds const for consistancy 2025-12-17 14:30:07 +08:00
李通洲 3e1167260d IO (Windows): removes unneeded null terminator appending 2025-12-17 14:30:07 +08:00
Dariqq 0130f610e9 Chore (Windows): Standardize windows header casing. (#2096) [ci skip]
Followup to 0b6ca158ea.

Co-authored-by: Dariqq <dariqq@noreply.codeberg.org>
2025-12-16 18:53:26 -06:00
李通洲 94941daf4f Memory (macOS): uses hw.memsize_usable 2025-12-16 10:41:27 +08:00
李通洲 2bbd723321 Release: v2.56.1 2025-12-16 10:16:36 +08:00
gitee-zeqi 608382109c Logo (Builtin): adds gxde logo (#2094)
* add gxde-logo

* add gxdeos

* add gxdeos

* add gxdeos
2025-12-15 13:30:47 +08:00
李通洲 bdc5174f68 DisplayServer (Linux): upgrades kde-output-device-v2 wayland protocol files (again)
Fixes #2093
2025-12-15 13:25:26 +08:00
李通洲 bc869f1be9 Chore: refines usage of PATH_MAX 2025-12-12 09:03:18 +08:00
Yelninei dc69e44829 CPU(Linux): Fix build on GNU. 2025-12-11 21:32:45 +08:00
李通洲 d236850119 CPUCache (macOS): fixes cache line size detection 2025-12-11 14:38:06 +08:00
李通洲 60ec8c9097 JsonSchema: documents cpu.tempSensor
Fixes #2073
2025-12-11 14:37:28 +08:00
李通洲 42e7a7d2f7 Doc: clarifies that we supports illumos only 2025-12-11 14:28:12 +08:00
李通洲 e766809e3a CPU (SunOS): supports tempSensor 2025-12-11 14:24:07 +08:00
Carter Li cb1f0300b9 GPU (Linux): add comments 2025-12-11 09:52:50 +08:00
Carter Li f2a29309f3 CPU (Linux): prevents variables from integer overflow 2025-12-11 09:52:50 +08:00
李通洲 6e7b4bab75 CPU (OpenBSD): supports tempSensor 2025-12-11 09:52:50 +08:00
李通洲 b4f39e251c CPU (NetBSD): supports tempSensor 2025-12-11 09:52:50 +08:00
李通洲 af6196fe6e CPU (FreeBSD): supports tempSensor 2025-12-11 09:52:50 +08:00
Carter Li bca56b2049 CPU (Linux): supports tempSensor 2025-12-11 09:52:50 +08:00
李通洲 f4401f172e CPU (Windows): supports tempSensor 2025-12-11 09:52:50 +08:00
李通洲 c11b88fee5 CPU (macOS): supports tempSensor 2025-12-11 09:52:50 +08:00
李通洲 88b1b558d7 CPU: adds option tempSensor 2025-12-11 09:52:50 +08:00
李通洲 ba6cdc77c9 IO (Windows): enhances openat 2025-12-11 09:52:50 +08:00
Carter Li b952772902 Packaging: update debian stuff [ci skip] 2025-12-11 09:52:50 +08:00
李通洲 7a322154fa Util (Windows): fixes / adds a new Unicode conversion function 2025-12-08 20:11:14 +08:00
李通洲 0b6ca158ea Packages (Windows): improves performance for directory enumeration 2025-12-08 16:42:14 +08:00
李通洲 100cd9a72b Platform (Windows): adds a null check 2025-12-08 09:49:54 +08:00
李通洲 98fb810f1f Platform (Windows): fixes if checks 2025-12-08 09:49:54 +08:00
李通洲 c613e558fd Swap (Windows): adds K32GetPerformanceInfo fallback 2025-12-08 09:49:41 +08:00
Carter Li c324f83826 Logo (Builtin): drop opak
Ref: #1070
2025-12-08 09:03:28 +08:00
Carter Li e50421a6ce Merge pull request #2083 from fastfetch-cli/dev
Release: v2.56.0
2025-12-05 22:42:51 +08:00
李通洲 417b944e1c Doc: updates changelog 2025-12-05 21:12:11 +08:00
李通洲 cb8b4b335d FFstrbuf: removes an unnecessary return 2025-12-05 21:10:19 +08:00
李通洲 c0160537b0 Zpool: fixes inconsistant CMake variables 2025-12-05 21:09:00 +08:00
李通洲 4cb7a6424a Logo (Builtin): tidy 2025-12-05 21:08:28 +08:00
李通洲 7d6c79d73e Doc: documents -c - 2025-12-05 10:41:18 +08:00
李通洲 8652737f64 Fastfetch: enhances config file loading with support for config directory
Fixes #2080
2025-12-05 10:32:42 +08:00
李通洲 d6ac89ea8d Release: v2.56.0 2025-12-04 16:15:20 +08:00
李通洲 2b620cf487 CI (SunOS): fixes a CI error 2025-12-04 16:15:20 +08:00
李通洲 f644df481c CPU: exposes numa node count in custom format 2025-12-04 15:21:27 +08:00
李通洲 e99ecacb52 Chore: adds ffIsValidNativeFD and uses it 2025-12-03 09:26:32 +08:00
李通洲 3e22dd4b0e Chore: uses _WIN32 always 2025-12-03 09:26:32 +08:00
Noa Himesaka 19f30ec687 Logo (Builtin): updates Codex Linux new logo (#2071)
* fix: Codex Linux new logo

reMarkable changed their logo so reflecting that change here too

* Modify ASCII art in codex.txt

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2025-12-03 09:09:07 +08:00
Alxhr0 76bee78200 Chore: fixes comment for AerynOS in builtin.c (#2078) 2025-12-03 09:00:09 +08:00
李通洲 ce7455d8f0 Zpool: allows disabling module 2025-12-01 17:20:50 +08:00
李通洲 5e27ee0f57 Shell: fixes ksh version detection on Linux 2025-12-01 10:04:40 +08:00
全てずんだもんの所爲です 84a5c6ebe8 Packages (Linux): add kiss packages count (#2072) 2025-11-30 19:10:07 -06:00
李通洲 ad7e23f64c TerminalFont: supports the newest Alacritty config format
Fixes #2070
2025-11-28 16:35:14 +08:00
李通洲 2738f20eea GPU (Linux): detect driver specific info for zhaoxin 2025-11-28 03:06:23 +00:00
李通洲 09362b236c Util (Windows): fixes compiling 2025-11-25 19:10:43 +08:00
Carter Li 3cfef81877 Users (Linux): always report the newest session info 2025-11-25 19:04:36 +08:00
Carter Li 3a04ae2542 Users (Linux): adds systemd fallback for user detection on Linux
Fixes #2064
2025-11-25 16:40:52 +08:00
Carter Li dbaf8a319d FFstrbuf: adds ffStrbufGetdelim(Restore) 2025-11-25 15:08:42 +08:00
Carter Li 2fe2a21bfe Terminal: reports sshd if $SSH_TTY is not available 2025-11-25 14:33:35 +08:00
Carter Li 37639c3582 Utils: inlines ffIsAbsolutePath 2025-11-25 14:33:35 +08:00
李通洲 9a74e6d7bc Users (Linux): adds missing endutxent 2025-11-25 14:32:36 +08:00
Carter Li 5d13389827 TerminalShell: uses absolute path when detecting version if available
Closes #2067
2025-11-25 09:10:30 +08:00
李通洲 1c2c6644d5 DE: adds Android OEM UI detection
Ref #1900
2025-11-24 15:17:52 +08:00
李通洲 ffcddf30e3 Logo: improve builtin logo printing for piping and buffering
Fixes #2065
2025-11-24 14:18:45 +08:00
李通洲 22c92c7b05 Doc: recommand Ubuntu PPA [ci skip] 2025-11-21 15:56:43 +08:00
李通洲 b569048010 CMake (SunOS): remove static link of libzfs 2025-11-21 15:56:43 +08:00
李通洲 f703d9ac89 Zpool: simplifies implementation by dropping platform-specific code 2025-11-20 18:18:25 +08:00
Steve Gilissen ed6abfd626 Logo (Builtin): adds OS/2 Warp logo (#2062)
* Add OS2 Warp logo

* Update ASCII art in os2warp.txt

* Refactor OS/2 Warp logo names for consistency

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2025-11-19 20:16:19 -06:00
李通洲 50388efc78 Zpool: uses runtime lookup for zpool properties to ensure portability
Fixes #2051
2025-11-19 20:26:18 +08:00
李通洲 7e8fb0fa14 Zpool: simplifies impl; exposes allocated/guid/readOnly 2025-11-19 19:27:19 +08:00
Steve Gilissen 9d70469665 Logo (Builtin): adds Amiga logo (#2061)
* Add Amiga logo

* Update ASCII art in amiga.txt

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2025-11-17 19:52:07 -06:00
李通洲 a94f0efb5b CPU: adds NUMA node detection 2025-11-18 09:30:47 +08:00
Carter Li da3a9be7c6 Packaging: update debian stuff [ci skip] 2025-11-18 09:11:54 +08:00
李通洲 cd8ab8e55a Command: Adds splitLines option 2025-11-17 11:01:32 +08:00
李通洲 1b5b32afad GPU (macOS): fixes a comment [ci skip] 2025-11-17 08:59:39 +08:00
Carter Li 917f784438 Merge pull request #2060 from fastfetch-cli/dev
Release: v2.55.1
2025-11-16 09:56:42 +08:00
李通洲 c2d5d5cca1 Release: v2.55.1 2025-11-16 09:29:24 +08:00
Carter Li b435738c34 CMake (macOS): corrects rpath addition for dlopen builds 2025-11-16 09:15:11 +08:00
apocelipes 934905e63a GPU: silence unused parameter warnings 2025-11-16 08:28:28 +08:00
apocelipes d15bb8a232 Display: fix an uninitialized FFDisplayOptions field 2025-11-15 22:34:33 +08:00
李通洲 c22bca1f87 Processing (Linux): blocks SIGCHLD and simplify poll error handling
Partially reverts e9ab67b380

Fixes #2056 & unfixes #1418
2025-11-15 19:34:13 +08:00
Carter Li e04cc9c9d5 Packaging: update debian changelog [ci skip] 2025-11-12 09:24:50 +08:00
Carter Li 7a2bf4e0ac Merge pull request #2049 from fastfetch-cli/dev
Releases: v2.55.0
2025-11-11 18:51:24 +08:00
李通洲 662f5127fa Shell: makes fish shell version detection more robust (v2) 2025-11-11 15:38:53 +08:00
李通洲 fb9117553b Shell: makes fish shell version detection more robust 2025-11-11 15:19:40 +08:00
李通洲 9f24e4363f Media (Linux): handles invalid percent-encoding in cover metadata 2025-11-11 15:16:12 +08:00
李通洲 084f9294f2 Media: updates naming convention from mediacover to media-cover for media cover logo sources 2025-11-11 14:42:55 +08:00
李通洲 a9f1f9a647 Doc: update changelog 2025-11-11 14:31:23 +08:00
李通洲 0aed89036b Chore: silenses some compiler warnings 2025-11-11 14:24:32 +08:00
李通洲 df15bbc5f2 Media: moves media cover cleanup logic to media detection 2025-11-11 14:00:43 +08:00
李通洲 e6b0bd3817 Media: fixes album cover serialization in JSON result 2025-11-11 13:58:45 +08:00
李通洲 11cd7153a2 Logo (Builtin): tidy [ci skip] 2025-11-11 13:53:34 +08:00
李通洲 f8bc1cb605 Releases: v2.55.0 2025-11-11 11:01:54 +08:00
李通洲 8b8eb6f290 TerminalShell (Linux): ignores run-parts
Ref: #2048
2025-11-11 10:10:47 +08:00
李通洲 056fe21ee2 Examples/25: removes parallel: true since we had it enabled by default [ci skip] 2025-11-11 10:07:58 +08:00
Carter Li cb0a88df22 [Command] enables parallel command execution by default 2025-11-11 09:28:44 +08:00
Carter Li 298c0431c3 Examples: improves clang version extraction method in 25.jsonc [ci skip] 2025-11-11 09:00:01 +08:00
Carter Li 448de9afa5 Command: makes compiler happy 2025-11-10 22:48:22 +08:00
Carter Li 9401a4b9ad Processing: adds a missing header 2025-11-10 18:09:19 +08:00
李通洲 ea92ad3785 Command: adds parallel and useStdErr options
Fixes #2045
2025-11-10 16:34:23 +08:00
李通洲 7aaad5e03e Processing: refactors process execution to separate spawning and reading 2025-11-10 16:34:23 +08:00
李通洲 645bf5c839 Disk: moves disk hiding by folder and FS type to detection code
Don't probe if hided

Fixes #2043
2025-11-06 13:39:30 +08:00
李通洲 7638e0e4a1 CMake: improves wordexp/glob detection and messaging 2025-11-05 10:21:05 +08:00
李通洲 302b8a7b1b CommandLine: adds dynamic output refresh support with interval option 2025-11-05 10:21:05 +08:00
李通洲 dbb9d8a660 Display: adds missing #include 2025-11-05 09:59:27 +08:00
李通洲 c51a164042 PublicIP / Weather: cleans up states after detection 2025-11-05 09:56:23 +08:00
李通洲 6b8a62da6e Linux (Host): improves Mac family detection by using prefix match 2025-11-04 09:12:35 +08:00
李通洲 578ca23e75 GPU (Hurd): adds support (requires libpciaccess) 2025-11-01 09:57:52 +00:00
李通洲 2e73a90835 GPU (OpenBSD): adds native GPU detection support 2025-11-01 17:23:59 +08:00
李通洲 cc6273fecc GPU (NetBSD): don't use system function name 2025-11-01 17:19:25 +08:00
李通洲 e63b777916 GPU: handles missing GPU type as null in JSON output 2025-11-01 16:44:36 +08:00
李通洲 907567f511 GPU (NetBSD): improves performance; drops libpciaccess dependency 2025-11-01 16:42:19 +08:00
李通洲 e0fd7308be Logo (Builtin): add Vincent OS
Fixes #2030
2025-10-31 11:04:18 +08:00
李通洲 b761034aae OS (Linux): prints debian version on Raspbery Pi OS
Fixes #2032
2025-10-31 11:04:18 +08:00
李通洲 04d6b1453d GPU (NetBSD): adds native GPU detection support 2025-10-31 11:04:18 +08:00
Carter Li 11d1754686 GPU: skips auxiliary display controllers
Fixes #2034
2025-10-30 14:46:30 +08:00
Carter Li 25e84decff GPU: unifies non-pci GPU device ID formatting across platforms 2025-10-30 11:01:06 +08:00
Carter Li 7d665b203f GPU: unifies GPU PCI device ID calculation logic across different platforms 2025-10-30 10:26:35 +08:00
李通洲 ac62442798 CMake: refines yyjson config and Apple rpath handling
Fixes #1998
2025-10-28 09:30:46 +08:00
李通洲 758f96de60 Icons (Windows): hides module when no icons are found
Fixes #2023
2025-10-24 14:46:09 +08:00
李通洲 db623b9c86 CI (Linux): adds Debian i386 packaging and verify deb package in CI
Fixes #2019
2025-10-22 17:45:50 +08:00
李通洲 c353bf3c96 Logo: adds automatic cleanup of temporary media cover files 2025-10-22 13:51:36 +08:00
李通洲 338b552499 Logo: adds support for using media cover as logo source 2025-10-21 15:05:25 +08:00
李通洲 5d73cc1232 Media: save media cover to temp file 2025-10-21 14:36:35 +08:00
李通洲 faddef7a3b Media (Windows): adds media cover extraction 2025-10-21 14:01:26 +08:00
Carter Li 2d9bbc8049 Media (Linux): adds media cover extraction 2025-10-21 09:44:36 +08:00
李通洲 64afaa07e7 Media (macOS): adds media cover extraction 2025-10-21 09:44:36 +08:00
李通洲 5cf3ab23b0 Utils (macOS): adds ffCfDictGetDataAsString 2025-10-21 08:49:34 +08:00
李通洲 3fe926d3a0 Doc: adds code-signing credit and privacy statement in README [ci skip]
As required by signpath
2025-10-20 23:43:32 +08:00
李通洲 f71bb682de Logo (Builtin): adds MacaroniOS
Fixes #2018
2025-10-20 15:12:11 +08:00
Carter Li 904f860f3c Packaging: builds for all Ubuntu versions [ci skip] 2025-10-20 14:58:23 +08:00
Carter Li 8f15c9604c Merge remote-tracking branch 'origin/master' into dev 2025-10-20 14:57:59 +08:00
李通洲 ff28f5807b Shell: supports brush version detection 2025-10-19 10:25:28 +08:00
李通洲 6a317366d7 Shell: fix fish version detection when LC_ALL is set
Fixes #2014
2025-10-19 10:25:28 +08:00
李通洲 dc3e4a2d18 JsonSchema: fixes copy-paste errors [ci skip]
Fixes #2013
2025-10-18 18:38:39 +08:00
Carter Li 46c4a71ba3 Merge pull request #2012 from fastfetch-cli/dev
Release: v2.54.0
2025-10-18 10:15:23 +08:00
Carter Li f0759acd11 Brightness (macOS): tidy 2025-10-18 09:35:34 +08:00
李通洲 96c7c2966d Brightness (macOS): prioritizes DDC/CI reply over simple I²C transaction 2025-10-18 01:11:03 +08:00
李通洲 554e7bce4a Logo (Builtin): adds Zraxyl
Fixes #1860
2025-10-18 00:56:14 +08:00
李通洲 70377a8afd Release: v2.54.0 2025-10-18 00:47:35 +08:00
李通洲 51bc6d421a CI (Windows): switches CI to use the release signing policy on the master branch 2025-10-18 00:47:35 +08:00
李通洲 be0756f8ba CMake: adds a new build option to gate wordexp usage and detection 2025-10-16 15:29:24 +08:00
李通洲 71a2cb4e1b Doc: adds security warning for Command module in README 2025-10-16 14:34:51 +08:00
李通洲 2eba761bed IO (OpenBSD): fixes incorrect glob usage 2025-10-16 14:33:53 +08:00
李通洲 4b5e1a816b Display (Windows): rename VRR to DRR 2025-10-16 13:24:44 +08:00
Dariqq a92e4b2d67 Chore (Windows): standardize more windows header casing.
Followup to 25353261d0
2025-10-14 15:49:06 +08:00
李通洲 a32404ba98 Doc: updates changelog 2025-10-14 14:51:44 +08:00
李通洲 0a792e4935 CPU (Android): adds detection support for Samsung Exynos SoCs 2025-10-14 14:49:29 +08:00
李通洲 05108977e8 CPU (Android): improves Android SoC vendor and model detection 2025-10-14 14:49:29 +08:00
李通洲 25353261d0 Chore (Windows): standardizes Windows header include casing. NOOP.
Fixes #2006
2025-10-14 09:10:24 +08:00
李通洲 4b517263d0 Chore (macOS): refactors code for better resource management 2025-10-13 14:27:23 +08:00
李通洲 98a65966e7 Doc: update changelog [ci skip] 2025-10-13 10:19:22 +08:00
李通洲 32dcf9487f Option: adds configurable spacing between icon and string keys
Fixes #2004
2025-10-13 09:54:34 +08:00
Carter Li e3a698f7b1 Brightness (macOS): fixes detection for external monitor on Intel platform 2025-10-11 21:26:37 +08:00
李通洲 1631f74700 Disk (Linux): revisits 78c6d71049 2025-10-11 18:20:56 +08:00
李通洲 78c6d71049 Disk (Linux): adds glob pattern matching for hidden disk folders
Fixes #1999
2025-10-11 16:19:11 +08:00
李通洲 0b9ecdeade Doc: adds Chinese README [ci skip] 2025-10-11 09:31:59 +08:00
李通洲 185a9211f1 Doc: update changelog 2025-10-10 15:09:25 +08:00
李通洲 24459b2fbf Brightness (macOS): enhance DDC/CI detection by enumerating all I2C buses 2025-10-10 14:24:11 +08:00
Carter Li 88c8dcb3e8 CPU (Linux): improves detection for T-Head CPU vendor
Ref: #1997
2025-10-10 10:55:12 +08:00
Carter Li f3a8fedf0a CPU (Linux): improves SoC name detection from device tree
Fixes #1997
2025-10-10 10:50:20 +08:00
李通洲 6b8b7c1a62 CI (Windows): signs PE files 2025-10-08 00:39:22 +08:00
李通洲 af26828f91 CPU (Linux): adds support for HP PA‑RISC & SuperH CPU architecture detection 2025-10-05 09:22:06 +08:00
李通洲 f4c43abbf7 Display (Windows): adds VRR status detection support 2025-10-05 09:17:30 +08:00
李通洲 e84739bff0 Logo (Builtin): update T2 2025-10-05 09:15:59 +08:00
李通洲 66aad0e4f1 Revert "Display (Windows): fixes incorrect refresh rate when VRR is enabled"
Doesn't work

This reverts commit 31ae7a642a.
2025-10-05 00:16:49 +08:00
Carter Li 77c43c0214 Display (Linux): prefer resolutions reported by randr mode info 2025-10-04 22:19:25 +08:00
李通洲 31ae7a642a Display (Windows): fixes incorrect refresh rate when VRR is enabled
Fixes #1994
2025-10-03 23:42:57 +08:00
Carter Li 1bbb21486c Disk (Linux): f* Android
Fixes #1993
2025-10-03 16:53:09 +08:00
李通洲 316d8ddf9b CI (Linux): disables post operations for polyfilled binaries
Fixes #1990
2025-10-03 12:16:15 +08:00
Carter Li 5d8c21a5ca Memory (Linux): fallbacks to calcuate ourselves when MemAvailable seems unreasonable
Fixes #1988
2025-10-02 07:39:20 +08:00
李通洲 240ba5c00c Platform (Windows): adds missing else for Wine version detection 2025-10-01 16:45:13 +08:00
Carter Li 554184ec72 OS (Windows): restores compatibility with WINE
Revert "OS (Windows): hard linking winbrand"

This reverts commit 4146bb6731.
2025-10-01 16:12:45 +08:00
李通洲 7a055a2254 CI: upgrades compiler versions 2025-10-01 10:07:28 +08:00
Carter Li 0a807ac1a3 TerminalFont (Linux): fixes default font size for ghostty
Fixes #1986
2025-10-01 08:09:04 +08:00
Carter Li 4d831c8c73 OS (Linux): don't change prettyName on Ubuntu development branch
Ref: #1483
2025-09-30 15:24:52 +08:00
李通洲 e6e78a7aae OS (macOS): improves OS detection accuracy and sets pretty name 2025-09-30 13:35:48 +08:00
李通洲 09bef5f41d OS (macOS): removes fallback parsing of legacy macOS license file
Doesn't work on Tahoe anymore
2025-09-30 13:22:00 +08:00
李通洲 e394efdd85 OS (macOS): trims whitespace from full user name 2025-09-30 13:19:58 +08:00
李通洲 c10b652a2e Swap (Windows): prevents integer overflow in swap size
Regression from 7ec0c664c5
2025-09-30 10:05:08 +08:00
李通洲 1594a69d6c Kernel (Windows): move kernel.displayVersion to OS.codeName 2025-09-30 10:01:01 +08:00
李通洲 9b1e318bd1 OS (Linux): sets code name for Ubuntu 2025-09-30 09:09:36 +08:00
李通洲 e292bf1dee OS (Linux): sets point release for Debian
Fixes #1985
2025-09-30 09:06:12 +08:00
李通洲 55a0c6e97d Logo (Builtin): adds EmperorOS
Fixes #1963
2025-09-29 10:07:26 +08:00
Rain Xelelo 8b8e4a40a4 Logo (Builtin): adds PrismLinux
Fixes #1983
2025-09-28 21:01:03 -05:00
李通洲 8be070998f Theme (Windows): moves Windows theme detection logic from DE to dedicated module
Like the last commit
2025-09-29 09:40:10 +08:00
李通洲 093f56a03d Theme (macOS): moves macOS theme detection logic from DE to dedicated module
The old behavior was inherited from neofetch. However `Aqua` and `Liquid Glass` are actually design language, not a DE. There is no DE on macOS.
2025-09-29 09:25:24 +08:00
李通洲 bd9744c27c CommandLine: adds --json flag as a shortcut for enabling JSON output 2025-09-28 15:07:45 +08:00
李通洲 adc25f4420 CI: adds Debian libc6 dependency to package config
Fixes #1981
2025-09-28 14:43:38 +08:00
李通洲 229fe7c7bf CMake: update contact info 2025-09-28 14:43:38 +08:00
李通洲 5d571752ae Chore: updates FUNDING info 2025-09-28 14:43:38 +08:00
李通洲 512ddfae6b Doc: adds padding check to logo request template 2025-09-28 09:40:48 +08:00
李通洲 7b689f94df Logo (Builtin): adds secureblue
Fixes #1979
2025-09-28 09:40:21 +08:00
李通洲 9eed149b09 CMake (Linux): adds i686 CI build and unify processor naming
Fixes #1978
2025-09-25 16:30:59 +08:00
李通洲 0f5d321df8 Chore: updates comments to use English descriptions 2025-09-24 10:11:02 +08:00
李通洲 4e84094fd8 CI (OpenBSD): updates CI workflow to upgrade packages before install 2025-09-23 16:41:18 +08:00
李通洲 7b9fce0189 CI (Linux): adds GCC 13 toolchain to CI build environment 2025-09-23 16:00:45 +08:00
李通洲 9ab5c33008 CI: fix release action 2025-09-23 10:19:55 +08:00
Carter Li 613b1d63f1 Packaging: updates debian stuff [ci skip] 2025-09-23 10:03:30 +08:00
Carter Li 8c86cafec7 Merge pull request #1976 from fastfetch-cli/dev
Release: v2.53.0
2025-09-23 09:55:28 +08:00
李通洲 4098cf51b3 Release: v2.53.0 2025-09-23 09:27:52 +08:00
李通洲 bfc23232f8 CPU (Android): adds support for new Qualcomm and MediaTek SoC codes 2025-09-23 09:13:10 +08:00
李通洲 483fba44dc Doc: update changelog [ci skip] 2025-09-22 16:40:10 +08:00
李通洲 851751f99d CPU (Linux): adds support for new ARM C1 series CPU part IDs
Follows changes of util-linux
2025-09-22 16:24:36 +08:00
李通洲 3e86130ddd Zpool: increase libzfs so version to 6
Fixes #1973
2025-09-22 14:32:19 +08:00
李通洲 350ffced13 CI: upgrades runner of intel macOS 2025-09-22 14:13:41 +08:00
李通洲 cdcdb78b97 CPU (Windows): refines ARMv8.4-A detection to require LSE2 2025-09-22 14:08:29 +08:00
Osama Albahrani 2ae9d01200 OS (Linux): Better Ubuntu flavor detection
- Fixes https://github.com/fastfetch-cli/fastfetch/issues/1974
2025-09-22 10:04:45 +08:00
李通洲 e95393750b Wifi (macOS): add (B)SSID detection back for Tohoe 26.0
Fixes #1874
2025-09-22 09:37:07 +08:00
李通洲 de9229697a TerminalFont: improve ghostty with command ghostty +show-config
Ref: #1972
2025-09-20 23:34:07 +08:00
NEOAPPS 9d23d28594 Logo (Builtin): update ObsidianOS logo (#1970)
* feat(logos): add new ObsidianOS logo

* feat(logos): update colors

* chore: remove internal paddings since they're not allowed
2025-09-20 23:02:25 +08:00
李通洲 57a4b9b6ed Disk: refactors mountpoint matching to use shared string utilities 2025-09-19 14:54:13 +08:00
李通洲 ef3989d18d CommandOption: refactors code with ffStrbufSeparatedContainIgnCaseS 2025-09-19 14:51:31 +08:00
李通洲 3079b44f63 FFstrbuf: adds more functions to match separated strings
1. ffStrbufMatchSeparatedIgnCaseNS
2. ffStrbufSeparatedContainNS
3. ffStrbufSeparatedContainNS
2025-09-19 14:34:27 +08:00
李通洲 403900639c Gamepad / Keyboard / Mouse: improves device error handling and memory cleanup 2025-09-19 13:36:02 +08:00
李通洲 0bb5b4cc9c Gamepad / Keyboard / Mouse: adds support to ignore input devices by name prefix
Fixes #1950
2025-09-19 11:00:18 +08:00
李通洲 1180eb55a4 Logo (Builtin): adds TempleOS
Fixes #1969
2025-09-19 09:46:23 +08:00
李通洲 f0e9caaf04 Disk: allows array input for disk folder and filesystem options 2025-09-18 14:51:00 +08:00
李通洲 2c22c3b0c0 CI (Windows): add chafa dependency 2025-09-18 13:44:51 +08:00
李通洲 e9065e15e8 TerminalFont: Improves Ghostty font config parsing with fallback font detection
Fixes #1967
2025-09-18 10:30:28 +08:00
李通洲 9e7816069b Revert "Logo (Builtin): add Starry Linux"
Ref: #1963

This reverts commit 4df4a1de78.
2025-09-17 16:09:05 +08:00
李通洲 82cdc4cd91 Disk (Linux): avoids invalid disk creation times before Linux epoch
Prevent fastfetch from printing invalid create date on Android
2025-09-17 15:37:51 +08:00
Carter Li 822ddc6dc6 Disk (Linux): replace statx(2) call to syscall(2) 2025-09-17 15:09:39 +08:00
李通洲 8bd171a9ff CI: adds glibc polyfill step for compatibility 2025-09-17 14:28:40 +08:00
李通洲 509d6bf30c CI: merge more jobs 2025-09-17 14:00:23 +08:00
李通洲 ab8a13b2d3 CI: update cmake version 2025-09-17 10:39:59 +08:00
Carter Li 3bcdcc5dbf CI: merge amd64 and aarch64 code with matrix 2025-09-16 16:28:45 +08:00
李通洲 38f4215a94 CPU (Windows): trims vendor string read from registry 2025-09-16 10:55:17 +08:00
李通洲 e3eec3f62a CPU (Windows): handles zero temperature data and refactors value use
Fixes #1960
2025-09-14 19:39:17 +08:00
李通洲 e025f28cdc Wifi (macOS): removes wdutil-based Wi-Fi detection code
Let's stop this hide and seek game.
2025-09-12 14:28:01 +08:00
李通洲 3ece4e3b4d Presets: add a new example [ci skip] 2025-09-12 14:11:41 +08:00
Carter Li 6d72a32d1d 3rdparty: upgrade widecharwidth 2025-09-11 14:54:25 +08:00
Carter Li 45be29bad3 CPU (Linux): replaces HWCAP defines with explicit bitmasks for ARM 2025-09-11 14:02:41 +08:00
李通洲 6f5e618341 CPU (Linux): add new ARM part numbers 2025-09-10 14:32:07 +08:00
李通洲 1abfa70237 LocalIP: adds IPv6 type selection for local IP display
`{ "type": "localip", "showIpv6": "ula" /* Show ULA only */ }`

Fixes #1459
2025-09-10 13:42:48 +08:00
李通洲 baaeef5ab5 Separator: uses widecharwidth for Unicode wcwidth and fixes issue that wchar_t on Windows is 2-byte length 2025-09-10 10:34:07 +08:00
李通洲 8eafec479e Separator: rename property length with times 2025-09-09 09:52:10 +08:00
李通洲 5f9e7c799a OpenGL (Windows): simplifies code by removing custom window proc
Adds more cleanups
2025-09-08 00:06:49 +08:00
Carter Li aeb1722eb9 Packaging: update debian stuff [ci skip] 2025-09-05 15:12:49 +08:00
Carter Li de18a07938 Release: v2.52.0 2025-09-05 13:04:53 +08:00
李通洲 88147f80ac Doc: update changelog 2025-09-05 12:38:14 +08:00
李通洲 505ff6ff65 Global: renames fractionTrailingZeros enum to always/never for consistance 2025-09-05 12:27:03 +08:00
李通洲 390549394d Fastfetch: removes redundant assignment in display config parsing
found by copilot
2025-09-05 11:08:37 +08:00
Carter Li f7e7d54c16 Release: v2.52.0 2025-09-05 10:46:30 +08:00
Carter Li 5e068d22c8 Btrfs (Linux): refactors Btrfs allocation to use profile string
Fixes #1941
2025-09-05 10:46:23 +08:00
李通洲 b77646f23e Btrfs (Linux): adds tracking of Btrfs data copy counts
Fixes(?) #1941
2025-09-05 00:18:00 +08:00
李通洲 aa40366a49 Terminal: ignores WSL2 unknown process for terminal detection 2025-09-04 22:31:59 +08:00
Carter Li a64a82f215 WMTheme (Linux): supports labwc on XFCE4 2025-09-04 18:50:23 +08:00
Qing Yun 0a4d6220e9 CPU (Linux): add cpu name detection for ia64 2025-09-04 18:34:14 +08:00
李通洲 6b037c595f Doc: update README 2025-09-04 16:36:55 +08:00
李通洲 f628f5c382 Settings: renames GNOME settings accessor for clarity 2025-09-04 16:17:01 +08:00
李通洲 cf713e32e1 Wallpaper (Linux): improves XFCE wallpaper detection via property enumeration 2025-09-04 13:54:49 +08:00
Carter Li 7d08f81075 Settings: removes direct XFConf support in favor of DBus backend 2025-09-04 09:43:57 +08:00
Carter Li 8822653335 DBus: adds function ffDBusGetInt 2025-09-04 09:35:52 +08:00
李通洲 75ff054255 Dbus: adds 2nd argument to ffDBusGetMethodReply 2025-09-04 08:45:09 +08:00
李通洲 c51cc8ce6b CI: bump dependencies 2025-09-03 16:01:09 +08:00
李通洲 44e23412b5 Doc: update changelog 2025-09-03 16:01:09 +08:00
李通洲 59742bca00 Fastfetch: improves frequency display config validation and schema 2025-09-03 16:01:09 +08:00
李通洲 303edb97ce Fastfetch: add option --faction-trailing-zeros 2025-09-03 14:20:23 +08:00
李通洲 37ab380a6f Logo (Chafa): fixes setting logo.width with chafa
Regression in v2.51.0

Fixes #1947
2025-09-03 10:49:58 +08:00
Carter Li a06e245c34 JsonSchema: update 2025-09-03 09:58:50 +08:00
Carter Li 5de432b083 Fastfetch: defaults display.fraction.ndigits to 2 2025-09-03 09:58:40 +08:00
Carter Li 817285ac01 Fastfetch: informs users that module-specific CLI options are no longer supported
... and provides guidance on transitioning to JSON config
2025-09-03 09:36:16 +08:00
李通洲 8687505505 LocalIP (Linux): skips interfaces without IPs unless MAC display is enabled 2025-09-02 15:00:35 +08:00
李通洲 34c34d25c4 JsonConfig: fixes fractionNdigits will be incorrectly set to 0 when specifying null 2025-09-02 14:44:15 +08:00
李通洲 21b15ee944 Display: rearranges default format; removes scaled resolution 2025-09-02 14:15:37 +08:00
李通洲 8e0a65126e LocalIP: honors fractionTrailingZeros 2025-09-02 14:13:37 +08:00
李通洲 54d8b0a95d Global: adds configurable trailing zeros for double formatting 2025-09-02 14:12:58 +08:00
李通洲 48fc72e95c DisplayServer: improves display size rounding and argument clarity 2025-09-02 09:36:19 +08:00
Carter Li e3d6a85888 Display (Linux): detect scale factor for X11 2025-09-01 21:20:34 +08:00
李通洲 7d92da8829 Global (Android): enable X11 related stuff 2025-09-01 16:28:13 +08:00
李通洲 2f3a361b1f CMake: enable zlib on all platforms 2025-09-01 09:59:06 +08:00
李通洲 ac71f21e6c DisplayServer (Android): update WM name accurately
See #1933
2025-08-30 14:14:48 +08:00
李通洲 8d5316f6aa CMake (Android): link to libm
Fix #1939
2025-08-30 13:31:37 +08:00
Carter Li 1242fda66f Merge pull request #1938 from fastfetch-cli/dev
Release: v2.51.1
2025-08-29 14:05:34 +08:00
李通洲 5a2b618d27 Release: v2.51.1 2025-08-29 13:55:52 +08:00
李通洲 d836d7569f CPU (macOS): removes reliance on unavailable ARM capability headers on macOS
Fixes https://github.com/Homebrew/homebrew-core/pull/235425
2025-08-29 13:45:16 +08:00
Carter Li 8a412e6823 Packaging: update debian stuff [ci skip] 2025-08-29 08:56:30 +08:00
Carter Li 16b6aac764 Merge pull request #1933 from fastfetch-cli/dev
Release: v2.51.0
2025-08-29 08:43:08 +08:00
Carter Li 9f5046d69f CPU/GPU (Linux): Improves CPU/GPU temp detection accuracy on Linux/Android 2025-08-28 18:58:00 +08:00
李通洲 cace1a7156 Revert "Uptime (Windows): use QueryUnbiasedInterruptTime"
Fixes #1935

This reverts commit b812f3ccde.
2025-08-28 18:22:06 +08:00
李通洲 9c0cf863ba JsonSchema: update 2025-08-28 16:36:00 +08:00
Carter Li ffe55d9eee DisplayServer (Linux): upgrade kde-output-device-v2 2025-08-28 16:09:47 +08:00
李通洲 28bc9523d6 Release: v2.51.0 2025-08-28 14:40:31 +08:00
李通洲 ebf810ad4b GPU (Android): adds GPU temp detection support 2025-08-28 14:29:00 +08:00
Carter Li 5c9a0a1f88 Fastfetch: clarify that --debug is debug-mode only 2025-08-28 09:32:01 +08:00
李通洲 bc05a30724 CPU (Linux): improve temp detection
Support Android
2025-08-28 09:29:33 +08:00
李通洲 98c7803a24 Battery (Android): fix battery temp detection 2025-08-27 16:28:54 +08:00
李通洲 0893013e78 DisplayServer (Android): fix display server name 2025-08-27 15:43:50 +08:00
李通洲 e6985a8832 Global: handles missing config directories more gracefully 2025-08-27 15:29:38 +08:00
Carter Li 7a87638fec InitSystem (GNU): support shepherd detection 2025-08-27 14:46:20 +08:00
李通洲 00f163be32 CPU (Windows): detects march on WoA
Tested in VM
2025-08-27 09:22:02 +08:00
李通洲 68bbb2980e CPU (macOS): detects march on Apple Silicon 2025-08-27 09:22:02 +08:00
Carter Li dd1a799abb CPU (Linux): detects march on aarch64 2025-08-27 09:22:02 +08:00
Carter Li 7611d672b7 Merge pull request #1931 from CarterLi/dev
Add GNU/Hurd support
2025-08-25 13:41:53 +08:00
carter bfb93cd8f5 Processing (Linux): enhances robustness when extracting process name and related fields
... by accurately handling process names with spaces or special characters.
2025-08-25 10:39:56 +08:00
李通洲 0998b1e59e DiskIO (Linux): trim trailing white spaces 2025-08-25 09:26:04 +08:00
李通洲 588c4c0026 Chore: silense compiler warnings 2025-08-25 09:25:25 +08:00
Carter Li a80ea2b117 CPUUsage: adds user guidance when CPU time fails to increase 2025-08-24 22:23:07 +08:00
Carter Li 13110e3074 LocalIP (GNU): adds MAC addr detection support 2025-08-24 22:15:06 +08:00
Carter Li 0b2c0445c0 InitSystem: tidy 2025-08-24 22:09:22 +08:00
Carter Li 062963d6cc CMake (GNU): disable wifi support 2025-08-24 22:04:58 +08:00
Carter Li 4b7f231b5a Processing (GNU): fix command name reading 2025-08-24 21:52:38 +08:00
Carter Li 74e0732390 Common (GNU): more __GNU__ tests 2025-08-24 21:40:22 +08:00
Carter Li e9104c38c6 Terminal (GNU): enable version detection 2025-08-24 13:04:12 +01:00
Carter Li 4a7b3a8493 Processing (GNU): hurd uses cmdline instead of comm 2025-08-24 19:57:54 +08:00
Carter Li 20fafa5a21 WM (GNU): enable 2025-08-24 19:56:52 +08:00
Carter Li 1d32344cf7 Global (GNU): code cleanups 2025-08-24 19:37:06 +08:00
Carter Li 82a1eaf276 Chore: tidy tabs 2025-08-24 19:09:51 +08:00
Carter Li 75a023f4d7 CMake (GNU): enable a lot of things 2025-08-24 12:05:14 +01:00
Yelninei 53424300e3 localip: Remove AF_LINK on GNU.
https://salsa.debian.org/glibc-team/glibc/-/blob/sid/debian/patches/hurd-i386/submitted-AF_LINK.diff
2025-08-24 11:29:02 +01:00
Yelninei d553bc4893 WIP: shepherd initsystem 2025-08-24 11:29:01 +01:00
Yelninei add2bfd108 Fix localip_linux on GNU 2025-08-24 11:29:01 +01:00
Yelninei e508100a15 disable ffPackagesGetNix on when it is not defined 2025-08-24 11:29:01 +01:00
Yelninei 1a2f4b4c1f Port netif_gnu to the new api. 2025-08-24 11:29:01 +01:00
Yelninei e968bca89d Fork netif_linux to netif_gnu.
netif_linux now uses linux specifics which do not work on GNU.
2025-08-24 11:29:01 +01:00
Yelninei 71fbe04367 Start work on GNU 2025-08-24 11:29:01 +01:00
李通洲 f2f9b10b18 TerminalShell: remove special handling of hyfetch
Ref: https://github.com/search?q=repo%3Ahykilpikonna%2Fhyfetch%20FFTS_IGNORE_PARENT&type=code
2025-08-24 00:00:10 +08:00
李通洲 fae4892643 Fastfetch: improves config file generation message with tips 2025-08-23 20:37:29 +08:00
李通洲 8589bf2392 Chore: silence compiler warnings 2025-08-23 15:31:42 +08:00
李通洲 8b18e69980 CPU: fix building on non-x86 2025-08-23 15:28:48 +08:00
李通洲 9ae968fbd3 CPU: adds CPU microarchitecture detection for x64 and reporting
Fixes #1928
2025-08-23 15:17:57 +08:00
李通洲 8f6608db74 Disk: adds formatted free and available disk size fields
Fixes #1929
2025-08-23 13:59:48 +08:00
李通洲 45b6a333ec Logo (Builtin): adds AerynOS
Fixes #1926
2025-08-22 14:23:52 +08:00
李通洲 5012bc250b Processes (Linux): be compatible with Hurd 2025-08-22 14:08:18 +08:00
李通洲 5775409cb9 DisplayServer (Android): update WM name 2025-08-22 14:07:58 +08:00
李通洲 64da80d520 Fastfetch: improves format help output for config and variables
Fixes #1927
2025-08-21 23:57:37 +08:00
Carter Li 8b1bfcb34b WM (Linux): uses the same X11 props as neofetch to query WM name
Fixes twin detection
2025-08-21 18:35:09 +08:00
Carter Li 784a7a92c8 DE (Linux): adds Trinity version detection support 2025-08-21 18:19:23 +08:00
李通洲 8331242f42 GPU (BSD): fallbacks to pciids/pci.ids 2025-08-21 10:54:34 +08:00
李通洲 79fea61c90 Merge remote-tracking branch 'origin' into dev 2025-08-21 10:41:04 +08:00
Carter Li a8e7d38afd Packaging: update debian stuff [ci skip] 2025-08-21 10:39:59 +08:00
Carter Li 24467e8c46 GPU (BSD): always use pci.ids provided by hwdata
Fixes #1924
2025-08-21 09:23:01 +08:00
李通洲 6867b87c3e Disk: disable hyperlink by default and move it to custom keys 2025-08-21 08:53:51 +08:00
Carter Li cb13d43a7a TerminalShell (Linux): always ignore pid1 (v2) 2025-08-21 00:19:52 +08:00
Carter Li bd7190ca6d TerminalShell (Linux): always ignore pid1 2025-08-21 00:12:41 +08:00
Carter Li 49982588cf Disk (Linux): remove unused headers 2025-08-20 23:52:53 +08:00
Carter Li de2dff5da0 Common: corrects the position for appending milliseconds 2025-08-20 11:07:53 +08:00
Carter Li b05c54486f LocalIP (Linux): improves netlink route parsing by avoiding possible message truncation
Fixes #1919
2025-08-20 11:07:06 +08:00
Carter Li 1f1d7cf936 FFstrbuf: handles double rounding and zero representation in formatter 2025-08-20 10:10:30 +08:00
李通洲 26253f8863 GPU (Windows): improves GPU detection by refining device filtering 2025-08-19 19:03:55 +08:00
李通洲 08e6db090b Shell (Windows): be compatible with fish 4 built by MSYS2 2025-08-19 17:25:04 +08:00
李通洲 ec0fa89cc8 Common: refactors number formatting to use type-specific append functions 2025-08-19 17:22:11 +08:00
李通洲 7f48500cfd Format: replaces format specifiers with type-safe append functions 2025-08-19 16:04:00 +08:00
李通洲 a7eecf6fc7 FFstrbuf: improves double formatting precision handling 2025-08-19 16:03:04 +08:00
李通洲 8e282a3865 Duration: use ffStrbufAppendUInt 2025-08-19 15:19:12 +08:00
李通洲 dcbf76b233 FFstrbuf: adds number appending functions 2025-08-19 15:00:30 +08:00
李通洲 70b11d953c Logo (Builtin): honor logo.width 2025-08-19 10:35:11 +08:00
李通洲 fa3b634c07 JsonConfig: support JSON5 2025-08-19 10:25:52 +08:00
李通洲 ea86273a0e Common: refactors time formatting to use a shared buffer and utility macro 2025-08-19 09:49:43 +08:00
李通洲 4f88e1f26d 3rdparty: upgrade yyjson to 0.12.0 2025-08-19 08:43:38 +08:00
李通洲 805e277429 JsonConfig: adds 'succeeded' module condition to JSON config
Fixes #1908
2025-08-18 14:18:37 +08:00
李通洲 3ce3de2963 OS: set the icon of unknown OS type as a cog 2025-08-18 14:03:52 +08:00
李通洲 3b5e9c74d6 Modules: return bool to indicate whether the detection is succeeded 2025-08-18 13:38:30 +08:00
李通洲 a9aaa36b2c CI (DFBSD): enable 2025-08-17 23:08:43 +08:00
李通洲 bef4ee1fbc CI (SunOS): fix build 2025-08-17 23:03:45 +08:00
李通洲 b3ddd084ba Merge remote-tracking branch 'upstream/master' into dev 2025-08-17 23:03:17 +08:00
Mathias Korsbäck fef3b7c647 CPU (macOS): changes CPU to M2 Pro for Mac14,12 host (#1915)
Currently states it's a M2 but according to https://support.apple.com/en-us/102852 and https://everymac.com/ultimate-mac-lookup/?search_keywords=Mac14%2C12 it's a M2 Pro.
2025-08-17 21:37:17 +08:00
653 changed files with 20654 additions and 11150 deletions
+3
View File
@@ -0,0 +1,3 @@
github: LinusDierheimer
ko_fi: carterli
custom: https://paypal.me/zhangsongcui
@@ -16,6 +16,15 @@ body:
options:
- label: I have checked the FAQ but the issue is not covered
required: true
- type: checkboxes
attributes:
label: Not a known issue
description: Please check if the issue is already known and being worked on.
options:
- label: I have checked the existing issues but the issue is not covered
required: true
- label: My issue is not about crashing on Fedora and KDE 6.6
required: true
- type: markdown
attributes:
value: "### General description of the bug"
+18 -9
View File
@@ -6,33 +6,42 @@ body:
- type: markdown
attributes:
value: |
Tip: A logo can be displayed by fastfetch without getting into fastfetch's official repo.
For highly customized logo for personal use, it's recommended to keep it locally.
Tip: You can display a logo in fastfetch without adding it to fastfetch's official repo.
For highly customized, personal logos, we recommend keeping them locally.
Please refer to https://github.com/fastfetch-cli/fastfetch/wiki/Migrate-Neofetch-Logo-To-Fastfetch
- type: textarea
attributes:
label: OS
description: Paste content of `/etc/os-release` and `/etc/lsb-release` here. If none of these files exist, describe a way to identify the distro
description: Paste the contents of `/etc/os-release` and `/etc/lsb-release` here. If neither file exists, describe how to identify the distro.
placeholder: cat /etc/os-release
validations:
required: true
- type: input
attributes:
label: Distro Website
description: To help prevent spam and verify the request, a distro website is required, and a downloadable ISO must be available on that site.
placeholder: https://example.com
validations:
required: true
- type: textarea
attributes:
label: ASCII Art
description: An ASCII logo should not take up too much space (smaller than 50x20 characters). Please also include the color codes if not available in `os-release`
description: The ASCII logo should not take up too much space (smaller than 50x20 characters, W x H). Please also include the color codes if they are not available in `os-release`.
placeholder: Paste ASCII art here
validations:
required: true
- type: input
attributes:
label: Original Image
description: If the ASCII art is based on an image, please provide a link to the original image
placeholder: Image URL or distro website URL
label: Original Image URL
description: If the ASCII art is based on an image, please provide a link to the original image file.
placeholder: Image URL from the distro website mentioned above
- type: checkboxes
attributes:
label: Checklist
options:
- label: The ASCII art is smaller than 50x20 characters (width x height)
- label: The ASCII art is smaller than 50x20 characters (W x H).
required: true
- label: The ASCII art contains color codes, or the color codes are available in `os-release`
- label: The ASCII art includes color codes, or the color codes are available in `os-release`.
required: true
- label: The ASCII art has no internal padding (spaces at the start and/or end of lines).
required: true
+26
View File
@@ -0,0 +1,26 @@
## Summary
<!-- Briefly describe what this PR does. -->
## Related issue (required for new logos for new distros)
<!--
If this PR adds a new logo, it MUST be linked to an existing "Logo Request" issue and has the requests fulfilled.
Use one of the following formats so GitHub links it properly:
- Closes #1234
- Fixes #1234
- Resolves #1234
PRs that add logos without an associated Logo Request issue will not be accepted.
-->
Closes #
## Changes
-
## Checklist
- [ ] I have tested my changes locally.
+249 -294
View File
@@ -13,7 +13,7 @@ jobs:
steps:
- name: checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: Install codespell
shell: bash
@@ -32,13 +32,13 @@ jobs:
contents: read
steps:
- name: checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: uname -a
run: uname -a
- name: configure project
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr . -DENABLE_VULKAN=OFF -DENABLE_WAYLAND=OFF -DENABLE_XCB_RANDR=OFF -DENABLE_XCB=OFF -DENABLE_XRANDR=OFF -DENABLE_X11=OFF -DENABLE_DRM=OFF -DENABLE_DRM_AMDGPU=OFF -DENABLE_GIO=OFF -DENABLE_DCONF=OFF -DENABLE_DBUS=OFF -DENABLE_XFCONF=OFF -DENABLE_SQLITE3=OFF -DENABLE_RPM=OFF -DENABLE_IMAGEMAGICK7=OFF -DENABLE_IMAGEMAGICK6=OFF -DENABLE_CHAFA=OFF -DENABLE_ZLIB=OFF -DENABLE_EGL=OFF -DENABLE_GLX=OFF -DENABLE_OPENCL=OFF -DENABLE_FREETYPE=OFF -DENABLE_PULSE=OFF -DENABLE_DDCUTIL=OFF -DENABLE_ELF=OFF -DENABLE_DIRECTX_HEADERS=OFF -DENABLE_THREADS=OFF
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr . -DENABLE_VULKAN=OFF -DENABLE_WAYLAND=OFF -DENABLE_XCB_RANDR=OFF -DENABLE_XCB=OFF -DENABLE_XRANDR=OFF -DENABLE_X11=OFF -DENABLE_DRM=OFF -DENABLE_DRM_AMDGPU=OFF -DENABLE_GIO=OFF -DENABLE_DCONF=OFF -DENABLE_DBUS=OFF -DENABLE_SQLITE3=OFF -DENABLE_RPM=OFF -DENABLE_IMAGEMAGICK7=OFF -DENABLE_IMAGEMAGICK6=OFF -DENABLE_CHAFA=OFF -DENABLE_ZLIB=OFF -DENABLE_EGL=OFF -DENABLE_GLX=OFF -DENABLE_OPENCL=OFF -DENABLE_FREETYPE=OFF -DENABLE_PULSE=OFF -DENABLE_DDCUTIL=OFF -DENABLE_ELF=OFF -DENABLE_DIRECTX_HEADERS=OFF -DENABLE_THREADS=OFF
- name: build project
run: cmake --build . --target package --verbose -j4
@@ -61,17 +61,24 @@ jobs:
- name: run tests
run: ctest --output-on-failure
linux-amd64:
name: Linux-amd64
runs-on: ubuntu-22.04
linux-hosts:
name: Linux-${{ matrix.arch }}
runs-on: ${{ matrix.runs-on }}
permissions:
security-events: write
contents: read
strategy:
matrix:
include:
- arch: amd64
runs-on: ubuntu-22.04
- arch: aarch64
runs-on: ubuntu-22.04-arm
outputs:
ffversion: ${{ steps.ffversion.outputs.ffversion }}
steps:
- name: checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: uname -a
run: uname -a
@@ -82,8 +89,11 @@ jobs:
- name: cat /proc/cpuinfo
run: cat /proc/cpuinfo
- name: add gcc-13 repo
run: sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
- name: install required packages
run: sudo apt-get update && sudo apt-get install -y 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 ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev libddcutil-dev directx-headers-dev
run: sudo apt-get update && sudo apt-get install -y gcc-13 g++-13 libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev libddcutil-dev directx-headers-dev rpm ninja-build
- name: install linuxbrew packages
run: |
@@ -91,18 +101,20 @@ jobs:
/home/linuxbrew/.linuxbrew/bin/brew install imagemagick chafa --ignore-dependencies
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
if: matrix.arch == 'amd64'
uses: github/codeql-action/init@v4
with:
languages: c
- name: configure project
run: PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_INSTALL_PREFIX=/usr .
run: CC=gcc-13 CXX=g++-13 PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -GNinja -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_INSTALL_PREFIX=/usr .
- name: build project
run: cmake --build . --target package --verbose -j4
- name: perform CodeQL analysis
uses: github/codeql-action/analyze@v3
if: matrix.arch == 'amd64'
uses: github/codeql-action/analyze@v4
- name: list features
run: ./fastfetch --list-features
@@ -126,21 +138,33 @@ jobs:
id: ffversion
run: echo "ffversion=$(./fastfetch --version-raw)" >> $GITHUB_OUTPUT
- name: polyfill glibc
run: |
wget https://github.com/CarterLi/polyfill-glibc/releases/download/v0.0.1/polyfill-glibc-${{ matrix.arch }} -O polyfill-glibc
chmod +x polyfill-glibc
strip fastfetch && ./polyfill-glibc fastfetch --target-glibc=2.17
strip flashfetch && ./polyfill-glibc flashfetch --target-glibc=2.17
echo 'set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-polyfilled")' >> CPackConfig.cmake
echo 'set(CPACK_PACKAGE_RELOCATABLE OFF)' >> CPackConfig.cmake
echo 'set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.17)")' >> CPackConfig.cmake
echo 'set(CPACK_RPM_SPEC_MORE_DEFINE "%global __os_install_post %{nil}")' >> CPackConfig.cmake
cpack -V
- name: upload artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: fastfetch-linux-amd64
name: fastfetch-linux-${{ matrix.arch }}
path: ./fastfetch-*.*
linux-aarch64:
name: Linux-aarch64
runs-on: ubuntu-22.04-arm
linux-i686:
name: Linux-i686
runs-on: ubuntu-22.04
permissions:
security-events: write
contents: read
steps:
- name: checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: uname -a
run: uname -a
@@ -151,20 +175,29 @@ jobs:
- name: cat /proc/cpuinfo
run: cat /proc/cpuinfo
- name: add gcc-13 repo
run: sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
- name: install required packages
run: sudo apt-get update && sudo apt-get install -y 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 ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev libchafa-dev libddcutil-dev rpm
run: sudo apt-get update && sudo apt-get install -y gcc-13 gcc-13-multilib libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev libddcutil-dev rpm ninja-build
- name: install linuxbrew packages
run: |
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
/home/linuxbrew/.linuxbrew/bin/brew install imagemagick chafa --ignore-dependencies
- name: cmake version
run: cmake --version
- name: configure project
run: PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_INSTALL_PREFIX=/usr .
run: CC=gcc-13 PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -DCMAKE_C_FLAGS="-m32 -march=i686 -mtune=i686" -DCMAKE_SYSTEM_PROCESSOR_OVERRIDE=i686 -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=i386 -GNinja -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_INSTALL_PREFIX=/usr -DENABLE_DIRECTX_HEADERS=Off .
- name: build project
run: cmake --build . --target package --verbose -j4
- name: check deb package
run: dpkg -I fastfetch-*.deb
- name: list features
run: ./fastfetch --list-features
@@ -183,14 +216,10 @@ jobs:
- name: run tests
run: ctest --output-on-failure
- name: get fastfetch version
id: ffversion
run: echo "ffversion=$(./fastfetch --version-raw)" >> $GITHUB_OUTPUT
- name: upload artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: fastfetch-linux-aarch64
name: fastfetch-linux-i686
path: ./fastfetch-*.*
linux-armv7l:
@@ -201,7 +230,7 @@ jobs:
contents: read
steps:
- name: checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: run VM
uses: uraimo/run-on-arch-action@v3
@@ -212,12 +241,13 @@ jobs:
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 ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev rpm
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
apt-get update && apt-get install -y software-properties-common ca-certificates gpg curl
add-apt-repository -y ppa:ubuntu-toolchain-r/test
curl -L https://apt.kitware.com/keys/kitware-archive-latest.asc | gpg --dearmor - | tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null
echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ focal main' | tee /etc/apt/sources.list.d/kitware.list >/dev/null
echo -e 'Acquire::https::Verify-Peer "false";\nAcquire::https::Verify-Host "false";' >> /etc/apt/apt.conf.d/99ignore-certificates
apt-get update && apt-get install -y cmake make gcc-13 libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev rpm
CC=gcc-13 cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_DIRECTX_HEADERS=Off -DCMAKE_INSTALL_PREFIX=/usr .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
@@ -227,7 +257,7 @@ jobs:
ctest --output-on-failure
- name: upload artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: fastfetch-linux-armv7l
path: ./fastfetch-*.*
@@ -240,7 +270,7 @@ jobs:
contents: read
steps:
- name: checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: run VM
uses: uraimo/run-on-arch-action@v3
@@ -252,8 +282,8 @@ jobs:
run: |
uname -a
apt-get update && apt-get install -y wget
apt-get install -y cmake 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 ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev rpm
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
apt-get install -y cmake make gcc libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev rpm
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_DIRECTX_HEADERS=Off -DCMAKE_INSTALL_PREFIX=/usr .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
@@ -263,32 +293,40 @@ jobs:
ctest --output-on-failure
- name: upload artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: fastfetch-linux-armv6l
path: ./fastfetch-*.*
linux-riscv64:
name: Linux-riscv64
runs-on: ubuntu-24.04
linux-vms:
name: Linux-${{ matrix.arch }}
runs-on: ubuntu-latest
permissions:
security-events: write
contents: read
strategy:
matrix:
include:
- arch: riscv64
- arch: ppc64le
- arch: s390x
steps:
- name: checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: run VM
uses: uraimo/run-on-arch-action@v3
id: runcmd
with:
arch: riscv64
arch: ${{ matrix.arch }}
distro: ubuntu22.04
githubToken: ${{ github.token }}
run: |
uname -a
apt-get update && apt-get install -y cmake 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 ocl-icd-opencl-dev libpulse-dev libdrm-dev libddcutil-dev libchafa-dev libelf-dev directx-headers-dev rpm
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
apt-get update && apt-get install -y software-properties-common
add-apt-repository -y ppa:ubuntu-toolchain-r/test
apt-get update && apt-get install -y cmake make gcc-13 libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libchafa-dev libelf-dev rpm
CC=gcc-13 cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_DIRECTX_HEADERS=Off -DCMAKE_INSTALL_PREFIX=/usr .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
@@ -298,86 +336,16 @@ jobs:
ctest --output-on-failure
- name: upload artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: fastfetch-linux-riscv64
path: ./fastfetch-*.*
linux-ppc64le:
name: Linux-ppc64le
runs-on: ubuntu-24.04
permissions:
security-events: write
contents: read
steps:
- name: checkout repository
uses: actions/checkout@v5
- name: run VM
uses: uraimo/run-on-arch-action@v3
id: runcmd
with:
arch: ppc64le
distro: ubuntu20.04
githubToken: ${{ github.token }}
run: |
uname -a
apt-get update && apt-get install -y cmake 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 ocl-icd-opencl-dev libpulse-dev libdrm-dev libchafa-dev libelf-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 --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
ctest --output-on-failure
- name: upload artifacts
uses: actions/upload-artifact@v4
with:
name: fastfetch-linux-ppc64le
path: ./fastfetch-*.*
linux-s390x:
name: Linux-s390x
runs-on: ubuntu-24.04
permissions:
security-events: write
contents: read
steps:
- name: checkout repository
uses: actions/checkout@v5
- name: run VM
uses: uraimo/run-on-arch-action@v3
id: runcmd
with:
arch: s390x
distro: ubuntu20.04
githubToken: ${{ github.token }}
run: |
uname -a
apt-get update && apt-get install -y cmake 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 ocl-icd-opencl-dev libpulse-dev libdrm-dev libchafa-dev libelf-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 --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
ctest --output-on-failure
- name: upload artifacts
uses: actions/upload-artifact@v4
with:
name: fastfetch-linux-s390x
name: fastfetch-linux-${{ matrix.arch }}
path: ./fastfetch-*.*
musl-amd64:
name: Musl-amd64
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: setup alpine linux
uses: jirutka/setup-alpine@master
@@ -386,7 +354,7 @@ jobs:
run: |
cat /etc/alpine-release
uname -a
apk add cmake samurai vulkan-loader-dev libxcb-dev libxrandr-dev rpm-dev wayland-dev libdrm-dev dconf-dev imagemagick-dev chafa-dev zlib-dev dbus-dev mesa-dev opencl-dev xfconf-dev sqlite-dev networkmanager-dev pulseaudio-dev ddcutil-dev elfutils-dev gcc g++
apk add cmake samurai vulkan-loader-dev libxcb-dev libxrandr-dev rpm-dev wayland-dev libdrm-dev dconf-dev imagemagick-dev chafa-dev zlib-dev dbus-dev mesa-dev opencl-dev sqlite-dev networkmanager-dev pulseaudio-dev ddcutil-dev elfutils-dev gcc g++
shell: alpine.sh --root {0}
- name: build
@@ -406,20 +374,27 @@ jobs:
shell: alpine.sh {0}
- name: upload artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: fastfetch-musl-amd64
path: ./fastfetch-*.*
macos-amd64:
name: macOS-amd64
runs-on: macos-13
macos-hosts:
name: macOS-${{ matrix.arch }}
runs-on: ${{ matrix.runs-on }}
permissions:
security-events: write
contents: read
strategy:
matrix:
include:
- arch: amd64
runs-on: macos-15-intel
- arch: aarch64
runs-on: macos-latest
steps:
- name: checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: uname -a
run: uname -a
@@ -453,89 +428,80 @@ jobs:
run: ctest --output-on-failure
- name: upload artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: fastfetch-macos-amd64
name: fastfetch-macos-${{ matrix.arch }}
path: ./fastfetch-*.*
macos-aarch64:
name: macOS-aarch64
runs-on: macos-latest
permissions:
security-events: write
contents: read
steps:
- name: checkout repository
uses: actions/checkout@v5
- name: uname -a
run: uname -a
- name: install required packages
run: |
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install --overwrite vulkan-loader vulkan-headers molten-vk imagemagick chafa
- name: configure project
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
- name: build project
run: cmake --build . --target package --verbose -j4
- name: list features
run: ./fastfetch --list-features
- name: run fastfetch
run: time ./fastfetch -c presets/ci.jsonc --stat false
- name: run fastfetch --format json
run: time ./fastfetch -c presets/ci.jsonc --format json
- name: run flashfetch
run: time ./flashfetch
- name: print dependencies
run: otool -L fastfetch
- name: run tests
run: ctest --output-on-failure
- name: upload artifacts
uses: actions/upload-artifact@v4
with:
name: fastfetch-macos-aarch64
path: ./fastfetch-*.*
sunos-amd64:
omnios-amd64:
runs-on: ubuntu-latest
name: SunOS-amd64
name: OmniOS-amd64
steps:
- name: checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: run VM
uses: vmactions/omnios-vm@v1
with:
usesh: true
envs: 'CMAKE_BUILD_TYPE'
prepare: |
uname -a
pkg update --accept
pkg install gcc13 cmake git pkg-config glib2 dbus sqlite-3 imagemagick
pkg install gcc14 cmake git pkg-config glib2 dbus sqlite-3 imagemagick ninja
run: |
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
cmake --build . --target package --verbose -j4
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -GNinja .
cmake --build . --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
ctest --output-on-failure
cpack
echo 'set(CPACK_PACKAGE_FILE_NAME "fastfetch-omnios-amd64")' >> CPackConfig.cmake
cpack -V
- name: upload artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: fastfetch-sunos-amd64
name: fastfetch-omnios-amd64
path: ./fastfetch-*.*
solaris-amd64:
runs-on: ubuntu-latest
name: Solaris-amd64
steps:
- name: checkout repository
uses: actions/checkout@v6
- name: run VM
uses: vmactions/solaris-vm@v1
with:
usesh: true
envs: 'CMAKE_BUILD_TYPE'
release: "11.4-gcc-14"
prepare: |
uname -a
pkg install cmake git pkg-config glib2 dbus sqlite-3 imagemagick ninja dconf mesa
run: |
export PKG_CONFIG_PATH=/usr/lib/64/pkgconfig
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -GNinja .
cmake --build . --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
ctest --output-on-failure
echo 'set(CPACK_PACKAGE_FILE_NAME "fastfetch-solaris-amd64")' >> CPackConfig.cmake
cpack -V
- name: upload artifacts
uses: actions/upload-artifact@v7
with:
name: fastfetch-solaris-amd64
path: ./fastfetch-*.*
freebsd-amd64:
@@ -546,7 +512,7 @@ jobs:
contents: read
steps:
- name: checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: run VM
uses: cross-platform-actions/action@master
@@ -555,11 +521,12 @@ jobs:
architecture: x86-64
cpu_count: 4
shell: bash
version: '14.3'
version: '15.0'
environment_variables: 'CMAKE_BUILD_TYPE'
run: |
uname -a
sudo pkg update
sudo pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl xfce4-conf egl opencl ocl-icd v4l_compat chafa
sudo pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl egl opencl ocl-icd v4l_compat chafa
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
@@ -570,7 +537,7 @@ jobs:
ctest --output-on-failure
- name: upload artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: fastfetch-freebsd-amd64
path: ./fastfetch-*.*
@@ -583,7 +550,7 @@ jobs:
contents: read
steps:
- name: checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: run VM
uses: cross-platform-actions/action@master
@@ -592,11 +559,13 @@ jobs:
architecture: x86-64
cpu_count: 4
shell: bash
version: '7.7'
version: '7.8'
environment_variables: 'CMAKE_BUILD_TYPE'
run: |
uname -a
sudo pkg_add -r cmake git pkgconf wayland vulkan-headers vulkan-loader glib2 dconf dbus sqlite3 xfconf imagemagick chafa
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
sudo pkg_add -u
sudo pkg_add -r llvm-21.1.2p0 cmake git pkgconf wayland vulkan-headers vulkan-loader glib2 dconf dbus sqlite3 imagemagick chafa
CC=clang-21 cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
@@ -606,7 +575,7 @@ jobs:
ctest --output-on-failure
- name: upload artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: fastfetch-openbsd-amd64
path: ./fastfetch-*.*
@@ -619,7 +588,7 @@ jobs:
contents: read
steps:
- name: checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: run VM
uses: cross-platform-actions/action@master
@@ -629,10 +598,11 @@ jobs:
cpu_count: 4
shell: bash
version: '10.1'
environment_variables: 'CMAKE_BUILD_TYPE'
run: |
uname -a
sudo pkgin -y install cmake git pkgconf wayland vulkan-headers dconf dbus sqlite3 ImageMagick
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
sudo pkgin -y install clang cmake git pkgconf wayland vulkan-headers dconf dbus sqlite3 ImageMagick
CC=clang cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
@@ -642,7 +612,7 @@ jobs:
ctest --output-on-failure
- name: upload artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: fastfetch-netbsd-amd64
path: ./fastfetch-*.*
@@ -650,25 +620,25 @@ jobs:
dragonfly-amd64:
name: DragonFly-amd64
runs-on: ubuntu-latest
if: false
permissions:
security-events: write
contents: read
steps:
- name: checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: run VM
uses: vmactions/dragonflybsd-vm@v1
with:
usesh: yes
envs: 'CMAKE_BUILD_TYPE'
prepare: |
uname -a
pkg update
pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl xfce4-conf egl opencl ocl-icd v4l_compat chafa libelf
pkg install -y llvm cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl egl opencl ocl-icd v4l_compat chafa libelf
run: |
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
env CC=clang cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
@@ -678,7 +648,7 @@ jobs:
ctest --output-on-failure
- name: upload artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: fastfetch-dragonfly-amd64
path: ./fastfetch-*.*
@@ -691,7 +661,7 @@ jobs:
contents: read
steps:
- name: checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: run VM
uses: cross-platform-actions/action@master
@@ -701,6 +671,7 @@ jobs:
architecture: x86-64
cpu_count: 4
shell: bash
environment_variables: 'CMAKE_BUILD_TYPE'
run: |
uname -a
pkgman install -y git dbus_devel mesa_devel libelf_devel imagemagick_devel opencl_headers ocl_icd_devel vulkan_devel zlib_devel chafa_devel cmake gcc make pkgconfig python3.10 || pkgman install -y git dbus_devel mesa_devel libelf_devel imagemagick_devel opencl_headers ocl_icd_devel vulkan_devel zlib_devel chafa_devel cmake gcc make pkgconfig python3.10
@@ -713,42 +684,66 @@ jobs:
ctest --output-on-failure
- name: upload artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: fastfetch-haiku-amd64
path: ./fastfetch-*.*
windows-amd64:
name: Windows-amd64
runs-on: windows-latest
windows-hosts:
name: Windows-${{ matrix.arch }}${{ matrix.win7-compat-postfix }}
runs-on: ${{ matrix.runs-on }}
permissions:
security-events: write
contents: read
strategy:
matrix:
include:
- arch: amd64
runs-on: windows-latest
msystem: CLANG64
msystem-lower: clang64
msys-arch: x86_64
win7-compat-flag: OFF
win7-compat-postfix: ""
- arch: amd64
runs-on: windows-latest
msystem: CLANG64
msystem-lower: clang64
msys-arch: x86_64
win7-compat-flag: ON
win7-compat-postfix: "-win7"
- arch: aarch64
runs-on: windows-11-arm
msystem: CLANGARM64
msystem-lower: clangarm64
msys-arch: aarch64
win7-compat-flag: OFF
win7-compat-postfix: ""
defaults:
run:
shell: msys2 {0}
steps:
- name: checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: setup-msys2
uses: msys2/setup-msys2@v2
with:
msystem: CLANG64
msystem: ${{ matrix.msystem }}
update: true
install: git mingw-w64-clang-x86_64-7zip mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-vulkan-headers mingw-w64-clang-x86_64-opencl-icd mingw-w64-clang-x86_64-opencl-headers mingw-w64-clang-x86_64-cppwinrt mingw-w64-clang-x86_64-imagemagick
install: git mingw-w64-clang-${{ matrix.msys-arch }}-7zip mingw-w64-clang-${{ matrix.msys-arch }}-cmake mingw-w64-clang-${{ matrix.msys-arch }}-clang mingw-w64-clang-${{ matrix.msys-arch }}-vulkan-loader mingw-w64-clang-${{ matrix.msys-arch }}-vulkan-headers mingw-w64-clang-${{ matrix.msys-arch }}-opencl-icd mingw-w64-clang-${{ matrix.msys-arch }}-opencl-headers mingw-w64-clang-${{ matrix.msys-arch }}-cppwinrt mingw-w64-clang-${{ matrix.msys-arch }}-imagemagick mingw-w64-clang-${{ matrix.msys-arch }}-chafa
- name: print msys version
run: uname -a
- name: configure project
run: env PKG_CONFIG_PATH=/clang64/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
run: env PKG_CONFIG_PATH=/${{ matrix.msystem-lower }}/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_WIN7_COMPAT=${{ matrix.win7-compat-flag }} .
- name: build project
run: cmake --build . --verbose -j4
- name: copy necessary dlls
run: cp /clang64/bin/{OpenCL,vulkan-1}.dll .
run: cp /${{ matrix.msystem-lower }}/bin/{OpenCL,vulkan-1}.dll .
- name: list features
run: ./fastfetch --list-features
@@ -768,102 +763,62 @@ jobs:
- name: run tests
run: ctest --output-on-failure
- name: create zip archive
run: 7z a -tzip -mx9 -bd -y fastfetch-windows-amd64.zip LICENSE *.dll fastfetch.exe flashfetch.exe presets
- name: create 7z archive
run: 7z a -t7z -mx9 -bd -y fastfetch-windows-amd64.7z LICENSE *.dll fastfetch.exe flashfetch.exe presets
- name: upload artifacts
uses: actions/upload-artifact@v4
- if: github.event_name == 'push' && github.repository == 'fastfetch-cli/fastfetch'
id: upload-unsigned-artifact
name: upload artifacts for signing
uses: actions/upload-artifact@v7
with:
name: fastfetch-windows-amd64
path: ./fastfetch-windows-amd64.*
name: fastfetch-windows-${{ matrix.arch }}${{ matrix.win7-compat-postfix }}
path: |
*.dll
fastfetch.exe
flashfetch.exe
windows-aarch64:
name: Windows-aarch64
runs-on: windows-11-arm
permissions:
security-events: write
contents: read
defaults:
run:
shell: msys2 {0}
steps:
- name: checkout repository
uses: actions/checkout@v5
- name: setup-msys2
uses: msys2/setup-msys2@v2
- if: github.event_name == 'push' && github.repository == 'fastfetch-cli/fastfetch'
name: submit signing request
uses: signpath/github-action-submit-signing-request@v1
with:
msystem: CLANGARM64
update: true
install: git mingw-w64-clang-aarch64-7zip mingw-w64-clang-aarch64-cmake mingw-w64-clang-aarch64-clang mingw-w64-clang-aarch64-vulkan-loader mingw-w64-clang-aarch64-vulkan-headers mingw-w64-clang-aarch64-opencl-icd mingw-w64-clang-aarch64-opencl-headers mingw-w64-clang-aarch64-cppwinrt mingw-w64-clang-aarch64-imagemagick
- name: print msys version
run: uname -a
- name: configure project
run: env PKG_CONFIG_PATH=/clangarm64/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
- name: build project
run: cmake --build . --verbose -j4
- name: copy necessary dlls
run: cp /clangarm64/bin/{OpenCL,vulkan-1}.dll .
- name: list features
run: ./fastfetch --list-features
- name: run fastfetch
run: time ./fastfetch -c presets/ci.jsonc --stat false
- name: run fastfetch --format json
run: time ./fastfetch -c presets/ci.jsonc --format json
- name: run flashfetch
run: time ./flashfetch
- name: print dependencies
run: ldd fastfetch
- name: run tests
run: ctest --output-on-failure
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
organization-id: '${{ vars.SIGNPATH_ORG_ID }}'
project-slug: 'fastfetch'
signing-policy-slug: ${{ github.ref == 'refs/heads/master' && 'release-signing' || 'test-signing' }}
github-artifact-id: '${{ steps.upload-unsigned-artifact.outputs.artifact-id }}'
wait-for-completion: true
output-artifact-directory: '.'
- name: create zip archive
run: 7z a -tzip -mx9 -bd -y fastfetch-windows-aarch64.zip LICENSE *.dll fastfetch.exe flashfetch.exe presets
run: 7z a -tzip -mx9 -bd -y fastfetch-windows-${{ matrix.arch }}${{ matrix.win7-compat-postfix }}.zip LICENSE *.dll fastfetch.exe flashfetch.exe presets
- name: create 7z archive
run: 7z a -t7z -mx9 -bd -y fastfetch-windows-aarch64.7z LICENSE *.dll fastfetch.exe flashfetch.exe presets
run: 7z a -t7z -mx9 -bd -y fastfetch-windows-${{ matrix.arch }}${{ matrix.win7-compat-postfix }}.7z LICENSE *.dll fastfetch.exe flashfetch.exe presets
- name: upload artifacts
uses: actions/upload-artifact@v4
- name: upload true artifacts
uses: actions/upload-artifact@v7
with:
name: fastfetch-windows-aarch64
path: ./fastfetch-windows-aarch64.*
name: fastfetch-windows-${{ matrix.arch }}${{ matrix.win7-compat-postfix }}
path: ./fastfetch-windows-${{ matrix.arch }}${{ matrix.win7-compat-postfix }}.*
overwrite: true
release:
if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'fastfetch-cli/fastfetch'
name: Release
runs-on: ubuntu-latest
needs:
- linux-amd64
- linux-aarch64
- linux-hosts
- linux-i686
- linux-armv7l
- linux-armv6l
- linux-riscv64
- linux-ppc64le
- linux-s390x
- linux-vms
- musl-amd64
- macos-amd64
- macos-aarch64
- macos-hosts
- freebsd-amd64
- openbsd-amd64
- netbsd-amd64
- sunos-amd64
- dragonfly-amd64
- solaris-amd64
- omnios-amd64
- haiku-amd64
- windows-amd64
- windows-aarch64
- windows-hosts
permissions:
contents: write
steps:
@@ -874,29 +829,29 @@ jobs:
repository: ${{ github.repository }}
- name: download artifacts
if: needs.linux-amd64.outputs.ffversion != steps.get_version_release.outputs.release
uses: actions/download-artifact@v4
if: needs.linux-hosts.outputs.ffversion != steps.get_version_release.outputs.release
uses: actions/download-artifact@v8
- name: create release
if: needs.linux-amd64.outputs.ffversion != steps.get_version_release.outputs.release
if: needs.linux-hosts.outputs.ffversion != steps.get_version_release.outputs.release
uses: ncipollo/release-action@v1
with:
tag: ${{ needs.linux-amd64.outputs.ffversion }}
tag: ${{ needs.linux-hosts.outputs.ffversion }}
commit: ${{ github.sha }}
artifactErrorsFailBuild: true
artifacts: fastfetch-*/fastfetch-*
body: "Please refer to [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/${{ needs.linux-amd64.outputs.ffversion }}/CHANGELOG.md) for details."
body: "Please refer to [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/${{ needs.linux-hosts.outputs.ffversion }}/CHANGELOG.md) for details."
- name: download source tarballs
if: needs.linux-amd64.outputs.ffversion != steps.get_version_release.outputs.release
if: needs.linux-hosts.outputs.ffversion != steps.get_version_release.outputs.release
run: |
for i in 1 2 3 4 5; do curl -L --remote-name-all --output-dir fastfetch-source --create-dirs https://github.com/${{ github.repository }}/archive/refs/tags/${{ needs.linux-amd64.outputs.ffversion }}.{tar.gz,zip} && break || sleep 5; done
for i in 1 2 3 4 5; do curl -L --remote-name-all --output-dir fastfetch-source --create-dirs https://github.com/${{ github.repository }}/archive/refs/tags/${{ needs.linux-hosts.outputs.ffversion }}.{tar.gz,zip} && break || sleep 5; done
ls fastfetch-*/*
- name: generate release notes
if: needs.linux-amd64.outputs.ffversion != steps.get_version_release.outputs.release
if: needs.linux-hosts.outputs.ffversion != steps.get_version_release.outputs.release
run: |
echo "Please refer to [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/${{ needs.linux-amd64.outputs.ffversion }}/CHANGELOG.md) for details." > fastfetch-release-notes.md
echo "Please refer to [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/${{ needs.linux-hosts.outputs.ffversion }}/CHANGELOG.md) for details." > fastfetch-release-notes.md
echo -e "\n---\n\n<details><summary>SHA256SUMs</summary><br>\n\n\`\`\`" >> fastfetch-release-notes.md
sha256sum fastfetch-*/* >> fastfetch-release-notes.md
echo -e "\`\`\`\n</details>" >> fastfetch-release-notes.md
@@ -905,10 +860,10 @@ jobs:
echo -e "\`\`\`\n</details>" >> fastfetch-release-notes.md
- name: update release body
if: needs.linux-amd64.outputs.ffversion != steps.get_version_release.outputs.release
if: needs.linux-hosts.outputs.ffversion != steps.get_version_release.outputs.release
uses: ncipollo/release-action@v1
with:
tag: ${{ needs.linux-amd64.outputs.ffversion }}
tag: ${{ needs.linux-hosts.outputs.ffversion }}
commit: ${{ github.sha }}
bodyFile: fastfetch-release-notes.md
allowUpdates: true
+407
View File
@@ -1,3 +1,410 @@
# 2.60.0
Changes:
* The CMake option `ENABLE_WIN7_COMPAT:BOOLEAN` now defaults to `OFF` and will be removed in v2.61.0, effectively dropping support for Windows 7 in the next release.
* This follows the Windows 7 deprecation notice introduced in v2.57.0.
* `wm.detectPlugin` now defaults to `true` (WM)
Features:
* Adds `{cwd}` for custom title formatting, which displays the current working directory (Title)
* Adds support for detecting the Zed version (#2200, Editor)
* Adds support for detecting `moss` packages (Packages, Linux)
* Adds support for detecting komorebi, FancyWM, and GlazeWM (WM, Windows)
* Adds support for WM plugin version detection on macOS (WM, macOS)
* Adds support for retrieving the executable path on OpenBSD (#2195, OpenBSD)
Bugfixes:
* Fixes a potential segmentation fault caused by dereferencing a negative index (#2198)
* Fixes `tempSensor` parsing so that it accepts only string values (#2202, CPU)
* Fixes an issue that unexpectedly caused fewer devices to be reported (Keyboard, Linux)
* Improves WM detection on LXQt by querying WM settings only when no WM has already been detected (#2199, WM, Linux)
* Fixes memory leaks in DBus connection handling and in the OpenGL EGL context lifecycle
* Fixes niri version detection on Fedora (WM, Linux)
* Includes various internal cleanups and optimizations
Logos:
* Adds `RengeOS` (#2170)
* Adds `Emmabuntüs` (#2207)
* Updates Artix Linux (#2157)
* Updates Linux Mint (#2186)
* Renames `Refracted Devuan` to `Refracta`
* Renames `ExodiaPredator` to `ExodiaOS`
# 2.59.0
Changes:
* Fastfetch no longer relies on the unreliable environment variables `$USER` or `%USERPROFILE%` to determine the current username (Title)
* People who set `$USER` to customize the Fastfetch title should use `{ "type": "title", "format": "your-custom-user-name" }` to achieve the same result.
* Fastfetch no longer tries to probe inaccessible remote disk drives on Windows (Disk, Windows)
* People who have remote drives may use `{ "type": "disk", "hideFolders": "X:\\" }` to ignore problematic ones.
* This change removes some ugly hacks from the codebase and matches the behavior on `*nix`.
Features:
* Adds Oracle Solaris support (#2176, SunOS)
* Adds UID / SID detection (Title)
* In custom format: `{user-id}`
* Switches to native GPU detection on GNU/Hurd and removes the `libpciaccess` dependency (GPU, Hurd)
* Improves memory size detection on macOS (Memory, macOS)
* Avoids relying on `hw.memsize_usable` by default, which may not be available on older macOS versions
* Improves Windows disk detection accuracy and performance (Disk, Windows)
* Adds more ARM CPU parts and removes duplicated cases (CPU, ARM)
Logos:
* Adds 6-color support to the NixOS logo (including the small variant) (#2180)
# 2.58.0
An early release to fix compatibility issues with KDE Plasma 6.6.
Breaking changes:
* The `de.slowVersionDetection` option has been removed. Slow version detection is now always enabled, as required on non-FHS-compliant distros (e.g., NixOS). (#2149, DE, Linux)
Features:
* Adds the `--structure-disabled <modules...>` command-line flag to temporarily disable module structure printing.
* For example: `fastfetch --structure-disabled colors` removes the color blocks from the default output.
* Supports chassis type detection on Linux ARM devices when reported via the device tree (Chassis, Linux)
* Supports Bedrock Linux version detection (#2155, OS, Linux)
* Honors the `DBPath` and `RootDir` settings in `pacman.conf` when detecting Pacman packages (#2154, Packages, Linux)
Bugfixes:
* Fixes a crash issue on KDE Plasma 6.6 (Display, Linux)
* Fixes the Command module not working with `--dynamic-interval` (#2152, Command)
* Fixes Quartz Compositor version detection. It now correctly reports the version of `WindowServer` (`SkyLight`) instead of `WindowManager`. (WM, macOS)
Logos:
* Adds Kiss2
# 2.57.1
Features:
* Tiny performance improvements (Windows)
* Improves the reliability of hostname retrieval (Title, Windows)
Bugfixes:
* Fixes potential compilation issues on Linux (#2142, Linux)
* Fixes compilation errors on macOS when building with older SDKs (#2140, macOS)
* Fixes compilation issues when building with `-DENABLE_SYSTEM_YYJSON=ON` (#2143)
Logos:
* Updates PrismLinux and adds a small variant
# 2.57.0
Deprecation notice:
* Support for Windows 7 (and 8.x) is deprecated and will be removed in a future release. Extended support for Windows 7 (and 8.1) ended on January 10, 2023. These versions do not officially support ANSI escape codes (running fastfetch on them requires a third-party terminal such as ConEmu). In addition, Windows 7 lacks some APIs used by fastfetch. Fastfetch currently loads these APIs dynamically at runtime to maintain compatibility, but this adds complexity to the codebase and increases the maintenance burden.
* A CMake flag `ENABLE_WIN7_COMPAT:BOOLEAN` has been introduced (defaults to `ON` for now). If set to `OFF`, Windows 7 compatibility code is excluded, and the resulting binaries will support only Windows 10 (version 1607 and later) and Windows 11.
* The main prebuilt Windows binaries on the Release page (`fastfetch-windows-amd64.*`) are built with `ENABLE_WIN7_COMPAT=OFF`. These are the binaries used by `scoop` and `winget`. Users who need Windows 7 (or 8.x) support can download the `-win7` variant instead.
* ~~The `ENABLE_WIN7_COMPAT` CMake option and the `-win7` variant binaries are planned to be removed in 2.60.0~~.
Features:
* Supports COSMIC DE version detection (DE, Linux)
* Supports niri version detection (#2121, WM, Linux)
* Supports cosmic-term version and terminal font detection (Terminal / TerminalFont, Linux)
* Supports urxvt font detection (TerminalFont, Linux) (#2105)
* Improves xterm font detection by checking `xterm.vt100.faceName` (TerminalFont, Linux)
* Supports Secure Boot detection (Bootmgr, macOS)
* Supports DPI scale factor detection on Windows 7 (Display, Windows)
* Supports xterm 256-color codes in color configuration
* In `display.color`: "`@<color-index>`" (e.g., "`@34`" for color index `34`)
* In `*.format` strings: "`#@<color-index>`" (e.g., "`#@34`" for color index `34`)
* Improves uptime accuracy on Windows 10+ (Uptime, Windows)
* Adds a new module `Logo` to query built-in logo raw data in JSON output (Logo)
* Usage: `fastfetch -s logo -l <logo-name> -j # Supported in JSON format only`
* Supports shell version detection even if the binary has been deleted (#2136, Shell, Linux)
* Overall code refinements and optimizations
Bugfixes:
* Skips local / loopback routes when detecting network interfaces (LocalIP, Linux) (#2127)
* Fixes CPU speed detection on s390x (CPU, Linux) (#2129)
* Fixes GPU detection error handling and supports case-insensitive PCI ID parsing (GPU, Windows)
* Fixes some networking issues and memory leaks (Networking)
* Fixes `exePath` reporting relative paths on macOS (Shell, macOS)
Logos:
* Adds openSUSE Tumbleweed braille logo
* Adds Xinux
* Renames HydraPWK to NetHydra
* Fixes colors of deepin and UOS
* Fixes colors of macOS and variants
# 2.56.1
Features:
* Improves compatibility with KDE Plasma 6.5 (#2093, Display)
* Adds a `tempSensor` option to specify the sensor name used for CPU temperature detection (CPU)
* Example: `{ "type": "cpu", "tempSensor": "hwmon0" /* Use /sys/class/hwmon/hwmon0 for temperature detection */ }`
* Refines Memory usage detection on macOS to match Activity Monitor more closely (Memory, macOS)
* Minor optimizations
Bugfixes:
* Fixes cache line size detection (CPU, macOS)
Logos:
* Removes Opak
* Updates GXDE
# 2.56.0
Features:
* Enhances config file loading. `--config` and `-c` with relative path now also searches paths defined in `fastfetch --list-config-paths` (typically `~/.config/fastfetch/`)
* This allows users to use `fastfetch -c my-config` without needing to specify the full path.
* Adds NUMA node count detection (CPU)
* Exposed via `{numa-nodes}` in custom format
* Supported on Linux, FreeBSD and Windows
* Supports the newest Alacritty config format (#2070, TerminalFont)
* Detects driver specific info for Zhaoxin GPUs (GPU, Linux)
* Detects Android OEM UI for certain OSes (DE, Android)
* Improves users detection on Linux (#2064, Users, Linux)
* Adds systemd fallback when utmp is unavailable
* Fixes resource leaks
* Always reports the newest session info
* Adds kiss package manager support (#2072, Packages, Linux)
* Reports `sshd` if `$SSH_TTY` is not available (Terminal)
* Zpool module rewrite (#2051, Zpool)
* Adds new Zpool properties: allocated, guid, readOnly
* Zpool module now uses runtime lookup for properties to ensure portability
* Adds NetBSD (requires `sudo`) and macOS support
* Adds `splitLines` option for Command module, which splits the output into sub modules, each containing one line of the output (Command)
```
* Command output:
Line 1
Line 2
Line 3
* Old behavior:
Command: Line 1
Line 2
Line 3
* With `"splitLines": true`:
Command 1: Line 1
Command 2: Line 2
Command 3: Line 3
```
Bugfixes:
* Fixes {m,o}ksh version detection on Linux (Shell)
* Fixes Alacritty config parsing for TOML format (#2070, TerminalFont)
* Improves builtin logo printing for piping and buffering (#2065, Logo)
* Uses absolute path when detecting shell and terminal version if available (#2067, TerminalShell)
Logos:
* Updates Codex Linux logo (#2071)
* Adds OS/2 Warp logo (#2062)
* Adds Amiga logo (#2061)
# 2.55.1
Bugfixes:
* Fix parallel command execution breaks randomly (#2056 / #2058, Command)
* Regression from v2.55.0
* Fix `dylib` searching path on macOS (macOS)
* Regression from v2.55.0
* Fix an uninitialized field (#2057, Display)
# 2.55.0
Changes:
* Commands are now executed in parallel by default to improve performance (#2045, Command)
* This behavior can be disabled in the config file with `"parallel": false` if it causes problems with certain scripts
* Folder/filesystem hiding is moved to the detection stage; hidden entries are no longer probed, improving performance (#2043, Disk)
Features:
* Adds `command.parallel` and `command.useStdErr` config options (Command)
* `parallel`: set to `false` to disable parallel execution (see Changes above)
* `useStdErr`: set to `true` to use stderr output instead of stdout
* Adds the command-line flag `--dynamic-interval <interval-in-ms>` to enable dynamic output auto-refresh (#2041)
* Due to internal limitations, some modules do not support dynamic updates (notably Display and Media)
* Adds support for using the current playing media's cover art as a logo source (Media / Logo)
* Usage: `"logo": { "type": "<image-protocol>", "source": "media-cover" }` in JSON config; or `--<image-protocol> media-cover` in command line
* Supports local sources only
* Adds native GPU detection support on OpenBSD and NetBSD (instead of depending on `libpciaccess`) (GPU)
* No functional changes
* Root privileges are required to access PCI config space on OpenBSD (as always)
* Adds GPU detection support on GNU/Hurd (GPU)
* Requires building with `libpciaccess`
* Shows Debian point release on Raspberry Pi OS (#2032, OS, Linux)
* Adds `Brush` shell version detection (Shell)
* Improves Mac family detection via prefix matching (Host)
Bugfixes:
* Ignores `run-parts` during terminal/shell detection (#2048, Terminal / Shell, Linux)
* Fixes fish version detection when `LC_ALL` is set (#2014, Shell, Linux)
* Hides the module when no desktop icons are found (#2023, Icons, Windows)
* Skips auxiliary display controllers to prevent the module from reporting duplicate entries (#2034, GPU, Linux)
* Refines Apple rpath handling; fixes building for the Homebrew version on macOS (#1998, CMake)
Logos:
* Adds Vincent OS and MacaroniOS
# 2.54.0
Windows binaries in Release page are now signed by SignPath.
Changes:
* Moves macOS and Windows design language detection from the DE module to the Theme module
Features:
* Adds `--json` and `-j` command line flags as a shortcut for `--format json`
* Various improvements to the OS module (OS)
* Displays point releases for Debian
* Displays code names for Ubuntu
* Displays build ID for macOS
* Displays code names for Windows (previously shown in the Kernel module)
* Adds basic support for Wine (Windows)
* Adds basic support for hppa and sh architectures (CPU, Linux)
* Improves T-Head SoC name detection from the device tree (#1997, CPU, Linux)
* Supports glob patterns in `Disk.hideFolders` (Disk)
* For example, `/boot/*` will match both `/boot/efi` and `/boot/firmware`
* Adds brightness-level detection for external monitor support on Intel macOS (Brightness, macOS)
* Adds configurable spacing between icon and text in keys
* `display.key.type: "both-N"` where N is `0-4`
* Useful for non-monospaced Nerd Fonts
* Adds detection support for modern Samsung Exynos SoCs (CPU, Android)
* Adds a new CMake option `-DENABLE_WORDEXP=<ON|OFF>` to enable or disable using `wordexp(3)` for acquiring logo file paths (`logo.source`)
* Enabled by default for compatibility
* Disabling this option reverts to using `glob(3)`, which is less functional but more secure
Bugfixes:
* Avoids integer overflow when calculating swap size (#1988, Swap, Windows)
* Trims whitespace from full user name (Title, macOS)
* Fixes default font size for Ghostty (#1986, TerminalFont, Linux)
* Works around an issue that could report impossibly high memory usage in rare cases (#1988, Memory, Linux)
* Fixes incorrect glibc dependency in polyfilled DEB packages (#1983, Linux)
* Fixes corrupted binaries in polyfilled RPM packages (#1990, Linux)
* Fixes crashes on ancient Android kernels (#1993, Disk, Android)
* Fixes incorrect usage of `glob(3)` (OpenBSD)
* Prefers resolutions reported by RandR mode info, fixing incorrect resolutions on XFCE when DPI scaling is enabled (Display, Linux)
* Various code cleanups and minor fixes
Logos:
* Adds secureblue, PrismLinux, EmperorOS and Zraxyl
* Updates T2
# 2.53.0
Changes:
* JSON property `length` in `Separator` module has been renamed to `times` for clarity (Separator)
Features:
* Adds IPv6 type selection (#1459, LocalIP)
* For example: `{ "type": "localip", "showIpv6": "ula" /* Show ULA only */ }`
* Adds more ARM CPU part IDs (CPU, Linux)
* Improves Ghostty font config parsing with fallback font detection (#1967, TerminalFont)
* Replaces statx(2) call with syscall(2) for better compatibility (Disk, Linux)
* Allows array input for disk folder and filesystem options (Disk)
* For example: `{ "type": "disk", "folders": ["/", "/home"] }`
* Adds support for ignoring input devices by name prefix (#1950, Keyboard / Mouse / Gamepad)
* For example: `{ "type": "keyboard", "ignores": ["Apple ", "Corsair "] }`
* Adds support for (B)SSID detection on macOS Tahoe (Wifi, macOS)
* Please don't expect it to work on later macOS versions
* Improves Ubuntu flavor detection (#1975, OS, Linux)
* Refines ARMv8.4-A detection to require LSE2 (CPU, Windows)
* Detects the latest Dimensity & Snapdragon SoC names (CPU, Android)
Bugfixes:
* Handles zero temperature data (#1960, CPU, Windows)
* Fixes `dlopen libzfs.so failed` error on Proxmox 9 (#1973, Zpool, Linux)
Logos:
* Removes Starry Linux
* Adds TempleOS
* Updates ObsidianOS
# 2.52.0
Changes:
* New optional build dependencies on Android
* main: chafa dbus glib imagemagick libelf libxcb libxrandr pulseaudio zlib
* x11: dconf (Optional)
* Dependency on `libxfconf` is removed. XFCE related detection now uses `libdbus` instead (Linux)
* The default format of `Display` module is updated to `{width}x{height} @ {scale-factor}x in {inch}", {refresh-rate} Hz`
* Replaced scaled resolution with scale factor for shorter texts and avoiding potential confusion.
Bugfixes:
* Fixes linking on 32-bit Android (#1939)
* Skips network interfaces without IPs unless MAC address is requested (#1949, LocalIP)
* Fixes unexpected padding when setting `logo.width` with chafa logos (#1947, Logo)
* Regression from v2.51.0
* Improves Wallpaper detection on XFCE4 (Wallpaper, Linux)
* Ignores process `Relay(xxx)` when detecting terminal on WSL2 (Terminal, Linux)
Features:
* Enables X11-related info (i.e., WM/DE) detection on Android (Global, Android)
* This requires many dependencies. See above.
* Adds scale factors detection for X11 (Display, Linux)
* X11 doesn't natively report scale factor as Wayland does. Instead, Fastfetch tries to detect `Xft.dpi` (DPI used by X FreeType for scaling fonts), which is usually set by the WM when DPI scaling is enabled.
* It's not always accurate. For example, XFCE4 has a separate config for text scaling, which is unaffected by the global DPI scaling setting.
* Adds `display.fraction.trailingZeros: [always|never]` option for fraction formatting
* The default value of `display.fraction.ndigits` is changed from `-1` (unlimited) to `2` for usability.
* Used for displaying scale factor in Display module mentioned above, alongside other places for printing raw fraction numbers.
* Informs users that module-specific CLI options are no longer supported and provide guidance for transitioning to JSON config
* Adds CPU name detection support for IA64 (CPU, Linux)
* Support Btrfs allocation profile detection (#1941, Btrfs, Linux)
# 2.51.1
Bugfixes:
* Fix building on macOS 14 or older; no functional changes (CPU, macOS)
# 2.51.0
Changes:
* Fastfetch now requires [yyjson 0.12](https://github.com/ibireme/yyjson/releases/tag/0.12.0) to build when using `-DENABLE_SYSTEM_YYJSON=ON`.
* The Disk module no longer shows hyperlink mountpoints by default, which cause issues on some real consoles (Disk)
* Instead, the custom key for the Disk module now supports `{mountpoint-link}` and `{name-link}` to show hyperlinks for mountpoints and names. For example, `{ "type": "disk", "key": "Disk ({mountpoint-link})" }` can be used to restore the old behavior.
Features:
* Adds `succeeded` module condition to JSONC config. When set to `false`, the module will only run if the last module failed (#1908)
* Useful for displaying fallback placeholders when a module fails. For example:
```jsonc
{
"host",
// If fastfetch fails to detect host info, display "DIY PC" instead
{
"type": "custom",
"condition": {
"succeeded": false
},
"key": "Host",
"format": "DIY PC"
}
}
```
* By upgrading to yyjson 0.12, fastfetch now adds [JSON5](https://json5.org/) format support for configuration files (#1907)
* [JSON5](https://json5.org/) is a superset of JSONC that allows unquoted keys, single quotes, multi-line strings, etc., and is fully compatible with JSONC and strict JSON.
* To use JSON5, simply name your config file with a `.json5` extension. The `.jsonc` extension is still supported and used as the default extension for better IDE syntax highlighting support.
* Fastfetch has been ported to [`GNU/Hurd`](https://www.gnu.org/software/hurd/) (#1895)
* Thanks to the efforts of @yelninei!
* Built-in logos now honor `logo.width` (#1905)
* When its value is larger than the actual logo width, the logo will be padded with spaces to the right
* Adds Trinity DE version detection (#1917, DE, Linux)
* Adds formatted free and available disk size fields (#1929, Disk)
* `{size-free}`: free size of the disk
* `{size-available}`: available size of the disk
* See [askubuntu.com](https://askubuntu.com/questions/249387/df-h-used-space-avail-free-space-is-less-than-the-total-size-of-home) for the difference between free and available size
* Adds [x86_64 micro-architecture level](https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels) detection (#1928, CPU)
* Useful when installing software that requires or is optimized for specific CPU features. E.g., [CachyOS](https://wiki.cachyos.org/features/optimized_repos/)
* Exposed via `{march}` in custom format
* Adds [Aarch64 micro-architecture level](https://en.wikipedia.org/wiki/AArch64#Profiles) detection (CPU)
* Supported on Linux (including Android), macOS and Windows
* This is not fully accurate because there are many optional features across different levels, and not all levels are detectable.
* Exposed via `{march}` in custom format.
* Adds shepherd detection support (InitSystem, Linux)
Bugfixes:
* Refines GPU detection logic to correctly handle virtual devices (#1920, GPU, Windows)
* Fixes possible default route detection failure when the route table is very large (#1919, LocalIP, Linux)
* Fastfetch now correctly parses `hwdata/pci.ids` files alongside `pciids/pci.ids` on FreeBSD when detecting GPU names (#1924, GPU, FreeBSD)
* Fixes twin WM detection (#1917, WM, Linux)
* Various fixes for Android support
* Corrects WM name for Android (WM, Android)
* Fixes battery temperature detection when running in ADB (Battery, Android)
* Adds CPU and GPU temperature detection support (CPU, Android)
Logos:
* Adds AerynOS
# 2.50.2
Bugfixes:
+375 -226
View File
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
project(fastfetch
VERSION 2.50.2
VERSION 2.60.0
LANGUAGES C
DESCRIPTION "Fast neofetch-like system information tool"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
@@ -9,6 +9,17 @@ project(fastfetch
set(PROJECT_LICENSE "MIT license")
if(DEFINED CMAKE_SYSTEM_PROCESSOR_OVERRIDE) # Used by github actions for i686 build
set(CMAKE_SYSTEM_PROCESSOR ${CMAKE_SYSTEM_PROCESSOR_OVERRIDE} CACHE INTERNAL "")
endif()
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" CMAKE_SYSTEM_PROCESSOR)
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
set(CMAKE_SYSTEM_PROCESSOR "amd64")
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
set(CMAKE_SYSTEM_PROCESSOR "aarch64")
endif()
message(STATUS "Build for system processor: ${CMAKE_SYSTEM_PROCESSOR}")
###################
# Target Platform #
###################
@@ -32,6 +43,8 @@ elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "SunOS")
set(SunOS TRUE CACHE BOOL "..." FORCE)
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Haiku")
set(Haiku TRUE CACHE BOOL "..." FORCE)
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "GNU")
set(GNU TRUE CACHE BOOL "..." FORCE)
elseif(NOT APPLE AND NOT WIN32)
message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}")
endif()
@@ -56,34 +69,31 @@ include(CheckIncludeFile)
include(CMakeDependentOption)
cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR FreeBSD OR OpenBSD OR NetBSD OR WIN32 OR ANDROID OR SunOS OR Haiku" OFF)
cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD" OFF)
cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_XRANDR "Enable xrandr" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_DRM "Enable libdrm" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_DRM_AMDGPU "Enable libdrm_amdgpu" ON "LINUX OR FreeBSD" OFF)
cmake_dependent_option(ENABLE_GIO "Enable gio-2.0" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_DCONF "Enable dconf" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_DBUS "Enable dbus-1" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS OR Haiku" OFF)
cmake_dependent_option(ENABLE_XFCONF "Enable libxfconf-0" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_SQLITE3 "Enable sqlite3" ON "LINUX OR FreeBSD OR APPLE OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_RPM "Enable rpm" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR APPLE OR WIN32 OR SunOS OR Haiku" OFF)
cmake_dependent_option(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR APPLE OR SunOS" OFF)
cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR FreeBSD OR OpenBSD OR NetBSD OR WIN32 OR ANDROID OR SunOS OR Haiku OR GNU" OFF)
cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR GNU" OFF)
cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS OR GNU" OFF)
cmake_dependent_option(ENABLE_XRANDR "Enable xrandr" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS OR GNU" OFF)
cmake_dependent_option(ENABLE_DRM "Enable libdrm" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS OR GNU" OFF)
cmake_dependent_option(ENABLE_DRM_AMDGPU "Enable libdrm_amdgpu" ON "LINUX OR FreeBSD OR GNU" OFF)
cmake_dependent_option(ENABLE_GIO "Enable gio-2.0" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS OR GNU" OFF)
cmake_dependent_option(ENABLE_DCONF "Enable dconf" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS OR GNU" OFF)
cmake_dependent_option(ENABLE_DBUS "Enable dbus-1" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS OR Haiku OR GNU" OFF)
cmake_dependent_option(ENABLE_SQLITE3 "Enable sqlite3" ON "LINUX OR FreeBSD OR APPLE OR OpenBSD OR NetBSD OR SunOS OR GNU" OFF)
cmake_dependent_option(ENABLE_RPM "Enable rpm" ON "LINUX OR GNU" OFF)
cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR APPLE OR ANDROID OR WIN32 OR SunOS OR Haiku OR GNU" OFF)
cmake_dependent_option(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR APPLE OR SunOS OR GNU" OFF)
cmake_dependent_option(ENABLE_CHAFA "Enable chafa" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF)
cmake_dependent_option(ENABLE_ZLIB "Enable zlib" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF)
cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR WIN32 OR SunOS OR Haiku" OFF)
cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS" OFF)
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR WIN32 OR ANDROID OR SunOS OR Haiku" OFF)
cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR WIN32 OR SunOS OR Haiku OR GNU" OFF)
cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS OR GNU" OFF)
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR WIN32 OR ANDROID OR SunOS OR Haiku OR GNU" OFF)
cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF)
cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR ANDROID OR GNU" OFF)
cmake_dependent_option(ENABLE_DDCUTIL "Enable ddcutil" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_DIRECTX_HEADERS "Enable DirectX headers for WSL" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_ELF "Enable libelf" ON "LINUX OR ANDROID OR DragonFly OR Haiku" OFF)
cmake_dependent_option(ENABLE_ELF "Enable libelf" ON "LINUX OR ANDROID OR DragonFly OR Haiku OR GNU" OFF)
cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" OFF)
cmake_dependent_option(ENABLE_LIBZFS "Enable libzfs" ON "LINUX OR FreeBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_PCIACCESS "Enable libpciaccess" ON "NetBSD OR OpenBSD" OFF)
option(ENABLE_ZLIB "Enable zlib" ON)
option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embedded) yyjson library" OFF)
option(ENABLE_ASAN "Build fastfetch with ASAN (address sanitizer)" OFF)
option(ENABLE_LTO "Enable link-time optimization in release mode if supported" ON)
@@ -94,6 +104,14 @@ option(IS_MUSL "Build with musl libc" OFF) # Used by Github Actions
option(INSTALL_LICENSE "Install license into /usr/share/licenses" ON)
option(ENABLE_EMBEDDED_PCIIDS "Embed pci.ids into fastfetch, requires `python`" OFF)
option(ENABLE_EMBEDDED_AMDGPUIDS "Embed amdgpu.ids into fastfetch, requires `python`" OFF)
option(ENABLE_WORDEXP "Enable using of wordexp(3) if available, instead of glob(3)" ON)
option(ENABLE_LIBZFS "Enable libzfs" ON)
if(WIN32 AND NOT CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
option(ENABLE_WIN7_COMPAT "Enable Windows 7 compatibility" OFF)
endif()
if(APPLE)
option(ENABLE_APPLE_MEMSIZE_USABLE "Use usable memory size as total memory size in Memory module, to match other systems" OFF)
endif()
set(BINARY_LINK_TYPE_OPTIONS dlopen dynamic static)
set(BINARY_LINK_TYPE dlopen CACHE STRING "How to link fastfetch")
@@ -148,7 +166,13 @@ if(WIN32 OR Haiku OR ENABLE_DIRECTX_HEADERS)
endif()
if(WIN32)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--tsaware -Wl,--build-id -Wl,--subsystem,console:6.1,--major-os-version,6,--minor-os-version,1")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--tsaware -Wl,--build-id")
if(ENABLE_WIN7_COMPAT)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--subsystem,console,--major-os-version,6,--minor-os-version,1")
else()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--subsystem,console,--major-os-version,10,--minor-os-version,0")
endif()
elseif(APPLE AND CMAKE_C_COMPILER_ID MATCHES "Clang")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fobjc-arc")
endif()
@@ -329,7 +353,7 @@ fastfetch_load_text(src/data/structure.txt DATATEXT_STRUCTURE)
configure_file(src/fastfetch_config.h.in fastfetch_config.h @ONLY)
configure_file(src/fastfetch_datatext.h.in fastfetch_datatext.h @ONLY)
if(APPLE)
configure_file(src/util/apple/Info.plist.in Info.plist @ONLY)
configure_file(src/common/apple/Info.plist.in Info.plist @ONLY)
endif()
####################
@@ -351,30 +375,38 @@ file(GENERATE OUTPUT logo_builtin.h CONTENT "${LOGO_BUILTIN_H}")
#######################
set(LIBFASTFETCH_SRC
src/common/commandoption.c
src/common/duration.c
src/common/font.c
src/common/format.c
src/common/frequency.c
src/common/init.c
src/common/jsonconfig.c
src/common/library.c
src/common/modules.c
src/common/netif/netif.c
src/common/networking/networking_common.c
src/common/option.c
src/common/parsing.c
src/common/percent.c
src/common/printing.c
src/common/properties.c
src/common/settings.c
src/common/size.c
src/common/temps.c
src/common/impl/commandoption.c
src/common/impl/duration.c
src/common/impl/font.c
src/common/impl/format.c
src/common/impl/frequency.c
src/common/impl/init.c
src/common/impl/jsonconfig.c
src/common/impl/library.c
src/common/impl/netif.c
src/common/impl/networking_common.c
src/common/impl/option.c
src/common/impl/parsing.c
src/common/impl/percent.c
src/common/impl/printing.c
src/common/impl/properties.c
src/common/impl/settings.c
src/common/impl/size.c
src/common/impl/temps.c
src/common/impl/time.c
src/common/impl/edidHelper.c
src/common/impl/base64.c
src/common/impl/FFlist.c
src/common/impl/FFstrbuf.c
src/common/impl/path.c
src/common/impl/FFPlatform.c
src/common/impl/smbiosHelper.c
src/detection/bluetoothradio/bluetoothradio.c
src/detection/bootmgr/bootmgr.c
src/detection/chassis/chassis.c
src/detection/cpu/cpu.c
src/detection/cpuusage/cpuusage.c
src/detection/command/command.c
src/detection/disk/disk.c
src/detection/diskio/diskio.c
src/detection/displayserver/displayserver.c
@@ -395,6 +427,7 @@ set(LIBFASTFETCH_SRC
src/detection/version/version.c
src/detection/vulkan/vulkan.c
src/detection/weather/weather.c
src/detection/zpool/zpool.c
src/logo/builtin.c
src/logo/image/im6.c
src/logo/image/im7.c
@@ -436,6 +469,7 @@ set(LIBFASTFETCH_SRC
src/modules/loadavg/loadavg.c
src/modules/locale/locale.c
src/modules/localip/localip.c
src/modules/logo/logo.c
src/modules/memory/memory.c
src/modules/monitor/monitor.c
src/modules/netio/netio.c
@@ -473,26 +507,22 @@ set(LIBFASTFETCH_SRC
src/modules/wm/wm.c
src/modules/wmtheme/wmtheme.c
src/modules/zpool/zpool.c
src/modules/modules.c
src/options/display.c
src/options/logo.c
src/options/general.c
src/util/edidHelper.c
src/util/base64.c
src/util/FFlist.c
src/util/FFstrbuf.c
src/util/kmod.c
src/util/path.c
src/util/platform/FFPlatform.c
src/util/smbiosHelper.c
)
if(LINUX)
list(APPEND LIBFASTFETCH_SRC
src/common/dbus.c
src/common/io/io_unix.c
src/common/netif/netif_linux.c
src/common/networking/networking_linux.c
src/common/processing_linux.c
src/common/impl/dbus.c
src/common/impl/io_unix.c
src/common/impl/netif_linux.c
src/common/impl/networking_linux.c
src/common/impl/processing_linux.c
src/common/impl/FFPlatform_unix.c
src/common/impl/binary_linux.c
src/common/impl/kmod_linux.c
src/detection/battery/battery_linux.c
src/detection/bios/bios_linux.c
src/detection/board/board_linux.c
@@ -512,6 +542,7 @@ if(LINUX)
src/detection/physicalmemory/physicalmemory_linux.c
src/detection/diskio/diskio_linux.c
src/detection/displayserver/linux/displayserver_linux.c
src/detection/displayserver/linux/common.c
src/detection/displayserver/linux/drm.c
src/detection/displayserver/linux/wayland/wayland.c
src/detection/displayserver/linux/wayland/global-output.c
@@ -566,16 +597,17 @@ if(LINUX)
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/detection/camera/camera_linux.c
src/detection/zpool/zpool_linux.c
src/util/platform/FFPlatform_unix.c
src/util/binary_linux.c
)
elseif(ANDROID)
list(APPEND LIBFASTFETCH_SRC
src/common/io/io_unix.c
src/common/netif/netif_linux.c
src/common/networking/networking_linux.c
src/common/processing_linux.c
src/common/impl/dbus.c
src/common/impl/io_unix.c
src/common/impl/netif_linux.c
src/common/impl/networking_linux.c
src/common/impl/processing_linux.c
src/common/impl/FFPlatform_unix.c
src/common/impl/binary_linux.c
src/common/impl/kmod_linux.c
src/detection/battery/battery_android.c
src/detection/bios/bios_android.c
src/detection/bluetooth/bluetooth_nosupport.c
@@ -587,7 +619,7 @@ elseif(ANDROID)
src/detection/chassis/chassis_nosupport.c
src/detection/cpu/cpu_linux.c
src/detection/cpucache/cpucache_linux.c
src/detection/cursor/cursor_nosupport.c
src/detection/cursor/cursor_linux.c
src/detection/cpuusage/cpuusage_linux.c
src/detection/disk/disk_linux.c
src/detection/dns/dns_linux.c
@@ -595,10 +627,16 @@ elseif(ANDROID)
src/detection/physicalmemory/physicalmemory_nosupport.c
src/detection/diskio/diskio_linux.c
src/detection/displayserver/displayserver_android.c
src/detection/font/font_nosupport.c
src/detection/gpu/gpu_nosupport.c
src/detection/displayserver/linux/common.c
src/detection/displayserver/linux/wmde.c
src/detection/displayserver/linux/xcb.c
src/detection/displayserver/linux/xlib.c
src/detection/gtk_qt/gtk.c
src/detection/gtk_qt/qt.c
src/detection/font/font_linux.c
src/detection/gpu/gpu_android.c
src/detection/host/host_android.c
src/detection/icons/icons_nosupport.c
src/detection/icons/icons_linux.c
src/detection/initsystem/initsystem_linux.c
src/detection/keyboard/keyboard_nosupport.c
src/detection/libc/libc_android.c
@@ -607,7 +645,7 @@ elseif(ANDROID)
src/detection/locale/locale_linux.c
src/detection/localip/localip_linux.c
src/detection/gamepad/gamepad_nosupport.c
src/detection/media/media_nosupport.c
src/detection/media/media_linux.c
src/detection/memory/memory_linux.c
src/detection/mouse/mouse_nosupport.c
src/detection/netio/netio_linux.c
@@ -617,33 +655,34 @@ elseif(ANDROID)
src/detection/packages/packages_nix.c
src/detection/poweradapter/poweradapter_nosupport.c
src/detection/processes/processes_linux.c
src/detection/sound/sound_nosupport.c
src/detection/sound/sound_linux.c
src/detection/swap/swap_linux.c
src/detection/terminalfont/terminalfont_android.c
src/detection/terminalfont/terminalfont_linux.c
src/detection/terminalshell/terminalshell_linux.c
src/detection/terminalsize/terminalsize_linux.c
src/detection/theme/theme_nosupport.c
src/detection/theme/theme_linux.c
src/detection/tpm/tpm_nosupport.c
src/detection/uptime/uptime_linux.c
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_nosupport.c
src/detection/wallpaper/wallpaper_linux.c
src/detection/wifi/wifi_android.c
src/detection/wm/wm_nosupport.c
src/detection/de/de_nosupport.c
src/detection/wmtheme/wmtheme_nosupport.c
src/detection/wm/wm_linux.c
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/detection/camera/camera_android.c
src/detection/zpool/zpool_nosupport.c
src/util/platform/FFPlatform_unix.c
src/util/binary_linux.c
)
elseif(FreeBSD)
list(APPEND LIBFASTFETCH_SRC
src/common/dbus.c
src/common/io/io_unix.c
src/common/netif/netif_bsd.c
src/common/networking/networking_linux.c
src/common/processing_linux.c
src/common/sysctl.c
src/common/impl/dbus.c
src/common/impl/io_unix.c
src/common/impl/netif_bsd.c
src/common/impl/networking_linux.c
src/common/impl/processing_linux.c
src/common/impl/sysctl.c
src/common/impl/FFPlatform_unix.c
src/common/impl/binary_linux.c
src/common/impl/kmod_bsd.c
src/detection/battery/battery_bsd.c
src/detection/bios/bios_bsd.c
src/detection/bluetoothradio/bluetoothradio_nosupport.c
@@ -662,6 +701,7 @@ elseif(FreeBSD)
src/detection/physicalmemory/physicalmemory_linux.c
src/detection/diskio/diskio_bsd.c
src/detection/displayserver/linux/displayserver_linux.c
src/detection/displayserver/linux/common.c
src/detection/displayserver/linux/drm.c
src/detection/displayserver/linux/wayland/wayland.c
src/detection/displayserver/linux/wayland/global-output.c
@@ -714,9 +754,6 @@ elseif(FreeBSD)
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/detection/camera/camera_linux.c
src/detection/zpool/zpool_linux.c
src/util/platform/FFPlatform_unix.c
src/util/binary_linux.c
)
if(DragonFly)
list(APPEND LIBFASTFETCH_SRC
@@ -731,12 +768,15 @@ elseif(FreeBSD)
endif()
elseif(NetBSD)
list(APPEND LIBFASTFETCH_SRC
src/common/dbus.c
src/common/io/io_unix.c
src/common/netif/netif_bsd.c
src/common/networking/networking_linux.c
src/common/processing_linux.c
src/common/sysctl.c
src/common/impl/dbus.c
src/common/impl/io_unix.c
src/common/impl/netif_bsd.c
src/common/impl/networking_linux.c
src/common/impl/processing_linux.c
src/common/impl/sysctl.c
src/common/impl/FFPlatform_unix.c
src/common/impl/binary_linux.c
src/common/impl/kmod_nbsd.c
src/detection/battery/battery_nbsd.c
src/detection/bios/bios_nbsd.c
src/detection/bluetooth/bluetooth_bsd.c
@@ -756,6 +796,7 @@ elseif(NetBSD)
src/detection/physicalmemory/physicalmemory_linux.c
src/detection/diskio/diskio_nbsd.c
src/detection/displayserver/linux/displayserver_linux.c
src/detection/displayserver/linux/common.c
src/detection/displayserver/linux/drm.c
src/detection/displayserver/linux/wayland/wayland.c
src/detection/displayserver/linux/wayland/global-output.c
@@ -769,7 +810,7 @@ elseif(NetBSD)
src/detection/displayserver/linux/xcb.c
src/detection/displayserver/linux/xlib.c
src/detection/font/font_linux.c
src/detection/gpu/gpu_general.c
src/detection/gpu/gpu_nbsd.c
src/detection/gpu/gpu_pci.c
src/detection/gtk_qt/gtk.c
src/detection/host/host_nbsd.c
@@ -807,18 +848,19 @@ elseif(NetBSD)
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/detection/camera/camera_linux.c
src/detection/zpool/zpool_linux.c
src/util/platform/FFPlatform_unix.c
src/util/binary_linux.c
)
elseif(OpenBSD)
list(APPEND LIBFASTFETCH_SRC
src/common/dbus.c
src/common/io/io_unix.c
src/common/netif/netif_bsd.c
src/common/networking/networking_linux.c
src/common/processing_linux.c
src/common/sysctl.c
src/common/impl/dbus.c
src/common/impl/io_unix.c
src/common/impl/netif_bsd.c
src/common/impl/networking_linux.c
src/common/impl/processing_linux.c
src/common/impl/sysctl.c
src/common/impl/FFPlatform_unix.c
src/common/impl/binary_linux.c
src/common/impl/smbiosHelper.c
src/common/impl/kmod_nosupport.c
src/detection/battery/battery_obsd.c
src/detection/bios/bios_windows.c
src/detection/bluetooth/bluetooth_nosupport.c
@@ -838,6 +880,7 @@ elseif(OpenBSD)
src/detection/physicalmemory/physicalmemory_linux.c
src/detection/diskio/diskio_obsd.c
src/detection/displayserver/linux/displayserver_linux.c
src/detection/displayserver/linux/common.c
src/detection/displayserver/linux/drm.c
src/detection/displayserver/linux/wayland/wayland.c
src/detection/displayserver/linux/wayland/global-output.c
@@ -852,7 +895,7 @@ elseif(OpenBSD)
src/detection/displayserver/linux/xlib.c
src/detection/font/font_linux.c
src/detection/gpu/gpu_pci.c
src/detection/gpu/gpu_general.c
src/detection/gpu/gpu_obsd.c
src/detection/gtk_qt/gtk.c
src/detection/host/host_obsd.c
src/detection/lm/lm_nosupport.c
@@ -889,18 +932,20 @@ elseif(OpenBSD)
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/detection/camera/camera_linux.c
src/detection/zpool/zpool_nosupport.c
src/util/platform/FFPlatform_unix.c
src/util/binary_linux.c
src/util/smbiosHelper.c
)
elseif(APPLE)
list(APPEND LIBFASTFETCH_SRC
src/common/io/io_unix.c
src/common/netif/netif_apple.c
src/common/networking/networking_linux.c
src/common/processing_linux.c
src/common/sysctl.c
src/common/impl/io_unix.c
src/common/impl/netif_apple.c
src/common/impl/networking_linux.c
src/common/impl/processing_linux.c
src/common/impl/sysctl.c
src/common/impl/FFPlatform_unix.c
src/common/impl/binary_apple.c
src/common/impl/kmod_apple.c
src/common/apple/cf_helpers.c
src/common/apple/osascript.m
src/common/apple/smc_temps.c
src/detection/battery/battery_apple.c
src/detection/bios/bios_apple.c
src/detection/bluetooth/bluetooth_apple.m
@@ -949,7 +994,7 @@ elseif(APPLE)
src/detection/terminalfont/terminalfont_apple.m
src/detection/terminalshell/terminalshell_linux.c
src/detection/terminalsize/terminalsize_linux.c
src/detection/theme/theme_nosupport.c
src/detection/theme/theme_apple.c
src/detection/tpm/tpm_apple.c
src/detection/uptime/uptime_bsd.c
src/detection/users/users_linux.c
@@ -959,19 +1004,24 @@ elseif(APPLE)
src/detection/de/de_nosupport.c
src/detection/wmtheme/wmtheme_apple.m
src/detection/camera/camera_apple.m
src/detection/zpool/zpool_nosupport.c
src/util/apple/cf_helpers.c
src/util/apple/osascript.m
src/util/apple/smc_temps.c
src/util/platform/FFPlatform_unix.c
src/util/binary_apple.c
)
elseif(WIN32)
list(APPEND LIBFASTFETCH_SRC
src/common/io/io_windows.c
src/common/netif/netif_windows.c
src/common/networking/networking_windows.c
src/common/processing_windows.c
src/common/impl/io_windows.c
src/common/impl/netif_windows.c
src/common/impl/networking_windows.c
src/common/impl/processing_windows.c
src/common/impl/FFPlatform_windows.c
src/common/impl/binary_windows.c
src/common/impl/debug_windows.c
src/common/impl/kmod_windows.c
src/common/windows/getline.c
src/common/windows/com.cpp
src/common/windows/registry.c
src/common/windows/unicode.c
src/common/windows/wmi.cpp
src/common/windows/variant.cpp
src/common/windows/version.c
src/detection/battery/battery_windows.c
src/detection/bios/bios_windows.c
src/detection/bluetooth/bluetooth_windows.c
@@ -1019,34 +1069,27 @@ elseif(WIN32)
src/detection/terminalfont/terminalfont_windows.c
src/detection/terminalshell/terminalshell_windows.c
src/detection/terminalsize/terminalsize_windows.c
src/detection/theme/theme_nosupport.c
src/detection/theme/theme_windows.c
src/detection/tpm/tpm_windows.c
src/detection/uptime/uptime_windows.c
src/detection/users/users_windows.c
src/detection/wallpaper/wallpaper_windows.c
src/detection/wifi/wifi_windows.c
src/detection/wm/wm_windows.cpp
src/detection/wm/wm_windows.c
src/detection/de/de_nosupport.c
src/detection/wmtheme/wmtheme_windows.c
src/detection/camera/camera_windows.cpp
src/detection/zpool/zpool_nosupport.c
src/util/windows/getline.c
src/util/windows/com.cpp
src/util/windows/registry.c
src/util/windows/unicode.c
src/util/windows/wmi.cpp
src/util/windows/version.c
src/util/platform/FFPlatform_windows.c
src/util/binary_windows.c
src/util/debug_windows.c
)
elseif(SunOS)
list(APPEND LIBFASTFETCH_SRC
src/common/dbus.c
src/common/io/io_unix.c
src/common/netif/netif_apple.c
src/common/networking/networking_linux.c
src/common/processing_linux.c
src/common/impl/dbus.c
src/common/impl/io_unix.c
src/common/impl/netif_apple.c
src/common/impl/networking_linux.c
src/common/impl/processing_linux.c
src/common/impl/FFPlatform_unix.c
src/common/impl/binary_linux.c
src/common/impl/kmod_sunos.c
src/detection/battery/battery_nosupport.c
src/detection/bios/bios_windows.c
src/detection/board/board_windows.c
@@ -1066,6 +1109,7 @@ elseif(SunOS)
src/detection/physicalmemory/physicalmemory_linux.c
src/detection/diskio/diskio_sunos.c
src/detection/displayserver/linux/displayserver_linux.c
src/detection/displayserver/linux/common.c
src/detection/displayserver/linux/drm.c
src/detection/displayserver/linux/wayland/wayland.c
src/detection/displayserver/linux/wayland/global-output.c
@@ -1117,17 +1161,18 @@ elseif(SunOS)
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/detection/camera/camera_nosupport.c
src/detection/zpool/zpool_linux.c
src/util/platform/FFPlatform_unix.c
src/util/binary_linux.c
)
elseif(Haiku)
list(APPEND LIBFASTFETCH_SRC
src/common/dbus.c
src/common/io/io_unix.c
src/common/netif/netif_haiku.c
src/common/networking/networking_linux.c
src/common/processing_linux.c
src/common/impl/dbus.c
src/common/impl/io_unix.c
src/common/impl/netif_haiku.c
src/common/impl/networking_linux.c
src/common/impl/processing_linux.c
src/common/impl/FFPlatform_unix.c
src/common/impl/binary_linux.c
src/common/impl/kmod_nosupport.c
src/common/haiku/version.cpp
src/detection/battery/battery_haiku.c
src/detection/bios/bios_windows.c
src/detection/board/board_windows.c
@@ -1186,11 +1231,86 @@ elseif(Haiku)
src/detection/de/de_nosupport.c
src/detection/wmtheme/wmtheme_nosupport.c
src/detection/camera/camera_nosupport.c
src/detection/zpool/zpool_nosupport.c
src/util/platform/FFPlatform_unix.c
src/util/binary_linux.c
src/util/haiku/version.cpp
)
elseif(GNU)
list(APPEND LIBFASTFETCH_SRC
src/common/impl/dbus.c
src/common/impl/io_unix.c
src/common/impl/netif_gnu.c
src/common/impl/networking_linux.c
src/common/impl/processing_linux.c
src/common/impl/FFPlatform_unix.c
src/common/impl/binary_linux.c
src/common/impl/kmod_nosupport.c
src/detection/battery/battery_nosupport.c
src/detection/bios/bios_nosupport.c
src/detection/board/board_nosupport.c
src/detection/bootmgr/bootmgr_nosupport.c
src/detection/brightness/brightness_nosupport.c
src/detection/btrfs/btrfs_nosupport.c
src/detection/chassis/chassis_nosupport.c
src/detection/cpu/cpu_linux.c
src/detection/cpucache/cpucache_nosupport.c
src/detection/cpuusage/cpuusage_linux.c
src/detection/cursor/cursor_linux.c
src/detection/bluetooth/bluetooth_linux.c
src/detection/bluetoothradio/bluetoothradio_linux.c
src/detection/disk/disk_linux.c
src/detection/dns/dns_linux.c
src/detection/physicaldisk/physicaldisk_nosupport.c
src/detection/physicalmemory/physicalmemory_nosupport.c
src/detection/diskio/diskio_nosupport.c
src/detection/displayserver/linux/displayserver_linux.c
src/detection/displayserver/linux/common.c
src/detection/displayserver/linux/drm.c
src/detection/displayserver/linux/wayland/wayland.c
src/detection/displayserver/linux/wayland/global-output.c
src/detection/displayserver/linux/wayland/zwlr-output.c
src/detection/displayserver/linux/wayland/wlr-output-management-unstable-v1-protocol.c
src/detection/displayserver/linux/wmde.c
src/detection/displayserver/linux/xcb.c
src/detection/displayserver/linux/xlib.c
src/detection/font/font_linux.c
src/detection/gpu/gpu_gnu.c
src/detection/gpu/gpu_pci.c
src/detection/gtk_qt/gtk.c
src/detection/host/host_nosupport.c
src/detection/icons/icons_linux.c
src/detection/initsystem/initsystem_linux.c
src/detection/keyboard/keyboard_nosupport.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_nosupport.c
src/detection/media/media_linux.c
src/detection/memory/memory_linux.c
src/detection/mouse/mouse_nosupport.c
src/detection/netio/netio_nosupport.c
src/detection/opengl/opengl_linux.c
src/detection/os/os_linux.c
src/detection/packages/packages_linux.c
src/detection/packages/packages_nix.c
src/detection/poweradapter/poweradapter_nosupport.c
src/detection/processes/processes_linux.c
src/detection/gtk_qt/qt.c
src/detection/sound/sound_linux.c
src/detection/swap/swap_linux.c
src/detection/terminalfont/terminalfont_linux.c
src/detection/terminalshell/terminalshell_linux.c
src/detection/terminalsize/terminalsize_linux.c
src/detection/theme/theme_linux.c
src/detection/tpm/tpm_nosupport.c
src/detection/uptime/uptime_linux.c
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_linux.c
src/detection/wifi/wifi_nosupport.c
src/detection/wm/wm_linux.c
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/detection/camera/camera_nosupport.c
)
endif()
if(ENABLE_DIRECTX_HEADERS)
@@ -1210,14 +1330,15 @@ endif()
include(CheckFunctionExists)
check_function_exists(wcwidth HAVE_WCWIDTH)
if(NOT HAVE_WCWIDTH)
list(APPEND LIBFASTFETCH_SRC src/3rdparty/mk_wcwidch/wcwidth.c)
endif()
if(LINUX)
check_function_exists(statx HAVE_STATX)
list(APPEND LIBFASTFETCH_SRC src/common/impl/wcwidth.c)
endif()
if(NOT WIN32)
check_function_exists(pipe2 HAVE_PIPE2)
endif()
check_function_exists(memrchr HAVE_MEMRCHR)
if(NOT HAVE_MEMRCHR)
list(APPEND LIBFASTFETCH_SRC src/common/impl/memrchr.c)
endif()
if(ENABLE_SYSTEM_YYJSON)
find_package(yyjson)
@@ -1236,16 +1357,25 @@ add_library(libfastfetch OBJECT
${LIBFASTFETCH_SRC}
)
include(CheckCSourceCompiles)
check_c_source_compiles("int main(void){int arr[1];return _Countof(arr);}" COMPILER_SUPPORTS_COUNT_OF)
if(COMPILER_SUPPORTS_COUNT_OF)
message(STATUS "_Countof is supported by the compiler")
target_compile_definitions(libfastfetch PUBLIC FF_SUPPORTS_COUNT_OF=1)
else()
message(STATUS "_Countof is NOT supported by the compiler")
endif()
if(yyjson_FOUND)
target_compile_definitions(libfastfetch PUBLIC FF_USE_SYSTEM_YYJSON)
target_compile_definitions(libfastfetch PUBLIC FF_USE_SYSTEM_YYJSON=1)
target_link_libraries(libfastfetch PUBLIC yyjson::yyjson)
# `target_link_libraries(yyjson::yyjson)` sets rpath implicitly
else()
# Used for dlopen finding dylibs installed by homebrew
# `/opt/homebrew/lib` is not on in dlopen search path by default
if(APPLE)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath,/opt/homebrew/lib -Wl,-rpath,/usr/local/lib")
endif()
endif()
# Used for dlopen finding dylibs installed by homebrew
# `/opt/homebrew/lib` is not on in dlopen search path by default
if(APPLE AND BINARY_LINK_TYPE STREQUAL "dlopen")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath,/opt/homebrew/lib -Wl,-rpath,/usr/local/lib")
endif()
if(ANDROID)
@@ -1307,13 +1437,47 @@ elseif(OpenBSD)
elseif(DragonFly)
target_compile_definitions(libfastfetch PUBLIC __FreeBSD__)
elseif(SunOS)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE __STDC_WANT_LIB_EXT1__ _FILE_OFFSET_BITS=64 __EXTENSIONS__ _POSIX_C_SOURCE)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE __STDC_WANT_LIB_EXT1__ _FILE_OFFSET_BITS=64 __EXTENSIONS__ _POSIX_C_SOURCE)
elseif(NetBSD)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-char-subscripts")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath,/usr/X11R7/lib -Wl,-rpath,/usr/pkg/lib") # ditto
elseif(Haiku)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE)
elseif(GNU)
# On Hurd PATH_MAX is not defined. Set an arbitrary limit as workaround.
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE PATH_MAX=4096 O_PATH=0)
endif()
if(APPLE)
if(ENABLE_APPLE_MEMSIZE_USABLE)
target_compile_definitions(libfastfetch PUBLIC FF_APPLE_MEMSIZE_USABLE=1)
else()
target_compile_definitions(libfastfetch PUBLIC FF_APPLE_MEMSIZE_USABLE=0)
endif()
endif()
if(WIN32)
check_function_exists(_msize HAVE_MSVC_MSIZE)
if(HAVE_MSVC_MSIZE)
target_compile_definitions(libfastfetch PUBLIC FF_HAVE_MSVC_MSIZE=1)
endif()
if(ENABLE_WIN7_COMPAT)
target_compile_definitions(libfastfetch PUBLIC FF_WIN7_COMPAT=1)
else()
target_compile_definitions(libfastfetch PUBLIC FF_WIN7_COMPAT=0)
endif()
else()
check_function_exists(malloc_usable_size HAVE_MALLOC_USABLE_SIZE)
if(HAVE_MALLOC_USABLE_SIZE)
target_compile_definitions(libfastfetch PUBLIC FF_HAVE_MALLOC_USABLE_SIZE=1)
else()
check_function_exists(malloc_size HAVE_MALLOC_SIZE)
if(HAVE_MALLOC_SIZE)
target_compile_definitions(libfastfetch PUBLIC FF_HAVE_MALLOC_SIZE=1)
endif()
endif()
endif()
if(FreeBSD OR OpenBSD OR NetBSD)
@@ -1326,10 +1490,6 @@ if(FreeBSD OR OpenBSD OR NetBSD)
unset(CMAKE_REQUIRED_DEFINITIONS)
endif()
if(HAVE_STATX)
target_compile_definitions(libfastfetch PUBLIC FF_HAVE_STATX)
endif()
if(HAVE_WCWIDTH)
target_compile_definitions(libfastfetch PUBLIC FF_HAVE_WCWIDTH)
endif()
@@ -1440,10 +1600,6 @@ ff_lib_enable(DBUS
"dbus-1"
"DBus"
)
ff_lib_enable(XFCONF
"libxfconf-0"
"XFConf"
)
ff_lib_enable(SQLITE3
"sqlite3"
"SQLite3"
@@ -1507,28 +1663,6 @@ ff_lib_enable(DIRECTX_HEADERS
"DirectX-Headers"
"DirectX-Headers"
)
ff_lib_enable(PCIACCESS
"pciaccess"
"pciaccess"
)
# The system <libzfs.h> is only usable on SunOS. We provide our local copy of it so it's always available.
if(ENABLE_LIBZFS)
if(BINARY_LINK_TYPE STREQUAL "dlopen")
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LIBZFS=1)
else()
set(CMAKE_REQUIRED_LIBRARIES_BACKUP ${CMAKE_REQUIRED_LIBRARIES})
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} zfs)
check_function_exists("libzfs_init" LIBZFS_FOUND)
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES_BACKUP})
if(NOT LIBZFS_FOUND)
message(STATUS "Library: missing: LIBZFS")
else()
message(STATUS "Library: found LIBZFS")
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LIBZFS=1)
target_link_libraries(libfastfetch PRIVATE zfs)
endif()
endif()
endif()
if(ENABLE_THREADS)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_THREADS=1)
@@ -1543,6 +1677,18 @@ endif()
if(ENABLE_EMBEDDED_AMDGPUIDS)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_EMBEDDED_AMDGPUIDS=1)
endif()
if(ENABLE_LIBZFS)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LIBZFS=1)
if(NOT BINARY_LINK_TYPE STREQUAL "dlopen")
target_link_libraries(libfastfetch
PRIVATE "zfs"
)
endif()
endif()
if(NOT HAVE_MEMRCHR)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_CUSTOM_MEMRCHR=1)
endif()
if(LINUX)
target_link_libraries(libfastfetch
@@ -1579,7 +1725,6 @@ elseif(APPLE)
)
elseif(WIN32)
target_link_libraries(libfastfetch
PRIVATE "dwmapi"
PRIVATE "gdi32"
PRIVATE "iphlpapi"
PRIVATE "ole32"
@@ -1589,14 +1734,11 @@ elseif(WIN32)
PRIVATE "version"
PRIVATE "hid"
PRIVATE "wtsapi32"
PRIVATE "imagehlp"
PRIVATE "cfgmgr32"
PRIVATE "winbrand"
PRIVATE "propsys"
PRIVATE "secur32"
)
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64")
# WoA only works on Windows 10 or higher
if(NOT ENABLE_WIN7_COMPAT)
target_link_libraries(libfastfetch
PRIVATE "mincore"
)
@@ -1634,22 +1776,30 @@ elseif(SunOS)
PRIVATE "socket"
PRIVATE "kstat"
PRIVATE "proc"
PRIVATE "zfs"
PRIVATE "nvpair"
PRIVATE "devinfo"
)
elseif(GNU)
target_link_libraries(libfastfetch
PRIVATE "m"
)
elseif(ANDROID)
CHECK_LIBRARY_EXISTS(-l:libandroid-wordexp.a wordexp "" HAVE_LIBANDROID_WORDEXP_STATIC)
if(HAVE_LIBANDROID_WORDEXP_STATIC)
target_link_libraries(libfastfetch
PRIVATE -l:libandroid-wordexp.a
)
else()
CHECK_LIBRARY_EXISTS(android-wordexp wordexp "" HAVE_LIBANDROID_WORDEXP)
if(HAVE_LIBANDROID_WORDEXP)
target_link_libraries(libfastfetch
PRIVATE "m"
)
if(ENABLE_WORDEXP)
# https://github.com/termux/termux-packages/pull/7056
CHECK_LIBRARY_EXISTS(-l:libandroid-wordexp.a wordexp "" HAVE_LIBANDROID_WORDEXP_STATIC)
if(HAVE_LIBANDROID_WORDEXP_STATIC)
target_link_libraries(libfastfetch
PRIVATE android-wordexp
PRIVATE -l:libandroid-wordexp.a
)
else()
CHECK_LIBRARY_EXISTS(android-wordexp wordexp "" HAVE_LIBANDROID_WORDEXP)
if(HAVE_LIBANDROID_WORDEXP)
target_link_libraries(libfastfetch
PRIVATE android-wordexp
)
endif()
endif()
endif()
elseif(Haiku)
@@ -1711,13 +1861,17 @@ if(NOT WIN32)
if(HAVE_UTMPX)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_UTMPX=1)
endif()
CHECK_INCLUDE_FILE("wordexp.h" HAVE_WORDEXP)
if(HAVE_WORDEXP)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_WORDEXP=1)
if(ENABLE_WORDEXP)
CHECK_INCLUDE_FILE("wordexp.h" HAVE_WORDEXP)
if(HAVE_WORDEXP)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_WORDEXP=1)
message(STATUS "wordexp.h found, wordexp support enabled")
else()
set(ENABLE_WORDEXP OFF)
endif()
endif()
CHECK_INCLUDE_FILE("glob.h" HAVE_GLOB)
if(HAVE_GLOB)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_GLOB=1)
if(NOT ENABLE_WORDEXP)
message(STATUS "wordexp.h not found or disabled, glob used instead")
endif()
if(ENABLE_THREADS AND CMAKE_USE_PTHREADS_INIT)
CHECK_INCLUDE_FILE("pthread_np.h" HAVE_PTHREAD_NP)
@@ -1772,7 +1926,7 @@ set_target_properties(fastfetch PROPERTIES LINKER_LANGUAGE C)
if(WIN32)
target_sources(fastfetch
PRIVATE src/util/windows/version.rc
PRIVATE src/common/windows/version.rc
)
elseif(APPLE)
target_link_options(fastfetch
@@ -1800,7 +1954,7 @@ if (BUILD_FLASHFETCH)
if(WIN32)
target_sources(flashfetch
PRIVATE src/util/windows/version.rc
PRIVATE src/common/windows/version.rc
)
elseif(APPLE)
target_link_options(flashfetch
@@ -1926,11 +2080,6 @@ install(
##################
set(CPACK_GENERATOR "TGZ;ZIP")
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
set(CMAKE_SYSTEM_PROCESSOR "amd64")
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
set(CMAKE_SYSTEM_PROCESSOR "aarch64")
endif()
if(APPLE)
string(TOLOWER "${CMAKE_PROJECT_NAME}-macos-${CMAKE_SYSTEM_PROCESSOR}" CPACK_PACKAGE_FILE_NAME) # use macos instead of darwin
elseif(IS_MUSL)
@@ -1970,14 +2119,14 @@ if(LINUX)
set(CPACK_RPM_PACKAGE_LICENSE "MIT")
endif()
endif()
elseif(FreeBSD)
elseif(FreeBSD AND NOT DragonFly)
set(CPACK_FREEBSD_PACKAGE_LICENSE "MIT")
set(CPACK_GENERATOR "${CPACK_GENERATOR};FREEBSD")
endif()
set(CPACK_SET_DESTDIR ON)
set(CPACK_PACKAGE_CONTACT "Linus Dierheimer <Linus@Dierheimer.de>")
set(CPACK_PACKAGE_CONTACT "Carter Li <zhangsongcui@live.cn>")
set(CPACK_PACKAGE_DESCRIPTION "\
fastfetch is a neofetch-like tool for fetching system information and displaying them in a pretty way. \
It is written mostly in C to achieve much better performance.\
+1 -1
View File
@@ -1,7 +1,7 @@
MIT License
Copyright (c) 2021-2023 Linus Dierheimer
Copyright (c) 2022-2025 Carter Li
Copyright (c) 2022-2026 Carter Li
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+75
View File
@@ -0,0 +1,75 @@
# Fastfetch
Fastfetch 是一款类似 neofetch 的系统信息展示工具,主要用 C 编写,强调性能和可定制性。支持 Linux、macOS、Windows 7+、Android、FreeBSD、OpenBSD、NetBSD、DragonFly、Haiku、SunOS。
示例配置见 presets/examples,更多截图与平台说明见 Wiki。
## 安装
Linux(部分):
- Debian 13+ / Ubuntu: apt install fastfetch
- Arch: pacman -S fastfetch
- Fedora: dnf install fastfetch
- openSUSE: zypper install fastfetch
- Linuxbrewbrew install fastfetch
- 各发行版打包状态:https://repology.org/project/fastfetch/versions
macOS
- Homebrewbrew install fastfetch
- MacPortssudo port install fastfetch
Windows
- scoop install fastfetch
- choco install fastfetch
- winget install fastfetch
- MSYS2pacman -S mingw-w64-<subsystem>-<arch>-fastfetch
BSD
- FreeBSDpkg install fastfetch
- NetBSDpkgin in fastfetch
- OpenBSDpkg_add fastfetch
AndroidTermux):
- pkg install fastfetch
Nightly 构建:
- https://nightly.link/fastfetch-cli/fastfetch/workflows/ci/dev?preview
## 源码构建
基本上是 `cmake . && make`。详见 Wikihttps://github.com/fastfetch-cli/fastfetch/wiki/Building
## 使用
- 默认运行:`fastfetch`
- 查看所有可用模块示例:`fastfetch -c all.jsonc`
- 以 JSON 输出指定模块:`fastfetch -s <module1>[:<module2>] --format json`
- 完整命令行帮助:`fastfetch --help`
- 生成最小配置:`fastfetch --gen-config [</path/to/config.jsonc>]`
- 生成完整配置:`fastfetch --gen-config-full`
- 请使用支持 JSON schema 的编辑器(如 VSCode)编辑配置文件!
- 如果你连接 Github 有网络困难(智能提示不生效),可将配置文件中的 `$schema` 的值替换为 `https://gitee.com/carterl/fastfetch/raw/dev/doc/json_schema.json`
## 定制
- 配置使用 JSONC,语法与选项见 Wikihttps://github.com/fastfetch-cli/fastfetch/wiki/Configuration
- 预设示例位于 presets,可用 `-c <filename>` 加载
- Logo 选项与图像显示见文档:https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options
- 模块格式化(示例,仅显示 GPU 名称):
```jsonc
{
"modules": [
{ "type": "gpu", "format": "{name}" }
]
}
```
详见:https://github.com/fastfetch-cli/fastfetch/wiki/Format-String-Guide
## 反馈与支持
- 使用问题:Discussions https://github.com/fastfetch-cli/fastfetch/discussions
- 疑似缺陷:Issues https://github.com/fastfetch-cli/fastfetch/issues(请填写模版)
## 赞助
<img src="https://github.com/user-attachments/assets/a36a6501-e8b0-4a10-9061-b9206d12ffba" width="220">
+13 -2
View File
@@ -11,8 +11,9 @@
[![latest packaged version(s)](https://repology.org/badge/latest-versions/fastfetch.svg)](https://repology.org/project/fastfetch/versions)
[![Packaging status](https://repology.org/badge/tiny-repos/fastfetch.svg)](https://repology.org/project/fastfetch/versions)
[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/fastfetch-cli/fastfetch)
[![中文README](https://img.shields.io/badge/%E4%B8%AD%E6%96%87-README-red)](README-cn.md)
Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying it in a visually appealing way. It is written mainly in C, with a focus on performance and customizability. Currently, it supports Linux, macOS, Windows 7+, Android, FreeBSD, OpenBSD, NetBSD, DragonFly, Haiku, and SunOS.
Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying it in a visually appealing way. It is written mainly in C, with a focus on performance and customizability. Currently, it supports Linux, macOS, Windows 7+, Android, FreeBSD, OpenBSD, NetBSD, DragonFly, Haiku and SunOS (illumos, Solaris).
<img src="screenshots/example1.png" width="49%" align="left" />
<img src="https://upload.wikimedia.org/wikipedia/commons/2/24/Transparent_Square_Tiles_Texture.png" width="49%" height="16px" align="left" />
@@ -36,7 +37,8 @@ Some distributions package outdated versions of fastfetch. Older versions receiv
<img src="https://repology.org/badge/vertical-allrepos/fastfetch.svg?columns=2" alt="Packaging status" align="right">
</a>
* Debian: `apt install fastfetch` (for Debian 13 or newer)
* Ubuntu: [`ppa:zhangsongcui3371/fastfetch`](https://launchpad.net/~zhangsongcui3371/+archive/ubuntu/fastfetch) (Ubuntu 22.04 or newer; latest version)
* Debian / Ubuntu: `apt install fastfetch` (Debian 13 or newer; Ubuntu 25.04 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: `pacman -S fastfetch`
* Fedora: `dnf install fastfetch`
@@ -103,6 +105,10 @@ Fastfetch uses JSONC (JSON with comments) for configuration. [See the Wiki for d
Logos can also be heavily customized; see the [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for more information.
### WARNING
Fastfetch supports a `Command` module that can run arbitrary shell commands. If you copy-paste a config file from an untrusted source, it may contain malicious commands that can harm your system or compromise your privacy. Please always review the config file before using it.
## FAQ
### Q: Neofetch is good enough. Why do I need fastfetch?
@@ -317,6 +323,11 @@ If you find Fastfetch useful, please consider donating.
* Current maintainer: [@CarterLi](https://paypal.me/zhangsongcui)
* Original author: [@LinusDierheimer](https://github.com/sponsors/LinusDierheimer)
## Code signing
* Free code signing provided by [SignPath.io](https://about.signpath.io/), certificate by [SignPath Foundation](https://signpath.org/)
* This program will not transfer any information to other networked systems unless specifically requested by the user or the person installing or operating it
## Star History
Give us a star to show your support!
+79 -1
View File
@@ -1,3 +1,82 @@
fastfetch (2.58.0~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
* Update to 2.58.0
-- Carter Li <zhangsongcui@live.cn> Thu, 22 Jan 2026 15:30:58 +0800
fastfetch (2.57.1~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
* Update to 2.57.1
-- Carter Li <zhangsongcui@live.cn> Wed, 14 Jan 2026 14:00:17 +0800
fastfetch (2.57.0~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
* Update to 2.57.0
-- Carter Li <zhangsongcui@live.cn> Mon, 12 Jan 2026 10:11:21 +0800
fastfetch (2.56.1~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
* Update to 2.56.1
-- Carter Li <zhangsongcui@live.cn> Thu, 18 Dec 2025 14:57:36 +0800
fastfetch (2.56.0~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
* Update to 2.56.0
-- Carter Li <zhangsongcui@live.cn> Mon, 08 Dec 2025 09:21:58 +0800
fastfetch (2.55.1~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
* Update to 2.55.1
-- Carter Li <zhangsongcui@live.cn> Mon, 17 Nov 2025 10:15:44 +0800
fastfetch (2.55.0~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
* Update to 2.55.0
-- Carter Li <zhangsongcui@live.cn> Wed, 12 Nov 2025 09:15:24 +0800
fastfetch (2.54.1~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
* Fix building on plucky
-- Carter Li <zhangsongcui@live.cn> Mon, 20 Oct 2025 14:27:02 +0800
fastfetch (2.54.0~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
* Update to 2.54.0
* Test independent changelog entries for different Ubuntu releases
-- Carter Li <zhangsongcui@live.cn> Mon, 20 Oct 2025 10:47:02 +0800
fastfetch (2.53.0) jammy; urgency=medium
* Update to 2.53.0
-- Carter Li <zhangsongcui@live.cn> Tue, 23 Sep 2025 09:58:48 +0800
fastfetch (2.52.0) jammy; urgency=medium
* Update to 2.52.0
-- Carter Li <zhangsongcui@live.cn> Fri, 05 Sep 2025 14:59:44 +0800
fastfetch (2.51.0) jammy; urgency=medium
* Update to 2.51.0
-- Carter Li <zhangsongcui@live.cn> Fri, 29 Aug 2025 08:55:03 +0800
fastfetch (2.50.2) jammy; urgency=medium
* Update to 2.50.2
-- Carter Li <zhangsongcui@live.cn> Thu, 21 Aug 2025 10:33:07 +0800
fastfetch (2.49.0) jammy; urgency=medium
* Update to 2.49.0
@@ -411,4 +490,3 @@ fastfetch (2.7.1) jammy; urgency=medium
* Initial release.
-- Carter Li <zhangsongcui@live.cn> Tue, 06 Feb 2024 15:01:11 +0800
+1 -1
View File
@@ -2,7 +2,7 @@ Source: fastfetch
Section: universe/utils
Priority: optional
Maintainer: Carter Li <zhangsongcui@live.cn>
Build-Depends: 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, ocl-icd-opencl-dev, libpulse-dev, libdrm-dev, libddcutil-dev, libchafa-dev, directx-headers-dev, pkgconf, cmake (>= 3.12), debhelper (>= 11.2), dh-cmake, dh-cmake-compat (= 1), dh-sequence-cmake, dh-sequence-ctest, ninja-build
Build-Depends: libelf-dev, libvulkan-dev, libwayland-dev, libxrandr-dev, libxcb-randr0-dev, libdconf-dev, libdbus-1-dev, libmagickcore-dev, libsqlite3-dev, librpm-dev, libegl-dev, libglx-dev, ocl-icd-opencl-dev, libpulse-dev, libdrm-dev, libddcutil-dev, libchafa-dev, directx-headers-dev, pkgconf, cmake (>= 3.12), debhelper (>= 11.2), dh-cmake, dh-cmake-compat (= 1), dh-sequence-cmake, dh-sequence-ctest, ninja-build, python3-setuptools
Standards-Version: 4.0.0
Homepage: https://github.com/fastfetch-cli/fastfetch
-1
View File
@@ -1 +0,0 @@
fastfetch_2.49.0_source.buildinfo universe/utils optional
+74 -2
View File
@@ -1,4 +1,76 @@
#!/usr/bin/env bash
# WARNING: DO NOT RUN THIS SCRIPT UNLESS YOU KNOW WHAT YOU ARE DOING.
debuild -S -i -I
dput ppa:zhangsongcui3371/fastfetch ~/fastfetch_*.changes
set -euo pipefail
command -v debuild >/dev/null 2>&1 || { echo "debuild not found. Install devscripts." >&2; exit 1; }
command -v dput >/dev/null 2>&1 || { echo "dput not found." >&2; exit 1; }
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
ROOT_DIR="$(cd -- "$SCRIPT_DIR/.." >/dev/null 2>&1 && pwd)"
OUT_DIR="$(dirname "$ROOT_DIR")"
PPA="ppa:zhangsongcui3371/fastfetch"
CODENAMES=( jammy noble plucky questing resolute )
DRY_RUN=0
if [[ -d "$OUT_DIR/build" ]]; then
echo "Output directory exists: $OUT_DIR/build" >&2
echo "Please move or delete it before proceeding." >&2
exit 1
fi
TEMPLATE="$ROOT_DIR/debian/changelog.tpl"
CHANGELOG_DEBIAN="$ROOT_DIR/debian/changelog"
if [[ ! -f "$TEMPLATE" ]]; then
echo "Template not found: $TEMPLATE" >&2
exit 1
fi
if ! grep -q '#UBUNTU_CODENAME#' "$TEMPLATE"; then
echo "Template missing placeholder: #UBUNTU_CODENAME#" >&2
exit 1
fi
echo "IMPORTANT: Before proceeding, please ensure that 'debian/changelog.tpl' is up-to-date"
echo " with the correct version number, release notes, and maintainer information."
echo
echo " The template must contain a placeholder like '#UBUNTU_CODENAME#' for the codename."
echo
read -p "Have you reviewed and updated 'debian/changelog.tpl'? (y/N): " -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
cleanup() {
rm -f "$CHANGELOG_DEBIAN"
rm -f "$ROOT_DIR/debian/files"
}
trap cleanup EXIT
shopt -s nullglob
for codename in "${CODENAMES[@]}"; do
echo "==> Publishing distro: $codename"
sed "s/#UBUNTU_CODENAME#/${codename}/g" "$TEMPLATE" > "$CHANGELOG_DEBIAN"
( cd "$ROOT_DIR" && debuild -S -i -I )
changes=( "$OUT_DIR"/fastfetch_*~${codename}_source.changes )
if [[ ${#changes[@]} -ne 1 ]]; then
echo "Unable to uniquely identify .changes for '$codename' in: $OUT_DIR" >&2
printf 'Found:\n'; printf ' %s\n' "${changes[@]}" >&2 || true
exit 1
fi
if [[ $DRY_RUN -eq 1 ]]; then
echo "[DRY-RUN] dput \"$PPA\" \"${changes[0]}\""
else
dput "$PPA" "${changes[0]}"
fi
rm -f "$OUT_DIR"/fastfetch_*~${codename}_source.{changes,dsc,tar.*}
echo "<== Done: $codename"
done
+225 -32
View File
@@ -237,6 +237,19 @@
"description": "Null to disable this condition"
}
]
},
"succeeded": {
"description": "Whether the module succeeded in the last run",
"oneOf": [
{
"type": "boolean",
"description": "True to only show the module if it succeeded, false to only show it if it failed"
},
{
"type": "null",
"description": "Null to disable this condition"
}
]
}
}
},
@@ -305,7 +318,7 @@
"type": "string"
},
"cpuFormat": {
"description": "Output format of the module `CPU`. See Wiki for formatting syntax\n 1. {name}: Name\n 2. {vendor}: Vendor\n 3. {cores-physical}: Physical core count\n 4. {cores-logical}: Logical core count\n 5. {cores-online}: Online core count\n 6. {freq-base}: Base frequency (formatted)\n 7. {freq-max}: Max frequency (formatted)\n 8. {temperature}: Temperature (formatted)\n 9. {core-types}: Logical core count grouped by frequency\n 10. {packages}: Processor package count",
"description": "Output format of the module `CPU`. See Wiki for formatting syntax\n 1. {name}: Name\n 2. {vendor}: Vendor\n 3. {cores-physical}: Physical core count\n 4. {cores-logical}: Logical core count\n 5. {cores-online}: Online core count\n 6. {freq-base}: Base frequency (formatted)\n 7. {freq-max}: Max frequency (formatted)\n 8. {temperature}: Temperature (formatted)\n 9. {core-types}: Logical core count grouped by frequency\n 10. {packages}: Processor package count\n 11. {march}: CPU microarchitecture\n 12. {numa-nodes}: NUMA node count",
"type": "string"
},
"cpucacheFormat": {
@@ -333,7 +346,7 @@
"type": "string"
},
"diskFormat": {
"description": "Output format of the module `Disk`. See Wiki for formatting syntax\n 1. {size-used}: Size used\n 2. {size-total}: Size total\n 3. {size-percentage}: Size percentage num\n 4. {files-used}: Files used\n 5. {files-total}: Files total\n 6. {files-percentage}: Files percentage num\n 7. {is-external}: True if external volume\n 8. {is-hidden}: True if hidden volume\n 9. {filesystem}: Filesystem\n 10. {name}: Label / name\n 11. {is-readonly}: True if read-only\n 12. {create-time}: Create time in local timezone\n 13. {size-percentage-bar}: Size percentage bar\n 14. {files-percentage-bar}: Files percentage bar\n 15. {days}: Days after creation\n 16. {hours}: Hours after creation\n 17. {minutes}: Minutes after creation\n 18. {seconds}: Seconds after creation\n 19. {milliseconds}: Milliseconds after creation\n 20. {mountpoint}: Mount point / drive letter\n 21. {mount-from}: Mount from (device path)\n 22. {years}: Years integer after creation\n 23. {days-of-year}: Days of year after creation\n 24. {years-fraction}: Years fraction after creation",
"description": "Output format of the module `Disk`. See Wiki for formatting syntax\n 1. {size-used}: Size used\n 2. {size-total}: Size total\n 3. {size-percentage}: Size percentage num\n 4. {files-used}: Files used\n 5. {files-total}: Files total\n 6. {files-percentage}: Files percentage num\n 7. {is-external}: True if external volume\n 8. {is-hidden}: True if hidden volume\n 9. {filesystem}: Filesystem\n 10. {name}: Label / name\n 11. {is-readonly}: True if read-only\n 12. {create-time}: Create time in local timezone\n 13. {size-percentage-bar}: Size percentage bar\n 14. {files-percentage-bar}: Files percentage bar\n 15. {days}: Days after creation\n 16. {hours}: Hours after creation\n 17. {minutes}: Minutes after creation\n 18. {seconds}: Seconds after creation\n 19. {milliseconds}: Milliseconds after creation\n 20. {mountpoint}: Mount point / drive letter\n 21. {mount-from}: Mount from (device path)\n 22. {years}: Years integer after creation\n 23. {days-of-year}: Days of year after creation\n 24. {years-fraction}: Years fraction after creation\n 25. {size-free}: Size free\n 26. {size-available}: Size available",
"type": "string"
},
"diskioFormat": {
@@ -429,7 +442,7 @@
"type": "string"
},
"packagesFormat": {
"description": "Output format of the module `Packages`. See Wiki for formatting syntax\n 1. {all}: Number of all packages\n 2. {pacman}: Number of pacman packages\n 3. {pacman-branch}: Pacman branch on manjaro\n 4. {dpkg}: Number of dpkg packages\n 5. {rpm}: Number of rpm packages\n 6. {emerge}: Number of emerge packages\n 7. {eopkg}: Number of eopkg packages\n 8. {xbps}: Number of xbps packages\n 9. {nix-system}: Number of nix-system packages\n 10. {nix-user}: Number of nix-user packages\n 11. {nix-default}: Number of nix-default packages\n 12. {apk}: Number of apk packages\n 13. {pkg}: Number of pkg packages\n 14. {flatpak-system}: Number of flatpak-system app packages\n 15. {flatpak-user}: Number of flatpak-user app packages\n 16. {snap}: Number of snap packages\n 17. {brew}: Number of brew packages\n 18. {brew-cask}: Number of brew-cask packages\n 19. {macports}: Number of macports packages\n 20. {scoop-user}: Number of scoop-user packages\n 21. {scoop-global}: Number of scoop-global packages\n 22. {choco}: Number of choco packages\n 23. {pkgtool}: Number of pkgtool packages\n 24. {paludis}: Number of paludis packages\n 25. {winget}: Number of winget packages\n 26. {opkg}: Number of opkg packages\n 27. {am-system}: Number of am-system packages\n 28. {sorcery}: Number of sorcery packages\n 29. {lpkg}: Number of lpkg packages\n 30. {lpkgbuild}: Number of lpkgbuild packages\n 31. {guix-system}: Number of guix-system packages\n 32. {guix-user}: Number of guix-user packages\n 33. {guix-home}: Number of guix-home packages\n 34. {linglong}: Number of linglong packages\n 35. {pacstall}: Number of pacstall packages\n 36. {mport}: Number of mport packages\n 37. {am-user}: Number of am-user (aka appman) packages\n 38. {pkgsrc}: Number of pkgsrc packages\n 39. {hpkg-system}: Number of hpkg-system packages\n 40. {hpkg-user}: Number of hpkg-user packages\n 41. {pisi}: Number of pisi packages\n 42. {soar}: Number of soar packages\n 43. {nix-all}: Total number of all nix packages\n 44. {flatpak-all}: Total number of all flatpak app packages\n 45. {brew-all}: Total number of all brew packages\n 46. {guix-all}: Total number of all guix packages\n 47. {hpkg-all}: Total number of all hpkg packages",
"description": "Output format of the module `Packages`. See Wiki for formatting syntax\n 1. {all}: Number of all packages\n 2. {pacman}: Number of pacman packages\n 3. {pacman-branch}: Pacman branch on manjaro\n 4. {dpkg}: Number of dpkg packages\n 5. {rpm}: Number of rpm packages\n 6. {emerge}: Number of emerge packages\n 7. {eopkg}: Number of eopkg packages\n 8. {xbps}: Number of xbps packages\n 9. {nix-system}: Number of nix-system packages\n 10. {nix-user}: Number of nix-user packages\n 11. {nix-default}: Number of nix-default packages\n 12. {apk}: Number of apk packages\n 13. {pkg}: Number of pkg packages\n 14. {flatpak-system}: Number of flatpak-system app packages\n 15. {flatpak-user}: Number of flatpak-user app packages\n 16. {snap}: Number of snap packages\n 17. {brew}: Number of brew packages\n 18. {brew-cask}: Number of brew-cask packages\n 19. {macports}: Number of macports packages\n 20. {scoop-user}: Number of scoop-user packages\n 21. {scoop-global}: Number of scoop-global packages\n 22. {choco}: Number of choco packages\n 23. {pkgtool}: Number of pkgtool packages\n 24. {paludis}: Number of paludis packages\n 25. {winget}: Number of winget packages\n 26. {opkg}: Number of opkg packages\n 27. {am-system}: Number of am-system packages\n 28. {sorcery}: Number of sorcery packages\n 29. {lpkg}: Number of lpkg packages\n 30. {lpkgbuild}: Number of lpkgbuild packages\n 31. {guix-system}: Number of guix-system packages\n 32. {guix-user}: Number of guix-user packages\n 33. {guix-home}: Number of guix-home packages\n 34. {linglong}: Number of linglong packages\n 35. {pacstall}: Number of pacstall packages\n 36. {mport}: Number of mport packages\n 37. {am-user}: Number of am-user (aka appman) packages\n 38. {pkgsrc}: Number of pkgsrc packages\n 39. {hpkg-system}: Number of hpkg-system packages\n 40. {hpkg-user}: Number of hpkg-user packages\n 41. {pisi}: Number of pisi packages\n 42. {soar}: Number of soar packages\n 43. {kiss}: Number of kiss packages\n 44. {moss}: Number of moss packages\n 45. {nix-all}: Total number of all nix packages\n 46. {flatpak-all}: Total number of all flatpak app packages\n 47. {brew-all}: Total number of all brew packages\n 48. {guix-all}: Total number of all guix packages\n 49. {hpkg-all}: Total number of all hpkg packages",
"type": "string"
},
"physicaldiskFormat": {
@@ -485,7 +498,7 @@
"type": "string"
},
"titleFormat": {
"description": "Output format of the module `Title`. See Wiki for formatting syntax\n 1. {user-name}: User name\n 2. {host-name}: Host name\n 3. {home-dir}: Home directory\n 4. {exe-path}: Executable path of current process\n 5. {user-shell}: User's default shell\n 6. {user-name-colored}: User name (colored)\n 7. {at-symbol-colored}: @ symbol (colored)\n 8. {host-name-colored}: Host name (colored)\n 9. {full-user-name}: Full user name",
"description": "Output format of the module `Title`. See Wiki for formatting syntax\n 1. {user-name}: User name\n 2. {host-name}: Host name\n 3. {home-dir}: Home directory\n 4. {exe-path}: Executable path of current process\n 5. {user-shell}: User's default shell\n 6. {user-name-colored}: User name (colored)\n 7. {at-symbol-colored}: @ symbol (colored)\n 8. {host-name-colored}: Host name (colored)\n 9. {full-user-name}: Full user name\n 10. {user-id}: UID (*nix) / SID (Windows)\n 11. {pid}: PID of current process\n 12. {cwd}: CWD with home dir replaced by `~`",
"type": "string"
},
"themeFormat": {
@@ -533,7 +546,7 @@
"type": "string"
},
"zpoolFormat": {
"description": "Output format of the module `Zpool`. See Wiki for formatting syntax\n 1. {name}: Zpool name\n 2. {state}: Zpool state\n 3. {used}: Size used\n 4. {total}: Size total\n 5. {used-percentage}: Size percentage num\n 6. {fragmentation-percentage}: Fragmentation percentage num\n 7. {used-percentage-bar}: Size percentage bar\n 8. {fragmentation-percentage-bar}: Fragmentation percentage bar",
"description": "Output format of the module `Zpool`. See Wiki for formatting syntax\n 1. {name}: Zpool name\n 2. {guid}: Zpool guid\n 3. {state}: Zpool state\n 4. {used}: Size used\n 5. {allocated}: Size allocated\n 6. {total}: Size total\n 7. {used-percentage}: Size used percentage num\n 8. {allocated-percentage}: Size allocated percentage num\n 9. {fragmentation-percentage}: Fragmentation percentage num\n 10. {used-percentage-bar}: Size used percentage bar\n 11. {allocated-percentage-bar}: Size allocated percentage bar\n 12. {fragmentation-percentage-bar}: Fragmentation percentage bar\n 13. {is-readonly}: Is read-only",
"type": "string"
}
},
@@ -995,7 +1008,7 @@
},
"type": {
"type": "string",
"description": "Set whether to show icon before string keys",
"description": "Set whether to show builtin icon before string keys",
"oneOf": [
{
"const": "none",
@@ -1007,11 +1020,31 @@
},
{
"const": "icon",
"description": "Show icon keys (requires newest nerd font)"
"description": "Show builtin icon (requires newest nerd font)"
},
{
"const": "both",
"description": "Show both icon and string keys"
"description": "Show both icon and string keys (alias of `both-1`)"
},
{
"const": "both-0",
"description": "Show both icon and string with no spaces between them"
},
{
"const": "both-1",
"description": "Show both icon and string with a space between them"
},
{
"const": "both-2",
"description": "Show both icon and string with 2 spaces between them"
},
{
"const": "both-3",
"description": "Show both icon and string with 3 spaces between them"
},
{
"const": "both-4",
"description": "Show both icon and string with 4 spaces between them"
}
],
"default": "string"
@@ -1277,10 +1310,19 @@
"description": "Set how frequency values should be displayed",
"properties": {
"ndigits": {
"type": "integer",
"description": "Set the number of digits to keep after the decimal point when formatting frequency values\nA positive value will show the frequency in GHz with decimal\n-1 will show the frequency in MHz",
"minimum": -1,
"maximum": 9,
"description": "Set the number of decimal places to display when formatting frequency values",
"oneOf": [
{
"type": "integer",
"minimum": 0,
"maximum": 9,
"description": "Integer value displays the frequency in GHz with specified decimal places"
},
{
"type": "null",
"description": "Null value display the frequency as integer MHz"
}
],
"default": 2
},
"spaceBeforeUnit": {
@@ -1320,6 +1362,28 @@
"description": "The number of digits will be automatically determined based on the value"
}
],
"default": 2
},
"trailingZeros": {
"description": "Set when to keep trailing zeros",
"oneOf": [
{
"type": "null",
"description": "Same as `default`"
},
{
"const": "default",
"description": "Use the behavior defined internally"
},
{
"const": "always",
"description": "Always keep trailing zeros"
},
{
"const": "never",
"description": "Never keep trailing zeros"
}
],
"default": null
}
}
@@ -1457,7 +1521,7 @@
"description": "Print battery capacity, status, etc"
},
"useSetupApi": {
"description": "Set if `SetupAPI` should be used on Windows to detect battery info, which supports multi batteries, but slower. Windows only",
"description": "Set if `CM API` should be used on Windows to detect battery info, which supports multi batteries, but slower. Windows only",
"type": "boolean",
"default": false
},
@@ -1816,6 +1880,10 @@
"temp": {
"$ref": "#/$defs/temperature"
},
"tempSensor": {
"description": "Set the temperature sensor to use for CPU temperature detection\n* Linux: `hwmon` or `thermal` path name (eg. `hwmon0`, `thermal_zone0)`\n* macOS: SMC sensor key (eg. `Tp01`)\n* Windows: thermal zone key (eg. `\\_TZ.CPUZ`)\n* FreeBSD: sysctl key (eg. `dev.cpu.0.temperature`)\n* NetBSD: sysmon sensor key (eg. `coretemp0`)",
"type": "string"
},
"showPeCoreCount": {
"description": "Detect and display CPU frequency of different core types (eg. Pcore and Ecore) if supported",
"type": "boolean",
@@ -1931,7 +1999,7 @@
"additionalProperties": false,
"properties": {
"type": {
"description": "Print some colored blocks",
"description": "Display the terminal's 16-color palette",
"const": "colors"
},
"symbol": {
@@ -2037,6 +2105,21 @@
"description": "Set the command text to be executed",
"type": "string"
},
"useStdErr": {
"description": "Set if stderr should be used instead of stdout for command output",
"type": "boolean",
"default": false
},
"parallel": {
"description": "Set if the command should be executed in parallel with other commands\nImprove performance when using multiple commands, but may cause issues with some commands",
"type": "boolean",
"default": true
},
"splitLines": {
"description": "Set if the command output should be split into multiple lines",
"type": "boolean",
"default": false
},
"key": {
"$ref": "#/$defs/key"
},
@@ -2263,17 +2346,60 @@
"const": "disk"
},
"folders": {
"type": "string",
"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"
"description": "A list of folder paths for the disk output\nDefault: auto detection using mount-points\nThis option overrides other `show*` options",
"oneOf": [
{
"type": "string",
"description": "A colon (semicolon on Windows) separated list of folder paths to get disk usage from",
"default": "/"
},
{
"type": "array",
"description": "An array of folder paths to get disk usage from",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
}
]
},
"hideFolders": {
"type": "string",
"description": "A colon (semicolon on Windows) separated list of folder paths to hide from the disk output",
"default": "/efi:/boot:/boot/efi:/boot/firmware"
"description": "A list of folder paths (or glob patterns) to hide from the disk output",
"oneOf": [
{
"type": "string",
"description": "A colon (semicolon on Windows) separated list of folder paths to hide from the disk output"
},
{
"type": "array",
"description": "An array of folder paths to hide from the disk output",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
}
],
"default": "/efi:/boot:/boot/*"
},
"hideFS": {
"type": "string",
"description": "A colon separated file systems to hide from the disk output"
"description": "A list of file systems to hide from the disk output",
"oneOf": [
{
"type": "string",
"description": "A colon separated list of file systems to hide from the disk output"
},
{
"type": "array",
"description": "An array of file systems to hide from the disk output",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
}
]
},
"showRegular": {
"type": "boolean",
@@ -2392,11 +2518,6 @@
"const": "de",
"description": "Print desktop environment name"
},
"slowVersionDetection": {
"type": "boolean",
"description": "Set if DE version should be detected with slow operations.\nShould be unnecessary for most cases.\nThis is only used as a fallback method. Please file a bug report if you encounter any issues.",
"default": false
},
"key": {
"$ref": "#/$defs/key"
},
@@ -2549,6 +2670,15 @@
"const": "gamepad",
"description": "List connected gamepads"
},
"ignores": {
"type": "array",
"description": "An array of case-insensitive device name prefixes to ignore",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
},
"percent": {
"$ref": "#/$defs/percent"
},
@@ -2808,6 +2938,15 @@
"const": "keyboard",
"description": "List (connected) keyboards"
},
"ignores": {
"type": "array",
"description": "An array of case-insensitive device name prefixes to ignore",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
},
"key": {
"$ref": "#/$defs/key"
},
@@ -2820,8 +2959,11 @@
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/memoryFormat"
"$ref": "#/$defs/keyboardFormat"
},
"condition": {
"$ref": "#/$defs/conditions"
@@ -2876,7 +3018,32 @@
},
"showIpv6": {
"description": "Show IPv6 addresses",
"type": "boolean",
"oneOf": [
{
"const": true,
"description": "Show the most useful IPv6 addresses"
},
{
"const": false,
"description": "Do not show IPv6 addresses"
},
{
"const": "gua",
"description": "Show only global unicast IPv6 addresses (2000::/3)"
},
{
"const": "ula",
"description": "Show only unique local IPv6 addresses (fc00::/7)"
},
{
"const": "lla",
"description": "Show only link-local IPv6 addresses (fe80::/10)"
},
{
"const": "unknown",
"description": "Show only IPv6 addresses that are not gua, ula or lla"
}
],
"default": false
},
"showSpeed": {
@@ -3030,6 +3197,20 @@
}
}
},
{
"title": "Logo",
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"const": "logo",
"description": "Query built-in logo for JSON output"
},
"condition": {
"$ref": "#/$defs/conditions"
}
}
},
{
"title": "Media",
"type": "object",
@@ -3106,6 +3287,15 @@
"const": "mouse",
"description": "List connected mouses"
},
"ignores": {
"type": "array",
"description": "An array of case-insensitive device name prefixes to ignore",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
},
"key": {
"$ref": "#/$defs/key"
},
@@ -3118,8 +3308,11 @@
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/memoryFormat"
"$ref": "#/$defs/mouseFormat"
},
"condition": {
"$ref": "#/$defs/conditions"
@@ -3643,8 +3836,8 @@
"description": "Set the color of the separator line",
"$ref": "#/$defs/outputColor"
},
"length": {
"description": "Set the length of the separator line, or 0 to auto-detect",
"times": {
"description": "Set the times of separator string to repeat, or 0 to auto-detect",
"type": "integer",
"minimum": 0,
"default": 0
@@ -4289,7 +4482,7 @@
"detectPlugin": {
"description": "Set if window manager plugin should be detected on supported platforms",
"type": "boolean",
"default": false
"default": true
},
"key": {
"$ref": "#/$defs/key"
+1
View File
@@ -109,6 +109,7 @@
},
"tpm",
"version",
"logo",
"break",
"colors"
]
+1 -1
View File
@@ -1,4 +1,4 @@
// Load with --load-config examples/2.jsonc
// Load with --config examples/2.jsonc
// Note that you must replace the image path to an existing image to display it.
{
+1 -1
View File
@@ -1,4 +1,4 @@
// Load with --load-config examples/2.jsonc
// Load with --config examples/2.jsonc
// Note that you must replace the image path to an existing image to display it.
{
+52 -51
View File
@@ -9,25 +9,26 @@
// Constants are reusable strings referenced by {$1}, {$2}, etc.
// These contain ANSI escape codes for cursor positioning
"constants": [
"──────────────────────────────────────────────", // {$1} - horizontal line for borders
"──────────────────────────────────────────────", // {$1} - horizontal line for inner borders
"\u001b[47D", // {$2} - move cursor left 47 columns
"\u001b[47C", // {$3} - move cursor right 47 columns
"\u001b[46C" // {$4} - move cursor right 46 columns
"\u001b[46C", // {$4} - move cursor right 46 columns
"══════════════════════════════════════════════" // {$5} - horizontal line for outer borders
],
"brightColor": false
},
"modules": [
{
"type": "version",
"key": "┌───────────────┬─{$1}┐\u001b[41D",
"key": "╔═══════════════╦═{$5}╗\u001b[41D",
"format": "\u001b[1m{#keys} {1} - {2} "
},
{
"type": "os",
// Key format breakdown for OS module:
// " {icon} \u001b[s{sysname}\u001b[u\u001b[10C│{$3}{$2}"
// " {icon} \u001b[s{sysname}\u001b[u\u001b[10C│{$3}{$2}"
//
// - Left border of key block
// - Left border of key block
// {icon} - OS icon (defined internally by fastfetch)
// \u001b[s - ANSI escape: save cursor position (ESC[s)
// {sysname} - Format variable: system name (e.g., "Linux", "Darwin")
@@ -36,28 +37,28 @@
// \u001b[10C - ANSI escape: move cursor right 10 columns (ESC[10C)
// │ - Right border of key block (always 10 columns from left border)
// {$3} - Reference to constants[2]: move cursor right 47 columns
// - Right border of value block
// - Right border of value block
// {$2} - Reference to constants[1]: move cursor left 47 columns
//
// This creates a fixed-width layout where the key block is exactly 10 columns wide,
// regardless of the actual content length. The cursor manipulation ensures proper
// alignment for the table-like structure.
"key": " {icon} \u001b[s{sysname}\u001b[u\u001b[10C{$3}{$2}"
"key": " {icon} \u001b[s{sysname}\u001b[u\u001b[10C{$3}{$2}"
},
{
"type": "datetime",
"key": " {icon} Fetched {$3}{$2}",
"key": " {icon} Fetched {$3}{$2}",
"format": "{year}-{month-pretty}-{day-pretty} {hour-pretty}:{minute-pretty}:{second-pretty} {timezone-name}"
},
{
"type": "locale",
"key": " {icon} Locale {$3}{$2}"
"key": " {icon} Locale {$3}{$2}"
},
// Hardware section with cyan color theme
{
"type": "custom",
"key": "{#cyan}┌──────────────┬{$1}┐{#keys}\u001b[37D",
"key": "{#cyan}┌──────────────┬{$1}┐{#keys}\u001b[37D",
"format": "{#bright_cyan} Hardware "
},
{
@@ -66,113 +67,113 @@
// │{#cyan}│ - Left border with cyan color
// {icon} - Chassis icon
// Chassis - Fixed label text
// │{$4}│{#keys}{$2} - Positioning and borders for value area
"key": "{#cyan}│ {icon} Chassis │{$4}│{#keys}{$2}"
// │{$4}│{#keys}{$2} - Positioning and borders for value area
"key": "{#cyan}│ {icon} Chassis │{$4}│{#keys}{$2}"
},
{
"type": "memory",
"key": "{#cyan}│ {icon} RAM │{$4}│{#keys}{$2}"
"key": "{#cyan}│ {icon} RAM │{$4}│{#keys}{$2}"
},
{
"type": "swap",
"key": "{#cyan}│ {icon} SWAP │{$4}│{#keys}{$2}"
"key": "{#cyan}│ {icon} SWAP │{$4}│{#keys}{$2}"
},
{
"type": "cpu",
"key": "{#cyan}│ {icon} CPU │{$4}│{#keys}{$2}",
"key": "{#cyan}│ {icon} CPU │{$4}│{#keys}{$2}",
"showPeCoreCount": true
},
{
"type": "gpu",
"key": "{#cyan}│ {icon} GPU │{$4}│{#keys}{$2}"
"key": "{#cyan}│ {icon} GPU │{$4}│{#keys}{$2}"
},
{
"type": "disk",
"key": "{#cyan}│ {icon} Disk │{$4}│{#keys}{$2}",
"key": "{#cyan}│ {icon} Disk │{$4}│{#keys}{$2}",
"format": "{size-used} \/ {size-total} ({size-percentage}) - {filesystem}",
},
{
"type": "battery",
"key": "{#cyan}│ {icon} Battery │{$4}│{#keys}{$2}"
"key": "{#cyan}│ {icon} Battery │{$4}│{#keys}{$2}"
},
{
"type": "custom",
"key": "{#cyan}└──────────────┴{$1}┘{#keys}",
"key": "{#cyan}└──────────────┴{$1}┘{#keys}",
"format": ""
},
// Desktop section with green color theme
{
"type": "custom",
"key": "{#green}┌──────────────┬{$1}┐{#keys}\u001b[37D",
"key": "{#green}┌──────────────┬{$1}┐{#keys}\u001b[37D",
"format": "{#bright_green} Desktop "
},
{
"type": "de",
"key": "{#green}│ {icon} Desktop │{$4}│{#keys}{$2}"
"key": "{#green}│ {icon} Desktop │{$4}│{#keys}{$2}"
},
{
"type": "wm",
"key": "{#green}│ {icon} Session │{$4}│{#keys}{$2}"
"key": "{#green}│ {icon} Session │{$4}│{#keys}{$2}"
},
{
"type": "display",
"key": "{#green}│ {icon} Display │{$4}│{#keys}{$2}",
"key": "{#green}│ {icon} Display │{$4}│{#keys}{$2}",
"compactType": "original-with-refresh-rate"
},
{
"type": "gpu",
"key": "{#green}│ {icon} G-Driver │{$4}│{#keys}{$2}",
"key": "{#green}│ {icon} G-Driver │{$4}│{#keys}{$2}",
"format": "{driver}"
},
{
"type": "custom",
"key": "{#green}└──────────────┴{$1}┘{#keys}",
"key": "{#green}└──────────────┴{$1}┘{#keys}",
"format": ""
},
// Terminal section with yellow color theme
{
"type": "custom",
"key": "{#yellow}┌──────────────┬{$1}┐{#keys}\u001b[37D",
"key": "{#yellow}┌──────────────┬{$1}┐{#keys}\u001b[37D",
"format": "{#bright_yellow} Terminal "
},
{
"type": "shell",
"key": "{#yellow}│ {icon} Shell │{$4}│{#keys}{$2}"
"key": "{#yellow}│ {icon} Shell │{$4}│{#keys}{$2}"
},
{
"type": "terminal",
"key": "{#yellow}│ {icon} Terminal │{$4}│{#keys}{$2}"
"key": "{#yellow}│ {icon} Terminal │{$4}│{#keys}{$2}"
},
{
"type": "terminalfont",
"key": "{#yellow}│ {icon} Term Font │{$4}│{#keys}{$2}"
"key": "{#yellow}│ {icon} Term Font │{$4}│{#keys}{$2}"
},
{
"type": "terminaltheme",
"key": "{#yellow}│ {icon} Colors │{$4}│{#keys}{$2}"
"key": "{#yellow}│ {icon} Colors │{$4}│{#keys}{$2}"
},
{
"type": "packages",
"key": "{#yellow}│ {icon} Packages │{$4}│{#keys}{$2}"
"key": "{#yellow}│ {icon} Packages │{$4}│{#keys}{$2}"
},
{
"type": "custom",
"key": "{#yellow}└──────────────┴{$1}┘{#keys}",
"key": "{#yellow}└──────────────┴{$1}┘{#keys}",
"format": ""
},
// Development section with red color theme
{
"type": "custom",
"key": "{#red}┌──────────────┬{$1}┐{#keys}\u001b[39D",
"key": "{#red}┌──────────────┬{$1}┐{#keys}\u001b[39D",
"format": "{#bright_red} Development "
},
{
"type": "command",
"keyIcon": "", // Custom icon override
"key": "{#red}│ {icon} Rust │{$4}│{#keys}{$2}",
"key": "{#red}│ {icon} Rust │{$4}│{#keys}{$2}",
"text": "rustc --version",
"format": "rustc {~6,13}" // Print 6th to 13th characters (version number)
},
@@ -182,8 +183,8 @@
"!system": "Windows" // Posix version
},
"keyIcon": "",
"key": "{#red}│ {icon} Clang │{$4}│{#keys}{$2}",
"text": "clang --version | head -1 | awk '{print $NF}'",
"key": "{#red}│ {icon} Clang │{$4}│{#keys}{$2}",
"text": "clang --version | sed -n 's/.*version \\([0-9][0-9.]*\\).*/\\1/p'",
"format": "clang {}"
},
{
@@ -192,67 +193,67 @@
"system": "Windows" // Windows version
},
"keyIcon": "",
"key": "{#red}│ {icon} Clang │{$4}│{#keys}{$2}",
"key": "{#red}│ {icon} Clang │{$4}│{#keys}{$2}",
"text": "clang --version | findstr version", // Finds the line with "version"
"format": "clang {~-6}" // Prints the last 6 characters (version number)
},
{
"type": "command",
"keyIcon": "",
"key": "{#red}│ {icon} NodeJS │{$4}│{#keys}{$2}",
"key": "{#red}│ {icon} NodeJS │{$4}│{#keys}{$2}",
"text": "node --version",
"format": "node {~1}" // {~1} removes first character (v)
},
{
"type": "command",
"keyIcon": "",
"key": "{#red}│ {icon} Go │{$4}│{#keys}{$2}",
"key": "{#red}│ {icon} Go │{$4}│{#keys}{$2}",
"text": "go version | cut -d' ' -f3",
"format": "go {~2}" // {~2} removes first 2 characters (go)
},
{
"type": "command",
"keyIcon": "",
"key": "{#red}│ {icon} Zig │{$4}│{#keys}{$2}",
"key": "{#red}│ {icon} Zig │{$4}│{#keys}{$2}",
"text": "zig version",
"format": "zig {}"
},
{
"type": "editor",
"key": "{#red}│ {icon} Editor │{$4}│{#keys}{$2}"
"key": "{#red}│ {icon} Editor │{$4}│{#keys}{$2}"
},
{
"type": "command",
"keyIcon": "󰊢",
"key": "{#red}│ {icon} Git │{$4}│{#keys}{$2}",
"key": "{#red}│ {icon} Git │{$4}│{#keys}{$2}",
"text": "git version",
"format": "git {~12}"
},
{
"type": "font",
"key": "{#red}│ {icon} Interface │{$4}│{#keys}{$2}"
"key": "{#red}│ {icon} Interface │{$4}│{#keys}{$2}"
},
{
"type": "custom",
"key": "{#red}└──────────────┴{$1}┘{#keys}",
"key": "{#red}└──────────────┴{$1}┘{#keys}",
"format": ""
},
// Uptime section with magenta color theme
{
"type": "custom",
"key": "{#magenta}┌──────────────┬{$1}┐{#keys}\u001b[36D",
"key": "{#magenta}┌──────────────┬{$1}┐{#keys}\u001b[36D",
"format": "{#bright_magenta} Uptime "
},
{
"type": "uptime",
"key": "{#magenta}│ {icon} Uptime │{$4}│{#keys}{$2}"
"key": "{#magenta}│ {icon} Uptime │{$4}│{#keys}{$2}"
},
{
"type": "users",
"myselfOnly": true, // Only show current user
"keyIcon": "",
"key": "{#magenta}│ {icon} Login │{$4}│{#keys}{$2}"
"key": "{#magenta}│ {icon} Login │{$4}│{#keys}{$2}"
},
{
"condition": { // Conditional module: only show on non-macOS
@@ -260,7 +261,7 @@
},
"type": "disk",
"keyIcon": "",
"key": "{#magenta}│ {icon} OS Age │{$4}│{#keys}{$2}",
"key": "{#magenta}│ {icon} OS Age │{$4}│{#keys}{$2}",
"folders": "/", // Check root filesystem
"format": "{create-time:10} [{days} days]" // Show creation time and age in days
},
@@ -270,18 +271,18 @@
},
"type": "disk",
"keyIcon": "",
"key": "{#magenta}│ {icon} OS Age │{$4}│{#keys}{$2}",
"key": "{#magenta}│ {icon} OS Age │{$4}│{#keys}{$2}",
"folders": "/System/Volumes/VM", // Work around for APFS on macOS
"format": "{create-time:10} [{days} days]"
},
{
"type": "custom",
"key": "{#magenta}└──────────────┴{$1}┘{#keys}",
"key": "{#magenta}└──────────────┴{$1}┘{#keys}",
"format": ""
},
{
"type": "custom",
"key": "└─────────────────{$1}┘", // Bottom border of the entire layout
"key": "╚═════════════════{$5}╝", // Bottom border of the entire layout
"format": ""
},
+1 -1
View File
@@ -1,6 +1,6 @@
// #1887
{
"$schema": "file:///Users/carter/fastfetch/doc/json_schema.json",
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": null,
"display": {
"constants": [
+1 -1
View File
@@ -1,4 +1,4 @@
// Load with --load-config examples/3.jsonc
// Load with --config examples/3.jsonc
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
+87
View File
@@ -0,0 +1,87 @@
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": null,
"display": {
"key": {
"type": "both",
"paddingLeft": 6,
"width": 17
}
},
"modules": [
{
"type": "custom",
"format": "|---------------------: {#1}Hardware{#} : ---------------------|"
},
"break",
{
"keyColor": "green",
"type": "host"
},
{
"keyColor": "green",
"type": "cpu"
},
{
"keyColor": "yellow",
"type": "memory"
},
{
"keyColor": "yellow",
"type": "swap"
},
{
"type": "custom",
"keyIcon": "",
"key": "Disks"
},
{
"type": "disk",
"key": " ",
"format": " [{mountpoint}] - {size-used} / {size-total} ({size-percentage})"
},
"break",
{
"type": "title",
"format": "|-------------------------------------------------------|\u001b[40D: {#1}{user-name} @ {host-name}{#} :"
},
"break",
{
"type": "os",
"keyColor": "cyan"
},
{
"type": "kernel",
"keyColor": "cyan"
},
{
"type": "packages",
"keyColor": "red",
"key": "Pkgs"
},
{
"type": "shell",
"keyColor": "red"
},
{
"type": "terminal",
"key": "Term",
"keyColor": "red"
},
{
"type": "locale",
"keyColor": "magenta"
},
"break",
{
"type": "custom",
"format": "|---------------------: {#1}Software{#} : ---------------------|"
},
"break",
{
"type": "colors",
"symbol": "circle",
"paddingLeft": 8
}
]
}
File diff suppressed because one or more lines are too long
+57
View File
@@ -0,0 +1,57 @@
// Inspired by microfetch
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": {
"type": "small"
},
"general": {
"detectVersion": false
},
"display": {
"separator": "  ",
"brightColor": false,
"key": {
"type": "both-2"
}
},
"modules": [
{
"type": "title",
"format": "{user-name-colored}{#light_red}@{host-name-colored} {#}{cwd}"
},
{
"type": "os",
"key": "System "
},
{
"type": "kernel",
"key": "Kernel "
},
{
"type": "shell",
"key": "Shell "
},
{
"type": "uptime",
"key": "Uptime "
},
{
"type": "wm",
"key": "Desktop "
},
{
"type": "memory",
"key": "Memory "
},
{
"type": "disk",
"key": "Storage (/) ",
"folders": "/"
},
{
"type": "colors",
"key": "Colors ",
"symbol": "circle"
}
]
}
+1 -1
View File
@@ -1,4 +1,4 @@
// Load with --load-config examples/4.jsonc
// Load with --config examples/4.jsonc
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
+1 -1
View File
@@ -1,4 +1,4 @@
// Load with --load-config examples/5.jsonc
// Load with --config examples/5.jsonc
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
+1 -1
View File
@@ -1,4 +1,4 @@
// Load with --load-config examples/2.jsonc
// Load with --config examples/2.jsonc
// Note that you must replace the image path to an existing image to display it.
{
+1 -1
View File
@@ -1,4 +1,4 @@
// Load with --load-config examples/2.jsonc
// Load with --config examples/2.jsonc
// Note that you must replace the image path to an existing image to display it.
{
-7
View File
@@ -1,7 +0,0 @@
{
"home": "https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c",
"license": "MIT compatible (embed in source)",
"version": "2007-05-26 (Unicode 5.0)",
"author": "Markus Kuhn",
"modified": "CarterLi"
}
-314
View File
@@ -1,314 +0,0 @@
/*
* This is an implementation of wcwidth() and wcswidth() (defined in
* IEEE Std 1002.1-2001) for Unicode.
*
* http://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html
* http://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html
*
* In fixed-width output devices, Latin characters all occupy a single
* "cell" position of equal width, whereas ideographic CJK characters
* occupy two such cells. Interoperability between terminal-line
* applications and (teletype-style) character terminals using the
* UTF-8 encoding requires agreement on which character should advance
* the cursor by how many cell positions. No established formal
* standards exist at present on which Unicode character shall occupy
* how many cell positions on character terminals. These routines are
* a first attempt of defining such behavior based on simple rules
* applied to data provided by the Unicode Consortium.
*
* For some graphical characters, the Unicode standard explicitly
* defines a character-cell width via the definition of the East Asian
* FullWidth (F), Wide (W), Half-width (H), and Narrow (Na) classes.
* In all these cases, there is no ambiguity about which width a
* terminal shall use. For characters in the East Asian Ambiguous (A)
* class, the width choice depends purely on a preference of backward
* compatibility with either historic CJK or Western practice.
* Choosing single-width for these characters is easy to justify as
* the appropriate long-term solution, as the CJK practice of
* displaying these characters as double-width comes from historic
* implementation simplicity (8-bit encoded characters were displayed
* single-width and 16-bit ones double-width, even for Greek,
* Cyrillic, etc.) and not any typographic considerations.
*
* Much less clear is the choice of width for the Not East Asian
* (Neutral) class. Existing practice does not dictate a width for any
* of these characters. It would nevertheless make sense
* typographically to allocate two character cells to characters such
* as for instance EM SPACE or VOLUME INTEGRAL, which cannot be
* represented adequately with a single-width glyph. The following
* routines at present merely assign a single-cell width to all
* neutral characters, in the interest of simplicity. This is not
* entirely satisfactory and should be reconsidered before
* establishing a formal standard in this area. At the moment, the
* decision which Not East Asian (Neutral) characters should be
* represented by double-width glyphs cannot yet be answered by
* applying a simple rule from the Unicode database content. Setting
* up a proper standard for the behavior of UTF-8 character terminals
* will require a careful analysis not only of each Unicode character,
* but also of each presentation form, something the author of these
* routines has avoided to do so far.
*
* http://www.unicode.org/unicode/reports/tr11/
*
* Markus Kuhn -- 2007-05-26 (Unicode 5.0)
*
* Permission to use, copy, modify, and distribute this software
* for any purpose and without fee is hereby granted. The author
* disclaims all warranties with regard to this software.
*
* Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
*/
#include <wchar.h>
struct interval {
int first;
int last;
};
/* auxiliary function for binary search in interval table */
static int bisearch(wchar_t ucs, const struct interval *table, int max) {
int min = 0;
int mid;
if (ucs < table[0].first || ucs > table[max].last)
return 0;
while (max >= min) {
mid = (min + max) / 2;
if (ucs > table[mid].last)
min = mid + 1;
else if (ucs < table[mid].first)
max = mid - 1;
else
return 1;
}
return 0;
}
/* The following two functions define the column width of an ISO 10646
* character as follows:
*
* - The null character (U+0000) has a column width of 0.
*
* - Other C0/C1 control characters and DEL will lead to a return
* value of -1.
*
* - Non-spacing and enclosing combining characters (general
* category code Mn or Me in the Unicode database) have a
* column width of 0.
*
* - SOFT HYPHEN (U+00AD) has a column width of 1.
*
* - Other format characters (general category code Cf in the Unicode
* database) and ZERO WIDTH SPACE (U+200B) have a column width of 0.
*
* - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF)
* have a column width of 0.
*
* - Spacing characters in the East Asian Wide (W) or East Asian
* Full-width (F) category as defined in Unicode Technical
* Report #11 have a column width of 2.
*
* - All remaining characters (including all printable
* ISO 8859-1 and WGL4 characters, Unicode control characters,
* etc.) have a column width of 1.
*
* This implementation assumes that wchar_t characters are encoded
* in ISO 10646.
*/
int mk_wcwidth(wchar_t ucs)
{
/* sorted list of non-overlapping intervals of non-spacing characters */
/* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */
static const struct interval combining[] = {
{ 0x0300, 0x036F }, { 0x0483, 0x0486 }, { 0x0488, 0x0489 },
{ 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 },
{ 0x05C4, 0x05C5 }, { 0x05C7, 0x05C7 }, { 0x0600, 0x0603 },
{ 0x0610, 0x0615 }, { 0x064B, 0x065E }, { 0x0670, 0x0670 },
{ 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED },
{ 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A },
{ 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x0901, 0x0902 },
{ 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D },
{ 0x0951, 0x0954 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 },
{ 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD },
{ 0x09E2, 0x09E3 }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C },
{ 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D },
{ 0x0A70, 0x0A71 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC },
{ 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD },
{ 0x0AE2, 0x0AE3 }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C },
{ 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, { 0x0B4D, 0x0B4D },
{ 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 },
{ 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 },
{ 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0CBC, 0x0CBC },
{ 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD },
{ 0x0CE2, 0x0CE3 }, { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D },
{ 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 },
{ 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E },
{ 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC },
{ 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 },
{ 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E },
{ 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 },
{ 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 },
{ 0x1032, 0x1032 }, { 0x1036, 0x1037 }, { 0x1039, 0x1039 },
{ 0x1058, 0x1059 }, { 0x1160, 0x11FF }, { 0x135F, 0x135F },
{ 0x1712, 0x1714 }, { 0x1732, 0x1734 }, { 0x1752, 0x1753 },
{ 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD },
{ 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD },
{ 0x180B, 0x180D }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 },
{ 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B },
{ 0x1A17, 0x1A18 }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 },
{ 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 },
{ 0x1B6B, 0x1B73 }, { 0x1DC0, 0x1DCA }, { 0x1DFE, 0x1DFF },
{ 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2063 },
{ 0x206A, 0x206F }, { 0x20D0, 0x20EF }, { 0x302A, 0x302F },
{ 0x3099, 0x309A }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B },
{ 0xA825, 0xA826 }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F },
{ 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB },
{ 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F },
{ 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 },
{ 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD },
{ 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F },
{ 0xE0100, 0xE01EF }
};
/* test for 8-bit control characters */
if (ucs == 0)
return 0;
if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))
return -1;
/* binary search in table of non-spacing characters */
if (bisearch(ucs, combining,
sizeof(combining) / sizeof(struct interval) - 1))
return 0;
/* if we arrive here, ucs is not a combining or C0/C1 control character */
return 1 +
(ucs >= 0x1100 &&
(ucs <= 0x115f || /* Hangul Jamo init. consonants */
ucs == 0x2329 || ucs == 0x232a ||
(ucs >= 0x2e80 && ucs <= 0xa4cf &&
ucs != 0x303f) || /* CJK ... Yi */
(ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */
(ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */
(ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */
(ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */
(ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */
(ucs >= 0xffe0 && ucs <= 0xffe6) ||
#ifndef _WIN32 // sizeof(wchar_t) == 2
(ucs >= 0x20000 && ucs <= 0x2fffd) ||
(ucs >= 0x30000 && ucs <= 0x3fffd) ||
#endif
0
));
}
int mk_wcswidth(const wchar_t *pwcs, size_t n)
{
int w, width = 0;
for (;*pwcs && n-- > 0; pwcs++)
if ((w = mk_wcwidth(*pwcs)) < 0)
return -1;
else
width += w;
return width;
}
/*
* The following functions are the same as mk_wcwidth() and
* mk_wcswidth(), except that spacing characters in the East Asian
* Ambiguous (A) category as defined in Unicode Technical Report #11
* have a column width of 2. This variant might be useful for users of
* CJK legacy encodings who want to migrate to UCS without changing
* the traditional terminal character-width behaviour. It is not
* otherwise recommended for general use.
*/
int mk_wcwidth_cjk(wchar_t ucs)
{
/* sorted list of non-overlapping intervals of East Asian Ambiguous
* characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */
static const struct interval ambiguous[] = {
{ 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 },
{ 0x00AA, 0x00AA }, { 0x00AE, 0x00AE }, { 0x00B0, 0x00B4 },
{ 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 },
{ 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 },
{ 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED },
{ 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA },
{ 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 },
{ 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B },
{ 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 },
{ 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 },
{ 0x0148, 0x014B }, { 0x014D, 0x014D }, { 0x0152, 0x0153 },
{ 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE },
{ 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 },
{ 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA },
{ 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 },
{ 0x02C4, 0x02C4 }, { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB },
{ 0x02CD, 0x02CD }, { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB },
{ 0x02DD, 0x02DD }, { 0x02DF, 0x02DF }, { 0x0391, 0x03A1 },
{ 0x03A3, 0x03A9 }, { 0x03B1, 0x03C1 }, { 0x03C3, 0x03C9 },
{ 0x0401, 0x0401 }, { 0x0410, 0x044F }, { 0x0451, 0x0451 },
{ 0x2010, 0x2010 }, { 0x2013, 0x2016 }, { 0x2018, 0x2019 },
{ 0x201C, 0x201D }, { 0x2020, 0x2022 }, { 0x2024, 0x2027 },
{ 0x2030, 0x2030 }, { 0x2032, 0x2033 }, { 0x2035, 0x2035 },
{ 0x203B, 0x203B }, { 0x203E, 0x203E }, { 0x2074, 0x2074 },
{ 0x207F, 0x207F }, { 0x2081, 0x2084 }, { 0x20AC, 0x20AC },
{ 0x2103, 0x2103 }, { 0x2105, 0x2105 }, { 0x2109, 0x2109 },
{ 0x2113, 0x2113 }, { 0x2116, 0x2116 }, { 0x2121, 0x2122 },
{ 0x2126, 0x2126 }, { 0x212B, 0x212B }, { 0x2153, 0x2154 },
{ 0x215B, 0x215E }, { 0x2160, 0x216B }, { 0x2170, 0x2179 },
{ 0x2190, 0x2199 }, { 0x21B8, 0x21B9 }, { 0x21D2, 0x21D2 },
{ 0x21D4, 0x21D4 }, { 0x21E7, 0x21E7 }, { 0x2200, 0x2200 },
{ 0x2202, 0x2203 }, { 0x2207, 0x2208 }, { 0x220B, 0x220B },
{ 0x220F, 0x220F }, { 0x2211, 0x2211 }, { 0x2215, 0x2215 },
{ 0x221A, 0x221A }, { 0x221D, 0x2220 }, { 0x2223, 0x2223 },
{ 0x2225, 0x2225 }, { 0x2227, 0x222C }, { 0x222E, 0x222E },
{ 0x2234, 0x2237 }, { 0x223C, 0x223D }, { 0x2248, 0x2248 },
{ 0x224C, 0x224C }, { 0x2252, 0x2252 }, { 0x2260, 0x2261 },
{ 0x2264, 0x2267 }, { 0x226A, 0x226B }, { 0x226E, 0x226F },
{ 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 },
{ 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF },
{ 0x2312, 0x2312 }, { 0x2460, 0x24E9 }, { 0x24EB, 0x254B },
{ 0x2550, 0x2573 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 },
{ 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 },
{ 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 },
{ 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 },
{ 0x25E2, 0x25E5 }, { 0x25EF, 0x25EF }, { 0x2605, 0x2606 },
{ 0x2609, 0x2609 }, { 0x260E, 0x260F }, { 0x2614, 0x2615 },
{ 0x261C, 0x261C }, { 0x261E, 0x261E }, { 0x2640, 0x2640 },
{ 0x2642, 0x2642 }, { 0x2660, 0x2661 }, { 0x2663, 0x2665 },
{ 0x2667, 0x266A }, { 0x266C, 0x266D }, { 0x266F, 0x266F },
{ 0x273D, 0x273D }, { 0x2776, 0x277F }, { 0xE000, 0xF8FF },
{ 0xFFFD, 0xFFFD }, { 0xF0000, 0xFFFFD }, { 0x100000, 0x10FFFD }
};
/* binary search in table of non-spacing characters */
if (bisearch(ucs, ambiguous,
sizeof(ambiguous) / sizeof(struct interval) - 1))
return 2;
return mk_wcwidth(ucs);
}
int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n)
{
int w, width = 0;
for (;*pwcs && n-- > 0; pwcs++)
if ((w = mk_wcwidth_cjk(*pwcs)) < 0)
return -1;
else
width += w;
return width;
}
+6
View File
@@ -0,0 +1,6 @@
{
"home": "https://github.com/ridiculousfish/widecharwidth",
"license": "Public domain",
"version": "Unicode 17",
"author": "ridiculousfish"
}
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,6 +1,6 @@
{
"home": "https://github.com/ibireme/yyjson",
"license": "MIT ( embed in source )",
"version": "0.11.1",
"version": "0.12.0",
"author": "ibireme"
}
+4196 -3943
View File
File diff suppressed because it is too large Load Diff
+174 -116
View File
@@ -32,7 +32,7 @@
/*==============================================================================
* Header Files
* MARK: - Header Files
*============================================================================*/
#include <stdio.h>
@@ -45,7 +45,7 @@
/*==============================================================================
* Compile-time Options
* MARK: - Compile-time Options
*============================================================================*/
/*
@@ -89,14 +89,8 @@
#endif
/*
Define as 1 to disable non-standard JSON features support at compile-time:
- YYJSON_READ_ALLOW_INF_AND_NAN
- YYJSON_READ_ALLOW_COMMENTS
- YYJSON_READ_ALLOW_TRAILING_COMMAS
- YYJSON_READ_ALLOW_INVALID_UNICODE
- YYJSON_READ_ALLOW_BOM
- YYJSON_WRITE_ALLOW_INF_AND_NAN
- YYJSON_WRITE_ALLOW_INVALID_UNICODE
Define as 1 to disable non-standard JSON features support at compile-time,
such as YYJSON_READ_ALLOW_XXX and YYJSON_WRITE_ALLOW_XXX.
This reduces binary size by about 10%, and slightly improves performance.
*/
@@ -151,7 +145,7 @@
/*==============================================================================
* Compiler Macros
* MARK: - Compiler Macros
*============================================================================*/
/** compiler version (MSVC) */
@@ -179,8 +173,10 @@
#endif
/** real gcc check */
#if !defined(__clang__) && !defined(__INTEL_COMPILER) && !defined(__ICC) && \
defined(__GNUC__)
#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \
!defined(__clang__) && !defined(__llvm__) && \
!defined(__INTEL_COMPILER) && !defined(__ICC) && \
!defined(__NVCC__) && !defined(__PGI) && !defined(__TINYC__)
# define YYJSON_IS_REAL_GCC 1
#else
# define YYJSON_IS_REAL_GCC 0
@@ -465,7 +461,7 @@
/*==============================================================================
* Compile Hint Begin
* MARK: - Compile Hint Begin
*============================================================================*/
/* extern "C" begin */
@@ -492,23 +488,23 @@ extern "C" {
/*==============================================================================
* Version
* MARK: - Version
*============================================================================*/
/** The major version of yyjson. */
#define YYJSON_VERSION_MAJOR 0
/** The minor version of yyjson. */
#define YYJSON_VERSION_MINOR 11
#define YYJSON_VERSION_MINOR 12
/** The patch version of yyjson. */
#define YYJSON_VERSION_PATCH 1
#define YYJSON_VERSION_PATCH 0
/** The version of yyjson in hex: `(major << 16) | (minor << 8) | (patch)`. */
#define YYJSON_VERSION_HEX 0x000B01
#define YYJSON_VERSION_HEX 0x000C00
/** The version string of yyjson. */
#define YYJSON_VERSION_STRING "0.11.1"
#define YYJSON_VERSION_STRING "0.12.0"
/** The version of yyjson in hex, same as `YYJSON_VERSION_HEX`. */
yyjson_api uint32_t yyjson_version(void);
@@ -516,7 +512,7 @@ yyjson_api uint32_t yyjson_version(void);
/*==============================================================================
* JSON Types
* MARK: - JSON Types
*============================================================================*/
/** Type of a JSON value (3 bit). */
@@ -578,7 +574,7 @@ typedef uint8_t yyjson_subtype;
/*==============================================================================
* Allocator
* MARK: - Allocator
*============================================================================*/
/**
@@ -662,7 +658,7 @@ yyjson_api void yyjson_alc_dyn_free(yyjson_alc *alc);
/*==============================================================================
* Text Locating
* MARK: - Text Locating
*============================================================================*/
/**
@@ -686,7 +682,7 @@ yyjson_api bool yyjson_locate_pos(const char *str, size_t len, size_t pos,
/*==============================================================================
* JSON Structure
* MARK: - JSON Structure
*============================================================================*/
/**
@@ -720,7 +716,7 @@ typedef struct yyjson_mut_val yyjson_mut_val;
/*==============================================================================
* JSON Reader API
* MARK: - JSON Reader API
*============================================================================*/
/** Run-time options for JSON reader. */
@@ -734,7 +730,7 @@ typedef uint32_t yyjson_read_flag;
- Report error if double number is infinity.
- Report error if string contains invalid UTF-8 character or BOM.
- Report error on trailing commas, comments, inf and nan literals. */
static const yyjson_read_flag YYJSON_READ_NOFLAG = 0;
static const yyjson_read_flag YYJSON_READ_NOFLAG = 0;
/** Read the input data in-situ.
This option allows the reader to modify and use input data to store string
@@ -742,27 +738,27 @@ static const yyjson_read_flag YYJSON_READ_NOFLAG = 0;
The caller should hold the input data before free the document.
The input data must be padded by at least `YYJSON_PADDING_SIZE` bytes.
For example: `[1,2]` should be `[1,2]\0\0\0\0`, input length should be 5. */
static const yyjson_read_flag YYJSON_READ_INSITU = 1 << 0;
static const yyjson_read_flag YYJSON_READ_INSITU = 1 << 0;
/** Stop when done instead of issuing an error if there's additional content
after a JSON document. This option may be used to parse small pieces of JSON
in larger data, such as `NDJSON`. */
static const yyjson_read_flag YYJSON_READ_STOP_WHEN_DONE = 1 << 1;
static const yyjson_read_flag YYJSON_READ_STOP_WHEN_DONE = 1 << 1;
/** Allow single trailing comma at the end of an object or array,
such as `[1,2,3,]`, `{"a":1,"b":2,}` (non-standard). */
static const yyjson_read_flag YYJSON_READ_ALLOW_TRAILING_COMMAS = 1 << 2;
static const yyjson_read_flag YYJSON_READ_ALLOW_TRAILING_COMMAS = 1 << 2;
/** Allow C-style single line and multiple line comments (non-standard). */
static const yyjson_read_flag YYJSON_READ_ALLOW_COMMENTS = 1 << 3;
/** Allow C-style single-line and mult-line comments (non-standard). */
static const yyjson_read_flag YYJSON_READ_ALLOW_COMMENTS = 1 << 3;
/** Allow inf/nan number and literal, case-insensitive,
such as 1e999, NaN, inf, -Infinity (non-standard). */
static const yyjson_read_flag YYJSON_READ_ALLOW_INF_AND_NAN = 1 << 4;
static const yyjson_read_flag YYJSON_READ_ALLOW_INF_AND_NAN = 1 << 4;
/** Read all numbers as raw strings (value with `YYJSON_TYPE_RAW` type),
inf/nan literal is also read as raw with `ALLOW_INF_AND_NAN` flag. */
static const yyjson_read_flag YYJSON_READ_NUMBER_AS_RAW = 1 << 5;
static const yyjson_read_flag YYJSON_READ_NUMBER_AS_RAW = 1 << 5;
/** Allow reading invalid unicode when parsing string values (non-standard).
Invalid characters will be allowed to appear in the string values, but
@@ -772,16 +768,62 @@ static const yyjson_read_flag YYJSON_READ_NUMBER_AS_RAW = 1 << 5;
@warning Strings in JSON values may contain incorrect encoding when this
option is used, you need to handle these strings carefully to avoid security
risks. */
static const yyjson_read_flag YYJSON_READ_ALLOW_INVALID_UNICODE = 1 << 6;
static const yyjson_read_flag YYJSON_READ_ALLOW_INVALID_UNICODE = 1 << 6;
/** Read big numbers as raw strings. These big numbers include integers that
cannot be represented by `int64_t` and `uint64_t`, and floating-point
numbers that cannot be represented by finite `double`.
The flag will be overridden by `YYJSON_READ_NUMBER_AS_RAW` flag. */
static const yyjson_read_flag YYJSON_READ_BIGNUM_AS_RAW = 1 << 7;
static const yyjson_read_flag YYJSON_READ_BIGNUM_AS_RAW = 1 << 7;
/** Allow UTF-8 BOM and skip it before parsing if any (non-standard). */
static const yyjson_read_flag YYJSON_READ_ALLOW_BOM = 1 << 8;
static const yyjson_read_flag YYJSON_READ_ALLOW_BOM = 1 << 8;
/** Allow extended number formats (non-standard):
- Hexadecimal numbers, such as `0x7B`.
- Numbers with leading or trailing decimal point, such as `.123`, `123.`.
- Numbers with a leading plus sign, such as `+123`. */
static const yyjson_read_flag YYJSON_READ_ALLOW_EXT_NUMBER = 1 << 9;
/** Allow extended escape sequences in strings (non-standard):
- Additional escapes: `\a`, `\e`, `\v`, ``\'``, `\?`, `\0`.
- Hex escapes: `\xNN`, such as `\x7B`.
- Line continuation: backslash followed by line terminator sequences.
- Unknown escape: if backslash is followed by an unsupported character,
the backslash will be removed and the character will be kept as-is.
However, `\1`-`\9` will still trigger an error. */
static const yyjson_read_flag YYJSON_READ_ALLOW_EXT_ESCAPE = 1 << 10;
/** Allow extended whitespace characters (non-standard):
- Vertical tab `\v` and form feed `\f`.
- Line separator `\u2028` and paragraph separator `\u2029`.
- Non-breaking space `\xA0`.
- Byte order mark: `\uFEFF`.
- Other Unicode characters in the Zs (Separator, space) category. */
static const yyjson_read_flag YYJSON_READ_ALLOW_EXT_WHITESPACE = 1 << 11;
/** Allow strings enclosed in single quotes (non-standard), such as ``'ab'``. */
static const yyjson_read_flag YYJSON_READ_ALLOW_SINGLE_QUOTED_STR = 1 << 12;
/** Allow object keys without quotes (non-standard), such as `{a:1,b:2}`.
This extends the ECMAScript IdentifierName rule by allowing any
non-whitespace character with code point above `U+007F`. */
static const yyjson_read_flag YYJSON_READ_ALLOW_UNQUOTED_KEY = 1 << 13;
/** Allow JSON5 format, see: [https://json5.org].
This flag supports all JSON5 features with some additional extensions:
- Accepts more escape sequences than JSON5 (e.g. `\a`, `\e`).
- Unquoted keys are not limited to ECMAScript IdentifierName.
- Allow case-insensitive `NaN`, `Inf` and `Infinity` literals. */
static const yyjson_read_flag YYJSON_READ_JSON5 =
(1 << 2) | /* YYJSON_READ_ALLOW_TRAILING_COMMAS */
(1 << 3) | /* YYJSON_READ_ALLOW_COMMENTS */
(1 << 4) | /* YYJSON_READ_ALLOW_INF_AND_NAN */
(1 << 9) | /* YYJSON_READ_ALLOW_EXT_NUMBER */
(1 << 10) | /* YYJSON_READ_ALLOW_EXT_ESCAPE */
(1 << 11) | /* YYJSON_READ_ALLOW_EXT_WHITESPACE */
(1 << 12) | /* YYJSON_READ_ALLOW_SINGLE_QUOTED_STR */
(1 << 13); /* YYJSON_READ_ALLOW_UNQUOTED_KEY */
@@ -794,7 +836,7 @@ static const yyjson_read_code YYJSON_READ_SUCCESS = 0;
/** Invalid parameter, such as NULL input string or 0 input length. */
static const yyjson_read_code YYJSON_READ_ERROR_INVALID_PARAMETER = 1;
/** Memory allocation failure occurs. */
/** Memory allocation failed. */
static const yyjson_read_code YYJSON_READ_ERROR_MEMORY_ALLOCATION = 2;
/** Input JSON string is empty. */
@@ -803,7 +845,7 @@ static const yyjson_read_code YYJSON_READ_ERROR_EMPTY_CONTENT = 3;
/** Unexpected content after document, such as `[123]abc`. */
static const yyjson_read_code YYJSON_READ_ERROR_UNEXPECTED_CONTENT = 4;
/** Unexpected ending, such as `[123`. */
/** Unexpected end of input, the parsed part is valid, such as `[123`. */
static const yyjson_read_code YYJSON_READ_ERROR_UNEXPECTED_END = 5;
/** Unexpected character inside the document, such as `[abc]`. */
@@ -812,7 +854,7 @@ static const yyjson_read_code YYJSON_READ_ERROR_UNEXPECTED_CHARACTER = 6;
/** Invalid JSON structure, such as `[1,]`. */
static const yyjson_read_code YYJSON_READ_ERROR_JSON_STRUCTURE = 7;
/** Invalid comment, such as unclosed multi-line comment. */
/** Invalid comment, deprecated, use `UNEXPECTED_END` for unclosed comment. */
static const yyjson_read_code YYJSON_READ_ERROR_INVALID_COMMENT = 8;
/** Invalid number, such as `123.e12`, `000`. */
@@ -830,7 +872,7 @@ static const yyjson_read_code YYJSON_READ_ERROR_FILE_OPEN = 12;
/** Failed to read a file. */
static const yyjson_read_code YYJSON_READ_ERROR_FILE_READ = 13;
/** Unexpected ending during incremental parsing. Parsing state is saved. */
/** Incomplete input during incremental parsing; parsing state is preserved. */
static const yyjson_read_code YYJSON_READ_ERROR_MORE = 14;
/** Error information for JSON reader. */
@@ -884,6 +926,7 @@ yyjson_api yyjson_doc *yyjson_read_opts(char *dat,
2. The `alc` is thread-safe or NULL.
@param path The JSON file's path.
This should be a null-terminated string using the system's native encoding.
If this path is NULL or invalid, the function will fail and return NULL.
@param flg The JSON read options.
Multiple options can be combined with `|` operator. 0 means no options.
@@ -960,6 +1003,9 @@ typedef struct yyjson_incr_state yyjson_incr_state;
2. Call `yyjson_incr_read()` repeatedly.
3. Call `yyjson_incr_free()` to free the state.
Note: The incremental JSON reader only supports standard JSON.
Flags for non-standard features (e.g. comments, trailing commas) are ignored.
@param buf The JSON data, null-terminator is not required.
If this parameter is NULL, the function will fail and return NULL.
@param buf_len The length of the JSON data in `buf`.
@@ -1088,27 +1134,7 @@ yyjson_api const char *yyjson_read_number(const char *dat,
const yyjson_alc *alc,
yyjson_read_err *err);
/**
Read a JSON number.
This function is thread-safe when data is not modified by other threads.
@param dat The JSON data (UTF-8 without BOM), null-terminator is required.
If this parameter is NULL, the function will fail and return NULL.
@param val The output value where result is stored.
If this parameter is NULL, the function will fail and return NULL.
The value will hold either UINT or SINT or REAL number;
@param flg The JSON read options.
Multiple options can be combined with `|` operator. 0 means no options.
Supports `YYJSON_READ_NUMBER_AS_RAW` and `YYJSON_READ_ALLOW_INF_AND_NAN`.
@param alc The memory allocator used for long number.
It is only used when the built-in floating point reader is disabled.
Pass NULL to use the libc's default allocator.
@param err A pointer to receive error information.
Pass NULL if you don't need error information.
@return If successful, a pointer to the character after the last character
used in the conversion, NULL if an error occurs.
*/
/** Same as `yyjson_read_number()`. */
yyjson_api_inline const char *yyjson_mut_read_number(const char *dat,
yyjson_mut_val *val,
yyjson_read_flag flg,
@@ -1122,7 +1148,7 @@ yyjson_api_inline const char *yyjson_mut_read_number(const char *dat,
/*==============================================================================
* JSON Writer API
* MARK: - JSON Writer API
*============================================================================*/
/** Run-time options for JSON writer. */
@@ -1230,7 +1256,7 @@ typedef struct yyjson_write_err {
#if !defined(YYJSON_DISABLE_WRITER) || !YYJSON_DISABLE_WRITER
/*==============================================================================
* JSON Document Writer API
* MARK: - JSON Document Writer API
*============================================================================*/
/**
@@ -1267,6 +1293,7 @@ yyjson_api char *yyjson_write_opts(const yyjson_doc *doc,
2. The `alc` is thread-safe or NULL.
@param path The JSON file's path.
This should be a null-terminated string using the system's native encoding.
If this path is NULL or invalid, the function will fail and return false.
If this file is not empty, the content will be discarded.
@param doc The JSON document.
@@ -1370,6 +1397,7 @@ yyjson_api char *yyjson_mut_write_opts(const yyjson_mut_doc *doc,
3. The `alc` is thread-safe or NULL.
@param path The JSON file's path.
This should be a null-terminated string using the system's native encoding.
If this path is NULL or invalid, the function will fail and return false.
If this file is not empty, the content will be discarded.
@param doc The mutable JSON document.
@@ -1439,7 +1467,7 @@ yyjson_api_inline char *yyjson_mut_write(const yyjson_mut_doc *doc,
/*==============================================================================
* JSON Value Writer API
* MARK: - JSON Value Writer API
*============================================================================*/
/**
@@ -1476,6 +1504,7 @@ yyjson_api char *yyjson_val_write_opts(const yyjson_val *val,
2. The `alc` is thread-safe or NULL.
@param path The JSON file's path.
This should be a null-terminated string using the system's native encoding.
If this path is NULL or invalid, the function will fail and return false.
If this file is not empty, the content will be discarded.
@param val The JSON root value.
@@ -1577,6 +1606,7 @@ yyjson_api char *yyjson_mut_val_write_opts(const yyjson_mut_val *val,
3. The `alc` is thread-safe or NULL.
@param path The JSON file's path.
This should be a null-terminated string using the system's native encoding.
If this path is NULL or invalid, the function will fail and return false.
If this file is not empty, the content will be discarded.
@param val The mutable JSON root value.
@@ -1643,12 +1673,40 @@ yyjson_api_inline char *yyjson_mut_val_write(const yyjson_mut_val *val,
return yyjson_mut_val_write_opts(val, flg, NULL, len, NULL);
}
/**
Write a JSON number.
@param val A JSON number value to be converted to a string.
If this parameter is invalid, the function will fail and return NULL.
@param buf A buffer to store the resulting null-terminated string.
If this parameter is NULL, the function will fail and return NULL.
For integer values, the buffer must be at least 21 bytes.
For floating-point values, the buffer must be at least 40 bytes.
@return On success, returns a pointer to the character after the last
written character. On failure, returns NULL.
@note
- This function is thread-safe and does not allocate memory
(when `YYJSON_DISABLE_FAST_FP_CONV` is not defined).
- This function will fail and return NULL only in the following cases:
1) `val` or `buf` is NULL;
2) `val` is not a number type;
3) `val` is `inf` or `nan`, and non-standard JSON is explicitly disabled
via the `YYJSON_DISABLE_NON_STANDARD` flag.
*/
yyjson_api char *yyjson_write_number(const yyjson_val *val, char *buf);
/** Same as `yyjson_write_number()`. */
yyjson_api_inline char *yyjson_mut_write_number(const yyjson_mut_val *val,
char *buf) {
return yyjson_write_number((const yyjson_val *)val, buf);
}
#endif /* YYJSON_DISABLE_WRITER */
/*==============================================================================
* JSON Document API
* MARK: - JSON Document API
*============================================================================*/
/** Returns the root value of this JSON document.
@@ -1673,7 +1731,7 @@ yyjson_api_inline void yyjson_doc_free(yyjson_doc *doc);
/*==============================================================================
* JSON Value Type API
* MARK: - JSON Value Type API
*============================================================================*/
/** Returns whether the JSON value is raw.
@@ -1735,7 +1793,7 @@ yyjson_api_inline bool yyjson_is_ctn(yyjson_val *val);
/*==============================================================================
* JSON Value Content API
* MARK: - JSON Value Content API
*============================================================================*/
/** Returns the JSON value's type.
@@ -1760,7 +1818,7 @@ yyjson_api_inline const char *yyjson_get_type_desc(yyjson_val *val);
yyjson_api_inline const char *yyjson_get_raw(yyjson_val *val);
/** Returns the content if the value is bool.
Returns NULL if `val` is NULL or type is not bool. */
Returns false if `val` is NULL or type is not bool. */
yyjson_api_inline bool yyjson_get_bool(yyjson_val *val);
/** Returns the content and cast to uint64_t.
@@ -1888,7 +1946,7 @@ yyjson_api_inline bool yyjson_set_str_noesc(yyjson_val *val, bool noesc);
/*==============================================================================
* JSON Array API
* MARK: - JSON Array API
*============================================================================*/
/** Returns the number of elements in this array.
@@ -1914,7 +1972,7 @@ yyjson_api_inline yyjson_val *yyjson_arr_get_last(yyjson_val *arr);
/*==============================================================================
* JSON Array Iterator API
* MARK: - JSON Array Iterator API
*============================================================================*/
/**
@@ -1996,7 +2054,7 @@ yyjson_api_inline yyjson_val *yyjson_arr_iter_next(yyjson_arr_iter *iter);
/*==============================================================================
* JSON Object API
* MARK: - JSON Object API
*============================================================================*/
/** Returns the number of key-value pairs in this object.
@@ -2026,7 +2084,7 @@ yyjson_api_inline yyjson_val *yyjson_obj_getn(yyjson_val *obj, const char *key,
/*==============================================================================
* JSON Object Iterator API
* MARK: - JSON Object Iterator API
*============================================================================*/
/**
@@ -2169,7 +2227,7 @@ yyjson_api_inline yyjson_val *yyjson_obj_iter_getn(yyjson_obj_iter *iter,
/*==============================================================================
* Mutable JSON Document API
* MARK: - Mutable JSON Document API
*============================================================================*/
/** Returns the root value of this JSON document.
@@ -2273,7 +2331,7 @@ yyjson_api yyjson_doc *yyjson_mut_val_imut_copy(yyjson_mut_val *val,
/*==============================================================================
* Mutable JSON Value Type API
* MARK: - Mutable JSON Value Type API
*============================================================================*/
/** Returns whether the JSON value is raw.
@@ -2335,7 +2393,7 @@ yyjson_api_inline bool yyjson_mut_is_ctn(yyjson_mut_val *val);
/*==============================================================================
* Mutable JSON Value Content API
* MARK: - Mutable JSON Value Content API
*============================================================================*/
/** Returns the JSON value's type.
@@ -2504,7 +2562,7 @@ yyjson_api_inline bool yyjson_mut_set_obj(yyjson_mut_val *val);
/*==============================================================================
* Mutable JSON Value Creation API
* MARK: - Mutable JSON Value Creation API
*============================================================================*/
/** Creates and returns a raw value, returns NULL on error.
@@ -2605,7 +2663,7 @@ yyjson_api_inline yyjson_mut_val *yyjson_mut_strncpy(yyjson_mut_doc *doc,
/*==============================================================================
* Mutable JSON Array API
* MARK: - Mutable JSON Array API
*============================================================================*/
/** Returns the number of elements in this array.
@@ -2629,7 +2687,7 @@ yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_get_last(yyjson_mut_val *arr);
/*==============================================================================
* Mutable JSON Array Iterator API
* MARK: - Mutable JSON Array Iterator API
*============================================================================*/
/**
@@ -2731,7 +2789,7 @@ yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_iter_remove(
/*==============================================================================
* Mutable JSON Array Creation API
* MARK: - Mutable JSON Array Creation API
*============================================================================*/
/**
@@ -3092,7 +3150,7 @@ yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_strncpy(
/*==============================================================================
* Mutable JSON Array Modification API
* MARK: - Mutable JSON Array Modification API
*============================================================================*/
/**
@@ -3205,7 +3263,7 @@ yyjson_api_inline bool yyjson_mut_arr_rotate(yyjson_mut_val *arr,
/*==============================================================================
* Mutable JSON Array Modification Convenience API
* MARK: - Mutable JSON Array Modification Convenience API
*============================================================================*/
/**
@@ -3411,7 +3469,7 @@ yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_add_obj(yyjson_mut_doc *doc,
/*==============================================================================
* Mutable JSON Object API
* MARK: - Mutable JSON Object API
*============================================================================*/
/** Returns the number of key-value pairs in this object.
@@ -3443,7 +3501,7 @@ yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_getn(yyjson_mut_val *obj,
/*==============================================================================
* Mutable JSON Object Iterator API
* MARK: - Mutable JSON Object Iterator API
*============================================================================*/
/**
@@ -3605,7 +3663,7 @@ yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_iter_getn(
/*==============================================================================
* Mutable JSON Object Creation API
* MARK: - Mutable JSON Object Creation API
*============================================================================*/
/** Creates and returns a mutable object, returns NULL on error. */
@@ -3652,7 +3710,7 @@ yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_with_kv(yyjson_mut_doc *doc,
/*==============================================================================
* Mutable JSON Object Modification API
* MARK: - Mutable JSON Object Modification API
*============================================================================*/
/**
@@ -3762,7 +3820,7 @@ yyjson_api_inline bool yyjson_mut_obj_rotate(yyjson_mut_val *obj,
/*==============================================================================
* Mutable JSON Object Modification Convenience API
* MARK: - Mutable JSON Object Modification Convenience API
*============================================================================*/
/** Adds a `null` value at the end of the object.
@@ -4002,7 +4060,7 @@ yyjson_api_inline bool yyjson_mut_obj_rename_keyn(yyjson_mut_doc *doc,
#if !defined(YYJSON_DISABLE_UTILS) || !YYJSON_DISABLE_UTILS
/*==============================================================================
* JSON Pointer API (RFC 6901)
* MARK: - JSON Pointer API (RFC 6901)
* https://tools.ietf.org/html/rfc6901
*============================================================================*/
@@ -4587,7 +4645,7 @@ yyjson_api_inline bool yyjson_ptr_ctx_remove(yyjson_ptr_ctx *ctx);
/*==============================================================================
* JSON Patch API (RFC 6902)
* MARK: - JSON Patch API (RFC 6902)
* https://tools.ietf.org/html/rfc6902
*============================================================================*/
@@ -4655,7 +4713,7 @@ yyjson_api yyjson_mut_val *yyjson_mut_patch(yyjson_mut_doc *doc,
/*==============================================================================
* JSON Merge-Patch API (RFC 7386)
* MARK: - JSON Merge-Patch API (RFC 7386)
* https://tools.ietf.org/html/rfc7386
*============================================================================*/
@@ -4688,7 +4746,7 @@ yyjson_api yyjson_mut_val *yyjson_mut_merge_patch(yyjson_mut_doc *doc,
/*==============================================================================
* JSON Structure (Implementation)
* MARK: - JSON Structure (Implementation)
*============================================================================*/
/** Payload of a JSON value (8 bytes). */
@@ -4725,7 +4783,7 @@ struct yyjson_doc {
/*==============================================================================
* Unsafe JSON Value API (Implementation)
* MARK: - Unsafe JSON Value API (Implementation)
*============================================================================*/
/*
@@ -5054,7 +5112,7 @@ yyjson_api_inline void unsafe_yyjson_set_obj(void *val, size_t size) {
/*==============================================================================
* JSON Document API (Implementation)
* MARK: - JSON Document API (Implementation)
*============================================================================*/
yyjson_api_inline yyjson_val *yyjson_doc_get_root(yyjson_doc *doc) {
@@ -5081,7 +5139,7 @@ yyjson_api_inline void yyjson_doc_free(yyjson_doc *doc) {
/*==============================================================================
* JSON Value Type API (Implementation)
* MARK: - JSON Value Type API (Implementation)
*============================================================================*/
yyjson_api_inline bool yyjson_is_raw(yyjson_val *val) {
@@ -5143,7 +5201,7 @@ yyjson_api_inline bool yyjson_is_ctn(yyjson_val *val) {
/*==============================================================================
* JSON Value Content API (Implementation)
* MARK: - JSON Value Content API (Implementation)
*============================================================================*/
yyjson_api_inline yyjson_type yyjson_get_type(yyjson_val *val) {
@@ -5326,7 +5384,7 @@ yyjson_api_inline bool yyjson_set_str_noesc(yyjson_val *val, bool noesc) {
/*==============================================================================
* JSON Array API (Implementation)
* MARK: - JSON Array API (Implementation)
*============================================================================*/
yyjson_api_inline size_t yyjson_arr_size(yyjson_val *arr) {
@@ -5376,7 +5434,7 @@ yyjson_api_inline yyjson_val *yyjson_arr_get_last(yyjson_val *arr) {
/*==============================================================================
* JSON Array Iterator API (Implementation)
* MARK: - JSON Array Iterator API (Implementation)
*============================================================================*/
yyjson_api_inline bool yyjson_arr_iter_init(yyjson_val *arr,
@@ -5415,7 +5473,7 @@ yyjson_api_inline yyjson_val *yyjson_arr_iter_next(yyjson_arr_iter *iter) {
/*==============================================================================
* JSON Object API (Implementation)
* MARK: - JSON Object API (Implementation)
*============================================================================*/
yyjson_api_inline size_t yyjson_obj_size(yyjson_val *obj) {
@@ -5444,7 +5502,7 @@ yyjson_api_inline yyjson_val *yyjson_obj_getn(yyjson_val *obj,
/*==============================================================================
* JSON Object Iterator API (Implementation)
* MARK: - JSON Object Iterator API (Implementation)
*============================================================================*/
yyjson_api_inline bool yyjson_obj_iter_init(yyjson_val *obj,
@@ -5521,7 +5579,7 @@ yyjson_api_inline yyjson_val *yyjson_obj_iter_getn(yyjson_obj_iter *iter,
/*==============================================================================
* Mutable JSON Structure (Implementation)
* MARK: - Mutable JSON Structure (Implementation)
*============================================================================*/
/**
@@ -5637,7 +5695,7 @@ yyjson_api_inline yyjson_mut_val *unsafe_yyjson_mut_val(yyjson_mut_doc *doc,
/*==============================================================================
* Mutable JSON Document API (Implementation)
* MARK: - Mutable JSON Document API (Implementation)
*============================================================================*/
yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_get_root(yyjson_mut_doc *doc) {
@@ -5652,7 +5710,7 @@ yyjson_api_inline void yyjson_mut_doc_set_root(yyjson_mut_doc *doc,
/*==============================================================================
* Mutable JSON Value Type API (Implementation)
* MARK: - Mutable JSON Value Type API (Implementation)
*============================================================================*/
yyjson_api_inline bool yyjson_mut_is_raw(yyjson_mut_val *val) {
@@ -5714,7 +5772,7 @@ yyjson_api_inline bool yyjson_mut_is_ctn(yyjson_mut_val *val) {
/*==============================================================================
* Mutable JSON Value Content API (Implementation)
* MARK: - Mutable JSON Value Content API (Implementation)
*============================================================================*/
yyjson_api_inline yyjson_type yyjson_mut_get_type(yyjson_mut_val *val) {
@@ -5893,7 +5951,7 @@ yyjson_api_inline bool yyjson_mut_set_obj(yyjson_mut_val *val) {
/*==============================================================================
* Mutable JSON Value Creation API (Implementation)
* MARK: - Mutable JSON Value Creation API (Implementation)
*============================================================================*/
#define yyjson_mut_val_one(func) \
@@ -6034,7 +6092,7 @@ yyjson_api_inline yyjson_mut_val *yyjson_mut_strncpy(yyjson_mut_doc *doc,
/*==============================================================================
* Mutable JSON Array API (Implementation)
* MARK: - Mutable JSON Array API (Implementation)
*============================================================================*/
yyjson_api_inline size_t yyjson_mut_arr_size(yyjson_mut_val *arr) {
@@ -6070,7 +6128,7 @@ yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_get_last(
/*==============================================================================
* Mutable JSON Array Iterator API (Implementation)
* MARK: - Mutable JSON Array Iterator API (Implementation)
*============================================================================*/
yyjson_api_inline bool yyjson_mut_arr_iter_init(yyjson_mut_val *arr,
@@ -6130,7 +6188,7 @@ yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_iter_remove(
/*==============================================================================
* Mutable JSON Array Creation API (Implementation)
* MARK: - Mutable JSON Array Creation API (Implementation)
*============================================================================*/
yyjson_api_inline yyjson_mut_val *yyjson_mut_arr(yyjson_mut_doc *doc) {
@@ -6310,7 +6368,7 @@ yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_strncpy(
/*==============================================================================
* Mutable JSON Array Modification API (Implementation)
* MARK: - Mutable JSON Array Modification API (Implementation)
*============================================================================*/
yyjson_api_inline bool yyjson_mut_arr_insert(yyjson_mut_val *arr,
@@ -6520,7 +6578,7 @@ yyjson_api_inline bool yyjson_mut_arr_rotate(yyjson_mut_val *arr,
/*==============================================================================
* Mutable JSON Array Modification Convenience API (Implementation)
* MARK: - Mutable JSON Array Modification Convenience API (Implementation)
*============================================================================*/
yyjson_api_inline bool yyjson_mut_arr_add_val(yyjson_mut_val *arr,
@@ -6686,7 +6744,7 @@ yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_add_obj(yyjson_mut_doc *doc,
/*==============================================================================
* Mutable JSON Object API (Implementation)
* MARK: - Mutable JSON Object API (Implementation)
*============================================================================*/
yyjson_api_inline size_t yyjson_mut_obj_size(yyjson_mut_val *obj) {
@@ -6715,7 +6773,7 @@ yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_getn(yyjson_mut_val *obj,
/*==============================================================================
* Mutable JSON Object Iterator API (Implementation)
* MARK: - Mutable JSON Object Iterator API (Implementation)
*============================================================================*/
yyjson_api_inline bool yyjson_mut_obj_iter_init(yyjson_mut_val *obj,
@@ -6806,7 +6864,7 @@ yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_iter_getn(
/*==============================================================================
* Mutable JSON Object Creation API (Implementation)
* MARK: - Mutable JSON Object Creation API (Implementation)
*============================================================================*/
yyjson_api_inline yyjson_mut_val *yyjson_mut_obj(yyjson_mut_doc *doc) {
@@ -6886,7 +6944,7 @@ yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_with_kv(yyjson_mut_doc *doc,
/*==============================================================================
* Mutable JSON Object Modification API (Implementation)
* MARK: - Mutable JSON Object Modification API (Implementation)
*============================================================================*/
yyjson_api_inline void unsafe_yyjson_mut_obj_add(yyjson_mut_val *obj,
@@ -7079,7 +7137,7 @@ yyjson_api_inline bool yyjson_mut_obj_rotate(yyjson_mut_val *obj,
/*==============================================================================
* Mutable JSON Object Modification Convenience API (Implementation)
* MARK: - Mutable JSON Object Modification Convenience API (Implementation)
*============================================================================*/
#define yyjson_mut_obj_add_func(func) \
@@ -7306,7 +7364,7 @@ yyjson_api_inline bool yyjson_mut_obj_rename_keyn(yyjson_mut_doc *doc,
#if !defined(YYJSON_DISABLE_UTILS) || !YYJSON_DISABLE_UTILS
/*==============================================================================
* JSON Pointer API (Implementation)
* MARK: - JSON Pointer API (Implementation)
*============================================================================*/
#define yyjson_ptr_set_err(_code, _msg) do { \
@@ -7965,7 +8023,7 @@ yyjson_api_inline bool yyjson_ptr_ctx_remove(yyjson_ptr_ctx *ctx) {
/*==============================================================================
* JSON Value at Pointer API (Implementation)
* MARK: - JSON Value at Pointer API (Implementation)
*============================================================================*/
/**
@@ -8068,7 +8126,7 @@ yyjson_api_inline bool yyjson_ptr_get_str(
/*==============================================================================
* Deprecated
* MARK: - Deprecated
*============================================================================*/
/** @deprecated renamed to `yyjson_doc_ptr_get` */
@@ -8152,7 +8210,7 @@ yyjson_api_inline yyjson_mut_val *unsafe_yyjson_mut_get_pointer(
/*==============================================================================
* Compiler Hint End
* MARK: - Compiler Hint End
*============================================================================*/
#if defined(__clang__)
@@ -1,7 +1,7 @@
#pragma once
#include "util/FFstrbuf.h"
#include "util/FFlist.h"
#include "common/FFstrbuf.h"
#include "common/FFlist.h"
typedef struct FFPlatformSysinfo
{
@@ -9,7 +9,6 @@ typedef struct FFPlatformSysinfo
FFstrbuf release;
FFstrbuf version;
FFstrbuf architecture;
FFstrbuf displayVersion;
uint32_t pageSize;
} FFPlatformSysinfo;
@@ -19,8 +18,15 @@ typedef struct FFPlatform
FFstrbuf cacheDir; // Trailing slash included
FFlist configDirs; // List of FFstrbuf, trailing slash included
FFlist dataDirs; // List of FFstrbuf, trailing slash included
FFstrbuf exePath; // The real path of current exe
FFstrbuf exePath; // The real path of current exe (empty if unavailable)
FFstrbuf cwd; // Trailing slash included
uint32_t pid;
#ifndef _WIN32
uint32_t uid;
#else
FFstrbuf sid;
#endif
FFstrbuf userName;
FFstrbuf fullUserName;
FFstrbuf hostName;
@@ -126,3 +126,10 @@ static inline void ffListClear(FFlist* list)
assert(sizeof(itemType) == (listVar).elementSize); \
(itemType*) ffListAdd(&(listVar)); \
})
#define FF_LIST_FIRST(itemType, listVar) FF_LIST_GET(itemType, listVar, 0)
#define FF_LIST_LAST(itemType, listVar) \
({ \
assert((listVar).length > 0); \
FF_LIST_GET(itemType, listVar, ((listVar).length - 1)); \
})
+120 -53
View File
@@ -24,6 +24,8 @@
#define FASTFETCH_STRBUF_DEFAULT_ALLOC 32
// static string (allocated == 0), chars points to a string literal
// dynamic string (allocated > 0), chars points to a heap allocated buffer
typedef struct FFstrbuf
{
uint32_t allocated;
@@ -34,6 +36,7 @@ typedef struct FFstrbuf
static inline void ffStrbufInit(FFstrbuf* strbuf);
void ffStrbufInitA(FFstrbuf* strbuf, uint32_t allocate);
void ffStrbufInitVF(FFstrbuf* strbuf, const char* format, va_list arguments);
void ffStrbufInitMoveNS(FFstrbuf* strbuf, uint32_t length, char* heapStr);
void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free);
void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free);
@@ -54,6 +57,10 @@ void ffStrbufPrependC(FFstrbuf* strbuf, char c);
void ffStrbufInsertNC(FFstrbuf* strbuf, uint32_t index, uint32_t num, char c);
// Clear the content of strbuf and set new value
// NOTE: Unlike ffStrbufAppend*, ffStrbufSet* functions may NOT reserve extra space
void ffStrbufSet(FFstrbuf* strbuf, const FFstrbuf* value);
void ffStrbufSetNS(FFstrbuf* strbuf, uint32_t length, const char* value);
FF_C_PRINTF(2, 3) void ffStrbufSetF(FFstrbuf* strbuf, const char* format, ...);
void ffStrbufTrimLeft(FFstrbuf* strbuf, char c);
@@ -96,13 +103,55 @@ FF_C_NODISCARD uint64_t ffStrbufToUInt(const FFstrbuf* strbuf, uint64_t defaultV
void ffStrbufUpperCase(FFstrbuf* strbuf);
void ffStrbufLowerCase(FFstrbuf* strbuf);
bool ffStrbufGetline(char** lineptr, size_t* n, FFstrbuf* buffer);
void ffStrbufGetlineRestore(char** lineptr, size_t* n, FFstrbuf* buffer);
// Function alters the buffer to extract lines or delimited segments (replaces the delimiter with '\0')
// so that buffer MUST be heap allocated (NOT a static string)
// `lineptr` must be `NULL` and `n` MUST be `0` for the first call
// Caller MUST NOT free `*lineptr`
bool ffStrbufGetdelim(char** lineptr, size_t* n, char delimiter, FFstrbuf* buffer);
void ffStrbufGetdelimRestore(char** lineptr, size_t* n, char delimiter, FFstrbuf* buffer);
/**
* @brief Read a line from a FFstrbuf.
*
* @details Behaves like getline(3) but reads from a FFstrbuf.
*
* @param[in,out] lineptr The pointer to a pointer that will be set to the start of the line
(points to buffer's internal memory address to avoid memory allocation and copy).
MUST NOT be freed by the caller, unlike `getline(3)`.
* MUST be NULL for the first call.
* @param[in,out] n The pointer to the size of the buffer of lineptr.
MUST be 0 for the first call.
* @param[in] buffer The buffer to read from.
MUST be heap allocated (NOT a static string).
*
* @return true if a line has been read, false if the end of the buffer has been reached.
*/
static inline bool ffStrbufGetline(char** lineptr, size_t* n, FFstrbuf* buffer)
{
return ffStrbufGetdelim(lineptr, n, '\n', buffer);
}
/**
* @brief Restore the end of a line that was modified by ffStrbufGetline.
* @warning This function should be called before breaking an ffStrbufGetline loop if `buffer` will be used later.
*/
static inline void ffStrbufGetlineRestore(char** lineptr, size_t* n, FFstrbuf* buffer)
{
ffStrbufGetdelimRestore(lineptr, n, '\n', buffer);
}
bool ffStrbufRemoveDupWhitespaces(FFstrbuf* strbuf);
bool ffStrbufMatchSeparatedNS(const FFstrbuf* strbuf, uint32_t compLength, const char* comp, char separator);
bool ffStrbufMatchSeparatedIgnCaseNS(const FFstrbuf* strbuf, uint32_t compLength, const char* comp, char separator);
bool ffStrbufSeparatedContainNS(const FFstrbuf* strbuf, uint32_t compLength, const char* comp, char separator);
bool ffStrbufSeparatedContainIgnCaseNS(const FFstrbuf* strbuf, uint32_t compLength, const char* comp, char separator);
int ffStrbufAppendUtf32CodePoint(FFstrbuf* strbuf, uint32_t codepoint);
void ffStrbufAppendSInt(FFstrbuf* strbuf, int64_t value);
void ffStrbufAppendUInt(FFstrbuf* strbuf, uint64_t value);
// Appends a double value to the string buffer with the specified precision (0~15).
// if `precision < 0`, let yyjson decide the precision
void ffStrbufAppendDouble(FFstrbuf* strbuf, double value, int8_t precision, bool trailingZeros);
FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateA(uint32_t allocate)
{
FFstrbuf strbuf;
@@ -113,7 +162,7 @@ FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateA(uint32_t allocate)
static inline void ffStrbufInitCopy(FFstrbuf* __restrict strbuf, const FFstrbuf* __restrict src)
{
if (src->allocated == 0) // static string
memcpy(strbuf, src, sizeof(FFstrbuf));
*strbuf = *src;
else
{
ffStrbufInitA(strbuf, src->allocated);
@@ -133,9 +182,7 @@ static inline void ffStrbufInitMove(FFstrbuf* strbuf, FFstrbuf* src)
{
if (src)
{
strbuf->allocated = src->allocated;
strbuf->chars = src->chars;
strbuf->length = src->length;
*strbuf = *src;
ffStrbufInit(src);
}
else
@@ -178,21 +225,17 @@ FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateF(const char* format, ...)
return strbuf;
}
static inline void ffStrbufInitMoveS(FFstrbuf* strbuf, char* heapStr)
{
ffStrbufInitMoveNS(strbuf, (uint32_t) strlen(heapStr), heapStr);
}
static inline void ffStrbufDestroy(FFstrbuf* strbuf)
{
extern char* CHAR_NULL_PTR;
if(strbuf->allocated > 0)
free(strbuf->chars);
if(strbuf->allocated == 0)
{
strbuf->length = 0;
strbuf->chars = CHAR_NULL_PTR;
return;
}
//Avoid free-after-use. These 3 assignments are cheap so don't remove them
strbuf->allocated = strbuf->length = 0;
free(strbuf->chars);
strbuf->chars = CHAR_NULL_PTR;
ffStrbufInit(strbuf);
}
FF_C_NODISCARD static inline uint32_t ffStrbufGetFree(const FFstrbuf* strbuf)
@@ -209,6 +252,30 @@ static inline void ffStrbufRecalculateLength(FFstrbuf* strbuf)
strbuf->length = (uint32_t) strlen(strbuf->chars);
}
static inline void ffStrbufSetS(FFstrbuf* strbuf, const char* value)
{
assert(strbuf != NULL);
if (value == NULL)
ffStrbufClear(strbuf);
else
ffStrbufSetNS(strbuf, (uint32_t) strlen(value), value);
}
static inline bool ffStrbufSetJsonVal(FFstrbuf* strbuf, yyjson_val* jsonVal)
{
assert(strbuf != NULL);
if (yyjson_is_str(jsonVal))
{
ffStrbufSetNS(strbuf, (uint32_t) unsafe_yyjson_get_len(jsonVal), unsafe_yyjson_get_str(jsonVal));
return true;
}
ffStrbufClear(strbuf);
return false;
}
static inline void ffStrbufAppendS(FFstrbuf* strbuf, const char* value)
{
if(value == NULL)
@@ -226,42 +293,10 @@ static inline bool ffStrbufAppendJsonVal(FFstrbuf* strbuf, yyjson_val* jsonVal)
return false;
}
static inline void ffStrbufSetS(FFstrbuf* strbuf, const char* value)
{
ffStrbufClear(strbuf);
if(value != NULL)
ffStrbufAppendNS(strbuf, (uint32_t) strlen(value), value);
}
static inline void ffStrbufSetNS(FFstrbuf* strbuf, uint32_t length, const char* value)
{
ffStrbufClear(strbuf);
ffStrbufAppendNS(strbuf, length, value);
}
static inline void ffStrbufSet(FFstrbuf* strbuf, const FFstrbuf* value)
{
assert(value && value != strbuf);
if (strbuf->allocated == 0 && value->allocated == 0)
{
memcpy(strbuf, value, sizeof(FFstrbuf));
return;
}
ffStrbufSetNS(strbuf, value->length, value->chars);
}
static inline bool ffStrbufSetJsonVal(FFstrbuf* strbuf, yyjson_val* jsonVal)
{
ffStrbufClear(strbuf);
return ffStrbufAppendJsonVal(strbuf, jsonVal);
}
static inline void ffStrbufInit(FFstrbuf* strbuf)
{
extern char* CHAR_NULL_PTR;
strbuf->allocated = 0;
strbuf->length = 0;
strbuf->allocated = strbuf->length = 0;
strbuf->chars = CHAR_NULL_PTR;
}
@@ -292,10 +327,12 @@ FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateStatic(const char* str)
static inline void ffStrbufSetStatic(FFstrbuf* strbuf, const char* value)
{
if(strbuf->allocated > 0)
ffStrbufDestroy(strbuf);
free(strbuf->chars);
if(value != NULL)
ffStrbufInitStatic(strbuf, value);
else
ffStrbufInit(strbuf);
}
static inline void ffStrbufInitNS(FFstrbuf* strbuf, uint32_t length, const char* str)
@@ -352,7 +389,7 @@ static inline void ffStrbufPrependS(FFstrbuf* strbuf, const char* value)
ffStrbufPrependNS(strbuf, (uint32_t) strlen(value), value);
}
static inline int ffStrbufComp(const FFstrbuf* strbuf, const FFstrbuf* comp)
static inline FF_C_NODISCARD int ffStrbufComp(const FFstrbuf* strbuf, const FFstrbuf* comp)
{
uint32_t length = strbuf->length > comp->length ? comp->length : strbuf->length;
return memcmp(strbuf->chars, comp->chars, length + 1);
@@ -560,4 +597,34 @@ static inline bool ffStrbufMatchSeparated(const FFstrbuf* strbuf, const FFstrbuf
return ffStrbufMatchSeparatedNS(strbuf, comp->length, comp->chars, separator);
}
static inline bool ffStrbufMatchSeparatedIgnCaseS(const FFstrbuf* strbuf, const char* comp, char separator)
{
return ffStrbufMatchSeparatedIgnCaseNS(strbuf, (uint32_t) strlen(comp), comp, separator);
}
static inline bool ffStrbufMatchSeparatedIgnCase(const FFstrbuf* strbuf, const FFstrbuf* comp, char separator)
{
return ffStrbufMatchSeparatedIgnCaseNS(strbuf, comp->length, comp->chars, separator);
}
static inline bool ffStrbufSeparatedContainS(const FFstrbuf* strbuf, const char* comp, char separator)
{
return ffStrbufSeparatedContainNS(strbuf, (uint32_t) strlen(comp), comp, separator);
}
static inline bool ffStrbufSeparatedContain(const FFstrbuf* strbuf, const FFstrbuf* comp, char separator)
{
return ffStrbufSeparatedContainNS(strbuf, comp->length, comp->chars, separator);
}
static inline bool ffStrbufSeparatedContainIgnCaseS(const FFstrbuf* strbuf, const char* comp, char separator)
{
return ffStrbufSeparatedContainIgnCaseNS(strbuf, (uint32_t) strlen(comp), comp, separator);
}
static inline bool ffStrbufSeparatedContainIgnCase(const FFstrbuf* strbuf, const FFstrbuf* comp, char separator)
{
return ffStrbufSeparatedContainIgnCaseNS(strbuf, comp->length, comp->chars, separator);
}
#define FF_STRBUF_AUTO_DESTROY FFstrbuf __attribute__((__cleanup__(ffStrbufDestroy)))
@@ -6,8 +6,8 @@
<string>fastfetch</string>
<key>CFBundleName</key>
<string>@PROJECT_NAME@</string>
<key>CFBundleShortVersionString</key>
<string>@PROJECT_VERSION@</string>
<key>CFBundleShortVersionString</key>
<string>@PROJECT_VERSION@</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>NSBluetoothAlwaysUsageDescription</key>
@@ -40,11 +40,9 @@ const char* ffCfNumGetInt(CFTypeRef cf, int32_t* result)
const char* ffCfStrGetString(CFTypeRef cf, FFstrbuf* result)
{
ffStrbufClear(result);
if (!cf)
{
ffStrbufClear(result);
return NULL;
}
if (CFGetTypeID(cf) == CFStringGetTypeID())
{
@@ -56,6 +54,8 @@ const char* ffCfStrGetString(CFTypeRef cf, FFstrbuf* result)
else
{
uint32_t length = (uint32_t) CFStringGetLength(cfStr);
if (length == 0)
return NULL;
ffStrbufEnsureFixedLengthFree(result, (uint32_t) CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8));
if(!CFStringGetCString(cfStr, result->chars, result->allocated, kCFStringEncodingUTF8))
return "CFStringGetCString() failed";
@@ -68,7 +68,9 @@ const char* ffCfStrGetString(CFTypeRef cf, FFstrbuf* result)
{
CFDataRef cfData = (CFDataRef)cf;
uint32_t length = (uint32_t)CFDataGetLength(cfData);
ffStrbufEnsureFree(result, length + 1);
if (length == 0)
return NULL;
ffStrbufEnsureFixedLengthFree(result, length + 1);
CFDataGetBytes(cfData, CFRangeMake(0, length), (uint8_t*)result->chars);
result->length = (uint32_t)strnlen(result->chars, length);
result->chars[result->length] = '\0';
@@ -79,6 +81,29 @@ const char* ffCfStrGetString(CFTypeRef cf, FFstrbuf* result)
return NULL;
}
const char* ffCfDataGetDataAsString(CFTypeRef cf, FFstrbuf* result)
{
ffStrbufClear(result);
if (!cf)
return NULL;
if (CFGetTypeID(cf) == CFDataGetTypeID())
{
CFDataRef cfData = (CFDataRef)cf;
uint32_t length = (uint32_t)CFDataGetLength(cfData);
if (length == 0)
return NULL;
ffStrbufEnsureFixedLengthFree(result, length + 1);
CFDataGetBytes(cfData, CFRangeMake(0, length), (uint8_t*)result->chars);
result->length = length;
result->chars[result->length] = '\0';
}
else
return "TypeID is not 'CFData'";
return NULL;
}
const char* ffCfDictGetString(CFDictionaryRef dict, CFStringRef key, FFstrbuf* result)
{
CFTypeRef cf = (CFTypeRef)CFDictionaryGetValue(dict, key);
@@ -88,6 +113,15 @@ const char* ffCfDictGetString(CFDictionaryRef dict, CFStringRef key, FFstrbuf* r
return ffCfStrGetString(cf, result);
}
const char* ffCfDictGetDataAsString(CFDictionaryRef dict, CFStringRef key, FFstrbuf* result)
{
CFTypeRef cf = (CFTypeRef)CFDictionaryGetValue(dict, key);
if(cf == NULL)
return "CFDictionaryGetValue() failed";
return ffCfDataGetDataAsString(cf, result);
}
const char* ffCfDictGetBool(CFDictionaryRef dict, CFStringRef key, bool* result)
{
CFBooleanRef cf = (CFBooleanRef)CFDictionaryGetValue(dict, key);
@@ -8,11 +8,13 @@
const char* ffCfStrGetString(CFTypeRef cf, FFstrbuf* result);
const char* ffCfNumGetInt(CFTypeRef cf, int32_t* result);
const char* ffCfNumGetInt64(CFTypeRef cf, int64_t* result);
const char* ffCfDataGetDataAsString(CFTypeRef cf, FFstrbuf* result);
const char* ffCfDictGetString(CFDictionaryRef dict, CFStringRef key, FFstrbuf* result);
const char* ffCfDictGetBool(CFDictionaryRef dict, CFStringRef key, bool* result);
const char* ffCfDictGetInt(CFDictionaryRef dict, CFStringRef key, int* result);
const char* ffCfDictGetInt64(CFDictionaryRef dict, CFStringRef key, int64_t* result);
const char* ffCfDictGetData(CFDictionaryRef dict, CFStringRef key, uint32_t offset, uint32_t size, uint8_t* result, uint32_t* length);
const char* ffCfDictGetDataAsString(CFDictionaryRef dict, CFStringRef key, FFstrbuf* result);
const char* ffCfDictGetDict(CFDictionaryRef dict, CFStringRef key, CFDictionaryRef* result);
static inline CFNumberRef ffCfCreateInt(int value)
@@ -22,6 +24,7 @@ static inline CFNumberRef ffCfCreateInt(int value)
static inline void cfReleaseWrapper(void* type)
{
assert(type);
if (*(CFTypeRef*) type)
CFRelease(*(CFTypeRef*) type);
}
@@ -1,6 +1,6 @@
#include "fastfetch.h"
#include "smc_temps.h"
#include "util/stringUtils.h"
#include "common/apple/cf_helpers.h"
#include "common/stringUtils.h"
#include <stdint.h>
#include <math.h>
@@ -137,14 +137,11 @@ static const char *smcReadSmcVal(io_connect_t conn, const UInt32Char_t key, SmcV
static const char *smcOpen(io_connect_t *conn)
{
io_object_t device = IOServiceGetMatchingService(MACH_PORT_NULL, IOServiceMatching("AppleSMC"));
FF_IOOBJECT_AUTO_RELEASE io_object_t device = IOServiceGetMatchingService(MACH_PORT_NULL, IOServiceMatching("AppleSMC"));
if (!device)
return "No SMC device found";
kern_return_t result = IOServiceOpen(device, mach_task_self(), 0, conn);
IOObjectRelease(device);
if (result != kIOReturnSuccess)
if (IOServiceOpen(device, mach_task_self(), 0, conn) != kIOReturnSuccess)
return "IOServiceOpen() failed";
return NULL;
@@ -159,113 +156,108 @@ static const char *smcReadValue(io_connect_t conn, const UInt32Char_t key, doubl
if (val.dataSize == 0)
return "Empty SMC result";
if (ffStrEquals(val.dataType, "ui8 ") ||
ffStrEquals(val.dataType, "ui16") ||
ffStrEquals(val.dataType, "ui32") ||
ffStrEquals(val.dataType, "ui64"))
switch (val.dataType[0])
{
uint64_t tmp = 0;
for (uint32_t i = 0; i < val.dataSize; i++)
tmp += (uint64_t)((uint8_t)(val.bytes[i]) * pow(256, val.dataSize - 1 - i));
*value = (double)tmp;
case 'u': // unsigned integer types
if (val.dataType[1] == 'i')
{
switch (val.dataSize)
{
case 1: *value = *(uint8_t *)(val.bytes); break;
case 2: *value = ntohs(*(uint16_t *)(val.bytes)); break;
case 4: *value = ntohl(*(uint32_t *)(val.bytes)); break;
case 8: *value = (double) ntohll(*(uint64_t *)(val.bytes)); break;
default:
return "Unsupported SMC unsigned integer data size";
}
}
else
return "Unsupported SMC unsigned data type";
break;
case 'f': // floating point types
if (ffStrEquals(val.dataType, "flt ") && val.dataSize == 4)
*value = *(float *)(val.bytes);
else if (val.dataType[1] == 'p' && val.dataSize == 2) // fixed point types
{
if (ffStrEquals(val.dataType, "fp1f"))
*value = ntohs(*(uint16_t *)(val.bytes)) / 32768.0;
else if (ffStrEquals(val.dataType, "fp4c"))
*value = ntohs(*(uint16_t *)(val.bytes)) / 4096.0;
else if (ffStrEquals(val.dataType, "fp5b"))
*value = ntohs(*(uint16_t *)(val.bytes)) / 2048.0;
else if (ffStrEquals(val.dataType, "fp6a"))
*value = ntohs(*(uint16_t *)(val.bytes)) / 1024.0;
else if (ffStrEquals(val.dataType, "fp79"))
*value = ntohs(*(uint16_t *)(val.bytes)) / 512.0;
else if (ffStrEquals(val.dataType, "fp88"))
*value = ntohs(*(uint16_t *)(val.bytes)) / 256.0;
else if (ffStrEquals(val.dataType, "fpa6"))
*value = ntohs(*(uint16_t *)(val.bytes)) / 64.0;
else if (ffStrEquals(val.dataType, "fpc4"))
*value = ntohs(*(uint16_t *)(val.bytes)) / 16.0;
else if (ffStrEquals(val.dataType, "fpe2"))
*value = ntohs(*(uint16_t *)(val.bytes)) / 4.0;
else
return "Unsupported SMC floating point data type";
}
else
return "Unsupported SMC floating point data type";
break;
case 's': // signed integer types
if (val.dataType[1] == 'i')
{
switch (val.dataSize)
{
case 1: *value = *(int8_t *)(val.bytes); break;
case 2: *value = ntohs(*(int16_t *)(val.bytes)); break;
case 4: *value = ntohl(*(int32_t *)(val.bytes)); break;
case 8: *value = (double)ntohll(*(int64_t *)(val.bytes)); break;
default: return "Unsupported SMC signed integer data size";
}
}
else if (val.dataType[1] == 'p' && val.dataSize == 2) // signed fixed point types
{
if (ffStrEquals(val.dataType, "sp1e"))
*value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 16384.0;
else if (ffStrEquals(val.dataType, "sp3c"))
*value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 4096.0;
else if (ffStrEquals(val.dataType, "sp4b"))
*value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 2048.0;
else if (ffStrEquals(val.dataType, "sp5a"))
*value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 1024.0;
else if (ffStrEquals(val.dataType, "sp69"))
*value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 512.0;
else if (ffStrEquals(val.dataType, "sp78"))
*value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 256.0;
else if (ffStrEquals(val.dataType, "sp87"))
*value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 128.0;
else if (ffStrEquals(val.dataType, "sp96"))
*value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 64.0;
else if (ffStrEquals(val.dataType, "spb4"))
*value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 16.0;
else if (ffStrEquals(val.dataType, "spf0"))
*value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 1.0;
else
return "Unsupported SMC signed integer data type";
}
else
return "Unsupported SMC signed data type";
break;
case '{': // special types like pwm
if (ffStrEquals(val.dataType, "{pwm") && val.dataSize == 2)
{
*value = (double)ntohs(*(uint16_t *)(val.bytes)) * 100 / 65536.0;
}
else
return "Unsupported SMC special data type";
break;
default:
return "Unsupported SMC data type";
}
else if (ffStrEquals(val.dataType, "flt "))
{
*value = *(float *)(val.bytes);
}
else if (ffStrEquals(val.dataType, "fp1f") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 32768.0;
}
else if (ffStrEquals(val.dataType, "fp4c") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 4096.0;
}
else if (ffStrEquals(val.dataType, "fp5b") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 2048.0;
}
else if (ffStrEquals(val.dataType, "fp6a") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 1024.0;
}
else if (ffStrEquals(val.dataType, "fp79") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 512.0;
}
else if (ffStrEquals(val.dataType, "fp88") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 256.0;
}
else if (ffStrEquals(val.dataType, "fpa6") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 64.0;
}
else if (ffStrEquals(val.dataType, "fpc4") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 16.0;
}
else if (ffStrEquals(val.dataType, "fpe2") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 4.0;
}
else if (ffStrEquals(val.dataType, "sp1e") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 16384.0;
}
else if (ffStrEquals(val.dataType, "sp3c") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 4096.0;
}
else if (ffStrEquals(val.dataType, "sp4b") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 2048.0;
}
else if (ffStrEquals(val.dataType, "sp5a") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 1024.0;
}
else if (ffStrEquals(val.dataType, "sp69") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 512.0;
}
else if (ffStrEquals(val.dataType, "sp78") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 256.0;
}
else if (ffStrEquals(val.dataType, "sp87") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 128.0;
}
else if (ffStrEquals(val.dataType, "sp96") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 64.0;
}
else if (ffStrEquals(val.dataType, "spb4") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 16.0;
}
else if (ffStrEquals(val.dataType, "spf0") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 1.0;
}
else if (ffStrEquals(val.dataType, "si8 ") && val.dataSize == 1)
{
signed char *bytes = (signed char *)val.bytes;
int16_t temp = 0;
temp += (int8_t)(bytes[0]);
*value = temp;
}
else if (ffStrEquals(val.dataType, "si16") && val.dataSize == 2)
{
*value = ntohs(*(int16_t *)(val.bytes));
}
else if (ffStrEquals(val.dataType, "{pwm") && val.dataSize == 2)
{
*value = (double)ntohs(*(uint16_t *)(val.bytes)) * 100 / 65536.0;
}
else
return "Unknown SMC data type";
return NULL;
}
@@ -280,15 +272,32 @@ static bool detectTemp(io_connect_t conn, const char* sensor, double* sum)
return true;
}
const char* ffDetectSmcTemps(enum FFTempType type, double* result)
static io_connect_t conn;
const char* ffDetectSmcSpecificTemp(const char* sensor, double* result)
{
static io_connect_t conn;
if (!conn)
{
if (smcOpen(&conn) != NULL)
conn = (io_connect_t) -1;
}
else if (conn == (io_connect_t) -1)
if (conn == (io_connect_t) -1)
return "Could not open SMC connection";
if (!detectTemp(conn, sensor, result))
return "Could not read SMC temperature";
return NULL;
}
const char* ffDetectSmcTemps(enum FFTempType type, double* result)
{
if (!conn)
{
if (smcOpen(&conn) != NULL)
conn = (io_connect_t) -1;
}
if (conn == (io_connect_t) -1)
return "Could not open SMC connection";
uint32_t count = 0;
@@ -30,4 +30,5 @@ enum FFTempType
FF_TEMP_MEMORY,
};
const char* ffDetectSmcSpecificTemp(const char* sensor, double* result);
const char* ffDetectSmcTemps(enum FFTempType type, double* result);
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#include <assert.h>
#ifdef __has_builtin
#if !__cplusplus && FF_SUPPORTS_COUNT_OF
#define ARRAY_SIZE(x) _Countof(x)
#elif __has_builtin(__is_array)
#define ARRAY_SIZE(x) ({ static_assert(__is_array(__typeof__(x)), "Must be an array"); (uint32_t) (sizeof(x) / sizeof(*(x))); })
#elif __has_builtin(__builtin_types_compatible_p)
#define ARRAY_SIZE(x) ({ static_assert(!__builtin_types_compatible_p(__typeof__(x), __typeof__(&*(x))), "Must not be a pointer"); (uint32_t) (sizeof(x) / sizeof(*(x))); })
#endif
#endif
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) ((uint32_t) (sizeof(x) / sizeof(*(x))))
#endif
-180
View File
@@ -1,180 +0,0 @@
#include "commandoption.h"
#include "common/color.h"
#include "common/printing.h"
#include "common/time.h"
#include "common/jsonconfig.h"
#include "fastfetch_datatext.h"
#include "modules/modules.h"
#include "util/stringUtils.h"
#include <ctype.h>
#include <inttypes.h>
void ffPrepareCommandOption(FFdata* data)
{
//If we don't have a custom structure, use the default one
if(data->structure.length == 0)
ffStrbufAppendS(&data->structure, FASTFETCH_DATATEXT_STRUCTURE); // Cannot use `ffStrbufSetStatic` here because we will modify the string
if(ffStrbufContainIgnCaseS(&data->structure, FF_CPUUSAGE_MODULE_NAME))
ffPrepareCPUUsage();
if(ffStrbufContainIgnCaseS(&data->structure, FF_DISKIO_MODULE_NAME))
{
__attribute__((__cleanup__(ffDestroyDiskIOOptions))) FFDiskIOOptions options;
ffInitDiskIOOptions(&options);
ffPrepareDiskIO(&options);
}
if(ffStrbufContainIgnCaseS(&data->structure, FF_NETIO_MODULE_NAME))
{
__attribute__((__cleanup__(ffDestroyNetIOOptions))) FFNetIOOptions options;
ffInitNetIOOptions(&options);
ffPrepareNetIO(&options);
}
if(instance.config.general.multithreading)
{
if(ffStrbufContainIgnCaseS(&data->structure, FF_PUBLICIP_MODULE_NAME))
{
__attribute__((__cleanup__(ffDestroyPublicIpOptions))) FFPublicIPOptions options;
ffInitPublicIpOptions(&options);
ffPreparePublicIp(&options);
}
if(ffStrbufContainIgnCaseS(&data->structure, FF_WEATHER_MODULE_NAME))
{
__attribute__((__cleanup__(ffDestroyWeatherOptions))) FFWeatherOptions options;
ffInitWeatherOptions(&options);
ffPrepareWeather(&options);
}
}
}
static void genJsonConfig(FFModuleBaseInfo* baseInfo, void* options, yyjson_mut_doc* doc)
{
yyjson_mut_val* modules = yyjson_mut_obj_get(doc->root, "modules");
if (!modules)
modules = yyjson_mut_obj_add_arr(doc, doc->root, "modules");
FF_STRBUF_AUTO_DESTROY type = ffStrbufCreateS(baseInfo->name);
ffStrbufLowerCase(&type);
if (instance.state.fullConfig)
{
yyjson_mut_val* module = yyjson_mut_obj(doc);
yyjson_mut_obj_add_strbuf(doc, module, "type", &type);
if (baseInfo->generateJsonConfig)
baseInfo->generateJsonConfig(options, doc, module);
if (yyjson_mut_obj_size(module) > 1)
yyjson_mut_arr_add_val(modules, module);
else
yyjson_mut_arr_add_strbuf(doc, modules, &type);
}
else
{
yyjson_mut_arr_add_strbuf(doc, modules, &type);
}
}
static void genJsonResult(FFModuleBaseInfo* baseInfo, void* options, yyjson_mut_doc* doc)
{
yyjson_mut_val* module = yyjson_mut_arr_add_obj(doc, doc->root);
yyjson_mut_obj_add_str(doc, module, "type", baseInfo->name);
if (baseInfo->generateJsonResult)
baseInfo->generateJsonResult(options, doc, module);
else
yyjson_mut_obj_add_str(doc, module, "error", "Unsupported for JSON format");
}
static void parseStructureCommand(
const char* line,
void (*fn)(FFModuleBaseInfo* baseInfo, void* options, yyjson_mut_doc* jsonDoc),
yyjson_mut_doc* jsonDoc
)
{
if(ffCharIsEnglishAlphabet(line[0]))
{
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(line[0]) - 'A']; *modules; ++modules)
{
FFModuleBaseInfo* baseInfo = *modules;
if (ffStrEqualsIgnCase(line, baseInfo->name))
{
uint8_t optionBuf[FF_OPTION_MAX_SIZE];
baseInfo->initOptions(optionBuf);
if (__builtin_expect(jsonDoc != NULL, false))
fn(baseInfo, optionBuf, jsonDoc);
else
baseInfo->printModule(optionBuf);
baseInfo->destroyOptions(optionBuf);
return;
}
}
}
ffPrintError(line, 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "<no implementation provided>");
}
void ffPrintCommandOption(FFdata* data, yyjson_mut_doc* jsonDoc)
{
//Parse the structure and call the modules
int32_t thres = instance.config.display.stat;
uint32_t startIndex = 0;
while (startIndex < data->structure.length)
{
uint32_t colonIndex = ffStrbufNextIndexC(&data->structure, startIndex, ':');
data->structure.chars[colonIndex] = '\0';
double ms = 0;
if(thres >= 0)
ms = ffTimeGetTick();
parseStructureCommand(data->structure.chars + startIndex, genJsonResult, jsonDoc);
if(thres >= 0)
{
ms = ffTimeGetTick() - ms;
if (jsonDoc)
{
yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(jsonDoc->root);
yyjson_mut_obj_add_real(jsonDoc, moduleJson, "stat", ms);
}
else
{
char str[64];
int len = snprintf(str, sizeof str, "%.3fms", ms);
if (thres > 0)
snprintf(str, sizeof str, "\e[%sm%.3fms\e[m", (ms <= thres ? FF_COLOR_FG_GREEN : ms <= 2 * thres ? FF_COLOR_FG_YELLOW : FF_COLOR_FG_RED), ms);
printf("\e7\e[1A\e[9999999C\e[%dD%s\e8", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
}
}
#if defined(_WIN32)
if (!jsonDoc && !instance.config.display.noBuffer) fflush(stdout);
#endif
startIndex = colonIndex + 1;
}
}
void ffMigrateCommandOptionToJsonc(FFdata* data, yyjson_mut_doc* jsonDoc)
{
//If we don't have a custom structure, use the default one
if(data->structure.length == 0)
ffStrbufAppendS(&data->structure, FASTFETCH_DATATEXT_STRUCTURE); // Cannot use `ffStrbufSetStatic` here because we will modify the string
//Parse the structure and call the modules
uint32_t startIndex = 0;
while (startIndex < data->structure.length)
{
uint32_t colonIndex = ffStrbufNextIndexC(&data->structure, startIndex, ':');
data->structure.chars[colonIndex] = '\0';
parseStructureCommand(data->structure.chars + startIndex, genJsonConfig, jsonDoc);
startIndex = colonIndex + 1;
}
}
+4 -10
View File
@@ -1,14 +1,8 @@
#pragma once
#include "fastfetch.h"
// Things only needed by fastfetch
typedef struct FFdata
{
FFstrbuf structure;
bool configLoaded;
} FFdata;
#include "common/ffdata.h"
void ffPrepareCommandOption(FFdata* data);
void ffPrintCommandOption(FFdata* data, yyjson_mut_doc* jsonDoc);
void ffMigrateCommandOptionToJsonc(FFdata* data, yyjson_mut_doc* jsonDoc);
void ffPrintCommandOption(FFdata* data);
void ffMigrateCommandOptionToJsonc(FFdata* data);
bool ffParseModuleOptions(const char* key, const char* value);
+8 -3
View File
@@ -3,7 +3,7 @@
#ifdef FF_HAVE_DBUS
#include <dbus/dbus.h>
#include "util/FFstrbuf.h"
#include "common/FFstrbuf.h"
#include "common/library.h"
typedef struct FFDBusLibrary
@@ -19,6 +19,7 @@ typedef struct FFDBusLibrary
FF_LIBRARY_SYMBOL(dbus_message_iter_next)
FF_LIBRARY_SYMBOL(dbus_message_unref)
FF_LIBRARY_SYMBOL(dbus_connection_send_with_reply_and_block)
FF_LIBRARY_SYMBOL(dbus_connection_unref)
} FFDBusLibrary;
typedef struct FFDBusData
@@ -31,14 +32,18 @@ const char* ffDBusLoadData(DBusBusType busType, FFDBusData* data); //Returns an
bool ffDBusGetString(FFDBusData* dbus, DBusMessageIter* iter, FFstrbuf* result);
bool ffDBusGetBool(FFDBusData* dbus, DBusMessageIter* iter, bool* result);
bool ffDBusGetUint(FFDBusData* dbus, DBusMessageIter* iter, uint32_t* result);
DBusMessage* ffDBusGetMethodReply(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* method, const char* arg);
DBusMessage* ffDBusGetMethodReply(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* method, const char* arg1, const char* arg2);
DBusMessage* ffDBusGetProperty(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property);
bool ffDBusGetPropertyString(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, FFstrbuf* result);
bool ffDBusGetInt(FFDBusData* dbus, DBusMessageIter* iter, int32_t* result);
bool ffDBusGetPropertyUint(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, uint32_t* result);
void ffDBusDestroyData(FFDBusData* data);
static inline DBusMessage* ffDBusGetAllProperties(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface)
{
return ffDBusGetMethodReply(dbus, busName, objectPath, "org.freedesktop.DBus.Properties", "GetAll", interface);
return ffDBusGetMethodReply(dbus, busName, objectPath, "org.freedesktop.DBus.Properties", "GetAll", interface, NULL);
}
#define FF_DBUS_AUTO_DESTROY_DATA __attribute__((__cleanup__(ffDBusDestroyData)))
#endif // FF_HAVE_DBUS
+2
View File
@@ -28,4 +28,6 @@ static inline const char* ffFindFileName(const char* file)
#define FF_DEBUG(format, ...) FF_DEBUG_PRINT(__FILE__, __LINE__, format, ##__VA_ARGS__)
#if _WIN32
const char* ffDebugWin32Error(unsigned long errorCode);
#endif
-87
View File
@@ -1,87 +0,0 @@
#include "duration.h"
void ffDurationAppendNum(uint64_t totalSeconds, FFstrbuf* result)
{
const FFOptionsDisplay* options = &instance.config.display;
const char* space = instance.config.display.durationSpaceBeforeUnit != FF_SPACE_BEFORE_UNIT_NEVER ? " " : "";
if(totalSeconds < 60)
{
ffStrbufAppendF(result, options->durationAbbreviation ? "%u%ssec" : "%u%ssecond", (unsigned) totalSeconds, space);
if (totalSeconds != 1)
ffStrbufAppendC(result, 's');
return;
}
uint32_t seconds = (uint32_t) (totalSeconds % 60);
totalSeconds /= 60;
if (seconds >= 30)
totalSeconds++;
uint32_t minutes = (uint32_t) (totalSeconds % 60);
totalSeconds /= 60;
uint32_t hours = (uint32_t) (totalSeconds % 24);
totalSeconds /= 24;
uint32_t days = (uint32_t) totalSeconds;
if(days > 0)
{
if(options->durationAbbreviation)
{
ffStrbufAppendF(result, "%u%sd", days, space);
if(hours > 0 || minutes > 0)
ffStrbufAppendC(result, ' ');
}
else
{
ffStrbufAppendF(result, "%u%sday", days, space);
if(days > 1)
ffStrbufAppendC(result, 's');
if(days >= 100)
ffStrbufAppendS(result, "(!)");
if(hours > 0 || minutes > 0)
ffStrbufAppendS(result, ", ");
}
}
if(hours > 0)
{
if(options->durationAbbreviation)
{
ffStrbufAppendF(result, "%u%sh", hours, space);
if (minutes > 0)
ffStrbufAppendC(result, ' ');
}
else
{
ffStrbufAppendF(result, "%u%shour", hours, space);
if(hours > 1)
ffStrbufAppendC(result, 's');
if(minutes > 0)
ffStrbufAppendS(result, ", ");
}
}
if(minutes > 0)
{
if(options->durationAbbreviation)
{
ffStrbufAppendF(result, "%u%sm", minutes, space);
}
else
{
ffStrbufAppendF(result, "%u%smin", minutes, space);
if(minutes > 1)
ffStrbufAppendC(result, 's');
}
}
}
+2
View File
@@ -1,3 +1,5 @@
#pragma once
#include "fastfetch.h"
void ffDurationAppendNum(uint64_t totalSeconds, FFstrbuf* result);
@@ -1,7 +1,7 @@
#pragma once
#include <stdint.h>
#include "util/FFstrbuf.h"
#include "common/FFstrbuf.h"
void ffEdidGetVendorAndModel(const uint8_t edid[128], FFstrbuf* result);
bool ffEdidGetName(const uint8_t edid[128], FFstrbuf* name);
+24
View File
@@ -0,0 +1,24 @@
#pragma once
#include "common/FFstrbuf.h"
typedef enum __attribute__((__packed__)) FFDataResultDocType
{
FF_RESULT_DOC_TYPE_DEFAULT = 0,
FF_RESULT_DOC_TYPE_JSON,
FF_RESULT_DOC_TYPE_CONFIG,
FF_RESULT_DOC_TYPE_CONFIG_FULL,
} FFDataResultDocType;
// FFdata aggregates configuration, generation parameters, and output state used by fastfetch.
// It holds the parsed configuration document, a mutable JSON document for results, and related metadata.
typedef struct FFdata
{
yyjson_doc* configDoc; // Parsed JSON configuration document
yyjson_mut_doc* resultDoc; // Mutable JSON document for storing results
FFstrbuf structure; // Custom output structure from command line
FFstrbuf structureDisabled; // Disabled modules in the output structure from command line
FFstrbuf genConfigPath; // Path to generate configuration file
FFDataResultDocType docType; // Type of result document
bool configLoaded;
} FFdata;
-221
View File
@@ -1,221 +0,0 @@
#include "fastfetch.h"
#include "common/font.h"
#include <string.h>
#include <ctype.h>
void ffFontInit(FFfont* font)
{
// Ensure no memory allocates
ffStrbufInit(&font->pretty);
ffStrbufInit(&font->name);
ffStrbufInit(&font->size);
ffListInit(&font->styles, sizeof(FFstrbuf));
}
static void strbufAppendNSExcludingC(FFstrbuf* strbuf, uint32_t length, const char* value, char exclude)
{
if(value == NULL || length == 0)
return;
ffStrbufEnsureFree(strbuf, length);
for(uint32_t i = 0; i < length; i++)
{
if(value[i] != exclude)
strbuf->chars[strbuf->length++] = value[i];
}
strbuf->chars[strbuf->length] = '\0';
}
static void fontInitPretty(FFfont* font)
{
ffStrbufAppend(&font->pretty, &font->name);
if(font->size.length == 0 && font->styles.length == 0)
return;
else if(font->pretty.length == 0)
ffStrbufAppendS(&font->pretty, "default");
ffStrbufAppendS(&font->pretty, " (");
if(font->size.length > 0)
{
ffStrbufAppend(&font->pretty, &font->size);
ffStrbufAppendS(&font->pretty, "pt");
if(font->styles.length > 0)
ffStrbufAppendS(&font->pretty, ", ");
}
for(uint32_t i = 0; i < font->styles.length; i++)
{
ffStrbufAppend(&font->pretty, FF_LIST_GET(FFstrbuf, font->styles, i));
if(i < font->styles.length - 1)
ffStrbufAppendS(&font->pretty, ", ");
}
ffStrbufAppendC(&font->pretty, ')');
}
void ffFontInitQt(FFfont* font, const char* data)
{
ffFontInit(font);
//See https://doc.qt.io/qt-5/qfont.html#toString
//Family
data = ffStrbufAppendSUntilC(&font->name, data, ',');
ffStrbufTrim(&font->name, ' ');
if (!data) goto exit;
data++;
//Size
data = ffStrbufAppendSUntilC(&font->size, data, ',');
ffStrbufTrim(&font->size, ' ');
if (!data) goto exit;
data++;
//Style
data = strrchr(data, ',');
if (!data) goto exit;
data++;
if (isalpha(*data))
{
do
{
FFstrbuf* style = (FFstrbuf*) ffListAdd(&font->styles);
ffStrbufInit(style);
data = ffStrbufAppendSUntilC(style, data, ' ');
if (data) data++;
} while (data);
}
exit:
fontInitPretty(font);
}
static void fontPangoParseWord(const char** data, FFfont* font, FFstrbuf* alternativeBuffer)
{
while(**data == ' ' || **data == '\t' || **data == ',')
++(*data);
const char* wordStart = *data;
while(**data != ' ' && **data != '\t' && **data != ',' && **data != '\0' && **data != '`' && **data != '\\')
++(*data);
uint32_t wordLength = (uint32_t) (*data - wordStart);
if(wordLength == 0)
return;
if(**data == '\0' || **data == '`' || **data == '\\')
{
ffStrbufAppendNS(&font->size, wordLength, wordStart);
if(ffStrbufEndsWithS(&font->size, "px"))
ffStrbufSubstrBefore(&font->size, font->size.length - 2);
double dummy;
if(sscanf(font->size.chars, "%lf", &dummy) == 1)
return;
ffStrbufClear(&font->size);
}
if(
strncasecmp(wordStart, "Ultra", 5) == 0 ||
strncasecmp(wordStart, "Extra", 5) == 0 ||
strncasecmp(wordStart, "Semi", 4) == 0 ||
strncasecmp(wordStart, "Demi", 4) == 0 ||
strncasecmp(wordStart, "Normal", wordLength) == 0 ||
strncasecmp(wordStart, "Roman", wordLength) == 0 ||
strncasecmp(wordStart, "Oblique", wordLength) == 0 ||
strncasecmp(wordStart, "Italic", wordLength) == 0 ||
strncasecmp(wordStart, "Thin", wordLength) == 0 ||
strncasecmp(wordStart, "Light", wordLength) == 0 ||
strncasecmp(wordStart, "Bold", wordLength) == 0 ||
strncasecmp(wordStart, "Black", wordLength) == 0 ||
strncasecmp(wordStart, "Condensed", wordLength) == 0 ||
strncasecmp(wordStart, "Expanded", wordLength) == 0
) {
if(alternativeBuffer == NULL)
{
alternativeBuffer = (FFstrbuf*) ffListAdd(&font->styles);
ffStrbufInit(alternativeBuffer);
}
strbufAppendNSExcludingC(alternativeBuffer, wordLength, wordStart, '-');
if(
strncasecmp(wordStart, "Ultra ", 6) == 0 ||
strncasecmp(wordStart, "Extra ", 6) == 0 ||
strncasecmp(wordStart, "Semi ", 5) == 0 ||
strncasecmp(wordStart, "Demi ", 5) == 0
) {
fontPangoParseWord(data, font, alternativeBuffer);
}
return;
}
if(alternativeBuffer != NULL)
{
strbufAppendNSExcludingC(alternativeBuffer, wordLength, wordStart, '-');
return;
}
if(font->name.length > 0)
ffStrbufAppendC(&font->name, ' ');
ffStrbufAppendNS(&font->name, wordLength, wordStart);
}
void ffFontInitPango(FFfont* font, const char* data)
{
ffFontInit(font);
while(*data != '\0' && *data != '`' && *data != '\\')
fontPangoParseWord(&data, font, NULL);
fontInitPretty(font);
}
void ffFontInitValues(FFfont* font, const char* name, const char* size)
{
ffFontInit(font);
ffStrbufAppendS(&font->name, name);
ffStrbufTrim(&font->name, '"');
ffStrbufAppendS(&font->size, size);
fontInitPretty(font);
}
void ffFontInitWithSpace(FFfont* font, const char* rawName)
{
const char* pspace = strrchr(rawName, ' ');
if(pspace == NULL)
{
ffFontInitCopy(font, rawName);
return;
}
ffFontInit(font);
ffStrbufAppendNS(&font->name, (uint32_t)(pspace - rawName), rawName);
ffStrbufAppendS(&font->size, pspace + 1);
fontInitPretty(font);
}
void ffFontDestroy(FFfont* font)
{
ffStrbufDestroy(&font->pretty);
ffStrbufDestroy(&font->name);
ffStrbufDestroy(&font->size);
FF_LIST_FOR_EACH(FFstrbuf, str, font->styles)
ffStrbufDestroy(str);
ffListDestroy(&font->styles);
}
+5 -2
View File
@@ -1,7 +1,7 @@
#pragma once
#include "util/FFstrbuf.h"
#include "util/FFlist.h"
#include "common/FFstrbuf.h"
#include "common/FFlist.h"
typedef struct FFfont
{
@@ -15,6 +15,9 @@ void ffFontInit(FFfont* font);
void ffFontInitQt(FFfont* font, const char* data);
void ffFontInitPango(FFfont* font, const char* data);
void ffFontInitValues(FFfont* font, const char* name, const char* size);
void ffFontInitXlfd(FFfont* font, const char* xlfd);
void ffFontInitXft(FFfont* font, const char* xft);
void ffFontInitMoveValues(FFfont* font, FFstrbuf* name, FFstrbuf* size, FFstrbuf* style);
void ffFontInitWithSpace(FFfont* font, const char* rawName);
void ffFontDestroy(FFfont* font);
+1 -1
View File
@@ -1,6 +1,6 @@
#pragma once
#include "util/FFstrbuf.h"
#include "common/FFstrbuf.h"
typedef enum __attribute__((__packed__)) FFformatArgType
{
-17
View File
@@ -1,17 +0,0 @@
#include "frequency.h"
bool ffFreqAppendNum(uint32_t mhz, FFstrbuf* result)
{
if (mhz == 0)
return false;
const FFOptionsDisplay* options = &instance.config.display;
const char* space = options->freqSpaceBeforeUnit == FF_SPACE_BEFORE_UNIT_NEVER ? "" : " ";
int8_t ndigits = options->freqNdigits;
if (ndigits >= 0)
ffStrbufAppendF(result, "%.*f%sGHz", ndigits, mhz / 1000., space);
else
ffStrbufAppendF(result, "%u%sMHz", (unsigned) mhz, space);
return true;
}
+2
View File
@@ -1,3 +1,5 @@
#pragma once
#include "fastfetch.h"
bool ffFreqAppendNum(uint32_t mhz, FFstrbuf* result);
@@ -1,3 +1,3 @@
#include "util/FFstrbuf.h"
#include "common/FFstrbuf.h"
bool ffGetFileVersion(const char* filePath, FFstrbuf* version);
@@ -1,6 +1,6 @@
#include "FFPlatform_private.h"
#include "util/stringUtils.h"
#include "common/io/io.h"
#include "common/stringUtils.h"
#include "common/io.h"
#include "detection/version/version.h"
void ffPlatformInit(FFPlatform* platform)
@@ -10,12 +10,17 @@ void ffPlatformInit(FFPlatform* platform)
ffListInit(&platform->configDirs, sizeof(FFstrbuf));
ffListInit(&platform->dataDirs, sizeof(FFstrbuf));
ffStrbufInit(&platform->exePath);
ffStrbufInit(&platform->cwd);
ffStrbufInit(&platform->userName);
ffStrbufInit(&platform->fullUserName);
ffStrbufInit(&platform->hostName);
ffStrbufInit(&platform->userShell);
#ifdef _WIN32
ffStrbufInit(&platform->sid);
#endif
FFPlatformSysinfo* info = &platform->sysinfo;
ffStrbufInit(&info->name);
@@ -45,18 +50,22 @@ void ffPlatformDestroy(FFPlatform* platform)
ffStrbufDestroy(dir);
ffListDestroy(&platform->dataDirs);
ffStrbufDestroy(&platform->exePath);
ffStrbufDestroy(&platform->cwd);
ffStrbufDestroy(&platform->userName);
ffStrbufDestroy(&platform->hostName);
ffStrbufDestroy(&platform->userShell);
ffStrbufDestroy(&platform->fullUserName);
#ifdef _WIN32
ffStrbufDestroy(&platform->sid);
#endif
FFPlatformSysinfo* info = &platform->sysinfo;
ffStrbufDestroy(&info->architecture);
ffStrbufDestroy(&info->name);
ffStrbufDestroy(&info->release);
ffStrbufDestroy(&info->version);
ffStrbufDestroy(&info->displayVersion);
}
void ffPlatformPathAddAbsolute(FFlist* dirs, const char* path)
@@ -1,6 +1,6 @@
#pragma once
#include "FFPlatform.h"
#include "common/FFPlatform.h"
void ffPlatformInitImpl(FFPlatform* platform);
@@ -1,7 +1,9 @@
#include "FFPlatform_private.h"
#include "util/stringUtils.h"
#include "common/FFstrbuf.h"
#include "common/arrayUtils.h"
#include "common/stringUtils.h"
#include "common/io.h"
#include "fastfetch_config.h"
#include "common/io/io.h"
#include <unistd.h>
#include <pwd.h>
@@ -10,10 +12,14 @@
#include <paths.h>
#ifdef __APPLE__
#include <libproc.h>
#include <mach-o/dyld.h>
#include <sys/sysctl.h>
#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
#elif defined(__FreeBSD__) || defined(__NetBSD__)
#include <sys/sysctl.h>
#elif defined(__OpenBSD__)
#include <sys/sysctl.h>
#include <kvm.h>
#include "common/path.h"
#elif defined(__HAIKU__)
#include <image.h>
#include <OS.h>
@@ -21,21 +27,25 @@
static void getExePath(FFPlatform* platform)
{
char exePath[PATH_MAX + 1];
#ifdef __linux__
char exePath[PATH_MAX];
#if defined(__linux__) || defined (__GNU__)
ssize_t exePathLen = readlink("/proc/self/exe", exePath, sizeof(exePath) - 1);
if (exePathLen >= 0)
exePath[exePathLen] = '\0';
#elif defined(__APPLE__)
int exePathLen = proc_pidpath((int) getpid(), exePath, sizeof(exePath));
uint32_t exePathLen = sizeof(exePath);
if (_NSGetExecutablePath(exePath, &exePathLen) == 0)
exePathLen = (uint32_t) strlen(exePath);
else
exePathLen = 0;
#elif defined(__FreeBSD__) || defined(__NetBSD__)
size_t exePathLen = sizeof(exePath);
if(sysctl(
(int[]){CTL_KERN,
#ifdef __FreeBSD__
KERN_PROC, KERN_PROC_PATHNAME, (int) getpid()
KERN_PROC, KERN_PROC_PATHNAME, (pid_t) platform->pid
#else
KERN_PROC_ARGS, (int) getpid(), KERN_PROC_PATHNAME
KERN_PROC_ARGS, platform->pid, KERN_PROC_PATHNAME
#endif
}, 4,
exePath, &exePathLen,
@@ -45,7 +55,81 @@ static void getExePath(FFPlatform* platform)
else
exePathLen--; // remove terminating NUL
#elif defined(__OpenBSD__)
// OpenBSD doesn't have a reliable way to get the executable path.
// Current implementation uses argv[0], which can be easily spoofed.
// See #2195
size_t exePathLen = 0;
kvm_t* kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, NULL);
if (kd)
{
int kpCount;
struct kinfo_proc* kp = kvm_getprocs(kd, KERN_PROC_PID, (pid_t) platform->pid, sizeof(*kp), &kpCount);
if (kp && kpCount == 1)
{
char** argv = kvm_getargv(kd, kp, 0);
if (argv && argv[0])
{
char* arg0 = argv[0];
if (arg0[0])
{
if (strchr(arg0, '/') != NULL) // likely a path (absolute or relative)
{
exePathLen = strlen(arg0);
if (exePathLen < ARRAY_SIZE(exePath))
{
memcpy(exePath, arg0, exePathLen);
exePath[exePathLen] = '\0';
}
else
exePathLen = 0;
}
else
{
FF_STRBUF_AUTO_DESTROY tmpPath = ffStrbufCreate();
if (ffFindExecutableInPath(arg0, &tmpPath) == NULL && tmpPath.length < ARRAY_SIZE(exePath))
{
memcpy(exePath, tmpPath.chars, tmpPath.length + 1);
exePathLen = tmpPath.length;
}
}
if (exePathLen > 0)
{
struct stat st;
if (stat(exePath, &st) == 0 && S_ISREG(st.st_mode))
{
int cntp;
struct kinfo_file* kf = kvm_getfiles(kd, KERN_FILE_BYPID, platform->pid, sizeof(*kf), &cntp);
if (kf)
{
int i;
for (i = 0; i < cntp; i++)
{
if (kf[i].fd_fd == KERN_FILE_TEXT)
{
// KERN_FILE_TEXT is the executable file, not a shared library, and should be unique in the list.
if (st.st_dev != (dev_t)kf[i].va_fsid || st.st_ino != (ino_t)kf[i].va_fileid)
i = -1;
break;
}
}
if (i < 0)
exePathLen = 0;
}
else
{
// If we can't get the list of open files, we can't verify that the file is actually the executable
// Assume it is
}
}
else
exePathLen = 0;
}
}
}
}
kvm_close(kd);
}
#elif defined(__sun)
ssize_t exePathLen = readlink("/proc/self/path/a.out", exePath, sizeof(exePath) - 1);
if (exePathLen >= 0)
@@ -57,7 +141,7 @@ static void getExePath(FFPlatform* platform)
while (get_next_image_info(B_CURRENT_TEAM, &cookie, &info) == B_OK) {
if (info.type == B_APP_IMAGE) {
exePathLen = strlcpy(exePath, info.name, PATH_MAX);
exePathLen = strlcpy(exePath, info.name, sizeof(exePath));
break;
}
}
@@ -176,13 +260,16 @@ static void getDataDirs(FFPlatform* platform)
static void getUserName(FFPlatform* platform, const struct passwd* pwd)
{
const char* user = getenv("USER");
if(!ffStrSet(user) && pwd)
user = pwd->pw_name;
ffStrbufAppendS(&platform->userName, user);
if (pwd) ffStrbufAppendS(&platform->fullUserName, pwd->pw_gecos);
if (pwd)
{
ffStrbufSetS(&platform->userName, pwd->pw_name);
ffStrbufSetS(&platform->fullUserName, pwd->pw_gecos);
ffStrbufTrimSpace(&platform->fullUserName);
}
else
{
ffStrbufSetS(&platform->userName, getenv("USER"));
}
}
static void getHostName(FFPlatform* platform, const struct utsname* uts)
@@ -211,7 +298,6 @@ static void getSysinfo(FFPlatformSysinfo* info, const struct utsname* uts)
else
#endif
ffStrbufAppendS(&info->architecture, uts->machine);
ffStrbufInit(&info->displayVersion);
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__OpenBSD__) || defined(__NetBSD__)
size_t length = sizeof(info->pageSize);
@@ -221,15 +307,28 @@ static void getSysinfo(FFPlatformSysinfo* info, const struct utsname* uts)
#endif
}
static void getCwd(FFPlatform* platform)
{
char cwd[PATH_MAX];
if (getcwd(cwd, sizeof(cwd)) != NULL)
{
ffStrbufSetS(&platform->cwd, cwd);
ffStrbufEnsureEndsWithC(&platform->cwd, '/');
}
}
void ffPlatformInitImpl(FFPlatform* platform)
{
struct passwd* pwd = getpwuid(getuid());
platform->pid = (uint32_t) getpid();
platform->uid = getuid();
struct passwd* pwd = getpwuid(platform->uid);
struct utsname uts;
if(uname(&uts) < 0)
memset(&uts, 0, sizeof(uts));
getExePath(platform);
getCwd(platform);
getHomeDir(platform, pwd);
getCacheDir(platform);
getConfigDirs(platform);
@@ -1,13 +1,15 @@
#include "FFPlatform_private.h"
#include "common/io/io.h"
#include "common/io.h"
#include "common/library.h"
#include "util/stringUtils.h"
#include "util/windows/unicode.h"
#include "util/windows/registry.h"
#include "util/windows/nt.h"
#include "common/mallocHelper.h"
#include "common/stringUtils.h"
#include "common/windows/unicode.h"
#include "common/windows/registry.h"
#include "common/windows/nt.h"
#include <Windows.h>
#include <windows.h>
#include <shlobj.h>
#include <sddl.h>
#define SECURITY_WIN32 1 // For secext.h
#include <secext.h>
@@ -16,7 +18,7 @@ static void getExePath(FFPlatform* platform)
{
wchar_t exePathW[MAX_PATH];
DWORD exePathWLen = GetModuleFileNameW(NULL, exePathW, MAX_PATH);
if (exePathWLen == 0 && exePathWLen >= MAX_PATH) return;
if (exePathWLen == 0 || exePathWLen >= MAX_PATH) return;
FF_AUTO_CLOSE_FD HANDLE hPath = CreateFileW(exePathW, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (hPath != INVALID_HANDLE_VALUE)
@@ -70,15 +72,15 @@ static void getCacheDir(FFPlatform* platform)
static void platformPathAddKnownFolder(FFlist* dirs, REFKNOWNFOLDERID folderId)
{
PWSTR pPath = NULL;
if(SUCCEEDED(SHGetKnownFolderPath(folderId, 0, NULL, &pPath)))
if (SUCCEEDED(SHGetKnownFolderPath(folderId, KF_FLAG_DEFAULT, NULL, &pPath)))
{
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreateWS(pPath);
CoTaskMemFree(pPath);
ffStrbufReplaceAllC(&buffer, '\\', '/');
ffStrbufEnsureEndsWithC(&buffer, '/');
if (!ffListContains(dirs, &buffer, (void*) ffStrbufEqual))
ffStrbufInitMove((FFstrbuf*) ffListAdd(dirs), &buffer);
}
CoTaskMemFree(pPath);
}
static void platformPathAddEnvSuffix(FFlist* dirs, const char* env, const char* suffix)
@@ -136,55 +138,76 @@ static void getDataDirs(FFPlatform* platform)
static void getUserName(FFPlatform* platform)
{
const char* userName = getenv("USERNAME");
if (ffStrSet(userName))
ffStrbufSetS(&platform->userName, userName);
else
{
wchar_t buffer[256];
DWORD len = ARRAY_SIZE(buffer);
if(GetUserNameW(buffer, &len))
ffStrbufSetWS(&platform->userName, buffer);
}
wchar_t buffer[256];
DWORD len = ARRAY_SIZE(buffer);
if (GetUserNameExW(NameDisplay, buffer, &len))
DWORD size = ARRAY_SIZE(buffer);
if (GetUserNameExW(NameDisplay, buffer, &size))
ffStrbufSetWS(&platform->fullUserName, buffer);
size = ARRAY_SIZE(buffer);
if (GetUserNameW(buffer, &size)) // GetUserNameExW(10002)?
{
ffStrbufSetWS(&platform->userName, buffer);
size = 0;
DWORD refDomainSize = 0;
SID_NAME_USE sidNameUse = SidTypeUnknown;
LookupAccountNameW(NULL, buffer, NULL, &size, NULL, &refDomainSize, &sidNameUse);
if (size > 0)
{
FF_AUTO_FREE PSID sid = (PSID) malloc(size);
FF_AUTO_FREE LPWSTR refDomain = (LPWSTR) malloc(refDomainSize * sizeof(wchar_t));
if (LookupAccountNameW(NULL, buffer, sid, &size, refDomain, &refDomainSize, &sidNameUse))
{
LPWSTR sidString;
if (ConvertSidToStringSidW(sid, &sidString))
{
ffStrbufSetWS(&platform->sid, sidString);
LocalFree(sidString);
}
}
}
}
else
ffStrbufSetS(&platform->userName, getenv("USERNAME"));
}
static void getHostName(FFPlatform* platform)
{
wchar_t buffer[128];
wchar_t buffer[256];
DWORD len = ARRAY_SIZE(buffer);
if(GetComputerNameExW(ComputerNameDnsHostname, buffer, &len))
ffStrbufSetWS(&platform->hostName, buffer);
if (GetComputerNameExW(ComputerNameDnsHostname, buffer, &len) && len > 0)
ffStrbufSetNWS(&platform->hostName, len, buffer);
else
{
len = ARRAY_SIZE(buffer);
if (GetComputerNameExW(ComputerNameNetBIOS, buffer, &len) && len > 0)
ffStrbufSetNWS(&platform->hostName, len, buffer);
}
}
static void getUserShell(FFPlatform* platform)
{
// Works in MSYS2
ffStrbufAppendS(&platform->userShell, getenv("SHELL"));
ffStrbufReplaceAllC(&platform->userShell, '\\', '/');
const char* userShell = getenv("SHELL");
if (userShell)
{
ffStrbufAppendS(&platform->userShell, userShell);
ffStrbufReplaceAllC(&platform->userShell, '\\', '/');
}
}
static void detectWine(FFstrbuf* buf)
static const char* detectWine(void)
{
const char * __cdecl wine_get_version(void);
HMODULE hntdll = GetModuleHandleW(L"ntdll.dll");
if (!hntdll) return;
if (!hntdll) return NULL;
FF_LIBRARY_LOAD_SYMBOL_LAZY(hntdll, wine_get_version);
if (!ffwine_get_version) return;
ffStrbufAppendS(buf, buf->length ? " - wine " : "wine ");
ffStrbufAppendS(buf, ffwine_get_version());
if (!ffwine_get_version) return NULL;
return ffwine_get_version();
}
static void getSystemReleaseAndVersion(FFPlatformSysinfo* info)
{
RTL_OSVERSIONINFOW osVersion = { .dwOSVersionInfoSize = sizeof(osVersion) };
if (!NT_SUCCESS(RtlGetVersion(&osVersion)))
return;
FF_HKEY_AUTO_DESTROY hKey = NULL;
if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", &hKey, NULL))
return;
@@ -194,44 +217,41 @@ static void getSystemReleaseAndVersion(FFPlatformSysinfo* info)
ffStrbufAppendF(&info->release,
"%u.%u.%u.%u",
(unsigned) osVersion.dwMajorVersion,
(unsigned) osVersion.dwMinorVersion,
(unsigned) osVersion.dwBuildNumber,
(unsigned) SharedUserData->NtMajorVersion,
(unsigned) SharedUserData->NtMinorVersion,
(unsigned) SharedUserData->NtBuildNumber,
(unsigned) ubr);
ffStrbufInit(&info->displayVersion);
if(!ffRegReadStrbuf(hKey, L"DisplayVersion", &info->displayVersion, NULL))
{
if (osVersion.szCSDVersion[0])
ffStrbufSetWS(&info->displayVersion, osVersion.szCSDVersion);
else
ffRegReadStrbuf(hKey, L"ReleaseId", &info->displayVersion, NULL); // For old Windows 10
}
detectWine(&info->displayVersion);
ffRegReadStrbuf(hKey, L"BuildLabEx", &info->version, NULL);
switch (osVersion.dwPlatformId)
const char* wineVersion = detectWine();
if (wineVersion)
{
case VER_PLATFORM_WIN32s:
ffStrbufSetStatic(&info->name, "WIN32s");
break;
case VER_PLATFORM_WIN32_WINDOWS:
ffStrbufSetStatic(&info->name, "WIN32_WINDOWS");
break;
case VER_PLATFORM_WIN32_NT:
ffStrbufSetStatic(&info->name, "WIN32_NT");
break;
if (instance.config.general.detectVersion)
ffStrbufSetF(&info->name, "Wine_%s", wineVersion);
else
ffStrbufSetStatic(&info->name, "Wine");
}
else
ffStrbufSetStatic(&info->name, "WIN32_NT");
}
static void getSystemArchitectureAndPageSize(FFPlatformSysinfo* info)
static void getSystemPageSize(FFPlatformSysinfo* info)
{
SYSTEM_INFO sysInfo;
GetNativeSystemInfo(&sysInfo);
SYSTEM_BASIC_INFORMATION sbi;
if (NT_SUCCESS(NtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), NULL)))
info->pageSize = sbi.PhysicalPageSize;
else
info->pageSize = 4096;
}
switch(sysInfo.wProcessorArchitecture)
static void getSystemArchitecture(FFPlatformSysinfo* info)
{
SYSTEM_PROCESSOR_INFORMATION spi;
if (NT_SUCCESS(NtQuerySystemInformation(SystemProcessorInformation, &spi, sizeof(spi), NULL)))
{
switch (spi.ProcessorArchitecture)
{
case PROCESSOR_ARCHITECTURE_AMD64:
ffStrbufSetStatic(&info->architecture, "x86_64");
break;
@@ -239,7 +259,7 @@ static void getSystemArchitectureAndPageSize(FFPlatformSysinfo* info)
ffStrbufSetStatic(&info->architecture, "ia64");
break;
case PROCESSOR_ARCHITECTURE_INTEL:
switch (sysInfo.wProcessorLevel)
switch (spi.ProcessorLevel)
{
case 4:
ffStrbufSetStatic(&info->architecture, "i486");
@@ -277,14 +297,28 @@ static void getSystemArchitectureAndPageSize(FFPlatformSysinfo* info)
default:
ffStrbufSetStatic(&info->architecture, "unknown");
break;
}
}
}
info->pageSize = sysInfo.dwPageSize;
static void getCwd(FFPlatform* platform)
{
#if _WIN64
static_assert(
offsetof(RTL_USER_PROCESS_PARAMETERS, Reserved2[5]) == 0x38,
"CurrentDirectory should be at offset 0x38 in RTL_USER_PROCESS_PARAMETERS. Structure layout mismatch detected.");
#endif
PCURDIR cwd = (PCURDIR) &NtCurrentTeb()->ProcessEnvironmentBlock->ProcessParameters->Reserved2[5];
ffStrbufSetNWS(&platform->cwd, cwd->DosPath.Length / sizeof(WCHAR), cwd->DosPath.Buffer);
ffStrbufReplaceAllC(&platform->cwd, '\\', '/');
ffStrbufEnsureEndsWithC(&platform->cwd, '/');
}
void ffPlatformInitImpl(FFPlatform* platform)
{
platform->pid = (uint32_t) GetCurrentProcessId();
getExePath(platform);
getCwd(platform);
getHomeDir(platform);
getCacheDir(platform);
getConfigDirs(platform);
@@ -295,5 +329,6 @@ void ffPlatformInitImpl(FFPlatform* platform)
getUserShell(platform);
getSystemReleaseAndVersion(&platform->sysinfo);
getSystemArchitectureAndPageSize(&platform->sysinfo);
getSystemArchitecture(&platform->sysinfo);
getSystemPageSize(&platform->sysinfo);
}
@@ -1,4 +1,4 @@
#include "FFlist.h"
#include "common/FFlist.h"
#include <stdlib.h>
#include <string.h>
@@ -1,7 +1,9 @@
#include "FFstrbuf.h"
#include "common/FFstrbuf.h"
#include "common/mallocHelper.h"
#include <ctype.h>
#include <inttypes.h>
#include <math.h>
char* CHAR_NULL_PTR = "";
@@ -20,11 +22,27 @@ void ffStrbufInitVF(FFstrbuf* strbuf, const char* format, va_list arguments)
{
assert(format != NULL);
int len = vasprintf(&strbuf->chars, format, arguments);
char* buffer = NULL;
int len = vasprintf(&buffer, format, arguments);
assert(len >= 0);
strbuf->allocated = (uint32_t)(len + 1);
strbuf->length = (uint32_t)len;
ffStrbufInitMoveNS(strbuf, (uint32_t)len, buffer);
}
// Takes ownership of `heapStr`. The caller must not free `heapStr` after calling this
// function; the memory will be managed and freed via the associated FFstrbuf.
void ffStrbufInitMoveNS(FFstrbuf* strbuf, uint32_t length, char* heapStr)
{
assert(heapStr != NULL);
strbuf->length = length;
size_t allocSize = ffMallocUsableSize(heapStr);
if (allocSize == 0)
allocSize = length + 1;
else if (allocSize > UINT32_MAX)
allocSize = UINT32_MAX;
strbuf->allocated = (uint32_t) allocSize;
strbuf->chars = heapStr;
}
void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free)
@@ -54,6 +72,7 @@ void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free)
strbuf->allocated = allocate;
}
// Ensure that at least `free` bytes are available in the buffer besides the current length
// for an empty buffer, free + 1 length memory will be allocated(+1 for the NUL)
void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free)
{
@@ -147,7 +166,7 @@ void ffStrbufAppendVF(FFstrbuf* strbuf, const char* format, va_list arguments)
uint32_t free = ffStrbufGetFree(strbuf);
int written = vsnprintf(strbuf->chars + strbuf->length, strbuf->allocated > 0 ? free + 1 : 0, format, arguments);
if(written > 0 && strbuf->length + (uint32_t) written > free)
if(written > 0 && (uint32_t) written > free)
{
ffStrbufEnsureFree(strbuf, (uint32_t) written);
written = vsnprintf(strbuf->chars + strbuf->length, (uint32_t) written + 1, format, copy);
@@ -164,7 +183,7 @@ const char* ffStrbufAppendSUntilC(FFstrbuf* strbuf, const char* value, char unti
if(value == NULL)
return NULL;
char* end = strchr(value, until);
const char* end = strchr(value, until);
if(end == NULL)
ffStrbufAppendS(strbuf, value);
else
@@ -219,6 +238,55 @@ void ffStrbufPrependC(FFstrbuf* strbuf, char c)
strbuf->length += 1;
}
void ffStrbufSetNS(FFstrbuf* strbuf, uint32_t length, const char* value)
{
assert(strbuf != NULL);
if (length == 0)
{
ffStrbufClear(strbuf);
return;
}
assert(value != NULL);
if (strbuf->allocated < length + 1)
{
if (strbuf->allocated > 0)
free(strbuf->chars);
strbuf->allocated = length + 1;
strbuf->chars = malloc(sizeof(char) * strbuf->allocated);
}
memcpy(strbuf->chars, value, length);
strbuf->length = length;
strbuf->chars[length] = '\0';
}
void ffStrbufSet(FFstrbuf* strbuf, const FFstrbuf* value)
{
assert(value && value != strbuf);
if (value->length == 0)
{
ffStrbufClear(strbuf);
return;
}
if (value->allocated == 0) // static string
{
if (strbuf->allocated != 0)
{
free(strbuf->chars);
strbuf->allocated = 0;
}
strbuf->chars = value->chars;
strbuf->length = value->length;
return;
}
ffStrbufSetNS(strbuf, value->length, value->chars);
}
void ffStrbufTrimLeft(FFstrbuf* strbuf, char c)
{
if(strbuf->length == 0)
@@ -380,7 +448,15 @@ void ffStrbufReplaceAllC(FFstrbuf* strbuf, char find, char replace)
return;
ffStrbufEnsureFree(strbuf, 0);
for (char *current_pos = strchr(strbuf->chars, find); current_pos; current_pos = strchr(current_pos + 1, find))
for (
char *current_pos = memchr(strbuf->chars, find, strbuf->length);
current_pos;
current_pos = memchr(
current_pos + 1,
find,
strbuf->length - (uint32_t)(current_pos + 1 - strbuf->chars)
)
)
*current_pos = replace;
}
@@ -542,6 +618,87 @@ int64_t ffStrbufToSInt(const FFstrbuf* strbuf, int64_t defaultValue)
return str_end == strbuf->chars ? defaultValue : (int64_t)result;
}
void ffStrbufAppendSInt(FFstrbuf* strbuf, int64_t value)
{
ffStrbufEnsureFree(strbuf, 21); // Required by yyjson_write_number
char* start = strbuf->chars + strbuf->length;
yyjson_val val = {};
unsafe_yyjson_set_sint(&val, value);
char* end = yyjson_write_number(&val, start);
assert(end != NULL);
strbuf->length += (uint32_t)(end - start);
}
void ffStrbufAppendUInt(FFstrbuf* strbuf, uint64_t value)
{
ffStrbufEnsureFree(strbuf, 21); // Required by yyjson_write_number
char* start = strbuf->chars + strbuf->length;
yyjson_val val = {};
unsafe_yyjson_set_uint(&val, value);
char* end = yyjson_write_number(&val, start);
assert(end != NULL);
strbuf->length += (uint32_t)(end - start);
}
void ffStrbufAppendDouble(FFstrbuf* strbuf, double value, int8_t precision, bool trailingZeros)
{
assert(precision <= 15); // yyjson_write_number supports up to 15 digits after the decimal point
ffStrbufEnsureFree(strbuf, 40); // Required by yyjson_write_number
char* start = strbuf->chars + strbuf->length;
if (precision == 0)
value = round(value);
yyjson_val val = {};
unsafe_yyjson_set_double(&val, value);
if (precision > 0)
unsafe_yyjson_set_fp_to_fixed(&val, precision);
// Write at most <precision> digits after the decimal point; doesn't append trailing zeros
char* end = yyjson_write_number(&val, start);
assert(end > start);
strbuf->length += (uint32_t)(end - start);
if (__builtin_expect(value > 1e21 || value < -1e21, false))
{
// If the value is too large, yyjson_write_number will write it in scientific notation
return;
}
if (trailingZeros)
{
if (precision > 1)
{
for (char* p = end - 1; *p != '.' && p > start; --p)
--precision;
if (precision > 0)
ffStrbufAppendNC(strbuf, (uint32_t) precision, '0');
}
else if (precision == 0 || (precision < 0 && end[-1] == '0'))
{
goto removeDecimalPoint;
}
}
else
{
if (end[-1] == '0')
{
removeDecimalPoint:
// yyjson always appends ".0" to make it a float point number. We need to remove it
strbuf->length -= 2;
strbuf->chars[strbuf->length] = '\0';
}
}
}
void ffStrbufUpperCase(FFstrbuf* strbuf)
{
for (uint32_t i = 0; i < strbuf->length; ++i)
@@ -566,19 +723,7 @@ void ffStrbufInsertNC(FFstrbuf* strbuf, uint32_t index, uint32_t num, char c)
strbuf->length += num;
}
/**
* @brief Read a line from a FFstrbuf.
*
* @details Behaves like getline(3) but reads from a FFstrbuf.
*
* @param[in,out] lineptr The pointer to a pointer that will be set to the start of the line.
* Can be NULL for the first call.
* @param[in,out] n The pointer to the size of the buffer of lineptr.
* @param[in] buffer The buffer to read from. The buffer must not be a string literal.
*
* @return true if a line has been read, false if the end of the buffer has been reached.
*/
bool ffStrbufGetline(char** lineptr, size_t* n, FFstrbuf* buffer)
bool ffStrbufGetdelim(char** lineptr, size_t* n, char delimiter, FFstrbuf* buffer)
{
assert(lineptr && n && buffer);
assert(buffer->allocated > 0 || (buffer->allocated == 0 && buffer->length == 0));
@@ -592,14 +737,14 @@ bool ffStrbufGetline(char** lineptr, size_t* n, FFstrbuf* buffer)
*lineptr += *n;
if (*lineptr >= pBufferEnd) // non-empty last line
return false;
**lineptr = '\n';
**lineptr = delimiter;
++*lineptr;
}
if (*lineptr >= pBufferEnd) // empty last line
return false;
size_t remaining = (size_t) (pBufferEnd - *lineptr);
char* ending = memchr(*lineptr, '\n', remaining);
char* ending = memchr(*lineptr, delimiter, remaining);
if (ending)
{
*n = (size_t) (ending - *lineptr);
@@ -610,9 +755,7 @@ bool ffStrbufGetline(char** lineptr, size_t* n, FFstrbuf* buffer)
return true;
}
/// @brief Restore the end of a line that was modified by ffStrbufGetline.
/// @warning This function should be called before breaking an ffStrbufGetline loop.
void ffStrbufGetlineRestore(char** lineptr, size_t* n, FFstrbuf* buffer)
void ffStrbufGetdelimRestore(char** lineptr, size_t* n, char delimiter, FFstrbuf* buffer)
{
assert(buffer && lineptr && n);
assert(buffer->allocated > 0 || (buffer->allocated == 0 && buffer->length == 0));
@@ -623,7 +766,7 @@ void ffStrbufGetlineRestore(char** lineptr, size_t* n, FFstrbuf* buffer)
*lineptr += *n;
if (*lineptr < buffer->chars + buffer->length)
**lineptr = '\n';
**lineptr = delimiter;
}
bool ffStrbufRemoveDupWhitespaces(FFstrbuf* strbuf)
@@ -648,7 +791,7 @@ bool ffStrbufRemoveDupWhitespaces(FFstrbuf* strbuf)
return changed;
}
/// @brief Check if a separated string contains a substring.
/// @brief Check if a separated string (comp) contains a substring (strbuf).
/// @param strbuf The substring to check.
/// @param compLength The length of the separated string to check.
/// @param comp The separated string to check.
@@ -677,6 +820,31 @@ bool ffStrbufMatchSeparatedNS(const FFstrbuf* strbuf, uint32_t compLength, const
return false;
}
/// @brief Case insensitive version of ffStrbufMatchSeparatedNS.
bool ffStrbufMatchSeparatedIgnCaseNS(const FFstrbuf* strbuf, uint32_t compLength, const char* comp, char separator)
{
if (strbuf->length == 0)
return true;
if (compLength == 0)
return false;
for (const char* p = comp; p < comp + compLength;)
{
const char* colon = memchr(p, separator, compLength);
if (colon == NULL)
return strcasecmp(strbuf->chars, p) == 0;
uint32_t substrLength = (uint32_t) (colon - p);
if (strbuf->length == substrLength && strncasecmp(strbuf->chars, p, substrLength) == 0)
return true;
p = colon + 1;
}
return false;
}
int ffStrbufAppendUtf32CodePoint(FFstrbuf* strbuf, uint32_t codepoint)
{
if (codepoint <= 0x7F) {
@@ -708,3 +876,42 @@ int ffStrbufAppendUtf32CodePoint(FFstrbuf* strbuf, uint32_t codepoint)
ffStrbufAppendS(strbuf, ""); // U+FFFD REPLACEMENT CHARACTER
return 1;
}
/// @brief Check if a separated string (strbuf) contains a substring (comp).
/// @param strbuf The separated to check.
/// @param compLength The length of the separated string to check.
/// @param comp The substring to check.
/// @param separator The separator character.
bool ffStrbufSeparatedContainNS(const FFstrbuf* strbuf, uint32_t compLength, const char* comp, char separator)
{
uint32_t startIndex = 0;
while(startIndex < strbuf->length)
{
uint32_t colonIndex = ffStrbufNextIndexC(strbuf, startIndex, separator);
uint32_t folderLength = colonIndex - startIndex;
if (folderLength == compLength && memcmp(strbuf->chars + startIndex, comp, compLength) == 0)
return true;
startIndex = colonIndex + 1;
}
return false;
}
bool ffStrbufSeparatedContainIgnCaseNS(const FFstrbuf* strbuf, uint32_t compLength, const char* comp, char separator)
{
uint32_t startIndex = 0;
while(startIndex < strbuf->length)
{
uint32_t colonIndex = ffStrbufNextIndexC(strbuf, startIndex, separator);
uint32_t folderLength = colonIndex - startIndex;
if (folderLength == compLength && strncasecmp(strbuf->chars + startIndex, comp, compLength) == 0)
return true;
startIndex = colonIndex + 1;
}
return false;
}
@@ -1,4 +1,4 @@
#include "base64.h"
#include "common/base64.h"
// https://github.com/kostya/benchmarks/blob/master/base64/test-nolib.c#L145
void ffBase64EncodeRaw(uint32_t size, const char *str, uint32_t *out_size, char *output)
@@ -1,7 +1,7 @@
#include "binary.h"
#include "common/io/io.h"
#include "util/stringUtils.h"
#include "util/mallocHelper.h"
#include "common/binary.h"
#include "common/io.h"
#include "common/stringUtils.h"
#include "common/mallocHelper.h"
#include <stdlib.h>
#include <string.h>
@@ -1,10 +1,10 @@
#include "binary.h"
#include "common/binary.h"
#if defined(FF_HAVE_ELF) || defined(__sun) || (defined(__FreeBSD__) && !defined(__DragonFly__)) || defined(__OpenBSD__) || defined(__NetBSD__)
#include "common/io/io.h"
#include "common/io.h"
#include "common/library.h"
#include "util/stringUtils.h"
#include "common/stringUtils.h"
#include <libelf.h> // #1254
#include <fcntl.h>
@@ -42,7 +42,7 @@ const char* ffBinaryExtractStrings(const char* elfFile, bool (*cb)(const char* s
if (!elfData.inited)
{
elfData.inited = true;
FF_LIBRARY_LOAD(libelf, "dlopen libelf" FF_LIBRARY_EXTENSION " failed", "libelf" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD_MESSAGE(libelf, "libelf" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libelf, elfData, elf_version)
if (elfData.ffelf_version(EV_CURRENT) == EV_NONE) return "elf_version() failed";
@@ -1,10 +1,9 @@
#include "binary.h"
#include "common/io/io.h"
#include "util/stringUtils.h"
#include "util/mallocHelper.h"
#include "common/binary.h"
#include "common/io.h"
#include "common/stringUtils.h"
#include "common/windows/nt.h"
#include <windows.h>
#include <imagehlp.h>
#include <stdlib.h>
#include <string.h>
@@ -17,19 +16,33 @@
*/
const char* ffBinaryExtractStrings(const char *peFile, bool (*cb)(const char *str, uint32_t len, void *userdata), void *userdata, uint32_t minLength)
{
// Use MapAndLoad with cleanup attribute to ensure proper unloading
__attribute__((__cleanup__(UnMapAndLoad))) LOADED_IMAGE loadedImage = {};
if (!MapAndLoad(peFile, NULL, &loadedImage, FALSE, TRUE))
return "File could not be loaded";
FF_AUTO_CLOSE_FD HANDLE hFile = CreateFileA(peFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return "CreateFileA() failed";
// Iterate through all sections in the PE file
for (ULONG i = 0; i < loadedImage.NumberOfSections; ++i)
FF_AUTO_CLOSE_FD HANDLE hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (!hMap)
return "CreateFileMappingW() failed";
void* base = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
if (!base)
return "MapViewOfFile() failed";
PIMAGE_NT_HEADERS ntHeaders = RtlImageNtHeader(base);
if (!ntHeaders)
{
UnmapViewOfFile(base);
return "RtlImageNtHeader() failed";
}
PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(ntHeaders);
for (WORD i = 0; i < ntHeaders->FileHeader.NumberOfSections; ++i, ++section)
{
PIMAGE_SECTION_HEADER section = &loadedImage.Sections[i];
// Look for initialized data sections with the name ".rdata" which typically contains string literals
if ((section->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) && ffStrEquals((const char*) section->Name, ".rdata"))
{
uint8_t *data = (uint8_t *) loadedImage.MappedAddress + section->PointerToRawData;
uint8_t *data = (uint8_t *) base + section->PointerToRawData;
// Scan the section for string literals
for (size_t off = 0; off < section->SizeOfRawData; ++off)
@@ -48,5 +61,6 @@ const char* ffBinaryExtractStrings(const char *peFile, bool (*cb)(const char *st
}
}
UnmapViewOfFile(base);
return NULL;
}
+257
View File
@@ -0,0 +1,257 @@
#include "common/commandoption.h"
#include "common/color.h"
#include "common/printing.h"
#include "common/time.h"
#include "common/jsonconfig.h"
#include "common/stringUtils.h"
#include "fastfetch_datatext.h"
#include "modules/modules.h"
#include <ctype.h>
#include <inttypes.h>
bool ffParseModuleOptions(const char* key, const char* value)
{
if (!ffStrStartsWith(key, "--") || !ffCharIsEnglishAlphabet(key[2])) return false;
if (value && !*value) value = NULL;
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(key[2]) - 'A']; *modules; ++modules)
{
FFModuleBaseInfo* baseInfo = *modules;
const char* subKey = ffOptionTestPrefix(key, baseInfo->name);
if (subKey != NULL)
{
if (subKey[0] == '\0' || subKey[0] == '-') // Key is exactly the module name or has a leading '-'
{
fprintf(stderr, "Error: unknown module key %s\n", key);
exit(477);
}
FF_STRBUF_AUTO_DESTROY moduleName = ffStrbufCreateS(baseInfo->name);
ffStrbufLowerCase(&moduleName);
FF_STRBUF_AUTO_DESTROY jsonKey = ffStrbufCreate();
bool flag = false;
for (const char* p = subKey; *p; ++p)
{
if (*p == '-')
{
if (flag)
{
fprintf(stderr, "Error: invalid double `-` in module key %s\n", key);
exit(477);
}
flag = true;
}
else
{
if (!isalpha((unsigned char)*p) && !isdigit((unsigned char)*p))
{
fprintf(stderr, "Error: invalid character `%c` in module key %s\n", *p, key);
exit(477);
}
if (flag)
{
flag = false;
ffStrbufAppendC(&jsonKey, (char) toupper((unsigned char) *p));
}
else
ffStrbufAppendC(&jsonKey, *p);
}
}
fprintf(stderr, "Error: Unsupported module option: %s\n", key);
fputs(" Support of module options has been removed. Please add the flag to the JSON config instead.\n", stderr);
fprintf(stderr, " Example (demonstration only): `{ \"modules\": [ { \"type\": \"%s\", \"%s\": %s%s%s } ] }`\n", moduleName.chars, jsonKey.chars, value ? "\"" : "", value ?: "true", value ? "\"" : "");
fputs(" See <https://github.com/fastfetch-cli/fastfetch/wiki/Configuration> for more information.\n", stderr);
exit(477);
}
}
return false;
}
void ffPrepareCommandOption(FFdata* data)
{
char* moduleType = NULL;
size_t moduleLen = 0;
while (ffStrbufGetdelim(&moduleType, &moduleLen, ':', &data->structure))
{
#define FF_IF_MODULE_MATCH(moduleNameConstant) if (moduleLen == strlen(moduleNameConstant) \
&& ffStrEqualsIgnCase(moduleType, moduleNameConstant) \
&& !ffStrbufSeparatedContainIgnCaseS(&data->structureDisabled, moduleNameConstant, ':'))
switch (moduleType[0])
{
case 'C': case 'c':
FF_IF_MODULE_MATCH(FF_CPUUSAGE_MODULE_NAME)
ffPrepareCPUUsage();
break;
case 'D': case 'd':
FF_IF_MODULE_MATCH(FF_DISKIO_MODULE_NAME)
{
__attribute__((__cleanup__(ffDestroyDiskIOOptions))) FFDiskIOOptions options;
ffInitDiskIOOptions(&options);
ffPrepareDiskIO(&options);
}
break;
case 'N': case 'n':
FF_IF_MODULE_MATCH(FF_NETIO_MODULE_NAME)
{
__attribute__((__cleanup__(ffDestroyNetIOOptions))) FFNetIOOptions options;
ffInitNetIOOptions(&options);
ffPrepareNetIO(&options);
}
break;
case 'P': case 'p':
FF_IF_MODULE_MATCH(FF_PUBLICIP_MODULE_NAME)
{
__attribute__((__cleanup__(ffDestroyPublicIpOptions))) FFPublicIPOptions options;
ffInitPublicIpOptions(&options);
ffPreparePublicIp(&options);
}
break;
case 'W': case 'w':
FF_IF_MODULE_MATCH(FF_WEATHER_MODULE_NAME)
{
__attribute__((__cleanup__(ffDestroyWeatherOptions))) FFWeatherOptions options;
ffInitWeatherOptions(&options);
ffPrepareWeather(&options);
}
break;
}
#undef FF_IF_MODULE_MATCH
}
}
static void genJsonConfig(FFdata* data, FFModuleBaseInfo* baseInfo, void* options)
{
yyjson_mut_doc* doc = data->resultDoc;
yyjson_mut_val* modules = yyjson_mut_obj_get(doc->root, "modules");
if (!modules)
modules = yyjson_mut_obj_add_arr(doc, doc->root, "modules");
FF_STRBUF_AUTO_DESTROY type = ffStrbufCreateS(baseInfo->name);
ffStrbufLowerCase(&type);
if (data->docType == FF_RESULT_DOC_TYPE_CONFIG_FULL)
{
yyjson_mut_val* module = yyjson_mut_obj(doc);
yyjson_mut_obj_add_strbuf(doc, module, "type", &type);
if (baseInfo->generateJsonConfig)
baseInfo->generateJsonConfig(options, doc, module);
if (yyjson_mut_obj_size(module) > 1)
yyjson_mut_arr_add_val(modules, module);
else
yyjson_mut_arr_add_strbuf(doc, modules, &type);
}
else
{
yyjson_mut_arr_add_strbuf(doc, modules, &type);
}
}
static void genJsonResult(FFdata* data, FFModuleBaseInfo* baseInfo, void* options)
{
yyjson_mut_doc* doc = data->resultDoc;
yyjson_mut_val* module = yyjson_mut_arr_add_obj(doc, doc->root);
yyjson_mut_obj_add_str(doc, module, "type", baseInfo->name);
if (baseInfo->generateJsonResult)
baseInfo->generateJsonResult(options, doc, module);
else
yyjson_mut_obj_add_str(doc, module, "error", "Unsupported for JSON format");
}
static void parseStructureCommand(
FFdata* data,
const char* line,
void (*fn)(FFdata*, FFModuleBaseInfo* baseInfo, void* options)
)
{
if(ffCharIsEnglishAlphabet(line[0]))
{
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(line[0]) - 'A']; *modules; ++modules)
{
FFModuleBaseInfo* baseInfo = *modules;
if (ffStrEqualsIgnCase(line, baseInfo->name))
{
uint8_t optionBuf[FF_OPTION_MAX_SIZE];
baseInfo->initOptions(optionBuf);
if (__builtin_expect(data->resultDoc != NULL, false))
fn(data, baseInfo, optionBuf);
else
baseInfo->printModule(optionBuf);
baseInfo->destroyOptions(optionBuf);
return;
}
}
}
ffPrintError(line, 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "<no implementation provided>");
}
void ffPrintCommandOption(FFdata* data)
{
//Parse the structure and call the modules
int32_t thres = instance.config.display.stat;
char* moduleType = NULL;
size_t moduleLen = 0;
while (ffStrbufGetdelim(&moduleType, &moduleLen, ':', &data->structure))
{
if (ffStrbufSeparatedContainIgnCaseS(&data->structureDisabled, moduleType, ':'))
continue;
double ms = 0;
if(thres >= 0)
ms = ffTimeGetTick();
parseStructureCommand(data, moduleType, genJsonResult);
if(thres >= 0)
{
ms = ffTimeGetTick() - ms;
if (data->resultDoc)
{
yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(data->resultDoc->root);
yyjson_mut_obj_add_real(data->resultDoc, moduleJson, "stat", ms);
}
else
{
char str[64];
int len = snprintf(str, sizeof str, "%.3fms", ms);
if (thres > 0)
snprintf(str, sizeof str, "\e[%sm%.3fms\e[m", (ms <= thres ? FF_COLOR_FG_GREEN : ms <= 2 * thres ? FF_COLOR_FG_YELLOW : FF_COLOR_FG_RED), ms);
printf("\e7\e[1A\e[9999999C\e[%dD%s\e8", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
}
}
#if defined(_WIN32)
if (!data->resultDoc && !instance.config.display.noBuffer) fflush(stdout);
#endif
}
}
void ffMigrateCommandOptionToJsonc(FFdata* data)
{
//If we don't have a custom structure, use the default one
if(data->structure.length == 0)
ffStrbufAppendS(&data->structure, FASTFETCH_DATATEXT_STRUCTURE); // Cannot use `ffStrbufSetStatic` here because we will modify the string
char* moduleType = NULL;
size_t moduleLen = 0;
while (ffStrbufGetdelim(&moduleType, &moduleLen, ':', &data->structure))
{
if (ffStrbufSeparatedContainIgnCaseS(&data->structureDisabled, moduleType, ':'))
continue;
parseStructureCommand(data, moduleType, genJsonConfig);
}
}
+68 -5
View File
@@ -1,9 +1,9 @@
#include "dbus.h"
#include "common/dbus.h"
#ifdef FF_HAVE_DBUS
#include "common/thread.h"
#include "util/stringUtils.h"
#include "common/stringUtils.h"
static bool loadLibSymbols(FFDBusLibrary* lib)
{
@@ -19,6 +19,7 @@ static bool loadLibSymbols(FFDBusLibrary* lib)
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_iter_next, false)
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_unref, false)
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_connection_send_with_reply_and_block, false)
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_connection_unref, false)
dbus = NULL; // don't auto dlclose
return true;
}
@@ -51,6 +52,15 @@ const char* ffDBusLoadData(DBusBusType busType, FFDBusData* data)
return NULL;
}
void ffDBusDestroyData(FFDBusData* data)
{
if (data->connection != NULL)
{
data->lib->ffdbus_connection_unref(data->connection);
data->connection = NULL;
}
}
bool ffDBusGetString(FFDBusData* dbus, DBusMessageIter* iter, FFstrbuf* result)
{
int argType = dbus->lib->ffdbus_message_iter_get_arg_type(iter);
@@ -162,14 +172,67 @@ bool ffDBusGetUint(FFDBusData* dbus, DBusMessageIter* iter, uint32_t* result)
return ffDBusGetUint(dbus, &subIter, result);
}
DBusMessage* ffDBusGetMethodReply(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* method, const char* arg)
bool ffDBusGetInt(FFDBusData* dbus, DBusMessageIter* iter, int32_t* result)
{
int argType = dbus->lib->ffdbus_message_iter_get_arg_type(iter);
if(argType == DBUS_TYPE_INT16)
{
int16_t value = 0;
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
*result = value;
return true;
}
if(argType == DBUS_TYPE_INT32)
{
dbus->lib->ffdbus_message_iter_get_basic(iter, result);
return true;
}
if(argType == DBUS_TYPE_BYTE)
{
uint8_t value = 0;
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
*result = value;
return true;
}
if(argType == DBUS_TYPE_UINT16)
{
uint16_t value = 0;
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
*result = (int16_t) value;
return true;
}
if(argType == DBUS_TYPE_UINT32)
{
dbus->lib->ffdbus_message_iter_get_basic(iter, result);
return true;
}
if(argType != DBUS_TYPE_VARIANT)
return false;
DBusMessageIter subIter;
dbus->lib->ffdbus_message_iter_recurse(iter, &subIter);
return ffDBusGetInt(dbus, &subIter, result);
}
DBusMessage* ffDBusGetMethodReply(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* method, const char* arg1, const char* arg2)
{
DBusMessage* message = dbus->lib->ffdbus_message_new_method_call(busName, objectPath, interface, method);
if(message == NULL)
return NULL;
if (arg)
dbus->lib->ffdbus_message_append_args(message, DBUS_TYPE_STRING, &arg, DBUS_TYPE_INVALID);
if (arg1)
{
if (arg2)
dbus->lib->ffdbus_message_append_args(message, DBUS_TYPE_STRING, &arg1, DBUS_TYPE_STRING, &arg2, DBUS_TYPE_INVALID);
else
dbus->lib->ffdbus_message_append_args(message, DBUS_TYPE_STRING, &arg1, DBUS_TYPE_INVALID);
}
DBusMessage* reply = dbus->lib->ffdbus_connection_send_with_reply_and_block(dbus->connection, message, instance.config.general.processingTimeout, NULL);
@@ -1,4 +1,4 @@
#include "debug.h"
#include "common/debug.h"
#include <windows.h>
+82
View File
@@ -0,0 +1,82 @@
#include "common/duration.h"
void ffDurationAppendNum(uint64_t totalSeconds, FFstrbuf* result)
{
const FFOptionsDisplay* options = &instance.config.display;
bool spaceBeforeUnit = options->durationSpaceBeforeUnit != FF_SPACE_BEFORE_UNIT_NEVER;
if (totalSeconds < 60)
{
ffStrbufAppendUInt(result, totalSeconds);
if (spaceBeforeUnit) ffStrbufAppendC(result, ' ');
ffStrbufAppendS(result, options->durationAbbreviation ? "sec" : "second");
if (totalSeconds != 1)
ffStrbufAppendC(result, 's');
return;
}
uint32_t seconds = (uint32_t) (totalSeconds % 60);
totalSeconds /= 60;
if (seconds >= 30)
totalSeconds++;
uint32_t minutes = (uint32_t) (totalSeconds % 60);
totalSeconds /= 60;
uint32_t hours = (uint32_t) (totalSeconds % 24);
totalSeconds /= 24;
uint32_t days = (uint32_t) totalSeconds;
if (days > 0)
{
ffStrbufAppendUInt(result, days);
if (spaceBeforeUnit) ffStrbufAppendC(result, ' ');
if (options->durationAbbreviation)
{
ffStrbufAppendC(result, 'd');
if (hours > 0 || minutes > 0)
ffStrbufAppendC(result, ' ');
}
else
{
ffStrbufAppendS(result, days == 1 ? "day" : "days");
if (days >= 100)
ffStrbufAppendS(result, "(!)");
if (hours > 0 || minutes > 0)
ffStrbufAppendS(result, ", ");
}
}
if (hours > 0)
{
ffStrbufAppendUInt(result, hours);
if (spaceBeforeUnit) ffStrbufAppendC(result, ' ');
if (options->durationAbbreviation)
{
ffStrbufAppendC(result, 'h');
if (minutes > 0)
ffStrbufAppendC(result, ' ');
}
else
{
ffStrbufAppendS(result, hours == 1 ? "hour" : "hours");
if (minutes > 0)
ffStrbufAppendS(result, ", ");
}
}
if (minutes > 0)
{
ffStrbufAppendUInt(result, minutes);
if (spaceBeforeUnit) ffStrbufAppendC(result, ' ');
if (options->durationAbbreviation)
ffStrbufAppendC(result, 'm');
else
ffStrbufAppendS(result, minutes == 1 ? "min" : "mins");
}
}
@@ -1,4 +1,4 @@
#include "edidHelper.h"
#include "common/edidHelper.h"
void ffEdidGetPhysicalResolution(const uint8_t edid[128], uint32_t* width, uint32_t* height)
{
+520
View File
@@ -0,0 +1,520 @@
#include "fastfetch.h"
#include "common/FFlist.h"
#include "common/FFstrbuf.h"
#include "common/stringUtils.h"
#include "common/font.h"
#include <string.h>
#include <ctype.h>
void ffFontInit(FFfont* font)
{
// Ensure no memory allocates
ffStrbufInit(&font->pretty);
ffStrbufInit(&font->name);
ffStrbufInit(&font->size);
ffListInit(&font->styles, sizeof(FFstrbuf));
}
static void strbufAppendNSExcludingC(FFstrbuf* strbuf, uint32_t length, const char* value, char exclude)
{
if(value == NULL || length == 0)
return;
ffStrbufEnsureFree(strbuf, length);
for(uint32_t i = 0; i < length; i++)
{
if(value[i] != exclude)
strbuf->chars[strbuf->length++] = value[i];
}
strbuf->chars[strbuf->length] = '\0';
}
static void fontInitPretty(FFfont* font)
{
ffStrbufAppend(&font->pretty, &font->name);
if(font->size.length == 0 && font->styles.length == 0)
return;
else if(font->pretty.length == 0)
ffStrbufAppendS(&font->pretty, "default");
ffStrbufAppendS(&font->pretty, " (");
if(font->size.length > 0)
{
ffStrbufAppend(&font->pretty, &font->size);
if (!ffStrbufEndsWithS(&font->size, "pt") && !ffStrbufEndsWithS(&font->size, "px"))
ffStrbufAppendS(&font->pretty, "pt");
if(font->styles.length > 0)
ffStrbufAppendS(&font->pretty, ", ");
}
for(uint32_t i = 0; i < font->styles.length; i++)
{
ffStrbufAppend(&font->pretty, FF_LIST_GET(FFstrbuf, font->styles, i));
if(i < font->styles.length - 1)
ffStrbufAppendS(&font->pretty, ", ");
}
ffStrbufAppendC(&font->pretty, ')');
}
void ffFontInitQt(FFfont* font, const char* data)
{
ffFontInit(font);
//See https://doc.qt.io/qt-5/qfont.html#toString
//Family
data = ffStrbufAppendSUntilC(&font->name, data, ',');
ffStrbufTrim(&font->name, ' ');
if (!data) goto exit;
data++;
//Size
data = ffStrbufAppendSUntilC(&font->size, data, ',');
ffStrbufTrim(&font->size, ' ');
if (!data) goto exit;
data++;
//Style
data = strrchr(data, ',');
if (!data) goto exit;
data++;
if (isalpha(*data))
{
do
{
FFstrbuf* style = (FFstrbuf*) ffListAdd(&font->styles);
ffStrbufInit(style);
data = ffStrbufAppendSUntilC(style, data, ' ');
if (data) data++;
} while (data);
}
exit:
fontInitPretty(font);
}
static void fontPangoParseWord(const char** data, FFfont* font, FFstrbuf* alternativeBuffer)
{
while(**data == ' ' || **data == '\t' || **data == ',')
++(*data);
const char* wordStart = *data;
while(**data != ' ' && **data != '\t' && **data != ',' && **data != '\0' && **data != '`' && **data != '\\')
++(*data);
uint32_t wordLength = (uint32_t) (*data - wordStart);
if(wordLength == 0)
return;
if(**data == '\0' || **data == '`' || **data == '\\')
{
ffStrbufAppendNS(&font->size, wordLength, wordStart);
if(ffStrbufEndsWithS(&font->size, "px"))
ffStrbufSubstrBefore(&font->size, font->size.length - 2);
double dummy;
if(sscanf(font->size.chars, "%lf", &dummy) == 1)
return;
ffStrbufClear(&font->size);
}
if(
ffStrStartsWithIgnCase(wordStart, "Ultra") ||
ffStrStartsWithIgnCase(wordStart, "Extra") ||
ffStrStartsWithIgnCase(wordStart, "Semi") ||
ffStrStartsWithIgnCase(wordStart, "Demi") ||
ffStrStartsWithIgnCase(wordStart, "Normal") ||
ffStrStartsWithIgnCase(wordStart, "Roman") ||
ffStrStartsWithIgnCase(wordStart, "Oblique") ||
ffStrStartsWithIgnCase(wordStart, "Italic") ||
ffStrStartsWithIgnCase(wordStart, "Thin") ||
ffStrStartsWithIgnCase(wordStart, "Light") ||
ffStrStartsWithIgnCase(wordStart, "Bold") ||
ffStrStartsWithIgnCase(wordStart, "Black") ||
ffStrStartsWithIgnCase(wordStart, "Condensed") ||
ffStrStartsWithIgnCase(wordStart, "Expanded")
) {
if(alternativeBuffer == NULL)
{
alternativeBuffer = (FFstrbuf*) ffListAdd(&font->styles);
ffStrbufInit(alternativeBuffer);
}
strbufAppendNSExcludingC(alternativeBuffer, wordLength, wordStart, '-');
if(
ffStrStartsWithIgnCase(wordStart, "Ultra ") ||
ffStrStartsWithIgnCase(wordStart, "Extra ") ||
ffStrStartsWithIgnCase(wordStart, "Semi ") ||
ffStrStartsWithIgnCase(wordStart, "Demi ")
) {
fontPangoParseWord(data, font, alternativeBuffer);
}
return;
}
if(alternativeBuffer != NULL)
{
strbufAppendNSExcludingC(alternativeBuffer, wordLength, wordStart, '-');
return;
}
if(font->name.length > 0)
ffStrbufAppendC(&font->name, ' ');
ffStrbufAppendNS(&font->name, wordLength, wordStart);
}
void ffFontInitPango(FFfont* font, const char* data)
{
ffFontInit(font);
while(*data != '\0' && *data != '`' && *data != '\\')
fontPangoParseWord(&data, font, NULL);
fontInitPretty(font);
}
void ffFontInitValues(FFfont* font, const char* name, const char* size)
{
ffFontInit(font);
ffStrbufAppendS(&font->name, name);
ffStrbufTrim(&font->name, '"');
ffStrbufAppendS(&font->size, size);
fontInitPretty(font);
}
void ffFontInitXlfd(FFfont* font, const char* xlfd)
{
assert(xlfd && *xlfd);
// https://en.wikipedia.org/wiki/X_logical_font_description
ffFontInit(font);
// XLFD: -foundry-family-weight-slant-setwidth-addstyle-pixelsize-pointsize-xres-yres-spacing-averagewidth-charsetregistry-charsetencoding
// It often starts with '-', which would create an empty first field. Skip it to align indexes.
if(*xlfd == '-')
xlfd++;
const char* pstart = xlfd;
for(int field = 0; field < 14; field++)
{
const char* pend = strchr(pstart, '-');
uint32_t length = pend ? (uint32_t)(pend - pstart) : (uint32_t) strlen(pstart);
if(length > 0)
{
if(field == 1) // family
{
ffStrbufAppendNS(&font->name, length, pstart);
}
else if(field == 7) // pointsize (decipoints, preferred)
{
// parse positive integer from substring
long deciPt = 0;
bool ok = true;
for(uint32_t i = 0; i < length; i++)
{
char c = pstart[i];
if(c < '0' || c > '9') { ok = false; break; }
deciPt = deciPt * 10 + (c - '0');
}
if(ok && deciPt > 0)
{
ffStrbufClear(&font->size);
char tmp[32];
if(deciPt % 10 == 0)
snprintf(tmp, sizeof(tmp), "%ldpt", deciPt / 10);
else
snprintf(tmp, sizeof(tmp), "%ld.%ldpt", deciPt / 10, deciPt % 10);
ffStrbufAppendS(&font->size, tmp);
}
}
else if(field == 6) // pixelsize (fallback if pointsize missing/invalid)
{
if(font->size.length == 0)
{
long px = 0;
bool ok = true;
for(uint32_t i = 0; i < length; i++)
{
char c = pstart[i];
if(c < '0' || c > '9') { ok = false; break; }
px = px * 10 + (c - '0');
}
if(ok && px > 0)
{
ffStrbufAppendNS(&font->size, length, pstart);
ffStrbufAppendS(&font->size, "px");
}
}
}
else if(field >= 2 && field <= 5) // weight/slant/setwidth/addstyle
{
// ignore "normal" (case-insensitive)
if(!(length == 6 && ffStrStartsWithIgnCase(pstart, "normal")))
{
FFstrbuf* style = (FFstrbuf*) ffListAdd(&font->styles);
ffStrbufInitNS(style, length, pstart);
}
}
}
if(!pend)
break;
pstart = pend + 1;
}
fontInitPretty(font);
}
void ffFontInitXft(FFfont* font, const char* xft)
{
assert(xft);
// https://en.wikipedia.org/wiki/Xft
// Xft/Fontconfig pattern examples:
// "DejaVu Sans Mono-10"
// "monospace:size=10:weight=bold:slant=italic"
// "Fira Code-12:style=Regular"
// Goal: extract family(name), size, and some common styles.
ffFontInit(font);
// 1) Parse "head" part before first ':' => usually "family[-size]" (may include commas)
const char* p = xft;
while(*p == ' ' || *p == '\t')
++p;
const char* headStart = p;
while(*p != '\0' && *p != ':')
++p;
const char* headEnd = p;
// trim tail spaces
while(headEnd > headStart && (headEnd[-1] == ' ' || headEnd[-1] == '\t'))
--headEnd;
// If multiple families are listed, take the first one (up to comma)
for(const char* q = headStart; q < headEnd; ++q)
{
if(*q == ',')
{
headEnd = q;
while(headEnd > headStart && (headEnd[-1] == ' ' || headEnd[-1] == '\t'))
--headEnd;
break;
}
}
// Try parse trailing "-<number>" as size, otherwise entire head is name
const char* dashPos = NULL;
const char* sizeStart = NULL;
for(const char* q = headEnd; q > headStart; )
{
--q;
if(*q == '-' && (q + 1) < headEnd && ffCharIsDigit(q[1]))
{
dashPos = q;
sizeStart = q + 1;
break;
}
}
if(dashPos)
{
bool ok = true;
bool seenDigit = false;
for(const char* q = sizeStart; q < headEnd; ++q)
{
if(ffCharIsDigit(*q))
seenDigit = true;
else if(*q == '.')
continue;
else
{
ok = false;
break;
}
}
if(ok && seenDigit)
{
const char* nameEnd = dashPos;
while(nameEnd > headStart && (nameEnd[-1] == ' ' || nameEnd[-1] == '\t'))
--nameEnd;
if(nameEnd > headStart)
ffStrbufAppendNS(&font->name, (uint32_t) (nameEnd - headStart), headStart);
if(headEnd > sizeStart)
ffStrbufAppendNS(&font->size, (uint32_t) (headEnd - sizeStart), sizeStart);
}
else
{
if(headEnd > headStart)
ffStrbufAppendNS(&font->name, (uint32_t) (headEnd - headStart), headStart);
}
}
else
{
if(headEnd > headStart)
ffStrbufAppendNS(&font->name, (uint32_t) (headEnd - headStart), headStart);
}
ffStrbufTrim(&font->name, ' ');
ffStrbufTrim(&font->name, '"');
// 2) Parse key=value fields after ':' (Fontconfig-like). Fields separated by ':'.
// Common keys: size, pixelsize, pointsize, style, weight, slant, width
while(*p == ':')
{
++p;
// key
const char* keyStart = p;
while(*p != '\0' && *p != '=' && *p != ':')
++p;
const char* keyEnd = p;
if(*p != '=')
continue; // skip tokens without '='
++p; // skip '='
// value (until next ':', allow backslash-escaping)
FF_STRBUF_AUTO_DESTROY value = ffStrbufCreate();
while(*p != '\0' && *p != ':')
{
if(*p == '\\' && p[1] != '\0')
{
++p;
ffStrbufAppendC(&value, *p);
++p;
continue;
}
ffStrbufAppendC(&value, *p);
++p;
}
ffStrbufTrim(&value, ' ');
ffStrbufTrim(&value, '"');
uint32_t keyLen = (uint32_t) (keyEnd - keyStart);
// helper: set numeric size if not set yet
const bool sizeEmpty = (font->size.length == 0);
if(value.length > 0)
{
if(
(keyLen == 4 && ffStrStartsWithIgnCase(keyStart, "size")) ||
(keyLen == 9 && ffStrStartsWithIgnCase(keyStart, "pixelsize"))
)
{
if(sizeEmpty && ffCharIsDigit(value.chars[0]))
{
ffStrbufAppend(&font->size, &value);
ffStrbufAppendS(&font->size, keyLen == 4 ? "pt" : "px");
}
}
else if(keyLen == 5 && ffStrStartsWithIgnCase(keyStart, "style"))
{
// style may contain multiple words: "Bold Italic"
const char* s = value.chars;
while(*s != '\0')
{
while(*s == ' ' || *s == '\t' || *s == ',')
++s;
const char* w = s;
while(*s != '\0' && *s != ' ' && *s != '\t' && *s != ',')
++s;
if(s > w)
{
FFstrbuf* style = FF_LIST_ADD(FFstrbuf, font->styles);
ffStrbufInitNS(style, (uint32_t) (s - w), w);
}
}
}
else if(
(keyLen == 6 && ffStrStartsWithIgnCase(keyStart, "weight")) ||
(keyLen == 5 && ffStrStartsWithIgnCase(keyStart, "slant")) ||
(keyLen == 5 && ffStrStartsWithIgnCase(keyStart, "width"))
) {
// normalize: remove '-' to align with other parsers ("Semi-Bold" -> "SemiBold")
FFstrbuf* style = FF_LIST_ADD(FFstrbuf, font->styles);
ffStrbufInit(style);
strbufAppendNSExcludingC(style, value.length, value.chars, '-');
ffStrbufTrim(style, ' ');
}
}
}
fontInitPretty(font);
}
void ffFontInitMoveValues(FFfont* font, FFstrbuf* name, FFstrbuf* size, FFstrbuf* style)
{
ffFontInit(font);
if (name) ffStrbufInitMove(&font->name, name);
if (size) ffStrbufInitMove(&font->size, size);
if (style)
{
FFstrbuf* styleBuf = FF_LIST_ADD(FFstrbuf, font->styles);
ffStrbufInitMove(styleBuf, style);
}
fontInitPretty(font);
}
void ffFontInitWithSpace(FFfont* font, const char* rawName)
{
const char* pspace = strrchr(rawName, ' ');
if(pspace == NULL)
{
ffFontInitCopy(font, rawName);
return;
}
ffFontInit(font);
ffStrbufAppendNS(&font->name, (uint32_t)(pspace - rawName), rawName);
ffStrbufAppendS(&font->size, pspace + 1);
fontInitPretty(font);
}
void ffFontDestroy(FFfont* font)
{
ffStrbufDestroy(&font->pretty);
ffStrbufDestroy(&font->name);
ffStrbufDestroy(&font->size);
FF_LIST_FOR_EACH(FFstrbuf, str, font->styles)
ffStrbufDestroy(str);
ffListDestroy(&font->styles);
}
@@ -1,8 +1,8 @@
#include "fastfetch.h"
#include "common/format.h"
#include "common/parsing.h"
#include "util/textModifier.h"
#include "util/stringUtils.h"
#include "common/textModifier.h"
#include "common/stringUtils.h"
#include <inttypes.h>
@@ -11,37 +11,31 @@ void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg)
switch(formatarg->type)
{
case FF_FORMAT_ARG_TYPE_INT:
ffStrbufAppendF(buffer, "%" PRIi32, *(int32_t*)formatarg->value);
ffStrbufAppendSInt(buffer, *(int32_t*)formatarg->value);
break;
case FF_FORMAT_ARG_TYPE_UINT:
ffStrbufAppendF(buffer, "%" PRIu32, *(uint32_t*)formatarg->value);
ffStrbufAppendUInt(buffer, *(uint32_t*)formatarg->value);
break;
case FF_FORMAT_ARG_TYPE_UINT64:
ffStrbufAppendF(buffer, "%" PRIu64, *(uint64_t*)formatarg->value);
ffStrbufAppendUInt(buffer, *(uint64_t*)formatarg->value);
break;
case FF_FORMAT_ARG_TYPE_UINT16:
ffStrbufAppendF(buffer, "%" PRIu16, *(uint16_t*)formatarg->value);
ffStrbufAppendUInt(buffer, *(uint16_t*)formatarg->value);
break;
case FF_FORMAT_ARG_TYPE_UINT8:
ffStrbufAppendF(buffer, "%" PRIu8, *(uint8_t*)formatarg->value);
ffStrbufAppendUInt(buffer, *(uint8_t*)formatarg->value);
break;
case FF_FORMAT_ARG_TYPE_STRING:
ffStrbufAppendS(buffer, (const char*)formatarg->value);
break;
case FF_FORMAT_ARG_TYPE_STRBUF:
ffStrbufAppend(buffer, (FFstrbuf*)formatarg->value);
ffStrbufAppend(buffer, (const FFstrbuf*)formatarg->value);
break;
case FF_FORMAT_ARG_TYPE_FLOAT:
if (instance.config.display.fractionNdigits >= 0)
ffStrbufAppendF(buffer, "%.*f", instance.config.display.fractionNdigits, *(float*)formatarg->value);
else
ffStrbufAppendF(buffer, "%g", *(float*)formatarg->value);
ffStrbufAppendDouble(buffer, *(float*)formatarg->value, instance.config.display.fractionNdigits, instance.config.display.fractionTrailingZeros != FF_FRACTION_TRAILING_ZEROS_TYPE_NEVER);
break;
case FF_FORMAT_ARG_TYPE_DOUBLE:
if (instance.config.display.fractionNdigits >= 0)
ffStrbufAppendF(buffer, "%.*f", instance.config.display.fractionNdigits, *(double*)formatarg->value);
else
ffStrbufAppendF(buffer, "%g", *(double*)formatarg->value);
ffStrbufAppendDouble(buffer, *(double*)formatarg->value, instance.config.display.fractionNdigits, instance.config.display.fractionTrailingZeros != FF_FRACTION_TRAILING_ZEROS_TYPE_NEVER);
break;
case FF_FORMAT_ARG_TYPE_BOOL:
ffStrbufAppendS(buffer, *(bool*)formatarg->value ? "true" : "false");
@@ -93,7 +87,7 @@ static uint32_t getArgumentIndex(const char* placeholderValue, uint32_t numArgs,
for (uint32_t i = 0; i < numArgs; ++i)
{
const FFformatarg* arg = &arguments[i];
if (arg->name && strcasecmp(placeholderValue, arg->name) == 0)
if (arg->name && ffStrEqualsIgnCase(placeholderValue, arg->name))
return i + 1;
}
}
@@ -210,7 +204,7 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
uint32_t index = getArgumentIndex(placeholderValue.chars, numArgs, arguments);
// testing for an invalid index
if (index > numArgs)
if (index > numArgs || index < 1)
{
appendInvalidPlaceholder(buffer, "{?", &placeholderValue, i, formatstr->length);
continue;
@@ -236,7 +230,7 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
uint32_t index = getArgumentIndex(placeholderValue.chars, numArgs, arguments);
// testing for an invalid index
if (index > numArgs)
if (index > numArgs || index < 1)
{
appendInvalidPlaceholder(buffer, "{/", &placeholderValue, i, formatstr->length);
continue;
+25
View File
@@ -0,0 +1,25 @@
#include "common/frequency.h"
bool ffFreqAppendNum(uint32_t mhz, FFstrbuf* result)
{
if (mhz == 0)
return false;
const FFOptionsDisplay* options = &instance.config.display;
bool spaceBeforeUnit = options->freqSpaceBeforeUnit != FF_SPACE_BEFORE_UNIT_NEVER;
int8_t ndigits = options->freqNdigits;
if (ndigits >= 0)
{
ffStrbufAppendDouble(result, mhz / 1000., ndigits, true);
if (spaceBeforeUnit) ffStrbufAppendC(result, ' ');
ffStrbufAppendS(result, "GHz");
}
else
{
ffStrbufAppendUInt(result, mhz);
if (spaceBeforeUnit) ffStrbufAppendC(result, ' ');
ffStrbufAppendS(result, "MHz");
}
return true;
}
+25 -26
View File
@@ -2,9 +2,9 @@
#include "common/init.h"
#include "common/parsing.h"
#include "common/thread.h"
#include "common/textModifier.h"
#include "detection/displayserver/displayserver.h"
#include "detection/terminaltheme/terminaltheme.h"
#include "util/textModifier.h"
#include "logo/logo.h"
#include <stdlib.h>
@@ -12,7 +12,7 @@
#include <locale.h>
#ifdef _WIN32
#include <windows.h>
#include "util/windows/unicode.h"
#include "common/windows/unicode.h"
#else
#include <signal.h>
#endif
@@ -28,8 +28,7 @@ static void initState(FFstate* state)
state->titleFqdn = false;
ffPlatformInit(&state->platform);
state->configDoc = NULL;
state->resultDoc = NULL;
state->dynamicInterval = 0;
{
// don't enable bright color if the terminal is in light mode
@@ -48,7 +47,7 @@ static void defaultConfig(void)
void ffInitInstance(void)
{
#ifdef WIN32
#ifdef _WIN32
// https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale?source=recommendat>
setlocale(LC_ALL, ".UTF8");
#else
@@ -74,6 +73,9 @@ static void resetConsole(void)
#if defined(_WIN32)
fflush(stdout);
#endif
if(instance.state.dynamicInterval > 0)
fputs("\033[?1049l", stdout); // Disable alternate buffer
}
#ifdef _WIN32
@@ -88,16 +90,12 @@ static void exitSignalHandler(FF_MAYBE_UNUSED int signal)
resetConsole();
exit(0);
}
static void chldSignalHandler(FF_MAYBE_UNUSED int signal)
{
// empty; used to interrupt the poll and read syscalls
}
#endif
void ffStart(void)
{
ffDisableLinewrap = instance.config.display.disableLinewrap && !instance.config.display.pipe && !instance.state.resultDoc;
ffHideCursor = instance.config.display.hideCursor && !instance.config.display.pipe && !instance.state.resultDoc;
ffDisableLinewrap = instance.config.display.disableLinewrap && !instance.config.display.pipe;
ffHideCursor = instance.config.display.hideCursor && !instance.config.display.pipe;
#ifdef _WIN32
SetErrorMode(SEM_FAILCRITICALERRORS);
@@ -117,11 +115,14 @@ void ffStart(void)
sigaction(SIGINT, &action, NULL);
sigaction(SIGTERM, &action, NULL);
sigaction(SIGQUIT, &action, NULL);
sigaction(SIGCHLD, &(struct sigaction) { .sa_handler = chldSignalHandler }, NULL);
sigset_t newmask;
sigemptyset(&newmask);
sigaddset(&newmask, SIGCHLD);
sigprocmask(SIG_BLOCK, &newmask, NULL);
#endif
//reset everything to default before we start printing
if(!instance.config.display.pipe && !instance.state.resultDoc)
if(!instance.config.display.pipe)
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
if(ffHideCursor)
@@ -130,14 +131,15 @@ void ffStart(void)
if(ffDisableLinewrap)
fputs("\033[?7l", stdout);
ffLogoPrint();
if(instance.state.dynamicInterval > 0)
{
fputs("\033[?1049h\033[H", stdout); // Enable alternate buffer
fflush(stdout);
}
}
void ffFinish(void)
{
if(instance.config.logo.printRemaining)
ffLogoPrintRemaining();
resetConsole();
}
@@ -151,9 +153,6 @@ static void destroyConfig(void)
static void destroyState(void)
{
ffPlatformDestroy(&instance.state.platform);
yyjson_doc_free(instance.state.configDoc);
yyjson_mut_doc_free(instance.state.resultDoc);
ffStrbufDestroy(&instance.state.genConfigPath);
}
void ffDestroyInstance(void)
@@ -208,9 +207,6 @@ void ffListFeatures(void)
#if FF_HAVE_ZLIB
"zlib\n"
#endif
#if FF_HAVE_XFCONF
"xfconf\n"
#endif
#if FF_HAVE_SQLITE3
"sqlite3\n"
#endif
@@ -229,9 +225,6 @@ void ffListFeatures(void)
#if FF_HAVE_FREETYPE
"freetype\n"
#endif
#if FF_HAVE_PCIACCESS
"libpciaccess\n"
#endif
#if FF_HAVE_PULSE
"libpulse\n"
#endif
@@ -259,6 +252,12 @@ void ffListFeatures(void)
#if FF_HAVE_EMBEDDED_PCIIDS
"Embedded pciids\n"
#endif
#if FF_WIN7_COMPAT
"Windows 7 Compatibility\n"
#endif
#if FF_APPLE_MEMSIZE_USABLE
"Apple memsize_usable\n"
#endif
""
, stdout);
}
@@ -1,6 +1,6 @@
#include "io.h"
#include "common/io.h"
#include "fastfetch.h"
#include "util/stringUtils.h"
#include "common/stringUtils.h"
#include "common/time.h"
#include <fcntl.h>
@@ -15,18 +15,15 @@
#if FF_HAVE_WORDEXP
#include <wordexp.h>
#elif FF_HAVE_GLOB
#warning "<wordexp.h> is not available, use <glob.h> instead"
#include <glob.h>
#else
#warning "Neither <wordexp.h> nor <glob.h> is available"
#include <glob.h>
#endif
static void createSubfolders(const char* fileName)
{
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate();
char *token = NULL;
const char *token = NULL;
while((token = strchr(fileName, '/')) != NULL)
{
ffStrbufAppendNS(&path, (uint32_t)(token - fileName + 1), fileName);
@@ -136,14 +133,14 @@ bool ffAppendFileBufferRelative(int dfd, const char* fileName, FFstrbuf* buffer)
return ffAppendFDBuffer(fd, buffer);
}
bool ffPathExpandEnv(FF_MAYBE_UNUSED const char* in, FF_MAYBE_UNUSED FFstrbuf* out)
bool ffPathExpandEnv(const char* in, FFstrbuf* out)
{
bool result = false;
#if FF_HAVE_WORDEXP // https://github.com/termux/termux-packages/pull/7056
#if FF_HAVE_WORDEXP
wordexp_t exp;
if (wordexp(in, &exp, 0) != 0)
if (wordexp(in, &exp, 0) != 0) // WARN: 0 = no safety flags; command substitution allowed
return false;
if (exp.we_wordc >= 1)
@@ -154,16 +151,23 @@ bool ffPathExpandEnv(FF_MAYBE_UNUSED const char* in, FF_MAYBE_UNUSED FFstrbuf* o
wordfree(&exp);
#elif FF_HAVE_GLOB
#else
glob_t gb;
if (glob(in, GLOB_NOSORT | GLOB_TILDE, NULL, &gb) != 0)
if (glob(in, GLOB_NOSORT
#ifdef GLOB_TILDE
| GLOB_TILDE
#endif
#ifdef GLOB_BRACE
| GLOB_BRACE
#endif
, NULL, &gb) != 0)
return false;
if (gb.gl_matchc >= 1)
if (gb.gl_pathc >= 1)
{
result = true;
ffStrbufSetS(out, gb.gl_pathv[gb.gl_matchc > 1 ? ffTimeGetNow() % gb.gl_matchc : 0]);
ffStrbufSetS(out, gb.gl_pathv[gb.gl_pathc > 1 ? ffTimeGetNow() % (unsigned) gb.gl_pathc : 0]);
}
globfree(&gb);
@@ -367,3 +371,8 @@ FFNativeFD ffGetNullFD(void)
hNullFile = open("/dev/null", O_WRONLY | O_CLOEXEC);
return hNullFile;
}
bool ffRemoveFile(const char* fileName)
{
return unlink(fileName) == 0;
}
@@ -1,10 +1,10 @@
#include "io.h"
#include "common/io.h"
#include "fastfetch.h"
#include "util/stringUtils.h"
#include "common/stringUtils.h"
#include <windows.h>
#include "common/windows/nt.h"
#include <ntstatus.h>
#include <winternl.h>
static void createSubfolders(const char* fileName)
{
@@ -102,31 +102,48 @@ bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer)
return ffAppendFDBuffer(handle, buffer);
}
HANDLE openat(HANDLE dfd, const char* fileName, bool directory)
HANDLE openatW(HANDLE dfd, const wchar_t* fileName, uint16_t fileNameLen, bool directory)
{
NTSTATUS ret;
UNICODE_STRING fileNameW;
ret = RtlAnsiStringToUnicodeString(&fileNameW, &(ANSI_STRING) {
.Length = (USHORT) strlen(fileName),
.Buffer = (PCHAR) fileName
}, TRUE);
if (!NT_SUCCESS(ret)) return INVALID_HANDLE_VALUE;
assert(fileNameLen <= 0x7FFF);
FF_AUTO_CLOSE_FD HANDLE hFile;
HANDLE hFile;
IO_STATUS_BLOCK iosb = {};
ret = NtOpenFile(&hFile, FILE_READ_DATA | SYNCHRONIZE, &(OBJECT_ATTRIBUTES) {
.Length = sizeof(OBJECT_ATTRIBUTES),
.RootDirectory = dfd,
.ObjectName = &fileNameW,
}, &iosb, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT | (directory ? FILE_DIRECTORY_FILE : FILE_NON_DIRECTORY_FILE));
RtlFreeUnicodeString(&fileNameW);
if(!NT_SUCCESS(ret) || iosb.Information != FILE_OPENED)
if(!NT_SUCCESS(NtOpenFile(&hFile,
(directory ? FILE_LIST_DIRECTORY | FILE_TRAVERSE : FILE_READ_DATA | FILE_READ_EA) | FILE_READ_ATTRIBUTES | SYNCHRONIZE, &(OBJECT_ATTRIBUTES) {
.Length = sizeof(OBJECT_ATTRIBUTES),
.RootDirectory = dfd,
.ObjectName = &(UNICODE_STRING) {
.Buffer = (PWSTR) fileName,
.Length = fileNameLen * (USHORT) sizeof(wchar_t),
.MaximumLength = (fileNameLen + 1) * (USHORT) sizeof(wchar_t),
},
.Attributes = OBJ_CASE_INSENSITIVE,
},
&iosb,
FILE_SHARE_READ | (directory ? FILE_SHARE_WRITE | FILE_SHARE_DELETE : 0),
FILE_SYNCHRONOUS_IO_NONALERT | (directory ? FILE_DIRECTORY_FILE : FILE_NON_DIRECTORY_FILE)
)))
return INVALID_HANDLE_VALUE;
return hFile;
}
HANDLE openat(HANDLE dfd, const char* fileName, bool directory)
{
wchar_t fileNameW[MAX_PATH];
int len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, fileName, -1, fileNameW, ARRAY_SIZE(fileNameW));
if (len == 0) return INVALID_HANDLE_VALUE;
// Implies `fileNameW[len] = L'\0';` and `len` includes the null terminator
for (int i = 0; i < len - 1; ++i)
{
if (fileNameW[i] == L'/')
fileNameW[i] = L'\\';
}
return openatW(dfd, fileNameW, (uint16_t)(len - 1), directory);
}
bool ffAppendFileBufferRelative(HANDLE dfd, const char* fileName, FFstrbuf* buffer)
{
HANDLE FF_AUTO_CLOSE_FD fd = openat(dfd, fileName, false);
@@ -371,3 +388,8 @@ FFNativeFD ffGetNullFD(void)
});
return hNullFile;
}
bool ffRemoveFile(const char* fileName)
{
return DeleteFileA(fileName) != FALSE;
}
@@ -2,11 +2,11 @@
#include "common/color.h"
#include "common/jsonconfig.h"
#include "common/printing.h"
#include "common/io/io.h"
#include "common/io.h"
#include "common/time.h"
#include "common/stringUtils.h"
#include "detection/version/version.h"
#include "modules/modules.h"
#include "util/stringUtils.h"
#include <assert.h>
#include <ctype.h>
@@ -101,16 +101,6 @@ const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair p
return "Invalid enum value type; must be a string or integer";
}
static inline void genJsonResult(FFModuleBaseInfo* baseInfo, void* options, yyjson_mut_doc* doc)
{
yyjson_mut_val* module = yyjson_mut_arr_add_obj(doc, doc->root);
yyjson_mut_obj_add_str(doc, module, "type", baseInfo->name);
if (baseInfo->generateJsonResult)
baseInfo->generateJsonResult(options, doc, module);
else
yyjson_mut_obj_add_str(doc, module, "error", "Unsupported for JSON format");
}
static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal, yyjson_mut_doc* jsonDoc)
{
if(!ffCharIsEnglishAlphabet(type[0])) return false;
@@ -123,14 +113,39 @@ static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal, yyjson_
uint8_t optionBuf[FF_OPTION_MAX_SIZE];
baseInfo->initOptions(optionBuf);
if (jsonVal) baseInfo->parseJsonObject(optionBuf, jsonVal);
if (__builtin_expect(jsonDoc != NULL, false))
genJsonResult(baseInfo, optionBuf, jsonDoc);
bool succeeded;
if (jsonDoc)
{
yyjson_mut_val* module = yyjson_mut_arr_add_obj(jsonDoc, jsonDoc->root);
yyjson_mut_obj_add_str(jsonDoc, module, "type", baseInfo->name);
if (baseInfo->generateJsonResult)
succeeded = baseInfo->generateJsonResult(optionBuf, jsonDoc, module);
else
{
yyjson_mut_obj_add_str(jsonDoc, module, "error", "Unsupported for JSON format");
succeeded = false;
}
}
else
baseInfo->printModule(optionBuf);
succeeded = baseInfo->printModule(optionBuf);
baseInfo->destroyOptions(optionBuf);
return true;
return succeeded;
}
}
if (jsonDoc)
{
yyjson_mut_val* module = yyjson_mut_arr_add_obj(jsonDoc, jsonDoc->root);
yyjson_mut_obj_add_strcpy(jsonDoc, module, "type", type);
yyjson_mut_obj_add_str(jsonDoc, module, "error", "Unknown module type");
}
else
{
FFModuleArgs moduleArgs;
ffOptionInitModuleArg(&moduleArgs, "");
ffPrintError(type, 0, &moduleArgs, FF_PRINT_TYPE_DEFAULT, "Unknown module type");
ffOptionDestroyModuleArg(&moduleArgs);
}
return false;
}
@@ -143,6 +158,16 @@ static void prepareModuleJsonObject(const char* type, yyjson_val* module)
ffPrepareCPUUsage();
break;
}
case 'c': case 'C': {
if (ffStrEqualsIgnCase(type, FF_COMMAND_MODULE_NAME))
{
__attribute__((__cleanup__(ffDestroyCommandOptions))) FFCommandOptions options;
ffInitCommandOptions(&options);
if (module) ffCommandModuleInfo.parseJsonObject(&options, module);
ffPrepareCommand(&options);
}
break;
}
case 'd': case 'D': {
if (ffStrEqualsIgnCase(type, FF_DISKIO_MODULE_NAME))
{
@@ -205,9 +230,10 @@ static bool matchesJsonArray(const char* str, yyjson_val* val)
return false;
}
static const char* printJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc)
static const char* printJsonConfig(FFdata* data, bool prepare)
{
yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc);
yyjson_mut_doc* jsonDoc = data->resultDoc;
yyjson_val* const root = yyjson_doc_get_root(data->configDoc);
assert(root);
if (!yyjson_is_obj(root))
@@ -217,6 +243,7 @@ static const char* printJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc)
if (!modules) return NULL;
if (!yyjson_is_arr(modules)) return "Property 'modules' must be an array of strings or objects";
bool succeeded = true;
int32_t thres = instance.config.display.stat;
yyjson_val* item;
size_t idx, max;
@@ -253,6 +280,15 @@ static const char* printJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc)
arch = yyjson_obj_get(conditions, "!arch");
if (arch && matchesJsonArray(ffVersionResult.architecture, arch))
continue;
yyjson_val* previousSucceeded = yyjson_obj_get(conditions, "succeeded");
if (previousSucceeded && !unsafe_yyjson_is_null(previousSucceeded))
{
if (!unsafe_yyjson_is_bool(previousSucceeded))
return "Property 'succeeded' in 'condition' must be a boolean";
if (succeeded != unsafe_yyjson_get_bool(previousSucceeded))
continue;
}
}
type = yyjson_get_str(yyjson_obj_get(module, "type"));
@@ -263,10 +299,13 @@ static const char* printJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc)
else
return "modules must be an array of strings or objects";
if (ffStrbufSeparatedContainIgnCaseS(&data->structureDisabled, type, ':'))
continue;
if(prepare)
prepareModuleJsonObject(type, module);
else if(!parseModuleJsonObject(type, module, jsonDoc))
return "Unknown module type";
else
succeeded = parseModuleJsonObject(type, module, jsonDoc);
if(!prepare && thres >= 0)
{
@@ -294,9 +333,10 @@ static const char* printJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc)
return NULL;
}
void ffPrintJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc)
void ffPrintJsonConfig(FFdata* data, bool prepare)
{
const char* error = printJsonConfig(prepare, jsonDoc);
yyjson_mut_doc* jsonDoc = data->resultDoc;
const char* error = printJsonConfig(data, prepare);
if (error)
{
if (jsonDoc)
+13
View File
@@ -0,0 +1,13 @@
#include "common/kmod.h"
#include "common/apple/cf_helpers.h"
#include <IOKit/kext/KextManager.h>
#include <CoreFoundation/CoreFoundation.h>
bool ffKmodLoaded(const char* modName)
{
FF_CFTYPE_AUTO_RELEASE CFStringRef name = CFStringCreateWithCString(kCFAllocatorDefault, modName, kCFStringEncodingUTF8);
FF_CFTYPE_AUTO_RELEASE CFArrayRef identifiers = CFArrayCreate(kCFAllocatorDefault, (const void**) &name, 1, &kCFTypeArrayCallBacks);
FF_CFTYPE_AUTO_RELEASE CFArrayRef keys = CFArrayCreate(kCFAllocatorDefault, NULL, 0, NULL);
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef kextInfo = KextManagerCopyLoadedKextInfo(identifiers, keys);
return CFDictionaryContainsKey(kextInfo, name);
}
+8
View File
@@ -0,0 +1,8 @@
#include "common/kmod.h"
#include <sys/param.h>
#include <sys/module.h>
bool ffKmodLoaded(const char* modName)
{
return modfind(modName) >= 0;
}
+23
View File
@@ -0,0 +1,23 @@
#include "common/kmod.h"
#include "common/io.h"
bool ffKmodLoaded(const char* modName)
{
static FFstrbuf modules;
if (modules.chars == NULL)
{
ffStrbufInitS(&modules, "\n");
ffAppendFileBuffer("/proc/modules", &modules);
}
if (modules.length == 0) return false;
uint32_t len = (uint32_t) strlen(modName);
if (len > 250) return false;
char temp[256];
temp[0] = '\n';
memcpy(temp + 1, modName, len);
temp[1 + len] = ' ';
return memmem(modules.chars, modules.length, temp, len + 2) != NULL;
}
+43
View File
@@ -0,0 +1,43 @@
#include "common/kmod.h"
#include "common/stringUtils.h"
#include <sys/module.h>
#include <sys/param.h>
typedef struct __attribute__((__packed__)) FFNbsdModList
{
int len;
modstat_t mods[];
} FFNbsdModList;
bool ffKmodLoaded(const char* modName)
{
static FFNbsdModList* list = NULL;
if (list == NULL)
{
struct iovec iov = {};
for (size_t len = 8192;; len = iov.iov_len)
{
iov.iov_len = len;
iov.iov_base = realloc(iov.iov_base, len);
if (modctl(MODCTL_STAT, &iov) < 0)
{
free(iov.iov_base);
return true; // ignore errors
}
if (len >= iov.iov_len) break;
}
list = (FFNbsdModList*) iov.iov_base;
}
for (int i = 0; i < list->len; i++)
{
if (ffStrEquals(list->mods[i].ms_name, modName))
return true;
}
return false;
}
+6
View File
@@ -0,0 +1,6 @@
#include "common/kmod.h"
bool ffKmodLoaded(FF_MAYBE_UNUSED const char* modName)
{
return true; // Don't generate kernel module related errors
}
+24
View File
@@ -0,0 +1,24 @@
#include "common/kmod.h"
#include "common/stringUtils.h"
#include <sys/modctl.h>
#include <errno.h>
bool ffKmodLoaded(const char* modName)
{
struct modinfo modinfo = {
.mi_id = -1,
.mi_nextid = -1,
.mi_info = MI_INFO_ALL,
};
for (int id = -1; modctl(MODINFO, id, &modinfo) == 0; id = modinfo.mi_id)
{
modinfo.mi_name[MODMAXNAMELEN - 1] = '\0';
if (ffStrEquals(modinfo.mi_name, modName))
return true;
}
return !(errno == EINVAL || errno == ENOENT);
}
+27
View File
@@ -0,0 +1,27 @@
#include "common/kmod.h"
#include "common/windows/nt.h"
#include "common/mallocHelper.h"
#include "common/stringUtils.h"
bool ffKmodLoaded(const char* modName)
{
ULONG bufferSize = 0;
NtQuerySystemInformation(SystemModuleInformation, NULL, 0, &bufferSize);
if (bufferSize == 0)
return true; // ignore errors
FF_AUTO_FREE RTL_PROCESS_MODULES* buffer = malloc(bufferSize);
if (!NT_SUCCESS(NtQuerySystemInformation(SystemModuleInformation, buffer, bufferSize, &bufferSize)))
return true; // ignore errors
for (ULONG i = 0; i < buffer->NumberOfModules; i++)
{
const char* name = (const char*) buffer->Modules[i].FullPathName + buffer->Modules[i].OffsetToFileName;
if (ffStrEqualsIgnCase(name, modName))
return true;
}
return false;
}
@@ -52,7 +52,7 @@ static void* libraryLoad(const char* path, int maxVersion)
for(int i = maxVersion; i >= 0; --i)
{
uint32_t originalLength = pathbuf.length;
ffStrbufAppendF(&pathbuf, "%i", i);
ffStrbufAppendSInt(&pathbuf, i);
result = dlopen(pathbuf.chars, FF_DLOPEN_FLAGS);
if(result != NULL)
+19
View File
@@ -0,0 +1,19 @@
#include "common/memrchr.h"
#include <stddef.h>
#include <stdint.h>
void* memrchr(const void* s, int c, size_t n)
{
if (n == 0) return NULL;
const uint8_t uc = (uint8_t) c;
const uint8_t* p = (const uint8_t*) s + n;
while (n--)
{
if (*--p == uc) return (void*) p;
}
return NULL;
}
@@ -1,4 +1,4 @@
#include "netif.h"
#include "common/netif.h"
#ifndef _WIN32
#include <net/if.h>
@@ -1,7 +1,6 @@
#include "netif.h"
#include "common/io/io.h"
#include "util/mallocHelper.h"
#include "common/netif.h"
#include "common/io.h"
#include "common/mallocHelper.h"
#include <net/if.h>
#include <net/if_dl.h>
@@ -73,7 +72,7 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
setsockopt(pfRoute, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout));
}
int pid = getpid();
uint32_t pid = instance.state.platform.pid;
struct {
struct rt_msghdr hdr;
@@ -86,7 +85,7 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
.rtm_version = RTM_VERSION,
.rtm_addrs = RTA_DST | RTA_IFP | RTA_IFA,
.rtm_msglen = sizeof(rtmsg.hdr) + sizeof(rtmsg.dst),
.rtm_pid = pid,
.rtm_pid = (pid_t) pid,
.rtm_seq = 1,
},
.dst = {
@@ -100,7 +99,7 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
if (send(pfRoute, &rtmsg, rtmsg.hdr.rtm_msglen, 0) != rtmsg.hdr.rtm_msglen)
return false;
while (recv(pfRoute, &rtmsg, sizeof(rtmsg), 0) > 0 && !(rtmsg.hdr.rtm_seq == 1 && rtmsg.hdr.rtm_pid == pid))
while (recv(pfRoute, &rtmsg, sizeof(rtmsg), 0) > 0 && !(rtmsg.hdr.rtm_seq == 1 && rtmsg.hdr.rtm_pid == (pid_t) pid))
;
#ifndef __sun // On Solaris, the RTF_GATEWAY flag is not set for default routes for some reason
@@ -146,7 +145,7 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
setsockopt(pfRoute, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout));
}
int pid = getpid();
uint32_t pid = instance.state.platform.pid;
struct {
struct rt_msghdr hdr;
@@ -159,7 +158,7 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
.rtm_version = RTM_VERSION,
.rtm_addrs = RTA_DST | RTA_IFP,
.rtm_msglen = sizeof(rtmsg.hdr) + sizeof(rtmsg.dst),
.rtm_pid = pid,
.rtm_pid = (pid_t) pid,
.rtm_seq = 2,
},
.dst = {
@@ -173,7 +172,7 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
if (send(pfRoute, &rtmsg, rtmsg.hdr.rtm_msglen, 0) != rtmsg.hdr.rtm_msglen)
return false;
while (recv(pfRoute, &rtmsg, sizeof(rtmsg), 0) > 0 && !(rtmsg.hdr.rtm_seq == 2 && rtmsg.hdr.rtm_pid == pid))
while (recv(pfRoute, &rtmsg, sizeof(rtmsg), 0) > 0 && !(rtmsg.hdr.rtm_seq == 2 && rtmsg.hdr.rtm_pid == (pid_t) pid))
;
#ifndef __sun // On Solaris, the RTF_GATEWAY flag is not set for default routes for some reason
@@ -1,7 +1,6 @@
#include "netif.h"
#include "common/io/io.h"
#include "util/mallocHelper.h"
#include "common/netif.h"
#include "common/io.h"
#include "common/mallocHelper.h"
#include <net/if.h>
#include <net/if_dl.h>
+35
View File
@@ -0,0 +1,35 @@
#include "common/netif.h"
#include "common/io.h"
#include <net/if.h>
#include <stdio.h>
#define FF_STR_INDIR(x) #x
#define FF_STR(x) FF_STR_INDIR(x)
bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
{
FILE* FF_AUTO_CLOSE_FILE netRoute = fopen("/proc/route", "r");
if (!netRoute) return false;
// skip first line
FF_UNUSED(fscanf(netRoute, "%*[^\n]\n"));
unsigned long long destination; //, gateway, flags, refCount, use, metric, mask, mtu, ...
while (fscanf(netRoute, "%" FF_STR(IF_NAMESIZE) "s%llx%*[^\n]", result->ifName, &destination) == 2)
{
if (destination != 0) continue;
result->ifIndex = if_nametoindex(result->ifName);
// TODO: Get the preferred source address
return true;
}
result->ifName[0] = '0';
return false;
}
bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
{
// TODO: AF_INET6
FF_UNUSED(result);
return false;
}
@@ -1,6 +1,6 @@
#include "netif.h"
#include "common/io/io.h"
#include "util/mallocHelper.h"
#include "common/netif.h"
#include "common/io.h"
#include "common/mallocHelper.h"
#include <arpa/inet.h>
#include <net/if.h>

Some files were not shown because too many files have changed in this diff Show More