mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-28 15:57:03 -05:00
Compare commits
20 Commits
v1.32.1
...
m1_cross_c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a6cc4ca210 | ||
|
|
b4f6c8d773 | ||
|
|
effe93ddd8 | ||
|
|
84b4c14d35 | ||
|
|
911164b513 | ||
|
|
411214797b | ||
|
|
5206a712fe | ||
|
|
641949ecda | ||
|
|
eadf9c1c2e | ||
|
|
ed37d56625 | ||
|
|
64185a0d2f | ||
|
|
aa72cd4d24 | ||
|
|
7dbf84f73a | ||
|
|
f077515a46 | ||
|
|
bb43af3fc9 | ||
|
|
94c0b663f6 | ||
|
|
cac656710e | ||
|
|
df807896ea | ||
|
|
31b63a11ce | ||
|
|
211f775b9f |
@@ -65,5 +65,4 @@ readability-*,
|
||||
-readability-redundant-access-specifiers,
|
||||
-readability-function-cognitive-complexity,
|
||||
-readability-identifier-naming,
|
||||
*-include-cleaner,
|
||||
-readability-qualified-auto'
|
||||
-readability-qualified-auto'
|
||||
@@ -1,5 +0,0 @@
|
||||
cmake-build-*/
|
||||
build*/
|
||||
|
||||
local/
|
||||
**/Dockerfile
|
||||
9
.gdbinit
9
.gdbinit
@@ -6,11 +6,4 @@ skip -rfu ^__gnu_debug::
|
||||
skip -rfu ^ImGui::
|
||||
|
||||
# Trigger breakpoint when execution reaches triggerSafeShutdown()
|
||||
break triggerSafeShutdown
|
||||
|
||||
# Print backtrace after execution jumped to an invalid address
|
||||
define fixbt
|
||||
set $pc = *(void **)$rsp
|
||||
set $rsp = $rsp + 8
|
||||
bt
|
||||
end
|
||||
break triggerSafeShutdown
|
||||
5
.gitattributes
vendored
5
.gitattributes
vendored
@@ -1,4 +1 @@
|
||||
lib/external/** linguist-vendored
|
||||
|
||||
dist/*.sh eol=lf
|
||||
dist/**/*Dockerfile eol=lf
|
||||
lib/external/** linguist-vendored
|
||||
1
.github/workflows/analysis.yml
vendored
1
.github/workflows/analysis.yml
vendored
@@ -46,7 +46,6 @@ jobs:
|
||||
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
set -x
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=gcc-12 CXX=g++-12 cmake \
|
||||
|
||||
123
.github/workflows/build.yml
vendored
123
.github/workflows/build.yml
vendored
@@ -63,7 +63,7 @@ jobs:
|
||||
- name: ⬇️ Install .NET
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '8.0.100'
|
||||
dotnet-version: '7.0.x'
|
||||
|
||||
- name: 📜 Set version variable
|
||||
run: |
|
||||
@@ -72,14 +72,13 @@ jobs:
|
||||
# Windows cmake build
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
set -x
|
||||
mkdir -p build
|
||||
cd build
|
||||
|
||||
cmake -G "Ninja" \
|
||||
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
|
||||
-DCMAKE_INSTALL_PREFIX="$PWD/install" \
|
||||
-DIMHEX_GENERATE_PACKAGE=ON \
|
||||
-DCREATE_PACKAGE=ON \
|
||||
-DIMHEX_USE_DEFAULT_BUILD_SETTINGS=ON \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
-DIMHEX_COMMIT_HASH_SHORT="${GITHUB_SHA::7}" \
|
||||
@@ -95,17 +94,15 @@ jobs:
|
||||
echo "ImHex checks for the existence of this file to determine if it is running in portable mode. You should not delete this file" > $PWD/install/PORTABLE
|
||||
|
||||
- name: ⬆️ Upload Windows Installer
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: Windows Installer x86_64
|
||||
path: |
|
||||
imhex-*.msi
|
||||
|
||||
- name: ⬆️ Upload Portable ZIP
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: Windows Portable x86_64
|
||||
path: |
|
||||
build/install/*
|
||||
@@ -113,16 +110,14 @@ jobs:
|
||||
- name: ⬇️ Download Mesa3D for NoGPU version
|
||||
shell: bash
|
||||
run: |
|
||||
set -x
|
||||
echo "NoGPU version Powered by Mesa 3D : https://fdossena.com/?p=mesa%2Findex.frag" > build/install/MESA.md
|
||||
curl https://werwolv.net/downloads/mesa/MesaForWindows-x64-latest.7z -L -o mesa.7z
|
||||
7z e mesa.7z
|
||||
mv opengl32.dll build/install
|
||||
|
||||
- name: ⬆️ Upload NoGPU Portable ZIP
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: Windows Portable NoGPU x86_64
|
||||
path: |
|
||||
build/install/*
|
||||
@@ -137,10 +132,18 @@ jobs:
|
||||
include:
|
||||
- suffix: "-NoGPU"
|
||||
custom_glfw: true
|
||||
toolchain_file: ""
|
||||
needs_update: true
|
||||
- suffix: ""
|
||||
custom_glfw: false
|
||||
toolchain_file: ""
|
||||
needs_update: true
|
||||
- suffix: "-ARM"
|
||||
custom_glfw: false
|
||||
toolchain_file: "dist/macOS/macos_arm_toolchain.cmake"
|
||||
needs_update: true
|
||||
|
||||
name: 🍎 macOS 12.0${{matrix.suffix}}
|
||||
name: 🍎 macOS 11.0${{matrix.suffix}}
|
||||
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
@@ -166,10 +169,13 @@ jobs:
|
||||
build/CMakeCache.txt
|
||||
key: ${{ runner.os }}-${{ matrix.suffix }}-cmakecache-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
- name: ⬇️ Update brew packages
|
||||
if: ${{matrix.needs_update}}
|
||||
run: |
|
||||
brew update
|
||||
|
||||
- name: ⬇️ Install dependencies
|
||||
run: |
|
||||
set -x
|
||||
brew reinstall python || brew link --overwrite python
|
||||
brew bundle --no-lock --file dist/Brewfile
|
||||
rm -rf /usr/local/Cellar/capstone
|
||||
|
||||
@@ -181,7 +187,7 @@ jobs:
|
||||
- name: ⬇️ Install .NET
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '8.0.100'
|
||||
dotnet-version: '7.0.x'
|
||||
|
||||
- name: 🧰 Checkout glfw
|
||||
if: ${{matrix.custom_glfw}}
|
||||
@@ -194,7 +200,6 @@ jobs:
|
||||
- name: ⬇️ Patch and install custom glfw
|
||||
if: ${{matrix.custom_glfw}}
|
||||
run: |
|
||||
set -x
|
||||
cd glfw
|
||||
git apply ../dist/macOS/0001-glfw-SW.patch
|
||||
|
||||
@@ -214,21 +219,24 @@ jobs:
|
||||
# MacOS cmake build
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
set -x
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=$(brew --prefix gcc@12)/bin/gcc-12 \
|
||||
CXX=$(brew --prefix gcc@12)/bin/g++-12 \
|
||||
CC=$(brew --prefix llvm)/bin/clang \
|
||||
CXX=$(brew --prefix llvm)/bin/clang++ \
|
||||
OBJC=$(brew --prefix llvm)/bin/clang \
|
||||
OBJCXX=$(brew --prefix llvm)/bin/clang++ \
|
||||
PKG_CONFIG_PATH="$(brew --prefix openssl)/lib/pkgconfig":"$(brew --prefix)/lib/pkgconfig" \
|
||||
cmake -G "Ninja" \
|
||||
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
|
||||
-DIMHEX_GENERATE_PACKAGE=ON \
|
||||
-DCMAKE_TOOLCHAIN_FILE="${{matrix.toolchain_file}}" \
|
||||
-DCREATE_BUNDLE=ON \
|
||||
-DCREATE_PACKAGE=ON \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
|
||||
-DNATIVE_CMAKE_C_COMPILER="$(brew --prefix gcc@12)/bin/gcc-12" \
|
||||
-DNATIVE_CMAKE_CXX_COMPILER="$(brew --prefix gcc@12)/bin/g++-12" \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
-DIMHEX_COMMIT_HASH_SHORT="${GITHUB_SHA::7}" \
|
||||
-DIMHEX_COMMIT_HASH_LONG="${GITHUB_SHA}" \
|
||||
@@ -238,56 +246,14 @@ jobs:
|
||||
ninja package
|
||||
|
||||
- name: ⬆️ Upload DMG
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: macOS DMG${{matrix.suffix}} x86_64
|
||||
path: build/*.dmg
|
||||
|
||||
macos-arm64:
|
||||
runs-on: ubuntu-22.04
|
||||
name: 🍎 macOS 12.1 arm64
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: 📁 Restore docker /cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: cache
|
||||
key: build-macos-arm64-cache
|
||||
|
||||
- name: 🐳 Inject /cache into docker
|
||||
uses: reproducible-containers/buildkit-cache-dance@v2.1.2 # Doesn't work with a MacOS runner ?
|
||||
with:
|
||||
cache-source: cache
|
||||
cache-target: /cache
|
||||
|
||||
- name: 🛠️ Build using docker
|
||||
run: |
|
||||
docker buildx build . -f dist/macOS/arm64.Dockerfile --progress=plain --build-arg 'JOBS=4' --build-arg "BUILD_TYPE=$(BUILD_TYPE)" --build-context imhex=$(pwd) --output out
|
||||
|
||||
- name: ⬆️ Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: macOS ZIP arm64
|
||||
path: out/
|
||||
|
||||
# See https://github.com/actions/cache/issues/342#issuecomment-1711054115
|
||||
- name: 🗑️ Delete old cache
|
||||
continue-on-error: true
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
gh extension install actions/gh-actions-cache
|
||||
gh actions-cache delete "build-macos-arm64-cache" --confirm || true
|
||||
|
||||
# Ubuntu build
|
||||
ubuntu:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: Ubuntu
|
||||
@@ -333,7 +299,7 @@ jobs:
|
||||
- name: ⬇️ Install .NET
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '8.0.100'
|
||||
dotnet-version: '7.0.x'
|
||||
|
||||
- name: 🏔️ Set Environment variables
|
||||
run: |
|
||||
@@ -344,7 +310,6 @@ jobs:
|
||||
# Ubuntu cmake build
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
set -x
|
||||
git config --global --add safe.directory '*'
|
||||
mkdir -p build
|
||||
cd build
|
||||
@@ -374,9 +339,8 @@ jobs:
|
||||
mv build/DebDir.deb imhex-${{env.IMHEX_VERSION}}-Ubuntu-${{ matrix.release_num }}-x86_64.deb
|
||||
|
||||
- name: ⬆️ Upload DEB
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: Ubuntu ${{ matrix.release_num }} DEB x86_64
|
||||
path: '*.deb'
|
||||
|
||||
@@ -410,16 +374,14 @@ jobs:
|
||||
|
||||
|
||||
- name: ⬆️ Upload AppImage
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: Linux AppImage x86_64
|
||||
path: 'out/*.AppImage'
|
||||
|
||||
- name: ⬆️ Upload AppImage zsync
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: Linux AppImage zsync x86_64
|
||||
path: 'out/*.AppImage.zsync'
|
||||
|
||||
@@ -452,7 +414,7 @@ jobs:
|
||||
- name: ⬇️ Install .NET
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '8.0.100'
|
||||
dotnet-version: '7.0.x'
|
||||
|
||||
- name: 📜 Setup ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
@@ -471,7 +433,6 @@ jobs:
|
||||
# ArchLinux cmake build
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
set -x
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=gcc CXX=g++ cmake -G "Ninja" \
|
||||
@@ -504,7 +465,6 @@ jobs:
|
||||
# makepkg doesn't want to run as root, so I had to chmod 777 all over
|
||||
- name: 📦 Package ArchLinux .pkg.tar.zst
|
||||
run: |
|
||||
set -x
|
||||
cd build
|
||||
|
||||
# the name is a small trick to make makepkg recognize it as the source
|
||||
@@ -520,9 +480,8 @@ jobs:
|
||||
mv *.pkg.tar.zst imhex-${{env.IMHEX_VERSION}}-ArchLinux-x86_64.pkg.tar.zst
|
||||
|
||||
- name: ⬆️ Upload imhex-archlinux.pkg.tar.zst
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: ArchLinux .pkg.tar.zst x86_64
|
||||
path: |
|
||||
build/imhex-${{env.IMHEX_VERSION}}-ArchLinux-x86_64.pkg.tar.zst
|
||||
@@ -537,14 +496,14 @@ jobs:
|
||||
mock_release: rawhide
|
||||
release_num: rawhide
|
||||
mock_config: fedora-rawhide
|
||||
- name: Fedora
|
||||
mock_release: f39
|
||||
release_num: 39
|
||||
mock_config: fedora-39
|
||||
- name: Fedora
|
||||
mock_release: f38
|
||||
release_num: 38
|
||||
mock_config: fedora-38
|
||||
- name: Fedora
|
||||
mock_release: f37
|
||||
release_num: 37
|
||||
mock_config: fedora-37
|
||||
- name: RHEL-AlmaLinux
|
||||
mock_release: epel9
|
||||
release_num: 9
|
||||
@@ -577,7 +536,6 @@ jobs:
|
||||
|
||||
- name: ⬇️ Update all packages and install dependencies
|
||||
run: |
|
||||
set -x
|
||||
dnf upgrade --disablerepo="*" --enablerepo="fedora,updates" -y
|
||||
dnf install --disablerepo="*" --enablerepo="fedora,updates" -y \
|
||||
fedpkg \
|
||||
@@ -586,7 +544,7 @@ jobs:
|
||||
- name: ⬇️ Install .NET
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '8.0.100'
|
||||
dotnet-version: '7.0.x'
|
||||
|
||||
- name: 📜 Setup ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.5
|
||||
@@ -648,9 +606,8 @@ jobs:
|
||||
$GITHUB_WORKSPACE/imhex-${{env.IMHEX_VERSION}}-${{matrix.name}}-${{matrix.release_num}}-x86_64.rpm
|
||||
|
||||
- name: ⬆️ Upload RPM
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: ${{ matrix.name }} ${{ matrix.release_num }} RPM x86_64
|
||||
path: |
|
||||
imhex-${{env.IMHEX_VERSION}}-${{matrix.name}}-${{matrix.release_num}}-x86_64.rpm
|
||||
|
||||
6
.github/workflows/build_web.yml
vendored
6
.github/workflows/build_web.yml
vendored
@@ -29,7 +29,7 @@ jobs:
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: cache
|
||||
key: web-cmakecache-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
key: build-web-cache
|
||||
|
||||
- name: 🐳 Inject /cache into docker
|
||||
uses: reproducible-containers/buildkit-cache-dance@v2.1.2
|
||||
@@ -43,7 +43,9 @@ jobs:
|
||||
|
||||
- name: 🔨 Fix permissions
|
||||
run: |
|
||||
chmod -c -R +rX "out/"
|
||||
chmod -c -R +rX "out/" | while read line; do
|
||||
echo "::warning title=Invalid file permissions automatically fixed::$line"
|
||||
done
|
||||
|
||||
- name: ⬆️ Upload artifacts
|
||||
uses: actions/upload-pages-artifact@v2
|
||||
|
||||
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
@@ -21,7 +21,6 @@ jobs:
|
||||
|
||||
- name: 📜 Verify version and set version variable
|
||||
run: |
|
||||
set -x
|
||||
project_version=`cat ImHex/VERSION`
|
||||
tag_version="${{github.event.release.tag_name}}"
|
||||
tag_version="${tag_version:1}"
|
||||
@@ -65,7 +64,6 @@ jobs:
|
||||
|
||||
- name: 📜 Verify version and set version variable
|
||||
run: |
|
||||
set -x
|
||||
project_version=`cat ImHex/VERSION`
|
||||
tag_version="${{github.event.release.tag_name}}"
|
||||
tag_version="${tag_version:1}"
|
||||
@@ -89,8 +87,7 @@ jobs:
|
||||
skip_unpack: true
|
||||
|
||||
- name: 🗜️ Unzip files when needed
|
||||
run: |
|
||||
set -x
|
||||
run: |
|
||||
for zipfile in ./*.zip
|
||||
do
|
||||
if [ `zipinfo -1 "$zipfile" | wc -l` -eq 1 ];
|
||||
@@ -115,7 +112,6 @@ jobs:
|
||||
|
||||
- name: ✒️ Prepare PKGBUILD
|
||||
run: |
|
||||
set -x
|
||||
cp ImHex/dist/Arch/PKGBUILD .
|
||||
|
||||
hash=`md5sum imhex-${{ env.IMHEX_VERSION }}-ArchLinux-x86_64.pkg.tar.zst | cut -d ' ' -f 1`
|
||||
|
||||
1
.github/workflows/tests.yml
vendored
1
.github/workflows/tests.yml
vendored
@@ -44,7 +44,6 @@ jobs:
|
||||
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
set -x
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=gcc-12 CXX=g++-12 cmake \
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,7 +3,6 @@
|
||||
|
||||
cmake-build-*/
|
||||
build*/
|
||||
local/
|
||||
venv/
|
||||
|
||||
*.mgc
|
||||
|
||||
27
.gitmodules
vendored
27
.gitmodules
vendored
@@ -1,25 +1,25 @@
|
||||
[submodule "lib/third_party/nativefiledialog"]
|
||||
path = lib/third_party/nativefiledialog
|
||||
[submodule "lib/external/nativefiledialog"]
|
||||
path = lib/external/nativefiledialog
|
||||
url = https://github.com/btzy/nativefiledialog-extended
|
||||
ignore = dirty
|
||||
[submodule "lib/third_party/yara/yara"]
|
||||
path = lib/third_party/yara/yara
|
||||
[submodule "lib/external/yara/yara"]
|
||||
path = lib/external/yara/yara
|
||||
url = https://github.com/VirusTotal/yara
|
||||
ignore = dirty
|
||||
[submodule "lib/third_party/xdgpp"]
|
||||
path = lib/third_party/xdgpp
|
||||
[submodule "lib/external/xdgpp"]
|
||||
path = lib/external/xdgpp
|
||||
url = https://git.sr.ht/~danyspin97/xdgpp
|
||||
ignore = dirty
|
||||
[submodule "lib/third_party/fmt"]
|
||||
path = lib/third_party/fmt
|
||||
[submodule "lib/external/fmt"]
|
||||
path = lib/external/fmt
|
||||
url = https://github.com/fmtlib/fmt
|
||||
ignore = dirty
|
||||
[submodule "lib/third_party/capstone"]
|
||||
path = lib/third_party/capstone
|
||||
[submodule "lib/external/capstone"]
|
||||
path = lib/external/capstone
|
||||
url = https://github.com/capstone-engine/capstone
|
||||
ignore = dirty
|
||||
[submodule "lib/third_party/jthread/jthread"]
|
||||
path = lib/third_party/jthread/jthread
|
||||
[submodule "lib/external/jthread/jthread"]
|
||||
path = lib/external/jthread/jthread
|
||||
url = https://github.com/josuttis/jthread
|
||||
ignore = dirty
|
||||
|
||||
@@ -33,6 +33,3 @@
|
||||
path = lib/external/libwolv
|
||||
url = https://github.com/WerWolv/libwolv
|
||||
|
||||
[submodule "lib/third_party/HashLibPlus"]
|
||||
path = lib/third_party/HashLibPlus
|
||||
url = https://github.com/WerWolv/HashLibPlus
|
||||
|
||||
@@ -14,8 +14,6 @@ option(IMHEX_ENABLE_LTO "Enables Link Time Optimizations if possible" OFF)
|
||||
option(IMHEX_USE_DEFAULT_BUILD_SETTINGS "Use default build settings" OFF)
|
||||
option(IMHEX_STRICT_WARNINGS "Enable most available warnings and treat them as errors" ON)
|
||||
option(IMHEX_STATIC_LINK_PLUGINS "Statically link all plugins into the main executable" OFF)
|
||||
option(IMHEX_GENERATE_PACKAGE "Specify if a native package should be built. Only usable on Windows and MacOS" OFF)
|
||||
option(IMHEX_ENABLE_UNITY_BUILD "Enables building ImHex as a unity build." OFF)
|
||||
|
||||
# Basic compiler and cmake configurations
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
@@ -39,7 +37,12 @@ setDefaultBuiltTypeIfUnset()
|
||||
detectBadClone()
|
||||
verifyCompiler()
|
||||
|
||||
detectBundledPlugins()
|
||||
# List plugin names here. Project name must match folder name
|
||||
set(PLUGINS
|
||||
builtin
|
||||
windows
|
||||
script_loader
|
||||
)
|
||||
|
||||
# Add various defines
|
||||
detectOS()
|
||||
@@ -62,4 +65,3 @@ add_subdirectory(tests EXCLUDE_FROM_ALL)
|
||||
# Configure packaging
|
||||
createPackage()
|
||||
generatePDBs()
|
||||
generateSDKDirectory()
|
||||
290
README.md
290
README.md
@@ -51,259 +51,86 @@ If you like my work, please consider supporting me on GitHub Sponsors, Patreon o
|
||||
|
||||
## Screenshots
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
<details>
|
||||
<summary><strong>More Screenshots</strong></summary>
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
</details>
|
||||
|
||||
## Features
|
||||
|
||||
<details>
|
||||
<summary><strong>Featureful hex view</strong></summary>
|
||||
|
||||
- Featureful hex view
|
||||
- Byte patching
|
||||
- Patch management
|
||||
- Infinite Undo/Redo
|
||||
- "Copy bytes as..."
|
||||
- Copy bytes as feature
|
||||
- Bytes
|
||||
- Hex string
|
||||
- C, C++, C#, Rust, Python, Java & JavaScript array
|
||||
- ASCII-Art hex view
|
||||
- HTML self-contained div
|
||||
- Simple string and hex search
|
||||
- Goto from start, end and current cursor position
|
||||
- String and hex search
|
||||
- Colorful highlighting
|
||||
- Configurable foreground highlighting rules
|
||||
- Background highlighting using patterns, find results and bookmarks
|
||||
- Displaying data as a list of many different types
|
||||
- Hexadecimal integers (8, 16, 32, 64 bit)
|
||||
- Signed and unsigned decimal integers (8, 16, 32, 64 bit)
|
||||
- Floats (16, 32, 64 bit)
|
||||
- RGBA8 Colors
|
||||
- HexII
|
||||
- Binary
|
||||
- Decoding data as ASCII and custom encodings
|
||||
- Built-in support for UTF-8, UTF-16, ShiftJIS, most Windows encodings and many more
|
||||
- Paged data view
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Custom C++-like pattern language for parsing highlighting a file's content</strong></summary>
|
||||
|
||||
- Automatic loading based on MIME types and magic values
|
||||
- Arrays, pointers, structs, unions, enums, bitfields, namespaces, little and big endian support, conditionals and much more!
|
||||
- Goto from start, end and current cursor position
|
||||
- Custom C++-like pattern language for parsing highlighting a file's content
|
||||
- Automatic loading based on MIME type
|
||||
- arrays, pointers, structs, unions, enums, bitfields, namespaces, little and big endian support, conditionals and much more!
|
||||
- Useful error messages, syntax highlighting and error marking
|
||||
- Support for visualizing many different types of data
|
||||
- Images
|
||||
- Audio
|
||||
- 3D Models
|
||||
- Coordinates
|
||||
- Time stamps
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Theming support</strong></summary>
|
||||
|
||||
- Doesn't burn out your retinas when used in late-night sessions
|
||||
- Dark mode by default, but a light mode is available as well
|
||||
- Customizable colors and styles for all UI elements through shareable theme files
|
||||
- Support for custom fonts
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Importing and Exporting data</strong></summary>
|
||||
|
||||
- Doesn't burn out your retinas when used in late-night sessions
|
||||
- Dark mode by default, but a light mode is available as well
|
||||
- Data importing
|
||||
- Base64 files
|
||||
- IPS and IPS32 patches
|
||||
- Markdown reports
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Data Inspector</strong></summary>
|
||||
|
||||
- Interpreting data as many different types with endianess, decimal, hexadecimal and octal support and bit inversion
|
||||
- Unsigned and signed integers (8, 16, 24, 32, 48, 64 bit)
|
||||
- Floats (16, 32, 64 bit)
|
||||
- Signed and Unsigned LEB128
|
||||
- ASCII, Wide and UTF-8 characters and strings
|
||||
- time32_t, time64_t, DOS date and time
|
||||
- GUIDs
|
||||
- RGBA8 and RGB65 Colors
|
||||
- Copying and modifying bytes through the inspector
|
||||
- Adding new data types through the pattern language
|
||||
- Support for hiding rows that aren't used
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Node-based data pre-processor</strong></summary>
|
||||
|
||||
- Modify, decrypt and decode data before it's being displayed in the hex editor
|
||||
- Modify data without touching the underlying source
|
||||
- Support for adding custom nodes
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Loading data from many different data sources</strong></summary>
|
||||
|
||||
- Local Files
|
||||
- Support for huge files with fast and efficient loading
|
||||
- Raw Disks
|
||||
- Loading data from raw disks and partitions
|
||||
- GDB Server
|
||||
- Access the RAM of a running process or embedded devices through GDB
|
||||
- Intel Hex and Motorola SREC data
|
||||
- Process Memory
|
||||
- Inspect the entire address space of a running process
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Data searching</strong></summary>
|
||||
|
||||
- Support for searching the entire file or only a selection
|
||||
- String extraction
|
||||
- Option to specify minimum length and character set (lower case, upper case, digits, symbols)
|
||||
- Option to specify encoding (ASCII, UTF-8, UTF-16 big and little endian)
|
||||
- Sequence search
|
||||
- Search for a sequence of bytes or characters
|
||||
- Option to ignore character case
|
||||
- Regex search
|
||||
- Search for strings using regular expressions
|
||||
- Binary Pattern
|
||||
- Search for sequences of bytes with optional wildcards
|
||||
- Numeric Value search
|
||||
- Search for signed/unsigned integers and floats
|
||||
- Search for ranges of values
|
||||
- Option to specify size and endianess
|
||||
- Option to ignore unaligned values
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Data hashing support</strong></summary>
|
||||
|
||||
- Many different algorithms available
|
||||
- CRC8, CRC16 and CRC32 with custom initial values and polynomials
|
||||
- Many default polynomials available
|
||||
- MD5
|
||||
- SHA-1, SHA-224, SHA-256, SHA-384, SHA-512
|
||||
- Adler32
|
||||
- AP
|
||||
- BKDR
|
||||
- Bernstein, Bernstein1
|
||||
- DEK, DJB, ELF, FNV1, FNV1a, JS, PJW, RS, SDBM
|
||||
- OneAtTime, Rotating, ShiftAndXor, SuperFast
|
||||
- Murmur2_32, MurmurHash3_x86_32, MurmurHash3_x86_128, MurmurHash3_x64_128
|
||||
- SipHash64, SipHash128
|
||||
- XXHash32, XXHash64
|
||||
- Tiger, Tiger2
|
||||
- Blake2B, Blake2S
|
||||
- Hashing of specific regions of the loaded data
|
||||
- Hashing of arbitrary strings
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Diffing support</strong></summary>
|
||||
|
||||
- Compare data of different data sources
|
||||
- Difference highlighting
|
||||
- Table view of differences
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Integrated disassembler</strong></summary>
|
||||
|
||||
- Support for all architectures supported by Capstone
|
||||
- ARM32 (ARM, Thumb, Cortex-M, AArch32)
|
||||
- ARM64
|
||||
- MIPS (MIPS32, MIPS64, MIPS32R6, Micro)
|
||||
- x86 (16-bit, 32-bit, 64-bit)
|
||||
- PowerPC (32-bit, 64-bit)
|
||||
- SPARC
|
||||
- IBM SystemZ
|
||||
- xCORE
|
||||
- M68K
|
||||
- TMS320C64X
|
||||
- M680X
|
||||
- Ethereum
|
||||
- RISC-V
|
||||
- WebAssembly
|
||||
- MOS65XX
|
||||
- Berkeley Packet Filter
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Bookmarks</strong></summary>
|
||||
|
||||
- Support for bookmarks with custom names and colors
|
||||
- Highlighting of bookmarked region in the hex editor
|
||||
- Jump to bookmarks
|
||||
- Open content of bookmark in a new tab
|
||||
- Add comments to bookmarks
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Featureful data analyzer and visualizer</strong></summary>
|
||||
|
||||
- Data exporting
|
||||
- IPS and IPS32 patches
|
||||
- Data inspector allowing interpretation of data as many different types (little and big endian)
|
||||
- Huge file support with fast and efficient loading
|
||||
- String search
|
||||
- Copying of strings
|
||||
- Copying of demangled strings
|
||||
- File hashing support
|
||||
- CRC16 and CRC32 with custom initial values and polynomials
|
||||
- MD4, MD5
|
||||
- SHA-1, SHA-224, SHA-256, SHA-384, SHA-512
|
||||
- Disassembler supporting many architectures (frontend for Capstone)
|
||||
- ARM32 (ARM, Thumb, Cortex-M, AArch32)
|
||||
- ARM64
|
||||
- MIPS (MIPS32, MIPS64, MIPS32R6, Micro)
|
||||
- x86 (16-bit, 32-bit, 64-bit)
|
||||
- PowerPC (32-bit, 64-bit)
|
||||
- SPARC
|
||||
- IBM SystemZ
|
||||
- xCORE
|
||||
- M68K
|
||||
- TMS320C64X
|
||||
- M680X
|
||||
- Ethereum
|
||||
- RISC-V
|
||||
- WebAssembly
|
||||
- MOS65XX
|
||||
- Berkeley Packet Filter
|
||||
- Bookmarks
|
||||
- Region highlighting
|
||||
- Comments
|
||||
- Data Analyzer
|
||||
- File magic-based file parser and MIME type database
|
||||
- Byte type distribution graph
|
||||
- Byte distribution graph
|
||||
- Entropy graph
|
||||
- Highest and average entropy
|
||||
- Encrypted / Compressed file detection
|
||||
- Digram and Layered distribution graphs
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>YARA Rule support</strong></summary>
|
||||
|
||||
- Scan a file for vulnerabilities with official yara rules
|
||||
- Highlight matches in the hex editor
|
||||
- Jump to matches
|
||||
- Apply multiple rules at once
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Helpful tools</strong></summary>
|
||||
|
||||
- Itanium, MSVC, Rust and D-Lang demangler based on LLVM
|
||||
- Built-in Content Store
|
||||
- Download all files found in the database directly from within ImHex
|
||||
- Yara Rules support
|
||||
- Quickly scan a file for vulnerabilities with official yara rules
|
||||
- Helpful tools
|
||||
- Itanium and MSVC demangler
|
||||
- ASCII table
|
||||
- Regex replacer
|
||||
- Mathematical expression evaluator (Calculator)
|
||||
- Graphing calculator
|
||||
- Hexadecimal Color picker with support for many different formats
|
||||
- Hexadecimal Color picker
|
||||
- Base converter
|
||||
- Byte swapper
|
||||
- UNIX Permissions calculator
|
||||
- Wikipedia term definition finder
|
||||
- File utilities
|
||||
- File splitter
|
||||
- File combiner
|
||||
- File shredder
|
||||
- IEEE754 Float visualizer
|
||||
- Division by invariant multiplication calculator
|
||||
- TCP Client/Server
|
||||
- Euclidean algorithm calculator
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Built-in Content updater</strong></summary>
|
||||
|
||||
- Download all files found in the database directly from within ImHex
|
||||
- Pattern files for decoding various file formats
|
||||
- Libraries for the pattern language
|
||||
- Magic files for file type detection
|
||||
- Custom data processor nodes
|
||||
- Custom encodings
|
||||
- Custom themes
|
||||
- Yara rules
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Modern Interface</strong></summary>
|
||||
|
||||
- Support for multiple workspaces
|
||||
- Support for custom layouts
|
||||
- Detachable windows
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Easy to get started</strong></summary>
|
||||
|
||||
- Support for many different languages
|
||||
- Simplified mode for beginners
|
||||
- Extensive documentation
|
||||
- Many example files available on [the Database](https://github.com/WerWolv/ImHex-Patterns)
|
||||
- Achievements guiding you through the features of ImHex
|
||||
- Interactive tutorials
|
||||
</details>
|
||||
|
||||
## Pattern Language
|
||||
|
||||
@@ -321,13 +148,7 @@ For format patterns, libraries, magic and constant files, check out the [ImHex-P
|
||||
|
||||
## Requirements
|
||||
|
||||
To use ImHex, the following minimal system requirements need to be met.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> ImHex requires a GPU with OpenGL 3.0 support in general.
|
||||
> There are releases available (with the `-NoGPU` suffix) that are software rendered and don't require a GPU, however these can be a lot slower than the GPU accelerated versions.
|
||||
>
|
||||
> If possible at all, make ImHex use the dedicated GPU on your system instead of the integrated one (especially Intel HD GPUs are known to cause issues).
|
||||
To use ImHex, the following minimal system requirements need to be met:
|
||||
|
||||
- **OS**:
|
||||
- **Windows**: Windows 7 or higher (Windows 10/11 recommended)
|
||||
@@ -354,9 +175,8 @@ To compile ImHex on any platform, GCC (or Clang) is required with a version that
|
||||
On macOS, Clang is also required to compile some ObjC code.
|
||||
All releases are being built using latest available GCC.
|
||||
|
||||
> [!NOTE]
|
||||
> Many dependencies are bundled into the repository using submodules so make sure to clone it using the `--recurse-submodules` option.
|
||||
> All dependencies that aren't bundled, can be installed using the dependency installer scripts found in the `/dist` folder.
|
||||
Many dependencies are bundled into the repository using submodules so make sure to clone it using the `--recurse-submodules` option.
|
||||
All dependencies that aren't bundled, can be installed using the dependency installer scripts found in the `/dist` folder.
|
||||
|
||||
For more information, check out the [Compiling](/dist/compiling) guide.
|
||||
|
||||
@@ -378,7 +198,7 @@ To develop plugins for ImHex, use one of the following two templates projects to
|
||||
- [Roblabla](https://github.com/Roblabla) for adding MSI Installer support to ImHex
|
||||
- [jam1garner](https://github.com/jam1garner) and [raytwo](https://github.com/raytwo) for their help with adding Rust support to plugins
|
||||
- [Mailaender](https://github.com/Mailaender) for getting ImHex onto Flathub
|
||||
- [iTrooz](https://github.com/iTrooz) for many improvements and new features to Imhex
|
||||
- [iTrooz](https://github.com/iTrooz) for many improvements related to release packaging and the GitHub Action runners.
|
||||
- Everybody else who has reported issues on Discord or GitHub that I had great conversations with :)
|
||||
|
||||
### Dependencies
|
||||
|
||||
@@ -7,4 +7,4 @@ If you built ImHex yourself and experience issues that are not present in the ve
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Any critical vulnerabilities can be reported through Discord (@werwolv).
|
||||
Any critical vulnerabilities can be reported through Discord @WerWolv#1337
|
||||
|
||||
@@ -89,6 +89,14 @@ endmacro()
|
||||
|
||||
|
||||
macro(configurePackingResources)
|
||||
set(IMHEX_FORCE_LINK_PLUGINS "")
|
||||
|
||||
option (CREATE_PACKAGE "Create a package with CPack" OFF)
|
||||
|
||||
if (APPLE)
|
||||
option (CREATE_BUNDLE "Create a bundle on macOS" OFF)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
if (NOT (CMAKE_BUILD_TYPE STREQUAL "Debug"))
|
||||
set(APPLICATION_TYPE WIN32)
|
||||
@@ -96,7 +104,7 @@ macro(configurePackingResources)
|
||||
|
||||
set(IMHEX_ICON "${IMHEX_BASE_FOLDER}/resources/resource.rc")
|
||||
|
||||
if (IMHEX_GENERATE_PACKAGE)
|
||||
if (CREATE_PACKAGE)
|
||||
set(CPACK_GENERATOR "WIX")
|
||||
set(CPACK_PACKAGE_NAME "ImHex")
|
||||
set(CPACK_PACKAGE_VENDOR "WerWolv")
|
||||
@@ -108,13 +116,13 @@ macro(configurePackingResources)
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "ImHex")
|
||||
set_property(INSTALL "$<TARGET_FILE_NAME:main>"
|
||||
PROPERTY CPACK_START_MENU_SHORTCUTS "ImHex"
|
||||
)
|
||||
)
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/resources/dist/windows/LICENSE.rtf")
|
||||
endif()
|
||||
elseif (APPLE)
|
||||
set (IMHEX_ICON "${IMHEX_BASE_FOLDER}/resources/dist/macos/AppIcon.icns")
|
||||
|
||||
if (IMHEX_GENERATE_PACKAGE)
|
||||
if (CREATE_BUNDLE)
|
||||
set(APPLICATION_TYPE MACOSX_BUNDLE)
|
||||
set_source_files_properties(${IMHEX_ICON} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
|
||||
set(MACOSX_BUNDLE_ICON_FILE "AppIcon.icns")
|
||||
@@ -129,9 +137,9 @@ macro(configurePackingResources)
|
||||
string(TIMESTAMP CURR_YEAR "%Y")
|
||||
set(MACOSX_BUNDLE_COPYRIGHT "Copyright © 2020 - ${CURR_YEAR} WerWolv. All rights reserved." )
|
||||
if ("${CMAKE_GENERATOR}" STREQUAL "Xcode")
|
||||
set (IMHEX_BUNDLE_PATH "${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/imhex.app")
|
||||
set (IMHEX_BUNDLE_PATH "${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/ImHex.app")
|
||||
else ()
|
||||
set (IMHEX_BUNDLE_PATH "${CMAKE_BINARY_DIR}/imhex.app")
|
||||
set (IMHEX_BUNDLE_PATH "${CMAKE_BINARY_DIR}/ImHex.app")
|
||||
endif()
|
||||
|
||||
set(PLUGINS_INSTALL_LOCATION "${IMHEX_BUNDLE_PATH}/Contents/MacOS/plugins")
|
||||
@@ -147,28 +155,30 @@ macro(createPackage)
|
||||
foreach (plugin IN LISTS PLUGINS)
|
||||
add_subdirectory("plugins/${plugin}")
|
||||
if (TARGET ${plugin})
|
||||
get_target_property(IS_RUST_PROJECT ${plugin} RUST_PROJECT)
|
||||
|
||||
set_target_properties(${plugin} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins)
|
||||
set_target_properties(${plugin} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins)
|
||||
|
||||
if (APPLE)
|
||||
if (IMHEX_GENERATE_PACKAGE)
|
||||
set_target_properties(${plugin} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PLUGINS_INSTALL_LOCATION})
|
||||
else ()
|
||||
set_target_properties(${plugin} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins)
|
||||
endif ()
|
||||
if (IS_RUST_PROJECT)
|
||||
set_target_properties(${plugin} PROPERTIES CARGO_BUILD_TARGET_DIR ${CMAKE_BINARY_DIR}/plugins)
|
||||
|
||||
get_target_property(PLUGIN_LOCATION ${plugin} LOCATION)
|
||||
|
||||
install(FILES "${PLUGIN_LOCATION}/../${plugin}.hexplug" DESTINATION "${PLUGINS_INSTALL_LOCATION}" PERMISSIONS ${LIBRARY_PERMISSIONS})
|
||||
else ()
|
||||
if (WIN32)
|
||||
get_target_property(target_type ${plugin} TYPE)
|
||||
if (target_type STREQUAL "SHARED_LIBRARY")
|
||||
install(TARGETS ${plugin} RUNTIME DESTINATION ${PLUGINS_INSTALL_LOCATION})
|
||||
install(TARGETS ${plugin} RUNTIME DESTINATION ${PLUGINS_INSTALL_LOCATION})
|
||||
elseif (APPLE)
|
||||
if (CREATE_BUNDLE)
|
||||
set_target_properties(${plugin} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PLUGINS_INSTALL_LOCATION})
|
||||
else ()
|
||||
install(TARGETS ${plugin} LIBRARY DESTINATION ${PLUGINS_INSTALL_LOCATION})
|
||||
endif()
|
||||
else()
|
||||
set_target_properties(${plugin} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins)
|
||||
endif ()
|
||||
else ()
|
||||
install(TARGETS ${plugin} LIBRARY DESTINATION ${PLUGINS_INSTALL_LOCATION})
|
||||
endif()
|
||||
|
||||
endif()
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
add_dependencies(imhex_all ${plugin})
|
||||
endif ()
|
||||
@@ -180,17 +190,12 @@ macro(createPackage)
|
||||
# Install binaries directly in the prefix, usually C:\Program Files\ImHex.
|
||||
set(CMAKE_INSTALL_BINDIR ".")
|
||||
|
||||
set(PLUGIN_TARGET_FILES "")
|
||||
foreach (plugin IN LISTS PLUGINS)
|
||||
list(APPEND PLUGIN_TARGET_FILES "$<TARGET_FILE:${plugin}>")
|
||||
endforeach ()
|
||||
|
||||
# Grab all dynamically linked dependencies.
|
||||
install(CODE "set(CMAKE_INSTALL_BINDIR \"${CMAKE_INSTALL_BINDIR}\")")
|
||||
install(CODE "set(PLUGIN_TARGET_FILES \"${PLUGIN_TARGET_FILES}\")")
|
||||
INSTALL(CODE "set(CMAKE_INSTALL_BINDIR \"${CMAKE_INSTALL_BINDIR}\")")
|
||||
INSTALL(CODE "LIST(APPEND DEP_FOLDERS \${PY_PARENT})")
|
||||
install(CODE [[
|
||||
file(GET_RUNTIME_DEPENDENCIES
|
||||
EXECUTABLES ${PLUGIN_TARGET_FILES} $<TARGET_FILE:libimhex> $<TARGET_FILE:main>
|
||||
EXECUTABLES $<TARGET_FILE:builtin> $<TARGET_FILE:libimhex> $<TARGET_FILE:main>
|
||||
RESOLVED_DEPENDENCIES_VAR _r_deps
|
||||
UNRESOLVED_DEPENDENCIES_VAR _u_deps
|
||||
CONFLICTING_DEPENDENCIES_PREFIX _c_deps
|
||||
@@ -217,27 +222,27 @@ macro(createPackage)
|
||||
elseif(UNIX AND NOT APPLE)
|
||||
|
||||
set_target_properties(libimhex PROPERTIES SOVERSION ${IMHEX_VERSION})
|
||||
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/dist/DEBIAN/control.in ${CMAKE_BINARY_DIR}/DEBIAN/control)
|
||||
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE DESTINATION ${CMAKE_INSTALL_PREFIX}/share/licenses/imhex)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dist/imhex.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/resources/icon.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/pixmaps RENAME imhex.png)
|
||||
install(FILES "$<TARGET_FILE:libimhex>" DESTINATION "${CMAKE_INSTALL_LIBDIR}" PERMISSIONS ${LIBRARY_PERMISSIONS})
|
||||
downloadImHexPatternsFiles("./share/imhex")
|
||||
|
||||
|
||||
# install AppStream file
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dist/net.werwolv.imhex.metainfo.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/metainfo)
|
||||
|
||||
|
||||
# install symlink for the old standard name
|
||||
file(CREATE_LINK net.werwolv.imhex.metainfo.xml ${CMAKE_CURRENT_BINARY_DIR}/net.werwolv.imhex.appdata.xml SYMBOLIC)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/net.werwolv.imhex.appdata.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/metainfo)
|
||||
|
||||
endif()
|
||||
|
||||
if (IMHEX_GENERATE_PACKAGE AND APPLE)
|
||||
|
||||
if (CREATE_BUNDLE)
|
||||
include(PostprocessBundle)
|
||||
|
||||
|
||||
set_target_properties(libimhex PROPERTIES SOVERSION ${IMHEX_VERSION})
|
||||
|
||||
set_property(TARGET main PROPERTY MACOSX_BUNDLE_INFO_PLIST ${MACOSX_BUNDLE_INFO_PLIST})
|
||||
@@ -250,7 +255,7 @@ macro(createPackage)
|
||||
add_custom_target(build-time-make-resources-directory ALL COMMAND ${CMAKE_COMMAND} -E make_directory "${IMHEX_BUNDLE_PATH}/Contents/Resources")
|
||||
|
||||
downloadImHexPatternsFiles("${IMHEX_BUNDLE_PATH}/Contents/MacOS")
|
||||
|
||||
|
||||
install(FILES ${IMHEX_ICON} DESTINATION "${IMHEX_BUNDLE_PATH}/Contents/Resources")
|
||||
install(TARGETS main BUNDLE DESTINATION ".")
|
||||
install(FILES $<TARGET_FILE:main> DESTINATION "${IMHEX_BUNDLE_PATH}")
|
||||
@@ -260,9 +265,6 @@ macro(createPackage)
|
||||
|
||||
# Enforce DragNDrop packaging.
|
||||
set(CPACK_GENERATOR "DragNDrop")
|
||||
|
||||
set(CPACK_BUNDLE_ICON "${CMAKE_SOURCE_DIR}/resources/dist/macos/AppIcon.icns" )
|
||||
set(CPACK_BUNDLE_PLIST "${CMAKE_BINARY_DIR}/imhex.app/Contents/Info.plist")
|
||||
else()
|
||||
install(TARGETS main RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
if(WIN32) # Forwarder is only needed on Windows
|
||||
@@ -270,8 +272,10 @@ macro(createPackage)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (IMHEX_GENERATE_PACKAGE)
|
||||
if (CREATE_PACKAGE)
|
||||
set (CPACK_BUNDLE_NAME "ImHex")
|
||||
set (CPACK_BUNDLE_ICON "${CMAKE_SOURCE_DIR}/resources/dist/macos/AppIcon.icns" )
|
||||
set (CPACK_BUNDLE_PLIST "${CMAKE_BINARY_DIR}/ImHex.app/Contents/Info.plist")
|
||||
|
||||
include(CPack)
|
||||
endif()
|
||||
@@ -293,6 +297,10 @@ macro(configureCMake)
|
||||
# Enable C and C++ languages
|
||||
enable_language(C CXX)
|
||||
|
||||
if (CMAKE_CROSSCOMPILING)
|
||||
message(STATUS "ImHex is being Cross-Compiled for ${CMAKE_SYSTEM_NAME}!")
|
||||
endif ()
|
||||
|
||||
# Configure use of recommended build tools
|
||||
if (IMHEX_USE_DEFAULT_BUILD_SETTINGS)
|
||||
message(STATUS "Configuring CMake to use recommended build tools...")
|
||||
@@ -376,7 +384,7 @@ function(detectBadClone)
|
||||
return()
|
||||
endif()
|
||||
|
||||
file (GLOB EXTERNAL_DIRS "lib/external/*" "lib/third_party/*")
|
||||
file (GLOB EXTERNAL_DIRS "lib/external/*")
|
||||
foreach (EXTERNAL_DIR ${EXTERNAL_DIRS})
|
||||
file(GLOB_RECURSE RESULT "${EXTERNAL_DIR}/*")
|
||||
list(LENGTH RESULT ENTRY_COUNT)
|
||||
@@ -400,35 +408,6 @@ function(verifyCompiler)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
macro(detectBundledPlugins)
|
||||
file(GLOB PLUGINS_DIRS "plugins/*")
|
||||
|
||||
if (NOT DEFINED IMHEX_INCLUDE_PLUGINS)
|
||||
foreach(PLUGIN_DIR ${PLUGINS_DIRS})
|
||||
if (EXISTS "${PLUGIN_DIR}/CMakeLists.txt")
|
||||
get_filename_component(PLUGIN_NAME ${PLUGIN_DIR} NAME)
|
||||
if (NOT (${PLUGIN_NAME} IN_LIST IMHEX_EXCLUDE_PLUGINS))
|
||||
list(APPEND PLUGINS ${PLUGIN_NAME})
|
||||
endif ()
|
||||
endif()
|
||||
endforeach()
|
||||
else()
|
||||
set(PLUGINS ${IMHEX_INCLUDE_PLUGINS})
|
||||
endif()
|
||||
|
||||
foreach(PLUGIN_NAME ${PLUGINS})
|
||||
message(STATUS "Enabled bundled plugin '${PLUGIN_NAME}'")
|
||||
endforeach()
|
||||
|
||||
if (NOT PLUGINS)
|
||||
message(FATAL_ERROR "No bundled plugins enabled")
|
||||
endif()
|
||||
|
||||
if (NOT ("builtin" IN_LIST PLUGINS))
|
||||
message(FATAL_ERROR "The 'builtin' plugin is required for ImHex to work!")
|
||||
endif ()
|
||||
endmacro()
|
||||
|
||||
macro(setVariableInParent variable value)
|
||||
get_directory_property(hasParent PARENT_DIRECTORY)
|
||||
|
||||
@@ -448,9 +427,9 @@ function(downloadImHexPatternsFiles dest)
|
||||
endif ()
|
||||
|
||||
FetchContent_Declare(
|
||||
imhex_patterns
|
||||
GIT_REPOSITORY https://github.com/WerWolv/ImHex-Patterns.git
|
||||
GIT_TAG origin/master
|
||||
imhex_patterns
|
||||
GIT_REPOSITORY https://github.com/WerWolv/ImHex-Patterns.git
|
||||
GIT_TAG origin/master
|
||||
)
|
||||
|
||||
message(STATUS "Downloading ImHex-Patterns repo branch ${PATTERNS_BRANCH}...")
|
||||
@@ -473,40 +452,23 @@ endfunction()
|
||||
|
||||
macro(setupCompilerFlags target)
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||
|
||||
# Define strict compilation flags
|
||||
if (IMHEX_STRICT_WARNINGS)
|
||||
set(IMHEX_COMMON_FLAGS "${IMHEX_COMMON_FLAGS} -Wall -Wextra -Wpedantic -Werror")
|
||||
endif()
|
||||
|
||||
if (UNIX AND NOT APPLE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
set(IMHEX_COMMON_FLAGS "${IMHEX_COMMON_FLAGS} -rdynamic")
|
||||
set(IMHEX_COMMON_FLAGS "-Wall -Wextra -Wpedantic -Werror")
|
||||
endif()
|
||||
|
||||
set(IMHEX_C_FLAGS "${IMHEX_COMMON_FLAGS} -Wno-array-bounds -Wno-deprecated-declarations")
|
||||
set(IMHEX_CXX_FLAGS "-fexceptions -frtti")
|
||||
|
||||
# Disable some warnings
|
||||
set(IMHEX_C_CXX_FLAGS "-Wno-unknown-warning-option -Wno-array-bounds -Wno-deprecated-declarations")
|
||||
|
||||
if (IMHEX_ENABLE_UNITY_BUILD AND WIN32)
|
||||
set(IMHEX_COMMON_FLAGS "${IMHEX_COMMON_FLAGS} -Wa,-mbig-obj")
|
||||
endif ()
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
set(IMHEX_C_FLAGS "${IMHEX_C_FLAGS} -Wno-restrict -Wno-stringop-overread -Wno-stringop-overflow -Wno-dangling-reference")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Disable some warnings for gcc
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
set(IMHEX_C_CXX_FLAGS "${IMHEX_C_CXX_FLAGS} -Wno-restrict -Wno-stringop-overread -Wno-stringop-overflow -Wno-dangling-reference")
|
||||
endif()
|
||||
|
||||
# Define emscripten-specific disabled warnings
|
||||
if (EMSCRIPTEN)
|
||||
set(IMHEX_C_CXX_FLAGS "${IMHEX_C_CXX_FLAGS} -pthread -Wno-dollar-in-identifier-extension -Wno-pthreads-mem-growth")
|
||||
set(IMHEX_C_FLAGS "${IMHEX_C_FLAGS} -pthread -Wno-dollar-in-identifier-extension -Wno-pthreads-mem-growth")
|
||||
endif ()
|
||||
|
||||
# Set actual CMake flags
|
||||
set_target_properties(${target} PROPERTIES COMPILE_FLAGS "${IMHEX_COMMON_FLAGS} ${IMHEX_C_CXX_FLAGS}")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${IMHEX_COMMON_FLAGS} ${IMHEX_C_CXX_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${IMHEX_COMMON_FLAGS} ${IMHEX_C_CXX_FLAGS} ${IMHEX_CXX_FLAGS}")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${IMHEX_C_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${IMHEX_CXX_FLAGS} ${IMHEX_C_FLAGS}")
|
||||
set(CMAKE_OBJC_FLAGS "${CMAKE_OBJC_FLAGS} ${IMHEX_COMMON_FLAGS}")
|
||||
endmacro()
|
||||
|
||||
@@ -514,43 +476,42 @@ endmacro()
|
||||
macro(setUninstallTarget)
|
||||
if(NOT TARGET uninstall)
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||
IMMEDIATE @ONLY)
|
||||
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||
IMMEDIATE @ONLY)
|
||||
|
||||
add_custom_target(uninstall
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(addBundledLibraries)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
set(EXTERNAL_LIBS_FOLDER "${CMAKE_CURRENT_SOURCE_DIR}/lib/external")
|
||||
set(THIRD_PARTY_LIBS_FOLDER "${CMAKE_CURRENT_SOURCE_DIR}/lib/third_party")
|
||||
set(EXTERN_LIBS_FOLDER "${CMAKE_CURRENT_SOURCE_DIR}/lib/external")
|
||||
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/imgui)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/imgui)
|
||||
set_target_properties(imgui PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/microtar EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/microtar EXCLUDE_FROM_ALL)
|
||||
set_target_properties(microtar PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
add_subdirectory(${EXTERNAL_LIBS_FOLDER}/libwolv EXCLUDE_FROM_ALL)
|
||||
set_property(TARGET libwolv-types PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET libwolv-utils PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET libwolv-io PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET libwolv-hash PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET libwolv-containers PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET libwolv-net PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET libwolv-math_eval PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/libwolv EXCLUDE_FROM_ALL)
|
||||
set_property(TARGET libwolv-types PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET libwolv-utils PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET libwolv-io PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET libwolv-hash PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET libwolv-containers PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET libwolv-net PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
set(XDGPP_INCLUDE_DIRS "${THIRD_PARTY_LIBS_FOLDER}/xdgpp")
|
||||
set(XDGPP_INCLUDE_DIRS "${EXTERN_LIBS_FOLDER}/xdgpp")
|
||||
set(FPHSA_NAME_MISMATCHED ON CACHE BOOL "")
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
if(NOT USE_SYSTEM_FMT)
|
||||
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/fmt EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/fmt EXCLUDE_FROM_ALL)
|
||||
set_target_properties(fmt PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set(FMT_LIBRARIES fmt::fmt-header-only)
|
||||
else()
|
||||
@@ -571,7 +532,7 @@ macro(addBundledLibraries)
|
||||
|
||||
# nfd
|
||||
if (NOT USE_SYSTEM_NFD)
|
||||
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/nativefiledialog EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/nativefiledialog EXCLUDE_FROM_ALL)
|
||||
set_target_properties(nfd PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set(NFD_LIBRARIES nfd)
|
||||
else()
|
||||
@@ -581,7 +542,7 @@ macro(addBundledLibraries)
|
||||
endif()
|
||||
|
||||
if(NOT USE_SYSTEM_NLOHMANN_JSON)
|
||||
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/nlohmann_json EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/nlohmann_json EXCLUDE_FROM_ALL)
|
||||
set(NLOHMANN_JSON_LIBRARIES nlohmann_json)
|
||||
else()
|
||||
find_package(nlohmann_json 3.10.2 REQUIRED)
|
||||
@@ -589,14 +550,32 @@ macro(addBundledLibraries)
|
||||
endif()
|
||||
|
||||
if (NOT USE_SYSTEM_LLVM)
|
||||
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/llvm-demangle EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/llvm-demangle EXCLUDE_FROM_ALL)
|
||||
set_target_properties(LLVMDemangle PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
else()
|
||||
find_package(LLVM REQUIRED Demangle)
|
||||
endif()
|
||||
|
||||
if (NOT USE_SYSTEM_YARA)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/yara EXCLUDE_FROM_ALL)
|
||||
set_target_properties(libyara PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set(YARA_LIBRARIES libyara)
|
||||
else()
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(YARA REQUIRED IMPORTED_TARGET yara)
|
||||
endif()
|
||||
|
||||
if (NOT USE_SYSTEM_MINIAUDIO)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/miniaudio EXCLUDE_FROM_ALL)
|
||||
set_target_properties(miniaudio PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set(MINIAUDIO_LIBRARIES miniaudio)
|
||||
else()
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(miniaudio REQUIRED IMPORTED_TARGET miniaudio)
|
||||
endif()
|
||||
|
||||
if (NOT USE_SYSTEM_JTHREAD)
|
||||
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/jthread EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/jthread EXCLUDE_FROM_ALL)
|
||||
set(JTHREAD_LIBRARIES jthread)
|
||||
else()
|
||||
find_path(JOSUTTIS_JTHREAD_INCLUDE_DIRS "condition_variable_any2.hpp")
|
||||
@@ -607,8 +586,22 @@ macro(addBundledLibraries)
|
||||
set(JTHREAD_LIBRARIES jthread)
|
||||
endif()
|
||||
|
||||
if (NOT USE_SYSTEM_CAPSTONE)
|
||||
set(CAPSTONE_BUILD_STATIC_RUNTIME OFF CACHE BOOL "Disable shared library building")
|
||||
set(CAPSTONE_BUILD_SHARED OFF CACHE BOOL "Disable shared library building")
|
||||
set(CAPSTONE_BUILD_TESTS OFF CACHE BOOL "Disable tests")
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/capstone EXCLUDE_FROM_ALL)
|
||||
set_target_properties(capstone PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
target_compile_options(capstone PRIVATE -Wno-unused-function)
|
||||
set(CAPSTONE_LIBRARIES "capstone")
|
||||
set(CAPSTONE_INCLUDE_DIRS ${EXTERN_LIBS_FOLDER}/capstone/include)
|
||||
else()
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_search_module(CAPSTONE 4.0.2 REQUIRED capstone)
|
||||
endif()
|
||||
|
||||
set(LIBPL_BUILD_CLI_AS_EXECUTABLE OFF)
|
||||
add_subdirectory(${EXTERNAL_LIBS_FOLDER}/pattern_language EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/pattern_language EXCLUDE_FROM_ALL)
|
||||
set_target_properties(libpl PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
find_package(mbedTLS 3.4.0 REQUIRED)
|
||||
@@ -645,12 +638,6 @@ macro(addBundledLibraries)
|
||||
endif ()
|
||||
endmacro()
|
||||
|
||||
function(enableUnityBuild TARGET)
|
||||
if (IMHEX_ENABLE_UNITY_BUILD)
|
||||
set_target_properties(${TARGET} PROPERTIES UNITY_BUILD ON UNITY_BUILD_MODE BATCH)
|
||||
endif ()
|
||||
endfunction()
|
||||
|
||||
function(generatePDBs)
|
||||
if (NOT WIN32 OR CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
return()
|
||||
@@ -680,11 +667,9 @@ function(generatePDBs)
|
||||
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/${GENERATED_PDB}.pdb
|
||||
WORKING_DIRECTORY ${cv2pdb_SOURCE_DIR}
|
||||
COMMAND
|
||||
(
|
||||
${CMAKE_COMMAND} -E remove -f ${CMAKE_BINARY_DIR}/${GENERATED_PDB}.pdb &&
|
||||
${cv2pdb_SOURCE_DIR}/cv2pdb64.exe
|
||||
$<TARGET_FILE:${PDB}>
|
||||
) || (exit 0)
|
||||
(${CMAKE_COMMAND} -E remove -f ${CMAKE_BINARY_DIR}/${GENERATED_PDB}.pdb &&
|
||||
${cv2pdb_SOURCE_DIR}/cv2pdb64.exe
|
||||
$<TARGET_FILE:${PDB}>) || (exit 0)
|
||||
DEPENDS $<TARGET_FILE:${PDB}>
|
||||
COMMAND_EXPAND_LISTS)
|
||||
|
||||
@@ -695,33 +680,10 @@ function(generatePDBs)
|
||||
endfunction()
|
||||
|
||||
function(generateSDKDirectory)
|
||||
if (WIN32)
|
||||
set(SDK_PATH "./sdk")
|
||||
elseif (APPLE)
|
||||
set(SDK_PATH "imhex.app/Contents/Resources/sdk")
|
||||
else()
|
||||
set(SDK_PATH "share/imhex/sdk")
|
||||
endif()
|
||||
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/lib/libimhex DESTINATION "${SDK_PATH}/lib")
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/lib/external DESTINATION "${SDK_PATH}/lib")
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/lib/third_party/imgui DESTINATION "${SDK_PATH}/lib/third_party")
|
||||
if (NOT USE_SYSTEM_FMT)
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/lib/third_party/fmt DESTINATION "${SDK_PATH}/lib/third_party")
|
||||
endif()
|
||||
if (NOT USE_SYSTEM_NLOHMANN_JSON)
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/lib/third_party/nlohmann_json DESTINATION "${SDK_PATH}/lib/third_party")
|
||||
endif()
|
||||
set(SDK_PATH "./sdk")
|
||||
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/lib/libimhex/include DESTINATION "${SDK_PATH}")
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/cmake/modules/ImHexPlugin.cmake DESTINATION "${SDK_PATH}/cmake/modules")
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/cmake/build_helpers.cmake DESTINATION "${SDK_PATH}/cmake")
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/cmake/sdk/CMakeLists.txt DESTINATION "${SDK_PATH}")
|
||||
install(TARGETS libimhex ARCHIVE DESTINATION "${SDK_PATH}/lib")
|
||||
install(TARGETS libimhex RUNTIME DESTINATION "${SDK_PATH}/lib")
|
||||
install(TARGETS libimhex LIBRARY DESTINATION "${SDK_PATH}/lib")
|
||||
endfunction()
|
||||
|
||||
function(addIncludesFromLibrary target library)
|
||||
get_target_property(library_include_dirs ${library} INTERFACE_INCLUDE_DIRECTORIES)
|
||||
target_include_directories(${target} PRIVATE ${library_include_dirs})
|
||||
endfunction()
|
||||
@@ -16,7 +16,7 @@ if (NOT DOTNET_EXECUTABLE)
|
||||
set(DOTNET_EXECUTABLE dotnet)
|
||||
endif ()
|
||||
|
||||
set(CORECLR_VERSION "8.0")
|
||||
set(CORECLR_VERSION "7.0")
|
||||
|
||||
execute_process(COMMAND ${DOTNET_EXECUTABLE} "--list-runtimes" OUTPUT_VARIABLE CORECLR_LIST_RUNTIMES_OUTPUT OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if (CORECLR_LIST_RUNTIMES_OUTPUT STREQUAL "")
|
||||
@@ -75,7 +75,7 @@ find_file(CoreClrEmbed_SHARED_LIBRARY nethost.dll nethost.so libnethost.so netho
|
||||
|
||||
if (CoreClrEmbed_INCLUDE_DIR AND CoreClrEmbed_LIBRARY)
|
||||
set(CoreClrEmbed_FOUND TRUE)
|
||||
set(CoreClrEmbed_LIBRARIES "${CoreClrEmbed_LIBRARY}" CACHE STRING "CoreClrEmbed libraries" FORCE)
|
||||
set(CoreClrEmbed_SHARED_LIBRARIES "${CoreClrEmbed_SHARED_LIBRARY}" CACHE STRING "CoreClrEmbed shared libraries" FORCE)
|
||||
set(CoreClrEmbed_INCLUDE_DIRS "${CoreClrEmbed_INCLUDE_DIR}" CACHE STRING "CoreClrEmbed include directories" FORCE)
|
||||
set(CoreClrEmbed_LIBRARIES "${CoreClrEmbed_LIBRARY}")
|
||||
set(CoreClrEmbed_SHARED_LIBRARIES "${CoreClrEmbed_SHARED_LIBRARY}")
|
||||
set(CoreClrEmbed_INCLUDE_DIRS "${CoreClrEmbed_INCLUDE_DIR}")
|
||||
endif()
|
||||
@@ -1,6 +1,6 @@
|
||||
macro(add_imhex_plugin)
|
||||
# Parse arguments
|
||||
set(options LIBRARY_PLUGIN)
|
||||
set(options "")
|
||||
set(oneValueArgs NAME)
|
||||
set(multiValueArgs SOURCES INCLUDES LIBRARIES)
|
||||
cmake_parse_arguments(IMHEX_PLUGIN "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
@@ -12,15 +12,8 @@ macro(add_imhex_plugin)
|
||||
|
||||
configure_file(${CMAKE_SOURCE_DIR}/dist/web/plugin-bundle.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/plugin-bundle.cpp @ONLY)
|
||||
target_sources(main PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/plugin-bundle.cpp)
|
||||
set(IMHEX_PLUGIN_SUFFIX ".hexplug")
|
||||
else()
|
||||
if (IMHEX_PLUGIN_LIBRARY_PLUGIN)
|
||||
set(IMHEX_PLUGIN_LIBRARY_TYPE SHARED)
|
||||
set(IMHEX_PLUGIN_SUFFIX ".hexpluglib")
|
||||
else()
|
||||
set(IMHEX_PLUGIN_LIBRARY_TYPE MODULE)
|
||||
set(IMHEX_PLUGIN_SUFFIX ".hexplug")
|
||||
endif()
|
||||
set(IMHEX_PLUGIN_LIBRARY_TYPE SHARED)
|
||||
endif()
|
||||
|
||||
# Define new project for plugin
|
||||
@@ -31,8 +24,7 @@ macro(add_imhex_plugin)
|
||||
|
||||
# Add include directories and link libraries
|
||||
target_include_directories(${IMHEX_PLUGIN_NAME} PUBLIC ${IMHEX_PLUGIN_INCLUDES})
|
||||
target_link_libraries(${IMHEX_PLUGIN_NAME} PRIVATE libimhex ${IMHEX_PLUGIN_LIBRARIES} ${FMT_LIBRARIES} imgui_all_includes libwolv)
|
||||
addIncludesFromLibrary(${IMHEX_PLUGIN_NAME} libpl)
|
||||
target_link_libraries(${IMHEX_PLUGIN_NAME} PRIVATE libimhex ${FMT_LIBRARIES} ${IMHEX_PLUGIN_LIBRARIES})
|
||||
|
||||
# Add IMHEX_PROJECT_NAME and IMHEX_VERSION define
|
||||
target_compile_definitions(${IMHEX_PLUGIN_NAME} PRIVATE IMHEX_PROJECT_NAME="${IMHEX_PLUGIN_NAME}")
|
||||
@@ -41,7 +33,6 @@ macro(add_imhex_plugin)
|
||||
|
||||
# Enable required compiler flags
|
||||
set_target_properties(${IMHEX_PLUGIN_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
enableUnityBuild(${IMHEX_PLUGIN_NAME})
|
||||
setupCompilerFlags(${IMHEX_PLUGIN_NAME})
|
||||
|
||||
# Configure build properties
|
||||
@@ -50,7 +41,7 @@ macro(add_imhex_plugin)
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins
|
||||
CXX_STANDARD 23
|
||||
PREFIX ""
|
||||
SUFFIX ${IMHEX_PLUGIN_SUFFIX}
|
||||
SUFFIX ".hexplug"
|
||||
)
|
||||
|
||||
# Setup a romfs for the plugin
|
||||
@@ -61,9 +52,7 @@ macro(add_imhex_plugin)
|
||||
target_link_libraries(${IMHEX_PLUGIN_NAME} PRIVATE ${LIBROMFS_LIBRARY})
|
||||
|
||||
# Add the new plugin to the main dependency list so it gets built by default
|
||||
if (TARGET imhex_all)
|
||||
add_dependencies(imhex_all ${IMHEX_PLUGIN_NAME})
|
||||
endif()
|
||||
add_dependencies(imhex_all ${IMHEX_PLUGIN_NAME})
|
||||
endmacro()
|
||||
|
||||
macro(add_romfs_resource input output)
|
||||
|
||||
@@ -24,38 +24,31 @@ if(CMAKE_GENERATOR)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# IMHEX PATCH BEGIN
|
||||
# The function defined above doesn't keep in mind that if we are cross-compiling to MacOS, APPLE must be 1,
|
||||
# so we force it here (where else would this script be run anyway ? This seems to be MacOS-specific code)
|
||||
SET(APPLE 1)
|
||||
# IMHEX PATCHE END
|
||||
|
||||
get_filename_component(BUNDLE_PATH "${BUNDLE_PATH}" ABSOLUTE)
|
||||
message(STATUS "Fixing up application bundle: ${BUNDLE_PATH}")
|
||||
|
||||
|
||||
# Make sure to fix up any included ImHex plugin.
|
||||
file(GLOB_RECURSE plugins "${BUNDLE_PATH}/Contents/MacOS/plugins/*.hexplug")
|
||||
file(GLOB_RECURSE plugin_libs "${BUNDLE_PATH}/Contents/MacOS/plugins/*.hexpluglib")
|
||||
file(GLOB_RECURSE extra_libs "${BUNDLE_PATH}/Contents/MacOS/plugins/*.hexplug")
|
||||
|
||||
|
||||
# BundleUtilities doesn't support DYLD_FALLBACK_LIBRARY_PATH behavior, which
|
||||
# makes it sometimes break on libraries that do weird things with @rpath. Specify
|
||||
# equivalent search directories until https://gitlab.kitware.com/cmake/cmake/issues/16625
|
||||
# is fixed and in our minimum CMake version.
|
||||
set(extra_dirs "/usr/local/lib" "/lib" "/usr/lib" ${EXTRA_BUNDLE_LIBRARY_PATHS} "${BUNDLE_PATH}/Contents/MacOS/plugins")
|
||||
set(extra_dirs "/usr/local/lib" "/lib" "/usr/lib" ${EXTRA_BUNDLE_LIBRARY_PATHS})
|
||||
message(STATUS "Fixing up application bundle: ${extra_dirs}")
|
||||
|
||||
# BundleUtilities is overly verbose, so disable most of its messages
|
||||
#function(message)
|
||||
# if(NOT ARGV MATCHES "^STATUS;")
|
||||
# _message(${ARGV})
|
||||
# endif()
|
||||
#endfunction()
|
||||
function(message)
|
||||
if(NOT ARGV MATCHES "^STATUS;")
|
||||
_message(${ARGV})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
include(BundleUtilities)
|
||||
set(BU_CHMOD_BUNDLE_ITEMS ON)
|
||||
fixup_bundle("${BUNDLE_PATH}" "${plugins};${plugin_libs}" "${extra_dirs}")
|
||||
fixup_bundle("${BUNDLE_PATH}" "${extra_libs}" "${extra_dirs}")
|
||||
|
||||
if (CODE_SIGN_CERTIFICATE_ID)
|
||||
# Hack around Apple Silicon signing bugs by copying the real app, signing it and moving it back.
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
project(ImHexSDK)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
|
||||
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/build_helpers.cmake")
|
||||
|
||||
set(IMHEX_BASE_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE)
|
||||
include(ImHexPlugin)
|
||||
|
||||
function(add_subdirectory_if_exists folder)
|
||||
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${folder}/CMakeLists.txt")
|
||||
add_subdirectory("${folder}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
set(IMHEX_EXTERNAL_PLUGIN_BUILD ON)
|
||||
add_custom_target(imhex_all)
|
||||
|
||||
add_subdirectory(lib/third_party/imgui)
|
||||
add_subdirectory_if_exists(lib/third_party/fmt)
|
||||
add_subdirectory_if_exists(lib/third_party/nlohmann_json)
|
||||
|
||||
add_subdirectory(lib/external/libwolv)
|
||||
|
||||
set(LIBPL_BUILD_CLI_AS_EXECUTABLE OFF)
|
||||
add_subdirectory(lib/external/pattern_language)
|
||||
|
||||
add_subdirectory(lib/libimhex)
|
||||
|
||||
if (WIN32)
|
||||
set_target_properties(libimhex PROPERTIES
|
||||
IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/lib/libimhex.dll"
|
||||
IMPORTED_IMPLIB "${CMAKE_CURRENT_SOURCE_DIR}/lib/liblibimhex.dll.a"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/lib/libimhex/include")
|
||||
elseif (APPLE)
|
||||
set_target_properties(libimhex PROPERTIES
|
||||
IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/lib/libimhex.dylib"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/lib/libimhex/include")
|
||||
else()
|
||||
set_target_properties(libimhex PROPERTIES
|
||||
IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/lib/libimhex.so"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/lib/libimhex/include")
|
||||
endif()
|
||||
4
dist/Arch/PKGBUILD
vendored
4
dist/Arch/PKGBUILD
vendored
@@ -8,7 +8,7 @@ pkgdesc="A Hex Editor for Reverse Engineers, Programmers and people who value th
|
||||
arch=("x86_64")
|
||||
url="https://github.com/WerWolv/ImHex"
|
||||
license=('GPL2')
|
||||
depends=(glfw mbedtls freetype2 libglvnd dbus gtk3 curl fmt yara nlohmann-json libarchive)
|
||||
depends=(glfw mbedtls freetype2 libglvnd dbus gtk3 curl fmt yara nlohmann-json)
|
||||
makedepends=(git)
|
||||
provides=(imhex)
|
||||
conflicts=(imhex)
|
||||
@@ -19,7 +19,7 @@ package() {
|
||||
install -Dm755 "$srcdir/usr/bin/imhex" "$pkgdir/usr/bin/imhex"
|
||||
install -Dm644 "$srcdir/usr/lib/libimhex.so.$pkgver" "$pkgdir/usr/lib/libimhex.so.$pkgver"
|
||||
|
||||
for plugin in "$srcdir/usr/lib/imhex/plugins/"*.hexplug*; do
|
||||
for plugin in "$srcdir/usr/lib/imhex/plugins/"*.hexplug; do
|
||||
install -Dm644 "$plugin" "$pkgdir/usr/lib/imhex/plugins/${plugin##*/}"
|
||||
done
|
||||
|
||||
|
||||
3
dist/Brewfile
vendored
3
dist/Brewfile
vendored
@@ -9,5 +9,4 @@ brew "curl"
|
||||
brew "gcc@12"
|
||||
brew "llvm"
|
||||
brew "glfw"
|
||||
brew "ninja"
|
||||
brew "libarchive"
|
||||
brew "ninja"
|
||||
2
dist/DEBIAN/control.in
vendored
2
dist/DEBIAN/control.in
vendored
@@ -4,7 +4,7 @@ Section: editors
|
||||
Priority: optional
|
||||
Architecture: amd64
|
||||
License: GNU GPL-2
|
||||
Depends: libglfw3 | libglfw3-wayland, libmagic1, libmbedtls14, libfreetype6, libopengl0, libdbus-1-3, xdg-desktop-portal, libarchive13
|
||||
Depends: libglfw3, libmagic1, libmbedtls14, libfreetype6, libopengl0, libdbus-1-3, xdg-desktop-portal
|
||||
Maintainer: WerWolv <hey@werwolv.net>
|
||||
Description: ImHex Hex Editor
|
||||
A Hex Editor for Reverse Engineers, Programmers and
|
||||
|
||||
1
dist/ImHex-9999.ebuild
vendored
1
dist/ImHex-9999.ebuild
vendored
@@ -24,6 +24,5 @@ RDEPEND="${DEPEND}
|
||||
dev-cpp/nlohmann_json
|
||||
dbus
|
||||
xdg-desktop-portal
|
||||
app-arch/libarchive
|
||||
"
|
||||
BDEPEND="${DEPEND}"
|
||||
|
||||
48
dist/compiling/docker.md
vendored
48
dist/compiling/docker.md
vendored
@@ -1,48 +0,0 @@
|
||||
For a TLDR of commands see [How to build](#How-to-build)
|
||||
|
||||
# Introduction
|
||||
|
||||
The original CI we used (vanilla Github Actions) was great for specifying what steps to execute to build packages. It could even do some custom steps with reusable actions. But it had problem: no local reproducibility. This meant that:
|
||||
- We couldn't test code properly locally, we were dependent on GitHub to do it
|
||||
- If something was wrong and we had to debug the build script, it was *long and painful* because we had to wait for Github runners to finish builds, and couldn't quickly iterate
|
||||
|
||||
To solve this, we are now trying to move the CI build script to docker containers (so using Dockerfiles)
|
||||
|
||||
# How to build
|
||||
|
||||
Commands are available in the [CI](../../.github/workflows/build.yml) and you should prefer copying them from there.
|
||||
But here is a general command that should work for every build we have:
|
||||
```
|
||||
docker buildx build . -f <DOCKERFILE_PATH> --progress plain --build-arg 'JOBS=4' --build-arg 'BUILD_TYPE=Debug' --build-context imhex=$(pwd) --output local
|
||||
```
|
||||
|
||||
where `<DOCKERFILE_PATH>` should be replaced by the wanted Dockerfile base d on the build you want to do:
|
||||
|
||||
| Wanted build | Dockerfile path |
|
||||
|--------------|-----------------------------|
|
||||
| MacOS M1 | dist/macOS/arm64.Dockerfile |
|
||||
| AppImage | dist/appimage/Dockerfile |
|
||||
| Web version | dist/web/Dockerfile |
|
||||
|
||||
We'll explain this command in the next section
|
||||
|
||||
# Useful knowledge about Docker builds
|
||||
|
||||
Docker-based builds work with a Dockerfile. You run the Dockerfile, it builds the package.
|
||||
|
||||
We are using a base environment (often given to us by dockerhub) (e.g. ubuntu:22.04) which is really just a root filesystem, and we then run shell commands in that env, just like a shell script
|
||||
|
||||
Docker-based builds have two kind of caches used:
|
||||
- layer cache, which mean that if a layer (instruction) hasn't been changed, and previous layers haven't changed, it will not be run again
|
||||
- a `COPY` layer will be invalidated if one of the file copied has changed
|
||||
- mount cache, which are per-instructions mounts that will be cached and restored in the next run. Mounts on different folders will not collide
|
||||
|
||||
Docker cache tends to grow very quickly when constantly making changes in the Dockerfile and rebuilding (a.k.a debugging what's going on), you can clear it with something like `docker system prune -a`
|
||||
|
||||
In the command saw earlier:
|
||||
- `.` is the base folder that the Dockerfile will be allowed to see
|
||||
- `-f <path>` is to specify the Dockerfile path
|
||||
- `--progress plain` is to allow you to see the output of instructions
|
||||
- `--build-arg <key>=<value>` is to allow to to specify arguments to the build (like -DKEY=VALUE in CMake)
|
||||
- `--build-context key=<folder>` is to specify folders other than the base folder that the Dockerfile is allowed to see
|
||||
- `--output <path>` is the path to write the output package to. If not specified, Docker will create an image as the output (probably not what you want)
|
||||
3
dist/compiling/macos.md
vendored
3
dist/compiling/macos.md
vendored
@@ -17,7 +17,8 @@ PKG_CONFIG_PATH="$(brew --prefix openssl)/lib/pkgconfig":"$(brew --prefix)/lib/p
|
||||
MACOSX_DEPLOYMENT_TARGET="10.15" \
|
||||
cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DIMHEX_GENERATE_PACKAGE=ON \
|
||||
-DCREATE_BUNDLE=ON \
|
||||
-DCREATE_PACKAGE=ON \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
|
||||
|
||||
27
dist/get_deps_archlinux.sh
vendored
27
dist/get_deps_archlinux.sh
vendored
@@ -1,18 +1,17 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
pacman -S $@ --needed \
|
||||
cmake \
|
||||
gcc \
|
||||
lld \
|
||||
glfw \
|
||||
file \
|
||||
mbedtls \
|
||||
freetype2 \
|
||||
dbus \
|
||||
gtk3 \
|
||||
curl \
|
||||
fmt \
|
||||
yara \
|
||||
cmake \
|
||||
gcc \
|
||||
lld \
|
||||
glfw \
|
||||
file \
|
||||
mbedtls \
|
||||
freetype2 \
|
||||
dbus \
|
||||
gtk3 \
|
||||
curl \
|
||||
fmt \
|
||||
yara \
|
||||
nlohmann-json \
|
||||
ninja \
|
||||
libarchive
|
||||
ninja
|
||||
|
||||
3
dist/get_deps_debian.sh
vendored
3
dist/get_deps_debian.sh
vendored
@@ -22,5 +22,4 @@ apt install -y \
|
||||
libdbus-1-dev \
|
||||
libcurl4-gnutls-dev \
|
||||
libgtk-3-dev \
|
||||
ninja-build \
|
||||
libarchive-dev
|
||||
ninja-build
|
||||
|
||||
3
dist/get_deps_fedora.sh
vendored
3
dist/get_deps_fedora.sh
vendored
@@ -12,5 +12,4 @@ dnf install -y \
|
||||
glfw-devel \
|
||||
lld \
|
||||
mbedtls-devel \
|
||||
gtk3-devel \
|
||||
libarchive-devel
|
||||
gtk3-devel
|
||||
3
dist/get_deps_msys2.sh
vendored
3
dist/get_deps_msys2.sh
vendored
@@ -12,5 +12,4 @@ pacman -S --needed --noconfirm \
|
||||
mingw-w64-x86_64-freetype \
|
||||
mingw-w64-x86_64-dlfcn \
|
||||
mingw-w64-x86_64-ninja \
|
||||
mingw-w64-x86_64-capstone \
|
||||
mingw-w64-x86_64-libarchive
|
||||
mingw-w64-x86_64-capstone
|
||||
|
||||
166
dist/macOS/arm64.Dockerfile
vendored
166
dist/macOS/arm64.Dockerfile
vendored
@@ -1,166 +0,0 @@
|
||||
# This base image is also known as "crosscompile". See arm64.crosscompile.Dockerfile
|
||||
FROM ghcr.io/itrooz/macos-crosscompile:clang17-nosdk as build
|
||||
|
||||
ENV MACOSX_DEPLOYMENT_TARGET 12.1
|
||||
|
||||
# -- DOWNLOADING STUFF
|
||||
|
||||
## Install make
|
||||
RUN --mount=type=cache,target=/var/lib/apt/lists/ apt update && apt install -y make
|
||||
|
||||
## fix environment
|
||||
### add install_name_tool for cmake command that won't have the right env set (see PostprocessBundle.cmake function postprocess_bundle())
|
||||
RUN cp /osxcross/build/cctools-port/cctools/misc/install_name_tool /usr/bin/install_name_tool
|
||||
### a cmake thing wants 'otool' and not '' apparently
|
||||
RUN cp /osxcross/target/bin/aarch64-apple-darwin23-otool /usr/bin/otool
|
||||
|
||||
## Clone glfw
|
||||
RUN <<EOF
|
||||
set -xe
|
||||
if [ "$CUSTOM_GLFW" ]; then
|
||||
git clone https://github.com/glfw/glfw /mnt/glfw
|
||||
fi
|
||||
EOF
|
||||
|
||||
RUN --mount=type=cache,target=/cache <<EOF
|
||||
## Download SDK is missing (it may have been removed from the image)
|
||||
set -xe
|
||||
if [ ! -d /osxcross/target/SDK/MacOSX14.0.sdk ]; then
|
||||
wget https://github.com/joseluisq/macosx-sdks/releases/download/14.0/MacOSX14.0.sdk.tar.xz -O /cache/MacOSX14.0.sdk.tar.xz -nc || true
|
||||
mkdir -p /osxcross/target/SDK
|
||||
tar -C /osxcross/target/SDK -xf /cache/MacOSX14.0.sdk.tar.xz
|
||||
fi
|
||||
EOF
|
||||
|
||||
|
||||
## Download libmagic
|
||||
### Clone libmagic
|
||||
RUN git clone https://github.com/file/file /mnt/file
|
||||
### Download libmagic dependencies
|
||||
RUN --mount=type=cache,target=/var/lib/apt/lists/ apt install -y libtool autoconf
|
||||
|
||||
# -- DOWNLOADING + BUILDING STUFF
|
||||
|
||||
ENV VCPKG_DEFAULT_BINARY_CACHE /cache/vcpkg
|
||||
RUN --mount=type=cache,target=/cache <<EOF
|
||||
## Install dependencies with vcpkg
|
||||
set -xe
|
||||
|
||||
mkdir -p $VCPKG_DEFAULT_BINARY_CACHE
|
||||
|
||||
vcpkg install --triplet=arm-osx-mytriplet curl
|
||||
vcpkg install --triplet=arm-osx-mytriplet mbedtls
|
||||
vcpkg install --triplet=arm-osx-mytriplet freetype
|
||||
vcpkg install --triplet=arm-osx-mytriplet josuttis-jthread
|
||||
vcpkg install --triplet=arm-osx-mytriplet libarchive
|
||||
EOF
|
||||
|
||||
## Install glfw3 dep
|
||||
ARG CUSTOM_GLFW
|
||||
RUN --mount=type=cache,target=/cache <<EOF
|
||||
set -xe
|
||||
if [ "$CUSTOM_GLFW" ]; then
|
||||
echo "Flag confirmation: using custom GLFW for software rendering"
|
||||
else
|
||||
echo "Flag confirmation: using system GLFW"
|
||||
vcpkg install --triplet=arm-osx-mytriplet glfw3
|
||||
fi
|
||||
EOF
|
||||
|
||||
# -- BUILDING STUFF
|
||||
ARG JOBS 1
|
||||
ARG BUILD_TYPE Debug
|
||||
|
||||
## Build libmagic
|
||||
RUN --mount=type=cache,target=/cache <<EOF
|
||||
ccache -zs
|
||||
set -xe
|
||||
|
||||
cd /mnt/file
|
||||
autoreconf -is
|
||||
|
||||
# when cross-compiling, libmagic needs to have an the same version installed in the system.
|
||||
# So we install it normally first
|
||||
./configure --prefix /usr
|
||||
make -j $JOBS install
|
||||
|
||||
# Now, we cross-compile it and install it in the libraries folder
|
||||
CC=/osxcross/target/bin/aarch64-apple-darwin23-clang CXX=/osxcross/target/bin/aarch64-apple-darwin23-clang++ ./configure --prefix /vcpkg/installed/arm-osx-mytriplet --host $OSXCROSS_HOST
|
||||
make -j $JOBS
|
||||
make install
|
||||
|
||||
ccache -s
|
||||
|
||||
EOF
|
||||
|
||||
## Patch glfw
|
||||
COPY --from=imhex /dist/macOS/0001-glfw-SW.patch /tmp
|
||||
RUN <<EOF
|
||||
set -xe
|
||||
if [ "$CUSTOM_GLFW" ]; then
|
||||
cd /mnt/glfw
|
||||
git apply /tmp/0001-glfw-SW.patch
|
||||
fi
|
||||
EOF
|
||||
|
||||
## Build glfw
|
||||
RUN --mount=type=cache,target=/cache <<EOF
|
||||
set -xe
|
||||
if [ "$CUSTOM_GLFW" ]; then
|
||||
ccache -zs
|
||||
|
||||
cd /mnt/glfw
|
||||
mkdir build
|
||||
cd build
|
||||
CC=o64-gcc CXX=o64-g++ cmake -G "Ninja" \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DBUILD_SHARED_LIBS=ON \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_INSTALL_PREFIX=/vcpkg/installed/arm-osx-mytriplet \
|
||||
-DVCPKG_TARGET_TRIPLET=arm-osx-mytriplet -DCMAKE_TOOLCHAIN_FILE=/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=/osxcross/target/toolchain.cmake -DCMAKE_OSX_SYSROOT=/osxcross/target/SDK/MacOSX14.0.sdk -DCMAKE_OSX_DEPLOYMENT_TARGET=14.0 \
|
||||
..
|
||||
ninja -j $JOBS install
|
||||
|
||||
ccache -s
|
||||
fi
|
||||
EOF
|
||||
|
||||
# Build ImHex
|
||||
## Copy ImHex
|
||||
COPY --from=imhex / /mnt/ImHex
|
||||
## Patch ImHex with hacks
|
||||
# COPY toolchain.cmake.2 /osxcross/target/toolchain.cmake
|
||||
# Configure ImHex build
|
||||
RUN --mount=type=cache,target=/cache --mount=type=cache,target=/mnt/ImHex/build/_deps \
|
||||
cd /mnt/ImHex && \
|
||||
# compilers
|
||||
CC=o64-clang CXX=o64-clang++ OBJC=/osxcross/target/bin/aarch64-apple-darwin23-clang OBJCXX=/osxcross/target/bin/aarch64-apple-darwin23-clang++ \
|
||||
cmake -G "Ninja" \
|
||||
`# ccache flags` \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_OBJC_COMPILER_LAUNCHER=ccache -DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
|
||||
`# MacOS cross-compiling flags` \
|
||||
-DVCPKG_TARGET_TRIPLET=arm-osx-mytriplet -DCMAKE_TOOLCHAIN_FILE=/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=/osxcross/target/toolchain.cmake -DCMAKE_OSX_SYSROOT=/osxcross/target/SDK/MacOSX14.0.sdk -DCMAKE_OSX_DEPLOYMENT_TARGET=14.0 \
|
||||
`# Override compilers for code generators` \
|
||||
-DNATIVE_CMAKE_C_COMPILER=/usr/bin/clang -DNATIVE_CMAKE_CXX_COMPILER=/usr/bin/clang++ \
|
||||
`# Normal ImHex flags` \
|
||||
-DIMHEX_GENERATE_PACKAGE=ON -DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
`# other flags` \
|
||||
-DIMHEX_STRICT_WARNINGS=OFF \
|
||||
-B build
|
||||
## Build ImHex
|
||||
RUN --mount=type=cache,target=/cache --mount=type=cache,target=/mnt/ImHex/build/_deps <<EOF
|
||||
ccache -zs
|
||||
set -xe
|
||||
|
||||
cd /mnt/ImHex
|
||||
cmake --build build --parallel $JOBS
|
||||
|
||||
ccache -s
|
||||
EOF
|
||||
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /mnt/ImHex/build/imhex.app imhex.app
|
||||
96
dist/macOS/arm64.crosscompile.Dockerfile
vendored
96
dist/macOS/arm64.crosscompile.Dockerfile
vendored
@@ -1,96 +0,0 @@
|
||||
# This image is is provided for reference, but a (probably more up to date) image should be available at https://github.com/iTrooz/macos-crosscompile
|
||||
FROM ubuntu:22.04
|
||||
|
||||
ENV PATH $PATH:/osxcross/target/bin
|
||||
ENV LD_LIBRARY_PATH /osxcross/target/lib
|
||||
ENV OSXCROSS_SDK /osxcross/target/SDK/MacOSX14.0.sdk
|
||||
ENV OSXCROSS_TARGET darwin23
|
||||
ENV OSXCROSS_TARGET_DIR /osxcross/target
|
||||
ENV OSXCROSS_HOST aarch64-apple-darwin23
|
||||
|
||||
# -- DOWNLOADING STUFF
|
||||
|
||||
# Install common stuff
|
||||
RUN --mount=type=cache,target=/var/lib/apt/lists/ export DEBIAN_FRONTEND=noninteractive &&\
|
||||
export TZ=Etc/UTC &&\
|
||||
dpkg --add-architecture i386 &&\
|
||||
apt update &&\
|
||||
apt -y install lsb-release build-essential python3 python3-pip git wget zip unzip pkg-config curl ninja-build software-properties-common gnupg libssl-dev ccache
|
||||
|
||||
# Install clang 17
|
||||
RUN --mount=type=cache,target=/var/lib/apt/lists/ wget https://apt.llvm.org/llvm.sh && chmod +x llvm.sh && ./llvm.sh 17 &&\
|
||||
ln -s /usr/bin/clang-17 /usr/bin/clang &&\
|
||||
ln -s /usr/bin/clang++-17 /usr/bin/clang++
|
||||
|
||||
# Install vcpkg
|
||||
RUN cd / &&\
|
||||
git clone --depth 1 https://github.com/Microsoft/vcpkg.git vcpkg &&\
|
||||
cd /vcpkg &&\
|
||||
./bootstrap-vcpkg.sh -disableMetrics &&\
|
||||
ln -s /vcpkg/vcpkg /usr/bin/ &&\
|
||||
vcpkg install vcpkg-cmake &&\
|
||||
ln -s /vcpkg/downloads/tools/cmake-*/cmake-*/bin/cmake /usr/bin/
|
||||
|
||||
RUN --mount=type=cache,target=/cache <<EOF
|
||||
## Clone osxcross
|
||||
set -xe
|
||||
git clone https://github.com/tpoechtrager/osxcross /cache/osxcross || true
|
||||
cd /cache/osxcross
|
||||
git pull
|
||||
cp -r /cache/osxcross /osxcross
|
||||
EOF
|
||||
|
||||
RUN --mount=type=cache,target=/cache <<EOF
|
||||
## Download SDK
|
||||
set -xe
|
||||
wget https://github.com/joseluisq/macosx-sdks/releases/download/14.0/MacOSX14.0.sdk.tar.xz -O /cache/MacOSX14.0.sdk.tar.xz -nc || true
|
||||
cp /cache/MacOSX14.0.sdk.tar.xz /osxcross/tarballs
|
||||
EOF
|
||||
|
||||
# Init stuff
|
||||
## setup ccache dir
|
||||
ENV CCACHE_DIR /cache/ccache
|
||||
|
||||
# Install triplet file
|
||||
COPY arm-osx-mytriplet.cmake /vcpkg/triplets/community
|
||||
|
||||
# -- BUILDING STUFF
|
||||
ARG JOBS 1
|
||||
|
||||
# Install osxcross
|
||||
## Build cross-compiler clang-17
|
||||
RUN --mount=type=cache,target=/cache <<EOF
|
||||
set -xe
|
||||
ccache -zs
|
||||
|
||||
cd /osxcross
|
||||
UNATTENDED=1 CC=/usr/lib/ccache/clang-17 CXX=/usr/lib/ccache/clang++-17 ./build.sh
|
||||
|
||||
ccache -s
|
||||
EOF
|
||||
# Not needed, because we don't use gcc for cross-compiling anymore
|
||||
# ## Install dependencies for gcc-13
|
||||
# RUN apt install -y gcc g++ zlib1g-dev libmpc-dev libmpfr-dev libgmp-dev
|
||||
# ## Build cross-compiler gcc-13
|
||||
# RUN --mount=type=cache,target=/cache <<EOF
|
||||
# set -xe
|
||||
# ccache -zs
|
||||
|
||||
# cd /osxcross
|
||||
# UNATTENDED=1 CC=/usr/lib/ccache/gcc CXX=/usr/lib/ccache/g++ GCC_VERSION=13.2.0 ./build_gcc.sh
|
||||
|
||||
# ccache -s
|
||||
# EOF
|
||||
|
||||
ARG DELETE_SDK=1
|
||||
RUN <<EOF
|
||||
# Conditionally delete the SDK from the image
|
||||
set -xe
|
||||
|
||||
if [ "$DELETE_SDK" ]; then
|
||||
rm -r /osxcross/target/SDK
|
||||
echo "Deleted the SDK from the image"
|
||||
else
|
||||
echo "NOT deleting the SDK from the image"
|
||||
fi
|
||||
EOF
|
||||
4
dist/macOS/macos_arm_toolchain.cmake
vendored
Normal file
4
dist/macOS/macos_arm_toolchain.cmake
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
set(CMAKE_SYSTEM_NAME Darwin)
|
||||
set(CMAKE_SYSTEM_PROCESSOR arm64)
|
||||
set(CMAKE_OSX_ARCHITECTURES arm64 CACHE INTERNAL "" FORCE)
|
||||
SET(CMAKE_OSX_SYSROOT macosx CACHE INTERNAL "" FORCE)
|
||||
3
dist/msys2/PKGBUILD
vendored
3
dist/msys2/PKGBUILD
vendored
@@ -16,8 +16,7 @@ makedepends=("${MINGW_PACKAGE_PREFIX}-gcc"
|
||||
"${MINGW_PACKAGE_PREFIX}-file"
|
||||
"${MINGW_PACKAGE_PREFIX}-mbedtls"
|
||||
"${MINGW_PACKAGE_PREFIX}-polly"
|
||||
"${MINGW_PACKAGE_PREFIX}-freetype"
|
||||
"${MINGW_PACKAGE_PREFIX}-libarchive")
|
||||
"${MINGW_PACKAGE_PREFIX}-freetype")
|
||||
|
||||
source=()
|
||||
sha256sums=()
|
||||
|
||||
43
dist/net.werwolv.ImHex.yaml
vendored
43
dist/net.werwolv.ImHex.yaml
vendored
@@ -12,10 +12,49 @@ finish-args:
|
||||
- --device=all
|
||||
|
||||
modules:
|
||||
- name: imhex
|
||||
buildsystem: cmake
|
||||
- name: libiconv
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.16.tar.gz
|
||||
sha256: e6a1b1b589654277ee790cce3734f07876ac4ccfaecbee8afa0b649cf529cc04
|
||||
|
||||
- name: glfw
|
||||
buildsystem: cmake-ninja
|
||||
builddir: true
|
||||
config-opts:
|
||||
- -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
- -DBUILD_SHARED_LIBS:BOOL=ON
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://github.com/glfw/glfw/releases/download/3.3.2/glfw-3.3.2.zip
|
||||
sha256: 08a33a512f29d7dbf78eab39bd7858576adcc95228c9efe8e4bc5f0f3261efc7
|
||||
cleanup:
|
||||
- /include
|
||||
- /lib/pkgconfig
|
||||
|
||||
- name: mbedtls
|
||||
buildsystem: cmake-ninja
|
||||
config-opts:
|
||||
- -DCMAKE_C_FLAGS=-fPIC
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://github.com/ARMmbed/mbedtls/archive/refs/tags/v2.27.0.tar.gz
|
||||
sha256: 2a07856e541f0e5f6eaee4f78018c52f25bd244ed76f9020dea54a8b02cac6ea
|
||||
|
||||
- name: nlohmann-json
|
||||
buildsystem: cmake-ninja
|
||||
builddir: true
|
||||
config-opts:
|
||||
- -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
- -DBUILD_TESTING=OFF
|
||||
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://github.com/nlohmann/json/archive/v3.9.1.tar.gz
|
||||
sha256: 4cf0df69731494668bdd6460ed8cb269b68de9c19ad8c27abc24cd72605b2d5b
|
||||
|
||||
- name: imhex
|
||||
buildsystem: cmake
|
||||
|
||||
sources:
|
||||
- type: git
|
||||
|
||||
13
dist/rpm/imhex.spec
vendored
13
dist/rpm/imhex.spec
vendored
@@ -27,7 +27,6 @@ BuildRequires: mbedtls-devel
|
||||
BuildRequires: yara-devel
|
||||
BuildRequires: nativefiledialog-extended-devel
|
||||
BuildRequires: dotnet-sdk-7.0
|
||||
BuildRequires: libarchive-devel
|
||||
%if 0%{?rhel}
|
||||
BuildRequires: gcc-toolset-12
|
||||
%endif
|
||||
@@ -62,7 +61,7 @@ same time ImHex is completely free and open source under the GPLv2 language.
|
||||
%prep
|
||||
%autosetup -n ImHex
|
||||
# remove bundled libs we aren't using
|
||||
rm -rf lib/third_party/{fmt,nlohmann_json,yara}
|
||||
rm -rf lib/external/{curl,fmt,llvm,nlohmann_json,yara}
|
||||
|
||||
%build
|
||||
%if 0%{?rhel}
|
||||
@@ -110,11 +109,11 @@ rm -f %{buildroot}%{_metainfodir}/net.werwolv.%{name}.appdata.xml
|
||||
appstream-util validate-relax --nonet %{buildroot}%{_metainfodir}/net.werwolv.%{name}.metainfo.xml
|
||||
|
||||
# install licenses
|
||||
cp -a lib/third_party/nativefiledialog/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/nativefiledialog-LICENSE
|
||||
cp -a lib/third_party/capstone/LICENSE.TXT %{buildroot}%{_datadir}/licenses/%{name}/capstone-LICENSE
|
||||
cp -a lib/third_party/capstone/suite/regress/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/capstone-regress-LICENSE
|
||||
cp -a lib/third_party/microtar/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/microtar-LICENSE
|
||||
cp -a lib/third_party/xdgpp/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/xdgpp-LICENSE
|
||||
cp -a lib/external/nativefiledialog/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/nativefiledialog-LICENSE
|
||||
cp -a lib/external/capstone/LICENSE.TXT %{buildroot}%{_datadir}/licenses/%{name}/capstone-LICENSE
|
||||
cp -a lib/external/capstone/suite/regress/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/capstone-regress-LICENSE
|
||||
cp -a lib/external/microtar/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/microtar-LICENSE
|
||||
cp -a lib/external/xdgpp/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/xdgpp-LICENSE
|
||||
|
||||
|
||||
%files
|
||||
|
||||
4
dist/web/Dockerfile
vendored
4
dist/web/Dockerfile
vendored
@@ -37,7 +37,6 @@ mkdir -p $VCPKG_DEFAULT_BINARY_CACHE
|
||||
/vcpkg/vcpkg install --triplet=wasm32-emscripten libmagic
|
||||
/vcpkg/vcpkg install --triplet=wasm32-emscripten freetype
|
||||
/vcpkg/vcpkg install --triplet=wasm32-emscripten mbedtls
|
||||
/vcpkg/vcpkg install --triplet=wasm32-emscripten libarchive
|
||||
EOF
|
||||
|
||||
# Build ImHex
|
||||
@@ -55,7 +54,6 @@ ccache -zs
|
||||
cmake /imhex \
|
||||
-DIMHEX_OFFLINE_BUILD=ON \
|
||||
-DIMHEX_STATIC_LINK_PLUGINS=ON \
|
||||
-DIMHEX_EXCLUDE_PLUGINS="script_loader" \
|
||||
-DNATIVE_CMAKE_C_COMPILER=gcc \
|
||||
-DNATIVE_CMAKE_CXX_COMPILER=g++ \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
@@ -85,8 +83,6 @@ COPY --from=build [ \
|
||||
"/build/favicon.ico", \
|
||||
"/build/icon.png", \
|
||||
"/build/manifest.json", \
|
||||
"/build/robots.txt", \
|
||||
"/build/sitemap.xml", \
|
||||
\
|
||||
# Destination \
|
||||
"./" \
|
||||
|
||||
51
dist/web/source/index.html
vendored
51
dist/web/source/index.html
vendored
@@ -1,22 +1,23 @@
|
||||
<!doctype html>
|
||||
<html lang="en-us">
|
||||
<head>
|
||||
<title>ImHex Web - Free Online Hex Editor for Reverse Engineers</title>
|
||||
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<link rel="manifest" href="manifest.json" />
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
|
||||
<!-- Primary Meta Tags -->
|
||||
<title>ImHex Web - Online Hex Editor</title>
|
||||
<meta name="title" content="ImHex">
|
||||
<meta name="description" content="Free and extremely powerful Online Hex Editor for your Web Browser. ImHex is a free and open source Hex Editor for Reverse Engineers and Developers and Data Analysts.">
|
||||
<meta name="description" content="A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM.">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
<link rel="apple-touch-icon" href="icon.png">
|
||||
|
||||
<!-- Open Graph / Facebook -->
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:url" content="https://imhex.werwolv.net/">
|
||||
<meta property="og:title" content="ImHex Web - Online Hex Editor">
|
||||
<meta property="og:description">
|
||||
<meta name="description" content="A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM.">
|
||||
<meta property="og:image" content="https://imhex.werwolv.net/assets/splash_wasm.png">
|
||||
|
||||
<!-- Twitter -->
|
||||
@@ -27,7 +28,9 @@
|
||||
content="A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM.">
|
||||
<meta property="twitter:image" content="https://imhex.werwolv.net/assets/splash_wasm.png">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
@@ -57,41 +60,15 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<title>ImHex Web</title>
|
||||
<script src="enable-threads.js"></script>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="loading" class="centered">
|
||||
<img src="https://raw.githubusercontent.com/WerWolv/ImHex/master/plugins/builtin/romfs/assets/dark/banner.png" id="logo" alt="ImHex Logo">
|
||||
<h1>A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM.</h1>
|
||||
<h2>Available both natively and on the web</h2>
|
||||
<h5>ImHex runs directly in your web browser with the help of Emscripten and WebAssembly.</h5>
|
||||
|
||||
<div style="height: 50%">
|
||||
<div style="height: 30%"> </div>
|
||||
<h2 id="not_working">
|
||||
Not loading in your Browser? <a href="https://imhex.werwolv.net">Try the native version</a>
|
||||
</h2>
|
||||
<div style="height: 50%"></div>
|
||||
</div>
|
||||
|
||||
<div class="loading_ripple">
|
||||
<div class="lds-ripple"><div></div><div></div></div>
|
||||
</div>
|
||||
|
||||
<div style="height: 10%">
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<a href="https://imhex.werwolv.net">Homepage</a>
|
||||
<p>Made with ♥️ by the ImHex Team</p>
|
||||
<a href="https://github.com/WerWolv/ImHex">GitHub</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p id="loading_text">ImHex is loading...</p>
|
||||
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas>
|
||||
|
||||
<script src="wasm-config.js"></script>
|
||||
<script async src="imhex.js"></script>
|
||||
<script type="text/javascript" src="wasm-config.js"></script>
|
||||
<script async type="text/javascript" src="imhex.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
4
dist/web/source/robots.txt
vendored
4
dist/web/source/robots.txt
vendored
@@ -1,4 +0,0 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
Sitemap: https://imhex.werwolv.net/sitemap.xml
|
||||
14
dist/web/source/sitemap.xml
vendored
14
dist/web/source/sitemap.xml
vendored
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset
|
||||
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
|
||||
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
|
||||
|
||||
<url>
|
||||
<loc>https://web.imhex.werwolv.net/</loc>
|
||||
<lastmod>2023-12-07T22:53:06+00:00</lastmod>
|
||||
</url>
|
||||
|
||||
|
||||
</urlset>
|
||||
123
dist/web/source/style.css
vendored
123
dist/web/source/style.css
vendored
@@ -1,6 +1,6 @@
|
||||
html, body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
margin: 0px;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@@ -16,120 +16,21 @@ body {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
display: none;
|
||||
border: 0 none;
|
||||
border: 0px none;
|
||||
}
|
||||
|
||||
h1, h2, h5 {
|
||||
color: #F0F0F0;
|
||||
font-size: 20px;
|
||||
font-family: monospace;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin-top: 60px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-top: 15px;
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
h5 {
|
||||
margin-top: 0;
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
#not_working {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#not_working.visible {
|
||||
opacity: 1;
|
||||
transition: opacity 2s ease;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #7893ff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-shadow: #3a4677 0 0 10px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
text-align: center;
|
||||
color: #F0F0F0;
|
||||
background-color: #0A0A0A;
|
||||
padding: 10px;
|
||||
font-family: monospace;
|
||||
font-size: 15px;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
gap: 10%;
|
||||
}
|
||||
|
||||
.centered {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.canvas_full_screen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
|
||||
.lds-ripple {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
.lds-ripple div {
|
||||
position: absolute;
|
||||
border: 4px solid #fff;
|
||||
opacity: 1;
|
||||
border-radius: 50%;
|
||||
animation: lds-ripple 1s cubic-bezier(0, 0.2, 0.8, 1) infinite;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.lds-ripple div:nth-child(2) {
|
||||
animation-delay: -0.5s;
|
||||
}
|
||||
@keyframes lds-ripple {
|
||||
0% {
|
||||
top: 36px;
|
||||
left: 36px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
4.9% {
|
||||
top: 36px;
|
||||
left: 36px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
5% {
|
||||
top: 36px;
|
||||
left: 36px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#loading_text {
|
||||
color: #F0F0F0;
|
||||
font-size: 30px;
|
||||
font-family: monospace;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
16
dist/web/source/wasm-config.js
vendored
16
dist/web/source/wasm-config.js
vendored
@@ -30,22 +30,16 @@ function glfwCreateStandardCursorCustom(shape) {
|
||||
return shape
|
||||
}
|
||||
|
||||
var notWorkingTimer = setTimeout(() => {
|
||||
document.getElementById("not_working").classList.add("visible")
|
||||
}, 5000);
|
||||
|
||||
var Module = {
|
||||
preRun: [],
|
||||
postRun: [],
|
||||
onRuntimeInitialized: function() {
|
||||
// Triggered when the wasm module is loaded and ready to use.
|
||||
document.getElementById("loading").style.display = "none"
|
||||
document.getElementById("loading_text").style.display = "none"
|
||||
document.getElementById("canvas").style.display = "initial"
|
||||
|
||||
clearTimeout(notWorkingTimer);
|
||||
},
|
||||
print: (function() { })(),
|
||||
printErr: function(text) { },
|
||||
printErr: function(text) { },
|
||||
canvas: (function() {
|
||||
let canvas = document.getElementById('canvas');
|
||||
// As a default initial behavior, pop up an alert when webgl context is lost. To make your
|
||||
@@ -73,10 +67,4 @@ function js_resizeCanvas() {
|
||||
canvas.height = Math.min(document.documentElement.clientHeight, window.innerHeight || 0);
|
||||
|
||||
canvas.classList.add("canvas_full_screen")
|
||||
|
||||
if (GLFW.active && GLFW.active.windowPosFunc) {
|
||||
getWasmTableEntry(GLFW.active.windowPosFunc)(GLFW.active.id, GLFW.active.x, GLFW.active.y);
|
||||
}
|
||||
|
||||
GLFW.onWindowSizeChanged();
|
||||
}
|
||||
0
lib/third_party/fmt → lib/external/fmt
vendored
0
lib/third_party/fmt → lib/external/fmt
vendored
40
lib/external/imgui/CMakeLists.txt
vendored
Normal file
40
lib/external/imgui/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(imgui)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
find_package(Freetype REQUIRED)
|
||||
find_package(OpenGL REQUIRED)
|
||||
pkg_search_module(GLFW REQUIRED glfw3)
|
||||
|
||||
add_library(imgui OBJECT
|
||||
source/imgui.cpp
|
||||
source/imgui_demo.cpp
|
||||
source/imgui_draw.cpp
|
||||
include/misc/freetype/imgui_freetype.cpp # TODO move source and includes in the same directory
|
||||
source/imgui_impl_glfw.cpp
|
||||
source/imgui_impl_opengl3.cpp
|
||||
source/imgui_tables.cpp
|
||||
source/imgui_widgets.cpp
|
||||
|
||||
source/TextEditor.cpp
|
||||
|
||||
source/imnodes.cpp
|
||||
|
||||
source/implot.cpp
|
||||
source/implot_items.cpp
|
||||
source/implot_demo.cpp
|
||||
|
||||
source/fonts/fontawesome_font.c
|
||||
source/fonts/codicons_font.c
|
||||
source/fonts/unifont_font.c
|
||||
)
|
||||
|
||||
target_compile_definitions(imgui PUBLIC IMGUI_IMPL_OPENGL_LOADER_GLAD)
|
||||
target_compile_definitions(imgui PUBLIC IMGUI_USER_CONFIG="imgui_config.h")
|
||||
target_compile_options(imgui PRIVATE -Wno-unknown-warning-option)
|
||||
|
||||
target_include_directories(imgui PUBLIC include ${FREETYPE_INCLUDE_DIRS} ${GLFW_INCLUDE_DIRS} ${OpenGL_INCLUDE_DIRS})
|
||||
target_link_directories(imgui PUBLIC ${GLFW_LIBRARY_DIRS} ${OpenGL_LIBRARY_DIRS})
|
||||
target_link_libraries(imgui PUBLIC Freetype::Freetype ${GLFW_LIBRARIES} ${OPENGL_LIBRARIES})
|
||||
@@ -9,7 +9,7 @@ extern const unsigned int codicons_compressed_size;
|
||||
extern const unsigned int codicons_compressed_data[52184/4];
|
||||
|
||||
#define ICON_MIN_VS 0xea60
|
||||
#define ICON_MAX_VS 0xec19
|
||||
#define ICON_MAX_VS 0xebdd
|
||||
#define ICON_VS_ADD "\xee\xa9\xa0" // U+ea60
|
||||
#define ICON_VS_PLUS "\xee\xa9\xa0" // U+ea60
|
||||
#define ICON_VS_GIST_NEW "\xee\xa9\xa0" // U+ea60
|
||||
@@ -473,4 +473,3 @@ extern const unsigned int codicons_compressed_data[52184/4];
|
||||
#define ICON_VS_GIT_PULL_REQUEST_DRAFT "\xee\xaf\x9b" // U+ebdb
|
||||
#define ICON_VS_DEBUG_ALL "\xee\xaf\x9c" // U+ebdc
|
||||
#define ICON_VS_DEBUG_COVERAGE "\xee\xaf\x9d" // U+ebdd
|
||||
#define ICON_VS_CHIP "\xee\xb0\x99" // U+ec19
|
||||
1015
lib/external/imgui/include/fonts/fontawesome_font.h
vendored
Normal file
1015
lib/external/imgui/include/fonts/fontawesome_font.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -126,19 +126,3 @@ namespace ImGui
|
||||
void MyFunction(const char* name, const MyMatrix44& v);
|
||||
}
|
||||
*/
|
||||
|
||||
#define IMGUI_ENABLE_TEST_ENGINE
|
||||
|
||||
|
||||
// IMPLOT CONFIG
|
||||
#define IMPLOT_CUSTOM_NUMERIC_TYPES (ImS8)(ImU8)(ImS16)(ImU16)(ImS32)(ImU32)(ImS64)(ImU64)(float)(double)(long double)
|
||||
|
||||
#define IM_OFFSETOF(_TYPE,_MEMBER) offsetof(_TYPE, _MEMBER)
|
||||
#define IM_FLOOR IM_TRUNC
|
||||
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
#define IMGUI_DISABLE_OBSOLETE_KEYIO
|
||||
#define IMGUI_ENABLE_FREETYPE
|
||||
#define ImDrawIdx unsigned int
|
||||
#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
|
||||
File diff suppressed because it is too large
Load Diff
9
lib/external/imgui/include/imgui_config.h
vendored
Normal file
9
lib/external/imgui/include/imgui_config.h
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// ImGui config (check imconfig.h for more information about these definitions)
|
||||
#pragma once
|
||||
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
#define IMGUI_DISABLE_OBSOLETE_KEYIO
|
||||
#define IMGUI_ENABLE_FREETYPE
|
||||
#define ImDrawIdx unsigned int
|
||||
#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
|
||||
@@ -16,15 +16,11 @@
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
struct GLFWwindow;
|
||||
struct GLFWmonitor;
|
||||
@@ -54,5 +50,3 @@ IMGUI_IMPL_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c);
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor* monitor, int event);
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
@@ -8,18 +8,10 @@
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices (Desktop OpenGL only).
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// About WebGL/ES:
|
||||
// - You need to '#define IMGUI_IMPL_OPENGL_ES2' or '#define IMGUI_IMPL_OPENGL_ES3' to use WebGL or OpenGL ES.
|
||||
// - This is done automatically on iOS, Android and Emscripten targets.
|
||||
// - For other targets, the define needs to be visible from the imgui_impl_opengl3.cpp compilation unit. If unsure, define globally or in imconfig.h.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
// About GLSL version:
|
||||
// The 'glsl_version' initialization parameter should be nullptr (default) or a "#version XXX" string.
|
||||
@@ -28,7 +20,6 @@
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
// Backend API
|
||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = nullptr);
|
||||
@@ -63,5 +54,3 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
@@ -32,12 +32,6 @@
|
||||
#ifndef __gl3w_h_
|
||||
#define __gl3w_h_
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <OpenGL/gl.h>
|
||||
#elif !defined(__EMSCRIPTEN__)
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
#if __has_include(<KHR/khrplatform.h>)
|
||||
#include <KHR/khrplatform.h>
|
||||
#else
|
||||
@@ -1163,9 +1157,7 @@ typedef khronos_uint16_t GLhalf;
|
||||
#define GL_TEXTURE_DEPTH_TYPE 0x8C16
|
||||
#define GL_UNSIGNED_NORMALIZED 0x8C17
|
||||
#define GL_FRAMEBUFFER_BINDING 0x8CA6
|
||||
#ifndef __APPLE__
|
||||
#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6
|
||||
#endif
|
||||
#define GL_RENDERBUFFER_BINDING 0x8CA7
|
||||
#define GL_READ_FRAMEBUFFER 0x8CA8
|
||||
#define GL_DRAW_FRAMEBUFFER 0x8CA9
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
// MIT License
|
||||
|
||||
// Copyright (c) 2023 Evan Pezent
|
||||
// Copyright (c) 2022 Evan Pezent
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -20,7 +20,7 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
// ImPlot v0.17
|
||||
// ImPlot v0.14
|
||||
|
||||
// Table of Contents:
|
||||
//
|
||||
@@ -60,7 +60,7 @@
|
||||
#endif
|
||||
|
||||
// ImPlot version string.
|
||||
#define IMPLOT_VERSION "0.17"
|
||||
#define IMPLOT_VERSION "0.14"
|
||||
// Indicates variable should deduced automatically.
|
||||
#define IMPLOT_AUTO -1
|
||||
// Special color used to indicate that a color should be deduced automatically.
|
||||
@@ -135,9 +135,10 @@ enum ImPlotFlags_ {
|
||||
ImPlotFlags_NoInputs = 1 << 3, // the user will not be able to interact with the plot
|
||||
ImPlotFlags_NoMenus = 1 << 4, // the user will not be able to open context menus
|
||||
ImPlotFlags_NoBoxSelect = 1 << 5, // the user will not be able to box-select
|
||||
ImPlotFlags_NoFrame = 1 << 6, // the ImGui frame will not be rendered
|
||||
ImPlotFlags_Equal = 1 << 7, // x and y axes pairs will be constrained to have the same units/pixel
|
||||
ImPlotFlags_Crosshairs = 1 << 8, // the default mouse cursor will be replaced with a crosshair when hovered
|
||||
ImPlotFlags_NoChild = 1 << 6, // a child window region will not be used to capture mouse scroll (can boost performance for single ImGui window applications)
|
||||
ImPlotFlags_NoFrame = 1 << 7, // the ImGui frame will not be rendered
|
||||
ImPlotFlags_Equal = 1 << 8, // x and y axes pairs will be constrained to have the same units/pixel
|
||||
ImPlotFlags_Crosshairs = 1 << 9, // the default mouse cursor will be replaced with a crosshair when hovered
|
||||
ImPlotFlags_CanvasOnly = ImPlotFlags_NoTitle | ImPlotFlags_NoLegend | ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect | ImPlotFlags_NoMouseText
|
||||
};
|
||||
|
||||
@@ -286,9 +287,8 @@ enum ImPlotInfLinesFlags_ {
|
||||
|
||||
// Flags for PlotPieChart
|
||||
enum ImPlotPieChartFlags_ {
|
||||
ImPlotPieChartFlags_None = 0, // default
|
||||
ImPlotPieChartFlags_Normalize = 1 << 10, // force normalization of pie chart values (i.e. always make a full circle if sum < 0)
|
||||
ImPlotPieChartFlags_IgnoreHidden = 1 << 11 // ignore hidden slices when drawing the pie chart (as if they were not there)
|
||||
ImPlotPieChartFlags_None = 0, // default
|
||||
ImPlotPieChartFlags_Normalize = 1 << 10 // force normalization of pie chart values (i.e. always make a full circle if sum < 0)
|
||||
};
|
||||
|
||||
// Flags for PlotHeatmap
|
||||
@@ -464,43 +464,41 @@ enum ImPlotBin_ {
|
||||
};
|
||||
|
||||
// Double precision version of ImVec2 used by ImPlot. Extensible by end users.
|
||||
IM_MSVC_RUNTIME_CHECKS_OFF
|
||||
struct ImPlotPoint {
|
||||
double x, y;
|
||||
constexpr ImPlotPoint() : x(0.0), y(0.0) { }
|
||||
constexpr ImPlotPoint(double _x, double _y) : x(_x), y(_y) { }
|
||||
constexpr ImPlotPoint(const ImVec2& p) : x((double)p.x), y((double)p.y) { }
|
||||
double& operator[] (size_t idx) { IM_ASSERT(idx == 0 || idx == 1); return ((double*)(void*)(char*)this)[idx]; }
|
||||
double operator[] (size_t idx) const { IM_ASSERT(idx == 0 || idx == 1); return ((const double*)(const void*)(const char*)this)[idx]; }
|
||||
ImPlotPoint() { x = y = 0.0; }
|
||||
ImPlotPoint(double _x, double _y) { x = _x; y = _y; }
|
||||
ImPlotPoint(const ImVec2& p) { x = p.x; y = p.y; }
|
||||
double operator[] (size_t idx) const { return (&x)[idx]; }
|
||||
double& operator[] (size_t idx) { return (&x)[idx]; }
|
||||
#ifdef IMPLOT_POINT_CLASS_EXTRA
|
||||
IMPLOT_POINT_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h
|
||||
// to convert back and forth between your math types and ImPlotPoint.
|
||||
#endif
|
||||
};
|
||||
IM_MSVC_RUNTIME_CHECKS_RESTORE
|
||||
|
||||
// Range defined by a min/max value.
|
||||
struct ImPlotRange {
|
||||
double Min, Max;
|
||||
constexpr ImPlotRange() : Min(0.0), Max(0.0) { }
|
||||
constexpr ImPlotRange(double _min, double _max) : Min(_min), Max(_max) { }
|
||||
bool Contains(double value) const { return value >= Min && value <= Max; }
|
||||
double Size() const { return Max - Min; }
|
||||
double Clamp(double value) const { return (value < Min) ? Min : (value > Max) ? Max : value; }
|
||||
ImPlotRange() { Min = 0; Max = 0; }
|
||||
ImPlotRange(double _min, double _max) { Min = _min; Max = _max; }
|
||||
bool Contains(double value) const { return value >= Min && value <= Max; }
|
||||
double Size() const { return Max - Min; }
|
||||
double Clamp(double value) const { return (value < Min) ? Min : (value > Max) ? Max : value; }
|
||||
};
|
||||
|
||||
// Combination of two range limits for X and Y axes. Also an AABB defined by Min()/Max().
|
||||
struct ImPlotRect {
|
||||
ImPlotRange X, Y;
|
||||
constexpr ImPlotRect() : X(0.0,0.0), Y(0.0,0.0) { }
|
||||
constexpr ImPlotRect(double x_min, double x_max, double y_min, double y_max) : X(x_min, x_max), Y(y_min, y_max) { }
|
||||
bool Contains(const ImPlotPoint& p) const { return Contains(p.x, p.y); }
|
||||
bool Contains(double x, double y) const { return X.Contains(x) && Y.Contains(y); }
|
||||
ImPlotPoint Size() const { return ImPlotPoint(X.Size(), Y.Size()); }
|
||||
ImPlotPoint Clamp(const ImPlotPoint& p) { return Clamp(p.x, p.y); }
|
||||
ImPlotPoint Clamp(double x, double y) { return ImPlotPoint(X.Clamp(x),Y.Clamp(y)); }
|
||||
ImPlotPoint Min() const { return ImPlotPoint(X.Min, Y.Min); }
|
||||
ImPlotPoint Max() const { return ImPlotPoint(X.Max, Y.Max); }
|
||||
ImPlotRect() { }
|
||||
ImPlotRect(double x_min, double x_max, double y_min, double y_max) { X.Min = x_min; X.Max = x_max; Y.Min = y_min; Y.Max = y_max; }
|
||||
bool Contains(const ImPlotPoint& p) const { return Contains(p.x, p.y); }
|
||||
bool Contains(double x, double y) const { return X.Contains(x) && Y.Contains(y); }
|
||||
ImPlotPoint Size() const { return ImPlotPoint(X.Size(), Y.Size()); }
|
||||
ImPlotPoint Clamp(const ImPlotPoint& p) { return Clamp(p.x, p.y); }
|
||||
ImPlotPoint Clamp(double x, double y) { return ImPlotPoint(X.Clamp(x),Y.Clamp(y)); }
|
||||
ImPlotPoint Min() const { return ImPlotPoint(X.Min, Y.Min); }
|
||||
ImPlotPoint Max() const { return ImPlotPoint(X.Max, Y.Max); }
|
||||
};
|
||||
|
||||
// Plot style structure
|
||||
@@ -730,7 +728,7 @@ IMPLOT_API void EndSubplots();
|
||||
|
||||
// Enables an axis or sets the label and/or flags for an existing axis. Leave #label = nullptr for no label.
|
||||
IMPLOT_API void SetupAxis(ImAxis axis, const char* label=nullptr, ImPlotAxisFlags flags=0);
|
||||
// Sets an axis range limits. If ImPlotCond_Always is used, the axes limits will be locked. Inversion with v_min > v_max is not supported; use SetupAxisLimits instead.
|
||||
// Sets an axis range limits. If ImPlotCond_Always is used, the axes limits will be locked.
|
||||
IMPLOT_API void SetupAxisLimits(ImAxis axis, double v_min, double v_max, ImPlotCond cond = ImPlotCond_Once);
|
||||
// Links an axis range limits to external values. Set to nullptr for no linkage. The pointer data must remain valid until EndPlot.
|
||||
IMPLOT_API void SetupAxisLinks(ImAxis axis, double* link_min, double* link_max);
|
||||
@@ -756,7 +754,7 @@ IMPLOT_API void SetupAxes(const char* x_label, const char* y_label, ImPlotAxisFl
|
||||
// Sets the primary X and Y axes range limits. If ImPlotCond_Always is used, the axes limits will be locked (shorthand for two calls to SetupAxisLimits).
|
||||
IMPLOT_API void SetupAxesLimits(double x_min, double x_max, double y_min, double y_max, ImPlotCond cond = ImPlotCond_Once);
|
||||
|
||||
// Sets up the plot legend. This can also be called immediately after BeginSubplots when using ImPlotSubplotFlags_ShareItems.
|
||||
// Sets up the plot legend.
|
||||
IMPLOT_API void SetupLegend(ImPlotLocation location, ImPlotLegendFlags flags=0);
|
||||
// Set the location of the current plot's mouse position text (default = South|East).
|
||||
IMPLOT_API void SetupMouseText(ImPlotLocation location, ImPlotMouseTextFlags flags=0);
|
||||
@@ -893,7 +891,6 @@ IMPLOT_TMP void PlotStems(const char* label_id, const T* xs, const T* ys, int co
|
||||
IMPLOT_TMP void PlotInfLines(const char* label_id, const T* values, int count, ImPlotInfLinesFlags flags=0, int offset=0, int stride=sizeof(T));
|
||||
|
||||
// Plots a pie chart. Center and radius are in plot units. #label_fmt can be set to nullptr for no labels.
|
||||
IMPLOT_TMP void PlotPieChart(const char* const label_ids[], const T* values, int count, double x, double y, double radius, ImPlotFormatter fmt, void* fmt_data=nullptr, double angle0=90, ImPlotPieChartFlags flags=0);
|
||||
IMPLOT_TMP void PlotPieChart(const char* const label_ids[], const T* values, int count, double x, double y, double radius, const char* label_fmt="%.1f", double angle0=90, ImPlotPieChartFlags flags=0);
|
||||
|
||||
// Plots a 2D heatmap chart. Values are expected to be in row-major order by default. Leave #scale_min and scale_max both at 0 for automatic color scaling, or set them to a predefined range. #label_fmt can be set to nullptr for no labels.
|
||||
@@ -926,18 +923,16 @@ IMPLOT_API void PlotDummy(const char* label_id, ImPlotDummyFlags flags=0);
|
||||
|
||||
// The following can be used to render interactive elements and/or annotations.
|
||||
// Like the item plotting functions above, they apply to the current x and y
|
||||
// axes, which can be changed with `SetAxis/SetAxes`. These functions return true
|
||||
// when user interaction causes the provided coordinates to change. Additional
|
||||
// user interactions can be retrieved through the optional output parameters.
|
||||
// axes, which can be changed with `SetAxis/SetAxes`.
|
||||
|
||||
// Shows a draggable point at x,y. #col defaults to ImGuiCol_Text.
|
||||
IMPLOT_API bool DragPoint(int id, double* x, double* y, const ImVec4& col, float size = 4, ImPlotDragToolFlags flags = 0, bool* out_clicked = nullptr, bool* out_hovered = nullptr, bool* held = nullptr);
|
||||
IMPLOT_API bool DragPoint(int id, double* x, double* y, const ImVec4& col, float size = 4, ImPlotDragToolFlags flags=0);
|
||||
// Shows a draggable vertical guide line at an x-value. #col defaults to ImGuiCol_Text.
|
||||
IMPLOT_API bool DragLineX(int id, double* x, const ImVec4& col, float thickness = 1, ImPlotDragToolFlags flags = 0, bool* out_clicked = nullptr, bool* out_hovered = nullptr, bool* held = nullptr);
|
||||
IMPLOT_API bool DragLineX(int id, double* x, const ImVec4& col, float thickness = 1, ImPlotDragToolFlags flags=0);
|
||||
// Shows a draggable horizontal guide line at a y-value. #col defaults to ImGuiCol_Text.
|
||||
IMPLOT_API bool DragLineY(int id, double* y, const ImVec4& col, float thickness = 1, ImPlotDragToolFlags flags = 0, bool* out_clicked = nullptr, bool* out_hovered = nullptr, bool* held = nullptr);
|
||||
IMPLOT_API bool DragLineY(int id, double* y, const ImVec4& col, float thickness = 1, ImPlotDragToolFlags flags=0);
|
||||
// Shows a draggable and resizeable rectangle.
|
||||
IMPLOT_API bool DragRect(int id, double* x1, double* y1, double* x2, double* y2, const ImVec4& col, ImPlotDragToolFlags flags = 0, bool* out_clicked = nullptr, bool* out_hovered = nullptr, bool* held = nullptr);
|
||||
IMPLOT_API bool DragRect(int id, double* x1, double* y1, double* x2, double* y2, const ImVec4& col, ImPlotDragToolFlags flags=0);
|
||||
|
||||
// Shows an annotation callout at a chosen point. Clamping keeps annotations in the plot area. Annotations are always rendered on top.
|
||||
IMPLOT_API void Annotation(double x, double y, const ImVec4& col, const ImVec2& pix_offset, bool clamp, bool round = false);
|
||||
@@ -1,6 +1,6 @@
|
||||
// MIT License
|
||||
|
||||
// Copyright (c) 2023 Evan Pezent
|
||||
// Copyright (c) 2022 Evan Pezent
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -20,7 +20,7 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
// ImPlot v0.17
|
||||
// ImPlot v0.14
|
||||
|
||||
// You may use this file to debug, understand or extend ImPlot features but we
|
||||
// don't provide any guarantee of forward compatibility!
|
||||
@@ -907,9 +907,8 @@ struct ImPlotAxis
|
||||
}
|
||||
|
||||
void PullLinks() {
|
||||
if (LinkedMin && LinkedMax) { SetRange(*LinkedMin, *LinkedMax); }
|
||||
else if (LinkedMin) { SetMin(*LinkedMin,true); }
|
||||
else if (LinkedMax) { SetMax(*LinkedMax,true); }
|
||||
if (LinkedMin) { SetMin(*LinkedMin,true); }
|
||||
if (LinkedMax) { SetMax(*LinkedMax,true); }
|
||||
}
|
||||
};
|
||||
|
||||
@@ -966,11 +965,9 @@ struct ImPlotLegend
|
||||
ImPlotLegendFlags PreviousFlags;
|
||||
ImPlotLocation Location;
|
||||
ImPlotLocation PreviousLocation;
|
||||
ImVec2 Scroll;
|
||||
ImVector<int> Indices;
|
||||
ImGuiTextBuffer Labels;
|
||||
ImRect Rect;
|
||||
ImRect RectClamped;
|
||||
bool Hovered;
|
||||
bool Held;
|
||||
bool CanGoInside;
|
||||
@@ -980,7 +977,6 @@ struct ImPlotLegend
|
||||
CanGoInside = true;
|
||||
Hovered = Held = false;
|
||||
Location = PreviousLocation = ImPlotLocation_NorthWest;
|
||||
Scroll = ImVec2(0,0);
|
||||
}
|
||||
|
||||
void Reset() { Indices.shrink(0); Labels.Buf.shrink(0); }
|
||||
@@ -1140,6 +1136,7 @@ struct ImPlotSubplot {
|
||||
ID = 0;
|
||||
Flags = PreviousFlags = ImPlotSubplotFlags_None;
|
||||
Rows = Cols = CurrentIdx = 0;
|
||||
FrameHovered = false;
|
||||
Items.Legend.Location = ImPlotLocation_North;
|
||||
Items.Legend.Flags = ImPlotLegendFlags_Horizontal|ImPlotLegendFlags_Outside;
|
||||
Items.Legend.CanGoInside = false;
|
||||
@@ -1218,6 +1215,9 @@ struct ImPlotContext {
|
||||
ImPlotAnnotationCollection Annotations;
|
||||
ImPlotTagCollection Tags;
|
||||
|
||||
// Flags
|
||||
bool ChildWindowMade;
|
||||
|
||||
// Style and Colormaps
|
||||
ImPlotStyle Style;
|
||||
ImVector<ImGuiColorMod> ColorModifiers;
|
||||
@@ -1414,15 +1414,13 @@ IMPLOT_API void ShowAxisContextMenu(ImPlotAxis& axis, ImPlotAxis* equal_axis, bo
|
||||
|
||||
// Gets the position of an inner rect that is located inside of an outer rect according to an ImPlotLocation and padding amount.
|
||||
IMPLOT_API ImVec2 GetLocationPos(const ImRect& outer_rect, const ImVec2& inner_size, ImPlotLocation location, const ImVec2& pad = ImVec2(0,0));
|
||||
// Calculates the bounding box size of a legend _before_ clipping.
|
||||
// Calculates the bounding box size of a legend
|
||||
IMPLOT_API ImVec2 CalcLegendSize(ImPlotItemGroup& items, const ImVec2& pad, const ImVec2& spacing, bool vertical);
|
||||
// Clips calculated legend size
|
||||
IMPLOT_API bool ClampLegendRect(ImRect& legend_rect, const ImRect& outer_rect, const ImVec2& pad);
|
||||
// Renders legend entries into a bounding box
|
||||
IMPLOT_API bool ShowLegendEntries(ImPlotItemGroup& items, const ImRect& legend_bb, bool interactable, const ImVec2& pad, const ImVec2& spacing, bool vertical, ImDrawList& DrawList);
|
||||
// Shows an alternate legend for the plot identified by #title_id, outside of the plot frame (can be called before or after of Begin/EndPlot but must occur in the same ImGui window! This is not thoroughly tested nor scrollable!).
|
||||
// Shows an alternate legend for the plot identified by #title_id, outside of the plot frame (can be called before or after of Begin/EndPlot but must occur in the same ImGui window!).
|
||||
IMPLOT_API void ShowAltLegend(const char* title_id, bool vertical = true, const ImVec2 size = ImVec2(0,0), bool interactable = true);
|
||||
// Shows a legend's context menu.
|
||||
// Shows an legends's context menu.
|
||||
IMPLOT_API bool ShowLegendContextMenu(ImPlotLegend& legend, bool visible);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -6,14 +6,13 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023/11/13: added support for ImFontConfig::RasterizationDensity field for scaling render density without scaling metrics.
|
||||
// 2023/08/01: added support for SVG fonts, enable by using '#define IMGUI_ENABLE_FREETYPE_LUNASVG' (#6591)
|
||||
// 2023/01/04: fixed a packing issue which in some occurrences would prevent large amount of glyphs from being packed correctly.
|
||||
// 2021/08/23: fixed crash when FT_Render_Glyph() fails to render a glyph and returns NULL.
|
||||
// 2021/03/05: added ImGuiFreeTypeBuilderFlags_Bitmap to load bitmap glyphs.
|
||||
// 2021/03/02: set 'atlas->TexPixelsUseColors = true' to help some backends with deciding of a prefered texture format.
|
||||
// 2021/01/28: added support for color-layered glyphs via ImGuiFreeTypeBuilderFlags_LoadColor (require Freetype 2.10+).
|
||||
// 2021/01/26: simplified integration by using '#define IMGUI_ENABLE_FREETYPE'. renamed ImGuiFreeType::XXX flags to ImGuiFreeTypeBuilderFlags_XXX for consistency with other API. removed ImGuiFreeType::BuildFontAtlas().
|
||||
// 2021/01/26: simplified integration by using '#define IMGUI_ENABLE_FREETYPE'.
|
||||
// renamed ImGuiFreeType::XXX flags to ImGuiFreeTypeBuilderFlags_XXX for consistency with other API. removed ImGuiFreeType::BuildFontAtlas().
|
||||
// 2020/06/04: fix for rare case where FT_Get_Char_Index() succeed but FT_Load_Glyph() fails.
|
||||
// 2019/02/09: added RasterizerFlags::Monochrome flag to disable font anti-aliasing (combine with ::MonoHinting for best results!)
|
||||
// 2019/01/15: added support for imgui allocators + added FreeType only override function SetAllocatorFunctions().
|
||||
@@ -34,8 +33,6 @@
|
||||
|
||||
// FIXME: cfg.OversampleH, OversampleV are not supported (but perhaps not so necessary with this rasterizer).
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_freetype.h"
|
||||
#include "imgui_internal.h" // ImMin,ImMax,ImFontAtlasBuild*,
|
||||
#include <stdint.h>
|
||||
@@ -45,15 +42,6 @@
|
||||
#include FT_GLYPH_H // <freetype/ftglyph.h>
|
||||
#include FT_SYNTHESIS_H // <freetype/ftsynth.h>
|
||||
|
||||
#ifdef IMGUI_ENABLE_FREETYPE_LUNASVG
|
||||
#include FT_OTSVG_H // <freetype/otsvg.h>
|
||||
#include FT_BBOX_H // <freetype/ftbbox.h>
|
||||
#include <lunasvg.h>
|
||||
#if !((FREETYPE_MAJOR >= 2) && (FREETYPE_MINOR >= 12))
|
||||
#error IMGUI_ENABLE_FREETYPE_LUNASVG requires FreeType version >= 2.12
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff)
|
||||
@@ -64,10 +52,8 @@
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
|
||||
#ifndef __clang__
|
||||
#pragma GCC diagnostic ignored "-Wsubobject-linkage" // warning: 'xxxx' has a field 'xxxx' whose type uses the anonymous namespace
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Data
|
||||
@@ -82,14 +68,6 @@ static void* (*GImGuiFreeTypeAllocFunc)(size_t size, void* user_data) = ImGuiFre
|
||||
static void (*GImGuiFreeTypeFreeFunc)(void* ptr, void* user_data) = ImGuiFreeTypeDefaultFreeFunc;
|
||||
static void* GImGuiFreeTypeAllocatorUserData = nullptr;
|
||||
|
||||
// Lunasvg support
|
||||
#ifdef IMGUI_ENABLE_FREETYPE_LUNASVG
|
||||
static FT_Error ImGuiLunasvgPortInit(FT_Pointer* state);
|
||||
static void ImGuiLunasvgPortFree(FT_Pointer* state);
|
||||
static FT_Error ImGuiLunasvgPortRender(FT_GlyphSlot slot, FT_Pointer* _state);
|
||||
static FT_Error ImGuiLunasvgPortPresetSlot(FT_GlyphSlot slot, FT_Bool cache, FT_Pointer* _state);
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Code
|
||||
//-------------------------------------------------------------------------
|
||||
@@ -167,8 +145,6 @@ namespace
|
||||
unsigned int UserFlags; // = ImFontConfig::RasterizerFlags
|
||||
FT_Int32 LoadFlags;
|
||||
FT_Render_Mode RenderMode;
|
||||
float RasterizationDensity;
|
||||
float InvRasterizationDensity;
|
||||
};
|
||||
|
||||
// From SDL_ttf: Handy routines for converting from fixed point
|
||||
@@ -211,9 +187,6 @@ namespace
|
||||
if (UserFlags & ImGuiFreeTypeBuilderFlags_LoadColor)
|
||||
LoadFlags |= FT_LOAD_COLOR;
|
||||
|
||||
RasterizationDensity = cfg.RasterizerDensity;
|
||||
InvRasterizationDensity = 1.0f / RasterizationDensity;
|
||||
|
||||
memset(&Info, 0, sizeof(Info));
|
||||
SetPixelHeight((uint32_t)cfg.SizePixels);
|
||||
|
||||
@@ -237,19 +210,19 @@ namespace
|
||||
FT_Size_RequestRec req;
|
||||
req.type = (UserFlags & ImGuiFreeTypeBuilderFlags_Bitmap) ? FT_SIZE_REQUEST_TYPE_NOMINAL : FT_SIZE_REQUEST_TYPE_REAL_DIM;
|
||||
req.width = 0;
|
||||
req.height = (uint32_t)(pixel_height * 64 * RasterizationDensity);
|
||||
req.height = (uint32_t)pixel_height * 64;
|
||||
req.horiResolution = 0;
|
||||
req.vertResolution = 0;
|
||||
FT_Request_Size(Face, &req);
|
||||
|
||||
// Update font info
|
||||
FT_Size_Metrics metrics = Face->size->metrics;
|
||||
Info.PixelHeight = (uint32_t)(pixel_height * InvRasterizationDensity);
|
||||
Info.Ascender = (float)FT_CEIL(metrics.ascender) * InvRasterizationDensity;
|
||||
Info.Descender = (float)FT_CEIL(metrics.descender) * InvRasterizationDensity;
|
||||
Info.LineSpacing = (float)FT_CEIL(metrics.height) * InvRasterizationDensity;
|
||||
Info.LineGap = (float)FT_CEIL(metrics.height - metrics.ascender + metrics.descender) * InvRasterizationDensity;
|
||||
Info.MaxAdvanceWidth = (float)FT_CEIL(metrics.max_advance) * InvRasterizationDensity;
|
||||
Info.PixelHeight = (uint32_t)pixel_height;
|
||||
Info.Ascender = (float)FT_CEIL(metrics.ascender);
|
||||
Info.Descender = (float)FT_CEIL(metrics.descender);
|
||||
Info.LineSpacing = (float)FT_CEIL(metrics.height);
|
||||
Info.LineGap = (float)FT_CEIL(metrics.height - metrics.ascender + metrics.descender);
|
||||
Info.MaxAdvanceWidth = (float)FT_CEIL(metrics.max_advance);
|
||||
}
|
||||
|
||||
const FT_Glyph_Metrics* FreeTypeFont::LoadGlyph(uint32_t codepoint)
|
||||
@@ -269,14 +242,7 @@ namespace
|
||||
|
||||
// Need an outline for this to work
|
||||
FT_GlyphSlot slot = Face->glyph;
|
||||
#ifdef IMGUI_ENABLE_FREETYPE_LUNASVG
|
||||
IM_ASSERT(slot->format == FT_GLYPH_FORMAT_OUTLINE || slot->format == FT_GLYPH_FORMAT_BITMAP || slot->format == FT_GLYPH_FORMAT_SVG);
|
||||
#else
|
||||
#if ((FREETYPE_MAJOR >= 2) && (FREETYPE_MINOR >= 12))
|
||||
IM_ASSERT(slot->format != FT_GLYPH_FORMAT_SVG && "The font contains SVG glyphs, you'll need to enable IMGUI_ENABLE_FREETYPE_LUNASVG in imconfig.h and install required libraries in order to use this font");
|
||||
#endif
|
||||
IM_ASSERT(slot->format == FT_GLYPH_FORMAT_OUTLINE || slot->format == FT_GLYPH_FORMAT_BITMAP);
|
||||
#endif // IMGUI_ENABLE_FREETYPE_LUNASVG
|
||||
|
||||
// Apply convenience transform (this is not picking from real "Bold"/"Italic" fonts! Merely applying FreeType helper transform. Oblique == Slanting)
|
||||
if (UserFlags & ImGuiFreeTypeBuilderFlags_Bold)
|
||||
@@ -703,15 +669,15 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
|
||||
const int ty = pack_rect.y + padding;
|
||||
|
||||
// Register glyph
|
||||
float x0 = info.OffsetX * src_tmp.Font.InvRasterizationDensity + font_off_x;
|
||||
float y0 = info.OffsetY * src_tmp.Font.InvRasterizationDensity + font_off_y;
|
||||
float x1 = x0 + info.Width * src_tmp.Font.InvRasterizationDensity;
|
||||
float y1 = y0 + info.Height * src_tmp.Font.InvRasterizationDensity;
|
||||
float x0 = info.OffsetX + font_off_x;
|
||||
float y0 = info.OffsetY + font_off_y;
|
||||
float x1 = x0 + info.Width;
|
||||
float y1 = y0 + info.Height;
|
||||
float u0 = (tx) / (float)atlas->TexWidth;
|
||||
float v0 = (ty) / (float)atlas->TexHeight;
|
||||
float u1 = (tx + info.Width) / (float)atlas->TexWidth;
|
||||
float v1 = (ty + info.Height) / (float)atlas->TexHeight;
|
||||
dst_font->AddGlyph(&cfg, (ImWchar)src_glyph.Codepoint, x0, y0, x1, y1, u0, v0, u1, v1, info.AdvanceX * src_tmp.Font.InvRasterizationDensity);
|
||||
dst_font->AddGlyph(&cfg, (ImWchar)src_glyph.Codepoint, x0, y0, x1, y1, u0, v0, u1, v1, info.AdvanceX);
|
||||
|
||||
ImFontGlyph* dst_glyph = &dst_font->Glyphs.back();
|
||||
IM_ASSERT(dst_glyph->Codepoint == src_glyph.Codepoint);
|
||||
@@ -804,14 +770,6 @@ static bool ImFontAtlasBuildWithFreeType(ImFontAtlas* atlas)
|
||||
// If you don't call FT_Add_Default_Modules() the rest of code may work, but FreeType won't use our custom allocator.
|
||||
FT_Add_Default_Modules(ft_library);
|
||||
|
||||
#ifdef IMGUI_ENABLE_FREETYPE_LUNASVG
|
||||
// Install svg hooks for FreeType
|
||||
// https://freetype.org/freetype2/docs/reference/ft2-properties.html#svg-hooks
|
||||
// https://freetype.org/freetype2/docs/reference/ft2-svg_fonts.html#svg_fonts
|
||||
SVG_RendererHooks hooks = { ImGuiLunasvgPortInit, ImGuiLunasvgPortFree, ImGuiLunasvgPortRender, ImGuiLunasvgPortPresetSlot };
|
||||
FT_Property_Set(ft_library, "ot-svg", "svg-hooks", &hooks);
|
||||
#endif // IMGUI_ENABLE_FREETYPE_LUNASVG
|
||||
|
||||
bool ret = ImFontAtlasBuildWithFreeTypeEx(ft_library, atlas, atlas->FontBuilderFlags);
|
||||
FT_Done_Library(ft_library);
|
||||
|
||||
@@ -832,115 +790,6 @@ void ImGuiFreeType::SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* u
|
||||
GImGuiFreeTypeAllocatorUserData = user_data;
|
||||
}
|
||||
|
||||
#ifdef IMGUI_ENABLE_FREETYPE_LUNASVG
|
||||
// For more details, see https://gitlab.freedesktop.org/freetype/freetype-demos/-/blob/master/src/rsvg-port.c
|
||||
// The original code from the demo is licensed under CeCILL-C Free Software License Agreement (https://gitlab.freedesktop.org/freetype/freetype/-/blob/master/LICENSE.TXT)
|
||||
struct LunasvgPortState
|
||||
{
|
||||
FT_Error err = FT_Err_Ok;
|
||||
lunasvg::Matrix matrix;
|
||||
std::unique_ptr<lunasvg::Document> svg = nullptr;
|
||||
};
|
||||
|
||||
static FT_Error ImGuiLunasvgPortInit(FT_Pointer* _state)
|
||||
{
|
||||
*_state = IM_NEW(LunasvgPortState)();
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
static void ImGuiLunasvgPortFree(FT_Pointer* _state)
|
||||
{
|
||||
IM_DELETE(*(LunasvgPortState**)_state);
|
||||
}
|
||||
|
||||
static FT_Error ImGuiLunasvgPortRender(FT_GlyphSlot slot, FT_Pointer* _state)
|
||||
{
|
||||
LunasvgPortState* state = *(LunasvgPortState**)_state;
|
||||
|
||||
// If there was an error while loading the svg in ImGuiLunasvgPortPresetSlot(), the renderer hook still get called, so just returns the error.
|
||||
if (state->err != FT_Err_Ok)
|
||||
return state->err;
|
||||
|
||||
// rows is height, pitch (or stride) equals to width * sizeof(int32)
|
||||
lunasvg::Bitmap bitmap((uint8_t*)slot->bitmap.buffer, slot->bitmap.width, slot->bitmap.rows, slot->bitmap.pitch);
|
||||
state->svg->setMatrix(state->svg->matrix().identity()); // Reset the svg matrix to the default value
|
||||
state->svg->render(bitmap, state->matrix); // state->matrix is already scaled and translated
|
||||
state->err = FT_Err_Ok;
|
||||
return state->err;
|
||||
}
|
||||
|
||||
static FT_Error ImGuiLunasvgPortPresetSlot(FT_GlyphSlot slot, FT_Bool cache, FT_Pointer* _state)
|
||||
{
|
||||
FT_SVG_Document document = (FT_SVG_Document)slot->other;
|
||||
LunasvgPortState* state = *(LunasvgPortState**)_state;
|
||||
FT_Size_Metrics& metrics = document->metrics;
|
||||
|
||||
// This function is called twice, once in the FT_Load_Glyph() and another right before ImGuiLunasvgPortRender().
|
||||
// If it's the latter, don't do anything because it's // already done in the former.
|
||||
if (cache)
|
||||
return state->err;
|
||||
|
||||
state->svg = lunasvg::Document::loadFromData((const char*)document->svg_document, document->svg_document_length);
|
||||
if (state->svg == nullptr)
|
||||
{
|
||||
state->err = FT_Err_Invalid_SVG_Document;
|
||||
return state->err;
|
||||
}
|
||||
|
||||
lunasvg::Box box = state->svg->box();
|
||||
double scale = std::min(metrics.x_ppem / box.w, metrics.y_ppem / box.h);
|
||||
double xx = (double)document->transform.xx / (1 << 16);
|
||||
double xy = -(double)document->transform.xy / (1 << 16);
|
||||
double yx = -(double)document->transform.yx / (1 << 16);
|
||||
double yy = (double)document->transform.yy / (1 << 16);
|
||||
double x0 = (double)document->delta.x / 64 * box.w / metrics.x_ppem;
|
||||
double y0 = -(double)document->delta.y / 64 * box.h / metrics.y_ppem;
|
||||
|
||||
// Scale and transform, we don't translate the svg yet
|
||||
state->matrix.identity();
|
||||
state->matrix.scale(scale, scale);
|
||||
state->matrix.transform(xx, xy, yx, yy, x0, y0);
|
||||
state->svg->setMatrix(state->matrix);
|
||||
|
||||
// Pre-translate the matrix for the rendering step
|
||||
state->matrix.translate(-box.x, -box.y);
|
||||
|
||||
// Get the box again after the transformation
|
||||
box = state->svg->box();
|
||||
|
||||
// Calculate the bitmap size
|
||||
slot->bitmap_left = FT_Int(box.x);
|
||||
slot->bitmap_top = FT_Int(-box.y);
|
||||
slot->bitmap.rows = (unsigned int)(ImCeil((float)box.h));
|
||||
slot->bitmap.width = (unsigned int)(ImCeil((float)box.w));
|
||||
slot->bitmap.pitch = slot->bitmap.width * 4;
|
||||
slot->bitmap.pixel_mode = FT_PIXEL_MODE_BGRA;
|
||||
|
||||
// Compute all the bearings and set them correctly. The outline is scaled already, we just need to use the bounding box.
|
||||
double metrics_width = box.w;
|
||||
double metrics_height = box.h;
|
||||
double horiBearingX = box.x;
|
||||
double horiBearingY = -box.y;
|
||||
double vertBearingX = slot->metrics.horiBearingX / 64.0 - slot->metrics.horiAdvance / 64.0 / 2.0;
|
||||
double vertBearingY = (slot->metrics.vertAdvance / 64.0 - slot->metrics.height / 64.0) / 2.0;
|
||||
slot->metrics.width = FT_Pos(IM_ROUND(metrics_width * 64.0)); // Using IM_ROUND() assume width and height are positive
|
||||
slot->metrics.height = FT_Pos(IM_ROUND(metrics_height * 64.0));
|
||||
slot->metrics.horiBearingX = FT_Pos(horiBearingX * 64);
|
||||
slot->metrics.horiBearingY = FT_Pos(horiBearingY * 64);
|
||||
slot->metrics.vertBearingX = FT_Pos(vertBearingX * 64);
|
||||
slot->metrics.vertBearingY = FT_Pos(vertBearingY * 64);
|
||||
|
||||
if (slot->metrics.vertAdvance == 0)
|
||||
slot->metrics.vertAdvance = FT_Pos(metrics_height * 1.2 * 64.0);
|
||||
|
||||
state->err = FT_Err_Ok;
|
||||
return state->err;
|
||||
}
|
||||
|
||||
#endif // #ifdef IMGUI_ENABLE_FREETYPE_LUNASVG
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
@@ -948,5 +797,3 @@ static FT_Error ImGuiLunasvgPortPresetSlot(FT_GlyphSlot slot, FT_Bool cache, FT_
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
@@ -2,8 +2,8 @@
|
||||
// (headers)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "imgui.h" // IMGUI_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
// Forward declarations
|
||||
struct ImFontAtlas;
|
||||
@@ -48,5 +48,3 @@ namespace ImGuiFreeType
|
||||
static inline bool BuildFontAtlas(ImFontAtlas* atlas, unsigned int flags = 0) { atlas->FontBuilderIO = GetBuilderForFreeType(); atlas->FontBuilderFlags = flags; return atlas->Build(); }
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
@@ -642,7 +642,7 @@ void TextEditor::HandleKeyboardInputs() {
|
||||
SetSelection(wordStart, wordEnd);
|
||||
Backspace();
|
||||
}
|
||||
else if (!IsReadOnly() && !ctrl && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Backspace)))
|
||||
else if (!IsReadOnly() && !ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Backspace)))
|
||||
Backspace();
|
||||
else if (!IsReadOnly() && ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Backspace))) {
|
||||
auto wordEnd = GetCursorPosition();
|
||||
@@ -1184,26 +1184,10 @@ void TextEditor::EnterCharacter(ImWchar aChar, bool aShift) {
|
||||
} else if (aChar == '\t') {
|
||||
auto &line = mLines[coord.mLine];
|
||||
auto cindex = GetCharacterIndex(coord);
|
||||
|
||||
if (!aShift) {
|
||||
auto spacesToInsert = mTabSize - (cindex % mTabSize);
|
||||
for (int j = 0; j < spacesToInsert; j++)
|
||||
line.insert(line.begin() + cindex, Glyph(' ', PaletteIndex::Background));
|
||||
SetCursorPosition(Coordinates(coord.mLine, GetCharacterColumn(coord.mLine, cindex + spacesToInsert)));
|
||||
} else {
|
||||
auto spacesToRemove = (cindex % mTabSize);
|
||||
if (spacesToRemove == 0) spacesToRemove = 4;
|
||||
|
||||
for (int j = 0; j < spacesToRemove; j++) {
|
||||
if ((line.begin() + cindex - 1)->mChar == ' ') {
|
||||
line.erase(line.begin() + cindex - 1);
|
||||
cindex -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
SetCursorPosition(Coordinates(coord.mLine, GetCharacterColumn(coord.mLine, std::max(0, cindex))));
|
||||
}
|
||||
|
||||
auto spacesToInsert = mTabSize - (cindex % mTabSize);
|
||||
for (int j = 0; j < spacesToInsert; j++)
|
||||
line.insert(line.begin() + cindex, Glyph(' ', PaletteIndex::Background));
|
||||
SetCursorPosition(Coordinates(coord.mLine, GetCharacterColumn(coord.mLine, cindex + spacesToInsert)));
|
||||
} else {
|
||||
char buf[7];
|
||||
int e = ImTextCharToUtf8(buf, 7, aChar);
|
||||
1095
lib/external/imgui/source/fonts/codicons_font.c
vendored
Normal file
1095
lib/external/imgui/source/fonts/codicons_font.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3025
lib/external/imgui/source/fonts/fontawesome_font.c
vendored
Normal file
3025
lib/external/imgui/source/fonts/fontawesome_font.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
116170
lib/external/imgui/source/fonts/unifont_font.c
vendored
Normal file
116170
lib/external/imgui/source/fonts/unifont_font.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -16,18 +16,12 @@
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys.
|
||||
// 2023-07-18: Inputs: Revert ignoring mouse data on GLFW_CURSOR_DISABLED as it can be used differently. User may set ImGuiConfigFLags_NoMouse if desired. (#5625, #6609)
|
||||
// 2023-06-12: Accept glfwGetTime() not returning a monotonically increasing value. This seems to happens on some Windows setup when peripherals disconnect, and is likely to also happen on browser + Emscripten. (#6491)
|
||||
// 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen/ImGuiMouseSource_Pen on Windows ONLY, using a custom WndProc hook. (#2702)
|
||||
// 2023-03-16: Inputs: Fixed key modifiers handling on secondary viewports (docking branch). Broken on 2023/01/04. (#6248, #6034)
|
||||
// 2023-03-14: Emscripten: Avoid using glfwGetError() and glfwGetGamepadState() which are not correctly implemented in Emscripten emulation. (#6240)
|
||||
@@ -38,7 +32,7 @@
|
||||
// 2022-10-18: Perform a dummy glfwGetError() read to cancel missing mouse cursors errors. Using GLFW_VERSION_COMBINED directly. (#5785)
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported).
|
||||
// 2022-09-01: Inputs: Honor GLFW_CURSOR_DISABLED by not setting mouse position *EDIT* Reverted 2023-07-18.
|
||||
// 2022-09-01: Inputs: Honor GLFW_CURSOR_DISABLED by not setting mouse position.
|
||||
// 2022-04-30: Inputs: Fixed ImGui_ImplGlfw_TranslateUntranslatedKey() for lower case letters on OSX.
|
||||
// 2022-03-23: Inputs: Fixed a regression in 1.87 which resulted in keyboard modifiers events being reported incorrectly on Linux/X11.
|
||||
// 2022-02-07: Added ImGui_ImplGlfw_InstallCallbacks()/ImGui_ImplGlfw_RestoreCallbacks() helpers to facilitate user installing callbacks after initializing backend.
|
||||
@@ -75,7 +69,6 @@
|
||||
// 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers.
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_glfw.h"
|
||||
|
||||
// Clang warnings with -Weverything
|
||||
@@ -114,11 +107,7 @@
|
||||
#define GLFW_HAS_WINDOW_HOVERED (GLFW_VERSION_COMBINED >= 3300) // 3.3+ GLFW_HOVERED
|
||||
#define GLFW_HAS_WINDOW_ALPHA (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwSetWindowOpacity
|
||||
#define GLFW_HAS_PER_MONITOR_DPI (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetMonitorContentScale
|
||||
#if defined(__EMSCRIPTEN__) || defined(__SWITCH__) // no Vulkan support in GLFW for Emscripten or homebrew Nintendo Switch
|
||||
#define GLFW_HAS_VULKAN (0)
|
||||
#else
|
||||
#define GLFW_HAS_VULKAN (GLFW_VERSION_COMBINED >= 3200) // 3.2+ glfwCreateWindowSurface
|
||||
#endif
|
||||
#define GLFW_HAS_FOCUS_WINDOW (GLFW_VERSION_COMBINED >= 3200) // 3.2+ glfwFocusWindow
|
||||
#define GLFW_HAS_FOCUS_ON_SHOW (GLFW_VERSION_COMBINED >= 3300) // 3.3+ GLFW_FOCUS_ON_SHOW
|
||||
#define GLFW_HAS_MONITOR_WORK_AREA (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetMonitorWorkarea
|
||||
@@ -170,7 +159,7 @@ struct ImGui_ImplGlfw_Data
|
||||
GLFWcharfun PrevUserCallbackChar;
|
||||
GLFWmonitorfun PrevUserCallbackMonitor;
|
||||
#ifdef _WIN32
|
||||
WNDPROC PrevWndProc;
|
||||
WNDPROC GlfwWndProc;
|
||||
#endif
|
||||
|
||||
ImGui_ImplGlfw_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
@@ -313,18 +302,6 @@ static ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int key)
|
||||
case GLFW_KEY_F10: return ImGuiKey_F10;
|
||||
case GLFW_KEY_F11: return ImGuiKey_F11;
|
||||
case GLFW_KEY_F12: return ImGuiKey_F12;
|
||||
case GLFW_KEY_F13: return ImGuiKey_F13;
|
||||
case GLFW_KEY_F14: return ImGuiKey_F14;
|
||||
case GLFW_KEY_F15: return ImGuiKey_F15;
|
||||
case GLFW_KEY_F16: return ImGuiKey_F16;
|
||||
case GLFW_KEY_F17: return ImGuiKey_F17;
|
||||
case GLFW_KEY_F18: return ImGuiKey_F18;
|
||||
case GLFW_KEY_F19: return ImGuiKey_F19;
|
||||
case GLFW_KEY_F20: return ImGuiKey_F20;
|
||||
case GLFW_KEY_F21: return ImGuiKey_F21;
|
||||
case GLFW_KEY_F22: return ImGuiKey_F22;
|
||||
case GLFW_KEY_F23: return ImGuiKey_F23;
|
||||
case GLFW_KEY_F24: return ImGuiKey_F24;
|
||||
default: return ImGuiKey_None;
|
||||
}
|
||||
}
|
||||
@@ -444,6 +421,8 @@ void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
if (bd->PrevUserCallbackCursorPos != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
|
||||
bd->PrevUserCallbackCursorPos(window, x, y);
|
||||
if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED)
|
||||
return;
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
@@ -464,6 +443,8 @@ void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered)
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
if (bd->PrevUserCallbackCursorEnter != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
|
||||
bd->PrevUserCallbackCursorEnter(window, entered);
|
||||
if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED)
|
||||
return;
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (entered)
|
||||
@@ -514,7 +495,48 @@ static EM_BOOL ImGui_ImplEmscripten_WheelCallback(int, const EmscriptenWheelEven
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
// GLFW doesn't allow to distinguish Mouse vs TouchScreen vs Pen.
|
||||
// Add support for Win32 (based on imgui_impl_win32), because we rely on _TouchScreen info to trickle inputs differently.
|
||||
static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo()
|
||||
{
|
||||
LPARAM extra_info = ::GetMessageExtraInfo();
|
||||
if ((extra_info & 0xFFFFFF80) == 0xFF515700)
|
||||
return ImGuiMouseSource_Pen;
|
||||
if ((extra_info & 0xFFFFFF80) == 0xFF515780)
|
||||
return ImGuiMouseSource_TouchScreen;
|
||||
return ImGuiMouseSource_Mouse;
|
||||
}
|
||||
static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
switch (msg)
|
||||
{
|
||||
case WM_MOUSEMOVE: case WM_NCMOUSEMOVE:
|
||||
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_LBUTTONUP:
|
||||
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: case WM_RBUTTONUP:
|
||||
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: case WM_MBUTTONUP:
|
||||
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK: case WM_XBUTTONUP:
|
||||
ImGui::GetIO().AddMouseSourceEvent(GetMouseSourceFromMessageExtraInfo());
|
||||
break;
|
||||
|
||||
// We have submitted https://github.com/glfw/glfw/pull/1568 to allow GLFW to support "transparent inputs".
|
||||
// In the meanwhile we implement custom per-platform workarounds here (FIXME-VIEWPORT: Implement same work-around for Linux/OSX!)
|
||||
#if !GLFW_HAS_MOUSE_PASSTHROUGH && GLFW_HAS_WINDOW_HOVERED
|
||||
case WM_NCHITTEST:
|
||||
{
|
||||
// Let mouse pass-through the window. This will allow the backend to call io.AddMouseViewportEvent() properly (which is OPTIONAL).
|
||||
// The ImGuiViewportFlags_NoInputs flag is set while dragging a viewport, as want to detect the window behind the one we are dragging.
|
||||
// If you cannot easily access those viewport flags from your windowing/event code: you may manually synchronize its state e.g. in
|
||||
// your main loop after calling UpdatePlatformWindows(). Iterate all viewports/platform windows and pass the flag to your windowing system.
|
||||
ImGuiViewport* viewport = (ImGuiViewport*)::GetPropA(hWnd, "IMGUI_VIEWPORT");
|
||||
if (viewport && (viewport->Flags & ImGuiViewportFlags_NoInputs))
|
||||
return HTTRANSPARENT;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return ::CallWindowProc(bd->GlfwWndProc, hWnd, msg, wParam, lParam);
|
||||
}
|
||||
#endif
|
||||
|
||||
void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window)
|
||||
@@ -654,8 +676,8 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
||||
|
||||
// Windows: register a WndProc hook so we can intercept some messages.
|
||||
#ifdef _WIN32
|
||||
bd->PrevWndProc = (WNDPROC)::GetWindowLongPtr((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC);
|
||||
IM_ASSERT(bd->PrevWndProc != nullptr);
|
||||
bd->GlfwWndProc = (WNDPROC)::GetWindowLongPtr((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC);
|
||||
IM_ASSERT(bd->GlfwWndProc != nullptr);
|
||||
::SetWindowLongPtr((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc);
|
||||
#endif
|
||||
|
||||
@@ -688,18 +710,15 @@ void ImGui_ImplGlfw_Shutdown()
|
||||
|
||||
if (bd->InstalledCallbacks)
|
||||
ImGui_ImplGlfw_RestoreCallbacks(bd->Window);
|
||||
#ifdef __EMSCRIPTEN__
|
||||
emscripten_set_wheel_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, nullptr, false, nullptr);
|
||||
#endif
|
||||
|
||||
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
|
||||
glfwDestroyCursor(bd->MouseCursors[cursor_n]);
|
||||
|
||||
// Windows: restore our WndProc hook
|
||||
// Windows: register a WndProc hook so we can intercept some messages.
|
||||
#ifdef _WIN32
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
::SetWindowLongPtr((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)bd->PrevWndProc);
|
||||
bd->PrevWndProc = nullptr;
|
||||
::SetWindowLongPtr((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)bd->GlfwWndProc);
|
||||
bd->GlfwWndProc = nullptr;
|
||||
#endif
|
||||
|
||||
io.BackendPlatformName = nullptr;
|
||||
@@ -714,6 +733,11 @@ static void ImGui_ImplGlfw_UpdateMouseData()
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
if (glfwGetInputMode(bd->Window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
|
||||
return;
|
||||
}
|
||||
|
||||
ImGuiID mouse_viewport_id = 0;
|
||||
const ImVec2 mouse_pos_prev = io.MousePos;
|
||||
@@ -869,14 +893,17 @@ static void ImGui_ImplGlfw_UpdateMonitors()
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
bd->WantUpdateMonitors = false;
|
||||
|
||||
int monitors_count = 0;
|
||||
GLFWmonitor** glfw_monitors = glfwGetMonitors(&monitors_count);
|
||||
if (monitors_count == 0) // Preserve existing monitor list if there are none. Happens on macOS sleeping (#5683)
|
||||
return;
|
||||
|
||||
platform_io.Monitors.resize(0);
|
||||
|
||||
// IMHEX PATCH BEGIN
|
||||
// REASON: Prevent occasional crash when having ImHex open and connecting to the computer over RDP
|
||||
// NOTE: Untested with this ImGui version
|
||||
if (monitors_count > 0)
|
||||
platform_io.Monitors.resize(0);
|
||||
// IMHEX PATCH END
|
||||
|
||||
bd->WantUpdateMonitors = false;
|
||||
for (int n = 0; n < monitors_count; n++)
|
||||
{
|
||||
ImGuiPlatformMonitor monitor;
|
||||
@@ -900,12 +927,7 @@ static void ImGui_ImplGlfw_UpdateMonitors()
|
||||
// Warning: the validity of monitor DPI information on Windows depends on the application DPI awareness settings, which generally needs to be set in the manifest or at runtime.
|
||||
float x_scale, y_scale;
|
||||
glfwGetMonitorContentScale(glfw_monitors[n], &x_scale, &y_scale);
|
||||
|
||||
// IMHEX PATCH BEGIN
|
||||
// REASON: Prevent occasional crash when a monitor connection status is changed
|
||||
if (x_scale > 0)
|
||||
monitor.DpiScale = x_scale;
|
||||
// IMHEX PATCH END
|
||||
monitor.DpiScale = x_scale;
|
||||
#endif
|
||||
monitor.PlatformHandle = (void*)glfw_monitors[n]; // [...] GLFW doc states: "guaranteed to be valid only until the monitor configuration changes"
|
||||
platform_io.Monitors.push_back(monitor);
|
||||
@@ -930,10 +952,7 @@ void ImGui_ImplGlfw_NewFrame()
|
||||
ImGui_ImplGlfw_UpdateMonitors();
|
||||
|
||||
// Setup time step
|
||||
// (Accept glfwGetTime() not returning a monotonically increasing value. Seems to happens on disconnecting peripherals and probably on VMs and Emscripten, see #6491, #6189, #6114, #3644)
|
||||
double current_time = glfwGetTime();
|
||||
if (current_time <= bd->Time)
|
||||
current_time = bd->Time + 0.00001f;
|
||||
io.DeltaTime = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f);
|
||||
bd->Time = current_time;
|
||||
|
||||
@@ -957,11 +976,8 @@ struct ImGui_ImplGlfw_ViewportData
|
||||
bool WindowOwned;
|
||||
int IgnoreWindowPosEventFrame;
|
||||
int IgnoreWindowSizeEventFrame;
|
||||
#ifdef _WIN32
|
||||
WNDPROC PrevWndProc;
|
||||
#endif
|
||||
|
||||
ImGui_ImplGlfw_ViewportData() { memset(this, 0, sizeof(*this)); IgnoreWindowSizeEventFrame = IgnoreWindowPosEventFrame = -1; }
|
||||
ImGui_ImplGlfw_ViewportData() { Window = nullptr; WindowOwned = false; IgnoreWindowSizeEventFrame = IgnoreWindowPosEventFrame = -1; }
|
||||
~ImGui_ImplGlfw_ViewportData() { IM_ASSERT(Window == nullptr); }
|
||||
};
|
||||
|
||||
@@ -1099,8 +1115,9 @@ static void ImGui_ImplGlfw_ShowWindow(ImGuiViewport* viewport)
|
||||
|
||||
// GLFW hack: install hook for WM_NCHITTEST message handler
|
||||
#if !GLFW_HAS_MOUSE_PASSTHROUGH && GLFW_HAS_WINDOW_HOVERED && defined(_WIN32)
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
::SetPropA(hwnd, "IMGUI_VIEWPORT", viewport);
|
||||
vd->PrevWndProc = (WNDPROC)::GetWindowLongPtr(hwnd, GWLP_WNDPROC);
|
||||
IM_ASSERT(bd->GlfwWndProc == (WNDPROC)::GetWindowLongPtr(hwnd, GWLP_WNDPROC));
|
||||
::SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc);
|
||||
#endif
|
||||
|
||||
@@ -1286,63 +1303,6 @@ static void ImGui_ImplGlfw_ShutdownPlatformInterface()
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// WndProc hook (declared here because we will need access to ImGui_ImplGlfw_ViewportData)
|
||||
#ifdef _WIN32
|
||||
static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo()
|
||||
{
|
||||
LPARAM extra_info = ::GetMessageExtraInfo();
|
||||
if ((extra_info & 0xFFFFFF80) == 0xFF515700)
|
||||
return ImGuiMouseSource_Pen;
|
||||
if ((extra_info & 0xFFFFFF80) == 0xFF515780)
|
||||
return ImGuiMouseSource_TouchScreen;
|
||||
return ImGuiMouseSource_Mouse;
|
||||
}
|
||||
static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
WNDPROC prev_wndproc = bd->PrevWndProc;
|
||||
ImGuiViewport* viewport = (ImGuiViewport*)::GetPropA(hWnd, "IMGUI_VIEWPORT");
|
||||
if (viewport != NULL)
|
||||
if (ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData)
|
||||
prev_wndproc = vd->PrevWndProc;
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
// GLFW doesn't allow to distinguish Mouse vs TouchScreen vs Pen.
|
||||
// Add support for Win32 (based on imgui_impl_win32), because we rely on _TouchScreen info to trickle inputs differently.
|
||||
case WM_MOUSEMOVE: case WM_NCMOUSEMOVE:
|
||||
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_LBUTTONUP:
|
||||
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: case WM_RBUTTONUP:
|
||||
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: case WM_MBUTTONUP:
|
||||
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK: case WM_XBUTTONUP:
|
||||
ImGui::GetIO().AddMouseSourceEvent(GetMouseSourceFromMessageExtraInfo());
|
||||
break;
|
||||
|
||||
// We have submitted https://github.com/glfw/glfw/pull/1568 to allow GLFW to support "transparent inputs".
|
||||
// In the meanwhile we implement custom per-platform workarounds here (FIXME-VIEWPORT: Implement same work-around for Linux/OSX!)
|
||||
#if !GLFW_HAS_MOUSE_PASSTHROUGH && GLFW_HAS_WINDOW_HOVERED
|
||||
case WM_NCHITTEST:
|
||||
{
|
||||
// Let mouse pass-through the window. This will allow the backend to call io.AddMouseViewportEvent() properly (which is OPTIONAL).
|
||||
// The ImGuiViewportFlags_NoInputs flag is set while dragging a viewport, as want to detect the window behind the one we are dragging.
|
||||
// If you cannot easily access those viewport flags from your windowing/event code: you may manually synchronize its state e.g. in
|
||||
// your main loop after calling UpdatePlatformWindows(). Iterate all viewports/platform windows and pass the flag to your windowing system.
|
||||
if (viewport && (viewport->Flags & ImGuiViewportFlags_NoInputs))
|
||||
return HTTRANSPARENT;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return ::CallWindowProc(prev_wndproc, hWnd, msg, wParam, lParam);
|
||||
}
|
||||
#endif // #ifdef _WIN32
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
@@ -8,25 +8,14 @@
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices (Desktop OpenGL only).
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// About WebGL/ES:
|
||||
// - You need to '#define IMGUI_IMPL_OPENGL_ES2' or '#define IMGUI_IMPL_OPENGL_ES3' to use WebGL or OpenGL ES.
|
||||
// - This is done automatically on iOS, Android and Emscripten targets.
|
||||
// - For other targets, the define needs to be visible from the imgui_impl_opengl3.cpp compilation unit. If unsure, define globally or in imconfig.h.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2023-11-08: OpenGL: Update GL3W based imgui_impl_opengl3_loader.h to load "libGL.so" instead of "libGL.so.1", accomodating for NetBSD systems having only "libGL.so.3" available. (#6983)
|
||||
// 2023-10-05: OpenGL: Rename symbols in our internal loader so that LTO compilation with another copy of gl3w is possible. (#6875, #6668, #4445)
|
||||
// 2023-06-20: OpenGL: Fixed erroneous use glGetIntegerv(GL_CONTEXT_PROFILE_MASK) on contexts lower than 3.2. (#6539, #6333)
|
||||
// 2023-05-09: OpenGL: Support for glBindSampler() backup/restore on ES3. (#6375)
|
||||
// 2023-04-18: OpenGL: Restore front and back polygon mode separately when supported by context. (#6333)
|
||||
// 2023-03-23: OpenGL: Properly restoring "no shader program bound" if it was the case prior to running the rendering function. (#6267, #6220, #6224)
|
||||
@@ -111,10 +100,13 @@
|
||||
#endif
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_opengl3.h"
|
||||
#include <stdio.h>
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
|
||||
#include <stddef.h> // intptr_t
|
||||
#else
|
||||
#include <stdint.h> // intptr_t
|
||||
#endif
|
||||
#if defined(__APPLE__)
|
||||
#include <TargetConditionals.h>
|
||||
#endif
|
||||
@@ -292,12 +284,7 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
io.BackendRendererName = "imgui_impl_opengl3";
|
||||
|
||||
// Query for GL version (e.g. 320 for GL 3.2)
|
||||
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
||||
// GLES 2
|
||||
bd->GlVersion = 200;
|
||||
bd->GlProfileIsES2 = true;
|
||||
#else
|
||||
// Desktop or GLES 3
|
||||
#if !defined(IMGUI_IMPL_OPENGL_ES2)
|
||||
GLint major = 0;
|
||||
GLint minor = 0;
|
||||
glGetIntegerv(GL_MAJOR_VERSION, &major);
|
||||
@@ -310,15 +297,10 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
}
|
||||
bd->GlVersion = (GLuint)(major * 100 + minor * 10);
|
||||
#if defined(GL_CONTEXT_PROFILE_MASK)
|
||||
if (bd->GlVersion >= 320)
|
||||
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &bd->GlProfileMask);
|
||||
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &bd->GlProfileMask);
|
||||
bd->GlProfileIsCompat = (bd->GlProfileMask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) != 0;
|
||||
#endif
|
||||
|
||||
#if defined(IMGUI_IMPL_OPENGL_ES3)
|
||||
bd->GlProfileIsES3 = true;
|
||||
#endif
|
||||
|
||||
bd->UseBufferSubData = false;
|
||||
/*
|
||||
// Query vendor to enable glBufferSubData kludge
|
||||
@@ -328,10 +310,16 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
bd->UseBufferSubData = true;
|
||||
#endif
|
||||
*/
|
||||
#elif defined(IMGUI_IMPL_OPENGL_ES2)
|
||||
bd->GlVersion = 200; // GLES 2
|
||||
bd->GlProfileIsES2 = true;
|
||||
#elif defined(IMGUI_IMPL_OPENGL_ES3)
|
||||
bd->GlVersion = 200; // Don't raise version as it is intended as a desktop version check for now.
|
||||
bd->GlProfileIsES3 = true;
|
||||
#endif
|
||||
|
||||
#ifdef IMGUI_IMPL_OPENGL_DEBUG
|
||||
printf("GlVersion = %d\nGlProfileIsCompat = %d\nGlProfileMask = 0x%X\nGlProfileIsES2 = %d, GlProfileIsES3 = %d\nGL_VENDOR = '%s'\nGL_RENDERER = '%s'\n", bd->GlVersion, bd->GlProfileIsCompat, bd->GlProfileMask, bd->GlProfileIsES2, bd->GlProfileIsES3, (const char*)glGetString(GL_VENDOR), (const char*)glGetString(GL_RENDERER)); // [DEBUG]
|
||||
printf("GL_MAJOR_VERSION = %d\nGL_MINOR_VERSION = %d\nGL_VENDOR = '%s'\nGL_RENDERER = '%s'\n", major, minor, (const char*)glGetString(GL_VENDOR), (const char*)glGetString(GL_RENDERER)); // [DEBUG]
|
||||
#endif
|
||||
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
|
||||
@@ -473,9 +461,9 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
|
||||
GL_CALL(glEnableVertexAttribArray(bd->AttribLocationVtxPos));
|
||||
GL_CALL(glEnableVertexAttribArray(bd->AttribLocationVtxUV));
|
||||
GL_CALL(glEnableVertexAttribArray(bd->AttribLocationVtxColor));
|
||||
GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)offsetof(ImDrawVert, pos)));
|
||||
GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)offsetof(ImDrawVert, uv)));
|
||||
GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)offsetof(ImDrawVert, col)));
|
||||
GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos)));
|
||||
GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv)));
|
||||
GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col)));
|
||||
}
|
||||
|
||||
// OpenGL3 Render function.
|
||||
@@ -974,13 +962,9 @@ static void ImGui_ImplOpenGL3_ShutdownPlatformInterface()
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
// MIT License
|
||||
|
||||
// Copyright (c) 2023 Evan Pezent
|
||||
// Copyright (c) 2022 Evan Pezent
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -20,7 +20,7 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
// ImPlot v0.17
|
||||
// ImPlot v0.14
|
||||
|
||||
/*
|
||||
|
||||
@@ -31,9 +31,6 @@ Below is a change-log of API breaking changes only. If you are using one of the
|
||||
When you are not sure about a old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all implot files.
|
||||
You can read releases logs https://github.com/epezent/implot/releases for more details.
|
||||
|
||||
- 2023/08/20 (0.17) - ImPlotFlags_NoChild was removed as child windows are no longer needed to capture scroll. You can safely remove this flag if you were using it.
|
||||
- 2023/06/26 (0.15) - Various build fixes related to updates in Dear ImGui internals.
|
||||
- 2022/11/25 (0.15) - Make PlotText honor ImPlotItemFlags_NoFit.
|
||||
- 2022/06/19 (0.14) - The signature of ColormapScale has changed to accommodate a new ImPlotColormapScaleFlags parameter
|
||||
- 2022/06/17 (0.14) - **IMPORTANT** All PlotX functions now take an ImPlotX_Flags `flags` parameter. Where applicable, it is located before the existing `offset` and `stride` parameters.
|
||||
If you were providing offset and stride values, you will need to update your function call to include a `flags` value. If you fail to do this, you will likely see
|
||||
@@ -136,11 +133,6 @@ You can read releases logs https://github.com/epezent/implot/releases for more d
|
||||
#define ImDrawFlags_RoundCornersAll ImDrawCornerFlags_All
|
||||
#endif
|
||||
|
||||
// Support for pre-1.89.7 versions.
|
||||
#if (IMGUI_VERSION_NUM < 18966)
|
||||
#define ImGuiButtonFlags_AllowOverlap ImGuiButtonFlags_AllowItemOverlap
|
||||
#endif
|
||||
|
||||
// Visual Studio warnings
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
|
||||
@@ -293,35 +285,35 @@ struct ImPlotStyleVarInfo {
|
||||
|
||||
static const ImPlotStyleVarInfo GPlotStyleVarInfo[] =
|
||||
{
|
||||
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImPlotStyle, LineWeight) }, // ImPlotStyleVar_LineWeight
|
||||
{ ImGuiDataType_S32, 1, (ImU32)offsetof(ImPlotStyle, Marker) }, // ImPlotStyleVar_Marker
|
||||
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImPlotStyle, MarkerSize) }, // ImPlotStyleVar_MarkerSize
|
||||
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImPlotStyle, MarkerWeight) }, // ImPlotStyleVar_MarkerWeight
|
||||
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImPlotStyle, FillAlpha) }, // ImPlotStyleVar_FillAlpha
|
||||
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImPlotStyle, ErrorBarSize) }, // ImPlotStyleVar_ErrorBarSize
|
||||
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImPlotStyle, ErrorBarWeight) }, // ImPlotStyleVar_ErrorBarWeight
|
||||
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImPlotStyle, DigitalBitHeight) }, // ImPlotStyleVar_DigitalBitHeight
|
||||
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImPlotStyle, DigitalBitGap) }, // ImPlotStyleVar_DigitalBitGap
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, LineWeight) }, // ImPlotStyleVar_LineWeight
|
||||
{ ImGuiDataType_S32, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, Marker) }, // ImPlotStyleVar_Marker
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, MarkerSize) }, // ImPlotStyleVar_MarkerSize
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, MarkerWeight) }, // ImPlotStyleVar_MarkerWeight
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, FillAlpha) }, // ImPlotStyleVar_FillAlpha
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, ErrorBarSize) }, // ImPlotStyleVar_ErrorBarSize
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, ErrorBarWeight) }, // ImPlotStyleVar_ErrorBarWeight
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, DigitalBitHeight) }, // ImPlotStyleVar_DigitalBitHeight
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, DigitalBitGap) }, // ImPlotStyleVar_DigitalBitGap
|
||||
|
||||
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImPlotStyle, PlotBorderSize) }, // ImPlotStyleVar_PlotBorderSize
|
||||
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImPlotStyle, MinorAlpha) }, // ImPlotStyleVar_MinorAlpha
|
||||
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImPlotStyle, MajorTickLen) }, // ImPlotStyleVar_MajorTickLen
|
||||
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImPlotStyle, MinorTickLen) }, // ImPlotStyleVar_MinorTickLen
|
||||
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImPlotStyle, MajorTickSize) }, // ImPlotStyleVar_MajorTickSize
|
||||
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImPlotStyle, MinorTickSize) }, // ImPlotStyleVar_MinorTickSize
|
||||
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImPlotStyle, MajorGridSize) }, // ImPlotStyleVar_MajorGridSize
|
||||
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImPlotStyle, MinorGridSize) }, // ImPlotStyleVar_MinorGridSize
|
||||
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImPlotStyle, PlotPadding) }, // ImPlotStyleVar_PlotPadding
|
||||
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImPlotStyle, LabelPadding) }, // ImPlotStyleVar_LabelPaddine
|
||||
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImPlotStyle, LegendPadding) }, // ImPlotStyleVar_LegendPadding
|
||||
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImPlotStyle, LegendInnerPadding) }, // ImPlotStyleVar_LegendInnerPadding
|
||||
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImPlotStyle, LegendSpacing) }, // ImPlotStyleVar_LegendSpacing
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, PlotBorderSize) }, // ImPlotStyleVar_PlotBorderSize
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, MinorAlpha) }, // ImPlotStyleVar_MinorAlpha
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MajorTickLen) }, // ImPlotStyleVar_MajorTickLen
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MinorTickLen) }, // ImPlotStyleVar_MinorTickLen
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MajorTickSize) }, // ImPlotStyleVar_MajorTickSize
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MinorTickSize) }, // ImPlotStyleVar_MinorTickSize
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MajorGridSize) }, // ImPlotStyleVar_MajorGridSize
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MinorGridSize) }, // ImPlotStyleVar_MinorGridSize
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, PlotPadding) }, // ImPlotStyleVar_PlotPadding
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, LabelPadding) }, // ImPlotStyleVar_LabelPaddine
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, LegendPadding) }, // ImPlotStyleVar_LegendPadding
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, LegendInnerPadding) }, // ImPlotStyleVar_LegendInnerPadding
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, LegendSpacing) }, // ImPlotStyleVar_LegendSpacing
|
||||
|
||||
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImPlotStyle, MousePosPadding) }, // ImPlotStyleVar_MousePosPadding
|
||||
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImPlotStyle, AnnotationPadding) }, // ImPlotStyleVar_AnnotationPadding
|
||||
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImPlotStyle, FitPadding) }, // ImPlotStyleVar_FitPadding
|
||||
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImPlotStyle, PlotDefaultSize) }, // ImPlotStyleVar_PlotDefaultSize
|
||||
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImPlotStyle, PlotMinSize) } // ImPlotStyleVar_PlotMinSize
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MousePosPadding) }, // ImPlotStyleVar_MousePosPadding
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, AnnotationPadding) }, // ImPlotStyleVar_AnnotationPadding
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, FitPadding) }, // ImPlotStyleVar_FitPadding
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, PlotDefaultSize) }, // ImPlotStyleVar_PlotDefaultSize
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, PlotMinSize) } // ImPlotStyleVar_PlotMinSize
|
||||
};
|
||||
|
||||
static const ImPlotStyleVarInfo* GetPlotStyleVarInfo(ImPlotStyleVar idx) {
|
||||
@@ -341,8 +333,8 @@ void AddTextVertical(ImDrawList *DrawList, ImVec2 pos, ImU32 col, const char *te
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImFont* font = g.Font;
|
||||
// Align to be pixel perfect
|
||||
pos.x = ImFloor(pos.x);
|
||||
pos.y = ImFloor(pos.y);
|
||||
pos.x = IM_FLOOR(pos.x);
|
||||
pos.y = IM_FLOOR(pos.y);
|
||||
const float scale = g.FontSize / font->FontSize;
|
||||
const char* s = text_begin;
|
||||
int chars_exp = (int)(text_end - s);
|
||||
@@ -493,6 +485,10 @@ void Initialize(ImPlotContext* ctx) {
|
||||
}
|
||||
|
||||
void ResetCtxForNextPlot(ImPlotContext* ctx) {
|
||||
// end child window if it was made
|
||||
if (ctx->ChildWindowMade)
|
||||
ImGui::EndChild();
|
||||
ctx->ChildWindowMade = false;
|
||||
// reset the next plot/item data
|
||||
ctx->NextPlotData.Reset();
|
||||
ctx->NextItemData.Reset();
|
||||
@@ -586,28 +582,6 @@ ImVec2 CalcLegendSize(ImPlotItemGroup& items, const ImVec2& pad, const ImVec2& s
|
||||
return legend_size;
|
||||
}
|
||||
|
||||
bool ClampLegendRect(ImRect& legend_rect, const ImRect& outer_rect, const ImVec2& pad) {
|
||||
bool clamped = false;
|
||||
ImRect outer_rect_pad(outer_rect.Min + pad, outer_rect.Max - pad);
|
||||
if (legend_rect.Min.x < outer_rect_pad.Min.x) {
|
||||
legend_rect.Min.x = outer_rect_pad.Min.x;
|
||||
clamped = true;
|
||||
}
|
||||
if (legend_rect.Min.y < outer_rect_pad.Min.y) {
|
||||
legend_rect.Min.y = outer_rect_pad.Min.y;
|
||||
clamped = true;
|
||||
}
|
||||
if (legend_rect.Max.x > outer_rect_pad.Max.x) {
|
||||
legend_rect.Max.x = outer_rect_pad.Max.x;
|
||||
clamped = true;
|
||||
}
|
||||
if (legend_rect.Max.y > outer_rect_pad.Max.y) {
|
||||
legend_rect.Max.y = outer_rect_pad.Max.y;
|
||||
clamped = true;
|
||||
}
|
||||
return clamped;
|
||||
}
|
||||
|
||||
int LegendSortingComp(const void* _a, const void* _b) {
|
||||
ImPlotItemGroup* items = GImPlot->SortItems;
|
||||
const int a = *(const int*)_a;
|
||||
@@ -1322,12 +1296,12 @@ bool DragFloat(const char*, F*, float, F, F) {
|
||||
|
||||
template <>
|
||||
bool DragFloat<double>(const char* label, double* v, float v_speed, double v_min, double v_max) {
|
||||
return ImGui::DragScalar(label, ImGuiDataType_Double, v, v_speed, &v_min, &v_max, "%.3g", 1);
|
||||
return ImGui::DragScalar(label, ImGuiDataType_Double, v, v_speed, &v_min, &v_max, "%.3f", 1);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool DragFloat<float>(const char* label, float* v, float v_speed, float v_min, float v_max) {
|
||||
return ImGui::DragScalar(label, ImGuiDataType_Float, v, v_speed, &v_min, &v_max, "%.3g", 1);
|
||||
return ImGui::DragScalar(label, ImGuiDataType_Float, v, v_speed, &v_min, &v_max, "%.3f", 1);
|
||||
}
|
||||
|
||||
inline void BeginDisabledControls(bool cond) {
|
||||
@@ -1574,7 +1548,7 @@ void ShowPlotContextMenu(ImPlotPlot& plot) {
|
||||
ImFlipFlag(plot.Flags, ImPlotFlags_Crosshairs);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (gp.CurrentSubplot != nullptr && !ImHasFlag(gp.CurrentSubplot->Flags, ImPlotSubplotFlags_NoMenus)) {
|
||||
if (gp.CurrentSubplot != nullptr && !ImHasFlag(gp.CurrentPlot->Flags, ImPlotSubplotFlags_NoMenus)) {
|
||||
ImGui::Separator();
|
||||
if ((ImGui::BeginMenu("Subplots"))) {
|
||||
ShowSubplotsContextMenu(*gp.CurrentSubplot);
|
||||
@@ -1834,7 +1808,7 @@ bool UpdateInput(ImPlotPlot& plot) {
|
||||
|
||||
// BUTTON STATE -----------------------------------------------------------
|
||||
|
||||
const ImGuiButtonFlags plot_button_flags = ImGuiButtonFlags_AllowOverlap
|
||||
const ImGuiButtonFlags plot_button_flags = ImGuiButtonFlags_AllowItemOverlap
|
||||
| ImGuiButtonFlags_PressedOnClick
|
||||
| ImGuiButtonFlags_PressedOnDoubleClick
|
||||
| ImGuiButtonFlags_MouseButtonLeft
|
||||
@@ -1844,9 +1818,7 @@ bool UpdateInput(ImPlotPlot& plot) {
|
||||
| plot_button_flags;
|
||||
|
||||
const bool plot_clicked = ImGui::ButtonBehavior(plot.PlotRect,plot.ID,&plot.Hovered,&plot.Held,plot_button_flags);
|
||||
#if (IMGUI_VERSION_NUM < 18966)
|
||||
ImGui::SetItemAllowOverlap(); // Handled by ButtonBehavior()
|
||||
#endif
|
||||
ImGui::SetItemAllowOverlap();
|
||||
|
||||
if (plot_clicked) {
|
||||
if (!ImHasFlag(plot.Flags, ImPlotFlags_NoBoxSelect) && IO.MouseClicked[gp.InputMap.Select] && ImHasFlag(IO.KeyMods, gp.InputMap.SelectMod)) {
|
||||
@@ -1979,12 +1951,10 @@ bool UpdateInput(ImPlotPlot& plot) {
|
||||
|
||||
// SCROLL INPUT -----------------------------------------------------------
|
||||
|
||||
if (any_hov && ImHasFlag(IO.KeyMods, gp.InputMap.ZoomMod)) {
|
||||
if (any_hov && IO.MouseWheel != 0 && ImHasFlag(IO.KeyMods, gp.InputMap.ZoomMod)) {
|
||||
|
||||
float zoom_rate = gp.InputMap.ZoomRate;
|
||||
if (IO.MouseWheel == 0.0f)
|
||||
zoom_rate = 0;
|
||||
else if (IO.MouseWheel > 0)
|
||||
if (IO.MouseWheel > 0)
|
||||
zoom_rate = (-zoom_rate) / (1.0f + (2.0f * zoom_rate));
|
||||
ImVec2 rect_size = plot.PlotRect.GetSize();
|
||||
float tx = ImRemap(IO.MousePos.x, plot.PlotRect.Min.x, plot.PlotRect.Max.x, 0.0f, 1.0f);
|
||||
@@ -1995,17 +1965,14 @@ bool UpdateInput(ImPlotPlot& plot) {
|
||||
const bool equal_zoom = axis_equal && x_axis.OrthoAxis != nullptr;
|
||||
const bool equal_locked = (equal_zoom != false) && x_axis.OrthoAxis->IsInputLocked();
|
||||
if (x_hov[i] && !x_axis.IsInputLocked() && !equal_locked) {
|
||||
ImGui::SetKeyOwner(ImGuiKey_MouseWheelY, plot.ID);
|
||||
if (zoom_rate != 0.0f) {
|
||||
float correction = (plot.Hovered && equal_zoom) ? 0.5f : 1.0f;
|
||||
const double plot_l = x_axis.PixelsToPlot(plot.PlotRect.Min.x - rect_size.x * tx * zoom_rate * correction);
|
||||
const double plot_r = x_axis.PixelsToPlot(plot.PlotRect.Max.x + rect_size.x * (1 - tx) * zoom_rate * correction);
|
||||
x_axis.SetMin(x_axis.IsInverted() ? plot_r : plot_l);
|
||||
x_axis.SetMax(x_axis.IsInverted() ? plot_l : plot_r);
|
||||
if (axis_equal && x_axis.OrthoAxis != nullptr)
|
||||
x_axis.OrthoAxis->SetAspect(x_axis.GetAspect());
|
||||
changed = true;
|
||||
}
|
||||
float correction = (plot.Hovered && equal_zoom) ? 0.5f : 1.0f;
|
||||
const double plot_l = x_axis.PixelsToPlot(plot.PlotRect.Min.x - rect_size.x * tx * zoom_rate * correction);
|
||||
const double plot_r = x_axis.PixelsToPlot(plot.PlotRect.Max.x + rect_size.x * (1 - tx) * zoom_rate * correction);
|
||||
x_axis.SetMin(x_axis.IsInverted() ? plot_r : plot_l);
|
||||
x_axis.SetMax(x_axis.IsInverted() ? plot_l : plot_r);
|
||||
if (axis_equal && x_axis.OrthoAxis != nullptr)
|
||||
x_axis.OrthoAxis->SetAspect(x_axis.GetAspect());
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < IMPLOT_NUM_Y_AXES; i++) {
|
||||
@@ -2013,17 +1980,14 @@ bool UpdateInput(ImPlotPlot& plot) {
|
||||
const bool equal_zoom = axis_equal && y_axis.OrthoAxis != nullptr;
|
||||
const bool equal_locked = equal_zoom && y_axis.OrthoAxis->IsInputLocked();
|
||||
if (y_hov[i] && !y_axis.IsInputLocked() && !equal_locked) {
|
||||
ImGui::SetKeyOwner(ImGuiKey_MouseWheelY, plot.ID);
|
||||
if (zoom_rate != 0.0f) {
|
||||
float correction = (plot.Hovered && equal_zoom) ? 0.5f : 1.0f;
|
||||
const double plot_t = y_axis.PixelsToPlot(plot.PlotRect.Min.y - rect_size.y * ty * zoom_rate * correction);
|
||||
const double plot_b = y_axis.PixelsToPlot(plot.PlotRect.Max.y + rect_size.y * (1 - ty) * zoom_rate * correction);
|
||||
y_axis.SetMin(y_axis.IsInverted() ? plot_t : plot_b);
|
||||
y_axis.SetMax(y_axis.IsInverted() ? plot_b : plot_t);
|
||||
if (axis_equal && y_axis.OrthoAxis != nullptr)
|
||||
y_axis.OrthoAxis->SetAspect(y_axis.GetAspect());
|
||||
changed = true;
|
||||
}
|
||||
float correction = (plot.Hovered && equal_zoom) ? 0.5f : 1.0f;
|
||||
const double plot_t = y_axis.PixelsToPlot(plot.PlotRect.Min.y - rect_size.y * ty * zoom_rate * correction);
|
||||
const double plot_b = y_axis.PixelsToPlot(plot.PlotRect.Max.y + rect_size.y * (1 - ty) * zoom_rate * correction);
|
||||
y_axis.SetMin(y_axis.IsInverted() ? plot_t : plot_b);
|
||||
y_axis.SetMax(y_axis.IsInverted() ? plot_b : plot_t);
|
||||
if (axis_equal && y_axis.OrthoAxis != nullptr)
|
||||
y_axis.OrthoAxis->SetAspect(y_axis.GetAspect());
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2305,19 +2269,19 @@ void SetupAxesLimits(double x_min, double x_max, double y_min, double y_max, ImP
|
||||
|
||||
void SetupLegend(ImPlotLocation location, ImPlotLegendFlags flags) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
IM_ASSERT_USER_ERROR((gp.CurrentPlot != nullptr && !gp.CurrentPlot->SetupLocked) || (gp.CurrentSubplot != nullptr && gp.CurrentPlot == nullptr),
|
||||
"Setup needs to be called after BeginPlot or BeginSubplots and before any setup locking functions (e.g. PlotX)!");
|
||||
if (gp.CurrentItems) {
|
||||
ImPlotLegend& legend = gp.CurrentItems->Legend;
|
||||
// check and set location
|
||||
if (location != legend.PreviousLocation)
|
||||
legend.Location = location;
|
||||
legend.PreviousLocation = location;
|
||||
// check and set flags
|
||||
if (flags != legend.PreviousFlags)
|
||||
legend.Flags = flags;
|
||||
legend.PreviousFlags = flags;
|
||||
}
|
||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr && !gp.CurrentPlot->SetupLocked,
|
||||
"Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!");
|
||||
IM_ASSERT_USER_ERROR(gp.CurrentItems != nullptr,
|
||||
"SetupLegend() needs to be called within an itemized context!");
|
||||
ImPlotLegend& legend = gp.CurrentItems->Legend;
|
||||
// check and set location
|
||||
if (location != legend.PreviousLocation)
|
||||
legend.Location = location;
|
||||
legend.PreviousLocation = location;
|
||||
// check and set flags
|
||||
if (flags != legend.PreviousFlags)
|
||||
legend.Flags = flags;
|
||||
legend.PreviousFlags = flags;
|
||||
}
|
||||
|
||||
void SetupMouseText(ImPlotLocation location, ImPlotMouseTextFlags flags) {
|
||||
@@ -2429,6 +2393,22 @@ bool BeginPlot(const char* title_id, const ImVec2& size, ImPlotFlags flags) {
|
||||
for (int i = 0; i < ImAxis_COUNT; ++i)
|
||||
ApplyNextPlotData(i);
|
||||
|
||||
// capture scroll with a child region
|
||||
if (!ImHasFlag(plot.Flags, ImPlotFlags_NoChild)) {
|
||||
ImVec2 child_size;
|
||||
if (gp.CurrentSubplot != nullptr)
|
||||
child_size = gp.CurrentSubplot->CellSize;
|
||||
else
|
||||
child_size = ImVec2(size.x == 0 ? gp.Style.PlotDefaultSize.x : size.x, size.y == 0 ? gp.Style.PlotDefaultSize.y : size.y);
|
||||
ImGui::BeginChild(title_id, child_size, false, ImGuiWindowFlags_NoScrollbar);
|
||||
Window = ImGui::GetCurrentWindow();
|
||||
Window->ScrollMax.y = 1.0f;
|
||||
gp.ChildWindowMade = true;
|
||||
}
|
||||
else {
|
||||
gp.ChildWindowMade = false;
|
||||
}
|
||||
|
||||
// clear text buffers
|
||||
plot.ClearTextBuffer();
|
||||
plot.SetTitle(title_id);
|
||||
@@ -2451,7 +2431,7 @@ bool BeginPlot(const char* title_id, const ImVec2& size, ImPlotFlags flags) {
|
||||
ResetCtxForNextPlot(GImPlot);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// setup items (or dont)
|
||||
if (gp.CurrentItems == nullptr)
|
||||
gp.CurrentItems = &plot.Items;
|
||||
@@ -2570,7 +2550,7 @@ void SetupFinish() {
|
||||
// (2) get y tick labels (needed for left/right pad)
|
||||
for (int i = 0; i < IMPLOT_NUM_Y_AXES; i++) {
|
||||
ImPlotAxis& axis = plot.YAxis(i);
|
||||
if (axis.WillRender() && axis.ShowDefaultTicks && plot_height > 0) {
|
||||
if (axis.WillRender() && axis.ShowDefaultTicks) {
|
||||
axis.Locator(axis.Ticker, axis.Range, plot_height, true, axis.Formatter, axis.FormatterData);
|
||||
}
|
||||
}
|
||||
@@ -2583,7 +2563,7 @@ void SetupFinish() {
|
||||
// (4) get x ticks
|
||||
for (int i = 0; i < IMPLOT_NUM_X_AXES; i++) {
|
||||
ImPlotAxis& axis = plot.XAxis(i);
|
||||
if (axis.WillRender() && axis.ShowDefaultTicks && plot_width > 0) {
|
||||
if (axis.WillRender() && axis.ShowDefaultTicks) {
|
||||
axis.Locator(axis.Ticker, axis.Range, plot_width, false, axis.Formatter, axis.FormatterData);
|
||||
}
|
||||
}
|
||||
@@ -2778,7 +2758,7 @@ void EndPlot() {
|
||||
|
||||
// FINAL RENDER -----------------------------------------------------------
|
||||
|
||||
const bool render_border = gp.Style.PlotBorderSize > 0 && GetStyleColorVec4(ImPlotCol_PlotBorder).w > 0;
|
||||
const bool render_border = gp.Style.PlotBorderSize > 0 && gp.Style.Colors[ImPlotCol_PlotBorder].w > 0;
|
||||
const bool any_x_held = plot.Held || AnyAxesHeld(&plot.Axes[ImAxis_X1], IMPLOT_NUM_X_AXES);
|
||||
const bool any_y_held = plot.Held || AnyAxesHeld(&plot.Axes[ImAxis_Y1], IMPLOT_NUM_Y_AXES);
|
||||
|
||||
@@ -3043,57 +3023,24 @@ void EndPlot() {
|
||||
legend.Location,
|
||||
legend_out ? gp.Style.PlotPadding : gp.Style.LegendPadding);
|
||||
legend.Rect = ImRect(legend_pos, legend_pos + legend_size);
|
||||
legend.RectClamped = legend.Rect;
|
||||
const bool legend_scrollable = ClampLegendRect(legend.RectClamped,
|
||||
legend_out ? plot.FrameRect : plot.PlotRect,
|
||||
legend_out ? gp.Style.PlotPadding : gp.Style.LegendPadding
|
||||
);
|
||||
const ImGuiButtonFlags legend_button_flags = ImGuiButtonFlags_AllowOverlap
|
||||
| ImGuiButtonFlags_PressedOnClick
|
||||
| ImGuiButtonFlags_PressedOnDoubleClick
|
||||
| ImGuiButtonFlags_MouseButtonLeft
|
||||
| ImGuiButtonFlags_MouseButtonRight
|
||||
| ImGuiButtonFlags_MouseButtonMiddle
|
||||
| ImGuiButtonFlags_FlattenChildren;
|
||||
ImGui::KeepAliveID(plot.Items.ID);
|
||||
ImGui::ButtonBehavior(legend.RectClamped, plot.Items.ID, &legend.Hovered, &legend.Held, legend_button_flags);
|
||||
legend.Hovered = legend.Hovered || (ImGui::IsWindowHovered() && legend.RectClamped.Contains(IO.MousePos));
|
||||
|
||||
if (legend_scrollable) {
|
||||
if (legend.Hovered) {
|
||||
ImGui::SetKeyOwner(ImGuiKey_MouseWheelY, plot.Items.ID);
|
||||
if (IO.MouseWheel != 0.0f) {
|
||||
ImVec2 max_step = legend.Rect.GetSize() * 0.67f;
|
||||
float font_size = ImGui::GetCurrentWindow()->CalcFontSize();
|
||||
float scroll_step = ImFloor(ImMin(2 * font_size, max_step.x));
|
||||
legend.Scroll.x += scroll_step * IO.MouseWheel;
|
||||
legend.Scroll.y += scroll_step * IO.MouseWheel;
|
||||
}
|
||||
}
|
||||
const ImVec2 min_scroll_offset = legend.RectClamped.GetSize() - legend.Rect.GetSize();
|
||||
legend.Scroll.x = ImClamp(legend.Scroll.x, min_scroll_offset.x, 0.0f);
|
||||
legend.Scroll.y = ImClamp(legend.Scroll.y, min_scroll_offset.y, 0.0f);
|
||||
const ImVec2 scroll_offset = legend_horz ? ImVec2(legend.Scroll.x, 0) : ImVec2(0, legend.Scroll.y);
|
||||
ImVec2 legend_offset = legend.RectClamped.Min - legend.Rect.Min + scroll_offset;
|
||||
legend.Rect.Min += legend_offset;
|
||||
legend.Rect.Max += legend_offset;
|
||||
} else {
|
||||
legend.Scroll = ImVec2(0,0);
|
||||
}
|
||||
// test hover
|
||||
legend.Hovered = ImGui::IsWindowHovered() && legend.Rect.Contains(IO.MousePos);
|
||||
|
||||
const ImU32 col_bg = GetStyleColorU32(ImPlotCol_LegendBg);
|
||||
const ImU32 col_bd = GetStyleColorU32(ImPlotCol_LegendBorder);
|
||||
ImGui::PushClipRect(legend.RectClamped.Min, legend.RectClamped.Max, true);
|
||||
DrawList.AddRectFilled(legend.RectClamped.Min, legend.RectClamped.Max, col_bg);
|
||||
if (legend_out)
|
||||
ImGui::PushClipRect(plot.FrameRect.Min, plot.FrameRect.Max, true);
|
||||
else
|
||||
PushPlotClipRect();
|
||||
ImU32 col_bg = GetStyleColorU32(ImPlotCol_LegendBg);
|
||||
ImU32 col_bd = GetStyleColorU32(ImPlotCol_LegendBorder);
|
||||
DrawList.AddRectFilled(legend.Rect.Min, legend.Rect.Max, col_bg);
|
||||
DrawList.AddRect(legend.Rect.Min, legend.Rect.Max, col_bd);
|
||||
bool legend_contextable = ShowLegendEntries(plot.Items, legend.Rect, legend.Hovered, gp.Style.LegendInnerPadding, gp.Style.LegendSpacing, !legend_horz, DrawList)
|
||||
&& !ImHasFlag(legend.Flags, ImPlotLegendFlags_NoMenus);
|
||||
DrawList.AddRect(legend.RectClamped.Min, legend.RectClamped.Max, col_bd);
|
||||
ImGui::PopClipRect();
|
||||
&& !ImHasFlag(legend.Flags, ImPlotLegendFlags_NoMenus);
|
||||
|
||||
// main ctx menu
|
||||
if (gp.OpenContextThisFrame && legend_contextable && !ImHasFlag(plot.Flags, ImPlotFlags_NoMenus))
|
||||
ImGui::OpenPopup("##LegendContext");
|
||||
|
||||
ImGui::OpenPopup("##LegendContext");
|
||||
ImGui::PopClipRect();
|
||||
if (ImGui::BeginPopup("##LegendContext")) {
|
||||
ImGui::Text("Legend"); ImGui::Separator();
|
||||
if (ShowLegendContextMenu(legend, !ImHasFlag(plot.Flags, ImPlotFlags_NoLegend)))
|
||||
@@ -3403,7 +3350,7 @@ bool BeginSubplots(const char* title, int rows, int cols, const ImVec2& size, Im
|
||||
subplot.FrameRect = ImRect(Window->DC.CursorPos, Window->DC.CursorPos + frame_size);
|
||||
subplot.GridRect.Min = subplot.FrameRect.Min + half_pad + ImVec2(0,pad_top);
|
||||
subplot.GridRect.Max = subplot.FrameRect.Max - half_pad;
|
||||
subplot.FrameHovered = subplot.FrameRect.Contains(ImGui::GetMousePos()) && ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows|ImGuiHoveredFlags_AllowWhenBlockedByActiveItem);
|
||||
subplot.FrameHovered = subplot.FrameRect.Contains(ImGui::GetMousePos()) && ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows);
|
||||
|
||||
// outside legend adjustments (TODO: make function)
|
||||
const bool share_items = ImHasFlag(subplot.Flags, ImPlotSubplotFlags_ShareItems);
|
||||
@@ -3450,7 +3397,7 @@ bool BeginSubplots(const char* title, int rows, int cols, const ImVec2& size, Im
|
||||
ImGui::KeepAliveID(sep_id);
|
||||
const ImRect sep_bb = ImRect(subplot.GridRect.Min.x, ypos-SUBPLOT_SPLITTER_HALF_THICKNESS, subplot.GridRect.Max.x, ypos+SUBPLOT_SPLITTER_HALF_THICKNESS);
|
||||
bool sep_hov = false, sep_hld = false;
|
||||
const bool sep_clk = ImGui::ButtonBehavior(sep_bb, sep_id, &sep_hov, &sep_hld, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnDoubleClick);
|
||||
const bool sep_clk = ImGui::ButtonBehavior(sep_bb, sep_id, &sep_hov, &sep_hld, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnDoubleClick);
|
||||
if ((sep_hov && G.HoveredIdTimer > SUBPLOT_SPLITTER_FEEDBACK_TIMER) || sep_hld) {
|
||||
if (sep_clk && ImGui::IsMouseDoubleClicked(0)) {
|
||||
float p = (subplot.RowRatios[r] + subplot.RowRatios[r+1])/2;
|
||||
@@ -3480,7 +3427,7 @@ bool BeginSubplots(const char* title, int rows, int cols, const ImVec2& size, Im
|
||||
ImGui::KeepAliveID(sep_id);
|
||||
const ImRect sep_bb = ImRect(xpos-SUBPLOT_SPLITTER_HALF_THICKNESS, subplot.GridRect.Min.y, xpos+SUBPLOT_SPLITTER_HALF_THICKNESS, subplot.GridRect.Max.y);
|
||||
bool sep_hov = false, sep_hld = false;
|
||||
const bool sep_clk = ImGui::ButtonBehavior(sep_bb, sep_id, &sep_hov, &sep_hld, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnDoubleClick);
|
||||
const bool sep_clk = ImGui::ButtonBehavior(sep_bb, sep_id, &sep_hov, &sep_hld, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnDoubleClick);
|
||||
if ((sep_hov && G.HoveredIdTimer > SUBPLOT_SPLITTER_FEEDBACK_TIMER) || sep_hld) {
|
||||
if (sep_clk && ImGui::IsMouseDoubleClicked(0)) {
|
||||
float p = (subplot.ColRatios[c] + subplot.ColRatios[c+1])/2;
|
||||
@@ -3541,7 +3488,6 @@ void EndSubplots() {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
IM_ASSERT_USER_ERROR(gp.CurrentSubplot != nullptr, "Mismatched BeginSubplots()/EndSubplots()!");
|
||||
ImPlotSubplot& subplot = *gp.CurrentSubplot;
|
||||
const ImGuiIO& IO = ImGui::GetIO();
|
||||
// set alignments
|
||||
for (int r = 0; r < subplot.Rows; ++r)
|
||||
subplot.RowAlignmentData[r].End();
|
||||
@@ -3560,60 +3506,24 @@ void EndSubplots() {
|
||||
const bool share_items = ImHasFlag(subplot.Flags, ImPlotSubplotFlags_ShareItems);
|
||||
ImDrawList& DrawList = *ImGui::GetWindowDrawList();
|
||||
if (share_items && !ImHasFlag(subplot.Flags, ImPlotSubplotFlags_NoLegend) && subplot.Items.GetLegendCount() > 0) {
|
||||
ImPlotLegend& legend = subplot.Items.Legend;
|
||||
const bool legend_horz = ImHasFlag(legend.Flags, ImPlotLegendFlags_Horizontal);
|
||||
const bool legend_horz = ImHasFlag(subplot.Items.Legend.Flags, ImPlotLegendFlags_Horizontal);
|
||||
const ImVec2 legend_size = CalcLegendSize(subplot.Items, gp.Style.LegendInnerPadding, gp.Style.LegendSpacing, !legend_horz);
|
||||
const ImVec2 legend_pos = GetLocationPos(subplot.FrameRect, legend_size, legend.Location, gp.Style.PlotPadding);
|
||||
legend.Rect = ImRect(legend_pos, legend_pos + legend_size);
|
||||
legend.RectClamped = legend.Rect;
|
||||
const bool legend_scrollable = ClampLegendRect(legend.RectClamped,subplot.FrameRect, gp.Style.PlotPadding);
|
||||
const ImGuiButtonFlags legend_button_flags = ImGuiButtonFlags_AllowOverlap
|
||||
| ImGuiButtonFlags_PressedOnClick
|
||||
| ImGuiButtonFlags_PressedOnDoubleClick
|
||||
| ImGuiButtonFlags_MouseButtonLeft
|
||||
| ImGuiButtonFlags_MouseButtonRight
|
||||
| ImGuiButtonFlags_MouseButtonMiddle
|
||||
| ImGuiButtonFlags_FlattenChildren;
|
||||
ImGui::KeepAliveID(subplot.Items.ID);
|
||||
ImGui::ButtonBehavior(legend.RectClamped, subplot.Items.ID, &legend.Hovered, &legend.Held, legend_button_flags);
|
||||
legend.Hovered = legend.Hovered || (subplot.FrameHovered && legend.RectClamped.Contains(ImGui::GetIO().MousePos));
|
||||
|
||||
if (legend_scrollable) {
|
||||
if (legend.Hovered) {
|
||||
ImGui::SetKeyOwner(ImGuiKey_MouseWheelY, subplot.Items.ID);
|
||||
if (IO.MouseWheel != 0.0f) {
|
||||
ImVec2 max_step = legend.Rect.GetSize() * 0.67f;
|
||||
float font_size = ImGui::GetCurrentWindow()->CalcFontSize();
|
||||
float scroll_step = ImFloor(ImMin(2 * font_size, max_step.x));
|
||||
legend.Scroll.x += scroll_step * IO.MouseWheel;
|
||||
legend.Scroll.y += scroll_step * IO.MouseWheel;
|
||||
}
|
||||
}
|
||||
const ImVec2 min_scroll_offset = legend.RectClamped.GetSize() - legend.Rect.GetSize();
|
||||
legend.Scroll.x = ImClamp(legend.Scroll.x, min_scroll_offset.x, 0.0f);
|
||||
legend.Scroll.y = ImClamp(legend.Scroll.y, min_scroll_offset.y, 0.0f);
|
||||
const ImVec2 scroll_offset = legend_horz ? ImVec2(legend.Scroll.x, 0) : ImVec2(0, legend.Scroll.y);
|
||||
ImVec2 legend_offset = legend.RectClamped.Min - legend.Rect.Min + scroll_offset;
|
||||
legend.Rect.Min += legend_offset;
|
||||
legend.Rect.Max += legend_offset;
|
||||
} else {
|
||||
legend.Scroll = ImVec2(0,0);
|
||||
}
|
||||
|
||||
const ImU32 col_bg = GetStyleColorU32(ImPlotCol_LegendBg);
|
||||
const ImU32 col_bd = GetStyleColorU32(ImPlotCol_LegendBorder);
|
||||
ImGui::PushClipRect(legend.RectClamped.Min, legend.RectClamped.Max, true);
|
||||
DrawList.AddRectFilled(legend.RectClamped.Min, legend.RectClamped.Max, col_bg);
|
||||
bool legend_contextable = ShowLegendEntries(subplot.Items, legend.Rect, legend.Hovered, gp.Style.LegendInnerPadding, gp.Style.LegendSpacing, !legend_horz, DrawList)
|
||||
&& !ImHasFlag(legend.Flags, ImPlotLegendFlags_NoMenus);
|
||||
DrawList.AddRect(legend.RectClamped.Min, legend.RectClamped.Max, col_bd);
|
||||
ImGui::PopClipRect();
|
||||
|
||||
const ImVec2 legend_pos = GetLocationPos(subplot.FrameRect, legend_size, subplot.Items.Legend.Location, gp.Style.PlotPadding);
|
||||
subplot.Items.Legend.Rect = ImRect(legend_pos, legend_pos + legend_size);
|
||||
subplot.Items.Legend.Hovered = subplot.FrameHovered && subplot.Items.Legend.Rect.Contains(ImGui::GetIO().MousePos);
|
||||
ImGui::PushClipRect(subplot.FrameRect.Min, subplot.FrameRect.Max, true);
|
||||
ImU32 col_bg = GetStyleColorU32(ImPlotCol_LegendBg);
|
||||
ImU32 col_bd = GetStyleColorU32(ImPlotCol_LegendBorder);
|
||||
DrawList.AddRectFilled(subplot.Items.Legend.Rect.Min, subplot.Items.Legend.Rect.Max, col_bg);
|
||||
DrawList.AddRect(subplot.Items.Legend.Rect.Min, subplot.Items.Legend.Rect.Max, col_bd);
|
||||
bool legend_contextable = ShowLegendEntries(subplot.Items, subplot.Items.Legend.Rect, subplot.Items.Legend.Hovered, gp.Style.LegendInnerPadding, gp.Style.LegendSpacing, !legend_horz, DrawList)
|
||||
&& !ImHasFlag(subplot.Items.Legend.Flags, ImPlotLegendFlags_NoMenus);
|
||||
if (legend_contextable && !ImHasFlag(subplot.Flags, ImPlotSubplotFlags_NoMenus) && ImGui::GetIO().MouseReleased[gp.InputMap.Menu])
|
||||
ImGui::OpenPopup("##LegendContext");
|
||||
ImGui::PopClipRect();
|
||||
if (ImGui::BeginPopup("##LegendContext")) {
|
||||
ImGui::Text("Legend"); ImGui::Separator();
|
||||
if (ShowLegendContextMenu(legend, !ImHasFlag(subplot.Flags, ImPlotFlags_NoLegend)))
|
||||
if (ShowLegendContextMenu(subplot.Items.Legend, !ImHasFlag(subplot.Flags, ImPlotFlags_NoLegend)))
|
||||
ImFlipFlag(subplot.Flags, ImPlotFlags_NoLegend);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
@@ -3894,7 +3804,7 @@ IMPLOT_API void TagYV(double y, const ImVec4& color, const char* fmt, va_list ar
|
||||
|
||||
static const float DRAG_GRAB_HALF_SIZE = 4.0f;
|
||||
|
||||
bool DragPoint(int n_id, double* x, double* y, const ImVec4& col, float radius, ImPlotDragToolFlags flags, bool* out_clicked, bool* out_hovered, bool* out_held) {
|
||||
bool DragPoint(int n_id, double* x, double* y, const ImVec4& col, float radius, ImPlotDragToolFlags flags) {
|
||||
ImGui::PushID("#IMPLOT_DRAG_POINT");
|
||||
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr, "DragPoint() needs to be called between BeginPlot() and EndPlot()!");
|
||||
SetupLock();
|
||||
@@ -3916,34 +3826,30 @@ bool DragPoint(int n_id, double* x, double* y, const ImVec4& col, float radius,
|
||||
bool hovered = false, held = false;
|
||||
|
||||
ImGui::KeepAliveID(id);
|
||||
if (input) {
|
||||
bool clicked = ImGui::ButtonBehavior(rect,id,&hovered,&held);
|
||||
if (out_clicked) *out_clicked = clicked;
|
||||
if (out_hovered) *out_hovered = hovered;
|
||||
if (out_held) *out_held = held;
|
||||
}
|
||||
if (input)
|
||||
ImGui::ButtonBehavior(rect,id,&hovered,&held);
|
||||
|
||||
bool modified = false;
|
||||
bool dragging = false;
|
||||
if (held && ImGui::IsMouseDragging(0)) {
|
||||
*x = ImPlot::GetPlotMousePos(IMPLOT_AUTO,IMPLOT_AUTO).x;
|
||||
*y = ImPlot::GetPlotMousePos(IMPLOT_AUTO,IMPLOT_AUTO).y;
|
||||
modified = true;
|
||||
dragging = true;
|
||||
}
|
||||
|
||||
PushPlotClipRect();
|
||||
ImDrawList& DrawList = *GetPlotDrawList();
|
||||
if ((hovered || held) && show_curs)
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
|
||||
if (modified && no_delay)
|
||||
if (dragging && no_delay)
|
||||
pos = PlotToPixels(*x,*y,IMPLOT_AUTO,IMPLOT_AUTO);
|
||||
DrawList.AddCircleFilled(pos, radius, col32);
|
||||
PopPlotClipRect();
|
||||
|
||||
ImGui::PopID();
|
||||
return modified;
|
||||
return dragging;
|
||||
}
|
||||
|
||||
bool DragLineX(int n_id, double* value, const ImVec4& col, float thickness, ImPlotDragToolFlags flags, bool* out_clicked, bool* out_hovered, bool* out_held) {
|
||||
bool DragLineX(int n_id, double* value, const ImVec4& col, float thickness, ImPlotDragToolFlags flags) {
|
||||
// ImGui::PushID("#IMPLOT_DRAG_LINE_X");
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr, "DragLineX() needs to be called between BeginPlot() and EndPlot()!");
|
||||
@@ -3965,12 +3871,8 @@ bool DragLineX(int n_id, double* value, const ImVec4& col, float thickness, ImPl
|
||||
bool hovered = false, held = false;
|
||||
|
||||
ImGui::KeepAliveID(id);
|
||||
if (input) {
|
||||
bool clicked = ImGui::ButtonBehavior(rect,id,&hovered,&held);
|
||||
if (out_clicked) *out_clicked = clicked;
|
||||
if (out_hovered) *out_hovered = hovered;
|
||||
if (out_held) *out_held = held;
|
||||
}
|
||||
if (input)
|
||||
ImGui::ButtonBehavior(rect,id,&hovered,&held);
|
||||
|
||||
if ((hovered || held) && show_curs)
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);
|
||||
@@ -3979,15 +3881,15 @@ bool DragLineX(int n_id, double* value, const ImVec4& col, float thickness, ImPl
|
||||
ImVec4 color = IsColorAuto(col) ? ImGui::GetStyleColorVec4(ImGuiCol_Text) : col;
|
||||
ImU32 col32 = ImGui::ColorConvertFloat4ToU32(color);
|
||||
|
||||
bool modified = false;
|
||||
bool dragging = false;
|
||||
if (held && ImGui::IsMouseDragging(0)) {
|
||||
*value = ImPlot::GetPlotMousePos(IMPLOT_AUTO,IMPLOT_AUTO).x;
|
||||
modified = true;
|
||||
dragging = true;
|
||||
}
|
||||
|
||||
PushPlotClipRect();
|
||||
ImDrawList& DrawList = *GetPlotDrawList();
|
||||
if (modified && no_delay)
|
||||
if (dragging && no_delay)
|
||||
x = IM_ROUND(PlotToPixels(*value,0,IMPLOT_AUTO,IMPLOT_AUTO).x);
|
||||
DrawList.AddLine(ImVec2(x,yt), ImVec2(x,yb), col32, thickness);
|
||||
DrawList.AddLine(ImVec2(x,yt), ImVec2(x,yt+len), col32, 3*thickness);
|
||||
@@ -3995,10 +3897,10 @@ bool DragLineX(int n_id, double* value, const ImVec4& col, float thickness, ImPl
|
||||
PopPlotClipRect();
|
||||
|
||||
// ImGui::PopID();
|
||||
return modified;
|
||||
return dragging;
|
||||
}
|
||||
|
||||
bool DragLineY(int n_id, double* value, const ImVec4& col, float thickness, ImPlotDragToolFlags flags, bool* out_clicked, bool* out_hovered, bool* out_held) {
|
||||
bool DragLineY(int n_id, double* value, const ImVec4& col, float thickness, ImPlotDragToolFlags flags) {
|
||||
ImGui::PushID("#IMPLOT_DRAG_LINE_Y");
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr, "DragLineY() needs to be called between BeginPlot() and EndPlot()!");
|
||||
@@ -4021,12 +3923,8 @@ bool DragLineY(int n_id, double* value, const ImVec4& col, float thickness, ImPl
|
||||
bool hovered = false, held = false;
|
||||
|
||||
ImGui::KeepAliveID(id);
|
||||
if (input) {
|
||||
bool clicked = ImGui::ButtonBehavior(rect,id,&hovered,&held);
|
||||
if (out_clicked) *out_clicked = clicked;
|
||||
if (out_hovered) *out_hovered = hovered;
|
||||
if (out_held) *out_held = held;
|
||||
}
|
||||
if (input)
|
||||
ImGui::ButtonBehavior(rect,id,&hovered,&held);
|
||||
|
||||
if ((hovered || held) && show_curs)
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeNS);
|
||||
@@ -4035,15 +3933,15 @@ bool DragLineY(int n_id, double* value, const ImVec4& col, float thickness, ImPl
|
||||
ImVec4 color = IsColorAuto(col) ? ImGui::GetStyleColorVec4(ImGuiCol_Text) : col;
|
||||
ImU32 col32 = ImGui::ColorConvertFloat4ToU32(color);
|
||||
|
||||
bool modified = false;
|
||||
bool dragging = false;
|
||||
if (held && ImGui::IsMouseDragging(0)) {
|
||||
*value = ImPlot::GetPlotMousePos(IMPLOT_AUTO,IMPLOT_AUTO).y;
|
||||
modified = true;
|
||||
dragging = true;
|
||||
}
|
||||
|
||||
PushPlotClipRect();
|
||||
ImDrawList& DrawList = *GetPlotDrawList();
|
||||
if (modified && no_delay)
|
||||
if (dragging && no_delay)
|
||||
y = IM_ROUND(PlotToPixels(0, *value,IMPLOT_AUTO,IMPLOT_AUTO).y);
|
||||
DrawList.AddLine(ImVec2(xl,y), ImVec2(xr,y), col32, thickness);
|
||||
DrawList.AddLine(ImVec2(xl,y), ImVec2(xl+len,y), col32, 3*thickness);
|
||||
@@ -4051,10 +3949,10 @@ bool DragLineY(int n_id, double* value, const ImVec4& col, float thickness, ImPl
|
||||
PopPlotClipRect();
|
||||
|
||||
ImGui::PopID();
|
||||
return modified;
|
||||
return dragging;
|
||||
}
|
||||
|
||||
bool DragRect(int n_id, double* x_min, double* y_min, double* x_max, double* y_max, const ImVec4& col, ImPlotDragToolFlags flags, bool* out_clicked, bool* out_hovered, bool* out_held) {
|
||||
bool DragRect(int n_id, double* x_min, double* y_min, double* x_max, double* y_max, const ImVec4& col, ImPlotDragToolFlags flags) {
|
||||
ImGui::PushID("#IMPLOT_DRAG_RECT");
|
||||
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr, "DragRect() needs to be called between BeginPlot() and EndPlot()!");
|
||||
SetupLock();
|
||||
@@ -4091,18 +3989,13 @@ bool DragRect(int n_id, double* x_min, double* y_min, double* x_max, double* y_m
|
||||
ImU32 col32_a = ImGui::ColorConvertFloat4ToU32(color);
|
||||
const ImGuiID id = ImGui::GetCurrentWindow()->GetID(n_id);
|
||||
|
||||
bool modified = false;
|
||||
bool clicked = false, hovered = false, held = false;
|
||||
bool dragging = false;
|
||||
bool hovered = false, held = false;
|
||||
ImRect b_rect(pc.x-DRAG_GRAB_HALF_SIZE,pc.y-DRAG_GRAB_HALF_SIZE,pc.x+DRAG_GRAB_HALF_SIZE,pc.y+DRAG_GRAB_HALF_SIZE);
|
||||
|
||||
ImGui::KeepAliveID(id);
|
||||
if (input) {
|
||||
// middle point
|
||||
clicked = ImGui::ButtonBehavior(b_rect,id,&hovered,&held);
|
||||
if (out_clicked) *out_clicked = clicked;
|
||||
if (out_hovered) *out_hovered = hovered;
|
||||
if (out_held) *out_held = held;
|
||||
}
|
||||
if (input)
|
||||
ImGui::ButtonBehavior(b_rect,id,&hovered,&held);
|
||||
|
||||
if ((hovered || held) && show_curs)
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeAll);
|
||||
@@ -4112,7 +4005,7 @@ bool DragRect(int n_id, double* x_min, double* y_min, double* x_max, double* y_m
|
||||
*y[i] = pp.y;
|
||||
*x[i] = pp.x;
|
||||
}
|
||||
modified = true;
|
||||
dragging = true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
@@ -4120,19 +4013,15 @@ bool DragRect(int n_id, double* x_min, double* y_min, double* x_max, double* y_m
|
||||
b_rect = ImRect(p[i].x-DRAG_GRAB_HALF_SIZE,p[i].y-DRAG_GRAB_HALF_SIZE,p[i].x+DRAG_GRAB_HALF_SIZE,p[i].y+DRAG_GRAB_HALF_SIZE);
|
||||
ImGuiID p_id = id + i + 1;
|
||||
ImGui::KeepAliveID(p_id);
|
||||
if (input) {
|
||||
clicked = ImGui::ButtonBehavior(b_rect,p_id,&hovered,&held);
|
||||
if (out_clicked) *out_clicked = *out_clicked || clicked;
|
||||
if (out_hovered) *out_hovered = *out_hovered || hovered;
|
||||
if (out_held) *out_held = *out_held || held;
|
||||
}
|
||||
if (input)
|
||||
ImGui::ButtonBehavior(b_rect,p_id,&hovered,&held);
|
||||
if ((hovered || held) && show_curs)
|
||||
ImGui::SetMouseCursor(cur[i]);
|
||||
|
||||
if (held && ImGui::IsMouseDragging(0)) {
|
||||
*x[i] = ImPlot::GetPlotMousePos(IMPLOT_AUTO,IMPLOT_AUTO).x;
|
||||
*y[i] = ImPlot::GetPlotMousePos(IMPLOT_AUTO,IMPLOT_AUTO).y;
|
||||
modified = true;
|
||||
dragging = true;
|
||||
}
|
||||
|
||||
// edges
|
||||
@@ -4142,12 +4031,8 @@ bool DragRect(int n_id, double* x_min, double* y_min, double* x_max, double* y_m
|
||||
: ImRect(e_min.x - DRAG_GRAB_HALF_SIZE, e_min.y + DRAG_GRAB_HALF_SIZE, e_max.x + DRAG_GRAB_HALF_SIZE, e_max.y - DRAG_GRAB_HALF_SIZE);
|
||||
ImGuiID e_id = id + i + 5;
|
||||
ImGui::KeepAliveID(e_id);
|
||||
if (input) {
|
||||
clicked = ImGui::ButtonBehavior(b_rect,e_id,&hovered,&held);
|
||||
if (out_clicked) *out_clicked = *out_clicked || clicked;
|
||||
if (out_hovered) *out_hovered = *out_hovered || hovered;
|
||||
if (out_held) *out_held = *out_held || held;
|
||||
}
|
||||
if (input)
|
||||
ImGui::ButtonBehavior(b_rect,e_id,&hovered,&held);
|
||||
if ((hovered || held) && show_curs)
|
||||
h[i] ? ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeNS) : ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);
|
||||
if (held && ImGui::IsMouseDragging(0)) {
|
||||
@@ -4155,7 +4040,7 @@ bool DragRect(int n_id, double* x_min, double* y_min, double* x_max, double* y_m
|
||||
*y[i] = ImPlot::GetPlotMousePos(IMPLOT_AUTO,IMPLOT_AUTO).y;
|
||||
else
|
||||
*x[i] = ImPlot::GetPlotMousePos(IMPLOT_AUTO,IMPLOT_AUTO).x;
|
||||
modified = true;
|
||||
dragging = true;
|
||||
}
|
||||
if (hovered && ImGui::IsMouseDoubleClicked(0))
|
||||
{
|
||||
@@ -4164,22 +4049,14 @@ bool DragRect(int n_id, double* x_min, double* y_min, double* x_max, double* y_m
|
||||
*y[i] = ((y[i] == y_min && *y_min < *y_max) || (y[i] == y_max && *y_max < *y_min)) ? b.Y.Min : b.Y.Max;
|
||||
else
|
||||
*x[i] = ((x[i] == x_min && *x_min < *x_max) || (x[i] == x_max && *x_max < *x_min)) ? b.X.Min : b.X.Max;
|
||||
modified = true;
|
||||
dragging = true;
|
||||
}
|
||||
}
|
||||
|
||||
const bool mouse_inside = rect_grab.Contains(ImGui::GetMousePos());
|
||||
const bool mouse_clicked = ImGui::IsMouseClicked(0);
|
||||
const bool mouse_down = ImGui::IsMouseDown(0);
|
||||
if (input && mouse_inside) {
|
||||
if (out_clicked) *out_clicked = *out_clicked || mouse_clicked;
|
||||
if (out_hovered) *out_hovered = true;
|
||||
if (out_held) *out_held = *out_held || mouse_down;
|
||||
}
|
||||
|
||||
PushPlotClipRect();
|
||||
ImDrawList& DrawList = *GetPlotDrawList();
|
||||
if (modified && no_delay) {
|
||||
if (dragging && no_delay) {
|
||||
for (int i = 0; i < 4; ++i)
|
||||
p[i] = PlotToPixels(*x[i],*y[i],IMPLOT_AUTO,IMPLOT_AUTO);
|
||||
pc = PlotToPixels((*x_min+*x_max)/2,(*y_min+*y_max)/2,IMPLOT_AUTO,IMPLOT_AUTO);
|
||||
@@ -4187,18 +4064,18 @@ bool DragRect(int n_id, double* x_min, double* y_min, double* x_max, double* y_m
|
||||
}
|
||||
DrawList.AddRectFilled(rect.Min, rect.Max, col32_a);
|
||||
DrawList.AddRect(rect.Min, rect.Max, col32);
|
||||
if (input && (modified || mouse_inside)) {
|
||||
if (input && (dragging || rect_grab.Contains(ImGui::GetMousePos()))) {
|
||||
DrawList.AddCircleFilled(pc,DRAG_GRAB_HALF_SIZE,col32);
|
||||
for (int i = 0; i < 4; ++i)
|
||||
DrawList.AddCircleFilled(p[i],DRAG_GRAB_HALF_SIZE,col32);
|
||||
}
|
||||
PopPlotClipRect();
|
||||
ImGui::PopID();
|
||||
return modified;
|
||||
return dragging;
|
||||
}
|
||||
|
||||
bool DragRect(int id, ImPlotRect* bounds, const ImVec4& col, ImPlotDragToolFlags flags, bool* out_clicked, bool* out_hovered, bool* out_held) {
|
||||
return DragRect(id, &bounds->X.Min, &bounds->Y.Min,&bounds->X.Max, &bounds->Y.Max, col, flags, out_clicked, out_hovered, out_held);
|
||||
bool DragRect(int id, ImPlotRect* bounds, const ImVec4& col, ImPlotDragToolFlags flags) {
|
||||
return DragRect(id, &bounds->X.Min, &bounds->Y.Min,&bounds->X.Max, &bounds->Y.Max, col, flags);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -4294,7 +4171,7 @@ bool BeginDragDropTargetAxis(ImAxis axis) {
|
||||
bool BeginDragDropTargetLegend() {
|
||||
SetupLock();
|
||||
ImPlotItemGroup& items = *GImPlot->CurrentItems;
|
||||
ImRect rect = items.Legend.RectClamped;
|
||||
ImRect rect = items.Legend.Rect;
|
||||
return ImGui::BeginDragDropTargetCustom(rect, items.ID);
|
||||
}
|
||||
|
||||
@@ -5233,7 +5110,6 @@ void ShowMetricsWindow(bool* p_popen) {
|
||||
static bool show_frame_rects = false;
|
||||
static bool show_subplot_frame_rects = false;
|
||||
static bool show_subplot_grid_rects = false;
|
||||
static bool show_legend_rects = false;
|
||||
|
||||
ImDrawList& fg = *ImGui::GetForegroundDrawList();
|
||||
|
||||
@@ -5258,7 +5134,6 @@ void ShowMetricsWindow(bool* p_popen) {
|
||||
ImGui::Checkbox("Show Axis Rects", &show_axis_rects);
|
||||
ImGui::Checkbox("Show Subplot Frame Rects", &show_subplot_frame_rects);
|
||||
ImGui::Checkbox("Show Subplot Grid Rects", &show_subplot_grid_rects);
|
||||
ImGui::Checkbox("Show Legend Rects", &show_legend_rects);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
const int n_plots = gp.Plots.GetBufSize();
|
||||
@@ -5280,10 +5155,6 @@ void ShowMetricsWindow(bool* p_popen) {
|
||||
fg.AddRect(plot->Axes[i].HoverRect.Min, plot->Axes[i].HoverRect.Max, IM_COL32(0,255,0,255));
|
||||
}
|
||||
}
|
||||
if (show_legend_rects && plot->Items.GetLegendCount() > 0) {
|
||||
fg.AddRect(plot->Items.Legend.Rect.Min, plot->Items.Legend.Rect.Max, IM_COL32(255,192,0,255));
|
||||
fg.AddRect(plot->Items.Legend.RectClamped.Min, plot->Items.Legend.RectClamped.Max, IM_COL32(255,128,0,255));
|
||||
}
|
||||
}
|
||||
for (int p = 0; p < n_subplots; ++p) {
|
||||
ImPlotSubplot* subplot = gp.Subplots.GetByIndex(p);
|
||||
@@ -5291,10 +5162,6 @@ void ShowMetricsWindow(bool* p_popen) {
|
||||
fg.AddRect(subplot->FrameRect.Min, subplot->FrameRect.Max, IM_COL32(255,0,0,255));
|
||||
if (show_subplot_grid_rects)
|
||||
fg.AddRect(subplot->GridRect.Min, subplot->GridRect.Max, IM_COL32(0,0,255,255));
|
||||
if (show_legend_rects && subplot->Items.GetLegendCount() > 0) {
|
||||
fg.AddRect(subplot->Items.Legend.Rect.Min, subplot->Items.Legend.Rect.Max, IM_COL32(255,192,0,255));
|
||||
fg.AddRect(subplot->Items.Legend.RectClamped.Min, subplot->Items.Legend.RectClamped.Max, IM_COL32(255,128,0,255));
|
||||
}
|
||||
}
|
||||
if (ImGui::TreeNode("Plots","Plots (%d)", n_plots)) {
|
||||
for (int p = 0; p < n_plots; ++p) {
|
||||
@@ -1,6 +1,6 @@
|
||||
// MIT License
|
||||
|
||||
// Copyright (c) 2023 Evan Pezent
|
||||
// Copyright (c) 2022 Evan Pezent
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -20,7 +20,7 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
// ImPlot v0.17
|
||||
// ImPlot v0.14
|
||||
|
||||
// We define this so that the demo does not accidentally use deprecated API
|
||||
#ifndef IMPLOT_DISABLE_OBSOLETE_FUNCTIONS
|
||||
@@ -610,8 +610,10 @@ void Demo_PieCharts() {
|
||||
static ImPlotPieChartFlags flags = 0;
|
||||
ImGui::SetNextItemWidth(250);
|
||||
ImGui::DragFloat4("Values", data1, 0.01f, 0, 1);
|
||||
CHECKBOX_FLAG(flags, ImPlotPieChartFlags_Normalize);
|
||||
CHECKBOX_FLAG(flags, ImPlotPieChartFlags_IgnoreHidden);
|
||||
if ((data1[0] + data1[1] + data1[2] + data1[3]) < 1) {
|
||||
ImGui::SameLine();
|
||||
CHECKBOX_FLAG(flags,ImPlotPieChartFlags_Normalize);
|
||||
}
|
||||
|
||||
if (ImPlot::BeginPlot("##Pie1", ImVec2(250,250), ImPlotFlags_Equal | ImPlotFlags_NoMouseText)) {
|
||||
ImPlot::SetupAxes(nullptr, nullptr, ImPlotAxisFlags_NoDecorations, ImPlotAxisFlags_NoDecorations);
|
||||
@@ -1145,7 +1147,7 @@ void Demo_MultipleAxes() {
|
||||
ImPlot::SetAxes(ImAxis_X1, ImAxis_Y2);
|
||||
ImPlot::PlotLine("f(x) = cos(x)*.2+.5", xs, ys2, 1001);
|
||||
}
|
||||
if (x2_axis && y3_axis) {
|
||||
if (y3_axis) {
|
||||
ImPlot::SetAxes(ImAxis_X2, ImAxis_Y3);
|
||||
ImPlot::PlotLine("f(x) = sin(x+.5)*100+200 ", xs2, ys3, 1001);
|
||||
}
|
||||
@@ -1262,7 +1264,7 @@ ImPlotPoint SinewaveGetter(int i, void* data) {
|
||||
|
||||
void Demo_SubplotsSizing() {
|
||||
|
||||
static ImPlotSubplotFlags flags = ImPlotSubplotFlags_ShareItems|ImPlotSubplotFlags_NoLegend;
|
||||
static ImPlotSubplotFlags flags = ImPlotSubplotFlags_None;
|
||||
ImGui::CheckboxFlags("ImPlotSubplotFlags_NoResize", (unsigned int*)&flags, ImPlotSubplotFlags_NoResize);
|
||||
ImGui::CheckboxFlags("ImPlotSubplotFlags_NoTitle", (unsigned int*)&flags, ImPlotSubplotFlags_NoTitle);
|
||||
|
||||
@@ -1270,26 +1272,17 @@ void Demo_SubplotsSizing() {
|
||||
static int cols = 3;
|
||||
ImGui::SliderInt("Rows",&rows,1,5);
|
||||
ImGui::SliderInt("Cols",&cols,1,5);
|
||||
if (rows < 1 || cols < 1) {
|
||||
ImGui::TextColored(ImVec4(1,0,0,1), "Nice try, but the number of rows and columns must be greater than 0!");
|
||||
return;
|
||||
}
|
||||
static float rratios[] = {5,1,1,1,1,1};
|
||||
static float cratios[] = {5,1,1,1,1,1};
|
||||
ImGui::DragScalarN("Row Ratios",ImGuiDataType_Float,rratios,rows,0.01f,nullptr);
|
||||
ImGui::DragScalarN("Col Ratios",ImGuiDataType_Float,cratios,cols,0.01f,nullptr);
|
||||
if (ImPlot::BeginSubplots("My Subplots", rows, cols, ImVec2(-1,400), flags, rratios, cratios)) {
|
||||
int id = 0;
|
||||
for (int i = 0; i < rows*cols; ++i) {
|
||||
if (ImPlot::BeginPlot("",ImVec2(),ImPlotFlags_NoLegend)) {
|
||||
ImPlot::SetupAxes(nullptr,nullptr,ImPlotAxisFlags_NoDecorations,ImPlotAxisFlags_NoDecorations);
|
||||
float fi = 0.01f * (i+1);
|
||||
if (rows*cols > 1) {
|
||||
ImPlot::SetNextLineStyle(SampleColormap((float)i/(float)(rows*cols-1),ImPlotColormap_Jet));
|
||||
}
|
||||
char label[16];
|
||||
snprintf(label, sizeof(label), "data%d", id++);
|
||||
ImPlot::PlotLineG(label,SinewaveGetter,&fi,1000);
|
||||
ImPlot::SetNextLineStyle(SampleColormap((float)i/(float)(rows*cols-1),ImPlotColormap_Jet));
|
||||
ImPlot::PlotLineG("data",SinewaveGetter,&fi,1000);
|
||||
ImPlot::EndPlot();
|
||||
}
|
||||
}
|
||||
@@ -1309,7 +1302,6 @@ void Demo_SubplotItemSharing() {
|
||||
static int id[] = {0,1,2,3,4,5};
|
||||
static int curj = -1;
|
||||
if (ImPlot::BeginSubplots("##ItemSharing", rows, cols, ImVec2(-1,400), flags)) {
|
||||
ImPlot::SetupLegend(ImPlotLocation_South, ImPlotLegendFlags_Sort|ImPlotLegendFlags_Horizontal);
|
||||
for (int i = 0; i < rows*cols; ++i) {
|
||||
if (ImPlot::BeginPlot("")) {
|
||||
float fc = 0.01f;
|
||||
@@ -1384,9 +1376,6 @@ void Demo_LegendOptions() {
|
||||
ImGui::SliderFloat2("LegendInnerPadding", (float*)&GetStyle().LegendInnerPadding, 0.0f, 10.0f, "%.0f");
|
||||
ImGui::SliderFloat2("LegendSpacing", (float*)&GetStyle().LegendSpacing, 0.0f, 5.0f, "%.0f");
|
||||
|
||||
static int num_dummy_items = 25;
|
||||
ImGui::SliderInt("Num Dummy Items (Demo Scrolling)", &num_dummy_items, 0, 100);
|
||||
|
||||
if (ImPlot::BeginPlot("##Legend",ImVec2(-1,0))) {
|
||||
ImPlot::SetupLegend(loc, flags);
|
||||
static MyImPlot::WaveData data1(0.001, 0.2, 4, 0.2);
|
||||
@@ -1395,21 +1384,16 @@ void Demo_LegendOptions() {
|
||||
static MyImPlot::WaveData data4(0.001, 0.2, 4, 0.8);
|
||||
static MyImPlot::WaveData data5(0.001, 0.2, 4, 1.0);
|
||||
|
||||
ImPlot::PlotLineG("Item 002", MyImPlot::SawWave, &data1, 1000); // "Item B" added to legend
|
||||
ImPlot::PlotLineG("Item 001##IDText", MyImPlot::SawWave, &data2, 1000); // "Item A" added to legend, text after ## used for ID only
|
||||
ImPlot::PlotLineG("Item B", MyImPlot::SawWave, &data1, 1000); // "Item B" added to legend
|
||||
ImPlot::PlotLineG("Item A##IDText", MyImPlot::SawWave, &data2, 1000); // "Item A" added to legend, text after ## used for ID only
|
||||
ImPlot::PlotLineG("##NotListed", MyImPlot::SawWave, &data3, 1000); // plotted, but not added to legend
|
||||
ImPlot::PlotLineG("Item 003", MyImPlot::SawWave, &data4, 1000); // "Item C" added to legend
|
||||
ImPlot::PlotLineG("Item 003", MyImPlot::SawWave, &data5, 1000); // combined with previous "Item C"
|
||||
ImPlot::PlotLineG("Item C", MyImPlot::SawWave, &data4, 1000); // "Item C" added to legend
|
||||
ImPlot::PlotLineG("Item C", MyImPlot::SawWave, &data5, 1000); // combined with previous "Item C"
|
||||
|
||||
for (int i = 0; i < num_dummy_items; ++i) {
|
||||
char label[16];
|
||||
snprintf(label, sizeof(label), "Item %03d", i+4);
|
||||
ImPlot::PlotDummy(label);
|
||||
}
|
||||
ImPlot::EndPlot();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void Demo_DragPoints() {
|
||||
@@ -1419,18 +1403,15 @@ void Demo_DragPoints() {
|
||||
ImGui::CheckboxFlags("NoFit", (unsigned int*)&flags, ImPlotDragToolFlags_NoFit); ImGui::SameLine();
|
||||
ImGui::CheckboxFlags("NoInput", (unsigned int*)&flags, ImPlotDragToolFlags_NoInputs);
|
||||
ImPlotAxisFlags ax_flags = ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoTickMarks;
|
||||
bool clicked[4] = {false, false, false, false};
|
||||
bool hovered[4] = {false, false, false, false};
|
||||
bool held[4] = {false, false, false, false};
|
||||
if (ImPlot::BeginPlot("##Bezier",ImVec2(-1,0),ImPlotFlags_CanvasOnly)) {
|
||||
ImPlot::SetupAxes(nullptr,nullptr,ax_flags,ax_flags);
|
||||
ImPlot::SetupAxesLimits(0,1,0,1);
|
||||
static ImPlotPoint P[] = {ImPlotPoint(.05f,.05f), ImPlotPoint(0.2,0.4), ImPlotPoint(0.8,0.6), ImPlotPoint(.95f,.95f)};
|
||||
|
||||
ImPlot::DragPoint(0,&P[0].x,&P[0].y, ImVec4(0,0.9f,0,1),4,flags, &clicked[0], &hovered[0], &held[0]);
|
||||
ImPlot::DragPoint(1,&P[1].x,&P[1].y, ImVec4(1,0.5f,1,1),4,flags, &clicked[1], &hovered[1], &held[1]);
|
||||
ImPlot::DragPoint(2,&P[2].x,&P[2].y, ImVec4(0,0.5f,1,1),4,flags, &clicked[2], &hovered[2], &held[2]);
|
||||
ImPlot::DragPoint(3,&P[3].x,&P[3].y, ImVec4(0,0.9f,0,1),4,flags, &clicked[3], &hovered[3], &held[3]);
|
||||
ImPlot::DragPoint(0,&P[0].x,&P[0].y, ImVec4(0,0.9f,0,1),4,flags);
|
||||
ImPlot::DragPoint(1,&P[1].x,&P[1].y, ImVec4(1,0.5f,1,1),4,flags);
|
||||
ImPlot::DragPoint(2,&P[2].x,&P[2].y, ImVec4(0,0.5f,1,1),4,flags);
|
||||
ImPlot::DragPoint(3,&P[3].x,&P[3].y, ImVec4(0,0.9f,0,1),4,flags);
|
||||
|
||||
static ImPlotPoint B[100];
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
@@ -1443,12 +1424,14 @@ void Demo_DragPoints() {
|
||||
B[i] = ImPlotPoint(w1*P[0].x + w2*P[1].x + w3*P[2].x + w4*P[3].x, w1*P[0].y + w2*P[1].y + w3*P[2].y + w4*P[3].y);
|
||||
}
|
||||
|
||||
ImPlot::SetNextLineStyle(ImVec4(1,0.5f,1,1),hovered[1]||held[1] ? 2.0f : 1.0f);
|
||||
|
||||
ImPlot::SetNextLineStyle(ImVec4(1,0.5f,1,1));
|
||||
ImPlot::PlotLine("##h1",&P[0].x, &P[0].y, 2, 0, 0, sizeof(ImPlotPoint));
|
||||
ImPlot::SetNextLineStyle(ImVec4(0,0.5f,1,1), hovered[2]||held[2] ? 2.0f : 1.0f);
|
||||
ImPlot::SetNextLineStyle(ImVec4(0,0.5f,1,1));
|
||||
ImPlot::PlotLine("##h2",&P[2].x, &P[2].y, 2, 0, 0, sizeof(ImPlotPoint));
|
||||
ImPlot::SetNextLineStyle(ImVec4(0,0.9f,0,1), hovered[0]||held[0]||hovered[3]||held[3] ? 3.0f : 2.0f);
|
||||
ImPlot::SetNextLineStyle(ImVec4(0,0.9f,0,1), 2);
|
||||
ImPlot::PlotLine("##bez",&B[0].x, &B[0].y, 100, 0, 0, sizeof(ImPlotPoint));
|
||||
|
||||
ImPlot::EndPlot();
|
||||
}
|
||||
}
|
||||
@@ -1462,9 +1445,6 @@ void Demo_DragLines() {
|
||||
static double y1 = 0.25;
|
||||
static double y2 = 0.75;
|
||||
static double f = 0.1;
|
||||
bool clicked = false;
|
||||
bool hovered = false;
|
||||
bool held = false;
|
||||
static ImPlotDragToolFlags flags = ImPlotDragToolFlags_None;
|
||||
ImGui::CheckboxFlags("NoCursors", (unsigned int*)&flags, ImPlotDragToolFlags_NoCursors); ImGui::SameLine();
|
||||
ImGui::CheckboxFlags("NoFit", (unsigned int*)&flags, ImPlotDragToolFlags_NoFit); ImGui::SameLine();
|
||||
@@ -1480,9 +1460,8 @@ void Demo_DragLines() {
|
||||
xs[i] = (x2+x1)/2+fabs(x2-x1)*(i/1000.0f - 0.5f);
|
||||
ys[i] = (y1+y2)/2+fabs(y2-y1)/2*sin(f*i/10);
|
||||
}
|
||||
ImPlot::DragLineY(120482,&f,ImVec4(1,0.5f,1,1),1,flags, &clicked, &hovered, &held);
|
||||
ImPlot::SetNextLineStyle(IMPLOT_AUTO_COL, hovered||held ? 2.0f : 1.0f);
|
||||
ImPlot::PlotLine("Interactive Data", xs, ys, 1000);
|
||||
ImPlot::DragLineY(120482,&f,ImVec4(1,0.5f,1,1),1,flags);
|
||||
ImPlot::EndPlot();
|
||||
}
|
||||
}
|
||||
@@ -1497,9 +1476,6 @@ void Demo_DragRects() {
|
||||
static float y_data3[512];
|
||||
static float sampling_freq = 44100;
|
||||
static float freq = 500;
|
||||
bool clicked = false;
|
||||
bool hovered = false;
|
||||
bool held = false;
|
||||
for (size_t i = 0; i < 512; ++i) {
|
||||
const float t = i / sampling_freq;
|
||||
x_data[i] = t;
|
||||
@@ -1509,7 +1485,6 @@ void Demo_DragRects() {
|
||||
y_data3[i] = y_data2[i] * -0.6f + sinf(3 * arg) * 0.4f;
|
||||
}
|
||||
ImGui::BulletText("Click and drag the edges, corners, and center of the rect.");
|
||||
ImGui::BulletText("Double click edges to expand rect to plot extents.");
|
||||
static ImPlotRect rect(0.0025,0.0045,0,0.5);
|
||||
static ImPlotDragToolFlags flags = ImPlotDragToolFlags_None;
|
||||
ImGui::CheckboxFlags("NoCursors", (unsigned int*)&flags, ImPlotDragToolFlags_NoCursors); ImGui::SameLine();
|
||||
@@ -1522,11 +1497,9 @@ void Demo_DragRects() {
|
||||
ImPlot::PlotLine("Signal 1", x_data, y_data1, 512);
|
||||
ImPlot::PlotLine("Signal 2", x_data, y_data2, 512);
|
||||
ImPlot::PlotLine("Signal 3", x_data, y_data3, 512);
|
||||
ImPlot::DragRect(0,&rect.X.Min,&rect.Y.Min,&rect.X.Max,&rect.Y.Max,ImVec4(1,0,1,1),flags, &clicked, &hovered, &held);
|
||||
ImPlot::DragRect(0,&rect.X.Min,&rect.Y.Min,&rect.X.Max,&rect.Y.Max,ImVec4(1,0,1,1),flags);
|
||||
ImPlot::EndPlot();
|
||||
}
|
||||
ImVec4 bg_col = held ? ImVec4(0.5f,0,0.5f,1) : (hovered ? ImVec4(0.25f,0,0.25f,1) : ImPlot::GetStyle().Colors[ImPlotCol_PlotBg]);
|
||||
ImPlot::PushStyleColor(ImPlotCol_PlotBg, bg_col);
|
||||
if (ImPlot::BeginPlot("##rect",ImVec2(-1,150), ImPlotFlags_CanvasOnly)) {
|
||||
ImPlot::SetupAxes(nullptr,nullptr,ImPlotAxisFlags_NoDecorations,ImPlotAxisFlags_NoDecorations);
|
||||
ImPlot::SetupAxesLimits(rect.X.Min, rect.X.Max, rect.Y.Min, rect.Y.Max, ImGuiCond_Always);
|
||||
@@ -1535,8 +1508,6 @@ void Demo_DragRects() {
|
||||
ImPlot::PlotLine("Signal 3", x_data, y_data3, 512);
|
||||
ImPlot::EndPlot();
|
||||
}
|
||||
ImPlot::PopStyleColor();
|
||||
ImGui::Text("Rect is %sclicked, %shovered, %sheld", clicked ? "" : "not ", hovered ? "" : "not ", held ? "" : "not ");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -2328,7 +2299,7 @@ ImPlotPoint Spiral(int idx, void*) {
|
||||
|
||||
void Sparkline(const char* id, const float* values, int count, float min_v, float max_v, int offset, const ImVec4& col, const ImVec2& size) {
|
||||
ImPlot::PushStyleVar(ImPlotStyleVar_PlotPadding, ImVec2(0,0));
|
||||
if (ImPlot::BeginPlot(id,size,ImPlotFlags_CanvasOnly)) {
|
||||
if (ImPlot::BeginPlot(id,size,ImPlotFlags_CanvasOnly|ImPlotFlags_NoChild)) {
|
||||
ImPlot::SetupAxes(nullptr,nullptr,ImPlotAxisFlags_NoDecorations,ImPlotAxisFlags_NoDecorations);
|
||||
ImPlot::SetupAxesLimits(0, count - 1, min_v, max_v, ImGuiCond_Always);
|
||||
ImPlot::SetNextLineStyle(col);
|
||||
@@ -1,6 +1,6 @@
|
||||
// MIT License
|
||||
|
||||
// Copyright (c) 2023 Evan Pezent
|
||||
// Copyright (c) 2020 Evan Pezent
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -20,7 +20,7 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
// ImPlot v0.17
|
||||
// ImPlot v0.14
|
||||
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
#include "implot.h"
|
||||
@@ -98,11 +98,11 @@ static IMPLOT_INLINE float ImInvSqrt(float x) { return 1.0f / sqrtf(x); }
|
||||
#define _CAT(x, y) _CAT_(x, y)
|
||||
#define _CAT_(x,y) x ## y
|
||||
#define _INSTANTIATE_FOR_NUMERIC_TYPES(chain) _CAT(_INSTANTIATE_FOR_NUMERIC_TYPES_1 chain, _END)
|
||||
#define _INSTANTIATE_FOR_NUMERIC_TYPES_1(T) INSTANTIATE_MACRO(T) _INSTANTIATE_FOR_NUMERIC_TYPES_2
|
||||
#define _INSTANTIATE_FOR_NUMERIC_TYPES_2(T) INSTANTIATE_MACRO(T) _INSTANTIATE_FOR_NUMERIC_TYPES_1
|
||||
#define _INSTANTIATE_FOR_NUMERIC_TYPES_1(T) INSTANTIATE_MACRO(T); _INSTANTIATE_FOR_NUMERIC_TYPES_2
|
||||
#define _INSTANTIATE_FOR_NUMERIC_TYPES_2(T) INSTANTIATE_MACRO(T); _INSTANTIATE_FOR_NUMERIC_TYPES_1
|
||||
#define _INSTANTIATE_FOR_NUMERIC_TYPES_1_END
|
||||
#define _INSTANTIATE_FOR_NUMERIC_TYPES_2_END
|
||||
#define CALL_INSTANTIATE_FOR_NUMERIC_TYPES() _INSTANTIATE_FOR_NUMERIC_TYPES(IMPLOT_NUMERIC_TYPES)
|
||||
#define CALL_INSTANTIATE_FOR_NUMERIC_TYPES() _INSTANTIATE_FOR_NUMERIC_TYPES(IMPLOT_NUMERIC_TYPES);
|
||||
|
||||
namespace ImPlot {
|
||||
|
||||
@@ -1287,7 +1287,7 @@ struct RendererShaded : RendererBase {
|
||||
return false;
|
||||
}
|
||||
const int intersect = (P11.y > P12.y && P22.y > P21.y) || (P12.y > P11.y && P21.y > P22.y);
|
||||
const ImVec2 intersection = intersect == 0 ? ImVec2(0,0) : Intersection(P11,P21,P12,P22);
|
||||
ImVec2 intersection = Intersection(P11,P21,P12,P22);
|
||||
draw_list._VtxWritePtr[0].pos = P11;
|
||||
draw_list._VtxWritePtr[0].uv = UV;
|
||||
draw_list._VtxWritePtr[0].col = Col;
|
||||
@@ -1569,10 +1569,6 @@ void RenderMarkers(const _Getter& getter, ImPlotMarker marker, float size, bool
|
||||
template <typename _Getter>
|
||||
void PlotLineEx(const char* label_id, const _Getter& getter, ImPlotLineFlags flags) {
|
||||
if (BeginItemEx(label_id, Fitter1<_Getter>(getter), flags, ImPlotCol_Line)) {
|
||||
if (getter.Count <= 0) {
|
||||
EndItem();
|
||||
return;
|
||||
}
|
||||
const ImPlotNextItemData& s = GetItemData();
|
||||
if (getter.Count > 1) {
|
||||
if (ImHasFlag(flags, ImPlotLineFlags_Shaded) && s.RenderFill) {
|
||||
@@ -1644,10 +1640,6 @@ void PlotLineG(const char* label_id, ImPlotGetter getter_func, void* data, int c
|
||||
template <typename Getter>
|
||||
void PlotScatterEx(const char* label_id, const Getter& getter, ImPlotScatterFlags flags) {
|
||||
if (BeginItemEx(label_id, Fitter1<Getter>(getter), flags, ImPlotCol_MarkerOutline)) {
|
||||
if (getter.Count <= 0) {
|
||||
EndItem();
|
||||
return;
|
||||
}
|
||||
const ImPlotNextItemData& s = GetItemData();
|
||||
ImPlotMarker marker = s.Marker == ImPlotMarker_None ? ImPlotMarker_Circle: s.Marker;
|
||||
if (marker != ImPlotMarker_None) {
|
||||
@@ -1694,12 +1686,8 @@ void PlotScatterG(const char* label_id, ImPlotGetter getter_func, void* data, in
|
||||
template <typename Getter>
|
||||
void PlotStairsEx(const char* label_id, const Getter& getter, ImPlotStairsFlags flags) {
|
||||
if (BeginItemEx(label_id, Fitter1<Getter>(getter), flags, ImPlotCol_Line)) {
|
||||
if (getter.Count <= 0) {
|
||||
EndItem();
|
||||
return;
|
||||
}
|
||||
const ImPlotNextItemData& s = GetItemData();
|
||||
if (getter.Count > 1) {
|
||||
if (getter.Count > 1 ) {
|
||||
if (s.RenderFill && ImHasFlag(flags,ImPlotStairsFlags_Shaded)) {
|
||||
const ImU32 col_fill = ImGui::GetColorU32(s.Colors[ImPlotCol_Fill]);
|
||||
if (ImHasFlag(flags, ImPlotStairsFlags_PreStep))
|
||||
@@ -1758,10 +1746,6 @@ void PlotStairsG(const char* label_id, ImPlotGetter getter_func, void* data, int
|
||||
template <typename Getter1, typename Getter2>
|
||||
void PlotShadedEx(const char* label_id, const Getter1& getter1, const Getter2& getter2, ImPlotShadedFlags flags) {
|
||||
if (BeginItemEx(label_id, Fitter2<Getter1,Getter2>(getter1,getter2), flags, ImPlotCol_Fill)) {
|
||||
if (getter1.Count <= 0 || getter2.Count <= 0) {
|
||||
EndItem();
|
||||
return;
|
||||
}
|
||||
const ImPlotNextItemData& s = GetItemData();
|
||||
if (s.RenderFill) {
|
||||
const ImU32 col = ImGui::GetColorU32(s.Colors[ImPlotCol_Fill]);
|
||||
@@ -1822,10 +1806,6 @@ void PlotShadedG(const char* label_id, ImPlotGetter getter_func1, void* data1, I
|
||||
template <typename Getter1, typename Getter2>
|
||||
void PlotBarsVEx(const char* label_id, const Getter1& getter1, const Getter2 getter2, double width, ImPlotBarsFlags flags) {
|
||||
if (BeginItemEx(label_id, FitterBarV<Getter1,Getter2>(getter1,getter2,width), flags, ImPlotCol_Fill)) {
|
||||
if (getter1.Count <= 0 || getter2.Count <= 0) {
|
||||
EndItem();
|
||||
return;
|
||||
}
|
||||
const ImPlotNextItemData& s = GetItemData();
|
||||
const ImU32 col_fill = ImGui::GetColorU32(s.Colors[ImPlotCol_Fill]);
|
||||
const ImU32 col_line = ImGui::GetColorU32(s.Colors[ImPlotCol_Line]);
|
||||
@@ -1846,10 +1826,6 @@ void PlotBarsVEx(const char* label_id, const Getter1& getter1, const Getter2 get
|
||||
template <typename Getter1, typename Getter2>
|
||||
void PlotBarsHEx(const char* label_id, const Getter1& getter1, const Getter2& getter2, double height, ImPlotBarsFlags flags) {
|
||||
if (BeginItemEx(label_id, FitterBarH<Getter1,Getter2>(getter1,getter2,height), flags, ImPlotCol_Fill)) {
|
||||
if (getter1.Count <= 0 || getter2.Count <= 0) {
|
||||
EndItem();
|
||||
return;
|
||||
}
|
||||
const ImPlotNextItemData& s = GetItemData();
|
||||
const ImU32 col_fill = ImGui::GetColorU32(s.Colors[ImPlotCol_Fill]);
|
||||
const ImU32 col_line = ImGui::GetColorU32(s.Colors[ImPlotCol_Line]);
|
||||
@@ -2006,10 +1982,6 @@ CALL_INSTANTIATE_FOR_NUMERIC_TYPES()
|
||||
template <typename _GetterPos, typename _GetterNeg>
|
||||
void PlotErrorBarsVEx(const char* label_id, const _GetterPos& getter_pos, const _GetterNeg& getter_neg, ImPlotErrorBarsFlags flags) {
|
||||
if (BeginItemEx(label_id, Fitter2<_GetterPos,_GetterNeg>(getter_pos, getter_neg), flags, IMPLOT_AUTO)) {
|
||||
if (getter_pos.Count <= 0 || getter_neg.Count <= 0) {
|
||||
EndItem();
|
||||
return;
|
||||
}
|
||||
const ImPlotNextItemData& s = GetItemData();
|
||||
ImDrawList& draw_list = *GetPlotDrawList();
|
||||
const ImU32 col = ImGui::GetColorU32(s.Colors[ImPlotCol_ErrorBar]);
|
||||
@@ -2031,10 +2003,6 @@ void PlotErrorBarsVEx(const char* label_id, const _GetterPos& getter_pos, const
|
||||
template <typename _GetterPos, typename _GetterNeg>
|
||||
void PlotErrorBarsHEx(const char* label_id, const _GetterPos& getter_pos, const _GetterNeg& getter_neg, ImPlotErrorBarsFlags flags) {
|
||||
if (BeginItemEx(label_id, Fitter2<_GetterPos,_GetterNeg>(getter_pos, getter_neg), flags, IMPLOT_AUTO)) {
|
||||
if (getter_pos.Count <= 0 || getter_neg.Count <= 0) {
|
||||
EndItem();
|
||||
return;
|
||||
}
|
||||
const ImPlotNextItemData& s = GetItemData();
|
||||
ImDrawList& draw_list = *GetPlotDrawList();
|
||||
const ImU32 col = ImGui::GetColorU32(s.Colors[ImPlotCol_ErrorBar]);
|
||||
@@ -2092,17 +2060,13 @@ CALL_INSTANTIATE_FOR_NUMERIC_TYPES()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <typename _GetterM, typename _GetterB>
|
||||
void PlotStemsEx(const char* label_id, const _GetterM& getter_mark, const _GetterB& getter_base, ImPlotStemsFlags flags) {
|
||||
if (BeginItemEx(label_id, Fitter2<_GetterM,_GetterB>(getter_mark,getter_base), flags, ImPlotCol_Line)) {
|
||||
if (getter_mark.Count <= 0 || getter_base.Count <= 0) {
|
||||
EndItem();
|
||||
return;
|
||||
}
|
||||
void PlotStemsEx(const char* label_id, const _GetterM& get_mark, const _GetterB& get_base, ImPlotStemsFlags flags) {
|
||||
if (BeginItemEx(label_id, Fitter2<_GetterM,_GetterB>(get_mark,get_base), flags, ImPlotCol_Line)) {
|
||||
const ImPlotNextItemData& s = GetItemData();
|
||||
// render stems
|
||||
if (s.RenderLine) {
|
||||
const ImU32 col_line = ImGui::GetColorU32(s.Colors[ImPlotCol_Line]);
|
||||
RenderPrimitives2<RendererLineSegments2>(getter_mark, getter_base, col_line, s.LineWeight);
|
||||
RenderPrimitives2<RendererLineSegments2>(get_mark, get_base, col_line, s.LineWeight);
|
||||
}
|
||||
// render markers
|
||||
if (s.Marker != ImPlotMarker_None) {
|
||||
@@ -2110,7 +2074,7 @@ void PlotStemsEx(const char* label_id, const _GetterM& getter_mark, const _Gette
|
||||
PushPlotClipRect(s.MarkerSize);
|
||||
const ImU32 col_line = ImGui::GetColorU32(s.Colors[ImPlotCol_MarkerOutline]);
|
||||
const ImU32 col_fill = ImGui::GetColorU32(s.Colors[ImPlotCol_MarkerFill]);
|
||||
RenderMarkers<_GetterM>(getter_mark, s.Marker, s.MarkerSize, s.RenderMarkerFill, col_fill, s.RenderMarkerLine, col_line, s.MarkerWeight);
|
||||
RenderMarkers<_GetterM>(get_mark, s.Marker, s.MarkerSize, s.RenderMarkerFill, col_fill, s.RenderMarkerLine, col_line, s.MarkerWeight);
|
||||
}
|
||||
EndItem();
|
||||
}
|
||||
@@ -2159,17 +2123,13 @@ template <typename T>
|
||||
void PlotInfLines(const char* label_id, const T* values, int count, ImPlotInfLinesFlags flags, int offset, int stride) {
|
||||
const ImPlotRect lims = GetPlotLimits(IMPLOT_AUTO,IMPLOT_AUTO);
|
||||
if (ImHasFlag(flags, ImPlotInfLinesFlags_Horizontal)) {
|
||||
GetterXY<IndexerConst,IndexerIdx<T>> getter_min(IndexerConst(lims.X.Min),IndexerIdx<T>(values,count,offset,stride),count);
|
||||
GetterXY<IndexerConst,IndexerIdx<T>> getter_max(IndexerConst(lims.X.Max),IndexerIdx<T>(values,count,offset,stride),count);
|
||||
if (BeginItemEx(label_id, FitterY<GetterXY<IndexerConst,IndexerIdx<T>>>(getter_min), flags, ImPlotCol_Line)) {
|
||||
if (count <= 0) {
|
||||
EndItem();
|
||||
return;
|
||||
}
|
||||
GetterXY<IndexerConst,IndexerIdx<T>> get_min(IndexerConst(lims.X.Min),IndexerIdx<T>(values,count,offset,stride),count);
|
||||
GetterXY<IndexerConst,IndexerIdx<T>> get_max(IndexerConst(lims.X.Max),IndexerIdx<T>(values,count,offset,stride),count);
|
||||
if (BeginItemEx(label_id, FitterY<GetterXY<IndexerConst,IndexerIdx<T>>>(get_min), flags, ImPlotCol_Line)) {
|
||||
const ImPlotNextItemData& s = GetItemData();
|
||||
const ImU32 col_line = ImGui::GetColorU32(s.Colors[ImPlotCol_Line]);
|
||||
if (s.RenderLine)
|
||||
RenderPrimitives2<RendererLineSegments2>(getter_min, getter_max, col_line, s.LineWeight);
|
||||
RenderPrimitives2<RendererLineSegments2>(get_min, get_max, col_line, s.LineWeight);
|
||||
EndItem();
|
||||
}
|
||||
}
|
||||
@@ -2177,10 +2137,6 @@ void PlotInfLines(const char* label_id, const T* values, int count, ImPlotInfLin
|
||||
GetterXY<IndexerIdx<T>,IndexerConst> get_min(IndexerIdx<T>(values,count,offset,stride),IndexerConst(lims.Y.Min),count);
|
||||
GetterXY<IndexerIdx<T>,IndexerConst> get_max(IndexerIdx<T>(values,count,offset,stride),IndexerConst(lims.Y.Max),count);
|
||||
if (BeginItemEx(label_id, FitterX<GetterXY<IndexerIdx<T>,IndexerConst>>(get_min), flags, ImPlotCol_Line)) {
|
||||
if (count <= 0) {
|
||||
EndItem();
|
||||
return;
|
||||
}
|
||||
const ImPlotNextItemData& s = GetItemData();
|
||||
const ImU32 col_line = ImGui::GetColorU32(s.Colors[ImPlotCol_Line]);
|
||||
if (s.RenderLine)
|
||||
@@ -2216,121 +2172,57 @@ IMPLOT_INLINE void RenderPieSlice(ImDrawList& draw_list, const ImPlotPoint& cent
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
double PieChartSum(const T* values, int count, bool ignore_hidden) {
|
||||
void PlotPieChart(const char* const label_ids[], const T* values, int count, double x, double y, double radius, const char* fmt, double angle0, ImPlotPieChartFlags flags) {
|
||||
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr, "PlotPieChart() needs to be called between BeginPlot() and EndPlot()!");
|
||||
ImDrawList & draw_list = *GetPlotDrawList();
|
||||
double sum = 0;
|
||||
if (ignore_hidden) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
ImPlotItemGroup& Items = *gp.CurrentItems;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (i >= Items.GetItemCount())
|
||||
break;
|
||||
|
||||
ImPlotItem* item = Items.GetItemByIndex(i);
|
||||
IM_ASSERT(item != nullptr);
|
||||
if (item->Show) {
|
||||
sum += (double)values[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
sum += (double)values[i];
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void PlotPieChartEx(const char* const label_ids[], const T* values, int count, ImPlotPoint center, double radius, double angle0, ImPlotPieChartFlags flags) {
|
||||
ImDrawList& draw_list = *GetPlotDrawList();
|
||||
|
||||
const bool ignore_hidden = ImHasFlag(flags, ImPlotPieChartFlags_IgnoreHidden);
|
||||
const double sum = PieChartSum(values, count, ignore_hidden);
|
||||
const bool normalize = ImHasFlag(flags, ImPlotPieChartFlags_Normalize) || sum > 1.0;
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
sum += (double)values[i];
|
||||
const bool normalize = ImHasFlag(flags,ImPlotPieChartFlags_Normalize) || sum > 1.0;
|
||||
ImPlotPoint center(x,y);
|
||||
PushPlotClipRect();
|
||||
double a0 = angle0 * 2 * IM_PI / 360.0;
|
||||
double a1 = angle0 * 2 * IM_PI / 360.0;
|
||||
ImPlotPoint Pmin = ImPlotPoint(center.x - radius, center.y - radius);
|
||||
ImPlotPoint Pmax = ImPlotPoint(center.x + radius, center.y + radius);
|
||||
ImPlotPoint Pmin = ImPlotPoint(x-radius,y-radius);
|
||||
ImPlotPoint Pmax = ImPlotPoint(x+radius,y+radius);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
ImPlotItem* item = GetItem(label_ids[i]);
|
||||
|
||||
const double percent = normalize ? (double)values[i] / sum : (double)values[i];
|
||||
const bool skip = sum <= 0.0 || (ignore_hidden && item != nullptr && !item->Show);
|
||||
if (!skip)
|
||||
a1 = a0 + 2 * IM_PI * percent;
|
||||
|
||||
if (BeginItemEx(label_ids[i], FitterRect(Pmin, Pmax))) {
|
||||
if (sum > 0.0) {
|
||||
ImU32 col = GetCurrentItem()->Color;
|
||||
if (percent < 0.5) {
|
||||
RenderPieSlice(draw_list, center, radius, a0, a1, col);
|
||||
}
|
||||
else {
|
||||
RenderPieSlice(draw_list, center, radius, a0, a0 + (a1 - a0) * 0.5, col);
|
||||
RenderPieSlice(draw_list, center, radius, a0 + (a1 - a0) * 0.5, a1, col);
|
||||
}
|
||||
double percent = normalize ? (double)values[i] / sum : (double)values[i];
|
||||
a1 = a0 + 2 * IM_PI * percent;
|
||||
if (BeginItemEx(label_ids[i], FitterRect(Pmin,Pmax))) {
|
||||
ImU32 col = GetCurrentItem()->Color;
|
||||
if (percent < 0.5) {
|
||||
RenderPieSlice(draw_list, center, radius, a0, a1, col);
|
||||
}
|
||||
else {
|
||||
RenderPieSlice(draw_list, center, radius, a0, a0 + (a1 - a0) * 0.5, col);
|
||||
RenderPieSlice(draw_list, center, radius, a0 + (a1 - a0) * 0.5, a1, col);
|
||||
}
|
||||
EndItem();
|
||||
}
|
||||
if (!skip)
|
||||
a0 = a1;
|
||||
a0 = a1;
|
||||
}
|
||||
}
|
||||
|
||||
int PieChartFormatter(double value, char* buff, int size, void* data) {
|
||||
const char* fmt = (const char*)data;
|
||||
return snprintf(buff, size, fmt, value);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void PlotPieChart(const char* const label_ids[], const T* values, int count, double x, double y, double radius, const char* fmt, double angle0, ImPlotPieChartFlags flags) {
|
||||
PlotPieChart<T>(label_ids, values, count, x, y, radius, PieChartFormatter, (void*)fmt, angle0, flags);
|
||||
}
|
||||
#define INSTANTIATE_MACRO(T) template IMPLOT_API void PlotPieChart<T>(const char* const label_ids[], const T* values, int count, double x, double y, double radius, const char* fmt, double angle0, ImPlotPieChartFlags flags);
|
||||
CALL_INSTANTIATE_FOR_NUMERIC_TYPES()
|
||||
#undef INSTANTIATE_MACRO
|
||||
|
||||
template <typename T>
|
||||
void PlotPieChart(const char* const label_ids[], const T* values, int count, double x, double y, double radius, ImPlotFormatter fmt, void* fmt_data, double angle0, ImPlotPieChartFlags flags) {
|
||||
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr, "PlotPieChart() needs to be called between BeginPlot() and EndPlot()!");
|
||||
ImDrawList& draw_list = *GetPlotDrawList();
|
||||
|
||||
const bool ignore_hidden = ImHasFlag(flags, ImPlotPieChartFlags_IgnoreHidden);
|
||||
const double sum = PieChartSum(values, count, ignore_hidden);
|
||||
const bool normalize = ImHasFlag(flags, ImPlotPieChartFlags_Normalize) || sum > 1.0;
|
||||
ImPlotPoint center(x, y);
|
||||
|
||||
PushPlotClipRect();
|
||||
PlotPieChartEx(label_ids, values, count, center, radius, angle0, flags);
|
||||
if (fmt != nullptr) {
|
||||
double a0 = angle0 * 2 * IM_PI / 360.0;
|
||||
double a1 = angle0 * 2 * IM_PI / 360.0;
|
||||
a0 = angle0 * 2 * IM_PI / 360.0;
|
||||
a1 = angle0 * 2 * IM_PI / 360.0;
|
||||
char buffer[32];
|
||||
for (int i = 0; i < count; ++i) {
|
||||
ImPlotItem* item = GetItem(label_ids[i]);
|
||||
IM_ASSERT(item != nullptr);
|
||||
|
||||
const double percent = normalize ? (double)values[i] / sum : (double)values[i];
|
||||
const bool skip = ignore_hidden && item != nullptr && !item->Show;
|
||||
|
||||
if (!skip) {
|
||||
a1 = a0 + 2 * IM_PI * percent;
|
||||
if (item->Show) {
|
||||
fmt((double)values[i], buffer, 32, fmt_data);
|
||||
ImVec2 size = ImGui::CalcTextSize(buffer);
|
||||
double angle = a0 + (a1 - a0) * 0.5;
|
||||
ImVec2 pos = PlotToPixels(center.x + 0.5 * radius * cos(angle), center.y + 0.5 * radius * sin(angle), IMPLOT_AUTO, IMPLOT_AUTO);
|
||||
ImU32 col = CalcTextColor(ImGui::ColorConvertU32ToFloat4(item->Color));
|
||||
draw_list.AddText(pos - size * 0.5f, col, buffer);
|
||||
}
|
||||
a0 = a1;
|
||||
double percent = normalize ? (double)values[i] / sum : (double)values[i];
|
||||
a1 = a0 + 2 * IM_PI * percent;
|
||||
if (item->Show) {
|
||||
ImFormatString(buffer, 32, fmt, (double)values[i]);
|
||||
ImVec2 size = ImGui::CalcTextSize(buffer);
|
||||
double angle = a0 + (a1 - a0) * 0.5;
|
||||
ImVec2 pos = PlotToPixels(center.x + 0.5 * radius * cos(angle), center.y + 0.5 * radius * sin(angle),IMPLOT_AUTO,IMPLOT_AUTO);
|
||||
ImU32 col = CalcTextColor(ImGui::ColorConvertU32ToFloat4(item->Color));
|
||||
draw_list.AddText(pos - size * 0.5f, col, buffer);
|
||||
}
|
||||
a0 = a1;
|
||||
}
|
||||
}
|
||||
PopPlotClipRect();
|
||||
}
|
||||
#define INSTANTIATE_MACRO(T) template IMPLOT_API void PlotPieChart(const char* const label_ids[], const T* values, int count, double x, double y, double radius, ImPlotFormatter fmt, void* fmt_data, double angle0, ImPlotPieChartFlags flags);
|
||||
#define INSTANTIATE_MACRO(T) template IMPLOT_API void PlotPieChart<T>(const char* const label_ids[], const T* values, int count, double x, double y, double radius, const char* fmt, double angle0, ImPlotPieChartFlags flags);
|
||||
CALL_INSTANTIATE_FOR_NUMERIC_TYPES()
|
||||
#undef INSTANTIATE_MACRO
|
||||
|
||||
@@ -2391,8 +2283,8 @@ struct GetterHeatmapColMaj {
|
||||
{ }
|
||||
template <typename I> IMPLOT_INLINE RectC operator()(I idx) const {
|
||||
double val = (double)Values[idx];
|
||||
const int r = idx % Rows;
|
||||
const int c = idx / Rows;
|
||||
const int r = idx % Cols;
|
||||
const int c = idx / Cols;
|
||||
const ImPlotPoint p(XRef + HalfSize.x + c*Width, YRef + YDir * (HalfSize.y + r*Height));
|
||||
RectC rect;
|
||||
rect.Pos = p;
|
||||
@@ -2483,10 +2375,6 @@ void RenderHeatmap(ImDrawList& draw_list, const T* values, int rows, int cols, d
|
||||
template <typename T>
|
||||
void PlotHeatmap(const char* label_id, const T* values, int rows, int cols, double scale_min, double scale_max, const char* fmt, const ImPlotPoint& bounds_min, const ImPlotPoint& bounds_max, ImPlotHeatmapFlags flags) {
|
||||
if (BeginItemEx(label_id, FitterRect(bounds_min, bounds_max))) {
|
||||
if (rows <= 0 || cols <= 0) {
|
||||
EndItem();
|
||||
return;
|
||||
}
|
||||
ImDrawList& draw_list = *GetPlotDrawList();
|
||||
const bool col_maj = ImHasFlag(flags, ImPlotHeatmapFlags_ColMajor);
|
||||
RenderHeatmap(draw_list, values, rows, cols, scale_min, scale_max, fmt, bounds_min, bounds_max, true, col_maj);
|
||||
@@ -2651,10 +2539,6 @@ double PlotHistogram2D(const char* label_id, const T* xs, const T* ys, int count
|
||||
}
|
||||
|
||||
if (BeginItemEx(label_id, FitterRect(range))) {
|
||||
if (y_bins <= 0 || x_bins <= 0) {
|
||||
EndItem();
|
||||
return max_count;
|
||||
}
|
||||
ImDrawList& draw_list = *GetPlotDrawList();
|
||||
RenderHeatmap(draw_list, &bin_counts.Data[0], y_bins, x_bins, 0, max_count, nullptr, range.Min(), range.Max(), false, col_maj);
|
||||
EndItem();
|
||||
@@ -2713,8 +2597,8 @@ void PlotDigitalEx(const char* label_id, Getter getter, ImPlotDigitalFlags flags
|
||||
//do not extend plot outside plot range
|
||||
if (pMin.x < x_axis.PixelMin) pMin.x = x_axis.PixelMin;
|
||||
if (pMax.x < x_axis.PixelMin) pMax.x = x_axis.PixelMin;
|
||||
if (pMin.x > x_axis.PixelMax) pMin.x = x_axis.PixelMax - 1; //fix issue related to https://github.com/ocornut/imgui/issues/3976
|
||||
if (pMax.x > x_axis.PixelMax) pMax.x = x_axis.PixelMax - 1; //fix issue related to https://github.com/ocornut/imgui/issues/3976
|
||||
if (pMin.x > x_axis.PixelMax) pMin.x = x_axis.PixelMax;
|
||||
if (pMax.x > x_axis.PixelMax) pMax.x = x_axis.PixelMax;
|
||||
//plot a rectangle that extends up to x2 with y1 height
|
||||
if ((pMax.x > pMin.x) && (gp.CurrentPlot->PlotRect.Contains(pMin) || gp.CurrentPlot->PlotRect.Contains(pMax))) {
|
||||
// ImVec4 colAlpha = item->Color;
|
||||
2
lib/external/libromfs
vendored
2
lib/external/libromfs
vendored
Submodule lib/external/libromfs updated: 0a72f7bb33...c42309b7c4
2
lib/external/libwolv
vendored
2
lib/external/libwolv
vendored
Submodule lib/external/libwolv updated: d25459dfa8...7e306b0e0a
@@ -11,7 +11,6 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace llvm {
|
||||
/// This is a llvm local version of __cxa_demangle. Other than the name and
|
||||
@@ -29,10 +28,8 @@ enum : int {
|
||||
demangle_success = 0,
|
||||
};
|
||||
|
||||
/// Returns a non-NULL pointer to a NUL-terminated C style string
|
||||
/// that should be explicitly freed, if successful. Otherwise, may return
|
||||
/// nullptr if mangled_name is not a valid mangling or is nullptr.
|
||||
char *itaniumDemangle(std::string_view mangled_name);
|
||||
char *itaniumDemangle(const char *mangled_name, char *buf, size_t *n,
|
||||
int *status);
|
||||
|
||||
enum MSDemangleFlags {
|
||||
MSDF_None = 0,
|
||||
@@ -49,25 +46,31 @@ enum MSDemangleFlags {
|
||||
/// success, or nullptr on error.
|
||||
/// If n_read is non-null and demangling was successful, it receives how many
|
||||
/// bytes of the input string were consumed.
|
||||
/// buf can point to a *n_buf bytes large buffer where the demangled name is
|
||||
/// stored. If the buffer is too small, it is grown with realloc(). If buf is
|
||||
/// nullptr, then this malloc()s memory for the result.
|
||||
/// *n_buf stores the size of buf on input if buf is non-nullptr, and it
|
||||
/// receives the size of the demangled string on output if n_buf is not nullptr.
|
||||
/// status receives one of the demangle_ enum entries above if it's not nullptr.
|
||||
/// Flags controls various details of the demangled representation.
|
||||
char *microsoftDemangle(std::string_view mangled_name, size_t *n_read,
|
||||
int *status, MSDemangleFlags Flags = MSDF_None);
|
||||
char *microsoftDemangle(const char *mangled_name, size_t *n_read, char *buf,
|
||||
size_t *n_buf, int *status,
|
||||
MSDemangleFlags Flags = MSDF_None);
|
||||
|
||||
// Demangles a Rust v0 mangled symbol.
|
||||
char *rustDemangle(std::string_view MangledName);
|
||||
char *rustDemangle(const char *MangledName);
|
||||
|
||||
// Demangles a D mangled symbol.
|
||||
char *dlangDemangle(std::string_view MangledName);
|
||||
char *dlangDemangle(const char *MangledName);
|
||||
|
||||
/// Attempt to demangle a string using different demangling schemes.
|
||||
/// The function uses heuristics to determine which demangling scheme to use.
|
||||
/// \param MangledName - reference to string to demangle.
|
||||
/// \returns - the demangled string, or a copy of the input string if no
|
||||
/// demangling occurred.
|
||||
std::string demangle(std::string_view MangledName);
|
||||
std::string demangle(const std::string &MangledName);
|
||||
|
||||
bool nonMicrosoftDemangle(std::string_view MangledName, std::string &Result);
|
||||
bool nonMicrosoftDemangle(const char *MangledName, std::string &Result);
|
||||
|
||||
/// "Partial" demangler. This supports demangling a string into an AST
|
||||
/// (typically an intermediate stage in itaniumDemangle) and querying certain
|
||||
@@ -84,7 +87,7 @@ struct ItaniumPartialDemangler {
|
||||
bool partialDemangle(const char *MangledName);
|
||||
|
||||
/// Just print the entire mangled name into Buf. Buf and N behave like the
|
||||
/// second and third parameters to __cxa_demangle.
|
||||
/// second and third parameters to itaniumDemangle.
|
||||
char *finishDemangle(char *Buf, size_t *N) const;
|
||||
|
||||
/// Get the base name of a function. This doesn't include trailing template
|
||||
@@ -13,11 +13,11 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef DEMANGLE_ITANIUMDEMANGLE_H
|
||||
#define DEMANGLE_ITANIUMDEMANGLE_H
|
||||
#ifndef LLVM_DEMANGLE_ITANIUMDEMANGLE_H
|
||||
#define LLVM_DEMANGLE_ITANIUMDEMANGLE_H
|
||||
|
||||
#include "DemangleConfig.h"
|
||||
#include "StringViewExtras.h"
|
||||
#include "StringView.h"
|
||||
#include "Utility.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
@@ -26,9 +26,6 @@
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <new>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
DEMANGLE_NAMESPACE_BEGIN
|
||||
@@ -288,7 +285,7 @@ public:
|
||||
// implementation.
|
||||
virtual void printRight(OutputBuffer &) const {}
|
||||
|
||||
virtual std::string_view getBaseName() const { return {}; }
|
||||
virtual StringView getBaseName() const { return StringView(); }
|
||||
|
||||
// Silence compiler warnings, this dtor will never be called.
|
||||
virtual ~Node() = default;
|
||||
@@ -347,10 +344,10 @@ struct NodeArrayNode : Node {
|
||||
|
||||
class DotSuffix final : public Node {
|
||||
const Node *Prefix;
|
||||
const std::string_view Suffix;
|
||||
const StringView Suffix;
|
||||
|
||||
public:
|
||||
DotSuffix(const Node *Prefix_, std::string_view Suffix_)
|
||||
DotSuffix(const Node *Prefix_, StringView Suffix_)
|
||||
: Node(KDotSuffix), Prefix(Prefix_), Suffix(Suffix_) {}
|
||||
|
||||
template<typename Fn> void match(Fn F) const { F(Prefix, Suffix); }
|
||||
@@ -365,15 +362,15 @@ public:
|
||||
|
||||
class VendorExtQualType final : public Node {
|
||||
const Node *Ty;
|
||||
std::string_view Ext;
|
||||
StringView Ext;
|
||||
const Node *TA;
|
||||
|
||||
public:
|
||||
VendorExtQualType(const Node *Ty_, std::string_view Ext_, const Node *TA_)
|
||||
VendorExtQualType(const Node *Ty_, StringView Ext_, const Node *TA_)
|
||||
: Node(KVendorExtQualType), Ty(Ty_), Ext(Ext_), TA(TA_) {}
|
||||
|
||||
const Node *getTy() const { return Ty; }
|
||||
std::string_view getExt() const { return Ext; }
|
||||
StringView getExt() const { return Ext; }
|
||||
const Node *getTA() const { return TA; }
|
||||
|
||||
template <typename Fn> void match(Fn F) const { F(Ty, Ext, TA); }
|
||||
@@ -464,10 +461,10 @@ public:
|
||||
|
||||
class PostfixQualifiedType final : public Node {
|
||||
const Node *Ty;
|
||||
const std::string_view Postfix;
|
||||
const StringView Postfix;
|
||||
|
||||
public:
|
||||
PostfixQualifiedType(const Node *Ty_, std::string_view Postfix_)
|
||||
PostfixQualifiedType(const Node *Ty_, StringView Postfix_)
|
||||
: Node(KPostfixQualifiedType), Ty(Ty_), Postfix(Postfix_) {}
|
||||
|
||||
template<typename Fn> void match(Fn F) const { F(Ty, Postfix); }
|
||||
@@ -479,15 +476,15 @@ public:
|
||||
};
|
||||
|
||||
class NameType final : public Node {
|
||||
const std::string_view Name;
|
||||
const StringView Name;
|
||||
|
||||
public:
|
||||
NameType(std::string_view Name_) : Node(KNameType), Name(Name_) {}
|
||||
NameType(StringView Name_) : Node(KNameType), Name(Name_) {}
|
||||
|
||||
template<typename Fn> void match(Fn F) const { F(Name); }
|
||||
|
||||
std::string_view getName() const { return Name; }
|
||||
std::string_view getBaseName() const override { return Name; }
|
||||
StringView getName() const { return Name; }
|
||||
StringView getBaseName() const override { return Name; }
|
||||
|
||||
void printLeft(OutputBuffer &OB) const override { OB += Name; }
|
||||
};
|
||||
@@ -513,10 +510,10 @@ public:
|
||||
};
|
||||
|
||||
class ElaboratedTypeSpefType : public Node {
|
||||
std::string_view Kind;
|
||||
StringView Kind;
|
||||
Node *Child;
|
||||
public:
|
||||
ElaboratedTypeSpefType(std::string_view Kind_, Node *Child_)
|
||||
ElaboratedTypeSpefType(StringView Kind_, Node *Child_)
|
||||
: Node(KElaboratedTypeSpefType), Kind(Kind_), Child(Child_) {}
|
||||
|
||||
template<typename Fn> void match(Fn F) const { F(Kind, Child); }
|
||||
@@ -530,17 +527,15 @@ public:
|
||||
|
||||
struct AbiTagAttr : Node {
|
||||
Node *Base;
|
||||
std::string_view Tag;
|
||||
StringView Tag;
|
||||
|
||||
AbiTagAttr(Node *Base_, std::string_view Tag_)
|
||||
: Node(KAbiTagAttr, Base_->RHSComponentCache, Base_->ArrayCache,
|
||||
Base_->FunctionCache),
|
||||
AbiTagAttr(Node* Base_, StringView Tag_)
|
||||
: Node(KAbiTagAttr, Base_->RHSComponentCache,
|
||||
Base_->ArrayCache, Base_->FunctionCache),
|
||||
Base(Base_), Tag(Tag_) {}
|
||||
|
||||
template<typename Fn> void match(Fn F) const { F(Base, Tag); }
|
||||
|
||||
std::string_view getBaseName() const override { return Base->getBaseName(); }
|
||||
|
||||
void printLeft(OutputBuffer &OB) const override {
|
||||
Base->printLeft(OB);
|
||||
OB += "[abi:";
|
||||
@@ -566,12 +561,12 @@ public:
|
||||
|
||||
class ObjCProtoName : public Node {
|
||||
const Node *Ty;
|
||||
std::string_view Protocol;
|
||||
StringView Protocol;
|
||||
|
||||
friend class PointerType;
|
||||
|
||||
public:
|
||||
ObjCProtoName(const Node *Ty_, std::string_view Protocol_)
|
||||
ObjCProtoName(const Node *Ty_, StringView Protocol_)
|
||||
: Node(KObjCProtoName), Ty(Ty_), Protocol(Protocol_) {}
|
||||
|
||||
template<typename Fn> void match(Fn F) const { F(Ty, Protocol); }
|
||||
@@ -948,11 +943,11 @@ public:
|
||||
};
|
||||
|
||||
class SpecialName final : public Node {
|
||||
const std::string_view Special;
|
||||
const StringView Special;
|
||||
const Node *Child;
|
||||
|
||||
public:
|
||||
SpecialName(std::string_view Special_, const Node *Child_)
|
||||
SpecialName(StringView Special_, const Node *Child_)
|
||||
: Node(KSpecialName), Special(Special_), Child(Child_) {}
|
||||
|
||||
template<typename Fn> void match(Fn F) const { F(Special, Child); }
|
||||
@@ -991,7 +986,7 @@ struct NestedName : Node {
|
||||
|
||||
template<typename Fn> void match(Fn F) const { F(Qual, Name); }
|
||||
|
||||
std::string_view getBaseName() const override { return Name->getBaseName(); }
|
||||
StringView getBaseName() const override { return Name->getBaseName(); }
|
||||
|
||||
void printLeft(OutputBuffer &OB) const override {
|
||||
Qual->print(OB);
|
||||
@@ -1031,7 +1026,7 @@ struct ModuleEntity : Node {
|
||||
|
||||
template <typename Fn> void match(Fn F) const { F(Module, Name); }
|
||||
|
||||
std::string_view getBaseName() const override { return Name->getBaseName(); }
|
||||
StringView getBaseName() const override { return Name->getBaseName(); }
|
||||
|
||||
void printLeft(OutputBuffer &OB) const override {
|
||||
Name->print(OB);
|
||||
@@ -1067,7 +1062,7 @@ public:
|
||||
|
||||
template<typename Fn> void match(Fn F) const { F(Qualifier, Name); }
|
||||
|
||||
std::string_view getBaseName() const override { return Name->getBaseName(); }
|
||||
StringView getBaseName() const override { return Name->getBaseName(); }
|
||||
|
||||
void printLeft(OutputBuffer &OB) const override {
|
||||
Qualifier->print(OB);
|
||||
@@ -1489,7 +1484,7 @@ struct NameWithTemplateArgs : Node {
|
||||
|
||||
template<typename Fn> void match(Fn F) const { F(Name, TemplateArgs); }
|
||||
|
||||
std::string_view getBaseName() const override { return Name->getBaseName(); }
|
||||
StringView getBaseName() const override { return Name->getBaseName(); }
|
||||
|
||||
void printLeft(OutputBuffer &OB) const override {
|
||||
Name->print(OB);
|
||||
@@ -1506,7 +1501,7 @@ public:
|
||||
|
||||
template<typename Fn> void match(Fn F) const { F(Child); }
|
||||
|
||||
std::string_view getBaseName() const override { return Child->getBaseName(); }
|
||||
StringView getBaseName() const override { return Child->getBaseName(); }
|
||||
|
||||
void printLeft(OutputBuffer &OB) const override {
|
||||
OB += "::";
|
||||
@@ -1542,20 +1537,20 @@ protected:
|
||||
return unsigned(SSK) >= unsigned(SpecialSubKind::string);
|
||||
}
|
||||
|
||||
std::string_view getBaseName() const override {
|
||||
StringView getBaseName() const override {
|
||||
switch (SSK) {
|
||||
case SpecialSubKind::allocator:
|
||||
return {"allocator"};
|
||||
return StringView("allocator");
|
||||
case SpecialSubKind::basic_string:
|
||||
return {"basic_string"};
|
||||
return StringView("basic_string");
|
||||
case SpecialSubKind::string:
|
||||
return {"basic_string"};
|
||||
return StringView("basic_string");
|
||||
case SpecialSubKind::istream:
|
||||
return {"basic_istream"};
|
||||
return StringView("basic_istream");
|
||||
case SpecialSubKind::ostream:
|
||||
return {"basic_ostream"};
|
||||
return StringView("basic_ostream");
|
||||
case SpecialSubKind::iostream:
|
||||
return {"basic_iostream"};
|
||||
return StringView("basic_iostream");
|
||||
}
|
||||
DEMANGLE_UNREACHABLE;
|
||||
}
|
||||
@@ -1579,12 +1574,12 @@ public:
|
||||
|
||||
template<typename Fn> void match(Fn F) const { F(SSK); }
|
||||
|
||||
std::string_view getBaseName() const override {
|
||||
std::string_view SV = ExpandedSpecialSubstitution::getBaseName();
|
||||
StringView getBaseName() const override {
|
||||
auto SV = ExpandedSpecialSubstitution::getBaseName ();
|
||||
if (isInstantiation()) {
|
||||
// The instantiations are typedefs that drop the "basic_" prefix.
|
||||
assert(llvm::itanium_demangle::starts_with(SV, "basic_"));
|
||||
SV.remove_prefix(sizeof("basic_") - 1);
|
||||
assert(SV.startsWith("basic_"));
|
||||
SV = SV.dropFront(sizeof("basic_") - 1);
|
||||
}
|
||||
return SV;
|
||||
}
|
||||
@@ -1632,11 +1627,10 @@ public:
|
||||
};
|
||||
|
||||
class UnnamedTypeName : public Node {
|
||||
const std::string_view Count;
|
||||
const StringView Count;
|
||||
|
||||
public:
|
||||
UnnamedTypeName(std::string_view Count_)
|
||||
: Node(KUnnamedTypeName), Count(Count_) {}
|
||||
UnnamedTypeName(StringView Count_) : Node(KUnnamedTypeName), Count(Count_) {}
|
||||
|
||||
template<typename Fn> void match(Fn F) const { F(Count); }
|
||||
|
||||
@@ -1650,11 +1644,11 @@ public:
|
||||
class ClosureTypeName : public Node {
|
||||
NodeArray TemplateParams;
|
||||
NodeArray Params;
|
||||
std::string_view Count;
|
||||
StringView Count;
|
||||
|
||||
public:
|
||||
ClosureTypeName(NodeArray TemplateParams_, NodeArray Params_,
|
||||
std::string_view Count_)
|
||||
StringView Count_)
|
||||
: Node(KClosureTypeName), TemplateParams(TemplateParams_),
|
||||
Params(Params_), Count(Count_) {}
|
||||
|
||||
@@ -1701,12 +1695,12 @@ public:
|
||||
|
||||
class BinaryExpr : public Node {
|
||||
const Node *LHS;
|
||||
const std::string_view InfixOperator;
|
||||
const StringView InfixOperator;
|
||||
const Node *RHS;
|
||||
|
||||
public:
|
||||
BinaryExpr(const Node *LHS_, std::string_view InfixOperator_,
|
||||
const Node *RHS_, Prec Prec_)
|
||||
BinaryExpr(const Node *LHS_, StringView InfixOperator_, const Node *RHS_,
|
||||
Prec Prec_)
|
||||
: Node(KBinaryExpr, Prec_), LHS(LHS_), InfixOperator(InfixOperator_),
|
||||
RHS(RHS_) {}
|
||||
|
||||
@@ -1755,10 +1749,10 @@ public:
|
||||
|
||||
class PostfixExpr : public Node {
|
||||
const Node *Child;
|
||||
const std::string_view Operator;
|
||||
const StringView Operator;
|
||||
|
||||
public:
|
||||
PostfixExpr(const Node *Child_, std::string_view Operator_, Prec Prec_)
|
||||
PostfixExpr(const Node *Child_, StringView Operator_, Prec Prec_)
|
||||
: Node(KPostfixExpr, Prec_), Child(Child_), Operator(Operator_) {}
|
||||
|
||||
template <typename Fn> void match(Fn F) const {
|
||||
@@ -1796,12 +1790,11 @@ public:
|
||||
|
||||
class MemberExpr : public Node {
|
||||
const Node *LHS;
|
||||
const std::string_view Kind;
|
||||
const StringView Kind;
|
||||
const Node *RHS;
|
||||
|
||||
public:
|
||||
MemberExpr(const Node *LHS_, std::string_view Kind_, const Node *RHS_,
|
||||
Prec Prec_)
|
||||
MemberExpr(const Node *LHS_, StringView Kind_, const Node *RHS_, Prec Prec_)
|
||||
: Node(KMemberExpr, Prec_), LHS(LHS_), Kind(Kind_), RHS(RHS_) {}
|
||||
|
||||
template <typename Fn> void match(Fn F) const {
|
||||
@@ -1818,14 +1811,13 @@ public:
|
||||
class SubobjectExpr : public Node {
|
||||
const Node *Type;
|
||||
const Node *SubExpr;
|
||||
std::string_view Offset;
|
||||
StringView Offset;
|
||||
NodeArray UnionSelectors;
|
||||
bool OnePastTheEnd;
|
||||
|
||||
public:
|
||||
SubobjectExpr(const Node *Type_, const Node *SubExpr_,
|
||||
std::string_view Offset_, NodeArray UnionSelectors_,
|
||||
bool OnePastTheEnd_)
|
||||
SubobjectExpr(const Node *Type_, const Node *SubExpr_, StringView Offset_,
|
||||
NodeArray UnionSelectors_, bool OnePastTheEnd_)
|
||||
: Node(KSubobjectExpr), Type(Type_), SubExpr(SubExpr_), Offset(Offset_),
|
||||
UnionSelectors(UnionSelectors_), OnePastTheEnd(OnePastTheEnd_) {}
|
||||
|
||||
@@ -1842,7 +1834,7 @@ public:
|
||||
OB += "0";
|
||||
} else if (Offset[0] == 'n') {
|
||||
OB += "-";
|
||||
OB += std::string_view(Offset.data() + 1, Offset.size() - 1);
|
||||
OB += Offset.dropFront();
|
||||
} else {
|
||||
OB += Offset;
|
||||
}
|
||||
@@ -1851,12 +1843,12 @@ public:
|
||||
};
|
||||
|
||||
class EnclosingExpr : public Node {
|
||||
const std::string_view Prefix;
|
||||
const StringView Prefix;
|
||||
const Node *Infix;
|
||||
const std::string_view Postfix;
|
||||
const StringView Postfix;
|
||||
|
||||
public:
|
||||
EnclosingExpr(std::string_view Prefix_, const Node *Infix_,
|
||||
EnclosingExpr(StringView Prefix_, const Node *Infix_,
|
||||
Prec Prec_ = Prec::Primary)
|
||||
: Node(KEnclosingExpr, Prec_), Prefix(Prefix_), Infix(Infix_) {}
|
||||
|
||||
@@ -1875,13 +1867,12 @@ public:
|
||||
|
||||
class CastExpr : public Node {
|
||||
// cast_kind<to>(from)
|
||||
const std::string_view CastKind;
|
||||
const StringView CastKind;
|
||||
const Node *To;
|
||||
const Node *From;
|
||||
|
||||
public:
|
||||
CastExpr(std::string_view CastKind_, const Node *To_, const Node *From_,
|
||||
Prec Prec_)
|
||||
CastExpr(StringView CastKind_, const Node *To_, const Node *From_, Prec Prec_)
|
||||
: Node(KCastExpr, Prec_), CastKind(CastKind_), To(To_), From(From_) {}
|
||||
|
||||
template <typename Fn> void match(Fn F) const {
|
||||
@@ -2004,11 +1995,11 @@ public:
|
||||
};
|
||||
|
||||
class PrefixExpr : public Node {
|
||||
std::string_view Prefix;
|
||||
StringView Prefix;
|
||||
Node *Child;
|
||||
|
||||
public:
|
||||
PrefixExpr(std::string_view Prefix_, Node *Child_, Prec Prec_)
|
||||
PrefixExpr(StringView Prefix_, Node *Child_, Prec Prec_)
|
||||
: Node(KPrefixExpr, Prec_), Prefix(Prefix_), Child(Child_) {}
|
||||
|
||||
template <typename Fn> void match(Fn F) const {
|
||||
@@ -2022,11 +2013,10 @@ public:
|
||||
};
|
||||
|
||||
class FunctionParam : public Node {
|
||||
std::string_view Number;
|
||||
StringView Number;
|
||||
|
||||
public:
|
||||
FunctionParam(std::string_view Number_)
|
||||
: Node(KFunctionParam), Number(Number_) {}
|
||||
FunctionParam(StringView Number_) : Node(KFunctionParam), Number(Number_) {}
|
||||
|
||||
template<typename Fn> void match(Fn F) const { F(Number); }
|
||||
|
||||
@@ -2061,11 +2051,11 @@ public:
|
||||
class PointerToMemberConversionExpr : public Node {
|
||||
const Node *Type;
|
||||
const Node *SubExpr;
|
||||
std::string_view Offset;
|
||||
StringView Offset;
|
||||
|
||||
public:
|
||||
PointerToMemberConversionExpr(const Node *Type_, const Node *SubExpr_,
|
||||
std::string_view Offset_, Prec Prec_)
|
||||
StringView Offset_, Prec Prec_)
|
||||
: Node(KPointerToMemberConversionExpr, Prec_), Type(Type_),
|
||||
SubExpr(SubExpr_), Offset(Offset_) {}
|
||||
|
||||
@@ -2150,11 +2140,11 @@ public:
|
||||
|
||||
class FoldExpr : public Node {
|
||||
const Node *Pack, *Init;
|
||||
std::string_view OperatorName;
|
||||
StringView OperatorName;
|
||||
bool IsLeftFold;
|
||||
|
||||
public:
|
||||
FoldExpr(bool IsLeftFold_, std::string_view OperatorName_, const Node *Pack_,
|
||||
FoldExpr(bool IsLeftFold_, StringView OperatorName_, const Node *Pack_,
|
||||
const Node *Init_)
|
||||
: Node(KFoldExpr), Pack(Pack_), Init(Init_), OperatorName(OperatorName_),
|
||||
IsLeftFold(IsLeftFold_) {}
|
||||
@@ -2218,7 +2208,7 @@ public:
|
||||
template<typename Fn> void match(Fn F) const { F(Value); }
|
||||
|
||||
void printLeft(OutputBuffer &OB) const override {
|
||||
OB += Value ? std::string_view("true") : std::string_view("false");
|
||||
OB += Value ? StringView("true") : StringView("false");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2256,10 +2246,10 @@ public:
|
||||
class EnumLiteral : public Node {
|
||||
// ty(integer)
|
||||
const Node *Ty;
|
||||
std::string_view Integer;
|
||||
StringView Integer;
|
||||
|
||||
public:
|
||||
EnumLiteral(const Node *Ty_, std::string_view Integer_)
|
||||
EnumLiteral(const Node *Ty_, StringView Integer_)
|
||||
: Node(KEnumLiteral), Ty(Ty_), Integer(Integer_) {}
|
||||
|
||||
template<typename Fn> void match(Fn F) const { F(Ty, Integer); }
|
||||
@@ -2270,18 +2260,18 @@ public:
|
||||
OB.printClose();
|
||||
|
||||
if (Integer[0] == 'n')
|
||||
OB << '-' << std::string_view(Integer.data() + 1, Integer.size() - 1);
|
||||
OB << "-" << Integer.dropFront(1);
|
||||
else
|
||||
OB << Integer;
|
||||
}
|
||||
};
|
||||
|
||||
class IntegerLiteral : public Node {
|
||||
std::string_view Type;
|
||||
std::string_view Value;
|
||||
StringView Type;
|
||||
StringView Value;
|
||||
|
||||
public:
|
||||
IntegerLiteral(std::string_view Type_, std::string_view Value_)
|
||||
IntegerLiteral(StringView Type_, StringView Value_)
|
||||
: Node(KIntegerLiteral), Type(Type_), Value(Value_) {}
|
||||
|
||||
template<typename Fn> void match(Fn F) const { F(Type, Value); }
|
||||
@@ -2293,9 +2283,10 @@ public:
|
||||
OB.printClose();
|
||||
}
|
||||
|
||||
if (Value[0] == 'n')
|
||||
OB << '-' << std::string_view(Value.data() + 1, Value.size() - 1);
|
||||
else
|
||||
if (Value[0] == 'n') {
|
||||
OB += '-';
|
||||
OB += Value.dropFront(1);
|
||||
} else
|
||||
OB += Value;
|
||||
|
||||
if (Type.size() <= 3)
|
||||
@@ -2318,26 +2309,29 @@ constexpr Node::Kind getFloatLiteralKind(long double *) {
|
||||
}
|
||||
|
||||
template <class Float> class FloatLiteralImpl : public Node {
|
||||
const std::string_view Contents;
|
||||
const StringView Contents;
|
||||
|
||||
static constexpr Kind KindForClass =
|
||||
float_literal_impl::getFloatLiteralKind((Float *)nullptr);
|
||||
|
||||
public:
|
||||
FloatLiteralImpl(std::string_view Contents_)
|
||||
FloatLiteralImpl(StringView Contents_)
|
||||
: Node(KindForClass), Contents(Contents_) {}
|
||||
|
||||
template<typename Fn> void match(Fn F) const { F(Contents); }
|
||||
|
||||
void printLeft(OutputBuffer &OB) const override {
|
||||
const char *first = Contents.begin();
|
||||
const char *last = Contents.end() + 1;
|
||||
|
||||
const size_t N = FloatData<Float>::mangled_size;
|
||||
if (Contents.size() >= N) {
|
||||
if (static_cast<std::size_t>(last - first) > N) {
|
||||
last = first + N;
|
||||
union {
|
||||
Float value;
|
||||
char buf[sizeof(Float)];
|
||||
};
|
||||
const char *t = Contents.data();
|
||||
const char *last = t + N;
|
||||
const char *t = first;
|
||||
char *e = buf;
|
||||
for (; t != last; ++t, ++e) {
|
||||
unsigned d1 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
|
||||
@@ -2352,7 +2346,7 @@ public:
|
||||
#endif
|
||||
char num[FloatData<Float>::max_demangled_size] = {0};
|
||||
int n = snprintf(num, sizeof(num), FloatData<Float>::spec, value);
|
||||
OB += std::string_view(num, n);
|
||||
OB += StringView(num, num + n);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -2479,9 +2473,8 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
|
||||
return res;
|
||||
}
|
||||
|
||||
bool consumeIf(std::string_view S) {
|
||||
if (llvm::itanium_demangle::starts_with(
|
||||
std::string_view(First, Last - First), S)) {
|
||||
bool consumeIf(StringView S) {
|
||||
if (StringView(First, Last).startsWith(S)) {
|
||||
First += S.size();
|
||||
return true;
|
||||
}
|
||||
@@ -2506,10 +2499,10 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
|
||||
|
||||
size_t numLeft() const { return static_cast<size_t>(Last - First); }
|
||||
|
||||
std::string_view parseNumber(bool AllowNegative = false);
|
||||
StringView parseNumber(bool AllowNegative = false);
|
||||
Qualifiers parseCVQualifiers();
|
||||
bool parsePositiveInteger(size_t *Out);
|
||||
std::string_view parseBareSourceName();
|
||||
StringView parseBareSourceName();
|
||||
|
||||
bool parseSeqId(size_t *Out);
|
||||
Node *parseSubstitution();
|
||||
@@ -2520,9 +2513,9 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
|
||||
|
||||
/// Parse the <expr> production.
|
||||
Node *parseExpr();
|
||||
Node *parsePrefixExpr(std::string_view Kind, Node::Prec Prec);
|
||||
Node *parseBinaryExpr(std::string_view Kind, Node::Prec Prec);
|
||||
Node *parseIntegerLiteral(std::string_view Lit);
|
||||
Node *parsePrefixExpr(StringView Kind, Node::Prec Prec);
|
||||
Node *parseBinaryExpr(StringView Kind, Node::Prec Prec);
|
||||
Node *parseIntegerLiteral(StringView Lit);
|
||||
Node *parseExprPrimary();
|
||||
template <class Float> Node *parseFloatingLiteral();
|
||||
Node *parseFunctionParam();
|
||||
@@ -2630,18 +2623,17 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
|
||||
bool operator!=(const char *Peek) const { return !this->operator==(Peek); }
|
||||
|
||||
public:
|
||||
std::string_view getSymbol() const {
|
||||
std::string_view Res = Name;
|
||||
StringView getSymbol() const {
|
||||
StringView Res = Name;
|
||||
if (Kind < Unnameable) {
|
||||
assert(llvm::itanium_demangle::starts_with(Res, "operator") &&
|
||||
assert(Res.startsWith("operator") &&
|
||||
"operator name does not start with 'operator'");
|
||||
Res.remove_prefix(sizeof("operator") - 1);
|
||||
if (llvm::itanium_demangle::starts_with(Res, ' '))
|
||||
Res.remove_prefix(1);
|
||||
Res = Res.dropFront(sizeof("operator") - 1);
|
||||
Res.consumeFront(' ');
|
||||
}
|
||||
return Res;
|
||||
}
|
||||
std::string_view getName() const { return Name; }
|
||||
StringView getName() const { return Name; }
|
||||
OIKind getKind() const { return Kind; }
|
||||
bool getFlag() const { return Flag; }
|
||||
Node::Prec getPrecedence() const { return Prec; }
|
||||
@@ -2861,7 +2853,7 @@ AbstractManglingParser<Derived, Alloc>::parseUnnamedTypeName(NameState *State) {
|
||||
TemplateParams.clear();
|
||||
|
||||
if (consumeIf("Ut")) {
|
||||
std::string_view Count = parseNumber();
|
||||
StringView Count = parseNumber();
|
||||
if (!consumeIf('_'))
|
||||
return nullptr;
|
||||
return make<UnnamedTypeName>(Count);
|
||||
@@ -2873,7 +2865,7 @@ AbstractManglingParser<Derived, Alloc>::parseUnnamedTypeName(NameState *State) {
|
||||
|
||||
size_t ParamsBegin = Names.size();
|
||||
while (look() == 'T' &&
|
||||
std::string_view("yptn").find(look(1)) != std::string_view::npos) {
|
||||
StringView("yptn").find(look(1)) != StringView::npos) {
|
||||
Node *T = parseTemplateParamDecl();
|
||||
if (!T)
|
||||
return nullptr;
|
||||
@@ -2916,7 +2908,7 @@ AbstractManglingParser<Derived, Alloc>::parseUnnamedTypeName(NameState *State) {
|
||||
}
|
||||
NodeArray Params = popTrailingNodeArray(ParamsBegin);
|
||||
|
||||
std::string_view Count = parseNumber();
|
||||
StringView Count = parseNumber();
|
||||
if (!consumeIf('_'))
|
||||
return nullptr;
|
||||
return make<ClosureTypeName>(TempParams, Params, Count);
|
||||
@@ -2938,9 +2930,9 @@ Node *AbstractManglingParser<Derived, Alloc>::parseSourceName(NameState *) {
|
||||
return nullptr;
|
||||
if (numLeft() < Length || Length == 0)
|
||||
return nullptr;
|
||||
std::string_view Name(First, Length);
|
||||
StringView Name(First, First + Length);
|
||||
First += Length;
|
||||
if (llvm::itanium_demangle::starts_with(Name, "_GLOBAL__N"))
|
||||
if (Name.startsWith("_GLOBAL__N"))
|
||||
return make<NameType>("(anonymous namespace)");
|
||||
return make<NameType>(Name);
|
||||
}
|
||||
@@ -3039,21 +3031,14 @@ AbstractManglingParser<Derived, Alloc>::parseOperatorEncoding() {
|
||||
if (numLeft() < 2)
|
||||
return nullptr;
|
||||
|
||||
// We can't use lower_bound as that can link to symbols in the C++ library,
|
||||
// and this must remain independant of that.
|
||||
size_t lower = 0u, upper = NumOps - 1; // Inclusive bounds.
|
||||
while (upper != lower) {
|
||||
size_t middle = (upper + lower) / 2;
|
||||
if (Ops[middle] < First)
|
||||
lower = middle + 1;
|
||||
else
|
||||
upper = middle;
|
||||
}
|
||||
if (Ops[lower] != First)
|
||||
auto Op = std::lower_bound(
|
||||
&Ops[0], &Ops[NumOps], First,
|
||||
[](const OperatorInfo &Op_, const char *Enc_) { return Op_ < Enc_; });
|
||||
if (Op == &Ops[NumOps] || *Op != First)
|
||||
return nullptr;
|
||||
|
||||
First += 2;
|
||||
return &Ops[lower];
|
||||
return Op;
|
||||
}
|
||||
|
||||
// <operator-name> ::= See parseOperatorEncoding()
|
||||
@@ -3454,7 +3439,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedName(bool Global) {
|
||||
template <typename Derived, typename Alloc>
|
||||
Node *AbstractManglingParser<Derived, Alloc>::parseAbiTags(Node *N) {
|
||||
while (consumeIf('B')) {
|
||||
std::string_view SN = parseBareSourceName();
|
||||
StringView SN = parseBareSourceName();
|
||||
if (SN.empty())
|
||||
return nullptr;
|
||||
N = make<AbiTagAttr>(N, SN);
|
||||
@@ -3466,16 +3451,16 @@ Node *AbstractManglingParser<Derived, Alloc>::parseAbiTags(Node *N) {
|
||||
|
||||
// <number> ::= [n] <non-negative decimal integer>
|
||||
template <typename Alloc, typename Derived>
|
||||
std::string_view
|
||||
StringView
|
||||
AbstractManglingParser<Alloc, Derived>::parseNumber(bool AllowNegative) {
|
||||
const char *Tmp = First;
|
||||
if (AllowNegative)
|
||||
consumeIf('n');
|
||||
if (numLeft() == 0 || !std::isdigit(*First))
|
||||
return std::string_view();
|
||||
return StringView();
|
||||
while (numLeft() != 0 && std::isdigit(*First))
|
||||
++First;
|
||||
return std::string_view(Tmp, First - Tmp);
|
||||
return StringView(Tmp, First);
|
||||
}
|
||||
|
||||
// <positive length number> ::= [0-9]*
|
||||
@@ -3492,11 +3477,11 @@ bool AbstractManglingParser<Alloc, Derived>::parsePositiveInteger(size_t *Out) {
|
||||
}
|
||||
|
||||
template <typename Alloc, typename Derived>
|
||||
std::string_view AbstractManglingParser<Alloc, Derived>::parseBareSourceName() {
|
||||
StringView AbstractManglingParser<Alloc, Derived>::parseBareSourceName() {
|
||||
size_t Int = 0;
|
||||
if (parsePositiveInteger(&Int) || numLeft() < Int)
|
||||
return {};
|
||||
std::string_view R(First, Int);
|
||||
return StringView();
|
||||
StringView R(First, First + Int);
|
||||
First += Int;
|
||||
return R;
|
||||
}
|
||||
@@ -3680,7 +3665,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parsePointerToMemberType() {
|
||||
// ::= Te <name> # dependent elaborated type specifier using 'enum'
|
||||
template <typename Derived, typename Alloc>
|
||||
Node *AbstractManglingParser<Derived, Alloc>::parseClassEnumType() {
|
||||
std::string_view ElabSpef;
|
||||
StringView ElabSpef;
|
||||
if (consumeIf("Ts"))
|
||||
ElabSpef = "struct";
|
||||
else if (consumeIf("Tu"))
|
||||
@@ -3704,18 +3689,17 @@ Node *AbstractManglingParser<Derived, Alloc>::parseClassEnumType() {
|
||||
template <typename Derived, typename Alloc>
|
||||
Node *AbstractManglingParser<Derived, Alloc>::parseQualifiedType() {
|
||||
if (consumeIf('U')) {
|
||||
std::string_view Qual = parseBareSourceName();
|
||||
StringView Qual = parseBareSourceName();
|
||||
if (Qual.empty())
|
||||
return nullptr;
|
||||
|
||||
// extension ::= U <objc-name> <objc-type> # objc-type<identifier>
|
||||
if (llvm::itanium_demangle::starts_with(Qual, "objcproto")) {
|
||||
constexpr size_t Len = sizeof("objcproto") - 1;
|
||||
std::string_view ProtoSourceName(Qual.data() + Len, Qual.size() - Len);
|
||||
std::string_view Proto;
|
||||
if (Qual.startsWith("objcproto")) {
|
||||
StringView ProtoSourceName = Qual.dropFront(std::strlen("objcproto"));
|
||||
StringView Proto;
|
||||
{
|
||||
ScopedOverride<const char *> SaveFirst(First, ProtoSourceName.data()),
|
||||
SaveLast(Last, &*ProtoSourceName.rbegin() + 1);
|
||||
ScopedOverride<const char *> SaveFirst(First, ProtoSourceName.begin()),
|
||||
SaveLast(Last, ProtoSourceName.end());
|
||||
Proto = parseBareSourceName();
|
||||
}
|
||||
if (Proto.empty())
|
||||
@@ -3883,7 +3867,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
|
||||
// <builtin-type> ::= u <source-name> # vendor extended type
|
||||
case 'u': {
|
||||
++First;
|
||||
std::string_view Res = parseBareSourceName();
|
||||
StringView Res = parseBareSourceName();
|
||||
if (Res.empty())
|
||||
return nullptr;
|
||||
// Typically, <builtin-type>s are not considered substitution candidates,
|
||||
@@ -4131,9 +4115,8 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
|
||||
}
|
||||
|
||||
template <typename Derived, typename Alloc>
|
||||
Node *
|
||||
AbstractManglingParser<Derived, Alloc>::parsePrefixExpr(std::string_view Kind,
|
||||
Node::Prec Prec) {
|
||||
Node *AbstractManglingParser<Derived, Alloc>::parsePrefixExpr(StringView Kind,
|
||||
Node::Prec Prec) {
|
||||
Node *E = getDerived().parseExpr();
|
||||
if (E == nullptr)
|
||||
return nullptr;
|
||||
@@ -4141,9 +4124,8 @@ AbstractManglingParser<Derived, Alloc>::parsePrefixExpr(std::string_view Kind,
|
||||
}
|
||||
|
||||
template <typename Derived, typename Alloc>
|
||||
Node *
|
||||
AbstractManglingParser<Derived, Alloc>::parseBinaryExpr(std::string_view Kind,
|
||||
Node::Prec Prec) {
|
||||
Node *AbstractManglingParser<Derived, Alloc>::parseBinaryExpr(StringView Kind,
|
||||
Node::Prec Prec) {
|
||||
Node *LHS = getDerived().parseExpr();
|
||||
if (LHS == nullptr)
|
||||
return nullptr;
|
||||
@@ -4154,9 +4136,9 @@ AbstractManglingParser<Derived, Alloc>::parseBinaryExpr(std::string_view Kind,
|
||||
}
|
||||
|
||||
template <typename Derived, typename Alloc>
|
||||
Node *AbstractManglingParser<Derived, Alloc>::parseIntegerLiteral(
|
||||
std::string_view Lit) {
|
||||
std::string_view Tmp = parseNumber(true);
|
||||
Node *
|
||||
AbstractManglingParser<Derived, Alloc>::parseIntegerLiteral(StringView Lit) {
|
||||
StringView Tmp = parseNumber(true);
|
||||
if (!Tmp.empty() && consumeIf('E'))
|
||||
return make<IntegerLiteral>(Lit, Tmp);
|
||||
return nullptr;
|
||||
@@ -4186,7 +4168,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseFunctionParam() {
|
||||
return make<NameType>("this");
|
||||
if (consumeIf("fp")) {
|
||||
parseCVQualifiers();
|
||||
std::string_view Num = parseNumber();
|
||||
StringView Num = parseNumber();
|
||||
if (!consumeIf('_'))
|
||||
return nullptr;
|
||||
return make<FunctionParam>(Num);
|
||||
@@ -4197,7 +4179,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseFunctionParam() {
|
||||
if (!consumeIf('p'))
|
||||
return nullptr;
|
||||
parseCVQualifiers();
|
||||
std::string_view Num = parseNumber();
|
||||
StringView Num = parseNumber();
|
||||
if (!consumeIf('_'))
|
||||
return nullptr;
|
||||
return make<FunctionParam>(Num);
|
||||
@@ -4351,7 +4333,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExprPrimary() {
|
||||
Node *T = getDerived().parseType();
|
||||
if (T == nullptr)
|
||||
return nullptr;
|
||||
std::string_view N = parseNumber(/*AllowNegative=*/true);
|
||||
StringView N = parseNumber(/*AllowNegative=*/true);
|
||||
if (N.empty())
|
||||
return nullptr;
|
||||
if (!consumeIf('E'))
|
||||
@@ -4474,7 +4456,7 @@ AbstractManglingParser<Derived, Alloc>::parsePointerToMemberConversionExpr(
|
||||
Node *Expr = getDerived().parseExpr();
|
||||
if (!Expr)
|
||||
return nullptr;
|
||||
std::string_view Offset = getDerived().parseNumber(true);
|
||||
StringView Offset = getDerived().parseNumber(true);
|
||||
if (!consumeIf('E'))
|
||||
return nullptr;
|
||||
return make<PointerToMemberConversionExpr>(Ty, Expr, Offset, Prec);
|
||||
@@ -4492,7 +4474,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseSubobjectExpr() {
|
||||
Node *Expr = getDerived().parseExpr();
|
||||
if (!Expr)
|
||||
return nullptr;
|
||||
std::string_view Offset = getDerived().parseNumber(true);
|
||||
StringView Offset = getDerived().parseNumber(true);
|
||||
size_t SelectorsBegin = Names.size();
|
||||
while (consumeIf('_')) {
|
||||
Node *Selector = make<NameType>(parseNumber());
|
||||
@@ -5129,7 +5111,7 @@ template <>
|
||||
struct FloatData<long double>
|
||||
{
|
||||
#if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \
|
||||
defined(__wasm__) || defined(__riscv) || defined(__loongarch__)
|
||||
defined(__wasm__) || defined(__riscv)
|
||||
static const size_t mangled_size = 32;
|
||||
#elif defined(__arm__) || defined(__mips__) || defined(__hexagon__)
|
||||
static const size_t mangled_size = 16;
|
||||
@@ -5151,7 +5133,7 @@ Node *AbstractManglingParser<Alloc, Derived>::parseFloatingLiteral() {
|
||||
const size_t N = FloatData<Float>::mangled_size;
|
||||
if (numLeft() <= N)
|
||||
return nullptr;
|
||||
std::string_view Data(First, N);
|
||||
StringView Data(First, First + N);
|
||||
for (char C : Data)
|
||||
if (!std::isxdigit(C))
|
||||
return nullptr;
|
||||
@@ -5471,8 +5453,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parse() {
|
||||
if (Encoding == nullptr)
|
||||
return nullptr;
|
||||
if (look() == '.') {
|
||||
Encoding =
|
||||
make<DotSuffix>(Encoding, std::string_view(First, Last - First));
|
||||
Encoding = make<DotSuffix>(Encoding, StringView(First, Last));
|
||||
First = Last;
|
||||
}
|
||||
if (numLeft() != 0)
|
||||
@@ -5508,4 +5489,4 @@ struct ManglingParser : AbstractManglingParser<ManglingParser<Alloc>, Alloc> {
|
||||
|
||||
DEMANGLE_NAMESPACE_END
|
||||
|
||||
#endif // DEMANGLE_ITANIUMDEMANGLE_H
|
||||
#endif // LLVM_DEMANGLE_ITANIUMDEMANGLE_H
|
||||
@@ -10,9 +10,8 @@
|
||||
#define LLVM_DEMANGLE_MICROSOFTDEMANGLE_H
|
||||
|
||||
#include "llvm/Demangle/MicrosoftDemangleNodes.h"
|
||||
#include "llvm/Demangle/StringView.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
namespace llvm {
|
||||
@@ -101,7 +100,7 @@ public:
|
||||
if (Head->Used <= Head->Capacity)
|
||||
return new (PP) T(std::forward<Args>(ConstructorArgs)...);
|
||||
|
||||
static_assert(Size < AllocUnit);
|
||||
static_assert(Size < AllocUnit, "");
|
||||
addNode(AllocUnit);
|
||||
Head->Used = Size;
|
||||
return new (Head->Buf) T(std::forward<Args>(ConstructorArgs)...);
|
||||
@@ -143,9 +142,9 @@ public:
|
||||
|
||||
// You are supposed to call parse() first and then check if error is true. If
|
||||
// it is false, call output() to write the formatted name to the given stream.
|
||||
SymbolNode *parse(std::string_view &MangledName);
|
||||
SymbolNode *parse(StringView &MangledName);
|
||||
|
||||
TagTypeNode *parseTagUniqueName(std::string_view &MangledName);
|
||||
TagTypeNode *parseTagUniqueName(StringView &MangledName);
|
||||
|
||||
// True if an error occurred.
|
||||
bool Error = false;
|
||||
@@ -153,112 +152,104 @@ public:
|
||||
void dumpBackReferences();
|
||||
|
||||
private:
|
||||
SymbolNode *demangleEncodedSymbol(std::string_view &MangledName,
|
||||
SymbolNode *demangleEncodedSymbol(StringView &MangledName,
|
||||
QualifiedNameNode *QN);
|
||||
SymbolNode *demangleDeclarator(std::string_view &MangledName);
|
||||
SymbolNode *demangleMD5Name(std::string_view &MangledName);
|
||||
SymbolNode *demangleTypeinfoName(std::string_view &MangledName);
|
||||
SymbolNode *demangleDeclarator(StringView &MangledName);
|
||||
SymbolNode *demangleMD5Name(StringView &MangledName);
|
||||
SymbolNode *demangleTypeinfoName(StringView &MangledName);
|
||||
|
||||
VariableSymbolNode *demangleVariableEncoding(std::string_view &MangledName,
|
||||
VariableSymbolNode *demangleVariableEncoding(StringView &MangledName,
|
||||
StorageClass SC);
|
||||
FunctionSymbolNode *demangleFunctionEncoding(std::string_view &MangledName);
|
||||
FunctionSymbolNode *demangleFunctionEncoding(StringView &MangledName);
|
||||
|
||||
Qualifiers demanglePointerExtQualifiers(std::string_view &MangledName);
|
||||
Qualifiers demanglePointerExtQualifiers(StringView &MangledName);
|
||||
|
||||
// Parser functions. This is a recursive-descent parser.
|
||||
TypeNode *demangleType(std::string_view &MangledName,
|
||||
QualifierMangleMode QMM);
|
||||
PrimitiveTypeNode *demanglePrimitiveType(std::string_view &MangledName);
|
||||
CustomTypeNode *demangleCustomType(std::string_view &MangledName);
|
||||
TagTypeNode *demangleClassType(std::string_view &MangledName);
|
||||
PointerTypeNode *demanglePointerType(std::string_view &MangledName);
|
||||
PointerTypeNode *demangleMemberPointerType(std::string_view &MangledName);
|
||||
FunctionSignatureNode *demangleFunctionType(std::string_view &MangledName,
|
||||
TypeNode *demangleType(StringView &MangledName, QualifierMangleMode QMM);
|
||||
PrimitiveTypeNode *demanglePrimitiveType(StringView &MangledName);
|
||||
CustomTypeNode *demangleCustomType(StringView &MangledName);
|
||||
TagTypeNode *demangleClassType(StringView &MangledName);
|
||||
PointerTypeNode *demanglePointerType(StringView &MangledName);
|
||||
PointerTypeNode *demangleMemberPointerType(StringView &MangledName);
|
||||
FunctionSignatureNode *demangleFunctionType(StringView &MangledName,
|
||||
bool HasThisQuals);
|
||||
|
||||
ArrayTypeNode *demangleArrayType(std::string_view &MangledName);
|
||||
ArrayTypeNode *demangleArrayType(StringView &MangledName);
|
||||
|
||||
NodeArrayNode *demangleFunctionParameterList(std::string_view &MangledName,
|
||||
NodeArrayNode *demangleFunctionParameterList(StringView &MangledName,
|
||||
bool &IsVariadic);
|
||||
NodeArrayNode *demangleTemplateParameterList(std::string_view &MangledName);
|
||||
NodeArrayNode *demangleTemplateParameterList(StringView &MangledName);
|
||||
|
||||
std::pair<uint64_t, bool> demangleNumber(std::string_view &MangledName);
|
||||
uint64_t demangleUnsigned(std::string_view &MangledName);
|
||||
int64_t demangleSigned(std::string_view &MangledName);
|
||||
std::pair<uint64_t, bool> demangleNumber(StringView &MangledName);
|
||||
uint64_t demangleUnsigned(StringView &MangledName);
|
||||
int64_t demangleSigned(StringView &MangledName);
|
||||
|
||||
void memorizeString(std::string_view s);
|
||||
void memorizeString(StringView s);
|
||||
void memorizeIdentifier(IdentifierNode *Identifier);
|
||||
|
||||
/// Allocate a copy of \p Borrowed into memory that we own.
|
||||
std::string_view copyString(std::string_view Borrowed);
|
||||
StringView copyString(StringView Borrowed);
|
||||
|
||||
QualifiedNameNode *
|
||||
demangleFullyQualifiedTypeName(std::string_view &MangledName);
|
||||
QualifiedNameNode *
|
||||
demangleFullyQualifiedSymbolName(std::string_view &MangledName);
|
||||
QualifiedNameNode *demangleFullyQualifiedTypeName(StringView &MangledName);
|
||||
QualifiedNameNode *demangleFullyQualifiedSymbolName(StringView &MangledName);
|
||||
|
||||
IdentifierNode *demangleUnqualifiedTypeName(std::string_view &MangledName,
|
||||
IdentifierNode *demangleUnqualifiedTypeName(StringView &MangledName,
|
||||
bool Memorize);
|
||||
IdentifierNode *demangleUnqualifiedSymbolName(std::string_view &MangledName,
|
||||
IdentifierNode *demangleUnqualifiedSymbolName(StringView &MangledName,
|
||||
NameBackrefBehavior NBB);
|
||||
|
||||
QualifiedNameNode *demangleNameScopeChain(std::string_view &MangledName,
|
||||
QualifiedNameNode *demangleNameScopeChain(StringView &MangledName,
|
||||
IdentifierNode *UnqualifiedName);
|
||||
IdentifierNode *demangleNameScopePiece(std::string_view &MangledName);
|
||||
IdentifierNode *demangleNameScopePiece(StringView &MangledName);
|
||||
|
||||
NamedIdentifierNode *demangleBackRefName(std::string_view &MangledName);
|
||||
IdentifierNode *
|
||||
demangleTemplateInstantiationName(std::string_view &MangledName,
|
||||
NameBackrefBehavior NBB);
|
||||
NamedIdentifierNode *demangleBackRefName(StringView &MangledName);
|
||||
IdentifierNode *demangleTemplateInstantiationName(StringView &MangledName,
|
||||
NameBackrefBehavior NBB);
|
||||
IntrinsicFunctionKind
|
||||
translateIntrinsicFunctionCode(char CH, FunctionIdentifierCodeGroup Group);
|
||||
IdentifierNode *demangleFunctionIdentifierCode(std::string_view &MangledName);
|
||||
IdentifierNode *demangleFunctionIdentifierCode(StringView &MangledName);
|
||||
IdentifierNode *
|
||||
demangleFunctionIdentifierCode(std::string_view &MangledName,
|
||||
demangleFunctionIdentifierCode(StringView &MangledName,
|
||||
FunctionIdentifierCodeGroup Group);
|
||||
StructorIdentifierNode *
|
||||
demangleStructorIdentifier(std::string_view &MangledName, bool IsDestructor);
|
||||
StructorIdentifierNode *demangleStructorIdentifier(StringView &MangledName,
|
||||
bool IsDestructor);
|
||||
ConversionOperatorIdentifierNode *
|
||||
demangleConversionOperatorIdentifier(std::string_view &MangledName);
|
||||
demangleConversionOperatorIdentifier(StringView &MangledName);
|
||||
LiteralOperatorIdentifierNode *
|
||||
demangleLiteralOperatorIdentifier(std::string_view &MangledName);
|
||||
demangleLiteralOperatorIdentifier(StringView &MangledName);
|
||||
|
||||
SymbolNode *demangleSpecialIntrinsic(std::string_view &MangledName);
|
||||
SymbolNode *demangleSpecialIntrinsic(StringView &MangledName);
|
||||
SpecialTableSymbolNode *
|
||||
demangleSpecialTableSymbolNode(std::string_view &MangledName,
|
||||
demangleSpecialTableSymbolNode(StringView &MangledName,
|
||||
SpecialIntrinsicKind SIK);
|
||||
LocalStaticGuardVariableNode *
|
||||
demangleLocalStaticGuard(std::string_view &MangledName, bool IsThread);
|
||||
demangleLocalStaticGuard(StringView &MangledName, bool IsThread);
|
||||
VariableSymbolNode *demangleUntypedVariable(ArenaAllocator &Arena,
|
||||
std::string_view &MangledName,
|
||||
std::string_view VariableName);
|
||||
StringView &MangledName,
|
||||
StringView VariableName);
|
||||
VariableSymbolNode *
|
||||
demangleRttiBaseClassDescriptorNode(ArenaAllocator &Arena,
|
||||
std::string_view &MangledName);
|
||||
FunctionSymbolNode *demangleInitFiniStub(std::string_view &MangledName,
|
||||
StringView &MangledName);
|
||||
FunctionSymbolNode *demangleInitFiniStub(StringView &MangledName,
|
||||
bool IsDestructor);
|
||||
|
||||
NamedIdentifierNode *demangleSimpleName(std::string_view &MangledName,
|
||||
NamedIdentifierNode *demangleSimpleName(StringView &MangledName,
|
||||
bool Memorize);
|
||||
NamedIdentifierNode *
|
||||
demangleAnonymousNamespaceName(std::string_view &MangledName);
|
||||
NamedIdentifierNode *
|
||||
demangleLocallyScopedNamePiece(std::string_view &MangledName);
|
||||
EncodedStringLiteralNode *
|
||||
demangleStringLiteral(std::string_view &MangledName);
|
||||
FunctionSymbolNode *demangleVcallThunkNode(std::string_view &MangledName);
|
||||
NamedIdentifierNode *demangleAnonymousNamespaceName(StringView &MangledName);
|
||||
NamedIdentifierNode *demangleLocallyScopedNamePiece(StringView &MangledName);
|
||||
EncodedStringLiteralNode *demangleStringLiteral(StringView &MangledName);
|
||||
FunctionSymbolNode *demangleVcallThunkNode(StringView &MangledName);
|
||||
|
||||
std::string_view demangleSimpleString(std::string_view &MangledName,
|
||||
bool Memorize);
|
||||
StringView demangleSimpleString(StringView &MangledName, bool Memorize);
|
||||
|
||||
FuncClass demangleFunctionClass(std::string_view &MangledName);
|
||||
CallingConv demangleCallingConvention(std::string_view &MangledName);
|
||||
StorageClass demangleVariableStorageClass(std::string_view &MangledName);
|
||||
bool demangleThrowSpecification(std::string_view &MangledName);
|
||||
wchar_t demangleWcharLiteral(std::string_view &MangledName);
|
||||
uint8_t demangleCharLiteral(std::string_view &MangledName);
|
||||
FuncClass demangleFunctionClass(StringView &MangledName);
|
||||
CallingConv demangleCallingConvention(StringView &MangledName);
|
||||
StorageClass demangleVariableStorageClass(StringView &MangledName);
|
||||
bool demangleThrowSpecification(StringView &MangledName);
|
||||
wchar_t demangleWcharLiteral(StringView &MangledName);
|
||||
uint8_t demangleCharLiteral(StringView &MangledName);
|
||||
|
||||
std::pair<Qualifiers, bool> demangleQualifiers(std::string_view &MangledName);
|
||||
std::pair<Qualifiers, bool> demangleQualifiers(StringView &MangledName);
|
||||
|
||||
// Memory allocator.
|
||||
ArenaAllocator Arena;
|
||||
@@ -13,10 +13,10 @@
|
||||
#ifndef LLVM_DEMANGLE_MICROSOFTDEMANGLENODES_H
|
||||
#define LLVM_DEMANGLE_MICROSOFTDEMANGLENODES_H
|
||||
|
||||
#include "llvm/Demangle/StringView.h"
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace llvm {
|
||||
namespace itanium_demangle {
|
||||
@@ -25,6 +25,7 @@ class OutputBuffer;
|
||||
}
|
||||
|
||||
using llvm::itanium_demangle::OutputBuffer;
|
||||
using llvm::itanium_demangle::StringView;
|
||||
|
||||
namespace llvm {
|
||||
namespace ms_demangle {
|
||||
@@ -383,7 +384,7 @@ struct NamedIdentifierNode : public IdentifierNode {
|
||||
|
||||
void output(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
std::string_view Name;
|
||||
StringView Name;
|
||||
};
|
||||
|
||||
struct IntrinsicFunctionIdentifierNode : public IdentifierNode {
|
||||
@@ -402,7 +403,7 @@ struct LiteralOperatorIdentifierNode : public IdentifierNode {
|
||||
|
||||
void output(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
std::string_view Name;
|
||||
StringView Name;
|
||||
};
|
||||
|
||||
struct LocalStaticGuardIdentifierNode : public IdentifierNode {
|
||||
@@ -515,8 +516,7 @@ struct NodeArrayNode : public Node {
|
||||
|
||||
void output(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
void output(OutputBuffer &OB, OutputFlags Flags,
|
||||
std::string_view Separator) const;
|
||||
void output(OutputBuffer &OB, OutputFlags Flags, StringView Separator) const;
|
||||
|
||||
Node **Nodes = nullptr;
|
||||
size_t Count = 0;
|
||||
@@ -601,7 +601,7 @@ struct EncodedStringLiteralNode : public SymbolNode {
|
||||
|
||||
void output(OutputBuffer &OB, OutputFlags Flags) const override;
|
||||
|
||||
std::string_view DecodedString;
|
||||
StringView DecodedString;
|
||||
bool IsTruncated = false;
|
||||
CharKind Char = CharKind::Char;
|
||||
};
|
||||
122
lib/external/llvm-demangle/include/llvm/Demangle/StringView.h
vendored
Normal file
122
lib/external/llvm-demangle/include/llvm/Demangle/StringView.h
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
//===--- StringView.h ----------------*- mode:c++;eval:(read-only-mode) -*-===//
|
||||
// Do not edit! See README.txt.
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// FIXME: Use std::string_view instead when we support C++17.
|
||||
// There are two copies of this file in the source tree. The one under
|
||||
// libcxxabi is the original and the one under llvm is the copy. Use
|
||||
// cp-to-llvm.sh to update the copy. See README.txt for more details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_DEMANGLE_STRINGVIEW_H
|
||||
#define LLVM_DEMANGLE_STRINGVIEW_H
|
||||
|
||||
#include "DemangleConfig.h"
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
DEMANGLE_NAMESPACE_BEGIN
|
||||
|
||||
class StringView {
|
||||
const char *First;
|
||||
const char *Last;
|
||||
|
||||
public:
|
||||
static const size_t npos = ~size_t(0);
|
||||
|
||||
template <size_t N>
|
||||
StringView(const char (&Str)[N]) : First(Str), Last(Str + N - 1) {}
|
||||
StringView(const char *First_, const char *Last_)
|
||||
: First(First_), Last(Last_) {}
|
||||
StringView(const char *First_, size_t Len)
|
||||
: First(First_), Last(First_ + Len) {}
|
||||
StringView(const char *Str) : First(Str), Last(Str + std::strlen(Str)) {}
|
||||
StringView() : First(nullptr), Last(nullptr) {}
|
||||
|
||||
StringView substr(size_t Pos, size_t Len = npos) const {
|
||||
assert(Pos <= size());
|
||||
if (Len > size() - Pos)
|
||||
Len = size() - Pos;
|
||||
return StringView(begin() + Pos, Len);
|
||||
}
|
||||
|
||||
size_t find(char C, size_t From = 0) const {
|
||||
// Avoid calling memchr with nullptr.
|
||||
if (From < size()) {
|
||||
// Just forward to memchr, which is faster than a hand-rolled loop.
|
||||
if (const void *P = ::memchr(First + From, C, size() - From))
|
||||
return size_t(static_cast<const char *>(P) - First);
|
||||
}
|
||||
return npos;
|
||||
}
|
||||
|
||||
StringView dropFront(size_t N = 1) const {
|
||||
if (N >= size())
|
||||
N = size();
|
||||
return StringView(First + N, Last);
|
||||
}
|
||||
|
||||
StringView dropBack(size_t N = 1) const {
|
||||
if (N >= size())
|
||||
N = size();
|
||||
return StringView(First, Last - N);
|
||||
}
|
||||
|
||||
char front() const {
|
||||
assert(!empty());
|
||||
return *begin();
|
||||
}
|
||||
|
||||
char back() const {
|
||||
assert(!empty());
|
||||
return *(end() - 1);
|
||||
}
|
||||
|
||||
char popFront() {
|
||||
assert(!empty());
|
||||
return *First++;
|
||||
}
|
||||
|
||||
bool consumeFront(char C) {
|
||||
if (!startsWith(C))
|
||||
return false;
|
||||
*this = dropFront(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool consumeFront(StringView S) {
|
||||
if (!startsWith(S))
|
||||
return false;
|
||||
*this = dropFront(S.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool startsWith(char C) const { return !empty() && *begin() == C; }
|
||||
|
||||
bool startsWith(StringView Str) const {
|
||||
if (Str.size() > size())
|
||||
return false;
|
||||
return std::strncmp(Str.begin(), begin(), Str.size()) == 0;
|
||||
}
|
||||
|
||||
const char &operator[](size_t Idx) const { return *(begin() + Idx); }
|
||||
|
||||
const char *begin() const { return First; }
|
||||
const char *end() const { return Last; }
|
||||
size_t size() const { return static_cast<size_t>(Last - First); }
|
||||
bool empty() const { return First == Last; }
|
||||
};
|
||||
|
||||
inline bool operator==(const StringView &LHS, const StringView &RHS) {
|
||||
return LHS.size() == RHS.size() &&
|
||||
std::strncmp(LHS.begin(), RHS.begin(), LHS.size()) == 0;
|
||||
}
|
||||
|
||||
DEMANGLE_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
@@ -13,19 +13,16 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef DEMANGLE_UTILITY_H
|
||||
#define DEMANGLE_UTILITY_H
|
||||
|
||||
#include "DemangleConfig.h"
|
||||
#ifndef LLVM_DEMANGLE_UTILITY_H
|
||||
#define LLVM_DEMANGLE_UTILITY_H
|
||||
|
||||
#include "StringView.h"
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <exception>
|
||||
#include <limits>
|
||||
#include <string_view>
|
||||
|
||||
DEMANGLE_NAMESPACE_BEGIN
|
||||
|
||||
@@ -67,22 +64,23 @@ class OutputBuffer {
|
||||
if (isNeg)
|
||||
*--TempPtr = '-';
|
||||
|
||||
return operator+=(
|
||||
std::string_view(TempPtr, Temp.data() + Temp.size() - TempPtr));
|
||||
return operator+=(StringView(TempPtr, Temp.data() + Temp.size()));
|
||||
}
|
||||
|
||||
public:
|
||||
OutputBuffer(char *StartBuf, size_t Size)
|
||||
: Buffer(StartBuf), BufferCapacity(Size) {}
|
||||
OutputBuffer(char *StartBuf, size_t *SizePtr)
|
||||
: OutputBuffer(StartBuf, StartBuf ? *SizePtr : 0) {}
|
||||
: Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {}
|
||||
OutputBuffer() = default;
|
||||
// Non-copyable
|
||||
OutputBuffer(const OutputBuffer &) = delete;
|
||||
OutputBuffer &operator=(const OutputBuffer &) = delete;
|
||||
|
||||
operator std::string_view() const {
|
||||
return std::string_view(Buffer, CurrentPosition);
|
||||
operator StringView() const { return StringView(Buffer, CurrentPosition); }
|
||||
|
||||
void reset(char *Buffer_, size_t BufferCapacity_) {
|
||||
CurrentPosition = 0;
|
||||
Buffer = Buffer_;
|
||||
BufferCapacity = BufferCapacity_;
|
||||
}
|
||||
|
||||
/// If a ParameterPackExpansion (or similar type) is encountered, the offset
|
||||
@@ -105,10 +103,10 @@ public:
|
||||
*this += Close;
|
||||
}
|
||||
|
||||
OutputBuffer &operator+=(std::string_view R) {
|
||||
OutputBuffer &operator+=(StringView R) {
|
||||
if (size_t Size = R.size()) {
|
||||
grow(Size);
|
||||
std::memcpy(Buffer + CurrentPosition, &*R.begin(), Size);
|
||||
std::memcpy(Buffer + CurrentPosition, R.begin(), Size);
|
||||
CurrentPosition += Size;
|
||||
}
|
||||
return *this;
|
||||
@@ -120,18 +118,18 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputBuffer &prepend(std::string_view R) {
|
||||
OutputBuffer &prepend(StringView R) {
|
||||
size_t Size = R.size();
|
||||
|
||||
grow(Size);
|
||||
std::memmove(Buffer + Size, Buffer, CurrentPosition);
|
||||
std::memcpy(Buffer, &*R.begin(), Size);
|
||||
std::memcpy(Buffer, R.begin(), Size);
|
||||
CurrentPosition += Size;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputBuffer &operator<<(std::string_view R) { return (*this += R); }
|
||||
OutputBuffer &operator<<(StringView R) { return (*this += R); }
|
||||
|
||||
OutputBuffer &operator<<(char C) { return (*this += C); }
|
||||
|
||||
@@ -200,6 +198,21 @@ public:
|
||||
ScopedOverride &operator=(const ScopedOverride &) = delete;
|
||||
};
|
||||
|
||||
inline bool initializeOutputBuffer(char *Buf, size_t *N, OutputBuffer &OB,
|
||||
size_t InitSize) {
|
||||
size_t BufferSize;
|
||||
if (Buf == nullptr) {
|
||||
Buf = static_cast<char *>(std::malloc(InitSize));
|
||||
if (Buf == nullptr)
|
||||
return false;
|
||||
BufferSize = InitSize;
|
||||
} else
|
||||
BufferSize = *N;
|
||||
|
||||
OB.reset(Buf, BufferSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
DEMANGLE_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
@@ -14,17 +14,16 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Demangle/Demangle.h"
|
||||
#include "llvm/Demangle/StringViewExtras.h"
|
||||
#include "llvm/Demangle/StringView.h"
|
||||
#include "llvm/Demangle/Utility.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <string_view>
|
||||
|
||||
using namespace llvm;
|
||||
using llvm::itanium_demangle::OutputBuffer;
|
||||
using llvm::itanium_demangle::starts_with;
|
||||
using llvm::itanium_demangle::StringView;
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -33,7 +32,7 @@ struct Demangler {
|
||||
/// Initialize the information structure we use to pass around information.
|
||||
///
|
||||
/// \param Mangled String to demangle.
|
||||
Demangler(std::string_view Mangled);
|
||||
Demangler(const char *Mangled);
|
||||
|
||||
/// Extract and demangle the mangled symbol and append it to the output
|
||||
/// string.
|
||||
@@ -53,42 +52,46 @@ private:
|
||||
/// \param Demangled output buffer to write the demangled name.
|
||||
/// \param Mangled mangled symbol to be demangled.
|
||||
///
|
||||
/// \return The remaining string on success or nullptr on failure.
|
||||
///
|
||||
/// \see https://dlang.org/spec/abi.html#name_mangling .
|
||||
/// \see https://dlang.org/spec/abi.html#MangledName .
|
||||
void parseMangle(OutputBuffer *Demangled, std::string_view &Mangled);
|
||||
const char *parseMangle(OutputBuffer *Demangled, const char *Mangled);
|
||||
|
||||
/// Extract the number from a given string.
|
||||
///
|
||||
/// \param Mangled string to extract the number.
|
||||
/// \param Ret assigned result value.
|
||||
///
|
||||
/// \note Ret larger than UINT_MAX is considered a failure.
|
||||
/// \return The remaining string on success or nullptr on failure.
|
||||
///
|
||||
/// \note A result larger than UINT_MAX is considered a failure.
|
||||
///
|
||||
/// \see https://dlang.org/spec/abi.html#Number .
|
||||
void decodeNumber(std::string_view &Mangled, unsigned long &Ret);
|
||||
const char *decodeNumber(const char *Mangled, unsigned long &Ret);
|
||||
|
||||
/// Extract the back reference position from a given string.
|
||||
///
|
||||
/// \param Mangled string to extract the back reference position.
|
||||
/// \param Ret assigned result value.
|
||||
///
|
||||
/// \return true on success, false on error.
|
||||
/// \return the remaining string on success or nullptr on failure.
|
||||
///
|
||||
/// \note Ret is always >= 0 on success, and unspecified on failure
|
||||
///
|
||||
/// \see https://dlang.org/spec/abi.html#back_ref .
|
||||
/// \see https://dlang.org/spec/abi.html#NumberBackRef .
|
||||
bool decodeBackrefPos(std::string_view &Mangled, long &Ret);
|
||||
const char *decodeBackrefPos(const char *Mangled, long &Ret);
|
||||
|
||||
/// Extract the symbol pointed by the back reference form a given string.
|
||||
///
|
||||
/// \param Mangled string to extract the back reference position.
|
||||
/// \param Ret assigned result value.
|
||||
///
|
||||
/// \return true on success, false on error.
|
||||
/// \return the remaining string on success or nullptr on failure.
|
||||
///
|
||||
/// \see https://dlang.org/spec/abi.html#back_ref .
|
||||
bool decodeBackref(std::string_view &Mangled, std::string_view &Ret);
|
||||
const char *decodeBackref(const char *Mangled, const char *&Ret);
|
||||
|
||||
/// Extract and demangle backreferenced symbol from a given mangled symbol
|
||||
/// and append it to the output string.
|
||||
@@ -96,18 +99,22 @@ private:
|
||||
/// \param Demangled output buffer to write the demangled name.
|
||||
/// \param Mangled mangled symbol to be demangled.
|
||||
///
|
||||
/// \return the remaining string on success or nullptr on failure.
|
||||
///
|
||||
/// \see https://dlang.org/spec/abi.html#back_ref .
|
||||
/// \see https://dlang.org/spec/abi.html#IdentifierBackRef .
|
||||
void parseSymbolBackref(OutputBuffer *Demangled, std::string_view &Mangled);
|
||||
const char *parseSymbolBackref(OutputBuffer *Demangled, const char *Mangled);
|
||||
|
||||
/// Extract and demangle backreferenced type from a given mangled symbol
|
||||
/// and append it to the output string.
|
||||
///
|
||||
/// \param Mangled mangled symbol to be demangled.
|
||||
///
|
||||
/// \return the remaining string on success or nullptr on failure.
|
||||
///
|
||||
/// \see https://dlang.org/spec/abi.html#back_ref .
|
||||
/// \see https://dlang.org/spec/abi.html#TypeBackRef .
|
||||
void parseTypeBackref(std::string_view &Mangled);
|
||||
const char *parseTypeBackref(const char *Mangled);
|
||||
|
||||
/// Check whether it is the beginning of a symbol name.
|
||||
///
|
||||
@@ -116,7 +123,7 @@ private:
|
||||
/// \return true on success, false otherwise.
|
||||
///
|
||||
/// \see https://dlang.org/spec/abi.html#SymbolName .
|
||||
bool isSymbolName(std::string_view Mangled);
|
||||
bool isSymbolName(const char *Mangled);
|
||||
|
||||
/// Extract and demangle an identifier from a given mangled symbol append it
|
||||
/// to the output string.
|
||||
@@ -124,8 +131,10 @@ private:
|
||||
/// \param Demangled Output buffer to write the demangled name.
|
||||
/// \param Mangled Mangled symbol to be demangled.
|
||||
///
|
||||
/// \return The remaining string on success or nullptr on failure.
|
||||
///
|
||||
/// \see https://dlang.org/spec/abi.html#SymbolName .
|
||||
void parseIdentifier(OutputBuffer *Demangled, std::string_view &Mangled);
|
||||
const char *parseIdentifier(OutputBuffer *Demangled, const char *Mangled);
|
||||
|
||||
/// Extract and demangle the plain identifier from a given mangled symbol and
|
||||
/// prepend/append it to the output string, with a special treatment for some
|
||||
@@ -135,9 +144,11 @@ private:
|
||||
/// \param Mangled Mangled symbol to be demangled.
|
||||
/// \param Len Length of the mangled symbol name.
|
||||
///
|
||||
/// \return The remaining string on success or nullptr on failure.
|
||||
///
|
||||
/// \see https://dlang.org/spec/abi.html#LName .
|
||||
void parseLName(OutputBuffer *Demangled, std::string_view &Mangled,
|
||||
unsigned long Len);
|
||||
const char *parseLName(OutputBuffer *Demangled, const char *Mangled,
|
||||
unsigned long Len);
|
||||
|
||||
/// Extract and demangle the qualified symbol from a given mangled symbol
|
||||
/// append it to the output string.
|
||||
@@ -145,38 +156,33 @@ private:
|
||||
/// \param Demangled Output buffer to write the demangled name.
|
||||
/// \param Mangled Mangled symbol to be demangled.
|
||||
///
|
||||
/// \return The remaining string on success or nullptr on failure.
|
||||
///
|
||||
/// \see https://dlang.org/spec/abi.html#QualifiedName .
|
||||
void parseQualified(OutputBuffer *Demangled, std::string_view &Mangled);
|
||||
const char *parseQualified(OutputBuffer *Demangled, const char *Mangled);
|
||||
|
||||
/// Extract and demangle a type from a given mangled symbol append it to
|
||||
/// the output string.
|
||||
///
|
||||
/// \param Mangled mangled symbol to be demangled.
|
||||
///
|
||||
/// \return true on success, false on error.
|
||||
/// \return the remaining string on success or nullptr on failure.
|
||||
///
|
||||
/// \see https://dlang.org/spec/abi.html#Type .
|
||||
bool parseType(std::string_view &Mangled);
|
||||
const char *parseType(const char *Mangled);
|
||||
|
||||
/// An immutable view of the string we are demangling.
|
||||
const std::string_view Str;
|
||||
/// The string we are demangling.
|
||||
const char *Str;
|
||||
/// The index of the last back reference.
|
||||
int LastBackref;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
void Demangler::decodeNumber(std::string_view &Mangled, unsigned long &Ret) {
|
||||
// Clear Mangled if trying to extract something that isn't a digit.
|
||||
if (Mangled.empty()) {
|
||||
Mangled = {};
|
||||
return;
|
||||
}
|
||||
|
||||
if (!std::isdigit(Mangled.front())) {
|
||||
Mangled = {};
|
||||
return;
|
||||
}
|
||||
const char *Demangler::decodeNumber(const char *Mangled, unsigned long &Ret) {
|
||||
// Return nullptr if trying to extract something that isn't a digit.
|
||||
if (Mangled == nullptr || !std::isdigit(*Mangled))
|
||||
return nullptr;
|
||||
|
||||
unsigned long Val = 0;
|
||||
|
||||
@@ -184,29 +190,25 @@ void Demangler::decodeNumber(std::string_view &Mangled, unsigned long &Ret) {
|
||||
unsigned long Digit = Mangled[0] - '0';
|
||||
|
||||
// Check for overflow.
|
||||
if (Val > (std::numeric_limits<unsigned int>::max() - Digit) / 10) {
|
||||
Mangled = {};
|
||||
return;
|
||||
}
|
||||
if (Val > (std::numeric_limits<unsigned int>::max() - Digit) / 10)
|
||||
return nullptr;
|
||||
|
||||
Val = Val * 10 + Digit;
|
||||
Mangled.remove_prefix(1);
|
||||
} while (!Mangled.empty() && std::isdigit(Mangled.front()));
|
||||
++Mangled;
|
||||
} while (std::isdigit(*Mangled));
|
||||
|
||||
if (Mangled.empty()) {
|
||||
Mangled = {};
|
||||
return;
|
||||
}
|
||||
if (*Mangled == '\0')
|
||||
return nullptr;
|
||||
|
||||
Ret = Val;
|
||||
return Mangled;
|
||||
}
|
||||
|
||||
bool Demangler::decodeBackrefPos(std::string_view &Mangled, long &Ret) {
|
||||
const char *Demangler::decodeBackrefPos(const char *Mangled, long &Ret) {
|
||||
// Return nullptr if trying to extract something that isn't a digit
|
||||
if (Mangled.empty()) {
|
||||
Mangled = {};
|
||||
return false;
|
||||
}
|
||||
if (Mangled == nullptr || !std::isalpha(*Mangled))
|
||||
return nullptr;
|
||||
|
||||
// Any identifier or non-basic type that has been emitted to the mangled
|
||||
// symbol before will not be emitted again, but is referenced by a special
|
||||
// sequence encoding the relative position of the original occurrence in the
|
||||
@@ -219,7 +221,7 @@ bool Demangler::decodeBackrefPos(std::string_view &Mangled, long &Ret) {
|
||||
// ^
|
||||
unsigned long Val = 0;
|
||||
|
||||
while (!Mangled.empty() && std::isalpha(Mangled.front())) {
|
||||
while (std::isalpha(*Mangled)) {
|
||||
// Check for overflow
|
||||
if (Val > (std::numeric_limits<unsigned long>::max() - 25) / 26)
|
||||
break;
|
||||
@@ -231,133 +233,116 @@ bool Demangler::decodeBackrefPos(std::string_view &Mangled, long &Ret) {
|
||||
if ((long)Val <= 0)
|
||||
break;
|
||||
Ret = Val;
|
||||
Mangled.remove_prefix(1);
|
||||
return true;
|
||||
return Mangled + 1;
|
||||
}
|
||||
|
||||
Val += Mangled[0] - 'A';
|
||||
Mangled.remove_prefix(1);
|
||||
++Mangled;
|
||||
}
|
||||
|
||||
Mangled = {};
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Demangler::decodeBackref(std::string_view &Mangled,
|
||||
std::string_view &Ret) {
|
||||
assert(!Mangled.empty() && Mangled.front() == 'Q' &&
|
||||
"Invalid back reference!");
|
||||
Ret = {};
|
||||
const char *Demangler::decodeBackref(const char *Mangled, const char *&Ret) {
|
||||
assert(Mangled != nullptr && *Mangled == 'Q' && "Invalid back reference!");
|
||||
Ret = nullptr;
|
||||
|
||||
// Position of 'Q'
|
||||
const char *Qpos = Mangled.data();
|
||||
const char *Qpos = Mangled;
|
||||
long RefPos;
|
||||
Mangled.remove_prefix(1);
|
||||
++Mangled;
|
||||
|
||||
if (!decodeBackrefPos(Mangled, RefPos)) {
|
||||
Mangled = {};
|
||||
return false;
|
||||
}
|
||||
Mangled = decodeBackrefPos(Mangled, RefPos);
|
||||
if (Mangled == nullptr)
|
||||
return nullptr;
|
||||
|
||||
if (RefPos > Qpos - Str.data()) {
|
||||
Mangled = {};
|
||||
return false;
|
||||
}
|
||||
if (RefPos > Qpos - Str)
|
||||
return nullptr;
|
||||
|
||||
// Set the position of the back reference.
|
||||
Ret = Qpos - RefPos;
|
||||
|
||||
return true;
|
||||
return Mangled;
|
||||
}
|
||||
|
||||
void Demangler::parseSymbolBackref(OutputBuffer *Demangled,
|
||||
std::string_view &Mangled) {
|
||||
const char *Demangler::parseSymbolBackref(OutputBuffer *Demangled,
|
||||
const char *Mangled) {
|
||||
// An identifier back reference always points to a digit 0 to 9.
|
||||
// IdentifierBackRef:
|
||||
// Q NumberBackRef
|
||||
// ^
|
||||
const char *Backref;
|
||||
unsigned long Len;
|
||||
|
||||
// Get position of the back reference
|
||||
std::string_view Backref;
|
||||
if (!decodeBackref(Mangled, Backref)) {
|
||||
Mangled = {};
|
||||
return;
|
||||
}
|
||||
Mangled = decodeBackref(Mangled, Backref);
|
||||
|
||||
// Must point to a simple identifier
|
||||
decodeNumber(Backref, Len);
|
||||
if (Backref.empty() || Backref.length() < Len) {
|
||||
Mangled = {};
|
||||
return;
|
||||
}
|
||||
Backref = decodeNumber(Backref, Len);
|
||||
if (Backref == nullptr || strlen(Backref) < Len)
|
||||
return nullptr;
|
||||
|
||||
parseLName(Demangled, Backref, Len);
|
||||
if (Backref.empty())
|
||||
Mangled = {};
|
||||
Backref = parseLName(Demangled, Backref, Len);
|
||||
if (Backref == nullptr)
|
||||
return nullptr;
|
||||
|
||||
return Mangled;
|
||||
}
|
||||
|
||||
void Demangler::parseTypeBackref(std::string_view &Mangled) {
|
||||
const char *Demangler::parseTypeBackref(const char *Mangled) {
|
||||
// A type back reference always points to a letter.
|
||||
// TypeBackRef:
|
||||
// Q NumberBackRef
|
||||
// ^
|
||||
const char *Backref;
|
||||
|
||||
// If we appear to be moving backwards through the mangle string, then
|
||||
// bail as this may be a recursive back reference.
|
||||
if (Mangled.data() - Str.data() >= LastBackref) {
|
||||
Mangled = {};
|
||||
return;
|
||||
}
|
||||
if (Mangled - Str >= LastBackref)
|
||||
return nullptr;
|
||||
|
||||
int SaveRefPos = LastBackref;
|
||||
LastBackref = Mangled.data() - Str.data();
|
||||
LastBackref = Mangled - Str;
|
||||
|
||||
// Get position of the back reference.
|
||||
std::string_view Backref;
|
||||
if (!decodeBackref(Mangled, Backref)) {
|
||||
Mangled = {};
|
||||
return;
|
||||
}
|
||||
Mangled = decodeBackref(Mangled, Backref);
|
||||
|
||||
// Can't decode back reference.
|
||||
if (Backref.empty()) {
|
||||
Mangled = {};
|
||||
return;
|
||||
}
|
||||
if (Backref == nullptr)
|
||||
return nullptr;
|
||||
|
||||
// TODO: Add support for function type back references.
|
||||
if (!parseType(Backref))
|
||||
Mangled = {};
|
||||
Backref = parseType(Backref);
|
||||
|
||||
LastBackref = SaveRefPos;
|
||||
|
||||
if (Backref.empty())
|
||||
Mangled = {};
|
||||
if (Backref == nullptr)
|
||||
return nullptr;
|
||||
|
||||
return Mangled;
|
||||
}
|
||||
|
||||
bool Demangler::isSymbolName(std::string_view Mangled) {
|
||||
bool Demangler::isSymbolName(const char *Mangled) {
|
||||
long Ret;
|
||||
const char *Qref = Mangled.data();
|
||||
const char *Qref = Mangled;
|
||||
|
||||
if (std::isdigit(Mangled.front()))
|
||||
if (std::isdigit(*Mangled))
|
||||
return true;
|
||||
|
||||
// TODO: Handle template instances.
|
||||
|
||||
if (Mangled.front() != 'Q')
|
||||
if (*Mangled != 'Q')
|
||||
return false;
|
||||
|
||||
Mangled.remove_prefix(1);
|
||||
bool Valid = decodeBackrefPos(Mangled, Ret);
|
||||
if (!Valid || Ret > Qref - Str.data())
|
||||
Mangled = decodeBackrefPos(Mangled + 1, Ret);
|
||||
if (Mangled == nullptr || Ret > Qref - Str)
|
||||
return false;
|
||||
|
||||
return std::isdigit(Qref[-Ret]);
|
||||
}
|
||||
|
||||
void Demangler::parseMangle(OutputBuffer *Demangled,
|
||||
std::string_view &Mangled) {
|
||||
const char *Demangler::parseMangle(OutputBuffer *Demangled,
|
||||
const char *Mangled) {
|
||||
// A D mangled symbol is comprised of both scope and type information.
|
||||
// MangleName:
|
||||
// _D QualifiedName Type
|
||||
@@ -367,24 +352,24 @@ void Demangler::parseMangle(OutputBuffer *Demangled,
|
||||
// above location.
|
||||
// Note that type is never a function type, but only the return type of
|
||||
// a function or the type of a variable.
|
||||
Mangled.remove_prefix(2);
|
||||
Mangled += 2;
|
||||
|
||||
parseQualified(Demangled, Mangled);
|
||||
Mangled = parseQualified(Demangled, Mangled);
|
||||
|
||||
if (Mangled.empty()) {
|
||||
Mangled = {};
|
||||
return;
|
||||
if (Mangled != nullptr) {
|
||||
// Artificial symbols end with 'Z' and have no type.
|
||||
if (*Mangled == 'Z')
|
||||
++Mangled;
|
||||
else {
|
||||
Mangled = parseType(Mangled);
|
||||
}
|
||||
}
|
||||
|
||||
// Artificial symbols end with 'Z' and have no type.
|
||||
if (Mangled.front() == 'Z') {
|
||||
Mangled.remove_prefix(1);
|
||||
} else if (!parseType(Mangled))
|
||||
Mangled = {};
|
||||
return Mangled;
|
||||
}
|
||||
|
||||
void Demangler::parseQualified(OutputBuffer *Demangled,
|
||||
std::string_view &Mangled) {
|
||||
const char *Demangler::parseQualified(OutputBuffer *Demangled,
|
||||
const char *Mangled) {
|
||||
// Qualified names are identifiers separated by their encoded length.
|
||||
// Nested functions also encode their argument types without specifying
|
||||
// what they return.
|
||||
@@ -403,10 +388,10 @@ void Demangler::parseQualified(OutputBuffer *Demangled,
|
||||
size_t NotFirst = false;
|
||||
do {
|
||||
// Skip over anonymous symbols.
|
||||
if (!Mangled.empty() && Mangled.front() == '0') {
|
||||
if (*Mangled == '0') {
|
||||
do
|
||||
Mangled.remove_prefix(1);
|
||||
while (!Mangled.empty() && Mangled.front() == '0');
|
||||
++Mangled;
|
||||
while (*Mangled == '0');
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -415,63 +400,62 @@ void Demangler::parseQualified(OutputBuffer *Demangled,
|
||||
*Demangled << '.';
|
||||
NotFirst = true;
|
||||
|
||||
parseIdentifier(Demangled, Mangled);
|
||||
} while (!Mangled.empty() && isSymbolName(Mangled));
|
||||
Mangled = parseIdentifier(Demangled, Mangled);
|
||||
|
||||
} while (Mangled && isSymbolName(Mangled));
|
||||
|
||||
return Mangled;
|
||||
}
|
||||
|
||||
void Demangler::parseIdentifier(OutputBuffer *Demangled,
|
||||
std::string_view &Mangled) {
|
||||
if (Mangled.empty()) {
|
||||
Mangled = {};
|
||||
return;
|
||||
}
|
||||
const char *Demangler::parseIdentifier(OutputBuffer *Demangled,
|
||||
const char *Mangled) {
|
||||
unsigned long Len;
|
||||
|
||||
if (Mangled.front() == 'Q')
|
||||
if (Mangled == nullptr || *Mangled == '\0')
|
||||
return nullptr;
|
||||
|
||||
if (*Mangled == 'Q')
|
||||
return parseSymbolBackref(Demangled, Mangled);
|
||||
|
||||
// TODO: Parse lengthless template instances.
|
||||
|
||||
unsigned long Len;
|
||||
decodeNumber(Mangled, Len);
|
||||
const char *Endptr = decodeNumber(Mangled, Len);
|
||||
|
||||
if (Mangled.empty()) {
|
||||
Mangled = {};
|
||||
return;
|
||||
}
|
||||
if (!Len || Mangled.length() < Len) {
|
||||
Mangled = {};
|
||||
return;
|
||||
}
|
||||
if (Endptr == nullptr || Len == 0)
|
||||
return nullptr;
|
||||
|
||||
if (strlen(Endptr) < Len)
|
||||
return nullptr;
|
||||
|
||||
Mangled = Endptr;
|
||||
|
||||
// TODO: Parse template instances with a length prefix.
|
||||
|
||||
// There can be multiple different declarations in the same function that
|
||||
// have the same mangled name. To make the mangled names unique, a fake
|
||||
// parent in the form `__Sddd' is added to the symbol.
|
||||
if (Len >= 4 && starts_with(Mangled, "__S")) {
|
||||
const size_t SuffixLen = Mangled.length() - Len;
|
||||
std::string_view P = Mangled.substr(3);
|
||||
while (P.length() > SuffixLen && std::isdigit(P.front()))
|
||||
P.remove_prefix(1);
|
||||
if (P.length() == SuffixLen) {
|
||||
if (Len >= 4 && Mangled[0] == '_' && Mangled[1] == '_' && Mangled[2] == 'S') {
|
||||
const char *NumPtr = Mangled + 3;
|
||||
while (NumPtr < (Mangled + Len) && std::isdigit(*NumPtr))
|
||||
++NumPtr;
|
||||
|
||||
if (Mangled + Len == NumPtr) {
|
||||
// Skip over the fake parent.
|
||||
Mangled.remove_prefix(Len);
|
||||
Mangled += Len;
|
||||
return parseIdentifier(Demangled, Mangled);
|
||||
}
|
||||
|
||||
// Else demangle it as a plain identifier.
|
||||
}
|
||||
|
||||
parseLName(Demangled, Mangled, Len);
|
||||
return parseLName(Demangled, Mangled, Len);
|
||||
}
|
||||
|
||||
bool Demangler::parseType(std::string_view &Mangled) {
|
||||
if (Mangled.empty()) {
|
||||
Mangled = {};
|
||||
return false;
|
||||
}
|
||||
const char *Demangler::parseType(const char *Mangled) {
|
||||
if (*Mangled == '\0')
|
||||
return nullptr;
|
||||
|
||||
switch (Mangled.front()) {
|
||||
switch (*Mangled) {
|
||||
// TODO: Parse type qualifiers.
|
||||
// TODO: Parse function types.
|
||||
// TODO: Parse compound types.
|
||||
@@ -480,102 +464,102 @@ bool Demangler::parseType(std::string_view &Mangled) {
|
||||
|
||||
// Basic types.
|
||||
case 'i':
|
||||
Mangled.remove_prefix(1);
|
||||
++Mangled;
|
||||
// TODO: Add type name dumping
|
||||
return true;
|
||||
return Mangled;
|
||||
|
||||
// TODO: Add support for the rest of the basic types.
|
||||
|
||||
// Back referenced type.
|
||||
case 'Q': {
|
||||
parseTypeBackref(Mangled);
|
||||
return true;
|
||||
}
|
||||
case 'Q':
|
||||
return parseTypeBackref(Mangled);
|
||||
|
||||
default: // unhandled.
|
||||
Mangled = {};
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Demangler::parseLName(OutputBuffer *Demangled, std::string_view &Mangled,
|
||||
unsigned long Len) {
|
||||
const char *Demangler::parseLName(OutputBuffer *Demangled, const char *Mangled,
|
||||
unsigned long Len) {
|
||||
switch (Len) {
|
||||
case 6:
|
||||
if (starts_with(Mangled, "__initZ")) {
|
||||
if (strncmp(Mangled, "__initZ", Len + 1) == 0) {
|
||||
// The static initializer for a given symbol.
|
||||
Demangled->prepend("initializer for ");
|
||||
Demangled->setCurrentPosition(Demangled->getCurrentPosition() - 1);
|
||||
Mangled.remove_prefix(Len);
|
||||
return;
|
||||
Mangled += Len;
|
||||
return Mangled;
|
||||
}
|
||||
if (starts_with(Mangled, "__vtblZ")) {
|
||||
if (strncmp(Mangled, "__vtblZ", Len + 1) == 0) {
|
||||
// The vtable symbol for a given class.
|
||||
Demangled->prepend("vtable for ");
|
||||
Demangled->setCurrentPosition(Demangled->getCurrentPosition() - 1);
|
||||
Mangled.remove_prefix(Len);
|
||||
return;
|
||||
Mangled += Len;
|
||||
return Mangled;
|
||||
}
|
||||
break;
|
||||
|
||||
case 7:
|
||||
if (starts_with(Mangled, "__ClassZ")) {
|
||||
if (strncmp(Mangled, "__ClassZ", Len + 1) == 0) {
|
||||
// The classinfo symbol for a given class.
|
||||
Demangled->prepend("ClassInfo for ");
|
||||
Demangled->setCurrentPosition(Demangled->getCurrentPosition() - 1);
|
||||
Mangled.remove_prefix(Len);
|
||||
return;
|
||||
Mangled += Len;
|
||||
return Mangled;
|
||||
}
|
||||
break;
|
||||
|
||||
case 11:
|
||||
if (starts_with(Mangled, "__InterfaceZ")) {
|
||||
if (strncmp(Mangled, "__InterfaceZ", Len + 1) == 0) {
|
||||
// The interface symbol for a given class.
|
||||
Demangled->prepend("Interface for ");
|
||||
Demangled->setCurrentPosition(Demangled->getCurrentPosition() - 1);
|
||||
Mangled.remove_prefix(Len);
|
||||
return;
|
||||
Mangled += Len;
|
||||
return Mangled;
|
||||
}
|
||||
break;
|
||||
|
||||
case 12:
|
||||
if (starts_with(Mangled, "__ModuleInfoZ")) {
|
||||
if (strncmp(Mangled, "__ModuleInfoZ", Len + 1) == 0) {
|
||||
// The ModuleInfo symbol for a given module.
|
||||
Demangled->prepend("ModuleInfo for ");
|
||||
Demangled->setCurrentPosition(Demangled->getCurrentPosition() - 1);
|
||||
Mangled.remove_prefix(Len);
|
||||
return;
|
||||
Mangled += Len;
|
||||
return Mangled;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
*Demangled << Mangled.substr(0, Len);
|
||||
Mangled.remove_prefix(Len);
|
||||
*Demangled << StringView(Mangled, Len);
|
||||
Mangled += Len;
|
||||
|
||||
return Mangled;
|
||||
}
|
||||
|
||||
Demangler::Demangler(std::string_view Mangled)
|
||||
: Str(Mangled), LastBackref(Mangled.length()) {}
|
||||
Demangler::Demangler(const char *Mangled)
|
||||
: Str(Mangled), LastBackref(strlen(Mangled)) {}
|
||||
|
||||
const char *Demangler::parseMangle(OutputBuffer *Demangled) {
|
||||
std::string_view M(this->Str);
|
||||
parseMangle(Demangled, M);
|
||||
return M.data();
|
||||
return parseMangle(Demangled, this->Str);
|
||||
}
|
||||
|
||||
char *llvm::dlangDemangle(std::string_view MangledName) {
|
||||
if (MangledName.empty() || !starts_with(MangledName, "_D"))
|
||||
char *llvm::dlangDemangle(const char *MangledName) {
|
||||
if (MangledName == nullptr || strncmp(MangledName, "_D", 2) != 0)
|
||||
return nullptr;
|
||||
|
||||
OutputBuffer Demangled;
|
||||
if (MangledName == "_Dmain") {
|
||||
if (!initializeOutputBuffer(nullptr, nullptr, Demangled, 1024))
|
||||
return nullptr;
|
||||
|
||||
if (strcmp(MangledName, "_Dmain") == 0) {
|
||||
Demangled << "D main";
|
||||
} else {
|
||||
|
||||
Demangler D(MangledName);
|
||||
const char *M = D.parseMangle(&Demangled);
|
||||
Demangler D = Demangler(MangledName);
|
||||
MangledName = D.parseMangle(&Demangled);
|
||||
|
||||
// Check that the entire symbol was successfully demangled.
|
||||
if (M == nullptr || *M != '\0') {
|
||||
if (MangledName == nullptr || *MangledName != '\0') {
|
||||
std::free(Demangled.getBuffer());
|
||||
return nullptr;
|
||||
}
|
||||
@@ -11,45 +11,45 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Demangle/Demangle.h"
|
||||
#include "llvm/Demangle/StringViewExtras.h"
|
||||
#include <cstdlib>
|
||||
#include <string_view>
|
||||
#include <cstring>
|
||||
|
||||
using llvm::itanium_demangle::starts_with;
|
||||
static bool isItaniumEncoding(const char *S) {
|
||||
// Itanium encoding requires 1 or 3 leading underscores, followed by 'Z'.
|
||||
return std::strncmp(S, "_Z", 2) == 0 || std::strncmp(S, "___Z", 4) == 0;
|
||||
}
|
||||
|
||||
std::string llvm::demangle(std::string_view MangledName) {
|
||||
static bool isRustEncoding(const char *S) { return S[0] == '_' && S[1] == 'R'; }
|
||||
|
||||
static bool isDLangEncoding(const std::string &MangledName) {
|
||||
return MangledName.size() >= 2 && MangledName[0] == '_' &&
|
||||
MangledName[1] == 'D';
|
||||
}
|
||||
|
||||
std::string llvm::demangle(const std::string &MangledName) {
|
||||
std::string Result;
|
||||
const char *S = MangledName.c_str();
|
||||
|
||||
if (nonMicrosoftDemangle(MangledName, Result))
|
||||
if (nonMicrosoftDemangle(S, Result))
|
||||
return Result;
|
||||
|
||||
if (starts_with(MangledName, '_') &&
|
||||
nonMicrosoftDemangle(MangledName.substr(1), Result))
|
||||
if (S[0] == '_' && nonMicrosoftDemangle(S + 1, Result))
|
||||
return Result;
|
||||
|
||||
if (char *Demangled = microsoftDemangle(MangledName, nullptr, nullptr)) {
|
||||
if (char *Demangled =
|
||||
microsoftDemangle(S, nullptr, nullptr, nullptr, nullptr)) {
|
||||
Result = Demangled;
|
||||
std::free(Demangled);
|
||||
} else {
|
||||
Result = MangledName;
|
||||
return Result;
|
||||
}
|
||||
return Result;
|
||||
|
||||
return MangledName;
|
||||
}
|
||||
|
||||
static bool isItaniumEncoding(std::string_view S) {
|
||||
// Itanium encoding requires 1 or 3 leading underscores, followed by 'Z'.
|
||||
return starts_with(S, "_Z") || starts_with(S, "___Z");
|
||||
}
|
||||
|
||||
static bool isRustEncoding(std::string_view S) { return starts_with(S, "_R"); }
|
||||
|
||||
static bool isDLangEncoding(std::string_view S) { return starts_with(S, "_D"); }
|
||||
|
||||
bool llvm::nonMicrosoftDemangle(std::string_view MangledName,
|
||||
std::string &Result) {
|
||||
bool llvm::nonMicrosoftDemangle(const char *MangledName, std::string &Result) {
|
||||
char *Demangled = nullptr;
|
||||
if (isItaniumEncoding(MangledName))
|
||||
Demangled = itaniumDemangle(MangledName);
|
||||
Demangled = itaniumDemangle(MangledName, nullptr, nullptr, nullptr);
|
||||
else if (isRustEncoding(MangledName))
|
||||
Demangled = rustDemangle(MangledName);
|
||||
else if (isDLangEncoding(MangledName))
|
||||
@@ -18,7 +18,6 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <exception>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
|
||||
@@ -79,8 +78,8 @@ struct DumpVisitor {
|
||||
}
|
||||
|
||||
void printStr(const char *S) { fprintf(stderr, "%s", S); }
|
||||
void print(std::string_view SV) {
|
||||
fprintf(stderr, "\"%.*s\"", (int)SV.size(), SV.data());
|
||||
void print(StringView SV) {
|
||||
fprintf(stderr, "\"%.*s\"", (int)SV.size(), SV.begin());
|
||||
}
|
||||
void print(const Node *N) {
|
||||
if (N)
|
||||
@@ -366,21 +365,36 @@ public:
|
||||
|
||||
using Demangler = itanium_demangle::ManglingParser<DefaultAllocator>;
|
||||
|
||||
char *llvm::itaniumDemangle(std::string_view MangledName) {
|
||||
if (MangledName.empty())
|
||||
return nullptr;
|
||||
|
||||
Demangler Parser(MangledName.data(),
|
||||
MangledName.data() + MangledName.length());
|
||||
Node *AST = Parser.parse();
|
||||
if (!AST)
|
||||
char *llvm::itaniumDemangle(const char *MangledName, char *Buf,
|
||||
size_t *N, int *Status) {
|
||||
if (MangledName == nullptr || (Buf != nullptr && N == nullptr)) {
|
||||
if (Status)
|
||||
*Status = demangle_invalid_args;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int InternalStatus = demangle_success;
|
||||
Demangler Parser(MangledName, MangledName + std::strlen(MangledName));
|
||||
OutputBuffer OB;
|
||||
assert(Parser.ForwardTemplateRefs.empty());
|
||||
AST->print(OB);
|
||||
OB += '\0';
|
||||
return OB.getBuffer();
|
||||
|
||||
Node *AST = Parser.parse();
|
||||
|
||||
if (AST == nullptr)
|
||||
InternalStatus = demangle_invalid_mangled_name;
|
||||
else if (!initializeOutputBuffer(Buf, N, OB, 1024))
|
||||
InternalStatus = demangle_memory_alloc_failure;
|
||||
else {
|
||||
assert(Parser.ForwardTemplateRefs.empty());
|
||||
AST->print(OB);
|
||||
OB += '\0';
|
||||
if (N != nullptr)
|
||||
*N = OB.getCurrentPosition();
|
||||
Buf = OB.getBuffer();
|
||||
}
|
||||
|
||||
if (Status)
|
||||
*Status = InternalStatus;
|
||||
return InternalStatus == demangle_success ? Buf : nullptr;
|
||||
}
|
||||
|
||||
ItaniumPartialDemangler::ItaniumPartialDemangler()
|
||||
@@ -413,7 +427,9 @@ bool ItaniumPartialDemangler::partialDemangle(const char *MangledName) {
|
||||
}
|
||||
|
||||
static char *printNode(const Node *RootNode, char *Buf, size_t *N) {
|
||||
OutputBuffer OB(Buf, N);
|
||||
OutputBuffer OB;
|
||||
if (!initializeOutputBuffer(Buf, N, OB, 128))
|
||||
return nullptr;
|
||||
RootNode->print(OB);
|
||||
OB += '\0';
|
||||
if (N != nullptr)
|
||||
@@ -456,7 +472,9 @@ char *ItaniumPartialDemangler::getFunctionDeclContextName(char *Buf,
|
||||
return nullptr;
|
||||
const Node *Name = static_cast<const FunctionEncoding *>(RootNode)->getName();
|
||||
|
||||
OutputBuffer OB(Buf, N);
|
||||
OutputBuffer OB;
|
||||
if (!initializeOutputBuffer(Buf, N, OB, 128))
|
||||
return nullptr;
|
||||
|
||||
KeepGoingLocalFunction:
|
||||
while (true) {
|
||||
@@ -507,7 +525,9 @@ char *ItaniumPartialDemangler::getFunctionParameters(char *Buf,
|
||||
return nullptr;
|
||||
NodeArray Params = static_cast<FunctionEncoding *>(RootNode)->getParams();
|
||||
|
||||
OutputBuffer OB(Buf, N);
|
||||
OutputBuffer OB;
|
||||
if (!initializeOutputBuffer(Buf, N, OB, 128))
|
||||
return nullptr;
|
||||
|
||||
OB += '(';
|
||||
Params.printWithComma(OB);
|
||||
@@ -523,7 +543,9 @@ char *ItaniumPartialDemangler::getFunctionReturnType(
|
||||
if (!isFunction())
|
||||
return nullptr;
|
||||
|
||||
OutputBuffer OB(Buf, N);
|
||||
OutputBuffer OB;
|
||||
if (!initializeOutputBuffer(Buf, N, OB, 128))
|
||||
return nullptr;
|
||||
|
||||
if (const Node *Ret =
|
||||
static_cast<const FunctionEncoding *>(RootNode)->getReturnType())
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user