Compare commits

...

61 Commits

Author SHA1 Message Date
Carter Li 0869809857 Merge pull request #2446 from fastfetch-cli/dev
Release: v2.66.0
2026-07-10 02:04:09 -05:00
Carter Li c31779e99d CI: ensures CMAKE_BUILD_TYPE is correctly set 2026-07-10 14:44:39 +08:00
Carter Li 89ad35d8a1 GPU (BSD): fixes building when DRM is not enabled 2026-07-10 13:41:13 +08:00
Carter Li d651f3de43 Common (Tracer): updates comments [ci skip] 2026-07-10 13:11:17 +08:00
Carter Li c34c3e5aae Release: v2.66.0 2026-07-10 10:21:45 +08:00
Carter Li c5c61584d9 CPU / GPU (macOS): fixes operator priority bug 2026-07-10 10:12:00 +08:00
Carter Li 48c3b4f980 CPU (Linux): removes ARM core count in CPU name 2026-07-10 08:32:42 +08:00
Carter Li 93bca8d480 CPU (Linux): disables printing package count by default
The detection code is problematic. Let's hide the package count before we can find the root cause.
2026-07-10 08:32:42 +08:00
Carter Li c690fe5aa9 BluetoothRadio: fixes memleaks 2026-07-10 08:32:42 +08:00
Carter Li 55e674e1cb GPU: code cleanups and bug fixes 2026-07-09 20:40:49 +08:00
Carter Li 0495c47909 GPU (Linux): fixes GPU core counting on Asahi Linux 2026-07-09 20:04:11 +08:00
Marvin Hinz 2f79c39f62 OS (Linux): adds support for proxmox backup server detection (#2443)
* add support for proxmox backup server detection

* Update Proxmox identifiers and pretty names

* Simplify Proxmox logo names in p.inc

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2026-07-09 19:05:22 +08:00
Carter Li 44056f1c85 GPU (Linux): fixes accurate AMD GPU names are not queried in driverSpecific mode 2026-07-08 18:14:06 +08:00
李通洲 6358bd7844 FFstrbuf: optimises ffStrbufEnsureFreeNoCheck 2026-07-07 19:15:36 +08:00
Carter Li 11d77e0d09 Logo (Builtin): updates linuxmint_small 2026-07-06 17:27:33 +08:00
李通洲 ec25659503 Presets: uses the builtin icons in examples/10 to avoid inconsistency [ci skip]
Fixes #2438
2026-07-05 08:16:55 +08:00
Carter Li 35dbcb2588 CI: updates scripts 2026-07-04 18:49:00 +08:00
Carter Li 8b6a74f2ec Doc: update changelog 2026-07-03 16:18:01 +08:00
Carter Li 2ea6c3767e Logo (Builtin): cleanup a lot of distro names 2026-07-03 16:15:58 +08:00
Carter Li 827bc26b0a Trace: removes useless empty lines 2026-07-03 15:40:32 +08:00
Carter Li e12f3631d4 OS (Linux): fixes potencial issue 2026-07-03 15:37:38 +08:00
Carter Li 52c9730542 Tracer: query tid only when threading is enabled 2026-07-03 15:36:41 +08:00
Carter Li 225d9e7771 Release: v2.65.3 2026-07-03 14:50:59 +08:00
Carter Li d031d6c20f FFPlatform (Windows): hard codes i686 CPU arch 2026-07-03 14:36:18 +08:00
李通洲 35af768d92 Shell (Windows): improves performance of Windows PowerShell version detection 2026-07-03 11:07:15 +08:00
Carter Li 22c4620345 Logo (Builtin): adds Azure Linux
Fixes #2435
2026-07-03 09:45:34 +08:00
Carter Li 81738aa303 WM (Linux): fixes compatibility with WSL 2.9.3+ 2026-07-02 17:34:43 +08:00
Carter Li 113f7d34d8 OS (Linux): Add Astra Linux version detection
Fixes #2427
2026-07-01 10:57:01 +08:00
Carter Li 62513004c8 Logo (Builtin): adds Flatcar 2026-07-01 10:29:47 +08:00
Carter Li 1b36c3cd5f Logo (Builtin): updates c.inc 2026-07-01 10:29:47 +08:00
eepy 78874ae583 Logo: add chimera2, parabola2_small, postmarketos2, qubes_small (#2430)
* Logo: add chimera2, parabola2_small, postmarketos2, qubes_small

* Logo: add types to chimera2, parabola2_small, postmarketos2, qubes_small, remove "parabola-gnulinux"

* Change logo names to use capital letters

---------

Co-authored-by: v_v <circlepuller@inbox.lv>
Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2026-06-30 21:29:39 -05:00
李通洲 a447928853 FFstrbuf: don't try to inline functions with varargs 2026-06-30 19:35:34 +08:00
李通洲 9f446bdad7 Common (Library): adds fast path for loading only one lib 2026-06-30 19:35:34 +08:00
李通洲 4cf060eb27 Logo (Image): improves performance of DLL searching on WIndows 2026-06-30 19:35:34 +08:00
Carter Li 08d419d75c Global: adds a simple tracer 2026-06-30 16:19:57 +08:00
Carter Li 3ae1bfdc24 Media (macOS): uses perl for faster startup 2026-06-30 15:22:19 +08:00
李通洲 0e257f25c2 Platform (Windows): one less syscall 2026-06-30 09:03:00 +08:00
Carter Li 195e148cc1 Common: inlines more functions 2026-06-30 09:03:00 +08:00
Carter Li 5ab192ee05 Common (Thread): adds ffThreadGetCurrentId 2026-06-30 00:39:36 +08:00
weedygmd 4897152af6 Logo: adds chimera linux small logo (#2426)
* added small chimera linux logo

* Add logo type for Chimera_small

---------

Co-authored-by: Weed <weedygmd>
Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2026-06-29 00:36:10 -05:00
Carter Li 69418cb527 Packaging: updates debian stuff [ci skip] 2026-06-29 10:12:54 +08:00
李通洲 0e90f3a7d4 GPU (Windows): fixes typo 2026-06-28 17:07:48 +08:00
Carter Li 1a663e72da Release: v2.65.2 (#2425) 2026-06-28 03:55:56 -05:00
李通洲 e0ae1ac1a2 GPU (Intel): adds comments 2026-06-28 16:26:00 +08:00
李通洲 e0d141ecf6 Memory (BSD): adds underflow protection (should not happen) 2026-06-28 16:25:08 +08:00
李通洲 29eb8bb57d Chore: fixes typos 2026-06-28 16:25:07 +08:00
李通洲 bc1f240558 Memory (Linux): uses strtoull to avoid overflow in 32-bit systems 2026-06-28 16:25:07 +08:00
李通洲 3e15a2591a Release: v2.65.2 2026-06-28 16:25:07 +08:00
李通洲 0ec9443de5 Logo (Builtin): adds Turkish
Fixes #2421
2026-06-28 16:25:07 +08:00
李通洲 4a4ca9a4a8 Memory (NetBSD): takes ZFS arc bytes into account
Used logic from FreeBSD
2026-06-28 16:25:07 +08:00
李通洲 acf76e565a Memory (FreeBSD): don't query c_min if querying size fails 2026-06-28 16:25:07 +08:00
李通洲 778aa21192 Memory (SunOS): takes ZFS arc bytes into account 2026-06-28 16:25:07 +08:00
Carter Li dfdc7284a2 Memory (Linux): takes ZFS arc bytes into account
Fixes #1995
2026-06-28 16:25:07 +08:00
Carter Li 231d7fcd4d Memory (FreeBSD): takes ZFS arc bytes into account
Fixes #2418
2026-06-28 16:25:07 +08:00
Carter Li a3184601dc GPU: detects PCIe speed only in driverSpecific mode
Fixes #2419
2026-06-28 16:25:07 +08:00
李通洲 e3dfeeb8db GPU (MT): adds PCIe speed detection support 2026-06-27 09:46:30 +08:00
Carter Li ccdcd6ab6f Codec (Linux): fixes crashing on AMD GPUs
Ref: https://github.com/fastfetch-cli/fastfetch/issues/2419#issuecomment-4812121503
2026-06-27 08:12:22 +08:00
Carter Li 64d205628e Common (Settings): adds SQLITE_OPEN_NOMUTEX fiag when opening sqlite db 2026-06-26 22:52:59 +08:00
Carter Li ff13adf1b4 Logo (Builtin): updates CachyOS 2026-06-26 00:18:08 +08:00
iinsert c38fd9ec10 Chore: adds Catnap repo link to attribution comments in examples 13-16 (#2417) 2026-06-25 23:07:49 +08:00
Carter Li 96793ec604 Packaging: updates debian stuff [ci skip] 2026-06-24 14:28:35 +08:00
91 changed files with 1406 additions and 565 deletions
+44 -21
View File
@@ -3,35 +3,58 @@ name: Reusable DragonFly amd64
on:
workflow_call:
env:
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
shell: cpa.sh {0}
steps:
- name: checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: run VM
uses: vmactions/dragonflybsd-vm@v1
- name: Start VM
uses: cross-platform-actions/action@master
with:
usesh: yes
envs: 'CMAKE_BUILD_TYPE'
prepare: |
uname -a
pkg update
pkg install -y llvm cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl egl opencl ocl-icd v4l_compat chafa libelf lua54 libva libvdpau
operating_system: dragonflybsd
version: '6.4.2'
shell: bash
cpu_count: 4
run: |
env CC=clang cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
ctest --output-on-failure
- name: Show system info
run: |
uname -a
pkg --version
- name: Update and install dependencies
run: |
sudo pkg update
sudo pkg install -y llvm cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl egl opencl ocl-icd v4l_compat chafa libelf lua54 libva libvdpau
- name: CMake configuration
run: env CC=clang cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_BUILD_TYPE=${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }} .
- name: CMake build
run: cmake --build . --target package --verbose -j4
- name: List features
run: ./fastfetch --list-features
- name: Run normal
run: time ./fastfetch -c presets/ci.jsonc --stat false
- name: Run json
run: time ./fastfetch -c presets/ci.jsonc --format json
- name: Run flashfetch
run: time ./flashfetch
- name: Run ldd
run: ldd fastfetch
- name: Run tests
run: ctest --output-on-failure
- name: upload artifacts
uses: actions/upload-artifact@v7
+43 -21
View File
@@ -3,37 +3,59 @@ name: Reusable FreeBSD amd64
on:
workflow_call:
env:
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
shell: cpa.sh {0}
steps:
- name: checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: run VM
- name: Start VM
uses: cross-platform-actions/action@master
with:
operating_system: freebsd
architecture: x86-64
cpu_count: 4
version: '15.1'
shell: bash
version: '15.0'
environment_variables: 'CMAKE_BUILD_TYPE'
run: |
uname -a
sudo pkg update
sudo pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl egl opencl ocl-icd v4l_compat chafa lua54 libva libvdpau
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
ctest --output-on-failure
cpu_count: 4
- name: Show system info
run: |
uname -a
freebsd-version
pkg -v
- name: Update and install dependencies
run: |
sudo pkg update
sudo pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl egl opencl ocl-icd v4l_compat chafa lua54 libva libvdpau
- name: CMake configuration
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_BUILD_TYPE=${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }} .
- name: CMake build
run: cmake --build . --target package --verbose -j4
- name: List features
run: ./fastfetch --list-features
- name: Run normal
run: time ./fastfetch -c presets/ci.jsonc --stat false
- name: Run json
run: time ./fastfetch -c presets/ci.jsonc --format json
- name: Run flashfetch
run: time ./flashfetch
- name: Run ldd
run: ldd fastfetch
- name: Run tests
run: ctest --output-on-failure
- name: upload artifacts
uses: actions/upload-artifact@v7
+35 -18
View File
@@ -3,35 +3,52 @@ name: Reusable Haiku amd64
on:
workflow_call:
env:
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
shell: cpa.sh {0}
steps:
- name: checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: run VM
- name: Start VM
uses: cross-platform-actions/action@master
with:
operating_system: haiku
version: 'r1beta5'
architecture: x86-64
cpu_count: 4
shell: bash
environment_variables: 'CMAKE_BUILD_TYPE'
run: |
uname -a
pkgman install -y git dbus_devel mesa_devel libelf_devel imagemagick_devel opencl_headers ocl_icd_devel vulkan_devel zlib_devel chafa_devel cmake gcc make pkgconfig python3.10 || pkgman install -y git dbus_devel mesa_devel libelf_devel imagemagick_devel opencl_headers ocl_icd_devel vulkan_devel zlib_devel chafa_devel cmake gcc make pkgconfig python3.10 lua
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ctest --output-on-failure
cpu_count: 4
- name: Show system info
run: uname -a
- name: Install dependencies
shell: cpa.sh {0} --reboot
run: pkgman install -y git dbus_devel mesa_devel libelf_devel imagemagick_devel opencl_headers ocl_icd_devel vulkan_devel zlib_devel chafa_devel cmake llvm22_clang ninja pkgconfig python3.10 lua || pkgman install -y git dbus_devel mesa_devel libelf_devel imagemagick_devel opencl_headers ocl_icd_devel vulkan_devel zlib_devel chafa_devel cmake llvm22_clang ninja pkgconfig python3.10 lua
- name: CMake configuration
run: CC=clang CXX=clang++ cmake -GNinja -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_BUILD_TYPE=${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }} .
- name: CMake build
run: cmake --build . --target package --verbose -j4
- name: List features
run: ./fastfetch --list-features
- name: Run normal
run: time ./fastfetch -c presets/ci.jsonc --stat false
- name: Run json
run: time ./fastfetch -c presets/ci.jsonc --format json
- name: Run flashfetch
run: time ./flashfetch
- name: Run tests
run: ctest --output-on-failure
- name: upload artifacts
uses: actions/upload-artifact@v7
+1 -1
View File
@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: run VM
uses: uraimo/run-on-arch-action@v3
+1 -1
View File
@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: run VM
uses: uraimo/run-on-arch-action@v3
+1 -1
View File
@@ -24,7 +24,7 @@ jobs:
ffversion: ${{ steps.ffversion.outputs.ffversion }}
steps:
- name: checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: uname -a
run: uname -a
+1 -1
View File
@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: uname -a
run: uname -a
+1 -1
View File
@@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: run VM
uses: uraimo/run-on-arch-action@v3
+1 -1
View File
@@ -18,7 +18,7 @@ jobs:
runs-on: ${{ inputs.runs-on }}
steps:
- name: checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: uname -a
run: uname -a
+1 -1
View File
@@ -10,7 +10,7 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- name: setup alpine linux
uses: jirutka/setup-alpine@master
+41 -20
View File
@@ -3,36 +3,57 @@ name: Reusable NetBSD amd64
on:
workflow_call:
env:
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
shell: cpa.sh {0}
steps:
- name: checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: run VM
- name: Start VM
uses: cross-platform-actions/action@master
with:
operating_system: netbsd
architecture: x86-64
cpu_count: 4
shell: bash
version: '10.1'
environment_variables: 'CMAKE_BUILD_TYPE'
run: |
uname -a
sudo pkgin -y install clang cmake git pkgconf wayland vulkan-headers dconf dbus sqlite3 ImageMagick libva libvdpau
CC=clang cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
ctest --output-on-failure
shell: bash
cpu_count: 4
- name: Show system info
run: |
uname -a
pkgin -v
- name: Update and install dependencies
run: |
sudo pkgin -y install clang cmake git pkgconf wayland vulkan-headers dconf dbus sqlite3 ImageMagick libva libvdpau
- name: CMake configuration
run: CC=clang cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_BUILD_TYPE=${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }} .
- name: CMake build
run: cmake --build . --target package --verbose -j4
- name: List features
run: ./fastfetch --list-features
- name: Run normal
run: time ./fastfetch -c presets/ci.jsonc --stat false
- name: Run json
run: time ./fastfetch -c presets/ci.jsonc --format json
- name: Run flashfetch
run: time ./flashfetch
- name: Run ldd
run: ldd fastfetch
- name: Run tests
run: ctest --output-on-failure
- name: upload artifacts
uses: actions/upload-artifact@v7
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
steps:
- name: checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: uname -a
run: uname -a
+48 -23
View File
@@ -3,37 +3,62 @@ name: Reusable OmniOS amd64
on:
workflow_call:
env:
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
shell: cpa.sh {0}
steps:
- name: checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: run VM
uses: vmactions/omnios-vm@v1
- name: Start VM
uses: cross-platform-actions/action@master
with:
usesh: true
envs: 'CMAKE_BUILD_TYPE'
prepare: |
uname -a
pkg update --accept || true
pkg install gcc14 cmake git pkg-config glib2 dbus sqlite-3 imagemagick ninja
operating_system: omnios
version: 'r151058'
shell: bash
cpu_count: 4
run: |
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -GNinja .
cmake --build . --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
ctest --output-on-failure
echo 'set(CPACK_PACKAGE_FILE_NAME "fastfetch-omnios-amd64")' >> CPackConfig.cmake
cpack -V
- name: Show system info
run: |
uname -a
- name: Update and install dependencies
run: |
sudo pkg update --accept || true
sudo pkg install gcc14 cmake git pkg-config glib2 dbus sqlite-3 imagemagick ninja
- name: CMake configuration
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -GNinja -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_BUILD_TYPE=${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }} .
- name: CMake build
run: cmake --build . --verbose -j4
- name: List features
run: ./fastfetch --list-features
- name: Run normal
run: time ./fastfetch -c presets/ci.jsonc --stat false
- name: Run json
run: time ./fastfetch -c presets/ci.jsonc --format json
- name: Run flashfetch
run: time ./flashfetch
- name: Run ldd
run: ldd fastfetch
- name: Run tests
run: ctest --output-on-failure
- name: Package
run: |
echo 'set(CPACK_PACKAGE_FILE_NAME "fastfetch-omnios-amd64")' >> CPackConfig.cmake
cpack -V
- name: upload artifacts
uses: actions/upload-artifact@v7
+41 -21
View File
@@ -3,37 +3,57 @@ name: Reusable OpenBSD amd64
on:
workflow_call:
env:
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
shell: cpa.sh {0}
steps:
- name: checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: run VM
- name: Start VM
uses: cross-platform-actions/action@master
with:
operating_system: openbsd
architecture: x86-64
cpu_count: 4
shell: bash
version: '7.9'
environment_variables: 'CMAKE_BUILD_TYPE'
run: |
uname -a
sudo pkg_add -u
sudo pkg_add -r llvm-21.1.8p4 cmake git wayland vulkan-headers vulkan-loader glib2 dconf dbus sqlite3 imagemagick chafa lua-5.4.8p0 # pkg-config is preinstalled
CC=clang-21 cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
ctest --output-on-failure
shell: bash
cpu_count: 4
- name: Show system info
run: |
uname -a
- name: Update and install dependencies
run: |
sudo pkg_add -u
sudo pkg_add -r llvm-21.1.8p4 cmake git wayland vulkan-headers vulkan-loader glib2 dconf dbus sqlite3 imagemagick chafa lua-5.4.8p0 # pkg-config is preinstalled
- name: CMake configuration
run: CC=clang-21 cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_BUILD_TYPE=${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }} .
- name: CMake build
run: cmake --build . --target package --verbose -j4
- name: List features
run: ./fastfetch --list-features
- name: Run normal
run: time ./fastfetch -c presets/ci.jsonc --stat false
- name: Run json
run: time ./fastfetch -c presets/ci.jsonc --format json
- name: Run flashfetch
run: time ./flashfetch
- name: Run ldd
run: ldd fastfetch
- name: Run tests
run: ctest --output-on-failure
- name: upload artifacts
uses: actions/upload-artifact@v7
+1 -1
View File
@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: run VM
uses: vmactions/solaris-vm@v1
+1 -1
View File
@@ -9,7 +9,7 @@ jobs:
steps:
- name: checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Install codespell
shell: bash
+1 -1
View File
@@ -30,7 +30,7 @@ jobs:
shell: msys2 {0}
steps:
- name: checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: setup-msys2
uses: msys2/setup-msys2@v2
+43
View File
@@ -1,3 +1,46 @@
# 2.66.0
Changes:
* CPU package count is no longer reported in the default output.
* Users can still print it in custom formats via `{packages}`
Bugfixes:
* Fixed compatibility with WSL 2.9.3 (#2433, WM, Linux)
* Fixed accurate AMD GPU names are not queried in `driverSpecific` mode (GPU, Linux)
* Fixed GPU core counting for Apple Silicon GPU on Asahi Linux (GPU, Linux)
* Some internal cleanups and optimizations
Features:
* Added Astra Linux version detection (OS, Linux)
* Improved performance of Windows PowerShell version detection (Shell, Windows)
* Improved performance of Media module on macOS (Media, macOS)
* Added proxmox backup server detection (#2443, OS, Linux)
Logos:
* Added Flatcar, Azure Linux
* Added Chimera_small, Chimera2, Parabola2_small, PostmarketOS2, Qubes_small
* Updated linuxmint_small
* Cleaned up distro names
# 2.65.2
Changes:
* Memory usage calculations now exclude the ZFS ARC cache on Linux, FreeBSD, NetBSD, and SunOS. (#1995 / #2418, Memory)
* This prevents the Memory module from reporting artificially high memory usage on systems with the ZFS kmod enabled.
Bugfixes:
* The GPU module no longer pings sleeping dedicated GPUs on dual-GPU laptops. (#2419, GPU)
* As a result, PCIe link speed detection (introduced in v2.65.0) is now only enabled in `driverSpecific` mode.
* Fixed a crash when detecting hardware codec support with the `amdgpu` driver on Linux. (#2419, Codec, Linux)
Logos:
* Updated CachyOS_small; fixed CachyOS logo colors to match the official logo better
* Added Turkish
# 2.65.1
No changes
# 2.65.0
Changes:
+23 -1
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.65.1
VERSION 2.66.0
LANGUAGES C
DESCRIPTION "Fast neofetch-like system information tool"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
@@ -105,6 +105,7 @@ cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND"
option(ENABLE_ZLIB "Enable zlib" ON)
option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embedded) yyjson library" OFF)
option(ENABLE_ASAN "Build fastfetch with ASAN (address sanitizer)" OFF)
option(ENABLE_TRACER "Build fastfetch with function tracing" OFF)
option(ENABLE_LTO "Enable link-time optimization in release mode if supported" ON)
option(BUILD_FLASHFETCH "Build flashfetch" ON) # Also build the flashfetch binary
option(BUILD_TESTS "Build tests" OFF) # Also create test executables
@@ -1365,6 +1366,22 @@ elseif(GNU)
)
endif()
if(ENABLE_TRACER)
message(STATUS "Tracer is enabled")
list(APPEND LIBFASTFETCH_SRC src/common/impl/tracer.c)
if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -finstrument-functions-after-inlining")
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -finstrument-functions -Dinline=\"__attribute__((no_instrument_function)) inline\"")
endif()
if(NOT WIN32)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -rdynamic")
elseif(CMAKE_C_COMPILER_ID MATCHES "Clang")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -gcodeview -fuse-ld=lld")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--pdb=${CMAKE_BINARY_DIR}/fastfetch.pdb")
endif()
endif()
# Proprietary GPU driver APIs
if(LINUX OR FreeBSD OR WIN32)
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_nvidia.c)
@@ -1889,6 +1906,11 @@ elseif(WIN32)
PRIVATE "runtimeobject"
)
endif()
if(ENABLE_TRACER)
target_link_libraries(libfastfetch
PRIVATE "dbghelp"
)
endif()
elseif(FreeBSD)
target_link_libraries(libfastfetch
PRIVATE "m"
+12
View File
@@ -1,3 +1,15 @@
fastfetch (2.65.2~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
* Update to 2.65.2
-- Carter Li <zhangsongcui@live.cn> Mon, 29 Jun 2026 10:05:47 +0800
fastfetch (2.65.1~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
* Update to 2.65.1
-- Carter Li <zhangsongcui@live.cn> Wed, 24 Jun 2026 14:21:06 +0800
fastfetch (2.64.2~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
* Update to 2.64.2
+1 -1
View File
@@ -10,7 +10,7 @@ SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
ROOT_DIR="$(cd -- "$SCRIPT_DIR/.." >/dev/null 2>&1 && pwd)"
OUT_DIR="$(dirname "$ROOT_DIR")"
PPA="ppa:zhangsongcui3371/fastfetch"
CODENAMES=( jammy noble plucky questing resolute )
CODENAMES=( jammy noble plucky questing resolute stonking )
DRY_RUN=0
if [[ -d "$OUT_DIR/build" ]]; then
+13 -13
View File
@@ -42,12 +42,12 @@
},
{
"type": "kernel",
"key": "│ ├",
"key": "│ ├{icon}",
"keyColor": "yellow"
},
{
"type": "packages",
"key": "│ ├󰏖",
"key": "│ ├{icon}",
"keyColor": "yellow"
},
{
@@ -62,22 +62,22 @@
},
{
"type": "lm",
"key": "│ ├󰧨",
"key": "│ ├{icon}",
"keyColor": "blue"
},
{
"type": "wmtheme",
"key": "│ ├󰉼",
"key": "│ ├{icon}",
"keyColor": "blue"
},
{
"type": "icons",
"key": "│ ├󰀻",
"key": "│ ├{icon}",
"keyColor": "blue"
},
{
"type": "terminal",
"key": "│ ├",
"key": "│ ├{icon}",
"keyColor": "blue"
},
{
@@ -92,32 +92,32 @@
},
{
"type": "cpu",
"key": "│ ├󰻠",
"key": "│ ├{icon}",
"keyColor": "green"
},
{
"type": "gpu",
"key": "│ ├󰍛",
"key": "│ ├{icon}",
"keyColor": "green"
},
{
"type": "disk",
"key": "│ ├",
"key": "│ ├{icon}",
"keyColor": "green"
},
{
"type": "memory",
"key": "│ ├󰑭",
"key": "│ ├{icon}",
"keyColor": "green"
},
{
"type": "swap",
"key": "│ ├󰓡",
"key": "│ ├{icon}",
"keyColor": "green"
},
{
"type": "uptime",
"key": "│ ├󰅐",
"key": "│ ├{icon}",
"keyColor": "green"
},
{
@@ -132,7 +132,7 @@
},
{
"type": "player",
"key": "│ ├󰥠",
"key": "│ ├{icon}",
"keyColor": "cyan"
},
{
+1 -1
View File
@@ -1,4 +1,4 @@
// Inspired by Catnap
// Inspired by Catnap (https://github.com/iinsertNameHere/catnap)
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": {
+1 -1
View File
@@ -1,4 +1,4 @@
// Inspired by Catnap
// Inspired by Catnap (https://github.com/iinsertNameHere/catnap)
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": {
+1 -1
View File
@@ -1,4 +1,4 @@
// Inspired by Catnap
// Inspired by Catnap (https://github.com/iinsertNameHere/catnap)
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": {
+1 -1
View File
@@ -1,4 +1,4 @@
// Inspired by Catnap
// Inspired by Catnap (https://github.com/iinsertNameHere/catnap)
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": {
+9 -2
View File
@@ -15,8 +15,6 @@ typedef struct FFlist {
uint32_t capacity;
} FFlist;
void* ffListAdd(FFlist* list, uint32_t elementSize);
// Removes the first element, and copy its value to `*result`
bool ffListShift(FFlist* list, uint32_t elementSize, void* __restrict result);
// Removes the last element, and copy its value to `*result`
@@ -105,6 +103,15 @@ static inline void ffListReserve(FFlist* list, uint32_t elementSize, uint32_t ne
list->capacity = newCapacity;
}
static inline void* ffListAdd(FFlist* list, uint32_t elementSize) {
if (__builtin_expect(list->length == list->capacity, false)) {
ffListReserve(list, elementSize, list->capacity == 0 ? FF_LIST_DEFAULT_ALLOC : list->capacity * 2);
}
++list->length;
return ffListGet(list, elementSize, list->length - 1);
}
#define FF_LIST_FOR_EACH(itemType, itemVarName, listVar) \
for (itemType* itemVarName = (itemType*) (listVar).data; \
itemVarName - (itemType*) (listVar).data < (intptr_t) (listVar).length; \
+100 -46
View File
@@ -37,16 +37,13 @@ static inline void ffStrbufInit(FFstrbuf* strbuf);
void ffStrbufInitA(FFstrbuf* strbuf, uint32_t allocate);
void ffStrbufInitVF(FFstrbuf* strbuf, const char* format, va_list arguments);
void ffStrbufInitMoveNS(FFstrbuf* strbuf, uint32_t length, char* heapStr);
FF_A_PRINTF(2, 3) void ffStrbufInitF(FFstrbuf* strbuf, const char* format, ...);
FF_A_PRINTF(1, 2) FF_A_NODISCARD FFstrbuf ffStrbufCreateF(const char* format, ...);
void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free);
void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free);
void ffStrbufClear(FFstrbuf* strbuf);
void ffStrbufEnsureFreeNoCheck(FFstrbuf* strbuf, uint32_t free);
static inline void ffStrbufAppend(FFstrbuf* __restrict strbuf, const FFstrbuf* __restrict value);
void ffStrbufAppendC(FFstrbuf* strbuf, char c);
void ffStrbufAppendNC(FFstrbuf* strbuf, uint32_t num, char c);
void ffStrbufAppendNS(FFstrbuf* strbuf, uint32_t length, const char* value);
void ffStrbufAppendTransformS(FFstrbuf* strbuf, const char* value, int (*transformFunc)(int));
FF_A_PRINTF(2, 3) void ffStrbufAppendF(FFstrbuf* strbuf, const char* format, ...);
void ffStrbufAppendVF(FFstrbuf* strbuf, const char* format, va_list arguments);
@@ -88,13 +85,6 @@ bool ffStrbufRemoveIgnCaseEndS(FFstrbuf* strbuf, const char* end);
bool ffStrbufEnsureEndsWithC(FFstrbuf* strbuf, char c);
void ffStrbufWriteTo(const FFstrbuf* strbuf, FILE* file);
void ffStrbufPutTo(const FFstrbuf* strbuf, FILE* file);
FF_A_NODISCARD double ffStrbufToDouble(const FFstrbuf* strbuf, double defaultValue);
FF_A_NODISCARD int64_t ffStrbufToSInt(const FFstrbuf* strbuf, int64_t defaultValue);
FF_A_NODISCARD uint64_t ffStrbufToUInt(const FFstrbuf* strbuf, uint64_t defaultValue);
void ffStrbufUpperCase(FFstrbuf* strbuf);
void ffStrbufLowerCase(FFstrbuf* strbuf);
@@ -182,31 +172,6 @@ FF_A_NODISCARD static inline FFstrbuf ffStrbufCreateMove(FFstrbuf* src) {
return strbuf;
}
FF_A_NODISCARD static inline FFstrbuf ffStrbufCreateVF(const char* format, va_list arguments) {
FFstrbuf strbuf;
ffStrbufInitVF(&strbuf, format, arguments);
return strbuf;
}
FF_A_PRINTF(2, 3) static inline void ffStrbufInitF(FFstrbuf* strbuf, const char* format, ...) {
va_list arguments;
va_start(arguments, format);
ffStrbufInitVF(strbuf, format, arguments);
va_end(arguments);
}
FF_A_PRINTF(1, 2) FF_A_NODISCARD static inline FFstrbuf
ffStrbufCreateF(const char* format, ...) {
FFstrbuf strbuf;
va_list arguments;
va_start(arguments, format);
ffStrbufInitVF(&strbuf, format, arguments);
va_end(arguments);
return strbuf;
}
static inline void ffStrbufInitMoveS(FFstrbuf* strbuf, char* heapStr) {
ffStrbufInitMoveNS(strbuf, (uint32_t) strlen(heapStr), heapStr);
}
@@ -229,6 +194,76 @@ FF_A_NODISCARD static inline uint32_t ffStrbufGetFree(const FFstrbuf* strbuf) {
return strbuf->allocated - strbuf->length - 1; // - 1 for the null byte
}
static inline void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free) {
if (__builtin_expect(free == 0, false)) {
if (__builtin_expect(!(strbuf->allocated == 0 && strbuf->length > 0), true)) {
return;
}
} else {
if (__builtin_expect(ffStrbufGetFree(strbuf) >= free, true)) {
return;
}
}
ffStrbufEnsureFreeNoCheck(strbuf, free);
}
static inline void ffStrbufClear(FFstrbuf* strbuf) {
assert(strbuf != NULL);
extern char* CHAR_NULL_PTR;
if (strbuf->allocated == 0) {
strbuf->chars = CHAR_NULL_PTR;
} else {
strbuf->chars[0] = '\0';
}
strbuf->length = 0;
}
static inline void ffStrbufAppendC(FFstrbuf* strbuf, char c) {
if (__builtin_expect(ffStrbufGetFree(strbuf) == 0, false)) {
ffStrbufEnsureFreeNoCheck(strbuf, 1);
}
strbuf->chars[strbuf->length++] = c;
strbuf->chars[strbuf->length] = '\0';
}
static inline void ffStrbufAppendNC(FFstrbuf* strbuf, uint32_t num, char c) {
if (__builtin_expect(num == 0, false)) {
return;
}
if (__builtin_expect(ffStrbufGetFree(strbuf) < num, false)) {
ffStrbufEnsureFreeNoCheck(strbuf, num);
}
memset(&strbuf->chars[strbuf->length], c, num);
strbuf->length += num;
strbuf->chars[strbuf->length] = '\0';
}
static inline void ffStrbufAppendNS(FFstrbuf* strbuf, uint32_t length, const char* value) {
if (__builtin_expect(value == NULL || length == 0, false)) {
return;
}
if (__builtin_expect(ffStrbufGetFree(strbuf) < length, false)) {
ffStrbufEnsureFreeNoCheck(strbuf, length);
}
memcpy(&strbuf->chars[strbuf->length], value, length);
strbuf->length += length;
strbuf->chars[strbuf->length] = '\0';
}
static inline void ffStrbufAppend(FFstrbuf* __restrict strbuf, const FFstrbuf* __restrict value) {
assert(value != strbuf);
if (value == NULL) {
return;
}
ffStrbufAppendNS(strbuf, value->length, value->chars);
}
static inline void ffStrbufRecalculateLength(FFstrbuf* strbuf) {
strbuf->length = (uint32_t) strlen(strbuf->chars);
}
@@ -338,14 +373,6 @@ FF_A_NODISCARD static inline FFstrbuf ffStrbufCreateS(const char* str) {
return strbuf;
}
static inline void ffStrbufAppend(FFstrbuf* __restrict strbuf, const FFstrbuf* __restrict value) {
assert(value != strbuf);
if (value == NULL) {
return;
}
ffStrbufAppendNS(strbuf, value->length, value->chars);
}
static inline void ffStrbufPrepend(FFstrbuf* strbuf, FFstrbuf* value) {
if (value == NULL) {
return;
@@ -578,6 +605,33 @@ static inline bool ffStrbufSeparatedContainIgnCase(const FFstrbuf* strbuf, const
return ffStrbufSeparatedContainIgnCaseNS(strbuf, comp->length, comp->chars, separator);
}
static inline void ffStrbufWriteTo(const FFstrbuf* strbuf, FILE* file) {
fwrite(strbuf->chars, sizeof(*strbuf->chars), strbuf->length, file);
}
static inline void ffStrbufPutTo(const FFstrbuf* strbuf, FILE* file) {
ffStrbufWriteTo(strbuf, file);
fputc('\n', file);
}
FF_A_NODISCARD static inline double ffStrbufToDouble(const FFstrbuf* strbuf, double defaultValue) {
char* str_end;
double result = strtod(strbuf->chars, &str_end);
return str_end == strbuf->chars ? defaultValue : result;
}
FF_A_NODISCARD static inline uint64_t ffStrbufToUInt(const FFstrbuf* strbuf, uint64_t defaultValue) {
char* str_end;
unsigned long long result = strtoull(strbuf->chars, &str_end, 10);
return str_end == strbuf->chars ? defaultValue : (uint64_t) result;
}
FF_A_NODISCARD static inline int64_t ffStrbufToSInt(const FFstrbuf* strbuf, int64_t defaultValue) {
char* str_end;
long long result = strtoll(strbuf->chars, &str_end, 10);
return str_end == strbuf->chars ? defaultValue : (int64_t) result;
}
// Returns true if the strbuf is modified
bool ffStrbufDecodeHexEscapeSequences(FFstrbuf* strbuf);
+32 -48
View File
@@ -236,54 +236,38 @@ static void getSystemPageSize(FFPlatformSysinfo* info) {
}
static void getSystemArchitecture(FFPlatformSysinfo* info) {
SYSTEM_PROCESSOR_INFORMATION spi;
if (NT_SUCCESS(NtQuerySystemInformation(SystemProcessorInformation, &spi, sizeof(spi), NULL))) {
switch (spi.ProcessorArchitecture) {
case PROCESSOR_ARCHITECTURE_AMD64:
ffStrbufSetStatic(&info->architecture, "x86_64");
break;
case PROCESSOR_ARCHITECTURE_IA64:
ffStrbufSetStatic(&info->architecture, "ia64");
break;
case PROCESSOR_ARCHITECTURE_INTEL:
switch (spi.ProcessorLevel) {
case 4:
ffStrbufSetStatic(&info->architecture, "i486");
break;
case 5:
ffStrbufSetStatic(&info->architecture, "i586");
break;
case 6:
ffStrbufSetStatic(&info->architecture, "i686");
break;
default:
ffStrbufSetStatic(&info->architecture, "i386");
break;
}
break;
case PROCESSOR_ARCHITECTURE_ARM64:
ffStrbufSetStatic(&info->architecture, "aarch64");
break;
case PROCESSOR_ARCHITECTURE_ARM:
ffStrbufSetStatic(&info->architecture, "arm");
break;
case PROCESSOR_ARCHITECTURE_PPC:
ffStrbufSetStatic(&info->architecture, "ppc");
break;
case PROCESSOR_ARCHITECTURE_MIPS:
ffStrbufSetStatic(&info->architecture, "mips");
break;
case PROCESSOR_ARCHITECTURE_ALPHA:
ffStrbufSetStatic(&info->architecture, "alpha");
break;
case PROCESSOR_ARCHITECTURE_ALPHA64:
ffStrbufSetStatic(&info->architecture, "alpha64");
break;
case PROCESSOR_ARCHITECTURE_UNKNOWN:
default:
ffStrbufSetStatic(&info->architecture, "unknown");
break;
}
switch (SharedUserData->NativeProcessorArchitecture) {
case PROCESSOR_ARCHITECTURE_AMD64:
ffStrbufSetStatic(&info->architecture, "x86_64");
break;
case PROCESSOR_ARCHITECTURE_IA64:
ffStrbufSetStatic(&info->architecture, "ia64");
break;
case PROCESSOR_ARCHITECTURE_INTEL:
ffStrbufSetStatic(&info->architecture, "i686");
break;
case PROCESSOR_ARCHITECTURE_ARM64:
ffStrbufSetStatic(&info->architecture, "aarch64");
break;
case PROCESSOR_ARCHITECTURE_ARM:
ffStrbufSetStatic(&info->architecture, "arm");
break;
case PROCESSOR_ARCHITECTURE_PPC:
ffStrbufSetStatic(&info->architecture, "ppc");
break;
case PROCESSOR_ARCHITECTURE_MIPS:
ffStrbufSetStatic(&info->architecture, "mips");
break;
case PROCESSOR_ARCHITECTURE_ALPHA:
ffStrbufSetStatic(&info->architecture, "alpha");
break;
case PROCESSOR_ARCHITECTURE_ALPHA64:
ffStrbufSetStatic(&info->architecture, "alpha64");
break;
case PROCESSOR_ARCHITECTURE_UNKNOWN:
default:
ffStrbufSetStatic(&info->architecture, "unknown");
break;
}
}
-9
View File
@@ -3,15 +3,6 @@
#include <stdlib.h>
#include <string.h>
void* ffListAdd(FFlist* list, uint32_t elementSize) {
if (list->length == list->capacity) {
ffListReserve(list, elementSize, list->capacity == 0 ? FF_LIST_DEFAULT_ALLOC : list->capacity * 2);
}
++list->length;
return ffListGet(list, elementSize, list->length - 1);
}
bool ffListShift(FFlist* list, uint32_t elementSize, void* __restrict result) {
if (list->length == 0) {
return false;
+26 -78
View File
@@ -45,18 +45,33 @@ void ffStrbufInitMoveNS(FFstrbuf* strbuf, uint32_t length, char* heapStr) {
strbuf->chars = heapStr;
}
void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free) {
if (ffStrbufGetFree(strbuf) >= free && !(strbuf->allocated == 0 && strbuf->length > 0)) {
return;
}
void ffStrbufInitF(FFstrbuf* strbuf, const char* format, ...) {
va_list arguments;
va_start(arguments, format);
ffStrbufInitVF(strbuf, format, arguments);
va_end(arguments);
}
uint32_t allocate = strbuf->allocated;
if (allocate < FASTFETCH_STRBUF_DEFAULT_ALLOC) {
FFstrbuf ffStrbufCreateF(const char* format, ...) {
FFstrbuf strbuf;
va_list arguments;
va_start(arguments, format);
ffStrbufInitVF(&strbuf, format, arguments);
va_end(arguments);
return strbuf;
}
void ffStrbufEnsureFreeNoCheck(FFstrbuf* strbuf, uint32_t free) {
uint32_t allocate = strbuf->length + free;
if (allocate < FASTFETCH_STRBUF_DEFAULT_ALLOC) { // `<` for null terminator
allocate = FASTFETCH_STRBUF_DEFAULT_ALLOC;
}
while ((strbuf->length + free + 1) > allocate) { // + 1 for the null byte
allocate *= 2;
} else {
// Round up to the next power of 2.
// If the value is already a power of 2, it will be rounded up to the next power of 2.
assert(allocate < (UINT32_MAX >> 1));
allocate = 1U << (32 - __builtin_clz(allocate));
}
if (strbuf->allocated == 0) {
@@ -100,46 +115,6 @@ void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free) {
strbuf->allocated = newCap;
}
void ffStrbufClear(FFstrbuf* strbuf) {
assert(strbuf != NULL);
if (strbuf->allocated == 0) {
strbuf->chars = CHAR_NULL_PTR;
} else {
strbuf->chars[0] = '\0';
}
strbuf->length = 0;
}
void ffStrbufAppendC(FFstrbuf* strbuf, char c) {
ffStrbufEnsureFree(strbuf, 1);
strbuf->chars[strbuf->length++] = c;
strbuf->chars[strbuf->length] = '\0';
}
void ffStrbufAppendNC(FFstrbuf* strbuf, uint32_t num, char c) {
if (num == 0) {
return;
}
ffStrbufEnsureFree(strbuf, num);
memset(&strbuf->chars[strbuf->length], c, num);
strbuf->length += num;
strbuf->chars[strbuf->length] = '\0';
}
void ffStrbufAppendNS(FFstrbuf* strbuf, uint32_t length, const char* value) {
if (value == NULL || length == 0) {
return;
}
ffStrbufEnsureFree(strbuf, length);
memcpy(&strbuf->chars[strbuf->length], value, length);
strbuf->length += length;
strbuf->chars[strbuf->length] = '\0';
}
void ffStrbufAppendTransformS(FFstrbuf* strbuf, const char* value, int (*transformFunc)(int)) {
if (value == NULL) {
return;
@@ -168,7 +143,7 @@ void ffStrbufAppendVF(FFstrbuf* strbuf, const char* format, va_list arguments) {
int written = vsnprintf(strbuf->chars + strbuf->length, strbuf->allocated > 0 ? free + 1 : 0, format, arguments);
if (written > 0 && (uint32_t) written > free) {
ffStrbufEnsureFree(strbuf, (uint32_t) written);
ffStrbufEnsureFreeNoCheck(strbuf, (uint32_t) written);
written = vsnprintf(strbuf->chars + strbuf->length, (uint32_t) written + 1, format, copy);
}
@@ -550,33 +525,6 @@ bool ffStrbufEnsureEndsWithC(FFstrbuf* strbuf, char c) {
return true;
}
void ffStrbufWriteTo(const FFstrbuf* strbuf, FILE* file) {
fwrite(strbuf->chars, sizeof(*strbuf->chars), strbuf->length, file);
}
void ffStrbufPutTo(const FFstrbuf* strbuf, FILE* file) {
ffStrbufWriteTo(strbuf, file);
fputc('\n', file);
}
double ffStrbufToDouble(const FFstrbuf* strbuf, double defaultValue) {
char* str_end;
double result = strtod(strbuf->chars, &str_end);
return str_end == strbuf->chars ? defaultValue : result;
}
uint64_t ffStrbufToUInt(const FFstrbuf* strbuf, uint64_t defaultValue) {
char* str_end;
unsigned long long result = strtoull(strbuf->chars, &str_end, 10);
return str_end == strbuf->chars ? defaultValue : (uint64_t) result;
}
int64_t ffStrbufToSInt(const FFstrbuf* strbuf, int64_t defaultValue) {
char* str_end;
long long result = strtoll(strbuf->chars, &str_end, 10);
return str_end == strbuf->chars ? defaultValue : (int64_t) result;
}
void ffStrbufAppendSInt(FFstrbuf* strbuf, int64_t value) {
ffStrbufEnsureFree(strbuf, 21); // Required by yyjson_write_number
char* start = strbuf->chars + strbuf->length;
+1 -1
View File
@@ -177,7 +177,7 @@ bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data) {
}
static inline void readWithLength(HANDLE handle, FFstrbuf* buffer, uint32_t length) {
ffStrbufEnsureFree(buffer, length);
ffStrbufEnsureFixedLengthFree(buffer, length);
DWORD bytesRead = 0;
while (
length > 0 &&
+4 -4
View File
@@ -27,7 +27,7 @@
#endif
#endif
static void* libraryLoad(const char* path, int maxVersion) {
void* ffLibraryLoadSingle(const char* path, int maxVersion) {
void* result = dlopen(path, FF_DLOPEN_FLAGS);
#if _WIN32
@@ -81,8 +81,8 @@ static void* libraryLoad(const char* path, int maxVersion) {
return result;
}
void* ffLibraryLoad(const char* path, int maxVersion, ...) {
void* result = libraryLoad(path, maxVersion);
void* ffLibraryLoadMulti(const char* path, int maxVersion, ...) {
void* result = ffLibraryLoadSingle(path, maxVersion);
if (!result) {
va_list defaultNames;
@@ -95,7 +95,7 @@ void* ffLibraryLoad(const char* path, int maxVersion, ...) {
}
int maxVersionRest = va_arg(defaultNames, int);
result = libraryLoad(pathRest, maxVersionRest);
result = ffLibraryLoadSingle(pathRest, maxVersionRest);
} while (!result);
va_end(defaultNames);
+1 -1
View File
@@ -391,7 +391,7 @@ int ffSettingsGetSQLite3Int(const char* dbPath, const char* query) {
}
sqlite3* db;
if (data->ffsqlite3_open_v2(dbPath, &db, SQLITE_OPEN_READONLY, NULL) != SQLITE_OK) {
if (data->ffsqlite3_open_v2(dbPath, &db, SQLITE_OPEN_READONLY | SQLITE_OPEN_NOMUTEX, NULL) != SQLITE_OK) {
return 0;
}
+148
View File
@@ -0,0 +1,148 @@
// DON'T CALL ANY FASTFETCH FUNCTION IN THIS FILE (to avoid recursion when -finstrument-functions is enabled)
#include <stdio.h>
#include <time.h>
#include <stdatomic.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#if !_WIN32
#include <dlfcn.h>
#include <pthread.h>
#include <unistd.h>
#else
#include <windows.h>
#include <dbghelp.h>
#endif
#if _WIN32
static LARGE_INTEGER freq;
#define NtCurrentProcess() ((HANDLE) (-1))
#endif
static struct trace_event {
uint64_t ts;
uint64_t tid;
void* func;
} events[4 * 1024 * 1024]; // 4M events, 96 MiB memory usage
static _Atomic uint32_t event_count;
__attribute__((no_instrument_function, always_inline)) static inline uint64_t get_time_us() {
#if !_WIN32
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (uint64_t) (ts.tv_sec * 1000000 + ts.tv_nsec / 1000);
#else
LARGE_INTEGER now;
QueryPerformanceCounter(&now);
return (uint64_t) (now.QuadPart * 1000000 / freq.QuadPart);
#endif
}
#if _WIN32
__attribute__((constructor, no_instrument_function)) void trace_init() {
QueryPerformanceFrequency(&freq);
}
#endif
__attribute__((destructor, no_instrument_function)) void trace_fini() {
#if _WIN32
uint32_t pid = (uint32_t) GetCurrentProcessId();
#else
uint32_t pid = (uint32_t) getpid();
#endif
char fileName[64];
snprintf(fileName, sizeof(fileName), "trace_%d.json", pid);
FILE* trace_file = fopen(fileName, "wb");
if (!trace_file) {
fprintf(stderr, "Failed to open trace file %s for writing\n", fileName);
abort();
}
fputs("[\n", trace_file);
#if _WIN32
SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_UNDNAME);
SymInitialize(NtCurrentProcess(), NULL, TRUE);
#endif
const char* fnName = NULL;
uint32_t count = atomic_load_explicit(&event_count, memory_order_acquire);
for (uint32_t i = 0; i < count; ++i) {
void* fn = events[i].func;
uint64_t ts = events[i].ts;
bool is_exit = (ts >> 63) != 0;
ts &= ~(1ULL << 63); // clear the highest bit
uint64_t tid = events[i].tid;
#if _WIN32
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO) buffer;
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymbol->MaxNameLen = MAX_SYM_NAME;
DWORD64 displacement = 0;
if (SymFromAddr(NtCurrentProcess(), (DWORD64) fn, &displacement, pSymbol)) {
fnName = pSymbol->Name;
}
#else
char buffer[32];
Dl_info info;
if (dladdr(fn, &info) && info.dli_sname) {
fnName = info.dli_sname;
}
#endif
else {
snprintf(buffer, sizeof(buffer), "%p", fn);
fnName = buffer;
}
fprintf(trace_file, "{\"name\":\"%s\",\"ph\":\"%c\",\"pid\":%" PRIu32 ",\"tid\":%" PRIu64 ",\"ts\":%" PRIu64 "}%c\n", fnName, is_exit ? 'E' : 'B', pid, tid, ts, i < count - 1 ? ',' : ' ');
}
fputc(']', trace_file);
fclose(trace_file);
fprintf(stderr, "Trace written to trace_%d.json with %u events. Use https://ui.perfetto.dev/ to view it.\n", pid, count);
#if _WIN32
SymCleanup(NtCurrentProcess());
#endif
}
__attribute__((no_instrument_function)) static void write_event(void* this_fn, bool is_exit) {
uint32_t idx = atomic_fetch_add_explicit(&event_count, 1, memory_order_relaxed);
if (__builtin_expect(idx >= sizeof(events) / sizeof(events[0]), false)) {
abort();
}
events[idx].ts = get_time_us();
#if ENABLE_THREADS
#if _WIN32
events[idx].tid = (uint64_t) GetCurrentThreadId();
#else
events[idx].tid = (uint64_t) (uintptr_t) pthread_self();
#endif
#else
events[idx].tid = 0;
#endif
events[idx].func = this_fn;
if (is_exit) {
events[idx].ts |= (1ULL << 63); // set the highest bit to indicate function exit
}
}
__attribute__((no_instrument_function)) void __cyg_profile_func_enter(void* this_fn, void* call_site) {
(void) call_site;
write_event(this_fn, false);
}
__attribute__((no_instrument_function)) void __cyg_profile_func_exit(void* this_fn, void* call_site) {
(void) call_site;
write_event(this_fn, true);
}
+7 -5
View File
@@ -35,9 +35,10 @@ static inline void ffLibraryUnload(void** handle) {
#define FF_LIBRARY_SYMBOL(symbolName) \
__typeof__(&symbolName) ff##symbolName;
#define FF_LIBRARY_LOAD(libraryObjectName, returnValue, ...) \
void* FF_A_CLEANUP(ffLibraryUnload) libraryObjectName = ffLibraryLoad(__VA_ARGS__, NULL); \
if (libraryObjectName == NULL) \
#define FF_LIBRARY_LOAD(libraryObjectName, returnValue, libraryFileName, maxVersion, ...) \
void* FF_A_CLEANUP(ffLibraryUnload) libraryObjectName = ffLibraryLoadSingle(libraryFileName, maxVersion); \
__VA_OPT__(if (__builtin_expect(libraryObjectName == NULL, false)) libraryObjectName = ffLibraryLoadMulti(__VA_ARGS__, NULL);) \
if (__builtin_expect(libraryObjectName == NULL, false)) \
return returnValue;
#define FF_LIBRARY_LOAD_MESSAGE(libraryObjectName, libraryFileName, maxVersion, ...) \
@@ -45,7 +46,7 @@ static inline void ffLibraryUnload(void** handle) {
#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, symbolMapping, symbolName, returnValue) \
symbolMapping = (__typeof__(&symbolName)) dlsym(library, #symbolName); \
if (symbolMapping == NULL) \
if (__builtin_expect(symbolMapping == NULL, false)) \
return returnValue;
#define FF_LIBRARY_LOAD_SYMBOL(library, symbolName, returnValue) \
@@ -66,7 +67,8 @@ static inline void ffLibraryUnload(void** handle) {
#define FF_LIBRARY_LOAD_SYMBOL_PTR(library, varName, symbolName, returnValue) \
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName)->ff##symbolName, symbolName, returnValue);
void* ffLibraryLoad(const char* path, int maxVersion, ...);
void* ffLibraryLoadSingle(const char* path, int maxVersion);
void* ffLibraryLoadMulti(const char* path, int maxVersion, ...);
#else
+7 -1
View File
@@ -4,7 +4,7 @@
#ifdef FF_HAVE_THREADS
#if defined(_WIN32)
#include <winternl.h>
#include "common/windows/nt.h"
#include <synchapi.h>
#include <process.h>
#include <processthreadsapi.h>
@@ -41,6 +41,9 @@ static inline bool ffThreadJoin(FFThreadType thread, uint32_t timeout) {
}
NtClose(thread);
return true;
}
static inline uintptr_t ffThreadGetCurrentId() {
return (uintptr_t) ffGetTeb()->ClientId.UniqueThread;
}
#else
#include <pthread.h>
@@ -104,6 +107,9 @@ static inline bool ffThreadJoin(FFThreadType thread, FF_A_UNUSED uint32_t timeou
#endif
pthread_join(thread, NULL);
return true;
}
static inline uintptr_t ffThreadGetCurrentId() {
return (uintptr_t) pthread_self();
}
#endif
#else // FF_HAVE_THREADS
+1 -1
View File
@@ -237,7 +237,7 @@ static const char* detectCodecByVaDrm(FFVAData* vaData, FFCodecOptions* options,
continue;
}
FF_AUTO_CLOSE_FD int fd = openat(drifd, entry->d_name, O_RDONLY | O_CLOEXEC);
FF_AUTO_CLOSE_FD int fd = openat(drifd, entry->d_name, O_RDWR | O_CLOEXEC);
if (fd < 0) {
continue;
}
+1 -1
View File
@@ -65,7 +65,7 @@ static const char* detectFrequency(FFCPUResult* cpu) {
// voltage-states5-sram stores supported <frequency / voltage> pairs of pcores from the lowest to the highest
// voltage-states1-sram stores ecores'
CFIndex propLength = CFDataGetLength(freqProperty);
if (propLength == 0 || propLength % (CFIndex) sizeof(uint32_t) * 2 != 0) {
if (propLength == 0 || propLength % (CFIndex) (sizeof(uint32_t) * 2) != 0) {
return "Invalid \"voltage-states5-sram\" length";
}
+1 -11
View File
@@ -461,7 +461,6 @@ static void detectArmName(FFstrbuf* cpuinfo, FFCPUResult* cpu, uint32_t implId)
char* line = NULL;
size_t len = 0;
uint32_t lastPartId = UINT32_MAX;
uint32_t num = 0;
while (ffStrbufGetline(&line, &len, cpuinfo)) {
if (!ffStrStartsWith(line, "CPU part\t: ")) {
continue;
@@ -529,10 +528,7 @@ static void detectArmName(FFstrbuf* cpuinfo, FFCPUResult* cpu, uint32_t implId)
}
if (lastPartId != partId) {
if (lastPartId != UINT32_MAX) {
if (num > 1) {
ffStrbufAppendF(&cpu->name, "*%u", num);
}
ffStrbufAppendS(&cpu->name, " + ");
ffStrbufAppendC(&cpu->name, '+');
}
if (name) {
ffStrbufAppendS(&cpu->name, name);
@@ -542,14 +538,8 @@ static void detectArmName(FFstrbuf* cpuinfo, FFCPUResult* cpu, uint32_t implId)
ffStrbufAppend(&cpu->name, &cpu->vendor);
}
lastPartId = partId;
num = 1;
} else {
++num;
}
}
if (num > 1) {
ffStrbufAppendF(&cpu->name, "*%u", num);
}
}
#endif
+1 -1
View File
@@ -324,7 +324,7 @@ const char* ffDetectGPU(const FFGPUOptions* options, FFlist* result) {
return "GPU detection failed";
}
bool ffGPUFillVendorByDeviceName(FFGPUResult* gpu) {
bool ffGPUDetectTypeByVendorAndName(FFGPUResult* gpu) {
if (gpu->type != FF_GPU_TYPE_UNKNOWN) {
return true;
}
+4 -1
View File
@@ -64,6 +64,9 @@ typedef struct FFGPUResult {
uint64_t deviceId;
} FFGPUResult;
static_assert(sizeof(((FFGPUResult*) NULL)->pcieSpeed) == 8, "pcieSpeed is not 8 bytes");
static_assert(sizeof(((FFGPUResult*) NULL)->psMax) == 4, "psMax has padding");
const char* ffDetectGPU(const FFGPUOptions* options, FFlist* result);
const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus);
@@ -104,4 +107,4 @@ static inline uint64_t ffGPUGeneral2Id(uint64_t originalId) {
return (1ULL << 63) | originalId;
}
bool ffGPUFillVendorByDeviceName(FFGPUResult* gpu);
bool ffGPUDetectTypeByVendorAndName(FFGPUResult* gpu);
+1 -3
View File
@@ -48,8 +48,6 @@ static double detectGpuTemp(const FFstrbuf* gpuName) {
}
#ifdef __aarch64__
#include "common/apple/cf_helpers.h"
#include <IOKit/IOKitLib.h>
static const char* detectFrequency(FFGPUResult* gpu) {
@@ -71,7 +69,7 @@ static const char* detectFrequency(FFGPUResult* gpu) {
// voltage-states9-sram stores supported <frequency / voltage> pairs of gpu from the lowest to the highest
CFIndex propLength = CFDataGetLength(freqProperty);
if (propLength == 0 || propLength % (CFIndex) sizeof(uint32_t) * 2 != 0) {
if (propLength == 0 || propLength % (CFIndex) (sizeof(uint32_t) * 2) != 0) {
return "Invalid \"voltage-states9-sram\" length";
}
+1 -1
View File
@@ -77,7 +77,7 @@ static const char* detectByPci(const FFGPUOptions* options, FFlist* gpus) {
}
}
ffGPUFillVendorByDeviceName(gpu);
ffGPUDetectTypeByVendorAndName(gpu);
}
return NULL;
+4 -4
View File
@@ -1,6 +1,7 @@
#include "gpu.h"
#if FF_HAVE_DRM
#include "gpu.h"
#include "common/strutil.h"
#include "common/io.h"
@@ -72,7 +73,6 @@ static const char* drmGetPciinfo(int drmfd, const char* drmId, struct drm_pciinf
};
if (ioctl(pcifd, PCIOCGETCONF, &pcio) < 0) {
perror("ioctl");
return "ioctl(pcifd, PCIOCGETCONF, &pc) failed";
}
@@ -188,7 +188,7 @@ const char* ffGPUDetectByDrmBSD(const FFGPUOptions* options, FFlist* gpus) {
}
}
ffGPUFillVendorByDeviceName(gpu);
ffGPUDetectTypeByVendorAndName(gpu);
}
return NULL;
@@ -201,4 +201,4 @@ const char* ffGPUDetectByDrmBSD(const FFGPUOptions* options, FFlist* gpus) {
return "Fastfetch was built without libdrm support";
}
#endif // __FreeBSD__ || __OpenBSD__
#endif // FF_HAVE_DRM
+10 -5
View File
@@ -50,7 +50,7 @@ const char* ffDrmDetectRadeon(const FFGPUOptions* options, FFGPUResult* gpu, con
}
if (ioctl(fd, DRM_IOCTL_RADEON_INFO, &(struct drm_radeon_info) {
.request = RADEON_INFO_MAX_SCLK, // MHz
.request = RADEON_INFO_MAX_SCLK, // KHz
.value = (uintptr_t) &value,
}) >= 0) {
gpu->frequency = (uint32_t) (value / 1000u);
@@ -59,7 +59,7 @@ const char* ffDrmDetectRadeon(const FFGPUOptions* options, FFGPUResult* gpu, con
if (options->driverSpecific) {
struct drm_radeon_gem_info gemInfo;
if (ioctl(fd, DRM_IOCTL_RADEON_GEM_INFO, &gemInfo) >= 0) {
// vram_usage can be bigger than vram_usage, so we use vram_size here
// vram_usage can be bigger than vram_size, so we use vram_size here
gpu->dedicated.total = gemInfo.vram_size;
gpu->shared.total = gemInfo.gart_size;
@@ -146,6 +146,7 @@ const char* ffDrmDetectAmdgpu(const FFGPUOptions* options, FFGPUResult* gpu, con
ffStrbufAppendF(&gpu->memoryType, "Unknown (%u)", devInfo.vram_type);
break;
}
#undef FF_VRAM_CASE
}
struct drm_amdgpu_memory_info memInfo;
@@ -228,12 +229,12 @@ static inline int popcountBytes(uint8_t* bytes, uint32_t length) {
length -= 4;
}
if (length >= 2) {
count += __builtin_popcountl(*(uint16_t*) bytes);
count += __builtin_popcount(*(uint16_t*) bytes);
bytes += 2;
length -= 2;
}
if (length) {
count += __builtin_popcountl(*(uint8_t*) bytes);
count += __builtin_popcount(*(uint8_t*) bytes);
}
return count;
}
@@ -306,7 +307,11 @@ const char* ffDrmDetectAsahi(FFGPUResult* gpu, int fd) {
.size = sizeof(paramsGlobal),
}) >= 0) {
// They removed `unstable_uabi_version` from the struct. Hopefully they won't introduce new ABI changes.
gpu->coreCount = (int32_t) (paramsGlobal.num_clusters_total * paramsGlobal.num_cores_per_cluster);
assert(paramsGlobal.num_clusters_total <= DRM_ASAHI_MAX_CLUSTERS);
gpu->coreCount = 0;
for (uint32_t i = 0; i < paramsGlobal.num_clusters_total; i++) {
gpu->coreCount += __builtin_popcountll(paramsGlobal.core_masks[i]);
}
gpu->frequency = paramsGlobal.max_frequency_khz / 1000;
gpu->deviceId = ffGPUGeneral2Id(paramsGlobal.chip_id);
+5 -2
View File
@@ -66,7 +66,10 @@ const char* ffDetectIntelGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverRe
}
uint32_t deviceCount = 0;
if (igclData.ffctlEnumerateDevices(igclData.apiHandle, &deviceCount, NULL)) {
// ctlEnumerateDevices MUST be called with deviceCount = 0 and devices = NULL first,
// otherwise it will be silently ignored and return CTL_RESULT_SUCCESS with deviceCount and devices unmodified.
// VERY STRANGE BEHAVIOR
if (igclData.ffctlEnumerateDevices(igclData.apiHandle, &deviceCount, NULL) != CTL_RESULT_SUCCESS) {
return "ctlEnumerateDevices(NULL) failed";
}
if (deviceCount == 0) {
@@ -74,7 +77,7 @@ const char* ffDetectIntelGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverRe
}
FF_AUTO_FREE ctl_device_adapter_handle_t* devices = malloc(deviceCount * sizeof(*devices));
if (igclData.ffctlEnumerateDevices(igclData.apiHandle, &deviceCount, devices)) {
if (igclData.ffctlEnumerateDevices(igclData.apiHandle, &deviceCount, devices) != CTL_RESULT_SUCCESS) {
return "ctlEnumerateDevices(devices) failed";
}
+53 -48
View File
@@ -7,7 +7,7 @@
#include <inttypes.h>
#include <stdint.h>
static bool pciDetectDriver(FFstrbuf* result, FFstrbuf* pciDir, FFstrbuf* buffer, FF_A_UNUSED const char* drmKey) {
static bool detectDriverFromSysfs(FFstrbuf* result, FFstrbuf* pciDir, FFstrbuf* buffer, FF_A_UNUSED const char* drmKey) {
uint32_t pciDirLength = pciDir->length;
ffStrbufAppendS(pciDir, "/driver");
char pathBuf[PATH_MAX];
@@ -90,6 +90,7 @@ static void pciDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu,
ffStrbufAppendS(pciDir, "/hwmon/");
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(pciDir->chars);
if (!dirp) {
ffStrbufSubstrBefore(pciDir, pciDirLen);
return;
}
@@ -101,6 +102,7 @@ static void pciDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu,
break;
}
if (!entry) {
ffStrbufSubstrBefore(pciDir, pciDirLen);
return;
}
ffStrbufAppendS(pciDir, entry->d_name);
@@ -407,37 +409,9 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
ffStrbufSetF(&gpu->platformApi, "DRM (%s)", drmKey);
}
pciDetectDriver(&gpu->driver, deviceDir, buffer, drmKey);
detectDriverFromSysfs(&gpu->driver, deviceDir, buffer, drmKey);
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
ffStrbufAppendS(deviceDir, "/max_link_speed");
if (ffReadFileBuffer(deviceDir->chars, buffer)) {
gpu->psMax.gen = pcieLinkSpeedToGen(buffer);
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
if (gpu->psMax.gen != FF_GPU_PCIE_SPEED_UNSET) {
ffStrbufAppendS(deviceDir, "/max_link_width");
if (ffReadFileBuffer(deviceDir->chars, buffer)) {
gpu->psMax.lanes = pcieWidthToLanes(buffer);
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
}
ffStrbufAppendS(deviceDir, "/current_link_speed");
if (ffReadFileBuffer(deviceDir->chars, buffer)) {
gpu->psCurr.gen = pcieLinkSpeedToGen(buffer);
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
if (gpu->psCurr.gen != FF_GPU_PCIE_SPEED_UNSET) {
ffStrbufAppendS(deviceDir, "/current_link_width");
if (ffReadFileBuffer(deviceDir->chars, buffer)) {
gpu->psCurr.lanes = pcieWidthToLanes(buffer);
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
}
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD) {
bool ok = false;
if (drmKey && options->driverSpecific) {
@@ -447,17 +421,17 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
if (!ok) {
pciDetectAmdSpecific(options, gpu, deviceDir, buffer);
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
ffStrbufAppendS(deviceDir, "/revision");
if (ffReadFileBuffer(deviceDir->chars, buffer)) {
char* pend;
uint64_t revision = strtoul(buffer->chars, &pend, 16);
if (pend != buffer->chars) {
ffGPUQueryAmdGpuName((uint16_t) deviceId, (uint8_t) revision, gpu);
}
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
}
ffStrbufAppendS(deviceDir, "/revision");
if (ffReadFileBuffer(deviceDir->chars, buffer)) {
char* pend;
uint64_t revision = strtoul(buffer->chars, &pend, 16);
if (pend != buffer->chars) {
ffGPUQueryAmdGpuName((uint16_t) deviceId, (uint8_t) revision, gpu);
}
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
} else if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_INTEL) {
pciDetectIntelSpecific(options, gpu, deviceDir, buffer, drmKey);
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
@@ -473,7 +447,7 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
pciDetectTempGeneral(options, gpu, deviceDir, buffer);
pciDetectZxSpecific(options, gpu, deviceDir, buffer);
} else {
ffGPUDetectDriverSpecific(options, gpu, (FFGpuDriverPciBusId) {
ffGPUDetectDriverSpecific(options, gpu, (FFGpuDriverPciBusId){
.domain = pciDomain,
.bus = pciBus,
.device = pciDevice,
@@ -485,13 +459,43 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
ffGPUFillVendorAndName(subclassId, (uint16_t) vendorId, (uint16_t) deviceId, gpu);
}
ffGPUFillVendorByDeviceName(gpu);
ffGPUDetectTypeByVendorAndName(gpu);
if (options->driverSpecific && gpu->pcieSpeed == FF_GPU_PCIE_SPEED_UNSET) {
ffStrbufAppendS(deviceDir, "/max_link_speed");
if (ffReadFileBuffer(deviceDir->chars, buffer)) {
gpu->psMax.gen = pcieLinkSpeedToGen(buffer);
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
if (gpu->psMax.gen != FF_GPU_PCIE_SPEED_UNSET) {
ffStrbufAppendS(deviceDir, "/max_link_width");
if (ffReadFileBuffer(deviceDir->chars, buffer)) {
gpu->psMax.lanes = pcieWidthToLanes(buffer);
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
}
ffStrbufAppendS(deviceDir, "/current_link_speed");
if (ffReadFileBuffer(deviceDir->chars, buffer)) {
gpu->psCurr.gen = pcieLinkSpeedToGen(buffer);
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
if (gpu->psCurr.gen != FF_GPU_PCIE_SPEED_UNSET) {
ffStrbufAppendS(deviceDir, "/current_link_width");
if (ffReadFileBuffer(deviceDir->chars, buffer)) {
gpu->psCurr.lanes = pcieWidthToLanes(buffer);
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
}
}
return NULL;
}
#if __aarch64__
#include "detection/cpu/cpu.h"
#include "detection/cpu/cpu.h"
FF_A_UNUSED static const char* drmDetectAsahiSpecific(FFGPUResult* gpu, const char* name, FF_A_UNUSED FFstrbuf* buffer, FF_A_UNUSED const char* drmKey) {
if (sscanf(name, "agx-t%lu", &gpu->deviceId) == 1) {
@@ -533,12 +537,12 @@ static const char* detectOf(FFlist* gpus, FFstrbuf* buffer, FFstrbuf* drmDir, co
gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
gpu->type = FF_GPU_TYPE_INTEGRATED;
gpu->type = FF_GPU_TYPE_INTEGRATED; // Open Firmware is only used on integrated GPUs
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
gpu->pcieSpeed = FF_GPU_PCIE_SPEED_UNSET;
pciDetectDriver(&gpu->driver, drmDir, buffer, drmKey);
detectDriverFromSysfs(&gpu->driver, drmDir, buffer, drmKey);
#ifdef __aarch64__
if (ffStrbufEqualS(&gpu->driver, "asahi")) {
@@ -555,7 +559,7 @@ static const char* detectOf(FFlist* gpus, FFstrbuf* buffer, FFstrbuf* drmDir, co
ffStrbufSetStatic(&gpu->vendor, "Broadcom"); // Raspberry Pi
} else {
ffStrbufSetS(&gpu->vendor, compatible);
gpu->vendor.chars[0] = (char) toupper(compatible[0]);
gpu->vendor.chars[0] = (char) toupper((uint8_t) compatible[0]);
}
}
@@ -584,10 +588,11 @@ static const char* drmDetectGPUs(const FFGPUOptions* options, FFlist* gpus) {
ffStrbufAppendS(&drmDir, entry->d_name);
ffStrbufAppendS(&drmDir, "/device/modalias");
if (!ffReadFileBuffer(drmDir.chars, &buffer)) {
ffReadFileBuffer(drmDir.chars, &buffer);
ffStrbufSubstrBefore(&drmDir, drmDir.length - (uint32_t) strlen("/modalias"));
if (!buffer.length) {
continue;
}
ffStrbufSubstrBefore(&drmDir, drmDir.length - (uint32_t) strlen("/modalias"));
if (ffStrbufStartsWithS(&buffer, "pci:")) {
detectPci(options, gpus, &buffer, &drmDir, entry->d_name);
+14
View File
@@ -190,6 +190,20 @@ const char* ffDetectMthreadsGpuInfo(const FFGpuDriverCondition* cond, FFGpuDrive
}
}
if (result.psCurr || result.psMax) {
MtmlPciInfo pciInfo;
if (mtmlData.ffmtmlDeviceGetPciInfo(device, &pciInfo) == MTML_SUCCESS) {
if (result.psCurr) {
result.psCurr->lanes = (uint16_t) pciInfo.pciCurWidth;
result.psCurr->gen = (uint16_t) pciInfo.pciCurGen;
}
if (result.psMax) {
result.psMax->lanes = (uint16_t) pciInfo.pciMaxWidth;
result.psMax->gen = (uint16_t) pciInfo.pciMaxGen;
}
}
}
return NULL;
#else
+51 -40
View File
@@ -21,7 +21,7 @@
#define GUID_DEVCLASS_DISPLAY_STRING L"{4d36e968-e325-11ce-bfc1-08002be10318}" // Found in <devguid.h>
static bool queryPciDeviceInfo(FFGPUResult* gpu, D3DKMT_DEVICE_IDS* outDeviceIds) {
static bool queryPciDeviceInfo(FFGPUResult* gpu, D3DKMT_DEVICE_IDS* outDeviceIds, bool queryPcieGen) {
FF_DEBUG("Query PCI device info: %08llX", gpu->deviceId);
static FFlist deviceIdsCache;
@@ -107,42 +107,44 @@ static bool queryPciDeviceInfo(FFGPUResult* gpu, D3DKMT_DEVICE_IDS* outDeviceIds
FF_DEBUG("Failed to get PCI bus number");
}
DEVPROPTYPE propType;
if (queryPcieGen) {
DEVPROPTYPE propType;
pciBufLen = sizeof(entry->maxLinkSpeed);
// Reports PCEe gen despite the PKEY name
CONFIGRET ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_MaxLinkSpeed, &propType, (PBYTE) &entry->maxLinkSpeed, &pciBufLen, 0);
if (ret == CR_SUCCESS) {
FF_DEBUG("PCIe max GEN: %u", entry->maxLinkSpeed);
} else {
FF_DEBUG("Failed to get PCIe max GEN: %s", ffDebugConfigRet(ret));
}
if (entry->maxLinkSpeed != FF_GPU_PCIE_SPEED_UNSET) {
pciBufLen = sizeof(entry->maxLinkWidth);
ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_MaxLinkWidth, &propType, (PBYTE) &entry->maxLinkWidth, &pciBufLen, 0);
pciBufLen = sizeof(entry->maxLinkSpeed);
// Reports PCIe gen despite the PKEY name
CONFIGRET ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_MaxLinkSpeed, &propType, (PBYTE) &entry->maxLinkSpeed, &pciBufLen, 0);
if (ret == CR_SUCCESS) {
FF_DEBUG("PCIe max link width: %u", entry->maxLinkWidth);
FF_DEBUG("PCIe max GEN: %u", entry->maxLinkSpeed);
} else {
FF_DEBUG("Failed to get PCIe max link width: %s", ffDebugConfigRet(ret));
FF_DEBUG("Failed to get PCIe max GEN: %s", ffDebugConfigRet(ret));
}
}
pciBufLen = sizeof(entry->currentLinkSpeed);
ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_CurrentLinkSpeed, &propType, (PBYTE) &entry->currentLinkSpeed, &pciBufLen, 0);
if (ret == CR_SUCCESS) {
FF_DEBUG("PCIe GEN: %u", entry->currentLinkSpeed);
} else {
FF_DEBUG("Failed to get PCIe GEN: %s", ffDebugConfigRet(ret));
}
if (entry->maxLinkSpeed != FF_GPU_PCIE_SPEED_UNSET) {
pciBufLen = sizeof(entry->maxLinkWidth);
ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_MaxLinkWidth, &propType, (PBYTE) &entry->maxLinkWidth, &pciBufLen, 0);
if (ret == CR_SUCCESS) {
FF_DEBUG("PCIe max link width: %u", entry->maxLinkWidth);
} else {
FF_DEBUG("Failed to get PCIe max link width: %s", ffDebugConfigRet(ret));
}
}
if (entry->currentLinkSpeed != FF_GPU_PCIE_SPEED_UNSET) {
pciBufLen = sizeof(entry->currentLinkWidth);
ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_CurrentLinkWidth, &propType, (PBYTE) &entry->currentLinkWidth, &pciBufLen, 0);
pciBufLen = sizeof(entry->currentLinkSpeed);
ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_CurrentLinkSpeed, &propType, (PBYTE) &entry->currentLinkSpeed, &pciBufLen, 0);
if (ret == CR_SUCCESS) {
FF_DEBUG("PCIe current link width: %u", entry->currentLinkWidth);
FF_DEBUG("PCIe GEN: %u", entry->currentLinkSpeed);
} else {
FF_DEBUG("Failed to get PCIe current link width: %s", ffDebugConfigRet(ret));
FF_DEBUG("Failed to get PCIe GEN: %s", ffDebugConfigRet(ret));
}
if (entry->currentLinkSpeed != FF_GPU_PCIE_SPEED_UNSET) {
pciBufLen = sizeof(entry->currentLinkWidth);
ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_CurrentLinkWidth, &propType, (PBYTE) &entry->currentLinkWidth, &pciBufLen, 0);
if (ret == CR_SUCCESS) {
FF_DEBUG("PCIe current link width: %u", entry->currentLinkWidth);
} else {
FF_DEBUG("Failed to get PCIe current link width: %s", ffDebugConfigRet(ret));
}
}
}
}
@@ -151,13 +153,16 @@ static bool queryPciDeviceInfo(FFGPUResult* gpu, D3DKMT_DEVICE_IDS* outDeviceIds
FF_LIST_FOR_EACH (CacheEntry, entry, deviceIdsCache) {
if (gpu->deviceId == entry->adapterAddress) {
FF_DEBUG("Cache hit for adapter address: %08llX", gpu->deviceId);
if (outDeviceIds->VendorID != -1u) {
if (outDeviceIds->VendorID == -1u) {
*outDeviceIds = entry->deviceIds;
}
gpu->psMax.gen = (uint16_t) entry->maxLinkSpeed;
gpu->psMax.lanes = (uint16_t) entry->maxLinkWidth;
gpu->psCurr.gen = (uint16_t) entry->currentLinkSpeed;
gpu->psCurr.lanes = (uint16_t) entry->currentLinkWidth;
if (queryPcieGen) {
gpu->psMax.gen = (uint16_t) entry->maxLinkSpeed;
gpu->psMax.lanes = (uint16_t) entry->maxLinkWidth;
gpu->psCurr.gen = (uint16_t) entry->currentLinkSpeed;
gpu->psCurr.lanes = (uint16_t) entry->currentLinkWidth;
}
return true;
}
}
@@ -220,7 +225,7 @@ static void ffStrbufSetWS(FFstrbuf* strbuf, const char16_t* str) {
static void closeDxgfd(void) {
if (dxgfd >= 0) {
close(dxgfd);
dxgfd = 0;
dxgfd = -2;
FF_DEBUG("Closed /dev/dxg file descriptor");
}
}
@@ -289,7 +294,7 @@ ffGPUDetectWsl2
});
if (!NT_SUCCESS(status)) {
FF_DEBUG("KMTQAITYPE_ADAPTERTYPE query failed for adapter #%u: %s", i, ffDebugNtStatus(status));
continue;
goto close_adapter;
}
if (adapterType.SoftwareDevice) {
FF_DEBUG("Skipping software adapter #%u", i);
@@ -371,9 +376,9 @@ ffGPUDetectWsl2
FF_DEBUG("KMTQAITYPE_PHYSICALADAPTERDEVICEIDS query failed for adapter #%u: %s", i, ffDebugNtStatus(status));
}
#if _WIN32
if (adapterAddress.BusNumber != -1u) {
if (queryPciDeviceInfo(gpu, &deviceIds.DeviceIds) && gpu->vendor.length == 0) {
#if _WIN32 && FF_WIN81_COMPAT
if (adapterAddress.BusNumber != -1u && (deviceIds.DeviceIds.VendorID == -1u || options->driverSpecific)) {
if (queryPciDeviceInfo(gpu, &deviceIds.DeviceIds, options->driverSpecific) && gpu->vendor.length == 0) {
ffStrbufSetStatic(&gpu->vendor, ffGPUGetVendorString(deviceIds.DeviceIds.VendorID));
}
}
@@ -448,6 +453,12 @@ ffGPUDetectWsl2
FF_DEBUG("Attempting to query vendor name via registry for adapter #%u", i);
queryVendorNameViaRegistry(&gpu->vendor, adapter->hAdapter);
}
#if !FF_WIN81_COMPAT
if (adapterAddress.BusNumber != -1u && options->driverSpecific && gpu->pcieSpeed == FF_GPU_PCIE_SPEED_UNSET) {
queryPciDeviceInfo(gpu, &deviceIds.DeviceIds, options->driverSpecific);
}
#endif
#endif
if (gpu->name.length == 0) {
@@ -596,7 +607,7 @@ ffGPUDetectWsl2
}
if (gpu->type == FF_GPU_TYPE_UNKNOWN) {
if (ffGPUFillVendorByDeviceName(gpu)) {
if (ffGPUDetectTypeByVendorAndName(gpu)) {
// OK
}
#if _WIN32
+11 -6
View File
@@ -111,8 +111,7 @@ static const char* getMediaByMediaRemote(FFMediaResult* result, bool saveCover)
}
#if !FF_MODULE_DISABLE_MEDIA
__attribute__((visibility("default"), used))
int ffPrintMediaByMediaRemote(bool saveCover) {
__attribute__((visibility("default"), used)) int ffPrintMediaByMediaRemote(int saveCover) {
FFMediaResult media = {
.status = ffStrbufCreate(),
.song = ffStrbufCreate(),
@@ -122,7 +121,7 @@ int ffPrintMediaByMediaRemote(bool saveCover) {
.player = ffStrbufCreate(),
.cover = ffStrbufCreate(),
};
if (getMediaByMediaRemote(&media, saveCover) != NULL) {
if (getMediaByMediaRemote(&media, !!saveCover) != NULL) {
return 1;
}
ffStrbufAppendC(&media.status, '\n');
@@ -157,13 +156,19 @@ int ffPrintMediaByMediaRemote(bool saveCover) {
static const char* getMediaByAuthorizedProcess(FFMediaResult* result, bool saveCover) {
// #1737
FF_STRBUF_AUTO_DESTROY script = ffStrbufCreateF("import ctypes;ctypes.CDLL('%s').ffPrintMediaByMediaRemote(%s)", instance.state.platform.exePath.chars, saveCover ? "True" : "False");
FF_STRBUF_AUTO_DESTROY script = ffStrbufCreateF("require DynaLoader;\
my $so = DynaLoader::dl_load_file('%s', 0);\
my $sym = DynaLoader::dl_find_symbol($so, 'ffPrintMediaByMediaRemote');\
DynaLoader::dl_install_xsub('fn', $sym, __FILE__);\
exit(fn(%c))",
instance.state.platform.exePath.chars,
saveCover ? '1' : '0');
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
const char* error = ffProcessAppendStdOut(
&buffer,
(char* const[]) { "/usr/bin/python3", // Must be signed by Apple. Homebrew python doesn't work
"-c",
(char* const[]) { "/usr/bin/perl", // Must be signed by Apple. Homebrew version doesn't work
"-e",
script.chars,
nil });
if (error) {
+8 -1
View File
@@ -9,8 +9,15 @@ const char* ffDetectMemory(FFMemoryResult* ram) {
// vm.stats.vm.* are int values
int32_t pagesFree = ffSysctlGetInt("vm.stats.vm.v_free_count", 0) + ffSysctlGetInt("vm.stats.vm.v_inactive_count", 0) + ffSysctlGetInt("vm.stats.vm.v_cache_count", 0);
int64_t bytesCache = ffSysctlGetInt64("vfs.bufspace", 0);
ram->bytesUsed = ram->bytesTotal - (uint64_t) pagesFree * instance.state.platform.sysinfo.pageSize;
ram->bytesUsed = ram->bytesTotal - (uint64_t) pagesFree * instance.state.platform.sysinfo.pageSize - (uint64_t) bytesCache;
int64_t bytesArc = ffSysctlGetInt64("kstat.zfs.misc.arcstats.size", 0);
if (bytesArc > 0) bytesArc -= ffSysctlGetInt64("kstat.zfs.misc.arcstats.c_min", 0);
if (bytesArc > 0 && (uint64_t) bytesArc < ram->bytesUsed) {
ram->bytesUsed -= (uint64_t) bytesArc;
}
return NULL;
}
+58 -19
View File
@@ -1,8 +1,5 @@
#include "memory.h"
#include "common/io.h"
#include "common/mallocHelper.h"
#include <inttypes.h>
const char* ffDetectMemory(FFMemoryResult* ram) {
char buf[PROC_FILE_BUFFSIZ];
@@ -21,35 +18,35 @@ const char* ffDetectMemory(FFMemoryResult* ram) {
sReclaimable = 0;
char* token = NULL;
if ((token = strstr(buf, "MemTotal:")) != NULL) {
memTotal = strtoul(token + strlen("MemTotal:"), NULL, 10);
if ((token = memmem(buf, (size_t) nRead, "MemTotal:", strlen("MemTotal:"))) != NULL) {
memTotal = (uint64_t) strtoull(token + strlen("MemTotal:"), NULL, 10);
} else {
return "MemTotal not found in /proc/meminfo";
}
if ((token = strstr(buf, "MemAvailable:")) != NULL) {
memAvailable = strtoul(token + strlen("MemAvailable:"), NULL, 10);
if ((token = memmem(buf, (size_t) nRead, "MemAvailable:", strlen("MemAvailable:"))) != NULL) {
memAvailable = (uint64_t) strtoull(token + strlen("MemAvailable:"), NULL, 10);
}
if (memAvailable == 0 || memAvailable >= memTotal) // MemAvailable can be unreasonable. #1988
{
if ((token = strstr(buf, "MemFree:")) != NULL) {
memFree = strtoul(token + strlen("MemFree:"), NULL, 10);
if (memAvailable == 0 || memAvailable >= memTotal) { // MemAvailable can be unreasonable. #1988
if ((token = memmem(buf, (size_t) nRead, "MemFree:", strlen("MemFree:"))) != NULL) {
memFree = (uint64_t) strtoull(token + strlen("MemFree:"), NULL, 10);
}
if ((token = strstr(buf, "Buffers:")) != NULL) {
buffers = strtoul(token + strlen("Buffers:"), NULL, 10);
if ((token = memmem(buf, (size_t) nRead, "Buffers:", strlen("Buffers:"))) != NULL) {
buffers = (uint64_t) strtoull(token + strlen("Buffers:"), NULL, 10);
}
if ((token = strstr(buf, "Cached:")) != NULL) {
cached = strtoul(token + strlen("Cached:"), NULL, 10);
if ((token = memmem(buf, (size_t) nRead, "Cached:", strlen("Cached:"))) != NULL) {
cached = (uint64_t) strtoull(token + strlen("Cached:"), NULL, 10);
}
if ((token = strstr(buf, "Shmem:")) != NULL) {
shmem = strtoul(token + strlen("Shmem:"), NULL, 10);
if ((token = memmem(buf, (size_t) nRead, "Shmem:", strlen("Shmem:"))) != NULL) {
shmem = (uint64_t) strtoull(token + strlen("Shmem:"), NULL, 10);
}
if ((token = strstr(buf, "SReclaimable:")) != NULL) {
sReclaimable = strtoul(token + strlen("SReclaimable:"), NULL, 10);
if ((token = memmem(buf, (size_t) nRead, "SReclaimable:", strlen("SReclaimable:"))) != NULL) {
sReclaimable = (uint64_t) strtoull(token + strlen("SReclaimable:"), NULL, 10);
}
memAvailable = memFree + buffers + cached + sReclaimable - shmem;
@@ -58,5 +55,47 @@ const char* ffDetectMemory(FFMemoryResult* ram) {
ram->bytesTotal = memTotal * 1024lu;
ram->bytesUsed = (memTotal - memAvailable) * 1024lu;
uint64_t arcSize = 0;
nRead = ffReadFileData("/proc/spl/kstat/zfs/arcstats", ARRAY_SIZE(buf) - 1, buf);
if (nRead > 0) {
buf[nRead] = '\0';
// 24 1 0x01 148 40256 2053603602 851614020716
// name type data
// hits 4 752
// Skip first line
const char* p = memchr(buf, '\n', (size_t) nRead);
if (__builtin_expect(p != NULL, true)) {
++p;
nRead -= (p - buf);
assert(nRead > 0);
// Find line offset of data
const char* pData = memmem(p, (size_t) nRead, "data\n", strlen("data\n"));
if (__builtin_expect(pData != NULL, true)) {
uint32_t dataOffset = (uint32_t) (pData - p);
p += dataOffset + strlen("data\n");
nRead -= (ssize_t) (dataOffset + strlen("data\n"));
assert(nRead > 0);
if ((token = memmem(p, (size_t) nRead, "\nsize ", strlen("\nsize "))) != NULL) {
arcSize = (uint64_t) strtoull(token + 1 + dataOffset, NULL, 10);
if (arcSize > 0) {
uint64_t arcMin = 0;
if ((token = memmem(p, (size_t) nRead, "\nc_min ", strlen("\nc_min "))) != NULL) {
arcMin = (uint64_t) strtoull(token + 1 + dataOffset, NULL, 10);
if (arcSize > arcMin) {
arcSize -= arcMin;
if (ram->bytesUsed > arcSize) {
ram->bytesUsed -= arcSize;
}
}
}
}
}
}
}
}
return NULL;
}
+6
View File
@@ -14,5 +14,11 @@ const char* ffDetectMemory(FFMemoryResult* ram) {
ram->bytesTotal = (uint64_t) buf.npages * instance.state.platform.sysinfo.pageSize;
ram->bytesUsed = ((uint64_t) buf.active + (uint64_t) buf.inactive + (uint64_t) buf.wired) * instance.state.platform.sysinfo.pageSize;
int64_t bytesArc = ffSysctlGetInt64("kstat.zfs.misc.arcstats.size", 0);
if (bytesArc > 0) bytesArc -= ffSysctlGetInt64("kstat.zfs.misc.arcstats.c_min", 0);
if (bytesArc > 0 && (uint64_t) bytesArc < ram->bytesUsed) {
ram->bytesUsed -= (uint64_t) bytesArc;
}
return NULL;
}
+36 -2
View File
@@ -1,9 +1,43 @@
#include "memory.h"
#include <unistd.h>
#include <kstat.h>
static inline void kstatFreeWrap(kstat_ctl_t** pkc) {
assert(pkc);
if (*pkc) {
kstat_close(*pkc);
}
}
const char* ffDetectMemory(FFMemoryResult* ram) {
ram->bytesTotal = (uint64_t) sysconf(_SC_PHYS_PAGES) * instance.state.platform.sysinfo.pageSize;
ram->bytesUsed = ram->bytesTotal - (uint64_t) sysconf(_SC_AVPHYS_PAGES) * instance.state.platform.sysinfo.pageSize;
uint64_t pageSize = instance.state.platform.sysinfo.pageSize;
ram->bytesTotal = (uint64_t) sysconf(_SC_PHYS_PAGES) * pageSize;
ram->bytesUsed = ram->bytesTotal - (uint64_t) sysconf(_SC_AVPHYS_PAGES) * pageSize;
FF_A_CLEANUP(kstatFreeWrap) kstat_ctl_t* kc = kstat_open();
if (kc != NULL) {
kstat_t* ksp = kstat_lookup(kc, "zfs", -1, "arcstats");
if (ksp != NULL && kstat_read(kc, ksp, NULL) != -1) {
kstat_named_t* kn_size = (kstat_named_t*) kstat_data_lookup(ksp, "size");
kstat_named_t* kn_cmin = (kstat_named_t*) kstat_data_lookup(ksp, "c_min");
if (kn_size != NULL && kn_cmin != NULL &&
kn_size->data_type == KSTAT_DATA_UINT64 &&
kn_cmin->data_type == KSTAT_DATA_UINT64) {
uint64_t arcSize = kn_size->value.ui64;
uint64_t arcMin = kn_cmin->value.ui64;
if (arcSize > arcMin) {
uint64_t reclaimableArc = arcSize - arcMin;
if (ram->bytesUsed > reclaimableArc) {
ram->bytesUsed -= reclaimableArc;
}
}
}
}
}
return NULL;
}
+37 -2
View File
@@ -208,7 +208,7 @@ FF_A_UNUSED static bool detectDebianDerived(FFOSResult* result) {
ffStrbufSetStatic(&result->idLike, "debian");
return true;
} else if (access("/usr/bin/pveversion", X_OK) == 0) {
ffStrbufSetStatic(&result->id, "pve");
ffStrbufSetStatic(&result->id, "proxmox");
ffStrbufSetStatic(&result->idLike, "debian");
ffStrbufSetStatic(&result->name, "Proxmox VE");
ffStrbufClear(&result->versionID);
@@ -220,8 +220,30 @@ FF_A_UNUSED static bool detectDebianDerived(FFOSResult* result) {
NULL,
}) == NULL) { // 8.2.2
ffStrbufTrimRightSpace(&result->versionID);
ffStrbufSetStatic(&result->prettyName, "Proxmox VE ");
ffStrbufAppend(&result->prettyName, &result->versionID);
} else {
ffStrbufSetStatic(&result->prettyName, "Proxmox VE");
}
return true;
} else if (access("/usr/sbin/proxmox-backup-manager", X_OK) == 0) {
ffStrbufSetStatic(&result->id, "proxmox");
ffStrbufSetStatic(&result->idLike, "debian");
ffStrbufSetStatic(&result->name, "Proxmox Backup Server");
ffStrbufClear(&result->versionID);
if (ffProcessAppendStdOut(&result->versionID, (char* const[]) {
"/usr/bin/dpkg-query",
"--showformat=${version}",
"--show",
"proxmox-backup-server",
NULL,
}) == NULL) {
ffStrbufTrimRightSpace(&result->versionID);
ffStrbufSetStatic(&result->prettyName, "Proxmox Backup Server ");
ffStrbufAppend(&result->prettyName, &result->versionID);
} else {
ffStrbufSetStatic(&result->prettyName, "Proxmox Backup Server");
}
ffStrbufSetF(&result->prettyName, "Proxmox VE %s", result->versionID.chars);
return true;
} else if (ffPathExists("/etc/rpi-issue", FF_PATHTYPE_FILE)) {
// Raspberry Pi OS
@@ -330,6 +352,17 @@ FF_A_UNUSED static void detectDeepinEnhancement(FFOSResult* result) {
}
}
FF_A_UNUSED static void detectAstraVersion(FFOSResult* result) {
// `PRETTY_NAME` is just `Astra Linux`; the version is in `VERSION_ID`, e.g. `2.12_x86-64`
if (result->version.length == 0) { // Should be empty. Just in case
ffStrbufAppendSUntilC(&result->version, result->versionID.chars, '_');
}
if (result->version.length > 0) {
ffStrbufAppendC(&result->prettyName, ' ');
ffStrbufAppend(&result->prettyName, &result->version);
}
}
static void detectOS(FFOSResult* os) {
#ifdef FF_CUSTOM_OS_RELEASE_PATH
parseOsRelease(FF_STR(FF_CUSTOM_OS_RELEASE_PATH), os);
@@ -389,6 +422,8 @@ void ffDetectOSImpl(FFOSResult* os) {
}
} else if (ffStrbufEqualS(&os->id, "deepin")) {
detectDeepinEnhancement(os);
} else if (ffStrbufEqualS(&os->id, "astra")) {
detectAstraVersion(os);
}
#endif
}
@@ -19,6 +19,7 @@
#define _PATH_LOCALBASE "/usr/pkg"
#elif _WIN32
#include "common/windows/registry.h"
#include "common/windows/version.h"
#include <windows.h>
@@ -248,6 +249,12 @@ static bool getShellVersionWinPowerShell(FFstrbuf* exe, FFstrbuf* version) {
return true;
}
FF_AUTO_CLOSE_FD HANDLE hKey = NULL;
if (ffRegOpenSubkeyForRead(ffRegGetRootKeyHandle(HKEY_LOCAL_MACHINE), L"SOFTWARE\\Microsoft\\PowerShell\\3\\PowerShellEngine", &hKey, NULL) && ffRegReadStrbuf(hKey, L"PowerShellVersion", version, NULL)) {
return true;
}
// Extremely slow
return ffProcessAppendStdOut(version, (char* const[]) { exe->chars, "-NoLogo", "-NoProfile", "-Command", "$PSVersionTable.PSVersion.ToString()", NULL }) == NULL;
}
#endif
+11 -6
View File
@@ -191,14 +191,19 @@ static const char* getWslg(FFstrbuf* result) {
return "Failed to read /mnt/wslg/versions.txt";
}
if (!ffStrbufStartsWithS(result, "WSLg ")) {
return "Failed to find WSLg version";
if (ffStrbufStartsWithS(result, "WSLg: ")) { // WSL 2.9.3+
ffStrbufSubstrBeforeFirstC(result, '\n');
ffStrbufSubstrAfter(result, (uint32_t) (strlen("WSLg: ") - 1));
} else if (ffStrbufStartsWithS(result, "WSLg ")) {
ffStrbufSubstrBeforeFirstC(result, '\n');
ffStrbufSubstrBeforeFirstC(result, '+');
ffStrbufSubstrAfterFirstC(result, ':');
ffStrbufTrimLeft(result, ' ');
} else {
ffStrbufClear(result);
return "Failed to parse WSLg version from /mnt/wslg/versions.txt";
}
ffStrbufSubstrBeforeFirstC(result, '\n');
ffStrbufSubstrBeforeFirstC(result, '+');
ffStrbufSubstrAfterFirstC(result, ':');
ffStrbufTrimLeft(result, ' ');
return NULL;
}
#endif
+26 -1
View File
@@ -804,7 +804,7 @@ static const FFlogo A[] = {
#ifdef FASTFETCH_DATATEXT_LOGO_JANUSLINUX
// Ataraxia
{
.names = { "Ataraxia Linux", "Ataraxia" },
.names = { "Ataraxia" }, // New name of JanusLinux
.lines = FASTFETCH_DATATEXT_LOGO_JANUSLINUX,
.colors = {
FF_COLOR_FG_BLUE,
@@ -876,6 +876,31 @@ static const FFlogo A[] = {
},
},
#endif
#ifdef FASTFETCH_DATATEXT_LOGO_AZURELINUX
// AzureLinux
{
.names = { "AzureLinux" },
.lines = FASTFETCH_DATATEXT_LOGO_AZURELINUX,
.colors = {
FF_COLOR_FG_GREEN,
FF_COLOR_FG_BLUE,
FF_COLOR_FG_WHITE, // konsole...
},
},
#endif
#ifdef FASTFETCH_DATATEXT_LOGO_AZURELINUX2
// AzureLinux2
{
.names = { "AzureLinux2" },
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_AZURELINUX2,
.colors = {
FF_COLOR_FG_GREEN,
FF_COLOR_FG_BLUE,
FF_COLOR_FG_WHITE, // konsole...
},
},
#endif
// LAST
{},
};
+16
View File
@@ -0,0 +1,16 @@
$1_((((((((((_
$1_(((((((((($2/////////
$1_((((((($2////////////
$1_(((((($2/////////////
$1_(((((($2/////////////
$1_((((((($2\\\\\\\\\\\\\
$1_((((((((($2\\\\\\\\\\\\\
$1_((((((($3.........$2\\\\\\\\
$1_((((($3...............$2\\\\\\
$1_((((($3..................$2\\\\\
$1_((((($3.....................$2\\\\
$1_((((($3.......................$2\\\\
$1_((((($3.........................$2\\\\
$1_((((($3...........................$2\\\
$1_((((($3.............................$2\\
$1_(((($3................................$2\
+16
View File
@@ -0,0 +1,16 @@
$1############
$1###########$2@@@@@@@@@
$1########$2@@@@@@@@@@@@
$1#######$2@@@@@@@@@@@@@
$1#######$2@@@@@@@@@@@@@
$1########$2@@@@@@@@@@@@@
$1##########$2@@@@@@@@@@@@@
$1########$3&&&&&&&&&$2@@@@@@@@
$1######$3&&&&&&&&&&&&&&&$2@@@@@@
$1######$3&&&&&&&&&&&&&&&&&&$2@@@@@
$1######$3&&&&&&&&&&&&&&&&&&&&&$2@@@@
$1######$3&&&&&&&&&&&&&&&&&&&&&&&$2@@@@
$1######$3&&&&&&&&&&&&&&&&&&&&&&&&&$2@@@@
$1######$3&&&&&&&&&&&&&&&&&&&&&&&&&&&$2@@@
$1######$3&&&&&&&&&&&&&&&&&&&&&&&&&&&&&$2@@
$1#####$3&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&$2@
+53 -8
View File
@@ -9,12 +9,12 @@ static const FFlogo C[] = {
.names = { "CachyOS" },
.lines = FASTFETCH_DATATEXT_LOGO_CACHYOS,
.colors = {
FF_COLOR_FG_CYAN,
FF_COLOR_FG_GREEN,
FF_COLOR_FG_CYAN,
FF_COLOR_FG_BLACK,
},
.colorKeys = FF_COLOR_FG_CYAN,
.colorTitle = FF_COLOR_FG_CYAN,
.colorTitle = FF_COLOR_FG_GREEN,
},
#endif
#ifdef FASTFETCH_DATATEXT_LOGO_CACHYOS_SMALL
@@ -24,10 +24,24 @@ static const FFlogo C[] = {
.type = FF_LOGO_LINE_TYPE_SMALL_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_CACHYOS_SMALL,
.colors = {
FF_COLOR_FG_GREEN,
FF_COLOR_FG_CYAN,
},
.colorKeys = FF_COLOR_FG_CYAN,
.colorTitle = FF_COLOR_FG_CYAN,
.colorTitle = FF_COLOR_FG_GREEN,
},
#endif
#ifdef FASTFETCH_DATATEXT_LOGO_CACHYOS_OLD_SMALL
// CachyOSOldSmall
{
.names = { "CachyOS_old_small" },
.type = FF_LOGO_LINE_TYPE_SMALL_BIT | FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_CACHYOS_OLD_SMALL,
.colors = {
FF_COLOR_FG_CYAN,
},
.colorKeys = FF_COLOR_FG_CYAN,
.colorTitle = FF_COLOR_FG_GREEN,
},
#endif
#ifdef FASTFETCH_DATATEXT_LOGO_CALCULATE
@@ -46,7 +60,7 @@ static const FFlogo C[] = {
#ifdef FASTFETCH_DATATEXT_LOGO_CALINIXOS
// CalinixOS
{
.names = { "Calinix", "calinixos" },
.names = { "CalinixOS" },
.lines = FASTFETCH_DATATEXT_LOGO_CALINIXOS,
.colors = {
FF_COLOR_FG_MAGENTA,
@@ -58,7 +72,7 @@ static const FFlogo C[] = {
#ifdef FASTFETCH_DATATEXT_LOGO_CALINIXOS_SMALL
// CalinixOSSmall
{
.names = { "Calinix_small", "calinixos_small" },
.names = { "CalinixOS_small" },
.type = FF_LOGO_LINE_TYPE_SMALL_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_CALINIXOS_SMALL,
.colors = {
@@ -95,7 +109,7 @@ static const FFlogo C[] = {
#ifdef FASTFETCH_DATATEXT_LOGO_CELOS
// CelOS
{
.names = { "Cel", "celos", "cel-linux", "celos-linux" },
.names = { "CelOS" },
.lines = FASTFETCH_DATATEXT_LOGO_CELOS,
.colors = {
FF_COLOR_FG_MAGENTA,
@@ -152,7 +166,7 @@ static const FFlogo C[] = {
#ifdef FASTFETCH_DATATEXT_LOGO_CEREUS
// Cereus
{
.names = { "Cereus", "Cereus Linux" },
.names = { "Cereus" },
.lines = FASTFETCH_DATATEXT_LOGO_CEREUS,
.colors = {
FF_COLOR_FG_256 "173",
@@ -218,6 +232,37 @@ static const FFlogo C[] = {
.colorTitle = FF_COLOR_FG_RED,
},
#endif
#ifdef FASTFETCH_DATATEXT_LOGO_CHIMERA_LINUX2
// Chimera2
{
.names = { "Chimera2" },
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_CHIMERA_LINUX2,
.colors = {
FF_COLOR_FG_BLUE,
FF_COLOR_FG_RED,
FF_COLOR_FG_MAGENTA,
},
.colorKeys = FF_COLOR_FG_MAGENTA,
.colorTitle = FF_COLOR_FG_RED,
},
#endif
#ifdef FASTFETCH_DATATEXT_LOGO_CHIMERA_LINUX_SMALL
// Chimera_small
{
.names = { "Chimera_small" },
.lines = FASTFETCH_DATATEXT_LOGO_CHIMERA_LINUX_SMALL,
.type = FF_LOGO_LINE_TYPE_SMALL_BIT,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_MAGENTA,
FF_COLOR_FG_BLUE,
FF_COLOR_FG_RED,
},
.colorKeys = FF_COLOR_FG_MAGENTA,
.colorTitle = FF_COLOR_FG_RED,
},
#endif
#ifdef FASTFETCH_DATATEXT_LOGO_CHONKYSEALOS
// ChonkySealOS
{
@@ -352,7 +397,7 @@ static const FFlogo C[] = {
#ifdef FASTFETCH_DATATEXT_LOGO_FEDORA_COREOS
// ContainerLinux
{
.names = { "ContainerLinux", "Container Linux", "Container Linux by CoreOS" },
.names = { "CoreOS", "Container Linux by CoreOS" },
.lines = FASTFETCH_DATATEXT_LOGO_FEDORA_COREOS,
.colors = {
FF_COLOR_FG_BLUE,
+8
View File
@@ -0,0 +1,8 @@
/''''''''''''/
/''''''''''''/
/''''''/
/''''''/
\......\
\......\
\.............../
\............./
+11 -8
View File
@@ -1,8 +1,11 @@
/''''''''''''/
/''''''''''''/
/''''''/
/''''''/
\......\
\......\
\.............../
\............./
...........
$2/,,,,$1...../
$2/,,,$1..$2,,$1../ $2()
$2/,,,,$1../
$2/,,,$1.../ $1/'\
$2/,$1...../ $2\,/
$2\,,,,,,\\ $1_
$2\,,$1....\\ $1/ \
$1\...$2,$1..\\ $2\_/
$1\..$2,,,,,,,,,,,,/
$1\$2,,$1........$2,,/
+15
View File
@@ -0,0 +1,15 @@
888888888888 $2888
$1888888888888 $2888
$1888888888888 $2888
$188888888P"' $2_,888
$1888888P' $2,jd88888
$188888P $2d88P'
$18888b $2j88' xxxxxxxxxx
$3_____ $218{ 8888888888
$38888b. $2l88, ,88" $3______
$3888888 $218b,_ ,d88P $3888888
$3888888b. $2`188bwwd88P' $3,d888888
$388888888b._ $2`"^^"'`$3.,d88888888
$3888888888888bo od888888888888
$388888888888888 88888888888888
$388888888888888 88888888888888
+7
View File
@@ -0,0 +1,7 @@
$3XXXXX $1I:
$3XXX' $1,I;
$3XX $1,f""'.,,,,
$2,, $1I: ;P"""
$2XX $1`t...f' $4jj
$2XXX. $1`"' $4.XXX
$2OOOOOC $4lXXXXX
+14 -1
View File
@@ -169,10 +169,23 @@ static const FFlogo F[] = {
.colorTitle = FF_COLOR_FG_DEFAULT,
},
#endif
#ifdef FASTFETCH_DATATEXT_LOGO_FLATCAR
// Flatcar
{
.names = { "Flatcar" },
.lines = FASTFETCH_DATATEXT_LOGO_FLATCAR,
.colors = {
FF_COLOR_FG_BLUE,
FF_COLOR_FG_DEFAULT,
},
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_DEFAULT,
},
#endif
#ifdef FASTFETCH_DATATEXT_LOGO_FILOTIMO
// Filotimo
{
.names = { "filotimo" },
.names = { "Filotimo" },
.lines = FASTFETCH_DATATEXT_LOGO_FILOTIMO,
.colors = {
FF_COLOR_FG_BLUE,
+9
View File
@@ -0,0 +1,9 @@
ΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞ
ΞΞ ΞΞΞ ΞΞΞ ΞΞ ΞΞΞ
ΞΞ ΞΞΞ Ξ Ξ ΞΞ ΞΞΞΞ
ΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞ
ΞΞ ΞΞ ΞΞ ΞΞ
Ξ ΞΞ ΞΞΞΞ Ξ ΞΞ Ξ
Ξ ΞΞ ΞΞ ΞΞ Ξ Ξ ΞΞΞ Ξ
Ξ ΞΞ ΞΞ ΞΞ Ξ ΞΞΞ ΞΞΞ Ξ
ΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞ
+2 -2
View File
@@ -19,7 +19,7 @@ static const FFlogo G[] = {
#ifdef FASTFETCH_DATATEXT_LOGO_GARUDA
// Garuda
{
.names = { "Garuda", "garuda-linux" },
.names = { "Garuda" },
.lines = FASTFETCH_DATATEXT_LOGO_GARUDA,
.colors = {
FF_COLOR_FG_RED,
@@ -167,7 +167,7 @@ static const FFlogo G[] = {
#ifdef FASTFETCH_DATATEXT_LOGO_GOLDENDOGLINUX
// GoldenDogLinux
{
.names = { "GoldenDog Linux", "GDL", "goldendoglinux" },
.names = { "GoldenDogLinux" },
.lines = FASTFETCH_DATATEXT_LOGO_GOLDENDOGLINUX,
.colors = {
FF_COLOR_FG_YELLOW,
+1 -1
View File
@@ -6,7 +6,7 @@ static const FFlogo J[] = {
#ifdef FASTFETCH_DATATEXT_LOGO_JANUSLINUX
// Januslinux
{
.names = { "januslinux", "janus" },
.names = { "januslinux" },
.lines = FASTFETCH_DATATEXT_LOGO_JANUSLINUX,
.colors = {
FF_COLOR_FG_BLUE,
+1 -1
View File
@@ -129,7 +129,7 @@ static const FFlogo K[] = {
#ifdef FASTFETCH_DATATEXT_LOGO_KISS
// KISSLinux
{
.names = { "KISS", "kiss-linux", "kisslinux" },
.names = { "KISS" },
.lines = FASTFETCH_DATATEXT_LOGO_KISS,
.colors = {
FF_COLOR_FG_MAGENTA,
+14
View File
@@ -231,6 +231,20 @@ static const FFlogo L[] = {
.colorTitle = FF_COLOR_FG_GREEN,
},
#endif
#ifdef FASTFETCH_DATATEXT_LOGO_LINUXMINT2_SMALL
// LinuxMint2Small
{
.names = { "linuxmint2_small" },
.type = FF_LOGO_LINE_TYPE_SMALL_BIT | FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_LINUXMINT2_SMALL,
.colors = {
FF_COLOR_FG_GREEN,
FF_COLOR_FG_WHITE,
},
.colorKeys = FF_COLOR_FG_GREEN,
.colorTitle = FF_COLOR_FG_GREEN,
},
#endif
#ifdef FASTFETCH_DATATEXT_LOGO_LINUXMINT_OLD
// LinuxMintOld
{
+7
View File
@@ -0,0 +1,7 @@
__________
|_ \
| $2| _____ $1|
| $2| | | | $1|
| $2| | | | $1|
| $2\__$2___/ $1|
\_________/
+10 -7
View File
@@ -1,7 +1,10 @@
__________
|_ \
| $2| _____ $1|
| $2| | | | $1|
| $2| | | | $1|
| $2\__$2___/ $1|
\_________/
____________________
| \
|_ $2| ___________ $1 |
| $2| / __ __ \$1 |
| $2| | | | | | |$1 |
| $2| | | | | | |$1 |
| $2| | | | | | |$1 |
| $2| \_/ \_/ | |$1 |
| $2\____________/_/$1 |
\___________________/
+3 -3
View File
@@ -52,7 +52,7 @@ static const FFlogo O[] = {
#ifdef FASTFETCH_DATATEXT_LOGO_OPENKYLIN
// OpenKylin
{
.names = { "openkylin", "open-kylin" },
.names = { "openKylin" },
.lines = FASTFETCH_DATATEXT_LOGO_OPENKYLIN,
.colors = {
FF_COLOR_FG_GREEN,
@@ -277,7 +277,7 @@ static const FFlogo O[] = {
#ifdef FASTFETCH_DATATEXT_LOGO_OPENMANDRIVA
// OpenMandriva
{
.names = { "openmandriva", "open-mandriva", "open_mandriva", "openmandriva lx" },
.names = { "OpenMandriva" },
.lines = FASTFETCH_DATATEXT_LOGO_OPENMANDRIVA,
.colors = {
FF_COLOR_FG_BLUE,
@@ -340,7 +340,7 @@ static const FFlogo O[] = {
#ifdef FASTFETCH_DATATEXT_LOGO_ORACLE
// Oracle
{
.names = { "oracle", "oracle linux", "oracle linux server" },
.names = { "ol", "oracle" }, // ID="ol"
.lines = FASTFETCH_DATATEXT_LOGO_ORACLE,
.colors = {
FF_COLOR_FG_RED,
+29 -4
View File
@@ -29,7 +29,7 @@ static const FFlogo P[] = {
#ifdef FASTFETCH_DATATEXT_LOGO_PARABOLA
// Parabola
{
.names = { "parabola", "parabola-gnulinux" },
.names = { "Parabola" },
.lines = FASTFETCH_DATATEXT_LOGO_PARABOLA,
.colors = {
FF_COLOR_FG_MAGENTA,
@@ -41,7 +41,7 @@ static const FFlogo P[] = {
#ifdef FASTFETCH_DATATEXT_LOGO_PARABOLA_SMALL
// ParabolaSmall
{
.names = { "parabola_small", "parabola-gnulinux_small" },
.names = { "Parabola_small", },
.type = FF_LOGO_LINE_TYPE_SMALL_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_PARABOLA_SMALL,
.colors = {
@@ -51,6 +51,19 @@ static const FFlogo P[] = {
.colorTitle = FF_COLOR_FG_MAGENTA,
},
#endif
#ifdef FASTFETCH_DATATEXT_LOGO_PARABOLA2_SMALL
// Parabola2Small
{
.names = { "Parabola2_small", },
.type = FF_LOGO_LINE_TYPE_SMALL_BIT | FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_PARABOLA2_SMALL,
.colors = {
FF_COLOR_FG_BLUE,
},
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE,
},
#endif
#ifdef FASTFETCH_DATATEXT_LOGO_PARCH
// Parch
{
@@ -171,7 +184,7 @@ static const FFlogo P[] = {
#ifdef FASTFETCH_DATATEXT_LOGO_PEROPESIS
// Peropesis
{
.names = { "Peropesis", "Peropesis Linux" },
.names = { "Peropesis" },
.lines = FASTFETCH_DATATEXT_LOGO_PEROPESIS,
.colors = {
FF_COLOR_FG_WHITE,
@@ -271,6 +284,18 @@ static const FFlogo P[] = {
},
},
#endif
#ifdef FASTFETCH_DATATEXT_LOGO_POSTMARKETOS2
// PostMarketOS2
{
.names = { "PostMarketOS2" },
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_POSTMARKETOS2,
.colors = {
FF_COLOR_FG_GREEN,
FF_COLOR_FG_WHITE,
},
},
#endif
#ifdef FASTFETCH_DATATEXT_LOGO_POSTMARKETOS_SMALL
// PostMarketOSSmall
{
@@ -286,7 +311,7 @@ static const FFlogo P[] = {
#ifdef FASTFETCH_DATATEXT_LOGO_PROXMOX
// Proxmox
{
.names = { "Proxmox", "pve" },
.names = { "Proxmox" },
.lines = FASTFETCH_DATATEXT_LOGO_PROXMOX,
.colors = {
FF_COLOR_FG_WHITE,
+7
View File
@@ -0,0 +1,7 @@
_. .d;' ,b,
_.=: `" "` ,d88}
` "888!'
}8!'
,P/
,1'
/'
+17
View File
@@ -0,0 +1,17 @@
db
d88b
d8888b
d888888b
j88888888b
!888888888b
j| J8^"888888b
d8[;__, '888888b
d88888P' '888888b
d88888P '888888b
d88888P '888888b
d88888P '1^`,.__
d88888P " ,A888b
d888888, =ooooooooooo888888b
d88888888, "J8888888888888888b
d888888888" ,d88888888888888888b
d88888888P' ,d8888888888888888888b
+12
View File
@@ -50,6 +50,18 @@ static const FFlogo Q[] = {
},
},
#endif
#ifdef FASTFETCH_DATATEXT_LOGO_QUBES_SMALL
// Qubes
{
.names = { "Qubes_small" },
.type = FF_LOGO_LINE_TYPE_SMALL_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_QUBES_SMALL,
.colors = {
FF_COLOR_FG_BLUE,
FF_COLOR_FG_MAGENTA,
},
},
#endif
#ifdef FASTFETCH_DATATEXT_LOGO_QUBYT
// Qubyt
{
+14
View File
@@ -0,0 +1,14 @@
.,dQb,.
.,qdQQQQQQQbq,.
.,qdQQQQQQQQQQQQQQQbq,.
dIQQQQQQQQP"'"1QQQQQQQQ^b
ttttI%QP'` `'1Q%^---|
tttttt |----|
tttttt |----|
tttttt |----|
tttttt |----|
ttttttti, .,;-----|
1ttttttttti, ,----------'
'"^1ttttttt|----------;,
'"^1ttt|---^-------->,
'"1|^'` "^==-:"
+2 -2
View File
@@ -157,7 +157,7 @@ static const FFlogo R[] = {
#ifdef FASTFETCH_DATATEXT_LOGO_REDSTAR
// RedstarOS
{
.names = { "redstar", "redstar-os", "redstaros" },
.names = { "Redstar" },
.lines = FASTFETCH_DATATEXT_LOGO_REDSTAR,
.colors = {
FF_COLOR_FG_RED,
@@ -257,7 +257,7 @@ static const FFlogo R[] = {
#ifdef FASTFETCH_DATATEXT_LOGO_ROSA
// RosaLinux
{
.names = { "rosa", "rosa-linux", "rosalinux" },
.names = { "ROSA" },
.lines = FASTFETCH_DATATEXT_LOGO_ROSA,
.colors = {
FF_COLOR_FG_RGB "250;250;250",
+1 -1
View File
@@ -75,7 +75,7 @@ static const FFlogo S[] = {
#ifdef FASTFETCH_DATATEXT_LOGO_SAMBABOX
// SambaBOX
{
.names = { "SambaBOX", "Profelis SambaBOX" },
.names = { "SambaBOX" },
.lines = FASTFETCH_DATATEXT_LOGO_SAMBABOX,
.colors = {
FF_COLOR_FG_YELLOW,
+12
View File
@@ -122,6 +122,18 @@ static const FFlogo T[] = {
.colorTitle = FF_COLOR_FG_256 "32",
},
#endif
#ifdef FASTFETCH_DATATEXT_LOGO_TURKISH
// Turkish
{
.names = { "Turkish", },
.lines = FASTFETCH_DATATEXT_LOGO_TURKISH,
.colors = {
FF_COLOR_FG_DEFAULT,
},
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_RED,
},
#endif
#ifdef FASTFETCH_DATATEXT_LOGO_TUXEDO_OS
// TuxedoOS
{
+20
View File
@@ -0,0 +1,20 @@
@@@@@@@@@
@@@@@@ @@
@@@@@
@@@@@
@@@@@@
@@@@@ @@@@@
@@@@@@ @@@@@@@@@@@@@
@@@@@@@ @@ @@@@@@ @
@@@@@@@@@@@ @@@@@
@@@@
@@@@
@@@@@@@@@@ @@@@@
@@@@@@@ @@ @@@@@@ @
@@@@@@ @@@@@@@@@@@@@
@@@@@ @@@@@@@
@@@@@@
@@@@@
@@@@@
@@@@@@ @@
@@@@@@@@@@
+5 -5
View File
@@ -35,7 +35,7 @@ static const FFlogo U[] = {
#ifdef FASTFETCH_DATATEXT_LOGO_UBUNTU
// Ubuntu
{
.names = { "ubuntu", "ubuntu-linux" },
.names = { "ubuntu" },
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU,
.colors = {
FF_COLOR_FG_RED,
@@ -46,7 +46,7 @@ static const FFlogo U[] = {
#ifdef FASTFETCH_DATATEXT_LOGO_UBUNTU_SMALL
// UbuntuSmall
{
.names = { "ubuntu_small", "ubuntu-linux_small" },
.names = { "ubuntu_small" },
.type = FF_LOGO_LINE_TYPE_SMALL_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_SMALL,
.colors = {
@@ -58,7 +58,7 @@ static const FFlogo U[] = {
#ifdef FASTFETCH_DATATEXT_LOGO_UBUNTU_OLD
// UbuntuOld
{
.names = { "ubuntu_old", "ubuntu-linux_old" },
.names = { "ubuntu_old" },
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_OLD,
.colors = {
@@ -87,7 +87,7 @@ static const FFlogo U[] = {
#ifdef FASTFETCH_DATATEXT_LOGO_UBUNTU_OLD2_SMALL
// UbuntuOld2Small
{
.names = { "ubuntu_old2_small", "ubuntu_old2_small" },
.names = { "ubuntu_old2_small" },
.type = FF_LOGO_LINE_TYPE_SMALL_BIT | FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_OLD2_SMALL,
.colors = {
@@ -211,7 +211,7 @@ static const FFlogo U[] = {
#ifdef FASTFETCH_DATATEXT_LOGO_ULTRAMARINE
// Ultramarine
{
.names = { "Ultramarine", "Ultramarine Linux" },
.names = { "Ultramarine" },
.lines = FASTFETCH_DATATEXT_LOGO_ULTRAMARINE,
.colors = {
FF_COLOR_FG_BLUE,
+6 -1
View File
@@ -12,7 +12,12 @@ static FF_LIBRARY_SYMBOL(ResizeImage)
}
FFLogoImageResult ffLogoPrintImageIM6(FFLogoRequestData* requestData) {
FF_LIBRARY_LOAD(imageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, "libMagickCore-6.Q16HDRI" FF_LIBRARY_EXTENSION, 8, "libMagickCore-6.Q16" FF_LIBRARY_EXTENSION, 8)
// clang-format off
FF_LIBRARY_LOAD(imageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR,
"libMagickCore-6.Q16HDRI" FF_LIBRARY_EXTENSION, 8,
"libMagickCore-6.Q16" FF_LIBRARY_EXTENSION, 8
)
// clang-format on
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR)
FFLogoImageResult result = ffLogoPrintImageImpl(requestData, &(FFIMData) {
+11 -1
View File
@@ -12,8 +12,18 @@ static FF_LIBRARY_SYMBOL(ResizeImage)
}
FFLogoImageResult ffLogoPrintImageIM7(FFLogoRequestData* requestData) {
FF_LIBRARY_LOAD(imageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, "libMagickCore-7.Q16HDRI" FF_LIBRARY_EXTENSION, 11, "libMagickCore-7.Q16" FF_LIBRARY_EXTENSION, 11, "libMagickCore-7.Q16HDRI-10" FF_LIBRARY_EXTENSION, -1 // Required for Windows
// clang-format off
#if _WIN32
FF_LIBRARY_LOAD(imageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR,
"libMagickCore-7.Q16HDRI-10" FF_LIBRARY_EXTENSION, 0
)
#else
FF_LIBRARY_LOAD(imageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR,
"libMagickCore-7.Q16HDRI" FF_LIBRARY_EXTENSION, 11,
"libMagickCore-7.Q16" FF_LIBRARY_EXTENSION, 11
)
#endif
// clang-format on
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR)
FFLogoImageResult result = ffLogoPrintImageImpl(requestData, &(FFIMData) {
+5 -2
View File
@@ -553,8 +553,11 @@ static bool printImageKitty(FFLogoRequestData* requestData, const ImageData* ima
#ifdef FF_HAVE_CHAFA
#include <chafa.h>
static bool printImageChafa(FFLogoRequestData* requestData, const ImageData* imageData) {
FF_LIBRARY_LOAD(chafa, false, "libchafa" FF_LIBRARY_EXTENSION, 1, "libchafa-0" FF_LIBRARY_EXTENSION, -1 // Required for Windows
)
#if _WIN32
FF_LIBRARY_LOAD(chafa, false, "libchafa-0" FF_LIBRARY_EXTENSION, 0)
#else
FF_LIBRARY_LOAD(chafa, false, "libchafa" FF_LIBRARY_EXTENSION, 1)
#endif
FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_symbol_map_new, false)
FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_symbol_map_apply_selectors, false)
FF_LIBRARY_LOAD_SYMBOL(chafa, chafa_canvas_config_new, false)
+11 -10
View File
@@ -7,6 +7,14 @@
#define FF_BLUETOOTHRADIO_DISPLAY_NAME "Bluetooth Radio"
static void destroyBluetoothRadios(FFlist* radios) {
FF_LIST_FOR_EACH (FFBluetoothRadioResult, radio, *radios) {
ffStrbufDestroy(&radio->name);
ffStrbufDestroy(&radio->address);
ffStrbufDestroy(&radio->vendor);
}
}
static void printDevice(FFBluetoothRadioOptions* options, const FFBluetoothRadioResult* radio, uint8_t index) {
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
if (options->moduleArgs.key.length == 0) {
@@ -113,14 +121,11 @@ bool ffPrintBluetoothRadio(FFBluetoothRadioOptions* options) {
} else {
ffPrintError(FF_BLUETOOTHRADIO_DISPLAY_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "No devices detected");
}
destroyBluetoothRadios(&radios);
return false;
}
FF_LIST_FOR_EACH (FFBluetoothRadioResult, radio, radios) {
ffStrbufDestroy(&radio->name);
ffStrbufDestroy(&radio->address);
ffStrbufDestroy(&radio->vendor);
}
destroyBluetoothRadios(&radios);
return true;
}
@@ -171,11 +176,7 @@ bool ffGenerateBluetoothRadioJsonResult(FF_A_UNUSED FFBluetoothRadioOptions* opt
yyjson_mut_obj_add_bool(doc, obj, "connectable", item->connectable);
}
FF_LIST_FOR_EACH (FFBluetoothRadioResult, radio, results) {
ffStrbufDestroy(&radio->name);
ffStrbufDestroy(&radio->address);
ffStrbufDestroy(&radio->vendor);
}
destroyBluetoothRadios(&results);
return true;
}
-4
View File
@@ -47,10 +47,6 @@ bool ffPrintCPU(FFCPUOptions* options) {
FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate();
if (cpu.packages > 1) {
ffStrbufAppendF(&str, "%u x ", cpu.packages);
}
if (cpu.name.length > 0) {
ffStrbufAppend(&str, &cpu.name);
} else if (cpu.vendor.length > 0) {
+26
View File
@@ -1139,6 +1139,32 @@ int main(void) {
VERIFY(strbuf.allocated == 0);
ffStrbufDestroy(&strbuf);
#if FASTFETCH_STRBUF_DEFAULT_ALLOC == 32
ffStrbufEnsureFreeNoCheck(&strbuf, 1);
VERIFY(strbuf.allocated == 32);
ffStrbufDestroy(&strbuf);
ffStrbufEnsureFreeNoCheck(&strbuf, 31);
VERIFY(strbuf.allocated == 32);
ffStrbufDestroy(&strbuf);
ffStrbufEnsureFreeNoCheck(&strbuf, 32);
VERIFY(strbuf.allocated == 64);
ffStrbufDestroy(&strbuf);
ffStrbufEnsureFreeNoCheck(&strbuf, 33);
VERIFY(strbuf.allocated == 64);
ffStrbufDestroy(&strbuf);
ffStrbufEnsureFreeNoCheck(&strbuf, 63);
VERIFY(strbuf.allocated == 64);
ffStrbufDestroy(&strbuf);
ffStrbufEnsureFreeNoCheck(&strbuf, 64);
VERIFY(strbuf.allocated == 128);
ffStrbufDestroy(&strbuf);
#endif
// Success
puts("\e[32mAll tests passed!" FASTFETCH_TEXT_MODIFIER_RESET);
}