diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000000..17a551e822
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,81 @@
+BasedOnStyle: LLVM
+Language: Cpp
+
+UseTab: Never
+IndentWidth: 4
+TabWidth: 4
+ContinuationIndentWidth: 4
+
+ColumnLimit: 0
+ReflowComments: true
+
+BreakBeforeBraces: Attach
+BreakBeforeCloseBracketBracedList: true
+BraceWrapping:
+ AfterControlStatement: false
+ AfterEnum: false
+ AfterFunction: false
+ AfterStruct: false
+ AfterUnion: false
+ AfterExternBlock: false
+ BeforeElse: false
+ BeforeCatch: false
+ SplitEmptyFunction: false
+ SplitEmptyRecord: false
+ SplitEmptyNamespace: false
+IndentExternBlock: NoIndent
+
+AllowShortIfStatementsOnASingleLine: AllIfsAndElse
+AllowShortLoopsOnASingleLine: true
+AllowShortBlocksOnASingleLine: true
+AllowShortFunctionsOnASingleLine: Empty
+InsertBraces: true
+
+PointerAlignment: Left
+DerivePointerAlignment: false
+SpaceBeforeParens: ControlStatements
+SpacesInParentheses: false
+SpaceAfterCStyleCast: true
+SpacesInLineCommentPrefix:
+ Minimum: 1
+ Maximum: 1
+SpacesInContainerLiterals: true
+
+SortIncludes: Never
+IndentPPDirectives: BeforeHash
+PPIndentWidth: 4
+
+IndentCaseLabels: true
+
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignOperands: DontAlign
+
+BinPackParameters: false
+BinPackArguments: false
+AlignAfterOpenBracket: DontAlign
+BracedInitializerIndentWidth: 4
+Cpp11BracedListStyle: Block
+
+ForEachMacros:
+ - FF_LIST_FOR_EACH
+ - yyjson_obj_foreach
+ - yyjson_arr_foreach
+ - yyjson_mut_obj_foreach
+ - yyjson_mut_arr_foreach
+
+AttributeMacros:
+ - FF_A_FALLTHROUGH
+ - FF_A_DEPRECATED
+ - FF_A_CLEANUP
+ - FF_A_NODISCARD
+ - FF_A_PRINTF
+ - FF_A_SCANF
+ - FF_A_NONNULL
+ - FF_A_RETURNS_NONNULL
+ - FF_A_UNUSED
+ - FF_A_PACKED
+ - FF_A_WEAK_IMPORT
+
+MaxEmptyLinesToKeep: 1
+KeepEmptyLinesAtTheStartOfBlocks: false
diff --git a/.clang-format-ignore b/.clang-format-ignore
new file mode 100644
index 0000000000..2602732186
--- /dev/null
+++ b/.clang-format-ignore
@@ -0,0 +1,2 @@
+src/3rdparty/**
+build/**
diff --git a/.github/workflows/build-dragonfly-amd64.yml b/.github/workflows/build-dragonfly-amd64.yml
new file mode 100644
index 0000000000..f4ed8230b1
--- /dev/null
+++ b/.github/workflows/build-dragonfly-amd64.yml
@@ -0,0 +1,40 @@
+name: Reusable DragonFly amd64
+
+on:
+ workflow_call:
+
+env:
+ CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: checkout repository
+ uses: actions/checkout@v6
+
+ - name: run VM
+ uses: vmactions/dragonflybsd-vm@v1
+ with:
+ usesh: yes
+ envs: 'CMAKE_BUILD_TYPE'
+ prepare: |
+ uname -a
+ pkg update
+ pkg install -y llvm cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl egl opencl ocl-icd v4l_compat chafa libelf
+
+ run: |
+ 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: upload artifacts
+ uses: actions/upload-artifact@v7
+ with:
+ name: fastfetch-dragonfly-amd64
+ path: ./fastfetch-*.*
diff --git a/.github/workflows/build-freebsd-amd64.yml b/.github/workflows/build-freebsd-amd64.yml
new file mode 100644
index 0000000000..f11181ed3f
--- /dev/null
+++ b/.github/workflows/build-freebsd-amd64.yml
@@ -0,0 +1,42 @@
+name: Reusable FreeBSD amd64
+
+on:
+ workflow_call:
+
+env:
+ CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: checkout repository
+ uses: actions/checkout@v6
+
+ - name: run VM
+ uses: cross-platform-actions/action@13ec3be3fbdf
+ with:
+ operating_system: freebsd
+ architecture: x86-64
+ cpu_count: 4
+ 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
+ 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: upload artifacts
+ uses: actions/upload-artifact@v7
+ with:
+ name: fastfetch-freebsd-amd64
+ path: ./fastfetch-*.*
diff --git a/.github/workflows/build-haiku-amd64.yml b/.github/workflows/build-haiku-amd64.yml
new file mode 100644
index 0000000000..c803673d03
--- /dev/null
+++ b/.github/workflows/build-haiku-amd64.yml
@@ -0,0 +1,40 @@
+name: Reusable Haiku amd64
+
+on:
+ workflow_call:
+
+env:
+ CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: checkout repository
+ uses: actions/checkout@v6
+
+ - name: run VM
+ uses: cross-platform-actions/action@13ec3be3fbdf
+ 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
+ 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
+
+ - name: upload artifacts
+ uses: actions/upload-artifact@v7
+ with:
+ name: fastfetch-haiku-amd64
+ path: ./fastfetch-*.*
diff --git a/.github/workflows/build-linux-armv6l.yml b/.github/workflows/build-linux-armv6l.yml
new file mode 100644
index 0000000000..de7fe1e363
--- /dev/null
+++ b/.github/workflows/build-linux-armv6l.yml
@@ -0,0 +1,40 @@
+name: Reusable Linux armv6l
+
+on:
+ workflow_call:
+
+env:
+ CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
+
+jobs:
+ build:
+ runs-on: ubuntu-24.04
+ steps:
+ - name: checkout repository
+ uses: actions/checkout@v6
+
+ - name: run VM
+ uses: uraimo/run-on-arch-action@v3
+ id: runcmd
+ with:
+ arch: armv6
+ distro: bookworm
+ githubToken: ${{ github.token }}
+ run: |
+ uname -a
+ apt-get update && apt-get install -y wget
+ apt-get install -y cmake make gcc libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev rpm
+ cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
+ cmake --build . --target package --verbose -j4
+ ./fastfetch --list-features
+ time ./fastfetch -c presets/ci.jsonc --stat false
+ time ./fastfetch -c presets/ci.jsonc --format json
+ time ./flashfetch
+ ldd fastfetch
+ ctest --output-on-failure
+
+ - name: upload artifacts
+ uses: actions/upload-artifact@v7
+ with:
+ name: fastfetch-linux-armv6l
+ path: ./fastfetch-*.*
diff --git a/.github/workflows/build-linux-armv7l.yml b/.github/workflows/build-linux-armv7l.yml
new file mode 100644
index 0000000000..ea91da0e8e
--- /dev/null
+++ b/.github/workflows/build-linux-armv7l.yml
@@ -0,0 +1,44 @@
+name: Reusable Linux armv7l
+
+on:
+ workflow_call:
+
+env:
+ CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
+
+jobs:
+ build:
+ runs-on: ubuntu-24.04
+ steps:
+ - name: checkout repository
+ uses: actions/checkout@v6
+
+ - name: run VM
+ uses: uraimo/run-on-arch-action@v3
+ id: runcmd
+ with:
+ arch: armv7
+ distro: ubuntu22.04
+ githubToken: ${{ github.token }}
+ run: |
+ uname -a
+ apt-get update && apt-get install -y software-properties-common ca-certificates gpg curl
+ add-apt-repository -y ppa:ubuntu-toolchain-r/test
+ curl -L https://apt.kitware.com/keys/kitware-archive-latest.asc | gpg --dearmor - | tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null
+ echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ jammy main' | tee /etc/apt/sources.list.d/kitware.list >/dev/null
+ echo -e 'Acquire::https::Verify-Peer "false";\nAcquire::https::Verify-Host "false";' >> /etc/apt/apt.conf.d/99ignore-certificates
+ apt-get update && apt-get install -y cmake make gcc-13 libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev rpm
+ CC=gcc-13 cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
+ cmake --build . --target package --verbose -j4
+ ./fastfetch --list-features
+ time ./fastfetch -c presets/ci.jsonc --stat false
+ time ./fastfetch -c presets/ci.jsonc --format json
+ time ./flashfetch
+ ldd fastfetch
+ ctest --output-on-failure
+
+ - name: upload artifacts
+ uses: actions/upload-artifact@v7
+ with:
+ name: fastfetch-linux-armv7l
+ path: ./fastfetch-*.*
diff --git a/.github/workflows/build-linux-hosts.yml b/.github/workflows/build-linux-hosts.yml
new file mode 100644
index 0000000000..635e2d5bab
--- /dev/null
+++ b/.github/workflows/build-linux-hosts.yml
@@ -0,0 +1,103 @@
+name: Reusable Linux Hosts
+
+on:
+ workflow_call:
+ inputs:
+ arch:
+ required: true
+ type: string
+ runs-on:
+ required: true
+ type: string
+ outputs:
+ ffversion:
+ description: fastfetch version from linux host build
+ value: ${{ jobs.build.outputs.ffversion }}
+
+env:
+ CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
+
+jobs:
+ build:
+ runs-on: ${{ inputs.runs-on }}
+ outputs:
+ ffversion: ${{ steps.ffversion.outputs.ffversion }}
+ steps:
+ - name: checkout repository
+ uses: actions/checkout@v6
+
+ - name: uname -a
+ run: uname -a
+
+ - name: cat /etc/os-release
+ run: cat /etc/os-release
+
+ - name: cat /proc/cpuinfo
+ run: cat /proc/cpuinfo
+
+ - name: add gcc-13 repo
+ run: sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
+
+ - name: install required packages
+ run: sudo apt-get update && sudo apt-get install -y gcc-13 libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev libddcutil-dev rpm ninja-build
+
+ - name: install linuxbrew packages
+ run: |
+ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
+ /home/linuxbrew/.linuxbrew/bin/brew install imagemagick chafa --ignore-dependencies
+
+ - name: Initialize CodeQL
+ if: inputs.arch == 'amd64'
+ uses: github/codeql-action/init@v4
+ with:
+ languages: c
+
+ - name: configure project
+ run: CC=gcc-13 PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -GNinja -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_INSTALL_PREFIX=/usr .
+
+ - name: build project
+ run: cmake --build . --target package --verbose -j4
+
+ - name: perform CodeQL analysis
+ if: inputs.arch == 'amd64'
+ uses: github/codeql-action/analyze@v4
+
+ - name: list features
+ run: ./fastfetch --list-features
+
+ - name: run fastfetch
+ run: time ./fastfetch -c presets/ci.jsonc --stat false
+
+ - name: run fastfetch --format json
+ run: time ./fastfetch -c presets/ci.jsonc --format json
+
+ - name: run flashfetch
+ run: time ./flashfetch
+
+ - name: print dependencies
+ run: ldd fastfetch
+
+ - name: run tests
+ run: ctest --output-on-failure
+
+ - name: get fastfetch version
+ id: ffversion
+ run: echo "ffversion=$(./fastfetch --version-raw)" >> $GITHUB_OUTPUT
+
+ - name: polyfill glibc
+ run: |
+ wget https://github.com/CarterLi/polyfill-glibc/releases/download/v0.0.1/polyfill-glibc-${{ inputs.arch }} -O polyfill-glibc
+ chmod +x polyfill-glibc
+ strip fastfetch && ./polyfill-glibc fastfetch --target-glibc=2.17
+ strip flashfetch && ./polyfill-glibc flashfetch --target-glibc=2.17
+ echo 'set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-polyfilled")' >> CPackConfig.cmake
+ echo 'set(CPACK_PACKAGE_RELOCATABLE OFF)' >> CPackConfig.cmake
+ echo 'set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.17)")' >> CPackConfig.cmake
+ echo 'set(CPACK_RPM_SPEC_MORE_DEFINE "%global __os_install_post %{nil}")' >> CPackConfig.cmake
+ cpack -V
+
+ - name: upload artifacts
+ uses: actions/upload-artifact@v7
+ with:
+ name: fastfetch-linux-${{ inputs.arch }}
+ path: ./fastfetch-*.*
diff --git a/.github/workflows/build-linux-i686.yml b/.github/workflows/build-linux-i686.yml
new file mode 100644
index 0000000000..01812658d5
--- /dev/null
+++ b/.github/workflows/build-linux-i686.yml
@@ -0,0 +1,70 @@
+name: Reusable Linux i686
+
+on:
+ workflow_call:
+
+env:
+ CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
+
+jobs:
+ build:
+ runs-on: ubuntu-22.04
+ steps:
+ - name: checkout repository
+ uses: actions/checkout@v6
+
+ - name: uname -a
+ run: uname -a
+
+ - name: cat /etc/os-release
+ run: cat /etc/os-release
+
+ - name: cat /proc/cpuinfo
+ run: cat /proc/cpuinfo
+
+ - name: add gcc-13 repo
+ run: sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
+
+ - name: install required packages
+ run: sudo apt-get update && sudo apt-get install -y gcc-13 gcc-13-multilib libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev libddcutil-dev rpm ninja-build
+
+ - name: install linuxbrew packages
+ run: |
+ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
+ /home/linuxbrew/.linuxbrew/bin/brew install imagemagick chafa --ignore-dependencies
+
+ - name: cmake version
+ run: cmake --version
+
+ - name: configure project
+ run: CC=gcc-13 PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -DCMAKE_C_FLAGS="-m32 -march=i686 -mtune=i686" -DCMAKE_SYSTEM_PROCESSOR_OVERRIDE=i686 -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=i386 -GNinja -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_INSTALL_PREFIX=/usr .
+
+ - name: build project
+ run: cmake --build . --target package --verbose -j4
+
+ - name: check deb package
+ run: dpkg -I fastfetch-*.deb
+
+ - name: list features
+ run: ./fastfetch --list-features
+
+ - name: run fastfetch
+ run: time ./fastfetch -c presets/ci.jsonc --stat false
+
+ - name: run fastfetch --format json
+ run: time ./fastfetch -c presets/ci.jsonc --format json
+
+ - name: run flashfetch
+ run: time ./flashfetch
+
+ - name: print dependencies
+ run: ldd fastfetch
+
+ - name: run tests
+ run: ctest --output-on-failure
+
+ - name: upload artifacts
+ uses: actions/upload-artifact@v7
+ with:
+ name: fastfetch-linux-i686
+ path: ./fastfetch-*.*
diff --git a/.github/workflows/build-linux-vms.yml b/.github/workflows/build-linux-vms.yml
new file mode 100644
index 0000000000..456a5a6116
--- /dev/null
+++ b/.github/workflows/build-linux-vms.yml
@@ -0,0 +1,45 @@
+name: Reusable Linux VMs
+
+on:
+ workflow_call:
+ inputs:
+ arch:
+ required: true
+ type: string
+
+env:
+ CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: checkout repository
+ uses: actions/checkout@v6
+
+ - name: run VM
+ uses: uraimo/run-on-arch-action@v3
+ id: runcmd
+ with:
+ arch: ${{ inputs.arch }}
+ distro: ubuntu22.04
+ githubToken: ${{ github.token }}
+ run: |
+ uname -a
+ apt-get update && apt-get install -y software-properties-common
+ add-apt-repository -y ppa:ubuntu-toolchain-r/test
+ apt-get update && apt-get install -y cmake make gcc-13 libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libchafa-dev libelf-dev rpm
+ CC=gcc-13 cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
+ cmake --build . --target package --verbose -j4
+ ./fastfetch --list-features
+ time ./fastfetch -c presets/ci.jsonc --stat false
+ time ./fastfetch -c presets/ci.jsonc --format json
+ time ./flashfetch
+ ldd fastfetch
+ ctest --output-on-failure
+
+ - name: upload artifacts
+ uses: actions/upload-artifact@v7
+ with:
+ name: fastfetch-linux-${{ inputs.arch }}
+ path: ./fastfetch-*.*
diff --git a/.github/workflows/build-macos-hosts.yml b/.github/workflows/build-macos-hosts.yml
new file mode 100644
index 0000000000..34b8db5e4b
--- /dev/null
+++ b/.github/workflows/build-macos-hosts.yml
@@ -0,0 +1,58 @@
+name: Reusable macOS Hosts
+
+on:
+ workflow_call:
+ inputs:
+ arch:
+ required: true
+ type: string
+ runs-on:
+ required: true
+ type: string
+
+env:
+ CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
+
+jobs:
+ build:
+ runs-on: ${{ inputs.runs-on }}
+ steps:
+ - name: checkout repository
+ uses: actions/checkout@v6
+
+ - name: uname -a
+ run: uname -a
+
+ - name: install required packages
+ run: |
+ HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install --overwrite vulkan-loader vulkan-headers molten-vk imagemagick chafa
+
+ - name: configure project
+ run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
+
+ - name: build project
+ run: cmake --build . --target package --verbose -j4
+
+ - name: list features
+ run: ./fastfetch --list-features
+
+ - name: run fastfetch
+ run: time ./fastfetch -c presets/ci.jsonc --structure-disabled vulkan --stat false
+
+ - name: run fastfetch --format json
+ run: time ./fastfetch -c presets/ci.jsonc --structure-disabled vulkan --format json
+
+ - name: run flashfetch
+ run: time ./flashfetch
+
+ - name: print dependencies
+ run: otool -L fastfetch
+
+ - name: run tests
+ run: ctest --output-on-failure
+
+ - name: upload artifacts
+ uses: actions/upload-artifact@v7
+ with:
+ name: fastfetch-macos-${{ inputs.arch }}
+ path: ./fastfetch-*.*
diff --git a/.github/workflows/build-musl-amd64.yml b/.github/workflows/build-musl-amd64.yml
new file mode 100644
index 0000000000..58f4a4c37c
--- /dev/null
+++ b/.github/workflows/build-musl-amd64.yml
@@ -0,0 +1,45 @@
+name: Reusable Musl amd64
+
+on:
+ workflow_call:
+
+env:
+ CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v6
+
+ - name: setup alpine linux
+ uses: jirutka/setup-alpine@ae3b3ddba350
+
+ - name: install dependencies
+ run: |
+ cat /etc/alpine-release
+ uname -a
+ apk add cmake samurai vulkan-loader-dev libxcb-dev libxrandr-dev rpm-dev wayland-dev libdrm-dev dconf-dev imagemagick-dev chafa-dev zlib-dev dbus-dev mesa-dev opencl-dev sqlite-dev networkmanager-dev pulseaudio-dev ddcutil-dev elfutils-dev gcc g++
+ shell: alpine.sh --root {0}
+
+ - name: build
+ run: |
+ cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr -DIS_MUSL=ON -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -GNinja .
+ cmake --build . --target package --verbose -j4
+ shell: alpine.sh {0}
+
+ - name: run
+ run: |
+ ./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: alpine.sh {0}
+
+ - name: upload artifacts
+ uses: actions/upload-artifact@v7
+ with:
+ name: fastfetch-musl-amd64
+ path: ./fastfetch-*.*
diff --git a/.github/workflows/build-netbsd-amd64.yml b/.github/workflows/build-netbsd-amd64.yml
new file mode 100644
index 0000000000..9537310c4f
--- /dev/null
+++ b/.github/workflows/build-netbsd-amd64.yml
@@ -0,0 +1,41 @@
+name: Reusable NetBSD amd64
+
+on:
+ workflow_call:
+
+env:
+ CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: checkout repository
+ uses: actions/checkout@v6
+
+ - name: run VM
+ uses: cross-platform-actions/action@13ec3be3fbdf
+ 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
+ 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: upload artifacts
+ uses: actions/upload-artifact@v7
+ with:
+ name: fastfetch-netbsd-amd64
+ path: ./fastfetch-*.*
diff --git a/.github/workflows/build-no-features-test.yml b/.github/workflows/build-no-features-test.yml
new file mode 100644
index 0000000000..5acee8f728
--- /dev/null
+++ b/.github/workflows/build-no-features-test.yml
@@ -0,0 +1,42 @@
+name: Reusable No Features Test
+
+on:
+ workflow_call:
+
+env:
+ CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: checkout repository
+ uses: actions/checkout@v6
+
+ - name: uname -a
+ run: uname -a
+
+ - name: configure project
+ run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr . -DENABLE_VULKAN=OFF -DENABLE_WAYLAND=OFF -DENABLE_XCB_RANDR=OFF -DENABLE_XCB=OFF -DENABLE_XRANDR=OFF -DENABLE_X11=OFF -DENABLE_DRM=OFF -DENABLE_DRM_AMDGPU=OFF -DENABLE_GIO=OFF -DENABLE_DCONF=OFF -DENABLE_DBUS=OFF -DENABLE_SQLITE3=OFF -DENABLE_RPM=OFF -DENABLE_IMAGEMAGICK7=OFF -DENABLE_IMAGEMAGICK6=OFF -DENABLE_CHAFA=OFF -DENABLE_ZLIB=OFF -DENABLE_EGL=OFF -DENABLE_GLX=OFF -DENABLE_OPENCL=OFF -DENABLE_FREETYPE=OFF -DENABLE_PULSE=OFF -DENABLE_DDCUTIL=OFF -DENABLE_ELF=OFF -DENABLE_THREADS=OFF
+
+ - name: build project
+ run: cmake --build . --target package --verbose -j4
+
+ - name: list features
+ run: ./fastfetch --list-features
+
+ - name: run fastfetch
+ run: time ./fastfetch -c presets/ci.jsonc --stat false
+
+ - name: run fastfetch --format json
+ run: time ./fastfetch -c presets/ci.jsonc --format json
+
+ - name: run flashfetch
+ run: time ./flashfetch
+
+ - name: print dependencies
+ run: ldd fastfetch
+
+ - name: run tests
+ run: ctest --output-on-failure
diff --git a/.github/workflows/build-omnios-amd64.yml b/.github/workflows/build-omnios-amd64.yml
new file mode 100644
index 0000000000..b7a9298186
--- /dev/null
+++ b/.github/workflows/build-omnios-amd64.yml
@@ -0,0 +1,42 @@
+name: Reusable OmniOS amd64
+
+on:
+ workflow_call:
+
+env:
+ CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: checkout repository
+ uses: actions/checkout@v6
+
+ - name: run VM
+ uses: vmactions/omnios-vm@v1
+ with:
+ usesh: true
+ envs: 'CMAKE_BUILD_TYPE'
+ prepare: |
+ uname -a
+ pkg update --accept
+ pkg install gcc14 cmake git pkg-config glib2 dbus sqlite-3 imagemagick ninja
+
+ 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: upload artifacts
+ uses: actions/upload-artifact@v7
+ with:
+ name: fastfetch-omnios-amd64
+ path: ./fastfetch-*.*
diff --git a/.github/workflows/build-openbsd-amd64.yml b/.github/workflows/build-openbsd-amd64.yml
new file mode 100644
index 0000000000..5cd0a291ac
--- /dev/null
+++ b/.github/workflows/build-openbsd-amd64.yml
@@ -0,0 +1,42 @@
+name: Reusable OpenBSD amd64
+
+on:
+ workflow_call:
+
+env:
+ CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: checkout repository
+ uses: actions/checkout@v6
+
+ - name: run VM
+ uses: cross-platform-actions/action@13ec3be3fbdf
+ with:
+ operating_system: openbsd
+ architecture: x86-64
+ cpu_count: 4
+ shell: bash
+ version: '7.8'
+ environment_variables: 'CMAKE_BUILD_TYPE'
+ run: |
+ uname -a
+ sudo pkg_add -u
+ sudo pkg_add -r llvm-21.1.2p0 cmake git pkgconf wayland vulkan-headers vulkan-loader glib2 dconf dbus sqlite3 imagemagick chafa
+ CC=clang-21 cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
+ cmake --build . --target package --verbose -j4
+ ./fastfetch --list-features
+ time ./fastfetch -c presets/ci.jsonc --stat false
+ time ./fastfetch -c presets/ci.jsonc --format json
+ time ./flashfetch
+ ldd fastfetch
+ ctest --output-on-failure
+
+ - name: upload artifacts
+ uses: actions/upload-artifact@v7
+ with:
+ name: fastfetch-openbsd-amd64
+ path: ./fastfetch-*.*
diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml
new file mode 100644
index 0000000000..3aab6f7f63
--- /dev/null
+++ b/.github/workflows/build-release.yml
@@ -0,0 +1,58 @@
+name: Reusable Release
+
+on:
+ workflow_call:
+ inputs:
+ ffversion:
+ required: true
+ type: string
+
+jobs:
+ release:
+ runs-on: ubuntu-latest
+ steps:
+ - name: get latest release version
+ id: get_version_release
+ uses: pozetroninc/github-action-get-latest-release@53d33d213ee7
+ with:
+ repository: ${{ github.repository }}
+
+ - name: download artifacts
+ if: inputs.ffversion != steps.get_version_release.outputs.release
+ uses: actions/download-artifact@v8
+
+ - name: create release
+ if: inputs.ffversion != steps.get_version_release.outputs.release
+ uses: ncipollo/release-action@v1
+ with:
+ tag: ${{ inputs.ffversion }}
+ commit: ${{ github.sha }}
+ artifactErrorsFailBuild: true
+ artifacts: fastfetch-*/fastfetch-*
+ body: "Please refer to [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/${{ inputs.ffversion }}/CHANGELOG.md) for details."
+
+ - name: download source tarballs
+ if: inputs.ffversion != steps.get_version_release.outputs.release
+ run: |
+ for i in 1 2 3 4 5; do curl -L --remote-name-all --output-dir fastfetch-source --create-dirs https://github.com/${{ github.repository }}/archive/refs/tags/${{ inputs.ffversion }}.{tar.gz,zip} && break || sleep 5; done
+ ls fastfetch-*/*
+
+ - name: generate release notes
+ if: inputs.ffversion != steps.get_version_release.outputs.release
+ run: |
+ echo "Please refer to [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/${{ inputs.ffversion }}/CHANGELOG.md) for details." > fastfetch-release-notes.md
+ echo -e "\n---\n\nSHA256SUMs
\n\n\`\`\`" >> fastfetch-release-notes.md
+ sha256sum fastfetch-*/* >> fastfetch-release-notes.md
+ echo -e "\`\`\`\n " >> fastfetch-release-notes.md
+ echo -e "\nSHA512SUMs
\n\n\`\`\`" >> fastfetch-release-notes.md
+ sha512sum fastfetch-*/* >> fastfetch-release-notes.md
+ echo -e "\`\`\`\n " >> fastfetch-release-notes.md
+
+ - name: update release body
+ if: inputs.ffversion != steps.get_version_release.outputs.release
+ uses: ncipollo/release-action@v1
+ with:
+ tag: ${{ inputs.ffversion }}
+ commit: ${{ github.sha }}
+ bodyFile: fastfetch-release-notes.md
+ allowUpdates: true
diff --git a/.github/workflows/build-solaris-amd64.yml b/.github/workflows/build-solaris-amd64.yml
new file mode 100644
index 0000000000..1cdc009b57
--- /dev/null
+++ b/.github/workflows/build-solaris-amd64.yml
@@ -0,0 +1,43 @@
+name: Reusable Solaris amd64
+
+on:
+ workflow_call:
+
+env:
+ CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: checkout repository
+ uses: actions/checkout@v6
+
+ - name: run VM
+ uses: vmactions/solaris-vm@v1
+ with:
+ usesh: true
+ envs: 'CMAKE_BUILD_TYPE'
+ release: "11.4-gcc-14"
+ prepare: |
+ uname -a
+ pkg install cmake git pkg-config glib2 dbus sqlite-3 imagemagick ninja dconf mesa
+
+ run: |
+ export PKG_CONFIG_PATH=/usr/lib/64/pkgconfig
+ cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -GNinja .
+ cmake --build . --verbose -j4
+ ./fastfetch --list-features
+ time ./fastfetch -c presets/ci.jsonc --stat false
+ time ./fastfetch -c presets/ci.jsonc --format json
+ time ./flashfetch
+ ldd fastfetch
+ ctest --output-on-failure
+ echo 'set(CPACK_PACKAGE_FILE_NAME "fastfetch-solaris-amd64")' >> CPackConfig.cmake
+ cpack -V
+
+ - name: upload artifacts
+ uses: actions/upload-artifact@v7
+ with:
+ name: fastfetch-solaris-amd64
+ path: ./fastfetch-*.*
diff --git a/.github/workflows/build-spellcheck.yml b/.github/workflows/build-spellcheck.yml
new file mode 100644
index 0000000000..ca675285f0
--- /dev/null
+++ b/.github/workflows/build-spellcheck.yml
@@ -0,0 +1,24 @@
+name: Reusable Spellcheck
+
+on:
+ workflow_call:
+
+env:
+ CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
+
+jobs:
+ spellcheck:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: checkout repository
+ uses: actions/checkout@v6
+
+ - name: Install codespell
+ shell: bash
+ run: |
+ sudo apt-get update || true
+ sudo apt-get install -y codespell
+
+ - name: Run Spellchecker
+ run: codespell
diff --git a/.github/workflows/build-windows-hosts.yml b/.github/workflows/build-windows-hosts.yml
new file mode 100644
index 0000000000..9c869f01ff
--- /dev/null
+++ b/.github/workflows/build-windows-hosts.yml
@@ -0,0 +1,106 @@
+name: Reusable Windows Hosts
+
+on:
+ workflow_call:
+ inputs:
+ arch:
+ required: true
+ type: string
+ runs-on:
+ required: true
+ type: string
+ msystem:
+ required: true
+ type: string
+ msystem-lower:
+ required: true
+ type: string
+ msys-arch:
+ required: true
+ type: string
+
+env:
+ CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
+
+jobs:
+ build:
+ runs-on: ${{ inputs.runs-on }}
+ defaults:
+ run:
+ shell: msys2 {0}
+ steps:
+ - name: checkout repository
+ uses: actions/checkout@v6
+
+ - name: setup-msys2
+ uses: msys2/setup-msys2@v2
+ with:
+ msystem: ${{ inputs.msystem }}
+ update: true
+ install: git mingw-w64-clang-${{ inputs.msys-arch }}-7zip mingw-w64-clang-${{ inputs.msys-arch }}-cmake mingw-w64-clang-${{ inputs.msys-arch }}-clang mingw-w64-clang-${{ inputs.msys-arch }}-vulkan-loader mingw-w64-clang-${{ inputs.msys-arch }}-vulkan-headers mingw-w64-clang-${{ inputs.msys-arch }}-opencl-icd mingw-w64-clang-${{ inputs.msys-arch }}-opencl-headers mingw-w64-clang-${{ inputs.msys-arch }}-cppwinrt mingw-w64-clang-${{ inputs.msys-arch }}-imagemagick mingw-w64-clang-${{ inputs.msys-arch }}-chafa mingw-w64-clang-${{ inputs.msys-arch }}-directx-headers
+
+ - name: print msys version
+ run: uname -a
+
+ - name: configure project
+ run: env PKG_CONFIG_PATH=/${{ inputs.msystem-lower }}/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
+
+ - name: build project
+ run: cmake --build . --verbose -j4
+
+ - name: copy necessary dlls
+ run: cp /${{ inputs.msystem-lower }}/bin/{OpenCL,vulkan-1}.dll .
+
+ - name: list features
+ run: ./fastfetch --list-features
+
+ - name: run fastfetch
+ run: time ./fastfetch -c presets/ci.jsonc --stat false
+
+ - name: run fastfetch --format json
+ run: time ./fastfetch -c presets/ci.jsonc --format json
+
+ - name: run flashfetch
+ run: time ./flashfetch
+
+ - name: print dependencies
+ run: ldd fastfetch
+
+ - name: run tests
+ run: ctest --output-on-failure
+
+ - if: github.event_name == 'push' && github.repository == 'fastfetch-cli/fastfetch'
+ id: upload-unsigned-artifact
+ name: upload artifacts for signing
+ uses: actions/upload-artifact@v7
+ with:
+ name: fastfetch-windows-${{ inputs.arch }}
+ path: |
+ *.dll
+ fastfetch.exe
+ flashfetch.exe
+
+ - if: github.event_name == 'push' && github.repository == 'fastfetch-cli/fastfetch'
+ name: submit signing request
+ uses: signpath/github-action-submit-signing-request@v1
+ with:
+ api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
+ organization-id: '${{ vars.SIGNPATH_ORG_ID }}'
+ project-slug: 'fastfetch'
+ signing-policy-slug: ${{ github.ref == 'refs/heads/master' && 'release-signing' || 'test-signing' }}
+ github-artifact-id: '${{ steps.upload-unsigned-artifact.outputs.artifact-id }}'
+ wait-for-completion: true
+ output-artifact-directory: '.'
+
+ - name: create zip archive
+ run: 7z a -tzip -mx9 -bd -y fastfetch-windows-${{ inputs.arch }}.zip LICENSE *.dll fastfetch.exe flashfetch.exe presets
+
+ - name: create 7z archive
+ run: 7z a -t7z -mx9 -bd -y fastfetch-windows-${{ inputs.arch }}.7z LICENSE *.dll fastfetch.exe flashfetch.exe presets
+
+ - name: upload true artifacts
+ uses: actions/upload-artifact@v7
+ with:
+ name: fastfetch-windows-${{ inputs.arch }}
+ path: ./fastfetch-windows-${{ inputs.arch }}.*
+ overwrite: true
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index a61f95b629..fc0c432b07 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -4,66 +4,20 @@ on:
- push
- pull_request
-env:
- CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
-
jobs:
spellcheck:
- runs-on: ubuntu-latest
-
- steps:
- - name: checkout repository
- uses: actions/checkout@v6
-
- - name: Install codespell
- shell: bash
- run: |
- sudo apt-get update || true
- sudo apt-get install -y codespell
-
- - name: Run Spellchecker
- run: codespell
+ uses: ./.github/workflows/build-spellcheck.yml
no-features-test:
name: No-features-test
- runs-on: ubuntu-latest
permissions:
security-events: write
contents: read
- steps:
- - name: checkout repository
- uses: actions/checkout@v6
-
- - name: uname -a
- run: uname -a
-
- - name: configure project
- run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr . -DENABLE_VULKAN=OFF -DENABLE_WAYLAND=OFF -DENABLE_XCB_RANDR=OFF -DENABLE_XCB=OFF -DENABLE_XRANDR=OFF -DENABLE_X11=OFF -DENABLE_DRM=OFF -DENABLE_DRM_AMDGPU=OFF -DENABLE_GIO=OFF -DENABLE_DCONF=OFF -DENABLE_DBUS=OFF -DENABLE_SQLITE3=OFF -DENABLE_RPM=OFF -DENABLE_IMAGEMAGICK7=OFF -DENABLE_IMAGEMAGICK6=OFF -DENABLE_CHAFA=OFF -DENABLE_ZLIB=OFF -DENABLE_EGL=OFF -DENABLE_GLX=OFF -DENABLE_OPENCL=OFF -DENABLE_FREETYPE=OFF -DENABLE_PULSE=OFF -DENABLE_DDCUTIL=OFF -DENABLE_ELF=OFF -DENABLE_THREADS=OFF
-
- - name: build project
- run: cmake --build . --target package --verbose -j4
-
- - name: list features
- run: ./fastfetch --list-features
-
- - name: run fastfetch
- run: time ./fastfetch -c presets/ci.jsonc --stat false
-
- - name: run fastfetch --format json
- run: time ./fastfetch -c presets/ci.jsonc --format json
-
- - name: run flashfetch
- run: time ./flashfetch
-
- - name: print dependencies
- run: ldd fastfetch
-
- - name: run tests
- run: ctest --output-on-failure
+ uses: ./.github/workflows/build-no-features-test.yml
+ secrets: inherit
linux-hosts:
name: Linux-${{ matrix.arch }}
- runs-on: ${{ matrix.runs-on }}
permissions:
security-events: write
contents: read
@@ -74,233 +28,38 @@ jobs:
runs-on: ubuntu-22.04
- arch: aarch64
runs-on: ubuntu-22.04-arm
- outputs:
- ffversion: ${{ steps.ffversion.outputs.ffversion }}
- steps:
- - name: checkout repository
- uses: actions/checkout@v6
-
- - name: uname -a
- run: uname -a
-
- - name: cat /etc/os-release
- run: cat /etc/os-release
-
- - name: cat /proc/cpuinfo
- run: cat /proc/cpuinfo
-
- - name: add gcc-13 repo
- run: sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
-
- - name: install required packages
- run: sudo apt-get update && sudo apt-get install -y gcc-13 libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev libddcutil-dev rpm ninja-build
-
- - name: install linuxbrew packages
- run: |
- /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
- /home/linuxbrew/.linuxbrew/bin/brew install imagemagick chafa --ignore-dependencies
-
- - name: Initialize CodeQL
- if: matrix.arch == 'amd64'
- uses: github/codeql-action/init@v4
- with:
- languages: c
-
- - name: configure project
- run: CC=gcc-13 PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -GNinja -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_INSTALL_PREFIX=/usr .
-
- - name: build project
- run: cmake --build . --target package --verbose -j4
-
- - name: perform CodeQL analysis
- if: matrix.arch == 'amd64'
- uses: github/codeql-action/analyze@v4
-
- - name: list features
- run: ./fastfetch --list-features
-
- - name: run fastfetch
- run: time ./fastfetch -c presets/ci.jsonc --stat false
-
- - name: run fastfetch --format json
- run: time ./fastfetch -c presets/ci.jsonc --format json
-
- - name: run flashfetch
- run: time ./flashfetch
-
- - name: print dependencies
- run: ldd fastfetch
-
- - name: run tests
- run: ctest --output-on-failure
-
- - name: get fastfetch version
- id: ffversion
- run: echo "ffversion=$(./fastfetch --version-raw)" >> $GITHUB_OUTPUT
-
- - name: polyfill glibc
- run: |
- wget https://github.com/CarterLi/polyfill-glibc/releases/download/v0.0.1/polyfill-glibc-${{ matrix.arch }} -O polyfill-glibc
- chmod +x polyfill-glibc
- strip fastfetch && ./polyfill-glibc fastfetch --target-glibc=2.17
- strip flashfetch && ./polyfill-glibc flashfetch --target-glibc=2.17
- echo 'set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-polyfilled")' >> CPackConfig.cmake
- echo 'set(CPACK_PACKAGE_RELOCATABLE OFF)' >> CPackConfig.cmake
- echo 'set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.17)")' >> CPackConfig.cmake
- echo 'set(CPACK_RPM_SPEC_MORE_DEFINE "%global __os_install_post %{nil}")' >> CPackConfig.cmake
- cpack -V
-
- - name: upload artifacts
- uses: actions/upload-artifact@v7
- with:
- name: fastfetch-linux-${{ matrix.arch }}
- path: ./fastfetch-*.*
+ uses: ./.github/workflows/build-linux-hosts.yml
+ with:
+ arch: ${{ matrix.arch }}
+ runs-on: ${{ matrix.runs-on }}
+ secrets: inherit
linux-i686:
name: Linux-i686
- runs-on: ubuntu-22.04
permissions:
security-events: write
contents: read
- steps:
- - name: checkout repository
- uses: actions/checkout@v6
-
- - name: uname -a
- run: uname -a
-
- - name: cat /etc/os-release
- run: cat /etc/os-release
-
- - name: cat /proc/cpuinfo
- run: cat /proc/cpuinfo
-
- - name: add gcc-13 repo
- run: sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
-
- - name: install required packages
- run: sudo apt-get update && sudo apt-get install -y gcc-13 gcc-13-multilib libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev libddcutil-dev rpm ninja-build
-
- - name: install linuxbrew packages
- run: |
- /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
- /home/linuxbrew/.linuxbrew/bin/brew install imagemagick chafa --ignore-dependencies
-
- - name: cmake version
- run: cmake --version
-
- - name: configure project
- run: CC=gcc-13 PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -DCMAKE_C_FLAGS="-m32 -march=i686 -mtune=i686" -DCMAKE_SYSTEM_PROCESSOR_OVERRIDE=i686 -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=i386 -GNinja -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_INSTALL_PREFIX=/usr .
-
- - name: build project
- run: cmake --build . --target package --verbose -j4
-
- - name: check deb package
- run: dpkg -I fastfetch-*.deb
-
- - name: list features
- run: ./fastfetch --list-features
-
- - name: run fastfetch
- run: time ./fastfetch -c presets/ci.jsonc --stat false
-
- - name: run fastfetch --format json
- run: time ./fastfetch -c presets/ci.jsonc --format json
-
- - name: run flashfetch
- run: time ./flashfetch
-
- - name: print dependencies
- run: ldd fastfetch
-
- - name: run tests
- run: ctest --output-on-failure
-
- - name: upload artifacts
- uses: actions/upload-artifact@v7
- with:
- name: fastfetch-linux-i686
- path: ./fastfetch-*.*
+ uses: ./.github/workflows/build-linux-i686.yml
+ secrets: inherit
linux-armv7l:
name: Linux-armv7l
- runs-on: ubuntu-24.04
permissions:
security-events: write
contents: read
- steps:
- - name: checkout repository
- uses: actions/checkout@v6
-
- - name: run VM
- uses: uraimo/run-on-arch-action@v3
- id: runcmd
- with:
- arch: armv7
- distro: ubuntu22.04
- githubToken: ${{ github.token }}
- run: |
- uname -a
- apt-get update && apt-get install -y software-properties-common ca-certificates gpg curl
- add-apt-repository -y ppa:ubuntu-toolchain-r/test
- curl -L https://apt.kitware.com/keys/kitware-archive-latest.asc | gpg --dearmor - | tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null
- echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ jammy main' | tee /etc/apt/sources.list.d/kitware.list >/dev/null
- echo -e 'Acquire::https::Verify-Peer "false";\nAcquire::https::Verify-Host "false";' >> /etc/apt/apt.conf.d/99ignore-certificates
- apt-get update && apt-get install -y cmake make gcc-13 libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev rpm
- CC=gcc-13 cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
- cmake --build . --target package --verbose -j4
- ./fastfetch --list-features
- time ./fastfetch -c presets/ci.jsonc --stat false
- time ./fastfetch -c presets/ci.jsonc --format json
- time ./flashfetch
- ldd fastfetch
- ctest --output-on-failure
-
- - name: upload artifacts
- uses: actions/upload-artifact@v7
- with:
- name: fastfetch-linux-armv7l
- path: ./fastfetch-*.*
+ uses: ./.github/workflows/build-linux-armv7l.yml
+ secrets: inherit
linux-armv6l:
name: Linux-armv6l
- runs-on: ubuntu-24.04
permissions:
security-events: write
contents: read
- steps:
- - name: checkout repository
- uses: actions/checkout@v6
-
- - name: run VM
- uses: uraimo/run-on-arch-action@v3
- id: runcmd
- with:
- arch: armv6
- distro: bookworm
- githubToken: ${{ github.token }}
- run: |
- uname -a
- apt-get update && apt-get install -y wget
- apt-get install -y cmake make gcc libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev rpm
- cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
- cmake --build . --target package --verbose -j4
- ./fastfetch --list-features
- time ./fastfetch -c presets/ci.jsonc --stat false
- time ./fastfetch -c presets/ci.jsonc --format json
- time ./flashfetch
- ldd fastfetch
- ctest --output-on-failure
-
- - name: upload artifacts
- uses: actions/upload-artifact@v7
- with:
- name: fastfetch-linux-armv6l
- path: ./fastfetch-*.*
+ uses: ./.github/workflows/build-linux-armv6l.yml
+ secrets: inherit
linux-vms:
name: Linux-${{ matrix.arch }}
- runs-on: ubuntu-latest
permissions:
security-events: write
contents: read
@@ -310,78 +69,18 @@ jobs:
- arch: riscv64
- arch: ppc64le
- arch: s390x
- steps:
- - name: checkout repository
- uses: actions/checkout@v6
-
- - name: run VM
- uses: uraimo/run-on-arch-action@v3
- id: runcmd
- with:
- arch: ${{ matrix.arch }}
- distro: ubuntu22.04
- githubToken: ${{ github.token }}
- run: |
- uname -a
- apt-get update && apt-get install -y software-properties-common
- add-apt-repository -y ppa:ubuntu-toolchain-r/test
- apt-get update && apt-get install -y cmake make gcc-13 libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libchafa-dev libelf-dev rpm
- CC=gcc-13 cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
- cmake --build . --target package --verbose -j4
- ./fastfetch --list-features
- time ./fastfetch -c presets/ci.jsonc --stat false
- time ./fastfetch -c presets/ci.jsonc --format json
- time ./flashfetch
- ldd fastfetch
- ctest --output-on-failure
-
- - name: upload artifacts
- uses: actions/upload-artifact@v7
- with:
- name: fastfetch-linux-${{ matrix.arch }}
- path: ./fastfetch-*.*
+ uses: ./.github/workflows/build-linux-vms.yml
+ with:
+ arch: ${{ matrix.arch }}
+ secrets: inherit
musl-amd64:
name: Musl-amd64
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v6
-
- - name: setup alpine linux
- uses: jirutka/setup-alpine@master
-
- - name: install dependencies
- run: |
- cat /etc/alpine-release
- uname -a
- apk add cmake samurai vulkan-loader-dev libxcb-dev libxrandr-dev rpm-dev wayland-dev libdrm-dev dconf-dev imagemagick-dev chafa-dev zlib-dev dbus-dev mesa-dev opencl-dev sqlite-dev networkmanager-dev pulseaudio-dev ddcutil-dev elfutils-dev gcc g++
- shell: alpine.sh --root {0}
-
- - name: build
- run: |
- cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr -DIS_MUSL=ON -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -GNinja .
- cmake --build . --target package --verbose -j4
- shell: alpine.sh {0}
-
- - name: run
- run: |
- ./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: alpine.sh {0}
-
- - name: upload artifacts
- uses: actions/upload-artifact@v7
- with:
- name: fastfetch-musl-amd64
- path: ./fastfetch-*.*
+ uses: ./.github/workflows/build-musl-amd64.yml
+ secrets: inherit
macos-hosts:
name: macOS-${{ matrix.arch }}
- runs-on: ${{ matrix.runs-on }}
permissions:
security-events: write
contents: read
@@ -392,306 +91,64 @@ jobs:
runs-on: macos-15-intel
- arch: aarch64
runs-on: macos-latest
- steps:
- - name: checkout repository
- uses: actions/checkout@v6
-
- - name: uname -a
- run: uname -a
-
- - name: install required packages
- run: |
- HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install --overwrite vulkan-loader vulkan-headers molten-vk imagemagick chafa
-
- - name: configure project
- run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
-
- - name: build project
- run: cmake --build . --target package --verbose -j4
-
- - name: list features
- run: ./fastfetch --list-features
-
- - name: run fastfetch
- run: time ./fastfetch -c presets/ci.jsonc --structure-disabled vulkan --stat false
-
- - name: run fastfetch --format json
- run: time ./fastfetch -c presets/ci.jsonc --structure-disabled vulkan --format json
-
- - name: run flashfetch
- run: time ./flashfetch
-
- - name: print dependencies
- run: otool -L fastfetch
-
- - name: run tests
- run: ctest --output-on-failure
-
- - name: upload artifacts
- uses: actions/upload-artifact@v7
- with:
- name: fastfetch-macos-${{ matrix.arch }}
- path: ./fastfetch-*.*
+ uses: ./.github/workflows/build-macos-hosts.yml
+ with:
+ arch: ${{ matrix.arch }}
+ runs-on: ${{ matrix.runs-on }}
+ secrets: inherit
omnios-amd64:
- runs-on: ubuntu-latest
name: OmniOS-amd64
- steps:
- - name: checkout repository
- uses: actions/checkout@v6
-
- - name: run VM
- uses: vmactions/omnios-vm@v1
- with:
- usesh: true
- envs: 'CMAKE_BUILD_TYPE'
- prepare: |
- uname -a
- pkg update --accept
- pkg install gcc14 cmake git pkg-config glib2 dbus sqlite-3 imagemagick ninja
-
- 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: upload artifacts
- uses: actions/upload-artifact@v7
- with:
- name: fastfetch-omnios-amd64
- path: ./fastfetch-*.*
+ uses: ./.github/workflows/build-omnios-amd64.yml
+ secrets: inherit
solaris-amd64:
- runs-on: ubuntu-latest
name: Solaris-amd64
- steps:
- - name: checkout repository
- uses: actions/checkout@v6
-
- - name: run VM
- uses: vmactions/solaris-vm@v1
- with:
- usesh: true
- envs: 'CMAKE_BUILD_TYPE'
- release: "11.4-gcc-14"
- prepare: |
- uname -a
- pkg install cmake git pkg-config glib2 dbus sqlite-3 imagemagick ninja dconf mesa
-
- run: |
- export PKG_CONFIG_PATH=/usr/lib/64/pkgconfig
- cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -GNinja .
- cmake --build . --verbose -j4
- ./fastfetch --list-features
- time ./fastfetch -c presets/ci.jsonc --stat false
- time ./fastfetch -c presets/ci.jsonc --format json
- time ./flashfetch
- ldd fastfetch
- ctest --output-on-failure
- echo 'set(CPACK_PACKAGE_FILE_NAME "fastfetch-solaris-amd64")' >> CPackConfig.cmake
- cpack -V
-
- - name: upload artifacts
- uses: actions/upload-artifact@v7
- with:
- name: fastfetch-solaris-amd64
- path: ./fastfetch-*.*
+ uses: ./.github/workflows/build-solaris-amd64.yml
+ secrets: inherit
freebsd-amd64:
name: FreeBSD-amd64
- runs-on: ubuntu-latest
permissions:
security-events: write
contents: read
- steps:
- - name: checkout repository
- uses: actions/checkout@v6
-
- - name: run VM
- uses: cross-platform-actions/action@master
- with:
- operating_system: freebsd
- architecture: x86-64
- cpu_count: 4
- 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
- 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: upload artifacts
- uses: actions/upload-artifact@v7
- with:
- name: fastfetch-freebsd-amd64
- path: ./fastfetch-*.*
+ uses: ./.github/workflows/build-freebsd-amd64.yml
+ secrets: inherit
openbsd-amd64:
name: OpenBSD-amd64
- runs-on: ubuntu-latest
permissions:
security-events: write
contents: read
- steps:
- - name: checkout repository
- uses: actions/checkout@v6
-
- - name: run VM
- uses: cross-platform-actions/action@master
- with:
- operating_system: openbsd
- architecture: x86-64
- cpu_count: 4
- shell: bash
- version: '7.8'
- environment_variables: 'CMAKE_BUILD_TYPE'
- run: |
- uname -a
- sudo pkg_add -u
- sudo pkg_add -r llvm-21.1.2p0 cmake git pkgconf wayland vulkan-headers vulkan-loader glib2 dconf dbus sqlite3 imagemagick chafa
- CC=clang-21 cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
- cmake --build . --target package --verbose -j4
- ./fastfetch --list-features
- time ./fastfetch -c presets/ci.jsonc --stat false
- time ./fastfetch -c presets/ci.jsonc --format json
- time ./flashfetch
- ldd fastfetch
- ctest --output-on-failure
-
- - name: upload artifacts
- uses: actions/upload-artifact@v7
- with:
- name: fastfetch-openbsd-amd64
- path: ./fastfetch-*.*
+ uses: ./.github/workflows/build-openbsd-amd64.yml
+ secrets: inherit
netbsd-amd64:
name: NetBSD-amd64
- runs-on: ubuntu-latest
permissions:
security-events: write
contents: read
- steps:
- - name: checkout repository
- uses: actions/checkout@v6
-
- - name: run 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
- 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: upload artifacts
- uses: actions/upload-artifact@v7
- with:
- name: fastfetch-netbsd-amd64
- path: ./fastfetch-*.*
+ uses: ./.github/workflows/build-netbsd-amd64.yml
+ secrets: inherit
dragonfly-amd64:
name: DragonFly-amd64
- runs-on: ubuntu-latest
permissions:
security-events: write
contents: read
- steps:
- - name: checkout repository
- uses: actions/checkout@v6
-
- - name: run VM
- uses: vmactions/dragonflybsd-vm@v1
- with:
- usesh: yes
- envs: 'CMAKE_BUILD_TYPE'
- prepare: |
- uname -a
- pkg update
- pkg install -y llvm cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl egl opencl ocl-icd v4l_compat chafa libelf
-
- run: |
- 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: upload artifacts
- uses: actions/upload-artifact@v7
- with:
- name: fastfetch-dragonfly-amd64
- path: ./fastfetch-*.*
+ uses: ./.github/workflows/build-dragonfly-amd64.yml
+ secrets: inherit
haiku-amd64:
name: Haiku-amd64
- runs-on: ubuntu-latest
permissions:
security-events: write
contents: read
- steps:
- - name: checkout repository
- uses: actions/checkout@v6
-
- - name: run 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
- 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
-
- - name: upload artifacts
- uses: actions/upload-artifact@v7
- with:
- name: fastfetch-haiku-amd64
- path: ./fastfetch-*.*
+ uses: ./.github/workflows/build-haiku-amd64.yml
+ secrets: inherit
windows-hosts:
name: Windows-${{ matrix.arch }}
- runs-on: ${{ matrix.runs-on }}
permissions:
security-events: write
contents: read
@@ -708,90 +165,18 @@ jobs:
msystem: CLANGARM64
msystem-lower: clangarm64
msys-arch: aarch64
- defaults:
- run:
- shell: msys2 {0}
- steps:
- - name: checkout repository
- uses: actions/checkout@v6
-
- - name: setup-msys2
- uses: msys2/setup-msys2@v2
- with:
- msystem: ${{ matrix.msystem }}
- update: true
- install: git mingw-w64-clang-${{ matrix.msys-arch }}-7zip mingw-w64-clang-${{ matrix.msys-arch }}-cmake mingw-w64-clang-${{ matrix.msys-arch }}-clang mingw-w64-clang-${{ matrix.msys-arch }}-vulkan-loader mingw-w64-clang-${{ matrix.msys-arch }}-vulkan-headers mingw-w64-clang-${{ matrix.msys-arch }}-opencl-icd mingw-w64-clang-${{ matrix.msys-arch }}-opencl-headers mingw-w64-clang-${{ matrix.msys-arch }}-cppwinrt mingw-w64-clang-${{ matrix.msys-arch }}-imagemagick mingw-w64-clang-${{ matrix.msys-arch }}-chafa mingw-w64-clang-${{ matrix.msys-arch }}-directx-headers
-
- - name: print msys version
- run: uname -a
-
- - name: configure project
- run: env PKG_CONFIG_PATH=/${{ matrix.msystem-lower }}/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
-
- - name: build project
- run: cmake --build . --verbose -j4
-
- - name: copy necessary dlls
- run: cp /${{ matrix.msystem-lower }}/bin/{OpenCL,vulkan-1}.dll .
-
- - name: list features
- run: ./fastfetch --list-features
-
- - name: run fastfetch
- run: time ./fastfetch -c presets/ci.jsonc --stat false
-
- - name: run fastfetch --format json
- run: time ./fastfetch -c presets/ci.jsonc --format json
-
- - name: run flashfetch
- run: time ./flashfetch
-
- - name: print dependencies
- run: ldd fastfetch
-
- - name: run tests
- run: ctest --output-on-failure
-
- - if: github.event_name == 'push' && github.repository == 'fastfetch-cli/fastfetch'
- id: upload-unsigned-artifact
- name: upload artifacts for signing
- uses: actions/upload-artifact@v7
- with:
- name: fastfetch-windows-${{ matrix.arch }}
- path: |
- *.dll
- fastfetch.exe
- flashfetch.exe
-
- - if: github.event_name == 'push' && github.repository == 'fastfetch-cli/fastfetch'
- name: submit signing request
- uses: signpath/github-action-submit-signing-request@v1
- with:
- api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
- organization-id: '${{ vars.SIGNPATH_ORG_ID }}'
- project-slug: 'fastfetch'
- signing-policy-slug: ${{ github.ref == 'refs/heads/master' && 'release-signing' || 'test-signing' }}
- github-artifact-id: '${{ steps.upload-unsigned-artifact.outputs.artifact-id }}'
- wait-for-completion: true
- output-artifact-directory: '.'
-
- - name: create zip archive
- run: 7z a -tzip -mx9 -bd -y fastfetch-windows-${{ matrix.arch }}.zip LICENSE *.dll fastfetch.exe flashfetch.exe presets
-
- - name: create 7z archive
- run: 7z a -t7z -mx9 -bd -y fastfetch-windows-${{ matrix.arch }}.7z LICENSE *.dll fastfetch.exe flashfetch.exe presets
-
- - name: upload true artifacts
- uses: actions/upload-artifact@v7
- with:
- name: fastfetch-windows-${{ matrix.arch }}
- path: ./fastfetch-windows-${{ matrix.arch }}.*
- overwrite: true
+ uses: ./.github/workflows/build-windows-hosts.yml
+ with:
+ arch: ${{ matrix.arch }}
+ runs-on: ${{ matrix.runs-on }}
+ msystem: ${{ matrix.msystem }}
+ msystem-lower: ${{ matrix.msystem-lower }}
+ msys-arch: ${{ matrix.msys-arch }}
+ secrets: inherit
release:
if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'fastfetch-cli/fastfetch'
name: Release
- runs-on: ubuntu-latest
needs:
- linux-hosts
- linux-i686
@@ -810,49 +195,7 @@ jobs:
- windows-hosts
permissions:
contents: write
- steps:
- - name: get latest release version
- id: get_version_release
- uses: pozetroninc/github-action-get-latest-release@master
- with:
- repository: ${{ github.repository }}
-
- - name: download artifacts
- if: needs.linux-hosts.outputs.ffversion != steps.get_version_release.outputs.release
- uses: actions/download-artifact@v8
-
- - name: create release
- if: needs.linux-hosts.outputs.ffversion != steps.get_version_release.outputs.release
- uses: ncipollo/release-action@v1
- with:
- tag: ${{ needs.linux-hosts.outputs.ffversion }}
- commit: ${{ github.sha }}
- artifactErrorsFailBuild: true
- artifacts: fastfetch-*/fastfetch-*
- body: "Please refer to [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/${{ needs.linux-hosts.outputs.ffversion }}/CHANGELOG.md) for details."
-
- - name: download source tarballs
- if: needs.linux-hosts.outputs.ffversion != steps.get_version_release.outputs.release
- run: |
- for i in 1 2 3 4 5; do curl -L --remote-name-all --output-dir fastfetch-source --create-dirs https://github.com/${{ github.repository }}/archive/refs/tags/${{ needs.linux-hosts.outputs.ffversion }}.{tar.gz,zip} && break || sleep 5; done
- ls fastfetch-*/*
-
- - name: generate release notes
- if: needs.linux-hosts.outputs.ffversion != steps.get_version_release.outputs.release
- run: |
- echo "Please refer to [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/${{ needs.linux-hosts.outputs.ffversion }}/CHANGELOG.md) for details." > fastfetch-release-notes.md
- echo -e "\n---\n\nSHA256SUMs
\n\n\`\`\`" >> fastfetch-release-notes.md
- sha256sum fastfetch-*/* >> fastfetch-release-notes.md
- echo -e "\`\`\`\n " >> fastfetch-release-notes.md
- echo -e "\nSHA512SUMs
\n\n\`\`\`" >> fastfetch-release-notes.md
- sha512sum fastfetch-*/* >> fastfetch-release-notes.md
- echo -e "\`\`\`\n " >> fastfetch-release-notes.md
-
- - name: update release body
- if: needs.linux-hosts.outputs.ffversion != steps.get_version_release.outputs.release
- uses: ncipollo/release-action@v1
- with:
- tag: ${{ needs.linux-hosts.outputs.ffversion }}
- commit: ${{ github.sha }}
- bodyFile: fastfetch-release-notes.md
- allowUpdates: true
+ uses: ./.github/workflows/build-release.yml
+ with:
+ ffversion: ${{ needs.linux-hosts.outputs.ffversion }}
+ secrets: inherit
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8d51df5d82..a803b726bb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -401,7 +401,7 @@ set(LIBFASTFETCH_SRC
src/common/impl/FFstrbuf.c
src/common/impl/path.c
src/common/impl/FFPlatform.c
- src/common/impl/smbiosHelper.c
+ src/common/impl/smbios.c
src/detection/bluetoothradio/bluetoothradio.c
src/detection/bootmgr/bootmgr.c
src/detection/chassis/chassis.c
@@ -561,7 +561,7 @@ if(LINUX)
src/detection/gpu/gpu_linux.c
src/detection/gpu/gpu_drm.c
src/detection/gpu/gpu_pci.c
- src/detection/gpu/gpu_wsl.c
+ src/detection/gpu/gpu_windows.c
src/detection/gtk_qt/gtk.c
src/detection/host/host_linux.c
src/detection/icons/icons_linux.c
@@ -793,7 +793,7 @@ elseif(NetBSD)
src/detection/cursor/cursor_linux.c
src/detection/disk/disk_bsd.c
src/detection/dns/dns_linux.c
- src/detection/physicaldisk/physicaldisk_nosupport.c
+ src/detection/physicaldisk/physicaldisk_nbsd.c
src/detection/physicalmemory/physicalmemory_linux.c
src/detection/diskio/diskio_nbsd.c
src/detection/displayserver/linux/displayserver_linux.c
@@ -860,7 +860,7 @@ elseif(OpenBSD)
src/common/impl/sysctl.c
src/common/impl/FFPlatform_unix.c
src/common/impl/binary_linux.c
- src/common/impl/smbiosHelper.c
+ src/common/impl/smbios.c
src/common/impl/kmod_nosupport.c
src/detection/battery/battery_obsd.c
src/detection/bios/bios_windows.c
@@ -877,7 +877,7 @@ elseif(OpenBSD)
src/detection/cursor/cursor_linux.c
src/detection/disk/disk_bsd.c
src/detection/dns/dns_linux.c
- src/detection/physicaldisk/physicaldisk_nosupport.c
+ src/detection/physicaldisk/physicaldisk_obsd.c
src/detection/physicalmemory/physicalmemory_linux.c
src/detection/diskio/diskio_obsd.c
src/detection/displayserver/linux/displayserver_linux.c
@@ -1767,12 +1767,14 @@ elseif(OpenBSD)
PRIVATE "m"
PRIVATE "kvm"
PRIVATE "sndio"
+ PRIVATE "util"
)
elseif(NetBSD)
target_link_libraries(libfastfetch
PRIVATE "bluetooth"
PRIVATE "m"
PRIVATE "prop"
+ PRIVATE "util"
)
elseif(SunOS)
target_link_libraries(libfastfetch
diff --git a/debian/changelog.tpl b/debian/changelog.tpl
index 2144517a68..1024e4f622 100644
--- a/debian/changelog.tpl
+++ b/debian/changelog.tpl
@@ -1,3 +1,9 @@
+fastfetch (2.61.0~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
+
+ * Update to 2.61.0
+
+ -- Carter Li Mon, 30 Mar 2026 09:51:18 +0800
+
fastfetch (2.58.0~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
* Update to 2.58.0
diff --git a/debian/control b/debian/control
index ed371f48a7..9cc8c32eb8 100644
--- a/debian/control
+++ b/debian/control
@@ -2,7 +2,7 @@ Source: fastfetch
Section: universe/utils
Priority: optional
Maintainer: Carter Li
-Build-Depends: libelf-dev, libvulkan-dev, libwayland-dev, libxrandr-dev, libxcb-randr0-dev, libdconf-dev, libdbus-1-dev, libmagickcore-dev, libsqlite3-dev, librpm-dev, libegl-dev, libglx-dev, ocl-icd-opencl-dev, libpulse-dev, libdrm-dev, libddcutil-dev, libchafa-dev, directx-headers-dev, pkgconf, cmake (>= 3.12), debhelper (>= 11.2), dh-cmake, dh-cmake-compat (= 1), dh-sequence-cmake, dh-sequence-ctest, ninja-build, python3-setuptools
+Build-Depends: libelf-dev, libvulkan-dev, libwayland-dev, libxrandr-dev, libxcb-randr0-dev, libdconf-dev, libdbus-1-dev, libmagickcore-dev, libsqlite3-dev, librpm-dev, libegl-dev, libglx-dev, ocl-icd-opencl-dev, libpulse-dev, libdrm-dev, libddcutil-dev, libchafa-dev, pkgconf, cmake (>= 3.12), debhelper (>= 11.2), dh-cmake, dh-cmake-compat (= 1), dh-sequence-cmake, dh-sequence-ctest, ninja-build, python3-setuptools
Standards-Version: 4.0.0
Homepage: https://github.com/fastfetch-cli/fastfetch
diff --git a/doc/json_schema.json b/doc/json_schema.json
index 6efa904c31..8d1d168be0 100644
--- a/doc/json_schema.json
+++ b/doc/json_schema.json
@@ -13,45 +13,45 @@
},
{
"type": "null",
- "$comment": "Disable default color"
+ "$comment": "Disable default coloring"
}
]
},
"key": {
- "description": "Key of the module\nOne whitespace character (` `) can be used to hide the key",
+ "description": "Module key\nUse a single space (` `) to hide the key",
"type": "string",
"minLength": 1
},
"keyColor": {
- "description": "Color of the module key to override the global setting `display.color.key`",
+ "description": "Color of the module key. Overrides `display.color.key`",
"$ref": "#/$defs/colors"
},
"keyWidth": {
- "description": "Width of the module key to override the global setting `display.keyWidth`",
+ "description": "Width of the module key. Overrides `display.keyWidth`",
"type": "integer",
"minimum": 1
},
"keyIcon": {
- "description": "Set the icon to be displayed by `display.keyType: \"icon\"`",
+ "description": "Icon to display when `display.key.type` is set to `icon`",
"type": "string"
},
"outputColor": {
- "description": "Output color of the module to override the global setting `display.color.output`",
+ "description": "Color of the module output. Overrides `display.color.output`",
"$ref": "#/$defs/colors"
},
"percentType": {
- "description": "Set the percentage output type",
+ "description": "Percentage output style",
"oneOf": [
{
"type": "number",
- "description": "0 to use global setting, 1 for percentage number, 2 for multi-color bar, 3 for both, 6 for bar only, 9 for colored number, 10 for monochrome bar",
+ "description": "0 uses the global setting; 1 shows the percentage number; 2 shows a multicolor bar; 3 shows both; 6 shows only the bar; 9 shows a colored number; 10 shows a monochrome bar",
"minimum": 0,
"maximum": 255,
"default": 9
},
{
"type": "array",
- "description": "Array of string flags",
+ "description": "Array of style flags",
"items": {
"enum": [
"num",
@@ -70,7 +70,7 @@
]
},
"percent": {
- "description": "Thresholds for percentage colors",
+ "description": "Color thresholds for percentage output",
"type": "object",
"additionalProperties": false,
"properties": {
@@ -78,13 +78,13 @@
"type": "integer",
"minimum": 0,
"maximum": 100,
- "description": "Values less than green will be shown in green"
+ "description": "Values below this threshold are shown in green"
},
"yellow": {
"type": "integer",
"minimum": 0,
"maximum": 100,
- "description": "Values greater than green and less than yellow will be shown in yellow.\nValues greater than yellow will be shown in red"
+ "description": "Values between the green and yellow thresholds are shown in yellow.\nValues above the yellow threshold are shown in red"
},
"type": {
"$ref": "#/$defs/percentType"
@@ -92,7 +92,7 @@
}
},
"temperature": {
- "description": "Detect and display temperature if supported",
+ "description": "Whether to detect and display temperature, if supported",
"oneOf": [
{
"type": "boolean",
@@ -106,13 +106,13 @@
"type": "integer",
"minimum": 0,
"maximum": 100,
- "description": "Values (in celsius) less than green will be shown in green"
+ "description": "Values in Celsius below this threshold are shown in green"
},
"yellow": {
"type": "integer",
"minimum": 0,
"maximum": 100,
- "description": "Values (in celsius) greater than green and less than yellow will be shown in yellow.\nValues greater than yellow will be shown in red"
+ "description": "Values in Celsius between the green and yellow thresholds are shown in yellow.\nValues above the yellow threshold are shown in red"
}
}
}
@@ -154,12 +154,12 @@
]
},
"conditions": {
- "description": "Only show the module if conditions are met",
+ "description": "Show the module only if these conditions are met",
"type": "object",
"additionalProperties": false,
"properties": {
"system": {
- "description": "System name to match",
+ "description": "System to match",
"oneOf": [
{
"$ref": "#/$defs/systems"
@@ -170,16 +170,16 @@
"items": {
"$ref": "#/$defs/systems"
},
- "description": "Array of system names to match"
+ "description": "Array of systems to match"
},
{
"type": "null",
- "description": "Null to disable this condition"
+ "description": "Set to null to disable this condition"
}
]
},
"!system": {
- "description": "System name to not match",
+ "description": "System not to match",
"oneOf": [
{
"$ref": "#/$defs/systems"
@@ -190,11 +190,11 @@
"items": {
"$ref": "#/$defs/systems"
},
- "description": "Array of system names to not match"
+ "description": "Array of systems not to match"
},
{
"type": "null",
- "description": "Null to disable this condition"
+ "description": "Set to null to disable this condition"
}
]
},
@@ -214,12 +214,12 @@
},
{
"type": "null",
- "description": "Null to disable this condition"
+ "description": "Set to null to disable this condition"
}
]
},
"!arch": {
- "description": "Architecture to not match",
+ "description": "Architecture not to match",
"oneOf": [
{
"$ref": "#/$defs/architectures"
@@ -230,11 +230,11 @@
"items": {
"$ref": "#/$defs/architectures"
},
- "description": "Array of architectures to not match"
+ "description": "Array of architectures not to match"
},
{
"type": "null",
- "description": "Null to disable this condition"
+ "description": "Set to null to disable this condition"
}
]
},
@@ -243,11 +243,11 @@
"oneOf": [
{
"type": "boolean",
- "description": "True to only show the module if it succeeded, false to only show it if it failed"
+ "description": "True to show the module only if it succeeded; false to show it only if it failed"
},
{
"type": "null",
- "description": "Null to disable this condition"
+ "description": "Set to null to disable this condition"
}
]
}
@@ -255,7 +255,7 @@
},
"spaceBeforeUnit": {
"type": "string",
- "description": "Whether to put a space before the unit",
+ "description": "Whether to insert a space before the unit",
"oneOf": [
{
"const": "default",
@@ -274,295 +274,295 @@
"batteryFormat": {
- "description": "Output format of the module `Battery`. See Wiki for formatting syntax\n 1. {manufacturer}: Battery manufacturer\n 2. {model-name}: Battery model name\n 3. {technology}: Battery technology\n 4. {capacity}: Battery capacity (percentage num)\n 5. {status}: Battery status\n 6. {temperature}: Battery temperature (formatted)\n 7. {cycle-count}: Battery cycle count\n 8. {serial}: Battery serial number\n 9. {manufacture-date}: Battery manufactor date\n 10. {capacity-bar}: Battery capacity (percentage bar)\n 11. {time-days}: Battery time remaining days\n 12. {time-hours}: Battery time remaining hours\n 13. {time-minutes}: Battery time remaining minutes\n 14. {time-seconds}: Battery time remaining seconds\n 15. {time-formatted}: Battery time remaining (formatted)",
+ "description": "Output format for the `Battery` module. See Wiki for formatting syntax\n 1. {manufacturer}: Battery manufacturer\n 2. {model-name}: Battery model name\n 3. {technology}: Battery technology\n 4. {capacity}: Battery capacity (percentage num)\n 5. {status}: Battery status\n 6. {temperature}: Battery temperature (formatted)\n 7. {cycle-count}: Battery cycle count\n 8. {serial}: Battery serial number\n 9. {manufacture-date}: Battery manufacture date\n 10. {capacity-bar}: Battery capacity (percentage bar)\n 11. {time-days}: Battery time remaining days\n 12. {time-hours}: Battery time remaining hours\n 13. {time-minutes}: Battery time remaining minutes\n 14. {time-seconds}: Battery time remaining seconds\n 15. {time-formatted}: Battery time remaining (formatted)",
"type": "string"
},
"biosFormat": {
- "description": "Output format of the module `BIOS`. See Wiki for formatting syntax\n 1. {date}: Bios date\n 2. {release}: Bios release\n 3. {vendor}: Bios vendor\n 4. {version}: Bios version\n 5. {type}: Firmware type",
+ "description": "Output format for the `BIOS` module. See Wiki for formatting syntax\n 1. {date}: BIOS date\n 2. {release}: BIOS release\n 3. {vendor}: BIOS vendor\n 4. {version}: BIOS version\n 5. {type}: Firmware type",
"type": "string"
},
"bluetoothFormat": {
- "description": "Output format of the module `Bluetooth`. See Wiki for formatting syntax\n 1. {name}: Name\n 2. {address}: Address\n 3. {type}: Type\n 4. {battery-percentage}: Battery percentage number\n 5. {connected}: Is connected\n 6. {battery-percentage-bar}: Battery percentage bar",
+ "description": "Output format for the `Bluetooth` module. See Wiki for formatting syntax\n 1. {name}: Name\n 2. {address}: Address\n 3. {type}: Type\n 4. {battery-percentage}: Battery percentage number\n 5. {connected}: Is connected\n 6. {battery-percentage-bar}: Battery percentage bar",
"type": "string"
},
"bluetoothradioFormat": {
- "description": "Output format of the module `BluetoothRadio`. See Wiki for formatting syntax\n 1. {name}: Radio name for discovering\n 2. {address}: Address\n 3. {lmp-version}: LMP version\n 4. {lmp-subversion}: LMP subversion\n 5. {version}: Bluetooth version\n 6. {vendor}: Vendor\n 7. {discoverable}: Discoverable\n 8. {connectable}: Connectable / Pairable",
+ "description": "Output format for the `BluetoothRadio` module. See Wiki for formatting syntax\n 1. {name}: Radio name for discovering\n 2. {address}: Address\n 3. {lmp-version}: LMP version\n 4. {lmp-subversion}: LMP subversion\n 5. {version}: Bluetooth version\n 6. {vendor}: Vendor\n 7. {discoverable}: Discoverable\n 8. {connectable}: Connectable / Pairable",
"type": "string"
},
"boardFormat": {
- "description": "Output format of the module `Board`. See Wiki for formatting syntax\n 1. {name}: Board name\n 2. {vendor}: Board vendor\n 3. {version}: Board version\n 4. {serial}: Board serial number",
+ "description": "Output format for the `Board` module. See Wiki for formatting syntax\n 1. {name}: Board name\n 2. {vendor}: Board vendor\n 3. {version}: Board version\n 4. {serial}: Board serial number",
"type": "string"
},
"bootmgrFormat": {
- "description": "Output format of the module `Bootmgr`. See Wiki for formatting syntax\n 1. {name}: Name / description\n 2. {firmware-path}: Firmware file path\n 3. {firmware-name}: Firmware file name\n 4. {secure-boot}: Is secure boot enabled\n 5. {order}: Boot order",
+ "description": "Output format for the `Bootmgr` module. See Wiki for formatting syntax\n 1. {name}: Name / description\n 2. {firmware-path}: Firmware file path\n 3. {firmware-name}: Firmware file name\n 4. {secure-boot}: Is secure boot enabled\n 5. {order}: Boot order",
"type": "string"
},
"brightnessFormat": {
- "description": "Output format of the module `Brightness`. See Wiki for formatting syntax\n 1. {percentage}: Screen brightness (percentage num)\n 2. {name}: Screen name\n 3. {max}: Maximum brightness value\n 4. {min}: Minimum brightness value\n 5. {current}: Current brightness value\n 6. {percentage-bar}: Screen brightness (percentage bar)\n 7. {is-builtin}: Is built-in screen",
+ "description": "Output format for the `Brightness` module. See Wiki for formatting syntax\n 1. {percentage}: Screen brightness (percentage num)\n 2. {name}: Screen name\n 3. {max}: Maximum brightness value\n 4. {min}: Minimum brightness value\n 5. {current}: Current brightness value\n 6. {percentage-bar}: Screen brightness (percentage bar)\n 7. {is-builtin}: Is built-in screen",
"type": "string"
},
"btrfsFormat": {
- "description": "Output format of the module `Btrfs`. See Wiki for formatting syntax\n 1. {name}: Name / Label\n 2. {uuid}: UUID\n 3. {devices}: Associated devices\n 4. {features}: Enabled features\n 5. {used}: Size used\n 6. {allocated}: Size allocated\n 7. {total}: Size total\n 8. {used-percentage}: Used percentage num\n 9. {allocated-percentage}: Allocated percentage num\n 10. {used-percentage-bar}: Used percentage bar\n 11. {allocated-percentage-bar}: Allocated percentage bar\n 12. {node-size}: Node size\n 13. {sector-size}: Sector size",
+ "description": "Output format for the `Btrfs` module. See Wiki for formatting syntax\n 1. {name}: Name / Label\n 2. {uuid}: UUID\n 3. {devices}: Associated devices\n 4. {features}: Enabled features\n 5. {used}: Size used\n 6. {allocated}: Size allocated\n 7. {total}: Size total\n 8. {used-percentage}: Used percentage num\n 9. {allocated-percentage}: Allocated percentage num\n 10. {used-percentage-bar}: Used percentage bar\n 11. {allocated-percentage-bar}: Allocated percentage bar\n 12. {node-size}: Node size\n 13. {sector-size}: Sector size",
"type": "string"
},
"cameraFormat": {
- "description": "Output format of the module `Camera`. See Wiki for formatting syntax\n 1. {name}: Device name\n 2. {vendor}: Vendor\n 3. {colorspace}: Color space\n 4. {id}: Identifier\n 5. {width}: Width (in px)\n 6. {height}: Height (in px)",
+ "description": "Output format for the `Camera` module. See Wiki for formatting syntax\n 1. {name}: Device name\n 2. {vendor}: Vendor\n 3. {colorspace}: Color space\n 4. {id}: Identifier\n 5. {width}: Width (in px)\n 6. {height}: Height (in px)",
"type": "string"
},
"chassisFormat": {
- "description": "Output format of the module `Chassis`. See Wiki for formatting syntax\n 1. {type}: Chassis type\n 2. {vendor}: Chassis vendor\n 3. {version}: Chassis version\n 4. {serial}: Chassis serial number",
+ "description": "Output format for the `Chassis` module. See Wiki for formatting syntax\n 1. {type}: Chassis type\n 2. {vendor}: Chassis vendor\n 3. {version}: Chassis version\n 4. {serial}: Chassis serial number",
"type": "string"
},
"commandFormat": {
- "description": "Output format of the module `Command`. See Wiki for formatting syntax\n 1. {result}: Command result",
+ "description": "Output format for the `Command` module. See Wiki for formatting syntax\n 1. {result}: Command result",
"type": "string"
},
"cpuFormat": {
- "description": "Output format of the module `CPU`. See Wiki for formatting syntax\n 1. {name}: Name\n 2. {vendor}: Vendor\n 3. {cores-physical}: Physical core count\n 4. {cores-logical}: Logical core count\n 5. {cores-online}: Online core count\n 6. {freq-base}: Base frequency (formatted)\n 7. {freq-max}: Max frequency (formatted)\n 8. {temperature}: Temperature (formatted)\n 9. {core-types}: Logical core count grouped by frequency\n 10. {packages}: Processor package count\n 11. {march}: CPU microarchitecture\n 12. {numa-nodes}: NUMA node count",
+ "description": "Output format for the `CPU` module. See Wiki for formatting syntax\n 1. {name}: Name\n 2. {vendor}: Vendor\n 3. {cores-physical}: Physical core count\n 4. {cores-logical}: Logical core count\n 5. {cores-online}: Online core count\n 6. {freq-base}: Base frequency (formatted)\n 7. {freq-max}: Max frequency (formatted)\n 8. {temperature}: Temperature (formatted)\n 9. {core-types}: Logical core count grouped by frequency\n 10. {packages}: Processor package count\n 11. {march}: CPU microarchitecture\n 12. {numa-nodes}: NUMA node count",
"type": "string"
},
"cpucacheFormat": {
- "description": "Output format of the module `CPUCache`. See Wiki for formatting syntax\n 1. {result}: Separate result\n 2. {sum}: Sum result",
+ "description": "Output format for the `CPUCache` module. See Wiki for formatting syntax\n 1. {result}: Separate result\n 2. {sum}: Sum result",
"type": "string"
},
"cpuusageFormat": {
- "description": "Output format of the module `CPUUsage`. See Wiki for formatting syntax\n 1. {avg}: CPU usage (percentage num, average)\n 2. {max}: CPU usage (percentage num, maximum)\n 3. {max-index}: CPU core index of maximum usage\n 4. {min}: CPU usage (percentage num, minimum)\n 5. {min-index}: CPU core index of minimum usage\n 6. {avg-bar}: CPU usage (percentage bar, average)\n 7. {max-bar}: CPU usage (percentage bar, maximum)\n 8. {min-bar}: CPU usage (percentage bar, minimum)",
+ "description": "Output format for the `CPUUsage` module. See Wiki for formatting syntax\n 1. {avg}: CPU usage (percentage num, average)\n 2. {max}: CPU usage (percentage num, maximum)\n 3. {max-index}: CPU core index of maximum usage\n 4. {min}: CPU usage (percentage num, minimum)\n 5. {min-index}: CPU core index of minimum usage\n 6. {avg-bar}: CPU usage (percentage bar, average)\n 7. {max-bar}: CPU usage (percentage bar, maximum)\n 8. {min-bar}: CPU usage (percentage bar, minimum)",
"type": "string"
},
"cursorFormat": {
- "description": "Output format of the module `Cursor`. See Wiki for formatting syntax\n 1. {theme}: Cursor theme\n 2. {size}: Cursor size",
+ "description": "Output format for the `Cursor` module. See Wiki for formatting syntax\n 1. {theme}: Cursor theme\n 2. {size}: Cursor size",
"type": "string"
},
"datetimeFormat": {
- "description": "Output format of the module `DateTime`. See Wiki for formatting syntax\n 1. {year}: Year\n 2. {year-short}: Last two digits of year\n 3. {month}: Month\n 4. {month-pretty}: Month with leading zero\n 5. {month-name}: Month name\n 6. {month-name-short}: Month name short\n 7. {week}: Week number on year\n 8. {weekday}: Weekday\n 9. {weekday-short}: Weekday short\n 10. {day-in-year}: Day in year\n 11. {day-in-month}: Day in month\n 12. {day-in-week}: Day in week\n 13. {hour}: Hour\n 14. {hour-pretty}: Hour with leading zero\n 15. {hour-12}: Hour 12h format\n 16. {hour-12-pretty}: Hour 12h format with leading zero\n 17. {minute}: Minute\n 18. {minute-pretty}: Minute with leading zero\n 19. {second}: Second\n 20. {second-pretty}: Second with leading zero\n 21. {offset-from-utc}: Offset from UTC in the ISO 8601 format\n 22. {timezone-name}: Locale-dependent timezone name or abbreviation\n 23. {day-pretty}: Day in month with leading zero",
+ "description": "Output format for the `DateTime` module. See Wiki for formatting syntax\n 1. {year}: Year\n 2. {year-short}: Last two digits of year\n 3. {month}: Month\n 4. {month-pretty}: Month with leading zero\n 5. {month-name}: Month name\n 6. {month-name-short}: Month name short\n 7. {week}: Week number on year\n 8. {weekday}: Weekday\n 9. {weekday-short}: Weekday short\n 10. {day-in-year}: Day in year\n 11. {day-in-month}: Day in month\n 12. {day-in-week}: Day in week\n 13. {hour}: Hour\n 14. {hour-pretty}: Hour with leading zero\n 15. {hour-12}: Hour 12h format\n 16. {hour-12-pretty}: Hour 12h format with leading zero\n 17. {minute}: Minute\n 18. {minute-pretty}: Minute with leading zero\n 19. {second}: Second\n 20. {second-pretty}: Second with leading zero\n 21. {offset-from-utc}: Offset from UTC in the ISO 8601 format\n 22. {timezone-name}: Locale-dependent timezone name or abbreviation\n 23. {day-pretty}: Day in month with leading zero",
"type": "string"
},
"deFormat": {
- "description": "Output format of the module `DE`. See Wiki for formatting syntax\n 1. {process-name}: DE process name\n 2. {pretty-name}: DE pretty name\n 3. {version}: DE version",
+ "description": "Output format for the `DE` module. See Wiki for formatting syntax\n 1. {process-name}: DE process name\n 2. {pretty-name}: DE pretty name\n 3. {version}: DE version",
"type": "string"
},
"displayFormat": {
- "description": "Output format of the module `Display`. See Wiki for formatting syntax\n 1. {width}: Screen configured width (in pixels)\n 2. {height}: Screen configured height (in pixels)\n 3. {refresh-rate}: Screen configured refresh rate (in Hz)\n 4. {scaled-width}: Screen scaled width (in pixels)\n 5. {scaled-height}: Screen scaled height (in pixels)\n 6. {name}: Screen name\n 7. {type}: Screen type (Built-in or External)\n 8. {rotation}: Screen rotation (in degrees)\n 9. {is-primary}: True if being the primary screen\n 10. {physical-width}: Screen physical width (in millimeters)\n 11. {physical-height}: Screen physical height (in millimeters)\n 12. {inch}: Physical diagonal length in inches\n 13. {ppi}: Pixels per inch (PPI)\n 14. {bit-depth}: Bits per color channel\n 15. {hdr-enabled}: True if high dynamic range (HDR) mode is enabled\n 16. {manufacture-year}: Year of manufacturing\n 17. {manufacture-week}: Nth week of manufacturing in the year\n 18. {serial}: Serial number\n 19. {platform-api}: The platform API used when detecting the display\n 20. {hdr-compatible}: True if the display is HDR compatible\n 21. {scale-factor}: HiDPI scale factor\n 22. {preferred-width}: Screen preferred width (in pixels)\n 23. {preferred-height}: Screen preferred height (in pixels)\n 24. {preferred-refresh-rate}: Screen preferred refresh rate (in Hz)\n 25. {dpi}: DPI",
+ "description": "Output format for the `Display` module. See Wiki for formatting syntax\n 1. {width}: Screen configured width (in pixels)\n 2. {height}: Screen configured height (in pixels)\n 3. {refresh-rate}: Screen configured refresh rate (in Hz)\n 4. {scaled-width}: Screen scaled width (in pixels)\n 5. {scaled-height}: Screen scaled height (in pixels)\n 6. {name}: Screen name\n 7. {type}: Screen type (Built-in or External)\n 8. {rotation}: Screen rotation (in degrees)\n 9. {is-primary}: True if being the primary screen\n 10. {physical-width}: Screen physical width (in millimeters)\n 11. {physical-height}: Screen physical height (in millimeters)\n 12. {inch}: Physical diagonal length in inches\n 13. {ppi}: Pixels per inch (PPI)\n 14. {bit-depth}: Bits per color channel\n 15. {hdr-enabled}: True if high dynamic range (HDR) mode is enabled\n 16. {manufacture-year}: Year of manufacturing\n 17. {manufacture-week}: Nth week of manufacturing in the year\n 18. {serial}: Serial number\n 19. {platform-api}: The platform API used when detecting the display\n 20. {hdr-compatible}: True if the display is HDR compatible\n 21. {scale-factor}: HiDPI scale factor\n 22. {preferred-width}: Screen preferred width (in pixels)\n 23. {preferred-height}: Screen preferred height (in pixels)\n 24. {preferred-refresh-rate}: Screen preferred refresh rate (in Hz)\n 25. {dpi}: DPI",
"type": "string"
},
"diskFormat": {
- "description": "Output format of the module `Disk`. See Wiki for formatting syntax\n 1. {size-used}: Size used\n 2. {size-total}: Size total\n 3. {size-percentage}: Size percentage num\n 4. {files-used}: Files used\n 5. {files-total}: Files total\n 6. {files-percentage}: Files percentage num\n 7. {is-external}: True if external volume\n 8. {is-hidden}: True if hidden volume\n 9. {filesystem}: Filesystem\n 10. {name}: Label / name\n 11. {is-readonly}: True if read-only\n 12. {create-time}: Create time in local timezone\n 13. {size-percentage-bar}: Size percentage bar\n 14. {files-percentage-bar}: Files percentage bar\n 15. {days}: Days after creation\n 16. {hours}: Hours after creation\n 17. {minutes}: Minutes after creation\n 18. {seconds}: Seconds after creation\n 19. {milliseconds}: Milliseconds after creation\n 20. {mountpoint}: Mount point / drive letter\n 21. {mount-from}: Mount from (device path)\n 22. {years}: Years integer after creation\n 23. {days-of-year}: Days of year after creation\n 24. {years-fraction}: Years fraction after creation\n 25. {size-free}: Size free\n 26. {size-available}: Size available",
+ "description": "Output format for the `Disk` module. See Wiki for formatting syntax\n 1. {size-used}: Size used\n 2. {size-total}: Size total\n 3. {size-percentage}: Size percentage num\n 4. {files-used}: Files used\n 5. {files-total}: Files total\n 6. {files-percentage}: Files percentage num\n 7. {is-external}: True if external volume\n 8. {is-hidden}: True if hidden volume\n 9. {filesystem}: Filesystem\n 10. {name}: Label / name\n 11. {is-readonly}: True if read-only\n 12. {create-time}: Create time in local timezone\n 13. {size-percentage-bar}: Size percentage bar\n 14. {files-percentage-bar}: Files percentage bar\n 15. {days}: Days after creation\n 16. {hours}: Hours after creation\n 17. {minutes}: Minutes after creation\n 18. {seconds}: Seconds after creation\n 19. {milliseconds}: Milliseconds after creation\n 20. {mountpoint}: Mount point / drive letter\n 21. {mount-from}: Mount from (device path)\n 22. {years}: Years integer after creation\n 23. {days-of-year}: Days of year after creation\n 24. {years-fraction}: Years fraction after creation\n 25. {size-free}: Size free\n 26. {size-available}: Size available",
"type": "string"
},
"diskioFormat": {
- "description": "Output format of the module `DiskIO`. See Wiki for formatting syntax\n 1. {size-read}: Size of data read [per second] (formatted)\n 2. {size-written}: Size of data written [per second] (formatted)\n 3. {name}: Device name\n 4. {dev-path}: Device raw file path\n 5. {bytes-read}: Size of data read [per second] (in bytes)\n 6. {bytes-written}: Size of data written [per second] (in bytes)\n 7. {read-count}: Number of reads\n 8. {write-count}: Number of writes",
+ "description": "Output format for the `DiskIO` module. See Wiki for formatting syntax\n 1. {size-read}: Size of data read [per second] (formatted)\n 2. {size-written}: Size of data written [per second] (formatted)\n 3. {name}: Device name\n 4. {dev-path}: Device raw file path\n 5. {bytes-read}: Size of data read [per second] (in bytes)\n 6. {bytes-written}: Size of data written [per second] (in bytes)\n 7. {read-count}: Number of reads\n 8. {write-count}: Number of writes",
"type": "string"
},
"dnsFormat": {
- "description": "Output format of the module `DNS`. See Wiki for formatting syntax\n 1. {result}: DNS result",
+ "description": "Output format for the `DNS` module. See Wiki for formatting syntax\n 1. {result}: DNS result",
"type": "string"
},
"editorFormat": {
- "description": "Output format of the module `Editor`. See Wiki for formatting syntax\n 1. {type}: Type (Visual / Editor)\n 2. {name}: Name\n 3. {exe-name}: Exe name of real path\n 4. {path}: Full path of real path\n 5. {version}: Version",
+ "description": "Output format for the `Editor` module. See Wiki for formatting syntax\n 1. {type}: Type (Visual / Editor)\n 2. {name}: Name\n 3. {exe-name}: Exe name of real path\n 4. {path}: Full path of real path\n 5. {version}: Version",
"type": "string"
},
"fontFormat": {
- "description": "Output format of the module `Font`. See Wiki for formatting syntax\n 1. {font1}: Font 1\n 2. {font2}: Font 2\n 3. {font3}: Font 3\n 4. {font4}: Font 4\n 5. {combined}: Combined fonts for display",
+ "description": "Output format for the `Font` module. See Wiki for formatting syntax\n 1. {font1}: Font 1\n 2. {font2}: Font 2\n 3. {font3}: Font 3\n 4. {font4}: Font 4\n 5. {combined}: Combined fonts for display",
"type": "string"
},
"gamepadFormat": {
- "description": "Output format of the module `Gamepad`. See Wiki for formatting syntax\n 1. {name}: Name\n 2. {serial}: Serial number\n 3. {battery-percentage}: Battery percentage num\n 4. {battery-percentage-bar}: Battery percentage bar",
+ "description": "Output format for the `Gamepad` module. See Wiki for formatting syntax\n 1. {name}: Name\n 2. {serial}: Serial number\n 3. {battery-percentage}: Battery percentage num\n 4. {battery-percentage-bar}: Battery percentage bar",
"type": "string"
},
"gpuFormat": {
- "description": "Output format of the module `GPU`. See Wiki for formatting syntax\n 1. {vendor}: GPU vendor\n 2. {name}: GPU name\n 3. {driver}: GPU driver\n 4. {temperature}: GPU temperature\n 5. {core-count}: GPU core count\n 6. {type}: GPU type\n 7. {dedicated-total}: GPU total dedicated memory\n 8. {dedicated-used}: GPU used dedicated memory\n 9. {shared-total}: GPU total shared memory\n 10. {shared-used}: GPU used shared memory\n 11. {platform-api}: The platform API used when detecting the GPU\n 12. {frequency}: Current frequency in GHz\n 13. {index}: GPU vendor specific index\n 14. {dedicated-percentage-num}: Dedicated memory usage percentage num\n 15. {dedicated-percentage-bar}: Dedicated memory usage percentage bar\n 16. {shared-percentage-num}: Shared memory usage percentage num\n 17. {shared-percentage-bar}: Shared memory usage percentage bar\n 18. {core-usage-num}: Core usage percentage num\n 19. {core-usage-bar}: Core usage percentage bar\n 20. {memory-type}: Memory type (Windows only)",
+ "description": "Output format for the `GPU` module. See Wiki for formatting syntax\n 1. {vendor}: GPU vendor\n 2. {name}: GPU name\n 3. {driver}: GPU driver\n 4. {temperature}: GPU temperature\n 5. {core-count}: GPU core count\n 6. {type}: GPU type\n 7. {dedicated-total}: GPU total dedicated memory\n 8. {dedicated-used}: GPU used dedicated memory\n 9. {shared-total}: GPU total shared memory\n 10. {shared-used}: GPU used shared memory\n 11. {platform-api}: The platform API used when detecting the GPU\n 12. {frequency}: Current frequency in GHz\n 13. {index}: GPU vendor specific index\n 14. {dedicated-percentage-num}: Dedicated memory usage percentage num\n 15. {dedicated-percentage-bar}: Dedicated memory usage percentage bar\n 16. {shared-percentage-num}: Shared memory usage percentage num\n 17. {shared-percentage-bar}: Shared memory usage percentage bar\n 18. {core-usage-num}: Core usage percentage num\n 19. {core-usage-bar}: Core usage percentage bar\n 20. {memory-type}: Memory type (Windows only)",
"type": "string"
},
"hostFormat": {
- "description": "Output format of the module `Host`. See Wiki for formatting syntax\n 1. {family}: Product family\n 2. {name}: Product name\n 3. {version}: Product version\n 4. {sku}: Product sku\n 5. {vendor}: Product vendor\n 6. {serial}: Product serial number\n 7. {uuid}: Product uuid",
+ "description": "Output format for the `Host` module. See Wiki for formatting syntax\n 1. {family}: Product family\n 2. {name}: Product name\n 3. {version}: Product version\n 4. {sku}: Product sku\n 5. {vendor}: Product vendor\n 6. {serial}: Product serial number\n 7. {uuid}: Product uuid",
"type": "string"
},
"iconsFormat": {
- "description": "Output format of the module `Icons`. See Wiki for formatting syntax\n 1. {icons1}: Icons part 1\n 2. {icons2}: Icons part 2",
+ "description": "Output format for the `Icons` module. See Wiki for formatting syntax\n 1. {icons1}: Icons part 1\n 2. {icons2}: Icons part 2",
"type": "string"
},
"initsystemFormat": {
- "description": "Output format of the module `InitSystem`. See Wiki for formatting syntax\n 1. {name}: Init system name\n 2. {exe}: Init system exe path\n 3. {version}: Init system version path\n 4. {pid}: Init system pid",
+ "description": "Output format for the `InitSystem` module. See Wiki for formatting syntax\n 1. {name}: Init system name\n 2. {exe}: Init system exe path\n 3. {version}: Init system version path\n 4. {pid}: Init system pid",
"type": "string"
},
"kernelFormat": {
- "description": "Output format of the module `Kernel`. See Wiki for formatting syntax\n 1. {sysname}: Sysname\n 2. {release}: Release\n 3. {version}: Version\n 4. {arch}: Architecture\n 5. {display-version}: Display version\n 6. {page-size}: Page size",
+ "description": "Output format for the `Kernel` module. See Wiki for formatting syntax\n 1. {sysname}: Sysname\n 2. {release}: Release\n 3. {version}: Version\n 4. {arch}: Architecture\n 5. {display-version}: Display version\n 6. {page-size}: Page size",
"type": "string"
},
"keyboardFormat": {
- "description": "Output format of the module `Keyboard`. See Wiki for formatting syntax\n 1. {name}: Name\n 2. {serial}: Serial number",
+ "description": "Output format for the `Keyboard` module. See Wiki for formatting syntax\n 1. {name}: Name\n 2. {serial}: Serial number",
"type": "string"
},
"lmFormat": {
- "description": "Output format of the module `LM`. See Wiki for formatting syntax\n 1. {service}: LM service\n 2. {type}: LM type\n 3. {version}: LM version",
+ "description": "Output format for the `LM` module. See Wiki for formatting syntax\n 1. {service}: LM service\n 2. {type}: LM type\n 3. {version}: LM version",
"type": "string"
},
"loadavgFormat": {
- "description": "Output format of the module `Loadavg`. See Wiki for formatting syntax\n 1. {loadavg1}: Load average over 1min\n 2. {loadavg2}: Load average over 5min\n 3. {loadavg3}: Load average over 15min",
+ "description": "Output format for the `Loadavg` module. See Wiki for formatting syntax\n 1. {loadavg1}: Load average over 1min\n 2. {loadavg2}: Load average over 5min\n 3. {loadavg3}: Load average over 15min",
"type": "string"
},
"localeFormat": {
- "description": "Output format of the module `Locale`. See Wiki for formatting syntax\n 1. {result}: Locale code",
+ "description": "Output format for the `Locale` module. See Wiki for formatting syntax\n 1. {result}: Locale code",
"type": "string"
},
"localipFormat": {
- "description": "Output format of the module `LocalIp`. See Wiki for formatting syntax\n 1. {ipv4}: IPv4 address\n 2. {ipv6}: IPv6 address\n 3. {mac}: MAC address\n 4. {ifname}: Interface name\n 5. {is-default-route}: Is default route\n 6. {mtu}: MTU size in bytes\n 7. {speed}: Link speed (formatted)\n 8. {flags}: Interface flags",
+ "description": "Output format for the `LocalIp` module. See Wiki for formatting syntax\n 1. {ipv4}: IPv4 address\n 2. {ipv6}: IPv6 address\n 3. {mac}: MAC address\n 4. {ifname}: Interface name\n 5. {is-default-route}: Is default route\n 6. {mtu}: MTU size in bytes\n 7. {speed}: Link speed (formatted)\n 8. {flags}: Interface flags",
"type": "string"
},
"mediaFormat": {
- "description": "Output format of the module `Media`. See Wiki for formatting syntax\n 1. {combined}: Pretty media name\n 2. {title}: Media name\n 3. {artist}: Artist name\n 4. {album}: Album name\n 5. {status}: Status",
+ "description": "Output format for the `Media` module. See Wiki for formatting syntax\n 1. {combined}: Pretty media name\n 2. {title}: Media name\n 3. {artist}: Artist name\n 4. {album}: Album name\n 5. {status}: Status",
"type": "string"
},
"memoryFormat": {
- "description": "Output format of the module `Memory`. See Wiki for formatting syntax\n 1. {used}: Used size\n 2. {total}: Total size\n 3. {percentage}: Percentage used (num)\n 4. {percentage-bar}: Percentage used (bar)",
+ "description": "Output format for the `Memory` module. See Wiki for formatting syntax\n 1. {used}: Used size\n 2. {total}: Total size\n 3. {percentage}: Percentage used (num)\n 4. {percentage-bar}: Percentage used (bar)",
"type": "string"
},
"monitorFormat": {
- "description": "Output format of the module `Monitor`. See Wiki for formatting syntax\n 1. {name}: Display name\n 2. {width}: Native resolution width in pixels\n 3. {height}: Native resolution height in pixels\n 4. {physical-width}: Physical width in millimeters\n 5. {physical-height}: Physical height in millimeters\n 6. {inch}: Physical diagonal length in inches\n 7. {ppi}: Pixels per inch (PPI)\n 8. {manufacture-year}: Year of manufacturing\n 9. {manufacture-week}: Nth week of manufacturing in the year\n 10. {serial}: Serial number\n 11. {refresh-rate}: Maximum refresh rate in Hz\n 12. {hdr-compatible}: True if the display is HDR compatible",
+ "description": "Output format for the `Monitor` module. See Wiki for formatting syntax\n 1. {name}: Display name\n 2. {width}: Native resolution width in pixels\n 3. {height}: Native resolution height in pixels\n 4. {physical-width}: Physical width in millimeters\n 5. {physical-height}: Physical height in millimeters\n 6. {inch}: Physical diagonal length in inches\n 7. {ppi}: Pixels per inch (PPI)\n 8. {manufacture-year}: Year of manufacturing\n 9. {manufacture-week}: Nth week of manufacturing in the year\n 10. {serial}: Serial number\n 11. {refresh-rate}: Maximum refresh rate in Hz\n 12. {hdr-compatible}: True if the display is HDR compatible",
"type": "string"
},
"mouseFormat": {
- "description": "Output format of the module `Mouse`. See Wiki for formatting syntax\n 1. {name}: Mouse name\n 2. {serial}: Mouse serial number",
+ "description": "Output format for the `Mouse` module. See Wiki for formatting syntax\n 1. {name}: Mouse name\n 2. {serial}: Mouse serial number",
"type": "string"
},
"netioFormat": {
- "description": "Output format of the module `NetIO`. See Wiki for formatting syntax\n 1. {rx-size}: Size of data received [per second] (formatted)\n 2. {tx-size}: Size of data sent [per second] (formatted)\n 3. {ifname}: Interface name\n 4. {is-default-route}: Is default route\n 5. {rx-bytes}: Size of data received [per second] (in bytes)\n 6. {tx-bytes}: Size of data sent [per second] (in bytes)\n 7. {rx-packets}: Number of packets received [per second]\n 8. {tx-packets}: Number of packets sent [per second]\n 9. {rx-errors}: Number of errors received [per second]\n 10. {tx-errors}: Number of errors sent [per second]\n 11. {rx-drops}: Number of packets dropped when receiving [per second]\n 12. {tx-drops}: Number of packets dropped when sending [per second]",
+ "description": "Output format for the `NetIO` module. See Wiki for formatting syntax\n 1. {rx-size}: Size of data received [per second] (formatted)\n 2. {tx-size}: Size of data sent [per second] (formatted)\n 3. {ifname}: Interface name\n 4. {is-default-route}: Is default route\n 5. {rx-bytes}: Size of data received [per second] (in bytes)\n 6. {tx-bytes}: Size of data sent [per second] (in bytes)\n 7. {rx-packets}: Number of packets received [per second]\n 8. {tx-packets}: Number of packets sent [per second]\n 9. {rx-errors}: Number of errors received [per second]\n 10. {tx-errors}: Number of errors sent [per second]\n 11. {rx-drops}: Number of packets dropped when receiving [per second]\n 12. {tx-drops}: Number of packets dropped when sending [per second]",
"type": "string"
},
"openclFormat": {
- "description": "Output format of the module `OpenCL`. See Wiki for formatting syntax\n 1. {version}: Platform version\n 2. {name}: Platform name\n 3. {vendor}: Platform vendor",
+ "description": "Output format for the `OpenCL` module. See Wiki for formatting syntax\n 1. {version}: Platform version\n 2. {name}: Platform name\n 3. {vendor}: Platform vendor",
"type": "string"
},
"openglFormat": {
- "description": "Output format of the module `OpenGL`. See Wiki for formatting syntax\n 1. {version}: OpenGL version\n 2. {renderer}: OpenGL renderer\n 3. {vendor}: OpenGL vendor\n 4. {slv}: OpenGL shading language version\n 5. {library}: OpenGL library used",
+ "description": "Output format for the `OpenGL` module. See Wiki for formatting syntax\n 1. {version}: OpenGL version\n 2. {renderer}: OpenGL renderer\n 3. {vendor}: OpenGL vendor\n 4. {slv}: OpenGL shading language version\n 5. {library}: OpenGL library used",
"type": "string"
},
"osFormat": {
- "description": "Output format of the module `OS`. See Wiki for formatting syntax\n 1. {sysname}: Name of the kernel\n 2. {name}: Name of the OS\n 3. {pretty-name}: Pretty name of the OS, if available\n 4. {id}: ID of the OS\n 5. {id-like}: ID like of the OS\n 6. {variant}: Variant of the OS\n 7. {variant-id}: Variant ID of the OS\n 8. {version}: Version of the OS\n 9. {version-id}: Version ID of the OS\n 10. {codename}: Version codename of the OS\n 11. {build-id}: Build ID of the OS\n 12. {arch}: Architecture of the OS",
+ "description": "Output format for the `OS` module. See Wiki for formatting syntax\n 1. {sysname}: Name of the kernel\n 2. {name}: Name of the OS\n 3. {pretty-name}: Pretty name of the OS, if available\n 4. {id}: ID of the OS\n 5. {id-like}: ID like of the OS\n 6. {variant}: Variant of the OS\n 7. {variant-id}: Variant ID of the OS\n 8. {version}: Version of the OS\n 9. {version-id}: Version ID of the OS\n 10. {codename}: Version codename of the OS\n 11. {build-id}: Build ID of the OS\n 12. {arch}: Architecture of the OS",
"type": "string"
},
"packagesFormat": {
- "description": "Output format of the module `Packages`. See Wiki for formatting syntax\n 1. {all}: Number of all packages\n 2. {pacman}: Number of pacman packages\n 3. {pacman-branch}: Pacman branch on manjaro\n 4. {dpkg}: Number of dpkg packages\n 5. {rpm}: Number of rpm packages\n 6. {emerge}: Number of emerge packages\n 7. {eopkg}: Number of eopkg packages\n 8. {xbps}: Number of xbps packages\n 9. {nix-system}: Number of nix-system packages\n 10. {nix-user}: Number of nix-user packages\n 11. {nix-default}: Number of nix-default packages\n 12. {apk}: Number of apk packages\n 13. {pkg}: Number of pkg packages\n 14. {flatpak-system}: Number of flatpak-system app packages\n 15. {flatpak-user}: Number of flatpak-user app packages\n 16. {snap}: Number of snap packages\n 17. {brew}: Number of brew packages\n 18. {brew-cask}: Number of brew-cask packages\n 19. {macports}: Number of macports packages\n 20. {scoop-user}: Number of scoop-user packages\n 21. {scoop-global}: Number of scoop-global packages\n 22. {choco}: Number of choco packages\n 23. {pkgtool}: Number of pkgtool packages\n 24. {paludis}: Number of paludis packages\n 25. {winget}: Number of winget packages\n 26. {opkg}: Number of opkg packages\n 27. {am-system}: Number of am-system packages\n 28. {sorcery}: Number of sorcery packages\n 29. {lpkg}: Number of lpkg packages\n 30. {lpkgbuild}: Number of lpkgbuild packages\n 31. {guix-system}: Number of guix-system packages\n 32. {guix-user}: Number of guix-user packages\n 33. {guix-home}: Number of guix-home packages\n 34. {linglong}: Number of linglong packages\n 35. {pacstall}: Number of pacstall packages\n 36. {mport}: Number of mport packages\n 37. {am-user}: Number of am-user (aka appman) packages\n 38. {pkgsrc}: Number of pkgsrc packages\n 39. {hpkg-system}: Number of hpkg-system packages\n 40. {hpkg-user}: Number of hpkg-user packages\n 41. {pisi}: Number of pisi packages\n 42. {soar}: Number of soar packages\n 43. {kiss}: Number of kiss packages\n 44. {moss}: Number of moss packages\n 45. {nix-all}: Total number of all nix packages\n 46. {flatpak-all}: Total number of all flatpak app packages\n 47. {brew-all}: Total number of all brew packages\n 48. {guix-all}: Total number of all guix packages\n 49. {hpkg-all}: Total number of all hpkg packages",
+ "description": "Output format for the `Packages` module. See Wiki for formatting syntax\n 1. {all}: Number of all packages\n 2. {pacman}: Number of pacman packages\n 3. {pacman-branch}: Pacman branch on manjaro\n 4. {dpkg}: Number of dpkg packages\n 5. {rpm}: Number of rpm packages\n 6. {emerge}: Number of emerge packages\n 7. {eopkg}: Number of eopkg packages\n 8. {xbps}: Number of xbps packages\n 9. {nix-system}: Number of nix-system packages\n 10. {nix-user}: Number of nix-user packages\n 11. {nix-default}: Number of nix-default packages\n 12. {apk}: Number of apk packages\n 13. {pkg}: Number of pkg packages\n 14. {flatpak-system}: Number of flatpak-system app packages\n 15. {flatpak-user}: Number of flatpak-user app packages\n 16. {snap}: Number of snap packages\n 17. {brew}: Number of brew packages\n 18. {brew-cask}: Number of brew-cask packages\n 19. {macports}: Number of macports packages\n 20. {scoop-user}: Number of scoop-user packages\n 21. {scoop-global}: Number of scoop-global packages\n 22. {choco}: Number of choco packages\n 23. {pkgtool}: Number of pkgtool packages\n 24. {paludis}: Number of paludis packages\n 25. {winget}: Number of winget packages\n 26. {opkg}: Number of opkg packages\n 27. {am-system}: Number of am-system packages\n 28. {sorcery}: Number of sorcery packages\n 29. {lpkg}: Number of lpkg packages\n 30. {lpkgbuild}: Number of lpkgbuild packages\n 31. {guix-system}: Number of guix-system packages\n 32. {guix-user}: Number of guix-user packages\n 33. {guix-home}: Number of guix-home packages\n 34. {linglong}: Number of linglong packages\n 35. {pacstall}: Number of pacstall packages\n 36. {mport}: Number of mport packages\n 37. {am-user}: Number of am-user (aka appman) packages\n 38. {pkgsrc}: Number of pkgsrc packages\n 39. {hpkg-system}: Number of hpkg-system packages\n 40. {hpkg-user}: Number of hpkg-user packages\n 41. {pisi}: Number of pisi packages\n 42. {soar}: Number of soar packages\n 43. {kiss}: Number of kiss packages\n 44. {moss}: Number of moss packages\n 45. {nix-all}: Total number of all nix packages\n 46. {flatpak-all}: Total number of all flatpak app packages\n 47. {brew-all}: Total number of all brew packages\n 48. {guix-all}: Total number of all guix packages\n 49. {hpkg-all}: Total number of all hpkg packages",
"type": "string"
},
"physicaldiskFormat": {
- "description": "Output format of the module `PhysicalDisk`. See Wiki for formatting syntax\n 1. {size}: Device size (formatted)\n 2. {name}: Device name\n 3. {interconnect}: Device interconnect type\n 4. {dev-path}: Device raw file path\n 5. {serial}: Serial number\n 6. {physical-type}: Device kind (SSD or HDD)\n 7. {removable-type}: Device kind (Removable or Fixed)\n 8. {readonly-type}: Device kind (Read-only or Read-write)\n 9. {revision}: Product revision\n 10. {temperature}: Device temperature (formatted)",
+ "description": "Output format for the `PhysicalDisk` module. See Wiki for formatting syntax\n 1. {size}: Device size (formatted)\n 2. {name}: Device name\n 3. {interconnect}: Device interconnect type\n 4. {dev-path}: Device raw file path\n 5. {serial}: Serial number\n 6. {physical-type}: Device kind (SSD or HDD)\n 7. {removable-type}: Device kind (Removable or Fixed)\n 8. {readonly-type}: Device kind (Read-only or Read-write)\n 9. {revision}: Product revision\n 10. {temperature}: Device temperature (formatted)",
"type": "string"
},
"physicalmemoryFormat": {
- "description": "Output format of the module `PhysicalMemory`. See Wiki for formatting syntax\n 1. {bytes}: Size (in bytes)\n 2. {size}: Size formatted\n 3. {max-speed}: Max speed (in MT/s)\n 4. {running-speed}: Running speed (in MT/s)\n 5. {type}: Type (DDR4, DDR5, etc.)\n 6. {form-factor}: Form factor (SODIMM, DIMM, etc.)\n 7. {locator}: Bank/Device Locator (BANK0/SIMM0, BANK0/SIMM1, etc.)\n 8. {vendor}: Vendor\n 9. {serial}: Serial number\n 10. {part-number}: Part number\n 11. {is-ecc-enabled}: True if ECC enabled\n 12. {is-installed}: True if a memory module is installed in the slot",
+ "description": "Output format for the `PhysicalMemory` module. See Wiki for formatting syntax\n 1. {bytes}: Size (in bytes)\n 2. {size}: Size formatted\n 3. {max-speed}: Max speed (in MT/s)\n 4. {running-speed}: Running speed (in MT/s)\n 5. {type}: Type (DDR4, DDR5, etc.)\n 6. {form-factor}: Form factor (SODIMM, DIMM, etc.)\n 7. {locator}: Bank/Device Locator (BANK0/SIMM0, BANK0/SIMM1, etc.)\n 8. {vendor}: Vendor\n 9. {serial}: Serial number\n 10. {part-number}: Part number\n 11. {is-ecc-enabled}: True if ECC enabled\n 12. {is-installed}: True if a memory module is installed in the slot",
"type": "string"
},
"playerFormat": {
- "description": "Output format of the module `Player`. See Wiki for formatting syntax\n 1. {player}: Pretty player name\n 2. {name}: Player name\n 3. {id}: Player Identifier\n 4. {url}: URL name",
+ "description": "Output format for the `Player` module. See Wiki for formatting syntax\n 1. {player}: Pretty player name\n 2. {name}: Player name\n 3. {id}: Player Identifier\n 4. {url}: URL name",
"type": "string"
},
"poweradapterFormat": {
- "description": "Output format of the module `PowerAdapter`. See Wiki for formatting syntax\n 1. {watts}: Power adapter watts\n 2. {name}: Power adapter name\n 3. {manufacturer}: Power adapter manufacturer\n 4. {model}: Power adapter model\n 5. {description}: Power adapter description\n 6. {serial}: Power adapter serial number",
+ "description": "Output format for the `PowerAdapter` module. See Wiki for formatting syntax\n 1. {watts}: Power adapter watts\n 2. {name}: Power adapter name\n 3. {manufacturer}: Power adapter manufacturer\n 4. {model}: Power adapter model\n 5. {description}: Power adapter description\n 6. {serial}: Power adapter serial number",
"type": "string"
},
"processesFormat": {
- "description": "Output format of the module `Processes`. See Wiki for formatting syntax\n 1. {result}: Process count",
+ "description": "Output format for the `Processes` module. See Wiki for formatting syntax\n 1. {result}: Process count",
"type": "string"
},
"publicipFormat": {
- "description": "Output format of the module `PublicIp`. See Wiki for formatting syntax\n 1. {ip}: Public IP address\n 2. {location}: Location",
+ "description": "Output format for the `PublicIp` module. See Wiki for formatting syntax\n 1. {ip}: Public IP address\n 2. {location}: Location",
"type": "string"
},
"shellFormat": {
- "description": "Output format of the module `Shell`. See Wiki for formatting syntax\n 1. {process-name}: Shell process name\n 2. {exe}: The first argument of the command line when running the shell\n 3. {exe-name}: Shell base name of arg0\n 4. {version}: Shell version\n 5. {pid}: Shell pid\n 6. {pretty-name}: Shell pretty name\n 7. {exe-path}: Shell full exe path\n 8. {tty}: Shell tty used",
+ "description": "Output format for the `Shell` module. See Wiki for formatting syntax\n 1. {process-name}: Shell process name\n 2. {exe}: The first argument of the command line when running the shell\n 3. {exe-name}: Shell base name of arg0\n 4. {version}: Shell version\n 5. {pid}: Shell pid\n 6. {pretty-name}: Shell pretty name\n 7. {exe-path}: Shell full exe path\n 8. {tty}: Shell tty used",
"type": "string"
},
"soundFormat": {
- "description": "Output format of the module `Sound`. See Wiki for formatting syntax\n 1. {is-main}: Is main sound device\n 2. {name}: Device name\n 3. {volume-percentage}: Volume (in percentage num)\n 4. {identifier}: Identifier\n 5. {volume-percentage-bar}: Volume (in percentage bar)\n 6. {platform-api}: Platform API used",
+ "description": "Output format for the `Sound` module. See Wiki for formatting syntax\n 1. {is-main}: Is main sound device\n 2. {is-active}: Is active sound device\n 3. {name}: Device name\n 4. {volume-percentage}: Volume (in percentage num)\n 5. {identifier}: Identifier\n 6. {volume-percentage-bar}: Volume (in percentage bar)\n 7. {platform-api}: Platform API used",
"type": "string"
},
"swapFormat": {
- "description": "Output format of the module `Swap`. See Wiki for formatting syntax\n 1. {used}: Used size\n 2. {total}: Total size\n 3. {percentage}: Percentage used (num)\n 4. {percentage-bar}: Percentage used (bar)\n 5. {name}: Name",
+ "description": "Output format for the `Swap` module. See Wiki for formatting syntax\n 1. {used}: Used size\n 2. {total}: Total size\n 3. {percentage}: Percentage used (num)\n 4. {percentage-bar}: Percentage used (bar)\n 5. {name}: Name",
"type": "string"
},
"terminalFormat": {
- "description": "Output format of the module `Terminal`. See Wiki for formatting syntax\n 1. {process-name}: Terminal process name\n 2. {exe}: The first argument of the command line when running the terminal\n 3. {exe-name}: Terminal base name of arg0\n 4. {pid}: Terminal pid\n 5. {pretty-name}: Terminal pretty name\n 6. {version}: Terminal version\n 7. {exe-path}: Terminal full exe path\n 8. {tty}: Terminal tty / pts used",
+ "description": "Output format for the `Terminal` module. See Wiki for formatting syntax\n 1. {process-name}: Terminal process name\n 2. {exe}: The first argument of the command line when running the terminal\n 3. {exe-name}: Terminal base name of arg0\n 4. {pid}: Terminal pid\n 5. {pretty-name}: Terminal pretty name\n 6. {version}: Terminal version\n 7. {exe-path}: Terminal full exe path\n 8. {tty}: Terminal tty / pts used",
"type": "string"
},
"terminalfontFormat": {
- "description": "Output format of the module `TerminalFont`. See Wiki for formatting syntax\n 1. {combined}: Terminal font combined\n 2. {name}: Terminal font name\n 3. {size}: Terminal font size\n 4. {styles}: Terminal font styles",
+ "description": "Output format for the `TerminalFont` module. See Wiki for formatting syntax\n 1. {combined}: Terminal font combined\n 2. {name}: Terminal font name\n 3. {size}: Terminal font size\n 4. {styles}: Terminal font styles",
"type": "string"
},
"terminalsizeFormat": {
- "description": "Output format of the module `TerminalSize`. See Wiki for formatting syntax\n 1. {rows}: Terminal rows\n 2. {columns}: Terminal columns\n 3. {width}: Terminal width (in pixels)\n 4. {height}: Terminal height (in pixels)",
+ "description": "Output format for the `TerminalSize` module. See Wiki for formatting syntax\n 1. {rows}: Terminal rows\n 2. {columns}: Terminal columns\n 3. {width}: Terminal width (in pixels)\n 4. {height}: Terminal height (in pixels)",
"type": "string"
},
"terminalthemeFormat": {
- "description": "Output format of the module `TerminalTheme`. See Wiki for formatting syntax\n 1. {fg-color}: Terminal foreground color\n 2. {fg-type}: Terminal foreground type (Dark / Light)\n 3. {bg-color}: Terminal background color\n 4. {bg-type}: Terminal background type (Dark / Light)",
+ "description": "Output format for the `TerminalTheme` module. See Wiki for formatting syntax\n 1. {fg-color}: Terminal foreground color\n 2. {fg-type}: Terminal foreground type (Dark / Light)\n 3. {bg-color}: Terminal background color\n 4. {bg-type}: Terminal background type (Dark / Light)",
"type": "string"
},
"titleFormat": {
- "description": "Output format of the module `Title`. See Wiki for formatting syntax\n 1. {user-name}: User name\n 2. {host-name}: Host name\n 3. {home-dir}: Home directory\n 4. {exe-path}: Executable path of current process\n 5. {user-shell}: User's default shell\n 6. {user-name-colored}: User name (colored)\n 7. {at-symbol-colored}: @ symbol (colored)\n 8. {host-name-colored}: Host name (colored)\n 9. {full-user-name}: Full user name\n 10. {user-id}: UID (*nix) / SID (Windows)\n 11. {pid}: PID of current process\n 12. {cwd}: CWD with home dir replaced by `~`",
+ "description": "Output format for the `Title` module. See Wiki for formatting syntax\n 1. {user-name}: User name\n 2. {host-name}: Host name\n 3. {home-dir}: Home directory\n 4. {exe-path}: Executable path of current process\n 5. {user-shell}: User's default shell\n 6. {user-name-colored}: User name (colored)\n 7. {at-symbol-colored}: @ symbol (colored)\n 8. {host-name-colored}: Host name (colored)\n 9. {full-user-name}: Full user name\n 10. {user-id}: UID (*nix) / SID (Windows)\n 11. {pid}: PID of current process\n 12. {cwd}: CWD with home dir replaced by `~`",
"type": "string"
},
"themeFormat": {
- "description": "Output format of the module `Theme`. See Wiki for formatting syntax\n 1. {theme1}: Theme part 1\n 2. {theme2}: Theme part 2",
+ "description": "Output format for the `Theme` module. See Wiki for formatting syntax\n 1. {theme1}: Theme part 1\n 2. {theme2}: Theme part 2",
"type": "string"
},
"tpmFormat": {
- "description": "Output format of the module `TPM`. See Wiki for formatting syntax\n 1. {version}: TPM device version\n 2. {description}: TPM general description",
+ "description": "Output format for the `TPM` module. See Wiki for formatting syntax\n 1. {version}: TPM device version\n 2. {description}: TPM general description",
"type": "string"
},
"uptimeFormat": {
- "description": "Output format of the module `Uptime`. See Wiki for formatting syntax\n 1. {days}: Days after boot\n 2. {hours}: Hours after boot\n 3. {minutes}: Minutes after boot\n 4. {seconds}: Seconds after boot\n 5. {milliseconds}: Milliseconds after boot\n 6. {boot-time}: Boot time in local timezone\n 7. {years}: Years integer after boot\n 8. {days-of-year}: Days of year after boot\n 9. {years-fraction}: Years fraction after boot\n 10. {formatted}: Formatted uptime",
+ "description": "Output format for the `Uptime` module. See Wiki for formatting syntax\n 1. {days}: Days after boot\n 2. {hours}: Hours after boot\n 3. {minutes}: Minutes after boot\n 4. {seconds}: Seconds after boot\n 5. {milliseconds}: Milliseconds after boot\n 6. {boot-time}: Boot time in local timezone\n 7. {years}: Years integer after boot\n 8. {days-of-year}: Days of year after boot\n 9. {years-fraction}: Years fraction after boot\n 10. {formatted}: Formatted uptime",
"type": "string"
},
"usersFormat": {
- "description": "Output format of the module `Users`. See Wiki for formatting syntax\n 1. {name}: User name\n 2. {host-name}: Host name\n 3. {session-name}: Session name\n 4. {client-ip}: Client IP\n 5. {login-time}: Login Time in local timezone\n 6. {days}: Days after login\n 7. {hours}: Hours after login\n 8. {minutes}: Minutes after login\n 9. {seconds}: Seconds after login\n 10. {milliseconds}: Milliseconds after login\n 11. {years}: Years integer after login\n 12. {days-of-year}: Days of year after login\n 13. {years-fraction}: Years fraction after login",
+ "description": "Output format for the `Users` module. See Wiki for formatting syntax\n 1. {name}: User name\n 2. {host-name}: Host name\n 3. {session-name}: Session name\n 4. {client-ip}: Client IP\n 5. {login-time}: Login Time in local timezone\n 6. {days}: Days after login\n 7. {hours}: Hours after login\n 8. {minutes}: Minutes after login\n 9. {seconds}: Seconds after login\n 10. {milliseconds}: Milliseconds after login\n 11. {years}: Years integer after login\n 12. {days-of-year}: Days of year after login\n 13. {years-fraction}: Years fraction after login",
"type": "string"
},
"versionFormat": {
- "description": "Output format of the module `Version`. See Wiki for formatting syntax\n 1. {project-name}: Project name\n 2. {version}: Version\n 3. {version-tweak}: Version tweak\n 4. {build-type}: Build type (debug or release)\n 5. {sysname}: System name\n 6. {arch}: Architecture\n 7. {cmake-built-type}: CMake build type when compiling (Debug, Release, RelWithDebInfo, MinSizeRel)\n 8. {compile-time}: Date time when compiling\n 9. {compiler}: Compiler used when compiling\n 10. {libc}: Libc used when compiling",
+ "description": "Output format for the `Version` module. See Wiki for formatting syntax\n 1. {project-name}: Project name\n 2. {version}: Version\n 3. {version-tweak}: Version tweak\n 4. {build-type}: Build type (debug or release)\n 5. {sysname}: System name\n 6. {arch}: Architecture\n 7. {cmake-built-type}: CMake build type when compiling (Debug, Release, RelWithDebInfo, MinSizeRel)\n 8. {compile-time}: Date time when compiling\n 9. {compiler}: Compiler used when compiling\n 10. {libc}: Libc used when compiling",
"type": "string"
},
"vulkanFormat": {
- "description": "Output format of the module `Vulkan`. See Wiki for formatting syntax\n 1. {driver}: Driver name\n 2. {api-version}: API version\n 3. {conformance-version}: Conformance version\n 4. {instance-version}: Instance version",
+ "description": "Output format for the `Vulkan` module. See Wiki for formatting syntax\n 1. {driver}: Driver name\n 2. {api-version}: API version\n 3. {conformance-version}: Conformance version\n 4. {instance-version}: Instance version",
"type": "string"
},
"wallpaperFormat": {
- "description": "Output format of the module `Wallpaper`. See Wiki for formatting syntax\n 1. {file-name}: File name\n 2. {full-path}: Full path",
+ "description": "Output format for the `Wallpaper` module. See Wiki for formatting syntax\n 1. {file-name}: File name\n 2. {full-path}: Full path",
"type": "string"
},
"weatherFormat": {
- "description": "Output format of the module `Weather`. See Wiki for formatting syntax\n 1. {result}: Weather result",
+ "description": "Output format for the `Weather` module. See Wiki for formatting syntax\n 1. {result}: Weather result",
"type": "string"
},
"wmFormat": {
- "description": "Output format of the module `WM`. See Wiki for formatting syntax\n 1. {process-name}: WM process name\n 2. {pretty-name}: WM pretty name\n 3. {protocol-name}: WM protocol name\n 4. {plugin-name}: WM plugin name\n 5. {version}: WM version",
+ "description": "Output format for the `WM` module. See Wiki for formatting syntax\n 1. {process-name}: WM process name\n 2. {pretty-name}: WM pretty name\n 3. {protocol-name}: WM protocol name\n 4. {plugin-name}: WM plugin name\n 5. {version}: WM version",
"type": "string"
},
"wifiFormat": {
- "description": "Output format of the module `Wifi`. See Wiki for formatting syntax\n 1. {inf-desc}: Interface description\n 2. {inf-status}: Interface status\n 3. {status}: Connection status\n 4. {ssid}: Connection SSID\n 5. {bssid}: Connection BSSID\n 6. {protocol}: Connection protocol\n 7. {signal-quality}: Connection signal quality (percentage num)\n 8. {rx-rate}: Connection RX rate\n 9. {tx-rate}: Connection TX rate\n 10. {security}: Connection Security algorithm\n 11. {signal-quality-bar}: Connection signal quality (percentage bar)\n 12. {channel}: Connection channel number\n 13. {band}: Connection channel band in GHz",
+ "description": "Output format for the `Wifi` module. See Wiki for formatting syntax\n 1. {inf-desc}: Interface description\n 2. {inf-status}: Interface status\n 3. {status}: Connection status\n 4. {ssid}: Connection SSID\n 5. {bssid}: Connection BSSID\n 6. {protocol}: Connection protocol\n 7. {signal-quality}: Connection signal quality (percentage num)\n 8. {rx-rate}: Connection RX rate\n 9. {tx-rate}: Connection TX rate\n 10. {security}: Connection Security algorithm\n 11. {signal-quality-bar}: Connection signal quality (percentage bar)\n 12. {channel}: Connection channel number\n 13. {band}: Connection channel band in GHz",
"type": "string"
},
"wmthemeFormat": {
- "description": "Output format of the module `WMTheme`. See Wiki for formatting syntax\n 1. {result}: WM theme",
+ "description": "Output format for the `WMTheme` module. See Wiki for formatting syntax\n 1. {result}: WM theme",
"type": "string"
},
"zpoolFormat": {
- "description": "Output format of the module `Zpool`. See Wiki for formatting syntax\n 1. {name}: Zpool name\n 2. {guid}: Zpool guid\n 3. {state}: Zpool state\n 4. {used}: Size used\n 5. {allocated}: Size allocated\n 6. {total}: Size total\n 7. {used-percentage}: Size used percentage num\n 8. {allocated-percentage}: Size allocated percentage num\n 9. {fragmentation-percentage}: Fragmentation percentage num\n 10. {used-percentage-bar}: Size used percentage bar\n 11. {allocated-percentage-bar}: Size allocated percentage bar\n 12. {fragmentation-percentage-bar}: Fragmentation percentage bar\n 13. {is-readonly}: Is read-only",
+ "description": "Output format for the `Zpool` module. See Wiki for formatting syntax\n 1. {name}: Zpool name\n 2. {guid}: Zpool guid\n 3. {state}: Zpool state\n 4. {size-used}: Size used\n 5. {size-allocated}: Size allocated\n 6. {size-total}: Size total\n 7. {used-percentage}: Size used percentage num\n 8. {allocated-percentage}: Size allocated percentage num\n 9. {frag-percentage}: Fragmentation percentage num\n 10. {used-percentage-bar}: Size used percentage bar\n 11. {allocated-percentage-bar}: Size allocated percentage bar\n 12. {frag-percentage-bar}: Fragmentation percentage bar\n 13. {is-readonly}: Is read-only",
"type": "string"
}
},
"type": "object",
"additionalProperties": false,
"title": "JSON config",
- "description": "JSON config file for fastfetch. Usually located at `~/.config/fastfetch/config.jsonc`",
+ "description": "Fastfetch JSON config file. Usually located at `~/.config/fastfetch/config.jsonc`",
"properties": {
"$schema": {
"type": "string",
- "description": "JSON schema URL, for JSON validation and IDE intelligence",
+ "description": "JSON Schema URL for validation and IDE support",
"format": "uri",
"default": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json"
},
"logo": {
- "description": "Fastfetch logo configurations\nSee also https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options",
+ "description": "Fastfetch logo configuration\nSee also https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options",
"oneOf": [
{
"description": "Disable logo",
@@ -570,20 +570,20 @@
"const": null
},
{
- "description": "Set the source file of the logo or built-in ASCII art name",
+ "description": "Path to a logo source file or the name of a built-in ASCII art logo",
"type": "string"
},
{
- "description": "Fastfetch logo configurations",
+ "description": "Fastfetch logo configuration",
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
- "description": "Set the type of the logo",
+ "description": "Logo type",
"oneOf": [
{
"const": "auto",
- "description": "If something is given, first try built-in, then file. Otherwise detect logo"
+ "description": "If a value is provided, try a built-in logo first, then a file. Otherwise, auto-detect the logo. Explicit type is highly recommended when use image files."
},
{
"const": "builtin",
@@ -595,7 +595,7 @@
},
{
"const": "file",
- "description": "Text file, printed with color code replacement"
+ "description": "Text file with color code replacement"
},
{
"const": "file-raw",
@@ -603,39 +603,43 @@
},
{
"const": "data",
- "description": "Text data, printed with color code replacement"
+ "description": "Text data with color code replacement"
},
{
"const": "data-raw",
"description": "Text data, printed as is"
},
+ {
+ "const": "command-raw",
+ "description": "Command that generates text data, printed as is"
+ },
{
"const": "sixel",
- "description": "Image file, printed as sixel codes"
+ "description": "Image file rendered as sixel"
},
{
"const": "kitty",
- "description": "Image file, printed using kitty graphics protocol"
+ "description": "Image file rendered using the Kitty graphics protocol"
},
{
"const": "kitty-direct",
- "description": "Image file, tells the terminal emulator to read image data from the specified file"
+ "description": "Image file. Instructs the terminal emulator to read image data directly from the specified file"
},
{
"const": "kitty-icat",
- "description": "Image file, uses `kitten icat` to display the image. Requires binary `kitten` to be installed"
+ "description": "Image file displayed using `kitten icat`. Requires the `kitten` binary to be installed"
},
{
"const": "iterm",
- "description": "Image file, uses `iTerm` image protocol"
+ "description": "Image file rendered using the iTerm image protocol"
},
{
"const": "chafa",
- "description": "Image file, prints `ASCII` art image generated by `libchafa`"
+ "description": "Image file rendered as ASCII art using `libchafa`"
},
{
"const": "raw",
- "description": "Image file, printed as `raw` binary string image"
+ "description": "Image file rendered as a raw binary string"
},
{
"const": "none",
@@ -646,7 +650,7 @@
},
"source": {
"type": "string",
- "description": "Set the source file of the logo"
+ "description": "Path to the logo source file"
},
"color": {
"type": "object",
@@ -695,11 +699,11 @@
"oneOf": [
{
"type": "null",
- "description": "Auto detect width (default)"
+ "description": "Auto-detect the width (default)"
},
{
"type": "integer",
- "description": "Set the width of the logo (in characters). Required for some image protocols",
+ "description": "Width of the logo in characters. Required by some image protocols",
"minimum": 1
}
]
@@ -708,11 +712,11 @@
"oneOf": [
{
"type": "null",
- "description": "Auto detect width (default)"
+ "description": "Auto-detect the height (default)"
},
{
"type": "integer",
- "description": "Set the height of the logo (in characters). Required for some image protocols",
+ "description": "Height of the logo in characters. Required by some image protocols",
"minimum": 1
}
]
@@ -720,28 +724,28 @@
"padding": {
"type": "object",
"additionalProperties": false,
- "description": "Set the padding of the logo",
+ "description": "Logo padding",
"properties": {
"top": {
"type": "integer",
- "description": "Set the top padding of the logo",
+ "description": "Top padding of the logo",
"minimum": 0
},
"left": {
"type": "integer",
- "description": "Set the left padding of the logo",
+ "description": "Left padding of the logo",
"minimum": 0
},
"right": {
"type": "integer",
- "description": "Set the right padding of the logo",
+ "description": "Right padding of the logo",
"minimum": 0
}
}
},
"printRemaining": {
"type": "boolean",
- "description": "Whether to print the remaining logo if it has more lines than modules to display",
+ "description": "Whether to print any remaining logo lines when the logo is taller than the module list",
"default": true
},
"preserveAspectRatio": {
@@ -756,7 +760,7 @@
},
"position": {
"type": "string",
- "description": "Set the position where the logo should be displayed",
+ "description": "Position of the logo",
"enum": [
"left",
"top",
@@ -855,7 +859,7 @@
]
},
"general": {
- "description": "Fastfetch general configurations",
+ "description": "General Fastfetch configuration",
"type": "object",
"additionalProperties": false,
"properties": {
@@ -874,7 +878,7 @@
"description": "The name of the player to use for Media and Player modules. Linux only"
},
"dsForceDrm": {
- "description": "Force display detection to use DRM. Linux only",
+ "description": "Force display detection to use DRM (Linux only)",
"oneOf": [
{
"type": "boolean",
@@ -906,7 +910,7 @@
},
"preRun": {
"type": "string",
- "description": "Set the command to be executed before printing logos",
+ "description": "Command to run before printing logos",
"default": ""
},
"detectVersion": {
@@ -917,12 +921,12 @@
}
},
"display": {
- "description": "Configure how things should be displayed",
+ "description": "Configure output formatting",
"type": "object",
"additionalProperties": false,
"properties": {
"stat": {
- "description": "Show time usage (in ms) for individual modules with optional threshold",
+ "description": "Show execution time (in ms) for individual modules, optionally above a threshold",
"oneOf": [
{
"type": "boolean",
@@ -941,7 +945,7 @@
},
"showErrors": {
"type": "boolean",
- "description": "Print occurring errors to the console. False to ignore errored modules",
+ "description": "Whether to print errors to the console. If false, modules that error are ignored",
"default": false
},
"disableLinewrap": {
@@ -956,14 +960,14 @@
},
"separator": {
"type": "string",
- "description": "Set the separator between key and value",
+ "description": "Separator between the key and value",
"default": ": "
},
"color": {
- "description": "Set the color of the keys and title",
+ "description": "Color of keys and titles",
"oneOf": [
{
- "description": "Set both the colors of keys and title",
+ "description": "Color for both keys and titles",
"$ref": "#/$defs/colors"
},
{
@@ -971,19 +975,19 @@
"additionalProperties": false,
"properties": {
"keys": {
- "description": "Set the color of the keys",
+ "description": "Color of keys",
"$ref": "#/$defs/colors"
},
"title": {
- "description": "Set the color of the title",
+ "description": "Color of titles",
"$ref": "#/$defs/colors"
},
"output": {
- "description": "Set the color of the module output",
+ "description": "Color of module output",
"$ref": "#/$defs/colors"
},
"separator": {
- "description": "Set the color of the key-value separator",
+ "description": "Color of the key-value separator",
"$ref": "#/$defs/colors"
}
}
@@ -991,24 +995,24 @@
]
},
"brightColor": {
- "description": "Set if the keys, title and ASCII logo should be printed in bright color",
+ "description": "Whether to print keys, titles, and the ASCII logo in bright colors",
"type": "boolean",
"default": true
},
"key": {
"type": "object",
"additionalProperties": false,
- "description": "Set how module keys should be displayed",
+ "description": "Configure how module keys are displayed",
"properties": {
"width": {
- "description": "Align the width of keys to number of characters, 0 to disable",
+ "description": "Key width in characters. Set to 0 to disable alignment",
"type": "integer",
"minimum": 0,
"default": 0
},
"type": {
"type": "string",
- "description": "Set whether to show builtin icon before string keys",
+ "description": "Whether to show a built-in icon before string keys",
"oneOf": [
{
"const": "none",
@@ -1020,7 +1024,7 @@
},
{
"const": "icon",
- "description": "Show builtin icon (requires newest nerd font)"
+ "description": "Show the built-in icon (requires a recent Nerd Font)"
},
{
"const": "both",
@@ -1051,7 +1055,7 @@
},
"paddingLeft": {
"type": "integer",
- "description": "Set the left padding of keys",
+ "description": "Left padding for keys",
"minimum": 0,
"default": 0
}
@@ -1060,7 +1064,7 @@
"size": {
"type": "object",
"additionalProperties": false,
- "description": "Set how size values should be displayed",
+ "description": "Configure how sizes are displayed",
"properties": {
"binaryPrefix": {
"type": "string",
@@ -1089,7 +1093,7 @@
},
"ndigits": {
"type": "integer",
- "description": "Set the number of digits to keep after the decimal point when formatting sizes",
+ "description": "Number of decimal places to use when formatting sizes",
"minimum": 0,
"maximum": 9,
"default": 2
@@ -1102,7 +1106,7 @@
"temp": {
"type": "object",
"additionalProperties": false,
- "description": "Set how temperature values should be displayed",
+ "description": "Configure how temperatures are displayed",
"properties": {
"unit": {
"type": "string",
@@ -1129,7 +1133,7 @@
},
"ndigits": {
"type": "integer",
- "description": "Set the number of digits to keep after the decimal point when formatting temperature values",
+ "description": "Number of decimal places to use when formatting temperatures",
"minimum": 0,
"maximum": 9,
"default": 1
@@ -1137,7 +1141,7 @@
"color": {
"type": "object",
"additionalProperties": false,
- "description": "Set colors used in different states of temperature values",
+ "description": "Colors used for different temperature states",
"properties": {
"green": {
"description": "Color used in green state",
@@ -1164,21 +1168,21 @@
"bar": {
"type": "object",
"additionalProperties": false,
- "description": "Set the bar configuration",
+ "description": "Bar configuration",
"properties": {
"char": {
"type": "object",
"additionalProperties": false,
- "description": "Set the characters used in the bar",
+ "description": "Characters used in the bar",
"properties": {
"elapsed": {
"type": "string",
- "description": "Set the character to use in elapsed part",
+ "description": "Character used for the elapsed portion",
"default": "■"
},
"total": {
"type": "string",
- "description": "Set the character to use in total part",
+ "description": "Character used for the remaining portion",
"default": "-"
}
}
@@ -1192,26 +1196,26 @@
{
"type": "object",
"additionalProperties": false,
- "description": "Set the string to use of borders of percentage bars",
+ "description": "Strings used for percentage bar borders",
"properties": {
"left": {
"type": "string",
- "description": "Set the string to use at left border",
+ "description": "String used for the left border",
"default": "[ "
},
"right": {
"type": "string",
- "description": "Set the string to use at right border",
+ "description": "String used for the right border",
"default": " ]"
},
"leftElapsed": {
"type": "string",
- "description": "If both leftElapsed and rightElapsed are set, the border will be used as parts of bar content",
+ "description": "If both `leftElapsed` and `rightElapsed` are set, the border is used as part of the bar content",
"default": ""
},
"rightElapsed": {
"type": "string",
- "description": "If both leftElapsed and rightElapsed are set, the border will be used as parts of bar content",
+ "description": "If both `leftElapsed` and `rightElapsed` are set, the border is used as part of the bar content",
"default": ""
}
}
@@ -1227,20 +1231,20 @@
{
"type": "object",
"additionalProperties": false,
- "description": "Set the color to use of percentage bars",
+ "description": "Colors used for percentage bars",
"properties": {
"elapsed": {
- "description": "Color to use in the elapsed part of percentage bars\nBy default, auto selected by percent.color.{green,yellow,red}",
+ "description": "Color used for the elapsed portion of percentage bars\nBy default, it is selected automatically from `percent.color.{green,yellow,red}`",
"$ref": "#/$defs/colors",
"default": "auto"
},
"total": {
- "description": "Color to use in the total part of percentage bars",
+ "description": "Color used for the remaining portion of percentage bars",
"$ref": "#/$defs/colors",
"default": "light_white"
},
"border": {
- "description": "Color to use in the borders of percentage bars",
+ "description": "Color used for percentage bar borders",
"$ref": "#/$defs/colors",
"default": "light_white"
}
@@ -1250,7 +1254,7 @@
},
"width": {
"type": "integer",
- "description": "Set the width of the bar, in number of characters",
+ "description": "Width of the bar in characters",
"minimum": 1,
"default": 10
}
@@ -1259,14 +1263,14 @@
"percent": {
"type": "object",
"additionalProperties": false,
- "description": "Set how percentage values should be displayed",
+ "description": "Configure how percentages are displayed",
"properties": {
"type": {
"$ref": "#/$defs/percentType"
},
"ndigits": {
"type": "number",
- "description": "Set the number of digits to keep after the decimal point when formatting percentage numbers",
+ "description": "Number of decimal places to use when formatting percentages",
"minimum": 0,
"maximum": 9,
"default": 0
@@ -1274,7 +1278,7 @@
"color": {
"type": "object",
"additionalProperties": false,
- "description": "Set colors used in different states of percentage bars and numbers",
+ "description": "Colors used for different percentage states",
"properties": {
"green": {
"description": "Color used in green state",
@@ -1298,7 +1302,7 @@
},
"width": {
"type": "integer",
- "description": "Set the width of the percentage number, in number of characters",
+ "description": "Width of the percentage number in characters",
"minimum": 0,
"default": 0
}
@@ -1307,7 +1311,7 @@
"freq": {
"type": "object",
"additionalProperties": false,
- "description": "Set how frequency values should be displayed",
+ "description": "Configure how frequencies are displayed",
"properties": {
"ndigits": {
"description": "Set the number of decimal places to display when formatting frequency values",
@@ -1316,11 +1320,11 @@
"type": "integer",
"minimum": 0,
"maximum": 9,
- "description": "Integer value displays the frequency in GHz with specified decimal places"
+ "description": "An integer displays the frequency in GHz with the specified number of decimal places"
},
{
"type": "null",
- "description": "Null value display the frequency as integer MHz"
+ "description": "A null value displays the frequency as an integer in MHz"
}
],
"default": 2
@@ -1332,11 +1336,11 @@
},
"duration": {
"type": "object",
- "description": "Set how duration values should be displayed",
+ "description": "Configure how durations are displayed",
"properties": {
"abbreviation": {
"type": "boolean",
- "description": "Set whether to abbreviate duration values\nIf true, the output will be in the form of \"1h 2m\" instead of \"1 hour, 2 mins\"",
+ "description": "Whether to abbreviate durations\nIf true, values are shown as \"1h 2m\" instead of \"1 hour, 2 mins\"",
"default": false
},
"spaceBeforeUnit": {
@@ -1347,25 +1351,25 @@
"fraction": {
"type": "object",
"additionalProperties": false,
- "description": "Set how ordinary fraction numbers should be displayed",
+ "description": "Configure how fractional values are displayed",
"properties": {
"ndigits": {
"oneOf": [
{
"type": "number",
- "description": "Set the number of digits to keep after the decimal point when formatting ordinary fraction numbers",
+ "description": "Number of decimal places to use when formatting fractional values",
"minimum": 0,
"maximum": 9
},
{
"type": "null",
- "description": "The number of digits will be automatically determined based on the value"
+ "description": "Automatically determine the number of decimal places based on the value"
}
],
"default": 2
},
"trailingZeros": {
- "description": "Set when to keep trailing zeros",
+ "description": "Control when trailing zeros are preserved",
"oneOf": [
{
"type": "null",
@@ -1373,7 +1377,7 @@
},
{
"const": "default",
- "description": "Use the behavior defined internally"
+ "description": "Use the built-in behavior"
},
{
"const": "always",
@@ -1388,14 +1392,30 @@
}
}
},
+ "common": {
+ "type": "object",
+ "additionalProperties": false,
+ "description": "Override the settings for `duration`, `fraction`, `freq`, `percent`, `size`, and `temp`\nPlace this before those properties to use it as their default configuration",
+ "properties": {
+ "ndigits": {
+ "description": "Default number of decimal places to display",
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 9
+ },
+ "spaceBeforeUnit": {
+ "$ref": "#/$defs/spaceBeforeUnit"
+ }
+ }
+ },
"noBuffer": {
"type": "boolean",
- "description": "Whether to disable the stdout application buffer",
+ "description": "Whether to disable stdout buffering",
"default": false
},
"constants": {
"type": "array",
- "description": "List of strings to be used in custom format of modules",
+ "description": "List of strings available for use in module custom formats",
"items": {
"type": "string"
}
@@ -1403,13 +1423,13 @@
}
},
"modules": {
- "description": "Fastfetch modules to run",
+ "description": "Modules to run",
"type": "array",
"items": {
"anyOf": [
{
"type": "string",
- "description": "Run module with default configurations",
+ "description": "Run a module with its default configuration",
"enum": [
"battery",
"bios",
@@ -1487,7 +1507,7 @@
},
{
"type": "object",
- "description": "Run module with custom configurations",
+ "description": "Run a module with a custom configuration",
"required": [
"type"
],
@@ -1504,7 +1524,7 @@
"properties": {
"type": {
"const": "break",
- "description": "Print a empty line"
+ "description": "Print an empty line"
},
"condition": {
"$ref": "#/$defs/conditions"
@@ -1518,10 +1538,10 @@
"properties": {
"type": {
"const": "battery",
- "description": "Print battery capacity, status, etc"
+ "description": "Print battery information"
},
"useSetupApi": {
- "description": "Set if `CM API` should be used on Windows to detect battery info, which supports multi batteries, but slower. Windows only",
+ "description": "Whether to use the `CM API` on Windows to detect battery information. Supports multiple batteries, but is slower (Windows only)",
"type": "boolean",
"default": false
},
@@ -1560,7 +1580,7 @@
"additionalProperties": false,
"properties": {
"type": {
- "description": "Print information of 1st-stage bootloader (name, version, release date, etc)",
+ "description": "Print first-stage bootloader information (name, version, release date, etc.)",
"const": "bios"
},
"key": {
@@ -1592,11 +1612,11 @@
"additionalProperties": false,
"properties": {
"type": {
- "description": "List (connected) bluetooth devices",
+ "description": "List connected Bluetooth devices",
"const": "bluetooth"
},
"showDisconnected": {
- "description": "Set if disconnected bluetooth devices should be printed",
+ "description": "Whether to show disconnected Bluetooth devices",
"type": "boolean",
"default": false
},
@@ -1632,7 +1652,7 @@
"additionalProperties": false,
"properties": {
"type": {
- "description": "List bluetooth radios width supported version and vendor",
+ "description": "List Bluetooth radios (supported versions, vendors, etc.)",
"const": "bluetoothradio"
},
"key": {
@@ -1664,7 +1684,7 @@
"additionalProperties": false,
"properties": {
"type": {
- "description": "Print motherboard name and other info",
+ "description": "Print motherboard name and other information",
"const": "board"
},
"key": {
@@ -1696,7 +1716,7 @@
"additionalProperties": false,
"properties": {
"type": {
- "description": "Print information of 2nd-stage bootloader (name, firmware, etc)",
+ "description": "Print second-stage bootloader information (name, firmware, etc.)",
"const": "bootmgr"
},
"key": {
@@ -1729,20 +1749,20 @@
"properties": {
"type": {
"const": "brightness",
- "description": "Print current brightness level of your monitors"
+ "description": "Print the current brightness level of your monitors"
},
"percent": {
"$ref": "#/$defs/percent"
},
"ddcciSleep": {
"type": "integer",
- "description": "Set the sleep times (in ms) when sending DDC/CI requests.\nSee for detail",
+ "description": "Sleep time in milliseconds between DDC/CI requests\nSee for details",
"minimum": 0,
"maximum": 400,
"default": 10
},
"compact": {
- "description": "Set if multiple results should be printed in one line",
+ "description": "Whether to print multiple results on a single line",
"type": "boolean",
"default": false
},
@@ -1843,7 +1863,7 @@
"properties": {
"type": {
"const": "chassis",
- "description": "Print chassis type (desktop, laptop, etc)"
+ "description": "Print chassis type information (desktop, laptop, etc.)"
},
"key": {
"$ref": "#/$defs/key"
@@ -1874,7 +1894,7 @@
"additionalProperties": false,
"properties": {
"type": {
- "description": "Print CPU name, frequency, etc",
+ "description": "Print CPU name, frequency, etc.",
"const": "cpu"
},
"temp": {
@@ -1885,7 +1905,7 @@
"type": "string"
},
"showPeCoreCount": {
- "description": "Detect and display CPU frequency of different core types (eg. Pcore and Ecore) if supported",
+ "description": "Whether to detect and display CPU frequencies for different core types (for example, P-cores and E-cores), if supported",
"type": "boolean",
"default": false
},
@@ -1954,14 +1974,14 @@
"properties": {
"type": {
"const": "cpuusage",
- "description": "Print CPU usage. Costs some time to collect data"
+ "description": "Print CPU usage. Collecting data takes some time"
},
"percent": {
"$ref": "#/$defs/percent"
},
"separate": {
"type": "boolean",
- "description": "Display CPU usage per CPU logical core, instead of an average result",
+ "description": "Show CPU usage for each logical core instead of an average",
"default": false
},
"waitTime": {
@@ -2012,7 +2032,7 @@
},
{
"const": "background",
- "description": "(whitespaces with background)"
+ "description": "Whitespace with background color"
},
{
"const": "circle",
@@ -2109,33 +2129,33 @@
"additionalProperties": false,
"properties": {
"type": {
- "description": "Running custom shell scripts",
+ "description": "Run a custom shell command",
"const": "command"
},
"shell": {
- "description": "Set the shell program to execute the command text\nDefault: cmd for Windows, /bin/sh for *nix",
+ "description": "Shell program used to execute the command text\nDefault: `cmd` on Windows, `/bin/sh` on Unix-like systems",
"type": "string"
},
"param": {
- "description": "Set the parameter used when starting the shell\nIf set to an empty string, it will be ignored\nDefault: /c for Windows, -c for *nix",
+ "description": "Parameter used when starting the shell\nIf set to an empty string, it is ignored\nDefault: `/c` on Windows, `-c` on Unix-like systems",
"type": "string"
},
"text": {
- "description": "Set the command text to be executed",
+ "description": "Command text to execute",
"type": "string"
},
"useStdErr": {
- "description": "Set if stderr should be used instead of stdout for command output",
+ "description": "Whether to use stderr instead of stdout for command output",
"type": "boolean",
"default": false
},
"parallel": {
- "description": "Set if the command should be executed in parallel with other commands\nImprove performance when using multiple commands, but may cause issues with some commands",
+ "description": "Whether to execute the command in parallel with other commands\nThis can improve performance when using multiple commands, but may cause issues with some commands",
"type": "boolean",
"default": true
},
"splitLines": {
- "description": "Set if the command output should be split into multiple lines",
+ "description": "Whether to split command output into multiple lines",
"type": "boolean",
"default": false
},
@@ -2207,7 +2227,7 @@
"const": "custom"
},
"key": {
- "description": "Leave empty not to print the key",
+ "description": "Leave empty to hide the key",
"type": "string"
},
"keyColor": {
@@ -2238,7 +2258,7 @@
"properties": {
"type": {
"const": "datetime",
- "description": "Print current date and time"
+ "description": "Print the current date and time"
},
"percent": {
"$ref": "#/$defs/percent"
@@ -2272,11 +2292,11 @@
"additionalProperties": false,
"properties": {
"type": {
- "description": "Print resolutions, refresh rates, etc",
+ "description": "Print display resolutions, refresh rates, etc.",
"const": "display"
},
"compactType": {
- "description": "Set if all displays should be printed in one line",
+ "description": "Whether to print all displays on a single line",
"oneOf": [
{
"const": null,
@@ -2306,12 +2326,12 @@
"default": null
},
"preciseRefreshRate": {
- "description": "Set if decimal refresh rates should not be rounded into integers when printing",
+ "description": "Whether to preserve decimal refresh rates instead of rounding them to integers",
"type": "boolean",
"default": false
},
"order": {
- "description": "Set the order should be used when printing",
+ "description": "Order to use when printing displays",
"oneOf": [
{
"const": null,
@@ -2361,7 +2381,7 @@
"additionalProperties": false,
"properties": {
"type": {
- "description": "Print partitions, space usage, disk type, etc",
+ "description": "Print partitions, space usage, file system, etc.",
"const": "disk"
},
"folders": {
@@ -2422,32 +2442,32 @@
},
"showRegular": {
"type": "boolean",
- "description": "Set if regular volume should be printed",
+ "description": "Whether to show regular volumes",
"default": true
},
"showExternal": {
"type": "boolean",
- "description": "Set if external volume should be printed",
+ "description": "Whether to show external volumes",
"default": true
},
"showHidden": {
"type": "boolean",
- "description": "Set if hidden volumes should be printed",
+ "description": "Whether to show hidden volumes",
"default": false
},
"showSubvolumes": {
"type": "boolean",
- "description": "Set if subvolumes should be printed",
+ "description": "Whether to show subvolumes",
"default": false
},
"showReadOnly": {
"type": "boolean",
- "description": "Set if read only volumes should be printed",
+ "description": "Whether to show read-only volumes",
"default": false
},
"showUnknown": {
"type": "boolean",
- "description": "Set if unknown (unable to detect sizes) volumes should be printed",
+ "description": "Whether to show unknown volumes whose sizes cannot be detected",
"default": false
},
"useAvailable": {
@@ -2491,11 +2511,11 @@
"const": "diskio"
},
"namePrefix": {
- "description": "Show disks with given name prefix only",
+ "description": "Show only disks whose names start with this prefix",
"type": "string"
},
"detectTotal": {
- "description": "Detect total bytes instead of current rate",
+ "description": "Show total bytes instead of the current rate",
"type": "boolean",
"default": false
},
@@ -2567,7 +2587,7 @@
"properties": {
"type": {
"const": "dns",
- "description": "Print DNS servers"
+ "description": "Print configured DNS servers"
},
"showType": {
"oneOf": [
@@ -2585,7 +2605,7 @@
}
],
"default": "both",
- "description": "Specify the type of DNS servers should be detected"
+ "description": "Which DNS server types to show"
},
"key": {
"$ref": "#/$defs/key"
@@ -2617,7 +2637,7 @@
"properties": {
"type": {
"const": "editor",
- "description": "Print information of the default editor ($VISUAL or $EDITOR)"
+ "description": "Print information about the default editor (`$VISUAL` or `$EDITOR`)"
},
"percent": {
"$ref": "#/$defs/percent"
@@ -2730,7 +2750,7 @@
"additionalProperties": false,
"properties": {
"type": {
- "description": "Print GPU names, graphic memory size, type, etc",
+ "description": "Print GPU names, memory sizes, types, etc.",
"const": "gpu"
},
"temp": {
@@ -2742,7 +2762,7 @@
"default": false
},
"detectionMethod": {
- "description": "Force using a specified method to detect GPUs",
+ "description": "Force a specific GPU detection method",
"type": "string",
"oneOf": [
{
@@ -2769,7 +2789,7 @@
"default": ""
},
"hideType": {
- "description": "Specify the type of GPUs should not be printed",
+ "description": "Hide GPUs of a specific type",
"oneOf": [
{
"const": null,
@@ -2827,7 +2847,7 @@
"properties": {
"type": {
"const": "host",
- "description": "Print product name of your computer"
+ "description": "Print your computer's product name"
},
"key": {
"$ref": "#/$defs/key"
@@ -2955,7 +2975,7 @@
"properties": {
"type": {
"const": "keyboard",
- "description": "List (connected) keyboards"
+ "description": "List connected keyboards"
},
"ignores": {
"type": "array",
@@ -3027,7 +3047,7 @@
"additionalProperties": false,
"properties": {
"type": {
- "description": "List local IP addresses (v4 or v6), MAC addresses, etc",
+ "description": "List local IP addresses (IPv4 or IPv6), MAC addresses, etc.",
"const": "localip"
},
"showIpv4": {
@@ -3066,7 +3086,7 @@
"default": false
},
"showSpeed": {
- "description": "Show ethernet rx speed",
+ "description": "Show Ethernet RX speed",
"type": "boolean",
"default": false
},
@@ -3091,7 +3111,7 @@
"default": true
},
"showAllIps": {
- "description": "Show all IPs bound to the same interface.\nBy default only the firstly detected IP is shown",
+ "description": "Show all IPs bound to the same interface\nBy default, only the first detected IP is shown",
"type": "boolean",
"default": false
},
@@ -3110,7 +3130,7 @@
"type": "string"
},
"defaultRouteOnly": {
- "description": "Show ips that are used for default routing only\nDoesn't work on Android",
+ "description": "Show only IPs used for the default route\nDoes not work on Android",
"type": "boolean",
"default": true
},
@@ -3237,7 +3257,7 @@
"properties": {
"type": {
"const": "media",
- "description": "Print song name of currently playing"
+ "description": "Print the name of the currently playing song"
},
"key": {
"$ref": "#/$defs/key"
@@ -3269,7 +3289,7 @@
"properties": {
"type": {
"const": "memory",
- "description": "Print system memory usage info"
+ "description": "Print system memory usage information"
},
"percent": {
"$ref": "#/$defs/percent"
@@ -3304,7 +3324,7 @@
"properties": {
"type": {
"const": "mouse",
- "description": "List connected mouses"
+ "description": "List connected mice"
},
"ignores": {
"type": "array",
@@ -3345,7 +3365,7 @@
"properties": {
"type": {
"const": "monitor",
- "description": "Alias of Display module (for backwards compatibility, deprecated)"
+ "description": "Same as Display module, but with a different default output format"
},
"key": {
"$ref": "#/$defs/key"
@@ -3380,11 +3400,11 @@
"const": "netio"
},
"namePrefix": {
- "description": "Show IPs with given name prefix only",
+ "description": "Show only interfaces whose names start with this prefix",
"type": "string"
},
"defaultRouteOnly": {
- "description": "Show ips that are used for default routing only\nDoesn't work on Android",
+ "description": "Show only interfaces used for the default route\nDoes not work on Android",
"type": "boolean",
"default": true
},
@@ -3429,7 +3449,7 @@
"properties": {
"type": {
"const": "opencl",
- "description": "Print highest OpenCL version supported by the GPU"
+ "description": "Print the highest OpenCL version supported by the GPU"
},
"key": {
"$ref": "#/$defs/key"
@@ -3460,7 +3480,7 @@
"additionalProperties": false,
"properties": {
"type": {
- "description": "Print highest OpenGL version supported by the GPU",
+ "description": "Print the highest OpenGL version supported by the GPU",
"const": "opengl"
},
"library": {
@@ -3511,7 +3531,7 @@
"properties": {
"type": {
"const": "os",
- "description": "Print OS / or Linux distro name and version"
+ "description": "Print the OS or Linux distribution name and version"
},
"key": {
"$ref": "#/$defs/key"
@@ -3548,7 +3568,7 @@
"disabled": {
"oneOf": [
{
- "description": "List of package managers to be disabled when detecting\nWarning: Some detection methods can be very slow.",
+ "description": "Package managers to disable during detection\nWarning: Some detection methods can be very slow.",
"type": "array",
"items": {
"type": "string",
@@ -3634,6 +3654,16 @@
"description": "Show disks with given name prefix only",
"type": "string"
},
+ "hideVirtual": {
+ "description": "Hide virtual disks (e.g. loop, RAM or file baked disks)",
+ "type": "boolean",
+ "default": false
+ },
+ "hideUnused": {
+ "description": "Hide disks with `size == 0` (likely unused/unconnected)",
+ "type": "boolean",
+ "default": true
+ },
"temp": {
"$ref": "#/$defs/temperature"
},
@@ -3670,7 +3700,7 @@
"description": "Print system physical memory devices"
},
"showEmptySlots": {
- "description": "Set if uninstalled memory slots should be printed",
+ "description": "Whether to show uninstalled memory slots",
"type": "boolean",
"default": false
},
@@ -3704,7 +3734,7 @@
"properties": {
"type": {
"const": "player",
- "description": "Print music player name"
+ "description": "Print the music player name that is currently active"
},
"key": {
"$ref": "#/$defs/key"
@@ -3768,7 +3798,7 @@
"properties": {
"type": {
"const": "processes",
- "description": "Count running processes"
+ "description": "Print the number of running processes"
},
"key": {
"$ref": "#/$defs/key"
@@ -3799,23 +3829,23 @@
"additionalProperties": false,
"properties": {
"type": {
- "description": "Print your public IP address, etc",
+ "description": "Print your public IP address and related information",
"const": "publicip"
},
"url": {
- "description": "The URL of public IP detection server to be used. Only HTTP protocol is supported",
+ "description": "URL of the public IP detection server to use. Only HTTP is supported",
"type": "string",
"format": "url",
"default": "http://ipinfo.io/ip"
},
"timeout": {
- "description": "Time in milliseconds to wait for the public ip server to respond.\n0 to disable timeout",
+ "description": "Time in milliseconds to wait for the public IP server to respond\nSet to 0 to disable the timeout",
"type": "integer",
"minimum": 0,
"default": 0
},
"ipv6": {
- "description": "Whether to use IPv6 for public IP detection server",
+ "description": "Whether to use IPv6 for the public IP detection server",
"type": "boolean",
"default": false
},
@@ -3852,16 +3882,16 @@
"const": "separator"
},
"string": {
- "description": "Set the string to be printed by the separator line",
+ "description": "String to print for the separator line",
"type": "string",
"default": "-"
},
"outputColor": {
- "description": "Set the color of the separator line",
+ "description": "Color of the separator line",
"$ref": "#/$defs/outputColor"
},
"times": {
- "description": "Set the times of separator string to repeat, or 0 to auto-detect",
+ "description": "Number of times to repeat the separator string, or 0 to auto-detect",
"type": "integer",
"minimum": 0,
"default": 0
@@ -3878,7 +3908,7 @@
"properties": {
"type": {
"const": "shell",
- "description": "Print current shell name and version"
+ "description": "Print the current shell name and version"
},
"key": {
"$ref": "#/$defs/key"
@@ -3909,11 +3939,11 @@
"additionalProperties": false,
"properties": {
"type": {
- "description": "Print sound devices, volume, etc",
+ "description": "Print sound devices, volume levels, etc.",
"const": "sound"
},
"soundType": {
- "description": "Set what type of sound devices should be printed",
+ "description": "Which sound devices to print",
"type": "string",
"oneOf": [
{
@@ -3968,7 +3998,7 @@
},
"separate": {
"type": "boolean",
- "description": "Set if detailed swap devices should be reported on separate lines instead of a summary",
+ "description": "Whether to report individual swap devices on separate lines instead of showing a summary",
"default": false
},
"percent": {
@@ -4004,7 +4034,7 @@
"properties": {
"type": {
"const": "terminal",
- "description": "Print current terminal name and version"
+ "description": "Print the current terminal name and version"
},
"key": {
"$ref": "#/$defs/key"
@@ -4036,7 +4066,7 @@
"properties": {
"type": {
"const": "terminalfont",
- "description": "Print font name and size used by current terminal"
+ "description": "Print the font name and size used by the current terminal"
},
"key": {
"$ref": "#/$defs/key"
@@ -4068,7 +4098,7 @@
"properties": {
"type": {
"const": "terminalsize",
- "description": "Print current terminal size"
+ "description": "Print the current terminal size"
},
"key": {
"$ref": "#/$defs/key"
@@ -4100,7 +4130,7 @@
"properties": {
"type": {
"const": "terminaltheme",
- "description": "Print current terminal theme (foreground and background colors)"
+ "description": "Print the current terminal theme (foreground and background colors)"
},
"key": {
"$ref": "#/$defs/key"
@@ -4132,7 +4162,7 @@
"properties": {
"type": {
"const": "theme",
- "description": "Print current theme of desktop environment"
+ "description": "Print the current desktop environment theme"
},
"key": {
"$ref": "#/$defs/key"
@@ -4163,29 +4193,29 @@
"additionalProperties": false,
"properties": {
"type": {
- "description": "Print title, which contains your user name, hostname",
+ "description": "Print the title, including your username and hostname",
"const": "title"
},
"fqdn": {
"type": "boolean",
- "description": "Set if the title should use fully qualified domain name",
+ "description": "Whether to use the fully qualified domain name in the title",
"default": false
},
"color": {
- "description": "Set colors of the different part of title",
+ "description": "Colors for the different parts of the title",
"type": "object",
"additionalProperties": false,
"properties": {
"user": {
- "description": "Set color of the user name (left part)",
+ "description": "Color of the username (left part)",
"$ref": "#/$defs/colors"
},
"at": {
- "description": "Set color of the @ symbol (middle part)",
+ "description": "Color of the @ symbol (middle part)",
"$ref": "#/$defs/colors"
},
"host": {
- "description": "Set color of the host name (right part)",
+ "description": "Color of the hostname (right part)",
"$ref": "#/$defs/colors"
}
}
@@ -4220,7 +4250,7 @@
"properties": {
"type": {
"const": "tpm",
- "description": "Print info of Trusted Platform Module (TPM) Security Device"
+ "description": "Print information about the Trusted Platform Module (TPM) security device"
},
"key": {
"$ref": "#/$defs/key"
@@ -4252,7 +4282,7 @@
"properties": {
"type": {
"const": "users",
- "description": "Print users currently logged in"
+ "description": "Print users who are currently logged in"
},
"compact": {
"type": "boolean",
@@ -4294,7 +4324,7 @@
"properties": {
"type": {
"const": "uptime",
- "description": "Print how long system has been running"
+ "description": "Print how long the system has been running"
},
"key": {
"$ref": "#/$defs/key"
@@ -4326,7 +4356,7 @@
"properties": {
"type": {
"const": "version",
- "description": "Print Fastfetch version"
+ "description": "Print the Fastfetch version and build information"
},
"key": {
"$ref": "#/$defs/key"
@@ -4358,7 +4388,7 @@
"properties": {
"type": {
"const": "vulkan",
- "description": "Print highest Vulkan version supported by the GPU"
+ "description": "Print the highest Vulkan version supported by the GPU"
},
"key": {
"$ref": "#/$defs/key"
@@ -4390,7 +4420,7 @@
"properties": {
"type": {
"const": "wallpaper",
- "description": "Print image file path of current wallpaper"
+ "description": "Print the file path of the current wallpaper"
},
"key": {
"$ref": "#/$defs/key"
@@ -4425,7 +4455,7 @@
"const": "weather"
},
"location": {
- "description": "The location to display\nMust be URI encoded (e.g., a whitespace must be encoded as \"+\")",
+ "description": "Location to display\nMust be URI-encoded (for example, spaces must be encoded as `+`)",
"type": "string"
},
"timeout": {
@@ -4435,7 +4465,7 @@
"default": 0
},
"outputFormat": {
- "description": "The output weather format to be used (must be URI encoded)",
+ "description": "Weather output format to use (must be URI-encoded)",
"type": "string",
"default": "%t+-+%C+(%l)"
},
@@ -4501,10 +4531,10 @@
"properties": {
"type": {
"const": "wm",
- "description": "Print window manager name and version"
+ "description": "Print the window manager name and version"
},
"detectPlugin": {
- "description": "Set if window manager plugin should be detected on supported platforms",
+ "description": "Whether to detect the window manager plugin on supported platforms",
"type": "boolean",
"default": true
},
@@ -4538,7 +4568,7 @@
"properties": {
"type": {
"const": "wmtheme",
- "description": "Print current theme of window manager"
+ "description": "Print the current window manager theme"
},
"key": {
"$ref": "#/$defs/key"
diff --git a/src/common/FFPlatform.h b/src/common/FFPlatform.h
index 75e81713c3..cf8224dda4 100644
--- a/src/common/FFPlatform.h
+++ b/src/common/FFPlatform.h
@@ -3,8 +3,7 @@
#include "common/FFstrbuf.h"
#include "common/FFlist.h"
-typedef struct FFPlatformSysinfo
-{
+typedef struct FFPlatformSysinfo {
FFstrbuf name;
FFstrbuf release;
FFstrbuf version;
@@ -12,8 +11,7 @@ typedef struct FFPlatformSysinfo
uint32_t pageSize;
} FFPlatformSysinfo;
-typedef struct FFPlatform
-{
+typedef struct FFPlatform {
FFstrbuf homeDir; // Trailing slash included
FFstrbuf cacheDir; // Trailing slash included
FFlist configDirs; // List of FFstrbuf, trailing slash included
@@ -22,11 +20,11 @@ typedef struct FFPlatform
FFstrbuf cwd; // Trailing slash included
uint32_t pid;
- #ifndef _WIN32
+#ifndef _WIN32
uint32_t uid;
- #else
+#else
FFstrbuf sid;
- #endif
+#endif
FFstrbuf userName;
FFstrbuf fullUserName;
FFstrbuf hostName;
diff --git a/src/common/FFcheckmacros.h b/src/common/FFcheckmacros.h
deleted file mode 100644
index 00d34b2d3f..0000000000
--- a/src/common/FFcheckmacros.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#pragma once
-
-#ifdef _MSC_VER
- #include
-#endif
-
-#if defined(__has_attribute) && __has_attribute(__warn_unused_result__)
- #define FF_C_NODISCARD __attribute__((__warn_unused_result__))
-#elif defined(_MSC_VER)
- #define FF_C_NODISCARD _Check_return_
-#else
- #define FF_C_NODISCARD
-#endif
-
-#if defined(__has_attribute) && __has_attribute(__format__)
- #define FF_C_PRINTF(formatStrIndex, argsStartIndex) __attribute__((__format__ (printf, formatStrIndex, argsStartIndex)))
-#else
- #define FF_C_PRINTF(formatStrIndex, argsStartIndex)
-#endif
-
-#if defined(__has_attribute) && __has_attribute(__format__)
- #define FF_C_SCANF(formatStrIndex, argsStartIndex) __attribute__((__format__ (scanf, formatStrIndex, argsStartIndex)))
-#else
- #define FF_C_SCANF(formatStrIndex, argsStartIndex)
-#endif
-
-#if defined(__has_attribute) && __has_attribute(__nonnull__)
- #define FF_C_NONNULL(argIndex, ...) __attribute__((__nonnull__(argIndex, ##__VA_ARGS__)))
-#else
- #define FF_C_NONNULL(argIndex, ...)
-#endif
-
-#if defined(__has_attribute) && __has_attribute(__returns_nonnull__)
- #define FF_C_RETURNS_NONNULL __attribute__((__returns_nonnull__))
-#else
- #define FF_C_RETURNS_NONNULL
-#endif
diff --git a/src/common/FFlist.h b/src/common/FFlist.h
index ec78012127..b380f6cf79 100644
--- a/src/common/FFlist.h
+++ b/src/common/FFlist.h
@@ -1,6 +1,6 @@
#pragma once
-#include "FFcheckmacros.h"
+#include "common/attributes.h"
#include
#include
@@ -9,136 +9,133 @@
#define FF_LIST_DEFAULT_ALLOC 16
-typedef struct FFlist
-{
+typedef struct FFlist {
uint8_t* data;
- uint32_t elementSize;
uint32_t length;
uint32_t capacity;
} FFlist;
-void* ffListAdd(FFlist* list);
+void* ffListAdd(FFlist* list, uint32_t elementSize);
// Removes the first element, and copy its value to `*result`
-bool ffListShift(FFlist* list, void* result);
+bool ffListShift(FFlist* list, uint32_t elementSize, void* result);
// Removes the last element, and copy its value to `*result`
-bool ffListPop(FFlist* list, void* result);
+bool ffListPop(FFlist* list, uint32_t elementSize, void* result);
-static inline void ffListInit(FFlist* list, uint32_t elementSize)
-{
- assert(elementSize > 0);
- list->elementSize = elementSize;
+static inline void ffListInit(FFlist* list) {
list->capacity = 0;
list->length = 0;
list->data = NULL;
}
-static inline void ffListInitA(FFlist* list, uint32_t elementSize, uint32_t capacity)
-{
- ffListInit(list, elementSize);
+static inline void ffListInitA(FFlist* list, uint32_t elementSize, uint32_t capacity) {
+ ffListInit(list);
list->capacity = capacity;
- list->data = __builtin_expect(capacity == 0, 0) ? NULL : (uint8_t*) malloc((size_t)list->capacity * list->elementSize);
+ list->data = __builtin_expect(capacity == 0, 0) ? NULL : (uint8_t*) malloc((size_t) capacity * elementSize);
}
-static inline FFlist ffListCreate(uint32_t elementSize)
-{
+FF_A_NODISCARD static inline FFlist ffListCreate() {
FFlist result;
- ffListInit(&result, elementSize);
+ ffListInit(&result);
return result;
}
-static inline void* ffListGet(const FFlist* list, uint32_t index)
-{
+FF_A_NODISCARD static inline FFlist ffListCreateA(uint32_t elementSize, uint32_t capacity) {
+ FFlist result;
+ ffListInitA(&result, elementSize, capacity);
+ return result;
+}
+
+FF_A_NODISCARD static inline void* ffListGet(const FFlist* list, uint32_t elementSize, uint32_t index) {
assert(list->capacity > index);
- return list->data + (index * list->elementSize);
+ return list->data + (index * elementSize);
}
-FF_C_NODISCARD static inline uint32_t ffListFirstIndexComp(const FFlist* list, void* compElement, bool(*compFunc)(const void*, const void*))
-{
- for(uint32_t i = 0; i < list->length; i++)
- {
- if(compFunc(ffListGet(list, i), compElement))
+FF_A_NODISCARD static inline uint32_t ffListFirstIndexComp(const FFlist* list, uint32_t elementSize, void* compElement, bool (*compFunc)(const void*, const void*)) {
+ for (uint32_t i = 0; i < list->length; i++) {
+ if (compFunc(ffListGet(list, elementSize, i), compElement)) {
return i;
+ }
}
return list->length;
}
-static inline bool ffListContains(const FFlist* list, void* compElement, bool(*compFunc)(const void*, const void*))
-{
- return ffListFirstIndexComp(list, compElement, compFunc) != list->length;
+FF_A_NODISCARD static inline bool ffListContains(const FFlist* list, uint32_t elementSize, void* compElement, bool (*compFunc)(const void*, const void*)) {
+ return ffListFirstIndexComp(list, elementSize, compElement, compFunc) != list->length;
}
-static inline void ffListSort(FFlist* list, int(*compar)(const void*, const void*))
-{
- qsort(list->data, list->length, list->elementSize, compar);
+static inline void ffListSort(FFlist* list, uint32_t elementSize, int (*compar)(const void*, const void*)) {
+ qsort(list->data, list->length, elementSize, compar);
}
// Move the contents of `src` into `list`, and left `src` empty
-static inline void ffListInitMove(FFlist* list, FFlist* src)
-{
- if (src)
- {
- list->elementSize = src->elementSize;
+static inline void ffListInitMove(FFlist* list, FFlist* src) {
+ if (src) {
list->capacity = src->capacity;
list->length = src->length;
list->data = src->data;
- ffListInit(src, list->elementSize);
- }
- else
- {
- ffListInit(list, 0);
+ ffListInit(src);
+ } else {
+ ffListInit(list);
}
}
-static inline void ffListDestroy(FFlist* list)
-{
- if (!list->data) return;
+static inline void ffListDestroy(FFlist* list) {
+ if (!list->data) {
+ return;
+ }
- //Avoid free-after-use. These 3 assignments are cheap so don't remove them
+ // Avoid free-after-use. These 3 assignments are cheap so don't remove them
list->capacity = list->length = 0;
free(list->data);
list->data = NULL;
}
-static inline void ffListClear(FFlist* list)
-{
+static inline void ffListClear(FFlist* list) {
list->length = 0;
}
-static inline void ffListReserve(FFlist* list, uint32_t newCapacity)
-{
- if (__builtin_expect(newCapacity <= list->capacity, false))
+static inline void ffListReserve(FFlist* list, uint32_t elementSize, uint32_t newCapacity) {
+ if (__builtin_expect(newCapacity <= list->capacity, false)) {
return;
+ }
- list->data = (uint8_t*) realloc(list->data, (size_t) newCapacity * list->elementSize);
+ list->data = (uint8_t*) realloc(list->data, (size_t) newCapacity * elementSize);
list->capacity = newCapacity;
}
-#define FF_LIST_FOR_EACH(itemType, itemVarName, listVar) \
- assert(sizeof(itemType) == (listVar).elementSize); \
- for(itemType* itemVarName = (itemType*)(listVar).data; \
- itemVarName - (itemType*)(listVar).data < (intptr_t)(listVar).length; \
+#define FF_LIST_FOR_EACH(itemType, itemVarName, listVar) \
+ for (itemType* itemVarName = (itemType*) (listVar).data; \
+ itemVarName - (itemType*) (listVar).data < (intptr_t) (listVar).length; \
++itemVarName)
-#define FF_LIST_AUTO_DESTROY FFlist __attribute__((__cleanup__(ffListDestroy)))
+#define FF_LIST_AUTO_DESTROY FFlist FF_A_CLEANUP(ffListDestroy)
#define FF_LIST_GET(itemType, listVar, index) \
- ({ \
- assert(sizeof(itemType) == (listVar).elementSize); \
+ ({ \
assert((listVar).capacity > (index)); \
- (itemType*)(listVar).data + (index); \
+ (itemType*) (listVar).data + (index); \
})
-#define FF_LIST_ADD(itemType, listVar) \
- ({ \
- assert(sizeof(itemType) == (listVar).elementSize); \
- (itemType*) ffListAdd(&(listVar)); \
- })
+#define FF_LIST_ADD(itemType, listVar) (itemType*) ffListAdd(&(listVar), (uint32_t) sizeof(itemType))
#define FF_LIST_FIRST(itemType, listVar) FF_LIST_GET(itemType, listVar, 0)
-#define FF_LIST_LAST(itemType, listVar) \
- ({ \
- assert((listVar).length > 0); \
+#define FF_LIST_LAST(itemType, listVar) \
+ ({ \
+ assert((listVar).length > 0); \
FF_LIST_GET(itemType, listVar, ((listVar).length - 1)); \
})
+
+#define FF_LIST_CONTAINS(listVar, pCompElement, compFunc) \
+ ({ \
+ typedef __typeof__(*(pCompElement)) compElementType; \
+ typedef bool compFuncType(const compElementType*, const compElementType*); \
+ static_assert(__builtin_types_compatible_p(__typeof__(compFunc), compFuncType), "In compatible callback function"); \
+ ffListContains(&(listVar), (uint32_t) sizeof(*(pCompElement)), (pCompElement), (bool (*)(const void*, const void*)) compFunc); \
+ })
+
+#define FF_LIST_SHIFT(listVar, pResult) \
+ ffListShift(&(listVar), (uint32_t) sizeof(*(pResult)), (pResult))
+#define FF_LIST_POP(listVar, pResult) \
+ ffListPop(&(listVar), (uint32_t) sizeof(*(pResult)), (pResult))
diff --git a/src/common/FFstrbuf.h b/src/common/FFstrbuf.h
index 80a8175506..2c9a09b9bd 100644
--- a/src/common/FFstrbuf.h
+++ b/src/common/FFstrbuf.h
@@ -1,6 +1,6 @@
#pragma once
-#include "FFcheckmacros.h"
+#include "common/attributes.h"
#include
#include
@@ -17,8 +17,8 @@
#endif
#ifdef _WIN32
- // #include
- __stdcall char* StrStrIA(const char* lpFirst, const char* lpSrch);
+// #include
+__stdcall char* StrStrIA(const char* lpFirst, const char* lpSrch);
#define strcasestr StrStrIA
#endif
@@ -26,8 +26,7 @@
// static string (allocated == 0), chars points to a string literal
// dynamic string (allocated > 0), chars points to a heap allocated buffer
-typedef struct FFstrbuf
-{
+typedef struct FFstrbuf {
uint32_t allocated;
uint32_t length;
char* chars;
@@ -47,8 +46,8 @@ static inline void ffStrbufAppend(FFstrbuf* __restrict strbuf, const FFstrbuf* _
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_C_PRINTF(2, 3) void ffStrbufAppendF(FFstrbuf* strbuf, const char* format, ...);
+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);
const char* ffStrbufAppendSUntilC(FFstrbuf* strbuf, const char* value, char until);
@@ -61,7 +60,7 @@ void ffStrbufInsertNC(FFstrbuf* strbuf, uint32_t index, uint32_t num, char c);
// NOTE: Unlike ffStrbufAppend*, ffStrbufSet* functions may NOT reserve extra space
void ffStrbufSet(FFstrbuf* strbuf, const FFstrbuf* value);
void ffStrbufSetNS(FFstrbuf* strbuf, uint32_t length, const char* value);
-FF_C_PRINTF(2, 3) void ffStrbufSetF(FFstrbuf* strbuf, const char* format, ...);
+FF_A_PRINTF(2, 3) void ffStrbufSetF(FFstrbuf* strbuf, const char* format, ...);
void ffStrbufTrimLeft(FFstrbuf* strbuf, char c);
void ffStrbufTrimRight(FFstrbuf* strbuf, char c);
@@ -72,10 +71,10 @@ bool ffStrbufRemoveSubstr(FFstrbuf* strbuf, uint32_t startIndex, uint32_t endInd
void ffStrbufRemoveS(FFstrbuf* strbuf, const char* str);
void ffStrbufRemoveStrings(FFstrbuf* strbuf, uint32_t numStrings, const char* strings[]);
-FF_C_NODISCARD uint32_t ffStrbufNextIndexC(const FFstrbuf* strbuf, uint32_t start, char c);
-FF_C_NODISCARD uint32_t ffStrbufNextIndexS(const FFstrbuf* strbuf, uint32_t start, const char* str);
+FF_A_NODISCARD uint32_t ffStrbufNextIndexC(const FFstrbuf* strbuf, uint32_t start, char c);
+FF_A_NODISCARD uint32_t ffStrbufNextIndexS(const FFstrbuf* strbuf, uint32_t start, const char* str);
-FF_C_NODISCARD uint32_t ffStrbufPreviousIndexC(const FFstrbuf* strbuf, uint32_t start, char c);
+FF_A_NODISCARD uint32_t ffStrbufPreviousIndexC(const FFstrbuf* strbuf, uint32_t start, char c);
void ffStrbufReplaceAllC(FFstrbuf* strbuf, char find, char replace);
@@ -87,7 +86,7 @@ bool ffStrbufSubstrAfterFirstS(FFstrbuf* strbuf, const char* str);
bool ffStrbufSubstrAfterLastC(FFstrbuf* strbuf, char c);
bool ffStrbufSubstr(FFstrbuf* strbuf, uint32_t start, uint32_t end);
-FF_C_NODISCARD uint32_t ffStrbufCountC(const FFstrbuf* strbuf, char c);
+FF_A_NODISCARD uint32_t ffStrbufCountC(const FFstrbuf* strbuf, char c);
bool ffStrbufRemoveIgnCaseEndS(FFstrbuf* strbuf, const char* end);
@@ -96,9 +95,9 @@ bool ffStrbufEnsureEndsWithC(FFstrbuf* strbuf, char c);
void ffStrbufWriteTo(const FFstrbuf* strbuf, FILE* file);
void ffStrbufPutTo(const FFstrbuf* strbuf, FILE* file);
-FF_C_NODISCARD double ffStrbufToDouble(const FFstrbuf* strbuf, double defaultValue);
-FF_C_NODISCARD int64_t ffStrbufToSInt(const FFstrbuf* strbuf, int64_t defaultValue);
-FF_C_NODISCARD uint64_t ffStrbufToUInt(const FFstrbuf* strbuf, uint64_t defaultValue);
+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);
@@ -126,16 +125,14 @@ void ffStrbufGetdelimRestore(char** lineptr, size_t* n, char delimiter, FFstrbuf
*
* @return true if a line has been read, false if the end of the buffer has been reached.
*/
-static inline bool ffStrbufGetline(char** lineptr, size_t* n, FFstrbuf* buffer)
-{
+static inline bool ffStrbufGetline(char** lineptr, size_t* n, FFstrbuf* buffer) {
return ffStrbufGetdelim(lineptr, n, '\n', buffer);
}
/**
* @brief Restore the end of a line that was modified by ffStrbufGetline.
* @warning This function should be called before breaking an ffStrbufGetline loop if `buffer` will be used later.
*/
-static inline void ffStrbufGetlineRestore(char** lineptr, size_t* n, FFstrbuf* buffer)
-{
+static inline void ffStrbufGetlineRestore(char** lineptr, size_t* n, FFstrbuf* buffer) {
ffStrbufGetdelimRestore(lineptr, n, '\n', buffer);
}
bool ffStrbufRemoveDupWhitespaces(FFstrbuf* strbuf);
@@ -152,69 +149,58 @@ void ffStrbufAppendUInt(FFstrbuf* strbuf, uint64_t value);
// if `precision < 0`, let yyjson decide the precision
void ffStrbufAppendDouble(FFstrbuf* strbuf, double value, int8_t precision, bool trailingZeros);
-FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateA(uint32_t allocate)
-{
+FF_A_NODISCARD static inline FFstrbuf ffStrbufCreateA(uint32_t allocate) {
FFstrbuf strbuf;
ffStrbufInitA(&strbuf, allocate);
return strbuf;
}
-static inline void ffStrbufInitCopy(FFstrbuf* __restrict strbuf, const FFstrbuf* __restrict src)
-{
- if (src->allocated == 0) // static string
+static inline void ffStrbufInitCopy(FFstrbuf* __restrict strbuf, const FFstrbuf* __restrict src) {
+ if (src->allocated == 0) { // static string
*strbuf = *src;
- else
- {
+ } else {
ffStrbufInitA(strbuf, src->allocated);
ffStrbufAppend(strbuf, src);
}
}
-FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateCopy(const FFstrbuf* src)
-{
+FF_A_NODISCARD static inline FFstrbuf ffStrbufCreateCopy(const FFstrbuf* src) {
FFstrbuf strbuf;
ffStrbufInitCopy(&strbuf, src);
return strbuf;
}
// Move the content of `src` into `strbuf`, and left `src` empty
-static inline void ffStrbufInitMove(FFstrbuf* strbuf, FFstrbuf* src)
-{
- if (src)
- {
+static inline void ffStrbufInitMove(FFstrbuf* strbuf, FFstrbuf* src) {
+ if (src) {
*strbuf = *src;
ffStrbufInit(src);
- }
- else
+ } else {
ffStrbufInit(strbuf);
+ }
}
-FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateMove(FFstrbuf* src)
-{
+FF_A_NODISCARD static inline FFstrbuf ffStrbufCreateMove(FFstrbuf* src) {
FFstrbuf strbuf;
ffStrbufInitMove(&strbuf, src);
return strbuf;
}
-FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateVF(const char* format, va_list arguments)
-{
+FF_A_NODISCARD static inline FFstrbuf ffStrbufCreateVF(const char* format, va_list arguments) {
FFstrbuf strbuf;
ffStrbufInitVF(&strbuf, format, arguments);
return strbuf;
}
-FF_C_PRINTF(2, 3)
-static inline void ffStrbufInitF(FFstrbuf* strbuf, const char* format, ...)
-{
+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_C_PRINTF(1, 2)
-FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateF(const char* format, ...)
-{
+FF_A_PRINTF(1, 2) FF_A_NODISCARD static inline FFstrbuf
+ffStrbufCreateF(const char* format, ...) {
FFstrbuf strbuf;
va_list arguments;
@@ -225,50 +211,46 @@ FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateF(const char* format, ...)
return strbuf;
}
-static inline void ffStrbufInitMoveS(FFstrbuf* strbuf, char* heapStr)
-{
+static inline void ffStrbufInitMoveS(FFstrbuf* strbuf, char* heapStr) {
ffStrbufInitMoveNS(strbuf, (uint32_t) strlen(heapStr), heapStr);
}
// Despite the name, this function resets strbuf to the initial/unallocated state
-static inline void ffStrbufDestroy(FFstrbuf* strbuf)
-{
- if(strbuf->allocated > 0)
+static inline void ffStrbufDestroy(FFstrbuf* strbuf) {
+ if (strbuf->allocated > 0) {
free(strbuf->chars);
+ }
ffStrbufInit(strbuf);
}
-FF_C_NODISCARD static inline uint32_t ffStrbufGetFree(const FFstrbuf* strbuf)
-{
+FF_A_NODISCARD static inline uint32_t ffStrbufGetFree(const FFstrbuf* strbuf) {
assert(strbuf != NULL);
- if(strbuf->allocated == 0)
+ if (strbuf->allocated == 0) {
return 0;
+ }
return strbuf->allocated - strbuf->length - 1; // - 1 for the null byte
}
-static inline void ffStrbufRecalculateLength(FFstrbuf* strbuf)
-{
+static inline void ffStrbufRecalculateLength(FFstrbuf* strbuf) {
strbuf->length = (uint32_t) strlen(strbuf->chars);
}
-static inline void ffStrbufSetS(FFstrbuf* strbuf, const char* value)
-{
+static inline void ffStrbufSetS(FFstrbuf* strbuf, const char* value) {
assert(strbuf != NULL);
- if (value == NULL)
+ if (value == NULL) {
ffStrbufClear(strbuf);
- else
+ } else {
ffStrbufSetNS(strbuf, (uint32_t) strlen(value), value);
+ }
}
-static inline bool ffStrbufSetJsonVal(FFstrbuf* strbuf, yyjson_val* jsonVal)
-{
+static inline bool ffStrbufSetJsonVal(FFstrbuf* strbuf, yyjson_val* jsonVal) {
assert(strbuf != NULL);
- if (yyjson_is_str(jsonVal))
- {
+ if (yyjson_is_str(jsonVal)) {
ffStrbufSetNS(strbuf, (uint32_t) unsafe_yyjson_get_len(jsonVal), unsafe_yyjson_get_str(jsonVal));
return true;
}
@@ -277,358 +259,309 @@ static inline bool ffStrbufSetJsonVal(FFstrbuf* strbuf, yyjson_val* jsonVal)
return false;
}
-static inline void ffStrbufAppendS(FFstrbuf* strbuf, const char* value)
-{
- if(value == NULL)
+static inline void ffStrbufAppendS(FFstrbuf* strbuf, const char* value) {
+ if (value == NULL) {
return;
+ }
ffStrbufAppendNS(strbuf, (uint32_t) strlen(value), value);
}
-static inline bool ffStrbufAppendJsonVal(FFstrbuf* strbuf, yyjson_val* jsonVal)
-{
- if (yyjson_is_str(jsonVal))
- {
+static inline bool ffStrbufAppendJsonVal(FFstrbuf* strbuf, yyjson_val* jsonVal) {
+ if (yyjson_is_str(jsonVal)) {
ffStrbufAppendNS(strbuf, (uint32_t) unsafe_yyjson_get_len(jsonVal), unsafe_yyjson_get_str(jsonVal));
return true;
}
return false;
}
-static inline void ffStrbufInit(FFstrbuf* strbuf)
-{
+static inline void ffStrbufInit(FFstrbuf* strbuf) {
extern char* CHAR_NULL_PTR;
strbuf->allocated = strbuf->length = 0;
strbuf->chars = CHAR_NULL_PTR;
}
-FF_C_NODISCARD static inline FFstrbuf ffStrbufCreate(void)
-{
+FF_A_NODISCARD static inline FFstrbuf ffStrbufCreate(void) {
FFstrbuf strbuf;
ffStrbufInit(&strbuf);
return strbuf;
}
-static inline void ffStrbufInitStatic(FFstrbuf* strbuf, const char* str)
-{
+static inline void ffStrbufInitStatic(FFstrbuf* strbuf, const char* str) {
ffStrbufInit(strbuf);
- if (!str) return;
+ if (!str) {
+ return;
+ }
strbuf->allocated = 0;
strbuf->length = (uint32_t) strlen(str);
strbuf->chars = (char*) str;
}
-FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateStatic(const char* str)
-{
+FF_A_NODISCARD static inline FFstrbuf ffStrbufCreateStatic(const char* str) {
FFstrbuf strbuf;
ffStrbufInitStatic(&strbuf, str);
return strbuf;
}
-static inline void ffStrbufSetStatic(FFstrbuf* strbuf, const char* value)
-{
- if(strbuf->allocated > 0)
+static inline void ffStrbufSetStatic(FFstrbuf* strbuf, const char* value) {
+ if (strbuf->allocated > 0) {
free(strbuf->chars);
+ }
- if(value != NULL)
+ if (value != NULL) {
ffStrbufInitStatic(strbuf, value);
- else
+ } else {
ffStrbufInit(strbuf);
+ }
}
-static inline void ffStrbufInitNS(FFstrbuf* strbuf, uint32_t length, const char* str)
-{
+static inline void ffStrbufInitNS(FFstrbuf* strbuf, uint32_t length, const char* str) {
ffStrbufInit(strbuf);
ffStrbufAppendNS(strbuf, length, str);
}
-FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateNS(uint32_t length, const char* str)
-{
+FF_A_NODISCARD static inline FFstrbuf ffStrbufCreateNS(uint32_t length, const char* str) {
FFstrbuf strbuf;
ffStrbufInitNS(&strbuf, length, str);
return strbuf;
}
-static inline bool ffStrbufInitJsonVal(FFstrbuf* strbuf, yyjson_val* jsonVal)
-{
+static inline bool ffStrbufInitJsonVal(FFstrbuf* strbuf, yyjson_val* jsonVal) {
ffStrbufInit(strbuf);
return ffStrbufAppendJsonVal(strbuf, jsonVal);
}
-static inline void ffStrbufInitS(FFstrbuf* strbuf, const char* str)
-{
+static inline void ffStrbufInitS(FFstrbuf* strbuf, const char* str) {
ffStrbufInit(strbuf);
ffStrbufAppendS(strbuf, str);
}
-FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateS(const char* str)
-{
+FF_A_NODISCARD static inline FFstrbuf ffStrbufCreateS(const char* str) {
FFstrbuf strbuf;
ffStrbufInitS(&strbuf, str);
return strbuf;
}
-static inline void ffStrbufAppend(FFstrbuf* __restrict strbuf, const FFstrbuf* __restrict value)
-{
+static inline void ffStrbufAppend(FFstrbuf* __restrict strbuf, const FFstrbuf* __restrict value) {
assert(value != strbuf);
- if(value == NULL)
+ if (value == NULL) {
return;
+ }
ffStrbufAppendNS(strbuf, value->length, value->chars);
}
-static inline void ffStrbufPrepend(FFstrbuf* strbuf, FFstrbuf* value)
-{
- if(value == NULL)
+static inline void ffStrbufPrepend(FFstrbuf* strbuf, FFstrbuf* value) {
+ if (value == NULL) {
return;
+ }
ffStrbufPrependNS(strbuf, value->length, value->chars);
}
-static inline void ffStrbufPrependS(FFstrbuf* strbuf, const char* value)
-{
- if(value == NULL)
+static inline void ffStrbufPrependS(FFstrbuf* strbuf, const char* value) {
+ if (value == NULL) {
return;
+ }
ffStrbufPrependNS(strbuf, (uint32_t) strlen(value), value);
}
-static inline FF_C_NODISCARD int ffStrbufComp(const FFstrbuf* strbuf, const FFstrbuf* comp)
-{
+static inline FF_A_NODISCARD int ffStrbufComp(const FFstrbuf* strbuf, const FFstrbuf* comp) {
uint32_t length = strbuf->length > comp->length ? comp->length : strbuf->length;
return memcmp(strbuf->chars, comp->chars, length + 1);
}
-static inline FF_C_NODISCARD bool ffStrbufEqual(const FFstrbuf* strbuf, const FFstrbuf* comp)
-{
+static inline FF_A_NODISCARD bool ffStrbufEqual(const FFstrbuf* strbuf, const FFstrbuf* comp) {
return ffStrbufComp(strbuf, comp) == 0;
}
-static inline FF_C_NODISCARD int ffStrbufCompS(const FFstrbuf* strbuf, const char* comp)
-{
+static inline FF_A_NODISCARD int ffStrbufCompS(const FFstrbuf* strbuf, const char* comp) {
return strcmp(strbuf->chars, comp);
}
-static inline FF_C_NODISCARD bool ffStrbufEqualS(const FFstrbuf* strbuf, const char* comp)
-{
+static inline FF_A_NODISCARD bool ffStrbufEqualS(const FFstrbuf* strbuf, const char* comp) {
return ffStrbufCompS(strbuf, comp) == 0;
}
-static inline FF_C_NODISCARD int ffStrbufIgnCaseCompS(const FFstrbuf* strbuf, const char* comp)
-{
+static inline FF_A_NODISCARD int ffStrbufIgnCaseCompS(const FFstrbuf* strbuf, const char* comp) {
return strcasecmp(strbuf->chars, comp);
}
-static inline FF_C_NODISCARD bool ffStrbufIgnCaseEqualS(const FFstrbuf* strbuf, const char* comp)
-{
+static inline FF_A_NODISCARD bool ffStrbufIgnCaseEqualS(const FFstrbuf* strbuf, const char* comp) {
return ffStrbufIgnCaseCompS(strbuf, comp) == 0;
}
-static inline FF_C_NODISCARD int ffStrbufIgnCaseComp(const FFstrbuf* strbuf, const FFstrbuf* comp)
-{
+static inline FF_A_NODISCARD int ffStrbufIgnCaseComp(const FFstrbuf* strbuf, const FFstrbuf* comp) {
return ffStrbufIgnCaseCompS(strbuf, comp->chars);
}
-static inline FF_C_NODISCARD bool ffStrbufIgnCaseEqual(const FFstrbuf* strbuf, const FFstrbuf* comp)
-{
+static inline FF_A_NODISCARD bool ffStrbufIgnCaseEqual(const FFstrbuf* strbuf, const FFstrbuf* comp) {
return ffStrbufIgnCaseComp(strbuf, comp) == 0;
}
-static inline FF_C_NODISCARD bool ffStrbufContainC(const FFstrbuf* strbuf, char c)
-{
+static inline FF_A_NODISCARD bool ffStrbufContainC(const FFstrbuf* strbuf, char c) {
return memchr(strbuf->chars, c, strbuf->length) != NULL;
}
-static inline FF_C_NODISCARD bool ffStrbufContainS(const FFstrbuf* strbuf, const char* str)
-{
+static inline FF_A_NODISCARD bool ffStrbufContainS(const FFstrbuf* strbuf, const char* str) {
return strstr(strbuf->chars, str) != NULL;
}
-static inline FF_C_NODISCARD bool ffStrbufContain(const FFstrbuf* strbuf, const FFstrbuf* str)
-{
+static inline FF_A_NODISCARD bool ffStrbufContain(const FFstrbuf* strbuf, const FFstrbuf* str) {
return ffStrbufContainS(strbuf, str->chars);
}
-static inline FF_C_NODISCARD bool ffStrbufContainIgnCaseS(const FFstrbuf* strbuf, const char* str)
-{
+static inline FF_A_NODISCARD bool ffStrbufContainIgnCaseS(const FFstrbuf* strbuf, const char* str) {
return strcasestr(strbuf->chars, str) != NULL;
}
-static inline FF_C_NODISCARD bool ffStrbufContainIgnCase(const FFstrbuf* strbuf, const FFstrbuf* str)
-{
+static inline FF_A_NODISCARD bool ffStrbufContainIgnCase(const FFstrbuf* strbuf, const FFstrbuf* str) {
return ffStrbufContainIgnCaseS(strbuf, str->chars);
}
-static inline FF_C_NODISCARD uint32_t ffStrbufFirstIndexC(const FFstrbuf* strbuf, char c)
-{
+static inline FF_A_NODISCARD uint32_t ffStrbufFirstIndexC(const FFstrbuf* strbuf, char c) {
return ffStrbufNextIndexC(strbuf, 0, c);
}
-static inline FF_C_NODISCARD uint32_t ffStrbufFirstIndex(const FFstrbuf* strbuf, const FFstrbuf* searched)
-{
+static inline FF_A_NODISCARD uint32_t ffStrbufFirstIndex(const FFstrbuf* strbuf, const FFstrbuf* searched) {
return ffStrbufNextIndexS(strbuf, 0, searched->chars);
}
-static inline FF_C_NODISCARD uint32_t ffStrbufFirstIndexS(const FFstrbuf* strbuf, const char* str)
-{
+static inline FF_A_NODISCARD uint32_t ffStrbufFirstIndexS(const FFstrbuf* strbuf, const char* str) {
return ffStrbufNextIndexS(strbuf, 0, str);
}
-static inline FF_C_NODISCARD uint32_t ffStrbufLastIndexC(const FFstrbuf* strbuf, char c)
-{
- if(strbuf->length == 0)
+static inline FF_A_NODISCARD uint32_t ffStrbufLastIndexC(const FFstrbuf* strbuf, char c) {
+ if (strbuf->length == 0) {
return 0;
+ }
return ffStrbufPreviousIndexC(strbuf, strbuf->length - 1, c);
}
-static inline bool ffStrbufSubstrBeforeFirstC(FFstrbuf* strbuf, char c)
-{
+static inline bool ffStrbufSubstrBeforeFirstC(FFstrbuf* strbuf, char c) {
return ffStrbufSubstrBefore(strbuf, ffStrbufFirstIndexC(strbuf, c));
}
-static inline bool ffStrbufSubstrBeforeLastC(FFstrbuf* strbuf, char c)
-{
+static inline bool ffStrbufSubstrBeforeLastC(FFstrbuf* strbuf, char c) {
return ffStrbufSubstrBefore(strbuf, ffStrbufLastIndexC(strbuf, c));
}
-static inline FF_C_NODISCARD bool ffStrbufStartsWithC(const FFstrbuf* strbuf, char c)
-{
+static inline FF_A_NODISCARD bool ffStrbufStartsWithC(const FFstrbuf* strbuf, char c) {
return strbuf->chars[0] == c;
}
-static inline FF_C_NODISCARD bool ffStrbufStartsWithSN(const FFstrbuf* strbuf, const char* start, uint32_t length)
-{
- if (length > strbuf->length)
+static inline FF_A_NODISCARD bool ffStrbufStartsWithSN(const FFstrbuf* strbuf, const char* start, uint32_t length) {
+ if (length > strbuf->length) {
return false;
+ }
return memcmp(strbuf->chars, start, length) == 0;
}
-static inline FF_C_NODISCARD bool ffStrbufStartsWithS(const FFstrbuf* strbuf, const char* start)
-{
+static inline FF_A_NODISCARD bool ffStrbufStartsWithS(const FFstrbuf* strbuf, const char* start) {
return ffStrbufStartsWithSN(strbuf, start, (uint32_t) strlen(start));
}
-static inline FF_C_NODISCARD bool ffStrbufStartsWith(const FFstrbuf* strbuf, const FFstrbuf* start)
-{
+static inline FF_A_NODISCARD bool ffStrbufStartsWith(const FFstrbuf* strbuf, const FFstrbuf* start) {
return ffStrbufStartsWithSN(strbuf, start->chars, start->length);
}
-static inline FF_C_NODISCARD bool ffStrbufStartsWithIgnCaseNS(const FFstrbuf* strbuf, uint32_t length, const char* start)
-{
- if(length > strbuf->length)
+static inline FF_A_NODISCARD bool ffStrbufStartsWithIgnCaseNS(const FFstrbuf* strbuf, uint32_t length, const char* start) {
+ if (length > strbuf->length) {
return false;
+ }
return strncasecmp(strbuf->chars, start, length) == 0;
}
-static inline FF_C_NODISCARD bool ffStrbufStartsWithIgnCaseS(const FFstrbuf* strbuf, const char* start)
-{
+static inline FF_A_NODISCARD bool ffStrbufStartsWithIgnCaseS(const FFstrbuf* strbuf, const char* start) {
return ffStrbufStartsWithIgnCaseNS(strbuf, (uint32_t) strlen(start), start);
}
-static inline FF_C_NODISCARD bool ffStrbufStartsWithIgnCase(const FFstrbuf* strbuf, const FFstrbuf* start)
-{
+static inline FF_A_NODISCARD bool ffStrbufStartsWithIgnCase(const FFstrbuf* strbuf, const FFstrbuf* start) {
return ffStrbufStartsWithIgnCaseNS(strbuf, start->length, start->chars);
}
-static inline FF_C_NODISCARD bool ffStrbufEndsWithC(const FFstrbuf* strbuf, char c)
-{
- return strbuf->length == 0 ? false :
- strbuf->chars[strbuf->length - 1] == c;
+static inline FF_A_NODISCARD bool ffStrbufEndsWithC(const FFstrbuf* strbuf, char c) {
+ return strbuf->length == 0 ? false : strbuf->chars[strbuf->length - 1] == c;
}
-static inline FF_C_NODISCARD bool ffStrbufEndsWithNS(const FFstrbuf* strbuf, uint32_t endLength, const char* end)
-{
- if(endLength > strbuf->length)
+static inline FF_A_NODISCARD bool ffStrbufEndsWithNS(const FFstrbuf* strbuf, uint32_t endLength, const char* end) {
+ if (endLength > strbuf->length) {
return false;
+ }
return memcmp(strbuf->chars + strbuf->length - endLength, end, endLength) == 0;
}
-static inline FF_C_NODISCARD bool ffStrbufEndsWithS(const FFstrbuf* strbuf, const char* end)
-{
+static inline FF_A_NODISCARD bool ffStrbufEndsWithS(const FFstrbuf* strbuf, const char* end) {
return ffStrbufEndsWithNS(strbuf, (uint32_t) strlen(end), end);
}
-static inline FF_C_NODISCARD bool ffStrbufEndsWithFn(const FFstrbuf* strbuf, int (*const fn)(int))
-{
- return strbuf->length == 0 ? false :
- fn(strbuf->chars[strbuf->length - 1]);
+static inline FF_A_NODISCARD bool ffStrbufEndsWithFn(const FFstrbuf* strbuf, int (*const fn)(int)) {
+ return strbuf->length == 0 ? false : fn(strbuf->chars[strbuf->length - 1]);
}
-static inline FF_C_NODISCARD bool ffStrbufEndsWith(const FFstrbuf* strbuf, const FFstrbuf* end)
-{
+static inline FF_A_NODISCARD bool ffStrbufEndsWith(const FFstrbuf* strbuf, const FFstrbuf* end) {
return ffStrbufEndsWithNS(strbuf, end->length, end->chars);
}
-static inline FF_C_NODISCARD bool ffStrbufEndsWithIgnCaseNS(const FFstrbuf* strbuf, uint32_t endLength, const char* end)
-{
- if(endLength > strbuf->length)
+static inline FF_A_NODISCARD bool ffStrbufEndsWithIgnCaseNS(const FFstrbuf* strbuf, uint32_t endLength, const char* end) {
+ if (endLength > strbuf->length) {
return false;
+ }
return strcasecmp(strbuf->chars + strbuf->length - endLength, end) == 0;
}
-static inline FF_C_NODISCARD bool ffStrbufEndsWithIgnCaseS(const FFstrbuf* strbuf, const char* end)
-{
+static inline FF_A_NODISCARD bool ffStrbufEndsWithIgnCaseS(const FFstrbuf* strbuf, const char* end) {
return ffStrbufEndsWithIgnCaseNS(strbuf, (uint32_t) strlen(end), end);
}
-static inline FF_C_NODISCARD bool ffStrbufEndsWithIgnCase(const FFstrbuf* strbuf, const FFstrbuf* end)
-{
+static inline FF_A_NODISCARD bool ffStrbufEndsWithIgnCase(const FFstrbuf* strbuf, const FFstrbuf* end) {
return ffStrbufEndsWithIgnCaseNS(strbuf, end->length, end->chars);
}
-static inline void ffStrbufTrim(FFstrbuf* strbuf, char c)
-{
+static inline void ffStrbufTrim(FFstrbuf* strbuf, char c) {
ffStrbufTrimRight(strbuf, c);
ffStrbufTrimLeft(strbuf, c);
}
-static inline void ffStrbufTrimSpace(FFstrbuf* strbuf)
-{
+static inline void ffStrbufTrimSpace(FFstrbuf* strbuf) {
ffStrbufTrimRightSpace(strbuf);
ffStrbufTrimLeftSpace(strbuf);
}
-static inline bool ffStrbufMatchSeparatedS(const FFstrbuf* strbuf, const char* comp, char separator)
-{
+static inline bool ffStrbufMatchSeparatedS(const FFstrbuf* strbuf, const char* comp, char separator) {
return ffStrbufMatchSeparatedNS(strbuf, (uint32_t) strlen(comp), comp, separator);
}
-static inline bool ffStrbufMatchSeparated(const FFstrbuf* strbuf, const FFstrbuf* comp, char separator)
-{
+static inline bool ffStrbufMatchSeparated(const FFstrbuf* strbuf, const FFstrbuf* comp, char separator) {
return ffStrbufMatchSeparatedNS(strbuf, comp->length, comp->chars, separator);
}
-static inline bool ffStrbufMatchSeparatedIgnCaseS(const FFstrbuf* strbuf, const char* comp, char separator)
-{
+static inline bool ffStrbufMatchSeparatedIgnCaseS(const FFstrbuf* strbuf, const char* comp, char separator) {
return ffStrbufMatchSeparatedIgnCaseNS(strbuf, (uint32_t) strlen(comp), comp, separator);
}
-static inline bool ffStrbufMatchSeparatedIgnCase(const FFstrbuf* strbuf, const FFstrbuf* comp, char separator)
-{
+static inline bool ffStrbufMatchSeparatedIgnCase(const FFstrbuf* strbuf, const FFstrbuf* comp, char separator) {
return ffStrbufMatchSeparatedIgnCaseNS(strbuf, comp->length, comp->chars, separator);
}
-static inline bool ffStrbufSeparatedContainS(const FFstrbuf* strbuf, const char* comp, char separator)
-{
+static inline bool ffStrbufSeparatedContainS(const FFstrbuf* strbuf, const char* comp, char separator) {
return ffStrbufSeparatedContainNS(strbuf, (uint32_t) strlen(comp), comp, separator);
}
-static inline bool ffStrbufSeparatedContain(const FFstrbuf* strbuf, const FFstrbuf* comp, char separator)
-{
+static inline bool ffStrbufSeparatedContain(const FFstrbuf* strbuf, const FFstrbuf* comp, char separator) {
return ffStrbufSeparatedContainNS(strbuf, comp->length, comp->chars, separator);
}
-static inline bool ffStrbufSeparatedContainIgnCaseS(const FFstrbuf* strbuf, const char* comp, char separator)
-{
+static inline bool ffStrbufSeparatedContainIgnCaseS(const FFstrbuf* strbuf, const char* comp, char separator) {
return ffStrbufSeparatedContainIgnCaseNS(strbuf, (uint32_t) strlen(comp), comp, separator);
}
-static inline bool ffStrbufSeparatedContainIgnCase(const FFstrbuf* strbuf, const FFstrbuf* comp, char separator)
-{
+static inline bool ffStrbufSeparatedContainIgnCase(const FFstrbuf* strbuf, const FFstrbuf* comp, char separator) {
return ffStrbufSeparatedContainIgnCaseNS(strbuf, comp->length, comp->chars, separator);
}
// Returns true if the strbuf is modified
bool ffStrbufDecodeHexEscapeSequences(FFstrbuf* strbuf);
-#define FF_STRBUF_AUTO_DESTROY FFstrbuf __attribute__((__cleanup__(ffStrbufDestroy)))
+#define FF_STRBUF_AUTO_DESTROY FFstrbuf FF_A_CLEANUP(ffStrbufDestroy)
diff --git a/src/common/apple/cf_helpers.c b/src/common/apple/cf_helpers.c
index 8156d3779e..e080f4decb 100644
--- a/src/common/apple/cf_helpers.c
+++ b/src/common/apple/cf_helpers.c
@@ -1,184 +1,183 @@
#include "cf_helpers.h"
-const char* ffCfNumGetInt64(CFTypeRef cf, int64_t* result)
-{
- if(CFGetTypeID(cf) == CFNumberGetTypeID())
- {
- if(!CFNumberGetValue((CFNumberRef)cf, kCFNumberSInt64Type, result))
+const char* ffCfNumGetInt64(CFTypeRef cf, int64_t* result) {
+ if (CFGetTypeID(cf) == CFNumberGetTypeID()) {
+ if (!CFNumberGetValue((CFNumberRef) cf, kCFNumberSInt64Type, result)) {
return "Number type is not SInt64";
+ }
return NULL;
- }
- else if(CFGetTypeID(cf) == CFDataGetTypeID())
- {
- if(CFDataGetLength((CFDataRef)cf) != sizeof(int64_t))
+ } else if (CFGetTypeID(cf) == CFDataGetTypeID()) {
+ if (CFDataGetLength((CFDataRef) cf) != sizeof(int64_t)) {
return "Data length is not sizeof(int64_t)";
- CFDataGetBytes((CFDataRef)cf, CFRangeMake(0, sizeof(int64_t)), (uint8_t*)result);
+ }
+ CFDataGetBytes((CFDataRef) cf, CFRangeMake(0, sizeof(int64_t)), (uint8_t*) result);
return NULL;
}
return "TypeID is neither 'CFNumber' nor 'CFData'";
}
-const char* ffCfNumGetInt(CFTypeRef cf, int32_t* result)
-{
- if(CFGetTypeID(cf) == CFNumberGetTypeID())
- {
- if(!CFNumberGetValue((CFNumberRef)cf, kCFNumberSInt32Type, result))
+const char* ffCfNumGetInt(CFTypeRef cf, int32_t* result) {
+ if (CFGetTypeID(cf) == CFNumberGetTypeID()) {
+ if (!CFNumberGetValue((CFNumberRef) cf, kCFNumberSInt32Type, result)) {
return "Number type is not SInt32";
+ }
return NULL;
- }
- else if(CFGetTypeID(cf) == CFDataGetTypeID())
- {
- if(CFDataGetLength((CFDataRef)cf) != sizeof(int))
+ } else if (CFGetTypeID(cf) == CFDataGetTypeID()) {
+ if (CFDataGetLength((CFDataRef) cf) != sizeof(int)) {
return "Data length is not sizeof(int)";
- CFDataGetBytes((CFDataRef)cf, CFRangeMake(0, sizeof(int)), (uint8_t*)result);
+ }
+ CFDataGetBytes((CFDataRef) cf, CFRangeMake(0, sizeof(int)), (uint8_t*) result);
return NULL;
}
return "TypeID is neither 'CFNumber' nor 'CFData'";
}
-const char* ffCfStrGetString(CFTypeRef cf, FFstrbuf* result)
-{
+const char* ffCfStrGetString(CFTypeRef cf, FFstrbuf* result) {
ffStrbufClear(result);
- if (!cf)
+ if (!cf) {
return NULL;
+ }
- if (CFGetTypeID(cf) == CFStringGetTypeID())
- {
- CFStringRef cfStr = (CFStringRef)cf;
+ if (CFGetTypeID(cf) == CFStringGetTypeID()) {
+ CFStringRef cfStr = (CFStringRef) cf;
const char* cstr = CFStringGetCStringPtr(cfStr, kCFStringEncodingUTF8);
- if (cstr)
+ if (cstr) {
ffStrbufSetS(result, cstr);
- else
- {
+ } else {
uint32_t length = (uint32_t) CFStringGetLength(cfStr);
- if (length == 0)
+ if (length == 0) {
return NULL;
+ }
ffStrbufEnsureFixedLengthFree(result, (uint32_t) CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8));
- if(!CFStringGetCString(cfStr, result->chars, result->allocated, kCFStringEncodingUTF8))
+ if (!CFStringGetCString(cfStr, result->chars, result->allocated, kCFStringEncodingUTF8)) {
return "CFStringGetCString() failed";
+ }
// CFStringGetCString ensures the buffer is NUL terminated
// https://developer.apple.com/documentation/corefoundation/1542721-cfstringgetcstring
- result->length = (uint32_t) strnlen(result->chars, (uint32_t)result->allocated);
+ result->length = (uint32_t) strnlen(result->chars, (uint32_t) result->allocated);
}
- }
- else if (CFGetTypeID(cf) == CFDataGetTypeID())
- {
- CFDataRef cfData = (CFDataRef)cf;
- uint32_t length = (uint32_t)CFDataGetLength(cfData);
- if (length == 0)
+ } else if (CFGetTypeID(cf) == CFDataGetTypeID()) {
+ CFDataRef cfData = (CFDataRef) cf;
+ uint32_t length = (uint32_t) CFDataGetLength(cfData);
+ if (length == 0) {
return NULL;
+ }
ffStrbufEnsureFixedLengthFree(result, length + 1);
- CFDataGetBytes(cfData, CFRangeMake(0, length), (uint8_t*)result->chars);
- result->length = (uint32_t)strnlen(result->chars, length);
+ CFDataGetBytes(cfData, CFRangeMake(0, length), (uint8_t*) result->chars);
+ result->length = (uint32_t) strnlen(result->chars, length);
result->chars[result->length] = '\0';
- }
- else
+ } else {
return "TypeID is neither 'CFString' nor 'CFData'";
+ }
return NULL;
}
-const char* ffCfDataGetDataAsString(CFTypeRef cf, FFstrbuf* result)
-{
+const char* ffCfDataGetDataAsString(CFTypeRef cf, FFstrbuf* result) {
ffStrbufClear(result);
- if (!cf)
+ if (!cf) {
return NULL;
+ }
- if (CFGetTypeID(cf) == CFDataGetTypeID())
- {
- CFDataRef cfData = (CFDataRef)cf;
- uint32_t length = (uint32_t)CFDataGetLength(cfData);
- if (length == 0)
+ if (CFGetTypeID(cf) == CFDataGetTypeID()) {
+ CFDataRef cfData = (CFDataRef) cf;
+ uint32_t length = (uint32_t) CFDataGetLength(cfData);
+ if (length == 0) {
return NULL;
+ }
ffStrbufEnsureFixedLengthFree(result, length + 1);
- CFDataGetBytes(cfData, CFRangeMake(0, length), (uint8_t*)result->chars);
+ CFDataGetBytes(cfData, CFRangeMake(0, length), (uint8_t*) result->chars);
result->length = length;
result->chars[result->length] = '\0';
- }
- else
+ } else {
return "TypeID is not 'CFData'";
+ }
return NULL;
}
-const char* ffCfDictGetString(CFDictionaryRef dict, CFStringRef key, FFstrbuf* result)
-{
- CFTypeRef cf = (CFTypeRef)CFDictionaryGetValue(dict, key);
- if(cf == NULL)
+const char* ffCfDictGetString(CFDictionaryRef dict, CFStringRef key, FFstrbuf* result) {
+ CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
+ if (cf == NULL) {
return "CFDictionaryGetValue() failed";
+ }
return ffCfStrGetString(cf, result);
}
-const char* ffCfDictGetDataAsString(CFDictionaryRef dict, CFStringRef key, FFstrbuf* result)
-{
- CFTypeRef cf = (CFTypeRef)CFDictionaryGetValue(dict, key);
- if(cf == NULL)
+const char* ffCfDictGetDataAsString(CFDictionaryRef dict, CFStringRef key, FFstrbuf* result) {
+ CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
+ if (cf == NULL) {
return "CFDictionaryGetValue() failed";
+ }
return ffCfDataGetDataAsString(cf, result);
}
-const char* ffCfDictGetBool(CFDictionaryRef dict, CFStringRef key, bool* result)
-{
- CFBooleanRef cf = (CFBooleanRef)CFDictionaryGetValue(dict, key);
- if(cf == NULL)
+const char* ffCfDictGetBool(CFDictionaryRef dict, CFStringRef key, bool* result) {
+ CFBooleanRef cf = (CFBooleanRef) CFDictionaryGetValue(dict, key);
+ if (cf == NULL) {
return "CFDictionaryGetValue() failed";
+ }
- if(CFGetTypeID(cf) != CFBooleanGetTypeID())
+ if (CFGetTypeID(cf) != CFBooleanGetTypeID()) {
return "TypeID is not 'CFBoolean'";
+ }
*result = CFBooleanGetValue(cf);
return NULL;
}
-const char* ffCfDictGetInt(CFDictionaryRef dict, CFStringRef key, int* result)
-{
- CFTypeRef cf = (CFTypeRef)CFDictionaryGetValue(dict, key);
- if(cf == NULL)
+const char* ffCfDictGetInt(CFDictionaryRef dict, CFStringRef key, int* result) {
+ CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
+ if (cf == NULL) {
return "CFDictionaryGetValue() failed";
+ }
return ffCfNumGetInt(cf, result);
}
-const char* ffCfDictGetInt64(CFDictionaryRef dict, CFStringRef key, int64_t* result)
-{
- CFTypeRef cf = (CFTypeRef)CFDictionaryGetValue(dict, key);
- if(cf == NULL)
+const char* ffCfDictGetInt64(CFDictionaryRef dict, CFStringRef key, int64_t* result) {
+ CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
+ if (cf == NULL) {
return "CFDictionaryGetValue() failed";
+ }
return ffCfNumGetInt64(cf, result);
}
-const char* ffCfDictGetData(CFDictionaryRef dict, CFStringRef key, uint32_t offset, uint32_t size, uint8_t* result, uint32_t* length)
-{
- CFTypeRef cf = (CFTypeRef)CFDictionaryGetValue(dict, key);
- if(cf == NULL)
+const char* ffCfDictGetData(CFDictionaryRef dict, CFStringRef key, uint32_t offset, uint32_t size, uint8_t* result, uint32_t* length) {
+ CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
+ if (cf == NULL) {
return "CFDictionaryGetValue() failed";
+ }
- if(CFGetTypeID(cf) != CFDataGetTypeID())
+ if (CFGetTypeID(cf) != CFDataGetTypeID()) {
return "TypeID is not 'CFData'";
+ }
- CFIndex trueLength = CFDataGetLength((CFDataRef)cf);
+ CFIndex trueLength = CFDataGetLength((CFDataRef) cf);
- if(trueLength < offset + size)
+ if (trueLength < offset + size) {
return "Data length is less than offset + size";
+ }
- if(length)
+ if (length) {
*length = (uint32_t) trueLength;
+ }
- CFDataGetBytes((CFDataRef)cf, CFRangeMake(offset, size), result);
+ CFDataGetBytes((CFDataRef) cf, CFRangeMake(offset, size), result);
return NULL;
}
-const char* ffCfDictGetDict(CFDictionaryRef dict, CFStringRef key, CFDictionaryRef* result)
-{
- CFDictionaryRef cf = (CFDictionaryRef)CFDictionaryGetValue(dict, key);
- if (cf == NULL || CFGetTypeID(cf) != CFDictionaryGetTypeID())
+const char* ffCfDictGetDict(CFDictionaryRef dict, CFStringRef key, CFDictionaryRef* result) {
+ CFDictionaryRef cf = (CFDictionaryRef) CFDictionaryGetValue(dict, key);
+ if (cf == NULL || CFGetTypeID(cf) != CFDictionaryGetTypeID()) {
return "TypeID is not 'CFDictionary'";
+ }
*result = cf;
return NULL;
diff --git a/src/common/apple/cf_helpers.h b/src/common/apple/cf_helpers.h
index c41a397dcc..8ce58ccc30 100644
--- a/src/common/apple/cf_helpers.h
+++ b/src/common/apple/cf_helpers.h
@@ -4,7 +4,7 @@
#include
#include
-//Return error info if failed, NULL otherwise
+// Return error info if failed, NULL otherwise
const char* ffCfStrGetString(CFTypeRef cf, FFstrbuf* result);
const char* ffCfNumGetInt(CFTypeRef cf, int32_t* result);
const char* ffCfNumGetInt64(CFTypeRef cf, int64_t* result);
@@ -17,24 +17,23 @@ const char* ffCfDictGetData(CFDictionaryRef dict, CFStringRef key, uint32_t offs
const char* ffCfDictGetDataAsString(CFDictionaryRef dict, CFStringRef key, FFstrbuf* result);
const char* ffCfDictGetDict(CFDictionaryRef dict, CFStringRef key, CFDictionaryRef* result);
-static inline CFNumberRef ffCfCreateInt(int value)
-{
+static inline CFNumberRef ffCfCreateInt(int value) {
return CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &value);
}
-static inline void cfReleaseWrapper(void* type)
-{
+static inline void cfReleaseWrapper(void* type) {
assert(type);
- if (*(CFTypeRef*) type)
+ if (*(CFTypeRef*) type) {
CFRelease(*(CFTypeRef*) type);
+ }
}
-#define FF_CFTYPE_AUTO_RELEASE __attribute__((__cleanup__(cfReleaseWrapper)))
+#define FF_CFTYPE_AUTO_RELEASE FF_A_CLEANUP(cfReleaseWrapper)
-static inline void wrapIoObjectRelease(io_object_t* service)
-{
+static inline void wrapIoObjectRelease(io_object_t* service) {
assert(service);
- if (*service)
+ if (*service) {
IOObjectRelease(*service);
+ }
}
-#define FF_IOOBJECT_AUTO_RELEASE __attribute__((__cleanup__(wrapIoObjectRelease)))
+#define FF_IOOBJECT_AUTO_RELEASE FF_A_CLEANUP(wrapIoObjectRelease)
diff --git a/src/common/apple/smc_temps.c b/src/common/apple/smc_temps.c
index 0a31a50527..07b2d3bc95 100644
--- a/src/common/apple/smc_temps.c
+++ b/src/common/apple/smc_temps.c
@@ -60,66 +60,64 @@ typedef struct
SmcBytes_t bytes;
} SmcVal_t;
-static uint32_t smcStrtoul(const char *str, int size, int base)
-{
+static uint32_t smcStrtoul(const char* str, int size, int base) {
uint32_t total = 0;
- for (int i = 0; i < size; i++)
- {
- if (base == 16)
- total += (uint32_t)(str[i] << (size - 1 - i) * 8);
- else
- total += (uint32_t)((unsigned char)(str[i]) << (size - 1 - i) * 8);
+ for (int i = 0; i < size; i++) {
+ if (base == 16) {
+ total += (uint32_t) (str[i] << (size - 1 - i) * 8);
+ } else {
+ total += (uint32_t) ((unsigned char) (str[i]) << (size - 1 - i) * 8);
+ }
}
return total;
}
-static void smcUltostr(char *str, uint32_t val)
-{
- str[0] = (char)(val >> 24);
- str[1] = (char)(val >> 16);
- str[2] = (char)(val >> 8);
- str[3] = (char)val;
+static void smcUltostr(char* str, uint32_t val) {
+ str[0] = (char) (val >> 24);
+ str[1] = (char) (val >> 16);
+ str[2] = (char) (val >> 8);
+ str[3] = (char) val;
str[4] = '\0';
}
-static const char *smcCall(io_connect_t conn, uint32_t selector, SmcKeyData_t *inputStructure, SmcKeyData_t *outputStructure)
-{
+static const char* smcCall(io_connect_t conn, uint32_t selector, SmcKeyData_t* inputStructure, SmcKeyData_t* outputStructure) {
size_t size = sizeof(SmcKeyData_t);
- if (IOConnectCallStructMethod(conn, selector, inputStructure, size, outputStructure, &size) != kIOReturnSuccess)
+ if (IOConnectCallStructMethod(conn, selector, inputStructure, size, outputStructure, &size) != kIOReturnSuccess) {
return "IOConnectCallStructMethod(conn) failed";
+ }
return NULL;
}
// Provides key info, using a cache to dramatically improve the energy impact of smcFanControl
-static const char *smcGetKeyInfo(io_connect_t conn, const uint32_t key, SmcKeyData_keyInfo_t *key_info)
-{
- SmcKeyData_t inputStructure = {0};
- SmcKeyData_t outputStructure = {0};
+static const char* smcGetKeyInfo(io_connect_t conn, const uint32_t key, SmcKeyData_keyInfo_t* key_info) {
+ SmcKeyData_t inputStructure = { 0 };
+ SmcKeyData_t outputStructure = { 0 };
inputStructure.key = key;
inputStructure.data8 = kSmcCmdReadKeyInfo;
- const char *error = smcCall(conn, kKernelIndexSmc, &inputStructure, &outputStructure);
- if (error)
+ const char* error = smcCall(conn, kKernelIndexSmc, &inputStructure, &outputStructure);
+ if (error) {
return error;
+ }
*key_info = outputStructure.keyInfo;
return NULL;
}
-static const char *smcReadSmcVal(io_connect_t conn, const UInt32Char_t key, SmcVal_t *val)
-{
- SmcKeyData_t inputStructure = {0};
- SmcKeyData_t outputStructure = {0};
+static const char* smcReadSmcVal(io_connect_t conn, const UInt32Char_t key, SmcVal_t* val) {
+ SmcKeyData_t inputStructure = { 0 };
+ SmcKeyData_t outputStructure = { 0 };
inputStructure.key = smcStrtoul(key, 4, 16);
strcpy(val->key, key);
- const char *error = smcGetKeyInfo(conn, inputStructure.key, &outputStructure.keyInfo);
- if (error)
+ const char* error = smcGetKeyInfo(conn, inputStructure.key, &outputStructure.keyInfo);
+ if (error) {
return error;
+ }
val->dataSize = outputStructure.keyInfo.dataSize;
smcUltostr(val->dataType, outputStructure.keyInfo.dataType);
@@ -127,132 +125,147 @@ static const char *smcReadSmcVal(io_connect_t conn, const UInt32Char_t key, SmcV
inputStructure.data8 = kSmcCmdReadBytes;
error = smcCall(conn, kKernelIndexSmc, &inputStructure, &outputStructure);
- if (error)
+ if (error) {
return error;
+ }
memcpy(val->bytes, outputStructure.bytes, sizeof(outputStructure.bytes));
return NULL;
}
-static const char *smcOpen(io_connect_t *conn)
-{
+static const char* smcOpen(io_connect_t* conn) {
FF_IOOBJECT_AUTO_RELEASE io_object_t device = IOServiceGetMatchingService(MACH_PORT_NULL, IOServiceMatching("AppleSMC"));
- if (!device)
+ if (!device) {
return "No SMC device found";
+ }
- if (IOServiceOpen(device, mach_task_self(), 0, conn) != kIOReturnSuccess)
+ if (IOServiceOpen(device, mach_task_self(), 0, conn) != kIOReturnSuccess) {
return "IOServiceOpen() failed";
+ }
return NULL;
}
-static const char *smcReadValue(io_connect_t conn, const UInt32Char_t key, double *value)
-{
- SmcVal_t val = {0};
+static const char* smcReadValue(io_connect_t conn, const UInt32Char_t key, double* value) {
+ SmcVal_t val = { 0 };
const char* error = smcReadSmcVal(conn, key, &val);
- if (error != NULL)
+ if (error != NULL) {
return error;
- if (val.dataSize == 0)
+ }
+ if (val.dataSize == 0) {
return "Empty SMC result";
+ }
- switch (val.dataType[0])
- {
+ switch (val.dataType[0]) {
case 'u': // unsigned integer types
- if (val.dataType[1] == 'i')
- {
- switch (val.dataSize)
- {
- case 1: *value = *(uint8_t *)(val.bytes); break;
- case 2: *value = ntohs(*(uint16_t *)(val.bytes)); break;
- case 4: *value = ntohl(*(uint32_t *)(val.bytes)); break;
- case 8: *value = (double) ntohll(*(uint64_t *)(val.bytes)); break;
+ if (val.dataType[1] == 'i') {
+ switch (val.dataSize) {
+ case 1:
+ *value = *(uint8_t*) (val.bytes);
+ break;
+ case 2:
+ *value = ntohs(*(uint16_t*) (val.bytes));
+ break;
+ case 4:
+ *value = ntohl(*(uint32_t*) (val.bytes));
+ break;
+ case 8:
+ *value = (double) ntohll(*(uint64_t*) (val.bytes));
+ break;
default:
return "Unsupported SMC unsigned integer data size";
}
- }
- else
+ } else {
return "Unsupported SMC unsigned data type";
+ }
break;
case 'f': // floating point types
- if (ffStrEquals(val.dataType, "flt ") && val.dataSize == 4)
- *value = *(float *)(val.bytes);
- else if (val.dataType[1] == 'p' && val.dataSize == 2) // fixed point types
+ if (ffStrEquals(val.dataType, "flt ") && val.dataSize == 4) {
+ *value = *(float*) (val.bytes);
+ } else if (val.dataType[1] == 'p' && val.dataSize == 2) // fixed point types
{
- if (ffStrEquals(val.dataType, "fp1f"))
- *value = ntohs(*(uint16_t *)(val.bytes)) / 32768.0;
- else if (ffStrEquals(val.dataType, "fp4c"))
- *value = ntohs(*(uint16_t *)(val.bytes)) / 4096.0;
- else if (ffStrEquals(val.dataType, "fp5b"))
- *value = ntohs(*(uint16_t *)(val.bytes)) / 2048.0;
- else if (ffStrEquals(val.dataType, "fp6a"))
- *value = ntohs(*(uint16_t *)(val.bytes)) / 1024.0;
- else if (ffStrEquals(val.dataType, "fp79"))
- *value = ntohs(*(uint16_t *)(val.bytes)) / 512.0;
- else if (ffStrEquals(val.dataType, "fp88"))
- *value = ntohs(*(uint16_t *)(val.bytes)) / 256.0;
- else if (ffStrEquals(val.dataType, "fpa6"))
- *value = ntohs(*(uint16_t *)(val.bytes)) / 64.0;
- else if (ffStrEquals(val.dataType, "fpc4"))
- *value = ntohs(*(uint16_t *)(val.bytes)) / 16.0;
- else if (ffStrEquals(val.dataType, "fpe2"))
- *value = ntohs(*(uint16_t *)(val.bytes)) / 4.0;
- else
+ if (ffStrEquals(val.dataType, "fp1f")) {
+ *value = ntohs(*(uint16_t*) (val.bytes)) / 32768.0;
+ } else if (ffStrEquals(val.dataType, "fp4c")) {
+ *value = ntohs(*(uint16_t*) (val.bytes)) / 4096.0;
+ } else if (ffStrEquals(val.dataType, "fp5b")) {
+ *value = ntohs(*(uint16_t*) (val.bytes)) / 2048.0;
+ } else if (ffStrEquals(val.dataType, "fp6a")) {
+ *value = ntohs(*(uint16_t*) (val.bytes)) / 1024.0;
+ } else if (ffStrEquals(val.dataType, "fp79")) {
+ *value = ntohs(*(uint16_t*) (val.bytes)) / 512.0;
+ } else if (ffStrEquals(val.dataType, "fp88")) {
+ *value = ntohs(*(uint16_t*) (val.bytes)) / 256.0;
+ } else if (ffStrEquals(val.dataType, "fpa6")) {
+ *value = ntohs(*(uint16_t*) (val.bytes)) / 64.0;
+ } else if (ffStrEquals(val.dataType, "fpc4")) {
+ *value = ntohs(*(uint16_t*) (val.bytes)) / 16.0;
+ } else if (ffStrEquals(val.dataType, "fpe2")) {
+ *value = ntohs(*(uint16_t*) (val.bytes)) / 4.0;
+ } else {
return "Unsupported SMC floating point data type";
- }
- else
+ }
+ } else {
return "Unsupported SMC floating point data type";
+ }
break;
case 's': // signed integer types
- if (val.dataType[1] == 'i')
- {
- switch (val.dataSize)
- {
- case 1: *value = *(int8_t *)(val.bytes); break;
- case 2: *value = ntohs(*(int16_t *)(val.bytes)); break;
- case 4: *value = ntohl(*(int32_t *)(val.bytes)); break;
- case 8: *value = (double)ntohll(*(int64_t *)(val.bytes)); break;
- default: return "Unsupported SMC signed integer data size";
+ if (val.dataType[1] == 'i') {
+ switch (val.dataSize) {
+ case 1:
+ *value = *(int8_t*) (val.bytes);
+ break;
+ case 2:
+ *value = ntohs(*(int16_t*) (val.bytes));
+ break;
+ case 4:
+ *value = ntohl(*(int32_t*) (val.bytes));
+ break;
+ case 8:
+ *value = (double) ntohll(*(int64_t*) (val.bytes));
+ break;
+ default:
+ return "Unsupported SMC signed integer data size";
}
- }
- else if (val.dataType[1] == 'p' && val.dataSize == 2) // signed fixed point types
+ } else if (val.dataType[1] == 'p' && val.dataSize == 2) // signed fixed point types
{
- if (ffStrEquals(val.dataType, "sp1e"))
- *value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 16384.0;
- else if (ffStrEquals(val.dataType, "sp3c"))
- *value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 4096.0;
- else if (ffStrEquals(val.dataType, "sp4b"))
- *value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 2048.0;
- else if (ffStrEquals(val.dataType, "sp5a"))
- *value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 1024.0;
- else if (ffStrEquals(val.dataType, "sp69"))
- *value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 512.0;
- else if (ffStrEquals(val.dataType, "sp78"))
- *value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 256.0;
- else if (ffStrEquals(val.dataType, "sp87"))
- *value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 128.0;
- else if (ffStrEquals(val.dataType, "sp96"))
- *value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 64.0;
- else if (ffStrEquals(val.dataType, "spb4"))
- *value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 16.0;
- else if (ffStrEquals(val.dataType, "spf0"))
- *value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 1.0;
- else
+ if (ffStrEquals(val.dataType, "sp1e")) {
+ *value = (int16_t) ntohs(*(int16_t*) (val.bytes)) / 16384.0;
+ } else if (ffStrEquals(val.dataType, "sp3c")) {
+ *value = (int16_t) ntohs(*(int16_t*) (val.bytes)) / 4096.0;
+ } else if (ffStrEquals(val.dataType, "sp4b")) {
+ *value = (int16_t) ntohs(*(int16_t*) (val.bytes)) / 2048.0;
+ } else if (ffStrEquals(val.dataType, "sp5a")) {
+ *value = (int16_t) ntohs(*(int16_t*) (val.bytes)) / 1024.0;
+ } else if (ffStrEquals(val.dataType, "sp69")) {
+ *value = (int16_t) ntohs(*(int16_t*) (val.bytes)) / 512.0;
+ } else if (ffStrEquals(val.dataType, "sp78")) {
+ *value = (int16_t) ntohs(*(int16_t*) (val.bytes)) / 256.0;
+ } else if (ffStrEquals(val.dataType, "sp87")) {
+ *value = (int16_t) ntohs(*(int16_t*) (val.bytes)) / 128.0;
+ } else if (ffStrEquals(val.dataType, "sp96")) {
+ *value = (int16_t) ntohs(*(int16_t*) (val.bytes)) / 64.0;
+ } else if (ffStrEquals(val.dataType, "spb4")) {
+ *value = (int16_t) ntohs(*(int16_t*) (val.bytes)) / 16.0;
+ } else if (ffStrEquals(val.dataType, "spf0")) {
+ *value = (int16_t) ntohs(*(int16_t*) (val.bytes)) / 1.0;
+ } else {
return "Unsupported SMC signed integer data type";
- }
- else
+ }
+ } else {
return "Unsupported SMC signed data type";
+ }
break;
case '{': // special types like pwm
- if (ffStrEquals(val.dataType, "{pwm") && val.dataSize == 2)
- {
- *value = (double)ntohs(*(uint16_t *)(val.bytes)) * 100 / 65536.0;
- }
- else
+ if (ffStrEquals(val.dataType, "{pwm") && val.dataSize == 2) {
+ *value = (double) ntohs(*(uint16_t*) (val.bytes)) * 100 / 65536.0;
+ } else {
return "Unsupported SMC special data type";
+ }
break;
default:
@@ -261,187 +274,191 @@ static const char *smcReadValue(io_connect_t conn, const UInt32Char_t key, doubl
return NULL;
}
-static bool detectTemp(io_connect_t conn, const char* sensor, double* sum)
-{
+static bool detectTemp(io_connect_t conn, const char* sensor, double* sum) {
double temp = 0;
const char* error = smcReadValue(conn, sensor, &temp);
- if (error) return false;
+ if (error) {
+ return false;
+ }
// https://github.com/exelban/stats/blob/14e29c4d60229c363cca9c9d25c30c87b7870830/Modules/Sensors/readers.swift#L124
- if (temp < 10 || temp > 120) return false;
+ if (temp < 10 || temp > 120) {
+ return false;
+ }
*sum += temp;
return true;
}
static io_connect_t conn;
-const char* ffDetectSmcSpecificTemp(const char* sensor, double* result)
-{
- if (!conn)
- {
- if (smcOpen(&conn) != NULL)
+const char* ffDetectSmcSpecificTemp(const char* sensor, double* result) {
+ if (!conn) {
+ if (smcOpen(&conn) != NULL) {
conn = (io_connect_t) -1;
+ }
}
- if (conn == (io_connect_t) -1)
+ if (conn == (io_connect_t) -1) {
return "Could not open SMC connection";
+ }
- if (!detectTemp(conn, sensor, result))
+ if (!detectTemp(conn, sensor, result)) {
return "Could not read SMC temperature";
+ }
return NULL;
}
-const char* ffDetectSmcTemps(enum FFTempType type, double* result)
-{
- if (!conn)
- {
- if (smcOpen(&conn) != NULL)
+const char* ffDetectSmcTemps(enum FFTempType type, double* result) {
+ if (!conn) {
+ if (smcOpen(&conn) != NULL) {
conn = (io_connect_t) -1;
+ }
}
- if (conn == (io_connect_t) -1)
+ if (conn == (io_connect_t) -1) {
return "Could not open SMC connection";
+ }
uint32_t count = 0;
*result = 0;
// https://github.com/exelban/stats/blob/master/Modules/Sensors/values.swift
- switch (type)
- {
- case FF_TEMP_CPU_X64:
- count += detectTemp(conn, "TC0D", result); // CPU diode
- count += detectTemp(conn, "TC0E", result); // CPU diode virtual
- count += detectTemp(conn, "TC0F", result); // CPU diode filtered
- count += detectTemp(conn, "TC0P", result); // CPU proximity
- break;
-
- case FF_TEMP_CPU_M1X:
- count += detectTemp(conn, "Tp09", result); // CPU efficient core 1
- count += detectTemp(conn, "Tp0T", result); // CPU efficient core 2
-
- count += detectTemp(conn, "Tp01", result); // CPU performance core 1
- count += detectTemp(conn, "Tp05", result); // CPU performance core 2
- count += detectTemp(conn, "Tp0D", result); // CPU performance core 3
- count += detectTemp(conn, "Tp0H", result); // CPU performance core 4
- count += detectTemp(conn, "Tp0L", result); // CPU performance core 5
- count += detectTemp(conn, "Tp0P", result); // CPU performance core 6
- count += detectTemp(conn, "Tp0X", result); // CPU performance core 7
- count += detectTemp(conn, "Tp0b", result); // CPU performance core 8
- break;
-
- case FF_TEMP_CPU_M2X:
- count += detectTemp(conn, "Tp1h", result); // CPU efficiency core 1
- count += detectTemp(conn, "Tp1t", result); // CPU efficiency core 2
- count += detectTemp(conn, "Tp1p", result); // CPU efficiency core 3
- count += detectTemp(conn, "Tp1l", result); // CPU efficiency core 4
-
- count += detectTemp(conn, "Tp01", result); // CPU performance core 1
- count += detectTemp(conn, "Tp05", result); // CPU performance core 2
- count += detectTemp(conn, "Tp09", result); // CPU performance core 3
- count += detectTemp(conn, "Tp0D", result); // CPU performance core 4
- count += detectTemp(conn, "Tp0X", result); // CPU performance core 5
- count += detectTemp(conn, "Tp0b", result); // CPU performance core 6
- count += detectTemp(conn, "Tp0f", result); // CPU performance core 7
- count += detectTemp(conn, "Tp0j", result); // CPU performance core 8
- break;
-
- case FF_TEMP_CPU_M3X:
- count += detectTemp(conn, "Te05", result); // CPU efficiency core 1
- count += detectTemp(conn, "Te0L", result); // CPU efficiency core 2
- count += detectTemp(conn, "Te0P", result); // CPU efficiency core 3
- count += detectTemp(conn, "Te0S", result); // CPU efficiency core 4
- count += detectTemp(conn, "Tf04", result); // CPU performance core 1
- count += detectTemp(conn, "Tf09", result); // CPU performance core 2
- count += detectTemp(conn, "Tf0A", result); // CPU performance core 3
- count += detectTemp(conn, "Tf0B", result); // CPU performance core 4
- count += detectTemp(conn, "Tf0D", result); // CPU performance core 5
- count += detectTemp(conn, "Tf0E", result); // CPU performance core 6
- count += detectTemp(conn, "Tf44", result); // CPU performance core 7
- count += detectTemp(conn, "Tf49", result); // CPU performance core 8
- count += detectTemp(conn, "Tf4A", result); // CPU performance core 9
- count += detectTemp(conn, "Tf4B", result); // CPU performance core 10
- count += detectTemp(conn, "Tf4D", result); // CPU performance core 11
- count += detectTemp(conn, "Tf4E", result); // CPU performance core 12
- break;
-
- case FF_TEMP_CPU_M4X:
- count += detectTemp(conn, "Te05", result); // CPU efficiency core 1
- count += detectTemp(conn, "Te0S", result); // CPU efficiency core 2
- count += detectTemp(conn, "Te09", result); // CPU efficiency core 3
- count += detectTemp(conn, "Te0H", result); // CPU efficiency core 4
- count += detectTemp(conn, "Tp01", result); // CPU performance core 1
- count += detectTemp(conn, "Tp05", result); // CPU performance core 2
- count += detectTemp(conn, "Tp09", result); // CPU performance core 3
- count += detectTemp(conn, "Tp0D", result); // CPU performance core 4
- count += detectTemp(conn, "Tp0V", result); // CPU performance core 5
- count += detectTemp(conn, "Tp0Y", result); // CPU performance core 6
- count += detectTemp(conn, "Tp0b", result); // CPU performance core 7
- count += detectTemp(conn, "Tp0e", result); // CPU performance core 8
- break;
-
- case FF_TEMP_GPU_INTEL:
- count += detectTemp(conn, "TCGC", result); // GPU Intel Graphics
- goto gpu_unknown;
-
- case FF_TEMP_GPU_AMD:
- count += detectTemp(conn, "TGDD", result); // GPU AMD Radeon
- goto gpu_unknown;
-
- case FF_TEMP_GPU_UNKNOWN: // Nvidia?
- gpu_unknown:
- count += detectTemp(conn, "TG0D", result); // GPU diode
- count += detectTemp(conn, "TG0P", result); // GPU proximity
- break;
-
- case FF_TEMP_GPU_M1X:
- count += detectTemp(conn, "Tg05", result); // GPU 1
- count += detectTemp(conn, "Tg0D", result); // GPU 2
- count += detectTemp(conn, "Tg0L", result); // GPU 3
- count += detectTemp(conn, "Tg0T", result); // GPU 4
- break;
-
- case FF_TEMP_GPU_M2X:
- count += detectTemp(conn, "Tg0f", result); // GPU 1
- count += detectTemp(conn, "Tg0j", result); // GPU 2
- break;
-
- case FF_TEMP_GPU_M3X:
- count += detectTemp(conn, "Tf14", result); // GPU 1
- count += detectTemp(conn, "Tf18", result); // GPU 2
- count += detectTemp(conn, "Tf19", result); // GPU 3
- count += detectTemp(conn, "Tf1A", result); // GPU 4
- count += detectTemp(conn, "Tf24", result); // GPU 5
- count += detectTemp(conn, "Tf28", result); // GPU 6
- count += detectTemp(conn, "Tf29", result); // GPU 7
- count += detectTemp(conn, "Tf2A", result); // GPU 8
- break;
-
- case FF_TEMP_GPU_M4X:
- count += detectTemp(conn, "Tg0G", result); // GPU 1 (Basic)
- count += detectTemp(conn, "Tg0H", result); // GPU 2 (Basic)
- count += detectTemp(conn, "Tg1U", result); // GPU 1 (Pro / Max)
- count += detectTemp(conn, "Tg1k", result); // GPU 2 (Pro / Max)
- count += detectTemp(conn, "Tg0K", result); // GPU 3
- count += detectTemp(conn, "Tg0L", result); // GPU 4
- count += detectTemp(conn, "Tg0d", result); // GPU 5
- count += detectTemp(conn, "Tg0e", result); // GPU 6
- count += detectTemp(conn, "Tg0j", result); // GPU 7
- count += detectTemp(conn, "Tg0k", result); // GPU 8
- break;
-
- case FF_TEMP_BATTERY:
- count += detectTemp(conn, "TB1T", result); // Battery
- count += detectTemp(conn, "TB2T", result); // Battery
- break;
-
- case FF_TEMP_MEMORY:
- count += detectTemp(conn, "Tm02", result); // Memory 1
- count += detectTemp(conn, "Tm06", result); // Memory 2
- count += detectTemp(conn, "Tm08", result); // Memory 3
- count += detectTemp(conn, "Tm09", result); // Memory 4
- break;
+ switch (type) {
+ case FF_TEMP_CPU_X64:
+ count += detectTemp(conn, "TC0D", result); // CPU diode
+ count += detectTemp(conn, "TC0E", result); // CPU diode virtual
+ count += detectTemp(conn, "TC0F", result); // CPU diode filtered
+ count += detectTemp(conn, "TC0P", result); // CPU proximity
+ break;
+
+ case FF_TEMP_CPU_M1X:
+ count += detectTemp(conn, "Tp09", result); // CPU efficient core 1
+ count += detectTemp(conn, "Tp0T", result); // CPU efficient core 2
+
+ count += detectTemp(conn, "Tp01", result); // CPU performance core 1
+ count += detectTemp(conn, "Tp05", result); // CPU performance core 2
+ count += detectTemp(conn, "Tp0D", result); // CPU performance core 3
+ count += detectTemp(conn, "Tp0H", result); // CPU performance core 4
+ count += detectTemp(conn, "Tp0L", result); // CPU performance core 5
+ count += detectTemp(conn, "Tp0P", result); // CPU performance core 6
+ count += detectTemp(conn, "Tp0X", result); // CPU performance core 7
+ count += detectTemp(conn, "Tp0b", result); // CPU performance core 8
+ break;
+
+ case FF_TEMP_CPU_M2X:
+ count += detectTemp(conn, "Tp1h", result); // CPU efficiency core 1
+ count += detectTemp(conn, "Tp1t", result); // CPU efficiency core 2
+ count += detectTemp(conn, "Tp1p", result); // CPU efficiency core 3
+ count += detectTemp(conn, "Tp1l", result); // CPU efficiency core 4
+
+ count += detectTemp(conn, "Tp01", result); // CPU performance core 1
+ count += detectTemp(conn, "Tp05", result); // CPU performance core 2
+ count += detectTemp(conn, "Tp09", result); // CPU performance core 3
+ count += detectTemp(conn, "Tp0D", result); // CPU performance core 4
+ count += detectTemp(conn, "Tp0X", result); // CPU performance core 5
+ count += detectTemp(conn, "Tp0b", result); // CPU performance core 6
+ count += detectTemp(conn, "Tp0f", result); // CPU performance core 7
+ count += detectTemp(conn, "Tp0j", result); // CPU performance core 8
+ break;
+
+ case FF_TEMP_CPU_M3X:
+ count += detectTemp(conn, "Te05", result); // CPU efficiency core 1
+ count += detectTemp(conn, "Te0L", result); // CPU efficiency core 2
+ count += detectTemp(conn, "Te0P", result); // CPU efficiency core 3
+ count += detectTemp(conn, "Te0S", result); // CPU efficiency core 4
+ count += detectTemp(conn, "Tf04", result); // CPU performance core 1
+ count += detectTemp(conn, "Tf09", result); // CPU performance core 2
+ count += detectTemp(conn, "Tf0A", result); // CPU performance core 3
+ count += detectTemp(conn, "Tf0B", result); // CPU performance core 4
+ count += detectTemp(conn, "Tf0D", result); // CPU performance core 5
+ count += detectTemp(conn, "Tf0E", result); // CPU performance core 6
+ count += detectTemp(conn, "Tf44", result); // CPU performance core 7
+ count += detectTemp(conn, "Tf49", result); // CPU performance core 8
+ count += detectTemp(conn, "Tf4A", result); // CPU performance core 9
+ count += detectTemp(conn, "Tf4B", result); // CPU performance core 10
+ count += detectTemp(conn, "Tf4D", result); // CPU performance core 11
+ count += detectTemp(conn, "Tf4E", result); // CPU performance core 12
+ break;
+
+ case FF_TEMP_CPU_M4X:
+ count += detectTemp(conn, "Te05", result); // CPU efficiency core 1
+ count += detectTemp(conn, "Te0S", result); // CPU efficiency core 2
+ count += detectTemp(conn, "Te09", result); // CPU efficiency core 3
+ count += detectTemp(conn, "Te0H", result); // CPU efficiency core 4
+ count += detectTemp(conn, "Tp01", result); // CPU performance core 1
+ count += detectTemp(conn, "Tp05", result); // CPU performance core 2
+ count += detectTemp(conn, "Tp09", result); // CPU performance core 3
+ count += detectTemp(conn, "Tp0D", result); // CPU performance core 4
+ count += detectTemp(conn, "Tp0V", result); // CPU performance core 5
+ count += detectTemp(conn, "Tp0Y", result); // CPU performance core 6
+ count += detectTemp(conn, "Tp0b", result); // CPU performance core 7
+ count += detectTemp(conn, "Tp0e", result); // CPU performance core 8
+ break;
+
+ case FF_TEMP_GPU_INTEL:
+ count += detectTemp(conn, "TCGC", result); // GPU Intel Graphics
+ goto gpu_unknown;
+
+ case FF_TEMP_GPU_AMD:
+ count += detectTemp(conn, "TGDD", result); // GPU AMD Radeon
+ goto gpu_unknown;
+
+ case FF_TEMP_GPU_UNKNOWN: // Nvidia?
+ gpu_unknown:
+ count += detectTemp(conn, "TG0D", result); // GPU diode
+ count += detectTemp(conn, "TG0P", result); // GPU proximity
+ break;
+
+ case FF_TEMP_GPU_M1X:
+ count += detectTemp(conn, "Tg05", result); // GPU 1
+ count += detectTemp(conn, "Tg0D", result); // GPU 2
+ count += detectTemp(conn, "Tg0L", result); // GPU 3
+ count += detectTemp(conn, "Tg0T", result); // GPU 4
+ break;
+
+ case FF_TEMP_GPU_M2X:
+ count += detectTemp(conn, "Tg0f", result); // GPU 1
+ count += detectTemp(conn, "Tg0j", result); // GPU 2
+ break;
+
+ case FF_TEMP_GPU_M3X:
+ count += detectTemp(conn, "Tf14", result); // GPU 1
+ count += detectTemp(conn, "Tf18", result); // GPU 2
+ count += detectTemp(conn, "Tf19", result); // GPU 3
+ count += detectTemp(conn, "Tf1A", result); // GPU 4
+ count += detectTemp(conn, "Tf24", result); // GPU 5
+ count += detectTemp(conn, "Tf28", result); // GPU 6
+ count += detectTemp(conn, "Tf29", result); // GPU 7
+ count += detectTemp(conn, "Tf2A", result); // GPU 8
+ break;
+
+ case FF_TEMP_GPU_M4X:
+ count += detectTemp(conn, "Tg0G", result); // GPU 1 (Basic)
+ count += detectTemp(conn, "Tg0H", result); // GPU 2 (Basic)
+ count += detectTemp(conn, "Tg1U", result); // GPU 1 (Pro / Max)
+ count += detectTemp(conn, "Tg1k", result); // GPU 2 (Pro / Max)
+ count += detectTemp(conn, "Tg0K", result); // GPU 3
+ count += detectTemp(conn, "Tg0L", result); // GPU 4
+ count += detectTemp(conn, "Tg0d", result); // GPU 5
+ count += detectTemp(conn, "Tg0e", result); // GPU 6
+ count += detectTemp(conn, "Tg0j", result); // GPU 7
+ count += detectTemp(conn, "Tg0k", result); // GPU 8
+ break;
+
+ case FF_TEMP_BATTERY:
+ count += detectTemp(conn, "TB1T", result); // Battery
+ count += detectTemp(conn, "TB2T", result); // Battery
+ break;
+
+ case FF_TEMP_MEMORY:
+ count += detectTemp(conn, "Tm02", result); // Memory 1
+ count += detectTemp(conn, "Tm06", result); // Memory 2
+ count += detectTemp(conn, "Tm08", result); // Memory 3
+ count += detectTemp(conn, "Tm09", result); // Memory 4
+ break;
}
- if (count == 0)
+ if (count == 0) {
return "No temperatures detected";
+ }
*result /= count;
diff --git a/src/common/apple/smc_temps.h b/src/common/apple/smc_temps.h
index 031f7c2e1f..6783bb95b9 100644
--- a/src/common/apple/smc_temps.h
+++ b/src/common/apple/smc_temps.h
@@ -2,15 +2,13 @@
#include "fastfetch.h"
-typedef struct FFTempValue
-{
+typedef struct FFTempValue {
FFstrbuf name;
FFstrbuf deviceClass;
double value;
} FFTempValue;
-enum FFTempType
-{
+enum FFTempType {
FF_TEMP_CPU_X64,
FF_TEMP_CPU_M1X,
FF_TEMP_CPU_M2X,
diff --git a/src/common/argType.h b/src/common/argType.h
index 481f9d225a..81217c7f94 100644
--- a/src/common/argType.h
+++ b/src/common/argType.h
@@ -5,14 +5,12 @@
// For ffRegReadValue(s)
// If length is 0, data will be allocated with malloc() and must be freed by the caller
// Otherwise, data must point to a buffer of at least length bytes, and the actual length of the data will be written to length.
-typedef struct FFArgBuffer
-{
+typedef struct FFArgBuffer {
void* data;
uint32_t length;
} FFArgBuffer;
-typedef enum __attribute__((__packed__)) FFArgType
-{
+typedef enum FF_A_PACKED FFArgType {
FF_ARG_TYPE_NULL = 0,
FF_ARG_TYPE_UINT,
FF_ARG_TYPE_UINT64,
@@ -28,18 +26,19 @@ typedef enum __attribute__((__packed__)) FFArgType
FF_ARG_TYPE_BUFFER,
} FFArgType;
-#define FF_ARG(variable, var_name) { _Generic((variable), \
- uint32_t: FF_ARG_TYPE_UINT, \
- uint64_t: FF_ARG_TYPE_UINT64, \
- uint16_t: FF_ARG_TYPE_UINT16, \
- uint8_t: FF_ARG_TYPE_UINT8, \
- int32_t: FF_ARG_TYPE_INT, \
- char*: FF_ARG_TYPE_STRING, \
- const char*: FF_ARG_TYPE_STRING, \
- FFstrbuf: FF_ARG_TYPE_STRBUF, \
- float: FF_ARG_TYPE_FLOAT, \
- double: FF_ARG_TYPE_DOUBLE, \
- FFlist: FF_ARG_TYPE_LIST, \
- bool: FF_ARG_TYPE_BOOL, \
- FFArgBuffer: FF_ARG_TYPE_BUFFER \
- ), _Generic((variable), char*: (variable), const char*: (variable), default: &(variable) ), (var_name) }
+#define FF_ARG(variable, var_name) { _Generic((variable), \
+ uint32_t: FF_ARG_TYPE_UINT, \
+ uint64_t: FF_ARG_TYPE_UINT64, \
+ uint16_t: FF_ARG_TYPE_UINT16, \
+ uint8_t: FF_ARG_TYPE_UINT8, \
+ int32_t: FF_ARG_TYPE_INT, \
+ char*: FF_ARG_TYPE_STRING, \
+ const char*: FF_ARG_TYPE_STRING, \
+ FFstrbuf: FF_ARG_TYPE_STRBUF, \
+ float: FF_ARG_TYPE_FLOAT, \
+ double: FF_ARG_TYPE_DOUBLE, \
+ FFlist: FF_ARG_TYPE_LIST, \
+ bool: FF_ARG_TYPE_BOOL, \
+ FFArgBuffer: FF_ARG_TYPE_BUFFER), \
+ _Generic((variable), char*: (variable), const char*: (variable), default: &(variable)), \
+ (var_name) }
diff --git a/src/common/attributes.h b/src/common/attributes.h
new file mode 100644
index 0000000000..2a91c01ed2
--- /dev/null
+++ b/src/common/attributes.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#ifdef _MSC_VER
+ #define __attribute__(x)
+#endif
+
+#define FF_A_FALLTHROUGH __attribute__((__fallthrough__))
+#define FF_A_DEPRECATED __attribute__((__deprecated__))
+#define FF_A_CLEANUP(func) __attribute__((__cleanup__(func)))
+#define FF_A_NODISCARD __attribute__((__warn_unused_result__))
+#define FF_A_PRINTF(formatStrIndex, argsStartIndex) __attribute__((__format__(printf, formatStrIndex, argsStartIndex)))
+#define FF_A_SCANF(formatStrIndex, argsStartIndex) __attribute__((__format__(scanf, formatStrIndex, argsStartIndex)))
+#define FF_A_NONNULL(argIndex, ...) __attribute__((__nonnull__(argIndex, ##__VA_ARGS__)))
+#define FF_A_RETURNS_NONNULL __attribute__((__returns_nonnull__))
+#define FF_A_UNUSED __attribute__((__unused__))
+#define FF_A_PACKED __attribute__((__packed__))
+#define FF_A_WEAK_IMPORT __attribute__((__weak_import__))
diff --git a/src/common/base64.h b/src/common/base64.h
index 5dc8ee7c6f..d17da5c70f 100644
--- a/src/common/base64.h
+++ b/src/common/base64.h
@@ -2,9 +2,8 @@
#include "fastfetch.h"
-void ffBase64EncodeRaw(uint32_t size, const char *str, uint32_t *out_size, char *output);
-static inline FFstrbuf ffBase64EncodeStrbuf(const FFstrbuf* in)
-{
+void ffBase64EncodeRaw(uint32_t size, const char* str, uint32_t* out_size, char* output);
+static inline FFstrbuf ffBase64EncodeStrbuf(const FFstrbuf* in) {
FFstrbuf out = ffStrbufCreateA(10 + in->length * 4 / 3);
ffBase64EncodeRaw(in->length, in->chars, &out.length, out.chars);
assert(out.length < out.allocated);
@@ -12,9 +11,8 @@ static inline FFstrbuf ffBase64EncodeStrbuf(const FFstrbuf* in)
return out;
}
-bool ffBase64DecodeRaw(uint32_t size, const char *str, uint32_t *out_size, char *output);
-static inline FFstrbuf ffBase64DecodeStrbuf(const FFstrbuf* in)
-{
+bool ffBase64DecodeRaw(uint32_t size, const char* str, uint32_t* out_size, char* output);
+static inline FFstrbuf ffBase64DecodeStrbuf(const FFstrbuf* in) {
FFstrbuf out = ffStrbufCreateA(10 + in->length * 3 / 4);
ffBase64DecodeRaw(in->length, in->chars, &out.length, out.chars);
assert(out.length < out.allocated);
diff --git a/src/common/dbus.h b/src/common/dbus.h
index cecd744cbc..864040241d 100644
--- a/src/common/dbus.h
+++ b/src/common/dbus.h
@@ -1,13 +1,12 @@
#pragma once
#ifdef FF_HAVE_DBUS
-#include
+ #include
-#include "common/FFstrbuf.h"
-#include "common/library.h"
+ #include "common/FFstrbuf.h"
+ #include "common/library.h"
-typedef struct FFDBusLibrary
-{
+typedef struct FFDBusLibrary {
FF_LIBRARY_SYMBOL(dbus_bus_get)
FF_LIBRARY_SYMBOL(dbus_message_new_method_call)
FF_LIBRARY_SYMBOL(dbus_message_append_args)
@@ -22,13 +21,12 @@ typedef struct FFDBusLibrary
FF_LIBRARY_SYMBOL(dbus_connection_unref)
} FFDBusLibrary;
-typedef struct FFDBusData
-{
+typedef struct FFDBusData {
const FFDBusLibrary* lib;
DBusConnection* connection;
} FFDBusData;
-const char* ffDBusLoadData(DBusBusType busType, FFDBusData* data); //Returns an error message or NULL on success
+const char* ffDBusLoadData(DBusBusType busType, FFDBusData* data); // Returns an error message or NULL on success
bool ffDBusGetString(FFDBusData* dbus, DBusMessageIter* iter, FFstrbuf* result);
bool ffDBusGetBool(FFDBusData* dbus, DBusMessageIter* iter, bool* result);
bool ffDBusGetUint(FFDBusData* dbus, DBusMessageIter* iter, uint32_t* result);
@@ -39,11 +37,10 @@ bool ffDBusGetInt(FFDBusData* dbus, DBusMessageIter* iter, int32_t* result);
bool ffDBusGetPropertyUint(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, uint32_t* result);
void ffDBusDestroyData(FFDBusData* data);
-static inline DBusMessage* ffDBusGetAllProperties(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface)
-{
+static inline DBusMessage* ffDBusGetAllProperties(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface) {
return ffDBusGetMethodReply(dbus, busName, objectPath, "org.freedesktop.DBus.Properties", "GetAll", interface, NULL);
}
-#define FF_DBUS_AUTO_DESTROY_DATA __attribute__((__cleanup__(ffDBusDestroyData)))
+ #define FF_DBUS_AUTO_DESTROY_DATA FF_A_CLEANUP(ffDBusDestroyData)
#endif // FF_HAVE_DBUS
diff --git a/src/common/debug.h b/src/common/debug.h
index 412fc2cb1d..a378fc841b 100644
--- a/src/common/debug.h
+++ b/src/common/debug.h
@@ -3,27 +3,29 @@
#include "fastfetch.h"
#include "common/time.h"
-static inline const char* ffFindFileName(const char* file)
-{
+static inline const char* ffFindFileName(const char* file) {
const char* lastSlash = __builtin_strrchr(file, '/');
- #ifdef _WIN32
- if (lastSlash == NULL)
+#ifdef _WIN32
+ if (lastSlash == NULL) {
lastSlash = __builtin_strrchr(file, '\\');
- #endif
- if (lastSlash != NULL)
+ }
+#endif
+ if (lastSlash != NULL) {
return lastSlash + 1;
+ }
return file;
}
#ifndef NDEBUG
- #define FF_DEBUG_PRINT(file_, line_, format_, ...) \
- do { \
- if (instance.config.display.debugMode) \
+ #define FF_DEBUG_PRINT(file_, line_, format_, ...) \
+ do { \
+ if (instance.config.display.debugMode) \
fprintf(stderr, "[%s%4d, %s] " format_ "\n", ffFindFileName(file_), line_, ffTimeToTimeStr(ffTimeGetNow()), ##__VA_ARGS__); \
} while (0)
#else
#define FF_DEBUG_PRINT(file_, line_, format_, ...) \
- do { } while (0)
+ do { \
+ } while (0)
#endif
#define FF_DEBUG(format, ...) FF_DEBUG_PRINT(__FILE__, __LINE__, format, ##__VA_ARGS__)
diff --git a/src/common/ffdata.h b/src/common/ffdata.h
index 51b401ff3f..189c0fab27 100644
--- a/src/common/ffdata.h
+++ b/src/common/ffdata.h
@@ -2,8 +2,7 @@
#include "common/FFstrbuf.h"
-typedef enum __attribute__((__packed__)) FFDataResultDocType
-{
+typedef enum FF_A_PACKED FFDataResultDocType {
FF_RESULT_DOC_TYPE_DEFAULT = 0,
FF_RESULT_DOC_TYPE_JSON,
FF_RESULT_DOC_TYPE_CONFIG,
@@ -12,13 +11,12 @@ typedef enum __attribute__((__packed__)) FFDataResultDocType
// FFdata aggregates configuration, generation parameters, and output state used by fastfetch.
// It holds the parsed configuration document, a mutable JSON document for results, and related metadata.
-typedef struct FFdata
-{
- yyjson_doc* configDoc; // Parsed JSON configuration document
- yyjson_mut_doc* resultDoc; // Mutable JSON document for storing results
- FFstrbuf structure; // Custom output structure from command line
- FFstrbuf structureDisabled; // Disabled modules in the output structure from command line
- FFstrbuf genConfigPath; // Path to generate configuration file
+typedef struct FFdata {
+ yyjson_doc* configDoc; // Parsed JSON configuration document
+ yyjson_mut_doc* resultDoc; // Mutable JSON document for storing results
+ FFstrbuf structure; // Custom output structure from command line
+ FFstrbuf structureDisabled; // Disabled modules in the output structure from command line
+ FFstrbuf genConfigPath; // Path to generate configuration file
FFDataResultDocType docType; // Type of result document
bool configLoaded;
} FFdata;
diff --git a/src/common/font.h b/src/common/font.h
index e10817eecb..f9d25e7fd0 100644
--- a/src/common/font.h
+++ b/src/common/font.h
@@ -3,8 +3,7 @@
#include "common/FFstrbuf.h"
#include "common/FFlist.h"
-typedef struct FFfont
-{
+typedef struct FFfont {
FFstrbuf pretty;
FFstrbuf name;
FFstrbuf size;
@@ -21,7 +20,6 @@ void ffFontInitMoveValues(FFfont* font, FFstrbuf* name, FFstrbuf* size, FFstrbuf
void ffFontInitWithSpace(FFfont* font, const char* rawName);
void ffFontDestroy(FFfont* font);
-static inline void ffFontInitCopy(FFfont* font, const char* name)
-{
+static inline void ffFontInitCopy(FFfont* font, const char* name) {
ffFontInitValues(font, name, NULL);
}
diff --git a/src/common/format.h b/src/common/format.h
index 3c7ada6ae4..f47fc86127 100644
--- a/src/common/format.h
+++ b/src/common/format.h
@@ -2,8 +2,7 @@
#include "common/argType.h"
-typedef struct FFformatarg
-{
+typedef struct FFformatarg {
FFArgType type;
const void* value;
const char* name; // argument name, must start with an alphabet
diff --git a/src/common/haiku/version.cpp b/src/common/haiku/version.cpp
index 8dcf672ee3..f8e65c3d5e 100644
--- a/src/common/haiku/version.cpp
+++ b/src/common/haiku/version.cpp
@@ -5,20 +5,22 @@ extern "C" {
#include
#include
-bool ffGetFileVersion(const char* filePath, FFstrbuf* version)
-{
+bool ffGetFileVersion(const char* filePath, FFstrbuf* version) {
BFile f(filePath, B_READ_ONLY);
- if (f.InitCheck() != B_OK)
+ if (f.InitCheck() != B_OK) {
return false;
+ }
BAppFileInfo fileInfo(&f);
- if (f.InitCheck() != B_OK)
+ if (f.InitCheck() != B_OK) {
return false;
+ }
version_info info;
- if (fileInfo.GetVersionInfo(&info, B_SYSTEM_VERSION_KIND) != B_OK)
+ if (fileInfo.GetVersionInfo(&info, B_SYSTEM_VERSION_KIND) != B_OK) {
return false;
+ }
- ffStrbufSetF(version, "%d.%d.%d", (int)info.major, (int)info.middle, (int)info.minor);
+ ffStrbufSetF(version, "%d.%d.%d", (int) info.major, (int) info.middle, (int) info.minor);
return true;
}
diff --git a/src/common/impl/FFPlatform.c b/src/common/impl/FFPlatform.c
index f84ab5878b..2e4d523a97 100644
--- a/src/common/impl/FFPlatform.c
+++ b/src/common/impl/FFPlatform.c
@@ -3,12 +3,11 @@
#include "common/io.h"
#include "detection/version/version.h"
-void ffPlatformInit(FFPlatform* platform)
-{
+void ffPlatformInit(FFPlatform* platform) {
ffStrbufInit(&platform->homeDir);
ffStrbufInit(&platform->cacheDir);
- ffListInit(&platform->configDirs, sizeof(FFstrbuf));
- ffListInit(&platform->dataDirs, sizeof(FFstrbuf));
+ ffListInit(&platform->configDirs);
+ ffListInit(&platform->dataDirs);
ffStrbufInit(&platform->exePath);
ffStrbufInit(&platform->cwd);
@@ -17,9 +16,9 @@ void ffPlatformInit(FFPlatform* platform)
ffStrbufInit(&platform->hostName);
ffStrbufInit(&platform->userShell);
- #ifdef _WIN32
+#ifdef _WIN32
ffStrbufInit(&platform->sid);
- #endif
+#endif
FFPlatformSysinfo* info = &platform->sysinfo;
@@ -30,24 +29,27 @@ void ffPlatformInit(FFPlatform* platform)
ffPlatformInitImpl(platform);
- if(info->name.length == 0)
+ if (info->name.length == 0) {
ffStrbufSetStatic(&info->name, ffVersionResult.sysName);
+ }
- if(info->architecture.length == 0)
+ if (info->architecture.length == 0) {
ffStrbufSetStatic(&info->architecture, ffVersionResult.architecture);
+ }
}
-void ffPlatformDestroy(FFPlatform* platform)
-{
+void ffPlatformDestroy(FFPlatform* platform) {
ffStrbufDestroy(&platform->homeDir);
ffStrbufDestroy(&platform->cacheDir);
- FF_LIST_FOR_EACH(FFstrbuf, dir, platform->configDirs)
+ FF_LIST_FOR_EACH (FFstrbuf, dir, platform->configDirs) {
ffStrbufDestroy(dir);
+ }
ffListDestroy(&platform->configDirs);
- FF_LIST_FOR_EACH(FFstrbuf, dir, platform->dataDirs)
+ FF_LIST_FOR_EACH (FFstrbuf, dir, platform->dataDirs) {
ffStrbufDestroy(dir);
+ }
ffListDestroy(&platform->dataDirs);
ffStrbufDestroy(&platform->exePath);
ffStrbufDestroy(&platform->cwd);
@@ -57,9 +59,9 @@ void ffPlatformDestroy(FFPlatform* platform)
ffStrbufDestroy(&platform->userShell);
ffStrbufDestroy(&platform->fullUserName);
- #ifdef _WIN32
+#ifdef _WIN32
ffStrbufDestroy(&platform->sid);
- #endif
+#endif
FFPlatformSysinfo* info = &platform->sysinfo;
ffStrbufDestroy(&info->architecture);
@@ -68,23 +70,24 @@ void ffPlatformDestroy(FFPlatform* platform)
ffStrbufDestroy(&info->version);
}
-void ffPlatformPathAddAbsolute(FFlist* dirs, const char* path)
-{
- if (!ffPathExists(path, FF_PATHTYPE_DIRECTORY))
+void ffPlatformPathAddAbsolute(FFlist* dirs, const char* path) {
+ if (!ffPathExists(path, FF_PATHTYPE_DIRECTORY)) {
return;
+ }
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreateS(path);
ffStrbufEnsureEndsWithC(&buffer, '/');
- if (!ffListContains(dirs, &buffer, (void*) ffStrbufEqual))
- ffStrbufInitMove((FFstrbuf*) ffListAdd(dirs), &buffer);
+ if (!FF_LIST_CONTAINS(*dirs, &buffer, ffStrbufEqual)) {
+ ffStrbufInitMove(FF_LIST_ADD(FFstrbuf, *dirs), &buffer);
+ }
}
-void ffPlatformPathAddHome(FFlist* dirs, const FFPlatform* platform, const char* suffix)
-{
+void ffPlatformPathAddHome(FFlist* dirs, const FFPlatform* platform, const char* suffix) {
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreateA(64);
ffStrbufAppend(&buffer, &platform->homeDir);
ffStrbufAppendS(&buffer, suffix);
ffStrbufEnsureEndsWithC(&buffer, '/');
- if (ffPathExists(buffer.chars, FF_PATHTYPE_DIRECTORY) && !ffListContains(dirs, &buffer, (void*) ffStrbufEqual))
- ffStrbufInitMove((FFstrbuf*) ffListAdd(dirs), &buffer);
+ if (ffPathExists(buffer.chars, FF_PATHTYPE_DIRECTORY) && !FF_LIST_CONTAINS(*dirs, &buffer, ffStrbufEqual)) {
+ ffStrbufInitMove(FF_LIST_ADD(FFstrbuf, *dirs), &buffer);
+ }
}
diff --git a/src/common/impl/FFPlatform_unix.c b/src/common/impl/FFPlatform_unix.c
index c93c863bde..8320a17719 100644
--- a/src/common/impl/FFPlatform_unix.c
+++ b/src/common/impl/FFPlatform_unix.c
@@ -25,154 +25,148 @@
#include
#endif
-static void getExePath(FFPlatform* platform)
-{
+static void getExePath(FFPlatform* platform) {
char exePath[PATH_MAX];
- #if defined(__linux__) || defined (__GNU__)
- ssize_t exePathLen = readlink("/proc/self/exe", exePath, sizeof(exePath) - 1);
- if (exePathLen >= 0)
- exePath[exePathLen] = '\0';
- #elif defined(__APPLE__)
- uint32_t exePathLen = sizeof(exePath);
- if (_NSGetExecutablePath(exePath, &exePathLen) == 0)
- exePathLen = (uint32_t) strlen(exePath);
- else
- exePathLen = 0;
- #elif defined(__FreeBSD__) || defined(__NetBSD__)
- size_t exePathLen = sizeof(exePath);
- if(sysctl(
- (int[]){CTL_KERN,
- #ifdef __FreeBSD__
- KERN_PROC, KERN_PROC_PATHNAME, (pid_t) platform->pid
- #else
- KERN_PROC_ARGS, platform->pid, KERN_PROC_PATHNAME
- #endif
- }, 4,
- exePath, &exePathLen,
- NULL, 0
- ) < 0)
- exePathLen = 0;
- else
- exePathLen--; // remove terminating NUL
- #elif defined(__OpenBSD__)
- // OpenBSD doesn't have a reliable way to get the executable path.
- // Current implementation uses argv[0], which can be easily spoofed.
- // See #2195
- size_t exePathLen = 0;
- kvm_t* kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, NULL);
- if (kd)
- {
- int kpCount;
- struct kinfo_proc* kp = kvm_getprocs(kd, KERN_PROC_PID, (pid_t) platform->pid, sizeof(*kp), &kpCount);
- if (kp && kpCount == 1)
- {
- char** argv = kvm_getargv(kd, kp, 0);
- if (argv && argv[0])
- {
- char* arg0 = argv[0];
- if (arg0[0])
+#if defined(__linux__) || defined(__GNU__)
+ ssize_t exePathLen = readlink("/proc/self/exe", exePath, sizeof(exePath) - 1);
+ if (exePathLen >= 0) {
+ exePath[exePathLen] = '\0';
+ }
+#elif defined(__APPLE__)
+ uint32_t exePathLen = sizeof(exePath);
+ if (_NSGetExecutablePath(exePath, &exePathLen) == 0) {
+ exePathLen = (uint32_t) strlen(exePath);
+ } else {
+ exePathLen = 0;
+ }
+#elif defined(__FreeBSD__) || defined(__NetBSD__)
+ size_t exePathLen = sizeof(exePath);
+ if (sysctl(
+ (int[]) { CTL_KERN,
+ #ifdef __FreeBSD__
+ KERN_PROC,
+ KERN_PROC_PATHNAME,
+ (pid_t) platform->pid
+ #else
+ KERN_PROC_ARGS,
+ (pid_t) platform->pid,
+ KERN_PROC_PATHNAME
+ #endif
+ },
+ 4,
+ exePath,
+ &exePathLen,
+ NULL,
+ 0) < 0)
+ exePathLen = 0;
+ else {
+ exePathLen--; // remove terminating NUL
+ }
+#elif defined(__OpenBSD__)
+ // OpenBSD doesn't have a reliable way to get the executable path.
+ // Current implementation uses argv[0], which can be easily spoofed.
+ // See #2195
+ size_t exePathLen = 0;
+ kvm_t* kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, NULL);
+ if (kd) {
+ int kpCount;
+ struct kinfo_proc* kp = kvm_getprocs(kd, KERN_PROC_PID, (pid_t) platform->pid, sizeof(*kp), &kpCount);
+ if (kp && kpCount == 1) {
+ char** argv = kvm_getargv(kd, kp, 0);
+ if (argv && argv[0]) {
+ char* arg0 = argv[0];
+ if (arg0[0]) {
+ if (strchr(arg0, '/') != NULL) // likely a path (absolute or relative)
{
- if (strchr(arg0, '/') != NULL) // likely a path (absolute or relative)
- {
- exePathLen = strlen(arg0);
- if (exePathLen < ARRAY_SIZE(exePath))
- {
- memcpy(exePath, arg0, exePathLen);
- exePath[exePathLen] = '\0';
- }
- else
- exePathLen = 0;
+ exePathLen = strlen(arg0);
+ if (exePathLen < ARRAY_SIZE(exePath)) {
+ memcpy(exePath, arg0, exePathLen);
+ exePath[exePathLen] = '\0';
+ } else {
+ exePathLen = 0;
}
- else
- {
- FF_STRBUF_AUTO_DESTROY tmpPath = ffStrbufCreate();
- if (ffFindExecutableInPath(arg0, &tmpPath) == NULL && tmpPath.length < ARRAY_SIZE(exePath))
- {
- memcpy(exePath, tmpPath.chars, tmpPath.length + 1);
- exePathLen = tmpPath.length;
- }
+ } else {
+ FF_STRBUF_AUTO_DESTROY tmpPath = ffStrbufCreate();
+ if (ffFindExecutableInPath(arg0, &tmpPath) == NULL && tmpPath.length < ARRAY_SIZE(exePath)) {
+ memcpy(exePath, tmpPath.chars, tmpPath.length + 1);
+ exePathLen = tmpPath.length;
}
+ }
- if (exePathLen > 0)
- {
- struct stat st;
- if (stat(exePath, &st) == 0 && S_ISREG(st.st_mode))
- {
- int cntp;
- struct kinfo_file* kf = kvm_getfiles(kd, KERN_FILE_BYPID, platform->pid, sizeof(*kf), &cntp);
- if (kf)
- {
- int i;
- for (i = 0; i < cntp; i++)
- {
- if (kf[i].fd_fd == KERN_FILE_TEXT)
- {
- // KERN_FILE_TEXT is the executable file, not a shared library, and should be unique in the list.
- if (st.st_dev != (dev_t)kf[i].va_fsid || st.st_ino != (ino_t)kf[i].va_fileid)
- i = -1;
- break;
+ if (exePathLen > 0) {
+ struct stat st;
+ if (stat(exePath, &st) == 0 && S_ISREG(st.st_mode)) {
+ int cntp;
+ struct kinfo_file* kf = kvm_getfiles(kd, KERN_FILE_BYPID, platform->pid, sizeof(*kf), &cntp);
+ if (kf) {
+ int i;
+ for (i = 0; i < cntp; i++) {
+ if (kf[i].fd_fd == KERN_FILE_TEXT) {
+ // KERN_FILE_TEXT is the executable file, not a shared library, and should be unique in the list.
+ if (st.st_dev != (dev_t) kf[i].va_fsid || st.st_ino != (ino_t) kf[i].va_fileid) {
+ i = -1;
}
+ break;
}
- if (i < 0)
- exePathLen = 0;
}
- else
- {
- // If we can't get the list of open files, we can't verify that the file is actually the executable
- // Assume it is
+ if (i < 0) {
+ exePathLen = 0;
}
+ } else {
+ // If we can't get the list of open files, we can't verify that the file is actually the executable
+ // Assume it is
}
- else
- exePathLen = 0;
+ } else {
+ exePathLen = 0;
}
}
}
}
- kvm_close(kd);
}
- #elif defined(__sun)
- ssize_t exePathLen = readlink("/proc/self/path/a.out", exePath, sizeof(exePath) - 1);
- if (exePathLen >= 0)
- exePath[exePathLen] = '\0';
- #elif defined(__HAIKU__)
- size_t exePathLen = 0;
- image_info info;
- int32 cookie = 0;
-
- while (get_next_image_info(B_CURRENT_TEAM, &cookie, &info) == B_OK) {
- if (info.type == B_APP_IMAGE) {
- exePathLen = strlcpy(exePath, info.name, sizeof(exePath));
- break;
- }
+ kvm_close(kd);
+ }
+#elif defined(__sun)
+ ssize_t exePathLen = readlink("/proc/self/path/a.out", exePath, sizeof(exePath) - 1);
+ if (exePathLen >= 0) {
+ exePath[exePathLen] = '\0';
+ }
+#elif defined(__HAIKU__)
+ size_t exePathLen = 0;
+ image_info info;
+ int32 cookie = 0;
+
+ while (get_next_image_info(B_CURRENT_TEAM, &cookie, &info) == B_OK) {
+ if (info.type == B_APP_IMAGE) {
+ exePathLen = strlcpy(exePath, info.name, sizeof(exePath));
+ break;
}
- #endif
- if (exePathLen > 0)
- {
+ }
+#endif
+ if (exePathLen > 0) {
ffStrbufEnsureFree(&platform->exePath, PATH_MAX);
- if (realpath(exePath, platform->exePath.chars))
+ if (realpath(exePath, platform->exePath.chars)) {
ffStrbufRecalculateLength(&platform->exePath);
- else
+ } else {
ffStrbufSetNS(&platform->exePath, (uint32_t) exePathLen, exePath);
+ }
}
}
-static void platformPathAddEnv(FFlist* dirs, const char* env)
-{
+static void platformPathAddEnv(FFlist* dirs, const char* env) {
const char* envValue = getenv(env);
- if(!ffStrSet(envValue))
+ if (!ffStrSet(envValue)) {
return;
+ }
FF_STRBUF_AUTO_DESTROY value = ffStrbufCreateA(64);
ffStrbufAppendS(&value, envValue);
uint32_t startIndex = 0;
- while (startIndex < value.length)
- {
+ while (startIndex < value.length) {
uint32_t colonIndex = ffStrbufNextIndexC(&value, startIndex, ':');
value.chars[colonIndex] = '\0';
- if(!ffStrSet(value.chars + startIndex))
- {
+ if (!ffStrSet(value.chars + startIndex)) {
startIndex = colonIndex + 1;
continue;
}
@@ -183,61 +177,53 @@ static void platformPathAddEnv(FFlist* dirs, const char* env)
}
}
-static void getHomeDir(FFPlatform* platform, const struct passwd* pwd)
-{
+static void getHomeDir(FFPlatform* platform, const struct passwd* pwd) {
const char* home = pwd ? pwd->pw_dir : getenv("HOME");
ffStrbufAppendS(&platform->homeDir, home);
ffStrbufEnsureEndsWithC(&platform->homeDir, '/');
}
-static void getCacheDir(FFPlatform* platform)
-{
+static void getCacheDir(FFPlatform* platform) {
const char* cache = getenv("XDG_CACHE_HOME");
- if(ffStrSet(cache))
- {
+ if (ffStrSet(cache)) {
ffStrbufAppendS(&platform->cacheDir, cache);
ffStrbufEnsureEndsWithC(&platform->cacheDir, '/');
- }
- else
- {
+ } else {
ffStrbufAppend(&platform->cacheDir, &platform->homeDir);
ffStrbufAppendS(&platform->cacheDir, ".cache/");
}
}
-static void getConfigDirs(FFPlatform* platform)
-{
+static void getConfigDirs(FFPlatform* platform) {
// Always make sure `${XDG_CONFIG_HOME:-$HOME/.config}` is the first entry
platformPathAddEnv(&platform->configDirs, "XDG_CONFIG_HOME");
ffPlatformPathAddHome(&platform->configDirs, platform, ".config/");
- #if defined(__APPLE__)
- ffPlatformPathAddHome(&platform->configDirs, platform, "Library/Preferences/");
- ffPlatformPathAddHome(&platform->configDirs, platform, "Library/Application Support/");
- #endif
- #if defined(__HAIKU__)
- ffPlatformPathAddHome(&platform->configDirs, platform, "config/settings/");
- #endif
+#if defined(__APPLE__)
+ ffPlatformPathAddHome(&platform->configDirs, platform, "Library/Preferences/");
+ ffPlatformPathAddHome(&platform->configDirs, platform, "Library/Application Support/");
+#endif
+#if defined(__HAIKU__)
+ ffPlatformPathAddHome(&platform->configDirs, platform, "config/settings/");
+#endif
ffPlatformPathAddHome(&platform->configDirs, platform, "");
platformPathAddEnv(&platform->configDirs, "XDG_CONFIG_DIRS");
- #if !defined(__APPLE__)
- ffPlatformPathAddAbsolute(&platform->configDirs, FASTFETCH_TARGET_DIR_ETC "/xdg/");
- #endif
+#if !defined(__APPLE__)
+ ffPlatformPathAddAbsolute(&platform->configDirs, FASTFETCH_TARGET_DIR_ETC "/xdg/");
+#endif
ffPlatformPathAddAbsolute(&platform->configDirs, FASTFETCH_TARGET_DIR_ETC "/");
ffPlatformPathAddAbsolute(&platform->configDirs, FASTFETCH_TARGET_DIR_INSTALL_SYSCONF "/");
}
-static void getDataDirs(FFPlatform* platform)
-{
+static void getDataDirs(FFPlatform* platform) {
platformPathAddEnv(&platform->dataDirs, "XDG_DATA_HOME");
ffPlatformPathAddHome(&platform->dataDirs, platform, ".local/share/");
// Add ${currentExePath}/../share
- if (platform->exePath.length > 0)
- {
+ if (platform->exePath.length > 0) {
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateCopy(&platform->exePath);
ffStrbufSubstrBeforeLastC(&path, '/');
ffStrbufSubstrBeforeLastC(&path, '/');
@@ -245,9 +231,9 @@ static void getDataDirs(FFPlatform* platform)
ffPlatformPathAddAbsolute(&platform->dataDirs, path.chars);
}
- #ifdef __APPLE__
- ffPlatformPathAddHome(&platform->dataDirs, platform, "Library/Application Support/");
- #endif
+#ifdef __APPLE__
+ ffPlatformPathAddHome(&platform->dataDirs, platform, "Library/Application Support/");
+#endif
ffPlatformPathAddHome(&platform->dataDirs, platform, "");
platformPathAddEnv(&platform->dataDirs, "XDG_DATA_DIRS");
@@ -258,74 +244,66 @@ static void getDataDirs(FFPlatform* platform)
ffPlatformPathAddAbsolute(&platform->dataDirs, FASTFETCH_TARGET_DIR_USR "/share/");
}
-static void getUserName(FFPlatform* platform, const struct passwd* pwd)
-{
- if (pwd)
- {
+static void getUserName(FFPlatform* platform, const struct passwd* pwd) {
+ if (pwd) {
ffStrbufSetS(&platform->userName, pwd->pw_name);
ffStrbufSetS(&platform->fullUserName, pwd->pw_gecos);
ffStrbufTrimSpace(&platform->fullUserName);
- }
- else
- {
+ } else {
ffStrbufSetS(&platform->userName, getenv("USER"));
}
}
-static void getHostName(FFPlatform* platform, const struct utsname* uts)
-{
+static void getHostName(FFPlatform* platform, const struct utsname* uts) {
ffStrbufAppendS(&platform->hostName, uts->nodename);
}
-static void getUserShell(FFPlatform* platform, const struct passwd* pwd)
-{
+static void getUserShell(FFPlatform* platform, const struct passwd* pwd) {
const char* shell = getenv("SHELL");
- if(!ffStrSet(shell) && pwd)
+ if (!ffStrSet(shell) && pwd) {
shell = pwd->pw_shell;
+ }
ffStrbufAppendS(&platform->userShell, shell);
}
-static void getSysinfo(FFPlatformSysinfo* info, const struct utsname* uts)
-{
+static void getSysinfo(FFPlatformSysinfo* info, const struct utsname* uts) {
ffStrbufAppendS(&info->name, uts->sysname);
ffStrbufAppendS(&info->release, uts->release);
ffStrbufAppendS(&info->version, uts->version);
- #ifdef __HAIKU__
+#ifdef __HAIKU__
/* historical reason */
- if (ffStrEquals(uts->machine, "BePC"))
+ if (ffStrEquals(uts->machine, "BePC")) {
ffStrbufSetStatic(&info->architecture, "i386");
- else
- #endif
- ffStrbufAppendS(&info->architecture, uts->machine);
+ } else
+#endif
+ ffStrbufAppendS(&info->architecture, uts->machine);
- #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__OpenBSD__) || defined(__NetBSD__)
+#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__OpenBSD__) || defined(__NetBSD__)
size_t length = sizeof(info->pageSize);
- sysctl((int[]){ CTL_HW, HW_PAGESIZE }, 2, &info->pageSize, &length, NULL, 0);
- #else
+ sysctl((int[]) { CTL_HW, HW_PAGESIZE }, 2, &info->pageSize, &length, NULL, 0);
+#else
info->pageSize = (uint32_t) sysconf(_SC_PAGESIZE);
- #endif
+#endif
}
-static void getCwd(FFPlatform* platform)
-{
+static void getCwd(FFPlatform* platform) {
char cwd[PATH_MAX];
- if (getcwd(cwd, sizeof(cwd)) != NULL)
- {
+ if (getcwd(cwd, sizeof(cwd)) != NULL) {
ffStrbufSetS(&platform->cwd, cwd);
ffStrbufEnsureEndsWithC(&platform->cwd, '/');
}
}
-void ffPlatformInitImpl(FFPlatform* platform)
-{
+void ffPlatformInitImpl(FFPlatform* platform) {
platform->pid = (uint32_t) getpid();
platform->uid = getuid();
struct passwd* pwd = getpwuid(platform->uid);
struct utsname uts;
- if(uname(&uts) < 0)
+ if (uname(&uts) < 0) {
memset(&uts, 0, sizeof(uts));
+ }
getExePath(platform);
getCwd(platform);
diff --git a/src/common/impl/FFPlatform_windows.c b/src/common/impl/FFPlatform_windows.c
index 1dc377766a..170494db8b 100644
--- a/src/common/impl/FFPlatform_windows.c
+++ b/src/common/impl/FFPlatform_windows.c
@@ -14,8 +14,7 @@
#define SECURITY_WIN32 1 // For secext.h
#include
-static void getExePath(FFPlatform* platform)
-{
+static void getExePath(FFPlatform* platform) {
wchar_t exePathW[MAX_PATH];
FF_AUTO_CLOSE_FD HANDLE hPath = CreateFileW(
@@ -26,19 +25,17 @@ static void getExePath(FFPlatform* platform)
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
NULL);
- if (hPath != INVALID_HANDLE_VALUE)
- {
+ if (hPath != INVALID_HANDLE_VALUE) {
DWORD len = GetFinalPathNameByHandleW(hPath, exePathW, MAX_PATH, FILE_NAME_NORMALIZED);
- if (len > 0 && len < MAX_PATH)
- {
+ if (len > 0 && len < MAX_PATH) {
ffStrbufSetNWS(&platform->exePath, len, exePathW);
- if (ffStrbufStartsWithS(&platform->exePath, "\\\\?\\"))
+ if (ffStrbufStartsWithS(&platform->exePath, "\\\\?\\")) {
ffStrbufSubstrAfter(&platform->exePath, 3);
+ }
}
}
- if (platform->exePath.length == 0)
- {
+ if (platform->exePath.length == 0) {
PCUNICODE_STRING imagePathName = &ffGetPeb()->ProcessParameters->ImagePathName;
ffStrbufSetNWS(&platform->exePath, imagePathName->Length / sizeof(wchar_t), imagePathName->Buffer);
}
@@ -46,17 +43,13 @@ static void getExePath(FFPlatform* platform)
ffStrbufReplaceAllC(&platform->exePath, '\\', '/');
}
-static void getHomeDir(FFPlatform* platform)
-{
+static void getHomeDir(FFPlatform* platform) {
PWSTR pPath = NULL;
- if(SUCCEEDED(SHGetKnownFolderPath(&FOLDERID_Profile, KF_FLAG_DEFAULT, NULL, &pPath)))
- {
+ if (SUCCEEDED(SHGetKnownFolderPath(&FOLDERID_Profile, KF_FLAG_DEFAULT, NULL, &pPath))) {
ffStrbufSetWS(&platform->homeDir, pPath);
ffStrbufReplaceAllC(&platform->homeDir, '\\', '/');
ffStrbufEnsureEndsWithC(&platform->homeDir, '/');
- }
- else
- {
+ } else {
ffStrbufSetS(&platform->homeDir, getenv("USERPROFILE"));
ffStrbufReplaceAllC(&platform->homeDir, '\\', '/');
ffStrbufEnsureEndsWithC(&platform->homeDir, '/');
@@ -64,61 +57,54 @@ static void getHomeDir(FFPlatform* platform)
CoTaskMemFree(pPath);
}
-static void getCacheDir(FFPlatform* platform)
-{
+static void getCacheDir(FFPlatform* platform) {
PWSTR pPath = NULL;
- if(SUCCEEDED(SHGetKnownFolderPath(&FOLDERID_LocalAppData, KF_FLAG_DEFAULT, NULL, &pPath)))
- {
+ if (SUCCEEDED(SHGetKnownFolderPath(&FOLDERID_LocalAppData, KF_FLAG_DEFAULT, NULL, &pPath))) {
ffStrbufSetWS(&platform->cacheDir, pPath);
ffStrbufReplaceAllC(&platform->cacheDir, '\\', '/');
ffStrbufEnsureEndsWithC(&platform->cacheDir, '/');
- }
- else
- {
+ } else {
ffStrbufAppend(&platform->cacheDir, &platform->homeDir);
ffStrbufAppendS(&platform->cacheDir, "AppData/Local/");
}
CoTaskMemFree(pPath);
}
-static void platformPathAddKnownFolder(FFlist* dirs, REFKNOWNFOLDERID folderId)
-{
+static void platformPathAddKnownFolder(FFlist* dirs, REFKNOWNFOLDERID folderId) {
PWSTR pPath = NULL;
- if (SUCCEEDED(SHGetKnownFolderPath(folderId, KF_FLAG_DEFAULT, NULL, &pPath)))
- {
+ if (SUCCEEDED(SHGetKnownFolderPath(folderId, KF_FLAG_DEFAULT, NULL, &pPath))) {
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreateWS(pPath);
CoTaskMemFree(pPath);
ffStrbufReplaceAllC(&buffer, '\\', '/');
ffStrbufEnsureEndsWithC(&buffer, '/');
- if (!ffListContains(dirs, &buffer, (void*) ffStrbufEqual))
- ffStrbufInitMove((FFstrbuf*) ffListAdd(dirs), &buffer);
+ if (!FF_LIST_CONTAINS(*dirs, &buffer, ffStrbufEqual)) {
+ ffStrbufInitMove(FF_LIST_ADD(FFstrbuf, *dirs), &buffer);
+ }
}
}
-static void platformPathAddEnvSuffix(FFlist* dirs, const char* env, const char* suffix)
-{
+static void platformPathAddEnvSuffix(FFlist* dirs, const char* env, const char* suffix) {
const char* value = getenv(env);
- if(!ffStrSet(value))
+ if (!ffStrSet(value)) {
return;
+ }
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreateA(64);
ffStrbufAppendS(&buffer, value);
ffStrbufReplaceAllC(&buffer, '\\', '/');
ffStrbufEnsureEndsWithC(&buffer, '/');
- if (suffix)
- {
+ if (suffix) {
ffStrbufAppendS(&buffer, suffix);
ffStrbufEnsureEndsWithC(&buffer, '/');
}
- if (ffPathExists(buffer.chars, FF_PATHTYPE_DIRECTORY) && !ffListContains(dirs, &buffer, (void*) ffStrbufEqual))
- ffStrbufInitMove((FFstrbuf*) ffListAdd(dirs), &buffer);
+ if (ffPathExists(buffer.chars, FF_PATHTYPE_DIRECTORY) && !FF_LIST_CONTAINS(*dirs, &buffer, ffStrbufEqual)) {
+ ffStrbufInitMove(FF_LIST_ADD(FFstrbuf, *dirs), &buffer);
+ }
}
-static void getConfigDirs(FFPlatform* platform)
-{
- if(getenv("MSYSTEM"))
- {
+static void getConfigDirs(FFPlatform* platform) {
+ if (getenv("MSYSTEM")) {
// We are in MSYS2 / Git Bash
platformPathAddEnvSuffix(&platform->configDirs, "HOME", ".config/");
platformPathAddEnvSuffix(&platform->configDirs, "HOME", NULL);
@@ -132,10 +118,8 @@ static void getConfigDirs(FFPlatform* platform)
ffPlatformPathAddHome(&platform->configDirs, platform, "");
}
-static void getDataDirs(FFPlatform* platform)
-{
- if(getenv("MSYSTEM") && getenv("HOME"))
- {
+static void getDataDirs(FFPlatform* platform) {
+ if (getenv("MSYSTEM") && getenv("HOME")) {
// We are in MSYS2 / Git Bash
platformPathAddEnvSuffix(&platform->dataDirs, "HOME", ".local/share/");
platformPathAddEnvSuffix(&platform->dataDirs, "HOME", NULL);
@@ -148,75 +132,83 @@ static void getDataDirs(FFPlatform* platform)
ffPlatformPathAddHome(&platform->dataDirs, platform, "");
}
-static void getUserName(FFPlatform* platform)
-{
+static void getUserName(FFPlatform* platform) {
wchar_t buffer[256];
DWORD size = ARRAY_SIZE(buffer);
- if (GetUserNameExW(NameDisplay, buffer, &size))
+ if (GetUserNameExW(NameDisplay, buffer, &size)) {
ffStrbufSetWS(&platform->fullUserName, buffer);
+ }
- size = ARRAY_SIZE(buffer);
- if (GetUserNameW(buffer, &size)) // GetUserNameExW(10002)?
- ffStrbufSetWS(&platform->userName, buffer);
- else
+ NTSYSAPI NTSTATUS NTAPI LsaGetUserName(
+ _Outptr_ PLSA_UNICODE_STRING* UserName,
+ _Outptr_opt_ PLSA_UNICODE_STRING* DomainName
+ );
+ PLSA_UNICODE_STRING userName = NULL;
+ if (NT_SUCCESS(LsaGetUserName(&userName, NULL))) {
+ ffStrbufSetNWS(&platform->userName, userName->Length / sizeof(wchar_t), userName->Buffer);
+ RtlFreeUnicodeString(userName);
+ LsaFreeMemory(userName);
+ } else {
ffStrbufSetS(&platform->userName, getenv("USERNAME"));
+ }
alignas(TOKEN_USER) char buf[SECURITY_MAX_SID_SIZE + sizeof(TOKEN_USER)];
- if (NT_SUCCESS(NtQueryInformationToken(NtCurrentProcessToken(), TokenUser, buf, sizeof(buf), &size)))
- {
+ if (NT_SUCCESS(NtQueryInformationToken(NtCurrentProcessToken(), TokenUser, buf, sizeof(buf), &size))) {
TOKEN_USER* tokenUser = (TOKEN_USER*) buf;
UNICODE_STRING sidString = { .Buffer = buffer, .Length = 0, .MaximumLength = sizeof(buffer) };
- if (NT_SUCCESS(RtlConvertSidToUnicodeString(&sidString, tokenUser->User.Sid, FALSE)))
+ if (NT_SUCCESS(RtlConvertSidToUnicodeString(&sidString, tokenUser->User.Sid, FALSE))) {
ffStrbufSetNWS(&platform->sid, sidString.Length / sizeof(wchar_t), sidString.Buffer);
+ }
}
}
-static void getHostName(FFPlatform* platform)
-{
+static void getHostName(FFPlatform* platform) {
wchar_t buffer[256];
DWORD len = ARRAY_SIZE(buffer);
- if (GetComputerNameExW(ComputerNameDnsHostname, buffer, &len) && len > 0)
+ if (GetComputerNameExW(ComputerNameDnsHostname, buffer, &len) && len > 0) {
ffStrbufSetNWS(&platform->hostName, len, buffer);
- else
- {
+ } else {
len = ARRAY_SIZE(buffer);
- if (GetComputerNameExW(ComputerNameNetBIOS, buffer, &len) && len > 0)
+ if (GetComputerNameExW(ComputerNameNetBIOS, buffer, &len) && len > 0) {
ffStrbufSetNWS(&platform->hostName, len, buffer);
+ }
}
}
-static void getUserShell(FFPlatform* platform)
-{
+static void getUserShell(FFPlatform* platform) {
// Works in MSYS2
const char* userShell = getenv("SHELL");
- if (userShell)
- {
+ if (userShell) {
ffStrbufAppendS(&platform->userShell, userShell);
ffStrbufReplaceAllC(&platform->userShell, '\\', '/');
}
}
-static const char* detectWine(void)
-{
- const char * __cdecl wine_get_version(void);
+static const char* detectWine(void) {
+ const char* __cdecl wine_get_version(void);
void* hntdll = ffLibraryGetModule(L"ntdll.dll");
- if (!hntdll) return NULL;
+ if (!hntdll) {
+ return NULL;
+ }
FF_LIBRARY_LOAD_SYMBOL_LAZY(hntdll, wine_get_version);
- if (!ffwine_get_version) return NULL;
+ if (!ffwine_get_version) {
+ return NULL;
+ }
return ffwine_get_version();
}
-static void getSystemReleaseAndVersion(FFPlatformSysinfo* info)
-{
+static void getSystemReleaseAndVersion(FFPlatformSysinfo* info) {
FF_AUTO_CLOSE_FD HANDLE hKey = NULL;
- if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", &hKey, NULL))
+ if (!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", &hKey, NULL)) {
return;
+ }
uint32_t ubr = 0;
ffRegReadValues(hKey, 2, (FFRegValueArg[]) {
- FF_ARG(ubr, L"UBR"),
- FF_ARG(info->version, L"BuildLabEx"),
- }, NULL);
+ FF_ARG(ubr, L"UBR"),
+ FF_ARG(info->version, L"BuildLabEx"),
+ },
+ NULL);
PPEB_FULL peb = ffGetPeb();
@@ -228,87 +220,82 @@ static void getSystemReleaseAndVersion(FFPlatformSysinfo* info)
(unsigned) ubr);
const char* wineVersion = detectWine();
- if (wineVersion)
+ if (wineVersion) {
ffStrbufSetF(&info->name, "Wine_%s", wineVersion);
- else
+ } else {
ffStrbufSetStatic(&info->name, "WIN32_NT");
+ }
}
-static void getSystemPageSize(FFPlatformSysinfo* info)
-{
+static void getSystemPageSize(FFPlatformSysinfo* info) {
SYSTEM_BASIC_INFORMATION sbi;
- if (NT_SUCCESS(NtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), NULL)))
+ if (NT_SUCCESS(NtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), NULL))) {
info->pageSize = sbi.PhysicalPageSize;
- else
+ } else {
info->pageSize = 4096;
+ }
}
-static void getSystemArchitecture(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;
+ 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;
}
}
}
-static void getCwd(FFPlatform* platform)
-{
+static void getCwd(FFPlatform* platform) {
PCURDIR cwd = &ffGetPeb()->ProcessParameters->CurrentDirectory;
ffStrbufSetNWS(&platform->cwd, cwd->DosPath.Length / sizeof(WCHAR), cwd->DosPath.Buffer);
ffStrbufReplaceAllC(&platform->cwd, '\\', '/');
ffStrbufEnsureEndsWithC(&platform->cwd, '/');
}
-void ffPlatformInitImpl(FFPlatform* platform)
-{
+void ffPlatformInitImpl(FFPlatform* platform) {
platform->pid = (uint32_t) (uintptr_t) ffGetTeb()->ClientId.UniqueProcess;
getExePath(platform);
getCwd(platform);
diff --git a/src/common/impl/FFlist.c b/src/common/impl/FFlist.c
index f389ced418..74df1e4681 100644
--- a/src/common/impl/FFlist.c
+++ b/src/common/impl/FFlist.c
@@ -3,32 +3,32 @@
#include
#include
-void* ffListAdd(FFlist* list)
-{
- if(list->length == list->capacity)
- ffListReserve(list, list->capacity == 0 ? FF_LIST_DEFAULT_ALLOC : list->capacity * 2);
+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, list->length - 1);
+ return ffListGet(list, elementSize, list->length - 1);
}
-bool ffListShift(FFlist* list, void* result)
-{
- if(list->length == 0)
+bool ffListShift(FFlist* list, uint32_t elementSize, void* result) {
+ if (list->length == 0) {
return false;
+ }
- memcpy(result, list->data, list->elementSize);
- memmove(list->data, list->data + list->elementSize, (size_t) list->elementSize * (list->length - 1));
+ memcpy(result, list->data, elementSize);
+ memmove(list->data, list->data + elementSize, (size_t) elementSize * (list->length - 1));
--list->length;
return true;
}
-bool ffListPop(FFlist* list, void* result)
-{
- if(list->length == 0)
+bool ffListPop(FFlist* list, uint32_t elementSize, void* result) {
+ if (list->length == 0) {
return false;
+ }
- memcpy(result, ffListGet(list, list->length - 1), list->elementSize);
+ memcpy(result, ffListGet(list, elementSize, list->length - 1), elementSize);
--list->length;
return true;
}
diff --git a/src/common/impl/FFstrbuf.c b/src/common/impl/FFstrbuf.c
index 5df26f7e0d..a530790556 100644
--- a/src/common/impl/FFstrbuf.c
+++ b/src/common/impl/FFstrbuf.c
@@ -8,119 +8,120 @@
char* CHAR_NULL_PTR = "";
-void ffStrbufInitA(FFstrbuf* strbuf, uint32_t allocate)
-{
+void ffStrbufInitA(FFstrbuf* strbuf, uint32_t allocate) {
strbuf->allocated = allocate;
- if(strbuf->allocated > 0)
+ if (strbuf->allocated > 0) {
strbuf->chars = (char*) malloc(sizeof(char) * strbuf->allocated);
+ }
- //This will set the length to zero and the null byte.
+ // This will set the length to zero and the null byte.
ffStrbufClear(strbuf);
}
-void ffStrbufInitVF(FFstrbuf* strbuf, const char* format, va_list arguments)
-{
+void ffStrbufInitVF(FFstrbuf* strbuf, const char* format, va_list arguments) {
assert(format != NULL);
char* buffer = NULL;
int len = vasprintf(&buffer, format, arguments);
assert(len >= 0);
- ffStrbufInitMoveNS(strbuf, (uint32_t)len, buffer);
+ ffStrbufInitMoveNS(strbuf, (uint32_t) len, buffer);
}
// Takes ownership of `heapStr`. The caller must not free `heapStr` after calling this
// function; the memory will be managed and freed via the associated FFstrbuf.
-void ffStrbufInitMoveNS(FFstrbuf* strbuf, uint32_t length, char* heapStr)
-{
+void ffStrbufInitMoveNS(FFstrbuf* strbuf, uint32_t length, char* heapStr) {
assert(heapStr != NULL);
strbuf->length = length;
size_t allocSize = ffMallocUsableSize(heapStr);
- if (allocSize == 0)
+ if (allocSize == 0) {
allocSize = length + 1;
- else if (allocSize > UINT32_MAX)
+ } else if (allocSize > UINT32_MAX) {
allocSize = UINT32_MAX;
+ }
strbuf->allocated = (uint32_t) allocSize;
strbuf->chars = heapStr;
}
-void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free)
-{
- if(ffStrbufGetFree(strbuf) >= free && !(strbuf->allocated == 0 && strbuf->length > 0))
+void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free) {
+ if (ffStrbufGetFree(strbuf) >= free && !(strbuf->allocated == 0 && strbuf->length > 0)) {
return;
+ }
uint32_t allocate = strbuf->allocated;
- if(allocate < FASTFETCH_STRBUF_DEFAULT_ALLOC)
+ if (allocate < FASTFETCH_STRBUF_DEFAULT_ALLOC) {
allocate = FASTFETCH_STRBUF_DEFAULT_ALLOC;
+ }
- while((strbuf->length + free + 1) > allocate) // + 1 for the null byte
+ while ((strbuf->length + free + 1) > allocate) { // + 1 for the null byte
allocate *= 2;
+ }
- if(strbuf->allocated == 0)
- {
+ if (strbuf->allocated == 0) {
char* newbuf = malloc(sizeof(*strbuf->chars) * allocate);
- if(strbuf->length == 0)
+ if (strbuf->length == 0) {
*newbuf = '\0';
- else
+ } else {
memcpy(newbuf, strbuf->chars, strbuf->length + 1);
+ }
strbuf->chars = newbuf;
- }
- else
+ } else {
strbuf->chars = realloc(strbuf->chars, sizeof(*strbuf->chars) * allocate);
+ }
strbuf->allocated = allocate;
}
// Ensure that at least `free` bytes are available in the buffer besides the current length
// for an empty buffer, free + 1 length memory will be allocated(+1 for the NUL)
-void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free)
-{
+void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free) {
uint32_t oldFree = ffStrbufGetFree(strbuf);
- if (oldFree >= free && !(strbuf->allocated == 0 && strbuf->length > 0))
+ if (oldFree >= free && !(strbuf->allocated == 0 && strbuf->length > 0)) {
return;
+ }
uint32_t newCap = strbuf->allocated + (free - oldFree);
- if(strbuf->allocated == 0)
- {
+ if (strbuf->allocated == 0) {
newCap += strbuf->length + 1;
char* newbuf = malloc(sizeof(*strbuf->chars) * newCap);
- if(strbuf->length == 0)
+ if (strbuf->length == 0) {
*newbuf = '\0';
- else
+ } else {
memcpy(newbuf, strbuf->chars, strbuf->length + 1);
+ }
strbuf->chars = newbuf;
- }
- else
+ } else {
strbuf->chars = realloc(strbuf->chars, sizeof(*strbuf->chars) * newCap);
+ }
strbuf->allocated = newCap;
}
-void ffStrbufClear(FFstrbuf* strbuf)
-{
+void ffStrbufClear(FFstrbuf* strbuf) {
assert(strbuf != NULL);
- if(strbuf->allocated == 0)
+ if (strbuf->allocated == 0) {
strbuf->chars = CHAR_NULL_PTR;
- else
+ } else {
strbuf->chars[0] = '\0';
+ }
strbuf->length = 0;
}
-void ffStrbufAppendC(FFstrbuf* strbuf, char c)
-{
+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;
+void ffStrbufAppendNC(FFstrbuf* strbuf, uint32_t num, char c) {
+ if (num == 0) {
+ return;
+ }
ffStrbufEnsureFree(strbuf, num);
memset(&strbuf->chars[strbuf->length], c, num);
@@ -128,10 +129,10 @@ void ffStrbufAppendNC(FFstrbuf* strbuf, uint32_t num, char c)
strbuf->chars[strbuf->length] = '\0';
}
-void ffStrbufAppendNS(FFstrbuf* strbuf, uint32_t length, const char* value)
-{
- if(value == NULL || 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);
@@ -139,26 +140,25 @@ void ffStrbufAppendNS(FFstrbuf* strbuf, uint32_t length, const char* value)
strbuf->chars[strbuf->length] = '\0';
}
-void ffStrbufAppendTransformS(FFstrbuf* strbuf, const char* value, int(*transformFunc)(int))
-{
- if(value == NULL)
+void ffStrbufAppendTransformS(FFstrbuf* strbuf, const char* value, int (*transformFunc)(int)) {
+ if (value == NULL) {
return;
+ }
- //Ensure capacity > 0 or the modification below will fail
+ // Ensure capacity > 0 or the modification below will fail
uint32_t length = (uint32_t) strlen(value);
- if(length == 0)
+ if (length == 0) {
return;
+ }
ffStrbufEnsureFree(strbuf, length);
- for(uint32_t i = 0; value[i] != '\0'; i++)
- {
+ for (uint32_t i = 0; value[i] != '\0'; i++) {
strbuf->chars[strbuf->length++] = (char) transformFunc(value[i]);
}
strbuf->chars[strbuf->length] = '\0';
}
-void ffStrbufAppendVF(FFstrbuf* strbuf, const char* format, va_list arguments)
-{
+void ffStrbufAppendVF(FFstrbuf* strbuf, const char* format, va_list arguments) {
assert(format != NULL);
va_list copy;
@@ -167,39 +167,39 @@ void ffStrbufAppendVF(FFstrbuf* strbuf, const char* format, va_list arguments)
uint32_t free = ffStrbufGetFree(strbuf);
int written = vsnprintf(strbuf->chars + strbuf->length, strbuf->allocated > 0 ? free + 1 : 0, format, arguments);
- if(written > 0 && (uint32_t) written > free)
- {
+ if (written > 0 && (uint32_t) written > free) {
ffStrbufEnsureFree(strbuf, (uint32_t) written);
written = vsnprintf(strbuf->chars + strbuf->length, (uint32_t) written + 1, format, copy);
}
va_end(copy);
- if(written > 0)
+ if (written > 0) {
strbuf->length += (uint32_t) written;
+ }
}
-const char* ffStrbufAppendSUntilC(FFstrbuf* strbuf, const char* value, char until)
-{
- if(value == NULL)
+const char* ffStrbufAppendSUntilC(FFstrbuf* strbuf, const char* value, char until) {
+ if (value == NULL) {
return NULL;
+ }
const char* end = strchr(value, until);
- if(end == NULL)
+ if (end == NULL) {
ffStrbufAppendS(strbuf, value);
- else
+ } else {
ffStrbufAppendNS(strbuf, (uint32_t) (end - value), value);
+ }
return end;
}
-void ffStrbufSetF(FFstrbuf* strbuf, const char* format, ...)
-{
+void ffStrbufSetF(FFstrbuf* strbuf, const char* format, ...) {
assert(format != NULL);
va_list arguments;
va_start(arguments, format);
- if(strbuf->allocated == 0) {
+ if (strbuf->allocated == 0) {
ffStrbufInitVF(strbuf, format, arguments);
va_end(arguments);
return;
@@ -210,8 +210,7 @@ void ffStrbufSetF(FFstrbuf* strbuf, const char* format, ...)
va_end(arguments);
}
-void ffStrbufAppendF(FFstrbuf* strbuf, const char* format, ...)
-{
+void ffStrbufAppendF(FFstrbuf* strbuf, const char* format, ...) {
assert(format != NULL);
va_list arguments;
@@ -220,10 +219,10 @@ void ffStrbufAppendF(FFstrbuf* strbuf, const char* format, ...)
va_end(arguments);
}
-void ffStrbufPrependNS(FFstrbuf* strbuf, uint32_t length, const char* value)
-{
- if(value == NULL || length == 0)
+void ffStrbufPrependNS(FFstrbuf* strbuf, uint32_t length, const char* value) {
+ if (value == NULL || length == 0) {
return;
+ }
ffStrbufEnsureFree(strbuf, length);
memmove(strbuf->chars + length, strbuf->chars, strbuf->length + 1); // + 1 for the null byte
@@ -231,53 +230,50 @@ void ffStrbufPrependNS(FFstrbuf* strbuf, uint32_t length, const char* value)
strbuf->length += length;
}
-void ffStrbufPrependC(FFstrbuf* strbuf, char c)
-{
+void ffStrbufPrependC(FFstrbuf* strbuf, char c) {
ffStrbufEnsureFree(strbuf, 1);
memmove(strbuf->chars + 1, strbuf->chars, strbuf->length + 1); // + 1 for the null byte
strbuf->chars[0] = c;
strbuf->length += 1;
}
-void ffStrbufSetNS(FFstrbuf* strbuf, uint32_t length, const char* value)
-{
+void ffStrbufSetNS(FFstrbuf* strbuf, uint32_t length, const char* value) {
assert(strbuf != NULL);
- if (length == 0)
- {
+ if (length == 0) {
ffStrbufClear(strbuf);
return;
}
assert(value != NULL);
- if (strbuf->allocated < length + 1)
- {
- if (strbuf->allocated > 0)
+ if (strbuf->allocated <= length) {
+ char* newBuf = malloc(sizeof(char) * (length + 1));
+ memcpy(newBuf, value, length);
+ if (strbuf->allocated > 0) {
free(strbuf->chars);
+ }
+ strbuf->chars = newBuf;
strbuf->allocated = length + 1;
- strbuf->chars = malloc(sizeof(char) * strbuf->allocated);
+ } else {
+ memmove(strbuf->chars, value, length);
}
- memcpy(strbuf->chars, value, length);
strbuf->length = length;
strbuf->chars[length] = '\0';
}
-void ffStrbufSet(FFstrbuf* strbuf, const FFstrbuf* value)
-{
+void ffStrbufSet(FFstrbuf* strbuf, const FFstrbuf* value) {
assert(value && value != strbuf);
- if (value->length == 0)
- {
+ if (value->length == 0) {
ffStrbufClear(strbuf);
return;
}
if (value->allocated == 0) // static string
{
- if (strbuf->allocated != 0)
- {
+ if (strbuf->allocated != 0) {
free(strbuf->chars);
strbuf->allocated = 0;
}
@@ -288,21 +284,22 @@ void ffStrbufSet(FFstrbuf* strbuf, const FFstrbuf* value)
ffStrbufSetNS(strbuf, value->length, value->chars);
}
-void ffStrbufTrimLeft(FFstrbuf* strbuf, char c)
-{
- if(strbuf->length == 0)
+void ffStrbufTrimLeft(FFstrbuf* strbuf, char c) {
+ if (strbuf->length == 0) {
return;
+ }
uint32_t index = 0;
- while(index < strbuf->length && strbuf->chars[index] == c)
+ while (index < strbuf->length && strbuf->chars[index] == c) {
++index;
+ }
- if(index == 0)
+ if (index == 0) {
return;
+ }
- if(strbuf->allocated == 0)
- {
- //static string
+ if (strbuf->allocated == 0) {
+ // static string
strbuf->length -= index;
strbuf->chars += index;
return;
@@ -313,21 +310,21 @@ void ffStrbufTrimLeft(FFstrbuf* strbuf, char c)
strbuf->chars[strbuf->length] = '\0';
}
-void ffStrbufTrimRight(FFstrbuf* strbuf, char c)
-{
- if (strbuf->length == 0)
+void ffStrbufTrimRight(FFstrbuf* strbuf, char c) {
+ if (strbuf->length == 0) {
return;
+ }
- if (!ffStrbufEndsWithC(strbuf, c))
+ if (!ffStrbufEndsWithC(strbuf, c)) {
return;
+ }
- do
+ do {
--strbuf->length;
- while (ffStrbufEndsWithC(strbuf, c));
+ } while (ffStrbufEndsWithC(strbuf, c));
- if (strbuf->allocated == 0)
- {
- //static string
+ if (strbuf->allocated == 0) {
+ // static string
ffStrbufInitNS(strbuf, strbuf->length, strbuf->chars);
return;
}
@@ -335,21 +332,22 @@ void ffStrbufTrimRight(FFstrbuf* strbuf, char c)
strbuf->chars[strbuf->length] = '\0';
}
-void ffStrbufTrimLeftSpace(FFstrbuf* strbuf)
-{
- if(strbuf->length == 0)
+void ffStrbufTrimLeftSpace(FFstrbuf* strbuf) {
+ if (strbuf->length == 0) {
return;
+ }
uint32_t index = 0;
- while(index < strbuf->length && isspace(strbuf->chars[index]))
+ while (index < strbuf->length && isspace(strbuf->chars[index])) {
++index;
+ }
- if(index == 0)
+ if (index == 0) {
return;
+ }
- if(strbuf->allocated == 0)
- {
- //static string
+ if (strbuf->allocated == 0) {
+ // static string
strbuf->length -= index;
strbuf->chars += index;
return;
@@ -360,21 +358,21 @@ void ffStrbufTrimLeftSpace(FFstrbuf* strbuf)
strbuf->chars[strbuf->length] = '\0';
}
-void ffStrbufTrimRightSpace(FFstrbuf* strbuf)
-{
- if (strbuf->length == 0)
+void ffStrbufTrimRightSpace(FFstrbuf* strbuf) {
+ if (strbuf->length == 0) {
return;
+ }
- if (!ffStrbufEndsWithFn(strbuf, isspace))
+ if (!ffStrbufEndsWithFn(strbuf, isspace)) {
return;
+ }
- do
+ do {
--strbuf->length;
- while (ffStrbufEndsWithFn(strbuf, isspace));
+ } while (ffStrbufEndsWithFn(strbuf, isspace));
- if (strbuf->allocated == 0)
- {
- //static string
+ if (strbuf->allocated == 0) {
+ // static string
ffStrbufInitNS(strbuf, strbuf->length, strbuf->chars);
return;
}
@@ -382,13 +380,12 @@ void ffStrbufTrimRightSpace(FFstrbuf* strbuf)
strbuf->chars[strbuf->length] = '\0';
}
-bool ffStrbufRemoveSubstr(FFstrbuf* strbuf, uint32_t startIndex, uint32_t endIndex)
-{
- if(startIndex > strbuf->length || startIndex >= endIndex)
+bool ffStrbufRemoveSubstr(FFstrbuf* strbuf, uint32_t startIndex, uint32_t endIndex) {
+ if (startIndex > strbuf->length || startIndex >= endIndex) {
return false;
+ }
- if(endIndex > strbuf->length)
- {
+ if (endIndex > strbuf->length) {
ffStrbufSubstrBefore(strbuf, startIndex);
return true;
}
@@ -400,77 +397,73 @@ bool ffStrbufRemoveSubstr(FFstrbuf* strbuf, uint32_t startIndex, uint32_t endInd
return true;
}
-void ffStrbufRemoveS(FFstrbuf* strbuf, const char* str)
-{
+void ffStrbufRemoveS(FFstrbuf* strbuf, const char* str) {
uint32_t stringLength = (uint32_t) strlen(str);
- for(uint32_t i = ffStrbufNextIndexS(strbuf, 0, str); i < strbuf->length; i = ffStrbufNextIndexS(strbuf, i, str))
+ for (uint32_t i = ffStrbufNextIndexS(strbuf, 0, str); i < strbuf->length; i = ffStrbufNextIndexS(strbuf, i, str)) {
ffStrbufRemoveSubstr(strbuf, i, i + stringLength);
+ }
}
-void ffStrbufRemoveStrings(FFstrbuf* strbuf, uint32_t numStrings, const char* strings[])
-{
- for(uint32_t i = 0; i < numStrings; i++)
+void ffStrbufRemoveStrings(FFstrbuf* strbuf, uint32_t numStrings, const char* strings[]) {
+ for (uint32_t i = 0; i < numStrings; i++) {
ffStrbufRemoveS(strbuf, strings[i]);
+ }
}
-uint32_t ffStrbufNextIndexC(const FFstrbuf* strbuf, uint32_t start, char c)
-{
+uint32_t ffStrbufNextIndexC(const FFstrbuf* strbuf, uint32_t start, char c) {
assert(start <= strbuf->length);
- const char* ptr = (const char*)memchr(strbuf->chars + start, c, strbuf->length - start);
- return ptr ? (uint32_t)(ptr - strbuf->chars) : strbuf->length;
+ const char* ptr = (const char*) memchr(strbuf->chars + start, c, strbuf->length - start);
+ return ptr ? (uint32_t) (ptr - strbuf->chars) : strbuf->length;
}
-uint32_t ffStrbufNextIndexS(const FFstrbuf* strbuf, uint32_t start, const char* str)
-{
+uint32_t ffStrbufNextIndexS(const FFstrbuf* strbuf, uint32_t start, const char* str) {
assert(start <= strbuf->length);
const char* ptr = strstr(strbuf->chars + start, str);
- return ptr ? (uint32_t)(ptr - strbuf->chars) : strbuf->length;
+ return ptr ? (uint32_t) (ptr - strbuf->chars) : strbuf->length;
}
-uint32_t ffStrbufPreviousIndexC(const FFstrbuf* strbuf, uint32_t start, char c)
-{
+uint32_t ffStrbufPreviousIndexC(const FFstrbuf* strbuf, uint32_t start, char c) {
assert(start <= strbuf->length);
- //We need to loop one higher than the actual index, because uint32_t is guaranteed to be >= 0, so this statement would always be true
- for(uint32_t i = start + 1; i > 0; i--)
- {
- if(strbuf->chars[i - 1] == c)
+ // We need to loop one higher than the actual index, because uint32_t is guaranteed to be >= 0, so this statement would always be true
+ for (uint32_t i = start + 1; i > 0; i--) {
+ if (strbuf->chars[i - 1] == c) {
return i - 1;
+ }
}
return strbuf->length;
}
-void ffStrbufReplaceAllC(FFstrbuf* strbuf, char find, char replace)
-{
- if (strbuf->length == 0)
+void ffStrbufReplaceAllC(FFstrbuf* strbuf, char find, char replace) {
+ if (strbuf->length == 0) {
return;
+ }
ffStrbufEnsureFree(strbuf, 0);
for (
- char *current_pos = memchr(strbuf->chars, find, strbuf->length);
+ char* current_pos = memchr(strbuf->chars, find, strbuf->length);
current_pos;
current_pos = memchr(
current_pos + 1,
find,
- strbuf->length - (uint32_t)(current_pos + 1 - strbuf->chars)
- )
- )
+ strbuf->length - (uint32_t) (current_pos + 1 - strbuf->chars))) {
*current_pos = replace;
+ }
}
-bool ffStrbufSubstrBefore(FFstrbuf* strbuf, uint32_t index)
-{
- if(strbuf->length <= index)
+bool ffStrbufSubstrBefore(FFstrbuf* strbuf, uint32_t index) {
+ if (strbuf->length <= index) {
return false;
+ }
- if(strbuf->allocated == 0)
- {
- //static string
- if (index < strbuf->length)
+ if (strbuf->allocated == 0) {
+ // static string
+ if (index < strbuf->length) {
ffStrbufInitNS(strbuf, index, strbuf->chars);
+ }
return true;
}
@@ -479,17 +472,14 @@ bool ffStrbufSubstrBefore(FFstrbuf* strbuf, uint32_t index)
return true;
}
-bool ffStrbufSubstrAfter(FFstrbuf* strbuf, uint32_t index)
-{
- if(index >= strbuf->length)
- {
+bool ffStrbufSubstrAfter(FFstrbuf* strbuf, uint32_t index) {
+ if (index >= strbuf->length) {
ffStrbufClear(strbuf);
return true;
}
- if(strbuf->allocated == 0)
- {
- //static string
+ if (strbuf->allocated == 0) {
+ // static string
strbuf->length -= index + 1;
strbuf->chars += index + 1;
return true;
@@ -501,48 +491,51 @@ bool ffStrbufSubstrAfter(FFstrbuf* strbuf, uint32_t index)
return true;
}
-bool ffStrbufSubstrAfterFirstC(FFstrbuf* strbuf, char c)
-{
+bool ffStrbufSubstrAfterFirstC(FFstrbuf* strbuf, char c) {
uint32_t index = ffStrbufFirstIndexC(strbuf, c);
- if(index >= strbuf->length)
+ if (index >= strbuf->length) {
return false;
+ }
ffStrbufSubstrAfter(strbuf, index);
return true;
}
-bool ffStrbufSubstrAfterFirstS(FFstrbuf* strbuf, const char* str)
-{
- if(*str == '\0')
+bool ffStrbufSubstrAfterFirstS(FFstrbuf* strbuf, const char* str) {
+ if (*str == '\0') {
return false;
+ }
uint32_t index = ffStrbufFirstIndexS(strbuf, str) + (uint32_t) strlen(str) - 1; // -1, because firstIndexS is already pointing to str[0], we want to add only the remaining length
- if(index >= strbuf->length)
+ if (index >= strbuf->length) {
return false;
+ }
ffStrbufSubstrAfter(strbuf, index);
return true;
}
-bool ffStrbufSubstrAfterLastC(FFstrbuf* strbuf, char c)
-{
+bool ffStrbufSubstrAfterLastC(FFstrbuf* strbuf, char c) {
uint32_t index = ffStrbufLastIndexC(strbuf, c);
- if(index >= strbuf->length)
+ if (index >= strbuf->length) {
return false;
+ }
ffStrbufSubstrAfter(strbuf, index);
return true;
}
-bool ffStrbufSubstr(FFstrbuf* strbuf, uint32_t start, uint32_t end)
-{
- if (__builtin_expect(start >= end, false))
- {
+bool ffStrbufSubstr(FFstrbuf* strbuf, uint32_t start, uint32_t end) {
+ if (__builtin_expect(start >= end, false)) {
ffStrbufClear(strbuf);
return false;
}
- if (__builtin_expect(start == 0, false)) return ffStrbufSubstrBefore(strbuf, end);
- if (__builtin_expect(end >= strbuf->length, false)) return ffStrbufSubstrAfter(strbuf, start - 1);
+ if (__builtin_expect(start == 0, false)) {
+ return ffStrbufSubstrBefore(strbuf, end);
+ }
+ if (__builtin_expect(end >= strbuf->length, false)) {
+ return ffStrbufSubstrAfter(strbuf, start - 1);
+ }
uint32_t len = end - start;
ffStrbufEnsureFixedLengthFree(strbuf, len); // In case of static string
@@ -553,24 +546,20 @@ bool ffStrbufSubstr(FFstrbuf* strbuf, uint32_t start, uint32_t end)
return true;
}
-uint32_t ffStrbufCountC(const FFstrbuf* strbuf, char c)
-{
+uint32_t ffStrbufCountC(const FFstrbuf* strbuf, char c) {
uint32_t result = 0;
- for(uint32_t i = 0; i < strbuf->length; i++)
- {
- if(strbuf->chars[i] == c)
+ for (uint32_t i = 0; i < strbuf->length; i++) {
+ if (strbuf->chars[i] == c) {
result++;
+ }
}
return result;
}
-
-bool ffStrbufRemoveIgnCaseEndS(FFstrbuf* strbuf, const char* end)
-{
+bool ffStrbufRemoveIgnCaseEndS(FFstrbuf* strbuf, const char* end) {
uint32_t endLength = (uint32_t) strlen(end);
- if(ffStrbufEndsWithIgnCaseNS(strbuf, endLength, end))
- {
+ if (ffStrbufEndsWithIgnCaseNS(strbuf, endLength, end)) {
ffStrbufSubstrBefore(strbuf, strbuf->length - endLength);
return true;
}
@@ -578,49 +567,43 @@ bool ffStrbufRemoveIgnCaseEndS(FFstrbuf* strbuf, const char* end)
return false;
}
-bool ffStrbufEnsureEndsWithC(FFstrbuf* strbuf, char c)
-{
- if(ffStrbufEndsWithC(strbuf, c))
+bool ffStrbufEnsureEndsWithC(FFstrbuf* strbuf, char c) {
+ if (ffStrbufEndsWithC(strbuf, c)) {
return false;
+ }
ffStrbufAppendC(strbuf, c);
return true;
}
-void ffStrbufWriteTo(const FFstrbuf* strbuf, FILE* file)
-{
+void ffStrbufWriteTo(const FFstrbuf* strbuf, FILE* file) {
fwrite(strbuf->chars, sizeof(*strbuf->chars), strbuf->length, file);
}
-void ffStrbufPutTo(const FFstrbuf* strbuf, FILE* file)
-{
+void ffStrbufPutTo(const FFstrbuf* strbuf, FILE* file) {
ffStrbufWriteTo(strbuf, file);
fputc('\n', file);
}
-double ffStrbufToDouble(const FFstrbuf* strbuf, double defaultValue)
-{
+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)
-{
+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;
+ return str_end == strbuf->chars ? defaultValue : (uint64_t) result;
}
-int64_t ffStrbufToSInt(const FFstrbuf* strbuf, int64_t defaultValue)
-{
+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;
+ return str_end == strbuf->chars ? defaultValue : (int64_t) result;
}
-void ffStrbufAppendSInt(FFstrbuf* strbuf, int64_t value)
-{
+void ffStrbufAppendSInt(FFstrbuf* strbuf, int64_t value) {
ffStrbufEnsureFree(strbuf, 21); // Required by yyjson_write_number
char* start = strbuf->chars + strbuf->length;
@@ -630,11 +613,10 @@ void ffStrbufAppendSInt(FFstrbuf* strbuf, int64_t value)
assert(end != NULL);
- strbuf->length += (uint32_t)(end - start);
+ strbuf->length += (uint32_t) (end - start);
}
-void ffStrbufAppendUInt(FFstrbuf* strbuf, uint64_t value)
-{
+void ffStrbufAppendUInt(FFstrbuf* strbuf, uint64_t value) {
ffStrbufEnsureFree(strbuf, 21); // Required by yyjson_write_number
char* start = strbuf->chars + strbuf->length;
@@ -644,54 +626,49 @@ void ffStrbufAppendUInt(FFstrbuf* strbuf, uint64_t value)
assert(end != NULL);
- strbuf->length += (uint32_t)(end - start);
+ strbuf->length += (uint32_t) (end - start);
}
-void ffStrbufAppendDouble(FFstrbuf* strbuf, double value, int8_t precision, bool trailingZeros)
-{
+void ffStrbufAppendDouble(FFstrbuf* strbuf, double value, int8_t precision, bool trailingZeros) {
assert(precision <= 15); // yyjson_write_number supports up to 15 digits after the decimal point
ffStrbufEnsureFree(strbuf, 40); // Required by yyjson_write_number
char* start = strbuf->chars + strbuf->length;
- if (precision == 0)
+ if (precision == 0) {
value = round(value);
+ }
yyjson_val val = {};
unsafe_yyjson_set_double(&val, value);
- if (precision > 0)
+ if (precision > 0) {
unsafe_yyjson_set_fp_to_fixed(&val, precision);
+ }
// Write at most digits after the decimal point; doesn't append trailing zeros
char* end = yyjson_write_number(&val, start);
assert(end > start);
- strbuf->length += (uint32_t)(end - start);
+ strbuf->length += (uint32_t) (end - start);
- if (__builtin_expect(value > 1e21 || value < -1e21, false))
- {
+ if (__builtin_expect(value > 1e21 || value < -1e21, false)) {
// If the value is too large, yyjson_write_number will write it in scientific notation
return;
}
- if (trailingZeros)
- {
- if (precision > 1)
- {
- for (char* p = end - 1; *p != '.' && p > start; --p)
+ if (trailingZeros) {
+ if (precision > 1) {
+ for (char* p = end - 1; *p != '.' && p > start; --p) {
--precision;
- if (precision > 0)
+ }
+ if (precision > 0) {
ffStrbufAppendNC(strbuf, (uint32_t) precision, '0');
- }
- else if (precision == 0 || (precision < 0 && end[-1] == '0'))
- {
+ }
+ } else if (precision == 0 || (precision < 0 && end[-1] == '0')) {
goto removeDecimalPoint;
}
- }
- else
- {
- if (end[-1] == '0')
- {
+ } else {
+ if (end[-1] == '0') {
removeDecimalPoint:
// yyjson always appends ".0" to make it a float point number. We need to remove it
strbuf->length -= 2;
@@ -700,23 +677,25 @@ void ffStrbufAppendDouble(FFstrbuf* strbuf, double value, int8_t precision, bool
}
}
-void ffStrbufUpperCase(FFstrbuf* strbuf)
-{
- for (uint32_t i = 0; i < strbuf->length; ++i)
+void ffStrbufUpperCase(FFstrbuf* strbuf) {
+ for (uint32_t i = 0; i < strbuf->length; ++i) {
strbuf->chars[i] = (char) toupper(strbuf->chars[i]);
+ }
}
-void ffStrbufLowerCase(FFstrbuf* strbuf)
-{
- for (uint32_t i = 0; i < strbuf->length; ++i)
+void ffStrbufLowerCase(FFstrbuf* strbuf) {
+ for (uint32_t i = 0; i < strbuf->length; ++i) {
strbuf->chars[i] = (char) tolower(strbuf->chars[i]);
+ }
}
-void ffStrbufInsertNC(FFstrbuf* strbuf, uint32_t index, uint32_t num, char c)
-{
- if(num == 0) return;
- if (index >= strbuf->length)
+void ffStrbufInsertNC(FFstrbuf* strbuf, uint32_t index, uint32_t num, char c) {
+ if (num == 0) {
+ return;
+ }
+ if (index >= strbuf->length) {
index = strbuf->length;
+ }
ffStrbufEnsureFree(strbuf, num);
memmove(strbuf->chars + index + num, strbuf->chars + index, strbuf->length - index + 1);
@@ -724,66 +703,70 @@ void ffStrbufInsertNC(FFstrbuf* strbuf, uint32_t index, uint32_t num, char c)
strbuf->length += num;
}
-bool ffStrbufGetdelim(char** lineptr, size_t* n, char delimiter, FFstrbuf* buffer)
-{
+bool ffStrbufGetdelim(char** lineptr, size_t* n, char delimiter, FFstrbuf* buffer) {
assert(lineptr && n && buffer);
assert(buffer->allocated > 0 || (buffer->allocated == 0 && buffer->length == 0));
assert(!*lineptr || (*lineptr >= buffer->chars && *lineptr <= buffer->chars + buffer->length));
const char* pBufferEnd = buffer->chars + buffer->length;
- if (!*lineptr)
+ if (!*lineptr) {
*lineptr = buffer->chars;
- else
- {
+ } else {
*lineptr += *n;
- if (*lineptr >= pBufferEnd) // non-empty last line
+ if (*lineptr >= pBufferEnd) { // non-empty last line
return false;
+ }
**lineptr = delimiter;
++*lineptr;
}
- if (*lineptr >= pBufferEnd) // empty last line
+ if (*lineptr >= pBufferEnd) { // empty last line
return false;
+ }
size_t remaining = (size_t) (pBufferEnd - *lineptr);
char* ending = memchr(*lineptr, delimiter, remaining);
- if (ending)
- {
+ if (ending) {
*n = (size_t) (ending - *lineptr);
*ending = '\0';
- }
- else
+ } else {
*n = remaining;
+ }
return true;
}
-void ffStrbufGetdelimRestore(char** lineptr, size_t* n, char delimiter, FFstrbuf* buffer)
-{
+void ffStrbufGetdelimRestore(char** lineptr, size_t* n, char delimiter, FFstrbuf* buffer) {
assert(buffer && lineptr && n);
assert(buffer->allocated > 0 || (buffer->allocated == 0 && buffer->length == 0));
assert(!*lineptr || (*lineptr >= buffer->chars && *lineptr <= buffer->chars + buffer->length));
- if (!*lineptr)
+ if (!*lineptr) {
return;
+ }
*lineptr += *n;
- if (*lineptr < buffer->chars + buffer->length)
+ if (*lineptr < buffer->chars + buffer->length) {
**lineptr = delimiter;
+ }
}
-bool ffStrbufRemoveDupWhitespaces(FFstrbuf* strbuf)
-{
- if (strbuf->allocated == 0) return false; // Doesn't work with static strings
+bool ffStrbufRemoveDupWhitespaces(FFstrbuf* strbuf) {
+ if (strbuf->allocated == 0) {
+ return false; // Doesn't work with static strings
+ }
bool changed = false;
- for (uint32_t i = 0; i < strbuf->length; i++)
- {
- if (strbuf->chars[i] != ' ') continue;
+ for (uint32_t i = 0; i < strbuf->length; i++) {
+ if (strbuf->chars[i] != ' ') {
+ continue;
+ }
i++;
uint32_t j = i;
for (; j < strbuf->length && strbuf->chars[j] == ' '; j++);
- if (j == i) continue;
+ if (j == i) {
+ continue;
+ }
memmove(&strbuf->chars[i], &strbuf->chars[j], strbuf->length - j + 1);
strbuf->length -= j - i;
changed = true;
@@ -797,23 +780,25 @@ bool ffStrbufRemoveDupWhitespaces(FFstrbuf* strbuf)
/// @param compLength The length of the separated string to check.
/// @param comp The separated string to check.
/// @param separator The separator character.
-bool ffStrbufMatchSeparatedNS(const FFstrbuf* strbuf, uint32_t compLength, const char* comp, char separator)
-{
- if (strbuf->length == 0)
+bool ffStrbufMatchSeparatedNS(const FFstrbuf* strbuf, uint32_t compLength, const char* comp, char separator) {
+ if (strbuf->length == 0) {
return true;
+ }
- if (compLength == 0)
+ if (compLength == 0) {
return false;
+ }
- for (const char* p = comp; p < comp + compLength;)
- {
+ for (const char* p = comp; p < comp + compLength;) {
const char* colon = memchr(p, separator, compLength);
- if (colon == NULL)
+ if (colon == NULL) {
return strcmp(strbuf->chars, p) == 0;
+ }
uint32_t substrLength = (uint32_t) (colon - p);
- if (strbuf->length == substrLength && memcmp(strbuf->chars, p, substrLength) == 0)
+ if (strbuf->length == substrLength && memcmp(strbuf->chars, p, substrLength) == 0) {
return true;
+ }
p = colon + 1;
}
@@ -822,23 +807,25 @@ bool ffStrbufMatchSeparatedNS(const FFstrbuf* strbuf, uint32_t compLength, const
}
/// @brief Case insensitive version of ffStrbufMatchSeparatedNS.
-bool ffStrbufMatchSeparatedIgnCaseNS(const FFstrbuf* strbuf, uint32_t compLength, const char* comp, char separator)
-{
- if (strbuf->length == 0)
+bool ffStrbufMatchSeparatedIgnCaseNS(const FFstrbuf* strbuf, uint32_t compLength, const char* comp, char separator) {
+ if (strbuf->length == 0) {
return true;
+ }
- if (compLength == 0)
+ if (compLength == 0) {
return false;
+ }
- for (const char* p = comp; p < comp + compLength;)
- {
+ for (const char* p = comp; p < comp + compLength;) {
const char* colon = memchr(p, separator, compLength);
- if (colon == NULL)
+ if (colon == NULL) {
return strcasecmp(strbuf->chars, p) == 0;
+ }
uint32_t substrLength = (uint32_t) (colon - p);
- if (strbuf->length == substrLength && strncasecmp(strbuf->chars, p, substrLength) == 0)
+ if (strbuf->length == substrLength && strncasecmp(strbuf->chars, p, substrLength) == 0) {
return true;
+ }
p = colon + 1;
}
@@ -846,31 +833,18 @@ bool ffStrbufMatchSeparatedIgnCaseNS(const FFstrbuf* strbuf, uint32_t compLength
return false;
}
-int ffStrbufAppendUtf32CodePoint(FFstrbuf* strbuf, uint32_t codepoint)
-{
+int ffStrbufAppendUtf32CodePoint(FFstrbuf* strbuf, uint32_t codepoint) {
if (codepoint <= 0x7F) {
- ffStrbufAppendC(strbuf, (char)codepoint);
+ ffStrbufAppendC(strbuf, (char) codepoint);
return 1;
} else if (codepoint <= 0x7FF) {
- ffStrbufAppendNS(strbuf, 2, (char[]){
- (char) (0xC0 | (codepoint >> 6)),
- (char) (0x80 | (codepoint & 0x3F))
- });
+ ffStrbufAppendNS(strbuf, 2, (char[]) { (char) (0xC0 | (codepoint >> 6)), (char) (0x80 | (codepoint & 0x3F)) });
return 2;
} else if (codepoint <= 0xFFFF) {
- ffStrbufAppendNS(strbuf, 3, (char[]){
- (char) (0xE0 | (codepoint >> 12)),
- (char) (0x80 | ((codepoint >> 6) & 0x3F)),
- (char) (0x80 | (codepoint & 0x3F))
- });
+ ffStrbufAppendNS(strbuf, 3, (char[]) { (char) (0xE0 | (codepoint >> 12)), (char) (0x80 | ((codepoint >> 6) & 0x3F)), (char) (0x80 | (codepoint & 0x3F)) });
return 3;
} else if (codepoint <= 0x10FFFF) {
- ffStrbufAppendNS(strbuf, 4, (char[]){
- (char) (0xF0 | (codepoint >> 18)),
- (char) (0x80 | ((codepoint >> 12) & 0x3F)),
- (char) (0x80 | ((codepoint >> 6) & 0x3F)),
- (char) (0x80 | (codepoint & 0x3F))
- });
+ ffStrbufAppendNS(strbuf, 4, (char[]) { (char) (0xF0 | (codepoint >> 18)), (char) (0x80 | ((codepoint >> 12) & 0x3F)), (char) (0x80 | ((codepoint >> 6) & 0x3F)), (char) (0x80 | (codepoint & 0x3F)) });
return 4;
}
@@ -883,16 +857,15 @@ int ffStrbufAppendUtf32CodePoint(FFstrbuf* strbuf, uint32_t codepoint)
/// @param compLength The length of the separated string to check.
/// @param comp The substring to check.
/// @param separator The separator character.
-bool ffStrbufSeparatedContainNS(const FFstrbuf* strbuf, uint32_t compLength, const char* comp, char separator)
-{
+bool ffStrbufSeparatedContainNS(const FFstrbuf* strbuf, uint32_t compLength, const char* comp, char separator) {
uint32_t startIndex = 0;
- while(startIndex < strbuf->length)
- {
+ while (startIndex < strbuf->length) {
uint32_t colonIndex = ffStrbufNextIndexC(strbuf, startIndex, separator);
uint32_t folderLength = colonIndex - startIndex;
- if (folderLength == compLength && memcmp(strbuf->chars + startIndex, comp, compLength) == 0)
+ if (folderLength == compLength && memcmp(strbuf->chars + startIndex, comp, compLength) == 0) {
return true;
+ }
startIndex = colonIndex + 1;
}
@@ -900,16 +873,15 @@ bool ffStrbufSeparatedContainNS(const FFstrbuf* strbuf, uint32_t compLength, con
return false;
}
-bool ffStrbufSeparatedContainIgnCaseNS(const FFstrbuf* strbuf, uint32_t compLength, const char* comp, char separator)
-{
+bool ffStrbufSeparatedContainIgnCaseNS(const FFstrbuf* strbuf, uint32_t compLength, const char* comp, char separator) {
uint32_t startIndex = 0;
- while(startIndex < strbuf->length)
- {
+ while (startIndex < strbuf->length) {
uint32_t colonIndex = ffStrbufNextIndexC(strbuf, startIndex, separator);
uint32_t folderLength = colonIndex - startIndex;
- if (folderLength == compLength && strncasecmp(strbuf->chars + startIndex, comp, compLength) == 0)
+ if (folderLength == compLength && strncasecmp(strbuf->chars + startIndex, comp, compLength) == 0) {
return true;
+ }
startIndex = colonIndex + 1;
}
@@ -917,12 +889,12 @@ bool ffStrbufSeparatedContainIgnCaseNS(const FFstrbuf* strbuf, uint32_t compLeng
return false;
}
-bool ffStrbufDecodeHexEscapeSequences(FFstrbuf* strbuf)
-{
+bool ffStrbufDecodeHexEscapeSequences(FFstrbuf* strbuf) {
assert(strbuf);
- if (strbuf->length < 4)
+ if (strbuf->length < 4) {
return false;
+ }
// Static string must be converted first.
assert(strbuf->allocated > 0);
@@ -931,18 +903,14 @@ bool ffStrbufDecodeHexEscapeSequences(FFstrbuf* strbuf)
uint32_t read = 0;
uint32_t write = 0;
- while (read < strbuf->length)
- {
+ while (read < strbuf->length) {
if (
read + 3 < strbuf->length &&
strbuf->chars[read] == '\\' &&
- strbuf->chars[read + 1] == 'x'
- )
- {
+ strbuf->chars[read + 1] == 'x') {
int8_t hi = ffHexCharToInt(strbuf->chars[read + 2]);
int8_t lo = ffHexCharToInt(strbuf->chars[read + 3]);
- if (hi >= 0 && lo >= 0)
- {
+ if (hi >= 0 && lo >= 0) {
strbuf->chars[write++] = (char) ((hi << 4) | lo);
read += 4;
changed = true;
diff --git a/src/common/impl/base64.c b/src/common/impl/base64.c
index 0567b75ed2..94f74f9e10 100644
--- a/src/common/impl/base64.c
+++ b/src/common/impl/base64.c
@@ -1,14 +1,12 @@
#include "common/base64.h"
// https://github.com/kostya/benchmarks/blob/master/base64/test-nolib.c#L145
-void ffBase64EncodeRaw(uint32_t size, const char *str, uint32_t *out_size, char *output)
-{
+void ffBase64EncodeRaw(uint32_t size, const char* str, uint32_t* out_size, char* output) {
static const char chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- char *out = output;
- const char *ends = str + (size - size % 3);
- while (str != ends)
- {
- uint32_t n = __builtin_bswap32(*(uint32_t *)str);
+ char* out = output;
+ const char* ends = str + (size - size % 3);
+ while (str != ends) {
+ uint32_t n = __builtin_bswap32(*(uint32_t*) str);
*out++ = chars[(n >> 26) & 63];
*out++ = chars[(n >> 20) & 63];
*out++ = chars[(n >> 14) & 63];
@@ -16,94 +14,94 @@ void ffBase64EncodeRaw(uint32_t size, const char *str, uint32_t *out_size, char
str += 3;
}
- if (size % 3 == 1)
- {
- uint64_t n = (uint64_t)*str << 16;
+ if (size % 3 == 1) {
+ uint64_t n = (uint64_t) *str << 16;
*out++ = chars[(n >> 18) & 63];
*out++ = chars[(n >> 12) & 63];
*out++ = '=';
*out++ = '=';
- }
- else if (size % 3 == 2)
- {
- uint64_t n = (uint64_t)*str++ << 16;
- n |= (uint64_t)*str << 8;
+ } else if (size % 3 == 2) {
+ uint64_t n = (uint64_t) *str++ << 16;
+ n |= (uint64_t) *str << 8;
*out++ = chars[(n >> 18) & 63];
*out++ = chars[(n >> 12) & 63];
*out++ = chars[(n >> 6) & 63];
*out++ = '=';
}
*out = '\0';
- *out_size = (uint32_t)(out - output);
+ *out_size = (uint32_t) (out - output);
}
static uint8_t decode_table[256];
-void init_decode_table()
-{
+void init_decode_table() {
uint8_t ch = 0;
- do
- {
+ do {
int32_t code = -1;
- if (ch >= 'A' && ch <= 'Z')
+ if (ch >= 'A' && ch <= 'Z') {
code = ch - 0x41;
- if (ch >= 'a' && ch <= 'z')
+ }
+ if (ch >= 'a' && ch <= 'z') {
code = ch - 0x47;
- if (ch >= '0' && ch <= '9')
+ }
+ if (ch >= '0' && ch <= '9') {
code = ch + 0x04;
- if (ch == '+' || ch == '-')
+ }
+ if (ch == '+' || ch == '-') {
code = 0x3E;
- if (ch == '/' || ch == '_')
+ }
+ if (ch == '/' || ch == '_') {
code = 0x3F;
+ }
decode_table[ch] = (uint8_t) code;
} while (ch++ < 0xFF);
}
#define next_char(x) uint8_t x = decode_table[(uint8_t) *str++];
-bool ffBase64DecodeRaw(uint32_t size, const char *str, uint32_t *out_size, char *output)
-{
- if (*(uint64_t*) decode_table == 0)
+bool ffBase64DecodeRaw(uint32_t size, const char* str, uint32_t* out_size, char* output) {
+ if (*(uint64_t*) decode_table == 0) {
init_decode_table();
+ }
- char *out = output;
- while (size > 0 && (str[size - 1] == '\n' || str[size - 1] == '\r' || str[size - 1] == '='))
+ char* out = output;
+ while (size > 0 && (str[size - 1] == '\n' || str[size - 1] == '\r' || str[size - 1] == '=')) {
size--;
+ }
- const char *ends = str + size - 4;
- while (true)
- {
- if (str > ends)
+ const char* ends = str + size - 4;
+ while (true) {
+ if (str > ends) {
break;
- while (*str == '\n' || *str == '\r')
+ }
+ while (*str == '\n' || *str == '\r') {
str++;
+ }
- if (str > ends)
+ if (str > ends) {
break;
+ }
next_char(a);
next_char(b);
next_char(c);
next_char(d);
- *out++ = (char)(a << 2 | b >> 4);
- *out++ = (char)(b << 4 | c >> 2);
- *out++ = (char)(c << 6 | d >> 0);
+ *out++ = (char) (a << 2 | b >> 4);
+ *out++ = (char) (b << 4 | c >> 2);
+ *out++ = (char) (c << 6 | d >> 0);
}
uint8_t mod = (uint8_t) (ends - str + 4) % 4;
- if (mod == 2)
- {
+ if (mod == 2) {
next_char(a);
next_char(b);
- *out++ = (char)(a << 2 | b >> 4);
- }
- else if (mod == 3)
- {
+ *out++ = (char) (a << 2 | b >> 4);
+ } else if (mod == 3) {
next_char(a);
next_char(b);
next_char(c);
- *out++ = (char)(a << 2 | b >> 4);
- *out++ = (char)(b << 4 | c >> 2);
+ *out++ = (char) (a << 2 | b >> 4);
+ *out++ = (char) (b << 4 | c >> 2);
}
*out = '\0';
diff --git a/src/common/impl/binary_apple.c b/src/common/impl/binary_apple.c
index dee65b6a69..248be543c0 100644
--- a/src/common/impl/binary_apple.c
+++ b/src/common/impl/binary_apple.c
@@ -1,11 +1,10 @@
#include "common/binary.h"
#include "common/io.h"
#include "common/stringUtils.h"
-#include "common/mallocHelper.h"
-#include
#include
#include
+#include
#include
#include
#include
@@ -14,19 +13,38 @@
// Ref: https://github.com/AlexDenisov/segment_dumper/blob/master/main.c
+typedef struct {
+ const uint8_t* data;
+ size_t length;
+} FFMemoryMapping;
+
+static inline void wrapMunmap(FFMemoryMapping* mapping) {
+ assert(mapping);
+ if (mapping->data == NULL || mapping->data == MAP_FAILED)
+ return;
+ munmap((void*) mapping->data, mapping->length);
+}
+
/**
- * Helper function to read data from a file at a specific offset
+ * Helper function to access data from a memory-mapped file at a specific offset
*/
-static inline bool readData(FILE *objFile, void *buf, size_t size, off_t offset)
-{
- fseek(objFile, offset, SEEK_SET);
- return fread(buf, 1, size, objFile) == size;
+static inline const void* readData(const FFMemoryMapping* mapping, size_t size, off_t offset) {
+ if (offset < 0) {
+ return NULL;
+ }
+
+ size_t start = (size_t) offset;
+ if (start > mapping->length || size > mapping->length - start) {
+ return NULL;
+ }
+
+ return mapping->data + start;
}
/**
* Handles a Mach-O section by extracting strings from the __cstring section
*
- * @param objFile File handle to the Mach-O object file
+ * @param mapping Memory mapping of the Mach-O object file
* @param name Section name to check
* @param offset Offset of the section in the file
* @param size Size of the section
@@ -36,23 +54,29 @@ static inline bool readData(FILE *objFile, void *buf, size_t size, off_t offset)
*
* @return true to continue processing, false to stop
*/
-static bool handleMachSection(FILE *objFile, const char *name, off_t offset, size_t size, bool (*cb)(const char *str, uint32_t len, void *userdata), void *userdata, uint32_t minLength)
-{
- if (!ffStrEquals(name, "__cstring")) return true;
+static bool handleMachSection(const FFMemoryMapping* mapping, const char* name, off_t offset, size_t size, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata, uint32_t minLength) {
+ if (!ffStrEquals(name, "__cstring")) {
+ return true;
+ }
- FF_AUTO_FREE char* data = (char*) malloc(size);
- if (!readData(objFile, data, size, offset))
+ const char* data = readData(mapping, size, offset);
+ if (!data) {
return true;
+ }
- for (size_t off = 0; off < size; ++off)
- {
- const char* p = (const char*) data + off;
- if (*p == '\0') continue;
- uint32_t len = (uint32_t) strlen(p);
- if (len < minLength) continue;
- if (*p >= ' ' && *p <= '~') // Ignore control characters
- {
- if (!cb(p, len, userdata)) return false;
+ for (size_t off = 0; off < size; ++off) {
+ const char* p = data + off;
+ if (*p == '\0') {
+ continue;
+ }
+ uint32_t len = (uint32_t) strnlen(p, size - off);
+ if (len < minLength) {
+ continue;
+ }
+ if (*p >= ' ' && *p <= '~') { // Ignore control characters
+ if (!cb(p, len, userdata)) {
+ return false;
+ }
}
off += len;
}
@@ -66,7 +90,7 @@ static bool handleMachSection(FILE *objFile, const char *name, off_t offset, siz
* LC_SEGMENT or LC_SEGMENT_64 commands that contain the __TEXT segment.
* It then processes the sections within that segment to extract strings.
*
- * @param objFile File handle to the Mach-O object file
+ * @param mapping Memory mapping of the Mach-O object file
* @param offset Offset of the Mach header in the file
* @param is_64 Whether this is a 64-bit Mach-O header
* @param cb Callback function to process strings
@@ -75,71 +99,81 @@ static bool handleMachSection(FILE *objFile, const char *name, off_t offset, siz
*
* @return NULL on success, error message on failure
*/
-static const char* dumpMachHeader(FILE *objFile, off_t offset, bool is_64, bool (*cb)(const char *str, uint32_t len, void *userdata), void *userdata, uint32_t minLength)
-{
+static const char* dumpMachHeader(const FFMemoryMapping* mapping, off_t offset, bool is_64, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata, uint32_t minLength) {
uint32_t ncmds;
off_t loadCommandsOffset = offset;
- if (is_64)
- {
- struct mach_header_64 header;
- if (!readData(objFile, &header, sizeof(header), offset))
+ if (is_64) {
+ const struct mach_header_64* header = readData(mapping, sizeof(struct mach_header_64), offset);
+ if (!header) {
return "read mach header failed";
+ }
- ncmds = header.ncmds;
- loadCommandsOffset += sizeof(header);
- }
- else
- {
- struct mach_header header;
- if (!readData(objFile, &header, sizeof(header), offset))
+ ncmds = header->ncmds;
+ loadCommandsOffset += sizeof(*header);
+ } else {
+ const struct mach_header* header = readData(mapping, sizeof(struct mach_header), offset);
+ if (!header) {
return "read mach header failed";
+ }
- ncmds = header.ncmds;
- loadCommandsOffset += sizeof(header);
+ ncmds = header->ncmds;
+ loadCommandsOffset += sizeof(*header);
}
off_t commandOffset = loadCommandsOffset;
- struct load_command cmd = {};
- for (uint32_t i = 0U; i < ncmds; i++, commandOffset += cmd.cmdsize)
- {
- if (!readData(objFile, &cmd, sizeof(cmd), commandOffset))
- continue;
+ const struct load_command* cmd = NULL;
+ for (uint32_t i = 0U; i < ncmds; i++, commandOffset += cmd->cmdsize) {
+ cmd = readData(mapping, sizeof(*cmd), commandOffset);
+ if (!cmd) {
+ break;
+ }
- if (cmd.cmd == LC_SEGMENT_64)
- {
- struct segment_command_64 segment;
- if (!readData(objFile, &segment, sizeof(segment), commandOffset))
+ if (cmd->cmdsize < sizeof(*cmd)) {
+ break;
+ }
+
+ if (cmd->cmd == LC_SEGMENT_64) {
+ const struct segment_command_64* segment = readData(mapping, sizeof(struct segment_command_64), commandOffset);
+ if (!segment) {
continue;
+ }
- if (!ffStrEquals(segment.segname, "__TEXT")) continue;
+ if (!ffStrEquals(segment->segname, "__TEXT")) {
+ continue;
+ }
- for (uint32_t j = 0U; j < segment.nsects; j++)
- {
- struct section_64 section;
- if (!readData(objFile, §ion, sizeof(section), (off_t) ((size_t) commandOffset + sizeof(segment) + j * sizeof(section))))
+ for (uint32_t j = 0U; j < segment->nsects; j++) {
+ off_t sectionOffset = commandOffset + (off_t) sizeof(*segment) + (off_t) (j * sizeof(struct section_64));
+ const struct section_64* section = readData(mapping, sizeof(struct section_64), sectionOffset);
+ if (!section) {
continue;
+ }
- if (!handleMachSection(objFile, section.sectname, section.offset, section.size, cb, userdata, minLength))
+ if (!handleMachSection(mapping, section->sectname, (off_t) section->offset, (size_t) section->size, cb, userdata, minLength)) {
return NULL;
+ }
}
- }
- else if (cmd.cmd == LC_SEGMENT)
- {
- struct segment_command segment;
- if (!readData(objFile, &segment, sizeof(segment), commandOffset))
+ } else if (cmd->cmd == LC_SEGMENT) {
+ const struct segment_command* segment = readData(mapping, sizeof(struct segment_command), commandOffset);
+ if (!segment) {
continue;
+ }
- if (!ffStrEquals(segment.segname, "__TEXT")) continue;
+ if (!ffStrEquals(segment->segname, "__TEXT")) {
+ continue;
+ }
- for (uint32_t j = 0; j < segment.nsects; j++)
- {
- struct section section;
- if (!readData(objFile, §ion, sizeof(section), (off_t) ((size_t) commandOffset + sizeof(segment) + j * sizeof(section))))
+ for (uint32_t j = 0; j < segment->nsects; j++) {
+ off_t sectionOffset = commandOffset + (off_t) sizeof(*segment) + (off_t) (j * sizeof(struct section));
+ const struct section* section = readData(mapping, sizeof(struct section), sectionOffset);
+ if (!section) {
continue;
+ }
- if (!handleMachSection(objFile, section.sectname, section.offset, section.size, cb, userdata, minLength))
+ if (!handleMachSection(mapping, section->sectname, (off_t) section->offset, (size_t) section->size, cb, userdata, minLength)) {
return NULL;
+ }
}
}
@@ -156,56 +190,65 @@ static const char* dumpMachHeader(FILE *objFile, off_t offset, bool is_64, bool
* multiple Mach-O binaries for different architectures. It extracts and processes
* each embedded Mach-O file.
*
- * @param objFile File handle to the universal binary
+ * @param mapping Memory mapping of the universal binary
* @param cb Callback function to process strings
* @param userdata User data for the callback
* @param minLength Minimum string length to extract
*
* @return NULL on success, error message on failure
*/
-static const char* dumpFatHeader(FILE *objFile, bool (*cb)(const char *str, uint32_t len, void *userdata), void *userdata, uint32_t minLength)
-{
- struct fat_header header;
- if (!readData(objFile, &header, sizeof(header), 0))
+static const char* dumpFatHeader(const FFMemoryMapping* mapping, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata, uint32_t minLength) {
+ const struct fat_header* headerRaw = readData(mapping, sizeof(struct fat_header), 0);
+ if (!headerRaw) {
return "read fat header failed";
+ }
+
+ struct fat_header header = *headerRaw;
bool needSwap = header.magic == FAT_CIGAM || header.magic == FAT_CIGAM_64;
- if (needSwap) swap_fat_header(&header, NX_UnknownByteOrder);
+ if (needSwap) {
+ swap_fat_header(&header, NX_UnknownByteOrder);
+ }
- for (uint32_t i = 0U; i < header.nfat_arch; i++)
- {
+ for (uint32_t i = 0U; i < header.nfat_arch; i++) {
off_t machHeaderOffset = 0;
- if (header.magic == FAT_MAGIC)
- {
- struct fat_arch arch;
- if (!readData(objFile, &arch, sizeof(arch), (off_t) (sizeof(header) + i * sizeof(arch))))
+ if (header.magic == FAT_MAGIC) {
+ off_t archOffset = (off_t) sizeof(struct fat_header) + (off_t) (i * sizeof(struct fat_arch));
+ const struct fat_arch* archRaw = readData(mapping, sizeof(struct fat_arch), archOffset);
+ if (!archRaw) {
continue;
+ }
- if (needSwap)
+ struct fat_arch arch = *archRaw;
+
+ if (needSwap) {
swap_fat_arch(&arch, 1, NX_UnknownByteOrder);
- machHeaderOffset = (off_t)arch.offset;
- }
- else
- {
- struct fat_arch_64 arch;
- if (!readData(objFile, &arch, sizeof(arch), (off_t) (sizeof(header) + i * sizeof(arch))))
+ }
+ machHeaderOffset = (off_t) arch.offset;
+ } else {
+ off_t archOffset = (off_t) sizeof(struct fat_header) + (off_t) (i * sizeof(struct fat_arch_64));
+ const struct fat_arch_64* archRaw = readData(mapping, sizeof(struct fat_arch_64), archOffset);
+ if (!archRaw) {
continue;
+ }
+
+ struct fat_arch_64 arch = *archRaw;
- if (needSwap)
+ if (needSwap) {
swap_fat_arch_64(&arch, 1, NX_UnknownByteOrder);
+ }
- machHeaderOffset = (off_t)arch.offset;
+ machHeaderOffset = (off_t) arch.offset;
}
- uint32_t magic;
- if (!readData(objFile, &magic, sizeof(magic), machHeaderOffset))
+ const uint32_t* magic = readData(mapping, sizeof(uint32_t), machHeaderOffset);
+ if (!magic) {
continue;
+ }
- if (magic == MH_MAGIC_64 || magic == MH_MAGIC)
- {
- dumpMachHeader(objFile, machHeaderOffset, magic == MH_MAGIC_64, cb, userdata, minLength);
- return NULL;
+ if (*magic == MH_MAGIC_64 || *magic == MH_MAGIC) {
+ return dumpMachHeader(mapping, machHeaderOffset, *magic == MH_MAGIC_64, cb, userdata, minLength);
}
}
return "Unsupported fat header";
@@ -219,26 +262,42 @@ static const char* dumpFatHeader(FILE *objFile, bool (*cb)(const char *str, uint
* It locates the __cstring section in the __TEXT segment which contains
* the string literals used in the program.
*/
-const char *ffBinaryExtractStrings(const char *machoFile, bool (*cb)(const char *str, uint32_t len, void *userdata), void *userdata, uint32_t minLength)
-{
- FF_AUTO_CLOSE_FILE FILE *objFile = fopen(machoFile, "rb");
- if (objFile == NULL)
+const char* ffBinaryExtractStrings(const char* machoFile, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata, uint32_t minLength) {
+ FF_AUTO_CLOSE_FD int fd = open(machoFile, O_RDONLY | O_CLOEXEC);
+ if (fd < 0) {
return "File could not be opened";
+ }
+
+ struct stat st;
+ if (fstat(fd, &st) != 0 || st.st_size <= 0) {
+ return "Failed to stat file";
+ }
+
+ FF_A_CLEANUP(wrapMunmap) FFMemoryMapping mapping = {
+ .data = mmap(NULL, (size_t) st.st_size, PROT_READ, MAP_PRIVATE, fd, 0),
+ .length = (size_t) st.st_size,
+ };
+ if (mapping.data == MAP_FAILED) {
+ return "mmap failed";
+ }
// Read the magic number to determine the type of binary
- uint32_t magic;
- if (!readData(objFile, &magic, sizeof(magic), 0))
+ const uint32_t* magic = readData(&mapping, sizeof(uint32_t), 0);
+ if (!magic) {
return "read magic number failed";
+ }
// Check for supported formats
// MH_CIGAM and MH_CIGAM_64 seem to be no longer used, as `swap_mach_header` is marked as deprecated.
// However FAT_CIGAM and FAT_CIGAM_64 are still used (/usr/bin/vim).
- if (magic != MH_MAGIC && magic != MH_MAGIC_64 && magic != FAT_CIGAM && magic != FAT_CIGAM_64 && magic != FAT_MAGIC && magic != FAT_MAGIC_64)
+ if (*magic != MH_MAGIC && *magic != MH_MAGIC_64 && *magic != FAT_CIGAM && *magic != FAT_CIGAM_64 && *magic != FAT_MAGIC && *magic != FAT_MAGIC_64) {
return "Unsupported format or big endian mach-o file";
+ }
// Process either a fat binary or a regular Mach-O binary
- if (magic == FAT_MAGIC || magic == FAT_MAGIC_64 || magic == FAT_CIGAM || magic == FAT_CIGAM_64)
- return dumpFatHeader(objFile, cb, userdata, minLength);
- else
- return dumpMachHeader(objFile, 0, magic == MH_MAGIC_64, cb, userdata, minLength);
+ if (*magic == FAT_MAGIC || *magic == FAT_MAGIC_64 || *magic == FAT_CIGAM || *magic == FAT_CIGAM_64) {
+ return dumpFatHeader(&mapping, cb, userdata, minLength);
+ } else {
+ return dumpMachHeader(&mapping, 0, *magic == MH_MAGIC_64, cb, userdata, minLength);
+ }
}
diff --git a/src/common/impl/binary_linux.c b/src/common/impl/binary_linux.c
index d6ecf15b52..240e758700 100644
--- a/src/common/impl/binary_linux.c
+++ b/src/common/impl/binary_linux.c
@@ -2,12 +2,12 @@
#if defined(FF_HAVE_ELF) || defined(__sun) || (defined(__FreeBSD__) && !defined(__DragonFly__)) || defined(__OpenBSD__) || defined(__NetBSD__)
-#include "common/io.h"
-#include "common/library.h"
-#include "common/stringUtils.h"
+ #include "common/io.h"
+ #include "common/library.h"
+ #include "common/stringUtils.h"
-#include // #1254
-#include
+ #include // #1254
+ #include
/**
* Structure to hold dynamically loaded libelf function pointers
@@ -36,15 +36,15 @@ struct FFElfData {
*
* The function supports both 32-bit and 64-bit ELF formats.
*/
-const char* ffBinaryExtractStrings(const char* elfFile, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata, uint32_t minLength)
-{
+const char* ffBinaryExtractStrings(const char* elfFile, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata, uint32_t minLength) {
// Initialize libelf if not already done
- if (!elfData.inited)
- {
+ if (!elfData.inited) {
elfData.inited = true;
FF_LIBRARY_LOAD_MESSAGE(libelf, "libelf" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libelf, elfData, elf_version)
- if (elfData.ffelf_version(EV_CURRENT) == EV_NONE) return "elf_version() failed";
+ if (elfData.ffelf_version(EV_CURRENT) == EV_NONE) {
+ return "elf_version() failed";
+ }
// Load all required libelf functions
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libelf, elfData, elf_begin)
@@ -59,56 +59,69 @@ const char* ffBinaryExtractStrings(const char* elfFile, bool (*cb)(const char* s
libelf = NULL;
}
- if (elfData.ffelf_end == NULL)
+ if (elfData.ffelf_end == NULL) {
return "load libelf failed";
+ }
// Open the ELF file
FF_AUTO_CLOSE_FD int fd = open(elfFile, O_RDONLY | O_CLOEXEC);
- if (fd < 0) return "open() failed";
+ if (fd < 0) {
+ return "open() failed";
+ }
Elf* elf = elfData.ffelf_begin(fd, ELF_C_READ, NULL);
- if (elf == NULL) return "elf_begin() failed";
+ if (elf == NULL) {
+ return "elf_begin() failed";
+ }
// Get the section header string table index
size_t shstrndx = 0;
- if (elfData.ffelf_getshdrstrndx(elf, &shstrndx) < 0)
- {
+ if (elfData.ffelf_getshdrstrndx(elf, &shstrndx) < 0) {
elfData.ffelf_end(elf);
return "elf_getshdrstrndx() failed";
}
// Iterate through all sections, looking for .rodata which contains string literals
Elf_Scn* scn = NULL;
- while ((scn = elfData.ffelf_nextscn(elf, scn)) != NULL)
- {
+ while ((scn = elfData.ffelf_nextscn(elf, scn)) != NULL) {
// Try 64-bit section header first, then 32-bit if that fails
Elf64_Shdr* shdr64 = elfData.ffelf64_getshdr(scn);
Elf32_Shdr* shdr32 = NULL;
- if (shdr64 == NULL)
- {
+ if (shdr64 == NULL) {
shdr32 = elfData.ffelf32_getshdr(scn);
- if (shdr32 == NULL) continue;
+ if (shdr32 == NULL) {
+ continue;
+ }
}
// Get the section name and check if it's .rodata
const char* name = elfData.ffelf_strptr(elf, shstrndx, shdr64 ? shdr64->sh_name : shdr32->sh_name);
- if (name == NULL || !ffStrEquals(name, ".rodata")) continue;
+ if (name == NULL || !ffStrEquals(name, ".rodata")) {
+ continue;
+ }
// Get the section data
Elf_Data* data = elfData.ffelf_getdata(scn, NULL);
- if (data == NULL) continue;
+ if (data == NULL) {
+ continue;
+ }
// Scan the section for string literals
- for (size_t off = 0; off < data->d_size; ++off)
- {
+ for (size_t off = 0; off < data->d_size; ++off) {
const char* p = (const char*) data->d_buf + off;
- if (*p == '\0') continue;
+ if (*p == '\0') {
+ continue;
+ }
uint32_t len = (uint32_t) strlen(p);
- if (len < minLength) continue;
+ if (len < minLength) {
+ continue;
+ }
// Only process printable ASCII characters
if (*p >= ' ' && *p <= '~') // Ignore control characters
{
- if (!cb(p, len, userdata)) break;
+ if (!cb(p, len, userdata)) {
+ break;
+ }
}
off += len;
}
@@ -125,8 +138,7 @@ const char* ffBinaryExtractStrings(const char* elfFile, bool (*cb)(const char* s
/**
* Fallback implementation when libelf is not available
*/
-const char* ffBinaryExtractStrings(const char* file, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata, uint32_t minLength)
-{
+const char* ffBinaryExtractStrings(const char* file, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata, uint32_t minLength) {
FF_UNUSED(file, cb, userdata, minLength);
return "Fastfetch was built without libelf support";
}
diff --git a/src/common/impl/binary_windows.c b/src/common/impl/binary_windows.c
index 39b9eab7f1..9dc21e5913 100644
--- a/src/common/impl/binary_windows.c
+++ b/src/common/impl/binary_windows.c
@@ -14,48 +14,51 @@
* (which typically contains string literals), and scans it for valid strings.
* Each string found is passed to the callback function for processing.
*/
-const char* ffBinaryExtractStrings(const char *peFile, bool (*cb)(const char *str, uint32_t len, void *userdata), void *userdata, uint32_t minLength)
-{
- FF_AUTO_CLOSE_FD HANDLE hFile = CreateFileA(peFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (hFile == INVALID_HANDLE_VALUE)
+const char* ffBinaryExtractStrings(const char* peFile, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata, uint32_t minLength) {
+ FF_AUTO_CLOSE_FD HANDLE hFile = CreateFileA(peFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hFile == INVALID_HANDLE_VALUE) {
return "CreateFileA() failed";
+ }
FF_AUTO_CLOSE_FD HANDLE hSection = NULL;
- if (!NT_SUCCESS(NtCreateSection(&hSection, SECTION_MAP_READ, NULL, NULL, PAGE_READONLY, SEC_COMMIT, hFile)))
+ if (!NT_SUCCESS(NtCreateSection(&hSection, SECTION_MAP_READ, NULL, NULL, PAGE_READONLY, SEC_COMMIT, hFile))) {
return "NtCreateSection() failed";
+ }
PVOID base = NULL;
SIZE_T viewSize = 0;
- if (!NT_SUCCESS(NtMapViewOfSection(hSection, NtCurrentProcess(), &base, 0, 0, NULL, &viewSize, ViewUnmap, 0, PAGE_READONLY)))
+ if (!NT_SUCCESS(NtMapViewOfSection(hSection, NtCurrentProcess(), &base, 0, 0, NULL, &viewSize, ViewUnmap, 0, PAGE_READONLY))) {
return "NtMapViewOfSection() failed";
+ }
PIMAGE_NT_HEADERS ntHeaders = RtlImageNtHeader(base);
- if (!ntHeaders)
- {
+ if (!ntHeaders) {
NtUnmapViewOfSection(NtCurrentProcess(), base);
return "RtlImageNtHeader() failed";
}
PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(ntHeaders);
- for (WORD i = 0; i < ntHeaders->FileHeader.NumberOfSections; ++i, ++section)
- {
+ for (WORD i = 0; i < ntHeaders->FileHeader.NumberOfSections; ++i, ++section) {
// Look for initialized data sections with the name ".rdata" which typically contains string literals
- if ((section->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) && ffStrEquals((const char*) section->Name, ".rdata"))
- {
- uint8_t *data = (uint8_t *) base + section->PointerToRawData;
+ if ((section->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) && ffStrEquals((const char*) section->Name, ".rdata")) {
+ uint8_t* data = (uint8_t*) base + section->PointerToRawData;
// Scan the section for string literals
- for (size_t off = 0; off < section->SizeOfRawData; ++off)
- {
+ for (size_t off = 0; off < section->SizeOfRawData; ++off) {
const char* p = (const char*) data + off;
- if (*p == '\0') continue;
+ if (*p == '\0') {
+ continue;
+ }
uint32_t len = (uint32_t) strlen(p);
- if (len < minLength) continue;
+ if (len < minLength) {
+ continue;
+ }
// Only process printable ASCII characters
if (*p >= ' ' && *p <= '~') // Ignore control characters
{
- if (!cb(p, len, userdata)) break;
+ if (!cb(p, len, userdata)) {
+ break;
+ }
}
off += len;
}
diff --git a/src/common/impl/commandoption.c b/src/common/impl/commandoption.c
index 7bfc489993..19e5b93339 100644
--- a/src/common/impl/commandoption.c
+++ b/src/common/impl/commandoption.c
@@ -10,16 +10,17 @@
#include
#include
-bool ffParseModuleOptions(const char* key, const char* value)
-{
- if (!ffStrStartsWith(key, "--") || !ffCharIsEnglishAlphabet(key[2])) return false;
- if (value && !*value) value = NULL;
- for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(key[2]) - 'A']; *modules; ++modules)
- {
+bool ffParseModuleOptions(const char* key, const char* value) {
+ if (!ffStrStartsWith(key, "--") || !ffCharIsEnglishAlphabet(key[2])) {
+ return false;
+ }
+ if (value && !*value) {
+ value = NULL;
+ }
+ for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(key[2]) - 'A']; *modules; ++modules) {
FFModuleBaseInfo* baseInfo = *modules;
const char* subKey = ffOptionTestPrefix(key, baseInfo->name);
- if (subKey != NULL)
- {
+ if (subKey != NULL) {
if (subKey[0] == '\0' || subKey[0] == '-') // Key is exactly the module name or has a leading '-'
{
fprintf(stderr, "Error: unknown module key %s\n", key);
@@ -31,32 +32,25 @@ bool ffParseModuleOptions(const char* key, const char* value)
FF_STRBUF_AUTO_DESTROY jsonKey = ffStrbufCreate();
bool flag = false;
- for (const char* p = subKey; *p; ++p)
- {
- if (*p == '-')
- {
- if (flag)
- {
+ for (const char* p = subKey; *p; ++p) {
+ if (*p == '-') {
+ if (flag) {
fprintf(stderr, "Error: invalid double `-` in module key %s\n", key);
exit(477);
}
flag = true;
- }
- else
- {
- if (!isalpha((unsigned char)*p) && !isdigit((unsigned char)*p))
- {
+ } else {
+ if (!isalpha((unsigned char) *p) && !isdigit((unsigned char) *p)) {
fprintf(stderr, "Error: invalid character `%c` in module key %s\n", *p, key);
exit(477);
}
- if (flag)
- {
+ if (flag) {
flag = false;
ffStrbufAppendC(&jsonKey, (char) toupper((unsigned char) *p));
- }
- else
+ } else {
ffStrbufAppendC(&jsonKey, *p);
+ }
}
}
fprintf(stderr, "Error: Unsupported module option: %s\n", key);
@@ -69,124 +63,115 @@ bool ffParseModuleOptions(const char* key, const char* value)
return false;
}
-void ffPrepareCommandOption(FFdata* data)
-{
+void ffPrepareCommandOption(FFdata* data) {
char* moduleType = NULL;
size_t moduleLen = 0;
- while (ffStrbufGetdelim(&moduleType, &moduleLen, ':', &data->structure))
- {
- #define FF_IF_MODULE_MATCH(moduleNameConstant) if (moduleLen == strlen(moduleNameConstant) \
- && ffStrEqualsIgnCase(moduleType, moduleNameConstant) \
- && !ffStrbufSeparatedContainIgnCaseS(&data->structureDisabled, moduleNameConstant, ':'))
+ while (ffStrbufGetdelim(&moduleType, &moduleLen, ':', &data->structure)) {
+#define FF_IF_MODULE_MATCH(moduleNameConstant) if (moduleLen == strlen(moduleNameConstant) && ffStrEqualsIgnCase(moduleType, moduleNameConstant) && !ffStrbufSeparatedContainIgnCaseS(&data->structureDisabled, moduleNameConstant, ':'))
- switch (moduleType[0])
- {
- case 'C': case 'c':
+ switch (moduleType[0]) {
+ case 'C':
+ case 'c':
FF_IF_MODULE_MATCH(FF_CPUUSAGE_MODULE_NAME)
- ffPrepareCPUUsage();
+ ffPrepareCPUUsage();
break;
- case 'D': case 'd':
- FF_IF_MODULE_MATCH(FF_DISKIO_MODULE_NAME)
- {
- __attribute__((__cleanup__(ffDestroyDiskIOOptions))) FFDiskIOOptions options;
+ case 'D':
+ case 'd':
+ FF_IF_MODULE_MATCH(FF_DISKIO_MODULE_NAME) {
+ FF_A_CLEANUP(ffDestroyDiskIOOptions) FFDiskIOOptions options;
ffInitDiskIOOptions(&options);
ffPrepareDiskIO(&options);
}
break;
- case 'N': case 'n':
- FF_IF_MODULE_MATCH(FF_NETIO_MODULE_NAME)
- {
- __attribute__((__cleanup__(ffDestroyNetIOOptions))) FFNetIOOptions options;
+ case 'N':
+ case 'n':
+ FF_IF_MODULE_MATCH(FF_NETIO_MODULE_NAME) {
+ FF_A_CLEANUP(ffDestroyNetIOOptions) FFNetIOOptions options;
ffInitNetIOOptions(&options);
ffPrepareNetIO(&options);
}
break;
- case 'P': case 'p':
- FF_IF_MODULE_MATCH(FF_PUBLICIP_MODULE_NAME)
- {
- __attribute__((__cleanup__(ffDestroyPublicIpOptions))) FFPublicIPOptions options;
+ case 'P':
+ case 'p':
+ FF_IF_MODULE_MATCH(FF_PUBLICIP_MODULE_NAME) {
+ FF_A_CLEANUP(ffDestroyPublicIpOptions) FFPublicIPOptions options;
ffInitPublicIpOptions(&options);
ffPreparePublicIp(&options);
}
break;
- case 'W': case 'w':
- FF_IF_MODULE_MATCH(FF_WEATHER_MODULE_NAME)
- {
- __attribute__((__cleanup__(ffDestroyWeatherOptions))) FFWeatherOptions options;
+ case 'W':
+ case 'w':
+ FF_IF_MODULE_MATCH(FF_WEATHER_MODULE_NAME) {
+ FF_A_CLEANUP(ffDestroyWeatherOptions) FFWeatherOptions options;
ffInitWeatherOptions(&options);
ffPrepareWeather(&options);
}
break;
}
- #undef FF_IF_MODULE_MATCH
+#undef FF_IF_MODULE_MATCH
}
}
-static void genJsonConfig(FFdata* data, FFModuleBaseInfo* baseInfo, void* options)
-{
+static void genJsonConfig(FFdata* data, FFModuleBaseInfo* baseInfo, void* options) {
yyjson_mut_doc* doc = data->resultDoc;
yyjson_mut_val* modules = yyjson_mut_obj_get(doc->root, "modules");
- if (!modules)
+ if (!modules) {
modules = yyjson_mut_obj_add_arr(doc, doc->root, "modules");
+ }
FF_STRBUF_AUTO_DESTROY type = ffStrbufCreateS(baseInfo->name);
ffStrbufLowerCase(&type);
- if (data->docType == FF_RESULT_DOC_TYPE_CONFIG_FULL)
- {
+ if (data->docType == FF_RESULT_DOC_TYPE_CONFIG_FULL) {
yyjson_mut_val* module = yyjson_mut_obj(doc);
yyjson_mut_obj_add_strbuf(doc, module, "type", &type);
- if (baseInfo->generateJsonConfig)
+ if (baseInfo->generateJsonConfig) {
baseInfo->generateJsonConfig(options, doc, module);
+ }
- if (yyjson_mut_obj_size(module) > 1)
+ if (yyjson_mut_obj_size(module) > 1) {
yyjson_mut_arr_add_val(modules, module);
- else
+ } else {
yyjson_mut_arr_add_strbuf(doc, modules, &type);
- }
- else
- {
+ }
+ } else {
yyjson_mut_arr_add_strbuf(doc, modules, &type);
}
}
-static void genJsonResult(FFdata* data, FFModuleBaseInfo* baseInfo, void* options)
-{
+static void genJsonResult(FFdata* data, FFModuleBaseInfo* baseInfo, void* options) {
yyjson_mut_doc* doc = data->resultDoc;
yyjson_mut_val* module = yyjson_mut_arr_add_obj(doc, doc->root);
yyjson_mut_obj_add_str(doc, module, "type", baseInfo->name);
- if (baseInfo->generateJsonResult)
+ if (baseInfo->generateJsonResult) {
baseInfo->generateJsonResult(options, doc, module);
- else
+ } else {
yyjson_mut_obj_add_str(doc, module, "error", "Unsupported for JSON format");
+ }
}
static void parseStructureCommand(
FFdata* data,
const char* line,
- void (*fn)(FFdata*, FFModuleBaseInfo* baseInfo, void* options)
-)
-{
- if(ffCharIsEnglishAlphabet(line[0]))
- {
- for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(line[0]) - 'A']; *modules; ++modules)
- {
+ void (*fn)(FFdata*, FFModuleBaseInfo* baseInfo, void* options)) {
+ if (ffCharIsEnglishAlphabet(line[0])) {
+ for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(line[0]) - 'A']; *modules; ++modules) {
FFModuleBaseInfo* baseInfo = *modules;
- if (ffStrEqualsIgnCase(line, baseInfo->name))
- {
+ if (ffStrEqualsIgnCase(line, baseInfo->name)) {
uint8_t optionBuf[FF_OPTION_MAX_SIZE];
baseInfo->initOptions(optionBuf);
- if (__builtin_expect(data->resultDoc != NULL, false))
+ if (__builtin_expect(data->resultDoc != NULL, false)) {
fn(data, baseInfo, optionBuf);
- else
+ } else {
baseInfo->printModule(optionBuf);
+ }
baseInfo->destroyOptions(optionBuf);
return;
}
@@ -196,61 +181,62 @@ static void parseStructureCommand(
ffPrintError(line, 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "");
}
-void ffPrintCommandOption(FFdata* data)
-{
- //Parse the structure and call the modules
+void ffPrintCommandOption(FFdata* data) {
+ // Parse the structure and call the modules
int32_t thres = instance.config.display.stat;
char* moduleType = NULL;
size_t moduleLen = 0;
- while (ffStrbufGetdelim(&moduleType, &moduleLen, ':', &data->structure))
- {
- if (ffStrbufSeparatedContainIgnCaseS(&data->structureDisabled, moduleType, ':'))
+ while (ffStrbufGetdelim(&moduleType, &moduleLen, ':', &data->structure)) {
+ if (ffStrbufSeparatedContainIgnCaseS(&data->structureDisabled, moduleType, ':')) {
continue;
+ }
double ms = 0;
- if(thres >= 0)
+ if (thres >= 0) {
ms = ffTimeGetTick();
+ }
parseStructureCommand(data, moduleType, genJsonResult);
- if(thres >= 0)
- {
+ if (thres >= 0) {
ms = ffTimeGetTick() - ms;
- if (data->resultDoc)
- {
+ if (data->resultDoc) {
yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(data->resultDoc->root);
yyjson_mut_obj_add_real(data->resultDoc, moduleJson, "stat", ms);
- }
- else
- {
+ } else {
char str[64];
int len = snprintf(str, sizeof str, "%.3fms", ms);
- if (thres > 0)
- snprintf(str, sizeof str, "\e[%sm%.3fms\e[m", (ms <= thres ? FF_COLOR_FG_GREEN : ms <= 2 * thres ? FF_COLOR_FG_YELLOW : FF_COLOR_FG_RED), ms);
+ if (thres > 0) {
+ snprintf(str, sizeof str, "\e[%sm%.3fms\e[m", (ms <= thres ? FF_COLOR_FG_GREEN : ms <= 2 * thres ? FF_COLOR_FG_YELLOW
+ : FF_COLOR_FG_RED),
+ ms);
+ }
printf("\e7\e[1A\e[9999999C\e[%dD%s\e8", len, str); // Save; Up 1; Right 9999999; Left ; Print ; Load
}
}
- #if defined(_WIN32)
- if (!data->resultDoc && !instance.config.display.noBuffer) fflush(stdout);
- #endif
+#if defined(_WIN32)
+ if (!data->resultDoc && !instance.config.display.noBuffer) {
+ fflush(stdout);
+ }
+#endif
}
}
-void ffMigrateCommandOptionToJsonc(FFdata* data)
-{
- //If we don't have a custom structure, use the default one
- if(data->structure.length == 0)
+void ffMigrateCommandOptionToJsonc(FFdata* data) {
+ // If we don't have a custom structure, use the default one
+ if (data->structure.length == 0) {
ffStrbufAppendS(&data->structure, FASTFETCH_DATATEXT_STRUCTURE); // Cannot use `ffStrbufSetStatic` here because we will modify the string
+ }
char* moduleType = NULL;
size_t moduleLen = 0;
- while (ffStrbufGetdelim(&moduleType, &moduleLen, ':', &data->structure))
- {
- if (ffStrbufSeparatedContainIgnCaseS(&data->structureDisabled, moduleType, ':'))
+ while (ffStrbufGetdelim(&moduleType, &moduleLen, ':', &data->structure)) {
+ if (ffStrbufSeparatedContainIgnCaseS(&data->structureDisabled, moduleType, ':')) {
continue;
+ }
parseStructureCommand(data, moduleType, genJsonConfig);
}
diff --git a/src/common/impl/dbus.c b/src/common/impl/dbus.c
index cf45700a99..e8ef68fdd4 100644
--- a/src/common/impl/dbus.c
+++ b/src/common/impl/dbus.c
@@ -2,11 +2,10 @@
#ifdef FF_HAVE_DBUS
-#include "common/thread.h"
-#include "common/stringUtils.h"
+ #include "common/thread.h"
+ #include "common/stringUtils.h"
-static bool loadLibSymbols(FFDBusLibrary* lib)
-{
+static bool loadLibSymbols(FFDBusLibrary* lib) {
FF_LIBRARY_LOAD(dbus, false, "libdbus-1" FF_LIBRARY_EXTENSION, 4);
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_bus_get, false)
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_new_method_call, false)
@@ -24,14 +23,12 @@ static bool loadLibSymbols(FFDBusLibrary* lib)
return true;
}
-static const FFDBusLibrary* loadLib(void)
-{
+static const FFDBusLibrary* loadLib(void) {
static FFDBusLibrary lib;
static bool loaded = false;
static bool loadSuccess = false;
- if(!loaded)
- {
+ if (!loaded) {
loaded = true;
loadSuccess = loadLibSymbols(&lib);
}
@@ -39,199 +36,189 @@ static const FFDBusLibrary* loadLib(void)
return loadSuccess ? &lib : NULL;
}
-const char* ffDBusLoadData(DBusBusType busType, FFDBusData* data)
-{
+const char* ffDBusLoadData(DBusBusType busType, FFDBusData* data) {
data->lib = loadLib();
- if(data->lib == NULL)
+ if (data->lib == NULL) {
return "Failed to load DBus library";
+ }
data->connection = data->lib->ffdbus_bus_get(busType, NULL);
- if(data->connection == NULL)
+ if (data->connection == NULL) {
return "Failed to connect to DBus";
+ }
return NULL;
}
-void ffDBusDestroyData(FFDBusData* data)
-{
- if (data->connection != NULL)
- {
+void ffDBusDestroyData(FFDBusData* data) {
+ if (data->connection != NULL) {
data->lib->ffdbus_connection_unref(data->connection);
data->connection = NULL;
}
}
-bool ffDBusGetString(FFDBusData* dbus, DBusMessageIter* iter, FFstrbuf* result)
-{
+bool ffDBusGetString(FFDBusData* dbus, DBusMessageIter* iter, FFstrbuf* result) {
int argType = dbus->lib->ffdbus_message_iter_get_arg_type(iter);
- if(argType == DBUS_TYPE_STRING || argType == DBUS_TYPE_OBJECT_PATH)
- {
+ if (argType == DBUS_TYPE_STRING || argType == DBUS_TYPE_OBJECT_PATH) {
const char* value = NULL;
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
- if(!ffStrSet(value))
+ if (!ffStrSet(value)) {
return false;
+ }
ffStrbufAppendS(result, value);
return true;
}
- if (argType == DBUS_TYPE_BYTE)
- {
+ if (argType == DBUS_TYPE_BYTE) {
uint8_t value;
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
ffStrbufAppendC(result, (char) value);
return false; // Don't append a comma
}
- if(argType != DBUS_TYPE_VARIANT && argType != DBUS_TYPE_ARRAY)
+ if (argType != DBUS_TYPE_VARIANT && argType != DBUS_TYPE_ARRAY) {
return false;
+ }
DBusMessageIter subIter;
dbus->lib->ffdbus_message_iter_recurse(iter, &subIter);
- if(argType == DBUS_TYPE_VARIANT)
+ if (argType == DBUS_TYPE_VARIANT) {
return ffDBusGetString(dbus, &subIter, result);
+ }
- //At this point we have an array
+ // At this point we have an array
bool foundAValue = false;
- while(true)
- {
- if(ffDBusGetString(dbus, &subIter, result))
- {
+ while (true) {
+ if (ffDBusGetString(dbus, &subIter, result)) {
foundAValue = true;
ffStrbufAppendS(result, ", ");
}
- if(!dbus->lib->ffdbus_message_iter_next(&subIter))
+ if (!dbus->lib->ffdbus_message_iter_next(&subIter)) {
break;
- else
+ } else {
continue;
+ }
}
- if(foundAValue)
+ if (foundAValue) {
ffStrbufSubstrBefore(result, result->length - 2);
+ }
return foundAValue;
}
-bool ffDBusGetBool(FFDBusData* dbus, DBusMessageIter* iter, bool* result)
-{
+bool ffDBusGetBool(FFDBusData* dbus, DBusMessageIter* iter, bool* result) {
int argType = dbus->lib->ffdbus_message_iter_get_arg_type(iter);
- if(argType == DBUS_TYPE_BOOLEAN)
- {
+ if (argType == DBUS_TYPE_BOOLEAN) {
dbus_bool_t value = 0;
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
*result = value != 0;
return true;
}
- if(argType != DBUS_TYPE_VARIANT)
+ if (argType != DBUS_TYPE_VARIANT) {
return false;
+ }
DBusMessageIter subIter;
dbus->lib->ffdbus_message_iter_recurse(iter, &subIter);
return ffDBusGetBool(dbus, &subIter, result);
}
-bool ffDBusGetUint(FFDBusData* dbus, DBusMessageIter* iter, uint32_t* result)
-{
+bool ffDBusGetUint(FFDBusData* dbus, DBusMessageIter* iter, uint32_t* result) {
int argType = dbus->lib->ffdbus_message_iter_get_arg_type(iter);
- if(argType == DBUS_TYPE_BYTE)
- {
+ if (argType == DBUS_TYPE_BYTE) {
uint8_t value = 0;
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
*result = value;
return true;
}
- if(argType == DBUS_TYPE_UINT16)
- {
+ if (argType == DBUS_TYPE_UINT16) {
uint16_t value = 0;
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
*result = value;
return true;
}
- if(argType == DBUS_TYPE_UINT32)
- {
+ if (argType == DBUS_TYPE_UINT32) {
dbus->lib->ffdbus_message_iter_get_basic(iter, result);
return true;
}
- if(argType != DBUS_TYPE_VARIANT)
+ if (argType != DBUS_TYPE_VARIANT) {
return false;
+ }
DBusMessageIter subIter;
dbus->lib->ffdbus_message_iter_recurse(iter, &subIter);
return ffDBusGetUint(dbus, &subIter, result);
}
-bool ffDBusGetInt(FFDBusData* dbus, DBusMessageIter* iter, int32_t* result)
-{
+bool ffDBusGetInt(FFDBusData* dbus, DBusMessageIter* iter, int32_t* result) {
int argType = dbus->lib->ffdbus_message_iter_get_arg_type(iter);
- if(argType == DBUS_TYPE_INT16)
- {
+ if (argType == DBUS_TYPE_INT16) {
int16_t value = 0;
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
*result = value;
return true;
}
- if(argType == DBUS_TYPE_INT32)
- {
+ if (argType == DBUS_TYPE_INT32) {
dbus->lib->ffdbus_message_iter_get_basic(iter, result);
return true;
}
- if(argType == DBUS_TYPE_BYTE)
- {
+ if (argType == DBUS_TYPE_BYTE) {
uint8_t value = 0;
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
*result = value;
return true;
}
- if(argType == DBUS_TYPE_UINT16)
- {
+ if (argType == DBUS_TYPE_UINT16) {
uint16_t value = 0;
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
*result = (int16_t) value;
return true;
}
- if(argType == DBUS_TYPE_UINT32)
- {
+ if (argType == DBUS_TYPE_UINT32) {
dbus->lib->ffdbus_message_iter_get_basic(iter, result);
return true;
}
- if(argType != DBUS_TYPE_VARIANT)
+ if (argType != DBUS_TYPE_VARIANT) {
return false;
+ }
DBusMessageIter subIter;
dbus->lib->ffdbus_message_iter_recurse(iter, &subIter);
return ffDBusGetInt(dbus, &subIter, result);
}
-DBusMessage* ffDBusGetMethodReply(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* method, const char* arg1, const char* arg2)
-{
+DBusMessage* ffDBusGetMethodReply(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* method, const char* arg1, const char* arg2) {
DBusMessage* message = dbus->lib->ffdbus_message_new_method_call(busName, objectPath, interface, method);
- if(message == NULL)
+ if (message == NULL) {
return NULL;
+ }
- if (arg1)
- {
- if (arg2)
+ if (arg1) {
+ if (arg2) {
dbus->lib->ffdbus_message_append_args(message, DBUS_TYPE_STRING, &arg1, DBUS_TYPE_STRING, &arg2, DBUS_TYPE_INVALID);
- else
+ } else {
dbus->lib->ffdbus_message_append_args(message, DBUS_TYPE_STRING, &arg1, DBUS_TYPE_INVALID);
+ }
}
DBusMessage* reply = dbus->lib->ffdbus_connection_send_with_reply_and_block(dbus->connection, message, instance.config.general.processingTimeout, NULL);
@@ -241,15 +228,17 @@ DBusMessage* ffDBusGetMethodReply(FFDBusData* dbus, const char* busName, const c
return reply;
}
-DBusMessage* ffDBusGetProperty(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property)
-{
+DBusMessage* ffDBusGetProperty(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property) {
DBusMessage* message = dbus->lib->ffdbus_message_new_method_call(busName, objectPath, "org.freedesktop.DBus.Properties", "Get");
- if(message == NULL)
+ if (message == NULL) {
return NULL;
+ }
dbus->lib->ffdbus_message_append_args(message,
- DBUS_TYPE_STRING, &interface,
- DBUS_TYPE_STRING, &property,
+ DBUS_TYPE_STRING,
+ &interface,
+ DBUS_TYPE_STRING,
+ &property,
DBUS_TYPE_INVALID);
DBusMessage* reply = dbus->lib->ffdbus_connection_send_with_reply_and_block(dbus->connection, message, instance.config.general.processingTimeout, NULL);
@@ -259,15 +248,14 @@ DBusMessage* ffDBusGetProperty(FFDBusData* dbus, const char* busName, const char
return reply;
}
-bool ffDBusGetPropertyString(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, FFstrbuf* result)
-{
+bool ffDBusGetPropertyString(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, FFstrbuf* result) {
DBusMessage* reply = ffDBusGetProperty(dbus, busName, objectPath, interface, property);
- if(reply == NULL)
+ if (reply == NULL) {
return false;
+ }
DBusMessageIter rootIterator;
- if(!dbus->lib->ffdbus_message_iter_init(reply, &rootIterator))
- {
+ if (!dbus->lib->ffdbus_message_iter_init(reply, &rootIterator)) {
dbus->lib->ffdbus_message_unref(reply);
return false;
}
@@ -279,15 +267,14 @@ bool ffDBusGetPropertyString(FFDBusData* dbus, const char* busName, const char*
return ret;
}
-bool ffDBusGetPropertyUint(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, uint32_t* result)
-{
+bool ffDBusGetPropertyUint(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, uint32_t* result) {
DBusMessage* reply = ffDBusGetProperty(dbus, busName, objectPath, interface, property);
- if(reply == NULL)
+ if (reply == NULL) {
return false;
+ }
DBusMessageIter rootIterator;
- if(!dbus->lib->ffdbus_message_iter_init(reply, &rootIterator))
- {
+ if (!dbus->lib->ffdbus_message_iter_init(reply, &rootIterator)) {
dbus->lib->ffdbus_message_unref(reply);
return false;
}
@@ -299,4 +286,4 @@ bool ffDBusGetPropertyUint(FFDBusData* dbus, const char* busName, const char* ob
return ret;
}
-#endif //FF_HAVE_DBUS
+#endif // FF_HAVE_DBUS
diff --git a/src/common/impl/debug_windows.c b/src/common/impl/debug_windows.c
index bb827f99bb..8bcfe53113 100644
--- a/src/common/impl/debug_windows.c
+++ b/src/common/impl/debug_windows.c
@@ -1,17 +1,18 @@
#include "common/debug.h"
+#include "common/windows/nt.h"
#include
-const char* ffDebugWin32Error(DWORD errorCode)
-{
- static char buffer[256];
+const char* ffDebugWin32Error(DWORD errorCode) {
+ static char buffer[512];
- DWORD len = FormatMessageA(
+ wchar_t bufferW[256];
+ ULONG len = FormatMessageW(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
(DWORD) errorCode,
0,
- buffer,
+ bufferW,
sizeof(buffer),
NULL);
@@ -19,32 +20,36 @@ const char* ffDebugWin32Error(DWORD errorCode)
snprintf(buffer, sizeof(buffer), "Unknown error code (%lu)", errorCode);
} else {
// Remove trailing newline
- while (len > 0 && (buffer[len - 1] == '\r' || buffer[len - 1] == '\n')) {
- buffer[--len] = '\0';
+ while (len > 0 && (bufferW[len - 1] == '\r' || bufferW[len - 1] == '\n')) {
+ --len;
+ }
+
+ if (NT_SUCCESS(RtlUnicodeToUTF8N(buffer, sizeof(buffer), &len, bufferW, len * sizeof(wchar_t)))) {
+ snprintf(buffer + len, sizeof(buffer) - len, " (%lu)", errorCode);
+ } else {
+ snprintf(buffer, sizeof(buffer), "Unknown error (%lu)", errorCode);
}
- snprintf(buffer + len, sizeof(buffer) - len + 2, " (%lu)", errorCode);
}
return buffer;
}
-const char* ffDebugNtStatus(NTSTATUS status)
-{
+const char* ffDebugNtStatus(NTSTATUS status) {
return ffDebugWin32Error(RtlNtStatusToDosError(status));
}
-static inline DWORD HRESULTToWin32Error(HRESULT hr)
-{
- if (SUCCEEDED(hr))
+static inline DWORD HRESULTToWin32Error(HRESULT hr) {
+ if (SUCCEEDED(hr)) {
return ERROR_SUCCESS;
+ }
- if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
+ if (HRESULT_FACILITY(hr) == FACILITY_WIN32) {
return HRESULT_CODE(hr);
+ }
return ERROR_INTERNAL_ERROR;
}
-const char* ffDebugHResult(HRESULT hr)
-{
+const char* ffDebugHResult(HRESULT hr) {
return ffDebugWin32Error(HRESULTToWin32Error(hr));
}
diff --git a/src/common/impl/duration.c b/src/common/impl/duration.c
index a767ca3860..a6a496548c 100644
--- a/src/common/impl/duration.c
+++ b/src/common/impl/duration.c
@@ -1,25 +1,27 @@
#include "common/duration.h"
-void ffDurationAppendNum(uint64_t totalSeconds, FFstrbuf* result)
-{
+void ffDurationAppendNum(uint64_t totalSeconds, FFstrbuf* result) {
const FFOptionsDisplay* options = &instance.config.display;
bool spaceBeforeUnit = options->durationSpaceBeforeUnit != FF_SPACE_BEFORE_UNIT_NEVER;
- if (totalSeconds < 60)
- {
+ if (totalSeconds < 60) {
ffStrbufAppendUInt(result, totalSeconds);
- if (spaceBeforeUnit) ffStrbufAppendC(result, ' ');
+ if (spaceBeforeUnit) {
+ ffStrbufAppendC(result, ' ');
+ }
ffStrbufAppendS(result, options->durationAbbreviation ? "sec" : "second");
- if (totalSeconds != 1)
+ if (totalSeconds != 1) {
ffStrbufAppendC(result, 's');
+ }
return;
}
uint32_t seconds = (uint32_t) (totalSeconds % 60);
totalSeconds /= 60;
- if (seconds >= 30)
+ if (seconds >= 30) {
totalSeconds++;
+ }
uint32_t minutes = (uint32_t) (totalSeconds % 60);
totalSeconds /= 60;
@@ -27,56 +29,59 @@ void ffDurationAppendNum(uint64_t totalSeconds, FFstrbuf* result)
totalSeconds /= 24;
uint32_t days = (uint32_t) totalSeconds;
- if (days > 0)
- {
+ if (days > 0) {
ffStrbufAppendUInt(result, days);
- if (spaceBeforeUnit) ffStrbufAppendC(result, ' ');
- if (options->durationAbbreviation)
- {
+ if (spaceBeforeUnit) {
+ ffStrbufAppendC(result, ' ');
+ }
+ if (options->durationAbbreviation) {
ffStrbufAppendC(result, 'd');
- if (hours > 0 || minutes > 0)
+ if (hours > 0 || minutes > 0) {
ffStrbufAppendC(result, ' ');
- }
- else
- {
+ }
+ } else {
ffStrbufAppendS(result, days == 1 ? "day" : "days");
- if (days >= 100)
+ if (days >= 100) {
ffStrbufAppendS(result, "(!)");
+ }
- if (hours > 0 || minutes > 0)
+ if (hours > 0 || minutes > 0) {
ffStrbufAppendS(result, ", ");
+ }
}
}
- if (hours > 0)
- {
+ if (hours > 0) {
ffStrbufAppendUInt(result, hours);
- if (spaceBeforeUnit) ffStrbufAppendC(result, ' ');
- if (options->durationAbbreviation)
- {
+ if (spaceBeforeUnit) {
+ ffStrbufAppendC(result, ' ');
+ }
+ if (options->durationAbbreviation) {
ffStrbufAppendC(result, 'h');
- if (minutes > 0)
+ if (minutes > 0) {
ffStrbufAppendC(result, ' ');
- }
- else
- {
+ }
+ } else {
ffStrbufAppendS(result, hours == 1 ? "hour" : "hours");
- if (minutes > 0)
+ if (minutes > 0) {
ffStrbufAppendS(result, ", ");
+ }
}
}
- if (minutes > 0)
- {
+ if (minutes > 0) {
ffStrbufAppendUInt(result, minutes);
- if (spaceBeforeUnit) ffStrbufAppendC(result, ' ');
- if (options->durationAbbreviation)
+ if (spaceBeforeUnit) {
+ ffStrbufAppendC(result, ' ');
+ }
+ if (options->durationAbbreviation) {
ffStrbufAppendC(result, 'm');
- else
+ } else {
ffStrbufAppendS(result, minutes == 1 ? "min" : "mins");
+ }
}
}
diff --git a/src/common/impl/edidHelper.c b/src/common/impl/edidHelper.c
index 8cf387adc6..1e3310e2a4 100644
--- a/src/common/impl/edidHelper.c
+++ b/src/common/impl/edidHelper.c
@@ -1,55 +1,39 @@
#include "common/edidHelper.h"
-void ffEdidGetPhysicalResolution(const uint8_t edid[128], uint32_t* width, uint32_t* height)
-{
+void ffEdidGetPhysicalResolution(const uint8_t edid[128], uint32_t* width, uint32_t* height) {
const int dtd = 54;
*width = (((uint32_t) edid[dtd + 4] >> 4) << 8) | edid[dtd + 2];
*height = (((uint32_t) edid[dtd + 7] >> 4) << 8) | edid[dtd + 5];
}
-void ffEdidGetPreferredResolutionAndRefreshRate(const uint8_t edid[128], uint32_t* width, uint32_t* height, double* refreshRate)
-{
- for (uint32_t i = 0x36; i < 0x7E; i += 0x12)
- { // read through descriptor blocks...
- if (edid[i] != 0x00 && edid[i + 1] != 0x00)
- { // a dtd
- uint32_t hactive = edid[i+2] + (uint32_t) ((edid[i + 4] & 0xf0) << 4);
- uint32_t hblank = edid[i+3] + (uint32_t) ((edid[i + 4] & 0x0f) << 8);
- uint32_t vactive = edid[i+5] + (uint32_t) ((edid[i + 7] & 0xf0) << 4);
- uint32_t vblank = edid[i+6] + (uint32_t) ((edid[i + 7] & 0x0f) << 8);
- uint32_t pixclk = ((uint32_t) edid[i+1] << 8) | (edid[i]);
+void ffEdidGetPreferredResolutionAndRefreshRate(const uint8_t edid[128], uint32_t* width, uint32_t* height, double* refreshRate) {
+ for (uint32_t i = 0x36; i < 0x7E; i += 0x12) { // read through descriptor blocks...
+ if (edid[i] != 0x00 && edid[i + 1] != 0x00) { // a dtd
+ uint32_t hactive = edid[i + 2] + (uint32_t) ((edid[i + 4] & 0xf0) << 4);
+ uint32_t hblank = edid[i + 3] + (uint32_t) ((edid[i + 4] & 0x0f) << 8);
+ uint32_t vactive = edid[i + 5] + (uint32_t) ((edid[i + 7] & 0xf0) << 4);
+ uint32_t vblank = edid[i + 6] + (uint32_t) ((edid[i + 7] & 0x0f) << 8);
+ uint32_t pixclk = ((uint32_t) edid[i + 1] << 8) | (edid[i]);
*width = hactive;
*height = vactive;
- *refreshRate = (double)pixclk * 10000 / (double)(hactive+hblank) / (double)(vactive+vblank);
+ *refreshRate = (double) pixclk * 10000 / (double) (hactive + hblank) / (double) (vactive + vblank);
return;
}
}
}
-void ffEdidGetVendorAndModel(const uint8_t edid[128], FFstrbuf* result)
-{
+void ffEdidGetVendorAndModel(const uint8_t edid[128], FFstrbuf* result) {
// https://github.com/jinksong/read_edid/blob/master/parse-edid/parse-edid.c
- ffStrbufAppendF(result, "%c%c%c%04X",
- (char) (((uint32_t)edid[8] >> 2 & 0x1f) + 'A' - 1),
- (char) (((((uint32_t)edid[8] & 0x3) << 3) | (((uint32_t)edid[9] & 0xe0) >> 5)) + 'A' - 1),
- (char) (((uint32_t)edid[9] & 0x1f) + 'A' - 1),
- (uint32_t) (edid[10] + (uint32_t) (edid[11] << 8))
- );
+ ffStrbufAppendF(result, "%c%c%c%04X", (char) (((uint32_t) edid[8] >> 2 & 0x1f) + 'A' - 1), (char) (((((uint32_t) edid[8] & 0x3) << 3) | (((uint32_t) edid[9] & 0xe0) >> 5)) + 'A' - 1), (char) (((uint32_t) edid[9] & 0x1f) + 'A' - 1), (uint32_t) (edid[10] + (uint32_t) (edid[11] << 8)));
}
-bool ffEdidGetName(const uint8_t edid[128], FFstrbuf* name)
-{
+bool ffEdidGetName(const uint8_t edid[128], FFstrbuf* name) {
// https://github.com/jinksong/read_edid/blob/master/parse-edid/parse-edid.c
- for (uint32_t i = 0x36; i < 0x7E; i += 0x12)
- { // read through descriptor blocks...
- if (edid[i] == 0x00)
- { // not a timing descriptor
- if (edid[i + 3] == 0xfc)
- { // Model Name tag
- for (uint32_t j = 0; j < 13; j++)
- {
- if (edid[i + 5 + j] == 0x0a)
- {
+ for (uint32_t i = 0x36; i < 0x7E; i += 0x12) { // read through descriptor blocks...
+ if (edid[i] == 0x00) { // not a timing descriptor
+ if (edid[i + 3] == 0xfc) { // Model Name tag
+ for (uint32_t j = 0; j < 13; j++) {
+ if (edid[i + 5 + j] == 0x0a) {
ffStrbufAppendNS(name, j, (const char*) &edid[i + 5]);
return true;
}
@@ -63,8 +47,7 @@ bool ffEdidGetName(const uint8_t edid[128], FFstrbuf* name)
return false;
}
-void ffEdidGetPhysicalSize(const uint8_t edid[128], uint32_t* width, uint32_t* height)
-{
+void ffEdidGetPhysicalSize(const uint8_t edid[128], uint32_t* width, uint32_t* height) {
// Detailed Timing Descriptors
uint32_t dw = (((uint32_t) edid[68] & 0xF0) << 4) + edid[66];
uint32_t dh = (((uint32_t) edid[68] & 0x0F) << 8) + edid[67];
@@ -74,53 +57,54 @@ void ffEdidGetPhysicalSize(const uint8_t edid[128], uint32_t* width, uint32_t* h
uint32_t bh = edid[22] * 10;
// Some monitors report invalid data in DTD. See #1406
- if (abs((int)dw - (int)bw) < 10 && abs((int)dh - (int)bh) < 10)
- {
+ if (abs((int) dw - (int) bw) < 10 && abs((int) dh - (int) bh) < 10) {
*width = dw;
*height = dh;
- }
- else
- {
+ } else {
*width = bw;
*height = bh;
}
}
-void ffEdidGetSerialAndManufactureDate(const uint8_t edid[128], uint32_t* serial, uint16_t* year, uint16_t* week)
-{
- if (edid[17] > 0 && edid[17] < 0xFF)
- {
+void ffEdidGetSerialAndManufactureDate(const uint8_t edid[128], uint32_t* serial, uint16_t* year, uint16_t* week) {
+ if (edid[17] > 0 && edid[17] < 0xFF) {
*year = (uint16_t) (edid[17] + 1990);
*week = (uint16_t) edid[16];
- if (*week == 0xFF) *week = 0;
- }
- else
+ if (*week == 0xFF) {
+ *week = 0;
+ }
+ } else {
*year = *week = 0;
+ }
*serial = *(uint32_t*) &edid[12];
}
-bool ffEdidGetHdrCompatible(const uint8_t* edid, uint32_t length)
-{
- if (length <= 128) return false;
- for (const uint8_t* cta = &edid[128]; cta < &edid[length]; cta += 128)
- {
+bool ffEdidGetHdrCompatible(const uint8_t* edid, uint32_t length) {
+ if (length <= 128) {
+ return false;
+ }
+ for (const uint8_t* cta = &edid[128]; cta < &edid[length]; cta += 128) {
// https://en.wikipedia.org/wiki/Extended_Display_Identification_Data#CTA_EDID_Timing_Extension_Block
- if (cta[0] != 0x02 /* CTA EDID */) continue;
- if (cta[1] < 0x03 /* Version 3 */) continue;
+ if (cta[0] != 0x02 /* CTA EDID */) {
+ continue;
+ }
+ if (cta[1] < 0x03 /* Version 3 */) {
+ continue;
+ }
const uint8_t offset = cta[2];
- if (offset <= 4) continue;
- for (uint8_t i = 4; i < offset;)
- {
+ if (offset <= 4) {
+ continue;
+ }
+ for (uint8_t i = 4; i < offset;) {
uint8_t blkLen = cta[i] & 0x1f;
- if (blkLen > 0)
- {
+ if (blkLen > 0) {
uint8_t blkTag = (cta[i] & 0xe0) >> 5;
- if (blkTag == 0x07 /* Extended Block Type Tag */)
- {
+ if (blkTag == 0x07 /* Extended Block Type Tag */) {
uint8_t extendedTag = cta[i + 1];
- if (extendedTag == 6 /* HDR SMDB */ || extendedTag == 7 /* HDR DMDB */)
+ if (extendedTag == 6 /* HDR SMDB */ || extendedTag == 7 /* HDR DMDB */) {
return true;
+ }
}
}
i += (uint8_t) (blkLen + 1);
@@ -129,15 +113,20 @@ bool ffEdidGetHdrCompatible(const uint8_t* edid, uint32_t length)
return false;
}
-bool ffEdidIsValid(const uint8_t edid[128], uint32_t length)
-{
- if (length < 128 || length % 128 != 0) return false;
+bool ffEdidIsValid(const uint8_t edid[128], uint32_t length) {
+ if (length < 128 || length % 128 != 0) {
+ return false;
+ }
static const uint8_t edidHeader[] = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 };
- if (memcmp(edid, edidHeader, sizeof(edidHeader)) != 0) return false;
+ if (memcmp(edid, edidHeader, sizeof(edidHeader)) != 0) {
+ return false;
+ }
uint8_t sum = 0;
- for (uint32_t i = 0; i < 128; i++) sum += edid[i];
+ for (uint32_t i = 0; i < 128; i++) {
+ sum += edid[i];
+ }
return sum == 0;
}
diff --git a/src/common/impl/font.c b/src/common/impl/font.c
index 7548ab2de2..b754c4c181 100644
--- a/src/common/impl/font.c
+++ b/src/common/impl/font.c
@@ -7,93 +7,98 @@
#include
#include
-void ffFontInit(FFfont* font)
-{
+void ffFontInit(FFfont* font) {
// Ensure no memory allocates
ffStrbufInit(&font->pretty);
ffStrbufInit(&font->name);
ffStrbufInit(&font->size);
- ffListInit(&font->styles, sizeof(FFstrbuf));
+ ffListInit(&font->styles);
}
-static void strbufAppendNSExcludingC(FFstrbuf* strbuf, uint32_t length, const char* value, char exclude)
-{
- if(value == NULL || length == 0)
+static void strbufAppendNSExcludingC(FFstrbuf* strbuf, uint32_t length, const char* value, char exclude) {
+ if (value == NULL || length == 0) {
return;
+ }
ffStrbufEnsureFree(strbuf, length);
- for(uint32_t i = 0; i < length; i++)
- {
- if(value[i] != exclude)
- strbuf->chars[strbuf->length++] = value[i];
+ for (uint32_t i = 0; i < length; i++) {
+ if (value[i] != exclude) {
+ strbuf->chars[strbuf->length++] = value[i];
+ }
}
strbuf->chars[strbuf->length] = '\0';
}
-static void fontInitPretty(FFfont* font)
-{
+static void fontInitPretty(FFfont* font) {
ffStrbufAppend(&font->pretty, &font->name);
- if(font->size.length == 0 && font->styles.length == 0)
+ if (font->size.length == 0 && font->styles.length == 0) {
return;
- else if(font->pretty.length == 0)
+ } else if (font->pretty.length == 0) {
ffStrbufAppendS(&font->pretty, "default");
+ }
ffStrbufAppendS(&font->pretty, " (");
- if(font->size.length > 0)
- {
+ if (font->size.length > 0) {
ffStrbufAppend(&font->pretty, &font->size);
- if (!ffStrbufEndsWithS(&font->size, "pt") && !ffStrbufEndsWithS(&font->size, "px"))
+ if (!ffStrbufEndsWithS(&font->size, "pt") && !ffStrbufEndsWithS(&font->size, "px")) {
ffStrbufAppendS(&font->pretty, "pt");
+ }
- if(font->styles.length > 0)
+ if (font->styles.length > 0) {
ffStrbufAppendS(&font->pretty, ", ");
+ }
}
- for(uint32_t i = 0; i < font->styles.length; i++)
- {
+ for (uint32_t i = 0; i < font->styles.length; i++) {
ffStrbufAppend(&font->pretty, FF_LIST_GET(FFstrbuf, font->styles, i));
- if(i < font->styles.length - 1)
+ if (i < font->styles.length - 1) {
ffStrbufAppendS(&font->pretty, ", ");
+ }
}
ffStrbufAppendC(&font->pretty, ')');
}
-void ffFontInitQt(FFfont* font, const char* data)
-{
+void ffFontInitQt(FFfont* font, const char* data) {
ffFontInit(font);
- //See https://doc.qt.io/qt-5/qfont.html#toString
+ // See https://doc.qt.io/qt-5/qfont.html#toString
- //Family
+ // Family
data = ffStrbufAppendSUntilC(&font->name, data, ',');
ffStrbufTrim(&font->name, ' ');
- if (!data) goto exit;
+ if (!data) {
+ goto exit;
+ }
data++;
- //Size
+ // Size
data = ffStrbufAppendSUntilC(&font->size, data, ',');
ffStrbufTrim(&font->size, ' ');
- if (!data) goto exit;
+ if (!data) {
+ goto exit;
+ }
data++;
- //Style
+ // Style
data = strrchr(data, ',');
- if (!data) goto exit;
+ if (!data) {
+ goto exit;
+ }
data++;
- if (isalpha(*data))
- {
- do
- {
- FFstrbuf* style = (FFstrbuf*) ffListAdd(&font->styles);
+ if (isalpha(*data)) {
+ do {
+ FFstrbuf* style = FF_LIST_ADD(FFstrbuf, font->styles);
ffStrbufInit(style);
data = ffStrbufAppendSUntilC(style, data, ' ');
- if (data) data++;
+ if (data) {
+ data++;
+ }
} while (data);
}
@@ -101,34 +106,37 @@ void ffFontInitQt(FFfont* font, const char* data)
fontInitPretty(font);
}
-static void fontPangoParseWord(const char** data, FFfont* font, FFstrbuf* alternativeBuffer)
-{
- while(**data == ' ' || **data == '\t' || **data == ',')
+static void fontPangoParseWord(const char** data, FFfont* font, FFstrbuf* alternativeBuffer) {
+ while (**data == ' ' || **data == '\t' || **data == ',') {
++(*data);
+ }
const char* wordStart = *data;
- while(**data != ' ' && **data != '\t' && **data != ',' && **data != '\0' && **data != '`' && **data != '\\')
+ while (**data != ' ' && **data != '\t' && **data != ',' && **data != '\0' && **data != '`' && **data != '\\') {
++(*data);
+ }
uint32_t wordLength = (uint32_t) (*data - wordStart);
- if(wordLength == 0)
+ if (wordLength == 0) {
return;
+ }
- if(**data == '\0' || **data == '`' || **data == '\\')
- {
+ if (**data == '\0' || **data == '`' || **data == '\\') {
ffStrbufAppendNS(&font->size, wordLength, wordStart);
- if(ffStrbufEndsWithS(&font->size, "px"))
+ if (ffStrbufEndsWithS(&font->size, "px")) {
ffStrbufSubstrBefore(&font->size, font->size.length - 2);
+ }
double dummy;
- if(sscanf(font->size.chars, "%lf", &dummy) == 1)
+ if (sscanf(font->size.chars, "%lf", &dummy) == 1) {
return;
+ }
ffStrbufClear(&font->size);
}
- if(
+ if (
ffStrStartsWithIgnCase(wordStart, "Ultra") ||
ffStrStartsWithIgnCase(wordStart, "Extra") ||
ffStrStartsWithIgnCase(wordStart, "Semi") ||
@@ -142,51 +150,47 @@ static void fontPangoParseWord(const char** data, FFfont* font, FFstrbuf* altern
ffStrStartsWithIgnCase(wordStart, "Bold") ||
ffStrStartsWithIgnCase(wordStart, "Black") ||
ffStrStartsWithIgnCase(wordStart, "Condensed") ||
- ffStrStartsWithIgnCase(wordStart, "Expanded")
- ) {
- if(alternativeBuffer == NULL)
- {
- alternativeBuffer = (FFstrbuf*) ffListAdd(&font->styles);
+ ffStrStartsWithIgnCase(wordStart, "Expanded")) {
+ if (alternativeBuffer == NULL) {
+ alternativeBuffer = FF_LIST_ADD(FFstrbuf, font->styles);
ffStrbufInit(alternativeBuffer);
}
strbufAppendNSExcludingC(alternativeBuffer, wordLength, wordStart, '-');
- if(
+ if (
ffStrStartsWithIgnCase(wordStart, "Ultra ") ||
ffStrStartsWithIgnCase(wordStart, "Extra ") ||
ffStrStartsWithIgnCase(wordStart, "Semi ") ||
- ffStrStartsWithIgnCase(wordStart, "Demi ")
- ) {
+ ffStrStartsWithIgnCase(wordStart, "Demi ")) {
fontPangoParseWord(data, font, alternativeBuffer);
}
return;
}
- if(alternativeBuffer != NULL)
- {
+ if (alternativeBuffer != NULL) {
strbufAppendNSExcludingC(alternativeBuffer, wordLength, wordStart, '-');
return;
}
- if(font->name.length > 0)
+ if (font->name.length > 0) {
ffStrbufAppendC(&font->name, ' ');
+ }
ffStrbufAppendNS(&font->name, wordLength, wordStart);
}
-void ffFontInitPango(FFfont* font, const char* data)
-{
+void ffFontInitPango(FFfont* font, const char* data) {
ffFontInit(font);
- while(*data != '\0' && *data != '`' && *data != '\\')
+ while (*data != '\0' && *data != '`' && *data != '\\') {
fontPangoParseWord(&data, font, NULL);
+ }
fontInitPretty(font);
}
-void ffFontInitValues(FFfont* font, const char* name, const char* size)
-{
+void ffFontInitValues(FFfont* font, const char* name, const char* size) {
ffFontInit(font);
ffStrbufAppendS(&font->name, name);
@@ -196,8 +200,7 @@ void ffFontInitValues(FFfont* font, const char* name, const char* size)
fontInitPretty(font);
}
-void ffFontInitXlfd(FFfont* font, const char* xlfd)
-{
+void ffFontInitXlfd(FFfont* font, const char* xlfd) {
assert(xlfd && *xlfd);
// https://en.wikipedia.org/wiki/X_logical_font_description
@@ -205,80 +208,78 @@ void ffFontInitXlfd(FFfont* font, const char* xlfd)
// XLFD: -foundry-family-weight-slant-setwidth-addstyle-pixelsize-pointsize-xres-yres-spacing-averagewidth-charsetregistry-charsetencoding
// It often starts with '-', which would create an empty first field. Skip it to align indexes.
- if(*xlfd == '-')
+ if (*xlfd == '-') {
xlfd++;
+ }
const char* pstart = xlfd;
- for(int field = 0; field < 14; field++)
- {
+ for (int field = 0; field < 14; field++) {
const char* pend = strchr(pstart, '-');
- uint32_t length = pend ? (uint32_t)(pend - pstart) : (uint32_t) strlen(pstart);
+ uint32_t length = pend ? (uint32_t) (pend - pstart) : (uint32_t) strlen(pstart);
- if(length > 0)
- {
- if(field == 1) // family
+ if (length > 0) {
+ if (field == 1) // family
{
ffStrbufAppendNS(&font->name, length, pstart);
- }
- else if(field == 7) // pointsize (decipoints, preferred)
+ } else if (field == 7) // pointsize (decipoints, preferred)
{
// parse positive integer from substring
long deciPt = 0;
bool ok = true;
- for(uint32_t i = 0; i < length; i++)
- {
+ for (uint32_t i = 0; i < length; i++) {
char c = pstart[i];
- if(c < '0' || c > '9') { ok = false; break; }
+ if (c < '0' || c > '9') {
+ ok = false;
+ break;
+ }
deciPt = deciPt * 10 + (c - '0');
}
- if(ok && deciPt > 0)
- {
+ if (ok && deciPt > 0) {
ffStrbufClear(&font->size);
char tmp[32];
- if(deciPt % 10 == 0)
+ if (deciPt % 10 == 0) {
snprintf(tmp, sizeof(tmp), "%ldpt", deciPt / 10);
- else
+ } else {
snprintf(tmp, sizeof(tmp), "%ld.%ldpt", deciPt / 10, deciPt % 10);
+ }
ffStrbufAppendS(&font->size, tmp);
}
- }
- else if(field == 6) // pixelsize (fallback if pointsize missing/invalid)
+ } else if (field == 6) // pixelsize (fallback if pointsize missing/invalid)
{
- if(font->size.length == 0)
- {
+ if (font->size.length == 0) {
long px = 0;
bool ok = true;
- for(uint32_t i = 0; i < length; i++)
- {
+ for (uint32_t i = 0; i < length; i++) {
char c = pstart[i];
- if(c < '0' || c > '9') { ok = false; break; }
+ if (c < '0' || c > '9') {
+ ok = false;
+ break;
+ }
px = px * 10 + (c - '0');
}
- if(ok && px > 0)
- {
+ if (ok && px > 0) {
ffStrbufAppendNS(&font->size, length, pstart);
ffStrbufAppendS(&font->size, "px");
}
}
- }
- else if(field >= 2 && field <= 5) // weight/slant/setwidth/addstyle
+ } else if (field >= 2 && field <= 5) // weight/slant/setwidth/addstyle
{
// ignore "normal" (case-insensitive)
- if(!(length == 6 && ffStrStartsWithIgnCase(pstart, "normal")))
- {
- FFstrbuf* style = (FFstrbuf*) ffListAdd(&font->styles);
+ if (!(length == 6 && ffStrStartsWithIgnCase(pstart, "normal"))) {
+ FFstrbuf* style = FF_LIST_ADD(FFstrbuf, font->styles);
ffStrbufInitNS(style, length, pstart);
}
}
}
- if(!pend)
+ if (!pend) {
break;
+ }
pstart = pend + 1;
}
@@ -286,8 +287,7 @@ void ffFontInitXlfd(FFfont* font, const char* xlfd)
fontInitPretty(font);
}
-void ffFontInitXft(FFfont* font, const char* xft)
-{
+void ffFontInitXft(FFfont* font, const char* xft) {
assert(xft);
// https://en.wikipedia.org/wiki/Xft
@@ -302,26 +302,28 @@ void ffFontInitXft(FFfont* font, const char* xft)
// 1) Parse "head" part before first ':' => usually "family[-size]" (may include commas)
const char* p = xft;
- while(*p == ' ' || *p == '\t')
+ while (*p == ' ' || *p == '\t') {
++p;
+ }
const char* headStart = p;
- while(*p != '\0' && *p != ':')
+ while (*p != '\0' && *p != ':') {
++p;
+ }
const char* headEnd = p;
// trim tail spaces
- while(headEnd > headStart && (headEnd[-1] == ' ' || headEnd[-1] == '\t'))
+ while (headEnd > headStart && (headEnd[-1] == ' ' || headEnd[-1] == '\t')) {
--headEnd;
+ }
// If multiple families are listed, take the first one (up to comma)
- for(const char* q = headStart; q < headEnd; ++q)
- {
- if(*q == ',')
- {
+ for (const char* q = headStart; q < headEnd; ++q) {
+ if (*q == ',') {
headEnd = q;
- while(headEnd > headStart && (headEnd[-1] == ' ' || headEnd[-1] == '\t'))
+ while (headEnd > headStart && (headEnd[-1] == ' ' || headEnd[-1] == '\t')) {
--headEnd;
+ }
break;
}
}
@@ -330,56 +332,51 @@ void ffFontInitXft(FFfont* font, const char* xft)
const char* dashPos = NULL;
const char* sizeStart = NULL;
- for(const char* q = headEnd; q > headStart; )
- {
+ for (const char* q = headEnd; q > headStart;) {
--q;
- if(*q == '-' && (q + 1) < headEnd && ffCharIsDigit(q[1]))
- {
+ if (*q == '-' && (q + 1) < headEnd && ffCharIsDigit(q[1])) {
dashPos = q;
sizeStart = q + 1;
break;
}
}
- if(dashPos)
- {
+ if (dashPos) {
bool ok = true;
bool seenDigit = false;
- for(const char* q = sizeStart; q < headEnd; ++q)
- {
- if(ffCharIsDigit(*q))
+ for (const char* q = sizeStart; q < headEnd; ++q) {
+ if (ffCharIsDigit(*q)) {
seenDigit = true;
- else if(*q == '.')
+ } else if (*q == '.') {
continue;
- else
- {
+ } else {
ok = false;
break;
}
}
- if(ok && seenDigit)
- {
+ if (ok && seenDigit) {
const char* nameEnd = dashPos;
- while(nameEnd > headStart && (nameEnd[-1] == ' ' || nameEnd[-1] == '\t'))
+ while (nameEnd > headStart && (nameEnd[-1] == ' ' || nameEnd[-1] == '\t')) {
--nameEnd;
+ }
- if(nameEnd > headStart)
+ if (nameEnd > headStart) {
ffStrbufAppendNS(&font->name, (uint32_t) (nameEnd - headStart), headStart);
+ }
- if(headEnd > sizeStart)
+ if (headEnd > sizeStart) {
ffStrbufAppendNS(&font->size, (uint32_t) (headEnd - sizeStart), sizeStart);
- }
- else
- {
- if(headEnd > headStart)
+ }
+ } else {
+ if (headEnd > headStart) {
ffStrbufAppendNS(&font->name, (uint32_t) (headEnd - headStart), headStart);
+ }
}
- }
- else
- {
- if(headEnd > headStart)
+ } else {
+ if (headEnd > headStart) {
ffStrbufAppendNS(&font->name, (uint32_t) (headEnd - headStart), headStart);
+ }
}
ffStrbufTrim(&font->name, ' ');
@@ -387,28 +384,27 @@ void ffFontInitXft(FFfont* font, const char* xft)
// 2) Parse key=value fields after ':' (Fontconfig-like). Fields separated by ':'.
// Common keys: size, pixelsize, pointsize, style, weight, slant, width
- while(*p == ':')
- {
+ while (*p == ':') {
++p;
// key
const char* keyStart = p;
- while(*p != '\0' && *p != '=' && *p != ':')
+ while (*p != '\0' && *p != '=' && *p != ':') {
++p;
+ }
const char* keyEnd = p;
- if(*p != '=')
+ if (*p != '=') {
continue; // skip tokens without '='
+ }
++p; // skip '='
// value (until next ':', allow backslash-escaping)
FF_STRBUF_AUTO_DESTROY value = ffStrbufCreate();
- while(*p != '\0' && *p != ':')
- {
- if(*p == '\\' && p[1] != '\0')
- {
+ while (*p != '\0' && *p != ':') {
+ if (*p == '\\' && p[1] != '\0') {
++p;
ffStrbufAppendC(&value, *p);
++p;
@@ -426,44 +422,36 @@ void ffFontInitXft(FFfont* font, const char* xft)
// helper: set numeric size if not set yet
const bool sizeEmpty = (font->size.length == 0);
- if(value.length > 0)
- {
- if(
+ if (value.length > 0) {
+ if (
(keyLen == 4 && ffStrStartsWithIgnCase(keyStart, "size")) ||
- (keyLen == 9 && ffStrStartsWithIgnCase(keyStart, "pixelsize"))
- )
- {
- if(sizeEmpty && ffCharIsDigit(value.chars[0]))
- {
+ (keyLen == 9 && ffStrStartsWithIgnCase(keyStart, "pixelsize"))) {
+ if (sizeEmpty && ffCharIsDigit(value.chars[0])) {
ffStrbufAppend(&font->size, &value);
ffStrbufAppendS(&font->size, keyLen == 4 ? "pt" : "px");
}
- }
- else if(keyLen == 5 && ffStrStartsWithIgnCase(keyStart, "style"))
- {
+ } else if (keyLen == 5 && ffStrStartsWithIgnCase(keyStart, "style")) {
// style may contain multiple words: "Bold Italic"
const char* s = value.chars;
- while(*s != '\0')
- {
- while(*s == ' ' || *s == '\t' || *s == ',')
+ while (*s != '\0') {
+ while (*s == ' ' || *s == '\t' || *s == ',') {
++s;
+ }
const char* w = s;
- while(*s != '\0' && *s != ' ' && *s != '\t' && *s != ',')
+ while (*s != '\0' && *s != ' ' && *s != '\t' && *s != ',') {
++s;
+ }
- if(s > w)
- {
+ if (s > w) {
FFstrbuf* style = FF_LIST_ADD(FFstrbuf, font->styles);
ffStrbufInitNS(style, (uint32_t) (s - w), w);
}
}
- }
- else if(
+ } else if (
(keyLen == 6 && ffStrStartsWithIgnCase(keyStart, "weight")) ||
(keyLen == 5 && ffStrStartsWithIgnCase(keyStart, "slant")) ||
- (keyLen == 5 && ffStrStartsWithIgnCase(keyStart, "width"))
- ) {
+ (keyLen == 5 && ffStrStartsWithIgnCase(keyStart, "width"))) {
// normalize: remove '-' to align with other parsers ("Semi-Bold" -> "SemiBold")
FFstrbuf* style = FF_LIST_ADD(FFstrbuf, font->styles);
ffStrbufInit(style);
@@ -476,14 +464,16 @@ void ffFontInitXft(FFfont* font, const char* xft)
fontInitPretty(font);
}
-void ffFontInitMoveValues(FFfont* font, FFstrbuf* name, FFstrbuf* size, FFstrbuf* style)
-{
+void ffFontInitMoveValues(FFfont* font, FFstrbuf* name, FFstrbuf* size, FFstrbuf* style) {
ffFontInit(font);
- if (name) ffStrbufInitMove(&font->name, name);
- if (size) ffStrbufInitMove(&font->size, size);
- if (style)
- {
+ if (name) {
+ ffStrbufInitMove(&font->name, name);
+ }
+ if (size) {
+ ffStrbufInitMove(&font->size, size);
+ }
+ if (style) {
FFstrbuf* styleBuf = FF_LIST_ADD(FFstrbuf, font->styles);
ffStrbufInitMove(styleBuf, style);
}
@@ -491,30 +481,28 @@ void ffFontInitMoveValues(FFfont* font, FFstrbuf* name, FFstrbuf* size, FFstrbuf
fontInitPretty(font);
}
-void ffFontInitWithSpace(FFfont* font, const char* rawName)
-{
+void ffFontInitWithSpace(FFfont* font, const char* rawName) {
const char* pspace = strrchr(rawName, ' ');
- if(pspace == NULL)
- {
+ if (pspace == NULL) {
ffFontInitCopy(font, rawName);
return;
}
ffFontInit(font);
- ffStrbufAppendNS(&font->name, (uint32_t)(pspace - rawName), rawName);
+ ffStrbufAppendNS(&font->name, (uint32_t) (pspace - rawName), rawName);
ffStrbufAppendS(&font->size, pspace + 1);
fontInitPretty(font);
}
-void ffFontDestroy(FFfont* font)
-{
+void ffFontDestroy(FFfont* font) {
ffStrbufDestroy(&font->pretty);
ffStrbufDestroy(&font->name);
ffStrbufDestroy(&font->size);
- FF_LIST_FOR_EACH(FFstrbuf, str, font->styles)
+ FF_LIST_FOR_EACH (FFstrbuf, str, font->styles) {
ffStrbufDestroy(str);
+ }
ffListDestroy(&font->styles);
}
diff --git a/src/common/impl/format.c b/src/common/impl/format.c
index 16b21c479d..37e7db623f 100644
--- a/src/common/impl/format.c
+++ b/src/common/impl/format.c
@@ -6,61 +6,58 @@
#include
-void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg)
-{
- switch(formatarg->type)
- {
+void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg) {
+ switch (formatarg->type) {
case FF_ARG_TYPE_INT:
- ffStrbufAppendSInt(buffer, *(int32_t*)formatarg->value);
+ ffStrbufAppendSInt(buffer, *(int32_t*) formatarg->value);
break;
case FF_ARG_TYPE_UINT:
- ffStrbufAppendUInt(buffer, *(uint32_t*)formatarg->value);
+ ffStrbufAppendUInt(buffer, *(uint32_t*) formatarg->value);
break;
case FF_ARG_TYPE_UINT64:
- ffStrbufAppendUInt(buffer, *(uint64_t*)formatarg->value);
+ ffStrbufAppendUInt(buffer, *(uint64_t*) formatarg->value);
break;
case FF_ARG_TYPE_UINT16:
- ffStrbufAppendUInt(buffer, *(uint16_t*)formatarg->value);
+ ffStrbufAppendUInt(buffer, *(uint16_t*) formatarg->value);
break;
case FF_ARG_TYPE_UINT8:
- ffStrbufAppendUInt(buffer, *(uint8_t*)formatarg->value);
+ ffStrbufAppendUInt(buffer, *(uint8_t*) formatarg->value);
break;
case FF_ARG_TYPE_STRING:
- ffStrbufAppendS(buffer, (const char*)formatarg->value);
+ ffStrbufAppendS(buffer, (const char*) formatarg->value);
break;
case FF_ARG_TYPE_STRBUF:
- ffStrbufAppend(buffer, (const FFstrbuf*)formatarg->value);
+ ffStrbufAppend(buffer, (const FFstrbuf*) formatarg->value);
break;
case FF_ARG_TYPE_FLOAT:
- ffStrbufAppendDouble(buffer, *(float*)formatarg->value, instance.config.display.fractionNdigits, instance.config.display.fractionTrailingZeros != FF_FRACTION_TRAILING_ZEROS_TYPE_NEVER);
+ ffStrbufAppendDouble(buffer, *(float*) formatarg->value, instance.config.display.fractionNdigits, instance.config.display.fractionTrailingZeros != FF_FRACTION_TRAILING_ZEROS_TYPE_NEVER);
break;
case FF_ARG_TYPE_DOUBLE:
- ffStrbufAppendDouble(buffer, *(double*)formatarg->value, instance.config.display.fractionNdigits, instance.config.display.fractionTrailingZeros != FF_FRACTION_TRAILING_ZEROS_TYPE_NEVER);
+ ffStrbufAppendDouble(buffer, *(double*) formatarg->value, instance.config.display.fractionNdigits, instance.config.display.fractionTrailingZeros != FF_FRACTION_TRAILING_ZEROS_TYPE_NEVER);
break;
case FF_ARG_TYPE_BOOL:
- ffStrbufAppendS(buffer, *(bool*)formatarg->value ? "true" : "false");
+ ffStrbufAppendS(buffer, *(bool*) formatarg->value ? "true" : "false");
break;
- case FF_ARG_TYPE_LIST:
- {
+ case FF_ARG_TYPE_LIST: {
const FFlist* list = (const FFlist*) formatarg->value;
- for(uint32_t i = 0; i < list->length; i++)
- {
+ for (uint32_t i = 0; i < list->length; i++) {
ffStrbufAppend(buffer, FF_LIST_GET(FFstrbuf, *list, i));
- if(i < list->length - 1)
+ if (i < list->length - 1) {
ffStrbufAppendS(buffer, ", ");
+ }
}
break;
}
- case FF_ARG_TYPE_BUFFER:
- {
+ case FF_ARG_TYPE_BUFFER: {
// Placeholder for binary data, just print the size for now
const FFArgBuffer* argBuffer = (const FFArgBuffer*) formatarg->value;
ffStrbufAppendF(buffer, "buffer(%u bytes)", argBuffer->length);
break;
}
default:
- if(formatarg->type != FF_ARG_TYPE_NULL)
+ if (formatarg->type != FF_ARG_TYPE_NULL) {
fprintf(stderr, "Error: format string \"%s\": argument is not implemented: %i\n", buffer->chars, formatarg->type);
+ }
break;
}
}
@@ -73,62 +70,48 @@ void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg)
* @param placeholderValue the string to parse
* @return uint32_t the parsed value
*/
-static uint32_t getArgumentIndex(const char* placeholderValue, uint32_t numArgs, const FFformatarg* arguments)
-{
+static uint32_t getArgumentIndex(const char* placeholderValue, uint32_t numArgs, const FFformatarg* arguments) {
char firstChar = placeholderValue[0];
- if (firstChar == '\0')
+ if (firstChar == '\0') {
return 0; // use arg counter
+ }
- if (firstChar >= '0' && firstChar <= '9')
- {
+ if (firstChar >= '0' && firstChar <= '9') {
char* pEnd = NULL;
uint32_t result = (uint32_t) strtoul(placeholderValue, &pEnd, 10);
- if (result > numArgs)
+ if (result > numArgs) {
return UINT32_MAX;
- if (*pEnd != '\0')
+ }
+ if (*pEnd != '\0') {
return UINT32_MAX;
+ }
return result;
- }
- else if (ffCharIsEnglishAlphabet(firstChar))
- {
- for (uint32_t i = 0; i < numArgs; ++i)
- {
+ } else if (ffCharIsEnglishAlphabet(firstChar)) {
+ for (uint32_t i = 0; i < numArgs; ++i) {
const FFformatarg* arg = &arguments[i];
- if (arg->name && ffStrEqualsIgnCase(placeholderValue, arg->name))
+ if (arg->name && ffStrEqualsIgnCase(placeholderValue, arg->name)) {
return i + 1;
+ }
}
}
return UINT32_MAX;
}
-static inline void appendInvalidPlaceholder(FFstrbuf* buffer, const char* start, const FFstrbuf* placeholderValue, uint32_t index, uint32_t formatStringLength)
-{
+static inline void appendInvalidPlaceholder(FFstrbuf* buffer, const char* start, const FFstrbuf* placeholderValue, uint32_t index, uint32_t formatStringLength) {
ffStrbufAppendS(buffer, start);
ffStrbufAppend(buffer, placeholderValue);
- if(index < formatStringLength)
+ if (index < formatStringLength) {
ffStrbufAppendC(buffer, '}');
+ }
}
-static inline bool formatArgSet(const FFformatarg* arg)
-{
- return arg->value != NULL && (
- (arg->type == FF_ARG_TYPE_DOUBLE && *(double*)arg->value > 0.0) ||
- (arg->type == FF_ARG_TYPE_FLOAT && *(float*)arg->value > 0.0) ||
- (arg->type == FF_ARG_TYPE_INT && *(int*)arg->value > 0) ||
- (arg->type == FF_ARG_TYPE_STRBUF && ((FFstrbuf*)arg->value)->length > 0) ||
- (arg->type == FF_ARG_TYPE_STRING && ffStrSet((char*)arg->value)) ||
- (arg->type == FF_ARG_TYPE_UINT8 && *(uint8_t*)arg->value > 0) ||
- (arg->type == FF_ARG_TYPE_UINT16 && *(uint16_t*)arg->value > 0) ||
- (arg->type == FF_ARG_TYPE_UINT && *(uint32_t*)arg->value > 0) ||
- (arg->type == FF_ARG_TYPE_BOOL && *(bool*)arg->value) ||
- (arg->type == FF_ARG_TYPE_LIST && ((FFlist*)arg->value)->length > 0)
- );
+static inline bool formatArgSet(const FFformatarg* arg) {
+ return arg->value != NULL && ((arg->type == FF_ARG_TYPE_DOUBLE && *(double*) arg->value > 0.0) || (arg->type == FF_ARG_TYPE_FLOAT && *(float*) arg->value > 0.0) || (arg->type == FF_ARG_TYPE_INT && *(int*) arg->value > 0) || (arg->type == FF_ARG_TYPE_STRBUF && ((FFstrbuf*) arg->value)->length > 0) || (arg->type == FF_ARG_TYPE_STRING && ffStrSet((char*) arg->value)) || (arg->type == FF_ARG_TYPE_UINT8 && *(uint8_t*) arg->value > 0) || (arg->type == FF_ARG_TYPE_UINT16 && *(uint16_t*) arg->value > 0) || (arg->type == FF_ARG_TYPE_UINT && *(uint32_t*) arg->value > 0) || (arg->type == FF_ARG_TYPE_BOOL && *(bool*) arg->value) || (arg->type == FF_ARG_TYPE_LIST && ((FFlist*) arg->value)->length > 0));
}
-void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t numArgs, const FFformatarg* arguments)
-{
+void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t numArgs, const FFformatarg* arguments) {
uint32_t argCounter = 0;
uint32_t numOpenIfs = 0;
@@ -136,11 +119,9 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
FF_STRBUF_AUTO_DESTROY placeholderValue = ffStrbufCreate();
- for(uint32_t i = 0; i < formatstr->length; ++i)
- {
+ for (uint32_t i = 0; i < formatstr->length; ++i) {
// if we don't have a placeholder start just copy the chars over to output buffer
- if(formatstr->chars[i] != '{')
- {
+ if (formatstr->chars[i] != '{') {
ffStrbufAppendC(buffer, formatstr->chars[i]);
continue;
}
@@ -149,8 +130,7 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
++i;
// double {{ elvaluates to a single { and doesn't count as start
- if(formatstr->chars[i] == '{')
- {
+ if (formatstr->chars[i] == '{') {
ffStrbufAppendC(buffer, '{');
continue;
}
@@ -165,61 +145,58 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
char firstChar = placeholderValue.chars[0];
- if (placeholderValue.length == 1)
- {
+ if (placeholderValue.length == 1) {
// test if for stop, if so break the loop
- if (firstChar == '-')
+ if (firstChar == '-') {
break;
+ }
// test for end of an if, if so do nothing
- if (firstChar == '?')
- {
- if(numOpenIfs == 0)
+ if (firstChar == '?') {
+ if (numOpenIfs == 0) {
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
- else
+ } else {
--numOpenIfs;
+ }
continue;
}
// test for end of a not if, if so do nothing
- if (firstChar == '/')
- {
- if(numOpenNotIfs == 0)
+ if (firstChar == '/') {
+ if (numOpenNotIfs == 0) {
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
- else
+ } else {
--numOpenNotIfs;
+ }
continue;
}
// test for end of a color, if so do nothing
- if (firstChar == '#')
- {
- if (!instance.config.display.pipe)
+ if (firstChar == '#') {
+ if (!instance.config.display.pipe) {
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
+ }
continue;
}
}
// test for if, if so evaluate it
- if (firstChar == '?')
- {
+ if (firstChar == '?') {
ffStrbufSubstrAfter(&placeholderValue, 0);
uint32_t index = getArgumentIndex(placeholderValue.chars, numArgs, arguments);
// testing for an invalid index
- if (index > numArgs || index < 1)
- {
+ if (index > numArgs || index < 1) {
appendInvalidPlaceholder(buffer, "{?", &placeholderValue, i, formatstr->length);
continue;
}
// continue normally if an format arg is set and the value is > 0
- if (formatArgSet(&arguments[index - 1]))
- {
+ if (formatArgSet(&arguments[index - 1])) {
++numOpenIfs;
continue;
}
@@ -230,22 +207,19 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
}
// test for not if, if so evaluate it
- if (firstChar == '/')
- {
+ if (firstChar == '/') {
ffStrbufSubstrAfter(&placeholderValue, 0);
uint32_t index = getArgumentIndex(placeholderValue.chars, numArgs, arguments);
// testing for an invalid index
- if (index > numArgs || index < 1)
- {
+ if (index > numArgs || index < 1) {
appendInvalidPlaceholder(buffer, "{/", &placeholderValue, i, formatstr->length);
continue;
}
- //continue normally if an format arg is not set or the value is 0
- if (!formatArgSet(&arguments[index - 1]))
- {
+ // continue normally if an format arg is not set or the value is 0
+ if (!formatArgSet(&arguments[index - 1])) {
++numOpenNotIfs;
continue;
}
@@ -255,11 +229,9 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
continue;
}
- //test for color, if so evaluate it
- if (firstChar == '#')
- {
- if (!instance.config.display.pipe)
- {
+ // test for color, if so evaluate it
+ if (firstChar == '#') {
+ if (!instance.config.display.pipe) {
ffStrbufAppendS(buffer, "\e[");
ffOptionParseColorNoClear(placeholderValue.chars + 1, buffer);
ffStrbufAppendC(buffer, 'm');
@@ -267,29 +239,25 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
continue;
}
- //test for constant or env var, if so evaluate it
- if (firstChar == '$')
- {
+ // test for constant or env var, if so evaluate it
+ if (firstChar == '$') {
char* pend = NULL;
int32_t indexSigned = (int32_t) strtol(placeholderValue.chars + 1, &pend, 10);
- if (pend == placeholderValue.chars + 1)
- {
+ if (pend == placeholderValue.chars + 1) {
// treat placeholder as an environment variable
char* envValue = getenv(placeholderValue.chars + 1);
- if (envValue)
+ if (envValue) {
ffStrbufAppendS(buffer, envValue);
- else
+ } else {
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
- }
- else
- {
+ }
+ } else {
// treat placeholder as a constant
uint32_t index = (uint32_t) (indexSigned < 0 ? (int32_t) instance.config.display.constants.length + indexSigned : indexSigned - 1);
- if (*pend != '\0' || instance.config.display.constants.length <= index)
+ if (*pend != '\0' || instance.config.display.constants.length <= index) {
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
- else
- {
+ } else {
FFstrbuf* item = FF_LIST_GET(FFstrbuf, instance.config.display.constants, index);
ffStrbufAppend(buffer, item);
}
@@ -299,115 +267,104 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
char* pSep = placeholderValue.chars;
char cSep = '\0';
- while (*pSep && *pSep != ':' && *pSep != '<' && *pSep != '>' && *pSep != '~')
+ while (*pSep && *pSep != ':' && *pSep != '<' && *pSep != '>' && *pSep != '~') {
++pSep;
- if (*pSep)
- {
+ }
+ if (*pSep) {
cSep = *pSep;
*pSep = '\0';
- }
- else
- {
+ } else {
pSep = NULL;
}
uint32_t index = getArgumentIndex(placeholderValue.chars, numArgs, arguments);
// test for invalid index
- if (index == 0)
+ if (index == 0) {
index = ++argCounter;
+ }
- if (index > numArgs)
- {
- if (pSep) *pSep = cSep;
+ if (index > numArgs) {
+ if (pSep) {
+ *pSep = cSep;
+ }
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
continue;
}
- if (!cSep)
+ if (!cSep) {
ffFormatAppendFormatArg(buffer, &arguments[index - 1]);
- else if (cSep == '~')
- {
+ } else if (cSep == '~') {
FF_STRBUF_AUTO_DESTROY tempString = ffStrbufCreate();
ffFormatAppendFormatArg(&tempString, &arguments[index - 1]);
char* pEnd = NULL;
int32_t start = (int32_t) strtol(pSep + 1, &pEnd, 10);
- if (start < 0)
+ if (start < 0) {
start = (int32_t) tempString.length + start;
- if (start >= 0 && (uint32_t) start < tempString.length)
- {
- if (*pEnd == '\0')
+ }
+ if (start >= 0 && (uint32_t) start < tempString.length) {
+ if (*pEnd == '\0') {
ffStrbufAppendNS(buffer, tempString.length - (uint32_t) start, &tempString.chars[start]);
- else if (*pEnd == ',')
- {
+ } else if (*pEnd == ',') {
int32_t end = (int32_t) strtol(pEnd + 1, &pEnd, 10);
- if (!*pEnd)
- {
- if (end < 0)
+ if (!*pEnd) {
+ if (end < 0) {
end = (int32_t) tempString.length + end;
- if ((uint32_t) end > tempString.length)
+ }
+ if ((uint32_t) end > tempString.length) {
end = (int32_t) tempString.length;
- if (end > start)
+ }
+ if (end > start) {
ffStrbufAppendNS(buffer, (uint32_t) (end - start), &tempString.chars[start]);
+ }
}
}
}
- if (*pEnd)
- {
+ if (*pEnd) {
*pSep = cSep;
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
continue;
}
- }
- else
- {
+ } else {
char* pEnd = NULL;
int32_t truncLength = (int32_t) strtol(pSep + 1, &pEnd, 10);
- if (*pEnd != '\0')
- {
+ if (*pEnd != '\0') {
*pSep = cSep;
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
continue;
}
bool ellipsis = false;
- if (truncLength < 0)
- {
+ if (truncLength < 0) {
ellipsis = true;
truncLength = -truncLength;
}
FF_STRBUF_AUTO_DESTROY tempString = ffStrbufCreate();
ffFormatAppendFormatArg(&tempString, &arguments[index - 1]);
- if (tempString.length == (uint32_t) truncLength)
+ if (tempString.length == (uint32_t) truncLength) {
ffStrbufAppend(buffer, &tempString);
- else if (tempString.length > (uint32_t) truncLength)
- {
- if (cSep == ':')
- {
+ } else if (tempString.length > (uint32_t) truncLength) {
+ if (cSep == ':') {
ffStrbufSubstrBefore(&tempString, (uint32_t) truncLength);
ffStrbufTrimRightSpace(&tempString);
+ } else {
+ ffStrbufSubstrBefore(&tempString, (uint32_t) (!ellipsis ? truncLength : truncLength - 1));
}
- else
- ffStrbufSubstrBefore(&tempString, (uint32_t) (!ellipsis? truncLength : truncLength - 1));
ffStrbufAppend(buffer, &tempString);
- if (ellipsis)
+ if (ellipsis) {
ffStrbufAppendS(buffer, "…");
- }
- else if (cSep == ':')
+ }
+ } else if (cSep == ':') {
ffStrbufAppend(buffer, &tempString);
- else
- {
- if (cSep == '<')
- {
+ } else {
+ if (cSep == '<') {
ffStrbufAppend(buffer, &tempString);
ffStrbufAppendNC(buffer, (uint32_t) truncLength - tempString.length, ' ');
- }
- else
- {
+ } else {
ffStrbufAppendNC(buffer, (uint32_t) truncLength - tempString.length, ' ');
ffStrbufAppend(buffer, &tempString);
}
@@ -415,6 +372,7 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
}
}
- if (!instance.config.display.pipe)
+ if (!instance.config.display.pipe) {
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
+ }
}
diff --git a/src/common/impl/frequency.c b/src/common/impl/frequency.c
index 3e5185be41..4838df8037 100644
--- a/src/common/impl/frequency.c
+++ b/src/common/impl/frequency.c
@@ -1,24 +1,25 @@
#include "common/frequency.h"
-bool ffFreqAppendNum(uint32_t mhz, FFstrbuf* result)
-{
- if (mhz == 0)
+bool ffFreqAppendNum(uint32_t mhz, FFstrbuf* result) {
+ if (mhz == 0) {
return false;
+ }
const FFOptionsDisplay* options = &instance.config.display;
bool spaceBeforeUnit = options->freqSpaceBeforeUnit != FF_SPACE_BEFORE_UNIT_NEVER;
int8_t ndigits = options->freqNdigits;
- if (ndigits >= 0)
- {
+ if (ndigits >= 0) {
ffStrbufAppendDouble(result, mhz / 1000., ndigits, true);
- if (spaceBeforeUnit) ffStrbufAppendC(result, ' ');
+ if (spaceBeforeUnit) {
+ ffStrbufAppendC(result, ' ');
+ }
ffStrbufAppendS(result, "GHz");
- }
- else
- {
+ } else {
ffStrbufAppendUInt(result, mhz);
- if (spaceBeforeUnit) ffStrbufAppendC(result, ' ');
+ if (spaceBeforeUnit) {
+ ffStrbufAppendC(result, ' ');
+ }
ffStrbufAppendS(result, "MHz");
}
return true;
diff --git a/src/common/impl/init.c b/src/common/impl/init.c
index 18c250d339..767eb7fdce 100644
--- a/src/common/impl/init.c
+++ b/src/common/impl/init.c
@@ -19,8 +19,7 @@
FFinstance instance; // Global singleton
-static void initState(FFstate* state)
-{
+static void initState(FFstate* state) {
state->logoWidth = 0;
state->logoHeight = 0;
state->keysHeight = 0;
@@ -33,27 +32,26 @@ static void initState(FFstate* state)
{
// don't enable bright color if the terminal is in light mode
FFTerminalThemeResult result;
- if (ffDetectTerminalTheme(&result, true /* forceEnv for performance */) && !result.bg.dark)
+ if (ffDetectTerminalTheme(&result, true /* forceEnv for performance */) && !result.bg.dark) {
state->terminalLightTheme = true;
+ }
}
}
-static void defaultConfig(void)
-{
+static void defaultConfig(void) {
ffOptionsInitLogo(&instance.config.logo);
ffOptionsInitGeneral(&instance.config.general);
ffOptionsInitDisplay(&instance.config.display);
}
-void ffInitInstance(void)
-{
- #ifdef _WIN32
- // https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale?source=recommendat>
- setlocale(LC_ALL, ".UTF8");
- #else
- // Never use `setlocale(LC_ALL, "")`
- setlocale(LC_TIME, "");
- #endif
+void ffInitInstance(void) {
+#ifdef _WIN32
+ // https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale?source=recommendat>
+ setlocale(LC_ALL, ".UTF8");
+#else
+ // Never use `setlocale(LC_ALL, "")`
+ setlocale(LC_TIME, "");
+#endif
defaultConfig();
initState(&instance.state);
@@ -65,61 +63,65 @@ static volatile bool ffHideCursor = true;
static volatile UINT oldCp = CP_UTF8;
#endif
-static void resetConsole(void)
-{
- if(ffDisableLinewrap)
+static void resetConsole(void) {
+ if (ffDisableLinewrap) {
fputs("\033[?7h", stdout);
+ }
- if(ffHideCursor)
+ if (ffHideCursor) {
fputs("\033[?25h", stdout);
+ }
- if(instance.state.dynamicInterval > 0)
+ if (instance.state.dynamicInterval > 0) {
fputs("\033[?1049l", stdout); // Disable alternate buffer
+ }
- #if defined(_WIN32)
- fflush(stdout);
+#if defined(_WIN32)
+ fflush(stdout);
- if(oldCp != CP_UTF8)
- SetConsoleOutputCP(oldCp);
- #endif
+ if (oldCp != CP_UTF8) {
+ SetConsoleOutputCP(oldCp);
+ }
+#endif
}
#ifdef _WIN32
-BOOL WINAPI consoleHandler(FF_MAYBE_UNUSED DWORD signal)
-{
+BOOL WINAPI consoleHandler(FF_A_UNUSED DWORD signal) {
resetConsole();
exit(0);
}
#else
-static void exitSignalHandler(FF_MAYBE_UNUSED int signal)
-{
+static void exitSignalHandler(FF_A_UNUSED int signal) {
resetConsole();
exit(0);
}
#endif
-void ffStart(void)
-{
+void ffStart(void) {
ffDisableLinewrap = instance.config.display.disableLinewrap && !instance.config.display.pipe;
ffHideCursor = instance.config.display.hideCursor && !instance.config.display.pipe;
- #ifdef _WIN32
+#ifdef _WIN32
SetErrorMode(SEM_FAILCRITICALERRORS);
- if (instance.config.display.noBuffer)
+ if (instance.config.display.noBuffer) {
setvbuf(stdout, NULL, _IONBF, 0);
- else
+ } else {
setvbuf(stdout, NULL, _IOFBF, 4096);
+ }
SetConsoleCtrlHandler(consoleHandler, TRUE);
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD mode = 0;
- if (GetConsoleMode(hStdout, &mode))
- {
+ if (GetConsoleMode(hStdout, &mode)) {
SetConsoleMode(hStdout, mode | ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
oldCp = GetConsoleOutputCP();
- if (oldCp != CP_UTF8) SetConsoleOutputCP(CP_UTF8);
+ if (oldCp != CP_UTF8) {
+ SetConsoleOutputCP(CP_UTF8);
+ }
+ }
+#else
+ if (instance.config.display.noBuffer) {
+ setvbuf(stdout, NULL, _IONBF, 0);
}
- #else
- if (instance.config.display.noBuffer) setvbuf(stdout, NULL, _IONBF, 0);
struct sigaction action = { .sa_handler = exitSignalHandler };
sigaction(SIGINT, &action, NULL);
sigaction(SIGTERM, &action, NULL);
@@ -128,142 +130,139 @@ void ffStart(void)
sigemptyset(&newmask);
sigaddset(&newmask, SIGCHLD);
sigprocmask(SIG_BLOCK, &newmask, NULL);
- #endif
+#endif
- //reset everything to default before we start printing
- if(!instance.config.display.pipe)
+ // reset everything to default before we start printing
+ if (!instance.config.display.pipe) {
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
+ }
- if(ffHideCursor)
+ if (ffHideCursor) {
fputs("\033[?25l", stdout);
+ }
- if(ffDisableLinewrap)
+ if (ffDisableLinewrap) {
fputs("\033[?7l", stdout);
+ }
- if(instance.state.dynamicInterval > 0)
- {
+ if (instance.state.dynamicInterval > 0) {
fputs("\033[?1049h\033[H", stdout); // Enable alternate buffer
fflush(stdout);
}
}
-void ffFinish(void)
-{
+void ffFinish(void) {
resetConsole();
}
-static void destroyConfig(void)
-{
+static void destroyConfig(void) {
ffOptionsDestroyLogo(&instance.config.logo);
ffOptionsDestroyGeneral(&instance.config.general);
ffOptionsDestroyDisplay(&instance.config.display);
}
-static void destroyState(void)
-{
+static void destroyState(void) {
ffPlatformDestroy(&instance.state.platform);
}
-void ffDestroyInstance(void)
-{
+void ffDestroyInstance(void) {
destroyConfig();
destroyState();
}
-//Must be in a file compiled with the libfastfetch target, because the FF_HAVE* macros are not defined for the executable targets
-void ffListFeatures(void)
-{
+// Must be in a file compiled with the libfastfetch target, because the FF_HAVE* macros are not defined for the executable targets
+void ffListFeatures(void) {
fputs(
- #if FF_HAVE_THREADS
- "threads\n"
- #endif
- #if FF_HAVE_VULKAN
- "vulkan\n"
- #endif
- #if FF_HAVE_WAYLAND
- "wayland\n"
- #endif
- #if FF_HAVE_XCB_RANDR
- "xcb-randr\n"
- #endif
- #if FF_HAVE_XRANDR
- "xrandr\n"
- #endif
- #if FF_HAVE_DRM
- "drm\n"
- #endif
- #if FF_HAVE_DRM_AMDGPU
- "drm_amdgpu\n"
- #endif
- #if FF_HAVE_GIO
- "gio\n"
- #endif
- #if FF_HAVE_DCONF
- "dconf\n"
- #endif
- #if FF_HAVE_DBUS
- "dbus\n"
- #endif
- #if FF_HAVE_IMAGEMAGICK7
- "imagemagick7\n"
- #endif
- #if FF_HAVE_IMAGEMAGICK6
- "imagemagick6\n"
- #endif
- #if FF_HAVE_CHAFA
- "chafa\n"
- #endif
- #if FF_HAVE_ZLIB
- "zlib\n"
- #endif
- #if FF_HAVE_SQLITE3
- "sqlite3\n"
- #endif
- #if FF_HAVE_RPM
- "rpm\n"
- #endif
- #if FF_HAVE_EGL
- "egl\n"
- #endif
- #if FF_HAVE_GLX
- "glx\n"
- #endif
- #if FF_HAVE_OPENCL
- "opencl\n"
- #endif
- #if FF_HAVE_FREETYPE
- "freetype\n"
- #endif
- #if FF_HAVE_PULSE
- "libpulse\n"
- #endif
- #if FF_HAVE_DDCUTIL
- "libddcutil\n"
- #endif
- #if FF_HAVE_ELF || __sun || (__FreeBSD__ && !__DragonFly__) || __OpenBSD__ || __NetBSD__
- "libelf\n"
- #endif
- #if FF_HAVE_LIBZFS
- "libzfs\n"
- #endif
- #if FF_USE_SYSTEM_YYJSON
- "System yyjson\n"
- #endif
- #if FF_HAVE_LINUX_VIDEODEV2
- "linux/videodev2\n"
- #endif
- #if FF_HAVE_LINUX_WIRELESS
- "linux/wireless\n"
- #endif
- #if FF_HAVE_EMBEDDED_PCIIDS
- "Embedded pciids\n"
- #endif
- #if FF_WIN81_COMPAT
- "Windows 8.1 Compatibility\n"
- #endif
- #if FF_APPLE_MEMSIZE_USABLE
- "Apple memsize_usable\n"
- #endif
- ""
- , stdout);
+#if FF_HAVE_THREADS
+ "threads\n"
+#endif
+#if FF_HAVE_VULKAN
+ "vulkan\n"
+#endif
+#if FF_HAVE_WAYLAND
+ "wayland\n"
+#endif
+#if FF_HAVE_XCB_RANDR
+ "xcb-randr\n"
+#endif
+#if FF_HAVE_XRANDR
+ "xrandr\n"
+#endif
+#if FF_HAVE_DRM
+ "drm\n"
+#endif
+#if FF_HAVE_DRM_AMDGPU
+ "drm_amdgpu\n"
+#endif
+#if FF_HAVE_GIO
+ "gio\n"
+#endif
+#if FF_HAVE_DCONF
+ "dconf\n"
+#endif
+#if FF_HAVE_DBUS
+ "dbus\n"
+#endif
+#if FF_HAVE_IMAGEMAGICK7
+ "imagemagick7\n"
+#endif
+#if FF_HAVE_IMAGEMAGICK6
+ "imagemagick6\n"
+#endif
+#if FF_HAVE_CHAFA
+ "chafa\n"
+#endif
+#if FF_HAVE_ZLIB
+ "zlib\n"
+#endif
+#if FF_HAVE_SQLITE3
+ "sqlite3\n"
+#endif
+#if FF_HAVE_RPM
+ "rpm\n"
+#endif
+#if FF_HAVE_EGL
+ "egl\n"
+#endif
+#if FF_HAVE_GLX
+ "glx\n"
+#endif
+#if FF_HAVE_OPENCL
+ "opencl\n"
+#endif
+#if FF_HAVE_FREETYPE
+ "freetype\n"
+#endif
+#if FF_HAVE_PULSE
+ "libpulse\n"
+#endif
+#if FF_HAVE_DDCUTIL
+ "libddcutil\n"
+#endif
+#if FF_HAVE_ELF || __sun || (__FreeBSD__ && !__DragonFly__) || __OpenBSD__ || __NetBSD__
+ "libelf\n"
+#endif
+#if FF_HAVE_LIBZFS
+ "libzfs\n"
+#endif
+#if FF_USE_SYSTEM_YYJSON
+ "System yyjson\n"
+#endif
+#if FF_HAVE_LINUX_VIDEODEV2
+ "linux/videodev2\n"
+#endif
+#if FF_HAVE_LINUX_WIRELESS
+ "linux/wireless\n"
+#endif
+#if FF_HAVE_EMBEDDED_PCIIDS
+ "Embedded pciids\n"
+#endif
+#if FF_WIN81_COMPAT
+ "Windows 8.1 Compatibility\n"
+#endif
+#if FF_APPLE_MEMSIZE_USABLE
+ "Apple memsize_usable\n"
+#endif
+ "",
+ stdout);
}
diff --git a/src/common/impl/io_unix.c b/src/common/impl/io_unix.c
index 12c07d7169..65cc9121a4 100644
--- a/src/common/impl/io_unix.c
+++ b/src/common/impl/io_unix.c
@@ -8,9 +8,9 @@
#include
#include
#ifndef __APPLE__
-#include
+ #include
#else
-#include
+ #include
#endif
#if FF_HAVE_WORDEXP
@@ -19,170 +19,166 @@
#include
#endif
-static void createSubfolders(const char* fileName)
-{
+static void createSubfolders(const char* fileName) {
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate();
- const char *token = NULL;
- while((token = strchr(fileName, '/')) != NULL)
- {
- ffStrbufAppendNS(&path, (uint32_t)(token - fileName + 1), fileName);
+ const char* token = NULL;
+ while ((token = strchr(fileName, '/')) != NULL) {
+ ffStrbufAppendNS(&path, (uint32_t) (token - fileName + 1), fileName);
mkdir(path.chars, S_IRWXU | S_IRGRP | S_IROTH);
fileName = token + 1;
}
}
-bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data)
-{
+bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data) {
int openFlagsModes = O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC;
mode_t openFlagsRights = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
int FF_AUTO_CLOSE_FD fd = open(fileName, openFlagsModes, openFlagsRights);
- if(fd == -1)
- {
- if (errno == ENOENT)
- {
+ if (fd == -1) {
+ if (errno == ENOENT) {
createSubfolders(fileName);
fd = open(fileName, openFlagsModes, openFlagsRights);
- if(fd == -1)
+ if (fd == -1) {
return false;
- }
- else
+ }
+ } else {
return false;
+ }
}
return write(fd, data, dataSize) > 0;
}
-static inline void readWithLength(int fd, FFstrbuf* buffer, uint32_t length)
-{
+static inline void readWithLength(int fd, FFstrbuf* buffer, uint32_t length) {
ffStrbufEnsureFixedLengthFree(buffer, length);
ssize_t bytesRead = 0;
- while(
- length > 0 && (bytesRead = read(fd, buffer->chars + buffer->length, length)) > 0
- ) {
+ while (
+ length > 0 && (bytesRead = read(fd, buffer->chars + buffer->length, length)) > 0) {
buffer->length += (uint32_t) bytesRead;
length -= (uint32_t) bytesRead;
}
}
-static inline void readUntilEOF(int fd, FFstrbuf* buffer)
-{
+static inline void readUntilEOF(int fd, FFstrbuf* buffer) {
ffStrbufEnsureFree(buffer, 31);
uint32_t available = ffStrbufGetFree(buffer);
ssize_t bytesRead = 0;
- while(
- (bytesRead = read(fd, buffer->chars + buffer->length, available)) > 0
- ) {
+ while (
+ (bytesRead = read(fd, buffer->chars + buffer->length, available)) > 0) {
buffer->length += (uint32_t) bytesRead;
- if((uint32_t) bytesRead == available)
+ if ((uint32_t) bytesRead == available) {
ffStrbufEnsureFree(buffer, buffer->allocated - 1); // Doubles capacity every round. -1 for the null byte.
+ }
available = ffStrbufGetFree(buffer);
}
}
-bool ffAppendFDBuffer(int fd, FFstrbuf* buffer)
-{
+bool ffAppendFDBuffer(int fd, FFstrbuf* buffer) {
struct stat fileInfo;
- if(fstat(fd, &fileInfo) != 0)
+ if (fstat(fd, &fileInfo) != 0) {
return false;
+ }
- if (fileInfo.st_size > 0)
- readWithLength(fd, buffer, (uint32_t)fileInfo.st_size);
- else
+ if (fileInfo.st_size > 0) {
+ readWithLength(fd, buffer, (uint32_t) fileInfo.st_size);
+ } else {
readUntilEOF(fd, buffer);
+ }
buffer->chars[buffer->length] = '\0';
return buffer->length > 0;
}
-bool ffPathExpandEnv(const char* in, FFstrbuf* out)
-{
+bool ffPathExpandEnv(const char* in, FFstrbuf* out) {
bool result = false;
- #if FF_HAVE_WORDEXP
+#if FF_HAVE_WORDEXP
wordexp_t exp;
- if (wordexp(in, &exp, 0) != 0) // WARN: 0 = no safety flags; command substitution allowed
+ if (wordexp(in, &exp, 0) != 0) { // WARN: 0 = no safety flags; command substitution allowed
return false;
+ }
- if (exp.we_wordc >= 1)
- {
+ if (exp.we_wordc >= 1) {
result = true;
ffStrbufSetS(out, exp.we_wordv[exp.we_wordc > 1 ? ffTimeGetNow() % exp.we_wordc : 0]);
}
wordfree(&exp);
- #else
+#else
glob_t gb;
if (glob(in, GLOB_NOSORT
- #ifdef GLOB_TILDE
- | GLOB_TILDE
- #endif
- #ifdef GLOB_BRACE
- | GLOB_BRACE
- #endif
- , NULL, &gb) != 0)
+ #ifdef GLOB_TILDE
+ | GLOB_TILDE
+ #endif
+ #ifdef GLOB_BRACE
+ | GLOB_BRACE
+ #endif
+ ,
+ NULL,
+ &gb) != 0)
return false;
- if (gb.gl_pathc >= 1)
- {
+ if (gb.gl_pathc >= 1) {
result = true;
ffStrbufSetS(out, gb.gl_pathv[gb.gl_pathc > 1 ? ffTimeGetNow() % (unsigned) gb.gl_pathc : 0]);
}
globfree(&gb);
- #endif
+#endif
return result;
}
static int ftty = -1;
static struct termios oldTerm;
-void restoreTerm(void)
-{
+void restoreTerm(void) {
tcsetattr(ftty, TCSAFLUSH, &oldTerm);
}
-const char* ffGetTerminalResponse(const char* request, int nParams, const char* format, ...)
-{
- if (ftty < 0)
- {
+const char* ffGetTerminalResponse(const char* request, int nParams, const char* format, ...) {
+ if (ftty < 0) {
ftty = open("/dev/tty", O_RDWR | O_NOCTTY | O_CLOEXEC);
- if (ftty < 0)
+ if (ftty < 0) {
return "open(\"/dev/tty\", O_RDWR | O_NOCTTY | O_CLOEXEC) failed";
+ }
- if(tcgetattr(ftty, &oldTerm) == -1)
+ if (tcgetattr(ftty, &oldTerm) == -1) {
return "tcgetattr(STDIN_FILENO, &oldTerm) failed";
+ }
struct termios newTerm = oldTerm;
newTerm.c_lflag &= (tcflag_t) ~(ICANON | ECHO);
- if(tcsetattr(ftty, TCSAFLUSH, &newTerm) == -1)
+ if (tcsetattr(ftty, TCSAFLUSH, &newTerm) == -1) {
return "tcsetattr(STDIN_FILENO, TCSAFLUSH, &newTerm)";
+ }
atexit(restoreTerm);
}
ffWriteFDData(ftty, strlen(request), request);
- //Give the terminal some time to respond
- #ifndef __APPLE__
- if(poll(&(struct pollfd) { .fd = ftty, .events = POLLIN }, 1, FF_IO_TERM_RESP_WAIT_MS) <= 0)
+// Give the terminal some time to respond
+#ifndef __APPLE__
+ if (poll(&(struct pollfd) { .fd = ftty, .events = POLLIN }, 1, FF_IO_TERM_RESP_WAIT_MS) <= 0) {
return "poll(/dev/tty) timeout or failed";
- #else
+ }
+#else
{
// On macOS, poll(/dev/tty) always returns immediately
// See also https://nathancraddock.com/blog/macos-dev-tty-polling/
fd_set rd;
FD_ZERO(&rd);
FD_SET(ftty, &rd);
- if(select(ftty + 1, &rd, NULL, NULL, &(struct timeval) { .tv_sec = FF_IO_TERM_RESP_WAIT_MS / 1000, .tv_usec = (FF_IO_TERM_RESP_WAIT_MS % 1000) * 1000 }) <= 0)
+ if (select(ftty + 1, &rd, NULL, NULL, &(struct timeval) { .tv_sec = FF_IO_TERM_RESP_WAIT_MS / 1000, .tv_usec = (FF_IO_TERM_RESP_WAIT_MS % 1000) * 1000 }) <= 0) {
return "select(/dev/tty) timeout or failed";
+ }
}
- #endif
+#endif
char buffer[1024];
size_t bytesRead = 0;
@@ -190,12 +186,10 @@ const char* ffGetTerminalResponse(const char* request, int nParams, const char*
va_list args;
va_start(args, format);
- while (true)
- {
+ while (true) {
ssize_t nRead = read(ftty, buffer + bytesRead, sizeof(buffer) - bytesRead - 1);
- if (nRead <= 0)
- {
+ if (nRead <= 0) {
va_end(args);
return "read(STDIN_FILENO, buffer, sizeof(buffer) - 1) failed";
}
@@ -208,13 +202,13 @@ const char* ffGetTerminalResponse(const char* request, int nParams, const char*
int ret = vsscanf(buffer, format, cargs);
va_end(cargs);
- if (ret <= 0)
- {
+ if (ret <= 0) {
va_end(args);
return "vsscanf(buffer, format, args) failed";
}
- if (ret >= nParams)
+ if (ret >= nParams) {
break;
+ }
}
va_end(args);
@@ -222,22 +216,22 @@ const char* ffGetTerminalResponse(const char* request, int nParams, const char*
return NULL;
}
-bool ffSuppressIO(bool suppress)
-{
- #ifndef NDEBUG
- if (instance.config.display.debugMode)
+bool ffSuppressIO(bool suppress) {
+#ifndef NDEBUG
+ if (instance.config.display.debugMode) {
return false;
- #endif
+ }
+#endif
static bool init = false;
static int origOut = -1;
static int origErr = -1;
static int nullFile = -1;
- if(!init)
- {
- if(!suppress)
+ if (!init) {
+ if (!suppress) {
return true;
+ }
origOut = dup(STDOUT_FILENO);
origErr = dup(STDERR_FILENO);
@@ -245,8 +239,9 @@ bool ffSuppressIO(bool suppress)
init = true;
}
- if(nullFile == -1)
+ if (nullFile == -1) {
return false;
+ }
fflush(stdout);
fflush(stderr);
@@ -256,47 +251,48 @@ bool ffSuppressIO(bool suppress)
return true;
}
-void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indentation, const char* folderName, bool pretty)
-{
+void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indentation, const char* folderName, bool pretty) {
FF_AUTO_CLOSE_FD int dfd = open(folder->chars, O_RDONLY | O_CLOEXEC);
- if (dfd < 0)
+ if (dfd < 0) {
return;
+ }
DIR* dir = fdopendir(dfd);
- if(dir == NULL)
+ if (dir == NULL) {
return;
+ }
uint32_t folderLength = folder->length;
- if(pretty && folderName != NULL)
- {
- for(uint8_t i = 0; i < indentation - 1; i++)
+ if (pretty && folderName != NULL) {
+ for (uint8_t i = 0; i < indentation - 1; i++) {
fputs(" | ", stdout);
+ }
printf("%s/\n", folderName);
}
struct dirent* entry;
- while((entry = readdir(dir)) != NULL)
- {
- if(entry->d_name[0] == '.') // skip hidden files
+ while ((entry = readdir(dir)) != NULL) {
+ if (entry->d_name[0] == '.') { // skip hidden files
continue;
+ }
bool isDir = false;
#if !defined(__sun) && !defined(__HAIKU__)
- if(entry->d_type != DT_UNKNOWN && entry->d_type != DT_LNK)
+ if (entry->d_type != DT_UNKNOWN && entry->d_type != DT_LNK) {
isDir = entry->d_type == DT_DIR;
- else
+ } else
#endif
{
struct stat stbuf;
- if (fstatat(dfd, entry->d_name, &stbuf, 0) < 0)
+ if (fstatat(dfd, entry->d_name, &stbuf, 0) < 0) {
isDir = false;
- else
+ } else {
isDir = S_ISDIR(stbuf.st_mode);
+ }
}
- if (isDir)
- {
+ if (isDir) {
ffStrbufAppendS(folder, entry->d_name);
ffStrbufAppendC(folder, '/');
listFilesRecursively(baseLength, folder, (uint8_t) (indentation + 1), entry->d_name, pretty);
@@ -304,13 +300,11 @@ void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indenta
continue;
}
- if (pretty)
- {
- for(uint8_t i = 0; i < indentation; i++)
+ if (pretty) {
+ for (uint8_t i = 0; i < indentation; i++) {
fputs(" | ", stdout);
- }
- else
- {
+ }
+ } else {
fputs(folder->chars + baseLength, stdout);
}
@@ -320,23 +314,21 @@ void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indenta
closedir(dir);
}
-void ffListFilesRecursively(const char* path, bool pretty)
-{
+void ffListFilesRecursively(const char* path, bool pretty) {
FF_STRBUF_AUTO_DESTROY folder = ffStrbufCreateS(path);
ffStrbufEnsureEndsWithC(&folder, '/');
listFilesRecursively(folder.length, &folder, 0, NULL, pretty);
}
-FFNativeFD ffGetNullFD(void)
-{
+FFNativeFD ffGetNullFD(void) {
static FFNativeFD hNullFile = -1;
- if (hNullFile != -1)
+ if (hNullFile != -1) {
return hNullFile;
+ }
hNullFile = open("/dev/null", O_WRONLY | O_CLOEXEC);
return hNullFile;
}
-bool ffRemoveFile(const char* fileName)
-{
+bool ffRemoveFile(const char* fileName) {
return unlink(fileName) == 0;
}
diff --git a/src/common/impl/io_windows.c b/src/common/impl/io_windows.c
index 3ca229c90f..49b49df094 100644
--- a/src/common/impl/io_windows.c
+++ b/src/common/impl/io_windows.c
@@ -6,15 +6,13 @@
#include
-static bool createSubfolders(wchar_t* fileName)
-{
+static bool createSubfolders(wchar_t* fileName) {
HANDLE hRoot = ffGetPeb()->ProcessParameters->CurrentDirectory.Handle;
bool closeRoot = false;
wchar_t* ptr = fileName;
// Absolute drive path: C:\...
- if (ffCharIsEnglishAlphabet((char)ptr[0]) && ptr[1] == L':' && ptr[2] == L'\\')
- {
+ if (ffCharIsEnglishAlphabet((char) ptr[0]) && ptr[1] == L':' && ptr[2] == L'\\') {
wchar_t saved = ptr[3];
ptr[3] = L'\0';
@@ -25,26 +23,27 @@ static bool createSubfolders(wchar_t* fileName)
NULL,
OPEN_EXISTING,
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_FLAG_BACKUP_SEMANTICS,
- NULL
- );
+ NULL);
ptr[3] = saved;
- if (hRoot == INVALID_HANDLE_VALUE)
+ if (hRoot == INVALID_HANDLE_VALUE) {
return false;
+ }
closeRoot = true;
ptr += 3; // skip "C:\"
}
// UNC path: \\server\share\...
- else if (ptr[0] == L'\\' && ptr[1] == L'\\')
- {
+ else if (ptr[0] == L'\\' && ptr[1] == L'\\') {
wchar_t* serverEnd = wcschr(ptr + 2, L'\\');
- if (serverEnd == NULL)
+ if (serverEnd == NULL) {
return false;
+ }
wchar_t* shareEnd = wcschr(serverEnd + 1, L'\\');
- if (shareEnd == NULL)
+ if (shareEnd == NULL) {
return true; // no parent subfolder exists before file name
+ }
wchar_t saved = *shareEnd;
*shareEnd = L'\0';
@@ -56,19 +55,18 @@ static bool createSubfolders(wchar_t* fileName)
NULL,
OPEN_EXISTING,
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_FLAG_BACKUP_SEMANTICS,
- NULL
- );
+ NULL);
*shareEnd = saved;
- if (hRoot == INVALID_HANDLE_VALUE)
+ if (hRoot == INVALID_HANDLE_VALUE) {
return false;
+ }
closeRoot = true;
ptr = shareEnd + 1; // first component under share
}
// Rooted path on current drive: \foo\bar
- else if (ptr[0] == L'\\')
- {
+ else if (ptr[0] == L'\\') {
UNICODE_STRING* dosPath = &ffGetPeb()->ProcessParameters->CurrentDirectory.DosPath;
wchar_t driveRoot[] = { dosPath->Buffer[0], L':', L'\\', L'\0' };
hRoot = CreateFileW(
@@ -78,23 +76,22 @@ static bool createSubfolders(wchar_t* fileName)
NULL,
OPEN_EXISTING,
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_FLAG_BACKUP_SEMANTICS,
- NULL
- );
- if (hRoot == INVALID_HANDLE_VALUE)
+ NULL);
+ if (hRoot == INVALID_HANDLE_VALUE) {
return false;
+ }
closeRoot = true;
ptr++; // skip leading '\'
}
- while (true)
- {
+ while (true) {
wchar_t* token = wcschr(ptr, L'\\');
- if (token == NULL)
+ if (token == NULL) {
break;
+ }
// Skip empty path segments caused by duplicated '\'
- if (token == ptr)
- {
+ if (token == ptr) {
ptr = token + 1;
continue;
}
@@ -110,8 +107,8 @@ static bool createSubfolders(wchar_t* fileName)
.RootDirectory = hRoot,
.ObjectName = &(UNICODE_STRING) {
.Buffer = ptr,
- .Length = (USHORT)((USHORT)(token - ptr) * sizeof(wchar_t)),
- .MaximumLength = (USHORT)((USHORT)(token - ptr) * sizeof(wchar_t)),
+ .Length = (USHORT) ((USHORT) (token - ptr) * sizeof(wchar_t)),
+ .MaximumLength = (USHORT) ((USHORT) (token - ptr) * sizeof(wchar_t)),
},
.Attributes = OBJ_CASE_INSENSITIVE,
},
@@ -122,155 +119,153 @@ static bool createSubfolders(wchar_t* fileName)
FILE_OPEN_IF,
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
- 0
- );
+ 0);
- if (!NT_SUCCESS(status))
- {
- if (closeRoot && hRoot != INVALID_HANDLE_VALUE)
+ if (!NT_SUCCESS(status)) {
+ if (closeRoot && hRoot != INVALID_HANDLE_VALUE) {
NtClose(hRoot);
+ }
return false;
}
- if (closeRoot && hRoot != INVALID_HANDLE_VALUE)
+ if (closeRoot && hRoot != INVALID_HANDLE_VALUE) {
NtClose(hRoot);
+ }
hRoot = hNew;
closeRoot = true;
ptr = token + 1;
}
- if (closeRoot && hRoot != INVALID_HANDLE_VALUE)
+ if (closeRoot && hRoot != INVALID_HANDLE_VALUE) {
NtClose(hRoot);
+ }
return true;
}
-bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data)
-{
+bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data) {
wchar_t fileNameW[MAX_PATH];
ULONG len = 0;
- if (!NT_SUCCESS(RtlUTF8ToUnicodeN(fileNameW, (ULONG) sizeof(fileNameW), &len, fileName, (ULONG)strlen(fileName) + 1)))
+ if (!NT_SUCCESS(RtlUTF8ToUnicodeN(fileNameW, (ULONG) sizeof(fileNameW), &len, fileName, (ULONG) strlen(fileName) + 1))) {
return false;
+ }
- for (ULONG i = 0; i < len / sizeof(wchar_t); ++i)
- {
- if (fileNameW[i] == L'/')
+ for (ULONG i = 0; i < len / sizeof(wchar_t); ++i) {
+ if (fileNameW[i] == L'/') {
fileNameW[i] = L'\\';
+ }
}
HANDLE FF_AUTO_CLOSE_FD handle = CreateFileW(fileNameW, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (handle == INVALID_HANDLE_VALUE)
- {
- if (GetLastError() == ERROR_PATH_NOT_FOUND)
- {
- if (!createSubfolders(fileNameW))
+ if (handle == INVALID_HANDLE_VALUE) {
+ if (GetLastError() == ERROR_PATH_NOT_FOUND) {
+ if (!createSubfolders(fileNameW)) {
return false;
+ }
handle = CreateFileW(fileNameW, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (handle == INVALID_HANDLE_VALUE)
+ if (handle == INVALID_HANDLE_VALUE) {
return false;
- }
- else
+ }
+ } else {
return false;
+ }
}
DWORD written;
- return !!WriteFile(handle, data, (DWORD)dataSize, &written, NULL);
+ return !!WriteFile(handle, data, (DWORD) dataSize, &written, NULL);
}
-static inline void readWithLength(HANDLE handle, FFstrbuf* buffer, uint32_t length)
-{
+static inline void readWithLength(HANDLE handle, FFstrbuf* buffer, uint32_t length) {
ffStrbufEnsureFree(buffer, length);
DWORD bytesRead = 0;
- while(
+ while (
length > 0 &&
ReadFile(handle, buffer->chars + buffer->length, length, &bytesRead, NULL) != FALSE &&
- bytesRead > 0
- ) {
+ bytesRead > 0) {
buffer->length += (uint32_t) bytesRead;
length -= (uint32_t) bytesRead;
}
}
-static inline void readUntilEOF(HANDLE handle, FFstrbuf* buffer)
-{
+static inline void readUntilEOF(HANDLE handle, FFstrbuf* buffer) {
ffStrbufEnsureFree(buffer, 31);
uint32_t available = ffStrbufGetFree(buffer);
DWORD bytesRead = 0;
- while(
+ while (
ReadFile(handle, buffer->chars + buffer->length, available, &bytesRead, NULL) != FALSE &&
- bytesRead > 0
- ) {
+ bytesRead > 0) {
buffer->length += (uint32_t) bytesRead;
- if((uint32_t) bytesRead == available)
+ if ((uint32_t) bytesRead == available) {
ffStrbufEnsureFree(buffer, buffer->allocated - 1); // Doubles capacity every round. -1 for the null byte.
+ }
available = ffStrbufGetFree(buffer);
}
}
-bool ffAppendFDBuffer(HANDLE handle, FFstrbuf* buffer)
-{
+bool ffAppendFDBuffer(HANDLE handle, FFstrbuf* buffer) {
FILE_STANDARD_INFORMATION fileInfo;
IO_STATUS_BLOCK iosb;
- if(!NT_SUCCESS(NtQueryInformationFile(handle, &iosb, &fileInfo, sizeof(fileInfo), FileStandardInformation)))
+ if (!NT_SUCCESS(NtQueryInformationFile(handle, &iosb, &fileInfo, sizeof(fileInfo), FileStandardInformation))) {
fileInfo.EndOfFile.QuadPart = 0;
+ }
- if (fileInfo.EndOfFile.QuadPart > 0)
- readWithLength(handle, buffer, (uint32_t)fileInfo.EndOfFile.QuadPart);
- else
+ if (fileInfo.EndOfFile.QuadPart > 0) {
+ readWithLength(handle, buffer, (uint32_t) fileInfo.EndOfFile.QuadPart);
+ } else {
readUntilEOF(handle, buffer);
+ }
buffer->chars[buffer->length] = '\0';
return buffer->length > 0;
}
-HANDLE openatW(HANDLE dfd, const wchar_t* fileName, uint16_t fileNameLen, bool directory)
-{
+HANDLE openatW(HANDLE dfd, const wchar_t* fileName, uint16_t fileNameLen, bool directory) {
assert(fileNameLen <= 0x7FFF);
HANDLE hFile;
IO_STATUS_BLOCK iosb = {};
- if(!NT_SUCCESS(NtOpenFile(&hFile,
- (directory ? FILE_LIST_DIRECTORY | FILE_TRAVERSE : FILE_READ_DATA | FILE_READ_EA) | FILE_READ_ATTRIBUTES | SYNCHRONIZE, &(OBJECT_ATTRIBUTES) {
- .Length = sizeof(OBJECT_ATTRIBUTES),
- .RootDirectory = dfd,
- .ObjectName = &(UNICODE_STRING) {
- .Buffer = (PWSTR) fileName,
- .Length = fileNameLen * (USHORT) sizeof(wchar_t),
- .MaximumLength = (fileNameLen + 1) * (USHORT) sizeof(wchar_t),
+ if (!NT_SUCCESS(NtOpenFile(&hFile,
+ (directory ? FILE_LIST_DIRECTORY | FILE_TRAVERSE : FILE_READ_DATA | FILE_READ_EA) | FILE_READ_ATTRIBUTES | SYNCHRONIZE,
+ &(OBJECT_ATTRIBUTES) {
+ .Length = sizeof(OBJECT_ATTRIBUTES),
+ .RootDirectory = dfd,
+ .ObjectName = &(UNICODE_STRING) {
+ .Buffer = (PWSTR) fileName,
+ .Length = fileNameLen * (USHORT) sizeof(wchar_t),
+ .MaximumLength = (fileNameLen + 1) * (USHORT) sizeof(wchar_t),
+ },
+ .Attributes = OBJ_CASE_INSENSITIVE,
},
- .Attributes = OBJ_CASE_INSENSITIVE,
- },
- &iosb,
- FILE_SHARE_READ | (directory ? FILE_SHARE_WRITE | FILE_SHARE_DELETE : 0),
- FILE_SYNCHRONOUS_IO_NONALERT | (directory ? FILE_DIRECTORY_FILE : FILE_NON_DIRECTORY_FILE)
- )))
+ &iosb,
+ FILE_SHARE_READ | (directory ? FILE_SHARE_WRITE | FILE_SHARE_DELETE : 0),
+ FILE_SYNCHRONOUS_IO_NONALERT | (directory ? FILE_DIRECTORY_FILE : FILE_NON_DIRECTORY_FILE)))) {
return INVALID_HANDLE_VALUE;
+ }
return hFile;
}
-HANDLE openat(HANDLE dfd, const char* fileName, int oflag)
-{
+HANDLE openat(HANDLE dfd, const char* fileName, int oflag) {
wchar_t fileNameW[MAX_PATH];
ULONG len;
- if (!NT_SUCCESS(RtlUTF8ToUnicodeN(fileNameW, (ULONG) sizeof(fileNameW), &len, fileName, (ULONG)strlen(fileName) + 1)))
+ if (!NT_SUCCESS(RtlUTF8ToUnicodeN(fileNameW, (ULONG) sizeof(fileNameW), &len, fileName, (ULONG) strlen(fileName) + 1))) {
return INVALID_HANDLE_VALUE;
+ }
// Implies `fileNameW[len] = L'\0';` and `len` includes the null terminator
len /= sizeof(wchar_t); // convert from bytes to characters
- for (uint32_t i = 0; i < len - 1; ++i)
- {
- if (fileNameW[i] == L'/')
+ for (uint32_t i = 0; i < len - 1; ++i) {
+ if (fileNameW[i] == L'/') {
fileNameW[i] = L'\\';
+ }
}
- return openatW(dfd, fileNameW, (uint16_t)(len - 1), !!(oflag & O_DIRECTORY));
+ return openatW(dfd, fileNameW, (uint16_t) (len - 1), !!(oflag & O_DIRECTORY));
}
-bool ffPathExpandEnv(const char* in, FFstrbuf* out)
-{
+bool ffPathExpandEnv(const char* in, FFstrbuf* out) {
if (in[0] == '~') {
if ((in[1] == '/' || in[1] == '\\' || in[1] == '\0') && !ffStrContainsC(in, '%')) {
ffStrbufSet(out, &instance.state.platform.homeDir);
@@ -281,24 +276,26 @@ bool ffPathExpandEnv(const char* in, FFstrbuf* out)
wchar_t pathInW[MAX_PATH], pathOutW[MAX_PATH];
ULONG len = (ULONG) strlen(in);
- if (!NT_SUCCESS(RtlUTF8ToUnicodeN(pathInW, (ULONG) sizeof(pathInW), &len, in, len)))
+ if (!NT_SUCCESS(RtlUTF8ToUnicodeN(pathInW, (ULONG) sizeof(pathInW), &len, in, len))) {
return false;
+ }
len /= sizeof(wchar_t); // convert from bytes to characters
- size_t outLen; // in characters, including null terminator
- if (!NT_SUCCESS(RtlExpandEnvironmentStrings(NULL, pathInW, len, pathOutW, ARRAY_SIZE(pathOutW), &outLen)))
+ SIZE_T outLen; // in characters, including null terminator
+ if (!NT_SUCCESS(RtlExpandEnvironmentStrings(NULL, pathInW, len, pathOutW, ARRAY_SIZE(pathOutW), &outLen))) {
return false;
+ }
ffStrbufSetNWS(out, (uint32_t) outLen - 1, pathOutW);
return true;
}
-bool ffSuppressIO(bool suppress)
-{
- #ifndef NDEBUG
- if (instance.config.display.debugMode)
+bool ffSuppressIO(bool suppress) {
+#ifndef NDEBUG
+ if (instance.config.display.debugMode) {
return false;
- #endif
+ }
+#endif
static bool init = false;
static HANDLE hOrigOut = INVALID_HANDLE_VALUE;
@@ -308,10 +305,10 @@ bool ffSuppressIO(bool suppress)
static int fOrigErr = -1;
static int fNullFile = -1;
- if (!init)
- {
- if(!suppress)
+ if (!init) {
+ if (!suppress) {
return true;
+ }
hOrigOut = GetStdHandle(STD_OUTPUT_HANDLE);
hOrigErr = GetStdHandle(STD_ERROR_HANDLE);
@@ -321,8 +318,9 @@ bool ffSuppressIO(bool suppress)
init = true;
}
- if (hNullFile == INVALID_HANDLE_VALUE || fNullFile == -1)
+ if (hNullFile == INVALID_HANDLE_VALUE || fNullFile == -1) {
return false;
+ }
fflush(stdout);
fflush(stderr);
@@ -335,14 +333,13 @@ bool ffSuppressIO(bool suppress)
return true;
}
-void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indentation, const char* folderName, bool pretty)
-{
+void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indentation, const char* folderName, bool pretty) {
uint32_t folderLength = folder->length;
- if(pretty && folderName != NULL)
- {
- for(uint8_t i = 0; i < indentation - 1; i++)
+ if (pretty && folderName != NULL) {
+ for (uint8_t i = 0; i < indentation - 1; i++) {
fputs(" | ", stdout);
+ }
printf("%s/\n", folderName);
}
@@ -350,15 +347,15 @@ void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indenta
WIN32_FIND_DATAA entry;
HANDLE hFind = FindFirstFileA(folder->chars, &entry);
ffStrbufTrimRight(folder, '*');
- if(hFind == INVALID_HANDLE_VALUE)
+ if (hFind == INVALID_HANDLE_VALUE) {
return;
+ }
- do
- {
- if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- {
- if(ffStrEquals(entry.cFileName, ".") || ffStrEquals(entry.cFileName, ".."))
+ do {
+ if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ if (ffStrEquals(entry.cFileName, ".") || ffStrEquals(entry.cFileName, "..")) {
continue;
+ }
ffStrbufSubstrBefore(folder, folderLength);
ffStrbufAppendS(folder, entry.cFileName);
@@ -368,13 +365,11 @@ void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indenta
continue;
}
- if (pretty)
- {
- for(uint8_t i = 0; i < indentation; i++)
+ if (pretty) {
+ for (uint8_t i = 0; i < indentation; i++) {
fputs(" | ", stdout);
- }
- else
- {
+ }
+ } else {
fputs(folder->chars + baseLength, stdout);
}
@@ -383,20 +378,17 @@ void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indenta
FindClose(hFind);
}
-void ffListFilesRecursively(const char* path, bool pretty)
-{
+void ffListFilesRecursively(const char* path, bool pretty) {
FF_STRBUF_AUTO_DESTROY folder = ffStrbufCreateS(path);
ffStrbufEnsureEndsWithC(&folder, '/');
listFilesRecursively(folder.length, &folder, 0, NULL, pretty);
}
-const char* ffGetTerminalResponse(const char* request, int nParams, const char* format, ...)
-{
+const char* ffGetTerminalResponse(const char* request, int nParams, const char* format, ...) {
HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
FF_AUTO_CLOSE_FD HANDLE hConin = INVALID_HANDLE_VALUE;
DWORD inputMode;
- if (!GetConsoleMode(hInput, &inputMode))
- {
+ if (!GetConsoleMode(hInput, &inputMode)) {
hConin = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, NULL);
hInput = hConin;
}
@@ -409,18 +401,15 @@ const char* ffGetTerminalResponse(const char* request, int nParams, const char*
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
FF_AUTO_CLOSE_FD HANDLE hConout = INVALID_HANDLE_VALUE;
DWORD outputMode;
- if (!GetConsoleMode(hOutput, &outputMode))
- {
+ if (!GetConsoleMode(hOutput, &outputMode)) {
hConout = CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, NULL);
hOutput = hConout;
}
WriteFile(hOutput, request, (DWORD) strlen(request), &bytes, NULL);
}
- while (true)
- {
- if (NtWaitForSingleObject(hInput, FALSE, &(LARGE_INTEGER) { .QuadPart = (int64_t) FF_IO_TERM_RESP_WAIT_MS * -10000 }) != STATUS_WAIT_0)
- {
+ while (true) {
+ if (NtWaitForSingleObject(hInput, FALSE, &(LARGE_INTEGER) { .QuadPart = (int64_t) FF_IO_TERM_RESP_WAIT_MS * -10000 }) != STATUS_WAIT_0) {
SetConsoleMode(hInput, inputMode);
return "NtWaitForSingleObject() failed or timeout";
}
@@ -428,17 +417,18 @@ const char* ffGetTerminalResponse(const char* request, int nParams, const char*
// Ignore all unexpected input events
INPUT_RECORD record;
DWORD len = 0;
- if (!PeekConsoleInputW(hInput, &record, 1, &len))
+ if (!PeekConsoleInputW(hInput, &record, 1, &len)) {
break;
+ }
if (
record.EventType == KEY_EVENT &&
record.Event.KeyEvent.uChar.UnicodeChar != L'\r' &&
- record.Event.KeyEvent.uChar.UnicodeChar != L'\n'
- )
+ record.Event.KeyEvent.uChar.UnicodeChar != L'\n') {
break;
- else
+ } else {
ReadConsoleInputW(hInput, &record, 1, &len);
+ }
}
va_list args;
@@ -447,11 +437,9 @@ const char* ffGetTerminalResponse(const char* request, int nParams, const char*
char buffer[1024];
uint32_t bytesRead = 0;
- while (true)
- {
+ while (true) {
DWORD bytes = 0;
- if (!ReadFile(hInput, buffer, sizeof(buffer) - 1, &bytes, NULL) || bytes == 0)
- {
+ if (!ReadFile(hInput, buffer, sizeof(buffer) - 1, &bytes, NULL) || bytes == 0) {
va_end(args);
return "ReadFile() failed";
}
@@ -464,13 +452,13 @@ const char* ffGetTerminalResponse(const char* request, int nParams, const char*
int ret = vsscanf(buffer, format, cargs);
va_end(cargs);
- if (ret <= 0)
- {
+ if (ret <= 0) {
va_end(args);
return "vsscanf(buffer, format, args) failed";
}
- if (ret >= nParams)
+ if (ret >= nParams) {
break;
+ }
}
SetConsoleMode(hInput, inputMode);
@@ -480,11 +468,11 @@ const char* ffGetTerminalResponse(const char* request, int nParams, const char*
return NULL;
}
-FFNativeFD ffGetNullFD(void)
-{
+FFNativeFD ffGetNullFD(void) {
static FFNativeFD hNullFile = INVALID_HANDLE_VALUE;
- if (hNullFile != INVALID_HANDLE_VALUE)
+ if (hNullFile != INVALID_HANDLE_VALUE) {
return hNullFile;
+ }
hNullFile = CreateFileW(
L"NUL",
GENERIC_READ | GENERIC_WRITE,
@@ -492,7 +480,7 @@ FFNativeFD ffGetNullFD(void)
0,
OPEN_EXISTING,
0,
- &(SECURITY_ATTRIBUTES){
+ &(SECURITY_ATTRIBUTES) {
.nLength = sizeof(SECURITY_ATTRIBUTES),
.lpSecurityDescriptor = NULL,
.bInheritHandle = TRUE,
@@ -500,7 +488,6 @@ FFNativeFD ffGetNullFD(void)
return hNullFile;
}
-bool ffRemoveFile(const char* fileName)
-{
+bool ffRemoveFile(const char* fileName) {
return DeleteFileA(fileName) != FALSE;
}
diff --git a/src/common/impl/jsonconfig.c b/src/common/impl/jsonconfig.c
index 5e5effb08e..0e71cde513 100644
--- a/src/common/impl/jsonconfig.c
+++ b/src/common/impl/jsonconfig.c
@@ -12,135 +12,117 @@
#include
#include
-bool ffJsonConfigParseModuleArgs(yyjson_val* key, yyjson_val* val, FFModuleArgs* moduleArgs)
-{
- if (unsafe_yyjson_equals_str(key, "type") || unsafe_yyjson_equals_str(key, "condition"))
+bool ffJsonConfigParseModuleArgs(yyjson_val* key, yyjson_val* val, FFModuleArgs* moduleArgs) {
+ if (unsafe_yyjson_equals_str(key, "type") || unsafe_yyjson_equals_str(key, "condition")) {
return true;
+ }
- if (unsafe_yyjson_equals_str(key, "key"))
- {
+ if (unsafe_yyjson_equals_str(key, "key")) {
ffStrbufSetJsonVal(&moduleArgs->key, val);
return true;
- }
- else if (unsafe_yyjson_equals_str(key, "format"))
- {
+ } else if (unsafe_yyjson_equals_str(key, "format")) {
ffStrbufSetJsonVal(&moduleArgs->outputFormat, val);
return true;
- }
- else if (unsafe_yyjson_equals_str(key, "outputColor"))
- {
+ } else if (unsafe_yyjson_equals_str(key, "outputColor")) {
ffOptionParseColor(yyjson_get_str(val), &moduleArgs->outputColor);
return true;
- }
- else if (unsafe_yyjson_equals_str(key, "keyColor"))
- {
+ } else if (unsafe_yyjson_equals_str(key, "keyColor")) {
ffOptionParseColor(yyjson_get_str(val), &moduleArgs->keyColor);
return true;
- }
- else if (unsafe_yyjson_equals_str(key, "keyWidth"))
- {
+ } else if (unsafe_yyjson_equals_str(key, "keyWidth")) {
moduleArgs->keyWidth = (uint32_t) yyjson_get_uint(val);
return true;
- }
- else if (unsafe_yyjson_equals_str(key, "keyIcon"))
- {
+ } else if (unsafe_yyjson_equals_str(key, "keyIcon")) {
ffStrbufSetJsonVal(&moduleArgs->keyIcon, val);
return true;
}
return false;
}
-void ffJsonConfigGenerateModuleArgsConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFModuleArgs* moduleArgs)
-{
- if (moduleArgs->key.length > 0)
+void ffJsonConfigGenerateModuleArgsConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFModuleArgs* moduleArgs) {
+ if (moduleArgs->key.length > 0) {
yyjson_mut_obj_add_strbuf(doc, module, "key", &moduleArgs->key);
- if (moduleArgs->outputFormat.length > 0)
+ }
+ if (moduleArgs->outputFormat.length > 0) {
yyjson_mut_obj_add_strbuf(doc, module, "format", &moduleArgs->outputFormat);
- if (moduleArgs->outputColor.length > 0)
+ }
+ if (moduleArgs->outputColor.length > 0) {
yyjson_mut_obj_add_strbuf(doc, module, "outputColor", &moduleArgs->outputColor);
- if (moduleArgs->keyColor.length > 0)
+ }
+ if (moduleArgs->keyColor.length > 0) {
yyjson_mut_obj_add_strbuf(doc, module, "keyColor", &moduleArgs->keyColor);
- if (moduleArgs->keyWidth > 0)
+ }
+ if (moduleArgs->keyWidth > 0) {
yyjson_mut_obj_add_uint(doc, module, "keyWidth", moduleArgs->keyWidth);
- if (moduleArgs->keyIcon.length > 0)
+ }
+ if (moduleArgs->keyIcon.length > 0) {
yyjson_mut_obj_add_strbuf(doc, module, "keyIcon", &moduleArgs->keyIcon);
+ }
}
-const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair pairs[])
-{
- if (yyjson_is_int(val))
- {
+const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair pairs[]) {
+ if (yyjson_is_int(val)) {
int intVal = yyjson_get_int(val);
- for (const FFKeyValuePair* pPair = pairs; pPair->key; ++pPair)
- {
- if (intVal == pPair->value)
- {
+ for (const FFKeyValuePair* pPair = pairs; pPair->key; ++pPair) {
+ if (intVal == pPair->value) {
*result = pPair->value;
return NULL;
}
}
return "Invalid enum integer";
- }
- else if (yyjson_is_str(val))
- {
+ } else if (yyjson_is_str(val)) {
const char* strVal = yyjson_get_str(val);
- for (const FFKeyValuePair* pPair = pairs; pPair->key; ++pPair)
- {
- if (ffStrEqualsIgnCase(strVal, pPair->key))
- {
+ for (const FFKeyValuePair* pPair = pairs; pPair->key; ++pPair) {
+ if (ffStrEqualsIgnCase(strVal, pPair->key)) {
*result = pPair->value;
return NULL;
}
}
return "Invalid enum string";
- }
- else
+ } else {
return "Invalid enum value type; must be a string or integer";
+ }
}
-static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal, yyjson_mut_doc* jsonDoc)
-{
- if(!ffCharIsEnglishAlphabet(type[0])) return false;
+static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal, yyjson_mut_doc* jsonDoc) {
+ if (!ffCharIsEnglishAlphabet(type[0])) {
+ return false;
+ }
- for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(type[0]) - 'A']; *modules; ++modules)
- {
+ for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(type[0]) - 'A']; *modules; ++modules) {
FFModuleBaseInfo* baseInfo = *modules;
- if (ffStrEqualsIgnCase(type, baseInfo->name))
- {
+ if (ffStrEqualsIgnCase(type, baseInfo->name)) {
uint8_t optionBuf[FF_OPTION_MAX_SIZE];
baseInfo->initOptions(optionBuf);
- if (jsonVal) baseInfo->parseJsonObject(optionBuf, jsonVal);
+ if (jsonVal) {
+ baseInfo->parseJsonObject(optionBuf, jsonVal);
+ }
bool succeeded;
- if (jsonDoc)
- {
+ if (jsonDoc) {
yyjson_mut_val* module = yyjson_mut_arr_add_obj(jsonDoc, jsonDoc->root);
yyjson_mut_obj_add_str(jsonDoc, module, "type", baseInfo->name);
- if (baseInfo->generateJsonResult)
+ if (baseInfo->generateJsonResult) {
succeeded = baseInfo->generateJsonResult(optionBuf, jsonDoc, module);
- else
- {
+ } else {
yyjson_mut_obj_add_str(jsonDoc, module, "error", "Unsupported for JSON format");
succeeded = false;
}
- }
- else
+ } else {
succeeded = baseInfo->printModule(optionBuf);
+ }
baseInfo->destroyOptions(optionBuf);
return succeeded;
}
}
- if (jsonDoc)
- {
+ if (jsonDoc) {
yyjson_mut_val* module = yyjson_mut_arr_add_obj(jsonDoc, jsonDoc->root);
yyjson_mut_obj_add_strcpy(jsonDoc, module, "type", type);
yyjson_mut_obj_add_str(jsonDoc, module, "error", "Unknown module type");
- }
- else
- {
+ } else {
FFModuleArgs moduleArgs;
ffOptionInitModuleArg(&moduleArgs, "");
ffPrintError(type, 0, &moduleArgs, FF_PRINT_TYPE_DEFAULT, "Unknown module type");
@@ -149,61 +131,71 @@ static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal, yyjson_
return false;
}
-static void prepareModuleJsonObject(const char* type, yyjson_val* module)
-{
- switch (type[0])
- {
- case 'b': case 'B': {
- if (ffStrEqualsIgnCase(type, FF_CPUUSAGE_MODULE_NAME))
+static void prepareModuleJsonObject(const char* type, yyjson_val* module) {
+ switch (type[0]) {
+ case 'b':
+ case 'B': {
+ if (ffStrEqualsIgnCase(type, FF_CPUUSAGE_MODULE_NAME)) {
ffPrepareCPUUsage();
+ }
break;
}
- case 'c': case 'C': {
- if (ffStrEqualsIgnCase(type, FF_COMMAND_MODULE_NAME))
- {
- __attribute__((__cleanup__(ffDestroyCommandOptions))) FFCommandOptions options;
+ case 'c':
+ case 'C': {
+ if (ffStrEqualsIgnCase(type, FF_COMMAND_MODULE_NAME)) {
+ FF_A_CLEANUP(ffDestroyCommandOptions) FFCommandOptions options;
ffInitCommandOptions(&options);
- if (module) ffCommandModuleInfo.parseJsonObject(&options, module);
+ if (module) {
+ ffCommandModuleInfo.parseJsonObject(&options, module);
+ }
ffPrepareCommand(&options);
}
break;
}
- case 'd': case 'D': {
- if (ffStrEqualsIgnCase(type, FF_DISKIO_MODULE_NAME))
- {
- __attribute__((__cleanup__(ffDestroyDiskIOOptions))) FFDiskIOOptions options;
+ case 'd':
+ case 'D': {
+ if (ffStrEqualsIgnCase(type, FF_DISKIO_MODULE_NAME)) {
+ FF_A_CLEANUP(ffDestroyDiskIOOptions) FFDiskIOOptions options;
ffInitDiskIOOptions(&options);
- if (module) ffDiskIOModuleInfo.parseJsonObject(&options, module);
+ if (module) {
+ ffDiskIOModuleInfo.parseJsonObject(&options, module);
+ }
ffPrepareDiskIO(&options);
}
break;
}
- case 'n': case 'N': {
- if (ffStrEqualsIgnCase(type, FF_NETIO_MODULE_NAME))
- {
- __attribute__((__cleanup__(ffDestroyNetIOOptions))) FFNetIOOptions options;
+ case 'n':
+ case 'N': {
+ if (ffStrEqualsIgnCase(type, FF_NETIO_MODULE_NAME)) {
+ FF_A_CLEANUP(ffDestroyNetIOOptions) FFNetIOOptions options;
ffInitNetIOOptions(&options);
- if (module) ffNetIOModuleInfo.parseJsonObject(&options, module);
+ if (module) {
+ ffNetIOModuleInfo.parseJsonObject(&options, module);
+ }
ffPrepareNetIO(&options);
}
break;
}
- case 'p': case 'P': {
- if (ffStrEqualsIgnCase(type, FF_PUBLICIP_MODULE_NAME))
- {
- __attribute__((__cleanup__(ffDestroyPublicIpOptions))) FFPublicIPOptions options;
+ case 'p':
+ case 'P': {
+ if (ffStrEqualsIgnCase(type, FF_PUBLICIP_MODULE_NAME)) {
+ FF_A_CLEANUP(ffDestroyPublicIpOptions) FFPublicIPOptions options;
ffInitPublicIpOptions(&options);
- if (module) ffPublicIPModuleInfo.parseJsonObject(&options, module);
+ if (module) {
+ ffPublicIPModuleInfo.parseJsonObject(&options, module);
+ }
ffPreparePublicIp(&options);
}
break;
}
- case 'w': case 'W': {
- if (ffStrEqualsIgnCase(type, FF_WEATHER_MODULE_NAME))
- {
- __attribute__((__cleanup__(ffDestroyWeatherOptions))) FFWeatherOptions options;
+ case 'w':
+ case 'W': {
+ if (ffStrEqualsIgnCase(type, FF_WEATHER_MODULE_NAME)) {
+ FF_A_CLEANUP(ffDestroyWeatherOptions) FFWeatherOptions options;
ffInitWeatherOptions(&options);
- if (module) ffWeatherModuleInfo.parseJsonObject(&options, module);
+ if (module) {
+ ffWeatherModuleInfo.parseJsonObject(&options, module);
+ }
ffPrepareWeather(&options);
}
break;
@@ -211,141 +203,154 @@ static void prepareModuleJsonObject(const char* type, yyjson_val* module)
}
}
-static bool matchesJsonArray(const char* str, yyjson_val* val)
-{
+static bool matchesJsonArray(const char* str, yyjson_val* val) {
assert(val);
- if (unsafe_yyjson_is_str(val))
+ if (unsafe_yyjson_is_str(val)) {
return ffStrEqualsIgnCase(str, unsafe_yyjson_get_str(val));
+ }
- if (!unsafe_yyjson_is_arr(val)) return false;
+ if (!unsafe_yyjson_is_arr(val)) {
+ return false;
+ }
size_t idx, max;
yyjson_val* item;
- yyjson_arr_foreach(val, idx, max, item)
- {
- if (yyjson_is_str(item) && ffStrEqualsIgnCase(str, unsafe_yyjson_get_str(item)))
+ yyjson_arr_foreach (val, idx, max, item) {
+ if (yyjson_is_str(item) && ffStrEqualsIgnCase(str, unsafe_yyjson_get_str(item))) {
return true;
+ }
}
return false;
}
-static const char* printJsonConfig(FFdata* data, bool prepare)
-{
+static const char* printJsonConfig(FFdata* data, bool prepare) {
yyjson_mut_doc* jsonDoc = data->resultDoc;
yyjson_val* const root = yyjson_doc_get_root(data->configDoc);
assert(root);
- if (!yyjson_is_obj(root))
+ if (!yyjson_is_obj(root)) {
return "Invalid JSON config format. Root value must be an object";
+ }
yyjson_val* modules = yyjson_obj_get(root, "modules");
- if (!modules) return NULL;
- if (!yyjson_is_arr(modules)) return "Property 'modules' must be an array of strings or objects";
+ if (!modules) {
+ return NULL;
+ }
+ if (!yyjson_is_arr(modules)) {
+ return "Property 'modules' must be an array of strings or objects";
+ }
bool succeeded = true;
int32_t thres = instance.config.display.stat;
yyjson_val* item;
size_t idx, max;
- yyjson_arr_foreach(modules, idx, max, item)
- {
+ yyjson_arr_foreach (modules, idx, max, item) {
double ms = 0;
- if(!prepare && thres >= 0)
+ if (!prepare && thres >= 0) {
ms = ffTimeGetTick();
+ }
yyjson_val* module = item;
const char* type = yyjson_get_str(module);
- if (type)
+ if (type) {
module = NULL;
- else if (yyjson_is_obj(module))
- {
+ } else if (yyjson_is_obj(module)) {
yyjson_val* conditions = yyjson_obj_get(module, "condition");
- if (conditions)
- {
- if (!yyjson_is_obj(conditions))
+ if (conditions) {
+ if (!yyjson_is_obj(conditions)) {
return "Property 'conditions' must be an object";
+ }
yyjson_val* system = yyjson_obj_get(conditions, "system");
- if (system && !matchesJsonArray(ffVersionResult.sysName, system))
+ if (system && !matchesJsonArray(ffVersionResult.sysName, system)) {
continue;
+ }
system = yyjson_obj_get(conditions, "!system");
- if (system && matchesJsonArray(ffVersionResult.sysName, system))
+ if (system && matchesJsonArray(ffVersionResult.sysName, system)) {
continue;
+ }
yyjson_val* arch = yyjson_obj_get(conditions, "arch");
- if (arch && !matchesJsonArray(ffVersionResult.architecture, arch))
+ if (arch && !matchesJsonArray(ffVersionResult.architecture, arch)) {
continue;
+ }
arch = yyjson_obj_get(conditions, "!arch");
- if (arch && matchesJsonArray(ffVersionResult.architecture, arch))
+ if (arch && matchesJsonArray(ffVersionResult.architecture, arch)) {
continue;
+ }
yyjson_val* previousSucceeded = yyjson_obj_get(conditions, "succeeded");
- if (previousSucceeded && !unsafe_yyjson_is_null(previousSucceeded))
- {
- if (!unsafe_yyjson_is_bool(previousSucceeded))
+ if (previousSucceeded && !unsafe_yyjson_is_null(previousSucceeded)) {
+ if (!unsafe_yyjson_is_bool(previousSucceeded)) {
return "Property 'succeeded' in 'condition' must be a boolean";
- if (succeeded != unsafe_yyjson_get_bool(previousSucceeded))
+ }
+ if (succeeded != unsafe_yyjson_get_bool(previousSucceeded)) {
continue;
+ }
}
}
type = yyjson_get_str(yyjson_obj_get(module, "type"));
- if (!type) return "module object must contain a \"type\" key ( case sensitive )";
- if (yyjson_obj_size(module) == 1) // contains only Property type
+ if (!type) {
+ return "module object must contain a \"type\" key ( case sensitive )";
+ }
+ if (yyjson_obj_size(module) == 1) { // contains only Property type
module = NULL;
- }
- else
+ }
+ } else {
return "modules must be an array of strings or objects";
+ }
- if (ffStrbufSeparatedContainIgnCaseS(&data->structureDisabled, type, ':'))
+ if (ffStrbufSeparatedContainIgnCaseS(&data->structureDisabled, type, ':')) {
continue;
+ }
- if(prepare)
+ if (prepare) {
prepareModuleJsonObject(type, module);
- else
+ } else {
succeeded = parseModuleJsonObject(type, module, jsonDoc);
+ }
- if(!prepare && thres >= 0)
- {
+ if (!prepare && thres >= 0) {
ms = ffTimeGetTick() - ms;
- if (jsonDoc)
- {
+ if (jsonDoc) {
yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(jsonDoc->root);
yyjson_mut_obj_add_real(jsonDoc, moduleJson, "stat", ms);
- }
- else
- {
+ } else {
char str[64];
int len = snprintf(str, sizeof str, "%.3fms", ms);
- if (thres > 0)
- snprintf(str, sizeof str, "\e[%sm%.3fms\e[m", (ms <= thres ? FF_COLOR_FG_GREEN : ms <= 2 * thres ? FF_COLOR_FG_YELLOW : FF_COLOR_FG_RED), ms);
+ if (thres > 0) {
+ snprintf(str, sizeof str, "\e[%sm%.3fms\e[m", (ms <= thres ? FF_COLOR_FG_GREEN : ms <= 2 * thres ? FF_COLOR_FG_YELLOW
+ : FF_COLOR_FG_RED),
+ ms);
+ }
printf("\e7\e[1A\e[9999999C\e[%dD%s\e8", len, str); // Save; Up 1; Right 9999999; Left ; Print ; Load
}
}
- #if defined(_WIN32)
- if (!instance.config.display.noBuffer && !jsonDoc) fflush(stdout);
- #endif
+#if defined(_WIN32)
+ if (!instance.config.display.noBuffer && !jsonDoc) {
+ fflush(stdout);
+ }
+#endif
}
return NULL;
}
-void ffPrintJsonConfig(FFdata* data, bool prepare)
-{
+void ffPrintJsonConfig(FFdata* data, bool prepare) {
yyjson_mut_doc* jsonDoc = data->resultDoc;
const char* error = printJsonConfig(data, prepare);
- if (error)
- {
- if (jsonDoc)
- {
+ if (error) {
+ if (jsonDoc) {
yyjson_mut_val* obj = yyjson_mut_obj(jsonDoc);
yyjson_mut_obj_add_str(jsonDoc, obj, "error", error);
yyjson_mut_doc_set_root(jsonDoc, obj);
- }
- else
+ } else {
ffPrintError("JsonConfig", 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "%s", error);
+ }
}
}
diff --git a/src/common/impl/kmod_apple.c b/src/common/impl/kmod_apple.c
index eb28faee69..82edc49463 100644
--- a/src/common/impl/kmod_apple.c
+++ b/src/common/impl/kmod_apple.c
@@ -3,8 +3,7 @@
#include
#include
-bool ffKmodLoaded(const char* modName)
-{
+bool ffKmodLoaded(const char* modName) {
FF_CFTYPE_AUTO_RELEASE CFStringRef name = CFStringCreateWithCString(kCFAllocatorDefault, modName, kCFStringEncodingUTF8);
FF_CFTYPE_AUTO_RELEASE CFArrayRef identifiers = CFArrayCreate(kCFAllocatorDefault, (const void**) &name, 1, &kCFTypeArrayCallBacks);
FF_CFTYPE_AUTO_RELEASE CFArrayRef keys = CFArrayCreate(kCFAllocatorDefault, NULL, 0, NULL);
diff --git a/src/common/impl/kmod_bsd.c b/src/common/impl/kmod_bsd.c
index 99ebafda7b..996d4abbd0 100644
--- a/src/common/impl/kmod_bsd.c
+++ b/src/common/impl/kmod_bsd.c
@@ -2,7 +2,6 @@
#include
#include
-bool ffKmodLoaded(const char* modName)
-{
+bool ffKmodLoaded(const char* modName) {
return modfind(modName) >= 0;
}
diff --git a/src/common/impl/kmod_linux.c b/src/common/impl/kmod_linux.c
index 940093b5db..204ab35857 100644
--- a/src/common/impl/kmod_linux.c
+++ b/src/common/impl/kmod_linux.c
@@ -1,19 +1,21 @@
#include "common/kmod.h"
#include "common/io.h"
-bool ffKmodLoaded(const char* modName)
-{
+bool ffKmodLoaded(const char* modName) {
static FFstrbuf modules;
- if (modules.chars == NULL)
- {
+ if (modules.chars == NULL) {
ffStrbufInitS(&modules, "\n");
ffAppendFileBuffer("/proc/modules", &modules);
}
- if (modules.length == 0) return false;
+ if (modules.length == 0) {
+ return false;
+ }
uint32_t len = (uint32_t) strlen(modName);
- if (len > 250) return false;
+ if (len > 250) {
+ return false;
+ }
char temp[256];
temp[0] = '\n';
diff --git a/src/common/impl/kmod_nbsd.c b/src/common/impl/kmod_nbsd.c
index f4e78eed8f..06149eab11 100644
--- a/src/common/impl/kmod_nbsd.c
+++ b/src/common/impl/kmod_nbsd.c
@@ -4,39 +4,36 @@
#include
#include
-typedef struct __attribute__((__packed__)) FFNbsdModList
-{
+typedef struct FF_A_PACKED FFNbsdModList {
int len;
modstat_t mods[];
} FFNbsdModList;
-bool ffKmodLoaded(const char* modName)
-{
+bool ffKmodLoaded(const char* modName) {
static FFNbsdModList* list = NULL;
- if (list == NULL)
- {
+ if (list == NULL) {
struct iovec iov = {};
- for (size_t len = 8192;; len = iov.iov_len)
- {
+ for (size_t len = 8192;; len = iov.iov_len) {
iov.iov_len = len;
iov.iov_base = realloc(iov.iov_base, len);
- if (modctl(MODCTL_STAT, &iov) < 0)
- {
+ if (modctl(MODCTL_STAT, &iov) < 0) {
free(iov.iov_base);
return true; // ignore errors
}
- if (len >= iov.iov_len) break;
+ if (len >= iov.iov_len) {
+ break;
+ }
}
list = (FFNbsdModList*) iov.iov_base;
}
- for (int i = 0; i < list->len; i++)
- {
- if (ffStrEquals(list->mods[i].ms_name, modName))
+ for (int i = 0; i < list->len; i++) {
+ if (ffStrEquals(list->mods[i].ms_name, modName)) {
return true;
+ }
}
return false;
diff --git a/src/common/impl/kmod_nosupport.c b/src/common/impl/kmod_nosupport.c
index 1ae3b0b33f..c254ba7b21 100644
--- a/src/common/impl/kmod_nosupport.c
+++ b/src/common/impl/kmod_nosupport.c
@@ -1,6 +1,5 @@
#include "common/kmod.h"
-bool ffKmodLoaded(FF_MAYBE_UNUSED const char* modName)
-{
+bool ffKmodLoaded(FF_A_UNUSED const char* modName) {
return true; // Don't generate kernel module related errors
}
diff --git a/src/common/impl/kmod_sunos.c b/src/common/impl/kmod_sunos.c
index e6c403c82f..de00206707 100644
--- a/src/common/impl/kmod_sunos.c
+++ b/src/common/impl/kmod_sunos.c
@@ -4,20 +4,19 @@
#include
#include
-bool ffKmodLoaded(const char* modName)
-{
+bool ffKmodLoaded(const char* modName) {
struct modinfo modinfo = {
.mi_id = -1,
.mi_nextid = -1,
.mi_info = MI_INFO_ALL,
};
- for (int id = -1; modctl(MODINFO, id, &modinfo) == 0; id = modinfo.mi_id)
- {
+ for (int id = -1; modctl(MODINFO, id, &modinfo) == 0; id = modinfo.mi_id) {
modinfo.mi_name[MODMAXNAMELEN - 1] = '\0';
- if (ffStrEquals(modinfo.mi_name, modName))
+ if (ffStrEquals(modinfo.mi_name, modName)) {
return true;
+ }
}
return !(errno == EINVAL || errno == ENOENT);
diff --git a/src/common/impl/kmod_windows.c b/src/common/impl/kmod_windows.c
index 3eb275760c..b8db05210c 100644
--- a/src/common/impl/kmod_windows.c
+++ b/src/common/impl/kmod_windows.c
@@ -3,24 +3,25 @@
#include "common/mallocHelper.h"
#include "common/stringUtils.h"
-bool ffKmodLoaded(const char* modName)
-{
+bool ffKmodLoaded(const char* modName) {
ULONG bufferSize = 0;
NtQuerySystemInformation(SystemModuleInformation, NULL, 0, &bufferSize);
- if (bufferSize == 0)
+ if (bufferSize == 0) {
return true; // ignore errors
+ }
FF_AUTO_FREE RTL_PROCESS_MODULES* buffer = malloc(bufferSize);
- if (!NT_SUCCESS(NtQuerySystemInformation(SystemModuleInformation, buffer, bufferSize, &bufferSize)))
+ if (!NT_SUCCESS(NtQuerySystemInformation(SystemModuleInformation, buffer, bufferSize, &bufferSize))) {
return true; // ignore errors
+ }
- for (ULONG i = 0; i < buffer->NumberOfModules; i++)
- {
+ for (ULONG i = 0; i < buffer->NumberOfModules; i++) {
const char* name = (const char*) buffer->Modules[i].FullPathName + buffer->Modules[i].OffsetToFileName;
- if (ffStrEqualsIgnCase(name, modName))
+ if (ffStrEqualsIgnCase(name, modName)) {
return true;
+ }
}
return false;
diff --git a/src/common/impl/library.c b/src/common/impl/library.c
index ee3626b457..863f851f31 100644
--- a/src/common/impl/library.c
+++ b/src/common/impl/library.c
@@ -2,33 +2,32 @@
#include "common/library.h"
#if _WIN32
-#include "common/debug.h"
-#include "common/windows/nt.h"
-#include
-#include
+ #include "common/debug.h"
+ #include "common/windows/nt.h"
+ #include
+ #include
#endif
#ifndef FF_DISABLE_DLOPEN
-#include
+ #include
-//Clang doesn't define __SANITIZE_ADDRESS__ but defines __has_feature(address_sanitizer)
-#if !defined(__SANITIZE_ADDRESS__) && defined(__has_feature)
- #if __has_feature(address_sanitizer)
- #define __SANITIZE_ADDRESS__
+ // Clang doesn't define __SANITIZE_ADDRESS__ but defines __has_feature(address_sanitizer)
+ #if !defined(__SANITIZE_ADDRESS__) && defined(__has_feature)
+ #if __has_feature(address_sanitizer)
+ #define __SANITIZE_ADDRESS__
+ #endif
#endif
-#endif
-#ifndef FF_DLOPEN_FLAGS
- #ifdef __SANITIZE_ADDRESS__
- #define FF_DLOPEN_FLAGS RTLD_LAZY | RTLD_NODELETE
- #else
- #define FF_DLOPEN_FLAGS RTLD_LAZY
+ #ifndef FF_DLOPEN_FLAGS
+ #ifdef __SANITIZE_ADDRESS__
+ #define FF_DLOPEN_FLAGS RTLD_LAZY | RTLD_NODELETE
+ #else
+ #define FF_DLOPEN_FLAGS RTLD_LAZY
+ #endif
#endif
-#endif
-static void* libraryLoad(const char* path, int maxVersion)
-{
+static void* libraryLoad(const char* path, int maxVersion) {
void* result = dlopen(path, FF_DLOPEN_FLAGS);
#ifdef _WIN32
@@ -36,12 +35,14 @@ static void* libraryLoad(const char* path, int maxVersion)
// libX.dll.1 never exists on Windows, while libX-1.dll may exist
FF_UNUSED(maxVersion)
- if(result != NULL)
+ if (result != NULL) {
return result;
+ }
uint32_t pathLen = ffStrbufLastIndexC(&instance.state.platform.exePath, '/');
- if (pathLen == instance.state.platform.exePath.length)
+ if (pathLen == instance.state.platform.exePath.length) {
return result;
+ }
char absPath[MAX_PATH * 2];
strcpy(mempcpy(absPath, instance.state.platform.exePath.chars, pathLen + 1), path);
@@ -49,21 +50,22 @@ static void* libraryLoad(const char* path, int maxVersion)
#else
- if(result != NULL || maxVersion < 0)
+ if (result != NULL || maxVersion < 0) {
return result;
+ }
FF_STRBUF_AUTO_DESTROY pathbuf = ffStrbufCreateA(64);
ffStrbufAppendS(&pathbuf, path);
ffStrbufAppendC(&pathbuf, '.');
- for(int i = maxVersion; i >= 0; --i)
- {
+ for (int i = maxVersion; i >= 0; --i) {
uint32_t originalLength = pathbuf.length;
ffStrbufAppendSInt(&pathbuf, i);
result = dlopen(pathbuf.chars, FF_DLOPEN_FLAGS);
- if(result != NULL)
+ if (result != NULL) {
break;
+ }
ffStrbufSubstrBefore(&pathbuf, originalLength);
}
@@ -73,20 +75,18 @@ static void* libraryLoad(const char* path, int maxVersion)
return result;
}
-void* ffLibraryLoad(const char* path, int maxVersion, ...)
-{
+void* ffLibraryLoad(const char* path, int maxVersion, ...) {
void* result = libraryLoad(path, maxVersion);
- if (!result)
- {
+ if (!result) {
va_list defaultNames;
va_start(defaultNames, maxVersion);
- do
- {
+ do {
const char* pathRest = va_arg(defaultNames, const char*);
- if(pathRest == NULL)
+ if (pathRest == NULL) {
break;
+ }
int maxVersionRest = va_arg(defaultNames, int);
result = libraryLoad(pathRest, maxVersionRest);
@@ -102,27 +102,25 @@ void* ffLibraryLoad(const char* path, int maxVersion, ...)
#if _WIN32
-void* dlopen(const char* path, FF_MAYBE_UNUSED int mode)
-{
+void* dlopen(const char* path, FF_A_UNUSED int mode) {
wchar_t pathW[MAX_PATH + 1];
ULONG pathWBytes = 0;
- NTSTATUS status = RtlUTF8ToUnicodeN(pathW, sizeof(pathW), &pathWBytes, path, (uint32_t)strlen(path) + 1);
- if (!NT_SUCCESS(status))
- {
+ NTSTATUS status = RtlUTF8ToUnicodeN(pathW, sizeof(pathW), &pathWBytes, path, (uint32_t) strlen(path) + 1);
+ if (!NT_SUCCESS(status)) {
FF_DEBUG("RtlUTF8ToUnicodeN failed for path %s with status 0x%08lX: %s", path, status, ffDebugNtStatus(status));
return NULL;
}
PVOID module = NULL;
status = LdrLoadDll(NULL, NULL, &(UNICODE_STRING) {
- .Length = (USHORT) pathWBytes - sizeof(wchar_t), // Exclude null terminator
- .MaximumLength = (USHORT) pathWBytes,
- .Buffer = pathW,
- }, &module);
+ .Length = (USHORT) pathWBytes - sizeof(wchar_t), // Exclude null terminator
+ .MaximumLength = (USHORT) pathWBytes,
+ .Buffer = pathW,
+ },
+ &module);
- if (!NT_SUCCESS(status))
- {
+ if (!NT_SUCCESS(status)) {
FF_DEBUG("LdrLoadDll failed for path %s with status 0x%08lX: %s", path, status, ffDebugNtStatus(status));
return NULL;
}
@@ -130,47 +128,44 @@ void* dlopen(const char* path, FF_MAYBE_UNUSED int mode)
return module;
}
-int dlclose(void* handle)
-{
+int dlclose(void* handle) {
NTSTATUS status = LdrUnloadDll(handle);
- if (!NT_SUCCESS(status))
- {
+ if (!NT_SUCCESS(status)) {
FF_DEBUG("LdrUnloadDll failed for handle %p with status 0x%08lX: %s", handle, status, ffDebugNtStatus(status));
return -1;
}
return 0;
}
-void* dlsym(void* handle, const char* symbol)
-{
+void* dlsym(void* handle, const char* symbol) {
void* address;
USHORT symbolBytes = (USHORT) strlen(symbol) + 1;
NTSTATUS status = LdrGetProcedureAddress(handle, &(ANSI_STRING) {
- .Length = symbolBytes - sizeof(char),
- .MaximumLength = symbolBytes,
- .Buffer = (char*) symbol,
- }, 0, &address);
- if (!NT_SUCCESS(status))
- {
+ .Length = symbolBytes - sizeof(char),
+ .MaximumLength = symbolBytes,
+ .Buffer = (char*) symbol,
+ },
+ 0,
+ &address);
+ if (!NT_SUCCESS(status)) {
FF_DEBUG("LdrGetProcedureAddress failed for symbol %s with status 0x%08lX: %s", symbol, status, ffDebugNtStatus(status));
return NULL;
}
return address;
}
-void* ffLibraryGetModule(const wchar_t* libraryFileName)
-{
+void* ffLibraryGetModule(const wchar_t* libraryFileName) {
assert(libraryFileName != NULL && "Use \"ffGetPeb()->ImageBaseAddress\" instead");
void* module = NULL;
USHORT libraryFileNameBytes = (USHORT) (wcslen(libraryFileName) * sizeof(wchar_t)) + sizeof(wchar_t);
NTSTATUS status = LdrGetDllHandle(NULL, NULL, &(UNICODE_STRING) {
- .Length = libraryFileNameBytes - sizeof(wchar_t),
- .MaximumLength = libraryFileNameBytes,
- .Buffer = (wchar_t*) libraryFileName,
- }, &module);
- if (!NT_SUCCESS(status))
- {
+ .Length = libraryFileNameBytes - sizeof(wchar_t),
+ .MaximumLength = libraryFileNameBytes,
+ .Buffer = (wchar_t*) libraryFileName,
+ },
+ &module);
+ if (!NT_SUCCESS(status)) {
FF_DEBUG("LdrGetDllHandle failed for library %ls with status 0x%08lX: %s", libraryFileName, status, ffDebugNtStatus(status));
return NULL;
}
diff --git a/src/common/impl/memrchr.c b/src/common/impl/memrchr.c
index 730a3ae3a5..aaf97e604a 100644
--- a/src/common/impl/memrchr.c
+++ b/src/common/impl/memrchr.c
@@ -2,17 +2,19 @@
#include
#include
-void* memrchr(const void* s, int c, size_t n)
-{
- if (n == 0) return NULL;
+void* memrchr(const void* s, int c, size_t n) {
+ if (n == 0) {
+ return NULL;
+ }
const uint8_t uc = (uint8_t) c;
const uint8_t* p = (const uint8_t*) s + n;
- while (n--)
- {
- if (*--p == uc) return (void*) p;
+ while (n--) {
+ if (*--p == uc) {
+ return (void*) p;
+ }
}
return NULL;
diff --git a/src/common/impl/netif.c b/src/common/impl/netif.c
index 708399bfa2..1525a185a0 100644
--- a/src/common/impl/netif.c
+++ b/src/common/impl/netif.c
@@ -5,8 +5,7 @@
#include
#endif
-const FFNetifDefaultRouteResult* ffNetifGetDefaultRouteV4(void)
-{
+const FFNetifDefaultRouteResult* ffNetifGetDefaultRouteV4(void) {
static FFNetifDefaultRouteResult result;
if (result.status == FF_NETIF_UNINITIALIZED) {
result.status = ffNetifGetDefaultRouteImplV4(&result) ? FF_NETIF_OK : FF_NETIF_INVALID;
@@ -14,8 +13,7 @@ const FFNetifDefaultRouteResult* ffNetifGetDefaultRouteV4(void)
return &result;
}
-const FFNetifDefaultRouteResult* ffNetifGetDefaultRouteV6(void)
-{
+const FFNetifDefaultRouteResult* ffNetifGetDefaultRouteV6(void) {
static FFNetifDefaultRouteResult result;
if (result.status == FF_NETIF_UNINITIALIZED) {
result.status = ffNetifGetDefaultRouteImplV6(&result) ? FF_NETIF_OK : FF_NETIF_INVALID;
diff --git a/src/common/impl/netif_apple.c b/src/common/impl/netif_apple.c
index 346ce89373..b37ea2cb9c 100644
--- a/src/common/impl/netif_apple.c
+++ b/src/common/impl/netif_apple.c
@@ -8,68 +8,66 @@
#include
#include
-#define ROUNDUP2(a, n) ((a) > 0 ? (1 + (((a) - 1U) | ((n) - 1))) : (n))
+#define ROUNDUP2(a, n) ((a) > 0 ? (1 + (((a) - 1U) | ((n) - 1))) : (n))
#if __APPLE__
// https://github.com/apple-oss-distributions/network_cmds/blob/8f38231438e6a4d16ef8015e97e12c2c05105644/rtsol.tproj/if.c#L243
- #define ROUNDUP(a) ROUNDUP2((a), sizeof(uint32_t))
+ #define ROUNDUP(a) ROUNDUP2((a), sizeof(uint32_t))
#elif __sun
// https://github.com/illumos/illumos-gate/blob/95b8c88950fa7b19af46bc63230137cf96b0bff7/usr/src/cmd/cmd-inet/usr.sbin/route.c#L339
- #define ROUNDUP(a) ROUNDUP2((a), sizeof(long))
+ #define ROUNDUP(a) ROUNDUP2((a), sizeof(long))
#else
#error unknown platform
#endif
-static struct sockaddr *
-get_rt_address(struct rt_msghdr *rtm, int desired)
-{
- struct sockaddr *sa = (struct sockaddr *)(rtm + 1);
+static struct sockaddr*
+get_rt_address(struct rt_msghdr* rtm, int desired) {
+ struct sockaddr* sa = (struct sockaddr*) (rtm + 1);
- for (int i = 0; i < RTAX_MAX; i++)
- {
- if (rtm->rtm_addrs & (1 << i))
- {
- if ((1 << i) == desired)
+ for (int i = 0; i < RTAX_MAX; i++) {
+ if (rtm->rtm_addrs & (1 << i)) {
+ if ((1 << i) == desired) {
return sa;
+ }
- #ifndef __sun
+#ifndef __sun
uint32_t salen = sa->sa_len;
- #else
+#else
uint32_t salen;
// https://github.com/illumos/illumos-gate/blob/95b8c88950fa7b19af46bc63230137cf96b0bff7/usr/src/cmd/cmd-inet/usr.sbin/route.c#L2941
switch (sa->sa_family) {
- case AF_INET:
- salen = sizeof (struct sockaddr_in);
- break;
- case AF_LINK:
- salen = sizeof (struct sockaddr_dl);
- break;
- case AF_INET6:
- salen = sizeof (struct sockaddr_in6);
- break;
- default:
- salen = sizeof (struct sockaddr);
- break;
+ case AF_INET:
+ salen = sizeof(struct sockaddr_in);
+ break;
+ case AF_LINK:
+ salen = sizeof(struct sockaddr_dl);
+ break;
+ case AF_INET6:
+ salen = sizeof(struct sockaddr_in6);
+ break;
+ default:
+ salen = sizeof(struct sockaddr);
+ break;
}
- #endif
- sa = (struct sockaddr *)(ROUNDUP(salen) + (char *)sa);
+#endif
+ sa = (struct sockaddr*) (ROUNDUP(salen) + (char*) sa);
}
}
return NULL;
}
-bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
-{
- //https://github.com/hashPirate/copenheimer-masscan-fork/blob/36f1ed9f7b751a7dccd5ed27874e2e703db7d481/src/rawsock-getif.c#L104
+bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
+ // https://github.com/hashPirate/copenheimer-masscan-fork/blob/36f1ed9f7b751a7dccd5ed27874e2e703db7d481/src/rawsock-getif.c#L104
FF_AUTO_CLOSE_FD int pfRoute = socket(PF_ROUTE, SOCK_RAW, AF_INET);
- if (pfRoute < 0)
+ if (pfRoute < 0) {
return false;
+ }
{
- struct timeval timeout = {1, 0};
- setsockopt(pfRoute, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
- setsockopt(pfRoute, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout));
+ struct timeval timeout = { 1, 0 };
+ setsockopt(pfRoute, SOL_SOCKET, SO_RCVTIMEO, (char*) &timeout, sizeof(timeout));
+ setsockopt(pfRoute, SOL_SOCKET, SO_SNDTIMEO, (char*) &timeout, sizeof(timeout));
}
uint32_t pid = instance.state.platform.pid;
@@ -90,38 +88,38 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
},
.dst = {
.sin_family = AF_INET,
- #ifndef __sun
+#ifndef __sun
.sin_len = sizeof(rtmsg.dst),
- #endif
+#endif
},
};
- if (send(pfRoute, &rtmsg, rtmsg.hdr.rtm_msglen, 0) != rtmsg.hdr.rtm_msglen)
+ if (send(pfRoute, &rtmsg, rtmsg.hdr.rtm_msglen, 0) != rtmsg.hdr.rtm_msglen) {
return false;
+ }
- while (recv(pfRoute, &rtmsg, sizeof(rtmsg), 0) > 0 && !(rtmsg.hdr.rtm_seq == 1 && rtmsg.hdr.rtm_pid == (pid_t) pid))
- ;
+ while (recv(pfRoute, &rtmsg, sizeof(rtmsg), 0) > 0 && !(rtmsg.hdr.rtm_seq == 1 && rtmsg.hdr.rtm_pid == (pid_t) pid));
- #ifndef __sun // On Solaris, the RTF_GATEWAY flag is not set for default routes for some reason
+#ifndef __sun // On Solaris, the RTF_GATEWAY flag is not set for default routes for some reason
if ((rtmsg.hdr.rtm_flags & (RTF_UP | RTF_GATEWAY)) == (RTF_UP | RTF_GATEWAY))
- #endif
+#endif
{
- struct sockaddr_dl* sdl = (struct sockaddr_dl *)get_rt_address(&rtmsg.hdr, RTA_IFP);
+ struct sockaddr_dl* sdl = (struct sockaddr_dl*) get_rt_address(&rtmsg.hdr, RTA_IFP);
if (sdl
- #ifndef __sun
+#ifndef __sun
&& sdl->sdl_len
- #endif
- )
- {
+#endif
+ ) {
assert(sdl->sdl_nlen <= IF_NAMESIZE);
memcpy(result->ifName, sdl->sdl_data, sdl->sdl_nlen);
result->ifName[sdl->sdl_nlen] = '\0';
result->ifIndex = sdl->sdl_index;
// Get the preferred source address
- struct sockaddr_in* src = (struct sockaddr_in*)get_rt_address(&rtmsg.hdr, RTA_IFA);
- if (src && src->sin_family == AF_INET)
+ struct sockaddr_in* src = (struct sockaddr_in*) get_rt_address(&rtmsg.hdr, RTA_IFA);
+ if (src && src->sin_family == AF_INET) {
result->preferredSourceAddrV4 = src->sin_addr.s_addr;
+ }
return true;
}
@@ -131,18 +129,18 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
return false;
}
-bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
-{
- //https://github.com/hashPirate/copenheimer-masscan-fork/blob/36f1ed9f7b751a7dccd5ed27874e2e703db7d481/src/rawsock-getif.c#L104
+bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result) {
+ // https://github.com/hashPirate/copenheimer-masscan-fork/blob/36f1ed9f7b751a7dccd5ed27874e2e703db7d481/src/rawsock-getif.c#L104
FF_AUTO_CLOSE_FD int pfRoute = socket(PF_ROUTE, SOCK_RAW, AF_INET6);
- if (pfRoute < 0)
+ if (pfRoute < 0) {
return false;
+ }
{
- struct timeval timeout = {1, 0};
- setsockopt(pfRoute, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
- setsockopt(pfRoute, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout));
+ struct timeval timeout = { 1, 0 };
+ setsockopt(pfRoute, SOL_SOCKET, SO_RCVTIMEO, (char*) &timeout, sizeof(timeout));
+ setsockopt(pfRoute, SOL_SOCKET, SO_SNDTIMEO, (char*) &timeout, sizeof(timeout));
}
uint32_t pid = instance.state.platform.pid;
@@ -163,29 +161,28 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
},
.dst = {
.sin6_family = AF_INET6,
- #ifndef __sun
+#ifndef __sun
.sin6_len = sizeof(rtmsg.dst),
- #endif
+#endif
},
};
- if (send(pfRoute, &rtmsg, rtmsg.hdr.rtm_msglen, 0) != rtmsg.hdr.rtm_msglen)
+ if (send(pfRoute, &rtmsg, rtmsg.hdr.rtm_msglen, 0) != rtmsg.hdr.rtm_msglen) {
return false;
+ }
- while (recv(pfRoute, &rtmsg, sizeof(rtmsg), 0) > 0 && !(rtmsg.hdr.rtm_seq == 2 && rtmsg.hdr.rtm_pid == (pid_t) pid))
- ;
+ while (recv(pfRoute, &rtmsg, sizeof(rtmsg), 0) > 0 && !(rtmsg.hdr.rtm_seq == 2 && rtmsg.hdr.rtm_pid == (pid_t) pid));
- #ifndef __sun // On Solaris, the RTF_GATEWAY flag is not set for default routes for some reason
+#ifndef __sun // On Solaris, the RTF_GATEWAY flag is not set for default routes for some reason
if ((rtmsg.hdr.rtm_flags & (RTF_UP | RTF_GATEWAY)) == (RTF_UP | RTF_GATEWAY))
- #endif
+#endif
{
- struct sockaddr_dl* sdl = (struct sockaddr_dl *)get_rt_address(&rtmsg.hdr, RTA_IFP);
+ struct sockaddr_dl* sdl = (struct sockaddr_dl*) get_rt_address(&rtmsg.hdr, RTA_IFP);
if (sdl
- #ifndef __sun
+#ifndef __sun
&& sdl->sdl_len
- #endif
- )
- {
+#endif
+ ) {
assert(sdl->sdl_nlen <= IF_NAMESIZE);
memcpy(result->ifName, sdl->sdl_data, sdl->sdl_nlen);
result->ifName[sdl->sdl_nlen] = '\0';
diff --git a/src/common/impl/netif_bsd.c b/src/common/impl/netif_bsd.c
index a5b240c003..72ef96b74f 100644
--- a/src/common/impl/netif_bsd.c
+++ b/src/common/impl/netif_bsd.c
@@ -9,75 +9,72 @@
#include
#include
-#define ROUNDUP2(a, n) ((a) > 0 ? (1 + (((a) - 1U) | ((n) - 1))) : (n))
+#define ROUNDUP2(a, n) ((a) > 0 ? (1 + (((a) - 1U) | ((n) - 1))) : (n))
#if __DragonFly__
// https://github.com/DragonFlyBSD/DragonFlyBSD/blob/cf0aa2f1e47a3f0a6055fe427563cb3f3e627064/sys/net/route.h#L315C9-L315C19
- #define ROUNDUP(a) ROUNDUP2((a), sizeof(long))
+ #define ROUNDUP(a) ROUNDUP2((a), sizeof(long))
#elif __FreeBSD__
// https://github.com/freebsd/freebsd-src/blob/e4c0ecba44b20ebb2e4d80978c2cb6d16b730cb9/sys/net/route.h#L368C9-L368C16
- #define ROUNDUP(a) ROUNDUP2((a), sizeof(long))
+ #define ROUNDUP(a) ROUNDUP2((a), sizeof(long))
#elif __NetBSD__
// https://github.com/NetBSD/src/blob/29beb637d057520c0ed37ac2cde966f7cc0cadf4/sys/net/route.h#L330
- #define ROUNDUP(a) ROUNDUP2((a), sizeof(uint64_t))
+ #define ROUNDUP(a) ROUNDUP2((a), sizeof(uint64_t))
#elif __OpenBSD__
// https://github.com/openbsd/src/blob/ca647cfa4ec3ccb8360714bc0ebc32a394f7fb6a/regress/sys/netinet/bindconnect/bindconnect.c#L250
- #define ROUNDUP(a) ROUNDUP2((a), sizeof(long))
+ #define ROUNDUP(a) ROUNDUP2((a), sizeof(long))
#else
#error unknown platform
#endif
-static struct sockaddr *
-get_rt_address(struct rt_msghdr *rtm, int desired)
-{
- struct sockaddr *sa = (struct sockaddr *)(rtm + 1);
+static struct sockaddr*
+get_rt_address(struct rt_msghdr* rtm, int desired) {
+ struct sockaddr* sa = (struct sockaddr*) (rtm + 1);
- for (int i = 0; i < RTAX_MAX; i++)
- {
- if (rtm->rtm_addrs & (1 << i))
- {
- if ((1 << i) == desired)
+ for (int i = 0; i < RTAX_MAX; i++) {
+ if (rtm->rtm_addrs & (1 << i)) {
+ if ((1 << i) == desired) {
return sa;
- sa = (struct sockaddr *)(ROUNDUP(sa->sa_len) + (char *)sa);
+ }
+ sa = (struct sockaddr*) (ROUNDUP(sa->sa_len) + (char*) sa);
}
}
return NULL;
}
-bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
-{
- int mib[6] = {CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_FLAGS, RTF_GATEWAY};
+bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
+ int mib[6] = { CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_FLAGS, RTF_GATEWAY };
size_t needed;
- if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0 || needed == 0)
+ if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0 || needed == 0) {
return false;
+ }
FF_AUTO_FREE char* buf = malloc(needed);
- if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
+ if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
return false;
+ }
char* lim = buf + needed;
struct rt_msghdr* rtm;
- for (char* next = buf; next < lim; next += rtm->rtm_msglen)
- {
- rtm = (struct rt_msghdr *)next;
- struct sockaddr* sa = (struct sockaddr *)(rtm + 1);
-
- if ((rtm->rtm_flags & RTF_GATEWAY) && !(rtm->rtm_flags & RTF_REJECT) && (sa->sa_family == AF_INET))
- {
- struct sockaddr_dl* sdl = (struct sockaddr_dl *)get_rt_address(rtm, RTA_IFP);
- if (sdl && sdl->sdl_family == AF_LINK)
- {
+ for (char* next = buf; next < lim; next += rtm->rtm_msglen) {
+ rtm = (struct rt_msghdr*) next;
+ struct sockaddr* sa = (struct sockaddr*) (rtm + 1);
+
+ if ((rtm->rtm_flags & RTF_GATEWAY) && !(rtm->rtm_flags & RTF_REJECT) && (sa->sa_family == AF_INET)) {
+ struct sockaddr_dl* sdl = (struct sockaddr_dl*) get_rt_address(rtm, RTA_IFP);
+ if (sdl && sdl->sdl_family == AF_LINK) {
assert(sdl->sdl_nlen <= IF_NAMESIZE);
memcpy(result->ifName, sdl->sdl_data, sdl->sdl_nlen);
result->ifName[sdl->sdl_nlen] = '\0';
result->ifIndex = sdl->sdl_index;
// Get the preferred source address
- struct sockaddr_in* src = (struct sockaddr_in*)get_rt_address(rtm, RTA_IFA);
- if (src && src->sin_family == AF_INET)
+ struct sockaddr_in* src = (struct sockaddr_in*) get_rt_address(rtm, RTA_IFA);
+ if (src && src->sin_family == AF_INET) {
result->preferredSourceAddrV4 = src->sin_addr.s_addr;
+ }
return true;
}
@@ -86,31 +83,29 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
return false;
}
-bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
-{
- int mib[6] = {CTL_NET, PF_ROUTE, 0, AF_INET6, NET_RT_FLAGS, RTF_GATEWAY};
+bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result) {
+ int mib[6] = { CTL_NET, PF_ROUTE, 0, AF_INET6, NET_RT_FLAGS, RTF_GATEWAY };
size_t needed;
- if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0 || needed == 0)
+ if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0 || needed == 0) {
return false;
+ }
FF_AUTO_FREE char* buf = malloc(needed);
- if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
+ if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
return false;
+ }
char* lim = buf + needed;
struct rt_msghdr* rtm;
- for (char* next = buf; next < lim; next += rtm->rtm_msglen)
- {
- rtm = (struct rt_msghdr *)next;
- struct sockaddr* sa = (struct sockaddr *)(rtm + 1);
-
- if ((rtm->rtm_flags & RTF_GATEWAY) && !(rtm->rtm_flags & RTF_REJECT) && (sa->sa_family == AF_INET6))
- {
- struct sockaddr_dl* sdl = (struct sockaddr_dl *)get_rt_address(rtm, RTA_IFP);
- if (sdl && sdl->sdl_family == AF_LINK)
- {
+ for (char* next = buf; next < lim; next += rtm->rtm_msglen) {
+ rtm = (struct rt_msghdr*) next;
+ struct sockaddr* sa = (struct sockaddr*) (rtm + 1);
+
+ if ((rtm->rtm_flags & RTF_GATEWAY) && !(rtm->rtm_flags & RTF_REJECT) && (sa->sa_family == AF_INET6)) {
+ struct sockaddr_dl* sdl = (struct sockaddr_dl*) get_rt_address(rtm, RTA_IFP);
+ if (sdl && sdl->sdl_family == AF_LINK) {
assert(sdl->sdl_nlen <= IF_NAMESIZE);
memcpy(result->ifName, sdl->sdl_data, sdl->sdl_nlen);
result->ifName[sdl->sdl_nlen] = '\0';
diff --git a/src/common/impl/netif_gnu.c b/src/common/impl/netif_gnu.c
index 219bbebab7..d2cf5d009e 100644
--- a/src/common/impl/netif_gnu.c
+++ b/src/common/impl/netif_gnu.c
@@ -7,18 +7,20 @@
#define FF_STR_INDIR(x) #x
#define FF_STR(x) FF_STR_INDIR(x)
-bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
-{
+bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
FILE* FF_AUTO_CLOSE_FILE netRoute = fopen("/proc/route", "r");
- if (!netRoute) return false;
+ if (!netRoute) {
+ return false;
+ }
// skip first line
FF_UNUSED(fscanf(netRoute, "%*[^\n]\n"));
unsigned long long destination; //, gateway, flags, refCount, use, metric, mask, mtu, ...
- while (fscanf(netRoute, "%" FF_STR(IF_NAMESIZE) "s%llx%*[^\n]", result->ifName, &destination) == 2)
- {
- if (destination != 0) continue;
+ while (fscanf(netRoute, "%" FF_STR(IF_NAMESIZE) "s%llx%*[^\n]", result->ifName, &destination) == 2) {
+ if (destination != 0) {
+ continue;
+ }
result->ifIndex = if_nametoindex(result->ifName);
// TODO: Get the preferred source address
return true;
@@ -27,8 +29,7 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
return false;
}
-bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
-{
+bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result) {
// TODO: AF_INET6
FF_UNUSED(result);
return false;
diff --git a/src/common/impl/netif_haiku.c b/src/common/impl/netif_haiku.c
index faa3ee8761..f04183a1fb 100644
--- a/src/common/impl/netif_haiku.c
+++ b/src/common/impl/netif_haiku.c
@@ -11,85 +11,95 @@
// loosely based on Haiku's src/bin/network/route/route.cpp
-bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
-{
+bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
FF_AUTO_CLOSE_FD int pfRoute = socket(AF_INET, SOCK_RAW, AF_INET);
- if (pfRoute < 0)
+ if (pfRoute < 0) {
return false;
+ }
struct ifconf config;
config.ifc_len = sizeof(config.ifc_value);
- if (ioctl(pfRoute, SIOCGRTSIZE, &config, sizeof(struct ifconf)) < 0)
+ if (ioctl(pfRoute, SIOCGRTSIZE, &config, sizeof(struct ifconf)) < 0) {
return false;
+ }
int size = config.ifc_value;
- if (size <= 0)
+ if (size <= 0) {
return false;
+ }
- FF_AUTO_FREE void *buffer = malloc((size_t) size);
+ FF_AUTO_FREE void* buffer = malloc((size_t) size);
if (buffer == NULL) {
return false;
}
config.ifc_len = size;
config.ifc_buf = buffer;
- if (ioctl(pfRoute, SIOCGRTTABLE, &config, sizeof(struct ifconf)) < 0)
+ if (ioctl(pfRoute, SIOCGRTTABLE, &config, sizeof(struct ifconf)) < 0) {
return false;
+ }
- struct ifreq *interface = (struct ifreq*)buffer;
- struct ifreq *end = (struct ifreq*)((uint8_t*)buffer + size);
+ struct ifreq* interface = (struct ifreq*) buffer;
+ struct ifreq* end = (struct ifreq*) ((uint8_t*) buffer + size);
while (interface < end) {
if (interface->ifr_route.flags & RTF_DEFAULT) {
// interface->ifr_metric?
strlcpy(result->ifName, interface->ifr_name, IF_NAMESIZE);
result->ifIndex = if_nametoindex(interface->ifr_name);
- if (interface->ifr_route.source)
- result->preferredSourceAddrV4 = ((struct sockaddr_in*)interface->ifr_route.source)->sin_addr.s_addr;
+ if (interface->ifr_route.source) {
+ result->preferredSourceAddrV4 = ((struct sockaddr_in*) interface->ifr_route.source)->sin_addr.s_addr;
+ }
return true;
}
size_t addressSize = 0;
- if (interface->ifr_route.destination != NULL)
+ if (interface->ifr_route.destination != NULL) {
addressSize += interface->ifr_route.destination->sa_len;
- if (interface->ifr_route.mask != NULL)
+ }
+ if (interface->ifr_route.mask != NULL) {
addressSize += interface->ifr_route.mask->sa_len;
- if (interface->ifr_route.gateway != NULL)
+ }
+ if (interface->ifr_route.gateway != NULL) {
addressSize += interface->ifr_route.gateway->sa_len;
+ }
- interface = (struct ifreq*)((addr_t)interface + IF_NAMESIZE + sizeof(struct route_entry) + addressSize);
+ interface = (struct ifreq*) ((addr_t) interface + IF_NAMESIZE + sizeof(struct route_entry) + addressSize);
}
return false;
}
-bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
-{
+bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result) {
FF_AUTO_CLOSE_FD int pfRoute = socket(AF_INET, SOCK_RAW, AF_INET6);
- if (pfRoute < 0)
+ if (pfRoute < 0) {
return false;
+ }
struct ifconf config;
config.ifc_len = sizeof(config.ifc_value);
- if (ioctl(pfRoute, SIOCGRTSIZE, &config, sizeof(struct ifconf)) < 0)
+ if (ioctl(pfRoute, SIOCGRTSIZE, &config, sizeof(struct ifconf)) < 0) {
return false;
+ }
int size = config.ifc_value;
- if (size <= 0)
+ if (size <= 0) {
return false;
+ }
- FF_AUTO_FREE void *buffer = malloc((size_t) size);
+ FF_AUTO_FREE void* buffer = malloc((size_t) size);
if (buffer == NULL) {
return false;
}
config.ifc_len = size;
config.ifc_buf = buffer;
- if (ioctl(pfRoute, SIOCGRTTABLE, &config, sizeof(struct ifconf)) < 0)
+ if (ioctl(pfRoute, SIOCGRTTABLE, &config, sizeof(struct ifconf)) < 0) {
return false;
+ }
- struct ifreq *interface = (struct ifreq*)buffer;
- struct ifreq *end = (struct ifreq*)((uint8_t*)buffer + size);
+ struct ifreq* interface = (struct ifreq*) buffer;
+ struct ifreq* end = (struct ifreq*) ((uint8_t*) buffer + size);
while (interface < end) {
if (interface->ifr_route.flags & RTF_DEFAULT) {
@@ -99,14 +109,17 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
}
size_t addressSize = 0;
- if (interface->ifr_route.destination != NULL)
+ if (interface->ifr_route.destination != NULL) {
addressSize += interface->ifr_route.destination->sa_len;
- if (interface->ifr_route.mask != NULL)
+ }
+ if (interface->ifr_route.mask != NULL) {
addressSize += interface->ifr_route.mask->sa_len;
- if (interface->ifr_route.gateway != NULL)
+ }
+ if (interface->ifr_route.gateway != NULL) {
addressSize += interface->ifr_route.gateway->sa_len;
+ }
- interface = (struct ifreq*)((addr_t)interface + IF_NAMESIZE + sizeof(struct route_entry) + addressSize);
+ interface = (struct ifreq*) ((addr_t) interface + IF_NAMESIZE + sizeof(struct route_entry) + addressSize);
}
return false;
}
diff --git a/src/common/impl/netif_linux.c b/src/common/impl/netif_linux.c
index 092d919fb6..67e4868212 100644
--- a/src/common/impl/netif_linux.c
+++ b/src/common/impl/netif_linux.c
@@ -7,35 +7,44 @@
#include
#include
-bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
-{
+static uint32_t ffNetifGetNetlinkPortId(int sock_fd) {
+ struct sockaddr_nl addr = {};
+ socklen_t addrLen = sizeof(addr);
+ if (getsockname(sock_fd, (struct sockaddr*) &addr, &addrLen) < 0) {
+ FF_DEBUG("Failed to query netlink socket address (use PID instead): %s", strerror(errno));
+ return instance.state.platform.pid;
+ } else {
+ FF_DEBUG("Netlink port ID: %u", addr.nl_pid);
+ return addr.nl_pid;
+ }
+}
+
+bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
FF_DEBUG("Starting IPv4 default route detection");
FF_AUTO_CLOSE_FD int sock_fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
- if (sock_fd < 0)
- {
+ if (sock_fd < 0) {
FF_DEBUG("Failed to create netlink socket: %s", strerror(errno));
return false;
}
FF_DEBUG("Created netlink socket: fd=%d", sock_fd);
- uint32_t pid = instance.state.platform.pid;
- FF_DEBUG("Process PID: %u", pid);
-
// Bind socket
struct sockaddr_nl addr = {
.nl_family = AF_NETLINK,
- .nl_pid = 0, // Let kernel choose PID
- .nl_groups = 0, // No multicast groups
+ .nl_pid = 0, // Let kernel choose PID
+ .nl_groups = 0, // No multicast groups
};
- if (bind(sock_fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
+ if (bind(sock_fd, (struct sockaddr*) &addr, sizeof(addr)) < 0) {
FF_DEBUG("Failed to bind socket: %s", strerror(errno));
return false;
}
FF_DEBUG("Successfully bound socket");
- struct __attribute__((__packed__)) {
+ uint32_t pid = ffNetifGetNetlinkPortId(sock_fd);
+
+ struct FF_A_PACKED {
struct nlmsghdr nlh;
struct rtmsg rtm;
struct rtattr rta;
@@ -52,8 +61,8 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
// Route message
.rtm = {
.rtm_family = AF_INET,
- .rtm_dst_len = 0, // Match all destinations
- .rtm_src_len = 0, // Match all sources
+ .rtm_dst_len = 0, // Match all destinations
+ .rtm_src_len = 0, // Match all sources
.rtm_tos = 0,
.rtm_table = RT_TABLE_UNSPEC,
.rtm_protocol = RTPROT_UNSPEC,
@@ -71,12 +80,11 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
struct sockaddr_nl dest_addr = {
.nl_family = AF_NETLINK,
- .nl_pid = 0, // Kernel
- .nl_groups = 0, // No multicast groups
+ .nl_pid = 0, // Kernel
+ .nl_groups = 0, // No multicast groups
};
- ssize_t sent = sendto(sock_fd, &req, sizeof(req), 0,
- (struct sockaddr*)&dest_addr, sizeof(dest_addr));
+ ssize_t sent = sendto(sock_fd, &req, sizeof(req), 0, (struct sockaddr*) &dest_addr, sizeof(dest_addr));
if (sent != sizeof(req)) {
FF_DEBUG("Failed to send netlink request: sent=%zd, expected=%zu", sent, sizeof(req));
@@ -89,19 +97,17 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
uint8_t buffer[1024 * 16]; // 16 KB buffer should be sufficient
uint32_t minMetric = UINT32_MAX;
- FF_MAYBE_UNUSED int routeCount = 0;
+ FF_A_UNUSED int routeCount = 0;
- while (true)
- {
- ssize_t received = recvfrom(sock_fd, buffer, sizeof(buffer), 0,
- (struct sockaddr*)&src_addr, &src_addr_len);
+ while (true) {
+ ssize_t received = recvfrom(sock_fd, buffer, sizeof(buffer), 0, (struct sockaddr*) &src_addr, &src_addr_len);
if (received < 0) {
FF_DEBUG("Failed to receive netlink response: %s", strerror(errno));
return false;
}
- if (received >= (ssize_t)sizeof(buffer)) {
+ if (received >= (ssize_t) sizeof(buffer)) {
FF_DEBUG("Received truncated message: received %zd, bufsize %zu", received, sizeof(buffer));
return false;
}
@@ -117,20 +123,19 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
uint32_t prefsrc;
} entry;
- for (const struct nlmsghdr* nlh = (struct nlmsghdr*)buffer;
+ for (const struct nlmsghdr* nlh = (struct nlmsghdr*) buffer;
NLMSG_OK(nlh, received);
- nlh = NLMSG_NEXT(nlh, received))
- {
- if (nlh->nlmsg_seq != 1 || nlh->nlmsg_pid != pid)
+ nlh = NLMSG_NEXT(nlh, received)) {
+ if (nlh->nlmsg_seq != 1 || nlh->nlmsg_pid != pid) {
continue;
- if (nlh->nlmsg_type == NLMSG_DONE)
- {
+ }
+ if (nlh->nlmsg_type == NLMSG_DONE) {
FF_DEBUG("Received NLMSG_DONE, processed %d routes", routeCount);
goto exit;
}
if (nlh->nlmsg_type == NLMSG_ERROR) {
- FF_DEBUG("Netlink reports error: %s", strerror(-((struct nlmsgerr*)NLMSG_DATA(nlh))->error));
+ FF_DEBUG("Netlink reports error: %s", strerror(-((struct nlmsgerr*) NLMSG_DATA(nlh))->error));
continue;
}
@@ -140,7 +145,7 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
}
routeCount++;
- struct rtmsg* rtm = (struct rtmsg*)NLMSG_DATA(nlh);
+ struct rtmsg* rtm = (struct rtmsg*) NLMSG_DATA(nlh);
if (rtm->rtm_family != AF_INET) {
FF_DEBUG("Skipping non-IPv4 route #%d (family=%d)", routeCount, rtm->rtm_family);
continue;
@@ -158,16 +163,16 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
}
FF_DEBUG("Processing IPv4 default route candidate #%d", routeCount);
- entry = (__typeof__(entry)) { }; // Default to zero metric (no RTA_PRIORITY found)
+ entry = (__typeof__(entry)) {}; // Default to zero metric (no RTA_PRIORITY found)
// Parse route attributes
size_t rtm_len = RTM_PAYLOAD(nlh);
for (struct rtattr* rta = RTM_RTA(rtm);
RTA_OK(rta, rtm_len);
- rta = RTA_NEXT(rta, rtm_len))
- {
- if (RTA_PAYLOAD(rta) < sizeof(uint32_t))
+ rta = RTA_NEXT(rta, rtm_len)) {
+ if (RTA_PAYLOAD(rta) < sizeof(uint32_t)) {
continue; // Skip invalid attributes
+ }
uint32_t rta_data = *(uint32_t*) RTA_DATA(rta);
switch (rta->rta_type) {
@@ -179,23 +184,26 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
FF_DEBUG("Found interface index: %u", entry.ifindex);
break;
case RTA_GATEWAY:
- FF_DEBUG("Found gateway: %s", inet_ntoa(*(struct in_addr*)&rta_data));
- if (rta_data == 0) goto next;
+ FF_DEBUG("Found gateway: %s", inet_ntoa(*(struct in_addr*) &rta_data));
+ if (rta_data == 0) {
+ goto next;
+ }
break;
case RTA_PRIORITY:
FF_DEBUG("Found metric: %u", rta_data);
- if (rta_data >= minMetric) goto next;
+ if (rta_data >= minMetric) {
+ goto next;
+ }
entry.metric = rta_data;
break;
case RTA_PREFSRC:
entry.prefsrc = rta_data;
- FF_DEBUG("Found preferred source: %s", inet_ntoa(*(struct in_addr*)&rta_data));
+ FF_DEBUG("Found preferred source: %s", inet_ntoa(*(struct in_addr*) &rta_data));
break;
}
}
- if (entry.ifindex == 0 || entry.metric >= minMetric)
- {
+ if (entry.ifindex == 0 || entry.metric >= minMetric) {
next:
FF_DEBUG("Skipping route: ifindex=%u, metric=%u", entry.ifindex, entry.metric);
continue;
@@ -204,8 +212,7 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
result->ifIndex = entry.ifindex;
FF_DEBUG("Updated best route: ifindex=%u, metric=%u, prefsrc=%x", entry.ifindex, entry.metric, entry.prefsrc);
result->preferredSourceAddrV4 = entry.prefsrc;
- if (minMetric == 0)
- {
+ if (minMetric == 0) {
FF_DEBUG("Found zero metric route, stopping further processing");
break; // Stop processing if we found a zero metric route
}
@@ -213,8 +220,7 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
}
exit:
- if (minMetric < UINT32_MAX)
- {
+ if (minMetric < UINT32_MAX) {
if_indextoname(result->ifIndex, result->ifName);
FF_DEBUG("Found default IPv4 route: interface=%s, index=%u, metric=%u", result->ifName, result->ifIndex, minMetric);
return true;
@@ -223,35 +229,32 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
return false;
}
-bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
-{
+bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result) {
FF_DEBUG("Starting IPv6 default route detection");
FF_AUTO_CLOSE_FD int sock_fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
- if (sock_fd < 0)
- {
+ if (sock_fd < 0) {
FF_DEBUG("Failed to create netlink socket: %s", strerror(errno));
return false;
}
FF_DEBUG("Created netlink socket: fd=%d", sock_fd);
- uint32_t pid = instance.state.platform.pid;
- FF_DEBUG("Process PID: %u", pid);
-
// Bind socket
struct sockaddr_nl addr = {
.nl_family = AF_NETLINK,
- .nl_pid = 0, // Let kernel choose PID
- .nl_groups = 0, // No multicast groups
+ .nl_pid = 0, // Let kernel choose PID
+ .nl_groups = 0, // No multicast groups
};
- if (bind(sock_fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
+ if (bind(sock_fd, (struct sockaddr*) &addr, sizeof(addr)) < 0) {
FF_DEBUG("Failed to bind socket: %s", strerror(errno));
return false;
}
FF_DEBUG("Successfully bound socket");
- struct __attribute__((__packed__)) {
+ uint32_t pid = ffNetifGetNetlinkPortId(sock_fd);
+
+ struct FF_A_PACKED {
struct nlmsghdr nlh;
struct rtmsg rtm;
struct rtattr rta;
@@ -267,9 +270,9 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
},
// Route message
.rtm = {
- .rtm_family = AF_INET6, // IPv6 instead of IPv4
- .rtm_dst_len = 0, // Match all destinations
- .rtm_src_len = 0, // Match all sources
+ .rtm_family = AF_INET6, // IPv6 instead of IPv4
+ .rtm_dst_len = 0, // Match all destinations
+ .rtm_src_len = 0, // Match all sources
.rtm_tos = 0,
.rtm_table = RT_TABLE_UNSPEC,
.rtm_protocol = RTPROT_UNSPEC,
@@ -287,12 +290,11 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
struct sockaddr_nl dest_addr = {
.nl_family = AF_NETLINK,
- .nl_pid = 0, // Kernel
- .nl_groups = 0, // No multicast groups
+ .nl_pid = 0, // Kernel
+ .nl_groups = 0, // No multicast groups
};
- ssize_t sent = sendto(sock_fd, &req, sizeof(req), 0,
- (struct sockaddr*)&dest_addr, sizeof(dest_addr));
+ ssize_t sent = sendto(sock_fd, &req, sizeof(req), 0, (struct sockaddr*) &dest_addr, sizeof(dest_addr));
if (sent != sizeof(req)) {
FF_DEBUG("Failed to send netlink request: sent=%zd, expected=%zu", sent, sizeof(req));
@@ -305,19 +307,17 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
uint8_t buffer[1024 * 16]; // 16 KB buffer should be sufficient
uint32_t minMetric = UINT32_MAX;
- FF_MAYBE_UNUSED int routeCount = 0;
+ FF_A_UNUSED int routeCount = 0;
- while (true)
- {
- ssize_t received = recvfrom(sock_fd, buffer, sizeof(buffer), 0,
- (struct sockaddr*)&src_addr, &src_addr_len);
+ while (true) {
+ ssize_t received = recvfrom(sock_fd, buffer, sizeof(buffer), 0, (struct sockaddr*) &src_addr, &src_addr_len);
if (received < 0) {
FF_DEBUG("Failed to receive netlink response: %s", strerror(errno));
return false;
}
- if (received >= (ssize_t)sizeof(buffer)) {
+ if (received >= (ssize_t) sizeof(buffer)) {
FF_DEBUG("Received truncated message: received %zd, bufsize %zu", received, sizeof(buffer));
return false;
}
@@ -332,20 +332,19 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
uint32_t ifindex;
} entry;
- for (const struct nlmsghdr* nlh = (struct nlmsghdr*)buffer;
+ for (const struct nlmsghdr* nlh = (struct nlmsghdr*) buffer;
NLMSG_OK(nlh, received);
- nlh = NLMSG_NEXT(nlh, received))
- {
- if (nlh->nlmsg_seq != 1 || nlh->nlmsg_pid != pid)
+ nlh = NLMSG_NEXT(nlh, received)) {
+ if (nlh->nlmsg_seq != 1 || nlh->nlmsg_pid != pid) {
continue;
- if (nlh->nlmsg_type == NLMSG_DONE)
- {
+ }
+ if (nlh->nlmsg_type == NLMSG_DONE) {
FF_DEBUG("Received NLMSG_DONE, processed %d routes", routeCount);
goto exit;
}
if (nlh->nlmsg_type == NLMSG_ERROR) {
- FF_DEBUG("Netlink reports error: %s", strerror(-((struct nlmsgerr*)NLMSG_DATA(nlh))->error));
+ FF_DEBUG("Netlink reports error: %s", strerror(-((struct nlmsgerr*) NLMSG_DATA(nlh))->error));
continue;
}
@@ -355,7 +354,7 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
}
routeCount++;
- struct rtmsg* rtm = (struct rtmsg*)NLMSG_DATA(nlh);
+ struct rtmsg* rtm = (struct rtmsg*) NLMSG_DATA(nlh);
if (rtm->rtm_family != AF_INET6) {
FF_DEBUG("Skipping non-IPv6 route #%d (family=%d)", routeCount, rtm->rtm_family);
continue;
@@ -373,18 +372,17 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
}
FF_DEBUG("Processing IPv6 default route candidate #%d", routeCount);
- entry = (__typeof__(entry)) { }; // Default to zero metric (no RTA_PRIORITY found)
+ entry = (__typeof__(entry)) {}; // Default to zero metric (no RTA_PRIORITY found)
// Parse route attributes
size_t rtm_len = RTM_PAYLOAD(nlh);
for (struct rtattr* rta = RTM_RTA(rtm);
RTA_OK(rta, rtm_len);
- rta = RTA_NEXT(rta, rtm_len))
- {
+ rta = RTA_NEXT(rta, rtm_len)) {
switch (rta->rta_type) {
case RTA_DST:
if (RTA_PAYLOAD(rta) >= sizeof(struct in6_addr)) {
- FF_MAYBE_UNUSED char str[INET6_ADDRSTRLEN];
+ FF_A_UNUSED char str[INET6_ADDRSTRLEN];
FF_DEBUG("Unexpected RTA_DST: %s", inet_ntop(AF_INET6, RTA_DATA(rta), str, sizeof(str)));
goto next;
}
@@ -398,8 +396,10 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
case RTA_GATEWAY:
if (RTA_PAYLOAD(rta) >= sizeof(struct in6_addr)) {
struct in6_addr* gw = (struct in6_addr*) RTA_DATA(rta);
- if (IN6_IS_ADDR_UNSPECIFIED(gw)) goto next;
- FF_MAYBE_UNUSED char str[INET6_ADDRSTRLEN];
+ if (IN6_IS_ADDR_UNSPECIFIED(gw)) {
+ goto next;
+ }
+ FF_A_UNUSED char str[INET6_ADDRSTRLEN];
FF_DEBUG("Found gateway: %s", inet_ntop(AF_INET6, gw, str, sizeof(str)));
}
break;
@@ -407,15 +407,16 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
if (RTA_PAYLOAD(rta) >= sizeof(uint32_t)) {
uint32_t metric = *(uint32_t*) RTA_DATA(rta);
FF_DEBUG("Found metric: %u", metric);
- if (metric >= minMetric) goto next;
+ if (metric >= minMetric) {
+ goto next;
+ }
entry.metric = metric;
}
break;
}
}
- if (entry.ifindex == 0 || entry.metric >= minMetric)
- {
+ if (entry.ifindex == 0 || entry.metric >= minMetric) {
next:
FF_DEBUG("Skipping route: ifindex=%u, metric=%u", entry.ifindex, entry.metric);
continue;
@@ -424,8 +425,7 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
result->ifIndex = entry.ifindex;
FF_DEBUG("Updated best route: ifindex=%u, metric=%u", entry.ifindex, entry.metric);
- if (minMetric == 0)
- {
+ if (minMetric == 0) {
FF_DEBUG("Found zero metric route, stopping further processing");
break; // Stop processing if we found a zero metric route
}
@@ -433,8 +433,7 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
}
exit:
- if (minMetric < UINT32_MAX)
- {
+ if (minMetric < UINT32_MAX) {
if_indextoname(result->ifIndex, result->ifName);
FF_DEBUG("Found default IPv6 route: interface=%s, index=%u, metric=%u", result->ifName, result->ifIndex, minMetric);
return true;
diff --git a/src/common/impl/netif_windows.c b/src/common/impl/netif_windows.c
index a78bbfba0b..702c249e64 100644
--- a/src/common/impl/netif_windows.c
+++ b/src/common/impl/netif_windows.c
@@ -4,29 +4,26 @@
#include // AF_INET6, IN6_IS_ADDR_UNSPECIFIED
#include
-bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
-{
+bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
PMIB_IPFORWARD_TABLE2 pIpForwardTable = NULL;
- if (!NETIO_SUCCESS(GetIpForwardTable2(AF_UNSPEC, &pIpForwardTable)))
+ if (!NETIO_SUCCESS(GetIpForwardTable2(AF_UNSPEC, &pIpForwardTable))) {
return false;
+ }
bool foundDefault = false;
uint32_t smallestMetric = UINT32_MAX;
- for (ULONG i = 0; i < pIpForwardTable->NumEntries; ++i)
- {
+ for (ULONG i = 0; i < pIpForwardTable->NumEntries; ++i) {
MIB_IPFORWARD_ROW2* row = &pIpForwardTable->Table[i];
if (row->DestinationPrefix.PrefixLength == 0 &&
row->DestinationPrefix.Prefix.Ipv4.sin_family == AF_INET &&
- row->DestinationPrefix.Prefix.Ipv4.sin_addr.S_un.S_addr == 0)
- {
+ row->DestinationPrefix.Prefix.Ipv4.sin_addr.S_un.S_addr == 0) {
MIB_IF_ROW2 ifRow = {
.InterfaceIndex = row->InterfaceIndex,
};
- if (NETIO_SUCCESS(GetIfEntry2(&ifRow)) && ifRow.OperStatus == IfOperStatusUp)
- {
+ if (NETIO_SUCCESS(GetIfEntry2(&ifRow)) && ifRow.OperStatus == IfOperStatusUp) {
MIB_IPINTERFACE_ROW ipInterfaceRow = {
.Family = AF_INET,
.InterfaceIndex = row->InterfaceIndex,
@@ -34,11 +31,11 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
uint32_t realMetric = row->Metric /* Metric offset */;
- if (NETIO_SUCCESS(GetIpInterfaceEntry(&ipInterfaceRow)))
+ if (NETIO_SUCCESS(GetIpInterfaceEntry(&ipInterfaceRow))) {
realMetric += ipInterfaceRow.Metric /* Interface metric */;
+ }
- if (realMetric < smallestMetric)
- {
+ if (realMetric < smallestMetric) {
smallestMetric = realMetric;
result->ifIndex = row->InterfaceIndex;
foundDefault = true;
@@ -53,30 +50,26 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
return foundDefault;
}
-
-bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
-{
+bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result) {
PMIB_IPFORWARD_TABLE2 pIpForwardTable = NULL;
- if (!NETIO_SUCCESS(GetIpForwardTable2(AF_UNSPEC, &pIpForwardTable)))
+ if (!NETIO_SUCCESS(GetIpForwardTable2(AF_UNSPEC, &pIpForwardTable))) {
return false;
+ }
bool foundDefault = false;
uint32_t smallestMetric = UINT32_MAX;
- for (ULONG i = 0; i < pIpForwardTable->NumEntries; ++i)
- {
+ for (ULONG i = 0; i < pIpForwardTable->NumEntries; ++i) {
MIB_IPFORWARD_ROW2* row = &pIpForwardTable->Table[i];
if (row->DestinationPrefix.PrefixLength == 0 &&
row->DestinationPrefix.Prefix.Ipv6.sin6_family == AF_INET6 &&
- IN6_IS_ADDR_UNSPECIFIED(&row->DestinationPrefix.Prefix.Ipv6.sin6_addr))
- {
+ IN6_IS_ADDR_UNSPECIFIED(&row->DestinationPrefix.Prefix.Ipv6.sin6_addr)) {
MIB_IF_ROW2 ifRow = {
.InterfaceIndex = row->InterfaceIndex,
};
- if (NETIO_SUCCESS(GetIfEntry2(&ifRow)) && ifRow.OperStatus == IfOperStatusUp)
- {
+ if (NETIO_SUCCESS(GetIfEntry2(&ifRow)) && ifRow.OperStatus == IfOperStatusUp) {
MIB_IPINTERFACE_ROW ipInterfaceRow = {
.Family = AF_INET6,
.InterfaceIndex = row->InterfaceIndex,
@@ -84,11 +77,11 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
uint32_t realMetric = row->Metric /* Metric offset */;
- if (NETIO_SUCCESS(GetIpInterfaceEntry(&ipInterfaceRow)))
+ if (NETIO_SUCCESS(GetIpInterfaceEntry(&ipInterfaceRow))) {
realMetric += ipInterfaceRow.Metric /* Interface metric */;
+ }
- if (realMetric < smallestMetric)
- {
+ if (realMetric < smallestMetric) {
smallestMetric = realMetric;
result->ifIndex = row->InterfaceIndex;
foundDefault = true;
diff --git a/src/common/impl/networking_common.c b/src/common/impl/networking_common.c
index 939f2e6276..ac0930756d 100644
--- a/src/common/impl/networking_common.c
+++ b/src/common/impl/networking_common.c
@@ -5,10 +5,9 @@
#include "common/debug.h"
#ifdef FF_HAVE_ZLIB
-#include
+ #include
-struct FFZlibLibrary
-{
+struct FFZlibLibrary {
FF_LIBRARY_SYMBOL(inflateInit2_)
FF_LIBRARY_SYMBOL(inflate)
FF_LIBRARY_SYMBOL(inflateEnd)
@@ -16,18 +15,17 @@ struct FFZlibLibrary
bool inited;
} zlibData;
-const char* ffNetworkingLoadZlibLibrary(void)
-{
- if (!zlibData.inited)
- {
+const char* ffNetworkingLoadZlibLibrary(void) {
+ if (!zlibData.inited) {
zlibData.inited = true;
FF_LIBRARY_LOAD_MESSAGE(zlib,
- #ifdef _WIN32
- "zlib1"
- #else
- "libz"
- #endif
- FF_LIBRARY_EXTENSION, 2)
+ #ifdef _WIN32
+ "zlib1"
+ #else
+ "libz"
+ #endif
+ FF_LIBRARY_EXTENSION,
+ 2)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(zlib, zlibData, inflateInit2_)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(zlib, zlibData, inflate)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(zlib, zlibData, inflateEnd)
@@ -37,16 +35,16 @@ const char* ffNetworkingLoadZlibLibrary(void)
}
// Try to pre-read gzip header to determine uncompressed size
-static uint32_t guessGzipOutputSize(const void* data, uint32_t dataSize)
-{
+static uint32_t guessGzipOutputSize(const void* data, uint32_t dataSize) {
// gzip file format: http://www.zlib.org/rfc-gzip.html
- if (dataSize < 10 || ((const uint8_t*)data)[0] != 0x1f || ((const uint8_t*)data)[1] != 0x8b)
+ if (dataSize < 10 || ((const uint8_t*) data)[0] != 0x1f || ((const uint8_t*) data)[1] != 0x8b) {
return 0;
+ }
// Uncompressed size in gzip format is stored in the last 4 bytes, but only valid if data is less than 4GB
if (dataSize > 18) {
// Get ISIZE value from the end of file (little endian)
- const uint8_t* tail = (const uint8_t*)data + dataSize - 4;
+ const uint8_t* tail = (const uint8_t*) data + dataSize - 4;
uint32_t uncompressedSize = (uint32_t) tail[0] | ((uint32_t) tail[1] << 8u) | ((uint32_t) tail[2] << 16u) | ((uint32_t) tail[3] << 24u);
// For valid gzip files, this value is the length of the uncompressed data modulo 2^32
@@ -65,8 +63,7 @@ static uint32_t guessGzipOutputSize(const void* data, uint32_t dataSize)
}
// Decompress gzip content
-bool ffNetworkingDecompressGzip(FFstrbuf* buffer, char* headerEnd)
-{
+bool ffNetworkingDecompressGzip(FFstrbuf* buffer, char* headerEnd) {
assert(headerEnd != NULL && *headerEnd == '\r');
// Calculate header size
@@ -96,7 +93,7 @@ bool ffNetworkingDecompressGzip(FFstrbuf* buffer, char* headerEnd)
uint32_t compressedSize = buffer->length - headerSize - 4;
// Check if content is actually in gzip format (gzip header magic is 0x1f 0x8b)
- if (compressedSize < 2 || (uint8_t)bodyStart[0] != 0x1f || (uint8_t)bodyStart[1] != 0x8b) {
+ if (compressedSize < 2 || (uint8_t) bodyStart[0] != 0x1f || (uint8_t) bodyStart[1] != 0x8b) {
FF_DEBUG("Content is not valid gzip format, skipping decompression");
return false;
}
@@ -113,14 +110,14 @@ bool ffNetworkingDecompressGzip(FFstrbuf* buffer, char* headerEnd)
.zalloc = Z_NULL,
.zfree = Z_NULL,
.opaque = Z_NULL,
- .avail_in = (uInt)compressedSize,
- .next_in = (Bytef*)bodyStart,
- .avail_out = (uInt)ffStrbufGetFree(&decompressedBuffer),
- .next_out = (Bytef*)decompressedBuffer.chars,
+ .avail_in = (uInt) compressedSize,
+ .next_in = (Bytef*) bodyStart,
+ .avail_out = (uInt) ffStrbufGetFree(&decompressedBuffer),
+ .next_out = (Bytef*) decompressedBuffer.chars,
};
// Initialize decompression engine
- if (zlibData.ffinflateInit2_(&zs, 16 + MAX_WBITS, ZLIB_VERSION, (int)sizeof(z_stream)) != Z_OK) {
+ if (zlibData.ffinflateInit2_(&zs, 16 + MAX_WBITS, ZLIB_VERSION, (int) sizeof(z_stream)) != Z_OK) {
FF_DEBUG("Failed to initialize decompression engine");
return false;
}
@@ -130,20 +127,19 @@ bool ffNetworkingDecompressGzip(FFstrbuf* buffer, char* headerEnd)
int result = zlibData.ffinflate(&zs, Z_FINISH);
// If output buffer is insufficient, try to extend buffer
- while (result == Z_BUF_ERROR || (result != Z_STREAM_END && zs.avail_out == 0))
- {
+ while (result == Z_BUF_ERROR || (result != Z_STREAM_END && zs.avail_out == 0)) {
FF_DEBUG("Output buffer insufficient, trying to extend");
// Save already decompressed data amount
- uint32_t alreadyDecompressed = (uint32_t)(availableOut - zs.avail_out);
+ uint32_t alreadyDecompressed = (uint32_t) (availableOut - zs.avail_out);
decompressedBuffer.length += alreadyDecompressed;
decompressedBuffer.chars[decompressedBuffer.length] = '\0';
ffStrbufEnsureFree(&decompressedBuffer, decompressedBuffer.length / 2);
// Set output parameters to point to new buffer
- zs.avail_out = (uInt)ffStrbufGetFree(&decompressedBuffer);
- zs.next_out = (Bytef*)(decompressedBuffer.chars + decompressedBuffer.length);
+ zs.avail_out = (uInt) ffStrbufGetFree(&decompressedBuffer);
+ zs.next_out = (Bytef*) (decompressedBuffer.chars + decompressedBuffer.length);
availableOut = zs.avail_out;
// Decompress again
@@ -153,7 +149,7 @@ bool ffNetworkingDecompressGzip(FFstrbuf* buffer, char* headerEnd)
zlibData.ffinflateEnd(&zs);
// Calculate decompressed size
- uint32_t decompressedSize = (uint32_t)(availableOut - zs.avail_out);
+ uint32_t decompressedSize = (uint32_t) (availableOut - zs.avail_out);
decompressedBuffer.length += decompressedSize;
decompressedBuffer.chars[decompressedBuffer.length] = '\0';
FF_DEBUG("Successfully decompressed %u bytes compressed data to %u bytes", compressedSize, decompressedBuffer.length);
@@ -163,19 +159,13 @@ bool ffNetworkingDecompressGzip(FFstrbuf* buffer, char* headerEnd)
char* line = NULL;
size_t len = 0;
- while (ffStrbufGetline(&line, &len, buffer))
- {
- if (ffStrStartsWithIgnCase(line, "Content-Encoding:"))
- {
+ while (ffStrbufGetline(&line, &len, buffer)) {
+ if (ffStrStartsWithIgnCase(line, "Content-Encoding:")) {
continue;
- }
- else if (ffStrStartsWithIgnCase(line, "Content-Length:"))
- {
+ } else if (ffStrStartsWithIgnCase(line, "Content-Length:")) {
ffStrbufAppendF(&newBuffer, "Content-Length: %u\r\n", decompressedBuffer.length);
continue;
- }
- else if (line[0] == '\r')
- {
+ } else if (line[0] == '\r') {
ffStrbufAppendS(&newBuffer, "\r\n");
ffStrbufGetlineRestore(&line, &len, buffer);
break;
diff --git a/src/common/impl/networking_linux.c b/src/common/impl/networking_linux.c
index cd9ab16eff..f63bc47aa3 100644
--- a/src/common/impl/networking_linux.c
+++ b/src/common/impl/networking_linux.c
@@ -16,132 +16,137 @@
#include
#include
-static const char* tryNonThreadingFastPath(FFNetworkingState* state)
-{
- #if defined(TCP_FASTOPEN) || __APPLE__
-
- if (!state->tfo)
- {
- #if __linux__ || __GNU__
- // Linux doesn't support sendto() on unconnected sockets
- FF_DEBUG("TCP Fast Open disabled, skipping");
- return "TCP Fast Open disabled";
- #endif
- }
- else
- {
- FF_DEBUG("Attempting to use TCP Fast Open to connect");
-
- #ifndef __APPLE__ // On macOS, TCP_FASTOPEN doesn't seem to be needed
- // Set TCP Fast Open
- int flag = 1;
- if (setsockopt(state->sockfd, IPPROTO_TCP,
- #ifdef __APPLE__
+static const char* tryNonThreadingFastPath(FFNetworkingState* state) {
+#if defined(TCP_FASTOPEN) || __APPLE__
+
+ if (!state->tfo) {
+ #if __linux__ || __GNU__
+ // Linux doesn't support sendto() on unconnected sockets
+ FF_DEBUG("TCP Fast Open disabled, skipping");
+ return "TCP Fast Open disabled";
+ #endif
+ } else {
+ FF_DEBUG("Attempting to use TCP Fast Open to connect");
+
+ #ifndef __APPLE__ // On macOS, TCP_FASTOPEN doesn't seem to be needed
+ // Set TCP Fast Open
+ int flag = 1;
+ if (setsockopt(state->sockfd, IPPROTO_TCP,
+ #ifdef __APPLE__
// https://github.com/rust-lang/libc/pull/3135
0x218 // TCP_FASTOPEN_FORCE_ENABLE
- #else
+ #else
TCP_FASTOPEN
- #endif
- , &flag, sizeof(flag)) != 0) {
- FF_DEBUG("Failed to set TCP_FASTOPEN option: %s", strerror(errno));
- return "setsockopt(TCP_FASTOPEN) failed";
- } else {
- #if __linux__ || __GNU__
- FF_DEBUG("Successfully set TCP_FASTOPEN option, queue length: %d", flag);
- #elif defined(__APPLE__)
- FF_DEBUG("Successfully set TCP_FASTOPEN_FORCE_ENABLE option");
- #else
- FF_DEBUG("Successfully set TCP_FASTOPEN option");
- #endif
- }
- #endif
- }
-
- #ifndef __APPLE__
- FF_DEBUG("Using sendto() + MSG_DONTWAIT to send %u bytes of data", state->command.length);
- ssize_t sent = sendto(state->sockfd,
- state->command.chars,
- state->command.length,
- #ifdef MSG_FASTOPEN
- MSG_FASTOPEN |
- #endif
- #ifdef MSG_NOSIGNAL
- MSG_NOSIGNAL |
- #endif
- MSG_DONTWAIT,
- state->addr->ai_addr,
- state->addr->ai_addrlen);
+ #endif
+ ,
+ &flag,
+ sizeof(flag)) != 0) {
+ FF_DEBUG("Failed to set TCP_FASTOPEN option: %s", strerror(errno));
+ return "setsockopt(TCP_FASTOPEN) failed";
+ } else {
+ #if __linux__ || __GNU__
+ FF_DEBUG("Successfully set TCP_FASTOPEN option, queue length: %d", flag);
+ #elif defined(__APPLE__)
+ FF_DEBUG("Successfully set TCP_FASTOPEN_FORCE_ENABLE option");
#else
- if (fcntl(state->sockfd, F_SETFL, O_NONBLOCK) == -1) {
- FF_DEBUG("fcntl(F_SETFL) failed: %s", strerror(errno));
- return "fcntl(F_SETFL) failed";
+ FF_DEBUG("Successfully set TCP_FASTOPEN option");
+ #endif
}
- FF_DEBUG("Using connectx() to send %u bytes of data", state->command.length);
- // Use connectx to establish connection and send data in one call
- size_t sent;
- if (connectx(state->sockfd,
+ #endif
+ }
+
+ #ifndef __APPLE__
+ FF_DEBUG("Using sendto() + MSG_DONTWAIT to send %u bytes of data", state->command.length);
+ ssize_t sent = sendto(state->sockfd,
+ state->command.chars,
+ state->command.length,
+ #ifdef MSG_FASTOPEN
+ MSG_FASTOPEN |
+ #endif
+ #ifdef MSG_NOSIGNAL
+ MSG_NOSIGNAL |
+ #endif
+ MSG_DONTWAIT,
+ state->addr->ai_addr,
+ state->addr->ai_addrlen);
+ #else
+ if (fcntl(state->sockfd, F_SETFL, O_NONBLOCK) == -1) {
+ FF_DEBUG("fcntl(F_SETFL) failed: %s", strerror(errno));
+ return "fcntl(F_SETFL) failed";
+ }
+ FF_DEBUG("Using connectx() to send %u bytes of data", state->command.length);
+ // Use connectx to establish connection and send data in one call
+ size_t sent;
+ if (connectx(state->sockfd,
&(sa_endpoints_t) {
.sae_dstaddr = state->addr->ai_addr,
.sae_dstaddrlen = state->addr->ai_addrlen,
},
- SAE_ASSOCID_ANY, state->tfo ? CONNECT_DATA_IDEMPOTENT : 0,
+ SAE_ASSOCID_ANY,
+ state->tfo ? CONNECT_DATA_IDEMPOTENT : 0,
&(struct iovec) {
.iov_base = state->command.chars,
.iov_len = state->command.length,
- }, 1, &sent, NULL) != 0) sent = 0;
- if (fcntl(state->sockfd, F_SETFL, 0) == -1) {
- FF_DEBUG("fcntl(F_SETFL) failed: %s", strerror(errno));
- return "fcntl(F_SETFL) failed";
- }
- #endif
- if (sent > 0 || (errno == EAGAIN || errno == EWOULDBLOCK
- #ifdef __APPLE__
- // On macOS EINPROGRESS means the connection cannot be completed immediately
- // On Linux, it means the TFO cookie is not available locally
- || errno == EINPROGRESS
- #endif
- ))
- {
- FF_DEBUG(
- #ifdef __APPLE__
- "connectx()"
- #else
- "sendto()"
- #endif
- " %s (sent=%zd, %s)", errno == 0 ? "succeeded" : "was in progress", sent, strerror(errno));
- freeaddrinfo(state->addr);
- state->addr = NULL;
- ffStrbufDestroy(&state->command);
- return NULL;
- }
-
+ },
+ 1,
+ &sent,
+ NULL) != 0) {
+ sent = 0;
+ }
+ if (fcntl(state->sockfd, F_SETFL, 0) == -1) {
+ FF_DEBUG("fcntl(F_SETFL) failed: %s", strerror(errno));
+ return "fcntl(F_SETFL) failed";
+ }
+ #endif
+ if (sent > 0 || (errno == EAGAIN || errno == EWOULDBLOCK
+ #ifdef __APPLE__
+ // On macOS EINPROGRESS means the connection cannot be completed immediately
+ // On Linux, it means the TFO cookie is not available locally
+ || errno == EINPROGRESS
+ #endif
+ )) {
FF_DEBUG(
- #ifdef __APPLE__
+ #ifdef __APPLE__
"connectx()"
- #else
+ #else
"sendto()"
- #endif
- " failed: %s", strerror(errno));
- #ifdef __APPLE__
- return "connectx() failed";
- #else
- return "sendto() failed";
- #endif
+ #endif
+ " %s (sent=%zd, %s)",
+ errno == 0 ? "succeeded" : "was in progress",
+ sent,
+ strerror(errno));
+ freeaddrinfo(state->addr);
+ state->addr = NULL;
+ ffStrbufDestroy(&state->command);
+ return NULL;
+ }
+
+ FF_DEBUG(
+ #ifdef __APPLE__
+ "connectx()"
+ #else
+ "sendto()"
+ #endif
+ " failed: %s",
+ strerror(errno));
+ #ifdef __APPLE__
+ return "connectx() failed";
#else
- FF_UNUSED(state);
- return "TFO support is not available";
+ return "sendto() failed";
#endif
+#else
+ FF_UNUSED(state);
+ return "TFO support is not available";
+#endif
}
// Traditional connect and send function
-static const char* connectAndSend(FFNetworkingState* state)
-{
+static const char* connectAndSend(FFNetworkingState* state) {
const char* ret = NULL;
FF_DEBUG("Using traditional connection method to connect");
FF_DEBUG("Attempting connect() to server...");
- if(connect(state->sockfd, state->addr->ai_addr, state->addr->ai_addrlen) == -1)
- {
+ if (connect(state->sockfd, state->addr->ai_addr, state->addr->ai_addrlen) == -1) {
FF_DEBUG("connect() failed: %s", strerror(errno));
ret = "connect() failed";
goto error;
@@ -149,8 +154,7 @@ static const char* connectAndSend(FFNetworkingState* state)
FF_DEBUG("connect() succeeded");
FF_DEBUG("Attempting to send %u bytes of data...", state->command.length);
- if(send(state->sockfd, state->command.chars, state->command.length, 0) < 0)
- {
+ if (send(state->sockfd, state->command.chars, state->command.length, 0) < 0) {
FF_DEBUG("send() failed: %s", strerror(errno));
ret = "send() failed";
goto error;
@@ -176,8 +180,7 @@ static const char* connectAndSend(FFNetworkingState* state)
FF_THREAD_ENTRY_DECL_WRAPPER(connectAndSend, FFNetworkingState*);
// Parallel DNS resolution and socket creation
-static const char* initNetworkingState(FFNetworkingState* state, const char* host, const char* path, const char* headers)
-{
+static const char* initNetworkingState(FFNetworkingState* state, const char* host, const char* path, const char* headers) {
FF_DEBUG("Initializing network connection state: host=%s, path=%s", host, path);
// Initialize command and host information
@@ -197,10 +200,10 @@ static const char* initNetworkingState(FFNetworkingState* state, const char* hos
ffStrbufAppendS(&state->command, headers);
ffStrbufAppendS(&state->command, "\r\n");
- #ifdef FF_HAVE_THREADS
+#ifdef FF_HAVE_THREADS
state->thread = 0;
FF_DEBUG("Thread ID initialized to 0");
- #endif
+#endif
const char* ret = NULL;
@@ -214,8 +217,7 @@ static const char* initNetworkingState(FFNetworkingState* state, const char* hos
// Use AI_NUMERICSERV flag to indicate the service is a numeric port, reducing parsing time
int gaiRes = getaddrinfo(host, "80", &hints, &state->addr);
- if(gaiRes != 0)
- {
+ if (gaiRes != 0) {
FF_DEBUG("getaddrinfo() failed: %s (res=%d)", gai_strerror(gaiRes), gaiRes);
ret = "getaddrinfo() failed";
goto error;
@@ -224,8 +226,7 @@ static const char* initNetworkingState(FFNetworkingState* state, const char* hos
FF_DEBUG("Creating socket");
state->sockfd = socket(state->addr->ai_family, state->addr->ai_socktype, state->addr->ai_protocol);
- if(state->sockfd == -1)
- {
+ if (state->sockfd == -1) {
FF_DEBUG("socket() failed: %s", strerror(errno));
ret = "socket() failed";
goto error;
@@ -233,57 +234,56 @@ static const char* initNetworkingState(FFNetworkingState* state, const char* hos
FF_DEBUG("Socket creation successful: fd=%d", state->sockfd);
int flag = 1;
- #ifdef TCP_NODELAY
+#ifdef TCP_NODELAY
// Disable Nagle's algorithm to reduce small packet transmission delay
if (setsockopt(state->sockfd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag)) != 0) {
FF_DEBUG("Failed to set TCP_NODELAY: %s", strerror(errno));
} else {
FF_DEBUG("Successfully disabled Nagle's algorithm");
}
- #endif
+#endif
- #ifdef TCP_QUICKACK
+#ifdef TCP_QUICKACK
// Set TCP_QUICKACK option to avoid delayed acknowledgments
if (setsockopt(state->sockfd, IPPROTO_TCP, TCP_QUICKACK, &flag, sizeof(flag)) != 0) {
FF_DEBUG("Failed to set TCP_QUICKACK: %s", strerror(errno));
} else {
FF_DEBUG("Successfully enabled TCP quick acknowledgment");
}
- #endif
+#endif
- if (state->timeout > 0)
- {
+ if (state->timeout > 0) {
FF_DEBUG("Setting connection timeout: %u ms", state->timeout);
- FF_MAYBE_UNUSED uint32_t sec = state->timeout / 1000;
- if (sec == 0) sec = 1;
+ FF_A_UNUSED uint32_t sec = state->timeout / 1000;
+ if (sec == 0) {
+ sec = 1;
+ }
- #ifdef TCP_CONNECTIONTIMEOUT
+#ifdef TCP_CONNECTIONTIMEOUT
FF_DEBUG("Using TCP_CONNECTIONTIMEOUT: %u seconds", sec);
setsockopt(state->sockfd, IPPROTO_TCP, TCP_CONNECTIONTIMEOUT, &sec, sizeof(sec));
- #elif defined(TCP_KEEPINIT)
+#elif defined(TCP_KEEPINIT)
FF_DEBUG("Using TCP_KEEPINIT: %u seconds", sec);
setsockopt(state->sockfd, IPPROTO_TCP, TCP_KEEPINIT, &sec, sizeof(sec));
- #elif defined(TCP_USER_TIMEOUT)
+#elif defined(TCP_USER_TIMEOUT)
FF_DEBUG("Using TCP_USER_TIMEOUT: %u milliseconds", state->timeout);
setsockopt(state->sockfd, IPPROTO_TCP, TCP_USER_TIMEOUT, &state->timeout, sizeof(state->timeout));
- #else
+#else
FF_DEBUG("Current platform does not support TCP connection timeout");
- #endif
+#endif
}
return NULL;
error:
FF_DEBUG("Error occurred during initialization");
- if (state->addr != NULL)
- {
+ if (state->addr != NULL) {
FF_DEBUG("Releasing address information");
freeaddrinfo(state->addr);
state->addr = NULL;
}
- if (state->sockfd > 0)
- {
+ if (state->sockfd > 0) {
FF_DEBUG("Closing socket: fd=%d", state->sockfd);
close(state->sockfd);
state->sockfd = -1;
@@ -291,31 +291,26 @@ static const char* initNetworkingState(FFNetworkingState* state, const char* hos
return ret;
}
-const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers)
-{
+const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers) {
FF_DEBUG("Preparing to send HTTP request: host=%s, path=%s", host, path);
- if (state->compression)
- {
+ if (state->compression) {
FF_DEBUG("Compression enabled, checking if zlib is available");
- #ifdef FF_HAVE_ZLIB
+#ifdef FF_HAVE_ZLIB
const char* zlibError = ffNetworkingLoadZlibLibrary();
// Only enable compression if zlib library is successfully loaded
- if (zlibError == NULL)
- {
+ if (zlibError == NULL) {
FF_DEBUG("Successfully loaded zlib library, compression enabled");
} else {
FF_DEBUG("Failed to load zlib library, compression disabled: %s", zlibError);
state->compression = false;
}
- #else
+#else
FF_DEBUG("zlib not supported at build time, compression disabled");
state->compression = false;
- #endif
- }
- else
- {
+#endif
+ } else {
FF_DEBUG("Compression disabled");
}
@@ -333,33 +328,30 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
}
FF_DEBUG("TryNonThreadingFastPath() failed: %s, trying traditional connection", tfoResult);
- #ifdef FF_HAVE_THREADS
- if (instance.config.general.multithreading)
- {
+#ifdef FF_HAVE_THREADS
+ if (instance.config.general.multithreading) {
FF_DEBUG("Multithreading mode enabled, creating connection thread");
state->thread = ffThreadCreate(connectAndSendThreadMain, state);
if (state->thread) {
- FF_DEBUG("Thread creation successful: thread=%p", (void*)(uintptr_t)state->thread);
+ FF_DEBUG("Thread creation successful: thread=%p", (void*) (uintptr_t) state->thread);
return NULL;
}
FF_DEBUG("Thread creation failed");
} else {
FF_DEBUG("Multithreading mode disabled, connecting in main thread");
}
- #endif
+#endif
return connectAndSend(state);
}
-const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer)
-{
+const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer) {
assert(buffer->allocated > 0);
FF_DEBUG("Preparing to receive HTTP response");
uint32_t timeout = state->timeout;
- #ifdef FF_HAVE_THREADS
- if (state->thread)
- {
+#ifdef FF_HAVE_THREADS
+ if (state->thread) {
FF_DEBUG("Connection thread is running, waiting for it to complete (timeout=%u ms)", timeout);
if (!ffThreadJoin(state->thread, timeout)) {
FF_DEBUG("Thread join failed or timed out");
@@ -368,10 +360,9 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
FF_DEBUG("Thread completed successfully");
state->thread = 0;
}
- #endif
+#endif
- if(state->sockfd == -1)
- {
+ if (state->sockfd == -1) {
FF_DEBUG("Invalid socket, HTTP request might have failed");
return "ffNetworkingSendHttpRequest() failed";
}
@@ -380,24 +371,22 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
int rcvbuf = 65536; // 64KB
setsockopt(state->sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
- #ifdef __APPLE__
+#ifdef __APPLE__
// poll for the socket to be readable.
// Because of the non-blocking connectx() call, the connection might not be established yet
FF_DEBUG("Using poll() to check if socket is readable");
{
int pollRes = poll(&(struct pollfd) {
- .fd = state->sockfd,
- .events = POLLIN
- }, 1, timeout > 0 ? (int) timeout : -1);
- if (pollRes == 0)
- {
+ .fd = state->sockfd,
+ .events = POLLIN },
+ 1,
+ timeout > 0 ? (int) timeout : -1);
+ if (pollRes == 0) {
FF_DEBUG("poll() timed out after %u ms", timeout);
close(state->sockfd);
state->sockfd = -1;
return "poll() timeout";
- }
- else if (pollRes == -1)
- {
+ } else if (pollRes == -1) {
FF_DEBUG("poll() failed: %s", strerror(errno));
close(state->sockfd);
state->sockfd = -1;
@@ -405,31 +394,31 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
}
}
FF_DEBUG("Socket is readable, proceeding to receive data");
- #else
- if(timeout > 0)
- {
+#else
+ if (timeout > 0) {
FF_DEBUG("Setting receive timeout: %u ms", timeout);
struct timeval timev;
timev.tv_sec = timeout / 1000;
- timev.tv_usec = (__typeof__(timev.tv_usec)) ((timeout % 1000) * 1000); //milliseconds to microseconds
+ timev.tv_usec = (__typeof__(timev.tv_usec)) ((timeout % 1000) * 1000); // milliseconds to microseconds
setsockopt(state->sockfd, SOL_SOCKET, SO_RCVTIMEO, &timev, sizeof(timev));
}
- #endif
+#endif
- if (shutdown(state->sockfd, SHUT_WR) == -1)
- {
+ if (shutdown(state->sockfd, SHUT_WR) == -1) {
FF_DEBUG("Failed to shutdown socket send: %s", strerror(errno));
// Not a critical error, continue anyway
}
FF_DEBUG("Starting data reception");
- FF_MAYBE_UNUSED int recvCount = 0;
+ FF_A_UNUSED int recvCount = 0;
uint32_t contentLength = 0;
uint32_t headerEnd = 0;
do {
FF_DEBUG("Data reception loop #%d, current buffer size: %u, available space: %u",
- ++recvCount, buffer->length, ffStrbufGetFree(buffer));
+ ++recvCount,
+ buffer->length,
+ ffStrbufGetFree(buffer));
// We set `Connection: close`, so the server will close the connection when done.
// Thus we can use MSG_WAITALL to wait until the buffer is full or the connection is closed.
@@ -453,7 +442,7 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
if (headerEnd == 0) {
char* pHeaderEnd = memmem(buffer->chars, buffer->length, "\r\n\r\n", 4);
if (pHeaderEnd) {
- headerEnd = (uint32_t)(pHeaderEnd - buffer->chars);
+ headerEnd = (uint32_t) (pHeaderEnd - buffer->chars);
FF_DEBUG("Found HTTP header end marker, position: %u", headerEnd);
// Check for Content-Length header to pre-allocate enough memory
@@ -496,8 +485,8 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
return "Invalid response";
}
- // If compression was used, try to decompress
- #ifdef FF_HAVE_ZLIB
+// If compression was used, try to decompress
+#ifdef FF_HAVE_ZLIB
if (state->compression) {
FF_DEBUG("Content received, checking if compressed");
if (!ffNetworkingDecompressGzip(buffer, buffer->chars + headerEnd)) {
@@ -507,7 +496,7 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
FF_DEBUG("Decompression successful or no decompression needed, total length after decompression: %u bytes", buffer->length);
}
}
- #endif
+#endif
return NULL;
}
diff --git a/src/common/impl/networking_windows.c b/src/common/impl/networking_windows.c
index 6200874928..65eaf24454 100644
--- a/src/common/impl/networking_windows.c
+++ b/src/common/impl/networking_windows.c
@@ -1,7 +1,7 @@
#include
#include
-//Must be included after
+// Must be included after
#include "fastfetch.h"
#include "common/networking.h"
#include "common/stringUtils.h"
@@ -9,23 +9,22 @@
static LPFN_CONNECTEX ConnectEx;
-static const char* initWsaData(WSADATA* wsaData)
-{
+static const char* initWsaData(WSADATA* wsaData) {
FF_DEBUG("Initializing WinSock");
- if(WSAStartup(MAKEWORD(2, 2), wsaData) != 0) {
+ if (WSAStartup(MAKEWORD(2, 2), wsaData) != 0) {
FF_DEBUG("WSAStartup() failed");
return "WSAStartup() failed";
}
- if(LOBYTE(wsaData->wVersion) != 2 || HIBYTE(wsaData->wVersion) != 2) {
+ if (LOBYTE(wsaData->wVersion) != 2 || HIBYTE(wsaData->wVersion) != 2) {
FF_DEBUG("Invalid wsaData version found: %d.%d", LOBYTE(wsaData->wVersion), HIBYTE(wsaData->wVersion));
WSACleanup();
return "Invalid wsaData version found";
}
- //Dummy socket needed for WSAIoctl
+ // Dummy socket needed for WSAIoctl
SOCKET sockfd = WSASocketW(AF_INET, SOCK_STREAM, 0, NULL, 0, 0);
- if(sockfd == INVALID_SOCKET) {
+ if (sockfd == INVALID_SOCKET) {
FF_DEBUG("WSASocketW(AF_INET, SOCK_STREAM) failed");
WSACleanup();
return "WSASocketW(AF_INET, SOCK_STREAM) failed";
@@ -33,10 +32,7 @@ static const char* initWsaData(WSADATA* wsaData)
DWORD dwBytes;
GUID guid = WSAID_CONNECTEX;
- if(WSAIoctl(sockfd, SIO_GET_EXTENSION_FUNCTION_POINTER,
- &guid, sizeof(guid),
- &ConnectEx, sizeof(ConnectEx),
- &dwBytes, NULL, NULL) != 0) {
+ if (WSAIoctl(sockfd, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid), &ConnectEx, sizeof(ConnectEx), &dwBytes, NULL, NULL) != 0) {
FF_DEBUG("WSAIoctl(sockfd, SIO_GET_EXTENSION_FUNCTION_POINTER) failed");
closesocket(sockfd);
WSACleanup();
@@ -49,45 +45,36 @@ static const char* initWsaData(WSADATA* wsaData)
return NULL;
}
-const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers)
-{
+const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers) {
FF_DEBUG("Preparing to send HTTP request: host=%s, path=%s", host, path);
- if (state->compression)
- {
- #ifdef FF_HAVE_ZLIB
+ if (state->compression) {
+#ifdef FF_HAVE_ZLIB
const char* zlibError = ffNetworkingLoadZlibLibrary();
// Only enable compression if zlib library is successfully loaded
- if (zlibError == NULL)
- {
+ if (zlibError == NULL) {
FF_DEBUG("Successfully loaded zlib library, compression enabled");
} else {
FF_DEBUG("Failed to load zlib library, compression disabled: %s", zlibError);
state->compression = false;
}
- #else
+#else
FF_DEBUG("zlib not supported at build time, compression disabled");
state->compression = false;
- #endif
- }
- else
- {
+#endif
+ } else {
FF_DEBUG("Compression disabled");
}
static WSADATA wsaData;
- if (wsaData.wVersion == 0)
- {
+ if (wsaData.wVersion == 0) {
const char* error = initWsaData(&wsaData);
- if (error != NULL)
- {
+ if (error != NULL) {
wsaData.wVersion = (WORD) -1;
FF_DEBUG("WinSock initialization failed: %s", error);
return error;
}
- }
- else if (wsaData.wVersion == (WORD) -1)
- {
+ } else if (wsaData.wVersion == (WORD) -1) {
FF_DEBUG("WinSock initialization previously failed");
return "initWsaData() failed before";
}
@@ -100,54 +87,52 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
};
wchar_t hostW[256];
- if (!NT_SUCCESS(RtlUTF8ToUnicodeN(hostW, (ULONG) sizeof(hostW), NULL, host, (ULONG) strlen(host) + 1)))
- {
+ if (!NT_SUCCESS(RtlUTF8ToUnicodeN(hostW, (ULONG) sizeof(hostW), NULL, host, (ULONG) strlen(host) + 1))) {
FF_DEBUG("Failed to convert host to wide string: %s", host);
return "Failed to convert host to wide string";
}
FF_DEBUG("Resolving address: %s (%s)", host, state->ipv6 ? "IPv6" : "IPv4");
- if(GetAddrInfoW(hostW, L"80", &hints, &addr) != 0)
- {
+ if (GetAddrInfoW(hostW, L"80", &hints, &addr) != 0) {
FF_DEBUG("GetAddrInfoW() failed");
return "GetAddrInfoW() failed";
}
state->sockfd = WSASocketW(addr->ai_family, addr->ai_socktype, addr->ai_protocol, NULL, 0, 0);
- if(state->sockfd == INVALID_SOCKET)
- {
+ if (state->sockfd == INVALID_SOCKET) {
FF_DEBUG("WSASocketW() failed");
FreeAddrInfoW(addr);
return "WSASocketW() failed";
}
DWORD flag = 1;
- #ifdef TCP_NODELAY
+#ifdef TCP_NODELAY
// Enable TCP_NODELAY to disable Nagle's algorithm
- if (setsockopt(state->sockfd, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(flag)) != 0) {
+ if (setsockopt(state->sockfd, IPPROTO_TCP, TCP_NODELAY, (char*) &flag, sizeof(flag)) != 0) {
FF_DEBUG("Failed to set TCP_NODELAY: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
} else {
FF_DEBUG("Successfully disabled Nagle's algorithm");
}
- #endif
+#endif
// Set timeout if needed
if (state->timeout > 0) {
FF_DEBUG("Setting connection timeout: %u ms", state->timeout);
- setsockopt(state->sockfd, SOL_SOCKET, SO_SNDTIMEO, (const char*)&state->timeout, sizeof(state->timeout));
- }
-
- //ConnectEx requires the socket to be initially bound
- if((state->ipv6
- ? bind(state->sockfd, (SOCKADDR *) &(struct sockaddr_in6) {
- .sin6_family = AF_INET6,
- .sin6_addr = in6addr_any,
- }, sizeof(struct sockaddr_in6))
- : bind(state->sockfd, (SOCKADDR *) &(struct sockaddr_in) {
- .sin_family = AF_INET,
- .sin_addr.s_addr = INADDR_ANY,
- }, sizeof(struct sockaddr_in))) != 0)
- {
+ setsockopt(state->sockfd, SOL_SOCKET, SO_SNDTIMEO, (const char*) &state->timeout, sizeof(state->timeout));
+ }
+
+ // ConnectEx requires the socket to be initially bound
+ if ((state->ipv6
+ ? bind(state->sockfd, (SOCKADDR*) &(struct sockaddr_in6) {
+ .sin6_family = AF_INET6,
+ .sin6_addr = in6addr_any,
+ },
+ sizeof(struct sockaddr_in6))
+ : bind(state->sockfd, (SOCKADDR*) &(struct sockaddr_in) {
+ .sin_family = AF_INET,
+ .sin_addr.s_addr = INADDR_ANY,
+ },
+ sizeof(struct sockaddr_in))) != 0) {
FF_DEBUG("bind() failed: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
closesocket(state->sockfd);
FreeAddrInfoW(addr);
@@ -156,7 +141,7 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
}
// Initialize overlapped structure with WSA event for asynchronous I/O
- state->overlapped = (OVERLAPPED){
+ state->overlapped = (OVERLAPPED) {
.hEvent = WSACreateEvent()
};
@@ -185,49 +170,39 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
ffStrbufAppendS(&state->command, headers);
ffStrbufAppendS(&state->command, "\r\n");
- #ifdef TCP_FASTOPEN
- if (state->tfo)
- {
+#ifdef TCP_FASTOPEN
+ if (state->tfo) {
// Set TCP Fast Open
flag = 1;
- if (setsockopt(state->sockfd, IPPROTO_TCP, TCP_FASTOPEN, (char*)&flag, sizeof(flag)) != 0) {
+ if (setsockopt(state->sockfd, IPPROTO_TCP, TCP_FASTOPEN, (char*) &flag, sizeof(flag)) != 0) {
FF_DEBUG("Failed to set TCP_FASTOPEN option: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
} else {
FF_DEBUG("Successfully set TCP_FASTOPEN option");
}
- }
- else
- {
+ } else {
FF_DEBUG("TCP Fast Open disabled");
}
- #endif
+#endif
FF_DEBUG("Using ConnectEx to send %u bytes of data", state->command.length);
DWORD sent = 0;
- BOOL result = ConnectEx(state->sockfd, addr->ai_addr, (int)addr->ai_addrlen,
- state->command.chars, state->command.length, &sent, &state->overlapped);
+ BOOL result = ConnectEx(state->sockfd, addr->ai_addr, (int) addr->ai_addrlen, state->command.chars, state->command.length, &sent, &state->overlapped);
FreeAddrInfoW(addr);
addr = NULL;
- if(!result)
- {
- if (WSAGetLastError() != WSA_IO_PENDING)
- {
+ if (!result) {
+ if (WSAGetLastError() != WSA_IO_PENDING) {
FF_DEBUG("ConnectEx() failed: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
WSACloseEvent(state->overlapped.hEvent);
closesocket(state->sockfd);
state->sockfd = INVALID_SOCKET;
ffStrbufDestroy(&state->command);
return "ConnectEx() failed";
- }
- else
- {
+ } else {
FF_DEBUG("ConnectEx() pending");
}
- }
- else
- {
+ } else {
FF_DEBUG("ConnectEx() succeeded, sent %u bytes of data", (unsigned) sent);
}
@@ -235,31 +210,28 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
return NULL;
}
-const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer)
-{
+const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer) {
assert(buffer->allocated > 0);
FF_DEBUG("Preparing to receive HTTP response");
- if (state->sockfd == INVALID_SOCKET)
- {
+ if (state->sockfd == INVALID_SOCKET) {
FF_DEBUG("Invalid socket, HTTP request might have failed");
return "ffNetworkingSendHttpRequest() failed";
}
uint32_t timeout = state->timeout;
- if (timeout > 0)
- {
+ if (timeout > 0) {
FF_DEBUG("WSAWaitForMultipleEvents with timeout: %u ms", timeout);
DWORD result = WSAWaitForMultipleEvents(1, &state->overlapped.hEvent, TRUE, timeout, FALSE);
- if (result != WSA_WAIT_EVENT_0)
- {
+ if (result != WSA_WAIT_EVENT_0) {
if (result == WSA_WAIT_TIMEOUT) {
FF_DEBUG("WSAWaitForMultipleEvents timed out");
} else {
FF_DEBUG("WSAWaitForMultipleEvents failed: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
}
- if (CancelIoEx((HANDLE) state->sockfd, &state->overlapped))
+ if (CancelIoEx((HANDLE) state->sockfd, &state->overlapped)) {
WSAWaitForMultipleEvents(1, &state->overlapped.hEvent, TRUE, 10, TRUE);
+ }
WSACloseEvent(state->overlapped.hEvent);
closesocket(state->sockfd);
ffStrbufDestroy(&state->command);
@@ -268,8 +240,7 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
}
DWORD transfer, flags;
- if (!WSAGetOverlappedResult(state->sockfd, &state->overlapped, &transfer, TRUE, &flags))
- {
+ if (!WSAGetOverlappedResult(state->sockfd, &state->overlapped, &transfer, TRUE, &flags)) {
FF_DEBUG("WSAGetOverlappedResult failed: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
closesocket(state->sockfd);
WSACloseEvent(state->overlapped.hEvent);
@@ -281,46 +252,49 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
WSACloseEvent(state->overlapped.hEvent);
state->overlapped.hEvent = NULL;
- if (setsockopt(state->sockfd, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0) != 0)
- {
+ if (setsockopt(state->sockfd, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0) != 0) {
FF_DEBUG("Failed to update connect context: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
// Not a critical error, continue anyway
}
- if (shutdown(state->sockfd, SD_SEND) == SOCKET_ERROR)
- {
+ if (shutdown(state->sockfd, SD_SEND) == SOCKET_ERROR) {
FF_DEBUG("Failed to shutdown socket send: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
// Not a critical error, continue anyway
}
- if(timeout > 0)
- {
+ if (timeout > 0) {
FF_DEBUG("Setting receive timeout: %u ms", timeout);
- setsockopt(state->sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));
+ setsockopt(state->sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*) &timeout, sizeof(timeout));
}
// Set larger receive buffer for better performance
int rcvbuf = 65536; // 64KB
- if (setsockopt(state->sockfd, SOL_SOCKET, SO_RCVBUF, (const char*)&rcvbuf, sizeof(rcvbuf)))
- {
+ if (setsockopt(state->sockfd, SOL_SOCKET, SO_RCVBUF, (const char*) &rcvbuf, sizeof(rcvbuf))) {
FF_DEBUG("Failed to set SO_RCVBUF: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
// Not a critical error, continue anyway
}
FF_DEBUG("Starting data reception");
- FF_MAYBE_UNUSED int recvCount = 0;
+ FF_A_UNUSED int recvCount = 0;
uint32_t contentLength = 0;
uint32_t headerEnd = 0;
do {
FF_DEBUG("Data reception loop #%d, current buffer size: %u, available space: %u",
- ++recvCount, buffer->length, ffStrbufGetFree(buffer));
+ ++recvCount,
+ buffer->length,
+ ffStrbufGetFree(buffer));
DWORD received = 0, recvFlags = 0;
int recvResult = WSARecv(state->sockfd, &(WSABUF) {
- .buf = buffer->chars + buffer->length,
- .len = (ULONG) ffStrbufGetFree(buffer),
- }, 1, &received, &recvFlags, NULL, NULL);
+ .buf = buffer->chars + buffer->length,
+ .len = (ULONG) ffStrbufGetFree(buffer),
+ },
+ 1,
+ &received,
+ &recvFlags,
+ NULL,
+ NULL);
if (recvResult == SOCKET_ERROR || received == 0) {
if (recvResult == 0 && received == 0) {
@@ -340,7 +314,7 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
if (headerEnd == 0) {
char* pHeaderEnd = strstr(buffer->chars, "\r\n\r\n");
if (pHeaderEnd) {
- headerEnd = (uint32_t)(pHeaderEnd - buffer->chars);
+ headerEnd = (uint32_t) (pHeaderEnd - buffer->chars);
FF_DEBUG("Found HTTP header end marker, position: %u", headerEnd);
// Check for Content-Length header to pre-allocate enough memory
@@ -358,7 +332,7 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
}
} while (ffStrbufGetFree(buffer) > 0);
- FF_DEBUG("Closing socket: fd=%u", (unsigned)state->sockfd);
+ FF_DEBUG("Closing socket: fd=%u", (unsigned) state->sockfd);
closesocket(state->sockfd);
state->sockfd = INVALID_SOCKET;
@@ -378,14 +352,15 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
if (ffStrbufStartsWithS(buffer, "HTTP/1.0 200 OK\r\n")) {
FF_DEBUG("Received valid HTTP 200 response, content length: %u bytes, total length: %u bytes",
- contentLength, buffer->length);
+ contentLength,
+ buffer->length);
} else {
FF_DEBUG("Invalid response: %.40s...", buffer->chars);
return "Invalid response";
}
- // If compression was used, try to decompress
- #ifdef FF_HAVE_ZLIB
+// If compression was used, try to decompress
+#ifdef FF_HAVE_ZLIB
if (state->compression) {
FF_DEBUG("Content received, checking if compressed");
if (!ffNetworkingDecompressGzip(buffer, buffer->chars + headerEnd)) {
@@ -395,7 +370,7 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
FF_DEBUG("Decompression successful or no decompression needed, total length after decompression: %u bytes", buffer->length);
}
}
- #endif
+#endif
return NULL;
}
diff --git a/src/common/impl/option.c b/src/common/impl/option.c
index 63da17ef38..a6dc09673b 100644
--- a/src/common/impl/option.c
+++ b/src/common/impl/option.c
@@ -4,34 +4,35 @@
#include "common/stringUtils.h"
// Return start position of the inner key if the argument key belongs to the module specified, NULL otherwise
-const char* ffOptionTestPrefix(const char* argumentKey, const char* moduleName)
-{
+const char* ffOptionTestPrefix(const char* argumentKey, const char* moduleName) {
const char* subKey = argumentKey;
- if(!(subKey[0] == '-' && subKey[1] == '-'))
+ if (!(subKey[0] == '-' && subKey[1] == '-')) {
return NULL;
+ }
subKey += 2;
- uint32_t moduleNameLen = (uint32_t)strlen(moduleName);
- if(strncasecmp(subKey, moduleName, moduleNameLen) != 0)
+ uint32_t moduleNameLen = (uint32_t) strlen(moduleName);
+ if (strncasecmp(subKey, moduleName, moduleNameLen) != 0) {
return NULL;
+ }
subKey += moduleNameLen;
- if(subKey[0] == '\0')
+ if (subKey[0] == '\0') {
return subKey;
+ }
- if(subKey[0] != '-')
+ if (subKey[0] != '-') {
return NULL;
+ }
subKey += 1;
return subKey;
}
-void ffOptionParseString(const char* argumentKey, const char* value, FFstrbuf* buffer)
-{
- if(value == NULL)
- {
+void ffOptionParseString(const char* argumentKey, const char* value, FFstrbuf* buffer) {
+ if (value == NULL) {
fprintf(stderr, "Error: usage: %s \n", argumentKey);
exit(477);
}
@@ -39,18 +40,15 @@ void ffOptionParseString(const char* argumentKey, const char* value, FFstrbuf* b
ffStrbufSetS(buffer, value);
}
-uint32_t ffOptionParseUInt32(const char* argumentKey, const char* value)
-{
- if(value == NULL)
- {
+uint32_t ffOptionParseUInt32(const char* argumentKey, const char* value) {
+ if (value == NULL) {
fprintf(stderr, "Error: usage: %s \n", argumentKey);
exit(480);
}
char* end;
uint32_t num = (uint32_t) strtoul(value, &end, 10);
- if(*end != '\0')
- {
+ if (*end != '\0') {
fprintf(stderr, "Error: usage: %s \n", argumentKey);
exit(479);
}
@@ -58,18 +56,15 @@ uint32_t ffOptionParseUInt32(const char* argumentKey, const char* value)
return num;
}
-int32_t ffOptionParseInt32(const char* argumentKey, const char* value)
-{
- if(value == NULL)
- {
+int32_t ffOptionParseInt32(const char* argumentKey, const char* value) {
+ if (value == NULL) {
fprintf(stderr, "Error: usage: %s \n", argumentKey);
exit(480);
}
char* end;
int32_t num = (int32_t) strtol(value, &end, 10);
- if(*end != '\0')
- {
+ if (*end != '\0') {
fprintf(stderr, "Error: usage: %s \n", argumentKey);
exit(479);
}
@@ -77,42 +72,38 @@ int32_t ffOptionParseInt32(const char* argumentKey, const char* value)
return num;
}
-int ffOptionParseEnum(const char* argumentKey, const char* requestedKey, FFKeyValuePair pairs[])
-{
- if(requestedKey == NULL)
- {
+int ffOptionParseEnum(const char* argumentKey, const char* requestedKey, FFKeyValuePair pairs[]) {
+ if (requestedKey == NULL) {
fprintf(stderr, "Error: usage: %s \n", argumentKey);
exit(476);
}
- for (const FFKeyValuePair* pPair = pairs; pPair->key; ++pPair)
- {
- if(ffStrEqualsIgnCase(requestedKey, pPair->key))
+ for (const FFKeyValuePair* pPair = pairs; pPair->key; ++pPair) {
+ if (ffStrEqualsIgnCase(requestedKey, pPair->key)) {
return pPair->value;
+ }
}
fprintf(stderr, "Error: unknown %s value: %s\n", argumentKey, requestedKey);
exit(478);
}
-bool ffOptionParseBoolean(const char* str)
-{
+bool ffOptionParseBoolean(const char* str) {
return (
!ffStrSet(str) ||
ffStrEqualsIgnCase(str, "true") ||
- ffStrEqualsIgnCase(str, "yes") ||
- ffStrEqualsIgnCase(str, "on") ||
- ffStrEqualsIgnCase(str, "1")
- );
+ ffStrEqualsIgnCase(str, "yes") ||
+ ffStrEqualsIgnCase(str, "on") ||
+ ffStrEqualsIgnCase(str, "1"));
}
-void ffOptionParseColorNoClear(const char* value, FFstrbuf* buffer)
-{
- if (!value || value[0] == '\0') return;
+void ffOptionParseColorNoClear(const char* value, FFstrbuf* buffer) {
+ if (!value || value[0] == '\0') {
+ return;
+ }
// If value is already an ANSI escape code, use it
- if (value[0] == '\e' && value[1] == '[')
- {
+ if (value[0] == '\e' && value[1] == '[') {
ffStrbufAppendS(buffer, value + 2);
ffStrbufTrimRight(buffer, 'm');
return;
@@ -120,54 +111,28 @@ void ffOptionParseColorNoClear(const char* value, FFstrbuf* buffer)
ffStrbufEnsureFree(buffer, 63);
- while(*value != '\0')
- {
- #define FF_APPEND_COLOR_CODE_COND(prefix, code) \
- if(ffStrStartsWithIgnCase(value, #prefix)) { ffStrbufAppendS(buffer, code); value += strlen(#prefix); continue; }
- #define FF_APPEND_COLOR_PROP_COND(prefix, prop) \
- if(ffStrStartsWithIgnCase(value, #prefix)) { if (instance.config.display.prop.length) ffStrbufAppend(buffer, &instance.config.display.prop); else ffStrbufAppendS(buffer, FF_COLOR_FG_DEFAULT); value += strlen(#prefix); continue; }
+ while (*value != '\0') {
+#define FF_APPEND_COLOR_CODE_COND(prefix, code) \
+ if (ffStrStartsWithIgnCase(value, #prefix)) { \
+ ffStrbufAppendS(buffer, code); \
+ value += strlen(#prefix); \
+ continue; \
+ }
+#define FF_APPEND_COLOR_PROP_COND(prefix, prop) \
+ if (ffStrStartsWithIgnCase(value, #prefix)) { \
+ if (instance.config.display.prop.length) ffStrbufAppend(buffer, &instance.config.display.prop); \
+ else ffStrbufAppendS(buffer, FF_COLOR_FG_DEFAULT); \
+ value += strlen(#prefix); \
+ continue; \
+ }
- if (ffCharIsEnglishAlphabet(value[0]))
- {
+ if (ffCharIsEnglishAlphabet(value[0])) {
FF_APPEND_COLOR_CODE_COND(reset_, FF_COLOR_MODE_RESET)
- else FF_APPEND_COLOR_CODE_COND(bold_, FF_COLOR_MODE_BOLD)
- else FF_APPEND_COLOR_CODE_COND(bright_, FF_COLOR_MODE_BOLD)
- else FF_APPEND_COLOR_CODE_COND(dim_, FF_COLOR_MODE_DIM)
- else FF_APPEND_COLOR_CODE_COND(italic_, FF_COLOR_MODE_ITALIC)
- else FF_APPEND_COLOR_CODE_COND(underline_, FF_COLOR_MODE_UNDERLINE)
- else FF_APPEND_COLOR_CODE_COND(blink_, FF_COLOR_MODE_BLINK)
- else FF_APPEND_COLOR_CODE_COND(inverse_, FF_COLOR_MODE_INVERSE)
- else FF_APPEND_COLOR_CODE_COND(hidden_, FF_COLOR_MODE_HIDDEN)
- else FF_APPEND_COLOR_CODE_COND(strike_, FF_COLOR_MODE_STRIKETHROUGH)
- else FF_APPEND_COLOR_CODE_COND(black, FF_COLOR_FG_BLACK)
- else FF_APPEND_COLOR_CODE_COND(red, FF_COLOR_FG_RED)
- else FF_APPEND_COLOR_CODE_COND(green, FF_COLOR_FG_GREEN)
- else FF_APPEND_COLOR_CODE_COND(yellow, FF_COLOR_FG_YELLOW)
- else FF_APPEND_COLOR_CODE_COND(blue, FF_COLOR_FG_BLUE)
- else FF_APPEND_COLOR_CODE_COND(magenta, FF_COLOR_FG_MAGENTA)
- else FF_APPEND_COLOR_CODE_COND(cyan, FF_COLOR_FG_CYAN)
- else FF_APPEND_COLOR_CODE_COND(white, FF_COLOR_FG_WHITE)
- else FF_APPEND_COLOR_CODE_COND(default, FF_COLOR_FG_DEFAULT)
- else FF_APPEND_COLOR_CODE_COND(light_black, FF_COLOR_FG_LIGHT_BLACK)
- else FF_APPEND_COLOR_CODE_COND(light_red, FF_COLOR_FG_LIGHT_RED)
- else FF_APPEND_COLOR_CODE_COND(light_green, FF_COLOR_FG_LIGHT_GREEN)
- else FF_APPEND_COLOR_CODE_COND(light_yellow, FF_COLOR_FG_LIGHT_YELLOW)
- else FF_APPEND_COLOR_CODE_COND(light_blue, FF_COLOR_FG_LIGHT_BLUE)
- else FF_APPEND_COLOR_CODE_COND(light_magenta, FF_COLOR_FG_LIGHT_MAGENTA)
- else FF_APPEND_COLOR_CODE_COND(light_cyan, FF_COLOR_FG_LIGHT_CYAN)
- else FF_APPEND_COLOR_CODE_COND(light_white, FF_COLOR_FG_LIGHT_WHITE)
- else FF_APPEND_COLOR_PROP_COND(keys, colorKeys)
- else FF_APPEND_COLOR_PROP_COND(title, colorTitle)
- else FF_APPEND_COLOR_PROP_COND(output, colorOutput)
- else FF_APPEND_COLOR_PROP_COND(separator, colorSeparator)
- else
- {
+ else FF_APPEND_COLOR_CODE_COND(bold_, FF_COLOR_MODE_BOLD) else FF_APPEND_COLOR_CODE_COND(bright_, FF_COLOR_MODE_BOLD) else FF_APPEND_COLOR_CODE_COND(dim_, FF_COLOR_MODE_DIM) else FF_APPEND_COLOR_CODE_COND(italic_, FF_COLOR_MODE_ITALIC) else FF_APPEND_COLOR_CODE_COND(underline_, FF_COLOR_MODE_UNDERLINE) else FF_APPEND_COLOR_CODE_COND(blink_, FF_COLOR_MODE_BLINK) else FF_APPEND_COLOR_CODE_COND(inverse_, FF_COLOR_MODE_INVERSE) else FF_APPEND_COLOR_CODE_COND(hidden_, FF_COLOR_MODE_HIDDEN) else FF_APPEND_COLOR_CODE_COND(strike_, FF_COLOR_MODE_STRIKETHROUGH) else FF_APPEND_COLOR_CODE_COND(black, FF_COLOR_FG_BLACK) else FF_APPEND_COLOR_CODE_COND(red, FF_COLOR_FG_RED) else FF_APPEND_COLOR_CODE_COND(green, FF_COLOR_FG_GREEN) else FF_APPEND_COLOR_CODE_COND(yellow, FF_COLOR_FG_YELLOW) else FF_APPEND_COLOR_CODE_COND(blue, FF_COLOR_FG_BLUE) else FF_APPEND_COLOR_CODE_COND(magenta, FF_COLOR_FG_MAGENTA) else FF_APPEND_COLOR_CODE_COND(cyan, FF_COLOR_FG_CYAN) else FF_APPEND_COLOR_CODE_COND(white, FF_COLOR_FG_WHITE) else FF_APPEND_COLOR_CODE_COND(default, FF_COLOR_FG_DEFAULT) else FF_APPEND_COLOR_CODE_COND(light_black, FF_COLOR_FG_LIGHT_BLACK) else FF_APPEND_COLOR_CODE_COND(light_red, FF_COLOR_FG_LIGHT_RED) else FF_APPEND_COLOR_CODE_COND(light_green, FF_COLOR_FG_LIGHT_GREEN) else FF_APPEND_COLOR_CODE_COND(light_yellow, FF_COLOR_FG_LIGHT_YELLOW) else FF_APPEND_COLOR_CODE_COND(light_blue, FF_COLOR_FG_LIGHT_BLUE) else FF_APPEND_COLOR_CODE_COND(light_magenta, FF_COLOR_FG_LIGHT_MAGENTA) else FF_APPEND_COLOR_CODE_COND(light_cyan, FF_COLOR_FG_LIGHT_CYAN) else FF_APPEND_COLOR_CODE_COND(light_white, FF_COLOR_FG_LIGHT_WHITE) else FF_APPEND_COLOR_PROP_COND(keys, colorKeys) else FF_APPEND_COLOR_PROP_COND(title, colorTitle) else FF_APPEND_COLOR_PROP_COND(output, colorOutput) else FF_APPEND_COLOR_PROP_COND(separator, colorSeparator) else {
fprintf(stderr, "Error: invalid color code found: %s\n", value);
exit(479);
}
- }
- else if (value[0] == '@')
- {
+ } else if (value[0] == '@') {
// Xterm 256 color
++value;
char* pend = NULL;
@@ -181,9 +146,7 @@ void ffOptionParseColorNoClear(const char* value, FFstrbuf* buffer)
ffStrbufAppendUInt(buffer, color);
value = pend;
continue;
- }
- else if (value[0] == '#')
- {
+ } else if (value[0] == '#') {
// RGB color
++value;
char* pend = NULL;
@@ -195,13 +158,11 @@ void ffOptionParseColorNoClear(const char* value, FFstrbuf* buffer)
if (pend - value > 6) {
fprintf(stderr, "Error: RGB color code too long: %s\n", value);
exit(479);
- }
- else if (pend - value == 3) {
+ } else if (pend - value == 3) {
rgb = ((rgb & 0xF00) >> 8) * 0x110000 +
- ((rgb & 0x0F0) >> 4) * 0x001100 +
- ((rgb & 0x00F) >> 0) * 0x000011;
- }
- else if (pend - value != 6) {
+ ((rgb & 0x0F0) >> 4) * 0x001100 +
+ ((rgb & 0x00F) >> 0) * 0x000011;
+ } else if (pend - value != 6) {
fprintf(stderr, "Error: invalid RGB color code length: %s\n", value);
exit(479);
}
@@ -214,7 +175,7 @@ void ffOptionParseColorNoClear(const char* value, FFstrbuf* buffer)
ffStrbufAppendC(buffer, *value);
++value;
- #undef FF_APPEND_COLOR_CODE_COND
- #undef FF_APPEND_COLOR_PROP_COND
+#undef FF_APPEND_COLOR_CODE_COND
+#undef FF_APPEND_COLOR_PROP_COND
}
}
diff --git a/src/common/impl/parsing.c b/src/common/impl/parsing.c
index 668a28773b..ad8c41c8d1 100644
--- a/src/common/impl/parsing.c
+++ b/src/common/impl/parsing.c
@@ -8,90 +8,82 @@
#pragma GCC diagnostic ignored "-Wformat"
#endif
-void ffParseSemver(FFstrbuf* buffer, const FFstrbuf* major, const FFstrbuf* minor, const FFstrbuf* patch)
-{
- if(major->length > 0)
+void ffParseSemver(FFstrbuf* buffer, const FFstrbuf* major, const FFstrbuf* minor, const FFstrbuf* patch) {
+ if (major->length > 0) {
ffStrbufAppend(buffer, major);
- else if(minor->length > 0 || patch->length > 0)
+ } else if (minor->length > 0 || patch->length > 0) {
ffStrbufAppendC(buffer, '1');
+ }
- if(minor->length == 0 && patch->length == 0)
+ if (minor->length == 0 && patch->length == 0) {
return;
+ }
ffStrbufAppendC(buffer, '.');
- if(minor->length > 0)
+ if (minor->length > 0) {
ffStrbufAppend(buffer, minor);
- else if(patch->length > 0)
+ } else if (patch->length > 0) {
ffStrbufAppendC(buffer, '0');
+ }
- if(patch->length == 0)
+ if (patch->length == 0) {
return;
+ }
ffStrbufAppendC(buffer, '.');
ffStrbufAppend(buffer, patch);
}
-int8_t ffVersionCompare(const FFVersion* version1, const FFVersion* version2)
-{
- if(version1->major != version2->major)
+int8_t ffVersionCompare(const FFVersion* version1, const FFVersion* version2) {
+ if (version1->major != version2->major) {
return version1->major > version2->major ? 1 : -1;
+ }
- if(version1->minor != version2->minor)
+ if (version1->minor != version2->minor) {
return version1->minor > version2->minor ? 1 : -1;
+ }
- if(version1->patch != version2->patch)
+ if (version1->patch != version2->patch) {
return version1->patch > version2->patch ? 1 : -1;
+ }
return 0;
}
-void ffVersionToPretty(const FFVersion* version, FFstrbuf* pretty)
-{
- if(version->major > 0 || version->minor > 0 || version->patch > 0)
- {
+void ffVersionToPretty(const FFVersion* version, FFstrbuf* pretty) {
+ if (version->major > 0 || version->minor > 0 || version->patch > 0) {
ffStrbufAppendUInt(pretty, version->major);
}
- if(version->minor > 0 || version->patch > 0)
- {
+ if (version->minor > 0 || version->patch > 0) {
ffStrbufAppendC(pretty, '.');
ffStrbufAppendUInt(pretty, version->minor);
}
- if(version->patch > 0)
- {
+ if (version->patch > 0) {
ffStrbufAppendC(pretty, '.');
ffStrbufAppendUInt(pretty, version->patch);
}
}
-void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, const FFstrbuf* gtk4)
-{
- if(gtk2->length > 0 && gtk3->length > 0 && gtk4->length > 0)
- {
- if((ffStrbufIgnCaseEqual(gtk2, gtk3)) && (ffStrbufIgnCaseEqual(gtk2, gtk4)))
- {
+void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, const FFstrbuf* gtk4) {
+ if (gtk2->length > 0 && gtk3->length > 0 && gtk4->length > 0) {
+ if ((ffStrbufIgnCaseEqual(gtk2, gtk3)) && (ffStrbufIgnCaseEqual(gtk2, gtk4))) {
ffStrbufAppend(buffer, gtk4);
ffStrbufAppendS(buffer, " [GTK2/3/4]");
- }
- else if(ffStrbufIgnCaseEqual(gtk2, gtk3))
- {
+ } else if (ffStrbufIgnCaseEqual(gtk2, gtk3)) {
ffStrbufAppend(buffer, gtk3);
ffStrbufAppendS(buffer, " [GTK2/3], ");
ffStrbufAppend(buffer, gtk4);
ffStrbufAppendS(buffer, " [GTK4]");
- }
- else if(ffStrbufIgnCaseEqual(gtk3, gtk4))
- {
+ } else if (ffStrbufIgnCaseEqual(gtk3, gtk4)) {
ffStrbufAppend(buffer, gtk2);
ffStrbufAppendS(buffer, " [GTK2], ");
ffStrbufAppend(buffer, gtk4);
ffStrbufAppendS(buffer, " [GTK3/4]");
- }
- else
- {
+ } else {
ffStrbufAppend(buffer, gtk2);
ffStrbufAppendS(buffer, " [GTK2], ");
ffStrbufAppend(buffer, gtk3);
@@ -99,49 +91,33 @@ void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, co
ffStrbufAppend(buffer, gtk4);
ffStrbufAppendS(buffer, " [GTK4]");
}
- }
- else if(gtk2->length > 0 && gtk3->length > 0)
- {
- if(ffStrbufIgnCaseEqual(gtk2, gtk3))
- {
+ } else if (gtk2->length > 0 && gtk3->length > 0) {
+ if (ffStrbufIgnCaseEqual(gtk2, gtk3)) {
ffStrbufAppend(buffer, gtk3);
ffStrbufAppendS(buffer, " [GTK2/3]");
- }
- else
- {
+ } else {
ffStrbufAppend(buffer, gtk2);
ffStrbufAppendS(buffer, " [GTK2], ");
ffStrbufAppend(buffer, gtk3);
ffStrbufAppendS(buffer, " [GTK3]");
}
- }
- else if(gtk3->length > 0 && gtk4->length > 0)
- {
- if(ffStrbufIgnCaseEqual(gtk3, gtk4))
- {
+ } else if (gtk3->length > 0 && gtk4->length > 0) {
+ if (ffStrbufIgnCaseEqual(gtk3, gtk4)) {
ffStrbufAppend(buffer, gtk4);
ffStrbufAppendS(buffer, " [GTK3/4]");
- }
- else
- {
+ } else {
ffStrbufAppend(buffer, gtk3);
ffStrbufAppendS(buffer, " [GTK3], ");
ffStrbufAppend(buffer, gtk4);
ffStrbufAppendS(buffer, " [GTK4]");
}
- }
- else if(gtk2->length > 0)
- {
+ } else if (gtk2->length > 0) {
ffStrbufAppend(buffer, gtk2);
ffStrbufAppendS(buffer, " [GTK2]");
- }
- else if(gtk3->length > 0)
- {
+ } else if (gtk3->length > 0) {
ffStrbufAppend(buffer, gtk3);
ffStrbufAppendS(buffer, " [GTK3]");
- }
- else if(gtk4->length > 0)
- {
+ } else if (gtk4->length > 0) {
ffStrbufAppend(buffer, gtk4);
ffStrbufAppendS(buffer, " [GTK4]");
}
diff --git a/src/common/impl/path.c b/src/common/impl/path.c
index 2c01d23302..03662502c0 100644
--- a/src/common/impl/path.c
+++ b/src/common/impl/path.c
@@ -3,44 +3,49 @@
#include "common/arrayUtils.h"
#if !_WIN32
-const char* ffFindExecutableInPath(const char* name, FFstrbuf* result)
-{
+const char* ffFindExecutableInPath(const char* name, FFstrbuf* result) {
char* path = getenv("PATH");
- if(!path)
+ if (!path) {
return "$PATH not set";
+ }
#ifdef _WIN32
const bool appendExe = !ffStrEndsWithIgnCase(name, ".exe");
#endif
- for (char* token = path; *token; path = token + 1)
- {
+ for (char* token = path; *token; path = token + 1) {
token = strchr(path,
- #ifdef _WIN32
- ';'
- #else
- ':'
- #endif
+ #ifdef _WIN32
+ ';'
+ #else
+ ':'
+ #endif
);
- if (!token) token = path + strlen(path);
+ if (!token) {
+ token = path + strlen(path);
+ }
- ffStrbufSetNS(result, (uint32_t)(token - path), path);
+ ffStrbufSetNS(result, (uint32_t) (token - path), path);
ffStrbufEnsureEndsWithC(result,
- #ifdef _WIN32
- '\\'
- #else
- '/'
- #endif
+ #ifdef _WIN32
+ '\\'
+ #else
+ '/'
+ #endif
);
ffStrbufAppendS(result, name);
- #ifdef _WIN32
- if (appendExe) ffStrbufAppendS(result, ".exe");
- if (!ffPathExists(result->chars, FF_PATHTYPE_FILE))
+ #ifdef _WIN32
+ if (appendExe) {
+ ffStrbufAppendS(result, ".exe");
+ }
+ if (!ffPathExists(result->chars, FF_PATHTYPE_FILE)) {
continue;
- #else
- if (access(result->chars, X_OK) != 0)
+ }
+ #else
+ if (access(result->chars, X_OK) != 0) {
continue;
- #endif
+ }
+ #endif
return NULL;
}
@@ -48,17 +53,15 @@ const char* ffFindExecutableInPath(const char* name, FFstrbuf* result)
return "Executable not found";
}
#else
-#include
-#include
-#include
-#include
+ #include
+ #include
+ #include
+ #include
-const char* ffFindExecutableInPath(const char* name, FFstrbuf* result)
-{
+const char* ffFindExecutableInPath(const char* name, FFstrbuf* result) {
char buffer[MAX_PATH + 1];
DWORD length = SearchPathA(NULL, name, ".exe", sizeof(buffer), buffer, NULL);
- if (length == 0)
- {
+ if (length == 0) {
ffStrbufClear(result);
return "Executable not found";
}
@@ -66,10 +69,8 @@ const char* ffFindExecutableInPath(const char* name, FFstrbuf* result)
return NULL;
}
-static inline int winerr2Errno(DWORD err)
-{
- switch (err)
- {
+static inline int winerr2Errno(DWORD err) {
+ switch (err) {
case ERROR_FILE_NOT_FOUND:
case ERROR_PATH_NOT_FOUND:
case ERROR_INVALID_NAME:
@@ -89,24 +90,20 @@ static inline int winerr2Errno(DWORD err)
}
}
-char* frealpath(HANDLE hFile, char* resolved_name)
-{
- if (__builtin_expect(hFile == INVALID_HANDLE_VALUE || !hFile, false))
- {
+char* frealpath(HANDLE hFile, char* resolved_name) {
+ if (__builtin_expect(hFile == INVALID_HANDLE_VALUE || !hFile, false)) {
errno = EINVAL;
return NULL;
}
wchar_t resolvedNameW[MAX_PATH + 4]; /* +4 for "\\\\?\\" prefix */
- DWORD lenW = GetFinalPathNameByHandleW(hFile, resolvedNameW, (DWORD)ARRAY_SIZE(resolvedNameW), FILE_NAME_NORMALIZED);
+ DWORD lenW = GetFinalPathNameByHandleW(hFile, resolvedNameW, (DWORD) ARRAY_SIZE(resolvedNameW), FILE_NAME_NORMALIZED);
- if (lenW == 0)
- {
+ if (lenW == 0) {
errno = winerr2Errno(GetLastError());
return NULL;
}
- if (lenW >= ARRAY_SIZE(resolvedNameW))
- {
+ if (lenW >= ARRAY_SIZE(resolvedNameW)) {
errno = E2BIG;
return NULL;
}
@@ -115,51 +112,41 @@ char* frealpath(HANDLE hFile, char* resolved_name)
wchar_t* srcW = resolvedNameW;
DWORD srcLenW = lenW;
- if (srcLenW >= 8 && wcsncmp(resolvedNameW, L"\\\\?\\UNC\\", 8) == 0)
- {
+ if (srcLenW >= 8 && wcsncmp(resolvedNameW, L"\\\\?\\UNC\\", 8) == 0) {
/* Convert "\\?\UNC\server\share" to "\\server\share" */
srcW += 6;
srcLenW -= 6;
*srcW = L'\\';
- }
- else if (srcLenW >= 4 && wcsncmp(resolvedNameW, L"\\\\?\\", 4) == 0)
- {
+ } else if (srcLenW >= 4 && wcsncmp(resolvedNameW, L"\\\\?\\", 4) == 0) {
srcW += 4;
srcLenW -= 4;
}
- if (resolved_name)
- {
+ if (resolved_name) {
ULONG outBytes = 0;
- if (!NT_SUCCESS(RtlUnicodeToUTF8N(resolved_name, MAX_PATH, &outBytes, srcW, (ULONG)(srcLenW * sizeof(wchar_t)))))
- {
+ if (!NT_SUCCESS(RtlUnicodeToUTF8N(resolved_name, MAX_PATH, &outBytes, srcW, (ULONG) (srcLenW * sizeof(wchar_t))))) {
errno = E2BIG;
return NULL;
}
- if (outBytes > MAX_PATH)
- {
+ if (outBytes > MAX_PATH) {
errno = E2BIG;
return NULL;
}
return resolved_name;
- }
- else
- {
+ } else {
/* UTF-8 worst-case: up to 4 bytes per UTF-16 code unit */
char tmp[(MAX_PATH + 4) * 4];
ULONG outBytes = 0;
- if (!NT_SUCCESS(RtlUnicodeToUTF8N(tmp, (ULONG)sizeof(tmp), &outBytes, srcW, (ULONG)(srcLenW * sizeof(wchar_t)))))
- {
+ if (!NT_SUCCESS(RtlUnicodeToUTF8N(tmp, (ULONG) sizeof(tmp), &outBytes, srcW, (ULONG) (srcLenW * sizeof(wchar_t))))) {
errno = E2BIG;
return NULL;
}
- resolved_name = (char*)malloc(outBytes);
- if (!resolved_name)
- {
+ resolved_name = (char*) malloc(outBytes);
+ if (!resolved_name) {
errno = ENOMEM;
return NULL;
}
@@ -171,10 +158,8 @@ char* frealpath(HANDLE hFile, char* resolved_name)
return resolved_name;
}
-char* realpath(const char* __restrict file_name, char* __restrict resolved_name)
-{
- if (!file_name)
- {
+char* realpath(const char* __restrict file_name, char* __restrict resolved_name) {
+ if (!file_name) {
errno = EINVAL;
return NULL;
}
@@ -182,8 +167,7 @@ char* realpath(const char* __restrict file_name, char* __restrict resolved_name)
wchar_t fileNameW[MAX_PATH];
ULONG lenBytes = 0;
- if (!NT_SUCCESS(RtlUTF8ToUnicodeN(fileNameW, (ULONG)sizeof(fileNameW), &lenBytes, file_name, (ULONG)strlen(file_name) + 1)))
- {
+ if (!NT_SUCCESS(RtlUTF8ToUnicodeN(fileNameW, (ULONG) sizeof(fileNameW), &lenBytes, file_name, (ULONG) strlen(file_name) + 1))) {
errno = EINVAL;
return NULL;
}
@@ -197,8 +181,7 @@ char* realpath(const char* __restrict file_name, char* __restrict resolved_name)
FILE_FLAG_BACKUP_SEMANTICS,
NULL);
- if (hFile == INVALID_HANDLE_VALUE)
- {
+ if (hFile == INVALID_HANDLE_VALUE) {
errno = winerr2Errno(GetLastError());
return NULL;
}
@@ -206,18 +189,15 @@ char* realpath(const char* __restrict file_name, char* __restrict resolved_name)
return frealpath(hFile, resolved_name);
}
-ssize_t freadlink(HANDLE hFile, char* buf, size_t bufsiz)
-{
- if (__builtin_expect(hFile == INVALID_HANDLE_VALUE || !buf || bufsiz == 0, false))
- {
+ssize_t freadlink(HANDLE hFile, char* buf, size_t bufsiz) {
+ if (__builtin_expect(hFile == INVALID_HANDLE_VALUE || !buf || bufsiz == 0, false)) {
errno = EINVAL;
return -1;
}
alignas(REPARSE_DATA_BUFFER) BYTE reparseBuf[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
DWORD bytesReturned = 0;
- if (!DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, NULL, 0, reparseBuf, (DWORD) sizeof(reparseBuf), &bytesReturned, NULL))
- {
+ if (!DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, NULL, 0, reparseBuf, (DWORD) sizeof(reparseBuf), &bytesReturned, NULL)) {
errno = winerr2Errno(GetLastError());
return -1;
}
@@ -226,59 +206,45 @@ ssize_t freadlink(HANDLE hFile, char* buf, size_t bufsiz)
const wchar_t* targetW = NULL;
USHORT targetBytes = 0;
- if (rp->ReparseTag == IO_REPARSE_TAG_SYMLINK)
- {
- if (rp->SymbolicLinkReparseBuffer.PrintNameLength > 0)
- {
+ if (rp->ReparseTag == IO_REPARSE_TAG_SYMLINK) {
+ if (rp->SymbolicLinkReparseBuffer.PrintNameLength > 0) {
targetW = rp->SymbolicLinkReparseBuffer.PathBuffer +
(rp->SymbolicLinkReparseBuffer.PrintNameOffset / sizeof(wchar_t));
targetBytes = rp->SymbolicLinkReparseBuffer.PrintNameLength;
- }
- else
- {
+ } else {
targetW = rp->SymbolicLinkReparseBuffer.PathBuffer +
(rp->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(wchar_t));
targetBytes = rp->SymbolicLinkReparseBuffer.SubstituteNameLength;
if (targetBytes >= 8 &&
- wcsncmp(targetW, L"\\??\\", 4) == 0)
- {
+ wcsncmp(targetW, L"\\??\\", 4) == 0) {
targetW += 4;
targetBytes -= 8;
}
}
- }
- else if (rp->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
- {
- if (rp->MountPointReparseBuffer.PrintNameLength > 0)
- {
+ } else if (rp->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) {
+ if (rp->MountPointReparseBuffer.PrintNameLength > 0) {
targetW = rp->MountPointReparseBuffer.PathBuffer +
(rp->MountPointReparseBuffer.PrintNameOffset / sizeof(wchar_t));
targetBytes = rp->MountPointReparseBuffer.PrintNameLength;
- }
- else
- {
+ } else {
targetW = rp->MountPointReparseBuffer.PathBuffer +
(rp->MountPointReparseBuffer.SubstituteNameOffset / sizeof(wchar_t));
targetBytes = rp->MountPointReparseBuffer.SubstituteNameLength;
if (targetBytes >= 8 &&
- wcsncmp(targetW, L"\\??\\", 4) == 0)
- {
+ wcsncmp(targetW, L"\\??\\", 4) == 0) {
targetW += 4;
targetBytes -= 8;
}
}
- }
- else
- {
+ } else {
errno = EINVAL;
return -1;
}
ULONG outBytes = 0;
- if (!NT_SUCCESS(RtlUnicodeToUTF8N(buf, (ULONG) bufsiz, &outBytes, targetW, targetBytes)))
- {
+ if (!NT_SUCCESS(RtlUnicodeToUTF8N(buf, (ULONG) bufsiz, &outBytes, targetW, targetBytes))) {
errno = E2BIG;
return -1;
}
@@ -287,18 +253,15 @@ ssize_t freadlink(HANDLE hFile, char* buf, size_t bufsiz)
return (ssize_t) outBytes;
}
-ssize_t readlink(const char* path, char* buf, size_t bufsiz)
-{
- if (!path || !buf || bufsiz == 0)
- {
+ssize_t readlink(const char* path, char* buf, size_t bufsiz) {
+ if (!path || !buf || bufsiz == 0) {
errno = EINVAL;
return -1;
}
wchar_t pathW[MAX_PATH];
ULONG pathWBytes = 0;
- if (!NT_SUCCESS(RtlUTF8ToUnicodeN(pathW, (ULONG) sizeof(pathW), &pathWBytes, path, (ULONG) strlen(path) + 1)))
- {
+ if (!NT_SUCCESS(RtlUTF8ToUnicodeN(pathW, (ULONG) sizeof(pathW), &pathWBytes, path, (ULONG) strlen(path) + 1))) {
errno = EINVAL;
return -1;
}
@@ -310,11 +273,9 @@ ssize_t readlink(const char* path, char* buf, size_t bufsiz)
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
- NULL
- );
+ NULL);
- if (hFile == INVALID_HANDLE_VALUE)
- {
+ if (hFile == INVALID_HANDLE_VALUE) {
errno = winerr2Errno(GetLastError());
return -1;
}
diff --git a/src/common/impl/percent.c b/src/common/impl/percent.c
index a367bce57b..ee0b8cf3ff 100644
--- a/src/common/impl/percent.c
+++ b/src/common/impl/percent.c
@@ -6,44 +6,42 @@
#include "common/textModifier.h"
#include "common/stringUtils.h"
-static void appendOutputColor(FFstrbuf* buffer, const FFModuleArgs* module)
-{
- if (module->outputColor.length)
+static void appendOutputColor(FFstrbuf* buffer, const FFModuleArgs* module) {
+ if (module->outputColor.length) {
ffStrbufAppendF(buffer, "\e[%sm", module->outputColor.chars);
- else if (instance.config.display.colorOutput.length)
+ } else if (instance.config.display.colorOutput.length) {
ffStrbufAppendF(buffer, "\e[%sm", instance.config.display.colorOutput.chars);
+ }
}
-const char* ffPercentParseTypeJsonConfig(yyjson_val* jsonVal, FFPercentageTypeFlags* result)
-{
- if (yyjson_is_uint(jsonVal))
- {
+const char* ffPercentParseTypeJsonConfig(yyjson_val* jsonVal, FFPercentageTypeFlags* result) {
+ if (yyjson_is_uint(jsonVal)) {
*result = (FFPercentageTypeFlags) yyjson_get_uint(jsonVal);
return NULL;
}
- if (yyjson_is_arr(jsonVal))
- {
+ if (yyjson_is_arr(jsonVal)) {
FFPercentageTypeFlags flags = 0;
yyjson_val* item;
size_t idx, max;
- yyjson_arr_foreach(jsonVal, idx, max, item)
- {
+ yyjson_arr_foreach (jsonVal, idx, max, item) {
const char* flag = yyjson_get_str(item);
- if (!flag)
+ if (!flag) {
return "Error: percent.type: invalid flag string";
- if (ffStrEqualsIgnCase(flag, "num"))
+ }
+ if (ffStrEqualsIgnCase(flag, "num")) {
flags |= FF_PERCENTAGE_TYPE_NUM_BIT;
- else if (ffStrEqualsIgnCase(flag, "bar"))
+ } else if (ffStrEqualsIgnCase(flag, "bar")) {
flags |= FF_PERCENTAGE_TYPE_BAR_BIT;
- else if (ffStrEqualsIgnCase(flag, "hide-others"))
+ } else if (ffStrEqualsIgnCase(flag, "hide-others")) {
flags |= FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT;
- else if (ffStrEqualsIgnCase(flag, "num-color"))
+ } else if (ffStrEqualsIgnCase(flag, "num-color")) {
flags |= FF_PERCENTAGE_TYPE_NUM_COLOR_BIT;
- else if (ffStrEqualsIgnCase(flag, "bar-monochrome"))
+ } else if (ffStrEqualsIgnCase(flag, "bar-monochrome")) {
flags |= FF_PERCENTAGE_TYPE_BAR_MONOCHROME_BIT;
- else
+ } else {
return "Error: percent.type: unknown flag string";
+ }
}
*result = flags;
@@ -53,8 +51,7 @@ const char* ffPercentParseTypeJsonConfig(yyjson_val* jsonVal, FFPercentageTypeFl
return "Error: usage: percent.type must be a number or an array of strings";
}
-void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFPercentageModuleConfig config, const FFModuleArgs* module)
-{
+void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFPercentageModuleConfig config, const FFModuleArgs* module) {
uint8_t green = config.green, yellow = config.yellow;
assert(green <= 100 && yellow <= 100);
@@ -65,30 +62,24 @@ void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFPercentageModuleConf
uint8_t blocksPercent = (uint8_t) (percent / 100.0 * options->barWidth + 0.5);
assert(blocksPercent <= options->barWidth);
- if(!borderAsValue && options->barBorderLeft.length)
- {
- if(!options->pipe && options->barColorBorder.length > 0)
+ if (!borderAsValue && options->barBorderLeft.length) {
+ if (!options->pipe && options->barColorBorder.length > 0) {
ffStrbufAppendF(buffer, "\e[%sm", options->barColorBorder.chars);
+ }
ffStrbufAppend(buffer, &options->barBorderLeft);
}
- if (percent == -DBL_MAX)
- {
+ if (percent == -DBL_MAX) {
// Use total color for simplification
- if(!options->pipe && options->barColorTotal.length > 0)
+ if (!options->pipe && options->barColorTotal.length > 0) {
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_BLACK "m");
+ }
- for (uint8_t i = 0; i < options->barWidth; ++i)
- {
- ffStrbufAppend(buffer, borderAsValue && i == 0
- ? &options->barBorderLeft
- : borderAsValue && i == options->barWidth - 1
- ? &options->barBorderRight
- : &options->barCharTotal);
+ for (uint8_t i = 0; i < options->barWidth; ++i) {
+ ffStrbufAppend(buffer, borderAsValue && i == 0 ? &options->barBorderLeft : borderAsValue && i == options->barWidth - 1 ? &options->barBorderRight
+ : &options->barCharTotal);
}
- }
- else
- {
+ } else {
const char* colorGreen = options->percentColorGreen.chars;
const char* colorYellow = options->percentColorYellow.chars;
const char* colorRed = options->percentColorRed.chars;
@@ -98,76 +89,70 @@ void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFPercentageModuleConf
bool autoColorElapsed = ffStrbufIgnCaseEqualS(&options->barColorElapsed, "auto");
bool monochrome = (percentType & FF_PERCENTAGE_TYPE_BAR_MONOCHROME_BIT) || !autoColorElapsed;
- if (!options->pipe && options->barColorElapsed.length > 0 && monochrome)
- {
+ if (!options->pipe && options->barColorElapsed.length > 0 && monochrome) {
const char* color = NULL;
- if (!autoColorElapsed)
+ if (!autoColorElapsed) {
color = options->barColorElapsed.chars;
- else if (green <= yellow)
- {
- if (percent < green) color = colorGreen;
- else if (percent < yellow) color = colorYellow;
- else color = colorRed;
- }
- else
- {
- if (percent < yellow) color = colorRed;
- else if (percent < green) color = colorYellow;
- else color = colorGreen;
+ } else if (green <= yellow) {
+ if (percent < green) {
+ color = colorGreen;
+ } else if (percent < yellow) {
+ color = colorYellow;
+ } else {
+ color = colorRed;
+ }
+ } else {
+ if (percent < yellow) {
+ color = colorRed;
+ } else if (percent < green) {
+ color = colorYellow;
+ } else {
+ color = colorGreen;
+ }
}
ffStrbufAppendF(buffer, "\e[%sm", color);
}
- for (uint8_t i = 0; i < blocksPercent; ++i)
- {
- if (!options->pipe && options->barColorElapsed.length > 0 && !monochrome)
- {
+ for (uint8_t i = 0; i < blocksPercent; ++i) {
+ if (!options->pipe && options->barColorElapsed.length > 0 && !monochrome) {
uint32_t section1Begin = (uint32_t) ((green <= yellow ? green : yellow) / 100.0 * options->barWidth + 0.5);
uint32_t section2Begin = (uint32_t) ((green > yellow ? green : yellow) / 100.0 * options->barWidth + 0.5);
- if (i == section2Begin)
+ if (i == section2Begin) {
ffStrbufAppendF(buffer, "\e[%sm", (green > yellow ? colorGreen : colorRed));
- else if (i == section1Begin)
+ } else if (i == section1Begin) {
ffStrbufAppendF(buffer, "\e[%sm", colorYellow);
- else if (i == 0)
+ } else if (i == 0) {
ffStrbufAppendF(buffer, "\e[%sm", (green <= yellow ? colorGreen : colorRed));
+ }
}
- ffStrbufAppend(buffer, borderAsValue && i == 0
- ? &options->barBorderLeftElapsed
- : borderAsValue && i == options->barWidth - 1
- ? &options->barBorderRightElapsed
- : &options->barCharElapsed);
+ ffStrbufAppend(buffer, borderAsValue && i == 0 ? &options->barBorderLeftElapsed : borderAsValue && i == options->barWidth - 1 ? &options->barBorderRightElapsed
+ : &options->barCharElapsed);
}
- if (blocksPercent < options->barWidth)
- {
- if(!options->pipe && options->barColorTotal.length > 0)
+ if (blocksPercent < options->barWidth) {
+ if (!options->pipe && options->barColorTotal.length > 0) {
ffStrbufAppendF(buffer, "\e[%sm", options->barColorTotal.chars);
- for (uint8_t i = blocksPercent; i < options->barWidth; ++i)
- {
- ffStrbufAppend(buffer, borderAsValue && i == 0
- ? &options->barBorderLeft
- : borderAsValue && i == options->barWidth - 1
- ? &options->barBorderRight
- : &options->barCharTotal);
+ }
+ for (uint8_t i = blocksPercent; i < options->barWidth; ++i) {
+ ffStrbufAppend(buffer, borderAsValue && i == 0 ? &options->barBorderLeft : borderAsValue && i == options->barWidth - 1 ? &options->barBorderRight
+ : &options->barCharTotal);
}
}
}
- if(!borderAsValue && options->barBorderRight.length)
- {
- if(!options->pipe && options->barColorBorder.length > 0)
+ if (!borderAsValue && options->barBorderRight.length) {
+ if (!options->pipe && options->barColorBorder.length > 0) {
ffStrbufAppendF(buffer, "\e[%sm", options->barColorBorder.chars);
+ }
ffStrbufAppend(buffer, &options->barBorderRight);
}
- if(!options->pipe && (options->barColorElapsed.length > 0 || options->barColorTotal.length > 0 || options->barColorBorder.length > 0))
- {
+ if (!options->pipe && (options->barColorElapsed.length > 0 || options->barColorTotal.length > 0 || options->barColorBorder.length > 0)) {
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
appendOutputColor(buffer, module);
}
}
-void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFPercentageModuleConfig config, bool parentheses, const FFModuleArgs* module)
-{
+void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFPercentageModuleConfig config, bool parentheses, const FFModuleArgs* module) {
uint8_t green = config.green, yellow = config.yellow;
assert(green <= 100 && yellow <= 100);
@@ -176,61 +161,57 @@ void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFPercentageModuleConf
bool colored = !!(percentType & FF_PERCENTAGE_TYPE_NUM_COLOR_BIT);
- if (parentheses)
+ if (parentheses) {
ffStrbufAppendC(buffer, '(');
+ }
- if (colored && !options->pipe)
- {
+ if (colored && !options->pipe) {
const char* colorGreen = options->percentColorGreen.chars;
const char* colorYellow = options->percentColorYellow.chars;
const char* colorRed = options->percentColorRed.chars;
- if(percent == -DBL_MAX)
+ if (percent == -DBL_MAX) {
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_BLACK "m");
- else if(green <= yellow)
- {
- if (percent > yellow)
+ } else if (green <= yellow) {
+ if (percent > yellow) {
ffStrbufAppendF(buffer, "\e[%sm", colorRed);
- else if (percent > green)
+ } else if (percent > green) {
ffStrbufAppendF(buffer, "\e[%sm", colorYellow);
- else
+ } else {
ffStrbufAppendF(buffer, "\e[%sm", colorGreen);
- }
- else
- {
- if (percent < yellow)
+ }
+ } else {
+ if (percent < yellow) {
ffStrbufAppendF(buffer, "\e[%sm", colorRed);
- else if (percent < green)
+ } else if (percent < green) {
ffStrbufAppendF(buffer, "\e[%sm", colorYellow);
- else
+ } else {
ffStrbufAppendF(buffer, "\e[%sm", colorGreen);
+ }
}
}
- ffStrbufAppendF(buffer, "%*.*f%s%%", options->percentWidth, options->percentNdigits, percent,
- options->percentSpaceBeforeUnit == FF_SPACE_BEFORE_UNIT_ALWAYS ? " " : "");
+ ffStrbufAppendF(buffer, "%*.*f%s%%", options->percentWidth, options->percentNdigits, percent, options->percentSpaceBeforeUnit == FF_SPACE_BEFORE_UNIT_ALWAYS ? " " : "");
- if (colored && !options->pipe)
- {
+ if (colored && !options->pipe) {
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
appendOutputColor(buffer, module);
}
- if (parentheses)
+ if (parentheses) {
ffStrbufAppendC(buffer, ')');
+ }
}
-bool ffPercentParseCommandOptions(const char* key, const char* subkey, const char* value, FFPercentageModuleConfig* config)
-{
- if (!ffStrStartsWithIgnCase(subkey, "percent-"))
+bool ffPercentParseCommandOptions(const char* key, const char* subkey, const char* value, FFPercentageModuleConfig* config) {
+ if (!ffStrStartsWithIgnCase(subkey, "percent-")) {
return false;
+ }
subkey += strlen("percent-");
- if (ffStrEqualsIgnCase(subkey, "green"))
- {
+ if (ffStrEqualsIgnCase(subkey, "green")) {
uint32_t num = ffOptionParseUInt32(key, value);
- if (num > 100)
- {
+ if (num > 100) {
fprintf(stderr, "Error: usage: %s must be between 0 and 100\n", key);
exit(480);
}
@@ -238,11 +219,9 @@ bool ffPercentParseCommandOptions(const char* key, const char* subkey, const cha
return true;
}
- if (ffStrEqualsIgnCase(subkey, "yellow"))
- {
+ if (ffStrEqualsIgnCase(subkey, "yellow")) {
uint32_t num = ffOptionParseUInt32(key, value);
- if (num > 100)
- {
+ if (num > 100) {
fprintf(stderr, "Error: usage: %s must be between 0 and 100\n", key);
exit(480);
}
@@ -250,8 +229,7 @@ bool ffPercentParseCommandOptions(const char* key, const char* subkey, const cha
return true;
}
- if (ffStrEqualsIgnCase(subkey, "type"))
- {
+ if (ffStrEqualsIgnCase(subkey, "type")) {
config->type = (FFPercentageTypeFlags) ffOptionParseUInt32(key, value);
return true;
}
@@ -259,25 +237,22 @@ bool ffPercentParseCommandOptions(const char* key, const char* subkey, const cha
return false;
}
-bool ffPercentParseJsonObject(yyjson_val* key, yyjson_val* value, FFPercentageModuleConfig* config)
-{
+bool ffPercentParseJsonObject(yyjson_val* key, yyjson_val* value, FFPercentageModuleConfig* config) {
assert(key);
- if (!unsafe_yyjson_equals_str(key, "percent"))
+ if (!unsafe_yyjson_equals_str(key, "percent")) {
return false;
+ }
- if (!yyjson_is_obj(value))
- {
+ if (!yyjson_is_obj(value)) {
fprintf(stderr, "Error: usage: %s must be an object\n", unsafe_yyjson_get_str(key));
exit(480);
}
yyjson_val* greenVal = yyjson_obj_get(value, "green");
- if (greenVal)
- {
+ if (greenVal) {
int num = yyjson_get_int(greenVal);
- if (num < 0 || num > 100)
- {
+ if (num < 0 || num > 100) {
fputs("Error: usage: percent.green must be between 0 and 100\n", stderr);
exit(480);
}
@@ -285,11 +260,9 @@ bool ffPercentParseJsonObject(yyjson_val* key, yyjson_val* value, FFPercentageMo
}
yyjson_val* yellowVal = yyjson_obj_get(value, "yellow");
- if (yellowVal)
- {
+ if (yellowVal) {
int num = yyjson_get_int(yellowVal);
- if (num < 0 || num > 100)
- {
+ if (num < 0 || num > 100) {
fputs("Error: usage: percent.yellow must be between 0 and 100\n", stderr);
exit(480);
}
@@ -297,11 +270,9 @@ bool ffPercentParseJsonObject(yyjson_val* key, yyjson_val* value, FFPercentageMo
}
yyjson_val* typeVal = yyjson_obj_get(value, "type");
- if (typeVal)
- {
+ if (typeVal) {
const char* error = ffPercentParseTypeJsonConfig(typeVal, &config->type);
- if (error)
- {
+ if (error) {
fputs(error, stderr);
exit(480);
}
@@ -310,8 +281,7 @@ bool ffPercentParseJsonObject(yyjson_val* key, yyjson_val* value, FFPercentageMo
return true;
}
-void ffPercentGenerateJsonConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFPercentageModuleConfig config)
-{
+void ffPercentGenerateJsonConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFPercentageModuleConfig config) {
yyjson_mut_val* percent = yyjson_mut_obj_add_obj(doc, module, "percent");
yyjson_mut_obj_add_uint(doc, percent, "green", config.green);
yyjson_mut_obj_add_uint(doc, percent, "yellow", config.yellow);
diff --git a/src/common/impl/printing.c b/src/common/impl/printing.c
index efb9a2e90c..c9f43c01c2 100644
--- a/src/common/impl/printing.c
+++ b/src/common/impl/printing.c
@@ -3,145 +3,146 @@
#include "common/textModifier.h"
#include "logo/logo.h"
-void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType)
-{
+void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType) {
ffLogoPrintLine();
- //This is used by --set-keyless, in this case we want neither the module name nor the separator
- if(moduleName == NULL)
+ // This is used by --set-keyless, in this case we want neither the module name nor the separator
+ if (moduleName == NULL) {
return;
+ }
- //This is used as a magic value for hiding keys
- if (!(moduleArgs && ffStrbufEqualS(&moduleArgs->key, " ")) && instance.config.display.keyType != FF_MODULE_KEY_TYPE_NONE)
- {
+ // This is used as a magic value for hiding keys
+ if (!(moduleArgs && ffStrbufEqualS(&moduleArgs->key, " ")) && instance.config.display.keyType != FF_MODULE_KEY_TYPE_NONE) {
ffPrintCharTimes(' ', instance.config.display.keyPaddingLeft);
- if(!instance.config.display.pipe)
- {
+ if (!instance.config.display.pipe) {
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
- if (instance.config.display.brightColor)
+ if (instance.config.display.brightColor) {
fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout);
+ }
- if(moduleArgs && !(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_COLOR) && moduleArgs->keyColor.length > 0)
+ if (moduleArgs && !(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_COLOR) && moduleArgs->keyColor.length > 0) {
ffPrintColor(&moduleArgs->keyColor);
- else
+ } else {
ffPrintColor(&instance.config.display.colorKeys);
+ }
}
- if (instance.config.display.keyType & FF_MODULE_KEY_TYPE_ICON && moduleArgs && moduleArgs->keyIcon.length > 0)
+ if (instance.config.display.keyType & FF_MODULE_KEY_TYPE_ICON && moduleArgs && moduleArgs->keyIcon.length > 0) {
ffStrbufWriteTo(&moduleArgs->keyIcon, stdout);
+ }
- if (instance.config.display.keyType & FF_MODULE_KEY_TYPE_STRING)
- {
+ if (instance.config.display.keyType & FF_MODULE_KEY_TYPE_STRING) {
ffPrintCharTimes(' ', instance.config.display.keyType >> FF_MODULE_KEY_TYPE_SPACE_SHIFT);
- //NULL check is required for modules with custom keys, e.g. disk with the folder path
- if((printType & FF_PRINT_TYPE_NO_CUSTOM_KEY) || !moduleArgs || moduleArgs->key.length == 0)
- {
+ // NULL check is required for modules with custom keys, e.g. disk with the folder path
+ if ((printType & FF_PRINT_TYPE_NO_CUSTOM_KEY) || !moduleArgs || moduleArgs->key.length == 0) {
fputs(moduleName, stdout);
- if(moduleIndex > 0)
+ if (moduleIndex > 0) {
printf(" %hhu", moduleIndex);
- }
- else
- {
+ }
+ } else {
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
FF_PARSE_FORMAT_STRING_CHECKED(&key, &moduleArgs->key, ((FFformatarg[]) {
- FF_ARG(moduleIndex, "index"),
- FF_ARG(moduleArgs->keyIcon, "icon"),
- }));
+ FF_ARG(moduleIndex, "index"),
+ FF_ARG(moduleArgs->keyIcon, "icon"),
+ }));
ffStrbufWriteTo(&key, stdout);
}
}
- if(!instance.config.display.pipe)
- {
+ if (!instance.config.display.pipe) {
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
ffPrintColor(&instance.config.display.colorSeparator);
}
ffStrbufWriteTo(&instance.config.display.keyValueSeparator, stdout);
- if(!instance.config.display.pipe && instance.config.display.colorSeparator.length)
+ if (!instance.config.display.pipe && instance.config.display.colorSeparator.length) {
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
+ }
- if (!(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_WIDTH))
- {
+ if (!(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_WIDTH)) {
uint32_t keyWidth = moduleArgs && moduleArgs->keyWidth > 0 ? moduleArgs->keyWidth : instance.config.display.keyWidth;
- if (keyWidth > 0)
+ if (keyWidth > 0) {
printf("\e[%uG", (unsigned) (keyWidth + instance.state.logoWidth));
+ }
}
}
- if(!instance.config.display.pipe)
- {
+ if (!instance.config.display.pipe) {
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
- if (moduleArgs && moduleArgs->outputColor.length)
+ if (moduleArgs && moduleArgs->outputColor.length) {
ffPrintColor(&moduleArgs->outputColor);
- else if (instance.config.display.colorOutput.length)
+ } else if (instance.config.display.colorOutput.length) {
ffPrintColor(&instance.config.display.colorOutput);
+ }
}
}
-void ffPrintFormat(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, uint32_t numArgs, const FFformatarg* arguments)
-{
+void ffPrintFormat(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, uint32_t numArgs, const FFformatarg* arguments) {
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
- if (moduleArgs)
+ if (moduleArgs) {
ffParseFormatString(&buffer, &moduleArgs->outputFormat, numArgs, arguments);
- else
+ } else {
ffStrbufAppendS(&buffer, "unknown");
+ }
ffPrintLogoAndKey(moduleName, moduleIndex, moduleArgs, printType);
ffStrbufPutTo(&buffer, stdout);
}
-void ffPrintError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, ...)
-{
- if(!instance.config.display.showErrors)
+void ffPrintError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, ...) {
+ if (!instance.config.display.showErrors) {
return;
+ }
ffPrintLogoAndKey(moduleName, moduleIndex, moduleArgs, printType);
- if(!instance.config.display.pipe)
+ if (!instance.config.display.pipe) {
fputs(FASTFETCH_TEXT_MODIFIER_ERROR, stdout);
+ }
va_list arguments;
va_start(arguments, message);
vprintf(message, arguments);
va_end(arguments);
- if(!instance.config.display.pipe)
+ if (!instance.config.display.pipe) {
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
+ }
putchar('\n');
}
-void ffPrintColor(const FFstrbuf* colorValue)
-{
- //If the color is not set, this would reset in \033[m, which resets everything.
- //So we only print it, if the main color is at least one char.
- if(colorValue->length == 0)
+void ffPrintColor(const FFstrbuf* colorValue) {
+ // If the color is not set, this would reset in \033[m, which resets everything.
+ // So we only print it, if the main color is at least one char.
+ if (colorValue->length == 0) {
return;
+ }
printf("\e[%sm", colorValue->chars);
}
-void ffPrintCharTimes(char c, uint32_t times)
-{
- if(times == 0)
+void ffPrintCharTimes(char c, uint32_t times) {
+ if (times == 0) {
return;
+ }
- if(times == 1)
- {
+ if (times == 1) {
putchar(c);
return;
}
char str[32];
- memset(str, c, sizeof(str)); //2 instructions when compiling with AVX2 enabled
- for(uint32_t i = sizeof(str); i <= times; i += (uint32_t)sizeof(str))
+ memset(str, c, sizeof(str)); // 2 instructions when compiling with AVX2 enabled
+ for (uint32_t i = sizeof(str); i <= times; i += (uint32_t) sizeof(str)) {
fwrite(str, 1, sizeof(str), stdout);
+ }
uint32_t remaining = times % sizeof(str);
- if(remaining > 0)
+ if (remaining > 0) {
fwrite(str, 1, remaining, stdout);
+ }
}
diff --git a/src/common/impl/processing_linux.c b/src/common/impl/processing_linux.c
index 472cec5a3e..6fda83ce6b 100644
--- a/src/common/impl/processing_linux.c
+++ b/src/common/impl/processing_linux.c
@@ -43,31 +43,30 @@ extern char** environ;
enum { FF_PIPE_BUFSIZ = 8192 };
-static inline int ffPipe2(int* fds, int flags)
-{
- #ifndef FF_HAVE_PIPE2
- if(pipe(fds) == -1)
- return -1;
- fcntl(fds[0], F_SETFL, fcntl(fds[0], F_GETFL) | flags);
- fcntl(fds[1], F_SETFL, fcntl(fds[1], F_GETFL) | flags);
- return 0;
- #else
- return pipe2(fds, flags);
- #endif
+static inline int ffPipe2(int* fds, int flags) {
+#ifndef FF_HAVE_PIPE2
+ if (pipe(fds) == -1) {
+ return -1;
+ }
+ fcntl(fds[0], F_SETFL, fcntl(fds[0], F_GETFL) | flags);
+ fcntl(fds[1], F_SETFL, fcntl(fds[1], F_GETFL) | flags);
+ return 0;
+#else
+ return pipe2(fds, flags);
+#endif
}
-
// Not thread-safe
-const char* ffProcessSpawn(char* const argv[], bool useStdErr, FFProcessHandle* outHandle)
-{
+const char* ffProcessSpawn(char* const argv[], bool useStdErr, FFProcessHandle* outHandle) {
int pipes[2];
- if(ffPipe2(pipes, O_CLOEXEC) == -1)
+ if (ffPipe2(pipes, O_CLOEXEC) == -1) {
return "pipe() failed";
+ }
pid_t childPid = -1;
int nullFile = ffGetNullFD();
- #if !(__ANDROID__ || __OpenBSD__)
+#if !(__ANDROID__ || __OpenBSD__)
// NetBSD / Darwin: native syscall
// Linux (glibc): clone3-execve
@@ -83,33 +82,29 @@ const char* ffProcessSpawn(char* const argv[], bool useStdErr, FFProcessHandle*
static char* oldLang = NULL;
static int langIndex = -1;
- if (langIndex >= 0)
- {
+ if (langIndex >= 0) {
// Found before
if (oldLang) // oldLang was set only if it needed to be changed
{
- if (environ[langIndex] != oldLang)
- {
+ if (environ[langIndex] != oldLang) {
// environ is changed outside of this function
langIndex = -1;
- }
- else
+ } else {
environ[langIndex] = (char*) "LANG=C.UTF-8";
+ }
}
}
- if (langIndex < 0)
- {
- for (int i = 0; environ[i] != NULL; i++)
- {
- if (ffStrStartsWith(environ[i], "LANG="))
- {
+ if (langIndex < 0) {
+ for (int i = 0; environ[i] != NULL; i++) {
+ if (ffStrStartsWith(environ[i], "LANG=")) {
langIndex = i;
const char* langValue = environ[i] + 5; // Skip "LANG="
if (ffStrEqualsIgnCase(langValue, "C") ||
ffStrStartsWithIgnCase(environ[i], "C.") ||
ffStrEqualsIgnCase(langValue, "en_US") ||
- ffStrStartsWithIgnCase(langValue, "en_US."))
+ ffStrStartsWithIgnCase(langValue, "en_US.")) {
break; // No need to change LANG
+ }
oldLang = environ[i];
environ[i] = (char*) "LANG=C.UTF-8"; // Set LANG to C.UTF-8 for consistent output
break;
@@ -119,33 +114,32 @@ const char* ffProcessSpawn(char* const argv[], bool useStdErr, FFProcessHandle*
int ret = posix_spawnp(&childPid, argv[0], &file_actions, NULL, argv, environ);
- if (oldLang)
+ if (oldLang) {
environ[langIndex] = oldLang;
+ }
posix_spawn_file_actions_destroy(&file_actions);
- if (ret != 0)
- {
+ if (ret != 0) {
close(pipes[0]);
close(pipes[1]);
- if (ret == ENOENT)
+ if (ret == ENOENT) {
return "command not found";
+ }
return "posix_spawnp() failed";
}
- #else
+#else
// https://github.com/termux/termux-packages/issues/25369
childPid = fork();
- if(childPid == -1)
- {
+ if (childPid == -1) {
close(pipes[0]);
close(pipes[1]);
return "fork() failed";
}
- if(childPid == 0)
- {
+ if (childPid == 0) {
// Child process
dup2(pipes[1], useStdErr ? STDERR_FILENO : STDOUT_FILENO);
dup2(nullFile, useStdErr ? STDOUT_FILENO : STDERR_FILENO);
@@ -154,7 +148,7 @@ const char* ffProcessSpawn(char* const argv[], bool useStdErr, FFProcessHandle*
_exit(127);
}
- #endif
+#endif
close(pipes[1]);
outHandle->pid = childPid;
@@ -162,8 +156,7 @@ const char* ffProcessSpawn(char* const argv[], bool useStdErr, FFProcessHandle*
return NULL;
}
-const char* ffProcessReadOutput(FFProcessHandle* handle, FFstrbuf* buffer)
-{
+const char* ffProcessReadOutput(FFProcessHandle* handle, FFstrbuf* buffer) {
assert(handle->pipeRead != -1);
assert(handle->pid != -1);
@@ -174,20 +167,15 @@ const char* ffProcessReadOutput(FFProcessHandle* handle, FFstrbuf* buffer)
handle->pid = -1;
char str[FF_PIPE_BUFSIZ];
- for (;;)
- {
- if (timeout >= 0)
- {
+ for (;;) {
+ if (timeout >= 0) {
struct pollfd pollfd = { childPipeFd, POLLIN, 0 };
int pollret = poll(&pollfd, 1, timeout);
- if (pollret == 0)
- {
+ if (pollret == 0) {
kill(childPid, SIGTERM);
waitpid(childPid, NULL, 0);
return "poll(&pollfd, 1, timeout) timeout (try increasing --processing-timeout)";
- }
- else if (pollret < 0 || (pollfd.revents & POLLERR))
- {
+ } else if (pollret < 0 || (pollfd.revents & POLLERR)) {
kill(childPid, SIGTERM);
waitpid(childPid, NULL, 0);
return pollret < 0
@@ -197,63 +185,65 @@ const char* ffProcessReadOutput(FFProcessHandle* handle, FFstrbuf* buffer)
}
ssize_t nRead = read(childPipeFd, str, FF_PIPE_BUFSIZ);
- if (nRead > 0)
+ if (nRead > 0) {
ffStrbufAppendNS(buffer, (uint32_t) nRead, str);
- else if (nRead == 0)
- {
+ } else if (nRead == 0) {
int stat_loc = 0;
- if (childPid > 0 && waitpid(childPid, &stat_loc, 0) == childPid)
- {
- if (!WIFEXITED(stat_loc))
+ if (childPid > 0 && waitpid(childPid, &stat_loc, 0) == childPid) {
+ if (!WIFEXITED(stat_loc)) {
return "child process exited abnormally";
- if (WEXITSTATUS(stat_loc) == 127)
+ }
+ if (WEXITSTATUS(stat_loc) == 127) {
return "command not found";
+ }
// We only handle 127 as an error. See `getTerminalVersionUrxvt` in `terminalshell.c`
return NULL;
}
return NULL;
- }
- else if (nRead < 0)
+ } else if (nRead < 0) {
break;
+ }
}
return "read(childPipeFd, str, FF_PIPE_BUFSIZ) failed";
}
-void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, const char** exeName, FFstrbuf* exePath)
-{
+void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, const char** exeName, FFstrbuf* exePath) {
assert(processName->length > 0);
ffStrbufClear(exe);
- if (exePath) ffStrbufClear(exePath);
+ if (exePath) {
+ ffStrbufClear(exePath);
+ }
- #if defined(__linux__) || defined(__GNU__)
+#if defined(__linux__) || defined(__GNU__)
char filePath[64];
- snprintf(filePath, sizeof(filePath), "/proc/%d/cmdline", (int)pid);
+ snprintf(filePath, sizeof(filePath), "/proc/%d/cmdline", (int) pid);
- if(ffReadFileBuffer(filePath, exe))
- {
+ if (ffReadFileBuffer(filePath, exe)) {
const char* p = exe->chars;
uint32_t len = (uint32_t) strlen(p);
- if (len + 1 < exe->length)
- {
+ if (len + 1 < exe->length) {
const char* name = memrchr(p, '/', len);
- if (name) name++; else name = p;
+ if (name) {
+ name++;
+ } else {
+ name = p;
+ }
// For interpreters, try to find the real script path in the arguments
if (ffStrStartsWith(name, "python")
- #ifndef __ANDROID__
+ #ifndef __ANDROID__
|| ffStrEquals(name, "guile") // for shepherd
- #endif
- )
- {
+ #endif
+ ) {
// `cmdline` always ends with a trailing '\0', and ffReadFileBuffer appends another \0
// So `exe->chars` is always double '\0' terminated
- for (p = p + len + 1; *p && *p == '-'; p += strlen(p) + 1) // Skip arguments
+ for (p = p + len + 1; *p && *p == '-'; p += strlen(p) + 1) { // Skip arguments
assert(p - exe->chars < exe->allocated);
- if (*p)
- {
+ }
+ if (*p) {
len = (uint32_t) strlen(p);
memmove(exe->chars, p, len + 1);
}
@@ -262,12 +252,11 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
assert(len < exe->allocated);
exe->length = len;
- ffStrbufTrimLeft(exe, '-'); //Login shells start with a dash
+ ffStrbufTrimLeft(exe, '-'); // Login shells start with a dash
}
- if (exePath)
- {
- snprintf(filePath, sizeof(filePath), "/proc/%d/exe", (int)pid);
+ if (exePath) {
+ snprintf(filePath, sizeof(filePath), "/proc/%d/exe", (int) pid);
char buf[PATH_MAX];
ssize_t length = readlink(filePath, buf, PATH_MAX - 1);
if (length > 0) // doesn't contain trailing NUL
@@ -275,64 +264,68 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
buf[length] = '\0';
// When the process is a deleted executable, the resolved path is like `/usr/bin/app (deleted)`
// But we can still access the binary via `/proc/pid/exe`. See #2136
- if (ffPathExists(buf, FF_PATHTYPE_ANY))
- ffStrbufSetNS(exePath, (uint32_t)length, buf);
+ if (ffPathExists(buf, FF_PATHTYPE_ANY)) {
+ ffStrbufSetNS(exePath, (uint32_t) length, buf);
+ }
}
- if (exePath->length == 0)
+ if (exePath->length == 0) {
ffStrbufSetS(exePath, filePath);
+ }
}
- #elif defined(__APPLE__)
+#elif defined(__APPLE__)
size_t len = 0;
int mibs[] = { CTL_KERN, KERN_PROCARGS2, pid };
- if (sysctl(mibs, ARRAY_SIZE(mibs), NULL, &len, NULL, 0) == 0)
- {// try get arg0
- //don't know why if don't let len longer, proArgs2 and len will change during the following sysctl() in old MacOS version.
+ if (sysctl(mibs, ARRAY_SIZE(mibs), NULL, &len, NULL, 0) == 0) { // try get arg0
+ // don't know why if don't let len longer, proArgs2 and len will change during the following sysctl() in old MacOS version.
len++;
FF_AUTO_FREE char* const procArgs2 = malloc(len);
- if (sysctl(mibs, ARRAY_SIZE(mibs), procArgs2, &len, NULL, 0) == 0)
- {
+ if (sysctl(mibs, ARRAY_SIZE(mibs), procArgs2, &len, NULL, 0) == 0) {
// https://gist.github.com/nonowarn/770696#file-getargv-c-L46
uint32_t argc = *(uint32_t*) procArgs2;
const char* realExePath = procArgs2 + sizeof(argc);
const char* arg0 = memchr(realExePath, '\0', len - (size_t) (realExePath - procArgs2));
- if (exePath)
+ if (exePath) {
ffStrbufSetNS(exePath, (uint32_t) (arg0 - realExePath), realExePath);
+ }
- do arg0++; while (*arg0 == '\0');
+ do {
+ arg0++;
+ } while (*arg0 == '\0');
assert(arg0 < procArgs2 + len);
- if (argc > 1)
- {
+ if (argc > 1) {
// #977
const char* p = strrchr(arg0, '/');
- if (p)
+ if (p) {
p++;
- else
+ } else {
p = arg0;
- if (ffStrStartsWithIgnCase(p, "python")) // /opt/homebrew/Cellar/python@3.12/3.12.3/Frameworks/Python.framework/Versions/3.12/Resources/Python.app/Contents/MacOS/Python /Users/carter/.local/bin/xonsh
+ }
+ if (ffStrStartsWithIgnCase(p, "python")) { // /opt/homebrew/Cellar/python@3.12/3.12.3/Frameworks/Python.framework/Versions/3.12/Resources/Python.app/Contents/MacOS/Python /Users/carter/.local/bin/xonsh
arg0 = p + strlen(p) + 1;
+ }
}
- if (*arg0 == '-') arg0++; // Login shells
+ if (*arg0 == '-') {
+ arg0++; // Login shells
+ }
ffStrbufSetS(exe, arg0);
}
}
- if (exePath || exe->length == 0)
- {
+ if (exePath || exe->length == 0) {
char buf[PROC_PIDPATHINFO_MAXSIZE];
int length = proc_pidpath(pid, buf, ARRAY_SIZE(buf));
- if (length > 0)
- {
- if (exe->length == 0)
+ if (length > 0) {
+ if (exe->length == 0) {
ffStrbufSetNS(exe, (uint32_t) length, buf);
- if (exePath)
- {
+ }
+ if (exePath) {
// We don't use exec_path above as exePath because it's a relative path and can be different
// from the actual executable being run (for example, when the original file is moved)
ffStrbufSetNS(exePath, (uint32_t) length, buf);
@@ -340,142 +333,159 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
}
}
- #elif defined(__FreeBSD__) || defined(__NetBSD__)
+#elif defined(__FreeBSD__) || defined(__NetBSD__)
size_t size = ARG_MAX;
FF_AUTO_FREE char* args = malloc(size);
static_assert(ARG_MAX > PATH_MAX, "");
- if(exePath && sysctl(
- (int[]){CTL_KERN,
- #if __FreeBSD__
- KERN_PROC, KERN_PROC_PATHNAME, pid
- #else
- KERN_PROC_ARGS, pid, KERN_PROC_PATHNAME
- #endif
- }, 4,
- args, &size,
- NULL, 0
- ) == 0)
+ if (exePath && sysctl((int[]) { CTL_KERN,
+ #if __FreeBSD__
+ KERN_PROC,
+ KERN_PROC_PATHNAME,
+ pid
+ #else
+ KERN_PROC_ARGS,
+ pid,
+ KERN_PROC_PATHNAME
+ #endif
+ },
+ 4,
+ args,
+ &size,
+ NULL,
+ 0) == 0)
ffStrbufSetNS(exePath, (uint32_t) (size - 1), args);
size = ARG_MAX;
- if(sysctl(
- (int[]){CTL_KERN,
- #if __FreeBSD__
- KERN_PROC, KERN_PROC_ARGS, pid
- #else
- KERN_PROC_ARGS, pid, KERN_PROC_ARGV,
- #endif
- }, 4,
- args, &size,
- NULL, 0
- ) == 0)
- {
+ if (sysctl(
+ (int[]) { CTL_KERN,
+ #if __FreeBSD__
+ KERN_PROC,
+ KERN_PROC_ARGS,
+ pid
+ #else
+ KERN_PROC_ARGS,
+ pid,
+ KERN_PROC_ARGV,
+ #endif
+ },
+ 4,
+ args,
+ &size,
+ NULL,
+ 0) == 0) {
char* arg0 = args;
size_t arg0Len = strlen(args);
- if (size > arg0Len + 1)
- {
+ if (size > arg0Len + 1) {
char* p = (char*) memrchr(args, '/', arg0Len);
- if (p)
+ if (p) {
p++;
- else
+ } else {
p = arg0;
+ }
if (ffStrStartsWith(p, "python")) // /usr/local/bin/python3.9 /home/carter/.local/bin/xonsh
{
arg0 += arg0Len + 1;
}
}
- if (arg0[0] == '-') arg0++;
+ if (arg0[0] == '-') {
+ arg0++;
+ }
ffStrbufSetS(exe, arg0);
}
- #elif defined(__sun)
+#elif defined(__sun)
char filePath[128];
snprintf(filePath, sizeof(filePath), "/proc/%d/psinfo", (int) pid);
psinfo_t proc;
- if (ffReadFileData(filePath, sizeof(proc), &proc) == sizeof(proc))
- {
+ if (ffReadFileData(filePath, sizeof(proc), &proc) == sizeof(proc)) {
const char* args = proc.pr_psargs;
- if (args[0] == '-') ++args;
+ if (args[0] == '-') {
+ ++args;
+ }
const char* end = strchr(args, ' ');
ffStrbufSetNS(exe, end ? (uint32_t) (end - args) : (uint32_t) strlen(args), args);
}
- if (exePath)
- {
+ if (exePath) {
snprintf(filePath, sizeof(filePath), "/proc/%d/path/a.out", (int) pid);
char buf[PATH_MAX];
ssize_t length = readlink(filePath, buf, PATH_MAX - 1);
if (length > 0) // doesn't contain trailing NUL
{
buf[length] = '\0';
- ffStrbufSetNS(exePath, (uint32_t)length, buf);
+ ffStrbufSetNS(exePath, (uint32_t) length, buf);
}
}
- #elif defined(__OpenBSD__)
+#elif defined(__OpenBSD__)
kvm_t* kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, NULL);
int count = 0;
const struct kinfo_proc* proc = kvm_getprocs(kd, KERN_PROC_PID, pid, sizeof(struct kinfo_proc), &count);
- if (proc)
- {
+ if (proc) {
char** argv = kvm_getargv(kd, proc, 0);
- if (argv)
- {
+ if (argv) {
const char* arg0 = argv[0];
- if (arg0[0] == '-') arg0++;
+ if (arg0[0] == '-') {
+ arg0++;
+ }
ffStrbufSetS(exe, arg0);
}
}
kvm_close(kd);
- #elif defined(__HAIKU__)
+#elif defined(__HAIKU__)
image_info info;
int32 cookie = 0;
- while (get_next_image_info(pid, &cookie, &info) == B_OK)
- {
- if (info.type != B_APP_IMAGE) continue;
+ while (get_next_image_info(pid, &cookie, &info) == B_OK) {
+ if (info.type != B_APP_IMAGE) {
+ continue;
+ }
ffStrbufSetS(exe, info.name);
- if (exePath)
+ if (exePath) {
ffStrbufSet(exePath, exe);
+ }
break;
}
- #endif
+#endif
- if(exe->length == 0)
+ if (exe->length == 0) {
ffStrbufSet(exe, processName);
+ }
assert(exe->length > 0);
uint32_t lastSlashIndex = ffStrbufLastIndexC(exe, '/');
- if(lastSlashIndex < exe->length)
+ if (lastSlashIndex < exe->length) {
*exeName = exe->chars + lastSlashIndex + 1;
+ }
}
-const char* ffProcessGetBasicInfoLinux(pid_t pid, FFstrbuf* name, pid_t* ppid, int32_t* tty)
-{
- if (pid <= 0)
+const char* ffProcessGetBasicInfoLinux(pid_t pid, FFstrbuf* name, pid_t* ppid, int32_t* tty) {
+ if (pid <= 0) {
return "Invalid pid";
+ }
- #if defined(__linux__) || defined(__GNU__)
+#if defined(__linux__) || defined(__GNU__)
char procFilePath[64];
#if __linux__
if (ppid || tty)
#endif
{
- snprintf(procFilePath, sizeof(procFilePath), "/proc/%d/stat", (int)pid);
+ snprintf(procFilePath, sizeof(procFilePath), "/proc/%d/stat", (int) pid);
char buf[PROC_FILE_BUFFSIZ];
ssize_t nRead = ffReadFileData(procFilePath, sizeof(buf) - 1, buf);
- if(nRead <= 8)
+ if (nRead <= 8) {
return "ffReadFileData(/proc/pid/stat, PROC_FILE_BUFFSIZ-1, buf) failed";
+ }
buf[nRead] = '\0'; // pid (comm) state ppid pgrp session tty
const char* pState = NULL;
@@ -483,66 +493,70 @@ const char* ffProcessGetBasicInfoLinux(pid_t pid, FFstrbuf* name, pid_t* ppid, i
{
// comm in `/proc/pid/stat` is not encoded, and may contain ' ', ')' or even `\n`
const char* start = memchr(buf, '(', (size_t) nRead);
- if (!start)
+ if (!start) {
return "memchr(stat, '(') failed";
+ }
start++;
const char* end = memrchr(start, ')', (size_t) nRead - (size_t) (start - buf));
- if (!end)
+ if (!end) {
return "memrchr(stat, ')') failed";
+ }
ffStrbufSetNS(name, (uint32_t) (end - start), start);
ffStrbufTrimRightSpace(name);
- if (name->chars[0] == '\0')
+ if (name->chars[0] == '\0') {
return "process name is empty";
+ }
pState = end + 2; // skip ") "
}
- #if !__linux__
+ #if !__linux__
if (ppid || tty)
- #endif
+ #endif
{
int ppid_, tty_;
- if(sscanf(pState + 2, "%d %*d %*d %d", &ppid_, &tty_) < 2)
+ if (sscanf(pState + 2, "%d %*d %*d %d", &ppid_, &tty_) < 2) {
return "sscanf(stat) failed";
+ }
- if (ppid)
+ if (ppid) {
*ppid = (pid_t) ppid_;
- if (tty)
+ }
+ if (tty) {
*tty = tty_ & 0xFF;
+ }
}
}
#if __linux__
- else
- {
- snprintf(procFilePath, sizeof(procFilePath), "/proc/%d/comm", (int)pid);
+ else {
+ snprintf(procFilePath, sizeof(procFilePath), "/proc/%d/comm", (int) pid);
ssize_t nRead = ffReadFileBuffer(procFilePath, name);
- if(nRead <= 0)
+ if (nRead <= 0) {
return "ffReadFileBuffer(/proc/pid/comm, name) failed";
+ }
ffStrbufTrimRightSpace(name);
}
#endif
- #elif defined(__APPLE__)
+#elif defined(__APPLE__)
struct kinfo_proc proc;
size_t size = sizeof(proc);
- if(sysctl(
- (int[]){CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}, 4,
- &proc, &size,
- NULL, 0
- ))
+ if (sysctl(
+ (int[]) { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid }, 4, &proc, &size, NULL, 0)) {
return "sysctl(KERN_PROC_PID) failed";
+ }
- ffStrbufSetS(name, proc.kp_proc.p_comm); //trancated to 16 chars
- if (ppid)
- *ppid = (pid_t)proc.kp_eproc.e_ppid;
- if (tty)
- {
+ ffStrbufSetS(name, proc.kp_proc.p_comm); // trancated to 16 chars
+ if (ppid) {
+ *ppid = (pid_t) proc.kp_eproc.e_ppid;
+ }
+ if (tty) {
*tty = ((proc.kp_eproc.e_tdev >> 24) & 0xFF) == 0x10
? proc.kp_eproc.e_tdev & 0xFFFFFF
: -1;
}
- #elif defined(__FreeBSD__)
+#elif defined(__FreeBSD__)
#ifdef __DragonFly__
#define ki_comm kp_comm
@@ -553,105 +567,106 @@ const char* ffProcessGetBasicInfoLinux(pid_t pid, FFstrbuf* name, pid_t* ppid, i
struct kinfo_proc proc;
size_t size = sizeof(proc);
- if(sysctl(
- (int[]){CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}, 4,
- &proc, &size,
- NULL, 0
- ))
+ if (sysctl(
+ (int[]) { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid }, 4, &proc, &size, NULL, 0)) {
return "sysctl(KERN_PROC_PID) failed";
+ }
ffStrbufSetS(name, proc.ki_comm);
- if (ppid)
- *ppid = (pid_t)proc.ki_ppid;
- if (tty)
- {
- if (proc.ki_tdev != NODEV && proc.ki_flag & P_CONTROLT)
- {
+ if (ppid) {
+ *ppid = (pid_t) proc.ki_ppid;
+ }
+ if (tty) {
+ if (proc.ki_tdev != NODEV && proc.ki_flag & P_CONTROLT) {
const char* ttyName = devname(proc.ki_tdev, S_IFCHR);
- if (ffStrStartsWith(ttyName, "pts/"))
+ if (ffStrStartsWith(ttyName, "pts/")) {
*tty = (int32_t) strtol(ttyName + strlen("pts/"), NULL, 10);
- else
+ } else {
*tty = -1;
- }
- else
+ }
+ } else {
*tty = -1;
+ }
}
- #elif defined(__NetBSD__)
+#elif defined(__NetBSD__)
struct kinfo_proc2 proc;
size_t size = sizeof(proc);
- if(sysctl(
- (int[]){CTL_KERN, KERN_PROC2, KERN_PROC_PID, pid, sizeof(proc), 1}, 6,
- &proc, &size,
- NULL, 0
- ) != 0)
+ if (sysctl(
+ (int[]) { CTL_KERN, KERN_PROC2, KERN_PROC_PID, pid, sizeof(proc), 1 }, 6, &proc, &size, NULL, 0) != 0) {
return "sysctl(KERN_PROC_PID) failed";
+ }
ffStrbufSetS(name, proc.p_comm);
- if (ppid)
- *ppid = (pid_t)proc.p_ppid;
- if (tty)
- {
- if (proc.p_flag & P_CONTROLT)
- {
+ if (ppid) {
+ *ppid = (pid_t) proc.p_ppid;
+ }
+ if (tty) {
+ if (proc.p_flag & P_CONTROLT) {
const char* ttyName = devname(proc.p_tdev, S_IFCHR);
- if (ffStrStartsWith(ttyName, "pts/"))
+ if (ffStrStartsWith(ttyName, "pts/")) {
*tty = (int32_t) strtol(ttyName + strlen("pts/"), NULL, 10);
- else
+ } else {
*tty = -1;
- }
- else
+ }
+ } else {
*tty = -1;
+ }
}
- #elif defined(__sun)
+#elif defined(__sun)
char path[128];
snprintf(path, sizeof(path), "/proc/%d/psinfo", (int) pid);
psinfo_t proc;
- if (ffReadFileData(path, sizeof(proc), &proc) != sizeof(proc))
+ if (ffReadFileData(path, sizeof(proc), &proc) != sizeof(proc)) {
return "ffReadFileData(psinfo) failed";
+ }
ffStrbufSetS(name, proc.pr_fname);
- if (ppid)
+ if (ppid) {
*ppid = proc.pr_ppid;
- if (tty)
+ }
+ if (tty) {
*tty = (int) proc.pr_ttydev;
+ }
- #elif defined(__OpenBSD__)
+#elif defined(__OpenBSD__)
kvm_t* kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, NULL);
int count = 0;
const struct kinfo_proc* proc = kvm_getprocs(kd, KERN_PROC_PID, pid, sizeof(struct kinfo_proc), &count);
- if (proc)
- {
+ if (proc) {
ffStrbufSetS(name, proc->p_comm);
- if (ppid)
+ if (ppid) {
*ppid = proc->p_ppid;
- if (tty)
+ }
+ if (tty) {
*tty = (int) proc->p_tdev;
+ }
}
kvm_close(kd);
- if (!proc)
+ if (!proc) {
return "kvm_getprocs() failed";
+ }
- #elif defined(__HAIKU__)
+#elif defined(__HAIKU__)
team_info info;
- if (get_team_info(pid, &info) == B_OK)
- {
+ if (get_team_info(pid, &info) == B_OK) {
ffStrbufSetS(name, info.name);
- if (ppid)
+ if (ppid) {
*ppid = info.parent;
+ }
}
FF_UNUSED(tty);
- #else
+#else
return "Unsupported platform";
- #endif
+#endif
return NULL;
}
diff --git a/src/common/impl/processing_windows.c b/src/common/impl/processing_windows.c
index e78e4fa561..846276b592 100644
--- a/src/common/impl/processing_windows.c
+++ b/src/common/impl/processing_windows.c
@@ -11,45 +11,44 @@
enum { FF_PIPE_BUFSIZ = 8192 };
-static void argvToCmdline(char* const argv[], FFstrbuf* result)
-{
+static void argvToCmdline(char* const argv[], FFstrbuf* result) {
// From https://gist.github.com/jin-x/cdd641d98887524b091fb1f82a68717d
FF_STRBUF_AUTO_DESTROY temp = ffStrbufCreate();
- for (int i = 0; argv[i] != NULL; i++)
- {
+ for (int i = 0; argv[i] != NULL; i++) {
ffStrbufSetS(&temp, argv[i]);
// Add slash (\) before double quotes (") and duplicate slashes before it
for (
uint32_t pos = ffStrbufFirstIndexC(&temp, '"'), cnt;
pos != temp.length;
- pos = ffStrbufNextIndexC(&temp, pos + cnt * 2, '"')
- ) {
+ pos = ffStrbufNextIndexC(&temp, pos + cnt * 2, '"')) {
cnt = 1;
while (pos > 0 && temp.chars[pos - 1] == '\\') { ++cnt, --pos; }
ffStrbufInsertNC(&temp, pos, cnt, '\\');
}
// Add quotes around string if whitespace chars are present (with slash duplicating at the end of string)
- if (ffStrbufFirstIndexS(&temp, " \t") != temp.length)
- {
+ if (ffStrbufFirstIndexS(&temp, " \t") != temp.length) {
uint32_t pos = temp.length;
uint32_t cnt = 0;
while (pos > 0 && temp.chars[pos - 1] == '\\') { ++cnt, --pos; }
- if (cnt > 0) ffStrbufAppendNC(&temp, cnt, '\\');
+ if (cnt > 0) {
+ ffStrbufAppendNC(&temp, cnt, '\\');
+ }
ffStrbufPrependC(&temp, '"');
ffStrbufAppendC(&temp, '"');
}
// Add space delimiter
- if (i > 0) ffStrbufAppendC(result, ' ');
+ if (i > 0) {
+ ffStrbufAppendC(result, ' ');
+ }
ffStrbufAppend(result, &temp);
ffStrbufClear(&temp);
}
}
-const char* ffProcessSpawn(char* const argv[], bool useStdErr, FFProcessHandle* outHandle)
-{
+const char* ffProcessSpawn(char* const argv[], bool useStdErr, FFProcessHandle* outHandle) {
const int32_t timeout = instance.config.general.processingTimeout;
wchar_t pipeName[32];
@@ -64,39 +63,36 @@ const char* ffProcessSpawn(char* const argv[], bool useStdErr, FFProcessHandle*
FF_PIPE_BUFSIZ,
FF_PIPE_BUFSIZ,
0,
- NULL
- );
- if (hChildPipeRead == INVALID_HANDLE_VALUE)
+ NULL);
+ if (hChildPipeRead == INVALID_HANDLE_VALUE) {
return "CreateNamedPipeW(L\"\\\\.\\pipe\\FASTFETCH-$(PID)\") failed";
+ }
HANDLE hChildPipeWrite = CreateFileW(
pipeName,
GENERIC_WRITE,
0,
- &(SECURITY_ATTRIBUTES){
+ &(SECURITY_ATTRIBUTES) {
.nLength = sizeof(SECURITY_ATTRIBUTES),
.lpSecurityDescriptor = NULL,
.bInheritHandle = TRUE,
},
OPEN_EXISTING,
0,
- NULL
- );
- if (hChildPipeWrite == INVALID_HANDLE_VALUE)
+ NULL);
+ if (hChildPipeWrite == INVALID_HANDLE_VALUE) {
return "CreateFileW(L\"\\\\.\\pipe\\FASTFETCH-$(PID)\") failed";
+ }
PROCESS_INFORMATION piProcInfo = {};
STARTUPINFOW siStartInfo = {
.cb = sizeof(siStartInfo),
.dwFlags = STARTF_USESTDHANDLES,
};
- if (useStdErr)
- {
+ if (useStdErr) {
siStartInfo.hStdOutput = ffGetNullFD();
siStartInfo.hStdError = hChildPipeWrite;
- }
- else
- {
+ } else {
siStartInfo.hStdOutput = hChildPipeWrite;
siStartInfo.hStdError = ffGetNullFD();
}
@@ -107,52 +103,51 @@ const char* ffProcessSpawn(char* const argv[], bool useStdErr, FFProcessHandle*
argvToCmdline(argv, &buf);
uint32_t cmdlineBytes = (buf.length + 1) * sizeof(wchar_t);
cmdline = malloc(cmdlineBytes);
- if (!NT_SUCCESS(RtlUTF8ToUnicodeN(cmdline, cmdlineBytes, NULL, buf.chars, buf.length + 1)))
+ if (!NT_SUCCESS(RtlUTF8ToUnicodeN(cmdline, cmdlineBytes, NULL, buf.chars, buf.length + 1))) {
return "RtlUTF8ToUnicodeN() failed";
+ }
}
BOOL success = CreateProcessW(
- NULL, // application name
- cmdline, // command line
- NULL, // process security attributes
- NULL, // primary thread security attributes
- TRUE, // handles are inherited
- 0, // creation flags
- NULL, // use parent's environment
- NULL, // use parent's current directory
- &siStartInfo, // STARTUPINFO pointer
- &piProcInfo // receives PROCESS_INFORMATION
+ NULL, // application name
+ cmdline, // command line
+ NULL, // process security attributes
+ NULL, // primary thread security attributes
+ TRUE, // handles are inherited
+ 0, // creation flags
+ NULL, // use parent's environment
+ NULL, // use parent's current directory
+ &siStartInfo, // STARTUPINFO pointer
+ &piProcInfo // receives PROCESS_INFORMATION
);
NtClose(hChildPipeWrite);
- if(!success)
- {
- if (GetLastError() == ERROR_FILE_NOT_FOUND)
+ if (!success) {
+ if (GetLastError() == ERROR_FILE_NOT_FOUND) {
return "command not found";
+ }
return "CreateProcessW() failed";
}
NtClose(piProcInfo.hThread); // we don't need the thread handle
- outHandle->pid = piProcInfo.hProcess;
- outHandle->pipeRead = hChildPipeRead;
+ outHandle->pid = piProcInfo.hProcess;
+ outHandle->pipeRead = hChildPipeRead;
hChildPipeRead = INVALID_HANDLE_VALUE; // ownership transferred, don't close it
return NULL;
}
-static void terminateChildProcess(HANDLE hProcess, HANDLE hChildPipeRead, HANDLE hReadEvent, IO_STATUS_BLOCK* piosb)
-{
+static void terminateChildProcess(HANDLE hProcess, HANDLE hChildPipeRead, HANDLE hReadEvent, IO_STATUS_BLOCK* piosb) {
IO_STATUS_BLOCK cancelIosb = {};
- if (NT_SUCCESS(NtCancelIoFileEx(hChildPipeRead, piosb, &cancelIosb)))
- {
- if (hReadEvent)
+ if (NT_SUCCESS(NtCancelIoFileEx(hChildPipeRead, piosb, &cancelIosb))) {
+ if (hReadEvent) {
NtWaitForSingleObject(hReadEvent, FALSE, &(LARGE_INTEGER) { .QuadPart = -100000 }); // wait for cancellation to complete
+ }
}
NtTerminateProcess(hProcess, 1);
}
-const char* ffProcessReadOutput(FFProcessHandle* handle, FFstrbuf* buffer)
-{
+const char* ffProcessReadOutput(FFProcessHandle* handle, FFstrbuf* buffer) {
assert(handle->pipeRead != INVALID_HANDLE_VALUE);
assert(handle->pid != INVALID_HANDLE_VALUE);
@@ -163,14 +158,14 @@ const char* ffProcessReadOutput(FFProcessHandle* handle, FFstrbuf* buffer)
handle->pid = INVALID_HANDLE_VALUE;
handle->pipeRead = INVALID_HANDLE_VALUE;
- if (timeout >= 0 && !NT_SUCCESS(NtCreateEvent(&hReadEvent, EVENT_ALL_ACCESS, NULL, SynchronizationEvent, FALSE)))
+ if (timeout >= 0 && !NT_SUCCESS(NtCreateEvent(&hReadEvent, EVENT_ALL_ACCESS, NULL, SynchronizationEvent, FALSE))) {
return "NtCreateEvent() failed";
+ }
char str[FF_PIPE_BUFSIZ];
uint32_t nRead = 0;
IO_STATUS_BLOCK iosb = {};
- do
- {
+ do {
NTSTATUS status = NtReadFile(
hChildPipeRead,
hReadEvent,
@@ -180,33 +175,29 @@ const char* ffProcessReadOutput(FFProcessHandle* handle, FFstrbuf* buffer)
str,
(ULONG) sizeof(str),
NULL,
- NULL
- );
- if (status == STATUS_PENDING)
- {
- switch (NtWaitForSingleObject(hReadEvent, FALSE, &(LARGE_INTEGER) { .QuadPart = (int64_t) timeout * -10000 }))
- {
- case STATUS_WAIT_0:
- status = iosb.Status;
- break;
-
- case STATUS_TIMEOUT:
- {
- terminateChildProcess(hProcess, hChildPipeRead, hReadEvent, &iosb);
- return "NtReadFile(hChildPipeRead) timed out";
- }
-
- default:
- terminateChildProcess(hProcess, hChildPipeRead, hReadEvent, &iosb);
- return "NtWaitForSingleObject(hReadEvent) failed";
+ NULL);
+ if (status == STATUS_PENDING) {
+ switch (NtWaitForSingleObject(hReadEvent, FALSE, &(LARGE_INTEGER) { .QuadPart = (int64_t) timeout * -10000 })) {
+ case STATUS_WAIT_0:
+ status = iosb.Status;
+ break;
+
+ case STATUS_TIMEOUT: {
+ terminateChildProcess(hProcess, hChildPipeRead, hReadEvent, &iosb);
+ return "NtReadFile(hChildPipeRead) timed out";
+ }
+
+ default:
+ terminateChildProcess(hProcess, hChildPipeRead, hReadEvent, &iosb);
+ return "NtWaitForSingleObject(hReadEvent) failed";
}
}
- if (status == STATUS_PIPE_BROKEN || status == STATUS_END_OF_FILE)
+ if (status == STATUS_PIPE_BROKEN || status == STATUS_END_OF_FILE) {
goto exit;
+ }
- if (!NT_SUCCESS(status))
- {
+ if (!NT_SUCCESS(status)) {
terminateChildProcess(hProcess, hChildPipeRead, NULL, &iosb);
return "NtReadFile(hChildPipeRead) failed";
}
@@ -215,81 +206,75 @@ const char* ffProcessReadOutput(FFProcessHandle* handle, FFstrbuf* buffer)
ffStrbufAppendNS(buffer, nRead, str);
} while (nRead > 0);
-exit:
- {
- PROCESS_BASIC_INFORMATION info = {};
- ULONG size;
- if(NT_SUCCESS(NtQueryInformationProcess(hProcess, ProcessBasicInformation, &info, sizeof(info), &size)))
- {
- assert(size == sizeof(info));
- if (info.ExitStatus != STILL_ACTIVE && info.ExitStatus != 0)
- return "Child process exited with an error";
+exit: {
+ PROCESS_BASIC_INFORMATION info = {};
+ ULONG size;
+ if (NT_SUCCESS(NtQueryInformationProcess(hProcess, ProcessBasicInformation, &info, sizeof(info), &size))) {
+ assert(size == sizeof(info));
+ if (info.ExitStatus != STILL_ACTIVE && info.ExitStatus != 0) {
+ return "Child process exited with an error";
}
- else
- return "NtQueryInformationProcess(ProcessBasicInformation) failed";
+ } else {
+ return "NtQueryInformationProcess(ProcessBasicInformation) failed";
}
+}
return NULL;
}
-bool ffProcessGetInfoWindows(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrbuf* exe, const char** exeName, FFstrbuf* exePath, bool* gui)
-{
+bool ffProcessGetInfoWindows(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrbuf* exe, const char** exeName, FFstrbuf* exePath, bool* gui) {
FF_AUTO_CLOSE_FD HANDLE hProcess = NtCurrentProcess();
- if(pid != 0)
- {
+ if (pid != 0) {
if (!NT_SUCCESS(NtOpenProcess(&hProcess, PROCESS_QUERY_LIMITED_INFORMATION, &(OBJECT_ATTRIBUTES) {
- .Length = sizeof(OBJECT_ATTRIBUTES),
- }, &(CLIENT_ID) { .UniqueProcess = (HANDLE)(uintptr_t) pid })))
+ .Length = sizeof(OBJECT_ATTRIBUTES),
+ },
+ &(CLIENT_ID) { .UniqueProcess = (HANDLE) (uintptr_t) pid }))) {
return false;
+ }
}
- if(ppid)
- {
+ if (ppid) {
PROCESS_BASIC_INFORMATION info = {};
ULONG size;
- if(NT_SUCCESS(NtQueryInformationProcess(hProcess, ProcessBasicInformation, &info, sizeof(info), &size)))
- {
+ if (NT_SUCCESS(NtQueryInformationProcess(hProcess, ProcessBasicInformation, &info, sizeof(info), &size))) {
assert(size == sizeof(info));
- *ppid = (uint32_t)info.InheritedFromUniqueProcessId;
- }
- else
+ *ppid = (uint32_t) info.InheritedFromUniqueProcessId;
+ } else {
return false;
+ }
}
- if(exe)
- {
+ if (exe) {
// TODO: It's possible to query the command line with `NtQueryInformationProcess(60/*ProcessCommandLineInformation*/)` since Windows 8.1
alignas(UNICODE_STRING) uint8_t buffer[4096];
ULONG size;
- if(NT_SUCCESS(NtQueryInformationProcess(hProcess, ProcessImageFileNameWin32, &buffer, sizeof(buffer), &size)))
- {
- UNICODE_STRING* imagePath = (UNICODE_STRING*)buffer;
+ if (NT_SUCCESS(NtQueryInformationProcess(hProcess, ProcessImageFileNameWin32, &buffer, sizeof(buffer), &size))) {
+ UNICODE_STRING* imagePath = (UNICODE_STRING*) buffer;
ffStrbufSetNWS(exe, imagePath->Length / sizeof(wchar_t), imagePath->Buffer);
- if (exePath) ffStrbufSet(exePath, exe);
+ if (exePath) {
+ ffStrbufSet(exePath, exe);
+ }
- if (pname && exeName)
- {
+ if (pname && exeName) {
*exeName = exe->chars + ffStrbufLastIndexC(exe, '\\') + 1;
ffStrbufSetS(pname, *exeName);
}
- }
- else
+ } else {
return false;
+ }
}
- if (gui)
- {
+ if (gui) {
SECTION_IMAGE_INFORMATION info = {};
ULONG size;
- if(NT_SUCCESS(NtQueryInformationProcess(hProcess, ProcessImageInformation, &info, sizeof(info), &size)))
- {
+ if (NT_SUCCESS(NtQueryInformationProcess(hProcess, ProcessImageInformation, &info, sizeof(info), &size))) {
assert(size == sizeof(info));
*gui = info.SubSystemType == IMAGE_SUBSYSTEM_WINDOWS_GUI;
- }
- else
+ } else {
return false;
+ }
}
return true;
diff --git a/src/common/impl/properties.c b/src/common/impl/properties.c
index 8b7859bdbd..33192b75dd 100644
--- a/src/common/impl/properties.c
+++ b/src/common/impl/properties.c
@@ -9,58 +9,60 @@
#include "common/windows/getline.h"
#endif
-bool ffParsePropLinePointer(const char** line, const char* start, FFstrbuf* buffer)
-{
- if(**line == '\0')
+bool ffParsePropLinePointer(const char** line, const char* start, FFstrbuf* buffer) {
+ if (**line == '\0') {
return false;
+ }
- //Skip any amount of whitespace at the begin of line
- while(**line == ' ' || **line == '\t')
+ // Skip any amount of whitespace at the begin of line
+ while (**line == ' ' || **line == '\t') {
++(*line);
+ }
- while(*start != '\0')
- {
+ while (*start != '\0') {
// Any amount of whitespace in the format string matches any amount of whitespace in the line, even none
- if(*start == ' ' || *start == '\t')
- {
- while(*start == ' ' || *start == '\t')
+ if (*start == ' ' || *start == '\t') {
+ while (*start == ' ' || *start == '\t') {
++start;
+ }
- while(**line == ' ' || **line == '\t')
+ while (**line == ' ' || **line == '\t') {
++(*line);
+ }
continue;
}
- //Line doesn't match start, skip it
- if(tolower(**line) != tolower(*start) || **line == '\0')
+ // Line doesn't match start, skip it
+ if (tolower(**line) != tolower(*start) || **line == '\0') {
return false;
+ }
- //Line and start match, continue testing
+ // Line and start match, continue testing
++(*line);
++start;
}
char valueEnd = '\n';
- //Allow faster parsing of XML
- if(*(*line - 1) == '>')
+ // Allow faster parsing of XML
+ if (*(*line - 1) == '>') {
valueEnd = '<';
+ }
- //Skip any amount of whitespace at the begin of the value
- while(**line == ' ' || **line == '\t')
+ // Skip any amount of whitespace at the begin of the value
+ while (**line == ' ' || **line == '\t') {
++(*line);
+ }
- //Allow faster parsing of quotet values
- if(**line == '"' || **line == '\'')
- {
+ // Allow faster parsing of quotet values
+ if (**line == '"' || **line == '\'') {
valueEnd = **line;
++(*line);
}
- //Copy the value to the buffer
- while(**line != valueEnd && **line != '\n' && **line != '\0')
- {
+ // Copy the value to the buffer
+ while (**line != valueEnd && **line != '\n' && **line != '\0') {
ffStrbufAppendC(buffer, **line);
++(*line);
}
@@ -70,17 +72,17 @@ bool ffParsePropLinePointer(const char** line, const char* start, FFstrbuf* buff
return true;
}
-bool ffParsePropLines(const char* lines, const char* start, FFstrbuf* buffer)
-{
- while(!ffParsePropLinePointer(&lines, start, buffer))
- {
- while(*lines != '\0' && *lines != '\n')
+bool ffParsePropLines(const char* lines, const char* start, FFstrbuf* buffer) {
+ while (!ffParsePropLinePointer(&lines, start, buffer)) {
+ while (*lines != '\0' && *lines != '\n') {
++lines;
+ }
- if(*lines == '\0')
+ if (*lines == '\0') {
return false;
+ }
- //Skip '\n'
+ // Skip '\n'
++lines;
}
@@ -91,81 +93,79 @@ bool ffParsePropLines(const char* lines, const char* start, FFstrbuf* buffer)
// Buffers which already contain content are not overwritten
// The last occurrence of start in the first file will be the one used
-bool ffParsePropFileValues(const char* filename, uint32_t numQueries, FFpropquery* queries)
-{
+bool ffParsePropFileValues(const char* filename, uint32_t numQueries, FFpropquery* queries) {
FF_AUTO_CLOSE_FILE FILE* file = fopen(filename, "r");
- if (file == NULL)
+ if (file == NULL) {
return false;
+ }
bool valueStorage[32];
bool* unsetValues = valueStorage;
- if (numQueries > ARRAY_SIZE(valueStorage))
+ if (numQueries > ARRAY_SIZE(valueStorage)) {
unsetValues = malloc(sizeof(bool) * numQueries);
+ }
bool allSet = true;
- for (uint32_t i = 0; i < numQueries; i++)
- {
+ for (uint32_t i = 0; i < numQueries; i++) {
unsetValues[i] = queries[i].buffer->length == 0;
- if (unsetValues[i])
+ if (unsetValues[i]) {
allSet = false;
+ }
}
- if (!allSet)
- {
+ if (!allSet) {
FF_AUTO_FREE char* line = NULL;
size_t len = 0;
- while (getline(&line, &len, file) != -1)
- {
- for(uint32_t i = 0; i < numQueries; i++)
- {
- if(!unsetValues[i])
+ while (getline(&line, &len, file) != -1) {
+ for (uint32_t i = 0; i < numQueries; i++) {
+ if (!unsetValues[i]) {
continue;
+ }
uint32_t currentLength = queries[i].buffer->length;
queries[i].buffer->length = 0;
- if(!ffParsePropLine(line, queries[i].start, queries[i].buffer))
+ if (!ffParsePropLine(line, queries[i].start, queries[i].buffer)) {
queries[i].buffer->length = currentLength;
+ }
}
}
}
- if(unsetValues != valueStorage)
+ if (unsetValues != valueStorage) {
free(unsetValues);
+ }
return true;
}
-bool ffParsePropFileHomeValues(const char* relativeFile, uint32_t numQueries, FFpropquery* queries)
-{
+bool ffParsePropFileHomeValues(const char* relativeFile, uint32_t numQueries, FFpropquery* queries) {
FF_STRBUF_AUTO_DESTROY absolutePath = ffStrbufCreateF("%s/%s", instance.state.platform.homeDir.chars, relativeFile);
return ffParsePropFileValues(absolutePath.chars, numQueries, queries);
}
-bool ffParsePropFileListValues(const FFlist* list, const char* relativeFile, uint32_t numQueries, FFpropquery* queries)
-{
+bool ffParsePropFileListValues(const FFlist* list, const char* relativeFile, uint32_t numQueries, FFpropquery* queries) {
bool foundAFile = false;
- FF_LIST_FOR_EACH(FFstrbuf, dirPrefix, *list)
- {
+ FF_LIST_FOR_EACH (FFstrbuf, dirPrefix, *list) {
const uint32_t dirPrefixLength = dirPrefix->length;
ffStrbufAppendS(dirPrefix, relativeFile);
- if(ffParsePropFileValues(dirPrefix->chars, numQueries, queries))
+ if (ffParsePropFileValues(dirPrefix->chars, numQueries, queries)) {
foundAFile = true;
+ }
ffStrbufSubstrBefore(dirPrefix, dirPrefixLength);
bool allSet = true;
- for(uint32_t k = 0; k < numQueries; k++)
- {
- if(queries[k].buffer->length == 0)
- {
+ for (uint32_t k = 0; k < numQueries; k++) {
+ if (queries[k].buffer->length == 0) {
allSet = false;
break;
}
}
- if(allSet)
+ if (allSet) {
break;
+ }
}
return foundAFile;
diff --git a/src/common/impl/settings.c b/src/common/impl/settings.c
index acb42195b1..e62342ded0 100644
--- a/src/common/impl/settings.c
+++ b/src/common/impl/settings.c
@@ -7,39 +7,38 @@
#include
#ifdef FF_HAVE_GIO
-#include
+ #include
-typedef struct GVariantGetters
-{
+typedef struct GVariantGetters {
FF_LIBRARY_SYMBOL(g_variant_dup_string)
FF_LIBRARY_SYMBOL(g_variant_get_boolean)
FF_LIBRARY_SYMBOL(g_variant_get_int32)
FF_LIBRARY_SYMBOL(g_variant_unref)
} GVariantGetters;
-static FFvariant getGVariantValue(GVariant* variant, FFvarianttype type, const GVariantGetters* variantGetters)
-{
+static FFvariant getGVariantValue(GVariant* variant, FFvarianttype type, const GVariantGetters* variantGetters) {
FFvariant result;
- if(variant == NULL)
+ if (variant == NULL) {
result = FF_VARIANT_NULL;
- else if(type == FF_VARIANT_TYPE_STRING)
- result = (FFvariant) {.strValue = variantGetters->ffg_variant_dup_string(variant, NULL)}; // Dup string, so that variant itself can be freed
- else if(type == FF_VARIANT_TYPE_BOOL)
- result = (FFvariant) {.boolValue = (bool) variantGetters->ffg_variant_get_boolean(variant), .boolValueSet = true};
- else if(type == FF_VARIANT_TYPE_INT)
- result = (FFvariant) {.intValue = variantGetters->ffg_variant_get_int32(variant)};
- else
+ } else if (type == FF_VARIANT_TYPE_STRING) {
+ result = (FFvariant) { .strValue = variantGetters->ffg_variant_dup_string(variant, NULL) }; // Dup string, so that variant itself can be freed
+ } else if (type == FF_VARIANT_TYPE_BOOL) {
+ result = (FFvariant) { .boolValue = (bool) variantGetters->ffg_variant_get_boolean(variant), .boolValueSet = true };
+ } else if (type == FF_VARIANT_TYPE_INT) {
+ result = (FFvariant) { .intValue = variantGetters->ffg_variant_get_int32(variant) };
+ } else {
result = FF_VARIANT_NULL;
+ }
- if(variant)
+ if (variant) {
variantGetters->ffg_variant_unref(variant);
+ }
return result;
}
-typedef struct GSettingsData
-{
+typedef struct GSettingsData {
FF_LIBRARY_SYMBOL(g_settings_schema_source_lookup)
FF_LIBRARY_SYMBOL(g_settings_schema_has_key)
FF_LIBRARY_SYMBOL(g_settings_new_full)
@@ -53,12 +52,10 @@ typedef struct GSettingsData
bool inited;
} GSettingsData;
-static const GSettingsData* getGSettingsData(void)
-{
+static const GSettingsData* getGSettingsData(void) {
static GSettingsData data;
- if (!data.inited)
- {
+ if (!data.inited) {
data.inited = true;
FF_LIBRARY_LOAD(libgsettings, NULL, "libgio-2.0" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_schema_source_lookup, NULL)
@@ -75,56 +72,61 @@ static const GSettingsData* getGSettingsData(void)
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data.variantGetters, g_variant_unref, NULL);
data.schemaSource = data.ffg_settings_schema_source_get_default();
- if (data.schemaSource)
+ if (data.schemaSource) {
libgsettings = NULL;
+ }
}
- if(!data.schemaSource)
+ if (!data.schemaSource) {
return NULL;
+ }
return &data;
}
-FFvariant ffSettingsGetGSettings(const char* schemaName, const char* path, const char* key, FFvarianttype type)
-{
+FFvariant ffSettingsGetGSettings(const char* schemaName, const char* path, const char* key, FFvarianttype type) {
const GSettingsData* data = getGSettingsData();
- if(data == NULL)
+ if (data == NULL) {
return FF_VARIANT_NULL;
+ }
GSettingsSchema* schema = data->ffg_settings_schema_source_lookup(data->schemaSource, schemaName, true);
- if(schema == NULL)
+ if (schema == NULL) {
return FF_VARIANT_NULL;
+ }
- if(data->ffg_settings_schema_has_key(schema, key) == false)
+ if (data->ffg_settings_schema_has_key(schema, key) == false) {
return FF_VARIANT_NULL;
+ }
GSettings* settings = data->ffg_settings_new_full(schema, NULL, path);
- if(settings == NULL)
+ if (settings == NULL) {
return FF_VARIANT_NULL;
+ }
GVariant* variant = data->ffg_settings_get_value(settings, key);
- if(variant != NULL)
+ if (variant != NULL) {
return getGVariantValue(variant, type, &data->variantGetters);
+ }
variant = data->ffg_settings_get_user_value(settings, key);
- if(variant != NULL)
+ if (variant != NULL) {
return getGVariantValue(variant, type, &data->variantGetters);
+ }
variant = data->ffg_settings_get_default_value(settings, key);
return getGVariantValue(variant, type, &data->variantGetters);
}
-#else //FF_HAVE_GIO
-FFvariant ffSettingsGetGSettings(const char* schemaName, const char* path, const char* key, FFvarianttype type)
-{
+#else // FF_HAVE_GIO
+FFvariant ffSettingsGetGSettings(const char* schemaName, const char* path, const char* key, FFvarianttype type) {
FF_UNUSED(schemaName, path, key, type)
return FF_VARIANT_NULL;
}
-#endif //FF_HAVE_GIO
+#endif // FF_HAVE_GIO
#ifdef FF_HAVE_DCONF
-#include
+ #include
-typedef struct DConfData
-{
+typedef struct DConfData {
FF_LIBRARY_SYMBOL(dconf_client_read_full)
FF_LIBRARY_SYMBOL(dconf_client_new)
GVariantGetters variantGetters;
@@ -133,12 +135,10 @@ typedef struct DConfData
bool inited;
} DConfData;
-static const DConfData* getDConfData(void)
-{
+static const DConfData* getDConfData(void) {
static DConfData data;
- if (!data.inited)
- {
+ if (!data.inited) {
data.inited = true;
FF_LIBRARY_LOAD(libdconf, NULL, "libdconf" FF_LIBRARY_EXTENSION, 2);
@@ -150,99 +150,96 @@ static const DConfData* getDConfData(void)
FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data.variantGetters, g_variant_unref, NULL)
data.client = data.ffdconf_client_new();
- if (data.client)
+ if (data.client) {
libdconf = NULL;
+ }
}
- if(!data.client)
+ if (!data.client) {
return NULL;
+ }
return &data;
}
-FFvariant ffSettingsGetDConf(const char* key, FFvarianttype type)
-{
+FFvariant ffSettingsGetDConf(const char* key, FFvarianttype type) {
const DConfData* data = getDConfData();
- if(data == NULL)
+ if (data == NULL) {
return FF_VARIANT_NULL;
+ }
GVariant* variant = data->ffdconf_client_read_full(data->client, key, DCONF_READ_FLAGS_NONE, NULL);
- if(variant != NULL)
+ if (variant != NULL) {
return getGVariantValue(variant, type, &data->variantGetters);
+ }
variant = data->ffdconf_client_read_full(data->client, key, DCONF_READ_USER_VALUE, NULL);
- if(variant != NULL)
+ if (variant != NULL) {
return getGVariantValue(variant, type, &data->variantGetters);
+ }
variant = data->ffdconf_client_read_full(data->client, key, DCONF_READ_DEFAULT_VALUE, NULL);
return getGVariantValue(variant, type, &data->variantGetters);
}
-#else //FF_HAVE_DCONF
-FFvariant ffSettingsGetDConf(const char* key, FFvarianttype type)
-{
+#else // FF_HAVE_DCONF
+FFvariant ffSettingsGetDConf(const char* key, FFvarianttype type) {
FF_UNUSED(key, type)
return FF_VARIANT_NULL;
}
-#endif //FF_HAVE_DCONF
+#endif // FF_HAVE_DCONF
-FFvariant ffSettingsGetGnome(const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type)
-{
+FFvariant ffSettingsGetGnome(const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type) {
FFvariant gsettings = ffSettingsGetGSettings(gsettingsSchemaName, gsettingsPath, gsettingsKey, type);
- if(
+ if (
(type == FF_VARIANT_TYPE_BOOL && gsettings.boolValueSet) ||
- (type != FF_VARIANT_TYPE_BOOL && gsettings.strValue != NULL)
- ) return gsettings;
+ (type != FF_VARIANT_TYPE_BOOL && gsettings.strValue != NULL)) {
+ return gsettings;
+ }
return ffSettingsGetDConf(dconfKey, type);
}
#ifdef FF_HAVE_DBUS
-#include "common/dbus.h"
+ #include "common/dbus.h"
-FFvariant ffSettingsGetXFConf(const char* channelName, const char* propertyName, FFvarianttype type)
-{
+FFvariant ffSettingsGetXFConf(const char* channelName, const char* propertyName, FFvarianttype type) {
FF_DBUS_AUTO_DESTROY_DATA FFDBusData dbus = {};
- if (ffDBusLoadData(DBUS_BUS_SESSION, &dbus) != NULL)
+ if (ffDBusLoadData(DBUS_BUS_SESSION, &dbus) != NULL) {
return FF_VARIANT_NULL;
+ }
DBusMessage* reply = ffDBusGetMethodReply(&dbus, "org.xfce.Xfconf", "/org/xfce/Xfconf", "org.xfce.Xfconf", "GetProperty", channelName, propertyName);
- if(!reply)
+ if (!reply) {
return FF_VARIANT_NULL;
+ }
DBusMessageIter rootIterator;
- if(!dbus.lib->ffdbus_message_iter_init(reply, &rootIterator))
- {
+ if (!dbus.lib->ffdbus_message_iter_init(reply, &rootIterator)) {
dbus.lib->ffdbus_message_unref(reply);
return FF_VARIANT_NULL;
}
- if(type == FF_VARIANT_TYPE_INT)
- {
+ if (type == FF_VARIANT_TYPE_INT) {
int32_t value;
- if (ffDBusGetInt(&dbus, &rootIterator, &value))
- {
+ if (ffDBusGetInt(&dbus, &rootIterator, &value)) {
dbus.lib->ffdbus_message_unref(reply);
return (FFvariant) { .intValue = value };
}
return FF_VARIANT_NULL;
}
- if(type == FF_VARIANT_TYPE_STRING)
- {
+ if (type == FF_VARIANT_TYPE_STRING) {
FFstrbuf value = ffStrbufCreate();
- if (ffDBusGetString(&dbus, &rootIterator, &value))
- {
+ if (ffDBusGetString(&dbus, &rootIterator, &value)) {
dbus.lib->ffdbus_message_unref(reply);
return (FFvariant) { .strValue = value.chars }; // Leaks value.chars
}
return FF_VARIANT_NULL;
}
- if(type == FF_VARIANT_TYPE_BOOL)
- {
+ if (type == FF_VARIANT_TYPE_BOOL) {
bool value;
- if (ffDBusGetBool(&dbus, &rootIterator, &value))
- {
+ if (ffDBusGetBool(&dbus, &rootIterator, &value)) {
dbus.lib->ffdbus_message_unref(reply);
return (FFvariant) { .boolValue = value, .boolValueSet = true };
}
@@ -251,26 +248,26 @@ FFvariant ffSettingsGetXFConf(const char* channelName, const char* propertyName,
return FF_VARIANT_NULL;
}
-#define FF_DBUS_ITER_CONTINUE(dbus, iterator) \
- { \
- if(!(dbus).lib->ffdbus_message_iter_next(iterator)) \
- break; \
- continue; \
- }
+ #define FF_DBUS_ITER_CONTINUE(dbus, iterator) \
+ { \
+ if (!(dbus).lib->ffdbus_message_iter_next(iterator)) \
+ break; \
+ continue; \
+ }
-FFvariant ffSettingsGetXFConfFirstMatch(const char* channelName, const char* propertyPrefix, FFvarianttype type, void* data, FFTestXfconfPropCallback* cb)
-{
+FFvariant ffSettingsGetXFConfFirstMatch(const char* channelName, const char* propertyPrefix, FFvarianttype type, void* data, FFTestXfconfPropCallback* cb) {
FF_DBUS_AUTO_DESTROY_DATA FFDBusData dbus = {};
- if (ffDBusLoadData(DBUS_BUS_SESSION, &dbus) != NULL)
+ if (ffDBusLoadData(DBUS_BUS_SESSION, &dbus) != NULL) {
return FF_VARIANT_NULL;
+ }
DBusMessage* reply = ffDBusGetMethodReply(&dbus, "org.xfce.Xfconf", "/org/xfce/Xfconf", "org.xfce.Xfconf", "GetAllProperties", channelName, propertyPrefix);
- if(!reply)
+ if (!reply) {
return FF_VARIANT_NULL;
+ }
DBusMessageIter rootIterator;
- if(!dbus.lib->ffdbus_message_iter_init(reply, &rootIterator))
- {
+ if (!dbus.lib->ffdbus_message_iter_init(reply, &rootIterator)) {
dbus.lib->ffdbus_message_unref(reply);
return FF_VARIANT_NULL;
}
@@ -278,10 +275,10 @@ FFvariant ffSettingsGetXFConfFirstMatch(const char* channelName, const char* pro
DBusMessageIter arrayIterator;
dbus.lib->ffdbus_message_iter_recurse(&rootIterator, &arrayIterator);
- while(true)
- {
- if(dbus.lib->ffdbus_message_iter_get_arg_type(&arrayIterator) != DBUS_TYPE_DICT_ENTRY)
+ while (true) {
+ if (dbus.lib->ffdbus_message_iter_get_arg_type(&arrayIterator) != DBUS_TYPE_DICT_ENTRY) {
FF_DBUS_ITER_CONTINUE(dbus, &arrayIterator)
+ }
DBusMessageIter dictIterator;
dbus.lib->ffdbus_message_iter_recurse(&arrayIterator, &dictIterator);
@@ -289,36 +286,32 @@ FFvariant ffSettingsGetXFConfFirstMatch(const char* channelName, const char* pro
const char* key;
dbus.lib->ffdbus_message_iter_get_basic(&dictIterator, &key);
- if (cb(data, key)) FF_DBUS_ITER_CONTINUE(dbus, &arrayIterator)
+ if (cb(data, key)) {
+ FF_DBUS_ITER_CONTINUE(dbus, &arrayIterator)
+ }
dbus.lib->ffdbus_message_iter_next(&dictIterator);
- if(type == FF_VARIANT_TYPE_INT)
- {
+ if (type == FF_VARIANT_TYPE_INT) {
int32_t value;
- if (ffDBusGetInt(&dbus, &dictIterator, &value))
- {
+ if (ffDBusGetInt(&dbus, &dictIterator, &value)) {
dbus.lib->ffdbus_message_unref(reply);
return (FFvariant) { .intValue = value };
}
return FF_VARIANT_NULL;
}
- if(type == FF_VARIANT_TYPE_STRING)
- {
+ if (type == FF_VARIANT_TYPE_STRING) {
FFstrbuf value = ffStrbufCreate();
- if (ffDBusGetString(&dbus, &dictIterator, &value))
- {
+ if (ffDBusGetString(&dbus, &dictIterator, &value)) {
dbus.lib->ffdbus_message_unref(reply);
return (FFvariant) { .strValue = value.chars }; // Leaks value.chars
}
return FF_VARIANT_NULL;
}
- if(type == FF_VARIANT_TYPE_BOOL)
- {
+ if (type == FF_VARIANT_TYPE_BOOL) {
bool value;
- if (ffDBusGetBool(&dbus, &dictIterator, &value))
- {
+ if (ffDBusGetBool(&dbus, &dictIterator, &value)) {
dbus.lib->ffdbus_message_unref(reply);
return (FFvariant) { .boolValue = value, .boolValueSet = true };
}
@@ -329,24 +322,21 @@ FFvariant ffSettingsGetXFConfFirstMatch(const char* channelName, const char* pro
return FF_VARIANT_NULL;
}
-#else //FF_HAVE_DBUS
-FFvariant ffSettingsGetXFConf(const char* channelName, const char* propertyName, FFvarianttype type)
-{
+#else // FF_HAVE_DBUS
+FFvariant ffSettingsGetXFConf(const char* channelName, const char* propertyName, FFvarianttype type) {
FF_UNUSED(channelName, propertyName, type)
return FF_VARIANT_NULL;
}
-FFvariant ffSettingsGetXFConfFirstMatch(const char* channelName, const char* propertyPrefix, FFvarianttype type, void* data, FFTestXfconfPropCallback* cb)
-{
+FFvariant ffSettingsGetXFConfFirstMatch(const char* channelName, const char* propertyPrefix, FFvarianttype type, void* data, FFTestXfconfPropCallback* cb) {
FF_UNUSED(channelName, propertyPrefix, type, data, cb);
return FF_VARIANT_NULL;
}
-#endif //FF_HAVE_DBUS
+#endif // FF_HAVE_DBUS
#ifdef FF_HAVE_SQLITE3
-#include
+ #include
-typedef struct SQLiteData
-{
+typedef struct SQLiteData {
FF_LIBRARY_SYMBOL(sqlite3_open_v2)
FF_LIBRARY_SYMBOL(sqlite3_prepare_v2)
FF_LIBRARY_SYMBOL(sqlite3_step)
@@ -359,12 +349,10 @@ typedef struct SQLiteData
bool inited;
} SQLiteData;
-static const SQLiteData* getSQLiteData(void)
-{
+static const SQLiteData* getSQLiteData(void) {
static SQLiteData data;
- if (!data.inited)
- {
+ if (!data.inited) {
data.inited = true;
FF_LIBRARY_LOAD(libsqlite, NULL, "libsqlite3" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_open_v2, NULL)
@@ -378,34 +366,35 @@ static const SQLiteData* getSQLiteData(void)
libsqlite = NULL;
}
- if (!data.ffsqlite3_close)
+ if (!data.ffsqlite3_close) {
return NULL;
+ }
return &data;
}
-int ffSettingsGetSQLite3Int(const char* dbPath, const char* query)
-{
- if(!ffPathExists(dbPath, FF_PATHTYPE_FILE))
+int ffSettingsGetSQLite3Int(const char* dbPath, const char* query) {
+ if (!ffPathExists(dbPath, FF_PATHTYPE_FILE)) {
return 0;
+ }
const SQLiteData* data = getSQLiteData();
- if(data == NULL)
+ if (data == NULL) {
return 0;
+ }
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, NULL) != SQLITE_OK) {
return 0;
+ }
sqlite3_stmt* stmt;
- if(data->ffsqlite3_prepare_v2(db, query, (int) strlen(query), &stmt, NULL) != SQLITE_OK)
- {
+ if (data->ffsqlite3_prepare_v2(db, query, (int) strlen(query), &stmt, NULL) != SQLITE_OK) {
data->ffsqlite3_close(db);
return 0;
}
- if(data->ffsqlite3_step(stmt) != SQLITE_ROW || data->ffsqlite3_data_count(stmt) < 1)
- {
+ if (data->ffsqlite3_step(stmt) != SQLITE_ROW || data->ffsqlite3_data_count(stmt) < 1) {
data->ffsqlite3_finalize(stmt);
data->ffsqlite3_close(db);
return 0;
@@ -419,71 +408,72 @@ int ffSettingsGetSQLite3Int(const char* dbPath, const char* query)
return result;
}
-bool ffSettingsGetSQLite3String(const char* dbPath, const char* query, FFstrbuf* result)
-{
- if(!ffPathExists(dbPath, FF_PATHTYPE_FILE))
+bool ffSettingsGetSQLite3String(const char* dbPath, const char* query, FFstrbuf* result) {
+ if (!ffPathExists(dbPath, FF_PATHTYPE_FILE)) {
return false;
+ }
const SQLiteData* data = getSQLiteData();
- if(data == NULL)
+ if (data == NULL) {
return false;
+ }
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, NULL) != SQLITE_OK) {
return false;
+ }
sqlite3_stmt* stmt;
- if(data->ffsqlite3_prepare_v2(db, query, (int) strlen(query), &stmt, NULL) != SQLITE_OK)
- {
+ if (data->ffsqlite3_prepare_v2(db, query, (int) strlen(query), &stmt, NULL) != SQLITE_OK) {
data->ffsqlite3_close(db);
return false;
}
- if(data->ffsqlite3_step(stmt) != SQLITE_ROW || data->ffsqlite3_data_count(stmt) < 1)
- {
+ if (data->ffsqlite3_step(stmt) != SQLITE_ROW || data->ffsqlite3_data_count(stmt) < 1) {
data->ffsqlite3_finalize(stmt);
data->ffsqlite3_close(db);
return false;
}
- ffStrbufSetS(result, (const char *) data->ffsqlite3_column_text(stmt, 0));
+ ffStrbufSetS(result, (const char*) data->ffsqlite3_column_text(stmt, 0));
data->ffsqlite3_finalize(stmt);
data->ffsqlite3_close(db);
return true;
}
-#else //FF_HAVE_SQLITE3
-int ffSettingsGetSQLite3Int(const char* dbPath, const char* query)
-{
+#else // FF_HAVE_SQLITE3
+int ffSettingsGetSQLite3Int(const char* dbPath, const char* query) {
FF_UNUSED(dbPath, query)
return 0;
}
-bool ffSettingsGetSQLite3String(const char* dbPath, const char* query, FFstrbuf* result)
-{
+bool ffSettingsGetSQLite3String(const char* dbPath, const char* query, FFstrbuf* result) {
FF_UNUSED(dbPath, query, result)
return false;
}
-#endif //FF_HAVE_SQLITE3
+#endif // FF_HAVE_SQLITE3
#ifdef __ANDROID__
-#include
+ #include
bool ffSettingsGetAndroidProperty(const char* propName, FFstrbuf* result) {
ffStrbufEnsureFree(result, PROP_VALUE_MAX);
int len = __system_property_get(propName, result->chars + result->length);
- if (len <= 0) return false;
+ if (len <= 0) {
+ return false;
+ }
result->length += (uint32_t) len;
result->chars[result->length] = '\0';
return true;
}
#elif defined(__FreeBSD__)
-#include
-bool ffSettingsGetFreeBSDKenv(const char* propName, FFstrbuf* result)
-{
- //https://wiki.ghostbsd.org/index.php/Kenv
+ #include
+bool ffSettingsGetFreeBSDKenv(const char* propName, FFstrbuf* result) {
+ // https://wiki.ghostbsd.org/index.php/Kenv
ffStrbufEnsureFree(result, KENV_MVALLEN);
int len = kenv(KENV_GET, propName, result->chars + result->length, KENV_MVALLEN);
- if (len <= 1) return false; // number of bytes copied, including NUL terminator
+ if (len <= 1) {
+ return false; // number of bytes copied, including NUL terminator
+ }
result->length += (uint32_t) len - 1;
return true;
}
diff --git a/src/common/impl/size.c b/src/common/impl/size.c
index 89e7e0551f..4e8d1e3711 100644
--- a/src/common/impl/size.c
+++ b/src/common/impl/size.c
@@ -2,43 +2,41 @@
#include
-static void appendNum(FFstrbuf* result, uint64_t bytes, uint32_t base, const char** prefixes)
-{
+static void appendNum(FFstrbuf* result, uint64_t bytes, uint32_t base, const char** prefixes) {
const FFOptionsDisplay* options = &instance.config.display;
double size = (double) bytes;
uint8_t counter = 0;
- while(size >= base && counter < options->sizeMaxPrefix && prefixes[counter + 1])
- {
+ while (size >= base && counter < options->sizeMaxPrefix && prefixes[counter + 1]) {
size /= base;
counter++;
}
- if (counter == 0)
+ if (counter == 0) {
ffStrbufAppendUInt(result, bytes);
- else
+ } else {
ffStrbufAppendDouble(result, size, (int8_t) options->sizeNdigits, true);
- if (options->sizeSpaceBeforeUnit != FF_SPACE_BEFORE_UNIT_NEVER)
+ }
+ if (options->sizeSpaceBeforeUnit != FF_SPACE_BEFORE_UNIT_NEVER) {
ffStrbufAppendC(result, ' ');
+ }
ffStrbufAppendS(result, prefixes[counter]);
}
-void ffSizeAppendNum(uint64_t bytes, FFstrbuf* result)
-{
+void ffSizeAppendNum(uint64_t bytes, FFstrbuf* result) {
const FFOptionsDisplay* options = &instance.config.display;
- switch (options->sizeBinaryPrefix)
- {
+ switch (options->sizeBinaryPrefix) {
case FF_SIZE_BINARY_PREFIX_TYPE_IEC:
- appendNum(result, bytes, 1024, (const char*[]) {"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB", NULL});
+ appendNum(result, bytes, 1024, (const char*[]) { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB", NULL });
break;
case FF_SIZE_BINARY_PREFIX_TYPE_SI:
- appendNum(result, bytes, 1000, (const char*[]) {"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB", NULL});
+ appendNum(result, bytes, 1000, (const char*[]) { "B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB", NULL });
break;
case FF_SIZE_BINARY_PREFIX_TYPE_JEDEC:
- appendNum(result, bytes, 1024, (const char*[]) {"B", "KB", "MB", "GB", "TB", NULL});
+ appendNum(result, bytes, 1024, (const char*[]) { "B", "KB", "MB", "GB", "TB", NULL });
break;
default:
- appendNum(result, bytes, 1024, (const char*[]) {"B", NULL});
+ appendNum(result, bytes, 1024, (const char*[]) { "B", NULL });
break;
}
}
diff --git a/src/common/impl/smbios.c b/src/common/impl/smbios.c
new file mode 100644
index 0000000000..7deeb8f29a
--- /dev/null
+++ b/src/common/impl/smbios.c
@@ -0,0 +1,804 @@
+#include "common/smbios.h"
+#include "common/io.h"
+#include "common/mallocHelper.h"
+#include "common/debug.h"
+
+bool ffIsSmbiosValueSet(FFstrbuf* value) {
+ ffStrbufTrimRightSpace(value);
+ return value->length > 0 &&
+ !ffStrbufStartsWithIgnCaseS(value, "To be filled") &&
+ !ffStrbufStartsWithIgnCaseS(value, "To be set") &&
+ !ffStrbufStartsWithIgnCaseS(value, "OEM") &&
+ !ffStrbufStartsWithIgnCaseS(value, "O.E.M.") &&
+ !ffStrbufStartsWithIgnCaseS(value, "System Product") &&
+ !ffStrbufStartsWithIgnCaseS(value, "Unknown Product") &&
+ !ffStrbufIgnCaseEqualS(value, "None") &&
+ !ffStrbufIgnCaseEqualS(value, "System Name") &&
+ !ffStrbufIgnCaseEqualS(value, "System Version") &&
+ !ffStrbufIgnCaseEqualS(value, "System SKU#") &&
+ !ffStrbufIgnCaseEqualS(value, "Default string") &&
+ !ffStrbufIgnCaseEqualS(value, "Undefined") &&
+ !ffStrbufIgnCaseEqualS(value, "Not Specified") &&
+ !ffStrbufIgnCaseEqualS(value, "Not Applicable") &&
+ !ffStrbufIgnCaseEqualS(value, "Not Defined") &&
+ !ffStrbufIgnCaseEqualS(value, "Not Available") &&
+ !ffStrbufIgnCaseEqualS(value, "INVALID") &&
+ !ffStrbufIgnCaseEqualS(value, "Type1ProductConfigId") &&
+ !ffStrbufIgnCaseEqualS(value, "TBD by OEM") &&
+ !ffStrbufIgnCaseEqualS(value, "No Enclosure") &&
+ !ffStrbufIgnCaseEqualS(value, "Chassis Version") &&
+ !ffStrbufIgnCaseEqualS(value, "All Series") &&
+ !ffStrbufIgnCaseEqualS(value, "N/A") &&
+ !ffStrbufIgnCaseEqualS(value, "Unknown") &&
+ !ffStrbufIgnCaseEqualS(value, "Standard") && ({
+ // Some SMBIOS implementations use "0x0000" to indicate an unset value, even for strings.
+ bool zero = ffStrbufStartsWithS(value, "0x0");
+ if (zero) {
+ for (size_t i = 2; i < value->length; i++) {
+ char c = value->chars[i];
+ if (c != '0') {
+ zero = false;
+ break;
+ }
+ }
+ }
+ !zero;
+ });
+}
+
+static bool smbiosTableInitialized = false;
+static FFSmbiosHeaderTable smbiosTable;
+
+const FFSmbiosHeader* ffSmbiosNextEntry(const FFSmbiosHeader* header) {
+ const char* p = ((const char*) header) + header->Length;
+ if (*p) {
+ do {
+ p += strlen(p) + 1;
+ } while (*p);
+ } else { // The terminator is always double 0 even if there is no string
+ p++;
+ }
+
+ return (const FFSmbiosHeader*) (p + 1);
+}
+
+static bool parseSmbiosTable(const uint8_t* data, uint32_t length) {
+ const FFSmbiosHeader* endOfTable = NULL;
+
+ FF_DEBUG("Parsing SMBIOS table structures with length %u bytes", length);
+ FF_A_UNUSED int structureCount = 0, totalCount = 0;
+ for (
+ const FFSmbiosHeader* header = (const FFSmbiosHeader*) data;
+ (const uint8_t*) header + sizeof(FFSmbiosHeader) < (const uint8_t*) data + length;
+ header = ffSmbiosNextEntry(header)) {
+ ++totalCount;
+ endOfTable = header;
+
+ if (header->Length < sizeof(FFSmbiosHeader)) {
+ FF_DEBUG("Invalid SMBIOS structure length %u at offset 0x%lx",
+ header->Length,
+ (unsigned long) ((const uint8_t*) header - data));
+ break;
+ }
+
+ if (header->Handle >= 0xFF00) {
+ FF_DEBUG("Invalid SMBIOS structure handle 0x%04x at offset 0x%lx",
+ header->Handle,
+ (unsigned long) ((const uint8_t*) header - data));
+ break;
+ }
+
+ // This doesn't verify the entire structure (e.g. string section can still be truncated),
+ // but at least ensures the formatted section is valid and prevents infinite loops
+ // when the table is severely malformed.
+ if (__builtin_expect((const uint8_t*) header + header->Length > (const uint8_t*) data + length, false)) {
+ FF_DEBUG("Truncated SMBIOS structure at offset 0x%lx: length %u is too small",
+ (unsigned long) ((const uint8_t*) header - data),
+ header->Length);
+ break;
+ }
+
+ if (header->Type < FF_SMBIOS_TYPE_END_OF_TABLE) {
+ if (!smbiosTable[header->Type]) {
+ smbiosTable[header->Type] = header;
+ FF_DEBUG("Found SMBIOS structure type %u, handle 0x%04X, length %u",
+ header->Type,
+ header->Handle,
+ header->Length);
+ structureCount++;
+ } else {
+ FF_DEBUG("Duplicate SMBIOS structure type %u, handle 0x%04X, length %u",
+ header->Type,
+ header->Handle,
+ header->Length);
+ }
+ } else if (header->Type == FF_SMBIOS_TYPE_END_OF_TABLE) {
+ FF_DEBUG("Reached SMBIOS end of type %u, handle 0x%04X, length %u",
+ header->Type,
+ header->Handle,
+ header->Length);
+ break;
+ } else {
+ FF_DEBUG("Found custom SMBIOS structure type %u, handle 0x%04X, length %u; ignoring",
+ header->Type,
+ header->Handle,
+ header->Length);
+ }
+ }
+
+ if (!endOfTable) {
+ FF_DEBUG("No SMBIOS structures found in table");
+ return false;
+ }
+
+ FF_DEBUG("Parsed %d/%d SMBIOS structures, end-of-table (Type 127) %s",
+ structureCount,
+ totalCount,
+ endOfTable->Type == FF_SMBIOS_TYPE_END_OF_TABLE ? "found." : "not found! SMBIOS data may be malformed.");
+ smbiosTable[FF_SMBIOS_TYPE_END_OF_TABLE] = endOfTable;
+
+ return true;
+}
+
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__sun) || defined(__HAIKU__) || defined(__OpenBSD__) || defined(__GNU__)
+ #include
+ #include
+ #include
+ #include
+ #include
+
+ #ifdef __linux__
+ #include "common/properties.h"
+ #elif defined(__FreeBSD__)
+ #include "common/settings.h"
+ #elif defined(__NetBSD__)
+ #include "common/sysctl.h"
+ #endif
+
+ #ifdef __linux__
+bool ffGetSmbiosValue(const char* devicesPath, const char* classPath, FFstrbuf* buffer) {
+ // /sys/class/dmi/id/* are all pseudo-files with very small content
+ // so reading the whole file at once is efficient
+ ffStrbufEnsureFixedLengthFree(buffer, 127);
+
+ ssize_t len = ffReadFileData(devicesPath, buffer->allocated - 1, buffer->chars);
+ if (len > 0) {
+ assert(len < buffer->allocated);
+ buffer->chars[len] = '\0';
+ buffer->length = (uint32_t) len;
+ ffStrbufTrimRightSpace(buffer);
+ if (ffIsSmbiosValueSet(buffer)) {
+ return true;
+ }
+ }
+
+ len = ffReadFileData(classPath, buffer->allocated - 1, buffer->chars);
+ if (len > 0) {
+ assert(len < buffer->allocated);
+ buffer->chars[len] = '\0';
+ buffer->length = (uint32_t) len;
+ ffStrbufTrimRightSpace(buffer);
+ if (ffIsSmbiosValueSet(buffer)) {
+ return true;
+ }
+ }
+
+ ffStrbufClear(buffer);
+ return false;
+}
+ #endif
+
+static bool readPhysicalMemory(int fd, off_t address, size_t length, void* buffer) {
+ #if !defined(__FreeBSD__) // Either causes kernel panic or returns EFAULT
+ // -1: unknown, 0: failed before (stop trying), 1: succeeded before
+ static int preadState = -1;
+ if (preadState != 0) {
+ ssize_t bytesRead = pread(fd, buffer, length, address);
+ if (bytesRead == (ssize_t) length) {
+ preadState = 1;
+ return true;
+ }
+
+ FF_DEBUG("pread failed at address 0x%lx for %zu bytes: %s. Falling back to mmap%s",
+ (unsigned long) address,
+ length,
+ strerror(errno),
+ preadState < 0 ? " and caching failure" : "");
+ preadState = 0;
+ } else {
+ FF_DEBUG("Skipping pread due to cached failure; using mmap");
+ }
+ #endif
+
+ off_t alignedAddress = address & ~((off_t) instance.state.platform.sysinfo.pageSize - 1);
+ size_t pageOffset = (size_t) (address - alignedAddress);
+ size_t mapLength = pageOffset + length;
+
+ void* p = mmap(NULL, mapLength, PROT_READ, MAP_SHARED, fd, alignedAddress);
+ if (p == MAP_FAILED) {
+ FF_DEBUG("mmap failed at aligned address 0x%lx for %zu bytes: %s",
+ (unsigned long) alignedAddress,
+ mapLength,
+ strerror(errno));
+ return false;
+ }
+
+ memcpy(buffer, (const uint8_t*) p + pageOffset, length);
+ munmap(p, mapLength);
+ return true;
+}
+
+typedef struct FFSmbios20EntryPoint {
+ uint8_t AnchorString[4];
+ uint8_t EntryPointStructureChecksum;
+ uint8_t EntryPointLength;
+ uint8_t SmbiosMajorVersion;
+ uint8_t SmbiosMinorVersion;
+ uint16_t MaximumStructureSize;
+ uint8_t EntryPointRevision;
+ uint8_t FormattedArea[5];
+ uint8_t IntermediateAnchorString[5];
+ uint8_t IntermediateChecksum;
+ uint16_t StructureTableLength;
+ uint32_t StructureTableAddress;
+ uint16_t NumberOfSmbiosStructures;
+ uint8_t SmbiosBcdRevision;
+} FF_A_PACKED FFSmbios20EntryPoint;
+static_assert(offsetof(FFSmbios20EntryPoint, SmbiosBcdRevision) == 0x1E,
+ "FFSmbios20EntryPoint: Wrong struct alignment");
+
+typedef struct FFSmbios30EntryPoint {
+ uint8_t AnchorString[5];
+ uint8_t EntryPointStructureChecksum;
+ uint8_t EntryPointLength;
+ uint8_t SmbiosMajorVersion;
+ uint8_t SmbiosMinorVersion;
+ uint8_t SmbiosDocrev;
+ uint8_t EntryPointRevision;
+ uint8_t Reversed;
+ uint32_t StructureTableMaximumSize;
+ uint64_t StructureTableAddress;
+} FF_A_PACKED FFSmbios30EntryPoint;
+
+static_assert(offsetof(FFSmbios30EntryPoint, StructureTableAddress) == 0x10,
+ "FFSmbios30EntryPoint: Wrong struct alignment");
+
+typedef union FFSmbiosEntryPoint {
+ FFSmbios20EntryPoint Smbios20;
+ FFSmbios30EntryPoint Smbios30;
+} FFSmbiosEntryPoint;
+
+static bool fillTableBufferFallback(FFstrbuf* buffer) {
+ const char* devMem =
+ #if __HAIKU__
+ "/dev/misc/mem";
+ #else
+ "/dev/mem"; // kern.securelevel must be -1
+ #endif
+ FF_DEBUG("Using physical memory searching implementation: %s", devMem);
+
+ uint32_t tableLength = 0;
+ off_t tableAddress = 0;
+ FF_AUTO_CLOSE_FD int fd = open(devMem, O_RDONLY | O_CLOEXEC);
+ if (fd < 0) {
+ FF_DEBUG("Failed to open memory device: %s", strerror(errno));
+ return false;
+ }
+ FF_DEBUG("Memory device opened successfully with fd=%d", fd);
+
+ // Works on legacy BIOS only
+ // See: https://wiki.osdev.org/System_Management_BIOS#UEFI_systems
+ // On BSD systems, we can get EFI system resource table (ESRT) via EFIIOC_GET_TABLE
+ // However, to acquire SMBIOS entry point, we need EFI configuration table (provided by EFI system table)
+ // which is not available via EFIIOC_GET_TABLE.
+ FF_AUTO_FREE uint8_t* smBiosBase = malloc(0x10000);
+ if (!readPhysicalMemory(fd, 0xF0000, 0x10000, smBiosBase)) {
+ FF_DEBUG("Failed to read SMBIOS memory region");
+ return false;
+ }
+ FF_DEBUG("Successfully read 0x10000 bytes from physical address 0xF0000");
+
+ for (off_t offset = 0; offset <= 0xffe0; offset += 0x10) {
+ FFSmbiosEntryPoint* p = (void*) (smBiosBase + offset);
+ if (memcmp(p, "_SM3_", sizeof(p->Smbios30.AnchorString)) == 0) {
+ FF_DEBUG("Found SMBIOS 3.0 entry point at phyaddr 0x%05lX", (unsigned long) (0xF0000 + offset));
+ if (p->Smbios30.EntryPointLength != sizeof(p->Smbios30)) {
+ FF_DEBUG("Invalid SMBIOS 3.0 entry point length: %u (expected %zu)",
+ p->Smbios30.EntryPointLength,
+ sizeof(p->Smbios30));
+ return false;
+ }
+ tableLength = p->Smbios30.StructureTableMaximumSize;
+ tableAddress = (off_t) p->Smbios30.StructureTableAddress;
+ FF_DEBUG("SMBIOS 3.0: tableLength=0x%x, tableAddress=0x%lx, version=%u.%u.%u",
+ tableLength,
+ (unsigned long) tableAddress,
+ p->Smbios30.SmbiosMajorVersion,
+ p->Smbios30.SmbiosMinorVersion,
+ p->Smbios30.SmbiosDocrev);
+ break;
+ } else if (memcmp(p, "_SM_", sizeof(p->Smbios20.AnchorString)) == 0) {
+ FF_DEBUG("Found SMBIOS 2.0 entry point at phyaddr 0x%05lX", (unsigned long) (0xF0000 + offset));
+ if (p->Smbios20.EntryPointLength != sizeof(p->Smbios20)) {
+ FF_DEBUG("Invalid SMBIOS 2.0 entry point length: %u (expected %zu)",
+ p->Smbios20.EntryPointLength,
+ sizeof(p->Smbios20));
+ return false;
+ }
+ tableLength = p->Smbios20.StructureTableLength;
+ tableAddress = (off_t) p->Smbios20.StructureTableAddress;
+ FF_DEBUG("SMBIOS 2.0: tableLength=0x%x, tableAddress=0x%lx, version=%u.%u",
+ tableLength,
+ (unsigned long) tableAddress,
+ p->Smbios20.SmbiosMajorVersion,
+ p->Smbios20.SmbiosMinorVersion);
+ break;
+ }
+ }
+ if (tableLength == 0) {
+ FF_DEBUG("No valid SMBIOS entry point found in memory region");
+ return false;
+ }
+
+ ffStrbufClear(buffer);
+ ffStrbufEnsureFixedLengthFree(buffer, tableLength);
+ FF_DEBUG("Attempting to read SMBIOS table data: %u bytes at 0x%lx", tableLength, (unsigned long) tableAddress);
+ if (readPhysicalMemory(fd, (off_t) tableAddress, tableLength, buffer->chars)) {
+ buffer->length = tableLength;
+ buffer->chars[buffer->length] = '\0';
+ FF_DEBUG("Successfully read SMBIOS table data: %u bytes", tableLength);
+ } else {
+ FF_DEBUG("Failed to read SMBIOS table data");
+ return false;
+ }
+
+ return true;
+}
+
+ #ifdef __OpenBSD__
+static bool detectSmbiosTableLength(const uint8_t* data, uint32_t bufferLength, uint32_t* tableLength) {
+ const uint8_t* p = data;
+ const uint8_t* end = data + bufferLength;
+
+ while (p + sizeof(FFSmbiosHeader) <= end) {
+ const FFSmbiosHeader* header = (const FFSmbiosHeader*) p;
+ if (header->Length < sizeof(*header)) {
+ FF_DEBUG("Invalid SMBIOS structure length %u at offset 0x%lx",
+ header->Length,
+ (unsigned long) (p - data));
+ return false;
+ }
+
+ if (header->Handle >= 0xFF00) {
+ FF_DEBUG("Invalid SMBIOS structure handle 0x%04x at offset 0x%lx",
+ header->Handle,
+ (unsigned long) (p - data));
+ return false;
+ }
+
+ const uint8_t* formattedEnd = p + header->Length;
+ if (formattedEnd > end) {
+ FF_DEBUG("Truncated SMBIOS structure at offset 0x%lx: length %u is too small",
+ (unsigned long) (p - data),
+ header->Length);
+ return false;
+ }
+
+ const char* string = (const char*) formattedEnd;
+ const char* stringEnd = (const char*) end;
+ while (true) {
+ size_t remaining = (size_t) (stringEnd - string);
+ if (remaining == 0) {
+ return false;
+ }
+
+ const char* nul = memchr(string, '\0', remaining);
+ if (!nul) {
+ return false;
+ }
+
+ string = nul + 1;
+ if (string >= stringEnd) {
+ return false;
+ }
+
+ if (*string == '\0') {
+ ++string;
+ break;
+ }
+ }
+
+ if (header->Type == FF_SMBIOS_TYPE_END_OF_TABLE) {
+ *tableLength = (uint32_t) (string - (const char*) data);
+ return true;
+ }
+
+ p = (const uint8_t*) string;
+ }
+
+ return false;
+}
+
+static bool fillTableBufferPlatform(FFstrbuf* buffer) {
+ FF_DEBUG("Using OpenBSD /var/run/dmesg.boot implementation");
+
+ char dmesg[2048];
+ ssize_t size = ffReadFileData("/var/run/dmesg.boot", sizeof(dmesg) - 1, dmesg);
+ if (size <= 0) {
+ FF_DEBUG("Failed to read /var/run/dmesg.boot");
+ return false;
+ } else {
+ FF_DEBUG("Successfully read %zd bytes from /var/run/dmesg.boot", size);
+ }
+ dmesg[size] = '\0';
+
+ const char* const needle = "\nbios0 at mainbus0: SMBIOS rev. ";
+ size_t needleLen = strlen(needle);
+ char* line = memmem(dmesg, (size_t) size, needle, needleLen);
+ if (!line) {
+ FF_DEBUG("Failed to find SMBIOS line in /var/run/dmesg.boot");
+ return false;
+ }
+ line += needleLen;
+
+ char* lineEnd = memchr(line, '\n', (size_t) ((dmesg + size) - line));
+ if (!lineEnd) {
+ lineEnd = dmesg + size;
+ }
+
+ char* address = memchr(line, '@', (size_t) (lineEnd - line));
+ if (!address) {
+ FF_DEBUG("Failed to find SMBIOS table address in dmesg line");
+ return false;
+ }
+
+ do {
+ ++address;
+ } while (address < lineEnd && (*address == ' ' || *address == '\t'));
+
+ errno = 0;
+ char* addressEnd = NULL;
+ unsigned long long parsedAddress = strtoull(address, &addressEnd, 16);
+ if (errno != 0 || addressEnd == address || parsedAddress == 0) {
+ FF_DEBUG("Failed to parse OpenBSD SMBIOS table address from line: %.*s",
+ (int) (lineEnd - line),
+ line);
+ return false;
+ }
+
+ off_t tableAddress = (off_t) parsedAddress;
+ FF_DEBUG("Parsed OpenBSD SMBIOS table address: 0x%llx", parsedAddress);
+
+ FF_AUTO_CLOSE_FD int fd = open("/dev/mem", O_RDONLY | O_CLOEXEC);
+ if (fd < 0) {
+ FF_DEBUG("Failed to open /dev/mem: %s", strerror(errno));
+ return false;
+ }
+
+ uint32_t readLength = 0x10000;
+ ffStrbufClear(buffer);
+ ffStrbufEnsureFixedLengthFree(buffer, readLength);
+
+ FF_DEBUG("Attempting to read OpenBSD SMBIOS table data: %u bytes at 0x%lx",
+ readLength,
+ (unsigned long) tableAddress);
+
+ if (!readPhysicalMemory(fd, tableAddress, readLength, buffer->chars)) {
+ FF_DEBUG("Failed to read OpenBSD SMBIOS table data");
+ return false;
+ }
+
+ uint32_t detectedLength = 0;
+ if (detectSmbiosTableLength((const uint8_t*) buffer->chars, readLength, &detectedLength)) {
+ buffer->length = detectedLength;
+ buffer->chars[buffer->length] = '\0';
+ FF_DEBUG("Determined OpenBSD SMBIOS table length: %u bytes", detectedLength);
+ return true;
+ }
+
+ FF_DEBUG("SMBIOS end-of-table marker not found within first %u bytes; give up", readLength);
+ ffStrbufClear(buffer);
+ return false;
+}
+ #else
+static bool fillTableBufferPlatform(FFstrbuf* buffer) {
+ #if __HAIKU__ && __GNU__
+ return false;
+ #elif defined(__linux__)
+ FF_DEBUG("Using Linux implementation - trying /sys/firmware/dmi/tables/DMI");
+ if (ffAppendFileBuffer("/sys/firmware/dmi/tables/DMI", buffer))
+ return true;
+
+ FF_DEBUG("Failed to read /sys/firmware/dmi/tables/DMI, falling back to memory-mapped implementation");
+ #endif
+
+ {
+ #if !defined(__sun) && !defined(__NetBSD__)
+ FF_DEBUG("Using memory-mapped implementation");
+ FF_STRBUF_AUTO_DESTROY strEntryAddress = ffStrbufCreate();
+ #ifdef __FreeBSD__
+ FF_DEBUG("Using FreeBSD kenv implementation");
+ if (!ffSettingsGetFreeBSDKenv("hint.smbios.0.mem", &strEntryAddress)) {
+ FF_DEBUG("Failed to get SMBIOS address from FreeBSD kenv");
+ return false; // non-UEFI systems
+ }
+ FF_DEBUG("Got SMBIOS address from kenv: %s", strEntryAddress.chars);
+ #elif defined(__linux__)
+ {
+ FF_DEBUG("Using Linux EFI systab implementation");
+ FF_STRBUF_AUTO_DESTROY systab = ffStrbufCreate();
+ if (!ffAppendFileBuffer("/sys/firmware/efi/systab", &systab)) {
+ FF_DEBUG("Failed to read /sys/firmware/efi/systab");
+ return false;
+ }
+ if (!ffParsePropLines(systab.chars, "SMBIOS3=", &strEntryAddress) &&
+ !ffParsePropLines(systab.chars, "SMBIOS=", &strEntryAddress)) {
+ FF_DEBUG("Failed to find SMBIOS entry in systab");
+ return false;
+ }
+ FF_DEBUG("Found SMBIOS entry in systab: %s", strEntryAddress.chars);
+ }
+ #endif
+
+ off_t entryAddress = (off_t) strtol(strEntryAddress.chars, NULL, 16);
+ if (entryAddress == 0) {
+ FF_DEBUG("Invalid SMBIOS entry address: 0");
+ return false;
+ }
+ FF_DEBUG("Parsed SMBIOS entry address: 0x%lx", (unsigned long) entryAddress);
+
+ FF_AUTO_CLOSE_FD int fd = open("/dev/mem", O_RDONLY | O_CLOEXEC);
+ if (fd < 0) {
+ FF_DEBUG("Failed to open /dev/mem: %s", strerror(errno));
+ return false;
+ }
+ FF_DEBUG("/dev/mem opened successfully with fd=%d", fd);
+
+ FFSmbiosEntryPoint entryPoint;
+ FF_DEBUG("Attempting to read %zu bytes from physical address 0x%lx",
+ sizeof(entryPoint),
+ (unsigned long) entryAddress);
+ if (!readPhysicalMemory(fd, entryAddress, sizeof(entryPoint), &entryPoint)) {
+ return false;
+ }
+ FF_DEBUG("Successfully read SMBIOS entry point data");
+ #else
+ // Sun or NetBSD
+ FF_DEBUG("Using %s specific implementation",
+ #ifdef __NetBSD__
+ "NetBSD"
+ #else
+ "SunOS"
+ #endif
+ );
+
+ FF_AUTO_CLOSE_FD int fd = open("/dev/smbios", O_RDONLY | O_CLOEXEC);
+ if (fd < 0) {
+ FF_DEBUG("Failed to open /dev/smbios: %s", strerror(errno));
+ return false;
+ }
+ FF_DEBUG("/dev/smbios opened successfully with fd=%d", fd);
+
+ FFSmbiosEntryPoint entryPoint;
+ #ifdef __NetBSD__
+ off_t addr = (off_t) ffSysctlGetInt64("machdep.smbios", 0);
+ if (addr == 0) {
+ FF_DEBUG("Failed to get SMBIOS address from sysctl");
+ return false;
+ }
+ FF_DEBUG("Got SMBIOS address from sysctl: 0x%lx", (unsigned long) addr);
+
+ if (pread(fd, &entryPoint, sizeof(entryPoint), addr) < 1) {
+ FF_DEBUG("Failed to read SMBIOS entry point: %s", strerror(errno));
+ return false;
+ }
+ FF_DEBUG("Successfully read SMBIOS entry point");
+ #else
+ FF_DEBUG("Reading SMBIOS entry point from /dev/smbios");
+ if (ffReadFDData(fd, sizeof(entryPoint), &entryPoint) < 1) {
+ FF_DEBUG("Failed to read SMBIOS entry point: %s", strerror(errno));
+ return false;
+ }
+ FF_DEBUG("Successfully read SMBIOS entry point");
+ #endif
+ #endif
+
+ uint32_t tableLength = 0;
+ off_t tableAddress = 0;
+ if (memcmp(entryPoint.Smbios20.AnchorString, "_SM_", sizeof(entryPoint.Smbios20.AnchorString)) == 0) {
+ FF_DEBUG("Found SMBIOS 2.0 entry point");
+ if (entryPoint.Smbios20.EntryPointLength != sizeof(entryPoint.Smbios20)) {
+ FF_DEBUG("Invalid SMBIOS 2.0 entry point length: %u (expected %zu)",
+ entryPoint.Smbios20.EntryPointLength,
+ sizeof(entryPoint.Smbios20));
+ return false;
+ }
+ tableLength = entryPoint.Smbios20.StructureTableLength;
+ tableAddress = (off_t) entryPoint.Smbios20.StructureTableAddress;
+ FF_DEBUG("SMBIOS 2.0: tableLength=0x%x, tableAddress=0x%lx, version=%u.%u",
+ tableLength,
+ (unsigned long) tableAddress,
+ entryPoint.Smbios20.SmbiosMajorVersion,
+ entryPoint.Smbios20.SmbiosMinorVersion);
+ } else if (memcmp(entryPoint.Smbios30.AnchorString, "_SM3_", sizeof(entryPoint.Smbios30.AnchorString)) == 0) {
+ FF_DEBUG("Found SMBIOS 3.0 entry point");
+ if (entryPoint.Smbios30.EntryPointLength != sizeof(entryPoint.Smbios30)) {
+ FF_DEBUG("Invalid SMBIOS 3.0 entry point length: %u (expected %zu)",
+ entryPoint.Smbios30.EntryPointLength,
+ sizeof(entryPoint.Smbios30));
+ return false;
+ }
+ tableLength = entryPoint.Smbios30.StructureTableMaximumSize;
+ tableAddress = (off_t) entryPoint.Smbios30.StructureTableAddress;
+ FF_DEBUG("SMBIOS 3.0: tableLength=0x%x, tableAddress=0x%lx, version=%u.%u.%u",
+ tableLength,
+ (unsigned long) tableAddress,
+ entryPoint.Smbios30.SmbiosMajorVersion,
+ entryPoint.Smbios30.SmbiosMinorVersion,
+ entryPoint.Smbios30.SmbiosDocrev);
+ } else {
+ FF_DEBUG("Unknown SMBIOS entry point format");
+ return false; // Dragonfly goes here
+ }
+
+ ffStrbufClear(buffer);
+ ffStrbufEnsureFixedLengthFree(buffer, tableLength);
+ FF_DEBUG("Attempting to read SMBIOS table data: %u bytes at 0x%lx", tableLength, (unsigned long) tableAddress);
+ if (readPhysicalMemory(fd, tableAddress, tableLength, buffer->chars)) {
+ buffer->length = tableLength;
+ buffer->chars[buffer->length] = '\0';
+ FF_DEBUG("Successfully read SMBIOS table data: %u bytes", tableLength);
+ } else {
+ ffStrbufClear(buffer);
+ return false;
+ }
+ }
+
+ return true;
+}
+ #endif
+
+const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable() {
+ static FFstrbuf buffer;
+ if (!smbiosTableInitialized) {
+ smbiosTableInitialized = true;
+ FF_DEBUG("Initializing SMBIOS buffer");
+ ffStrbufInit(&buffer);
+
+ if (!fillTableBufferPlatform(&buffer)) {
+ FF_DEBUG("Platform specific SMBIOS retrieval failed, trying fallback method");
+ if (!fillTableBufferFallback(&buffer)) {
+ FF_DEBUG("Fallback SMBIOS retrieval also failed");
+ ffStrbufDestroy(&buffer);
+ return NULL;
+ }
+ }
+
+ if (!parseSmbiosTable((const uint8_t*) buffer.chars, buffer.length)) {
+ ffStrbufClear(&buffer);
+ }
+ }
+
+ if (buffer.length == 0) {
+ FF_DEBUG("No valid SMBIOS data available");
+ return NULL;
+ }
+
+ return &smbiosTable;
+}
+#elif defined(_WIN32)
+ #include "common/windows/nt.h"
+
+ #pragma GCC diagnostic ignored "-Wmultichar"
+
+typedef struct FFRawSmbiosData {
+ uint8_t Used20CallingMethod;
+ uint8_t SMBIOSMajorVersion;
+ uint8_t SMBIOSMinorVersion;
+ uint8_t DmiRevision;
+ uint32_t Length;
+ uint8_t SMBIOSTableData[];
+} FFRawSmbiosData;
+
+const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable() {
+ static SYSTEM_FIRMWARE_TABLE_INFORMATION* buffer;
+
+ if (!smbiosTableInitialized) {
+ smbiosTableInitialized = true;
+ FF_DEBUG("Initializing Windows SMBIOS buffer");
+
+ FF_DEBUG("Querying system firmware table size with signature 'RSMB'");
+ SYSTEM_FIRMWARE_TABLE_INFORMATION sfti = {
+ .ProviderSignature = 'RSMB',
+ .Action = SystemFirmwareTableGet,
+ };
+ ULONG bufSize = 0;
+ NtQuerySystemInformation(SystemFirmwareTableInformation, &sfti, sizeof(sfti), &bufSize);
+ if (bufSize <= sizeof(FFRawSmbiosData) + sizeof(sfti)) {
+ FF_DEBUG("Invalid firmware table size: %lu (must be > %zu)", bufSize, sizeof(FFRawSmbiosData) + sizeof(sfti));
+ return NULL;
+ }
+ if (bufSize != sfti.TableBufferLength + (ULONG) sizeof(sfti)) {
+ FF_DEBUG("Firmware table size mismatch: NtQuerySystemInformation returned %lu but expected %lu",
+ bufSize,
+ sfti.TableBufferLength + (ULONG) sizeof(sfti));
+ return NULL;
+ }
+ FF_DEBUG("Firmware table size: %lu bytes", bufSize);
+
+ buffer = malloc(bufSize);
+ *buffer = sfti;
+ FF_DEBUG("Allocated buffer for SMBIOS data");
+
+ if (!NT_SUCCESS(NtQuerySystemInformation(SystemFirmwareTableInformation, buffer, bufSize, &bufSize))) {
+ FF_DEBUG("NtQuerySystemInformation(SystemFirmwareTableInformation) failed");
+ free(buffer);
+ buffer = NULL;
+ return NULL;
+ }
+ FFRawSmbiosData* rawData = (FFRawSmbiosData*) buffer->TableBuffer;
+
+ FF_DEBUG("Successfully retrieved SMBIOS data: version %u.%u, length %u bytes",
+ rawData->SMBIOSMajorVersion,
+ rawData->SMBIOSMinorVersion,
+ rawData->Length);
+
+ if (!parseSmbiosTable(rawData->SMBIOSTableData, rawData->Length)) {
+ free(buffer);
+ buffer = NULL;
+ return NULL;
+ }
+ }
+
+ if (!buffer) {
+ FF_DEBUG("No valid SMBIOS data available");
+ return NULL;
+ }
+ return &smbiosTable;
+}
+#elif defined(__APPLE__)
+ #include "common/apple/cf_helpers.h"
+
+const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable() {
+ static CFDataRef smbiosDataBuffer;
+
+ if (!smbiosTableInitialized) {
+ smbiosTableInitialized = true;
+ FF_DEBUG("Initializing SMBIOS buffer on Apple platform");
+
+ FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t registryEntry = IOServiceGetMatchingService(MACH_PORT_NULL, IOServiceMatching("AppleSMBIOS"));
+
+ if (!registryEntry) {
+ FF_DEBUG("IOServiceGetMatchingService() failed to find AppleSMBIOS");
+ return NULL;
+ }
+
+ FF_DEBUG("AppleSMBIOS service found, retrieving SMBIOS data");
+ smbiosDataBuffer = IORegistryEntryCreateCFProperty(registryEntry, CFSTR("SMBIOS"), kCFAllocatorDefault, kNilOptions);
+ if (!smbiosDataBuffer) {
+ FF_DEBUG("IORegistryEntryCreateCFProperty() failed to get SMBIOS data");
+ return NULL;
+ }
+ if (CFGetTypeID(smbiosDataBuffer) != CFDataGetTypeID()) {
+ FF_DEBUG("Unexpected SMBIOS data type: expected CFData");
+ CFRelease(smbiosDataBuffer);
+ smbiosDataBuffer = NULL;
+ return NULL;
+ }
+
+ FF_DEBUG("Successfully retrieved SMBIOS data: %lu bytes", CFDataGetLength(smbiosDataBuffer));
+ if (!parseSmbiosTable((const uint8_t*) CFDataGetBytePtr(smbiosDataBuffer), (uint32_t) CFDataGetLength(smbiosDataBuffer))) {
+ CFRelease(smbiosDataBuffer);
+ smbiosDataBuffer = NULL;
+ return NULL;
+ }
+ }
+
+ if (!smbiosDataBuffer) {
+ FF_DEBUG("No valid SMBIOS data available");
+ return NULL;
+ }
+
+ return &smbiosTable;
+}
+#endif
diff --git a/src/common/impl/smbiosHelper.c b/src/common/impl/smbiosHelper.c
deleted file mode 100644
index a41638ccb4..0000000000
--- a/src/common/impl/smbiosHelper.c
+++ /dev/null
@@ -1,640 +0,0 @@
-#include "common/smbiosHelper.h"
-#include "common/io.h"
-#include "common/unused.h"
-#include "common/mallocHelper.h"
-#include "common/debug.h"
-
-bool ffIsSmbiosValueSet(FFstrbuf* value)
-{
- ffStrbufTrimRightSpace(value);
- return
- value->length > 0 &&
- !ffStrbufStartsWithIgnCaseS(value, "To be filled") &&
- !ffStrbufStartsWithIgnCaseS(value, "To be set") &&
- !ffStrbufStartsWithIgnCaseS(value, "OEM") &&
- !ffStrbufStartsWithIgnCaseS(value, "O.E.M.") &&
- !ffStrbufStartsWithIgnCaseS(value, "System Product") &&
- !ffStrbufStartsWithIgnCaseS(value, "Unknown Product") &&
- !ffStrbufIgnCaseEqualS(value, "None") &&
- !ffStrbufIgnCaseEqualS(value, "System Name") &&
- !ffStrbufIgnCaseEqualS(value, "System Version") &&
- !ffStrbufIgnCaseEqualS(value, "System SKU#") &&
- !ffStrbufIgnCaseEqualS(value, "Default string") &&
- !ffStrbufIgnCaseEqualS(value, "Undefined") &&
- !ffStrbufIgnCaseEqualS(value, "Not Specified") &&
- !ffStrbufIgnCaseEqualS(value, "Not Applicable") &&
- !ffStrbufIgnCaseEqualS(value, "Not Defined") &&
- !ffStrbufIgnCaseEqualS(value, "Not Available") &&
- !ffStrbufIgnCaseEqualS(value, "INVALID") &&
- !ffStrbufIgnCaseEqualS(value, "Type1ProductConfigId") &&
- !ffStrbufIgnCaseEqualS(value, "TBD by OEM") &&
- !ffStrbufIgnCaseEqualS(value, "No Enclosure") &&
- !ffStrbufIgnCaseEqualS(value, "Chassis Version") &&
- !ffStrbufIgnCaseEqualS(value, "All Series") &&
- !ffStrbufIgnCaseEqualS(value, "N/A") &&
- !ffStrbufIgnCaseEqualS(value, "Unknown") &&
- !ffStrbufIgnCaseEqualS(value, "Standard") && ({
- // Some SMBIOS implementations use "0x0000" to indicate an unset value, even for strings.
- bool zero = ffStrbufStartsWithS(value, "0x0");
- if (zero)
- {
- for (size_t i = 2; i < value->length; i++)
- {
- char c = value->chars[i];
- if (c != '0')
- {
- zero = false;
- break;
- }
- }
- }
- !zero;
- })
- ;
-}
-
-static bool smbiosTableInitialized = false;
-static FFSmbiosHeaderTable smbiosTable;
-
-const FFSmbiosHeader* ffSmbiosNextEntry(const FFSmbiosHeader* header)
-{
- const char* p = ((const char*) header) + header->Length;
- if (*p)
- {
- do
- p += strlen(p) + 1;
- while (*p);
- }
- else // The terminator is always double 0 even if there is no string
- p ++;
-
- return (const FFSmbiosHeader*) (p + 1);
-}
-
-static bool parseSmbiosTable(const uint8_t* data, uint32_t length)
-{
- const FFSmbiosHeader* endOfTable = NULL;
-
- FF_DEBUG("Parsing SMBIOS table structures with length %u bytes", length);
- FF_MAYBE_UNUSED int structureCount = 0, totalCount = 0;
- for (
- const FFSmbiosHeader* header = (const FFSmbiosHeader*) data;
- (const uint8_t*) header + sizeof(FFSmbiosHeader) < (const uint8_t*) data + length;
- header = ffSmbiosNextEntry(header)
- )
- {
- ++totalCount;
- endOfTable = header;
-
- // This doesn't verify the entire structure (e.g. string section can still be truncated),
- // but at least ensures the formatted section is valid and prevents infinite loops
- // when the table is severely malformed.
- if (__builtin_expect((const uint8_t*) header + header->Length > (const uint8_t*) data + length, false))
- {
- FF_DEBUG("Truncated SMBIOS structure at offset 0x%lx: length %u is too small",
- (unsigned long)((const uint8_t*) header - data), header->Length);
- break;
- }
-
- if (header->Type < FF_SMBIOS_TYPE_END_OF_TABLE)
- {
- if (!smbiosTable[header->Type])
- {
- smbiosTable[header->Type] = header;
- FF_DEBUG("Found SMBIOS structure type %u, handle 0x%04X, length %u",
- header->Type, header->Handle, header->Length);
- structureCount++;
- }
- else
- {
- FF_DEBUG("Duplicate SMBIOS structure type %u, handle 0x%04X, length %u",
- header->Type, header->Handle, header->Length);
- }
- }
- else if (header->Type == FF_SMBIOS_TYPE_END_OF_TABLE)
- {
- FF_DEBUG("Reached SMBIOS end of type %u, handle 0x%04X, length %u",
- header->Type, header->Handle, header->Length);
- break;
- }
- else
- {
- FF_DEBUG("Found custom SMBIOS structure type %u, handle 0x%04X, length %u; ignoring",
- header->Type, header->Handle, header->Length);
- }
- }
-
- if (!endOfTable)
- {
- FF_DEBUG("No SMBIOS structures found in table");
- return false;
- }
-
- FF_DEBUG("Parsed %d/%d SMBIOS structures, end-of-table (Type 127) %s",
- structureCount,
- totalCount,
- endOfTable->Type == FF_SMBIOS_TYPE_END_OF_TABLE ? "found." : "not found! SMBIOS data may be malformed.");
- smbiosTable[FF_SMBIOS_TYPE_END_OF_TABLE] = endOfTable;
-
- return true;
-}
-
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__sun) || defined(__HAIKU__) || defined(__OpenBSD__) || defined(__GNU__)
-#include
-#include
-#include
-#include
-#include
-
-#ifdef __linux__
- #include "common/properties.h"
-#elif defined(__FreeBSD__)
- #include "common/settings.h"
- #define loff_t off_t // FreeBSD doesn't have loff_t
-#elif defined(__sun)
- #define loff_t off_t
-#elif defined(__NetBSD__)
- #include "common/sysctl.h"
- #define loff_t off_t
-#endif
-
-#ifdef __linux__
-bool ffGetSmbiosValue(const char* devicesPath, const char* classPath, FFstrbuf* buffer)
-{
- // /sys/class/dmi/id/* are all pseudo-files with very small content
- // so reading the whole file at once is efficient
- ffStrbufEnsureFixedLengthFree(buffer, 127);
-
- ssize_t len = ffReadFileData(devicesPath, buffer->allocated - 1, buffer->chars);
- if (len > 0)
- {
- assert(len < buffer->allocated);
- buffer->chars[len] = '\0';
- buffer->length = (uint32_t) len;
- ffStrbufTrimRightSpace(buffer);
- if(ffIsSmbiosValueSet(buffer))
- return true;
- }
-
- len = ffReadFileData(classPath, buffer->allocated - 1, buffer->chars);
- if (len > 0)
- {
- assert(len < buffer->allocated);
- buffer->chars[len] = '\0';
- buffer->length = (uint32_t) len;
- ffStrbufTrimRightSpace(buffer);
- if(ffIsSmbiosValueSet(buffer))
- return true;
- }
-
- ffStrbufClear(buffer);
- return false;
-}
-#endif
-
-typedef struct FFSmbios20EntryPoint
-{
- uint8_t AnchorString[4];
- uint8_t EntryPointStructureChecksum;
- uint8_t EntryPointLength;
- uint8_t SmbiosMajorVersion;
- uint8_t SmbiosMinorVersion;
- uint16_t MaximumStructureSize;
- uint8_t EntryPointRevision;
- uint8_t FormattedArea[5];
- uint8_t IntermediateAnchorString[5];
- uint8_t IntermediateChecksum;
- uint16_t StructureTableLength;
- uint32_t StructureTableAddress;
- uint16_t NumberOfSmbiosStructures;
- uint8_t SmbiosBcdRevision;
-} __attribute__((__packed__)) FFSmbios20EntryPoint;
-static_assert(offsetof(FFSmbios20EntryPoint, SmbiosBcdRevision) == 0x1E,
- "FFSmbios20EntryPoint: Wrong struct alignment");
-
-typedef struct FFSmbios30EntryPoint
-{
- uint8_t AnchorString[5];
- uint8_t EntryPointStructureChecksum;
- uint8_t EntryPointLength;
- uint8_t SmbiosMajorVersion;
- uint8_t SmbiosMinorVersion;
- uint8_t SmbiosDocrev;
- uint8_t EntryPointRevision;
- uint8_t Reversed;
- uint32_t StructureTableMaximumSize;
- uint64_t StructureTableAddress;
-} __attribute__((__packed__)) FFSmbios30EntryPoint;
-
-static_assert(offsetof(FFSmbios30EntryPoint, StructureTableAddress) == 0x10,
- "FFSmbios30EntryPoint: Wrong struct alignment");
-
-typedef union FFSmbiosEntryPoint
-{
- FFSmbios20EntryPoint Smbios20;
- FFSmbios30EntryPoint Smbios30;
-} FFSmbiosEntryPoint;
-
-const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable()
-{
- static FFstrbuf buffer;
-
- if (!smbiosTableInitialized)
- {
- smbiosTableInitialized = true;
- FF_DEBUG("Initializing SMBIOS buffer");
- ffStrbufInit(&buffer);
- #if !__HAIKU__ && !__OpenBSD__ && !__DragonFly__ && !__GNU__
- #ifdef __linux__
- FF_DEBUG("Using Linux implementation - trying /sys/firmware/dmi/tables/DMI");
- if (!ffAppendFileBuffer("/sys/firmware/dmi/tables/DMI", &buffer))
- #endif
- {
- #if !defined(__sun) && !defined(__NetBSD__)
- FF_DEBUG("Using memory-mapped implementation");
- FF_STRBUF_AUTO_DESTROY strEntryAddress = ffStrbufCreate();
- #ifdef __FreeBSD__
- FF_DEBUG("Using FreeBSD kenv implementation");
- if (!ffSettingsGetFreeBSDKenv("hint.smbios.0.mem", &strEntryAddress)) {
- FF_DEBUG("Failed to get SMBIOS address from FreeBSD kenv");
- return NULL;
- }
- FF_DEBUG("Got SMBIOS address from kenv: %s", strEntryAddress.chars);
- #elif defined(__linux__)
- {
- FF_DEBUG("Using Linux EFI systab implementation");
- FF_STRBUF_AUTO_DESTROY systab = ffStrbufCreate();
- if (!ffAppendFileBuffer("/sys/firmware/efi/systab", &systab)) {
- FF_DEBUG("Failed to read /sys/firmware/efi/systab");
- return NULL;
- }
- if (!ffParsePropLines(systab.chars, "SMBIOS3=", &strEntryAddress) &&
- !ffParsePropLines(systab.chars, "SMBIOS=", &strEntryAddress)) {
- FF_DEBUG("Failed to find SMBIOS entry in systab");
- return NULL;
- }
- FF_DEBUG("Found SMBIOS entry in systab: %s", strEntryAddress.chars);
- }
- #endif
-
- loff_t entryAddress = (loff_t) strtol(strEntryAddress.chars, NULL, 16);
- if (entryAddress == 0) {
- FF_DEBUG("Invalid SMBIOS entry address: 0");
- return NULL;
- }
- FF_DEBUG("Parsed SMBIOS entry address: 0x%lx", (unsigned long)entryAddress);
-
- FF_AUTO_CLOSE_FD int fd = open("/dev/mem", O_RDONLY | O_CLOEXEC);
- if (fd < 0) {
- FF_DEBUG("Failed to open /dev/mem: %s", strerror(errno));
- return NULL;
- }
- FF_DEBUG("/dev/mem opened successfully with fd=%d", fd);
-
- FFSmbiosEntryPoint entryPoint;
- FF_DEBUG("Attempting to read %zu bytes from physical address 0x%lx",
- sizeof(entryPoint), (unsigned long)entryAddress);
- if (pread(fd, &entryPoint, sizeof(entryPoint), entryAddress) < 0x10)
- {
- FF_DEBUG("pread failed, trying mmap");
- // `pread /dev/mem` returns EFAULT in FreeBSD
- // https://stackoverflow.com/questions/69372330/how-to-read-dev-mem-using-read
- void* p = mmap(NULL, sizeof(entryPoint), PROT_READ, MAP_SHARED, fd, entryAddress);
- if (p == MAP_FAILED) {
- FF_DEBUG("mmap failed: %s", strerror(errno));
- return NULL;
- }
- memcpy(&entryPoint, p, sizeof(entryPoint));
- munmap(p, sizeof(entryPoint));
- FF_DEBUG("Successfully read entry point data via mmap");
- } else {
- FF_DEBUG("Successfully read entry point data via pread");
- }
- #else
- // Sun or NetBSD
- FF_DEBUG("Using %s specific implementation",
- #ifdef __NetBSD__
- "NetBSD"
- #else
- "SunOS"
- #endif
- );
-
- FF_AUTO_CLOSE_FD int fd = open("/dev/smbios", O_RDONLY | O_CLOEXEC);
- if (fd < 0) {
- FF_DEBUG("Failed to open /dev/smbios: %s", strerror(errno));
- return NULL;
- }
- FF_DEBUG("/dev/smbios opened successfully with fd=%d", fd);
-
- FFSmbiosEntryPoint entryPoint;
- #ifdef __NetBSD__
- off_t addr = (off_t) ffSysctlGetInt64("machdep.smbios", 0);
- if (addr == 0) {
- FF_DEBUG("Failed to get SMBIOS address from sysctl");
- return NULL;
- }
- FF_DEBUG("Got SMBIOS address from sysctl: 0x%lx", (unsigned long)addr);
-
- if (pread(fd, &entryPoint, sizeof(entryPoint), addr) < 1) {
- FF_DEBUG("Failed to read SMBIOS entry point: %s", strerror(errno));
- return NULL;
- }
- FF_DEBUG("Successfully read SMBIOS entry point");
- #else
- FF_DEBUG("Reading SMBIOS entry point from /dev/smbios");
- if (ffReadFDData(fd, sizeof(entryPoint), &entryPoint) < 1) {
- FF_DEBUG("Failed to read SMBIOS entry point: %s", strerror(errno));
- return NULL;
- }
- FF_DEBUG("Successfully read SMBIOS entry point");
- #endif
- #endif
-
- uint32_t tableLength = 0;
- loff_t tableAddress = 0;
- if (memcmp(entryPoint.Smbios20.AnchorString, "_SM_", sizeof(entryPoint.Smbios20.AnchorString)) == 0)
- {
- FF_DEBUG("Found SMBIOS 2.0 entry point");
- if (entryPoint.Smbios20.EntryPointLength != sizeof(entryPoint.Smbios20)) {
- FF_DEBUG("Invalid SMBIOS 2.0 entry point length: %u (expected %zu)",
- entryPoint.Smbios20.EntryPointLength, sizeof(entryPoint.Smbios20));
- return NULL;
- }
- tableLength = entryPoint.Smbios20.StructureTableLength;
- tableAddress = (loff_t) entryPoint.Smbios20.StructureTableAddress;
- FF_DEBUG("SMBIOS 2.0: tableLength=0x%x, tableAddress=0x%lx, version=%u.%u",
- tableLength, (unsigned long)tableAddress,
- entryPoint.Smbios20.SmbiosMajorVersion, entryPoint.Smbios20.SmbiosMinorVersion);
- }
- else if (memcmp(entryPoint.Smbios30.AnchorString, "_SM3_", sizeof(entryPoint.Smbios30.AnchorString)) == 0)
- {
- FF_DEBUG("Found SMBIOS 3.0 entry point");
- if (entryPoint.Smbios30.EntryPointLength != sizeof(entryPoint.Smbios30)) {
- FF_DEBUG("Invalid SMBIOS 3.0 entry point length: %u (expected %zu)",
- entryPoint.Smbios30.EntryPointLength, sizeof(entryPoint.Smbios30));
- return NULL;
- }
- tableLength = entryPoint.Smbios30.StructureTableMaximumSize;
- tableAddress = (loff_t) entryPoint.Smbios30.StructureTableAddress;
- FF_DEBUG("SMBIOS 3.0: tableLength=0x%x, tableAddress=0x%lx, version=%u.%u.%u",
- tableLength, (unsigned long)tableAddress,
- entryPoint.Smbios30.SmbiosMajorVersion, entryPoint.Smbios30.SmbiosMinorVersion, entryPoint.Smbios30.SmbiosDocrev);
- }
- else {
- FF_DEBUG("Unknown SMBIOS entry point format");
- return NULL;
- }
-
- ffStrbufEnsureFixedLengthFree(&buffer, tableLength);
- FF_DEBUG("Attempting to read SMBIOS table data: %u bytes at 0x%lx", tableLength, (unsigned long)tableAddress);
- if (pread(fd, buffer.chars, tableLength, tableAddress) == (ssize_t) tableLength)
- {
- buffer.length = tableLength;
- buffer.chars[buffer.length] = '\0';
- FF_DEBUG("Successfully read SMBIOS table data: %u bytes", tableLength);
- }
- else
- {
- FF_DEBUG("pread failed, trying mmap");
- // entryPoint.StructureTableAddress must be page aligned.
- // Unaligned physical memory access results in all kinds of crashes.
- void* p = mmap(NULL, tableLength, PROT_READ, MAP_SHARED, fd, tableAddress);
- if (p == MAP_FAILED)
- {
- FF_DEBUG("mmap failed: %s", strerror(errno));
- ffStrbufDestroy(&buffer); // free buffer and reset state
- return NULL;
- }
- ffStrbufSetNS(&buffer, tableLength, (char*) p);
- munmap(p, tableLength);
- FF_DEBUG("Successfully read SMBIOS table data via mmap: %u bytes", tableLength);
- }
- }
- #else
- {
- FF_DEBUG("Using %s implementation",
- #if __HAIKU__
- "Haiku"
- #else
- "OpenBSD"
- #endif
- );
-
- uint32_t tableLength = 0;
- off_t tableAddress = 0;
- FF_AUTO_CLOSE_FD int fd = open(
- #if __HAIKU__
- "/dev/misc/mem"
- #else
- "/dev/mem" // kern.securelevel must be -1
- #endif
- , O_RDONLY | O_CLOEXEC);
- if (fd < 0) {
- FF_DEBUG("Failed to open memory device: %s", strerror(errno));
- return NULL;
- }
- FF_DEBUG("Memory device opened successfully with fd=%d", fd);
-
- // Works on legacy BIOS only
- // See: https://wiki.osdev.org/System_Management_BIOS#UEFI_systems
- // On BSD systems, we can get EFI system resource table (ESRT) via EFIIOC_GET_TABLE
- // However, to acquire SMBIOS entry point, we need EFI configuration table (provided by EFI system table)
- // which is not available via EFIIOC_GET_TABLE.
- FF_AUTO_FREE uint8_t* smBiosBase = malloc(0x10000);
- if (pread(fd, smBiosBase, 0x10000, 0xF0000) != 0x10000) {
- FF_DEBUG("Failed to read SMBIOS memory region: %s", strerror(errno));
- return NULL;
- }
- FF_DEBUG("Successfully read 0x10000 bytes from physical address 0xF0000");
-
- for (off_t offset = 0; offset <= 0xffe0; offset += 0x10)
- {
- FFSmbiosEntryPoint* p = (void*)(smBiosBase + offset);
- if (memcmp(p, "_SM3_", sizeof(p->Smbios30.AnchorString)) == 0)
- {
- FF_DEBUG("Found SMBIOS 3.0 entry point at offset 0x%lx", (unsigned long)offset);
- if (p->Smbios30.EntryPointLength != sizeof(p->Smbios30)) {
- FF_DEBUG("Invalid SMBIOS 3.0 entry point length: %u (expected %zu)",
- p->Smbios30.EntryPointLength, sizeof(p->Smbios30));
- return NULL;
- }
- tableLength = p->Smbios30.StructureTableMaximumSize;
- tableAddress = (off_t) p->Smbios30.StructureTableAddress;
- FF_DEBUG("SMBIOS 3.0: tableLength=0x%x, tableAddress=0x%lx, version=%u.%u.%u",
- tableLength, (unsigned long)tableAddress,
- p->Smbios30.SmbiosMajorVersion, p->Smbios30.SmbiosMinorVersion, p->Smbios30.SmbiosDocrev);
- break;
- }
- else if (memcmp(p, "_SM_", sizeof(p->Smbios20.AnchorString)) == 0)
- {
- FF_DEBUG("Found SMBIOS 2.0 entry point at offset 0x%lx", (unsigned long)offset);
- if (p->Smbios20.EntryPointLength != sizeof(p->Smbios20)) {
- FF_DEBUG("Invalid SMBIOS 2.0 entry point length: %u (expected %zu)",
- p->Smbios20.EntryPointLength, sizeof(p->Smbios20));
- return NULL;
- }
- tableLength = p->Smbios20.StructureTableLength;
- tableAddress = (off_t) p->Smbios20.StructureTableAddress;
- FF_DEBUG("SMBIOS 2.0: tableLength=0x%x, tableAddress=0x%lx, version=%u.%u",
- tableLength, (unsigned long)tableAddress,
- p->Smbios20.SmbiosMajorVersion, p->Smbios20.SmbiosMinorVersion);
- break;
- }
- }
- if (tableLength == 0) {
- FF_DEBUG("No valid SMBIOS entry point found in memory region");
- return NULL;
- }
-
- ffStrbufEnsureFixedLengthFree(&buffer, tableLength);
- FF_DEBUG("Attempting to read SMBIOS table data: %u bytes at 0x%lx", tableLength, (unsigned long)tableAddress);
- if (pread(fd, buffer.chars, tableLength, tableAddress) == tableLength)
- {
- buffer.length = tableLength;
- buffer.chars[buffer.length] = '\0';
- FF_DEBUG("Successfully read SMBIOS table data: %u bytes", tableLength);
- }
- else {
- FF_DEBUG("Failed to read SMBIOS table data: %s", strerror(errno));
- return NULL;
- }
- }
- #endif
-
- if (!parseSmbiosTable((const uint8_t*) buffer.chars, buffer.length))
- ffStrbufClear(&buffer);
- }
-
- if (buffer.length == 0) {
- FF_DEBUG("No valid SMBIOS data available");
- return NULL;
- }
-
- return &smbiosTable;
-}
-#elif defined(_WIN32)
-#include "common/windows/nt.h"
-
-#pragma GCC diagnostic ignored "-Wmultichar"
-
-typedef struct FFRawSmbiosData
-{
- uint8_t Used20CallingMethod;
- uint8_t SMBIOSMajorVersion;
- uint8_t SMBIOSMinorVersion;
- uint8_t DmiRevision;
- uint32_t Length;
- uint8_t SMBIOSTableData[];
-} FFRawSmbiosData;
-
-const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable()
-{
- static SYSTEM_FIRMWARE_TABLE_INFORMATION* buffer;
-
- if (!smbiosTableInitialized)
- {
- smbiosTableInitialized = true;
- FF_DEBUG("Initializing Windows SMBIOS buffer");
-
- FF_DEBUG("Querying system firmware table size with signature 'RSMB'");
- SYSTEM_FIRMWARE_TABLE_INFORMATION sfti = {
- .ProviderSignature = 'RSMB',
- .Action = SystemFirmwareTableGet,
- };
- ULONG bufSize = 0;
- NtQuerySystemInformation(SystemFirmwareTableInformation, &sfti, sizeof(sfti), &bufSize);
- if (bufSize <= sizeof(FFRawSmbiosData) + sizeof(sfti)) {
- FF_DEBUG("Invalid firmware table size: %lu (must be > %zu)", bufSize, sizeof(FFRawSmbiosData) + sizeof(sfti));
- return NULL;
- }
- if (bufSize != sfti.TableBufferLength + (ULONG) sizeof(sfti)) {
- FF_DEBUG("Firmware table size mismatch: NtQuerySystemInformation returned %lu but expected %lu",
- bufSize, sfti.TableBufferLength + (ULONG) sizeof(sfti));
- return NULL;
- }
- FF_DEBUG("Firmware table size: %lu bytes", bufSize);
-
- buffer = malloc(bufSize);
- *buffer = sfti;
- FF_DEBUG("Allocated buffer for SMBIOS data");
-
- if (!NT_SUCCESS(NtQuerySystemInformation(SystemFirmwareTableInformation, buffer, bufSize, &bufSize)))
- {
- FF_DEBUG("NtQuerySystemInformation(SystemFirmwareTableInformation) failed");
- free(buffer);
- buffer = NULL;
- return NULL;
- }
- FFRawSmbiosData* rawData = (FFRawSmbiosData*) buffer->TableBuffer;
-
- FF_DEBUG("Successfully retrieved SMBIOS data: version %u.%u, length %u bytes",
- rawData->SMBIOSMajorVersion, rawData->SMBIOSMinorVersion, rawData->Length);
-
- if (!parseSmbiosTable(rawData->SMBIOSTableData, rawData->Length))
- {
- free(buffer);
- buffer = NULL;
- return NULL;
- }
- }
-
- if (!buffer) {
- FF_DEBUG("No valid SMBIOS data available");
- return NULL;
- }
- return &smbiosTable;
-}
-#elif defined(__APPLE__)
-#include "common/apple/cf_helpers.h"
-
-const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable()
-{
- static CFDataRef smbiosDataBuffer;
-
- if (!smbiosTableInitialized)
- {
- smbiosTableInitialized = true;
- FF_DEBUG("Initializing SMBIOS buffer on Apple platform");
-
- FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t registryEntry = IOServiceGetMatchingService(MACH_PORT_NULL, IOServiceMatching("AppleSMBIOS"));
-
- if (!registryEntry)
- {
- FF_DEBUG("IOServiceGetMatchingService() failed to find AppleSMBIOS");
- return NULL;
- }
-
- FF_DEBUG("AppleSMBIOS service found, retrieving SMBIOS data");
- smbiosDataBuffer = IORegistryEntryCreateCFProperty(registryEntry, CFSTR("SMBIOS"), kCFAllocatorDefault, kNilOptions);
- if (!smbiosDataBuffer)
- {
- FF_DEBUG("IORegistryEntryCreateCFProperty() failed to get SMBIOS data");
- return NULL;
- }
- if (CFGetTypeID(smbiosDataBuffer) != CFDataGetTypeID())
- {
- FF_DEBUG("Unexpected SMBIOS data type: expected CFData");
- CFRelease(smbiosDataBuffer);
- smbiosDataBuffer = NULL;
- return NULL;
- }
-
- FF_DEBUG("Successfully retrieved SMBIOS data: %lu bytes", CFDataGetLength(smbiosDataBuffer));
- if (!parseSmbiosTable((const uint8_t*) CFDataGetBytePtr(smbiosDataBuffer), (uint32_t) CFDataGetLength(smbiosDataBuffer)))
- {
- CFRelease(smbiosDataBuffer);
- smbiosDataBuffer = NULL;
- return NULL;
- }
- }
-
- if (!smbiosDataBuffer)
- {
- FF_DEBUG("No valid SMBIOS data available");
- return NULL;
- }
-
- return &smbiosTable;
-}
-#endif
diff --git a/src/common/impl/sysctl.c b/src/common/impl/sysctl.c
index 9b1c52d11a..62268754a0 100644
--- a/src/common/impl/sysctl.c
+++ b/src/common/impl/sysctl.c
@@ -3,86 +3,89 @@
#include
#ifdef __OpenBSD__
-const char* ffSysctlGetString(int mib1, int mib2, FFstrbuf* result)
-{
+const char* ffSysctlGetString(int mib1, int mib2, FFstrbuf* result) {
size_t neededLength;
- if (sysctl((int[]) {mib1, mib2}, 2, NULL, &neededLength, NULL, 0) != 0 || neededLength == 1) //neededLength is 1 for empty strings, because of the null terminator
- return "sysctlbyname() failed";
+ if (sysctl((int[]) { mib1, mib2 }, 2, NULL, &neededLength, NULL, 0) != 0 || neededLength == 1) { // neededLength is 1 for empty strings, because of the null terminator
+ return "sysctl() length query failed";
+ }
ffStrbufEnsureFree(result, (uint32_t) neededLength - 1);
- if (sysctl((int[]) {mib1, mib2}, 2, result->chars + result->length, &neededLength, NULL, 0) == 0)
- result->length += (uint32_t) neededLength - 1;
+ if (sysctl((int[]) { mib1, mib2 }, 2, result->chars + result->length, &neededLength, NULL, 0) != 0) {
+ return "sysctl() failed to retrieve string data";
+ }
+ result->length += (uint32_t) neededLength - 1;
result->chars[result->length] = '\0';
return NULL;
}
-int ffSysctlGetInt(int mib1, int mib2, int defaultValue)
-{
+int ffSysctlGetInt(int mib1, int mib2, int defaultValue) {
int result;
size_t neededLength = sizeof(result);
- if (sysctl((int[]) {mib1, mib2}, 2, &result, &neededLength, NULL, 0) != 0)
+ if (sysctl((int[]) { mib1, mib2 }, 2, &result, &neededLength, NULL, 0) != 0) {
return defaultValue;
+ }
return result;
}
-int64_t ffSysctlGetInt64(int mib1, int mib2, int64_t defaultValue)
-{
+int64_t ffSysctlGetInt64(int mib1, int mib2, int64_t defaultValue) {
int64_t result;
size_t neededLength = sizeof(result);
- if(sysctl((int[]) {mib1, mib2}, 2, &result, &neededLength, NULL, 0) != 0)
+ if (sysctl((int[]) { mib1, mib2 }, 2, &result, &neededLength, NULL, 0) != 0) {
return defaultValue;
+ }
return result;
}
#else
-const char* ffSysctlGetString(const char* propName, FFstrbuf* result)
-{
+const char* ffSysctlGetString(const char* propName, FFstrbuf* result) {
size_t neededLength;
- if(sysctlbyname(propName, NULL, &neededLength, NULL, 0) != 0 || neededLength == 1) //neededLength is 1 for empty strings, because of the null terminator
+ if (sysctlbyname(propName, NULL, &neededLength, NULL, 0) != 0 || neededLength == 1) { // neededLength is 1 for empty strings, because of the null terminator
return "sysctlbyname() failed";
+ }
ffStrbufEnsureFree(result, (uint32_t) neededLength - 1);
- if(sysctlbyname(propName, result->chars + result->length, &neededLength, NULL, 0) == 0)
+ if (sysctlbyname(propName, result->chars + result->length, &neededLength, NULL, 0) == 0) {
result->length += (uint32_t) neededLength - 1;
+ }
result->chars[result->length] = '\0';
return NULL;
}
-int ffSysctlGetInt(const char* propName, int defaultValue)
-{
+int ffSysctlGetInt(const char* propName, int defaultValue) {
int result;
size_t neededLength = sizeof(result);
- if(sysctlbyname(propName, &result, &neededLength, NULL, 0) != 0)
+ if (sysctlbyname(propName, &result, &neededLength, NULL, 0) != 0) {
return defaultValue;
+ }
return result;
}
-int64_t ffSysctlGetInt64(const char* propName, int64_t defaultValue)
-{
+int64_t ffSysctlGetInt64(const char* propName, int64_t defaultValue) {
int64_t result;
size_t neededLength = sizeof(result);
- if(sysctlbyname(propName, &result, &neededLength, NULL, 0) != 0)
+ if (sysctlbyname(propName, &result, &neededLength, NULL, 0) != 0) {
return defaultValue;
+ }
return result;
}
#endif // OpenBSD
-void* ffSysctlGetData(int* request, u_int requestLength, size_t* resultLength)
-{
- if(sysctl(request, requestLength, NULL, resultLength, NULL, 0) != 0)
+void* ffSysctlGetData(int* request, u_int requestLength, size_t* resultLength) {
+ if (sysctl(request, requestLength, NULL, resultLength, NULL, 0) != 0) {
return NULL;
+ }
void* data = malloc(*resultLength);
- if(data == NULL)
+ if (data == NULL) {
return NULL;
+ }
- if(sysctl(request, requestLength, data, resultLength, NULL, 0) != 0)
- {
+ if (sysctl(request, requestLength, data, resultLength, NULL, 0) != 0) {
free(data);
return NULL;
}
diff --git a/src/common/impl/temps.c b/src/common/impl/temps.c
index 29d705aa41..7bb2a66652 100644
--- a/src/common/impl/temps.c
+++ b/src/common/impl/temps.c
@@ -3,10 +3,10 @@
#include "common/textModifier.h"
#include "common/stringUtils.h"
-void ffTempsAppendNum(double celsius, FFstrbuf* buffer, FFColorRangeConfig config, const FFModuleArgs* module)
-{
- if (celsius == -DBL_MAX) // ignores invalid value
+void ffTempsAppendNum(double celsius, FFstrbuf* buffer, FFColorRangeConfig config, const FFModuleArgs* module) {
+ if (celsius == -DBL_MAX) { // ignores invalid value
return;
+ }
const FFOptionsDisplay* options = &instance.config.display;
const char* colorGreen = options->tempColorGreen.chars;
@@ -15,76 +15,68 @@ void ffTempsAppendNum(double celsius, FFstrbuf* buffer, FFColorRangeConfig confi
uint8_t green = config.green, yellow = config.yellow;
- if (!options->pipe)
- {
- if(green <= yellow)
- {
- if (celsius > yellow)
+ if (!options->pipe) {
+ if (green <= yellow) {
+ if (celsius > yellow) {
ffStrbufAppendF(buffer, "\e[%sm", colorRed);
- else if (celsius > green)
+ } else if (celsius > green) {
ffStrbufAppendF(buffer, "\e[%sm", colorYellow);
- else
+ } else {
ffStrbufAppendF(buffer, "\e[%sm", colorGreen);
- }
- else
- {
- if (celsius < yellow)
+ }
+ } else {
+ if (celsius < yellow) {
ffStrbufAppendF(buffer, "\e[%sm", colorRed);
- else if (celsius < green)
+ } else if (celsius < green) {
ffStrbufAppendF(buffer, "\e[%sm", colorYellow);
- else
+ } else {
ffStrbufAppendF(buffer, "\e[%sm", colorGreen);
+ }
}
}
- switch (options->tempUnit)
- {
+ switch (options->tempUnit) {
case FF_TEMPERATURE_UNIT_DEFAULT:
case FF_TEMPERATURE_UNIT_CELSIUS:
- ffStrbufAppendF(buffer, "%.*f%s°C", options->tempNdigits, celsius,
- options->tempSpaceBeforeUnit == FF_SPACE_BEFORE_UNIT_ALWAYS ? " " : "");
+ ffStrbufAppendF(buffer, "%.*f%s°C", options->tempNdigits, celsius, options->tempSpaceBeforeUnit == FF_SPACE_BEFORE_UNIT_ALWAYS ? " " : "");
break;
case FF_TEMPERATURE_UNIT_FAHRENHEIT:
- ffStrbufAppendF(buffer, "%.*f%s°F", options->tempNdigits, celsius * 1.8 + 32,
- options->tempSpaceBeforeUnit == FF_SPACE_BEFORE_UNIT_ALWAYS ? " " : "");
+ ffStrbufAppendF(buffer, "%.*f%s°F", options->tempNdigits, celsius * 1.8 + 32, options->tempSpaceBeforeUnit == FF_SPACE_BEFORE_UNIT_ALWAYS ? " " : "");
break;
case FF_TEMPERATURE_UNIT_KELVIN:
- ffStrbufAppendF(buffer, "%.*f%sK", options->tempNdigits, celsius + 273.15,
- options->tempSpaceBeforeUnit == FF_SPACE_BEFORE_UNIT_NEVER ? "" : " ");
+ ffStrbufAppendF(buffer, "%.*f%sK", options->tempNdigits, celsius + 273.15, options->tempSpaceBeforeUnit == FF_SPACE_BEFORE_UNIT_NEVER ? "" : " ");
break;
}
- if (!options->pipe)
- {
+ if (!options->pipe) {
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
- if (module->outputColor.length)
+ if (module->outputColor.length) {
ffStrbufAppendF(buffer, "\e[%sm", module->outputColor.chars);
- else if (instance.config.display.colorOutput.length)
+ } else if (instance.config.display.colorOutput.length) {
ffStrbufAppendF(buffer, "\e[%sm", instance.config.display.colorOutput.chars);
+ }
}
}
-bool ffTempsParseCommandOptions(const char* key, const char* subkey, const char* value, bool* useTemp, FFColorRangeConfig* config)
-{
- if (!ffStrStartsWithIgnCase(subkey, "temp"))
+bool ffTempsParseCommandOptions(const char* key, const char* subkey, const char* value, bool* useTemp, FFColorRangeConfig* config) {
+ if (!ffStrStartsWithIgnCase(subkey, "temp")) {
return false;
+ }
- if (subkey[strlen("temp")] == '\0')
- {
+ if (subkey[strlen("temp")] == '\0') {
*useTemp = ffOptionParseBoolean(value);
return true;
}
- if (subkey[strlen("temp")] != '-')
+ if (subkey[strlen("temp")] != '-') {
return false;
+ }
subkey += strlen("temp-");
- if (ffStrEqualsIgnCase(subkey, "green"))
- {
+ if (ffStrEqualsIgnCase(subkey, "green")) {
uint32_t num = ffOptionParseUInt32(key, value);
- if (num > 100)
- {
+ if (num > 100) {
fprintf(stderr, "Error: usage: %s must be between 0 and 100\n", key);
exit(480);
}
@@ -92,11 +84,9 @@ bool ffTempsParseCommandOptions(const char* key, const char* subkey, const char*
return true;
}
- if (ffStrEqualsIgnCase(subkey, "yellow"))
- {
+ if (ffStrEqualsIgnCase(subkey, "yellow")) {
uint32_t num = ffOptionParseUInt32(key, value);
- if (num > 100)
- {
+ if (num > 100) {
fprintf(stderr, "Error: usage: %s must be between 0 and 100\n", key);
exit(480);
}
@@ -107,27 +97,24 @@ bool ffTempsParseCommandOptions(const char* key, const char* subkey, const char*
return false;
}
-bool ffTempsParseJsonObject(yyjson_val* key, yyjson_val* value, bool* useTemp, FFColorRangeConfig* config)
-{
+bool ffTempsParseJsonObject(yyjson_val* key, yyjson_val* value, bool* useTemp, FFColorRangeConfig* config) {
assert(key);
- if (!unsafe_yyjson_equals_str(key, "temp"))
+ if (!unsafe_yyjson_equals_str(key, "temp")) {
return false;
+ }
- if (yyjson_is_bool(value))
- {
+ if (yyjson_is_bool(value)) {
*useTemp = yyjson_get_bool(value);
return true;
}
- if (yyjson_is_null(value))
- {
+ if (yyjson_is_null(value)) {
*useTemp = false;
return true;
}
- if (!yyjson_is_obj(value))
- {
+ if (!yyjson_is_obj(value)) {
fprintf(stderr, "Error: usage: %s must be an object or a boolean\n", unsafe_yyjson_get_str(key));
exit(480);
}
@@ -135,11 +122,9 @@ bool ffTempsParseJsonObject(yyjson_val* key, yyjson_val* value, bool* useTemp, F
*useTemp = true;
yyjson_val* greenVal = yyjson_obj_get(value, "green");
- if (greenVal)
- {
+ if (greenVal) {
int num = yyjson_get_int(greenVal);
- if (num < 0 || num > 100)
- {
+ if (num < 0 || num > 100) {
fputs("Error: usage: temp.green must be between 0 and 100\n", stderr);
exit(480);
}
@@ -147,11 +132,9 @@ bool ffTempsParseJsonObject(yyjson_val* key, yyjson_val* value, bool* useTemp, F
}
yyjson_val* yellowVal = yyjson_obj_get(value, "yellow");
- if (yellowVal)
- {
+ if (yellowVal) {
int num = yyjson_get_int(yellowVal);
- if (num < 0 || num > 100)
- {
+ if (num < 0 || num > 100) {
fputs("Error: usage: temp.yellow must be between 0 and 100\n", stderr);
exit(480);
}
@@ -161,12 +144,10 @@ bool ffTempsParseJsonObject(yyjson_val* key, yyjson_val* value, bool* useTemp, F
return true;
}
-void ffTempsGenerateJsonConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, bool temp, FFColorRangeConfig config)
-{
- if (!temp)
+void ffTempsGenerateJsonConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, bool temp, FFColorRangeConfig config) {
+ if (!temp) {
yyjson_mut_obj_add_bool(doc, module, "temp", false);
- else
- {
+ } else {
yyjson_mut_val* temp = yyjson_mut_obj_add_obj(doc, module, "temp");
yyjson_mut_obj_add_uint(doc, temp, "green", config.green);
yyjson_mut_obj_add_uint(doc, temp, "yellow", config.yellow);
diff --git a/src/common/impl/time.c b/src/common/impl/time.c
index a991cb5604..c60d1fecee 100644
--- a/src/common/impl/time.c
+++ b/src/common/impl/time.c
@@ -9,9 +9,10 @@ char ffTimeInternalBuffer[64]; // Reduce memory usage and prevent redundant allo
#pragma GCC diagnostic ignored "-Wformat"
#endif
-const char* ffTimeToFullStr(uint64_t msec)
-{
- if (msec == 0) return "";
+const char* ffTimeToFullStr(uint64_t msec) {
+ if (msec == 0) {
+ return "";
+ }
time_t tsec = (time_t) (msec / 1000);
const struct tm* tm = localtime(&tsec);
@@ -22,18 +23,20 @@ const char* ffTimeToFullStr(uint64_t msec)
return ffTimeInternalBuffer;
}
-const char* ffTimeToShortStr(uint64_t msec)
-{
- if (msec == 0) return "";
+const char* ffTimeToShortStr(uint64_t msec) {
+ if (msec == 0) {
+ return "";
+ }
time_t tsec = (time_t) (msec / 1000);
strftime(ffTimeInternalBuffer, ARRAY_SIZE(ffTimeInternalBuffer), "%F %T", localtime(&tsec));
return ffTimeInternalBuffer;
}
-const char* ffTimeToTimeStr(uint64_t msec)
-{
- if (msec == 0) return "";
+const char* ffTimeToTimeStr(uint64_t msec) {
+ if (msec == 0) {
+ return "";
+ }
time_t tsec = (time_t) (msec / 1000);
uint32_t len = (uint32_t) strftime(ffTimeInternalBuffer, ARRAY_SIZE(ffTimeInternalBuffer), "%T", localtime(&tsec));
@@ -45,31 +48,32 @@ const char* ffTimeToTimeStr(uint64_t msec)
#pragma GCC diagnostic pop
#endif
-FFTimeGetAgeResult ffTimeGetAge(uint64_t birthMs, uint64_t nowMs)
-{
+FFTimeGetAgeResult ffTimeGetAge(uint64_t birthMs, uint64_t nowMs) {
FFTimeGetAgeResult result = {};
- if (__builtin_expect(birthMs == 0 || nowMs < birthMs, 0))
+ if (__builtin_expect(birthMs == 0 || nowMs < birthMs, 0)) {
return result;
+ }
time_t birth_s = (time_t) (birthMs / 1000);
struct tm birth_tm;
- #ifdef _WIN32
+#ifdef _WIN32
localtime_s(&birth_tm, &birth_s);
- #else
+#else
localtime_r(&birth_s, &birth_tm);
- #endif
+#endif
time_t now_s = (time_t) (nowMs / 1000);
struct tm now_tm;
- #ifdef _WIN32
+#ifdef _WIN32
localtime_s(&now_tm, &now_s);
- #else
+#else
localtime_r(&now_s, &now_tm);
- #endif
+#endif
result.years = (uint32_t) (now_tm.tm_year - birth_tm.tm_year);
- if (now_tm.tm_yday < birth_tm.tm_yday)
+ if (now_tm.tm_yday < birth_tm.tm_yday) {
result.years--;
+ }
birth_tm.tm_year += (int) result.years;
birth_s = mktime(&birth_tm);
@@ -83,13 +87,11 @@ FFTimeGetAgeResult ffTimeGetAge(uint64_t birthMs, uint64_t nowMs)
}
#ifdef _WIN32
- double ffQpcMultiplier;
-
- __attribute__((constructor))
- static void ffTimeInitQpcMultiplier(void)
- {
- LARGE_INTEGER frequency;
- RtlQueryPerformanceFrequency(&frequency);
- ffQpcMultiplier = 1000. / (double) frequency.QuadPart;
- }
+double ffQpcMultiplier;
+
+__attribute__((constructor)) static void ffTimeInitQpcMultiplier(void) {
+ LARGE_INTEGER frequency;
+ RtlQueryPerformanceFrequency(&frequency);
+ ffQpcMultiplier = 1000. / (double) frequency.QuadPart;
+}
#endif
diff --git a/src/common/impl/wcwidth.c b/src/common/impl/wcwidth.c
index 5cad57ef6f..5b4a1adc97 100644
--- a/src/common/impl/wcwidth.c
+++ b/src/common/impl/wcwidth.c
@@ -1,8 +1,7 @@
#include "common/wcwidth.h"
#include "3rdparty/widecharwidth/widechar_width_c.h"
-int mk_wcwidth(uint32_t wc)
-{
+int mk_wcwidth(uint32_t wc) {
// // We render U+1F6E1 (🛡) with a width of 2,
// // but widechar_width says it has a width of 1 because Unicode classifies it as "neutral".
// //
diff --git a/src/common/io.h b/src/common/io.h
index 2d2851f00e..f7aec0b42f 100644
--- a/src/common/io.h
+++ b/src/common/io.h
@@ -8,7 +8,7 @@
#include
#include
#include "common/windows/nt.h"
- typedef HANDLE FFNativeFD;
+typedef HANDLE FFNativeFD;
#define FF_INVALID_FD INVALID_HANDLE_VALUE
#else
#include
@@ -17,7 +17,7 @@
#include
#include
#include
- typedef int FFNativeFD;
+typedef int FFNativeFD;
#define FF_INVALID_FD (-1)
// procfs's file can be changed between read calls such as /proc/meminfo and /proc/uptime.
// one safe way to read correct data is reading the whole file in a single read syscall
@@ -40,282 +40,257 @@ HANDLE openat(HANDLE dfd, const char* fileName, int oflag);
HANDLE openatW(HANDLE dfd, const wchar_t* fileName, uint16_t fileNameLen, bool directory);
#endif
-
-static inline bool ffIsValidNativeFD(FFNativeFD fd)
-{
- #ifndef _WIN32
- return fd >= 0;
- #else
- // https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
- return fd != INVALID_HANDLE_VALUE && fd != NULL;
- #endif
+static inline bool ffIsValidNativeFD(FFNativeFD fd) {
+#ifndef _WIN32
+ return fd >= 0;
+#else
+ // https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
+ return fd != INVALID_HANDLE_VALUE && fd != NULL;
+#endif
}
-FF_C_NONNULL(1)
-static inline bool wrapClose(FFNativeFD* pfd)
-{
+FF_A_NONNULL(1) static inline bool wrapClose(FFNativeFD* pfd) {
assert(pfd);
- if (!ffIsValidNativeFD(*pfd))
+ if (!ffIsValidNativeFD(*pfd)) {
return false;
+ }
- #ifndef _WIN32
- close(*pfd);
- #else
- NtClose(*pfd);
- #endif
+#ifndef _WIN32
+ close(*pfd);
+#else
+ NtClose(*pfd);
+#endif
return true;
}
-#define FF_AUTO_CLOSE_FD __attribute__((__cleanup__(wrapClose)))
-
-static inline FFNativeFD FFUnixFD2NativeFD(int unixfd)
-{
- #ifndef _WIN32
- return unixfd;
- #else
- return (FFNativeFD) _get_osfhandle(unixfd);
- #endif
+#define FF_AUTO_CLOSE_FD FF_A_CLEANUP(wrapClose)
+
+static inline FFNativeFD FFUnixFD2NativeFD(int unixfd) {
+#ifndef _WIN32
+ return unixfd;
+#else
+ return (FFNativeFD) _get_osfhandle(unixfd);
+#endif
}
-FF_C_NONNULL(3)
-static inline bool ffWriteFDData(FFNativeFD fd, size_t dataSize, const void* data)
-{
- #ifndef _WIN32
- return write(fd, data, dataSize) != -1;
- #else
- DWORD written;
- return WriteFile(fd, data, (DWORD) dataSize, &written, NULL) && written == dataSize;
- #endif
+FF_A_NONNULL(3) static inline bool ffWriteFDData(FFNativeFD fd, size_t dataSize, const void* data) {
+#ifndef _WIN32
+ return write(fd, data, dataSize) != -1;
+#else
+ DWORD written;
+ return WriteFile(fd, data, (DWORD) dataSize, &written, NULL) && written == dataSize;
+#endif
}
-FF_C_NONNULL(2)
-static inline bool ffWriteFDBuffer(FFNativeFD fd, const FFstrbuf* content)
-{
+FF_A_NONNULL(2) static inline bool ffWriteFDBuffer(FFNativeFD fd, const FFstrbuf* content) {
return ffWriteFDData(fd, content->length, content->chars);
}
-FF_C_NONNULL(1, 3)
-bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data);
+FF_A_NONNULL(1, 3) bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data);
-FF_C_NONNULL(1, 2)
-static inline bool ffWriteFileBuffer(const char* fileName, const FFstrbuf* buffer)
-{
+FF_A_NONNULL(1, 2) static inline bool ffWriteFileBuffer(const char* fileName, const FFstrbuf* buffer) {
return ffWriteFileData(fileName, buffer->length, buffer->chars);
}
-FF_C_NONNULL(3)
-static inline ssize_t ffReadFDData(FFNativeFD fd, size_t dataSize, void* data)
-{
- #ifndef _WIN32
- return read(fd, data, dataSize);
- #else
- DWORD bytesRead;
- if(!ReadFile(fd, data, (DWORD)dataSize, &bytesRead, NULL))
- return -1;
-
- return (ssize_t)bytesRead;
- #endif
+FF_A_NONNULL(3) static inline ssize_t ffReadFDData(FFNativeFD fd, size_t dataSize, void* data) {
+#ifndef _WIN32
+ return read(fd, data, dataSize);
+#else
+ DWORD bytesRead;
+ if (!ReadFile(fd, data, (DWORD) dataSize, &bytesRead, NULL)) {
+ return -1;
+ }
+
+ return (ssize_t) bytesRead;
+#endif
}
-FF_C_NONNULL(2)
-bool ffAppendFDBuffer(FFNativeFD fd, FFstrbuf* buffer);
+FF_A_NONNULL(2) bool ffAppendFDBuffer(FFNativeFD fd, FFstrbuf* buffer);
-FF_C_NONNULL(1, 3)
-static inline ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data)
-{
+FF_A_NONNULL(1, 3) static inline ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data) {
FFNativeFD FF_AUTO_CLOSE_FD fd =
- #ifndef _WIN32
+#ifndef _WIN32
open(fileName, O_RDONLY | O_CLOEXEC);
- #else
+#else
CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- #endif
+#endif
- if (!ffIsValidNativeFD(fd))
+ if (!ffIsValidNativeFD(fd)) {
return -1;
+ }
return ffReadFDData(fd, dataSize, data);
}
-FF_C_NONNULL(2, 4)
-static inline ssize_t ffReadFileDataRelative(FFNativeFD dfd, const char* fileName, size_t dataSize, void* data)
-{
+FF_A_NONNULL(2, 4) static inline ssize_t ffReadFileDataRelative(FFNativeFD dfd, const char* fileName, size_t dataSize, void* data) {
FFNativeFD FF_AUTO_CLOSE_FD fd = openat(dfd, fileName, O_RDONLY | O_CLOEXEC);
- if (!ffIsValidNativeFD(fd))
+ if (!ffIsValidNativeFD(fd)) {
return -1;
+ }
return ffReadFDData(fd, dataSize, data);
}
-FF_C_NONNULL(1, 2)
-static inline bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer)
-{
+FF_A_NONNULL(1, 2) static inline bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer) {
FFNativeFD FF_AUTO_CLOSE_FD fd =
- #ifndef _WIN32
+#ifndef _WIN32
open(fileName, O_RDONLY | O_CLOEXEC);
- #else
+#else
CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- #endif
+#endif
- if (!ffIsValidNativeFD(fd))
+ if (!ffIsValidNativeFD(fd)) {
return false;
+ }
return ffAppendFDBuffer(fd, buffer);
}
-FF_C_NONNULL(2, 3)
-static inline bool ffAppendFileBufferRelative(FFNativeFD dfd, const char* fileName, FFstrbuf* buffer)
-{
+FF_A_NONNULL(2, 3) static inline bool ffAppendFileBufferRelative(FFNativeFD dfd, const char* fileName, FFstrbuf* buffer) {
FFNativeFD FF_AUTO_CLOSE_FD fd = openat(dfd, fileName, O_RDONLY | O_CLOEXEC);
- if (!ffIsValidNativeFD(fd))
+ if (!ffIsValidNativeFD(fd)) {
return false;
+ }
return ffAppendFDBuffer(fd, buffer);
}
-FF_C_NONNULL(2)
-static inline bool ffReadFDBuffer(FFNativeFD fd, FFstrbuf* buffer)
-{
+FF_A_NONNULL(2) static inline bool ffReadFDBuffer(FFNativeFD fd, FFstrbuf* buffer) {
ffStrbufClear(buffer);
return ffAppendFDBuffer(fd, buffer);
}
-FF_C_NONNULL(1, 2)
-static inline bool ffReadFileBuffer(const char* fileName, FFstrbuf* buffer)
-{
+FF_A_NONNULL(1, 2) static inline bool ffReadFileBuffer(const char* fileName, FFstrbuf* buffer) {
ffStrbufClear(buffer);
return ffAppendFileBuffer(fileName, buffer);
}
-FF_C_NONNULL(2, 3)
-static inline bool ffReadFileBufferRelative(FFNativeFD dfd, const char* fileName, FFstrbuf* buffer)
-{
+FF_A_NONNULL(2, 3) static inline bool ffReadFileBufferRelative(FFNativeFD dfd, const char* fileName, FFstrbuf* buffer) {
ffStrbufClear(buffer);
return ffAppendFileBufferRelative(dfd, fileName, buffer);
}
-typedef enum __attribute__((__packed__)) FFPathType
-{
+typedef enum FF_A_PACKED FFPathType {
FF_PATHTYPE_FILE = 1 << 0,
FF_PATHTYPE_DIRECTORY = 1 << 1,
FF_PATHTYPE_ANY = FF_PATHTYPE_FILE | FF_PATHTYPE_DIRECTORY,
FF_PATHTYPE_FORCE_UNSIGNED = UINT8_MAX,
} FFPathType;
-FF_C_NONNULL(1)
-static inline bool ffPathExists(const char* path, FFPathType pathType)
-{
- #ifdef _WIN32
+FF_A_NONNULL(1) static inline bool ffPathExists(const char* path, FFPathType pathType) {
+#ifdef _WIN32
wchar_t wPath[MAX_PATH];
- if (!NT_SUCCESS(RtlUTF8ToUnicodeN(wPath, (ULONG) sizeof(wPath), NULL, path, (ULONG)strlen(path) + 1)))
+ if (!NT_SUCCESS(RtlUTF8ToUnicodeN(wPath, (ULONG) sizeof(wPath), NULL, path, (ULONG) strlen(path) + 1))) {
return false;
+ }
DWORD attr = GetFileAttributesW(wPath);
- if(attr == INVALID_FILE_ATTRIBUTES)
+ if (attr == INVALID_FILE_ATTRIBUTES) {
return false;
+ }
- if(pathType & FF_PATHTYPE_FILE && !(attr & FILE_ATTRIBUTE_DIRECTORY))
+ if (pathType & FF_PATHTYPE_FILE && !(attr & FILE_ATTRIBUTE_DIRECTORY)) {
return true;
+ }
- if(pathType & FF_PATHTYPE_DIRECTORY && (attr & FILE_ATTRIBUTE_DIRECTORY))
+ if (pathType & FF_PATHTYPE_DIRECTORY && (attr & FILE_ATTRIBUTE_DIRECTORY)) {
return true;
+ }
- #else
+#else
- if (pathType == FF_PATHTYPE_ANY)
- {
+ if (pathType == FF_PATHTYPE_ANY) {
// Zero overhead
return access(path, F_OK) == 0;
- }
- else
- {
+ } else {
struct stat fileStat;
- if(stat(path, &fileStat) != 0)
+ if (stat(path, &fileStat) != 0) {
return false;
+ }
unsigned int mode = fileStat.st_mode & S_IFMT;
- if(pathType & FF_PATHTYPE_FILE && mode != S_IFDIR)
+ if (pathType & FF_PATHTYPE_FILE && mode != S_IFDIR) {
return true;
+ }
- if(pathType & FF_PATHTYPE_DIRECTORY && mode == S_IFDIR)
+ if (pathType & FF_PATHTYPE_DIRECTORY && mode == S_IFDIR) {
return true;
+ }
}
- #endif
+#endif
return false;
}
-FF_C_NONNULL(1, 2)
-bool ffPathExpandEnv(const char* in, FFstrbuf* out);
+FF_A_NONNULL(1, 2) bool ffPathExpandEnv(const char* in, FFstrbuf* out);
#define FF_IO_TERM_RESP_WAIT_MS 100 // #554
-FF_C_SCANF(3, 4)
-FF_C_NONNULL(1, 3)
+FF_A_SCANF(3, 4)
+FF_A_NONNULL(1, 3)
const char* ffGetTerminalResponse(const char* request, int nParams, const char* format, ...);
// Not thread safe!
bool ffSuppressIO(bool suppress);
-static inline void ffUnsuppressIO(bool* suppressed)
-{
- if (!*suppressed) return;
+static inline void ffUnsuppressIO(bool* suppressed) {
+ if (!*suppressed) {
+ return;
+ }
ffSuppressIO(false);
*suppressed = false;
}
-#define FF_SUPPRESS_IO() bool __attribute__((__cleanup__(ffUnsuppressIO), __unused__)) io_suppressed__ = ffSuppressIO(true)
+#define FF_SUPPRESS_IO() bool FF_A_CLEANUP(ffUnsuppressIO) FF_A_UNUSED io_suppressed__ = ffSuppressIO(true)
void ffListFilesRecursively(const char* path, bool pretty);
-FF_C_NONNULL(1)
-static inline bool wrapFclose(FILE** pfile)
-{
+FF_A_NONNULL(1) static inline bool wrapFclose(FILE** pfile) {
assert(pfile);
- if (!*pfile)
+ if (!*pfile) {
return false;
+ }
fclose(*pfile);
return true;
}
-#define FF_AUTO_CLOSE_FILE __attribute__((__cleanup__(wrapFclose)))
+#define FF_AUTO_CLOSE_FILE FF_A_CLEANUP(wrapFclose)
-FF_C_NONNULL(1)
+FF_A_NONNULL(1)
#ifndef _WIN32
-static inline bool wrapClosedir(DIR** pdir)
-{
+static inline bool wrapClosedir(DIR** pdir) {
assert(pdir);
- if (!*pdir)
+ if (!*pdir) {
return false;
+ }
closedir(*pdir);
return true;
}
#else
-static inline bool wrapClosedir(HANDLE* pdir)
-{
+static inline bool wrapClosedir(HANDLE* pdir) {
assert(pdir);
- if (!*pdir)
+ if (!*pdir) {
return false;
+ }
FindClose(*pdir);
return true;
}
#endif
-#define FF_AUTO_CLOSE_DIR __attribute__((__cleanup__(wrapClosedir)))
+#define FF_AUTO_CLOSE_DIR FF_A_CLEANUP(wrapClosedir)
-FF_C_NONNULL(1, 2, 3)
-static inline bool ffSearchUserConfigFile(const FFlist* configDirs, const char* fileSubpath, FFstrbuf* result)
-{
+FF_A_NONNULL(1, 2, 3) static inline bool ffSearchUserConfigFile(const FFlist* configDirs, const char* fileSubpath, FFstrbuf* result) {
// configDirs is a list of FFstrbufs include the trailing slash
- FF_LIST_FOR_EACH(FFstrbuf, dir, *configDirs)
- {
+ FF_LIST_FOR_EACH (FFstrbuf, dir, *configDirs) {
ffStrbufClear(result);
ffStrbufAppend(result, dir);
ffStrbufAppendS(result, fileSubpath);
- if (ffPathExists(result->chars, FF_PATHTYPE_FILE))
+ if (ffPathExists(result->chars, FF_PATHTYPE_FILE)) {
return true;
+ }
}
return false;
diff --git a/src/common/jsonconfig.h b/src/common/jsonconfig.h
index 55f9ab5f89..a78aafd160 100644
--- a/src/common/jsonconfig.h
+++ b/src/common/jsonconfig.h
@@ -6,20 +6,20 @@
bool ffJsonConfigParseModuleArgs(yyjson_val* key, yyjson_val* val, FFModuleArgs* moduleArgs);
const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair pairs[]);
-yyjson_api_inline yyjson_mut_val* yyjson_mut_strbuf(yyjson_mut_doc *doc, const FFstrbuf* buf) {
+yyjson_api_inline yyjson_mut_val* yyjson_mut_strbuf(yyjson_mut_doc* doc, const FFstrbuf* buf) {
return yyjson_mut_strncpy(doc, buf->chars, buf->length);
}
-yyjson_api_inline bool yyjson_mut_obj_add_strbuf(yyjson_mut_doc *doc,
- yyjson_mut_val *obj,
- const char *_key,
- const FFstrbuf* buf) {
+yyjson_api_inline bool yyjson_mut_obj_add_strbuf(yyjson_mut_doc* doc,
+ yyjson_mut_val* obj,
+ const char* _key,
+ const FFstrbuf* buf) {
return yyjson_mut_obj_add_strncpy(doc, obj, _key, buf->chars, buf->length);
}
-yyjson_api_inline bool yyjson_mut_arr_add_strbuf(yyjson_mut_doc *doc,
- yyjson_mut_val *obj,
- const FFstrbuf* buf) {
+yyjson_api_inline bool yyjson_mut_arr_add_strbuf(yyjson_mut_doc* doc,
+ yyjson_mut_val* obj,
+ const FFstrbuf* buf) {
return yyjson_mut_arr_add_strncpy(doc, obj, buf->chars, buf->length);
}
diff --git a/src/common/library.h b/src/common/library.h
index 9c4ee72822..97500ac9ee 100644
--- a/src/common/library.h
+++ b/src/common/library.h
@@ -1,107 +1,106 @@
#pragma once
#include "fastfetch.h"
-#include "common/FFcheckmacros.h"
#ifndef FF_DISABLE_DLOPEN
-#if defined(_WIN32)
- #define FF_DLOPEN_FLAGS 0
- FF_C_NODISCARD void* dlopen(const char* path, int mode);
- FF_C_NODISCARD void* dlsym(void* handle, const char* symbol);
- int dlclose(void* handle);
-#else
- #include
-#endif
-
-#ifdef _WIN32
- #define FF_LIBRARY_EXTENSION ".dll"
-#elif defined(__APPLE__)
- #define FF_LIBRARY_EXTENSION ".dylib"
-#else
- #define FF_LIBRARY_EXTENSION ".so"
-#endif
-
-static inline void ffLibraryUnload(void** handle)
-{
+ #if defined(_WIN32)
+ #define FF_DLOPEN_FLAGS 0
+FF_A_NODISCARD void* dlopen(const char* path, int mode);
+FF_A_NODISCARD void* dlsym(void* handle, const char* symbol);
+int dlclose(void* handle);
+ #else
+ #include
+ #endif
+
+ #ifdef _WIN32
+ #define FF_LIBRARY_EXTENSION ".dll"
+ #elif defined(__APPLE__)
+ #define FF_LIBRARY_EXTENSION ".dylib"
+ #else
+ #define FF_LIBRARY_EXTENSION ".so"
+ #endif
+
+static inline void ffLibraryUnload(void** handle) {
assert(handle);
- if (*handle)
+ if (*handle) {
dlclose(*handle);
+ }
}
-#if __cplusplus
-#define __auto_type auto
-#endif
+ #if __cplusplus
+ #define __auto_type auto
+ #endif
-#define FF_LIBRARY_SYMBOL(symbolName) \
- __typeof__(&symbolName) ff ## symbolName;
+ #define FF_LIBRARY_SYMBOL(symbolName) \
+ __typeof__(&symbolName) ff##symbolName;
-#define FF_LIBRARY_LOAD(libraryObjectName, returnValue, ...) \
- void* __attribute__((__cleanup__(ffLibraryUnload))) libraryObjectName = ffLibraryLoad(__VA_ARGS__, NULL);\
- if(libraryObjectName == NULL) \
- return returnValue;
+ #define FF_LIBRARY_LOAD(libraryObjectName, returnValue, ...) \
+ void* FF_A_CLEANUP(ffLibraryUnload) libraryObjectName = ffLibraryLoad(__VA_ARGS__, NULL); \
+ if (libraryObjectName == NULL) \
+ return returnValue;
-#define FF_LIBRARY_LOAD_MESSAGE(libraryObjectName, libraryFileName, maxVersion, ...) \
- FF_LIBRARY_LOAD(libraryObjectName, "dlopen(" libraryFileName ") failed", libraryFileName, maxVersion, ##__VA_ARGS__)
+ #define FF_LIBRARY_LOAD_MESSAGE(libraryObjectName, libraryFileName, maxVersion, ...) \
+ FF_LIBRARY_LOAD(libraryObjectName, "dlopen(" libraryFileName ") failed", libraryFileName, maxVersion, ##__VA_ARGS__)
-#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, symbolMapping, symbolName, returnValue) \
- symbolMapping = (__typeof__(&symbolName)) dlsym(library, #symbolName); \
- if(symbolMapping == NULL) \
- return returnValue;
+ #define FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, symbolMapping, symbolName, returnValue) \
+ symbolMapping = (__typeof__(&symbolName)) dlsym(library, #symbolName); \
+ if (symbolMapping == NULL) \
+ return returnValue;
-#define FF_LIBRARY_LOAD_SYMBOL(library, symbolName, returnValue) \
- __auto_type FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, returnValue);
+ #define FF_LIBRARY_LOAD_SYMBOL(library, symbolName, returnValue) \
+ __auto_type FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff##symbolName, symbolName, returnValue);
-#define FF_LIBRARY_LOAD_SYMBOL_LAZY(library, symbolName) \
- __auto_type ff ## symbolName = (__typeof__(&symbolName)) dlsym(library, #symbolName);
+ #define FF_LIBRARY_LOAD_SYMBOL_LAZY(library, symbolName) \
+ __auto_type ff##symbolName = (__typeof__(&symbolName)) dlsym(library, #symbolName);
-#define FF_LIBRARY_LOAD_SYMBOL_MESSAGE(library, symbolName) \
- __auto_type FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, "dlsym " #symbolName " failed");
+ #define FF_LIBRARY_LOAD_SYMBOL_MESSAGE(library, symbolName) \
+ __auto_type FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff##symbolName, symbolName, "dlsym " #symbolName " failed");
-#define FF_LIBRARY_LOAD_SYMBOL_VAR(library, varName, symbolName, returnValue) \
- FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff ## symbolName, symbolName, returnValue);
+ #define FF_LIBRARY_LOAD_SYMBOL_VAR(library, varName, symbolName, returnValue) \
+ FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff##symbolName, symbolName, returnValue);
-#define FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(library, varName, symbolName) \
- FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff ## symbolName, symbolName, "dlsym " #symbolName " failed");
+ #define FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(library, varName, symbolName) \
+ FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff##symbolName, symbolName, "dlsym " #symbolName " failed");
-#define FF_LIBRARY_LOAD_SYMBOL_PTR(library, varName, symbolName, returnValue) \
- FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName)->ff ## symbolName, symbolName, returnValue);
+ #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, ...);
#else
-#define FF_LIBRARY_EXTENSION ""
+ #define FF_LIBRARY_EXTENSION ""
-#define FF_LIBRARY_SYMBOL(symbolName) \
- __typeof__(&symbolName) ff ## symbolName;
+ #define FF_LIBRARY_SYMBOL(symbolName) \
+ __typeof__(&symbolName) ff##symbolName;
-#define FF_LIBRARY_LOAD(libraryObjectName, returnValue, ...) \
- FF_MAYBE_UNUSED void* libraryObjectName = NULL; // Placeholder
+ #define FF_LIBRARY_LOAD(libraryObjectName, returnValue, ...) \
+ FF_A_UNUSED void* libraryObjectName = NULL; // Placeholder
-#define FF_LIBRARY_LOAD_MESSAGE(libraryObjectName, libraryFileName, maxVersion, ...) \
- FF_LIBRARY_LOAD(libraryObjectName, , libraryFileName, maxVersion, ##__VA_ARGS__)
+ #define FF_LIBRARY_LOAD_MESSAGE(libraryObjectName, libraryFileName, maxVersion, ...) \
+ FF_LIBRARY_LOAD(libraryObjectName, , libraryFileName, maxVersion, ##__VA_ARGS__)
-#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, symbolMapping, symbolName, returnValue) \
- symbolMapping = (__typeof__(&symbolName)) &symbolName;
+ #define FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, symbolMapping, symbolName, returnValue) \
+ symbolMapping = (__typeof__(&symbolName)) &symbolName;
-#define FF_LIBRARY_LOAD_SYMBOL(library, symbolName, returnValue) \
- FF_MAYBE_UNUSED __auto_type FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, returnValue);
+ #define FF_LIBRARY_LOAD_SYMBOL(library, symbolName, returnValue) \
+ FF_A_UNUSED __auto_type FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff##symbolName, symbolName, returnValue);
-#define FF_LIBRARY_LOAD_SYMBOL_LAZY(library, symbolName) \
- FF_MAYBE_UNUSED __auto_type ff ## symbolName = (__typeof__(&symbolName)) &symbolName;
+ #define FF_LIBRARY_LOAD_SYMBOL_LAZY(library, symbolName) \
+ FF_A_UNUSED __auto_type ff##symbolName = (__typeof__(&symbolName)) &symbolName;
-#define FF_LIBRARY_LOAD_SYMBOL_MESSAGE(library, symbolName) \
- FF_MAYBE_UNUSED __auto_type FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, "dlsym " #symbolName " failed");
+ #define FF_LIBRARY_LOAD_SYMBOL_MESSAGE(library, symbolName) \
+ FF_A_UNUSED __auto_type FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff##symbolName, symbolName, "dlsym " #symbolName " failed");
-#define FF_LIBRARY_LOAD_SYMBOL_VAR(library, varName, symbolName, returnValue) \
- FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff ## symbolName, symbolName, returnValue);
+ #define FF_LIBRARY_LOAD_SYMBOL_VAR(library, varName, symbolName, returnValue) \
+ FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff##symbolName, symbolName, returnValue);
-#define FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(library, varName, symbolName) \
- FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff ## symbolName, symbolName, "dlsym " #symbolName " failed");
+ #define FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(library, varName, symbolName) \
+ FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff##symbolName, symbolName, "dlsym " #symbolName " failed");
-#define FF_LIBRARY_LOAD_SYMBOL_PTR(library, varName, symbolName, returnValue) \
- FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName)->ff ## symbolName, symbolName, returnValue);
+ #define FF_LIBRARY_LOAD_SYMBOL_PTR(library, varName, symbolName, returnValue) \
+ FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName)->ff##symbolName, symbolName, returnValue);
#endif
diff --git a/src/common/mallocHelper.h b/src/common/mallocHelper.h
index a36423d694..5b24df4713 100644
--- a/src/common/mallocHelper.h
+++ b/src/common/mallocHelper.h
@@ -13,27 +13,26 @@
#include
#endif
-static inline void ffWrapFree(const void* pPtr)
-{
+static inline void ffWrapFree(const void* pPtr) {
assert(pPtr);
- if(*(void**)pPtr)
- free(*(void**)pPtr);
+ if (*(void**) pPtr) {
+ free(*(void**) pPtr);
+ }
}
-#define FF_AUTO_FREE __attribute__((__cleanup__(ffWrapFree)))
+#define FF_AUTO_FREE FF_A_CLEANUP(ffWrapFree)
// ptr MUST be a malloc'ed pointer
-static inline size_t ffMallocUsableSize(const void* ptr)
-{
+static inline size_t ffMallocUsableSize(const void* ptr) {
assert(ptr);
- #if FF_HAVE_MALLOC_USABLE_SIZE
- return malloc_usable_size((void*) ptr);
- #elif FF_HAVE_MALLOC_SIZE
- return malloc_size((void*) ptr);
- #elif FF_HAVE_MSVC_MSIZE
- return _msize((void*) ptr);
- #else
- (void) ptr;
- return 0; // Not supported
- #endif
+#if FF_HAVE_MALLOC_USABLE_SIZE
+ return malloc_usable_size((void*) ptr);
+#elif FF_HAVE_MALLOC_SIZE
+ return malloc_size((void*) ptr);
+#elif FF_HAVE_MSVC_MSIZE
+ return _msize((void*) ptr);
+#else
+ (void) ptr;
+ return 0; // Not supported
+#endif
}
diff --git a/src/common/netif.h b/src/common/netif.h
index 99a1a69a02..d3984df423 100644
--- a/src/common/netif.h
+++ b/src/common/netif.h
@@ -7,7 +7,7 @@
#include
#endif
-typedef enum __attribute__((__packed__)) FFNetifDefaultRouteResultStatus {
+typedef enum FF_A_PACKED FFNetifDefaultRouteResultStatus {
FF_NETIF_UNINITIALIZED,
FF_NETIF_INVALID,
FF_NETIF_OK
@@ -16,10 +16,10 @@ typedef enum __attribute__((__packed__)) FFNetifDefaultRouteResultStatus {
typedef struct FFNetifDefaultRouteResult {
uint32_t ifIndex;
- #ifndef _WIN32
+#ifndef _WIN32
char ifName[IF_NAMESIZE + 1];
uint32_t preferredSourceAddrV4;
- #endif
+#endif
enum FFNetifDefaultRouteResultStatus status;
} FFNetifDefaultRouteResult;
diff --git a/src/common/networking.h b/src/common/networking.h
index 91428b7054..2554e2231e 100644
--- a/src/common/networking.h
+++ b/src/common/networking.h
@@ -10,23 +10,23 @@
struct addrinfo;
typedef struct FFNetworkingState {
- #ifdef _WIN32
- uintptr_t sockfd;
- OVERLAPPED overlapped;
- #else
- int sockfd;
- struct addrinfo* addr;
-
- #ifdef FF_HAVE_THREADS
- FFThreadType thread;
- #endif
+#ifdef _WIN32
+ uintptr_t sockfd;
+ OVERLAPPED overlapped;
+#else
+ int sockfd;
+ struct addrinfo* addr;
+
+ #ifdef FF_HAVE_THREADS
+ FFThreadType thread;
#endif
+#endif
FFstrbuf command;
uint32_t timeout;
bool ipv6;
bool compression; // if true, HTTP content compression will be enabled if supported
- bool tfo; // if true, TCP Fast Open will be attempted first, and fallback to traditional connection if it fails
+ bool tfo; // if true, TCP Fast Open will be attempted first, and fallback to traditional connection if it fails
} FFNetworkingState;
const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers);
diff --git a/src/common/option.h b/src/common/option.h
index 00a082361e..ce0a0ab015 100644
--- a/src/common/option.h
+++ b/src/common/option.h
@@ -6,14 +6,12 @@ struct yyjson_val;
struct yyjson_mut_doc;
struct yyjson_mut_val;
-typedef struct FFModuleFormatArg
-{
+typedef struct FFModuleFormatArg {
const char* desc;
const char* name;
} FFModuleFormatArg;
-typedef struct FFModuleFormatArgList
-{
+typedef struct FFModuleFormatArgList {
FFModuleFormatArg* args;
uint32_t count;
} FFModuleFormatArgList;
@@ -21,8 +19,7 @@ typedef struct FFModuleFormatArgList
#define FF_FORMAT_ARG_LIST(list) { .args = list, .count = sizeof(list) / sizeof(FFModuleFormatArg) }
// Must be the first field of FFModuleOptions
-typedef struct FFModuleBaseInfo
-{
+typedef struct FFModuleBaseInfo {
const char* name;
const char* description;
// A dirty polymorphic implementation in C.
@@ -32,15 +29,14 @@ typedef struct FFModuleBaseInfo
void (*initOptions)(void* options);
void (*destroyOptions)(void* options);
- void (*parseJsonObject)(void* options, struct yyjson_val *module);
- bool (*printModule)(void* options); // true on success
+ void (*parseJsonObject)(void* options, struct yyjson_val* module);
+ bool (*printModule)(void* options); // true on success
bool (*generateJsonResult)(void* options, struct yyjson_mut_doc* doc, struct yyjson_mut_val* module); // true on success
void (*generateJsonConfig)(void* options, struct yyjson_mut_doc* doc, struct yyjson_mut_val* obj);
FFModuleFormatArgList formatArgs;
} FFModuleBaseInfo;
-typedef enum __attribute__((__packed__)) FFModuleKeyType
-{
+typedef enum FF_A_PACKED FFModuleKeyType {
FF_MODULE_KEY_TYPE_NONE = 0,
FF_MODULE_KEY_TYPE_STRING = 1 << 0,
FF_MODULE_KEY_TYPE_ICON = 1 << 1,
@@ -54,8 +50,7 @@ typedef enum __attribute__((__packed__)) FFModuleKeyType
FF_MODULE_KEY_TYPE_FORCE_UNSIGNED = UINT8_MAX,
} FFModuleKeyType;
-typedef struct FFModuleArgs
-{
+typedef struct FFModuleArgs {
FFstrbuf key;
FFstrbuf keyColor;
FFstrbuf keyIcon;
@@ -64,27 +59,24 @@ typedef struct FFModuleArgs
uint32_t keyWidth;
} FFModuleArgs;
-typedef struct FFKeyValuePair
-{
+typedef struct FFKeyValuePair {
const char* key;
int value;
} FFKeyValuePair;
const char* ffOptionTestPrefix(const char* argumentKey, const char* moduleName);
void ffOptionParseString(const char* argumentKey, const char* value, FFstrbuf* buffer);
-FF_C_NODISCARD uint32_t ffOptionParseUInt32(const char* argumentKey, const char* value);
-FF_C_NODISCARD int32_t ffOptionParseInt32(const char* argumentKey, const char* value);
-FF_C_NODISCARD int ffOptionParseEnum(const char* argumentKey, const char* requestedKey, FFKeyValuePair pairs[]);
-FF_C_NODISCARD bool ffOptionParseBoolean(const char* str);
+FF_A_NODISCARD uint32_t ffOptionParseUInt32(const char* argumentKey, const char* value);
+FF_A_NODISCARD int32_t ffOptionParseInt32(const char* argumentKey, const char* value);
+FF_A_NODISCARD int ffOptionParseEnum(const char* argumentKey, const char* requestedKey, FFKeyValuePair pairs[]);
+FF_A_NODISCARD bool ffOptionParseBoolean(const char* str);
void ffOptionParseColorNoClear(const char* value, FFstrbuf* buffer);
-static inline void ffOptionParseColor(const char* value, FFstrbuf* buffer)
-{
+static inline void ffOptionParseColor(const char* value, FFstrbuf* buffer) {
ffStrbufClear(buffer);
ffOptionParseColorNoClear(value, buffer);
}
-static inline void ffOptionInitModuleArg(FFModuleArgs* args, const char* icon)
-{
+static inline void ffOptionInitModuleArg(FFModuleArgs* args, const char* icon) {
ffStrbufInit(&args->key);
ffStrbufInit(&args->keyColor);
ffStrbufInitStatic(&args->keyIcon, icon);
@@ -93,8 +85,7 @@ static inline void ffOptionInitModuleArg(FFModuleArgs* args, const char* icon)
args->keyWidth = 0;
}
-static inline void ffOptionDestroyModuleArg(FFModuleArgs* args)
-{
+static inline void ffOptionDestroyModuleArg(FFModuleArgs* args) {
ffStrbufDestroy(&args->key);
ffStrbufDestroy(&args->keyColor);
ffStrbufDestroy(&args->keyIcon);
diff --git a/src/common/parsing.h b/src/common/parsing.h
index f870fd1856..c3a4bee93a 100644
--- a/src/common/parsing.h
+++ b/src/common/parsing.h
@@ -4,20 +4,18 @@
#include
-typedef struct FFVersion
-{
+typedef struct FFVersion {
uint32_t major;
uint32_t minor;
uint32_t patch;
} FFVersion;
-typedef struct FFColorRangeConfig
-{
+typedef struct FFColorRangeConfig {
uint8_t green;
uint8_t yellow;
} FFColorRangeConfig;
-#define FF_VERSION_INIT ((FFVersion) {0})
+#define FF_VERSION_INIT ((FFVersion) { 0 })
void ffParseSemver(FFstrbuf* buffer, const FFstrbuf* major, const FFstrbuf* minor, const FFstrbuf* patch);
void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, const FFstrbuf* gtk4);
diff --git a/src/common/path.h b/src/common/path.h
index 73680034c4..79d181df24 100644
--- a/src/common/path.h
+++ b/src/common/path.h
@@ -4,19 +4,18 @@
#include "common/stringUtils.h"
const char* ffFindExecutableInPath(const char* name, FFstrbuf* result);
-static inline bool ffIsAbsolutePath(const char* path)
-{
- #ifdef _WIN32
+static inline bool ffIsAbsolutePath(const char* path) {
+#ifdef _WIN32
return (ffCharIsEnglishAlphabet(path[0]) && path[1] == ':' && (path[2] == '\\' || path[2] == '/')) // drive letter path
- || (path[0] == '\\' && path[1] == '\\'); // UNC path
- #else
+ || (path[0] == '\\' && path[1] == '\\'); // UNC path
+#else
return path[0] == '/';
- #endif
+#endif
}
#if _WIN32
char* frealpath(void* __restrict hFile, char* __restrict resolved_name /*MAX_PATH*/);
-char* realpath(const char* __restrict file_name, char* __restrict resolved_name /*MAX_PATH*/);
+char* realpath(const char* __restrict file_name, char* __restrict resolved_name /*MAX_PATH*/);
ssize_t freadlink(void* hFile, char* buf, size_t bufsiz);
ssize_t readlink(const char* path, char* buf, size_t bufsiz);
#endif
diff --git a/src/common/percent.h b/src/common/percent.h
index 4ce3c2f0b1..c2eeba6b9d 100644
--- a/src/common/percent.h
+++ b/src/common/percent.h
@@ -4,8 +4,7 @@
#include "common/parsing.h"
#include "common/option.h"
-typedef enum __attribute__((__packed__)) FFPercentageTypeFlags
-{
+typedef enum FF_A_PACKED FFPercentageTypeFlags {
FF_PERCENTAGE_TYPE_NONE = 0,
FF_PERCENTAGE_TYPE_NUM_BIT = 1 << 0,
FF_PERCENTAGE_TYPE_BAR_BIT = 1 << 1,
@@ -16,8 +15,7 @@ typedef enum __attribute__((__packed__)) FFPercentageTypeFlags
} FFPercentageTypeFlags;
static_assert(sizeof(FFPercentageTypeFlags) == 1, "");
-typedef struct FFPercentageModuleConfig
-{
+typedef struct FFPercentageModuleConfig {
uint8_t green;
uint8_t yellow;
FFPercentageTypeFlags type;
diff --git a/src/common/printing.h b/src/common/printing.h
index 1ee79d540b..9401dd729a 100644
--- a/src/common/printing.h
+++ b/src/common/printing.h
@@ -3,7 +3,7 @@
#include "fastfetch.h"
#include "common/format.h"
-typedef enum __attribute__((__packed__)) FFPrintType {
+typedef enum FF_A_PACKED FFPrintType {
FF_PRINT_TYPE_DEFAULT = 0,
FF_PRINT_TYPE_NO_CUSTOM_KEY = 1 << 0, // key has been formatted outside
FF_PRINT_TYPE_NO_CUSTOM_KEY_COLOR = 1 << 1,
@@ -16,6 +16,6 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
void ffPrintFormat(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, uint32_t numArgs, const FFformatarg* arguments);
#define FF_PRINT_FORMAT_CHECKED(moduleName, moduleIndex, moduleArgs, printType, arguments) \
ffPrintFormat((moduleName), (moduleIndex), (moduleArgs), (printType), (sizeof(arguments) / sizeof(*arguments)), (arguments));
-FF_C_PRINTF(5, 6) void ffPrintError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, ...);
+FF_A_PRINTF(5, 6) void ffPrintError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, ...);
void ffPrintColor(const FFstrbuf* colorValue);
void ffPrintCharTimes(char c, uint32_t times);
diff --git a/src/common/processing.h b/src/common/processing.h
index c62235ca27..51105c8baf 100644
--- a/src/common/processing.h
+++ b/src/common/processing.h
@@ -3,43 +3,47 @@
#include "common/FFstrbuf.h"
#ifndef _WIN32
-#include // pid_t
+ #include // pid_t
#endif
typedef struct FFProcessHandle {
- #if _WIN32
- void* pid; // HANDLE
+#if _WIN32
+ void* pid; // HANDLE
void* pipeRead; // HANDLE
- #else
+#else
pid_t pid;
int pipeRead;
- #endif
+#endif
} FFProcessHandle;
const char* ffProcessSpawn(char* const argv[], bool useStdErr, FFProcessHandle* outHandle);
const char* ffProcessReadOutput(FFProcessHandle* handle, FFstrbuf* buffer); // Destroys handle internally
-static inline const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[])
-{
+static inline const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]) {
FFProcessHandle handle;
const char* error = ffProcessSpawn(argv, false, &handle);
- if (error) return error;
+ if (error) {
+ return error;
+ }
error = ffProcessReadOutput(&handle, buffer);
- if (!error)
+ if (!error) {
ffStrbufTrimRightSpace(buffer);
+ }
return error;
}
-static inline const char* ffProcessAppendStdErr(FFstrbuf* buffer, char* const argv[])
-{
+static inline const char* ffProcessAppendStdErr(FFstrbuf* buffer, char* const argv[]) {
FFProcessHandle handle;
const char* error = ffProcessSpawn(argv, true, &handle);
- if (error) return error;
+ if (error) {
+ return error;
+ }
error = ffProcessReadOutput(&handle, buffer);
- if (!error)
+ if (!error) {
ffStrbufTrimRightSpace(buffer);
+ }
return error;
}
diff --git a/src/common/properties.h b/src/common/properties.h
index 9cc9ff34ff..789a757c33 100644
--- a/src/common/properties.h
+++ b/src/common/properties.h
@@ -2,8 +2,7 @@
#include "fastfetch.h"
-typedef struct FFpropquery
-{
+typedef struct FFpropquery {
const char* start;
FFstrbuf* buffer;
} FFpropquery;
@@ -15,42 +14,34 @@ bool ffParsePropFileListValues(const FFlist* list, const char* relativeFile, uin
bool ffParsePropLinePointer(const char** line, const char* start, FFstrbuf* buffer);
-static inline bool ffParsePropLine(const char* line, const char* start, FFstrbuf* buffer)
-{
+static inline bool ffParsePropLine(const char* line, const char* start, FFstrbuf* buffer) {
return ffParsePropLinePointer(&line, start, buffer);
}
-static inline bool ffParsePropFile(const char* filename, const char* start, FFstrbuf* buffer)
-{
- return ffParsePropFileValues(filename, 1, (FFpropquery[]){{start, buffer}});
+static inline bool ffParsePropFile(const char* filename, const char* start, FFstrbuf* buffer) {
+ return ffParsePropFileValues(filename, 1, (FFpropquery[]) { { start, buffer } });
}
-static inline bool ffParsePropFileHome(const char* relativeFile, const char* start, FFstrbuf* buffer)
-{
- return ffParsePropFileHomeValues(relativeFile, 1, (FFpropquery[]){{start, buffer}});
+static inline bool ffParsePropFileHome(const char* relativeFile, const char* start, FFstrbuf* buffer) {
+ return ffParsePropFileHomeValues(relativeFile, 1, (FFpropquery[]) { { start, buffer } });
}
-static inline bool ffParsePropFileList(const FFlist* list, const char* relativeFile, const char* start, FFstrbuf* buffer)
-{
- return ffParsePropFileListValues(list, relativeFile, 1, (FFpropquery[]){{start, buffer}});
+static inline bool ffParsePropFileList(const FFlist* list, const char* relativeFile, const char* start, FFstrbuf* buffer) {
+ return ffParsePropFileListValues(list, relativeFile, 1, (FFpropquery[]) { { start, buffer } });
}
-static inline bool ffParsePropFileConfigValues(const char* relativeFile, uint32_t numQueries, FFpropquery* queries)
-{
+static inline bool ffParsePropFileConfigValues(const char* relativeFile, uint32_t numQueries, FFpropquery* queries) {
return ffParsePropFileListValues(&instance.state.platform.configDirs, relativeFile, numQueries, queries);
}
-static inline bool ffParsePropFileConfig(const char* relativeFile, const char* start, FFstrbuf* buffer)
-{
- return ffParsePropFileConfigValues(relativeFile, 1, (FFpropquery[]){{start, buffer}});
+static inline bool ffParsePropFileConfig(const char* relativeFile, const char* start, FFstrbuf* buffer) {
+ return ffParsePropFileConfigValues(relativeFile, 1, (FFpropquery[]) { { start, buffer } });
}
-static inline bool ffParsePropFileDataValues(const char* relativeFile, uint32_t numQueries, FFpropquery* queries)
-{
+static inline bool ffParsePropFileDataValues(const char* relativeFile, uint32_t numQueries, FFpropquery* queries) {
return ffParsePropFileListValues(&instance.state.platform.dataDirs, relativeFile, numQueries, queries);
}
-static inline bool ffParsePropFileData(const char* relativeFile, const char* start, FFstrbuf* buffer)
-{
- return ffParsePropFileDataValues(relativeFile, 1, (FFpropquery[]){{start, buffer}});
+static inline bool ffParsePropFileData(const char* relativeFile, const char* start, FFstrbuf* buffer) {
+ return ffParsePropFileDataValues(relativeFile, 1, (FFpropquery[]) { { start, buffer } });
}
diff --git a/src/common/settings.h b/src/common/settings.h
index 86fd66313d..02658670eb 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -2,15 +2,13 @@
#include "fastfetch.h"
-typedef enum __attribute__((__packed__)) FFvarianttype
-{
+typedef enum FF_A_PACKED FFvarianttype {
FF_VARIANT_TYPE_STRING,
FF_VARIANT_TYPE_BOOL,
FF_VARIANT_TYPE_INT
} FFvarianttype;
-typedef union FFvariant
-{
+typedef union FFvariant {
const char* strValue;
int32_t intValue;
struct
@@ -20,7 +18,7 @@ typedef union FFvariant
};
} FFvariant;
-#define FF_VARIANT_NULL ((FFvariant){.strValue = NULL})
+#define FF_VARIANT_NULL ((FFvariant) { .strValue = NULL })
FFvariant ffSettingsGetDConf(const char* key, FFvarianttype type);
FFvariant ffSettingsGetGSettings(const char* schemaName, const char* path, const char* key, FFvarianttype type);
diff --git a/src/common/smbiosHelper.h b/src/common/smbios.h
similarity index 88%
rename from src/common/smbiosHelper.h
rename to src/common/smbios.h
index d4d62c5f09..24edbdabb3 100644
--- a/src/common/smbiosHelper.h
+++ b/src/common/smbios.h
@@ -3,16 +3,16 @@
#include "common/FFstrbuf.h"
bool ffIsSmbiosValueSet(FFstrbuf* value);
-static inline void ffCleanUpSmbiosValue(FFstrbuf* value)
-{
- if (!ffIsSmbiosValueSet(value))
+static inline void ffCleanUpSmbiosValue(FFstrbuf* value) {
+ if (!ffIsSmbiosValueSet(value)) {
ffStrbufClear(value);
+ }
}
// https://github.com/KunYi/DumpSMBIOS
-// https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.7.0.pdf
+// https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.9.0.pdf
-typedef enum __attribute__((__packed__)) FFSmbiosType // : uint8_t
+typedef enum FF_A_PACKED FFSmbiosType // : uint8_t
{
FF_SMBIOS_TYPE_BIOS = 0,
FF_SMBIOS_TYPE_SYSTEM_INFO = 1,
@@ -20,7 +20,7 @@ typedef enum __attribute__((__packed__)) FFSmbiosType // : uint8_t
FF_SMBIOS_TYPE_SYSTEM_ENCLOSURE = 3,
FF_SMBIOS_TYPE_PROCESSOR_INFO = 4,
FF_SMBIOS_TYPE_MEMORY_CONTROLLER_INFO = 5, // obsolete
- FF_SMBIOS_TYPE_MEMORY_MODULE_INFO = 6, // obsolete
+ FF_SMBIOS_TYPE_MEMORY_MODULE_INFO = 6, // obsolete
FF_SMBIOS_TYPE_CACHE_INFO = 7,
FF_SMBIOS_TYPE_PORT_CONNECTOR_INFO = 8,
FF_SMBIOS_TYPE_SYSTEM_SLOTS = 9,
@@ -68,8 +68,7 @@ typedef enum __attribute__((__packed__)) FFSmbiosType // : uint8_t
} FFSmbiosType;
static_assert(sizeof(FFSmbiosType) == 1, "FFSmbiosType should be 1 byte");
-typedef struct FFSmbiosHeader
-{
+typedef struct FFSmbiosHeader {
// Type of SMBIOS structure. Do NOT test `Type == FF_SMBIOS_END_OF_TABLE` to determine the end of the table,
// as malformed tables may be missing the end-of-table marker.
// **Use FFSmbiosHeaderTable[FF_SMBIOS_TYPE_END_OF_TABLE] pointer instead.**
@@ -79,23 +78,25 @@ typedef struct FFSmbiosHeader
uint8_t Length;
// Unique handle, used to reference this structure from other structures.
// Not guaranteed to be consistent across reboots or even multiple reads of the same table.
+ // Must be less than 0xFF00
uint16_t Handle;
-} __attribute__((__packed__)) FFSmbiosHeader;
+} FF_A_PACKED FFSmbiosHeader;
static_assert(sizeof(FFSmbiosHeader) == 4, "FFSmbiosHeader should be 4 bytes");
-static inline const char* ffSmbiosLocateString(const char* start, uint8_t index /* start from 1 */)
-{
- if (index == 0 || *start == '\0')
+static inline const char* ffSmbiosLocateString(const char* start, uint8_t index /* start from 1 */) {
+ if (index == 0 || *start == '\0') {
return NULL;
- while (--index)
+ }
+ while (--index) {
start += strlen(start) + 1;
+ }
return start;
}
typedef const FFSmbiosHeader* FFSmbiosHeaderTable[FF_SMBIOS_TYPE__MAX];
const FFSmbiosHeader* ffSmbiosNextEntry(const FFSmbiosHeader* header);
-const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable();
+const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable(void);
#ifdef __linux__
bool ffGetSmbiosValue(const char* devicesPath, const char* classPath, FFstrbuf* buffer);
diff --git a/src/common/stringUtils.h b/src/common/stringUtils.h
index 3afbe6ec3c..34e5cc8324 100644
--- a/src/common/stringUtils.h
+++ b/src/common/stringUtils.h
@@ -5,102 +5,93 @@
#include
#include
-static inline bool ffStrSet(const char* str)
-{
- if(str == NULL)
+static inline bool ffStrSet(const char* str) {
+ if (str == NULL) {
return false;
+ }
- while(isspace(*str))
+ while (isspace(*str)) {
str++;
+ }
return *str != '\0';
}
-
-static inline bool ffStrStartsWithIgnCase(const char* str, const char* compareTo)
-{
+static inline bool ffStrStartsWithIgnCase(const char* str, const char* compareTo) {
return strncasecmp(str, compareTo, strlen(compareTo)) == 0;
}
-static inline bool ffStrEqualsIgnCase(const char* str, const char* compareTo)
-{
+static inline bool ffStrEqualsIgnCase(const char* str, const char* compareTo) {
return strcasecmp(str, compareTo) == 0;
}
-static inline bool ffStrStartsWith(const char* str, const char* compareTo)
-{
+static inline bool ffStrStartsWith(const char* str, const char* compareTo) {
return strncmp(str, compareTo, strlen(compareTo)) == 0;
}
-static inline bool ffStrEndsWith(const char* str, const char* compareTo)
-{
+static inline bool ffStrEndsWith(const char* str, const char* compareTo) {
size_t strLength = strlen(str);
size_t compareToLength = strlen(compareTo);
- if (strLength < compareToLength)
+ if (strLength < compareToLength) {
return false;
+ }
return memcmp(str + strLength - compareToLength, compareTo, compareToLength) == 0;
}
-static inline bool ffStrEndsWithIgnCase(const char* str, const char* compareTo)
-{
+static inline bool ffStrEndsWithIgnCase(const char* str, const char* compareTo) {
size_t strLength = strlen(str);
size_t compareToLength = strlen(compareTo);
- if (strLength < compareToLength)
+ if (strLength < compareToLength) {
return false;
+ }
return strncasecmp(str + strLength - compareToLength, compareTo, compareToLength) == 0;
}
-static inline bool ffStrEquals(const char* str, const char* compareTo)
-{
+static inline bool ffStrEquals(const char* str, const char* compareTo) {
return strcmp(str, compareTo) == 0;
}
-static inline bool ffStrContains(const char* str, const char* compareTo)
-{
+static inline bool ffStrContains(const char* str, const char* compareTo) {
return strstr(str, compareTo) != NULL;
}
-static inline bool ffStrContainsIgnCase(const char* str, const char* compareTo)
-{
+static inline bool ffStrContainsIgnCase(const char* str, const char* compareTo) {
return strcasestr(str, compareTo) != NULL;
}
-static inline bool ffStrContainsC(const char* str, char compareTo)
-{
+static inline bool ffStrContainsC(const char* str, char compareTo) {
return strchr(str, compareTo) != NULL;
}
-static inline bool ffCharIsEnglishAlphabet(char c)
-{
+static inline bool ffCharIsEnglishAlphabet(char c) {
return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
}
-static inline bool ffCharIsDigit(char c)
-{
+static inline bool ffCharIsDigit(char c) {
return '0' <= c && c <= '9';
}
-static inline bool ffCharIsHexDigit(char c)
-{
+static inline bool ffCharIsHexDigit(char c) {
return ffCharIsDigit(c) || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F');
}
-static inline int8_t ffHexCharToInt(char c)
-{
- if (ffCharIsDigit(c))
+static inline int8_t ffHexCharToInt(char c) {
+ if (ffCharIsDigit(c)) {
return (int8_t) (c - '0');
- else if ('a' <= c && c <= 'f')
+ } else if ('a' <= c && c <= 'f') {
return (int8_t) (c - 'a' + 10);
- else if ('A' <= c && c <= 'F')
+ } else if ('A' <= c && c <= 'F') {
return (int8_t) (c - 'A' + 10);
- else
+ } else {
return -1;
+ }
}
// Copies at most (dstBufSiz - 1) bytes from src to dst; dst is always null-terminated
-static inline char* ffStrCopy(char* __restrict__ dst, const char* __restrict__ src, size_t dstBufSiz)
-{
- if (__builtin_expect(dst == NULL, false) || dstBufSiz == 0) return dst;
+static inline char* ffStrCopy(char* __restrict__ dst, const char* __restrict__ src, size_t dstBufSiz) {
+ if (__builtin_expect(dst == NULL, false) || dstBufSiz == 0) {
+ return dst;
+ }
size_t len = strnlen(src, dstBufSiz - 1);
memcpy(dst, src, len);
diff --git a/src/common/sysctl.h b/src/common/sysctl.h
index 3442c4e911..1baabe6285 100644
--- a/src/common/sysctl.h
+++ b/src/common/sysctl.h
@@ -1,18 +1,17 @@
#pragma once
#include "fastfetch.h"
-#include "common/FFcheckmacros.h"
#include
#include
#ifdef __OpenBSD__
const char* ffSysctlGetString(int mib1, int mib2, FFstrbuf* result);
-FF_C_NODISCARD int ffSysctlGetInt(int mib1, int mib2, int defaultValue);
-FF_C_NODISCARD int64_t ffSysctlGetInt64(int mib1, int mib2, int64_t defaultValue);
+FF_A_NODISCARD int ffSysctlGetInt(int mib1, int mib2, int defaultValue);
+FF_A_NODISCARD int64_t ffSysctlGetInt64(int mib1, int mib2, int64_t defaultValue);
#else
const char* ffSysctlGetString(const char* propName, FFstrbuf* result);
-FF_C_NODISCARD int ffSysctlGetInt(const char* propName, int defaultValue);
-FF_C_NODISCARD int64_t ffSysctlGetInt64(const char* propName, int64_t defaultValue);
+FF_A_NODISCARD int ffSysctlGetInt(const char* propName, int defaultValue);
+FF_A_NODISCARD int64_t ffSysctlGetInt64(const char* propName, int64_t defaultValue);
#endif
-FF_C_NODISCARD void* ffSysctlGetData(int* request, u_int requestLength, size_t* resultLength);
+FF_A_NODISCARD void* ffSysctlGetData(int* request, u_int requestLength, size_t* resultLength);
diff --git a/src/common/textModifier.h b/src/common/textModifier.h
index dbc4338cd2..77d6e55959 100644
--- a/src/common/textModifier.h
+++ b/src/common/textModifier.h
@@ -1,5 +1,5 @@
#pragma once
-#define FASTFETCH_TEXT_MODIFIER_BOLT "\033[1m"
+#define FASTFETCH_TEXT_MODIFIER_BOLT "\033[1m"
#define FASTFETCH_TEXT_MODIFIER_ERROR "\033[1;31m"
#define FASTFETCH_TEXT_MODIFIER_RESET "\033[m"
diff --git a/src/common/thread.h b/src/common/thread.h
index dbe0da1083..64d8478d9c 100644
--- a/src/common/thread.h
+++ b/src/common/thread.h
@@ -9,81 +9,107 @@
#include
#include
#define FF_THREAD_MUTEX_INITIALIZER SRWLOCK_INIT
- typedef SRWLOCK FFThreadMutex;
- typedef HANDLE FFThreadType;
- static inline void ffThreadMutexLock(FFThreadMutex* mutex) { AcquireSRWLockExclusive(mutex); }
- static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { ReleaseSRWLockExclusive(mutex); }
- static inline FFThreadType ffThreadCreate(unsigned (__stdcall* func)(void*), void* data) {
- return (FFThreadType)_beginthreadex(NULL, 0, func, data, 0, NULL);
- }
- #define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) static __stdcall unsigned fn ## ThreadMain (void* data) { fn((paramType)data); return 0; }
- #define FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(fn) static __stdcall unsigned fn ## ThreadMain () { fn(); return 0; }
- static inline void ffThreadDetach(FFThreadType thread) { NtClose(thread); }
- static inline bool ffThreadJoin(FFThreadType thread, uint32_t timeout)
- {
- if (NtWaitForSingleObject(thread, FALSE, timeout == 0 ? NULL : &(LARGE_INTEGER) { .QuadPart = (int64_t) timeout * -10000 }) != STATUS_WAIT_0)
- {
- TerminateThread(thread, (DWORD) -1);
- NtClose(thread);
- return false;
+typedef SRWLOCK FFThreadMutex;
+typedef HANDLE FFThreadType;
+static inline void ffThreadMutexLock(FFThreadMutex* mutex) {
+ AcquireSRWLockExclusive(mutex);
+}
+static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) {
+ ReleaseSRWLockExclusive(mutex);
+}
+static inline FFThreadType ffThreadCreate(unsigned(__stdcall* func)(void*), void* data) {
+ return (FFThreadType) _beginthreadex(NULL, 0, func, data, 0, NULL);
+}
+ #define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) \
+ static __stdcall unsigned fn##ThreadMain(void* data) { \
+ fn((paramType) data); \
+ return 0; \
}
- NtClose(thread);
- return true;
- }
+ #define FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(fn) \
+ static __stdcall unsigned fn##ThreadMain() { \
+ fn(); \
+ return 0; \
+ }
+static inline void ffThreadDetach(FFThreadType thread) {
+ NtClose(thread);
+}
+static inline bool ffThreadJoin(FFThreadType thread, uint32_t timeout) {
+ if (NtWaitForSingleObject(thread, FALSE, timeout == 0 ? NULL : &(LARGE_INTEGER) { .QuadPart = (int64_t) timeout * -10000 }) != STATUS_WAIT_0) {
+ TerminateThread(thread, (DWORD) -1);
+ NtClose(thread);
+ return false;
+ }
+ NtClose(thread);
+ return true;
+}
#else
#include
#include
#if FF_HAVE_PTHREAD_NP
#include
#endif
- typedef pthread_t FFThreadType;
+typedef pthread_t FFThreadType;
#if __APPLE__
#include
#define FF_THREAD_MUTEX_INITIALIZER OS_UNFAIR_LOCK_INIT
- typedef os_unfair_lock FFThreadMutex;
- static inline void ffThreadMutexLock(os_unfair_lock* mutex) { os_unfair_lock_lock(mutex); }
- static inline void ffThreadMutexUnlock(os_unfair_lock* mutex) { os_unfair_lock_unlock(mutex); }
+typedef os_unfair_lock FFThreadMutex;
+static inline void ffThreadMutexLock(os_unfair_lock* mutex) {
+ os_unfair_lock_lock(mutex);
+}
+static inline void ffThreadMutexUnlock(os_unfair_lock* mutex) {
+ os_unfair_lock_unlock(mutex);
+}
#else
#define FF_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
- typedef pthread_mutex_t FFThreadMutex;
- static inline void ffThreadMutexLock(FFThreadMutex* mutex) { pthread_mutex_lock(mutex); }
- static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { pthread_mutex_unlock(mutex); }
+typedef pthread_mutex_t FFThreadMutex;
+static inline void ffThreadMutexLock(FFThreadMutex* mutex) {
+ pthread_mutex_lock(mutex);
+}
+static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) {
+ pthread_mutex_unlock(mutex);
+}
#endif
- static inline FFThreadType ffThreadCreate(void* (* func)(void*), void* data) {
- FFThreadType newThread = 0;
- pthread_create(&newThread, NULL, func, data);
- return newThread;
- }
- #define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) static void* fn ## ThreadMain (void* data) { fn((paramType)data); return NULL; }
- #define FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(fn) static void* fn ## ThreadMain () { fn(); return NULL; }
- static inline void ffThreadDetach(FFThreadType thread) { pthread_detach(thread); }
- static inline bool ffThreadJoin(FFThreadType thread, FF_MAYBE_UNUSED uint32_t timeout)
- {
- #if HAVE_TIMEDJOIN_NP
- if (timeout > 0)
- {
- struct timespec ts;
- if (clock_gettime(CLOCK_REALTIME, &ts) == 0)
- {
- ts.tv_sec += timeout / 1000;
- ts.tv_nsec += (timeout % 1000) * 1000000;
- if (pthread_timedjoin_np(thread, NULL, &ts) != 0)
- {
- pthread_kill(thread, SIGTERM);
- return false;
- }
- return true;
- }
- }
- #endif
- pthread_join(thread, NULL);
+static inline FFThreadType ffThreadCreate(void* (*func)(void*), void* data) {
+ FFThreadType newThread = 0;
+ pthread_create(&newThread, NULL, func, data);
+ return newThread;
+}
+ #define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) \
+ static void* fn##ThreadMain(void* data) { \
+ fn((paramType) data); \
+ return NULL; \
+ }
+ #define FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(fn) \
+ static void* fn##ThreadMain() { \
+ fn(); \
+ return NULL; \
+ }
+static inline void ffThreadDetach(FFThreadType thread) {
+ pthread_detach(thread);
+}
+static inline bool ffThreadJoin(FFThreadType thread, FF_A_UNUSED uint32_t timeout) {
+ #if HAVE_TIMEDJOIN_NP
+ if (timeout > 0) {
+ struct timespec ts;
+ if (clock_gettime(CLOCK_REALTIME, &ts) == 0) {
+ ts.tv_sec += timeout / 1000;
+ ts.tv_nsec += (timeout % 1000) * 1000000;
+ if (pthread_timedjoin_np(thread, NULL, &ts) != 0) {
+ pthread_kill(thread, SIGTERM);
+ return false;
+ }
return true;
}
+ }
+ #endif
+ pthread_join(thread, NULL);
+ return true;
+}
#endif
-#else //FF_HAVE_THREADS
+#else // FF_HAVE_THREADS
#define FF_THREAD_MUTEX_INITIALIZER 0
- typedef char FFThreadMutex;
- static inline void ffThreadMutexLock(FFThreadMutex* mutex) { FF_UNUSED(mutex) }
- static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { FF_UNUSED(mutex) }
+typedef char FFThreadMutex;
+static inline void ffThreadMutexLock(FF_A_UNUSED FFThreadMutex* mutex) {}
+static inline void ffThreadMutexUnlock(FF_A_UNUSED FFThreadMutex* mutex) {}
#define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType)
-#endif //FF_HAVE_THREADS
+#endif // FF_HAVE_THREADS
diff --git a/src/common/time.h b/src/common/time.h
index 0156a9c723..23529fe791 100644
--- a/src/common/time.h
+++ b/src/common/time.h
@@ -13,55 +13,53 @@
#include "common/arrayUtils.h"
-static inline double ffTimeGetTick(void) //In msec
+static inline double ffTimeGetTick(void) // In msec
{
- #ifdef _WIN32
- extern double ffQpcMultiplier;
- LARGE_INTEGER start;
- RtlQueryPerformanceCounter(&start);
- return (double) start.QuadPart * ffQpcMultiplier;
- #elif defined(__HAIKU__)
- return (double) system_time() / 1000.;
- #else
- struct timespec timeNow;
- clock_gettime(CLOCK_MONOTONIC, &timeNow);
- return (double) timeNow.tv_sec * 1000. + (double) timeNow.tv_nsec / 1000000.;
- #endif
+#ifdef _WIN32
+ extern double ffQpcMultiplier;
+ LARGE_INTEGER start;
+ RtlQueryPerformanceCounter(&start);
+ return (double) start.QuadPart * ffQpcMultiplier;
+#elif defined(__HAIKU__)
+ return (double) system_time() / 1000.;
+#else
+ struct timespec timeNow;
+ clock_gettime(CLOCK_MONOTONIC, &timeNow);
+ return (double) timeNow.tv_sec * 1000. + (double) timeNow.tv_nsec / 1000000.;
+#endif
}
#if _WIN32
-static inline uint64_t ffFileTimeToUnixMs(uint64_t value)
-{
- if (__builtin_expect(__builtin_usubll_overflow(value, 116444736000000000ull, &value), false))
+static inline uint64_t ffFileTimeToUnixMs(uint64_t value) {
+ if (__builtin_expect(__builtin_usubll_overflow(value, 116444736000000000ull, &value), false)) {
return 0;
+ }
return value / 10000ull;
}
#endif
-static inline uint64_t ffTimeGetNow(void)
-{
- #ifdef _WIN32
- uint64_t timeNow = ffKSystemTimeToUInt64(&SharedUserData->SystemTime);
- return ffFileTimeToUnixMs((uint64_t) timeNow);
- #elif defined(__HAIKU__)
- return (uint64_t) real_time_clock_usecs() / 1000u;
- #else
- struct timespec timeNow;
- clock_gettime(CLOCK_REALTIME, &timeNow);
- return (uint64_t)(((uint64_t) timeNow.tv_sec * 1000u) + ((uint64_t) timeNow.tv_nsec / 1000000u));
- #endif
+static inline uint64_t ffTimeGetNow(void) {
+#ifdef _WIN32
+ uint64_t timeNow = ffKSystemTimeToUInt64(&SharedUserData->SystemTime);
+ return ffFileTimeToUnixMs((uint64_t) timeNow);
+#elif defined(__HAIKU__)
+ return (uint64_t) real_time_clock_usecs() / 1000u;
+#else
+ struct timespec timeNow;
+ clock_gettime(CLOCK_REALTIME, &timeNow);
+ return (uint64_t) (((uint64_t) timeNow.tv_sec * 1000u) + ((uint64_t) timeNow.tv_nsec / 1000000u));
+#endif
}
// Returns true if not interrupted
-static inline bool ffTimeSleep(uint32_t msec)
-{
- #ifdef _WIN32
- LARGE_INTEGER interval;
- interval.QuadPart = -(int64_t) msec * 10000; // Relative time in 100-nanosecond intervals
- return NT_SUCCESS(NtDelayExecution(TRUE, &interval));
- #else
- return nanosleep(&(struct timespec){ msec / 1000, (long) (msec % 1000) * 1000000 }, NULL) == 0;
- #endif
+static inline bool ffTimeSleep(uint32_t msec) {
+#ifdef _WIN32
+ LARGE_INTEGER interval;
+ interval.QuadPart = -(int64_t) msec * 10000; // Relative time in 100-nanosecond intervals
+ return NT_SUCCESS(NtDelayExecution(TRUE, &interval));
+#else
+ return nanosleep(&(struct timespec) { msec / 1000, (long) (msec % 1000) * 1000000 }, NULL) == 0;
+#endif
}
// Not thread-safe
@@ -73,8 +71,7 @@ const char* ffTimeToShortStr(uint64_t msec);
// Not thread-safe
const char* ffTimeToTimeStr(uint64_t msec);
-typedef struct FFTimeGetAgeResult
-{
+typedef struct FFTimeGetAgeResult {
uint32_t years;
uint32_t daysOfYear;
double yearsFraction;
diff --git a/src/common/unused.h b/src/common/unused.h
index 937ac9bf95..98e21a2e6e 100644
--- a/src/common/unused.h
+++ b/src/common/unused.h
@@ -1,9 +1,6 @@
#pragma once
-static inline void ffUnused(int dummy, ...) { (void) dummy; }
+static inline void ffUnused(int dummy, ...) {
+ (void) dummy;
+}
#define FF_UNUSED(...) ffUnused(0, __VA_ARGS__);
-#if defined(__GNUC__) || defined(__clang__)
- #define FF_MAYBE_UNUSED __attribute__ ((__unused__))
-#else
- #define FF_MAYBE_UNUSED
-#endif
diff --git a/src/common/wcwidth.h b/src/common/wcwidth.h
index 1f972b6a06..af00837af5 100644
--- a/src/common/wcwidth.h
+++ b/src/common/wcwidth.h
@@ -3,7 +3,7 @@
#include
#ifdef FF_HAVE_WCWIDTH
-#include
+ #include
// Should be char32_t but it's not defined on macOS
static_assert(sizeof(wchar_t) == sizeof(uint32_t), "wcwidth implementation requires wchar_t to be 32 bits");
diff --git a/src/common/windows/com.cpp b/src/common/windows/com.cpp
index 47da8e3193..4ad067b8d2 100644
--- a/src/common/windows/com.cpp
+++ b/src/common/windows/com.cpp
@@ -3,18 +3,17 @@
#include
-//https://learn.microsoft.com/en-us/windows/win32/wmisdk/example--getting-wmi-data-from-the-local-computer
-//https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/computer-system-hardware-classes
-static void CoUninitializeWrap(void)
-{
+// https://learn.microsoft.com/en-us/windows/win32/wmisdk/example--getting-wmi-data-from-the-local-computer
+// https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/computer-system-hardware-classes
+static void CoUninitializeWrap(void) {
CoUninitialize();
}
-static const char* doInitCom()
-{
+static const char* doInitCom() {
// Initialize COM
- if (FAILED(CoInitializeEx(NULL, COINIT_MULTITHREADED)))
+ if (FAILED(CoInitializeEx(NULL, COINIT_MULTITHREADED))) {
return "CoInitializeEx() failed";
+ }
// Set general COM security levels
@@ -30,8 +29,7 @@ static const char* doInitCom()
NULL // Reserved
);
- if (FAILED(hRes) && hRes != RPC_E_TOO_LATE /* Has been set by a random dll */)
- {
+ if (FAILED(hRes) && hRes != RPC_E_TOO_LATE /* Has been set by a random dll */) {
CoUninitialize();
return "CoInitializeSecurity() failed";
}
@@ -40,10 +38,10 @@ static const char* doInitCom()
return NULL;
}
-const char* ffInitCom(void)
-{
+const char* ffInitCom(void) {
static const char* error = "";
- if (error && error[0] == '\0')
+ if (error && error[0] == '\0') {
error = doInitCom();
+ }
return error;
}
diff --git a/src/common/windows/com.hpp b/src/common/windows/com.hpp
index 3714d79dc9..16bb1ac71c 100644
--- a/src/common/windows/com.hpp
+++ b/src/common/windows/com.hpp
@@ -2,17 +2,18 @@
#ifdef __cplusplus
-#include
+ #include
const char* ffInitCom(void);
-static inline void ffReleaseComObject(void* ppUnknown)
-{
+static inline void ffReleaseComObject(void* ppUnknown) {
IUnknown* pUnknown = *(IUnknown**) ppUnknown;
- if (pUnknown) pUnknown->Release();
+ if (pUnknown) {
+ pUnknown->Release();
+ }
}
-#define FF_AUTO_RELEASE_COM_OBJECT __attribute__((__cleanup__(ffReleaseComObject)))
+ #define FF_AUTO_RELEASE_COM_OBJECT FF_A_CLEANUP(ffReleaseComObject)
#else
// Win32 COM headers requires C++ compiler
diff --git a/src/common/windows/getline.c b/src/common/windows/getline.c
index cb1760f788..3d43d55f37 100644
--- a/src/common/windows/getline.c
+++ b/src/common/windows/getline.c
@@ -3,7 +3,7 @@
#include
#include
-ssize_t getline(char **lineptr, size_t *n, FILE *stream) {
+ssize_t getline(char** lineptr, size_t* n, FILE* stream) {
ssize_t pos = -1;
int c;
@@ -28,13 +28,13 @@ ssize_t getline(char **lineptr, size_t *n, FILE *stream) {
}
pos = 0;
- while(c != EOF) {
- if ((size_t)(pos + 1) >= *n) {
+ while (c != EOF) {
+ if ((size_t) (pos + 1) >= *n) {
size_t new_size = *n + (*n >> 2);
if (new_size < 128) {
new_size = 128;
}
- char *new_ptr = realloc(*lineptr, new_size);
+ char* new_ptr = realloc(*lineptr, new_size);
if (new_ptr == NULL) {
pos = -1;
goto exit;
@@ -43,7 +43,7 @@ ssize_t getline(char **lineptr, size_t *n, FILE *stream) {
*lineptr = new_ptr;
}
- ((char *)(*lineptr))[pos ++] = (char)c;
+ ((char*) (*lineptr))[pos++] = (char) c;
if (c == '\n') {
break;
}
diff --git a/src/common/windows/getline.h b/src/common/windows/getline.h
index 0c0e9ec700..49ba5db201 100644
--- a/src/common/windows/getline.h
+++ b/src/common/windows/getline.h
@@ -3,4 +3,4 @@
#include
#include
-ssize_t getline(char **lineptr, size_t *n, FILE *stream);
+ssize_t getline(char** lineptr, size_t* n, FILE* stream);
diff --git a/src/common/windows/nt.h b/src/common/windows/nt.h
index 3cc63a223f..1c2d08269c 100644
--- a/src/common/windows/nt.h
+++ b/src/common/windows/nt.h
@@ -30,10 +30,8 @@ NTSYSAPI NTSTATUS NTAPI NtPowerInformation(
OUT PVOID OutputBuffer OPTIONAL,
IN ULONG OutputBufferLength);
-
NTSYSAPI NTSTATUS NTAPI RtlGetVersion(
- _Inout_ PRTL_OSVERSIONINFOW lpVersionInformation
-);
+ _Inout_ PRTL_OSVERSIONINFOW lpVersionInformation);
NTSYSAPI NTSTATUS NTAPI NtQueryDirectoryFile(
IN HANDLE FileHandle,
@@ -49,29 +47,26 @@ NTSYSAPI NTSTATUS NTAPI NtQueryDirectoryFile(
IN BOOLEAN RestartScan);
// https://ntdoc.m417z.com/process_devicemap_information_ex
-typedef struct _PROCESS_DEVICEMAP_INFORMATION_EX
-{
- union
- {
+typedef struct _PROCESS_DEVICEMAP_INFORMATION_EX {
+ union {
struct
{
HANDLE DirectoryHandle; // A handle to a directory object that can be set as the new device map for the process. This handle must have DIRECTORY_TRAVERSE access.
} Set;
struct
{
- ULONG DriveMap; // A bitmask that indicates which drive letters are currently in use in the process's device map.
- UCHAR DriveType[32]; // A value that indicates the type of each drive (e.g., local disk, network drive, etc.). // DRIVE_* WinBase.h
+ ULONG DriveMap; // A bitmask that indicates which drive letters are currently in use in the process's device map.
+ UCHAR DriveType[32]; // A value that indicates the type of each drive (e.g., local disk, network drive, etc.). // DRIVE_* WinBase.h
} Query;
};
ULONG Flags; // PROCESS_LUID_DOSDEVICES_ONLY
} PROCESS_DEVICEMAP_INFORMATION_EX, *PPROCESS_DEVICEMAP_INFORMATION_EX;
#ifndef NtCurrentProcess
-#define NtCurrentProcess() ((HANDLE)(LONG_PTR)-1)
+ #define NtCurrentProcess() ((HANDLE) (LONG_PTR) - 1)
#endif
-typedef struct _CURDIR
-{
+typedef struct _CURDIR {
UNICODE_STRING DosPath;
HANDLE Handle;
} CURDIR, *PCURDIR;
@@ -81,15 +76,13 @@ NTSYSAPI PIMAGE_NT_HEADERS NTAPI RtlImageNtHeader(IN PVOID BaseOfImage);
/**
* The SECTION_IMAGE_INFORMATION structure contains detailed information about an image section.
*/
-typedef struct _SECTION_IMAGE_INFORMATION
-{
- PVOID TransferAddress; // The address of the image entry point function.
- ULONG ZeroBits; // The number of high-order address bits that must be zero in the image base address.
- SIZE_T MaximumStackSize; // The maximum stack size of threads from the PE file header.
- SIZE_T CommittedStackSize; // The initial stack size of threads from the PE file header.
- ULONG SubSystemType; // The image subsystem from the PE file header (e.g., Windows GUI, Windows CUI, POSIX).
- union
- {
+typedef struct _SECTION_IMAGE_INFORMATION {
+ PVOID TransferAddress; // The address of the image entry point function.
+ ULONG ZeroBits; // The number of high-order address bits that must be zero in the image base address.
+ SIZE_T MaximumStackSize; // The maximum stack size of threads from the PE file header.
+ SIZE_T CommittedStackSize; // The initial stack size of threads from the PE file header.
+ ULONG SubSystemType; // The image subsystem from the PE file header (e.g., Windows GUI, Windows CUI, POSIX).
+ union {
struct
{
USHORT SubSystemMinorVersion;
@@ -97,8 +90,7 @@ typedef struct _SECTION_IMAGE_INFORMATION
};
ULONG SubSystemVersion;
};
- union
- {
+ union {
struct
{
USHORT MajorOperatingSystemVersion;
@@ -106,35 +98,32 @@ typedef struct _SECTION_IMAGE_INFORMATION
};
ULONG OperatingSystemVersion;
};
- USHORT ImageCharacteristics; // The image characteristics from the PE file header.
- USHORT DllCharacteristics; // The DLL characteristics flags (e.g., ASLR, NX compatibility).
- USHORT Machine; // The image architecture (e.g., x86, x64, ARM).
- BOOLEAN ImageContainsCode; // The image contains native executable code.
- union
- {
+ USHORT ImageCharacteristics; // The image characteristics from the PE file header.
+ USHORT DllCharacteristics; // The DLL characteristics flags (e.g., ASLR, NX compatibility).
+ USHORT Machine; // The image architecture (e.g., x86, x64, ARM).
+ BOOLEAN ImageContainsCode; // The image contains native executable code.
+ union {
UCHAR ImageFlags;
struct
{
- UCHAR ComPlusNativeReady : 1; // The image contains precompiled .NET assembly generated by NGEN (Native Image Generator).
- UCHAR ComPlusILOnly : 1; // the image contains only Microsoft Intermediate Language (IL) assembly.
- UCHAR ImageDynamicallyRelocated : 1; // The image was mapped using a random base address rather than the preferred base address.
- UCHAR ImageMappedFlat : 1; // The image was mapped using a single contiguous region, rather than separate regions for each section.
- UCHAR BaseBelow4gb : 1; // The image was mapped using a base address below the 4 GB boundary.
- UCHAR ComPlusPrefer32bit : 1; // The image prefers to run as a 32-bit process, even on a 64-bit system.
+ UCHAR ComPlusNativeReady : 1; // The image contains precompiled .NET assembly generated by NGEN (Native Image Generator).
+ UCHAR ComPlusILOnly : 1; // the image contains only Microsoft Intermediate Language (IL) assembly.
+ UCHAR ImageDynamicallyRelocated : 1; // The image was mapped using a random base address rather than the preferred base address.
+ UCHAR ImageMappedFlat : 1; // The image was mapped using a single contiguous region, rather than separate regions for each section.
+ UCHAR BaseBelow4gb : 1; // The image was mapped using a base address below the 4 GB boundary.
+ UCHAR ComPlusPrefer32bit : 1; // The image prefers to run as a 32-bit process, even on a 64-bit system.
UCHAR Reserved : 2;
};
};
- ULONG LoaderFlags; // Reserved by ntdll.dll for the Windows loader.
- ULONG ImageFileSize; // The size of the image, in bytes, including all headers.
- ULONG CheckSum; // The image file checksum, from the PE optional header.
+ ULONG LoaderFlags; // Reserved by ntdll.dll for the Windows loader.
+ ULONG ImageFileSize; // The size of the image, in bytes, including all headers.
+ ULONG CheckSum; // The image file checksum, from the PE optional header.
} SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION;
-typedef struct _SYSTEM_BOOT_ENVIRONMENT_INFORMATION
-{
+typedef struct _SYSTEM_BOOT_ENVIRONMENT_INFORMATION {
GUID BootIdentifier;
FIRMWARE_TYPE FirmwareType;
- union
- {
+ union {
ULONGLONG BootFlags;
struct
{
@@ -146,15 +135,14 @@ typedef struct _SYSTEM_BOOT_ENVIRONMENT_INFORMATION
ULONGLONG DbgSystemHiveReplace : 1;
ULONGLONG DbgMeasuredLaunchSmmProtections : 1;
ULONGLONG DbgMeasuredLaunchSmmLevel : 7; // 20H1
- ULONGLONG DbgBugCheckRecovery : 1; // 24H2
+ ULONGLONG DbgBugCheckRecovery : 1; // 24H2
ULONGLONG DbgFASR : 1;
ULONGLONG DbgUseCachedBcd : 1;
};
};
} SYSTEM_BOOT_ENVIRONMENT_INFORMATION;
-typedef struct _RTL_PROCESS_MODULE_INFORMATION
-{
+typedef struct _RTL_PROCESS_MODULE_INFORMATION {
PVOID Section;
PVOID MappedBase;
PVOID ImageBase;
@@ -167,8 +155,7 @@ typedef struct _RTL_PROCESS_MODULE_INFORMATION
UCHAR FullPathName[256];
} RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION;
-typedef struct _RTL_PROCESS_MODULES
-{
+typedef struct _RTL_PROCESS_MODULES {
ULONG NumberOfModules;
_Field_size_(NumberOfModules) RTL_PROCESS_MODULE_INFORMATION Modules[1];
} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES;
@@ -184,8 +171,7 @@ NTSTATUS NTAPI NtQuerySystemEnvironmentValueEx(
NTSTATUS NTAPI RtlGUIDFromString(IN PCUNICODE_STRING GuidString, OUT GUID* Guid);
NTSTATUS NTAPI RtlStringFromGUIDEx(IN GUID* Guid, OUT PCUNICODE_STRING GuidString, _In_ BOOLEAN AllocateGuidString);
-typedef struct _SYSTEM_SECUREBOOT_INFORMATION
-{
+typedef struct _SYSTEM_SECUREBOOT_INFORMATION {
BOOLEAN SecureBootEnabled;
BOOLEAN SecureBootCapable;
} SYSTEM_SECUREBOOT_INFORMATION, *PSYSTEM_SECUREBOOT_INFORMATION;
@@ -196,18 +182,15 @@ NTSTATUS NTAPI NtQuerySystemInformationEx(
_In_ ULONG InputBufferLength,
_Out_writes_bytes_opt_(SystemInformationLength) PVOID SystemInformation,
_In_ ULONG SystemInformationLength,
- _Out_opt_ PULONG ReturnLength
-);
+ _Out_opt_ PULONG ReturnLength);
-typedef enum _SYSTEM_FIRMWARE_TABLE_ACTION
-{
+typedef enum _SYSTEM_FIRMWARE_TABLE_ACTION {
SystemFirmwareTableEnumerate,
SystemFirmwareTableGet,
SystemFirmwareTableMax
} SYSTEM_FIRMWARE_TABLE_ACTION;
-typedef struct _SYSTEM_FIRMWARE_TABLE_INFORMATION
-{
+typedef struct _SYSTEM_FIRMWARE_TABLE_INFORMATION {
ULONG ProviderSignature; // (same as the GetSystemFirmwareTable function)
SYSTEM_FIRMWARE_TABLE_ACTION Action;
ULONG TableID;
@@ -220,8 +203,7 @@ NTSYSAPI NTSTATUS NTAPI NtDelayExecution(_In_ BOOLEAN Alertable, _In_ PLARGE_INT
/**
* The KSYSTEM_TIME structure represents interrupt time, system time, and time zone bias.
*/
-typedef struct _KSYSTEM_TIME
-{
+typedef struct _KSYSTEM_TIME {
ULONG LowPart;
LONG High1Time;
LONG High2Time;
@@ -240,8 +222,7 @@ typedef struct _KSYSTEM_TIME
* \remarks NEC98x86 represents the NEC PC-98 architecture,
* supported only on very early Windows releases.
*/
-typedef enum _ALTERNATIVE_ARCHITECTURE_TYPE
-{
+typedef enum _ALTERNATIVE_ARCHITECTURE_TYPE {
StandardDesign,
NEC98x86,
EndAlternatives
@@ -252,8 +233,7 @@ typedef enum _ALTERNATIVE_ARCHITECTURE_TYPE
*
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/ns-ntddk-kuser_shared_data
*/
-typedef struct _KUSER_SHARED_DATA
-{
+typedef struct _KUSER_SHARED_DATA {
//
// Current low 32-bit of tick count and tick count multiplier.
//
@@ -344,14 +324,13 @@ typedef struct _KUSER_SHARED_DATA
// This value controls Application Compatibility (AppCompat) switchback processing.
//
- union
- {
+ union {
ULONG AppCompatFlag;
struct
{
- ULONG SwitchbackEnabled : 1; // Basic switchback processing
- ULONG ExtendedHeuristics : 1; // Extended switchback heuristics
- ULONG TelemetryFallback : 1; // Telemetry-driven fallback
+ ULONG SwitchbackEnabled : 1; // Basic switchback processing
+ ULONG ExtendedHeuristics : 1; // Extended switchback heuristics
+ ULONG TelemetryFallback : 1; // Telemetry-driven fallback
ULONG Reserved : 29;
} AppCompatFlags;
};
@@ -435,13 +414,12 @@ typedef struct _KUSER_SHARED_DATA
BOOLEAN ProcessorFeatures[PROCESSOR_FEATURE_MAX];
-
//
// Reserved fields - do not use.
//
ULONG MaximumUserModeAddressDeprecated; // Deprecated, use SystemBasicInformation instead.
- ULONG SystemRangeStartDeprecated; // Deprecated, use SystemRangeStartInformation instead.
+ ULONG SystemRangeStartDeprecated; // Deprecated, use SystemRangeStartInformation instead.
//
// Time slippage while in debugger.
@@ -489,8 +467,7 @@ typedef struct _KUSER_SHARED_DATA
// Mitigation policies.
//
- union
- {
+ union {
UCHAR MitigationPolicies;
struct
{
@@ -562,8 +539,7 @@ typedef struct _KUSER_SHARED_DATA
// Virtualization flags.
//
- union
- {
+ union {
UCHAR VirtualizationFlags;
#if defined(_ARM64_)
@@ -580,7 +556,6 @@ typedef struct _KUSER_SHARED_DATA
};
#endif
-
};
//
@@ -598,8 +573,7 @@ typedef struct _KUSER_SHARED_DATA
// API for an accurate result
//
- union
- {
+ union {
ULONG SharedDataFlags;
struct
{
@@ -608,20 +582,20 @@ typedef struct _KUSER_SHARED_DATA
// Use the bit definitions instead.
//
- ULONG DbgErrorPortPresent : 1;
- ULONG DbgElevationEnabled : 1;
- ULONG DbgVirtEnabled : 1;
+ ULONG DbgErrorPortPresent : 1;
+ ULONG DbgElevationEnabled : 1;
+ ULONG DbgVirtEnabled : 1;
ULONG DbgInstallerDetectEnabled : 1;
- ULONG DbgLkgEnabled : 1;
- ULONG DbgDynProcessorEnabled : 1;
- ULONG DbgConsoleBrokerEnabled : 1;
- ULONG DbgSecureBootEnabled : 1;
- ULONG DbgMultiSessionSku : 1;
+ ULONG DbgLkgEnabled : 1;
+ ULONG DbgDynProcessorEnabled : 1;
+ ULONG DbgConsoleBrokerEnabled : 1;
+ ULONG DbgSecureBootEnabled : 1;
+ ULONG DbgMultiSessionSku : 1;
ULONG DbgMultiUsersInSessionSku : 1;
ULONG DbgStateSeparationEnabled : 1;
- ULONG DbgSplitTokenEnabled : 1;
- ULONG DbgShadowAdminEnabled : 1;
- ULONG SpareBits : 19;
+ ULONG DbgSplitTokenEnabled : 1;
+ ULONG DbgShadowAdminEnabled : 1;
+ ULONG SpareBits : 19;
};
};
@@ -630,63 +604,57 @@ typedef struct _KUSER_SHARED_DATA
#define SharedUserData ((const KUSER_SHARED_DATA*) 0x7FFE0000UL)
-static inline uint64_t ffKSystemTimeToUInt64(const volatile KSYSTEM_TIME* pTime)
-{
- #if _WIN64
+static inline uint64_t ffKSystemTimeToUInt64(const volatile KSYSTEM_TIME* pTime) {
+#if _WIN64
// This is safe even if pTime is not 8-byte aligned
// See https://learn.microsoft.com/en-us/windows/win32/winprog64/fault-alignments
return *(const volatile uint64_t*) pTime;
- #else
+#else
uint32_t low, high1, high2;
do {
- high1 = pTime->High1Time;
- low = pTime->LowPart;
- high2 = pTime->High2Time;
+ high1 = (uint32_t) pTime->High1Time;
+ low = (uint32_t) pTime->LowPart;
+ high2 = (uint32_t) pTime->High2Time;
} while (high1 != high2);
return ((uint64_t) high1 << 32) | low;
- #endif
+#endif
}
-static inline bool ffIsWindows10OrGreater()
-{
- #if FF_WIN81_COMPAT
+static inline bool ffIsWindows10OrGreater() {
+#if FF_WIN81_COMPAT
return SharedUserData->NtMajorVersion >= 10;
- #else
+#else
return true;
- #endif
+#endif
}
-static inline bool ffIsWindows11OrGreater()
-{
+static inline bool ffIsWindows11OrGreater() {
return ffIsWindows10OrGreater() && SharedUserData->NtBuildNumber >= 22000;
}
NTSYSAPI NTSTATUS NTAPI NtOpenProcessToken(
_In_ HANDLE ProcessHandle,
_In_ ACCESS_MASK DesiredAccess,
- _Out_ PHANDLE TokenHandle
-);
+ _Out_ PHANDLE TokenHandle);
NTSYSAPI NTSTATUS NTAPI NtAdjustPrivilegesToken(
_In_ HANDLE TokenHandle,
_In_ BOOLEAN DisableAllPrivileges,
_In_opt_ PTOKEN_PRIVILEGES NewState,
_In_ ULONG BufferLength,
_Out_writes_bytes_to_opt_(BufferLength, *ReturnLength) PTOKEN_PRIVILEGES PreviousState,
- _Out_opt_ PULONG ReturnLength
-);
+ _Out_opt_ PULONG ReturnLength);
NTSYSAPI NTSTATUS NTAPI NtQueryInformationToken(
_In_ HANDLE TokenHandle,
_In_ TOKEN_INFORMATION_CLASS TokenInformationClass,
_Out_writes_bytes_to_opt_(TokenInformationLength, *ReturnLength) PVOID TokenInformation,
_In_ ULONG TokenInformationLength,
- _Out_ PULONG ReturnLength
-);
-#define NtCurrentProcessToken() ((HANDLE)(LONG_PTR)-4) // for NtQueryInformationToken only; Windows 8+
+ _Out_ PULONG ReturnLength);
+#define NtCurrentProcessToken() ((HANDLE) (LONG_PTR) - 4) // for NtQueryInformationToken only; Windows 8+
NTSYSAPI NTSTATUS NTAPI NtReadFile(
_In_ HANDLE FileHandle,
@@ -697,49 +665,42 @@ NTSYSAPI NTSTATUS NTAPI NtReadFile(
_Out_writes_bytes_(Length) PVOID Buffer,
_In_ ULONG Length,
_In_opt_ PLARGE_INTEGER ByteOffset,
- _In_opt_ PULONG Key
-);
+ _In_opt_ PULONG Key);
NTSYSAPI NTSTATUS NTAPI NtCreateEvent(
_Out_ PHANDLE EventHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
_In_ EVENT_TYPE EventType,
- _In_ BOOLEAN InitialState
-);
+ _In_ BOOLEAN InitialState);
NTSYSAPI NTSTATUS NTAPI NtQueryAttributesFile(
_In_ PCOBJECT_ATTRIBUTES ObjectAttributes,
- _Out_ PFILE_BASIC_INFORMATION FileInformation
-);
+ _Out_ PFILE_BASIC_INFORMATION FileInformation);
NTSYSAPI NTSTATUS NTAPI RtlUnicodeToUTF8N(
_Out_writes_bytes_to_(UTF8StringMaxByteCount, *UTF8StringActualByteCount) PCHAR UTF8StringDestination,
_In_ ULONG UTF8StringMaxByteCount,
_Out_opt_ PULONG UTF8StringActualByteCount,
_In_reads_bytes_(UnicodeStringByteCount) PCWCH UnicodeStringSource,
- _In_ ULONG UnicodeStringByteCount
-);
+ _In_ ULONG UnicodeStringByteCount);
NTSYSAPI NTSTATUS NTAPI RtlUTF8ToUnicodeN(
_Out_writes_bytes_to_(UnicodeStringMaxByteCount, *UnicodeStringActualByteCount) PWSTR UnicodeStringDestination,
_In_ ULONG UnicodeStringMaxByteCount,
_Out_opt_ PULONG UnicodeStringActualByteCount,
_In_reads_bytes_(UTF8StringByteCount) PCCH UTF8StringSource,
- _In_ ULONG UTF8StringByteCount
-);
+ _In_ ULONG UTF8StringByteCount);
#define RTL_MAX_DRIVE_LETTERS 32
-typedef struct _RTL_DRIVE_LETTER_CURDIR
-{
+typedef struct _RTL_DRIVE_LETTER_CURDIR {
USHORT Flags;
USHORT Length;
ULONG TimeStamp;
STRING DosPath;
} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR;
-typedef struct _RTL_USER_PROCESS_PARAMETERS_FULL
-{
+typedef struct _RTL_USER_PROCESS_PARAMETERS_FULL {
ULONG MaximumLength;
ULONG Length;
@@ -794,8 +755,7 @@ typedef struct CPTABLEINFO* PCPTABLEINFO;
typedef struct NLSTABLEINFO* PNLSTABLEINFO;
typedef struct GDI_HANDLE_ENTRY* PGDI_HANDLE_ENTRY;
-typedef struct _PEB_FULL
-{
+typedef struct _PEB_FULL {
//
// The process was cloned with an inherited address space.
//
@@ -811,19 +771,18 @@ typedef struct _PEB_FULL
//
BOOLEAN BeingDebugged;
- union
- {
+ union {
BOOLEAN BitField;
struct
{
- BOOLEAN ImageUsesLargePages : 1; // The process uses large image regions (4 MB).
- BOOLEAN IsProtectedProcess : 1; // The process is a protected process.
- BOOLEAN IsImageDynamicallyRelocated : 1; // The process image base address was relocated.
- BOOLEAN SkipPatchingUser32Forwarders : 1; // The process skipped forwarders for User32.dll functions. 1 for 64-bit, 0 for 32-bit.
- BOOLEAN IsPackagedProcess : 1; // The process is a packaged store process (APPX/MSIX).
- BOOLEAN IsAppContainerProcess : 1; // The process has an AppContainer token.
- BOOLEAN IsProtectedProcessLight : 1; // The process is a protected process (light).
- BOOLEAN IsLongPathAwareProcess : 1; // The process is long path aware.
+ BOOLEAN ImageUsesLargePages : 1; // The process uses large image regions (4 MB).
+ BOOLEAN IsProtectedProcess : 1; // The process is a protected process.
+ BOOLEAN IsImageDynamicallyRelocated : 1; // The process image base address was relocated.
+ BOOLEAN SkipPatchingUser32Forwarders : 1; // The process skipped forwarders for User32.dll functions. 1 for 64-bit, 0 for 32-bit.
+ BOOLEAN IsPackagedProcess : 1; // The process is a packaged store process (APPX/MSIX).
+ BOOLEAN IsAppContainerProcess : 1; // The process has an AppContainer token.
+ BOOLEAN IsProtectedProcessLight : 1; // The process is a protected process (light).
+ BOOLEAN IsLongPathAwareProcess : 1; // The process is long path aware.
};
};
@@ -875,19 +834,18 @@ typedef struct _PEB_FULL
//
// Cross process flags.
//
- union
- {
+ union {
ULONG CrossProcessFlags;
struct
{
- ULONG ProcessInJob : 1; // The process is part of a job.
- ULONG ProcessInitializing : 1; // The process is initializing.
- ULONG ProcessUsingVEH : 1; // The process is using VEH.
- ULONG ProcessUsingVCH : 1; // The process is using VCH.
- ULONG ProcessUsingFTH : 1; // The process is using FTH.
- ULONG ProcessPreviouslyThrottled : 1; // The process was previously throttled.
- ULONG ProcessCurrentlyThrottled : 1; // The process is currently throttled.
- ULONG ProcessImagesHotPatched : 1; // The process images are hot patched. // RS5
+ ULONG ProcessInJob : 1; // The process is part of a job.
+ ULONG ProcessInitializing : 1; // The process is initializing.
+ ULONG ProcessUsingVEH : 1; // The process is using VEH.
+ ULONG ProcessUsingVCH : 1; // The process is using VCH.
+ ULONG ProcessUsingFTH : 1; // The process is using FTH.
+ ULONG ProcessPreviouslyThrottled : 1; // The process was previously throttled.
+ ULONG ProcessCurrentlyThrottled : 1; // The process is currently throttled.
+ ULONG ProcessImagesHotPatched : 1; // The process images are hot patched. // RS5
ULONG ReservedBits0 : 24;
};
};
@@ -895,8 +853,7 @@ typedef struct _PEB_FULL
//
// User32 KERNEL_CALLBACK_TABLE (ntuser.h)
//
- union
- {
+ union {
PKERNEL_CALLBACK_TABLE KernelCallbackTable;
PVOID UserSharedInfoPtr;
};
@@ -969,8 +926,7 @@ typedef struct _PEB_FULL
//
// Global flags for the system.
//
- union
- {
+ union {
ULONG NtGlobalFlag;
struct
{
@@ -1115,8 +1071,7 @@ typedef struct _PEB_FULL
// ...
} PEB_FULL, *PPEB_FULL;
-typedef struct _TEB_FULL
-{
+typedef struct _TEB_FULL {
//
// Thread Information Block (TIB) contains the thread's stack, base and limit addresses, the current stack pointer, and the exception list.
//
@@ -1188,13 +1143,11 @@ typedef struct _TEB_FULL
LCID CurrentLocale;
} TEB_FULL, *PTEB_FULL;
-static inline PTEB_FULL ffGetTeb()
-{
+static inline PTEB_FULL ffGetTeb() {
return (PTEB_FULL) NtCurrentTeb();
}
-static inline PPEB_FULL ffGetPeb()
-{
+static inline PPEB_FULL ffGetPeb() {
return ffGetTeb()->ProcessEnvironmentBlock;
}
@@ -1204,23 +1157,20 @@ NTSYSAPI NTSTATUS NTAPI RtlExpandEnvironmentStrings(
_In_ SIZE_T SourceLength,
_Out_writes_(DestinationLength) PWSTR Destination,
_In_ SIZE_T DestinationLength,
- _Out_opt_ PSIZE_T ReturnLength
-);
+ _Out_opt_ PSIZE_T ReturnLength);
NTSYSAPI NTSTATUS NTAPI NtOpenKey(
_Out_ PHANDLE KeyHandle,
_In_ ACCESS_MASK DesiredAccess,
- _In_ POBJECT_ATTRIBUTES ObjectAttributes
-);
-
-typedef enum _KEY_VALUE_INFORMATION_CLASS
-{
- KeyValueBasicInformation, // KEY_VALUE_BASIC_INFORMATION
- KeyValueFullInformation, // KEY_VALUE_FULL_INFORMATION
- KeyValuePartialInformation, // KEY_VALUE_PARTIAL_INFORMATION
- KeyValueFullInformationAlign64, // KEY_VALUE_FULL_INFORMATION_ALIGN64
- KeyValuePartialInformationAlign64, // KEY_VALUE_PARTIAL_INFORMATION_ALIGN64
- KeyValueLayerInformation, // KEY_VALUE_LAYER_INFORMATION
+ _In_ POBJECT_ATTRIBUTES ObjectAttributes);
+
+typedef enum _KEY_VALUE_INFORMATION_CLASS {
+ KeyValueBasicInformation, // KEY_VALUE_BASIC_INFORMATION
+ KeyValueFullInformation, // KEY_VALUE_FULL_INFORMATION
+ KeyValuePartialInformation, // KEY_VALUE_PARTIAL_INFORMATION
+ KeyValueFullInformationAlign64, // KEY_VALUE_FULL_INFORMATION_ALIGN64
+ KeyValuePartialInformationAlign64, // KEY_VALUE_PARTIAL_INFORMATION_ALIGN64
+ KeyValueLayerInformation, // KEY_VALUE_LAYER_INFORMATION
MaxKeyValueInfoClass
} KEY_VALUE_INFORMATION_CLASS;
@@ -1230,34 +1180,30 @@ NTSYSAPI NTSTATUS NTAPI NtQueryValueKey(
_In_ KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
_Out_writes_bytes_to_opt_(Length, *ResultLength) PVOID KeyValueInformation,
_In_ ULONG Length,
- _Out_ PULONG ResultLength
-);
+ _Out_ PULONG ResultLength);
NTSYSAPI NTSTATUS NTAPI RtlOpenCurrentUser(
_In_ ACCESS_MASK DesiredAccess,
- _Out_ PHANDLE CurrentUserKey
-);
+ _Out_ PHANDLE CurrentUserKey);
-typedef struct _KEY_VALUE_PARTIAL_INFORMATION
-{
+typedef struct _KEY_VALUE_PARTIAL_INFORMATION {
ULONG TitleIndex;
ULONG Type;
ULONG DataLength;
_Field_size_bytes_(DataLength) UCHAR Data[];
} KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION;
-typedef enum _KEY_INFORMATION_CLASS
-{
- KeyBasicInformation, // KEY_BASIC_INFORMATION
- KeyNodeInformation, // KEY_NODE_INFORMATION
- KeyFullInformation, // KEY_FULL_INFORMATION
- KeyNameInformation, // KEY_NAME_INFORMATION
- KeyCachedInformation, // KEY_CACHED_INFORMATION
- KeyFlagsInformation, // KEY_FLAGS_INFORMATION
+typedef enum _KEY_INFORMATION_CLASS {
+ KeyBasicInformation, // KEY_BASIC_INFORMATION
+ KeyNodeInformation, // KEY_NODE_INFORMATION
+ KeyFullInformation, // KEY_FULL_INFORMATION
+ KeyNameInformation, // KEY_NAME_INFORMATION
+ KeyCachedInformation, // KEY_CACHED_INFORMATION
+ KeyFlagsInformation, // KEY_FLAGS_INFORMATION
KeyVirtualizationInformation, // KEY_VIRTUALIZATION_INFORMATION
- KeyHandleTagsInformation, // KEY_HANDLE_TAGS_INFORMATION
- KeyTrustInformation, // KEY_TRUST_INFORMATION
- KeyLayerInformation, // KEY_LAYER_INFORMATION
+ KeyHandleTagsInformation, // KEY_HANDLE_TAGS_INFORMATION
+ KeyTrustInformation, // KEY_TRUST_INFORMATION
+ KeyLayerInformation, // KEY_LAYER_INFORMATION
MaxKeyInfoClass
} KEY_INFORMATION_CLASS;
@@ -1267,19 +1213,16 @@ NTSYSAPI NTSTATUS NTAPI NtEnumerateKey(
_In_ KEY_INFORMATION_CLASS KeyInformationClass,
_Out_writes_bytes_to_opt_(Length, *ResultLength) PVOID KeyInformation,
_In_ ULONG Length,
- _Out_ PULONG ResultLength
-);
+ _Out_ PULONG ResultLength);
-typedef struct _KEY_BASIC_INFORMATION
-{
- LARGE_INTEGER LastWriteTime; // Number of 100-nanosecond intervals since this key or any of its values changed.
- ULONG TitleIndex; // Reserved // A legacy field originally intended for use with localization such as an index of a resource table.
- ULONG NameLength; // The size, in bytes, of the key name string in the Name array.
- _Field_size_bytes_(NameLength) WCHAR Name[]; // The name of the registry key. This string is not null-terminated.
+typedef struct _KEY_BASIC_INFORMATION {
+ LARGE_INTEGER LastWriteTime; // Number of 100-nanosecond intervals since this key or any of its values changed.
+ ULONG TitleIndex; // Reserved // A legacy field originally intended for use with localization such as an index of a resource table.
+ ULONG NameLength; // The size, in bytes, of the key name string in the Name array.
+ _Field_size_bytes_(NameLength) WCHAR Name[]; // The name of the registry key. This string is not null-terminated.
} KEY_BASIC_INFORMATION, *PKEY_BASIC_INFORMATION;
-typedef struct _KEY_FULL_INFORMATION
-{
+typedef struct _KEY_FULL_INFORMATION {
LARGE_INTEGER LastWriteTime;
ULONG TitleIndex;
ULONG ClassOffset;
@@ -1298,40 +1241,34 @@ NTSYSAPI NTSTATUS NTAPI NtQueryKey(
_In_ KEY_INFORMATION_CLASS KeyInformationClass,
_Out_writes_bytes_to_opt_(Length, *ResultLength) PVOID KeyInformation,
_In_ ULONG Length,
- _Out_ PULONG ResultLength
-);
+ _Out_ PULONG ResultLength);
NTSYSAPI NTSTATUS NTAPI NtOpenProcess(
_Out_ PHANDLE ProcessHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ PCOBJECT_ATTRIBUTES ObjectAttributes,
- _In_opt_ PCLIENT_ID ClientId
-);
+ _In_opt_ PCLIENT_ID ClientId);
NTSYSAPI NTSTATUS NTAPI LdrLoadDll(
_In_opt_ PCWSTR DllPath,
_In_opt_ PULONG DllCharacteristics,
_In_ PCUNICODE_STRING DllName,
- _Out_ PVOID *DllHandle
-);
+ _Out_ PVOID* DllHandle);
NTSYSAPI NTSTATUS NTAPI LdrUnloadDll(
- _In_ PVOID DllHandle
-);
+ _In_ PVOID DllHandle);
NTSYSAPI NTSTATUS NTAPI LdrGetDllHandle(
_In_opt_ PCWSTR DllPath,
_In_opt_ PULONG DllCharacteristics,
_In_ PCUNICODE_STRING DllName,
- _Out_ PVOID *DllHandle
-);
+ _Out_ PVOID* DllHandle);
NTSYSAPI NTSTATUS NTAPI LdrGetProcedureAddress(
_In_ PVOID DllHandle,
_In_opt_ PCANSI_STRING ProcedureName,
_In_opt_ ULONG ProcedureNumber,
- _Out_ PVOID *ProcedureAddress
-);
+ _Out_ PVOID* ProcedureAddress);
typedef enum _SECTION_INHERIT {
ViewShare = 1,
@@ -1345,42 +1282,35 @@ NTSYSAPI NTSTATUS NTAPI NtCreateSection(
_In_opt_ PLARGE_INTEGER MaximumSize,
_In_ ULONG SectionPageProtection,
_In_ ULONG AllocationAttributes,
- _In_opt_ HANDLE FileHandle
-);
+ _In_opt_ HANDLE FileHandle);
NTSYSAPI NTSTATUS NTAPI NtMapViewOfSection(
_In_ HANDLE SectionHandle,
_In_ HANDLE ProcessHandle,
- _Inout_ _At_(*BaseAddress, _Readable_bytes_(*ViewSize) _Writable_bytes_(*ViewSize) _Post_readable_byte_size_(*ViewSize)) PVOID *BaseAddress,
+ _Inout_ _At_(*BaseAddress, _Readable_bytes_(*ViewSize) _Writable_bytes_(*ViewSize) _Post_readable_byte_size_(*ViewSize)) PVOID* BaseAddress,
_In_ ULONG_PTR ZeroBits,
_In_ SIZE_T CommitSize,
_Inout_opt_ PLARGE_INTEGER SectionOffset,
_Inout_ PSIZE_T ViewSize,
_In_ SECTION_INHERIT InheritDisposition,
_In_ ULONG AllocationType,
- _In_ ULONG PageProtection
-);
+ _In_ ULONG PageProtection);
NTSYSAPI NTSTATUS NTAPI NtUnmapViewOfSection(
_In_ HANDLE ProcessHandle,
- _In_opt_ PVOID BaseAddress
-);
+ _In_opt_ PVOID BaseAddress);
NTSYSAPI LOGICAL NTAPI RtlQueryPerformanceCounter(
- _Out_ PLARGE_INTEGER PerformanceCounter
-);
+ _Out_ PLARGE_INTEGER PerformanceCounter);
NTSYSAPI LOGICAL NTAPI RtlQueryPerformanceFrequency(
- _Out_ PLARGE_INTEGER PerformanceFrequency
-);
+ _Out_ PLARGE_INTEGER PerformanceFrequency);
NTSYSAPI NTSTATUS NTAPI NtCancelIoFileEx(
_In_ HANDLE FileHandle,
_In_opt_ PIO_STATUS_BLOCK IoRequestToCancel,
- _Out_ PIO_STATUS_BLOCK IoStatusBlock
-);
+ _Out_ PIO_STATUS_BLOCK IoStatusBlock);
NTSYSAPI NTSTATUS NTAPI NtTerminateProcess(
_In_opt_ HANDLE ProcessHandle,
- _In_ NTSTATUS ExitStatus
-);
+ _In_ NTSTATUS ExitStatus);
diff --git a/src/common/windows/perflib_.h b/src/common/windows/perflib_.h
index 0d261b9636..f30ed541c8 100644
--- a/src/common/windows/perflib_.h
+++ b/src/common/windows/perflib_.h
@@ -5,10 +5,10 @@
// Missing from of MinGW-w64 SDK
-#define PERF_WILDCARD_COUNTER 0xFFFFFFFF
-#define PERF_WILDCARD_INSTANCE L"*"
+#define PERF_WILDCARD_COUNTER 0xFFFFFFFF
+#define PERF_WILDCARD_INSTANCE L"*"
#define PERF_AGGREGATE_INSTANCE L"_Total"
-#define PERF_MAX_INSTANCE_NAME 1024
+#define PERF_MAX_INSTANCE_NAME 1024
typedef struct _PERF_INSTANCE_HEADER {
ULONG Size; // = sizeof(PERF_INSTANCE_HEADER) + sizeof(InstanceName) + sizeof(Padding)
@@ -19,28 +19,28 @@ typedef struct _PERF_INSTANCE_HEADER {
} PERF_INSTANCE_HEADER, *PPERF_INSTANCE_HEADER;
typedef struct _PERF_COUNTER_IDENTIFIER {
- GUID CounterSetGuid; // The GUID of the counterset.
- ULONG Status; // Win32 error code indicating success/failure of the add/delete operation.
- ULONG Size; // sizeof(PERF_COUNTER_IDENTIFIER) + sizeof(InstanceName) + sizeof(Padding)
- ULONG CounterId; // CounterId, or PERF_WILDCARD_COUNTER for all counters.
- ULONG InstanceId; // InstanceId, or 0xFFFFFFFF to not filter on instance ID.
- ULONG Index; // Set by PerfQueryCounterInfo to the position in which the corresponding counter data is returned.
- ULONG Reserved; // Reserved.
+ GUID CounterSetGuid; // The GUID of the counterset.
+ ULONG Status; // Win32 error code indicating success/failure of the add/delete operation.
+ ULONG Size; // sizeof(PERF_COUNTER_IDENTIFIER) + sizeof(InstanceName) + sizeof(Padding)
+ ULONG CounterId; // CounterId, or PERF_WILDCARD_COUNTER for all counters.
+ ULONG InstanceId; // InstanceId, or 0xFFFFFFFF to not filter on instance ID.
+ ULONG Index; // Set by PerfQueryCounterInfo to the position in which the corresponding counter data is returned.
+ ULONG Reserved; // Reserved.
// Followed by:
// WCHAR InstanceName[];
// WCHAR Padding[];
-} PERF_COUNTER_IDENTIFIER, * PPERF_COUNTER_IDENTIFIER;
+} PERF_COUNTER_IDENTIFIER, *PPERF_COUNTER_IDENTIFIER;
typedef struct _PERF_DATA_HEADER {
- ULONG dwTotalSize; // = sizeof(PERF_DATA_HEADER) + sizeof(PERF_COUNTER_HEADER blocks...)
- ULONG dwNumCounters; // The number of PERF_COUNTER_HEADER blocks.
- LONGLONG PerfTimeStamp; // Timestamp from a high-resolution clock.
- LONGLONG PerfTime100NSec; // The number of 100 nanosecond intervals since January 1, 1601, in Coordinated Universal Time (UTC).
- LONGLONG PerfFreq; // The frequency of a high-resolution clock.
- SYSTEMTIME SystemTime; // The time at which data is collected on the provider side.
+ ULONG dwTotalSize; // = sizeof(PERF_DATA_HEADER) + sizeof(PERF_COUNTER_HEADER blocks...)
+ ULONG dwNumCounters; // The number of PERF_COUNTER_HEADER blocks.
+ LONGLONG PerfTimeStamp; // Timestamp from a high-resolution clock.
+ LONGLONG PerfTime100NSec; // The number of 100 nanosecond intervals since January 1, 1601, in Coordinated Universal Time (UTC).
+ LONGLONG PerfFreq; // The frequency of a high-resolution clock.
+ SYSTEMTIME SystemTime; // The time at which data is collected on the provider side.
// Followed by:
// PERF_COUNTER_HEADER blocks...;
-} PERF_DATA_HEADER, * PPERF_DATA_HEADER;
+} PERF_DATA_HEADER, *PPERF_DATA_HEADER;
typedef enum _PerfCounterDataType {
PERF_ERROR_RETURN = 0, /* An error occurred when the performance counter value was queried. */
@@ -51,90 +51,84 @@ typedef enum _PerfCounterDataType {
} PerfCounterDataType;
typedef struct _PERF_COUNTER_HEADER {
- ULONG dwStatus; // Win32 error code indicating success/failure of the query operation.
+ ULONG dwStatus; // Win32 error code indicating success/failure of the query operation.
PerfCounterDataType dwType; // Result type - error, single/single, multi/single, single/multi, multi/multi.
- ULONG dwSize; // = sizeof(PERF_COUNTER_HEADER) + sizeof(Additional data)
- ULONG Reserved; // Reserved.
+ ULONG dwSize; // = sizeof(PERF_COUNTER_HEADER) + sizeof(Additional data)
+ ULONG Reserved; // Reserved.
// Followed by additional data:
// If dwType == PERF_ERROR_RETURN: nothing.
// If dwType == PERF_SINGLE_COUNTER: PERF_COUNTER_DATA block.
// If dwType == PERF_MULTIPLE_COUNTERS: PERF_MULTI_COUNTERS block + PERF_COUNTER_DATA blocks.
// If dwType == PERF_MULTIPLE_INSTANCES: PERF_MULTI_INSTANCES block.
// If dwType == PERF_COUNTERSET: PERF_MULTI_COUNTERS block + PERF_MULTI_INSTANCES block.
-} PERF_COUNTER_HEADER, * PPERF_COUNTER_HEADER;
+} PERF_COUNTER_HEADER, *PPERF_COUNTER_HEADER;
typedef struct _PERF_MULTI_INSTANCES {
- ULONG dwTotalSize; // = sizeof(PERF_MULTI_INSTANCES) + sizeof(instance data blocks...)
- ULONG dwInstances; // Number of instance data blocks.
+ ULONG dwTotalSize; // = sizeof(PERF_MULTI_INSTANCES) + sizeof(instance data blocks...)
+ ULONG dwInstances; // Number of instance data blocks.
// Followed by:
// Instance data blocks...;
-} PERF_MULTI_INSTANCES, * PPERF_MULTI_INSTANCES;
+} PERF_MULTI_INSTANCES, *PPERF_MULTI_INSTANCES;
typedef struct _PERF_MULTI_COUNTERS {
- ULONG dwSize; // sizeof(PERF_MULTI_COUNTERS) + sizeof(CounterIds)
- ULONG dwCounters; // Number of counter ids.
+ ULONG dwSize; // sizeof(PERF_MULTI_COUNTERS) + sizeof(CounterIds)
+ ULONG dwCounters; // Number of counter ids.
// Followed by:
// DWORD CounterIds[dwCounters];
-} PERF_MULTI_COUNTERS, * PPERF_MULTI_COUNTERS;
+} PERF_MULTI_COUNTERS, *PPERF_MULTI_COUNTERS;
typedef struct _PERF_COUNTER_DATA {
- ULONG dwDataSize; // Size of the counter data, in bytes.
- ULONG dwSize; // = sizeof(PERF_COUNTER_DATA) + sizeof(Data) + sizeof(Padding)
+ ULONG dwDataSize; // Size of the counter data, in bytes.
+ ULONG dwSize; // = sizeof(PERF_COUNTER_DATA) + sizeof(Data) + sizeof(Padding)
// Followed by:
// BYTE Data[dwDataSize];
// BYTE Padding[];
-} PERF_COUNTER_DATA, * PPERF_COUNTER_DATA;
+} PERF_COUNTER_DATA, *PPERF_COUNTER_DATA;
_Success_(return == ERROR_SUCCESS)
-ULONG
-WINAPI
-PerfEnumerateCounterSetInstances(
- _In_opt_z_ LPCWSTR szMachine,
- _In_ LPCGUID pCounterSetId,
- _Out_opt_bytecap_post_bytecount_(cbInstances, *pcbInstancesActual) PPERF_INSTANCE_HEADER pInstances,
- DWORD cbInstances,
- _Out_ LPDWORD pcbInstancesActual
- );
+ ULONG
+ WINAPI
+ PerfEnumerateCounterSetInstances(
+ _In_opt_z_ LPCWSTR szMachine,
+ _In_ LPCGUID pCounterSetId,
+ _Out_opt_bytecap_post_bytecount_(cbInstances, *pcbInstancesActual) PPERF_INSTANCE_HEADER pInstances,
+ DWORD cbInstances,
+ _Out_ LPDWORD pcbInstancesActual);
_Success_(return == ERROR_SUCCESS)
-ULONG
-WINAPI
-PerfOpenQueryHandle(
- _In_opt_z_ LPCWSTR szMachine,
- _Out_ HANDLE * phQuery
- );
+ ULONG
+ WINAPI
+ PerfOpenQueryHandle(
+ _In_opt_z_ LPCWSTR szMachine,
+ _Out_ HANDLE* phQuery);
_Success_(return == ERROR_SUCCESS)
-ULONG
-WINAPI
-PerfCloseQueryHandle(
- _In_ HANDLE hQuery
- );
+ ULONG
+ WINAPI
+ PerfCloseQueryHandle(
+ _In_ HANDLE hQuery);
_Success_(return == ERROR_SUCCESS)
-ULONG
-WINAPI
-PerfAddCounters(
- _In_ HANDLE hQuery,
- _Inout_bytecount_(cbCounters) PPERF_COUNTER_IDENTIFIER pCounters,
- DWORD cbCounters
- );
+ ULONG
+ WINAPI
+ PerfAddCounters(
+ _In_ HANDLE hQuery,
+ _Inout_bytecount_(cbCounters) PPERF_COUNTER_IDENTIFIER pCounters,
+ DWORD cbCounters);
_Success_(return == ERROR_SUCCESS)
-ULONG
-WINAPI
-PerfDeleteCounters(
- _In_ HANDLE hQuery,
- _Inout_bytecount_(cbCounters) PPERF_COUNTER_IDENTIFIER pCounters,
- DWORD cbCounters
- );
+ ULONG
+ WINAPI
+ PerfDeleteCounters(
+ _In_ HANDLE hQuery,
+ _Inout_bytecount_(cbCounters) PPERF_COUNTER_IDENTIFIER pCounters,
+ DWORD cbCounters);
_Success_(return == ERROR_SUCCESS)
-ULONG
-WINAPI
-PerfQueryCounterData(
- _In_ HANDLE hQuery,
- _Out_opt_bytecap_post_bytecount_(cbCounterBlock, *pcbCounterBlockActual) PPERF_DATA_HEADER pCounterBlock,
- DWORD cbCounterBlock,
- _Out_ LPDWORD pcbCounterBlockActual
- );
+ ULONG
+ WINAPI
+ PerfQueryCounterData(
+ _In_ HANDLE hQuery,
+ _Out_opt_bytecap_post_bytecount_(cbCounterBlock, *pcbCounterBlockActual) PPERF_DATA_HEADER pCounterBlock,
+ DWORD cbCounterBlock,
+ _Out_ LPDWORD pcbCounterBlockActual);
diff --git a/src/common/windows/registry.c b/src/common/windows/registry.c
index a8c0204922..b2d6611d75 100644
--- a/src/common/windows/registry.c
+++ b/src/common/windows/registry.c
@@ -9,9 +9,9 @@
static HANDLE hRootKeys[8 /*(uintptr_t) HKEY_CURRENT_USER_LOCAL_SETTINGS - (uintptr_t) HKEY_CLASSES_ROOT + 1*/];
-static const char* hKey2Str(HANDLE hRootKey)
-{
- #define HKEY_CASE(compareKey) if(hRootKey == hRootKeys[(uintptr_t)compareKey - (uintptr_t)HKEY_CLASSES_ROOT]) return #compareKey;
+static const char* hKey2Str(HANDLE hRootKey) {
+#define HKEY_CASE(compareKey) \
+ if (hRootKey == hRootKeys[(uintptr_t) compareKey - (uintptr_t) HKEY_CLASSES_ROOT]) return #compareKey;
HKEY_CASE(HKEY_CLASSES_ROOT)
HKEY_CASE(HKEY_CURRENT_USER)
HKEY_CASE(HKEY_LOCAL_MACHINE)
@@ -20,31 +20,27 @@ static const char* hKey2Str(HANDLE hRootKey)
HKEY_CASE(HKEY_CURRENT_CONFIG)
HKEY_CASE(HKEY_DYN_DATA)
HKEY_CASE(HKEY_CURRENT_USER_LOCAL_SETTINGS)
- #undef HKEY_CASE
+#undef HKEY_CASE
return "UNKNOWN";
}
-HANDLE ffRegGetRootKeyHandle(HKEY hKey)
-{
+HANDLE ffRegGetRootKeyHandle(HKEY hKey) {
assert(hKey);
assert((uintptr_t) hKey >= (uintptr_t) HKEY_CLASSES_ROOT && (uintptr_t) hKey <= (uintptr_t) HKEY_CURRENT_USER_LOCAL_SETTINGS);
- FF_DEBUG("Getting root key handle for HKEY %08llx", (uint64_t)(uintptr_t) hKey);
+ FF_DEBUG("Getting root key handle for HKEY %08llx", (uint64_t) (uintptr_t) hKey);
HANDLE result = hRootKeys[(uintptr_t) hKey - (uintptr_t) HKEY_CLASSES_ROOT];
- if (result)
- {
+ if (result) {
FF_DEBUG("Found cached root key handle for %s -> %p", hKey2Str(result), result);
return result;
}
- switch ((uintptr_t) hKey)
- {
+ switch ((uintptr_t) hKey) {
case (uintptr_t) HKEY_CURRENT_USER: {
NTSTATUS status = RtlOpenCurrentUser(KEY_READ, &result);
- if (!NT_SUCCESS(status))
- {
+ if (!NT_SUCCESS(status)) {
FF_DEBUG("RtlOpenCurrentUser() failed: %s", ffDebugNtStatus(status));
return NULL;
}
@@ -54,13 +50,12 @@ HANDLE ffRegGetRootKeyHandle(HKEY hKey)
case (uintptr_t) HKEY_LOCAL_MACHINE: {
UNICODE_STRING path = RTL_CONSTANT_STRING(L"\\Registry\\Machine");
NTSTATUS status = NtOpenKey(&result, KEY_READ, &(OBJECT_ATTRIBUTES) {
- .Length = sizeof(OBJECT_ATTRIBUTES),
- .RootDirectory = NULL,
- .ObjectName = &path,
- .Attributes = OBJ_CASE_INSENSITIVE,
- });
- if (!NT_SUCCESS(status))
- {
+ .Length = sizeof(OBJECT_ATTRIBUTES),
+ .RootDirectory = NULL,
+ .ObjectName = &path,
+ .Attributes = OBJ_CASE_INSENSITIVE,
+ });
+ if (!NT_SUCCESS(status)) {
FF_DEBUG("NtOpenKey(%ls) failed: %s (0x%08lx)", path.Buffer, ffDebugNtStatus(status), status);
return NULL;
}
@@ -77,8 +72,7 @@ HANDLE ffRegGetRootKeyHandle(HKEY hKey)
return result;
}
-bool ffRegOpenSubkeyForRead(HANDLE hKey, const wchar_t* subKeyW, HANDLE* result, FFstrbuf* error)
-{
+bool ffRegOpenSubkeyForRead(HANDLE hKey, const wchar_t* subKeyW, HANDLE* result, FFstrbuf* error) {
assert(hKey);
assert(subKeyW);
assert(result);
@@ -87,18 +81,16 @@ bool ffRegOpenSubkeyForRead(HANDLE hKey, const wchar_t* subKeyW, HANDLE* result,
USHORT subKeyLen = (USHORT) (wcslen(subKeyW) * sizeof(wchar_t));
if (!NT_SUCCESS(NtOpenKey(result, KEY_READ, &(OBJECT_ATTRIBUTES) {
- .Length = sizeof(OBJECT_ATTRIBUTES),
- .RootDirectory = hKey,
- .ObjectName = &(UNICODE_STRING) {
- .Length = subKeyLen,
- .MaximumLength = subKeyLen + (USHORT) sizeof(wchar_t),
- .Buffer = (wchar_t*) subKeyW,
- },
- })))
- {
+ .Length = sizeof(OBJECT_ATTRIBUTES),
+ .RootDirectory = hKey,
+ .ObjectName = &(UNICODE_STRING) {
+ .Length = subKeyLen,
+ .MaximumLength = subKeyLen + (USHORT) sizeof(wchar_t),
+ .Buffer = (wchar_t*) subKeyW,
+ },
+ }))) {
FF_DEBUG("NtOpenKey(%s\\) failed", hKey2Str(hKey));
- if (error)
- {
+ if (error) {
FF_STRBUF_AUTO_DESTROY subKeyA = ffStrbufCreateWS(subKeyW);
ffStrbufAppendF(error, "NtOpenKey(%s\\%s) failed", hKey2Str(hKey), subKeyA.chars);
}
@@ -108,24 +100,22 @@ bool ffRegOpenSubkeyForRead(HANDLE hKey, const wchar_t* subKeyW, HANDLE* result,
return true;
}
-static bool processRegValue(const FFRegValueArg* arg, const ULONG regType, const void* regData, ULONG regDataLen, FFstrbuf* error)
-{
- switch (arg->type)
- {
- case FF_ARG_TYPE_STRBUF:
- {
- if (regType != REG_SZ && regType != REG_EXPAND_SZ)
+static bool processRegValue(const FFRegValueArg* arg, const ULONG regType, const void* regData, ULONG regDataLen, FFstrbuf* error) {
+ switch (arg->type) {
+ case FF_ARG_TYPE_STRBUF: {
+ if (regType != REG_SZ && regType != REG_EXPAND_SZ) {
goto type_mismatch;
+ }
FFstrbuf* strbuf = (FFstrbuf*) arg->value;
uint32_t strLen = regDataLen / sizeof(wchar_t);
- if (strLen == 0)
+ if (strLen == 0) {
ffStrbufClear(strbuf);
- else
- {
+ } else {
const wchar_t* ws = (const wchar_t*) regData;
- if (ws[strLen - 1] == L'\0')
+ if (ws[strLen - 1] == L'\0') {
--strLen;
+ }
ffStrbufSetNWS(strbuf, strLen, ws);
}
break;
@@ -135,73 +125,65 @@ static bool processRegValue(const FFRegValueArg* arg, const ULONG regType, const
case FF_ARG_TYPE_UINT64:
case FF_ARG_TYPE_UINT16:
case FF_ARG_TYPE_UINT8:
- case FF_ARG_TYPE_BOOL:
- {
+ case FF_ARG_TYPE_BOOL: {
uint64_t value = 0;
- if (regType == REG_DWORD)
- {
- if (regDataLen < sizeof(uint32_t))
+ if (regType == REG_DWORD) {
+ if (regDataLen < sizeof(uint32_t)) {
goto type_mismatch;
+ }
value = *(uint32_t*) regData;
- }
- else if (regType == REG_QWORD)
- {
- if (regDataLen < sizeof(uint64_t))
+ } else if (regType == REG_QWORD) {
+ if (regDataLen < sizeof(uint64_t)) {
goto type_mismatch;
+ }
value = *(uint64_t*) regData;
- }
- else
+ } else {
goto type_mismatch;
+ }
- if (arg->type == FF_ARG_TYPE_UINT) *(uint32_t*) arg->value = (uint32_t) value;
- else if (arg->type == FF_ARG_TYPE_UINT64) *(uint64_t*) arg->value = (uint64_t) value;
- else if (arg->type == FF_ARG_TYPE_UINT16) *(uint16_t*) arg->value = (uint16_t) value;
- else if (arg->type == FF_ARG_TYPE_UINT8) *(uint8_t*) arg->value = (uint8_t) value;
- else if (arg->type == FF_ARG_TYPE_BOOL) *(bool*) arg->value = value != 0;
+ if (arg->type == FF_ARG_TYPE_UINT) {
+ *(uint32_t*) arg->value = (uint32_t) value;
+ } else if (arg->type == FF_ARG_TYPE_UINT64) {
+ *(uint64_t*) arg->value = (uint64_t) value;
+ } else if (arg->type == FF_ARG_TYPE_UINT16) {
+ *(uint16_t*) arg->value = (uint16_t) value;
+ } else if (arg->type == FF_ARG_TYPE_UINT8) {
+ *(uint8_t*) arg->value = (uint8_t) value;
+ } else if (arg->type == FF_ARG_TYPE_BOOL) {
+ *(bool*) arg->value = value != 0;
+ }
break;
}
- case FF_ARG_TYPE_FLOAT:
- {
- if (regDataLen < sizeof(float))
+ case FF_ARG_TYPE_FLOAT: {
+ if (regDataLen < sizeof(float)) {
goto type_mismatch;
+ }
*(float*) arg->value = *(float*) regData;
break;
}
- case FF_ARG_TYPE_DOUBLE:
- {
- if (regDataLen < sizeof(double))
+ case FF_ARG_TYPE_DOUBLE: {
+ if (regDataLen < sizeof(double)) {
goto type_mismatch;
+ }
*(double*) arg->value = *(double*) regData;
break;
}
- case FF_ARG_TYPE_LIST:
- {
- if (regType != REG_MULTI_SZ)
+ case FF_ARG_TYPE_LIST: {
+ if (regType != REG_MULTI_SZ) {
goto type_mismatch;
-
- FFlist* list = (FFlist*) arg->value;
- if (list->elementSize != sizeof(FFstrbuf))
- {
- if (error)
- {
- FF_STRBUF_AUTO_DESTROY nameA = arg->name ? ffStrbufCreateWS(arg->name) : ffStrbufCreateStatic("(default)");
- ffStrbufAppendF(error, "ffRegReadValues(%s) type mismatch: expected list of strbuf for REG_MULTI_SZ", nameA.chars);
- }
- return false;
}
+ FFlist* list = (FFlist*) arg->value;
ffListClear(list);
for (
const wchar_t* ptr = (const wchar_t*) regData;
(const uint8_t*) ptr < (const uint8_t*) regData + regDataLen && *ptr;
- ptr++
- )
- {
+ ptr++) {
uint32_t strLen = (uint32_t) wcsnlen(ptr, regDataLen / sizeof(wchar_t) - (size_t) (ptr - (const wchar_t*) regData));
ffStrbufInitNWS(FF_LIST_ADD(FFstrbuf, *list), strLen, ptr);
ptr += strLen;
@@ -209,20 +191,16 @@ static bool processRegValue(const FFRegValueArg* arg, const ULONG regType, const
break;
}
- case FF_ARG_TYPE_BUFFER:
- {
- if (regType != REG_BINARY)
+ case FF_ARG_TYPE_BUFFER: {
+ if (regType != REG_BINARY) {
goto type_mismatch;
+ }
FFArgBuffer* buffer = (FFArgBuffer*) arg->value;
- if (buffer->length == 0)
- {
+ if (buffer->length == 0) {
buffer->data = malloc(regDataLen);
- }
- else if (buffer->length < regDataLen)
- {
- if (error)
- {
+ } else if (buffer->length < regDataLen) {
+ if (error) {
FF_STRBUF_AUTO_DESTROY nameA = arg->name ? ffStrbufCreateWS(arg->name) : ffStrbufCreateStatic("(default)");
ffStrbufAppendF(error, "ffRegReadValues(%s) buffer too small (%u): expected %u", nameA.chars, (unsigned) buffer->length, (unsigned) regDataLen);
}
@@ -237,8 +215,7 @@ static bool processRegValue(const FFRegValueArg* arg, const ULONG regType, const
case FF_ARG_TYPE_STRING:
case FF_ARG_TYPE_NULL:
default:
- if (error)
- {
+ if (error) {
FF_STRBUF_AUTO_DESTROY nameA = arg->name ? ffStrbufCreateWS(arg->name) : ffStrbufCreateStatic("(default)");
ffStrbufAppendF(error, "processRegValue(%s) unsupported FFArgType %u", nameA.chars, (unsigned) arg->type);
}
@@ -249,18 +226,18 @@ static bool processRegValue(const FFRegValueArg* arg, const ULONG regType, const
type_mismatch:
FF_DEBUG("ffRegReadValues(%ls) type mismatch: regType=%u, argType=%u, dataLen=%u",
- arg->name ?: L"(default)", (unsigned) regType, (unsigned) arg->type, (unsigned) regDataLen);
- if (error)
- {
+ arg->name ?: L"(default)",
+ (unsigned) regType,
+ (unsigned) arg->type,
+ (unsigned) regDataLen);
+ if (error) {
FF_STRBUF_AUTO_DESTROY nameA = arg->name ? ffStrbufCreateWS(arg->name) : ffStrbufCreateStatic("(default)");
- ffStrbufAppendF(error, "ffRegReadValues(%s) type mismatch: regType=%u, argType=%u, dataLen=%u",
- nameA.chars, (unsigned) regType, (unsigned) arg->type, (unsigned) regDataLen);
+ ffStrbufAppendF(error, "ffRegReadValues(%s) type mismatch: regType=%u, argType=%u, dataLen=%u", nameA.chars, (unsigned) regType, (unsigned) arg->type, (unsigned) regDataLen);
}
return false;
}
-bool ffRegReadValue(HANDLE hKey, const FFRegValueArg* arg, FFstrbuf* error)
-{
+bool ffRegReadValue(HANDLE hKey, const FFRegValueArg* arg, FFstrbuf* error) {
UNICODE_STRING* valueNameU = &(UNICODE_STRING) {
.Length = arg->name ? (USHORT) (wcslen(arg->name) * sizeof(wchar_t)) : 0 /*(default)*/,
.MaximumLength = 0,
@@ -272,14 +249,13 @@ bool ffRegReadValue(HANDLE hKey, const FFRegValueArg* arg, FFstrbuf* error)
KEY_VALUE_PARTIAL_INFORMATION* buffer = (KEY_VALUE_PARTIAL_INFORMATION*) &staticBuffer;
DWORD bufSize = sizeof(staticBuffer);
- if (NT_SUCCESS(NtQueryValueKey(hKey, valueNameU, KeyValuePartialInformation, buffer, bufSize, &bufSize)))
+ if (NT_SUCCESS(NtQueryValueKey(hKey, valueNameU, KeyValuePartialInformation, buffer, bufSize, &bufSize))) {
goto process_value;
+ }
- if (bufSize == 0)
- {
+ if (bufSize == 0) {
FF_DEBUG("NtQueryValueKey(%p, %ls) failed (bufSize=0)", hKey, arg->name ?: L"(default)");
- if (error)
- {
+ if (error) {
FF_STRBUF_AUTO_DESTROY valueNameA = arg->name ? ffStrbufCreateWS(arg->name) : ffStrbufCreateStatic("(default)");
ffStrbufAppendF(error, "NtQueryValueKey(%p, %s) failed", hKey, valueNameA.chars);
}
@@ -289,11 +265,9 @@ bool ffRegReadValue(HANDLE hKey, const FFRegValueArg* arg, FFstrbuf* error)
dynamicBuffer = (uint8_t*) malloc(bufSize);
buffer = (KEY_VALUE_PARTIAL_INFORMATION*) dynamicBuffer;
- if (!NT_SUCCESS(NtQueryValueKey(hKey, valueNameU, KeyValuePartialInformation, buffer, bufSize, &bufSize)))
- {
+ if (!NT_SUCCESS(NtQueryValueKey(hKey, valueNameU, KeyValuePartialInformation, buffer, bufSize, &bufSize))) {
FF_DEBUG("NtQueryValueKey(%p, %ls, buffer=%u) failed", hKey, arg->name ?: L"(default)", (unsigned) bufSize);
- if (error)
- {
+ if (error) {
FF_STRBUF_AUTO_DESTROY valueNameA = arg->name ? ffStrbufCreateWS(arg->name) : ffStrbufCreateStatic("(default)");
ffStrbufAppendF(error, "NtQueryValueKey(%p, %s, buffer) failed", hKey, valueNameA.chars);
}
@@ -305,22 +279,22 @@ bool ffRegReadValue(HANDLE hKey, const FFRegValueArg* arg, FFstrbuf* error)
return processRegValue(arg, buffer->Type, buffer->Data, buffer->DataLength, error);
}
-bool ffRegReadValues(HANDLE hKey, uint32_t argc, const FFRegValueArg argv[], FFstrbuf* error)
-{
- if (__builtin_expect(argc == 0, false))
+bool ffRegReadValues(HANDLE hKey, uint32_t argc, const FFRegValueArg argv[], FFstrbuf* error) {
+ if (__builtin_expect(argc == 0, false)) {
return true;
+ }
assert(argv);
FF_AUTO_FREE UNICODE_STRING* names = (UNICODE_STRING*) calloc(argc, sizeof(*names));
FF_AUTO_FREE KEY_VALUE_ENTRY* entries = (KEY_VALUE_ENTRY*) calloc(argc, sizeof(*entries));
- for (uint32_t i = 0; i < argc; ++i)
- {
- if (__builtin_expect(!argv[i].value, false))
- {
+ for (uint32_t i = 0; i < argc; ++i) {
+ if (__builtin_expect(!argv[i].value, false)) {
FF_DEBUG("ffRegReadValues(argv[%u].value) is NULL", (unsigned) i);
- if (error) ffStrbufAppendF(error, "ffRegReadValues(argv[%u].pVar) is NULL", (unsigned) i);
+ if (error) {
+ ffStrbufAppendF(error, "ffRegReadValues(argv[%u].pVar) is NULL", (unsigned) i);
+ }
return false;
}
@@ -333,54 +307,51 @@ bool ffRegReadValues(HANDLE hKey, uint32_t argc, const FFRegValueArg argv[], FFs
}
ULONG bufferSize = argc * 128;
- if (bufferSize < 512)
+ if (bufferSize < 512) {
bufferSize = 512;
+ }
FF_AUTO_FREE uint8_t* buffer = NULL;
- while (true)
- {
+ while (true) {
buffer = (uint8_t*) realloc(buffer, bufferSize);
ULONG writtenSize = bufferSize;
ULONG requiredSize = 0;
NTSTATUS status = NtQueryMultipleValueKey(hKey, entries, argc, buffer, &writtenSize, &requiredSize);
- if (!NT_SUCCESS(status))
- {
+ if (!NT_SUCCESS(status)) {
// Buffer too small: docs guarantee requiredSize is returned when provided.
- if (requiredSize > bufferSize)
- {
+ if (requiredSize > bufferSize) {
FF_DEBUG("NtQueryMultipleValueKey(%p) resize buffer: %u -> %u", hKey, (unsigned) bufferSize, (unsigned) requiredSize);
bufferSize = requiredSize;
continue;
}
FF_DEBUG("NtQueryMultipleValueKey(%p, argc=%u) failed, status=0x%08X", hKey, (unsigned) argc, (unsigned) status);
- if (error)
- ffStrbufAppendF(error, "NtQueryMultipleValueKey(%p, argc=%u) failed, status=0x%08X",
- hKey, (unsigned) argc, (unsigned) status);
+ if (error) {
+ ffStrbufAppendF(error, "NtQueryMultipleValueKey(%p, argc=%u) failed, status=0x%08X", hKey, (unsigned) argc, (unsigned) status);
+ }
return false;
}
break;
}
- for (uint32_t i = 0; i < argc; ++i)
- {
+ for (uint32_t i = 0; i < argc; ++i) {
const FFRegValueArg* arg = &argv[i];
const KEY_VALUE_ENTRY* entry = &entries[i];
FF_DEBUG("Read value[%u] from %p: type=%u, len=%u", (unsigned) i, hKey, (unsigned) entry->Type, (unsigned) entry->DataLength);
- if (!processRegValue(arg, entry->Type, buffer + entry->DataOffset, entry->DataLength, error))
+ if (!processRegValue(arg, entry->Type, buffer + entry->DataOffset, entry->DataLength, error)) {
return false;
+ }
}
return true;
}
-bool ffRegGetSubKey(HANDLE hKey, uint32_t index, FFstrbuf* result, FFstrbuf* error)
-{
+bool ffRegGetSubKey(HANDLE hKey, uint32_t index, FFstrbuf* result, FFstrbuf* error) {
assert(hKey);
assert(result);
@@ -388,11 +359,11 @@ bool ffRegGetSubKey(HANDLE hKey, uint32_t index, FFstrbuf* result, FFstrbuf* err
ULONG bufSize = (ULONG) sizeof(buffer);
KEY_BASIC_INFORMATION* keyInfo = (KEY_BASIC_INFORMATION*) buffer;
- if (!NT_SUCCESS(NtEnumerateKey(hKey, index, KeyBasicInformation, keyInfo, bufSize, &bufSize)))
- {
+ if (!NT_SUCCESS(NtEnumerateKey(hKey, index, KeyBasicInformation, keyInfo, bufSize, &bufSize))) {
FF_DEBUG("NtEnumerateKey(hKey=%p, index=%u) failed", hKey, (unsigned) index);
- if (error)
+ if (error) {
ffStrbufAppendF(error, "NtEnumerateKey(hKey=%p, %u, keyInfo) failed", hKey, (unsigned) index);
+ }
return false;
}
@@ -400,8 +371,7 @@ bool ffRegGetSubKey(HANDLE hKey, uint32_t index, FFstrbuf* result, FFstrbuf* err
return true;
}
-bool ffRegGetNSubKeys(HANDLE hKey, uint32_t* result, FFstrbuf* error)
-{
+bool ffRegGetNSubKeys(HANDLE hKey, uint32_t* result, FFstrbuf* error) {
assert(hKey);
assert(result);
@@ -409,11 +379,11 @@ bool ffRegGetNSubKeys(HANDLE hKey, uint32_t* result, FFstrbuf* error)
ULONG bufSize = sizeof(buffer);
KEY_FULL_INFORMATION* keyInfo = (KEY_FULL_INFORMATION*) buffer;
- if (!NT_SUCCESS(NtQueryKey(hKey, KeyFullInformation, keyInfo, bufSize, &bufSize)))
- {
+ if (!NT_SUCCESS(NtQueryKey(hKey, KeyFullInformation, keyInfo, bufSize, &bufSize))) {
FF_DEBUG("NtQueryKey(hKey=%p, KeyFullInformation) failed", hKey);
- if (error)
+ if (error) {
ffStrbufAppendF(error, "NtQueryKey(hKey=%p, KeyFullInformation, keyInfo) failed", hKey);
+ }
return false;
}
diff --git a/src/common/windows/registry.h b/src/common/windows/registry.h
index b056dd3b6d..9745372415 100644
--- a/src/common/windows/registry.h
+++ b/src/common/windows/registry.h
@@ -5,18 +5,17 @@
#include "common/io.h"
#ifndef HKEY_CURRENT_USER
-#define HKEY_CLASSES_ROOT ((HKEY) (ULONG_PTR)((LONG)0x80000000))
-#define HKEY_CURRENT_USER ((HKEY) (ULONG_PTR)((LONG)0x80000001))
-#define HKEY_LOCAL_MACHINE ((HKEY) (ULONG_PTR)((LONG)0x80000002))
-#define HKEY_USERS ((HKEY) (ULONG_PTR)((LONG)0x80000003))
-#define HKEY_PERFORMANCE_DATA ((HKEY) (ULONG_PTR)((LONG)0x80000004))
-#define HKEY_CURRENT_CONFIG ((HKEY) (ULONG_PTR)((LONG)0x80000005))
-#define HKEY_DYN_DATA ((HKEY) (ULONG_PTR)((LONG)0x80000006))
-#define HKEY_CURRENT_USER_LOCAL_SETTINGS ((HKEY) (ULONG_PTR)((LONG)0x80000007))
+ #define HKEY_CLASSES_ROOT ((HKEY) (ULONG_PTR) ((LONG) 0x80000000))
+ #define HKEY_CURRENT_USER ((HKEY) (ULONG_PTR) ((LONG) 0x80000001))
+ #define HKEY_LOCAL_MACHINE ((HKEY) (ULONG_PTR) ((LONG) 0x80000002))
+ #define HKEY_USERS ((HKEY) (ULONG_PTR) ((LONG) 0x80000003))
+ #define HKEY_PERFORMANCE_DATA ((HKEY) (ULONG_PTR) ((LONG) 0x80000004))
+ #define HKEY_CURRENT_CONFIG ((HKEY) (ULONG_PTR) ((LONG) 0x80000005))
+ #define HKEY_DYN_DATA ((HKEY) (ULONG_PTR) ((LONG) 0x80000006))
+ #define HKEY_CURRENT_USER_LOCAL_SETTINGS ((HKEY) (ULONG_PTR) ((LONG) 0x80000007))
#endif
-typedef struct FFRegValueArg
-{
+typedef struct FFRegValueArg {
FFArgType type;
const void* value;
const wchar_t* name;
@@ -29,40 +28,39 @@ bool ffRegReadValues(HANDLE hKey, uint32_t argc, const FFRegValueArg argv[], FFs
bool ffRegGetSubKey(HANDLE hKey, uint32_t index, FFstrbuf* result, FFstrbuf* error);
bool ffRegGetNSubKeys(HANDLE hKey, uint32_t* result, FFstrbuf* error);
-static inline bool ffRegOpenKeyForRead(HKEY hRootKey, const wchar_t* subKeyW, HANDLE* result, FFstrbuf* error)
-{
+static inline bool ffRegOpenKeyForRead(HKEY hRootKey, const wchar_t* subKeyW, HANDLE* result, FFstrbuf* error) {
return ffRegOpenSubkeyForRead(ffRegGetRootKeyHandle(hRootKey), subKeyW, result, error);
}
-static inline bool ffRegReadStrbuf(HANDLE hKey, const wchar_t* valueNameW, FFstrbuf* result, FFstrbuf* error)
-{
+static inline bool ffRegReadStrbuf(HANDLE hKey, const wchar_t* valueNameW, FFstrbuf* result, FFstrbuf* error) {
return ffRegReadValue(hKey, &(FFRegValueArg) {
- .type = FF_ARG_TYPE_STRBUF,
- .value = result,
- .name = valueNameW,
- }, error);
+ .type = FF_ARG_TYPE_STRBUF,
+ .value = result,
+ .name = valueNameW,
+ },
+ error);
}
-static inline bool ffRegReadUint(HANDLE hKey, const wchar_t* valueNameW, uint32_t* result, FFstrbuf* error)
-{
+static inline bool ffRegReadUint(HANDLE hKey, const wchar_t* valueNameW, uint32_t* result, FFstrbuf* error) {
return ffRegReadValue(hKey, &(FFRegValueArg) {
- .type = FF_ARG_TYPE_UINT,
- .value = result,
- .name = valueNameW,
- }, error);
+ .type = FF_ARG_TYPE_UINT,
+ .value = result,
+ .name = valueNameW,
+ },
+ error);
}
-static inline bool ffRegReadUint64(HANDLE hKey, const wchar_t* valueNameW, uint64_t* result, FFstrbuf* error)
-{
+static inline bool ffRegReadUint64(HANDLE hKey, const wchar_t* valueNameW, uint64_t* result, FFstrbuf* error) {
return ffRegReadValue(hKey, &(FFRegValueArg) {
- .type = FF_ARG_TYPE_UINT64,
- .value = result,
- .name = valueNameW,
- }, error);
+ .type = FF_ARG_TYPE_UINT64,
+ .value = result,
+ .name = valueNameW,
+ },
+ error);
}
-static inline bool ffRegReadData(HANDLE hKey, const wchar_t* valueNameW, FFArgBuffer* buffer, FFstrbuf* error)
-{
+static inline bool ffRegReadData(HANDLE hKey, const wchar_t* valueNameW, FFArgBuffer* buffer, FFstrbuf* error) {
return ffRegReadValue(hKey, &(FFRegValueArg) {
- .type = FF_ARG_TYPE_BUFFER,
- .value = buffer,
- .name = valueNameW,
- }, error);
+ .type = FF_ARG_TYPE_BUFFER,
+ .value = buffer,
+ .name = valueNameW,
+ },
+ error);
}
diff --git a/src/common/windows/unicode.c b/src/common/windows/unicode.c
index 24aa3d5649..06008ba429 100644
--- a/src/common/windows/unicode.c
+++ b/src/common/windows/unicode.c
@@ -2,10 +2,8 @@
#include "common/windows/nt.h"
-void ffStrbufSetNWS(FFstrbuf* result, uint32_t length, const wchar_t* source)
-{
- if(!length)
- {
+void ffStrbufSetNWS(FFstrbuf* result, uint32_t length, const wchar_t* source) {
+ if (!length) {
ffStrbufClear(result);
return;
}
@@ -13,8 +11,7 @@ void ffStrbufSetNWS(FFstrbuf* result, uint32_t length, const wchar_t* source)
ULONG size_needed = 0;
NTSTATUS status = RtlUnicodeToUTF8N(NULL, 0, &size_needed, source, length * sizeof(wchar_t));
- if (size_needed == 0)
- {
+ if (size_needed == 0) {
ffStrbufSetF(result, "RtlUnicodeToUTF8N failed: %X", (unsigned) status);
return;
}
@@ -26,16 +23,15 @@ void ffStrbufSetNWS(FFstrbuf* result, uint32_t length, const wchar_t* source)
result->chars[size_needed] = '\0';
}
-void ffStrbufAppendNWS(FFstrbuf* result, uint32_t length, const wchar_t* source)
-{
- if(!length)
+void ffStrbufAppendNWS(FFstrbuf* result, uint32_t length, const wchar_t* source) {
+ if (!length) {
return;
+ }
ULONG size_needed = 0;
NTSTATUS status = RtlUnicodeToUTF8N(NULL, 0, &size_needed, source, length * sizeof(wchar_t));
- if (size_needed == 0)
- {
+ if (size_needed == 0) {
ffStrbufAppendF(result, "RtlUnicodeToUTF8N failed: %X", (unsigned) status);
return;
}
diff --git a/src/common/windows/unicode.h b/src/common/windows/unicode.h
index 8a31624325..f58b425e5b 100644
--- a/src/common/windows/unicode.h
+++ b/src/common/windows/unicode.h
@@ -6,39 +6,41 @@
void ffStrbufSetNWS(FFstrbuf* result, uint32_t length, const wchar_t* source);
void ffStrbufAppendNWS(FFstrbuf* result, uint32_t length, const wchar_t* source);
-static inline void ffStrbufSetWS(FFstrbuf* result, const wchar_t* source)
-{
- if (!source) return ffStrbufClear(result);
- return ffStrbufSetNWS(result, (uint32_t)wcslen(source), source);
+static inline void ffStrbufSetWS(FFstrbuf* result, const wchar_t* source) {
+ if (!source) {
+ return ffStrbufClear(result);
+ }
+ return ffStrbufSetNWS(result, (uint32_t) wcslen(source), source);
}
-static inline void ffStrbufAppendWS(FFstrbuf* result, const wchar_t* source)
-{
- if (!source) return;
- return ffStrbufAppendNWS(result, (uint32_t)wcslen(source), source);
+static inline void ffStrbufAppendWS(FFstrbuf* result, const wchar_t* source) {
+ if (!source) {
+ return;
+ }
+ return ffStrbufAppendNWS(result, (uint32_t) wcslen(source), source);
}
-static inline void ffStrbufInitNWS(FFstrbuf* result, uint32_t length, const wchar_t* source)
-{
+static inline void ffStrbufInitNWS(FFstrbuf* result, uint32_t length, const wchar_t* source) {
ffStrbufInit(result);
return ffStrbufSetNWS(result, length, source);
}
-static inline void ffStrbufInitWS(FFstrbuf* result, const wchar_t* source)
-{
- if (!source) return ffStrbufInit(result);
- return ffStrbufInitNWS(result, (uint32_t)wcslen(source), source);
+static inline void ffStrbufInitWS(FFstrbuf* result, const wchar_t* source) {
+ if (!source) {
+ return ffStrbufInit(result);
+ }
+ return ffStrbufInitNWS(result, (uint32_t) wcslen(source), source);
}
-static inline FFstrbuf ffStrbufCreateNWS(uint32_t length, const wchar_t* source)
-{
+static inline FFstrbuf ffStrbufCreateNWS(uint32_t length, const wchar_t* source) {
FFstrbuf result;
ffStrbufInitNWS(&result, length, source);
return result;
}
-static inline FFstrbuf ffStrbufCreateWS(const wchar_t* source)
-{
- if (!source) return ffStrbufCreate();
- return ffStrbufCreateNWS((uint32_t)wcslen(source), source);
+static inline FFstrbuf ffStrbufCreateWS(const wchar_t* source) {
+ if (!source) {
+ return ffStrbufCreate();
+ }
+ return ffStrbufCreateNWS((uint32_t) wcslen(source), source);
}
diff --git a/src/common/windows/unicode.hpp b/src/common/windows/unicode.hpp
index 418a206df8..f9c355aa6f 100644
--- a/src/common/windows/unicode.hpp
+++ b/src/common/windows/unicode.hpp
@@ -3,23 +3,20 @@
#ifdef __cplusplus
extern "C" {
-#include "unicode.h"
+ #include "unicode.h"
}
-#include
+ #include
-static inline void ffStrbufInitWSV(FFstrbuf* result, const std::wstring_view source)
-{
+static inline void ffStrbufInitWSV(FFstrbuf* result, const std::wstring_view source) {
return ffStrbufInitNWS(result, (uint32_t) source.size(), source.data());
}
-static inline FFstrbuf ffStrbufCreateWSV(const std::wstring_view source)
-{
+static inline FFstrbuf ffStrbufCreateWSV(const std::wstring_view source) {
return ffStrbufCreateNWS((uint32_t) source.size(), source.data());
}
-static inline void ffStrbufSetWSV(FFstrbuf* result, const std::wstring_view source)
-{
+static inline void ffStrbufSetWSV(FFstrbuf* result, const std::wstring_view source) {
return ffStrbufSetNWS(result, (uint32_t) source.size(), source.data());
}
diff --git a/src/common/windows/util.hpp b/src/common/windows/util.hpp
index 9891d638c1..939f6bb45f 100644
--- a/src/common/windows/util.hpp
+++ b/src/common/windows/util.hpp
@@ -6,14 +6,16 @@
template
struct on_scope_exit {
static_assert(std::is_nothrow_move_constructible::value,
- "Fn must be nothrow move constructible");
+ "Fn must be nothrow move constructible");
- explicit on_scope_exit(Fn &&fn) noexcept
+ explicit on_scope_exit(Fn&& fn) noexcept
: _fn(std::move(fn)) {};
on_scope_exit(const on_scope_exit&) = delete;
on_scope_exit& operator=(const on_scope_exit&) = delete;
- ~on_scope_exit() noexcept { this->_fn(); }
+ ~on_scope_exit() noexcept {
+ this->_fn();
+ }
-private:
+ private:
Fn _fn;
};
diff --git a/src/common/windows/variant.cpp b/src/common/windows/variant.cpp
index fa3b9a0e54..d5610d3085 100644
--- a/src/common/windows/variant.cpp
+++ b/src/common/windows/variant.cpp
@@ -2,8 +2,7 @@
#include
-FFWmiVariant::FFWmiVariant(std::initializer_list strings): FFWmiVariant()
-{
+FFWmiVariant::FFWmiVariant(std::initializer_list strings) : FFWmiVariant() {
SAFEARRAYBOUND bound = {
.cElements = (ULONG) strings.size(),
.lLbound = 0,
diff --git a/src/common/windows/variant.hpp b/src/common/windows/variant.hpp
index b2e68cfa8f..58e46b7d74 100644
--- a/src/common/windows/variant.hpp
+++ b/src/common/windows/variant.hpp
@@ -7,8 +7,7 @@
#include
template
-struct FFBaseVariant: TVariant
-{
+struct FFBaseVariant : TVariant {
bool hasValue() {
return this->vt != VT_EMPTY;
}
@@ -17,8 +16,8 @@ struct FFBaseVariant: TVariant
return this->hasValue();
}
- template T get()
- {
+ template
+ T get() {
// boolean
if constexpr (std::is_same_v) {
assert(this->vt == VT_BOOL);
@@ -29,16 +28,13 @@ struct FFBaseVariant: TVariant
else if constexpr (std::is_same_v) {
assert(this->vt == VT_I1);
return this->cVal;
- }
- else if constexpr (std::is_same_v) {
+ } else if constexpr (std::is_same_v) {
assert(this->vt == VT_I2);
return this->iVal;
- }
- else if constexpr (std::is_same_v) {
+ } else if constexpr (std::is_same_v) {
assert(this->vt == VT_I4 || this->vt == VT_INT);
return this->intVal;
- }
- else if constexpr (std::is_same_v) {
+ } else if constexpr (std::is_same_v) {
assert(this->vt == VT_I8);
return this->llVal;
}
@@ -47,16 +43,13 @@ struct FFBaseVariant: TVariant
else if constexpr (std::is_same_v) {
assert(this->vt == VT_UI1);
return this->bVal;
- }
- else if constexpr (std::is_same_v) {
+ } else if constexpr (std::is_same_v) {
assert(this->vt == VT_UI2);
return this->uiVal;
- }
- else if constexpr (std::is_same_v) {
+ } else if constexpr (std::is_same_v) {
assert(this->vt == VT_UI4 || this->vt == VT_UINT);
return this->uintVal;
- }
- else if constexpr (std::is_same_v) {
+ } else if constexpr (std::is_same_v) {
assert(this->vt == VT_UI8);
return this->ullVal;
}
@@ -65,8 +58,7 @@ struct FFBaseVariant: TVariant
else if constexpr (std::is_same_v) {
assert(this->vt == VT_R4);
return this->fltVal;
- }
- else if constexpr (std::is_same_v) {
+ } else if constexpr (std::is_same_v) {
assert(this->vt == VT_R8);
return this->dblVal;
}
@@ -75,95 +67,98 @@ struct FFBaseVariant: TVariant
else if constexpr (std::is_same_v) {
assert(this->vt == VT_LPSTR);
return this->pcVal;
- }
- else if constexpr (std::is_same_v) {
+ } else if constexpr (std::is_same_v) {
assert(this->vt == VT_BSTR || this->vt == VT_LPWSTR);
- if (this->vt == VT_LPWSTR)
+ if (this->vt == VT_LPWSTR) {
return this->bstrVal;
- else
+ } else {
return { this->bstrVal, SysStringLen(this->bstrVal) };
+ }
}
// array signed
else if constexpr (std::is_same_v>) {
assert(this->vt & VT_ARRAY);
assert((this->vt & ~VT_ARRAY) == VT_I1);
- return std::make_pair((int8_t*)this->parray->pvData, this->parray->cDims);
- }
- else if constexpr (std::is_same_v>) {
+ return std::make_pair((int8_t*) this->parray->pvData, this->parray->cDims);
+ } else if constexpr (std::is_same_v>) {
assert(this->vt & VT_ARRAY);
assert((this->vt & ~VT_ARRAY) == VT_I2);
- return std::make_pair((int16_t*)this->parray->pvData, this->parray->cDims);
- }
- else if constexpr (std::is_same_v>) {
+ return std::make_pair((int16_t*) this->parray->pvData, this->parray->cDims);
+ } else if constexpr (std::is_same_v>) {
assert(this->vt & VT_ARRAY);
assert((this->vt & ~VT_ARRAY) == VT_I4);
- return std::make_pair((int32_t*)this->parray->pvData, this->parray->cDims);
- }
- else if constexpr (std::is_same_v>) {
+ return std::make_pair((int32_t*) this->parray->pvData, this->parray->cDims);
+ } else if constexpr (std::is_same_v>) {
assert(this->vt & VT_ARRAY);
assert((this->vt & ~VT_ARRAY) == VT_I8);
- return std::make_pair((int64_t*)this->parray->pvData, this->parray->cDims);
+ return std::make_pair((int64_t*) this->parray->pvData, this->parray->cDims);
}
// array unsigned
else if constexpr (std::is_same_v>) {
assert(this->vt & VT_ARRAY);
assert((this->vt & ~VT_ARRAY) == VT_UI1);
- return std::make_pair((uint8_t*)this->parray->pvData, this->parray->cDims);
- }
- else if constexpr (std::is_same_v>) {
+ return std::make_pair((uint8_t*) this->parray->pvData, this->parray->cDims);
+ } else if constexpr (std::is_same_v>) {
assert(this->vt & VT_ARRAY);
assert((this->vt & ~VT_ARRAY) == VT_UI2);
- return std::make_pair((uint16_t*)this->parray->pvData, this->parray->cDims);
- }
- else if constexpr (std::is_same_v>) {
+ return std::make_pair((uint16_t*) this->parray->pvData, this->parray->cDims);
+ } else if constexpr (std::is_same_v>) {
assert(this->vt & VT_ARRAY);
assert((this->vt & ~VT_ARRAY) == VT_UI4);
- return std::make_pair((uint32_t*)this->parray->pvData, this->parray->cDims);
- }
- else if constexpr (std::is_same_v>) {
+ return std::make_pair((uint32_t*) this->parray->pvData, this->parray->cDims);
+ } else if constexpr (std::is_same_v>) {
assert(this->vt & VT_ARRAY);
assert((this->vt & ~VT_ARRAY) == VT_UI8);
- return std::make_pair((uint64_t*)this->parray->pvData, this->parray->cDims);
- }
- else {
+ return std::make_pair((uint64_t*) this->parray->pvData, this->parray->cDims);
+ } else {
assert(false && "unsupported type");
__builtin_unreachable();
}
}
};
-struct FFWmiVariant: FFBaseVariant
-{
+struct FFWmiVariant : FFBaseVariant {
FFWmiVariant(const FFWmiVariant&) = delete;
FFWmiVariant(FFWmiVariant&&); // don't define it to enforce NRVO optimization
- explicit FFWmiVariant() { VariantInit(this); }
+ explicit FFWmiVariant() {
+ VariantInit(this);
+ }
explicit FFWmiVariant(std::initializer_list strings);
- ~FFWmiVariant() { VariantClear(this); }
+ ~FFWmiVariant() {
+ VariantClear(this);
+ }
};
static_assert(sizeof(FFWmiVariant) == sizeof(VARIANT), "");
-struct FFPropVariant: FFBaseVariant
-{
+struct FFPropVariant : FFBaseVariant {
FFPropVariant(const FFPropVariant&) = delete;
FFPropVariant(FFPropVariant&&); // don't define it to enforce NRVO optimization
- explicit FFPropVariant() { PropVariantInit(this); }
- ~FFPropVariant() { PropVariantClear(this); }
+ explicit FFPropVariant() {
+ PropVariantInit(this);
+ }
+ ~FFPropVariant() {
+ PropVariantClear(this);
+ }
};
static_assert(sizeof(FFPropVariant) == sizeof(PROPVARIANT), "");
-namespace
-{
- // Provide our bstr_t to avoid libstdc++ dependency
- struct bstr_t
- {
- explicit bstr_t(const wchar_t* str) noexcept: _bstr(SysAllocString(str)) {}
- ~bstr_t(void) noexcept { SysFreeString(_bstr); }
- explicit operator const wchar_t*(void) const noexcept { return _bstr; }
- operator BSTR(void) const noexcept { return _bstr; }
+namespace {
+// Provide our bstr_t to avoid libstdc++ dependency
+struct bstr_t {
+ explicit bstr_t(const wchar_t* str) noexcept : _bstr(SysAllocString(str)) {}
+ ~bstr_t(void) noexcept {
+ SysFreeString(_bstr);
+ }
+ explicit operator const wchar_t*(void) const noexcept {
+ return _bstr;
+ }
+ operator BSTR(void) const noexcept {
+ return _bstr;
+ }
- private:
- BSTR _bstr;
- };
-}
+ private:
+ BSTR _bstr;
+};
+} // namespace
diff --git a/src/common/windows/version.c b/src/common/windows/version.c
index df00e29a2d..6b4c589fed 100644
--- a/src/common/windows/version.c
+++ b/src/common/windows/version.c
@@ -5,53 +5,46 @@
#include
-bool ffGetFileVersion(const wchar_t* filePath, const wchar_t* stringName, FFstrbuf* version)
-{
+bool ffGetFileVersion(const wchar_t* filePath, const wchar_t* stringName, FFstrbuf* version) {
FF_DEBUG("ffGetFileVersion: enter filePath=%ls stringName=%ls", filePath, stringName);
DWORD handle;
DWORD size = GetFileVersionInfoSizeW(filePath, &handle);
- if (size == 0)
- {
+ if (size == 0) {
DWORD err = GetLastError();
FF_DEBUG("GetFileVersionInfoSizeW failed: err=%lu (%s)",
- (unsigned long) err, ffDebugWin32Error(err));
+ (unsigned long) err,
+ ffDebugWin32Error(err));
return false;
}
FF_DEBUG("GetFileVersionInfoSizeW ok: size=%lu handle=%lu",
- (unsigned long) size, (unsigned long) handle);
+ (unsigned long) size,
+ (unsigned long) handle);
FF_AUTO_FREE void* versionData = malloc(size);
- if (!versionData)
- {
+ if (!versionData) {
FF_DEBUG("malloc failed: size=%lu", (unsigned long) size);
return false;
}
- if (!GetFileVersionInfoW(filePath, handle, size, versionData))
- {
+ if (!GetFileVersionInfoW(filePath, handle, size, versionData)) {
DWORD err = GetLastError();
FF_DEBUG("GetFileVersionInfoW failed: err=%lu (%s)",
- (unsigned long) err, ffDebugWin32Error(err));
+ (unsigned long) err,
+ ffDebugWin32Error(err));
return false;
}
FF_DEBUG("GetFileVersionInfoW ok");
- if (!stringName)
- {
+ if (!stringName) {
VS_FIXEDFILEINFO* verInfo;
UINT len;
if (VerQueryValueW(versionData, L"\\", (void**) &verInfo, &len) &&
len &&
- verInfo->dwSignature == 0xFEEF04BD)
- {
- ffStrbufSetF(version, "%u.%u.%u.%u",
- (unsigned) ((verInfo->dwProductVersionMS >> 16) & 0xffff),
- (unsigned) ((verInfo->dwProductVersionMS >> 0) & 0xffff),
- (unsigned) ((verInfo->dwProductVersionLS >> 16) & 0xffff),
- (unsigned) ((verInfo->dwProductVersionLS >> 0) & 0xffff));
+ verInfo->dwSignature == 0xFEEF04BD) {
+ ffStrbufSetF(version, "%u.%u.%u.%u", (unsigned) ((verInfo->dwProductVersionMS >> 16) & 0xffff), (unsigned) ((verInfo->dwProductVersionMS >> 0) & 0xffff), (unsigned) ((verInfo->dwProductVersionLS >> 16) & 0xffff), (unsigned) ((verInfo->dwProductVersionLS >> 0) & 0xffff));
FF_DEBUG("fixed version resolved: %s", version->chars);
return true;
}
@@ -60,30 +53,28 @@ bool ffGetFileVersion(const wchar_t* filePath, const wchar_t* stringName, FFstrb
return false;
}
- struct { WORD language; WORD codePage; }* translations;
+ struct {
+ WORD language;
+ WORD codePage;
+ }* translations;
UINT translationsLen;
if (VerQueryValueW(versionData, L"\\VarFileInfo\\Translation", (void**) &translations, &translationsLen) &&
- translationsLen >= sizeof(*translations))
- {
+ translationsLen >= sizeof(*translations)) {
wchar_t subBlock[128];
- snwprintf(subBlock, ARRAY_SIZE(subBlock), L"\\StringFileInfo\\%04x%04x\\%ls",
- translations[0].language, translations[0].codePage, stringName);
+ snwprintf(subBlock, ARRAY_SIZE(subBlock), L"\\StringFileInfo\\%04x%04x\\%ls", translations[0].language, translations[0].codePage, stringName);
FF_DEBUG("query version string with translation: %ls", subBlock);
wchar_t* value;
UINT valueLen; // Number of characters, including null terminator
- if (VerQueryValueW(versionData, subBlock, (void**) &value, &valueLen) && valueLen > 0)
- {
+ if (VerQueryValueW(versionData, subBlock, (void**) &value, &valueLen) && valueLen > 0) {
ffStrbufSetNWS(version, valueLen - 1, value);
FF_DEBUG("version string resolved (translation fallback): %s", version->chars);
return true;
}
FF_DEBUG("translation fallback query failed");
- }
- else
- {
+ } else {
FF_DEBUG("no translation table found in version resource");
}
diff --git a/src/common/windows/version.h b/src/common/windows/version.h
index 73e7cc1e50..457c0534a8 100644
--- a/src/common/windows/version.h
+++ b/src/common/windows/version.h
@@ -1,6 +1,5 @@
#include "fastfetch.h"
-
/**
* @brief Retrieves a specific version string for a Windows file.
*
diff --git a/src/common/windows/wmi.cpp b/src/common/windows/wmi.cpp
index 74dbb3f194..381bf59224 100644
--- a/src/common/windows/wmi.cpp
+++ b/src/common/windows/wmi.cpp
@@ -6,8 +6,7 @@
#include
#include
-static const char* doInitService(const wchar_t* networkResource, IWbemServices** result)
-{
+static const char* doInitService(const wchar_t* networkResource, IWbemServices** result) {
HRESULT hres;
// Obtain the initial locator to WMI
@@ -19,8 +18,9 @@ static const char* doInitService(const wchar_t* networkResource, IWbemServices**
IID_IWbemLocator,
(LPVOID*) &pLoc);
- if (FAILED(hres))
+ if (FAILED(hres)) {
return "Failed to create IWbemLocator object";
+ }
// Connect to WMI through the IWbemLocator::ConnectServer method
IWbemServices* pSvc = nullptr;
@@ -29,47 +29,46 @@ static const char* doInitService(const wchar_t* networkResource, IWbemServices**
// the current user and obtain pointer pSvc
// to make IWbemServices calls.
hres = pLoc->ConnectServer(
- bstr_t(networkResource), // Object path of WMI namespace
- nullptr, // User name. nullptr = current user
- nullptr, // User password. nullptr = current
- 0, // Locale. nullptr indicates current
- 0, // Security flags.
- 0, // Authority (for example, Kerberos)
- 0, // Context object
- &pSvc // pointer to IWbemServices proxy
+ bstr_t(networkResource), // Object path of WMI namespace
+ nullptr, // User name. nullptr = current user
+ nullptr, // User password. nullptr = current
+ 0, // Locale. nullptr indicates current
+ 0, // Security flags.
+ 0, // Authority (for example, Kerberos)
+ 0, // Context object
+ &pSvc // pointer to IWbemServices proxy
);
pLoc->Release();
pLoc = nullptr;
- if (FAILED(hres))
+ if (FAILED(hres)) {
return "Could not connect WMI server";
+ }
*result = pSvc;
return NULL;
}
-FFWmiQuery::FFWmiQuery(const wchar_t* queryStr, FFstrbuf* error, FFWmiNamespace wmiNs)
-{
+FFWmiQuery::FFWmiQuery(const wchar_t* queryStr, FFstrbuf* error, FFWmiNamespace wmiNs) {
const char* errStr;
- if ((errStr = ffInitCom()))
- {
- if (error)
+ if ((errStr = ffInitCom())) {
+ if (error) {
ffStrbufSetS(error, errStr);
+ }
return;
}
static IWbemServices* contexts[(int) FFWmiNamespace::LAST];
- IWbemServices* context = contexts[(int)wmiNs];
- if (!context)
- {
- if ((errStr = doInitService(wmiNs == FFWmiNamespace::CIMV2 ? L"ROOT\\CIMV2" : L"ROOT\\WMI", &context)))
- {
- if (error)
+ IWbemServices* context = contexts[(int) wmiNs];
+ if (!context) {
+ if ((errStr = doInitService(wmiNs == FFWmiNamespace::CIMV2 ? L"ROOT\\CIMV2" : L"ROOT\\WMI", &context))) {
+ if (error) {
ffStrbufSetS(error, errStr);
+ }
return;
}
- contexts[(int)wmiNs] = context;
+ contexts[(int) wmiNs] = context;
}
this->pService = context;
@@ -82,44 +81,37 @@ FFWmiQuery::FFWmiQuery(const wchar_t* queryStr, FFstrbuf* error, FFWmiNamespace
nullptr,
&this->pEnumerator);
- if (FAILED(hres))
- {
- if(error)
+ if (FAILED(hres)) {
+ if (error) {
ffStrbufAppendF(error, "Query for '%ls' failed. Error code = 0x%lX", queryStr, hres);
+ }
}
}
-bool FFWmiRecord::getString(const wchar_t* key, FFstrbuf* strbuf)
-{
+bool FFWmiRecord::getString(const wchar_t* key, FFstrbuf* strbuf) {
bool result = true;
FFWmiVariant vtProp;
CIMTYPE type;
- if(FAILED(obj->Get(key, 0, &vtProp, &type, nullptr)) || vtProp.vt != VT_BSTR)
- {
+ if (FAILED(obj->Get(key, 0, &vtProp, &type, nullptr)) || vtProp.vt != VT_BSTR) {
result = false;
- }
- else
- {
- switch(vtProp.vt)
- {
+ } else {
+ switch (vtProp.vt) {
case VT_BSTR:
- if(type == CIM_DATETIME)
- {
- FF_AUTO_RELEASE_COM_OBJECT ISWbemDateTime *pDateTime = nullptr;
+ if (type == CIM_DATETIME) {
+ FF_AUTO_RELEASE_COM_OBJECT ISWbemDateTime* pDateTime = nullptr;
BSTR dateStr;
- if(FAILED(CoCreateInstance(__uuidof(SWbemDateTime), 0, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDateTime))))
+ if (FAILED(CoCreateInstance(__uuidof(SWbemDateTime), 0, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDateTime)))) {
result = false;
- else if(FAILED(pDateTime->put_Value(vtProp.bstrVal)))
+ } else if (FAILED(pDateTime->put_Value(vtProp.bstrVal))) {
result = false;
- else if(FAILED(pDateTime->GetFileTime(VARIANT_TRUE, &dateStr)))
+ } else if (FAILED(pDateTime->GetFileTime(VARIANT_TRUE, &dateStr))) {
result = false;
- else
+ } else {
ffStrbufSetNWS(strbuf, SysStringLen(dateStr), dateStr);
- }
- else
- {
+ }
+ } else {
ffStrbufSetNWS(strbuf, SysStringLen(vtProp.bstrVal), vtProp.bstrVal);
}
break;
@@ -137,100 +129,155 @@ bool FFWmiRecord::getString(const wchar_t* key, FFstrbuf* strbuf)
return result;
}
-bool FFWmiRecord::getSigned(const wchar_t* key, int64_t* integer)
-{
+bool FFWmiRecord::getSigned(const wchar_t* key, int64_t* integer) {
bool result = true;
FFWmiVariant vtProp;
CIMTYPE type;
- if(FAILED(obj->Get(key, 0, &vtProp, &type, nullptr)))
- {
+ if (FAILED(obj->Get(key, 0, &vtProp, &type, nullptr))) {
result = false;
- }
- else
- {
- switch(vtProp.vt)
- {
- case VT_BSTR: *integer = wcstoll(vtProp.bstrVal, nullptr, 10); break;
- case VT_I1: *integer = vtProp.cVal; break;
- case VT_I2: *integer = vtProp.iVal; break;
+ } else {
+ switch (vtProp.vt) {
+ case VT_BSTR:
+ *integer = wcstoll(vtProp.bstrVal, nullptr, 10);
+ break;
+ case VT_I1:
+ *integer = vtProp.cVal;
+ break;
+ case VT_I2:
+ *integer = vtProp.iVal;
+ break;
case VT_INT:
- case VT_I4: *integer = vtProp.intVal; break;
- case VT_I8: *integer = vtProp.llVal; break;
- case VT_UI1: *integer = (int64_t)vtProp.bVal; break;
- case VT_UI2: *integer = (int64_t)vtProp.uiVal; break;
+ case VT_I4:
+ *integer = vtProp.intVal;
+ break;
+ case VT_I8:
+ *integer = vtProp.llVal;
+ break;
+ case VT_UI1:
+ *integer = (int64_t) vtProp.bVal;
+ break;
+ case VT_UI2:
+ *integer = (int64_t) vtProp.uiVal;
+ break;
case VT_UINT:
- case VT_UI4: *integer = (int64_t)vtProp.uintVal; break;
- case VT_UI8: *integer = (int64_t)vtProp.ullVal; break;
- case VT_BOOL: *integer = vtProp.boolVal != VARIANT_FALSE; break;
- default: *integer = 0; result = false;
+ case VT_UI4:
+ *integer = (int64_t) vtProp.uintVal;
+ break;
+ case VT_UI8:
+ *integer = (int64_t) vtProp.ullVal;
+ break;
+ case VT_BOOL:
+ *integer = vtProp.boolVal != VARIANT_FALSE;
+ break;
+ default:
+ *integer = 0;
+ result = false;
}
}
return result;
}
-bool FFWmiRecord::getUnsigned(const wchar_t* key, uint64_t* integer)
-{
+bool FFWmiRecord::getUnsigned(const wchar_t* key, uint64_t* integer) {
bool result = true;
FFWmiVariant vtProp;
- if(FAILED(obj->Get(key, 0, &vtProp, nullptr, nullptr)))
- {
+ if (FAILED(obj->Get(key, 0, &vtProp, nullptr, nullptr))) {
result = false;
- }
- else
- {
- switch(vtProp.vt)
- {
- case VT_BSTR: *integer = wcstoull(vtProp.bstrVal, nullptr, 10); break;
- case VT_I1: *integer = (uint64_t)vtProp.cVal; break;
- case VT_I2: *integer = (uint64_t)vtProp.iVal; break;
+ } else {
+ switch (vtProp.vt) {
+ case VT_BSTR:
+ *integer = wcstoull(vtProp.bstrVal, nullptr, 10);
+ break;
+ case VT_I1:
+ *integer = (uint64_t) vtProp.cVal;
+ break;
+ case VT_I2:
+ *integer = (uint64_t) vtProp.iVal;
+ break;
case VT_INT:
- case VT_I4: *integer = (uint64_t)vtProp.intVal; break;
- case VT_I8: *integer = (uint64_t)vtProp.llVal; break;
- case VT_UI1: *integer = vtProp.bVal; break;
- case VT_UI2: *integer = vtProp.uiVal; break;
+ case VT_I4:
+ *integer = (uint64_t) vtProp.intVal;
+ break;
+ case VT_I8:
+ *integer = (uint64_t) vtProp.llVal;
+ break;
+ case VT_UI1:
+ *integer = vtProp.bVal;
+ break;
+ case VT_UI2:
+ *integer = vtProp.uiVal;
+ break;
case VT_UINT:
- case VT_UI4: *integer = vtProp.uintVal; break;
- case VT_UI8: *integer = vtProp.ullVal; break;
- case VT_BOOL: *integer = vtProp.boolVal != VARIANT_FALSE; break;
- default: *integer = 0; result = false;
+ case VT_UI4:
+ *integer = vtProp.uintVal;
+ break;
+ case VT_UI8:
+ *integer = vtProp.ullVal;
+ break;
+ case VT_BOOL:
+ *integer = vtProp.boolVal != VARIANT_FALSE;
+ break;
+ default:
+ *integer = 0;
+ result = false;
}
}
return result;
}
-bool FFWmiRecord::getReal(const wchar_t* key, double* real)
-{
+bool FFWmiRecord::getReal(const wchar_t* key, double* real) {
bool result = true;
FFWmiVariant vtProp;
- if(FAILED(obj->Get(key, 0, &vtProp, nullptr, nullptr)))
- {
+ if (FAILED(obj->Get(key, 0, &vtProp, nullptr, nullptr))) {
result = false;
- }
- else
- {
- switch(vtProp.vt)
- {
- case VT_BSTR: *real = wcstod(vtProp.bstrVal, nullptr); break;
- case VT_I1: *real = vtProp.cVal; break;
- case VT_I2: *real = vtProp.iVal; break;
+ } else {
+ switch (vtProp.vt) {
+ case VT_BSTR:
+ *real = wcstod(vtProp.bstrVal, nullptr);
+ break;
+ case VT_I1:
+ *real = vtProp.cVal;
+ break;
+ case VT_I2:
+ *real = vtProp.iVal;
+ break;
case VT_INT:
- case VT_I4: *real = vtProp.intVal; break;
- case VT_I8: *real = (double)vtProp.llVal; break;
- case VT_UI1: *real = vtProp.bVal; break;
- case VT_UI2: *real = vtProp.uiVal; break;
+ case VT_I4:
+ *real = vtProp.intVal;
+ break;
+ case VT_I8:
+ *real = (double) vtProp.llVal;
+ break;
+ case VT_UI1:
+ *real = vtProp.bVal;
+ break;
+ case VT_UI2:
+ *real = vtProp.uiVal;
+ break;
case VT_UINT:
- case VT_UI4: *real = vtProp.uintVal; break;
- case VT_UI8: *real = (double)vtProp.ullVal; break;
- case VT_R4: *real = vtProp.fltVal; break;
- case VT_R8: *real = vtProp.dblVal; break;
- case VT_BOOL: *real = vtProp.boolVal != VARIANT_FALSE; break;
- default: *real = -DBL_MAX; result = false;
+ case VT_UI4:
+ *real = vtProp.uintVal;
+ break;
+ case VT_UI8:
+ *real = (double) vtProp.ullVal;
+ break;
+ case VT_R4:
+ *real = vtProp.fltVal;
+ break;
+ case VT_R8:
+ *real = vtProp.dblVal;
+ break;
+ case VT_BOOL:
+ *real = vtProp.boolVal != VARIANT_FALSE;
+ break;
+ default:
+ *real = -DBL_MAX;
+ result = false;
}
}
return result;
diff --git a/src/common/windows/wmi.hpp b/src/common/windows/wmi.hpp
index a72a72dccf..47334f78ec 100644
--- a/src/common/windows/wmi.hpp
+++ b/src/common/windows/wmi.hpp
@@ -6,10 +6,10 @@ extern "C" {
#include "fastfetch.h"
}
-#include
-#include
+ #include
+ #include
-#include "variant.hpp"
+ #include "variant.hpp"
enum class FFWmiNamespace {
CIMV2,
@@ -17,17 +17,26 @@ enum class FFWmiNamespace {
LAST,
};
-struct FFWmiRecord
-{
+struct FFWmiRecord {
IWbemClassObject* obj = nullptr;
- explicit FFWmiRecord(IWbemClassObject* obj): obj(obj) {};
+ explicit FFWmiRecord(IWbemClassObject* obj) : obj(obj) {};
FFWmiRecord(const FFWmiRecord&) = delete;
- FFWmiRecord(FFWmiRecord&& other) { *this = (FFWmiRecord&&)other; }
- ~FFWmiRecord() { if(obj) obj->Release(); }
- explicit operator bool() { return !!obj; }
- FFWmiRecord& operator =(FFWmiRecord&& other) {
- if(obj) obj->Release();
+ FFWmiRecord(FFWmiRecord&& other) {
+ *this = (FFWmiRecord&&) other;
+ }
+ ~FFWmiRecord() {
+ if (obj) {
+ obj->Release();
+ }
+ }
+ explicit operator bool() {
+ return !!obj;
+ }
+ FFWmiRecord& operator=(FFWmiRecord&& other) {
+ if (obj) {
+ obj->Release();
+ }
obj = other.obj;
other.obj = nullptr;
return *this;
@@ -44,20 +53,29 @@ struct FFWmiRecord
}
};
-struct FFWmiQuery
-{
+struct FFWmiQuery {
IWbemServices* pService = nullptr;
IEnumWbemClassObject* pEnumerator = nullptr;
FFWmiQuery(const wchar_t* queryStr, FFstrbuf* error = nullptr, FFWmiNamespace wmiNs = FFWmiNamespace::CIMV2);
- explicit FFWmiQuery(IEnumWbemClassObject* pEnumerator): pEnumerator(pEnumerator) {}
+ explicit FFWmiQuery(IEnumWbemClassObject* pEnumerator) : pEnumerator(pEnumerator) {}
FFWmiQuery(const FFWmiQuery& other) = delete;
- FFWmiQuery(FFWmiQuery&& other) { *this = (FFWmiQuery&&)other; }
- ~FFWmiQuery() { if(pEnumerator) pEnumerator->Release(); }
+ FFWmiQuery(FFWmiQuery&& other) {
+ *this = (FFWmiQuery&&) other;
+ }
+ ~FFWmiQuery() {
+ if (pEnumerator) {
+ pEnumerator->Release();
+ }
+ }
- explicit operator bool() { return !!pEnumerator; }
- FFWmiQuery& operator =(FFWmiQuery&& other) {
- if(pEnumerator) pEnumerator->Release();
+ explicit operator bool() {
+ return !!pEnumerator;
+ }
+ FFWmiQuery& operator=(FFWmiQuery&& other) {
+ if (pEnumerator) {
+ pEnumerator->Release();
+ }
pEnumerator = other.pEnumerator;
other.pEnumerator = nullptr;
return *this;
diff --git a/src/data/help.json b/src/data/help.json
index 0be2b8c8e3..da6732fbc3 100644
--- a/src/data/help.json
+++ b/src/data/help.json
@@ -3,7 +3,7 @@
{
"short": "h",
"long": "help",
- "desc": "Display this help message or help for a specific command",
+ "desc": "Show this help message or help for a specific command",
"arg": {
"type": "command",
"optional": true
@@ -12,11 +12,11 @@
{
"short": "v",
"long": "version",
- "desc": "Show the full version of fastfetch"
+ "desc": "Show the full Fastfetch version"
},
{
"long": "version-raw",
- "desc": "Display the raw version string (major.minor.patch)"
+ "desc": "Show the raw version string (major.minor.patch)"
},
{
"long": "list-config-paths",
@@ -36,7 +36,7 @@
},
{
"long": "list-presets",
- "desc": "List presets that fastfetch knows about",
+ "desc": "List available presets",
"remark": "Presets can be loaded with \"--config \""
},
{
@@ -46,15 +46,15 @@
},
{
"long": "print-logos",
- "desc": "Display available logos"
+ "desc": "Show available logos"
},
{
"long": "print-structure",
- "desc": "Display the default structure"
+ "desc": "Show the default structure"
},
{
"long": "format",
- "desc": "Set output format",
+ "desc": "Set the output format",
"arg": {
"type": "enum",
"enum": {
@@ -77,8 +77,8 @@
},
{
"long": "dynamic-interval",
- "desc": "Keep fastfetch open and update the output every milliseconds",
- "remark": "0 (default) to disable the behavior; don't work with --json",
+ "desc": "Keep Fastfetch running and refresh the output every milliseconds",
+ "remark": "Set to 0 (default) to disable this behavior; does not work with --json",
"arg": {
"type": "num",
"default": 0
@@ -90,7 +90,7 @@
"short": "c",
"long": "config",
"desc": "Specify the config file or preset to load",
- "remark": "The file will be searched according to the order shown by \"fastfetch --list-config-paths\". Use \"-\" to read config from stdin or \"none\" to disable further config loading. See also https://github.com/fastfetch-cli/fastfetch/wiki/Configuration for more info",
+ "remark": "The file is searched in the order shown by \"fastfetch --list-config-paths\". Use \"-\" to read config from stdin, or \"none\" to disable further config loading. See also https://github.com/fastfetch-cli/fastfetch/wiki/Configuration for details",
"arg": {
"type": "config"
}
@@ -98,7 +98,7 @@
{
"long": "gen-config",
"desc": "Generate a minimal config file at the specified path",
- "remark": "Defaults to \"~/.config/fastfetch/config.jsonc\". Will print the generated config if is \"-\"",
+ "remark": "Defaults to \"~/.config/fastfetch/config.jsonc\". Prints the generated config if is \"-\"",
"arg": {
"type": "path",
"optional": true
@@ -106,8 +106,8 @@
},
{
"long": "gen-config-full",
- "desc": "Generate a full config file with all optional options at the specified path",
- "remark": "Defaults to \"~/.config/fastfetch/config.jsonc\". Will print the generated config if is \"-\"",
+ "desc": "Generate a full config file with all optional settings at the specified path",
+ "remark": "Defaults to \"~/.config/fastfetch/config.jsonc\". Prints the generated config if is \"-\"",
"arg": {
"type": "path",
"optional": true
@@ -152,7 +152,7 @@
},
{
"long": "ds-force-drm",
- "desc": "Specify whether only DRM should be used to detect displays",
+ "desc": "Specify whether display detection should use DRM only",
"remark": [
"Use this option if you encounter problems with other detection methods.",
"Linux only"
@@ -170,7 +170,7 @@
},
{
"long": "detect-version",
- "desc": "Specify whether to detect and display versions of terminal, shell, editor, and others",
+ "desc": "Specify whether to detect and display versions for terminal, shell, editor, and others",
"remark": "Mainly for benchmarking",
"arg": {
"type": "bool",
@@ -183,31 +183,31 @@
{
"short": "l",
"long": "logo",
- "desc": "Set the logo source. Use \"none\" to disable the logo",
- "remark": "Should be the name of a built-in logo or a path to an image file. See also https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options",
+ "desc": "Set the logo source. Use \"none\" to disable logo output",
+ "remark": "Use either a built-in logo name or a path to an image file. See also https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options",
"arg": {
"type": "logo"
}
},
{
"long": "logo-type",
- "desc": "Set the type of the logo specified in \"--logo\"",
+ "desc": "Set the type of logo specified by \"--logo\"",
"remark": "See also https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options",
"arg": {
"type": "enum",
"enum": {
- "auto": "If something is given, first try built-in, then file. Otherwise detect logo",
+ "auto": "If a value is provided, try built-in first, then file. Otherwise auto-detect the logo",
"builtin": "Built-in ASCII art",
"small": "Built-in ASCII art, small version",
"file": "Text file, printed with color code replacement",
"file-raw": "Text file, printed as is",
"data": "Text data, printed with color code replacement",
"data-raw": "Text data, printed as is",
- "sixel": "Image file, printed as sixel codes",
- "kitty": "Image file, printed using kitty graphics protocol",
+ "sixel": "Image file, rendered as sixel",
+ "kitty": "Image file, rendered using the Kitty graphics protocol",
"kitty-direct": "Image file, tells the terminal emulator to read image data from the specified file",
- "kitty-icat": "Image file, uses `kitten icat` to display the image. Requires binary `kitten` to be installed",
- "iterm": "Image file, printed using iterm graphics protocol",
+ "kitty-icat": "Image file, displayed using `kitten icat`. Requires the `kitten` binary",
+ "iterm": "Image file, rendered using the iTerm graphics protocol",
"chafa": "Image file, printed as ASCII art using libchafa",
"raw": "Image file, printed as raw binary string",
"none": "Disable logo printing"
@@ -279,7 +279,7 @@
},
{
"long": "logo-print-remaining",
- "desc": "Specify whether to print the remaining logo if it has more lines than modules to display",
+ "desc": "Specify whether to print remaining logo lines when the logo is taller than the module list",
"arg": {
"type": "bool",
"optional": true,
@@ -288,7 +288,7 @@
},
{
"long": "logo-position",
- "desc": "Set the position where the logo should be displayed",
+ "desc": "Set the display position of the logo",
"arg": {
"type": "enum",
"enum": {
@@ -398,7 +398,7 @@
{
"long": "chafa-fg-only",
"desc": "Produce character-cell output using foreground colors only",
- "remark": "See chafa document for detail",
+ "remark": "See the Chafa documentation for details",
"arg": {
"type": "bool",
"optional": true,
@@ -408,7 +408,7 @@
{
"long": "chafa-symbols",
"desc": "Specify character symbols to employ in final output",
- "remark": "See chafa document for detail",
+ "remark": "See the Chafa documentation for details",
"arg": {
"type": "str"
}
@@ -416,7 +416,7 @@
{
"long": "chafa-canvas-mode",
"desc": "Determine how colors are used in the output",
- "remark": "This value maps the int value of enum ChafaCanvasMode. See chafa document for detail",
+ "remark": "This value maps to the integer value of enum ChafaCanvasMode. See the Chafa documentation for details",
"arg": {
"type": "enum",
"enum": {
@@ -433,8 +433,8 @@
},
{
"long": "chafa-color-space",
- "desc": "Set color space used for quantization",
- "remark": "This value maps the int value of enum ChafaColorSpace. See chafa document for detail",
+ "desc": "Set the color space used for quantization",
+ "remark": "This value maps to the integer value of enum ChafaColorSpace. See the Chafa documentation for details",
"arg": {
"type": "enum",
"enum": {
@@ -445,8 +445,8 @@
},
{
"long": "chafa-dither-mode",
- "desc": "Set output dither mode (No effect with 24-bit color)",
- "remark": "This value maps the int value of enum ChafaDitherMode. See chafa document for detail",
+ "desc": "Set the output dithering mode (no effect with 24-bit color)",
+ "remark": "This value maps to the integer value of enum ChafaDitherMode. See the Chafa documentation for details",
"arg": {
"type": "enum",
"enum": {
@@ -462,7 +462,7 @@
"short": "s",
"long": "structure",
"desc": "Set the structure of the fetch",
- "remark": "Must be a colon-separated list of keys. Use \"fastfetch --list-modules\" to see available options",
+ "remark": "Must be a colon-separated list of module keys. Use \"fastfetch --list-modules\" to see available options",
"arg": {
"type": "structure",
"default": "\"fastfetch --print-structure\""
@@ -478,7 +478,7 @@
},
{
"long": "stat",
- "desc": "Show time usage (in ms) for individual modules",
+ "desc": "Show execution time (ms) for individual modules",
"arg": {
"type": "bool",
"optional": true,
@@ -541,7 +541,7 @@
{
"long": "duration-abbreviation",
"desc": "Specify whether to abbreviate duration values",
- "remark": "If true, the output will be in the form of \"1h 2m\" instead of \"1 hour, 2 mins\"",
+ "remark": "If true, output is shown as \"1h 2m\" instead of \"1 hour, 2 mins\"",
"arg": {
"type": "bool",
"optional": true,
@@ -582,7 +582,7 @@
"enum": {
"none": "Disable keys",
"string": "Show string",
- "icon": "Show icon (requires newest nerd font)",
+ "icon": "Show icon (requires a recent Nerd Font)",
"both": "Show both icon and string (alias of `both-1`)",
"both-0": "Show both icon and string with no spaces between them",
"both-1": "Show both icon and string with a space between them",
@@ -639,7 +639,7 @@
},
{
"long": "percent-type",
- "desc": "Set the percentage output type",
+ "desc": "Set the percentage output style",
"remark": [
"1 for percentage number",
"2 for multi-color bar",
@@ -655,7 +655,7 @@
},
{
"long": "percent-ndigits",
- "desc": "Set the number of digits to keep after the decimal point when formatting percentage numbers",
+ "desc": "Set the number of decimal places to use when formatting percentages",
"arg": {
"type": "num",
"default": 0
@@ -702,7 +702,7 @@
},
{
"long": "percent-width",
- "desc": "Specify the width of the percentage number, in number of characters",
+ "desc": "Specify the width of the percentage number, in characters",
"remark": "This option affects only percentage numbers, not bars",
"arg": {
"type": "num",
@@ -711,7 +711,7 @@
},
{
"long": "bar-char-elapsed",
- "desc": "Set the character to use in the elapsed part of percentage bars",
+ "desc": "Set the character used for the elapsed part of percentage bars",
"arg": {
"type": "str",
"default": "\u25a0"
@@ -719,7 +719,7 @@
},
{
"long": "bar-char-total",
- "desc": "Set the character to use in the total part of percentage bars",
+ "desc": "Set the character used for the total part of percentage bars",
"arg": {
"type": "str",
"default": "-"
@@ -743,7 +743,7 @@
},
{
"long": "bar-border-left-elapsed",
- "desc": "If both bar-border-left-elapsed and bar-border-right-elapsed are set, the border will be used as parts of bar content",
+ "desc": "If both bar-border-left-elapsed and bar-border-right-elapsed are set, the border is used as part of the bar content",
"arg": {
"type": "string",
"default": ""
@@ -751,7 +751,7 @@
},
{
"long": "bar-border-right-elapsed",
- "desc": "If both bar-border-left-elapsed and bar-border-right-elapsed are set, the border will be used as parts of bar content",
+ "desc": "If both bar-border-left-elapsed and bar-border-right-elapsed are set, the border is used as part of the bar content",
"arg": {
"type": "string",
"default": ""
@@ -759,8 +759,8 @@
},
{
"long": "bar-color-elapsed",
- "desc": "Set the color to use in the elapsed part of percentage bars",
- "remark": "By default, auto selected by percent-color-{green,yellow,red}",
+ "desc": "Set the color used for the elapsed part of percentage bars",
+ "remark": "By default, this is auto-selected by percent-color-{green,yellow,red}",
"arg": {
"type": "color",
"default": ""
@@ -768,7 +768,7 @@
},
{
"long": "bar-color-total",
- "desc": "Set the color to use in the total part of percentage bars",
+ "desc": "Set the color used for the total part of percentage bars",
"arg": {
"type": "color",
"default": "light_white"
@@ -776,7 +776,7 @@
},
{
"long": "bar-color-border",
- "desc": "Set the color to use in the borders of percentage bars",
+ "desc": "Set the color used for percentage bar borders",
"arg": {
"type": "color",
"default": "light_white"
@@ -792,7 +792,7 @@
},
{
"long": "no-buffer",
- "desc": "Specify whether the stdout application buffer should be disabled",
+ "desc": "Specify whether stdout buffering should be disabled",
"arg": {
"type": "bool",
"optional": true,
@@ -801,7 +801,7 @@
},
{
"long": "size-ndigits",
- "desc": "Set the number of digits to keep after the decimal point when formatting sizes",
+ "desc": "Set the number of decimal places to use when formatting sizes",
"arg": {
"type": "num"
}
@@ -852,7 +852,7 @@
},
{
"long": "freq-ndigits",
- "desc": "Set the number of digits to keep after the decimal point when printing CPU/GPU frequency in GHz",
+ "desc": "Set the number of decimal places to use when printing CPU/GPU frequency in GHz",
"arg": {
"type": "num",
"default": 2
@@ -872,7 +872,7 @@
},
{
"long": "fraction-ndigits",
- "desc": "Set the number of digits to keep after the decimal point when printing ordinary fraction numbers",
+ "desc": "Set the number of decimal places to use when printing fractional values",
"remark": "If negative, the number of digits will be automatically determined based on the value",
"arg": {
"type": "num",
@@ -885,7 +885,7 @@
"arg": {
"type": "enum",
"enum": {
- "default": "Use the behavior defined internally",
+ "default": "Use the built-in behavior",
"always": "Always keep trailing zeros",
"never": "Never keep trailing zeros"
}
@@ -907,7 +907,7 @@
},
{
"long": "temp-ndigits",
- "desc": "Set the number of digits to keep after the decimal point when printing temperature",
+ "desc": "Set the number of decimal places to use when printing temperatures",
"arg": {
"type": "num",
"default": 2
diff --git a/src/detection/battery/battery.h b/src/detection/battery/battery.h
index ddeb7c6e7b..1a3b4e99a7 100644
--- a/src/detection/battery/battery.h
+++ b/src/detection/battery/battery.h
@@ -5,14 +5,24 @@
#define FF_BATTERY_TEMP_UNSET (-DBL_MAX)
-typedef struct FFBatteryResult
-{
+typedef enum FFBatteryStatus {
+ FF_BATTERY_STATUS_NONE = 0,
+ FF_BATTERY_STATUS_UNKNOWN = 1 << 0,
+ FF_BATTERY_STATUS_AC_CONNECTED = 1 << 1,
+ FF_BATTERY_STATUS_USB_CONNECTED = 1 << 2,
+ FF_BATTERY_STATUS_WIRELESS_CONNECTED = 1 << 3,
+ FF_BATTERY_STATUS_CHARGING = 1 << 4,
+ FF_BATTERY_STATUS_DISCHARGING = 1 << 5,
+ FF_BATTERY_STATUS_CRITICAL = 1 << 6,
+} FFBatteryStatus;
+
+typedef struct FFBatteryResult {
FFstrbuf manufacturer;
FFstrbuf manufactureDate;
FFstrbuf modelName;
FFstrbuf technology;
- FFstrbuf status;
FFstrbuf serial;
+ FFBatteryStatus status;
double capacity;
double temperature;
uint32_t cycleCount;
diff --git a/src/detection/battery/battery_android.c b/src/detection/battery/battery_android.c
index 9425dbd199..4c52d3a774 100644
--- a/src/detection/battery/battery_android.c
+++ b/src/detection/battery/battery_android.c
@@ -7,142 +7,141 @@
#define FF_TERMUX_API_PATH FASTFETCH_TARGET_DIR_ROOT "/libexec/termux-api"
#define FF_TERMUX_API_PARAM "BatteryStatus"
-static inline void wrapYyjsonFree(yyjson_doc** doc)
-{
+static inline void wrapYyjsonFree(yyjson_doc** doc) {
assert(doc);
- if (*doc)
+ if (*doc) {
yyjson_doc_free(*doc);
+ }
}
-static const char* parseTermuxApi(FFBatteryOptions* options, FFlist* results)
-{
+static const char* parseTermuxApi(FFBatteryOptions* options, FFlist* results) {
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
- if(ffProcessAppendStdOut(&buffer, (char* const[]){
- FF_TERMUX_API_PATH,
- FF_TERMUX_API_PARAM,
- NULL
- }))
+ if (ffProcessAppendStdOut(&buffer, (char* const[]) { FF_TERMUX_API_PATH, FF_TERMUX_API_PARAM, NULL })) {
return "Starting `" FF_TERMUX_API_PATH " " FF_TERMUX_API_PARAM "` failed";
+ }
- yyjson_doc* __attribute__((__cleanup__(wrapYyjsonFree))) doc = yyjson_read_opts(buffer.chars, buffer.length, 0, NULL, NULL);
- if (!doc)
+ yyjson_doc* FF_A_CLEANUP(wrapYyjsonFree) doc = yyjson_read_opts(buffer.chars, buffer.length, 0, NULL, NULL);
+ if (!doc) {
return "Failed to parse battery info";
+ }
yyjson_val* root = yyjson_doc_get_root(doc);
- if (!yyjson_is_obj(root))
+ if (!yyjson_is_obj(root)) {
return "Battery info result is not a JSON object";
+ }
- FFBatteryResult* battery = ffListAdd(results);
+ FFBatteryResult* battery = FF_LIST_ADD(FFBatteryResult, *results);
battery->temperature = FF_BATTERY_TEMP_UNSET;
battery->cycleCount = 0;
battery->timeRemaining = -1;
+ battery->status = FF_BATTERY_STATUS_NONE;
ffStrbufInit(&battery->manufacturer);
ffStrbufInit(&battery->modelName);
- ffStrbufInit(&battery->status);
ffStrbufInit(&battery->technology);
ffStrbufInit(&battery->serial);
ffStrbufInit(&battery->manufactureDate);
battery->capacity = yyjson_get_num(yyjson_obj_get(root, "percentage"));
const char* acStatus = yyjson_get_str(yyjson_obj_get(root, "plugged"));
- if (acStatus)
- {
- if (ffStrEquals(acStatus, "PLUGGED_AC"))
- ffStrbufAppendS(&battery->status, "AC Connected, ");
- else if (ffStrEquals(acStatus, "PLUGGED_USB"))
- ffStrbufAppendS(&battery->status, "USB Connected, ");
- else if (ffStrEquals(acStatus, "PLUGGED_WIRELESS"))
- ffStrbufAppendS(&battery->status, "Wireless Connected, ");
+ if (acStatus) {
+ if (ffStrEquals(acStatus, "PLUGGED_AC")) {
+ battery->status |= FF_BATTERY_STATUS_AC_CONNECTED;
+ } else if (ffStrEquals(acStatus, "PLUGGED_USB")) {
+ battery->status |= FF_BATTERY_STATUS_USB_CONNECTED;
+ } else if (ffStrEquals(acStatus, "PLUGGED_WIRELESS")) {
+ battery->status |= FF_BATTERY_STATUS_WIRELESS_CONNECTED;
+ }
}
const char* status = yyjson_get_str(yyjson_obj_get(root, "status"));
- if (status)
- {
- if (ffStrEquals(status, "CHARGING"))
- ffStrbufAppendS(&battery->status, "Charging");
- else if (ffStrEquals(status, "DISCHARGING"))
- ffStrbufAppendS(&battery->status, "Discharging");
+ if (status) {
+ if (ffStrEquals(status, "CHARGING")) {
+ battery->status |= FF_BATTERY_STATUS_CHARGING;
+ } else if (ffStrEquals(status, "DISCHARGING")) {
+ battery->status |= FF_BATTERY_STATUS_DISCHARGING;
+ }
}
- ffStrbufTrimRight(&battery->status, ' ');
- ffStrbufTrimRight(&battery->status, ',');
- if(options->temp)
+ if (options->temp) {
battery->temperature = yyjson_get_num(yyjson_obj_get(root, "temperature"));
+ }
return NULL;
}
-static const char* parseDumpsys(FFBatteryOptions* options, FFlist* results)
-{
+static const char* parseDumpsys(FFBatteryOptions* options, FFlist* results) {
FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
- if (ffProcessAppendStdOut(&buf, (char* []) {
- "/system/bin/dumpsys",
- "battery",
- NULL,
- }) != NULL || buf.length == 0)
+ if (ffProcessAppendStdOut(&buf, (char*[]) {
+ "/system/bin/dumpsys",
+ "battery",
+ NULL,
+ }) != NULL ||
+ buf.length == 0) {
return "Executing `/system/bin/dumpsys battery` failed"; // Only works in `adb shell`, or when rooted
+ }
- if (!ffStrbufStartsWithS(&buf, "Current Battery Service state:\n"))
+ if (!ffStrbufStartsWithS(&buf, "Current Battery Service state:\n")) {
return "Invalid `/system/bin/dumpsys battery` result";
+ }
const char* start = buf.chars + strlen("Current Battery Service state:\n");
FF_STRBUF_AUTO_DESTROY temp = ffStrbufCreate();
- if (!ffParsePropLines(start, "present: ", &temp) || !ffStrbufEqualS(&temp, "true"))
+ if (!ffParsePropLines(start, "present: ", &temp) || !ffStrbufEqualS(&temp, "true")) {
return NULL;
+ }
ffStrbufClear(&temp);
- FFBatteryResult* battery = ffListAdd(results);
+ FFBatteryResult* battery = FF_LIST_ADD(FFBatteryResult, *results);
battery->temperature = FF_BATTERY_TEMP_UNSET;
battery->cycleCount = 0;
battery->timeRemaining = -1;
battery->capacity = 0;
+ battery->status = FF_BATTERY_STATUS_NONE;
ffStrbufInit(&battery->manufacturer);
ffStrbufInit(&battery->modelName);
- ffStrbufInit(&battery->status);
ffStrbufInit(&battery->technology);
ffStrbufInit(&battery->serial);
ffStrbufInit(&battery->manufactureDate);
- if (ffParsePropLines(start, "AC powered: ", &temp) && ffStrbufEqualS(&temp, "true"))
- ffStrbufAppendS(&battery->status, "AC powered");
+ if (ffParsePropLines(start, "AC powered: ", &temp) && ffStrbufEqualS(&temp, "true")) {
+ battery->status |= FF_BATTERY_STATUS_AC_CONNECTED;
+ }
ffStrbufClear(&temp);
- if (ffParsePropLines(start, "USB powered: ", &temp) && ffStrbufEqualS(&temp, "true"))
- {
- if (battery->status.length) ffStrbufAppendS(&battery->status, ", ");
- ffStrbufAppendS(&battery->status, "USB powered");
+ if (ffParsePropLines(start, "USB powered: ", &temp) && ffStrbufEqualS(&temp, "true")) {
+ battery->status |= FF_BATTERY_STATUS_USB_CONNECTED;
}
ffStrbufClear(&temp);
- if (ffParsePropLines(start, "Wireless powered: ", &temp) && ffStrbufEqualS(&temp, "true"))
- {
- if (battery->status.length) ffStrbufAppendS(&battery->status, ", ");
- ffStrbufAppendS(&battery->status, "Wireless powered");
+ if (ffParsePropLines(start, "Wireless powered: ", &temp) && ffStrbufEqualS(&temp, "true")) {
+ battery->status |= FF_BATTERY_STATUS_WIRELESS_CONNECTED;
}
ffStrbufClear(&temp);
{
double level = 0, scale = 0;
- if (ffParsePropLines(start, "level: ", &temp))
+ if (ffParsePropLines(start, "level: ", &temp)) {
level = ffStrbufToDouble(&temp, -DBL_MAX);
+ }
ffStrbufClear(&temp);
- if (ffParsePropLines(start, "scale: ", &temp))
+ if (ffParsePropLines(start, "scale: ", &temp)) {
scale = ffStrbufToDouble(&temp, -DBL_MAX);
+ }
ffStrbufClear(&temp);
- if (level > 0 && scale > 0)
+ if (level > 0 && scale > 0) {
battery->capacity = level * 100 / scale;
+ }
}
- if(options->temp)
- {
- if (ffParsePropLines(start, "temperature: ", &temp))
- {
+ if (options->temp) {
+ if (ffParsePropLines(start, "temperature: ", &temp)) {
battery->temperature = ffStrbufToDouble(&temp, FF_BATTERY_TEMP_UNSET);
- if (battery->temperature != FF_BATTERY_TEMP_UNSET)
+ if (battery->temperature != FF_BATTERY_TEMP_UNSET) {
battery->temperature /= 10.0; // Android returns temperature in tenths of a degree
+ }
}
ffStrbufClear(&temp);
}
@@ -152,10 +151,10 @@ static const char* parseDumpsys(FFBatteryOptions* options, FFlist* results)
return NULL;
}
-const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
-{
+const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results) {
const char* error = parseTermuxApi(options, results);
- if (error && parseDumpsys(options, results) == NULL)
+ if (error && parseDumpsys(options, results) == NULL) {
return NULL;
+ }
return error;
}
diff --git a/src/detection/battery/battery_apple.c b/src/detection/battery/battery_apple.c
index d4935de2f1..c22aa6d43e 100644
--- a/src/detection/battery/battery_apple.c
+++ b/src/detection/battery/battery_apple.c
@@ -6,51 +6,56 @@
#include
#include
-const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
-{
+const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results) {
FF_IOOBJECT_AUTO_RELEASE io_iterator_t iterator = IO_OBJECT_NULL;
- if (IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching("AppleSmartBattery"), &iterator) != kIOReturnSuccess)
+ if (IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching("AppleSmartBattery"), &iterator) != kIOReturnSuccess) {
return "IOServiceGetMatchingServices() failed";
+ }
io_registry_entry_t registryEntry;
- while ((registryEntry = IOIteratorNext(iterator)) != IO_OBJECT_NULL)
- {
+ while ((registryEntry = IOIteratorNext(iterator)) != IO_OBJECT_NULL) {
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryBattery = registryEntry;
FF_CFTYPE_AUTO_RELEASE CFMutableDictionaryRef properties = NULL;
- if (IORegistryEntryCreateCFProperties(entryBattery, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
+ if (IORegistryEntryCreateCFProperties(entryBattery, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess) {
continue;
+ }
int currentCapacity, maxCapacity;
- if (ffCfDictGetInt(properties, CFSTR(kIOPMPSMaxCapacityKey), &maxCapacity) != NULL || maxCapacity <= 0)
+ if (ffCfDictGetInt(properties, CFSTR(kIOPMPSMaxCapacityKey), &maxCapacity) != NULL || maxCapacity <= 0) {
continue;
+ }
- if (ffCfDictGetInt(properties, CFSTR(kIOPMPSCurrentCapacityKey), ¤tCapacity) != NULL || currentCapacity <= 0)
+ if (ffCfDictGetInt(properties, CFSTR(kIOPMPSCurrentCapacityKey), ¤tCapacity) != NULL || currentCapacity <= 0) {
continue;
+ }
bool boolValue;
- FFBatteryResult* battery = ffListAdd(results);
+ FFBatteryResult* battery = FF_LIST_ADD(FFBatteryResult, *results);
battery->temperature = FF_BATTERY_TEMP_UNSET;
ffStrbufInit(&battery->manufacturer);
ffStrbufInit(&battery->modelName);
ffStrbufInit(&battery->serial);
ffStrbufInit(&battery->technology);
- ffStrbufInit(&battery->status);
ffStrbufInit(&battery->manufactureDate);
+ battery->status = FF_BATTERY_STATUS_NONE;
battery->capacity = currentCapacity * 100.0 / maxCapacity;
+ battery->cycleCount = 0;
+ battery->timeRemaining = -1;
ffCfDictGetString(properties, CFSTR(kIOPMDeviceNameKey), &battery->modelName);
ffCfDictGetString(properties, CFSTR(kIOPMPSSerialKey), &battery->serial);
ffCfDictGetString(properties, CFSTR(kIOPMPSManufacturerKey), &battery->manufacturer);
- if (!ffCfDictGetBool(properties, CFSTR("built-in"), &boolValue) && boolValue)
- {
- if (!battery->manufacturer.length)
+ if (!ffCfDictGetBool(properties, CFSTR("built-in"), &boolValue) && boolValue) {
+ if (!battery->manufacturer.length) {
ffStrbufAppendS(&battery->manufacturer, "Apple Inc.");
+ }
ffStrbufAppendS(&battery->technology, "Lithium");
- if (!battery->modelName.length)
+ if (!battery->modelName.length) {
ffStrbufAppendS(&battery->modelName, "Built-in");
+ }
}
int32_t cycleCount = 0;
@@ -58,43 +63,37 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
battery->cycleCount = cycleCount < 0 ? 0 : (uint32_t) cycleCount;
battery->timeRemaining = -1;
- if (ffCfDictGetBool(properties, CFSTR(kIOPMPSExternalConnectedKey), &boolValue) == NULL)
- {
- if (boolValue)
- ffStrbufAppendS(&battery->status, "AC connected, ");
- else
- {
- ffStrbufAppendS(&battery->status, "Discharging, ");
+ if (ffCfDictGetBool(properties, CFSTR(kIOPMPSExternalConnectedKey), &boolValue) == NULL) {
+ if (boolValue) {
+ battery->status |= FF_BATTERY_STATUS_AC_CONNECTED;
+ } else {
+ battery->status |= FF_BATTERY_STATUS_DISCHARGING;
ffCfDictGetInt(properties, CFSTR("AvgTimeToEmpty"), &battery->timeRemaining); // in minutes
- if (battery->timeRemaining < 0 || battery->timeRemaining >= 0xFFFF)
+ if (battery->timeRemaining < 0 || battery->timeRemaining >= 0xFFFF) {
battery->timeRemaining = -1;
- else
+ } else {
battery->timeRemaining *= 60;
+ }
}
}
- if (ffCfDictGetBool(properties, CFSTR(kIOPMPSIsChargingKey), &boolValue) == NULL && boolValue)
- ffStrbufAppendS(&battery->status, "Charging, ");
- if (ffCfDictGetBool(properties, CFSTR(kIOPMPSAtCriticalLevelKey), &boolValue) == NULL && boolValue)
- ffStrbufAppendS(&battery->status, "Critical, ");
- ffStrbufTrimRight(&battery->status, ' ');
- ffStrbufTrimRight(&battery->status, ',');
+ if (ffCfDictGetBool(properties, CFSTR(kIOPMPSIsChargingKey), &boolValue) == NULL && boolValue) {
+ battery->status |= FF_BATTERY_STATUS_CHARGING;
+ }
+ if (ffCfDictGetBool(properties, CFSTR(kIOPMPSAtCriticalLevelKey), &boolValue) == NULL && boolValue) {
+ battery->status |= FF_BATTERY_STATUS_CRITICAL;
+ }
int sbdsManufactureDate = 0;
- if (ffCfDictGetInt(properties, CFSTR(kIOPMPSManufactureDateKey), &sbdsManufactureDate) == NULL)
- {
+ if (ffCfDictGetInt(properties, CFSTR(kIOPMPSManufactureDateKey), &sbdsManufactureDate) == NULL) {
int day = sbdsManufactureDate & 0b11111;
int month = (sbdsManufactureDate >> 5) & 0b1111;
int year = (sbdsManufactureDate >> 9) + 1800;
ffStrbufSetF(&battery->manufactureDate, "%.4d-%.2d-%.2d", year, month, day);
- }
- else
- {
+ } else {
CFDictionaryRef batteryData;
- if (ffCfDictGetDict(properties, CFSTR("BatteryData"), &batteryData) == NULL)
- {
+ if (ffCfDictGetDict(properties, CFSTR("BatteryData"), &batteryData) == NULL) {
char manufactureDate[sizeof(uint64_t)];
- if (ffCfDictGetInt64(batteryData, CFSTR(kIOPMPSManufactureDateKey), (int64_t*) manufactureDate) == NULL)
- {
+ if (ffCfDictGetInt64(batteryData, CFSTR(kIOPMPSManufactureDateKey), (int64_t*) manufactureDate) == NULL) {
// https://github.com/AsahiLinux/linux/blob/b5c05cbffb0488c7618106926d522cc3b43d93d5/drivers/power/supply/macsmc_power.c#L410-L419
int year = (manufactureDate[0] - '0') * 10 + (manufactureDate[1] - '0') + 2000 - 8;
int month = (manufactureDate[2] - '0') * 10 + (manufactureDate[3] - '0');
@@ -104,13 +103,13 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
}
}
- if (options->temp)
- {
+ if (options->temp) {
int64_t temp;
- if (!ffCfDictGetInt64(properties, CFSTR(kIOPMPSBatteryTemperatureKey), &temp))
+ if (!ffCfDictGetInt64(properties, CFSTR(kIOPMPSBatteryTemperatureKey), &temp)) {
battery->temperature = (double) temp / 10 - 273.15;
- else
+ } else {
ffDetectSmcTemps(FF_TEMP_BATTERY, &battery->temperature);
+ }
}
}
diff --git a/src/detection/battery/battery_bsd.c b/src/detection/battery/battery_bsd.c
index d8ccd97f65..336a17e06b 100644
--- a/src/detection/battery/battery_bsd.c
+++ b/src/detection/battery/battery_bsd.c
@@ -8,88 +8,83 @@
#include
#include
-const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* results)
-{
- //https://www.freebsd.org/cgi/man.cgi?acpi_battery(4)
- //https://gitlab.xfce.org/panel-plugins/xfce4-battery-plugin/-/blob/master/panel-plugin/libacpi.c
+const char* ffDetectBattery(FF_A_UNUSED FFBatteryOptions* options, FFlist* results) {
+ // https://www.freebsd.org/cgi/man.cgi?acpi_battery(4)
+ // https://gitlab.xfce.org/panel-plugins/xfce4-battery-plugin/-/blob/master/panel-plugin/libacpi.c
int units = ffSysctlGetInt("hw.acpi.battery.units", -100);
- if (units < 0)
+ if (units < 0) {
return "sysctlbyname(\"hw.acpi.battery.units\") failed";
+ }
- if(units == 0)
+ if (units == 0) {
return NULL;
+ }
FF_AUTO_CLOSE_FD int acpifd = open("/dev/acpi", O_RDONLY | O_CLOEXEC);
- if(acpifd < 0)
+ if (acpifd < 0) {
return "open(\"/dev/acpi\", O_RDONLY | O_CLOEXEC) failed";
+ }
- for(int i = 0; i < units; ++i)
- {
+ for (int i = 0; i < units; ++i) {
union acpi_battery_ioctl_arg battio;
battio.unit = i;
- if(ioctl(acpifd, ACPIIO_BATT_GET_BATTINFO, &battio) < 0 || (battio.battinfo.state == ACPI_BATT_STAT_NOT_PRESENT))
+ if (ioctl(acpifd, ACPIIO_BATT_GET_BATTINFO, &battio) < 0 || (battio.battinfo.state == ACPI_BATT_STAT_NOT_PRESENT)) {
continue;
+ }
- FFBatteryResult* battery = ffListAdd(results);
+ FFBatteryResult* battery = FF_LIST_ADD(FFBatteryResult, *results);
battery->temperature = FF_BATTERY_TEMP_UNSET;
battery->cycleCount = 0;
ffStrbufInit(&battery->manufacturer);
ffStrbufInit(&battery->modelName);
- ffStrbufInit(&battery->status);
ffStrbufInit(&battery->technology);
ffStrbufInit(&battery->serial);
ffStrbufInit(&battery->manufactureDate);
+ battery->status = FF_BATTERY_STATUS_NONE;
battery->timeRemaining = -1;
- if (battio.battinfo.min > 0)
+ if (battio.battinfo.min > 0) {
battery->timeRemaining = battio.battinfo.min * 60;
- battery->capacity = battio.battinfo.cap;
- if(battio.battinfo.state == ACPI_BATT_STAT_INVALID)
- {
- ffStrbufAppendS(&battery->status, "Unknown, ");
}
- else
- {
- if(battio.battinfo.state & ACPI_BATT_STAT_DISCHARG)
- ffStrbufAppendS(&battery->status, "Discharging, ");
- else if(battio.battinfo.state & ACPI_BATT_STAT_CHARGING)
- ffStrbufAppendS(&battery->status, "Charging, ");
- if(battio.battinfo.state & ACPI_BATT_STAT_CRITICAL)
- ffStrbufAppendS(&battery->status, "Critical, ");
+ battery->capacity = battio.battinfo.cap;
+ if (battio.battinfo.state == ACPI_BATT_STAT_INVALID) {
+ battery->status |= FF_BATTERY_STATUS_UNKNOWN;
+ } else {
+ if (battio.battinfo.state & ACPI_BATT_STAT_DISCHARG) {
+ battery->status |= FF_BATTERY_STATUS_DISCHARGING;
+ }
+ if (battio.battinfo.state & ACPI_BATT_STAT_CHARGING) {
+ battery->status |= FF_BATTERY_STATUS_CHARGING;
+ }
+ if (battio.battinfo.state & ACPI_BATT_STAT_CRITICAL) {
+ battery->status |= FF_BATTERY_STATUS_CRITICAL;
+ }
}
int acadStatus;
- if (ioctl(acpifd, ACPIIO_ACAD_GET_STATUS, &acadStatus) >= 0 && acadStatus)
- {
- ffStrbufAppendS(&battery->status, "AC Connected");
- }
- else
- {
- ffStrbufTrimRight(&battery->status, ' ');
- ffStrbufTrimRight(&battery->status, ',');
+ if (ioctl(acpifd, ACPIIO_ACAD_GET_STATUS, &acadStatus) >= 0 && acadStatus) {
+ battery->status |= FF_BATTERY_STATUS_AC_CONNECTED;
}
- #ifdef ACPIIO_BATT_GET_BIX
+#ifdef ACPIIO_BATT_GET_BIX
battio.unit = i;
- if (ioctl(acpifd, ACPIIO_BATT_GET_BIX, &battio) >= 0)
- {
+ if (ioctl(acpifd, ACPIIO_BATT_GET_BIX, &battio) >= 0) {
ffStrbufAppendS(&battery->manufacturer, battio.bix.oeminfo);
ffStrbufAppendS(&battery->modelName, battio.bix.model);
ffStrbufAppendS(&battery->technology, battio.bix.type);
ffStrbufAppendS(&battery->serial, battio.bix.serial);
battery->cycleCount = battio.bix.cycles;
}
- #elif defined(ACPIIO_BATT_GET_BIF)
+#elif defined(ACPIIO_BATT_GET_BIF)
battio.unit = i;
- if (ioctl(acpifd, ACPIIO_BATT_GET_BIF, &battio) >= 0)
- {
+ if (ioctl(acpifd, ACPIIO_BATT_GET_BIF, &battio) >= 0) {
ffStrbufAppendS(&battery->manufacturer, battio.bif.oeminfo);
ffStrbufAppendS(&battery->modelName, battio.bif.model);
ffStrbufAppendS(&battery->technology, battio.bif.type);
ffStrbufAppendS(&battery->serial, battio.bif.serial);
}
- #endif
+#endif
}
return NULL;
}
diff --git a/src/detection/battery/battery_haiku.c b/src/detection/battery/battery_haiku.c
index 54d5978eee..aa620e6e5c 100644
--- a/src/detection/battery/battery_haiku.c
+++ b/src/detection/battery/battery_haiku.c
@@ -6,56 +6,64 @@
#include
#include
-const char* parseBattery(int dfd, const char* battId, FFlist* results)
-{
+const char* parseBattery(int dfd, const char* battId, FFlist* results) {
FF_AUTO_CLOSE_FD int fd = openat(dfd, battId, O_RDWR);
- if (fd < 0) return "openat() failed";
+ if (fd < 0) {
+ return "openat() failed";
+ }
acpi_battery_info basic = {};
- if (ioctl(fd, GET_BATTERY_INFO, &basic, sizeof(basic)) != 0)
+ if (ioctl(fd, GET_BATTERY_INFO, &basic, sizeof(basic)) != 0) {
return "ioctl(GET_BATTERY_INFO) failed";
+ }
acpi_extended_battery_info extended = {};
- if (ioctl(fd, GET_EXTENDED_BATTERY_INFO, &extended, sizeof(extended)) != 0)
+ if (ioctl(fd, GET_EXTENDED_BATTERY_INFO, &extended, sizeof(extended)) != 0) {
return "ioctl(GET_EXTENDED_BATTERY_INFO) failed";
+ }
- if (extended.last_full_charge == (uint32)-1)
+ if (extended.last_full_charge == (uint32) -1) {
return "Skipped";
+ }
- FFBatteryResult* battery = (FFBatteryResult*)ffListAdd(results);
+ FFBatteryResult* battery = FF_LIST_ADD(FFBatteryResult, *results);
ffStrbufInitS(&battery->modelName, extended.model_number);
ffStrbufInitS(&battery->manufacturer, extended.oem_info);
ffStrbufInit(&battery->manufactureDate);
ffStrbufInitS(&battery->technology, extended.type); // extended.technology?
- ffStrbufInit(&battery->status);
ffStrbufInitS(&battery->serial, extended.serial_number);
+ battery->status = FF_BATTERY_STATUS_NONE;
battery->temperature = FF_BATTERY_TEMP_UNSET;
battery->cycleCount = extended.cycles;
battery->timeRemaining = -1;
battery->capacity = (double) basic.capacity * 100. / (double) extended.last_full_charge;
- if (basic.state & BATTERY_DISCHARGING)
- ffStrbufAppendS(&battery->status, "Discharging, ");
- if (basic.state & BATTERY_CHARGING)
- ffStrbufAppendS(&battery->status, "Charging, ");
- if (basic.state & BATTERY_CRITICAL_STATE)
- ffStrbufAppendS(&battery->status, "Critical, ");
- if (basic.state & BATTERY_NOT_CHARGING)
- ffStrbufAppendS(&battery->status, "AC Connected, ");
- ffStrbufTrimRight(&battery->status, ' ');
- ffStrbufTrimRight(&battery->status, ',');
+ if (basic.state & BATTERY_DISCHARGING) {
+ battery->status |= FF_BATTERY_STATUS_DISCHARGING;
+ }
+ if (basic.state & BATTERY_CHARGING) {
+ battery->status |= FF_BATTERY_STATUS_CHARGING;
+ }
+ if (basic.state & BATTERY_CRITICAL_STATE) {
+ battery->status |= FF_BATTERY_STATUS_CRITICAL;
+ }
+ if (basic.state & BATTERY_NOT_CHARGING || basic.state & BATTERY_CHARGING) {
+ battery->status |= FF_BATTERY_STATUS_AC_CONNECTED;
+ }
return NULL;
}
-const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* results)
-{
+const char* ffDetectBattery(FF_A_UNUSED FFBatteryOptions* options, FFlist* results) {
FF_AUTO_CLOSE_DIR DIR* dir = opendir("/dev/power/acpi_battery/");
- if (!dir) return "opendir(/dev/power/acpi_battery) failed";
+ if (!dir) {
+ return "opendir(/dev/power/acpi_battery) failed";
+ }
struct dirent* entry;
- while ((entry = readdir(dir)))
- {
- if (entry->d_name[0] == '.') continue;
+ while ((entry = readdir(dir))) {
+ if (entry->d_name[0] == '.') {
+ continue;
+ }
parseBattery(dirfd(dir), entry->d_name, results);
}
diff --git a/src/detection/battery/battery_linux.c b/src/detection/battery/battery_linux.c
index d750dc61e1..13fc4d05cc 100644
--- a/src/detection/battery/battery_linux.c
+++ b/src/detection/battery/battery_linux.c
@@ -1,6 +1,7 @@
#include "battery.h"
#include "common/io.h"
#include "common/stringUtils.h"
+#include "common/debug.h"
#include
#include
@@ -8,174 +9,194 @@
// https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-power
-static bool checkAc(const char* id, FFstrbuf* tmpBuffer)
-{
- if (ffStrStartsWith(id, "BAT"))
- ffStrbufSetS(tmpBuffer, "/sys/class/power_supply/ADP1/online");
- else if (ffStrStartsWith(id, "macsmc-battery"))
- ffStrbufSetS(tmpBuffer, "/sys/class/power_supply/macsmc-ac/online");
- else
- ffStrbufClear(tmpBuffer);
-
- char online = '\0';
- return ffReadFileData(tmpBuffer->chars, 1, &online) == 1 && online == '1';
-}
-
-static void parseBattery(int dfd, const char* id, FFBatteryOptions* options, FFlist* results)
-{
+static bool parseBattery(int dfd, const char* id, FFBatteryOptions* options, FFlist* results, bool* acConnected) {
FF_STRBUF_AUTO_DESTROY tmpBuffer = ffStrbufCreate();
- // type must exist and be "Battery"
- if (!ffReadFileBufferRelative(dfd, "type", &tmpBuffer))
- return;
+ {
+ char present = '\0';
+ if (ffReadFileDataRelative(dfd, "present", 1, &present) && present == '0') {
+ FF_DEBUG("Battery \"%s\": Not present", id);
+ return false;
+ }
+ }
+
+ // type must exist
+ if (!ffReadFileBufferRelative(dfd, "type", &tmpBuffer)) {
+ FF_DEBUG("Battery \"%s\": No type file", id);
+ return false;
+ }
ffStrbufTrimRightSpace(&tmpBuffer);
- if(!ffStrbufIgnCaseEqualS(&tmpBuffer, "Battery"))
- return;
+ if (ffStrbufEqualS(&tmpBuffer, "Mains")) {
+ if (*acConnected) {
+ FF_DEBUG("Battery \"%s\": Type is Mains, but AC is already connected", id);
+ return false;
+ }
+
+ char online = '\0';
+ if (ffReadFileDataRelative(dfd, "online", 1, &online) == 1 && online == '1') {
+ *acConnected = true;
+ }
+ FF_DEBUG("Battery \"%s\": Type is Mains, AC Connected: %s", id, *acConnected ? "Yes" : "No");
+ return false;
+ } else if (!ffStrbufEqualS(&tmpBuffer, "Battery")) {
+ FF_DEBUG("Battery \"%s\": Type is not Battery or Mains, but \"%s\"", id, tmpBuffer.chars);
+ return false;
+ }
// scope may not exist or must not be "Device"
- if (ffReadFileBufferRelative(dfd, "scope", &tmpBuffer))
+ if (ffReadFileBufferRelative(dfd, "scope", &tmpBuffer)) {
ffStrbufTrimRightSpace(&tmpBuffer);
- if(ffStrbufIgnCaseEqualS(&tmpBuffer, "Device"))
- return;
+ FF_DEBUG("Battery \"%s\": Scope is \"%s\"", id, tmpBuffer.chars);
+ if (ffStrbufEqualS(&tmpBuffer, "Device")) {
+ return false;
+ }
+ }
- // capacity must exist and be not empty
+ // `capacity` must exist
// This is expensive in my laptop
- if (!ffReadFileBufferRelative(dfd, "capacity", &tmpBuffer))
- return;
+ if (!ffReadFileBufferRelative(dfd, "capacity", &tmpBuffer)) {
+ FF_DEBUG("Battery \"%s\": No capacity file", id);
+ return false;
+ }
- FFBatteryResult* result = ffListAdd(results);
+ FFBatteryResult* result = FF_LIST_ADD(FFBatteryResult, *results);
+ ffStrbufInit(&result->manufacturer);
+ ffStrbufInit(&result->modelName);
+ ffStrbufInit(&result->technology);
+ ffStrbufInit(&result->serial);
+ ffStrbufInit(&result->manufactureDate);
+ result->status = FF_BATTERY_STATUS_NONE;
result->capacity = ffStrbufToDouble(&tmpBuffer, 0);
+ result->cycleCount = 0;
+ result->temperature = FF_BATTERY_TEMP_UNSET;
+ result->timeRemaining = -1;
- //At this point, we have a battery. Try to get as much values as possible.
+ // At this point, we have a battery. Try to get as much values as possible.
- ffStrbufInit(&result->manufacturer);
- if (ffReadFileBufferRelative(dfd, "manufacturer", &result->manufacturer))
+ if (ffReadFileBufferRelative(dfd, "manufacturer", &result->manufacturer)) {
ffStrbufTrimRightSpace(&result->manufacturer);
- else if (ffStrEquals(id, "macsmc-battery")) // asahi
+ } else if (ffStrEquals(id, "macsmc-battery")) { // asahi
ffStrbufSetStatic(&result->manufacturer, "Apple Inc.");
+ }
- ffStrbufInit(&result->modelName);
- if (ffReadFileBufferRelative(dfd, "model_name", &result->modelName))
+ if (ffReadFileBufferRelative(dfd, "model_name", &result->modelName)) {
ffStrbufTrimRightSpace(&result->modelName);
+ }
- ffStrbufInit(&result->technology);
- if (ffReadFileBufferRelative(dfd, "technology", &result->technology))
+ if (ffReadFileBufferRelative(dfd, "technology", &result->technology)) {
ffStrbufTrimRightSpace(&result->technology);
+ }
- ffStrbufInit(&result->status);
- if (ffReadFileBufferRelative(dfd, "status", &result->status))
- ffStrbufTrimRightSpace(&result->status);
+ if (ffReadFileBufferRelative(dfd, "status", &tmpBuffer)) {
+ ffStrbufTrimRightSpace(&tmpBuffer);
+ }
// Unknown, Charging, Discharging, Not charging, Full
- result->timeRemaining = -1;
- if (ffStrbufEqualS(&result->status, "Discharging"))
- {
- if (ffReadFileBufferRelative(dfd, "time_to_empty_now", &tmpBuffer))
- result->timeRemaining = (int32_t) ffStrbufToSInt(&tmpBuffer, 0);
- else
- {
- if (ffReadFileBufferRelative(dfd, "charge_now", &tmpBuffer))
- {
- int64_t chargeNow = ffStrbufToSInt(&tmpBuffer, 0);
- if (chargeNow > 0)
- {
- if (ffReadFileBufferRelative(dfd, "current_now", &tmpBuffer))
- {
- int64_t currentNow = ffStrbufToSInt(&tmpBuffer, INT64_MIN);
- if (currentNow < 0) currentNow = -currentNow;
- if (currentNow > 0)
+ if (ffStrbufEqualS(&tmpBuffer, "Discharging")) {
+ result->status |= FF_BATTERY_STATUS_DISCHARGING;
+ FF_STRBUF_AUTO_DESTROY now = ffStrbufCreate();
+ if (ffReadFileBufferRelative(dfd, "time_to_empty_now", &now)) {
+ result->timeRemaining = (int32_t) ffStrbufToSInt(&now, 0);
+ } else {
+ if (ffReadFileBufferRelative(dfd, "charge_now", &now)) {
+ int64_t chargeNow = ffStrbufToSInt(&now, 0);
+ if (chargeNow > 0) {
+ if (ffReadFileBufferRelative(dfd, "current_now", &now)) {
+ int64_t currentNow = ffStrbufToSInt(&now, INT64_MIN);
+ if (currentNow < 0) {
+ currentNow = -currentNow;
+ }
+ if (currentNow > 0) {
result->timeRemaining = (int32_t) ((chargeNow * 3600) / currentNow);
+ }
}
}
}
}
-
- if (checkAc(id, &tmpBuffer))
- ffStrbufAppendS(&result->status, ", AC Connected");
- }
- else if (ffStrbufEqualS(&result->status, "Not charging") || ffStrbufEqualS(&result->status, "Full"))
- ffStrbufSetStatic(&result->status, "AC Connected");
- else if (ffStrbufEqualS(&result->status, "Charging"))
- ffStrbufAppendS(&result->status, ", AC Connected");
- else if (ffStrbufEqualS(&result->status, "Unknown"))
- {
- ffStrbufClear(&result->status);
- if (checkAc(id, &tmpBuffer))
- ffStrbufAppendS(&result->status, "AC Connected");
+ } else if (ffStrbufEqualS(&tmpBuffer, "Charging")) {
+ result->status |= FF_BATTERY_STATUS_CHARGING;
+ } else if (ffStrbufEqualS(&tmpBuffer, "Unknown")) {
+ result->status |= FF_BATTERY_STATUS_UNKNOWN;
}
- if (ffReadFileBufferRelative(dfd, "capacity_level", &tmpBuffer))
- {
+ if (ffReadFileBufferRelative(dfd, "capacity_level", &tmpBuffer)) {
ffStrbufTrimRightSpace(&tmpBuffer);
- if (ffStrbufEqualS(&tmpBuffer, "Critical"))
- {
- if (result->status.length)
- ffStrbufAppendS(&result->status, ", Critical");
- else
- ffStrbufSetStatic(&result->status, "Critical");
+ if (ffStrbufEqualS(&tmpBuffer, "Critical")) {
+ result->status |= FF_BATTERY_STATUS_CRITICAL;
}
}
- ffStrbufInit(&result->serial);
- if (ffReadFileBufferRelative(dfd, "serial_number", &result->serial))
+ if (ffReadFileBufferRelative(dfd, "serial_number", &result->serial)) {
ffStrbufTrimRightSpace(&result->serial);
+ }
- if (ffReadFileBufferRelative(dfd, "cycle_count", &tmpBuffer))
- {
+ if (ffReadFileBufferRelative(dfd, "cycle_count", &tmpBuffer)) {
int64_t cycleCount = ffStrbufToSInt(&tmpBuffer, 0);
result->cycleCount = cycleCount < 0 || cycleCount > UINT32_MAX ? 0 : (uint32_t) cycleCount;
}
- ffStrbufInit(&result->manufactureDate);
- if (ffReadFileBufferRelative(dfd, "manufacture_year", &tmpBuffer))
- {
+ if (ffReadFileBufferRelative(dfd, "manufacture_year", &tmpBuffer)) {
int year = (int) ffStrbufToSInt(&tmpBuffer, 0);
- if (year > 0)
- {
- if (ffReadFileBufferRelative(dfd, "manufacture_month", &tmpBuffer))
- {
+ if (year > 0) {
+ if (ffReadFileBufferRelative(dfd, "manufacture_month", &tmpBuffer)) {
int month = (int) ffStrbufToSInt(&tmpBuffer, 0);
- if (month > 0)
- {
- if (ffReadFileBufferRelative(dfd, "manufacture_day", &tmpBuffer))
- {
+ if (month > 0) {
+ if (ffReadFileBufferRelative(dfd, "manufacture_day", &tmpBuffer)) {
int day = (int) ffStrbufToSInt(&tmpBuffer, 0);
- if (day > 0)
+ if (day > 0) {
ffStrbufSetF(&result->manufactureDate, "%.4d-%.2d-%.2d", year, month, day);
+ }
}
}
}
}
}
- result->temperature = FF_BATTERY_TEMP_UNSET;
- if (options->temp)
- {
- if (ffReadFileBufferRelative(dfd, "temp", &tmpBuffer))
- {
+ if (options->temp) {
+ if (ffReadFileBufferRelative(dfd, "temp", &tmpBuffer)) {
result->temperature = ffStrbufToDouble(&tmpBuffer, FF_BATTERY_TEMP_UNSET);
- if (result->temperature != FF_BATTERY_TEMP_UNSET)
+ if (result->temperature != FF_BATTERY_TEMP_UNSET) {
result->temperature /= 10;
+ }
}
}
+
+ FF_DEBUG("Battery \"%s\": Capacity: %.2f%%, Status: \"%x\", Time Remaining: %d seconds, Temperature: %.1f°C, Cycle Count: %u",
+ id,
+ result->capacity,
+ result->status,
+ result->timeRemaining,
+ result->temperature,
+ result->cycleCount);
+ return true;
}
-const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
-{
+const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results) {
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/sys/class/power_supply/");
- if(dirp == NULL)
+ if (dirp == NULL) {
return "opendir(\"/sys/class/power_supply/\") == NULL";
+ }
+
+ bool acConnected = false;
struct dirent* entry;
- while((entry = readdir(dirp)) != NULL)
- {
- if(entry->d_name[0] == '.')
+ while ((entry = readdir(dirp)) != NULL) {
+ if (entry->d_name[0] == '.') {
continue;
+ }
FF_AUTO_CLOSE_FD int dfd = openat(dirfd(dirp), entry->d_name, O_RDONLY | O_CLOEXEC | O_PATH | O_DIRECTORY);
- if (dfd > 0) parseBattery(dfd, entry->d_name, options, results);
+ if (dfd >= 0) {
+ parseBattery(dfd, entry->d_name, options, results, &acConnected);
+ }
+ }
+
+ if (acConnected) {
+ FF_LIST_FOR_EACH (FFBatteryResult, batt, *results) {
+ batt->status |= FF_BATTERY_STATUS_AC_CONNECTED;
+ }
}
return NULL;
diff --git a/src/detection/battery/battery_nbsd.c b/src/detection/battery/battery_nbsd.c
index 37ef649667..f24907c5e1 100644
--- a/src/detection/battery/battery_nbsd.c
+++ b/src/detection/battery/battery_nbsd.c
@@ -14,92 +14,90 @@
#include
#include
-const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* results)
-{
+const char* ffDetectBattery(FF_A_UNUSED FFBatteryOptions* options, FFlist* results) {
FF_AUTO_CLOSE_FD int fd = open(_PATH_SYSMON, O_RDONLY | O_CLOEXEC);
- if (fd < 0) return "open(_PATH_SYSMON, O_RDONLY | O_CLOEXEC) failed";
+ if (fd < 0) {
+ return "open(_PATH_SYSMON, O_RDONLY | O_CLOEXEC) failed";
+ }
prop_dictionary_t root = NULL;
- if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &root) < 0)
+ if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &root) < 0) {
return "prop_dictionary_recv_ioctl(ENVSYS_GETDICTIONARY) failed";
+ }
bool acConnected = false;
{
prop_array_t acad = prop_dictionary_get(root, "acpiacad0");
- if (acad)
- {
+ if (acad) {
prop_dictionary_t dict = prop_array_get(acad, 0);
prop_dictionary_get_uint8(dict, "cur-value", (uint8_t*) &acConnected);
}
}
prop_object_iterator_t itKey = prop_dictionary_iterator(root);
- for (prop_dictionary_keysym_t key; (key = prop_object_iterator_next(itKey)) != NULL; )
- {
- if (!ffStrStartsWith(prop_dictionary_keysym_value(key), "acpibat")) continue;
+ for (prop_dictionary_keysym_t key; (key = prop_object_iterator_next(itKey)) != NULL;) {
+ if (!ffStrStartsWith(prop_dictionary_keysym_value(key), "acpibat")) {
+ continue;
+ }
prop_array_t bat = prop_dictionary_get_keysym(root, key);
uint32_t max = 0, curr = 0, dischargeRate = 0;
bool charging = false, critical = false;
prop_object_iterator_t iter = prop_array_iterator(bat);
- for (prop_dictionary_t dict; (dict = prop_object_iterator_next(iter)) != NULL;)
- {
- if (prop_object_type(dict) != PROP_TYPE_DICTIONARY)
+ for (prop_dictionary_t dict; (dict = prop_object_iterator_next(iter)) != NULL;) {
+ if (prop_object_type(dict) != PROP_TYPE_DICTIONARY) {
continue;
+ }
const char* desc = NULL;
- if (!prop_dictionary_get_string(dict, "description", &desc))
+ if (!prop_dictionary_get_string(dict, "description", &desc)) {
continue;
+ }
- if (ffStrEquals(desc, "present"))
- {
+ if (ffStrEquals(desc, "present")) {
int value = 0;
- if (prop_dictionary_get_int(dict, "cur-value", &value) && value == 0)
+ if (prop_dictionary_get_int(dict, "cur-value", &value) && value == 0) {
continue;
- }
- else if (ffStrEquals(desc, "charging"))
- {
+ }
+ } else if (ffStrEquals(desc, "charging")) {
prop_dictionary_get_uint8(dict, "cur-value", (uint8_t*) &charging);
- }
- else if (ffStrEquals(desc, "charge"))
- {
+ } else if (ffStrEquals(desc, "charge")) {
prop_dictionary_get_uint32(dict, "max-value", &max);
prop_dictionary_get_uint32(dict, "cur-value", &curr);
const char* state = NULL;
- if (prop_dictionary_get_string(dict, "state", &state) && ffStrEquals(state, "critical"))
+ if (prop_dictionary_get_string(dict, "state", &state) && ffStrEquals(state, "critical")) {
critical = true;
- }
- else if (ffStrEquals(desc, "discharge rate"))
+ }
+ } else if (ffStrEquals(desc, "discharge rate")) {
prop_dictionary_get_uint(dict, "cur-value", &dischargeRate);
+ }
}
- if (max > 0)
- {
- FFBatteryResult* battery = ffListAdd(results);
+ if (max > 0) {
+ FFBatteryResult* battery = FF_LIST_ADD(FFBatteryResult, *results);
battery->temperature = FF_BATTERY_TEMP_UNSET;
battery->cycleCount = 0;
ffStrbufInit(&battery->manufacturer);
ffStrbufInit(&battery->modelName);
- ffStrbufInit(&battery->status);
ffStrbufInit(&battery->technology);
ffStrbufInit(&battery->serial);
ffStrbufInit(&battery->manufactureDate);
+ battery->status = FF_BATTERY_STATUS_NONE;
battery->timeRemaining = -1;
battery->capacity = (double) curr / (double) max * 100.;
- if (charging)
- ffStrbufAppendS(&battery->status, "Charging, ");
- else if (dischargeRate)
- {
- ffStrbufAppendS(&battery->status, "Discharging, ");
- battery->timeRemaining = (int32_t)((double)curr / dischargeRate * 3600);
+ if (charging) {
+ battery->status |= FF_BATTERY_STATUS_CHARGING;
+ } else if (dischargeRate) {
+ battery->status |= FF_BATTERY_STATUS_DISCHARGING;
+ battery->timeRemaining = (int32_t) ((double) curr / dischargeRate * 3600);
+ }
+ if (critical) {
+ battery->status |= FF_BATTERY_STATUS_CRITICAL;
+ }
+ if (acConnected) {
+ battery->status |= FF_BATTERY_STATUS_AC_CONNECTED;
}
- if (critical)
- ffStrbufAppendS(&battery->status, "Critical, ");
- if (acConnected)
- ffStrbufAppendS(&battery->status, "AC Connected");
- ffStrbufTrimRight(&battery->status, ' ');
- ffStrbufTrimRight(&battery->status, ',');
}
prop_object_iterator_release(iter);
diff --git a/src/detection/battery/battery_nosupport.c b/src/detection/battery/battery_nosupport.c
index 02f084748f..efd0f736f8 100644
--- a/src/detection/battery/battery_nosupport.c
+++ b/src/detection/battery/battery_nosupport.c
@@ -1,8 +1,7 @@
#include "fastfetch.h"
#include "battery.h"
-const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
-{
+const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results) {
FF_UNUSED(options, results)
return "Not supported on this platform";
}
diff --git a/src/detection/battery/battery_obsd.c b/src/detection/battery/battery_obsd.c
index 2cd5c9e4a8..ee664ce690 100644
--- a/src/detection/battery/battery_obsd.c
+++ b/src/detection/battery/battery_obsd.c
@@ -6,46 +6,54 @@
#include
#include
-const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* result)
-{
+const char* ffDetectBattery(FF_A_UNUSED FFBatteryOptions* options, FFlist* result) {
FF_AUTO_CLOSE_FD int devfd = open("/dev/apm", O_RDONLY | O_CLOEXEC);
- if (devfd < 0) return "open(dev/apm, O_RDONLY | O_CLOEXEC) failed";
+ if (devfd < 0) {
+ return "open(dev/apm, O_RDONLY | O_CLOEXEC) failed";
+ }
struct apm_power_info info = {};
- if (ioctl(devfd, APM_IOC_GETPOWER, &info) < 0)
+ if (ioctl(devfd, APM_IOC_GETPOWER, &info) < 0) {
return "ioctl(APM_IOC_GETPOWER) failed";
+ }
- if (info.battery_state == APM_BATTERY_ABSENT)
+ if (info.battery_state == APM_BATTERY_ABSENT) {
return NULL;
+ }
- FFBatteryResult* battery = (FFBatteryResult*) ffListAdd(result);
+ FFBatteryResult* battery = FF_LIST_ADD(FFBatteryResult, *result);
battery->temperature = FF_BATTERY_TEMP_UNSET;
battery->cycleCount = 0;
battery->timeRemaining = -1;
battery->capacity = info.battery_life;
ffStrbufInit(&battery->manufacturer);
ffStrbufInit(&battery->modelName);
- ffStrbufInit(&battery->status);
ffStrbufInit(&battery->technology);
ffStrbufInit(&battery->serial);
ffStrbufInit(&battery->manufactureDate);
+ battery->status = FF_BATTERY_STATUS_NONE;
- if (info.ac_state == APM_AC_ON)
- ffStrbufAppendS(&battery->status, "AC Connected");
- else if (info.ac_state == APM_AC_BACKUP)
- ffStrbufAppendS(&battery->status, "Backup In Use");
- else if (info.ac_state == APM_AC_OFF)
- {
+ if (info.ac_state == APM_AC_ON || info.ac_state == APM_AC_BACKUP) {
+ battery->status |= FF_BATTERY_STATUS_AC_CONNECTED;
+ } else if (info.ac_state == APM_AC_OFF) {
battery->timeRemaining = (int) info.minutes_left * 60;
- ffStrbufAppendS(&battery->status, "Discharging");
+ battery->status |= FF_BATTERY_STATUS_DISCHARGING;
}
- if (info.battery_state == APM_BATT_CRITICAL || info.battery_state == APM_BATT_CHARGING)
- {
- if (battery->status.length) ffStrbufAppendS(&battery->status, ", ");
- ffStrbufAppendS(&battery->status, info.battery_state == APM_BATT_CRITICAL ? "Critical" : "Charging");
+ if (info.battery_state == APM_BATT_CRITICAL || info.battery_state == APM_BATT_CHARGING || info.battery_state == APM_BATT_UNKNOWN) {
+ switch (info.battery_state) {
+ case APM_BATT_UNKNOWN:
+ battery->status |= FF_BATTERY_STATUS_UNKNOWN;
+ break;
+ case APM_BATT_CHARGING:
+ battery->status |= FF_BATTERY_STATUS_CHARGING;
+ break;
+ case APM_BATT_CRITICAL:
+ battery->status |= FF_BATTERY_STATUS_CRITICAL;
+ break;
+ }
}
return NULL;
diff --git a/src/detection/battery/battery_windows.c b/src/detection/battery/battery_windows.c
index 3196885115..de94d75a8e 100644
--- a/src/detection/battery/battery_windows.c
+++ b/src/detection/battery/battery_windows.c
@@ -4,7 +4,7 @@
#include "common/windows/nt.h"
#include "common/windows/unicode.h"
#include "common/mallocHelper.h"
-#include "common/smbiosHelper.h"
+#include "common/smbios.h"
#undef WIN32_LEAN_AND_MEAN
#include
@@ -12,172 +12,194 @@
#include
#include
-static const char* detectWithCmApi(FFBatteryOptions* options, FFlist* results)
-{
- //https://learn.microsoft.com/en-us/windows-hardware/drivers/install/using-device-interfaces
+static const char* detectWithCmApi(FFBatteryOptions* options, FFlist* results) {
+ // https://learn.microsoft.com/en-us/windows-hardware/drivers/install/using-device-interfaces
ULONG cchDeviceInterfaces = 0;
- CONFIGRET cr = CM_Get_Device_Interface_List_SizeW(&cchDeviceInterfaces, (LPGUID)&GUID_DEVCLASS_BATTERY, NULL, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
- if (cr != CR_SUCCESS)
+ if (CM_Get_Device_Interface_List_SizeW(
+ &cchDeviceInterfaces,
+ (LPGUID) &GUID_DEVCLASS_BATTERY,
+ NULL,
+ CM_GET_DEVICE_INTERFACE_LIST_PRESENT) != CR_SUCCESS) {
return "CM_Get_Device_Interface_List_SizeW() failed";
+ }
- if (cchDeviceInterfaces <= 1)
+ if (cchDeviceInterfaces <= 1) {
return NULL; // Not found
+ }
- wchar_t* FF_AUTO_FREE mszDeviceInterfaces = (wchar_t*)malloc(cchDeviceInterfaces * sizeof(wchar_t));
- cr = CM_Get_Device_Interface_ListW((LPGUID)&GUID_DEVCLASS_BATTERY, NULL, mszDeviceInterfaces, cchDeviceInterfaces, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
- if (cr != CR_SUCCESS)
+ wchar_t* FF_AUTO_FREE mszDeviceInterfaces = (wchar_t*) malloc(cchDeviceInterfaces * sizeof(wchar_t));
+ if (CM_Get_Device_Interface_ListW(
+ (LPGUID) &GUID_DEVCLASS_BATTERY,
+ NULL,
+ mszDeviceInterfaces,
+ cchDeviceInterfaces,
+ CM_GET_DEVICE_INTERFACE_LIST_PRESENT) != CR_SUCCESS) {
return "CM_Get_Device_Interface_ListW() failed";
+ }
- for (const wchar_t* pDeviceInterface = mszDeviceInterfaces; *pDeviceInterface; pDeviceInterface += wcslen(pDeviceInterface) + 1)
- {
+ for (const wchar_t* p = mszDeviceInterfaces; *p; p += wcslen(p) + 1) {
HANDLE FF_AUTO_CLOSE_FD hBattery =
- CreateFileW(pDeviceInterface, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ CreateFileW(p, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if(hBattery == INVALID_HANDLE_VALUE)
+ if (hBattery == INVALID_HANDLE_VALUE) {
continue;
+ }
BATTERY_QUERY_INFORMATION bqi = { .InformationLevel = BatteryInformation };
DWORD dwWait = 0;
DWORD dwOut;
- if(!DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_TAG, &dwWait, sizeof(dwWait), &bqi.BatteryTag, sizeof(bqi.BatteryTag), &dwOut, NULL) && bqi.BatteryTag)
+ if (!DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_TAG, &dwWait, sizeof(dwWait), &bqi.BatteryTag, sizeof(bqi.BatteryTag), &dwOut, NULL) && bqi.BatteryTag) {
continue;
+ }
- BATTERY_INFORMATION bi = {0};
- if(!DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), &bi, sizeof(bi), &dwOut, NULL))
+ BATTERY_INFORMATION bi = { 0 };
+ if (!DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), &bi, sizeof(bi), &dwOut, NULL)) {
continue;
+ }
- if(!(bi.Capabilities & BATTERY_SYSTEM_BATTERY))
+ if (!(bi.Capabilities & BATTERY_SYSTEM_BATTERY)) {
continue;
+ }
- FFBatteryResult* battery = (FFBatteryResult*)ffListAdd(results);
+ FFBatteryResult* battery = FF_LIST_ADD(FFBatteryResult, *results);
- if(memcmp(bi.Chemistry, "PbAc", 4) == 0)
+ if (memcmp(bi.Chemistry, "PbAc", 4) == 0) {
ffStrbufInitStatic(&battery->technology, "Lead Acid");
- else if(memcmp(bi.Chemistry, "LION", 4) == 0 || memcmp(bi.Chemistry, "Li-I", 4) == 0)
+ } else if (memcmp(bi.Chemistry, "LION", 4) == 0 || memcmp(bi.Chemistry, "Li-I", 4) == 0) {
ffStrbufInitStatic(&battery->technology, "Lithium Ion");
- else if(memcmp(bi.Chemistry, "NiCd", 4) == 0)
+ } else if (memcmp(bi.Chemistry, "NiCd", 4) == 0) {
ffStrbufInitStatic(&battery->technology, "Nickel Cadmium");
- else if(memcmp(bi.Chemistry, "NiMH", 4) == 0)
+ } else if (memcmp(bi.Chemistry, "NiMH", 4) == 0) {
ffStrbufInitStatic(&battery->technology, "Nickel Metal Hydride");
- else if(memcmp(bi.Chemistry, "NiZn", 4) == 0)
+ } else if (memcmp(bi.Chemistry, "NiZn", 4) == 0) {
ffStrbufInitStatic(&battery->technology, "Nickel Zinc");
- else if(memcmp(bi.Chemistry, "RAM\0", 4) == 0)
+ } else if (memcmp(bi.Chemistry, "RAM\0", 4) == 0) {
ffStrbufInitStatic(&battery->technology, "Rechargeable Alkaline-Manganese");
- else
+ } else {
ffStrbufInitStatic(&battery->technology, "Unknown");
+ }
{
ffStrbufInit(&battery->modelName);
bqi.InformationLevel = BatteryDeviceName;
wchar_t name[64];
- if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), name, sizeof(name), &dwOut, NULL))
+ if (DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), name, sizeof(name), &dwOut, NULL)) {
ffStrbufSetWS(&battery->modelName, name);
+ }
}
{
ffStrbufInit(&battery->manufacturer);
bqi.InformationLevel = BatteryManufactureName;
wchar_t name[64];
- if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), name, sizeof(name), &dwOut, NULL))
+ if (DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), name, sizeof(name), &dwOut, NULL)) {
ffStrbufSetWS(&battery->manufacturer, name);
+ }
}
{
ffStrbufInit(&battery->manufactureDate);
bqi.InformationLevel = BatteryManufactureDate;
BATTERY_MANUFACTURE_DATE date;
- if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), &date, sizeof(date), &dwOut, NULL))
+ if (DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), &date, sizeof(date), &dwOut, NULL)) {
ffStrbufSetF(&battery->manufactureDate, "%.4d-%.2d-%.2d", date.Year < 1000 ? date.Year + 1900 : date.Year, date.Month, date.Day);
+ }
}
{
ffStrbufInit(&battery->serial);
bqi.InformationLevel = BatterySerialNumber;
wchar_t name[64];
- if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), name, sizeof(name), &dwOut, NULL))
+ if (DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), name, sizeof(name), &dwOut, NULL)) {
ffStrbufSetWS(&battery->serial, name);
+ }
}
battery->cycleCount = bi.CycleCount;
battery->temperature = FF_BATTERY_TEMP_UNSET;
- if(options->temp)
- {
+ if (options->temp) {
bqi.InformationLevel = BatteryTemperature;
ULONG temp;
- if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), &temp, sizeof(temp), &dwOut, NULL))
+ if (DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), &temp, sizeof(temp), &dwOut, NULL)) {
battery->temperature = temp / 10.0 - 273.15;
+ }
}
{
bqi.InformationLevel = BatteryEstimatedTime;
ULONG time;
- if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), &time, sizeof(time), &dwOut, NULL))
+ if (DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), &time, sizeof(time), &dwOut, NULL)) {
battery->timeRemaining = time == BATTERY_UNKNOWN_TIME ? -1 : (int32_t) time;
+ }
}
{
BATTERY_STATUS bs;
BATTERY_WAIT_STATUS bws = { .BatteryTag = bqi.BatteryTag };
- if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_STATUS, &bws, sizeof(bws), &bs, sizeof(bs), &dwOut, NULL) && bs.Capacity != BATTERY_UNKNOWN_CAPACITY && bi.FullChargedCapacity != 0)
+ if (DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_STATUS, &bws, sizeof(bws), &bs, sizeof(bs), &dwOut, NULL) && bs.Capacity != BATTERY_UNKNOWN_CAPACITY && bi.FullChargedCapacity != 0) {
battery->capacity = bs.Capacity * 100.0 / bi.FullChargedCapacity;
- else
- battery->capacity = 0;
- ffStrbufInit(&battery->status);
- if(bs.PowerState & BATTERY_POWER_ON_LINE)
- ffStrbufAppendS(&battery->status, "AC Connected, ");
- if(bs.PowerState & BATTERY_DISCHARGING)
- ffStrbufAppendS(&battery->status, "Discharging, ");
- if(bs.PowerState & BATTERY_CHARGING)
- ffStrbufAppendS(&battery->status, "Charging, ");
- if(bs.PowerState & BATTERY_CRITICAL)
- ffStrbufAppendS(&battery->status, "Critical, ");
- ffStrbufTrimRight(&battery->status, ' ');
- ffStrbufTrimRight(&battery->status, ',');
+ battery->status = FF_BATTERY_STATUS_NONE;
+ if (bs.PowerState & BATTERY_POWER_ON_LINE) {
+ battery->status |= FF_BATTERY_STATUS_AC_CONNECTED;
+ }
+ if (bs.PowerState & BATTERY_DISCHARGING) {
+ battery->status |= FF_BATTERY_STATUS_DISCHARGING;
+ }
+ if (bs.PowerState & BATTERY_CHARGING) {
+ battery->status |= FF_BATTERY_STATUS_CHARGING;
+ }
+ if (bs.PowerState & BATTERY_CRITICAL) {
+ battery->status |= FF_BATTERY_STATUS_CRITICAL;
+ }
+ } else {
+ battery->status = FF_BATTERY_STATUS_UNKNOWN;
+ battery->capacity = 0;
+ }
}
}
return NULL;
}
-typedef struct FFSmbiosPortableBattery
-{
+typedef struct FFSmbiosPortableBattery {
FFSmbiosHeader Header;
// 2.1+
- uint8_t Location; // string
- uint8_t Manufacturer; // string
- uint8_t ManufactureDate; // string
- uint8_t SerialNumber; // string
- uint8_t DeviceName; // string
- uint8_t DeviceChemistry; // enum
- uint16_t DesignCapacity; // varies
- uint16_t DesignVoltage; // varies
- uint8_t SbdsVersionNumber; // string
+ uint8_t Location; // string
+ uint8_t Manufacturer; // string
+ uint8_t ManufactureDate; // string
+ uint8_t SerialNumber; // string
+ uint8_t DeviceName; // string
+ uint8_t DeviceChemistry; // enum
+ uint16_t DesignCapacity; // varies
+ uint16_t DesignVoltage; // varies
+ uint8_t SbdsVersionNumber; // string
uint8_t MaximumErrorInBatteryData; // varies
// 2.2+
- uint16_t SbdsSerialNumber; // varies
- uint16_t SbdsManufactureDate; // varies
- uint8_t SbdsDeviceChemistry; // string
+ uint16_t SbdsSerialNumber; // varies
+ uint16_t SbdsManufactureDate; // varies
+ uint8_t SbdsDeviceChemistry; // string
uint8_t DesignCapacityMultiplier; // varies
- uint16_t OEMSpecific; // varies
-} __attribute__((__packed__)) FFSmbiosPortableBattery;
+ uint16_t OEMSpecific; // varies
+} FF_A_PACKED FFSmbiosPortableBattery;
static_assert(offsetof(FFSmbiosPortableBattery, OEMSpecific) == 0x16,
"FFSmbiosPortableBattery: Wrong struct alignment");
-static const char* detectBySmbios(FFBatteryResult* battery)
-{
+static const char* detectBySmbios(FFBatteryResult* battery) {
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
- if (!smbiosTable)
+ if (!smbiosTable) {
return "Failed to get SMBIOS data";
+ }
const FFSmbiosPortableBattery* data = (const FFSmbiosPortableBattery*) (*smbiosTable)[FF_SMBIOS_TYPE_PORTABLE_BATTERY];
- if (!data)
+ if (!data) {
return "Portable battery section is not found in SMBIOS data";
+ }
const char* strings = (const char*) data + data->Header.Length;
@@ -186,70 +208,81 @@ static const char* detectBySmbios(FFBatteryResult* battery)
ffStrbufSetStatic(&battery->manufacturer, ffSmbiosLocateString(strings, data->Manufacturer));
ffCleanUpSmbiosValue(&battery->manufacturer);
- if (data->ManufactureDate)
- {
+ if (data->ManufactureDate) {
ffStrbufSetStatic(&battery->manufactureDate, ffSmbiosLocateString(strings, data->ManufactureDate));
ffCleanUpSmbiosValue(&battery->manufactureDate);
- }
- else if (data->Header.Length > offsetof(FFSmbiosPortableBattery, SbdsManufactureDate))
- {
+ } else if (data->Header.Length > offsetof(FFSmbiosPortableBattery, SbdsManufactureDate)) {
int day = data->SbdsManufactureDate & 0b11111;
int month = (data->SbdsManufactureDate >> 5) & 0b1111;
int year = (data->SbdsManufactureDate >> 9) + 1800;
ffStrbufSetF(&battery->manufactureDate, "%.4d-%.2d-%.2d", year, month, day);
}
- switch (data->DeviceChemistry)
- {
- case 0x01: ffStrbufSetStatic(&battery->technology, "Other"); break;
- case 0x02: ffStrbufSetStatic(&battery->technology, "Unknown"); break;
- case 0x03: ffStrbufSetStatic(&battery->technology, "Lead Acid"); break;
- case 0x04: ffStrbufSetStatic(&battery->technology, "Nickel Cadmium"); break;
- case 0x05: ffStrbufSetStatic(&battery->technology, "Nickel metal hydride"); break;
- case 0x06: ffStrbufSetStatic(&battery->technology, "Lithium-ion"); break;
- case 0x07: ffStrbufSetStatic(&battery->technology, "Zinc air"); break;
- case 0x08: ffStrbufSetStatic(&battery->technology, "Lithium Polymer"); break;
+ switch (data->DeviceChemistry) {
+ case 0x01:
+ ffStrbufSetStatic(&battery->technology, "Other");
+ break;
+ case 0x02:
+ ffStrbufSetStatic(&battery->technology, "Unknown");
+ break;
+ case 0x03:
+ ffStrbufSetStatic(&battery->technology, "Lead Acid");
+ break;
+ case 0x04:
+ ffStrbufSetStatic(&battery->technology, "Nickel Cadmium");
+ break;
+ case 0x05:
+ ffStrbufSetStatic(&battery->technology, "Nickel metal hydride");
+ break;
+ case 0x06:
+ ffStrbufSetStatic(&battery->technology, "Lithium-ion");
+ break;
+ case 0x07:
+ ffStrbufSetStatic(&battery->technology, "Zinc air");
+ break;
+ case 0x08:
+ ffStrbufSetStatic(&battery->technology, "Lithium Polymer");
+ break;
}
- if (data->SerialNumber)
- {
+ if (data->SerialNumber) {
ffStrbufSetStatic(&battery->serial, ffSmbiosLocateString(strings, data->SerialNumber));
ffCleanUpSmbiosValue(&battery->serial);
- }
- else if (data->Header.Length > offsetof(FFSmbiosPortableBattery, SbdsSerialNumber))
- {
+ } else if (data->Header.Length > offsetof(FFSmbiosPortableBattery, SbdsSerialNumber)) {
ffStrbufSetF(&battery->serial, "%4X", data->SbdsSerialNumber);
}
return NULL;
}
-static const char* detectWithNtApi(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* results)
-{
+static const char* detectWithNtApi(FF_A_UNUSED FFBatteryOptions* options, FFlist* results) {
SYSTEM_BATTERY_STATE info;
- if (NT_SUCCESS(NtPowerInformation(SystemBatteryState, NULL, 0, &info, sizeof(info))) && info.BatteryPresent)
- {
- FFBatteryResult* battery = (FFBatteryResult*)ffListAdd(results);
+ if (NT_SUCCESS(NtPowerInformation(SystemBatteryState, NULL, 0, &info, sizeof(info))) &&
+ info.BatteryPresent) {
+ FFBatteryResult* battery = FF_LIST_ADD(FFBatteryResult, *results);
ffStrbufInit(&battery->modelName);
ffStrbufInit(&battery->manufacturer);
ffStrbufInit(&battery->manufactureDate);
ffStrbufInit(&battery->technology);
- ffStrbufInit(&battery->status);
ffStrbufInit(&battery->serial);
battery->temperature = FF_BATTERY_TEMP_UNSET;
battery->cycleCount = 0;
battery->timeRemaining = info.EstimatedTime == BATTERY_UNKNOWN_TIME ? -1 : (int32_t) info.EstimatedTime;
+ battery->status = FF_BATTERY_STATUS_NONE;
battery->capacity = info.RemainingCapacity * 100.0 / info.MaxCapacity;
- if(info.AcOnLine)
- {
- ffStrbufAppendS(&battery->status, "AC Connected");
- if(info.Charging)
- ffStrbufAppendS(&battery->status, ", Charging");
+ if (info.AcOnLine) {
+ battery->status |= FF_BATTERY_STATUS_AC_CONNECTED;
+ }
+ if (info.Charging) {
+ battery->status |= FF_BATTERY_STATUS_CHARGING;
+ }
+ if (info.Discharging) {
+ battery->status |= FF_BATTERY_STATUS_DISCHARGING;
+ }
+ if (info.DefaultAlert1 > 0 && info.RemainingCapacity <= info.DefaultAlert1) {
+ battery->status |= FF_BATTERY_STATUS_CRITICAL;
}
- else if(info.Discharging)
- ffStrbufAppendS(&battery->status, "Discharging");
-
detectBySmbios(battery);
@@ -258,8 +291,7 @@ static const char* detectWithNtApi(FF_MAYBE_UNUSED FFBatteryOptions* options, FF
return "NtPowerInformation(SystemBatteryState) failed";
}
-const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
-{
+const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results) {
return options->useSetupApi
? detectWithCmApi(options, results)
: detectWithNtApi(options, results);
diff --git a/src/detection/bios/bios.h b/src/detection/bios/bios.h
index 4a0969d266..cdb48c2924 100644
--- a/src/detection/bios/bios.h
+++ b/src/detection/bios/bios.h
@@ -3,8 +3,7 @@
#include "fastfetch.h"
#include "modules/bios/option.h"
-typedef struct FFBiosResult
-{
+typedef struct FFBiosResult {
FFstrbuf date;
FFstrbuf release;
FFstrbuf vendor;
diff --git a/src/detection/bios/bios_android.c b/src/detection/bios/bios_android.c
index b2b20aaf9d..a53db0db50 100644
--- a/src/detection/bios/bios_android.c
+++ b/src/detection/bios/bios_android.c
@@ -1,13 +1,14 @@
#include "bios.h"
#include "common/settings.h"
-const char* ffDetectBios(FFBiosResult* bios)
-{
- if (!ffSettingsGetAndroidProperty("ro.bootloader", &bios->version))
+const char* ffDetectBios(FFBiosResult* bios) {
+ if (!ffSettingsGetAndroidProperty("ro.bootloader", &bios->version)) {
ffSettingsGetAndroidProperty("ro.boot.bootloader", &bios->version);
+ }
- if (ffStrbufIgnCaseEqualS(&bios->version, "unknown"))
+ if (ffStrbufIgnCaseEqualS(&bios->version, "unknown")) {
ffStrbufClear(&bios->version);
+ }
ffStrbufSetStatic(&bios->type, "Bootloader");
diff --git a/src/detection/bios/bios_apple.c b/src/detection/bios/bios_apple.c
index 87df39d356..96845d8886 100644
--- a/src/detection/bios/bios_apple.c
+++ b/src/detection/bios/bios_apple.c
@@ -3,31 +3,33 @@
#include
-const char* ffDetectBios(FFBiosResult* bios)
-{
- #ifndef __aarch64__
+const char* ffDetectBios(FFBiosResult* bios) {
+#ifndef __aarch64__
- //https://github.com/osquery/osquery/blob/master/osquery/tables/system/darwin/smbios_tables.cpp
- //For Intel
+ // https://github.com/osquery/osquery/blob/master/osquery/tables/system/darwin/smbios_tables.cpp
+ // For Intel
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t deviceRom = IORegistryEntryFromPath(MACH_PORT_NULL, "IODeviceTree:/rom");
- if (!deviceRom)
+ if (!deviceRom) {
return "IODeviceTree:/rom not found";
+ }
FF_CFTYPE_AUTO_RELEASE CFMutableDictionaryRef deviceRomProps = NULL;
- if(IORegistryEntryCreateCFProperties(deviceRom, &deviceRomProps, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
+ if (IORegistryEntryCreateCFProperties(deviceRom, &deviceRomProps, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess) {
return "IORegistryEntryCreateCFProperties(deviceRom) failed";
+ }
ffCfDictGetString(deviceRomProps, CFSTR("vendor"), &bios->vendor);
ffCfDictGetString(deviceRomProps, CFSTR("version"), &bios->version);
ffCfDictGetString(deviceRomProps, CFSTR("release-date"), &bios->date);
ffStrbufSetStatic(&bios->type, "UEFI");
- #else
+#else
- //For arm64
+ // For arm64
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t device = IORegistryEntryFromPath(MACH_PORT_NULL, "IODeviceTree:/");
- if (!device)
+ if (!device) {
return "IODeviceTree:/ not found";
+ }
FF_CFTYPE_AUTO_RELEASE CFDataRef manufacturer = IORegistryEntryCreateCFProperty(device, CFSTR("manufacturer"), kCFAllocatorDefault, kNilOptions);
ffCfStrGetString(manufacturer, &bios->vendor);
@@ -35,23 +37,21 @@ const char* ffDetectBios(FFBiosResult* bios)
ffCfStrGetString(timeStamp, &bios->date);
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t deviceChosen = IORegistryEntryFromPath(MACH_PORT_NULL, "IODeviceTree:/chosen");
- if (deviceChosen)
- {
+ if (deviceChosen) {
FF_CFTYPE_AUTO_RELEASE CFStringRef systemFirmwareVersion = IORegistryEntryCreateCFProperty(deviceChosen, CFSTR("system-firmware-version"), kCFAllocatorDefault, kNilOptions);
- if (systemFirmwareVersion)
- {
+ if (systemFirmwareVersion) {
ffCfStrGetString(systemFirmwareVersion, &bios->version);
uint32_t index = ffStrbufFirstIndexC(&bios->version, '-');
- if (index != bios->version.length)
- {
+ if (index != bios->version.length) {
ffStrbufAppendNS(&bios->type, index, bios->version.chars);
ffStrbufRemoveSubstr(&bios->version, 0, index + 1);
}
}
}
- if (!bios->type.length)
+ if (!bios->type.length) {
ffStrbufSetStatic(&bios->type, "iBoot");
- #endif
+ }
+#endif
return NULL;
}
diff --git a/src/detection/bios/bios_bsd.c b/src/detection/bios/bios_bsd.c
index 35f371ab7f..66e50ea517 100644
--- a/src/detection/bios/bios_bsd.c
+++ b/src/detection/bios/bios_bsd.c
@@ -3,10 +3,9 @@
#include "common/settings.h"
#include "common/sysctl.h"
#include "common/io.h"
-#include "common/smbiosHelper.h"
+#include "common/smbios.h"
-const char* ffDetectBios(FFBiosResult* result)
-{
+const char* ffDetectBios(FFBiosResult* result) {
ffSettingsGetFreeBSDKenv("smbios.bios.reldate", &result->date);
ffCleanUpSmbiosValue(&result->date);
ffSettingsGetFreeBSDKenv("smbios.bios.revision", &result->release);
@@ -17,16 +16,15 @@ const char* ffDetectBios(FFBiosResult* result)
ffCleanUpSmbiosValue(&result->version);
ffSysctlGetString("machdep.bootmethod", &result->type);
- if (result->type.length == 0)
- {
- if (ffSettingsGetFreeBSDKenv("loader.efi", &result->type))
+ if (result->type.length == 0) {
+ if (ffSettingsGetFreeBSDKenv("loader.efi", &result->type)) {
ffStrbufSetStatic(&result->type, ffStrbufEqualS(&result->type, "1") ? "UEFI" : "BIOS");
- else
- {
+ } else {
ffStrbufSetStatic(&result->type,
ffPathExists("/dev/efi" /*efidev*/, FF_PATHTYPE_FILE) ||
- ffPathExists("/boot/efi/efi/" /*efi partition. Note /boot/efi exists on BIOS system*/, FF_PATHTYPE_DIRECTORY)
- ? "UEFI" : "BIOS");
+ ffPathExists("/boot/efi/efi/" /*efi partition. Note /boot/efi exists on BIOS system*/, FF_PATHTYPE_DIRECTORY)
+ ? "UEFI"
+ : "BIOS");
}
}
return NULL;
diff --git a/src/detection/bios/bios_linux.c b/src/detection/bios/bios_linux.c
index 5e6a27a95b..8776631e2d 100644
--- a/src/detection/bios/bios_linux.c
+++ b/src/detection/bios/bios_linux.c
@@ -1,24 +1,21 @@
#include "bios.h"
#include "common/io.h"
-#include "common/smbiosHelper.h"
+#include "common/smbios.h"
-const char* ffDetectBios(FFBiosResult* bios)
-{
- if (ffGetSmbiosValue("/sys/devices/virtual/dmi/id/bios_date", "/sys/class/dmi/id/bios_date", &bios->date))
- {
+const char* ffDetectBios(FFBiosResult* bios) {
+ if (ffGetSmbiosValue("/sys/devices/virtual/dmi/id/bios_date", "/sys/class/dmi/id/bios_date", &bios->date)) {
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/bios_release", "/sys/class/dmi/id/bios_release", &bios->release);
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/bios_vendor", "/sys/class/dmi/id/bios_vendor", &bios->vendor);
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/bios_version", "/sys/class/dmi/id/bios_version", &bios->version);
- }
- else if (ffReadFileBuffer("/proc/device-tree/chosen/u-boot,version", &bios->version))
- {
+ } else if (ffReadFileBuffer("/proc/device-tree/chosen/u-boot,version", &bios->version)) {
ffStrbufTrimRight(&bios->version, '\0');
ffStrbufSetStatic(&bios->vendor, "U-Boot");
}
- if (ffPathExists("/sys/firmware/efi/", FF_PATHTYPE_DIRECTORY) || ffPathExists("/sys/firmware/acpi/tables/UEFI", FF_PATHTYPE_FILE))
+ if (ffPathExists("/sys/firmware/efi/", FF_PATHTYPE_DIRECTORY) || ffPathExists("/sys/firmware/acpi/tables/UEFI", FF_PATHTYPE_FILE)) {
ffStrbufSetStatic(&bios->type, "UEFI");
- else
+ } else {
ffStrbufSetStatic(&bios->type, "BIOS");
+ }
return NULL;
}
diff --git a/src/detection/bios/bios_nbsd.c b/src/detection/bios/bios_nbsd.c
index 10b326dd12..3ab43ed0b4 100644
--- a/src/detection/bios/bios_nbsd.c
+++ b/src/detection/bios/bios_nbsd.c
@@ -1,15 +1,20 @@
#include "bios.h"
#include "common/sysctl.h"
-#include "common/smbiosHelper.h"
+#include "common/smbios.h"
+#include "common/io.h"
-const char* ffDetectBios(FFBiosResult* bios)
-{
- if (ffSysctlGetString("machdep.dmi.bios-date", &bios->date) == NULL)
+const char* ffDetectBios(FFBiosResult* bios) {
+ if (ffSysctlGetString("machdep.dmi.bios-date", &bios->date) == NULL) {
ffCleanUpSmbiosValue(&bios->date);
- if (ffSysctlGetString("machdep.dmi.bios-version", &bios->version) == NULL)
+ }
+ if (ffSysctlGetString("machdep.dmi.bios-version", &bios->version) == NULL) {
ffCleanUpSmbiosValue(&bios->version);
- if (ffSysctlGetString("machdep.dmi.bios-vendor", &bios->vendor) == NULL)
+ }
+ if (ffSysctlGetString("machdep.dmi.bios-vendor", &bios->vendor) == NULL) {
ffCleanUpSmbiosValue(&bios->vendor);
- ffSysctlGetString("machdep.bootmethod", &bios->type);
+ }
+ if (ffSysctlGetString("machdep.bootmethod", &bios->type) != NULL) {
+ ffStrbufSetStatic(&bios->type, ffPathExists("/dev/efi", FF_PATHTYPE_FILE) ? "UEFI" : "BIOS");
+ }
return NULL;
}
diff --git a/src/detection/bios/bios_nosupport.c b/src/detection/bios/bios_nosupport.c
index ac544fd3e0..e044835700 100644
--- a/src/detection/bios/bios_nosupport.c
+++ b/src/detection/bios/bios_nosupport.c
@@ -1,6 +1,5 @@
#include "bios.h"
-const char* ffDetectBios(FF_MAYBE_UNUSED FFBiosResult* bios)
-{
+const char* ffDetectBios(FF_A_UNUSED FFBiosResult* bios) {
return "Not supported on this platform";
}
diff --git a/src/detection/bios/bios_windows.c b/src/detection/bios/bios_windows.c
index f1196a3d4f..42b7674a42 100644
--- a/src/detection/bios/bios_windows.c
+++ b/src/detection/bios/bios_windows.c
@@ -1,59 +1,58 @@
#include "bios.h"
-#include "common/smbiosHelper.h"
+#include "common/smbios.h"
#ifdef _WIN32
-#include "common/windows/registry.h"
+ #include "common/windows/registry.h"
-#include
-#include "common/windows/nt.h"
+ #include
+ #include "common/windows/nt.h"
#elif __OpenBSD__
-#include "common/io.h"
+ #include "common/io.h"
-#include
-#include
+ #include
+ #include
#elif __sun
-#include
-#include
+ #include
+ #include
#elif __APPLE__
-#include "common/apple/cf_helpers.h"
-#include
+ #include "common/apple/cf_helpers.h"
+ #include
#endif
-typedef struct FFSmbiosBios
-{
+typedef struct FFSmbiosBios {
FFSmbiosHeader Header;
- uint8_t Vendor; // string
- uint8_t BiosVersion; // string
+ uint8_t Vendor; // string
+ uint8_t BiosVersion; // string
uint16_t BiosStartingAddressSegment; // varies
- uint8_t BiosReleaseDate; // string
- uint8_t BiosRomSize; // string
- uint64_t BiosCharacteristics; // bit field
+ uint8_t BiosReleaseDate; // string
+ uint8_t BiosRomSize; // string
+ uint64_t BiosCharacteristics; // bit field
// 2.4+
- uint8_t BiosCharacteristicsExtensionBytes[2]; // bit field
- uint8_t SystemBiosMajorRelease; // varies
- uint8_t SystemBiosMinorRelease; // varies
+ uint8_t BiosCharacteristicsExtensionBytes[2]; // bit field
+ uint8_t SystemBiosMajorRelease; // varies
+ uint8_t SystemBiosMinorRelease; // varies
uint8_t EmbeddedControllerFirmwareMajorRelease; // varies
uint8_t EmbeddedControllerFirmwareMinorRelease; // varies
// 3.1+
uint16_t ExtendedBiosRomSize; // bit field
-} __attribute__((__packed__)) FFSmbiosBios;
+} FF_A_PACKED FFSmbiosBios;
static_assert(offsetof(FFSmbiosBios, ExtendedBiosRomSize) == 0x18,
"FFSmbiosBios: Wrong struct alignment");
-
-const char* ffDetectBios(FFBiosResult* bios)
-{
+const char* ffDetectBios(FFBiosResult* bios) {
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
- if (!smbiosTable)
+ if (!smbiosTable) {
return "Failed to get SMBIOS data";
+ }
const FFSmbiosBios* data = (const FFSmbiosBios*) (*smbiosTable)[FF_SMBIOS_TYPE_BIOS];
- if (!data)
+ if (!data) {
return "BIOS section is not found in SMBIOS data";
+ }
const char* strings = (const char*) data + data->Header.Length;
@@ -64,41 +63,45 @@ const char* ffDetectBios(FFBiosResult* bios)
ffStrbufSetStatic(&bios->date, ffSmbiosLocateString(strings, data->BiosReleaseDate));
ffCleanUpSmbiosValue(&bios->date);
- if (data->Header.Length > offsetof(FFSmbiosBios, SystemBiosMajorRelease))
+ if (data->Header.Length > offsetof(FFSmbiosBios, SystemBiosMajorRelease)) {
ffStrbufSetF(&bios->release, "%u.%u", data->SystemBiosMajorRelease, data->SystemBiosMinorRelease);
+ }
- #ifdef _WIN32
+#ifdef _WIN32
// Same as GetFirmwareType, but support (?) Windows 7
// https://ntdoc.m417z.com/system_information_class
SYSTEM_BOOT_ENVIRONMENT_INFORMATION sbei;
- if (NT_SUCCESS(NtQuerySystemInformation(SystemBootEnvironmentInformation, &sbei, sizeof(sbei), NULL)))
- {
- switch (sbei.FirmwareType)
- {
- case FirmwareTypeBios: ffStrbufSetStatic(&bios->type, "BIOS"); break;
- case FirmwareTypeUefi: ffStrbufSetStatic(&bios->type, "UEFI"); break;
- default: break;
+ if (NT_SUCCESS(NtQuerySystemInformation(SystemBootEnvironmentInformation, &sbei, sizeof(sbei), NULL))) {
+ switch (sbei.FirmwareType) {
+ case FirmwareTypeBios:
+ ffStrbufSetStatic(&bios->type, "BIOS");
+ break;
+ case FirmwareTypeUefi:
+ ffStrbufSetStatic(&bios->type, "UEFI");
+ break;
+ default:
+ break;
}
}
- #elif __sun
+#elif __sun
di_node_t rootNode = di_init("/", DINFOPROP);
- if (rootNode != DI_NODE_NIL)
- {
+ if (rootNode != DI_NODE_NIL) {
char* efiVersion = NULL;
- if (di_prop_lookup_strings(DDI_DEV_T_ANY, rootNode, "efi-version", &efiVersion) > 0)
+ if (di_prop_lookup_strings(DDI_DEV_T_ANY, rootNode, "efi-version", &efiVersion) > 0) {
ffStrbufSetStatic(&bios->type, "UEFI");
- else
+ } else {
ffStrbufSetStatic(&bios->type, "BIOS");
+ }
}
di_fini(rootNode);
- #elif __HAIKU__ || __OpenBSD__
+#elif __HAIKU__ || __OpenBSD__
// Currently SMBIOS detection is supported in legacy BIOS only
ffStrbufSetStatic(&bios->type, "BIOS");
- #elif __APPLE__
+#elif __APPLE__
// Intel Macs use UEFI from day one
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t deviceEfi = IORegistryEntryFromPath(MACH_PORT_NULL, "IODeviceTree:/efi");
ffStrbufSetStatic(&bios->type, deviceEfi ? "UEFI" : "BIOS");
- #endif
+#endif
return NULL;
}
diff --git a/src/detection/bluetooth/bluetooth.h b/src/detection/bluetooth/bluetooth.h
index 0a4153ce5a..dde80853d9 100644
--- a/src/detection/bluetooth/bluetooth.h
+++ b/src/detection/bluetooth/bluetooth.h
@@ -3,8 +3,7 @@
#include "fastfetch.h"
#include "modules/bluetooth/option.h"
-typedef struct FFBluetoothResult
-{
+typedef struct FFBluetoothResult {
FFstrbuf name;
FFstrbuf address;
FFstrbuf type;
diff --git a/src/detection/bluetooth/bluetooth_apple.m b/src/detection/bluetooth/bluetooth_apple.m
index e7d3abd391..9cbf732a50 100644
--- a/src/detection/bluetooth/bluetooth_apple.m
+++ b/src/detection/bluetooth/bluetooth_apple.m
@@ -21,7 +21,7 @@ @interface IOBluetoothDevice()
if (!options->showDisconnected && !ioDevice.isConnected)
continue;
- FFBluetoothResult* device = ffListAdd(devices);
+ FFBluetoothResult* device = FF_LIST_ADD(FFBluetoothResult, *devices);
ffStrbufInitS(&device->name, ioDevice.name.UTF8String);
ffStrbufInitS(&device->address, ioDevice.addressString.UTF8String);
ffStrbufReplaceAllC(&device->address, '-', ':');
diff --git a/src/detection/bluetooth/bluetooth_bsd.c b/src/detection/bluetooth/bluetooth_bsd.c
index 7425c614f0..db9f23cf74 100644
--- a/src/detection/bluetooth/bluetooth_bsd.c
+++ b/src/detection/bluetooth/bluetooth_bsd.c
@@ -3,15 +3,14 @@
#define L2CAP_SOCKET_CHECKED
#include