mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-10-29 19:20:43 +01:00
Compare commits
152 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0ae71b69ce | |||
| 20277b9ee9 | |||
| b6d95a0ce5 | |||
| daf5421be7 | |||
| b739dfee0b | |||
| 80101a5803 | |||
| cf33bef128 | |||
| 7e786bee31 | |||
| cbea6c3cb1 | |||
| 48a234d742 | |||
| c271708f7d | |||
| b42f11442c | |||
| 73918956d7 | |||
| 6559c7f42d | |||
| 56950e790f | |||
| e7642ea3a2 | |||
| a88ef86ce3 | |||
| fcf4aca3b7 | |||
| 3f8d141313 | |||
| 97a9be27b9 | |||
| dc46ecbcac | |||
| 984fadf70f | |||
| 1a42cbe1cf | |||
| 9c7cfb864f | |||
| 6d795a3572 | |||
| 2af56232a4 | |||
| 3196f5efaa | |||
| 1626ced83c | |||
| 241ddb79b0 | |||
| 66ce39e3fc | |||
| 3fae9e0274 | |||
| 5eaf98ecd2 | |||
| 00b7c5b56c | |||
| 305ab14e7b | |||
| a58fc4f77d | |||
| b653ef730d | |||
| dc464d6efe | |||
| 1c3f0eb7c0 | |||
| 476cd67345 | |||
| 2c736697d2 | |||
| 738ad59f54 | |||
| 5476e01407 | |||
| 4f0b00116e | |||
| 6490e2707f | |||
| ccf3909372 | |||
| 18eef29d0a | |||
| f6c25667fe | |||
| 97fa52fef0 | |||
| c5a8950ad4 | |||
| 111c1bab75 | |||
| 47dfd8a271 | |||
| bc1d305aaa | |||
| dda39f0c67 | |||
| 0b72c9b083 | |||
| 69f3d9ae33 | |||
| db46e06f2e | |||
| 7223803a76 | |||
| 9db4ec82fd | |||
| 62180366fc | |||
| 0feec933ea | |||
| 6c03db8be9 | |||
| f0564fb9a7 | |||
| 8bf1aca7fc | |||
| 445311978e | |||
| d9f5e006b5 | |||
| 21fbf14fb8 | |||
| bc8ce39193 | |||
| ac3fc219cf | |||
| dd30c82b83 | |||
| b41cdb0ca6 | |||
| 2b03bacb28 | |||
| 7dcc7d40d5 | |||
| a0fd59d869 | |||
| 1c352bb4de | |||
| 29d626f41d | |||
| 8ca6bb084d | |||
| 0b3ef5d35c | |||
| 98c8c5b344 | |||
| eeae601924 | |||
| 773e3ea497 | |||
| 317c0cfb86 | |||
| e0c31be9d5 | |||
| 75f00af98d | |||
| 9d6bb7d717 | |||
| 2ae9c3da33 | |||
| bf1af71d03 | |||
| 61656a1a7a | |||
| ba18705d2e | |||
| 873454191f | |||
| f8908b9a36 | |||
| 8ca551cccc | |||
| 0869809857 | |||
| c31779e99d | |||
| 89ad35d8a1 | |||
| d651f3de43 | |||
| c34c3e5aae | |||
| c5c61584d9 | |||
| 48c3b4f980 | |||
| 93bca8d480 | |||
| c690fe5aa9 | |||
| 55e674e1cb | |||
| 0495c47909 | |||
| 2f79c39f62 | |||
| 44056f1c85 | |||
| 6358bd7844 | |||
| 11d77e0d09 | |||
| ec25659503 | |||
| 35dbcb2588 | |||
| 8b6a74f2ec | |||
| 2ea6c3767e | |||
| 827bc26b0a | |||
| e12f3631d4 | |||
| 52c9730542 | |||
| 225d9e7771 | |||
| d031d6c20f | |||
| 35af768d92 | |||
| 22c4620345 | |||
| 81738aa303 | |||
| 113f7d34d8 | |||
| 62513004c8 | |||
| 1b36c3cd5f | |||
| 78874ae583 | |||
| a447928853 | |||
| 9f446bdad7 | |||
| 4cf060eb27 | |||
| 08d419d75c | |||
| 3ae1bfdc24 | |||
| 0e257f25c2 | |||
| 195e148cc1 | |||
| 5ab192ee05 | |||
| 4897152af6 | |||
| 69418cb527 | |||
| 0e90f3a7d4 | |||
| 1a663e72da | |||
| e0ae1ac1a2 | |||
| e0d141ecf6 | |||
| 29eb8bb57d | |||
| bc1f240558 | |||
| 3e15a2591a | |||
| 0ec9443de5 | |||
| 4a4ca9a4a8 | |||
| acf76e565a | |||
| 778aa21192 | |||
| dfdc7284a2 | |||
| 231d7fcd4d | |||
| a3184601dc | |||
| e3dfeeb8db | |||
| ccdcd6ab6f | |||
| 64d205628e | |||
| ff13adf1b4 | |||
| c38fd9ec10 | |||
| 96793ec604 |
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
[codespell]
|
[codespell]
|
||||||
check-filenames =
|
check-filenames =
|
||||||
builtin = clear,rare,usage,informal
|
builtin = clear,rare,usage,informal
|
||||||
skip = */.git,*/cmake-build-*,*/.idea,*/completions,*/presets,*/screenshots,*/tests,*/3rdparty,*/logo/ascii,./src/detection/gpu/asahi_drm.h,./src/detection/cpu/cpu_x86.c,./src/detection/gpu/gpu_bsddrm.c,./src/detection/displayserver/linux/wayland/*-protocol.*,./build,./build-*,./build_*
|
skip = */.git,*/cmake-build-*,*/.idea,*/completions,*/presets,*/screenshots,*/tests,*/3rdparty,*/logo/ascii,./src/detection/gpu/asahi_drm.h,./src/detection/cpu/cpu_x86.c,./src/detection/gpu/gpu_bsddrm.c,./src/detection/displayserver/linux/wayland/*-protocol.*,./build,./build-*,./build_*,./src/common/impl/genconfig.c
|
||||||
ignore-words-list = iterm,compiletime,unknwn,pengwin,siduction,master,slave,sur,doas,conexant,ags,bu,renderD,SME,Carmel,kinda
|
ignore-words-list = iterm,compiletime,unknwn,pengwin,siduction,master,slave,sur,doas,conexant,ags,bu,renderD,SME,Carmel,kinda
|
||||||
|
|||||||
@@ -6,16 +6,31 @@ body:
|
|||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
value: |
|
value: |
|
||||||
Tip: You can display a logo in fastfetch without adding it to fastfetch's official repo.
|
> [!WARNING]
|
||||||
|
> **NB:** If your logo request does not meet the basic requirements outlined in this template, the issue may be closed at any time without any further explanation.
|
||||||
|
|
||||||
|
**Tip:** You can display a logo in fastfetch without adding it to fastfetch's official repo.
|
||||||
For highly customized, personal logos, we recommend keeping them locally.
|
For highly customized, personal logos, we recommend keeping them locally.
|
||||||
Please refer to https://github.com/fastfetch-cli/fastfetch/wiki/Migrate-Neofetch-Logo-To-Fastfetch
|
You can test your logo locally using:
|
||||||
|
`fastfetch -l /path/to/logo.txt --logo-color-1 white --logo-color-2 red`
|
||||||
|
Please refer to the [Migration Guide](https://github.com/fastfetch-cli/fastfetch/wiki/Migrate-Neofetch-Logo-To-Fastfetch) for details on color placeholders (`$1`, `$2`, etc.).
|
||||||
|
|
||||||
- type: textarea
|
- type: textarea
|
||||||
attributes:
|
attributes:
|
||||||
label: OS
|
label: OS
|
||||||
description: Paste the contents of `/etc/os-release` and `/etc/lsb-release` here. If neither file exists, describe how to identify the distro.
|
description: Paste the contents of `/etc/os-release` (specifically the `ID` and `PRETTY_NAME` fields). If neither file exists, describe how to identify the distro.
|
||||||
placeholder: cat /etc/os-release
|
placeholder: cat /etc/os-release
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
|
- type: input
|
||||||
|
attributes:
|
||||||
|
label: Public repository URL
|
||||||
|
description: A public repository is required to verify the request. Please provide a link to the repository where the distro is developed.
|
||||||
|
placeholder: https://github.com/example/distro
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
- type: input
|
- type: input
|
||||||
attributes:
|
attributes:
|
||||||
label: Distro Website
|
label: Distro Website
|
||||||
@@ -23,25 +38,35 @@ body:
|
|||||||
placeholder: https://example.com
|
placeholder: https://example.com
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
- type: textarea
|
- type: textarea
|
||||||
attributes:
|
attributes:
|
||||||
label: ASCII Art
|
label: ASCII Art
|
||||||
description: The ASCII logo should not take up too much space (smaller than 50x20 characters, W x H). Please also include the color codes if they are not available in `os-release`.
|
description: |
|
||||||
placeholder: Paste ASCII art here
|
The ASCII logo should not take up too much space (smaller than 50x20 characters, W x H).
|
||||||
|
**Important:** Fastfetch uses `$1`, `$2`, `$3` etc. for color placeholders. Do NOT use hardcoded ANSI escape codes (like `\033[38;2...m`) or Neofetch's `${c1}` syntax.
|
||||||
|
Take <https://github.com/fastfetch-cli/fastfetch/tree/dev/src/logo/ascii> as examples.
|
||||||
|
placeholder: Paste ASCII art with $1, $2 placeholders here
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
- type: input
|
- type: input
|
||||||
attributes:
|
attributes:
|
||||||
label: Original Image URL
|
label: Original Image URL
|
||||||
description: If the ASCII art is based on an image, please provide a link to the original image file.
|
description: If the ASCII art is based on an image, please provide a link to the original image file.
|
||||||
placeholder: Image URL from the distro website mentioned above
|
placeholder: Image URL from the distro website mentioned above
|
||||||
|
|
||||||
- type: checkboxes
|
- type: checkboxes
|
||||||
attributes:
|
attributes:
|
||||||
label: Checklist
|
label: Checklist
|
||||||
options:
|
options:
|
||||||
|
- label: My distro has reached a stable state (out of beta, alpha, RC).
|
||||||
|
required: true
|
||||||
- label: The ASCII art is smaller than 50x20 characters (W x H).
|
- label: The ASCII art is smaller than 50x20 characters (W x H).
|
||||||
required: true
|
required: true
|
||||||
- label: The ASCII art includes color codes, or the color codes are available in `os-release`.
|
- label: The ASCII art uses `$N` color placeholders (or colors are natively available in `os-release`).
|
||||||
required: true
|
required: true
|
||||||
- label: The ASCII art has no internal padding (spaces at the start and/or end of lines).
|
- label: The ASCII art has no unnecessary trailing spaces at the end of lines.
|
||||||
|
required: true
|
||||||
|
- label: I promise that I will send a removal request if the distro is discontinued.
|
||||||
required: true
|
required: true
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
|
day: "sunday"
|
||||||
|
cooldown:
|
||||||
|
default-days: 7
|
||||||
|
open-pull-requests-limit: 10
|
||||||
|
commit-message:
|
||||||
|
prefix: "CI"
|
||||||
|
labels:
|
||||||
|
- "ci"
|
||||||
|
groups:
|
||||||
|
github-actions:
|
||||||
|
patterns:
|
||||||
|
- "*"
|
||||||
@@ -3,38 +3,64 @@ name: Reusable DragonFly amd64
|
|||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
|
|
||||||
env:
|
permissions:
|
||||||
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: cpa.sh {0}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: checkout repository
|
- name: checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
- name: run VM
|
- name: Start VM
|
||||||
uses: vmactions/dragonflybsd-vm@v1
|
uses: cross-platform-actions/action@5ea7e8e4677bd726033a10b094ba1c5762b15dee # v1.3.0
|
||||||
with:
|
with:
|
||||||
usesh: yes
|
operating_system: dragonflybsd
|
||||||
envs: 'CMAKE_BUILD_TYPE'
|
version: '6.4.2'
|
||||||
prepare: |
|
shell: bash
|
||||||
uname -a
|
cpu_count: 4
|
||||||
pkg update
|
|
||||||
pkg install -y llvm cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl egl opencl ocl-icd v4l_compat chafa libelf lua54 libva libvdpau
|
|
||||||
|
|
||||||
run: |
|
- name: Show system info
|
||||||
env CC=clang cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
|
run: |
|
||||||
cmake --build . --target package --verbose -j4
|
uname -a
|
||||||
./fastfetch --list-features
|
pkg --version
|
||||||
time ./fastfetch -c presets/ci.jsonc --stat false
|
|
||||||
time ./fastfetch -c presets/ci.jsonc --format json
|
- name: Update and install dependencies
|
||||||
time ./flashfetch
|
run: |
|
||||||
ldd fastfetch
|
sudo pkg update
|
||||||
ctest --output-on-failure
|
sudo pkg install -y llvm cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl egl opencl ocl-icd v4l_compat chafa libelf lua54 libva libvdpau
|
||||||
|
|
||||||
|
- name: CMake configuration
|
||||||
|
run: env CC=clang cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_BUILD_TYPE=${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }} .
|
||||||
|
|
||||||
|
- name: CMake build
|
||||||
|
run: cmake --build . --target package --verbose -j4
|
||||||
|
|
||||||
|
- name: List features
|
||||||
|
run: ./fastfetch --list-features
|
||||||
|
|
||||||
|
- name: Run normal
|
||||||
|
run: time ./fastfetch -c presets/ci.jsonc --stat false
|
||||||
|
|
||||||
|
- name: Run json
|
||||||
|
run: time ./fastfetch -c presets/ci.jsonc --format json
|
||||||
|
|
||||||
|
- name: Run flashfetch
|
||||||
|
run: time ./flashfetch
|
||||||
|
|
||||||
|
- name: Run ldd
|
||||||
|
run: ldd fastfetch
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: ctest --output-on-failure
|
||||||
|
|
||||||
- name: upload artifacts
|
- name: upload artifacts
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: fastfetch-dragonfly-amd64
|
name: fastfetch-dragonfly-amd64
|
||||||
path: ./fastfetch-*.*
|
path: ./fastfetch-*.*
|
||||||
|
|||||||
@@ -3,40 +3,65 @@ name: Reusable FreeBSD amd64
|
|||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
|
|
||||||
env:
|
permissions:
|
||||||
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: cpa.sh {0}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: checkout repository
|
- name: checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
- name: run VM
|
- name: Start VM
|
||||||
uses: cross-platform-actions/action@master
|
uses: cross-platform-actions/action@5ea7e8e4677bd726033a10b094ba1c5762b15dee # v1.3.0
|
||||||
with:
|
with:
|
||||||
operating_system: freebsd
|
operating_system: freebsd
|
||||||
architecture: x86-64
|
version: '15.1'
|
||||||
cpu_count: 4
|
|
||||||
shell: bash
|
shell: bash
|
||||||
version: '15.0'
|
cpu_count: 4
|
||||||
environment_variables: 'CMAKE_BUILD_TYPE'
|
|
||||||
run: |
|
- name: Show system info
|
||||||
uname -a
|
run: |
|
||||||
sudo pkg update
|
uname -a
|
||||||
sudo pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl egl opencl ocl-icd v4l_compat chafa lua54 libva libvdpau
|
freebsd-version
|
||||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
|
pkg -v
|
||||||
cmake --build . --target package --verbose -j4
|
|
||||||
./fastfetch --list-features
|
- name: Update and install dependencies
|
||||||
time ./fastfetch -c presets/ci.jsonc --stat false
|
run: |
|
||||||
time ./fastfetch -c presets/ci.jsonc --format json
|
sudo pkg update
|
||||||
time ./flashfetch
|
sudo pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3 egl opencl ocl-icd v4l_compat chafa lua54 libva libvdpau
|
||||||
ldd fastfetch
|
|
||||||
ctest --output-on-failure
|
- name: CMake configuration
|
||||||
|
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_BUILD_TYPE=${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }} .
|
||||||
|
|
||||||
|
- name: CMake build
|
||||||
|
run: cmake --build . --target package --verbose -j4
|
||||||
|
|
||||||
|
- name: List features
|
||||||
|
run: ./fastfetch --list-features
|
||||||
|
|
||||||
|
- name: Run normal
|
||||||
|
run: time ./fastfetch -c presets/ci.jsonc --stat false
|
||||||
|
|
||||||
|
- name: Run json
|
||||||
|
run: time ./fastfetch -c presets/ci.jsonc --format json
|
||||||
|
|
||||||
|
- name: Run flashfetch
|
||||||
|
run: time ./flashfetch
|
||||||
|
|
||||||
|
- name: Run ldd
|
||||||
|
run: ldd fastfetch
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: ctest --output-on-failure
|
||||||
|
|
||||||
- name: upload artifacts
|
- name: upload artifacts
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: fastfetch-freebsd-amd64
|
name: fastfetch-freebsd-amd64
|
||||||
path: ./fastfetch-*.*
|
path: ./fastfetch-*.*
|
||||||
|
|||||||
@@ -3,38 +3,58 @@ name: Reusable Haiku amd64
|
|||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
|
|
||||||
env:
|
permissions:
|
||||||
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: cpa.sh {0}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: checkout repository
|
- name: checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
- name: run VM
|
- name: Start VM
|
||||||
uses: cross-platform-actions/action@master
|
uses: cross-platform-actions/action@5ea7e8e4677bd726033a10b094ba1c5762b15dee # v1.3.0
|
||||||
with:
|
with:
|
||||||
operating_system: haiku
|
operating_system: haiku
|
||||||
version: 'r1beta5'
|
version: 'r1beta5'
|
||||||
architecture: x86-64
|
|
||||||
cpu_count: 4
|
|
||||||
shell: bash
|
shell: bash
|
||||||
environment_variables: 'CMAKE_BUILD_TYPE'
|
cpu_count: 4
|
||||||
run: |
|
|
||||||
uname -a
|
- name: Show system info
|
||||||
pkgman install -y git dbus_devel mesa_devel libelf_devel imagemagick_devel opencl_headers ocl_icd_devel vulkan_devel zlib_devel chafa_devel cmake gcc make pkgconfig python3.10 || pkgman install -y git dbus_devel mesa_devel libelf_devel imagemagick_devel opencl_headers ocl_icd_devel vulkan_devel zlib_devel chafa_devel cmake gcc make pkgconfig python3.10 lua
|
run: uname -a
|
||||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
|
|
||||||
cmake --build . --target package --verbose -j4
|
- name: Install dependencies
|
||||||
./fastfetch --list-features
|
shell: cpa.sh {0} --reboot
|
||||||
time ./fastfetch -c presets/ci.jsonc --stat false
|
run: pkgman install -y git dbus_devel mesa_devel libelf_devel imagemagick_devel opencl_headers ocl_icd_devel vulkan_devel zlib_devel chafa_devel cmake llvm22_clang ninja pkgconfig python3.10 lua || pkgman install -y git dbus_devel mesa_devel libelf_devel imagemagick_devel opencl_headers ocl_icd_devel vulkan_devel zlib_devel chafa_devel cmake llvm22_clang ninja pkgconfig python3.10 lua
|
||||||
time ./fastfetch -c presets/ci.jsonc --format json
|
|
||||||
time ./flashfetch
|
- name: CMake configuration
|
||||||
ctest --output-on-failure
|
run: CC=clang CXX=clang++ cmake -GNinja -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_BUILD_TYPE=${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }} .
|
||||||
|
|
||||||
|
- name: CMake build
|
||||||
|
run: cmake --build . --target package --verbose -j4
|
||||||
|
|
||||||
|
- name: List features
|
||||||
|
run: ./fastfetch --list-features
|
||||||
|
|
||||||
|
- name: Run normal
|
||||||
|
run: time ./fastfetch -c presets/ci.jsonc --stat false
|
||||||
|
|
||||||
|
- name: Run json
|
||||||
|
run: time ./fastfetch -c presets/ci.jsonc --format json
|
||||||
|
|
||||||
|
- name: Run flashfetch
|
||||||
|
run: time ./flashfetch
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: ctest --output-on-failure
|
||||||
|
|
||||||
- name: upload artifacts
|
- name: upload artifacts
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: fastfetch-haiku-amd64
|
name: fastfetch-haiku-amd64
|
||||||
path: ./fastfetch-*.*
|
path: ./fastfetch-*.*
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
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 libefl-all-dev liblua5.4-dev libvdpau-dev libva-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-*.*
|
|
||||||
@@ -3,6 +3,9 @@ name: Reusable Linux armv7l
|
|||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
env:
|
env:
|
||||||
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
|
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
|
||||||
|
|
||||||
@@ -11,10 +14,10 @@ jobs:
|
|||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
steps:
|
steps:
|
||||||
- name: checkout repository
|
- name: checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
- name: run VM
|
- name: run VM
|
||||||
uses: uraimo/run-on-arch-action@v3
|
uses: uraimo/run-on-arch-action@f9b26e3a1a408d5fd530d20c17b9f3f4428ff8d9 # v3.1.0
|
||||||
id: runcmd
|
id: runcmd
|
||||||
with:
|
with:
|
||||||
arch: armv7
|
arch: armv7
|
||||||
@@ -38,7 +41,7 @@ jobs:
|
|||||||
ctest --output-on-failure
|
ctest --output-on-failure
|
||||||
|
|
||||||
- name: upload artifacts
|
- name: upload artifacts
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: fastfetch-linux-armv7l
|
name: fastfetch-linux-armv7l
|
||||||
path: ./fastfetch-*.*
|
path: ./fastfetch-*.*
|
||||||
|
|||||||
@@ -14,6 +14,10 @@ on:
|
|||||||
description: fastfetch version from linux host build
|
description: fastfetch version from linux host build
|
||||||
value: ${{ jobs.build.outputs.ffversion }}
|
value: ${{ jobs.build.outputs.ffversion }}
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
security-events: write
|
||||||
|
contents: read
|
||||||
|
|
||||||
env:
|
env:
|
||||||
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
|
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
|
||||||
|
|
||||||
@@ -24,7 +28,7 @@ jobs:
|
|||||||
ffversion: ${{ steps.ffversion.outputs.ffversion }}
|
ffversion: ${{ steps.ffversion.outputs.ffversion }}
|
||||||
steps:
|
steps:
|
||||||
- name: checkout repository
|
- name: checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
- name: uname -a
|
- name: uname -a
|
||||||
run: uname -a
|
run: uname -a
|
||||||
@@ -48,7 +52,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
if: inputs.arch == 'amd64'
|
if: inputs.arch == 'amd64'
|
||||||
uses: github/codeql-action/init@v4
|
uses: github/codeql-action/init@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6
|
||||||
with:
|
with:
|
||||||
languages: c
|
languages: c
|
||||||
|
|
||||||
@@ -60,7 +64,7 @@ jobs:
|
|||||||
|
|
||||||
- name: perform CodeQL analysis
|
- name: perform CodeQL analysis
|
||||||
if: inputs.arch == 'amd64'
|
if: inputs.arch == 'amd64'
|
||||||
uses: github/codeql-action/analyze@v4
|
uses: github/codeql-action/analyze@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6
|
||||||
|
|
||||||
- name: list features
|
- name: list features
|
||||||
run: ./fastfetch --list-features
|
run: ./fastfetch --list-features
|
||||||
@@ -97,7 +101,7 @@ jobs:
|
|||||||
cpack -V
|
cpack -V
|
||||||
|
|
||||||
- name: upload artifacts
|
- name: upload artifacts
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: fastfetch-linux-${{ inputs.arch }}
|
name: fastfetch-linux-${{ inputs.arch }}
|
||||||
path: ./fastfetch-*.*
|
path: ./fastfetch-*.*
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ name: Reusable Linux i686
|
|||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
env:
|
env:
|
||||||
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
|
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
|
||||||
|
|
||||||
@@ -11,7 +14,7 @@ jobs:
|
|||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- name: checkout repository
|
- name: checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
- name: uname -a
|
- name: uname -a
|
||||||
run: uname -a
|
run: uname -a
|
||||||
@@ -64,7 +67,7 @@ jobs:
|
|||||||
run: ctest --output-on-failure
|
run: ctest --output-on-failure
|
||||||
|
|
||||||
- name: upload artifacts
|
- name: upload artifacts
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: fastfetch-linux-i686
|
name: fastfetch-linux-i686
|
||||||
path: ./fastfetch-*.*
|
path: ./fastfetch-*.*
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
name: Reusable Linux loong64
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
env:
|
||||||
|
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
steps:
|
||||||
|
- name: checkout repository
|
||||||
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
|
- name: set up QEMU for loong64
|
||||||
|
uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4.2.0
|
||||||
|
|
||||||
|
- name: build in loong64 container
|
||||||
|
run: |
|
||||||
|
docker run --rm --platform linux/loong64 \
|
||||||
|
-v ${{ github.workspace }}:/workspace \
|
||||||
|
-w /workspace \
|
||||||
|
lcr.loongnix.cn/debian:14 \
|
||||||
|
bash -c '
|
||||||
|
set -e
|
||||||
|
uname -a
|
||||||
|
cat /etc/os-release || true
|
||||||
|
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
cmake make gcc g++ \
|
||||||
|
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 libefl-all-dev \
|
||||||
|
liblua5.4-dev \
|
||||||
|
libvdpau-dev libva-dev \
|
||||||
|
rpm
|
||||||
|
|
||||||
|
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||||
|
cmake --build . --target package --verbose -j$(nproc)
|
||||||
|
./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@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
|
with:
|
||||||
|
name: fastfetch-linux-loong64
|
||||||
|
path: ./fastfetch-*.*
|
||||||
@@ -7,6 +7,9 @@ on:
|
|||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
env:
|
env:
|
||||||
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
|
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
|
||||||
|
|
||||||
@@ -15,10 +18,10 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: checkout repository
|
- name: checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
- name: run VM
|
- name: run VM
|
||||||
uses: uraimo/run-on-arch-action@v3
|
uses: uraimo/run-on-arch-action@f9b26e3a1a408d5fd530d20c17b9f3f4428ff8d9 # v3.1.0
|
||||||
id: runcmd
|
id: runcmd
|
||||||
with:
|
with:
|
||||||
arch: ${{ inputs.arch }}
|
arch: ${{ inputs.arch }}
|
||||||
@@ -39,7 +42,7 @@ jobs:
|
|||||||
ctest --output-on-failure
|
ctest --output-on-failure
|
||||||
|
|
||||||
- name: upload artifacts
|
- name: upload artifacts
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: fastfetch-linux-${{ inputs.arch }}
|
name: fastfetch-linux-${{ inputs.arch }}
|
||||||
path: ./fastfetch-*.*
|
path: ./fastfetch-*.*
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ on:
|
|||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
env:
|
env:
|
||||||
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
|
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
|
||||||
|
|
||||||
@@ -18,7 +21,7 @@ jobs:
|
|||||||
runs-on: ${{ inputs.runs-on }}
|
runs-on: ${{ inputs.runs-on }}
|
||||||
steps:
|
steps:
|
||||||
- name: checkout repository
|
- name: checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
- name: uname -a
|
- name: uname -a
|
||||||
run: uname -a
|
run: uname -a
|
||||||
@@ -53,7 +56,7 @@ jobs:
|
|||||||
run: ctest --output-on-failure
|
run: ctest --output-on-failure
|
||||||
|
|
||||||
- name: upload artifacts
|
- name: upload artifacts
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: fastfetch-macos-${{ inputs.arch }}
|
name: fastfetch-macos-${{ inputs.arch }}
|
||||||
path: ./fastfetch-*.*
|
path: ./fastfetch-*.*
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ name: Reusable Musl amd64
|
|||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
env:
|
env:
|
||||||
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
|
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
|
||||||
|
|
||||||
@@ -10,10 +13,10 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
- name: setup alpine linux
|
- name: setup alpine linux
|
||||||
uses: jirutka/setup-alpine@master
|
uses: jirutka/setup-alpine@ae3b3ddba35054804fc4a3507b519fa7e8152050 # v1.4.1
|
||||||
with:
|
with:
|
||||||
branch: edge
|
branch: edge
|
||||||
|
|
||||||
@@ -41,7 +44,7 @@ jobs:
|
|||||||
shell: alpine.sh {0}
|
shell: alpine.sh {0}
|
||||||
|
|
||||||
- name: upload artifacts
|
- name: upload artifacts
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: fastfetch-musl-amd64
|
name: fastfetch-musl-amd64
|
||||||
path: ./fastfetch-*.*
|
path: ./fastfetch-*.*
|
||||||
|
|||||||
@@ -3,39 +3,63 @@ name: Reusable NetBSD amd64
|
|||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
|
|
||||||
env:
|
permissions:
|
||||||
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: cpa.sh {0}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: checkout repository
|
- name: checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
- name: run VM
|
- name: Start VM
|
||||||
uses: cross-platform-actions/action@master
|
uses: cross-platform-actions/action@5ea7e8e4677bd726033a10b094ba1c5762b15dee # v1.3.0
|
||||||
with:
|
with:
|
||||||
operating_system: netbsd
|
operating_system: netbsd
|
||||||
architecture: x86-64
|
|
||||||
cpu_count: 4
|
|
||||||
shell: bash
|
|
||||||
version: '10.1'
|
version: '10.1'
|
||||||
environment_variables: 'CMAKE_BUILD_TYPE'
|
shell: bash
|
||||||
run: |
|
cpu_count: 4
|
||||||
uname -a
|
|
||||||
sudo pkgin -y install clang cmake git pkgconf wayland vulkan-headers dconf dbus sqlite3 ImageMagick libva libvdpau
|
- name: Show system info
|
||||||
CC=clang cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
|
run: |
|
||||||
cmake --build . --target package --verbose -j4
|
uname -a
|
||||||
./fastfetch --list-features
|
pkgin -v
|
||||||
time ./fastfetch -c presets/ci.jsonc --stat false
|
|
||||||
time ./fastfetch -c presets/ci.jsonc --format json
|
- name: Update and install dependencies
|
||||||
time ./flashfetch
|
run: |
|
||||||
ldd fastfetch
|
sudo pkgin -y install clang cmake git pkgconf wayland vulkan-headers dconf dbus sqlite3 ImageMagick libva libvdpau
|
||||||
ctest --output-on-failure
|
|
||||||
|
- name: CMake configuration
|
||||||
|
run: CC=clang cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_BUILD_TYPE=${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }} .
|
||||||
|
|
||||||
|
- name: CMake build
|
||||||
|
run: cmake --build . --target package --verbose -j4
|
||||||
|
|
||||||
|
- name: List features
|
||||||
|
run: ./fastfetch --list-features
|
||||||
|
|
||||||
|
- name: Run normal
|
||||||
|
run: time ./fastfetch -c presets/ci.jsonc --stat false
|
||||||
|
|
||||||
|
- name: Run json
|
||||||
|
run: time ./fastfetch -c presets/ci.jsonc --format json
|
||||||
|
|
||||||
|
- name: Run flashfetch
|
||||||
|
run: time ./flashfetch
|
||||||
|
|
||||||
|
- name: Run ldd
|
||||||
|
run: ldd fastfetch
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: ctest --output-on-failure
|
||||||
|
|
||||||
- name: upload artifacts
|
- name: upload artifacts
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: fastfetch-netbsd-amd64
|
name: fastfetch-netbsd-amd64
|
||||||
path: ./fastfetch-*.*
|
path: ./fastfetch-*.*
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ name: Reusable No Features Test
|
|||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
env:
|
env:
|
||||||
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
|
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
|
||||||
|
|
||||||
@@ -12,7 +15,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: checkout repository
|
- name: checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
- name: uname -a
|
- name: uname -a
|
||||||
run: uname -a
|
run: uname -a
|
||||||
|
|||||||
@@ -3,40 +3,68 @@ name: Reusable OmniOS amd64
|
|||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
|
|
||||||
env:
|
permissions:
|
||||||
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: cpa.sh {0}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: checkout repository
|
- name: checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
- name: run VM
|
- name: Start VM
|
||||||
uses: vmactions/omnios-vm@v1
|
uses: cross-platform-actions/action@5ea7e8e4677bd726033a10b094ba1c5762b15dee # v1.3.0
|
||||||
with:
|
with:
|
||||||
usesh: true
|
operating_system: omnios
|
||||||
envs: 'CMAKE_BUILD_TYPE'
|
version: 'r151058'
|
||||||
prepare: |
|
shell: bash
|
||||||
uname -a
|
cpu_count: 4
|
||||||
pkg update --accept || true
|
|
||||||
pkg install gcc14 cmake git pkg-config glib2 dbus sqlite-3 imagemagick ninja
|
|
||||||
|
|
||||||
run: |
|
- name: Show system info
|
||||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -GNinja .
|
run: |
|
||||||
cmake --build . --verbose -j4
|
uname -a
|
||||||
./fastfetch --list-features
|
|
||||||
time ./fastfetch -c presets/ci.jsonc --stat false
|
- name: Update and install dependencies
|
||||||
time ./fastfetch -c presets/ci.jsonc --format json
|
run: |
|
||||||
time ./flashfetch
|
sudo pkg update --accept || true
|
||||||
ldd fastfetch
|
sudo pkg install gcc14 cmake git pkg-config glib2 dbus sqlite-3 imagemagick ninja
|
||||||
ctest --output-on-failure
|
|
||||||
echo 'set(CPACK_PACKAGE_FILE_NAME "fastfetch-omnios-amd64")' >> CPackConfig.cmake
|
- name: CMake configuration
|
||||||
cpack -V
|
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -GNinja -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_BUILD_TYPE=${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }} .
|
||||||
|
|
||||||
|
- name: CMake build
|
||||||
|
run: cmake --build . --verbose -j4
|
||||||
|
|
||||||
|
- name: List features
|
||||||
|
run: ./fastfetch --list-features
|
||||||
|
|
||||||
|
- name: Run normal
|
||||||
|
run: time ./fastfetch -c presets/ci.jsonc --stat false
|
||||||
|
|
||||||
|
- name: Run json
|
||||||
|
run: time ./fastfetch -c presets/ci.jsonc --format json
|
||||||
|
|
||||||
|
- name: Run flashfetch
|
||||||
|
run: time ./flashfetch
|
||||||
|
|
||||||
|
- name: Run ldd
|
||||||
|
run: ldd fastfetch
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: ctest --output-on-failure
|
||||||
|
|
||||||
|
- name: Package
|
||||||
|
run: |
|
||||||
|
echo 'set(CPACK_PACKAGE_FILE_NAME "fastfetch-omnios-amd64")' >> CPackConfig.cmake
|
||||||
|
cpack -V
|
||||||
|
|
||||||
- name: upload artifacts
|
- name: upload artifacts
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: fastfetch-omnios-amd64
|
name: fastfetch-omnios-amd64
|
||||||
path: ./fastfetch-*.*
|
path: ./fastfetch-*.*
|
||||||
|
|||||||
@@ -3,40 +3,63 @@ name: Reusable OpenBSD amd64
|
|||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
|
|
||||||
env:
|
permissions:
|
||||||
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: cpa.sh {0}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: checkout repository
|
- name: checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
- name: run VM
|
- name: Start VM
|
||||||
uses: cross-platform-actions/action@master
|
uses: cross-platform-actions/action@5ea7e8e4677bd726033a10b094ba1c5762b15dee # v1.3.0
|
||||||
with:
|
with:
|
||||||
operating_system: openbsd
|
operating_system: openbsd
|
||||||
architecture: x86-64
|
|
||||||
cpu_count: 4
|
|
||||||
shell: bash
|
|
||||||
version: '7.9'
|
version: '7.9'
|
||||||
environment_variables: 'CMAKE_BUILD_TYPE'
|
shell: bash
|
||||||
run: |
|
cpu_count: 4
|
||||||
uname -a
|
|
||||||
sudo pkg_add -u
|
- name: Show system info
|
||||||
sudo pkg_add -r llvm-21.1.8p4 cmake git wayland vulkan-headers vulkan-loader glib2 dconf dbus sqlite3 imagemagick chafa lua-5.4.8p0 # pkg-config is preinstalled
|
run: |
|
||||||
CC=clang-21 cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
|
uname -a
|
||||||
cmake --build . --target package --verbose -j4
|
|
||||||
./fastfetch --list-features
|
- name: Update and install dependencies
|
||||||
time ./fastfetch -c presets/ci.jsonc --stat false
|
run: |
|
||||||
time ./fastfetch -c presets/ci.jsonc --format json
|
sudo pkg_add -u
|
||||||
time ./flashfetch
|
sudo pkg_add -r llvm-21.1.8p4 cmake git wayland vulkan-headers vulkan-loader glib2 dconf dbus sqlite3 imagemagick chafa lua-5.4.8p0 # pkg-config is preinstalled
|
||||||
ldd fastfetch
|
|
||||||
ctest --output-on-failure
|
- name: CMake configuration
|
||||||
|
run: CC=clang-21 cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_BUILD_TYPE=${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }} .
|
||||||
|
|
||||||
|
- name: CMake build
|
||||||
|
run: cmake --build . --target package --verbose -j4
|
||||||
|
|
||||||
|
- name: List features
|
||||||
|
run: ./fastfetch --list-features
|
||||||
|
|
||||||
|
- name: Run normal
|
||||||
|
run: time ./fastfetch -c presets/ci.jsonc --stat false
|
||||||
|
|
||||||
|
- name: Run json
|
||||||
|
run: time ./fastfetch -c presets/ci.jsonc --format json
|
||||||
|
|
||||||
|
- name: Run flashfetch
|
||||||
|
run: time ./flashfetch
|
||||||
|
|
||||||
|
- name: Run ldd
|
||||||
|
run: ldd fastfetch
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: ctest --output-on-failure
|
||||||
|
|
||||||
- name: upload artifacts
|
- name: upload artifacts
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: fastfetch-openbsd-amd64
|
name: fastfetch-openbsd-amd64
|
||||||
path: ./fastfetch-*.*
|
path: ./fastfetch-*.*
|
||||||
|
|||||||
@@ -7,23 +7,26 @@ on:
|
|||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release:
|
release:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: get latest release version
|
- name: get latest release version
|
||||||
id: get_version_release
|
id: get_version_release
|
||||||
uses: pozetroninc/github-action-get-latest-release@master
|
uses: pozetroninc/github-action-get-latest-release@2a61c339ea7ef0a336d1daa35ef0cb1418e7676c # v0.8.0
|
||||||
with:
|
with:
|
||||||
repository: ${{ github.repository }}
|
repository: ${{ github.repository }}
|
||||||
|
|
||||||
- name: download artifacts
|
- name: download artifacts
|
||||||
if: inputs.ffversion != steps.get_version_release.outputs.release
|
if: inputs.ffversion != steps.get_version_release.outputs.release
|
||||||
uses: actions/download-artifact@v8
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||||
|
|
||||||
- name: create release
|
- name: create release
|
||||||
if: inputs.ffversion != steps.get_version_release.outputs.release
|
if: inputs.ffversion != steps.get_version_release.outputs.release
|
||||||
uses: ncipollo/release-action@v1
|
uses: ncipollo/release-action@339a81892b84b4eeb0f6e744e4574d79d0d9b8dd # v1.21.0
|
||||||
with:
|
with:
|
||||||
tag: ${{ inputs.ffversion }}
|
tag: ${{ inputs.ffversion }}
|
||||||
commit: ${{ github.sha }}
|
commit: ${{ github.sha }}
|
||||||
@@ -50,7 +53,7 @@ jobs:
|
|||||||
|
|
||||||
- name: update release body
|
- name: update release body
|
||||||
if: inputs.ffversion != steps.get_version_release.outputs.release
|
if: inputs.ffversion != steps.get_version_release.outputs.release
|
||||||
uses: ncipollo/release-action@v1
|
uses: ncipollo/release-action@339a81892b84b4eeb0f6e744e4574d79d0d9b8dd # v1.21.0
|
||||||
with:
|
with:
|
||||||
tag: ${{ inputs.ffversion }}
|
tag: ${{ inputs.ffversion }}
|
||||||
commit: ${{ github.sha }}
|
commit: ${{ github.sha }}
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ name: Reusable Solaris amd64
|
|||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
env:
|
env:
|
||||||
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
|
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
|
||||||
|
|
||||||
@@ -11,10 +14,10 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: checkout repository
|
- name: checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
- name: run VM
|
- name: run VM
|
||||||
uses: vmactions/solaris-vm@v1
|
uses: vmactions/solaris-vm@315163f088b66e55bbcc45928bd224d4973b2312 # v1.3.8
|
||||||
with:
|
with:
|
||||||
usesh: true
|
usesh: true
|
||||||
envs: 'CMAKE_BUILD_TYPE'
|
envs: 'CMAKE_BUILD_TYPE'
|
||||||
@@ -37,7 +40,7 @@ jobs:
|
|||||||
cpack -V
|
cpack -V
|
||||||
|
|
||||||
- name: upload artifacts
|
- name: upload artifacts
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: fastfetch-solaris-amd64
|
name: fastfetch-solaris-amd64
|
||||||
path: ./fastfetch-*.*
|
path: ./fastfetch-*.*
|
||||||
|
|||||||
@@ -3,13 +3,16 @@ name: Reusable Spellcheck
|
|||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
spellcheck:
|
spellcheck:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: checkout repository
|
- name: checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
- name: Install codespell
|
- name: Install codespell
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|||||||
@@ -18,6 +18,18 @@ on:
|
|||||||
msys-arch:
|
msys-arch:
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
secrets:
|
||||||
|
SIGNPATH_API_TOKEN:
|
||||||
|
description: SignPath REST API token used to submit the signing request
|
||||||
|
# Optional so that runs without the secret (pull requests, forks)
|
||||||
|
# still work; the signing step is skipped there anyway.
|
||||||
|
required: false
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
# The SignPath action reads job details and downloads the unsigned
|
||||||
|
# artifact with the workflow token.
|
||||||
|
actions: read
|
||||||
|
|
||||||
env:
|
env:
|
||||||
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
|
CMAKE_BUILD_TYPE: ${{ vars.CMAKE_BUILD_TYPE || 'RelWithDebInfo' }}
|
||||||
@@ -30,10 +42,10 @@ jobs:
|
|||||||
shell: msys2 {0}
|
shell: msys2 {0}
|
||||||
steps:
|
steps:
|
||||||
- name: checkout repository
|
- name: checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
- name: setup-msys2
|
- name: setup-msys2
|
||||||
uses: msys2/setup-msys2@v2
|
uses: msys2/setup-msys2@66cd2cce69caa17b53920067426061ca1de3a884 # v2.32.0
|
||||||
with:
|
with:
|
||||||
msystem: ${{ inputs.msystem }}
|
msystem: ${{ inputs.msystem }}
|
||||||
update: true
|
update: true
|
||||||
@@ -72,7 +84,7 @@ jobs:
|
|||||||
- if: github.event_name == 'push' && github.repository == 'fastfetch-cli/fastfetch'
|
- if: github.event_name == 'push' && github.repository == 'fastfetch-cli/fastfetch'
|
||||||
id: upload-unsigned-artifact
|
id: upload-unsigned-artifact
|
||||||
name: upload artifacts for signing
|
name: upload artifacts for signing
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: fastfetch-windows-${{ inputs.arch }}
|
name: fastfetch-windows-${{ inputs.arch }}
|
||||||
path: |
|
path: |
|
||||||
@@ -82,7 +94,7 @@ jobs:
|
|||||||
|
|
||||||
- if: github.event_name == 'push' && github.repository == 'fastfetch-cli/fastfetch'
|
- if: github.event_name == 'push' && github.repository == 'fastfetch-cli/fastfetch'
|
||||||
name: submit signing request
|
name: submit signing request
|
||||||
uses: signpath/github-action-submit-signing-request@v1
|
uses: signpath/github-action-submit-signing-request@b9d91eadd323de506c0c81cf0c7fe7438f3360fd # v2.2
|
||||||
with:
|
with:
|
||||||
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
|
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
|
||||||
organization-id: '${{ vars.SIGNPATH_ORG_ID }}'
|
organization-id: '${{ vars.SIGNPATH_ORG_ID }}'
|
||||||
@@ -99,7 +111,7 @@ jobs:
|
|||||||
run: 7z a -t7z -mx9 -bd -y fastfetch-windows-${{ inputs.arch }}.7z LICENSE *.dll fastfetch.exe flashfetch.exe presets
|
run: 7z a -t7z -mx9 -bd -y fastfetch-windows-${{ inputs.arch }}.7z LICENSE *.dll fastfetch.exe flashfetch.exe presets
|
||||||
|
|
||||||
- name: upload true artifacts
|
- name: upload true artifacts
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: fastfetch-windows-${{ inputs.arch }}
|
name: fastfetch-windows-${{ inputs.arch }}
|
||||||
path: ./fastfetch-windows-${{ inputs.arch }}.*
|
path: ./fastfetch-windows-${{ inputs.arch }}.*
|
||||||
|
|||||||
+19
-34
@@ -6,16 +6,16 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
spellcheck:
|
spellcheck:
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
uses: ./.github/workflows/build-spellcheck.yml
|
uses: ./.github/workflows/build-spellcheck.yml
|
||||||
|
|
||||||
no-features-test:
|
no-features-test:
|
||||||
needs: spellcheck
|
needs: spellcheck
|
||||||
name: No-features-test
|
name: No-features-test
|
||||||
permissions:
|
permissions:
|
||||||
security-events: write
|
|
||||||
contents: read
|
contents: read
|
||||||
uses: ./.github/workflows/build-no-features-test.yml
|
uses: ./.github/workflows/build-no-features-test.yml
|
||||||
secrets: inherit
|
|
||||||
|
|
||||||
linux-hosts:
|
linux-hosts:
|
||||||
needs: no-features-test
|
needs: no-features-test
|
||||||
@@ -34,40 +34,32 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
arch: ${{ matrix.arch }}
|
arch: ${{ matrix.arch }}
|
||||||
runs-on: ${{ matrix.runs-on }}
|
runs-on: ${{ matrix.runs-on }}
|
||||||
secrets: inherit
|
|
||||||
|
|
||||||
linux-i686:
|
linux-i686:
|
||||||
needs: no-features-test
|
needs: no-features-test
|
||||||
name: Linux-i686
|
name: Linux-i686
|
||||||
permissions:
|
permissions:
|
||||||
security-events: write
|
|
||||||
contents: read
|
contents: read
|
||||||
uses: ./.github/workflows/build-linux-i686.yml
|
uses: ./.github/workflows/build-linux-i686.yml
|
||||||
secrets: inherit
|
|
||||||
|
|
||||||
linux-armv7l:
|
linux-armv7l:
|
||||||
needs: no-features-test
|
needs: no-features-test
|
||||||
name: Linux-armv7l
|
name: Linux-armv7l
|
||||||
permissions:
|
permissions:
|
||||||
security-events: write
|
|
||||||
contents: read
|
contents: read
|
||||||
uses: ./.github/workflows/build-linux-armv7l.yml
|
uses: ./.github/workflows/build-linux-armv7l.yml
|
||||||
secrets: inherit
|
|
||||||
|
|
||||||
linux-armv6l:
|
linux-loong64:
|
||||||
needs: no-features-test
|
needs: no-features-test
|
||||||
name: Linux-armv6l
|
name: Linux-loong64
|
||||||
permissions:
|
permissions:
|
||||||
security-events: write
|
|
||||||
contents: read
|
contents: read
|
||||||
uses: ./.github/workflows/build-linux-armv6l.yml
|
uses: ./.github/workflows/build-linux-loong64.yml
|
||||||
secrets: inherit
|
|
||||||
|
|
||||||
linux-vms:
|
linux-vms:
|
||||||
needs: no-features-test
|
needs: no-features-test
|
||||||
name: Linux-${{ matrix.arch }}
|
name: Linux-${{ matrix.arch }}
|
||||||
permissions:
|
permissions:
|
||||||
security-events: write
|
|
||||||
contents: read
|
contents: read
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
@@ -78,19 +70,18 @@ jobs:
|
|||||||
uses: ./.github/workflows/build-linux-vms.yml
|
uses: ./.github/workflows/build-linux-vms.yml
|
||||||
with:
|
with:
|
||||||
arch: ${{ matrix.arch }}
|
arch: ${{ matrix.arch }}
|
||||||
secrets: inherit
|
|
||||||
|
|
||||||
musl-amd64:
|
musl-amd64:
|
||||||
needs: no-features-test
|
needs: no-features-test
|
||||||
name: Musl-amd64
|
name: Musl-amd64
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
uses: ./.github/workflows/build-musl-amd64.yml
|
uses: ./.github/workflows/build-musl-amd64.yml
|
||||||
secrets: inherit
|
|
||||||
|
|
||||||
macos-hosts:
|
macos-hosts:
|
||||||
needs: no-features-test
|
needs: no-features-test
|
||||||
name: macOS-${{ matrix.arch }}
|
name: macOS-${{ matrix.arch }}
|
||||||
permissions:
|
permissions:
|
||||||
security-events: write
|
|
||||||
contents: read
|
contents: read
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
@@ -103,71 +94,65 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
arch: ${{ matrix.arch }}
|
arch: ${{ matrix.arch }}
|
||||||
runs-on: ${{ matrix.runs-on }}
|
runs-on: ${{ matrix.runs-on }}
|
||||||
secrets: inherit
|
|
||||||
|
|
||||||
omnios-amd64:
|
omnios-amd64:
|
||||||
needs: no-features-test
|
needs: no-features-test
|
||||||
name: OmniOS-amd64
|
name: OmniOS-amd64
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
uses: ./.github/workflows/build-omnios-amd64.yml
|
uses: ./.github/workflows/build-omnios-amd64.yml
|
||||||
secrets: inherit
|
|
||||||
|
|
||||||
solaris-amd64:
|
solaris-amd64:
|
||||||
needs: no-features-test
|
needs: no-features-test
|
||||||
name: Solaris-amd64
|
name: Solaris-amd64
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
uses: ./.github/workflows/build-solaris-amd64.yml
|
uses: ./.github/workflows/build-solaris-amd64.yml
|
||||||
secrets: inherit
|
|
||||||
|
|
||||||
freebsd-amd64:
|
freebsd-amd64:
|
||||||
needs: no-features-test
|
needs: no-features-test
|
||||||
name: FreeBSD-amd64
|
name: FreeBSD-amd64
|
||||||
permissions:
|
permissions:
|
||||||
security-events: write
|
|
||||||
contents: read
|
contents: read
|
||||||
uses: ./.github/workflows/build-freebsd-amd64.yml
|
uses: ./.github/workflows/build-freebsd-amd64.yml
|
||||||
secrets: inherit
|
|
||||||
|
|
||||||
openbsd-amd64:
|
openbsd-amd64:
|
||||||
needs: no-features-test
|
needs: no-features-test
|
||||||
name: OpenBSD-amd64
|
name: OpenBSD-amd64
|
||||||
permissions:
|
permissions:
|
||||||
security-events: write
|
|
||||||
contents: read
|
contents: read
|
||||||
uses: ./.github/workflows/build-openbsd-amd64.yml
|
uses: ./.github/workflows/build-openbsd-amd64.yml
|
||||||
secrets: inherit
|
|
||||||
|
|
||||||
netbsd-amd64:
|
netbsd-amd64:
|
||||||
needs: no-features-test
|
needs: no-features-test
|
||||||
name: NetBSD-amd64
|
name: NetBSD-amd64
|
||||||
permissions:
|
permissions:
|
||||||
security-events: write
|
|
||||||
contents: read
|
contents: read
|
||||||
uses: ./.github/workflows/build-netbsd-amd64.yml
|
uses: ./.github/workflows/build-netbsd-amd64.yml
|
||||||
secrets: inherit
|
|
||||||
|
|
||||||
dragonfly-amd64:
|
dragonfly-amd64:
|
||||||
needs: no-features-test
|
needs: no-features-test
|
||||||
name: DragonFly-amd64
|
name: DragonFly-amd64
|
||||||
permissions:
|
permissions:
|
||||||
security-events: write
|
|
||||||
contents: read
|
contents: read
|
||||||
uses: ./.github/workflows/build-dragonfly-amd64.yml
|
uses: ./.github/workflows/build-dragonfly-amd64.yml
|
||||||
secrets: inherit
|
|
||||||
|
|
||||||
haiku-amd64:
|
haiku-amd64:
|
||||||
|
if: false # Disabled because the Haiku build is currently broken
|
||||||
needs: no-features-test
|
needs: no-features-test
|
||||||
name: Haiku-amd64
|
name: Haiku-amd64
|
||||||
permissions:
|
permissions:
|
||||||
security-events: write
|
|
||||||
contents: read
|
contents: read
|
||||||
uses: ./.github/workflows/build-haiku-amd64.yml
|
uses: ./.github/workflows/build-haiku-amd64.yml
|
||||||
secrets: inherit
|
|
||||||
|
|
||||||
windows-hosts:
|
windows-hosts:
|
||||||
needs: no-features-test
|
needs: no-features-test
|
||||||
name: Windows-${{ matrix.arch }}
|
name: Windows-${{ matrix.arch }}
|
||||||
permissions:
|
permissions:
|
||||||
security-events: write
|
|
||||||
contents: read
|
contents: read
|
||||||
|
# The SignPath action reads job details and downloads the unsigned
|
||||||
|
# artifact with the workflow token.
|
||||||
|
actions: read
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
@@ -188,7 +173,8 @@ jobs:
|
|||||||
msystem: ${{ matrix.msystem }}
|
msystem: ${{ matrix.msystem }}
|
||||||
msystem-lower: ${{ matrix.msystem-lower }}
|
msystem-lower: ${{ matrix.msystem-lower }}
|
||||||
msys-arch: ${{ matrix.msys-arch }}
|
msys-arch: ${{ matrix.msys-arch }}
|
||||||
secrets: inherit
|
secrets:
|
||||||
|
SIGNPATH_API_TOKEN: ${{ secrets.SIGNPATH_API_TOKEN }}
|
||||||
|
|
||||||
release:
|
release:
|
||||||
if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'fastfetch-cli/fastfetch'
|
if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'fastfetch-cli/fastfetch'
|
||||||
@@ -197,7 +183,7 @@ jobs:
|
|||||||
- linux-hosts
|
- linux-hosts
|
||||||
- linux-i686
|
- linux-i686
|
||||||
- linux-armv7l
|
- linux-armv7l
|
||||||
- linux-armv6l
|
- linux-loong64
|
||||||
- linux-vms
|
- linux-vms
|
||||||
- musl-amd64
|
- musl-amd64
|
||||||
- macos-hosts
|
- macos-hosts
|
||||||
@@ -207,11 +193,10 @@ jobs:
|
|||||||
- dragonfly-amd64
|
- dragonfly-amd64
|
||||||
- solaris-amd64
|
- solaris-amd64
|
||||||
- omnios-amd64
|
- omnios-amd64
|
||||||
- haiku-amd64
|
# - haiku-amd64
|
||||||
- windows-hosts
|
- windows-hosts
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
uses: ./.github/workflows/build-release.yml
|
uses: ./.github/workflows/build-release.yml
|
||||||
with:
|
with:
|
||||||
ffversion: ${{ needs.linux-hosts.outputs.ffversion }}
|
ffversion: ${{ needs.linux-hosts.outputs.ffversion }}
|
||||||
secrets: inherit
|
|
||||||
|
|||||||
@@ -1,3 +1,89 @@
|
|||||||
|
# 2.67.0
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
* The minimum supported compiler version has been raised to GCC 13 (released on 2023-04-26) and Clang 16 (released on 2023-03-17) to accommodate the new C23 syntax used throughout the codebase. (General)
|
||||||
|
* As a result, building from source in Debian 12 (which only ships GCC 12 by default) is no longer supported. Users must upgrade their compiler or use the prebuilt binaries from the GitHub releases page.
|
||||||
|
* The `general.preRun` option has been removed due to security concerns. (General)
|
||||||
|
* Users who relied on this option to run a command before printing output will need to move that logic to an external wrapper.
|
||||||
|
* The `{status}` placeholder in Battery custom format is now an array type instead of a single comma-separated string. (Battery)
|
||||||
|
* This is a breaking change for users who print `{status}` in Lua scripts. They can use `table.concat(...)` to join the array into a single string if needed.
|
||||||
|
* The `--gen-config-*` flags (`--gen-config-full`, `--gen-config-force`, `--gen-config-full-force`) have been removed and their functions have been merged into `--gen-config`. (Global)
|
||||||
|
* See features below.
|
||||||
|
|
||||||
|
Features:
|
||||||
|
* `--gen-config` now opens an interactive configuration TUI to make generating config files easier.
|
||||||
|
* It falls back to non-interactive generation when `$NO_COLOR` is set or when stdin/stdout is not a TTY. This behavior can also be used to disable the interactive mode.
|
||||||
|
* Added an experimental [WebUI](https://fastfetch-cli.github.io/fastfetch-config/) ([separate project](https://github.com/fastfetch-cli/fastfetch-config)) for generating and editing configs.
|
||||||
|
* Added `-w`/`--watch` as a seconds-based alias for `--dynamic-interval`, defaulting to 1 second when no value is provided. (#2478, Watch)
|
||||||
|
* Added InitSystem detection on Windows, reporting the first userland process (`smss.exe`). (InitSystem, Windows)
|
||||||
|
* Added CPU and GPU temperature detection support for Apple M5 series chips. (CPU / GPU, macOS)
|
||||||
|
* Reported `Basic` as the Windows theme when DWM is disabled. (Theme, Windows)
|
||||||
|
* Improved Ghostty terminal font detection performance. (#2122, TerminalFont)
|
||||||
|
* It now parses Ghostty directly instead of running `ghostty +show-config`.
|
||||||
|
* Added support for a wider range of TOML config syntaxes used by Alacritty. (#2456, TerminalFont)
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
* Fixed a potential fish version detection error. (Shell, Linux)
|
||||||
|
* Fixed incorrect resolution reporting when a monitor advertises multiple preferred modes. (#2481, Display, Linux)
|
||||||
|
* Fixed connected monitors being missed when Wayland output events arrive late. (#2451, Display, Linux)
|
||||||
|
* Fixed VP9 codec detection on macOS. (Codec, macOS)
|
||||||
|
* Corrected Base64 encoding on big-endian hosts. (#2470)
|
||||||
|
* Fixed invalid URL parsing in the PublicIP module. (PublicIP)
|
||||||
|
* Correctly reported virtual GPUs on Windows. (#2461, GPU, Windows)
|
||||||
|
* Added a size limit for network responses to prevent excessive memory usage and mitigate potential attacks. (PublicIP / Weather)
|
||||||
|
* Fixed Ubuntu Studio Core detection (OS, Linux)
|
||||||
|
* Relaxed the HTTP response check so that both `HTTP/1.0` and `HTTP/1.1` responses are accepted when fetching data over the network. (PublicIP / Weather)
|
||||||
|
* Various internal cleanups and optimizations:
|
||||||
|
* Fixed multiple memory leaks (Separator, Camera, Codec, Display)
|
||||||
|
* Added integer overflow checks to the string buffer implementation
|
||||||
|
* Various code cleanups and compiler warning fixes
|
||||||
|
|
||||||
|
Logos:
|
||||||
|
* Removed Hypros, MagpieOS, Furreto, EmperorOS and Magix
|
||||||
|
|
||||||
|
# 2.66.0
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
* CPU package count is no longer reported in the default output.
|
||||||
|
* Users can still print it in custom formats via `{packages}`
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
* Fixed compatibility with WSL 2.9.3 (#2433, WM, Linux)
|
||||||
|
* Fixed accurate AMD GPU names are not queried in `driverSpecific` mode (GPU, Linux)
|
||||||
|
* Fixed GPU core counting for Apple Silicon GPU on Asahi Linux (GPU, Linux)
|
||||||
|
* Some internal cleanups and optimizations
|
||||||
|
|
||||||
|
Features:
|
||||||
|
* Added Astra Linux version detection (OS, Linux)
|
||||||
|
* Improved performance of Windows PowerShell version detection (Shell, Windows)
|
||||||
|
* Improved performance of Media module on macOS (Media, macOS)
|
||||||
|
* Added proxmox backup server detection (#2443, OS, Linux)
|
||||||
|
|
||||||
|
Logos:
|
||||||
|
* Added Flatcar, Azure Linux
|
||||||
|
* Added Chimera_small, Chimera2, Parabola2_small, PostmarketOS2, Qubes_small
|
||||||
|
* Updated linuxmint_small
|
||||||
|
* Cleaned up distro names
|
||||||
|
|
||||||
|
# 2.65.2
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
* Memory usage calculations now exclude the ZFS ARC cache on Linux, FreeBSD, NetBSD, and SunOS. (#1995 / #2418, Memory)
|
||||||
|
* This prevents the Memory module from reporting artificially high memory usage on systems with the ZFS kmod enabled.
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
* The GPU module no longer pings sleeping dedicated GPUs on dual-GPU laptops. (#2419, GPU)
|
||||||
|
* As a result, PCIe link speed detection (introduced in v2.65.0) is now only enabled in `driverSpecific` mode.
|
||||||
|
* Fixed a crash when detecting hardware codec support with the `amdgpu` driver on Linux. (#2419, Codec, Linux)
|
||||||
|
|
||||||
|
Logos:
|
||||||
|
* Updated CachyOS_small; fixed CachyOS logo colors to match the official logo better
|
||||||
|
* Added Turkish
|
||||||
|
|
||||||
|
# 2.65.1
|
||||||
|
|
||||||
|
No changes
|
||||||
|
|
||||||
# 2.65.0
|
# 2.65.0
|
||||||
|
|
||||||
Changes:
|
Changes:
|
||||||
|
|||||||
+49
-3
@@ -1,7 +1,7 @@
|
|||||||
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
||||||
|
|
||||||
project(fastfetch
|
project(fastfetch
|
||||||
VERSION 2.65.1
|
VERSION 2.67.0
|
||||||
LANGUAGES C
|
LANGUAGES C
|
||||||
DESCRIPTION "Fast neofetch-like system information tool"
|
DESCRIPTION "Fast neofetch-like system information tool"
|
||||||
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
|
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
|
||||||
@@ -105,6 +105,7 @@ cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND"
|
|||||||
option(ENABLE_ZLIB "Enable zlib" ON)
|
option(ENABLE_ZLIB "Enable zlib" ON)
|
||||||
option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embedded) yyjson library" OFF)
|
option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embedded) yyjson library" OFF)
|
||||||
option(ENABLE_ASAN "Build fastfetch with ASAN (address sanitizer)" OFF)
|
option(ENABLE_ASAN "Build fastfetch with ASAN (address sanitizer)" OFF)
|
||||||
|
option(ENABLE_TRACER "Build fastfetch with function tracing" OFF)
|
||||||
option(ENABLE_LTO "Enable link-time optimization in release mode if supported" ON)
|
option(ENABLE_LTO "Enable link-time optimization in release mode if supported" ON)
|
||||||
option(BUILD_FLASHFETCH "Build flashfetch" ON) # Also build the flashfetch binary
|
option(BUILD_FLASHFETCH "Build flashfetch" ON) # Also build the flashfetch binary
|
||||||
option(BUILD_TESTS "Build tests" OFF) # Also create test executables
|
option(BUILD_TESTS "Build tests" OFF) # Also create test executables
|
||||||
@@ -181,7 +182,30 @@ endif()
|
|||||||
|
|
||||||
set(WARNING_FLAGS "-Wall -Wextra -Wconversion -Werror=uninitialized -Werror=return-type -Werror=vla")
|
set(WARNING_FLAGS "-Wall -Wextra -Wconversion -Werror=uninitialized -Werror=return-type -Werror=vla")
|
||||||
|
|
||||||
set(CMAKE_C_STANDARD 11)
|
if(LINUX)
|
||||||
|
if(NOT IS_MUSL) # `NOT DEFINED IS_MUSL` doesn't work
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${CMAKE_C_COMPILER} -print-file-name=libc.so
|
||||||
|
OUTPUT_VARIABLE LIBC_PATH
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
|
||||||
|
if(LIBC_PATH MATCHES "-musl")
|
||||||
|
set(IS_MUSL ON CACHE BOOL "Build with musl libc" FORCE)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(IS_MUSL)
|
||||||
|
message(STATUS "MUSL libc detected")
|
||||||
|
# Silence ioctl related warnings
|
||||||
|
set(WARNING_FLAGS "${WARNING_FLAGS} -Wno-sign-conversion")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Minimal compiler version supported: GCC 13 (2023-04-26), Clang 16 (2023-03-17)
|
||||||
|
# Most C23 features are allowed with noticeable exceptions of `constexpr` and `#embed`
|
||||||
|
# See https://cppreference.com/c/compiler_support/23 for detail
|
||||||
|
set(CMAKE_C_STANDARD 23)
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} -Werror=incompatible-pointer-types -Werror=implicit-function-declaration -Werror=int-conversion")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} -Werror=incompatible-pointer-types -Werror=implicit-function-declaration -Werror=int-conversion")
|
||||||
|
|
||||||
if(WIN32 OR Haiku)
|
if(WIN32 OR Haiku)
|
||||||
@@ -410,6 +434,7 @@ set(LIBFASTFETCH_SRC
|
|||||||
src/common/impl/font.c
|
src/common/impl/font.c
|
||||||
src/common/impl/format.c
|
src/common/impl/format.c
|
||||||
src/common/impl/frequency.c
|
src/common/impl/frequency.c
|
||||||
|
src/common/impl/genconfig.c
|
||||||
src/common/impl/init.c
|
src/common/impl/init.c
|
||||||
src/common/impl/jsonconfig.c
|
src/common/impl/jsonconfig.c
|
||||||
src/common/impl/library.c
|
src/common/impl/library.c
|
||||||
@@ -1099,7 +1124,7 @@ elseif(WIN32)
|
|||||||
src/detection/gpu/gpu_windows.cpp
|
src/detection/gpu/gpu_windows.cpp
|
||||||
src/detection/host/host_windows.c
|
src/detection/host/host_windows.c
|
||||||
src/detection/icons/icons_windows.c
|
src/detection/icons/icons_windows.c
|
||||||
src/detection/initsystem/initsystem_nosupport.c
|
src/detection/initsystem/initsystem_windows.c
|
||||||
src/detection/keyboard/keyboard_windows.c
|
src/detection/keyboard/keyboard_windows.c
|
||||||
src/detection/libc/libc_windows.cpp
|
src/detection/libc/libc_windows.cpp
|
||||||
src/detection/lm/lm_nosupport.c
|
src/detection/lm/lm_nosupport.c
|
||||||
@@ -1365,6 +1390,22 @@ elseif(GNU)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(ENABLE_TRACER)
|
||||||
|
message(STATUS "Tracer is enabled")
|
||||||
|
list(APPEND LIBFASTFETCH_SRC src/common/impl/tracer.c)
|
||||||
|
if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -finstrument-functions-after-inlining")
|
||||||
|
else()
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -finstrument-functions -Dinline=\"__attribute__((no_instrument_function)) inline\"")
|
||||||
|
endif()
|
||||||
|
if(NOT WIN32)
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -rdynamic")
|
||||||
|
elseif(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -gcodeview -fuse-ld=lld")
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--pdb=${CMAKE_BINARY_DIR}/fastfetch.pdb")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
# Proprietary GPU driver APIs
|
# Proprietary GPU driver APIs
|
||||||
if(LINUX OR FreeBSD OR WIN32)
|
if(LINUX OR FreeBSD OR WIN32)
|
||||||
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_nvidia.c)
|
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_nvidia.c)
|
||||||
@@ -1889,6 +1930,11 @@ elseif(WIN32)
|
|||||||
PRIVATE "runtimeobject"
|
PRIVATE "runtimeobject"
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
if(ENABLE_TRACER)
|
||||||
|
target_link_libraries(libfastfetch
|
||||||
|
PRIVATE "dbghelp"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
elseif(FreeBSD)
|
elseif(FreeBSD)
|
||||||
target_link_libraries(libfastfetch
|
target_link_libraries(libfastfetch
|
||||||
PRIVATE "m"
|
PRIVATE "m"
|
||||||
|
|||||||
@@ -199,7 +199,8 @@ See [#1096](https://github.com/fastfetch-cli/fastfetch/issues/1096).
|
|||||||
|
|
||||||
### Q: Fastfetch shows fewer dpkg packages than neofetch. Is it a bug?
|
### Q: Fastfetch shows fewer dpkg packages than neofetch. Is it a bug?
|
||||||
|
|
||||||
Neofetch incorrectly counts `rc` packages (packages that have been removed but still have configuration files remaining). See bug: https://github.com/dylanaraps/neofetch/issues/2278
|
1. Neofetch incorrectly counts `rc` packages for apt (packages that have been removed but still have configuration files remaining). See bug: https://github.com/dylanaraps/neofetch/issues/2278
|
||||||
|
2. Neofetch incorrectly counts `gpg-pubkey` as packages for rpm. You may check the results of `dnf list --installed | wc -l` and `rpm -qa | wc -l` to see the difference.
|
||||||
|
|
||||||
### Q: I use Debian / Ubuntu / Debian-derived distro. My GPU is detected as `XXXX Device XXXX (VGA compatible)`. Is this a bug?
|
### Q: I use Debian / Ubuntu / Debian-derived distro. My GPU is detected as `XXXX Device XXXX (VGA compatible)`. Is this a bug?
|
||||||
|
|
||||||
|
|||||||
Vendored
+18
@@ -1,3 +1,21 @@
|
|||||||
|
fastfetch (2.66.0~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
|
||||||
|
|
||||||
|
* Update to 2.66.0
|
||||||
|
|
||||||
|
-- Carter Li <zhangsongcui@live.cn> Fri, 10 Jul 2026 15:13:37 +0800
|
||||||
|
|
||||||
|
fastfetch (2.65.2~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
|
||||||
|
|
||||||
|
* Update to 2.65.2
|
||||||
|
|
||||||
|
-- Carter Li <zhangsongcui@live.cn> Mon, 29 Jun 2026 10:05:47 +0800
|
||||||
|
|
||||||
|
fastfetch (2.65.1~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
|
||||||
|
|
||||||
|
* Update to 2.65.1
|
||||||
|
|
||||||
|
-- Carter Li <zhangsongcui@live.cn> Wed, 24 Jun 2026 14:21:06 +0800
|
||||||
|
|
||||||
fastfetch (2.64.2~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
|
fastfetch (2.64.2~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
|
||||||
|
|
||||||
* Update to 2.64.2
|
* Update to 2.64.2
|
||||||
|
|||||||
Vendored
+1
-1
@@ -10,7 +10,7 @@ SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
|
|||||||
ROOT_DIR="$(cd -- "$SCRIPT_DIR/.." >/dev/null 2>&1 && pwd)"
|
ROOT_DIR="$(cd -- "$SCRIPT_DIR/.." >/dev/null 2>&1 && pwd)"
|
||||||
OUT_DIR="$(dirname "$ROOT_DIR")"
|
OUT_DIR="$(dirname "$ROOT_DIR")"
|
||||||
PPA="ppa:zhangsongcui3371/fastfetch"
|
PPA="ppa:zhangsongcui3371/fastfetch"
|
||||||
CODENAMES=( jammy noble plucky questing resolute )
|
CODENAMES=( jammy noble plucky questing resolute stonking )
|
||||||
DRY_RUN=0
|
DRY_RUN=0
|
||||||
|
|
||||||
if [[ -d "$OUT_DIR/build" ]]; then
|
if [[ -d "$OUT_DIR/build" ]]; then
|
||||||
|
|||||||
+12
-20
@@ -83,6 +83,16 @@
|
|||||||
"type": "num",
|
"type": "num",
|
||||||
"default": 0
|
"default": 0
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"long": "watch",
|
||||||
|
"short": "w",
|
||||||
|
"desc": "Alias of dynamic-interval, but the value is in seconds instead of milliseconds. If no value is provided, it defaults to 1 second",
|
||||||
|
"arg": {
|
||||||
|
"type": "num",
|
||||||
|
"optional": true,
|
||||||
|
"default": 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"Config": [
|
"Config": [
|
||||||
@@ -97,26 +107,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"long": "gen-config",
|
"long": "gen-config",
|
||||||
"desc": "Generate a minimal config file at the specified path",
|
"desc": "Interactively generate a config file at the specified path",
|
||||||
"remark": "Defaults to \"~/.config/fastfetch/config.jsonc\". Prints the generated config if <path> is \"-\"",
|
"remark": "Opens an interactive configuration UI when run in a terminal. Falls back to non-interactive generation when env-var `$NO_COLOR` is set or stdin/stdout is not a TTY. Defaults to \"~/.config/fastfetch/config.jsonc\". Prints the generated config if <path> is \"-\"",
|
||||||
"arg": {
|
|
||||||
"type": "path",
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"long": "gen-config-full",
|
|
||||||
"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 <path> is \"-\"",
|
|
||||||
"arg": {
|
|
||||||
"type": "path",
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"long": "gen-config-force",
|
|
||||||
"desc": "Generate a config file at the specified path, overwriting any existing file",
|
|
||||||
"remark": "Defaults to \"~/.config/fastfetch/config.jsonc\"",
|
|
||||||
"arg": {
|
"arg": {
|
||||||
"type": "path",
|
"type": "path",
|
||||||
"optional": true
|
"optional": true
|
||||||
|
|||||||
@@ -243,7 +243,7 @@
|
|||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "True to show the module only if it succeeded; false to show it only if it failed"
|
"description": "True to show the module only if the last run succeeded; false to show it only if the last run failed"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "null",
|
"type": "null",
|
||||||
@@ -912,11 +912,6 @@
|
|||||||
"description": "Set the timeout (ms) when waiting for child processes, `-1` for no timeout",
|
"description": "Set the timeout (ms) when waiting for child processes, `-1` for no timeout",
|
||||||
"default": 5000
|
"default": 5000
|
||||||
},
|
},
|
||||||
"preRun": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Command to run before printing logos",
|
|
||||||
"default": ""
|
|
||||||
},
|
|
||||||
"detectVersion": {
|
"detectVersion": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Whether to detect and display component versions. Mainly for benchmarking",
|
"description": "Whether to detect and display component versions. Mainly for benchmarking",
|
||||||
|
|||||||
+13
-13
@@ -42,12 +42,12 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "kernel",
|
"type": "kernel",
|
||||||
"key": "│ ├",
|
"key": "│ ├{icon}",
|
||||||
"keyColor": "yellow"
|
"keyColor": "yellow"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "packages",
|
"type": "packages",
|
||||||
"key": "│ ├",
|
"key": "│ ├{icon}",
|
||||||
"keyColor": "yellow"
|
"keyColor": "yellow"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -62,22 +62,22 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "lm",
|
"type": "lm",
|
||||||
"key": "│ ├",
|
"key": "│ ├{icon}",
|
||||||
"keyColor": "blue"
|
"keyColor": "blue"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "wmtheme",
|
"type": "wmtheme",
|
||||||
"key": "│ ├",
|
"key": "│ ├{icon}",
|
||||||
"keyColor": "blue"
|
"keyColor": "blue"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "icons",
|
"type": "icons",
|
||||||
"key": "│ ├",
|
"key": "│ ├{icon}",
|
||||||
"keyColor": "blue"
|
"keyColor": "blue"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "terminal",
|
"type": "terminal",
|
||||||
"key": "│ ├",
|
"key": "│ ├{icon}",
|
||||||
"keyColor": "blue"
|
"keyColor": "blue"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -92,32 +92,32 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "cpu",
|
"type": "cpu",
|
||||||
"key": "│ ├",
|
"key": "│ ├{icon}",
|
||||||
"keyColor": "green"
|
"keyColor": "green"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "gpu",
|
"type": "gpu",
|
||||||
"key": "│ ├",
|
"key": "│ ├{icon}",
|
||||||
"keyColor": "green"
|
"keyColor": "green"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "disk",
|
"type": "disk",
|
||||||
"key": "│ ├",
|
"key": "│ ├{icon}",
|
||||||
"keyColor": "green"
|
"keyColor": "green"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "memory",
|
"type": "memory",
|
||||||
"key": "│ ├",
|
"key": "│ ├{icon}",
|
||||||
"keyColor": "green"
|
"keyColor": "green"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "swap",
|
"type": "swap",
|
||||||
"key": "│ ├",
|
"key": "│ ├{icon}",
|
||||||
"keyColor": "green"
|
"keyColor": "green"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "uptime",
|
"type": "uptime",
|
||||||
"key": "│ ├",
|
"key": "│ ├{icon}",
|
||||||
"keyColor": "green"
|
"keyColor": "green"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -132,7 +132,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "player",
|
"type": "player",
|
||||||
"key": "│ ├",
|
"key": "│ ├{icon}",
|
||||||
"keyColor": "cyan"
|
"keyColor": "cyan"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Inspired by Catnap
|
// Inspired by Catnap (https://github.com/iinsertNameHere/catnap)
|
||||||
{
|
{
|
||||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||||
"logo": {
|
"logo": {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Inspired by Catnap
|
// Inspired by Catnap (https://github.com/iinsertNameHere/catnap)
|
||||||
{
|
{
|
||||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||||
"logo": {
|
"logo": {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Inspired by Catnap
|
// Inspired by Catnap (https://github.com/iinsertNameHere/catnap)
|
||||||
{
|
{
|
||||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||||
"logo": {
|
"logo": {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Inspired by Catnap
|
// Inspired by Catnap (https://github.com/iinsertNameHere/catnap)
|
||||||
{
|
{
|
||||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||||
"logo": {
|
"logo": {
|
||||||
|
|||||||
@@ -16,6 +16,13 @@
|
|||||||
"separator",
|
"separator",
|
||||||
"os",
|
"os",
|
||||||
"host",
|
"host",
|
||||||
|
{
|
||||||
|
"type": "board",
|
||||||
|
"key": "Host",
|
||||||
|
"condition": {
|
||||||
|
"succeeded": false
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "kernel",
|
"type": "kernel",
|
||||||
"format": "{release}"
|
"format": "{release}"
|
||||||
|
|||||||
+40
-15
@@ -1,11 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/attributes.h"
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#define FF_LIST_DEFAULT_ALLOC 16
|
#define FF_LIST_DEFAULT_ALLOC 16
|
||||||
|
|
||||||
@@ -15,8 +14,6 @@ typedef struct FFlist {
|
|||||||
uint32_t capacity;
|
uint32_t capacity;
|
||||||
} FFlist;
|
} FFlist;
|
||||||
|
|
||||||
void* ffListAdd(FFlist* list, uint32_t elementSize);
|
|
||||||
|
|
||||||
// Removes the first element, and copy its value to `*result`
|
// Removes the first element, and copy its value to `*result`
|
||||||
bool ffListShift(FFlist* list, uint32_t elementSize, void* __restrict result);
|
bool ffListShift(FFlist* list, uint32_t elementSize, void* __restrict result);
|
||||||
// Removes the last element, and copy its value to `*result`
|
// Removes the last element, and copy its value to `*result`
|
||||||
@@ -25,33 +22,33 @@ bool ffListPop(FFlist* list, uint32_t elementSize, void* __restrict result);
|
|||||||
static inline void ffListInit(FFlist* list) {
|
static inline void ffListInit(FFlist* list) {
|
||||||
list->capacity = 0;
|
list->capacity = 0;
|
||||||
list->length = 0;
|
list->length = 0;
|
||||||
list->data = NULL;
|
list->data = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ffListInitA(FFlist* list, uint32_t elementSize, uint32_t capacity) {
|
static inline void ffListInitA(FFlist* list, uint32_t elementSize, uint32_t capacity) {
|
||||||
ffListInit(list);
|
ffListInit(list);
|
||||||
list->capacity = capacity;
|
list->capacity = capacity;
|
||||||
list->data = __builtin_expect(capacity == 0, 0) ? NULL : (uint8_t*) malloc((size_t) capacity * elementSize);
|
list->data = __builtin_expect(capacity == 0, 0) ? nullptr : (uint8_t*) malloc((size_t) capacity * elementSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_A_NODISCARD static inline FFlist ffListCreate() {
|
[[nodiscard]] static inline FFlist ffListCreate() {
|
||||||
FFlist result;
|
FFlist result;
|
||||||
ffListInit(&result);
|
ffListInit(&result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_A_NODISCARD static inline FFlist ffListCreateA(uint32_t elementSize, uint32_t capacity) {
|
[[nodiscard]] static inline FFlist ffListCreateA(uint32_t elementSize, uint32_t capacity) {
|
||||||
FFlist result;
|
FFlist result;
|
||||||
ffListInitA(&result, elementSize, capacity);
|
ffListInitA(&result, elementSize, capacity);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_A_NODISCARD static inline void* ffListGet(const FFlist* list, uint32_t elementSize, uint32_t index) {
|
[[nodiscard]] static inline void* ffListGet(const FFlist* list, uint32_t elementSize, uint32_t index) {
|
||||||
assert(list->capacity > index);
|
assert(list->capacity > index);
|
||||||
return list->data + (index * elementSize);
|
return list->data + (index * elementSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_A_NODISCARD static inline uint32_t ffListFirstIndexComp(const FFlist* list, uint32_t elementSize, void* compElement, bool (*compFunc)(const void*, const void*)) {
|
[[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++) {
|
for (uint32_t i = 0; i < list->length; i++) {
|
||||||
if (compFunc(ffListGet(list, elementSize, i), compElement)) {
|
if (compFunc(ffListGet(list, elementSize, i), compElement)) {
|
||||||
return i;
|
return i;
|
||||||
@@ -61,7 +58,7 @@ FF_A_NODISCARD static inline uint32_t ffListFirstIndexComp(const FFlist* list, u
|
|||||||
return list->length;
|
return list->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_A_NODISCARD static inline bool ffListContains(const FFlist* list, uint32_t elementSize, void* compElement, bool (*compFunc)(const void*, const void*)) {
|
[[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;
|
return ffListFirstIndexComp(list, elementSize, compElement, compFunc) != list->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,7 +86,7 @@ static inline void ffListDestroy(FFlist* list) {
|
|||||||
// 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;
|
list->capacity = list->length = 0;
|
||||||
free(list->data);
|
free(list->data);
|
||||||
list->data = NULL;
|
list->data = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ffListClear(FFlist* list) {
|
static inline void ffListClear(FFlist* list) {
|
||||||
@@ -105,12 +102,34 @@ static inline void ffListReserve(FFlist* list, uint32_t elementSize, uint32_t ne
|
|||||||
list->capacity = newCapacity;
|
list->capacity = newCapacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void* ffListAdd(FFlist* list, uint32_t elementSize) {
|
||||||
|
if (__builtin_expect(list->length == list->capacity, false)) {
|
||||||
|
ffListReserve(list, elementSize, list->capacity == 0 ? FF_LIST_DEFAULT_ALLOC : list->capacity * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
++list->length;
|
||||||
|
return ffListGet(list, elementSize, list->length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ffListRemoveAt(FFlist* list, uint32_t elementSize, uint32_t index) {
|
||||||
|
assert(list->length > index);
|
||||||
|
memmove(list->data + (index * elementSize), list->data + ((index + 1) * elementSize), (size_t) (list->length - index - 1) * elementSize);
|
||||||
|
--list->length;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ffListInsertAt(FFlist* list, uint32_t elementSize, uint32_t index, const void* element) {
|
||||||
|
assert(list->length >= index);
|
||||||
|
ffListAdd(list, elementSize);
|
||||||
|
memmove(list->data + ((index + 1) * elementSize), list->data + (index * elementSize), (size_t) (list->length - index - 1) * elementSize);
|
||||||
|
memcpy(list->data + (index * elementSize), element, elementSize);
|
||||||
|
}
|
||||||
|
|
||||||
#define FF_LIST_FOR_EACH(itemType, itemVarName, listVar) \
|
#define FF_LIST_FOR_EACH(itemType, itemVarName, listVar) \
|
||||||
for (itemType* itemVarName = (itemType*) (listVar).data; \
|
for (itemType* itemVarName = (itemType*) (listVar).data; \
|
||||||
itemVarName - (itemType*) (listVar).data < (intptr_t) (listVar).length; \
|
itemVarName - (itemType*) (listVar).data < (intptr_t) (listVar).length; \
|
||||||
++itemVarName)
|
++itemVarName)
|
||||||
|
|
||||||
#define FF_LIST_AUTO_DESTROY FFlist FF_A_CLEANUP(ffListDestroy)
|
#define FF_LIST_AUTO_DESTROY [[gnu::cleanup(ffListDestroy)]] FFlist
|
||||||
|
|
||||||
#define FF_LIST_GET(itemType, listVar, index) \
|
#define FF_LIST_GET(itemType, listVar, index) \
|
||||||
({ \
|
({ \
|
||||||
@@ -120,6 +139,12 @@ static inline void ffListReserve(FFlist* list, uint32_t elementSize, uint32_t ne
|
|||||||
|
|
||||||
#define FF_LIST_ADD(itemType, listVar) (itemType*) ffListAdd(&(listVar), (uint32_t) sizeof(itemType))
|
#define FF_LIST_ADD(itemType, listVar) (itemType*) ffListAdd(&(listVar), (uint32_t) sizeof(itemType))
|
||||||
|
|
||||||
|
#define FF_LIST_REMOVE_AT(itemType, listVar, index) \
|
||||||
|
ffListRemoveAt(&(listVar), (uint32_t) sizeof(itemType), (index))
|
||||||
|
|
||||||
|
#define FF_LIST_INSERT_AT(itemType, listVar, index, pElement) \
|
||||||
|
ffListInsertAt(&(listVar), (uint32_t) sizeof(itemType), (index), (pElement))
|
||||||
|
|
||||||
#define FF_LIST_FIRST(itemType, listVar) FF_LIST_GET(itemType, listVar, 0)
|
#define FF_LIST_FIRST(itemType, listVar) FF_LIST_GET(itemType, listVar, 0)
|
||||||
#define FF_LIST_LAST(itemType, listVar) \
|
#define FF_LIST_LAST(itemType, listVar) \
|
||||||
({ \
|
({ \
|
||||||
@@ -129,9 +154,9 @@ static inline void ffListReserve(FFlist* list, uint32_t elementSize, uint32_t ne
|
|||||||
|
|
||||||
#define FF_LIST_CONTAINS(listVar, pCompElement, compFunc) \
|
#define FF_LIST_CONTAINS(listVar, pCompElement, compFunc) \
|
||||||
({ \
|
({ \
|
||||||
typedef __typeof__(*(pCompElement)) compElementType; \
|
typedef typeof(*(pCompElement)) compElementType; \
|
||||||
typedef bool compFuncType(const compElementType*, const compElementType*); \
|
typedef bool compFuncType(const compElementType*, const compElementType*); \
|
||||||
static_assert(__builtin_types_compatible_p(__typeof__(compFunc), compFuncType), "Incompatible callback function"); \
|
static_assert(__builtin_types_compatible_p(typeof(compFunc), compFuncType), "Incompatible callback function"); \
|
||||||
ffListContains(&(listVar), (uint32_t) sizeof(*(pCompElement)), (pCompElement), (bool (*)(const void*, const void*)) compFunc); \
|
ffListContains(&(listVar), (uint32_t) sizeof(*(pCompElement)), (pCompElement), (bool (*)(const void*, const void*)) compFunc); \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
+154
-108
@@ -1,7 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/attributes.h"
|
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
@@ -37,18 +35,15 @@ static inline void ffStrbufInit(FFstrbuf* strbuf);
|
|||||||
void ffStrbufInitA(FFstrbuf* strbuf, uint32_t allocate);
|
void ffStrbufInitA(FFstrbuf* strbuf, uint32_t allocate);
|
||||||
void ffStrbufInitVF(FFstrbuf* strbuf, const char* format, va_list arguments);
|
void ffStrbufInitVF(FFstrbuf* strbuf, const char* format, va_list arguments);
|
||||||
void ffStrbufInitMoveNS(FFstrbuf* strbuf, uint32_t length, char* heapStr);
|
void ffStrbufInitMoveNS(FFstrbuf* strbuf, uint32_t length, char* heapStr);
|
||||||
|
[[gnu::format(printf, 2, 3)]] void ffStrbufInitF(FFstrbuf* strbuf, const char* format, ...);
|
||||||
|
[[gnu::format(printf, 1, 2)]] [[nodiscard]] FFstrbuf ffStrbufCreateF(const char* format, ...);
|
||||||
|
|
||||||
void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free);
|
|
||||||
void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free);
|
void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free);
|
||||||
|
void ffStrbufEnsureFreeNoCheck(FFstrbuf* strbuf, uint32_t free);
|
||||||
void ffStrbufClear(FFstrbuf* strbuf);
|
|
||||||
|
|
||||||
static inline void ffStrbufAppend(FFstrbuf* __restrict strbuf, const FFstrbuf* __restrict value);
|
static inline void ffStrbufAppend(FFstrbuf* __restrict strbuf, const FFstrbuf* __restrict value);
|
||||||
void ffStrbufAppendC(FFstrbuf* strbuf, char c);
|
|
||||||
void ffStrbufAppendNC(FFstrbuf* strbuf, uint32_t num, char c);
|
|
||||||
void ffStrbufAppendNS(FFstrbuf* strbuf, uint32_t length, const char* value);
|
|
||||||
void ffStrbufAppendTransformS(FFstrbuf* strbuf, const char* value, int (*transformFunc)(int));
|
void ffStrbufAppendTransformS(FFstrbuf* strbuf, const char* value, int (*transformFunc)(int));
|
||||||
FF_A_PRINTF(2, 3) void ffStrbufAppendF(FFstrbuf* strbuf, const char* format, ...);
|
[[gnu::format(printf, 2, 3)]] void ffStrbufAppendF(FFstrbuf* strbuf, const char* format, ...);
|
||||||
void ffStrbufAppendVF(FFstrbuf* strbuf, const char* format, va_list arguments);
|
void ffStrbufAppendVF(FFstrbuf* strbuf, const char* format, va_list arguments);
|
||||||
const char* ffStrbufAppendSUntilC(FFstrbuf* strbuf, const char* value, char until);
|
const char* ffStrbufAppendSUntilC(FFstrbuf* strbuf, const char* value, char until);
|
||||||
|
|
||||||
@@ -61,7 +56,7 @@ void ffStrbufInsertNC(FFstrbuf* strbuf, uint32_t index, uint32_t num, char c);
|
|||||||
// NOTE: Unlike ffStrbufAppend*, ffStrbufSet* functions may NOT reserve extra space
|
// NOTE: Unlike ffStrbufAppend*, ffStrbufSet* functions may NOT reserve extra space
|
||||||
void ffStrbufSet(FFstrbuf* strbuf, const FFstrbuf* value);
|
void ffStrbufSet(FFstrbuf* strbuf, const FFstrbuf* value);
|
||||||
void ffStrbufSetNS(FFstrbuf* strbuf, uint32_t length, const char* value);
|
void ffStrbufSetNS(FFstrbuf* strbuf, uint32_t length, const char* value);
|
||||||
FF_A_PRINTF(2, 3) void ffStrbufSetF(FFstrbuf* strbuf, const char* format, ...);
|
[[gnu::format(printf, 2, 3)]] void ffStrbufSetF(FFstrbuf* strbuf, const char* format, ...);
|
||||||
|
|
||||||
void ffStrbufTrimLeft(FFstrbuf* strbuf, char c);
|
void ffStrbufTrimLeft(FFstrbuf* strbuf, char c);
|
||||||
void ffStrbufTrimRight(FFstrbuf* strbuf, char c);
|
void ffStrbufTrimRight(FFstrbuf* strbuf, char c);
|
||||||
@@ -82,25 +77,18 @@ bool ffStrbufSubstrAfterFirstS(FFstrbuf* strbuf, const char* str);
|
|||||||
bool ffStrbufSubstrAfterLastC(FFstrbuf* strbuf, char c);
|
bool ffStrbufSubstrAfterLastC(FFstrbuf* strbuf, char c);
|
||||||
bool ffStrbufSubstr(FFstrbuf* strbuf, uint32_t start, uint32_t end);
|
bool ffStrbufSubstr(FFstrbuf* strbuf, uint32_t start, uint32_t end);
|
||||||
|
|
||||||
FF_A_NODISCARD uint32_t ffStrbufCountC(const FFstrbuf* strbuf, char c);
|
[[nodiscard]] uint32_t ffStrbufCountC(const FFstrbuf* strbuf, char c);
|
||||||
|
|
||||||
bool ffStrbufRemoveIgnCaseEndS(FFstrbuf* strbuf, const char* end);
|
bool ffStrbufRemoveIgnCaseEndS(FFstrbuf* strbuf, const char* end);
|
||||||
|
|
||||||
bool ffStrbufEnsureEndsWithC(FFstrbuf* strbuf, char c);
|
bool ffStrbufEnsureEndsWithC(FFstrbuf* strbuf, char c);
|
||||||
|
|
||||||
void ffStrbufWriteTo(const FFstrbuf* strbuf, FILE* file);
|
|
||||||
void ffStrbufPutTo(const FFstrbuf* strbuf, FILE* file);
|
|
||||||
|
|
||||||
FF_A_NODISCARD double ffStrbufToDouble(const FFstrbuf* strbuf, double defaultValue);
|
|
||||||
FF_A_NODISCARD int64_t ffStrbufToSInt(const FFstrbuf* strbuf, int64_t defaultValue);
|
|
||||||
FF_A_NODISCARD uint64_t ffStrbufToUInt(const FFstrbuf* strbuf, uint64_t defaultValue);
|
|
||||||
|
|
||||||
void ffStrbufUpperCase(FFstrbuf* strbuf);
|
void ffStrbufUpperCase(FFstrbuf* strbuf);
|
||||||
void ffStrbufLowerCase(FFstrbuf* strbuf);
|
void ffStrbufLowerCase(FFstrbuf* strbuf);
|
||||||
|
|
||||||
// Function alters the buffer to extract lines or delimited segments (replaces the delimiter with '\0')
|
// Function alters the buffer to extract lines or delimited segments (replaces the delimiter with '\0')
|
||||||
// so that buffer MUST be heap allocated (NOT a static string)
|
// so that buffer MUST be heap allocated (NOT a static string)
|
||||||
// `lineptr` must be `NULL` and `n` MUST be `0` for the first call
|
// `lineptr` must be `nullptr` and `n` MUST be `0` for the first call
|
||||||
// Caller MUST NOT free `*lineptr`
|
// Caller MUST NOT free `*lineptr`
|
||||||
bool ffStrbufGetdelim(char** lineptr, size_t* n, char delimiter, FFstrbuf* buffer);
|
bool ffStrbufGetdelim(char** lineptr, size_t* n, char delimiter, FFstrbuf* buffer);
|
||||||
void ffStrbufGetdelimRestore(char** lineptr, size_t* n, char delimiter, FFstrbuf* buffer);
|
void ffStrbufGetdelimRestore(char** lineptr, size_t* n, char delimiter, FFstrbuf* buffer);
|
||||||
@@ -113,7 +101,7 @@ void ffStrbufGetdelimRestore(char** lineptr, size_t* n, char delimiter, FFstrbuf
|
|||||||
* @param[in,out] lineptr The pointer to a pointer that will be set to the start of the line
|
* @param[in,out] lineptr The pointer to a pointer that will be set to the start of the line
|
||||||
(points to buffer's internal memory address to avoid memory allocation and copy).
|
(points to buffer's internal memory address to avoid memory allocation and copy).
|
||||||
MUST NOT be freed by the caller, unlike `getline(3)`.
|
MUST NOT be freed by the caller, unlike `getline(3)`.
|
||||||
* MUST be NULL for the first call.
|
* MUST be nullptr for the first call.
|
||||||
* @param[in,out] n The pointer to the size of the buffer of lineptr.
|
* @param[in,out] n The pointer to the size of the buffer of lineptr.
|
||||||
MUST be 0 for the first call.
|
MUST be 0 for the first call.
|
||||||
* @param[in] buffer The buffer to read from.
|
* @param[in] buffer The buffer to read from.
|
||||||
@@ -145,7 +133,7 @@ void ffStrbufAppendUInt(FFstrbuf* strbuf, uint64_t value);
|
|||||||
// if `precision < 0`, let yyjson decide the precision
|
// if `precision < 0`, let yyjson decide the precision
|
||||||
void ffStrbufAppendDouble(FFstrbuf* strbuf, double value, int8_t precision, bool trailingZeros);
|
void ffStrbufAppendDouble(FFstrbuf* strbuf, double value, int8_t precision, bool trailingZeros);
|
||||||
|
|
||||||
FF_A_NODISCARD static inline FFstrbuf ffStrbufCreateA(uint32_t allocate) {
|
[[nodiscard]] static inline FFstrbuf ffStrbufCreateA(uint32_t allocate) {
|
||||||
FFstrbuf strbuf;
|
FFstrbuf strbuf;
|
||||||
ffStrbufInitA(&strbuf, allocate);
|
ffStrbufInitA(&strbuf, allocate);
|
||||||
return strbuf;
|
return strbuf;
|
||||||
@@ -160,7 +148,7 @@ static inline void ffStrbufInitCopy(FFstrbuf* __restrict strbuf, const FFstrbuf*
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_A_NODISCARD static inline FFstrbuf ffStrbufCreateCopy(const FFstrbuf* src) {
|
[[nodiscard]] static inline FFstrbuf ffStrbufCreateCopy(const FFstrbuf* src) {
|
||||||
FFstrbuf strbuf;
|
FFstrbuf strbuf;
|
||||||
ffStrbufInitCopy(&strbuf, src);
|
ffStrbufInitCopy(&strbuf, src);
|
||||||
return strbuf;
|
return strbuf;
|
||||||
@@ -176,37 +164,12 @@ static inline void ffStrbufInitMove(FFstrbuf* strbuf, FFstrbuf* src) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_A_NODISCARD static inline FFstrbuf ffStrbufCreateMove(FFstrbuf* src) {
|
[[nodiscard]] static inline FFstrbuf ffStrbufCreateMove(FFstrbuf* src) {
|
||||||
FFstrbuf strbuf;
|
FFstrbuf strbuf;
|
||||||
ffStrbufInitMove(&strbuf, src);
|
ffStrbufInitMove(&strbuf, src);
|
||||||
return strbuf;
|
return strbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_A_NODISCARD static inline FFstrbuf ffStrbufCreateVF(const char* format, va_list arguments) {
|
|
||||||
FFstrbuf strbuf;
|
|
||||||
ffStrbufInitVF(&strbuf, format, arguments);
|
|
||||||
return strbuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
FF_A_PRINTF(2, 3) static inline void ffStrbufInitF(FFstrbuf* strbuf, const char* format, ...) {
|
|
||||||
va_list arguments;
|
|
||||||
va_start(arguments, format);
|
|
||||||
ffStrbufInitVF(strbuf, format, arguments);
|
|
||||||
va_end(arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
FF_A_PRINTF(1, 2) FF_A_NODISCARD static inline FFstrbuf
|
|
||||||
ffStrbufCreateF(const char* format, ...) {
|
|
||||||
FFstrbuf strbuf;
|
|
||||||
|
|
||||||
va_list arguments;
|
|
||||||
va_start(arguments, format);
|
|
||||||
ffStrbufInitVF(&strbuf, format, arguments);
|
|
||||||
va_end(arguments);
|
|
||||||
|
|
||||||
return strbuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void ffStrbufInitMoveS(FFstrbuf* strbuf, char* heapStr) {
|
static inline void ffStrbufInitMoveS(FFstrbuf* strbuf, char* heapStr) {
|
||||||
ffStrbufInitMoveNS(strbuf, (uint32_t) strlen(heapStr), heapStr);
|
ffStrbufInitMoveNS(strbuf, (uint32_t) strlen(heapStr), heapStr);
|
||||||
}
|
}
|
||||||
@@ -220,8 +183,8 @@ static inline void ffStrbufDestroy(FFstrbuf* strbuf) {
|
|||||||
ffStrbufInit(strbuf);
|
ffStrbufInit(strbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_A_NODISCARD static inline uint32_t ffStrbufGetFree(const FFstrbuf* strbuf) {
|
[[nodiscard]] static inline uint32_t ffStrbufGetFree(const FFstrbuf* strbuf) {
|
||||||
assert(strbuf != NULL);
|
assert(strbuf != nullptr);
|
||||||
if (strbuf->allocated == 0) {
|
if (strbuf->allocated == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -229,14 +192,78 @@ FF_A_NODISCARD static inline uint32_t ffStrbufGetFree(const FFstrbuf* strbuf) {
|
|||||||
return strbuf->allocated - strbuf->length - 1; // - 1 for the null byte
|
return strbuf->allocated - strbuf->length - 1; // - 1 for the null byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free) {
|
||||||
|
if (__builtin_expect(free == 0, false)) {
|
||||||
|
if (__builtin_expect(!(strbuf->allocated == 0 && strbuf->length > 0), true)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (__builtin_expect(ffStrbufGetFree(strbuf) >= free, true)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ffStrbufEnsureFreeNoCheck(strbuf, free);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void ffStrbufClear(FFstrbuf* strbuf) {
|
||||||
|
assert(strbuf != nullptr);
|
||||||
|
extern char* CHAR_NULL_PTR;
|
||||||
|
|
||||||
|
if (strbuf->allocated == 0) {
|
||||||
|
strbuf->chars = CHAR_NULL_PTR;
|
||||||
|
} else {
|
||||||
|
strbuf->chars[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
strbuf->length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ffStrbufAppendC(FFstrbuf* strbuf, char c) {
|
||||||
|
ffStrbufEnsureFree(strbuf, 1);
|
||||||
|
strbuf->chars[strbuf->length++] = c;
|
||||||
|
strbuf->chars[strbuf->length] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ffStrbufAppendNC(FFstrbuf* strbuf, uint32_t num, char c) {
|
||||||
|
if (__builtin_expect(num == 0, false)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ffStrbufEnsureFree(strbuf, num);
|
||||||
|
|
||||||
|
memset(&strbuf->chars[strbuf->length], c, num);
|
||||||
|
strbuf->length += num;
|
||||||
|
strbuf->chars[strbuf->length] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ffStrbufAppendNS(FFstrbuf* strbuf, uint32_t length, const char* value) {
|
||||||
|
if (__builtin_expect(value == nullptr || length == 0, false)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ffStrbufEnsureFree(strbuf, length);
|
||||||
|
|
||||||
|
memcpy(&strbuf->chars[strbuf->length], value, length);
|
||||||
|
strbuf->length += length;
|
||||||
|
strbuf->chars[strbuf->length] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ffStrbufAppend(FFstrbuf* __restrict strbuf, const FFstrbuf* __restrict value) {
|
||||||
|
assert(value != strbuf);
|
||||||
|
if (value == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ffStrbufAppendNS(strbuf, value->length, value->chars);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void ffStrbufRecalculateLength(FFstrbuf* strbuf) {
|
static inline void ffStrbufRecalculateLength(FFstrbuf* strbuf) {
|
||||||
strbuf->length = (uint32_t) strlen(strbuf->chars);
|
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);
|
assert(strbuf != nullptr);
|
||||||
|
|
||||||
if (value == NULL) {
|
if (value == nullptr) {
|
||||||
ffStrbufClear(strbuf);
|
ffStrbufClear(strbuf);
|
||||||
} else {
|
} else {
|
||||||
ffStrbufSetNS(strbuf, (uint32_t) strlen(value), value);
|
ffStrbufSetNS(strbuf, (uint32_t) strlen(value), value);
|
||||||
@@ -244,7 +271,7 @@ static inline void ffStrbufSetS(FFstrbuf* strbuf, const char* value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline bool ffStrbufSetJsonVal(FFstrbuf* strbuf, yyjson_val* jsonVal) {
|
static inline bool ffStrbufSetJsonVal(FFstrbuf* strbuf, yyjson_val* jsonVal) {
|
||||||
assert(strbuf != NULL);
|
assert(strbuf != nullptr);
|
||||||
|
|
||||||
if (yyjson_is_str(jsonVal)) {
|
if (yyjson_is_str(jsonVal)) {
|
||||||
ffStrbufSetNS(strbuf, (uint32_t) unsafe_yyjson_get_len(jsonVal), unsafe_yyjson_get_str(jsonVal));
|
ffStrbufSetNS(strbuf, (uint32_t) unsafe_yyjson_get_len(jsonVal), unsafe_yyjson_get_str(jsonVal));
|
||||||
@@ -256,7 +283,7 @@ static inline bool ffStrbufSetJsonVal(FFstrbuf* strbuf, yyjson_val* jsonVal) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void ffStrbufAppendS(FFstrbuf* strbuf, const char* value) {
|
static inline void ffStrbufAppendS(FFstrbuf* strbuf, const char* value) {
|
||||||
if (value == NULL) {
|
if (value == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ffStrbufAppendNS(strbuf, (uint32_t) strlen(value), value);
|
ffStrbufAppendNS(strbuf, (uint32_t) strlen(value), value);
|
||||||
@@ -276,7 +303,7 @@ static inline void ffStrbufInit(FFstrbuf* strbuf) {
|
|||||||
strbuf->chars = CHAR_NULL_PTR;
|
strbuf->chars = CHAR_NULL_PTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_A_NODISCARD static inline FFstrbuf ffStrbufCreate(void) {
|
[[nodiscard]] static inline FFstrbuf ffStrbufCreate(void) {
|
||||||
FFstrbuf strbuf;
|
FFstrbuf strbuf;
|
||||||
ffStrbufInit(&strbuf);
|
ffStrbufInit(&strbuf);
|
||||||
return strbuf;
|
return strbuf;
|
||||||
@@ -293,7 +320,7 @@ static inline void ffStrbufInitStatic(FFstrbuf* strbuf, const char* str) {
|
|||||||
strbuf->chars = (char*) str;
|
strbuf->chars = (char*) str;
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_A_NODISCARD static inline FFstrbuf ffStrbufCreateStatic(const char* str) {
|
[[nodiscard]] static inline FFstrbuf ffStrbufCreateStatic(const char* str) {
|
||||||
FFstrbuf strbuf;
|
FFstrbuf strbuf;
|
||||||
ffStrbufInitStatic(&strbuf, str);
|
ffStrbufInitStatic(&strbuf, str);
|
||||||
return strbuf;
|
return strbuf;
|
||||||
@@ -304,7 +331,7 @@ static inline void ffStrbufSetStatic(FFstrbuf* strbuf, const char* value) {
|
|||||||
free(strbuf->chars);
|
free(strbuf->chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value != NULL) {
|
if (value != nullptr) {
|
||||||
ffStrbufInitStatic(strbuf, value);
|
ffStrbufInitStatic(strbuf, value);
|
||||||
} else {
|
} else {
|
||||||
ffStrbufInit(strbuf);
|
ffStrbufInit(strbuf);
|
||||||
@@ -316,7 +343,7 @@ static inline void ffStrbufInitNS(FFstrbuf* strbuf, uint32_t length, const char*
|
|||||||
ffStrbufAppendNS(strbuf, length, str);
|
ffStrbufAppendNS(strbuf, length, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_A_NODISCARD static inline FFstrbuf ffStrbufCreateNS(uint32_t length, const char* str) {
|
[[nodiscard]] static inline FFstrbuf ffStrbufCreateNS(uint32_t length, const char* str) {
|
||||||
FFstrbuf strbuf;
|
FFstrbuf strbuf;
|
||||||
ffStrbufInitNS(&strbuf, length, str);
|
ffStrbufInitNS(&strbuf, length, str);
|
||||||
return strbuf;
|
return strbuf;
|
||||||
@@ -332,121 +359,113 @@ static inline void ffStrbufInitS(FFstrbuf* strbuf, const char* str) {
|
|||||||
ffStrbufAppendS(strbuf, str);
|
ffStrbufAppendS(strbuf, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_A_NODISCARD static inline FFstrbuf ffStrbufCreateS(const char* str) {
|
[[nodiscard]] static inline FFstrbuf ffStrbufCreateS(const char* str) {
|
||||||
FFstrbuf strbuf;
|
FFstrbuf strbuf;
|
||||||
ffStrbufInitS(&strbuf, str);
|
ffStrbufInitS(&strbuf, str);
|
||||||
return strbuf;
|
return strbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ffStrbufAppend(FFstrbuf* __restrict strbuf, const FFstrbuf* __restrict value) {
|
|
||||||
assert(value != strbuf);
|
|
||||||
if (value == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ffStrbufAppendNS(strbuf, value->length, value->chars);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void ffStrbufPrepend(FFstrbuf* strbuf, FFstrbuf* value) {
|
static inline void ffStrbufPrepend(FFstrbuf* strbuf, FFstrbuf* value) {
|
||||||
if (value == NULL) {
|
if (value == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ffStrbufPrependNS(strbuf, value->length, value->chars);
|
ffStrbufPrependNS(strbuf, value->length, value->chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ffStrbufPrependS(FFstrbuf* strbuf, const char* value) {
|
static inline void ffStrbufPrependS(FFstrbuf* strbuf, const char* value) {
|
||||||
if (value == NULL) {
|
if (value == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ffStrbufPrependNS(strbuf, (uint32_t) strlen(value), value);
|
ffStrbufPrependNS(strbuf, (uint32_t) strlen(value), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD int ffStrbufComp(const FFstrbuf* strbuf, const FFstrbuf* comp) {
|
[[nodiscard]] static inline int ffStrbufComp(const FFstrbuf* strbuf, const FFstrbuf* comp) {
|
||||||
uint32_t length = strbuf->length > comp->length ? comp->length : strbuf->length;
|
uint32_t length = strbuf->length > comp->length ? comp->length : strbuf->length;
|
||||||
return memcmp(strbuf->chars, comp->chars, length + 1);
|
return memcmp(strbuf->chars, comp->chars, length + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD bool ffStrbufEqual(const FFstrbuf* strbuf, const FFstrbuf* comp) {
|
[[nodiscard]] static inline bool ffStrbufEqual(const FFstrbuf* strbuf, const FFstrbuf* comp) {
|
||||||
return ffStrbufComp(strbuf, comp) == 0;
|
return ffStrbufComp(strbuf, comp) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD int ffStrbufCompS(const FFstrbuf* strbuf, const char* comp) {
|
[[nodiscard]] static inline int ffStrbufCompS(const FFstrbuf* strbuf, const char* comp) {
|
||||||
return strcmp(strbuf->chars, comp);
|
return strcmp(strbuf->chars, comp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD bool ffStrbufEqualS(const FFstrbuf* strbuf, const char* comp) {
|
[[nodiscard]] static inline bool ffStrbufEqualS(const FFstrbuf* strbuf, const char* comp) {
|
||||||
return ffStrbufCompS(strbuf, comp) == 0;
|
return ffStrbufCompS(strbuf, comp) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD int ffStrbufIgnCaseCompS(const FFstrbuf* strbuf, const char* comp) {
|
[[nodiscard]] static inline int ffStrbufIgnCaseCompS(const FFstrbuf* strbuf, const char* comp) {
|
||||||
return strcasecmp(strbuf->chars, comp);
|
return strcasecmp(strbuf->chars, comp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD bool ffStrbufIgnCaseEqualS(const FFstrbuf* strbuf, const char* comp) {
|
[[nodiscard]] static inline bool ffStrbufIgnCaseEqualS(const FFstrbuf* strbuf, const char* comp) {
|
||||||
return ffStrbufIgnCaseCompS(strbuf, comp) == 0;
|
return ffStrbufIgnCaseCompS(strbuf, comp) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD int ffStrbufIgnCaseComp(const FFstrbuf* strbuf, const FFstrbuf* comp) {
|
[[nodiscard]] static inline int ffStrbufIgnCaseComp(const FFstrbuf* strbuf, const FFstrbuf* comp) {
|
||||||
return ffStrbufIgnCaseCompS(strbuf, comp->chars);
|
return ffStrbufIgnCaseCompS(strbuf, comp->chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD bool ffStrbufIgnCaseEqual(const FFstrbuf* strbuf, const FFstrbuf* comp) {
|
[[nodiscard]] static inline bool ffStrbufIgnCaseEqual(const FFstrbuf* strbuf, const FFstrbuf* comp) {
|
||||||
return ffStrbufIgnCaseComp(strbuf, comp) == 0;
|
return ffStrbufIgnCaseComp(strbuf, comp) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD bool ffStrbufContainC(const FFstrbuf* strbuf, char c) {
|
[[nodiscard]] static inline bool ffStrbufContainC(const FFstrbuf* strbuf, char c) {
|
||||||
return memchr(strbuf->chars, c, strbuf->length) != NULL;
|
return memchr(strbuf->chars, c, strbuf->length) != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD bool ffStrbufContainS(const FFstrbuf* strbuf, const char* str) {
|
[[nodiscard]] static inline bool ffStrbufContainS(const FFstrbuf* strbuf, const char* str) {
|
||||||
return strstr(strbuf->chars, str) != NULL;
|
return strstr(strbuf->chars, str) != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD bool ffStrbufContain(const FFstrbuf* strbuf, const FFstrbuf* str) {
|
[[nodiscard]] static inline bool ffStrbufContain(const FFstrbuf* strbuf, const FFstrbuf* str) {
|
||||||
return ffStrbufContainS(strbuf, str->chars);
|
return ffStrbufContainS(strbuf, str->chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD bool ffStrbufContainIgnCaseS(const FFstrbuf* strbuf, const char* str) {
|
[[nodiscard]] static inline bool ffStrbufContainIgnCaseS(const FFstrbuf* strbuf, const char* str) {
|
||||||
return strcasestr(strbuf->chars, str) != NULL;
|
return strcasestr(strbuf->chars, str) != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD bool ffStrbufContainIgnCase(const FFstrbuf* strbuf, const FFstrbuf* str) {
|
[[nodiscard]] static inline bool ffStrbufContainIgnCase(const FFstrbuf* strbuf, const FFstrbuf* str) {
|
||||||
return ffStrbufContainIgnCaseS(strbuf, str->chars);
|
return ffStrbufContainIgnCaseS(strbuf, str->chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_A_NODISCARD static inline uint32_t ffStrbufNextIndexC(const FFstrbuf* strbuf, uint32_t start, char c) {
|
[[nodiscard]] static inline uint32_t ffStrbufNextIndexC(const FFstrbuf* strbuf, uint32_t start, char c) {
|
||||||
assert(start <= strbuf->length);
|
assert(start <= strbuf->length);
|
||||||
|
|
||||||
const char* ptr = (const char*) memchr(strbuf->chars + start, c, strbuf->length - start);
|
const char* ptr = (const char*) memchr(strbuf->chars + start, c, strbuf->length - start);
|
||||||
return ptr ? (uint32_t) (ptr - strbuf->chars) : strbuf->length;
|
return ptr ? (uint32_t) (ptr - strbuf->chars) : strbuf->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_A_NODISCARD static inline uint32_t ffStrbufNextIndexS(const FFstrbuf* strbuf, uint32_t start, const char* str) {
|
[[nodiscard]] static inline uint32_t ffStrbufNextIndexS(const FFstrbuf* strbuf, uint32_t start, const char* str) {
|
||||||
assert(start <= strbuf->length);
|
assert(start <= strbuf->length);
|
||||||
|
|
||||||
const char* ptr = strstr(strbuf->chars + start, str);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_A_NODISCARD static inline uint32_t ffStrbufPreviousIndexC(const FFstrbuf* strbuf, uint32_t start, char c) {
|
[[nodiscard]] static inline uint32_t ffStrbufPreviousIndexC(const FFstrbuf* strbuf, uint32_t start, char c) {
|
||||||
assert(start <= strbuf->length);
|
assert(start <= strbuf->length);
|
||||||
|
|
||||||
const char* ptr = (const char*) memrchr(strbuf->chars, c, start + 1);
|
const char* ptr = (const char*) memrchr(strbuf->chars, c, start + 1);
|
||||||
return ptr ? (uint32_t) (ptr - strbuf->chars) : strbuf->length;
|
return ptr ? (uint32_t) (ptr - strbuf->chars) : strbuf->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD uint32_t ffStrbufFirstIndexC(const FFstrbuf* strbuf, char c) {
|
[[nodiscard]] static inline uint32_t ffStrbufFirstIndexC(const FFstrbuf* strbuf, char c) {
|
||||||
return ffStrbufNextIndexC(strbuf, 0, c);
|
return ffStrbufNextIndexC(strbuf, 0, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD uint32_t ffStrbufFirstIndex(const FFstrbuf* strbuf, const FFstrbuf* searched) {
|
[[nodiscard]] static inline uint32_t ffStrbufFirstIndex(const FFstrbuf* strbuf, const FFstrbuf* searched) {
|
||||||
return ffStrbufNextIndexS(strbuf, 0, searched->chars);
|
return ffStrbufNextIndexS(strbuf, 0, searched->chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD uint32_t ffStrbufFirstIndexS(const FFstrbuf* strbuf, const char* str) {
|
[[nodiscard]] static inline uint32_t ffStrbufFirstIndexS(const FFstrbuf* strbuf, const char* str) {
|
||||||
return ffStrbufNextIndexS(strbuf, 0, str);
|
return ffStrbufNextIndexS(strbuf, 0, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD uint32_t ffStrbufLastIndexC(const FFstrbuf* strbuf, char c) {
|
[[nodiscard]] static inline uint32_t ffStrbufLastIndexC(const FFstrbuf* strbuf, char c) {
|
||||||
if (strbuf->length == 0) {
|
if (strbuf->length == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -462,11 +481,11 @@ static inline bool ffStrbufSubstrBeforeLastC(FFstrbuf* strbuf, char c) {
|
|||||||
return ffStrbufSubstrBefore(strbuf, ffStrbufLastIndexC(strbuf, c));
|
return ffStrbufSubstrBefore(strbuf, ffStrbufLastIndexC(strbuf, c));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD bool ffStrbufStartsWithC(const FFstrbuf* strbuf, char c) {
|
[[nodiscard]] static inline bool ffStrbufStartsWithC(const FFstrbuf* strbuf, char c) {
|
||||||
return strbuf->chars[0] == c;
|
return strbuf->chars[0] == c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD bool ffStrbufStartsWithSN(const FFstrbuf* strbuf, const char* start, uint32_t length) {
|
[[nodiscard]] static inline bool ffStrbufStartsWithSN(const FFstrbuf* strbuf, const char* start, uint32_t length) {
|
||||||
if (length > strbuf->length) {
|
if (length > strbuf->length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -474,34 +493,34 @@ static inline FF_A_NODISCARD bool ffStrbufStartsWithSN(const FFstrbuf* strbuf, c
|
|||||||
return memcmp(strbuf->chars, start, length) == 0;
|
return memcmp(strbuf->chars, start, length) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD bool ffStrbufStartsWithS(const FFstrbuf* strbuf, const char* start) {
|
[[nodiscard]] static inline bool ffStrbufStartsWithS(const FFstrbuf* strbuf, const char* start) {
|
||||||
return ffStrbufStartsWithSN(strbuf, start, (uint32_t) strlen(start));
|
return ffStrbufStartsWithSN(strbuf, start, (uint32_t) strlen(start));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD bool ffStrbufStartsWith(const FFstrbuf* strbuf, const FFstrbuf* start) {
|
[[nodiscard]] static inline bool ffStrbufStartsWith(const FFstrbuf* strbuf, const FFstrbuf* start) {
|
||||||
return ffStrbufStartsWithSN(strbuf, start->chars, start->length);
|
return ffStrbufStartsWithSN(strbuf, start->chars, start->length);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD bool ffStrbufStartsWithIgnCaseNS(const FFstrbuf* strbuf, uint32_t length, const char* start) {
|
[[nodiscard]] static inline bool ffStrbufStartsWithIgnCaseNS(const FFstrbuf* strbuf, uint32_t length, const char* start) {
|
||||||
if (length > strbuf->length) {
|
if (length > strbuf->length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return strncasecmp(strbuf->chars, start, length) == 0;
|
return strncasecmp(strbuf->chars, start, length) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD bool ffStrbufStartsWithIgnCaseS(const FFstrbuf* strbuf, const char* start) {
|
[[nodiscard]] static inline bool ffStrbufStartsWithIgnCaseS(const FFstrbuf* strbuf, const char* start) {
|
||||||
return ffStrbufStartsWithIgnCaseNS(strbuf, (uint32_t) strlen(start), start);
|
return ffStrbufStartsWithIgnCaseNS(strbuf, (uint32_t) strlen(start), start);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD bool ffStrbufStartsWithIgnCase(const FFstrbuf* strbuf, const FFstrbuf* start) {
|
[[nodiscard]] static inline bool ffStrbufStartsWithIgnCase(const FFstrbuf* strbuf, const FFstrbuf* start) {
|
||||||
return ffStrbufStartsWithIgnCaseNS(strbuf, start->length, start->chars);
|
return ffStrbufStartsWithIgnCaseNS(strbuf, start->length, start->chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD bool ffStrbufEndsWithC(const FFstrbuf* strbuf, char c) {
|
[[nodiscard]] static inline bool ffStrbufEndsWithC(const FFstrbuf* strbuf, char c) {
|
||||||
return strbuf->length == 0 ? false : strbuf->chars[strbuf->length - 1] == c;
|
return strbuf->length == 0 ? false : strbuf->chars[strbuf->length - 1] == c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD bool ffStrbufEndsWithNS(const FFstrbuf* strbuf, uint32_t endLength, const char* end) {
|
[[nodiscard]] static inline bool ffStrbufEndsWithNS(const FFstrbuf* strbuf, uint32_t endLength, const char* end) {
|
||||||
if (endLength > strbuf->length) {
|
if (endLength > strbuf->length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -509,30 +528,30 @@ static inline FF_A_NODISCARD bool ffStrbufEndsWithNS(const FFstrbuf* strbuf, uin
|
|||||||
return memcmp(strbuf->chars + strbuf->length - endLength, end, endLength) == 0;
|
return memcmp(strbuf->chars + strbuf->length - endLength, end, endLength) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD bool ffStrbufEndsWithS(const FFstrbuf* strbuf, const char* end) {
|
[[nodiscard]] static inline bool ffStrbufEndsWithS(const FFstrbuf* strbuf, const char* end) {
|
||||||
return ffStrbufEndsWithNS(strbuf, (uint32_t) strlen(end), end);
|
return ffStrbufEndsWithNS(strbuf, (uint32_t) strlen(end), end);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD bool ffStrbufEndsWithFn(const FFstrbuf* strbuf, int (*const fn)(int)) {
|
[[nodiscard]] static inline bool ffStrbufEndsWithFn(const FFstrbuf* strbuf, int (*const fn)(int)) {
|
||||||
return strbuf->length == 0 ? false : fn(strbuf->chars[strbuf->length - 1]);
|
return strbuf->length == 0 ? false : fn(strbuf->chars[strbuf->length - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD bool ffStrbufEndsWith(const FFstrbuf* strbuf, const FFstrbuf* end) {
|
[[nodiscard]] static inline bool ffStrbufEndsWith(const FFstrbuf* strbuf, const FFstrbuf* end) {
|
||||||
return ffStrbufEndsWithNS(strbuf, end->length, end->chars);
|
return ffStrbufEndsWithNS(strbuf, end->length, end->chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD bool ffStrbufEndsWithIgnCaseNS(const FFstrbuf* strbuf, uint32_t endLength, const char* end) {
|
[[nodiscard]] static inline bool ffStrbufEndsWithIgnCaseNS(const FFstrbuf* strbuf, uint32_t endLength, const char* end) {
|
||||||
if (endLength > strbuf->length) {
|
if (endLength > strbuf->length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return strcasecmp(strbuf->chars + strbuf->length - endLength, end) == 0;
|
return strcasecmp(strbuf->chars + strbuf->length - endLength, end) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD bool ffStrbufEndsWithIgnCaseS(const FFstrbuf* strbuf, const char* end) {
|
[[nodiscard]] static inline bool ffStrbufEndsWithIgnCaseS(const FFstrbuf* strbuf, const char* end) {
|
||||||
return ffStrbufEndsWithIgnCaseNS(strbuf, (uint32_t) strlen(end), end);
|
return ffStrbufEndsWithIgnCaseNS(strbuf, (uint32_t) strlen(end), end);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FF_A_NODISCARD bool ffStrbufEndsWithIgnCase(const FFstrbuf* strbuf, const FFstrbuf* end) {
|
[[nodiscard]] static inline bool ffStrbufEndsWithIgnCase(const FFstrbuf* strbuf, const FFstrbuf* end) {
|
||||||
return ffStrbufEndsWithIgnCaseNS(strbuf, end->length, end->chars);
|
return ffStrbufEndsWithIgnCaseNS(strbuf, end->length, end->chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -578,7 +597,34 @@ static inline bool ffStrbufSeparatedContainIgnCase(const FFstrbuf* strbuf, const
|
|||||||
return ffStrbufSeparatedContainIgnCaseNS(strbuf, comp->length, comp->chars, separator);
|
return ffStrbufSeparatedContainIgnCaseNS(strbuf, comp->length, comp->chars, separator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void ffStrbufWriteTo(const FFstrbuf* strbuf, FILE* file) {
|
||||||
|
fwrite(strbuf->chars, sizeof(*strbuf->chars), strbuf->length, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ffStrbufPutTo(const FFstrbuf* strbuf, FILE* file) {
|
||||||
|
ffStrbufWriteTo(strbuf, file);
|
||||||
|
fputc('\n', file);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] static inline double ffStrbufToDouble(const FFstrbuf* strbuf, double defaultValue) {
|
||||||
|
char* str_end;
|
||||||
|
double result = strtod(strbuf->chars, &str_end);
|
||||||
|
return str_end == strbuf->chars ? defaultValue : result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] static inline uint64_t ffStrbufToUInt(const FFstrbuf* strbuf, uint64_t defaultValue) {
|
||||||
|
char* str_end;
|
||||||
|
unsigned long long result = strtoull(strbuf->chars, &str_end, 10);
|
||||||
|
return str_end == strbuf->chars ? defaultValue : (uint64_t) result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] static inline int64_t ffStrbufToSInt(const FFstrbuf* strbuf, int64_t defaultValue) {
|
||||||
|
char* str_end;
|
||||||
|
long long result = strtoll(strbuf->chars, &str_end, 10);
|
||||||
|
return str_end == strbuf->chars ? defaultValue : (int64_t) result;
|
||||||
|
}
|
||||||
|
|
||||||
// Returns true if the strbuf is modified
|
// Returns true if the strbuf is modified
|
||||||
bool ffStrbufDecodeHexEscapeSequences(FFstrbuf* strbuf);
|
bool ffStrbufDecodeHexEscapeSequences(FFstrbuf* strbuf);
|
||||||
|
|
||||||
#define FF_STRBUF_AUTO_DESTROY FFstrbuf FF_A_CLEANUP(ffStrbufDestroy)
|
#define FF_STRBUF_AUTO_DESTROY [[gnu::cleanup(ffStrbufDestroy)]] FFstrbuf
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ const char* ffCfNumGetInt64(CFTypeRef cf, int64_t* result) {
|
|||||||
if (!CFNumberGetValue((CFNumberRef) cf, kCFNumberSInt64Type, result)) {
|
if (!CFNumberGetValue((CFNumberRef) cf, kCFNumberSInt64Type, result)) {
|
||||||
return "Number type is not SInt64";
|
return "Number type is not SInt64";
|
||||||
}
|
}
|
||||||
return NULL;
|
return nullptr;
|
||||||
} else if (CFGetTypeID(cf) == CFDataGetTypeID()) {
|
} else if (CFGetTypeID(cf) == CFDataGetTypeID()) {
|
||||||
if (CFDataGetLength((CFDataRef) cf) != sizeof(int64_t)) {
|
if (CFDataGetLength((CFDataRef) cf) != sizeof(int64_t)) {
|
||||||
return "Data length is not 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 nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "TypeID is neither 'CFNumber' nor 'CFData'";
|
return "TypeID is neither 'CFNumber' nor 'CFData'";
|
||||||
@@ -22,13 +22,13 @@ const char* ffCfNumGetInt(CFTypeRef cf, int32_t* result) {
|
|||||||
if (!CFNumberGetValue((CFNumberRef) cf, kCFNumberSInt32Type, result)) {
|
if (!CFNumberGetValue((CFNumberRef) cf, kCFNumberSInt32Type, result)) {
|
||||||
return "Number type is not SInt32";
|
return "Number type is not SInt32";
|
||||||
}
|
}
|
||||||
return NULL;
|
return nullptr;
|
||||||
} else if (CFGetTypeID(cf) == CFDataGetTypeID()) {
|
} else if (CFGetTypeID(cf) == CFDataGetTypeID()) {
|
||||||
if (CFDataGetLength((CFDataRef) cf) != sizeof(*result)) {
|
if (CFDataGetLength((CFDataRef) cf) != sizeof(*result)) {
|
||||||
return "Data length is not sizeof(int32_t)";
|
return "Data length is not sizeof(int32_t)";
|
||||||
}
|
}
|
||||||
CFDataGetBytes((CFDataRef) cf, CFRangeMake(0, sizeof(*result)), (uint8_t*) result);
|
CFDataGetBytes((CFDataRef) cf, CFRangeMake(0, sizeof(*result)), (uint8_t*) result);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "TypeID is neither 'CFNumber' nor 'CFData'";
|
return "TypeID is neither 'CFNumber' nor 'CFData'";
|
||||||
@@ -40,7 +40,7 @@ const char* ffCfNumGetDouble(CFTypeRef cf, double* result) {
|
|||||||
!CFNumberGetValue((CFNumberRef) cf, kCFNumberFloatType, result)) {
|
!CFNumberGetValue((CFNumberRef) cf, kCFNumberFloatType, result)) {
|
||||||
return "Number type is not Double or Float";
|
return "Number type is not Double or Float";
|
||||||
}
|
}
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "TypeID is neither 'CFNumber'";
|
return "TypeID is neither 'CFNumber'";
|
||||||
@@ -54,13 +54,13 @@ const char* ffCfDateGetEpoch(CFTypeRef cf, uint64_t* result) {
|
|||||||
CFAbsoluteTime absTime = CFDateGetAbsoluteTime((CFDateRef) cf);
|
CFAbsoluteTime absTime = CFDateGetAbsoluteTime((CFDateRef) cf);
|
||||||
// Convert from seconds to milliseconds and add the difference between 1970 and 2001 in milliseconds
|
// Convert from seconds to milliseconds and add the difference between 1970 and 2001 in milliseconds
|
||||||
*result = (uint64_t) ((absTime + 978307200 /*kCFAbsoluteTimeIntervalSince1970*/) * 1000);
|
*result = (uint64_t) ((absTime + 978307200 /*kCFAbsoluteTimeIntervalSince1970*/) * 1000);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ffCfStrGetString(CFTypeRef cf, FFstrbuf* result) {
|
const char* ffCfStrGetString(CFTypeRef cf, FFstrbuf* result) {
|
||||||
ffStrbufClear(result);
|
ffStrbufClear(result);
|
||||||
if (!cf) {
|
if (!cf) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CFGetTypeID(cf) == CFStringGetTypeID()) {
|
if (CFGetTypeID(cf) == CFStringGetTypeID()) {
|
||||||
@@ -72,7 +72,7 @@ const char* ffCfStrGetString(CFTypeRef cf, FFstrbuf* result) {
|
|||||||
} else {
|
} else {
|
||||||
uint32_t length = (uint32_t) CFStringGetLength(cfStr);
|
uint32_t length = (uint32_t) CFStringGetLength(cfStr);
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
ffStrbufEnsureFixedLengthFree(result, (uint32_t) CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8));
|
ffStrbufEnsureFixedLengthFree(result, (uint32_t) CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8));
|
||||||
if (!CFStringGetCString(cfStr, result->chars, result->allocated, kCFStringEncodingUTF8)) {
|
if (!CFStringGetCString(cfStr, result->chars, result->allocated, kCFStringEncodingUTF8)) {
|
||||||
@@ -86,7 +86,7 @@ const char* ffCfStrGetString(CFTypeRef cf, FFstrbuf* result) {
|
|||||||
CFDataRef cfData = (CFDataRef) cf;
|
CFDataRef cfData = (CFDataRef) cf;
|
||||||
uint32_t length = (uint32_t) CFDataGetLength(cfData);
|
uint32_t length = (uint32_t) CFDataGetLength(cfData);
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
ffStrbufEnsureFixedLengthFree(result, length + 1);
|
ffStrbufEnsureFixedLengthFree(result, length + 1);
|
||||||
CFDataGetBytes(cfData, CFRangeMake(0, length), (uint8_t*) result->chars);
|
CFDataGetBytes(cfData, CFRangeMake(0, length), (uint8_t*) result->chars);
|
||||||
@@ -96,20 +96,20 @@ const char* ffCfStrGetString(CFTypeRef cf, FFstrbuf* result) {
|
|||||||
return "TypeID is neither 'CFString' nor 'CFData'";
|
return "TypeID is neither 'CFString' nor 'CFData'";
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ffCfDataGetDataAsString(CFTypeRef cf, FFstrbuf* result) {
|
const char* ffCfDataGetDataAsString(CFTypeRef cf, FFstrbuf* result) {
|
||||||
ffStrbufClear(result);
|
ffStrbufClear(result);
|
||||||
if (!cf) {
|
if (!cf) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CFGetTypeID(cf) == CFDataGetTypeID()) {
|
if (CFGetTypeID(cf) == CFDataGetTypeID()) {
|
||||||
CFDataRef cfData = (CFDataRef) cf;
|
CFDataRef cfData = (CFDataRef) cf;
|
||||||
uint32_t length = (uint32_t) CFDataGetLength(cfData);
|
uint32_t length = (uint32_t) CFDataGetLength(cfData);
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
ffStrbufEnsureFixedLengthFree(result, length + 1);
|
ffStrbufEnsureFixedLengthFree(result, length + 1);
|
||||||
CFDataGetBytes(cfData, CFRangeMake(0, length), (uint8_t*) result->chars);
|
CFDataGetBytes(cfData, CFRangeMake(0, length), (uint8_t*) result->chars);
|
||||||
@@ -119,12 +119,12 @@ const char* ffCfDataGetDataAsString(CFTypeRef cf, FFstrbuf* result) {
|
|||||||
return "TypeID is not 'CFData'";
|
return "TypeID is not 'CFData'";
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ffCfDictGetString(CFDictionaryRef dict, CFStringRef key, FFstrbuf* result) {
|
const char* ffCfDictGetString(CFDictionaryRef dict, CFStringRef key, FFstrbuf* result) {
|
||||||
CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
|
CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
|
||||||
if (cf == NULL) {
|
if (cf == nullptr) {
|
||||||
return "CFDictionaryGetValue() failed";
|
return "CFDictionaryGetValue() failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@ const char* ffCfDictGetString(CFDictionaryRef dict, CFStringRef key, FFstrbuf* r
|
|||||||
|
|
||||||
const char* ffCfDictGetDataAsString(CFDictionaryRef dict, CFStringRef key, FFstrbuf* result) {
|
const char* ffCfDictGetDataAsString(CFDictionaryRef dict, CFStringRef key, FFstrbuf* result) {
|
||||||
CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
|
CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
|
||||||
if (cf == NULL) {
|
if (cf == nullptr) {
|
||||||
return "CFDictionaryGetValue() failed";
|
return "CFDictionaryGetValue() failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +142,7 @@ const char* ffCfDictGetDataAsString(CFDictionaryRef dict, CFStringRef key, FFstr
|
|||||||
|
|
||||||
const char* ffCfDictGetBool(CFDictionaryRef dict, CFStringRef key, bool* result) {
|
const char* ffCfDictGetBool(CFDictionaryRef dict, CFStringRef key, bool* result) {
|
||||||
CFBooleanRef cf = (CFBooleanRef) CFDictionaryGetValue(dict, key);
|
CFBooleanRef cf = (CFBooleanRef) CFDictionaryGetValue(dict, key);
|
||||||
if (cf == NULL) {
|
if (cf == nullptr) {
|
||||||
return "CFDictionaryGetValue() failed";
|
return "CFDictionaryGetValue() failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,12 +151,12 @@ const char* ffCfDictGetBool(CFDictionaryRef dict, CFStringRef key, bool* result)
|
|||||||
}
|
}
|
||||||
|
|
||||||
*result = CFBooleanGetValue(cf);
|
*result = CFBooleanGetValue(cf);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ffCfDictGetInt(CFDictionaryRef dict, CFStringRef key, int* result) {
|
const char* ffCfDictGetInt(CFDictionaryRef dict, CFStringRef key, int* result) {
|
||||||
CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
|
CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
|
||||||
if (cf == NULL) {
|
if (cf == nullptr) {
|
||||||
return "CFDictionaryGetValue() failed";
|
return "CFDictionaryGetValue() failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,7 +165,7 @@ const char* ffCfDictGetInt(CFDictionaryRef dict, CFStringRef key, int* result) {
|
|||||||
|
|
||||||
const char* ffCfDictGetInt64(CFDictionaryRef dict, CFStringRef key, int64_t* result) {
|
const char* ffCfDictGetInt64(CFDictionaryRef dict, CFStringRef key, int64_t* result) {
|
||||||
CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
|
CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
|
||||||
if (cf == NULL) {
|
if (cf == nullptr) {
|
||||||
return "CFDictionaryGetValue() failed";
|
return "CFDictionaryGetValue() failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +174,7 @@ const char* ffCfDictGetInt64(CFDictionaryRef dict, CFStringRef key, int64_t* res
|
|||||||
|
|
||||||
const char* ffCfDictGetDouble(CFDictionaryRef dict, CFStringRef key, double* result) {
|
const char* ffCfDictGetDouble(CFDictionaryRef dict, CFStringRef key, double* result) {
|
||||||
CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
|
CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
|
||||||
if (cf == NULL) {
|
if (cf == nullptr) {
|
||||||
return "CFDictionaryGetValue() failed";
|
return "CFDictionaryGetValue() failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +183,7 @@ const char* ffCfDictGetDouble(CFDictionaryRef dict, CFStringRef key, double* res
|
|||||||
|
|
||||||
const char* ffCfDictGetData(CFDictionaryRef dict, CFStringRef key, uint32_t offset, uint32_t size, uint8_t* result, uint32_t* length) {
|
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);
|
CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
|
||||||
if (cf == NULL) {
|
if (cf == nullptr) {
|
||||||
return "CFDictionaryGetValue() failed";
|
return "CFDictionaryGetValue() failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,22 +202,22 @@ const char* ffCfDictGetData(CFDictionaryRef dict, CFStringRef key, uint32_t offs
|
|||||||
}
|
}
|
||||||
|
|
||||||
CFDataGetBytes((CFDataRef) cf, CFRangeMake(offset, size), result);
|
CFDataGetBytes((CFDataRef) cf, CFRangeMake(offset, size), result);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ffCfDictGetDict(CFDictionaryRef dict, CFStringRef key, CFDictionaryRef* result) {
|
const char* ffCfDictGetDict(CFDictionaryRef dict, CFStringRef key, CFDictionaryRef* result) {
|
||||||
CFDictionaryRef cf = (CFDictionaryRef) CFDictionaryGetValue(dict, key);
|
CFDictionaryRef cf = (CFDictionaryRef) CFDictionaryGetValue(dict, key);
|
||||||
if (cf == NULL || CFGetTypeID(cf) != CFDictionaryGetTypeID()) {
|
if (cf == nullptr || CFGetTypeID(cf) != CFDictionaryGetTypeID()) {
|
||||||
return "TypeID is not 'CFDictionary'";
|
return "TypeID is not 'CFDictionary'";
|
||||||
}
|
}
|
||||||
|
|
||||||
*result = cf;
|
*result = cf;
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ffCfDictGetDateAsEpoch(CFDictionaryRef dict, CFStringRef key, uint64_t* result) {
|
const char* ffCfDictGetDateAsEpoch(CFDictionaryRef dict, CFStringRef key, uint64_t* result) {
|
||||||
CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
|
CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
|
||||||
if (cf == NULL) {
|
if (cf == nullptr) {
|
||||||
return "CFDictionaryGetValue() failed";
|
return "CFDictionaryGetValue() failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#include <CoreFoundation/CoreFoundation.h>
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
#include <IOKit/IOKitLib.h>
|
#include <IOKit/IOKitLib.h>
|
||||||
|
|
||||||
// Return error info if failed, NULL otherwise
|
// Return error info if failed, nullptr otherwise
|
||||||
const char* ffCfStrGetString(CFTypeRef cf, FFstrbuf* result);
|
const char* ffCfStrGetString(CFTypeRef cf, FFstrbuf* result);
|
||||||
const char* ffCfNumGetInt(CFTypeRef cf, int32_t* result);
|
const char* ffCfNumGetInt(CFTypeRef cf, int32_t* result);
|
||||||
const char* ffCfNumGetInt64(CFTypeRef cf, int64_t* result);
|
const char* ffCfNumGetInt64(CFTypeRef cf, int64_t* result);
|
||||||
@@ -32,7 +32,7 @@ static inline void cfReleaseWrapper(void* type) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FF_CFTYPE_AUTO_RELEASE FF_A_CLEANUP(cfReleaseWrapper)
|
#define FF_CFTYPE_AUTO_RELEASE [[gnu::cleanup(cfReleaseWrapper)]]
|
||||||
|
|
||||||
static inline void wrapIoObjectRelease(io_object_t* service) {
|
static inline void wrapIoObjectRelease(io_object_t* service) {
|
||||||
assert(service);
|
assert(service);
|
||||||
@@ -40,4 +40,4 @@ static inline void wrapIoObjectRelease(io_object_t* service) {
|
|||||||
IOObjectRelease(*service);
|
IOObjectRelease(*service);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#define FF_IOOBJECT_AUTO_RELEASE FF_A_CLEANUP(wrapIoObjectRelease)
|
#define FF_IOOBJECT_AUTO_RELEASE [[gnu::cleanup(wrapIoObjectRelease)]]
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ static const char* smcCall(io_connect_t conn, uint32_t selector, SmcKeyData_t* i
|
|||||||
if (IOConnectCallStructMethod(conn, selector, inputStructure, size, outputStructure, &size) != kIOReturnSuccess) {
|
if (IOConnectCallStructMethod(conn, selector, inputStructure, size, outputStructure, &size) != kIOReturnSuccess) {
|
||||||
return "IOConnectCallStructMethod(conn) failed";
|
return "IOConnectCallStructMethod(conn) failed";
|
||||||
}
|
}
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Provides key info, using a cache to dramatically improve the energy impact of smcFanControl
|
// Provides key info, using a cache to dramatically improve the energy impact of smcFanControl
|
||||||
@@ -103,7 +103,7 @@ static const char* smcGetKeyInfo(io_connect_t conn, const uint32_t key, SmcKeyDa
|
|||||||
}
|
}
|
||||||
|
|
||||||
*key_info = outputStructure.keyInfo;
|
*key_info = outputStructure.keyInfo;
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* smcReadSmcVal(io_connect_t conn, const UInt32Char_t key, SmcVal_t* val) {
|
static const char* smcReadSmcVal(io_connect_t conn, const UInt32Char_t key, SmcVal_t* val) {
|
||||||
@@ -130,7 +130,7 @@ static const char* smcReadSmcVal(io_connect_t conn, const UInt32Char_t key, SmcV
|
|||||||
|
|
||||||
memcpy(val->bytes, outputStructure.bytes, sizeof(outputStructure.bytes));
|
memcpy(val->bytes, outputStructure.bytes, sizeof(outputStructure.bytes));
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* smcOpen(io_connect_t* conn) {
|
static const char* smcOpen(io_connect_t* conn) {
|
||||||
@@ -143,13 +143,13 @@ static const char* smcOpen(io_connect_t* conn) {
|
|||||||
return "IOServiceOpen() failed";
|
return "IOServiceOpen() failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* smcReadValue(io_connect_t conn, const UInt32Char_t key, double* value) {
|
static const char* smcReadValue(io_connect_t conn, const UInt32Char_t key, double* value) {
|
||||||
SmcVal_t val = { 0 };
|
SmcVal_t val = { 0 };
|
||||||
const char* error = smcReadSmcVal(conn, key, &val);
|
const char* error = smcReadSmcVal(conn, key, &val);
|
||||||
if (error != NULL) {
|
if (error != nullptr) {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
if (val.dataSize == 0) {
|
if (val.dataSize == 0) {
|
||||||
@@ -270,7 +270,7 @@ static const char* smcReadValue(io_connect_t conn, const UInt32Char_t key, doubl
|
|||||||
default:
|
default:
|
||||||
return "Unsupported SMC data type";
|
return "Unsupported SMC data type";
|
||||||
}
|
}
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool detectTemp(io_connect_t conn, const char* sensor, double* sum) {
|
static bool detectTemp(io_connect_t conn, const char* sensor, double* sum) {
|
||||||
@@ -291,7 +291,7 @@ static io_connect_t conn;
|
|||||||
|
|
||||||
const char* ffDetectSmcSpecificTemp(const char* sensor, double* result) {
|
const char* ffDetectSmcSpecificTemp(const char* sensor, double* result) {
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
if (smcOpen(&conn) != NULL) {
|
if (smcOpen(&conn) != nullptr) {
|
||||||
conn = (io_connect_t) -1;
|
conn = (io_connect_t) -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -303,12 +303,12 @@ const char* ffDetectSmcSpecificTemp(const char* sensor, double* result) {
|
|||||||
return "Could not read SMC temperature";
|
return "Could not read SMC temperature";
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ffDetectSmcTemps(enum FFTempType type, double* result) {
|
const char* ffDetectSmcTemps(enum FFTempType type, double* result) {
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
if (smcOpen(&conn) != NULL) {
|
if (smcOpen(&conn) != nullptr) {
|
||||||
conn = (io_connect_t) -1;
|
conn = (io_connect_t) -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -392,6 +392,27 @@ const char* ffDetectSmcTemps(enum FFTempType type, double* result) {
|
|||||||
count += detectTemp(conn, "Tp0e", result); // CPU performance core 8
|
count += detectTemp(conn, "Tp0e", result); // CPU performance core 8
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FF_TEMP_CPU_M5X:
|
||||||
|
count += detectTemp(conn, "Tp00", result); // CPU super core 1
|
||||||
|
count += detectTemp(conn, "Tp04", result); // CPU super core 2
|
||||||
|
count += detectTemp(conn, "Tp08", result); // CPU super core 3
|
||||||
|
count += detectTemp(conn, "Tp0C", result); // CPU super core 4
|
||||||
|
count += detectTemp(conn, "Tp0G", result); // CPU super core 5
|
||||||
|
count += detectTemp(conn, "Tp0K", result); // CPU super core 6
|
||||||
|
count += detectTemp(conn, "Tp0O", result); // CPU performance core 1
|
||||||
|
count += detectTemp(conn, "Tp0R", result); // CPU performance core 2
|
||||||
|
count += detectTemp(conn, "Tp0U", result); // CPU performance core 3
|
||||||
|
count += detectTemp(conn, "Tp0X", result); // CPU performance core 4
|
||||||
|
count += detectTemp(conn, "Tp0a", result); // CPU performance core 5
|
||||||
|
count += detectTemp(conn, "Tp0d", result); // CPU performance core 6
|
||||||
|
count += detectTemp(conn, "Tp0g", result); // CPU performance core 7
|
||||||
|
count += detectTemp(conn, "Tp0j", result); // CPU performance core 8
|
||||||
|
count += detectTemp(conn, "Tp0m", result); // CPU performance core 9
|
||||||
|
count += detectTemp(conn, "Tp0p", result); // CPU performance core 10
|
||||||
|
count += detectTemp(conn, "Tp0u", result); // CPU performance core 11
|
||||||
|
count += detectTemp(conn, "Tp0y", result); // CPU performance core 12
|
||||||
|
break;
|
||||||
|
|
||||||
case FF_TEMP_GPU_INTEL:
|
case FF_TEMP_GPU_INTEL:
|
||||||
count += detectTemp(conn, "TCGC", result); // GPU Intel Graphics
|
count += detectTemp(conn, "TCGC", result); // GPU Intel Graphics
|
||||||
goto gpu_unknown;
|
goto gpu_unknown;
|
||||||
@@ -442,6 +463,17 @@ const char* ffDetectSmcTemps(enum FFTempType type, double* result) {
|
|||||||
count += detectTemp(conn, "Tg0k", result); // GPU 8
|
count += detectTemp(conn, "Tg0k", result); // GPU 8
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FF_TEMP_GPU_M5X:
|
||||||
|
count += detectTemp(conn, "Tg0U", result); // GPU 1
|
||||||
|
count += detectTemp(conn, "Tg0X", result); // GPU 2
|
||||||
|
count += detectTemp(conn, "Tg0d", result); // GPU 3
|
||||||
|
count += detectTemp(conn, "Tg0g", result); // GPU 4
|
||||||
|
count += detectTemp(conn, "Tg0j", result); // GPU 5
|
||||||
|
count += detectTemp(conn, "Tg1Y", result); // GPU 6
|
||||||
|
count += detectTemp(conn, "Tg1c", result); // GPU 7
|
||||||
|
count += detectTemp(conn, "Tg1g", result); // GPU 8
|
||||||
|
break;
|
||||||
|
|
||||||
case FF_TEMP_BATTERY:
|
case FF_TEMP_BATTERY:
|
||||||
count += detectTemp(conn, "TB1T", result); // Battery
|
count += detectTemp(conn, "TB1T", result); // Battery
|
||||||
count += detectTemp(conn, "TB2T", result); // Battery
|
count += detectTemp(conn, "TB2T", result); // Battery
|
||||||
@@ -452,6 +484,9 @@ const char* ffDetectSmcTemps(enum FFTempType type, double* result) {
|
|||||||
count += detectTemp(conn, "Tm06", result); // Memory 2
|
count += detectTemp(conn, "Tm06", result); // Memory 2
|
||||||
count += detectTemp(conn, "Tm08", result); // Memory 3
|
count += detectTemp(conn, "Tm08", result); // Memory 3
|
||||||
count += detectTemp(conn, "Tm09", result); // Memory 4
|
count += detectTemp(conn, "Tm09", result); // Memory 4
|
||||||
|
count += detectTemp(conn, "Tm0p", result); // Memory Proximity 1 (M4)
|
||||||
|
count += detectTemp(conn, "Tm1p", result); // Memory Proximity 2 (M4)
|
||||||
|
count += detectTemp(conn, "Tm2p", result); // Memory Proximity 3 (M4)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -461,5 +496,5 @@ const char* ffDetectSmcTemps(enum FFTempType type, double* result) {
|
|||||||
|
|
||||||
*result /= count;
|
*result /= count;
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,12 +8,13 @@ typedef struct FFTempValue {
|
|||||||
double value;
|
double value;
|
||||||
} FFTempValue;
|
} FFTempValue;
|
||||||
|
|
||||||
enum FFTempType {
|
enum FFTempType: uint8_t {
|
||||||
FF_TEMP_CPU_X64,
|
FF_TEMP_CPU_X64,
|
||||||
FF_TEMP_CPU_M1X,
|
FF_TEMP_CPU_M1X,
|
||||||
FF_TEMP_CPU_M2X,
|
FF_TEMP_CPU_M2X,
|
||||||
FF_TEMP_CPU_M3X,
|
FF_TEMP_CPU_M3X,
|
||||||
FF_TEMP_CPU_M4X,
|
FF_TEMP_CPU_M4X,
|
||||||
|
FF_TEMP_CPU_M5X,
|
||||||
|
|
||||||
FF_TEMP_GPU_INTEL,
|
FF_TEMP_GPU_INTEL,
|
||||||
FF_TEMP_GPU_AMD,
|
FF_TEMP_GPU_AMD,
|
||||||
@@ -22,6 +23,7 @@ enum FFTempType {
|
|||||||
FF_TEMP_GPU_M2X,
|
FF_TEMP_GPU_M2X,
|
||||||
FF_TEMP_GPU_M3X,
|
FF_TEMP_GPU_M3X,
|
||||||
FF_TEMP_GPU_M4X,
|
FF_TEMP_GPU_M4X,
|
||||||
|
FF_TEMP_GPU_M5X,
|
||||||
|
|
||||||
FF_TEMP_BATTERY,
|
FF_TEMP_BATTERY,
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ bool ffGetAppNameAndVersion(const char* exePath, FFstrbuf* retName, FFstrbuf* re
|
|||||||
|
|
||||||
lastSlash -= strlen("MacOS");
|
lastSlash -= strlen("MacOS");
|
||||||
char infoPlistPath[PATH_MAX];
|
char infoPlistPath[PATH_MAX];
|
||||||
memcpy(infoPlistPath, exePath, lastSlash - exePath);
|
memcpy(infoPlistPath, exePath, (size_t) (lastSlash - exePath));
|
||||||
memcpy(infoPlistPath + (lastSlash - exePath), "Info.plist", sizeof("Info.plist")); // X.app/Contents/Info.plist
|
memcpy(infoPlistPath + (lastSlash - exePath), "Info.plist", sizeof("Info.plist")); // X.app/Contents/Info.plist
|
||||||
NSError* error;
|
NSError* error;
|
||||||
NSDictionary* dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL fileURLWithPath:@(infoPlistPath)]
|
NSDictionary* dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL fileURLWithPath:@(infoPlistPath)]
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ typedef struct FFArgBuffer {
|
|||||||
uint32_t length;
|
uint32_t length;
|
||||||
} FFArgBuffer;
|
} FFArgBuffer;
|
||||||
|
|
||||||
typedef enum FF_A_PACKED FFArgType {
|
typedef enum FFArgType: uint8_t {
|
||||||
FF_ARG_TYPE_NULL = 0,
|
FF_ARG_TYPE_NULL = 0,
|
||||||
FF_ARG_TYPE_UINT,
|
FF_ARG_TYPE_UINT,
|
||||||
FF_ARG_TYPE_UINT64,
|
FF_ARG_TYPE_UINT64,
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
#if !__cplusplus && FF_SUPPORTS_COUNT_OF
|
#if !__cplusplus && FF_SUPPORTS_COUNT_OF
|
||||||
#define ARRAY_SIZE(x) _Countof(x)
|
#define ARRAY_SIZE(x) _Countof(x)
|
||||||
#elif __has_builtin(__is_array)
|
#elif __has_builtin(__is_array)
|
||||||
#define ARRAY_SIZE(x) ({ static_assert(__is_array(__typeof__(x)), "Must be an array"); (uint32_t) (sizeof(x) / sizeof(*(x))); })
|
#define ARRAY_SIZE(x) ({ static_assert(__is_array(typeof(x)), "Must be an array"); (uint32_t) (sizeof(x) / sizeof(*(x))); })
|
||||||
#elif __has_builtin(__builtin_types_compatible_p)
|
#elif __has_builtin(__builtin_types_compatible_p)
|
||||||
#define ARRAY_SIZE(x) ({ static_assert(!__builtin_types_compatible_p(__typeof__(x), __typeof__(&*(x))), "Must not be a pointer"); (uint32_t) (sizeof(x) / sizeof(*(x))); })
|
#define ARRAY_SIZE(x) ({ static_assert(!__builtin_types_compatible_p(typeof(x), typeof(&*(x))), "Must not be a pointer"); (uint32_t) (sizeof(x) / sizeof(*(x))); })
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#ifndef ARRAY_SIZE
|
#ifndef ARRAY_SIZE
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef __has_attribute
|
|
||||||
#error Unsupported compiler
|
|
||||||
#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__))
|
|
||||||
#define FF_A_ALWAYS_INLINE __attribute__((__always_inline__))
|
|
||||||
#define FF_A_COLD __attribute__((__cold__))
|
|
||||||
+1
-1
@@ -11,7 +11,7 @@
|
|||||||
* @param userdata User-provided data passed to the callback function
|
* @param userdata User-provided data passed to the callback function
|
||||||
* @param minLength Minimum length of strings to extract
|
* @param minLength Minimum length of strings to extract
|
||||||
*
|
*
|
||||||
* @return NULL on success, error message on failure.
|
* @return nullptr on success, error message on failure.
|
||||||
* @note This function won't return an error if no strings are found.
|
* @note This function won't return an error if no strings are found.
|
||||||
* Always check if strings are correctly extracted after this function all.
|
* Always check if strings are correctly extracted after this function all.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -10,6 +10,16 @@
|
|||||||
#define FF_COLOR_MODE_HIDDEN "8;"
|
#define FF_COLOR_MODE_HIDDEN "8;"
|
||||||
#define FF_COLOR_MODE_STRIKETHROUGH "9;"
|
#define FF_COLOR_MODE_STRIKETHROUGH "9;"
|
||||||
|
|
||||||
|
#define FF_COLOR_MODE_RESET_ "0"
|
||||||
|
#define FF_COLOR_MODE_BOLD_ "1"
|
||||||
|
#define FF_COLOR_MODE_DIM_ "2"
|
||||||
|
#define FF_COLOR_MODE_ITALIC_ "3"
|
||||||
|
#define FF_COLOR_MODE_UNDERLINE_ "4"
|
||||||
|
#define FF_COLOR_MODE_BLINK_ "5"
|
||||||
|
#define FF_COLOR_MODE_INVERSE_ "7"
|
||||||
|
#define FF_COLOR_MODE_HIDDEN_ "8"
|
||||||
|
#define FF_COLOR_MODE_STRIKETHROUGH_ "9"
|
||||||
|
|
||||||
#define FF_COLOR_FG_BLACK "30"
|
#define FF_COLOR_FG_BLACK "30"
|
||||||
#define FF_COLOR_FG_RED "31"
|
#define FF_COLOR_FG_RED "31"
|
||||||
#define FF_COLOR_FG_GREEN "32"
|
#define FF_COLOR_FG_GREEN "32"
|
||||||
|
|||||||
+3
-3
@@ -26,7 +26,7 @@ typedef struct FFDBusData {
|
|||||||
DBusConnection* connection;
|
DBusConnection* connection;
|
||||||
} FFDBusData;
|
} 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 nullptr on success
|
||||||
bool ffDBusGetString(FFDBusData* dbus, DBusMessageIter* iter, FFstrbuf* result);
|
bool ffDBusGetString(FFDBusData* dbus, DBusMessageIter* iter, FFstrbuf* result);
|
||||||
bool ffDBusGetBool(FFDBusData* dbus, DBusMessageIter* iter, bool* result);
|
bool ffDBusGetBool(FFDBusData* dbus, DBusMessageIter* iter, bool* result);
|
||||||
bool ffDBusGetUint(FFDBusData* dbus, DBusMessageIter* iter, uint64_t* result);
|
bool ffDBusGetUint(FFDBusData* dbus, DBusMessageIter* iter, uint64_t* result);
|
||||||
@@ -38,9 +38,9 @@ bool ffDBusGetPropertyUint(FFDBusData* dbus, const char* busName, const char* ob
|
|||||||
void ffDBusDestroyData(FFDBusData* data);
|
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);
|
return ffDBusGetMethodReply(dbus, busName, objectPath, "org.freedesktop.DBus.Properties", "GetAll", interface, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FF_DBUS_AUTO_DESTROY_DATA FF_A_CLEANUP(ffDBusDestroyData)
|
#define FF_DBUS_AUTO_DESTROY_DATA [[gnu::cleanup(ffDBusDestroyData)]]
|
||||||
|
|
||||||
#endif // FF_HAVE_DBUS
|
#endif // FF_HAVE_DBUS
|
||||||
|
|||||||
+2
-2
@@ -6,11 +6,11 @@
|
|||||||
static inline const char* ffFindFileName(const char* file) {
|
static inline const char* ffFindFileName(const char* file) {
|
||||||
const char* lastSlash = __builtin_strrchr(file, '/');
|
const char* lastSlash = __builtin_strrchr(file, '/');
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (lastSlash == NULL) {
|
if (lastSlash == nullptr) {
|
||||||
lastSlash = __builtin_strrchr(file, '\\');
|
lastSlash = __builtin_strrchr(file, '\\');
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (lastSlash != NULL) {
|
if (lastSlash != nullptr) {
|
||||||
return lastSlash + 1;
|
return lastSlash + 1;
|
||||||
}
|
}
|
||||||
return file;
|
return file;
|
||||||
|
|||||||
+2
-1
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "common/FFstrbuf.h"
|
#include "common/FFstrbuf.h"
|
||||||
|
|
||||||
typedef enum FF_A_PACKED FFDataResultDocType {
|
typedef enum FFDataResultDocType: uint8_t {
|
||||||
FF_RESULT_DOC_TYPE_DEFAULT = 0,
|
FF_RESULT_DOC_TYPE_DEFAULT = 0,
|
||||||
FF_RESULT_DOC_TYPE_JSON,
|
FF_RESULT_DOC_TYPE_JSON,
|
||||||
FF_RESULT_DOC_TYPE_CONFIG,
|
FF_RESULT_DOC_TYPE_CONFIG,
|
||||||
@@ -19,4 +19,5 @@ typedef struct FFdata {
|
|||||||
FFstrbuf genConfigPath; // Path to generate configuration file
|
FFstrbuf genConfigPath; // Path to generate configuration file
|
||||||
FFDataResultDocType docType; // Type of result document
|
FFDataResultDocType docType; // Type of result document
|
||||||
bool configLoaded;
|
bool configLoaded;
|
||||||
|
bool genConfigInteractive; // `--gen-config` entered the interactive CUI
|
||||||
} FFdata;
|
} FFdata;
|
||||||
|
|||||||
+1
-1
@@ -21,5 +21,5 @@ void ffFontInitWithSpace(FFfont* font, const char* rawName);
|
|||||||
void ffFontDestroy(FFfont* font);
|
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);
|
ffFontInitValues(font, name, nullptr);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/ffdata.h"
|
||||||
|
|
||||||
|
// Runs the interactive config generation CUI.
|
||||||
|
//
|
||||||
|
// On success (the user saved the config), it sets `data->structure` to the user chosen
|
||||||
|
// module structure and `instance.config.logo.type` to the user chosen logo type, creates
|
||||||
|
// the result document and returns true. The caller is expected to call `writeConfigFile`.
|
||||||
|
// Returns false if the user quits without saving.
|
||||||
|
bool ffGenConfigInteractive(FFdata* data);
|
||||||
@@ -57,7 +57,7 @@ static void getExePath(FFPlatform* platform) {
|
|||||||
4,
|
4,
|
||||||
exePath,
|
exePath,
|
||||||
&exePathLen,
|
&exePathLen,
|
||||||
NULL,
|
nullptr,
|
||||||
0) < 0)
|
0) < 0)
|
||||||
exePathLen = 0;
|
exePathLen = 0;
|
||||||
else {
|
else {
|
||||||
@@ -68,7 +68,7 @@ static void getExePath(FFPlatform* platform) {
|
|||||||
// Current implementation uses argv[0], which can be easily spoofed.
|
// Current implementation uses argv[0], which can be easily spoofed.
|
||||||
// See #2195
|
// See #2195
|
||||||
size_t exePathLen = 0;
|
size_t exePathLen = 0;
|
||||||
kvm_t* kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, NULL);
|
kvm_t* kd = kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr);
|
||||||
if (kd) {
|
if (kd) {
|
||||||
int kpCount;
|
int kpCount;
|
||||||
struct kinfo_proc* kp = kvm_getprocs(kd, KERN_PROC_PID, (pid_t) platform->pid, sizeof(*kp), &kpCount);
|
struct kinfo_proc* kp = kvm_getprocs(kd, KERN_PROC_PID, (pid_t) platform->pid, sizeof(*kp), &kpCount);
|
||||||
@@ -77,7 +77,7 @@ static void getExePath(FFPlatform* platform) {
|
|||||||
if (argv && argv[0]) {
|
if (argv && argv[0]) {
|
||||||
char* arg0 = argv[0];
|
char* arg0 = argv[0];
|
||||||
if (arg0[0]) {
|
if (arg0[0]) {
|
||||||
if (strchr(arg0, '/') != NULL) // likely a path (absolute or relative)
|
if (strchr(arg0, '/') != nullptr) // likely a path (absolute or relative)
|
||||||
{
|
{
|
||||||
exePathLen = strlen(arg0);
|
exePathLen = strlen(arg0);
|
||||||
if (exePathLen < ARRAY_SIZE(exePath)) {
|
if (exePathLen < ARRAY_SIZE(exePath)) {
|
||||||
@@ -88,7 +88,7 @@ static void getExePath(FFPlatform* platform) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
FF_STRBUF_AUTO_DESTROY tmpPath = ffStrbufCreate();
|
FF_STRBUF_AUTO_DESTROY tmpPath = ffStrbufCreate();
|
||||||
if (ffFindExecutableInPath(arg0, &tmpPath) == NULL && tmpPath.length < ARRAY_SIZE(exePath)) {
|
if (ffFindExecutableInPath(arg0, &tmpPath) == nullptr && tmpPath.length < ARRAY_SIZE(exePath)) {
|
||||||
memcpy(exePath, tmpPath.chars, tmpPath.length + 1);
|
memcpy(exePath, tmpPath.chars, tmpPath.length + 1);
|
||||||
exePathLen = tmpPath.length;
|
exePathLen = tmpPath.length;
|
||||||
}
|
}
|
||||||
@@ -282,7 +282,7 @@ static void getSysinfo(FFPlatformSysinfo* info, const struct utsname* uts) {
|
|||||||
|
|
||||||
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__OpenBSD__) || defined(__NetBSD__)
|
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
size_t length = sizeof(info->pageSize);
|
size_t length = sizeof(info->pageSize);
|
||||||
sysctl((int[]) { CTL_HW, HW_PAGESIZE }, 2, &info->pageSize, &length, NULL, 0);
|
sysctl((int[]) { CTL_HW, HW_PAGESIZE }, 2, &info->pageSize, &length, nullptr, 0);
|
||||||
#else
|
#else
|
||||||
info->pageSize = (uint32_t) sysconf(_SC_PAGESIZE);
|
info->pageSize = (uint32_t) sysconf(_SC_PAGESIZE);
|
||||||
#endif
|
#endif
|
||||||
@@ -290,7 +290,7 @@ static void getSysinfo(FFPlatformSysinfo* info, const struct utsname* uts) {
|
|||||||
|
|
||||||
static void getCwd(FFPlatform* platform) {
|
static void getCwd(FFPlatform* platform) {
|
||||||
char cwd[PATH_MAX];
|
char cwd[PATH_MAX];
|
||||||
if (getcwd(cwd, sizeof(cwd)) != NULL) {
|
if (getcwd(cwd, sizeof(cwd)) != nullptr) {
|
||||||
ffStrbufSetS(&platform->cwd, cwd);
|
ffStrbufSetS(&platform->cwd, cwd);
|
||||||
ffStrbufEnsureEndsWithC(&platform->cwd, '/');
|
ffStrbufEnsureEndsWithC(&platform->cwd, '/');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,10 +21,10 @@ static void getExePath(FFPlatform* platform) {
|
|||||||
ffGetPeb()->ProcessParameters->ImagePathName.Buffer,
|
ffGetPeb()->ProcessParameters->ImagePathName.Buffer,
|
||||||
GENERIC_READ,
|
GENERIC_READ,
|
||||||
FILE_SHARE_READ,
|
FILE_SHARE_READ,
|
||||||
NULL,
|
nullptr,
|
||||||
OPEN_EXISTING,
|
OPEN_EXISTING,
|
||||||
FILE_FLAG_BACKUP_SEMANTICS,
|
FILE_FLAG_BACKUP_SEMANTICS,
|
||||||
NULL);
|
nullptr);
|
||||||
if (hPath != INVALID_HANDLE_VALUE) {
|
if (hPath != INVALID_HANDLE_VALUE) {
|
||||||
DWORD len = GetFinalPathNameByHandleW(hPath, exePathW, MAX_PATH, FILE_NAME_NORMALIZED);
|
DWORD len = GetFinalPathNameByHandleW(hPath, exePathW, MAX_PATH, FILE_NAME_NORMALIZED);
|
||||||
if (len > 0 && len < MAX_PATH) {
|
if (len > 0 && len < MAX_PATH) {
|
||||||
@@ -44,8 +44,8 @@ static void getExePath(FFPlatform* platform) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void getHomeDir(FFPlatform* platform) {
|
static void getHomeDir(FFPlatform* platform) {
|
||||||
PWSTR pPath = NULL;
|
PWSTR pPath = nullptr;
|
||||||
if (SUCCEEDED(SHGetKnownFolderPath(&FOLDERID_Profile, KF_FLAG_DEFAULT, NULL, &pPath))) {
|
if (SUCCEEDED(SHGetKnownFolderPath(&FOLDERID_Profile, KF_FLAG_DEFAULT, nullptr, &pPath))) {
|
||||||
ffStrbufSetWS(&platform->homeDir, pPath);
|
ffStrbufSetWS(&platform->homeDir, pPath);
|
||||||
ffStrbufReplaceAllC(&platform->homeDir, '\\', '/');
|
ffStrbufReplaceAllC(&platform->homeDir, '\\', '/');
|
||||||
ffStrbufEnsureEndsWithC(&platform->homeDir, '/');
|
ffStrbufEnsureEndsWithC(&platform->homeDir, '/');
|
||||||
@@ -58,8 +58,8 @@ static void getHomeDir(FFPlatform* platform) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void getCacheDir(FFPlatform* platform) {
|
static void getCacheDir(FFPlatform* platform) {
|
||||||
PWSTR pPath = NULL;
|
PWSTR pPath = nullptr;
|
||||||
if (SUCCEEDED(SHGetKnownFolderPath(&FOLDERID_LocalAppData, KF_FLAG_DEFAULT, NULL, &pPath))) {
|
if (SUCCEEDED(SHGetKnownFolderPath(&FOLDERID_LocalAppData, KF_FLAG_DEFAULT, nullptr, &pPath))) {
|
||||||
ffStrbufSetWS(&platform->cacheDir, pPath);
|
ffStrbufSetWS(&platform->cacheDir, pPath);
|
||||||
ffStrbufReplaceAllC(&platform->cacheDir, '\\', '/');
|
ffStrbufReplaceAllC(&platform->cacheDir, '\\', '/');
|
||||||
ffStrbufEnsureEndsWithC(&platform->cacheDir, '/');
|
ffStrbufEnsureEndsWithC(&platform->cacheDir, '/');
|
||||||
@@ -71,8 +71,8 @@ static void getCacheDir(FFPlatform* platform) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void platformPathAddKnownFolder(FFlist* dirs, REFKNOWNFOLDERID folderId) {
|
static void platformPathAddKnownFolder(FFlist* dirs, REFKNOWNFOLDERID folderId) {
|
||||||
PWSTR pPath = NULL;
|
PWSTR pPath = nullptr;
|
||||||
if (SUCCEEDED(SHGetKnownFolderPath(folderId, KF_FLAG_DEFAULT, NULL, &pPath))) {
|
if (SUCCEEDED(SHGetKnownFolderPath(folderId, KF_FLAG_DEFAULT, nullptr, &pPath))) {
|
||||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreateWS(pPath);
|
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreateWS(pPath);
|
||||||
CoTaskMemFree(pPath);
|
CoTaskMemFree(pPath);
|
||||||
ffStrbufReplaceAllC(&buffer, '\\', '/');
|
ffStrbufReplaceAllC(&buffer, '\\', '/');
|
||||||
@@ -107,7 +107,7 @@ static void getConfigDirs(FFPlatform* platform) {
|
|||||||
if (getenv("MSYSTEM")) {
|
if (getenv("MSYSTEM")) {
|
||||||
// We are in MSYS2 / Git Bash
|
// We are in MSYS2 / Git Bash
|
||||||
platformPathAddEnvSuffix(&platform->configDirs, "HOME", ".config/");
|
platformPathAddEnvSuffix(&platform->configDirs, "HOME", ".config/");
|
||||||
platformPathAddEnvSuffix(&platform->configDirs, "HOME", NULL);
|
platformPathAddEnvSuffix(&platform->configDirs, "HOME", nullptr);
|
||||||
platformPathAddEnvSuffix(&platform->configDirs, "MINGW_PREFIX", "etc");
|
platformPathAddEnvSuffix(&platform->configDirs, "MINGW_PREFIX", "etc");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,7 +122,7 @@ static void getDataDirs(FFPlatform* platform) {
|
|||||||
if (getenv("MSYSTEM") && getenv("HOME")) {
|
if (getenv("MSYSTEM") && getenv("HOME")) {
|
||||||
// We are in MSYS2 / Git Bash
|
// We are in MSYS2 / Git Bash
|
||||||
platformPathAddEnvSuffix(&platform->dataDirs, "HOME", ".local/share/");
|
platformPathAddEnvSuffix(&platform->dataDirs, "HOME", ".local/share/");
|
||||||
platformPathAddEnvSuffix(&platform->dataDirs, "HOME", NULL);
|
platformPathAddEnvSuffix(&platform->dataDirs, "HOME", nullptr);
|
||||||
platformPathAddEnvSuffix(&platform->dataDirs, "MINGW_PREFIX", "share");
|
platformPathAddEnvSuffix(&platform->dataDirs, "MINGW_PREFIX", "share");
|
||||||
}
|
}
|
||||||
ffPlatformPathAddHome(&platform->dataDirs, platform, ".local/share/");
|
ffPlatformPathAddHome(&platform->dataDirs, platform, ".local/share/");
|
||||||
@@ -142,8 +142,8 @@ static void getUserName(FFPlatform* platform) {
|
|||||||
NTSYSAPI NTSTATUS NTAPI LsaGetUserName(
|
NTSYSAPI NTSTATUS NTAPI LsaGetUserName(
|
||||||
_Outptr_ PLSA_UNICODE_STRING * UserName,
|
_Outptr_ PLSA_UNICODE_STRING * UserName,
|
||||||
_Outptr_opt_ PLSA_UNICODE_STRING * DomainName);
|
_Outptr_opt_ PLSA_UNICODE_STRING * DomainName);
|
||||||
PLSA_UNICODE_STRING userName = NULL;
|
PLSA_UNICODE_STRING userName = nullptr;
|
||||||
if (NT_SUCCESS(LsaGetUserName(&userName, NULL))) {
|
if (NT_SUCCESS(LsaGetUserName(&userName, nullptr))) {
|
||||||
ffStrbufSetNWS(&platform->userName, userName->Length / sizeof(wchar_t), userName->Buffer);
|
ffStrbufSetNWS(&platform->userName, userName->Length / sizeof(wchar_t), userName->Buffer);
|
||||||
RtlFreeUnicodeString(userName); // Required. userName.Buffer is allocated separately
|
RtlFreeUnicodeString(userName); // Required. userName.Buffer is allocated separately
|
||||||
LsaFreeMemory(userName);
|
LsaFreeMemory(userName);
|
||||||
@@ -187,18 +187,18 @@ static const char* detectWine(void) {
|
|||||||
const char* __cdecl wine_get_version(void);
|
const char* __cdecl wine_get_version(void);
|
||||||
void* hntdll = ffLibraryGetModule(L"ntdll.dll");
|
void* hntdll = ffLibraryGetModule(L"ntdll.dll");
|
||||||
if (!hntdll) {
|
if (!hntdll) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
FF_LIBRARY_LOAD_SYMBOL_LAZY(hntdll, wine_get_version);
|
FF_LIBRARY_LOAD_SYMBOL_LAZY(hntdll, wine_get_version);
|
||||||
if (!ffwine_get_version) {
|
if (!ffwine_get_version) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ffwine_get_version();
|
return ffwine_get_version();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void getSystemReleaseAndVersion(FFPlatformSysinfo* info) {
|
static void getSystemReleaseAndVersion(FFPlatformSysinfo* info) {
|
||||||
FF_AUTO_CLOSE_FD HANDLE hKey = NULL;
|
FF_AUTO_CLOSE_FD HANDLE hKey = nullptr;
|
||||||
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, nullptr)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,7 +207,7 @@ static void getSystemReleaseAndVersion(FFPlatformSysinfo* info) {
|
|||||||
FF_ARG(ubr, L"UBR"),
|
FF_ARG(ubr, L"UBR"),
|
||||||
FF_ARG(info->version, L"BuildLabEx"),
|
FF_ARG(info->version, L"BuildLabEx"),
|
||||||
},
|
},
|
||||||
NULL);
|
nullptr);
|
||||||
|
|
||||||
PPEB_FULL peb = ffGetPeb();
|
PPEB_FULL peb = ffGetPeb();
|
||||||
|
|
||||||
@@ -228,7 +228,7 @@ static void getSystemReleaseAndVersion(FFPlatformSysinfo* info) {
|
|||||||
|
|
||||||
static void getSystemPageSize(FFPlatformSysinfo* info) {
|
static void getSystemPageSize(FFPlatformSysinfo* info) {
|
||||||
SYSTEM_BASIC_INFORMATION sbi;
|
SYSTEM_BASIC_INFORMATION sbi;
|
||||||
if (NT_SUCCESS(NtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), NULL))) {
|
if (NT_SUCCESS(NtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), nullptr))) {
|
||||||
info->pageSize = sbi.PhysicalPageSize;
|
info->pageSize = sbi.PhysicalPageSize;
|
||||||
} else {
|
} else {
|
||||||
info->pageSize = 4096;
|
info->pageSize = 4096;
|
||||||
@@ -236,54 +236,38 @@ static void getSystemPageSize(FFPlatformSysinfo* info) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void getSystemArchitecture(FFPlatformSysinfo* info) {
|
static void getSystemArchitecture(FFPlatformSysinfo* info) {
|
||||||
SYSTEM_PROCESSOR_INFORMATION spi;
|
switch (SharedUserData->NativeProcessorArchitecture) {
|
||||||
if (NT_SUCCESS(NtQuerySystemInformation(SystemProcessorInformation, &spi, sizeof(spi), NULL))) {
|
case PROCESSOR_ARCHITECTURE_AMD64:
|
||||||
switch (spi.ProcessorArchitecture) {
|
ffStrbufSetStatic(&info->architecture, "x86_64");
|
||||||
case PROCESSOR_ARCHITECTURE_AMD64:
|
break;
|
||||||
ffStrbufSetStatic(&info->architecture, "x86_64");
|
case PROCESSOR_ARCHITECTURE_IA64:
|
||||||
break;
|
ffStrbufSetStatic(&info->architecture, "ia64");
|
||||||
case PROCESSOR_ARCHITECTURE_IA64:
|
break;
|
||||||
ffStrbufSetStatic(&info->architecture, "ia64");
|
case PROCESSOR_ARCHITECTURE_INTEL:
|
||||||
break;
|
ffStrbufSetStatic(&info->architecture, "i686");
|
||||||
case PROCESSOR_ARCHITECTURE_INTEL:
|
break;
|
||||||
switch (spi.ProcessorLevel) {
|
case PROCESSOR_ARCHITECTURE_ARM64:
|
||||||
case 4:
|
ffStrbufSetStatic(&info->architecture, "aarch64");
|
||||||
ffStrbufSetStatic(&info->architecture, "i486");
|
break;
|
||||||
break;
|
case PROCESSOR_ARCHITECTURE_ARM:
|
||||||
case 5:
|
ffStrbufSetStatic(&info->architecture, "arm");
|
||||||
ffStrbufSetStatic(&info->architecture, "i586");
|
break;
|
||||||
break;
|
case PROCESSOR_ARCHITECTURE_PPC:
|
||||||
case 6:
|
ffStrbufSetStatic(&info->architecture, "ppc");
|
||||||
ffStrbufSetStatic(&info->architecture, "i686");
|
break;
|
||||||
break;
|
case PROCESSOR_ARCHITECTURE_MIPS:
|
||||||
default:
|
ffStrbufSetStatic(&info->architecture, "mips");
|
||||||
ffStrbufSetStatic(&info->architecture, "i386");
|
break;
|
||||||
break;
|
case PROCESSOR_ARCHITECTURE_ALPHA:
|
||||||
}
|
ffStrbufSetStatic(&info->architecture, "alpha");
|
||||||
break;
|
break;
|
||||||
case PROCESSOR_ARCHITECTURE_ARM64:
|
case PROCESSOR_ARCHITECTURE_ALPHA64:
|
||||||
ffStrbufSetStatic(&info->architecture, "aarch64");
|
ffStrbufSetStatic(&info->architecture, "alpha64");
|
||||||
break;
|
break;
|
||||||
case PROCESSOR_ARCHITECTURE_ARM:
|
case PROCESSOR_ARCHITECTURE_UNKNOWN:
|
||||||
ffStrbufSetStatic(&info->architecture, "arm");
|
default:
|
||||||
break;
|
ffStrbufSetStatic(&info->architecture, "unknown");
|
||||||
case PROCESSOR_ARCHITECTURE_PPC:
|
break;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,15 +3,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
void* ffListAdd(FFlist* list, uint32_t elementSize) {
|
|
||||||
if (list->length == list->capacity) {
|
|
||||||
ffListReserve(list, elementSize, list->capacity == 0 ? FF_LIST_DEFAULT_ALLOC : list->capacity * 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
++list->length;
|
|
||||||
return ffListGet(list, elementSize, list->length - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ffListShift(FFlist* list, uint32_t elementSize, void* __restrict result) {
|
bool ffListShift(FFlist* list, uint32_t elementSize, void* __restrict result) {
|
||||||
if (list->length == 0) {
|
if (list->length == 0) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
+71
-103
@@ -1,6 +1,7 @@
|
|||||||
#include "common/FFstrbuf.h"
|
#include "common/FFstrbuf.h"
|
||||||
#include "common/mallocHelper.h"
|
#include "common/mallocHelper.h"
|
||||||
#include "common/strutil.h"
|
#include "common/strutil.h"
|
||||||
|
#include "common/debug.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
@@ -20,9 +21,9 @@ void ffStrbufInitA(FFstrbuf* strbuf, uint32_t allocate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ffStrbufInitVF(FFstrbuf* strbuf, const char* format, va_list arguments) {
|
void ffStrbufInitVF(FFstrbuf* strbuf, const char* format, va_list arguments) {
|
||||||
assert(format != NULL);
|
assert(format != nullptr);
|
||||||
|
|
||||||
char* buffer = NULL;
|
char* buffer = nullptr;
|
||||||
int len = vasprintf(&buffer, format, arguments);
|
int len = vasprintf(&buffer, format, arguments);
|
||||||
assert(len >= 0);
|
assert(len >= 0);
|
||||||
|
|
||||||
@@ -32,7 +33,7 @@ void ffStrbufInitVF(FFstrbuf* strbuf, const char* format, va_list arguments) {
|
|||||||
// Takes ownership of `heapStr`. The caller must not free `heapStr` after calling this
|
// 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.
|
// 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);
|
assert(heapStr != nullptr);
|
||||||
|
|
||||||
strbuf->length = length;
|
strbuf->length = length;
|
||||||
size_t allocSize = ffMallocUsableSize(heapStr);
|
size_t allocSize = ffMallocUsableSize(heapStr);
|
||||||
@@ -45,18 +46,44 @@ void ffStrbufInitMoveNS(FFstrbuf* strbuf, uint32_t length, char* heapStr) {
|
|||||||
strbuf->chars = heapStr;
|
strbuf->chars = heapStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free) {
|
void ffStrbufInitF(FFstrbuf* strbuf, const char* format, ...) {
|
||||||
if (ffStrbufGetFree(strbuf) >= free && !(strbuf->allocated == 0 && strbuf->length > 0)) {
|
va_list arguments;
|
||||||
return;
|
va_start(arguments, format);
|
||||||
|
ffStrbufInitVF(strbuf, format, arguments);
|
||||||
|
va_end(arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
FFstrbuf ffStrbufCreateF(const char* format, ...) {
|
||||||
|
FFstrbuf strbuf;
|
||||||
|
|
||||||
|
va_list arguments;
|
||||||
|
va_start(arguments, format);
|
||||||
|
ffStrbufInitVF(&strbuf, format, arguments);
|
||||||
|
va_end(arguments);
|
||||||
|
|
||||||
|
return strbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ffStrbufEnsureFreeNoCheck(FFstrbuf* strbuf, uint32_t free) {
|
||||||
|
uint32_t allocate;
|
||||||
|
if (__builtin_expect(__builtin_uadd_overflow(strbuf->length, free, &allocate), false)) {
|
||||||
|
FF_DEBUG("Error: Integer overflow when calculating allocation size. Aborting");
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t allocate = strbuf->allocated;
|
if (allocate < FASTFETCH_STRBUF_DEFAULT_ALLOC) { // `<` for null terminator
|
||||||
if (allocate < FASTFETCH_STRBUF_DEFAULT_ALLOC) {
|
|
||||||
allocate = FASTFETCH_STRBUF_DEFAULT_ALLOC;
|
allocate = FASTFETCH_STRBUF_DEFAULT_ALLOC;
|
||||||
}
|
} else {
|
||||||
|
if (__builtin_expect(allocate > (UINT32_MAX >> 1), false)) {
|
||||||
|
// User tried to allocate more than 2GB of memory, which exceeds the maximum size supported by FFstrbuf.
|
||||||
|
// This is likely an error or an attempt to exploit the program. Abort to prevent potential issues.
|
||||||
|
FF_DEBUG("Error: Attempted to allocate %" PRIu32 " bytes more than 2GB of memory in FFstrbuf. Aborting", allocate);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
while ((strbuf->length + free + 1) > allocate) { // + 1 for the null byte
|
// Round up to the next power of 2.
|
||||||
allocate *= 2;
|
// If the value is already a power of 2, it will be rounded up to the next power of 2.
|
||||||
|
allocate = 1U << (32 - __builtin_clz(allocate));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strbuf->allocated == 0) {
|
if (strbuf->allocated == 0) {
|
||||||
@@ -76,16 +103,17 @@ void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free) {
|
|||||||
|
|
||||||
// Ensure that at least `free` bytes are available in the buffer besides the current length
|
// 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)
|
// for an empty buffer, free + 1 length memory will be allocated(+1 for the NUL)
|
||||||
|
// This function ensures a dynamic buffer is allocated even if free == 0
|
||||||
void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free) {
|
void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free) {
|
||||||
uint32_t oldFree = ffStrbufGetFree(strbuf);
|
uint32_t newCap;
|
||||||
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;
|
assert(strbuf->length < UINT32_MAX - 1); // We don't use static strings with length >= UINT32_MAX - 1, so this should never happen
|
||||||
|
if (__builtin_expect(__builtin_uadd_overflow(strbuf->length + 1, free, &newCap), false)) {
|
||||||
|
FF_DEBUG("Error: Integer overflow when calculating new capacity. Aborting");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
char* newbuf = malloc(sizeof(*strbuf->chars) * newCap);
|
char* newbuf = malloc(sizeof(*strbuf->chars) * newCap);
|
||||||
if (strbuf->length == 0) {
|
if (strbuf->length == 0) {
|
||||||
*newbuf = '\0';
|
*newbuf = '\0';
|
||||||
@@ -94,54 +122,23 @@ void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free) {
|
|||||||
}
|
}
|
||||||
strbuf->chars = newbuf;
|
strbuf->chars = newbuf;
|
||||||
} else {
|
} else {
|
||||||
|
uint32_t oldFree = ffStrbufGetFree(strbuf);
|
||||||
|
if (oldFree >= free) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (__builtin_expect(__builtin_uadd_overflow(strbuf->allocated, free - oldFree, &newCap), false)) {
|
||||||
|
FF_DEBUG("Error: Integer overflow when calculating new capacity. Aborting");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
strbuf->chars = realloc(strbuf->chars, sizeof(*strbuf->chars) * newCap);
|
strbuf->chars = realloc(strbuf->chars, sizeof(*strbuf->chars) * newCap);
|
||||||
}
|
}
|
||||||
|
|
||||||
strbuf->allocated = newCap;
|
strbuf->allocated = newCap;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ffStrbufClear(FFstrbuf* strbuf) {
|
|
||||||
assert(strbuf != NULL);
|
|
||||||
|
|
||||||
if (strbuf->allocated == 0) {
|
|
||||||
strbuf->chars = CHAR_NULL_PTR;
|
|
||||||
} else {
|
|
||||||
strbuf->chars[0] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
strbuf->length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ffStrbufAppendC(FFstrbuf* strbuf, char c) {
|
|
||||||
ffStrbufEnsureFree(strbuf, 1);
|
|
||||||
strbuf->chars[strbuf->length++] = c;
|
|
||||||
strbuf->chars[strbuf->length] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
void ffStrbufAppendNC(FFstrbuf* strbuf, uint32_t num, char c) {
|
|
||||||
if (num == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ffStrbufEnsureFree(strbuf, num);
|
|
||||||
memset(&strbuf->chars[strbuf->length], c, num);
|
|
||||||
strbuf->length += num;
|
|
||||||
strbuf->chars[strbuf->length] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
void ffStrbufAppendNS(FFstrbuf* strbuf, uint32_t length, const char* value) {
|
|
||||||
if (value == NULL || length == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ffStrbufEnsureFree(strbuf, length);
|
|
||||||
memcpy(&strbuf->chars[strbuf->length], value, length);
|
|
||||||
strbuf->length += length;
|
|
||||||
strbuf->chars[strbuf->length] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
void ffStrbufAppendTransformS(FFstrbuf* strbuf, const char* value, int (*transformFunc)(int)) {
|
void ffStrbufAppendTransformS(FFstrbuf* strbuf, const char* value, int (*transformFunc)(int)) {
|
||||||
if (value == NULL) {
|
if (value == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,7 +156,7 @@ void ffStrbufAppendTransformS(FFstrbuf* strbuf, const char* value, int (*transfo
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ffStrbufAppendVF(FFstrbuf* strbuf, const char* format, va_list arguments) {
|
void ffStrbufAppendVF(FFstrbuf* strbuf, const char* format, va_list arguments) {
|
||||||
assert(format != NULL);
|
assert(format != nullptr);
|
||||||
|
|
||||||
va_list copy;
|
va_list copy;
|
||||||
va_copy(copy, arguments);
|
va_copy(copy, arguments);
|
||||||
@@ -168,7 +165,7 @@ void ffStrbufAppendVF(FFstrbuf* strbuf, const char* format, va_list arguments) {
|
|||||||
int written = vsnprintf(strbuf->chars + strbuf->length, strbuf->allocated > 0 ? free + 1 : 0, format, arguments);
|
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);
|
ffStrbufEnsureFreeNoCheck(strbuf, (uint32_t) written);
|
||||||
written = vsnprintf(strbuf->chars + strbuf->length, (uint32_t) written + 1, format, copy);
|
written = vsnprintf(strbuf->chars + strbuf->length, (uint32_t) written + 1, format, copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,12 +177,12 @@ void ffStrbufAppendVF(FFstrbuf* strbuf, const char* format, va_list arguments) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char* ffStrbufAppendSUntilC(FFstrbuf* strbuf, const char* value, char until) {
|
const char* ffStrbufAppendSUntilC(FFstrbuf* strbuf, const char* value, char until) {
|
||||||
if (value == NULL) {
|
if (value == nullptr) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* end = strchr(value, until);
|
const char* end = strchr(value, until);
|
||||||
if (end == NULL) {
|
if (end == nullptr) {
|
||||||
ffStrbufAppendS(strbuf, value);
|
ffStrbufAppendS(strbuf, value);
|
||||||
} else {
|
} else {
|
||||||
ffStrbufAppendNS(strbuf, (uint32_t) (end - value), value);
|
ffStrbufAppendNS(strbuf, (uint32_t) (end - value), value);
|
||||||
@@ -194,7 +191,7 @@ const char* ffStrbufAppendSUntilC(FFstrbuf* strbuf, const char* value, char unti
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ffStrbufSetF(FFstrbuf* strbuf, const char* format, ...) {
|
void ffStrbufSetF(FFstrbuf* strbuf, const char* format, ...) {
|
||||||
assert(format != NULL);
|
assert(format != nullptr);
|
||||||
|
|
||||||
va_list arguments;
|
va_list arguments;
|
||||||
va_start(arguments, format);
|
va_start(arguments, format);
|
||||||
@@ -211,7 +208,7 @@ void ffStrbufSetF(FFstrbuf* strbuf, const char* format, ...) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ffStrbufAppendF(FFstrbuf* strbuf, const char* format, ...) {
|
void ffStrbufAppendF(FFstrbuf* strbuf, const char* format, ...) {
|
||||||
assert(format != NULL);
|
assert(format != nullptr);
|
||||||
|
|
||||||
va_list arguments;
|
va_list arguments;
|
||||||
va_start(arguments, format);
|
va_start(arguments, format);
|
||||||
@@ -220,7 +217,7 @@ void ffStrbufAppendF(FFstrbuf* strbuf, const char* format, ...) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ffStrbufPrependNS(FFstrbuf* strbuf, uint32_t length, const char* value) {
|
void ffStrbufPrependNS(FFstrbuf* strbuf, uint32_t length, const char* value) {
|
||||||
if (value == NULL || length == 0) {
|
if (value == nullptr || length == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,14 +235,14 @@ void ffStrbufPrependC(FFstrbuf* strbuf, char c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ffStrbufSetNS(FFstrbuf* strbuf, uint32_t length, const char* value) {
|
void ffStrbufSetNS(FFstrbuf* strbuf, uint32_t length, const char* value) {
|
||||||
assert(strbuf != NULL);
|
assert(strbuf != nullptr);
|
||||||
|
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
ffStrbufClear(strbuf);
|
ffStrbufClear(strbuf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(value != NULL);
|
assert(value != nullptr);
|
||||||
|
|
||||||
if (strbuf->allocated <= length) {
|
if (strbuf->allocated <= length) {
|
||||||
char* newBuf = malloc(sizeof(char) * (length + 1));
|
char* newBuf = malloc(sizeof(char) * (length + 1));
|
||||||
@@ -435,9 +432,7 @@ bool ffStrbufSubstrBefore(FFstrbuf* strbuf, uint32_t index) {
|
|||||||
|
|
||||||
if (strbuf->allocated == 0) {
|
if (strbuf->allocated == 0) {
|
||||||
// static string
|
// static string
|
||||||
if (index < strbuf->length) {
|
ffStrbufInitNS(strbuf, index, strbuf->chars);
|
||||||
ffStrbufInitNS(strbuf, index, strbuf->chars);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -550,33 +545,6 @@ bool ffStrbufEnsureEndsWithC(FFstrbuf* strbuf, char c) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ffStrbufWriteTo(const FFstrbuf* strbuf, FILE* file) {
|
|
||||||
fwrite(strbuf->chars, sizeof(*strbuf->chars), strbuf->length, file);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ffStrbufPutTo(const FFstrbuf* strbuf, FILE* file) {
|
|
||||||
ffStrbufWriteTo(strbuf, file);
|
|
||||||
fputc('\n', file);
|
|
||||||
}
|
|
||||||
|
|
||||||
double ffStrbufToDouble(const FFstrbuf* strbuf, double defaultValue) {
|
|
||||||
char* str_end;
|
|
||||||
double result = strtod(strbuf->chars, &str_end);
|
|
||||||
return str_end == strbuf->chars ? defaultValue : result;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t ffStrbufToUInt(const FFstrbuf* strbuf, uint64_t defaultValue) {
|
|
||||||
char* str_end;
|
|
||||||
unsigned long long result = strtoull(strbuf->chars, &str_end, 10);
|
|
||||||
return str_end == strbuf->chars ? defaultValue : (uint64_t) result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t ffStrbufToSInt(const FFstrbuf* strbuf, int64_t defaultValue) {
|
|
||||||
char* str_end;
|
|
||||||
long long result = strtoll(strbuf->chars, &str_end, 10);
|
|
||||||
return str_end == strbuf->chars ? defaultValue : (int64_t) result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ffStrbufAppendSInt(FFstrbuf* strbuf, int64_t value) {
|
void ffStrbufAppendSInt(FFstrbuf* strbuf, int64_t value) {
|
||||||
ffStrbufEnsureFree(strbuf, 21); // Required by yyjson_write_number
|
ffStrbufEnsureFree(strbuf, 21); // Required by yyjson_write_number
|
||||||
char* start = strbuf->chars + strbuf->length;
|
char* start = strbuf->chars + strbuf->length;
|
||||||
@@ -585,7 +553,7 @@ void ffStrbufAppendSInt(FFstrbuf* strbuf, int64_t value) {
|
|||||||
unsafe_yyjson_set_sint(&val, value);
|
unsafe_yyjson_set_sint(&val, value);
|
||||||
char* end = yyjson_write_number(&val, start);
|
char* end = yyjson_write_number(&val, start);
|
||||||
|
|
||||||
assert(end != NULL);
|
assert(end != nullptr);
|
||||||
|
|
||||||
strbuf->length += (uint32_t) (end - start);
|
strbuf->length += (uint32_t) (end - start);
|
||||||
}
|
}
|
||||||
@@ -598,7 +566,7 @@ void ffStrbufAppendUInt(FFstrbuf* strbuf, uint64_t value) {
|
|||||||
unsafe_yyjson_set_uint(&val, value);
|
unsafe_yyjson_set_uint(&val, value);
|
||||||
char* end = yyjson_write_number(&val, start);
|
char* end = yyjson_write_number(&val, start);
|
||||||
|
|
||||||
assert(end != NULL);
|
assert(end != nullptr);
|
||||||
|
|
||||||
strbuf->length += (uint32_t) (end - start);
|
strbuf->length += (uint32_t) (end - start);
|
||||||
}
|
}
|
||||||
@@ -765,7 +733,7 @@ bool ffStrbufMatchSeparatedNS(const FFstrbuf* strbuf, uint32_t compLength, const
|
|||||||
|
|
||||||
for (const char* p = comp; p < comp + compLength;) {
|
for (const char* p = comp; p < comp + compLength;) {
|
||||||
const char* colon = memchr(p, separator, (size_t) (comp + compLength - p));
|
const char* colon = memchr(p, separator, (size_t) (comp + compLength - p));
|
||||||
if (colon == NULL) {
|
if (colon == nullptr) {
|
||||||
uint32_t remainingLen = (uint32_t) (comp + compLength - p);
|
uint32_t remainingLen = (uint32_t) (comp + compLength - p);
|
||||||
return strbuf->length == remainingLen && memcmp(strbuf->chars, p, remainingLen) == 0;
|
return strbuf->length == remainingLen && memcmp(strbuf->chars, p, remainingLen) == 0;
|
||||||
}
|
}
|
||||||
@@ -793,7 +761,7 @@ bool ffStrbufMatchSeparatedIgnCaseNS(const FFstrbuf* strbuf, uint32_t compLength
|
|||||||
|
|
||||||
for (const char* p = comp; p < comp + compLength;) {
|
for (const char* p = comp; p < comp + compLength;) {
|
||||||
const char* colon = memchr(p, separator, (size_t) (comp + compLength - p));
|
const char* colon = memchr(p, separator, (size_t) (comp + compLength - p));
|
||||||
if (colon == NULL) {
|
if (colon == nullptr) {
|
||||||
uint32_t remainingLen = (uint32_t) (comp + compLength - p);
|
uint32_t remainingLen = (uint32_t) (comp + compLength - p);
|
||||||
return strbuf->length == remainingLen && strncasecmp(strbuf->chars, p, remainingLen) == 0;
|
return strbuf->length == remainingLen && strncasecmp(strbuf->chars, p, remainingLen) == 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,13 @@ void ffBase64EncodeRaw(uint32_t size, const char* str, uint32_t* out_size, char*
|
|||||||
char* out = output;
|
char* out = output;
|
||||||
const char* ends = str + (size - size % 3);
|
const char* ends = str + (size - size % 3);
|
||||||
while (str != ends) {
|
while (str != ends) {
|
||||||
uint32_t n = __builtin_bswap32(*(uint32_t*) str);
|
uint32_t n = *(uint32_t*) str;
|
||||||
|
#if !__BIG_ENDIAN__
|
||||||
|
// The 3 input bytes must be laid out big-endian (str[0] in the most
|
||||||
|
// significant position). On little-endian hosts swap; on big-endian
|
||||||
|
// hosts the word is already in the right order.
|
||||||
|
n = __builtin_bswap32(n);
|
||||||
|
#endif
|
||||||
*out++ = chars[(n >> 26) & 63];
|
*out++ = chars[(n >> 26) & 63];
|
||||||
*out++ = chars[(n >> 20) & 63];
|
*out++ = chars[(n >> 20) & 63];
|
||||||
*out++ = chars[(n >> 14) & 63];
|
*out++ = chars[(n >> 14) & 63];
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ typedef struct {
|
|||||||
|
|
||||||
static inline void wrapMunmap(FFMemoryMapping* mapping) {
|
static inline void wrapMunmap(FFMemoryMapping* mapping) {
|
||||||
assert(mapping);
|
assert(mapping);
|
||||||
if (mapping->data == NULL || mapping->data == MAP_FAILED) {
|
if (mapping->data == nullptr || mapping->data == MAP_FAILED) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
munmap((void*) mapping->data, mapping->length);
|
munmap((void*) mapping->data, mapping->length);
|
||||||
@@ -31,12 +31,12 @@ static inline void wrapMunmap(FFMemoryMapping* mapping) {
|
|||||||
*/
|
*/
|
||||||
static inline const void* readData(const FFMemoryMapping* mapping, size_t size, off_t offset) {
|
static inline const void* readData(const FFMemoryMapping* mapping, size_t size, off_t offset) {
|
||||||
if (offset < 0) {
|
if (offset < 0) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t start = (size_t) offset;
|
size_t start = (size_t) offset;
|
||||||
if (start > mapping->length || size > mapping->length - start) {
|
if (start > mapping->length || size > mapping->length - start) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mapping->data + start;
|
return mapping->data + start;
|
||||||
@@ -99,7 +99,7 @@ static bool handleMachSection(const FFMemoryMapping* mapping, const char* name,
|
|||||||
* @param userdata User data for the callback
|
* @param userdata User data for the callback
|
||||||
* @param minLength Minimum string length to extract
|
* @param minLength Minimum string length to extract
|
||||||
*
|
*
|
||||||
* @return NULL on success, error message on failure
|
* @return nullptr on success, error message on failure
|
||||||
*/
|
*/
|
||||||
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) {
|
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;
|
uint32_t ncmds;
|
||||||
@@ -124,7 +124,7 @@ static const char* dumpMachHeader(const FFMemoryMapping* mapping, off_t offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
off_t commandOffset = loadCommandsOffset;
|
off_t commandOffset = loadCommandsOffset;
|
||||||
const struct load_command* cmd = NULL;
|
const struct load_command* cmd = nullptr;
|
||||||
for (uint32_t i = 0U; i < ncmds; i++, commandOffset += cmd->cmdsize) {
|
for (uint32_t i = 0U; i < ncmds; i++, commandOffset += cmd->cmdsize) {
|
||||||
cmd = readData(mapping, sizeof(*cmd), commandOffset);
|
cmd = readData(mapping, sizeof(*cmd), commandOffset);
|
||||||
if (!cmd) {
|
if (!cmd) {
|
||||||
@@ -153,7 +153,7 @@ static const char* dumpMachHeader(const FFMemoryMapping* mapping, off_t offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!handleMachSection(mapping, section->sectname, (off_t) section->offset, (size_t) section->size, cb, userdata, minLength)) {
|
if (!handleMachSection(mapping, section->sectname, (off_t) section->offset, (size_t) section->size, cb, userdata, minLength)) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (cmd->cmd == LC_SEGMENT) {
|
} else if (cmd->cmd == LC_SEGMENT) {
|
||||||
@@ -174,13 +174,13 @@ static const char* dumpMachHeader(const FFMemoryMapping* mapping, off_t offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!handleMachSection(mapping, section->sectname, (off_t) section->offset, (size_t) section->size, cb, userdata, minLength)) {
|
if (!handleMachSection(mapping, section->sectname, (off_t) section->offset, (size_t) section->size, cb, userdata, minLength)) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -195,7 +195,7 @@ static const char* dumpMachHeader(const FFMemoryMapping* mapping, off_t offset,
|
|||||||
* @param userdata User data for the callback
|
* @param userdata User data for the callback
|
||||||
* @param minLength Minimum string length to extract
|
* @param minLength Minimum string length to extract
|
||||||
*
|
*
|
||||||
* @return NULL on success, error message on failure
|
* @return nullptr on success, error message on failure
|
||||||
*/
|
*/
|
||||||
static const char* dumpFatHeader(const FFMemoryMapping* mapping, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata, uint32_t minLength) {
|
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);
|
const struct fat_header* headerRaw = readData(mapping, sizeof(struct fat_header), 0);
|
||||||
@@ -273,8 +273,8 @@ const char* ffBinaryExtractStrings(const char* machoFile, bool (*cb)(const char*
|
|||||||
return "Failed to stat file";
|
return "Failed to stat file";
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_A_CLEANUP(wrapMunmap) FFMemoryMapping mapping = {
|
[[gnu::cleanup(wrapMunmap)]] FFMemoryMapping mapping = {
|
||||||
.data = mmap(NULL, (size_t) st.st_size, PROT_READ, MAP_PRIVATE, fd, 0),
|
.data = mmap(nullptr, (size_t) st.st_size, PROT_READ, MAP_PRIVATE, fd, 0),
|
||||||
.length = (size_t) st.st_size,
|
.length = (size_t) st.st_size,
|
||||||
};
|
};
|
||||||
if (mapping.data == MAP_FAILED) {
|
if (mapping.data == MAP_FAILED) {
|
||||||
|
|||||||
@@ -56,10 +56,10 @@ const char* ffBinaryExtractStrings(const char* elfFile, bool (*cb)(const char* s
|
|||||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libelf, elfData, elf_strptr)
|
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libelf, elfData, elf_strptr)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libelf, elfData, elf_end)
|
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libelf, elfData, elf_end)
|
||||||
|
|
||||||
libelf = NULL;
|
libelf = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elfData.ffelf_end == NULL) {
|
if (elfData.ffelf_end == nullptr) {
|
||||||
return "load libelf failed";
|
return "load libelf failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,8 +69,8 @@ const char* ffBinaryExtractStrings(const char* elfFile, bool (*cb)(const char* s
|
|||||||
return "open() failed";
|
return "open() failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
Elf* elf = elfData.ffelf_begin(fd, ELF_C_READ, NULL);
|
Elf* elf = elfData.ffelf_begin(fd, ELF_C_READ, nullptr);
|
||||||
if (elf == NULL) {
|
if (elf == nullptr) {
|
||||||
return "elf_begin() failed";
|
return "elf_begin() failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,27 +82,27 @@ const char* ffBinaryExtractStrings(const char* elfFile, bool (*cb)(const char* s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Iterate through all sections, looking for .rodata which contains string literals
|
// Iterate through all sections, looking for .rodata which contains string literals
|
||||||
Elf_Scn* scn = NULL;
|
Elf_Scn* scn = nullptr;
|
||||||
while ((scn = elfData.ffelf_nextscn(elf, scn)) != NULL) {
|
while ((scn = elfData.ffelf_nextscn(elf, scn)) != nullptr) {
|
||||||
// Try 64-bit section header first, then 32-bit if that fails
|
// Try 64-bit section header first, then 32-bit if that fails
|
||||||
Elf64_Shdr* shdr64 = elfData.ffelf64_getshdr(scn);
|
Elf64_Shdr* shdr64 = elfData.ffelf64_getshdr(scn);
|
||||||
Elf32_Shdr* shdr32 = NULL;
|
Elf32_Shdr* shdr32 = nullptr;
|
||||||
if (shdr64 == NULL) {
|
if (shdr64 == nullptr) {
|
||||||
shdr32 = elfData.ffelf32_getshdr(scn);
|
shdr32 = elfData.ffelf32_getshdr(scn);
|
||||||
if (shdr32 == NULL) {
|
if (shdr32 == nullptr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the section name and check if it's .rodata
|
// 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);
|
const char* name = elfData.ffelf_strptr(elf, shstrndx, shdr64 ? shdr64->sh_name : shdr32->sh_name);
|
||||||
if (name == NULL || !ffStrEquals(name, ".rodata")) {
|
if (name == nullptr || !ffStrEquals(name, ".rodata")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the section data
|
// Get the section data
|
||||||
Elf_Data* data = elfData.ffelf_getdata(scn, NULL);
|
Elf_Data* data = elfData.ffelf_getdata(scn, nullptr);
|
||||||
if (data == NULL) {
|
if (data == nullptr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ const char* ffBinaryExtractStrings(const char* elfFile, bool (*cb)(const char* s
|
|||||||
}
|
}
|
||||||
|
|
||||||
elfData.ffelf_end(elf);
|
elfData.ffelf_end(elf);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -15,19 +15,19 @@
|
|||||||
* Each string found is passed to the callback function for processing.
|
* 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) {
|
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);
|
FF_AUTO_CLOSE_FD HANDLE hFile = CreateFileA(peFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||||
if (hFile == INVALID_HANDLE_VALUE) {
|
if (hFile == INVALID_HANDLE_VALUE) {
|
||||||
return "CreateFileA() failed";
|
return "CreateFileA() failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_AUTO_CLOSE_FD HANDLE hSection = NULL;
|
FF_AUTO_CLOSE_FD HANDLE hSection = nullptr;
|
||||||
if (!NT_SUCCESS(NtCreateSection(&hSection, SECTION_MAP_READ, NULL, NULL, PAGE_READONLY, SEC_COMMIT, hFile))) {
|
if (!NT_SUCCESS(NtCreateSection(&hSection, SECTION_MAP_READ, nullptr, nullptr, PAGE_READONLY, SEC_COMMIT, hFile))) {
|
||||||
return "NtCreateSection() failed";
|
return "NtCreateSection() failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
PVOID base = NULL;
|
PVOID base = nullptr;
|
||||||
SIZE_T viewSize = 0;
|
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, nullptr, &viewSize, ViewUnmap, 0, PAGE_READONLY))) {
|
||||||
return "NtMapViewOfSection() failed";
|
return "NtMapViewOfSection() failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,5 +67,5 @@ const char* ffBinaryExtractStrings(const char* peFile, bool (*cb)(const char* st
|
|||||||
}
|
}
|
||||||
|
|
||||||
NtUnmapViewOfSection(NtCurrentProcess(), base);
|
NtUnmapViewOfSection(NtCurrentProcess(), base);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ bool ffParseModuleOptions(const char* key, const char* value) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (value && !*value) {
|
if (value && !*value) {
|
||||||
value = NULL;
|
value = nullptr;
|
||||||
}
|
}
|
||||||
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(key[2]) - 'A']; *modules; ++modules) {
|
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(key[2]) - 'A']; *modules; ++modules) {
|
||||||
FFModuleBaseInfo* baseInfo = *modules;
|
FFModuleBaseInfo* baseInfo = *modules;
|
||||||
const char* subKey = ffOptionTestPrefix(key, baseInfo->name);
|
const char* subKey = ffOptionTestPrefix(key, baseInfo->name);
|
||||||
if (subKey != NULL) {
|
if (subKey != nullptr) {
|
||||||
if (subKey[0] == '\0' || subKey[0] == '-') // Key is exactly the module name or has a leading '-'
|
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);
|
fprintf(stderr, "Error: unknown module key %s\n", key);
|
||||||
@@ -64,7 +64,7 @@ bool ffParseModuleOptions(const char* key, const char* value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ffPrepareCommandOption(FFdata* data) {
|
void ffPrepareCommandOption(FFdata* data) {
|
||||||
char* moduleType = NULL;
|
char* moduleType = nullptr;
|
||||||
size_t moduleLen = 0;
|
size_t moduleLen = 0;
|
||||||
while (ffStrbufGetdelim(&moduleType, &moduleLen, ':', &data->structure)) {
|
while (ffStrbufGetdelim(&moduleType, &moduleLen, ':', &data->structure)) {
|
||||||
#define FF_IF_MODULE_MATCH(moduleNameConstant) if (moduleLen == strlen(moduleNameConstant) && ffStrEqualsIgnCase(moduleType, moduleNameConstant) && !ffStrbufSeparatedContainIgnCaseS(&data->structureDisabled, moduleNameConstant, ':'))
|
#define FF_IF_MODULE_MATCH(moduleNameConstant) if (moduleLen == strlen(moduleNameConstant) && ffStrEqualsIgnCase(moduleType, moduleNameConstant) && !ffStrbufSeparatedContainIgnCaseS(&data->structureDisabled, moduleNameConstant, ':'))
|
||||||
@@ -82,7 +82,7 @@ void ffPrepareCommandOption(FFdata* data) {
|
|||||||
case 'D':
|
case 'D':
|
||||||
case 'd':
|
case 'd':
|
||||||
FF_IF_MODULE_MATCH(FF_DISKIO_MODULE_NAME) {
|
FF_IF_MODULE_MATCH(FF_DISKIO_MODULE_NAME) {
|
||||||
FF_A_CLEANUP(ffDestroyDiskIOOptions) FFDiskIOOptions options;
|
[[gnu::cleanup(ffDestroyDiskIOOptions)]] FFDiskIOOptions options;
|
||||||
ffInitDiskIOOptions(&options);
|
ffInitDiskIOOptions(&options);
|
||||||
ffPrepareDiskIO(&options);
|
ffPrepareDiskIO(&options);
|
||||||
}
|
}
|
||||||
@@ -93,7 +93,7 @@ void ffPrepareCommandOption(FFdata* data) {
|
|||||||
case 'N':
|
case 'N':
|
||||||
case 'n':
|
case 'n':
|
||||||
FF_IF_MODULE_MATCH(FF_NETIO_MODULE_NAME) {
|
FF_IF_MODULE_MATCH(FF_NETIO_MODULE_NAME) {
|
||||||
FF_A_CLEANUP(ffDestroyNetIOOptions) FFNetIOOptions options;
|
[[gnu::cleanup(ffDestroyNetIOOptions)]] FFNetIOOptions options;
|
||||||
ffInitNetIOOptions(&options);
|
ffInitNetIOOptions(&options);
|
||||||
ffPrepareNetIO(&options);
|
ffPrepareNetIO(&options);
|
||||||
}
|
}
|
||||||
@@ -104,7 +104,7 @@ void ffPrepareCommandOption(FFdata* data) {
|
|||||||
case 'P':
|
case 'P':
|
||||||
case 'p':
|
case 'p':
|
||||||
FF_IF_MODULE_MATCH(FF_PUBLICIP_MODULE_NAME) {
|
FF_IF_MODULE_MATCH(FF_PUBLICIP_MODULE_NAME) {
|
||||||
FF_A_CLEANUP(ffDestroyPublicIpOptions) FFPublicIPOptions options;
|
[[gnu::cleanup(ffDestroyPublicIpOptions)]] FFPublicIPOptions options;
|
||||||
ffInitPublicIpOptions(&options);
|
ffInitPublicIpOptions(&options);
|
||||||
ffPreparePublicIp(&options);
|
ffPreparePublicIp(&options);
|
||||||
}
|
}
|
||||||
@@ -115,7 +115,7 @@ void ffPrepareCommandOption(FFdata* data) {
|
|||||||
case 'W':
|
case 'W':
|
||||||
case 'w':
|
case 'w':
|
||||||
FF_IF_MODULE_MATCH(FF_WEATHER_MODULE_NAME) {
|
FF_IF_MODULE_MATCH(FF_WEATHER_MODULE_NAME) {
|
||||||
FF_A_CLEANUP(ffDestroyWeatherOptions) FFWeatherOptions options;
|
[[gnu::cleanup(ffDestroyWeatherOptions)]] FFWeatherOptions options;
|
||||||
ffInitWeatherOptions(&options);
|
ffInitWeatherOptions(&options);
|
||||||
ffPrepareWeather(&options);
|
ffPrepareWeather(&options);
|
||||||
}
|
}
|
||||||
@@ -175,9 +175,9 @@ static bool parseStructureCommand(
|
|||||||
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(line[0]) - 'A']; *modules; ++modules) {
|
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(line[0]) - 'A']; *modules; ++modules) {
|
||||||
FFModuleBaseInfo* baseInfo = *modules;
|
FFModuleBaseInfo* baseInfo = *modules;
|
||||||
if (ffStrEqualsIgnCase(line, baseInfo->name)) {
|
if (ffStrEqualsIgnCase(line, baseInfo->name)) {
|
||||||
uint8_t optionBuf[FF_OPTION_MAX_SIZE];
|
alignas(uint64_t) uint8_t optionBuf[FF_OPTION_MAX_SIZE];
|
||||||
baseInfo->initOptions(optionBuf);
|
baseInfo->initOptions(optionBuf);
|
||||||
if (data->resultDoc != NULL) {
|
if (data->resultDoc != nullptr) {
|
||||||
fn(data, baseInfo, optionBuf);
|
fn(data, baseInfo, optionBuf);
|
||||||
} else {
|
} else {
|
||||||
baseInfo->printModule(optionBuf);
|
baseInfo->printModule(optionBuf);
|
||||||
@@ -194,7 +194,7 @@ static bool parseStructureCommand(
|
|||||||
yyjson_mut_obj_add_str(doc, module, "type", line);
|
yyjson_mut_obj_add_str(doc, module, "type", line);
|
||||||
yyjson_mut_obj_add_str(doc, module, "error", "Unknown module type");
|
yyjson_mut_obj_add_str(doc, module, "error", "Unknown module type");
|
||||||
} else {
|
} else {
|
||||||
ffPrintError(line, 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "<no implementation provided>");
|
ffPrintError(line, 0, nullptr, FF_PRINT_TYPE_NO_CUSTOM_KEY, "<no implementation provided>");
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -203,7 +203,7 @@ void ffPrintCommandOption(FFdata* data) {
|
|||||||
// Parse the structure and call the modules
|
// Parse the structure and call the modules
|
||||||
int32_t thres = instance.config.display.stat;
|
int32_t thres = instance.config.display.stat;
|
||||||
|
|
||||||
char* moduleType = NULL;
|
char* moduleType = nullptr;
|
||||||
size_t moduleLen = 0;
|
size_t moduleLen = 0;
|
||||||
while (ffStrbufGetdelim(&moduleType, &moduleLen, ':', &data->structure)) {
|
while (ffStrbufGetdelim(&moduleType, &moduleLen, ':', &data->structure)) {
|
||||||
if (ffStrbufSeparatedContainIgnCaseS(&data->structureDisabled, moduleType, ':')) {
|
if (ffStrbufSeparatedContainIgnCaseS(&data->structureDisabled, moduleType, ':')) {
|
||||||
@@ -244,12 +244,7 @@ void ffPrintCommandOption(FFdata* data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ffMigrateCommandOptionToJsonc(FFdata* data) {
|
void ffMigrateCommandOptionToJsonc(FFdata* data) {
|
||||||
// If we don't have a custom structure, use the default one
|
char* moduleType = nullptr;
|
||||||
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;
|
size_t moduleLen = 0;
|
||||||
while (ffStrbufGetdelim(&moduleType, &moduleLen, ':', &data->structure)) {
|
while (ffStrbufGetdelim(&moduleType, &moduleLen, ':', &data->structure)) {
|
||||||
if (ffStrbufSeparatedContainIgnCaseS(&data->structureDisabled, moduleType, ':')) {
|
if (ffStrbufSeparatedContainIgnCaseS(&data->structureDisabled, moduleType, ':')) {
|
||||||
|
|||||||
+17
-17
@@ -19,7 +19,7 @@ static bool loadLibSymbols(FFDBusLibrary* lib) {
|
|||||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_unref, false)
|
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_unref, false)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_connection_send_with_reply_and_block, false)
|
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_connection_send_with_reply_and_block, false)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_connection_unref, false)
|
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_connection_unref, false)
|
||||||
dbus = NULL; // don't auto dlclose
|
dbus = nullptr; // don't auto dlclose
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,27 +33,27 @@ static const FFDBusLibrary* loadLib(void) {
|
|||||||
loadSuccess = loadLibSymbols(&lib);
|
loadSuccess = loadLibSymbols(&lib);
|
||||||
}
|
}
|
||||||
|
|
||||||
return loadSuccess ? &lib : NULL;
|
return loadSuccess ? &lib : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ffDBusLoadData(DBusBusType busType, FFDBusData* data) {
|
const char* ffDBusLoadData(DBusBusType busType, FFDBusData* data) {
|
||||||
data->lib = loadLib();
|
data->lib = loadLib();
|
||||||
if (data->lib == NULL) {
|
if (data->lib == nullptr) {
|
||||||
return "Failed to load DBus library";
|
return "Failed to load DBus library";
|
||||||
}
|
}
|
||||||
|
|
||||||
data->connection = data->lib->ffdbus_bus_get(busType, NULL);
|
data->connection = data->lib->ffdbus_bus_get(busType, nullptr);
|
||||||
if (data->connection == NULL) {
|
if (data->connection == nullptr) {
|
||||||
return "Failed to connect to DBus";
|
return "Failed to connect to DBus";
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ffDBusDestroyData(FFDBusData* data) {
|
void ffDBusDestroyData(FFDBusData* data) {
|
||||||
if (data->connection != NULL) {
|
if (data->connection != nullptr) {
|
||||||
data->lib->ffdbus_connection_unref(data->connection);
|
data->lib->ffdbus_connection_unref(data->connection);
|
||||||
data->connection = NULL;
|
data->connection = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ bool ffDBusGetString(FFDBusData* dbus, DBusMessageIter* iter, FFstrbuf* result)
|
|||||||
int argType = dbus->lib->ffdbus_message_iter_get_arg_type(iter);
|
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;
|
const char* value = nullptr;
|
||||||
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
|
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
|
||||||
|
|
||||||
if (!ffStrSet(value)) {
|
if (!ffStrSet(value)) {
|
||||||
@@ -254,8 +254,8 @@ bool ffDBusGetInt(FFDBusData* dbus, DBusMessageIter* iter, int64_t* 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);
|
DBusMessage* message = dbus->lib->ffdbus_message_new_method_call(busName, objectPath, interface, method);
|
||||||
if (message == NULL) {
|
if (message == nullptr) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arg1) {
|
if (arg1) {
|
||||||
@@ -266,7 +266,7 @@ DBusMessage* ffDBusGetMethodReply(FFDBusData* dbus, const char* busName, const c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DBusMessage* reply = dbus->lib->ffdbus_connection_send_with_reply_and_block(dbus->connection, message, instance.config.general.processingTimeout, NULL);
|
DBusMessage* reply = dbus->lib->ffdbus_connection_send_with_reply_and_block(dbus->connection, message, instance.config.general.processingTimeout, nullptr);
|
||||||
|
|
||||||
dbus->lib->ffdbus_message_unref(message);
|
dbus->lib->ffdbus_message_unref(message);
|
||||||
|
|
||||||
@@ -275,8 +275,8 @@ DBusMessage* ffDBusGetMethodReply(FFDBusData* dbus, const char* busName, const c
|
|||||||
|
|
||||||
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");
|
DBusMessage* message = dbus->lib->ffdbus_message_new_method_call(busName, objectPath, "org.freedesktop.DBus.Properties", "Get");
|
||||||
if (message == NULL) {
|
if (message == nullptr) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbus->lib->ffdbus_message_append_args(message,
|
dbus->lib->ffdbus_message_append_args(message,
|
||||||
@@ -286,7 +286,7 @@ DBusMessage* ffDBusGetProperty(FFDBusData* dbus, const char* busName, const char
|
|||||||
&property,
|
&property,
|
||||||
DBUS_TYPE_INVALID);
|
DBUS_TYPE_INVALID);
|
||||||
|
|
||||||
DBusMessage* reply = dbus->lib->ffdbus_connection_send_with_reply_and_block(dbus->connection, message, instance.config.general.processingTimeout, NULL);
|
DBusMessage* reply = dbus->lib->ffdbus_connection_send_with_reply_and_block(dbus->connection, message, instance.config.general.processingTimeout, nullptr);
|
||||||
|
|
||||||
dbus->lib->ffdbus_message_unref(message);
|
dbus->lib->ffdbus_message_unref(message);
|
||||||
|
|
||||||
@@ -295,7 +295,7 @@ DBusMessage* ffDBusGetProperty(FFDBusData* dbus, const char* busName, const char
|
|||||||
|
|
||||||
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);
|
DBusMessage* reply = ffDBusGetProperty(dbus, busName, objectPath, interface, property);
|
||||||
if (reply == NULL) {
|
if (reply == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,7 +314,7 @@ bool ffDBusGetPropertyString(FFDBusData* dbus, const char* busName, const char*
|
|||||||
|
|
||||||
bool ffDBusGetPropertyUint(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, uint64_t* result) {
|
bool ffDBusGetPropertyUint(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, uint64_t* result) {
|
||||||
DBusMessage* reply = ffDBusGetProperty(dbus, busName, objectPath, interface, property);
|
DBusMessage* reply = ffDBusGetProperty(dbus, busName, objectPath, interface, property);
|
||||||
if (reply == NULL) {
|
if (reply == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ const char* ffDebugWin32Error(DWORD errorCode) {
|
|||||||
wchar_t bufferW[256];
|
wchar_t bufferW[256];
|
||||||
ULONG len = FormatMessageW(
|
ULONG len = FormatMessageW(
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
NULL,
|
nullptr,
|
||||||
(DWORD) errorCode,
|
(DWORD) errorCode,
|
||||||
0,
|
0,
|
||||||
bufferW,
|
bufferW,
|
||||||
ARRAY_SIZE(bufferW),
|
ARRAY_SIZE(bufferW),
|
||||||
NULL);
|
nullptr);
|
||||||
|
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
snprintf(buffer, sizeof(buffer), "Unknown error code (%lu)", errorCode);
|
snprintf(buffer, sizeof(buffer), "Unknown error code (%lu)", errorCode);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ void ffFontInit(FFfont* font) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void strbufAppendNSExcludingC(FFstrbuf* strbuf, uint32_t length, const char* value, char exclude) {
|
static void strbufAppendNSExcludingC(FFstrbuf* strbuf, uint32_t length, const char* value, char exclude) {
|
||||||
if (value == NULL || length == 0) {
|
if (value == nullptr || length == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,7 +151,7 @@ static void fontPangoParseWord(const char** data, FFfont* font, FFstrbuf* altern
|
|||||||
ffStrStartsWithIgnCase(wordStart, "Black") ||
|
ffStrStartsWithIgnCase(wordStart, "Black") ||
|
||||||
ffStrStartsWithIgnCase(wordStart, "Condensed") ||
|
ffStrStartsWithIgnCase(wordStart, "Condensed") ||
|
||||||
ffStrStartsWithIgnCase(wordStart, "Expanded")) {
|
ffStrStartsWithIgnCase(wordStart, "Expanded")) {
|
||||||
if (alternativeBuffer == NULL) {
|
if (alternativeBuffer == nullptr) {
|
||||||
alternativeBuffer = FF_LIST_ADD(FFstrbuf, font->styles);
|
alternativeBuffer = FF_LIST_ADD(FFstrbuf, font->styles);
|
||||||
ffStrbufInit(alternativeBuffer);
|
ffStrbufInit(alternativeBuffer);
|
||||||
}
|
}
|
||||||
@@ -169,7 +169,7 @@ static void fontPangoParseWord(const char** data, FFfont* font, FFstrbuf* altern
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alternativeBuffer != NULL) {
|
if (alternativeBuffer != nullptr) {
|
||||||
strbufAppendNSExcludingC(alternativeBuffer, wordLength, wordStart, '-');
|
strbufAppendNSExcludingC(alternativeBuffer, wordLength, wordStart, '-');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -184,7 +184,7 @@ void ffFontInitPango(FFfont* font, const char* data) {
|
|||||||
ffFontInit(font);
|
ffFontInit(font);
|
||||||
|
|
||||||
while (*data != '\0' && *data != '`' && *data != '\\') {
|
while (*data != '\0' && *data != '`' && *data != '\\') {
|
||||||
fontPangoParseWord(&data, font, NULL);
|
fontPangoParseWord(&data, font, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
fontInitPretty(font);
|
fontInitPretty(font);
|
||||||
@@ -329,8 +329,8 @@ void ffFontInitXft(FFfont* font, const char* xft) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Try parse trailing "-<number>" as size, otherwise entire head is name
|
// Try parse trailing "-<number>" as size, otherwise entire head is name
|
||||||
const char* dashPos = NULL;
|
const char* dashPos = nullptr;
|
||||||
const char* sizeStart = NULL;
|
const char* sizeStart = nullptr;
|
||||||
|
|
||||||
for (const char* q = headEnd; q > headStart;) {
|
for (const char* q = headEnd; q > headStart;) {
|
||||||
--q;
|
--q;
|
||||||
@@ -488,7 +488,7 @@ void ffFontInitMoveValues(FFfont* font, FFstrbuf* name, FFstrbuf* size, FFstrbuf
|
|||||||
|
|
||||||
void ffFontInitWithSpace(FFfont* font, const char* rawName) {
|
void ffFontInitWithSpace(FFfont* font, const char* rawName) {
|
||||||
const char* pspace = strrchr(rawName, ' ');
|
const char* pspace = strrchr(rawName, ' ');
|
||||||
if (pspace == NULL) {
|
if (pspace == nullptr) {
|
||||||
ffFontInitCopy(font, rawName);
|
ffFontInitCopy(font, rawName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-19
@@ -78,7 +78,7 @@ static uint32_t getArgumentIndex(const char* placeholderValue, uint32_t numArgs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (firstChar >= '0' && firstChar <= '9') {
|
if (firstChar >= '0' && firstChar <= '9') {
|
||||||
char* pEnd = NULL;
|
char* pEnd = nullptr;
|
||||||
uint32_t result = (uint32_t) strtoul(placeholderValue, &pEnd, 10);
|
uint32_t result = (uint32_t) strtoul(placeholderValue, &pEnd, 10);
|
||||||
if (result > numArgs) {
|
if (result > numArgs) {
|
||||||
return UINT32_MAX;
|
return UINT32_MAX;
|
||||||
@@ -109,10 +109,24 @@ static inline void appendInvalidPlaceholder(FFstrbuf* buffer, const char* start,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline bool formatArgSet(const FFformatarg* arg) {
|
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 && *(int32_t*) 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_UINT64 && *(uint64_t*) arg->value > 0) || (arg->type == FF_ARG_TYPE_BOOL && *(bool*) arg->value) || (arg->type == FF_ARG_TYPE_LIST && ((FFlist*) arg->value)->length > 0));
|
// clang-format off
|
||||||
|
return arg->value != nullptr && (
|
||||||
|
(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 && *(int32_t*) 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_UINT64 && *(uint64_t*) arg->value > 0) ||
|
||||||
|
(arg->type == FF_ARG_TYPE_BOOL && *(bool*) arg->value) ||
|
||||||
|
(arg->type == FF_ARG_TYPE_LIST && ((FFlist*) arg->value)->length > 0)
|
||||||
|
);
|
||||||
|
// clang-format on
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_A_UNUSED static inline void normalizeArgName(FFstrbuf* dst, const char* src) {
|
[[maybe_unused]] static inline void normalizeArgName(FFstrbuf* dst, const char* src) {
|
||||||
ffStrbufClear(dst);
|
ffStrbufClear(dst);
|
||||||
bool flag = false;
|
bool flag = false;
|
||||||
for (const char* p = src; *p; ++p) {
|
for (const char* p = src; *p; ++p) {
|
||||||
@@ -131,7 +145,7 @@ FF_A_UNUSED static inline void normalizeArgName(FFstrbuf* dst, const char* src)
|
|||||||
#include "common/lua.h"
|
#include "common/lua.h"
|
||||||
|
|
||||||
static void appendLuaError(FFstrbuf* buffer, const char* prefix, lua_State* L) {
|
static void appendLuaError(FFstrbuf* buffer, const char* prefix, lua_State* L) {
|
||||||
const char* err = lua_tolstring(L, -1, NULL);
|
const char* err = lua_tolstring(L, -1, nullptr);
|
||||||
if (err) {
|
if (err) {
|
||||||
const char* tmp = strchr(err, ':');
|
const char* tmp = strchr(err, ':');
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
@@ -228,12 +242,12 @@ static bool parseLuaString(FFstrbuf* buffer, const char* script, uint32_t script
|
|||||||
ffStrbufAppendS(buffer, "Lua result error: no result");
|
ffStrbufAppendS(buffer, "Lua result error: no result");
|
||||||
} else {
|
} else {
|
||||||
// Convert first result to string
|
// Convert first result to string
|
||||||
const char* res = lua_tolstring(L, 1, NULL);
|
const char* res = lua_tolstring(L, 1, nullptr);
|
||||||
if (res) {
|
if (res) {
|
||||||
ffStrbufAppendS(buffer, res);
|
ffStrbufAppendS(buffer, res);
|
||||||
} else {
|
} else {
|
||||||
luaL_tolstring(L, 1, NULL);
|
luaL_tolstring(L, 1, nullptr);
|
||||||
const char* sval = lua_tolstring(L, -1, NULL);
|
const char* sval = lua_tolstring(L, -1, nullptr);
|
||||||
if (sval) {
|
if (sval) {
|
||||||
ffStrbufAppendS(buffer, sval);
|
ffStrbufAppendS(buffer, sval);
|
||||||
}
|
}
|
||||||
@@ -273,10 +287,10 @@ struct FFQuickJSData {
|
|||||||
|
|
||||||
static const char* loadQuickJSState(void) {
|
static const char* loadQuickJSState(void) {
|
||||||
if (qjsData.inited) {
|
if (qjsData.inited) {
|
||||||
if (qjsData.ctx == NULL) {
|
if (qjsData.ctx == nullptr) {
|
||||||
return "QuickJS is not available";
|
return "QuickJS is not available";
|
||||||
}
|
}
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
qjsData.inited = true;
|
qjsData.inited = true;
|
||||||
@@ -301,20 +315,20 @@ static const char* loadQuickJSState(void) {
|
|||||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libqjs, qjsData, JS_FreeValue)
|
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libqjs, qjsData, JS_FreeValue)
|
||||||
|
|
||||||
qjsData.rt = qjsData.ffJS_NewRuntime();
|
qjsData.rt = qjsData.ffJS_NewRuntime();
|
||||||
if (qjsData.rt == NULL) {
|
if (qjsData.rt == nullptr) {
|
||||||
return "JS_NewRuntime() failed";
|
return "JS_NewRuntime() failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
qjsData.ctx = qjsData.ffJS_NewContext(qjsData.rt);
|
qjsData.ctx = qjsData.ffJS_NewContext(qjsData.rt);
|
||||||
if (qjsData.ctx == NULL) {
|
if (qjsData.ctx == nullptr) {
|
||||||
qjsData.ffJS_FreeRuntime(qjsData.rt);
|
qjsData.ffJS_FreeRuntime(qjsData.rt);
|
||||||
qjsData.rt = NULL;
|
qjsData.rt = nullptr;
|
||||||
return "JS_NewContext() failed";
|
return "JS_NewContext() failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
libqjs = NULL; // don't close quickjs
|
libqjs = nullptr; // don't close quickjs
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool parseQuickJSString(FFstrbuf* buffer, const char* script, uint32_t scriptLen, uint32_t numArgs, const FFformatarg* arguments) {
|
static bool parseQuickJSString(FFstrbuf* buffer, const char* script, uint32_t scriptLen, uint32_t numArgs, const FFformatarg* arguments) {
|
||||||
@@ -401,7 +415,7 @@ static bool parseQuickJSString(FFstrbuf* buffer, const char* script, uint32_t sc
|
|||||||
bool ret = false;
|
bool ret = false;
|
||||||
if (JS_IsException(result)) {
|
if (JS_IsException(result)) {
|
||||||
JSValue exc = qjsData.ffJS_GetException(ctx);
|
JSValue exc = qjsData.ffJS_GetException(ctx);
|
||||||
const char* message = qjsData.ffJS_ToCStringLen2(ctx, NULL, exc, false);
|
const char* message = qjsData.ffJS_ToCStringLen2(ctx, nullptr, exc, false);
|
||||||
qjsData.ffJS_FreeValue(ctx, exc);
|
qjsData.ffJS_FreeValue(ctx, exc);
|
||||||
ffStrbufAppendF(buffer, "Qjs runtime error: %s", message ?: "unknown");
|
ffStrbufAppendF(buffer, "Qjs runtime error: %s", message ?: "unknown");
|
||||||
if (message) {
|
if (message) {
|
||||||
@@ -587,7 +601,7 @@ static bool parseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint3
|
|||||||
|
|
||||||
// test for constant or env var, if so evaluate it
|
// test for constant or env var, if so evaluate it
|
||||||
if (firstChar == '$') {
|
if (firstChar == '$') {
|
||||||
char* pend = NULL;
|
char* pend = nullptr;
|
||||||
int32_t indexSigned = (int32_t) strtol(placeholderValue.chars + 1, &pend, 10);
|
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
|
// treat placeholder as an environment variable
|
||||||
@@ -620,7 +634,7 @@ static bool parseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint3
|
|||||||
cSep = *pSep;
|
cSep = *pSep;
|
||||||
*pSep = '\0';
|
*pSep = '\0';
|
||||||
} else {
|
} else {
|
||||||
pSep = NULL;
|
pSep = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t index = getArgumentIndex(placeholderValue.chars, numArgs, arguments);
|
uint32_t index = getArgumentIndex(placeholderValue.chars, numArgs, arguments);
|
||||||
@@ -646,7 +660,7 @@ static bool parseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint3
|
|||||||
FF_STRBUF_AUTO_DESTROY trailingEscape = ffStrbufCreate();
|
FF_STRBUF_AUTO_DESTROY trailingEscape = ffStrbufCreate();
|
||||||
skipAnsiEscape(&tempString, buffer, &trailingEscape);
|
skipAnsiEscape(&tempString, buffer, &trailingEscape);
|
||||||
|
|
||||||
char* pEnd = NULL;
|
char* pEnd = nullptr;
|
||||||
int32_t start = (int32_t) strtol(pSep + 1, &pEnd, 10);
|
int32_t start = (int32_t) strtol(pSep + 1, &pEnd, 10);
|
||||||
if (start < 0) {
|
if (start < 0) {
|
||||||
start = (int32_t) tempString.length + start;
|
start = (int32_t) tempString.length + start;
|
||||||
@@ -680,7 +694,7 @@ static bool parseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint3
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
char* pEnd = NULL;
|
char* pEnd = nullptr;
|
||||||
int32_t truncLength = (int32_t) strtol(pSep + 1, &pEnd, 10);
|
int32_t truncLength = (int32_t) strtol(pSep + 1, &pEnd, 10);
|
||||||
if (*pEnd != '\0') {
|
if (*pEnd != '\0') {
|
||||||
*pSep = cSep;
|
*pSep = cSep;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -105,12 +105,12 @@ static void resetConsole(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
BOOL WINAPI consoleHandler(FF_A_UNUSED DWORD signal) {
|
BOOL WINAPI consoleHandler([[maybe_unused]] DWORD signal) {
|
||||||
resetConsole();
|
resetConsole();
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static void exitSignalHandler(FF_A_UNUSED int signal) {
|
static void exitSignalHandler([[maybe_unused]] int signal) {
|
||||||
resetConsole();
|
resetConsole();
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
@@ -123,26 +123,26 @@ void ffStart(void) {
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
SetErrorMode(SEM_FAILCRITICALERRORS);
|
SetErrorMode(SEM_FAILCRITICALERRORS);
|
||||||
if (instance.config.display.noBuffer) {
|
if (instance.config.display.noBuffer) {
|
||||||
setvbuf(stdout, NULL, _IONBF, 0);
|
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||||
} else {
|
} else {
|
||||||
setvbuf(stdout, NULL, _IOFBF, 4096);
|
setvbuf(stdout, nullptr, _IOFBF, 4096);
|
||||||
}
|
}
|
||||||
SetConsoleCtrlHandler(consoleHandler, TRUE);
|
SetConsoleCtrlHandler(consoleHandler, TRUE);
|
||||||
#else
|
#else
|
||||||
if (instance.config.display.noBuffer) {
|
if (instance.config.display.noBuffer) {
|
||||||
setvbuf(stdout, NULL, _IONBF, 0);
|
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||||
}
|
}
|
||||||
struct sigaction action;
|
struct sigaction action;
|
||||||
sigemptyset(&action.sa_mask);
|
sigemptyset(&action.sa_mask);
|
||||||
action.sa_flags = 0;
|
action.sa_flags = 0;
|
||||||
action.sa_handler = exitSignalHandler;
|
action.sa_handler = exitSignalHandler;
|
||||||
sigaction(SIGINT, &action, NULL);
|
sigaction(SIGINT, &action, nullptr);
|
||||||
sigaction(SIGTERM, &action, NULL);
|
sigaction(SIGTERM, &action, nullptr);
|
||||||
sigaction(SIGQUIT, &action, NULL);
|
sigaction(SIGQUIT, &action, nullptr);
|
||||||
sigset_t newmask;
|
sigset_t newmask;
|
||||||
sigemptyset(&newmask);
|
sigemptyset(&newmask);
|
||||||
sigaddset(&newmask, SIGCHLD);
|
sigaddset(&newmask, SIGCHLD);
|
||||||
sigprocmask(SIG_BLOCK, &newmask, NULL);
|
sigprocmask(SIG_BLOCK, &newmask, nullptr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// reset everything to default before we start printing
|
// reset everything to default before we start printing
|
||||||
|
|||||||
+10
-10
@@ -22,8 +22,8 @@
|
|||||||
static void createSubfolders(const char* fileName) {
|
static void createSubfolders(const char* fileName) {
|
||||||
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate();
|
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate();
|
||||||
|
|
||||||
const char* token = NULL;
|
const char* token = nullptr;
|
||||||
while ((token = strchr(fileName, '/')) != NULL) {
|
while ((token = strchr(fileName, '/')) != nullptr) {
|
||||||
ffStrbufAppendNS(&path, (uint32_t) (token - fileName + 1), fileName);
|
ffStrbufAppendNS(&path, (uint32_t) (token - fileName + 1), fileName);
|
||||||
mkdir(path.chars, S_IRWXU | S_IRGRP | S_IROTH);
|
mkdir(path.chars, S_IRWXU | S_IRGRP | S_IROTH);
|
||||||
fileName = token + 1;
|
fileName = token + 1;
|
||||||
@@ -34,7 +34,7 @@ bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data) {
|
|||||||
int openFlagsModes = O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC;
|
int openFlagsModes = O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC;
|
||||||
mode_t openFlagsRights = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
|
mode_t openFlagsRights = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
|
||||||
|
|
||||||
int FF_AUTO_CLOSE_FD fd = open(fileName, openFlagsModes, openFlagsRights);
|
FF_AUTO_CLOSE_FD int fd = open(fileName, openFlagsModes, openFlagsRights);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
if (errno == ENOENT) {
|
if (errno == ENOENT) {
|
||||||
createSubfolders(fileName);
|
createSubfolders(fileName);
|
||||||
@@ -119,7 +119,7 @@ bool ffPathExpandEnv(const char* in, FFstrbuf* out) {
|
|||||||
| GLOB_BRACE
|
| GLOB_BRACE
|
||||||
#endif
|
#endif
|
||||||
,
|
,
|
||||||
NULL,
|
nullptr,
|
||||||
&gb) != 0)
|
&gb) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -174,7 +174,7 @@ const char* ffGetTerminalResponse(const char* request, int nParams, const char*
|
|||||||
fd_set rd;
|
fd_set rd;
|
||||||
FD_ZERO(&rd);
|
FD_ZERO(&rd);
|
||||||
FD_SET(ftty, &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, nullptr, nullptr, &(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";
|
return "select(/dev/tty) timeout or failed";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -213,7 +213,7 @@ const char* ffGetTerminalResponse(const char* request, int nParams, const char*
|
|||||||
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ffSuppressIO(bool suppress) {
|
bool ffSuppressIO(bool suppress) {
|
||||||
@@ -258,14 +258,14 @@ void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indenta
|
|||||||
}
|
}
|
||||||
|
|
||||||
FF_AUTO_CLOSE_DIR DIR* dir = fdopendir(dfd);
|
FF_AUTO_CLOSE_DIR DIR* dir = fdopendir(dfd);
|
||||||
if (dir == NULL) {
|
if (dir == nullptr) {
|
||||||
close(dfd);
|
close(dfd);
|
||||||
return; // Should not happen
|
return; // Should not happen
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t folderLength = folder->length;
|
uint32_t folderLength = folder->length;
|
||||||
|
|
||||||
if (pretty && folderName != NULL) {
|
if (pretty && folderName != nullptr) {
|
||||||
for (uint8_t i = 0; i < indentation - 1; i++) {
|
for (uint8_t i = 0; i < indentation - 1; i++) {
|
||||||
fputs(" | ", stdout);
|
fputs(" | ", stdout);
|
||||||
}
|
}
|
||||||
@@ -274,7 +274,7 @@ void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indenta
|
|||||||
|
|
||||||
struct dirent* entry;
|
struct dirent* entry;
|
||||||
|
|
||||||
while ((entry = readdir(dir)) != NULL) {
|
while ((entry = readdir(dir)) != nullptr) {
|
||||||
if (entry->d_name[0] == '.') { // skip hidden files
|
if (entry->d_name[0] == '.') { // skip hidden files
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -316,7 +316,7 @@ void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indenta
|
|||||||
void ffListFilesRecursively(const char* path, bool pretty) {
|
void ffListFilesRecursively(const char* path, bool pretty) {
|
||||||
FF_STRBUF_AUTO_DESTROY folder = ffStrbufCreateS(path);
|
FF_STRBUF_AUTO_DESTROY folder = ffStrbufCreateS(path);
|
||||||
ffStrbufEnsureEndsWithC(&folder, '/');
|
ffStrbufEnsureEndsWithC(&folder, '/');
|
||||||
listFilesRecursively(folder.length, &folder, 0, NULL, pretty);
|
listFilesRecursively(folder.length, &folder, 0, nullptr, pretty);
|
||||||
}
|
}
|
||||||
|
|
||||||
FFNativeFD ffGetNullFD(void) {
|
FFNativeFD ffGetNullFD(void) {
|
||||||
|
|||||||
@@ -20,10 +20,10 @@ static bool createSubfolders(wchar_t* fileName) {
|
|||||||
fileName,
|
fileName,
|
||||||
FILE_LIST_DIRECTORY | FILE_TRAVERSE | SYNCHRONIZE,
|
FILE_LIST_DIRECTORY | FILE_TRAVERSE | SYNCHRONIZE,
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
NULL,
|
nullptr,
|
||||||
OPEN_EXISTING,
|
OPEN_EXISTING,
|
||||||
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_FLAG_BACKUP_SEMANTICS,
|
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_FLAG_BACKUP_SEMANTICS,
|
||||||
NULL);
|
nullptr);
|
||||||
|
|
||||||
ptr[3] = saved;
|
ptr[3] = saved;
|
||||||
if (hRoot == INVALID_HANDLE_VALUE) {
|
if (hRoot == INVALID_HANDLE_VALUE) {
|
||||||
@@ -36,12 +36,12 @@ static bool createSubfolders(wchar_t* fileName) {
|
|||||||
// UNC path: \\server\share\...
|
// 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'\\');
|
wchar_t* serverEnd = wcschr(ptr + 2, L'\\');
|
||||||
if (serverEnd == NULL) {
|
if (serverEnd == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
wchar_t* shareEnd = wcschr(serverEnd + 1, L'\\');
|
wchar_t* shareEnd = wcschr(serverEnd + 1, L'\\');
|
||||||
if (shareEnd == NULL) {
|
if (shareEnd == nullptr) {
|
||||||
return true; // no parent subfolder exists before file name
|
return true; // no parent subfolder exists before file name
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,10 +52,10 @@ static bool createSubfolders(wchar_t* fileName) {
|
|||||||
fileName,
|
fileName,
|
||||||
FILE_LIST_DIRECTORY | FILE_TRAVERSE | SYNCHRONIZE,
|
FILE_LIST_DIRECTORY | FILE_TRAVERSE | SYNCHRONIZE,
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
NULL,
|
nullptr,
|
||||||
OPEN_EXISTING,
|
OPEN_EXISTING,
|
||||||
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_FLAG_BACKUP_SEMANTICS,
|
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_FLAG_BACKUP_SEMANTICS,
|
||||||
NULL);
|
nullptr);
|
||||||
|
|
||||||
*shareEnd = saved;
|
*shareEnd = saved;
|
||||||
if (hRoot == INVALID_HANDLE_VALUE) {
|
if (hRoot == INVALID_HANDLE_VALUE) {
|
||||||
@@ -73,10 +73,10 @@ static bool createSubfolders(wchar_t* fileName) {
|
|||||||
driveRoot,
|
driveRoot,
|
||||||
FILE_LIST_DIRECTORY | FILE_TRAVERSE | SYNCHRONIZE,
|
FILE_LIST_DIRECTORY | FILE_TRAVERSE | SYNCHRONIZE,
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
NULL,
|
nullptr,
|
||||||
OPEN_EXISTING,
|
OPEN_EXISTING,
|
||||||
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_FLAG_BACKUP_SEMANTICS,
|
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_FLAG_BACKUP_SEMANTICS,
|
||||||
NULL);
|
nullptr);
|
||||||
if (hRoot == INVALID_HANDLE_VALUE) {
|
if (hRoot == INVALID_HANDLE_VALUE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -86,7 +86,7 @@ static bool createSubfolders(wchar_t* fileName) {
|
|||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
wchar_t* token = wcschr(ptr, L'\\');
|
wchar_t* token = wcschr(ptr, L'\\');
|
||||||
if (token == NULL) {
|
if (token == nullptr) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,12 +113,12 @@ static bool createSubfolders(wchar_t* fileName) {
|
|||||||
.Attributes = OBJ_CASE_INSENSITIVE,
|
.Attributes = OBJ_CASE_INSENSITIVE,
|
||||||
},
|
},
|
||||||
&iosb,
|
&iosb,
|
||||||
NULL,
|
nullptr,
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
FILE_OPEN_IF,
|
FILE_OPEN_IF,
|
||||||
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
|
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
|
||||||
NULL,
|
nullptr,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
if (!NT_SUCCESS(status)) {
|
if (!NT_SUCCESS(status)) {
|
||||||
@@ -157,13 +157,13 @@ bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE FF_AUTO_CLOSE_FD handle = CreateFileW(fileNameW, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
FF_AUTO_CLOSE_FD HANDLE handle = CreateFileW(fileNameW, GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||||
if (handle == INVALID_HANDLE_VALUE) {
|
if (handle == INVALID_HANDLE_VALUE) {
|
||||||
if (GetLastError() == ERROR_PATH_NOT_FOUND) {
|
if (GetLastError() == ERROR_PATH_NOT_FOUND) {
|
||||||
if (!createSubfolders(fileNameW)) {
|
if (!createSubfolders(fileNameW)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
handle = CreateFileW(fileNameW, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
handle = CreateFileW(fileNameW, GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||||
if (handle == INVALID_HANDLE_VALUE) {
|
if (handle == INVALID_HANDLE_VALUE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -173,15 +173,15 @@ bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DWORD written;
|
DWORD written;
|
||||||
return !!WriteFile(handle, data, (DWORD) dataSize, &written, NULL);
|
return !!WriteFile(handle, data, (DWORD) dataSize, &written, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
ffStrbufEnsureFixedLengthFree(buffer, length);
|
||||||
DWORD bytesRead = 0;
|
DWORD bytesRead = 0;
|
||||||
while (
|
while (
|
||||||
length > 0 &&
|
length > 0 &&
|
||||||
ReadFile(handle, buffer->chars + buffer->length, length, &bytesRead, NULL) != FALSE &&
|
ReadFile(handle, buffer->chars + buffer->length, length, &bytesRead, nullptr) != FALSE &&
|
||||||
bytesRead > 0) {
|
bytesRead > 0) {
|
||||||
buffer->length += (uint32_t) bytesRead;
|
buffer->length += (uint32_t) bytesRead;
|
||||||
length -= (uint32_t) bytesRead;
|
length -= (uint32_t) bytesRead;
|
||||||
@@ -193,7 +193,7 @@ static inline void readUntilEOF(HANDLE handle, FFstrbuf* buffer) {
|
|||||||
uint32_t available = ffStrbufGetFree(buffer);
|
uint32_t available = ffStrbufGetFree(buffer);
|
||||||
DWORD bytesRead = 0;
|
DWORD bytesRead = 0;
|
||||||
while (
|
while (
|
||||||
ReadFile(handle, buffer->chars + buffer->length, available, &bytesRead, NULL) != FALSE &&
|
ReadFile(handle, buffer->chars + buffer->length, available, &bytesRead, nullptr) != FALSE &&
|
||||||
bytesRead > 0) {
|
bytesRead > 0) {
|
||||||
buffer->length += (uint32_t) bytesRead;
|
buffer->length += (uint32_t) bytesRead;
|
||||||
if ((uint32_t) bytesRead == available) {
|
if ((uint32_t) bytesRead == available) {
|
||||||
@@ -282,7 +282,7 @@ bool ffPathExpandEnv(const char* in, FFstrbuf* out) {
|
|||||||
len /= sizeof(wchar_t); // convert from bytes to characters
|
len /= sizeof(wchar_t); // convert from bytes to characters
|
||||||
|
|
||||||
SIZE_T outLen; // in characters, including null terminator
|
SIZE_T outLen; // in characters, including null terminator
|
||||||
if (!NT_SUCCESS(RtlExpandEnvironmentStrings(NULL, pathInW, len, pathOutW, ARRAY_SIZE(pathOutW), &outLen))) {
|
if (!NT_SUCCESS(RtlExpandEnvironmentStrings(nullptr, pathInW, len, pathOutW, ARRAY_SIZE(pathOutW), &outLen))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,7 +336,7 @@ bool ffSuppressIO(bool suppress) {
|
|||||||
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;
|
uint32_t folderLength = folder->length;
|
||||||
|
|
||||||
if (pretty && folderName != NULL) {
|
if (pretty && folderName != nullptr) {
|
||||||
for (uint8_t i = 0; i < indentation - 1; i++) {
|
for (uint8_t i = 0; i < indentation - 1; i++) {
|
||||||
fputs(" | ", stdout);
|
fputs(" | ", stdout);
|
||||||
}
|
}
|
||||||
@@ -381,7 +381,7 @@ void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indenta
|
|||||||
void ffListFilesRecursively(const char* path, bool pretty) {
|
void ffListFilesRecursively(const char* path, bool pretty) {
|
||||||
FF_STRBUF_AUTO_DESTROY folder = ffStrbufCreateS(path);
|
FF_STRBUF_AUTO_DESTROY folder = ffStrbufCreateS(path);
|
||||||
ffStrbufEnsureEndsWithC(&folder, '/');
|
ffStrbufEnsureEndsWithC(&folder, '/');
|
||||||
listFilesRecursively(folder.length, &folder, 0, NULL, pretty);
|
listFilesRecursively(folder.length, &folder, 0, nullptr, pretty);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ffGetTerminalResponse(const char* request, int nParams, const char* format, ...) {
|
const char* ffGetTerminalResponse(const char* request, int nParams, const char* format, ...) {
|
||||||
@@ -390,7 +390,7 @@ const char* ffGetTerminalResponse(const char* request, int nParams, const char*
|
|||||||
DWORD inputMode = 0;
|
DWORD inputMode = 0;
|
||||||
bool hasInputMode = !!GetConsoleMode(hInput, &inputMode);
|
bool hasInputMode = !!GetConsoleMode(hInput, &inputMode);
|
||||||
if (!hasInputMode) {
|
if (!hasInputMode) {
|
||||||
hConin = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, NULL);
|
hConin = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, nullptr);
|
||||||
hInput = hConin;
|
hInput = hConin;
|
||||||
hasInputMode = !!GetConsoleMode(hInput, &inputMode);
|
hasInputMode = !!GetConsoleMode(hInput, &inputMode);
|
||||||
}
|
}
|
||||||
@@ -404,10 +404,10 @@ const char* ffGetTerminalResponse(const char* request, int nParams, const char*
|
|||||||
FF_AUTO_CLOSE_FD HANDLE hConout = INVALID_HANDLE_VALUE;
|
FF_AUTO_CLOSE_FD HANDLE hConout = INVALID_HANDLE_VALUE;
|
||||||
DWORD outputMode;
|
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);
|
hConout = CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, nullptr);
|
||||||
hOutput = hConout;
|
hOutput = hConout;
|
||||||
}
|
}
|
||||||
WriteFile(hOutput, request, (DWORD) strlen(request), &bytes, NULL);
|
WriteFile(hOutput, request, (DWORD) strlen(request), &bytes, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -441,7 +441,7 @@ const char* ffGetTerminalResponse(const char* request, int nParams, const char*
|
|||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
DWORD bytes = 0;
|
DWORD bytes = 0;
|
||||||
if (!ReadFile(hInput, buffer + bytesRead, (DWORD) (sizeof(buffer) - 1 - bytesRead), &bytes, NULL) || bytes == 0) {
|
if (!ReadFile(hInput, buffer + bytesRead, (DWORD) (sizeof(buffer) - 1 - bytesRead), &bytes, nullptr) || bytes == 0) {
|
||||||
va_end(args);
|
va_end(args);
|
||||||
return "ReadFile() failed";
|
return "ReadFile() failed";
|
||||||
}
|
}
|
||||||
@@ -473,7 +473,7 @@ const char* ffGetTerminalResponse(const char* request, int nParams, const char*
|
|||||||
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
FFNativeFD ffGetNullFD(void) {
|
FFNativeFD ffGetNullFD(void) {
|
||||||
@@ -490,7 +490,7 @@ FFNativeFD ffGetNullFD(void) {
|
|||||||
0,
|
0,
|
||||||
&(SECURITY_ATTRIBUTES) {
|
&(SECURITY_ATTRIBUTES) {
|
||||||
.nLength = sizeof(SECURITY_ATTRIBUTES),
|
.nLength = sizeof(SECURITY_ATTRIBUTES),
|
||||||
.lpSecurityDescriptor = NULL,
|
.lpSecurityDescriptor = nullptr,
|
||||||
.bInheritHandle = TRUE,
|
.bInheritHandle = TRUE,
|
||||||
});
|
});
|
||||||
return hNullFile;
|
return hNullFile;
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair p
|
|||||||
for (const FFKeyValuePair* pPair = pairs; pPair->key; ++pPair) {
|
for (const FFKeyValuePair* pPair = pairs; pPair->key; ++pPair) {
|
||||||
if (intVal == pPair->value) {
|
if (intVal == pPair->value) {
|
||||||
*result = pPair->value;
|
*result = pPair->value;
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair p
|
|||||||
for (const FFKeyValuePair* pPair = pairs; pPair->key; ++pPair) {
|
for (const FFKeyValuePair* pPair = pairs; pPair->key; ++pPair) {
|
||||||
if (ffStrEqualsIgnCase(strVal, pPair->key)) {
|
if (ffStrEqualsIgnCase(strVal, pPair->key)) {
|
||||||
*result = pPair->value;
|
*result = pPair->value;
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal, yyjson_
|
|||||||
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(type[0]) - 'A']; *modules; ++modules) {
|
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(type[0]) - 'A']; *modules; ++modules) {
|
||||||
FFModuleBaseInfo* baseInfo = *modules;
|
FFModuleBaseInfo* baseInfo = *modules;
|
||||||
if (ffStrEqualsIgnCase(type, baseInfo->name)) {
|
if (ffStrEqualsIgnCase(type, baseInfo->name)) {
|
||||||
uint8_t optionBuf[FF_OPTION_MAX_SIZE];
|
alignas(uint64_t) uint8_t optionBuf[FF_OPTION_MAX_SIZE];
|
||||||
baseInfo->initOptions(optionBuf);
|
baseInfo->initOptions(optionBuf);
|
||||||
if (jsonVal) {
|
if (jsonVal) {
|
||||||
baseInfo->parseJsonObject(optionBuf, jsonVal);
|
baseInfo->parseJsonObject(optionBuf, jsonVal);
|
||||||
@@ -139,7 +139,7 @@ static void prepareModuleJsonObject(const char* type, yyjson_val* module) {
|
|||||||
if (ffStrEqualsIgnCase(type, FF_CPUUSAGE_MODULE_NAME)) {
|
if (ffStrEqualsIgnCase(type, FF_CPUUSAGE_MODULE_NAME)) {
|
||||||
ffPrepareCPUUsage();
|
ffPrepareCPUUsage();
|
||||||
} else if (ffStrEqualsIgnCase(type, FF_COMMAND_MODULE_NAME)) {
|
} else if (ffStrEqualsIgnCase(type, FF_COMMAND_MODULE_NAME)) {
|
||||||
FF_A_CLEANUP(ffDestroyCommandOptions) FFCommandOptions options;
|
[[gnu::cleanup(ffDestroyCommandOptions)]] FFCommandOptions options;
|
||||||
ffInitCommandOptions(&options);
|
ffInitCommandOptions(&options);
|
||||||
if (module) {
|
if (module) {
|
||||||
ffCommandModuleInfo.parseJsonObject(&options, module);
|
ffCommandModuleInfo.parseJsonObject(&options, module);
|
||||||
@@ -154,7 +154,7 @@ static void prepareModuleJsonObject(const char* type, yyjson_val* module) {
|
|||||||
case 'd':
|
case 'd':
|
||||||
case 'D': {
|
case 'D': {
|
||||||
if (ffStrEqualsIgnCase(type, FF_DISKIO_MODULE_NAME)) {
|
if (ffStrEqualsIgnCase(type, FF_DISKIO_MODULE_NAME)) {
|
||||||
FF_A_CLEANUP(ffDestroyDiskIOOptions) FFDiskIOOptions options;
|
[[gnu::cleanup(ffDestroyDiskIOOptions)]] FFDiskIOOptions options;
|
||||||
ffInitDiskIOOptions(&options);
|
ffInitDiskIOOptions(&options);
|
||||||
if (module) {
|
if (module) {
|
||||||
ffDiskIOModuleInfo.parseJsonObject(&options, module);
|
ffDiskIOModuleInfo.parseJsonObject(&options, module);
|
||||||
@@ -169,7 +169,7 @@ static void prepareModuleJsonObject(const char* type, yyjson_val* module) {
|
|||||||
case 'n':
|
case 'n':
|
||||||
case 'N': {
|
case 'N': {
|
||||||
if (ffStrEqualsIgnCase(type, FF_NETIO_MODULE_NAME)) {
|
if (ffStrEqualsIgnCase(type, FF_NETIO_MODULE_NAME)) {
|
||||||
FF_A_CLEANUP(ffDestroyNetIOOptions) FFNetIOOptions options;
|
[[gnu::cleanup(ffDestroyNetIOOptions)]] FFNetIOOptions options;
|
||||||
ffInitNetIOOptions(&options);
|
ffInitNetIOOptions(&options);
|
||||||
if (module) {
|
if (module) {
|
||||||
ffNetIOModuleInfo.parseJsonObject(&options, module);
|
ffNetIOModuleInfo.parseJsonObject(&options, module);
|
||||||
@@ -184,7 +184,7 @@ static void prepareModuleJsonObject(const char* type, yyjson_val* module) {
|
|||||||
case 'p':
|
case 'p':
|
||||||
case 'P': {
|
case 'P': {
|
||||||
if (ffStrEqualsIgnCase(type, FF_PUBLICIP_MODULE_NAME)) {
|
if (ffStrEqualsIgnCase(type, FF_PUBLICIP_MODULE_NAME)) {
|
||||||
FF_A_CLEANUP(ffDestroyPublicIpOptions) FFPublicIPOptions options;
|
[[gnu::cleanup(ffDestroyPublicIpOptions)]] FFPublicIPOptions options;
|
||||||
ffInitPublicIpOptions(&options);
|
ffInitPublicIpOptions(&options);
|
||||||
if (module) {
|
if (module) {
|
||||||
ffPublicIPModuleInfo.parseJsonObject(&options, module);
|
ffPublicIPModuleInfo.parseJsonObject(&options, module);
|
||||||
@@ -199,7 +199,7 @@ static void prepareModuleJsonObject(const char* type, yyjson_val* module) {
|
|||||||
case 'w':
|
case 'w':
|
||||||
case 'W': {
|
case 'W': {
|
||||||
if (ffStrEqualsIgnCase(type, FF_WEATHER_MODULE_NAME)) {
|
if (ffStrEqualsIgnCase(type, FF_WEATHER_MODULE_NAME)) {
|
||||||
FF_A_CLEANUP(ffDestroyWeatherOptions) FFWeatherOptions options;
|
[[gnu::cleanup(ffDestroyWeatherOptions)]] FFWeatherOptions options;
|
||||||
ffInitWeatherOptions(&options);
|
ffInitWeatherOptions(&options);
|
||||||
if (module) {
|
if (module) {
|
||||||
ffWeatherModuleInfo.parseJsonObject(&options, module);
|
ffWeatherModuleInfo.parseJsonObject(&options, module);
|
||||||
@@ -244,7 +244,7 @@ static const char* printJsonConfig(FFdata* data, bool prepare) {
|
|||||||
|
|
||||||
yyjson_val* modules = yyjson_obj_get(root, "modules");
|
yyjson_val* modules = yyjson_obj_get(root, "modules");
|
||||||
if (!modules) {
|
if (!modules) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (!yyjson_is_arr(modules)) {
|
if (!yyjson_is_arr(modules)) {
|
||||||
return "Property 'modules' must be an array of strings or objects";
|
return "Property 'modules' must be an array of strings or objects";
|
||||||
@@ -263,7 +263,7 @@ static const char* printJsonConfig(FFdata* data, bool prepare) {
|
|||||||
yyjson_val* module = item;
|
yyjson_val* module = item;
|
||||||
const char* type = yyjson_get_str(module);
|
const char* type = yyjson_get_str(module);
|
||||||
if (type) {
|
if (type) {
|
||||||
module = NULL;
|
module = nullptr;
|
||||||
} else if (yyjson_is_obj(module)) {
|
} else if (yyjson_is_obj(module)) {
|
||||||
yyjson_val* conditions = yyjson_obj_get(module, "condition");
|
yyjson_val* conditions = yyjson_obj_get(module, "condition");
|
||||||
if (conditions) {
|
if (conditions) {
|
||||||
@@ -307,7 +307,7 @@ static const char* printJsonConfig(FFdata* data, bool prepare) {
|
|||||||
return "module object must contain a \"type\" key ( case sensitive )";
|
return "module object must contain a \"type\" key ( case sensitive )";
|
||||||
}
|
}
|
||||||
if (yyjson_obj_size(module) == 1) { // contains only Property type
|
if (yyjson_obj_size(module) == 1) { // contains only Property type
|
||||||
module = NULL;
|
module = nullptr;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return "modules must be an array of strings or objects";
|
return "modules must be an array of strings or objects";
|
||||||
@@ -347,7 +347,7 @@ static const char* printJsonConfig(FFdata* data, bool prepare) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ffPrintJsonConfig(FFdata* data, bool prepare) {
|
void ffPrintJsonConfig(FFdata* data, bool prepare) {
|
||||||
@@ -359,7 +359,7 @@ void ffPrintJsonConfig(FFdata* data, bool prepare) {
|
|||||||
yyjson_mut_obj_add_str(jsonDoc, obj, "error", error);
|
yyjson_mut_obj_add_str(jsonDoc, obj, "error", error);
|
||||||
yyjson_mut_doc_set_root(jsonDoc, obj);
|
yyjson_mut_doc_set_root(jsonDoc, obj);
|
||||||
} else {
|
} else {
|
||||||
ffPrintError("JsonConfig", 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "%s", error);
|
ffPrintError("JsonConfig", 0, nullptr, FF_PRINT_TYPE_NO_CUSTOM_KEY, "%s", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
bool ffKmodLoaded(const char* modName) {
|
bool ffKmodLoaded(const char* modName) {
|
||||||
FF_CFTYPE_AUTO_RELEASE CFStringRef name = CFStringCreateWithCString(kCFAllocatorDefault, modName, kCFStringEncodingUTF8);
|
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 identifiers = CFArrayCreate(kCFAllocatorDefault, (const void**) &name, 1, &kCFTypeArrayCallBacks);
|
||||||
FF_CFTYPE_AUTO_RELEASE CFArrayRef keys = CFArrayCreate(kCFAllocatorDefault, NULL, 0, NULL);
|
FF_CFTYPE_AUTO_RELEASE CFArrayRef keys = CFArrayCreate(kCFAllocatorDefault, nullptr, 0, nullptr);
|
||||||
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef kextInfo = KextManagerCopyLoadedKextInfo(identifiers, keys);
|
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef kextInfo = KextManagerCopyLoadedKextInfo(identifiers, keys);
|
||||||
return CFDictionaryContainsKey(kextInfo, name);
|
return CFDictionaryContainsKey(kextInfo, name);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
bool ffKmodLoaded(const char* modName) {
|
bool ffKmodLoaded(const char* modName) {
|
||||||
static FFstrbuf modules;
|
static FFstrbuf modules;
|
||||||
if (modules.chars == NULL) {
|
if (modules.chars == nullptr) {
|
||||||
ffStrbufInitS(&modules, "\n");
|
ffStrbufInitS(&modules, "\n");
|
||||||
ffAppendFileBuffer("/proc/modules", &modules);
|
ffAppendFileBuffer("/proc/modules", &modules);
|
||||||
}
|
}
|
||||||
@@ -21,5 +21,5 @@ bool ffKmodLoaded(const char* modName) {
|
|||||||
temp[0] = '\n';
|
temp[0] = '\n';
|
||||||
memcpy(temp + 1, modName, len);
|
memcpy(temp + 1, modName, len);
|
||||||
temp[1 + len] = ' ';
|
temp[1 + len] = ' ';
|
||||||
return memmem(modules.chars, modules.length, temp, len + 2) != NULL;
|
return memmem(modules.chars, modules.length, temp, len + 2) != nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,15 +4,15 @@
|
|||||||
#include <sys/module.h>
|
#include <sys/module.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
|
||||||
typedef struct FF_A_PACKED FFNbsdModList {
|
typedef struct [[gnu::packed]] FFNbsdModList {
|
||||||
int len;
|
int len;
|
||||||
modstat_t mods[];
|
modstat_t mods[];
|
||||||
} FFNbsdModList;
|
} FFNbsdModList;
|
||||||
|
|
||||||
bool ffKmodLoaded(const char* modName) {
|
bool ffKmodLoaded(const char* modName) {
|
||||||
static FFNbsdModList* list = NULL;
|
static FFNbsdModList* list = nullptr;
|
||||||
|
|
||||||
if (list == NULL) {
|
if (list == nullptr) {
|
||||||
struct iovec iov = {};
|
struct iovec iov = {};
|
||||||
|
|
||||||
for (size_t len = 8192;; len = iov.iov_len) {
|
for (size_t len = 8192;; len = iov.iov_len) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include "common/kmod.h"
|
#include "common/kmod.h"
|
||||||
|
|
||||||
bool ffKmodLoaded(FF_A_UNUSED const char* modName) {
|
bool ffKmodLoaded([[maybe_unused]] const char* modName) {
|
||||||
return true; // Don't generate kernel module related errors
|
return true; // Don't generate kernel module related errors
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
bool ffKmodLoaded(const char* modName) {
|
bool ffKmodLoaded(const char* modName) {
|
||||||
ULONG bufferSize = 0;
|
ULONG bufferSize = 0;
|
||||||
NtQuerySystemInformation(SystemModuleInformation, NULL, 0, &bufferSize);
|
NtQuerySystemInformation(SystemModuleInformation, nullptr, 0, &bufferSize);
|
||||||
if (bufferSize == 0) {
|
if (bufferSize == 0) {
|
||||||
return true; // ignore errors
|
return true; // ignore errors
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-19
@@ -27,7 +27,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void* libraryLoad(const char* path, int maxVersion) {
|
void* ffLibraryLoadSingle(const char* path, int maxVersion) {
|
||||||
void* result = dlopen(path, FF_DLOPEN_FLAGS);
|
void* result = dlopen(path, FF_DLOPEN_FLAGS);
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
@@ -35,7 +35,7 @@ static void* libraryLoad(const char* path, int maxVersion) {
|
|||||||
// libX.dll.1 never exists on Windows, while libX-1.dll may exist
|
// libX.dll.1 never exists on Windows, while libX-1.dll may exist
|
||||||
FF_UNUSED(maxVersion)
|
FF_UNUSED(maxVersion)
|
||||||
|
|
||||||
if (result != NULL) {
|
if (result != nullptr) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,11 +50,11 @@ static void* libraryLoad(const char* path, int maxVersion) {
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
if (result == NULL) {
|
if (result == nullptr) {
|
||||||
FF_DEBUG("dlopen(\"%s\"): %s", path, dlerror());
|
FF_DEBUG("dlopen(\"%s\"): %s", path, dlerror());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result != NULL || maxVersion < 0) {
|
if (result != nullptr || maxVersion < 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ static void* libraryLoad(const char* path, int maxVersion) {
|
|||||||
ffStrbufAppendSInt(&pathbuf, i);
|
ffStrbufAppendSInt(&pathbuf, i);
|
||||||
|
|
||||||
result = dlopen(pathbuf.chars, FF_DLOPEN_FLAGS);
|
result = dlopen(pathbuf.chars, FF_DLOPEN_FLAGS);
|
||||||
if (result != NULL) {
|
if (result != nullptr) {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
FF_DEBUG("dlopen(\"%s\"): %s", pathbuf.chars, dlerror());
|
FF_DEBUG("dlopen(\"%s\"): %s", pathbuf.chars, dlerror());
|
||||||
@@ -81,8 +81,8 @@ static void* libraryLoad(const char* path, int maxVersion) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* ffLibraryLoad(const char* path, int maxVersion, ...) {
|
void* ffLibraryLoadMulti(const char* path, int maxVersion, ...) {
|
||||||
void* result = libraryLoad(path, maxVersion);
|
void* result = ffLibraryLoadSingle(path, maxVersion);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
va_list defaultNames;
|
va_list defaultNames;
|
||||||
@@ -90,12 +90,12 @@ void* ffLibraryLoad(const char* path, int maxVersion, ...) {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
const char* pathRest = va_arg(defaultNames, const char*);
|
const char* pathRest = va_arg(defaultNames, const char*);
|
||||||
if (pathRest == NULL) {
|
if (pathRest == nullptr) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int maxVersionRest = va_arg(defaultNames, int);
|
int maxVersionRest = va_arg(defaultNames, int);
|
||||||
result = libraryLoad(pathRest, maxVersionRest);
|
result = ffLibraryLoadSingle(pathRest, maxVersionRest);
|
||||||
} while (!result);
|
} while (!result);
|
||||||
|
|
||||||
va_end(defaultNames);
|
va_end(defaultNames);
|
||||||
@@ -108,18 +108,18 @@ void* ffLibraryLoad(const char* path, int maxVersion, ...) {
|
|||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
|
|
||||||
void* dlopen(const char* path, FF_A_UNUSED int mode) {
|
void* dlopen(const char* path, [[maybe_unused]] int mode) {
|
||||||
wchar_t pathW[MAX_PATH + 1];
|
wchar_t pathW[MAX_PATH + 1];
|
||||||
ULONG pathWBytes = 0;
|
ULONG pathWBytes = 0;
|
||||||
|
|
||||||
NTSTATUS status = RtlUTF8ToUnicodeN(pathW, sizeof(pathW), &pathWBytes, path, (uint32_t) strlen(path) + 1);
|
NTSTATUS status = RtlUTF8ToUnicodeN(pathW, sizeof(pathW), &pathWBytes, path, (uint32_t) strlen(path) + 1);
|
||||||
if (!NT_SUCCESS(status)) {
|
if (!NT_SUCCESS(status)) {
|
||||||
FF_DEBUG("RtlUTF8ToUnicodeN failed for path %s with status 0x%08lX: %s", path, status, ffDebugNtStatus(status));
|
FF_DEBUG("RtlUTF8ToUnicodeN failed for path %s with status 0x%08lX: %s", path, status, ffDebugNtStatus(status));
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
PVOID module = NULL;
|
PVOID module = nullptr;
|
||||||
status = LdrLoadDll(NULL, NULL, &(UNICODE_STRING) {
|
status = LdrLoadDll(nullptr, nullptr, &(UNICODE_STRING) {
|
||||||
.Length = (USHORT) (pathWBytes - sizeof(wchar_t)), // Exclude null terminator
|
.Length = (USHORT) (pathWBytes - sizeof(wchar_t)), // Exclude null terminator
|
||||||
.MaximumLength = (USHORT) pathWBytes,
|
.MaximumLength = (USHORT) pathWBytes,
|
||||||
.Buffer = pathW,
|
.Buffer = pathW,
|
||||||
@@ -128,7 +128,7 @@ void* dlopen(const char* path, FF_A_UNUSED int mode) {
|
|||||||
|
|
||||||
if (!NT_SUCCESS(status)) {
|
if (!NT_SUCCESS(status)) {
|
||||||
FF_DEBUG("LdrLoadDll failed for path %s with status 0x%08lX: %s", path, status, ffDebugNtStatus(status));
|
FF_DEBUG("LdrLoadDll failed for path %s with status 0x%08lX: %s", path, status, ffDebugNtStatus(status));
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return module;
|
return module;
|
||||||
@@ -155,17 +155,17 @@ void* dlsym(void* handle, const char* symbol) {
|
|||||||
&address);
|
&address);
|
||||||
if (!NT_SUCCESS(status)) {
|
if (!NT_SUCCESS(status)) {
|
||||||
FF_DEBUG("LdrGetProcedureAddress failed for symbol %s with status 0x%08lX: %s", symbol, status, ffDebugNtStatus(status));
|
FF_DEBUG("LdrGetProcedureAddress failed for symbol %s with status 0x%08lX: %s", symbol, status, ffDebugNtStatus(status));
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* ffLibraryGetModule(const wchar_t* libraryFileName) {
|
void* ffLibraryGetModule(const wchar_t* libraryFileName) {
|
||||||
assert(libraryFileName != NULL && "Use \"ffGetPeb()->ImageBaseAddress\" instead");
|
assert(libraryFileName != nullptr && "Use \"ffGetPeb()->ImageBaseAddress\" instead");
|
||||||
|
|
||||||
void* module = NULL;
|
void* module = nullptr;
|
||||||
USHORT libraryFileNameBytes = (USHORT) (wcslen(libraryFileName) * sizeof(wchar_t) + sizeof(wchar_t));
|
USHORT libraryFileNameBytes = (USHORT) (wcslen(libraryFileName) * sizeof(wchar_t) + sizeof(wchar_t));
|
||||||
NTSTATUS status = LdrGetDllHandle(NULL, NULL, &(UNICODE_STRING) {
|
NTSTATUS status = LdrGetDllHandle(nullptr, nullptr, &(UNICODE_STRING) {
|
||||||
.Length = libraryFileNameBytes - sizeof(wchar_t),
|
.Length = libraryFileNameBytes - sizeof(wchar_t),
|
||||||
.MaximumLength = libraryFileNameBytes,
|
.MaximumLength = libraryFileNameBytes,
|
||||||
.Buffer = (wchar_t*) libraryFileName,
|
.Buffer = (wchar_t*) libraryFileName,
|
||||||
@@ -173,7 +173,7 @@ void* ffLibraryGetModule(const wchar_t* libraryFileName) {
|
|||||||
&module);
|
&module);
|
||||||
if (!NT_SUCCESS(status)) {
|
if (!NT_SUCCESS(status)) {
|
||||||
FF_DEBUG("LdrGetDllHandle failed for library %ls with status 0x%08lX: %s", libraryFileName, status, ffDebugNtStatus(status));
|
FF_DEBUG("LdrGetDllHandle failed for library %ls with status 0x%08lX: %s", libraryFileName, status, ffDebugNtStatus(status));
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ static int yyjsonEncode(lua_State* L) {
|
|||||||
pretty = (int) lua_toboolean(L, 2);
|
pretty = (int) lua_toboolean(L, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
yyjson_mut_doc* doc = yyjson_mut_doc_new(NULL);
|
yyjson_mut_doc* doc = yyjson_mut_doc_new(nullptr);
|
||||||
if (__builtin_expect(!doc, false)) {
|
if (__builtin_expect(!doc, false)) {
|
||||||
lua_pushlstring(L, "yyjson: yyjson_mut_doc_new() failed", strlen("yyjson: yyjson_mut_doc_new() failed"));
|
lua_pushlstring(L, "yyjson: yyjson_mut_doc_new() failed", strlen("yyjson: yyjson_mut_doc_new() failed"));
|
||||||
return lua_error(L);
|
return lua_error(L);
|
||||||
@@ -120,9 +120,9 @@ static int yyjsonEncode(lua_State* L) {
|
|||||||
|
|
||||||
size_t jsonLen;
|
size_t jsonLen;
|
||||||
yyjson_write_err err = {};
|
yyjson_write_err err = {};
|
||||||
FF_AUTO_FREE const char* jsonStr = yyjson_mut_write_opts(doc, YYJSON_WRITE_ALLOW_INF_AND_NAN | (pretty ? YYJSON_WRITE_PRETTY_TWO_SPACES : 0), NULL, &jsonLen, &err);
|
FF_AUTO_FREE const char* jsonStr = yyjson_mut_write_opts(doc, YYJSON_WRITE_ALLOW_INF_AND_NAN | (pretty ? YYJSON_WRITE_PRETTY_TWO_SPACES : 0), nullptr, &jsonLen, &err);
|
||||||
|
|
||||||
if (__builtin_expect(jsonStr != NULL, true)) {
|
if (__builtin_expect(jsonStr != nullptr, true)) {
|
||||||
lua_pushlstring(L, jsonStr, jsonLen);
|
lua_pushlstring(L, jsonStr, jsonLen);
|
||||||
yyjson_mut_doc_free(doc);
|
yyjson_mut_doc_free(doc);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -140,10 +140,10 @@ static int yyjsonEncode(lua_State* L) {
|
|||||||
|
|
||||||
const char* ffLuaLoadState(void) {
|
const char* ffLuaLoadState(void) {
|
||||||
if (luaData.inited) {
|
if (luaData.inited) {
|
||||||
if (luaData.L == NULL) {
|
if (luaData.L == nullptr) {
|
||||||
return "Lua library is not available";
|
return "Lua library is not available";
|
||||||
}
|
}
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
luaData.inited = true;
|
luaData.inited = true;
|
||||||
@@ -211,7 +211,7 @@ const char* ffLuaLoadState(void) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
lua_State* L = ffluaL_newstate();
|
lua_State* L = ffluaL_newstate();
|
||||||
if (L == NULL) {
|
if (L == nullptr) {
|
||||||
return "luaL_newstate() failed";
|
return "luaL_newstate() failed";
|
||||||
}
|
}
|
||||||
#if LUA_VERSION_NUM >= 505
|
#if LUA_VERSION_NUM >= 505
|
||||||
@@ -226,8 +226,8 @@ const char* ffLuaLoadState(void) {
|
|||||||
lua_pushcfunction(L, yyjsonEncode);
|
lua_pushcfunction(L, yyjsonEncode);
|
||||||
lua_setglobal(L, "json_encode");
|
lua_setglobal(L, "json_encode");
|
||||||
luaData.L = L;
|
luaData.L = L;
|
||||||
liblua = NULL; // don't close lua
|
liblua = nullptr; // don't close lua
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
void* memrchr(const void* s, int c, size_t n) {
|
void* memrchr(const void* s, int c, size_t n) {
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t uc = (uint8_t) c;
|
const uint8_t uc = (uint8_t) c;
|
||||||
@@ -17,5 +17,5 @@ void* memrchr(const void* s, int c, size_t n) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ get_rt_address(struct rt_msghdr* rtm, int desired) {
|
|||||||
sa = (struct sockaddr*) (ROUNDUP(salen) + (char*) sa);
|
sa = (struct sockaddr*) (ROUNDUP(salen) + (char*) sa);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
|
bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
|
||||||
|
|||||||
@@ -39,20 +39,20 @@ get_rt_address(struct rt_msghdr* rtm, int desired) {
|
|||||||
sa = (struct sockaddr*) (ROUNDUP(sa->sa_len) + (char*) sa);
|
sa = (struct sockaddr*) (ROUNDUP(sa->sa_len) + (char*) sa);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
|
bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
|
||||||
int mib[6] = { CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_FLAGS, RTF_GATEWAY };
|
int mib[6] = { CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_FLAGS, RTF_GATEWAY };
|
||||||
size_t needed;
|
size_t needed;
|
||||||
|
|
||||||
if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0 || needed == 0) {
|
if (sysctl(mib, 6, nullptr, &needed, nullptr, 0) < 0 || needed == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_AUTO_FREE char* buf = malloc(needed);
|
FF_AUTO_FREE char* buf = malloc(needed);
|
||||||
|
|
||||||
if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
|
if (sysctl(mib, 6, buf, &needed, nullptr, 0) < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,13 +89,13 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result) {
|
|||||||
int mib[6] = { CTL_NET, PF_ROUTE, 0, AF_INET6, NET_RT_FLAGS, RTF_GATEWAY };
|
int mib[6] = { CTL_NET, PF_ROUTE, 0, AF_INET6, NET_RT_FLAGS, RTF_GATEWAY };
|
||||||
size_t needed;
|
size_t needed;
|
||||||
|
|
||||||
if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0 || needed == 0) {
|
if (sysctl(mib, 6, nullptr, &needed, nullptr, 0) < 0 || needed == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_AUTO_FREE char* buf = malloc(needed);
|
FF_AUTO_FREE char* buf = malloc(needed);
|
||||||
|
|
||||||
if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
|
if (sysctl(mib, 6, buf, &needed, nullptr, 0) < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
|
bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
|
||||||
FILE* FF_AUTO_CLOSE_FILE netRoute = fopen("/proc/route", "r");
|
FF_AUTO_CLOSE_FILE FILE* netRoute = fopen("/proc/route", "r");
|
||||||
|
|
||||||
if (!netRoute) {
|
if (!netRoute) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FF_AUTO_FREE void* buffer = malloc((size_t) size);
|
FF_AUTO_FREE void* buffer = malloc((size_t) size);
|
||||||
if (buffer == NULL) {
|
if (buffer == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,13 +54,13 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t addressSize = 0;
|
size_t addressSize = 0;
|
||||||
if (interface->ifr_route.destination != NULL) {
|
if (interface->ifr_route.destination != nullptr) {
|
||||||
addressSize += interface->ifr_route.destination->sa_len;
|
addressSize += interface->ifr_route.destination->sa_len;
|
||||||
}
|
}
|
||||||
if (interface->ifr_route.mask != NULL) {
|
if (interface->ifr_route.mask != nullptr) {
|
||||||
addressSize += interface->ifr_route.mask->sa_len;
|
addressSize += interface->ifr_route.mask->sa_len;
|
||||||
}
|
}
|
||||||
if (interface->ifr_route.gateway != NULL) {
|
if (interface->ifr_route.gateway != nullptr) {
|
||||||
addressSize += interface->ifr_route.gateway->sa_len;
|
addressSize += interface->ifr_route.gateway->sa_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FF_AUTO_FREE void* buffer = malloc((size_t) size);
|
FF_AUTO_FREE void* buffer = malloc((size_t) size);
|
||||||
if (buffer == NULL) {
|
if (buffer == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,13 +109,13 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t addressSize = 0;
|
size_t addressSize = 0;
|
||||||
if (interface->ifr_route.destination != NULL) {
|
if (interface->ifr_route.destination != nullptr) {
|
||||||
addressSize += interface->ifr_route.destination->sa_len;
|
addressSize += interface->ifr_route.destination->sa_len;
|
||||||
}
|
}
|
||||||
if (interface->ifr_route.mask != NULL) {
|
if (interface->ifr_route.mask != nullptr) {
|
||||||
addressSize += interface->ifr_route.mask->sa_len;
|
addressSize += interface->ifr_route.mask->sa_len;
|
||||||
}
|
}
|
||||||
if (interface->ifr_route.gateway != NULL) {
|
if (interface->ifr_route.gateway != nullptr) {
|
||||||
addressSize += interface->ifr_route.gateway->sa_len;
|
addressSize += interface->ifr_route.gateway->sa_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
|
|||||||
|
|
||||||
uint32_t pid = ffNetifGetNetlinkPortId(sock_fd);
|
uint32_t pid = ffNetifGetNetlinkPortId(sock_fd);
|
||||||
|
|
||||||
struct FF_A_PACKED {
|
struct [[gnu::packed]] {
|
||||||
struct nlmsghdr nlh;
|
struct nlmsghdr nlh;
|
||||||
struct rtmsg rtm;
|
struct rtmsg rtm;
|
||||||
struct rtattr rta;
|
struct rtattr rta;
|
||||||
@@ -97,7 +97,7 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
|
|||||||
|
|
||||||
uint8_t buffer[1024 * 16]; // 16 KB buffer should be sufficient
|
uint8_t buffer[1024 * 16]; // 16 KB buffer should be sufficient
|
||||||
uint32_t minMetric = UINT32_MAX;
|
uint32_t minMetric = UINT32_MAX;
|
||||||
FF_A_UNUSED int routeCount = 0;
|
[[maybe_unused]] int routeCount = 0;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
ssize_t received = recvfrom(sock_fd, buffer, sizeof(buffer), 0, (struct sockaddr*) &src_addr, &src_addr_len);
|
ssize_t received = recvfrom(sock_fd, buffer, sizeof(buffer), 0, (struct sockaddr*) &src_addr, &src_addr_len);
|
||||||
@@ -163,7 +163,7 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FF_DEBUG("Processing IPv4 default route candidate #%d", routeCount);
|
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
|
// Parse route attributes
|
||||||
size_t rtm_len = RTM_PAYLOAD(nlh);
|
size_t rtm_len = RTM_PAYLOAD(nlh);
|
||||||
@@ -254,7 +254,7 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result) {
|
|||||||
|
|
||||||
uint32_t pid = ffNetifGetNetlinkPortId(sock_fd);
|
uint32_t pid = ffNetifGetNetlinkPortId(sock_fd);
|
||||||
|
|
||||||
struct FF_A_PACKED {
|
struct [[gnu::packed]] {
|
||||||
struct nlmsghdr nlh;
|
struct nlmsghdr nlh;
|
||||||
struct rtmsg rtm;
|
struct rtmsg rtm;
|
||||||
struct rtattr rta;
|
struct rtattr rta;
|
||||||
@@ -307,7 +307,7 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result) {
|
|||||||
|
|
||||||
uint8_t buffer[1024 * 16]; // 16 KB buffer should be sufficient
|
uint8_t buffer[1024 * 16]; // 16 KB buffer should be sufficient
|
||||||
uint32_t minMetric = UINT32_MAX;
|
uint32_t minMetric = UINT32_MAX;
|
||||||
FF_A_UNUSED int routeCount = 0;
|
[[maybe_unused]] int routeCount = 0;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
ssize_t received = recvfrom(sock_fd, buffer, sizeof(buffer), 0, (struct sockaddr*) &src_addr, &src_addr_len);
|
ssize_t received = recvfrom(sock_fd, buffer, sizeof(buffer), 0, (struct sockaddr*) &src_addr, &src_addr_len);
|
||||||
@@ -372,7 +372,7 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FF_DEBUG("Processing IPv6 default route candidate #%d", routeCount);
|
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
|
// Parse route attributes
|
||||||
size_t rtm_len = RTM_PAYLOAD(nlh);
|
size_t rtm_len = RTM_PAYLOAD(nlh);
|
||||||
@@ -382,7 +382,7 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result) {
|
|||||||
switch (rta->rta_type) {
|
switch (rta->rta_type) {
|
||||||
case RTA_DST:
|
case RTA_DST:
|
||||||
if (RTA_PAYLOAD(rta) >= sizeof(struct in6_addr)) {
|
if (RTA_PAYLOAD(rta) >= sizeof(struct in6_addr)) {
|
||||||
FF_A_UNUSED char str[INET6_ADDRSTRLEN];
|
[[maybe_unused]] char str[INET6_ADDRSTRLEN];
|
||||||
FF_DEBUG("Unexpected RTA_DST: %s", inet_ntop(AF_INET6, RTA_DATA(rta), str, sizeof(str)));
|
FF_DEBUG("Unexpected RTA_DST: %s", inet_ntop(AF_INET6, RTA_DATA(rta), str, sizeof(str)));
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
@@ -399,7 +399,7 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result) {
|
|||||||
if (IN6_IS_ADDR_UNSPECIFIED(gw)) {
|
if (IN6_IS_ADDR_UNSPECIFIED(gw)) {
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
FF_A_UNUSED char str[INET6_ADDRSTRLEN];
|
[[maybe_unused]] char str[INET6_ADDRSTRLEN];
|
||||||
FF_DEBUG("Found gateway: %s", inet_ntop(AF_INET6, gw, str, sizeof(str)));
|
FF_DEBUG("Found gateway: %s", inet_ntop(AF_INET6, gw, str, sizeof(str)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
|
|
||||||
bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
|
bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
|
||||||
PMIB_IPFORWARD_TABLE2 pIpForwardTable = NULL;
|
PMIB_IPFORWARD_TABLE2 pIpForwardTable = nullptr;
|
||||||
|
|
||||||
if (!NETIO_SUCCESS(GetIpForwardTable2(AF_INET, &pIpForwardTable))) {
|
if (!NETIO_SUCCESS(GetIpForwardTable2(AF_INET, &pIpForwardTable))) {
|
||||||
return false;
|
return false;
|
||||||
@@ -48,7 +48,7 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result) {
|
bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result) {
|
||||||
PMIB_IPFORWARD_TABLE2 pIpForwardTable = NULL;
|
PMIB_IPFORWARD_TABLE2 pIpForwardTable = nullptr;
|
||||||
|
|
||||||
if (!NETIO_SUCCESS(GetIpForwardTable2(AF_INET6, &pIpForwardTable))) {
|
if (!NETIO_SUCCESS(GetIpForwardTable2(AF_INET6, &pIpForwardTable))) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ const char* ffNetworkingLoadZlibLibrary(void) {
|
|||||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(zlib, zlibData, inflateInit2_)
|
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, inflate)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(zlib, zlibData, inflateEnd)
|
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(zlib, zlibData, inflateEnd)
|
||||||
zlib = NULL; // don't auto dlclose
|
zlib = nullptr; // don't auto dlclose
|
||||||
}
|
}
|
||||||
return zlibData.ffinflateEnd == NULL ? "Failed to load libz" : NULL;
|
return zlibData.ffinflateEnd == nullptr ? "Failed to load libz" : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to pre-read gzip header to determine uncompressed size
|
// Try to pre-read gzip header to determine uncompressed size
|
||||||
@@ -64,14 +64,14 @@ static uint32_t guessGzipOutputSize(const void* data, uint32_t dataSize) {
|
|||||||
|
|
||||||
// Decompress gzip content
|
// Decompress gzip content
|
||||||
bool ffNetworkingDecompressGzip(FFstrbuf* buffer, char* headerEnd) {
|
bool ffNetworkingDecompressGzip(FFstrbuf* buffer, char* headerEnd) {
|
||||||
assert(headerEnd != NULL && *headerEnd == '\r');
|
assert(headerEnd != nullptr && *headerEnd == '\r');
|
||||||
|
|
||||||
// Calculate header size
|
// Calculate header size
|
||||||
uint32_t headerSize = (uint32_t) (headerEnd - buffer->chars);
|
uint32_t headerSize = (uint32_t) (headerEnd - buffer->chars);
|
||||||
|
|
||||||
*headerEnd = '\0'; // Replace delimiter with null character for easier processing
|
*headerEnd = '\0'; // Replace delimiter with null character for easier processing
|
||||||
// Ensure Content-Encoding is in response headers, not in response body
|
// Ensure Content-Encoding is in response headers, not in response body
|
||||||
bool hasGzip = strcasestr(buffer->chars, "\nContent-Encoding: gzip") != NULL;
|
bool hasGzip = strcasestr(buffer->chars, "\nContent-Encoding: gzip") != nullptr;
|
||||||
*headerEnd = '\r'; // Restore delimiter
|
*headerEnd = '\r'; // Restore delimiter
|
||||||
|
|
||||||
if (!hasGzip) {
|
if (!hasGzip) {
|
||||||
@@ -165,7 +165,7 @@ bool ffNetworkingDecompressGzip(FFstrbuf* buffer, char* headerEnd) {
|
|||||||
// Use decompressedBuffer.length (total) not decompressedSize (last chunk only)
|
// Use decompressedBuffer.length (total) not decompressedSize (last chunk only)
|
||||||
FF_STRBUF_AUTO_DESTROY newBuffer = ffStrbufCreateA(headerSize + decompressedBuffer.length + 64);
|
FF_STRBUF_AUTO_DESTROY newBuffer = ffStrbufCreateA(headerSize + decompressedBuffer.length + 64);
|
||||||
|
|
||||||
char* line = NULL;
|
char* line = nullptr;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
while (ffStrbufGetline(&line, &len, buffer)) {
|
while (ffStrbufGetline(&line, &len, buffer)) {
|
||||||
if (ffStrStartsWithIgnCase(line, "Content-Encoding:")) {
|
if (ffStrStartsWithIgnCase(line, "Content-Encoding:")) {
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ static const char* tryNonThreadingFastPath(FFNetworkingState* state) {
|
|||||||
},
|
},
|
||||||
1,
|
1,
|
||||||
&sent,
|
&sent,
|
||||||
NULL) != 0) {
|
nullptr) != 0) {
|
||||||
sent = 0;
|
sent = 0;
|
||||||
}
|
}
|
||||||
if (fcntl(state->sockfd, F_SETFL, 0) == -1) {
|
if (fcntl(state->sockfd, F_SETFL, 0) == -1) {
|
||||||
@@ -123,9 +123,9 @@ static const char* tryNonThreadingFastPath(FFNetworkingState* state) {
|
|||||||
sent,
|
sent,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
freeaddrinfo(state->addr);
|
freeaddrinfo(state->addr);
|
||||||
state->addr = NULL;
|
state->addr = nullptr;
|
||||||
ffStrbufDestroy(&state->command);
|
ffStrbufDestroy(&state->command);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_DEBUG(
|
FF_DEBUG(
|
||||||
@@ -149,7 +149,7 @@ static const char* tryNonThreadingFastPath(FFNetworkingState* state) {
|
|||||||
|
|
||||||
// Traditional connect and send function
|
// Traditional connect and send function
|
||||||
static const char* connectAndSend(FFNetworkingState* state) {
|
static const char* connectAndSend(FFNetworkingState* state) {
|
||||||
const char* ret = NULL;
|
const char* ret = nullptr;
|
||||||
FF_DEBUG("Using traditional connection method to connect");
|
FF_DEBUG("Using traditional connection method to connect");
|
||||||
|
|
||||||
FF_DEBUG("Attempting connect() to server...");
|
FF_DEBUG("Attempting connect() to server...");
|
||||||
@@ -178,7 +178,7 @@ error:
|
|||||||
exit:
|
exit:
|
||||||
FF_DEBUG("Releasing address info and other resources");
|
FF_DEBUG("Releasing address info and other resources");
|
||||||
freeaddrinfo(state->addr);
|
freeaddrinfo(state->addr);
|
||||||
state->addr = NULL;
|
state->addr = nullptr;
|
||||||
ffStrbufDestroy(&state->command);
|
ffStrbufDestroy(&state->command);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -212,7 +212,7 @@ static const char* initNetworkingState(FFNetworkingState* state, const char* hos
|
|||||||
FF_DEBUG("Thread ID initialized to 0");
|
FF_DEBUG("Thread ID initialized to 0");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char* ret = NULL;
|
const char* ret = nullptr;
|
||||||
|
|
||||||
struct addrinfo hints = {
|
struct addrinfo hints = {
|
||||||
.ai_family = state->ipv6 ? AF_INET6 : AF_INET,
|
.ai_family = state->ipv6 ? AF_INET6 : AF_INET,
|
||||||
@@ -261,7 +261,7 @@ static const char* initNetworkingState(FFNetworkingState* state, const char* hos
|
|||||||
|
|
||||||
if (state->timeout > 0) {
|
if (state->timeout > 0) {
|
||||||
FF_DEBUG("Setting connection timeout: %u ms", state->timeout);
|
FF_DEBUG("Setting connection timeout: %u ms", state->timeout);
|
||||||
FF_A_UNUSED uint32_t sec = state->timeout / 1000;
|
[[maybe_unused]] uint32_t sec = state->timeout / 1000;
|
||||||
if (sec == 0) {
|
if (sec == 0) {
|
||||||
sec = 1;
|
sec = 1;
|
||||||
}
|
}
|
||||||
@@ -280,14 +280,14 @@ static const char* initNetworkingState(FFNetworkingState* state, const char* hos
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
FF_DEBUG("Error occurred during initialization");
|
FF_DEBUG("Error occurred during initialization");
|
||||||
if (state->addr != NULL) {
|
if (state->addr != nullptr) {
|
||||||
FF_DEBUG("Releasing address information");
|
FF_DEBUG("Releasing address information");
|
||||||
freeaddrinfo(state->addr);
|
freeaddrinfo(state->addr);
|
||||||
state->addr = NULL;
|
state->addr = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->sockfd > 0) {
|
if (state->sockfd > 0) {
|
||||||
@@ -307,7 +307,7 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
|
|||||||
#ifdef FF_HAVE_ZLIB
|
#ifdef FF_HAVE_ZLIB
|
||||||
const char* zlibError = ffNetworkingLoadZlibLibrary();
|
const char* zlibError = ffNetworkingLoadZlibLibrary();
|
||||||
// Only enable compression if zlib library is successfully loaded
|
// Only enable compression if zlib library is successfully loaded
|
||||||
if (zlibError == NULL) {
|
if (zlibError == nullptr) {
|
||||||
FF_DEBUG("Successfully loaded zlib library, compression enabled");
|
FF_DEBUG("Successfully loaded zlib library, compression enabled");
|
||||||
} else {
|
} else {
|
||||||
FF_DEBUG("Failed to load zlib library, compression disabled: %s", zlibError);
|
FF_DEBUG("Failed to load zlib library, compression disabled: %s", zlibError);
|
||||||
@@ -322,16 +322,16 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char* initResult = initNetworkingState(state, host, path, headers);
|
const char* initResult = initNetworkingState(state, host, path, headers);
|
||||||
if (initResult != NULL) {
|
if (initResult != nullptr) {
|
||||||
FF_DEBUG("Initialization failed: %s", initResult);
|
FF_DEBUG("Initialization failed: %s", initResult);
|
||||||
return initResult;
|
return initResult;
|
||||||
}
|
}
|
||||||
FF_DEBUG("Network state initialization successful");
|
FF_DEBUG("Network state initialization successful");
|
||||||
|
|
||||||
const char* tfoResult = tryNonThreadingFastPath(state);
|
const char* tfoResult = tryNonThreadingFastPath(state);
|
||||||
if (tfoResult == NULL) {
|
if (tfoResult == nullptr) {
|
||||||
FF_DEBUG("TryNonThreadingFastPath() succeeded or in progress");
|
FF_DEBUG("TryNonThreadingFastPath() succeeded or in progress");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
FF_DEBUG("TryNonThreadingFastPath() failed: %s, trying traditional connection", tfoResult);
|
FF_DEBUG("TryNonThreadingFastPath() failed: %s, trying traditional connection", tfoResult);
|
||||||
|
|
||||||
@@ -341,7 +341,7 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
|
|||||||
state->thread = ffThreadCreate(connectAndSendThreadMain, state);
|
state->thread = ffThreadCreate(connectAndSendThreadMain, state);
|
||||||
if (state->thread) {
|
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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
FF_DEBUG("Thread creation failed");
|
FF_DEBUG("Thread creation failed");
|
||||||
} else {
|
} else {
|
||||||
@@ -406,7 +406,7 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
FF_DEBUG("Setting receive timeout: %u ms", timeout);
|
FF_DEBUG("Setting receive timeout: %u ms", timeout);
|
||||||
struct timeval timev;
|
struct timeval timev;
|
||||||
timev.tv_sec = timeout / 1000;
|
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));
|
setsockopt(state->sockfd, SOL_SOCKET, SO_RCVTIMEO, &timev, sizeof(timev));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -417,7 +417,7 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
}
|
}
|
||||||
|
|
||||||
FF_DEBUG("Starting data reception");
|
FF_DEBUG("Starting data reception");
|
||||||
FF_A_UNUSED int recvCount = 0;
|
[[maybe_unused]] int recvCount = 0;
|
||||||
uint32_t contentLength = 0;
|
uint32_t contentLength = 0;
|
||||||
uint32_t headerEnd = 0;
|
uint32_t headerEnd = 0;
|
||||||
|
|
||||||
@@ -455,8 +455,15 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
// Check for Content-Length header to pre-allocate enough memory
|
// Check for Content-Length header to pre-allocate enough memory
|
||||||
const char* clHeader = strcasestr(buffer->chars, "Content-Length:");
|
const char* clHeader = strcasestr(buffer->chars, "Content-Length:");
|
||||||
if (clHeader) {
|
if (clHeader) {
|
||||||
contentLength = (uint32_t) strtoul(clHeader + 15, NULL, 10);
|
contentLength = (uint32_t) strtoul(clHeader + 15, nullptr, 10);
|
||||||
if (contentLength > 0) {
|
if (contentLength > 0) {
|
||||||
|
if (contentLength > 1024 * 1024) { // 1MB limit to prevent excessive memory allocation and potential attacks
|
||||||
|
FF_DEBUG("Content-Length is too large: %u bytes, aborting", contentLength);
|
||||||
|
close(state->sockfd);
|
||||||
|
state->sockfd = -1;
|
||||||
|
return "Content-Length too large";
|
||||||
|
}
|
||||||
|
|
||||||
FF_DEBUG("Detected Content-Length: %u, pre-allocating buffer", contentLength);
|
FF_DEBUG("Detected Content-Length: %u, pre-allocating buffer", contentLength);
|
||||||
// Ensure buffer is large enough, adding header size and some margin
|
// Ensure buffer is large enough, adding header size and some margin
|
||||||
ffStrbufEnsureFree(buffer, contentLength + 16);
|
ffStrbufEnsureFree(buffer, contentLength + 16);
|
||||||
@@ -481,7 +488,7 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
return "No HTTP header end found";
|
return "No HTTP header end found";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ffStrbufStartsWithS(buffer, "HTTP/1.0 200 OK\r\n")) {
|
if (!ffStrbufStartsWithS(buffer, "HTTP/1.0 200 OK\r\n") && !ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n")) {
|
||||||
FF_DEBUG("Invalid response: %.40s...", buffer->chars);
|
FF_DEBUG("Invalid response: %.40s...", buffer->chars);
|
||||||
return "Invalid response";
|
return "Invalid response";
|
||||||
}
|
}
|
||||||
@@ -505,5 +512,5 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ static const char* initWsaData(WSADATA* wsaData) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dummy socket needed for WSAIoctl
|
// Dummy socket needed for WSAIoctl
|
||||||
SOCKET sockfd = WSASocketW(AF_INET, SOCK_STREAM, 0, NULL, 0, 0);
|
SOCKET sockfd = WSASocketW(AF_INET, SOCK_STREAM, 0, nullptr, 0, 0);
|
||||||
if (sockfd == INVALID_SOCKET) {
|
if (sockfd == INVALID_SOCKET) {
|
||||||
FF_DEBUG("WSASocketW(AF_INET, SOCK_STREAM) failed");
|
FF_DEBUG("WSASocketW(AF_INET, SOCK_STREAM) failed");
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
@@ -32,7 +32,7 @@ static const char* initWsaData(WSADATA* wsaData) {
|
|||||||
|
|
||||||
DWORD dwBytes;
|
DWORD dwBytes;
|
||||||
GUID guid = WSAID_CONNECTEX;
|
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, nullptr, nullptr) != 0) {
|
||||||
FF_DEBUG("WSAIoctl(sockfd, SIO_GET_EXTENSION_FUNCTION_POINTER) failed");
|
FF_DEBUG("WSAIoctl(sockfd, SIO_GET_EXTENSION_FUNCTION_POINTER) failed");
|
||||||
closesocket(sockfd);
|
closesocket(sockfd);
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
@@ -42,7 +42,7 @@ static const char* initWsaData(WSADATA* wsaData) {
|
|||||||
closesocket(sockfd);
|
closesocket(sockfd);
|
||||||
FF_DEBUG("WinSock initialized successfully");
|
FF_DEBUG("WinSock initialized successfully");
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
@@ -52,7 +52,7 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
|
|||||||
#ifdef FF_HAVE_ZLIB
|
#ifdef FF_HAVE_ZLIB
|
||||||
const char* zlibError = ffNetworkingLoadZlibLibrary();
|
const char* zlibError = ffNetworkingLoadZlibLibrary();
|
||||||
// Only enable compression if zlib library is successfully loaded
|
// Only enable compression if zlib library is successfully loaded
|
||||||
if (zlibError == NULL) {
|
if (zlibError == nullptr) {
|
||||||
FF_DEBUG("Successfully loaded zlib library, compression enabled");
|
FF_DEBUG("Successfully loaded zlib library, compression enabled");
|
||||||
} else {
|
} else {
|
||||||
FF_DEBUG("Failed to load zlib library, compression disabled: %s", zlibError);
|
FF_DEBUG("Failed to load zlib library, compression disabled: %s", zlibError);
|
||||||
@@ -69,7 +69,7 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
|
|||||||
static WSADATA wsaData;
|
static WSADATA wsaData;
|
||||||
if (wsaData.wVersion == 0) {
|
if (wsaData.wVersion == 0) {
|
||||||
const char* error = initWsaData(&wsaData);
|
const char* error = initWsaData(&wsaData);
|
||||||
if (error != NULL) {
|
if (error != nullptr) {
|
||||||
wsaData.wVersion = (WORD) -1;
|
wsaData.wVersion = (WORD) -1;
|
||||||
FF_DEBUG("WinSock initialization failed: %s", error);
|
FF_DEBUG("WinSock initialization failed: %s", error);
|
||||||
return error;
|
return error;
|
||||||
@@ -87,7 +87,7 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
|
|||||||
};
|
};
|
||||||
|
|
||||||
wchar_t hostW[256];
|
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), nullptr, host, (ULONG) strlen(host) + 1))) {
|
||||||
FF_DEBUG("Failed to convert host to wide string: %s", host);
|
FF_DEBUG("Failed to convert host to wide string: %s", host);
|
||||||
return "Failed to convert host to wide string";
|
return "Failed to convert host to wide string";
|
||||||
}
|
}
|
||||||
@@ -98,7 +98,7 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
|
|||||||
return "GetAddrInfoW() failed";
|
return "GetAddrInfoW() failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
state->sockfd = WSASocketW(addr->ai_family, addr->ai_socktype, addr->ai_protocol, NULL, 0, 0);
|
state->sockfd = WSASocketW(addr->ai_family, addr->ai_socktype, addr->ai_protocol, nullptr, 0, 0);
|
||||||
if (state->sockfd == INVALID_SOCKET) {
|
if (state->sockfd == INVALID_SOCKET) {
|
||||||
FF_DEBUG("WSASocketW() failed");
|
FF_DEBUG("WSASocketW() failed");
|
||||||
FreeAddrInfoW(addr);
|
FreeAddrInfoW(addr);
|
||||||
@@ -141,16 +141,14 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize overlapped structure with WSA event for asynchronous I/O
|
// Initialize overlapped structure with WSA event for asynchronous I/O
|
||||||
state->overlapped = (OVERLAPPED) {
|
state->overlapped = (OVERLAPPED) {};
|
||||||
.hEvent = WSACreateEvent()
|
|
||||||
};
|
|
||||||
|
|
||||||
if (state->overlapped.hEvent == WSA_INVALID_EVENT) {
|
if (!NT_SUCCESS(NtCreateEvent(&state->overlapped.hEvent, EVENT_ALL_ACCESS, nullptr, NotificationEvent, FALSE))) {
|
||||||
FF_DEBUG("WSACreateEvent() failed");
|
FF_DEBUG("NtCreateEvent() failed");
|
||||||
closesocket(state->sockfd);
|
closesocket(state->sockfd);
|
||||||
FreeAddrInfoW(addr);
|
FreeAddrInfoW(addr);
|
||||||
state->sockfd = INVALID_SOCKET;
|
state->sockfd = INVALID_SOCKET;
|
||||||
return "WSACreateEvent() failed";
|
return "NtCreateEvent() failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build HTTP command
|
// Build HTTP command
|
||||||
@@ -189,12 +187,12 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
|
|||||||
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);
|
FreeAddrInfoW(addr);
|
||||||
addr = NULL;
|
addr = nullptr;
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
if (WSAGetLastError() != WSA_IO_PENDING) {
|
if (WSAGetLastError() != WSA_IO_PENDING) {
|
||||||
FF_DEBUG("ConnectEx() failed: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
|
FF_DEBUG("ConnectEx() failed: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
|
||||||
WSACloseEvent(state->overlapped.hEvent);
|
NtClose(state->overlapped.hEvent);
|
||||||
closesocket(state->sockfd);
|
closesocket(state->sockfd);
|
||||||
state->sockfd = INVALID_SOCKET;
|
state->sockfd = INVALID_SOCKET;
|
||||||
ffStrbufDestroy(&state->command);
|
ffStrbufDestroy(&state->command);
|
||||||
@@ -207,7 +205,7 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
|
|||||||
}
|
}
|
||||||
|
|
||||||
// No need to cleanup state fields here since we need them in the receive function
|
// No need to cleanup state fields here since we need them in the receive function
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer) {
|
const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer) {
|
||||||
@@ -219,40 +217,30 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
return "ffNetworkingSendHttpRequest() failed";
|
return "ffNetworkingSendHttpRequest() failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD transfer;
|
||||||
uint32_t timeout = state->timeout;
|
uint32_t timeout = state->timeout;
|
||||||
if (timeout > 0) {
|
if (!GetOverlappedResultEx((HANDLE) state->sockfd, &state->overlapped, &transfer, timeout > 0 ? timeout : INFINITE, FALSE)) {
|
||||||
FF_DEBUG("WSAWaitForMultipleEvents with timeout: %u ms", timeout);
|
DWORD error = GetLastError();
|
||||||
DWORD result = WSAWaitForMultipleEvents(1, &state->overlapped.hEvent, TRUE, timeout, FALSE);
|
if (error == WAIT_TIMEOUT) {
|
||||||
if (result != WSA_WAIT_EVENT_0) {
|
FF_DEBUG("GetOverlappedResultEx timed out");
|
||||||
if (result == WSA_WAIT_TIMEOUT) {
|
} else {
|
||||||
FF_DEBUG("WSAWaitForMultipleEvents timed out");
|
FF_DEBUG("GetOverlappedResultEx failed: %s", ffDebugWin32Error(error));
|
||||||
} else {
|
|
||||||
FF_DEBUG("WSAWaitForMultipleEvents failed: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
return "WSAWaitForMultipleEvents() failed or timeout";
|
|
||||||
}
|
}
|
||||||
}
|
IO_STATUS_BLOCK cancelIosb = {};
|
||||||
|
if (NT_SUCCESS(NtCancelIoFileEx((HANDLE) state->sockfd, (PIO_STATUS_BLOCK) &state->overlapped, &cancelIosb))) {
|
||||||
DWORD transfer, flags;
|
NtWaitForSingleObject(state->overlapped.hEvent, TRUE, &(LARGE_INTEGER) { .QuadPart = (int64_t) 10 * -10000 });
|
||||||
if (!WSAGetOverlappedResult(state->sockfd, &state->overlapped, &transfer, TRUE, &flags)) {
|
}
|
||||||
FF_DEBUG("WSAGetOverlappedResult failed: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
|
NtClose(state->overlapped.hEvent);
|
||||||
closesocket(state->sockfd);
|
closesocket(state->sockfd);
|
||||||
WSACloseEvent(state->overlapped.hEvent);
|
|
||||||
ffStrbufDestroy(&state->command);
|
ffStrbufDestroy(&state->command);
|
||||||
return "WSAGetOverlappedResult() failed";
|
return "GetOverlappedResultEx() failed or timeout";
|
||||||
}
|
}
|
||||||
FF_DEBUG("WSAGetOverlappedResult succeeded, %u bytes sent", (unsigned) transfer);
|
FF_DEBUG("GetOverlappedResultEx succeeded, %u bytes sent", (unsigned) transfer);
|
||||||
ffStrbufDestroy(&state->command);
|
ffStrbufDestroy(&state->command);
|
||||||
WSACloseEvent(state->overlapped.hEvent);
|
NtClose(state->overlapped.hEvent);
|
||||||
state->overlapped.hEvent = NULL;
|
state->overlapped.hEvent = nullptr;
|
||||||
|
|
||||||
if (setsockopt(state->sockfd, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0) != 0) {
|
if (setsockopt(state->sockfd, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, nullptr, 0) != 0) {
|
||||||
FF_DEBUG("Failed to update connect context: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
|
FF_DEBUG("Failed to update connect context: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
|
||||||
// Not a critical error, continue anyway
|
// Not a critical error, continue anyway
|
||||||
}
|
}
|
||||||
@@ -275,7 +263,7 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
}
|
}
|
||||||
|
|
||||||
FF_DEBUG("Starting data reception");
|
FF_DEBUG("Starting data reception");
|
||||||
FF_A_UNUSED int recvCount = 0;
|
[[maybe_unused]] int recvCount = 0;
|
||||||
uint32_t contentLength = 0;
|
uint32_t contentLength = 0;
|
||||||
uint32_t headerEnd = 0;
|
uint32_t headerEnd = 0;
|
||||||
|
|
||||||
@@ -293,8 +281,8 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
1,
|
1,
|
||||||
&received,
|
&received,
|
||||||
&recvFlags,
|
&recvFlags,
|
||||||
NULL,
|
nullptr,
|
||||||
NULL);
|
nullptr);
|
||||||
|
|
||||||
if (recvResult == SOCKET_ERROR || received == 0) {
|
if (recvResult == SOCKET_ERROR || received == 0) {
|
||||||
if (recvResult == 0 && received == 0) {
|
if (recvResult == 0 && received == 0) {
|
||||||
@@ -320,8 +308,15 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
// Check for Content-Length header to pre-allocate enough memory
|
// Check for Content-Length header to pre-allocate enough memory
|
||||||
const char* clHeader = strcasestr(buffer->chars, "Content-Length:");
|
const char* clHeader = strcasestr(buffer->chars, "Content-Length:");
|
||||||
if (clHeader) {
|
if (clHeader) {
|
||||||
contentLength = (uint32_t) strtoul(clHeader + 15, NULL, 10);
|
contentLength = (uint32_t) strtoul(clHeader + 15, nullptr, 10);
|
||||||
if (contentLength > 0) {
|
if (contentLength > 0) {
|
||||||
|
if (contentLength > 1024 * 1024) { // 1MB limit to prevent excessive memory allocation and potential attacks
|
||||||
|
FF_DEBUG("Content-Length is too large: %u bytes, aborting", contentLength);
|
||||||
|
closesocket(state->sockfd);
|
||||||
|
state->sockfd = INVALID_SOCKET;
|
||||||
|
return "Content-Length too large";
|
||||||
|
}
|
||||||
|
|
||||||
FF_DEBUG("Detected Content-Length: %u, pre-allocating buffer", contentLength);
|
FF_DEBUG("Detected Content-Length: %u, pre-allocating buffer", contentLength);
|
||||||
// Ensure buffer is large enough, adding header size and some margin
|
// Ensure buffer is large enough, adding header size and some margin
|
||||||
ffStrbufEnsureFree(buffer, contentLength + 16);
|
ffStrbufEnsureFree(buffer, contentLength + 16);
|
||||||
@@ -346,7 +341,7 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
return "No HTTP header end found";
|
return "No HTTP header end found";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ffStrbufStartsWithS(buffer, "HTTP/1.0 200 OK\r\n")) {
|
if (!ffStrbufStartsWithS(buffer, "HTTP/1.0 200 OK\r\n") && !ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n")) {
|
||||||
FF_DEBUG("Invalid response: %.40s...", buffer->chars);
|
FF_DEBUG("Invalid response: %.40s...", buffer->chars);
|
||||||
return "Invalid response";
|
return "Invalid response";
|
||||||
}
|
}
|
||||||
@@ -372,5 +367,5 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-10
@@ -5,19 +5,19 @@
|
|||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
// Return start position of the inner key if the argument key belongs to the module specified, NULL otherwise
|
// Return start position of the inner key if the argument key belongs to the module specified, nullptr otherwise
|
||||||
const char* ffOptionTestPrefix(const char* argumentKey, const char* moduleName) {
|
const char* ffOptionTestPrefix(const char* argumentKey, const char* moduleName) {
|
||||||
assert(argumentKey && moduleName);
|
assert(argumentKey && moduleName);
|
||||||
|
|
||||||
const char* subKey = argumentKey;
|
const char* subKey = argumentKey;
|
||||||
if (!(subKey[0] == '-' && subKey[1] == '-')) {
|
if (!(subKey[0] == '-' && subKey[1] == '-')) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
subKey += 2;
|
subKey += 2;
|
||||||
uint32_t moduleNameLen = (uint32_t) strlen(moduleName);
|
uint32_t moduleNameLen = (uint32_t) strlen(moduleName);
|
||||||
if (strncasecmp(subKey, moduleName, moduleNameLen) != 0) {
|
if (strncasecmp(subKey, moduleName, moduleNameLen) != 0) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
subKey += moduleNameLen;
|
subKey += moduleNameLen;
|
||||||
@@ -27,7 +27,7 @@ const char* ffOptionTestPrefix(const char* argumentKey, const char* moduleName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (subKey[0] != '-') {
|
if (subKey[0] != '-') {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
subKey += 1;
|
subKey += 1;
|
||||||
@@ -36,7 +36,7 @@ const char* ffOptionTestPrefix(const char* argumentKey, const char* moduleName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ffOptionParseString(const char* argumentKey, const char* value, FFstrbuf* buffer) {
|
void ffOptionParseString(const char* argumentKey, const char* value, FFstrbuf* buffer) {
|
||||||
if (value == NULL) {
|
if (value == nullptr) {
|
||||||
fprintf(stderr, "Error: usage: %s <str>\n", argumentKey);
|
fprintf(stderr, "Error: usage: %s <str>\n", argumentKey);
|
||||||
exit(477);
|
exit(477);
|
||||||
}
|
}
|
||||||
@@ -45,7 +45,7 @@ void ffOptionParseString(const char* argumentKey, const char* value, FFstrbuf* b
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ffOptionParseUInt32(const char* argumentKey, const char* value) {
|
uint32_t ffOptionParseUInt32(const char* argumentKey, const char* value) {
|
||||||
if (value == NULL) {
|
if (value == nullptr) {
|
||||||
fprintf(stderr, "Error: usage: %s <num>\n", argumentKey);
|
fprintf(stderr, "Error: usage: %s <num>\n", argumentKey);
|
||||||
exit(480);
|
exit(480);
|
||||||
}
|
}
|
||||||
@@ -61,7 +61,7 @@ uint32_t ffOptionParseUInt32(const char* argumentKey, const char* value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t ffOptionParseInt32(const char* argumentKey, const char* value) {
|
int32_t ffOptionParseInt32(const char* argumentKey, const char* value) {
|
||||||
if (value == NULL) {
|
if (value == nullptr) {
|
||||||
fprintf(stderr, "Error: usage: %s <num>\n", argumentKey);
|
fprintf(stderr, "Error: usage: %s <num>\n", argumentKey);
|
||||||
exit(480);
|
exit(480);
|
||||||
}
|
}
|
||||||
@@ -77,7 +77,7 @@ int32_t ffOptionParseInt32(const char* argumentKey, const char* value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int ffOptionParseEnum(const char* argumentKey, const char* requestedKey, FFKeyValuePair pairs[]) {
|
int ffOptionParseEnum(const char* argumentKey, const char* requestedKey, FFKeyValuePair pairs[]) {
|
||||||
if (requestedKey == NULL) {
|
if (requestedKey == nullptr) {
|
||||||
fprintf(stderr, "Error: usage: %s <value>\n", argumentKey);
|
fprintf(stderr, "Error: usage: %s <value>\n", argumentKey);
|
||||||
exit(476);
|
exit(476);
|
||||||
}
|
}
|
||||||
@@ -139,7 +139,7 @@ void ffOptionParseColorNoClear(const char* value, FFstrbuf* buffer) {
|
|||||||
} else if (value[0] == '@') {
|
} else if (value[0] == '@') {
|
||||||
// Xterm 256 color
|
// Xterm 256 color
|
||||||
++value;
|
++value;
|
||||||
char* pend = NULL;
|
char* pend = nullptr;
|
||||||
uint32_t color = (uint32_t) strtoul(value, &pend, 10);
|
uint32_t color = (uint32_t) strtoul(value, &pend, 10);
|
||||||
if (pend == value || color > 255) {
|
if (pend == value || color > 255) {
|
||||||
fprintf(stderr, "Error: invalid 256 color code found: %s\n", value);
|
fprintf(stderr, "Error: invalid 256 color code found: %s\n", value);
|
||||||
@@ -153,7 +153,7 @@ void ffOptionParseColorNoClear(const char* value, FFstrbuf* buffer) {
|
|||||||
} else if (value[0] == '#') {
|
} else if (value[0] == '#') {
|
||||||
// RGB color
|
// RGB color
|
||||||
++value;
|
++value;
|
||||||
char* pend = NULL;
|
char* pend = nullptr;
|
||||||
uint32_t rgb = (uint32_t) strtoul(value, &pend, 16);
|
uint32_t rgb = (uint32_t) strtoul(value, &pend, 16);
|
||||||
if (pend == value) {
|
if (pend == value) {
|
||||||
fprintf(stderr, "Error: invalid RGB color code found: %s\n", value);
|
fprintf(stderr, "Error: invalid RGB color code found: %s\n", value);
|
||||||
|
|||||||
+18
-18
@@ -47,7 +47,7 @@ const char* ffFindExecutableInPath(const char* name, FFstrbuf* result) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
ffStrbufClear(result);
|
ffStrbufClear(result);
|
||||||
return "Executable not found";
|
return "Executable not found";
|
||||||
@@ -60,13 +60,13 @@ const char* ffFindExecutableInPath(const char* name, FFstrbuf* result) {
|
|||||||
|
|
||||||
const char* ffFindExecutableInPath(const char* name, FFstrbuf* result) {
|
const char* ffFindExecutableInPath(const char* name, FFstrbuf* result) {
|
||||||
char buffer[MAX_PATH + 1];
|
char buffer[MAX_PATH + 1];
|
||||||
DWORD length = SearchPathA(NULL, name, ".exe", sizeof(buffer), buffer, NULL);
|
DWORD length = SearchPathA(nullptr, name, ".exe", sizeof(buffer), buffer, nullptr);
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
ffStrbufClear(result);
|
ffStrbufClear(result);
|
||||||
return "Executable not found";
|
return "Executable not found";
|
||||||
}
|
}
|
||||||
ffStrbufSetS(result, buffer);
|
ffStrbufSetS(result, buffer);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int winerr2Errno(DWORD err) {
|
static inline int winerr2Errno(DWORD err) {
|
||||||
@@ -93,7 +93,7 @@ static inline int winerr2Errno(DWORD err) {
|
|||||||
char* frealpath(HANDLE hFile, char* resolved_name) {
|
char* frealpath(HANDLE hFile, char* resolved_name) {
|
||||||
if (__builtin_expect(hFile == INVALID_HANDLE_VALUE || !hFile, false)) {
|
if (__builtin_expect(hFile == INVALID_HANDLE_VALUE || !hFile, false)) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
wchar_t resolvedNameW[MAX_PATH + 4]; /* +4 for "\\\\?\\" prefix */
|
wchar_t resolvedNameW[MAX_PATH + 4]; /* +4 for "\\\\?\\" prefix */
|
||||||
@@ -101,11 +101,11 @@ char* frealpath(HANDLE hFile, char* resolved_name) {
|
|||||||
|
|
||||||
if (lenW == 0) {
|
if (lenW == 0) {
|
||||||
errno = winerr2Errno(GetLastError());
|
errno = winerr2Errno(GetLastError());
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (lenW >= ARRAY_SIZE(resolvedNameW)) {
|
if (lenW >= ARRAY_SIZE(resolvedNameW)) {
|
||||||
errno = E2BIG;
|
errno = E2BIG;
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
lenW++; // Include null terminator
|
lenW++; // Include null terminator
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ char* frealpath(HANDLE hFile, char* resolved_name) {
|
|||||||
ULONG outBytes = 0;
|
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;
|
errno = E2BIG;
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* UTF-8 worst-case: up to 4 bytes per UTF-16 code unit */
|
/* UTF-8 worst-case: up to 4 bytes per UTF-16 code unit */
|
||||||
@@ -135,13 +135,13 @@ char* frealpath(HANDLE hFile, char* resolved_name) {
|
|||||||
|
|
||||||
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;
|
errno = E2BIG;
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
resolved_name = (char*) malloc(outBytes);
|
resolved_name = (char*) malloc(outBytes);
|
||||||
if (!resolved_name) {
|
if (!resolved_name) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(resolved_name, tmp, outBytes);
|
memcpy(resolved_name, tmp, outBytes);
|
||||||
@@ -153,7 +153,7 @@ char* frealpath(HANDLE hFile, char* resolved_name) {
|
|||||||
char* realpath(const char* __restrict file_name, char* __restrict resolved_name) {
|
char* realpath(const char* __restrict file_name, char* __restrict resolved_name) {
|
||||||
if (!file_name) {
|
if (!file_name) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
wchar_t fileNameW[MAX_PATH];
|
wchar_t fileNameW[MAX_PATH];
|
||||||
@@ -161,21 +161,21 @@ char* realpath(const char* __restrict file_name, char* __restrict resolved_name)
|
|||||||
|
|
||||||
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;
|
errno = EINVAL;
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_AUTO_CLOSE_FD HANDLE hFile = CreateFileW(
|
FF_AUTO_CLOSE_FD HANDLE hFile = CreateFileW(
|
||||||
fileNameW,
|
fileNameW,
|
||||||
0,
|
0,
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
NULL,
|
nullptr,
|
||||||
OPEN_EXISTING,
|
OPEN_EXISTING,
|
||||||
FILE_FLAG_BACKUP_SEMANTICS,
|
FILE_FLAG_BACKUP_SEMANTICS,
|
||||||
NULL);
|
nullptr);
|
||||||
|
|
||||||
if (hFile == INVALID_HANDLE_VALUE) {
|
if (hFile == INVALID_HANDLE_VALUE) {
|
||||||
errno = winerr2Errno(GetLastError());
|
errno = winerr2Errno(GetLastError());
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return frealpath(hFile, resolved_name);
|
return frealpath(hFile, resolved_name);
|
||||||
@@ -189,13 +189,13 @@ ssize_t freadlink(HANDLE hFile, char* buf, size_t bufsiz) {
|
|||||||
|
|
||||||
alignas(REPARSE_DATA_BUFFER) BYTE reparseBuf[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
|
alignas(REPARSE_DATA_BUFFER) BYTE reparseBuf[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
|
||||||
DWORD bytesReturned = 0;
|
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, nullptr, 0, reparseBuf, (DWORD) sizeof(reparseBuf), &bytesReturned, nullptr)) {
|
||||||
errno = winerr2Errno(GetLastError());
|
errno = winerr2Errno(GetLastError());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
REPARSE_DATA_BUFFER* rp = (REPARSE_DATA_BUFFER*) reparseBuf;
|
REPARSE_DATA_BUFFER* rp = (REPARSE_DATA_BUFFER*) reparseBuf;
|
||||||
const wchar_t* targetW = NULL;
|
const wchar_t* targetW = nullptr;
|
||||||
USHORT targetBytes = 0;
|
USHORT targetBytes = 0;
|
||||||
|
|
||||||
if (rp->ReparseTag == IO_REPARSE_TAG_SYMLINK) {
|
if (rp->ReparseTag == IO_REPARSE_TAG_SYMLINK) {
|
||||||
@@ -262,10 +262,10 @@ ssize_t readlink(const char* path, char* buf, size_t bufsiz) {
|
|||||||
pathW,
|
pathW,
|
||||||
0,
|
0,
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
NULL,
|
nullptr,
|
||||||
OPEN_EXISTING,
|
OPEN_EXISTING,
|
||||||
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
|
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
|
||||||
NULL);
|
nullptr);
|
||||||
|
|
||||||
if (hFile == INVALID_HANDLE_VALUE) {
|
if (hFile == INVALID_HANDLE_VALUE) {
|
||||||
errno = winerr2Errno(GetLastError());
|
errno = winerr2Errno(GetLastError());
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ static void appendOutputColor(FFstrbuf* buffer, const FFModuleArgs* module) {
|
|||||||
const char* ffPercentParseTypeJsonConfig(yyjson_val* jsonVal, FFPercentageTypeFlags* result) {
|
const char* ffPercentParseTypeJsonConfig(yyjson_val* jsonVal, FFPercentageTypeFlags* result) {
|
||||||
if (yyjson_is_uint(jsonVal)) {
|
if (yyjson_is_uint(jsonVal)) {
|
||||||
*result = (FFPercentageTypeFlags) yyjson_get_uint(jsonVal);
|
*result = (FFPercentageTypeFlags) yyjson_get_uint(jsonVal);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (yyjson_is_arr(jsonVal)) {
|
if (yyjson_is_arr(jsonVal)) {
|
||||||
FFPercentageTypeFlags flags = 0;
|
FFPercentageTypeFlags flags = 0;
|
||||||
@@ -45,7 +45,7 @@ const char* ffPercentParseTypeJsonConfig(yyjson_val* jsonVal, FFPercentageTypeFl
|
|||||||
}
|
}
|
||||||
|
|
||||||
*result = flags;
|
*result = flags;
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "Error: usage: percent.type must be a number or an array of strings";
|
return "Error: usage: percent.type must be a number or an array of strings";
|
||||||
@@ -90,7 +90,7 @@ void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFPercentageModuleConf
|
|||||||
|
|
||||||
bool monochrome = (percentType & FF_PERCENTAGE_TYPE_BAR_MONOCHROME_BIT) || !autoColorElapsed;
|
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;
|
const char* color = nullptr;
|
||||||
if (!autoColorElapsed) {
|
if (!autoColorElapsed) {
|
||||||
color = options->barColorElapsed.chars;
|
color = options->barColorElapsed.chars;
|
||||||
} else if (green <= yellow) {
|
} else if (green <= yellow) {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
|
|||||||
ffLogoPrintLine();
|
ffLogoPrintLine();
|
||||||
|
|
||||||
// This is used by --set-keyless, in this case we want neither the module name nor the separator
|
// This is used by --set-keyless, in this case we want neither the module name nor the separator
|
||||||
if (moduleName == NULL) {
|
if (moduleName == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
|
|||||||
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);
|
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
|
// nullptr 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) {
|
if ((printType & FF_PRINT_TYPE_NO_CUSTOM_KEY) || !moduleArgs || moduleArgs->key.length == 0) {
|
||||||
fputs(moduleName, stdout);
|
fputs(moduleName, stdout);
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
|
|||||||
bool ffPrintFormat(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, uint32_t numArgs, const FFformatarg* arguments) {
|
bool ffPrintFormat(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, uint32_t numArgs, const FFformatarg* arguments) {
|
||||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||||
bool success;
|
bool success;
|
||||||
if (__builtin_expect(moduleArgs != NULL, 1)) {
|
if (__builtin_expect(moduleArgs != nullptr, 1)) {
|
||||||
success = ffParseFormatString(&buffer, &moduleArgs->outputFormat, numArgs, arguments);
|
success = ffParseFormatString(&buffer, &moduleArgs->outputFormat, numArgs, arguments);
|
||||||
} else {
|
} else {
|
||||||
ffStrbufSetStatic(&buffer, "undefined format");
|
ffStrbufSetStatic(&buffer, "undefined format");
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ const char* ffProcessSpawn(char* const argv[], bool useStdErr, FFProcessHandle*
|
|||||||
posix_spawn_file_actions_adddup2(&file_actions, pipes[1], useStdErr ? STDERR_FILENO : STDOUT_FILENO);
|
posix_spawn_file_actions_adddup2(&file_actions, pipes[1], useStdErr ? STDERR_FILENO : STDOUT_FILENO);
|
||||||
posix_spawn_file_actions_adddup2(&file_actions, nullFile, useStdErr ? STDOUT_FILENO : STDERR_FILENO);
|
posix_spawn_file_actions_adddup2(&file_actions, nullFile, useStdErr ? STDOUT_FILENO : STDERR_FILENO);
|
||||||
|
|
||||||
static char* oldLang = NULL;
|
static char* oldLang = nullptr;
|
||||||
static int langIndex = -1;
|
static int langIndex = -1;
|
||||||
|
|
||||||
if (langIndex >= 0) {
|
if (langIndex >= 0) {
|
||||||
@@ -95,7 +95,7 @@ const char* ffProcessSpawn(char* const argv[], bool useStdErr, FFProcessHandle*
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (langIndex < 0) {
|
if (langIndex < 0) {
|
||||||
for (int i = 0; environ[i] != NULL; i++) {
|
for (int i = 0; environ[i] != nullptr; i++) {
|
||||||
if (ffStrStartsWith(environ[i], "LANG=")) {
|
if (ffStrStartsWith(environ[i], "LANG=")) {
|
||||||
langIndex = i;
|
langIndex = i;
|
||||||
const char* langValue = environ[i] + 5; // Skip "LANG="
|
const char* langValue = environ[i] + 5; // Skip "LANG="
|
||||||
@@ -112,7 +112,7 @@ const char* ffProcessSpawn(char* const argv[], bool useStdErr, FFProcessHandle*
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret = posix_spawnp(&childPid, argv[0], &file_actions, NULL, argv, environ);
|
int ret = posix_spawnp(&childPid, argv[0], &file_actions, nullptr, argv, environ);
|
||||||
|
|
||||||
if (oldLang) {
|
if (oldLang) {
|
||||||
environ[langIndex] = oldLang;
|
environ[langIndex] = oldLang;
|
||||||
@@ -153,7 +153,7 @@ const char* ffProcessSpawn(char* const argv[], bool useStdErr, FFProcessHandle*
|
|||||||
close(pipes[1]);
|
close(pipes[1]);
|
||||||
outHandle->pid = childPid;
|
outHandle->pid = childPid;
|
||||||
outHandle->pipeRead = pipes[0];
|
outHandle->pipeRead = pipes[0];
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ffProcessReadOutput(FFProcessHandle* handle, FFstrbuf* buffer) {
|
const char* ffProcessReadOutput(FFProcessHandle* handle, FFstrbuf* buffer) {
|
||||||
@@ -173,11 +173,11 @@ const char* ffProcessReadOutput(FFProcessHandle* handle, FFstrbuf* buffer) {
|
|||||||
int pollret = poll(&pollfd, 1, timeout);
|
int pollret = poll(&pollfd, 1, timeout);
|
||||||
if (pollret == 0) {
|
if (pollret == 0) {
|
||||||
kill(childPid, SIGTERM);
|
kill(childPid, SIGTERM);
|
||||||
waitpid(childPid, NULL, 0);
|
waitpid(childPid, nullptr, 0);
|
||||||
return "poll(&pollfd, 1, timeout) timeout (try increasing --processing-timeout)";
|
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);
|
kill(childPid, SIGTERM);
|
||||||
waitpid(childPid, NULL, 0);
|
waitpid(childPid, nullptr, 0);
|
||||||
return pollret < 0
|
return pollret < 0
|
||||||
? "poll(&pollfd, 1, timeout) error: pollret < 0"
|
? "poll(&pollfd, 1, timeout) error: pollret < 0"
|
||||||
: "poll(&pollfd, 1, timeout) error: pollfd.revents & POLLERR";
|
: "poll(&pollfd, 1, timeout) error: pollfd.revents & POLLERR";
|
||||||
@@ -197,9 +197,9 @@ const char* ffProcessReadOutput(FFProcessHandle* handle, FFstrbuf* buffer) {
|
|||||||
return "command not found";
|
return "command not found";
|
||||||
}
|
}
|
||||||
// We only handle 127 as an error. See `getTerminalVersionUrxvt` in `terminalshell.c`
|
// We only handle 127 as an error. See `getTerminalVersionUrxvt` in `terminalshell.c`
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return NULL;
|
return nullptr;
|
||||||
} else if (nRead < 0) {
|
} else if (nRead < 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -278,11 +278,11 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
|
|||||||
|
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
int mibs[] = { CTL_KERN, KERN_PROCARGS2, pid };
|
int mibs[] = { CTL_KERN, KERN_PROCARGS2, pid };
|
||||||
if (sysctl(mibs, ARRAY_SIZE(mibs), NULL, &len, NULL, 0) == 0) { // try get arg0
|
if (sysctl(mibs, ARRAY_SIZE(mibs), nullptr, &len, nullptr, 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.
|
// don't know why if don't let len longer, proArgs2 and len will change during the following sysctl() in old MacOS version.
|
||||||
len++;
|
len++;
|
||||||
FF_AUTO_FREE char* const procArgs2 = malloc(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, nullptr, 0) == 0) {
|
||||||
// https://gist.github.com/nonowarn/770696#file-getargv-c-L46
|
// https://gist.github.com/nonowarn/770696#file-getargv-c-L46
|
||||||
uint32_t argc = *(uint32_t*) procArgs2;
|
uint32_t argc = *(uint32_t*) procArgs2;
|
||||||
const char* realExePath = procArgs2 + sizeof(argc);
|
const char* realExePath = procArgs2 + sizeof(argc);
|
||||||
@@ -354,7 +354,7 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
|
|||||||
4,
|
4,
|
||||||
args,
|
args,
|
||||||
&size,
|
&size,
|
||||||
NULL,
|
nullptr,
|
||||||
0) == 0)
|
0) == 0)
|
||||||
ffStrbufSetNS(exePath, (uint32_t) (size - 1), args);
|
ffStrbufSetNS(exePath, (uint32_t) (size - 1), args);
|
||||||
|
|
||||||
@@ -374,7 +374,7 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
|
|||||||
4,
|
4,
|
||||||
args,
|
args,
|
||||||
&size,
|
&size,
|
||||||
NULL,
|
nullptr,
|
||||||
0) == 0) {
|
0) == 0) {
|
||||||
char* arg0 = args;
|
char* arg0 = args;
|
||||||
size_t arg0Len = strlen(args);
|
size_t arg0Len = strlen(args);
|
||||||
@@ -423,7 +423,7 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
|
|||||||
|
|
||||||
#elif defined(__OpenBSD__)
|
#elif defined(__OpenBSD__)
|
||||||
|
|
||||||
kvm_t* kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, NULL);
|
kvm_t* kd = kvm_open(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr);
|
||||||
int count = 0;
|
int count = 0;
|
||||||
const struct kinfo_proc* proc = kvm_getprocs(kd, KERN_PROC_PID, pid, sizeof(struct kinfo_proc), &count);
|
const struct kinfo_proc* proc = kvm_getprocs(kd, KERN_PROC_PID, pid, sizeof(struct kinfo_proc), &count);
|
||||||
if (proc) {
|
if (proc) {
|
||||||
@@ -488,7 +488,7 @@ const char* ffProcessGetBasicInfoLinux(pid_t pid, FFstrbuf* name, pid_t* ppid, i
|
|||||||
}
|
}
|
||||||
buf[nRead] = '\0'; // pid (comm) state ppid pgrp session tty
|
buf[nRead] = '\0'; // pid (comm) state ppid pgrp session tty
|
||||||
|
|
||||||
const char* pState = NULL;
|
const char* pState = nullptr;
|
||||||
|
|
||||||
{
|
{
|
||||||
// comm in `/proc/pid/stat` is not encoded, and may contain ' ', ')' or even `\n`
|
// comm in `/proc/pid/stat` is not encoded, and may contain ' ', ')' or even `\n`
|
||||||
@@ -542,7 +542,7 @@ const char* ffProcessGetBasicInfoLinux(pid_t pid, FFstrbuf* name, pid_t* ppid, i
|
|||||||
struct kinfo_proc proc;
|
struct kinfo_proc proc;
|
||||||
size_t size = sizeof(proc);
|
size_t size = sizeof(proc);
|
||||||
if (sysctl(
|
if (sysctl(
|
||||||
(int[]) { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid }, 4, &proc, &size, NULL, 0)) {
|
(int[]) { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid }, 4, &proc, &size, nullptr, 0)) {
|
||||||
return "sysctl(KERN_PROC_PID) failed";
|
return "sysctl(KERN_PROC_PID) failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -568,7 +568,7 @@ const char* ffProcessGetBasicInfoLinux(pid_t pid, FFstrbuf* name, pid_t* ppid, i
|
|||||||
struct kinfo_proc proc;
|
struct kinfo_proc proc;
|
||||||
size_t size = sizeof(proc);
|
size_t size = sizeof(proc);
|
||||||
if (sysctl(
|
if (sysctl(
|
||||||
(int[]) { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid }, 4, &proc, &size, NULL, 0)) {
|
(int[]) { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid }, 4, &proc, &size, nullptr, 0)) {
|
||||||
return "sysctl(KERN_PROC_PID) failed";
|
return "sysctl(KERN_PROC_PID) failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -580,7 +580,7 @@ const char* ffProcessGetBasicInfoLinux(pid_t pid, FFstrbuf* name, pid_t* ppid, i
|
|||||||
if (proc.ki_tdev != NODEV && proc.ki_flag & P_CONTROLT) {
|
if (proc.ki_tdev != NODEV && proc.ki_flag & P_CONTROLT) {
|
||||||
const char* ttyName = devname(proc.ki_tdev, S_IFCHR);
|
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);
|
*tty = (int32_t) strtol(ttyName + strlen("pts/"), nullptr, 10);
|
||||||
} else {
|
} else {
|
||||||
*tty = -1;
|
*tty = -1;
|
||||||
}
|
}
|
||||||
@@ -594,7 +594,7 @@ const char* ffProcessGetBasicInfoLinux(pid_t pid, FFstrbuf* name, pid_t* ppid, i
|
|||||||
struct kinfo_proc2 proc;
|
struct kinfo_proc2 proc;
|
||||||
size_t size = sizeof(proc);
|
size_t size = sizeof(proc);
|
||||||
if (sysctl(
|
if (sysctl(
|
||||||
(int[]) { CTL_KERN, KERN_PROC2, KERN_PROC_PID, pid, sizeof(proc), 1 }, 6, &proc, &size, NULL, 0) != 0) {
|
(int[]) { CTL_KERN, KERN_PROC2, KERN_PROC_PID, pid, sizeof(proc), 1 }, 6, &proc, &size, nullptr, 0) != 0) {
|
||||||
return "sysctl(KERN_PROC_PID) failed";
|
return "sysctl(KERN_PROC_PID) failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -606,7 +606,7 @@ const char* ffProcessGetBasicInfoLinux(pid_t pid, FFstrbuf* name, pid_t* ppid, i
|
|||||||
if (proc.p_flag & P_CONTROLT) {
|
if (proc.p_flag & P_CONTROLT) {
|
||||||
const char* ttyName = devname(proc.p_tdev, S_IFCHR);
|
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);
|
*tty = (int32_t) strtol(ttyName + strlen("pts/"), nullptr, 10);
|
||||||
} else {
|
} else {
|
||||||
*tty = -1;
|
*tty = -1;
|
||||||
}
|
}
|
||||||
@@ -633,7 +633,7 @@ const char* ffProcessGetBasicInfoLinux(pid_t pid, FFstrbuf* name, pid_t* ppid, i
|
|||||||
|
|
||||||
#elif defined(__OpenBSD__)
|
#elif defined(__OpenBSD__)
|
||||||
|
|
||||||
kvm_t* kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, NULL);
|
kvm_t* kd = kvm_open(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr);
|
||||||
int count = 0;
|
int count = 0;
|
||||||
const struct kinfo_proc* proc = kvm_getprocs(kd, KERN_PROC_PID, pid, sizeof(struct kinfo_proc), &count);
|
const struct kinfo_proc* proc = kvm_getprocs(kd, KERN_PROC_PID, pid, sizeof(struct kinfo_proc), &count);
|
||||||
if (proc) {
|
if (proc) {
|
||||||
@@ -668,5 +668,5 @@ const char* ffProcessGetBasicInfoLinux(pid_t pid, FFstrbuf* name, pid_t* ppid, i
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ static void argvToCmdline(char* const argv[], FFstrbuf* result) {
|
|||||||
// From https://gist.github.com/jin-x/cdd641d98887524b091fb1f82a68717d
|
// From https://gist.github.com/jin-x/cdd641d98887524b091fb1f82a68717d
|
||||||
|
|
||||||
FF_STRBUF_AUTO_DESTROY temp = ffStrbufCreate();
|
FF_STRBUF_AUTO_DESTROY temp = ffStrbufCreate();
|
||||||
for (int i = 0; argv[i] != NULL; i++) {
|
for (int i = 0; argv[i] != nullptr; i++) {
|
||||||
ffStrbufSetS(&temp, argv[i]);
|
ffStrbufSetS(&temp, argv[i]);
|
||||||
// Add slash (\) before double quotes (") and duplicate slashes before it
|
// Add slash (\) before double quotes (") and duplicate slashes before it
|
||||||
for (
|
for (
|
||||||
@@ -63,7 +63,7 @@ const char* ffProcessSpawn(char* const argv[], bool useStdErr, FFProcessHandle*
|
|||||||
FF_PIPE_BUFSIZ,
|
FF_PIPE_BUFSIZ,
|
||||||
FF_PIPE_BUFSIZ,
|
FF_PIPE_BUFSIZ,
|
||||||
0,
|
0,
|
||||||
NULL);
|
nullptr);
|
||||||
if (hChildPipeRead == INVALID_HANDLE_VALUE) {
|
if (hChildPipeRead == INVALID_HANDLE_VALUE) {
|
||||||
return "CreateNamedPipeW(L\"\\\\.\\pipe\\FASTFETCH-$(PID)\") failed";
|
return "CreateNamedPipeW(L\"\\\\.\\pipe\\FASTFETCH-$(PID)\") failed";
|
||||||
}
|
}
|
||||||
@@ -74,12 +74,12 @@ const char* ffProcessSpawn(char* const argv[], bool useStdErr, FFProcessHandle*
|
|||||||
0,
|
0,
|
||||||
&(SECURITY_ATTRIBUTES) {
|
&(SECURITY_ATTRIBUTES) {
|
||||||
.nLength = sizeof(SECURITY_ATTRIBUTES),
|
.nLength = sizeof(SECURITY_ATTRIBUTES),
|
||||||
.lpSecurityDescriptor = NULL,
|
.lpSecurityDescriptor = nullptr,
|
||||||
.bInheritHandle = TRUE,
|
.bInheritHandle = TRUE,
|
||||||
},
|
},
|
||||||
OPEN_EXISTING,
|
OPEN_EXISTING,
|
||||||
0,
|
0,
|
||||||
NULL);
|
nullptr);
|
||||||
if (hChildPipeWrite == INVALID_HANDLE_VALUE) {
|
if (hChildPipeWrite == INVALID_HANDLE_VALUE) {
|
||||||
return "CreateFileW(L\"\\\\.\\pipe\\FASTFETCH-$(PID)\") failed";
|
return "CreateFileW(L\"\\\\.\\pipe\\FASTFETCH-$(PID)\") failed";
|
||||||
}
|
}
|
||||||
@@ -97,26 +97,26 @@ const char* ffProcessSpawn(char* const argv[], bool useStdErr, FFProcessHandle*
|
|||||||
siStartInfo.hStdError = ffGetNullFD();
|
siStartInfo.hStdError = ffGetNullFD();
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_AUTO_FREE wchar_t* cmdline = NULL;
|
FF_AUTO_FREE wchar_t* cmdline = nullptr;
|
||||||
{
|
{
|
||||||
FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
|
FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
|
||||||
argvToCmdline(argv, &buf);
|
argvToCmdline(argv, &buf);
|
||||||
uint32_t cmdlineBytes = (buf.length + 1) * sizeof(wchar_t);
|
uint32_t cmdlineBytes = (buf.length + 1) * sizeof(wchar_t);
|
||||||
cmdline = malloc(cmdlineBytes);
|
cmdline = malloc(cmdlineBytes);
|
||||||
if (!NT_SUCCESS(RtlUTF8ToUnicodeN(cmdline, cmdlineBytes, NULL, buf.chars, buf.length + 1))) {
|
if (!NT_SUCCESS(RtlUTF8ToUnicodeN(cmdline, cmdlineBytes, nullptr, buf.chars, buf.length + 1))) {
|
||||||
return "RtlUTF8ToUnicodeN() failed";
|
return "RtlUTF8ToUnicodeN() failed";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL success = CreateProcessW(
|
BOOL success = CreateProcessW(
|
||||||
NULL, // application name
|
nullptr, // application name
|
||||||
cmdline, // command line
|
cmdline, // command line
|
||||||
NULL, // process security attributes
|
nullptr, // process security attributes
|
||||||
NULL, // primary thread security attributes
|
nullptr, // primary thread security attributes
|
||||||
TRUE, // handles are inherited
|
TRUE, // handles are inherited
|
||||||
0, // creation flags
|
0, // creation flags
|
||||||
NULL, // use parent's environment
|
nullptr, // use parent's environment
|
||||||
NULL, // use parent's current directory
|
nullptr, // use parent's current directory
|
||||||
&siStartInfo, // STARTUPINFO pointer
|
&siStartInfo, // STARTUPINFO pointer
|
||||||
&piProcInfo // receives PROCESS_INFORMATION
|
&piProcInfo // receives PROCESS_INFORMATION
|
||||||
);
|
);
|
||||||
@@ -134,7 +134,7 @@ const char* ffProcessSpawn(char* const argv[], bool useStdErr, FFProcessHandle*
|
|||||||
outHandle->pipeRead = hChildPipeRead;
|
outHandle->pipeRead = hChildPipeRead;
|
||||||
hChildPipeRead = INVALID_HANDLE_VALUE; // ownership transferred, don't close it
|
hChildPipeRead = INVALID_HANDLE_VALUE; // ownership transferred, don't close it
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
@@ -154,11 +154,11 @@ const char* ffProcessReadOutput(FFProcessHandle* handle, FFstrbuf* buffer) {
|
|||||||
int32_t timeout = instance.config.general.processingTimeout;
|
int32_t timeout = instance.config.general.processingTimeout;
|
||||||
FF_AUTO_CLOSE_FD HANDLE hProcess = handle->pid;
|
FF_AUTO_CLOSE_FD HANDLE hProcess = handle->pid;
|
||||||
FF_AUTO_CLOSE_FD HANDLE hChildPipeRead = handle->pipeRead;
|
FF_AUTO_CLOSE_FD HANDLE hChildPipeRead = handle->pipeRead;
|
||||||
FF_AUTO_CLOSE_FD HANDLE hReadEvent = NULL;
|
FF_AUTO_CLOSE_FD HANDLE hReadEvent = nullptr;
|
||||||
handle->pid = INVALID_HANDLE_VALUE;
|
handle->pid = INVALID_HANDLE_VALUE;
|
||||||
handle->pipeRead = 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, nullptr, SynchronizationEvent, FALSE))) {
|
||||||
return "NtCreateEvent() failed";
|
return "NtCreateEvent() failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,13 +169,13 @@ const char* ffProcessReadOutput(FFProcessHandle* handle, FFstrbuf* buffer) {
|
|||||||
NTSTATUS status = NtReadFile(
|
NTSTATUS status = NtReadFile(
|
||||||
hChildPipeRead,
|
hChildPipeRead,
|
||||||
hReadEvent,
|
hReadEvent,
|
||||||
NULL,
|
nullptr,
|
||||||
NULL,
|
nullptr,
|
||||||
&iosb,
|
&iosb,
|
||||||
str,
|
str,
|
||||||
(ULONG) sizeof(str),
|
(ULONG) sizeof(str),
|
||||||
NULL,
|
nullptr,
|
||||||
NULL);
|
nullptr);
|
||||||
if (status == STATUS_PENDING) {
|
if (status == STATUS_PENDING) {
|
||||||
switch (NtWaitForSingleObject(hReadEvent, FALSE, &(LARGE_INTEGER) { .QuadPart = (int64_t) timeout * -10000 })) {
|
switch (NtWaitForSingleObject(hReadEvent, FALSE, &(LARGE_INTEGER) { .QuadPart = (int64_t) timeout * -10000 })) {
|
||||||
case STATUS_WAIT_0:
|
case STATUS_WAIT_0:
|
||||||
@@ -198,7 +198,7 @@ const char* ffProcessReadOutput(FFProcessHandle* handle, FFstrbuf* buffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!NT_SUCCESS(status)) {
|
if (!NT_SUCCESS(status)) {
|
||||||
terminateChildProcess(hProcess, hChildPipeRead, NULL, &iosb);
|
terminateChildProcess(hProcess, hChildPipeRead, nullptr, &iosb);
|
||||||
return "NtReadFile(hChildPipeRead) failed";
|
return "NtReadFile(hChildPipeRead) failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,7 +219,7 @@ exit: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ bool ffParsePropLines(const char* lines, const char* start, FFstrbuf* buffer) {
|
|||||||
|
|
||||||
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");
|
FF_AUTO_CLOSE_FILE FILE* file = fopen(filename, "r");
|
||||||
if (file == NULL) {
|
if (file == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +115,7 @@ bool ffParsePropFileValues(const char* filename, uint32_t numQueries, FFpropquer
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!allSet) {
|
if (!allSet) {
|
||||||
FF_AUTO_FREE char* line = NULL;
|
FF_AUTO_FREE char* line = nullptr;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
||||||
while (getline(&line, &len, file) != -1) {
|
while (getline(&line, &len, file) != -1) {
|
||||||
|
|||||||
+60
-60
@@ -19,10 +19,10 @@ typedef struct GVariantGetters {
|
|||||||
static FFvariant getGVariantValue(GVariant* variant, FFvarianttype type, const GVariantGetters* variantGetters) {
|
static FFvariant getGVariantValue(GVariant* variant, FFvarianttype type, const GVariantGetters* variantGetters) {
|
||||||
FFvariant result;
|
FFvariant result;
|
||||||
|
|
||||||
if (variant == NULL) {
|
if (variant == nullptr) {
|
||||||
result = FF_VARIANT_NULL;
|
result = FF_VARIANT_NULL;
|
||||||
} else if (type == FF_VARIANT_TYPE_STRING) {
|
} 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
|
result = (FFvariant) { .strValue = variantGetters->ffg_variant_dup_string(variant, nullptr) }; // Dup string, so that variant itself can be freed
|
||||||
} else if (type == FF_VARIANT_TYPE_BOOL) {
|
} else if (type == FF_VARIANT_TYPE_BOOL) {
|
||||||
result = (FFvariant) { .boolValue = (bool) variantGetters->ffg_variant_get_boolean(variant), .boolValueSet = true };
|
result = (FFvariant) { .boolValue = (bool) variantGetters->ffg_variant_get_boolean(variant), .boolValueSet = true };
|
||||||
} else if (type == FF_VARIANT_TYPE_INT) {
|
} else if (type == FF_VARIANT_TYPE_INT) {
|
||||||
@@ -57,27 +57,27 @@ static const GSettingsData* getGSettingsData(void) {
|
|||||||
|
|
||||||
if (!data.inited) {
|
if (!data.inited) {
|
||||||
data.inited = true;
|
data.inited = true;
|
||||||
FF_LIBRARY_LOAD(libgsettings, NULL, "libgio-2.0" FF_LIBRARY_EXTENSION, 1);
|
FF_LIBRARY_LOAD(libgsettings, nullptr, "libgio-2.0" FF_LIBRARY_EXTENSION, 1);
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_schema_source_lookup, NULL)
|
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_schema_source_lookup, nullptr)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_schema_has_key, NULL)
|
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_schema_has_key, nullptr)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_new_full, NULL)
|
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_new_full, nullptr)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_get_value, NULL)
|
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_get_value, nullptr)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_get_user_value, NULL)
|
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_get_user_value, nullptr)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_get_default_value, NULL)
|
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_get_default_value, nullptr)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_schema_source_get_default, NULL)
|
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_schema_source_get_default, nullptr)
|
||||||
|
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data.variantGetters, g_variant_dup_string, NULL)
|
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data.variantGetters, g_variant_dup_string, nullptr)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data.variantGetters, g_variant_get_boolean, NULL)
|
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data.variantGetters, g_variant_get_boolean, nullptr)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data.variantGetters, g_variant_get_int32, NULL)
|
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data.variantGetters, g_variant_get_int32, nullptr)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data.variantGetters, g_variant_unref, NULL);
|
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data.variantGetters, g_variant_unref, nullptr);
|
||||||
|
|
||||||
data.schemaSource = data.ffg_settings_schema_source_get_default();
|
data.schemaSource = data.ffg_settings_schema_source_get_default();
|
||||||
if (data.schemaSource) {
|
if (data.schemaSource) {
|
||||||
libgsettings = NULL;
|
libgsettings = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!data.schemaSource) {
|
if (!data.schemaSource) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &data;
|
return &data;
|
||||||
@@ -85,12 +85,12 @@ static const GSettingsData* getGSettingsData(void) {
|
|||||||
|
|
||||||
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();
|
const GSettingsData* data = getGSettingsData();
|
||||||
if (data == NULL) {
|
if (data == nullptr) {
|
||||||
return FF_VARIANT_NULL;
|
return FF_VARIANT_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
GSettingsSchema* schema = data->ffg_settings_schema_source_lookup(data->schemaSource, schemaName, true);
|
GSettingsSchema* schema = data->ffg_settings_schema_source_lookup(data->schemaSource, schemaName, true);
|
||||||
if (schema == NULL) {
|
if (schema == nullptr) {
|
||||||
return FF_VARIANT_NULL;
|
return FF_VARIANT_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,18 +98,18 @@ FFvariant ffSettingsGetGSettings(const char* schemaName, const char* path, const
|
|||||||
return FF_VARIANT_NULL;
|
return FF_VARIANT_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
GSettings* settings = data->ffg_settings_new_full(schema, NULL, path);
|
GSettings* settings = data->ffg_settings_new_full(schema, nullptr, path);
|
||||||
if (settings == NULL) {
|
if (settings == nullptr) {
|
||||||
return FF_VARIANT_NULL;
|
return FF_VARIANT_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
GVariant* variant = data->ffg_settings_get_value(settings, key);
|
GVariant* variant = data->ffg_settings_get_value(settings, key);
|
||||||
if (variant != NULL) {
|
if (variant != nullptr) {
|
||||||
return getGVariantValue(variant, type, &data->variantGetters);
|
return getGVariantValue(variant, type, &data->variantGetters);
|
||||||
}
|
}
|
||||||
|
|
||||||
variant = data->ffg_settings_get_user_value(settings, key);
|
variant = data->ffg_settings_get_user_value(settings, key);
|
||||||
if (variant != NULL) {
|
if (variant != nullptr) {
|
||||||
return getGVariantValue(variant, type, &data->variantGetters);
|
return getGVariantValue(variant, type, &data->variantGetters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,21 +141,21 @@ static const DConfData* getDConfData(void) {
|
|||||||
if (!data.inited) {
|
if (!data.inited) {
|
||||||
data.inited = true;
|
data.inited = true;
|
||||||
|
|
||||||
FF_LIBRARY_LOAD(libdconf, NULL, "libdconf" FF_LIBRARY_EXTENSION, 2);
|
FF_LIBRARY_LOAD(libdconf, nullptr, "libdconf" FF_LIBRARY_EXTENSION, 2);
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data, dconf_client_read_full, NULL)
|
FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data, dconf_client_read_full, nullptr)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data, dconf_client_new, NULL)
|
FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data, dconf_client_new, nullptr)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data.variantGetters, g_variant_dup_string, NULL)
|
FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data.variantGetters, g_variant_dup_string, nullptr)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data.variantGetters, g_variant_get_boolean, NULL)
|
FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data.variantGetters, g_variant_get_boolean, nullptr)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data.variantGetters, g_variant_get_int32, NULL)
|
FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data.variantGetters, g_variant_get_int32, nullptr)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data.variantGetters, g_variant_unref, NULL)
|
FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data.variantGetters, g_variant_unref, nullptr)
|
||||||
|
|
||||||
data.client = data.ffdconf_client_new();
|
data.client = data.ffdconf_client_new();
|
||||||
if (data.client) {
|
if (data.client) {
|
||||||
libdconf = NULL;
|
libdconf = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!data.client) {
|
if (!data.client) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &data;
|
return &data;
|
||||||
@@ -163,21 +163,21 @@ static const DConfData* getDConfData(void) {
|
|||||||
|
|
||||||
FFvariant ffSettingsGetDConf(const char* key, FFvarianttype type) {
|
FFvariant ffSettingsGetDConf(const char* key, FFvarianttype type) {
|
||||||
const DConfData* data = getDConfData();
|
const DConfData* data = getDConfData();
|
||||||
if (data == NULL) {
|
if (data == nullptr) {
|
||||||
return FF_VARIANT_NULL;
|
return FF_VARIANT_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
GVariant* variant = data->ffdconf_client_read_full(data->client, key, DCONF_READ_FLAGS_NONE, NULL);
|
GVariant* variant = data->ffdconf_client_read_full(data->client, key, DCONF_READ_FLAGS_NONE, nullptr);
|
||||||
if (variant != NULL) {
|
if (variant != nullptr) {
|
||||||
return getGVariantValue(variant, type, &data->variantGetters);
|
return getGVariantValue(variant, type, &data->variantGetters);
|
||||||
}
|
}
|
||||||
|
|
||||||
variant = data->ffdconf_client_read_full(data->client, key, DCONF_READ_USER_VALUE, NULL);
|
variant = data->ffdconf_client_read_full(data->client, key, DCONF_READ_USER_VALUE, nullptr);
|
||||||
if (variant != NULL) {
|
if (variant != nullptr) {
|
||||||
return getGVariantValue(variant, type, &data->variantGetters);
|
return getGVariantValue(variant, type, &data->variantGetters);
|
||||||
}
|
}
|
||||||
|
|
||||||
variant = data->ffdconf_client_read_full(data->client, key, DCONF_READ_DEFAULT_VALUE, NULL);
|
variant = data->ffdconf_client_read_full(data->client, key, DCONF_READ_DEFAULT_VALUE, nullptr);
|
||||||
return getGVariantValue(variant, type, &data->variantGetters);
|
return getGVariantValue(variant, type, &data->variantGetters);
|
||||||
}
|
}
|
||||||
#else // FF_HAVE_DCONF
|
#else // FF_HAVE_DCONF
|
||||||
@@ -192,7 +192,7 @@ FFvariant ffSettingsGetGnome(const char* dconfKey, const char* gsettingsSchemaNa
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
(type == FF_VARIANT_TYPE_BOOL && gsettings.boolValueSet) ||
|
(type == FF_VARIANT_TYPE_BOOL && gsettings.boolValueSet) ||
|
||||||
(type != FF_VARIANT_TYPE_BOOL && gsettings.strValue != NULL)) {
|
(type != FF_VARIANT_TYPE_BOOL && gsettings.strValue != nullptr)) {
|
||||||
return gsettings;
|
return gsettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,7 +204,7 @@ FFvariant ffSettingsGetGnome(const char* dconfKey, const char* gsettingsSchemaNa
|
|||||||
|
|
||||||
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 = {};
|
FF_DBUS_AUTO_DESTROY_DATA FFDBusData dbus = {};
|
||||||
if (ffDBusLoadData(DBUS_BUS_SESSION, &dbus) != NULL) {
|
if (ffDBusLoadData(DBUS_BUS_SESSION, &dbus) != nullptr) {
|
||||||
return FF_VARIANT_NULL;
|
return FF_VARIANT_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,7 +260,7 @@ FFvariant ffSettingsGetXFConf(const char* channelName, const char* propertyName,
|
|||||||
|
|
||||||
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 = {};
|
FF_DBUS_AUTO_DESTROY_DATA FFDBusData dbus = {};
|
||||||
if (ffDBusLoadData(DBUS_BUS_SESSION, &dbus) != NULL) {
|
if (ffDBusLoadData(DBUS_BUS_SESSION, &dbus) != nullptr) {
|
||||||
return FF_VARIANT_NULL;
|
return FF_VARIANT_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -361,20 +361,20 @@ static const SQLiteData* getSQLiteData(void) {
|
|||||||
|
|
||||||
if (!data.inited) {
|
if (!data.inited) {
|
||||||
data.inited = true;
|
data.inited = true;
|
||||||
FF_LIBRARY_LOAD(libsqlite, NULL, "libsqlite3" FF_LIBRARY_EXTENSION, 1);
|
FF_LIBRARY_LOAD(libsqlite, nullptr, "libsqlite3" FF_LIBRARY_EXTENSION, 1);
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_open_v2, NULL)
|
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_open_v2, nullptr)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_prepare_v2, NULL)
|
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_prepare_v2, nullptr)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_step, NULL)
|
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_step, nullptr)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_data_count, NULL)
|
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_data_count, nullptr)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_column_int, NULL)
|
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_column_int, nullptr)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_column_text, NULL)
|
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_column_text, nullptr)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_finalize, NULL)
|
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_finalize, nullptr)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_close, NULL)
|
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_close, nullptr)
|
||||||
libsqlite = NULL;
|
libsqlite = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data.ffsqlite3_close) {
|
if (!data.ffsqlite3_close) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &data;
|
return &data;
|
||||||
@@ -386,17 +386,17 @@ int ffSettingsGetSQLite3Int(const char* dbPath, const char* query) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const SQLiteData* data = getSQLiteData();
|
const SQLiteData* data = getSQLiteData();
|
||||||
if (data == NULL) {
|
if (data == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3* db;
|
sqlite3* db;
|
||||||
if (data->ffsqlite3_open_v2(dbPath, &db, SQLITE_OPEN_READONLY, NULL) != SQLITE_OK) {
|
if (data->ffsqlite3_open_v2(dbPath, &db, SQLITE_OPEN_READONLY | SQLITE_OPEN_NOMUTEX, nullptr) != SQLITE_OK) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3_stmt* stmt;
|
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, nullptr) != SQLITE_OK) {
|
||||||
data->ffsqlite3_close(db);
|
data->ffsqlite3_close(db);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -421,17 +421,17 @@ bool ffSettingsGetSQLite3String(const char* dbPath, const char* query, FFstrbuf*
|
|||||||
}
|
}
|
||||||
|
|
||||||
const SQLiteData* data = getSQLiteData();
|
const SQLiteData* data = getSQLiteData();
|
||||||
if (data == NULL) {
|
if (data == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3* db;
|
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, nullptr) != SQLITE_OK) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3_stmt* stmt;
|
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, nullptr) != SQLITE_OK) {
|
||||||
data->ffsqlite3_close(db);
|
data->ffsqlite3_close(db);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -514,12 +514,12 @@ typedef struct E_Config {
|
|||||||
#define FF_EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct_type, member, type) \
|
#define FF_EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct_type, member, type) \
|
||||||
do { \
|
do { \
|
||||||
struct_type ___ett; \
|
struct_type ___ett; \
|
||||||
ffeet_data_descriptor_element_add(edd, #member, type, EET_G_UNKNOWN, (char*) (&(___ett.member)) - (char*) (&(___ett)), 0, /* 0, */ NULL, NULL); \
|
ffeet_data_descriptor_element_add(edd, #member, type, EET_G_UNKNOWN, (char*) (&(___ett.member)) - (char*) (&(___ett)), 0, /* 0, */ nullptr, nullptr); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#define FF_EET_DATA_DESCRIPTOR_ADD_LIST(edd, struct_type, member, subtype) \
|
#define FF_EET_DATA_DESCRIPTOR_ADD_LIST(edd, struct_type, member, subtype) \
|
||||||
do { \
|
do { \
|
||||||
struct_type ___ett; \
|
struct_type ___ett; \
|
||||||
ffeet_data_descriptor_element_add(edd, #member, EET_T_UNKNOW, EET_G_LIST, (char*) (&(___ett.member)) - (char*) (&(___ett)), 0, /* 0, */ NULL, subtype); \
|
ffeet_data_descriptor_element_add(edd, #member, EET_T_UNKNOW, EET_G_LIST, (char*) (&(___ett.member)) - (char*) (&(___ett)), 0, /* 0, */ nullptr, subtype); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
bool ffSettingsGetEnlightenmentProperty(ffEnlightenmentSettings* result) {
|
bool ffSettingsGetEnlightenmentProperty(ffEnlightenmentSettings* result) {
|
||||||
@@ -603,7 +603,7 @@ bool ffSettingsGetEnlightenmentProperty(ffEnlightenmentSettings* result) {
|
|||||||
return !!parsed;
|
return !!parsed;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
bool ffSettingsGetEnlightenmentProperty(FF_A_UNUSED ffEnlightenmentSettings* result) {
|
bool ffSettingsGetEnlightenmentProperty([[maybe_unused]] ffEnlightenmentSettings* result) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -27,16 +27,16 @@ void ffSizeAppendNum(uint64_t bytes, FFstrbuf* result) {
|
|||||||
const FFOptionsDisplay* options = &instance.config.display;
|
const FFOptionsDisplay* options = &instance.config.display;
|
||||||
switch (options->sizeBinaryPrefix) {
|
switch (options->sizeBinaryPrefix) {
|
||||||
case FF_SIZE_BINARY_PREFIX_TYPE_IEC:
|
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", nullptr });
|
||||||
break;
|
break;
|
||||||
case FF_SIZE_BINARY_PREFIX_TYPE_SI:
|
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", nullptr });
|
||||||
break;
|
break;
|
||||||
case FF_SIZE_BINARY_PREFIX_TYPE_JEDEC:
|
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", nullptr });
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
appendNum(result, bytes, 1024, (const char*[]) { "B", NULL });
|
appendNum(result, bytes, 1024, (const char*[]) { "B", nullptr });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-25
@@ -63,10 +63,10 @@ const FFSmbiosHeader* ffSmbiosNextEntry(const FFSmbiosHeader* header) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool parseSmbiosTable(const uint8_t* data, uint32_t length) {
|
static bool parseSmbiosTable(const uint8_t* data, uint32_t length) {
|
||||||
const FFSmbiosHeader* endOfTable = NULL;
|
const FFSmbiosHeader* endOfTable = nullptr;
|
||||||
|
|
||||||
FF_DEBUG("Parsing SMBIOS table structures with length %u bytes", length);
|
FF_DEBUG("Parsing SMBIOS table structures with length %u bytes", length);
|
||||||
FF_A_UNUSED int structureCount = 0, totalCount = 0;
|
[[maybe_unused]] int structureCount = 0, totalCount = 0;
|
||||||
for (
|
for (
|
||||||
const FFSmbiosHeader* header = (const FFSmbiosHeader*) data;
|
const FFSmbiosHeader* header = (const FFSmbiosHeader*) data;
|
||||||
(const uint8_t*) header + sizeof(FFSmbiosHeader) < (const uint8_t*) data + length;
|
(const uint8_t*) header + sizeof(FFSmbiosHeader) < (const uint8_t*) data + length;
|
||||||
@@ -214,7 +214,7 @@ static bool readPhysicalMemory(int fd, off_t address, size_t length, void* buffe
|
|||||||
size_t pageOffset = (size_t) (address - alignedAddress);
|
size_t pageOffset = (size_t) (address - alignedAddress);
|
||||||
size_t mapLength = pageOffset + length;
|
size_t mapLength = pageOffset + length;
|
||||||
|
|
||||||
void* p = mmap(NULL, mapLength, PROT_READ, MAP_SHARED, fd, alignedAddress);
|
void* p = mmap(nullptr, mapLength, PROT_READ, MAP_SHARED, fd, alignedAddress);
|
||||||
if (p == MAP_FAILED) {
|
if (p == MAP_FAILED) {
|
||||||
FF_DEBUG("mmap failed at aligned address 0x%lx for %zu bytes: %s",
|
FF_DEBUG("mmap failed at aligned address 0x%lx for %zu bytes: %s",
|
||||||
(unsigned long) alignedAddress,
|
(unsigned long) alignedAddress,
|
||||||
@@ -228,7 +228,7 @@ static bool readPhysicalMemory(int fd, off_t address, size_t length, void* buffe
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct FFSmbios20EntryPoint {
|
typedef struct [[gnu::packed]] FFSmbios20EntryPoint {
|
||||||
uint8_t AnchorString[4];
|
uint8_t AnchorString[4];
|
||||||
uint8_t EntryPointStructureChecksum;
|
uint8_t EntryPointStructureChecksum;
|
||||||
uint8_t EntryPointLength;
|
uint8_t EntryPointLength;
|
||||||
@@ -243,11 +243,11 @@ typedef struct FFSmbios20EntryPoint {
|
|||||||
uint32_t StructureTableAddress;
|
uint32_t StructureTableAddress;
|
||||||
uint16_t NumberOfSmbiosStructures;
|
uint16_t NumberOfSmbiosStructures;
|
||||||
uint8_t SmbiosBcdRevision;
|
uint8_t SmbiosBcdRevision;
|
||||||
} FF_A_PACKED FFSmbios20EntryPoint;
|
} FFSmbios20EntryPoint;
|
||||||
static_assert(offsetof(FFSmbios20EntryPoint, SmbiosBcdRevision) == 0x1E,
|
static_assert(offsetof(FFSmbios20EntryPoint, SmbiosBcdRevision) == 0x1E,
|
||||||
"FFSmbios20EntryPoint: Wrong struct alignment");
|
"FFSmbios20EntryPoint: Wrong struct alignment");
|
||||||
|
|
||||||
typedef struct FFSmbios30EntryPoint {
|
typedef struct [[gnu::packed]] FFSmbios30EntryPoint {
|
||||||
uint8_t AnchorString[5];
|
uint8_t AnchorString[5];
|
||||||
uint8_t EntryPointStructureChecksum;
|
uint8_t EntryPointStructureChecksum;
|
||||||
uint8_t EntryPointLength;
|
uint8_t EntryPointLength;
|
||||||
@@ -258,7 +258,7 @@ typedef struct FFSmbios30EntryPoint {
|
|||||||
uint8_t Reversed;
|
uint8_t Reversed;
|
||||||
uint32_t StructureTableMaximumSize;
|
uint32_t StructureTableMaximumSize;
|
||||||
uint64_t StructureTableAddress;
|
uint64_t StructureTableAddress;
|
||||||
} FF_A_PACKED FFSmbios30EntryPoint;
|
} FFSmbios30EntryPoint;
|
||||||
|
|
||||||
static_assert(offsetof(FFSmbios30EntryPoint, StructureTableAddress) == 0x10,
|
static_assert(offsetof(FFSmbios30EntryPoint, StructureTableAddress) == 0x10,
|
||||||
"FFSmbios30EntryPoint: Wrong struct alignment");
|
"FFSmbios30EntryPoint: Wrong struct alignment");
|
||||||
@@ -457,7 +457,7 @@ static bool fillTableBufferPlatform(FFstrbuf* buffer) {
|
|||||||
} while (address < lineEnd && (*address == ' ' || *address == '\t'));
|
} while (address < lineEnd && (*address == ' ' || *address == '\t'));
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
char* addressEnd = NULL;
|
char* addressEnd = nullptr;
|
||||||
unsigned long long parsedAddress = strtoull(address, &addressEnd, 16);
|
unsigned long long parsedAddress = strtoull(address, &addressEnd, 16);
|
||||||
if (errno != 0 || addressEnd == address || parsedAddress == 0) {
|
if (errno != 0 || addressEnd == address || parsedAddress == 0) {
|
||||||
FF_DEBUG("Failed to parse OpenBSD SMBIOS table address from line: %.*s",
|
FF_DEBUG("Failed to parse OpenBSD SMBIOS table address from line: %.*s",
|
||||||
@@ -541,7 +541,7 @@ static bool fillTableBufferPlatform(FFstrbuf* buffer) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
off_t entryAddress = (off_t) strtol(strEntryAddress.chars, NULL, 16);
|
off_t entryAddress = (off_t) strtol(strEntryAddress.chars, nullptr, 16);
|
||||||
if (entryAddress == 0) {
|
if (entryAddress == 0) {
|
||||||
FF_DEBUG("Invalid SMBIOS entry address: 0");
|
FF_DEBUG("Invalid SMBIOS entry address: 0");
|
||||||
return false;
|
return false;
|
||||||
@@ -671,7 +671,7 @@ const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable() {
|
|||||||
if (!fillTableBufferFallback(&buffer)) {
|
if (!fillTableBufferFallback(&buffer)) {
|
||||||
FF_DEBUG("Fallback SMBIOS retrieval also failed");
|
FF_DEBUG("Fallback SMBIOS retrieval also failed");
|
||||||
ffStrbufDestroy(&buffer);
|
ffStrbufDestroy(&buffer);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -682,7 +682,7 @@ const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable() {
|
|||||||
|
|
||||||
if (buffer.length == 0) {
|
if (buffer.length == 0) {
|
||||||
FF_DEBUG("No valid SMBIOS data available");
|
FF_DEBUG("No valid SMBIOS data available");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &smbiosTable;
|
return &smbiosTable;
|
||||||
@@ -717,13 +717,13 @@ const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable() {
|
|||||||
NtQuerySystemInformation(SystemFirmwareTableInformation, &sfti, sizeof(sfti), &bufSize);
|
NtQuerySystemInformation(SystemFirmwareTableInformation, &sfti, sizeof(sfti), &bufSize);
|
||||||
if (bufSize <= sizeof(FFRawSmbiosData) + sizeof(sfti)) {
|
if (bufSize <= sizeof(FFRawSmbiosData) + sizeof(sfti)) {
|
||||||
FF_DEBUG("Invalid firmware table size: %lu (must be > %zu)", bufSize, sizeof(FFRawSmbiosData) + sizeof(sfti));
|
FF_DEBUG("Invalid firmware table size: %lu (must be > %zu)", bufSize, sizeof(FFRawSmbiosData) + sizeof(sfti));
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (bufSize != sfti.TableBufferLength + (ULONG) sizeof(sfti)) {
|
if (bufSize != sfti.TableBufferLength + (ULONG) sizeof(sfti)) {
|
||||||
FF_DEBUG("Firmware table size mismatch: NtQuerySystemInformation returned %lu but expected %lu",
|
FF_DEBUG("Firmware table size mismatch: NtQuerySystemInformation returned %lu but expected %lu",
|
||||||
bufSize,
|
bufSize,
|
||||||
sfti.TableBufferLength + (ULONG) sizeof(sfti));
|
sfti.TableBufferLength + (ULONG) sizeof(sfti));
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
FF_DEBUG("Firmware table size: %lu bytes", bufSize);
|
FF_DEBUG("Firmware table size: %lu bytes", bufSize);
|
||||||
|
|
||||||
@@ -734,8 +734,8 @@ const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable() {
|
|||||||
if (!NT_SUCCESS(NtQuerySystemInformation(SystemFirmwareTableInformation, buffer, bufSize, &bufSize))) {
|
if (!NT_SUCCESS(NtQuerySystemInformation(SystemFirmwareTableInformation, buffer, bufSize, &bufSize))) {
|
||||||
FF_DEBUG("NtQuerySystemInformation(SystemFirmwareTableInformation) failed");
|
FF_DEBUG("NtQuerySystemInformation(SystemFirmwareTableInformation) failed");
|
||||||
free(buffer);
|
free(buffer);
|
||||||
buffer = NULL;
|
buffer = nullptr;
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
FFRawSmbiosData* rawData = (FFRawSmbiosData*) buffer->TableBuffer;
|
FFRawSmbiosData* rawData = (FFRawSmbiosData*) buffer->TableBuffer;
|
||||||
|
|
||||||
@@ -746,14 +746,14 @@ const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable() {
|
|||||||
|
|
||||||
if (!parseSmbiosTable(rawData->SMBIOSTableData, rawData->Length)) {
|
if (!parseSmbiosTable(rawData->SMBIOSTableData, rawData->Length)) {
|
||||||
free(buffer);
|
free(buffer);
|
||||||
buffer = NULL;
|
buffer = nullptr;
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
FF_DEBUG("No valid SMBIOS data available");
|
FF_DEBUG("No valid SMBIOS data available");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return &smbiosTable;
|
return &smbiosTable;
|
||||||
}
|
}
|
||||||
@@ -771,33 +771,33 @@ const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable() {
|
|||||||
|
|
||||||
if (!registryEntry) {
|
if (!registryEntry) {
|
||||||
FF_DEBUG("IOServiceGetMatchingService() failed to find AppleSMBIOS");
|
FF_DEBUG("IOServiceGetMatchingService() failed to find AppleSMBIOS");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_DEBUG("AppleSMBIOS service found, retrieving SMBIOS data");
|
FF_DEBUG("AppleSMBIOS service found, retrieving SMBIOS data");
|
||||||
smbiosDataBuffer = IORegistryEntryCreateCFProperty(registryEntry, CFSTR("SMBIOS"), kCFAllocatorDefault, kNilOptions);
|
smbiosDataBuffer = IORegistryEntryCreateCFProperty(registryEntry, CFSTR("SMBIOS"), kCFAllocatorDefault, kNilOptions);
|
||||||
if (!smbiosDataBuffer) {
|
if (!smbiosDataBuffer) {
|
||||||
FF_DEBUG("IORegistryEntryCreateCFProperty() failed to get SMBIOS data");
|
FF_DEBUG("IORegistryEntryCreateCFProperty() failed to get SMBIOS data");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (CFGetTypeID(smbiosDataBuffer) != CFDataGetTypeID()) {
|
if (CFGetTypeID(smbiosDataBuffer) != CFDataGetTypeID()) {
|
||||||
FF_DEBUG("Unexpected SMBIOS data type: expected CFData");
|
FF_DEBUG("Unexpected SMBIOS data type: expected CFData");
|
||||||
CFRelease(smbiosDataBuffer);
|
CFRelease(smbiosDataBuffer);
|
||||||
smbiosDataBuffer = NULL;
|
smbiosDataBuffer = nullptr;
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_DEBUG("Successfully retrieved SMBIOS data: %lu bytes", CFDataGetLength(smbiosDataBuffer));
|
FF_DEBUG("Successfully retrieved SMBIOS data: %lu bytes", CFDataGetLength(smbiosDataBuffer));
|
||||||
if (!parseSmbiosTable((const uint8_t*) CFDataGetBytePtr(smbiosDataBuffer), (uint32_t) CFDataGetLength(smbiosDataBuffer))) {
|
if (!parseSmbiosTable((const uint8_t*) CFDataGetBytePtr(smbiosDataBuffer), (uint32_t) CFDataGetLength(smbiosDataBuffer))) {
|
||||||
CFRelease(smbiosDataBuffer);
|
CFRelease(smbiosDataBuffer);
|
||||||
smbiosDataBuffer = NULL;
|
smbiosDataBuffer = nullptr;
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!smbiosDataBuffer) {
|
if (!smbiosDataBuffer) {
|
||||||
FF_DEBUG("No valid SMBIOS data available");
|
FF_DEBUG("No valid SMBIOS data available");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &smbiosTable;
|
return &smbiosTable;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "common/strutil.h"
|
#include "common/strutil.h"
|
||||||
|
#include "common/wcwidth.h"
|
||||||
|
|
||||||
uint8_t ffUtf8CharLenWidth(const char* str, uint32_t length, uint8_t* width) {
|
uint8_t ffUtf8CharLenWidth(const char* str, uint32_t length, uint8_t* width) {
|
||||||
if (__builtin_expect(length == 0 || *str == '\0', false)) {
|
if (__builtin_expect(length == 0 || *str == '\0', false)) {
|
||||||
|
|||||||
+14
-14
@@ -5,26 +5,26 @@
|
|||||||
#ifdef __OpenBSD__
|
#ifdef __OpenBSD__
|
||||||
const char* ffSysctlGetString(int mib1, int mib2, FFstrbuf* result) {
|
const char* ffSysctlGetString(int mib1, int mib2, FFstrbuf* result) {
|
||||||
size_t neededLength;
|
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
|
if (sysctl((int[]) { mib1, mib2 }, 2, nullptr, &neededLength, nullptr, 0) != 0 || neededLength == 1) { // neededLength is 1 for empty strings, because of the null terminator
|
||||||
return "sysctl() length query failed";
|
return "sysctl() length query failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
ffStrbufEnsureFree(result, (uint32_t) neededLength - 1);
|
ffStrbufEnsureFree(result, (uint32_t) neededLength - 1);
|
||||||
|
|
||||||
if (sysctl((int[]) { mib1, mib2 }, 2, result->chars + result->length, &neededLength, NULL, 0) != 0) {
|
if (sysctl((int[]) { mib1, mib2 }, 2, result->chars + result->length, &neededLength, nullptr, 0) != 0) {
|
||||||
return "sysctl() failed to retrieve string data";
|
return "sysctl() failed to retrieve string data";
|
||||||
}
|
}
|
||||||
|
|
||||||
result->length += (uint32_t) neededLength - 1;
|
result->length += (uint32_t) neededLength - 1;
|
||||||
result->chars[result->length] = '\0';
|
result->chars[result->length] = '\0';
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ffSysctlGetInt(int mib1, int mib2, int defaultValue) {
|
int ffSysctlGetInt(int mib1, int mib2, int defaultValue) {
|
||||||
int result;
|
int result;
|
||||||
size_t neededLength = sizeof(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, nullptr, 0) != 0) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -33,7 +33,7 @@ int ffSysctlGetInt(int mib1, int mib2, int defaultValue) {
|
|||||||
int64_t ffSysctlGetInt64(int mib1, int mib2, int64_t defaultValue) {
|
int64_t ffSysctlGetInt64(int mib1, int mib2, int64_t defaultValue) {
|
||||||
int64_t result;
|
int64_t result;
|
||||||
size_t neededLength = sizeof(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, nullptr, 0) != 0) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -41,13 +41,13 @@ int64_t ffSysctlGetInt64(int mib1, int mib2, int64_t defaultValue) {
|
|||||||
#else
|
#else
|
||||||
const char* ffSysctlGetString(const char* propName, FFstrbuf* result) {
|
const char* ffSysctlGetString(const char* propName, FFstrbuf* result) {
|
||||||
size_t neededLength;
|
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, nullptr, &neededLength, nullptr, 0) != 0 || neededLength == 1) { // neededLength is 1 for empty strings, because of the null terminator
|
||||||
return "sysctlbyname() failed";
|
return "sysctlbyname() failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
ffStrbufEnsureFree(result, (uint32_t) neededLength - 1);
|
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, nullptr, 0) != 0) {
|
||||||
return "sysctlbyname() failed to retrieve string data";
|
return "sysctlbyname() failed to retrieve string data";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,13 +55,13 @@ const char* ffSysctlGetString(const char* propName, FFstrbuf* result) {
|
|||||||
|
|
||||||
result->chars[result->length] = '\0';
|
result->chars[result->length] = '\0';
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ffSysctlGetInt(const char* propName, int defaultValue) {
|
int ffSysctlGetInt(const char* propName, int defaultValue) {
|
||||||
int result;
|
int result;
|
||||||
size_t neededLength = sizeof(result);
|
size_t neededLength = sizeof(result);
|
||||||
if (sysctlbyname(propName, &result, &neededLength, NULL, 0) != 0) {
|
if (sysctlbyname(propName, &result, &neededLength, nullptr, 0) != 0) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -70,7 +70,7 @@ int ffSysctlGetInt(const char* propName, int defaultValue) {
|
|||||||
int64_t ffSysctlGetInt64(const char* propName, int64_t defaultValue) {
|
int64_t ffSysctlGetInt64(const char* propName, int64_t defaultValue) {
|
||||||
int64_t result;
|
int64_t result;
|
||||||
size_t neededLength = sizeof(result);
|
size_t neededLength = sizeof(result);
|
||||||
if (sysctlbyname(propName, &result, &neededLength, NULL, 0) != 0) {
|
if (sysctlbyname(propName, &result, &neededLength, nullptr, 0) != 0) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -78,15 +78,15 @@ int64_t ffSysctlGetInt64(const char* propName, int64_t defaultValue) {
|
|||||||
#endif // OpenBSD
|
#endif // OpenBSD
|
||||||
|
|
||||||
void* ffSysctlGetData(int* request, u_int requestLength, size_t* resultLength) {
|
void* ffSysctlGetData(int* request, u_int requestLength, size_t* resultLength) {
|
||||||
if (sysctl(request, requestLength, NULL, resultLength, NULL, 0) != 0) {
|
if (sysctl(request, requestLength, nullptr, resultLength, nullptr, 0) != 0) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* data = malloc(*resultLength);
|
void* data = malloc(*resultLength);
|
||||||
|
|
||||||
if (sysctl(request, requestLength, data, resultLength, NULL, 0) != 0) {
|
if (sysctl(request, requestLength, data, resultLength, nullptr, 0) != 0) {
|
||||||
free(data);
|
free(data);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user