mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
Compare commits
68 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 163781557f | |||
| 16e6decebf | |||
| e10c9cc164 | |||
| 7ef994d0cf | |||
| 019c9f0f77 | |||
| 5fec607ebe | |||
| b065b3da51 | |||
| 1337525eb5 | |||
| 30ea52938e | |||
| d43ed33661 | |||
| 03aab33507 | |||
| 420d1cf804 | |||
| 5d901da81b | |||
| 5c783e64c0 | |||
| 2efa5a1869 | |||
| 5bfabe7a52 | |||
| c9c9a58f59 | |||
| 546908fc29 | |||
| 0a17da2da0 | |||
| bc6fd025cb | |||
| 9e49451340 | |||
| 4d185e64ac | |||
| 1fa9a61b3f | |||
| 234552fbf2 | |||
| 8423efb686 | |||
| cd8c15d01e | |||
| 3163cfb1b6 | |||
| 7ae007a1d0 | |||
| 0b52d75415 | |||
| 3a7f4f5848 | |||
| 072f67988f | |||
| c640ddbff7 | |||
| 981ae6bdd1 | |||
| 977e3f317e | |||
| e2ee24598c | |||
| 1be90084ab | |||
| 6ded0f9bb0 | |||
| d60b25e424 | |||
| 874f3918b7 | |||
| 61690a1804 | |||
| 1e43e35857 | |||
| 8c86003220 | |||
| 18c3cd2e66 | |||
| b21f35e914 | |||
| 32e3ed1fda | |||
| 6f87026b0c | |||
| e23edae917 | |||
| bdc867031a | |||
| e96b0f7a73 | |||
| 37fe446a58 | |||
| f03a0bc202 | |||
| bcbc5a4bff | |||
| 0b1e2faba1 | |||
| 4708a5e59c | |||
| 7925469e2f | |||
| 53116d65f1 | |||
| 01917b781b | |||
| d01fc56ea2 | |||
| 9c870a57f0 | |||
| 7e557a06b3 | |||
| fa63038862 | |||
| 8439204cef | |||
| 710df0b87b | |||
| 302f0fc85f | |||
| 241aa3a02c | |||
| a17f3dc3f8 | |||
| 34c0bf58cb | |||
| b64b93fc4a |
+21
-10
@@ -520,12 +520,12 @@ jobs:
|
|||||||
architecture: x86-64
|
architecture: x86-64
|
||||||
cpu_count: 4
|
cpu_count: 4
|
||||||
shell: bash
|
shell: bash
|
||||||
version: '7.7'
|
version: '7.8'
|
||||||
run: |
|
run: |
|
||||||
uname -a
|
uname -a
|
||||||
sudo pkg_add -u
|
sudo pkg_add -u
|
||||||
sudo pkg_add -r llvm-19.1.7p3 cmake git pkgconf wayland vulkan-headers vulkan-loader glib2 dconf dbus sqlite3 imagemagick chafa
|
sudo pkg_add -r llvm-21.1.2p0 cmake git pkgconf wayland vulkan-headers vulkan-loader glib2 dconf dbus sqlite3 imagemagick chafa
|
||||||
CC=clang-19 cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
|
CC=clang-21 cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
|
||||||
cmake --build . --target package --verbose -j4
|
cmake --build . --target package --verbose -j4
|
||||||
./fastfetch --list-features
|
./fastfetch --list-features
|
||||||
time ./fastfetch -c presets/ci.jsonc --stat false
|
time ./fastfetch -c presets/ci.jsonc --stat false
|
||||||
@@ -647,7 +647,7 @@ jobs:
|
|||||||
path: ./fastfetch-*.*
|
path: ./fastfetch-*.*
|
||||||
|
|
||||||
windows-hosts:
|
windows-hosts:
|
||||||
name: Windows-${{ matrix.arch }}
|
name: Windows-${{ matrix.arch }}${{ matrix.win7-compat-postfix }}
|
||||||
runs-on: ${{ matrix.runs-on }}
|
runs-on: ${{ matrix.runs-on }}
|
||||||
permissions:
|
permissions:
|
||||||
security-events: write
|
security-events: write
|
||||||
@@ -660,11 +660,22 @@ jobs:
|
|||||||
msystem: CLANG64
|
msystem: CLANG64
|
||||||
msystem-lower: clang64
|
msystem-lower: clang64
|
||||||
msys-arch: x86_64
|
msys-arch: x86_64
|
||||||
|
win7-compat-flag: OFF
|
||||||
|
win7-compat-postfix: ""
|
||||||
|
- arch: amd64
|
||||||
|
runs-on: windows-latest
|
||||||
|
msystem: CLANG64
|
||||||
|
msystem-lower: clang64
|
||||||
|
msys-arch: x86_64
|
||||||
|
win7-compat-flag: ON
|
||||||
|
win7-compat-postfix: "-win7"
|
||||||
- arch: aarch64
|
- arch: aarch64
|
||||||
runs-on: windows-11-arm
|
runs-on: windows-11-arm
|
||||||
msystem: CLANGARM64
|
msystem: CLANGARM64
|
||||||
msystem-lower: clangarm64
|
msystem-lower: clangarm64
|
||||||
msys-arch: aarch64
|
msys-arch: aarch64
|
||||||
|
win7-compat-flag: OFF
|
||||||
|
win7-compat-postfix: ""
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
shell: msys2 {0}
|
shell: msys2 {0}
|
||||||
@@ -683,7 +694,7 @@ jobs:
|
|||||||
run: uname -a
|
run: uname -a
|
||||||
|
|
||||||
- name: configure project
|
- name: configure project
|
||||||
run: env PKG_CONFIG_PATH=/${{ matrix.msystem-lower }}/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
run: env PKG_CONFIG_PATH=/${{ matrix.msystem-lower }}/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_WIN7_COMPAT=${{ matrix.win7-compat-flag }} .
|
||||||
|
|
||||||
- name: build project
|
- name: build project
|
||||||
run: cmake --build . --verbose -j4
|
run: cmake --build . --verbose -j4
|
||||||
@@ -714,7 +725,7 @@ jobs:
|
|||||||
name: upload artifacts for signing
|
name: upload artifacts for signing
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: fastfetch-windows-${{ matrix.arch }}
|
name: fastfetch-windows-${{ matrix.arch }}${{ matrix.win7-compat-postfix }}
|
||||||
path: |
|
path: |
|
||||||
*.dll
|
*.dll
|
||||||
fastfetch.exe
|
fastfetch.exe
|
||||||
@@ -733,16 +744,16 @@ jobs:
|
|||||||
output-artifact-directory: '.'
|
output-artifact-directory: '.'
|
||||||
|
|
||||||
- name: create zip archive
|
- name: create zip archive
|
||||||
run: 7z a -tzip -mx9 -bd -y fastfetch-windows-${{ matrix.arch }}.zip LICENSE *.dll fastfetch.exe flashfetch.exe presets
|
run: 7z a -tzip -mx9 -bd -y fastfetch-windows-${{ matrix.arch }}${{ matrix.win7-compat-postfix }}.zip LICENSE *.dll fastfetch.exe flashfetch.exe presets
|
||||||
|
|
||||||
- name: create 7z archive
|
- name: create 7z archive
|
||||||
run: 7z a -t7z -mx9 -bd -y fastfetch-windows-${{ matrix.arch }}.7z LICENSE *.dll fastfetch.exe flashfetch.exe presets
|
run: 7z a -t7z -mx9 -bd -y fastfetch-windows-${{ matrix.arch }}${{ matrix.win7-compat-postfix }}.7z LICENSE *.dll fastfetch.exe flashfetch.exe presets
|
||||||
|
|
||||||
- name: upload true artifacts
|
- name: upload true artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: fastfetch-windows-${{ matrix.arch }}
|
name: fastfetch-windows-${{ matrix.arch }}${{ matrix.win7-compat-postfix }}
|
||||||
path: ./fastfetch-windows-${{ matrix.arch }}.*
|
path: ./fastfetch-windows-${{ matrix.arch }}${{ matrix.win7-compat-postfix }}.*
|
||||||
overwrite: true
|
overwrite: true
|
||||||
|
|
||||||
release:
|
release:
|
||||||
|
|||||||
@@ -1,3 +1,42 @@
|
|||||||
|
# 2.57.0
|
||||||
|
|
||||||
|
Deprecation notice:
|
||||||
|
* Support for Windows 7 (and 8.x) is deprecated and will be removed in a future release. Extended support for Windows 7 (and 8.1) ended on January 10, 2023. These versions do not officially support ANSI escape codes (running fastfetch on them requires a third-party terminal such as ConEmu). In addition, Windows 7 lacks some APIs used by fastfetch. Fastfetch currently loads these APIs dynamically at runtime to maintain compatibility, but this adds complexity to the codebase and increases the maintenance burden.
|
||||||
|
* A CMake flag `ENABLE_WIN7_COMPAT:BOOLEAN` has been introduced (defaults to `ON` for now). If set to `OFF`, Windows 7 compatibility code is excluded, and the resulting binaries will support only Windows 10 (version 1607 and later) and Windows 11.
|
||||||
|
* The main prebuilt Windows binaries on the Release page (`fastfetch-windows-amd64.*`) are built with `ENABLE_WIN7_COMPAT=OFF`. These are the binaries used by `scoop` and `winget`. Users who need Windows 7 (or 8.x) support can download the `-win7` variant instead.
|
||||||
|
* The `ENABLE_WIN7_COMPAT` CMake option and the `-win7` variant binaries are planned to be removed in 2.60.0.
|
||||||
|
|
||||||
|
Features:
|
||||||
|
* Supports COSMIC DE version detection (DE, Linux)
|
||||||
|
* Supports niri version detection (#2121, WM, Linux)
|
||||||
|
* Supports cosmic-term version and terminal font detection (Terminal / TerminalFont, Linux)
|
||||||
|
* Supports urxvt font detection (TerminalFont, Linux) (#2105)
|
||||||
|
* Improves xterm font detection by checking `xterm.vt100.faceName` (TerminalFont, Linux)
|
||||||
|
* Supports Secure Boot detection (Bootmgr, macOS)
|
||||||
|
* Supports DPI scale factor detection on Windows 7 (Display, Windows)
|
||||||
|
* Supports xterm 256-color codes in color configuration
|
||||||
|
* In `display.color`: "@<color-index>" (e.g., "@34" for color index 34)
|
||||||
|
* In `*.format` strings: "#@<color-index>" (e.g., "#@34" for color index 34)
|
||||||
|
* Improves uptime accuracy on Windows 10+ (Uptime, Windows)
|
||||||
|
* Adds a new module `Logo` to query built-in logo raw data in JSON output (Logo)
|
||||||
|
* Usage: `fastfetch -s logo -l <logo-name> -j # Supported in JSON format only`
|
||||||
|
* Supports shell version detection even if the binary has been deleted (#2136, Shell, Linux)
|
||||||
|
* Overall code refinements and optimizations
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
* Skips local / loopback routes when detecting network interfaces (LocalIP, Linux) (#2127)
|
||||||
|
* Fixes CPU speed detection on s390x (CPU, Linux) (#2129)
|
||||||
|
* Fixes GPU detection error handling and supports case-insensitive PCI ID parsing (GPU, Windows)
|
||||||
|
* Fixes some networking issues and memory leaks (Networking)
|
||||||
|
* Fixes `exePath` reporting relative paths on macOS (Shell, macOS)
|
||||||
|
|
||||||
|
Logos:
|
||||||
|
* Adds openSUSE Tumbleweed braille logo
|
||||||
|
* Adds Xinux
|
||||||
|
* Renames HydraPWK to NetHydra
|
||||||
|
* Fixes colors of deepin and UOS
|
||||||
|
* Fixes colors of macOS and variants
|
||||||
|
|
||||||
# 2.56.1
|
# 2.56.1
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
|
|||||||
+154
-123
@@ -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.56.1
|
VERSION 2.57.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"
|
||||||
@@ -107,6 +107,9 @@ option(ENABLE_EMBEDDED_PCIIDS "Embed pci.ids into fastfetch, requires `python`"
|
|||||||
option(ENABLE_EMBEDDED_AMDGPUIDS "Embed amdgpu.ids into fastfetch, requires `python`" OFF)
|
option(ENABLE_EMBEDDED_AMDGPUIDS "Embed amdgpu.ids into fastfetch, requires `python`" OFF)
|
||||||
option(ENABLE_WORDEXP "Enable using of wordexp(3) if available, instead of glob(3)" ON)
|
option(ENABLE_WORDEXP "Enable using of wordexp(3) if available, instead of glob(3)" ON)
|
||||||
option(ENABLE_LIBZFS "Enable libzfs" ON)
|
option(ENABLE_LIBZFS "Enable libzfs" ON)
|
||||||
|
if(WIN32 AND NOT CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
|
||||||
|
option(ENABLE_WIN7_COMPAT "Enable Windows 7 compatibility" ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
set(BINARY_LINK_TYPE_OPTIONS dlopen dynamic static)
|
set(BINARY_LINK_TYPE_OPTIONS dlopen dynamic static)
|
||||||
set(BINARY_LINK_TYPE dlopen CACHE STRING "How to link fastfetch")
|
set(BINARY_LINK_TYPE dlopen CACHE STRING "How to link fastfetch")
|
||||||
@@ -161,7 +164,13 @@ if(WIN32 OR Haiku OR ENABLE_DIRECTX_HEADERS)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--tsaware -Wl,--build-id -Wl,--subsystem,console:6.1,--major-os-version,6,--minor-os-version,1")
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--tsaware -Wl,--build-id")
|
||||||
|
|
||||||
|
if(ENABLE_WIN7_COMPAT)
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--subsystem,console,--major-os-version,6,--minor-os-version,1")
|
||||||
|
else()
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--subsystem,console,--major-os-version,10,--minor-os-version,0")
|
||||||
|
endif()
|
||||||
elseif(APPLE AND CMAKE_C_COMPILER_ID MATCHES "Clang")
|
elseif(APPLE AND CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fobjc-arc")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fobjc-arc")
|
||||||
endif()
|
endif()
|
||||||
@@ -342,7 +351,7 @@ fastfetch_load_text(src/data/structure.txt DATATEXT_STRUCTURE)
|
|||||||
configure_file(src/fastfetch_config.h.in fastfetch_config.h @ONLY)
|
configure_file(src/fastfetch_config.h.in fastfetch_config.h @ONLY)
|
||||||
configure_file(src/fastfetch_datatext.h.in fastfetch_datatext.h @ONLY)
|
configure_file(src/fastfetch_datatext.h.in fastfetch_datatext.h @ONLY)
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
configure_file(src/util/apple/Info.plist.in Info.plist @ONLY)
|
configure_file(src/common/apple/Info.plist.in Info.plist @ONLY)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
####################
|
####################
|
||||||
@@ -364,26 +373,33 @@ file(GENERATE OUTPUT logo_builtin.h CONTENT "${LOGO_BUILTIN_H}")
|
|||||||
#######################
|
#######################
|
||||||
|
|
||||||
set(LIBFASTFETCH_SRC
|
set(LIBFASTFETCH_SRC
|
||||||
src/common/commandoption.c
|
src/common/impl/commandoption.c
|
||||||
src/common/duration.c
|
src/common/impl/duration.c
|
||||||
src/common/font.c
|
src/common/impl/font.c
|
||||||
src/common/format.c
|
src/common/impl/format.c
|
||||||
src/common/frequency.c
|
src/common/impl/frequency.c
|
||||||
src/common/init.c
|
src/common/impl/init.c
|
||||||
src/common/jsonconfig.c
|
src/common/impl/jsonconfig.c
|
||||||
src/common/library.c
|
src/common/impl/library.c
|
||||||
src/common/modules.c
|
src/common/impl/netif.c
|
||||||
src/common/netif/netif.c
|
src/common/impl/networking_common.c
|
||||||
src/common/networking/networking_common.c
|
src/common/impl/option.c
|
||||||
src/common/option.c
|
src/common/impl/parsing.c
|
||||||
src/common/parsing.c
|
src/common/impl/percent.c
|
||||||
src/common/percent.c
|
src/common/impl/printing.c
|
||||||
src/common/printing.c
|
src/common/impl/properties.c
|
||||||
src/common/properties.c
|
src/common/impl/settings.c
|
||||||
src/common/settings.c
|
src/common/impl/size.c
|
||||||
src/common/size.c
|
src/common/impl/temps.c
|
||||||
src/common/temps.c
|
src/common/impl/time.c
|
||||||
src/common/time.c
|
src/common/impl/edidHelper.c
|
||||||
|
src/common/impl/base64.c
|
||||||
|
src/common/impl/FFlist.c
|
||||||
|
src/common/impl/FFstrbuf.c
|
||||||
|
src/common/impl/kmod.c
|
||||||
|
src/common/impl/path.c
|
||||||
|
src/common/impl/FFPlatform.c
|
||||||
|
src/common/impl/smbiosHelper.c
|
||||||
src/detection/bluetoothradio/bluetoothradio.c
|
src/detection/bluetoothradio/bluetoothradio.c
|
||||||
src/detection/bootmgr/bootmgr.c
|
src/detection/bootmgr/bootmgr.c
|
||||||
src/detection/chassis/chassis.c
|
src/detection/chassis/chassis.c
|
||||||
@@ -452,6 +468,7 @@ set(LIBFASTFETCH_SRC
|
|||||||
src/modules/loadavg/loadavg.c
|
src/modules/loadavg/loadavg.c
|
||||||
src/modules/locale/locale.c
|
src/modules/locale/locale.c
|
||||||
src/modules/localip/localip.c
|
src/modules/localip/localip.c
|
||||||
|
src/modules/logo/logo.c
|
||||||
src/modules/memory/memory.c
|
src/modules/memory/memory.c
|
||||||
src/modules/monitor/monitor.c
|
src/modules/monitor/monitor.c
|
||||||
src/modules/netio/netio.c
|
src/modules/netio/netio.c
|
||||||
@@ -489,26 +506,21 @@ set(LIBFASTFETCH_SRC
|
|||||||
src/modules/wm/wm.c
|
src/modules/wm/wm.c
|
||||||
src/modules/wmtheme/wmtheme.c
|
src/modules/wmtheme/wmtheme.c
|
||||||
src/modules/zpool/zpool.c
|
src/modules/zpool/zpool.c
|
||||||
|
src/modules/modules.c
|
||||||
src/options/display.c
|
src/options/display.c
|
||||||
src/options/logo.c
|
src/options/logo.c
|
||||||
src/options/general.c
|
src/options/general.c
|
||||||
src/util/edidHelper.c
|
|
||||||
src/util/base64.c
|
|
||||||
src/util/FFlist.c
|
|
||||||
src/util/FFstrbuf.c
|
|
||||||
src/util/kmod.c
|
|
||||||
src/util/path.c
|
|
||||||
src/util/platform/FFPlatform.c
|
|
||||||
src/util/smbiosHelper.c
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if(LINUX)
|
if(LINUX)
|
||||||
list(APPEND LIBFASTFETCH_SRC
|
list(APPEND LIBFASTFETCH_SRC
|
||||||
src/common/dbus.c
|
src/common/impl/dbus.c
|
||||||
src/common/io/io_unix.c
|
src/common/impl/io_unix.c
|
||||||
src/common/netif/netif_linux.c
|
src/common/impl/netif_linux.c
|
||||||
src/common/networking/networking_linux.c
|
src/common/impl/networking_linux.c
|
||||||
src/common/processing_linux.c
|
src/common/impl/processing_linux.c
|
||||||
|
src/common/impl/FFPlatform_unix.c
|
||||||
|
src/common/impl/binary_linux.c
|
||||||
src/detection/battery/battery_linux.c
|
src/detection/battery/battery_linux.c
|
||||||
src/detection/bios/bios_linux.c
|
src/detection/bios/bios_linux.c
|
||||||
src/detection/board/board_linux.c
|
src/detection/board/board_linux.c
|
||||||
@@ -583,16 +595,16 @@ if(LINUX)
|
|||||||
src/detection/de/de_linux.c
|
src/detection/de/de_linux.c
|
||||||
src/detection/wmtheme/wmtheme_linux.c
|
src/detection/wmtheme/wmtheme_linux.c
|
||||||
src/detection/camera/camera_linux.c
|
src/detection/camera/camera_linux.c
|
||||||
src/util/platform/FFPlatform_unix.c
|
|
||||||
src/util/binary_linux.c
|
|
||||||
)
|
)
|
||||||
elseif(ANDROID)
|
elseif(ANDROID)
|
||||||
list(APPEND LIBFASTFETCH_SRC
|
list(APPEND LIBFASTFETCH_SRC
|
||||||
src/common/dbus.c
|
src/common/impl/dbus.c
|
||||||
src/common/io/io_unix.c
|
src/common/impl/io_unix.c
|
||||||
src/common/netif/netif_linux.c
|
src/common/impl/netif_linux.c
|
||||||
src/common/networking/networking_linux.c
|
src/common/impl/networking_linux.c
|
||||||
src/common/processing_linux.c
|
src/common/impl/processing_linux.c
|
||||||
|
src/common/impl/FFPlatform_unix.c
|
||||||
|
src/common/impl/binary_linux.c
|
||||||
src/detection/battery/battery_android.c
|
src/detection/battery/battery_android.c
|
||||||
src/detection/bios/bios_android.c
|
src/detection/bios/bios_android.c
|
||||||
src/detection/bluetooth/bluetooth_nosupport.c
|
src/detection/bluetooth/bluetooth_nosupport.c
|
||||||
@@ -656,17 +668,17 @@ elseif(ANDROID)
|
|||||||
src/detection/de/de_linux.c
|
src/detection/de/de_linux.c
|
||||||
src/detection/wmtheme/wmtheme_linux.c
|
src/detection/wmtheme/wmtheme_linux.c
|
||||||
src/detection/camera/camera_android.c
|
src/detection/camera/camera_android.c
|
||||||
src/util/platform/FFPlatform_unix.c
|
|
||||||
src/util/binary_linux.c
|
|
||||||
)
|
)
|
||||||
elseif(FreeBSD)
|
elseif(FreeBSD)
|
||||||
list(APPEND LIBFASTFETCH_SRC
|
list(APPEND LIBFASTFETCH_SRC
|
||||||
src/common/dbus.c
|
src/common/impl/dbus.c
|
||||||
src/common/io/io_unix.c
|
src/common/impl/io_unix.c
|
||||||
src/common/netif/netif_bsd.c
|
src/common/impl/netif_bsd.c
|
||||||
src/common/networking/networking_linux.c
|
src/common/impl/networking_linux.c
|
||||||
src/common/processing_linux.c
|
src/common/impl/processing_linux.c
|
||||||
src/common/sysctl.c
|
src/common/impl/sysctl.c
|
||||||
|
src/common/impl/FFPlatform_unix.c
|
||||||
|
src/common/impl/binary_linux.c
|
||||||
src/detection/battery/battery_bsd.c
|
src/detection/battery/battery_bsd.c
|
||||||
src/detection/bios/bios_bsd.c
|
src/detection/bios/bios_bsd.c
|
||||||
src/detection/bluetoothradio/bluetoothradio_nosupport.c
|
src/detection/bluetoothradio/bluetoothradio_nosupport.c
|
||||||
@@ -738,8 +750,6 @@ elseif(FreeBSD)
|
|||||||
src/detection/de/de_linux.c
|
src/detection/de/de_linux.c
|
||||||
src/detection/wmtheme/wmtheme_linux.c
|
src/detection/wmtheme/wmtheme_linux.c
|
||||||
src/detection/camera/camera_linux.c
|
src/detection/camera/camera_linux.c
|
||||||
src/util/platform/FFPlatform_unix.c
|
|
||||||
src/util/binary_linux.c
|
|
||||||
)
|
)
|
||||||
if(DragonFly)
|
if(DragonFly)
|
||||||
list(APPEND LIBFASTFETCH_SRC
|
list(APPEND LIBFASTFETCH_SRC
|
||||||
@@ -754,12 +764,14 @@ elseif(FreeBSD)
|
|||||||
endif()
|
endif()
|
||||||
elseif(NetBSD)
|
elseif(NetBSD)
|
||||||
list(APPEND LIBFASTFETCH_SRC
|
list(APPEND LIBFASTFETCH_SRC
|
||||||
src/common/dbus.c
|
src/common/impl/dbus.c
|
||||||
src/common/io/io_unix.c
|
src/common/impl/io_unix.c
|
||||||
src/common/netif/netif_bsd.c
|
src/common/impl/netif_bsd.c
|
||||||
src/common/networking/networking_linux.c
|
src/common/impl/networking_linux.c
|
||||||
src/common/processing_linux.c
|
src/common/impl/processing_linux.c
|
||||||
src/common/sysctl.c
|
src/common/impl/sysctl.c
|
||||||
|
src/common/impl/FFPlatform_unix.c
|
||||||
|
src/common/impl/binary_linux.c
|
||||||
src/detection/battery/battery_nbsd.c
|
src/detection/battery/battery_nbsd.c
|
||||||
src/detection/bios/bios_nbsd.c
|
src/detection/bios/bios_nbsd.c
|
||||||
src/detection/bluetooth/bluetooth_bsd.c
|
src/detection/bluetooth/bluetooth_bsd.c
|
||||||
@@ -831,17 +843,18 @@ elseif(NetBSD)
|
|||||||
src/detection/de/de_linux.c
|
src/detection/de/de_linux.c
|
||||||
src/detection/wmtheme/wmtheme_linux.c
|
src/detection/wmtheme/wmtheme_linux.c
|
||||||
src/detection/camera/camera_linux.c
|
src/detection/camera/camera_linux.c
|
||||||
src/util/platform/FFPlatform_unix.c
|
|
||||||
src/util/binary_linux.c
|
|
||||||
)
|
)
|
||||||
elseif(OpenBSD)
|
elseif(OpenBSD)
|
||||||
list(APPEND LIBFASTFETCH_SRC
|
list(APPEND LIBFASTFETCH_SRC
|
||||||
src/common/dbus.c
|
src/common/impl/dbus.c
|
||||||
src/common/io/io_unix.c
|
src/common/impl/io_unix.c
|
||||||
src/common/netif/netif_bsd.c
|
src/common/impl/netif_bsd.c
|
||||||
src/common/networking/networking_linux.c
|
src/common/impl/networking_linux.c
|
||||||
src/common/processing_linux.c
|
src/common/impl/processing_linux.c
|
||||||
src/common/sysctl.c
|
src/common/impl/sysctl.c
|
||||||
|
src/common/impl/FFPlatform_unix.c
|
||||||
|
src/common/impl/binary_linux.c
|
||||||
|
src/common/impl/smbiosHelper.c
|
||||||
src/detection/battery/battery_obsd.c
|
src/detection/battery/battery_obsd.c
|
||||||
src/detection/bios/bios_windows.c
|
src/detection/bios/bios_windows.c
|
||||||
src/detection/bluetooth/bluetooth_nosupport.c
|
src/detection/bluetooth/bluetooth_nosupport.c
|
||||||
@@ -913,17 +926,19 @@ elseif(OpenBSD)
|
|||||||
src/detection/de/de_linux.c
|
src/detection/de/de_linux.c
|
||||||
src/detection/wmtheme/wmtheme_linux.c
|
src/detection/wmtheme/wmtheme_linux.c
|
||||||
src/detection/camera/camera_linux.c
|
src/detection/camera/camera_linux.c
|
||||||
src/util/platform/FFPlatform_unix.c
|
|
||||||
src/util/binary_linux.c
|
|
||||||
src/util/smbiosHelper.c
|
|
||||||
)
|
)
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
list(APPEND LIBFASTFETCH_SRC
|
list(APPEND LIBFASTFETCH_SRC
|
||||||
src/common/io/io_unix.c
|
src/common/impl/io_unix.c
|
||||||
src/common/netif/netif_apple.c
|
src/common/impl/netif_apple.c
|
||||||
src/common/networking/networking_linux.c
|
src/common/impl/networking_linux.c
|
||||||
src/common/processing_linux.c
|
src/common/impl/processing_linux.c
|
||||||
src/common/sysctl.c
|
src/common/impl/sysctl.c
|
||||||
|
src/common/impl/FFPlatform_unix.c
|
||||||
|
src/common/impl/binary_apple.c
|
||||||
|
src/common/apple/cf_helpers.c
|
||||||
|
src/common/apple/osascript.m
|
||||||
|
src/common/apple/smc_temps.c
|
||||||
src/detection/battery/battery_apple.c
|
src/detection/battery/battery_apple.c
|
||||||
src/detection/bios/bios_apple.c
|
src/detection/bios/bios_apple.c
|
||||||
src/detection/bluetooth/bluetooth_apple.m
|
src/detection/bluetooth/bluetooth_apple.m
|
||||||
@@ -982,18 +997,22 @@ elseif(APPLE)
|
|||||||
src/detection/de/de_nosupport.c
|
src/detection/de/de_nosupport.c
|
||||||
src/detection/wmtheme/wmtheme_apple.m
|
src/detection/wmtheme/wmtheme_apple.m
|
||||||
src/detection/camera/camera_apple.m
|
src/detection/camera/camera_apple.m
|
||||||
src/util/apple/cf_helpers.c
|
|
||||||
src/util/apple/osascript.m
|
|
||||||
src/util/apple/smc_temps.c
|
|
||||||
src/util/platform/FFPlatform_unix.c
|
|
||||||
src/util/binary_apple.c
|
|
||||||
)
|
)
|
||||||
elseif(WIN32)
|
elseif(WIN32)
|
||||||
list(APPEND LIBFASTFETCH_SRC
|
list(APPEND LIBFASTFETCH_SRC
|
||||||
src/common/io/io_windows.c
|
src/common/impl/io_windows.c
|
||||||
src/common/netif/netif_windows.c
|
src/common/impl/netif_windows.c
|
||||||
src/common/networking/networking_windows.c
|
src/common/impl/networking_windows.c
|
||||||
src/common/processing_windows.c
|
src/common/impl/processing_windows.c
|
||||||
|
src/common/impl/FFPlatform_windows.c
|
||||||
|
src/common/impl/binary_windows.c
|
||||||
|
src/common/impl/debug_windows.c
|
||||||
|
src/common/windows/getline.c
|
||||||
|
src/common/windows/com.cpp
|
||||||
|
src/common/windows/registry.c
|
||||||
|
src/common/windows/unicode.c
|
||||||
|
src/common/windows/wmi.cpp
|
||||||
|
src/common/windows/version.c
|
||||||
src/detection/battery/battery_windows.c
|
src/detection/battery/battery_windows.c
|
||||||
src/detection/bios/bios_windows.c
|
src/detection/bios/bios_windows.c
|
||||||
src/detection/bluetooth/bluetooth_windows.c
|
src/detection/bluetooth/bluetooth_windows.c
|
||||||
@@ -1051,23 +1070,16 @@ elseif(WIN32)
|
|||||||
src/detection/de/de_nosupport.c
|
src/detection/de/de_nosupport.c
|
||||||
src/detection/wmtheme/wmtheme_windows.c
|
src/detection/wmtheme/wmtheme_windows.c
|
||||||
src/detection/camera/camera_windows.cpp
|
src/detection/camera/camera_windows.cpp
|
||||||
src/util/windows/getline.c
|
|
||||||
src/util/windows/com.cpp
|
|
||||||
src/util/windows/registry.c
|
|
||||||
src/util/windows/unicode.c
|
|
||||||
src/util/windows/wmi.cpp
|
|
||||||
src/util/windows/version.c
|
|
||||||
src/util/platform/FFPlatform_windows.c
|
|
||||||
src/util/binary_windows.c
|
|
||||||
src/util/debug_windows.c
|
|
||||||
)
|
)
|
||||||
elseif(SunOS)
|
elseif(SunOS)
|
||||||
list(APPEND LIBFASTFETCH_SRC
|
list(APPEND LIBFASTFETCH_SRC
|
||||||
src/common/dbus.c
|
src/common/impl/dbus.c
|
||||||
src/common/io/io_unix.c
|
src/common/impl/io_unix.c
|
||||||
src/common/netif/netif_apple.c
|
src/common/impl/netif_apple.c
|
||||||
src/common/networking/networking_linux.c
|
src/common/impl/networking_linux.c
|
||||||
src/common/processing_linux.c
|
src/common/impl/processing_linux.c
|
||||||
|
src/common/impl/FFPlatform_unix.c
|
||||||
|
src/common/impl/binary_linux.c
|
||||||
src/detection/battery/battery_nosupport.c
|
src/detection/battery/battery_nosupport.c
|
||||||
src/detection/bios/bios_windows.c
|
src/detection/bios/bios_windows.c
|
||||||
src/detection/board/board_windows.c
|
src/detection/board/board_windows.c
|
||||||
@@ -1139,16 +1151,17 @@ elseif(SunOS)
|
|||||||
src/detection/de/de_linux.c
|
src/detection/de/de_linux.c
|
||||||
src/detection/wmtheme/wmtheme_linux.c
|
src/detection/wmtheme/wmtheme_linux.c
|
||||||
src/detection/camera/camera_nosupport.c
|
src/detection/camera/camera_nosupport.c
|
||||||
src/util/platform/FFPlatform_unix.c
|
|
||||||
src/util/binary_linux.c
|
|
||||||
)
|
)
|
||||||
elseif(Haiku)
|
elseif(Haiku)
|
||||||
list(APPEND LIBFASTFETCH_SRC
|
list(APPEND LIBFASTFETCH_SRC
|
||||||
src/common/dbus.c
|
src/common/impl/dbus.c
|
||||||
src/common/io/io_unix.c
|
src/common/impl/io_unix.c
|
||||||
src/common/netif/netif_haiku.c
|
src/common/impl/netif_haiku.c
|
||||||
src/common/networking/networking_linux.c
|
src/common/impl/networking_linux.c
|
||||||
src/common/processing_linux.c
|
src/common/impl/processing_linux.c
|
||||||
|
src/common/impl/FFPlatform_unix.c
|
||||||
|
src/common/impl/binary_linux.c
|
||||||
|
src/common/haiku/version.cpp
|
||||||
src/detection/battery/battery_haiku.c
|
src/detection/battery/battery_haiku.c
|
||||||
src/detection/bios/bios_windows.c
|
src/detection/bios/bios_windows.c
|
||||||
src/detection/board/board_windows.c
|
src/detection/board/board_windows.c
|
||||||
@@ -1207,17 +1220,16 @@ elseif(Haiku)
|
|||||||
src/detection/de/de_nosupport.c
|
src/detection/de/de_nosupport.c
|
||||||
src/detection/wmtheme/wmtheme_nosupport.c
|
src/detection/wmtheme/wmtheme_nosupport.c
|
||||||
src/detection/camera/camera_nosupport.c
|
src/detection/camera/camera_nosupport.c
|
||||||
src/util/platform/FFPlatform_unix.c
|
|
||||||
src/util/binary_linux.c
|
|
||||||
src/util/haiku/version.cpp
|
|
||||||
)
|
)
|
||||||
elseif(GNU)
|
elseif(GNU)
|
||||||
list(APPEND LIBFASTFETCH_SRC
|
list(APPEND LIBFASTFETCH_SRC
|
||||||
src/common/dbus.c
|
src/common/impl/dbus.c
|
||||||
src/common/io/io_unix.c
|
src/common/impl/io_unix.c
|
||||||
src/common/netif/netif_gnu.c
|
src/common/impl/netif_gnu.c
|
||||||
src/common/networking/networking_linux.c
|
src/common/impl/networking_linux.c
|
||||||
src/common/processing_linux.c
|
src/common/impl/processing_linux.c
|
||||||
|
src/common/impl/FFPlatform_unix.c
|
||||||
|
src/common/impl/binary_linux.c
|
||||||
src/detection/battery/battery_nosupport.c
|
src/detection/battery/battery_nosupport.c
|
||||||
src/detection/bios/bios_nosupport.c
|
src/detection/bios/bios_nosupport.c
|
||||||
src/detection/board/board_nosupport.c
|
src/detection/board/board_nosupport.c
|
||||||
@@ -1286,8 +1298,6 @@ elseif(GNU)
|
|||||||
src/detection/de/de_linux.c
|
src/detection/de/de_linux.c
|
||||||
src/detection/wmtheme/wmtheme_linux.c
|
src/detection/wmtheme/wmtheme_linux.c
|
||||||
src/detection/camera/camera_nosupport.c
|
src/detection/camera/camera_nosupport.c
|
||||||
src/util/platform/FFPlatform_unix.c
|
|
||||||
src/util/binary_linux.c
|
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -1308,7 +1318,7 @@ endif()
|
|||||||
include(CheckFunctionExists)
|
include(CheckFunctionExists)
|
||||||
check_function_exists(wcwidth HAVE_WCWIDTH)
|
check_function_exists(wcwidth HAVE_WCWIDTH)
|
||||||
if(NOT HAVE_WCWIDTH)
|
if(NOT HAVE_WCWIDTH)
|
||||||
list(APPEND LIBFASTFETCH_SRC src/util/wcwidth.c)
|
list(APPEND LIBFASTFETCH_SRC src/common/impl/wcwidth.c)
|
||||||
endif()
|
endif()
|
||||||
if(NOT WIN32)
|
if(NOT WIN32)
|
||||||
check_function_exists(pipe2 HAVE_PIPE2)
|
check_function_exists(pipe2 HAVE_PIPE2)
|
||||||
@@ -1402,7 +1412,7 @@ elseif(OpenBSD)
|
|||||||
elseif(DragonFly)
|
elseif(DragonFly)
|
||||||
target_compile_definitions(libfastfetch PUBLIC __FreeBSD__)
|
target_compile_definitions(libfastfetch PUBLIC __FreeBSD__)
|
||||||
elseif(SunOS)
|
elseif(SunOS)
|
||||||
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE __STDC_WANT_LIB_EXT1__ _FILE_OFFSET_BITS=64 __EXTENSIONS__ _POSIX_C_SOURCE)
|
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE __STDC_WANT_LIB_EXT1__ _FILE_OFFSET_BITS=64 __EXTENSIONS__ _POSIX_C_SOURCE)
|
||||||
elseif(NetBSD)
|
elseif(NetBSD)
|
||||||
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE)
|
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE)
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-char-subscripts")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-char-subscripts")
|
||||||
@@ -1410,9 +1420,31 @@ elseif(NetBSD)
|
|||||||
elseif(Haiku)
|
elseif(Haiku)
|
||||||
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE)
|
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE)
|
||||||
elseif(GNU)
|
elseif(GNU)
|
||||||
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE)
|
|
||||||
# On Hurd PATH_MAX is not defined. Set an arbitrary limit as workaround.
|
# On Hurd PATH_MAX is not defined. Set an arbitrary limit as workaround.
|
||||||
target_compile_definitions(libfastfetch PUBLIC PATH_MAX=4096)
|
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE PATH_MAX=4096 O_PATH=0)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
check_function_exists(_msize HAVE_MSVC_MSIZE)
|
||||||
|
if(HAVE_MSVC_MSIZE)
|
||||||
|
target_compile_definitions(libfastfetch PUBLIC FF_HAVE_MSVC_MSIZE=1)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ENABLE_WIN7_COMPAT)
|
||||||
|
target_compile_definitions(libfastfetch PUBLIC FF_WIN7_COMPAT=1)
|
||||||
|
else()
|
||||||
|
target_compile_definitions(libfastfetch PUBLIC FF_WIN7_COMPAT=0)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
check_function_exists(malloc_usable_size HAVE_MALLOC_USABLE_SIZE)
|
||||||
|
if(HAVE_MALLOC_USABLE_SIZE)
|
||||||
|
target_compile_definitions(libfastfetch PUBLIC FF_HAVE_MALLOC_USABLE_SIZE=1)
|
||||||
|
else()
|
||||||
|
check_function_exists(malloc_size HAVE_MALLOC_SIZE)
|
||||||
|
if(HAVE_MALLOC_SIZE)
|
||||||
|
target_compile_definitions(libfastfetch PUBLIC FF_HAVE_MALLOC_SIZE=1)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(FreeBSD OR OpenBSD OR NetBSD)
|
if(FreeBSD OR OpenBSD OR NetBSD)
|
||||||
@@ -1676,8 +1708,7 @@ elseif(WIN32)
|
|||||||
PRIVATE "propsys"
|
PRIVATE "propsys"
|
||||||
PRIVATE "secur32"
|
PRIVATE "secur32"
|
||||||
)
|
)
|
||||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
|
if(NOT ENABLE_WIN7_COMPAT)
|
||||||
# WoA only works on Windows 10 or higher
|
|
||||||
target_link_libraries(libfastfetch
|
target_link_libraries(libfastfetch
|
||||||
PRIVATE "mincore"
|
PRIVATE "mincore"
|
||||||
)
|
)
|
||||||
@@ -1865,7 +1896,7 @@ set_target_properties(fastfetch PROPERTIES LINKER_LANGUAGE C)
|
|||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
target_sources(fastfetch
|
target_sources(fastfetch
|
||||||
PRIVATE src/util/windows/version.rc
|
PRIVATE src/common/windows/version.rc
|
||||||
)
|
)
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
target_link_options(fastfetch
|
target_link_options(fastfetch
|
||||||
@@ -1893,7 +1924,7 @@ if (BUILD_FLASHFETCH)
|
|||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
target_sources(flashfetch
|
target_sources(flashfetch
|
||||||
PRIVATE src/util/windows/version.rc
|
PRIVATE src/common/windows/version.rc
|
||||||
)
|
)
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
target_link_options(flashfetch
|
target_link_options(flashfetch
|
||||||
|
|||||||
+22
-2
@@ -2964,8 +2964,11 @@
|
|||||||
"keyWidth": {
|
"keyWidth": {
|
||||||
"$ref": "#/$defs/keyWidth"
|
"$ref": "#/$defs/keyWidth"
|
||||||
},
|
},
|
||||||
|
"outputColor": {
|
||||||
|
"$ref": "#/$defs/outputColor"
|
||||||
|
},
|
||||||
"format": {
|
"format": {
|
||||||
"$ref": "#/$defs/memoryFormat"
|
"$ref": "#/$defs/keyboardFormat"
|
||||||
},
|
},
|
||||||
"condition": {
|
"condition": {
|
||||||
"$ref": "#/$defs/conditions"
|
"$ref": "#/$defs/conditions"
|
||||||
@@ -3199,6 +3202,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"title": "Logo",
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"const": "logo",
|
||||||
|
"description": "Query built-in logo for JSON output"
|
||||||
|
},
|
||||||
|
"condition": {
|
||||||
|
"$ref": "#/$defs/conditions"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"title": "Media",
|
"title": "Media",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@@ -3296,8 +3313,11 @@
|
|||||||
"keyWidth": {
|
"keyWidth": {
|
||||||
"$ref": "#/$defs/keyWidth"
|
"$ref": "#/$defs/keyWidth"
|
||||||
},
|
},
|
||||||
|
"outputColor": {
|
||||||
|
"$ref": "#/$defs/outputColor"
|
||||||
|
},
|
||||||
"format": {
|
"format": {
|
||||||
"$ref": "#/$defs/memoryFormat"
|
"$ref": "#/$defs/mouseFormat"
|
||||||
},
|
},
|
||||||
"condition": {
|
"condition": {
|
||||||
"$ref": "#/$defs/conditions"
|
"$ref": "#/$defs/conditions"
|
||||||
|
|||||||
@@ -109,6 +109,7 @@
|
|||||||
},
|
},
|
||||||
"tpm",
|
"tpm",
|
||||||
"version",
|
"version",
|
||||||
|
"logo",
|
||||||
"break",
|
"break",
|
||||||
"colors"
|
"colors"
|
||||||
]
|
]
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "util/FFstrbuf.h"
|
#include "common/FFstrbuf.h"
|
||||||
#include "util/FFlist.h"
|
#include "common/FFlist.h"
|
||||||
|
|
||||||
typedef struct FFPlatformSysinfo
|
typedef struct FFPlatformSysinfo
|
||||||
{
|
{
|
||||||
@@ -126,3 +126,10 @@ static inline void ffListClear(FFlist* list)
|
|||||||
assert(sizeof(itemType) == (listVar).elementSize); \
|
assert(sizeof(itemType) == (listVar).elementSize); \
|
||||||
(itemType*) ffListAdd(&(listVar)); \
|
(itemType*) ffListAdd(&(listVar)); \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
#define FF_LIST_FIRST(itemType, listVar) FF_LIST_GET(itemType, listVar, 0)
|
||||||
|
#define FF_LIST_LAST(itemType, listVar) \
|
||||||
|
({ \
|
||||||
|
assert((listVar).length > 0); \
|
||||||
|
FF_LIST_GET(itemType, listVar, ((listVar).length - 1)); \
|
||||||
|
})
|
||||||
@@ -24,6 +24,8 @@
|
|||||||
|
|
||||||
#define FASTFETCH_STRBUF_DEFAULT_ALLOC 32
|
#define FASTFETCH_STRBUF_DEFAULT_ALLOC 32
|
||||||
|
|
||||||
|
// static string (allocated == 0), chars points to a string literal
|
||||||
|
// dynamic string (allocated > 0), chars points to a heap allocated buffer
|
||||||
typedef struct FFstrbuf
|
typedef struct FFstrbuf
|
||||||
{
|
{
|
||||||
uint32_t allocated;
|
uint32_t allocated;
|
||||||
@@ -34,6 +36,7 @@ typedef struct FFstrbuf
|
|||||||
static inline void ffStrbufInit(FFstrbuf* strbuf);
|
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 ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free);
|
void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free);
|
||||||
void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free);
|
void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free);
|
||||||
@@ -54,6 +57,10 @@ void ffStrbufPrependC(FFstrbuf* strbuf, char c);
|
|||||||
|
|
||||||
void ffStrbufInsertNC(FFstrbuf* strbuf, uint32_t index, uint32_t num, char c);
|
void ffStrbufInsertNC(FFstrbuf* strbuf, uint32_t index, uint32_t num, char c);
|
||||||
|
|
||||||
|
// Clear the content of strbuf and set new value
|
||||||
|
// NOTE: Unlike ffStrbufAppend*, ffStrbufSet* functions may NOT reserve extra space
|
||||||
|
void ffStrbufSet(FFstrbuf* strbuf, const FFstrbuf* value);
|
||||||
|
void ffStrbufSetNS(FFstrbuf* strbuf, uint32_t length, const char* value);
|
||||||
FF_C_PRINTF(2, 3) void ffStrbufSetF(FFstrbuf* strbuf, const char* format, ...);
|
FF_C_PRINTF(2, 3) void ffStrbufSetF(FFstrbuf* strbuf, const char* format, ...);
|
||||||
|
|
||||||
void ffStrbufTrimLeft(FFstrbuf* strbuf, char c);
|
void ffStrbufTrimLeft(FFstrbuf* strbuf, char c);
|
||||||
@@ -147,7 +154,7 @@ FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateA(uint32_t allocate)
|
|||||||
static inline void ffStrbufInitCopy(FFstrbuf* __restrict strbuf, const FFstrbuf* __restrict src)
|
static inline void ffStrbufInitCopy(FFstrbuf* __restrict strbuf, const FFstrbuf* __restrict src)
|
||||||
{
|
{
|
||||||
if (src->allocated == 0) // static string
|
if (src->allocated == 0) // static string
|
||||||
memcpy(strbuf, src, sizeof(FFstrbuf));
|
*strbuf = *src;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ffStrbufInitA(strbuf, src->allocated);
|
ffStrbufInitA(strbuf, src->allocated);
|
||||||
@@ -167,9 +174,7 @@ static inline void ffStrbufInitMove(FFstrbuf* strbuf, FFstrbuf* src)
|
|||||||
{
|
{
|
||||||
if (src)
|
if (src)
|
||||||
{
|
{
|
||||||
strbuf->allocated = src->allocated;
|
*strbuf = *src;
|
||||||
strbuf->chars = src->chars;
|
|
||||||
strbuf->length = src->length;
|
|
||||||
ffStrbufInit(src);
|
ffStrbufInit(src);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -212,21 +217,17 @@ FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateF(const char* format, ...)
|
|||||||
return strbuf;
|
return strbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void ffStrbufInitMoveS(FFstrbuf* strbuf, char* heapStr)
|
||||||
|
{
|
||||||
|
ffStrbufInitMoveNS(strbuf, (uint32_t) strlen(heapStr), heapStr);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void ffStrbufDestroy(FFstrbuf* strbuf)
|
static inline void ffStrbufDestroy(FFstrbuf* strbuf)
|
||||||
{
|
{
|
||||||
extern char* CHAR_NULL_PTR;
|
if(strbuf->allocated > 0)
|
||||||
|
free(strbuf->chars);
|
||||||
|
|
||||||
if(strbuf->allocated == 0)
|
ffStrbufInit(strbuf);
|
||||||
{
|
|
||||||
strbuf->length = 0;
|
|
||||||
strbuf->chars = CHAR_NULL_PTR;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Avoid free-after-use. These 3 assignments are cheap so don't remove them
|
|
||||||
strbuf->allocated = strbuf->length = 0;
|
|
||||||
free(strbuf->chars);
|
|
||||||
strbuf->chars = CHAR_NULL_PTR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_C_NODISCARD static inline uint32_t ffStrbufGetFree(const FFstrbuf* strbuf)
|
FF_C_NODISCARD static inline uint32_t ffStrbufGetFree(const FFstrbuf* strbuf)
|
||||||
@@ -243,6 +244,30 @@ 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)
|
||||||
|
{
|
||||||
|
assert(strbuf != NULL);
|
||||||
|
|
||||||
|
if (value == NULL)
|
||||||
|
ffStrbufClear(strbuf);
|
||||||
|
else
|
||||||
|
ffStrbufSetNS(strbuf, (uint32_t) strlen(value), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool ffStrbufSetJsonVal(FFstrbuf* strbuf, yyjson_val* jsonVal)
|
||||||
|
{
|
||||||
|
assert(strbuf != NULL);
|
||||||
|
|
||||||
|
if (yyjson_is_str(jsonVal))
|
||||||
|
{
|
||||||
|
ffStrbufSetNS(strbuf, (uint32_t) unsafe_yyjson_get_len(jsonVal), unsafe_yyjson_get_str(jsonVal));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ffStrbufClear(strbuf);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void ffStrbufAppendS(FFstrbuf* strbuf, const char* value)
|
static inline void ffStrbufAppendS(FFstrbuf* strbuf, const char* value)
|
||||||
{
|
{
|
||||||
if(value == NULL)
|
if(value == NULL)
|
||||||
@@ -260,42 +285,10 @@ static inline bool ffStrbufAppendJsonVal(FFstrbuf* strbuf, yyjson_val* jsonVal)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ffStrbufSetS(FFstrbuf* strbuf, const char* value)
|
|
||||||
{
|
|
||||||
ffStrbufClear(strbuf);
|
|
||||||
|
|
||||||
if(value != NULL)
|
|
||||||
ffStrbufAppendNS(strbuf, (uint32_t) strlen(value), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void ffStrbufSetNS(FFstrbuf* strbuf, uint32_t length, const char* value)
|
|
||||||
{
|
|
||||||
ffStrbufClear(strbuf);
|
|
||||||
ffStrbufAppendNS(strbuf, length, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void ffStrbufSet(FFstrbuf* strbuf, const FFstrbuf* value)
|
|
||||||
{
|
|
||||||
assert(value && value != strbuf);
|
|
||||||
if (strbuf->allocated == 0 && value->allocated == 0)
|
|
||||||
{
|
|
||||||
memcpy(strbuf, value, sizeof(FFstrbuf));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ffStrbufSetNS(strbuf, value->length, value->chars);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool ffStrbufSetJsonVal(FFstrbuf* strbuf, yyjson_val* jsonVal)
|
|
||||||
{
|
|
||||||
ffStrbufClear(strbuf);
|
|
||||||
return ffStrbufAppendJsonVal(strbuf, jsonVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void ffStrbufInit(FFstrbuf* strbuf)
|
static inline void ffStrbufInit(FFstrbuf* strbuf)
|
||||||
{
|
{
|
||||||
extern char* CHAR_NULL_PTR;
|
extern char* CHAR_NULL_PTR;
|
||||||
strbuf->allocated = 0;
|
strbuf->allocated = strbuf->length = 0;
|
||||||
strbuf->length = 0;
|
|
||||||
strbuf->chars = CHAR_NULL_PTR;
|
strbuf->chars = CHAR_NULL_PTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,10 +319,12 @@ FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateStatic(const char* str)
|
|||||||
static inline void ffStrbufSetStatic(FFstrbuf* strbuf, const char* value)
|
static inline void ffStrbufSetStatic(FFstrbuf* strbuf, const char* value)
|
||||||
{
|
{
|
||||||
if(strbuf->allocated > 0)
|
if(strbuf->allocated > 0)
|
||||||
ffStrbufDestroy(strbuf);
|
free(strbuf->chars);
|
||||||
|
|
||||||
if(value != NULL)
|
if(value != NULL)
|
||||||
ffStrbufInitStatic(strbuf, value);
|
ffStrbufInitStatic(strbuf, value);
|
||||||
|
else
|
||||||
|
ffStrbufInit(strbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ffStrbufInitNS(FFstrbuf* strbuf, uint32_t length, const char* str)
|
static inline void ffStrbufInitNS(FFstrbuf* strbuf, uint32_t length, const char* str)
|
||||||
@@ -386,7 +381,7 @@ static inline void ffStrbufPrependS(FFstrbuf* strbuf, const char* value)
|
|||||||
ffStrbufPrependNS(strbuf, (uint32_t) strlen(value), value);
|
ffStrbufPrependNS(strbuf, (uint32_t) strlen(value), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int ffStrbufComp(const FFstrbuf* strbuf, const FFstrbuf* comp)
|
static inline FF_C_NODISCARD int ffStrbufComp(const FFstrbuf* strbuf, const FFstrbuf* comp)
|
||||||
{
|
{
|
||||||
uint32_t length = strbuf->length > comp->length ? comp->length : strbuf->length;
|
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);
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "smc_temps.h"
|
#include "smc_temps.h"
|
||||||
#include "util/apple/cf_helpers.h"
|
#include "common/apple/cf_helpers.h"
|
||||||
#include "util/stringUtils.h"
|
#include "common/stringUtils.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@@ -156,113 +156,108 @@ static const char *smcReadValue(io_connect_t conn, const UInt32Char_t key, doubl
|
|||||||
if (val.dataSize == 0)
|
if (val.dataSize == 0)
|
||||||
return "Empty SMC result";
|
return "Empty SMC result";
|
||||||
|
|
||||||
if (ffStrEquals(val.dataType, "ui8 ") ||
|
switch (val.dataType[0])
|
||||||
ffStrEquals(val.dataType, "ui16") ||
|
|
||||||
ffStrEquals(val.dataType, "ui32") ||
|
|
||||||
ffStrEquals(val.dataType, "ui64"))
|
|
||||||
{
|
{
|
||||||
uint64_t tmp = 0;
|
case 'u': // unsigned integer types
|
||||||
for (uint32_t i = 0; i < val.dataSize; i++)
|
if (val.dataType[1] == 'i')
|
||||||
tmp += (uint64_t)((uint8_t)(val.bytes[i]) * pow(256, val.dataSize - 1 - i));
|
{
|
||||||
*value = (double)tmp;
|
switch (val.dataSize)
|
||||||
|
{
|
||||||
|
case 1: *value = *(uint8_t *)(val.bytes); break;
|
||||||
|
case 2: *value = ntohs(*(uint16_t *)(val.bytes)); break;
|
||||||
|
case 4: *value = ntohl(*(uint32_t *)(val.bytes)); break;
|
||||||
|
case 8: *value = ntohll(*(uint64_t *)(val.bytes)); break;
|
||||||
|
default:
|
||||||
|
return "Unsupported SMC unsigned integer data size";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return "Unsupported SMC unsigned data type";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'f': // floating point types
|
||||||
|
if (ffStrEquals(val.dataType, "flt ") && val.dataSize == 4)
|
||||||
|
*value = *(float *)(val.bytes);
|
||||||
|
else if (val.dataType[1] == 'p' && val.dataSize == 2) // fixed point types
|
||||||
|
{
|
||||||
|
if (ffStrEquals(val.dataType, "fp1f"))
|
||||||
|
*value = ntohs(*(uint16_t *)(val.bytes)) / 32768.0;
|
||||||
|
else if (ffStrEquals(val.dataType, "fp4c"))
|
||||||
|
*value = ntohs(*(uint16_t *)(val.bytes)) / 4096.0;
|
||||||
|
else if (ffStrEquals(val.dataType, "fp5b"))
|
||||||
|
*value = ntohs(*(uint16_t *)(val.bytes)) / 2048.0;
|
||||||
|
else if (ffStrEquals(val.dataType, "fp6a"))
|
||||||
|
*value = ntohs(*(uint16_t *)(val.bytes)) / 1024.0;
|
||||||
|
else if (ffStrEquals(val.dataType, "fp79"))
|
||||||
|
*value = ntohs(*(uint16_t *)(val.bytes)) / 512.0;
|
||||||
|
else if (ffStrEquals(val.dataType, "fp88"))
|
||||||
|
*value = ntohs(*(uint16_t *)(val.bytes)) / 256.0;
|
||||||
|
else if (ffStrEquals(val.dataType, "fpa6"))
|
||||||
|
*value = ntohs(*(uint16_t *)(val.bytes)) / 64.0;
|
||||||
|
else if (ffStrEquals(val.dataType, "fpc4"))
|
||||||
|
*value = ntohs(*(uint16_t *)(val.bytes)) / 16.0;
|
||||||
|
else if (ffStrEquals(val.dataType, "fpe2"))
|
||||||
|
*value = ntohs(*(uint16_t *)(val.bytes)) / 4.0;
|
||||||
|
else
|
||||||
|
return "Unsupported SMC floating point data type";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return "Unsupported SMC floating point data type";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's': // signed integer types
|
||||||
|
if (val.dataType[1] == 'i')
|
||||||
|
{
|
||||||
|
switch (val.dataSize)
|
||||||
|
{
|
||||||
|
case 1: *value = *(int8_t *)(val.bytes); break;
|
||||||
|
case 2: *value = ntohs(*(int16_t *)(val.bytes)); break;
|
||||||
|
case 4: *value = ntohl(*(int32_t *)(val.bytes)); break;
|
||||||
|
case 8: *value = ntohll(*(int64_t *)(val.bytes)); break;
|
||||||
|
default: return "Unsupported SMC signed integer data size";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (val.dataType[1] == 'p' && val.dataSize == 2) // signed fixed point types
|
||||||
|
{
|
||||||
|
if (ffStrEquals(val.dataType, "sp1e"))
|
||||||
|
*value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 16384.0;
|
||||||
|
else if (ffStrEquals(val.dataType, "sp3c"))
|
||||||
|
*value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 4096.0;
|
||||||
|
else if (ffStrEquals(val.dataType, "sp4b"))
|
||||||
|
*value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 2048.0;
|
||||||
|
else if (ffStrEquals(val.dataType, "sp5a"))
|
||||||
|
*value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 1024.0;
|
||||||
|
else if (ffStrEquals(val.dataType, "sp69"))
|
||||||
|
*value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 512.0;
|
||||||
|
else if (ffStrEquals(val.dataType, "sp78"))
|
||||||
|
*value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 256.0;
|
||||||
|
else if (ffStrEquals(val.dataType, "sp87"))
|
||||||
|
*value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 128.0;
|
||||||
|
else if (ffStrEquals(val.dataType, "sp96"))
|
||||||
|
*value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 64.0;
|
||||||
|
else if (ffStrEquals(val.dataType, "spb4"))
|
||||||
|
*value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 16.0;
|
||||||
|
else if (ffStrEquals(val.dataType, "spf0"))
|
||||||
|
*value = (int16_t)ntohs(*(int16_t *)(val.bytes)) / 1.0;
|
||||||
|
else
|
||||||
|
return "Unsupported SMC signed integer data type";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return "Unsupported SMC signed data type";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '{': // special types like pwm
|
||||||
|
if (ffStrEquals(val.dataType, "{pwm") && val.dataSize == 2)
|
||||||
|
{
|
||||||
|
*value = (double)ntohs(*(uint16_t *)(val.bytes)) * 100 / 65536.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return "Unsupported SMC special data type";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return "Unsupported SMC data type";
|
||||||
}
|
}
|
||||||
else if (ffStrEquals(val.dataType, "flt "))
|
|
||||||
{
|
|
||||||
*value = *(float *)(val.bytes);
|
|
||||||
}
|
|
||||||
else if (ffStrEquals(val.dataType, "fp1f") && val.dataSize == 2)
|
|
||||||
{
|
|
||||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 32768.0;
|
|
||||||
}
|
|
||||||
else if (ffStrEquals(val.dataType, "fp4c") && val.dataSize == 2)
|
|
||||||
{
|
|
||||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 4096.0;
|
|
||||||
}
|
|
||||||
else if (ffStrEquals(val.dataType, "fp5b") && val.dataSize == 2)
|
|
||||||
{
|
|
||||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 2048.0;
|
|
||||||
}
|
|
||||||
else if (ffStrEquals(val.dataType, "fp6a") && val.dataSize == 2)
|
|
||||||
{
|
|
||||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 1024.0;
|
|
||||||
}
|
|
||||||
else if (ffStrEquals(val.dataType, "fp79") && val.dataSize == 2)
|
|
||||||
{
|
|
||||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 512.0;
|
|
||||||
}
|
|
||||||
else if (ffStrEquals(val.dataType, "fp88") && val.dataSize == 2)
|
|
||||||
{
|
|
||||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 256.0;
|
|
||||||
}
|
|
||||||
else if (ffStrEquals(val.dataType, "fpa6") && val.dataSize == 2)
|
|
||||||
{
|
|
||||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 64.0;
|
|
||||||
}
|
|
||||||
else if (ffStrEquals(val.dataType, "fpc4") && val.dataSize == 2)
|
|
||||||
{
|
|
||||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 16.0;
|
|
||||||
}
|
|
||||||
else if (ffStrEquals(val.dataType, "fpe2") && val.dataSize == 2)
|
|
||||||
{
|
|
||||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 4.0;
|
|
||||||
}
|
|
||||||
else if (ffStrEquals(val.dataType, "sp1e") && val.dataSize == 2)
|
|
||||||
{
|
|
||||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 16384.0;
|
|
||||||
}
|
|
||||||
else if (ffStrEquals(val.dataType, "sp3c") && val.dataSize == 2)
|
|
||||||
{
|
|
||||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 4096.0;
|
|
||||||
}
|
|
||||||
else if (ffStrEquals(val.dataType, "sp4b") && val.dataSize == 2)
|
|
||||||
{
|
|
||||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 2048.0;
|
|
||||||
}
|
|
||||||
else if (ffStrEquals(val.dataType, "sp5a") && val.dataSize == 2)
|
|
||||||
{
|
|
||||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 1024.0;
|
|
||||||
}
|
|
||||||
else if (ffStrEquals(val.dataType, "sp69") && val.dataSize == 2)
|
|
||||||
{
|
|
||||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 512.0;
|
|
||||||
}
|
|
||||||
else if (ffStrEquals(val.dataType, "sp78") && val.dataSize == 2)
|
|
||||||
{
|
|
||||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 256.0;
|
|
||||||
}
|
|
||||||
else if (ffStrEquals(val.dataType, "sp87") && val.dataSize == 2)
|
|
||||||
{
|
|
||||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 128.0;
|
|
||||||
}
|
|
||||||
else if (ffStrEquals(val.dataType, "sp96") && val.dataSize == 2)
|
|
||||||
{
|
|
||||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 64.0;
|
|
||||||
}
|
|
||||||
else if (ffStrEquals(val.dataType, "spb4") && val.dataSize == 2)
|
|
||||||
{
|
|
||||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 16.0;
|
|
||||||
}
|
|
||||||
else if (ffStrEquals(val.dataType, "spf0") && val.dataSize == 2)
|
|
||||||
{
|
|
||||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 1.0;
|
|
||||||
}
|
|
||||||
else if (ffStrEquals(val.dataType, "si8 ") && val.dataSize == 1)
|
|
||||||
{
|
|
||||||
signed char *bytes = (signed char *)val.bytes;
|
|
||||||
int16_t temp = 0;
|
|
||||||
temp += (int8_t)(bytes[0]);
|
|
||||||
*value = temp;
|
|
||||||
}
|
|
||||||
else if (ffStrEquals(val.dataType, "si16") && val.dataSize == 2)
|
|
||||||
{
|
|
||||||
*value = ntohs(*(int16_t *)(val.bytes));
|
|
||||||
}
|
|
||||||
else if (ffStrEquals(val.dataType, "{pwm") && val.dataSize == 2)
|
|
||||||
{
|
|
||||||
*value = (double)ntohs(*(uint16_t *)(val.bytes)) * 100 / 65536.0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return "Unknown SMC data type";
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
#ifdef FF_HAVE_DBUS
|
#ifdef FF_HAVE_DBUS
|
||||||
#include <dbus/dbus.h>
|
#include <dbus/dbus.h>
|
||||||
|
|
||||||
#include "util/FFstrbuf.h"
|
#include "common/FFstrbuf.h"
|
||||||
#include "common/library.h"
|
#include "common/library.h"
|
||||||
|
|
||||||
typedef struct FFDBusLibrary
|
typedef struct FFDBusLibrary
|
||||||
|
|||||||
@@ -28,4 +28,6 @@ static inline const char* ffFindFileName(const char* file)
|
|||||||
|
|
||||||
#define FF_DEBUG(format, ...) FF_DEBUG_PRINT(__FILE__, __LINE__, format, ##__VA_ARGS__)
|
#define FF_DEBUG(format, ...) FF_DEBUG_PRINT(__FILE__, __LINE__, format, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
const char* ffDebugWin32Error(unsigned long errorCode);
|
const char* ffDebugWin32Error(unsigned long errorCode);
|
||||||
|
#endif
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
#include "fastfetch.h"
|
#include "fastfetch.h"
|
||||||
|
|
||||||
void ffDurationAppendNum(uint64_t totalSeconds, FFstrbuf* result);
|
void ffDurationAppendNum(uint64_t totalSeconds, FFstrbuf* result);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "util/FFstrbuf.h"
|
#include "common/FFstrbuf.h"
|
||||||
|
|
||||||
void ffEdidGetVendorAndModel(const uint8_t edid[128], FFstrbuf* result);
|
void ffEdidGetVendorAndModel(const uint8_t edid[128], FFstrbuf* result);
|
||||||
bool ffEdidGetName(const uint8_t edid[128], FFstrbuf* name);
|
bool ffEdidGetName(const uint8_t edid[128], FFstrbuf* name);
|
||||||
@@ -1,238 +0,0 @@
|
|||||||
#include "fastfetch.h"
|
|
||||||
#include "util/FFlist.h"
|
|
||||||
#include "util/FFstrbuf.h"
|
|
||||||
#include "common/font.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
void ffFontInit(FFfont* font)
|
|
||||||
{
|
|
||||||
// Ensure no memory allocates
|
|
||||||
ffStrbufInit(&font->pretty);
|
|
||||||
ffStrbufInit(&font->name);
|
|
||||||
ffStrbufInit(&font->size);
|
|
||||||
ffListInit(&font->styles, sizeof(FFstrbuf));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void strbufAppendNSExcludingC(FFstrbuf* strbuf, uint32_t length, const char* value, char exclude)
|
|
||||||
{
|
|
||||||
if(value == NULL || length == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ffStrbufEnsureFree(strbuf, length);
|
|
||||||
|
|
||||||
for(uint32_t i = 0; i < length; i++)
|
|
||||||
{
|
|
||||||
if(value[i] != exclude)
|
|
||||||
strbuf->chars[strbuf->length++] = value[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
strbuf->chars[strbuf->length] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fontInitPretty(FFfont* font)
|
|
||||||
{
|
|
||||||
ffStrbufAppend(&font->pretty, &font->name);
|
|
||||||
|
|
||||||
if(font->size.length == 0 && font->styles.length == 0)
|
|
||||||
return;
|
|
||||||
else if(font->pretty.length == 0)
|
|
||||||
ffStrbufAppendS(&font->pretty, "default");
|
|
||||||
|
|
||||||
ffStrbufAppendS(&font->pretty, " (");
|
|
||||||
|
|
||||||
if(font->size.length > 0)
|
|
||||||
{
|
|
||||||
ffStrbufAppend(&font->pretty, &font->size);
|
|
||||||
ffStrbufAppendS(&font->pretty, "pt");
|
|
||||||
|
|
||||||
if(font->styles.length > 0)
|
|
||||||
ffStrbufAppendS(&font->pretty, ", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
for(uint32_t i = 0; i < font->styles.length; i++)
|
|
||||||
{
|
|
||||||
ffStrbufAppend(&font->pretty, FF_LIST_GET(FFstrbuf, font->styles, i));
|
|
||||||
|
|
||||||
if(i < font->styles.length - 1)
|
|
||||||
ffStrbufAppendS(&font->pretty, ", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
ffStrbufAppendC(&font->pretty, ')');
|
|
||||||
}
|
|
||||||
|
|
||||||
void ffFontInitQt(FFfont* font, const char* data)
|
|
||||||
{
|
|
||||||
ffFontInit(font);
|
|
||||||
|
|
||||||
//See https://doc.qt.io/qt-5/qfont.html#toString
|
|
||||||
|
|
||||||
//Family
|
|
||||||
data = ffStrbufAppendSUntilC(&font->name, data, ',');
|
|
||||||
ffStrbufTrim(&font->name, ' ');
|
|
||||||
if (!data) goto exit;
|
|
||||||
data++;
|
|
||||||
|
|
||||||
//Size
|
|
||||||
data = ffStrbufAppendSUntilC(&font->size, data, ',');
|
|
||||||
ffStrbufTrim(&font->size, ' ');
|
|
||||||
if (!data) goto exit;
|
|
||||||
data++;
|
|
||||||
|
|
||||||
//Style
|
|
||||||
data = strrchr(data, ',');
|
|
||||||
if (!data) goto exit;
|
|
||||||
data++;
|
|
||||||
if (isalpha(*data))
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
FFstrbuf* style = (FFstrbuf*) ffListAdd(&font->styles);
|
|
||||||
ffStrbufInit(style);
|
|
||||||
data = ffStrbufAppendSUntilC(style, data, ' ');
|
|
||||||
if (data) data++;
|
|
||||||
} while (data);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit:
|
|
||||||
fontInitPretty(font);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fontPangoParseWord(const char** data, FFfont* font, FFstrbuf* alternativeBuffer)
|
|
||||||
{
|
|
||||||
while(**data == ' ' || **data == '\t' || **data == ',')
|
|
||||||
++(*data);
|
|
||||||
|
|
||||||
const char* wordStart = *data;
|
|
||||||
|
|
||||||
while(**data != ' ' && **data != '\t' && **data != ',' && **data != '\0' && **data != '`' && **data != '\\')
|
|
||||||
++(*data);
|
|
||||||
|
|
||||||
uint32_t wordLength = (uint32_t) (*data - wordStart);
|
|
||||||
if(wordLength == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(**data == '\0' || **data == '`' || **data == '\\')
|
|
||||||
{
|
|
||||||
ffStrbufAppendNS(&font->size, wordLength, wordStart);
|
|
||||||
if(ffStrbufEndsWithS(&font->size, "px"))
|
|
||||||
ffStrbufSubstrBefore(&font->size, font->size.length - 2);
|
|
||||||
|
|
||||||
double dummy;
|
|
||||||
if(sscanf(font->size.chars, "%lf", &dummy) == 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ffStrbufClear(&font->size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(
|
|
||||||
strncasecmp(wordStart, "Ultra", 5) == 0 ||
|
|
||||||
strncasecmp(wordStart, "Extra", 5) == 0 ||
|
|
||||||
strncasecmp(wordStart, "Semi", 4) == 0 ||
|
|
||||||
strncasecmp(wordStart, "Demi", 4) == 0 ||
|
|
||||||
strncasecmp(wordStart, "Normal", wordLength) == 0 ||
|
|
||||||
strncasecmp(wordStart, "Roman", wordLength) == 0 ||
|
|
||||||
strncasecmp(wordStart, "Oblique", wordLength) == 0 ||
|
|
||||||
strncasecmp(wordStart, "Italic", wordLength) == 0 ||
|
|
||||||
strncasecmp(wordStart, "Thin", wordLength) == 0 ||
|
|
||||||
strncasecmp(wordStart, "Light", wordLength) == 0 ||
|
|
||||||
strncasecmp(wordStart, "Bold", wordLength) == 0 ||
|
|
||||||
strncasecmp(wordStart, "Black", wordLength) == 0 ||
|
|
||||||
strncasecmp(wordStart, "Condensed", wordLength) == 0 ||
|
|
||||||
strncasecmp(wordStart, "Expanded", wordLength) == 0
|
|
||||||
) {
|
|
||||||
if(alternativeBuffer == NULL)
|
|
||||||
{
|
|
||||||
alternativeBuffer = (FFstrbuf*) ffListAdd(&font->styles);
|
|
||||||
ffStrbufInit(alternativeBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
strbufAppendNSExcludingC(alternativeBuffer, wordLength, wordStart, '-');
|
|
||||||
|
|
||||||
if(
|
|
||||||
strncasecmp(wordStart, "Ultra ", 6) == 0 ||
|
|
||||||
strncasecmp(wordStart, "Extra ", 6) == 0 ||
|
|
||||||
strncasecmp(wordStart, "Semi ", 5) == 0 ||
|
|
||||||
strncasecmp(wordStart, "Demi ", 5) == 0
|
|
||||||
) {
|
|
||||||
fontPangoParseWord(data, font, alternativeBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(alternativeBuffer != NULL)
|
|
||||||
{
|
|
||||||
strbufAppendNSExcludingC(alternativeBuffer, wordLength, wordStart, '-');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(font->name.length > 0)
|
|
||||||
ffStrbufAppendC(&font->name, ' ');
|
|
||||||
ffStrbufAppendNS(&font->name, wordLength, wordStart);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ffFontInitPango(FFfont* font, const char* data)
|
|
||||||
{
|
|
||||||
ffFontInit(font);
|
|
||||||
|
|
||||||
while(*data != '\0' && *data != '`' && *data != '\\')
|
|
||||||
fontPangoParseWord(&data, font, NULL);
|
|
||||||
|
|
||||||
fontInitPretty(font);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ffFontInitValues(FFfont* font, const char* name, const char* size)
|
|
||||||
{
|
|
||||||
ffFontInit(font);
|
|
||||||
|
|
||||||
ffStrbufAppendS(&font->name, name);
|
|
||||||
ffStrbufTrim(&font->name, '"');
|
|
||||||
ffStrbufAppendS(&font->size, size);
|
|
||||||
|
|
||||||
fontInitPretty(font);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ffFontInitMoveValues(FFfont* font, FFstrbuf* name, FFstrbuf* size, FFstrbuf* style)
|
|
||||||
{
|
|
||||||
ffFontInit(font);
|
|
||||||
|
|
||||||
if (name) ffStrbufInitMove(&font->name, name);
|
|
||||||
if (size) ffStrbufInitMove(&font->size, size);
|
|
||||||
if (style)
|
|
||||||
{
|
|
||||||
FFstrbuf* styleBuf = FF_LIST_ADD(FFstrbuf, font->styles);
|
|
||||||
ffStrbufInitMove(styleBuf, style);
|
|
||||||
}
|
|
||||||
|
|
||||||
fontInitPretty(font);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ffFontInitWithSpace(FFfont* font, const char* rawName)
|
|
||||||
{
|
|
||||||
const char* pspace = strrchr(rawName, ' ');
|
|
||||||
if(pspace == NULL)
|
|
||||||
{
|
|
||||||
ffFontInitCopy(font, rawName);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ffFontInit(font);
|
|
||||||
|
|
||||||
ffStrbufAppendNS(&font->name, (uint32_t)(pspace - rawName), rawName);
|
|
||||||
ffStrbufAppendS(&font->size, pspace + 1);
|
|
||||||
|
|
||||||
fontInitPretty(font);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ffFontDestroy(FFfont* font)
|
|
||||||
{
|
|
||||||
ffStrbufDestroy(&font->pretty);
|
|
||||||
ffStrbufDestroy(&font->name);
|
|
||||||
ffStrbufDestroy(&font->size);
|
|
||||||
|
|
||||||
FF_LIST_FOR_EACH(FFstrbuf, str, font->styles)
|
|
||||||
ffStrbufDestroy(str);
|
|
||||||
ffListDestroy(&font->styles);
|
|
||||||
}
|
|
||||||
+4
-2
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "util/FFstrbuf.h"
|
#include "common/FFstrbuf.h"
|
||||||
#include "util/FFlist.h"
|
#include "common/FFlist.h"
|
||||||
|
|
||||||
typedef struct FFfont
|
typedef struct FFfont
|
||||||
{
|
{
|
||||||
@@ -15,6 +15,8 @@ void ffFontInit(FFfont* font);
|
|||||||
void ffFontInitQt(FFfont* font, const char* data);
|
void ffFontInitQt(FFfont* font, const char* data);
|
||||||
void ffFontInitPango(FFfont* font, const char* data);
|
void ffFontInitPango(FFfont* font, const char* data);
|
||||||
void ffFontInitValues(FFfont* font, const char* name, const char* size);
|
void ffFontInitValues(FFfont* font, const char* name, const char* size);
|
||||||
|
void ffFontInitXlfd(FFfont* font, const char* xlfd);
|
||||||
|
void ffFontInitXft(FFfont* font, const char* xft);
|
||||||
void ffFontInitMoveValues(FFfont* font, FFstrbuf* name, FFstrbuf* size, FFstrbuf* style);
|
void ffFontInitMoveValues(FFfont* font, FFstrbuf* name, FFstrbuf* size, FFstrbuf* style);
|
||||||
void ffFontInitWithSpace(FFfont* font, const char* rawName);
|
void ffFontInitWithSpace(FFfont* font, const char* rawName);
|
||||||
void ffFontDestroy(FFfont* font);
|
void ffFontDestroy(FFfont* font);
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "util/FFstrbuf.h"
|
#include "common/FFstrbuf.h"
|
||||||
|
|
||||||
typedef enum __attribute__((__packed__)) FFformatArgType
|
typedef enum __attribute__((__packed__)) FFformatArgType
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
#include "fastfetch.h"
|
#include "fastfetch.h"
|
||||||
|
|
||||||
bool ffFreqAppendNum(uint32_t mhz, FFstrbuf* result);
|
bool ffFreqAppendNum(uint32_t mhz, FFstrbuf* result);
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
#include "util/FFstrbuf.h"
|
#include "common/FFstrbuf.h"
|
||||||
|
|
||||||
bool ffGetFileVersion(const char* filePath, FFstrbuf* version);
|
bool ffGetFileVersion(const char* filePath, FFstrbuf* version);
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "FFPlatform_private.h"
|
#include "FFPlatform_private.h"
|
||||||
#include "util/stringUtils.h"
|
#include "common/stringUtils.h"
|
||||||
#include "common/io/io.h"
|
#include "common/io.h"
|
||||||
#include "detection/version/version.h"
|
#include "detection/version/version.h"
|
||||||
|
|
||||||
void ffPlatformInit(FFPlatform* platform)
|
void ffPlatformInit(FFPlatform* platform)
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "FFPlatform.h"
|
#include "common/FFPlatform.h"
|
||||||
|
|
||||||
void ffPlatformInitImpl(FFPlatform* platform);
|
void ffPlatformInitImpl(FFPlatform* platform);
|
||||||
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
#include "FFPlatform_private.h"
|
#include "FFPlatform_private.h"
|
||||||
#include "util/FFstrbuf.h"
|
#include "common/FFstrbuf.h"
|
||||||
#include "util/stringUtils.h"
|
#include "common/stringUtils.h"
|
||||||
|
#include "common/io.h"
|
||||||
#include "fastfetch_config.h"
|
#include "fastfetch_config.h"
|
||||||
#include "common/io/io.h"
|
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
#include "FFPlatform_private.h"
|
#include "FFPlatform_private.h"
|
||||||
#include "common/io/io.h"
|
#include "common/io.h"
|
||||||
#include "common/library.h"
|
#include "common/library.h"
|
||||||
#include "util/stringUtils.h"
|
#include "common/stringUtils.h"
|
||||||
#include "util/windows/unicode.h"
|
#include "common/windows/unicode.h"
|
||||||
#include "util/windows/registry.h"
|
#include "common/windows/registry.h"
|
||||||
#include "util/windows/nt.h"
|
#include "common/windows/nt.h"
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "FFlist.h"
|
#include "common/FFlist.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "FFstrbuf.h"
|
#include "common/FFstrbuf.h"
|
||||||
|
#include "common/mallocHelper.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
@@ -21,11 +22,27 @@ void ffStrbufInitVF(FFstrbuf* strbuf, const char* format, va_list arguments)
|
|||||||
{
|
{
|
||||||
assert(format != NULL);
|
assert(format != NULL);
|
||||||
|
|
||||||
int len = vasprintf(&strbuf->chars, format, arguments);
|
char* buffer = NULL;
|
||||||
|
int len = vasprintf(&buffer, format, arguments);
|
||||||
assert(len >= 0);
|
assert(len >= 0);
|
||||||
|
|
||||||
strbuf->allocated = (uint32_t)(len + 1);
|
ffStrbufInitMoveNS(strbuf, (uint32_t)len, buffer);
|
||||||
strbuf->length = (uint32_t)len;
|
}
|
||||||
|
|
||||||
|
// Takes ownership of `heapStr`. The caller must not free `heapStr` after calling this
|
||||||
|
// function; the memory will be managed and freed via the associated FFstrbuf.
|
||||||
|
void ffStrbufInitMoveNS(FFstrbuf* strbuf, uint32_t length, char* heapStr)
|
||||||
|
{
|
||||||
|
assert(heapStr != NULL);
|
||||||
|
|
||||||
|
strbuf->length = length;
|
||||||
|
size_t allocSize = ffMallocUsableSize(heapStr);
|
||||||
|
if (allocSize == 0)
|
||||||
|
allocSize = length + 1;
|
||||||
|
else if (allocSize > UINT32_MAX)
|
||||||
|
allocSize = UINT32_MAX;
|
||||||
|
strbuf->allocated = (uint32_t) allocSize;
|
||||||
|
strbuf->chars = heapStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free)
|
void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free)
|
||||||
@@ -55,6 +72,7 @@ void ffStrbufEnsureFree(FFstrbuf* strbuf, uint32_t free)
|
|||||||
strbuf->allocated = allocate;
|
strbuf->allocated = allocate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure that at least `free` bytes are available in the buffer besides the current length
|
||||||
// for an empty buffer, free + 1 length memory will be allocated(+1 for the NUL)
|
// for an empty buffer, free + 1 length memory will be allocated(+1 for the NUL)
|
||||||
void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free)
|
void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free)
|
||||||
{
|
{
|
||||||
@@ -148,7 +166,7 @@ void ffStrbufAppendVF(FFstrbuf* strbuf, const char* format, va_list arguments)
|
|||||||
uint32_t free = ffStrbufGetFree(strbuf);
|
uint32_t free = ffStrbufGetFree(strbuf);
|
||||||
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 && strbuf->length + (uint32_t) written > free)
|
if(written > 0 && (uint32_t) written > free)
|
||||||
{
|
{
|
||||||
ffStrbufEnsureFree(strbuf, (uint32_t) written);
|
ffStrbufEnsureFree(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);
|
||||||
@@ -220,6 +238,55 @@ void ffStrbufPrependC(FFstrbuf* strbuf, char c)
|
|||||||
strbuf->length += 1;
|
strbuf->length += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ffStrbufSetNS(FFstrbuf* strbuf, uint32_t length, const char* value)
|
||||||
|
{
|
||||||
|
assert(strbuf != NULL);
|
||||||
|
|
||||||
|
if (length == 0)
|
||||||
|
{
|
||||||
|
ffStrbufClear(strbuf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(value != NULL);
|
||||||
|
|
||||||
|
if (strbuf->allocated < length + 1)
|
||||||
|
{
|
||||||
|
if (strbuf->allocated > 0)
|
||||||
|
free(strbuf->chars);
|
||||||
|
strbuf->allocated = length + 1;
|
||||||
|
strbuf->chars = malloc(sizeof(char) * strbuf->allocated);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(strbuf->chars, value, length);
|
||||||
|
strbuf->length = length;
|
||||||
|
strbuf->chars[length] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
void ffStrbufSet(FFstrbuf* strbuf, const FFstrbuf* value)
|
||||||
|
{
|
||||||
|
assert(value && value != strbuf);
|
||||||
|
|
||||||
|
if (value->length == 0)
|
||||||
|
{
|
||||||
|
ffStrbufClear(strbuf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value->allocated == 0) // static string
|
||||||
|
{
|
||||||
|
if (strbuf->allocated != 0)
|
||||||
|
{
|
||||||
|
free(strbuf->chars);
|
||||||
|
strbuf->allocated = 0;
|
||||||
|
}
|
||||||
|
strbuf->chars = value->chars;
|
||||||
|
strbuf->length = value->length;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ffStrbufSetNS(strbuf, value->length, value->chars);
|
||||||
|
}
|
||||||
|
|
||||||
void ffStrbufTrimLeft(FFstrbuf* strbuf, char c)
|
void ffStrbufTrimLeft(FFstrbuf* strbuf, char c)
|
||||||
{
|
{
|
||||||
if(strbuf->length == 0)
|
if(strbuf->length == 0)
|
||||||
@@ -381,7 +448,15 @@ void ffStrbufReplaceAllC(FFstrbuf* strbuf, char find, char replace)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
ffStrbufEnsureFree(strbuf, 0);
|
ffStrbufEnsureFree(strbuf, 0);
|
||||||
for (char *current_pos = strchr(strbuf->chars, find); current_pos; current_pos = strchr(current_pos + 1, find))
|
for (
|
||||||
|
char *current_pos = memchr(strbuf->chars, find, strbuf->length);
|
||||||
|
current_pos;
|
||||||
|
current_pos = memchr(
|
||||||
|
current_pos + 1,
|
||||||
|
find,
|
||||||
|
strbuf->length - (uint32_t)(current_pos + 1 - strbuf->chars)
|
||||||
|
)
|
||||||
|
)
|
||||||
*current_pos = replace;
|
*current_pos = replace;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "base64.h"
|
#include "common/base64.h"
|
||||||
|
|
||||||
// https://github.com/kostya/benchmarks/blob/master/base64/test-nolib.c#L145
|
// https://github.com/kostya/benchmarks/blob/master/base64/test-nolib.c#L145
|
||||||
void ffBase64EncodeRaw(uint32_t size, const char *str, uint32_t *out_size, char *output)
|
void ffBase64EncodeRaw(uint32_t size, const char *str, uint32_t *out_size, char *output)
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "binary.h"
|
#include "common/binary.h"
|
||||||
#include "common/io/io.h"
|
#include "common/io.h"
|
||||||
#include "util/stringUtils.h"
|
#include "common/stringUtils.h"
|
||||||
#include "util/mallocHelper.h"
|
#include "common/mallocHelper.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
#include "binary.h"
|
#include "common/binary.h"
|
||||||
|
|
||||||
#if defined(FF_HAVE_ELF) || defined(__sun) || (defined(__FreeBSD__) && !defined(__DragonFly__)) || defined(__OpenBSD__) || defined(__NetBSD__)
|
#if defined(FF_HAVE_ELF) || defined(__sun) || (defined(__FreeBSD__) && !defined(__DragonFly__)) || defined(__OpenBSD__) || defined(__NetBSD__)
|
||||||
|
|
||||||
#include "common/io/io.h"
|
#include "common/io.h"
|
||||||
#include "common/library.h"
|
#include "common/library.h"
|
||||||
#include "util/stringUtils.h"
|
#include "common/stringUtils.h"
|
||||||
|
|
||||||
#include <libelf.h> // #1254
|
#include <libelf.h> // #1254
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@@ -42,7 +42,7 @@ const char* ffBinaryExtractStrings(const char* elfFile, bool (*cb)(const char* s
|
|||||||
if (!elfData.inited)
|
if (!elfData.inited)
|
||||||
{
|
{
|
||||||
elfData.inited = true;
|
elfData.inited = true;
|
||||||
FF_LIBRARY_LOAD(libelf, "dlopen libelf" FF_LIBRARY_EXTENSION " failed", "libelf" FF_LIBRARY_EXTENSION, 1);
|
FF_LIBRARY_LOAD_MESSAGE(libelf, "libelf" FF_LIBRARY_EXTENSION, 1);
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libelf, elfData, elf_version)
|
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libelf, elfData, elf_version)
|
||||||
if (elfData.ffelf_version(EV_CURRENT) == EV_NONE) return "elf_version() failed";
|
if (elfData.ffelf_version(EV_CURRENT) == EV_NONE) return "elf_version() failed";
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "binary.h"
|
#include "common/binary.h"
|
||||||
#include "common/io/io.h"
|
#include "common/io.h"
|
||||||
#include "util/stringUtils.h"
|
#include "common/stringUtils.h"
|
||||||
#include "util/mallocHelper.h"
|
#include "common/mallocHelper.h"
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <imagehlp.h>
|
#include <imagehlp.h>
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
#include "commandoption.h"
|
#include "common/commandoption.h"
|
||||||
#include "common/color.h"
|
#include "common/color.h"
|
||||||
#include "common/printing.h"
|
#include "common/printing.h"
|
||||||
#include "common/time.h"
|
#include "common/time.h"
|
||||||
#include "common/jsonconfig.h"
|
#include "common/jsonconfig.h"
|
||||||
|
#include "common/stringUtils.h"
|
||||||
#include "fastfetch_datatext.h"
|
#include "fastfetch_datatext.h"
|
||||||
#include "modules/modules.h"
|
#include "modules/modules.h"
|
||||||
#include "util/stringUtils.h"
|
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
#include "dbus.h"
|
#include "common/dbus.h"
|
||||||
|
|
||||||
#ifdef FF_HAVE_DBUS
|
#ifdef FF_HAVE_DBUS
|
||||||
|
|
||||||
#include "common/thread.h"
|
#include "common/thread.h"
|
||||||
#include "util/stringUtils.h"
|
#include "common/stringUtils.h"
|
||||||
|
|
||||||
static bool loadLibSymbols(FFDBusLibrary* lib)
|
static bool loadLibSymbols(FFDBusLibrary* lib)
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "debug.h"
|
#include "common/debug.h"
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "duration.h"
|
#include "common/duration.h"
|
||||||
|
|
||||||
void ffDurationAppendNum(uint64_t totalSeconds, FFstrbuf* result)
|
void ffDurationAppendNum(uint64_t totalSeconds, FFstrbuf* result)
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "edidHelper.h"
|
#include "common/edidHelper.h"
|
||||||
|
|
||||||
void ffEdidGetPhysicalResolution(const uint8_t edid[128], uint32_t* width, uint32_t* height)
|
void ffEdidGetPhysicalResolution(const uint8_t edid[128], uint32_t* width, uint32_t* height)
|
||||||
{
|
{
|
||||||
@@ -0,0 +1,520 @@
|
|||||||
|
#include "fastfetch.h"
|
||||||
|
#include "common/FFlist.h"
|
||||||
|
#include "common/FFstrbuf.h"
|
||||||
|
#include "common/stringUtils.h"
|
||||||
|
#include "common/font.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
void ffFontInit(FFfont* font)
|
||||||
|
{
|
||||||
|
// Ensure no memory allocates
|
||||||
|
ffStrbufInit(&font->pretty);
|
||||||
|
ffStrbufInit(&font->name);
|
||||||
|
ffStrbufInit(&font->size);
|
||||||
|
ffListInit(&font->styles, sizeof(FFstrbuf));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void strbufAppendNSExcludingC(FFstrbuf* strbuf, uint32_t length, const char* value, char exclude)
|
||||||
|
{
|
||||||
|
if(value == NULL || length == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ffStrbufEnsureFree(strbuf, length);
|
||||||
|
|
||||||
|
for(uint32_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
if(value[i] != exclude)
|
||||||
|
strbuf->chars[strbuf->length++] = value[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
strbuf->chars[strbuf->length] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fontInitPretty(FFfont* font)
|
||||||
|
{
|
||||||
|
ffStrbufAppend(&font->pretty, &font->name);
|
||||||
|
|
||||||
|
if(font->size.length == 0 && font->styles.length == 0)
|
||||||
|
return;
|
||||||
|
else if(font->pretty.length == 0)
|
||||||
|
ffStrbufAppendS(&font->pretty, "default");
|
||||||
|
|
||||||
|
ffStrbufAppendS(&font->pretty, " (");
|
||||||
|
|
||||||
|
if(font->size.length > 0)
|
||||||
|
{
|
||||||
|
ffStrbufAppend(&font->pretty, &font->size);
|
||||||
|
if (!ffStrbufEndsWithS(&font->size, "pt") && !ffStrbufEndsWithS(&font->size, "px"))
|
||||||
|
ffStrbufAppendS(&font->pretty, "pt");
|
||||||
|
|
||||||
|
if(font->styles.length > 0)
|
||||||
|
ffStrbufAppendS(&font->pretty, ", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
for(uint32_t i = 0; i < font->styles.length; i++)
|
||||||
|
{
|
||||||
|
ffStrbufAppend(&font->pretty, FF_LIST_GET(FFstrbuf, font->styles, i));
|
||||||
|
|
||||||
|
if(i < font->styles.length - 1)
|
||||||
|
ffStrbufAppendS(&font->pretty, ", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
ffStrbufAppendC(&font->pretty, ')');
|
||||||
|
}
|
||||||
|
|
||||||
|
void ffFontInitQt(FFfont* font, const char* data)
|
||||||
|
{
|
||||||
|
ffFontInit(font);
|
||||||
|
|
||||||
|
//See https://doc.qt.io/qt-5/qfont.html#toString
|
||||||
|
|
||||||
|
//Family
|
||||||
|
data = ffStrbufAppendSUntilC(&font->name, data, ',');
|
||||||
|
ffStrbufTrim(&font->name, ' ');
|
||||||
|
if (!data) goto exit;
|
||||||
|
data++;
|
||||||
|
|
||||||
|
//Size
|
||||||
|
data = ffStrbufAppendSUntilC(&font->size, data, ',');
|
||||||
|
ffStrbufTrim(&font->size, ' ');
|
||||||
|
if (!data) goto exit;
|
||||||
|
data++;
|
||||||
|
|
||||||
|
//Style
|
||||||
|
data = strrchr(data, ',');
|
||||||
|
if (!data) goto exit;
|
||||||
|
data++;
|
||||||
|
if (isalpha(*data))
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
FFstrbuf* style = (FFstrbuf*) ffListAdd(&font->styles);
|
||||||
|
ffStrbufInit(style);
|
||||||
|
data = ffStrbufAppendSUntilC(style, data, ' ');
|
||||||
|
if (data) data++;
|
||||||
|
} while (data);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
fontInitPretty(font);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fontPangoParseWord(const char** data, FFfont* font, FFstrbuf* alternativeBuffer)
|
||||||
|
{
|
||||||
|
while(**data == ' ' || **data == '\t' || **data == ',')
|
||||||
|
++(*data);
|
||||||
|
|
||||||
|
const char* wordStart = *data;
|
||||||
|
|
||||||
|
while(**data != ' ' && **data != '\t' && **data != ',' && **data != '\0' && **data != '`' && **data != '\\')
|
||||||
|
++(*data);
|
||||||
|
|
||||||
|
uint32_t wordLength = (uint32_t) (*data - wordStart);
|
||||||
|
if(wordLength == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(**data == '\0' || **data == '`' || **data == '\\')
|
||||||
|
{
|
||||||
|
ffStrbufAppendNS(&font->size, wordLength, wordStart);
|
||||||
|
if(ffStrbufEndsWithS(&font->size, "px"))
|
||||||
|
ffStrbufSubstrBefore(&font->size, font->size.length - 2);
|
||||||
|
|
||||||
|
double dummy;
|
||||||
|
if(sscanf(font->size.chars, "%lf", &dummy) == 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ffStrbufClear(&font->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(
|
||||||
|
ffStrStartsWithIgnCase(wordStart, "Ultra") ||
|
||||||
|
ffStrStartsWithIgnCase(wordStart, "Extra") ||
|
||||||
|
ffStrStartsWithIgnCase(wordStart, "Semi") ||
|
||||||
|
ffStrStartsWithIgnCase(wordStart, "Demi") ||
|
||||||
|
ffStrStartsWithIgnCase(wordStart, "Normal") ||
|
||||||
|
ffStrStartsWithIgnCase(wordStart, "Roman") ||
|
||||||
|
ffStrStartsWithIgnCase(wordStart, "Oblique") ||
|
||||||
|
ffStrStartsWithIgnCase(wordStart, "Italic") ||
|
||||||
|
ffStrStartsWithIgnCase(wordStart, "Thin") ||
|
||||||
|
ffStrStartsWithIgnCase(wordStart, "Light") ||
|
||||||
|
ffStrStartsWithIgnCase(wordStart, "Bold") ||
|
||||||
|
ffStrStartsWithIgnCase(wordStart, "Black") ||
|
||||||
|
ffStrStartsWithIgnCase(wordStart, "Condensed") ||
|
||||||
|
ffStrStartsWithIgnCase(wordStart, "Expanded")
|
||||||
|
) {
|
||||||
|
if(alternativeBuffer == NULL)
|
||||||
|
{
|
||||||
|
alternativeBuffer = (FFstrbuf*) ffListAdd(&font->styles);
|
||||||
|
ffStrbufInit(alternativeBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
strbufAppendNSExcludingC(alternativeBuffer, wordLength, wordStart, '-');
|
||||||
|
|
||||||
|
if(
|
||||||
|
ffStrStartsWithIgnCase(wordStart, "Ultra ") ||
|
||||||
|
ffStrStartsWithIgnCase(wordStart, "Extra ") ||
|
||||||
|
ffStrStartsWithIgnCase(wordStart, "Semi ") ||
|
||||||
|
ffStrStartsWithIgnCase(wordStart, "Demi ")
|
||||||
|
) {
|
||||||
|
fontPangoParseWord(data, font, alternativeBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(alternativeBuffer != NULL)
|
||||||
|
{
|
||||||
|
strbufAppendNSExcludingC(alternativeBuffer, wordLength, wordStart, '-');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(font->name.length > 0)
|
||||||
|
ffStrbufAppendC(&font->name, ' ');
|
||||||
|
ffStrbufAppendNS(&font->name, wordLength, wordStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ffFontInitPango(FFfont* font, const char* data)
|
||||||
|
{
|
||||||
|
ffFontInit(font);
|
||||||
|
|
||||||
|
while(*data != '\0' && *data != '`' && *data != '\\')
|
||||||
|
fontPangoParseWord(&data, font, NULL);
|
||||||
|
|
||||||
|
fontInitPretty(font);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ffFontInitValues(FFfont* font, const char* name, const char* size)
|
||||||
|
{
|
||||||
|
ffFontInit(font);
|
||||||
|
|
||||||
|
ffStrbufAppendS(&font->name, name);
|
||||||
|
ffStrbufTrim(&font->name, '"');
|
||||||
|
ffStrbufAppendS(&font->size, size);
|
||||||
|
|
||||||
|
fontInitPretty(font);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ffFontInitXlfd(FFfont* font, const char* xlfd)
|
||||||
|
{
|
||||||
|
assert(xlfd && *xlfd);
|
||||||
|
|
||||||
|
// https://en.wikipedia.org/wiki/X_logical_font_description
|
||||||
|
ffFontInit(font);
|
||||||
|
|
||||||
|
// XLFD: -foundry-family-weight-slant-setwidth-addstyle-pixelsize-pointsize-xres-yres-spacing-averagewidth-charsetregistry-charsetencoding
|
||||||
|
// It often starts with '-', which would create an empty first field. Skip it to align indexes.
|
||||||
|
if(*xlfd == '-')
|
||||||
|
xlfd++;
|
||||||
|
|
||||||
|
const char* pstart = xlfd;
|
||||||
|
|
||||||
|
for(int field = 0; field < 14; field++)
|
||||||
|
{
|
||||||
|
const char* pend = strchr(pstart, '-');
|
||||||
|
uint32_t length = pend ? (uint32_t)(pend - pstart) : (uint32_t) strlen(pstart);
|
||||||
|
|
||||||
|
if(length > 0)
|
||||||
|
{
|
||||||
|
if(field == 1) // family
|
||||||
|
{
|
||||||
|
ffStrbufAppendNS(&font->name, length, pstart);
|
||||||
|
}
|
||||||
|
else if(field == 7) // pointsize (decipoints, preferred)
|
||||||
|
{
|
||||||
|
// parse positive integer from substring
|
||||||
|
long deciPt = 0;
|
||||||
|
bool ok = true;
|
||||||
|
for(uint32_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
char c = pstart[i];
|
||||||
|
if(c < '0' || c > '9') { ok = false; break; }
|
||||||
|
deciPt = deciPt * 10 + (c - '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ok && deciPt > 0)
|
||||||
|
{
|
||||||
|
ffStrbufClear(&font->size);
|
||||||
|
|
||||||
|
char tmp[32];
|
||||||
|
if(deciPt % 10 == 0)
|
||||||
|
snprintf(tmp, sizeof(tmp), "%ldpt", deciPt / 10);
|
||||||
|
else
|
||||||
|
snprintf(tmp, sizeof(tmp), "%ld.%ldpt", deciPt / 10, deciPt % 10);
|
||||||
|
|
||||||
|
ffStrbufAppendS(&font->size, tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(field == 6) // pixelsize (fallback if pointsize missing/invalid)
|
||||||
|
{
|
||||||
|
if(font->size.length == 0)
|
||||||
|
{
|
||||||
|
long px = 0;
|
||||||
|
bool ok = true;
|
||||||
|
for(uint32_t i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
char c = pstart[i];
|
||||||
|
if(c < '0' || c > '9') { ok = false; break; }
|
||||||
|
px = px * 10 + (c - '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ok && px > 0)
|
||||||
|
{
|
||||||
|
ffStrbufAppendNS(&font->size, length, pstart);
|
||||||
|
ffStrbufAppendS(&font->size, "px");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(field >= 2 && field <= 5) // weight/slant/setwidth/addstyle
|
||||||
|
{
|
||||||
|
// ignore "normal" (case-insensitive)
|
||||||
|
if(!(length == 6 && ffStrStartsWithIgnCase(pstart, "normal")))
|
||||||
|
{
|
||||||
|
FFstrbuf* style = (FFstrbuf*) ffListAdd(&font->styles);
|
||||||
|
ffStrbufInitNS(style, length, pstart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!pend)
|
||||||
|
break;
|
||||||
|
|
||||||
|
pstart = pend + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fontInitPretty(font);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ffFontInitXft(FFfont* font, const char* xft)
|
||||||
|
{
|
||||||
|
assert(xft);
|
||||||
|
|
||||||
|
// https://en.wikipedia.org/wiki/Xft
|
||||||
|
// Xft/Fontconfig pattern examples:
|
||||||
|
// "DejaVu Sans Mono-10"
|
||||||
|
// "monospace:size=10:weight=bold:slant=italic"
|
||||||
|
// "Fira Code-12:style=Regular"
|
||||||
|
// Goal: extract family(name), size, and some common styles.
|
||||||
|
|
||||||
|
ffFontInit(font);
|
||||||
|
|
||||||
|
// 1) Parse "head" part before first ':' => usually "family[-size]" (may include commas)
|
||||||
|
const char* p = xft;
|
||||||
|
|
||||||
|
while(*p == ' ' || *p == '\t')
|
||||||
|
++p;
|
||||||
|
|
||||||
|
const char* headStart = p;
|
||||||
|
while(*p != '\0' && *p != ':')
|
||||||
|
++p;
|
||||||
|
const char* headEnd = p;
|
||||||
|
|
||||||
|
// trim tail spaces
|
||||||
|
while(headEnd > headStart && (headEnd[-1] == ' ' || headEnd[-1] == '\t'))
|
||||||
|
--headEnd;
|
||||||
|
|
||||||
|
// If multiple families are listed, take the first one (up to comma)
|
||||||
|
for(const char* q = headStart; q < headEnd; ++q)
|
||||||
|
{
|
||||||
|
if(*q == ',')
|
||||||
|
{
|
||||||
|
headEnd = q;
|
||||||
|
while(headEnd > headStart && (headEnd[-1] == ' ' || headEnd[-1] == '\t'))
|
||||||
|
--headEnd;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try parse trailing "-<number>" as size, otherwise entire head is name
|
||||||
|
const char* dashPos = NULL;
|
||||||
|
const char* sizeStart = NULL;
|
||||||
|
|
||||||
|
for(const char* q = headEnd; q > headStart; )
|
||||||
|
{
|
||||||
|
--q;
|
||||||
|
if(*q == '-' && (q + 1) < headEnd && ffCharIsDigit(q[1]))
|
||||||
|
{
|
||||||
|
dashPos = q;
|
||||||
|
sizeStart = q + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dashPos)
|
||||||
|
{
|
||||||
|
bool ok = true;
|
||||||
|
bool seenDigit = false;
|
||||||
|
for(const char* q = sizeStart; q < headEnd; ++q)
|
||||||
|
{
|
||||||
|
if(ffCharIsDigit(*q))
|
||||||
|
seenDigit = true;
|
||||||
|
else if(*q == '.')
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ok = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ok && seenDigit)
|
||||||
|
{
|
||||||
|
const char* nameEnd = dashPos;
|
||||||
|
while(nameEnd > headStart && (nameEnd[-1] == ' ' || nameEnd[-1] == '\t'))
|
||||||
|
--nameEnd;
|
||||||
|
|
||||||
|
if(nameEnd > headStart)
|
||||||
|
ffStrbufAppendNS(&font->name, (uint32_t) (nameEnd - headStart), headStart);
|
||||||
|
|
||||||
|
if(headEnd > sizeStart)
|
||||||
|
ffStrbufAppendNS(&font->size, (uint32_t) (headEnd - sizeStart), sizeStart);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(headEnd > headStart)
|
||||||
|
ffStrbufAppendNS(&font->name, (uint32_t) (headEnd - headStart), headStart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(headEnd > headStart)
|
||||||
|
ffStrbufAppendNS(&font->name, (uint32_t) (headEnd - headStart), headStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
ffStrbufTrim(&font->name, ' ');
|
||||||
|
ffStrbufTrim(&font->name, '"');
|
||||||
|
|
||||||
|
// 2) Parse key=value fields after ':' (Fontconfig-like). Fields separated by ':'.
|
||||||
|
// Common keys: size, pixelsize, pointsize, style, weight, slant, width
|
||||||
|
while(*p == ':')
|
||||||
|
{
|
||||||
|
++p;
|
||||||
|
|
||||||
|
// key
|
||||||
|
const char* keyStart = p;
|
||||||
|
while(*p != '\0' && *p != '=' && *p != ':')
|
||||||
|
++p;
|
||||||
|
const char* keyEnd = p;
|
||||||
|
|
||||||
|
if(*p != '=')
|
||||||
|
continue; // skip tokens without '='
|
||||||
|
|
||||||
|
++p; // skip '='
|
||||||
|
|
||||||
|
// value (until next ':', allow backslash-escaping)
|
||||||
|
FF_STRBUF_AUTO_DESTROY value = ffStrbufCreate();
|
||||||
|
|
||||||
|
while(*p != '\0' && *p != ':')
|
||||||
|
{
|
||||||
|
if(*p == '\\' && p[1] != '\0')
|
||||||
|
{
|
||||||
|
++p;
|
||||||
|
ffStrbufAppendC(&value, *p);
|
||||||
|
++p;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ffStrbufAppendC(&value, *p);
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
ffStrbufTrim(&value, ' ');
|
||||||
|
ffStrbufTrim(&value, '"');
|
||||||
|
|
||||||
|
uint32_t keyLen = (uint32_t) (keyEnd - keyStart);
|
||||||
|
|
||||||
|
// helper: set numeric size if not set yet
|
||||||
|
const bool sizeEmpty = (font->size.length == 0);
|
||||||
|
if(value.length > 0)
|
||||||
|
{
|
||||||
|
if(
|
||||||
|
(keyLen == 4 && ffStrStartsWithIgnCase(keyStart, "size")) ||
|
||||||
|
(keyLen == 9 && ffStrStartsWithIgnCase(keyStart, "pixelsize"))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if(sizeEmpty && ffCharIsDigit(value.chars[0]))
|
||||||
|
{
|
||||||
|
ffStrbufAppend(&font->size, &value);
|
||||||
|
ffStrbufAppendS(&font->size, keyLen == 4 ? "pt" : "px");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(keyLen == 5 && ffStrStartsWithIgnCase(keyStart, "style"))
|
||||||
|
{
|
||||||
|
// style may contain multiple words: "Bold Italic"
|
||||||
|
const char* s = value.chars;
|
||||||
|
while(*s != '\0')
|
||||||
|
{
|
||||||
|
while(*s == ' ' || *s == '\t' || *s == ',')
|
||||||
|
++s;
|
||||||
|
|
||||||
|
const char* w = s;
|
||||||
|
while(*s != '\0' && *s != ' ' && *s != '\t' && *s != ',')
|
||||||
|
++s;
|
||||||
|
|
||||||
|
if(s > w)
|
||||||
|
{
|
||||||
|
FFstrbuf* style = FF_LIST_ADD(FFstrbuf, font->styles);
|
||||||
|
ffStrbufInitNS(style, (uint32_t) (s - w), w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(
|
||||||
|
(keyLen == 6 && ffStrStartsWithIgnCase(keyStart, "weight")) ||
|
||||||
|
(keyLen == 5 && ffStrStartsWithIgnCase(keyStart, "slant")) ||
|
||||||
|
(keyLen == 5 && ffStrStartsWithIgnCase(keyStart, "width"))
|
||||||
|
) {
|
||||||
|
// normalize: remove '-' to align with other parsers ("Semi-Bold" -> "SemiBold")
|
||||||
|
FFstrbuf* style = FF_LIST_ADD(FFstrbuf, font->styles);
|
||||||
|
ffStrbufInit(style);
|
||||||
|
strbufAppendNSExcludingC(style, value.length, value.chars, '-');
|
||||||
|
ffStrbufTrim(style, ' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fontInitPretty(font);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ffFontInitMoveValues(FFfont* font, FFstrbuf* name, FFstrbuf* size, FFstrbuf* style)
|
||||||
|
{
|
||||||
|
ffFontInit(font);
|
||||||
|
|
||||||
|
if (name) ffStrbufInitMove(&font->name, name);
|
||||||
|
if (size) ffStrbufInitMove(&font->size, size);
|
||||||
|
if (style)
|
||||||
|
{
|
||||||
|
FFstrbuf* styleBuf = FF_LIST_ADD(FFstrbuf, font->styles);
|
||||||
|
ffStrbufInitMove(styleBuf, style);
|
||||||
|
}
|
||||||
|
|
||||||
|
fontInitPretty(font);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ffFontInitWithSpace(FFfont* font, const char* rawName)
|
||||||
|
{
|
||||||
|
const char* pspace = strrchr(rawName, ' ');
|
||||||
|
if(pspace == NULL)
|
||||||
|
{
|
||||||
|
ffFontInitCopy(font, rawName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ffFontInit(font);
|
||||||
|
|
||||||
|
ffStrbufAppendNS(&font->name, (uint32_t)(pspace - rawName), rawName);
|
||||||
|
ffStrbufAppendS(&font->size, pspace + 1);
|
||||||
|
|
||||||
|
fontInitPretty(font);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ffFontDestroy(FFfont* font)
|
||||||
|
{
|
||||||
|
ffStrbufDestroy(&font->pretty);
|
||||||
|
ffStrbufDestroy(&font->name);
|
||||||
|
ffStrbufDestroy(&font->size);
|
||||||
|
|
||||||
|
FF_LIST_FOR_EACH(FFstrbuf, str, font->styles)
|
||||||
|
ffStrbufDestroy(str);
|
||||||
|
ffListDestroy(&font->styles);
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
#include "fastfetch.h"
|
#include "fastfetch.h"
|
||||||
#include "common/format.h"
|
#include "common/format.h"
|
||||||
#include "common/parsing.h"
|
#include "common/parsing.h"
|
||||||
#include "util/textModifier.h"
|
#include "common/textModifier.h"
|
||||||
#include "util/stringUtils.h"
|
#include "common/stringUtils.h"
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "frequency.h"
|
#include "common/frequency.h"
|
||||||
|
|
||||||
bool ffFreqAppendNum(uint32_t mhz, FFstrbuf* result)
|
bool ffFreqAppendNum(uint32_t mhz, FFstrbuf* result)
|
||||||
{
|
{
|
||||||
@@ -2,9 +2,9 @@
|
|||||||
#include "common/init.h"
|
#include "common/init.h"
|
||||||
#include "common/parsing.h"
|
#include "common/parsing.h"
|
||||||
#include "common/thread.h"
|
#include "common/thread.h"
|
||||||
|
#include "common/textModifier.h"
|
||||||
#include "detection/displayserver/displayserver.h"
|
#include "detection/displayserver/displayserver.h"
|
||||||
#include "detection/terminaltheme/terminaltheme.h"
|
#include "detection/terminaltheme/terminaltheme.h"
|
||||||
#include "util/textModifier.h"
|
|
||||||
#include "logo/logo.h"
|
#include "logo/logo.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "util/windows/unicode.h"
|
#include "common/windows/unicode.h"
|
||||||
#else
|
#else
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -262,6 +262,9 @@ void ffListFeatures(void)
|
|||||||
#if FF_HAVE_EMBEDDED_PCIIDS
|
#if FF_HAVE_EMBEDDED_PCIIDS
|
||||||
"Embedded pciids\n"
|
"Embedded pciids\n"
|
||||||
#endif
|
#endif
|
||||||
|
#if FF_WIN7_COMPAT
|
||||||
|
"Windows 7 Compatibility\n"
|
||||||
|
#endif
|
||||||
""
|
""
|
||||||
, stdout);
|
, stdout);
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "io.h"
|
#include "common/io.h"
|
||||||
#include "fastfetch.h"
|
#include "fastfetch.h"
|
||||||
#include "util/stringUtils.h"
|
#include "common/stringUtils.h"
|
||||||
#include "common/time.h"
|
#include "common/time.h"
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
#include "io.h"
|
#include "common/io.h"
|
||||||
#include "fastfetch.h"
|
#include "fastfetch.h"
|
||||||
#include "util/stringUtils.h"
|
#include "common/stringUtils.h"
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "util/windows/nt.h"
|
#include "common/windows/nt.h"
|
||||||
#include <ntstatus.h>
|
#include <ntstatus.h>
|
||||||
|
|
||||||
static void createSubfolders(const char* fileName)
|
static void createSubfolders(const char* fileName)
|
||||||
@@ -2,11 +2,11 @@
|
|||||||
#include "common/color.h"
|
#include "common/color.h"
|
||||||
#include "common/jsonconfig.h"
|
#include "common/jsonconfig.h"
|
||||||
#include "common/printing.h"
|
#include "common/printing.h"
|
||||||
#include "common/io/io.h"
|
#include "common/io.h"
|
||||||
#include "common/time.h"
|
#include "common/time.h"
|
||||||
|
#include "common/stringUtils.h"
|
||||||
#include "detection/version/version.h"
|
#include "detection/version/version.h"
|
||||||
#include "modules/modules.h"
|
#include "modules/modules.h"
|
||||||
#include "util/stringUtils.h"
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "kmod.h"
|
#include "common/kmod.h"
|
||||||
|
|
||||||
#if __linux__
|
#if __linux__
|
||||||
#include "common/io/io.h"
|
#include "common/io.h"
|
||||||
|
|
||||||
bool ffKmodLoaded(const char* modName)
|
bool ffKmodLoaded(const char* modName)
|
||||||
{
|
{
|
||||||
@@ -32,7 +32,7 @@ bool ffKmodLoaded(const char* modName)
|
|||||||
return modfind(modName) >= 0;
|
return modfind(modName) >= 0;
|
||||||
}
|
}
|
||||||
#elif __NetBSD__
|
#elif __NetBSD__
|
||||||
#include "util/stringUtils.h"
|
#include "common/stringUtils.h"
|
||||||
|
|
||||||
#include <sys/module.h>
|
#include <sys/module.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@@ -75,7 +75,7 @@ bool ffKmodLoaded(const char* modName)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#elif __APPLE__
|
#elif __APPLE__
|
||||||
#include "util/apple/cf_helpers.h"
|
#include "common/apple/cf_helpers.h"
|
||||||
#include <IOKit/kext/KextManager.h>
|
#include <IOKit/kext/KextManager.h>
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "netif.h"
|
#include "common/netif.h"
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
#include "netif.h"
|
#include "common/netif.h"
|
||||||
|
#include "common/io.h"
|
||||||
#include "common/io/io.h"
|
#include "common/mallocHelper.h"
|
||||||
#include "util/mallocHelper.h"
|
|
||||||
|
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <net/if_dl.h>
|
#include <net/if_dl.h>
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
#include "netif.h"
|
#include "common/netif.h"
|
||||||
|
#include "common/io.h"
|
||||||
#include "common/io/io.h"
|
#include "common/mallocHelper.h"
|
||||||
#include "util/mallocHelper.h"
|
|
||||||
|
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <net/if_dl.h>
|
#include <net/if_dl.h>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#include "netif.h"
|
#include "common/netif.h"
|
||||||
#include "common/io/io.h"
|
#include "common/io.h"
|
||||||
|
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "netif.h"
|
#include "common/netif.h"
|
||||||
#include "common/io/io.h"
|
#include "common/io.h"
|
||||||
#include "util/mallocHelper.h"
|
#include "common/mallocHelper.h"
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "netif.h"
|
#include "common/netif.h"
|
||||||
#include "common/io/io.h"
|
#include "common/io.h"
|
||||||
#include "util/mallocHelper.h"
|
#include "common/mallocHelper.h"
|
||||||
#include "util/debug.h"
|
#include "common/debug.h"
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <linux/rtnetlink.h>
|
#include <linux/rtnetlink.h>
|
||||||
@@ -151,6 +151,12 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Skip local/loopback routes
|
||||||
|
if (rtm->rtm_scope == RT_SCOPE_HOST || rtm->rtm_type == RTN_LOCAL) {
|
||||||
|
FF_DEBUG("Skipping local route #%d (scope=%d, type=%d)", routeCount, rtm->rtm_scope, rtm->rtm_type);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
@@ -360,6 +366,12 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Skip local/loopback routes
|
||||||
|
if (rtm->rtm_scope == RT_SCOPE_HOST || rtm->rtm_type == RTN_LOCAL) {
|
||||||
|
FF_DEBUG("Skipping local route #%d (scope=%d, type=%d)", routeCount, rtm->rtm_scope, rtm->rtm_type);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#include "netif.h"
|
#include "common/netif.h"
|
||||||
#include "util/mallocHelper.h"
|
#include "common/mallocHelper.h"
|
||||||
|
|
||||||
#include <ws2tcpip.h> // AF_INET6, IN6_IS_ADDR_UNSPECIFIED
|
#include <ws2tcpip.h> // AF_INET6, IN6_IS_ADDR_UNSPECIFIED
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
#include "fastfetch.h"
|
#include "fastfetch.h"
|
||||||
#include "common/library.h"
|
#include "common/library.h"
|
||||||
#include "common/networking/networking.h"
|
#include "common/networking.h"
|
||||||
#include "util/stringUtils.h"
|
#include "common/stringUtils.h"
|
||||||
#include "util/debug.h"
|
#include "common/debug.h"
|
||||||
|
|
||||||
#ifdef FF_HAVE_ZLIB
|
#ifdef FF_HAVE_ZLIB
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
@@ -12,7 +12,6 @@ struct FFZlibLibrary
|
|||||||
FF_LIBRARY_SYMBOL(inflateInit2_)
|
FF_LIBRARY_SYMBOL(inflateInit2_)
|
||||||
FF_LIBRARY_SYMBOL(inflate)
|
FF_LIBRARY_SYMBOL(inflate)
|
||||||
FF_LIBRARY_SYMBOL(inflateEnd)
|
FF_LIBRARY_SYMBOL(inflateEnd)
|
||||||
FF_LIBRARY_SYMBOL(inflateGetHeader)
|
|
||||||
|
|
||||||
bool inited;
|
bool inited;
|
||||||
} zlibData;
|
} zlibData;
|
||||||
@@ -22,7 +21,7 @@ const char* ffNetworkingLoadZlibLibrary(void)
|
|||||||
if (!zlibData.inited)
|
if (!zlibData.inited)
|
||||||
{
|
{
|
||||||
zlibData.inited = true;
|
zlibData.inited = true;
|
||||||
FF_LIBRARY_LOAD(zlib, "dlopen libz failed",
|
FF_LIBRARY_LOAD_MESSAGE(zlib,
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
"zlib1"
|
"zlib1"
|
||||||
#else
|
#else
|
||||||
@@ -32,7 +31,6 @@ 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)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(zlib, zlibData, inflateGetHeader)
|
|
||||||
zlib = NULL; // don't auto dlclose
|
zlib = NULL; // don't auto dlclose
|
||||||
}
|
}
|
||||||
return zlibData.ffinflateEnd == NULL ? "Failed to load libz" : NULL;
|
return zlibData.ffinflateEnd == NULL ? "Failed to load libz" : NULL;
|
||||||
@@ -69,6 +67,8 @@ 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');
|
||||||
|
|
||||||
// Calculate header size
|
// Calculate header size
|
||||||
uint32_t headerSize = (uint32_t) (headerEnd - buffer->chars);
|
uint32_t headerSize = (uint32_t) (headerEnd - buffer->chars);
|
||||||
|
|
||||||
@@ -86,15 +86,15 @@ bool ffNetworkingDecompressGzip(FFstrbuf* buffer, char* headerEnd)
|
|||||||
|
|
||||||
const char* bodyStart = headerEnd + 4; // Skip delimiter
|
const char* bodyStart = headerEnd + 4; // Skip delimiter
|
||||||
|
|
||||||
// Calculate compressed content size
|
if (buffer->length <= headerSize + 4) {
|
||||||
uint32_t compressedSize = buffer->length - headerSize - 4;
|
|
||||||
|
|
||||||
if (compressedSize <= 0) {
|
|
||||||
// No content to decompress
|
// No content to decompress
|
||||||
FF_DEBUG("Compressed content size is 0, skipping decompression");
|
FF_DEBUG("Compressed content size is 0, skipping decompression");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate compressed content size
|
||||||
|
uint32_t compressedSize = buffer->length - headerSize - 4;
|
||||||
|
|
||||||
// Check if content is actually in gzip format (gzip header magic is 0x1f 0x8b)
|
// Check if content is actually in gzip format (gzip header magic is 0x1f 0x8b)
|
||||||
if (compressedSize < 2 || (uint8_t)bodyStart[0] != 0x1f || (uint8_t)bodyStart[1] != 0x8b) {
|
if (compressedSize < 2 || (uint8_t)bodyStart[0] != 0x1f || (uint8_t)bodyStart[1] != 0x8b) {
|
||||||
FF_DEBUG("Content is not valid gzip format, skipping decompression");
|
FF_DEBUG("Content is not valid gzip format, skipping decompression");
|
||||||
@@ -137,7 +137,7 @@ bool ffNetworkingDecompressGzip(FFstrbuf* buffer, char* headerEnd)
|
|||||||
// Save already decompressed data amount
|
// Save already decompressed data amount
|
||||||
uint32_t alreadyDecompressed = (uint32_t)(availableOut - zs.avail_out);
|
uint32_t alreadyDecompressed = (uint32_t)(availableOut - zs.avail_out);
|
||||||
decompressedBuffer.length += alreadyDecompressed;
|
decompressedBuffer.length += alreadyDecompressed;
|
||||||
decompressedBuffer.chars[decompressedBuffer.length] = '\0'; // Ensure null-terminated string
|
decompressedBuffer.chars[decompressedBuffer.length] = '\0';
|
||||||
|
|
||||||
ffStrbufEnsureFree(&decompressedBuffer, decompressedBuffer.length / 2);
|
ffStrbufEnsureFree(&decompressedBuffer, decompressedBuffer.length / 2);
|
||||||
|
|
||||||
@@ -155,7 +155,7 @@ bool ffNetworkingDecompressGzip(FFstrbuf* buffer, char* headerEnd)
|
|||||||
// Calculate decompressed size
|
// Calculate decompressed size
|
||||||
uint32_t decompressedSize = (uint32_t)(availableOut - zs.avail_out);
|
uint32_t decompressedSize = (uint32_t)(availableOut - zs.avail_out);
|
||||||
decompressedBuffer.length += decompressedSize;
|
decompressedBuffer.length += decompressedSize;
|
||||||
decompressedBuffer.chars[decompressedSize] = '\0'; // Ensure null-terminated string
|
decompressedBuffer.chars[decompressedBuffer.length] = '\0';
|
||||||
FF_DEBUG("Successfully decompressed %u bytes compressed data to %u bytes", compressedSize, decompressedBuffer.length);
|
FF_DEBUG("Successfully decompressed %u bytes compressed data to %u bytes", compressedSize, decompressedBuffer.length);
|
||||||
|
|
||||||
// Modify Content-Length header and remove Content-Encoding header
|
// Modify Content-Length header and remove Content-Encoding header
|
||||||
@@ -171,7 +171,7 @@ bool ffNetworkingDecompressGzip(FFstrbuf* buffer, char* headerEnd)
|
|||||||
}
|
}
|
||||||
else if (ffStrStartsWithIgnCase(line, "Content-Length:"))
|
else if (ffStrStartsWithIgnCase(line, "Content-Length:"))
|
||||||
{
|
{
|
||||||
ffStrbufAppendF(&newBuffer, "Content-Length: %u\r\n", decompressedSize);
|
ffStrbufAppendF(&newBuffer, "Content-Length: %u\r\n", decompressedBuffer.length);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (line[0] == '\r')
|
else if (line[0] == '\r')
|
||||||
@@ -181,7 +181,7 @@ bool ffNetworkingDecompressGzip(FFstrbuf* buffer, char* headerEnd)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ffStrbufAppendS(&newBuffer, line);
|
ffStrbufAppendS(&newBuffer, line); // Including the trailing \r
|
||||||
ffStrbufAppendC(&newBuffer, '\n');
|
ffStrbufAppendC(&newBuffer, '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
#include "fastfetch.h"
|
#include "fastfetch.h"
|
||||||
#include "common/networking/networking.h"
|
#include "common/networking.h"
|
||||||
#include "common/time.h"
|
#include "common/time.h"
|
||||||
#include "common/library.h"
|
#include "common/library.h"
|
||||||
#include "util/stringUtils.h"
|
#include "common/stringUtils.h"
|
||||||
#include "util/mallocHelper.h"
|
#include "common/mallocHelper.h"
|
||||||
#include "util/debug.h"
|
#include "common/debug.h"
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
@@ -34,11 +34,7 @@ static const char* tryNonThreadingFastPath(FFNetworkingState* state)
|
|||||||
|
|
||||||
#ifndef __APPLE__ // On macOS, TCP_FASTOPEN doesn't seem to be needed
|
#ifndef __APPLE__ // On macOS, TCP_FASTOPEN doesn't seem to be needed
|
||||||
// Set TCP Fast Open
|
// Set TCP Fast Open
|
||||||
#if __linux__ || __GNU__
|
int flag = 1;
|
||||||
int flag = 5; // the queue length of pending packets
|
|
||||||
#else
|
|
||||||
int flag = 1; // enable TCP Fast Open
|
|
||||||
#endif
|
|
||||||
if (setsockopt(state->sockfd, IPPROTO_TCP,
|
if (setsockopt(state->sockfd, IPPROTO_TCP,
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
// https://github.com/rust-lang/libc/pull/3135
|
// https://github.com/rust-lang/libc/pull/3135
|
||||||
@@ -186,15 +182,12 @@ static const char* initNetworkingState(FFNetworkingState* state, const char* hos
|
|||||||
FF_DEBUG("Initializing network connection state: host=%s, path=%s", host, path);
|
FF_DEBUG("Initializing network connection state: host=%s, path=%s", host, path);
|
||||||
|
|
||||||
// Initialize command and host information
|
// Initialize command and host information
|
||||||
ffStrbufInitA(&state->command, 64);
|
ffStrbufInitA(&state->command, 128);
|
||||||
ffStrbufAppendS(&state->command, "GET ");
|
ffStrbufAppendS(&state->command, "GET ");
|
||||||
ffStrbufAppendS(&state->command, path);
|
ffStrbufAppendS(&state->command, path);
|
||||||
ffStrbufAppendS(&state->command, " HTTP/1.0\nHost: ");
|
ffStrbufAppendS(&state->command, " HTTP/1.0\r\nHost: ");
|
||||||
ffStrbufAppendS(&state->command, host);
|
ffStrbufAppendS(&state->command, host);
|
||||||
ffStrbufAppendS(&state->command, "\r\n");
|
ffStrbufAppendS(&state->command, "\r\nConnection: close\r\n"); // Explicitly tell the server we don't need to keep the connection
|
||||||
|
|
||||||
// Add extra optimized HTTP headers
|
|
||||||
ffStrbufAppendS(&state->command, "Connection: close\r\n"); // Explicitly tell the server we don't need to keep the connection
|
|
||||||
|
|
||||||
// If compression needs to be enabled
|
// If compression needs to be enabled
|
||||||
if (state->compression) {
|
if (state->compression) {
|
||||||
@@ -221,9 +214,10 @@ static const char* initNetworkingState(FFNetworkingState* state, const char* hos
|
|||||||
FF_DEBUG("Resolving address: %s (%s)", host, state->ipv6 ? "IPv6" : "IPv4");
|
FF_DEBUG("Resolving address: %s (%s)", host, state->ipv6 ? "IPv6" : "IPv4");
|
||||||
// Use AI_NUMERICSERV flag to indicate the service is a numeric port, reducing parsing time
|
// Use AI_NUMERICSERV flag to indicate the service is a numeric port, reducing parsing time
|
||||||
|
|
||||||
if(getaddrinfo(host, "80", &hints, &state->addr) != 0)
|
int gaiRes = getaddrinfo(host, "80", &hints, &state->addr);
|
||||||
|
if(gaiRes != 0)
|
||||||
{
|
{
|
||||||
FF_DEBUG("getaddrinfo() failed: %s", gai_strerror(errno));
|
FF_DEBUG("getaddrinfo() failed: %s (res=%d)", gai_strerror(gaiRes), gaiRes);
|
||||||
ret = "getaddrinfo() failed";
|
ret = "getaddrinfo() failed";
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@@ -360,6 +354,7 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
|
|||||||
|
|
||||||
const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer)
|
const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer)
|
||||||
{
|
{
|
||||||
|
assert(buffer->allocated > 0);
|
||||||
FF_DEBUG("Preparing to receive HTTP response");
|
FF_DEBUG("Preparing to receive HTTP response");
|
||||||
uint32_t timeout = state->timeout;
|
uint32_t timeout = state->timeout;
|
||||||
|
|
||||||
@@ -390,15 +385,25 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
// poll for the socket to be readable.
|
// poll for the socket to be readable.
|
||||||
// Because of the non-blocking connectx() call, the connection might not be established yet
|
// Because of the non-blocking connectx() call, the connection might not be established yet
|
||||||
FF_DEBUG("Using poll() to check if socket is readable");
|
FF_DEBUG("Using poll() to check if socket is readable");
|
||||||
if (poll(&(struct pollfd) {
|
|
||||||
.fd = state->sockfd,
|
|
||||||
.events = POLLIN
|
|
||||||
}, 1, timeout > 0 ? (int) timeout : -1) == -1)
|
|
||||||
{
|
{
|
||||||
FF_DEBUG("poll() failed: %s (errno=%d)", strerror(errno), errno);
|
int pollRes = poll(&(struct pollfd) {
|
||||||
close(state->sockfd);
|
.fd = state->sockfd,
|
||||||
state->sockfd = -1;
|
.events = POLLIN
|
||||||
return "poll() failed";
|
}, 1, timeout > 0 ? (int) timeout : -1);
|
||||||
|
if (pollRes == 0)
|
||||||
|
{
|
||||||
|
FF_DEBUG("poll() timed out after %u ms", timeout);
|
||||||
|
close(state->sockfd);
|
||||||
|
state->sockfd = -1;
|
||||||
|
return "poll() timeout";
|
||||||
|
}
|
||||||
|
else if (pollRes == -1)
|
||||||
|
{
|
||||||
|
FF_DEBUG("poll() failed: %s (errno=%d)", strerror(errno), errno);
|
||||||
|
close(state->sockfd);
|
||||||
|
state->sockfd = -1;
|
||||||
|
return "poll() failed";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
FF_DEBUG("Socket is readable, proceeding to receive data");
|
FF_DEBUG("Socket is readable, proceeding to receive data");
|
||||||
#else
|
#else
|
||||||
@@ -415,12 +420,14 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
FF_DEBUG("Starting data reception");
|
FF_DEBUG("Starting data reception");
|
||||||
FF_MAYBE_UNUSED int recvCount = 0;
|
FF_MAYBE_UNUSED int recvCount = 0;
|
||||||
uint32_t contentLength = 0;
|
uint32_t contentLength = 0;
|
||||||
char* headerEnd = NULL;
|
uint32_t headerEnd = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
FF_DEBUG("Data reception loop #%d, current buffer size: %u, available space: %u",
|
FF_DEBUG("Data reception loop #%d, current buffer size: %u, available space: %u",
|
||||||
++recvCount, buffer->length, ffStrbufGetFree(buffer));
|
++recvCount, buffer->length, ffStrbufGetFree(buffer));
|
||||||
|
|
||||||
|
// We set `Connection: close`, so the server will close the connection when done.
|
||||||
|
// Thus we can use MSG_WAITALL to wait until the buffer is full or the connection is closed.
|
||||||
ssize_t received = recv(state->sockfd, buffer->chars + buffer->length, ffStrbufGetFree(buffer), MSG_WAITALL);
|
ssize_t received = recv(state->sockfd, buffer->chars + buffer->length, ffStrbufGetFree(buffer), MSG_WAITALL);
|
||||||
|
|
||||||
if (received <= 0) {
|
if (received <= 0) {
|
||||||
@@ -438,10 +445,11 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
FF_DEBUG("Successfully received %zd bytes of data, total: %u bytes", received, buffer->length);
|
FF_DEBUG("Successfully received %zd bytes of data, total: %u bytes", received, buffer->length);
|
||||||
|
|
||||||
// Check if HTTP header end marker is found
|
// Check if HTTP header end marker is found
|
||||||
if (headerEnd == NULL) {
|
if (headerEnd == 0) {
|
||||||
headerEnd = memmem(buffer->chars, buffer->length, "\r\n\r\n", 4);
|
char* pHeaderEnd = memmem(buffer->chars, buffer->length, "\r\n\r\n", 4);
|
||||||
if (headerEnd != NULL) {
|
if (pHeaderEnd) {
|
||||||
FF_DEBUG("Found HTTP header end marker, position: %ld", (long)(headerEnd - buffer->chars));
|
headerEnd = (uint32_t)(pHeaderEnd - buffer->chars);
|
||||||
|
FF_DEBUG("Found HTTP header end marker, position: %u", headerEnd);
|
||||||
|
|
||||||
// Check for Content-Length header to pre-allocate enough memory
|
// 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:");
|
||||||
@@ -451,7 +459,7 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
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);
|
||||||
FF_DEBUG("Extended receive buffer to %u bytes", buffer->length);
|
FF_DEBUG("Extended receive buffer to %u bytes", buffer->allocated);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -467,12 +475,12 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
return "Empty server response received";
|
return "Empty server response received";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (headerEnd == NULL) {
|
if (headerEnd == 0) {
|
||||||
FF_DEBUG("No HTTP header end marker found");
|
FF_DEBUG("No HTTP header end marker found");
|
||||||
return "No HTTP header end found";
|
return "No HTTP header end found";
|
||||||
}
|
}
|
||||||
if (contentLength > 0 && buffer->length != contentLength + (uint32_t)(headerEnd - buffer->chars) + 4) {
|
if (contentLength > 0 && buffer->length != contentLength + headerEnd + 4) {
|
||||||
FF_DEBUG("Received content length mismatches: %u != %u", buffer->length, contentLength + (uint32_t)(headerEnd - buffer->chars) + 4);
|
FF_DEBUG("Received content length mismatches: %u != %u", buffer->length, contentLength + headerEnd + 4);
|
||||||
return "Content length mismatch";
|
return "Content length mismatch";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -487,7 +495,7 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
#ifdef FF_HAVE_ZLIB
|
#ifdef FF_HAVE_ZLIB
|
||||||
if (state->compression) {
|
if (state->compression) {
|
||||||
FF_DEBUG("Content received, checking if compressed");
|
FF_DEBUG("Content received, checking if compressed");
|
||||||
if (!ffNetworkingDecompressGzip(buffer, headerEnd)) {
|
if (!ffNetworkingDecompressGzip(buffer, buffer->chars + headerEnd)) {
|
||||||
FF_DEBUG("Decompression failed or invalid compression format");
|
FF_DEBUG("Decompression failed or invalid compression format");
|
||||||
return "Failed to decompress or invalid format";
|
return "Failed to decompress or invalid format";
|
||||||
} else {
|
} else {
|
||||||
@@ -3,9 +3,9 @@
|
|||||||
|
|
||||||
//Must be included after <mswsock.h>
|
//Must be included after <mswsock.h>
|
||||||
#include "fastfetch.h"
|
#include "fastfetch.h"
|
||||||
#include "common/networking/networking.h"
|
#include "common/networking.h"
|
||||||
#include "util/stringUtils.h"
|
#include "common/stringUtils.h"
|
||||||
#include "util/debug.h"
|
#include "common/debug.h"
|
||||||
|
|
||||||
static LPFN_CONNECTEX ConnectEx;
|
static LPFN_CONNECTEX ConnectEx;
|
||||||
|
|
||||||
@@ -19,6 +19,7 @@ static const char* initWsaData(WSADATA* wsaData)
|
|||||||
|
|
||||||
if(LOBYTE(wsaData->wVersion) != 2 || HIBYTE(wsaData->wVersion) != 2) {
|
if(LOBYTE(wsaData->wVersion) != 2 || HIBYTE(wsaData->wVersion) != 2) {
|
||||||
FF_DEBUG("Invalid wsaData version found: %d.%d", LOBYTE(wsaData->wVersion), HIBYTE(wsaData->wVersion));
|
FF_DEBUG("Invalid wsaData version found: %d.%d", LOBYTE(wsaData->wVersion), HIBYTE(wsaData->wVersion));
|
||||||
|
WSACleanup();
|
||||||
return "Invalid wsaData version found";
|
return "Invalid wsaData version found";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,6 +27,7 @@ static const char* initWsaData(WSADATA* wsaData)
|
|||||||
SOCKET sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
SOCKET sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
if(sockfd == INVALID_SOCKET) {
|
if(sockfd == INVALID_SOCKET) {
|
||||||
FF_DEBUG("socket(AF_INET, SOCK_STREAM) failed");
|
FF_DEBUG("socket(AF_INET, SOCK_STREAM) failed");
|
||||||
|
WSACleanup();
|
||||||
return "socket(AF_INET, SOCK_STREAM) failed";
|
return "socket(AF_INET, SOCK_STREAM) failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,6 +38,8 @@ static const char* initWsaData(WSADATA* wsaData)
|
|||||||
&ConnectEx, sizeof(ConnectEx),
|
&ConnectEx, sizeof(ConnectEx),
|
||||||
&dwBytes, NULL, NULL) != 0) {
|
&dwBytes, NULL, NULL) != 0) {
|
||||||
FF_DEBUG("WSAIoctl(sockfd, SIO_GET_EXTENSION_FUNCTION_POINTER) failed");
|
FF_DEBUG("WSAIoctl(sockfd, SIO_GET_EXTENSION_FUNCTION_POINTER) failed");
|
||||||
|
closesocket(sockfd);
|
||||||
|
WSACleanup();
|
||||||
return "WSAIoctl(sockfd, SIO_GET_EXTENSION_FUNCTION_POINTER) failed";
|
return "WSAIoctl(sockfd, SIO_GET_EXTENSION_FUNCTION_POINTER) failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,26 +148,35 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
|
|||||||
return "bind() failed";
|
return "bind() failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize overlapped structure for asynchronous I/O
|
// Initialize overlapped structure with WSA event for asynchronous I/O
|
||||||
memset(&state->overlapped, 0, sizeof(OVERLAPPED));
|
state->overlapped = (OVERLAPPED){
|
||||||
|
.hEvent = WSACreateEvent()
|
||||||
|
};
|
||||||
|
|
||||||
|
if (state->overlapped.hEvent == WSA_INVALID_EVENT) {
|
||||||
|
FF_DEBUG("WSACreateEvent() failed");
|
||||||
|
closesocket(state->sockfd);
|
||||||
|
freeaddrinfo(addr);
|
||||||
|
state->sockfd = INVALID_SOCKET;
|
||||||
|
return "WSACreateEvent() failed";
|
||||||
|
}
|
||||||
|
|
||||||
// Build HTTP command
|
// Build HTTP command
|
||||||
FF_STRBUF_AUTO_DESTROY command = ffStrbufCreateA(64);
|
ffStrbufInitA(&state->command, 128);
|
||||||
ffStrbufAppendS(&command, "GET ");
|
ffStrbufAppendS(&state->command, "GET ");
|
||||||
ffStrbufAppendS(&command, path);
|
ffStrbufAppendS(&state->command, path);
|
||||||
ffStrbufAppendS(&command, " HTTP/1.0\nHost: ");
|
ffStrbufAppendS(&state->command, " HTTP/1.0\r\nHost: ");
|
||||||
ffStrbufAppendS(&command, host);
|
ffStrbufAppendS(&state->command, host);
|
||||||
ffStrbufAppendS(&command, "\r\n");
|
ffStrbufAppendS(&state->command, "\r\nConnection: close\r\n"); // Explicitly request connection closure
|
||||||
ffStrbufAppendS(&command, "Connection: close\r\n"); // Explicitly request connection closure
|
|
||||||
|
|
||||||
// Add compression support if enabled
|
// Add compression support if enabled
|
||||||
if (state->compression) {
|
if (state->compression) {
|
||||||
FF_DEBUG("Enabling HTTP content compression");
|
FF_DEBUG("Enabling HTTP content compression");
|
||||||
ffStrbufAppendS(&command, "Accept-Encoding: gzip\r\n");
|
ffStrbufAppendS(&state->command, "Accept-Encoding: gzip\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
ffStrbufAppendS(&command, headers);
|
ffStrbufAppendS(&state->command, headers);
|
||||||
ffStrbufAppendS(&command, "\r\n");
|
ffStrbufAppendS(&state->command, "\r\n");
|
||||||
|
|
||||||
#ifdef TCP_FASTOPEN
|
#ifdef TCP_FASTOPEN
|
||||||
if (state->tfo)
|
if (state->tfo)
|
||||||
@@ -182,10 +195,10 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FF_DEBUG("Using ConnectEx to send %u bytes of data", command.length);
|
FF_DEBUG("Using ConnectEx to send %u bytes of data", state->command.length);
|
||||||
DWORD sent = 0;
|
DWORD sent = 0;
|
||||||
BOOL result = ConnectEx(state->sockfd, addr->ai_addr, (int)addr->ai_addrlen,
|
BOOL result = ConnectEx(state->sockfd, addr->ai_addr, (int)addr->ai_addrlen,
|
||||||
command.chars, command.length, &sent, &state->overlapped);
|
state->command.chars, state->command.length, &sent, &state->overlapped);
|
||||||
|
|
||||||
freeaddrinfo(addr);
|
freeaddrinfo(addr);
|
||||||
addr = NULL;
|
addr = NULL;
|
||||||
@@ -195,8 +208,10 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
|
|||||||
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);
|
||||||
closesocket(state->sockfd);
|
closesocket(state->sockfd);
|
||||||
state->sockfd = INVALID_SOCKET;
|
state->sockfd = INVALID_SOCKET;
|
||||||
|
ffStrbufDestroy(&state->command);
|
||||||
return "ConnectEx() failed";
|
return "ConnectEx() failed";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -215,6 +230,7 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
|
|||||||
|
|
||||||
const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer)
|
const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer)
|
||||||
{
|
{
|
||||||
|
assert(buffer->allocated > 0);
|
||||||
FF_DEBUG("Preparing to receive HTTP response");
|
FF_DEBUG("Preparing to receive HTTP response");
|
||||||
|
|
||||||
if (state->sockfd == INVALID_SOCKET)
|
if (state->sockfd == INVALID_SOCKET)
|
||||||
@@ -226,13 +242,20 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
uint32_t timeout = state->timeout;
|
uint32_t timeout = state->timeout;
|
||||||
if (timeout > 0)
|
if (timeout > 0)
|
||||||
{
|
{
|
||||||
FF_DEBUG("WaitForSingleObject with timeout: %u ms", timeout);
|
FF_DEBUG("WSAWaitForMultipleEvents with timeout: %u ms", timeout);
|
||||||
if (WaitForSingleObject((HANDLE)state->sockfd, timeout) != WAIT_OBJECT_0)
|
DWORD result = WSAWaitForMultipleEvents(1, &state->overlapped.hEvent, TRUE, timeout, FALSE);
|
||||||
|
if (result != WSA_WAIT_EVENT_0)
|
||||||
{
|
{
|
||||||
FF_DEBUG("WaitForSingleObject failed or timed out");
|
if (result == WSA_WAIT_TIMEOUT) {
|
||||||
|
FF_DEBUG("WSAWaitForMultipleEvents timed out");
|
||||||
|
} else {
|
||||||
|
FF_DEBUG("WSAWaitForMultipleEvents failed: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
|
||||||
|
}
|
||||||
CancelIo((HANDLE) state->sockfd);
|
CancelIo((HANDLE) state->sockfd);
|
||||||
|
WSACloseEvent(state->overlapped.hEvent);
|
||||||
closesocket(state->sockfd);
|
closesocket(state->sockfd);
|
||||||
return "WaitForSingleObject(state->sockfd) failed or timeout";
|
ffStrbufDestroy(&state->command);
|
||||||
|
return "WSAWaitForMultipleEvents() failed or timeout";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,8 +264,20 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
{
|
{
|
||||||
FF_DEBUG("WSAGetOverlappedResult failed: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
|
FF_DEBUG("WSAGetOverlappedResult failed: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
|
||||||
closesocket(state->sockfd);
|
closesocket(state->sockfd);
|
||||||
|
WSACloseEvent(state->overlapped.hEvent);
|
||||||
|
ffStrbufDestroy(&state->command);
|
||||||
return "WSAGetOverlappedResult() failed";
|
return "WSAGetOverlappedResult() failed";
|
||||||
}
|
}
|
||||||
|
FF_DEBUG("WSAGetOverlappedResult succeeded, %u bytes sent", (unsigned) transfer);
|
||||||
|
ffStrbufDestroy(&state->command);
|
||||||
|
WSACloseEvent(state->overlapped.hEvent);
|
||||||
|
state->overlapped.hEvent = NULL;
|
||||||
|
|
||||||
|
if (setsockopt(state->sockfd, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0) != 0)
|
||||||
|
{
|
||||||
|
FF_DEBUG("Failed to update connect context: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
|
||||||
|
// Not a critical error, continue anyway
|
||||||
|
}
|
||||||
|
|
||||||
if(timeout > 0)
|
if(timeout > 0)
|
||||||
{
|
{
|
||||||
@@ -252,12 +287,16 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
|
|
||||||
// Set larger receive buffer for better performance
|
// Set larger receive buffer for better performance
|
||||||
int rcvbuf = 65536; // 64KB
|
int rcvbuf = 65536; // 64KB
|
||||||
setsockopt(state->sockfd, SOL_SOCKET, SO_RCVBUF, (const char*)&rcvbuf, sizeof(rcvbuf));
|
if (setsockopt(state->sockfd, SOL_SOCKET, SO_RCVBUF, (const char*)&rcvbuf, sizeof(rcvbuf)))
|
||||||
|
{
|
||||||
|
FF_DEBUG("Failed to set SO_RCVBUF: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
|
||||||
|
// Not a critical error, continue anyway
|
||||||
|
}
|
||||||
|
|
||||||
FF_DEBUG("Starting data reception");
|
FF_DEBUG("Starting data reception");
|
||||||
FF_MAYBE_UNUSED int recvCount = 0;
|
FF_MAYBE_UNUSED int recvCount = 0;
|
||||||
uint32_t contentLength = 0;
|
uint32_t contentLength = 0;
|
||||||
char* headerEnd = NULL;
|
uint32_t headerEnd = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
FF_DEBUG("Data reception loop #%d, current buffer size: %u, available space: %u",
|
FF_DEBUG("Data reception loop #%d, current buffer size: %u, available space: %u",
|
||||||
@@ -280,10 +319,11 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
FF_DEBUG("Successfully received %zd bytes of data, total: %u bytes", received, buffer->length);
|
FF_DEBUG("Successfully received %zd bytes of data, total: %u bytes", received, buffer->length);
|
||||||
|
|
||||||
// Check if HTTP header end marker is found
|
// Check if HTTP header end marker is found
|
||||||
if (headerEnd == NULL) {
|
if (headerEnd == 0) {
|
||||||
headerEnd = strstr(buffer->chars, "\r\n\r\n");
|
char* pHeaderEnd = strstr(buffer->chars, "\r\n\r\n");
|
||||||
if (headerEnd != NULL) {
|
if (pHeaderEnd) {
|
||||||
FF_DEBUG("Found HTTP header end marker, position: %ld", (long)(headerEnd - buffer->chars));
|
headerEnd = (uint32_t)(pHeaderEnd - buffer->chars);
|
||||||
|
FF_DEBUG("Found HTTP header end marker, position: %u", headerEnd);
|
||||||
|
|
||||||
// Check for Content-Length header to pre-allocate enough memory
|
// 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:");
|
||||||
@@ -309,10 +349,14 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
return "Empty server response received";
|
return "Empty server response received";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (headerEnd == NULL) {
|
if (headerEnd == 0) {
|
||||||
FF_DEBUG("No HTTP header end marker found");
|
FF_DEBUG("No HTTP header end marker found");
|
||||||
return "No HTTP header end found";
|
return "No HTTP header end found";
|
||||||
}
|
}
|
||||||
|
if (contentLength > 0 && buffer->length != contentLength + headerEnd + 4) {
|
||||||
|
FF_DEBUG("Received content length mismatches: %u != %u", buffer->length, contentLength + headerEnd + 4);
|
||||||
|
return "Content length mismatch";
|
||||||
|
}
|
||||||
|
|
||||||
if (ffStrbufStartsWithS(buffer, "HTTP/1.0 200 OK\r\n")) {
|
if (ffStrbufStartsWithS(buffer, "HTTP/1.0 200 OK\r\n")) {
|
||||||
FF_DEBUG("Received valid HTTP 200 response, content length: %u bytes, total length: %u bytes",
|
FF_DEBUG("Received valid HTTP 200 response, content length: %u bytes, total length: %u bytes",
|
||||||
@@ -326,7 +370,7 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
#ifdef FF_HAVE_ZLIB
|
#ifdef FF_HAVE_ZLIB
|
||||||
if (state->compression) {
|
if (state->compression) {
|
||||||
FF_DEBUG("Content received, checking if compressed");
|
FF_DEBUG("Content received, checking if compressed");
|
||||||
if (!ffNetworkingDecompressGzip(buffer, headerEnd)) {
|
if (!ffNetworkingDecompressGzip(buffer, buffer->chars + headerEnd)) {
|
||||||
FF_DEBUG("Decompression failed or invalid compression format");
|
FF_DEBUG("Decompression failed or invalid compression format");
|
||||||
return "Failed to decompress or invalid format";
|
return "Failed to decompress or invalid format";
|
||||||
} else {
|
} else {
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "fastfetch.h"
|
#include "fastfetch.h"
|
||||||
#include "common/option.h"
|
#include "common/option.h"
|
||||||
#include "common/color.h"
|
#include "common/color.h"
|
||||||
#include "util/stringUtils.h"
|
#include "common/stringUtils.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, NULL otherwise
|
||||||
const char* ffOptionTestPrefix(const char* argumentKey, const char* moduleName)
|
const char* ffOptionTestPrefix(const char* argumentKey, const char* moduleName)
|
||||||
@@ -166,6 +166,22 @@ void ffOptionParseColorNoClear(const char* value, FFstrbuf* buffer)
|
|||||||
exit(479);
|
exit(479);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (value[0] == '@')
|
||||||
|
{
|
||||||
|
// Xterm 256 color
|
||||||
|
++value;
|
||||||
|
char* pend = NULL;
|
||||||
|
uint32_t color = (uint32_t) strtoul(value, &pend, 10);
|
||||||
|
if (pend == value || color > 255) {
|
||||||
|
fprintf(stderr, "Error: invalid 256 color code found: %s\n", value);
|
||||||
|
exit(479);
|
||||||
|
}
|
||||||
|
|
||||||
|
ffStrbufAppendS(buffer, FF_COLOR_FG_256);
|
||||||
|
ffStrbufAppendUInt(buffer, color);
|
||||||
|
value = pend;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
else if (value[0] == '#')
|
else if (value[0] == '#')
|
||||||
{
|
{
|
||||||
// RGB color
|
// RGB color
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
#include "path.h"
|
#include "common/path.h"
|
||||||
|
#include "common/io.h"
|
||||||
#include "common/io/io.h"
|
#include "common/stringUtils.h"
|
||||||
#include "util/stringUtils.h"
|
|
||||||
|
|
||||||
#if !_WIN32
|
#if !_WIN32
|
||||||
const char* ffFindExecutableInPath(const char* name, FFstrbuf* result)
|
const char* ffFindExecutableInPath(const char* name, FFstrbuf* result)
|
||||||
@@ -3,8 +3,8 @@
|
|||||||
#include "common/color.h"
|
#include "common/color.h"
|
||||||
#include "common/option.h"
|
#include "common/option.h"
|
||||||
#include "common/jsonconfig.h"
|
#include "common/jsonconfig.h"
|
||||||
#include "util/textModifier.h"
|
#include "common/textModifier.h"
|
||||||
#include "util/stringUtils.h"
|
#include "common/stringUtils.h"
|
||||||
|
|
||||||
static void appendOutputColor(FFstrbuf* buffer, const FFModuleArgs* module)
|
static void appendOutputColor(FFstrbuf* buffer, const FFModuleArgs* module)
|
||||||
{
|
{
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "fastfetch.h"
|
#include "fastfetch.h"
|
||||||
#include "common/printing.h"
|
#include "common/printing.h"
|
||||||
|
#include "common/textModifier.h"
|
||||||
#include "logo/logo.h"
|
#include "logo/logo.h"
|
||||||
#include "util/textModifier.h"
|
|
||||||
|
|
||||||
void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType)
|
void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType)
|
||||||
{
|
{
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
#include "fastfetch.h"
|
#include "fastfetch.h"
|
||||||
#include "common/processing.h"
|
#include "common/processing.h"
|
||||||
#include "common/io/io.h"
|
#include "common/io.h"
|
||||||
#include "util/stringUtils.h"
|
#include "common/stringUtils.h"
|
||||||
#include "util/mallocHelper.h"
|
#include "common/mallocHelper.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -222,6 +222,7 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
|
|||||||
{
|
{
|
||||||
assert(processName->length > 0);
|
assert(processName->length > 0);
|
||||||
ffStrbufClear(exe);
|
ffStrbufClear(exe);
|
||||||
|
if (exePath) ffStrbufClear(exePath);
|
||||||
|
|
||||||
#if defined(__linux__) || defined(__GNU__)
|
#if defined(__linux__) || defined(__GNU__)
|
||||||
|
|
||||||
@@ -270,13 +271,14 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
|
|||||||
if (length > 0) // doesn't contain trailing NUL
|
if (length > 0) // doesn't contain trailing NUL
|
||||||
{
|
{
|
||||||
buf[length] = '\0';
|
buf[length] = '\0';
|
||||||
ffStrbufEnsureFixedLengthFree(exePath, (uint32_t)length);
|
// When the process is a deleted executable, the resolved path is like `/usr/bin/app (deleted)`
|
||||||
ffStrbufAppendNS(exePath, (uint32_t)length, buf);
|
// But we can still access the binary via `/proc/pid/exe`. See #2136
|
||||||
|
if (ffPathExists(buf, FF_PATHTYPE_ANY))
|
||||||
|
ffStrbufSetNS(exePath, (uint32_t)length, buf);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
if (exePath->length == 0)
|
||||||
ffStrbufSetS(exePath, filePath);
|
ffStrbufSetS(exePath, filePath);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
@@ -318,16 +320,21 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
|
|||||||
ffStrbufSetS(exe, arg0);
|
ffStrbufSetS(exe, arg0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (exePath || exe->length == 0)
|
||||||
{
|
{
|
||||||
char buf[PROC_PIDPATHINFO_MAXSIZE];
|
char buf[PROC_PIDPATHINFO_MAXSIZE];
|
||||||
int length = proc_pidpath(pid, buf, ARRAY_SIZE(buf));
|
int length = proc_pidpath(pid, buf, ARRAY_SIZE(buf));
|
||||||
if (length > 0)
|
if (length > 0)
|
||||||
{
|
{
|
||||||
ffStrbufEnsureFixedLengthFree(exe, (uint32_t) length);
|
if (exe->length == 0)
|
||||||
ffStrbufAppendNS(exe, (uint32_t) length, buf);
|
ffStrbufSetNS(exe, (uint32_t) length, buf);
|
||||||
if (exePath)
|
if (exePath)
|
||||||
ffStrbufSet(exePath, exe);
|
{
|
||||||
|
// We don't use exec_path above as exePath because it's a relative path and can be different
|
||||||
|
// from the actual executable being run (for example, when the original file is moved)
|
||||||
|
ffStrbufSetNS(exePath, (uint32_t) length, buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,8 +410,7 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
|
|||||||
if (length > 0) // doesn't contain trailing NUL
|
if (length > 0) // doesn't contain trailing NUL
|
||||||
{
|
{
|
||||||
buf[length] = '\0';
|
buf[length] = '\0';
|
||||||
ffStrbufEnsureFixedLengthFree(exePath, (uint32_t)length);
|
ffStrbufSetNS(exePath, (uint32_t)length, buf);
|
||||||
ffStrbufAppendNS(exePath, (uint32_t)length, buf);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "fastfetch.h"
|
#include "fastfetch.h"
|
||||||
#include "common/processing.h"
|
#include "common/processing.h"
|
||||||
#include "common/io/io.h"
|
#include "common/io.h"
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <ntstatus.h>
|
#include <ntstatus.h>
|
||||||
@@ -152,7 +152,7 @@ const char* ffProcessReadOutput(FFProcessHandle* handle, FFstrbuf* buffer)
|
|||||||
switch (GetLastError())
|
switch (GetLastError())
|
||||||
{
|
{
|
||||||
case ERROR_IO_PENDING:
|
case ERROR_IO_PENDING:
|
||||||
#if __aarch64__
|
#if !FF_WIN7_COMPAT
|
||||||
if (!GetOverlappedResultEx(hChildPipeRead, &overlapped, &nRead, timeout < 0 ? INFINITE : (DWORD) timeout, FALSE))
|
if (!GetOverlappedResultEx(hChildPipeRead, &overlapped, &nRead, timeout < 0 ? INFINITE : (DWORD) timeout, FALSE))
|
||||||
#else
|
#else
|
||||||
// To support Windows 7
|
// To support Windows 7
|
||||||
@@ -172,7 +172,7 @@ const char* ffProcessReadOutput(FFProcessHandle* handle, FFstrbuf* buffer)
|
|||||||
CancelIo(hChildPipeRead);
|
CancelIo(hChildPipeRead);
|
||||||
TerminateProcess(hProcess, 1);
|
TerminateProcess(hProcess, 1);
|
||||||
return "GetOverlappedResult"
|
return "GetOverlappedResult"
|
||||||
#if __aarch64__
|
#if !FF_WIN7_COMPAT
|
||||||
"Ex"
|
"Ex"
|
||||||
#endif
|
#endif
|
||||||
"(hChildPipeRead) failed";
|
"(hChildPipeRead) failed";
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
#include "fastfetch.h"
|
#include "fastfetch.h"
|
||||||
#include "common/properties.h"
|
#include "common/properties.h"
|
||||||
#include "common/io/io.h"
|
#include "common/io.h"
|
||||||
#include "util/mallocHelper.h"
|
#include "common/mallocHelper.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "util/windows/getline.h"
|
#include "common/windows/getline.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool ffParsePropLinePointer(const char** line, const char* start, FFstrbuf* buffer)
|
bool ffParsePropLinePointer(const char** line, const char* start, FFstrbuf* buffer)
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "common/library.h"
|
#include "common/library.h"
|
||||||
#include "common/thread.h"
|
#include "common/thread.h"
|
||||||
#include "common/io/io.h"
|
#include "common/io.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "size.h"
|
#include "common/size.h"
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
#include "smbiosHelper.h"
|
#include "common/smbiosHelper.h"
|
||||||
#include "common/io/io.h"
|
#include "common/io.h"
|
||||||
#include "util/unused.h"
|
#include "common/unused.h"
|
||||||
#include "util/mallocHelper.h"
|
#include "common/mallocHelper.h"
|
||||||
#include "util/debug.h"
|
#include "common/debug.h"
|
||||||
|
|
||||||
bool ffIsSmbiosValueSet(FFstrbuf* value)
|
bool ffIsSmbiosValueSet(FFstrbuf* value)
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "sysctl.h"
|
#include "common/sysctl.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "fastfetch.h"
|
#include "fastfetch.h"
|
||||||
#include "common/temps.h"
|
#include "common/temps.h"
|
||||||
#include "util/textModifier.h"
|
#include "common/textModifier.h"
|
||||||
#include "util/stringUtils.h"
|
#include "common/stringUtils.h"
|
||||||
|
|
||||||
void ffTempsAppendNum(double celsius, FFstrbuf* buffer, FFColorRangeConfig config, const FFModuleArgs* module)
|
void ffTempsAppendNum(double celsius, FFstrbuf* buffer, FFColorRangeConfig config, const FFModuleArgs* module)
|
||||||
{
|
{
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
#include "common/time.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
char ffTimeInternalBuffer[64]; // Reduce memory usage and prevent redundant allocations
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wformat"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char* ffTimeToFullStr(uint64_t msec)
|
||||||
|
{
|
||||||
|
if (msec == 0) return "";
|
||||||
|
time_t tsec = (time_t) (msec / 1000);
|
||||||
|
const struct tm* tm = localtime(&tsec);
|
||||||
|
|
||||||
|
uint32_t len = 0;
|
||||||
|
len += (uint32_t) strftime(ffTimeInternalBuffer, ARRAY_SIZE(ffTimeInternalBuffer) - len, "%FT%T", tm);
|
||||||
|
len += (uint32_t) snprintf(ffTimeInternalBuffer + len, ARRAY_SIZE(ffTimeInternalBuffer) - len, ".%03u", (unsigned) (msec % 1000));
|
||||||
|
len += (uint32_t) strftime(ffTimeInternalBuffer + len, ARRAY_SIZE(ffTimeInternalBuffer) - len, "%z", tm);
|
||||||
|
return ffTimeInternalBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* ffTimeToShortStr(uint64_t msec)
|
||||||
|
{
|
||||||
|
if (msec == 0) return "";
|
||||||
|
time_t tsec = (time_t) (msec / 1000);
|
||||||
|
|
||||||
|
strftime(ffTimeInternalBuffer, ARRAY_SIZE(ffTimeInternalBuffer), "%F %T", localtime(&tsec));
|
||||||
|
return ffTimeInternalBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* ffTimeToTimeStr(uint64_t msec)
|
||||||
|
{
|
||||||
|
if (msec == 0) return "";
|
||||||
|
time_t tsec = (time_t) (msec / 1000);
|
||||||
|
|
||||||
|
uint32_t len = (uint32_t) strftime(ffTimeInternalBuffer, ARRAY_SIZE(ffTimeInternalBuffer), "%T", localtime(&tsec));
|
||||||
|
sprintf(ffTimeInternalBuffer + len, ".%03u", (unsigned) (msec % 1000));
|
||||||
|
return ffTimeInternalBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FFTimeGetAgeResult ffTimeGetAge(uint64_t birthMs, uint64_t nowMs)
|
||||||
|
{
|
||||||
|
FFTimeGetAgeResult result = {};
|
||||||
|
if (__builtin_expect(birthMs == 0 || nowMs < birthMs, 0))
|
||||||
|
return result;
|
||||||
|
|
||||||
|
time_t birth_s = (time_t) (birthMs / 1000);
|
||||||
|
struct tm birth_tm;
|
||||||
|
#ifdef _WIN32
|
||||||
|
localtime_s(&birth_tm, &birth_s);
|
||||||
|
#else
|
||||||
|
localtime_r(&birth_s, &birth_tm);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
time_t now_s = (time_t) (nowMs / 1000);
|
||||||
|
struct tm now_tm;
|
||||||
|
#ifdef _WIN32
|
||||||
|
localtime_s(&now_tm, &now_s);
|
||||||
|
#else
|
||||||
|
localtime_r(&now_s, &now_tm);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
result.years = (uint32_t) (now_tm.tm_year - birth_tm.tm_year);
|
||||||
|
if (now_tm.tm_yday < birth_tm.tm_yday)
|
||||||
|
result.years--;
|
||||||
|
|
||||||
|
birth_tm.tm_year += (int) result.years;
|
||||||
|
birth_s = mktime(&birth_tm);
|
||||||
|
uint32_t diff_s = (uint32_t) (now_s - birth_s);
|
||||||
|
result.daysOfYear = diff_s / (24 * 60 * 60);
|
||||||
|
|
||||||
|
birth_tm.tm_year += 1;
|
||||||
|
result.yearsFraction = (double) diff_s / (double) (mktime(&birth_tm) - birth_s) + result.years;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "wcwidth.h"
|
#include "common/wcwidth.h"
|
||||||
#include "3rdparty/widecharwidth/widechar_width_c.h"
|
#include "3rdparty/widecharwidth/widechar_width_c.h"
|
||||||
|
|
||||||
int mk_wcwidth(uint32_t wc)
|
int mk_wcwidth(uint32_t wc)
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "util/FFstrbuf.h"
|
#include "common/FFstrbuf.h"
|
||||||
#include "util/FFlist.h"
|
#include "common/FFlist.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <fileapi.h>
|
#include <fileapi.h>
|
||||||
+12
-1
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "fastfetch.h"
|
#include "fastfetch.h"
|
||||||
#include "util/FFcheckmacros.h"
|
#include "common/FFcheckmacros.h"
|
||||||
|
|
||||||
#ifndef FF_DISABLE_DLOPEN
|
#ifndef FF_DISABLE_DLOPEN
|
||||||
|
|
||||||
@@ -38,6 +38,14 @@ static inline void ffLibraryUnload(void** handle)
|
|||||||
if(libraryObjectName == NULL) \
|
if(libraryObjectName == NULL) \
|
||||||
return returnValue;
|
return returnValue;
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
#define FF_LIBRARY_LOAD_MESSAGE(libraryObjectName, libraryFileName, maxVersion, ...) \
|
||||||
|
FF_LIBRARY_LOAD(libraryObjectName, "LoadLibraryA(" libraryFileName ") failed", libraryFileName, maxVersion, ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define FF_LIBRARY_LOAD_MESSAGE(libraryObjectName, libraryFileName, maxVersion, ...) \
|
||||||
|
FF_LIBRARY_LOAD(libraryObjectName, "dlopen(" libraryFileName ") failed", libraryFileName, maxVersion, ##__VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, symbolMapping, symbolName, returnValue) \
|
#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, symbolMapping, symbolName, returnValue) \
|
||||||
symbolMapping = (__typeof__(&symbolName)) dlsym(library, #symbolName); \
|
symbolMapping = (__typeof__(&symbolName)) dlsym(library, #symbolName); \
|
||||||
if(symbolMapping == NULL) \
|
if(symbolMapping == NULL) \
|
||||||
@@ -73,6 +81,9 @@ void* ffLibraryLoad(const char* path, int maxVersion, ...);
|
|||||||
#define FF_LIBRARY_LOAD(libraryObjectName, returnValue, ...) \
|
#define FF_LIBRARY_LOAD(libraryObjectName, returnValue, ...) \
|
||||||
FF_MAYBE_UNUSED void* libraryObjectName = NULL; // Placeholder
|
FF_MAYBE_UNUSED void* libraryObjectName = NULL; // Placeholder
|
||||||
|
|
||||||
|
#define FF_LIBRARY_LOAD_MESSAGE(libraryObjectName, libraryFileName, maxVersion, ...) \
|
||||||
|
FF_LIBRARY_LOAD(libraryObjectName, , libraryFileName, maxVersion, ##__VA_ARGS__)
|
||||||
|
|
||||||
#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, symbolMapping, symbolName, returnValue) \
|
#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, symbolMapping, symbolName, returnValue) \
|
||||||
symbolMapping = (__typeof__(&symbolName)) &symbolName;
|
symbolMapping = (__typeof__(&symbolName)) &symbolName;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#if FF_HAVE_MALLOC_USABLE_SIZE || FF_HAVE_MSVC_MSIZE
|
||||||
|
#if __has_include(<malloc.h>)
|
||||||
|
#include <malloc.h>
|
||||||
|
#else
|
||||||
|
#include <malloc_np.h> // For DragonFly BSD
|
||||||
|
#endif
|
||||||
|
#elif FF_HAVE_MALLOC_SIZE
|
||||||
|
#include <malloc/malloc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline void ffWrapFree(const void* pPtr)
|
||||||
|
{
|
||||||
|
assert(pPtr);
|
||||||
|
if(*(void**)pPtr)
|
||||||
|
free(*(void**)pPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FF_AUTO_FREE __attribute__((__cleanup__(ffWrapFree)))
|
||||||
|
|
||||||
|
// ptr MUST be a malloc'ed pointer
|
||||||
|
static inline size_t ffMallocUsableSize(const void* ptr)
|
||||||
|
{
|
||||||
|
assert(ptr);
|
||||||
|
#if FF_HAVE_MALLOC_USABLE_SIZE
|
||||||
|
return malloc_usable_size((void*) ptr);
|
||||||
|
#elif FF_HAVE_MALLOC_SIZE
|
||||||
|
return malloc_size((void*) ptr);
|
||||||
|
#elif FF_HAVE_MSVC_MSIZE
|
||||||
|
return _msize((void*) ptr);
|
||||||
|
#else
|
||||||
|
(void) ptr;
|
||||||
|
return 0; // Not supported
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/thread.h"
|
#include "common/thread.h"
|
||||||
#include "util/FFstrbuf.h"
|
#include "common/FFstrbuf.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <minwindef.h>
|
#include <minwindef.h>
|
||||||
@@ -15,7 +15,6 @@ typedef struct FFNetworkingState {
|
|||||||
OVERLAPPED overlapped;
|
OVERLAPPED overlapped;
|
||||||
#else
|
#else
|
||||||
int sockfd;
|
int sockfd;
|
||||||
FFstrbuf command;
|
|
||||||
struct addrinfo* addr;
|
struct addrinfo* addr;
|
||||||
|
|
||||||
#ifdef FF_HAVE_THREADS
|
#ifdef FF_HAVE_THREADS
|
||||||
@@ -23,6 +22,7 @@ typedef struct FFNetworkingState {
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
FFstrbuf command;
|
||||||
uint32_t timeout;
|
uint32_t timeout;
|
||||||
bool ipv6;
|
bool ipv6;
|
||||||
bool compression; // if true, HTTP content compression will be enabled if supported
|
bool compression; // if true, HTTP content compression will be enabled if supported
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "util/FFstrbuf.h"
|
#include "common/FFstrbuf.h"
|
||||||
|
|
||||||
struct yyjson_val;
|
struct yyjson_val;
|
||||||
struct yyjson_mut_doc;
|
struct yyjson_mut_doc;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "util/FFstrbuf.h"
|
#include "common/FFstrbuf.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "util/FFstrbuf.h"
|
#include "common/FFstrbuf.h"
|
||||||
#include "util/stringUtils.h"
|
#include "common/stringUtils.h"
|
||||||
|
|
||||||
const char* ffFindExecutableInPath(const char* name, FFstrbuf* result);
|
const char* ffFindExecutableInPath(const char* name, FFstrbuf* result);
|
||||||
static inline bool ffIsAbsolutePath(const char* path)
|
static inline bool ffIsAbsolutePath(const char* path)
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "util/FFstrbuf.h"
|
#include "common/FFstrbuf.h"
|
||||||
#include "common/parsing.h"
|
#include "common/parsing.h"
|
||||||
#include "common/option.h"
|
#include "common/option.h"
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "util/FFstrbuf.h"
|
#include "common/FFstrbuf.h"
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <sys/types.h> // pid_t
|
#include <sys/types.h> // pid_t
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
#include "fastfetch.h"
|
#include "fastfetch.h"
|
||||||
|
|
||||||
void ffSizeAppendNum(uint64_t bytes, FFstrbuf* result);
|
void ffSizeAppendNum(uint64_t bytes, FFstrbuf* result);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "util/FFstrbuf.h"
|
#include "common/FFstrbuf.h"
|
||||||
|
|
||||||
bool ffIsSmbiosValueSet(FFstrbuf* value);
|
bool ffIsSmbiosValueSet(FFstrbuf* value);
|
||||||
static inline void ffCleanUpSmbiosValue(FFstrbuf* value)
|
static inline void ffCleanUpSmbiosValue(FFstrbuf* value)
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "fastfetch.h"
|
#include "fastfetch.h"
|
||||||
#include "util/FFcheckmacros.h"
|
#include "common/FFcheckmacros.h"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
#include <time.h>
|
|
||||||
|
|
||||||
char ffTimeInternalBuffer[64]; // Reduce memory usage and prevent redundant allocations
|
|
||||||
+6
-80
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <stdio.h>
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <synchapi.h>
|
#include <synchapi.h>
|
||||||
#include <profileapi.h>
|
#include <profileapi.h>
|
||||||
@@ -11,7 +10,7 @@
|
|||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "util/arrayUtils.h"
|
#include "common/arrayUtils.h"
|
||||||
|
|
||||||
static inline double ffTimeGetTick(void) //In msec
|
static inline double ffTimeGetTick(void) //In msec
|
||||||
{
|
{
|
||||||
@@ -54,52 +53,14 @@ static inline void ffTimeSleep(uint32_t msec)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
// Not thread-safe
|
||||||
#pragma GCC diagnostic push
|
const char* ffTimeToFullStr(uint64_t msec);
|
||||||
#pragma GCC diagnostic ignored "-Wformat"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Not thread-safe
|
// Not thread-safe
|
||||||
static inline const char* ffTimeToFullStr(uint64_t msec)
|
const char* ffTimeToShortStr(uint64_t msec);
|
||||||
{
|
|
||||||
if (msec == 0) return "";
|
|
||||||
time_t tsec = (time_t) (msec / 1000);
|
|
||||||
const struct tm* tm = localtime(&tsec);
|
|
||||||
|
|
||||||
extern char ffTimeInternalBuffer[64];
|
|
||||||
uint32_t len = 0;
|
|
||||||
len += (uint32_t) strftime(ffTimeInternalBuffer, ARRAY_SIZE(ffTimeInternalBuffer) - len, "%FT%T", tm);
|
|
||||||
len += (uint32_t) snprintf(ffTimeInternalBuffer + len, ARRAY_SIZE(ffTimeInternalBuffer) - len, ".%03u", (unsigned) (msec % 1000));
|
|
||||||
len += (uint32_t) strftime(ffTimeInternalBuffer + len, ARRAY_SIZE(ffTimeInternalBuffer) - len, "%z", tm);
|
|
||||||
return ffTimeInternalBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not thread-safe
|
// Not thread-safe
|
||||||
static inline const char* ffTimeToShortStr(uint64_t msec)
|
const char* ffTimeToTimeStr(uint64_t msec);
|
||||||
{
|
|
||||||
if (msec == 0) return "";
|
|
||||||
time_t tsec = (time_t) (msec / 1000);
|
|
||||||
|
|
||||||
extern char ffTimeInternalBuffer[64];
|
|
||||||
strftime(ffTimeInternalBuffer, ARRAY_SIZE(ffTimeInternalBuffer), "%F %T", localtime(&tsec));
|
|
||||||
return ffTimeInternalBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not thread-safe
|
|
||||||
static inline const char* ffTimeToTimeStr(uint64_t msec)
|
|
||||||
{
|
|
||||||
if (msec == 0) return "";
|
|
||||||
time_t tsec = (time_t) (msec / 1000);
|
|
||||||
|
|
||||||
extern char ffTimeInternalBuffer[64];
|
|
||||||
uint32_t len = (uint32_t) strftime(ffTimeInternalBuffer, ARRAY_SIZE(ffTimeInternalBuffer), "%T", localtime(&tsec));
|
|
||||||
sprintf(ffTimeInternalBuffer + len, ".%03u", (unsigned) (msec % 1000));
|
|
||||||
return ffTimeInternalBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct FFTimeGetAgeResult
|
typedef struct FFTimeGetAgeResult
|
||||||
{
|
{
|
||||||
@@ -108,39 +69,4 @@ typedef struct FFTimeGetAgeResult
|
|||||||
double yearsFraction;
|
double yearsFraction;
|
||||||
} FFTimeGetAgeResult;
|
} FFTimeGetAgeResult;
|
||||||
|
|
||||||
static inline FFTimeGetAgeResult ffTimeGetAge(uint64_t birthMs, uint64_t nowMs)
|
FFTimeGetAgeResult ffTimeGetAge(uint64_t birthMs, uint64_t nowMs);
|
||||||
{
|
|
||||||
FFTimeGetAgeResult result = {};
|
|
||||||
if (__builtin_expect(birthMs == 0 || nowMs < birthMs, 0))
|
|
||||||
return result;
|
|
||||||
|
|
||||||
time_t birth_s = (time_t) (birthMs / 1000);
|
|
||||||
struct tm birth_tm;
|
|
||||||
#ifdef _WIN32
|
|
||||||
localtime_s(&birth_tm, &birth_s);
|
|
||||||
#else
|
|
||||||
localtime_r(&birth_s, &birth_tm);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
time_t now_s = (time_t) (nowMs / 1000);
|
|
||||||
struct tm now_tm;
|
|
||||||
#ifdef _WIN32
|
|
||||||
localtime_s(&now_tm, &now_s);
|
|
||||||
#else
|
|
||||||
localtime_r(&now_s, &now_tm);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
result.years = (uint32_t) (now_tm.tm_year - birth_tm.tm_year);
|
|
||||||
if (now_tm.tm_yday < birth_tm.tm_yday)
|
|
||||||
result.years--;
|
|
||||||
|
|
||||||
birth_tm.tm_year += (int) result.years;
|
|
||||||
birth_s = mktime(&birth_tm);
|
|
||||||
uint32_t diff_s = (uint32_t) (now_s - birth_s);
|
|
||||||
result.daysOfYear = diff_s / (24 * 60 * 60);
|
|
||||||
|
|
||||||
birth_tm.tm_year += 1;
|
|
||||||
result.yearsFraction = (double) diff_s / (double) (mktime(&birth_tm) - birth_s) + result.years;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user