Compare commits

...

65 Commits

Author SHA1 Message Date
Carter Li 215029ea27 Merge pull request #919 from fastfetch-cli/dev
Release: v2.12.0
2024-05-14 15:53:45 +08:00
李通洲 533f54fb73 Doc: update changelog [ci skip] 2024-05-14 15:20:22 +08:00
李通洲 a6212c5b01 PhysicalMemory: add Ramaxel vendor id support 2024-05-14 14:11:12 +08:00
李通洲 ba76b18367 Fastfetch: remove support of flag based config 2024-05-14 14:08:54 +08:00
李通洲 4290efb49d Release: v2.12.0 2024-05-14 10:48:21 +08:00
李通洲 30b85fc169 JsonConfig: report row and column on JSON parsing errors 2024-05-14 10:47:20 +08:00
李通洲 dc94ac8d0c Doc: update json_schema 2024-05-14 10:25:29 +08:00
李通洲 1d9e612262 Presets: update [ci skip] 2024-05-14 09:11:27 +08:00
李通洲 be1791e386 LocalIP: add option --localip-show-all-ips 2024-05-13 23:33:06 +08:00
李通洲 3b8c2d6ee6 Logo (Builtin): add Quirinux 2024-05-13 22:27:35 +08:00
Null-Ping c661e55053 PhysicalMemory: Fix ram vendor names from ids. (#917)
Change 0x0198 from HyperX to Kingston to match https://www.jedec.org/standards-documents/docs/jep-106ab. (The standard does not contain an entry for HyperX at all).
Remove the ambiguous 0x1315 - according to the standard, it belongs to Tioga Technologies and not Crucial.
Rename Hynix to SK Hynix to match the standard.
2024-05-13 22:20:27 +08:00
李通洲 56403bab5c PhysicalMemory: try converting vendor ID to name 2024-05-13 20:29:46 +08:00
李通洲 caef317ade GPU: a tiny optimization 2024-05-13 19:33:31 +08:00
李通洲 131e01f35b Presets: add archey
Ref: https://github.com/HorlogeSkynet/archey4
2024-05-13 16:45:14 +08:00
李通洲 c8e3c6882a Kernel: print kernel name in default format 2024-05-13 16:41:00 +08:00
李通洲 c985bdbbfd Logo: add macOS3 2024-05-13 15:50:10 +08:00
李通洲 b80eb47ecd PhysicalMemory: better Linux compatibility 2024-05-13 15:08:27 +08:00
Carter Li 68942c1d3f PhysicalMemory (FreeBSD): fix EFAULT errors 2024-05-13 11:06:05 +08:00
李通洲 b36b74448f Doc: update changelog 2024-05-12 20:24:56 +08:00
李通洲 217bb6657e PhysicalMemory: fix output format 2024-05-12 20:17:57 +08:00
李通洲 df2862996b PhysicalMemory: detect ecc & bank locator 2024-05-12 19:55:04 +08:00
李通洲 df6ab6427e PhysicalMemory: improve default output format; detect part number 2024-05-12 19:15:03 +08:00
李通洲 82d848727c Logo (Builtin): fix alternate logo doesn't work with type builtin
Fix #914
2024-05-12 18:32:05 +08:00
李通洲 d0d6323b1f PhysicalMemory (FreeBSD): add support 2024-05-12 18:32:05 +08:00
李通洲 6439921f85 Smbios (Windows): check if getting SMBIOS data succeeds 2024-05-11 18:07:56 +08:00
李通洲 d28907ee9d PhysicalMemory (Linux): add support
Note: this module requires root permission to work in Linux
2024-05-11 18:05:30 +08:00
李通洲 41f0971570 PhysicalMemory: ignore trash values 2024-05-11 15:12:28 +08:00
李通洲 ab0bd79bb8 PhysicalMemory: add module to ci.jsonc and all.jsonc 2024-05-11 15:05:43 +08:00
李通洲 07747aa819 PhysicalMemory (macOS): add support 2024-05-11 15:05:43 +08:00
李通洲 68efcdd0dd PhysicalMemory: add new module 2024-05-11 15:05:43 +08:00
李通洲 fef3100fd7 Smbios: add struct layout check 2024-05-11 15:05:43 +08:00
Bernhard M. Wiedemann 08a940bfd4 Logo: Add the openSUSE Slowroll distribution (#913) 2024-05-11 15:03:13 +08:00
李通洲 d6a99c631e Image: support specifying --logo-width only for --kitty-direct and --iterm
Fix: #836

Ref: https://github.com/kovidgoyal/kitty/issues/7424
2024-05-10 14:30:00 +08:00
李通洲 3d4077c2d0 Config: support more color prefixes 2024-05-10 13:39:06 +08:00
djinnalexio ce6b595421 🔧 JsonConfig: add missing brightness properties 2024-05-10 11:13:47 +08:00
djinnalexio 7d8c085254 🔧 JsonConfig: add dim colors to validation 2024-05-10 11:13:47 +08:00
Souma ec0af17fb5 Terminal (macOS): fix compatibility with (*term) (#909)
Ignore <shell> (<char>term).
This is because Fig(<shell> (figterm)) migrated to CodeWhisperer(<shell> (cwterm)) and CodeWhisperer renamed to Q(<shell> (qterm)).
Future changes will all be ignored by this change.
Related: #676
2024-05-09 19:39:17 +08:00
李通洲 2accfbc894 Networking (Windows): fix compiling 2024-05-09 16:35:51 +08:00
李通洲 01d2fa1228 Doc: update changelog (ci skip) 2024-05-09 16:32:10 +08:00
李通洲 f16843d60f Doc: update changelog 2024-05-09 16:27:24 +08:00
李通洲 acc77ebddd PublicIP: add option --publicip-ipv6 2024-05-09 15:54:49 +08:00
李通洲 7eb145fb7f Presets: add loadavg to all.jsonc and ci.jsonc 2024-05-09 09:56:34 +08:00
Carter Li 34a6eb13c6 Loadavg (BSD): add missing headers 2024-05-09 09:51:41 +08:00
李通洲 0f5e746fe2 Loadavg: add option --loadavg-ndigits 2024-05-09 09:40:53 +08:00
李通洲 b62ad16aa6 Loadavg (BSD): use sysctl 2024-05-09 09:20:18 +08:00
李通洲 f79498e4b5 PublicIP / Weather: clarify error messages
Fix #907
2024-05-09 08:49:25 +08:00
李通洲 31c433b353 Display: rename --temperature-* to --temp-* as stated in help messages
Fix #908
2024-05-09 08:46:59 +08:00
李通洲 852c6abf2e Loadavg (Android): fix compiling 2024-05-08 21:54:13 +08:00
Quinten Van Damme df3fa6f8a8 Logo: Fix dahliaOS detection (#906) 2024-05-08 19:30:25 +08:00
李通洲 738daa1c77 Loadavg: new module 2024-05-08 18:34:34 +08:00
李通洲 4204cfc500 Doc: update help message for --module-output-color 2024-05-08 16:17:05 +08:00
李通洲 9cb08d115a Separator: add --separator-output-color 2024-05-08 16:11:16 +08:00
李通洲 459f159b1b Fastfetch: revert to module color after printing custom colors 2024-05-08 15:25:59 +08:00
李通洲 2880536513 Fastfetch: support --module-ouput-color (WIP) 2024-05-08 15:01:57 +08:00
李通洲 64cb1bfdfd Doc: remove duplicated entry 2024-05-08 14:33:00 +08:00
李通洲 b80c30ace3 Doc: default --hide-cursor to false 2024-05-08 11:06:38 +08:00
李通洲 19b8849bfc Fastfetch: remove the long deprecated flag --set & `-set-keyless 2024-05-08 11:06:03 +08:00
Carter Li 8f457f047c TerminalFont (Linux): searching for font config in st binary 2024-05-08 09:54:33 +08:00
Carter Li 299bc7468f Terminal (Linux): fix exePath detection 2024-05-08 09:54:33 +08:00
Carter Li c213b0769b Merge remote-tracking branch 'origin/master' into dev 2024-05-07 09:34:02 +08:00
AcatXIo 260c883d07 Presets: Update hardware.jsonc (#899)
Update hardware.jsonc preset, fix logo being forced to arch, add more hardware information.
2024-05-07 08:54:36 +08:00
Carter Li da0db042fa Merge pull request #897 from fastfetch-cli/dev
Release: 2.11.5
2024-05-07 00:41:44 +08:00
李通洲 ae5732e2a8 Release: v2.11.5 2024-05-07 00:38:08 +08:00
李通洲 1f05a33807 Logo (Builtin): temp fix for openmandriva logo detection
Fix #896
2024-05-07 00:19:07 +08:00
李通洲 f090951abc Doc: remove --os-file completely 2024-05-06 22:48:46 +08:00
86 changed files with 1896 additions and 471 deletions
+43 -8
View File
@@ -1,27 +1,62 @@
# 2.12.0
Changes:
* The long deprecated flag based config files are removed.
* They can still be used with `xargs fastfetch < /path/to/config.conf`
* `--gen-config` can be used to migrate them to json based config files
* The long deprecated options `--set` and `--set-keyless` are removed.
* `Kernel` module now prints kernel name by default
Features:
* Support `st` terminal font detection for font configuration compiled in `st` binary (TerminalFont, Linux)
* Add option `--color-output` to change output color of all modules except `Title`, `Separator`
* `display.color.output` in JSONC config file
* Add option `--<module>-output-color` to change output color of one specified module, which overrides the global option `--color-output`
* Add option `--publicip-ipv6` to print IPv6 address (PublicIP)
* Add new module `Loadavg` to print load averages (Loadavg)
* Add new module `PhysicalMemory` to print information of physical memory devices (PhysicalMemory)
* Requires root permission to work on Linux and FreeBSD
* Support specifying `--logo-width` only for `--kitty-direct` and `--iterm` (Logo)
* Add option `--localip-show-all-ips` to show all IPs assigned to the same interface (LocalIP)
* Default to `false`
* Improve compatibility with `(*term)` (#909, Terminal, macOS)
Bugfixes:
* Rename option `--temperature-unit` to `--temp-unit` as documented in help messages
* Fix alternate logo doesn't work with `{ "type": "builtin" }` (#914, Logo)
Logos:
* Fix DahliaOS detection
* Add openSUSE Slowroll
* Add macOS3
* Add Quirinux
# 2.11.5
Bugfix:
* Fix logo printing for OpenMandriva (#896)
* Remove `--os-file` in help messages
# 2.11.4
Changes:
* Fastfetch will print a colorless ascii logo in `--pipe` mode for better `lolcat` compatibility. `fastfetch | lolcat` should work and no `--pipe false` needed.
* Previously the logo would be disabled in `--pipe` mode.
* `--os-file` was removed and CMake option `-DCUSTOM_OS_RELEASE_PATH=/path/to/os-release` was added. This option should not used in most cases.
* Use `--pipe -l none` to get the old beheavior
* `--os-file` was removed and CMake option `-DCUSTOM_OS_RELEASE_PATH=/path/to/os-release` was introduced for configuring at compile time by package managers if needed. This option should not used in most cases.
Bugfixes:
* Fix possible out-of-bound memory access (#868)
* Fix Apple Terminal detection (macOS, Terminal)
* Fix doubled output in custom formation (#852)
* Fix Apple Terminal detection (#878, macOS, Terminal)
* Fix deprecation warning for macOS 14.0 hopefully (#860, macOS, Camera)
* Fix memory leaks when passing informative options
* Fix memory leaks when passing informative options (#888)
* Fix JSON config `size.ndigits` doesn't work
Features:
* Enable `--pipe` mode if environment variable `$NO_COLOR` is set
* Support Armbian and Proxmox distro detection (OS, Linux)
Logo:
* Add Armbian
# 2.11.3
+16 -3
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.11.4
VERSION 2.12.0
LANGUAGES C
DESCRIPTION "Fast neofetch-like system information tool"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
@@ -297,6 +297,7 @@ set(LIBFASTFETCH_SRC
src/detection/opencl/opencl.c
src/detection/os/os.c
src/detection/packages/packages.c
src/detection/physicalmemory/physicalmemory.c
src/detection/publicip/publicip.c
src/detection/terminaltheme/terminaltheme.c
src/detection/terminalfont/terminalfont.c
@@ -334,6 +335,7 @@ set(LIBFASTFETCH_SRC
src/modules/gamepad/gamepad.c
src/modules/kernel/kernel.c
src/modules/lm/lm.c
src/modules/loadavg/loadavg.c
src/modules/locale/locale.c
src/modules/localip/localip.c
src/modules/memory/memory.c
@@ -344,6 +346,7 @@ set(LIBFASTFETCH_SRC
src/modules/os/os.c
src/modules/packages/packages.c
src/modules/physicaldisk/physicaldisk.c
src/modules/physicalmemory/physicalmemory.c
src/modules/processes/processes.c
src/modules/player/player.c
src/modules/poweradapter/poweradapter.c
@@ -399,6 +402,7 @@ if(LINUX)
src/detection/bluetooth/bluetooth_linux.c
src/detection/disk/disk_linux.c
src/detection/physicaldisk/physicaldisk_linux.c
src/detection/physicalmemory/physicalmemory_linux.c
src/detection/diskio/diskio_linux.c
src/detection/displayserver/linux/displayserver_linux.c
src/detection/displayserver/linux/drm.c
@@ -417,6 +421,7 @@ if(LINUX)
src/detection/icons/icons_linux.c
src/detection/libc/libc_linux.c
src/detection/lm/lm_linux.c
src/detection/loadavg/loadavg_linux.c
src/detection/locale/locale_linux.c
src/detection/localip/localip_linux.c
src/detection/gamepad/gamepad_linux.c
@@ -464,6 +469,7 @@ elseif(ANDROID)
src/detection/cpuusage/cpuusage_linux.c
src/detection/disk/disk_linux.c
src/detection/physicaldisk/physicaldisk_linux.c
src/detection/physicalmemory/physicalmemory_nosupport.c
src/detection/diskio/diskio_linux.c
src/detection/displayserver/displayserver_android.c
src/detection/font/font_nosupport.c
@@ -472,6 +478,7 @@ elseif(ANDROID)
src/detection/icons/icons_nosupport.c
src/detection/libc/libc_android.c
src/detection/lm/lm_nosupport.c
src/detection/loadavg/loadavg_linux.c
src/detection/locale/locale_linux.c
src/detection/localip/localip_linux.c
src/detection/gamepad/gamepad_nosupport.c
@@ -520,6 +527,7 @@ elseif(BSD)
src/detection/cursor/cursor_linux.c
src/detection/disk/disk_bsd.c
src/detection/physicaldisk/physicaldisk_bsd.c
src/detection/physicalmemory/physicalmemory_linux.c
src/detection/diskio/diskio_bsd.c
src/detection/displayserver/linux/displayserver_linux.c
src/detection/displayserver/linux/drm.c
@@ -538,6 +546,7 @@ elseif(BSD)
src/detection/lm/lm_linux.c
src/detection/icons/icons_linux.c
src/detection/libc/libc_bsd.c
src/detection/loadavg/loadavg_bsd.c
src/detection/locale/locale_linux.c
src/detection/localip/localip_linux.c
src/detection/gamepad/gamepad_bsd.c
@@ -586,14 +595,16 @@ elseif(APPLE)
src/detection/cursor/cursor_apple.m
src/detection/disk/disk_bsd.c
src/detection/physicaldisk/physicaldisk_apple.c
src/detection/physicalmemory/physicalmemory_apple.m
src/detection/diskio/diskio_apple.c
src/detection/displayserver/displayserver_apple.c
src/detection/font/font_apple.m
src/detection/gpu/gpu_apple.c
src/detection/gpu/gpu_apple.m
src/detection/host/host_apple.c
src/detection/lm/lm_nosupport.c
src/detection/icons/icons_nosupport.c
src/detection/lm/lm_nosupport.c
src/detection/loadavg/loadavg_bsd.c
src/detection/libc/libc_apple.c
src/detection/locale/locale_linux.c
src/detection/localip/localip_linux.c
@@ -651,11 +662,13 @@ elseif(WIN32)
src/detection/icons/icons_windows.c
src/detection/libc/libc_windows.cpp
src/detection/lm/lm_nosupport.c
src/detection/loadavg/loadavg_nosupport.c
src/detection/locale/locale_windows.c
src/detection/localip/localip_windows.c
src/detection/gamepad/gamepad_windows.c
src/detection/media/media_nosupport.c
src/detection/memory/memory_windows.c
src/detection/physicalmemory/physicalmemory_linux.c
src/detection/monitor/monitor_windows.c
src/detection/netio/netio_windows.c
src/detection/opengl/opengl_windows.c
@@ -767,7 +780,7 @@ if(BSD AND EXISTS "/usr/local/bin/objdump")
endif()
endif()
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE __STDC_WANT_LIB_EXT1__=1)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE __STDC_WANT_LIB_EXT1__=1 _FILE_OFFSET_BITS=64)
if(WIN32)
target_compile_definitions(libfastfetch PUBLIC WIN32_LEAN_AND_MEAN=1)
elseif(APPLE)
-4
View File
@@ -191,7 +191,6 @@ __fastfetch_completion()
"--escape-bedrock"
"--pipe"
"--title-fqdn"
"--escape-bedrock"
"--disk-folders"
"--disk-show-external"
"--disk-show-hidden"
@@ -227,8 +226,6 @@ __fastfetch_completion()
"--separator"
"-s"
"--structure"
"--set"
"--set-keyless"
"--player-name"
"--percent-type"
"--publicip-url"
@@ -360,7 +357,6 @@ __fastfetch_completion()
local FF_OPTIONS_PATH=(
"-c"
"--config"
"--os-file"
"--lib-pci"
"--lib-vulkan"
"--lib-wayland"
+148 -4
View File
@@ -4,9 +4,8 @@
"colors": {
"type": "string",
"enum": [
"reset_", "bright_", "dim_",
"black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", "default",
"bright_black", "bright_red", "bright_green", "bright_yellow", "bright_blue", "bright_magenta", "bright_cyan", "bright_white"
"reset_", "bright_", "dim_", "italic_", "underline_", "blink_", "inverse_", "hidden_", "strike_", "light_",
"black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", "default"
]
},
"key": {
@@ -24,9 +23,13 @@
"default": 0
},
"format": {
"description": "Output format of the module",
"description": "Output format of the module. See `-h &lt;module&gt;-format` for detail",
"type": "string"
},
"outputColor": {
"description": "Output color of the module. Left empty to use `display.color.output`",
"$ref": "#/$defs/colors"
},
"percent": {
"description": "Threshold of percentage colors",
"type": "object",
@@ -380,6 +383,10 @@
"title": {
"description": "Set the color of the title",
"$ref": "#/$defs/colors"
},
"output": {
"description": "Set the color of the module output",
"$ref": "#/$defs/colors"
}
}
}
@@ -694,6 +701,7 @@
"icons",
"kernel",
"lm",
"loadavg",
"locale",
"localip",
"media",
@@ -893,6 +901,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -927,6 +938,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -958,6 +972,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -984,6 +1001,21 @@
"minimum": 0,
"maximum": 400,
"default": 10
},
"key": {
"$ref": "#/$defs/key"
},
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"format": {
"$ref": "#/$defs/format"
}
}
},
@@ -1002,6 +1034,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1035,6 +1070,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1142,6 +1180,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1166,6 +1207,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1215,6 +1259,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1275,6 +1322,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1307,6 +1357,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1335,6 +1388,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1361,6 +1417,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1406,6 +1465,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1448,6 +1510,11 @@
"type": "boolean",
"default": true
},
"showAllIps": {
"description": "Show all IPs bound to the same interface.\nBy default only the first IP is shown",
"type": "boolean",
"default": false
},
"compact": {
"description": "Show all IPs in one line",
"type": "boolean",
@@ -1468,6 +1535,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1494,6 +1564,42 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"format": {
"$ref": "#/$defs/format"
}
}
},
{
"title": "Loadavg",
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"const": "loadavg",
"description": "Print system load averages"
},
"ndigits": {
"type": "integer",
"description": "Set the number of digits to keep after the decimal point",
"minimum": 0,
"maximum": 9,
"default": 2
},
"key": {
"$ref": "#/$defs/key"
},
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1531,6 +1637,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1564,6 +1673,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1618,6 +1730,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1648,6 +1763,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1677,12 +1795,20 @@
"minimum": 0,
"default": "disabled (0)"
},
"ipv6": {
"description": "Whether to use IPv6 for public IP detection server",
"type": "boolean",
"default": false
},
"key": {
"$ref": "#/$defs/key"
},
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1704,6 +1830,9 @@
"description": "Set the string to be printed",
"type": "string",
"default": "-"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
}
}
},
@@ -1735,6 +1864,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1761,6 +1893,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1808,6 +1943,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1846,6 +1984,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
@@ -1874,6 +2015,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
+2
View File
@@ -10,6 +10,7 @@
"chassis",
"kernel",
"uptime",
"loadavg",
"processes",
"packages",
"shell",
@@ -33,6 +34,7 @@
"cpuusage",
"gpu",
"memory",
"physicalmemory",
"swap",
"disk",
"battery",
+84
View File
@@ -0,0 +1,84 @@
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"modules": [
{
"type": "title",
"key": "User",
"format": "{1}"
},
{
"type": "title",
"key": "Hostname",
"format": "{2}"
},
{
"type": "host",
"key": "Model"
},
{
"type": "os",
"format": "{3} {9} {12}"
},
"kernel",
"uptime",
{
"type": "loadavg",
"key": "Load Average"
},
"processes",
{
"type": "wm",
"key": "Window Manager"
},
{
"type": "de",
"key": "Desktop Environment"
},
{
"type": "shell",
"format": "{7}"
},
{
"type": "terminal",
"format": "{5} {6} \u001b[37m█\u001b[97m█ \u001b[36m█\u001b[96m█ \u001b[35m█\u001b[95m█ \u001b[34m█\u001b[94m█ \u001b[33m█\u001b[93m█ \u001b[32m█\u001b[92m█ \u001b[31m█\u001b[91m█ \u001b[30m█\u001b[90m█"
},
{
"type": "packages",
"format": "{1}"
},
{
"type": "cpu",
"key": "Temperature",
"temp": true,
"format": "{8}"
},
{
"type": "cpu",
"key": "CPU",
"format": "{4} x {1}"
},
{
"type": "gpu",
"format": "{2}"
},
{
"type": "memory",
"key": "RAM"
},
{
"type": "disk",
"key": "Disk",
"folders": "/"
},
{
"type": "localip",
"key": "LAN IP",
"showIpv6": true,
"showPrefixLen": false
},
{
"type": "publicip",
"key": "WAN IP"
}
]
}
+3
View File
@@ -6,6 +6,7 @@
"showErrors": true,
"noBuffer": true
},
"logo": null,
"modules": [
"title",
"separator",
@@ -16,6 +17,7 @@
"chassis",
"kernel",
"uptime",
"loadavg",
"processes",
"packages",
"shell",
@@ -39,6 +41,7 @@
"cpuusage",
"gpu",
"memory",
"physicalmemory",
"swap",
"disk",
"battery",
+25 -13
View File
@@ -1,25 +1,37 @@
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": {
"type": "builtin",
"source": "arch"
},
"modules": [
"host",
"display",
{
"type": "host",
"format": "{?2}{2}{?}{?5} ({5}){?}"
},
"chassis",
{
"type": "board",
"format": "{?1}{1}{?}{?2} ({2}){?}"
},
"cpu",
"gpu",
{
"type": "memory",
"format": "{?2}{2}{?}"
},
{
"type": "disk",
"format": "{?2}{2}{?}"
},
"physicaldisk",
"gpu",
"display",
"monitor",
{
"type": "wifi",
"format": "{?1}{1}{?}{?6} - {6}{?}"
},
{
"type": "sound",
"format": "{?2}{2}{?}"
},
"camera",
{
"type": "battery",
"format": "{?1}{1} {?}{?2}{2} {?}{?3}({3}){?}"
}
"format": "{?1}{1}{?}{?2} {2}{?}{?3} ({3}){?}"
},
"poweradapter"
]
}
+2 -21
View File
@@ -79,29 +79,10 @@ static void genJsonResult(FFModuleBaseInfo* baseInfo, yyjson_mut_doc* doc)
static void parseStructureCommand(
const char* line,
FFlist* customValues,
void (*fn)(FFModuleBaseInfo *baseInfo, yyjson_mut_doc* jsonDoc),
yyjson_mut_doc* jsonDoc
)
{
// handle `--set` and `--set-keyless`
FF_LIST_FOR_EACH(FFCustomValue, customValue, *customValues)
{
if (ffStrbufEqualS(&customValue->key, line))
{
__attribute__((__cleanup__(ffDestroyCustomOptions))) FFCustomOptions options;
ffInitCustomOptions(&options);
if (customValue->printKey)
ffStrbufAppend(&options.moduleArgs.key, &customValue->key);
ffStrbufAppend(&options.moduleArgs.outputFormat, &customValue->value);
if (__builtin_expect(jsonDoc != NULL, false))
fn((FFModuleBaseInfo*) &options, jsonDoc);
else
ffPrintCustom(&options);
return;
}
}
if(ffCharIsEnglishAlphabet(line[0]))
{
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(line[0]) - 'A']; *modules; ++modules)
@@ -134,7 +115,7 @@ void ffPrintCommandOption(FFdata* data, yyjson_mut_doc* jsonDoc)
if(instance.config.display.stat)
ms = ffTimeGetTick();
parseStructureCommand(data->structure.chars + startIndex, &data->customValues, genJsonResult, jsonDoc);
parseStructureCommand(data->structure.chars + startIndex, genJsonResult, jsonDoc);
if(instance.config.display.stat)
{
@@ -177,7 +158,7 @@ void ffMigrateCommandOptionToJsonc(FFdata* data, yyjson_mut_doc* jsonDoc)
uint32_t colonIndex = ffStrbufNextIndexC(&data->structure, startIndex, ':');
data->structure.chars[colonIndex] = '\0';
parseStructureCommand(data->structure.chars + startIndex, &data->customValues, genJsonConfig, jsonDoc);
parseStructureCommand(data->structure.chars + startIndex, genJsonConfig, jsonDoc);
startIndex = colonIndex + 1;
}
-8
View File
@@ -2,18 +2,10 @@
#include "fastfetch.h"
typedef struct FFCustomValue
{
bool printKey;
FFstrbuf key;
FFstrbuf value;
} FFCustomValue;
// Things only needed by fastfetch
typedef struct FFdata
{
FFstrbuf structure;
FFlist customValues; // List of FFCustomValue
bool configLoaded;
} FFdata;
+5
View File
@@ -22,6 +22,11 @@ bool ffJsonConfigParseModuleArgs(const char* key, yyjson_val* val, FFModuleArgs*
ffStrbufSetNS(&moduleArgs->outputFormat, (uint32_t) yyjson_get_len(val), yyjson_get_str(val));
return true;
}
else if(ffStrEqualsIgnCase(key, "outputColor"))
{
ffOptionParseColor(yyjson_get_str(val), &moduleArgs->outputColor);
return true;
}
else if(ffStrEqualsIgnCase(key, "keyColor"))
{
ffOptionParseColor(yyjson_get_str(val), &moduleArgs->keyColor);
+2
View File
@@ -71,6 +71,7 @@ static FFModuleBaseInfo* K[] = {
static FFModuleBaseInfo* L[] = {
(void*) &instance.config.modules.lm,
(void*) &instance.config.modules.loadavg,
(void*) &instance.config.modules.locale,
(void*) &instance.config.modules.localIP,
NULL,
@@ -98,6 +99,7 @@ static FFModuleBaseInfo* O[] = {
static FFModuleBaseInfo* P[] = {
(void*) &instance.config.modules.packages,
(void*) &instance.config.modules.physicalDisk,
(void*) &instance.config.modules.physicalMemory,
(void*) &instance.config.modules.player,
(void*) &instance.config.modules.powerAdapter,
(void*) &instance.config.modules.processes,
+1
View File
@@ -22,6 +22,7 @@ typedef struct FFNetworkingState {
#endif
uint32_t timeout;
bool ipv6;
} FFNetworkingState;
const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers);
+1 -1
View File
@@ -14,7 +14,7 @@ static const char* connectAndSend(FFNetworkingState* state)
struct addrinfo* addr;
if(getaddrinfo(state->host.chars, "80", &(struct addrinfo) {
.ai_family = AF_INET,
.ai_family = state->ipv6 ? AF_INET6 : AF_INET,
.ai_socktype = SOCK_STREAM,
}, &addr) != 0)
{
+1 -1
View File
@@ -51,7 +51,7 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
struct addrinfo* addr;
if(getaddrinfo(host, "80", &(struct addrinfo) {
.ai_family = AF_INET,
.ai_family = state->ipv6 ? AF_INET6 : AF_INET,
.ai_socktype = SOCK_STREAM,
}, &addr) != 0)
return "getaddrinfo() failed";
+18
View File
@@ -39,6 +39,16 @@ bool ffOptionParseModuleArgs(const char* argumentKey, const char* subKey, const
ffOptionParseString(argumentKey, value, &result->outputFormat);
return true;
}
else if(ffStrEqualsIgnCase(subKey, "output-color"))
{
if(value == NULL)
{
fprintf(stderr, "Error: usage: %s <str>\n", argumentKey);
exit(477);
}
ffOptionParseColor(value, &result->outputColor);
return true;
}
else if(ffStrEqualsIgnCase(subKey, "key-color"))
{
if(value == NULL)
@@ -148,6 +158,12 @@ void ffOptionParseColor(const char* value, FFstrbuf* buffer)
FF_APPEND_COLOR_CODE_COND(reset_, FF_COLOR_MODE_RESET)
else FF_APPEND_COLOR_CODE_COND(bright_, FF_COLOR_MODE_BOLD)
else FF_APPEND_COLOR_CODE_COND(dim_, FF_COLOR_MODE_DIM)
else FF_APPEND_COLOR_CODE_COND(italic_, FF_COLOR_MODE_ITALIC)
else FF_APPEND_COLOR_CODE_COND(underline_, FF_COLOR_MODE_UNDERLINE)
else FF_APPEND_COLOR_CODE_COND(blink_, FF_COLOR_MODE_BLINK)
else FF_APPEND_COLOR_CODE_COND(inverse_, FF_COLOR_MODE_INVERSE)
else FF_APPEND_COLOR_CODE_COND(hidden_, FF_COLOR_MODE_HIDDEN)
else FF_APPEND_COLOR_CODE_COND(strike_, FF_COLOR_MODE_STRIKETHROUGH)
else FF_APPEND_COLOR_CODE_COND(black, FF_COLOR_FG_BLACK)
else FF_APPEND_COLOR_CODE_COND(red, FF_COLOR_FG_RED)
else FF_APPEND_COLOR_CODE_COND(green, FF_COLOR_FG_GREEN)
@@ -180,6 +196,7 @@ void ffOptionInitModuleArg(FFModuleArgs* args)
ffStrbufInit(&args->key);
ffStrbufInit(&args->keyColor);
ffStrbufInit(&args->outputFormat);
ffStrbufInit(&args->outputColor);
args->keyWidth = 0;
}
@@ -188,4 +205,5 @@ void ffOptionDestroyModuleArg(FFModuleArgs* args)
ffStrbufDestroy(&args->key);
ffStrbufDestroy(&args->keyColor);
ffStrbufDestroy(&args->outputFormat);
ffStrbufDestroy(&args->outputColor);
}
+1
View File
@@ -50,6 +50,7 @@ typedef struct FFModuleArgs
FFstrbuf key;
FFstrbuf keyColor;
FFstrbuf outputFormat;
FFstrbuf outputColor;
uint32_t keyWidth;
} FFModuleArgs;
+15 -3
View File
@@ -6,7 +6,15 @@
#include "util/textModifier.h"
#include "util/stringUtils.h"
void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig config)
static void appendOutputColor(FFstrbuf* buffer, const FFModuleArgs* module)
{
if (module->outputColor.length)
ffStrbufAppendF(buffer, "\e[%sm", module->outputColor.chars);
else if (instance.config.display.colorOutput.length)
ffStrbufAppendF(buffer, "\e[%sm", instance.config.display.colorOutput.chars);
}
void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig config, const FFModuleArgs* module)
{
uint8_t green = config.green, yellow = config.yellow;
assert(green <= 100 && yellow <= 100);
@@ -66,16 +74,19 @@ void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig con
if(options->barBorder)
{
if(!options->pipe)
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_WHITE "m ]");
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_WHITE "m ]");\
else
ffStrbufAppendS(buffer, " ]");
}
if(!options->pipe)
{
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
appendOutputColor(buffer, module);
}
}
void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFColorRangeConfig config, bool parentheses)
void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFColorRangeConfig config, bool parentheses, const FFModuleArgs* module)
{
uint8_t green = config.green, yellow = config.yellow;
assert(green <= 100 && yellow <= 100);
@@ -120,6 +131,7 @@ void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFColorRangeConfig con
if (colored && !options->pipe)
{
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
appendOutputColor(buffer, module);
}
if (parentheses)
+3 -2
View File
@@ -2,6 +2,7 @@
#include "util/FFstrbuf.h"
#include "common/parsing.h"
#include "common/option.h"
enum
{
@@ -21,8 +22,8 @@ enum
// [yellow, green): print yellow
// [0, yellow): print red
void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig config);
void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFColorRangeConfig config, bool parentheses);
void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig config, const FFModuleArgs* module);
void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFColorRangeConfig config, bool parentheses, const FFModuleArgs* module);
typedef struct yyjson_val yyjson_val;
typedef struct yyjson_mut_doc yyjson_mut_doc;
+6 -1
View File
@@ -49,8 +49,13 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
ffStrbufWriteTo(&instance.config.display.keyValueSeparator, stdout);
if(!instance.config.display.pipe)
{
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
if (moduleArgs->outputColor.length)
ffPrintColor(&moduleArgs->outputColor);
else if (instance.config.display.colorOutput.length)
ffPrintColor(&instance.config.display.colorOutput);
}
if (!instance.config.display.pipe && !(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_WIDTH))
{
+8 -2
View File
@@ -3,7 +3,7 @@
#include "util/textModifier.h"
#include "util/stringUtils.h"
void ffTempsAppendNum(double celsius, FFstrbuf* buffer, FFColorRangeConfig config)
void ffTempsAppendNum(double celsius, FFstrbuf* buffer, FFColorRangeConfig config, const FFModuleArgs* module)
{
if (celsius != celsius) // ignores NaN
return;
@@ -37,7 +37,7 @@ void ffTempsAppendNum(double celsius, FFstrbuf* buffer, FFColorRangeConfig confi
}
}
switch (options->temperatureUnit)
switch (options->tempUnit)
{
case FF_TEMPERATURE_UNIT_CELSIUS:
ffStrbufAppendF(buffer, "%.*f°C", options->tempNdigits, celsius);
@@ -51,7 +51,13 @@ void ffTempsAppendNum(double celsius, FFstrbuf* buffer, FFColorRangeConfig confi
}
if (!options->pipe)
{
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
if (module->outputColor.length)
ffStrbufAppendF(buffer, "\e[%sm", module->outputColor.chars);
else if (instance.config.display.colorOutput.length)
ffStrbufAppendF(buffer, "\e[%sm", instance.config.display.colorOutput.chars);
}
}
bool ffTempsParseCommandOptions(const char* key, const char* subkey, const char* value, bool* useTemp, FFColorRangeConfig* config)
+2 -1
View File
@@ -1,8 +1,9 @@
#pragma once
#include "common/parsing.h"
#include "common/option.h"
void ffTempsAppendNum(double celsius, FFstrbuf* buffer, FFColorRangeConfig config);
void ffTempsAppendNum(double celsius, FFstrbuf* buffer, FFColorRangeConfig config, const FFModuleArgs* module);
bool ffTempsParseCommandOptions(const char* key, const char* subkey, const char* value, bool* useTemp, FFColorRangeConfig* config);
bool ffTempsParseJsonObject(const char* key, yyjson_val* value, bool* useTemp, FFColorRangeConfig* config);
void ffTempsGenerateJsonConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FF_MAYBE_UNUSED bool defaultTemp, FFColorRangeConfig defaultConfig, bool temp, FFColorRangeConfig config);
+47 -22
View File
@@ -436,7 +436,7 @@
{
"long": "color-keys",
"desc": "Set the color of the keys",
"remark": "See `-h color` for the list of available colors",
"remark": "Doesn't affect module Title, Separator and Colors. See `-h color` for the list of available colors",
"arg": {
"type": "color"
}
@@ -449,6 +449,14 @@
"type": "color"
}
},
{
"long": "color-output",
"desc": "Set the color of module output",
"remark": "See `-h color` for the list of available colors",
"arg": {
"type": "color"
}
},
{
"long": "color",
"desc": "Set the color of both the keys and title",
@@ -481,22 +489,6 @@
"default": ": "
}
},
{
"long": "set",
"desc": "Hard set the value of a key",
"remark": "Deprecated. Use \"Custom\" module instead",
"arg": {
"type": "key=value"
}
},
{
"long": "set-keyless",
"desc": "Hard set the value of a key, but don't print the key or the separator",
"remark": "Deprecated. Use \"Custom\" module instead",
"arg": {
"type": "key=value"
}
},
{
"long": "show-errors",
"desc": "Print occurring errors",
@@ -521,7 +513,7 @@
"arg": {
"type": "bool",
"optional": true,
"default": true
"default": false
}
},
{
@@ -938,11 +930,11 @@
}
},
{
"long": "os-file",
"desc": "Set the additional file path which containing OS information",
"remark": "Linux only",
"long": "separator-output-color",
"desc": "Set the color of the separator module",
"arg": {
"type": "path"
"type": "color",
"default": "default"
}
},
{
@@ -1236,6 +1228,14 @@
"default": false
}
},
{
"long": "loadavg-ndigits",
"desc": "Set the number of digits to keep after the decimal point when printing load average",
"arg": {
"type": "num",
"default": 2
}
},
{
"long": "localip-show-ipv4",
"desc": "Show IPv4 addresses in local ip module",
@@ -1298,6 +1298,15 @@
"default": true
}
},
{
"long": "localip-show-all-ips",
"desc": "Show all IPs bound to the same interface. By default only the first IP is shown",
"arg": {
"type": "bool",
"optional": true,
"default": false
}
},
{
"long": "localip-compact",
"desc": "Show all IPs in one line",
@@ -1348,6 +1357,14 @@
"type": "str"
}
},
{
"long": "publicip-ipv6",
"desc": "Whether to use IPv6 for public IP detection server",
"arg": {
"type": "bool",
"default": false
}
},
{
"long": "weather-location",
"desc": "Set the location to be used",
@@ -1522,6 +1539,14 @@
},
"pseudo": true
},
{
"long": "<module>-output-color",
"desc": "Override the global \"--color-output\" option for each specific module",
"arg": {
"type": "color"
},
"pseudo": true
},
{
"long": "<module>-key-width",
"desc": "Override the global \"--key-width\" option for each specific module",
+1 -1
View File
@@ -5,6 +5,6 @@ Infos about them can be found here: https://en.wikipedia.org/wiki/ANSI_escape_co
Examples:
--color 35: sets the color to magenta. `--color magenta` is also supported
--color 38;5;38: sets the color to 38th color of ANSI 256 colors
--color 4;92: sets the color to bright Green with underline
--color 4;92: sets the color to bright Green with underline. `--color underline_green` is also supported
--color 5;104: blinking text on a blue background
If no color is set, the main color of the logo will be used.
+9 -4
View File
@@ -154,8 +154,6 @@ static const char* detectWithSetupApi(FFBatteryOptions* options, FFlist* results
return NULL;
}
typedef struct FFSmbiosPortableBattery
{
FFSmbiosHeader Header;
@@ -178,11 +176,18 @@ typedef struct FFSmbiosPortableBattery
uint8_t SbdsDeviceChemistry; // string
uint8_t DesignCapacityMultiplier; // varies
uint16_t OEMSpecific; // varies
} FFSmbiosPortableBattery;
} __attribute__((__packed__)) FFSmbiosPortableBattery;
static_assert(offsetof(FFSmbiosPortableBattery, OEMSpecific) == 0x16,
"FFSmbiosPortableBattery: Wrong struct alignment");
const char* detectBySmbios(FFBatteryResult* battery)
{
const FFSmbiosPortableBattery* data = (const FFSmbiosPortableBattery*) (*ffGetSmbiosHeaderTable())[FF_SMBIOS_TYPE_PORTABLE_BATTERY];
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
if (!smbiosTable)
return "Failed to get SMBIOS data";
const FFSmbiosPortableBattery* data = (const FFSmbiosPortableBattery*) (*smbiosTable)[FF_SMBIOS_TYPE_PORTABLE_BATTERY];
if (!data)
return "Portable battery section is not found in SMBIOS data";
+10 -3
View File
@@ -35,7 +35,7 @@ typedef struct FFSmbiosBios
uint16_t BiosStartingAddressSegment; // varies
uint8_t BiosReleaseDate; // string
uint8_t BiosRomSize; // string
uint32_t BiosCharacteristics; // bit field
uint64_t BiosCharacteristics; // bit field
// 2.4+
uint8_t BiosCharacteristicsExtensionBytes[2]; // bit field
@@ -46,11 +46,18 @@ typedef struct FFSmbiosBios
// 3.1+
uint16_t ExtendedBiosRomSize; // bit field
} FFSmbiosBios;
} __attribute__((__packed__)) FFSmbiosBios;
static_assert(offsetof(FFSmbiosBios, ExtendedBiosRomSize) == 0x18,
"FFSmbiosBios: Wrong struct alignment");
const char* ffDetectBios(FFBiosResult* bios)
{
const FFSmbiosBios* data = (const FFSmbiosBios*) (*ffGetSmbiosHeaderTable())[FF_SMBIOS_TYPE_BIOS];
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
if (!smbiosTable)
return "Failed to get SMBIOS data";
const FFSmbiosBios* data = (const FFSmbiosBios*) (*smbiosTable)[FF_SMBIOS_TYPE_BIOS];
if (!data)
return "BIOS section is not found in SMBIOS data";
+11 -4
View File
@@ -14,13 +14,20 @@ typedef struct FFSmbiosBaseboard
uint8_t LocationInChassis; // string
uint16_t ChassisHandle; // varies
uint8_t BoardType; // enum
uint8_t NumberOfContainedObjectHandle; // varies
uint16_t ContainedObjectHandle[]; // varies
} FFSmbiosBaseboard;
uint8_t NumberOfContainedObjectHandles; // varies
uint16_t ContainedObjectHandles[]; // varies
} __attribute__((__packed__)) FFSmbiosBaseboard;
static_assert(offsetof(FFSmbiosBaseboard, ContainedObjectHandles) == 0x0F,
"FFSmbiosBaseboard: Wrong struct alignment");
const char* ffDetectBoard(FFBoardResult* board)
{
const FFSmbiosBaseboard* data = (const FFSmbiosBaseboard*) (*ffGetSmbiosHeaderTable())[FF_SMBIOS_TYPE_BASEBOARD_INFO];
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
if (!smbiosTable)
return "Failed to get SMBIOS data";
const FFSmbiosBaseboard* data = (const FFSmbiosBaseboard*) (*smbiosTable)[FF_SMBIOS_TYPE_BASEBOARD_INFO];
if (!data)
return "Baseboard information section is not found in SMBIOS data";
+9 -2
View File
@@ -25,11 +25,18 @@ typedef struct FFSmbiosSystemEnclosure
uint8_t ContainedElementCount; // varies
uint8_t ContainedRecordLength; // varies
uint8_t ContainedElements[]; // varies
} FFSmbiosSystemEnclosure;
} __attribute__((__packed__)) FFSmbiosSystemEnclosure;
static_assert(offsetof(FFSmbiosSystemEnclosure, ContainedElements) == 0x15,
"FFSmbiosSystemEnclosure: Wrong struct alignment");
const char* ffDetectChassis(FFChassisResult* result)
{
const FFSmbiosSystemEnclosure* data = (const FFSmbiosSystemEnclosure*) (*ffGetSmbiosHeaderTable())[FF_SMBIOS_TYPE_SYSTEM_ENCLOSURE];
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
if (!smbiosTable)
return "Failed to get SMBIOS data";
const FFSmbiosSystemEnclosure* data = (const FFSmbiosSystemEnclosure*) (*smbiosTable)[FF_SMBIOS_TYPE_SYSTEM_ENCLOSURE];
if (!data)
return "System enclosure is not found in SMBIOS data";
+9 -2
View File
@@ -48,7 +48,10 @@ typedef struct FFSmbiosProcessorInfo
// 3.6+
uint16_t ThreadEnabled; // varies
} FFSmbiosProcessorInfo;
} __attribute__((__packed__)) FFSmbiosProcessorInfo;
static_assert(offsetof(FFSmbiosProcessorInfo, ThreadEnabled) == 0x30,
"FFSmbiosProcessorInfo: Wrong struct alignment");
#if defined(__x86_64__) || defined(__i386__)
@@ -77,7 +80,11 @@ inline static const char* detectSpeedByCpuid(FF_MAYBE_UNUSED FFCPUResult* cpu)
static const char* detectMaxSpeedBySmbios(FFCPUResult* cpu)
{
const FFSmbiosProcessorInfo* data = (const FFSmbiosProcessorInfo*) (*ffGetSmbiosHeaderTable())[FF_SMBIOS_TYPE_PROCESSOR_INFO];
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
if (!smbiosTable)
return "Failed to get SMBIOS data";
const FFSmbiosProcessorInfo* data = (const FFSmbiosProcessorInfo*) (*smbiosTable)[FF_SMBIOS_TYPE_PROCESSOR_INFO];
if (!data)
return "Processor information is not found in SMBIOS data";
+15 -33
View File
@@ -14,42 +14,24 @@ const char* FF_GPU_VENDOR_NAME_MICROSOFT = "Microsoft";
const char* FF_GPU_VENDOR_NAME_REDHAT = "RedHat";
const char* FF_GPU_VENDOR_NAME_ORACLE = "Oracle";
static inline bool arrayContains(const unsigned arr[], unsigned vendorId, unsigned length)
{
for (unsigned i = 0; i < length; ++i)
{
if (arr[i] == vendorId)
return true;
}
return false;
}
const char* ffGetGPUVendorString(unsigned vendorId)
{
// https://devicehunt.com/all-pci-vendors
if(vendorId == 0x106b)
return FF_GPU_VENDOR_NAME_APPLE;
if(arrayContains((const unsigned[]) {0x1002, 0x1022}, vendorId, 2))
return FF_GPU_VENDOR_NAME_AMD;
else if(arrayContains((const unsigned[]) {0x03e7, 0x8086, 0x8087}, vendorId, 3))
return FF_GPU_VENDOR_NAME_INTEL;
else if(arrayContains((const unsigned[]) {0x0955, 0x10de, 0x12d2}, vendorId, 3))
return FF_GPU_VENDOR_NAME_NVIDIA;
else if(arrayContains((const unsigned[]) {0x5143}, vendorId, 1))
return FF_GPU_VENDOR_NAME_QUALCOMM;
else if(arrayContains((const unsigned[]) {0x14c3}, vendorId, 1))
return FF_GPU_VENDOR_NAME_MTK;
else if(arrayContains((const unsigned[]) {0x15ad}, vendorId, 1))
return FF_GPU_VENDOR_NAME_VMWARE;
else if(arrayContains((const unsigned[]) {0x1af4}, vendorId, 1))
return FF_GPU_VENDOR_NAME_REDHAT;
else if(arrayContains((const unsigned[]) {0x1ab8}, vendorId, 1))
return FF_GPU_VENDOR_NAME_PARALLEL;
else if(arrayContains((const unsigned[]) {0x1414}, vendorId, 1))
return FF_GPU_VENDOR_NAME_MICROSOFT;
else if(arrayContains((const unsigned[]) {0x108e}, vendorId, 1))
return FF_GPU_VENDOR_NAME_ORACLE;
return NULL;
switch (vendorId)
{
case 0x106b: return FF_GPU_VENDOR_NAME_APPLE;
case 0x1002: case 0x1022: return FF_GPU_VENDOR_NAME_AMD;
case 0x8086: case 0x8087: case 0x03e7: return FF_GPU_VENDOR_NAME_INTEL;
case 0x0955: case 0x10de: case 0x12d2: return FF_GPU_VENDOR_NAME_NVIDIA;
case 0x5143: return FF_GPU_VENDOR_NAME_QUALCOMM;
case 0x14c3: return FF_GPU_VENDOR_NAME_MTK;
case 0x15ad: return FF_GPU_VENDOR_NAME_VMWARE;
case 0x1af4: return FF_GPU_VENDOR_NAME_REDHAT;
case 0x1ab8: return FF_GPU_VENDOR_NAME_PARALLEL;
case 0x1414: return FF_GPU_VENDOR_NAME_MICROSOFT;
case 0x108e: return FF_GPU_VENDOR_NAME_ORACLE;
default: return NULL;
}
}
const char* detectByOpenGL(FFlist* gpus)
+10 -3
View File
@@ -18,17 +18,24 @@ typedef struct FFSmbiosSystemInfo
uint8_t ClockSeqHiAndReserved;
uint8_t ClockSeqLow;
uint8_t Node[6];
} UUID; // varies
} __attribute__((__packed__)) UUID; // varies
uint8_t WakeUpType; // enum
// 2.4+
uint8_t SKUNumber; // string
uint8_t Family; // string
} FFSmbiosSystemInfo;
} __attribute__((__packed__)) FFSmbiosSystemInfo;
static_assert(offsetof(FFSmbiosSystemInfo, Family) == 0x1A,
"FFSmbiosSystemInfo: Wrong struct alignment");
const char* ffDetectHost(FFHostResult* host)
{
const FFSmbiosSystemInfo* data = (const FFSmbiosSystemInfo*) (*ffGetSmbiosHeaderTable())[FF_SMBIOS_TYPE_SYSTEM_INFO];
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
if (!smbiosTable)
return "Failed to get SMBIOS data";
const FFSmbiosSystemInfo* data = (const FFSmbiosSystemInfo*) (*smbiosTable)[FF_SMBIOS_TYPE_SYSTEM_INFO];
if (!data)
return "System information is not found in SMBIOS data";
+5
View File
@@ -0,0 +1,5 @@
#pragma once
#include "fastfetch.h"
const char* ffDetectLoadavg(double result[3]);
+20
View File
@@ -0,0 +1,20 @@
#include "detection/loadavg/loadavg.h"
#include <sys/sysctl.h>
#ifdef __FreeBSD__
#include <sys/types.h>
#include <sys/resource.h>
#include <vm/vm_param.h>
#endif
const char* ffDetectLoadavg(double result[3])
{
struct loadavg load;
size_t size = sizeof(load);
if (sysctl((int []) { CTL_VM, VM_LOADAVG }, 2, &load, &size, NULL, 0) < 0)
return "sysctl({CTL_VM, VM_LOADAVG}) failed";
for (int i = 0; i < 3; i++)
result[i] = (double) load.ldavg[i] / (double) load.fscale;
return NULL;
}
+31
View File
@@ -0,0 +1,31 @@
#include "detection/loadavg/loadavg.h"
#include "common/io/io.h"
#include <sys/sysinfo.h>
const char* ffDetectLoadavg(double result[3])
{
#ifndef __ANDROID__ // cat: /proc/loadavg: Permission denied
// Don't use syscall for container compatibility. #620
char buf[64];
ssize_t nRead = ffReadFileData("/proc/uptime", sizeof(buf) - 1, buf);
if (nRead > 0)
{
buf[nRead] = '\0';
if (sscanf(buf, "%lf %lf %lf", &result[0], &result[1], &result[2]) == 3)
return NULL;
}
#endif
// getloadavg requires higher ANDROID_API version
struct sysinfo si;
if (sysinfo(&si) < 0)
return "sysinfo() failed";
for (int i = 0; i < 3; i++)
result[i] = (double) si.loads[i] / (1 << SI_LOAD_SHIFT);
return NULL;
}
@@ -0,0 +1,6 @@
#include "detection/loadavg/loadavg.h"
const char* ffDetectLoadavg(FF_MAYBE_UNUSED double result[3])
{
return "Not supported on this platform";
}
+16 -8
View File
@@ -17,7 +17,7 @@
#include <netpacket/packet.h>
#endif
static void addNewIp(FFlist* list, const char* name, const char* addr, int type, bool defaultRoute)
static void addNewIp(FFlist* list, const char* name, const char* addr, int type, bool defaultRoute, bool firstOnly)
{
FFLocalIpResult* ip = NULL;
@@ -40,11 +40,19 @@ static void addNewIp(FFlist* list, const char* name, const char* addr, int type,
switch (type)
{
case AF_INET:
if (ip->ipv4.length) ffStrbufAppendC(&ip->ipv4, ',');
if (ip->ipv4.length)
{
if (firstOnly) return;
ffStrbufAppendC(&ip->ipv4, ',');
}
ffStrbufAppendS(&ip->ipv4, addr);
break;
case AF_INET6:
if (ip->ipv6.length) ffStrbufAppendC(&ip->ipv6, ',');
if (ip->ipv6.length)
{
if (firstOnly) return;
ffStrbufAppendC(&ip->ipv6, ',');
}
ffStrbufAppendS(&ip->ipv6, addr);
break;
case -1:
@@ -67,7 +75,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
continue;
bool isDefaultRoute = ffStrEquals(defaultRouteIfName, ifa->ifa_name);
if (options->defaultRouteOnly && !isDefaultRoute)
if ((options->showType & FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT) && !isDefaultRoute)
continue;
if ((ifa->ifa_flags & IFF_LOOPBACK) && !(options->showType & FF_LOCALIP_TYPE_LOOP_BIT))
@@ -96,7 +104,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
}
}
addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET, isDefaultRoute);
addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET, isDefaultRoute, !(options->showType & FF_LOCALIP_TYPE_ALL_IPS_BIT));
}
else if (ifa->ifa_addr->sa_family == AF_INET6)
{
@@ -121,7 +129,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
}
}
addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET6, isDefaultRoute);
addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET6, isDefaultRoute, !(options->showType & FF_LOCALIP_TYPE_ALL_IPS_BIT));
}
#if defined(__FreeBSD__) || defined(__APPLE__)
else if (ifa->ifa_addr->sa_family == AF_LINK)
@@ -133,7 +141,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
uint8_t* ptr = (uint8_t*) LLADDR((struct sockaddr_dl *)ifa->ifa_addr);
snprintf(addressBuffer, sizeof(addressBuffer), "%02x:%02x:%02x:%02x:%02x:%02x",
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
addNewIp(results, ifa->ifa_name, addressBuffer, -1, isDefaultRoute);
addNewIp(results, ifa->ifa_name, addressBuffer, -1, isDefaultRoute, false);
}
#else
else if (ifa->ifa_addr->sa_family == AF_PACKET)
@@ -145,7 +153,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
uint8_t* ptr = ((struct sockaddr_ll *)ifa->ifa_addr)->sll_addr;
snprintf(addressBuffer, sizeof(addressBuffer), "%02x:%02x:%02x:%02x:%02x:%02x",
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
addNewIp(results, ifa->ifa_name, addressBuffer, -1, isDefaultRoute);
addNewIp(results, ifa->ifa_name, addressBuffer, -1, isDefaultRoute, false);
}
#endif
}
+13 -1
View File
@@ -78,7 +78,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
for (IP_ADAPTER_ADDRESSES* adapter = adapter_addresses; adapter; adapter = adapter->Next)
{
bool isDefaultRoute = adapter->IfIndex == defaultRouteIfIndex;
if (options->defaultRouteOnly && !isDefaultRoute)
if ((options->showType & FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT) && !isDefaultRoute)
continue;
bool isLoop = adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK;
@@ -102,10 +102,14 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
newIp = false;
}
uint32_t typesToAdd = options->showType & (FF_LOCALIP_TYPE_IPV4_BIT | FF_LOCALIP_TYPE_IPV6_BIT | FF_LOCALIP_TYPE_ALL_IPS_BIT);
for (IP_ADAPTER_UNICAST_ADDRESS* ifa = adapter->FirstUnicastAddress; ifa; ifa = ifa->Next)
{
if (ifa->Address.lpSockaddr->sa_family == AF_INET)
{
if (!(typesToAdd & (FF_LOCALIP_TYPE_IPV4_BIT | FF_LOCALIP_TYPE_ALL_IPS_BIT))) continue;
SOCKADDR_IN* ipv4 = (SOCKADDR_IN*) ifa->Address.lpSockaddr;
char addressBuffer[INET_ADDRSTRLEN + 4];
inet_ntop(AF_INET, &ipv4->sin_addr, addressBuffer, INET_ADDRSTRLEN);
@@ -118,9 +122,14 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
addNewIp(results, name, addressBuffer, AF_INET, newIp, isDefaultRoute);
newIp = false;
typesToAdd &= ~(unsigned) FF_LOCALIP_TYPE_IPV4_BIT;
if (typesToAdd == 0) break;
}
else if (ifa->Address.lpSockaddr->sa_family == AF_INET6)
{
if (!(typesToAdd & (FF_LOCALIP_TYPE_IPV6_BIT | FF_LOCALIP_TYPE_ALL_IPS_BIT))) continue;
SOCKADDR_IN6* ipv6 = (SOCKADDR_IN6*) ifa->Address.lpSockaddr;
char addressBuffer[INET6_ADDRSTRLEN + 4];
inet_ntop(AF_INET6, &ipv6->sin6_addr, addressBuffer, INET6_ADDRSTRLEN);
@@ -133,6 +142,9 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
addNewIp(results, name, addressBuffer, AF_INET6, newIp, isDefaultRoute);
newIp = false;
typesToAdd &= ~(unsigned) FF_LOCALIP_TYPE_IPV6_BIT;
if (typesToAdd == 0) break;
}
}
}
@@ -0,0 +1,43 @@
#include "physicalmemory.h"
static inline const char* getVendorString(unsigned vendorId)
{
switch (vendorId)
{
case 0x017A: return "Apacer";
case 0x0198: return "Kingston";
case 0x029E: return "Corsair";
case 0x04CB: return "A-DATA";
case 0x04CD: return "G-Skill";
case 0x059B: case 0x859B: return "Crucial";
case 0x00CE: case 0x80CE: case 0xCE00: return "Samsung";
case 0x014F: return "Transcend";
case 0x2C00: case 0x802C: return "Micron";
case 0xAD00: case 0x80AD: return "SK Hynix";
case 0x5105: case 0x8551: return "Qimonda";
case 0x02FE: return "Elpida";
case 0x0467: return "Ramaxel";
default: return NULL;
}
}
void FFPhysicalMemoryUpdateVendorString(FFPhysicalMemoryResult* device)
{
char vendorIdStr[5];
if (ffStrbufStartsWithS(&device->vendor, "0x"))
{
if (device->vendor.length < 6) return;
memcpy(vendorIdStr, device->vendor.chars + 2, 4);
}
else
{
if (device->vendor.length < 4) return;
memcpy(vendorIdStr, device->vendor.chars, 4);
}
vendorIdStr[4] = '\0';
char* pEnd = NULL;
uint32_t vendorId = (uint32_t) strtoul(vendorIdStr, &pEnd, 16);
if (*pEnd != '\0') return;
const char* vendorStr = getVendorString(vendorId);
if (vendorStr) ffStrbufSetStatic(&device->vendor, vendorStr);
}
@@ -0,0 +1,21 @@
#pragma once
#include "fastfetch.h"
typedef struct FFPhysicalMemoryResult
{
uint64_t size; // B
uint32_t maxSpeed; // MT/s
uint32_t runningSpeed; // MT/s
FFstrbuf type;
FFstrbuf formFactor;
FFstrbuf locator;
FFstrbuf partNumber;
FFstrbuf vendor;
FFstrbuf serial;
bool ecc;
} FFPhysicalMemoryResult;
const char* ffDetectPhysicalMemory(FFlist* result); // list of FFPhysicalMemoryResult
void FFPhysicalMemoryUpdateVendorString(FFPhysicalMemoryResult* device);
@@ -0,0 +1,121 @@
#include "physicalmemory.h"
#include "common/processing.h"
#include "util/smbiosHelper.h"
#include "util/stringUtils.h"
#import <Foundation/Foundation.h>
static void appendDevice(
FFlist* result,
NSString* type,
NSString* vendor,
NSString* size,
// Intel only
NSString* locator,
NSString* serial,
NSString* partNumber,
NSString* speed,
bool ecc)
{
FFPhysicalMemoryResult* device = ffListAdd(result);
ffStrbufInitS(&device->type, type.UTF8String);
ffStrbufInit(&device->formFactor);
ffStrbufInitS(&device->locator, locator.UTF8String);
ffStrbufInitS(&device->vendor, vendor.UTF8String);
FFPhysicalMemoryUpdateVendorString(device);
ffStrbufInitS(&device->serial, serial.UTF8String);
ffCleanUpSmbiosValue(&device->serial);
ffStrbufInitS(&device->partNumber, partNumber.UTF8String);
ffCleanUpSmbiosValue(&device->partNumber);
device->size = 0;
device->maxSpeed = 0;
device->runningSpeed = 0;
device->ecc = ecc;
if (size)
{
char* unit = NULL;
device->size = strtoul(size.UTF8String, &unit, 10);
if (*unit == ' ') ++unit;
switch (*unit)
{
case 'G': device->size *= 1024ULL * 1024 * 1024; break;
case 'M': device->size *= 1024ULL * 1024; break;
case 'K': device->size *= 1024ULL; break;
case 'T': device->size *= 1024ULL * 1024 * 1024 * 1024; break;
}
}
if (speed)
{
char* unit = NULL;
device->maxSpeed = (uint32_t) strtoul(speed.UTF8String, &unit, 10);
if (*unit == ' ') ++unit;
switch (*unit)
{
case 'T': device->maxSpeed *= 1000 * 1000; break;
case 'G': device->maxSpeed *= 1000; break;
case 'K': device->maxSpeed /= 1000; break;
}
device->runningSpeed = device->maxSpeed;
}
}
const char* ffDetectPhysicalMemory(FFlist* result)
{
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
if (ffProcessAppendStdOut(&buffer, (char* const[]) {
"system_profiler",
"SPMemoryDataType",
"-xml",
"-detailLevel",
"full",
NULL
}) != NULL)
return "Starting `system_profiler SPMemoryDataType -xml -detailLevel full` failed";
NSArray* arr = [NSPropertyListSerialization propertyListWithData:[NSData dataWithBytes:buffer.chars length:buffer.length]
options:NSPropertyListImmutable
format:nil
error:nil];
if (!arr || !arr.count)
return "system_profiler SPMemoryDataType returned an empty array";
for (NSDictionary* data in arr[0][@"_items"])
{
if (data[@"_items"])
{
// for Intel
for (NSDictionary* item in data[@"_items"])
{
appendDevice(result,
item[@"dimm_type"],
item[@"dimm_manufacturer"],
item[@"dimm_size"],
item[@"_name"],
item[@"dimm_serial_number"],
item[@"dimm_part_number"],
item[@"dimm_speed"],
!![data[@"global_ecc_state"] isEqualToString:@"ecc_enabled"]);
}
}
else
{
// for Apple Silicon
appendDevice(result,
data[@"dimm_type"],
data[@"dimm_manufacturer"],
data[@"SPMemoryDataType"],
nil,
nil,
nil,
nil,
false);
}
}
return NULL;
}
@@ -0,0 +1,204 @@
#include "physicalmemory.h"
#include "util/smbiosHelper.h"
// 7.18
typedef struct FFSmbiosMemoryDevice
{
FFSmbiosHeader Header;
// 2.1+
uint16_t PhysicalMemoryArrayHandle; // varies
uint16_t MemoryErrorInformationHandle; //varies
uint16_t TotalWidth; // varies
uint16_t DataWidth; // varies
uint16_t Size; // varies
uint8_t FormFactor; // enum
uint8_t DeviceSet; // varies
uint8_t DeviceLocator; // string
uint8_t BankLocator; // string
uint8_t MemoryType; // enum
uint16_t TypeDetail; // bit field
// 2.3+
uint16_t Speed; // varies
uint8_t Manufacturer; // string
uint8_t SerialNumber; // string
uint8_t AssetTag; // string
uint8_t PartNumber; // string
// 2.6+
uint8_t Attributes; // varies
// 2.7+
uint32_t ExtendedSize; // varies
uint16_t ConfiguredMemorySpeed; // varies
// 2.8+
uint16_t MinimumVoltage; // varies
uint16_t MaximumVoltage; // varies
uint16_t ConfiguredVoltage; // varies
// 3.2+
uint8_t MemoryTechnology; // varies
uint16_t MemoryOperatingMode; // bit field
uint8_t FirmwareVersion; // string
uint16_t ModuleManufacturerID; // varies
uint16_t ModuleProductID; // varies
uint16_t MemorySubsystemControllerManufacturerID; // vaies
uint16_t MemorySubsystemControllerProductID; // varies
uint64_t NonVolatileSize; // varies
uint64_t VolatileSize; // varies
uint64_t CacheSize; // varies
uint64_t LogicalSize; // varies
// 3.3+
uint32_t ExtendedSpeed; // varies
uint32_t ExtendedConfiguredSpeed; // varies
// 3.7+
uint16_t Pmic0ManufacturerID; // varies
uint16_t Pmic0RevisionNumber; // varies
uint16_t RcdManufacturerID; // varies
uint16_t RcdRevisionNumber; // varies
} __attribute__((__packed__)) FFSmbiosMemoryDevice;
static_assert(offsetof(FFSmbiosMemoryDevice, RcdRevisionNumber) == 0x62,
"FFSmbiosMemoryDevice: Wrong struct alignment");
const char* ffDetectPhysicalMemory(FFlist* result)
{
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
if (!smbiosTable)
return "Failed to get SMBIOS data";
const FFSmbiosMemoryDevice* data = (const FFSmbiosMemoryDevice*) (*smbiosTable)[FF_SMBIOS_TYPE_MEMORY_DEVICE];
if (!data)
return "Memory device is not found in SMBIOS data";
for (; data->Header.Type == FF_SMBIOS_TYPE_MEMORY_DEVICE;
data = (const FFSmbiosMemoryDevice*) ffSmbiosNextEntry(&data->Header))
{
if (data->Size == 0) continue;
const char* strings = (const char*) data + data->Header.Length;
FFPhysicalMemoryResult* device = ffListAdd(result);
ffStrbufInit(&device->type);
ffStrbufInit(&device->formFactor);
ffStrbufInit(&device->locator);
ffStrbufInit(&device->vendor);
ffStrbufInit(&device->serial);
ffStrbufInit(&device->partNumber);
device->size = 0;
device->maxSpeed = 0;
device->runningSpeed = 0;
device->ecc = false;
if (data->TotalWidth != 0xFFFF && data->DataWidth != 0xFFFF)
device->ecc = data->TotalWidth > data->DataWidth;
if (data->Size != 0xFFFF)
{
if (data->Size == 0x7FFF)
device->size = (data->ExtendedSize & ~(1 << 31)) * 1024 * 1024;
else if (data->Size & (1 << 15))
{
// in kB
device->size = (data->Size & ~(1u << 15)) * 1024ULL;
}
else
{
// in MB
device->size = data->Size * 1024ULL * 1024ULL;
}
}
ffStrbufSetF(&device->locator, "%s/%s", ffSmbiosLocateString(strings, data->BankLocator), ffSmbiosLocateString(strings, data->DeviceLocator));
switch (data->FormFactor)
{
case 0x01: ffStrbufSetStatic(&device->formFactor, "Other"); break;
case 0x02: ffStrbufSetStatic(&device->formFactor, "Unknown"); break;
case 0x03: ffStrbufSetStatic(&device->formFactor, "SIMM"); break;
case 0x04: ffStrbufSetStatic(&device->formFactor, "SIP"); break;
case 0x05: ffStrbufSetStatic(&device->formFactor, "Chip"); break;
case 0x06: ffStrbufSetStatic(&device->formFactor, "DIP"); break;
case 0x07: ffStrbufSetStatic(&device->formFactor, "ZIP"); break;
case 0x08: ffStrbufSetStatic(&device->formFactor, "Proprietary Card"); break;
case 0x09: ffStrbufSetStatic(&device->formFactor, "DIMM"); break;
case 0x0A: ffStrbufSetStatic(&device->formFactor, "TSOP"); break;
case 0x0B: ffStrbufSetStatic(&device->formFactor, "Row of chips"); break;
case 0x0C: ffStrbufSetStatic(&device->formFactor, "RIMM"); break;
case 0x0D: ffStrbufSetStatic(&device->formFactor, "SODIMM"); break;
case 0x0E: ffStrbufSetStatic(&device->formFactor, "SRIMM"); break;
case 0x0F: ffStrbufSetStatic(&device->formFactor, "FBDIMM"); break;
case 0x10: ffStrbufSetStatic(&device->formFactor, "Die"); break;
default: ffStrbufSetF(&device->formFactor, "Unknown (%d)", (int) data->FormFactor); break;
}
switch (data->MemoryType)
{
case 0x01: ffStrbufSetStatic(&device->type, "Other"); break;
case 0x02: ffStrbufSetStatic(&device->type, "Unknown"); break;
case 0x03: ffStrbufSetStatic(&device->type, "DRAM"); break;
case 0x04: ffStrbufSetStatic(&device->type, "EDRAM"); break;
case 0x05: ffStrbufSetStatic(&device->type, "VRAM"); break;
case 0x06: ffStrbufSetStatic(&device->type, "SRAM"); break;
case 0x07: ffStrbufSetStatic(&device->type, "RAM"); break;
case 0x08: ffStrbufSetStatic(&device->type, "ROM"); break;
case 0x09: ffStrbufSetStatic(&device->type, "FLASH"); break;
case 0x0A: ffStrbufSetStatic(&device->type, "EEPROM"); break;
case 0x0B: ffStrbufSetStatic(&device->type, "FEPROM"); break;
case 0x0C: ffStrbufSetStatic(&device->type, "EPROM"); break;
case 0x0D: ffStrbufSetStatic(&device->type, "CDRAM"); break;
case 0x0E: ffStrbufSetStatic(&device->type, "3DRAM"); break;
case 0x0F: ffStrbufSetStatic(&device->type, "SDRAM"); break;
case 0x10: ffStrbufSetStatic(&device->type, "SGRAM"); break;
case 0x11: ffStrbufSetStatic(&device->type, "RDRAM"); break;
case 0x12: ffStrbufSetStatic(&device->type, "DDR"); break;
case 0x13: ffStrbufSetStatic(&device->type, "DDR2"); break;
case 0x14: ffStrbufSetStatic(&device->type, "DDR2 FB-DIMM"); break;
case 0x15:
case 0x16:
case 0x17: ffStrbufSetStatic(&device->type, "Reserved"); break;
case 0x18: ffStrbufSetStatic(&device->type, "DDR3"); break;
case 0x19: ffStrbufSetStatic(&device->type, "FBD2"); break;
case 0x1A: ffStrbufSetStatic(&device->type, "DDR4"); break;
case 0x1B: ffStrbufSetStatic(&device->type, "LPDDR"); break;
case 0x1C: ffStrbufSetStatic(&device->type, "LPDDR2"); break;
case 0x1D: ffStrbufSetStatic(&device->type, "LPDDR3"); break;
case 0x1E: ffStrbufSetStatic(&device->type, "LPDDR4"); break;
case 0x1F: ffStrbufSetStatic(&device->type, "Logical non-volatile device"); break;
case 0x20: ffStrbufSetStatic(&device->type, "HBM"); break;
case 0x21: ffStrbufSetStatic(&device->type, "HBM2"); break;
case 0x22: ffStrbufSetStatic(&device->type, "DDR5"); break;
case 0x23: ffStrbufSetStatic(&device->type, "LPDDR5"); break;
case 0x24: ffStrbufSetStatic(&device->type, "HBM3"); break;
default: ffStrbufSetF(&device->type, "Unknown (%d)", (int) data->MemoryType); break;
}
if (data->Header.Length > offsetof(FFSmbiosMemoryDevice, Speed)) // 2.3+
{
if (data->Speed)
device->maxSpeed = data->Speed == 0xFFFF ? data->ExtendedSpeed : data->Speed;
ffStrbufSetStatic(&device->vendor, ffSmbiosLocateString(strings, data->Manufacturer));
FFPhysicalMemoryUpdateVendorString(device);
ffStrbufSetStatic(&device->serial, ffSmbiosLocateString(strings, data->SerialNumber));
ffCleanUpSmbiosValue(&device->serial);
ffStrbufSetStatic(&device->partNumber, ffSmbiosLocateString(strings, data->PartNumber));
ffCleanUpSmbiosValue(&device->partNumber);
}
if (data->Header.Length > offsetof(FFSmbiosMemoryDevice, ConfiguredMemorySpeed)) // 2.7+
{
if (data->ConfiguredMemorySpeed)
device->runningSpeed = data->ConfiguredMemorySpeed == 0xFFFF
? data->ExtendedConfiguredSpeed : data->ConfiguredMemorySpeed;
}
}
return NULL;
}
@@ -0,0 +1,6 @@
#include "physicalmemory.h"
const char* ffDetectPhysicalMemory(FF_MAYBE_UNUSED FFlist* result)
{
return "Not supported on this platform";
}
+16 -11
View File
@@ -2,21 +2,24 @@
#include "common/networking.h"
#define FF_UNITIALIZED ((const char*)(uintptr_t) -1)
static FFNetworkingState state;
static const char* status = FF_UNITIALIZED;
static FFNetworkingState states[2];
static const char* statuses[2] = { FF_UNITIALIZED, FF_UNITIALIZED };
void ffPreparePublicIp(FFPublicIpOptions* options)
{
if (status != FF_UNITIALIZED)
FFNetworkingState* state = &states[options->ipv6];
const char** status = &statuses[options->ipv6];
if (*status != FF_UNITIALIZED)
{
fputs("Error: this module can only be used once due to internal limitations\n", stderr);
fputs("Error: PublicIp module can only be used once due to internal limitations\n", stderr);
exit(1);
}
state.timeout = options->timeout;
state->timeout = options->timeout;
state->ipv6 = options->ipv6;
if (options->url.length == 0)
status = ffNetworkingSendHttpRequest(&state, "ipinfo.io", "/json", NULL);
*status = ffNetworkingSendHttpRequest(state, options->ipv6 ? "v6.ipinfo.io" : "ipinfo.io", "/json", NULL);
else
{
FF_STRBUF_AUTO_DESTROY host = ffStrbufCreateCopy(&options->url);
@@ -40,7 +43,7 @@ void ffPreparePublicIp(FFPublicIpOptions* options)
host.chars[pathStartIndex] = '\0';
}
status = ffNetworkingSendHttpRequest(&state, host.chars, path.length == 0 ? "/" : path.chars, NULL);
*status = ffNetworkingSendHttpRequest(state, host.chars, path.length == 0 ? "/" : path.chars, NULL);
}
}
@@ -53,14 +56,16 @@ static inline void wrapYyjsonFree(yyjson_doc** doc)
const char* ffDetectPublicIp(FFPublicIpOptions* options, FFPublicIpResult* result)
{
if (status == FF_UNITIALIZED)
FFNetworkingState* state = &states[options->ipv6];
const char** status = &statuses[options->ipv6];
if (*status == FF_UNITIALIZED)
ffPreparePublicIp(options);
if (status != NULL)
return status;
if (*status != NULL)
return *status;
FF_STRBUF_AUTO_DESTROY response = ffStrbufCreateA(4096);
const char* error = ffNetworkingRecvHttpResponse(&state, &response);
const char* error = ffNetworkingRecvHttpResponse(state, &response);
if (error == NULL)
ffStrbufSubstrAfterFirstS(&response, "\r\n\r\n");
else
+45 -11
View File
@@ -3,6 +3,7 @@
#include "common/properties.h"
#include "common/parsing.h"
#include "common/io/io.h"
#include "common/processing.h"
#include "detection/terminalshell/terminalshell.h"
#include "detection/displayserver/displayserver.h"
#include "util/mallocHelper.h"
@@ -265,9 +266,9 @@ static void detectXterm(FFTerminalFontResult* terminalFont)
ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars);
}
static void detectSt(FFTerminalFontResult* terminalFont, uint32_t pid)
static void detectSt(FFTerminalFontResult* terminalFont, const FFTerminalResult* terminal)
{
FF_STRBUF_AUTO_DESTROY size = ffStrbufCreateF("/proc/%u/cmdline", pid);
FF_STRBUF_AUTO_DESTROY size = ffStrbufCreateF("/proc/%u/cmdline", terminal->pid);
FF_STRBUF_AUTO_DESTROY font = ffStrbufCreate();
if (!ffAppendFileBuffer(size.chars, &font))
{
@@ -276,20 +277,53 @@ static void detectSt(FFTerminalFontResult* terminalFont, uint32_t pid)
}
const char* p = memmem(font.chars, font.length, "\0-f", sizeof("\0-f")); // find parameter of `-f`
if (!p)
if (p)
{
ffStrbufAppendF(&terminalFont->error, "st was not executed with `-f` parameter");
return;
// st was executed with `-f` parameter
ffStrbufSubstrAfter(&font, (uint32_t) (p + (sizeof("\0-f") - 1) - font.chars));
ffStrbufRecalculateLength(&font);
}
else
{
ffStrbufClear(&font);
if (ffProcessAppendStdOut(&font, (char* const[]) {
"strings",
terminal->exePath.chars,
NULL,
}) != NULL || font.length == 0)
{
ffStrbufAppendS(&terminalFont->error, "Failed to run `strings st`");
return;
}
// Search font config string in st binary
uint32_t middleIndex = ffStrbufFirstIndexS(&font, "size=");
if (middleIndex == font.length)
{
ffStrbufAppendS(&terminalFont->error, "No font config found in st binary");
return;
}
uint32_t startIndex = ffStrbufPreviousIndexC(&font, middleIndex, '\n');
if (startIndex == font.length) startIndex = 0;
uint32_t endIndex = ffStrbufNextIndexC(&font, middleIndex, '\n');
ffStrbufSubstrBefore(&font, endIndex);
ffStrbufSubstrAfter(&font, startIndex);
}
ffStrbufSubstrAfter(&font, (uint32_t) (p + (sizeof("\0-f") - 1) - font.chars));
ffStrbufRecalculateLength(&font);
// JetBrainsMono Nerd Font Mono:pixelsize=12:antialias=true:autohint=true
// `monospace:size=15` || `monospace` || `:size=15`
uint32_t index = ffStrbufFirstIndexS(&font, ":size=");
uint32_t index = ffStrbufFirstIndexC(&font, ':');
if (index != font.length)
{
ffStrbufSetS(&size, font.chars + index + strlen(":size="));
uint32_t sIndex = ffStrbufNextIndexS(&font, index + 1, "size=");
if (sIndex != font.length)
{
sIndex += strlen("size=");
uint32_t sIndexEnd = ffStrbufNextIndexC(&font, sIndex, ':');
ffStrbufSetNS(&size, sIndexEnd - sIndex, font.chars + sIndex);
}
ffStrbufSubstrBefore(&font, index);
}
else
@@ -365,7 +399,7 @@ void ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFo
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "xterm"))
detectXterm(terminalFont);
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "st"))
detectSt(terminalFont, terminal->pid);
detectSt(terminalFont, terminal);
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "warp"))
detectWarp(terminalFont);
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "weston-terminal"))
@@ -46,7 +46,7 @@ static void getProcessInformation(pid_t pid, FFstrbuf* processName, FFstrbuf* ex
ssize_t length = readlink(filePath, exePath->chars, exePath->allocated - 1);
if (length > 0) // doesn't contain trailing NUL
{
exePath->chars[length + 1] = '\0';
exePath->chars[length] = '\0';
exePath->length = (uint32_t) length;
}
@@ -307,10 +307,19 @@ static pid_t getTerminalInfo(FFTerminalResult* result, pid_t pid)
#ifdef __APPLE__
// https://github.com/fastfetch-cli/fastfetch/discussions/501
if (ffStrEndsWith(name, " (figterm)") || ffStrEndsWith(name, " (cwterm)"))
const char* pLeft = strstr(name, " (");
if (pLeft)
{
if (__builtin_expect(getProcessNameAndPpid(ppid, name, &ppid, NULL) != NULL, false))
return 0;
pLeft += 2;
const char* pRight = strstr(pLeft, "term)");
if (pRight && pRight[5] == '\0')
{
for (; pLeft < pRight; ++pLeft)
if (*pLeft < 'a' || *pLeft > 'z')
break;
if (pLeft == pRight && getProcessNameAndPpid(ppid, name, &ppid, NULL) != NULL)
return 0;
}
}
#endif
+1 -1
View File
@@ -8,7 +8,7 @@ void ffPrepareWeather(FFWeatherOptions* options)
{
if (status != FF_UNITIALIZED)
{
fputs("Error: this module can only be used once due to internal limitations\n", stderr);
fputs("Error: Weather module can only be used once due to internal limitations\n", stderr);
exit(1);
}
+56 -172
View File
@@ -317,7 +317,43 @@ static void listModules(bool pretty)
}
}
static void parseOption(FFdata* data, const char* key, const char* value);
// Temporary copy before new release of yyjson
static bool ffyyjson_locate_pos(const char *str, size_t len, size_t pos,
size_t *line, size_t *col, size_t *chr) {
size_t line_sum = 0, line_pos = 0, chr_sum = 0;
const uint8_t *cur = (const uint8_t *)str;
const uint8_t *end = cur + pos;
if (!str || pos > len) {
if (line) *line = 0;
if (col) *col = 0;
if (chr) *chr = 0;
return false;
}
while (cur < end) {
uint8_t c = *cur;
chr_sum += 1;
if (__builtin_expect(c < 0x80, true)) { /* 0xxxxxxx (0x00-0x7F) ASCII */
if (c == '\n') {
line_sum += 1;
line_pos = chr_sum;
}
cur += 1;
}
else if (c < 0xC0) cur += 1; /* 10xxxxxx (0x80-0xBF) Invalid */
else if (c < 0xE0) cur += 2; /* 110xxxxx (0xC0-0xDF) 2-byte UTF-8 */
else if (c < 0xF0) cur += 3; /* 1110xxxx (0xE0-0xEF) 3-byte UTF-8 */
else if (c < 0xF8) cur += 4; /* 11110xxx (0xF0-0xF7) 4-byte UTF-8 */
else cur += 1; /* 11111xxx (0xF8-0xFF) Invalid */
}
if (line) *line = line_sum + 1;
if (col) *col = chr_sum - line_pos + 1;
if (chr) *chr = chr_sum;
return true;
}
static bool parseJsoncFile(const char* path)
{
@@ -325,12 +361,16 @@ static bool parseJsoncFile(const char* path)
{
yyjson_read_err error;
instance.state.configDoc = yyjson_read_file(path, YYJSON_READ_ALLOW_COMMENTS | YYJSON_READ_ALLOW_TRAILING_COMMAS | YYJSON_READ_ALLOW_INF_AND_NAN, NULL, &error);
instance.state.configDoc = yyjson_read_file(path, YYJSON_READ_ALLOW_COMMENTS | YYJSON_READ_ALLOW_TRAILING_COMMAS, NULL, &error);
if (!instance.state.configDoc)
{
if (error.code != YYJSON_READ_ERROR_FILE_OPEN)
{
fprintf(stderr, "Error: failed to parse JSON config file `%s` at pos %zu: %s\n", path, error.pos, error.msg);
size_t row = 0, col = error.pos;
FF_STRBUF_AUTO_DESTROY content = ffStrbufCreate();
if (ffAppendFileBuffer(path, &content))
ffyyjson_locate_pos(content.chars, content.length, error.pos, &row, &col, NULL);
fprintf(stderr, "Error: failed to parse JSON config file `%s` at (%zu, %zu): %s\n", path, row, col, error.msg);
exit(477);
}
return false;
@@ -360,104 +400,6 @@ static bool parseJsoncFile(const char* path)
return true;
}
static bool parseConfigFile(FFdata* data, const char* path)
{
FF_AUTO_CLOSE_FILE FILE* file = fopen(path, "r");
if(file == NULL)
return false;
char* line = NULL;
size_t len = 0;
ssize_t read;
FF_STRBUF_AUTO_DESTROY unescaped = ffStrbufCreate();
while ((read = getline(&line, &len, file)) != -1)
{
char* lineStart = line;
char* lineEnd = line + read - 1;
//Trim line left
while(isspace(*lineStart))
++lineStart;
//Continue if line is empty or a comment
if(*lineStart == '\0' || *lineStart == '#')
continue;
//Trim line right
while(lineEnd > lineStart && isspace(*lineEnd))
--lineEnd;
*(lineEnd + 1) = '\0';
char* valueStart = strchr(lineStart, ' ');
//If the line has no white space, it is only a key
if(valueStart == NULL)
{
parseOption(data, lineStart, NULL);
continue;
}
//separate the key from the value
*valueStart = '\0';
++valueStart;
//Trim space of value left
while(isspace(*valueStart))
++valueStart;
//If we want whitespace in values, we need to quote it. This is done to keep consistency with shell.
if((*valueStart == '"' || *valueStart == '\'') && *valueStart == *lineEnd && lineEnd > valueStart)
{
++valueStart;
*lineEnd = '\0';
--lineEnd;
}
if (strchr(valueStart, '\\'))
{
// Unescape all `\x`s
const char* value = valueStart;
while(*value != '\0')
{
if(*value != '\\')
{
ffStrbufAppendC(&unescaped, *value);
++value;
continue;
}
++value;
switch(*value)
{
case 'n': ffStrbufAppendC(&unescaped, '\n'); break;
case 't': ffStrbufAppendC(&unescaped, '\t'); break;
case 'e': ffStrbufAppendC(&unescaped, '\e'); break;
case '\\': ffStrbufAppendC(&unescaped, '\\'); break;
default:
ffStrbufAppendC(&unescaped, '\\');
ffStrbufAppendC(&unescaped, *value);
break;
}
++value;
}
parseOption(data, lineStart, unescaped.chars);
ffStrbufClear(&unescaped);
}
else
{
parseOption(data, lineStart, valueStart);
}
}
if(line != NULL)
free(line);
return true;
}
static void generateConfigFile(bool force, const char* filePath)
{
if (!filePath)
@@ -467,11 +409,6 @@ static void generateConfigFile(bool force, const char* filePath)
}
else
{
if (ffStrEqualsIgnCase(filePath, "conf") || ffStrEqualsIgnCase(filePath, "jsonc"))
{
fputs("Error: specifying file type is no longer supported\n", stderr);
exit(477);
}
ffStrbufSetS(&instance.state.genConfigPath, filePath);
}
@@ -507,19 +444,15 @@ static void optionParseConfigFile(FFdata* data, const char* key, const char* val
if (ffStrEqualsIgnCase(value, "none"))
return;
bool isJsonConfig = fileNameLen > strlen(".jsonc") && strcasecmp(value + fileNameLen - strlen(".jsonc"), ".jsonc") == 0;
if (ffStrEndsWithIgnCase(value, ".conf"))
{
fprintf(stderr, "Error: flag based config files are no longer not supported: %s\n", value);
exit(414);
}
//Try to load as an absolute path
if(isJsonConfig ? parseJsoncFile(value) : parseConfigFile(data, value))
return;
{
bool success = isJsonConfig ? parseJsoncFile(value) : parseConfigFile(data, value);
if(success)
return;
}
if (parseJsoncFile(value)) return;
//Try to load as a relative path
@@ -531,15 +464,14 @@ static void optionParseConfigFile(FFdata* data, const char* key, const char* val
ffStrbufAppendS(&absolutePath, "fastfetch/presets/");
ffStrbufAppendS(&absolutePath, value);
bool success = isJsonConfig ? parseJsoncFile(absolutePath.chars) : parseConfigFile(data, absolutePath.chars);
bool success = parseJsoncFile(absolutePath.chars);
if (!success)
{
ffStrbufAppendS(&absolutePath, ".jsonc");
success = parseJsoncFile(absolutePath.chars);
}
if(success)
return;
if (success) return;
}
{
@@ -549,15 +481,14 @@ static void optionParseConfigFile(FFdata* data, const char* key, const char* val
ffStrbufAppendS(&absolutePath, "/presets/");
ffStrbufAppendS(&absolutePath, value);
bool success = isJsonConfig ? parseJsoncFile(absolutePath.chars) : parseConfigFile(data, absolutePath.chars);
bool success = parseJsoncFile(absolutePath.chars);
if (!success)
{
ffStrbufAppendS(&absolutePath, ".jsonc");
success = parseJsoncFile(absolutePath.chars);
}
if(success)
return;
if (success) return;
}
//File not found
@@ -695,38 +626,7 @@ static void parseCommand(FFdata* data, char* key, char* value)
static void parseOption(FFdata* data, const char* key, const char* value)
{
if(ffStrEqualsIgnCase(key, "--set") || ffStrEqualsIgnCase(key, "--set-keyless"))
{
FF_STRBUF_AUTO_DESTROY customValueStr = ffStrbufCreate();
ffOptionParseString(key, value, &customValueStr);
uint32_t index = ffStrbufFirstIndexC(&customValueStr, '=');
if(index == 0 || index == customValueStr.length)
{
fprintf(stderr, "Error: usage: %s <key>=<str>\n", key);
exit(477);
}
FF_STRBUF_AUTO_DESTROY customKey = ffStrbufCreateNS(index, customValueStr.chars);
FFCustomValue* customValue = NULL;
FF_LIST_FOR_EACH(FFCustomValue, x, data->customValues)
{
if(ffStrbufEqual(&x->key, &customKey))
{
ffStrbufDestroy(&x->key);
ffStrbufDestroy(&x->value);
customValue = x;
break;
}
}
if(!customValue) customValue = (FFCustomValue*) ffListAdd(&data->customValues);
ffStrbufInitMove(&customValue->key, &customKey);
ffStrbufSubstrAfter(&customValueStr, index);
ffStrbufInitMove(&customValue->value, &customValueStr);
customValue->printKey = key[5] == '\0';
}
else if(ffStrEqualsIgnCase(key, "-s") || ffStrEqualsIgnCase(key, "--structure"))
if(ffStrEqualsIgnCase(key, "-s") || ffStrEqualsIgnCase(key, "--structure"))
ffOptionParseString(key, value, &data->structure);
else if(
@@ -744,7 +644,7 @@ static void parseOption(FFdata* data, const char* key, const char* value)
}
}
static void parseConfigFiles(FFdata* data)
static void parseConfigFiles(void)
{
if (__builtin_expect(instance.state.genConfigPath.length == 0, true))
{
@@ -758,15 +658,6 @@ static void parseConfigFiles(FFdata* data)
if (success) return;
}
}
FF_LIST_FOR_EACH(FFstrbuf, dir, instance.state.platform.configDirs)
{
uint32_t dirLength = dir->length;
ffStrbufAppendS(dir, "fastfetch/config.conf");
bool success = parseConfigFile(data, dir->chars);
ffStrbufSubstrBefore(dir, dirLength);
if (success) return;
}
}
static void parseArguments(FFdata* data, int argc, char** argv, void (*parser)(FFdata* data, char* key, char* value))
@@ -868,13 +759,12 @@ int main(int argc, char** argv)
//Data stores things only needed for the configuration of fastfetch
FFdata data = {
.structure = ffStrbufCreate(),
.customValues = ffListCreate(sizeof(FFCustomValue)),
.configLoaded = false,
};
parseArguments(&data, argc, argv, parseCommand);
if(!data.configLoaded && !getenv("NO_CONFIG"))
parseConfigFiles(&data);
parseConfigFiles();
parseArguments(&data, argc, argv, (void*) parseOption);
if (__builtin_expect(instance.state.genConfigPath.length == 0, true))
@@ -883,10 +773,4 @@ int main(int argc, char** argv)
writeConfigFile(&data, &instance.state.genConfigPath);
ffStrbufDestroy(&data.structure);
FF_LIST_FOR_EACH(FFCustomValue, customValue, data.customValues)
{
ffStrbufDestroy(&customValue->key);
ffStrbufDestroy(&customValue->value);
}
ffListDestroy(&data.customValues);
}
+16
View File
@@ -0,0 +1,16 @@
${c1} -:+:.
${c1} :++++.
${c1} /+++/.
${c1} .:-::- .+/:-\`\`.::-
${c1} .:/++++++/::::/++++++/::`
${c2} .:///////////////////////::`
${c2} /////////////////////////`
${c3}+++++++++++++++++++++++++`
${c3}++++++++++++++++++++++++
${c4}ssssssssssssssssssssssss.
${c4}:ssssssssssssssssssssssss-
${c5} osssssssssssssssssssssssss`
${c5} `syyyyyyyyyyyyyyyyyyyyyyyyys`
${c6} `ossssssssssssssssssssssss
${c6} :ooooooooooooooooooo+.
${c6} `:++oo+/:- -:/+o+/-
+20
View File
@@ -0,0 +1,20 @@
_,......,_
_aaQQQQQQWQQQQQQQaa.
ajQQQ??^' '^??QQQw.
,aQQP^ ?4QQa
wQQP ^4QQa
,QQP' ,aaaaa. ^$Q6,
,QQP ajQQQWWWWQQQw. 4QQ
QQP aQQP? ?$QQ. 4Q6
jQQ jQQ' ?WQr 'QQb
QQf ]QQ' ]QQ QQ6
QQf ]QQ ]QQ) QQQ
QQ6 'QQ6 ]QQ QQf
]QQ. ^4QQaa .QQP ,QQ'
$QQ. ^?QQQQf _yQP ,QQP
^WQQ6. aQQ? _QQP
^4QQQ6a. ajQQP' aQQP
?QQQQQWQaaaaaaajQWQP? aQQP'
?QQQQP????????^' saWQP?
^?QQQgaaa._ __aaaQQQP?'
'^?QWQQQQQQQQ@??^'
+17
View File
@@ -0,0 +1,17 @@
$2 @=++++++++++=@
$2 =++++++++++++++++++=
$2 *++++++++++++++++++++++*
$2 =++++++++++++++++++++++++++=
$2 *++++++++$1-..........-$2++++++++*
$2 =++++++++$1..............$2++++++++=
$2@++++++++$1:.....$2:++$1:.....:$2++++++++@
$2=++++++++$1:.....$2++++$1.....:$2++++++++=
$2=++++++++$1:.....$2++++$1.....:$2++++++++=
$2#++++++++$1:.....$2++++$1.....:$2++++++++#
$2 +++++++++$1......$2--$1......$2+++++++++
$2 @++++++++$1:............:$2++++++++@
$2 @+++++++++++$1-....-$2+++++++++++@
$2 *++++++++++$1::::$2++++++++++*
$2 *++++++++++++++++++++*
$2 @*++++++++++++++*@
$2 @#====#@
+37 -3
View File
@@ -1115,9 +1115,9 @@ static const FFlogo C[] = {
};
static const FFlogo D[] = {
// Dahlia
// DahliaOS
{
.names = {"dahlia"},
.names = {"dahliaOS"},
.lines = FASTFETCH_DATATEXT_LOGO_DAHLIA,
.colors = {
FF_COLOR_FG_RED,
@@ -2461,6 +2461,21 @@ static const FFlogo M[] = {
.colorKeys = FF_COLOR_FG_YELLOW,
.colorTitle = FF_COLOR_FG_GREEN,
},
// MacOS3
{
.names = {"macos3", "mac3"},
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_MACOS3,
.colors = {
FF_COLOR_FG_GREEN,
FF_COLOR_FG_YELLOW,
FF_COLOR_FG_RED,
FF_COLOR_FG_MAGENTA,
FF_COLOR_FG_BLUE,
},
.colorKeys = FF_COLOR_FG_YELLOW,
.colorTitle = FF_COLOR_FG_GREEN,
},
// MainsailOS
{
.names = {"MainsailOS"},
@@ -3004,9 +3019,19 @@ static const FFlogo O[] = {
.colorKeys = FF_COLOR_FG_GREEN,
.colorTitle = FF_COLOR_FG_GREEN,
},
// openSUSESlowroll
{
.names = {"opensuse_slowroll", "opensuse-slowroll", "opensuse-tumbleweed-slowroll"},
.lines = FASTFETCH_DATATEXT_LOGO_OPENSUSE_SLOWROLL,
.colors = {
FF_COLOR_FG_WHITE,
},
.colorKeys = FF_COLOR_FG_GREEN,
.colorTitle = FF_COLOR_FG_GREEN,
},
// OpenMandriva
{
.names = {"openmandriva", "open-mandriva", "open_mandriva"},
.names = {"openmandriva", "open-mandriva", "open_mandriva", "openmandriva lx"},
.lines = FASTFETCH_DATATEXT_LOGO_OPENMANDRIVA,
.colors = {
FF_COLOR_FG_BLUE,
@@ -3442,6 +3467,15 @@ static const FFlogo Q[] = {
FF_COLOR_FG_WHITE,
},
},
// Quirinux
{
.names = {"Quirinux"},
.lines = FASTFETCH_DATATEXT_LOGO_QUIRINUX,
.colors = {
FF_COLOR_FG_WHITE,
FF_COLOR_FG_MAGENTA,
},
},
// LAST
{},
};
+9 -4
View File
@@ -84,9 +84,10 @@ static bool printImageIterm(bool printError)
ffStrbufAppendNC(&buf, options->paddingTop, '\n');
ffStrbufAppendNC(&buf, options->paddingLeft, ' ');
}
ffStrbufAppendF(&buf, "\e]1337;File=inline=1:%s\a",
base64.chars
);
if (options->width)
ffStrbufAppendF(&buf, "\e]1337;File=inline=1;width=%u:%s\a", (unsigned) options->width, base64.chars);
else
ffStrbufAppendF(&buf, "\e]1337;File=inline=1:%s\a", base64.chars);
ffWriteFDBuffer(FFUnixFD2NativeFD(STDOUT_FILENO), &buf);
if (!options->separate)
@@ -164,7 +165,11 @@ static bool printImageKittyDirect(bool printError)
ffPrintCharTimes('\n', options->paddingTop);
ffPrintCharTimes(' ', options->paddingLeft);
}
printf("\e_Ga=T,f=100,t=f;%s\e\\", base64.chars);
if (options->width)
printf("\e_Ga=T,f=100,t=f,c=%u;%s\e\\", (unsigned) options->width, base64.chars);
else
printf("\e_Ga=T,f=100,t=f;%s\e\\", base64.chars);
fflush(stdout);
if (!options->separate)
{
+12 -8
View File
@@ -436,7 +436,7 @@ static bool logoTryKnownType(void)
}
if(options->type == FF_LOGO_TYPE_BUILTIN)
return logoPrintBuiltinIfExists(&options->source, FF_LOGO_SIZE_NORMAL);
return logoPrintBuiltinIfExists(&options->source, FF_LOGO_SIZE_UNKNOWN);
if(options->type == FF_LOGO_TYPE_SMALL)
return logoPrintBuiltinIfExists(&options->source, FF_LOGO_SIZE_SMALL);
@@ -461,12 +461,6 @@ static bool logoTryKnownType(void)
return logoPrintImageIfExists(options->type, instance.config.display.showErrors);
}
static void logoPrintKnownType(void)
{
if(!logoTryKnownType())
logoPrintDetected(FF_LOGO_SIZE_UNKNOWN);
}
void ffLogoPrint(void)
{
//When generate JSON result, we don't have a logo or padding.
@@ -497,7 +491,17 @@ void ffLogoPrint(void)
//If the source and source type is set to something else than auto, always print with the set type.
if(options->source.length > 0 && options->type != FF_LOGO_TYPE_AUTO)
{
logoPrintKnownType();
if(!logoTryKnownType())
{
if (instance.config.display.showErrors)
{
// Image logo should have been handled
if(options->type == FF_LOGO_TYPE_BUILTIN || options->type == FF_LOGO_TYPE_SMALL)
fprintf(stderr, "Logo: Failed to load %s logo: %s \n", options->type == FF_LOGO_TYPE_BUILTIN ? "builtin" : "builtin small", options->source.chars);
}
logoPrintDetected(FF_LOGO_SIZE_UNKNOWN);
}
return;
}
+5 -5
View File
@@ -25,7 +25,7 @@ static void printBattery(FFBatteryOptions* options, FFBatteryResult* result, uin
{
if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_BAR_BIT)
{
ffPercentAppendBar(&str, result->capacity, options->percent);
ffPercentAppendBar(&str, result->capacity, options->percent, &options->moduleArgs);
}
if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_NUM_BIT)
@@ -33,7 +33,7 @@ static void printBattery(FFBatteryOptions* options, FFBatteryResult* result, uin
if(str.length > 0)
ffStrbufAppendC(&str, ' ');
ffPercentAppendNum(&str, result->capacity, options->percent, str.length > 0);
ffPercentAppendNum(&str, result->capacity, options->percent, str.length > 0, &options->moduleArgs);
}
}
@@ -50,7 +50,7 @@ static void printBattery(FFBatteryOptions* options, FFBatteryResult* result, uin
if(str.length > 0)
ffStrbufAppendS(&str, " - ");
ffTempsAppendNum(result->temperature, &str, options->tempConfig);
ffTempsAppendNum(result->temperature, &str, options->tempConfig, &options->moduleArgs);
}
ffStrbufPutTo(&str, stdout);
@@ -58,9 +58,9 @@ static void printBattery(FFBatteryOptions* options, FFBatteryResult* result, uin
else
{
FF_STRBUF_AUTO_DESTROY capacityStr = ffStrbufCreate();
ffPercentAppendNum(&capacityStr, result->capacity, options->percent, false);
ffPercentAppendNum(&capacityStr, result->capacity, options->percent, false, &options->moduleArgs);
FF_STRBUF_AUTO_DESTROY tempStr = ffStrbufCreate();
ffTempsAppendNum(result->temperature, &tempStr, options->tempConfig);
ffTempsAppendNum(result->temperature, &tempStr, options->tempConfig, &options->moduleArgs);
FF_PRINT_FORMAT_CHECKED(FF_BATTERY_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_BATTERY_NUM_FORMAT_ARGS, ((FFformatarg[]) {
{FF_FORMAT_ARG_TYPE_STRBUF, &result->manufacturer},
{FF_FORMAT_ARG_TYPE_STRBUF, &result->modelName},
+2 -2
View File
@@ -19,7 +19,7 @@ static void printDevice(FFBluetoothOptions* options, const FFBluetoothResult* de
{
if (buffer.length)
ffStrbufAppendC(&buffer, ' ');
ffPercentAppendNum(&buffer, device->battery, options->percent, buffer.length > 0);
ffPercentAppendNum(&buffer, device->battery, options->percent, buffer.length > 0, &options->moduleArgs);
}
if (!device->connected)
@@ -30,7 +30,7 @@ static void printDevice(FFBluetoothOptions* options, const FFBluetoothResult* de
else
{
FF_STRBUF_AUTO_DESTROY percentageStr = ffStrbufCreate();
ffPercentAppendNum(&percentageStr, device->battery, options->percent, false);
ffPercentAppendNum(&percentageStr, device->battery, options->percent, false, &options->moduleArgs);
FF_PRINT_FORMAT_CHECKED(FF_BLUETOOTH_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_BLUETOOTH_NUM_FORMAT_ARGS, ((FFformatarg[]) {
{FF_FORMAT_ARG_TYPE_STRBUF, &device->name},
+3 -3
View File
@@ -52,7 +52,7 @@ void ffPrintBrightness(FFBrightnessOptions* options)
if (instance.config.display.percentType & FF_PERCENTAGE_TYPE_BAR_BIT)
{
ffPercentAppendBar(&str, percent, options->percent);
ffPercentAppendBar(&str, percent, options->percent, &options->moduleArgs);
}
if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_NUM_BIT)
@@ -60,7 +60,7 @@ void ffPrintBrightness(FFBrightnessOptions* options)
if(str.length > 0)
ffStrbufAppendC(&str, ' ');
ffPercentAppendNum(&str, percent, options->percent, str.length > 0);
ffPercentAppendNum(&str, percent, options->percent, str.length > 0, &options->moduleArgs);
}
ffStrbufPutTo(&str, stdout);
@@ -68,7 +68,7 @@ void ffPrintBrightness(FFBrightnessOptions* options)
else
{
FF_STRBUF_AUTO_DESTROY valueStr = ffStrbufCreate();
ffPercentAppendNum(&valueStr, percent, options->percent, false);
ffPercentAppendNum(&valueStr, percent, options->percent, false, &options->moduleArgs);
FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_BRIGHTNESS_NUM_FORMAT_ARGS, ((FFformatarg[]) {
{FF_FORMAT_ARG_TYPE_STRBUF, &valueStr},
{FF_FORMAT_ARG_TYPE_STRBUF, &item->name},
+2 -2
View File
@@ -57,7 +57,7 @@ void ffPrintCPU(FFCPUOptions* options)
if(cpu.temperature == cpu.temperature) //FF_CPU_TEMP_UNSET
{
ffStrbufAppendS(&str, " - ");
ffTempsAppendNum(cpu.temperature, &str, options->tempConfig);
ffTempsAppendNum(cpu.temperature, &str, options->tempConfig, &options->moduleArgs);
}
ffStrbufPutTo(&str, stdout);
@@ -65,7 +65,7 @@ void ffPrintCPU(FFCPUOptions* options)
else
{
FF_STRBUF_AUTO_DESTROY tempStr = ffStrbufCreate();
ffTempsAppendNum(cpu.temperature, &tempStr, options->tempConfig);
ffTempsAppendNum(cpu.temperature, &tempStr, options->tempConfig, &options->moduleArgs);
FF_PRINT_FORMAT_CHECKED(FF_CPU_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_CPU_NUM_FORMAT_ARGS, ((FFformatarg[]){
{FF_FORMAT_ARG_TYPE_STRBUF, &cpu.name},
{FF_FORMAT_ARG_TYPE_STRBUF, &cpu.vendor},
+6 -6
View File
@@ -52,12 +52,12 @@ void ffPrintCPUUsage(FFCPUUsageOptions* options)
if (!options->separate)
{
if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_BAR_BIT)
ffPercentAppendBar(&str, avgValue, options->percent);
ffPercentAppendBar(&str, avgValue, options->percent, &options->moduleArgs);
if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_NUM_BIT)
{
if(str.length > 0)
ffStrbufAppendC(&str, ' ');
ffPercentAppendNum(&str, avgValue, options->percent, str.length > 0);
ffPercentAppendNum(&str, avgValue, options->percent, str.length > 0, &options->moduleArgs);
}
}
else
@@ -66,7 +66,7 @@ void ffPrintCPUUsage(FFCPUUsageOptions* options)
{
if(str.length > 0)
ffStrbufAppendC(&str, ' ');
ffPercentAppendNum(&str, *percent, options->percent, false);
ffPercentAppendNum(&str, *percent, options->percent, false, &options->moduleArgs);
}
}
ffStrbufPutTo(&str, stdout);
@@ -74,11 +74,11 @@ void ffPrintCPUUsage(FFCPUUsageOptions* options)
else
{
FF_STRBUF_AUTO_DESTROY avgStr = ffStrbufCreate();
ffPercentAppendNum(&avgStr, avgValue, options->percent, false);
ffPercentAppendNum(&avgStr, avgValue, options->percent, false, &options->moduleArgs);
FF_STRBUF_AUTO_DESTROY minStr = ffStrbufCreate();
ffPercentAppendNum(&minStr, minValue, options->percent, false);
ffPercentAppendNum(&minStr, minValue, options->percent, false, &options->moduleArgs);
FF_STRBUF_AUTO_DESTROY maxStr = ffStrbufCreate();
ffPercentAppendNum(&maxStr, maxValue, options->percent, false);
ffPercentAppendNum(&maxStr, maxValue, options->percent, false, &options->moduleArgs);
FF_PRINT_FORMAT_CHECKED(FF_CPUUSAGE_DISPLAY_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_CPUUSAGE_NUM_FORMAT_ARGS, ((FFformatarg[]){
{FF_FORMAT_ARG_TYPE_STRBUF, &avgStr},
{FF_FORMAT_ARG_TYPE_STRBUF, &maxStr},
+4 -4
View File
@@ -60,7 +60,7 @@ static void printDisk(FFDiskOptions* options, const FFDisk* disk)
{
if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_BAR_BIT)
{
ffPercentAppendBar(&str, bytesPercentage, options->percent);
ffPercentAppendBar(&str, bytesPercentage, options->percent, &options->moduleArgs);
ffStrbufAppendC(&str, ' ');
}
@@ -69,7 +69,7 @@ static void printDisk(FFDiskOptions* options, const FFDisk* disk)
if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_NUM_BIT)
{
ffPercentAppendNum(&str, bytesPercentage, options->percent, str.length > 0);
ffPercentAppendNum(&str, bytesPercentage, options->percent, str.length > 0, &options->moduleArgs);
ffStrbufAppendC(&str, ' ');
}
}
@@ -105,10 +105,10 @@ static void printDisk(FFDiskOptions* options, const FFDisk* disk)
else
{
FF_STRBUF_AUTO_DESTROY bytesPercentageStr = ffStrbufCreate();
ffPercentAppendNum(&bytesPercentageStr, bytesPercentage, options->percent, false);
ffPercentAppendNum(&bytesPercentageStr, bytesPercentage, options->percent, false, &options->moduleArgs);
FF_STRBUF_AUTO_DESTROY filesPercentageStr = ffStrbufCreate();
double filesPercentage = disk->filesTotal > 0 ? ((double) disk->filesUsed / (double) disk->filesTotal) * 100.0 : 0;
ffPercentAppendNum(&filesPercentageStr, filesPercentage, options->percent, false);
ffPercentAppendNum(&filesPercentageStr, filesPercentage, options->percent, false, &options->moduleArgs);
bool isExternal = !!(disk->type & FF_DISK_VOLUME_TYPE_EXTERNAL_BIT);
bool isHidden = !!(disk->type & FF_DISK_VOLUME_TYPE_HIDDEN_BIT);
+2 -2
View File
@@ -19,14 +19,14 @@ static void printDevice(FFGamepadOptions* options, const FFGamepadDevice* device
{
if (buffer.length)
ffStrbufAppendC(&buffer, ' ');
ffPercentAppendNum(&buffer, device->battery, options->percent, buffer.length > 0);
ffPercentAppendNum(&buffer, device->battery, options->percent, buffer.length > 0, &options->moduleArgs);
}
ffStrbufPutTo(&buffer, stdout);
}
else
{
FF_STRBUF_AUTO_DESTROY percentageStr = ffStrbufCreate();
ffPercentAppendNum(&percentageStr, device->battery, options->percent, false);
ffPercentAppendNum(&percentageStr, device->battery, options->percent, false, &options->moduleArgs);
FF_PRINT_FORMAT_CHECKED(FF_GAMEPAD_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_GAMEPAD_NUM_FORMAT_ARGS, ((FFformatarg[]) {
{FF_FORMAT_ARG_TYPE_STRBUF, &device->name},
+3 -3
View File
@@ -45,7 +45,7 @@ static void printGPUResult(FFGPUOptions* options, uint8_t index, const FFGPUResu
if(gpu->temperature == gpu->temperature) //FF_GPU_TEMP_UNSET
{
ffStrbufAppendS(&output, " - ");
ffTempsAppendNum(gpu->temperature, &output, options->tempConfig);
ffTempsAppendNum(gpu->temperature, &output, options->tempConfig, &options->moduleArgs);
}
if(gpu->dedicated.total != FF_GPU_VMEM_SIZE_UNSET && gpu->dedicated.total != 0)
@@ -61,7 +61,7 @@ static void printGPUResult(FFGPUOptions* options, uint8_t index, const FFGPUResu
if(gpu->dedicated.used != FF_GPU_VMEM_SIZE_UNSET)
{
ffStrbufAppendS(&output, ", ");
ffPercentAppendNum(&output, (double) gpu->dedicated.used / (double) gpu->dedicated.total * 100.0, options->percent, false);
ffPercentAppendNum(&output, (double) gpu->dedicated.used / (double) gpu->dedicated.total * 100.0, options->percent, false, &options->moduleArgs);
}
ffStrbufAppendC(&output, ')');
}
@@ -74,7 +74,7 @@ static void printGPUResult(FFGPUOptions* options, uint8_t index, const FFGPUResu
else
{
FF_STRBUF_AUTO_DESTROY tempStr = ffStrbufCreate();
ffTempsAppendNum(gpu->temperature, &tempStr, options->tempConfig);
ffTempsAppendNum(gpu->temperature, &tempStr, options->tempConfig, &options->moduleArgs);
FF_PRINT_FORMAT_CHECKED(FF_GPU_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_GPU_NUM_FORMAT_ARGS, ((FFformatarg[]) {
{FF_FORMAT_ARG_TYPE_STRBUF, &gpu->vendor},
{FF_FORMAT_ARG_TYPE_STRBUF, &gpu->name},
+2 -2
View File
@@ -11,7 +11,7 @@ void ffPrintKernel(FFKernelOptions* options)
if(options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(FF_KERNEL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
ffStrbufWriteTo(&platform->systemRelease, stdout);
printf("%s %s", platform->systemName.chars, platform->systemRelease.chars);
if(platform->systemDisplayVersion.length > 0)
printf(" (%s)\n", platform->systemDisplayVersion.chars);
@@ -77,7 +77,7 @@ void ffGenerateKernelJsonResult(FF_MAYBE_UNUSED FFKernelOptions* options, yyjson
void ffPrintKernelHelpFormat(void)
{
FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_KERNEL_MODULE_NAME, "{2}", FF_KERNEL_NUM_FORMAT_ARGS, ((const char* []) {
FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_KERNEL_MODULE_NAME, "{1} {2}", FF_KERNEL_NUM_FORMAT_ARGS, ((const char* []) {
"Sysname",
"Release",
"Version",
+131
View File
@@ -0,0 +1,131 @@
#include "common/printing.h"
#include "common/jsonconfig.h"
#include "detection/loadavg/loadavg.h"
#include "modules/loadavg/loadavg.h"
#include "util/stringUtils.h"
#define FF_LOADAVG_NUM_FORMAT_ARGS 3
void ffPrintLoadavg(FFLoadavgOptions* options)
{
double result[3] = { 0.0 / 0.0, 0.0 / 0.0, 0.0 / 0.0 };
const char* error = ffDetectLoadavg(result);
if(error)
{
ffPrintError(FF_LOADAVG_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", error);
return;
}
if(options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(FF_LOADAVG_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
printf("%.*f, %.*f, %.*f\n", options->ndigits, result[0], options->ndigits, result[1], options->ndigits, result[2]);
}
else
{
FF_PRINT_FORMAT_CHECKED(FF_LOADAVG_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_LOADAVG_NUM_FORMAT_ARGS, ((FFformatarg[]){
{FF_FORMAT_ARG_TYPE_DOUBLE, &result[0]},
{FF_FORMAT_ARG_TYPE_DOUBLE, &result[1]},
{FF_FORMAT_ARG_TYPE_DOUBLE, &result[2]},
}));
}
}
bool ffParseLoadavgCommandOptions(FFLoadavgOptions* options, const char* key, const char* value)
{
const char* subKey = ffOptionTestPrefix(key, FF_LOADAVG_MODULE_NAME);
if (!subKey) return false;
if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs))
return true;
if (ffStrEqualsIgnCase(subKey, "ndigits"))
{
options->ndigits = (uint8_t) ffOptionParseUInt32(key, value);
return true;
}
return false;
}
void ffParseLoadavgJsonObject(FFLoadavgOptions* options, yyjson_val* module)
{
yyjson_val *key_, *val;
size_t idx, max;
yyjson_obj_foreach(module, idx, max, key_, val)
{
const char* key = yyjson_get_str(key_);
if(ffStrEqualsIgnCase(key, "type"))
continue;
if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs))
continue;
if (ffStrEqualsIgnCase(key, "ndigits"))
{
options->ndigits = (uint8_t) yyjson_get_uint(val);
continue;
}
ffPrintError(FF_LOADAVG_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Unknown JSON key %s", key);
}
}
void ffGenerateLoadavgJsonConfig(FFLoadavgOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
__attribute__((__cleanup__(ffDestroyLoadavgOptions))) FFLoadavgOptions defaultOptions;
ffInitLoadavgOptions(&defaultOptions);
ffJsonConfigGenerateModuleArgsConfig(doc, module, &defaultOptions.moduleArgs, &options->moduleArgs);
if (defaultOptions.ndigits != options->ndigits)
yyjson_mut_obj_add_uint(doc, module, "ndigits", options->ndigits);
}
void ffGenerateLoadavgJsonResult(FF_MAYBE_UNUSED FFLoadavgOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
double result[3] = { 0.0 / 0.0, 0.0 / 0.0, 0.0 / 0.0 };
const char* error = ffDetectLoadavg(result);
if(error)
{
yyjson_mut_obj_add_str(doc, module, "error", error);
return;
}
yyjson_mut_val* arr = yyjson_mut_obj_add_arr(doc, module, "result");
for (size_t i = 0; i < 3; i++)
yyjson_mut_arr_add_real(doc, arr, result[i]);
}
void ffPrintLoadavgHelpFormat(void)
{
FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_LOADAVG_MODULE_NAME, "{1}, {2}, {3}", FF_LOADAVG_NUM_FORMAT_ARGS, ((const char* []) {
"Load average over 1min",
"Load average over 5min",
"Load average over 15min",
}));
}
void ffInitLoadavgOptions(FFLoadavgOptions* options)
{
ffOptionInitModuleBaseInfo(
&options->moduleInfo,
FF_LOADAVG_MODULE_NAME,
"Print system load averages",
ffParseLoadavgCommandOptions,
ffParseLoadavgJsonObject,
ffPrintLoadavg,
ffGenerateLoadavgJsonResult,
ffPrintLoadavgHelpFormat,
ffGenerateLoadavgJsonConfig
);
ffOptionInitModuleArg(&options->moduleArgs);
options->ndigits = 2;
}
void ffDestroyLoadavgOptions(FFLoadavgOptions* options)
{
ffOptionDestroyModuleArg(&options->moduleArgs);
}
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#include "fastfetch.h"
#define FF_LOADAVG_MODULE_NAME "Loadavg"
void ffPrintLoadavg(FFLoadavgOptions* options);
void ffInitLoadavgOptions(FFLoadavgOptions* options);
void ffDestroyLoadavgOptions(FFLoadavgOptions* options);
+13
View File
@@ -0,0 +1,13 @@
#pragma once
// This file will be included in "fastfetch.h", do NOT put unnecessary things here
#include "common/option.h"
typedef struct FFLoadavgOptions
{
FFModuleBaseInfo moduleInfo;
FFModuleArgs moduleArgs;
uint8_t ndigits;
} FFLoadavgOptions;
+42 -18
View File
@@ -192,15 +192,27 @@ bool ffParseLocalIpCommandOptions(FFLocalIpOptions* options, const char* key, co
return true;
}
if (ffStrEqualsIgnCase(subKey, "name-prefix"))
if (ffStrEqualsIgnCase(subKey, "default-route-only"))
{
ffOptionParseString(key, value, &options->namePrefix);
if (ffOptionParseBoolean(value))
options->showType |= FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT;
else
options->showType &= ~FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT;
return true;
}
if (ffStrEqualsIgnCase(subKey, "default-route-only"))
if (ffStrEqualsIgnCase(subKey, "show-all-ips"))
{
options->defaultRouteOnly = ffOptionParseBoolean(value);
if (ffOptionParseBoolean(value))
options->showType |= FF_LOCALIP_TYPE_ALL_IPS_BIT;
else
options->showType &= ~FF_LOCALIP_TYPE_ALL_IPS_BIT;
return true;
}
if (ffStrEqualsIgnCase(subKey, "name-prefix"))
{
ffOptionParseString(key, value, &options->namePrefix);
return true;
}
@@ -274,15 +286,27 @@ void ffParseLocalIpJsonObject(FFLocalIpOptions* options, yyjson_val* module)
continue;
}
if (ffStrEqualsIgnCase(key, "namePrefix"))
if (ffStrEqualsIgnCase(key, "defaultRouteOnly"))
{
ffStrbufSetS(&options->namePrefix, yyjson_get_str(val));
if (yyjson_get_bool(val))
options->showType |= FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT;
else
options->showType &= ~FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT;
continue;
}
if (ffStrEqualsIgnCase(key, "defaultRouteOnly"))
if (ffStrEqualsIgnCase(key, "showAllIps"))
{
options->defaultRouteOnly = yyjson_get_bool(val);
if (yyjson_get_bool(val))
options->showType |= FF_LOCALIP_TYPE_ALL_IPS_BIT;
else
options->showType &= ~FF_LOCALIP_TYPE_ALL_IPS_BIT;
continue;
}
if (ffStrEqualsIgnCase(key, "namePrefix"))
{
ffStrbufSetS(&options->namePrefix, yyjson_get_str(val));
continue;
}
@@ -316,13 +340,16 @@ void ffGenerateLocalIpJsonConfig(FFLocalIpOptions* options, yyjson_mut_doc* doc,
if (options->showType & FF_LOCALIP_TYPE_COMPACT_BIT)
yyjson_mut_obj_add_bool(doc, module, "compact", true);
if (options->showType & FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT)
yyjson_mut_obj_add_bool(doc, module, "defaultRouteOnly", true);
if (options->showType & FF_LOCALIP_TYPE_ALL_IPS_BIT)
yyjson_mut_obj_add_bool(doc, module, "showAllIps", true);
}
if (!ffStrbufEqual(&options->namePrefix, &defaultOptions.namePrefix))
yyjson_mut_obj_add_strbuf(doc, module, "namePrefix", &options->namePrefix);
if (options->defaultRouteOnly != defaultOptions.defaultRouteOnly)
yyjson_mut_obj_add_bool(doc, module, "defaultRouteOnly", options->defaultRouteOnly);
}
void ffGenerateLocalIpJsonResult(FF_MAYBE_UNUSED FFLocalIpOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
@@ -383,15 +410,12 @@ void ffInitLocalIpOptions(FFLocalIpOptions* options)
);
ffOptionInitModuleArg(&options->moduleArgs);
options->showType = FF_LOCALIP_TYPE_IPV4_BIT | FF_LOCALIP_TYPE_PREFIX_LEN_BIT;
ffStrbufInit(&options->namePrefix);
options->defaultRouteOnly =
#ifdef __ANDROID__
false
#else
true
options->showType = FF_LOCALIP_TYPE_IPV4_BIT | FF_LOCALIP_TYPE_PREFIX_LEN_BIT
#ifndef __ANDROID__
| FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT
#endif
;
ffStrbufInit(&options->namePrefix);
}
void ffDestroyLocalIpOptions(FFLocalIpOptions* options)
+3 -2
View File
@@ -13,7 +13,9 @@ typedef enum FFLocalIpType
FF_LOCALIP_TYPE_MAC_BIT = 1 << 3,
FF_LOCALIP_TYPE_PREFIX_LEN_BIT = 1 << 4,
FF_LOCALIP_TYPE_COMPACT_BIT = 1 << 10,
FF_LOCALIP_TYPE_COMPACT_BIT = 1 << 10,
FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT = 1 << 11,
FF_LOCALIP_TYPE_ALL_IPS_BIT = 1 << 12,
} FFLocalIpType;
typedef struct FFLocalIpOptions
@@ -23,5 +25,4 @@ typedef struct FFLocalIpOptions
FFLocalIpType showType;
FFstrbuf namePrefix;
bool defaultRouteOnly;
} FFLocalIpOptions;
+3 -3
View File
@@ -40,7 +40,7 @@ void ffPrintMemory(FFMemoryOptions* options)
if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_BAR_BIT)
{
ffPercentAppendBar(&str, percentage, options->percent);
ffPercentAppendBar(&str, percentage, options->percent, &options->moduleArgs);
ffStrbufAppendC(&str, ' ');
}
@@ -48,7 +48,7 @@ void ffPrintMemory(FFMemoryOptions* options)
ffStrbufAppendF(&str, "%s / %s ", usedPretty.chars, totalPretty.chars);
if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_NUM_BIT)
ffPercentAppendNum(&str, percentage, options->percent, str.length > 0);
ffPercentAppendNum(&str, percentage, options->percent, str.length > 0, &options->moduleArgs);
ffStrbufTrimRight(&str, ' ');
ffStrbufPutTo(&str, stdout);
@@ -57,7 +57,7 @@ void ffPrintMemory(FFMemoryOptions* options)
else
{
FF_STRBUF_AUTO_DESTROY percentageStr = ffStrbufCreate();
ffPercentAppendNum(&percentageStr, percentage, options->percent, false);
ffPercentAppendNum(&percentageStr, percentage, options->percent, false, &options->moduleArgs);
FF_PRINT_FORMAT_CHECKED(FF_MEMORY_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_MEMORY_NUM_FORMAT_ARGS, ((FFformatarg[]){
{FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty},
{FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty},
+2
View File
@@ -28,6 +28,7 @@
#include "modules/icons/icons.h"
#include "modules/kernel/kernel.h"
#include "modules/lm/lm.h"
#include "modules/loadavg/loadavg.h"
#include "modules/locale/locale.h"
#include "modules/localip/localip.h"
#include "modules/media/media.h"
@@ -39,6 +40,7 @@
#include "modules/os/os.h"
#include "modules/packages/packages.h"
#include "modules/physicaldisk/physicaldisk.h"
#include "modules/physicalmemory/physicalmemory.h"
#include "modules/player/player.h"
#include "modules/poweradapter/poweradapter.h"
#include "modules/processes/processes.h"
+2
View File
@@ -27,6 +27,7 @@
#include "modules/gpu/option.h"
#include "modules/icons/option.h"
#include "modules/kernel/option.h"
#include "modules/loadavg/option.h"
#include "modules/locale/option.h"
#include "modules/lm/option.h"
#include "modules/localip/option.h"
@@ -39,6 +40,7 @@
#include "modules/os/option.h"
#include "modules/packages/option.h"
#include "modules/physicaldisk/option.h"
#include "modules/physicalmemory/option.h"
#include "modules/player/option.h"
#include "modules/poweradapter/option.h"
#include "modules/processes/option.h"
+2 -2
View File
@@ -97,14 +97,14 @@ void ffPrintPhysicalDisk(FFPhysicalDiskOptions* options)
if(buffer.length > 0)
ffStrbufAppendS(&buffer, " - ");
ffTempsAppendNum(dev->temperature, &buffer, options->tempConfig);
ffTempsAppendNum(dev->temperature, &buffer, options->tempConfig, &options->moduleArgs);
}
ffStrbufPutTo(&buffer, stdout);
}
else
{
FF_STRBUF_AUTO_DESTROY tempStr = ffStrbufCreate();
ffTempsAppendNum(dev->temperature, &tempStr, options->tempConfig);
ffTempsAppendNum(dev->temperature, &tempStr, options->tempConfig, &options->moduleArgs);
if (dev->type & FF_PHYSICALDISK_TYPE_READWRITE)
readOnlyType = "Read-write";
FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_PHYSICALDISK_NUM_FORMAT_ARGS, ((FFformatarg[]){
+12
View File
@@ -0,0 +1,12 @@
#pragma once
// This file will be included in "fastfetch.h", do NOT put unnecessary things here
#include "common/option.h"
#include "common/percent.h"
typedef struct FFPhysicalMemoryOptions
{
FFModuleBaseInfo moduleInfo;
FFModuleArgs moduleArgs;
} FFPhysicalMemoryOptions;
+192
View File
@@ -0,0 +1,192 @@
#include "common/printing.h"
#include "common/jsonconfig.h"
#include "common/parsing.h"
#include "common/percent.h"
#include "detection/physicalmemory/physicalmemory.h"
#include "modules/physicalmemory/physicalmemory.h"
#include "util/stringUtils.h"
#define FF_PHYSICALMEMORY_NUM_FORMAT_ARGS 11
#define FF_PHYSICALMEMORY_DISPLAY_NAME "Physical Memory"
void ffPrintPhysicalMemory(FFPhysicalMemoryOptions* options)
{
FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFPhysicalMemoryResult));
const char* error = ffDetectPhysicalMemory(&result);
if(error)
{
ffPrintError(FF_PHYSICALMEMORY_DISPLAY_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", error);
return;
}
FF_STRBUF_AUTO_DESTROY prettySize = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
uint32_t i = 0;
FF_LIST_FOR_EACH(FFPhysicalMemoryResult, device, result)
{
++i;
ffStrbufClear(&prettySize);
ffParseSize(device->size, &prettySize);
if (options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(
FF_PHYSICALMEMORY_DISPLAY_NAME,
result.length == 1 ? 0 : (uint8_t) i,
&options->moduleArgs,
FF_PRINT_TYPE_DEFAULT);
fputs(prettySize.chars, stdout);
fputs(" - ", stdout);
ffStrbufWriteTo(&device->type, stdout);
if (device->maxSpeed > 0)
printf("-%u", device->maxSpeed);
if (device->runningSpeed > 0 && device->runningSpeed != device->maxSpeed)
printf(" @ %u MT/s", device->runningSpeed);
if (device->vendor.length > 0)
printf(" (%s)", device->vendor.chars);
if (device->ecc)
fputs(" - ECC", stdout);
putchar('\n');
}
else
{
FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_PHYSICALMEMORY_NUM_FORMAT_ARGS, ((FFformatarg[]) {
{FF_FORMAT_ARG_TYPE_UINT64, &device->size},
{FF_FORMAT_ARG_TYPE_STRBUF, &prettySize},
{FF_FORMAT_ARG_TYPE_UINT, &device->maxSpeed},
{FF_FORMAT_ARG_TYPE_UINT, &device->runningSpeed},
{FF_FORMAT_ARG_TYPE_STRBUF, &device->type},
{FF_FORMAT_ARG_TYPE_STRBUF, &device->formFactor},
{FF_FORMAT_ARG_TYPE_DOUBLE, &device->locator},
{FF_FORMAT_ARG_TYPE_STRBUF, &device->vendor},
{FF_FORMAT_ARG_TYPE_STRBUF, &device->serial},
{FF_FORMAT_ARG_TYPE_STRBUF, &device->partNumber},
{FF_FORMAT_ARG_TYPE_BOOL, &device->ecc},
}));
}
}
FF_LIST_FOR_EACH(FFPhysicalMemoryResult, device, result)
{
ffStrbufDestroy(&device->type);
ffStrbufDestroy(&device->locator);
ffStrbufDestroy(&device->formFactor);
ffStrbufDestroy(&device->vendor);
ffStrbufDestroy(&device->serial);
ffStrbufDestroy(&device->partNumber);
}
}
bool ffParsePhysicalMemoryCommandOptions(FFPhysicalMemoryOptions* options, const char* key, const char* value)
{
const char* subKey = ffOptionTestPrefix(key, FF_PHYSICALMEMORY_MODULE_NAME);
if (!subKey) return false;
if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs))
return true;
return false;
}
void ffParsePhysicalMemoryJsonObject(FFPhysicalMemoryOptions* options, yyjson_val* module)
{
yyjson_val *key_, *val;
size_t idx, max;
yyjson_obj_foreach(module, idx, max, key_, val)
{
const char* key = yyjson_get_str(key_);
if(ffStrEqualsIgnCase(key, "type"))
continue;
if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs))
continue;
ffPrintError(FF_PHYSICALMEMORY_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Unknown JSON key %s", key);
}
}
void ffGeneratePhysicalMemoryJsonConfig(FFPhysicalMemoryOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
__attribute__((__cleanup__(ffDestroyPhysicalMemoryOptions))) FFPhysicalMemoryOptions defaultOptions;
ffInitPhysicalMemoryOptions(&defaultOptions);
ffJsonConfigGenerateModuleArgsConfig(doc, module, &defaultOptions.moduleArgs, &options->moduleArgs);
}
void ffGeneratePhysicalMemoryJsonResult(FF_MAYBE_UNUSED FFPhysicalMemoryOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFPhysicalMemoryResult));
const char* error = ffDetectPhysicalMemory(&result);
if(error)
{
yyjson_mut_obj_add_str(doc, module, "error", error);
return;
}
yyjson_mut_val* arr = yyjson_mut_obj_add_arr(doc, module, "result");
FF_LIST_FOR_EACH(FFPhysicalMemoryResult, device, result)
{
yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr);
yyjson_mut_obj_add_uint(doc, obj, "size", device->size);
yyjson_mut_obj_add_uint(doc, obj, "maxSpeed", device->maxSpeed);
yyjson_mut_obj_add_uint(doc, obj, "runningSpeed", device->runningSpeed);
yyjson_mut_obj_add_strbuf(doc, obj, "type", &device->type);
yyjson_mut_obj_add_strbuf(doc, obj, "locator", &device->locator);
yyjson_mut_obj_add_strbuf(doc, obj, "formFactor", &device->formFactor);
yyjson_mut_obj_add_strbuf(doc, obj, "vendor", &device->vendor);
yyjson_mut_obj_add_strbuf(doc, obj, "serial", &device->serial);
yyjson_mut_obj_add_strbuf(doc, obj, "partNumber", &device->partNumber);
yyjson_mut_obj_add_bool(doc, obj, "ecc", device->ecc);
}
FF_LIST_FOR_EACH(FFPhysicalMemoryResult, device, result)
{
ffStrbufDestroy(&device->type);
ffStrbufDestroy(&device->locator);
ffStrbufDestroy(&device->formFactor);
ffStrbufDestroy(&device->vendor);
ffStrbufDestroy(&device->serial);
ffStrbufDestroy(&device->partNumber);
}
}
void ffPrintPhysicalMemoryHelpFormat(void)
{
FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_PHYSICALMEMORY_MODULE_NAME, "{7} {5}-{3}: {2}, running at {4} MT/s", FF_PHYSICALMEMORY_NUM_FORMAT_ARGS, ((const char* []) {
"Size (in bytes)",
"Size formatted",
"Max speed (in MT/s)",
"Running speed (in MT/s)",
"Type (DDR4, DDR5, etc.)",
"Form factor (SODIMM, DIMM, etc.)",
"Bank/Device Locator (BANK0/SIMM0, BANK0/SIMM1, etc.)",
"Vendor",
"Serial number",
"Part number",
"ECC enabled",
}));
}
void ffInitPhysicalMemoryOptions(FFPhysicalMemoryOptions* options)
{
ffOptionInitModuleBaseInfo(
&options->moduleInfo,
FF_PHYSICALMEMORY_MODULE_NAME,
"Print system physical memory devices",
ffParsePhysicalMemoryCommandOptions,
ffParsePhysicalMemoryJsonObject,
ffPrintPhysicalMemory,
ffGeneratePhysicalMemoryJsonResult,
ffPrintPhysicalMemoryHelpFormat,
ffGeneratePhysicalMemoryJsonConfig
);
ffOptionInitModuleArg(&options->moduleArgs);
}
void ffDestroyPhysicalMemoryOptions(FFPhysicalMemoryOptions* options)
{
ffOptionDestroyModuleArg(&options->moduleArgs);
}
@@ -0,0 +1,9 @@
#pragma once
#include "fastfetch.h"
#define FF_PHYSICALMEMORY_MODULE_NAME "PhysicalMemory"
void ffPrintPhysicalMemory(FFPhysicalMemoryOptions* options);
void ffInitPhysicalMemoryOptions(FFPhysicalMemoryOptions* options);
void ffDestroyPhysicalMemoryOptions(FFPhysicalMemoryOptions* options);
+1
View File
@@ -11,4 +11,5 @@ typedef struct FFPublicIpOptions
FFstrbuf url;
uint32_t timeout;
bool ipv6;
} FFPublicIpOptions;
+19
View File
@@ -59,6 +59,12 @@ bool ffParsePublicIpCommandOptions(FFPublicIpOptions* options, const char* key,
return true;
}
if (ffStrEqualsIgnCase(subKey, "ipv6"))
{
options->ipv6 = ffOptionParseBoolean(value);
return true;
}
return false;
}
@@ -87,6 +93,12 @@ void ffParsePublicIpJsonObject(FFPublicIpOptions* options, yyjson_val* module)
continue;
}
if (ffStrEqualsIgnCase(key, "ipv6"))
{
options->ipv6 = yyjson_get_bool(val);
continue;
}
ffPrintError(FF_PUBLICIP_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Unknown JSON key %s", key);
}
}
@@ -100,6 +112,12 @@ void ffGeneratePublicIpJsonConfig(FFPublicIpOptions* options, yyjson_mut_doc* do
if (!ffStrbufEqual(&options->url, &defaultOptions.url))
yyjson_mut_obj_add_strbuf(doc, module, "url", &options->url);
if (defaultOptions.timeout != options->timeout)
yyjson_mut_obj_add_uint(doc, module, "timeout", options->timeout);
if (defaultOptions.ipv6 != options->ipv6)
yyjson_mut_obj_add_bool(doc, module, "ipv6", options->ipv6);
}
void ffGeneratePublicIpJsonResult(FFPublicIpOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
@@ -148,6 +166,7 @@ void ffInitPublicIpOptions(FFPublicIpOptions* options)
ffStrbufInit(&options->url);
options->timeout = 0;
options->ipv6 = false;
}
void ffDestroyPublicIpOptions(FFPublicIpOptions* options)
+1
View File
@@ -9,4 +9,5 @@ typedef struct FFSeparatorOptions
FFModuleBaseInfo moduleInfo;
FFstrbuf string;
FFstrbuf outputColor;
} FFSeparatorOptions;
+14
View File
@@ -43,6 +43,8 @@ void ffPrintSeparator(FFSeparatorOptions* options)
+ (fqdn ? platform->hostName.length : ffStrbufFirstIndexC(&platform->hostName, '.')); // host name
ffLogoPrintLine();
if(options->outputColor.length)
ffPrintColor(&options->outputColor);
if(__builtin_expect(options->string.length == 1, 1))
{
ffPrintCharTimes(options->string.chars[0], titleLength);
@@ -97,6 +99,12 @@ bool ffParseSeparatorCommandOptions(FFSeparatorOptions* options, const char* key
return true;
}
if (ffStrEqualsIgnCase(subKey, "output-color"))
{
ffOptionParseColor(value, &options->outputColor);
return true;
}
return false;
}
@@ -116,6 +124,12 @@ void ffParseSeparatorJsonObject(FFSeparatorOptions* options, yyjson_val* module)
continue;
}
if (ffStrEndsWithIgnCase(key, "outputColor"))
{
ffOptionParseColor(yyjson_get_str(val), &options->outputColor);
continue;
}
ffPrintError(FF_SEPARATOR_MODULE_NAME, 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "Unknown JSON key %s", key);
}
}
+3 -3
View File
@@ -24,7 +24,7 @@ static void printDevice(FFSoundOptions* options, const FFSoundDevice* device, ui
if (str.length)
ffStrbufAppendC(&str, ' ');
ffPercentAppendBar(&str, device->volume, options->percent);
ffPercentAppendBar(&str, device->volume, options->percent, &options->moduleArgs);
}
if (instance.config.display.percentType & FF_PERCENTAGE_TYPE_NUM_BIT)
@@ -32,7 +32,7 @@ static void printDevice(FFSoundOptions* options, const FFSoundDevice* device, ui
if (str.length)
ffStrbufAppendC(&str, ' ');
ffPercentAppendNum(&str, device->volume, options->percent, str.length > 0);
ffPercentAppendNum(&str, device->volume, options->percent, str.length > 0, &options->moduleArgs);
}
}
@@ -47,7 +47,7 @@ static void printDevice(FFSoundOptions* options, const FFSoundDevice* device, ui
else
{
FF_STRBUF_AUTO_DESTROY percentageStr = ffStrbufCreate();
ffPercentAppendNum(&percentageStr, device->volume, options->percent, false);
ffPercentAppendNum(&percentageStr, device->volume, options->percent, false, &options->moduleArgs);
FF_PRINT_FORMAT_CHECKED(FF_SOUND_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_SOUND_NUM_FORMAT_ARGS, ((FFformatarg[]) {
{FF_FORMAT_ARG_TYPE_BOOL, &device->main},
+5 -5
View File
@@ -37,19 +37,19 @@ void ffPrintSwap(FFSwapOptions* options)
{
if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_BAR_BIT)
{
ffPercentAppendBar(&str, 0, options->percent);
ffPercentAppendBar(&str, 0, options->percent, &options->moduleArgs);
ffStrbufAppendC(&str, ' ');
}
if(!(instance.config.display.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT))
ffStrbufAppendS(&str, "Disabled");
else
ffPercentAppendNum(&str, 0, options->percent, str.length > 0);
ffPercentAppendNum(&str, 0, options->percent, str.length > 0, &options->moduleArgs);
}
else
{
if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_BAR_BIT)
{
ffPercentAppendBar(&str, percentage, options->percent);
ffPercentAppendBar(&str, percentage, options->percent, &options->moduleArgs);
ffStrbufAppendC(&str, ' ');
}
@@ -57,7 +57,7 @@ void ffPrintSwap(FFSwapOptions* options)
ffStrbufAppendF(&str, "%s / %s ", usedPretty.chars, totalPretty.chars);
if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_NUM_BIT)
ffPercentAppendNum(&str, percentage, options->percent, str.length > 0);
ffPercentAppendNum(&str, percentage, options->percent, str.length > 0, &options->moduleArgs);
}
ffStrbufTrimRight(&str, ' ');
@@ -66,7 +66,7 @@ void ffPrintSwap(FFSwapOptions* options)
else
{
FF_STRBUF_AUTO_DESTROY percentageStr = ffStrbufCreate();
ffPercentAppendNum(&percentageStr, percentage, options->percent, false);
ffPercentAppendNum(&percentageStr, percentage, options->percent, false, &options->moduleArgs);
FF_PRINT_FORMAT_CHECKED(FF_SWAP_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_SWAP_NUM_FORMAT_ARGS, ((FFformatarg[]){
{FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty},
{FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty},
+17 -7
View File
@@ -48,6 +48,9 @@ const char* ffOptionsParseDisplayJsonConfig(FFOptionsDisplay* options, yyjson_va
const char* colorTitle = yyjson_get_str(yyjson_obj_get(val, "title"));
if (colorTitle)
ffOptionParseColor(colorTitle, &options->colorTitle);
const char* colorOutput = yyjson_get_str(yyjson_obj_get(val, "output"));
if (colorOutput)
ffOptionParseColor(colorOutput, &options->colorOutput);
}
else
return "display.color must be either a string or an object";
@@ -113,7 +116,7 @@ const char* ffOptionsParseDisplayJsonConfig(FFOptionsDisplay* options, yyjson_va
{},
});
if (error) return error;
options->temperatureUnit = (FFTemperatureUnit) value;
options->tempUnit = (FFTemperatureUnit) value;
}
yyjson_val* ndigits = yyjson_obj_get(val, "ndigits");
@@ -244,6 +247,11 @@ bool ffOptionsParseDisplayCommandLine(FFOptionsDisplay* options, const char* key
optionCheckString(key, value, &options->colorTitle);
ffOptionParseColor(value, &options->colorTitle);
}
else if(ffStrEqualsIgnCase(subkey, "output"))
{
optionCheckString(key, value, &options->colorOutput);
ffOptionParseColor(value, &options->colorOutput);
}
else
return false;
}
@@ -277,12 +285,12 @@ bool ffOptionsParseDisplayCommandLine(FFOptionsDisplay* options, const char* key
{}
});
}
else if(ffStrStartsWithIgnCase(key, "--temperature-"))
else if(ffStrStartsWithIgnCase(key, "--temp-"))
{
const char* subkey = key + strlen("--temperature-");
const char* subkey = key + strlen("--temp-");
if(ffStrEqualsIgnCase(subkey, "unit"))
{
options->temperatureUnit = (FFTemperatureUnit) ffOptionParseEnum(key, value, (FFKeyValuePair[]) {
options->tempUnit = (FFTemperatureUnit) ffOptionParseEnum(key, value, (FFKeyValuePair[]) {
{ "CELSIUS", FF_TEMPERATURE_UNIT_CELSIUS },
{ "C", FF_TEMPERATURE_UNIT_CELSIUS },
{ "FAHRENHEIT", FF_TEMPERATURE_UNIT_FAHRENHEIT },
@@ -346,6 +354,7 @@ void ffOptionsInitDisplay(FFOptionsDisplay* options)
{
ffStrbufInit(&options->colorKeys);
ffStrbufInit(&options->colorTitle);
ffStrbufInit(&options->colorOutput);
options->brightColor = true;
ffStrbufInitStatic(&options->keyValueSeparator, ": ");
@@ -366,7 +375,7 @@ void ffOptionsInitDisplay(FFOptionsDisplay* options)
options->noBuffer = false;
options->keyWidth = 0;
options->temperatureUnit = FF_TEMPERATURE_UNIT_CELSIUS;
options->tempUnit = FF_TEMPERATURE_UNIT_CELSIUS;
options->tempNdigits = 1;
ffStrbufInitStatic(&options->tempColorGreen, FF_COLOR_FG_GREEN);
ffStrbufInitStatic(&options->tempColorYellow, FF_COLOR_FG_LIGHT_YELLOW);
@@ -389,6 +398,7 @@ void ffOptionsDestroyDisplay(FFOptionsDisplay* options)
{
ffStrbufDestroy(&options->colorKeys);
ffStrbufDestroy(&options->colorTitle);
ffStrbufDestroy(&options->colorOutput);
ffStrbufDestroy(&options->keyValueSeparator);
ffStrbufDestroy(&options->barCharElapsed);
ffStrbufDestroy(&options->barCharTotal);
@@ -478,9 +488,9 @@ void ffOptionsGenerateDisplayJsonConfig(FFOptionsDisplay* options, yyjson_mut_do
{
yyjson_mut_val* temperature = yyjson_mut_obj(doc);
if (options->temperatureUnit != defaultOptions.temperatureUnit)
if (options->tempUnit != defaultOptions.tempUnit)
{
switch (options->temperatureUnit)
switch (options->tempUnit)
{
case FF_TEMPERATURE_UNIT_CELSIUS:
yyjson_mut_obj_add_str(doc, obj, "unit", "C");
+2 -1
View File
@@ -21,6 +21,7 @@ typedef struct FFOptionsDisplay
//If one of those is empty, ffLogoPrint will set them
FFstrbuf colorKeys;
FFstrbuf colorTitle;
FFstrbuf colorOutput;
bool brightColor;
@@ -34,7 +35,7 @@ typedef struct FFOptionsDisplay
FFBinaryPrefixType binaryPrefixType;
uint8_t sizeNdigits;
uint8_t sizeMaxPrefix;
FFTemperatureUnit temperatureUnit;
FFTemperatureUnit tempUnit;
uint8_t tempNdigits;
FFstrbuf tempColorGreen;
FFstrbuf tempColorYellow;
+4
View File
@@ -29,6 +29,7 @@ void ffOptionsInitModules(FFOptionsModules* options)
ffInitIconsOptions(&options->icons);
ffInitKernelOptions(&options->kernel);
ffInitLMOptions(&options->lm);
ffInitLoadavgOptions(&options->loadavg);
ffInitLocalIpOptions(&options->localIP);
ffInitLocaleOptions(&options->locale);
ffInitMediaOptions(&options->media);
@@ -40,6 +41,7 @@ void ffOptionsInitModules(FFOptionsModules* options)
ffInitOpenGLOptions(&options->openGL);
ffInitPackagesOptions(&options->packages);
ffInitPhysicalDiskOptions(&options->physicalDisk);
ffInitPhysicalMemoryOptions(&options->physicalMemory);
ffInitPlayerOptions(&options->player);
ffInitPowerAdapterOptions(&options->powerAdapter);
ffInitProcessesOptions(&options->processes);
@@ -93,6 +95,7 @@ void ffOptionsDestroyModules(FFOptionsModules* options)
ffDestroyIconsOptions(&options->icons);
ffDestroyKernelOptions(&options->kernel);
ffDestroyLMOptions(&options->lm);
ffDestroyLoadavgOptions(&options->loadavg);
ffDestroyLocalIpOptions(&options->localIP);
ffDestroyLocaleOptions(&options->locale);
ffDestroyMediaOptions(&options->media);
@@ -103,6 +106,7 @@ void ffOptionsDestroyModules(FFOptionsModules* options)
ffDestroyOpenCLOptions(&options->openCL);
ffDestroyOpenGLOptions(&options->openGL);
ffDestroyPhysicalDiskOptions(&options->physicalDisk);
ffDestroyPhysicalMemoryOptions(&options->physicalMemory);
ffDestroyPackagesOptions(&options->packages);
ffDestroyPlayerOptions(&options->player);
ffDestroyPowerAdapterOptions(&options->powerAdapter);
+2
View File
@@ -30,6 +30,7 @@ typedef struct FFOptionsModules
FFIconsOptions icons;
FFKernelOptions kernel;
FFLMOptions lm;
FFLoadavgOptions loadavg;
FFLocalIpOptions localIP;
FFLocaleOptions locale;
FFMediaOptions media;
@@ -41,6 +42,7 @@ typedef struct FFOptionsModules
FFOpenGLOptions openGL;
FFPackagesOptions packages;
FFPhysicalDiskOptions physicalDisk;
FFPhysicalMemoryOptions physicalMemory;
FFPlayerOptions player;
FFPowerAdapterOptions powerAdapter;
FFProcessesOptions processes;
+140 -18
View File
@@ -1,6 +1,7 @@
#include "smbiosHelper.h"
#include "common/io/io.h"
#include "util/unused.h"
#include "util/mallocHelper.h"
bool ffIsSmbiosValueSet(FFstrbuf* value)
{
@@ -11,10 +12,8 @@ bool ffIsSmbiosValueSet(FFstrbuf* value)
!ffStrbufStartsWithIgnCaseS(value, "To be set") &&
!ffStrbufStartsWithIgnCaseS(value, "OEM") &&
!ffStrbufStartsWithIgnCaseS(value, "O.E.M.") &&
!ffStrbufStartsWithIgnCaseS(value, "System Product") &&
!ffStrbufIgnCaseEqualS(value, "None") &&
!ffStrbufIgnCaseEqualS(value, "System Product") &&
!ffStrbufIgnCaseEqualS(value, "System Product Name") &&
!ffStrbufIgnCaseEqualS(value, "System Product Version") &&
!ffStrbufIgnCaseEqualS(value, "System Name") &&
!ffStrbufIgnCaseEqualS(value, "System Version") &&
!ffStrbufIgnCaseEqualS(value, "Default string") &&
@@ -28,11 +27,38 @@ bool ffIsSmbiosValueSet(FFstrbuf* value)
!ffStrbufIgnCaseEqualS(value, "No Enclosure") &&
!ffStrbufIgnCaseEqualS(value, "Chassis Version") &&
!ffStrbufIgnCaseEqualS(value, "All Series") &&
!ffStrbufIgnCaseEqualS(value, "N/A")
!ffStrbufIgnCaseEqualS(value, "N/A") &&
!ffStrbufIgnCaseEqualS(value, "0x0000")
;
}
const FFSmbiosHeader* ffSmbiosNextEntry(const FFSmbiosHeader* header)
{
const char* p = ((const char*) header) + header->Length;
if (*p)
{
do
p += strlen(p) + 1;
while (*p);
}
else // The terminator is always double 0 even if there is no string
p ++;
return (const FFSmbiosHeader*) (p + 1);
}
#if defined(__linux__) || defined(__FreeBSD__)
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#ifdef __linux__
#include "common/properties.h"
#else
#include "common/settings.h"
#define loff_t off_t // FreeBSD doesn't have loff_t
#endif
bool ffGetSmbiosValue(const char* devicesPath, const char* classPath, FFstrbuf* buffer)
{
if (ffReadFileBuffer(devicesPath, buffer))
@@ -52,25 +78,119 @@ bool ffGetSmbiosValue(const char* devicesPath, const char* classPath, FFstrbuf*
ffStrbufClear(buffer);
return false;
}
typedef struct FFSmbios30EntryPoint
{
uint8_t AnchorString[5];
uint8_t EntryPointStructureChecksum;
uint8_t EntryPointLength;
uint8_t SmbiosMajorVersion;
uint8_t SmbiosMinorVersion;
uint8_t SmbiosDocrev;
uint8_t EntryPointRevision;
uint8_t Reversed;
uint32_t StructureTableMaximumSize;
uint64_t StructureTableAddress;
} __attribute__((__packed__)) FFSmbios30EntryPoint;
static_assert(offsetof(FFSmbios30EntryPoint, StructureTableAddress) == 0x10,
"FFSmbiosProcessorInfo: Wrong struct alignment");
const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable()
{
static FFstrbuf buffer;
static FFSmbiosHeaderTable table;
if (buffer.chars == NULL)
{
#ifdef __linux__
if (!ffAppendFileBuffer("/sys/firmware/dmi/tables/DMI", &buffer))
#endif
{
FF_STRBUF_AUTO_DESTROY strEntry = ffStrbufCreate();
// Only support SMBIOS 3.x for simplification
#ifdef __FreeBSD__
if (!ffSettingsGetFreeBSDKenv("hint.smbios.0.mem", &strEntry))
return NULL;
#else
if (!ffParsePropFile("/sys/firmware/efi/systab", "SMBIOS3=", &strEntry))
return NULL;
#endif
loff_t pEntry = (loff_t) strtol(strEntry.chars, NULL, 0);
if (pEntry == 0) return NULL;
FF_AUTO_CLOSE_FD int fd = open("/dev/mem", O_RDONLY);
if (fd < 0) return NULL;
FFSmbios30EntryPoint entryPoint;
if (pread(fd, &entryPoint, sizeof(entryPoint), pEntry) != sizeof(entryPoint))
{
// `pread /dev/mem` returns EFAULT in FreeBSD
// https://stackoverflow.com/questions/69372330/how-to-read-dev-mem-using-read
void* p = mmap(NULL, sizeof(entryPoint), PROT_READ, MAP_SHARED, fd, pEntry);
if (p == MAP_FAILED) return NULL;
memcpy(&entryPoint, p, sizeof(entryPoint));
munmap(p, sizeof(entryPoint));
}
if (memcmp(entryPoint.AnchorString, "_SM3_", sizeof(entryPoint.AnchorString)) != 0 ||
entryPoint.EntryPointLength != sizeof(entryPoint))
return NULL;
ffStrbufEnsureFixedLengthFree(&buffer, entryPoint.StructureTableMaximumSize);
if (pread(fd, buffer.chars, entryPoint.StructureTableMaximumSize, pEntry) == (loff_t) entryPoint.StructureTableMaximumSize)
{
buffer.length = (uint32_t) entryPoint.StructureTableMaximumSize;
buffer.chars[buffer.length] = '\0';
}
else
{
// entryPoint.StructureTableAddress must be page aligned.
// Unaligned physical memory access results in all kinds of crashes.
void* p = mmap(NULL, entryPoint.StructureTableMaximumSize, PROT_READ, MAP_SHARED, fd, (loff_t) entryPoint.StructureTableAddress);
if (p == MAP_FAILED)
{
ffStrbufDestroy(&buffer); // free buffer and reset state
return NULL;
}
ffStrbufSetNS(&buffer, entryPoint.StructureTableMaximumSize, (char*) p);
munmap(p, entryPoint.StructureTableMaximumSize);
}
}
for (
const FFSmbiosHeader* header = (const FFSmbiosHeader*) buffer.chars;
(const uint8_t*) header < (const uint8_t*) buffer.chars + buffer.length;
header = ffSmbiosNextEntry(header)
)
{
if (header->Type < FF_SMBIOS_TYPE_END_OF_TABLE)
{
if (!table[header->Type])
table[header->Type] = header;
}
else if (header->Type == FF_SMBIOS_TYPE_END_OF_TABLE)
break;
}
}
return &table;
}
#elif defined(_WIN32)
#include <windows.h>
#pragma GCC diagnostic ignored "-Wmultichar"
const FFSmbiosHeader* ffSmbiosNextEntry(const FFSmbiosHeader* header)
typedef struct FFRawSmbiosData
{
const char* p = ((const char*) header) + header->Length;
if (*p)
{
do
p += strlen(p) + 1;
while (*p);
}
else // The terminator is always double 0 even if there is no string
p ++;
return (const FFSmbiosHeader*) (p + 1);
}
uint8_t Used20CallingMethod;
uint8_t SMBIOSMajorVersion;
uint8_t SMBIOSMinorVersion;
uint8_t DmiRevision;
uint32_t Length;
uint8_t SMBIOSTableData[];
} FFRawSmbiosData;
const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable()
{
@@ -81,7 +201,9 @@ const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable()
{
const DWORD signature = 'RSMB';
uint32_t bufSize = GetSystemFirmwareTable(signature, 0, NULL, 0);
assert(bufSize > sizeof(FFRawSmbiosData));
if (bufSize <= sizeof(FFRawSmbiosData))
return NULL;
buffer = (FFRawSmbiosData*) malloc(bufSize);
assert(buffer);
FF_MAYBE_UNUSED uint32_t resultSize = GetSystemFirmwareTable(signature, 0, buffer, bufSize);
+4 -14
View File
@@ -12,9 +12,6 @@ static inline void ffCleanUpSmbiosValue(FFstrbuf* value)
ffStrbufClear(value);
}
#ifdef __linux__
bool ffGetSmbiosValue(const char* devicesPath, const char* classPath, FFstrbuf* buffer);
#elif defined(_WIN32)
// https://github.com/KunYi/DumpSMBIOS
// https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.7.0.pdf
@@ -78,19 +75,9 @@ typedef struct FFSmbiosHeader
FFSmbiosType Type;
uint8_t Length;
uint16_t Handle;
} FFSmbiosHeader;
} __attribute__((__packed__)) FFSmbiosHeader;
static_assert(sizeof(FFSmbiosHeader) == 4, "FFSmbiosHeader should be 4 bytes");
typedef struct FFRawSmbiosData
{
uint8_t Used20CallingMethod;
uint8_t SMBIOSMajorVersion;
uint8_t SMBIOSMinorVersion;
uint8_t DmiRevision;
uint32_t Length;
uint8_t SMBIOSTableData[];
} FFRawSmbiosData;
static inline const char* ffSmbiosLocateString(const char* start, uint8_t index /* start from 1 */)
{
if (index == 0 || *start == '\0')
@@ -104,6 +91,9 @@ typedef const FFSmbiosHeader* FFSmbiosHeaderTable[FF_SMBIOS_TYPE_END_OF_TABLE];
const FFSmbiosHeader* ffSmbiosNextEntry(const FFSmbiosHeader* header);
const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable();
#ifdef __linux__
bool ffGetSmbiosValue(const char* devicesPath, const char* classPath, FFstrbuf* buffer);
#endif
#endif