mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-01-31 01:15:24 +01:00
Compare commits
179 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f67c0cbd2e | ||
|
|
ff7cc0867b | ||
|
|
ac1a6d3348 | ||
|
|
582bba6c91 | ||
|
|
aaf156478e | ||
|
|
0539c177ab | ||
|
|
fb1323b72f | ||
|
|
dc557dd0e5 | ||
|
|
2d0cfc9c2c | ||
|
|
625a25cd50 | ||
|
|
b8a29d1cd8 | ||
|
|
0fabdf9a01 | ||
|
|
9c3ae795c8 | ||
|
|
de26226fa1 | ||
|
|
121920c074 | ||
|
|
05e19470b2 | ||
|
|
b6680e4aca | ||
|
|
f9d70af841 | ||
|
|
7587581d1f | ||
|
|
8f19976c10 | ||
|
|
8567d68433 | ||
|
|
6542301566 | ||
|
|
a359f77cf6 | ||
|
|
4c9a81f3d8 | ||
|
|
9234b493a3 | ||
|
|
f84425b67c | ||
|
|
8a0c1874dd | ||
|
|
fa23628ae2 | ||
|
|
8a594e673d | ||
|
|
92b9390c51 | ||
|
|
c5c5b2a7b9 | ||
|
|
32a9d0e48b | ||
|
|
80a961bb25 | ||
|
|
d4e227286e | ||
|
|
ba705c8c24 | ||
|
|
b6ae4b173e | ||
|
|
23a28be346 | ||
|
|
a0e24dd36f | ||
|
|
a2cde5e17b | ||
|
|
ecc46e9294 | ||
|
|
20b1190d47 | ||
|
|
29b736bcf7 | ||
|
|
a48bc76ca6 | ||
|
|
305c01cdfa | ||
|
|
88bbdf4696 | ||
|
|
afc11279a9 | ||
|
|
a3fb2a84d5 | ||
|
|
4db23e6677 | ||
|
|
5dd36a7969 | ||
|
|
35a3d0027e | ||
|
|
02789ebd86 | ||
|
|
dfd1846b93 | ||
|
|
872205abc6 | ||
|
|
c52cebd20a | ||
|
|
f449b54f87 | ||
|
|
ffcb6e2f6f | ||
|
|
5daa1aa115 | ||
|
|
1dc009f752 | ||
|
|
009b4ff5e7 | ||
|
|
f1a947af92 | ||
|
|
97c098b1ff | ||
|
|
e252cb6643 | ||
|
|
75c0236e1e | ||
|
|
9c4a98bc25 | ||
|
|
9cba11cde5 | ||
|
|
fac5512b04 | ||
|
|
ed9bf05971 | ||
|
|
19d0f3bdc5 | ||
|
|
2abe53de43 | ||
|
|
37a25750d7 | ||
|
|
d3e288447f | ||
|
|
4a44d2668c | ||
|
|
752b1420a3 | ||
|
|
71705fc91f | ||
|
|
645efc7520 | ||
|
|
b6ee0e5219 | ||
|
|
7acf32debc | ||
|
|
13397f68a3 | ||
|
|
79250722d6 | ||
|
|
04b8748a8f | ||
|
|
2dab8053ea | ||
|
|
f8bab2e465 | ||
|
|
46221a8500 | ||
|
|
8b0e61af8c | ||
|
|
2b0a78811a | ||
|
|
5798cd7176 | ||
|
|
5c25637381 | ||
|
|
8316228771 | ||
|
|
695250155e | ||
|
|
545e606c11 | ||
|
|
52771fdb17 | ||
|
|
de631a1052 | ||
|
|
605398db67 | ||
|
|
407c989860 | ||
|
|
9b4b112a97 | ||
|
|
865b75bcbb | ||
|
|
795b0813cc | ||
|
|
3e1f2b8b9d | ||
|
|
1f0d6f0ac7 | ||
|
|
4ab4f4a67c | ||
|
|
5dbdd5e5e4 | ||
|
|
f03cddf674 | ||
|
|
726e908a49 | ||
|
|
043cd673b8 | ||
|
|
f84173e5cc | ||
|
|
bef7ae7f6c | ||
|
|
33aed95a6c | ||
|
|
282317c46e | ||
|
|
2d6a42ac06 | ||
|
|
cd98f72f10 | ||
|
|
29a98f317e | ||
|
|
6334082e6f | ||
|
|
bd4a6a10f9 | ||
|
|
ea4d988082 | ||
|
|
bf8693a7e8 | ||
|
|
32a67c48e0 | ||
|
|
e93f81ca7a | ||
|
|
8f107f5345 | ||
|
|
741046079c | ||
|
|
df7646fd34 | ||
|
|
d350408161 | ||
|
|
bde55a6fe2 | ||
|
|
83c1bed868 | ||
|
|
6845f026bc | ||
|
|
f2c796bcc5 | ||
|
|
a930daf575 | ||
|
|
36d8e5f295 | ||
|
|
71100679a3 | ||
|
|
e3b61b5b1f | ||
|
|
42a5e7422c | ||
|
|
24782950e4 | ||
|
|
e5639102cb | ||
|
|
b74d05603d | ||
|
|
23fd57f641 | ||
|
|
53ae93751c | ||
|
|
ec8736107c | ||
|
|
9e21ee1bc4 | ||
|
|
31497c2b86 | ||
|
|
0600832ddb | ||
|
|
4a57bd7fd4 | ||
|
|
fbe0c8b9cc | ||
|
|
2e3501366f | ||
|
|
ef7169dbbf | ||
|
|
de9d08075e | ||
|
|
c58f6f2f70 | ||
|
|
56aa5d9657 | ||
|
|
754057b496 | ||
|
|
513c44f07f | ||
|
|
0090655899 | ||
|
|
7103e9be1e | ||
|
|
b04906c3e9 | ||
|
|
fc5fe8b48c | ||
|
|
e32e91af5c | ||
|
|
aa5b026d4a | ||
|
|
9568f3305b | ||
|
|
f33064a1e2 | ||
|
|
6c9a2e96e1 | ||
|
|
8c98f5d928 | ||
|
|
19f0cfcf06 | ||
|
|
4f42d95d3c | ||
|
|
68823c524f | ||
|
|
05917796a5 | ||
|
|
d64da07b7d | ||
|
|
27074a809c | ||
|
|
33b366180e | ||
|
|
d8e310e7bf | ||
|
|
534ddd80ae | ||
|
|
d34f2ec142 | ||
|
|
7381a02dae | ||
|
|
333c7ef61b | ||
|
|
77d5a04aa4 | ||
|
|
d3effdb176 | ||
|
|
d7e1350b95 | ||
|
|
14ac653e45 | ||
|
|
a5e4274cd2 | ||
|
|
16b1095a7b | ||
|
|
3b5b3ffa91 | ||
|
|
7ebcca36d2 | ||
|
|
501c543d1b |
1
.github/workflows/cron_publish_flatpak.yml
vendored
1
.github/workflows/cron_publish_flatpak.yml
vendored
@@ -10,6 +10,7 @@ jobs:
|
||||
if: github.repository == 'PCSX2/pcsx2'
|
||||
name: "Check if release is needed"
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 180
|
||||
outputs:
|
||||
PCSX2_RELEASE: ${{ steps.getinfo.outputs.PCSX2_RELEASE }}
|
||||
FLATHUB_RELEASE: ${{ steps.getinfo.outputs.FLATHUB_RELEASE }}
|
||||
|
||||
4
.github/workflows/linux_build_matrix.yml
vendored
4
.github/workflows/linux_build_matrix.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
uses: ./.github/workflows/linux_build_qt.yml
|
||||
with:
|
||||
jobName: "AppImage Build"
|
||||
artifactPrefixName: "PCSX2-linux-Qt-x64-appimage-sse4"
|
||||
artifactPrefixName: "PCSX2-linux-Qt-x64-appimage"
|
||||
compiler: clang
|
||||
cmakeflags: ""
|
||||
buildAppImage: true
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
uses: ./.github/workflows/linux_build_flatpak.yml
|
||||
with:
|
||||
jobName: "Flatpak Build"
|
||||
artifactPrefixName: "PCSX2-linux-Qt-x64-flatpak-sse4"
|
||||
artifactPrefixName: "PCSX2-linux-Qt-x64-flatpak"
|
||||
compiler: clang
|
||||
cmakeflags: ""
|
||||
publish: false
|
||||
|
||||
2
.github/workflows/linux_build_qt.yml
vendored
2
.github/workflows/linux_build_qt.yml
vendored
@@ -55,7 +55,7 @@ jobs:
|
||||
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||
CCACHE_COMPRESS: true
|
||||
CCACHE_COMPRESSLEVEL: 9
|
||||
CCACHE_MAXSIZE: 100M
|
||||
CCACHE_MAXSIZE: 500M
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
|
||||
42
.github/workflows/macos_build.yml
vendored
42
.github/workflows/macos_build.yml
vendored
@@ -25,6 +25,10 @@ on:
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
sign_and_notarize:
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
jobs:
|
||||
build_macos:
|
||||
@@ -38,7 +42,9 @@ jobs:
|
||||
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||
CCACHE_COMPRESS: true
|
||||
CCACHE_COMPRESSLEVEL: 9
|
||||
CCACHE_MAXSIZE: 100M
|
||||
CCACHE_MAXSIZE: 500M
|
||||
# Only way to use a secret in an if statement
|
||||
SIGN_KEY: ${{ secrets.APPLE_SIGN_P12_B64 }}
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
@@ -143,6 +149,38 @@ jobs:
|
||||
run: make -j$(getconf _NPROCESSORS_ONLN) unittests
|
||||
|
||||
- name: Prepare Build Artifacts
|
||||
run: |
|
||||
mv build/pcsx2*/PCSX2.app PCSX2.app
|
||||
|
||||
- name: Pull the Signing Keys and Notarization Credentials
|
||||
if: ${{ inputs.sign_and_notarize == true && env.SIGN_KEY }}
|
||||
run: |
|
||||
echo "${{ secrets.APPLE_SIGN_P12_B64 }}" | base64 -d > cert.p12
|
||||
echo "${{ secrets.APPLE_APPSTORECONNECT_CFG }}" | base64 -d > key.json
|
||||
|
||||
- name: Sign the Application
|
||||
if: ${{ inputs.sign_and_notarize == true && env.SIGN_KEY }}
|
||||
uses: indygreg/apple-code-sign-action@v1.1
|
||||
with:
|
||||
input_path: 'PCSX2.app'
|
||||
p12_file: cert.p12
|
||||
p12_password: "${{ secrets.APPLE_SIGN_P12_PASS }}"
|
||||
sign_args: |
|
||||
--for-notarization
|
||||
--code-signature-flags=runtime
|
||||
--entitlements-xml-file=pcsx2/Resources/PCSX2.entitlements
|
||||
notarize: true
|
||||
# max_wait_seconds is only present on my fork located at F0bes/apple-code-sign-action@demo4
|
||||
# If we are timing out we should switch to the newest upstream (if I get it upstreamed)
|
||||
# or use my fork.
|
||||
# max_wait_seconds: '2000'
|
||||
staple: true
|
||||
# Generated using rcodesign
|
||||
# Despite what the docs say, I found that this file is required and I had 0 luck
|
||||
# passing the issuer id, key, etc through arguments.
|
||||
app_store_connect_api_key_json_file: 'key.json'
|
||||
|
||||
- name: Zip Build Artifacts
|
||||
run: |
|
||||
TAG="$(git tag --points-at HEAD)"
|
||||
if [ -z "$TAG" ]; then
|
||||
@@ -150,7 +188,7 @@ jobs:
|
||||
else
|
||||
APPNAME="PCSX2-$TAG"
|
||||
fi
|
||||
mv build/pcsx2*/PCSX2.app "$APPNAME.app"
|
||||
mv PCSX2.app "$APPNAME.app"
|
||||
tar --options xz:compression-level=9 -cvJf "${{ steps.artifact-metadata.outputs.artifact-name }}.tar.xz" "$APPNAME.app"
|
||||
mkdir ci-artifacts
|
||||
cp "${{ steps.artifact-metadata.outputs.artifact-name }}.tar.xz" ci-artifacts/macOS.tar.xz
|
||||
|
||||
1
.github/workflows/macos_build_matrix.yml
vendored
1
.github/workflows/macos_build_matrix.yml
vendored
@@ -16,4 +16,5 @@ jobs:
|
||||
with:
|
||||
jobName: "MacOS Build"
|
||||
artifactPrefixName: "PCSX2-macos-Qt"
|
||||
sign_and_notarize: true # If we find that notarization takes a long time we should disable that on PR builds
|
||||
secrets: inherit
|
||||
|
||||
3
.github/workflows/release_cut_new.yml
vendored
3
.github/workflows/release_cut_new.yml
vendored
@@ -148,6 +148,7 @@ jobs:
|
||||
artifactPrefixName: "PCSX2-macos-Qt"
|
||||
fetchTags: true
|
||||
stableBuild: ${{ github.event_name == 'workflow_dispatch' && inputs.is_prelease == 'false' }}
|
||||
sign_and_notarize: true
|
||||
secrets: inherit
|
||||
|
||||
# Upload the Artifacts
|
||||
@@ -204,7 +205,7 @@ jobs:
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 22
|
||||
|
||||
- name: Announce Release
|
||||
env:
|
||||
|
||||
25
.github/workflows/scripts/linux/appimage-qt.sh
vendored
25
.github/workflows/scripts/linux/appimage-qt.sh
vendored
@@ -63,9 +63,9 @@ declare -a REMOVE_LIBS=(
|
||||
|
||||
set -e
|
||||
|
||||
LINUXDEPLOY=./linuxdeploy-x86_64
|
||||
LINUXDEPLOY_PLUGIN_QT=./linuxdeploy-plugin-qt-x86_64
|
||||
APPIMAGETOOL=./appimagetool-x86_64
|
||||
LINUXDEPLOY=./linuxdeploy-x86_64.AppImage
|
||||
LINUXDEPLOY_PLUGIN_QT=./linuxdeploy-plugin-qt-x86_64.AppImage
|
||||
APPIMAGETOOL=./appimagetool-x86_64.AppImage
|
||||
PATCHELF=patchelf
|
||||
|
||||
if [ ! -f "$LINUXDEPLOY" ]; then
|
||||
@@ -78,11 +78,8 @@ if [ ! -f "$LINUXDEPLOY_PLUGIN_QT" ]; then
|
||||
chmod +x "$LINUXDEPLOY_PLUGIN_QT"
|
||||
fi
|
||||
|
||||
# Using go-appimage
|
||||
# Backported from https://github.com/stenzek/duckstation/pull/3251
|
||||
if [ ! -f "$APPIMAGETOOL" ]; then
|
||||
APPIMAGETOOLURL=$(wget -q https://api.github.com/repos/probonopd/go-appimage/releases -O - | sed 's/[()",{} ]/\n/g' | grep -o 'https.*continuous.*tool.*86_64.*mage$' | head -1)
|
||||
"$PCSX2DIR/tools/retry.sh" wget -O "$APPIMAGETOOL" "$APPIMAGETOOLURL"
|
||||
"$PCSX2DIR/tools/retry.sh" wget -O "$APPIMAGETOOL" https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
|
||||
chmod +x "$APPIMAGETOOL"
|
||||
fi
|
||||
|
||||
@@ -190,17 +187,6 @@ echo "Generating AppStream metainfo..."
|
||||
mkdir -p "$OUTDIR/usr/share/metainfo"
|
||||
"$SCRIPTDIR/generate-metainfo.sh" "$OUTDIR/usr/share/metainfo/net.pcsx2.PCSX2.appdata.xml"
|
||||
|
||||
# Copy in AppRun hooks.
|
||||
# Unfortunately linuxdeploy is a bit lame and doesn't let us provide our own AppRun hooks, instead
|
||||
# they have to come from plugins.. and screw writing one of those just to disable Wayland.
|
||||
echo "Copying AppRun hooks..."
|
||||
mkdir -p "$OUTDIR/apprun-hooks"
|
||||
for hookpath in "$SCRIPTDIR/apprun-hooks"/*; do
|
||||
hookname=$(basename "$hookpath")
|
||||
cp -v "$hookpath" "$OUTDIR/apprun-hooks/$hookname"
|
||||
sed -i -e 's/exec /source "$this_dir"\/apprun-hooks\/"'"$hookname"'"\nexec /' "$OUTDIR/AppRun"
|
||||
done
|
||||
|
||||
echo "Generating AppImage..."
|
||||
GIT_VERSION=$(git tag --points-at HEAD)
|
||||
|
||||
@@ -213,5 +199,4 @@ if [[ "${GIT_VERSION}" == "" ]]; then
|
||||
fi
|
||||
|
||||
rm -f "$NAME.AppImage"
|
||||
ARCH=x86_64 VERSION="${GIT_VERSION}" "$APPIMAGETOOL" -s "$OUTDIR" && mv ./*.AppImage "$NAME.AppImage"
|
||||
|
||||
$APPIMAGETOOL -v "$OUTDIR" "$NAME.AppImage"
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
if [[ -z "$I_WANT_A_BROKEN_WAYLAND_UI" ]]; then
|
||||
echo "Forcing X11 instead of Wayland, due to various protocol limitations"
|
||||
echo "and Qt issues. If you want to use Wayland, launch PCSX2 with"
|
||||
echo "I_WANT_A_BROKEN_WAYLAND_UI=YES set."
|
||||
export QT_QPA_PLATFORM=xcb
|
||||
else
|
||||
echo "Wayland is not being disabled. Do not complain when things break."
|
||||
fi
|
||||
|
||||
@@ -16,12 +16,12 @@ fi
|
||||
|
||||
LIBBACKTRACE=ad106d5fdd5d960bd33fae1c48a351af567fd075
|
||||
LIBJPEG=9f
|
||||
LIBPNG=1.6.44
|
||||
LIBWEBP=1.4.0
|
||||
LIBPNG=1.6.45
|
||||
LIBWEBP=1.5.0
|
||||
LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
|
||||
SDL=SDL2-2.30.11
|
||||
QT=6.8.1
|
||||
ZSTD=1.5.6
|
||||
SDL=SDL3-3.2.6
|
||||
QT=6.8.2
|
||||
ZSTD=1.5.7
|
||||
|
||||
SHADERC=2024.1
|
||||
SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec
|
||||
@@ -34,17 +34,17 @@ cd deps-build
|
||||
cat > SHASUMS <<EOF
|
||||
fd6f417fe9e3a071cf1424a5152d926a34c4a3c5070745470be6cf12a404ed79 $LIBBACKTRACE.zip
|
||||
04705c110cb2469caa79fb71fba3d7bf834914706e9641a4589485c1f832565b jpegsrc.v$LIBJPEG.tar.gz
|
||||
60c4da1d5b7f0aa8d158da48e8f8afa9773c1c8baa5d21974df61f1886b8ce8e libpng-$LIBPNG.tar.xz
|
||||
61f873ec69e3be1b99535634340d5bde750b2e4447caa1db9f61be3fd49ab1e5 libwebp-$LIBWEBP.tar.gz
|
||||
926485350139ffb51ef69760db35f78846c805fef3d59bfdcb2fba704663f370 libpng-$LIBPNG.tar.xz
|
||||
7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c libwebp-$LIBWEBP.tar.gz
|
||||
0728800155f3ed0a0c87e03addbd30ecbe374f7b080678bbca1506051d50dec3 $LZ4.tar.gz
|
||||
8b8d4aef2038533da814965220f88f77d60dfa0f32685f80ead65e501337da7f $SDL.tar.gz
|
||||
8c29e06cf42aacc1eafc4077ae2ec6c6fcb96a626157e0593d5e82a34fd403c1 zstd-$ZSTD.tar.gz
|
||||
40b14562ef3bd779bc0e0418ea2ae08fa28235f8ea6e8c0cb3bce1d6ad58dcaf qtbase-everywhere-src-$QT.tar.xz
|
||||
138cc2909aa98f5ff7283e36eb3936eb5e625d3ca3b4febae2ca21d8903dd237 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
3d0de73596e36b2daa7c48d77c4426bb091752856912fba720215f756c560dd0 qtsvg-everywhere-src-$QT.tar.xz
|
||||
9d43d409be08b8681a0155a9c65114b69c9a3fc11aef6487bb7fdc5b283c432d qttools-everywhere-src-$QT.tar.xz
|
||||
635a6093e99152243b807de51077485ceadd4786d4acb135b9340b2303035a4a qttranslations-everywhere-src-$QT.tar.xz
|
||||
2226fbde4e2ddd12f8bf4b239c8f38fd706a54e789e63467dfddc77129eca203 qtwayland-everywhere-src-$QT.tar.xz
|
||||
096a0b843dd1124afda41c24bd05034af75af37e9a1b9d205cc0a70193b27e1a $SDL.tar.gz
|
||||
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
|
||||
012043ce6d411e6e8a91fdc4e05e6bedcfa10fcb1347d3c33908f7fdd10dfe05 qtbase-everywhere-src-$QT.tar.xz
|
||||
d2a1bbb84707b8a0aec29227b170be00f04383fbf2361943596d09e7e443c8e1 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
aa2579f21ca66d19cbcf31d87e9067e07932635d36869c8239d4decd0a9dc1fa qtsvg-everywhere-src-$QT.tar.xz
|
||||
326381b7d43f07913612f291abc298ae79bd95382e2233abce982cff2b53d2c0 qttools-everywhere-src-$QT.tar.xz
|
||||
d2106e8a580bfd77702c4c1840299288d344902b0e2c758ca813ea04c6d6a3d1 qttranslations-everywhere-src-$QT.tar.xz
|
||||
5e46157908295f2bf924462d8c0855b0508ba338ced9e810891fefa295dc9647 qtwayland-everywhere-src-$QT.tar.xz
|
||||
eb3b5f0c16313d34f208d90c2fa1e588a23283eed63b101edd5422be6165d528 shaderc-$SHADERC.tar.gz
|
||||
aa27e4454ce631c5a17924ce0624eac736da19fc6f5a2ab15a6c58da7b36950f shaderc-glslang-$SHADERC_GLSLANG.tar.gz
|
||||
5d866ce34a4b6908e262e5ebfffc0a5e11dd411640b5f24c85a80ad44c0d4697 shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "sdl2",
|
||||
"name": "sdl3",
|
||||
"buildsystem": "cmake-ninja",
|
||||
"builddir": true,
|
||||
"config-opts": [
|
||||
@@ -14,8 +14,8 @@
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://libsdl.org/release/SDL2-2.30.11.tar.gz",
|
||||
"sha256": "8b8d4aef2038533da814965220f88f77d60dfa0f32685f80ead65e501337da7f"
|
||||
"url": "https://libsdl.org/release/SDL3-3.2.6.tar.gz",
|
||||
"sha256": "096a0b843dd1124afda41c24bd05034af75af37e9a1b9d205cc0a70193b27e1a"
|
||||
}
|
||||
],
|
||||
"cleanup": [
|
||||
@@ -19,14 +19,14 @@
|
||||
"--device=all",
|
||||
"--share=network",
|
||||
"--share=ipc",
|
||||
"--socket=x11",
|
||||
"--socket=wayland",
|
||||
"--socket=fallback-x11",
|
||||
"--socket=pulseaudio",
|
||||
"--talk-name=org.freedesktop.ScreenSaver",
|
||||
"--env=QT_QPA_PLATFORM=xcb"
|
||||
"--talk-name=org.freedesktop.ScreenSaver"
|
||||
],
|
||||
"modules": [
|
||||
"modules/10-libpcap.json",
|
||||
"modules/20-sdl2.json",
|
||||
"modules/20-sdl3.json",
|
||||
"modules/21-libbacktrace.json",
|
||||
"modules/22-shaderc.json",
|
||||
{
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 133 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 2.3 MiB |
@@ -6,17 +6,21 @@
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>GPL-3.0+</project_license>
|
||||
<name>PCSX2</name>
|
||||
<developer_name>PCSX2</developer_name>
|
||||
<summary>PlayStation 2 Emulator</summary>
|
||||
<developer id="net.pcsx2">
|
||||
<name>PCSX2 Team</name>
|
||||
</developer>
|
||||
<summary>PlayStation 2 emulator</summary>
|
||||
<description>
|
||||
<p>PCSX2 is a free and open-source PlayStation 2 (PS2) emulator. Its purpose is to emulate the PS2's hardware, using a combination of MIPS CPU Interpreters, Recompilers, and a Virtual Machine which manages hardware states and PS2 system memory. This allows you to play PS2 games on your PC, with many additional features and benefits.</p>
|
||||
<p>PlayStation 2 and PS2 are registered trademarks of Sony Interactive Entertainment. This application is not affiliated in any way with Sony Interactive Entertainment.</p>
|
||||
</description>
|
||||
<url type="homepage">https://pcsx2.net/</url>
|
||||
<url type="vcs-browser">https://github.com/PCSX2/pcsx2</url>
|
||||
<url type="bugtracker">https://github.com/PCSX2/pcsx2/issues</url>
|
||||
<url type="donation">https://github.com/sponsors/PCSX2</url>
|
||||
<url type="faq">https://pcsx2.net/docs/</url>
|
||||
<url type="help">https://pcsx2.net/discord</url>
|
||||
<url type="contribute">https://github.com/PCSX2/pcsx2/blob/master/.github/CONTRIBUTING.md</url>
|
||||
<url type="translate">https://crowdin.com/project/pcsx2-emulator</url>
|
||||
<url type="contact">https://mastodon.social/@PCSX2</url>
|
||||
<screenshots>
|
||||
@@ -37,6 +41,26 @@
|
||||
</caption>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<categories>
|
||||
<category>Game</category>
|
||||
<category>Emulator</category>
|
||||
</categories>
|
||||
<branding>
|
||||
<color type="primary" scheme_preference="light">#3584e4</color>
|
||||
<color type="primary" scheme_preference="dark">#241f31</color>
|
||||
</branding>
|
||||
<supports>
|
||||
<control>keyboard</control>
|
||||
<control>pointing</control>
|
||||
<internet>offline-only</internet>
|
||||
</supports>
|
||||
<recommends>
|
||||
<control>gamepad</control>
|
||||
<memory>8192</memory>
|
||||
</recommends>
|
||||
<requires>
|
||||
<display_length compare="ge">768</display_length>
|
||||
</requires>
|
||||
<content_rating type="oars-1.1"/>
|
||||
<update_contact>pcsx2_AT_pcsx2.net</update_contact>
|
||||
<releases>
|
||||
|
||||
@@ -40,12 +40,12 @@ fi
|
||||
|
||||
FREETYPE=2.13.3
|
||||
HARFBUZZ=10.0.1
|
||||
SDL=SDL2-2.30.11
|
||||
ZSTD=1.5.6
|
||||
SDL=SDL3-3.2.6
|
||||
ZSTD=1.5.7
|
||||
LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
|
||||
LIBPNG=1.6.44
|
||||
LIBPNG=1.6.45
|
||||
LIBJPEG=9f
|
||||
LIBWEBP=1.4.0
|
||||
LIBWEBP=1.5.0
|
||||
FFMPEG=6.0
|
||||
MOLTENVK=1.2.9
|
||||
QT=6.7.2
|
||||
@@ -76,11 +76,11 @@ CMAKE_ARCH_UNIVERSAL=-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64"
|
||||
cat > SHASUMS <<EOF
|
||||
0550350666d427c74daeb85d5ac7bb353acba5f76956395995311a9c6f063289 freetype-$FREETYPE.tar.xz
|
||||
e7358ea86fe10fb9261931af6f010d4358dac64f7074420ca9bc94aae2bdd542 harfbuzz-$HARFBUZZ.tar.gz
|
||||
8b8d4aef2038533da814965220f88f77d60dfa0f32685f80ead65e501337da7f $SDL.tar.gz
|
||||
8c29e06cf42aacc1eafc4077ae2ec6c6fcb96a626157e0593d5e82a34fd403c1 zstd-$ZSTD.tar.gz
|
||||
096a0b843dd1124afda41c24bd05034af75af37e9a1b9d205cc0a70193b27e1a $SDL.tar.gz
|
||||
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
|
||||
0728800155f3ed0a0c87e03addbd30ecbe374f7b080678bbca1506051d50dec3 $LZ4.tar.gz
|
||||
60c4da1d5b7f0aa8d158da48e8f8afa9773c1c8baa5d21974df61f1886b8ce8e libpng-$LIBPNG.tar.xz
|
||||
61f873ec69e3be1b99535634340d5bde750b2e4447caa1db9f61be3fd49ab1e5 libwebp-$LIBWEBP.tar.gz
|
||||
926485350139ffb51ef69760db35f78846c805fef3d59bfdcb2fba704663f370 libpng-$LIBPNG.tar.xz
|
||||
7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c libwebp-$LIBWEBP.tar.gz
|
||||
04705c110cb2469caa79fb71fba3d7bf834914706e9641a4589485c1f832565b jpegsrc.v$LIBJPEG.tar.gz
|
||||
57be87c22d9b49c112b6d24bc67d42508660e6b718b3db89c44e47e289137082 ffmpeg-$FFMPEG.tar.xz
|
||||
f415a09385030c6510a936155ce211f617c31506db5fbc563e804345f1ecf56e v$MOLTENVK.tar.gz
|
||||
|
||||
@@ -22,12 +22,12 @@ fi
|
||||
|
||||
FREETYPE=2.13.3
|
||||
HARFBUZZ=10.0.1
|
||||
SDL=SDL2-2.30.11
|
||||
ZSTD=1.5.6
|
||||
SDL=SDL3-3.2.6
|
||||
ZSTD=1.5.7
|
||||
LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
|
||||
LIBPNG=1.6.44
|
||||
LIBPNG=1.6.45
|
||||
LIBJPEG=9f
|
||||
LIBWEBP=1.4.0
|
||||
LIBWEBP=1.5.0
|
||||
FFMPEG=6.0
|
||||
MOLTENVK=1.2.9
|
||||
QT=6.7.2
|
||||
@@ -56,11 +56,11 @@ CMAKE_COMMON=(
|
||||
cat > SHASUMS <<EOF
|
||||
0550350666d427c74daeb85d5ac7bb353acba5f76956395995311a9c6f063289 freetype-$FREETYPE.tar.xz
|
||||
e7358ea86fe10fb9261931af6f010d4358dac64f7074420ca9bc94aae2bdd542 harfbuzz-$HARFBUZZ.tar.gz
|
||||
8b8d4aef2038533da814965220f88f77d60dfa0f32685f80ead65e501337da7f $SDL.tar.gz
|
||||
8c29e06cf42aacc1eafc4077ae2ec6c6fcb96a626157e0593d5e82a34fd403c1 zstd-$ZSTD.tar.gz
|
||||
096a0b843dd1124afda41c24bd05034af75af37e9a1b9d205cc0a70193b27e1a $SDL.tar.gz
|
||||
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
|
||||
0728800155f3ed0a0c87e03addbd30ecbe374f7b080678bbca1506051d50dec3 $LZ4.tar.gz
|
||||
60c4da1d5b7f0aa8d158da48e8f8afa9773c1c8baa5d21974df61f1886b8ce8e libpng-$LIBPNG.tar.xz
|
||||
61f873ec69e3be1b99535634340d5bde750b2e4447caa1db9f61be3fd49ab1e5 libwebp-$LIBWEBP.tar.gz
|
||||
926485350139ffb51ef69760db35f78846c805fef3d59bfdcb2fba704663f370 libpng-$LIBPNG.tar.xz
|
||||
7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c libwebp-$LIBWEBP.tar.gz
|
||||
04705c110cb2469caa79fb71fba3d7bf834914706e9641a4589485c1f832565b jpegsrc.v$LIBJPEG.tar.gz
|
||||
57be87c22d9b49c112b6d24bc67d42508660e6b718b3db89c44e47e289137082 ffmpeg-$FFMPEG.tar.xz
|
||||
f415a09385030c6510a936155ce211f617c31506db5fbc563e804345f1ecf56e v$MOLTENVK.tar.gz
|
||||
|
||||
640
.github/workflows/scripts/releases/announce-release/package-lock.json
generated
vendored
640
.github/workflows/scripts/releases/announce-release/package-lock.json
generated
vendored
@@ -10,8 +10,8 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@octokit/plugin-retry": "^3.0.9",
|
||||
"@octokit/plugin-throttling": "^3.5.2",
|
||||
"@octokit/rest": "^18.12.0",
|
||||
"@octokit/plugin-throttling": "^9.4.0",
|
||||
"@octokit/rest": "^21.1.1",
|
||||
"discord.js": "^13.2.0"
|
||||
}
|
||||
},
|
||||
@@ -61,45 +61,102 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/auth-token": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
|
||||
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3"
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-5.1.2.tgz",
|
||||
"integrity": "sha512-JcQDsBdg49Yky2w2ld20IHAlwr8d/d8N6NiOXbtuoPCqzbsiJgF633mVUw3x4mo0H5ypataQIX7SFu3yy44Mpw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/core": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz",
|
||||
"integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==",
|
||||
"version": "6.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.4.tgz",
|
||||
"integrity": "sha512-lAS9k7d6I0MPN+gb9bKDt7X8SdxknYqAMh44S5L+lNqIN2NuV8nvv3g8rPp7MuRxcOpxpUIATWprO0C34a8Qmg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/auth-token": "^2.4.4",
|
||||
"@octokit/graphql": "^4.5.8",
|
||||
"@octokit/request": "^5.6.0",
|
||||
"@octokit/request-error": "^2.0.5",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"before-after-hook": "^2.2.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
"@octokit/auth-token": "^5.0.0",
|
||||
"@octokit/graphql": "^8.1.2",
|
||||
"@octokit/request": "^9.2.1",
|
||||
"@octokit/request-error": "^6.1.7",
|
||||
"@octokit/types": "^13.6.2",
|
||||
"before-after-hook": "^3.0.2",
|
||||
"universal-user-agent": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/core/node_modules/@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/core/node_modules/@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/endpoint": {
|
||||
"version": "6.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
|
||||
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
|
||||
"version": "10.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.3.tgz",
|
||||
"integrity": "sha512-nBRBMpKPhQUxCsQQeW+rCJ/OPSMcj3g0nfHn01zGYZXuNDvvXudF/TYY6APj5THlurerpFN4a/dQAIAaM6BYhA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
"@octokit/types": "^13.6.2",
|
||||
"universal-user-agent": "^7.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/endpoint/node_modules/@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/endpoint/node_modules/@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/graphql": {
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
|
||||
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
|
||||
"version": "8.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-8.2.1.tgz",
|
||||
"integrity": "sha512-n57hXtOoHrhwTWdvhVkdJHdhTv0JstjDbDRhJfwIRNfFqmSo1DaK/mD2syoNUoLCyqSjBpGAKOG0BuwF392slw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/request": "^5.6.0",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
"@octokit/request": "^9.2.2",
|
||||
"@octokit/types": "^13.8.0",
|
||||
"universal-user-agent": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/graphql/node_modules/@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/graphql/node_modules/@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/openapi-types": {
|
||||
@@ -108,28 +165,75 @@
|
||||
"integrity": "sha512-dWZfYvCCdjZzDYA3lIAMF72Q0jld8xidqCq5Ryw09eBJXZdcM6he0vWBTvw/b5UnGYqexxOyHWgfrsTlUJL3Gw=="
|
||||
},
|
||||
"node_modules/@octokit/plugin-paginate-rest": {
|
||||
"version": "2.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.9.tgz",
|
||||
"integrity": "sha512-gfSCMgz5scFKsR0dW4jaYsDJVt/UwCHp4dF7sHlmSekZvwzvLiOAGZ4MQkEsL5DW9hIk2W+UQkYZMTA1b6Wsqw==",
|
||||
"version": "11.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.4.2.tgz",
|
||||
"integrity": "sha512-BXJ7XPCTDXFF+wxcg/zscfgw2O/iDPtNSkwwR1W1W5c4Mb3zav/M2XvxQ23nVmKj7jpweB4g8viMeCQdm7LMVA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.33.0"
|
||||
"@octokit/types": "^13.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-request-log": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
|
||||
"integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==",
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-5.3.1.tgz",
|
||||
"integrity": "sha512-n/lNeCtq+9ofhC15xzmJCNKP2BWTv8Ih2TTy+jatNCCq/gQP/V7rK3fjIfuz0pDWDALO/o/4QY4hyOF6TQQFUw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=3"
|
||||
"@octokit/core": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-rest-endpoint-methods": {
|
||||
"version": "5.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.12.1.tgz",
|
||||
"integrity": "sha512-0nY3htfl6x9UkPcqv8pm9vOC/bTA7f4IMDWln13neHRdNWQvOQgZ9fRxK7BAc74rye4yVINEFi9Yb9rnGUvosA==",
|
||||
"version": "13.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.3.1.tgz",
|
||||
"integrity": "sha512-o8uOBdsyR+WR8MK9Cco8dCgvG13H1RlM1nWnK/W7TEACQBFux/vPREgKucxUfuDQ5yi1T3hGf4C5ZmZXAERgwQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.33.0",
|
||||
"deprecation": "^2.3.1"
|
||||
"@octokit/types": "^13.8.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-retry": {
|
||||
@@ -142,49 +246,107 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-throttling": {
|
||||
"version": "3.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-3.7.0.tgz",
|
||||
"integrity": "sha512-qrKT1Yl/KuwGSC6/oHpLBot3ooC9rq0/ryDYBCpkRtoj+R8T47xTMDT6Tk2CxWopFota/8Pi/2SqArqwC0JPow==",
|
||||
"version": "9.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-9.4.0.tgz",
|
||||
"integrity": "sha512-IOlXxXhZA4Z3m0EEYtrrACkuHiArHLZ3CvqWwOez/pURNqRuwfoFlTPbN5Muf28pzFuztxPyiUiNwz8KctdZaQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.1",
|
||||
"@octokit/types": "^13.7.0",
|
||||
"bottleneck": "^2.15.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": "^3.5.0"
|
||||
"@octokit/core": "^6.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-throttling/node_modules/@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/plugin-throttling/node_modules/@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request": {
|
||||
"version": "5.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz",
|
||||
"integrity": "sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==",
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.2.2.tgz",
|
||||
"integrity": "sha512-dZl0ZHx6gOQGcffgm1/Sf6JfEpmh34v3Af2Uci02vzUYz6qEN6zepoRtmybWXIGXFIK8K9ylE3b+duCWqhArtg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/endpoint": "^6.0.1",
|
||||
"@octokit/request-error": "^2.1.0",
|
||||
"@octokit/types": "^6.16.1",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"node-fetch": "^2.6.1",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
"@octokit/endpoint": "^10.1.3",
|
||||
"@octokit/request-error": "^6.1.7",
|
||||
"@octokit/types": "^13.6.2",
|
||||
"fast-content-type-parse": "^2.0.0",
|
||||
"universal-user-agent": "^7.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request-error": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
|
||||
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
|
||||
"version": "6.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.7.tgz",
|
||||
"integrity": "sha512-69NIppAwaauwZv6aOzb+VVLwt+0havz9GT5YplkeJv7fG7a40qpLt/yZKyiDxAhgz0EtgNdNcb96Z0u+Zyuy2g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
"@octokit/types": "^13.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request-error/node_modules/@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/request-error/node_modules/@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request/node_modules/@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/request/node_modules/@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest": {
|
||||
"version": "18.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz",
|
||||
"integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==",
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-21.1.1.tgz",
|
||||
"integrity": "sha512-sTQV7va0IUVZcntzy1q3QqPm/r8rWtDCqpRAmb8eXXnKkjoQEtFe3Nt5GTVsHft+R6jJoHeSiVLcgcvhtue/rg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/core": "^3.5.1",
|
||||
"@octokit/plugin-paginate-rest": "^2.16.8",
|
||||
"@octokit/plugin-request-log": "^1.0.4",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^5.12.0"
|
||||
"@octokit/core": "^6.1.4",
|
||||
"@octokit/plugin-paginate-rest": "^11.4.2",
|
||||
"@octokit/plugin-request-log": "^5.3.1",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^13.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/types": {
|
||||
@@ -234,9 +396,10 @@
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
|
||||
},
|
||||
"node_modules/before-after-hook": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
|
||||
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-3.0.2.tgz",
|
||||
"integrity": "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/bottleneck": {
|
||||
"version": "2.19.5",
|
||||
@@ -270,11 +433,6 @@
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/deprecation": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
|
||||
},
|
||||
"node_modules/discord-api-types": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.23.1.tgz",
|
||||
@@ -316,6 +474,22 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-content-type-parse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-2.0.1.tgz",
|
||||
"integrity": "sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/fastify"
|
||||
},
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/fastify"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-obj": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
|
||||
@@ -324,14 +498,6 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash.isequal": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
||||
@@ -375,14 +541,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/ow": {
|
||||
"version": "0.27.0",
|
||||
"resolved": "https://registry.npmjs.org/ow/-/ow-0.27.0.tgz",
|
||||
@@ -429,9 +587,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/universal-user-agent": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
|
||||
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz",
|
||||
"integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/vali-date": {
|
||||
"version": "1.0.0",
|
||||
@@ -455,11 +614,6 @@
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.17.1",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
|
||||
@@ -517,45 +671,86 @@
|
||||
}
|
||||
},
|
||||
"@octokit/auth-token": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
|
||||
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.0.3"
|
||||
}
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-5.1.2.tgz",
|
||||
"integrity": "sha512-JcQDsBdg49Yky2w2ld20IHAlwr8d/d8N6NiOXbtuoPCqzbsiJgF633mVUw3x4mo0H5ypataQIX7SFu3yy44Mpw=="
|
||||
},
|
||||
"@octokit/core": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz",
|
||||
"integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==",
|
||||
"version": "6.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.4.tgz",
|
||||
"integrity": "sha512-lAS9k7d6I0MPN+gb9bKDt7X8SdxknYqAMh44S5L+lNqIN2NuV8nvv3g8rPp7MuRxcOpxpUIATWprO0C34a8Qmg==",
|
||||
"requires": {
|
||||
"@octokit/auth-token": "^2.4.4",
|
||||
"@octokit/graphql": "^4.5.8",
|
||||
"@octokit/request": "^5.6.0",
|
||||
"@octokit/request-error": "^2.0.5",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"before-after-hook": "^2.2.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
"@octokit/auth-token": "^5.0.0",
|
||||
"@octokit/graphql": "^8.1.2",
|
||||
"@octokit/request": "^9.2.1",
|
||||
"@octokit/request-error": "^6.1.7",
|
||||
"@octokit/types": "^13.6.2",
|
||||
"before-after-hook": "^3.0.2",
|
||||
"universal-user-agent": "^7.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g=="
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"requires": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@octokit/endpoint": {
|
||||
"version": "6.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
|
||||
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
|
||||
"version": "10.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.3.tgz",
|
||||
"integrity": "sha512-nBRBMpKPhQUxCsQQeW+rCJ/OPSMcj3g0nfHn01zGYZXuNDvvXudF/TYY6APj5THlurerpFN4a/dQAIAaM6BYhA==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
"@octokit/types": "^13.6.2",
|
||||
"universal-user-agent": "^7.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g=="
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"requires": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@octokit/graphql": {
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
|
||||
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
|
||||
"version": "8.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-8.2.1.tgz",
|
||||
"integrity": "sha512-n57hXtOoHrhwTWdvhVkdJHdhTv0JstjDbDRhJfwIRNfFqmSo1DaK/mD2syoNUoLCyqSjBpGAKOG0BuwF392slw==",
|
||||
"requires": {
|
||||
"@octokit/request": "^5.6.0",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
"@octokit/request": "^9.2.2",
|
||||
"@octokit/types": "^13.8.0",
|
||||
"universal-user-agent": "^7.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g=="
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"requires": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@octokit/openapi-types": {
|
||||
@@ -564,26 +759,55 @@
|
||||
"integrity": "sha512-dWZfYvCCdjZzDYA3lIAMF72Q0jld8xidqCq5Ryw09eBJXZdcM6he0vWBTvw/b5UnGYqexxOyHWgfrsTlUJL3Gw=="
|
||||
},
|
||||
"@octokit/plugin-paginate-rest": {
|
||||
"version": "2.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.9.tgz",
|
||||
"integrity": "sha512-gfSCMgz5scFKsR0dW4jaYsDJVt/UwCHp4dF7sHlmSekZvwzvLiOAGZ4MQkEsL5DW9hIk2W+UQkYZMTA1b6Wsqw==",
|
||||
"version": "11.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.4.2.tgz",
|
||||
"integrity": "sha512-BXJ7XPCTDXFF+wxcg/zscfgw2O/iDPtNSkwwR1W1W5c4Mb3zav/M2XvxQ23nVmKj7jpweB4g8viMeCQdm7LMVA==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.33.0"
|
||||
"@octokit/types": "^13.7.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g=="
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"requires": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@octokit/plugin-request-log": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
|
||||
"integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==",
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-5.3.1.tgz",
|
||||
"integrity": "sha512-n/lNeCtq+9ofhC15xzmJCNKP2BWTv8Ih2TTy+jatNCCq/gQP/V7rK3fjIfuz0pDWDALO/o/4QY4hyOF6TQQFUw==",
|
||||
"requires": {}
|
||||
},
|
||||
"@octokit/plugin-rest-endpoint-methods": {
|
||||
"version": "5.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.12.1.tgz",
|
||||
"integrity": "sha512-0nY3htfl6x9UkPcqv8pm9vOC/bTA7f4IMDWln13neHRdNWQvOQgZ9fRxK7BAc74rye4yVINEFi9Yb9rnGUvosA==",
|
||||
"version": "13.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.3.1.tgz",
|
||||
"integrity": "sha512-o8uOBdsyR+WR8MK9Cco8dCgvG13H1RlM1nWnK/W7TEACQBFux/vPREgKucxUfuDQ5yi1T3hGf4C5ZmZXAERgwQ==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.33.0",
|
||||
"deprecation": "^2.3.1"
|
||||
"@octokit/types": "^13.8.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g=="
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"requires": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@octokit/plugin-retry": {
|
||||
@@ -596,46 +820,88 @@
|
||||
}
|
||||
},
|
||||
"@octokit/plugin-throttling": {
|
||||
"version": "3.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-3.7.0.tgz",
|
||||
"integrity": "sha512-qrKT1Yl/KuwGSC6/oHpLBot3ooC9rq0/ryDYBCpkRtoj+R8T47xTMDT6Tk2CxWopFota/8Pi/2SqArqwC0JPow==",
|
||||
"version": "9.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-9.4.0.tgz",
|
||||
"integrity": "sha512-IOlXxXhZA4Z3m0EEYtrrACkuHiArHLZ3CvqWwOez/pURNqRuwfoFlTPbN5Muf28pzFuztxPyiUiNwz8KctdZaQ==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.0.1",
|
||||
"@octokit/types": "^13.7.0",
|
||||
"bottleneck": "^2.15.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g=="
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"requires": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@octokit/request": {
|
||||
"version": "5.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz",
|
||||
"integrity": "sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==",
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.2.2.tgz",
|
||||
"integrity": "sha512-dZl0ZHx6gOQGcffgm1/Sf6JfEpmh34v3Af2Uci02vzUYz6qEN6zepoRtmybWXIGXFIK8K9ylE3b+duCWqhArtg==",
|
||||
"requires": {
|
||||
"@octokit/endpoint": "^6.0.1",
|
||||
"@octokit/request-error": "^2.1.0",
|
||||
"@octokit/types": "^6.16.1",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"node-fetch": "^2.6.1",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
"@octokit/endpoint": "^10.1.3",
|
||||
"@octokit/request-error": "^6.1.7",
|
||||
"@octokit/types": "^13.6.2",
|
||||
"fast-content-type-parse": "^2.0.0",
|
||||
"universal-user-agent": "^7.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g=="
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"requires": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@octokit/request-error": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
|
||||
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
|
||||
"version": "6.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.7.tgz",
|
||||
"integrity": "sha512-69NIppAwaauwZv6aOzb+VVLwt+0havz9GT5YplkeJv7fG7a40qpLt/yZKyiDxAhgz0EtgNdNcb96Z0u+Zyuy2g==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
"@octokit/types": "^13.6.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g=="
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"requires": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@octokit/rest": {
|
||||
"version": "18.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz",
|
||||
"integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==",
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-21.1.1.tgz",
|
||||
"integrity": "sha512-sTQV7va0IUVZcntzy1q3QqPm/r8rWtDCqpRAmb8eXXnKkjoQEtFe3Nt5GTVsHft+R6jJoHeSiVLcgcvhtue/rg==",
|
||||
"requires": {
|
||||
"@octokit/core": "^3.5.1",
|
||||
"@octokit/plugin-paginate-rest": "^2.16.8",
|
||||
"@octokit/plugin-request-log": "^1.0.4",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^5.12.0"
|
||||
"@octokit/core": "^6.1.4",
|
||||
"@octokit/plugin-paginate-rest": "^11.4.2",
|
||||
"@octokit/plugin-request-log": "^5.3.1",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^13.3.0"
|
||||
}
|
||||
},
|
||||
"@octokit/types": {
|
||||
@@ -675,9 +941,9 @@
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
|
||||
},
|
||||
"before-after-hook": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
|
||||
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-3.0.2.tgz",
|
||||
"integrity": "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A=="
|
||||
},
|
||||
"bottleneck": {
|
||||
"version": "2.19.5",
|
||||
@@ -702,11 +968,6 @@
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
|
||||
},
|
||||
"deprecation": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
|
||||
},
|
||||
"discord-api-types": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.23.1.tgz",
|
||||
@@ -735,16 +996,16 @@
|
||||
"is-obj": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"fast-content-type-parse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-2.0.1.tgz",
|
||||
"integrity": "sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q=="
|
||||
},
|
||||
"is-obj": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
|
||||
"integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="
|
||||
},
|
||||
"is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
|
||||
},
|
||||
"lodash.isequal": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
||||
@@ -771,14 +1032,6 @@
|
||||
"whatwg-url": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"ow": {
|
||||
"version": "0.27.0",
|
||||
"resolved": "https://registry.npmjs.org/ow/-/ow-0.27.0.tgz",
|
||||
@@ -813,9 +1066,9 @@
|
||||
"integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA=="
|
||||
},
|
||||
"universal-user-agent": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
|
||||
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz",
|
||||
"integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q=="
|
||||
},
|
||||
"vali-date": {
|
||||
"version": "1.0.0",
|
||||
@@ -836,11 +1089,6 @@
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"ws": {
|
||||
"version": "8.17.1",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@octokit/plugin-retry": "^3.0.9",
|
||||
"@octokit/plugin-throttling": "^3.5.2",
|
||||
"@octokit/rest": "^18.12.0",
|
||||
"@octokit/plugin-throttling": "^9.4.0",
|
||||
"@octokit/rest": "^21.1.1",
|
||||
"discord.js": "^13.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
337
.github/workflows/scripts/releases/generate-release-notes/package-lock.json
generated
vendored
337
.github/workflows/scripts/releases/generate-release-notes/package-lock.json
generated
vendored
@@ -1,22 +1,33 @@
|
||||
{
|
||||
"name": "generate-release-notes",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@octokit/auth-token": {
|
||||
"packages": {
|
||||
"": {
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@octokit/plugin-retry": "^3.0.9",
|
||||
"@octokit/plugin-throttling": "^3.5.2",
|
||||
"@octokit/rest": "^21.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/auth-token": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
|
||||
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3"
|
||||
}
|
||||
},
|
||||
"@octokit/core": {
|
||||
"node_modules/@octokit/core": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz",
|
||||
"integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@octokit/auth-token": "^2.4.4",
|
||||
"@octokit/graphql": "^4.5.8",
|
||||
"@octokit/request": "^5.6.0",
|
||||
@@ -26,76 +37,60 @@
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/endpoint": {
|
||||
"node_modules/@octokit/endpoint": {
|
||||
"version": "6.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
|
||||
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/graphql": {
|
||||
"node_modules/@octokit/graphql": {
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
|
||||
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@octokit/request": "^5.6.0",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/openapi-types": {
|
||||
"node_modules/@octokit/openapi-types": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.1.0.tgz",
|
||||
"integrity": "sha512-dWZfYvCCdjZzDYA3lIAMF72Q0jld8xidqCq5Ryw09eBJXZdcM6he0vWBTvw/b5UnGYqexxOyHWgfrsTlUJL3Gw=="
|
||||
},
|
||||
"@octokit/plugin-paginate-rest": {
|
||||
"version": "2.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.9.tgz",
|
||||
"integrity": "sha512-gfSCMgz5scFKsR0dW4jaYsDJVt/UwCHp4dF7sHlmSekZvwzvLiOAGZ4MQkEsL5DW9hIk2W+UQkYZMTA1b6Wsqw==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.33.0"
|
||||
}
|
||||
},
|
||||
"@octokit/plugin-request-log": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
|
||||
"integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA=="
|
||||
},
|
||||
"@octokit/plugin-rest-endpoint-methods": {
|
||||
"version": "5.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.12.1.tgz",
|
||||
"integrity": "sha512-0nY3htfl6x9UkPcqv8pm9vOC/bTA7f4IMDWln13neHRdNWQvOQgZ9fRxK7BAc74rye4yVINEFi9Yb9rnGUvosA==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.33.0",
|
||||
"deprecation": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"@octokit/plugin-retry": {
|
||||
"node_modules/@octokit/plugin-retry": {
|
||||
"version": "3.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-3.0.9.tgz",
|
||||
"integrity": "sha512-r+fArdP5+TG6l1Rv/C9hVoty6tldw6cE2pRHNGmFPdyfrc696R6JjrQ3d7HdVqGwuzfyrcaLAKD7K8TX8aehUQ==",
|
||||
"requires": {
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"bottleneck": "^2.15.3"
|
||||
}
|
||||
},
|
||||
"@octokit/plugin-throttling": {
|
||||
"node_modules/@octokit/plugin-throttling": {
|
||||
"version": "3.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-3.5.2.tgz",
|
||||
"integrity": "sha512-Eu7kfJxU8vmHqWGNszWpg+GVp2tnAfax3XQV5CkYPEE69C+KvInJXW9WajgSeW+cxYe0UVdouzCtcreGNuJo7A==",
|
||||
"requires": {
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.1",
|
||||
"bottleneck": "^2.15.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": "^3.5.0"
|
||||
}
|
||||
},
|
||||
"@octokit/request": {
|
||||
"node_modules/@octokit/request": {
|
||||
"version": "5.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz",
|
||||
"integrity": "sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@octokit/endpoint": "^6.0.1",
|
||||
"@octokit/request-error": "^2.1.0",
|
||||
"@octokit/types": "^6.16.1",
|
||||
@@ -104,99 +99,295 @@
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/request-error": {
|
||||
"node_modules/@octokit/request-error": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
|
||||
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"@octokit/rest": {
|
||||
"version": "18.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz",
|
||||
"integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==",
|
||||
"requires": {
|
||||
"@octokit/core": "^3.5.1",
|
||||
"@octokit/plugin-paginate-rest": "^2.16.8",
|
||||
"@octokit/plugin-request-log": "^1.0.4",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^5.12.0"
|
||||
"node_modules/@octokit/rest": {
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-21.1.1.tgz",
|
||||
"integrity": "sha512-sTQV7va0IUVZcntzy1q3QqPm/r8rWtDCqpRAmb8eXXnKkjoQEtFe3Nt5GTVsHft+R6jJoHeSiVLcgcvhtue/rg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/core": "^6.1.4",
|
||||
"@octokit/plugin-paginate-rest": "^11.4.2",
|
||||
"@octokit/plugin-request-log": "^5.3.1",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^13.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"@octokit/types": {
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/auth-token": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-5.1.2.tgz",
|
||||
"integrity": "sha512-JcQDsBdg49Yky2w2ld20IHAlwr8d/d8N6NiOXbtuoPCqzbsiJgF633mVUw3x4mo0H5ypataQIX7SFu3yy44Mpw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/core": {
|
||||
"version": "6.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.4.tgz",
|
||||
"integrity": "sha512-lAS9k7d6I0MPN+gb9bKDt7X8SdxknYqAMh44S5L+lNqIN2NuV8nvv3g8rPp7MuRxcOpxpUIATWprO0C34a8Qmg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/auth-token": "^5.0.0",
|
||||
"@octokit/graphql": "^8.1.2",
|
||||
"@octokit/request": "^9.2.1",
|
||||
"@octokit/request-error": "^6.1.7",
|
||||
"@octokit/types": "^13.6.2",
|
||||
"before-after-hook": "^3.0.2",
|
||||
"universal-user-agent": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/endpoint": {
|
||||
"version": "10.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.3.tgz",
|
||||
"integrity": "sha512-nBRBMpKPhQUxCsQQeW+rCJ/OPSMcj3g0nfHn01zGYZXuNDvvXudF/TYY6APj5THlurerpFN4a/dQAIAaM6BYhA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^13.6.2",
|
||||
"universal-user-agent": "^7.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/graphql": {
|
||||
"version": "8.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-8.2.1.tgz",
|
||||
"integrity": "sha512-n57hXtOoHrhwTWdvhVkdJHdhTv0JstjDbDRhJfwIRNfFqmSo1DaK/mD2syoNUoLCyqSjBpGAKOG0BuwF392slw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/request": "^9.2.2",
|
||||
"@octokit/types": "^13.8.0",
|
||||
"universal-user-agent": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/plugin-paginate-rest": {
|
||||
"version": "11.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.4.2.tgz",
|
||||
"integrity": "sha512-BXJ7XPCTDXFF+wxcg/zscfgw2O/iDPtNSkwwR1W1W5c4Mb3zav/M2XvxQ23nVmKj7jpweB4g8viMeCQdm7LMVA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^13.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/plugin-request-log": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-5.3.1.tgz",
|
||||
"integrity": "sha512-n/lNeCtq+9ofhC15xzmJCNKP2BWTv8Ih2TTy+jatNCCq/gQP/V7rK3fjIfuz0pDWDALO/o/4QY4hyOF6TQQFUw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/plugin-rest-endpoint-methods": {
|
||||
"version": "13.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.3.1.tgz",
|
||||
"integrity": "sha512-o8uOBdsyR+WR8MK9Cco8dCgvG13H1RlM1nWnK/W7TEACQBFux/vPREgKucxUfuDQ5yi1T3hGf4C5ZmZXAERgwQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^13.8.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/request": {
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.2.2.tgz",
|
||||
"integrity": "sha512-dZl0ZHx6gOQGcffgm1/Sf6JfEpmh34v3Af2Uci02vzUYz6qEN6zepoRtmybWXIGXFIK8K9ylE3b+duCWqhArtg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/endpoint": "^10.1.3",
|
||||
"@octokit/request-error": "^6.1.7",
|
||||
"@octokit/types": "^13.6.2",
|
||||
"fast-content-type-parse": "^2.0.0",
|
||||
"universal-user-agent": "^7.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/request-error": {
|
||||
"version": "6.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.7.tgz",
|
||||
"integrity": "sha512-69NIppAwaauwZv6aOzb+VVLwt+0havz9GT5YplkeJv7fG7a40qpLt/yZKyiDxAhgz0EtgNdNcb96Z0u+Zyuy2g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^13.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/before-after-hook": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-3.0.2.tgz",
|
||||
"integrity": "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/universal-user-agent": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz",
|
||||
"integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/@octokit/types": {
|
||||
"version": "6.33.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.33.0.tgz",
|
||||
"integrity": "sha512-0zffZ048M0UhthyPXQHLz4038Ak46nMWZXkzlXvXB/M/L1jYPBceq4iZj4qjKVrvveaJrrgKdJ9+3yUuITfcCw==",
|
||||
"requires": {
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^11.1.0"
|
||||
}
|
||||
},
|
||||
"before-after-hook": {
|
||||
"node_modules/before-after-hook": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
|
||||
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
|
||||
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==",
|
||||
"peer": true
|
||||
},
|
||||
"bottleneck": {
|
||||
"node_modules/bottleneck": {
|
||||
"version": "2.19.5",
|
||||
"resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz",
|
||||
"integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="
|
||||
},
|
||||
"deprecation": {
|
||||
"node_modules/deprecation": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==",
|
||||
"peer": true
|
||||
},
|
||||
"is-plain-object": {
|
||||
"node_modules/fast-content-type-parse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-2.0.1.tgz",
|
||||
"integrity": "sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/fastify"
|
||||
},
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/fastify"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node-fetch": {
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"once": {
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"tr46": {
|
||||
"node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
|
||||
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
|
||||
"peer": true
|
||||
},
|
||||
"universal-user-agent": {
|
||||
"node_modules/universal-user-agent": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
|
||||
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
|
||||
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==",
|
||||
"peer": true
|
||||
},
|
||||
"webidl-conversions": {
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
|
||||
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=",
|
||||
"peer": true
|
||||
},
|
||||
"whatwg-url": {
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"peer": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
"dependencies": {
|
||||
"@octokit/plugin-retry": "^3.0.9",
|
||||
"@octokit/plugin-throttling": "^3.5.2",
|
||||
"@octokit/rest": "^18.12.0"
|
||||
"@octokit/rest": "^21.1.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,15 +45,15 @@ cd "%BUILDDIR%"
|
||||
set FREETYPE=2.13.3
|
||||
set HARFBUZZ=10.0.1
|
||||
set LIBJPEG=9f
|
||||
set LIBPNG=1643
|
||||
set LIBPNG=1645
|
||||
set LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
|
||||
set QT=6.8.1
|
||||
set QT=6.8.2
|
||||
set QTMINOR=6.8
|
||||
set SDL=SDL2-2.30.11
|
||||
set WEBP=1.4.0
|
||||
set SDL=SDL3-3.2.6
|
||||
set WEBP=1.5.0
|
||||
set ZLIB=1.3.1
|
||||
set ZLIBSHORT=131
|
||||
set ZSTD=1.5.6
|
||||
set ZSTD=1.5.7
|
||||
|
||||
set SHADERC=2024.1
|
||||
set SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec
|
||||
@@ -62,19 +62,18 @@ set SHADERC_SPIRVTOOLS=dd4b663e13c07fea4fbb3f70c1c91c86731099f7
|
||||
|
||||
call :downloadfile "freetype-%FREETYPE%.tar.gz" https://sourceforge.net/projects/freetype/files/freetype2/%FREETYPE%/freetype-%FREETYPE%.tar.gz/download 5c3a8e78f7b24c20b25b54ee575d6daa40007a5f4eea2845861c3409b3021747 || goto error
|
||||
call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuzz/archive/refs/tags/%HARFBUZZ%.zip 8adf9f5a4b6022aa2744f45c89ce347df46fea8403e99f01d650b11c417d0aa8 || goto error
|
||||
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1643.zip fc466a1e638e635d6c66363bdf3f38555b81b0141d0b06ba45b49ccca327436d || goto error
|
||||
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1645.zip a66c4b1350b67776e90263e2550933067cd9ccbd318db489f84dcc0d2b033249 || goto error
|
||||
call :downloadfile "jpegsr%LIBJPEG%.zip" https://ijg.org/files/jpegsr%LIBJPEG%.zip 6255da8c89e09d694e6800688c76145eb6870a76ac0d36c74fccd61b3940aafa || goto error
|
||||
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 61f873ec69e3be1b99535634340d5bde750b2e4447caa1db9f61be3fd49ab1e5 || goto error
|
||||
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c || goto error
|
||||
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/%LZ4%.zip" 0c33119688d6b180c7e760b0acd70059222389cfd581632623784bee27e51a31 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" a0b3e7ac5f708042683ff0f22e069bdf75563540c615f9854ecc9bc8913e2488 || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" e22d997bd15b795a176c8da62c8c1da0a674eb534e02f7c01ca507bf11bce0c3 || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 247a0a58039275a5a4fb499a600a90f66dc6e00321bb6f86a9b8d8020344d853 || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 57bd332e5550ff70a852560c591b786b6ba587c5e41cb5ef91038d82db137ab9 || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" c65a89140f5d68137ffec67d631ec97002fb37077d9b4eb4ee45cbec39b1c38a || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 30a8e7773e1f274557e049a97f158b808f344247da03ae5240e4956c81d51cd5 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 665e5aa2a613affe099a38d61257ecc5ef4bf38b109d915147aa8b005399d68a || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 44087aec0caa4aa81437e787917d29d97536484a682a5d51ec035878e57c0b5c || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 83c72b5dfad04854acf61d592e3f9cdc2ed894779aab8d0470d966715266caaf || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 144d55e4d199793a76c53f19872633a79aec0314039f6f99b6a10b5be7a78fbf || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" 102539447c1c76d206f24bcca2c911270cf53991548d9c3d7d0d01855f651e3b || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 33ccac9f99a357ffd83cb2d7179a0c0ffcba85a14d23d86619d5dc9721ded42f || goto error
|
||||
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://zlib.net/zlib%ZLIBSHORT%.zip" 72af66d44fcc14c22013b46b814d5d2514673dda3d115e64b690c1ad636e7b17 || goto error
|
||||
call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 3b1c3b46e416d36931efd34663122d7f51b550c87f74de2d38249516fe7d8be5 || goto error
|
||||
call :downloadfile "zstd-fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch" https://github.com/facebook/zstd/commit/fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch 8df152f4969b308546306c074628de761f0b80265de7de534e3822fab22d7535 || goto error
|
||||
call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 7897bc5d620580d9b7cd3539c44b59d78f3657d33663fe97a145e07b4ebd69a4 || goto error
|
||||
|
||||
call :downloadfile "shaderc-%SHADERC%.zip" "https://github.com/google/shaderc/archive/refs/tags/v%SHADERC%.zip" 6c9f42ed6bf42750f5369b089909abfdcf0101488b4a1f41116d5159d00af8e7 || goto error
|
||||
call :downloadfile "shaderc-glslang-%SHADERC_GLSLANG%.zip" "https://github.com/KhronosGroup/glslang/archive/%SHADERC_GLSLANG%.zip" 03ad8a6fa987af4653d0cfe6bdaed41bcf617f1366a151fb1574da75950cd3e8 || goto error
|
||||
@@ -159,7 +158,6 @@ echo Building Zstandard...
|
||||
rmdir /S /Q "zstd-%ZSTD%"
|
||||
%SEVENZIP% x "-x^!zstd-%ZSTD%\tests\cli-tests\bin" "zstd-%ZSTD%.zip" || goto error
|
||||
cd "zstd-%ZSTD%"
|
||||
%PATCH% -p1 < "..\zstd-fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch" || goto error
|
||||
cmake %ARM64TOOLCHAIN% -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DZSTD_BUILD_SHARED=ON -DZSTD_BUILD_STATIC=OFF -DZSTD_BUILD_PROGRAMS=OFF -B build -G Ninja build/cmake
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
@@ -181,7 +179,7 @@ cd "%SDL%" || goto error
|
||||
cmake -B build %ARM64TOOLCHAIN% -DCMAKE_BUILD_TYPE=Release %FORCEPDB% -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DSDL_SHARED=ON -DSDL_STATIC=OFF -G Ninja || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
copy build\SDL2.pdb "%INSTALLDIR%\bin" || goto error
|
||||
copy build\SDL3.pdb "%INSTALLDIR%\bin" || goto error
|
||||
cd .. || goto error
|
||||
|
||||
if %DEBUG%==1 (
|
||||
|
||||
@@ -43,15 +43,15 @@ cd "%BUILDDIR%"
|
||||
set FREETYPE=2.13.3
|
||||
set HARFBUZZ=10.0.1
|
||||
set LIBJPEG=9f
|
||||
set LIBPNG=1643
|
||||
set LIBPNG=1645
|
||||
set LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
|
||||
set QT=6.8.1
|
||||
set QT=6.8.2
|
||||
set QTMINOR=6.8
|
||||
set SDL=SDL2-2.30.11
|
||||
set WEBP=1.4.0
|
||||
set SDL=SDL3-3.2.6
|
||||
set WEBP=1.5.0
|
||||
set ZLIB=1.3.1
|
||||
set ZLIBSHORT=131
|
||||
set ZSTD=1.5.6
|
||||
set ZSTD=1.5.7
|
||||
|
||||
set SHADERC=2024.1
|
||||
set SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec
|
||||
@@ -60,19 +60,18 @@ set SHADERC_SPIRVTOOLS=dd4b663e13c07fea4fbb3f70c1c91c86731099f7
|
||||
|
||||
call :downloadfile "freetype-%FREETYPE%.tar.gz" https://sourceforge.net/projects/freetype/files/freetype2/%FREETYPE%/freetype-%FREETYPE%.tar.gz/download 5c3a8e78f7b24c20b25b54ee575d6daa40007a5f4eea2845861c3409b3021747 || goto error
|
||||
call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuzz/archive/refs/tags/%HARFBUZZ%.zip 8adf9f5a4b6022aa2744f45c89ce347df46fea8403e99f01d650b11c417d0aa8 || goto error
|
||||
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1643.zip fc466a1e638e635d6c66363bdf3f38555b81b0141d0b06ba45b49ccca327436d || goto error
|
||||
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1645.zip a66c4b1350b67776e90263e2550933067cd9ccbd318db489f84dcc0d2b033249 || goto error
|
||||
call :downloadfile "jpegsr%LIBJPEG%.zip" https://ijg.org/files/jpegsr%LIBJPEG%.zip 6255da8c89e09d694e6800688c76145eb6870a76ac0d36c74fccd61b3940aafa || goto error
|
||||
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 61f873ec69e3be1b99535634340d5bde750b2e4447caa1db9f61be3fd49ab1e5 || goto error
|
||||
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c || goto error
|
||||
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/%LZ4%.zip" 0c33119688d6b180c7e760b0acd70059222389cfd581632623784bee27e51a31 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" a0b3e7ac5f708042683ff0f22e069bdf75563540c615f9854ecc9bc8913e2488 || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" e22d997bd15b795a176c8da62c8c1da0a674eb534e02f7c01ca507bf11bce0c3 || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 247a0a58039275a5a4fb499a600a90f66dc6e00321bb6f86a9b8d8020344d853 || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 57bd332e5550ff70a852560c591b786b6ba587c5e41cb5ef91038d82db137ab9 || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" c65a89140f5d68137ffec67d631ec97002fb37077d9b4eb4ee45cbec39b1c38a || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 30a8e7773e1f274557e049a97f158b808f344247da03ae5240e4956c81d51cd5 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 665e5aa2a613affe099a38d61257ecc5ef4bf38b109d915147aa8b005399d68a || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 44087aec0caa4aa81437e787917d29d97536484a682a5d51ec035878e57c0b5c || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 83c72b5dfad04854acf61d592e3f9cdc2ed894779aab8d0470d966715266caaf || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 144d55e4d199793a76c53f19872633a79aec0314039f6f99b6a10b5be7a78fbf || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" 102539447c1c76d206f24bcca2c911270cf53991548d9c3d7d0d01855f651e3b || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 33ccac9f99a357ffd83cb2d7179a0c0ffcba85a14d23d86619d5dc9721ded42f || goto error
|
||||
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://zlib.net/zlib%ZLIBSHORT%.zip" 72af66d44fcc14c22013b46b814d5d2514673dda3d115e64b690c1ad636e7b17 || goto error
|
||||
call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 3b1c3b46e416d36931efd34663122d7f51b550c87f74de2d38249516fe7d8be5 || goto error
|
||||
call :downloadfile "zstd-fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch" https://github.com/facebook/zstd/commit/fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch 8df152f4969b308546306c074628de761f0b80265de7de534e3822fab22d7535 || goto error
|
||||
call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 7897bc5d620580d9b7cd3539c44b59d78f3657d33663fe97a145e07b4ebd69a4 || goto error
|
||||
|
||||
call :downloadfile "shaderc-%SHADERC%.zip" "https://github.com/google/shaderc/archive/refs/tags/v%SHADERC%.zip" 6c9f42ed6bf42750f5369b089909abfdcf0101488b4a1f41116d5159d00af8e7 || goto error
|
||||
call :downloadfile "shaderc-glslang-%SHADERC_GLSLANG%.zip" "https://github.com/KhronosGroup/glslang/archive/%SHADERC_GLSLANG%.zip" 03ad8a6fa987af4653d0cfe6bdaed41bcf617f1366a151fb1574da75950cd3e8 || goto error
|
||||
@@ -156,7 +155,6 @@ echo Building Zstandard...
|
||||
rmdir /S /Q "zstd-%ZSTD%"
|
||||
%SEVENZIP% x "-x^!zstd-%ZSTD%\tests\cli-tests\bin" "zstd-%ZSTD%.zip" || goto error
|
||||
cd "zstd-%ZSTD%"
|
||||
%PATCH% -p1 < "..\zstd-fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch" || goto error
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DZSTD_BUILD_SHARED=ON -DZSTD_BUILD_STATIC=OFF -DZSTD_BUILD_PROGRAMS=OFF -B build -G Ninja build/cmake
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
@@ -178,7 +176,7 @@ cd "%SDL%" || goto error
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=Release %FORCEPDB% -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DSDL_SHARED=ON -DSDL_STATIC=OFF -G Ninja || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
copy build\SDL2.pdb "%INSTALLDIR%\bin" || goto error
|
||||
copy build\SDL3.pdb "%INSTALLDIR%\bin" || goto error
|
||||
cd .. || goto error
|
||||
|
||||
if %DEBUG%==1 (
|
||||
|
||||
2
.github/workflows/windows_build_matrix.yml
vendored
2
.github/workflows/windows_build_matrix.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
lint_vs_proj_files:
|
||||
name: Lint VS Project Files
|
||||
if: github.repository != 'PCSX2/pcsx2' || github.event_name == 'pull_request'
|
||||
runs-on: windows-2019
|
||||
runs-on: windows-2025
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
28
.github/workflows/windows_build_qt.yml
vendored
28
.github/workflows/windows_build_qt.yml
vendored
@@ -12,7 +12,7 @@ on:
|
||||
os:
|
||||
required: false
|
||||
type: string
|
||||
default: windows-2022
|
||||
default: windows-2025
|
||||
platform:
|
||||
required: false
|
||||
type: string
|
||||
@@ -55,13 +55,31 @@ jobs:
|
||||
POWERSHELL_TELEMETRY_OPTOUT: 1
|
||||
|
||||
steps:
|
||||
- name: Tempfix Clang
|
||||
if: inputs.configuration == 'CMake'
|
||||
run: choco uninstall llvm
|
||||
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Configure MSBuild Clang Version
|
||||
if: inputs.configuration != 'CMake'
|
||||
shell: pwsh
|
||||
run: |
|
||||
[string[]] $clang_cl = &clang-cl.exe --version
|
||||
|
||||
$version = [Regex]::Match($clang_cl[0], "(\d+\.\d+\.\d+)")
|
||||
$path = $clang_cl[3].TrimStart("InstalledDir: ").TrimEnd("\bin")
|
||||
|
||||
$output = @"
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<LLVMInstallDir>$path</LLVMInstallDir>
|
||||
<LLVMToolsVersion>$version</LLVMToolsVersion>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
"@
|
||||
|
||||
Write-Host $output
|
||||
|
||||
$output | Out-File Directory.build.props
|
||||
|
||||
# actions/checkout elides tags, fetch them primarily for releases
|
||||
- name: Fetch Tags
|
||||
if: ${{ inputs.fetchTags }}
|
||||
|
||||
11
3rdparty/cpuinfo/include/cpuinfo.h
vendored
11
3rdparty/cpuinfo/include/cpuinfo.h
vendored
@@ -419,6 +419,8 @@ enum cpuinfo_uarch {
|
||||
cpuinfo_uarch_zen3 = 0x0020010B,
|
||||
/** AMD Zen 4 microarchitecture. */
|
||||
cpuinfo_uarch_zen4 = 0x0020010C,
|
||||
/** AMD Zen 5 microarchitecture. */
|
||||
cpuinfo_uarch_zen5 = 0x0020010D,
|
||||
|
||||
/** NSC Geode and AMD Geode GX and LX. */
|
||||
cpuinfo_uarch_geode = 0x00200200,
|
||||
@@ -818,6 +820,7 @@ struct cpuinfo_x86_isa {
|
||||
bool avx512vp2intersect;
|
||||
bool avx512_4vnniw;
|
||||
bool avx512_4fmaps;
|
||||
bool avx10_1;
|
||||
bool amx_bf16;
|
||||
bool amx_tile;
|
||||
bool amx_int8;
|
||||
@@ -1433,6 +1436,14 @@ static inline bool cpuinfo_has_x86_avx_ne_convert(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool cpuinfo_has_x86_avx10_1(void) {
|
||||
#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
|
||||
return cpuinfo_isa.avx10_1;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool cpuinfo_has_x86_hle(void) {
|
||||
#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
|
||||
return cpuinfo_isa.hle;
|
||||
|
||||
3
3rdparty/cpuinfo/src/arm/cache.c
vendored
3
3rdparty/cpuinfo/src/arm/cache.c
vendored
@@ -1341,7 +1341,8 @@ void cpuinfo_arm_decode_cache(
|
||||
* information, please refer to the technical manuals
|
||||
* linked above
|
||||
*/
|
||||
const uint32_t min_l2_size_KB = uarch == cpuinfo_uarch_neoverse_v2 ? 1024 : 256;
|
||||
const uint32_t min_l2_size_KB =
|
||||
(uarch == cpuinfo_uarch_neoverse_v2 || midr_is_ampere_altra(midr)) ? 1024 : 256;
|
||||
const uint32_t min_l3_size_KB = 0;
|
||||
|
||||
*l1i = (struct cpuinfo_cache){
|
||||
|
||||
6
3rdparty/cpuinfo/src/arm/midr.h
vendored
6
3rdparty/cpuinfo/src/arm/midr.h
vendored
@@ -34,6 +34,7 @@
|
||||
#define CPUINFO_ARM_MIDR_KRYO_SILVER_820 UINT32_C(0x510F2110)
|
||||
#define CPUINFO_ARM_MIDR_EXYNOS_M1_M2 UINT32_C(0x530F0010)
|
||||
#define CPUINFO_ARM_MIDR_DENVER2 UINT32_C(0x4E0F0030)
|
||||
#define CPUINFO_ARM_MIDR_AMPERE_ALTRA UINT32_C(0x413fd0c1)
|
||||
|
||||
inline static uint32_t midr_set_implementer(uint32_t midr, uint32_t implementer) {
|
||||
return (midr & ~CPUINFO_ARM_MIDR_IMPLEMENTER_MASK) |
|
||||
@@ -167,6 +168,11 @@ inline static bool midr_is_kryo_gold(uint32_t midr) {
|
||||
return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_KRYO_GOLD & uarch_mask);
|
||||
}
|
||||
|
||||
inline static bool midr_is_ampere_altra(uint32_t midr) {
|
||||
const uint32_t uarch_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
|
||||
return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_AMPERE_ALTRA & uarch_mask);
|
||||
}
|
||||
|
||||
inline static uint32_t midr_score_core(uint32_t midr) {
|
||||
const uint32_t core_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
|
||||
switch (midr & core_mask) {
|
||||
|
||||
5
3rdparty/cpuinfo/src/x86/isa.c
vendored
5
3rdparty/cpuinfo/src/x86/isa.c
vendored
@@ -429,6 +429,11 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa(
|
||||
*/
|
||||
isa.avx512f = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x00010000));
|
||||
|
||||
/*
|
||||
* AVX 10.1 instructions:
|
||||
*/
|
||||
isa.avx10_1 = avx512_regs && !!(structured_feature_info1.edx & UINT32_C(0x00080000));
|
||||
|
||||
/*
|
||||
* AVX512PF instructions:
|
||||
* - Intel: ebx[bit 26] in structured feature info (ecx = 0).
|
||||
|
||||
2
3rdparty/cpuinfo/src/x86/uarch.c
vendored
2
3rdparty/cpuinfo/src/x86/uarch.c
vendored
@@ -387,6 +387,8 @@ enum cpuinfo_uarch cpuinfo_x86_decode_uarch(
|
||||
return cpuinfo_uarch_zen4;
|
||||
}
|
||||
break;
|
||||
case 0x1a:
|
||||
return cpuinfo_uarch_zen5;
|
||||
}
|
||||
break;
|
||||
case cpuinfo_vendor_hygon:
|
||||
|
||||
220
3rdparty/fmt/CMakeLists.txt
vendored
220
3rdparty/fmt/CMakeLists.txt
vendored
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.8...3.26)
|
||||
cmake_minimum_required(VERSION 3.8...3.28)
|
||||
|
||||
# Fallback for using newer policies on CMake <3.12.
|
||||
if (${CMAKE_VERSION} VERSION_LESS 3.12)
|
||||
@@ -36,6 +36,12 @@ function(enable_module target)
|
||||
endif ()
|
||||
endfunction()
|
||||
|
||||
set(FMT_USE_CMAKE_MODULES FALSE)
|
||||
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.28 AND
|
||||
CMAKE_GENERATOR STREQUAL "Ninja")
|
||||
set(FMT_USE_CMAKE_MODULES TRUE)
|
||||
endif ()
|
||||
|
||||
# Adds a library compiled with C++20 module support.
|
||||
# `enabled` is a CMake variables that specifies if modules are enabled.
|
||||
# If modules are disabled `add_module_library` falls back to creating a
|
||||
@@ -53,6 +59,7 @@ function(add_module_library name)
|
||||
if (NOT ${${AML_IF}})
|
||||
# Create a non-modular library.
|
||||
target_sources(${name} PRIVATE ${AML_FALLBACK})
|
||||
set_target_properties(${name} PROPERTIES CXX_SCAN_FOR_MODULES OFF)
|
||||
return()
|
||||
endif ()
|
||||
|
||||
@@ -62,48 +69,55 @@ function(add_module_library name)
|
||||
target_compile_options(${name} PUBLIC -fmodules-ts)
|
||||
endif ()
|
||||
|
||||
# `std` is affected by CMake options and may be higher than C++20.
|
||||
get_target_property(std ${name} CXX_STANDARD)
|
||||
target_compile_definitions(${name} PRIVATE FMT_MODULE)
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(pcms)
|
||||
foreach (src ${sources})
|
||||
get_filename_component(pcm ${src} NAME_WE)
|
||||
set(pcm ${pcm}.pcm)
|
||||
if (FMT_USE_CMAKE_MODULES)
|
||||
target_sources(${name} PUBLIC FILE_SET fmt TYPE CXX_MODULES
|
||||
FILES ${sources})
|
||||
else()
|
||||
# `std` is affected by CMake options and may be higher than C++20.
|
||||
get_target_property(std ${name} CXX_STANDARD)
|
||||
|
||||
# Propagate -fmodule-file=*.pcm to targets that link with this library.
|
||||
target_compile_options(
|
||||
${name} PUBLIC -fmodule-file=${CMAKE_CURRENT_BINARY_DIR}/${pcm})
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(pcms)
|
||||
foreach (src ${sources})
|
||||
get_filename_component(pcm ${src} NAME_WE)
|
||||
set(pcm ${pcm}.pcm)
|
||||
|
||||
# Use an absolute path to prevent target_link_libraries prepending -l
|
||||
# to it.
|
||||
set(pcms ${pcms} ${CMAKE_CURRENT_BINARY_DIR}/${pcm})
|
||||
add_custom_command(
|
||||
OUTPUT ${pcm}
|
||||
COMMAND ${CMAKE_CXX_COMPILER}
|
||||
-std=c++${std} -x c++-module --precompile -c
|
||||
-o ${pcm} ${CMAKE_CURRENT_SOURCE_DIR}/${src}
|
||||
"-I$<JOIN:$<TARGET_PROPERTY:${name},INCLUDE_DIRECTORIES>,;-I>"
|
||||
# Required by the -I generator expression above.
|
||||
COMMAND_EXPAND_LISTS
|
||||
DEPENDS ${src})
|
||||
endforeach ()
|
||||
# Propagate -fmodule-file=*.pcm to targets that link with this library.
|
||||
target_compile_options(
|
||||
${name} PUBLIC -fmodule-file=${CMAKE_CURRENT_BINARY_DIR}/${pcm})
|
||||
|
||||
# Add .pcm files as sources to make sure they are built before the library.
|
||||
set(sources)
|
||||
foreach (pcm ${pcms})
|
||||
get_filename_component(pcm_we ${pcm} NAME_WE)
|
||||
set(obj ${pcm_we}.o)
|
||||
# Use an absolute path to prevent target_link_libraries prepending -l.
|
||||
set(sources ${sources} ${pcm} ${CMAKE_CURRENT_BINARY_DIR}/${obj})
|
||||
add_custom_command(
|
||||
OUTPUT ${obj}
|
||||
COMMAND ${CMAKE_CXX_COMPILER} $<TARGET_PROPERTY:${name},COMPILE_OPTIONS>
|
||||
-c -o ${obj} ${pcm}
|
||||
DEPENDS ${pcm})
|
||||
endforeach ()
|
||||
endif ()
|
||||
target_sources(${name} PRIVATE ${sources})
|
||||
# Use an absolute path to prevent target_link_libraries prepending -l
|
||||
# to it.
|
||||
set(pcms ${pcms} ${CMAKE_CURRENT_BINARY_DIR}/${pcm})
|
||||
add_custom_command(
|
||||
OUTPUT ${pcm}
|
||||
COMMAND ${CMAKE_CXX_COMPILER}
|
||||
-std=c++${std} -x c++-module --precompile -c
|
||||
-o ${pcm} ${CMAKE_CURRENT_SOURCE_DIR}/${src}
|
||||
"-I$<JOIN:$<TARGET_PROPERTY:${name},INCLUDE_DIRECTORIES>,;-I>"
|
||||
# Required by the -I generator expression above.
|
||||
COMMAND_EXPAND_LISTS
|
||||
DEPENDS ${src})
|
||||
endforeach ()
|
||||
|
||||
# Add .pcm files as sources to make sure they are built before the library.
|
||||
set(sources)
|
||||
foreach (pcm ${pcms})
|
||||
get_filename_component(pcm_we ${pcm} NAME_WE)
|
||||
set(obj ${pcm_we}.o)
|
||||
# Use an absolute path to prevent target_link_libraries prepending -l.
|
||||
set(sources ${sources} ${pcm} ${CMAKE_CURRENT_BINARY_DIR}/${obj})
|
||||
add_custom_command(
|
||||
OUTPUT ${obj}
|
||||
COMMAND ${CMAKE_CXX_COMPILER} $<TARGET_PROPERTY:${name},COMPILE_OPTIONS>
|
||||
-c -o ${obj} ${pcm}
|
||||
DEPENDS ${pcm})
|
||||
endforeach ()
|
||||
endif ()
|
||||
target_sources(${name} PRIVATE ${sources})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
include(CMakeParseArguments)
|
||||
@@ -145,21 +159,33 @@ option(FMT_WERROR "Halt the compilation with an error on compiler warnings."
|
||||
OFF)
|
||||
|
||||
# Options that control generation of various targets.
|
||||
option(FMT_DOC "Generate the doc target." ${FMT_MASTER_PROJECT})
|
||||
option(FMT_INSTALL "Generate the install target." ON)
|
||||
option(FMT_TEST "Generate the test target." ${FMT_MASTER_PROJECT})
|
||||
option(FMT_FUZZ "Generate the fuzz target." OFF)
|
||||
option(FMT_OS "Include core requiring OS (Windows/Posix) " ON)
|
||||
option(FMT_CUDA_TEST "Generate the cuda-test target." OFF)
|
||||
option(FMT_OS "Include OS-specific APIs." ON)
|
||||
option(FMT_MODULE "Build a module instead of a traditional library." OFF)
|
||||
option(FMT_SYSTEM_HEADERS "Expose headers with marking them as system." OFF)
|
||||
option(FMT_UNICODE "Enable Unicode support." ON)
|
||||
|
||||
if (FMT_TEST AND FMT_MODULE)
|
||||
# The tests require {fmt} to be compiled as traditional library
|
||||
message(STATUS "Testing is incompatible with build mode 'module'.")
|
||||
endif ()
|
||||
set(FMT_SYSTEM_HEADERS_ATTRIBUTE "")
|
||||
if (FMT_SYSTEM_HEADERS)
|
||||
set(FMT_SYSTEM_HEADERS_ATTRIBUTE SYSTEM)
|
||||
endif ()
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "MSDOS")
|
||||
set(FMT_TEST OFF)
|
||||
message(STATUS "MSDOS is incompatible with gtest")
|
||||
endif ()
|
||||
|
||||
# Get version from core.h
|
||||
file(READ include/fmt/core.h core_h)
|
||||
if (NOT core_h MATCHES "FMT_VERSION ([0-9]+)([0-9][0-9])([0-9][0-9])")
|
||||
message(FATAL_ERROR "Cannot get FMT_VERSION from core.h.")
|
||||
# Get version from base.h
|
||||
file(READ include/fmt/base.h base_h)
|
||||
if (NOT base_h MATCHES "FMT_VERSION ([0-9]+)([0-9][0-9])([0-9][0-9])")
|
||||
message(FATAL_ERROR "Cannot get FMT_VERSION from base.h.")
|
||||
endif ()
|
||||
# Use math to skip leading zeros if any.
|
||||
math(EXPR CPACK_PACKAGE_VERSION_MAJOR ${CMAKE_MATCH_1})
|
||||
@@ -167,7 +193,7 @@ math(EXPR CPACK_PACKAGE_VERSION_MINOR ${CMAKE_MATCH_2})
|
||||
math(EXPR CPACK_PACKAGE_VERSION_PATCH ${CMAKE_MATCH_3})
|
||||
join(FMT_VERSION ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.
|
||||
${CPACK_PACKAGE_VERSION_PATCH})
|
||||
message(STATUS "Version: ${FMT_VERSION}")
|
||||
message(STATUS "{fmt} version: ${FMT_VERSION}")
|
||||
|
||||
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
|
||||
|
||||
@@ -214,7 +240,13 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
endif ()
|
||||
if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0)
|
||||
set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wshift-overflow=2
|
||||
-Wnull-dereference -Wduplicated-cond)
|
||||
-Wduplicated-cond)
|
||||
# Workaround for GCC regression
|
||||
# [12/13/14/15 regression] New (since gcc 12) false positive null-dereference in vector.resize
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108860
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.0)
|
||||
set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wnull-dereference)
|
||||
endif ()
|
||||
endif ()
|
||||
set(WERROR_FLAG -Werror)
|
||||
endif ()
|
||||
@@ -263,13 +295,10 @@ function(add_headers VAR)
|
||||
endfunction()
|
||||
|
||||
# Define the fmt library, its includes and the needed defines.
|
||||
add_headers(FMT_HEADERS args.h chrono.h color.h compile.h core.h format.h
|
||||
add_headers(FMT_HEADERS args.h base.h chrono.h color.h compile.h core.h format.h
|
||||
format-inl.h os.h ostream.h printf.h ranges.h std.h
|
||||
xchar.h)
|
||||
set(FMT_SOURCES src/format.cc)
|
||||
if (FMT_OS)
|
||||
set(FMT_SOURCES ${FMT_SOURCES} src/os.cc)
|
||||
endif ()
|
||||
|
||||
add_module_library(fmt src/fmt.cc FALLBACK
|
||||
${FMT_SOURCES} ${FMT_HEADERS} README.md ChangeLog.md
|
||||
@@ -277,6 +306,10 @@ add_module_library(fmt src/fmt.cc FALLBACK
|
||||
add_library(fmt::fmt ALIAS fmt)
|
||||
if (FMT_MODULE)
|
||||
enable_module(fmt)
|
||||
elseif (FMT_OS)
|
||||
target_sources(fmt PRIVATE src/os.cc)
|
||||
else()
|
||||
target_compile_definitions(fmt PRIVATE FMT_OS=0)
|
||||
endif ()
|
||||
|
||||
if (FMT_WERROR)
|
||||
@@ -292,7 +325,7 @@ else ()
|
||||
message(WARNING "Feature cxx_std_11 is unknown for the CXX compiler")
|
||||
endif ()
|
||||
|
||||
target_include_directories(fmt ${FMT_SYSTEM_HEADERS_ATTRIBUTE} PUBLIC
|
||||
target_include_directories(fmt ${FMT_SYSTEM_HEADERS_ATTRIBUTE} BEFORE PUBLIC
|
||||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:${FMT_INC_DIR}>)
|
||||
|
||||
@@ -328,11 +361,21 @@ endif ()
|
||||
add_library(fmt-header-only INTERFACE)
|
||||
add_library(fmt::fmt-header-only ALIAS fmt-header-only)
|
||||
|
||||
if (NOT MSVC)
|
||||
# Unicode is always supported on compilers other than MSVC.
|
||||
elseif (FMT_UNICODE)
|
||||
# Unicode support requires compiling with /utf-8.
|
||||
target_compile_options(fmt PUBLIC $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CXX_COMPILER_ID:MSVC>>:/utf-8>)
|
||||
target_compile_options(fmt-header-only INTERFACE $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CXX_COMPILER_ID:MSVC>>:/utf-8>)
|
||||
else ()
|
||||
target_compile_definitions(fmt PUBLIC FMT_UNICODE=0)
|
||||
endif ()
|
||||
|
||||
target_compile_definitions(fmt-header-only INTERFACE FMT_HEADER_ONLY=1)
|
||||
target_compile_features(fmt-header-only INTERFACE cxx_std_11)
|
||||
|
||||
target_include_directories(fmt-header-only
|
||||
${FMT_SYSTEM_HEADERS_ATTRIBUTE} INTERFACE
|
||||
${FMT_SYSTEM_HEADERS_ATTRIBUTE} BEFORE INTERFACE
|
||||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:${FMT_INC_DIR}>)
|
||||
|
||||
@@ -377,12 +420,20 @@ if (FMT_INSTALL)
|
||||
|
||||
set(INSTALL_TARGETS fmt fmt-header-only)
|
||||
|
||||
set(INSTALL_FILE_SET)
|
||||
if (FMT_USE_CMAKE_MODULES)
|
||||
set(INSTALL_FILE_SET FILE_SET fmt DESTINATION "${FMT_INC_DIR}/fmt")
|
||||
endif()
|
||||
|
||||
# Install the library and headers.
|
||||
install(TARGETS ${INSTALL_TARGETS} EXPORT ${targets_export_name}
|
||||
install(TARGETS ${INSTALL_TARGETS}
|
||||
COMPONENT fmt-core
|
||||
EXPORT ${targets_export_name}
|
||||
LIBRARY DESTINATION ${FMT_LIB_DIR}
|
||||
ARCHIVE DESTINATION ${FMT_LIB_DIR}
|
||||
PUBLIC_HEADER DESTINATION "${FMT_INC_DIR}/fmt"
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
${INSTALL_FILE_SET})
|
||||
|
||||
# Use a namespace because CMake provides better diagnostics for namespaced
|
||||
# imported targets.
|
||||
@@ -390,13 +441,61 @@ if (FMT_INSTALL)
|
||||
FILE ${PROJECT_BINARY_DIR}/${targets_export_name}.cmake)
|
||||
|
||||
# Install version, config and target files.
|
||||
install(
|
||||
FILES ${project_config} ${version_config}
|
||||
DESTINATION ${FMT_CMAKE_DIR})
|
||||
install(FILES ${project_config} ${version_config}
|
||||
DESTINATION ${FMT_CMAKE_DIR}
|
||||
COMPONENT fmt-core)
|
||||
install(EXPORT ${targets_export_name} DESTINATION ${FMT_CMAKE_DIR}
|
||||
NAMESPACE fmt::)
|
||||
NAMESPACE fmt::
|
||||
COMPONENT fmt-core)
|
||||
|
||||
install(FILES "${pkgconfig}" DESTINATION "${FMT_PKGCONFIG_DIR}")
|
||||
install(FILES "${pkgconfig}" DESTINATION "${FMT_PKGCONFIG_DIR}"
|
||||
COMPONENT fmt-core)
|
||||
endif ()
|
||||
|
||||
function(add_doc_target)
|
||||
find_program(DOXYGEN doxygen
|
||||
PATHS "$ENV{ProgramFiles}/doxygen/bin"
|
||||
"$ENV{ProgramFiles\(x86\)}/doxygen/bin")
|
||||
if (NOT DOXYGEN)
|
||||
message(STATUS "Target 'doc' disabled because doxygen not found")
|
||||
return ()
|
||||
endif ()
|
||||
|
||||
find_program(MKDOCS mkdocs)
|
||||
if (NOT MKDOCS)
|
||||
message(STATUS "Target 'doc' disabled because mkdocs not found")
|
||||
return ()
|
||||
endif ()
|
||||
|
||||
set(sources )
|
||||
foreach (source api.md index.md syntax.md get-started.md fmt.css fmt.js)
|
||||
set(sources ${sources} doc/${source})
|
||||
endforeach()
|
||||
|
||||
add_custom_target(
|
||||
doc
|
||||
COMMAND
|
||||
${CMAKE_COMMAND}
|
||||
-E env PYTHONPATH=${CMAKE_CURRENT_SOURCE_DIR}/support/python
|
||||
${MKDOCS} build -f ${CMAKE_CURRENT_SOURCE_DIR}/support/mkdocs.yml
|
||||
# MkDocs requires the site dir to be outside of the doc dir.
|
||||
--site-dir ${CMAKE_CURRENT_BINARY_DIR}/doc-html
|
||||
--no-directory-urls
|
||||
SOURCES ${sources})
|
||||
|
||||
include(GNUInstallDirs)
|
||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc-html/
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/doc/fmt
|
||||
COMPONENT fmt-doc OPTIONAL)
|
||||
endfunction()
|
||||
|
||||
if (FMT_DOC)
|
||||
add_doc_target()
|
||||
endif ()
|
||||
|
||||
if (FMT_TEST)
|
||||
enable_testing()
|
||||
add_subdirectory(test)
|
||||
endif ()
|
||||
|
||||
# Control fuzzing independent of the unit tests.
|
||||
@@ -421,8 +520,7 @@ if (FMT_MASTER_PROJECT AND EXISTS ${gitignore})
|
||||
string(REPLACE "*" ".*" line "${line}")
|
||||
set(ignored_files ${ignored_files} "${line}$" "${line}/")
|
||||
endforeach ()
|
||||
set(ignored_files ${ignored_files}
|
||||
/.git /breathe /format-benchmark sphinx/ .buildinfo .doctrees)
|
||||
set(ignored_files ${ignored_files} /.git /build/doxyxml .vagrant)
|
||||
|
||||
set(CPACK_SOURCE_GENERATOR ZIP)
|
||||
set(CPACK_SOURCE_IGNORE_FILES ${ignored_files})
|
||||
|
||||
7790
3rdparty/fmt/ChangeLog.md
vendored
7790
3rdparty/fmt/ChangeLog.md
vendored
File diff suppressed because it is too large
Load Diff
81
3rdparty/fmt/README.md
vendored
81
3rdparty/fmt/README.md
vendored
@@ -20,16 +20,16 @@ that help victims of the war in Ukraine: <https://www.stopputin.net/>.
|
||||
Q&A: ask questions on [StackOverflow with the tag
|
||||
fmt](https://stackoverflow.com/questions/tagged/fmt).
|
||||
|
||||
Try {fmt} in [Compiler Explorer](https://godbolt.org/z/Eq5763).
|
||||
Try {fmt} in [Compiler Explorer](https://godbolt.org/z/8Mx1EW73v).
|
||||
|
||||
# Features
|
||||
|
||||
- Simple [format API](https://fmt.dev/latest/api.html) with positional
|
||||
- Simple [format API](https://fmt.dev/latest/api/) with positional
|
||||
arguments for localization
|
||||
- Implementation of [C++20
|
||||
std::format](https://en.cppreference.com/w/cpp/utility/format) and
|
||||
[C++23 std::print](https://en.cppreference.com/w/cpp/io/print)
|
||||
- [Format string syntax](https://fmt.dev/latest/syntax.html) similar
|
||||
- [Format string syntax](https://fmt.dev/latest/syntax/) similar
|
||||
to Python\'s
|
||||
[format](https://docs.python.org/3/library/stdtypes.html#str.format)
|
||||
- Fast IEEE 754 floating-point formatter with correct rounding,
|
||||
@@ -37,10 +37,10 @@ Try {fmt} in [Compiler Explorer](https://godbolt.org/z/Eq5763).
|
||||
[Dragonbox](https://github.com/jk-jeon/dragonbox) algorithm
|
||||
- Portable Unicode support
|
||||
- Safe [printf
|
||||
implementation](https://fmt.dev/latest/api.html#printf-formatting)
|
||||
implementation](https://fmt.dev/latest/api/#printf-formatting)
|
||||
including the POSIX extension for positional arguments
|
||||
- Extensibility: [support for user-defined
|
||||
types](https://fmt.dev/latest/api.html#formatting-user-defined-types)
|
||||
types](https://fmt.dev/latest/api/#formatting-user-defined-types)
|
||||
- High performance: faster than common standard library
|
||||
implementations of `(s)printf`, iostreams, `to_string` and
|
||||
`to_chars`, see [Speed tests](#speed-tests) and [Converting a
|
||||
@@ -58,8 +58,8 @@ Try {fmt} in [Compiler Explorer](https://godbolt.org/z/Eq5763).
|
||||
buffer overflow errors
|
||||
- Ease of use: small self-contained code base, no external
|
||||
dependencies, permissive MIT
|
||||
[license](https://github.com/fmtlib/fmt/blob/master/LICENSE.rst)
|
||||
- [Portability](https://fmt.dev/latest/index.html#portability) with
|
||||
[license](https://github.com/fmtlib/fmt/blob/master/LICENSE)
|
||||
- [Portability](https://fmt.dev/latest/#portability) with
|
||||
consistent output across platforms and support for older compilers
|
||||
- Clean warning-free codebase even on high warning levels such as
|
||||
`-Wall -Wextra -pedantic`
|
||||
@@ -203,43 +203,38 @@ and [ryu](https://github.com/ulfjack/ryu):
|
||||
|
||||
## Compile time and code bloat
|
||||
|
||||
The script
|
||||
[bloat-test.py](https://github.com/fmtlib/format-benchmark/blob/master/bloat-test.py)
|
||||
from [format-benchmark](https://github.com/fmtlib/format-benchmark)
|
||||
tests compile time and code bloat for nontrivial projects. It generates
|
||||
100 translation units and uses `printf()` or its alternative five times
|
||||
in each to simulate a medium-sized project. The resulting executable
|
||||
size and compile time (Apple LLVM version 8.1.0 (clang-802.0.42), macOS
|
||||
Sierra, best of three) is shown in the following tables.
|
||||
The script [bloat-test.py][test] from [format-benchmark][bench] tests compile
|
||||
time and code bloat for nontrivial projects. It generates 100 translation units
|
||||
and uses `printf()` or its alternative five times in each to simulate a
|
||||
medium-sized project. The resulting executable size and compile time (Apple
|
||||
clang version 15.0.0 (clang-1500.1.0.2.5), macOS Sonoma, best of three) is shown
|
||||
in the following tables.
|
||||
|
||||
[test]: https://github.com/fmtlib/format-benchmark/blob/master/bloat-test.py
|
||||
[bench]: https://github.com/fmtlib/format-benchmark
|
||||
|
||||
**Optimized build (-O3)**
|
||||
|
||||
| Method | Compile Time, s | Executable size, KiB | Stripped size, KiB |
|
||||
|---------------|-----------------|----------------------|--------------------|
|
||||
| printf | 2.6 | 29 | 26 |
|
||||
| printf+string | 16.4 | 29 | 26 |
|
||||
| iostreams | 31.1 | 59 | 55 |
|
||||
| {fmt} | 19.0 | 37 | 34 |
|
||||
| Boost Format | 91.9 | 226 | 203 |
|
||||
| Folly Format | 115.7 | 101 | 88 |
|
||||
| printf | 1.6 | 54 | 50 |
|
||||
| IOStreams | 25.9 | 98 | 84 |
|
||||
| fmt 83652df | 4.8 | 54 | 50 |
|
||||
| tinyformat | 29.1 | 161 | 136 |
|
||||
| Boost Format | 55.0 | 530 | 317 |
|
||||
|
||||
As you can see, {fmt} has 60% less overhead in terms of resulting binary
|
||||
code size compared to iostreams and comes pretty close to `printf`.
|
||||
Boost Format and Folly Format have the largest overheads.
|
||||
|
||||
`printf+string` is the same as `printf` but with an extra `<string>`
|
||||
include to measure the overhead of the latter.
|
||||
{fmt} is fast to compile and is comparable to `printf` in terms of per-call
|
||||
binary size (within a rounding error on this system).
|
||||
|
||||
**Non-optimized build**
|
||||
|
||||
| Method | Compile Time, s | Executable size, KiB | Stripped size, KiB |
|
||||
|---------------|-----------------|----------------------|--------------------|
|
||||
| printf | 2.2 | 33 | 30 |
|
||||
| printf+string | 16.0 | 33 | 30 |
|
||||
| iostreams | 28.3 | 56 | 52 |
|
||||
| {fmt} | 18.2 | 59 | 50 |
|
||||
| Boost Format | 54.1 | 365 | 303 |
|
||||
| Folly Format | 79.9 | 445 | 430 |
|
||||
| printf | 1.4 | 54 | 50 |
|
||||
| IOStreams | 23.4 | 92 | 68 |
|
||||
| {fmt} 83652df | 4.4 | 89 | 85 |
|
||||
| tinyformat | 24.5 | 204 | 161 |
|
||||
| Boost Format | 36.4 | 831 | 462 |
|
||||
|
||||
`libc`, `lib(std)c++`, and `libfmt` are all linked as shared libraries
|
||||
to compare formatting function overhead only. Boost Format is a
|
||||
@@ -248,7 +243,7 @@ header-only library so it doesn\'t provide any linkage options.
|
||||
## Running the tests
|
||||
|
||||
Please refer to [Building the
|
||||
library](https://fmt.dev/latest/usage.html#building-the-library) for
|
||||
library](https://fmt.dev/latest/get-started/#building-from-source) for
|
||||
instructions on how to build the library and run the unit tests.
|
||||
|
||||
Benchmarks reside in a separate repository,
|
||||
@@ -270,8 +265,7 @@ or the bloat test:
|
||||
|
||||
# Migrating code
|
||||
|
||||
[clang-tidy](https://clang.llvm.org/extra/clang-tidy/) v17 (not yet
|
||||
released) provides the
|
||||
[clang-tidy](https://clang.llvm.org/extra/clang-tidy/) v18 provides the
|
||||
[modernize-use-std-print](https://clang.llvm.org/extra/clang-tidy/checks/modernize/use-std-print.html)
|
||||
check that is capable of converting occurrences of `printf` and
|
||||
`fprintf` to `fmt::print` if configured to do so. (By default it
|
||||
@@ -297,13 +291,14 @@ converts to `std::print`.)
|
||||
- [ccache](https://ccache.dev/): a compiler cache
|
||||
- [ClickHouse](https://github.com/ClickHouse/ClickHouse): an
|
||||
analytical database management system
|
||||
- [ContextVision](https://www.contextvision.com/): medical imaging software
|
||||
- [Contour](https://github.com/contour-terminal/contour/): a modern
|
||||
terminal emulator
|
||||
- [CUAUV](https://cuauv.org/): Cornell University\'s autonomous
|
||||
underwater vehicle
|
||||
- [Drake](https://drake.mit.edu/): a planning, control, and analysis
|
||||
toolbox for nonlinear dynamical systems (MIT)
|
||||
- [Envoy](https://lyft.github.io/envoy/): C++ L7 proxy and
|
||||
- [Envoy](https://github.com/envoyproxy/envoy): C++ L7 proxy and
|
||||
communication bus (Lyft)
|
||||
- [FiveM](https://fivem.net/): a modification framework for GTA V
|
||||
- [fmtlog](https://github.com/MengRao/fmtlog): a performant
|
||||
@@ -343,7 +338,7 @@ converts to `std::print`.)
|
||||
- [Quill](https://github.com/odygrd/quill): asynchronous low-latency
|
||||
logging library
|
||||
- [QKW](https://github.com/ravijanjam/qkw): generalizing aliasing to
|
||||
simplify navigation, and executing complex multi-line terminal
|
||||
simplify navigation, and execute complex multi-line terminal
|
||||
command sequences
|
||||
- [redis-cerberus](https://github.com/HunanTV/redis-cerberus): a Redis
|
||||
cluster proxy
|
||||
@@ -432,7 +427,7 @@ code bloat issues (see [Benchmarks](#benchmarks)).
|
||||
|
||||
## FastFormat
|
||||
|
||||
This is an interesting library that is fast, safe, and has positional
|
||||
This is an interesting library that is fast, safe and has positional
|
||||
arguments. However, it has significant limitations, citing its author:
|
||||
|
||||
> Three features that have no hope of being accommodated within the
|
||||
@@ -442,8 +437,8 @@ arguments. However, it has significant limitations, citing its author:
|
||||
> - Octal/hexadecimal encoding
|
||||
> - Runtime width/alignment specification
|
||||
|
||||
It is also quite big and has a heavy dependency, STLSoft, which might be
|
||||
too restrictive for using it in some projects.
|
||||
It is also quite big and has a heavy dependency, on STLSoft, which might be
|
||||
too restrictive for use in some projects.
|
||||
|
||||
## Boost Spirit.Karma
|
||||
|
||||
@@ -462,7 +457,7 @@ second](http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html).
|
||||
|
||||
# Documentation License
|
||||
|
||||
The [Format String Syntax](https://fmt.dev/latest/syntax.html) section
|
||||
The [Format String Syntax](https://fmt.dev/latest/syntax/) section
|
||||
in the documentation is based on the one from Python [string module
|
||||
documentation](https://docs.python.org/3/library/string.html#module-string).
|
||||
For this reason, the documentation is distributed under the Python
|
||||
@@ -486,5 +481,5 @@ To report a security issue, please disclose it at [security
|
||||
advisory](https://github.com/fmtlib/fmt/security/advisories/new).
|
||||
|
||||
This project is maintained by a team of volunteers on a
|
||||
reasonable-effort basis. As such, please give us at least 90 days to
|
||||
reasonable-effort basis. As such, please give us at least *90* days to
|
||||
work on a fix before public exposure.
|
||||
|
||||
163
3rdparty/fmt/include/fmt/args.h
vendored
163
3rdparty/fmt/include/fmt/args.h
vendored
@@ -8,14 +8,15 @@
|
||||
#ifndef FMT_ARGS_H_
|
||||
#define FMT_ARGS_H_
|
||||
|
||||
#include <functional> // std::reference_wrapper
|
||||
#include <memory> // std::unique_ptr
|
||||
#include <vector>
|
||||
#ifndef FMT_MODULE
|
||||
# include <functional> // std::reference_wrapper
|
||||
# include <memory> // std::unique_ptr
|
||||
# include <vector>
|
||||
#endif
|
||||
|
||||
#include "core.h"
|
||||
#include "format.h" // std_string_view
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T> struct is_reference_wrapper : std::false_type {};
|
||||
@@ -28,15 +29,18 @@ auto unwrap(const std::reference_wrapper<T>& v) -> const T& {
|
||||
return static_cast<const T&>(v);
|
||||
}
|
||||
|
||||
class dynamic_arg_list {
|
||||
// Workaround for clang's -Wweak-vtables. Unlike for regular classes, for
|
||||
// templates it doesn't complain about inability to deduce single translation
|
||||
// unit for placing vtable. So storage_node_base is made a fake template.
|
||||
template <typename = void> struct node {
|
||||
virtual ~node() = default;
|
||||
std::unique_ptr<node<>> next;
|
||||
};
|
||||
// node is defined outside dynamic_arg_list to workaround a C2504 bug in MSVC
|
||||
// 2022 (v17.10.0).
|
||||
//
|
||||
// Workaround for clang's -Wweak-vtables. Unlike for regular classes, for
|
||||
// templates it doesn't complain about inability to deduce single translation
|
||||
// unit for placing vtable. So node is made a fake template.
|
||||
template <typename = void> struct node {
|
||||
virtual ~node() = default;
|
||||
std::unique_ptr<node<>> next;
|
||||
};
|
||||
|
||||
class dynamic_arg_list {
|
||||
template <typename T> struct typed_node : node<> {
|
||||
T value;
|
||||
|
||||
@@ -62,28 +66,18 @@ class dynamic_arg_list {
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
\rst
|
||||
A dynamic version of `fmt::format_arg_store`.
|
||||
It's equipped with a storage to potentially temporary objects which lifetimes
|
||||
could be shorter than the format arguments object.
|
||||
|
||||
It can be implicitly converted into `~fmt::basic_format_args` for passing
|
||||
into type-erased formatting functions such as `~fmt::vformat`.
|
||||
\endrst
|
||||
* A dynamic list of formatting arguments with storage.
|
||||
*
|
||||
* It can be implicitly converted into `fmt::basic_format_args` for passing
|
||||
* into type-erased formatting functions such as `fmt::vformat`.
|
||||
*/
|
||||
template <typename Context>
|
||||
class dynamic_format_arg_store
|
||||
#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
|
||||
// Workaround a GCC template argument substitution bug.
|
||||
: public basic_format_args<Context>
|
||||
#endif
|
||||
{
|
||||
template <typename Context> class dynamic_format_arg_store {
|
||||
private:
|
||||
using char_type = typename Context::char_type;
|
||||
|
||||
template <typename T> struct need_copy {
|
||||
static constexpr detail::type mapped_type =
|
||||
detail::mapped_type_constant<T, Context>::value;
|
||||
detail::mapped_type_constant<T, char_type>::value;
|
||||
|
||||
enum {
|
||||
value = !(detail::is_reference_wrapper<T>::value ||
|
||||
@@ -96,7 +90,7 @@ class dynamic_format_arg_store
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using stored_type = conditional_t<
|
||||
using stored_t = conditional_t<
|
||||
std::is_convertible<T, std::basic_string<char_type>>::value &&
|
||||
!detail::is_reference_wrapper<T>::value,
|
||||
std::basic_string<char_type>, T>;
|
||||
@@ -111,80 +105,72 @@ class dynamic_format_arg_store
|
||||
|
||||
friend class basic_format_args<Context>;
|
||||
|
||||
auto get_types() const -> unsigned long long {
|
||||
return detail::is_unpacked_bit | data_.size() |
|
||||
(named_info_.empty()
|
||||
? 0ULL
|
||||
: static_cast<unsigned long long>(detail::has_named_args_bit));
|
||||
}
|
||||
|
||||
auto data() const -> const basic_format_arg<Context>* {
|
||||
return named_info_.empty() ? data_.data() : data_.data() + 1;
|
||||
}
|
||||
|
||||
template <typename T> void emplace_arg(const T& arg) {
|
||||
data_.emplace_back(detail::make_arg<Context>(arg));
|
||||
data_.emplace_back(arg);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void emplace_arg(const detail::named_arg<char_type, T>& arg) {
|
||||
if (named_info_.empty()) {
|
||||
constexpr const detail::named_arg_info<char_type>* zero_ptr{nullptr};
|
||||
data_.insert(data_.begin(), {zero_ptr, 0});
|
||||
}
|
||||
data_.emplace_back(detail::make_arg<Context>(detail::unwrap(arg.value)));
|
||||
if (named_info_.empty())
|
||||
data_.insert(data_.begin(), basic_format_arg<Context>(nullptr, 0));
|
||||
data_.emplace_back(detail::unwrap(arg.value));
|
||||
auto pop_one = [](std::vector<basic_format_arg<Context>>* data) {
|
||||
data->pop_back();
|
||||
};
|
||||
std::unique_ptr<std::vector<basic_format_arg<Context>>, decltype(pop_one)>
|
||||
guard{&data_, pop_one};
|
||||
named_info_.push_back({arg.name, static_cast<int>(data_.size() - 2u)});
|
||||
data_[0].value_.named_args = {named_info_.data(), named_info_.size()};
|
||||
data_[0] = {named_info_.data(), named_info_.size()};
|
||||
guard.release();
|
||||
}
|
||||
|
||||
public:
|
||||
constexpr dynamic_format_arg_store() = default;
|
||||
|
||||
operator basic_format_args<Context>() const {
|
||||
return basic_format_args<Context>(data(), static_cast<int>(data_.size()),
|
||||
!named_info_.empty());
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Adds an argument into the dynamic store for later passing to a formatting
|
||||
function.
|
||||
|
||||
Note that custom types and string types (but not string views) are copied
|
||||
into the store dynamically allocating memory if necessary.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::dynamic_format_arg_store<fmt::format_context> store;
|
||||
store.push_back(42);
|
||||
store.push_back("abc");
|
||||
store.push_back(1.5f);
|
||||
std::string result = fmt::vformat("{} and {} and {}", store);
|
||||
\endrst
|
||||
*/
|
||||
* Adds an argument into the dynamic store for later passing to a formatting
|
||||
* function.
|
||||
*
|
||||
* Note that custom types and string types (but not string views) are copied
|
||||
* into the store dynamically allocating memory if necessary.
|
||||
*
|
||||
* **Example**:
|
||||
*
|
||||
* fmt::dynamic_format_arg_store<fmt::format_context> store;
|
||||
* store.push_back(42);
|
||||
* store.push_back("abc");
|
||||
* store.push_back(1.5f);
|
||||
* std::string result = fmt::vformat("{} and {} and {}", store);
|
||||
*/
|
||||
template <typename T> void push_back(const T& arg) {
|
||||
if (detail::const_check(need_copy<T>::value))
|
||||
emplace_arg(dynamic_args_.push<stored_type<T>>(arg));
|
||||
emplace_arg(dynamic_args_.push<stored_t<T>>(arg));
|
||||
else
|
||||
emplace_arg(detail::unwrap(arg));
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Adds a reference to the argument into the dynamic store for later passing to
|
||||
a formatting function.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::dynamic_format_arg_store<fmt::format_context> store;
|
||||
char band[] = "Rolling Stones";
|
||||
store.push_back(std::cref(band));
|
||||
band[9] = 'c'; // Changing str affects the output.
|
||||
std::string result = fmt::vformat("{}", store);
|
||||
// result == "Rolling Scones"
|
||||
\endrst
|
||||
*/
|
||||
* Adds a reference to the argument into the dynamic store for later passing
|
||||
* to a formatting function.
|
||||
*
|
||||
* **Example**:
|
||||
*
|
||||
* fmt::dynamic_format_arg_store<fmt::format_context> store;
|
||||
* char band[] = "Rolling Stones";
|
||||
* store.push_back(std::cref(band));
|
||||
* band[9] = 'c'; // Changing str affects the output.
|
||||
* std::string result = fmt::vformat("{}", store);
|
||||
* // result == "Rolling Scones"
|
||||
*/
|
||||
template <typename T> void push_back(std::reference_wrapper<T> arg) {
|
||||
static_assert(
|
||||
need_copy<T>::value,
|
||||
@@ -193,41 +179,40 @@ class dynamic_format_arg_store
|
||||
}
|
||||
|
||||
/**
|
||||
Adds named argument into the dynamic store for later passing to a formatting
|
||||
function. ``std::reference_wrapper`` is supported to avoid copying of the
|
||||
argument. The name is always copied into the store.
|
||||
*/
|
||||
* Adds named argument into the dynamic store for later passing to a
|
||||
* formatting function. `std::reference_wrapper` is supported to avoid
|
||||
* copying of the argument. The name is always copied into the store.
|
||||
*/
|
||||
template <typename T>
|
||||
void push_back(const detail::named_arg<char_type, T>& arg) {
|
||||
const char_type* arg_name =
|
||||
dynamic_args_.push<std::basic_string<char_type>>(arg.name).c_str();
|
||||
if (detail::const_check(need_copy<T>::value)) {
|
||||
emplace_arg(
|
||||
fmt::arg(arg_name, dynamic_args_.push<stored_type<T>>(arg.value)));
|
||||
fmt::arg(arg_name, dynamic_args_.push<stored_t<T>>(arg.value)));
|
||||
} else {
|
||||
emplace_arg(fmt::arg(arg_name, arg.value));
|
||||
}
|
||||
}
|
||||
|
||||
/** Erase all elements from the store */
|
||||
/// Erase all elements from the store.
|
||||
void clear() {
|
||||
data_.clear();
|
||||
named_info_.clear();
|
||||
dynamic_args_ = detail::dynamic_arg_list();
|
||||
dynamic_args_ = {};
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Reserves space to store at least *new_cap* arguments including
|
||||
*new_cap_named* named arguments.
|
||||
\endrst
|
||||
*/
|
||||
/// Reserves space to store at least `new_cap` arguments including
|
||||
/// `new_cap_named` named arguments.
|
||||
void reserve(size_t new_cap, size_t new_cap_named) {
|
||||
FMT_ASSERT(new_cap >= new_cap_named,
|
||||
"Set of arguments includes set of named arguments");
|
||||
"set of arguments includes set of named arguments");
|
||||
data_.reserve(new_cap);
|
||||
named_info_.reserve(new_cap_named);
|
||||
}
|
||||
|
||||
/// Returns the number of elements in the store.
|
||||
size_t size() const noexcept { return data_.size(); }
|
||||
};
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
2958
3rdparty/fmt/include/fmt/base.h
vendored
Normal file
2958
3rdparty/fmt/include/fmt/base.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1234
3rdparty/fmt/include/fmt/chrono.h
vendored
1234
3rdparty/fmt/include/fmt/chrono.h
vendored
File diff suppressed because it is too large
Load Diff
221
3rdparty/fmt/include/fmt/color.h
vendored
221
3rdparty/fmt/include/fmt/color.h
vendored
@@ -227,7 +227,7 @@ struct color_type {
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
/** A text style consisting of foreground and background colors and emphasis. */
|
||||
/// A text style consisting of foreground and background colors and emphasis.
|
||||
class text_style {
|
||||
public:
|
||||
FMT_CONSTEXPR text_style(emphasis em = emphasis()) noexcept
|
||||
@@ -239,7 +239,7 @@ class text_style {
|
||||
foreground_color = rhs.foreground_color;
|
||||
} else if (rhs.set_foreground_color) {
|
||||
if (!foreground_color.is_rgb || !rhs.foreground_color.is_rgb)
|
||||
FMT_THROW(format_error("can't OR a terminal color"));
|
||||
report_error("can't OR a terminal color");
|
||||
foreground_color.value.rgb_color |= rhs.foreground_color.value.rgb_color;
|
||||
}
|
||||
|
||||
@@ -248,7 +248,7 @@ class text_style {
|
||||
background_color = rhs.background_color;
|
||||
} else if (rhs.set_background_color) {
|
||||
if (!background_color.is_rgb || !rhs.background_color.is_rgb)
|
||||
FMT_THROW(format_error("can't OR a terminal color"));
|
||||
report_error("can't OR a terminal color");
|
||||
background_color.value.rgb_color |= rhs.background_color.value.rgb_color;
|
||||
}
|
||||
|
||||
@@ -310,13 +310,13 @@ class text_style {
|
||||
emphasis ems;
|
||||
};
|
||||
|
||||
/** Creates a text style from the foreground (text) color. */
|
||||
/// Creates a text style from the foreground (text) color.
|
||||
FMT_CONSTEXPR inline auto fg(detail::color_type foreground) noexcept
|
||||
-> text_style {
|
||||
return text_style(true, foreground);
|
||||
}
|
||||
|
||||
/** Creates a text style from the background color. */
|
||||
/// Creates a text style from the background color.
|
||||
FMT_CONSTEXPR inline auto bg(detail::color_type background) noexcept
|
||||
-> text_style {
|
||||
return text_style(false, background);
|
||||
@@ -330,7 +330,7 @@ FMT_CONSTEXPR inline auto operator|(emphasis lhs, emphasis rhs) noexcept
|
||||
namespace detail {
|
||||
|
||||
template <typename Char> struct ansi_color_escape {
|
||||
FMT_CONSTEXPR ansi_color_escape(detail::color_type text_color,
|
||||
FMT_CONSTEXPR ansi_color_escape(color_type text_color,
|
||||
const char* esc) noexcept {
|
||||
// If we have a terminal color, we need to output another escape code
|
||||
// sequence.
|
||||
@@ -390,8 +390,8 @@ template <typename Char> struct ansi_color_escape {
|
||||
FMT_CONSTEXPR operator const Char*() const noexcept { return buffer; }
|
||||
|
||||
FMT_CONSTEXPR auto begin() const noexcept -> const Char* { return buffer; }
|
||||
FMT_CONSTEXPR_CHAR_TRAITS auto end() const noexcept -> const Char* {
|
||||
return buffer + std::char_traits<Char>::length(buffer);
|
||||
FMT_CONSTEXPR20 auto end() const noexcept -> const Char* {
|
||||
return buffer + basic_string_view<Char>(buffer).size();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -412,13 +412,13 @@ template <typename Char> struct ansi_color_escape {
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
FMT_CONSTEXPR auto make_foreground_color(detail::color_type foreground) noexcept
|
||||
FMT_CONSTEXPR auto make_foreground_color(color_type foreground) noexcept
|
||||
-> ansi_color_escape<Char> {
|
||||
return ansi_color_escape<Char>(foreground, "\x1b[38;2;");
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
FMT_CONSTEXPR auto make_background_color(detail::color_type background) noexcept
|
||||
FMT_CONSTEXPR auto make_background_color(color_type background) noexcept
|
||||
-> ansi_color_escape<Char> {
|
||||
return ansi_color_escape<Char>(background, "\x1b[48;2;");
|
||||
}
|
||||
@@ -434,7 +434,7 @@ template <typename Char> inline void reset_color(buffer<Char>& buffer) {
|
||||
buffer.append(reset_color.begin(), reset_color.end());
|
||||
}
|
||||
|
||||
template <typename T> struct styled_arg : detail::view {
|
||||
template <typename T> struct styled_arg : view {
|
||||
const T& value;
|
||||
text_style style;
|
||||
styled_arg(const T& v, text_style s) : value(v), style(s) {}
|
||||
@@ -442,145 +442,115 @@ template <typename T> struct styled_arg : detail::view {
|
||||
|
||||
template <typename Char>
|
||||
void vformat_to(buffer<Char>& buf, const text_style& ts,
|
||||
basic_string_view<Char> format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
||||
basic_string_view<Char> fmt,
|
||||
basic_format_args<buffered_context<Char>> args) {
|
||||
bool has_style = false;
|
||||
if (ts.has_emphasis()) {
|
||||
has_style = true;
|
||||
auto emphasis = detail::make_emphasis<Char>(ts.get_emphasis());
|
||||
auto emphasis = make_emphasis<Char>(ts.get_emphasis());
|
||||
buf.append(emphasis.begin(), emphasis.end());
|
||||
}
|
||||
if (ts.has_foreground()) {
|
||||
has_style = true;
|
||||
auto foreground = detail::make_foreground_color<Char>(ts.get_foreground());
|
||||
auto foreground = make_foreground_color<Char>(ts.get_foreground());
|
||||
buf.append(foreground.begin(), foreground.end());
|
||||
}
|
||||
if (ts.has_background()) {
|
||||
has_style = true;
|
||||
auto background = detail::make_background_color<Char>(ts.get_background());
|
||||
auto background = make_background_color<Char>(ts.get_background());
|
||||
buf.append(background.begin(), background.end());
|
||||
}
|
||||
detail::vformat_to(buf, format_str, args, {});
|
||||
if (has_style) detail::reset_color<Char>(buf);
|
||||
vformat_to(buf, fmt, args);
|
||||
if (has_style) reset_color<Char>(buf);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
inline void vprint(std::FILE* f, const text_style& ts, string_view fmt,
|
||||
inline void vprint(FILE* f, const text_style& ts, string_view fmt,
|
||||
format_args args) {
|
||||
// Legacy wide streams are not supported.
|
||||
auto buf = memory_buffer();
|
||||
detail::vformat_to(buf, ts, fmt, args);
|
||||
if (detail::is_utf8()) {
|
||||
detail::print(f, string_view(buf.begin(), buf.size()));
|
||||
return;
|
||||
}
|
||||
buf.push_back('\0');
|
||||
int result = std::fputs(buf.data(), f);
|
||||
if (result < 0)
|
||||
FMT_THROW(system_error(errno, FMT_STRING("cannot write to file")));
|
||||
print(f, FMT_STRING("{}"), string_view(buf.begin(), buf.size()));
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Formats a string and prints it to the specified file stream using ANSI
|
||||
escape sequences to specify text formatting.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
|
||||
"Elapsed time: {0:.2f} seconds", 1.23);
|
||||
\endrst
|
||||
* Formats a string and prints it to the specified file stream using ANSI
|
||||
* escape sequences to specify text formatting.
|
||||
*
|
||||
* **Example**:
|
||||
*
|
||||
* fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
|
||||
* "Elapsed time: {0:.2f} seconds", 1.23);
|
||||
*/
|
||||
template <typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_string<S>::value)>
|
||||
void print(std::FILE* f, const text_style& ts, const S& format_str,
|
||||
const Args&... args) {
|
||||
vprint(f, ts, format_str,
|
||||
fmt::make_format_args<buffer_context<char_t<S>>>(args...));
|
||||
template <typename... T>
|
||||
void print(FILE* f, const text_style& ts, format_string<T...> fmt,
|
||||
T&&... args) {
|
||||
vprint(f, ts, fmt.str, vargs<T...>{{args...}});
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Formats a string and prints it to stdout using ANSI escape sequences to
|
||||
specify text formatting.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
|
||||
"Elapsed time: {0:.2f} seconds", 1.23);
|
||||
\endrst
|
||||
* Formats a string and prints it to stdout using ANSI escape sequences to
|
||||
* specify text formatting.
|
||||
*
|
||||
* **Example**:
|
||||
*
|
||||
* fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
|
||||
* "Elapsed time: {0:.2f} seconds", 1.23);
|
||||
*/
|
||||
template <typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_string<S>::value)>
|
||||
void print(const text_style& ts, const S& format_str, const Args&... args) {
|
||||
return print(stdout, ts, format_str, args...);
|
||||
template <typename... T>
|
||||
void print(const text_style& ts, format_string<T...> fmt, T&&... args) {
|
||||
return print(stdout, ts, fmt, std::forward<T>(args)...);
|
||||
}
|
||||
|
||||
template <typename S, typename Char = char_t<S>>
|
||||
inline auto vformat(
|
||||
const text_style& ts, const S& format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args)
|
||||
-> std::basic_string<Char> {
|
||||
basic_memory_buffer<Char> buf;
|
||||
detail::vformat_to(buf, ts, detail::to_string_view(format_str), args);
|
||||
inline auto vformat(const text_style& ts, string_view fmt, format_args args)
|
||||
-> std::string {
|
||||
auto buf = memory_buffer();
|
||||
detail::vformat_to(buf, ts, fmt, args);
|
||||
return fmt::to_string(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Formats arguments and returns the result as a string using ANSI
|
||||
escape sequences to specify text formatting.
|
||||
|
||||
**Example**::
|
||||
|
||||
#include <fmt/color.h>
|
||||
std::string message = fmt::format(fmt::emphasis::bold | fg(fmt::color::red),
|
||||
"The answer is {}", 42);
|
||||
\endrst
|
||||
*/
|
||||
template <typename S, typename... Args, typename Char = char_t<S>>
|
||||
inline auto format(const text_style& ts, const S& format_str,
|
||||
const Args&... args) -> std::basic_string<Char> {
|
||||
return fmt::vformat(ts, detail::to_string_view(format_str),
|
||||
fmt::make_format_args<buffer_context<Char>>(args...));
|
||||
* Formats arguments and returns the result as a string using ANSI escape
|
||||
* sequences to specify text formatting.
|
||||
*
|
||||
* **Example**:
|
||||
*
|
||||
* ```
|
||||
* #include <fmt/color.h>
|
||||
* std::string message = fmt::format(fmt::emphasis::bold | fg(fmt::color::red),
|
||||
* "The answer is {}", 42);
|
||||
* ```
|
||||
*/
|
||||
template <typename... T>
|
||||
inline auto format(const text_style& ts, format_string<T...> fmt, T&&... args)
|
||||
-> std::string {
|
||||
return fmt::vformat(ts, fmt.str, vargs<T...>{{args...}});
|
||||
}
|
||||
|
||||
/**
|
||||
Formats a string with the given text_style and writes the output to ``out``.
|
||||
*/
|
||||
template <typename OutputIt, typename Char,
|
||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value)>
|
||||
auto vformat_to(OutputIt out, const text_style& ts,
|
||||
basic_string_view<Char> format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args)
|
||||
-> OutputIt {
|
||||
auto&& buf = detail::get_buffer<Char>(out);
|
||||
detail::vformat_to(buf, ts, format_str, args);
|
||||
/// Formats a string with the given text_style and writes the output to `out`.
|
||||
template <typename OutputIt,
|
||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
|
||||
auto vformat_to(OutputIt out, const text_style& ts, string_view fmt,
|
||||
format_args args) -> OutputIt {
|
||||
auto&& buf = detail::get_buffer<char>(out);
|
||||
detail::vformat_to(buf, ts, fmt, args);
|
||||
return detail::get_iterator(buf, out);
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Formats arguments with the given text_style, writes the result to the output
|
||||
iterator ``out`` and returns the iterator past the end of the output range.
|
||||
|
||||
**Example**::
|
||||
|
||||
std::vector<char> out;
|
||||
fmt::format_to(std::back_inserter(out),
|
||||
fmt::emphasis::bold | fg(fmt::color::red), "{}", 42);
|
||||
\endrst
|
||||
*/
|
||||
template <
|
||||
typename OutputIt, typename S, typename... Args,
|
||||
bool enable = detail::is_output_iterator<OutputIt, char_t<S>>::value &&
|
||||
detail::is_string<S>::value>
|
||||
inline auto format_to(OutputIt out, const text_style& ts, const S& format_str,
|
||||
Args&&... args) ->
|
||||
typename std::enable_if<enable, OutputIt>::type {
|
||||
return vformat_to(out, ts, detail::to_string_view(format_str),
|
||||
fmt::make_format_args<buffer_context<char_t<S>>>(args...));
|
||||
* Formats arguments with the given text style, writes the result to the output
|
||||
* iterator `out` and returns the iterator past the end of the output range.
|
||||
*
|
||||
* **Example**:
|
||||
*
|
||||
* std::vector<char> out;
|
||||
* fmt::format_to(std::back_inserter(out),
|
||||
* fmt::emphasis::bold | fg(fmt::color::red), "{}", 42);
|
||||
*/
|
||||
template <typename OutputIt, typename... T,
|
||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
|
||||
inline auto format_to(OutputIt out, const text_style& ts,
|
||||
format_string<T...> fmt, T&&... args) -> OutputIt {
|
||||
return vformat_to(out, ts, fmt.str, vargs<T...>{{args...}});
|
||||
}
|
||||
|
||||
template <typename T, typename Char>
|
||||
@@ -589,47 +559,44 @@ struct formatter<detail::styled_arg<T>, Char> : formatter<T, Char> {
|
||||
auto format(const detail::styled_arg<T>& arg, FormatContext& ctx) const
|
||||
-> decltype(ctx.out()) {
|
||||
const auto& ts = arg.style;
|
||||
const auto& value = arg.value;
|
||||
auto out = ctx.out();
|
||||
|
||||
bool has_style = false;
|
||||
if (ts.has_emphasis()) {
|
||||
has_style = true;
|
||||
auto emphasis = detail::make_emphasis<Char>(ts.get_emphasis());
|
||||
out = std::copy(emphasis.begin(), emphasis.end(), out);
|
||||
out = detail::copy<Char>(emphasis.begin(), emphasis.end(), out);
|
||||
}
|
||||
if (ts.has_foreground()) {
|
||||
has_style = true;
|
||||
auto foreground =
|
||||
detail::make_foreground_color<Char>(ts.get_foreground());
|
||||
out = std::copy(foreground.begin(), foreground.end(), out);
|
||||
out = detail::copy<Char>(foreground.begin(), foreground.end(), out);
|
||||
}
|
||||
if (ts.has_background()) {
|
||||
has_style = true;
|
||||
auto background =
|
||||
detail::make_background_color<Char>(ts.get_background());
|
||||
out = std::copy(background.begin(), background.end(), out);
|
||||
out = detail::copy<Char>(background.begin(), background.end(), out);
|
||||
}
|
||||
out = formatter<T, Char>::format(value, ctx);
|
||||
out = formatter<T, Char>::format(arg.value, ctx);
|
||||
if (has_style) {
|
||||
auto reset_color = string_view("\x1b[0m");
|
||||
out = std::copy(reset_color.begin(), reset_color.end(), out);
|
||||
out = detail::copy<Char>(reset_color.begin(), reset_color.end(), out);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
\rst
|
||||
Returns an argument that will be formatted using ANSI escape sequences,
|
||||
to be used in a formatting function.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::print("Elapsed time: {0:.2f} seconds",
|
||||
fmt::styled(1.23, fmt::fg(fmt::color::green) |
|
||||
fmt::bg(fmt::color::blue)));
|
||||
\endrst
|
||||
* Returns an argument that will be formatted using ANSI escape sequences,
|
||||
* to be used in a formatting function.
|
||||
*
|
||||
* **Example**:
|
||||
*
|
||||
* fmt::print("Elapsed time: {0:.2f} seconds",
|
||||
* fmt::styled(1.23, fmt::fg(fmt::color::green) |
|
||||
* fmt::bg(fmt::color::blue)));
|
||||
*/
|
||||
template <typename T>
|
||||
FMT_CONSTEXPR auto styled(const T& value, text_style ts)
|
||||
|
||||
164
3rdparty/fmt/include/fmt/compile.h
vendored
164
3rdparty/fmt/include/fmt/compile.h
vendored
@@ -8,49 +8,44 @@
|
||||
#ifndef FMT_COMPILE_H_
|
||||
#define FMT_COMPILE_H_
|
||||
|
||||
#ifndef FMT_MODULE
|
||||
# include <iterator> // std::back_inserter
|
||||
#endif
|
||||
|
||||
#include "format.h"
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
namespace detail {
|
||||
|
||||
template <typename Char, typename InputIt>
|
||||
FMT_CONSTEXPR inline auto copy_str(InputIt begin, InputIt end,
|
||||
counting_iterator it) -> counting_iterator {
|
||||
return it + (end - begin);
|
||||
}
|
||||
|
||||
// A compile-time string which is compiled into fast formatting code.
|
||||
class compiled_string {};
|
||||
FMT_EXPORT class compiled_string {};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename S>
|
||||
struct is_compiled_string : std::is_base_of<compiled_string, S> {};
|
||||
|
||||
/**
|
||||
\rst
|
||||
Converts a string literal *s* into a format string that will be parsed at
|
||||
compile time and converted into efficient formatting code. Requires C++17
|
||||
``constexpr if`` compiler support.
|
||||
|
||||
**Example**::
|
||||
|
||||
// Converts 42 into std::string using the most efficient method and no
|
||||
// runtime format string processing.
|
||||
std::string s = fmt::format(FMT_COMPILE("{}"), 42);
|
||||
\endrst
|
||||
* Converts a string literal `s` into a format string that will be parsed at
|
||||
* compile time and converted into efficient formatting code. Requires C++17
|
||||
* `constexpr if` compiler support.
|
||||
*
|
||||
* **Example**:
|
||||
*
|
||||
* // Converts 42 into std::string using the most efficient method and no
|
||||
* // runtime format string processing.
|
||||
* std::string s = fmt::format(FMT_COMPILE("{}"), 42);
|
||||
*/
|
||||
#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)
|
||||
# define FMT_COMPILE(s) \
|
||||
FMT_STRING_IMPL(s, fmt::detail::compiled_string, explicit)
|
||||
# define FMT_COMPILE(s) FMT_STRING_IMPL(s, fmt::compiled_string)
|
||||
#else
|
||||
# define FMT_COMPILE(s) FMT_STRING(s)
|
||||
#endif
|
||||
|
||||
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
|
||||
template <typename Char, size_t N,
|
||||
fmt::detail_exported::fixed_string<Char, N> Str>
|
||||
template <typename Char, size_t N, fmt::detail::fixed_string<Char, N> Str>
|
||||
struct udl_compiled_string : compiled_string {
|
||||
using char_type = Char;
|
||||
explicit constexpr operator basic_string_view<char_type>() const {
|
||||
constexpr explicit operator basic_string_view<char_type>() const {
|
||||
return {Str.data, N - 1};
|
||||
}
|
||||
};
|
||||
@@ -75,6 +70,29 @@ constexpr const auto& get([[maybe_unused]] const T& first,
|
||||
return detail::get<N - 1>(rest...);
|
||||
}
|
||||
|
||||
# if FMT_USE_NONTYPE_TEMPLATE_ARGS
|
||||
template <int N, typename T, typename... Args, typename Char>
|
||||
constexpr auto get_arg_index_by_name(basic_string_view<Char> name) -> int {
|
||||
if constexpr (is_static_named_arg<T>()) {
|
||||
if (name == T::name) return N;
|
||||
}
|
||||
if constexpr (sizeof...(Args) > 0)
|
||||
return get_arg_index_by_name<N + 1, Args...>(name);
|
||||
(void)name; // Workaround an MSVC bug about "unused" parameter.
|
||||
return -1;
|
||||
}
|
||||
# endif
|
||||
|
||||
template <typename... Args, typename Char>
|
||||
FMT_CONSTEXPR auto get_arg_index_by_name(basic_string_view<Char> name) -> int {
|
||||
# if FMT_USE_NONTYPE_TEMPLATE_ARGS
|
||||
if constexpr (sizeof...(Args) > 0)
|
||||
return get_arg_index_by_name<0, Args...>(name);
|
||||
# endif
|
||||
(void)name;
|
||||
return -1;
|
||||
}
|
||||
|
||||
template <typename Char, typename... Args>
|
||||
constexpr int get_arg_index_by_name(basic_string_view<Char> name,
|
||||
type_list<Args...>) {
|
||||
@@ -144,11 +162,12 @@ template <typename Char, typename T, int N> struct field {
|
||||
template <typename OutputIt, typename... Args>
|
||||
constexpr OutputIt format(OutputIt out, const Args&... args) const {
|
||||
const T& arg = get_arg_checked<T, N>(args...);
|
||||
if constexpr (std::is_convertible_v<T, basic_string_view<Char>>) {
|
||||
if constexpr (std::is_convertible<T, basic_string_view<Char>>::value) {
|
||||
auto s = basic_string_view<Char>(arg);
|
||||
return copy_str<Char>(s.begin(), s.end(), out);
|
||||
return copy<Char>(s.begin(), s.end(), out);
|
||||
} else {
|
||||
return write<Char>(out, arg);
|
||||
}
|
||||
return write<Char>(out, arg);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -236,13 +255,12 @@ constexpr size_t parse_text(basic_string_view<Char> str, size_t pos) {
|
||||
}
|
||||
|
||||
template <typename Args, size_t POS, int ID, typename S>
|
||||
constexpr auto compile_format_string(S format_str);
|
||||
constexpr auto compile_format_string(S fmt);
|
||||
|
||||
template <typename Args, size_t POS, int ID, typename T, typename S>
|
||||
constexpr auto parse_tail(T head, S format_str) {
|
||||
if constexpr (POS !=
|
||||
basic_string_view<typename S::char_type>(format_str).size()) {
|
||||
constexpr auto tail = compile_format_string<Args, POS, ID>(format_str);
|
||||
constexpr auto parse_tail(T head, S fmt) {
|
||||
if constexpr (POS != basic_string_view<typename S::char_type>(fmt).size()) {
|
||||
constexpr auto tail = compile_format_string<Args, POS, ID>(fmt);
|
||||
if constexpr (std::is_same<remove_cvref_t<decltype(tail)>,
|
||||
unknown_format>())
|
||||
return tail;
|
||||
@@ -274,6 +292,7 @@ constexpr parse_specs_result<T, Char> parse_specs(basic_string_view<Char> str,
|
||||
}
|
||||
|
||||
template <typename Char> struct arg_id_handler {
|
||||
arg_id_kind kind;
|
||||
arg_ref<Char> arg_id;
|
||||
|
||||
constexpr int on_auto() {
|
||||
@@ -281,25 +300,28 @@ template <typename Char> struct arg_id_handler {
|
||||
return 0;
|
||||
}
|
||||
constexpr int on_index(int id) {
|
||||
kind = arg_id_kind::index;
|
||||
arg_id = arg_ref<Char>(id);
|
||||
return 0;
|
||||
}
|
||||
constexpr int on_name(basic_string_view<Char> id) {
|
||||
kind = arg_id_kind::name;
|
||||
arg_id = arg_ref<Char>(id);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char> struct parse_arg_id_result {
|
||||
arg_id_kind kind;
|
||||
arg_ref<Char> arg_id;
|
||||
const Char* arg_id_end;
|
||||
};
|
||||
|
||||
template <int ID, typename Char>
|
||||
constexpr auto parse_arg_id(const Char* begin, const Char* end) {
|
||||
auto handler = arg_id_handler<Char>{arg_ref<Char>{}};
|
||||
auto handler = arg_id_handler<Char>{arg_id_kind::none, arg_ref<Char>{}};
|
||||
auto arg_id_end = parse_arg_id(begin, end, handler);
|
||||
return parse_arg_id_result<Char>{handler.arg_id, arg_id_end};
|
||||
return parse_arg_id_result<Char>{handler.kind, handler.arg_id, arg_id_end};
|
||||
}
|
||||
|
||||
template <typename T, typename Enable = void> struct field_type {
|
||||
@@ -313,14 +335,13 @@ struct field_type<T, enable_if_t<detail::is_named_arg<T>::value>> {
|
||||
|
||||
template <typename T, typename Args, size_t END_POS, int ARG_INDEX, int NEXT_ID,
|
||||
typename S>
|
||||
constexpr auto parse_replacement_field_then_tail(S format_str) {
|
||||
constexpr auto parse_replacement_field_then_tail(S fmt) {
|
||||
using char_type = typename S::char_type;
|
||||
constexpr auto str = basic_string_view<char_type>(format_str);
|
||||
constexpr auto str = basic_string_view<char_type>(fmt);
|
||||
constexpr char_type c = END_POS != str.size() ? str[END_POS] : char_type();
|
||||
if constexpr (c == '}') {
|
||||
return parse_tail<Args, END_POS + 1, NEXT_ID>(
|
||||
field<char_type, typename field_type<T>::type, ARG_INDEX>(),
|
||||
format_str);
|
||||
field<char_type, typename field_type<T>::type, ARG_INDEX>(), fmt);
|
||||
} else if constexpr (c != ':') {
|
||||
FMT_THROW(format_error("expected ':'"));
|
||||
} else {
|
||||
@@ -333,7 +354,7 @@ constexpr auto parse_replacement_field_then_tail(S format_str) {
|
||||
return parse_tail<Args, result.end + 1, result.next_arg_id>(
|
||||
spec_field<char_type, typename field_type<T>::type, ARG_INDEX>{
|
||||
result.fmt},
|
||||
format_str);
|
||||
fmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -341,22 +362,21 @@ constexpr auto parse_replacement_field_then_tail(S format_str) {
|
||||
// Compiles a non-empty format string and returns the compiled representation
|
||||
// or unknown_format() on unrecognized input.
|
||||
template <typename Args, size_t POS, int ID, typename S>
|
||||
constexpr auto compile_format_string(S format_str) {
|
||||
constexpr auto compile_format_string(S fmt) {
|
||||
using char_type = typename S::char_type;
|
||||
constexpr auto str = basic_string_view<char_type>(format_str);
|
||||
constexpr auto str = basic_string_view<char_type>(fmt);
|
||||
if constexpr (str[POS] == '{') {
|
||||
if constexpr (POS + 1 == str.size())
|
||||
FMT_THROW(format_error("unmatched '{' in format string"));
|
||||
if constexpr (str[POS + 1] == '{') {
|
||||
return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), format_str);
|
||||
return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), fmt);
|
||||
} else if constexpr (str[POS + 1] == '}' || str[POS + 1] == ':') {
|
||||
static_assert(ID != manual_indexing_id,
|
||||
"cannot switch from manual to automatic argument indexing");
|
||||
constexpr auto next_id =
|
||||
ID != manual_indexing_id ? ID + 1 : manual_indexing_id;
|
||||
return parse_replacement_field_then_tail<get_type<ID, Args>, Args,
|
||||
POS + 1, ID, next_id>(
|
||||
format_str);
|
||||
POS + 1, ID, next_id>(fmt);
|
||||
} else {
|
||||
constexpr auto arg_id_result =
|
||||
parse_arg_id<ID>(str.data() + POS + 1, str.data() + str.size());
|
||||
@@ -364,28 +384,27 @@ constexpr auto compile_format_string(S format_str) {
|
||||
constexpr char_type c =
|
||||
arg_id_end_pos != str.size() ? str[arg_id_end_pos] : char_type();
|
||||
static_assert(c == '}' || c == ':', "missing '}' in format string");
|
||||
if constexpr (arg_id_result.arg_id.kind == arg_id_kind::index) {
|
||||
if constexpr (arg_id_result.kind == arg_id_kind::index) {
|
||||
static_assert(
|
||||
ID == manual_indexing_id || ID == 0,
|
||||
"cannot switch from automatic to manual argument indexing");
|
||||
constexpr auto arg_index = arg_id_result.arg_id.val.index;
|
||||
constexpr auto arg_index = arg_id_result.arg_id.index;
|
||||
return parse_replacement_field_then_tail<get_type<arg_index, Args>,
|
||||
Args, arg_id_end_pos,
|
||||
arg_index, manual_indexing_id>(
|
||||
format_str);
|
||||
} else if constexpr (arg_id_result.arg_id.kind == arg_id_kind::name) {
|
||||
fmt);
|
||||
} else if constexpr (arg_id_result.kind == arg_id_kind::name) {
|
||||
constexpr auto arg_index =
|
||||
get_arg_index_by_name(arg_id_result.arg_id.val.name, Args{});
|
||||
get_arg_index_by_name(arg_id_result.arg_id.name, Args{});
|
||||
if constexpr (arg_index >= 0) {
|
||||
constexpr auto next_id =
|
||||
ID != manual_indexing_id ? ID + 1 : manual_indexing_id;
|
||||
return parse_replacement_field_then_tail<
|
||||
decltype(get_type<arg_index, Args>::value), Args, arg_id_end_pos,
|
||||
arg_index, next_id>(format_str);
|
||||
arg_index, next_id>(fmt);
|
||||
} else if constexpr (c == '}') {
|
||||
return parse_tail<Args, arg_id_end_pos + 1, ID>(
|
||||
runtime_named_field<char_type>{arg_id_result.arg_id.val.name},
|
||||
format_str);
|
||||
runtime_named_field<char_type>{arg_id_result.arg_id.name}, fmt);
|
||||
} else if constexpr (c == ':') {
|
||||
return unknown_format(); // no type info for specs parsing
|
||||
}
|
||||
@@ -394,29 +413,26 @@ constexpr auto compile_format_string(S format_str) {
|
||||
} else if constexpr (str[POS] == '}') {
|
||||
if constexpr (POS + 1 == str.size())
|
||||
FMT_THROW(format_error("unmatched '}' in format string"));
|
||||
return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), format_str);
|
||||
return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), fmt);
|
||||
} else {
|
||||
constexpr auto end = parse_text(str, POS + 1);
|
||||
if constexpr (end - POS > 1) {
|
||||
return parse_tail<Args, end, ID>(make_text(str, POS, end - POS),
|
||||
format_str);
|
||||
return parse_tail<Args, end, ID>(make_text(str, POS, end - POS), fmt);
|
||||
} else {
|
||||
return parse_tail<Args, end, ID>(code_unit<char_type>{str[POS]},
|
||||
format_str);
|
||||
return parse_tail<Args, end, ID>(code_unit<char_type>{str[POS]}, fmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Args, typename S,
|
||||
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
|
||||
constexpr auto compile(S format_str) {
|
||||
constexpr auto str = basic_string_view<typename S::char_type>(format_str);
|
||||
constexpr auto compile(S fmt) {
|
||||
constexpr auto str = basic_string_view<typename S::char_type>(fmt);
|
||||
if constexpr (str.size() == 0) {
|
||||
return detail::make_text(str, 0, 0);
|
||||
} else {
|
||||
constexpr auto result =
|
||||
detail::compile_format_string<detail::type_list<Args...>, 0, 0>(
|
||||
format_str);
|
||||
detail::compile_format_string<detail::type_list<Args...>, 0, 0>(fmt);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -488,40 +504,40 @@ FMT_CONSTEXPR OutputIt format_to(OutputIt out, const S&, Args&&... args) {
|
||||
|
||||
template <typename OutputIt, typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
|
||||
auto format_to_n(OutputIt out, size_t n, const S& format_str, Args&&... args)
|
||||
auto format_to_n(OutputIt out, size_t n, const S& fmt, Args&&... args)
|
||||
-> format_to_n_result<OutputIt> {
|
||||
using traits = detail::fixed_buffer_traits;
|
||||
auto buf = detail::iterator_buffer<OutputIt, char, traits>(out, n);
|
||||
fmt::format_to(std::back_inserter(buf), format_str,
|
||||
std::forward<Args>(args)...);
|
||||
fmt::format_to(std::back_inserter(buf), fmt, std::forward<Args>(args)...);
|
||||
return {buf.out(), buf.count()};
|
||||
}
|
||||
|
||||
template <typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
|
||||
FMT_CONSTEXPR20 auto formatted_size(const S& format_str, const Args&... args)
|
||||
FMT_CONSTEXPR20 auto formatted_size(const S& fmt, const Args&... args)
|
||||
-> size_t {
|
||||
return fmt::format_to(detail::counting_iterator(), format_str, args...)
|
||||
.count();
|
||||
auto buf = detail::counting_buffer<>();
|
||||
fmt::format_to(appender(buf), fmt, args...);
|
||||
return buf.count();
|
||||
}
|
||||
|
||||
template <typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
|
||||
void print(std::FILE* f, const S& format_str, const Args&... args) {
|
||||
memory_buffer buffer;
|
||||
fmt::format_to(std::back_inserter(buffer), format_str, args...);
|
||||
detail::print(f, {buffer.data(), buffer.size()});
|
||||
void print(std::FILE* f, const S& fmt, const Args&... args) {
|
||||
auto buf = memory_buffer();
|
||||
fmt::format_to(appender(buf), fmt, args...);
|
||||
detail::print(f, {buf.data(), buf.size()});
|
||||
}
|
||||
|
||||
template <typename S, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
|
||||
void print(const S& format_str, const Args&... args) {
|
||||
print(stdout, format_str, args...);
|
||||
void print(const S& fmt, const Args&... args) {
|
||||
print(stdout, fmt, args...);
|
||||
}
|
||||
|
||||
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
|
||||
inline namespace literals {
|
||||
template <detail_exported::fixed_string Str> constexpr auto operator""_cf() {
|
||||
template <detail::fixed_string Str> constexpr auto operator""_cf() {
|
||||
using char_t = remove_cvref_t<decltype(Str.data[0])>;
|
||||
return detail::udl_compiled_string<char_t, sizeof(Str.data) / sizeof(char_t),
|
||||
Str>();
|
||||
|
||||
2972
3rdparty/fmt/include/fmt/core.h
vendored
2972
3rdparty/fmt/include/fmt/core.h
vendored
File diff suppressed because it is too large
Load Diff
395
3rdparty/fmt/include/fmt/format-inl.h
vendored
395
3rdparty/fmt/include/fmt/format-inl.h
vendored
@@ -8,36 +8,36 @@
|
||||
#ifndef FMT_FORMAT_INL_H_
|
||||
#define FMT_FORMAT_INL_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <cerrno> // errno
|
||||
#include <climits>
|
||||
#include <cmath>
|
||||
#include <exception>
|
||||
|
||||
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
|
||||
# include <locale>
|
||||
#ifndef FMT_MODULE
|
||||
# include <algorithm>
|
||||
# include <cerrno> // errno
|
||||
# include <climits>
|
||||
# include <cmath>
|
||||
# include <exception>
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && !defined(FMT_WINDOWS_NO_WCHAR)
|
||||
#if defined(_WIN32) && !defined(FMT_USE_WRITE_CONSOLE)
|
||||
# include <io.h> // _isatty
|
||||
#endif
|
||||
|
||||
#include "format.h"
|
||||
|
||||
#if FMT_USE_LOCALE
|
||||
# include <locale>
|
||||
#endif
|
||||
|
||||
#ifndef FMT_FUNC
|
||||
# define FMT_FUNC
|
||||
#endif
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
namespace detail {
|
||||
|
||||
FMT_FUNC void assert_fail(const char* file, int line, const char* message) {
|
||||
// Use unchecked std::fprintf to avoid triggering another assertion when
|
||||
// writing to stderr fails
|
||||
std::fprintf(stderr, "%s:%d: assertion failed: %s", file, line, message);
|
||||
// Chosen instead of std::abort to satisfy Clang in CUDA mode during device
|
||||
// code pass.
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
FMT_FUNC void throw_format_error(const char* message) {
|
||||
FMT_THROW(format_error(message));
|
||||
// writing to stderr fails.
|
||||
fprintf(stderr, "%s:%d: assertion failed: %s", file, line, message);
|
||||
abort();
|
||||
}
|
||||
|
||||
FMT_FUNC void format_error_code(detail::buffer<char>& out, int error_code,
|
||||
@@ -56,89 +56,105 @@ FMT_FUNC void format_error_code(detail::buffer<char>& out, int error_code,
|
||||
++error_code_size;
|
||||
}
|
||||
error_code_size += detail::to_unsigned(detail::count_digits(abs_value));
|
||||
auto it = buffer_appender<char>(out);
|
||||
auto it = appender(out);
|
||||
if (message.size() <= inline_buffer_size - error_code_size)
|
||||
fmt::format_to(it, FMT_STRING("{}{}"), message, SEP);
|
||||
fmt::format_to(it, FMT_STRING("{}{}"), ERROR_STR, error_code);
|
||||
FMT_ASSERT(out.size() <= inline_buffer_size, "");
|
||||
}
|
||||
|
||||
FMT_FUNC void report_error(format_func func, int error_code,
|
||||
const char* message) noexcept {
|
||||
FMT_FUNC void do_report_error(format_func func, int error_code,
|
||||
const char* message) noexcept {
|
||||
memory_buffer full_message;
|
||||
func(full_message, error_code, message);
|
||||
// Don't use fwrite_fully because the latter may throw.
|
||||
// Don't use fwrite_all because the latter may throw.
|
||||
if (std::fwrite(full_message.data(), full_message.size(), 1, stderr) > 0)
|
||||
std::fputc('\n', stderr);
|
||||
}
|
||||
|
||||
// A wrapper around fwrite that throws on error.
|
||||
inline void fwrite_fully(const void* ptr, size_t count, FILE* stream) {
|
||||
inline void fwrite_all(const void* ptr, size_t count, FILE* stream) {
|
||||
size_t written = std::fwrite(ptr, 1, count, stream);
|
||||
if (written < count)
|
||||
FMT_THROW(system_error(errno, FMT_STRING("cannot write to file")));
|
||||
}
|
||||
|
||||
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
|
||||
#if FMT_USE_LOCALE
|
||||
using std::locale;
|
||||
using std::numpunct;
|
||||
using std::use_facet;
|
||||
|
||||
template <typename Locale>
|
||||
locale_ref::locale_ref(const Locale& loc) : locale_(&loc) {
|
||||
static_assert(std::is_same<Locale, std::locale>::value, "");
|
||||
static_assert(std::is_same<Locale, locale>::value, "");
|
||||
}
|
||||
#else
|
||||
struct locale {};
|
||||
template <typename Char> struct numpunct {
|
||||
auto grouping() const -> std::string { return "\03"; }
|
||||
auto thousands_sep() const -> Char { return ','; }
|
||||
auto decimal_point() const -> Char { return '.'; }
|
||||
};
|
||||
template <typename Facet> Facet use_facet(locale) { return {}; }
|
||||
#endif // FMT_USE_LOCALE
|
||||
|
||||
template <typename Locale> auto locale_ref::get() const -> Locale {
|
||||
static_assert(std::is_same<Locale, std::locale>::value, "");
|
||||
return locale_ ? *static_cast<const std::locale*>(locale_) : std::locale();
|
||||
static_assert(std::is_same<Locale, locale>::value, "");
|
||||
#if FMT_USE_LOCALE
|
||||
if (locale_) return *static_cast<const locale*>(locale_);
|
||||
#endif
|
||||
return locale();
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
FMT_FUNC auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result<Char> {
|
||||
auto& facet = std::use_facet<std::numpunct<Char>>(loc.get<std::locale>());
|
||||
auto&& facet = use_facet<numpunct<Char>>(loc.get<locale>());
|
||||
auto grouping = facet.grouping();
|
||||
auto thousands_sep = grouping.empty() ? Char() : facet.thousands_sep();
|
||||
return {std::move(grouping), thousands_sep};
|
||||
}
|
||||
template <typename Char>
|
||||
FMT_FUNC auto decimal_point_impl(locale_ref loc) -> Char {
|
||||
return std::use_facet<std::numpunct<Char>>(loc.get<std::locale>())
|
||||
.decimal_point();
|
||||
return use_facet<numpunct<Char>>(loc.get<locale>()).decimal_point();
|
||||
}
|
||||
#else
|
||||
template <typename Char>
|
||||
FMT_FUNC auto thousands_sep_impl(locale_ref) -> thousands_sep_result<Char> {
|
||||
return {"\03", FMT_STATIC_THOUSANDS_SEPARATOR};
|
||||
}
|
||||
template <typename Char> FMT_FUNC Char decimal_point_impl(locale_ref) {
|
||||
return '.';
|
||||
}
|
||||
#endif
|
||||
|
||||
#if FMT_USE_LOCALE
|
||||
FMT_FUNC auto write_loc(appender out, loc_value value,
|
||||
const format_specs<>& specs, locale_ref loc) -> bool {
|
||||
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
|
||||
const format_specs& specs, locale_ref loc) -> bool {
|
||||
auto locale = loc.get<std::locale>();
|
||||
// We cannot use the num_put<char> facet because it may produce output in
|
||||
// a wrong encoding.
|
||||
using facet = format_facet<std::locale>;
|
||||
if (std::has_facet<facet>(locale))
|
||||
return std::use_facet<facet>(locale).put(out, value, specs);
|
||||
return use_facet<facet>(locale).put(out, value, specs);
|
||||
return facet(locale).put(out, value, specs);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
} // namespace detail
|
||||
|
||||
FMT_FUNC void report_error(const char* message) {
|
||||
#if FMT_USE_EXCEPTIONS
|
||||
// Use FMT_THROW instead of throw to avoid bogus unreachable code warnings
|
||||
// from MSVC.
|
||||
FMT_THROW(format_error(message));
|
||||
#else
|
||||
fputs(message, stderr);
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Locale> typename Locale::id format_facet<Locale>::id;
|
||||
|
||||
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
|
||||
template <typename Locale> format_facet<Locale>::format_facet(Locale& loc) {
|
||||
auto& numpunct = std::use_facet<std::numpunct<char>>(loc);
|
||||
grouping_ = numpunct.grouping();
|
||||
if (!grouping_.empty()) separator_ = std::string(1, numpunct.thousands_sep());
|
||||
auto& np = detail::use_facet<detail::numpunct<char>>(loc);
|
||||
grouping_ = np.grouping();
|
||||
if (!grouping_.empty()) separator_ = std::string(1, np.thousands_sep());
|
||||
}
|
||||
|
||||
#if FMT_USE_LOCALE
|
||||
template <>
|
||||
FMT_API FMT_FUNC auto format_facet<std::locale>::do_put(
|
||||
appender out, loc_value val, const format_specs<>& specs) const -> bool {
|
||||
appender out, loc_value val, const format_specs& specs) const -> bool {
|
||||
return val.visit(
|
||||
detail::loc_writer<>{out, specs, separator_, grouping_, decimal_point_});
|
||||
}
|
||||
@@ -1411,7 +1427,7 @@ FMT_FUNC void format_system_error(detail::buffer<char>& out, int error_code,
|
||||
const char* message) noexcept {
|
||||
FMT_TRY {
|
||||
auto ec = std::error_code(error_code, std::generic_category());
|
||||
write(std::back_inserter(out), std::system_error(ec, message).what());
|
||||
detail::write(appender(out), std::system_error(ec, message).what());
|
||||
return;
|
||||
}
|
||||
FMT_CATCH(...) {}
|
||||
@@ -1420,7 +1436,7 @@ FMT_FUNC void format_system_error(detail::buffer<char>& out, int error_code,
|
||||
|
||||
FMT_FUNC void report_system_error(int error_code,
|
||||
const char* message) noexcept {
|
||||
report_error(format_system_error, error_code, message);
|
||||
do_report_error(format_system_error, error_code, message);
|
||||
}
|
||||
|
||||
FMT_FUNC auto vformat(string_view fmt, format_args args) -> std::string {
|
||||
@@ -1432,9 +1448,252 @@ FMT_FUNC auto vformat(string_view fmt, format_args args) -> std::string {
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
#if !defined(_WIN32) || defined(FMT_WINDOWS_NO_WCHAR)
|
||||
|
||||
FMT_FUNC void vformat_to(buffer<char>& buf, string_view fmt, format_args args,
|
||||
locale_ref loc) {
|
||||
auto out = appender(buf);
|
||||
if (fmt.size() == 2 && equal2(fmt.data(), "{}"))
|
||||
return args.get(0).visit(default_arg_formatter<char>{out});
|
||||
parse_format_string(
|
||||
fmt, format_handler<char>{parse_context<char>(fmt), {out, args, loc}});
|
||||
}
|
||||
|
||||
template <typename T> struct span {
|
||||
T* data;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
template <typename F> auto flockfile(F* f) -> decltype(_lock_file(f)) {
|
||||
_lock_file(f);
|
||||
}
|
||||
template <typename F> auto funlockfile(F* f) -> decltype(_unlock_file(f)) {
|
||||
_unlock_file(f);
|
||||
}
|
||||
|
||||
#ifndef getc_unlocked
|
||||
template <typename F> auto getc_unlocked(F* f) -> decltype(_fgetc_nolock(f)) {
|
||||
return _fgetc_nolock(f);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename F = FILE, typename Enable = void>
|
||||
struct has_flockfile : std::false_type {};
|
||||
|
||||
template <typename F>
|
||||
struct has_flockfile<F, void_t<decltype(flockfile(&std::declval<F&>()))>>
|
||||
: std::true_type {};
|
||||
|
||||
// A FILE wrapper. F is FILE defined as a template parameter to make system API
|
||||
// detection work.
|
||||
template <typename F> class file_base {
|
||||
public:
|
||||
F* file_;
|
||||
|
||||
public:
|
||||
file_base(F* file) : file_(file) {}
|
||||
operator F*() const { return file_; }
|
||||
|
||||
// Reads a code unit from the stream.
|
||||
auto get() -> int {
|
||||
int result = getc_unlocked(file_);
|
||||
if (result == EOF && ferror(file_) != 0)
|
||||
FMT_THROW(system_error(errno, FMT_STRING("getc failed")));
|
||||
return result;
|
||||
}
|
||||
|
||||
// Puts the code unit back into the stream buffer.
|
||||
void unget(char c) {
|
||||
if (ungetc(c, file_) == EOF)
|
||||
FMT_THROW(system_error(errno, FMT_STRING("ungetc failed")));
|
||||
}
|
||||
|
||||
void flush() { fflush(this->file_); }
|
||||
};
|
||||
|
||||
// A FILE wrapper for glibc.
|
||||
template <typename F> class glibc_file : public file_base<F> {
|
||||
private:
|
||||
enum {
|
||||
line_buffered = 0x200, // _IO_LINE_BUF
|
||||
unbuffered = 2 // _IO_UNBUFFERED
|
||||
};
|
||||
|
||||
public:
|
||||
using file_base<F>::file_base;
|
||||
|
||||
auto is_buffered() const -> bool {
|
||||
return (this->file_->_flags & unbuffered) == 0;
|
||||
}
|
||||
|
||||
void init_buffer() {
|
||||
if (this->file_->_IO_write_ptr) return;
|
||||
// Force buffer initialization by placing and removing a char in a buffer.
|
||||
assume(this->file_->_IO_write_ptr >= this->file_->_IO_write_end);
|
||||
putc_unlocked(0, this->file_);
|
||||
--this->file_->_IO_write_ptr;
|
||||
}
|
||||
|
||||
// Returns the file's read buffer.
|
||||
auto get_read_buffer() const -> span<const char> {
|
||||
auto ptr = this->file_->_IO_read_ptr;
|
||||
return {ptr, to_unsigned(this->file_->_IO_read_end - ptr)};
|
||||
}
|
||||
|
||||
// Returns the file's write buffer.
|
||||
auto get_write_buffer() const -> span<char> {
|
||||
auto ptr = this->file_->_IO_write_ptr;
|
||||
return {ptr, to_unsigned(this->file_->_IO_buf_end - ptr)};
|
||||
}
|
||||
|
||||
void advance_write_buffer(size_t size) { this->file_->_IO_write_ptr += size; }
|
||||
|
||||
bool needs_flush() const {
|
||||
if ((this->file_->_flags & line_buffered) == 0) return false;
|
||||
char* end = this->file_->_IO_write_end;
|
||||
return memchr(end, '\n', to_unsigned(this->file_->_IO_write_ptr - end));
|
||||
}
|
||||
|
||||
void flush() { fflush_unlocked(this->file_); }
|
||||
};
|
||||
|
||||
// A FILE wrapper for Apple's libc.
|
||||
template <typename F> class apple_file : public file_base<F> {
|
||||
private:
|
||||
enum {
|
||||
line_buffered = 1, // __SNBF
|
||||
unbuffered = 2 // __SLBF
|
||||
};
|
||||
|
||||
public:
|
||||
using file_base<F>::file_base;
|
||||
|
||||
auto is_buffered() const -> bool {
|
||||
return (this->file_->_flags & unbuffered) == 0;
|
||||
}
|
||||
|
||||
void init_buffer() {
|
||||
if (this->file_->_p) return;
|
||||
// Force buffer initialization by placing and removing a char in a buffer.
|
||||
putc_unlocked(0, this->file_);
|
||||
--this->file_->_p;
|
||||
++this->file_->_w;
|
||||
}
|
||||
|
||||
auto get_read_buffer() const -> span<const char> {
|
||||
return {reinterpret_cast<char*>(this->file_->_p),
|
||||
to_unsigned(this->file_->_r)};
|
||||
}
|
||||
|
||||
auto get_write_buffer() const -> span<char> {
|
||||
return {reinterpret_cast<char*>(this->file_->_p),
|
||||
to_unsigned(this->file_->_bf._base + this->file_->_bf._size -
|
||||
this->file_->_p)};
|
||||
}
|
||||
|
||||
void advance_write_buffer(size_t size) {
|
||||
this->file_->_p += size;
|
||||
this->file_->_w -= size;
|
||||
}
|
||||
|
||||
bool needs_flush() const {
|
||||
if ((this->file_->_flags & line_buffered) == 0) return false;
|
||||
return memchr(this->file_->_p + this->file_->_w, '\n',
|
||||
to_unsigned(-this->file_->_w));
|
||||
}
|
||||
};
|
||||
|
||||
// A fallback FILE wrapper.
|
||||
template <typename F> class fallback_file : public file_base<F> {
|
||||
private:
|
||||
char next_; // The next unconsumed character in the buffer.
|
||||
bool has_next_ = false;
|
||||
|
||||
public:
|
||||
using file_base<F>::file_base;
|
||||
|
||||
auto is_buffered() const -> bool { return false; }
|
||||
auto needs_flush() const -> bool { return false; }
|
||||
void init_buffer() {}
|
||||
|
||||
auto get_read_buffer() const -> span<const char> {
|
||||
return {&next_, has_next_ ? 1u : 0u};
|
||||
}
|
||||
|
||||
auto get_write_buffer() const -> span<char> { return {nullptr, 0}; }
|
||||
|
||||
void advance_write_buffer(size_t) {}
|
||||
|
||||
auto get() -> int {
|
||||
has_next_ = false;
|
||||
return file_base<F>::get();
|
||||
}
|
||||
|
||||
void unget(char c) {
|
||||
file_base<F>::unget(c);
|
||||
next_ = c;
|
||||
has_next_ = true;
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef FMT_USE_FALLBACK_FILE
|
||||
# define FMT_USE_FALLBACK_FILE 0
|
||||
#endif
|
||||
|
||||
template <typename F,
|
||||
FMT_ENABLE_IF(sizeof(F::_p) != 0 && !FMT_USE_FALLBACK_FILE)>
|
||||
auto get_file(F* f, int) -> apple_file<F> {
|
||||
return f;
|
||||
}
|
||||
template <typename F,
|
||||
FMT_ENABLE_IF(sizeof(F::_IO_read_ptr) != 0 && !FMT_USE_FALLBACK_FILE)>
|
||||
inline auto get_file(F* f, int) -> glibc_file<F> {
|
||||
return f;
|
||||
}
|
||||
|
||||
inline auto get_file(FILE* f, ...) -> fallback_file<FILE> { return f; }
|
||||
|
||||
using file_ref = decltype(get_file(static_cast<FILE*>(nullptr), 0));
|
||||
|
||||
template <typename F = FILE, typename Enable = void>
|
||||
class file_print_buffer : public buffer<char> {
|
||||
public:
|
||||
explicit file_print_buffer(F*) : buffer(nullptr, size_t()) {}
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
class file_print_buffer<F, enable_if_t<has_flockfile<F>::value>>
|
||||
: public buffer<char> {
|
||||
private:
|
||||
file_ref file_;
|
||||
|
||||
static void grow(buffer<char>& base, size_t) {
|
||||
auto& self = static_cast<file_print_buffer&>(base);
|
||||
self.file_.advance_write_buffer(self.size());
|
||||
if (self.file_.get_write_buffer().size == 0) self.file_.flush();
|
||||
auto buf = self.file_.get_write_buffer();
|
||||
FMT_ASSERT(buf.size > 0, "");
|
||||
self.set(buf.data, buf.size);
|
||||
self.clear();
|
||||
}
|
||||
|
||||
public:
|
||||
explicit file_print_buffer(F* f) : buffer(grow, size_t()), file_(f) {
|
||||
flockfile(f);
|
||||
file_.init_buffer();
|
||||
auto buf = file_.get_write_buffer();
|
||||
set(buf.data, buf.size);
|
||||
}
|
||||
~file_print_buffer() {
|
||||
file_.advance_write_buffer(size());
|
||||
bool flush = file_.needs_flush();
|
||||
F* f = file_; // Make funlockfile depend on the template parameter F
|
||||
funlockfile(f); // for the system API detection to work.
|
||||
if (flush) fflush(file_);
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(_WIN32) || defined(FMT_USE_WRITE_CONSOLE)
|
||||
FMT_FUNC auto write_console(int, string_view) -> bool { return false; }
|
||||
FMT_FUNC auto write_console(std::FILE*, string_view) -> bool { return false; }
|
||||
#else
|
||||
using dword = conditional_t<sizeof(long) == 4, unsigned long, unsigned>;
|
||||
extern "C" __declspec(dllimport) int __stdcall WriteConsoleW( //
|
||||
@@ -1445,39 +1704,51 @@ FMT_FUNC bool write_console(int fd, string_view text) {
|
||||
return WriteConsoleW(reinterpret_cast<void*>(_get_osfhandle(fd)), u16.c_str(),
|
||||
static_cast<dword>(u16.size()), nullptr, nullptr) != 0;
|
||||
}
|
||||
|
||||
FMT_FUNC auto write_console(std::FILE* f, string_view text) -> bool {
|
||||
return write_console(_fileno(f), text);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
// Print assuming legacy (non-Unicode) encoding.
|
||||
FMT_FUNC void vprint_mojibake(std::FILE* f, string_view fmt, format_args args) {
|
||||
FMT_FUNC void vprint_mojibake(std::FILE* f, string_view fmt, format_args args,
|
||||
bool newline) {
|
||||
auto buffer = memory_buffer();
|
||||
detail::vformat_to(buffer, fmt, args);
|
||||
fwrite_fully(buffer.data(), buffer.size(), f);
|
||||
if (newline) buffer.push_back('\n');
|
||||
fwrite_all(buffer.data(), buffer.size(), f);
|
||||
}
|
||||
#endif
|
||||
|
||||
FMT_FUNC void print(std::FILE* f, string_view text) {
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && !defined(FMT_USE_WRITE_CONSOLE)
|
||||
int fd = _fileno(f);
|
||||
if (_isatty(fd)) {
|
||||
std::fflush(f);
|
||||
if (write_console(fd, text)) return;
|
||||
}
|
||||
#endif
|
||||
fwrite_fully(text.data(), text.size(), f);
|
||||
fwrite_all(text.data(), text.size(), f);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
FMT_FUNC void vprint(std::FILE* f, string_view fmt, format_args args) {
|
||||
FMT_FUNC void vprint_buffered(std::FILE* f, string_view fmt, format_args args) {
|
||||
auto buffer = memory_buffer();
|
||||
detail::vformat_to(buffer, fmt, args);
|
||||
detail::print(f, {buffer.data(), buffer.size()});
|
||||
}
|
||||
|
||||
FMT_FUNC void vprint(std::FILE* f, string_view fmt, format_args args) {
|
||||
if (!detail::file_ref(f).is_buffered() || !detail::has_flockfile<>())
|
||||
return vprint_buffered(f, fmt, args);
|
||||
auto&& buffer = detail::file_print_buffer<>(f);
|
||||
return detail::vformat_to(buffer, fmt, args);
|
||||
}
|
||||
|
||||
FMT_FUNC void vprintln(std::FILE* f, string_view fmt, format_args args) {
|
||||
auto buffer = memory_buffer();
|
||||
detail::vformat_to(buffer, fmt, args);
|
||||
buffer.push_back('\n');
|
||||
detail::print(f, {buffer.data(), buffer.size()});
|
||||
}
|
||||
|
||||
FMT_FUNC void vprint(string_view fmt, format_args args) {
|
||||
vprint(stdout, fmt, args);
|
||||
}
|
||||
|
||||
3059
3rdparty/fmt/include/fmt/format.h
vendored
3059
3rdparty/fmt/include/fmt/format.h
vendored
File diff suppressed because it is too large
Load Diff
272
3rdparty/fmt/include/fmt/os.h
vendored
272
3rdparty/fmt/include/fmt/os.h
vendored
@@ -8,18 +8,18 @@
|
||||
#ifndef FMT_OS_H_
|
||||
#define FMT_OS_H_
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
#include <system_error> // std::system_error
|
||||
|
||||
#include "format.h"
|
||||
|
||||
#if defined __APPLE__ || defined(__FreeBSD__)
|
||||
#ifndef FMT_MODULE
|
||||
# include <cerrno>
|
||||
# include <cstddef>
|
||||
# include <cstdio>
|
||||
# include <system_error> // std::system_error
|
||||
|
||||
# if FMT_HAS_INCLUDE(<xlocale.h>)
|
||||
# include <xlocale.h> // for LC_NUMERIC_MASK on OS X
|
||||
# include <xlocale.h> // LC_NUMERIC_MASK on macOS
|
||||
# endif
|
||||
#endif
|
||||
#endif // FMT_MODULE
|
||||
|
||||
#ifndef FMT_USE_FCNTL
|
||||
// UWP doesn't provide _pipe.
|
||||
@@ -77,46 +77,33 @@ FMT_BEGIN_NAMESPACE
|
||||
FMT_BEGIN_EXPORT
|
||||
|
||||
/**
|
||||
\rst
|
||||
A reference to a null-terminated string. It can be constructed from a C
|
||||
string or ``std::string``.
|
||||
|
||||
You can use one of the following type aliases for common character types:
|
||||
|
||||
+---------------+-----------------------------+
|
||||
| Type | Definition |
|
||||
+===============+=============================+
|
||||
| cstring_view | basic_cstring_view<char> |
|
||||
+---------------+-----------------------------+
|
||||
| wcstring_view | basic_cstring_view<wchar_t> |
|
||||
+---------------+-----------------------------+
|
||||
|
||||
This class is most useful as a parameter type to allow passing
|
||||
different types of strings to a function, for example::
|
||||
|
||||
template <typename... Args>
|
||||
std::string format(cstring_view format_str, const Args & ... args);
|
||||
|
||||
format("{}", 42);
|
||||
format(std::string("{}"), 42);
|
||||
\endrst
|
||||
* A reference to a null-terminated string. It can be constructed from a C
|
||||
* string or `std::string`.
|
||||
*
|
||||
* You can use one of the following type aliases for common character types:
|
||||
*
|
||||
* +---------------+-----------------------------+
|
||||
* | Type | Definition |
|
||||
* +===============+=============================+
|
||||
* | cstring_view | basic_cstring_view<char> |
|
||||
* +---------------+-----------------------------+
|
||||
* | wcstring_view | basic_cstring_view<wchar_t> |
|
||||
* +---------------+-----------------------------+
|
||||
*
|
||||
* This class is most useful as a parameter type for functions that wrap C APIs.
|
||||
*/
|
||||
template <typename Char> class basic_cstring_view {
|
||||
private:
|
||||
const Char* data_;
|
||||
|
||||
public:
|
||||
/** Constructs a string reference object from a C string. */
|
||||
/// Constructs a string reference object from a C string.
|
||||
basic_cstring_view(const Char* s) : data_(s) {}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Constructs a string reference from an ``std::string`` object.
|
||||
\endrst
|
||||
*/
|
||||
/// Constructs a string reference from an `std::string` object.
|
||||
basic_cstring_view(const std::basic_string<Char>& s) : data_(s.c_str()) {}
|
||||
|
||||
/** Returns the pointer to a C string. */
|
||||
/// Returns the pointer to a C string.
|
||||
auto c_str() const -> const Char* { return data_; }
|
||||
};
|
||||
|
||||
@@ -131,41 +118,38 @@ FMT_API void format_windows_error(buffer<char>& out, int error_code,
|
||||
const char* message) noexcept;
|
||||
}
|
||||
|
||||
FMT_API std::system_error vwindows_error(int error_code, string_view format_str,
|
||||
FMT_API std::system_error vwindows_error(int error_code, string_view fmt,
|
||||
format_args args);
|
||||
|
||||
/**
|
||||
\rst
|
||||
Constructs a :class:`std::system_error` object with the description
|
||||
of the form
|
||||
|
||||
.. parsed-literal::
|
||||
*<message>*: *<system-message>*
|
||||
|
||||
where *<message>* is the formatted message and *<system-message>* is the
|
||||
system message corresponding to the error code.
|
||||
*error_code* is a Windows error code as given by ``GetLastError``.
|
||||
If *error_code* is not a valid error code such as -1, the system message
|
||||
will look like "error -1".
|
||||
|
||||
**Example**::
|
||||
|
||||
// This throws a system_error with the description
|
||||
// cannot open file 'madeup': The system cannot find the file specified.
|
||||
// or similar (system message may vary).
|
||||
const char *filename = "madeup";
|
||||
LPOFSTRUCT of = LPOFSTRUCT();
|
||||
HFILE file = OpenFile(filename, &of, OF_READ);
|
||||
if (file == HFILE_ERROR) {
|
||||
throw fmt::windows_error(GetLastError(),
|
||||
"cannot open file '{}'", filename);
|
||||
}
|
||||
\endrst
|
||||
*/
|
||||
template <typename... Args>
|
||||
std::system_error windows_error(int error_code, string_view message,
|
||||
const Args&... args) {
|
||||
return vwindows_error(error_code, message, fmt::make_format_args(args...));
|
||||
* Constructs a `std::system_error` object with the description of the form
|
||||
*
|
||||
* <message>: <system-message>
|
||||
*
|
||||
* where `<message>` is the formatted message and `<system-message>` is the
|
||||
* system message corresponding to the error code.
|
||||
* `error_code` is a Windows error code as given by `GetLastError`.
|
||||
* If `error_code` is not a valid error code such as -1, the system message
|
||||
* will look like "error -1".
|
||||
*
|
||||
* **Example**:
|
||||
*
|
||||
* // This throws a system_error with the description
|
||||
* // cannot open file 'madeup': The system cannot find the file
|
||||
* specified.
|
||||
* // or similar (system message may vary).
|
||||
* const char *filename = "madeup";
|
||||
* LPOFSTRUCT of = LPOFSTRUCT();
|
||||
* HFILE file = OpenFile(filename, &of, OF_READ);
|
||||
* if (file == HFILE_ERROR) {
|
||||
* throw fmt::windows_error(GetLastError(),
|
||||
* "cannot open file '{}'", filename);
|
||||
* }
|
||||
*/
|
||||
template <typename... T>
|
||||
auto windows_error(int error_code, string_view message, const T&... args)
|
||||
-> std::system_error {
|
||||
return vwindows_error(error_code, message, vargs<T...>{{args...}});
|
||||
}
|
||||
|
||||
// Reports a Windows error without throwing an exception.
|
||||
@@ -180,8 +164,8 @@ inline auto system_category() noexcept -> const std::error_category& {
|
||||
// std::system is not available on some platforms such as iOS (#2248).
|
||||
#ifdef __OSX__
|
||||
template <typename S, typename... Args, typename Char = char_t<S>>
|
||||
void say(const S& format_str, Args&&... args) {
|
||||
std::system(format("say \"{}\"", format(format_str, args...)).c_str());
|
||||
void say(const S& fmt, Args&&... args) {
|
||||
std::system(format("say \"{}\"", format(fmt, args...)).c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -192,24 +176,24 @@ class buffered_file {
|
||||
|
||||
friend class file;
|
||||
|
||||
explicit buffered_file(FILE* f) : file_(f) {}
|
||||
inline explicit buffered_file(FILE* f) : file_(f) {}
|
||||
|
||||
public:
|
||||
buffered_file(const buffered_file&) = delete;
|
||||
void operator=(const buffered_file&) = delete;
|
||||
|
||||
// Constructs a buffered_file object which doesn't represent any file.
|
||||
buffered_file() noexcept : file_(nullptr) {}
|
||||
inline buffered_file() noexcept : file_(nullptr) {}
|
||||
|
||||
// Destroys the object closing the file it represents if any.
|
||||
FMT_API ~buffered_file() noexcept;
|
||||
|
||||
public:
|
||||
buffered_file(buffered_file&& other) noexcept : file_(other.file_) {
|
||||
inline buffered_file(buffered_file&& other) noexcept : file_(other.file_) {
|
||||
other.file_ = nullptr;
|
||||
}
|
||||
|
||||
auto operator=(buffered_file&& other) -> buffered_file& {
|
||||
inline auto operator=(buffered_file&& other) -> buffered_file& {
|
||||
close();
|
||||
file_ = other.file_;
|
||||
other.file_ = nullptr;
|
||||
@@ -223,21 +207,20 @@ class buffered_file {
|
||||
FMT_API void close();
|
||||
|
||||
// Returns the pointer to a FILE object representing this file.
|
||||
auto get() const noexcept -> FILE* { return file_; }
|
||||
inline auto get() const noexcept -> FILE* { return file_; }
|
||||
|
||||
FMT_API auto descriptor() const -> int;
|
||||
|
||||
void vprint(string_view format_str, format_args args) {
|
||||
fmt::vprint(file_, format_str, args);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void print(string_view format_str, const Args&... args) {
|
||||
vprint(format_str, fmt::make_format_args(args...));
|
||||
template <typename... T>
|
||||
inline void print(string_view fmt, const T&... args) {
|
||||
fmt::vargs<T...> vargs = {{args...}};
|
||||
detail::is_locking<T...>() ? fmt::vprint_buffered(file_, fmt, vargs)
|
||||
: fmt::vprint(file_, fmt, vargs);
|
||||
}
|
||||
};
|
||||
|
||||
#if FMT_USE_FCNTL
|
||||
|
||||
// A file. Closed file is represented by a file object with descriptor -1.
|
||||
// Methods that are not declared with noexcept may throw
|
||||
// fmt::system_error in case of failure. Note that some errors such as
|
||||
@@ -251,6 +234,8 @@ class FMT_API file {
|
||||
// Constructs a file object with a given descriptor.
|
||||
explicit file(int fd) : fd_(fd) {}
|
||||
|
||||
friend struct pipe;
|
||||
|
||||
public:
|
||||
// Possible values for the oflag argument to the constructor.
|
||||
enum {
|
||||
@@ -263,7 +248,7 @@ class FMT_API file {
|
||||
};
|
||||
|
||||
// Constructs a file object which doesn't represent any file.
|
||||
file() noexcept : fd_(-1) {}
|
||||
inline file() noexcept : fd_(-1) {}
|
||||
|
||||
// Opens a file and constructs a file object representing this file.
|
||||
file(cstring_view path, int oflag);
|
||||
@@ -272,10 +257,10 @@ class FMT_API file {
|
||||
file(const file&) = delete;
|
||||
void operator=(const file&) = delete;
|
||||
|
||||
file(file&& other) noexcept : fd_(other.fd_) { other.fd_ = -1; }
|
||||
inline file(file&& other) noexcept : fd_(other.fd_) { other.fd_ = -1; }
|
||||
|
||||
// Move assignment is not noexcept because close may throw.
|
||||
auto operator=(file&& other) -> file& {
|
||||
inline auto operator=(file&& other) -> file& {
|
||||
close();
|
||||
fd_ = other.fd_;
|
||||
other.fd_ = -1;
|
||||
@@ -286,7 +271,7 @@ class FMT_API file {
|
||||
~file() noexcept;
|
||||
|
||||
// Returns the file descriptor.
|
||||
auto descriptor() const noexcept -> int { return fd_; }
|
||||
inline auto descriptor() const noexcept -> int { return fd_; }
|
||||
|
||||
// Closes the file.
|
||||
void close();
|
||||
@@ -313,11 +298,6 @@ class FMT_API file {
|
||||
// necessary.
|
||||
void dup2(int fd, std::error_code& ec) noexcept;
|
||||
|
||||
// Creates a pipe setting up read_end and write_end file objects for reading
|
||||
// and writing respectively.
|
||||
// DEPRECATED! Taking files as out parameters is deprecated.
|
||||
static void pipe(file& read_end, file& write_end);
|
||||
|
||||
// Creates a buffered_file object associated with this file and detaches
|
||||
// this file object from the file.
|
||||
auto fdopen(const char* mode) -> buffered_file;
|
||||
@@ -329,15 +309,24 @@ class FMT_API file {
|
||||
# endif
|
||||
};
|
||||
|
||||
struct FMT_API pipe {
|
||||
file read_end;
|
||||
file write_end;
|
||||
|
||||
// Creates a pipe setting up read_end and write_end file objects for reading
|
||||
// and writing respectively.
|
||||
pipe();
|
||||
};
|
||||
|
||||
// Returns the memory page size.
|
||||
auto getpagesize() -> long;
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct buffer_size {
|
||||
buffer_size() = default;
|
||||
constexpr buffer_size() = default;
|
||||
size_t value = 0;
|
||||
auto operator=(size_t val) const -> buffer_size {
|
||||
FMT_CONSTEXPR auto operator=(size_t val) const -> buffer_size {
|
||||
auto bs = buffer_size();
|
||||
bs.value = val;
|
||||
return bs;
|
||||
@@ -348,7 +337,7 @@ struct ostream_params {
|
||||
int oflag = file::WRONLY | file::CREATE | file::TRUNC;
|
||||
size_t buffer_size = BUFSIZ > 32768 ? BUFSIZ : 32768;
|
||||
|
||||
ostream_params() {}
|
||||
constexpr ostream_params() {}
|
||||
|
||||
template <typename... T>
|
||||
ostream_params(T... params, int new_oflag) : ostream_params(params...) {
|
||||
@@ -369,79 +358,62 @@ struct ostream_params {
|
||||
# endif
|
||||
};
|
||||
|
||||
class file_buffer final : public buffer<char> {
|
||||
} // namespace detail
|
||||
|
||||
FMT_INLINE_VARIABLE constexpr auto buffer_size = detail::buffer_size();
|
||||
|
||||
/// A fast buffered output stream for writing from a single thread. Writing from
|
||||
/// multiple threads without external synchronization may result in a data race.
|
||||
class FMT_API ostream : private detail::buffer<char> {
|
||||
private:
|
||||
file file_;
|
||||
|
||||
FMT_API void grow(size_t) override;
|
||||
ostream(cstring_view path, const detail::ostream_params& params);
|
||||
|
||||
static void grow(buffer<char>& buf, size_t);
|
||||
|
||||
public:
|
||||
FMT_API file_buffer(cstring_view path, const ostream_params& params);
|
||||
FMT_API file_buffer(file_buffer&& other);
|
||||
FMT_API ~file_buffer();
|
||||
ostream(ostream&& other) noexcept;
|
||||
~ostream();
|
||||
|
||||
void flush() {
|
||||
operator writer() {
|
||||
detail::buffer<char>& buf = *this;
|
||||
return buf;
|
||||
}
|
||||
|
||||
inline void flush() {
|
||||
if (size() == 0) return;
|
||||
file_.write(data(), size() * sizeof(data()[0]));
|
||||
clear();
|
||||
}
|
||||
|
||||
void close() {
|
||||
flush();
|
||||
file_.close();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// Added {} below to work around default constructor error known to
|
||||
// occur in Xcode versions 7.2.1 and 8.2.1.
|
||||
constexpr detail::buffer_size buffer_size{};
|
||||
|
||||
/** A fast output stream which is not thread-safe. */
|
||||
class FMT_API ostream {
|
||||
private:
|
||||
FMT_MSC_WARNING(suppress : 4251)
|
||||
detail::file_buffer buffer_;
|
||||
|
||||
ostream(cstring_view path, const detail::ostream_params& params)
|
||||
: buffer_(path, params) {}
|
||||
|
||||
public:
|
||||
ostream(ostream&& other) : buffer_(std::move(other.buffer_)) {}
|
||||
|
||||
~ostream();
|
||||
|
||||
void flush() { buffer_.flush(); }
|
||||
|
||||
template <typename... T>
|
||||
friend auto output_file(cstring_view path, T... params) -> ostream;
|
||||
|
||||
void close() { buffer_.close(); }
|
||||
inline void close() {
|
||||
flush();
|
||||
file_.close();
|
||||
}
|
||||
|
||||
/**
|
||||
Formats ``args`` according to specifications in ``fmt`` and writes the
|
||||
output to the file.
|
||||
*/
|
||||
/// Formats `args` according to specifications in `fmt` and writes the
|
||||
/// output to the file.
|
||||
template <typename... T> void print(format_string<T...> fmt, T&&... args) {
|
||||
vformat_to(std::back_inserter(buffer_), fmt,
|
||||
fmt::make_format_args(args...));
|
||||
vformat_to(appender(*this), fmt.str, vargs<T...>{{args...}});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
\rst
|
||||
Opens a file for writing. Supported parameters passed in *params*:
|
||||
|
||||
* ``<integer>``: Flags passed to `open
|
||||
<https://pubs.opengroup.org/onlinepubs/007904875/functions/open.html>`_
|
||||
(``file::WRONLY | file::CREATE | file::TRUNC`` by default)
|
||||
* ``buffer_size=<integer>``: Output buffer size
|
||||
|
||||
**Example**::
|
||||
|
||||
auto out = fmt::output_file("guide.txt");
|
||||
out.print("Don't {}", "Panic");
|
||||
\endrst
|
||||
* Opens a file for writing. Supported parameters passed in `params`:
|
||||
*
|
||||
* - `<integer>`: Flags passed to [open](
|
||||
* https://pubs.opengroup.org/onlinepubs/007904875/functions/open.html)
|
||||
* (`file::WRONLY | file::CREATE | file::TRUNC` by default)
|
||||
* - `buffer_size=<integer>`: Output buffer size
|
||||
*
|
||||
* **Example**:
|
||||
*
|
||||
* auto out = fmt::output_file("guide.txt");
|
||||
* out.print("Don't {}", "Panic");
|
||||
*/
|
||||
template <typename... T>
|
||||
inline auto output_file(cstring_view path, T... params) -> ostream {
|
||||
|
||||
205
3rdparty/fmt/include/fmt/ostream.h
vendored
205
3rdparty/fmt/include/fmt/ostream.h
vendored
@@ -8,7 +8,9 @@
|
||||
#ifndef FMT_OSTREAM_H_
|
||||
#define FMT_OSTREAM_H_
|
||||
|
||||
#include <fstream> // std::filebuf
|
||||
#ifndef FMT_MODULE
|
||||
# include <fstream> // std::filebuf
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef __GLIBCXX__
|
||||
@@ -18,42 +20,19 @@
|
||||
# include <io.h>
|
||||
#endif
|
||||
|
||||
#include "format.h"
|
||||
#include "chrono.h" // formatbuf
|
||||
|
||||
#ifdef _MSVC_STL_UPDATE
|
||||
# define FMT_MSVC_STL_UPDATE _MSVC_STL_UPDATE
|
||||
#elif defined(_MSC_VER) && _MSC_VER < 1912 // VS 15.5
|
||||
# define FMT_MSVC_STL_UPDATE _MSVC_LANG
|
||||
#else
|
||||
# define FMT_MSVC_STL_UPDATE 0
|
||||
#endif
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
namespace detail {
|
||||
|
||||
template <typename Streambuf> class formatbuf : public Streambuf {
|
||||
private:
|
||||
using char_type = typename Streambuf::char_type;
|
||||
using streamsize = decltype(std::declval<Streambuf>().sputn(nullptr, 0));
|
||||
using int_type = typename Streambuf::int_type;
|
||||
using traits_type = typename Streambuf::traits_type;
|
||||
|
||||
buffer<char_type>& buffer_;
|
||||
|
||||
public:
|
||||
explicit formatbuf(buffer<char_type>& buf) : buffer_(buf) {}
|
||||
|
||||
protected:
|
||||
// The put area is always empty. This makes the implementation simpler and has
|
||||
// the advantage that the streambuf and the buffer are always in sync and
|
||||
// sputc never writes into uninitialized memory. A disadvantage is that each
|
||||
// call to sputc always results in a (virtual) call to overflow. There is no
|
||||
// disadvantage here for sputn since this always results in a call to xsputn.
|
||||
|
||||
auto overflow(int_type ch) -> int_type override {
|
||||
if (!traits_type::eq_int_type(ch, traits_type::eof()))
|
||||
buffer_.push_back(static_cast<char_type>(ch));
|
||||
return ch;
|
||||
}
|
||||
|
||||
auto xsputn(const char_type* s, streamsize count) -> streamsize override {
|
||||
buffer_.append(s, s + count);
|
||||
return count;
|
||||
}
|
||||
};
|
||||
|
||||
// Generate a unique explicit instantion in every translation unit using a tag
|
||||
// type in an anonymous namespace.
|
||||
namespace {
|
||||
@@ -64,53 +43,18 @@ class file_access {
|
||||
friend auto get_file(BufType& obj) -> FILE* { return obj.*FileMemberPtr; }
|
||||
};
|
||||
|
||||
#if FMT_MSC_VERSION
|
||||
#if FMT_MSVC_STL_UPDATE
|
||||
template class file_access<file_access_tag, std::filebuf,
|
||||
&std::filebuf::_Myfile>;
|
||||
auto get_file(std::filebuf&) -> FILE*;
|
||||
#endif
|
||||
|
||||
inline auto write_ostream_unicode(std::ostream& os, fmt::string_view data)
|
||||
-> bool {
|
||||
FILE* f = nullptr;
|
||||
#if FMT_MSC_VERSION && false
|
||||
if (auto* buf = dynamic_cast<std::filebuf*>(os.rdbuf()))
|
||||
f = get_file(*buf);
|
||||
else
|
||||
return false;
|
||||
#elif defined(_WIN32) && defined(__GLIBCXX__)
|
||||
auto* rdbuf = os.rdbuf();
|
||||
if (auto* sfbuf = dynamic_cast<__gnu_cxx::stdio_sync_filebuf<char>*>(rdbuf))
|
||||
f = sfbuf->file();
|
||||
else if (auto* fbuf = dynamic_cast<__gnu_cxx::stdio_filebuf<char>*>(rdbuf))
|
||||
f = fbuf->file();
|
||||
else
|
||||
return false;
|
||||
#else
|
||||
ignore_unused(os, data, f);
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
if (f) {
|
||||
int fd = _fileno(f);
|
||||
if (_isatty(fd)) {
|
||||
os.flush();
|
||||
return write_console(fd, data);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
inline auto write_ostream_unicode(std::wostream&,
|
||||
fmt::basic_string_view<wchar_t>) -> bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write the content of buf to os.
|
||||
// It is a separate function rather than a part of vprint to simplify testing.
|
||||
template <typename Char>
|
||||
void write_buffer(std::basic_ostream<Char>& os, buffer<Char>& buf) {
|
||||
const Char* buf_data = buf.data();
|
||||
using unsigned_streamsize = std::make_unsigned<std::streamsize>::type;
|
||||
using unsigned_streamsize = make_unsigned_t<std::streamsize>;
|
||||
unsigned_streamsize size = buf.size();
|
||||
unsigned_streamsize max_size = to_unsigned(max_value<std::streamsize>());
|
||||
do {
|
||||
@@ -121,21 +65,9 @@ void write_buffer(std::basic_ostream<Char>& os, buffer<Char>& buf) {
|
||||
} while (size != 0);
|
||||
}
|
||||
|
||||
template <typename Char, typename T>
|
||||
void format_value(buffer<Char>& buf, const T& value) {
|
||||
auto&& format_buf = formatbuf<std::basic_streambuf<Char>>(buf);
|
||||
auto&& output = std::basic_ostream<Char>(&format_buf);
|
||||
#if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
|
||||
output.imbue(std::locale::classic()); // The default is always unlocalized.
|
||||
#endif
|
||||
output << value;
|
||||
output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
|
||||
}
|
||||
|
||||
template <typename T> struct streamed_view {
|
||||
const T& value;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// Formats an object of type T that has an overloaded ostream operator<<.
|
||||
@@ -143,11 +75,14 @@ template <typename Char>
|
||||
struct basic_ostream_formatter : formatter<basic_string_view<Char>, Char> {
|
||||
void set_debug_format() = delete;
|
||||
|
||||
template <typename T, typename OutputIt>
|
||||
auto format(const T& value, basic_format_context<OutputIt, Char>& ctx) const
|
||||
-> OutputIt {
|
||||
template <typename T, typename Context>
|
||||
auto format(const T& value, Context& ctx) const -> decltype(ctx.out()) {
|
||||
auto buffer = basic_memory_buffer<Char>();
|
||||
detail::format_value(buffer, value);
|
||||
auto&& formatbuf = detail::formatbuf<std::basic_streambuf<Char>>(buffer);
|
||||
auto&& output = std::basic_ostream<Char>(&formatbuf);
|
||||
output.imbue(std::locale::classic()); // The default is always unlocalized.
|
||||
output << value;
|
||||
output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
|
||||
return formatter<basic_string_view<Char>, Char>::format(
|
||||
{buffer.data(), buffer.size()}, ctx);
|
||||
}
|
||||
@@ -158,73 +93,67 @@ using ostream_formatter = basic_ostream_formatter<char>;
|
||||
template <typename T, typename Char>
|
||||
struct formatter<detail::streamed_view<T>, Char>
|
||||
: basic_ostream_formatter<Char> {
|
||||
template <typename OutputIt>
|
||||
auto format(detail::streamed_view<T> view,
|
||||
basic_format_context<OutputIt, Char>& ctx) const -> OutputIt {
|
||||
template <typename Context>
|
||||
auto format(detail::streamed_view<T> view, Context& ctx) const
|
||||
-> decltype(ctx.out()) {
|
||||
return basic_ostream_formatter<Char>::format(view.value, ctx);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
\rst
|
||||
Returns a view that formats `value` via an ostream ``operator<<``.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::print("Current thread id: {}\n",
|
||||
fmt::streamed(std::this_thread::get_id()));
|
||||
\endrst
|
||||
* Returns a view that formats `value` via an ostream `operator<<`.
|
||||
*
|
||||
* **Example**:
|
||||
*
|
||||
* fmt::print("Current thread id: {}\n",
|
||||
* fmt::streamed(std::this_thread::get_id()));
|
||||
*/
|
||||
template <typename T>
|
||||
constexpr auto streamed(const T& value) -> detail::streamed_view<T> {
|
||||
return {value};
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
inline void vprint_directly(std::ostream& os, string_view format_str,
|
||||
format_args args) {
|
||||
inline void vprint(std::ostream& os, string_view fmt, format_args args) {
|
||||
auto buffer = memory_buffer();
|
||||
detail::vformat_to(buffer, format_str, args);
|
||||
detail::write_buffer(os, buffer);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
FMT_EXPORT template <typename Char>
|
||||
void vprint(std::basic_ostream<Char>& os,
|
||||
basic_string_view<type_identity_t<Char>> format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
||||
auto buffer = basic_memory_buffer<Char>();
|
||||
detail::vformat_to(buffer, format_str, args);
|
||||
if (detail::write_ostream_unicode(os, {buffer.data(), buffer.size()})) return;
|
||||
detail::vformat_to(buffer, fmt, args);
|
||||
FILE* f = nullptr;
|
||||
#if FMT_MSVC_STL_UPDATE && FMT_USE_RTTI
|
||||
if (auto* buf = dynamic_cast<std::filebuf*>(os.rdbuf()))
|
||||
f = detail::get_file(*buf);
|
||||
#elif defined(_WIN32) && defined(__GLIBCXX__) && FMT_USE_RTTI
|
||||
auto* rdbuf = os.rdbuf();
|
||||
if (auto* sfbuf = dynamic_cast<__gnu_cxx::stdio_sync_filebuf<char>*>(rdbuf))
|
||||
f = sfbuf->file();
|
||||
else if (auto* fbuf = dynamic_cast<__gnu_cxx::stdio_filebuf<char>*>(rdbuf))
|
||||
f = fbuf->file();
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
if (f) {
|
||||
int fd = _fileno(f);
|
||||
if (_isatty(fd)) {
|
||||
os.flush();
|
||||
if (detail::write_console(fd, {buffer.data(), buffer.size()})) return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
detail::ignore_unused(f);
|
||||
detail::write_buffer(os, buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Prints formatted data to the stream *os*.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::print(cerr, "Don't {}!", "panic");
|
||||
\endrst
|
||||
* Prints formatted data to the stream `os`.
|
||||
*
|
||||
* **Example**:
|
||||
*
|
||||
* fmt::print(cerr, "Don't {}!", "panic");
|
||||
*/
|
||||
FMT_EXPORT template <typename... T>
|
||||
void print(std::ostream& os, format_string<T...> fmt, T&&... args) {
|
||||
const auto& vargs = fmt::make_format_args(args...);
|
||||
if (detail::is_utf8())
|
||||
vprint(os, fmt, vargs);
|
||||
else
|
||||
detail::vprint_directly(os, fmt, vargs);
|
||||
}
|
||||
|
||||
FMT_EXPORT
|
||||
template <typename... Args>
|
||||
void print(std::wostream& os,
|
||||
basic_format_string<wchar_t, type_identity_t<Args>...> fmt,
|
||||
Args&&... args) {
|
||||
vprint(os, fmt, fmt::make_format_args<buffer_context<wchar_t>>(args...));
|
||||
fmt::vargs<T...> vargs = {{args...}};
|
||||
if (detail::use_utf8) return vprint(os, fmt.str, vargs);
|
||||
auto buffer = memory_buffer();
|
||||
detail::vformat_to(buffer, fmt.str, vargs);
|
||||
detail::write_buffer(os, buffer);
|
||||
}
|
||||
|
||||
FMT_EXPORT template <typename... T>
|
||||
@@ -232,14 +161,6 @@ void println(std::ostream& os, format_string<T...> fmt, T&&... args) {
|
||||
fmt::print(os, "{}\n", fmt::format(fmt, std::forward<T>(args)...));
|
||||
}
|
||||
|
||||
FMT_EXPORT
|
||||
template <typename... Args>
|
||||
void println(std::wostream& os,
|
||||
basic_format_string<wchar_t, type_identity_t<Args>...> fmt,
|
||||
Args&&... args) {
|
||||
print(os, L"{}\n", fmt::format(fmt, std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_OSTREAM_H_
|
||||
|
||||
412
3rdparty/fmt/include/fmt/printf.h
vendored
412
3rdparty/fmt/include/fmt/printf.h
vendored
@@ -8,8 +8,10 @@
|
||||
#ifndef FMT_PRINTF_H_
|
||||
#define FMT_PRINTF_H_
|
||||
|
||||
#include <algorithm> // std::max
|
||||
#include <limits> // std::numeric_limits
|
||||
#ifndef FMT_MODULE
|
||||
# include <algorithm> // std::max
|
||||
# include <limits> // std::numeric_limits
|
||||
#endif
|
||||
|
||||
#include "format.h"
|
||||
|
||||
@@ -22,7 +24,7 @@ template <typename T> struct printf_formatter {
|
||||
|
||||
template <typename Char> class basic_printf_context {
|
||||
private:
|
||||
detail::buffer_appender<Char> out_;
|
||||
basic_appender<Char> out_;
|
||||
basic_format_args<basic_printf_context> args_;
|
||||
|
||||
static_assert(std::is_same<Char, char>::value ||
|
||||
@@ -31,43 +33,53 @@ template <typename Char> class basic_printf_context {
|
||||
|
||||
public:
|
||||
using char_type = Char;
|
||||
using parse_context_type = basic_format_parse_context<Char>;
|
||||
using parse_context_type = parse_context<Char>;
|
||||
template <typename T> using formatter_type = printf_formatter<T>;
|
||||
enum { builtin_types = 1 };
|
||||
|
||||
/**
|
||||
\rst
|
||||
Constructs a ``printf_context`` object. References to the arguments are
|
||||
stored in the context object so make sure they have appropriate lifetimes.
|
||||
\endrst
|
||||
*/
|
||||
basic_printf_context(detail::buffer_appender<Char> out,
|
||||
/// Constructs a `printf_context` object. References to the arguments are
|
||||
/// stored in the context object so make sure they have appropriate lifetimes.
|
||||
basic_printf_context(basic_appender<Char> out,
|
||||
basic_format_args<basic_printf_context> args)
|
||||
: out_(out), args_(args) {}
|
||||
|
||||
auto out() -> detail::buffer_appender<Char> { return out_; }
|
||||
void advance_to(detail::buffer_appender<Char>) {}
|
||||
auto out() -> basic_appender<Char> { return out_; }
|
||||
void advance_to(basic_appender<Char>) {}
|
||||
|
||||
auto locale() -> detail::locale_ref { return {}; }
|
||||
|
||||
auto arg(int id) const -> basic_format_arg<basic_printf_context> {
|
||||
return args_.get(id);
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void on_error(const char* message) {
|
||||
detail::error_handler().on_error(message);
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Return the result via the out param to workaround gcc bug 77539.
|
||||
template <bool IS_CONSTEXPR, typename T, typename Ptr = const T*>
|
||||
FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr& out) -> bool {
|
||||
for (out = first; out != last; ++out) {
|
||||
if (*out == value) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline auto find<false, char>(const char* first, const char* last, char value,
|
||||
const char*& out) -> bool {
|
||||
out =
|
||||
static_cast<const char*>(memchr(first, value, to_unsigned(last - first)));
|
||||
return out != nullptr;
|
||||
}
|
||||
|
||||
// Checks if a value fits in int - used to avoid warnings about comparing
|
||||
// signed and unsigned integers.
|
||||
template <bool IsSigned> struct int_checker {
|
||||
template <typename T> static auto fits_in_int(T value) -> bool {
|
||||
unsigned max = max_value<int>();
|
||||
unsigned max = to_unsigned(max_value<int>());
|
||||
return value <= max;
|
||||
}
|
||||
static auto fits_in_int(bool) -> bool { return true; }
|
||||
inline static auto fits_in_int(bool) -> bool { return true; }
|
||||
};
|
||||
|
||||
template <> struct int_checker<true> {
|
||||
@@ -75,20 +87,20 @@ template <> struct int_checker<true> {
|
||||
return value >= (std::numeric_limits<int>::min)() &&
|
||||
value <= max_value<int>();
|
||||
}
|
||||
static auto fits_in_int(int) -> bool { return true; }
|
||||
inline static auto fits_in_int(int) -> bool { return true; }
|
||||
};
|
||||
|
||||
struct printf_precision_handler {
|
||||
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
|
||||
auto operator()(T value) -> int {
|
||||
if (!int_checker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
|
||||
throw_format_error("number is too big");
|
||||
report_error("number is too big");
|
||||
return (std::max)(static_cast<int>(value), 0);
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
|
||||
auto operator()(T) -> int {
|
||||
throw_format_error("precision is not integer");
|
||||
report_error("precision is not integer");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
@@ -133,25 +145,19 @@ template <typename T, typename Context> class arg_converter {
|
||||
using target_type = conditional_t<std::is_same<T, void>::value, U, T>;
|
||||
if (const_check(sizeof(target_type) <= sizeof(int))) {
|
||||
// Extra casts are used to silence warnings.
|
||||
if (is_signed) {
|
||||
auto n = static_cast<int>(static_cast<target_type>(value));
|
||||
arg_ = detail::make_arg<Context>(n);
|
||||
} else {
|
||||
using unsigned_type = typename make_unsigned_or_bool<target_type>::type;
|
||||
auto n = static_cast<unsigned>(static_cast<unsigned_type>(value));
|
||||
arg_ = detail::make_arg<Context>(n);
|
||||
}
|
||||
using unsigned_type = typename make_unsigned_or_bool<target_type>::type;
|
||||
if (is_signed)
|
||||
arg_ = static_cast<int>(static_cast<target_type>(value));
|
||||
else
|
||||
arg_ = static_cast<unsigned>(static_cast<unsigned_type>(value));
|
||||
} else {
|
||||
if (is_signed) {
|
||||
// glibc's printf doesn't sign extend arguments of smaller types:
|
||||
// std::printf("%lld", -42); // prints "4294967254"
|
||||
// but we don't have to do the same because it's a UB.
|
||||
auto n = static_cast<long long>(value);
|
||||
arg_ = detail::make_arg<Context>(n);
|
||||
} else {
|
||||
auto n = static_cast<typename make_unsigned_or_bool<U>::type>(value);
|
||||
arg_ = detail::make_arg<Context>(n);
|
||||
}
|
||||
// glibc's printf doesn't sign extend arguments of smaller types:
|
||||
// std::printf("%lld", -42); // prints "4294967254"
|
||||
// but we don't have to do the same because it's a UB.
|
||||
if (is_signed)
|
||||
arg_ = static_cast<long long>(value);
|
||||
else
|
||||
arg_ = static_cast<typename make_unsigned_or_bool<U>::type>(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,7 +171,7 @@ template <typename T, typename Context> class arg_converter {
|
||||
// unsigned).
|
||||
template <typename T, typename Context, typename Char>
|
||||
void convert_arg(basic_format_arg<Context>& arg, Char type) {
|
||||
visit_format_arg(arg_converter<T, Context>(arg, type), arg);
|
||||
arg.visit(arg_converter<T, Context>(arg, type));
|
||||
}
|
||||
|
||||
// Converts an integer argument to char for printf.
|
||||
@@ -178,8 +184,7 @@ template <typename Context> class char_converter {
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
|
||||
void operator()(T value) {
|
||||
auto c = static_cast<typename Context::char_type>(value);
|
||||
arg_ = detail::make_arg<Context>(c);
|
||||
arg_ = static_cast<typename Context::char_type>(value);
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
|
||||
@@ -195,28 +200,28 @@ template <typename Char> struct get_cstring {
|
||||
|
||||
// Checks if an argument is a valid printf width specifier and sets
|
||||
// left alignment if it is negative.
|
||||
template <typename Char> class printf_width_handler {
|
||||
class printf_width_handler {
|
||||
private:
|
||||
format_specs<Char>& specs_;
|
||||
format_specs& specs_;
|
||||
|
||||
public:
|
||||
explicit printf_width_handler(format_specs<Char>& specs) : specs_(specs) {}
|
||||
inline explicit printf_width_handler(format_specs& specs) : specs_(specs) {}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
|
||||
auto operator()(T value) -> unsigned {
|
||||
auto width = static_cast<uint32_or_64_or_128_t<T>>(value);
|
||||
if (detail::is_negative(value)) {
|
||||
specs_.align = align::left;
|
||||
specs_.set_align(align::left);
|
||||
width = 0 - width;
|
||||
}
|
||||
unsigned int_max = max_value<int>();
|
||||
if (width > int_max) throw_format_error("number is too big");
|
||||
unsigned int_max = to_unsigned(max_value<int>());
|
||||
if (width > int_max) report_error("number is too big");
|
||||
return static_cast<unsigned>(width);
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
|
||||
auto operator()(T) -> unsigned {
|
||||
throw_format_error("width is not integer");
|
||||
report_error("width is not integer");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
@@ -224,12 +229,12 @@ template <typename Char> class printf_width_handler {
|
||||
// Workaround for a bug with the XL compiler when initializing
|
||||
// printf_arg_formatter's base class.
|
||||
template <typename Char>
|
||||
auto make_arg_formatter(buffer_appender<Char> iter, format_specs<Char>& s)
|
||||
auto make_arg_formatter(basic_appender<Char> iter, format_specs& s)
|
||||
-> arg_formatter<Char> {
|
||||
return {iter, s, locale_ref()};
|
||||
}
|
||||
|
||||
// The ``printf`` argument formatter.
|
||||
// The `printf` argument formatter.
|
||||
template <typename Char>
|
||||
class printf_arg_formatter : public arg_formatter<Char> {
|
||||
private:
|
||||
@@ -240,105 +245,96 @@ class printf_arg_formatter : public arg_formatter<Char> {
|
||||
|
||||
void write_null_pointer(bool is_string = false) {
|
||||
auto s = this->specs;
|
||||
s.type = presentation_type::none;
|
||||
write_bytes(this->out, is_string ? "(null)" : "(nil)", s);
|
||||
s.set_type(presentation_type::none);
|
||||
write_bytes<Char>(this->out, is_string ? "(null)" : "(nil)", s);
|
||||
}
|
||||
|
||||
template <typename T> void write(T value) {
|
||||
detail::write<Char>(this->out, value, this->specs, this->locale);
|
||||
}
|
||||
|
||||
public:
|
||||
printf_arg_formatter(buffer_appender<Char> iter, format_specs<Char>& s,
|
||||
printf_arg_formatter(basic_appender<Char> iter, format_specs& s,
|
||||
context_type& ctx)
|
||||
: base(make_arg_formatter(iter, s)), context_(ctx) {}
|
||||
|
||||
void operator()(monostate value) { base::operator()(value); }
|
||||
void operator()(monostate value) { write(value); }
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(detail::is_integral<T>::value)>
|
||||
void operator()(T value) {
|
||||
// MSVC2013 fails to compile separate overloads for bool and Char so use
|
||||
// std::is_same instead.
|
||||
if (!std::is_same<T, Char>::value) {
|
||||
base::operator()(value);
|
||||
write(value);
|
||||
return;
|
||||
}
|
||||
format_specs<Char> fmt_specs = this->specs;
|
||||
if (fmt_specs.type != presentation_type::none &&
|
||||
fmt_specs.type != presentation_type::chr) {
|
||||
format_specs s = this->specs;
|
||||
if (s.type() != presentation_type::none &&
|
||||
s.type() != presentation_type::chr) {
|
||||
return (*this)(static_cast<int>(value));
|
||||
}
|
||||
fmt_specs.sign = sign::none;
|
||||
fmt_specs.alt = false;
|
||||
fmt_specs.fill[0] = ' '; // Ignore '0' flag for char types.
|
||||
s.set_sign(sign::none);
|
||||
s.clear_alt();
|
||||
s.set_fill(' '); // Ignore '0' flag for char types.
|
||||
// align::numeric needs to be overwritten here since the '0' flag is
|
||||
// ignored for non-numeric types
|
||||
if (fmt_specs.align == align::none || fmt_specs.align == align::numeric)
|
||||
fmt_specs.align = align::right;
|
||||
write<Char>(this->out, static_cast<Char>(value), fmt_specs);
|
||||
if (s.align() == align::none || s.align() == align::numeric)
|
||||
s.set_align(align::right);
|
||||
detail::write<Char>(this->out, static_cast<Char>(value), s);
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
|
||||
void operator()(T value) {
|
||||
base::operator()(value);
|
||||
write(value);
|
||||
}
|
||||
|
||||
/** Formats a null-terminated C string. */
|
||||
void operator()(const char* value) {
|
||||
if (value)
|
||||
base::operator()(value);
|
||||
write(value);
|
||||
else
|
||||
write_null_pointer(this->specs.type != presentation_type::pointer);
|
||||
write_null_pointer(this->specs.type() != presentation_type::pointer);
|
||||
}
|
||||
|
||||
/** Formats a null-terminated wide C string. */
|
||||
void operator()(const wchar_t* value) {
|
||||
if (value)
|
||||
base::operator()(value);
|
||||
write(value);
|
||||
else
|
||||
write_null_pointer(this->specs.type != presentation_type::pointer);
|
||||
write_null_pointer(this->specs.type() != presentation_type::pointer);
|
||||
}
|
||||
|
||||
void operator()(basic_string_view<Char> value) { base::operator()(value); }
|
||||
void operator()(basic_string_view<Char> value) { write(value); }
|
||||
|
||||
/** Formats a pointer. */
|
||||
void operator()(const void* value) {
|
||||
if (value)
|
||||
base::operator()(value);
|
||||
write(value);
|
||||
else
|
||||
write_null_pointer();
|
||||
}
|
||||
|
||||
/** Formats an argument of a custom (user-defined) type. */
|
||||
void operator()(typename basic_format_arg<context_type>::handle handle) {
|
||||
auto parse_ctx = basic_format_parse_context<Char>({});
|
||||
auto parse_ctx = parse_context<Char>({});
|
||||
handle.format(parse_ctx, context_);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
void parse_flags(format_specs<Char>& specs, const Char*& it, const Char* end) {
|
||||
void parse_flags(format_specs& specs, const Char*& it, const Char* end) {
|
||||
for (; it != end; ++it) {
|
||||
switch (*it) {
|
||||
case '-':
|
||||
specs.align = align::left;
|
||||
break;
|
||||
case '+':
|
||||
specs.sign = sign::plus;
|
||||
break;
|
||||
case '0':
|
||||
specs.fill[0] = '0';
|
||||
break;
|
||||
case '-': specs.set_align(align::left); break;
|
||||
case '+': specs.set_sign(sign::plus); break;
|
||||
case '0': specs.set_fill('0'); break;
|
||||
case ' ':
|
||||
if (specs.sign != sign::plus) specs.sign = sign::space;
|
||||
if (specs.sign() != sign::plus) specs.set_sign(sign::space);
|
||||
break;
|
||||
case '#':
|
||||
specs.alt = true;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
case '#': specs.set_alt(); break;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Char, typename GetArg>
|
||||
auto parse_header(const Char*& it, const Char* end, format_specs<Char>& specs,
|
||||
auto parse_header(const Char*& it, const Char* end, format_specs& specs,
|
||||
GetArg get_arg) -> int {
|
||||
int arg_index = -1;
|
||||
Char c = *it;
|
||||
@@ -350,11 +346,11 @@ auto parse_header(const Char*& it, const Char* end, format_specs<Char>& specs,
|
||||
++it;
|
||||
arg_index = value != -1 ? value : max_value<int>();
|
||||
} else {
|
||||
if (c == '0') specs.fill[0] = '0';
|
||||
if (c == '0') specs.set_fill('0');
|
||||
if (value != 0) {
|
||||
// Nonzero value means that we parsed width and don't need to
|
||||
// parse it or flags again, so return now.
|
||||
if (value == -1) throw_format_error("number is too big");
|
||||
if (value == -1) report_error("number is too big");
|
||||
specs.width = value;
|
||||
return arg_index;
|
||||
}
|
||||
@@ -365,63 +361,47 @@ auto parse_header(const Char*& it, const Char* end, format_specs<Char>& specs,
|
||||
if (it != end) {
|
||||
if (*it >= '0' && *it <= '9') {
|
||||
specs.width = parse_nonnegative_int(it, end, -1);
|
||||
if (specs.width == -1) throw_format_error("number is too big");
|
||||
if (specs.width == -1) report_error("number is too big");
|
||||
} else if (*it == '*') {
|
||||
++it;
|
||||
specs.width = static_cast<int>(visit_format_arg(
|
||||
detail::printf_width_handler<Char>(specs), get_arg(-1)));
|
||||
specs.width = static_cast<int>(
|
||||
get_arg(-1).visit(detail::printf_width_handler(specs)));
|
||||
}
|
||||
}
|
||||
return arg_index;
|
||||
}
|
||||
|
||||
inline auto parse_printf_presentation_type(char c, type t)
|
||||
inline auto parse_printf_presentation_type(char c, type t, bool& upper)
|
||||
-> presentation_type {
|
||||
using pt = presentation_type;
|
||||
constexpr auto integral_set = sint_set | uint_set | bool_set | char_set;
|
||||
switch (c) {
|
||||
case 'd':
|
||||
return in(t, integral_set) ? pt::dec : pt::none;
|
||||
case 'o':
|
||||
return in(t, integral_set) ? pt::oct : pt::none;
|
||||
case 'x':
|
||||
return in(t, integral_set) ? pt::hex_lower : pt::none;
|
||||
case 'X':
|
||||
return in(t, integral_set) ? pt::hex_upper : pt::none;
|
||||
case 'a':
|
||||
return in(t, float_set) ? pt::hexfloat_lower : pt::none;
|
||||
case 'A':
|
||||
return in(t, float_set) ? pt::hexfloat_upper : pt::none;
|
||||
case 'e':
|
||||
return in(t, float_set) ? pt::exp_lower : pt::none;
|
||||
case 'E':
|
||||
return in(t, float_set) ? pt::exp_upper : pt::none;
|
||||
case 'f':
|
||||
return in(t, float_set) ? pt::fixed_lower : pt::none;
|
||||
case 'F':
|
||||
return in(t, float_set) ? pt::fixed_upper : pt::none;
|
||||
case 'g':
|
||||
return in(t, float_set) ? pt::general_lower : pt::none;
|
||||
case 'G':
|
||||
return in(t, float_set) ? pt::general_upper : pt::none;
|
||||
case 'c':
|
||||
return in(t, integral_set) ? pt::chr : pt::none;
|
||||
case 's':
|
||||
return in(t, string_set | cstring_set) ? pt::string : pt::none;
|
||||
case 'p':
|
||||
return in(t, pointer_set | cstring_set) ? pt::pointer : pt::none;
|
||||
default:
|
||||
return pt::none;
|
||||
case 'd': return in(t, integral_set) ? pt::dec : pt::none;
|
||||
case 'o': return in(t, integral_set) ? pt::oct : pt::none;
|
||||
case 'X': upper = true; FMT_FALLTHROUGH;
|
||||
case 'x': return in(t, integral_set) ? pt::hex : pt::none;
|
||||
case 'E': upper = true; FMT_FALLTHROUGH;
|
||||
case 'e': return in(t, float_set) ? pt::exp : pt::none;
|
||||
case 'F': upper = true; FMT_FALLTHROUGH;
|
||||
case 'f': return in(t, float_set) ? pt::fixed : pt::none;
|
||||
case 'G': upper = true; FMT_FALLTHROUGH;
|
||||
case 'g': return in(t, float_set) ? pt::general : pt::none;
|
||||
case 'A': upper = true; FMT_FALLTHROUGH;
|
||||
case 'a': return in(t, float_set) ? pt::hexfloat : pt::none;
|
||||
case 'c': return in(t, integral_set) ? pt::chr : pt::none;
|
||||
case 's': return in(t, string_set | cstring_set) ? pt::string : pt::none;
|
||||
case 'p': return in(t, pointer_set | cstring_set) ? pt::pointer : pt::none;
|
||||
default: return pt::none;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Char, typename Context>
|
||||
void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
|
||||
basic_format_args<Context> args) {
|
||||
using iterator = buffer_appender<Char>;
|
||||
using iterator = basic_appender<Char>;
|
||||
auto out = iterator(buf);
|
||||
auto context = basic_printf_context<Char>(out, args);
|
||||
auto parse_ctx = basic_format_parse_context<Char>(format);
|
||||
auto parse_ctx = parse_context<Char>(format);
|
||||
|
||||
// Returns the argument with specified index or, if arg_index is -1, the next
|
||||
// argument.
|
||||
@@ -449,12 +429,12 @@ void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
|
||||
}
|
||||
write(out, basic_string_view<Char>(start, to_unsigned(it - 1 - start)));
|
||||
|
||||
auto specs = format_specs<Char>();
|
||||
specs.align = align::right;
|
||||
auto specs = format_specs();
|
||||
specs.set_align(align::right);
|
||||
|
||||
// Parse argument index, flags and width.
|
||||
int arg_index = parse_header(it, end, specs, get_arg);
|
||||
if (arg_index == 0) throw_format_error("argument not found");
|
||||
if (arg_index == 0) report_error("argument not found");
|
||||
|
||||
// Parse precision.
|
||||
if (it != end && *it == '.') {
|
||||
@@ -464,8 +444,8 @@ void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
|
||||
specs.precision = parse_nonnegative_int(it, end, 0);
|
||||
} else if (c == '*') {
|
||||
++it;
|
||||
specs.precision = static_cast<int>(
|
||||
visit_format_arg(printf_precision_handler(), get_arg(-1)));
|
||||
specs.precision =
|
||||
static_cast<int>(get_arg(-1).visit(printf_precision_handler()));
|
||||
} else {
|
||||
specs.precision = 0;
|
||||
}
|
||||
@@ -474,25 +454,26 @@ void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
|
||||
auto arg = get_arg(arg_index);
|
||||
// For d, i, o, u, x, and X conversion specifiers, if a precision is
|
||||
// specified, the '0' flag is ignored
|
||||
if (specs.precision >= 0 && arg.is_integral()) {
|
||||
if (specs.precision >= 0 && is_integral_type(arg.type())) {
|
||||
// Ignore '0' for non-numeric types or if '-' present.
|
||||
specs.fill[0] = ' ';
|
||||
specs.set_fill(' ');
|
||||
}
|
||||
if (specs.precision >= 0 && arg.type() == type::cstring_type) {
|
||||
auto str = visit_format_arg(get_cstring<Char>(), arg);
|
||||
auto str = arg.visit(get_cstring<Char>());
|
||||
auto str_end = str + specs.precision;
|
||||
auto nul = std::find(str, str_end, Char());
|
||||
auto sv = basic_string_view<Char>(
|
||||
str, to_unsigned(nul != str_end ? nul - str : specs.precision));
|
||||
arg = make_arg<basic_printf_context<Char>>(sv);
|
||||
arg = sv;
|
||||
}
|
||||
if (specs.alt && visit_format_arg(is_zero_int(), arg)) specs.alt = false;
|
||||
if (specs.fill[0] == '0') {
|
||||
if (arg.is_arithmetic() && specs.align != align::left)
|
||||
specs.align = align::numeric;
|
||||
else
|
||||
specs.fill[0] = ' '; // Ignore '0' flag for non-numeric types or if '-'
|
||||
// flag is also present.
|
||||
if (specs.alt() && arg.visit(is_zero_int())) specs.clear_alt();
|
||||
if (specs.fill_unit<Char>() == '0') {
|
||||
if (is_arithmetic_type(arg.type()) && specs.align() != align::left) {
|
||||
specs.set_align(align::numeric);
|
||||
} else {
|
||||
// Ignore '0' flag for non-numeric types or if '-' flag is also present.
|
||||
specs.set_fill(' ');
|
||||
}
|
||||
}
|
||||
|
||||
// Parse length and convert the argument to the required type.
|
||||
@@ -517,47 +498,39 @@ void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
|
||||
convert_arg<long>(arg, t);
|
||||
}
|
||||
break;
|
||||
case 'j':
|
||||
convert_arg<intmax_t>(arg, t);
|
||||
break;
|
||||
case 'z':
|
||||
convert_arg<size_t>(arg, t);
|
||||
break;
|
||||
case 't':
|
||||
convert_arg<std::ptrdiff_t>(arg, t);
|
||||
break;
|
||||
case 'j': convert_arg<intmax_t>(arg, t); break;
|
||||
case 'z': convert_arg<size_t>(arg, t); break;
|
||||
case 't': convert_arg<std::ptrdiff_t>(arg, t); break;
|
||||
case 'L':
|
||||
// printf produces garbage when 'L' is omitted for long double, no
|
||||
// need to do the same.
|
||||
break;
|
||||
default:
|
||||
--it;
|
||||
convert_arg<void>(arg, c);
|
||||
default: --it; convert_arg<void>(arg, c);
|
||||
}
|
||||
|
||||
// Parse type.
|
||||
if (it == end) throw_format_error("invalid format string");
|
||||
if (it == end) report_error("invalid format string");
|
||||
char type = static_cast<char>(*it++);
|
||||
if (arg.is_integral()) {
|
||||
if (is_integral_type(arg.type())) {
|
||||
// Normalize type.
|
||||
switch (type) {
|
||||
case 'i':
|
||||
case 'u':
|
||||
type = 'd';
|
||||
break;
|
||||
case 'u': type = 'd'; break;
|
||||
case 'c':
|
||||
visit_format_arg(char_converter<basic_printf_context<Char>>(arg), arg);
|
||||
arg.visit(char_converter<basic_printf_context<Char>>(arg));
|
||||
break;
|
||||
}
|
||||
}
|
||||
specs.type = parse_printf_presentation_type(type, arg.type());
|
||||
if (specs.type == presentation_type::none)
|
||||
throw_format_error("invalid format specifier");
|
||||
bool upper = false;
|
||||
specs.set_type(parse_printf_presentation_type(type, arg.type(), upper));
|
||||
if (specs.type() == presentation_type::none)
|
||||
report_error("invalid format specifier");
|
||||
if (upper) specs.set_upper();
|
||||
|
||||
start = it;
|
||||
|
||||
// Format argument.
|
||||
visit_format_arg(printf_arg_formatter<Char>(out, specs, context), arg);
|
||||
arg.visit(printf_arg_formatter<Char>(out, specs, context));
|
||||
}
|
||||
write(out, basic_string_view<Char>(start, to_unsigned(it - start)));
|
||||
}
|
||||
@@ -569,56 +542,44 @@ using wprintf_context = basic_printf_context<wchar_t>;
|
||||
using printf_args = basic_format_args<printf_context>;
|
||||
using wprintf_args = basic_format_args<wprintf_context>;
|
||||
|
||||
/**
|
||||
\rst
|
||||
Constructs an `~fmt::format_arg_store` object that contains references to
|
||||
arguments and can be implicitly converted to `~fmt::printf_args`.
|
||||
\endrst
|
||||
*/
|
||||
template <typename... T>
|
||||
inline auto make_printf_args(const T&... args)
|
||||
-> format_arg_store<printf_context, T...> {
|
||||
return {args...};
|
||||
/// Constructs an `format_arg_store` object that contains references to
|
||||
/// arguments and can be implicitly converted to `printf_args`.
|
||||
template <typename Char = char, typename... T>
|
||||
inline auto make_printf_args(T&... args)
|
||||
-> decltype(fmt::make_format_args<basic_printf_context<Char>>(args...)) {
|
||||
return fmt::make_format_args<basic_printf_context<Char>>(args...);
|
||||
}
|
||||
|
||||
// DEPRECATED!
|
||||
template <typename... T>
|
||||
inline auto make_wprintf_args(const T&... args)
|
||||
-> format_arg_store<wprintf_context, T...> {
|
||||
return {args...};
|
||||
}
|
||||
template <typename Char> struct vprintf_args {
|
||||
using type = basic_format_args<basic_printf_context<Char>>;
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
inline auto vsprintf(
|
||||
basic_string_view<Char> fmt,
|
||||
basic_format_args<basic_printf_context<type_identity_t<Char>>> args)
|
||||
inline auto vsprintf(basic_string_view<Char> fmt,
|
||||
typename vprintf_args<Char>::type args)
|
||||
-> std::basic_string<Char> {
|
||||
auto buf = basic_memory_buffer<Char>();
|
||||
detail::vprintf(buf, fmt, args);
|
||||
return to_string(buf);
|
||||
return {buf.data(), buf.size()};
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Formats arguments and returns the result as a string.
|
||||
|
||||
**Example**::
|
||||
|
||||
std::string message = fmt::sprintf("The answer is %d", 42);
|
||||
\endrst
|
||||
*/
|
||||
template <typename S, typename... T,
|
||||
typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>>
|
||||
* Formats `args` according to specifications in `fmt` and returns the result
|
||||
* as as string.
|
||||
*
|
||||
* **Example**:
|
||||
*
|
||||
* std::string message = fmt::sprintf("The answer is %d", 42);
|
||||
*/
|
||||
template <typename S, typename... T, typename Char = detail::char_t<S>>
|
||||
inline auto sprintf(const S& fmt, const T&... args) -> std::basic_string<Char> {
|
||||
return vsprintf(detail::to_string_view(fmt),
|
||||
fmt::make_format_args<basic_printf_context<Char>>(args...));
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline auto vfprintf(
|
||||
std::FILE* f, basic_string_view<Char> fmt,
|
||||
basic_format_args<basic_printf_context<type_identity_t<Char>>> args)
|
||||
-> int {
|
||||
inline auto vfprintf(std::FILE* f, basic_string_view<Char> fmt,
|
||||
typename vprintf_args<Char>::type args) -> int {
|
||||
auto buf = basic_memory_buffer<Char>();
|
||||
detail::vprintf(buf, fmt, args);
|
||||
size_t size = buf.size();
|
||||
@@ -628,36 +589,33 @@ inline auto vfprintf(
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Prints formatted data to the file *f*.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::fprintf(stderr, "Don't %s!", "panic");
|
||||
\endrst
|
||||
* Formats `args` according to specifications in `fmt` and writes the output
|
||||
* to `f`.
|
||||
*
|
||||
* **Example**:
|
||||
*
|
||||
* fmt::fprintf(stderr, "Don't %s!", "panic");
|
||||
*/
|
||||
template <typename S, typename... T, typename Char = char_t<S>>
|
||||
template <typename S, typename... T, typename Char = detail::char_t<S>>
|
||||
inline auto fprintf(std::FILE* f, const S& fmt, const T&... args) -> int {
|
||||
return vfprintf(f, detail::to_string_view(fmt),
|
||||
fmt::make_format_args<basic_printf_context<Char>>(args...));
|
||||
make_printf_args<Char>(args...));
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
FMT_DEPRECATED inline auto vprintf(
|
||||
basic_string_view<Char> fmt,
|
||||
basic_format_args<basic_printf_context<type_identity_t<Char>>> args)
|
||||
FMT_DEPRECATED inline auto vprintf(basic_string_view<Char> fmt,
|
||||
typename vprintf_args<Char>::type args)
|
||||
-> int {
|
||||
return vfprintf(stdout, fmt, args);
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Prints formatted data to ``stdout``.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::printf("Elapsed time: %.2f seconds", 1.23);
|
||||
\endrst
|
||||
* Formats `args` according to specifications in `fmt` and writes the output
|
||||
* to `stdout`.
|
||||
*
|
||||
* **Example**:
|
||||
*
|
||||
* fmt::printf("Elapsed time: %.2f seconds", 1.23);
|
||||
*/
|
||||
template <typename... T>
|
||||
inline auto printf(string_view fmt, const T&... args) -> int {
|
||||
@@ -666,7 +624,7 @@ inline auto printf(string_view fmt, const T&... args) -> int {
|
||||
template <typename... T>
|
||||
FMT_DEPRECATED inline auto printf(basic_string_view<wchar_t> fmt,
|
||||
const T&... args) -> int {
|
||||
return vfprintf(stdout, fmt, make_wprintf_args(args...));
|
||||
return vfprintf(stdout, fmt, make_printf_args<wchar_t>(args...));
|
||||
}
|
||||
|
||||
FMT_END_EXPORT
|
||||
|
||||
620
3rdparty/fmt/include/fmt/ranges.h
vendored
620
3rdparty/fmt/include/fmt/ranges.h
vendored
@@ -8,67 +8,31 @@
|
||||
#ifndef FMT_RANGES_H_
|
||||
#define FMT_RANGES_H_
|
||||
|
||||
#include <initializer_list>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#ifndef FMT_MODULE
|
||||
# include <initializer_list>
|
||||
# include <iterator>
|
||||
# include <string>
|
||||
# include <tuple>
|
||||
# include <type_traits>
|
||||
# include <utility>
|
||||
#endif
|
||||
|
||||
#include "format.h"
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
FMT_EXPORT
|
||||
enum class range_format { disabled, map, set, sequence, string, debug_string };
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename Range, typename OutputIt>
|
||||
auto copy(const Range& range, OutputIt out) -> OutputIt {
|
||||
for (auto it = range.begin(), end = range.end(); it != end; ++it)
|
||||
*out++ = *it;
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename OutputIt>
|
||||
auto copy(const char* str, OutputIt out) -> OutputIt {
|
||||
while (*str) *out++ = *str++;
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename OutputIt> auto copy(char ch, OutputIt out) -> OutputIt {
|
||||
*out++ = ch;
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename OutputIt> auto copy(wchar_t ch, OutputIt out) -> OutputIt {
|
||||
*out++ = ch;
|
||||
return out;
|
||||
}
|
||||
|
||||
// Returns true if T has a std::string-like interface, like std::string_view.
|
||||
template <typename T> class is_std_string_like {
|
||||
template <typename U>
|
||||
static auto check(U* p)
|
||||
-> decltype((void)p->find('a'), p->length(), (void)p->data(), int());
|
||||
template <typename> static void check(...);
|
||||
|
||||
public:
|
||||
static constexpr const bool value =
|
||||
is_string<T>::value ||
|
||||
std::is_convertible<T, std_string_view<char>>::value ||
|
||||
!std::is_void<decltype(check<T>(nullptr))>::value;
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
struct is_std_string_like<fmt::basic_string_view<Char>> : std::true_type {};
|
||||
|
||||
template <typename T> class is_map {
|
||||
template <typename U> static auto check(U*) -> typename U::mapped_type;
|
||||
template <typename> static void check(...);
|
||||
|
||||
public:
|
||||
#ifdef FMT_FORMAT_MAP_AS_LIST // DEPRECATED!
|
||||
static constexpr const bool value = false;
|
||||
#else
|
||||
static constexpr const bool value =
|
||||
!std::is_void<decltype(check<T>(nullptr))>::value;
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename T> class is_set {
|
||||
@@ -76,26 +40,10 @@ template <typename T> class is_set {
|
||||
template <typename> static void check(...);
|
||||
|
||||
public:
|
||||
#ifdef FMT_FORMAT_SET_AS_LIST // DEPRECATED!
|
||||
static constexpr const bool value = false;
|
||||
#else
|
||||
static constexpr const bool value =
|
||||
!std::is_void<decltype(check<T>(nullptr))>::value && !is_map<T>::value;
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename... Ts> struct conditional_helper {};
|
||||
|
||||
template <typename T, typename _ = void> struct is_range_ : std::false_type {};
|
||||
|
||||
#if !FMT_MSC_VERSION || FMT_MSC_VERSION > 1800
|
||||
|
||||
# define FMT_DECLTYPE_RETURN(val) \
|
||||
->decltype(val) { return val; } \
|
||||
static_assert( \
|
||||
true, "") // This makes it so that a semicolon is required after the
|
||||
// macro, which helps clang-format handle the formatting.
|
||||
|
||||
// C array overload
|
||||
template <typename T, std::size_t N>
|
||||
auto range_begin(const T (&arr)[N]) -> const T* {
|
||||
@@ -110,17 +58,21 @@ template <typename T, typename Enable = void>
|
||||
struct has_member_fn_begin_end_t : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct has_member_fn_begin_end_t<T, void_t<decltype(std::declval<T>().begin()),
|
||||
struct has_member_fn_begin_end_t<T, void_t<decltype(*std::declval<T>().begin()),
|
||||
decltype(std::declval<T>().end())>>
|
||||
: std::true_type {};
|
||||
|
||||
// Member function overload
|
||||
// Member function overloads.
|
||||
template <typename T>
|
||||
auto range_begin(T&& rng) FMT_DECLTYPE_RETURN(static_cast<T&&>(rng).begin());
|
||||
auto range_begin(T&& rng) -> decltype(static_cast<T&&>(rng).begin()) {
|
||||
return static_cast<T&&>(rng).begin();
|
||||
}
|
||||
template <typename T>
|
||||
auto range_end(T&& rng) FMT_DECLTYPE_RETURN(static_cast<T&&>(rng).end());
|
||||
auto range_end(T&& rng) -> decltype(static_cast<T&&>(rng).end()) {
|
||||
return static_cast<T&&>(rng).end();
|
||||
}
|
||||
|
||||
// ADL overload. Only participates in overload resolution if member functions
|
||||
// ADL overloads. Only participate in overload resolution if member functions
|
||||
// are not found.
|
||||
template <typename T>
|
||||
auto range_begin(T&& rng)
|
||||
@@ -141,31 +93,30 @@ struct has_mutable_begin_end : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct has_const_begin_end<
|
||||
T,
|
||||
void_t<
|
||||
decltype(detail::range_begin(std::declval<const remove_cvref_t<T>&>())),
|
||||
decltype(detail::range_end(std::declval<const remove_cvref_t<T>&>()))>>
|
||||
T, void_t<decltype(*detail::range_begin(
|
||||
std::declval<const remove_cvref_t<T>&>())),
|
||||
decltype(detail::range_end(
|
||||
std::declval<const remove_cvref_t<T>&>()))>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct has_mutable_begin_end<
|
||||
T, void_t<decltype(detail::range_begin(std::declval<T>())),
|
||||
decltype(detail::range_end(std::declval<T>())),
|
||||
T, void_t<decltype(*detail::range_begin(std::declval<T&>())),
|
||||
decltype(detail::range_end(std::declval<T&>())),
|
||||
// the extra int here is because older versions of MSVC don't
|
||||
// SFINAE properly unless there are distinct types
|
||||
int>> : std::true_type {};
|
||||
|
||||
template <typename T, typename _ = void> struct is_range_ : std::false_type {};
|
||||
template <typename T>
|
||||
struct is_range_<T, void>
|
||||
: std::integral_constant<bool, (has_const_begin_end<T>::value ||
|
||||
has_mutable_begin_end<T>::value)> {};
|
||||
# undef FMT_DECLTYPE_RETURN
|
||||
#endif
|
||||
|
||||
// tuple_size and tuple_element check.
|
||||
template <typename T> class is_tuple_like_ {
|
||||
template <typename U>
|
||||
static auto check(U* p) -> decltype(std::tuple_size<U>::value, int());
|
||||
template <typename U, typename V = typename std::remove_cv<U>::type>
|
||||
static auto check(U* p) -> decltype(std::tuple_size<V>::value, 0);
|
||||
template <typename> static void check(...);
|
||||
|
||||
public:
|
||||
@@ -206,12 +157,13 @@ class is_tuple_formattable_ {
|
||||
static constexpr const bool value = false;
|
||||
};
|
||||
template <typename T, typename C> class is_tuple_formattable_<T, C, true> {
|
||||
template <std::size_t... Is>
|
||||
static auto check2(index_sequence<Is...>,
|
||||
integer_sequence<bool, (Is == Is)...>) -> std::true_type;
|
||||
static auto check2(...) -> std::false_type;
|
||||
template <std::size_t... Is>
|
||||
static auto check(index_sequence<Is...>) -> decltype(check2(
|
||||
template <size_t... Is>
|
||||
static auto all_true(index_sequence<Is...>,
|
||||
integer_sequence<bool, (Is >= 0)...>) -> std::true_type;
|
||||
static auto all_true(...) -> std::false_type;
|
||||
|
||||
template <size_t... Is>
|
||||
static auto check(index_sequence<Is...>) -> decltype(all_true(
|
||||
index_sequence<Is...>{},
|
||||
integer_sequence<bool,
|
||||
(is_formattable<typename std::tuple_element<Is, T>::type,
|
||||
@@ -292,21 +244,32 @@ FMT_CONSTEXPR auto maybe_set_debug_format(Formatter& f, bool set)
|
||||
template <typename Formatter>
|
||||
FMT_CONSTEXPR void maybe_set_debug_format(Formatter&, ...) {}
|
||||
|
||||
template <typename T>
|
||||
struct range_format_kind_
|
||||
: std::integral_constant<range_format,
|
||||
std::is_same<uncvref_type<T>, T>::value
|
||||
? range_format::disabled
|
||||
: is_map<T>::value ? range_format::map
|
||||
: is_set<T>::value ? range_format::set
|
||||
: range_format::sequence> {};
|
||||
|
||||
template <range_format K>
|
||||
using range_format_constant = std::integral_constant<range_format, K>;
|
||||
|
||||
// These are not generic lambdas for compatibility with C++11.
|
||||
template <typename ParseContext> struct parse_empty_specs {
|
||||
template <typename Char> struct parse_empty_specs {
|
||||
template <typename Formatter> FMT_CONSTEXPR void operator()(Formatter& f) {
|
||||
f.parse(ctx);
|
||||
detail::maybe_set_debug_format(f, true);
|
||||
}
|
||||
ParseContext& ctx;
|
||||
parse_context<Char>& ctx;
|
||||
};
|
||||
template <typename FormatContext> struct format_tuple_element {
|
||||
using char_type = typename FormatContext::char_type;
|
||||
|
||||
template <typename T>
|
||||
void operator()(const formatter<T, char_type>& f, const T& v) {
|
||||
if (i > 0)
|
||||
ctx.advance_to(detail::copy_str<char_type>(separator, ctx.out()));
|
||||
if (i > 0) ctx.advance_to(detail::copy<char_type>(separator, ctx.out()));
|
||||
ctx.advance_to(f.format(v, ctx));
|
||||
++i;
|
||||
}
|
||||
@@ -355,66 +318,48 @@ struct formatter<Tuple, Char,
|
||||
closing_bracket_ = close;
|
||||
}
|
||||
|
||||
template <typename ParseContext>
|
||||
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
auto it = ctx.begin();
|
||||
if (it != ctx.end() && *it != '}')
|
||||
FMT_THROW(format_error("invalid format specifier"));
|
||||
detail::for_each(formatters_, detail::parse_empty_specs<ParseContext>{ctx});
|
||||
auto end = ctx.end();
|
||||
if (it != end && detail::to_ascii(*it) == 'n') {
|
||||
++it;
|
||||
set_brackets({}, {});
|
||||
set_separator({});
|
||||
}
|
||||
if (it != end && *it != '}') report_error("invalid format specifier");
|
||||
ctx.advance_to(it);
|
||||
detail::for_each(formatters_, detail::parse_empty_specs<Char>{ctx});
|
||||
return it;
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
auto format(const Tuple& value, FormatContext& ctx) const
|
||||
-> decltype(ctx.out()) {
|
||||
ctx.advance_to(detail::copy_str<Char>(opening_bracket_, ctx.out()));
|
||||
ctx.advance_to(detail::copy<Char>(opening_bracket_, ctx.out()));
|
||||
detail::for_each2(
|
||||
formatters_, value,
|
||||
detail::format_tuple_element<FormatContext>{0, ctx, separator_});
|
||||
return detail::copy_str<Char>(closing_bracket_, ctx.out());
|
||||
return detail::copy<Char>(closing_bracket_, ctx.out());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Char> struct is_range {
|
||||
static constexpr const bool value =
|
||||
detail::is_range_<T>::value && !detail::is_std_string_like<T>::value &&
|
||||
!std::is_convertible<T, std::basic_string<Char>>::value &&
|
||||
!std::is_convertible<T, detail::std_string_view<Char>>::value;
|
||||
detail::is_range_<T>::value && !detail::has_to_string_view<T>::value;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
template <typename Context> struct range_mapper {
|
||||
using mapper = arg_mapper<Context>;
|
||||
|
||||
template <typename T,
|
||||
FMT_ENABLE_IF(has_formatter<remove_cvref_t<T>, Context>::value)>
|
||||
static auto map(T&& value) -> T&& {
|
||||
return static_cast<T&&>(value);
|
||||
}
|
||||
template <typename T,
|
||||
FMT_ENABLE_IF(!has_formatter<remove_cvref_t<T>, Context>::value)>
|
||||
static auto map(T&& value)
|
||||
-> decltype(mapper().map(static_cast<T&&>(value))) {
|
||||
return mapper().map(static_cast<T&&>(value));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char, typename Element>
|
||||
using range_formatter_type =
|
||||
formatter<remove_cvref_t<decltype(range_mapper<buffer_context<Char>>{}.map(
|
||||
std::declval<Element>()))>,
|
||||
Char>;
|
||||
using range_formatter_type = formatter<remove_cvref_t<Element>, Char>;
|
||||
|
||||
template <typename R>
|
||||
using maybe_const_range =
|
||||
conditional_t<has_const_begin_end<R>::value, const R, R>;
|
||||
|
||||
// Workaround a bug in MSVC 2015 and earlier.
|
||||
#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1910
|
||||
template <typename R, typename Char>
|
||||
struct is_formattable_delayed
|
||||
: is_formattable<uncvref_type<maybe_const_range<R>>, Char> {};
|
||||
#endif
|
||||
} // namespace detail
|
||||
|
||||
template <typename...> struct conjunction : std::true_type {};
|
||||
@@ -438,6 +383,24 @@ struct range_formatter<
|
||||
detail::string_literal<Char, '['>{};
|
||||
basic_string_view<Char> closing_bracket_ =
|
||||
detail::string_literal<Char, ']'>{};
|
||||
bool is_debug = false;
|
||||
|
||||
template <typename Output, typename It, typename Sentinel, typename U = T,
|
||||
FMT_ENABLE_IF(std::is_same<U, Char>::value)>
|
||||
auto write_debug_string(Output& out, It it, Sentinel end) const -> Output {
|
||||
auto buf = basic_memory_buffer<Char>();
|
||||
for (; it != end; ++it) buf.push_back(*it);
|
||||
auto specs = format_specs();
|
||||
specs.set_type(presentation_type::debug);
|
||||
return detail::write<Char>(
|
||||
out, basic_string_view<Char>(buf.data(), buf.size()), specs);
|
||||
}
|
||||
|
||||
template <typename Output, typename It, typename Sentinel, typename U = T,
|
||||
FMT_ENABLE_IF(!std::is_same<U, Char>::value)>
|
||||
auto write_debug_string(Output& out, It, Sentinel) const -> Output {
|
||||
return out;
|
||||
}
|
||||
|
||||
public:
|
||||
FMT_CONSTEXPR range_formatter() {}
|
||||
@@ -456,21 +419,40 @@ struct range_formatter<
|
||||
closing_bracket_ = close;
|
||||
}
|
||||
|
||||
template <typename ParseContext>
|
||||
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
auto it = ctx.begin();
|
||||
auto end = ctx.end();
|
||||
detail::maybe_set_debug_format(underlying_, true);
|
||||
if (it == end) return underlying_.parse(ctx);
|
||||
|
||||
if (it != end && *it == 'n') {
|
||||
switch (detail::to_ascii(*it)) {
|
||||
case 'n':
|
||||
set_brackets({}, {});
|
||||
++it;
|
||||
break;
|
||||
case '?':
|
||||
is_debug = true;
|
||||
set_brackets({}, {});
|
||||
++it;
|
||||
if (it == end || *it != 's') report_error("invalid format specifier");
|
||||
FMT_FALLTHROUGH;
|
||||
case 's':
|
||||
if (!std::is_same<T, Char>::value)
|
||||
report_error("invalid format specifier");
|
||||
if (!is_debug) {
|
||||
set_brackets(detail::string_literal<Char, '"'>{},
|
||||
detail::string_literal<Char, '"'>{});
|
||||
set_separator({});
|
||||
detail::maybe_set_debug_format(underlying_, false);
|
||||
}
|
||||
++it;
|
||||
return it;
|
||||
}
|
||||
|
||||
if (it != end && *it != '}') {
|
||||
if (*it != ':') FMT_THROW(format_error("invalid format specifier"));
|
||||
if (*it != ':') report_error("invalid format specifier");
|
||||
detail::maybe_set_debug_format(underlying_, false);
|
||||
++it;
|
||||
} else {
|
||||
detail::maybe_set_debug_format(underlying_, true);
|
||||
}
|
||||
|
||||
ctx.advance_to(it);
|
||||
@@ -479,80 +461,26 @@ struct range_formatter<
|
||||
|
||||
template <typename R, typename FormatContext>
|
||||
auto format(R&& range, FormatContext& ctx) const -> decltype(ctx.out()) {
|
||||
detail::range_mapper<buffer_context<Char>> mapper;
|
||||
auto out = ctx.out();
|
||||
out = detail::copy_str<Char>(opening_bracket_, out);
|
||||
int i = 0;
|
||||
auto it = detail::range_begin(range);
|
||||
auto end = detail::range_end(range);
|
||||
if (is_debug) return write_debug_string(out, std::move(it), end);
|
||||
|
||||
out = detail::copy<Char>(opening_bracket_, out);
|
||||
int i = 0;
|
||||
for (; it != end; ++it) {
|
||||
if (i > 0) out = detail::copy_str<Char>(separator_, out);
|
||||
if (i > 0) out = detail::copy<Char>(separator_, out);
|
||||
ctx.advance_to(out);
|
||||
auto&& item = *it;
|
||||
out = underlying_.format(mapper.map(item), ctx);
|
||||
auto&& item = *it; // Need an lvalue
|
||||
out = underlying_.format(item, ctx);
|
||||
++i;
|
||||
}
|
||||
out = detail::copy_str<Char>(closing_bracket_, out);
|
||||
out = detail::copy<Char>(closing_bracket_, out);
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
enum class range_format { disabled, map, set, sequence, string, debug_string };
|
||||
|
||||
namespace detail {
|
||||
template <typename T>
|
||||
struct range_format_kind_
|
||||
: std::integral_constant<range_format,
|
||||
std::is_same<uncvref_type<T>, T>::value
|
||||
? range_format::disabled
|
||||
: is_map<T>::value ? range_format::map
|
||||
: is_set<T>::value ? range_format::set
|
||||
: range_format::sequence> {};
|
||||
|
||||
template <range_format K, typename R, typename Char, typename Enable = void>
|
||||
struct range_default_formatter;
|
||||
|
||||
template <range_format K>
|
||||
using range_format_constant = std::integral_constant<range_format, K>;
|
||||
|
||||
template <range_format K, typename R, typename Char>
|
||||
struct range_default_formatter<
|
||||
K, R, Char,
|
||||
enable_if_t<(K == range_format::sequence || K == range_format::map ||
|
||||
K == range_format::set)>> {
|
||||
using range_type = detail::maybe_const_range<R>;
|
||||
range_formatter<detail::uncvref_type<range_type>, Char> underlying_;
|
||||
|
||||
FMT_CONSTEXPR range_default_formatter() { init(range_format_constant<K>()); }
|
||||
|
||||
FMT_CONSTEXPR void init(range_format_constant<range_format::set>) {
|
||||
underlying_.set_brackets(detail::string_literal<Char, '{'>{},
|
||||
detail::string_literal<Char, '}'>{});
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void init(range_format_constant<range_format::map>) {
|
||||
underlying_.set_brackets(detail::string_literal<Char, '{'>{},
|
||||
detail::string_literal<Char, '}'>{});
|
||||
underlying_.underlying().set_brackets({}, {});
|
||||
underlying_.underlying().set_separator(
|
||||
detail::string_literal<Char, ':', ' '>{});
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void init(range_format_constant<range_format::sequence>) {}
|
||||
|
||||
template <typename ParseContext>
|
||||
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
return underlying_.parse(ctx);
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
auto format(range_type& range, FormatContext& ctx) const
|
||||
-> decltype(ctx.out()) {
|
||||
return underlying_.format(range, ctx);
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
FMT_EXPORT
|
||||
template <typename T, typename Char, typename Enable = void>
|
||||
struct range_format_kind
|
||||
: conditional_t<
|
||||
@@ -562,23 +490,189 @@ struct range_format_kind
|
||||
template <typename R, typename Char>
|
||||
struct formatter<
|
||||
R, Char,
|
||||
enable_if_t<conjunction<bool_constant<range_format_kind<R, Char>::value !=
|
||||
range_format::disabled>
|
||||
// Workaround a bug in MSVC 2015 and earlier.
|
||||
#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1910
|
||||
,
|
||||
detail::is_formattable_delayed<R, Char>
|
||||
#endif
|
||||
>::value>>
|
||||
: detail::range_default_formatter<range_format_kind<R, Char>::value, R,
|
||||
Char> {
|
||||
enable_if_t<conjunction<
|
||||
bool_constant<
|
||||
range_format_kind<R, Char>::value != range_format::disabled &&
|
||||
range_format_kind<R, Char>::value != range_format::map &&
|
||||
range_format_kind<R, Char>::value != range_format::string &&
|
||||
range_format_kind<R, Char>::value != range_format::debug_string>,
|
||||
detail::is_formattable_delayed<R, Char>>::value>> {
|
||||
private:
|
||||
using range_type = detail::maybe_const_range<R>;
|
||||
range_formatter<detail::uncvref_type<range_type>, Char> range_formatter_;
|
||||
|
||||
public:
|
||||
using nonlocking = void;
|
||||
|
||||
FMT_CONSTEXPR formatter() {
|
||||
if (detail::const_check(range_format_kind<R, Char>::value !=
|
||||
range_format::set))
|
||||
return;
|
||||
range_formatter_.set_brackets(detail::string_literal<Char, '{'>{},
|
||||
detail::string_literal<Char, '}'>{});
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
return range_formatter_.parse(ctx);
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
auto format(range_type& range, FormatContext& ctx) const
|
||||
-> decltype(ctx.out()) {
|
||||
return range_formatter_.format(range, ctx);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char, typename... T> struct tuple_join_view : detail::view {
|
||||
const std::tuple<T...>& tuple;
|
||||
// A map formatter.
|
||||
template <typename R, typename Char>
|
||||
struct formatter<
|
||||
R, Char,
|
||||
enable_if_t<range_format_kind<R, Char>::value == range_format::map>> {
|
||||
private:
|
||||
using map_type = detail::maybe_const_range<R>;
|
||||
using element_type = detail::uncvref_type<map_type>;
|
||||
|
||||
decltype(detail::tuple::get_formatters<element_type, Char>(
|
||||
detail::tuple_index_sequence<element_type>())) formatters_;
|
||||
bool no_delimiters_ = false;
|
||||
|
||||
public:
|
||||
FMT_CONSTEXPR formatter() {}
|
||||
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
auto it = ctx.begin();
|
||||
auto end = ctx.end();
|
||||
if (it != end) {
|
||||
if (detail::to_ascii(*it) == 'n') {
|
||||
no_delimiters_ = true;
|
||||
++it;
|
||||
}
|
||||
if (it != end && *it != '}') {
|
||||
if (*it != ':') report_error("invalid format specifier");
|
||||
++it;
|
||||
}
|
||||
ctx.advance_to(it);
|
||||
}
|
||||
detail::for_each(formatters_, detail::parse_empty_specs<Char>{ctx});
|
||||
return it;
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
auto format(map_type& map, FormatContext& ctx) const -> decltype(ctx.out()) {
|
||||
auto out = ctx.out();
|
||||
basic_string_view<Char> open = detail::string_literal<Char, '{'>{};
|
||||
if (!no_delimiters_) out = detail::copy<Char>(open, out);
|
||||
int i = 0;
|
||||
basic_string_view<Char> sep = detail::string_literal<Char, ',', ' '>{};
|
||||
for (auto&& value : map) {
|
||||
if (i > 0) out = detail::copy<Char>(sep, out);
|
||||
ctx.advance_to(out);
|
||||
detail::for_each2(formatters_, value,
|
||||
detail::format_tuple_element<FormatContext>{
|
||||
0, ctx, detail::string_literal<Char, ':', ' '>{}});
|
||||
++i;
|
||||
}
|
||||
basic_string_view<Char> close = detail::string_literal<Char, '}'>{};
|
||||
if (!no_delimiters_) out = detail::copy<Char>(close, out);
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
// A (debug_)string formatter.
|
||||
template <typename R, typename Char>
|
||||
struct formatter<
|
||||
R, Char,
|
||||
enable_if_t<range_format_kind<R, Char>::value == range_format::string ||
|
||||
range_format_kind<R, Char>::value ==
|
||||
range_format::debug_string>> {
|
||||
private:
|
||||
using range_type = detail::maybe_const_range<R>;
|
||||
using string_type =
|
||||
conditional_t<std::is_constructible<
|
||||
detail::std_string_view<Char>,
|
||||
decltype(detail::range_begin(std::declval<R>())),
|
||||
decltype(detail::range_end(std::declval<R>()))>::value,
|
||||
detail::std_string_view<Char>, std::basic_string<Char>>;
|
||||
|
||||
formatter<string_type, Char> underlying_;
|
||||
|
||||
public:
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
return underlying_.parse(ctx);
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
auto format(range_type& range, FormatContext& ctx) const
|
||||
-> decltype(ctx.out()) {
|
||||
auto out = ctx.out();
|
||||
if (detail::const_check(range_format_kind<R, Char>::value ==
|
||||
range_format::debug_string))
|
||||
*out++ = '"';
|
||||
out = underlying_.format(
|
||||
string_type{detail::range_begin(range), detail::range_end(range)}, ctx);
|
||||
if (detail::const_check(range_format_kind<R, Char>::value ==
|
||||
range_format::debug_string))
|
||||
*out++ = '"';
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename It, typename Sentinel, typename Char = char>
|
||||
struct join_view : detail::view {
|
||||
It begin;
|
||||
Sentinel end;
|
||||
basic_string_view<Char> sep;
|
||||
|
||||
tuple_join_view(const std::tuple<T...>& t, basic_string_view<Char> s)
|
||||
join_view(It b, Sentinel e, basic_string_view<Char> s)
|
||||
: begin(std::move(b)), end(e), sep(s) {}
|
||||
};
|
||||
|
||||
template <typename It, typename Sentinel, typename Char>
|
||||
struct formatter<join_view<It, Sentinel, Char>, Char> {
|
||||
private:
|
||||
using value_type =
|
||||
#ifdef __cpp_lib_ranges
|
||||
std::iter_value_t<It>;
|
||||
#else
|
||||
typename std::iterator_traits<It>::value_type;
|
||||
#endif
|
||||
formatter<remove_cvref_t<value_type>, Char> value_formatter_;
|
||||
|
||||
using view = conditional_t<std::is_copy_constructible<It>::value,
|
||||
const join_view<It, Sentinel, Char>,
|
||||
join_view<It, Sentinel, Char>>;
|
||||
|
||||
public:
|
||||
using nonlocking = void;
|
||||
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
return value_formatter_.parse(ctx);
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
auto format(view& value, FormatContext& ctx) const -> decltype(ctx.out()) {
|
||||
using iter =
|
||||
conditional_t<std::is_copy_constructible<view>::value, It, It&>;
|
||||
iter it = value.begin;
|
||||
auto out = ctx.out();
|
||||
if (it == value.end) return out;
|
||||
out = value_formatter_.format(*it, ctx);
|
||||
++it;
|
||||
while (it != value.end) {
|
||||
out = detail::copy<Char>(value.sep.begin(), value.sep.end(), out);
|
||||
ctx.advance_to(out);
|
||||
out = value_formatter_.format(*it, ctx);
|
||||
++it;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char, typename Tuple> struct tuple_join_view : detail::view {
|
||||
const Tuple& tuple;
|
||||
basic_string_view<Char> sep;
|
||||
|
||||
tuple_join_view(const Tuple& t, basic_string_view<Char> s)
|
||||
: tuple(t), sep{s} {}
|
||||
};
|
||||
|
||||
@@ -589,65 +683,64 @@ template <typename Char, typename... T> struct tuple_join_view : detail::view {
|
||||
# define FMT_TUPLE_JOIN_SPECIFIERS 0
|
||||
#endif
|
||||
|
||||
template <typename Char, typename... T>
|
||||
struct formatter<tuple_join_view<Char, T...>, Char> {
|
||||
template <typename ParseContext>
|
||||
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
return do_parse(ctx, std::integral_constant<size_t, sizeof...(T)>());
|
||||
template <typename Char, typename Tuple>
|
||||
struct formatter<tuple_join_view<Char, Tuple>, Char,
|
||||
enable_if_t<is_tuple_like<Tuple>::value>> {
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
return do_parse(ctx, std::tuple_size<Tuple>());
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
auto format(const tuple_join_view<Char, T...>& value,
|
||||
auto format(const tuple_join_view<Char, Tuple>& value,
|
||||
FormatContext& ctx) const -> typename FormatContext::iterator {
|
||||
return do_format(value, ctx,
|
||||
std::integral_constant<size_t, sizeof...(T)>());
|
||||
return do_format(value, ctx, std::tuple_size<Tuple>());
|
||||
}
|
||||
|
||||
private:
|
||||
std::tuple<formatter<typename std::decay<T>::type, Char>...> formatters_;
|
||||
decltype(detail::tuple::get_formatters<Tuple, Char>(
|
||||
detail::tuple_index_sequence<Tuple>())) formatters_;
|
||||
|
||||
template <typename ParseContext>
|
||||
FMT_CONSTEXPR auto do_parse(ParseContext& ctx,
|
||||
FMT_CONSTEXPR auto do_parse(parse_context<Char>& ctx,
|
||||
std::integral_constant<size_t, 0>)
|
||||
-> decltype(ctx.begin()) {
|
||||
-> const Char* {
|
||||
return ctx.begin();
|
||||
}
|
||||
|
||||
template <typename ParseContext, size_t N>
|
||||
FMT_CONSTEXPR auto do_parse(ParseContext& ctx,
|
||||
template <size_t N>
|
||||
FMT_CONSTEXPR auto do_parse(parse_context<Char>& ctx,
|
||||
std::integral_constant<size_t, N>)
|
||||
-> decltype(ctx.begin()) {
|
||||
-> const Char* {
|
||||
auto end = ctx.begin();
|
||||
#if FMT_TUPLE_JOIN_SPECIFIERS
|
||||
end = std::get<sizeof...(T) - N>(formatters_).parse(ctx);
|
||||
end = std::get<std::tuple_size<Tuple>::value - N>(formatters_).parse(ctx);
|
||||
if (N > 1) {
|
||||
auto end1 = do_parse(ctx, std::integral_constant<size_t, N - 1>());
|
||||
if (end != end1)
|
||||
FMT_THROW(format_error("incompatible format specs for tuple elements"));
|
||||
report_error("incompatible format specs for tuple elements");
|
||||
}
|
||||
#endif
|
||||
return end;
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
auto do_format(const tuple_join_view<Char, T...>&, FormatContext& ctx,
|
||||
auto do_format(const tuple_join_view<Char, Tuple>&, FormatContext& ctx,
|
||||
std::integral_constant<size_t, 0>) const ->
|
||||
typename FormatContext::iterator {
|
||||
return ctx.out();
|
||||
}
|
||||
|
||||
template <typename FormatContext, size_t N>
|
||||
auto do_format(const tuple_join_view<Char, T...>& value, FormatContext& ctx,
|
||||
auto do_format(const tuple_join_view<Char, Tuple>& value, FormatContext& ctx,
|
||||
std::integral_constant<size_t, N>) const ->
|
||||
typename FormatContext::iterator {
|
||||
auto out = std::get<sizeof...(T) - N>(formatters_)
|
||||
.format(std::get<sizeof...(T) - N>(value.tuple), ctx);
|
||||
if (N > 1) {
|
||||
out = std::copy(value.sep.begin(), value.sep.end(), out);
|
||||
ctx.advance_to(out);
|
||||
return do_format(value, ctx, std::integral_constant<size_t, N - 1>());
|
||||
}
|
||||
return out;
|
||||
using std::get;
|
||||
auto out =
|
||||
std::get<std::tuple_size<Tuple>::value - N>(formatters_)
|
||||
.format(get<std::tuple_size<Tuple>::value - N>(value.tuple), ctx);
|
||||
if (N <= 1) return out;
|
||||
out = detail::copy<Char>(value.sep, out);
|
||||
ctx.advance_to(out);
|
||||
return do_format(value, ctx, std::integral_constant<size_t, N - 1>());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -691,40 +784,57 @@ struct formatter<
|
||||
|
||||
FMT_BEGIN_EXPORT
|
||||
|
||||
/// Returns a view that formats the iterator range `[begin, end)` with elements
|
||||
/// separated by `sep`.
|
||||
template <typename It, typename Sentinel>
|
||||
auto join(It begin, Sentinel end, string_view sep) -> join_view<It, Sentinel> {
|
||||
return {std::move(begin), end, sep};
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Returns an object that formats `tuple` with elements separated by `sep`.
|
||||
|
||||
**Example**::
|
||||
|
||||
std::tuple<int, char> t = {1, 'a'};
|
||||
fmt::print("{}", fmt::join(t, ", "));
|
||||
// Output: "1, a"
|
||||
\endrst
|
||||
* Returns a view that formats `range` with elements separated by `sep`.
|
||||
*
|
||||
* **Example**:
|
||||
*
|
||||
* auto v = std::vector<int>{1, 2, 3};
|
||||
* fmt::print("{}", fmt::join(v, ", "));
|
||||
* // Output: 1, 2, 3
|
||||
*
|
||||
* `fmt::join` applies passed format specifiers to the range elements:
|
||||
*
|
||||
* fmt::print("{:02}", fmt::join(v, ", "));
|
||||
* // Output: 01, 02, 03
|
||||
*/
|
||||
template <typename... T>
|
||||
FMT_CONSTEXPR auto join(const std::tuple<T...>& tuple, string_view sep)
|
||||
-> tuple_join_view<char, T...> {
|
||||
return {tuple, sep};
|
||||
template <typename Range, FMT_ENABLE_IF(!is_tuple_like<Range>::value)>
|
||||
auto join(Range&& r, string_view sep)
|
||||
-> join_view<decltype(detail::range_begin(r)),
|
||||
decltype(detail::range_end(r))> {
|
||||
return {detail::range_begin(r), detail::range_end(r), sep};
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
FMT_CONSTEXPR auto join(const std::tuple<T...>& tuple,
|
||||
basic_string_view<wchar_t> sep)
|
||||
-> tuple_join_view<wchar_t, T...> {
|
||||
/**
|
||||
* Returns an object that formats `std::tuple` with elements separated by `sep`.
|
||||
*
|
||||
* **Example**:
|
||||
*
|
||||
* auto t = std::tuple<int, char>{1, 'a'};
|
||||
* fmt::print("{}", fmt::join(t, ", "));
|
||||
* // Output: 1, a
|
||||
*/
|
||||
template <typename Tuple, FMT_ENABLE_IF(is_tuple_like<Tuple>::value)>
|
||||
FMT_CONSTEXPR auto join(const Tuple& tuple, string_view sep)
|
||||
-> tuple_join_view<char, Tuple> {
|
||||
return {tuple, sep};
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Returns an object that formats `initializer_list` with elements separated by
|
||||
`sep`.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::print("{}", fmt::join({1, 2, 3}, ", "));
|
||||
// Output: "1, 2, 3"
|
||||
\endrst
|
||||
* Returns an object that formats `std::initializer_list` with elements
|
||||
* separated by `sep`.
|
||||
*
|
||||
* **Example**:
|
||||
*
|
||||
* fmt::print("{}", fmt::join({1, 2, 3}, ", "));
|
||||
* // Output: "1, 2, 3"
|
||||
*/
|
||||
template <typename T>
|
||||
auto join(std::initializer_list<T> list, string_view sep)
|
||||
|
||||
477
3rdparty/fmt/include/fmt/std.h
vendored
477
3rdparty/fmt/include/fmt/std.h
vendored
@@ -8,39 +8,49 @@
|
||||
#ifndef FMT_STD_H_
|
||||
#define FMT_STD_H_
|
||||
|
||||
#include <atomic>
|
||||
#include <bitset>
|
||||
#include <cstdlib>
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "format.h"
|
||||
#include "ostream.h"
|
||||
|
||||
#ifndef FMT_MODULE
|
||||
# include <atomic>
|
||||
# include <bitset>
|
||||
# include <complex>
|
||||
# include <cstdlib>
|
||||
# include <exception>
|
||||
# include <functional>
|
||||
# include <memory>
|
||||
# include <thread>
|
||||
# include <type_traits>
|
||||
# include <typeinfo>
|
||||
# include <utility>
|
||||
# include <vector>
|
||||
|
||||
// Check FMT_CPLUSPLUS to suppress a bogus warning in MSVC.
|
||||
# if FMT_CPLUSPLUS >= 201703L
|
||||
# if FMT_HAS_INCLUDE(<filesystem>) && \
|
||||
(!defined(FMT_CPP_LIB_FILESYSTEM) || FMT_CPP_LIB_FILESYSTEM != 0)
|
||||
# include <filesystem>
|
||||
# endif
|
||||
# if FMT_HAS_INCLUDE(<variant>)
|
||||
# include <variant>
|
||||
# endif
|
||||
# if FMT_HAS_INCLUDE(<optional>)
|
||||
# include <optional>
|
||||
# endif
|
||||
# endif
|
||||
// Use > instead of >= in the version check because <source_location> may be
|
||||
// available after C++17 but before C++20 is marked as implemented.
|
||||
# if FMT_CPLUSPLUS > 201703L && FMT_HAS_INCLUDE(<source_location>)
|
||||
# include <source_location>
|
||||
# endif
|
||||
# if FMT_CPLUSPLUS > 202002L && FMT_HAS_INCLUDE(<expected>)
|
||||
# include <expected>
|
||||
# endif
|
||||
#endif // FMT_MODULE
|
||||
|
||||
#if FMT_HAS_INCLUDE(<version>)
|
||||
# include <version>
|
||||
#endif
|
||||
// Checking FMT_CPLUSPLUS for warning suppression in MSVC.
|
||||
#if FMT_CPLUSPLUS >= 201703L
|
||||
# if FMT_HAS_INCLUDE(<filesystem>)
|
||||
# include <filesystem>
|
||||
# endif
|
||||
# if FMT_HAS_INCLUDE(<variant>)
|
||||
# include <variant>
|
||||
# endif
|
||||
# if FMT_HAS_INCLUDE(<optional>)
|
||||
# include <optional>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if FMT_CPLUSPLUS > 201703L && FMT_HAS_INCLUDE(<source_location>)
|
||||
# include <source_location>
|
||||
#endif
|
||||
|
||||
// GCC 4 does not support FMT_HAS_INCLUDE.
|
||||
#if FMT_HAS_INCLUDE(<cxxabi.h>) || defined(__GLIBCXX__)
|
||||
@@ -52,17 +62,6 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Check if typeid is available.
|
||||
#ifndef FMT_USE_TYPEID
|
||||
// __RTTI is for EDG compilers. In MSVC typeid is available without RTTI.
|
||||
# if defined(__GXX_RTTI) || FMT_HAS_FEATURE(cxx_rtti) || FMT_MSC_VERSION || \
|
||||
defined(__INTEL_RTTI__) || defined(__RTTI)
|
||||
# define FMT_USE_TYPEID 1
|
||||
# else
|
||||
# define FMT_USE_TYPEID 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// For older Xcode versions, __cpp_lib_xxx flags are inaccurately defined.
|
||||
#ifndef FMT_CPP_LIB_FILESYSTEM
|
||||
# ifdef __cpp_lib_filesystem
|
||||
@@ -117,7 +116,7 @@ void write_escaped_path(basic_memory_buffer<Char>& quoted,
|
||||
FMT_EXPORT
|
||||
template <typename Char> struct formatter<std::filesystem::path, Char> {
|
||||
private:
|
||||
format_specs<Char> specs_;
|
||||
format_specs specs_;
|
||||
detail::arg_ref<Char> width_ref_;
|
||||
bool debug_ = false;
|
||||
char path_type_ = 0;
|
||||
@@ -125,33 +124,33 @@ template <typename Char> struct formatter<std::filesystem::path, Char> {
|
||||
public:
|
||||
FMT_CONSTEXPR void set_debug_format(bool set = true) { debug_ = set; }
|
||||
|
||||
template <typename ParseContext> FMT_CONSTEXPR auto parse(ParseContext& ctx) {
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) {
|
||||
auto it = ctx.begin(), end = ctx.end();
|
||||
if (it == end) return it;
|
||||
|
||||
it = detail::parse_align(it, end, specs_);
|
||||
if (it == end) return it;
|
||||
|
||||
it = detail::parse_dynamic_spec(it, end, specs_.width, width_ref_, ctx);
|
||||
Char c = *it;
|
||||
if ((c >= '0' && c <= '9') || c == '{')
|
||||
it = detail::parse_width(it, end, specs_, width_ref_, ctx);
|
||||
if (it != end && *it == '?') {
|
||||
debug_ = true;
|
||||
++it;
|
||||
}
|
||||
if (it != end && (*it == 'g')) path_type_ = *it++;
|
||||
if (it != end && (*it == 'g')) path_type_ = detail::to_ascii(*it++);
|
||||
return it;
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
auto format(const std::filesystem::path& p, FormatContext& ctx) const {
|
||||
auto specs = specs_;
|
||||
# ifdef _WIN32
|
||||
auto path_string = !path_type_ ? p.native() : p.generic_wstring();
|
||||
# else
|
||||
auto path_string = !path_type_ ? p.native() : p.generic_string();
|
||||
# endif
|
||||
auto path_string =
|
||||
!path_type_ ? p.native()
|
||||
: p.generic_string<std::filesystem::path::value_type>();
|
||||
|
||||
detail::handle_dynamic_spec<detail::width_checker>(specs.width, width_ref_,
|
||||
ctx);
|
||||
detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_,
|
||||
ctx);
|
||||
if (!debug_) {
|
||||
auto s = detail::get_path_string<Char>(p, path_string);
|
||||
return detail::write(ctx.out(), basic_string_view<Char>(s), specs);
|
||||
@@ -163,13 +162,30 @@ template <typename Char> struct formatter<std::filesystem::path, Char> {
|
||||
specs);
|
||||
}
|
||||
};
|
||||
|
||||
class path : public std::filesystem::path {
|
||||
public:
|
||||
auto display_string() const -> std::string {
|
||||
const std::filesystem::path& base = *this;
|
||||
return fmt::format(FMT_STRING("{}"), base);
|
||||
}
|
||||
auto system_string() const -> std::string { return string(); }
|
||||
|
||||
auto generic_display_string() const -> std::string {
|
||||
const std::filesystem::path& base = *this;
|
||||
return fmt::format(FMT_STRING("{:g}"), base);
|
||||
}
|
||||
auto generic_system_string() const -> std::string { return generic_string(); }
|
||||
};
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
#endif // FMT_CPP_LIB_FILESYSTEM
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
FMT_EXPORT
|
||||
template <std::size_t N, typename Char>
|
||||
struct formatter<std::bitset<N>, Char> : nested_formatter<string_view> {
|
||||
struct formatter<std::bitset<N>, Char>
|
||||
: nested_formatter<basic_string_view<Char>, Char> {
|
||||
private:
|
||||
// Functor because C++11 doesn't support generic lambdas.
|
||||
struct writer {
|
||||
@@ -189,7 +205,7 @@ struct formatter<std::bitset<N>, Char> : nested_formatter<string_view> {
|
||||
template <typename FormatContext>
|
||||
auto format(const std::bitset<N>& bs, FormatContext& ctx) const
|
||||
-> decltype(ctx.out()) {
|
||||
return write_padded(ctx, writer{bs});
|
||||
return this->write_padded(ctx, writer{bs});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -222,7 +238,7 @@ struct formatter<std::optional<T>, Char,
|
||||
FMT_CONSTEXPR static void maybe_set_debug_format(U&, ...) {}
|
||||
|
||||
public:
|
||||
template <typename ParseContext> FMT_CONSTEXPR auto parse(ParseContext& ctx) {
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) {
|
||||
maybe_set_debug_format(underlying_, true);
|
||||
return underlying_.parse(ctx);
|
||||
}
|
||||
@@ -242,13 +258,62 @@ struct formatter<std::optional<T>, Char,
|
||||
FMT_END_NAMESPACE
|
||||
#endif // __cpp_lib_optional
|
||||
|
||||
#if defined(__cpp_lib_expected) || FMT_CPP_LIB_VARIANT
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
namespace detail {
|
||||
|
||||
template <typename Char, typename OutputIt, typename T>
|
||||
auto write_escaped_alternative(OutputIt out, const T& v) -> OutputIt {
|
||||
if constexpr (has_to_string_view<T>::value)
|
||||
return write_escaped_string<Char>(out, detail::to_string_view(v));
|
||||
if constexpr (std::is_same_v<T, Char>) return write_escaped_char(out, v);
|
||||
return write<Char>(out, v);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
#endif
|
||||
|
||||
#ifdef __cpp_lib_expected
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
FMT_EXPORT
|
||||
template <typename T, typename E, typename Char>
|
||||
struct formatter<std::expected<T, E>, Char,
|
||||
std::enable_if_t<(std::is_void<T>::value ||
|
||||
is_formattable<T, Char>::value) &&
|
||||
is_formattable<E, Char>::value>> {
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
return ctx.begin();
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
auto format(const std::expected<T, E>& value, FormatContext& ctx) const
|
||||
-> decltype(ctx.out()) {
|
||||
auto out = ctx.out();
|
||||
|
||||
if (value.has_value()) {
|
||||
out = detail::write<Char>(out, "expected(");
|
||||
if constexpr (!std::is_void<T>::value)
|
||||
out = detail::write_escaped_alternative<Char>(out, *value);
|
||||
} else {
|
||||
out = detail::write<Char>(out, "unexpected(");
|
||||
out = detail::write_escaped_alternative<Char>(out, value.error());
|
||||
}
|
||||
*out++ = ')';
|
||||
return out;
|
||||
}
|
||||
};
|
||||
FMT_END_NAMESPACE
|
||||
#endif // __cpp_lib_expected
|
||||
|
||||
#ifdef __cpp_lib_source_location
|
||||
FMT_BEGIN_NAMESPACE
|
||||
FMT_EXPORT
|
||||
template <> struct formatter<std::source_location> {
|
||||
template <typename ParseContext> FMT_CONSTEXPR auto parse(ParseContext& ctx) {
|
||||
return ctx.begin();
|
||||
}
|
||||
FMT_CONSTEXPR auto parse(parse_context<>& ctx) { return ctx.begin(); }
|
||||
|
||||
template <typename FormatContext>
|
||||
auto format(const std::source_location& loc, FormatContext& ctx) const
|
||||
@@ -291,16 +356,6 @@ template <typename T, typename C> class is_variant_formattable_ {
|
||||
decltype(check(variant_index_sequence<T>{}))::value;
|
||||
};
|
||||
|
||||
template <typename Char, typename OutputIt, typename T>
|
||||
auto write_variant_alternative(OutputIt out, const T& v) -> OutputIt {
|
||||
if constexpr (is_string<T>::value)
|
||||
return write_escaped_string<Char>(out, detail::to_string_view(v));
|
||||
else if constexpr (std::is_same_v<T, Char>)
|
||||
return write_escaped_char(out, v);
|
||||
else
|
||||
return write<Char>(out, v);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T> struct is_variant_like {
|
||||
@@ -314,8 +369,7 @@ template <typename T, typename C> struct is_variant_formattable {
|
||||
|
||||
FMT_EXPORT
|
||||
template <typename Char> struct formatter<std::monostate, Char> {
|
||||
template <typename ParseContext>
|
||||
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
return ctx.begin();
|
||||
}
|
||||
|
||||
@@ -332,8 +386,7 @@ struct formatter<
|
||||
Variant, Char,
|
||||
std::enable_if_t<std::conjunction_v<
|
||||
is_variant_like<Variant>, is_variant_formattable<Variant, Char>>>> {
|
||||
template <typename ParseContext>
|
||||
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
return ctx.begin();
|
||||
}
|
||||
|
||||
@@ -346,7 +399,7 @@ struct formatter<
|
||||
FMT_TRY {
|
||||
std::visit(
|
||||
[&](const auto& v) {
|
||||
out = detail::write_variant_alternative<Char>(out, v);
|
||||
out = detail::write_escaped_alternative<Char>(out, v);
|
||||
},
|
||||
value);
|
||||
}
|
||||
@@ -362,23 +415,128 @@ FMT_END_NAMESPACE
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
FMT_EXPORT
|
||||
template <typename Char> struct formatter<std::error_code, Char> {
|
||||
template <typename ParseContext>
|
||||
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
return ctx.begin();
|
||||
template <> struct formatter<std::error_code> {
|
||||
private:
|
||||
format_specs specs_;
|
||||
detail::arg_ref<char> width_ref_;
|
||||
|
||||
public:
|
||||
FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* {
|
||||
auto it = ctx.begin(), end = ctx.end();
|
||||
if (it == end) return it;
|
||||
|
||||
it = detail::parse_align(it, end, specs_);
|
||||
if (it == end) return it;
|
||||
|
||||
char c = *it;
|
||||
if ((c >= '0' && c <= '9') || c == '{')
|
||||
it = detail::parse_width(it, end, specs_, width_ref_, ctx);
|
||||
return it;
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
FMT_CONSTEXPR auto format(const std::error_code& ec, FormatContext& ctx) const
|
||||
-> decltype(ctx.out()) {
|
||||
auto out = ctx.out();
|
||||
out = detail::write_bytes(out, ec.category().name(), format_specs<Char>());
|
||||
out = detail::write<Char>(out, Char(':'));
|
||||
out = detail::write<Char>(out, ec.value());
|
||||
return out;
|
||||
FMT_CONSTEXPR20 auto format(const std::error_code& ec,
|
||||
FormatContext& ctx) const -> decltype(ctx.out()) {
|
||||
auto specs = specs_;
|
||||
detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_,
|
||||
ctx);
|
||||
memory_buffer buf;
|
||||
buf.append(string_view(ec.category().name()));
|
||||
buf.push_back(':');
|
||||
detail::write<char>(appender(buf), ec.value());
|
||||
return detail::write<char>(ctx.out(), string_view(buf.data(), buf.size()),
|
||||
specs);
|
||||
}
|
||||
};
|
||||
|
||||
#if FMT_USE_RTTI
|
||||
namespace detail {
|
||||
|
||||
template <typename Char, typename OutputIt>
|
||||
auto write_demangled_name(OutputIt out, const std::type_info& ti) -> OutputIt {
|
||||
# ifdef FMT_HAS_ABI_CXA_DEMANGLE
|
||||
int status = 0;
|
||||
std::size_t size = 0;
|
||||
std::unique_ptr<char, void (*)(void*)> demangled_name_ptr(
|
||||
abi::__cxa_demangle(ti.name(), nullptr, &size, &status), &std::free);
|
||||
|
||||
string_view demangled_name_view;
|
||||
if (demangled_name_ptr) {
|
||||
demangled_name_view = demangled_name_ptr.get();
|
||||
|
||||
// Normalization of stdlib inline namespace names.
|
||||
// libc++ inline namespaces.
|
||||
// std::__1::* -> std::*
|
||||
// std::__1::__fs::* -> std::*
|
||||
// libstdc++ inline namespaces.
|
||||
// std::__cxx11::* -> std::*
|
||||
// std::filesystem::__cxx11::* -> std::filesystem::*
|
||||
if (demangled_name_view.starts_with("std::")) {
|
||||
char* begin = demangled_name_ptr.get();
|
||||
char* to = begin + 5; // std::
|
||||
for (char *from = to, *end = begin + demangled_name_view.size();
|
||||
from < end;) {
|
||||
// This is safe, because demangled_name is NUL-terminated.
|
||||
if (from[0] == '_' && from[1] == '_') {
|
||||
char* next = from + 1;
|
||||
while (next < end && *next != ':') next++;
|
||||
if (next[0] == ':' && next[1] == ':') {
|
||||
from = next + 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
*to++ = *from++;
|
||||
}
|
||||
demangled_name_view = {begin, detail::to_unsigned(to - begin)};
|
||||
}
|
||||
} else {
|
||||
demangled_name_view = string_view(ti.name());
|
||||
}
|
||||
return detail::write_bytes<Char>(out, demangled_name_view);
|
||||
# elif FMT_MSC_VERSION
|
||||
const string_view demangled_name(ti.name());
|
||||
for (std::size_t i = 0; i < demangled_name.size(); ++i) {
|
||||
auto sub = demangled_name;
|
||||
sub.remove_prefix(i);
|
||||
if (sub.starts_with("enum ")) {
|
||||
i += 4;
|
||||
continue;
|
||||
}
|
||||
if (sub.starts_with("class ") || sub.starts_with("union ")) {
|
||||
i += 5;
|
||||
continue;
|
||||
}
|
||||
if (sub.starts_with("struct ")) {
|
||||
i += 6;
|
||||
continue;
|
||||
}
|
||||
if (*sub.begin() != ' ') *out++ = *sub.begin();
|
||||
}
|
||||
return out;
|
||||
# else
|
||||
return detail::write_bytes<Char>(out, string_view(ti.name()));
|
||||
# endif
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
FMT_EXPORT
|
||||
template <typename Char>
|
||||
struct formatter<std::type_info, Char // DEPRECATED! Mixing code unit types.
|
||||
> {
|
||||
public:
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
return ctx.begin();
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
auto format(const std::type_info& ti, Context& ctx) const
|
||||
-> decltype(ctx.out()) {
|
||||
return detail::write_demangled_name<Char>(ctx.out(), ti);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
FMT_EXPORT
|
||||
template <typename T, typename Char>
|
||||
struct formatter<
|
||||
@@ -388,81 +546,29 @@ struct formatter<
|
||||
bool with_typename_ = false;
|
||||
|
||||
public:
|
||||
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
|
||||
-> decltype(ctx.begin()) {
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
auto it = ctx.begin();
|
||||
auto end = ctx.end();
|
||||
if (it == end || *it == '}') return it;
|
||||
if (*it == 't') {
|
||||
++it;
|
||||
with_typename_ = FMT_USE_TYPEID != 0;
|
||||
with_typename_ = FMT_USE_RTTI != 0;
|
||||
}
|
||||
return it;
|
||||
}
|
||||
|
||||
template <typename OutputIt>
|
||||
auto format(const std::exception& ex,
|
||||
basic_format_context<OutputIt, Char>& ctx) const -> OutputIt {
|
||||
format_specs<Char> spec;
|
||||
template <typename Context>
|
||||
auto format(const std::exception& ex, Context& ctx) const
|
||||
-> decltype(ctx.out()) {
|
||||
auto out = ctx.out();
|
||||
if (!with_typename_)
|
||||
return detail::write_bytes(out, string_view(ex.what()), spec);
|
||||
|
||||
#if FMT_USE_TYPEID
|
||||
const std::type_info& ti = typeid(ex);
|
||||
# ifdef FMT_HAS_ABI_CXA_DEMANGLE
|
||||
int status = 0;
|
||||
std::size_t size = 0;
|
||||
std::unique_ptr<char, void (*)(void*)> demangled_name_ptr(
|
||||
abi::__cxa_demangle(ti.name(), nullptr, &size, &status), &std::free);
|
||||
|
||||
string_view demangled_name_view;
|
||||
if (demangled_name_ptr) {
|
||||
demangled_name_view = demangled_name_ptr.get();
|
||||
|
||||
// Normalization of stdlib inline namespace names.
|
||||
// libc++ inline namespaces.
|
||||
// std::__1::* -> std::*
|
||||
// std::__1::__fs::* -> std::*
|
||||
// libstdc++ inline namespaces.
|
||||
// std::__cxx11::* -> std::*
|
||||
// std::filesystem::__cxx11::* -> std::filesystem::*
|
||||
if (demangled_name_view.starts_with("std::")) {
|
||||
char* begin = demangled_name_ptr.get();
|
||||
char* to = begin + 5; // std::
|
||||
for (char *from = to, *end = begin + demangled_name_view.size();
|
||||
from < end;) {
|
||||
// This is safe, because demangled_name is NUL-terminated.
|
||||
if (from[0] == '_' && from[1] == '_') {
|
||||
char* next = from + 1;
|
||||
while (next < end && *next != ':') next++;
|
||||
if (next[0] == ':' && next[1] == ':') {
|
||||
from = next + 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
*to++ = *from++;
|
||||
}
|
||||
demangled_name_view = {begin, detail::to_unsigned(to - begin)};
|
||||
}
|
||||
} else {
|
||||
demangled_name_view = string_view(ti.name());
|
||||
#if FMT_USE_RTTI
|
||||
if (with_typename_) {
|
||||
out = detail::write_demangled_name<Char>(out, typeid(ex));
|
||||
*out++ = ':';
|
||||
*out++ = ' ';
|
||||
}
|
||||
out = detail::write_bytes(out, demangled_name_view, spec);
|
||||
# elif FMT_MSC_VERSION
|
||||
string_view demangled_name_view(ti.name());
|
||||
if (demangled_name_view.starts_with("class "))
|
||||
demangled_name_view.remove_prefix(6);
|
||||
else if (demangled_name_view.starts_with("struct "))
|
||||
demangled_name_view.remove_prefix(7);
|
||||
out = detail::write_bytes(out, demangled_name_view, spec);
|
||||
# else
|
||||
out = detail::write_bytes(out, string_view(ti.name()), spec);
|
||||
# endif
|
||||
*out++ = ':';
|
||||
*out++ = ' ';
|
||||
return detail::write_bytes(out, string_view(ex.what()), spec);
|
||||
#endif
|
||||
return detail::write_bytes<Char>(out, string_view(ex.what()));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -509,6 +615,14 @@ struct formatter<BitRef, Char,
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Deleter>
|
||||
auto ptr(const std::unique_ptr<T, Deleter>& p) -> const void* {
|
||||
return p.get();
|
||||
}
|
||||
template <typename T> auto ptr(const std::shared_ptr<T>& p) -> const void* {
|
||||
return p.get();
|
||||
}
|
||||
|
||||
FMT_EXPORT
|
||||
template <typename T, typename Char>
|
||||
struct formatter<std::atomic<T>, Char,
|
||||
@@ -533,5 +647,80 @@ struct formatter<std::atomic_flag, Char> : formatter<bool, Char> {
|
||||
};
|
||||
#endif // __cpp_lib_atomic_flag_test
|
||||
|
||||
FMT_EXPORT
|
||||
template <typename T, typename Char> struct formatter<std::complex<T>, Char> {
|
||||
private:
|
||||
detail::dynamic_format_specs<Char> specs_;
|
||||
|
||||
template <typename FormatContext, typename OutputIt>
|
||||
FMT_CONSTEXPR auto do_format(const std::complex<T>& c,
|
||||
detail::dynamic_format_specs<Char>& specs,
|
||||
FormatContext& ctx, OutputIt out) const
|
||||
-> OutputIt {
|
||||
if (c.real() != 0) {
|
||||
*out++ = Char('(');
|
||||
out = detail::write<Char>(out, c.real(), specs, ctx.locale());
|
||||
specs.set_sign(sign::plus);
|
||||
out = detail::write<Char>(out, c.imag(), specs, ctx.locale());
|
||||
if (!detail::isfinite(c.imag())) *out++ = Char(' ');
|
||||
*out++ = Char('i');
|
||||
*out++ = Char(')');
|
||||
return out;
|
||||
}
|
||||
out = detail::write<Char>(out, c.imag(), specs, ctx.locale());
|
||||
if (!detail::isfinite(c.imag())) *out++ = Char(' ');
|
||||
*out++ = Char('i');
|
||||
return out;
|
||||
}
|
||||
|
||||
public:
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
if (ctx.begin() == ctx.end() || *ctx.begin() == '}') return ctx.begin();
|
||||
return parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx,
|
||||
detail::type_constant<T, Char>::value);
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
auto format(const std::complex<T>& c, FormatContext& ctx) const
|
||||
-> decltype(ctx.out()) {
|
||||
auto specs = specs_;
|
||||
if (specs.dynamic()) {
|
||||
detail::handle_dynamic_spec(specs.dynamic_width(), specs.width,
|
||||
specs.width_ref, ctx);
|
||||
detail::handle_dynamic_spec(specs.dynamic_precision(), specs.precision,
|
||||
specs.precision_ref, ctx);
|
||||
}
|
||||
|
||||
if (specs.width == 0) return do_format(c, specs, ctx, ctx.out());
|
||||
auto buf = basic_memory_buffer<Char>();
|
||||
|
||||
auto outer_specs = format_specs();
|
||||
outer_specs.width = specs.width;
|
||||
outer_specs.copy_fill_from(specs);
|
||||
outer_specs.set_align(specs.align());
|
||||
|
||||
specs.width = 0;
|
||||
specs.set_fill({});
|
||||
specs.set_align(align::none);
|
||||
|
||||
do_format(c, specs, ctx, basic_appender<Char>(buf));
|
||||
return detail::write<Char>(ctx.out(),
|
||||
basic_string_view<Char>(buf.data(), buf.size()),
|
||||
outer_specs);
|
||||
}
|
||||
};
|
||||
|
||||
FMT_EXPORT
|
||||
template <typename T, typename Char>
|
||||
struct formatter<std::reference_wrapper<T>, Char,
|
||||
enable_if_t<is_formattable<remove_cvref_t<T>, Char>::value>>
|
||||
: formatter<remove_cvref_t<T>, Char> {
|
||||
template <typename FormatContext>
|
||||
auto format(std::reference_wrapper<T> ref, FormatContext& ctx) const
|
||||
-> decltype(ctx.out()) {
|
||||
return formatter<remove_cvref_t<T>, Char>::format(ref.get(), ctx);
|
||||
}
|
||||
};
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
#endif // FMT_STD_H_
|
||||
|
||||
268
3rdparty/fmt/include/fmt/xchar.h
vendored
268
3rdparty/fmt/include/fmt/xchar.h
vendored
@@ -8,12 +8,16 @@
|
||||
#ifndef FMT_XCHAR_H_
|
||||
#define FMT_XCHAR_H_
|
||||
|
||||
#include <cwchar>
|
||||
|
||||
#include "color.h"
|
||||
#include "format.h"
|
||||
#include "ostream.h"
|
||||
#include "ranges.h"
|
||||
|
||||
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
|
||||
# include <locale>
|
||||
#ifndef FMT_MODULE
|
||||
# include <cwchar>
|
||||
# if FMT_USE_LOCALE
|
||||
# include <locale>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
@@ -22,10 +26,26 @@ namespace detail {
|
||||
template <typename T>
|
||||
using is_exotic_char = bool_constant<!std::is_same<T, char>::value>;
|
||||
|
||||
inline auto write_loc(std::back_insert_iterator<detail::buffer<wchar_t>> out,
|
||||
loc_value value, const format_specs<wchar_t>& specs,
|
||||
locale_ref loc) -> bool {
|
||||
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
|
||||
template <typename S, typename = void> struct format_string_char {};
|
||||
|
||||
template <typename S>
|
||||
struct format_string_char<
|
||||
S, void_t<decltype(sizeof(detail::to_string_view(std::declval<S>())))>> {
|
||||
using type = char_t<S>;
|
||||
};
|
||||
|
||||
template <typename S>
|
||||
struct format_string_char<
|
||||
S, enable_if_t<std::is_base_of<detail::compile_string, S>::value>> {
|
||||
using type = typename S::char_type;
|
||||
};
|
||||
|
||||
template <typename S>
|
||||
using format_string_char_t = typename format_string_char<S>::type;
|
||||
|
||||
inline auto write_loc(basic_appender<wchar_t> out, loc_value value,
|
||||
const format_specs& specs, locale_ref loc) -> bool {
|
||||
#if FMT_USE_LOCALE
|
||||
auto& numpunct =
|
||||
std::use_facet<std::numpunct<wchar_t>>(loc.get<std::locale>());
|
||||
auto separator = std::wstring();
|
||||
@@ -40,42 +60,79 @@ inline auto write_loc(std::back_insert_iterator<detail::buffer<wchar_t>> out,
|
||||
FMT_BEGIN_EXPORT
|
||||
|
||||
using wstring_view = basic_string_view<wchar_t>;
|
||||
using wformat_parse_context = basic_format_parse_context<wchar_t>;
|
||||
using wformat_context = buffer_context<wchar_t>;
|
||||
using wformat_parse_context = parse_context<wchar_t>;
|
||||
using wformat_context = buffered_context<wchar_t>;
|
||||
using wformat_args = basic_format_args<wformat_context>;
|
||||
using wmemory_buffer = basic_memory_buffer<wchar_t>;
|
||||
|
||||
#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
|
||||
// Workaround broken conversion on older gcc.
|
||||
template <typename... Args> using wformat_string = wstring_view;
|
||||
inline auto runtime(wstring_view s) -> wstring_view { return s; }
|
||||
#else
|
||||
template <typename... Args>
|
||||
using wformat_string = basic_format_string<wchar_t, type_identity_t<Args>...>;
|
||||
template <typename Char, typename... T> struct basic_fstring {
|
||||
private:
|
||||
basic_string_view<Char> str_;
|
||||
|
||||
static constexpr int num_static_named_args =
|
||||
detail::count_static_named_args<T...>();
|
||||
|
||||
using checker = detail::format_string_checker<
|
||||
Char, static_cast<int>(sizeof...(T)), num_static_named_args,
|
||||
num_static_named_args != detail::count_named_args<T...>()>;
|
||||
|
||||
using arg_pack = detail::arg_pack<T...>;
|
||||
|
||||
public:
|
||||
using t = basic_fstring;
|
||||
|
||||
template <typename S,
|
||||
FMT_ENABLE_IF(
|
||||
std::is_convertible<const S&, basic_string_view<Char>>::value)>
|
||||
FMT_CONSTEVAL FMT_ALWAYS_INLINE basic_fstring(const S& s) : str_(s) {
|
||||
if (FMT_USE_CONSTEVAL)
|
||||
detail::parse_format_string<Char>(s, checker(s, arg_pack()));
|
||||
}
|
||||
template <typename S,
|
||||
FMT_ENABLE_IF(std::is_base_of<detail::compile_string, S>::value&&
|
||||
std::is_same<typename S::char_type, Char>::value)>
|
||||
FMT_ALWAYS_INLINE basic_fstring(const S&) : str_(S()) {
|
||||
FMT_CONSTEXPR auto sv = basic_string_view<Char>(S());
|
||||
FMT_CONSTEXPR int ignore =
|
||||
(parse_format_string(sv, checker(sv, arg_pack())), 0);
|
||||
detail::ignore_unused(ignore);
|
||||
}
|
||||
basic_fstring(runtime_format_string<Char> fmt) : str_(fmt.str) {}
|
||||
|
||||
operator basic_string_view<Char>() const { return str_; }
|
||||
auto get() const -> basic_string_view<Char> { return str_; }
|
||||
};
|
||||
|
||||
template <typename Char, typename... T>
|
||||
using basic_format_string = basic_fstring<Char, T...>;
|
||||
|
||||
template <typename... T>
|
||||
using wformat_string = typename basic_format_string<wchar_t, T...>::t;
|
||||
inline auto runtime(wstring_view s) -> runtime_format_string<wchar_t> {
|
||||
return {{s}};
|
||||
}
|
||||
#endif
|
||||
|
||||
template <> struct is_char<wchar_t> : std::true_type {};
|
||||
template <> struct is_char<detail::char8_type> : std::true_type {};
|
||||
template <> struct is_char<char16_t> : std::true_type {};
|
||||
template <> struct is_char<char32_t> : std::true_type {};
|
||||
|
||||
#ifdef __cpp_char8_t
|
||||
template <> struct is_char<char8_t> : bool_constant<detail::is_utf8_enabled> {};
|
||||
#endif
|
||||
|
||||
template <typename... T>
|
||||
constexpr auto make_wformat_args(const T&... args)
|
||||
-> format_arg_store<wformat_context, T...> {
|
||||
return {args...};
|
||||
constexpr auto make_wformat_args(T&... args)
|
||||
-> decltype(fmt::make_format_args<wformat_context>(args...)) {
|
||||
return fmt::make_format_args<wformat_context>(args...);
|
||||
}
|
||||
|
||||
#if !FMT_USE_NONTYPE_TEMPLATE_ARGS
|
||||
inline namespace literals {
|
||||
#if FMT_USE_USER_DEFINED_LITERALS && !FMT_USE_NONTYPE_TEMPLATE_ARGS
|
||||
constexpr auto operator""_a(const wchar_t* s, size_t)
|
||||
-> detail::udl_arg<wchar_t> {
|
||||
inline auto operator""_a(const wchar_t* s, size_t) -> detail::udl_arg<wchar_t> {
|
||||
return {s};
|
||||
}
|
||||
#endif
|
||||
} // namespace literals
|
||||
#endif
|
||||
|
||||
template <typename It, typename Sentinel>
|
||||
auto join(It begin, Sentinel end, wstring_view sep)
|
||||
@@ -83,9 +140,9 @@ auto join(It begin, Sentinel end, wstring_view sep)
|
||||
return {begin, end, sep};
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
template <typename Range, FMT_ENABLE_IF(!is_tuple_like<Range>::value)>
|
||||
auto join(Range&& range, wstring_view sep)
|
||||
-> join_view<detail::iterator_t<Range>, detail::sentinel_t<Range>,
|
||||
-> join_view<decltype(std::begin(range)), decltype(std::end(range)),
|
||||
wchar_t> {
|
||||
return join(std::begin(range), std::end(range), sep);
|
||||
}
|
||||
@@ -96,13 +153,19 @@ auto join(std::initializer_list<T> list, wstring_view sep)
|
||||
return join(std::begin(list), std::end(list), sep);
|
||||
}
|
||||
|
||||
template <typename Tuple, FMT_ENABLE_IF(is_tuple_like<Tuple>::value)>
|
||||
auto join(const Tuple& tuple, basic_string_view<wchar_t> sep)
|
||||
-> tuple_join_view<wchar_t, Tuple> {
|
||||
return {tuple, sep};
|
||||
}
|
||||
|
||||
template <typename Char, FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
|
||||
auto vformat(basic_string_view<Char> format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args)
|
||||
auto vformat(basic_string_view<Char> fmt,
|
||||
typename detail::vformat_args<Char>::type args)
|
||||
-> std::basic_string<Char> {
|
||||
auto buf = basic_memory_buffer<Char>();
|
||||
detail::vformat_to(buf, format_str, args);
|
||||
return to_string(buf);
|
||||
detail::vformat_to(buf, fmt, args);
|
||||
return {buf.data(), buf.size()};
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
@@ -110,110 +173,122 @@ auto format(wformat_string<T...> fmt, T&&... args) -> std::wstring {
|
||||
return vformat(fmt::wstring_view(fmt), fmt::make_wformat_args(args...));
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename... T>
|
||||
auto format_to(OutputIt out, wformat_string<T...> fmt, T&&... args)
|
||||
-> OutputIt {
|
||||
return vformat_to(out, fmt::wstring_view(fmt),
|
||||
fmt::make_wformat_args(args...));
|
||||
}
|
||||
|
||||
// Pass char_t as a default template parameter instead of using
|
||||
// std::basic_string<char_t<S>> to reduce the symbol size.
|
||||
template <typename S, typename... T, typename Char = char_t<S>,
|
||||
template <typename S, typename... T,
|
||||
typename Char = detail::format_string_char_t<S>,
|
||||
FMT_ENABLE_IF(!std::is_same<Char, char>::value &&
|
||||
!std::is_same<Char, wchar_t>::value)>
|
||||
auto format(const S& format_str, T&&... args) -> std::basic_string<Char> {
|
||||
return vformat(detail::to_string_view(format_str),
|
||||
fmt::make_format_args<buffer_context<Char>>(args...));
|
||||
auto format(const S& fmt, T&&... args) -> std::basic_string<Char> {
|
||||
return vformat(detail::to_string_view(fmt),
|
||||
fmt::make_format_args<buffered_context<Char>>(args...));
|
||||
}
|
||||
|
||||
template <typename Locale, typename S, typename Char = char_t<S>,
|
||||
template <typename Locale, typename S,
|
||||
typename Char = detail::format_string_char_t<S>,
|
||||
FMT_ENABLE_IF(detail::is_locale<Locale>::value&&
|
||||
detail::is_exotic_char<Char>::value)>
|
||||
inline auto vformat(
|
||||
const Locale& loc, const S& format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args)
|
||||
inline auto vformat(const Locale& loc, const S& fmt,
|
||||
typename detail::vformat_args<Char>::type args)
|
||||
-> std::basic_string<Char> {
|
||||
return detail::vformat(loc, detail::to_string_view(format_str), args);
|
||||
auto buf = basic_memory_buffer<Char>();
|
||||
detail::vformat_to(buf, detail::to_string_view(fmt), args,
|
||||
detail::locale_ref(loc));
|
||||
return {buf.data(), buf.size()};
|
||||
}
|
||||
|
||||
template <typename Locale, typename S, typename... T, typename Char = char_t<S>,
|
||||
template <typename Locale, typename S, typename... T,
|
||||
typename Char = detail::format_string_char_t<S>,
|
||||
FMT_ENABLE_IF(detail::is_locale<Locale>::value&&
|
||||
detail::is_exotic_char<Char>::value)>
|
||||
inline auto format(const Locale& loc, const S& format_str, T&&... args)
|
||||
inline auto format(const Locale& loc, const S& fmt, T&&... args)
|
||||
-> std::basic_string<Char> {
|
||||
return detail::vformat(loc, detail::to_string_view(format_str),
|
||||
fmt::make_format_args<buffer_context<Char>>(args...));
|
||||
return vformat(loc, detail::to_string_view(fmt),
|
||||
fmt::make_format_args<buffered_context<Char>>(args...));
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename S, typename Char = char_t<S>,
|
||||
template <typename OutputIt, typename S,
|
||||
typename Char = detail::format_string_char_t<S>,
|
||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
|
||||
detail::is_exotic_char<Char>::value)>
|
||||
auto vformat_to(OutputIt out, const S& format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args)
|
||||
-> OutputIt {
|
||||
auto vformat_to(OutputIt out, const S& fmt,
|
||||
typename detail::vformat_args<Char>::type args) -> OutputIt {
|
||||
auto&& buf = detail::get_buffer<Char>(out);
|
||||
detail::vformat_to(buf, detail::to_string_view(format_str), args);
|
||||
detail::vformat_to(buf, detail::to_string_view(fmt), args);
|
||||
return detail::get_iterator(buf, out);
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename S, typename... T,
|
||||
typename Char = char_t<S>,
|
||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
|
||||
detail::is_exotic_char<Char>::value)>
|
||||
typename Char = detail::format_string_char_t<S>,
|
||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value &&
|
||||
!std::is_same<Char, char>::value &&
|
||||
!std::is_same<Char, wchar_t>::value)>
|
||||
inline auto format_to(OutputIt out, const S& fmt, T&&... args) -> OutputIt {
|
||||
return vformat_to(out, detail::to_string_view(fmt),
|
||||
fmt::make_format_args<buffer_context<Char>>(args...));
|
||||
fmt::make_format_args<buffered_context<Char>>(args...));
|
||||
}
|
||||
|
||||
template <typename Locale, typename S, typename OutputIt, typename... Args,
|
||||
typename Char = char_t<S>,
|
||||
typename Char = detail::format_string_char_t<S>,
|
||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
|
||||
detail::is_locale<Locale>::value&&
|
||||
detail::is_exotic_char<Char>::value)>
|
||||
inline auto vformat_to(
|
||||
OutputIt out, const Locale& loc, const S& format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args) -> OutputIt {
|
||||
inline auto vformat_to(OutputIt out, const Locale& loc, const S& fmt,
|
||||
typename detail::vformat_args<Char>::type args)
|
||||
-> OutputIt {
|
||||
auto&& buf = detail::get_buffer<Char>(out);
|
||||
vformat_to(buf, detail::to_string_view(format_str), args,
|
||||
detail::locale_ref(loc));
|
||||
vformat_to(buf, detail::to_string_view(fmt), args, detail::locale_ref(loc));
|
||||
return detail::get_iterator(buf, out);
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename Locale, typename S, typename... T,
|
||||
typename Char = char_t<S>,
|
||||
template <typename Locale, typename OutputIt, typename S, typename... T,
|
||||
typename Char = detail::format_string_char_t<S>,
|
||||
bool enable = detail::is_output_iterator<OutputIt, Char>::value &&
|
||||
detail::is_locale<Locale>::value &&
|
||||
detail::is_exotic_char<Char>::value>
|
||||
inline auto format_to(OutputIt out, const Locale& loc, const S& format_str,
|
||||
inline auto format_to(OutputIt out, const Locale& loc, const S& fmt,
|
||||
T&&... args) ->
|
||||
typename std::enable_if<enable, OutputIt>::type {
|
||||
return vformat_to(out, loc, detail::to_string_view(format_str),
|
||||
fmt::make_format_args<buffer_context<Char>>(args...));
|
||||
return vformat_to(out, loc, detail::to_string_view(fmt),
|
||||
fmt::make_format_args<buffered_context<Char>>(args...));
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename Char, typename... Args,
|
||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
|
||||
detail::is_exotic_char<Char>::value)>
|
||||
inline auto vformat_to_n(
|
||||
OutputIt out, size_t n, basic_string_view<Char> format_str,
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args)
|
||||
inline auto vformat_to_n(OutputIt out, size_t n, basic_string_view<Char> fmt,
|
||||
typename detail::vformat_args<Char>::type args)
|
||||
-> format_to_n_result<OutputIt> {
|
||||
using traits = detail::fixed_buffer_traits;
|
||||
auto buf = detail::iterator_buffer<OutputIt, Char, traits>(out, n);
|
||||
detail::vformat_to(buf, format_str, args);
|
||||
detail::vformat_to(buf, fmt, args);
|
||||
return {buf.out(), buf.count()};
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename S, typename... T,
|
||||
typename Char = char_t<S>,
|
||||
typename Char = detail::format_string_char_t<S>,
|
||||
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
|
||||
detail::is_exotic_char<Char>::value)>
|
||||
inline auto format_to_n(OutputIt out, size_t n, const S& fmt, T&&... args)
|
||||
-> format_to_n_result<OutputIt> {
|
||||
return vformat_to_n(out, n, detail::to_string_view(fmt),
|
||||
fmt::make_format_args<buffer_context<Char>>(args...));
|
||||
return vformat_to_n(out, n, fmt::basic_string_view<Char>(fmt),
|
||||
fmt::make_format_args<buffered_context<Char>>(args...));
|
||||
}
|
||||
|
||||
template <typename S, typename... T, typename Char = char_t<S>,
|
||||
template <typename S, typename... T,
|
||||
typename Char = detail::format_string_char_t<S>,
|
||||
FMT_ENABLE_IF(detail::is_exotic_char<Char>::value)>
|
||||
inline auto formatted_size(const S& fmt, T&&... args) -> size_t {
|
||||
auto buf = detail::counting_buffer<Char>();
|
||||
detail::vformat_to(buf, detail::to_string_view(fmt),
|
||||
fmt::make_format_args<buffer_context<Char>>(args...));
|
||||
fmt::make_format_args<buffered_context<Char>>(args...));
|
||||
return buf.count();
|
||||
}
|
||||
|
||||
@@ -247,9 +322,48 @@ template <typename... T> void println(wformat_string<T...> fmt, T&&... args) {
|
||||
return print(L"{}\n", fmt::format(fmt, std::forward<T>(args)...));
|
||||
}
|
||||
|
||||
/**
|
||||
Converts *value* to ``std::wstring`` using the default format for type *T*.
|
||||
*/
|
||||
inline auto vformat(const text_style& ts, wstring_view fmt, wformat_args args)
|
||||
-> std::wstring {
|
||||
auto buf = wmemory_buffer();
|
||||
detail::vformat_to(buf, ts, fmt, args);
|
||||
return {buf.data(), buf.size()};
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
inline auto format(const text_style& ts, wformat_string<T...> fmt, T&&... args)
|
||||
-> std::wstring {
|
||||
return fmt::vformat(ts, fmt, fmt::make_wformat_args(args...));
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
FMT_DEPRECATED void print(std::FILE* f, const text_style& ts,
|
||||
wformat_string<T...> fmt, const T&... args) {
|
||||
vprint(f, ts, fmt, fmt::make_wformat_args(args...));
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
FMT_DEPRECATED void print(const text_style& ts, wformat_string<T...> fmt,
|
||||
const T&... args) {
|
||||
return print(stdout, ts, fmt, args...);
|
||||
}
|
||||
|
||||
inline void vprint(std::wostream& os, wstring_view fmt, wformat_args args) {
|
||||
auto buffer = basic_memory_buffer<wchar_t>();
|
||||
detail::vformat_to(buffer, fmt, args);
|
||||
detail::write_buffer(os, buffer);
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
void print(std::wostream& os, wformat_string<T...> fmt, T&&... args) {
|
||||
vprint(os, fmt, fmt::make_format_args<buffered_context<wchar_t>>(args...));
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
void println(std::wostream& os, wformat_string<T...> fmt, T&&... args) {
|
||||
print(os, L"{}\n", fmt::format(fmt, std::forward<T>(args)...));
|
||||
}
|
||||
|
||||
/// Converts `value` to `std::wstring` using the default format for type `T`.
|
||||
template <typename T> inline auto to_wstring(const T& value) -> std::wstring {
|
||||
return format(FMT_STRING(L"{}"), value);
|
||||
}
|
||||
|
||||
107
3rdparty/fmt/src/fmt.cc
vendored
107
3rdparty/fmt/src/fmt.cc
vendored
@@ -1,38 +1,57 @@
|
||||
module;
|
||||
|
||||
#ifdef _MSVC_LANG
|
||||
# define FMT_CPLUSPLUS _MSVC_LANG
|
||||
#else
|
||||
# define FMT_CPLUSPLUS __cplusplus
|
||||
#endif
|
||||
|
||||
// Put all implementation-provided headers into the global module fragment
|
||||
// to prevent attachment to this module.
|
||||
#include <algorithm>
|
||||
#ifndef FMT_IMPORT_STD
|
||||
# include <algorithm>
|
||||
# include <bitset>
|
||||
# include <chrono>
|
||||
# include <cmath>
|
||||
# include <complex>
|
||||
# include <cstddef>
|
||||
# include <cstdint>
|
||||
# include <cstdio>
|
||||
# include <cstdlib>
|
||||
# include <cstring>
|
||||
# include <ctime>
|
||||
# include <exception>
|
||||
# if FMT_CPLUSPLUS > 202002L
|
||||
# include <expected>
|
||||
# endif
|
||||
# include <filesystem>
|
||||
# include <fstream>
|
||||
# include <functional>
|
||||
# include <iterator>
|
||||
# include <limits>
|
||||
# include <locale>
|
||||
# include <memory>
|
||||
# include <optional>
|
||||
# include <ostream>
|
||||
# include <source_location>
|
||||
# include <stdexcept>
|
||||
# include <string>
|
||||
# include <string_view>
|
||||
# include <system_error>
|
||||
# include <thread>
|
||||
# include <type_traits>
|
||||
# include <typeinfo>
|
||||
# include <utility>
|
||||
# include <variant>
|
||||
# include <vector>
|
||||
#else
|
||||
# include <limits.h>
|
||||
# include <stdint.h>
|
||||
# include <stdio.h>
|
||||
# include <time.h>
|
||||
#endif
|
||||
#include <cerrno>
|
||||
#include <chrono>
|
||||
#include <climits>
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <exception>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <locale>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <ostream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <system_error>
|
||||
#include <thread>
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
#include <version>
|
||||
|
||||
#if __has_include(<cxxabi.h>)
|
||||
@@ -70,6 +89,10 @@ module;
|
||||
|
||||
export module fmt;
|
||||
|
||||
#ifdef FMT_IMPORT_STD
|
||||
import std;
|
||||
#endif
|
||||
|
||||
#define FMT_EXPORT export
|
||||
#define FMT_BEGIN_EXPORT export {
|
||||
#define FMT_END_EXPORT }
|
||||
@@ -83,6 +106,10 @@ export module fmt;
|
||||
extern "C++" {
|
||||
#endif
|
||||
|
||||
#ifndef FMT_OS
|
||||
# define FMT_OS 1
|
||||
#endif
|
||||
|
||||
// All library-provided declarations and definitions must be in the module
|
||||
// purview to be exported.
|
||||
#include "fmt/args.h"
|
||||
@@ -90,8 +117,12 @@ extern "C++" {
|
||||
#include "fmt/color.h"
|
||||
#include "fmt/compile.h"
|
||||
#include "fmt/format.h"
|
||||
#include "fmt/os.h"
|
||||
#if FMT_OS
|
||||
# include "fmt/os.h"
|
||||
#endif
|
||||
#include "fmt/ostream.h"
|
||||
#include "fmt/printf.h"
|
||||
#include "fmt/ranges.h"
|
||||
#include "fmt/std.h"
|
||||
#include "fmt/xchar.h"
|
||||
|
||||
@@ -104,5 +135,17 @@ extern "C++" {
|
||||
module :private;
|
||||
#endif
|
||||
|
||||
#include "format.cc"
|
||||
#include "os.cc"
|
||||
#ifdef FMT_ATTACH_TO_GLOBAL_MODULE
|
||||
extern "C++" {
|
||||
#endif
|
||||
|
||||
#if FMT_HAS_INCLUDE("format.cc")
|
||||
# include "format.cc"
|
||||
#endif
|
||||
#if FMT_OS && FMT_HAS_INCLUDE("os.cc")
|
||||
# include "os.cc"
|
||||
#endif
|
||||
|
||||
#ifdef FMT_ATTACH_TO_GLOBAL_MODULE
|
||||
}
|
||||
#endif
|
||||
|
||||
5
3rdparty/fmt/src/format.cc
vendored
5
3rdparty/fmt/src/format.cc
vendored
@@ -15,7 +15,8 @@ template FMT_API auto dragonbox::to_decimal(float x) noexcept
|
||||
template FMT_API auto dragonbox::to_decimal(double x) noexcept
|
||||
-> dragonbox::decimal_fp<double>;
|
||||
|
||||
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
|
||||
#if FMT_USE_LOCALE
|
||||
// DEPRECATED! locale_ref in the detail namespace
|
||||
template FMT_API locale_ref::locale_ref(const std::locale& loc);
|
||||
template FMT_API auto locale_ref::get<std::locale>() const -> std::locale;
|
||||
#endif
|
||||
@@ -26,8 +27,10 @@ template FMT_API auto thousands_sep_impl(locale_ref)
|
||||
-> thousands_sep_result<char>;
|
||||
template FMT_API auto decimal_point_impl(locale_ref) -> char;
|
||||
|
||||
// DEPRECATED!
|
||||
template FMT_API void buffer<char>::append(const char*, const char*);
|
||||
|
||||
// DEPRECATED!
|
||||
template FMT_API void vformat_to(buffer<char>&, string_view,
|
||||
typename vformat_args<>::type, locale_ref);
|
||||
|
||||
|
||||
152
3rdparty/fmt/src/os.cc
vendored
152
3rdparty/fmt/src/os.cc
vendored
@@ -12,47 +12,51 @@
|
||||
|
||||
#include "fmt/os.h"
|
||||
|
||||
#include <climits>
|
||||
#ifndef FMT_MODULE
|
||||
# include <climits>
|
||||
|
||||
#if FMT_USE_FCNTL
|
||||
# include <sys/stat.h>
|
||||
# include <sys/types.h>
|
||||
# if FMT_USE_FCNTL
|
||||
# include <sys/stat.h>
|
||||
# include <sys/types.h>
|
||||
|
||||
# ifdef _WRS_KERNEL // VxWorks7 kernel
|
||||
# include <ioLib.h> // getpagesize
|
||||
# ifdef _WRS_KERNEL // VxWorks7 kernel
|
||||
# include <ioLib.h> // getpagesize
|
||||
# endif
|
||||
|
||||
# ifndef _WIN32
|
||||
# include <unistd.h>
|
||||
# else
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <io.h>
|
||||
# endif // _WIN32
|
||||
# endif // FMT_USE_FCNTL
|
||||
|
||||
# ifdef _WIN32
|
||||
# include <windows.h>
|
||||
# endif
|
||||
|
||||
# ifndef _WIN32
|
||||
# include <unistd.h>
|
||||
# else
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <io.h>
|
||||
|
||||
# ifndef S_IRUSR
|
||||
# define S_IRUSR _S_IREAD
|
||||
# endif
|
||||
# ifndef S_IWUSR
|
||||
# define S_IWUSR _S_IWRITE
|
||||
# endif
|
||||
# ifndef S_IRGRP
|
||||
# define S_IRGRP 0
|
||||
# endif
|
||||
# ifndef S_IWGRP
|
||||
# define S_IWGRP 0
|
||||
# endif
|
||||
# ifndef S_IROTH
|
||||
# define S_IROTH 0
|
||||
# endif
|
||||
# ifndef S_IWOTH
|
||||
# define S_IWOTH 0
|
||||
# endif
|
||||
# endif // _WIN32
|
||||
#endif // FMT_USE_FCNTL
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
# ifndef S_IRUSR
|
||||
# define S_IRUSR _S_IREAD
|
||||
# endif
|
||||
# ifndef S_IWUSR
|
||||
# define S_IWUSR _S_IWRITE
|
||||
# endif
|
||||
# ifndef S_IRGRP
|
||||
# define S_IRGRP 0
|
||||
# endif
|
||||
# ifndef S_IWGRP
|
||||
# define S_IWGRP 0
|
||||
# endif
|
||||
# ifndef S_IROTH
|
||||
# define S_IROTH 0
|
||||
# endif
|
||||
# ifndef S_IWOTH
|
||||
# define S_IWOTH 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
@@ -156,7 +160,7 @@ void detail::format_windows_error(detail::buffer<char>& out, int error_code,
|
||||
}
|
||||
|
||||
void report_windows_error(int error_code, const char* message) noexcept {
|
||||
report_error(detail::format_windows_error, error_code, message);
|
||||
do_report_error(detail::format_windows_error, error_code, message);
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
@@ -182,12 +186,14 @@ void buffered_file::close() {
|
||||
}
|
||||
|
||||
int buffered_file::descriptor() const {
|
||||
#if !defined(fileno)
|
||||
#ifdef FMT_HAS_SYSTEM
|
||||
// fileno is a macro on OpenBSD.
|
||||
# ifdef fileno
|
||||
# undef fileno
|
||||
# endif
|
||||
int fd = FMT_POSIX_CALL(fileno(file_));
|
||||
#elif defined(FMT_HAS_SYSTEM)
|
||||
// fileno is a macro on OpenBSD so we cannot use FMT_POSIX_CALL.
|
||||
# define FMT_DISABLE_MACRO
|
||||
int fd = FMT_SYSTEM(fileno FMT_DISABLE_MACRO(file_));
|
||||
#elif defined(_WIN32)
|
||||
int fd = _fileno(file_);
|
||||
#else
|
||||
int fd = fileno(file_);
|
||||
#endif
|
||||
@@ -200,6 +206,7 @@ int buffered_file::descriptor() const {
|
||||
# ifdef _WIN32
|
||||
using mode_t = int;
|
||||
# endif
|
||||
|
||||
constexpr mode_t default_open_mode =
|
||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
|
||||
|
||||
@@ -301,29 +308,6 @@ void file::dup2(int fd, std::error_code& ec) noexcept {
|
||||
if (result == -1) ec = std::error_code(errno, std::generic_category());
|
||||
}
|
||||
|
||||
void file::pipe(file& read_end, file& write_end) {
|
||||
// Close the descriptors first to make sure that assignments don't throw
|
||||
// and there are no leaks.
|
||||
read_end.close();
|
||||
write_end.close();
|
||||
int fds[2] = {};
|
||||
# ifdef _WIN32
|
||||
// Make the default pipe capacity same as on Linux 2.6.11+.
|
||||
enum { DEFAULT_CAPACITY = 65536 };
|
||||
int result = FMT_POSIX_CALL(pipe(fds, DEFAULT_CAPACITY, _O_BINARY));
|
||||
# else
|
||||
// Don't retry as the pipe function doesn't return EINTR.
|
||||
// http://pubs.opengroup.org/onlinepubs/009696799/functions/pipe.html
|
||||
int result = FMT_POSIX_CALL(pipe(fds));
|
||||
# endif
|
||||
if (result != 0)
|
||||
FMT_THROW(system_error(errno, FMT_STRING("cannot create pipe")));
|
||||
// The following assignments don't throw because read_fd and write_fd
|
||||
// are closed.
|
||||
read_end = file(fds[0]);
|
||||
write_end = file(fds[1]);
|
||||
}
|
||||
|
||||
buffered_file file::fdopen(const char* mode) {
|
||||
// Don't retry as fdopen doesn't return EINTR.
|
||||
# if defined(__MINGW32__) && defined(_POSIX_)
|
||||
@@ -352,6 +336,24 @@ file file::open_windows_file(wcstring_view path, int oflag) {
|
||||
}
|
||||
# endif
|
||||
|
||||
pipe::pipe() {
|
||||
int fds[2] = {};
|
||||
# ifdef _WIN32
|
||||
// Make the default pipe capacity same as on Linux 2.6.11+.
|
||||
enum { DEFAULT_CAPACITY = 65536 };
|
||||
int result = FMT_POSIX_CALL(pipe(fds, DEFAULT_CAPACITY, _O_BINARY));
|
||||
# else
|
||||
// Don't retry as the pipe function doesn't return EINTR.
|
||||
// http://pubs.opengroup.org/onlinepubs/009696799/functions/pipe.html
|
||||
int result = FMT_POSIX_CALL(pipe(fds));
|
||||
# endif
|
||||
if (result != 0)
|
||||
FMT_THROW(system_error(errno, FMT_STRING("cannot create pipe")));
|
||||
// The following assignments don't throw.
|
||||
read_end = file(fds[0]);
|
||||
write_end = file(fds[1]);
|
||||
}
|
||||
|
||||
# if !defined(__MSDOS__)
|
||||
long getpagesize() {
|
||||
# ifdef _WIN32
|
||||
@@ -372,31 +374,25 @@ long getpagesize() {
|
||||
}
|
||||
# endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
void file_buffer::grow(size_t) {
|
||||
if (this->size() == this->capacity()) flush();
|
||||
void ostream::grow(buffer<char>& buf, size_t) {
|
||||
if (buf.size() == buf.capacity()) static_cast<ostream&>(buf).flush();
|
||||
}
|
||||
|
||||
file_buffer::file_buffer(cstring_view path,
|
||||
const detail::ostream_params& params)
|
||||
: file_(path, params.oflag) {
|
||||
ostream::ostream(cstring_view path, const detail::ostream_params& params)
|
||||
: buffer<char>(grow), file_(path, params.oflag) {
|
||||
set(new char[params.buffer_size], params.buffer_size);
|
||||
}
|
||||
|
||||
file_buffer::file_buffer(file_buffer&& other)
|
||||
: detail::buffer<char>(other.data(), other.size(), other.capacity()),
|
||||
ostream::ostream(ostream&& other) noexcept
|
||||
: buffer<char>(grow, other.data(), other.size(), other.capacity()),
|
||||
file_(std::move(other.file_)) {
|
||||
other.clear();
|
||||
other.set(nullptr, 0);
|
||||
}
|
||||
|
||||
file_buffer::~file_buffer() {
|
||||
ostream::~ostream() {
|
||||
flush();
|
||||
delete[] data();
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
ostream::~ostream() = default;
|
||||
#endif // FMT_USE_FCNTL
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
18
3rdparty/imgui/include/imconfig.h
vendored
18
3rdparty/imgui/include/imconfig.h
vendored
@@ -29,7 +29,6 @@
|
||||
|
||||
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names.
|
||||
#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
//#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87+ disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This is automatically done by IMGUI_DISABLE_OBSOLETE_FUNCTIONS.
|
||||
|
||||
//---- Disable all of Dear ImGui or don't implement standard windows/tools.
|
||||
// It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp.
|
||||
@@ -43,12 +42,13 @@
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a)
|
||||
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, IME).
|
||||
//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default).
|
||||
//#define IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS // Don't implement default io.PlatformOpenInShellFn() handler (Win32: ShellExecute(), require shell32.lib/.a, Mac/Linux: use system("")).
|
||||
//#define IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS // Don't implement default platform_io.Platform_OpenInShellFn() handler (Win32: ShellExecute(), require shell32.lib/.a, Mac/Linux: use system("")).
|
||||
//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf)
|
||||
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
|
||||
//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
|
||||
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
|
||||
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
|
||||
//#define IMGUI_DISABLE_DEFAULT_FONT // Disable default embedded font (ProggyClean.ttf), remove ~9.5 KB from output binary. AddFontDefault() will assert.
|
||||
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
|
||||
|
||||
//---- Enable Test Engine / Automation features.
|
||||
@@ -59,9 +59,12 @@
|
||||
//#define IMGUI_INCLUDE_IMGUI_USER_H
|
||||
//#define IMGUI_USER_H_FILENAME "my_folder/my_imgui_user.h"
|
||||
|
||||
//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
|
||||
//---- Pack vertex colors as BGRA8 instead of RGBA8 (to avoid converting from one to another). Need dedicated backend support.
|
||||
//#define IMGUI_USE_BGRA_PACKED_COLOR
|
||||
|
||||
//---- Use legacy CRC32-adler tables (used before 1.91.6), in order to preserve old .ini data that you cannot afford to invalidate.
|
||||
//#define IMGUI_USE_LEGACY_CRC32_ADLER
|
||||
|
||||
//---- Use 32-bit for ImWchar (default is 16-bit) to support Unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
|
||||
//#define IMGUI_USE_WCHAR32
|
||||
|
||||
@@ -83,10 +86,13 @@
|
||||
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
|
||||
#define IMGUI_ENABLE_FREETYPE
|
||||
|
||||
//---- Use FreeType+lunasvg library to render OpenType SVG fonts (SVGinOT)
|
||||
// Requires lunasvg headers to be available in the include path + program to be linked with the lunasvg library (not provided).
|
||||
//---- Use FreeType + plutosvg or lunasvg to render OpenType SVG fonts (SVGinOT)
|
||||
// Only works in combination with IMGUI_ENABLE_FREETYPE.
|
||||
// (implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement)
|
||||
// - lunasvg is currently easier to acquire/install, as e.g. it is part of vcpkg.
|
||||
// - plutosvg will support more fonts and may load them faster. It currently requires to be built manually but it is fairly easy. See misc/freetype/README for instructions.
|
||||
// - Both require headers to be available in the include path + program to be linked with the library code (not provided).
|
||||
// - (note: lunasvg implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement)
|
||||
//#define IMGUI_ENABLE_FREETYPE_PLUTOSVG
|
||||
//#define IMGUI_ENABLE_FREETYPE_LUNASVG
|
||||
|
||||
//---- Use stb_truetype to build and rasterize the font atlas (default)
|
||||
|
||||
516
3rdparty/imgui/include/imgui.h
vendored
516
3rdparty/imgui/include/imgui.h
vendored
File diff suppressed because it is too large
Load Diff
7
3rdparty/imgui/include/imgui_freetype.h
vendored
7
3rdparty/imgui/include/imgui_freetype.h
vendored
@@ -5,6 +5,13 @@
|
||||
#include "imgui.h" // IMGUI_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
// Usage:
|
||||
// - Add '#define IMGUI_ENABLE_FREETYPE' in your imconfig to enable support for imgui_freetype in imgui.
|
||||
|
||||
// Optional support for OpenType SVG fonts:
|
||||
// - Add '#define IMGUI_ENABLE_FREETYPE_PLUTOSVG' to use plutosvg (not provided). See #7927.
|
||||
// - Add '#define IMGUI_ENABLE_FREETYPE_LUNASVG' to use lunasvg (not provided). See #6591.
|
||||
|
||||
// Forward declarations
|
||||
struct ImFontAtlas;
|
||||
struct ImFontBuilderIO;
|
||||
|
||||
660
3rdparty/imgui/include/imgui_internal.h
vendored
660
3rdparty/imgui/include/imgui_internal.h
vendored
File diff suppressed because it is too large
Load Diff
4
3rdparty/imgui/include/imgui_stdlib.h
vendored
4
3rdparty/imgui/include/imgui_stdlib.h
vendored
@@ -9,6 +9,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace ImGui
|
||||
@@ -19,3 +21,5 @@ namespace ImGui
|
||||
IMGUI_API bool InputTextMultiline(const char* label, std::string* str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = nullptr, void* user_data = nullptr);
|
||||
IMGUI_API bool InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = nullptr, void* user_data = nullptr);
|
||||
}
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
98
3rdparty/imgui/include/imstb_textedit.h
vendored
98
3rdparty/imgui/include/imstb_textedit.h
vendored
@@ -3,6 +3,8 @@
|
||||
// Those changes would need to be pushed into nothings/stb:
|
||||
// - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321)
|
||||
// - Fix in stb_textedit_find_charpos to handle last line (see https://github.com/ocornut/imgui/issues/6000 + #6783)
|
||||
// - Added name to struct or it may be forward declared in our code.
|
||||
// - Added UTF-8 support (see https://github.com/nothings/stb/issues/188 + https://github.com/ocornut/imgui/pull/7925)
|
||||
// Grep for [DEAR IMGUI] to find the changes.
|
||||
// - Also renamed macros used or defined outside of IMSTB_TEXTEDIT_IMPLEMENTATION block from STB_TEXTEDIT_* to IMSTB_TEXTEDIT_*
|
||||
|
||||
@@ -209,6 +211,7 @@
|
||||
// int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
// int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len)
|
||||
// void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXEDIT_KEYTYPE key)
|
||||
// void stb_textedit_text(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int text_len)
|
||||
//
|
||||
// Each of these functions potentially updates the string and updates the
|
||||
// state.
|
||||
@@ -243,7 +246,12 @@
|
||||
// various definitions like STB_TEXTEDIT_K_LEFT have the is-key-event bit
|
||||
// set, and make STB_TEXTEDIT_KEYTOCHAR check that the is-key-event bit is
|
||||
// clear. STB_TEXTEDIT_KEYTYPE defaults to int, but you can #define it to
|
||||
// anything other type you wante before including.
|
||||
// anything other type you want before including.
|
||||
// if the STB_TEXTEDIT_KEYTOTEXT function is defined, selected keys are
|
||||
// transformed into text and stb_textedit_text() is automatically called.
|
||||
//
|
||||
// text: [DEAR IMGUI] added 2024-09
|
||||
// call this to text inputs sent to the textfield.
|
||||
//
|
||||
//
|
||||
// When rendering, you can read the cursor position and selection state from
|
||||
@@ -318,7 +326,7 @@ typedef struct
|
||||
int undo_char_point, redo_char_point;
|
||||
} StbUndoState;
|
||||
|
||||
typedef struct
|
||||
typedef struct STB_TexteditState
|
||||
{
|
||||
/////////////////////
|
||||
//
|
||||
@@ -438,13 +446,13 @@ static int stb_text_locate_coord(IMSTB_TEXTEDIT_STRING *str, float x, float y)
|
||||
if (x < r.x1) {
|
||||
// search characters in row for one that straddles 'x'
|
||||
prev_x = r.x0;
|
||||
for (k=0; k < r.num_chars; ++k) {
|
||||
for (k=0; k < r.num_chars; k = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, i + k) - i) {
|
||||
float w = STB_TEXTEDIT_GETWIDTH(str, i, k);
|
||||
if (x < prev_x+w) {
|
||||
if (x < prev_x+w/2)
|
||||
return k+i;
|
||||
else
|
||||
return k+i+1;
|
||||
return IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, i + k);
|
||||
}
|
||||
prev_x += w;
|
||||
}
|
||||
@@ -563,7 +571,7 @@ static void stb_textedit_find_charpos(StbFindState *find, IMSTB_TEXTEDIT_STRING
|
||||
|
||||
// now scan to find xpos
|
||||
find->x = r.x0;
|
||||
for (i=0; first+i < n; ++i)
|
||||
for (i=0; first+i < n; i = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, first + i) - first)
|
||||
find->x += STB_TEXTEDIT_GETWIDTH(str, first, i);
|
||||
}
|
||||
|
||||
@@ -640,6 +648,17 @@ static void stb_textedit_move_to_last(IMSTB_TEXTEDIT_STRING *str, STB_TexteditSt
|
||||
}
|
||||
}
|
||||
|
||||
// [DEAR IMGUI]
|
||||
// Functions must be implemented for UTF8 support
|
||||
// Code in this file that uses those functions is modified for [DEAR IMGUI] and deviates from the original stb_textedit.
|
||||
// There is not necessarily a '[DEAR IMGUI]' at the usage sites.
|
||||
#ifndef IMSTB_TEXTEDIT_GETPREVCHARINDEX
|
||||
#define IMSTB_TEXTEDIT_GETPREVCHARINDEX(obj, idx) (idx - 1)
|
||||
#endif
|
||||
#ifndef IMSTB_TEXTEDIT_GETNEXTCHARINDEX
|
||||
#define IMSTB_TEXTEDIT_GETNEXTCHARINDEX(obj, idx) (idx + 1)
|
||||
#endif
|
||||
|
||||
#ifdef STB_TEXTEDIT_IS_SPACE
|
||||
static int is_word_boundary( IMSTB_TEXTEDIT_STRING *str, int idx )
|
||||
{
|
||||
@@ -720,36 +739,44 @@ static int stb_textedit_paste_internal(IMSTB_TEXTEDIT_STRING *str, STB_TexteditS
|
||||
#define STB_TEXTEDIT_KEYTYPE int
|
||||
#endif
|
||||
|
||||
// [DEAR IMGUI] Added stb_textedit_text(), extracted out and called by stb_textedit_key() for backward compatibility.
|
||||
static void stb_textedit_text(IMSTB_TEXTEDIT_STRING* str, STB_TexteditState* state, const IMSTB_TEXTEDIT_CHARTYPE* text, int text_len)
|
||||
{
|
||||
// can't add newline in single-line mode
|
||||
if (text[0] == '\n' && state->single_line)
|
||||
return;
|
||||
|
||||
if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)) {
|
||||
stb_text_makeundo_replace(str, state, state->cursor, 1, 1);
|
||||
STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1);
|
||||
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, text_len)) {
|
||||
state->cursor += text_len;
|
||||
state->has_preferred_x = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
stb_textedit_delete_selection(str, state); // implicitly clamps
|
||||
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, text_len)) {
|
||||
stb_text_makeundo_insert(state, state->cursor, text_len);
|
||||
state->cursor += text_len;
|
||||
state->has_preferred_x = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// API key: process a keyboard input
|
||||
static void stb_textedit_key(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_KEYTYPE key)
|
||||
{
|
||||
retry:
|
||||
switch (key) {
|
||||
default: {
|
||||
#ifdef STB_TEXTEDIT_KEYTOTEXT
|
||||
int c = STB_TEXTEDIT_KEYTOTEXT(key);
|
||||
if (c > 0) {
|
||||
IMSTB_TEXTEDIT_CHARTYPE ch = (IMSTB_TEXTEDIT_CHARTYPE) c;
|
||||
|
||||
// can't add newline in single-line mode
|
||||
if (c == '\n' && state->single_line)
|
||||
break;
|
||||
|
||||
if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)) {
|
||||
stb_text_makeundo_replace(str, state, state->cursor, 1, 1);
|
||||
STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1);
|
||||
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) {
|
||||
++state->cursor;
|
||||
state->has_preferred_x = 0;
|
||||
}
|
||||
} else {
|
||||
stb_textedit_delete_selection(str,state); // implicitly clamps
|
||||
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) {
|
||||
stb_text_makeundo_insert(state, state->cursor, 1);
|
||||
++state->cursor;
|
||||
state->has_preferred_x = 0;
|
||||
}
|
||||
}
|
||||
IMSTB_TEXTEDIT_CHARTYPE ch = (IMSTB_TEXTEDIT_CHARTYPE)c;
|
||||
stb_textedit_text(str, state, &ch, 1);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -775,7 +802,7 @@ retry:
|
||||
stb_textedit_move_to_first(state);
|
||||
else
|
||||
if (state->cursor > 0)
|
||||
--state->cursor;
|
||||
state->cursor = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, state->cursor);
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
|
||||
@@ -784,7 +811,7 @@ retry:
|
||||
if (STB_TEXT_HAS_SELECTION(state))
|
||||
stb_textedit_move_to_last(str, state);
|
||||
else
|
||||
++state->cursor;
|
||||
state->cursor = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor);
|
||||
stb_textedit_clamp(str, state);
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
@@ -794,7 +821,7 @@ retry:
|
||||
stb_textedit_prep_selection_at_cursor(state);
|
||||
// move selection left
|
||||
if (state->select_end > 0)
|
||||
--state->select_end;
|
||||
state->select_end = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, state->select_end);
|
||||
state->cursor = state->select_end;
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
@@ -844,7 +871,7 @@ retry:
|
||||
case STB_TEXTEDIT_K_RIGHT | STB_TEXTEDIT_K_SHIFT:
|
||||
stb_textedit_prep_selection_at_cursor(state);
|
||||
// move selection right
|
||||
++state->select_end;
|
||||
state->select_end = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->select_end);
|
||||
stb_textedit_clamp(str, state);
|
||||
state->cursor = state->select_end;
|
||||
state->has_preferred_x = 0;
|
||||
@@ -900,7 +927,7 @@ retry:
|
||||
x += dx;
|
||||
if (x > goal_x)
|
||||
break;
|
||||
++state->cursor;
|
||||
state->cursor = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor);
|
||||
}
|
||||
stb_textedit_clamp(str, state);
|
||||
|
||||
@@ -962,7 +989,7 @@ retry:
|
||||
x += dx;
|
||||
if (x > goal_x)
|
||||
break;
|
||||
++state->cursor;
|
||||
state->cursor = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor);
|
||||
}
|
||||
stb_textedit_clamp(str, state);
|
||||
|
||||
@@ -990,7 +1017,7 @@ retry:
|
||||
else {
|
||||
int n = STB_TEXTEDIT_STRINGLEN(str);
|
||||
if (state->cursor < n)
|
||||
stb_textedit_delete(str, state, state->cursor, 1);
|
||||
stb_textedit_delete(str, state, state->cursor, IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor) - state->cursor);
|
||||
}
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
@@ -1002,8 +1029,9 @@ retry:
|
||||
else {
|
||||
stb_textedit_clamp(str, state);
|
||||
if (state->cursor > 0) {
|
||||
stb_textedit_delete(str, state, state->cursor-1, 1);
|
||||
--state->cursor;
|
||||
int prev = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, state->cursor);
|
||||
stb_textedit_delete(str, state, prev, state->cursor - prev);
|
||||
state->cursor = prev;
|
||||
}
|
||||
}
|
||||
state->has_preferred_x = 0;
|
||||
|
||||
2746
3rdparty/imgui/src/imgui.cpp
vendored
2746
3rdparty/imgui/src/imgui.cpp
vendored
File diff suppressed because it is too large
Load Diff
364
3rdparty/imgui/src/imgui_demo.cpp
vendored
364
3rdparty/imgui/src/imgui_demo.cpp
vendored
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.91.0
|
||||
// dear imgui, v1.91.8
|
||||
// (demo code)
|
||||
|
||||
// Help:
|
||||
@@ -116,6 +116,9 @@ Index of this file:
|
||||
#if !defined(_MSC_VER) || _MSC_VER >= 1800
|
||||
#include <inttypes.h> // PRId64/PRIu64, not avail in some MinGW headers.
|
||||
#endif
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten/version.h> // __EMSCRIPTEN_major__ etc.
|
||||
#endif
|
||||
|
||||
// Visual Studio warnings
|
||||
#ifdef _MSC_VER
|
||||
@@ -142,12 +145,16 @@ Index of this file:
|
||||
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
|
||||
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size
|
||||
#pragma GCC diagnostic ignored "-Wformat-security" // warning: format string is not a string literal (potentially insecure)
|
||||
#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function
|
||||
#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value
|
||||
#pragma GCC diagnostic ignored "-Wmisleading-indentation" // [__GNUC__ >= 6] warning: this 'if' clause does not guard this statement // GCC 6.0+ only. See #883 on GitHub.
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
|
||||
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size
|
||||
#pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'int'/'void*', but argument X has type 'unsigned int'/'ImGuiWindow*'
|
||||
#pragma GCC diagnostic ignored "-Wformat-security" // warning: format string is not a string literal (potentially insecure)
|
||||
#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function
|
||||
#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value
|
||||
#pragma GCC diagnostic ignored "-Wmisleading-indentation" // [__GNUC__ >= 6] warning: this 'if' clause does not guard this statement // GCC 6.0+ only. See #883 on GitHub.
|
||||
#pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when simplifying division / ..when changing X +- C1 cmp C2 to X cmp C2 -+ C1
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers
|
||||
#endif
|
||||
|
||||
// Play it nice with Windows users (Update: May 2018, Notepad now supports Unix-style carriage returns!)
|
||||
@@ -288,6 +295,7 @@ struct ExampleMemberInfo
|
||||
// Metadata description of ExampleTreeNode struct.
|
||||
static const ExampleMemberInfo ExampleTreeNodeMemberInfos[]
|
||||
{
|
||||
{ "MyName", ImGuiDataType_String, 1, offsetof(ExampleTreeNode, Name) },
|
||||
{ "MyBool", ImGuiDataType_Bool, 1, offsetof(ExampleTreeNode, DataMyBool) },
|
||||
{ "MyInt", ImGuiDataType_S32, 1, offsetof(ExampleTreeNode, DataMyInt) },
|
||||
{ "MyVec2", ImGuiDataType_Float, 2, offsetof(ExampleTreeNode, DataMyVec2) },
|
||||
@@ -305,28 +313,36 @@ static ExampleTreeNode* ExampleTree_CreateNode(const char* name, int uid, Exampl
|
||||
return node;
|
||||
}
|
||||
|
||||
static void ExampleTree_DestroyNode(ExampleTreeNode* node)
|
||||
{
|
||||
for (ExampleTreeNode* child_node : node->Childs)
|
||||
ExampleTree_DestroyNode(child_node);
|
||||
IM_DELETE(node);
|
||||
}
|
||||
|
||||
// Create example tree data
|
||||
// (this allocates _many_ more times than most other code in either Dear ImGui or others demo)
|
||||
static ExampleTreeNode* ExampleTree_CreateDemoTree()
|
||||
{
|
||||
static const char* root_names[] = { "Apple", "Banana", "Cherry", "Kiwi", "Mango", "Orange", "Pear", "Pineapple", "Strawberry", "Watermelon" };
|
||||
char name_buf[32];
|
||||
const size_t NAME_MAX_LEN = sizeof(ExampleTreeNode::Name);
|
||||
char name_buf[NAME_MAX_LEN];
|
||||
int uid = 0;
|
||||
ExampleTreeNode* node_L0 = ExampleTree_CreateNode("<ROOT>", ++uid, NULL);
|
||||
const int root_items_multiplier = 2;
|
||||
for (int idx_L0 = 0; idx_L0 < IM_ARRAYSIZE(root_names) * root_items_multiplier; idx_L0++)
|
||||
{
|
||||
snprintf(name_buf, 32, "%s %d", root_names[idx_L0 / root_items_multiplier], idx_L0 % root_items_multiplier);
|
||||
snprintf(name_buf, IM_ARRAYSIZE(name_buf), "%s %d", root_names[idx_L0 / root_items_multiplier], idx_L0 % root_items_multiplier);
|
||||
ExampleTreeNode* node_L1 = ExampleTree_CreateNode(name_buf, ++uid, node_L0);
|
||||
const int number_of_childs = (int)strlen(node_L1->Name);
|
||||
for (int idx_L1 = 0; idx_L1 < number_of_childs; idx_L1++)
|
||||
{
|
||||
snprintf(name_buf, 32, "Child %d", idx_L1);
|
||||
snprintf(name_buf, IM_ARRAYSIZE(name_buf), "Child %d", idx_L1);
|
||||
ExampleTreeNode* node_L2 = ExampleTree_CreateNode(name_buf, ++uid, node_L1);
|
||||
node_L2->HasData = true;
|
||||
if (idx_L1 == 0)
|
||||
{
|
||||
snprintf(name_buf, 32, "Sub-child %d", 0);
|
||||
snprintf(name_buf, IM_ARRAYSIZE(name_buf), "Sub-child %d", 0);
|
||||
ExampleTreeNode* node_L3 = ExampleTree_CreateNode(name_buf, ++uid, node_L2);
|
||||
node_L3->HasData = true;
|
||||
}
|
||||
@@ -339,7 +355,7 @@ static ExampleTreeNode* ExampleTree_CreateDemoTree()
|
||||
// [SECTION] Demo Window / ShowDemoWindow()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Data to be shared accross different functions of the demo.
|
||||
// Data to be shared across different functions of the demo.
|
||||
struct ImGuiDemoWindowData
|
||||
{
|
||||
// Examples Apps (accessible from the "Examples" menu)
|
||||
@@ -367,6 +383,8 @@ struct ImGuiDemoWindowData
|
||||
|
||||
// Other data
|
||||
ExampleTreeNode* DemoTree = NULL;
|
||||
|
||||
~ImGuiDemoWindowData() { if (DemoTree) ExampleTree_DestroyNode(DemoTree); }
|
||||
};
|
||||
|
||||
// Demonstrate most Dear ImGui features (this is big function!)
|
||||
@@ -497,8 +515,6 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
ImGui::SameLine(); HelpMarker("Enable keyboard controls.");
|
||||
ImGui::CheckboxFlags("io.ConfigFlags: NavEnableGamepad", &io.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad);
|
||||
ImGui::SameLine(); HelpMarker("Enable gamepad controls. Require backend to set io.BackendFlags |= ImGuiBackendFlags_HasGamepad.\n\nRead instructions in imgui.cpp for details.");
|
||||
ImGui::CheckboxFlags("io.ConfigFlags: NavEnableSetMousePos", &io.ConfigFlags, ImGuiConfigFlags_NavEnableSetMousePos);
|
||||
ImGui::SameLine(); HelpMarker("Instruct navigation to move the mouse cursor. See comment for ImGuiConfigFlags_NavEnableSetMousePos.");
|
||||
ImGui::CheckboxFlags("io.ConfigFlags: NoMouse", &io.ConfigFlags, ImGuiConfigFlags_NoMouse);
|
||||
ImGui::SameLine(); HelpMarker("Instruct dear imgui to disable mouse inputs and interactions.");
|
||||
|
||||
@@ -525,6 +541,29 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
ImGui::Checkbox("io.MouseDrawCursor", &io.MouseDrawCursor);
|
||||
ImGui::SameLine(); HelpMarker("Instruct Dear ImGui to render a mouse cursor itself. Note that a mouse cursor rendered via your application GPU rendering path will feel more laggy than hardware cursor, but will be more in sync with your other visuals.\n\nSome desktop applications may use both kinds of cursors (e.g. enable software cursor only when resizing/dragging something).");
|
||||
|
||||
ImGui::SeparatorText("Keyboard/Gamepad Navigation");
|
||||
ImGui::Checkbox("io.ConfigNavSwapGamepadButtons", &io.ConfigNavSwapGamepadButtons);
|
||||
ImGui::Checkbox("io.ConfigNavMoveSetMousePos", &io.ConfigNavMoveSetMousePos);
|
||||
ImGui::SameLine(); HelpMarker("Directional/tabbing navigation teleports the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is difficult");
|
||||
ImGui::Checkbox("io.ConfigNavCaptureKeyboard", &io.ConfigNavCaptureKeyboard);
|
||||
ImGui::Checkbox("io.ConfigNavEscapeClearFocusItem", &io.ConfigNavEscapeClearFocusItem);
|
||||
ImGui::SameLine(); HelpMarker("Pressing Escape clears focused item.");
|
||||
ImGui::Checkbox("io.ConfigNavEscapeClearFocusWindow", &io.ConfigNavEscapeClearFocusWindow);
|
||||
ImGui::SameLine(); HelpMarker("Pressing Escape clears focused window.");
|
||||
ImGui::Checkbox("io.ConfigNavCursorVisibleAuto", &io.ConfigNavCursorVisibleAuto);
|
||||
ImGui::SameLine(); HelpMarker("Using directional navigation key makes the cursor visible. Mouse click hides the cursor.");
|
||||
ImGui::Checkbox("io.ConfigNavCursorVisibleAlways", &io.ConfigNavCursorVisibleAlways);
|
||||
ImGui::SameLine(); HelpMarker("Navigation cursor is always visible.");
|
||||
|
||||
ImGui::SeparatorText("Windows");
|
||||
ImGui::Checkbox("io.ConfigWindowsResizeFromEdges", &io.ConfigWindowsResizeFromEdges);
|
||||
ImGui::SameLine(); HelpMarker("Enable resizing of windows from their edges and from the lower-left corner.\nThis requires ImGuiBackendFlags_HasMouseCursors for better mouse cursor feedback.");
|
||||
ImGui::Checkbox("io.ConfigWindowsMoveFromTitleBarOnly", &io.ConfigWindowsMoveFromTitleBarOnly);
|
||||
ImGui::Checkbox("io.ConfigWindowsCopyContentsWithCtrlC", &io.ConfigWindowsCopyContentsWithCtrlC); // [EXPERIMENTAL]
|
||||
ImGui::SameLine(); HelpMarker("*EXPERIMENTAL* CTRL+C copy the contents of focused window into the clipboard.\n\nExperimental because:\n- (1) has known issues with nested Begin/End pairs.\n- (2) text output quality varies.\n- (3) text output is in submission order rather than spatial order.");
|
||||
ImGui::Checkbox("io.ConfigScrollbarScrollByPage", &io.ConfigScrollbarScrollByPage);
|
||||
ImGui::SameLine(); HelpMarker("Enable scrolling page by page when clicking outside the scrollbar grab.\nWhen disabled, always scroll to clicked location.\nWhen enabled, Shift+Click scrolls to clicked location.");
|
||||
|
||||
ImGui::SeparatorText("Widgets");
|
||||
ImGui::Checkbox("io.ConfigInputTextCursorBlink", &io.ConfigInputTextCursorBlink);
|
||||
ImGui::SameLine(); HelpMarker("Enable blinking cursor (optional as some users consider it to be distracting).");
|
||||
@@ -532,18 +571,35 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
ImGui::SameLine(); HelpMarker("Pressing Enter will keep item active and select contents (single-line only).");
|
||||
ImGui::Checkbox("io.ConfigDragClickToInputText", &io.ConfigDragClickToInputText);
|
||||
ImGui::SameLine(); HelpMarker("Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving).");
|
||||
ImGui::Checkbox("io.ConfigWindowsResizeFromEdges", &io.ConfigWindowsResizeFromEdges);
|
||||
ImGui::SameLine(); HelpMarker("Enable resizing of windows from their edges and from the lower-left corner.\nThis requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback.");
|
||||
ImGui::Checkbox("io.ConfigWindowsMoveFromTitleBarOnly", &io.ConfigWindowsMoveFromTitleBarOnly);
|
||||
ImGui::Checkbox("io.ConfigMacOSXBehaviors", &io.ConfigMacOSXBehaviors);
|
||||
ImGui::SameLine(); HelpMarker("Swap Cmd<>Ctrl keys, enable various MacOS style behaviors.");
|
||||
ImGui::Text("Also see Style->Rendering for rendering options.");
|
||||
|
||||
// Also read: https://github.com/ocornut/imgui/wiki/Error-Handling
|
||||
ImGui::SeparatorText("Error Handling");
|
||||
|
||||
ImGui::Checkbox("io.ConfigErrorRecovery", &io.ConfigErrorRecovery);
|
||||
ImGui::SameLine(); HelpMarker(
|
||||
"Options to configure how we handle recoverable errors.\n"
|
||||
"- Error recovery is not perfect nor guaranteed! It is a feature to ease development.\n"
|
||||
"- You not are not supposed to rely on it in the course of a normal application run.\n"
|
||||
"- Possible usage: facilitate recovery from errors triggered from a scripting language or after specific exceptions handlers.\n"
|
||||
"- Always ensure that on programmers seat you have at minimum Asserts or Tooltips enabled when making direct imgui API call!"
|
||||
"Otherwise it would severely hinder your ability to catch and correct mistakes!");
|
||||
ImGui::Checkbox("io.ConfigErrorRecoveryEnableAssert", &io.ConfigErrorRecoveryEnableAssert);
|
||||
ImGui::Checkbox("io.ConfigErrorRecoveryEnableDebugLog", &io.ConfigErrorRecoveryEnableDebugLog);
|
||||
ImGui::Checkbox("io.ConfigErrorRecoveryEnableTooltip", &io.ConfigErrorRecoveryEnableTooltip);
|
||||
if (!io.ConfigErrorRecoveryEnableAssert && !io.ConfigErrorRecoveryEnableDebugLog && !io.ConfigErrorRecoveryEnableTooltip)
|
||||
io.ConfigErrorRecoveryEnableAssert = io.ConfigErrorRecoveryEnableDebugLog = io.ConfigErrorRecoveryEnableTooltip = true;
|
||||
|
||||
// Also read: https://github.com/ocornut/imgui/wiki/Debug-Tools
|
||||
ImGui::SeparatorText("Debug");
|
||||
ImGui::Checkbox("io.ConfigDebugIsDebuggerPresent", &io.ConfigDebugIsDebuggerPresent);
|
||||
ImGui::SameLine(); HelpMarker("Enable various tools calling IM_DEBUG_BREAK().\n\nRequires a debugger being attached, otherwise IM_DEBUG_BREAK() options will appear to crash your application.");
|
||||
ImGui::Checkbox("io.ConfigDebugHighlightIdConflicts", &io.ConfigDebugHighlightIdConflicts);
|
||||
ImGui::SameLine(); HelpMarker("Highlight and show an error message when multiple items have conflicting identifiers.");
|
||||
ImGui::BeginDisabled();
|
||||
ImGui::Checkbox("io.ConfigDebugBeginReturnValueOnce", &io.ConfigDebugBeginReturnValueOnce); // .
|
||||
ImGui::Checkbox("io.ConfigDebugBeginReturnValueOnce", &io.ConfigDebugBeginReturnValueOnce);
|
||||
ImGui::EndDisabled();
|
||||
ImGui::SameLine(); HelpMarker("First calls to Begin()/BeginChild() will return false.\n\nTHIS OPTION IS DISABLED because it needs to be set at application boot-time to make sense. Showing the disabled option is a way to make this feature easier to discover.");
|
||||
ImGui::Checkbox("io.ConfigDebugBeginReturnValueLoop", &io.ConfigDebugBeginReturnValueLoop);
|
||||
@@ -571,6 +627,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
ImGui::CheckboxFlags("io.BackendFlags: HasSetMousePos", &io.BackendFlags, ImGuiBackendFlags_HasSetMousePos);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: RendererHasVtxOffset", &io.BackendFlags, ImGuiBackendFlags_RendererHasVtxOffset);
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::TreePop();
|
||||
ImGui::Spacing();
|
||||
}
|
||||
@@ -680,22 +737,32 @@ static void ShowDemoWindowMenuBar(ImGuiDemoWindowData* demo_data)
|
||||
if (ImGui::BeginMenu("Tools"))
|
||||
{
|
||||
IMGUI_DEMO_MARKER("Menu/Tools");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
||||
const bool has_debug_tools = true;
|
||||
#else
|
||||
const bool has_debug_tools = false;
|
||||
#endif
|
||||
ImGui::MenuItem("Metrics/Debugger", NULL, &demo_data->ShowMetrics, has_debug_tools);
|
||||
if (ImGui::BeginMenu("Debug Options"))
|
||||
{
|
||||
ImGui::BeginDisabled(!has_debug_tools);
|
||||
ImGui::Checkbox("Highlight ID Conflicts", &io.ConfigDebugHighlightIdConflicts);
|
||||
ImGui::EndDisabled();
|
||||
ImGui::Checkbox("Assert on error recovery", &io.ConfigErrorRecoveryEnableAssert);
|
||||
ImGui::TextDisabled("(see Demo->Configuration for details & more)");
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::MenuItem("Debug Log", NULL, &demo_data->ShowDebugLog, has_debug_tools);
|
||||
ImGui::MenuItem("ID Stack Tool", NULL, &demo_data->ShowIDStackTool, has_debug_tools);
|
||||
ImGui::MenuItem("Style Editor", NULL, &demo_data->ShowStyleEditor);
|
||||
bool is_debugger_present = ImGui::GetIO().ConfigDebugIsDebuggerPresent;
|
||||
if (ImGui::MenuItem("Item Picker", NULL, false, has_debug_tools && is_debugger_present))
|
||||
bool is_debugger_present = io.ConfigDebugIsDebuggerPresent;
|
||||
if (ImGui::MenuItem("Item Picker", NULL, false, has_debug_tools))// && is_debugger_present))
|
||||
ImGui::DebugStartItemPicker();
|
||||
if (!is_debugger_present)
|
||||
ImGui::SetItemTooltip("Requires io.ConfigDebugIsDebuggerPresent=true to be set.\n\nWe otherwise disable the menu option to avoid casual users crashing the application.\n\nYou can however always access the Item Picker in Metrics->Tools.");
|
||||
ImGui::Separator();
|
||||
ImGui::SetItemTooltip("Requires io.ConfigDebugIsDebuggerPresent=true to be set.\n\nWe otherwise disable some extra features to avoid casual users crashing the application.");
|
||||
ImGui::MenuItem("Style Editor", NULL, &demo_data->ShowStyleEditor);
|
||||
ImGui::MenuItem("About Dear ImGui", NULL, &demo_data->ShowAbout);
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMenuBar();
|
||||
@@ -974,7 +1041,7 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||||
|
||||
// The following examples are passed for documentation purpose but may not be useful to most users.
|
||||
// Passing ImGuiHoveredFlags_ForTooltip to IsItemHovered() will pull ImGuiHoveredFlags flags values from
|
||||
// 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav' depending on whether mouse or gamepad/keyboard is being used.
|
||||
// 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav' depending on whether mouse or keyboard/gamepad is being used.
|
||||
// With default settings, ImGuiHoveredFlags_ForTooltip is equivalent to ImGuiHoveredFlags_DelayShort + ImGuiHoveredFlags_Stationary.
|
||||
ImGui::Button("Manual", sz);
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip))
|
||||
@@ -1055,7 +1122,7 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnDoubleClick", &base_flags, ImGuiTreeNodeFlags_OpenOnDoubleClick);
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAvailWidth", &base_flags, ImGuiTreeNodeFlags_SpanAvailWidth); ImGui::SameLine(); HelpMarker("Extend hit area to all available width instead of allowing more items to be laid out after the node.");
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", &base_flags, ImGuiTreeNodeFlags_SpanFullWidth);
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanTextWidth", &base_flags, ImGuiTreeNodeFlags_SpanTextWidth); ImGui::SameLine(); HelpMarker("Reduce hit area to the text label and a bit of margin.");
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanLabelWidth", &base_flags, ImGuiTreeNodeFlags_SpanLabelWidth); ImGui::SameLine(); HelpMarker("Reduce hit area to the text label and a bit of margin.");
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAllColumns", &base_flags, ImGuiTreeNodeFlags_SpanAllColumns); ImGui::SameLine(); HelpMarker("For use in Tables only.");
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_AllowOverlap", &base_flags, ImGuiTreeNodeFlags_AllowOverlap);
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_Framed", &base_flags, ImGuiTreeNodeFlags_Framed); ImGui::SameLine(); HelpMarker("Draw frame with background (e.g. for CollapsingHeader)");
|
||||
@@ -1092,9 +1159,9 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||||
ImGui::Text("This is a drag and drop source");
|
||||
ImGui::EndDragDropSource();
|
||||
}
|
||||
if (i == 2 && (base_flags & ImGuiTreeNodeFlags_SpanTextWidth))
|
||||
if (i == 2 && (base_flags & ImGuiTreeNodeFlags_SpanLabelWidth))
|
||||
{
|
||||
// Item 2 has an additional inline button to help demonstrate SpanTextWidth.
|
||||
// Item 2 has an additional inline button to help demonstrate SpanLabelWidth.
|
||||
ImGui::SameLine();
|
||||
if (ImGui::SmallButton("button")) {}
|
||||
}
|
||||
@@ -1775,6 +1842,16 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
IMGUI_DEMO_MARKER("Widgets/Text Input/Eliding, Alignment");
|
||||
if (ImGui::TreeNode("Eliding, Alignment"))
|
||||
{
|
||||
static char buf1[128] = "/path/to/some/folder/with/long/filename.cpp";
|
||||
static ImGuiInputTextFlags flags = ImGuiInputTextFlags_ElideLeft;
|
||||
ImGui::CheckboxFlags("ImGuiInputTextFlags_ElideLeft", &flags, ImGuiInputTextFlags_ElideLeft);
|
||||
ImGui::InputText("Path", buf1, IM_ARRAYSIZE(buf1), flags);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
IMGUI_DEMO_MARKER("Widgets/Text Input/Miscellaneous");
|
||||
if (ImGui::TreeNode("Miscellaneous"))
|
||||
{
|
||||
@@ -1996,8 +2073,12 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||||
ImGui::SameLine();
|
||||
ImGui::SliderInt("Sample count", &display_count, 1, 400);
|
||||
float (*func)(void*, int) = (func_type == 0) ? Funcs::Sin : Funcs::Saw;
|
||||
ImGui::PlotLines("Lines", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0, 80));
|
||||
ImGui::PlotHistogram("Histogram", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0, 80));
|
||||
ImGui::PlotLines("Lines##2", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0, 80));
|
||||
ImGui::PlotHistogram("Histogram##2", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0, 80));
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Text("Need better plotting and graphing? Consider using ImPlot:");
|
||||
ImGui::TextLinkOpenURL("https://github.com/epezent/implot");
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::TreePop();
|
||||
@@ -2036,19 +2117,16 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||||
if (ImGui::TreeNode("Color/Picker Widgets"))
|
||||
{
|
||||
static ImVec4 color = ImVec4(114.0f / 255.0f, 144.0f / 255.0f, 154.0f / 255.0f, 200.0f / 255.0f);
|
||||
static ImGuiColorEditFlags base_flags = ImGuiColorEditFlags_None;
|
||||
|
||||
static bool alpha_preview = true;
|
||||
static bool alpha_half_preview = false;
|
||||
static bool drag_and_drop = true;
|
||||
static bool options_menu = true;
|
||||
static bool hdr = false;
|
||||
ImGui::SeparatorText("Options");
|
||||
ImGui::Checkbox("With Alpha Preview", &alpha_preview);
|
||||
ImGui::Checkbox("With Half Alpha Preview", &alpha_half_preview);
|
||||
ImGui::Checkbox("With Drag and Drop", &drag_and_drop);
|
||||
ImGui::Checkbox("With Options Menu", &options_menu); ImGui::SameLine(); HelpMarker("Right-click on the individual color widget to show options.");
|
||||
ImGui::Checkbox("With HDR", &hdr); ImGui::SameLine(); HelpMarker("Currently all this does is to lift the 0..1 limits on dragging widgets.");
|
||||
ImGuiColorEditFlags misc_flags = (hdr ? ImGuiColorEditFlags_HDR : 0) | (drag_and_drop ? 0 : ImGuiColorEditFlags_NoDragDrop) | (alpha_half_preview ? ImGuiColorEditFlags_AlphaPreviewHalf : (alpha_preview ? ImGuiColorEditFlags_AlphaPreview : 0)) | (options_menu ? 0 : ImGuiColorEditFlags_NoOptions);
|
||||
ImGui::CheckboxFlags("ImGuiColorEditFlags_NoAlpha", &base_flags, ImGuiColorEditFlags_NoAlpha);
|
||||
ImGui::CheckboxFlags("ImGuiColorEditFlags_AlphaOpaque", &base_flags, ImGuiColorEditFlags_AlphaOpaque);
|
||||
ImGui::CheckboxFlags("ImGuiColorEditFlags_AlphaNoBg", &base_flags, ImGuiColorEditFlags_AlphaNoBg);
|
||||
ImGui::CheckboxFlags("ImGuiColorEditFlags_AlphaPreviewHalf", &base_flags, ImGuiColorEditFlags_AlphaPreviewHalf);
|
||||
ImGui::CheckboxFlags("ImGuiColorEditFlags_NoDragDrop", &base_flags, ImGuiColorEditFlags_NoDragDrop);
|
||||
ImGui::CheckboxFlags("ImGuiColorEditFlags_NoOptions", &base_flags, ImGuiColorEditFlags_NoOptions); ImGui::SameLine(); HelpMarker("Right-click on the individual color widget to show options.");
|
||||
ImGui::CheckboxFlags("ImGuiColorEditFlags_HDR", &base_flags, ImGuiColorEditFlags_HDR); ImGui::SameLine(); HelpMarker("Currently all this does is to lift the 0..1 limits on dragging widgets.");
|
||||
|
||||
IMGUI_DEMO_MARKER("Widgets/Color/ColorEdit");
|
||||
ImGui::SeparatorText("Inline color editor");
|
||||
@@ -2056,15 +2134,15 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||||
ImGui::SameLine(); HelpMarker(
|
||||
"Click on the color square to open a color picker.\n"
|
||||
"CTRL+click on individual component to input value.\n");
|
||||
ImGui::ColorEdit3("MyColor##1", (float*)&color, misc_flags);
|
||||
ImGui::ColorEdit3("MyColor##1", (float*)&color, base_flags);
|
||||
|
||||
IMGUI_DEMO_MARKER("Widgets/Color/ColorEdit (HSV, with Alpha)");
|
||||
ImGui::Text("Color widget HSV with Alpha:");
|
||||
ImGui::ColorEdit4("MyColor##2", (float*)&color, ImGuiColorEditFlags_DisplayHSV | misc_flags);
|
||||
ImGui::ColorEdit4("MyColor##2", (float*)&color, ImGuiColorEditFlags_DisplayHSV | base_flags);
|
||||
|
||||
IMGUI_DEMO_MARKER("Widgets/Color/ColorEdit (float display)");
|
||||
ImGui::Text("Color widget with Float Display:");
|
||||
ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float | misc_flags);
|
||||
ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float | base_flags);
|
||||
|
||||
IMGUI_DEMO_MARKER("Widgets/Color/ColorButton (with Picker)");
|
||||
ImGui::Text("Color button with Picker:");
|
||||
@@ -2072,7 +2150,7 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||||
"With the ImGuiColorEditFlags_NoInputs flag you can hide all the slider/text inputs.\n"
|
||||
"With the ImGuiColorEditFlags_NoLabel flag you can pass a non-empty label which will only "
|
||||
"be used for the tooltip and picker popup.");
|
||||
ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | misc_flags);
|
||||
ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | base_flags);
|
||||
|
||||
IMGUI_DEMO_MARKER("Widgets/Color/ColorButton (with custom Picker popup)");
|
||||
ImGui::Text("Color button with Custom Picker Popup:");
|
||||
@@ -2092,7 +2170,7 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||||
}
|
||||
|
||||
static ImVec4 backup_color;
|
||||
bool open_popup = ImGui::ColorButton("MyColor##3b", color, misc_flags);
|
||||
bool open_popup = ImGui::ColorButton("MyColor##3b", color, base_flags);
|
||||
ImGui::SameLine(0, ImGui::GetStyle().ItemInnerSpacing.x);
|
||||
open_popup |= ImGui::Button("Palette");
|
||||
if (open_popup)
|
||||
@@ -2104,7 +2182,7 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||||
{
|
||||
ImGui::Text("MY CUSTOM COLOR PICKER WITH AN AMAZING PALETTE!");
|
||||
ImGui::Separator();
|
||||
ImGui::ColorPicker4("##picker", (float*)&color, misc_flags | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoSmallPreview);
|
||||
ImGui::ColorPicker4("##picker", (float*)&color, base_flags | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoSmallPreview);
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::BeginGroup(); // Lock X position
|
||||
@@ -2146,40 +2224,42 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||||
ImGui::Text("Color button only:");
|
||||
static bool no_border = false;
|
||||
ImGui::Checkbox("ImGuiColorEditFlags_NoBorder", &no_border);
|
||||
ImGui::ColorButton("MyColor##3c", *(ImVec4*)&color, misc_flags | (no_border ? ImGuiColorEditFlags_NoBorder : 0), ImVec2(80, 80));
|
||||
ImGui::ColorButton("MyColor##3c", *(ImVec4*)&color, base_flags | (no_border ? ImGuiColorEditFlags_NoBorder : 0), ImVec2(80, 80));
|
||||
|
||||
IMGUI_DEMO_MARKER("Widgets/Color/ColorPicker");
|
||||
ImGui::SeparatorText("Color picker");
|
||||
static bool alpha = true;
|
||||
static bool alpha_bar = true;
|
||||
static bool side_preview = true;
|
||||
|
||||
static bool ref_color = false;
|
||||
static ImVec4 ref_color_v(1.0f, 0.0f, 1.0f, 0.5f);
|
||||
static int display_mode = 0;
|
||||
static int picker_mode = 0;
|
||||
ImGui::Checkbox("With Alpha", &alpha);
|
||||
ImGui::Checkbox("With Alpha Bar", &alpha_bar);
|
||||
ImGui::Checkbox("With Side Preview", &side_preview);
|
||||
if (side_preview)
|
||||
static int display_mode = 0;
|
||||
static ImGuiColorEditFlags color_picker_flags = ImGuiColorEditFlags_AlphaBar;
|
||||
|
||||
ImGui::PushID("Color picker");
|
||||
ImGui::CheckboxFlags("ImGuiColorEditFlags_NoAlpha", &color_picker_flags, ImGuiColorEditFlags_NoAlpha);
|
||||
ImGui::CheckboxFlags("ImGuiColorEditFlags_AlphaBar", &color_picker_flags, ImGuiColorEditFlags_AlphaBar);
|
||||
ImGui::CheckboxFlags("ImGuiColorEditFlags_NoSidePreview", &color_picker_flags, ImGuiColorEditFlags_NoSidePreview);
|
||||
if (color_picker_flags & ImGuiColorEditFlags_NoSidePreview)
|
||||
{
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("With Ref Color", &ref_color);
|
||||
if (ref_color)
|
||||
{
|
||||
ImGui::SameLine();
|
||||
ImGui::ColorEdit4("##RefColor", &ref_color_v.x, ImGuiColorEditFlags_NoInputs | misc_flags);
|
||||
ImGui::ColorEdit4("##RefColor", &ref_color_v.x, ImGuiColorEditFlags_NoInputs | base_flags);
|
||||
}
|
||||
}
|
||||
ImGui::Combo("Display Mode", &display_mode, "Auto/Current\0None\0RGB Only\0HSV Only\0Hex Only\0");
|
||||
|
||||
ImGui::Combo("Picker Mode", &picker_mode, "Auto/Current\0ImGuiColorEditFlags_PickerHueBar\0ImGuiColorEditFlags_PickerHueWheel\0");
|
||||
ImGui::SameLine(); HelpMarker("When not specified explicitly, user can right-click the picker to change mode.");
|
||||
|
||||
ImGui::Combo("Display Mode", &display_mode, "Auto/Current\0ImGuiColorEditFlags_NoInputs\0ImGuiColorEditFlags_DisplayRGB\0ImGuiColorEditFlags_DisplayHSV\0ImGuiColorEditFlags_DisplayHex\0");
|
||||
ImGui::SameLine(); HelpMarker(
|
||||
"ColorEdit defaults to displaying RGB inputs if you don't specify a display mode, "
|
||||
"but the user can change it with a right-click on those inputs.\n\nColorPicker defaults to displaying RGB+HSV+Hex "
|
||||
"if you don't specify a display mode.\n\nYou can change the defaults using SetColorEditOptions().");
|
||||
ImGui::SameLine(); HelpMarker("When not specified explicitly (Auto/Current mode), user can right-click the picker to change mode.");
|
||||
ImGuiColorEditFlags flags = misc_flags;
|
||||
if (!alpha) flags |= ImGuiColorEditFlags_NoAlpha; // This is by default if you call ColorPicker3() instead of ColorPicker4()
|
||||
if (alpha_bar) flags |= ImGuiColorEditFlags_AlphaBar;
|
||||
if (!side_preview) flags |= ImGuiColorEditFlags_NoSidePreview;
|
||||
|
||||
ImGuiColorEditFlags flags = base_flags | color_picker_flags;
|
||||
if (picker_mode == 1) flags |= ImGuiColorEditFlags_PickerHueBar;
|
||||
if (picker_mode == 2) flags |= ImGuiColorEditFlags_PickerHueWheel;
|
||||
if (display_mode == 1) flags |= ImGuiColorEditFlags_NoInputs; // Disable all RGB/HSV/Hex displays
|
||||
@@ -2208,6 +2288,7 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(w);
|
||||
ImGui::ColorPicker3("##MyColor##6", (float*)&color, ImGuiColorEditFlags_PickerHueWheel | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoAlpha);
|
||||
ImGui::PopID();
|
||||
|
||||
// HSV encoded support (to avoid RGB<>HSV round trips and singularities when S==0 or V==0)
|
||||
static ImVec4 color_hsv(0.23f, 1.0f, 1.0f, 1.0f); // Stored as HSV!
|
||||
@@ -2231,13 +2312,18 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||||
// Demonstrate using advanced flags for DragXXX and SliderXXX functions. Note that the flags are the same!
|
||||
static ImGuiSliderFlags flags = ImGuiSliderFlags_None;
|
||||
ImGui::CheckboxFlags("ImGuiSliderFlags_AlwaysClamp", &flags, ImGuiSliderFlags_AlwaysClamp);
|
||||
ImGui::SameLine(); HelpMarker("Always clamp value to min/max bounds (if any) when input manually with CTRL+Click.");
|
||||
ImGui::CheckboxFlags("ImGuiSliderFlags_ClampOnInput", &flags, ImGuiSliderFlags_ClampOnInput);
|
||||
ImGui::SameLine(); HelpMarker("Clamp value to min/max bounds when input manually with CTRL+Click. By default CTRL+Click allows going out of bounds.");
|
||||
ImGui::CheckboxFlags("ImGuiSliderFlags_ClampZeroRange", &flags, ImGuiSliderFlags_ClampZeroRange);
|
||||
ImGui::SameLine(); HelpMarker("Clamp even if min==max==0.0f. Otherwise DragXXX functions don't clamp.");
|
||||
ImGui::CheckboxFlags("ImGuiSliderFlags_Logarithmic", &flags, ImGuiSliderFlags_Logarithmic);
|
||||
ImGui::SameLine(); HelpMarker("Enable logarithmic editing (more precision for small values).");
|
||||
ImGui::CheckboxFlags("ImGuiSliderFlags_NoRoundToFormat", &flags, ImGuiSliderFlags_NoRoundToFormat);
|
||||
ImGui::SameLine(); HelpMarker("Disable rounding underlying value to match precision of the format string (e.g. %.3f values are rounded to those 3 digits).");
|
||||
ImGui::CheckboxFlags("ImGuiSliderFlags_NoInput", &flags, ImGuiSliderFlags_NoInput);
|
||||
ImGui::SameLine(); HelpMarker("Disable CTRL+Click or Enter key allowing to input text directly into the widget.");
|
||||
ImGui::CheckboxFlags("ImGuiSliderFlags_NoSpeedTweaks", &flags, ImGuiSliderFlags_NoSpeedTweaks);
|
||||
ImGui::SameLine(); HelpMarker("Disable keyboard modifiers altering tweak speed. Useful if you want to alter tweak speed yourself based on your own logic.");
|
||||
ImGui::CheckboxFlags("ImGuiSliderFlags_WrapAround", &flags, ImGuiSliderFlags_WrapAround);
|
||||
ImGui::SameLine(); HelpMarker("Enable wrapping around from max to min and from min to max (only supported by DragXXX() functions)");
|
||||
|
||||
@@ -2249,6 +2335,8 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||||
ImGui::DragFloat("DragFloat (0 -> +inf)", &drag_f, 0.005f, 0.0f, FLT_MAX, "%.3f", flags);
|
||||
ImGui::DragFloat("DragFloat (-inf -> 1)", &drag_f, 0.005f, -FLT_MAX, 1.0f, "%.3f", flags);
|
||||
ImGui::DragFloat("DragFloat (-inf -> +inf)", &drag_f, 0.005f, -FLT_MAX, +FLT_MAX, "%.3f", flags);
|
||||
//ImGui::DragFloat("DragFloat (0 -> 0)", &drag_f, 0.005f, 0.0f, 0.0f, "%.3f", flags); // To test ClampZeroRange
|
||||
//ImGui::DragFloat("DragFloat (100 -> 100)", &drag_f, 0.005f, 100.0f, 100.0f, "%.3f", flags);
|
||||
ImGui::DragInt("DragInt (0 -> 100)", &drag_i, 0.5f, 0, 100, "%d", flags);
|
||||
|
||||
// Sliders
|
||||
@@ -2588,6 +2676,11 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||||
IMGUI_DEMO_MARKER("Widgets/Drag and Drop/Drag to reorder items (simple)");
|
||||
if (ImGui::TreeNode("Drag to reorder items (simple)"))
|
||||
{
|
||||
// FIXME: there is temporary (usually single-frame) ID Conflict during reordering as a same item may be submitting twice.
|
||||
// This code was always slightly faulty but in a way which was not easily noticeable.
|
||||
// Until we fix this, enable ImGuiItemFlags_AllowDuplicateId to disable detecting the issue.
|
||||
ImGui::PushItemFlag(ImGuiItemFlags_AllowDuplicateId, true);
|
||||
|
||||
// Simple reordering
|
||||
HelpMarker(
|
||||
"We don't use the drag and drop api at all here! "
|
||||
@@ -2609,6 +2702,8 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PopItemFlag();
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
@@ -2761,7 +2856,7 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||||
static bool embed_all_inside_a_child_window = false;
|
||||
ImGui::Checkbox("Embed everything inside a child window for testing _RootWindow flag.", &embed_all_inside_a_child_window);
|
||||
if (embed_all_inside_a_child_window)
|
||||
ImGui::BeginChild("outer_child", ImVec2(0, ImGui::GetFontSize() * 20.0f), ImGuiChildFlags_Border);
|
||||
ImGui::BeginChild("outer_child", ImVec2(0, ImGui::GetFontSize() * 20.0f), ImGuiChildFlags_Borders);
|
||||
|
||||
// Testing IsWindowFocused() function with its various flags.
|
||||
ImGui::BulletText(
|
||||
@@ -2809,7 +2904,7 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||||
ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow),
|
||||
ImGui::IsWindowHovered(ImGuiHoveredFlags_Stationary));
|
||||
|
||||
ImGui::BeginChild("child", ImVec2(0, 50), ImGuiChildFlags_Border);
|
||||
ImGui::BeginChild("child", ImVec2(0, 50), ImGuiChildFlags_Borders);
|
||||
ImGui::Text("This is another child window for testing the _ChildWindows flag.");
|
||||
ImGui::EndChild();
|
||||
if (embed_all_inside_a_child_window)
|
||||
@@ -3374,7 +3469,7 @@ static void ShowDemoWindowMultiSelect(ImGuiDemoWindowData* demo_data)
|
||||
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_NoAutoClear", &flags, ImGuiMultiSelectFlags_NoAutoClear);
|
||||
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_BoxSelect2d", &flags, ImGuiMultiSelectFlags_BoxSelect2d); // Cannot use ImGuiMultiSelectFlags_BoxSelect1d as checkboxes are varying width.
|
||||
|
||||
if (ImGui::BeginChild("##Basket", ImVec2(-FLT_MIN, ImGui::GetFontSize() * 20), ImGuiChildFlags_Border | ImGuiChildFlags_ResizeY))
|
||||
if (ImGui::BeginChild("##Basket", ImVec2(-FLT_MIN, ImGui::GetFontSize() * 20), ImGuiChildFlags_Borders | ImGuiChildFlags_ResizeY))
|
||||
{
|
||||
ImGuiMultiSelectIO* ms_io = ImGui::BeginMultiSelect(flags, -1, IM_ARRAYSIZE(items));
|
||||
ImGuiSelectionExternalStorage storage_wrapper;
|
||||
@@ -3676,7 +3771,7 @@ static void ShowDemoWindowMultiSelect(ImGuiDemoWindowData* demo_data)
|
||||
{
|
||||
ImVec2 color_button_sz(ImGui::GetFontSize(), ImGui::GetFontSize());
|
||||
if (widget_type == WidgetType_TreeNode)
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(ImGui::GetStyle().ItemSpacing.x, 0.0f));
|
||||
ImGui::PushStyleVarY(ImGuiStyleVar_ItemSpacing, 0.0f);
|
||||
|
||||
ImGuiMultiSelectIO* ms_io = ImGui::BeginMultiSelect(flags, selection.Size, items.Size);
|
||||
selection.ApplyRequests(ms_io);
|
||||
@@ -3692,7 +3787,7 @@ static void ShowDemoWindowMultiSelect(ImGuiDemoWindowData* demo_data)
|
||||
ImGui::BeginTable("##Split", 2, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_NoPadOuterX);
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch, 0.70f);
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch, 0.30f);
|
||||
//ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(ImGui::GetStyle().ItemSpacing.x, 0.0f));
|
||||
//ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacingY, 0.0f);
|
||||
}
|
||||
|
||||
ImGuiListClipper clipper;
|
||||
@@ -3880,7 +3975,7 @@ static void ShowDemoWindowLayout()
|
||||
if (!disable_menu)
|
||||
window_flags |= ImGuiWindowFlags_MenuBar;
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 5.0f);
|
||||
ImGui::BeginChild("ChildR", ImVec2(0, 260), ImGuiChildFlags_Border, window_flags);
|
||||
ImGui::BeginChild("ChildR", ImVec2(0, 260), ImGuiChildFlags_Borders, window_flags);
|
||||
if (!disable_menu && ImGui::BeginMenuBar())
|
||||
{
|
||||
if (ImGui::BeginMenu("Menu"))
|
||||
@@ -3909,8 +4004,11 @@ static void ShowDemoWindowLayout()
|
||||
ImGui::SeparatorText("Manual-resize");
|
||||
{
|
||||
HelpMarker("Drag bottom border to resize. Double-click bottom border to auto-fit to vertical contents.");
|
||||
//if (ImGui::Button("Set Height to 200"))
|
||||
// ImGui::SetNextWindowSize(ImVec2(-FLT_MIN, 200.0f));
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::GetStyleColorVec4(ImGuiCol_FrameBg));
|
||||
if (ImGui::BeginChild("ResizableChild", ImVec2(-FLT_MIN, ImGui::GetTextLineHeightWithSpacing() * 8), ImGuiChildFlags_Border | ImGuiChildFlags_ResizeY))
|
||||
if (ImGui::BeginChild("ResizableChild", ImVec2(-FLT_MIN, ImGui::GetTextLineHeightWithSpacing() * 8), ImGuiChildFlags_Borders | ImGuiChildFlags_ResizeY))
|
||||
for (int n = 0; n < 10; n++)
|
||||
ImGui::Text("Line %04d", n);
|
||||
ImGui::PopStyleColor();
|
||||
@@ -3928,7 +4026,7 @@ static void ShowDemoWindowLayout()
|
||||
ImGui::DragInt("Max Height (in Lines)", &max_height_in_lines, 0.2f);
|
||||
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(0.0f, ImGui::GetTextLineHeightWithSpacing() * 1), ImVec2(FLT_MAX, ImGui::GetTextLineHeightWithSpacing() * max_height_in_lines));
|
||||
if (ImGui::BeginChild("ConstrainedChild", ImVec2(-FLT_MIN, 0.0f), ImGuiChildFlags_Border | ImGuiChildFlags_AutoResizeY))
|
||||
if (ImGui::BeginChild("ConstrainedChild", ImVec2(-FLT_MIN, 0.0f), ImGuiChildFlags_Borders | ImGuiChildFlags_AutoResizeY))
|
||||
for (int n = 0; n < draw_lines; n++)
|
||||
ImGui::Text("Line %04d", n);
|
||||
ImGui::EndChild();
|
||||
@@ -3946,11 +4044,11 @@ static void ShowDemoWindowLayout()
|
||||
{
|
||||
static int offset_x = 0;
|
||||
static bool override_bg_color = true;
|
||||
static ImGuiChildFlags child_flags = ImGuiChildFlags_Border | ImGuiChildFlags_ResizeX | ImGuiChildFlags_ResizeY;
|
||||
static ImGuiChildFlags child_flags = ImGuiChildFlags_Borders | ImGuiChildFlags_ResizeX | ImGuiChildFlags_ResizeY;
|
||||
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
|
||||
ImGui::DragInt("Offset X", &offset_x, 1.0f, -1000, 1000);
|
||||
ImGui::Checkbox("Override ChildBg color", &override_bg_color);
|
||||
ImGui::CheckboxFlags("ImGuiChildFlags_Border", &child_flags, ImGuiChildFlags_Border);
|
||||
ImGui::CheckboxFlags("ImGuiChildFlags_Borders", &child_flags, ImGuiChildFlags_Borders);
|
||||
ImGui::CheckboxFlags("ImGuiChildFlags_AlwaysUseWindowPadding", &child_flags, ImGuiChildFlags_AlwaysUseWindowPadding);
|
||||
ImGui::CheckboxFlags("ImGuiChildFlags_ResizeX", &child_flags, ImGuiChildFlags_ResizeX);
|
||||
ImGui::CheckboxFlags("ImGuiChildFlags_ResizeY", &child_flags, ImGuiChildFlags_ResizeY);
|
||||
@@ -4217,7 +4315,7 @@ static void ShowDemoWindowLayout()
|
||||
// down by FramePadding.y ahead of time)
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("OK Blahblah"); ImGui::SameLine();
|
||||
ImGui::Button("Some framed item"); ImGui::SameLine();
|
||||
ImGui::Button("Some framed item##2"); ImGui::SameLine();
|
||||
HelpMarker("We call AlignTextToFramePadding() to vertically align the text baseline by +FramePadding.y");
|
||||
|
||||
// SmallButton() uses the same vertical padding as Text
|
||||
@@ -4360,7 +4458,7 @@ static void ShowDemoWindowLayout()
|
||||
|
||||
const ImGuiWindowFlags child_flags = enable_extra_decorations ? ImGuiWindowFlags_MenuBar : 0;
|
||||
const ImGuiID child_id = ImGui::GetID((void*)(intptr_t)i);
|
||||
const bool child_is_visible = ImGui::BeginChild(child_id, ImVec2(child_w, 200.0f), ImGuiChildFlags_Border, child_flags);
|
||||
const bool child_is_visible = ImGui::BeginChild(child_id, ImVec2(child_w, 200.0f), ImGuiChildFlags_Borders, child_flags);
|
||||
if (ImGui::BeginMenuBar())
|
||||
{
|
||||
ImGui::TextUnformatted("abc");
|
||||
@@ -4407,7 +4505,7 @@ static void ShowDemoWindowLayout()
|
||||
float child_height = ImGui::GetTextLineHeight() + style.ScrollbarSize + style.WindowPadding.y * 2.0f;
|
||||
ImGuiWindowFlags child_flags = ImGuiWindowFlags_HorizontalScrollbar | (enable_extra_decorations ? ImGuiWindowFlags_AlwaysVerticalScrollbar : 0);
|
||||
ImGuiID child_id = ImGui::GetID((void*)(intptr_t)i);
|
||||
bool child_is_visible = ImGui::BeginChild(child_id, ImVec2(-100, child_height), ImGuiChildFlags_Border, child_flags);
|
||||
bool child_is_visible = ImGui::BeginChild(child_id, ImVec2(-100, child_height), ImGuiChildFlags_Borders, child_flags);
|
||||
if (scroll_to_off)
|
||||
ImGui::SetScrollX(scroll_to_off_px);
|
||||
if (scroll_to_pos)
|
||||
@@ -4449,7 +4547,7 @@ static void ShowDemoWindowLayout()
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2.0f, 1.0f));
|
||||
ImVec2 scrolling_child_size = ImVec2(0, ImGui::GetFrameHeightWithSpacing() * 7 + 30);
|
||||
ImGui::BeginChild("scrolling", scrolling_child_size, ImGuiChildFlags_Border, ImGuiWindowFlags_HorizontalScrollbar);
|
||||
ImGui::BeginChild("scrolling", scrolling_child_size, ImGuiChildFlags_Borders, ImGuiWindowFlags_HorizontalScrollbar);
|
||||
for (int line = 0; line < lines; line++)
|
||||
{
|
||||
// Display random stuff. For the sake of this trivial demo we are using basic Button() + SameLine()
|
||||
@@ -4595,7 +4693,7 @@ static void ShowDemoWindowLayout()
|
||||
}
|
||||
if (show_child)
|
||||
{
|
||||
ImGui::BeginChild("child", ImVec2(0, 0), ImGuiChildFlags_Border);
|
||||
ImGui::BeginChild("child", ImVec2(0, 0), ImGuiChildFlags_Borders);
|
||||
ImGui::EndChild();
|
||||
}
|
||||
ImGui::End();
|
||||
@@ -5081,8 +5179,8 @@ const ImGuiTableSortSpecs* MyItem::s_current_sort_specs = NULL;
|
||||
static void PushStyleCompact()
|
||||
{
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(style.FramePadding.x, (float)(int)(style.FramePadding.y * 0.60f)));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x, (float)(int)(style.ItemSpacing.y * 0.60f)));
|
||||
ImGui::PushStyleVarY(ImGuiStyleVar_FramePadding, (float)(int)(style.FramePadding.y * 0.60f));
|
||||
ImGui::PushStyleVarY(ImGuiStyleVar_ItemSpacing, (float)(int)(style.ItemSpacing.y * 0.60f));
|
||||
}
|
||||
|
||||
static void PopStyleCompact()
|
||||
@@ -6116,7 +6214,7 @@ static void ShowDemoWindowTables()
|
||||
for (int row = 0; row < 8; row++)
|
||||
{
|
||||
if ((row % 3) == 2)
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(style.CellPadding.x, 20.0f));
|
||||
ImGui::PushStyleVarY(ImGuiStyleVar_CellPadding, 20.0f);
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_None);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("CellPadding.y = %.2f", style.CellPadding.y);
|
||||
@@ -6259,15 +6357,17 @@ static void ShowDemoWindowTables()
|
||||
IMGUI_DEMO_MARKER("Tables/Tree view");
|
||||
if (ImGui::TreeNode("Tree view"))
|
||||
{
|
||||
static ImGuiTableFlags flags = ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody;
|
||||
static ImGuiTableFlags table_flags = ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody;
|
||||
|
||||
static ImGuiTreeNodeFlags tree_node_flags = ImGuiTreeNodeFlags_SpanAllColumns;
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", &tree_node_flags, ImGuiTreeNodeFlags_SpanFullWidth);
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanTextWidth", &tree_node_flags, ImGuiTreeNodeFlags_SpanTextWidth);
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAllColumns", &tree_node_flags, ImGuiTreeNodeFlags_SpanAllColumns);
|
||||
static ImGuiTreeNodeFlags tree_node_flags_base = ImGuiTreeNodeFlags_SpanAllColumns;
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", &tree_node_flags_base, ImGuiTreeNodeFlags_SpanFullWidth);
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanLabelWidth", &tree_node_flags_base, ImGuiTreeNodeFlags_SpanLabelWidth);
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAllColumns", &tree_node_flags_base, ImGuiTreeNodeFlags_SpanAllColumns);
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_LabelSpanAllColumns", &tree_node_flags_base, ImGuiTreeNodeFlags_LabelSpanAllColumns);
|
||||
ImGui::SameLine(); HelpMarker("Useful if you know that you aren't displaying contents in other columns");
|
||||
|
||||
HelpMarker("See \"Columns flags\" section to configure how indentation is applied to individual columns.");
|
||||
if (ImGui::BeginTable("3ways", 3, flags))
|
||||
if (ImGui::BeginTable("3ways", 3, table_flags))
|
||||
{
|
||||
// The first column will use the default _WidthStretch when ScrollX is Off and _WidthFixed when ScrollX is On
|
||||
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_NoHide);
|
||||
@@ -6288,13 +6388,21 @@ static void ShowDemoWindowTables()
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
const bool is_folder = (node->ChildCount > 0);
|
||||
|
||||
ImGuiTreeNodeFlags node_flags = tree_node_flags_base;
|
||||
if (node != &all_nodes[0])
|
||||
node_flags &= ~ImGuiTreeNodeFlags_LabelSpanAllColumns; // Only demonstrate this on the root node.
|
||||
|
||||
if (is_folder)
|
||||
{
|
||||
bool open = ImGui::TreeNodeEx(node->Name, tree_node_flags);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextDisabled("--");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted(node->Type);
|
||||
bool open = ImGui::TreeNodeEx(node->Name, node_flags);
|
||||
if ((node_flags & ImGuiTreeNodeFlags_LabelSpanAllColumns) == 0)
|
||||
{
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextDisabled("--");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted(node->Type);
|
||||
}
|
||||
if (open)
|
||||
{
|
||||
for (int child_n = 0; child_n < node->ChildCount; child_n++)
|
||||
@@ -6304,7 +6412,7 @@ static void ShowDemoWindowTables()
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::TreeNodeEx(node->Name, tree_node_flags | ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_Bullet | ImGuiTreeNodeFlags_NoTreePushOnOpen);
|
||||
ImGui::TreeNodeEx(node->Name, node_flags | ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_Bullet | ImGuiTreeNodeFlags_NoTreePushOnOpen);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", node->Size);
|
||||
ImGui::TableNextColumn();
|
||||
@@ -6314,7 +6422,7 @@ static void ShowDemoWindowTables()
|
||||
};
|
||||
static const MyTreeNode nodes[] =
|
||||
{
|
||||
{ "Root", "Folder", -1, 1, 3 }, // 0
|
||||
{ "Root with Long Name", "Folder", -1, 1, 3 }, // 0
|
||||
{ "Music", "Folder", -1, 4, 2 }, // 1
|
||||
{ "Textures", "Folder", -1, 6, 3 }, // 2
|
||||
{ "desktop.ini", "System file", 1024, -1,-1 }, // 3
|
||||
@@ -6395,7 +6503,11 @@ static void ShowDemoWindowTables()
|
||||
// FIXME: It would be nice to actually demonstrate full-featured selection using those checkbox.
|
||||
static bool column_selected[3] = {};
|
||||
|
||||
// Instead of calling TableHeadersRow() we'll submit custom headers ourselves
|
||||
// Instead of calling TableHeadersRow() we'll submit custom headers ourselves.
|
||||
// (A different approach is also possible:
|
||||
// - Specify ImGuiTableColumnFlags_NoHeaderLabel in some TableSetupColumn() call.
|
||||
// - Call TableHeadersRow() normally. This will submit TableHeader() with no name.
|
||||
// - Then call TableSetColumnIndex() to position yourself in the column and submit your stuff e.g. Checkbox().)
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
||||
for (int column = 0; column < COLUMNS_COUNT; column++)
|
||||
{
|
||||
@@ -6410,6 +6522,7 @@ static void ShowDemoWindowTables()
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
// Submit table contents
|
||||
for (int row = 0; row < 5; row++)
|
||||
{
|
||||
ImGui::TableNextRow();
|
||||
@@ -6444,6 +6557,7 @@ static void ShowDemoWindowTables()
|
||||
ImGui::CheckboxFlags("_ScrollX", &table_flags, ImGuiTableFlags_ScrollX);
|
||||
ImGui::CheckboxFlags("_ScrollY", &table_flags, ImGuiTableFlags_ScrollY);
|
||||
ImGui::CheckboxFlags("_Resizable", &table_flags, ImGuiTableFlags_Resizable);
|
||||
ImGui::CheckboxFlags("_Sortable", &table_flags, ImGuiTableFlags_Sortable);
|
||||
ImGui::CheckboxFlags("_NoBordersInBody", &table_flags, ImGuiTableFlags_NoBordersInBody);
|
||||
ImGui::CheckboxFlags("_HighlightHoveredColumn", &table_flags, ImGuiTableFlags_HighlightHoveredColumn);
|
||||
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
|
||||
@@ -7134,12 +7248,14 @@ static void ShowDemoWindowColumns()
|
||||
{
|
||||
if (h_borders && ImGui::GetColumnIndex() == 0)
|
||||
ImGui::Separator();
|
||||
ImGui::PushID(i);
|
||||
ImGui::Text("%c%c%c", 'a' + i, 'a' + i, 'a' + i);
|
||||
ImGui::Text("Width %.2f", ImGui::GetColumnWidth());
|
||||
ImGui::Text("Avail %.2f", ImGui::GetContentRegionAvail().x);
|
||||
ImGui::Text("Offset %.2f", ImGui::GetColumnOffset());
|
||||
ImGui::Text("Long text that is likely to clip");
|
||||
ImGui::Button("Button", ImVec2(-FLT_MIN, 0.0f));
|
||||
ImGui::PopID();
|
||||
ImGui::NextColumn();
|
||||
}
|
||||
ImGui::Columns(1);
|
||||
@@ -7292,18 +7408,15 @@ static void ShowDemoWindowInputs()
|
||||
ImGui::Text("Mouse down:");
|
||||
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseDown(i)) { ImGui::SameLine(); ImGui::Text("b%d (%.02f secs)", i, io.MouseDownDuration[i]); }
|
||||
ImGui::Text("Mouse wheel: %.1f", io.MouseWheel);
|
||||
ImGui::Text("Mouse clicked count:");
|
||||
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (io.MouseClickedCount[i] > 0) { ImGui::SameLine(); ImGui::Text("b%d: %d", i, io.MouseClickedCount[i]); }
|
||||
|
||||
// We iterate both legacy native range and named ImGuiKey ranges. This is a little unusual/odd but this allows
|
||||
// displaying the data for old/new backends.
|
||||
// User code should never have to go through such hoops!
|
||||
// You can generally iterate between ImGuiKey_NamedKey_BEGIN and ImGuiKey_NamedKey_END.
|
||||
#ifdef IMGUI_DISABLE_OBSOLETE_KEYIO
|
||||
struct funcs { static bool IsLegacyNativeDupe(ImGuiKey) { return false; } };
|
||||
ImGuiKey start_key = ImGuiKey_NamedKey_BEGIN;
|
||||
#else
|
||||
struct funcs { static bool IsLegacyNativeDupe(ImGuiKey key) { return key >= 0 && key < 512 && ImGui::GetIO().KeyMap[key] != -1; } }; // Hide Native<>ImGuiKey duplicates when both exists in the array
|
||||
ImGuiKey start_key = (ImGuiKey)0;
|
||||
#endif
|
||||
ImGui::Text("Keys down:"); for (ImGuiKey key = start_key; key < ImGuiKey_NamedKey_END; key = (ImGuiKey)(key + 1)) { if (funcs::IsLegacyNativeDupe(key) || !ImGui::IsKeyDown(key)) continue; ImGui::SameLine(); ImGui::Text((key < ImGuiKey_NamedKey_BEGIN) ? "\"%s\"" : "\"%s\" %d", ImGui::GetKeyName(key), key); }
|
||||
ImGui::Text("Keys mods: %s%s%s%s", io.KeyCtrl ? "CTRL " : "", io.KeyShift ? "SHIFT " : "", io.KeyAlt ? "ALT " : "", io.KeySuper ? "SUPER " : "");
|
||||
ImGui::Text("Chars queue:"); for (int i = 0; i < io.InputQueueCharacters.Size; i++) { ImWchar c = io.InputQueueCharacters[i]; ImGui::SameLine(); ImGui::Text("\'%c\' (0x%04X)", (c > ' ' && c <= 255) ? (char)c : '?', c); } // FIXME: We should convert 'c' to UTF-8 here but the functions are not public.
|
||||
@@ -7462,7 +7575,8 @@ static void ShowDemoWindowInputs()
|
||||
IM_ASSERT(IM_ARRAYSIZE(mouse_cursors_names) == ImGuiMouseCursor_COUNT);
|
||||
|
||||
ImGuiMouseCursor current = ImGui::GetMouseCursor();
|
||||
ImGui::Text("Current mouse cursor = %d: %s", current, mouse_cursors_names[current]);
|
||||
const char* cursor_name = (current >= ImGuiMouseCursor_Arrow) && (current < ImGuiMouseCursor_COUNT) ? mouse_cursors_names[current] : "N/A";
|
||||
ImGui::Text("Current mouse cursor = %d: %s", current, cursor_name);
|
||||
ImGui::BeginDisabled(true);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: HasMouseCursors", &io.BackendFlags, ImGuiBackendFlags_HasMouseCursors);
|
||||
ImGui::EndDisabled();
|
||||
@@ -7598,7 +7712,8 @@ void ImGui::ShowAboutWindow(bool* p_open)
|
||||
ImGui::TextLinkOpenURL("Funding", "https://github.com/ocornut/imgui/wiki/Funding");
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::Text("By Omar Cornut and all Dear ImGui contributors.");
|
||||
ImGui::Text("(c) 2014-2025 Omar Cornut");
|
||||
ImGui::Text("Developed by Omar Cornut and all Dear ImGui contributors.");
|
||||
ImGui::Text("Dear ImGui is licensed under the MIT License, see LICENSE for more information.");
|
||||
ImGui::Text("If your company uses this, please consider funding the project.");
|
||||
|
||||
@@ -7625,9 +7740,6 @@ void ImGui::ShowAboutWindow(bool* p_open)
|
||||
#ifdef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
ImGui::Text("define: IMGUI_DISABLE_OBSOLETE_FUNCTIONS");
|
||||
#endif
|
||||
#ifdef IMGUI_DISABLE_OBSOLETE_KEYIO
|
||||
ImGui::Text("define: IMGUI_DISABLE_OBSOLETE_KEYIO");
|
||||
#endif
|
||||
#ifdef IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS
|
||||
ImGui::Text("define: IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS");
|
||||
#endif
|
||||
@@ -7687,6 +7799,7 @@ void ImGui::ShowAboutWindow(bool* p_open)
|
||||
#endif
|
||||
#ifdef __EMSCRIPTEN__
|
||||
ImGui::Text("define: __EMSCRIPTEN__");
|
||||
ImGui::Text("Emscripten: %d.%d.%d", __EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__);
|
||||
#endif
|
||||
ImGui::Separator();
|
||||
ImGui::Text("io.BackendPlatformName: %s", io.BackendPlatformName ? io.BackendPlatformName : "NULL");
|
||||
@@ -7694,12 +7807,13 @@ void ImGui::ShowAboutWindow(bool* p_open)
|
||||
ImGui::Text("io.ConfigFlags: 0x%08X", io.ConfigFlags);
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) ImGui::Text(" NavEnableKeyboard");
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) ImGui::Text(" NavEnableGamepad");
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) ImGui::Text(" NavEnableSetMousePos");
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard) ImGui::Text(" NavNoCaptureKeyboard");
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_NoMouse) ImGui::Text(" NoMouse");
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) ImGui::Text(" NoMouseCursorChange");
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_NoKeyboard) ImGui::Text(" NoKeyboard");
|
||||
if (io.MouseDrawCursor) ImGui::Text("io.MouseDrawCursor");
|
||||
if (io.ConfigMacOSXBehaviors) ImGui::Text("io.ConfigMacOSXBehaviors");
|
||||
if (io.ConfigNavMoveSetMousePos) ImGui::Text("io.ConfigNavMoveSetMousePos");
|
||||
if (io.ConfigNavCaptureKeyboard) ImGui::Text("io.ConfigNavCaptureKeyboard");
|
||||
if (io.ConfigInputTextCursorBlink) ImGui::Text("io.ConfigInputTextCursorBlink");
|
||||
if (io.ConfigWindowsResizeFromEdges) ImGui::Text("io.ConfigWindowsResizeFromEdges");
|
||||
if (io.ConfigWindowsMoveFromTitleBarOnly) ImGui::Text("io.ConfigWindowsMoveFromTitleBarOnly");
|
||||
@@ -7756,6 +7870,8 @@ void ImGui::ShowFontSelector(const char* label)
|
||||
ImGui::PushID((void*)font);
|
||||
if (ImGui::Selectable(font->GetDebugName(), font == font_current))
|
||||
io.FontDefault = font;
|
||||
if (font == font_current)
|
||||
ImGui::SetItemDefaultFocus();
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
@@ -7852,7 +7968,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
||||
ImGui::SliderFloat("FrameBorderSize", &style.FrameBorderSize, 0.0f, 1.0f, "%.0f");
|
||||
ImGui::SliderFloat("TabBorderSize", &style.TabBorderSize, 0.0f, 1.0f, "%.0f");
|
||||
ImGui::SliderFloat("TabBarBorderSize", &style.TabBarBorderSize, 0.0f, 2.0f, "%.0f");
|
||||
ImGui::SliderFloat("TabBarOverlineSize", &style.TabBarOverlineSize, 0.0f, 2.0f, "%.0f");
|
||||
ImGui::SliderFloat("TabBarOverlineSize", &style.TabBarOverlineSize, 0.0f, 3.0f, "%.0f");
|
||||
ImGui::SameLine(); HelpMarker("Overline is only drawn over the selected tab when ImGuiTabBarFlags_DrawSelectedOverline is set.");
|
||||
|
||||
ImGui::SeparatorText("Rounding");
|
||||
@@ -7932,16 +8048,16 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
||||
filter.Draw("Filter colors", ImGui::GetFontSize() * 16);
|
||||
|
||||
static ImGuiColorEditFlags alpha_flags = 0;
|
||||
if (ImGui::RadioButton("Opaque", alpha_flags == ImGuiColorEditFlags_None)) { alpha_flags = ImGuiColorEditFlags_None; } ImGui::SameLine();
|
||||
if (ImGui::RadioButton("Alpha", alpha_flags == ImGuiColorEditFlags_AlphaPreview)) { alpha_flags = ImGuiColorEditFlags_AlphaPreview; } ImGui::SameLine();
|
||||
if (ImGui::RadioButton("Both", alpha_flags == ImGuiColorEditFlags_AlphaPreviewHalf)) { alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf; } ImGui::SameLine();
|
||||
if (ImGui::RadioButton("Opaque", alpha_flags == ImGuiColorEditFlags_AlphaOpaque)) { alpha_flags = ImGuiColorEditFlags_AlphaOpaque; } ImGui::SameLine();
|
||||
if (ImGui::RadioButton("Alpha", alpha_flags == ImGuiColorEditFlags_None)) { alpha_flags = ImGuiColorEditFlags_None; } ImGui::SameLine();
|
||||
if (ImGui::RadioButton("Both", alpha_flags == ImGuiColorEditFlags_AlphaPreviewHalf)) { alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf; } ImGui::SameLine();
|
||||
HelpMarker(
|
||||
"In the color list:\n"
|
||||
"Left-click on color square to open color picker,\n"
|
||||
"Right-click to open edit options menu.");
|
||||
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(0.0f, ImGui::GetTextLineHeightWithSpacing() * 10), ImVec2(FLT_MAX, FLT_MAX));
|
||||
ImGui::BeginChild("##colors", ImVec2(0, 0), ImGuiChildFlags_Border | ImGuiChildFlags_NavFlattened, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar);
|
||||
ImGui::BeginChild("##colors", ImVec2(0, 0), ImGuiChildFlags_Borders | ImGuiChildFlags_NavFlattened, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar);
|
||||
ImGui::PushItemWidth(ImGui::GetFontSize() * -12);
|
||||
for (int i = 0; i < ImGuiCol_COUNT; i++)
|
||||
{
|
||||
@@ -8175,7 +8291,7 @@ static void ShowExampleMenuFile()
|
||||
{
|
||||
static bool enabled = true;
|
||||
ImGui::MenuItem("Enabled", "", &enabled);
|
||||
ImGui::BeginChild("child", ImVec2(0, 60), ImGuiChildFlags_Border);
|
||||
ImGui::BeginChild("child", ImVec2(0, 60), ImGuiChildFlags_Borders);
|
||||
for (int i = 0; i < 10; i++)
|
||||
ImGui::Text("Scrolling Text %d", i);
|
||||
ImGui::EndChild();
|
||||
@@ -8772,7 +8888,7 @@ static void ShowExampleAppLayout(bool* p_open)
|
||||
// Left
|
||||
static int selected = 0;
|
||||
{
|
||||
ImGui::BeginChild("left pane", ImVec2(150, 0), ImGuiChildFlags_Border | ImGuiChildFlags_ResizeX);
|
||||
ImGui::BeginChild("left pane", ImVec2(150, 0), ImGuiChildFlags_Borders | ImGuiChildFlags_ResizeX);
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
// FIXME: Good candidate to use ImGuiSelectableFlags_SelectOnNav
|
||||
@@ -8833,7 +8949,7 @@ struct ExampleAppPropertyEditor
|
||||
{
|
||||
// Left side: draw tree
|
||||
// - Currently using a table to benefit from RowBg feature
|
||||
if (ImGui::BeginChild("##tree", ImVec2(300, 0), ImGuiChildFlags_ResizeX | ImGuiChildFlags_Border | ImGuiChildFlags_NavFlattened))
|
||||
if (ImGui::BeginChild("##tree", ImVec2(300, 0), ImGuiChildFlags_ResizeX | ImGuiChildFlags_Borders | ImGuiChildFlags_NavFlattened))
|
||||
{
|
||||
ImGui::SetNextItemWidth(-FLT_MIN);
|
||||
ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_F, ImGuiInputFlags_Tooltip);
|
||||
@@ -8863,6 +8979,8 @@ struct ExampleAppPropertyEditor
|
||||
ImGui::Separator();
|
||||
if (ImGui::BeginTable("##properties", 2, ImGuiTableFlags_Resizable | ImGuiTableFlags_ScrollY))
|
||||
{
|
||||
// Push object ID after we entered the table, so table is shared for all objects
|
||||
ImGui::PushID((int)node->UID);
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch, 2.0f); // Default twice larger
|
||||
if (node->HasData)
|
||||
@@ -8901,10 +9019,16 @@ struct ExampleAppPropertyEditor
|
||||
ImGui::SliderScalarN("##Editor", field_desc.DataType, field_ptr, field_desc.DataCount, &v_min, &v_max);
|
||||
break;
|
||||
}
|
||||
case ImGuiDataType_String:
|
||||
{
|
||||
ImGui::InputText("##Editor", reinterpret_cast<char*>(field_ptr), 28);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
ImGui::PopID();
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
@@ -9447,7 +9571,7 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
// To use a child window instead we could use, e.g:
|
||||
// ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); // Disable padding
|
||||
// ImGui::PushStyleColor(ImGuiCol_ChildBg, IM_COL32(50, 50, 50, 255)); // Set a background color
|
||||
// ImGui::BeginChild("canvas", ImVec2(0.0f, 0.0f), ImGuiChildFlags_Border, ImGuiWindowFlags_NoMove);
|
||||
// ImGui::BeginChild("canvas", ImVec2(0.0f, 0.0f), ImGuiChildFlags_Borders, ImGuiWindowFlags_NoMove);
|
||||
// ImGui::PopStyleColor();
|
||||
// ImGui::PopStyleVar();
|
||||
// [...]
|
||||
@@ -10098,8 +10222,8 @@ struct ExampleAssetsBrowser
|
||||
}
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui::SetNextWindowContentSize(ImVec2(0.0f, LayoutOuterPadding + LayoutLineCount * (LayoutItemSize.x + LayoutItemSpacing)));
|
||||
if (ImGui::BeginChild("Assets", ImVec2(0.0f, -ImGui::GetTextLineHeightWithSpacing()), ImGuiChildFlags_Border, ImGuiWindowFlags_NoMove))
|
||||
ImGui::SetNextWindowContentSize(ImVec2(0.0f, LayoutOuterPadding + LayoutLineCount * (LayoutItemSize.y + LayoutItemSpacing)));
|
||||
if (ImGui::BeginChild("Assets", ImVec2(0.0f, -ImGui::GetTextLineHeightWithSpacing()), ImGuiChildFlags_Borders, ImGuiWindowFlags_NoMove))
|
||||
{
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
|
||||
@@ -10148,7 +10272,7 @@ struct ExampleAssetsBrowser
|
||||
|
||||
// Rendering parameters
|
||||
const ImU32 icon_type_overlay_colors[3] = { 0, IM_COL32(200, 70, 70, 255), IM_COL32(70, 170, 70, 255) };
|
||||
const ImU32 icon_bg_color = ImGui::GetColorU32(ImGuiCol_MenuBarBg);
|
||||
const ImU32 icon_bg_color = ImGui::GetColorU32(IM_COL32(35, 35, 35, 220));
|
||||
const ImVec2 icon_type_overlay_size = ImVec2(4.0f, 4.0f);
|
||||
const bool display_label = (LayoutItemSize.x >= ImGui::CalcTextSize("999").x);
|
||||
|
||||
@@ -10310,6 +10434,8 @@ void ImGui::ShowAboutWindow(bool*) {}
|
||||
void ImGui::ShowDemoWindow(bool*) {}
|
||||
void ImGui::ShowUserGuide() {}
|
||||
void ImGui::ShowStyleEditor(ImGuiStyle*) {}
|
||||
bool ImGui::ShowStyleSelector(const char* label) { return false; }
|
||||
void ImGui::ShowFontSelector(const char* label) {}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
656
3rdparty/imgui/src/imgui_draw.cpp
vendored
656
3rdparty/imgui/src/imgui_draw.cpp
vendored
File diff suppressed because it is too large
Load Diff
55
3rdparty/imgui/src/imgui_freetype.cpp
vendored
55
3rdparty/imgui/src/imgui_freetype.cpp
vendored
@@ -6,10 +6,11 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2024/10/17: added plutosvg support for SVG Fonts (seems faster/better than lunasvg). Enable by using '#define IMGUI_ENABLE_FREETYPE_PLUTOSVG'. (#7927)
|
||||
// 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/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/08/23: fixed crash when FT_Render_Glyph() fails to render a glyph and returns nullptr.
|
||||
// 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 preferred texture format.
|
||||
// 2021/01/28: added support for color-layered glyphs via ImGuiFreeTypeBuilderFlags_LoadColor (require Freetype 2.10+).
|
||||
@@ -32,7 +33,7 @@
|
||||
// - For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
|
||||
// - The default dear imgui styles will be impacted by this change (alpha values will need tweaking).
|
||||
|
||||
// FIXME: cfg.OversampleH, OversampleV are not supported (but perhaps not so necessary with this rasterizer).
|
||||
// FIXME: cfg.OversampleH, OversampleV are not supported, but generally not necessary with this rasterizer because Hinting makes everything look better.
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
@@ -45,12 +46,21 @@
|
||||
#include FT_GLYPH_H // <freetype/ftglyph.h>
|
||||
#include FT_SYNTHESIS_H // <freetype/ftsynth.h>
|
||||
|
||||
#ifdef IMGUI_ENABLE_FREETYPE_LUNASVG
|
||||
// Handle LunaSVG and PlutoSVG
|
||||
#if defined(IMGUI_ENABLE_FREETYPE_LUNASVG) && defined(IMGUI_ENABLE_FREETYPE_PLUTOSVG)
|
||||
#error "Cannot enable both IMGUI_ENABLE_FREETYPE_LUNASVG and IMGUI_ENABLE_FREETYPE_PLUTOSVG"
|
||||
#endif
|
||||
#ifdef IMGUI_ENABLE_FREETYPE_LUNASVG
|
||||
#include FT_OTSVG_H // <freetype/otsvg.h>
|
||||
#include FT_BBOX_H // <freetype/ftbbox.h>
|
||||
#include <lunasvg.h>
|
||||
#endif
|
||||
#ifdef IMGUI_ENABLE_FREETYPE_PLUTOSVG
|
||||
#include <plutosvg.h>
|
||||
#endif
|
||||
#if defined(IMGUI_ENABLE_FREETYPE_LUNASVG) || defined (IMGUI_ENABLE_FREETYPE_PLUTOSVG)
|
||||
#if !((FREETYPE_MAJOR >= 2) && (FREETYPE_MINOR >= 12))
|
||||
#error IMGUI_ENABLE_FREETYPE_LUNASVG requires FreeType version >= 2.12
|
||||
#error IMGUI_ENABLE_FREETYPE_PLUTOSVG or IMGUI_ENABLE_FREETYPE_LUNASVG requires FreeType version >= 2.12
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -94,6 +104,9 @@ static FT_Error ImGuiLunasvgPortPresetSlot(FT_GlyphSlot slot, FT_Bool cache, FT_
|
||||
// Code
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
#define FT_CEIL(X) (((X + 63) & -64) / 64) // From SDL_ttf: Handy routines for converting from fixed point
|
||||
#define FT_SCALEFACTOR 64.0f
|
||||
|
||||
namespace
|
||||
{
|
||||
// Glyph metrics:
|
||||
@@ -159,6 +172,7 @@ namespace
|
||||
const FT_Glyph_Metrics* LoadGlyph(uint32_t in_codepoint);
|
||||
const FT_Bitmap* RenderGlyphAndGetInfo(GlyphInfo* out_glyph_info);
|
||||
void BlitGlyph(const FT_Bitmap* ft_bitmap, uint32_t* dst, uint32_t dst_pitch, unsigned char* multiply_table = nullptr);
|
||||
FreeTypeFont() { memset((void*)this, 0, sizeof(*this)); }
|
||||
~FreeTypeFont() { CloseFont(); }
|
||||
|
||||
// [Internals]
|
||||
@@ -171,9 +185,6 @@ namespace
|
||||
float InvRasterizationDensity;
|
||||
};
|
||||
|
||||
// From SDL_ttf: Handy routines for converting from fixed point
|
||||
#define FT_CEIL(X) (((X + 63) & -64) / 64)
|
||||
|
||||
bool FreeTypeFont::InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_font_builder_flags)
|
||||
{
|
||||
FT_Error error = FT_New_Memory_Face(ft_library, (uint8_t*)cfg.FontData, (uint32_t)cfg.FontDataSize, (uint32_t)cfg.FontNo, &Face);
|
||||
@@ -269,11 +280,11 @@ namespace
|
||||
|
||||
// Need an outline for this to work
|
||||
FT_GlyphSlot slot = Face->glyph;
|
||||
#ifdef IMGUI_ENABLE_FREETYPE_LUNASVG
|
||||
#if defined(IMGUI_ENABLE_FREETYPE_LUNASVG) || defined(IMGUI_ENABLE_FREETYPE_PLUTOSVG)
|
||||
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");
|
||||
IM_ASSERT(slot->format != FT_GLYPH_FORMAT_SVG && "The font contains SVG glyphs, you'll need to enable IMGUI_ENABLE_FREETYPE_PLUTOSVG or 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
|
||||
@@ -305,7 +316,7 @@ namespace
|
||||
out_glyph_info->Height = (int)ft_bitmap->rows;
|
||||
out_glyph_info->OffsetX = Face->glyph->bitmap_left;
|
||||
out_glyph_info->OffsetY = -Face->glyph->bitmap_top;
|
||||
out_glyph_info->AdvanceX = (float)FT_CEIL(slot->advance.x);
|
||||
out_glyph_info->AdvanceX = (float)slot->advance.x / FT_SCALEFACTOR;
|
||||
out_glyph_info->IsColored = (ft_bitmap->pixel_mode == FT_PIXEL_MODE_BGRA);
|
||||
|
||||
return ft_bitmap;
|
||||
@@ -480,8 +491,9 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
|
||||
for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
|
||||
{
|
||||
// Check for valid range. This may also help detect *some* dangling pointers, because a common
|
||||
// user error is to setup ImFontConfig::GlyphRanges with a pointer to data that isn't persistent.
|
||||
IM_ASSERT(src_range[0] <= src_range[1]);
|
||||
// user error is to setup ImFontConfig::GlyphRanges with a pointer to data that isn't persistent,
|
||||
// or to forget to zero-terminate the glyph range array.
|
||||
IM_ASSERT(src_range[0] <= src_range[1] && "Invalid range: is your glyph range array persistent? it is zero-terminated?");
|
||||
src_tmp.GlyphsHighest = ImMax(src_tmp.GlyphsHighest, (int)src_range[1]);
|
||||
}
|
||||
dst_tmp.SrcCount++;
|
||||
@@ -561,6 +573,7 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
|
||||
// 8. Render/rasterize font characters into the texture
|
||||
int total_surface = 0;
|
||||
int buf_rects_out_n = 0;
|
||||
const int pack_padding = atlas->TexGlyphPadding;
|
||||
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
|
||||
{
|
||||
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
|
||||
@@ -578,7 +591,6 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
|
||||
ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, cfg.RasterizerMultiply);
|
||||
|
||||
// Gather the sizes of all rectangles we will need to pack
|
||||
const int padding = atlas->TexGlyphPadding;
|
||||
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsList.Size; glyph_i++)
|
||||
{
|
||||
ImFontBuildSrcGlyphFT& src_glyph = src_tmp.GlyphsList[glyph_i];
|
||||
@@ -606,11 +618,13 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
|
||||
buf_bitmap_current_used_bytes += bitmap_size_in_bytes;
|
||||
src_tmp.Font.BlitGlyph(ft_bitmap, src_glyph.BitmapData, src_glyph.Info.Width, multiply_enabled ? multiply_table : nullptr);
|
||||
|
||||
src_tmp.Rects[glyph_i].w = (stbrp_coord)(src_glyph.Info.Width + padding);
|
||||
src_tmp.Rects[glyph_i].h = (stbrp_coord)(src_glyph.Info.Height + padding);
|
||||
src_tmp.Rects[glyph_i].w = (stbrp_coord)(src_glyph.Info.Width + pack_padding);
|
||||
src_tmp.Rects[glyph_i].h = (stbrp_coord)(src_glyph.Info.Height + pack_padding);
|
||||
total_surface += src_tmp.Rects[glyph_i].w * src_tmp.Rects[glyph_i].h;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < atlas->CustomRects.Size; i++)
|
||||
total_surface += (atlas->CustomRects[i].Width + pack_padding) * (atlas->CustomRects[i].Height + pack_padding);
|
||||
|
||||
// We need a width for the skyline algorithm, any width!
|
||||
// The exact width doesn't really matter much, but some API/GPU have texture size limitations and increasing width can decrease height.
|
||||
@@ -670,8 +684,6 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
|
||||
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
|
||||
{
|
||||
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
|
||||
if (src_tmp.GlyphsCount == 0)
|
||||
continue;
|
||||
|
||||
// When merging fonts with MergeMode=true:
|
||||
// - We can have multiple input fonts writing into a same destination font.
|
||||
@@ -682,6 +694,9 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
|
||||
const float ascent = src_tmp.Font.Info.Ascender;
|
||||
const float descent = src_tmp.Font.Info.Descender;
|
||||
ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent);
|
||||
|
||||
if (src_tmp.GlyphsCount == 0)
|
||||
continue;
|
||||
const float font_off_x = cfg.GlyphOffset.x;
|
||||
const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent);
|
||||
|
||||
@@ -809,6 +824,10 @@ static bool ImFontAtlasBuildWithFreeType(ImFontAtlas* atlas)
|
||||
SVG_RendererHooks hooks = { ImGuiLunasvgPortInit, ImGuiLunasvgPortFree, ImGuiLunasvgPortRender, ImGuiLunasvgPortPresetSlot };
|
||||
FT_Property_Set(ft_library, "ot-svg", "svg-hooks", &hooks);
|
||||
#endif // IMGUI_ENABLE_FREETYPE_LUNASVG
|
||||
#ifdef IMGUI_ENABLE_FREETYPE_PLUTOSVG
|
||||
// With plutosvg, use provided hooks
|
||||
FT_Property_Set(ft_library, "ot-svg", "svg-hooks", plutosvg_ft_svg_hooks());
|
||||
#endif // IMGUI_ENABLE_FREETYPE_PLUTOSVG
|
||||
|
||||
bool ret = ImFontAtlasBuildWithFreeTypeEx(ft_library, atlas, atlas->FontBuilderFlags);
|
||||
FT_Done_Library(ft_library);
|
||||
|
||||
3
3rdparty/imgui/src/imgui_stdlib.cpp
vendored
3
3rdparty/imgui/src/imgui_stdlib.cpp
vendored
@@ -8,6 +8,7 @@
|
||||
// https://github.com/ocornut/imgui/wiki/Useful-Extensions#cness
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_stdlib.h"
|
||||
|
||||
// Clang warnings with -Weverything
|
||||
@@ -83,3 +84,5 @@ bool ImGui::InputTextWithHint(const char* label, const char* hint, std::string*
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
136
3rdparty/imgui/src/imgui_tables.cpp
vendored
136
3rdparty/imgui/src/imgui_tables.cpp
vendored
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.91.0
|
||||
// dear imgui, v1.91.8
|
||||
// (tables and columns code)
|
||||
|
||||
/*
|
||||
@@ -229,9 +229,14 @@ Index of this file:
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"// warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
|
||||
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
|
||||
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access
|
||||
#pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
|
||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked
|
||||
#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function
|
||||
#pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'int'/'void*', but argument X has type 'unsigned int'/'ImGuiWindow*'
|
||||
#pragma GCC diagnostic ignored "-Wstrict-overflow"
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
||||
#endif
|
||||
|
||||
@@ -328,7 +333,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
// - always performing the GetOrAddByKey() O(log N) query in g.Tables.Map[].
|
||||
const bool use_child_window = (flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) != 0;
|
||||
const ImVec2 avail_size = GetContentRegionAvail();
|
||||
const ImVec2 actual_outer_size = CalcItemSize(outer_size, ImMax(avail_size.x, 1.0f), use_child_window ? ImMax(avail_size.y, 1.0f) : 0.0f);
|
||||
const ImVec2 actual_outer_size = ImTrunc(CalcItemSize(outer_size, ImMax(avail_size.x, 1.0f), use_child_window ? ImMax(avail_size.y, 1.0f) : 0.0f));
|
||||
const ImRect outer_rect(outer_window->DC.CursorPos, outer_window->DC.CursorPos + actual_outer_size);
|
||||
const bool outer_window_is_measuring_size = (outer_window->AutoFitFramesX > 0) || (outer_window->AutoFitFramesY > 0); // Doesn't apply to AlwaysAutoResize windows!
|
||||
if (use_child_window && IsClippedEx(outer_rect, 0) && !outer_window_is_measuring_size)
|
||||
@@ -369,6 +374,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
table->ColumnsCount = columns_count;
|
||||
table->IsLayoutLocked = false;
|
||||
table->InnerWidth = inner_width;
|
||||
table->NavLayer = (ImS8)outer_window->DC.NavLayerCurrent;
|
||||
temp_data->UserOuterSize = outer_size;
|
||||
|
||||
// Instance data (for instance 0, TableID == TableInstanceID)
|
||||
@@ -409,7 +415,8 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
|
||||
// Reset scroll if we are reactivating it
|
||||
if ((previous_flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) == 0)
|
||||
SetNextWindowScroll(ImVec2(0.0f, 0.0f));
|
||||
if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasScroll) == 0)
|
||||
SetNextWindowScroll(ImVec2(0.0f, 0.0f));
|
||||
|
||||
// Create scrolling region (without border and zero window padding)
|
||||
ImGuiWindowFlags child_window_flags = (flags & ImGuiTableFlags_ScrollX) ? ImGuiWindowFlags_HorizontalScrollbar : ImGuiWindowFlags_None;
|
||||
@@ -460,16 +467,27 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
temp_data->HostBackupItemWidthStackSize = outer_window->DC.ItemWidthStack.Size;
|
||||
inner_window->DC.PrevLineSize = inner_window->DC.CurrLineSize = ImVec2(0.0f, 0.0f);
|
||||
|
||||
// Make left and top borders not overlap our contents by offsetting HostClipRect (#6765)
|
||||
// Make borders not overlap our contents by offsetting HostClipRect (#6765, #7428, #3752)
|
||||
// (we normally shouldn't alter HostClipRect as we rely on TableMergeDrawChannels() expanding non-clipped column toward the
|
||||
// limits of that rectangle, in order for ImDrawListSplitter::Merge() to merge the draw commands. However since the overlap
|
||||
// problem only affect scrolling tables in this case we can get away with doing it without extra cost).
|
||||
if (inner_window != outer_window)
|
||||
{
|
||||
// FIXME: Because inner_window's Scrollbar doesn't know about border size, since it's not encoded in window->WindowBorderSize,
|
||||
// it already overlaps it and doesn't need an extra offset. Ideally we should be able to pass custom border size with
|
||||
// different x/y values to BeginChild().
|
||||
if (flags & ImGuiTableFlags_BordersOuterV)
|
||||
{
|
||||
table->HostClipRect.Min.x = ImMin(table->HostClipRect.Min.x + TABLE_BORDER_SIZE, table->HostClipRect.Max.x);
|
||||
if (inner_window->DecoOuterSizeX2 == 0.0f)
|
||||
table->HostClipRect.Max.x = ImMax(table->HostClipRect.Max.x - TABLE_BORDER_SIZE, table->HostClipRect.Min.x);
|
||||
}
|
||||
if (flags & ImGuiTableFlags_BordersOuterH)
|
||||
{
|
||||
table->HostClipRect.Min.y = ImMin(table->HostClipRect.Min.y + TABLE_BORDER_SIZE, table->HostClipRect.Max.y);
|
||||
if (inner_window->DecoOuterSizeY2 == 0.0f)
|
||||
table->HostClipRect.Max.y = ImMax(table->HostClipRect.Max.y - TABLE_BORDER_SIZE, table->HostClipRect.Min.y);
|
||||
}
|
||||
}
|
||||
|
||||
// Padding and Spacing
|
||||
@@ -497,7 +515,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
table->InnerClipRect = (inner_window == outer_window) ? table->WorkRect : inner_window->ClipRect;
|
||||
table->InnerClipRect.ClipWith(table->WorkRect); // We need this to honor inner_width
|
||||
table->InnerClipRect.ClipWithFull(table->HostClipRect);
|
||||
table->InnerClipRect.Max.y = (flags & ImGuiTableFlags_NoHostExtendY) ? ImMin(table->InnerClipRect.Max.y, inner_window->WorkRect.Max.y) : inner_window->ClipRect.Max.y;
|
||||
table->InnerClipRect.Max.y = (flags & ImGuiTableFlags_NoHostExtendY) ? ImMin(table->InnerClipRect.Max.y, inner_window->WorkRect.Max.y) : table->HostClipRect.Max.y;
|
||||
|
||||
table->RowPosY1 = table->RowPosY2 = table->WorkRect.Min.y; // This is needed somehow
|
||||
table->RowTextBaseline = 0.0f; // This will be cleared again by TableBeginRow()
|
||||
@@ -855,7 +873,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
||||
|
||||
// Calculate ideal/auto column width (that's the width required for all contents to be visible without clipping)
|
||||
// Combine width from regular rows + width from headers unless requested not to.
|
||||
if (!column->IsPreserveWidthAuto)
|
||||
if (!column->IsPreserveWidthAuto && table->InstanceCurrent == 0)
|
||||
column->WidthAuto = TableGetColumnWidthAuto(table, column);
|
||||
|
||||
// Non-resizable columns keep their requested width (apply user value regardless of IsPreserveWidthAuto)
|
||||
@@ -1033,7 +1051,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
||||
const int column_n = table->DisplayOrderToIndex[order_n];
|
||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||
|
||||
column->NavLayerCurrent = (ImS8)(table->FreezeRowsCount > 0 ? ImGuiNavLayer_Menu : ImGuiNavLayer_Main); // Use Count NOT request so Header line changes layer when frozen
|
||||
// Initial nav layer: using FreezeRowsCount, NOT FreezeRowsRequest, so Header line changes layer when frozen
|
||||
column->NavLayerCurrent = (ImS8)(table->FreezeRowsCount > 0 ? ImGuiNavLayer_Menu : (ImGuiNavLayer)table->NavLayer);
|
||||
|
||||
if (offset_x_frozen && table->FreezeColumnsCount == visible_n)
|
||||
{
|
||||
@@ -1059,16 +1078,12 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
||||
continue;
|
||||
}
|
||||
|
||||
// Detect hovered column
|
||||
if (is_hovering_table && mouse_skewed_x >= column->ClipRect.Min.x && mouse_skewed_x < column->ClipRect.Max.x)
|
||||
table->HoveredColumnBody = (ImGuiTableColumnIdx)column_n;
|
||||
|
||||
// Lock start position
|
||||
column->MinX = offset_x;
|
||||
|
||||
// Lock width based on start position and minimum/maximum width for this position
|
||||
float max_width = TableGetMaxColumnWidth(table, column_n);
|
||||
column->WidthGiven = ImMin(column->WidthGiven, max_width);
|
||||
column->WidthMax = TableCalcMaxColumnWidth(table, column_n);
|
||||
column->WidthGiven = ImMin(column->WidthGiven, column->WidthMax);
|
||||
column->WidthGiven = ImMax(column->WidthGiven, ImMin(column->WidthRequest, table->MinColumnWidth));
|
||||
column->MaxX = offset_x + column->WidthGiven + table->CellSpacingX1 + table->CellSpacingX2 + table->CellPaddingX * 2.0f;
|
||||
|
||||
@@ -1117,8 +1132,13 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
||||
column->Flags |= ImGuiTableColumnFlags_IsVisible;
|
||||
if (column->SortOrder != -1)
|
||||
column->Flags |= ImGuiTableColumnFlags_IsSorted;
|
||||
if (table->HoveredColumnBody == column_n)
|
||||
|
||||
// Detect hovered column
|
||||
if (is_hovering_table && mouse_skewed_x >= column->ClipRect.Min.x && mouse_skewed_x < column->ClipRect.Max.x)
|
||||
{
|
||||
column->Flags |= ImGuiTableColumnFlags_IsHovered;
|
||||
table->HoveredColumnBody = (ImGuiTableColumnIdx)column_n;
|
||||
}
|
||||
|
||||
// Alignment
|
||||
// FIXME-TABLE: This align based on the whole column width, not per-cell, and therefore isn't useful in
|
||||
@@ -1148,7 +1168,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
||||
}
|
||||
|
||||
// Don't decrement auto-fit counters until container window got a chance to submit its items
|
||||
if (table->HostSkipItems == false)
|
||||
if (table->HostSkipItems == false && table->InstanceCurrent == 0)
|
||||
{
|
||||
column->AutoFitQueue >>= 1;
|
||||
column->CannotSkipItemsQueue >>= 1;
|
||||
@@ -1249,7 +1269,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
||||
if (table->Flags & ImGuiTableFlags_NoClip)
|
||||
table->DrawSplitter->SetCurrentChannel(inner_window->DrawList, TABLE_DRAW_CHANNEL_NOCLIP);
|
||||
else
|
||||
inner_window->DrawList->PushClipRect(inner_window->ClipRect.Min, inner_window->ClipRect.Max, false);
|
||||
inner_window->DrawList->PushClipRect(inner_window->InnerClipRect.Min, inner_window->InnerClipRect.Max, false); // FIXME: use table->InnerClipRect?
|
||||
}
|
||||
|
||||
// Process hit-testing on resizing borders. Actual size change will be applied in EndTable()
|
||||
@@ -1319,7 +1339,11 @@ void ImGui::EndTable()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
IM_ASSERT(table != NULL && "Only call EndTable() if BeginTable() returns true!");
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "EndTable() call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
|
||||
// This assert would be very useful to catch a common error... unfortunately it would probably trigger in some
|
||||
// cases, and for consistency user may sometimes output empty tables (and still benefit from e.g. outer border)
|
||||
@@ -1471,8 +1495,10 @@ void ImGui::EndTable()
|
||||
if (inner_window != outer_window)
|
||||
{
|
||||
short backup_nav_layers_active_mask = inner_window->DC.NavLayersActiveMask;
|
||||
inner_window->DC.NavLayersActiveMask |= 1 << ImGuiNavLayer_Main; // So empty table don't appear to navigate differently.
|
||||
inner_window->DC.NavLayersActiveMask |= 1 << table->NavLayer; // So empty table don't appear to navigate differently.
|
||||
g.CurrentTable = NULL; // To avoid error recovery recursing
|
||||
EndChild();
|
||||
g.CurrentTable = table;
|
||||
inner_window->DC.NavLayersActiveMask = backup_nav_layers_active_mask;
|
||||
}
|
||||
else
|
||||
@@ -1540,8 +1566,12 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
IM_ASSERT(table != NULL && "Need to call TableSetupColumn() after BeginTable()!");
|
||||
IM_ASSERT(table->IsLayoutLocked == false && "Need to call call TableSetupColumn() before first row!");
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT(table->IsLayoutLocked == false && "Need to call TableSetupColumn() before first row!");
|
||||
IM_ASSERT((flags & ImGuiTableColumnFlags_StatusMask_) == 0 && "Illegal to pass StatusMask values to TableSetupColumn()");
|
||||
if (table->DeclColumnsCount >= table->ColumnsCount)
|
||||
{
|
||||
@@ -1614,7 +1644,11 @@ void ImGui::TableSetupScrollFreeze(int columns, int rows)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
IM_ASSERT(table != NULL && "Need to call TableSetupColumn() after BeginTable()!");
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT(table->IsLayoutLocked == false && "Need to call TableSetupColumn() before first row!");
|
||||
IM_ASSERT(columns >= 0 && columns < IMGUI_TABLE_MAX_COLUMNS);
|
||||
IM_ASSERT(rows >= 0 && rows < 128); // Arbitrary limit
|
||||
@@ -1691,9 +1725,11 @@ void ImGui::TableSetColumnEnabled(int column_n, bool enabled)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
IM_ASSERT(table != NULL);
|
||||
if (!table)
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT(table->Flags & ImGuiTableFlags_Hideable); // See comments above
|
||||
if (column_n < 0)
|
||||
column_n = table->CurrentColumn;
|
||||
@@ -1998,8 +2034,8 @@ void ImGui::TableEndRow(ImGuiTable* table)
|
||||
if (unfreeze_rows_request)
|
||||
{
|
||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||
table->Columns[column_n].NavLayerCurrent = ImGuiNavLayer_Main;
|
||||
const float y0 = ImMax(table->RowPosY2 + 1, window->InnerClipRect.Min.y);
|
||||
table->Columns[column_n].NavLayerCurrent = table->NavLayer;
|
||||
const float y0 = ImMax(table->RowPosY2 + 1, table->InnerClipRect.Min.y);
|
||||
table_instance->LastFrozenHeight = y0 - table->OuterRect.Min.y;
|
||||
|
||||
if (unfreeze_rows_actual)
|
||||
@@ -2008,8 +2044,8 @@ void ImGui::TableEndRow(ImGuiTable* table)
|
||||
table->IsUnfrozenRows = true;
|
||||
|
||||
// BgClipRect starts as table->InnerClipRect, reduce it now and make BgClipRectForDrawCmd == BgClipRect
|
||||
table->BgClipRect.Min.y = table->Bg2ClipRectForDrawCmd.Min.y = ImMin(y0, window->InnerClipRect.Max.y);
|
||||
table->BgClipRect.Max.y = table->Bg2ClipRectForDrawCmd.Max.y = window->InnerClipRect.Max.y;
|
||||
table->BgClipRect.Min.y = table->Bg2ClipRectForDrawCmd.Min.y = ImMin(y0, table->InnerClipRect.Max.y);
|
||||
table->BgClipRect.Max.y = table->Bg2ClipRectForDrawCmd.Max.y = table->InnerClipRect.Max.y;
|
||||
table->Bg2DrawChannelCurrent = table->Bg2DrawChannelUnfrozen;
|
||||
IM_ASSERT(table->Bg2ClipRectForDrawCmd.Min.y <= table->Bg2ClipRectForDrawCmd.Max.y);
|
||||
|
||||
@@ -2195,8 +2231,8 @@ void ImGui::TableEndCell(ImGuiTable* table)
|
||||
// Note that actual columns widths are computed in TableUpdateLayout().
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Maximum column content width given current layout. Use column->MinX so this value on a per-column basis.
|
||||
float ImGui::TableGetMaxColumnWidth(const ImGuiTable* table, int column_n)
|
||||
// Maximum column content width given current layout. Use column->MinX so this value differs on a per-column basis.
|
||||
float ImGui::TableCalcMaxColumnWidth(const ImGuiTable* table, int column_n)
|
||||
{
|
||||
const ImGuiTableColumn* column = &table->Columns[column_n];
|
||||
float max_width = FLT_MAX;
|
||||
@@ -2258,7 +2294,7 @@ void ImGui::TableSetColumnWidth(int column_n, float width)
|
||||
// Compare both requested and actual given width to avoid overwriting requested width when column is stuck (minimum size, bounded)
|
||||
IM_ASSERT(table->MinColumnWidth > 0.0f);
|
||||
const float min_width = table->MinColumnWidth;
|
||||
const float max_width = ImMax(min_width, TableGetMaxColumnWidth(table, column_n));
|
||||
const float max_width = ImMax(min_width, column_0->WidthMax); // Don't use TableCalcMaxColumnWidth() here as it would rely on MinX from last instance (#7933)
|
||||
column_0_width = ImClamp(column_0_width, min_width, max_width);
|
||||
if (column_0->WidthGiven == column_0_width || column_0->WidthRequest == column_0_width)
|
||||
return;
|
||||
@@ -2743,7 +2779,7 @@ void ImGui::TableDrawBorders(ImGuiTable* table)
|
||||
const ImU32 outer_col = table->BorderColorStrong;
|
||||
if ((table->Flags & ImGuiTableFlags_BordersOuter) == ImGuiTableFlags_BordersOuter)
|
||||
{
|
||||
inner_drawlist->AddRect(outer_border.Min, outer_border.Max + ImVec2(1, 1), outer_col, 0.0f, 0, border_size);
|
||||
inner_drawlist->AddRect(outer_border.Min, outer_border.Max, outer_col, 0.0f, 0, border_size);
|
||||
}
|
||||
else if (table->Flags & ImGuiTableFlags_BordersOuterV)
|
||||
{
|
||||
@@ -3007,15 +3043,21 @@ float ImGui::TableGetHeaderAngledMaxLabelWidth()
|
||||
// The intent is that advanced users willing to create customized headers would not need to use this helper
|
||||
// and can create their own! For example: TableHeader() may be preceded by Checkbox() or other custom widgets.
|
||||
// See 'Demo->Tables->Custom headers' for a demonstration of implementing a custom version of this.
|
||||
// This code is constructed to not make much use of internal functions, as it is intended to be a template to copy.
|
||||
// This code is intentionally written to not make much use of internal functions, to give you better direction
|
||||
// if you need to write your own.
|
||||
// FIXME-TABLE: TableOpenContextMenu() and TableGetHeaderRowHeight() are not public.
|
||||
void ImGui::TableHeadersRow()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
IM_ASSERT(table != NULL && "Need to call TableHeadersRow() after BeginTable()!");
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Layout if not already done (this is automatically done by TableNextRow, we do it here solely to facilitate stepping in debugger as it is frequent to step in TableUpdateLayout)
|
||||
// Call layout if not already done. This is automatically done by TableNextRow: we do it here _only_ to make
|
||||
// it easier to debug-step in TableUpdateLayout(). Your own version of this function doesn't need this.
|
||||
if (!table->IsLayoutLocked)
|
||||
TableUpdateLayout(table);
|
||||
|
||||
@@ -3032,8 +3074,7 @@ void ImGui::TableHeadersRow()
|
||||
if (!TableSetColumnIndex(column_n))
|
||||
continue;
|
||||
|
||||
// Push an id to allow unnamed labels (generally accidental, but let's behave nicely with them)
|
||||
// In your own code you may omit the PushID/PopID all-together, provided you know they won't collide.
|
||||
// Push an id to allow empty/unnamed headers. This is also idiomatic as it ensure there is a consistent ID path to access columns (for e.g. automation)
|
||||
const char* name = (TableGetColumnFlags(column_n) & ImGuiTableColumnFlags_NoHeaderLabel) ? "" : TableGetColumnName(column_n);
|
||||
PushID(column_n);
|
||||
TableHeader(name);
|
||||
@@ -3058,7 +3099,12 @@ void ImGui::TableHeader(const char* label)
|
||||
return;
|
||||
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
IM_ASSERT(table != NULL && "Need to call TableHeader() after BeginTable()!");
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
|
||||
IM_ASSERT(table->CurrentColumn != -1);
|
||||
const int column_n = table->CurrentColumn;
|
||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||
@@ -3124,7 +3170,7 @@ void ImGui::TableHeader(const char* label)
|
||||
if ((table->RowFlags & ImGuiTableRowFlags_Headers) == 0)
|
||||
TableSetBgColor(ImGuiTableBgTarget_CellBg, GetColorU32(ImGuiCol_TableHeaderBg), table->CurrentColumn);
|
||||
}
|
||||
RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_Compact | ImGuiNavHighlightFlags_NoRounding);
|
||||
RenderNavCursor(bb, id, ImGuiNavRenderCursorFlags_Compact | ImGuiNavRenderCursorFlags_NoRounding);
|
||||
if (held)
|
||||
table->HeldHeaderColumn = (ImGuiTableColumnIdx)column_n;
|
||||
window->DC.CursorPos.y -= g.Style.ItemSpacing.y * 0.5f;
|
||||
@@ -3233,7 +3279,11 @@ void ImGui::TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
ImDrawList* draw_list = window->DrawList;
|
||||
IM_ASSERT(table != NULL && "Need to call TableHeadersRow() after BeginTable()!");
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT(table->CurrentRow == -1 && "Must be first row");
|
||||
|
||||
if (max_label_width == 0.0f)
|
||||
@@ -3278,7 +3328,7 @@ void ImGui::TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label
|
||||
const ImVec2 align = g.Style.TableAngledHeadersTextAlign;
|
||||
|
||||
// Draw background and labels in first pass, then all borders.
|
||||
float max_x = 0.0f;
|
||||
float max_x = -FLT_MAX;
|
||||
for (int pass = 0; pass < 2; pass++)
|
||||
for (int order_n = 0; order_n < data_count; order_n++)
|
||||
{
|
||||
@@ -4396,7 +4446,7 @@ void ImGui::EndColumns()
|
||||
{
|
||||
ButtonBehavior(column_hit_rect, column_id, &hovered, &held);
|
||||
if (hovered || held)
|
||||
g.MouseCursor = ImGuiMouseCursor_ResizeEW;
|
||||
SetMouseCursor(ImGuiMouseCursor_ResizeEW);
|
||||
if (held && !(column->Flags & ImGuiOldColumnFlags_NoResize))
|
||||
dragging_column = n;
|
||||
}
|
||||
@@ -4428,12 +4478,12 @@ void ImGui::EndColumns()
|
||||
NavUpdateCurrentWindowIsScrollPushableX();
|
||||
}
|
||||
|
||||
void ImGui::Columns(int columns_count, const char* id, bool border)
|
||||
void ImGui::Columns(int columns_count, const char* id, bool borders)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
IM_ASSERT(columns_count >= 1);
|
||||
|
||||
ImGuiOldColumnFlags flags = (border ? 0 : ImGuiOldColumnFlags_NoBorder);
|
||||
ImGuiOldColumnFlags flags = (borders ? 0 : ImGuiOldColumnFlags_NoBorder);
|
||||
//flags |= ImGuiOldColumnFlags_NoPreserveWidths; // NB: Legacy behavior
|
||||
ImGuiOldColumns* columns = window->DC.CurrentColumns;
|
||||
if (columns != NULL && columns->Count == columns_count && columns->Flags == flags)
|
||||
|
||||
1307
3rdparty/imgui/src/imgui_widgets.cpp
vendored
1307
3rdparty/imgui/src/imgui_widgets.cpp
vendored
File diff suppressed because it is too large
Load Diff
291
3rdparty/promptfont/promptfont.sfd
vendored
291
3rdparty/promptfont/promptfont.sfd
vendored
@@ -23,7 +23,7 @@ OS2Version: 0
|
||||
OS2_WeightWidthSlopeOnly: 0
|
||||
OS2_UseTypoMetrics: 0
|
||||
CreationTime: 1544355305
|
||||
ModificationTime: 1712653578
|
||||
ModificationTime: 1736751870
|
||||
PfmFamily: 33
|
||||
TTFWeight: 400
|
||||
TTFWidth: 5
|
||||
@@ -65,7 +65,7 @@ NameList: AGL For New Fonts
|
||||
DisplaySize: -48
|
||||
AntiAlias: 1
|
||||
FitToEm: 0
|
||||
WinInfo: 8816 38 14
|
||||
WinInfo: 8360 38 14
|
||||
BeginPrivate: 8
|
||||
BlueValues 29 [0 0 380 380 490 490 660 660]
|
||||
OtherBlues 39 [-210 -210 -180 -180 -160 -160 280 280]
|
||||
@@ -77,7 +77,7 @@ StemSnapV 13 [140 180 200]
|
||||
ForceBold 4 true
|
||||
EndPrivate
|
||||
TeXData: 1 0 0 335544 167772 111848 513802 1048576 111848 783286 444596 497025 792723 393216 433062 380633 303038 157286 324010 404750 52429 2506097 1059062 262144
|
||||
BeginChars: 1114112 731
|
||||
BeginChars: 1114112 733
|
||||
|
||||
StartChar: exclam
|
||||
Encoding: 33 33 0
|
||||
@@ -19511,40 +19511,40 @@ VStem: 92.5596 41.7305<171.236 408.764> 189.39 149.051<176.142 403.858> 699.66 1
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
500 600.610351562 m 1
|
||||
671.459960938 600.610351562 810.610351562 461.459960938 810.610351562 290 c 0
|
||||
810.610351562 118.540039062 671.459960938 -20.6103515625 500 -20.6103515625 c 0
|
||||
328.540039062 -20.6103515625 189.389648438 118.540039062 189.389648438 290 c 0
|
||||
189.389648438 461.459960938 328.540039062 600.610351562 500 600.610351562 c 1
|
||||
699.66015625 102.129882812 m 1
|
||||
699.66015625 167.830078125 l 1
|
||||
456.870117188 167.830078125 l 1
|
||||
456.870117188 463.459960938 l 1
|
||||
338.440429688 463.459960938 l 1
|
||||
338.440429688 102.129882812 l 1
|
||||
699.66015625 102.129882812 l 1
|
||||
500 -117.440429688 m 0
|
||||
445 -117.440429688 391.639648438 -106.66015625 341.400390625 -85.41015625 c 0
|
||||
292.879882812 -64.8896484375 249.309570312 -35.509765625 211.900390625 1.900390625 c 0
|
||||
174.490234375 39.3095703125 145.110351562 82.8798828125 124.58984375 131.400390625 c 0
|
||||
103.33984375 181.639648438 92.5595703125 235.009765625 92.5595703125 290 c 0
|
||||
92.5595703125 344.990234375 103.33984375 398.360351562 124.58984375 448.599609375 c 0
|
||||
145.110351562 497.120117188 174.490234375 540.690429688 211.900390625 578.099609375 c 0
|
||||
249.309570312 615.509765625 292.879882812 644.889648438 341.400390625 665.41015625 c 0
|
||||
391.639648438 686.66015625 445.009765625 697.440429688 500 697.440429688 c 0
|
||||
554.990234375 697.440429688 608.360351562 686.66015625 658.599609375 665.41015625 c 0
|
||||
707.120117188 644.889648438 750.690429688 615.509765625 788.099609375 578.099609375 c 0
|
||||
825.509765625 540.690429688 854.889648438 497.120117188 875.41015625 448.599609375 c 0
|
||||
896.66015625 398.360351562 907.440429688 344.990234375 907.440429688 290 c 0
|
||||
907.440429688 235.009765625 896.66015625 181.639648438 875.41015625 131.400390625 c 0
|
||||
854.889648438 82.8798828125 825.509765625 39.3095703125 788.099609375 1.900390625 c 0
|
||||
750.690429688 -35.509765625 707.120117188 -64.8896484375 658.599609375 -85.41015625 c 0
|
||||
608.360351562 -106.66015625 554.990234375 -117.440429688 500 -117.440429688 c 0
|
||||
500 655.709960938 m 0
|
||||
298.349609375 655.709960938 134.290039062 491.66015625 134.290039062 290 c 0
|
||||
134.290039062 88.33984375 298.33984375 -75.7099609375 500 -75.7099609375 c 0
|
||||
701.66015625 -75.7099609375 865.709960938 88.349609375 865.709960938 290 c 0
|
||||
865.709960938 491.650390625 701.66015625 655.709960938 500 655.709960938 c 0
|
||||
500 600.610351562 m 5
|
||||
671.459960938 600.610351562 810.610351562 461.459960938 810.610351562 290 c 4
|
||||
810.610351562 118.540039062 671.459960938 -20.6103515625 500 -20.6103515625 c 4
|
||||
328.540039062 -20.6103515625 189.389648438 118.540039062 189.389648438 290 c 4
|
||||
189.389648438 461.459960938 328.540039062 600.610351562 500 600.610351562 c 5
|
||||
699.66015625 102.129882812 m 5
|
||||
699.66015625 167.830078125 l 5
|
||||
456.870117188 167.830078125 l 5
|
||||
456.870117188 463.459960938 l 5
|
||||
338.440429688 463.459960938 l 5
|
||||
338.440429688 102.129882812 l 5
|
||||
699.66015625 102.129882812 l 5
|
||||
500 -117.440429688 m 4
|
||||
445 -117.440429688 391.639648438 -106.66015625 341.400390625 -85.41015625 c 4
|
||||
292.879882812 -64.8896484375 249.309570312 -35.509765625 211.900390625 1.900390625 c 4
|
||||
174.490234375 39.3095703125 145.110351562 82.8798828125 124.58984375 131.400390625 c 4
|
||||
103.33984375 181.639648438 92.5595703125 235.009765625 92.5595703125 290 c 4
|
||||
92.5595703125 344.990234375 103.33984375 398.360351562 124.58984375 448.599609375 c 4
|
||||
145.110351562 497.120117188 174.490234375 540.690429688 211.900390625 578.099609375 c 4
|
||||
249.309570312 615.509765625 292.879882812 644.889648438 341.400390625 665.41015625 c 4
|
||||
391.639648438 686.66015625 445.009765625 697.440429688 500 697.440429688 c 4
|
||||
554.990234375 697.440429688 608.360351562 686.66015625 658.599609375 665.41015625 c 4
|
||||
707.120117188 644.889648438 750.690429688 615.509765625 788.099609375 578.099609375 c 4
|
||||
825.509765625 540.690429688 854.889648438 497.120117188 875.41015625 448.599609375 c 4
|
||||
896.66015625 398.360351562 907.440429688 344.990234375 907.440429688 290 c 4
|
||||
907.440429688 235.009765625 896.66015625 181.639648438 875.41015625 131.400390625 c 4
|
||||
854.889648438 82.8798828125 825.509765625 39.3095703125 788.099609375 1.900390625 c 4
|
||||
750.690429688 -35.509765625 707.120117188 -64.8896484375 658.599609375 -85.41015625 c 4
|
||||
608.360351562 -106.66015625 554.990234375 -117.440429688 500 -117.440429688 c 4
|
||||
500 655.709960938 m 4
|
||||
298.349609375 655.709960938 134.290039062 491.66015625 134.290039062 290 c 4
|
||||
134.290039062 88.33984375 298.33984375 -75.7099609375 500 -75.7099609375 c 4
|
||||
701.66015625 -75.7099609375 865.709960938 88.349609375 865.709960938 290 c 4
|
||||
865.709960938 491.650390625 701.66015625 655.709960938 500 655.709960938 c 4
|
||||
EndSplineSet
|
||||
Validated: 5
|
||||
EndChar
|
||||
@@ -30101,7 +30101,7 @@ SplineSet
|
||||
79 -59.400390625 120 -102.200195312 170.799804688 -102.200195312 c 2
|
||||
838.200195312 -102.200195312 l 2
|
||||
EndSplineSet
|
||||
Validated: 524321
|
||||
Validated: 33
|
||||
EndChar
|
||||
|
||||
StartChar: uni23F6
|
||||
@@ -30171,7 +30171,7 @@ SplineSet
|
||||
79 -59.400390625 120 -102.200195312 170.799804688 -102.200195312 c 2
|
||||
838.200195312 -102.200195312 l 1
|
||||
EndSplineSet
|
||||
Validated: 524321
|
||||
Validated: 33
|
||||
EndChar
|
||||
|
||||
StartChar: uni23F7
|
||||
@@ -35271,5 +35271,218 @@ SplineSet
|
||||
EndSplineSet
|
||||
Validated: 1
|
||||
EndChar
|
||||
|
||||
StartChar: uni2446
|
||||
Encoding: 9286 9286 731
|
||||
Width: 1000
|
||||
HStem: 98.667 78.666<441.304 558.479> 298.667 80.666<211.095 321.99 686.039 796.635> 364 81.333<440.808 559.266> 544.667 80.666<210.809 321.868 685.514 796.925>
|
||||
VStem: 104 80<406.859 516.049> 326.667 80<269.844 311.038> 349.333 80<429.563 517.407> 578.667 80<424.535 517.66> 593.333 80.667<270.25 314.708> 824 80<406.439 515.845>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
869.333007812 361.333007812 m 1x9840
|
||||
887.333007812 310.666992188 925.333007812 194 915.333007812 116.666992188 c 0
|
||||
902 10.6669921875 842.666992188 -30.6669921875 836 -35.3330078125 c 0
|
||||
832 -38.6669921875 827.333007812 -40 822 -41.3330078125 c 0
|
||||
812 -43.3330078125 802 -44 792 -44 c 0
|
||||
770.666992188 -44 750 -39.3330078125 732.666992188 -30.6669921875 c 0
|
||||
708 -18.6669921875 690 1.3330078125 676 30 c 0
|
||||
654 76 656 148 662 194.666992188 c 1
|
||||
661.333007812 194 658.666992188 194.666992188 655.333007812 195.333007812 c 0
|
||||
627.333007812 138 568 98.6669921875 500 98.6669921875 c 0
|
||||
431.333007812 98.6669921875 372 138.666992188 344 196 c 0
|
||||
340 195.333007812 336 194 334.666992188 194.666992188 c 1
|
||||
342.666992188 135.333007812 344.666992188 73.3330078125 324 30 c 0
|
||||
310 1.3330078125 291.333007812 -18.6669921875 267.333007812 -30.6669921875 c 0
|
||||
241.333007812 -43.3330078125 210 -46.6669921875 178 -40.6669921875 c 0
|
||||
172.666992188 -40 168 -38 164 -35.3330078125 c 0
|
||||
157.333007812 -31.3330078125 98 10.6669921875 84.6669921875 116.666992188 c 0
|
||||
74.6669921875 199.333007812 116 323.333007812 133.333007812 369.333007812 c 1
|
||||
114.666992188 396 104 428 104 462.666992188 c 0
|
||||
104 552 176.666992188 625.333007812 266.666992188 625.333007812 c 0
|
||||
299.333007812 625.333007812 329.333007812 615.333007812 354.666992188 599.333007812 c 1
|
||||
385.333007812 646 436 677.333007812 492.666992188 681.333007812 c 0
|
||||
557.333007812 685.333007812 619.333007812 653.333007812 655.333007812 600 c 1
|
||||
680.666992188 615.333007812 710 624.666992188 741.333007812 624.666992188 c 0
|
||||
830.666992188 624.666992188 904 552 904 462 c 0
|
||||
904 424 891.333007812 389.333007812 869.333007812 361.333007812 c 1x9840
|
||||
741.333007812 544.666992188 m 0
|
||||
695.333007812 544.666992188 658.666992188 507.333007812 658.666992188 462 c 0
|
||||
658.666992188 416.666992188 696 379.333007812 741.333007812 379.333007812 c 0xd940
|
||||
786.666992188 379.333007812 824 416.666992188 824 462 c 0
|
||||
824 507.333007812 786.666992188 544.666992188 741.333007812 544.666992188 c 0
|
||||
498 601.333007812 m 0
|
||||
459.333007812 598.666992188 426 572.666992188 411.333007812 536.666992188 c 0
|
||||
422.666992188 514.666992188 429.333007812 489.333007812 429.333007812 462.666992188 c 0
|
||||
429.333007812 450.666992188 428 439.333007812 426 428.666992188 c 1
|
||||
448 439.333007812 473.333007812 445.333007812 500 445.333007812 c 0xbb40
|
||||
530.666992188 445.333007812 558.666992188 437.333007812 583.333007812 424 c 1
|
||||
580 436 578.666992188 448.666992188 578.666992188 462 c 0
|
||||
578.666992188 490 585.333007812 516 598 539.333007812 c 0
|
||||
580 579.333007812 540 604 498 601.333007812 c 0
|
||||
266.666992188 544.666992188 m 0
|
||||
220.666992188 544.666992188 184 507.333007812 184 462 c 0
|
||||
184 416.666992188 221.333007812 379.333007812 266.666992188 379.333007812 c 0xda40
|
||||
312 379.333007812 349.333007812 416.666992188 349.333007812 462 c 0
|
||||
349.333007812 507.333007812 312 544.666992188 266.666992188 544.666992188 c 0
|
||||
305.333007812 270 m 2
|
||||
310.666992188 271.333007812 318.666992188 273.333007812 326.666992188 274 c 0xdc40
|
||||
326.666992188 287.333007812 328 300 331.333007812 312 c 1
|
||||
311.333007812 303.333007812 290 298.666992188 266.666992188 298.666992188 c 0
|
||||
240.666992188 298.666992188 216 305.333007812 194 316 c 1
|
||||
174.666992188 259.333007812 152.666992188 176 159.333007812 123.333007812 c 0
|
||||
164 82.6669921875 178 56 189.333007812 39.3330078125 c 0
|
||||
198.666992188 26.6669921875 216 20.6669921875 230.666992188 28 c 1
|
||||
234 29.3330078125 244 34.6669921875 254 56 c 0
|
||||
273.333007812 96 260 180 255.333007812 212 c 2
|
||||
255.333007812 212.666992188 l 2
|
||||
251.333007812 236.666992188 267.333007812 259.333007812 293.333007812 266.666992188 c 2
|
||||
305.333007812 270 l 2
|
||||
500 177.333007812 m 0
|
||||
551.333007812 177.333007812 593.333007812 219.333007812 593.333007812 270.666992188 c 0
|
||||
593.333007812 322 551.333007812 364 500 364 c 0xbcc0
|
||||
448.666992188 364 406.666992188 322 406.666992188 270.666992188 c 0
|
||||
406.666992188 219.333007812 448.666992188 177.333007812 500 177.333007812 c 0
|
||||
840.666992188 123.333007812 m 0
|
||||
846.666992188 174.666992188 826 256 808 311.333007812 c 1
|
||||
788 302.666992188 765.333007812 297.333007812 742 297.333007812 c 0
|
||||
715.333007812 297.333007812 690 304 668 315.333007812 c 1
|
||||
671.333007812 302 673.333007812 288 674 274 c 0
|
||||
684 273.333007812 694.666992188 271.333007812 701.333007812 268 c 2
|
||||
708.666992188 264.666992188 l 2
|
||||
729.333007812 254.666992188 741.333007812 234.666992188 738 213.333007812 c 2
|
||||
738 212 l 2
|
||||
734 183.333007812 726.666992188 95.3330078125 746 55.3330078125 c 0
|
||||
756 34 766 29.3330078125 769.333007812 27.3330078125 c 1
|
||||
784 20.6669921875 801.333007812 26 810.666992188 39.3330078125 c 0
|
||||
822 56 835.333007812 82.6669921875 840.666992188 123.333007812 c 0
|
||||
EndSplineSet
|
||||
Validated: 524321
|
||||
EndChar
|
||||
|
||||
StartChar: uni221B
|
||||
Encoding: 8731 8731 732
|
||||
Width: 1000
|
||||
HStem: -209.992 21.2588<741.927 862.934> -160.664 62.5283<723.687 881.174> 85.9395 69.8691<723.687 780.459> 183.879 21.2588<741.929 862.934>
|
||||
VStem: 594.865 21.2588<-62.9303 58.0754> 644.194 75.9316<-81.1715 76.316> 904.145 56.5225<-89.7754 -64.665> 988.736 21.2598<-62.9292 58.0743>
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
133.1953125 240.114257812 m 1
|
||||
128.731445312 224.2734375 135.630859375 215.740234375 135.630859375 215.740234375 c 1
|
||||
158.787109375 176.336914062 l 1
|
||||
148.629882812 119.875976562 174.627929688 78.4345703125 190.466796875 57.7236328125 c 0
|
||||
206.305664062 37.001953125 310.713867188 -99.0751953125 323.712890625 -114.518554688 c 0
|
||||
336.711914062 -129.954101562 389.11328125 -183.991210938 445.583984375 -142.953125 c 0
|
||||
502.044921875 -101.926757812 483.362304688 -32.052734375 483.362304688 -32.052734375 c 1
|
||||
459.1875 57.931640625 l 1
|
||||
589.7890625 74.3857421875 547.140625 186.911132812 547.140625 186.911132812 c 1
|
||||
601.831054688 241.602539062 l 1
|
||||
601.831054688 241.602539062 714.356445312 198.951171875 730.811523438 329.545898438 c 1
|
||||
820.79296875 305.37890625 l 1
|
||||
820.79296875 305.37890625 890.669921875 286.688476562 931.6953125 343.159179688 c 0
|
||||
972.721679688 399.619140625 918.696289062 452.03125 903.262695312 465.030273438 c 0
|
||||
887.829101562 478.029296875 751.73828125 582.424804688 731.018554688 598.275390625 c 0
|
||||
710.296875 614.114257812 668.864257812 640.114257812 612.404296875 629.965820312 c 1
|
||||
573.001953125 653.122070312 l 1
|
||||
573.001953125 653.122070312 564.466796875 660.03125 548.627929688 655.55859375 c 2
|
||||
548.627929688 655.55859375 543.954101562 661.450195312 532.172851562 654.5390625 c 0
|
||||
520.391601562 647.627929688 493.986328125 630.569335938 477.126953125 596.651367188 c 1
|
||||
477.126953125 596.651367188 474.28515625 591.78125 480.166015625 586.296875 c 1
|
||||
480.166015625 586.296875 474.078125 568.424804688 482.6015625 555.021484375 c 0
|
||||
491.13671875 541.616210938 501.688476562 524.559570312 501.688476562 524.559570312 c 1
|
||||
264.205078125 287.03125 l 1
|
||||
264.205078125 287.03125 247.146484375 297.59375 233.741210938 306.119140625 c 0
|
||||
220.337890625 314.654296875 202.465820312 308.553710938 202.465820312 308.553710938 c 1
|
||||
196.981445312 314.444335938 192.1015625 311.604492188 192.1015625 311.604492188 c 1
|
||||
158.18359375 294.744140625 141.125 268.340820312 134.213867188 256.559570312 c 0
|
||||
127.3046875 244.786132812 133.1953125 240.114257812 133.1953125 240.114257812 c 1
|
||||
829.455078125 781.646484375 m 1
|
||||
829.455078125 781.645507812 l 1
|
||||
792.041015625 795.248046875 760.869140625 792.16796875 741.635742188 772.922851562 c 0
|
||||
733.508789062 764.796875 733.508789062 751.620117188 741.635742188 743.482421875 c 0
|
||||
749.764648438 735.364257812 762.939453125 735.354492188 771.069335938 743.482421875 c 0
|
||||
777.907226562 750.30859375 794.809570312 749.956054688 815.208007812 742.526367188 c 0
|
||||
841.3828125 732.993164062 871.2109375 712.708007812 897.041015625 686.876953125 c 0
|
||||
952.763671875 631.153320312 967.78125 575.046875 953.635742188 560.903320312 c 0
|
||||
945.508789062 552.776367188 945.508789062 539.599609375 953.635742188 531.4609375 c 0
|
||||
957.70703125 527.401367188 963.024414062 525.373046875 968.352539062 525.373046875 c 0
|
||||
973.680664062 525.373046875 979 527.401367188 983.067382812 531.47265625 c 0
|
||||
1019.61816406 568.0234375 995.288085938 647.485351562 926.47265625 716.319335938 c 0
|
||||
896.052734375 746.73046875 861.592773438 769.926757812 829.455078125 781.646484375 c 1
|
||||
748.963867188 663.739257812 m 1
|
||||
748.96484375 663.73828125 l 1
|
||||
755.135742188 669.899414062 792.102539062 663.115234375 832.69140625 622.525390625 c 0
|
||||
873.270507812 581.946289062 880.076171875 544.970703125 873.904296875 538.798828125 c 0
|
||||
865.788085938 530.669921875 865.788085938 517.484375 873.915039062 509.357421875 c 0
|
||||
877.984375 505.297851562 883.303710938 503.268554688 888.631835938 503.268554688 c 0
|
||||
893.958984375 503.268554688 899.2890625 505.297851562 903.356445312 509.3671875 c 0
|
||||
932.717773438 538.74609375 915.375976562 598.71484375 862.123046875 651.959960938 c 0
|
||||
808.888671875 705.224609375 748.888671875 722.555664062 719.528320312 693.184570312 c 0
|
||||
711.401367188 685.056640625 711.401367188 671.879882812 719.528320312 663.743164062 c 0
|
||||
727.661132812 655.600585938 740.825195312 655.62109375 748.963867188 663.739257812 c 1
|
||||
213.166015625 -210 m 1
|
||||
231.399414062 -210 247.083984375 -204.524414062 258.532226562 -193.078125 c 0
|
||||
266.661132812 -184.94921875 266.661132812 -171.772460938 258.532226562 -163.635742188 c 0
|
||||
250.403320312 -155.497070312 237.227539062 -155.506835938 229.098632812 -163.635742188 c 0
|
||||
214.944335938 -177.799804688 158.858398438 -162.770507812 103.127929688 -107.0390625 c 0
|
||||
77.3056640625 -81.208984375 57.01171875 -51.380859375 47.478515625 -25.2060546875 c 0
|
||||
40.046875 -4.818359375 39.6826171875 12.095703125 46.5205078125 18.931640625 c 0
|
||||
54.6494140625 27.0595703125 54.6494140625 40.2353515625 46.5205078125 48.3740234375 c 0
|
||||
38.3935546875 56.5126953125 25.2177734375 56.5009765625 17.0888671875 48.3740234375 c 0
|
||||
-2.1630859375 29.1337890625 -5.2548828125 -2.056640625 8.3583984375 -39.4521484375 c 0
|
||||
20.06640625 -71.5888671875 43.2763671875 -106.049804688 73.6953125 -136.470703125 c 0
|
||||
120.946289062 -183.729492188 173.2109375 -210.008789062 213.166015625 -210 c 1
|
||||
138.03515625 -72.1201171875 m 1
|
||||
160.764648438 -94.8388671875 186.5859375 -112.198242188 210.741210938 -120.9921875 c 0
|
||||
223.53125 -125.655273438 234.375976562 -127.456054688 243.53515625 -127.456054688 c 0
|
||||
262.7890625 -127.456054688 274.487304688 -119.473632812 280.627929688 -113.333007812 c 0
|
||||
288.744140625 -105.204101562 288.744140625 -92.017578125 280.6171875 -83.890625 c 0
|
||||
272.490234375 -75.7744140625 259.302734375 -75.7626953125 251.17578125 -83.890625 c 0
|
||||
248.990234375 -86.1083984375 240.174804688 -87.408203125 224.979492188 -81.880859375 c 0
|
||||
206.673828125 -75.2099609375 185.711914062 -60.921875 167.458007812 -42.67578125 c 0
|
||||
149.212890625 -24.4306640625 134.924804688 -3.458984375 128.252929688 14.845703125 c 0
|
||||
122.7265625 30.01953125 124.02734375 38.8251953125 126.245117188 41.041015625 c 0
|
||||
134.374023438 49.16796875 134.374023438 62.34375 126.245117188 70.4833984375 c 0
|
||||
118.116210938 78.6220703125 104.940429688 78.6103515625 96.8134765625 70.4833984375 c 0
|
||||
87.748046875 61.4169921875 74.6875 40.279296875 89.1416015625 0.5966796875 c 0
|
||||
97.9560546875 -23.5703125 115.315429688 -49.400390625 138.03515625 -72.1201171875 c 1
|
||||
802.430664062 155.80859375 m 0
|
||||
715.083007812 155.80859375 644.194335938 84.919921875 644.194335938 -2.427734375 c 0
|
||||
644.194335938 -89.775390625 715.083007812 -160.6640625 802.430664062 -160.6640625 c 0
|
||||
889.778320312 -160.6640625 960.666992188 -89.775390625 960.666992188 -2.427734375 c 0
|
||||
960.666992188 84.919921875 889.778320312 155.80859375 802.430664062 155.80859375 c 0
|
||||
904.14453125 -98.1357421875 m 1
|
||||
720.125976562 -98.1357421875 l 1
|
||||
720.125976562 85.939453125 l 1
|
||||
780.458984375 85.939453125 l 1
|
||||
780.458984375 -64.6650390625 l 1
|
||||
904.14453125 -64.6650390625 l 1
|
||||
904.14453125 -98.1357421875 l 1
|
||||
802.430664062 -209.9921875 m 0
|
||||
830.4453125 -209.9921875 857.633789062 -204.500976562 883.227539062 -193.674804688 c 0
|
||||
907.9453125 -183.221679688 930.141601562 -168.25390625 949.19921875 -149.196289062 c 0
|
||||
968.2578125 -130.138671875 983.224609375 -107.942382812 993.678710938 -83.2236328125 c 0
|
||||
1004.50390625 -57.6298828125 1009.99609375 -30.44140625 1009.99609375 -2.427734375 c 0
|
||||
1009.99609375 25.5869140625 1004.50390625 52.775390625 993.678710938 78.369140625 c 0
|
||||
983.224609375 103.087890625 968.2578125 125.284179688 949.19921875 144.341796875 c 0
|
||||
930.141601562 163.399414062 907.9453125 178.3671875 883.227539062 188.8203125 c 0
|
||||
857.6328125 199.646484375 830.4453125 205.137695312 802.430664062 205.137695312 c 0
|
||||
774.416015625 205.137695312 747.227539062 199.646484375 721.633789062 188.8203125 c 0
|
||||
696.916015625 178.3671875 674.719726562 163.399414062 655.662109375 144.341796875 c 0
|
||||
636.603515625 125.284179688 621.63671875 103.087890625 611.182617188 78.369140625 c 0
|
||||
600.357421875 52.775390625 594.865234375 25.5869140625 594.865234375 -2.427734375 c 0
|
||||
594.865234375 -30.44140625 600.357421875 -57.6298828125 611.182617188 -83.2236328125 c 0
|
||||
621.63671875 -107.942382812 636.603515625 -130.138671875 655.662109375 -149.196289062 c 0
|
||||
674.719726562 -168.25390625 696.916015625 -183.221679688 721.633789062 -193.674804688 c 0
|
||||
747.228515625 -204.500976562 774.411132812 -209.9921875 802.430664062 -209.9921875 c 0
|
||||
802.430664062 183.87890625 m 0
|
||||
905.1640625 183.87890625 988.736328125 100.299804688 988.736328125 -2.427734375 c 0
|
||||
988.736328125 -105.155273438 905.1640625 -188.733398438 802.430664062 -188.733398438 c 0
|
||||
699.697265625 -188.733398438 616.124023438 -105.161132812 616.124023438 -2.427734375 c 0
|
||||
616.124023438 100.305664062 699.703125 183.87890625 802.430664062 183.87890625 c 0
|
||||
EndSplineSet
|
||||
Validated: 524325
|
||||
EndChar
|
||||
EndChars
|
||||
EndSplineFont
|
||||
|
||||
2
3rdparty/vixl/CMakeLists.txt
vendored
2
3rdparty/vixl/CMakeLists.txt
vendored
@@ -56,6 +56,8 @@ target_compile_definitions(vixl PUBLIC
|
||||
VIXL_INCLUDE_TARGET_A64
|
||||
)
|
||||
|
||||
target_compile_definitions(vixl PRIVATE VIXL_CODE_BUFFER_MALLOC)
|
||||
|
||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
|
||||
message("Enabling vixl debug assertions")
|
||||
target_compile_definitions(vixl PUBLIC VIXL_DEBUG)
|
||||
|
||||
@@ -159,8 +159,8 @@ template <>
|
||||
inline GenericOperand ABI::GetReturnGenericOperand<void>() const {
|
||||
return GenericOperand();
|
||||
}
|
||||
}
|
||||
} // namespace vixl::aarch64
|
||||
} // namespace aarch64
|
||||
} // namespace vixl
|
||||
|
||||
#endif // VIXL_AARCH64_ABI_AARCH64_H_
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "../globals-vixl.h"
|
||||
#include "../invalset-vixl.h"
|
||||
#include "../utils-vixl.h"
|
||||
|
||||
#include "operands-aarch64.h"
|
||||
|
||||
namespace vixl {
|
||||
@@ -403,6 +404,15 @@ enum LoadStoreScalingOption {
|
||||
// Assembler.
|
||||
class Assembler : public vixl::internal::AssemblerBase {
|
||||
public:
|
||||
explicit Assembler(
|
||||
PositionIndependentCodeOption pic = PositionIndependentCode)
|
||||
: pic_(pic), cpu_features_(CPUFeatures::AArch64LegacyBaseline()) {}
|
||||
explicit Assembler(
|
||||
size_t capacity,
|
||||
PositionIndependentCodeOption pic = PositionIndependentCode)
|
||||
: AssemblerBase(capacity),
|
||||
pic_(pic),
|
||||
cpu_features_(CPUFeatures::AArch64LegacyBaseline()) {}
|
||||
Assembler(byte* buffer,
|
||||
size_t capacity,
|
||||
PositionIndependentCodeOption pic = PositionIndependentCode)
|
||||
@@ -2148,6 +2158,9 @@ class Assembler : public vixl::internal::AssemblerBase {
|
||||
// System instruction with pre-encoded op (op1:crn:crm:op2).
|
||||
void sys(int op, const Register& xt = xzr);
|
||||
|
||||
// System instruction with result.
|
||||
void sysl(int op, const Register& xt = xzr);
|
||||
|
||||
// System data cache operation.
|
||||
void dc(DataCacheOp op, const Register& rt);
|
||||
|
||||
@@ -3608,6 +3621,117 @@ class Assembler : public vixl::internal::AssemblerBase {
|
||||
// Unsigned 8-bit integer matrix multiply-accumulate (vector).
|
||||
void ummla(const VRegister& vd, const VRegister& vn, const VRegister& vm);
|
||||
|
||||
// Bit Clear and exclusive-OR.
|
||||
void bcax(const VRegister& vd,
|
||||
const VRegister& vn,
|
||||
const VRegister& vm,
|
||||
const VRegister& va);
|
||||
|
||||
// Three-way Exclusive-OR.
|
||||
void eor3(const VRegister& vd,
|
||||
const VRegister& vn,
|
||||
const VRegister& vm,
|
||||
const VRegister& va);
|
||||
|
||||
// Exclusive-OR and Rotate.
|
||||
void xar(const VRegister& vd,
|
||||
const VRegister& vn,
|
||||
const VRegister& vm,
|
||||
int rotate);
|
||||
|
||||
// Rotate and Exclusive-OR
|
||||
void rax1(const VRegister& vd, const VRegister& vn, const VRegister& vm);
|
||||
|
||||
// SHA1 hash update (choose).
|
||||
void sha1c(const VRegister& vd, const VRegister& vn, const VRegister& vm);
|
||||
|
||||
// SHA1 fixed rotate.
|
||||
void sha1h(const VRegister& sd, const VRegister& sn);
|
||||
|
||||
// SHA1 hash update (majority).
|
||||
void sha1m(const VRegister& vd, const VRegister& vn, const VRegister& vm);
|
||||
|
||||
// SHA1 hash update (parity).
|
||||
void sha1p(const VRegister& vd, const VRegister& vn, const VRegister& vm);
|
||||
|
||||
// SHA1 schedule update 0.
|
||||
void sha1su0(const VRegister& vd, const VRegister& vn, const VRegister& vm);
|
||||
|
||||
// SHA1 schedule update 1.
|
||||
void sha1su1(const VRegister& vd, const VRegister& vn);
|
||||
|
||||
// SHA256 hash update (part 1).
|
||||
void sha256h(const VRegister& vd, const VRegister& vn, const VRegister& vm);
|
||||
|
||||
// SHA256 hash update (part 2).
|
||||
void sha256h2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
|
||||
|
||||
// SHA256 schedule update 0.
|
||||
void sha256su0(const VRegister& vd, const VRegister& vn);
|
||||
|
||||
// SHA256 schedule update 1.
|
||||
void sha256su1(const VRegister& vd, const VRegister& vn, const VRegister& vm);
|
||||
|
||||
// SHA512 hash update part 1.
|
||||
void sha512h(const VRegister& vd, const VRegister& vn, const VRegister& vm);
|
||||
|
||||
// SHA512 hash update part 2.
|
||||
void sha512h2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
|
||||
|
||||
// SHA512 schedule Update 0.
|
||||
void sha512su0(const VRegister& vd, const VRegister& vn);
|
||||
|
||||
// SHA512 schedule Update 1.
|
||||
void sha512su1(const VRegister& vd, const VRegister& vn, const VRegister& vm);
|
||||
|
||||
// AES single round decryption.
|
||||
void aesd(const VRegister& vd, const VRegister& vn);
|
||||
|
||||
// AES single round encryption.
|
||||
void aese(const VRegister& vd, const VRegister& vn);
|
||||
|
||||
// AES inverse mix columns.
|
||||
void aesimc(const VRegister& vd, const VRegister& vn);
|
||||
|
||||
// AES mix columns.
|
||||
void aesmc(const VRegister& vd, const VRegister& vn);
|
||||
|
||||
// SM3PARTW1.
|
||||
void sm3partw1(const VRegister& vd, const VRegister& vn, const VRegister& vm);
|
||||
|
||||
// SM3PARTW2.
|
||||
void sm3partw2(const VRegister& vd, const VRegister& vn, const VRegister& vm);
|
||||
|
||||
// SM3SS1.
|
||||
void sm3ss1(const VRegister& vd,
|
||||
const VRegister& vn,
|
||||
const VRegister& vm,
|
||||
const VRegister& va);
|
||||
|
||||
// SM3TT1A.
|
||||
void sm3tt1a(const VRegister& vd,
|
||||
const VRegister& vn,
|
||||
const VRegister& vm,
|
||||
int index);
|
||||
|
||||
// SM3TT1B.
|
||||
void sm3tt1b(const VRegister& vd,
|
||||
const VRegister& vn,
|
||||
const VRegister& vm,
|
||||
int index);
|
||||
|
||||
// SM3TT2A.
|
||||
void sm3tt2a(const VRegister& vd,
|
||||
const VRegister& vn,
|
||||
const VRegister& vm,
|
||||
int index);
|
||||
|
||||
// SM3TT2B.
|
||||
void sm3tt2b(const VRegister& vd,
|
||||
const VRegister& vn,
|
||||
const VRegister& vm,
|
||||
int index);
|
||||
|
||||
// Scalable Vector Extensions.
|
||||
|
||||
// Absolute value (predicated).
|
||||
@@ -7062,6 +7186,21 @@ class Assembler : public vixl::internal::AssemblerBase {
|
||||
// Unsigned Minimum.
|
||||
void umin(const Register& rd, const Register& rn, const Operand& op);
|
||||
|
||||
// Check feature status.
|
||||
void chkfeat(const Register& rd);
|
||||
|
||||
// Guarded Control Stack Push.
|
||||
void gcspushm(const Register& rt);
|
||||
|
||||
// Guarded Control Stack Pop.
|
||||
void gcspopm(const Register& rt);
|
||||
|
||||
// Guarded Control Stack Switch Stack 1.
|
||||
void gcsss1(const Register& rt);
|
||||
|
||||
// Guarded Control Stack Switch Stack 2.
|
||||
void gcsss2(const Register& rt);
|
||||
|
||||
// Emit generic instructions.
|
||||
|
||||
// Emit raw instructions into the instruction stream.
|
||||
@@ -7530,6 +7669,8 @@ class Assembler : public vixl::internal::AssemblerBase {
|
||||
static Instr VFormat(VRegister vd) {
|
||||
if (vd.Is64Bits()) {
|
||||
switch (vd.GetLanes()) {
|
||||
case 1:
|
||||
return NEON_1D;
|
||||
case 2:
|
||||
return NEON_2S;
|
||||
case 4:
|
||||
|
||||
4241
3rdparty/vixl/include/vixl/aarch64/constants-aarch64.h
vendored
4241
3rdparty/vixl/include/vixl/aarch64/constants-aarch64.h
vendored
File diff suppressed because it is too large
Load Diff
@@ -32,6 +32,7 @@
|
||||
#include <unordered_map>
|
||||
|
||||
#include "../cpu-features.h"
|
||||
|
||||
#include "decoder-aarch64.h"
|
||||
#include "decoder-visitor-map-aarch64.h"
|
||||
|
||||
@@ -112,6 +113,7 @@ class CPUFeaturesAuditor : public DecoderVisitor {
|
||||
#define DECLARE(A) virtual void Visit##A(const Instruction* instr);
|
||||
VISITOR_LIST(DECLARE)
|
||||
#undef DECLARE
|
||||
void VisitCryptoSM3(const Instruction* instr);
|
||||
|
||||
void LoadStoreHelper(const Instruction* instr);
|
||||
void LoadStorePairHelper(const Instruction* instr);
|
||||
@@ -126,6 +128,7 @@ class CPUFeaturesAuditor : public DecoderVisitor {
|
||||
uint32_t,
|
||||
std::function<void(CPUFeaturesAuditor*, const Instruction*)>>;
|
||||
static const FormToVisitorFnMap* GetFormToVisitorFnMap();
|
||||
uint32_t form_hash_;
|
||||
};
|
||||
|
||||
} // namespace aarch64
|
||||
|
||||
276
3rdparty/vixl/include/vixl/aarch64/debugger-aarch64.h
vendored
Normal file
276
3rdparty/vixl/include/vixl/aarch64/debugger-aarch64.h
vendored
Normal file
@@ -0,0 +1,276 @@
|
||||
// Copyright 2023, VIXL authors
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of ARM Limited nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without
|
||||
// specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef VIXL_AARCH64_DEBUGGER_AARCH64_H_
|
||||
#define VIXL_AARCH64_DEBUGGER_AARCH64_H_
|
||||
|
||||
#include <optional>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#include "../cpu-features.h"
|
||||
#include "../globals-vixl.h"
|
||||
#include "../utils-vixl.h"
|
||||
|
||||
#include "abi-aarch64.h"
|
||||
#include "cpu-features-auditor-aarch64.h"
|
||||
#include "disasm-aarch64.h"
|
||||
#include "instructions-aarch64.h"
|
||||
#include "simulator-aarch64.h"
|
||||
#include "simulator-constants-aarch64.h"
|
||||
|
||||
#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
|
||||
|
||||
namespace vixl {
|
||||
namespace aarch64 {
|
||||
|
||||
class Simulator;
|
||||
|
||||
enum DebugReturn { DebugContinue, DebugExit };
|
||||
|
||||
|
||||
// A debugger command that performs some action when used by the simulator
|
||||
// debugger.
|
||||
class DebuggerCmd {
|
||||
public:
|
||||
DebuggerCmd(Simulator* sim,
|
||||
std::string cmd_word,
|
||||
std::string cmd_alias,
|
||||
std::string usage,
|
||||
std::string description);
|
||||
virtual ~DebuggerCmd() {}
|
||||
|
||||
// Perform some action based on the arguments passed in. Returns true if the
|
||||
// debugger should exit after the action, false otherwise.
|
||||
virtual DebugReturn Action(const std::vector<std::string>& args) = 0;
|
||||
|
||||
// Return the command word.
|
||||
std::string_view GetCommandWord() { return command_word_; }
|
||||
// Return the alias for this command. Returns an empty string if this command
|
||||
// has no alias.
|
||||
std::string_view GetCommandAlias() { return command_alias_; }
|
||||
// Return this commands usage.
|
||||
std::string_view GetArgsString() { return args_str_; }
|
||||
// Return this commands description.
|
||||
std::string_view GetDescription() { return description_; }
|
||||
|
||||
protected:
|
||||
// Simulator which this command will be performed on.
|
||||
Simulator* sim_;
|
||||
// Stream to output the result of the command to.
|
||||
FILE* ostream_;
|
||||
// Command word that, when given to the interactive debugger, calls Action.
|
||||
std::string command_word_;
|
||||
// Optional alias for the command_word.
|
||||
std::string command_alias_;
|
||||
// Optional string showing the arguments that can be passed to the command.
|
||||
std::string args_str_;
|
||||
// Optional description of the command.
|
||||
std::string description_;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Base debugger command handlers:
|
||||
//
|
||||
|
||||
|
||||
class HelpCmd : public DebuggerCmd {
|
||||
public:
|
||||
HelpCmd(Simulator* sim)
|
||||
: DebuggerCmd(sim, "help", "h", "", "Display this help message.") {}
|
||||
|
||||
DebugReturn Action(const std::vector<std::string>& args) override;
|
||||
};
|
||||
|
||||
|
||||
class BreakCmd : public DebuggerCmd {
|
||||
public:
|
||||
BreakCmd(Simulator* sim)
|
||||
: DebuggerCmd(sim,
|
||||
"break",
|
||||
"b",
|
||||
"<address>",
|
||||
"Set or remove a breakpoint.") {}
|
||||
|
||||
DebugReturn Action(const std::vector<std::string>& args) override;
|
||||
};
|
||||
|
||||
|
||||
class StepCmd : public DebuggerCmd {
|
||||
public:
|
||||
StepCmd(Simulator* sim)
|
||||
: DebuggerCmd(sim,
|
||||
"step",
|
||||
"s",
|
||||
"[<n>]",
|
||||
"Step n instructions, default step 1 instruction.") {}
|
||||
|
||||
DebugReturn Action(const std::vector<std::string>& args) override;
|
||||
};
|
||||
|
||||
|
||||
class ContinueCmd : public DebuggerCmd {
|
||||
public:
|
||||
ContinueCmd(Simulator* sim)
|
||||
: DebuggerCmd(sim,
|
||||
"continue",
|
||||
"c",
|
||||
"",
|
||||
"Exit the debugger and continue executing instructions.") {}
|
||||
|
||||
DebugReturn Action(const std::vector<std::string>& args) override;
|
||||
};
|
||||
|
||||
|
||||
class PrintCmd : public DebuggerCmd {
|
||||
public:
|
||||
PrintCmd(Simulator* sim)
|
||||
: DebuggerCmd(sim,
|
||||
"print",
|
||||
"p",
|
||||
"<register|all|system>",
|
||||
"Print the contents of a register, all registers or all"
|
||||
" system registers.") {}
|
||||
|
||||
DebugReturn Action(const std::vector<std::string>& args) override;
|
||||
};
|
||||
|
||||
|
||||
class TraceCmd : public DebuggerCmd {
|
||||
public:
|
||||
TraceCmd(Simulator* sim)
|
||||
: DebuggerCmd(sim,
|
||||
"trace",
|
||||
"t",
|
||||
"",
|
||||
"Start/stop memory and register tracing.") {}
|
||||
|
||||
DebugReturn Action(const std::vector<std::string>& args) override;
|
||||
};
|
||||
|
||||
|
||||
class GdbCmd : public DebuggerCmd {
|
||||
public:
|
||||
GdbCmd(Simulator* sim)
|
||||
: DebuggerCmd(sim,
|
||||
"gdb",
|
||||
"g",
|
||||
"",
|
||||
"Enter an already running instance of gdb.") {}
|
||||
|
||||
DebugReturn Action(const std::vector<std::string>& args) override;
|
||||
};
|
||||
|
||||
|
||||
// A debugger for the Simulator which takes input from the user in order to
|
||||
// control the running of the Simulator.
|
||||
class Debugger {
|
||||
public:
|
||||
// A pair consisting of a register character (e.g: W, X, V) and a register
|
||||
// code (e.g: 0, 1 ...31) which represents a single parsed register.
|
||||
//
|
||||
// Note: the register character is guaranteed to be upper case.
|
||||
using RegisterParsedFormat = std::pair<char, unsigned>;
|
||||
|
||||
Debugger(Simulator* sim);
|
||||
|
||||
// Set the input stream, from which commands are read, to a custom stream.
|
||||
void SetInputStream(std::istream* stream) { input_stream_ = stream; }
|
||||
|
||||
// Register a new command for the debugger.
|
||||
template <class T>
|
||||
void RegisterCmd();
|
||||
|
||||
// Set a breakpoint at the given address.
|
||||
void RegisterBreakpoint(uint64_t addr) { breakpoints_.insert(addr); }
|
||||
// Remove a breakpoint at the given address.
|
||||
void RemoveBreakpoint(uint64_t addr) { breakpoints_.erase(addr); }
|
||||
// Return true if the address is the location of a breakpoint.
|
||||
bool IsBreakpoint(uint64_t addr) const {
|
||||
return (breakpoints_.find(addr) != breakpoints_.end());
|
||||
}
|
||||
// Return true if the simulator pc is a breakpoint.
|
||||
bool IsAtBreakpoint() const;
|
||||
|
||||
// Main loop for the debugger. Keep prompting for user inputted debugger
|
||||
// commands and try to execute them until a command is given that exits the
|
||||
// interactive debugger.
|
||||
void Debug();
|
||||
|
||||
// Get an unsigned integer value from a string and return it in 'value'.
|
||||
// Base is used to determine the numeric base of the number to be read,
|
||||
// i.e: 8 for octal, 10 for decimal, 16 for hexadecimal and 0 for
|
||||
// auto-detect. Return true if an integer value was found, false otherwise.
|
||||
static std::optional<uint64_t> ParseUint64String(std::string_view uint64_str,
|
||||
int base = 0);
|
||||
|
||||
// Get a register from a string and return it in 'reg'. Return true if a
|
||||
// valid register character and code (e.g: W0, X29, V31) was found, false
|
||||
// otherwise.
|
||||
static std::optional<RegisterParsedFormat> ParseRegString(
|
||||
std::string_view reg_str);
|
||||
|
||||
// Print the usage of each debugger command.
|
||||
void PrintUsage();
|
||||
|
||||
private:
|
||||
// Split a string based on the separator given (a single space character by
|
||||
// default) and return as a std::vector of strings.
|
||||
static std::vector<std::string> Tokenize(std::string_view input_line,
|
||||
char separator = ' ');
|
||||
|
||||
// Try to execute a single debugger command.
|
||||
DebugReturn ExecDebugCommand(const std::vector<std::string>& tokenized_cmd);
|
||||
|
||||
// Return true if the string is zero, i.e: all characters in the string
|
||||
// (other than prefixes) are zero.
|
||||
static bool IsZeroUint64String(std::string_view uint64_str, int base);
|
||||
|
||||
// The simulator that this debugger acts on.
|
||||
Simulator* sim_;
|
||||
|
||||
// A vector of all commands recognised by the debugger.
|
||||
std::vector<std::unique_ptr<DebuggerCmd>> debugger_cmds_;
|
||||
|
||||
// Input stream from which commands are read. Default is std::cin.
|
||||
std::istream* input_stream_;
|
||||
|
||||
// Output stream from the simulator.
|
||||
FILE* ostream_;
|
||||
|
||||
// A list of all instruction addresses that, when executed by the
|
||||
// simulator, will start the interactive debugger if it hasn't already.
|
||||
std::unordered_set<uint64_t> breakpoints_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace aarch64
|
||||
} // namespace vixl
|
||||
|
||||
#endif // VIXL_INCLUDE_SIMULATOR_AARCH64
|
||||
|
||||
#endif // VIXL_AARCH64_DEBUGGER_AARCH64_H_
|
||||
@@ -3764,7 +3764,7 @@ static const DecodeMapping kDecodeMapping[] = {
|
||||
{"001110"_b, "autiaz_hi_hints"},
|
||||
{"001111"_b, "autibz_hi_hints"},
|
||||
{"0100xx"_b, "bti_hb_hints"},
|
||||
{"010100"_b, "chkfeat_hi_hints"},
|
||||
{"010100"_b, "chkfeat_hf_hints"},
|
||||
{"0101x1"_b, "hint_hm_hints"},
|
||||
{"01x110"_b, "hint_hm_hints"},
|
||||
{"10xxxx"_b, "hint_hm_hints"},
|
||||
|
||||
@@ -2074,7 +2074,6 @@
|
||||
{"scvtf_asimdmiscfp16_r"_h, &VISITORCLASS::VisitNEON2RegMiscFP16}, \
|
||||
{"ucvtf_asimdmiscfp16_r"_h, &VISITORCLASS::VisitNEON2RegMiscFP16}, \
|
||||
{"addhn_asimddiff_n"_h, &VISITORCLASS::VisitNEON3Different}, \
|
||||
{"pmull_asimddiff_l"_h, &VISITORCLASS::VisitNEON3Different}, \
|
||||
{"raddhn_asimddiff_n"_h, &VISITORCLASS::VisitNEON3Different}, \
|
||||
{"rsubhn_asimddiff_n"_h, &VISITORCLASS::VisitNEON3Different}, \
|
||||
{"sabal_asimddiff_l"_h, &VISITORCLASS::VisitNEON3Different}, \
|
||||
@@ -2592,6 +2591,7 @@
|
||||
{"dmb_bo_barriers"_h, &VISITORCLASS::VisitSystem}, \
|
||||
{"dsb_bo_barriers"_h, &VISITORCLASS::VisitSystem}, \
|
||||
{"hint_hm_hints"_h, &VISITORCLASS::VisitSystem}, \
|
||||
{"chkfeat_hf_hints"_h, &VISITORCLASS::VisitSystem}, \
|
||||
{"mrs_rs_systemmove"_h, &VISITORCLASS::VisitSystem}, \
|
||||
{"msr_sr_systemmove"_h, &VISITORCLASS::VisitSystem}, \
|
||||
{"psb_hc_hints"_h, &VISITORCLASS::VisitSystem}, \
|
||||
@@ -2638,7 +2638,6 @@
|
||||
&VISITORCLASS::VisitUnconditionalBranchToRegister}, \
|
||||
{"ret_64r_branch_reg"_h, \
|
||||
&VISITORCLASS::VisitUnconditionalBranchToRegister}, \
|
||||
{"bcax_vvv16_crypto4"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"bfcvtn_asimdmisc_4s"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"bfdot_asimdelem_e"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"bfdot_asimdsame2_d"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
@@ -2646,7 +2645,6 @@
|
||||
{"bfmlal_asimdsame2_f"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"bfmmla_asimdsame2_e"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"dsb_bon_barriers"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"eor3_vvv16_crypto4"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"ld64b_64l_memop"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"ldgm_64bulk_ldsttags"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"ldtrb_32_ldst_unpriv"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
@@ -2658,18 +2656,13 @@
|
||||
{"ldtrsw_64_ldst_unpriv"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"ldtr_32_ldst_unpriv"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"ldtr_64_ldst_unpriv"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"rax1_vvv2_cryptosha512_3"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"sha512h2_qqv_cryptosha512_3"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"sha512h_qqv_cryptosha512_3"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"sha512su0_vv2_cryptosha512_2"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"sha512su1_vvv2_cryptosha512_3"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"sm3partw1_vvv4_cryptosha512_3"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"sm3partw2_vvv4_cryptosha512_3"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"sm3ss1_vvv4_crypto4"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"sm3tt1a_vvv4_crypto3_imm2"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"sm3tt1b_vvv4_crypto3_imm2"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"sm3tt2a_vvv4_crypto3_imm2"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"sm3tt2b_vvv_crypto3_imm2"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"sm3partw1_vvv4_cryptosha512_3"_h, &VISITORCLASS::VisitCryptoSM3}, \
|
||||
{"sm3partw2_vvv4_cryptosha512_3"_h, &VISITORCLASS::VisitCryptoSM3}, \
|
||||
{"sm3ss1_vvv4_crypto4"_h, &VISITORCLASS::VisitCryptoSM3}, \
|
||||
{"sm3tt1a_vvv4_crypto3_imm2"_h, &VISITORCLASS::VisitCryptoSM3}, \
|
||||
{"sm3tt1b_vvv4_crypto3_imm2"_h, &VISITORCLASS::VisitCryptoSM3}, \
|
||||
{"sm3tt2a_vvv4_crypto3_imm2"_h, &VISITORCLASS::VisitCryptoSM3}, \
|
||||
{"sm3tt2b_vvv_crypto3_imm2"_h, &VISITORCLASS::VisitCryptoSM3}, \
|
||||
{"sm4ekey_vvv4_cryptosha512_3"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"sm4e_vv4_cryptosha512_2"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"st64b_64l_memop"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
@@ -2686,7 +2679,6 @@
|
||||
{"ttest_br_systemresult"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"wfet_only_systeminstrswithreg"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"wfit_only_systeminstrswithreg"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"xar_vvv2_crypto3_imm6"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"bfcvt_z_p_z_s2bf"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"bfcvtnt_z_p_z_s2bf"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
{"bfdot_z_zzz"_h, &VISITORCLASS::VisitUnimplemented}, \
|
||||
@@ -2827,6 +2819,7 @@
|
||||
{"fmlal_asimdsame_f"_h, &VISITORCLASS::VisitNEON3Same}, \
|
||||
{"fmlsl2_asimdsame_f"_h, &VISITORCLASS::VisitNEON3Same}, \
|
||||
{"fmlsl_asimdsame_f"_h, &VISITORCLASS::VisitNEON3Same}, \
|
||||
{"pmull_asimddiff_l"_h, &VISITORCLASS::VisitNEON3Different}, \
|
||||
{"ushll_asimdshf_l"_h, &VISITORCLASS::VisitNEONShiftImmediate}, \
|
||||
{"sshll_asimdshf_l"_h, &VISITORCLASS::VisitNEONShiftImmediate}, \
|
||||
{"shrn_asimdshf_n"_h, &VISITORCLASS::VisitNEONShiftImmediate}, \
|
||||
|
||||
@@ -228,6 +228,11 @@ class Disassembler : public DecoderVisitor {
|
||||
void DisassembleNEONScalarShiftRightNarrowImm(const Instruction* instr);
|
||||
void DisassembleNEONScalar2RegMiscOnlyD(const Instruction* instr);
|
||||
void DisassembleNEONFPScalar2RegMisc(const Instruction* instr);
|
||||
void DisassembleNEONPolynomialMul(const Instruction* instr);
|
||||
void DisassembleNEON4Same(const Instruction* instr);
|
||||
void DisassembleNEONXar(const Instruction* instr);
|
||||
void DisassembleNEONRax1(const Instruction* instr);
|
||||
void DisassembleSHA512(const Instruction* instr);
|
||||
|
||||
void DisassembleMTELoadTag(const Instruction* instr);
|
||||
void DisassembleMTEStoreTag(const Instruction* instr);
|
||||
@@ -238,6 +243,8 @@ class Disassembler : public DecoderVisitor {
|
||||
void Disassemble_Xd_XnSP_Xm(const Instruction* instr);
|
||||
void Disassemble_Xd_XnSP_XmSP(const Instruction* instr);
|
||||
|
||||
void VisitCryptoSM3(const Instruction* instr);
|
||||
|
||||
void Format(const Instruction* instr,
|
||||
const char* mnemonic,
|
||||
const char* format0,
|
||||
|
||||
@@ -32,11 +32,6 @@
|
||||
|
||||
#include "constants-aarch64.h"
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"
|
||||
#endif
|
||||
|
||||
namespace vixl {
|
||||
namespace aarch64 {
|
||||
// ISA constants. --------------------------------------------------------------
|
||||
@@ -152,19 +147,19 @@ const unsigned kMTETagWidth = 4;
|
||||
|
||||
// Make these moved float constants backwards compatible
|
||||
// with explicit vixl::aarch64:: namespace references.
|
||||
using vixl::kDoubleMantissaBits;
|
||||
using vixl::kDoubleExponentBits;
|
||||
using vixl::kFloatMantissaBits;
|
||||
using vixl::kFloatExponentBits;
|
||||
using vixl::kFloat16MantissaBits;
|
||||
using vixl::kDoubleMantissaBits;
|
||||
using vixl::kFloat16ExponentBits;
|
||||
using vixl::kFloat16MantissaBits;
|
||||
using vixl::kFloatExponentBits;
|
||||
using vixl::kFloatMantissaBits;
|
||||
|
||||
using vixl::kFP16PositiveInfinity;
|
||||
using vixl::kFP16NegativeInfinity;
|
||||
using vixl::kFP32PositiveInfinity;
|
||||
using vixl::kFP16PositiveInfinity;
|
||||
using vixl::kFP32NegativeInfinity;
|
||||
using vixl::kFP64PositiveInfinity;
|
||||
using vixl::kFP32PositiveInfinity;
|
||||
using vixl::kFP64NegativeInfinity;
|
||||
using vixl::kFP64PositiveInfinity;
|
||||
|
||||
using vixl::kFP16DefaultNaN;
|
||||
using vixl::kFP32DefaultNaN;
|
||||
@@ -222,9 +217,10 @@ enum VectorFormat {
|
||||
kFormatVnQ = kFormatSVEQ | kFormatSVE,
|
||||
kFormatVnO = kFormatSVEO | kFormatSVE,
|
||||
|
||||
// An artificial value, used by simulator trace tests and a few oddball
|
||||
// Artificial values, used by simulator trace tests and a few oddball
|
||||
// instructions (such as FMLAL).
|
||||
kFormat2H = 0xfffffffe
|
||||
kFormat2H = 0xfffffffe,
|
||||
kFormat1Q = 0xfffffffd
|
||||
};
|
||||
|
||||
// Instructions. ---------------------------------------------------------------
|
||||
@@ -1141,8 +1137,4 @@ class NEONFormatDecoder {
|
||||
} // namespace aarch64
|
||||
} // namespace vixl
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // VIXL_AARCH64_INSTRUCTIONS_AARCH64_H_
|
||||
|
||||
@@ -664,6 +664,10 @@ enum FPMacroNaNPropagationOption {
|
||||
|
||||
class MacroAssembler : public Assembler, public MacroAssemblerInterface {
|
||||
public:
|
||||
explicit MacroAssembler(
|
||||
PositionIndependentCodeOption pic = PositionIndependentCode);
|
||||
MacroAssembler(size_t capacity,
|
||||
PositionIndependentCodeOption pic = PositionIndependentCode);
|
||||
MacroAssembler(byte* buffer,
|
||||
size_t capacity,
|
||||
PositionIndependentCodeOption pic = PositionIndependentCode);
|
||||
@@ -1750,7 +1754,7 @@ class MacroAssembler : public Assembler, public MacroAssemblerInterface {
|
||||
V(casah, Casah) \
|
||||
V(caslh, Caslh) \
|
||||
V(casalh, Casalh)
|
||||
// clang-format on
|
||||
// clang-format on
|
||||
|
||||
#define DEFINE_MACRO_ASM_FUNC(ASM, MASM) \
|
||||
void MASM(const Register& rs, const Register& rt, const MemOperand& src) { \
|
||||
@@ -1768,7 +1772,7 @@ class MacroAssembler : public Assembler, public MacroAssemblerInterface {
|
||||
V(caspa, Caspa) \
|
||||
V(caspl, Caspl) \
|
||||
V(caspal, Caspal)
|
||||
// clang-format on
|
||||
// clang-format on
|
||||
|
||||
#define DEFINE_MACRO_ASM_FUNC(ASM, MASM) \
|
||||
void MASM(const Register& rs, \
|
||||
@@ -1813,7 +1817,7 @@ class MacroAssembler : public Assembler, public MacroAssemblerInterface {
|
||||
V(MASM##alb, ASM##alb) \
|
||||
V(MASM##ah, ASM##ah) \
|
||||
V(MASM##alh, ASM##alh)
|
||||
// clang-format on
|
||||
// clang-format on
|
||||
|
||||
#define DEFINE_MACRO_LOAD_ASM_FUNC(MASM, ASM) \
|
||||
void MASM(const Register& rs, const Register& rt, const MemOperand& src) { \
|
||||
@@ -2713,6 +2717,27 @@ class MacroAssembler : public Assembler, public MacroAssemblerInterface {
|
||||
subps(xd, xn, xm);
|
||||
}
|
||||
void Cmpp(const Register& xn, const Register& xm) { Subps(xzr, xn, xm); }
|
||||
void Chkfeat(const Register& xdn);
|
||||
void Gcspushm(const Register& rt) {
|
||||
VIXL_ASSERT(allow_macro_instructions_);
|
||||
SingleEmissionCheckScope guard(this);
|
||||
gcspushm(rt);
|
||||
}
|
||||
void Gcspopm(const Register& rt = xzr) {
|
||||
VIXL_ASSERT(allow_macro_instructions_);
|
||||
SingleEmissionCheckScope guard(this);
|
||||
gcspopm(rt);
|
||||
}
|
||||
void Gcsss1(const Register& rt) {
|
||||
VIXL_ASSERT(allow_macro_instructions_);
|
||||
SingleEmissionCheckScope guard(this);
|
||||
gcsss1(rt);
|
||||
}
|
||||
void Gcsss2(const Register& rt) {
|
||||
VIXL_ASSERT(allow_macro_instructions_);
|
||||
SingleEmissionCheckScope guard(this);
|
||||
gcsss2(rt);
|
||||
}
|
||||
|
||||
// NEON 3 vector register instructions.
|
||||
#define NEON_3VREG_MACRO_LIST(V) \
|
||||
@@ -2762,6 +2787,7 @@ class MacroAssembler : public Assembler, public MacroAssemblerInterface {
|
||||
V(pmull2, Pmull2) \
|
||||
V(raddhn, Raddhn) \
|
||||
V(raddhn2, Raddhn2) \
|
||||
V(rax1, Rax1) \
|
||||
V(rsubhn, Rsubhn) \
|
||||
V(rsubhn2, Rsubhn2) \
|
||||
V(saba, Saba) \
|
||||
@@ -2774,8 +2800,20 @@ class MacroAssembler : public Assembler, public MacroAssemblerInterface {
|
||||
V(saddl2, Saddl2) \
|
||||
V(saddw, Saddw) \
|
||||
V(saddw2, Saddw2) \
|
||||
V(sha1c, Sha1c) \
|
||||
V(sha1m, Sha1m) \
|
||||
V(sha1p, Sha1p) \
|
||||
V(sha1su0, Sha1su0) \
|
||||
V(sha256h, Sha256h) \
|
||||
V(sha256h2, Sha256h2) \
|
||||
V(sha256su1, Sha256su1) \
|
||||
V(sha512h, Sha512h) \
|
||||
V(sha512h2, Sha512h2) \
|
||||
V(sha512su1, Sha512su1) \
|
||||
V(shadd, Shadd) \
|
||||
V(shsub, Shsub) \
|
||||
V(sm3partw1, Sm3partw1) \
|
||||
V(sm3partw2, Sm3partw2) \
|
||||
V(smax, Smax) \
|
||||
V(smaxp, Smaxp) \
|
||||
V(smin, Smin) \
|
||||
@@ -2870,6 +2908,10 @@ class MacroAssembler : public Assembler, public MacroAssemblerInterface {
|
||||
V(abs, Abs) \
|
||||
V(addp, Addp) \
|
||||
V(addv, Addv) \
|
||||
V(aesd, Aesd) \
|
||||
V(aese, Aese) \
|
||||
V(aesimc, Aesimc) \
|
||||
V(aesmc, Aesmc) \
|
||||
V(cls, Cls) \
|
||||
V(clz, Clz) \
|
||||
V(cnt, Cnt) \
|
||||
@@ -2918,6 +2960,10 @@ class MacroAssembler : public Assembler, public MacroAssemblerInterface {
|
||||
V(sadalp, Sadalp) \
|
||||
V(saddlp, Saddlp) \
|
||||
V(saddlv, Saddlv) \
|
||||
V(sha1h, Sha1h) \
|
||||
V(sha1su1, Sha1su1) \
|
||||
V(sha256su0, Sha256su0) \
|
||||
V(sha512su0, Sha512su0) \
|
||||
V(smaxv, Smaxv) \
|
||||
V(sminv, Sminv) \
|
||||
V(sqabs, Sqabs) \
|
||||
@@ -3008,7 +3054,11 @@ class MacroAssembler : public Assembler, public MacroAssemblerInterface {
|
||||
V(umlsl, Umlsl) \
|
||||
V(umlsl2, Umlsl2) \
|
||||
V(sudot, Sudot) \
|
||||
V(usdot, Usdot)
|
||||
V(usdot, Usdot) \
|
||||
V(sm3tt1a, Sm3tt1a) \
|
||||
V(sm3tt1b, Sm3tt1b) \
|
||||
V(sm3tt2a, Sm3tt2a) \
|
||||
V(sm3tt2b, Sm3tt2b)
|
||||
|
||||
|
||||
#define DEFINE_MACRO_ASM_FUNC(ASM, MASM) \
|
||||
@@ -3127,6 +3177,14 @@ class MacroAssembler : public Assembler, public MacroAssemblerInterface {
|
||||
SVE_3VREG_COMMUTATIVE_MACRO_LIST(DEFINE_MACRO_ASM_FUNC)
|
||||
#undef DEFINE_MACRO_ASM_FUNC
|
||||
|
||||
void Bcax(const VRegister& vd,
|
||||
const VRegister& vn,
|
||||
const VRegister& vm,
|
||||
const VRegister& va) {
|
||||
VIXL_ASSERT(allow_macro_instructions_);
|
||||
SingleEmissionCheckScope guard(this);
|
||||
bcax(vd, vn, vm, va);
|
||||
}
|
||||
void Bic(const VRegister& vd, const int imm8, const int left_shift = 0) {
|
||||
VIXL_ASSERT(allow_macro_instructions_);
|
||||
SingleEmissionCheckScope guard(this);
|
||||
@@ -3167,6 +3225,14 @@ class MacroAssembler : public Assembler, public MacroAssemblerInterface {
|
||||
SingleEmissionCheckScope guard(this);
|
||||
dup(vd, rn);
|
||||
}
|
||||
void Eor3(const VRegister& vd,
|
||||
const VRegister& vn,
|
||||
const VRegister& vm,
|
||||
const VRegister& va) {
|
||||
VIXL_ASSERT(allow_macro_instructions_);
|
||||
SingleEmissionCheckScope guard(this);
|
||||
eor3(vd, vn, vm, va);
|
||||
}
|
||||
void Ext(const VRegister& vd,
|
||||
const VRegister& vn,
|
||||
const VRegister& vm,
|
||||
@@ -3463,6 +3529,14 @@ class MacroAssembler : public Assembler, public MacroAssemblerInterface {
|
||||
SingleEmissionCheckScope guard(this);
|
||||
st4(vt, vt2, vt3, vt4, lane, dst);
|
||||
}
|
||||
void Sm3ss1(const VRegister& vd,
|
||||
const VRegister& vn,
|
||||
const VRegister& vm,
|
||||
const VRegister& va) {
|
||||
VIXL_ASSERT(allow_macro_instructions_);
|
||||
SingleEmissionCheckScope guard(this);
|
||||
sm3ss1(vd, vn, vm, va);
|
||||
}
|
||||
void Smov(const Register& rd, const VRegister& vn, int vn_index) {
|
||||
VIXL_ASSERT(allow_macro_instructions_);
|
||||
SingleEmissionCheckScope guard(this);
|
||||
@@ -3473,6 +3547,14 @@ class MacroAssembler : public Assembler, public MacroAssemblerInterface {
|
||||
SingleEmissionCheckScope guard(this);
|
||||
umov(rd, vn, vn_index);
|
||||
}
|
||||
void Xar(const VRegister& vd,
|
||||
const VRegister& vn,
|
||||
const VRegister& vm,
|
||||
int rotate) {
|
||||
VIXL_ASSERT(allow_macro_instructions_);
|
||||
SingleEmissionCheckScope guard(this);
|
||||
xar(vd, vn, vm, rotate);
|
||||
}
|
||||
void Crc32b(const Register& rd, const Register& rn, const Register& rm) {
|
||||
VIXL_ASSERT(allow_macro_instructions_);
|
||||
SingleEmissionCheckScope guard(this);
|
||||
@@ -8580,6 +8662,16 @@ class UseScratchRegisterScope {
|
||||
return AcquireFrom(available, kGoverningPRegisterMask).P();
|
||||
}
|
||||
|
||||
// TODO: extend to other scratch register lists.
|
||||
bool TryAcquire(const Register& required_reg) {
|
||||
CPURegList* list = masm_->GetScratchRegisterList();
|
||||
if (list->IncludesAliasOf(required_reg)) {
|
||||
list->Remove(required_reg);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Register AcquireRegisterOfSize(int size_in_bits);
|
||||
Register AcquireSameSizeAs(const Register& reg) {
|
||||
return AcquireRegisterOfSize(reg.GetSizeInBits());
|
||||
|
||||
@@ -735,7 +735,7 @@ class SVEMemOperand {
|
||||
class IntegerOperand {
|
||||
public:
|
||||
#define VIXL_INT_TYPES(V) \
|
||||
V(char) V(short) V(int) V(long) V(long long) // NOLINT(runtime/int)
|
||||
V(char) V(short) V(int) V(long) V(long long) // NOLINT(google-runtime-int)
|
||||
#define VIXL_DECL_INT_OVERLOADS(T) \
|
||||
/* These are allowed to be implicit constructors because this is a */ \
|
||||
/* wrapper class that doesn't normally perform any type conversion. */ \
|
||||
@@ -993,7 +993,7 @@ class GenericOperand {
|
||||
// We only support sizes up to X/D register sizes.
|
||||
size_t mem_op_size_;
|
||||
};
|
||||
}
|
||||
} // namespace vixl::aarch64
|
||||
} // namespace aarch64
|
||||
} // namespace vixl
|
||||
|
||||
#endif // VIXL_AARCH64_OPERANDS_AARCH64_H_
|
||||
|
||||
@@ -575,6 +575,7 @@ class VRegister : public CPURegister {
|
||||
VRegister V4S() const;
|
||||
VRegister V1D() const;
|
||||
VRegister V2D() const;
|
||||
VRegister V1Q() const;
|
||||
VRegister S4B() const;
|
||||
|
||||
bool IsValid() const { return IsValidVRegister(); }
|
||||
@@ -895,7 +896,7 @@ bool AreSameLaneSize(const CPURegister& reg1,
|
||||
const CPURegister& reg2,
|
||||
const CPURegister& reg3 = NoCPUReg,
|
||||
const CPURegister& reg4 = NoCPUReg);
|
||||
}
|
||||
} // namespace vixl::aarch64
|
||||
} // namespace aarch64
|
||||
} // namespace vixl
|
||||
|
||||
#endif // VIXL_AARCH64_REGISTERS_AARCH64_H_
|
||||
|
||||
@@ -28,15 +28,18 @@
|
||||
#define VIXL_AARCH64_SIMULATOR_AARCH64_H_
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <random>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "../cpu-features.h"
|
||||
#include "../globals-vixl.h"
|
||||
#include "../utils-vixl.h"
|
||||
|
||||
#include "../cpu-features.h"
|
||||
#include "abi-aarch64.h"
|
||||
#include "cpu-features-auditor-aarch64.h"
|
||||
#include "debugger-aarch64.h"
|
||||
#include "disasm-aarch64.h"
|
||||
#include "instructions-aarch64.h"
|
||||
#include "simulator-constants-aarch64.h"
|
||||
@@ -67,6 +70,28 @@ namespace aarch64 {
|
||||
class Simulator;
|
||||
struct RuntimeCallStructHelper;
|
||||
|
||||
enum class MemoryAccessResult { Success = 0, Failure = 1 };
|
||||
|
||||
// Try to access a piece of memory at the given address. Accessing that memory
|
||||
// might raise a signal which, if handled by a custom signal handler, should
|
||||
// setup the native and simulated context in order to continue. Return whether
|
||||
// the memory access failed (i.e: raised a signal) or succeeded.
|
||||
MemoryAccessResult TryMemoryAccess(uintptr_t address, uintptr_t access_size);
|
||||
|
||||
#ifdef VIXL_ENABLE_IMPLICIT_CHECKS
|
||||
// Access a byte of memory from the address at the given offset. If the memory
|
||||
// could be accessed then return MemoryAccessResult::Success. If the memory
|
||||
// could not be accessed, and therefore raised a signal, setup the simulated
|
||||
// context and return MemoryAccessResult::Failure.
|
||||
//
|
||||
// If a signal is raised then it is expected that the signal handler will place
|
||||
// MemoryAccessResult::Failure in the native return register and the address of
|
||||
// _vixl_internal_AccessMemory_continue into the native instruction pointer.
|
||||
extern "C" MemoryAccessResult _vixl_internal_ReadMemory(uintptr_t address,
|
||||
uintptr_t offset);
|
||||
extern "C" uintptr_t _vixl_internal_AccessMemory_continue();
|
||||
#endif // VIXL_ENABLE_IMPLICIT_CHECKS
|
||||
|
||||
class SimStack {
|
||||
public:
|
||||
SimStack() {}
|
||||
@@ -135,7 +160,7 @@ class SimStack {
|
||||
|
||||
// Allocate the stack, locking the parameters.
|
||||
Allocated Allocate() {
|
||||
size_t align_to = 1 << align_log2_;
|
||||
size_t align_to = uint64_t{1} << align_log2_;
|
||||
size_t l = AlignUp(limit_guard_size_, align_to);
|
||||
size_t u = AlignUp(usable_size_, align_to);
|
||||
size_t b = AlignUp(base_guard_size_, align_to);
|
||||
@@ -365,7 +390,7 @@ class Memory {
|
||||
}
|
||||
|
||||
template <typename T, typename A>
|
||||
T Read(A address, Instruction const* pc = nullptr) const {
|
||||
std::optional<T> Read(A address, Instruction const* pc = nullptr) const {
|
||||
T value;
|
||||
VIXL_STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) ||
|
||||
(sizeof(value) == 4) || (sizeof(value) == 8) ||
|
||||
@@ -377,12 +402,16 @@ class Memory {
|
||||
if (!IsMTETagsMatched(address, pc)) {
|
||||
VIXL_ABORT_WITH_MSG("Tag mismatch.");
|
||||
}
|
||||
if (TryMemoryAccess(reinterpret_cast<uintptr_t>(base), sizeof(value)) ==
|
||||
MemoryAccessResult::Failure) {
|
||||
return std::nullopt;
|
||||
}
|
||||
memcpy(&value, base, sizeof(value));
|
||||
return value;
|
||||
}
|
||||
|
||||
template <typename T, typename A>
|
||||
void Write(A address, T value, Instruction const* pc = nullptr) const {
|
||||
bool Write(A address, T value, Instruction const* pc = nullptr) const {
|
||||
VIXL_STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) ||
|
||||
(sizeof(value) == 4) || (sizeof(value) == 8) ||
|
||||
(sizeof(value) == 16));
|
||||
@@ -393,11 +422,16 @@ class Memory {
|
||||
if (!IsMTETagsMatched(address, pc)) {
|
||||
VIXL_ABORT_WITH_MSG("Tag mismatch.");
|
||||
}
|
||||
if (TryMemoryAccess(reinterpret_cast<uintptr_t>(base), sizeof(value)) ==
|
||||
MemoryAccessResult::Failure) {
|
||||
return false;
|
||||
}
|
||||
memcpy(base, &value, sizeof(value));
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
uint64_t ReadUint(int size_in_bytes, A address) const {
|
||||
std::optional<uint64_t> ReadUint(int size_in_bytes, A address) const {
|
||||
switch (size_in_bytes) {
|
||||
case 1:
|
||||
return Read<uint8_t>(address);
|
||||
@@ -413,7 +447,7 @@ class Memory {
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
int64_t ReadInt(int size_in_bytes, A address) const {
|
||||
std::optional<int64_t> ReadInt(int size_in_bytes, A address) const {
|
||||
switch (size_in_bytes) {
|
||||
case 1:
|
||||
return Read<int8_t>(address);
|
||||
@@ -429,7 +463,7 @@ class Memory {
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
void Write(int size_in_bytes, A address, uint64_t value) const {
|
||||
bool Write(int size_in_bytes, A address, uint64_t value) const {
|
||||
switch (size_in_bytes) {
|
||||
case 1:
|
||||
return Write(address, static_cast<uint8_t>(value));
|
||||
@@ -441,6 +475,7 @@ class Memory {
|
||||
return Write(address, value);
|
||||
}
|
||||
VIXL_UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
|
||||
void AppendMetaData(MetaDataDepot* metadata_depot) {
|
||||
@@ -649,7 +684,7 @@ class LogicPRegister {
|
||||
|
||||
void SetAllBits() {
|
||||
int chunk_size = sizeof(ChunkType) * kBitsPerByte;
|
||||
ChunkType bits = GetUintMask(chunk_size);
|
||||
ChunkType bits = static_cast<ChunkType>(GetUintMask(chunk_size));
|
||||
for (int lane = 0;
|
||||
lane < (static_cast<int>(register_.GetSizeInBits() / chunk_size));
|
||||
lane++) {
|
||||
@@ -702,6 +737,8 @@ class LogicPRegister {
|
||||
SimPRegister& register_;
|
||||
};
|
||||
|
||||
using vixl_uint128_t = std::pair<uint64_t, uint64_t>;
|
||||
|
||||
// Representation of a vector register, with typed getters and setters for lanes
|
||||
// and additional information to represent lane state.
|
||||
class LogicVRegister {
|
||||
@@ -830,6 +867,17 @@ class LogicVRegister {
|
||||
}
|
||||
}
|
||||
|
||||
void SetUint(VectorFormat vform, int index, vixl_uint128_t value) const {
|
||||
if (LaneSizeInBitsFromFormat(vform) <= 64) {
|
||||
SetUint(vform, index, value.second);
|
||||
return;
|
||||
}
|
||||
// TODO: Extend this to SVE.
|
||||
VIXL_ASSERT((vform == kFormat1Q) && (index == 0));
|
||||
SetUint(kFormat2D, 0, value.second);
|
||||
SetUint(kFormat2D, 1, value.first);
|
||||
}
|
||||
|
||||
void SetUintArray(VectorFormat vform, const uint64_t* src) const {
|
||||
ClearForWrite(vform);
|
||||
for (int i = 0; i < LaneCountFromFormat(vform); i++) {
|
||||
@@ -1233,6 +1281,11 @@ class SimExclusiveGlobalMonitor {
|
||||
uint32_t seed_;
|
||||
};
|
||||
|
||||
class Debugger;
|
||||
|
||||
template <uint32_t mode>
|
||||
uint64_t CryptoOp(uint64_t x, uint64_t y, uint64_t z);
|
||||
|
||||
class Simulator : public DecoderVisitor {
|
||||
public:
|
||||
explicit Simulator(Decoder* decoder,
|
||||
@@ -1248,7 +1301,7 @@ class Simulator : public DecoderVisitor {
|
||||
|
||||
|
||||
#if defined(VIXL_HAS_ABI_SUPPORT) && __cplusplus >= 201103L && \
|
||||
(defined(__clang__) || GCC_VERSION_OR_NEWER(4, 9, 1))
|
||||
(defined(_MSC_VER) || defined(__clang__) || GCC_VERSION_OR_NEWER(4, 9, 1))
|
||||
// Templated `RunFrom` version taking care of passing arguments and returning
|
||||
// the result value.
|
||||
// This allows code like:
|
||||
@@ -1307,6 +1360,8 @@ class Simulator : public DecoderVisitor {
|
||||
static const Instruction* kEndOfSimAddress;
|
||||
|
||||
// Simulation helpers.
|
||||
bool IsSimulationFinished() const { return pc_ == kEndOfSimAddress; }
|
||||
|
||||
const Instruction* ReadPc() const { return pc_; }
|
||||
VIXL_DEPRECATED("ReadPc", const Instruction* pc() const) { return ReadPc(); }
|
||||
|
||||
@@ -1456,6 +1511,7 @@ class Simulator : public DecoderVisitor {
|
||||
void SimulateNEONFPMulByElementLong(const Instruction* instr);
|
||||
void SimulateNEONComplexMulByElement(const Instruction* instr);
|
||||
void SimulateNEONDotProdByElement(const Instruction* instr);
|
||||
void SimulateNEONSHA3(const Instruction* instr);
|
||||
void SimulateMTEAddSubTag(const Instruction* instr);
|
||||
void SimulateMTETagMaskInsert(const Instruction* instr);
|
||||
void SimulateMTESubPointer(const Instruction* instr);
|
||||
@@ -1475,7 +1531,9 @@ class Simulator : public DecoderVisitor {
|
||||
void SimulateSetGM(const Instruction* instr);
|
||||
void SimulateSignedMinMax(const Instruction* instr);
|
||||
void SimulateUnsignedMinMax(const Instruction* instr);
|
||||
void SimulateSHA512(const Instruction* instr);
|
||||
|
||||
void VisitCryptoSM3(const Instruction* instr);
|
||||
|
||||
// Integer register accessors.
|
||||
|
||||
@@ -2006,62 +2064,66 @@ class Simulator : public DecoderVisitor {
|
||||
}
|
||||
|
||||
template <typename T, typename A>
|
||||
T MemRead(A address) const {
|
||||
std::optional<T> MemRead(A address) const {
|
||||
Instruction const* pc = ReadPc();
|
||||
return memory_.Read<T>(address, pc);
|
||||
}
|
||||
|
||||
template <typename T, typename A>
|
||||
void MemWrite(A address, T value) const {
|
||||
bool MemWrite(A address, T value) const {
|
||||
Instruction const* pc = ReadPc();
|
||||
return memory_.Write(address, value, pc);
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
uint64_t MemReadUint(int size_in_bytes, A address) const {
|
||||
std::optional<uint64_t> MemReadUint(int size_in_bytes, A address) const {
|
||||
return memory_.ReadUint(size_in_bytes, address);
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
int64_t MemReadInt(int size_in_bytes, A address) const {
|
||||
std::optional<int64_t> MemReadInt(int size_in_bytes, A address) const {
|
||||
return memory_.ReadInt(size_in_bytes, address);
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
void MemWrite(int size_in_bytes, A address, uint64_t value) const {
|
||||
bool MemWrite(int size_in_bytes, A address, uint64_t value) const {
|
||||
return memory_.Write(size_in_bytes, address, value);
|
||||
}
|
||||
|
||||
void LoadLane(LogicVRegister dst,
|
||||
bool LoadLane(LogicVRegister dst,
|
||||
VectorFormat vform,
|
||||
int index,
|
||||
uint64_t addr) const {
|
||||
unsigned msize_in_bytes = LaneSizeInBytesFromFormat(vform);
|
||||
LoadUintToLane(dst, vform, msize_in_bytes, index, addr);
|
||||
return LoadUintToLane(dst, vform, msize_in_bytes, index, addr);
|
||||
}
|
||||
|
||||
void LoadUintToLane(LogicVRegister dst,
|
||||
bool LoadUintToLane(LogicVRegister dst,
|
||||
VectorFormat vform,
|
||||
unsigned msize_in_bytes,
|
||||
int index,
|
||||
uint64_t addr) const {
|
||||
dst.SetUint(vform, index, MemReadUint(msize_in_bytes, addr));
|
||||
VIXL_DEFINE_OR_RETURN_FALSE(value, MemReadUint(msize_in_bytes, addr));
|
||||
dst.SetUint(vform, index, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
void LoadIntToLane(LogicVRegister dst,
|
||||
bool LoadIntToLane(LogicVRegister dst,
|
||||
VectorFormat vform,
|
||||
unsigned msize_in_bytes,
|
||||
int index,
|
||||
uint64_t addr) const {
|
||||
dst.SetInt(vform, index, MemReadInt(msize_in_bytes, addr));
|
||||
VIXL_DEFINE_OR_RETURN_FALSE(value, MemReadInt(msize_in_bytes, addr));
|
||||
dst.SetInt(vform, index, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
void StoreLane(const LogicVRegister& src,
|
||||
bool StoreLane(const LogicVRegister& src,
|
||||
VectorFormat vform,
|
||||
int index,
|
||||
uint64_t addr) const {
|
||||
unsigned msize_in_bytes = LaneSizeInBytesFromFormat(vform);
|
||||
MemWrite(msize_in_bytes, addr, src.Uint(vform, index));
|
||||
return MemWrite(msize_in_bytes, addr, src.Uint(vform, index));
|
||||
}
|
||||
|
||||
uint64_t ComputeMemOperandAddress(const MemOperand& mem_op) const;
|
||||
@@ -2072,12 +2134,14 @@ class Simulator : public DecoderVisitor {
|
||||
return ReadCPURegister<T>(operand.GetCPURegister());
|
||||
} else {
|
||||
VIXL_ASSERT(operand.IsMemOperand());
|
||||
return MemRead<T>(ComputeMemOperandAddress(operand.GetMemOperand()));
|
||||
auto res = MemRead<T>(ComputeMemOperandAddress(operand.GetMemOperand()));
|
||||
VIXL_ASSERT(res);
|
||||
return *res;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void WriteGenericOperand(GenericOperand operand,
|
||||
bool WriteGenericOperand(GenericOperand operand,
|
||||
T value,
|
||||
RegLogMode log_mode = LogRegWrites) {
|
||||
if (operand.IsCPURegister()) {
|
||||
@@ -2093,8 +2157,9 @@ class Simulator : public DecoderVisitor {
|
||||
WriteCPURegister(operand.GetCPURegister(), raw, log_mode);
|
||||
} else {
|
||||
VIXL_ASSERT(operand.IsMemOperand());
|
||||
MemWrite(ComputeMemOperandAddress(operand.GetMemOperand()), value);
|
||||
return MemWrite(ComputeMemOperandAddress(operand.GetMemOperand()), value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReadN() const { return nzcv_.GetN() != 0; }
|
||||
@@ -2470,12 +2535,16 @@ class Simulator : public DecoderVisitor {
|
||||
// Other state updates, including system registers.
|
||||
void PrintSystemRegister(SystemRegister id);
|
||||
void PrintTakenBranch(const Instruction* target);
|
||||
void PrintGCS(bool is_push, uint64_t addr, size_t entry);
|
||||
void LogSystemRegister(SystemRegister id) {
|
||||
if (ShouldTraceSysRegs()) PrintSystemRegister(id);
|
||||
}
|
||||
void LogTakenBranch(const Instruction* target) {
|
||||
if (ShouldTraceBranches()) PrintTakenBranch(target);
|
||||
}
|
||||
void LogGCS(bool is_push, uint64_t addr, size_t entry) {
|
||||
if (ShouldTraceSysRegs()) PrintGCS(is_push, addr, entry);
|
||||
}
|
||||
|
||||
// Trace memory accesses.
|
||||
|
||||
@@ -2837,7 +2906,7 @@ class Simulator : public DecoderVisitor {
|
||||
}
|
||||
|
||||
if (offset == 0) {
|
||||
while ((exclude & (1 << tag)) != 0) {
|
||||
while ((exclude & (uint64_t{1} << tag)) != 0) {
|
||||
tag = (tag + 1) % 16;
|
||||
}
|
||||
}
|
||||
@@ -2845,7 +2914,7 @@ class Simulator : public DecoderVisitor {
|
||||
while (offset > 0) {
|
||||
offset--;
|
||||
tag = (tag + 1) % 16;
|
||||
while ((exclude & (1 << tag)) != 0) {
|
||||
while ((exclude & (uint64_t{1} << tag)) != 0) {
|
||||
tag = (tag + 1) % 16;
|
||||
}
|
||||
}
|
||||
@@ -2857,12 +2926,15 @@ class Simulator : public DecoderVisitor {
|
||||
return (addr & ~(UINT64_C(0xf) << 56)) | (tag << 56);
|
||||
}
|
||||
|
||||
#if __linux__
|
||||
#define VIXL_HAS_SIMULATED_MMAP
|
||||
// Create or remove a mapping with memory protection. Memory attributes such
|
||||
// as MTE and BTI are represented by metadata in Simulator.
|
||||
void* Mmap(
|
||||
void* address, size_t length, int prot, int flags, int fd, off_t offset);
|
||||
|
||||
int Munmap(void* address, size_t length, int prot);
|
||||
#endif
|
||||
|
||||
// The common CPUFeatures interface with the set of available features.
|
||||
|
||||
@@ -2885,7 +2957,7 @@ class Simulator : public DecoderVisitor {
|
||||
// Also, the initialisation of the tuples in RuntimeCall(Non)Void is incorrect
|
||||
// in GCC before 4.9.1: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51253
|
||||
#if defined(VIXL_HAS_ABI_SUPPORT) && __cplusplus >= 201103L && \
|
||||
(defined(__clang__) || GCC_VERSION_OR_NEWER(4, 9, 1))
|
||||
(defined(_MSC_VER) || defined(__clang__) || GCC_VERSION_OR_NEWER(4, 9, 1))
|
||||
|
||||
#define VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT
|
||||
|
||||
@@ -2943,7 +3015,10 @@ class Simulator : public DecoderVisitor {
|
||||
R return_value = DoRuntimeCall(function,
|
||||
argument_operands,
|
||||
__local_index_sequence_for<P...>{});
|
||||
WriteGenericOperand(abi.GetReturnGenericOperand<R>(), return_value);
|
||||
bool succeeded =
|
||||
WriteGenericOperand(abi.GetReturnGenericOperand<R>(), return_value);
|
||||
USE(succeeded);
|
||||
VIXL_ASSERT(succeeded);
|
||||
}
|
||||
|
||||
template <typename R, typename... P>
|
||||
@@ -3076,8 +3151,9 @@ class Simulator : public DecoderVisitor {
|
||||
// either MTE protected or not.
|
||||
if (count != expected) {
|
||||
std::stringstream sstream;
|
||||
sstream << std::hex << "MTE WARNING : the memory region being unmapped "
|
||||
"starting at address 0x"
|
||||
sstream << std::hex
|
||||
<< "MTE WARNING : the memory region being unmapped "
|
||||
"starting at address 0x"
|
||||
<< reinterpret_cast<uint64_t>(address)
|
||||
<< "is not fully MTE protected.\n";
|
||||
VIXL_WARNING(sstream.str().c_str());
|
||||
@@ -3115,6 +3191,52 @@ class Simulator : public DecoderVisitor {
|
||||
meta_data_.RegisterBranchInterception(*function, callback);
|
||||
}
|
||||
|
||||
// Return the current output stream in use by the simulator.
|
||||
FILE* GetOutputStream() const { return stream_; }
|
||||
|
||||
bool IsDebuggerEnabled() const { return debugger_enabled_; }
|
||||
|
||||
void SetDebuggerEnabled(bool enabled) { debugger_enabled_ = enabled; }
|
||||
|
||||
Debugger* GetDebugger() const { return debugger_.get(); }
|
||||
|
||||
#ifdef VIXL_ENABLE_IMPLICIT_CHECKS
|
||||
// Returns true if the faulting instruction address (usually the program
|
||||
// counter or instruction pointer) comes from an internal VIXL memory access.
|
||||
// This can be used by signal handlers to check if a signal was raised from
|
||||
// the simulator (via TryMemoryAccess) before the actual
|
||||
// access occurs.
|
||||
bool IsSimulatedMemoryAccess(uintptr_t fault_pc) const {
|
||||
return (fault_pc ==
|
||||
reinterpret_cast<uintptr_t>(&_vixl_internal_ReadMemory));
|
||||
}
|
||||
|
||||
// Get the instruction address of the internal VIXL memory access continuation
|
||||
// label. Signal handlers can resume execution at this address to return to
|
||||
// TryMemoryAccess which will continue simulation.
|
||||
uintptr_t GetSignalReturnAddress() const {
|
||||
return reinterpret_cast<uintptr_t>(&_vixl_internal_AccessMemory_continue);
|
||||
}
|
||||
|
||||
// Replace the fault address reported by the kernel with the actual faulting
|
||||
// address.
|
||||
//
|
||||
// This is required because TryMemoryAccess reads a section of
|
||||
// memory 1 byte at a time meaning the fault address reported may not be the
|
||||
// base address of memory being accessed.
|
||||
void ReplaceFaultAddress(siginfo_t* siginfo, void* context) {
|
||||
#ifdef __x86_64__
|
||||
// The base address being accessed is passed in as the first argument to
|
||||
// _vixl_internal_ReadMemory.
|
||||
ucontext_t* uc = reinterpret_cast<ucontext_t*>(context);
|
||||
siginfo->si_addr = reinterpret_cast<void*>(uc->uc_mcontext.gregs[REG_RDI]);
|
||||
#else
|
||||
USE(siginfo);
|
||||
USE(context);
|
||||
#endif // __x86_64__
|
||||
}
|
||||
#endif // VIXL_ENABLE_IMPLICIT_CHECKS
|
||||
|
||||
protected:
|
||||
const char* clr_normal;
|
||||
const char* clr_flag_name;
|
||||
@@ -3195,8 +3317,9 @@ class Simulator : public DecoderVisitor {
|
||||
uint64_t left,
|
||||
uint64_t right,
|
||||
int carry_in);
|
||||
using vixl_uint128_t = std::pair<uint64_t, uint64_t>;
|
||||
vixl_uint128_t Add128(vixl_uint128_t x, vixl_uint128_t y);
|
||||
vixl_uint128_t Lsl128(vixl_uint128_t x, unsigned shift) const;
|
||||
vixl_uint128_t Eor128(vixl_uint128_t x, vixl_uint128_t y) const;
|
||||
vixl_uint128_t Mul64(uint64_t x, uint64_t y);
|
||||
vixl_uint128_t Neg128(vixl_uint128_t x);
|
||||
void LogicalHelper(const Instruction* instr, int64_t op2);
|
||||
@@ -3278,92 +3401,95 @@ class Simulator : public DecoderVisitor {
|
||||
uint64_t PolynomialMult(uint64_t op1,
|
||||
uint64_t op2,
|
||||
int lane_size_in_bits) const;
|
||||
vixl_uint128_t PolynomialMult128(uint64_t op1,
|
||||
uint64_t op2,
|
||||
int lane_size_in_bits) const;
|
||||
|
||||
void ld1(VectorFormat vform, LogicVRegister dst, uint64_t addr);
|
||||
void ld1(VectorFormat vform, LogicVRegister dst, int index, uint64_t addr);
|
||||
void ld1r(VectorFormat vform, LogicVRegister dst, uint64_t addr);
|
||||
void ld1r(VectorFormat vform,
|
||||
bool ld1(VectorFormat vform, LogicVRegister dst, uint64_t addr);
|
||||
bool ld1(VectorFormat vform, LogicVRegister dst, int index, uint64_t addr);
|
||||
bool ld1r(VectorFormat vform, LogicVRegister dst, uint64_t addr);
|
||||
bool ld1r(VectorFormat vform,
|
||||
VectorFormat unpack_vform,
|
||||
LogicVRegister dst,
|
||||
uint64_t addr,
|
||||
bool is_signed = false);
|
||||
void ld2(VectorFormat vform,
|
||||
bool ld2(VectorFormat vform,
|
||||
LogicVRegister dst1,
|
||||
LogicVRegister dst2,
|
||||
uint64_t addr);
|
||||
void ld2(VectorFormat vform,
|
||||
bool ld2(VectorFormat vform,
|
||||
LogicVRegister dst1,
|
||||
LogicVRegister dst2,
|
||||
int index,
|
||||
uint64_t addr);
|
||||
void ld2r(VectorFormat vform,
|
||||
bool ld2r(VectorFormat vform,
|
||||
LogicVRegister dst1,
|
||||
LogicVRegister dst2,
|
||||
uint64_t addr);
|
||||
void ld3(VectorFormat vform,
|
||||
bool ld3(VectorFormat vform,
|
||||
LogicVRegister dst1,
|
||||
LogicVRegister dst2,
|
||||
LogicVRegister dst3,
|
||||
uint64_t addr);
|
||||
void ld3(VectorFormat vform,
|
||||
bool ld3(VectorFormat vform,
|
||||
LogicVRegister dst1,
|
||||
LogicVRegister dst2,
|
||||
LogicVRegister dst3,
|
||||
int index,
|
||||
uint64_t addr);
|
||||
void ld3r(VectorFormat vform,
|
||||
bool ld3r(VectorFormat vform,
|
||||
LogicVRegister dst1,
|
||||
LogicVRegister dst2,
|
||||
LogicVRegister dst3,
|
||||
uint64_t addr);
|
||||
void ld4(VectorFormat vform,
|
||||
bool ld4(VectorFormat vform,
|
||||
LogicVRegister dst1,
|
||||
LogicVRegister dst2,
|
||||
LogicVRegister dst3,
|
||||
LogicVRegister dst4,
|
||||
uint64_t addr);
|
||||
void ld4(VectorFormat vform,
|
||||
bool ld4(VectorFormat vform,
|
||||
LogicVRegister dst1,
|
||||
LogicVRegister dst2,
|
||||
LogicVRegister dst3,
|
||||
LogicVRegister dst4,
|
||||
int index,
|
||||
uint64_t addr);
|
||||
void ld4r(VectorFormat vform,
|
||||
bool ld4r(VectorFormat vform,
|
||||
LogicVRegister dst1,
|
||||
LogicVRegister dst2,
|
||||
LogicVRegister dst3,
|
||||
LogicVRegister dst4,
|
||||
uint64_t addr);
|
||||
void st1(VectorFormat vform, LogicVRegister src, uint64_t addr);
|
||||
void st1(VectorFormat vform, LogicVRegister src, int index, uint64_t addr);
|
||||
void st2(VectorFormat vform,
|
||||
bool st1(VectorFormat vform, LogicVRegister src, uint64_t addr);
|
||||
bool st1(VectorFormat vform, LogicVRegister src, int index, uint64_t addr);
|
||||
bool st2(VectorFormat vform,
|
||||
LogicVRegister src,
|
||||
LogicVRegister src2,
|
||||
uint64_t addr);
|
||||
void st2(VectorFormat vform,
|
||||
bool st2(VectorFormat vform,
|
||||
LogicVRegister src,
|
||||
LogicVRegister src2,
|
||||
int index,
|
||||
uint64_t addr);
|
||||
void st3(VectorFormat vform,
|
||||
bool st3(VectorFormat vform,
|
||||
LogicVRegister src,
|
||||
LogicVRegister src2,
|
||||
LogicVRegister src3,
|
||||
uint64_t addr);
|
||||
void st3(VectorFormat vform,
|
||||
bool st3(VectorFormat vform,
|
||||
LogicVRegister src,
|
||||
LogicVRegister src2,
|
||||
LogicVRegister src3,
|
||||
int index,
|
||||
uint64_t addr);
|
||||
void st4(VectorFormat vform,
|
||||
bool st4(VectorFormat vform,
|
||||
LogicVRegister src,
|
||||
LogicVRegister src2,
|
||||
LogicVRegister src3,
|
||||
LogicVRegister src4,
|
||||
uint64_t addr);
|
||||
void st4(VectorFormat vform,
|
||||
bool st4(VectorFormat vform,
|
||||
LogicVRegister src,
|
||||
LogicVRegister src2,
|
||||
LogicVRegister src3,
|
||||
@@ -3649,6 +3775,10 @@ class Simulator : public DecoderVisitor {
|
||||
LogicVRegister dst,
|
||||
const LogicVRegister& src,
|
||||
int rotation);
|
||||
LogicVRegister rol(VectorFormat vform,
|
||||
LogicVRegister dst,
|
||||
const LogicVRegister& src,
|
||||
int rotation);
|
||||
LogicVRegister ext(VectorFormat vform,
|
||||
LogicVRegister dst,
|
||||
const LogicVRegister& src1,
|
||||
@@ -4373,6 +4503,90 @@ class Simulator : public DecoderVisitor {
|
||||
LogicVRegister srcdst,
|
||||
const LogicVRegister& src1,
|
||||
const LogicVRegister& src2);
|
||||
|
||||
template <unsigned N>
|
||||
static void SHARotateEltsLeftOne(uint64_t (&x)[N]) {
|
||||
VIXL_STATIC_ASSERT(N == 4);
|
||||
uint64_t temp = x[3];
|
||||
x[3] = x[2];
|
||||
x[2] = x[1];
|
||||
x[1] = x[0];
|
||||
x[0] = temp;
|
||||
}
|
||||
|
||||
template <uint32_t mode>
|
||||
LogicVRegister sha1(LogicVRegister srcdst,
|
||||
const LogicVRegister& src1,
|
||||
const LogicVRegister& src2) {
|
||||
uint64_t y = src1.Uint(kFormat4S, 0);
|
||||
uint64_t sd[4] = {};
|
||||
srcdst.UintArray(kFormat4S, sd);
|
||||
|
||||
for (unsigned i = 0; i < ArrayLength(sd); i++) {
|
||||
uint64_t t = CryptoOp<mode>(sd[1], sd[2], sd[3]);
|
||||
|
||||
y += RotateLeft(sd[0], 5, kSRegSize) + t;
|
||||
y += src2.Uint(kFormat4S, i);
|
||||
|
||||
sd[1] = RotateLeft(sd[1], 30, kSRegSize);
|
||||
|
||||
// y:sd = ROL(y:sd, 32)
|
||||
SHARotateEltsLeftOne(sd);
|
||||
std::swap(sd[0], y);
|
||||
}
|
||||
|
||||
srcdst.SetUintArray(kFormat4S, sd);
|
||||
return srcdst;
|
||||
}
|
||||
|
||||
LogicVRegister sha2h(LogicVRegister srcdst,
|
||||
const LogicVRegister& src1,
|
||||
const LogicVRegister& src2,
|
||||
bool part1);
|
||||
LogicVRegister sha2su0(LogicVRegister srcdst, const LogicVRegister& src1);
|
||||
LogicVRegister sha2su1(LogicVRegister srcdst,
|
||||
const LogicVRegister& src1,
|
||||
const LogicVRegister& src2);
|
||||
LogicVRegister sha512h(LogicVRegister srcdst,
|
||||
const LogicVRegister& src1,
|
||||
const LogicVRegister& src2);
|
||||
LogicVRegister sha512h2(LogicVRegister srcdst,
|
||||
const LogicVRegister& src1,
|
||||
const LogicVRegister& src2);
|
||||
LogicVRegister sha512su0(LogicVRegister srcdst, const LogicVRegister& src1);
|
||||
LogicVRegister sha512su1(LogicVRegister srcdst,
|
||||
const LogicVRegister& src1,
|
||||
const LogicVRegister& src2);
|
||||
|
||||
|
||||
LogicVRegister aes(LogicVRegister srcdst,
|
||||
const LogicVRegister& src1,
|
||||
bool decrypt);
|
||||
LogicVRegister aesmix(LogicVRegister srcdst,
|
||||
const LogicVRegister& src1,
|
||||
bool inverse);
|
||||
|
||||
LogicVRegister sm3partw1(LogicVRegister dst,
|
||||
const LogicVRegister& src1,
|
||||
const LogicVRegister& src2);
|
||||
LogicVRegister sm3partw2(LogicVRegister dst,
|
||||
const LogicVRegister& src1,
|
||||
const LogicVRegister& src2);
|
||||
LogicVRegister sm3ss1(LogicVRegister dst,
|
||||
const LogicVRegister& src1,
|
||||
const LogicVRegister& src2,
|
||||
const LogicVRegister& src3);
|
||||
LogicVRegister sm3tt1(LogicVRegister srcdst,
|
||||
const LogicVRegister& src1,
|
||||
const LogicVRegister& src2,
|
||||
int index,
|
||||
bool is_a);
|
||||
LogicVRegister sm3tt2(LogicVRegister srcdst,
|
||||
const LogicVRegister& src1,
|
||||
const LogicVRegister& src2,
|
||||
int index,
|
||||
bool is_a);
|
||||
|
||||
#define NEON_3VREG_LOGIC_LIST(V) \
|
||||
V(addhn) \
|
||||
V(addhn2) \
|
||||
@@ -4940,7 +5154,8 @@ class Simulator : public DecoderVisitor {
|
||||
unsigned zt_code,
|
||||
const LogicSVEAddressVector& addr);
|
||||
// Load each active zt<i>[lane] from `addr.GetElementAddress(lane, ...)`.
|
||||
void SVEStructuredLoadHelper(VectorFormat vform,
|
||||
// Returns false if a load failed.
|
||||
bool SVEStructuredLoadHelper(VectorFormat vform,
|
||||
const LogicPRegister& pg,
|
||||
unsigned zt_code,
|
||||
const LogicSVEAddressVector& addr,
|
||||
@@ -5138,10 +5353,12 @@ class Simulator : public DecoderVisitor {
|
||||
|
||||
bool CanReadMemory(uintptr_t address, size_t size);
|
||||
|
||||
#ifndef _WIN32
|
||||
// CanReadMemory needs placeholder file descriptors, so we use a pipe. We can
|
||||
// save some system call overhead by opening them on construction, rather than
|
||||
// on every call to CanReadMemory.
|
||||
int placeholder_pipe_fd_[2];
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
static T FPDefaultNaN();
|
||||
@@ -5220,11 +5437,15 @@ class Simulator : public DecoderVisitor {
|
||||
CPUFeaturesAuditor cpu_features_auditor_;
|
||||
std::vector<CPUFeatures> saved_cpu_features_;
|
||||
|
||||
// State for *rand48 functions, used to simulate randomness with repeatable
|
||||
// linear_congruential_engine, used to simulate randomness with repeatable
|
||||
// behaviour (so that tests are deterministic). This is used to simulate RNDR
|
||||
// and RNDRRS, as well as to simulate a source of entropy for architecturally
|
||||
// undefined behaviour.
|
||||
uint16_t rand_state_[3];
|
||||
std::linear_congruential_engine<uint64_t,
|
||||
0x5DEECE66D,
|
||||
0xB,
|
||||
static_cast<uint64_t>(1) << 48>
|
||||
rand_gen_;
|
||||
|
||||
// A configurable size of SVE vector registers.
|
||||
unsigned vector_length_;
|
||||
@@ -5232,6 +5453,167 @@ class Simulator : public DecoderVisitor {
|
||||
// Representation of memory attributes such as MTE tagging and BTI page
|
||||
// protection in addition to branch interceptions.
|
||||
MetaDataDepot meta_data_;
|
||||
|
||||
// True if the debugger is enabled and might get entered.
|
||||
bool debugger_enabled_;
|
||||
|
||||
// Debugger for the simulator.
|
||||
std::unique_ptr<Debugger> debugger_;
|
||||
|
||||
// The Guarded Control Stack is represented using a vector, where the more
|
||||
// recently stored addresses are at higher-numbered indices.
|
||||
using GuardedControlStack = std::vector<uint64_t>;
|
||||
|
||||
// The GCSManager handles the synchronisation of GCS across multiple
|
||||
// Simulator instances. Each Simulator has its own stack, but all share
|
||||
// a GCSManager instance. This allows exchanging stacks between Simulators
|
||||
// in a threaded application.
|
||||
class GCSManager {
|
||||
public:
|
||||
// Allocate a new Guarded Control Stack and add it to the vector of stacks.
|
||||
uint64_t AllocateStack() {
|
||||
const std::lock_guard<std::mutex> lock(stacks_mtx_);
|
||||
|
||||
GuardedControlStack* new_stack = new GuardedControlStack;
|
||||
uint64_t result;
|
||||
|
||||
// Put the new stack into the first available slot.
|
||||
for (result = 0; result < stacks_.size(); result++) {
|
||||
if (stacks_[result] == nullptr) {
|
||||
stacks_[result] = new_stack;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If there were no slots, create a new one.
|
||||
if (result == stacks_.size()) {
|
||||
stacks_.push_back(new_stack);
|
||||
}
|
||||
|
||||
// Shift the index to look like a stack pointer aligned to a page.
|
||||
result <<= kPageSizeLog2;
|
||||
|
||||
// Push the tagged index onto the new stack as a seal.
|
||||
new_stack->push_back(result + 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Free a Guarded Control Stack and set the stacks_ slot to null.
|
||||
void FreeStack(uint64_t gcs) {
|
||||
const std::lock_guard<std::mutex> lock(stacks_mtx_);
|
||||
uint64_t gcs_index = GetGCSIndex(gcs);
|
||||
GuardedControlStack* gcsptr = stacks_[gcs_index];
|
||||
if (gcsptr == nullptr) {
|
||||
VIXL_ABORT_WITH_MSG("Tried to free unallocated GCS ");
|
||||
} else {
|
||||
delete gcsptr;
|
||||
stacks_[gcs_index] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Get a pointer to the GCS vector using a GCS id.
|
||||
GuardedControlStack* GetGCSPtr(uint64_t gcs) const {
|
||||
return stacks_[GetGCSIndex(gcs)];
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t GetGCSIndex(uint64_t gcs) const { return gcs >> 12; }
|
||||
|
||||
std::vector<GuardedControlStack*> stacks_;
|
||||
std::mutex stacks_mtx_;
|
||||
};
|
||||
|
||||
// A GCS id indicating no GCS has been allocated.
|
||||
static const uint64_t kGCSNoStack = kPageSize - 1;
|
||||
uint64_t gcs_;
|
||||
bool gcs_enabled_;
|
||||
|
||||
public:
|
||||
GCSManager& GetGCSManager() {
|
||||
static GCSManager manager;
|
||||
return manager;
|
||||
}
|
||||
|
||||
void EnableGCSCheck() { gcs_enabled_ = true; }
|
||||
void DisableGCSCheck() { gcs_enabled_ = false; }
|
||||
bool IsGCSCheckEnabled() const { return gcs_enabled_; }
|
||||
|
||||
private:
|
||||
bool IsAllocatedGCS(uint64_t gcs) const { return gcs != kGCSNoStack; }
|
||||
void ResetGCSState() {
|
||||
GCSManager& m = GetGCSManager();
|
||||
if (IsAllocatedGCS(gcs_)) {
|
||||
m.FreeStack(gcs_);
|
||||
}
|
||||
ActivateGCS(m.AllocateStack());
|
||||
GCSPop(); // Remove seal.
|
||||
}
|
||||
|
||||
GuardedControlStack* GetGCSPtr(uint64_t gcs) {
|
||||
GCSManager& m = GetGCSManager();
|
||||
GuardedControlStack* result = m.GetGCSPtr(gcs);
|
||||
return result;
|
||||
}
|
||||
GuardedControlStack* GetActiveGCSPtr() { return GetGCSPtr(gcs_); }
|
||||
|
||||
uint64_t ActivateGCS(uint64_t gcs) {
|
||||
uint64_t outgoing_gcs = gcs_;
|
||||
gcs_ = gcs;
|
||||
return outgoing_gcs;
|
||||
}
|
||||
|
||||
void GCSPush(uint64_t addr) {
|
||||
GetActiveGCSPtr()->push_back(addr);
|
||||
size_t entry = GetActiveGCSPtr()->size() - 1;
|
||||
LogGCS(/* is_push = */ true, addr, entry);
|
||||
}
|
||||
|
||||
uint64_t GCSPop() {
|
||||
GuardedControlStack* gcs = GetActiveGCSPtr();
|
||||
if (gcs->empty()) {
|
||||
return 0;
|
||||
}
|
||||
uint64_t return_addr = gcs->back();
|
||||
size_t entry = gcs->size() - 1;
|
||||
gcs->pop_back();
|
||||
LogGCS(/* is_push = */ false, return_addr, entry);
|
||||
return return_addr;
|
||||
}
|
||||
|
||||
uint64_t GCSPeek() {
|
||||
GuardedControlStack* gcs = GetActiveGCSPtr();
|
||||
if (gcs->empty()) {
|
||||
return 0;
|
||||
}
|
||||
uint64_t return_addr = gcs->back();
|
||||
return return_addr;
|
||||
}
|
||||
|
||||
void ReportGCSFailure(const char* msg) {
|
||||
if (IsGCSCheckEnabled()) {
|
||||
GuardedControlStack* gcs = GetActiveGCSPtr();
|
||||
printf("%s", msg);
|
||||
if (gcs == nullptr) {
|
||||
printf("GCS pointer is null\n");
|
||||
} else {
|
||||
printf("GCS records, most recent first:\n");
|
||||
int most_recent_index = static_cast<int>(gcs->size()) - 1;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (!gcs->empty()) {
|
||||
uint64_t entry = gcs->back();
|
||||
gcs->pop_back();
|
||||
int index = most_recent_index - i;
|
||||
printf(" gcs%" PRIu64 "[%d]: 0x%016" PRIx64 "\n",
|
||||
gcs_,
|
||||
index,
|
||||
entry);
|
||||
}
|
||||
}
|
||||
printf("End of GCS records.\n");
|
||||
}
|
||||
VIXL_ABORT_WITH_MSG("GCS failed ");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT) && __cplusplus < 201402L
|
||||
|
||||
@@ -43,6 +43,9 @@ namespace internal {
|
||||
|
||||
class AssemblerBase {
|
||||
public:
|
||||
AssemblerBase() : allow_assembler_(false) {}
|
||||
explicit AssemblerBase(size_t capacity)
|
||||
: buffer_(capacity), allow_assembler_(false) {}
|
||||
AssemblerBase(byte* buffer, size_t capacity)
|
||||
: buffer_(buffer, capacity), allow_assembler_(false) {}
|
||||
|
||||
|
||||
29
3rdparty/vixl/include/vixl/code-buffer-vixl.h
vendored
29
3rdparty/vixl/include/vixl/code-buffer-vixl.h
vendored
@@ -36,11 +36,21 @@ namespace vixl {
|
||||
|
||||
class CodeBuffer {
|
||||
public:
|
||||
static const size_t kDefaultCapacity = 4 * KBytes;
|
||||
|
||||
explicit CodeBuffer(size_t capacity = kDefaultCapacity);
|
||||
CodeBuffer(byte* buffer, size_t capacity);
|
||||
~CodeBuffer() VIXL_NEGATIVE_TESTING_ALLOW_EXCEPTION;
|
||||
|
||||
void Reset();
|
||||
|
||||
// Make the buffer executable or writable. These states are mutually
|
||||
// exclusive.
|
||||
// Note that these require page-aligned memory blocks, which we can only
|
||||
// guarantee with VIXL_CODE_BUFFER_MMAP.
|
||||
void SetExecutable();
|
||||
void SetWritable();
|
||||
|
||||
ptrdiff_t GetOffsetFrom(ptrdiff_t offset) const {
|
||||
ptrdiff_t cursor_offset = cursor_ - buffer_;
|
||||
VIXL_ASSERT((offset >= 0) && (offset <= cursor_offset));
|
||||
@@ -136,6 +146,10 @@ class CodeBuffer {
|
||||
return GetCapacity();
|
||||
}
|
||||
|
||||
bool IsManaged() const { return managed_; }
|
||||
|
||||
void Grow(size_t new_capacity);
|
||||
|
||||
bool IsDirty() const { return dirty_; }
|
||||
|
||||
void SetClean() { dirty_ = false; }
|
||||
@@ -144,9 +158,24 @@ class CodeBuffer {
|
||||
return GetRemainingBytes() >= amount;
|
||||
}
|
||||
|
||||
void EnsureSpaceFor(size_t amount, bool* has_grown) {
|
||||
bool is_full = !HasSpaceFor(amount);
|
||||
if (is_full) Grow(capacity_ * 2 + amount);
|
||||
VIXL_ASSERT(has_grown != NULL);
|
||||
*has_grown = is_full;
|
||||
}
|
||||
void EnsureSpaceFor(size_t amount) {
|
||||
bool placeholder;
|
||||
EnsureSpaceFor(amount, &placeholder);
|
||||
}
|
||||
|
||||
private:
|
||||
// Backing store of the buffer.
|
||||
byte* buffer_;
|
||||
// If true the backing store is allocated and deallocated by the buffer. The
|
||||
// backing store can then grow on demand. If false the backing store is
|
||||
// provided by the user and cannot be resized internally.
|
||||
bool managed_;
|
||||
// Pointer to the next location to be written.
|
||||
byte* cursor_;
|
||||
// True if there has been any write since the buffer was created or cleaned.
|
||||
|
||||
@@ -68,14 +68,19 @@ class CodeBufferCheckScope {
|
||||
size_t size,
|
||||
BufferSpacePolicy check_policy = kReserveBufferSpace,
|
||||
SizePolicy size_policy = kMaximumSize)
|
||||
: assembler_(NULL), initialised_(false) {
|
||||
: CodeBufferCheckScope() {
|
||||
Open(assembler, size, check_policy, size_policy);
|
||||
}
|
||||
|
||||
// This constructor does not implicitly initialise the scope. Instead, the
|
||||
// user is required to explicitly call the `Open` function before using the
|
||||
// scope.
|
||||
CodeBufferCheckScope() : assembler_(NULL), initialised_(false) {
|
||||
CodeBufferCheckScope()
|
||||
: assembler_(NULL),
|
||||
assert_policy_(kMaximumSize),
|
||||
limit_(0),
|
||||
previous_allow_assembler_(false),
|
||||
initialised_(false) {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
@@ -90,7 +95,7 @@ class CodeBufferCheckScope {
|
||||
VIXL_ASSERT(assembler != NULL);
|
||||
assembler_ = assembler;
|
||||
if (check_policy == kReserveBufferSpace) {
|
||||
VIXL_ASSERT(assembler->GetBuffer()->HasSpaceFor(size));
|
||||
assembler->GetBuffer()->EnsureSpaceFor(size);
|
||||
}
|
||||
#ifdef VIXL_DEBUG
|
||||
limit_ = assembler_->GetSizeOfCodeGenerated() + size;
|
||||
@@ -152,14 +157,15 @@ class EmissionCheckScope : public CodeBufferCheckScope {
|
||||
// constructed.
|
||||
EmissionCheckScope(MacroAssemblerInterface* masm,
|
||||
size_t size,
|
||||
SizePolicy size_policy = kMaximumSize) {
|
||||
SizePolicy size_policy = kMaximumSize)
|
||||
: EmissionCheckScope() {
|
||||
Open(masm, size, size_policy);
|
||||
}
|
||||
|
||||
// This constructor does not implicitly initialise the scope. Instead, the
|
||||
// user is required to explicitly call the `Open` function before using the
|
||||
// scope.
|
||||
EmissionCheckScope() {}
|
||||
EmissionCheckScope() : masm_(nullptr), pool_policy_(kBlockPools) {}
|
||||
|
||||
virtual ~EmissionCheckScope() { Close(); }
|
||||
|
||||
@@ -250,14 +256,15 @@ class ExactAssemblyScope : public EmissionCheckScope {
|
||||
// constructed.
|
||||
ExactAssemblyScope(MacroAssemblerInterface* masm,
|
||||
size_t size,
|
||||
SizePolicy size_policy = kExactSize) {
|
||||
SizePolicy size_policy = kExactSize)
|
||||
: ExactAssemblyScope() {
|
||||
Open(masm, size, size_policy);
|
||||
}
|
||||
|
||||
// This constructor does not implicitly initialise the scope. Instead, the
|
||||
// user is required to explicitly call the `Open` function before using the
|
||||
// scope.
|
||||
ExactAssemblyScope() {}
|
||||
ExactAssemblyScope() : previous_allow_macro_assembler_(false) {}
|
||||
|
||||
virtual ~ExactAssemblyScope() { Close(); }
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#define VIXL_COMPILER_INTRINSICS_H
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "globals-vixl.h"
|
||||
|
||||
namespace vixl {
|
||||
@@ -112,7 +113,8 @@ inline int CountLeadingSignBits(V value, int width = (sizeof(V) * 8)) {
|
||||
VIXL_ASSERT(IsPowerOf2(width) && (width <= 64));
|
||||
#if COMPILER_HAS_BUILTIN_CLRSB
|
||||
VIXL_ASSERT((LLONG_MIN <= value) && (value <= LLONG_MAX));
|
||||
int ll_width = sizeof(long long) * kBitsPerByte; // NOLINT(runtime/int)
|
||||
int ll_width =
|
||||
sizeof(long long) * kBitsPerByte; // NOLINT(google-runtime-int)
|
||||
int result = __builtin_clrsbll(value) - (ll_width - width);
|
||||
// Check that the value fits in the specified width.
|
||||
VIXL_ASSERT(result >= 0);
|
||||
|
||||
3
3rdparty/vixl/include/vixl/cpu-features.h
vendored
3
3rdparty/vixl/include/vixl/cpu-features.h
vendored
@@ -201,7 +201,8 @@ namespace vixl {
|
||||
/* Extended BFloat16 instructions */ \
|
||||
V(kEBF16, "EBF16", "ebf16") \
|
||||
V(kSVE_EBF16, "EBF16 (SVE)", "sveebf16") \
|
||||
V(kCSSC, "CSSC", "cssc")
|
||||
V(kCSSC, "CSSC", "cssc") \
|
||||
V(kGCS, "GCS", "gcs")
|
||||
// clang-format on
|
||||
|
||||
|
||||
|
||||
16
3rdparty/vixl/include/vixl/globals-vixl.h
vendored
16
3rdparty/vixl/include/vixl/globals-vixl.h
vendored
@@ -27,8 +27,8 @@
|
||||
#ifndef VIXL_GLOBALS_H
|
||||
#define VIXL_GLOBALS_H
|
||||
|
||||
#if __cplusplus < 201402L
|
||||
#error VIXL requires C++14
|
||||
#if __cplusplus < 201703L
|
||||
#error VIXL requires C++17
|
||||
#endif
|
||||
|
||||
// Get standard C99 macros for integer types.
|
||||
@@ -215,6 +215,18 @@ inline void USE(const T1&, const T2&, const T3&, const T4&) {}
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
// Evaluate 'init' to an std::optional and return if it's empty. If 'init' is
|
||||
// not empty then define a variable 'name' with the value inside the
|
||||
// std::optional.
|
||||
#define VIXL_DEFINE_OR_RETURN(name, init) \
|
||||
auto opt##name = init; \
|
||||
if (!opt##name) return; \
|
||||
auto name = *opt##name;
|
||||
#define VIXL_DEFINE_OR_RETURN_FALSE(name, init) \
|
||||
auto opt##name = init; \
|
||||
if (!opt##name) return false; \
|
||||
auto name = *opt##name;
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
#define VIXL_NO_RETURN [[noreturn]]
|
||||
#else
|
||||
|
||||
31
3rdparty/vixl/include/vixl/invalset-vixl.h
vendored
31
3rdparty/vixl/include/vixl/invalset-vixl.h
vendored
@@ -1,4 +1,3 @@
|
||||
// Copyright 2015, VIXL authors
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
@@ -27,9 +26,8 @@
|
||||
#ifndef VIXL_INVALSET_H_
|
||||
#define VIXL_INVALSET_H_
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
#include "globals-vixl.h"
|
||||
@@ -92,6 +90,7 @@ class InvalSet {
|
||||
public:
|
||||
InvalSet();
|
||||
~InvalSet() VIXL_NEGATIVE_TESTING_ALLOW_EXCEPTION;
|
||||
InvalSet(InvalSet&&); // movable
|
||||
|
||||
static const size_t kNPreallocatedElements = N_PREALLOCATED_ELEMENTS;
|
||||
static const KeyType kInvalidKey = INVALID_KEY;
|
||||
@@ -245,12 +244,11 @@ class InvalSet {
|
||||
|
||||
template <class S>
|
||||
class InvalSetIterator {
|
||||
public:
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using value_type = typename S::_ElementType;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = typename S::_ElementType*;
|
||||
using reference = typename S::_ElementType&;
|
||||
using pointer = S*;
|
||||
using reference = S&;
|
||||
|
||||
private:
|
||||
// Redefine types to mirror the associated set types.
|
||||
@@ -327,6 +325,27 @@ InvalSet<TEMPLATE_INVALSET_P_DEF>::InvalSet()
|
||||
#endif
|
||||
}
|
||||
|
||||
template <TEMPLATE_INVALSET_P_DECL>
|
||||
InvalSet<TEMPLATE_INVALSET_P_DEF>::InvalSet(InvalSet&& other)
|
||||
: valid_cached_min_(false), sorted_(true), size_(0), vector_(NULL) {
|
||||
VIXL_ASSERT(other.monitor() == 0);
|
||||
if (this != &other) {
|
||||
sorted_ = other.sorted_;
|
||||
size_ = other.size_;
|
||||
#ifdef VIXL_DEBUG
|
||||
monitor_ = 0;
|
||||
#endif
|
||||
if (other.IsUsingVector()) {
|
||||
vector_ = other.vector_;
|
||||
other.vector_ = NULL;
|
||||
} else {
|
||||
std::move(other.preallocated_,
|
||||
other.preallocated_ + other.size_,
|
||||
preallocated_);
|
||||
}
|
||||
other.clear();
|
||||
}
|
||||
}
|
||||
|
||||
template <TEMPLATE_INVALSET_P_DECL>
|
||||
InvalSet<TEMPLATE_INVALSET_P_DEF>::~InvalSet()
|
||||
|
||||
@@ -27,10 +27,10 @@
|
||||
#ifndef VIXL_POOL_MANAGER_IMPL_H_
|
||||
#define VIXL_POOL_MANAGER_IMPL_H_
|
||||
|
||||
#include "pool-manager.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "assembler-base-vixl.h"
|
||||
#include "pool-manager.h"
|
||||
|
||||
namespace vixl {
|
||||
|
||||
@@ -487,7 +487,7 @@ void PoolManager<T>::Release(T pc) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
PoolManager<T>::~PoolManager<T>() VIXL_NEGATIVE_TESTING_ALLOW_EXCEPTION {
|
||||
PoolManager<T>::~PoolManager() VIXL_NEGATIVE_TESTING_ALLOW_EXCEPTION {
|
||||
#ifdef VIXL_DEBUG
|
||||
// Check for unbound objects.
|
||||
for (objects_iter iter = objects_.begin(); iter != objects_.end(); ++iter) {
|
||||
@@ -517,6 +517,6 @@ int PoolManager<T>::GetPoolSizeForTest() const {
|
||||
}
|
||||
return size;
|
||||
}
|
||||
}
|
||||
} // namespace vixl
|
||||
|
||||
#endif // VIXL_POOL_MANAGER_IMPL_H_
|
||||
|
||||
3
3rdparty/vixl/include/vixl/pool-manager.h
vendored
3
3rdparty/vixl/include/vixl/pool-manager.h
vendored
@@ -27,11 +27,10 @@
|
||||
#ifndef VIXL_POOL_MANAGER_H_
|
||||
#define VIXL_POOL_MANAGER_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
#include "globals-vixl.h"
|
||||
|
||||
49
3rdparty/vixl/include/vixl/utils-vixl.h
vendored
49
3rdparty/vixl/include/vixl/utils-vixl.h
vendored
@@ -239,6 +239,11 @@ inline uint64_t RotateRight(uint64_t value,
|
||||
return value & width_mask;
|
||||
}
|
||||
|
||||
inline uint64_t RotateLeft(uint64_t value,
|
||||
unsigned int rotate,
|
||||
unsigned int width) {
|
||||
return RotateRight(value, width - rotate, width);
|
||||
}
|
||||
|
||||
// Wrapper class for passing FP16 values through the assembler.
|
||||
// This is purely to aid with type checking/casting.
|
||||
@@ -291,6 +296,12 @@ T UnsignedNegate(T value) {
|
||||
return ~value + 1;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool CanBeNegated(T value) {
|
||||
VIXL_STATIC_ASSERT(std::is_signed<T>::value);
|
||||
return (value == std::numeric_limits<T>::min()) ? false : true;
|
||||
}
|
||||
|
||||
// An absolute operation for signed integers that is defined for results outside
|
||||
// the representable range. Specifically, Abs(MIN_INT) is MIN_INT.
|
||||
template <typename T>
|
||||
@@ -548,13 +559,14 @@ inline T SignExtend(T val, int size_in_bits) {
|
||||
template <typename T>
|
||||
T ReverseBytes(T value, int block_bytes_log2) {
|
||||
VIXL_ASSERT((sizeof(value) == 4) || (sizeof(value) == 8));
|
||||
VIXL_ASSERT((1U << block_bytes_log2) <= sizeof(value));
|
||||
VIXL_ASSERT((uint64_t{1} << block_bytes_log2) <= sizeof(value));
|
||||
// Split the 64-bit value into an 8-bit array, where b[0] is the least
|
||||
// significant byte, and b[7] is the most significant.
|
||||
uint8_t bytes[8];
|
||||
uint64_t mask = UINT64_C(0xff00000000000000);
|
||||
for (int i = 7; i >= 0; i--) {
|
||||
bytes[i] = (static_cast<uint64_t>(value) & mask) >> (i * 8);
|
||||
bytes[i] =
|
||||
static_cast<uint8_t>((static_cast<uint64_t>(value) & mask) >> (i * 8));
|
||||
mask >>= 8;
|
||||
}
|
||||
|
||||
@@ -611,6 +623,39 @@ bool IsWordAligned(T pointer) {
|
||||
return IsAligned<4>(pointer);
|
||||
}
|
||||
|
||||
template <unsigned BITS, typename T>
|
||||
bool IsRepeatingPattern(T value) {
|
||||
VIXL_STATIC_ASSERT(std::is_unsigned<T>::value);
|
||||
VIXL_ASSERT(IsMultiple(sizeof(value) * kBitsPerByte, BITS));
|
||||
VIXL_ASSERT(IsMultiple(BITS, 2));
|
||||
VIXL_STATIC_ASSERT(BITS >= 2);
|
||||
#if (defined(__x86_64__) || defined(__i386)) && \
|
||||
__clang_major__ >= 17 && __clang_major__ <= 19
|
||||
// Workaround for https://github.com/llvm/llvm-project/issues/108722
|
||||
unsigned hbits = BITS / 2;
|
||||
T midmask = (~static_cast<T>(0) >> BITS) << hbits;
|
||||
// E.g. for bytes in a word (0xb3b2b1b0): .b3b2b1. == .b2b1b0.
|
||||
return (((value >> hbits) & midmask) == ((value << hbits) & midmask));
|
||||
#else
|
||||
return value == RotateRight(value, BITS, sizeof(value) * kBitsPerByte);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool AllBytesMatch(T value) {
|
||||
return IsRepeatingPattern<kBitsPerByte>(value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool AllHalfwordsMatch(T value) {
|
||||
return IsRepeatingPattern<kBitsPerByte * 2>(value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool AllWordsMatch(T value) {
|
||||
return IsRepeatingPattern<kBitsPerByte * 4>(value);
|
||||
}
|
||||
|
||||
// Increment a pointer until it has the specified alignment. The alignment must
|
||||
// be a power of two.
|
||||
template <class T>
|
||||
|
||||
371
3rdparty/vixl/src/aarch64/assembler-aarch64.cc
vendored
371
3rdparty/vixl/src/aarch64/assembler-aarch64.cc
vendored
@@ -25,9 +25,10 @@
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
#include "assembler-aarch64.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "assembler-aarch64.h"
|
||||
#include "macro-assembler-aarch64.h"
|
||||
|
||||
namespace vixl {
|
||||
@@ -1176,8 +1177,7 @@ void Assembler::LoadStorePairNonTemporal(const CPURegister& rt,
|
||||
VIXL_ASSERT(addr.IsImmediateOffset());
|
||||
|
||||
unsigned size =
|
||||
CalcLSPairDataSize(static_cast<LoadStorePairOp>(
|
||||
static_cast<uint32_t>(op) & static_cast<uint32_t>(LoadStorePairMask)));
|
||||
CalcLSPairDataSize(static_cast<LoadStorePairOp>(op & LoadStorePairMask));
|
||||
VIXL_ASSERT(IsImmLSPair(addr.GetOffset(), size));
|
||||
int offset = static_cast<int>(addr.GetOffset());
|
||||
Emit(op | Rt(rt) | Rt2(rt2) | RnSP(addr.GetBaseRegister()) |
|
||||
@@ -1918,6 +1918,12 @@ void Assembler::sys(int op, const Register& xt) {
|
||||
}
|
||||
|
||||
|
||||
void Assembler::sysl(int op, const Register& xt) {
|
||||
VIXL_ASSERT(xt.Is64Bits());
|
||||
Emit(SYSL | SysOp(op) | Rt(xt));
|
||||
}
|
||||
|
||||
|
||||
void Assembler::dc(DataCacheOp op, const Register& rt) {
|
||||
if (op == CVAP) VIXL_ASSERT(CPUHas(CPUFeatures::kDCPoP));
|
||||
if (op == CVADP) VIXL_ASSERT(CPUHas(CPUFeatures::kDCCVADP));
|
||||
@@ -1930,6 +1936,35 @@ void Assembler::ic(InstructionCacheOp op, const Register& rt) {
|
||||
sys(op, rt);
|
||||
}
|
||||
|
||||
void Assembler::gcspushm(const Register& rt) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kGCS));
|
||||
sys(GCSPUSHM, rt);
|
||||
}
|
||||
|
||||
void Assembler::gcspopm(const Register& rt) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kGCS));
|
||||
sysl(GCSPOPM, rt);
|
||||
}
|
||||
|
||||
|
||||
void Assembler::gcsss1(const Register& rt) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kGCS));
|
||||
sys(GCSSS1, rt);
|
||||
}
|
||||
|
||||
|
||||
void Assembler::gcsss2(const Register& rt) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kGCS));
|
||||
sysl(GCSSS2, rt);
|
||||
}
|
||||
|
||||
|
||||
void Assembler::chkfeat(const Register& rd) {
|
||||
VIXL_ASSERT(rd.Is(x16));
|
||||
USE(rd);
|
||||
hint(CHKFEAT);
|
||||
}
|
||||
|
||||
|
||||
void Assembler::hint(SystemHint code) { hint(static_cast<int>(code)); }
|
||||
|
||||
@@ -2913,6 +2948,25 @@ void Assembler::st1(const VRegister& vt, int lane, const MemOperand& dst) {
|
||||
LoadStoreStructSingle(vt, lane, dst, NEONLoadStoreSingleStructStore1);
|
||||
}
|
||||
|
||||
void Assembler::pmull(const VRegister& vd,
|
||||
const VRegister& vn,
|
||||
const VRegister& vm) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(AreSameFormat(vn, vm));
|
||||
VIXL_ASSERT((vn.Is8B() && vd.Is8H()) || (vn.Is1D() && vd.Is1Q()));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kPmull1Q) || vd.Is8H());
|
||||
Emit(VFormat(vn) | NEON_PMULL | Rm(vm) | Rn(vn) | Rd(vd));
|
||||
}
|
||||
|
||||
void Assembler::pmull2(const VRegister& vd,
|
||||
const VRegister& vn,
|
||||
const VRegister& vm) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(AreSameFormat(vn, vm));
|
||||
VIXL_ASSERT((vn.Is16B() && vd.Is8H()) || (vn.Is2D() && vd.Is1Q()));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kPmull1Q) || vd.Is8H());
|
||||
Emit(VFormat(vn) | NEON_PMULL2 | Rm(vm) | Rn(vn) | Rd(vd));
|
||||
}
|
||||
|
||||
void Assembler::NEON3DifferentL(const VRegister& vd,
|
||||
const VRegister& vn,
|
||||
@@ -2925,7 +2979,7 @@ void Assembler::NEON3DifferentL(const VRegister& vd,
|
||||
(vn.Is8H() && vd.Is4S()) || (vn.Is4S() && vd.Is2D()));
|
||||
Instr format, op = vop;
|
||||
if (vd.IsScalar()) {
|
||||
op |= static_cast<Instr>(NEON_Q) | static_cast<Instr>(NEONScalar);
|
||||
op |= NEON_Q | NEONScalar;
|
||||
format = SFormat(vn);
|
||||
} else {
|
||||
format = VFormat(vn);
|
||||
@@ -2960,8 +3014,6 @@ void Assembler::NEON3DifferentHN(const VRegister& vd,
|
||||
|
||||
// clang-format off
|
||||
#define NEON_3DIFF_LONG_LIST(V) \
|
||||
V(pmull, NEON_PMULL, vn.IsVector() && vn.Is8B()) \
|
||||
V(pmull2, NEON_PMULL2, vn.IsVector() && vn.Is16B()) \
|
||||
V(saddl, NEON_SADDL, vn.IsVector() && vn.IsD()) \
|
||||
V(saddl2, NEON_SADDL2, vn.IsVector() && vn.IsQ()) \
|
||||
V(sabal, NEON_SABAL, vn.IsVector() && vn.IsD()) \
|
||||
@@ -3650,7 +3702,7 @@ void Assembler::NEONFPConvertToInt(const VRegister& vd,
|
||||
Instr op) {
|
||||
if (vn.IsScalar()) {
|
||||
VIXL_ASSERT((vd.Is1S() && vn.Is1S()) || (vd.Is1D() && vn.Is1D()));
|
||||
op |= static_cast<Instr>(NEON_Q) | static_cast<Instr>(NEONScalar);
|
||||
op |= NEON_Q | NEONScalar;
|
||||
}
|
||||
Emit(FPFormat(vn) | op | Rn(vn) | Rd(vd));
|
||||
}
|
||||
@@ -3662,9 +3714,9 @@ void Assembler::NEONFP16ConvertToInt(const VRegister& vd,
|
||||
VIXL_ASSERT(AreSameFormat(vd, vn));
|
||||
VIXL_ASSERT(vn.IsLaneSizeH());
|
||||
if (vn.IsScalar()) {
|
||||
op |= static_cast<Instr>(NEON_Q) | static_cast<Instr>(NEONScalar);
|
||||
op |= NEON_Q | NEONScalar;
|
||||
} else if (vn.Is8H()) {
|
||||
op |= static_cast<Instr>(NEON_Q);
|
||||
op |= NEON_Q;
|
||||
}
|
||||
Emit(op | Rn(vn) | Rd(vd));
|
||||
}
|
||||
@@ -3838,7 +3890,7 @@ void Assembler::NEON3Same(const VRegister& vd,
|
||||
|
||||
Instr format, op = vop;
|
||||
if (vd.IsScalar()) {
|
||||
op |= static_cast<Instr>(NEON_Q) | static_cast<Instr>(NEONScalar);
|
||||
op |= NEON_Q | NEONScalar;
|
||||
format = SFormat(vd);
|
||||
} else {
|
||||
format = VFormat(vd);
|
||||
@@ -3890,18 +3942,15 @@ void Assembler::NEON3SameFP16(const VRegister& vd,
|
||||
Instr op; \
|
||||
if (vd.IsScalar()) { \
|
||||
if (vd.Is1H()) { \
|
||||
if ((static_cast<uint32_t>(SCA_OP_H) & \
|
||||
static_cast<uint32_t>(NEONScalar2RegMiscFP16FMask)) == \
|
||||
static_cast<uint32_t>(NEONScalar2RegMiscFP16Fixed)) { \
|
||||
if ((SCA_OP_H & NEONScalar2RegMiscFP16FMask) == \
|
||||
NEONScalar2RegMiscFP16Fixed) { \
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON, CPUFeatures::kNEONHalf)); \
|
||||
} else { \
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kFPHalf)); \
|
||||
} \
|
||||
op = SCA_OP_H; \
|
||||
} else { \
|
||||
if ((static_cast<uint32_t>(SCA_OP) & \
|
||||
static_cast<uint32_t>(NEONScalar2RegMiscFMask)) == \
|
||||
static_cast<uint32_t>(NEONScalar2RegMiscFixed)) { \
|
||||
if ((SCA_OP & NEONScalar2RegMiscFMask) == NEONScalar2RegMiscFixed) { \
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON)); \
|
||||
} \
|
||||
VIXL_ASSERT(vd.Is1S() || vd.Is1D()); \
|
||||
@@ -3915,7 +3964,7 @@ void Assembler::NEON3SameFP16(const VRegister& vd,
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEONHalf)); \
|
||||
op = VEC_OP##_H; \
|
||||
if (vd.Is8H()) { \
|
||||
op |= static_cast<Instr>(NEON_Q); \
|
||||
op |= NEON_Q; \
|
||||
} \
|
||||
} else { \
|
||||
op = VEC_OP; \
|
||||
@@ -3981,7 +4030,7 @@ void Assembler::NEON2RegMisc(const VRegister& vd,
|
||||
|
||||
Instr format, op = vop;
|
||||
if (vd.IsScalar()) {
|
||||
op |= static_cast<Instr>(NEON_Q) | static_cast<Instr>(NEONScalar);
|
||||
op |= NEON_Q | NEONScalar;
|
||||
format = SFormat(vd);
|
||||
} else {
|
||||
format = VFormat(vd);
|
||||
@@ -4057,7 +4106,7 @@ void Assembler::NEONFP2RegMisc(const VRegister& vd,
|
||||
Instr op = vop;
|
||||
if (vd.IsScalar()) {
|
||||
VIXL_ASSERT(vd.Is1S() || vd.Is1D());
|
||||
op |= static_cast<Instr>(NEON_Q) | static_cast<Instr>(NEONScalar);
|
||||
op |= NEON_Q | NEONScalar;
|
||||
} else {
|
||||
VIXL_ASSERT(vd.Is2S() || vd.Is2D() || vd.Is4S());
|
||||
}
|
||||
@@ -4077,11 +4126,11 @@ void Assembler::NEONFP2RegMiscFP16(const VRegister& vd,
|
||||
Instr op = vop;
|
||||
if (vd.IsScalar()) {
|
||||
VIXL_ASSERT(vd.Is1H());
|
||||
op |= static_cast<Instr>(NEON_Q) | static_cast<Instr>(NEONScalar);
|
||||
op |= NEON_Q | NEONScalar;
|
||||
} else {
|
||||
VIXL_ASSERT(vd.Is4H() || vd.Is8H());
|
||||
if (vd.Is8H()) {
|
||||
op |= static_cast<Instr>(NEON_Q);
|
||||
op |= NEON_Q;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4273,9 +4322,7 @@ NEON_3SAME_LIST(VIXL_DEFINE_ASM_FUNC)
|
||||
op = SCA_OP_H; \
|
||||
} else { \
|
||||
VIXL_ASSERT(vd.Is1H() || vd.Is1S() || vd.Is1D()); \
|
||||
if ((static_cast<uint32_t>(SCA_OP) & \
|
||||
static_cast<uint32_t>(NEONScalar3SameFMask)) == \
|
||||
static_cast<uint32_t>(NEONScalar3SameFixed)) { \
|
||||
if ((SCA_OP & NEONScalar3SameFMask) == NEONScalar3SameFixed) { \
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON)); \
|
||||
if (vd.Is1H()) VIXL_ASSERT(CPUHas(CPUFeatures::kNEONHalf)); \
|
||||
} else if (vd.Is1H()) { \
|
||||
@@ -4341,11 +4388,11 @@ void Assembler::sqrdmlah(const VRegister& vd,
|
||||
const VRegister& vm) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON, CPUFeatures::kRDM));
|
||||
VIXL_ASSERT(AreSameFormat(vd, vn, vm));
|
||||
VIXL_ASSERT(vd.IsVector() || !vd.IsQ());
|
||||
VIXL_ASSERT(vd.IsLaneSizeH() || vd.IsLaneSizeS());
|
||||
|
||||
Instr format, op = NEON_SQRDMLAH;
|
||||
if (vd.IsScalar()) {
|
||||
op |= static_cast<Instr>(NEON_Q) | static_cast<Instr>(NEONScalar);
|
||||
op |= NEON_Q | NEONScalar;
|
||||
format = SFormat(vd);
|
||||
} else {
|
||||
format = VFormat(vd);
|
||||
@@ -4360,11 +4407,11 @@ void Assembler::sqrdmlsh(const VRegister& vd,
|
||||
const VRegister& vm) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON, CPUFeatures::kRDM));
|
||||
VIXL_ASSERT(AreSameFormat(vd, vn, vm));
|
||||
VIXL_ASSERT(vd.IsVector() || !vd.IsQ());
|
||||
VIXL_ASSERT(vd.IsLaneSizeH() || vd.IsLaneSizeS());
|
||||
|
||||
Instr format, op = NEON_SQRDMLSH;
|
||||
if (vd.IsScalar()) {
|
||||
op |= static_cast<Instr>(NEON_Q) | static_cast<Instr>(NEONScalar);
|
||||
op |= NEON_Q | NEONScalar;
|
||||
format = SFormat(vd);
|
||||
} else {
|
||||
format = VFormat(vd);
|
||||
@@ -4625,13 +4672,13 @@ void Assembler::NEONFPByElement(const VRegister& vd,
|
||||
}
|
||||
|
||||
if (vd.IsScalar()) {
|
||||
op |= static_cast<Instr>(NEON_Q) | static_cast<Instr>(NEONScalar);
|
||||
op |= NEON_Q | NEONScalar;
|
||||
}
|
||||
|
||||
if (!vm.Is1H()) {
|
||||
op |= FPFormat(vd);
|
||||
} else if (vd.Is8H()) {
|
||||
op |= static_cast<Instr>(NEON_Q);
|
||||
op |= NEON_Q;
|
||||
}
|
||||
|
||||
Emit(op | ImmNEONHLM(vm_index, index_num_bits) | Rm(vm) | Rn(vn) | Rd(vd));
|
||||
@@ -4653,7 +4700,7 @@ void Assembler::NEONByElement(const VRegister& vd,
|
||||
Instr format, op = vop;
|
||||
int index_num_bits = vm.Is1H() ? 3 : 2;
|
||||
if (vd.IsScalar()) {
|
||||
op |= static_cast<Instr>(NEONScalar) | static_cast<Instr>(NEON_Q);
|
||||
op |= NEONScalar | NEON_Q;
|
||||
format = SFormat(vn);
|
||||
} else {
|
||||
format = VFormat(vn);
|
||||
@@ -4681,7 +4728,7 @@ void Assembler::NEONByElementL(const VRegister& vd,
|
||||
Instr format, op = vop;
|
||||
int index_num_bits = vm.Is1H() ? 3 : 2;
|
||||
if (vd.IsScalar()) {
|
||||
op |= static_cast<Instr>(NEONScalar) | static_cast<Instr>(NEON_Q);
|
||||
op |= NEONScalar | NEON_Q;
|
||||
format = SFormat(vn);
|
||||
} else {
|
||||
format = VFormat(vn);
|
||||
@@ -4917,7 +4964,7 @@ void Assembler::NEONXtn(const VRegister& vd,
|
||||
if (vd.IsScalar()) {
|
||||
VIXL_ASSERT((vd.Is1B() && vn.Is1H()) || (vd.Is1H() && vn.Is1S()) ||
|
||||
(vd.Is1S() && vn.Is1D()));
|
||||
op |= static_cast<Instr>(NEON_Q) | static_cast<Instr>(NEONScalar);
|
||||
op |= NEON_Q | NEONScalar;
|
||||
format = SFormat(vd);
|
||||
} else {
|
||||
VIXL_ASSERT((vd.Is8B() && vn.Is8H()) || (vd.Is4H() && vn.Is4S()) ||
|
||||
@@ -5829,6 +5876,247 @@ void Assembler::ummla(const VRegister& vd, const VRegister& vn, const VRegister&
|
||||
Emit(0x6e80a400 | Rd(vd) | Rn(vn) | Rm(vm));
|
||||
}
|
||||
|
||||
void Assembler::bcax(const VRegister& vd, const VRegister& vn, const VRegister& vm, const VRegister& va) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kSHA3));
|
||||
VIXL_ASSERT(vd.Is16B() && vn.Is16B() && vm.Is16B());
|
||||
|
||||
Emit(0xce200000 | Rd(vd) | Rn(vn) | Rm(vm) | Ra(va));
|
||||
}
|
||||
|
||||
void Assembler::eor3(const VRegister& vd, const VRegister& vn, const VRegister& vm, const VRegister& va) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kSHA3));
|
||||
VIXL_ASSERT(vd.Is16B() && vn.Is16B() && vm.Is16B() && va.Is16B());
|
||||
|
||||
Emit(0xce000000 | Rd(vd) | Rn(vn) | Rm(vm) | Ra(va));
|
||||
}
|
||||
|
||||
void Assembler::xar(const VRegister& vd, const VRegister& vn, const VRegister& vm, int rotate) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kSHA3));
|
||||
VIXL_ASSERT(vd.Is2D() && vn.Is2D() && vm.Is2D());
|
||||
VIXL_ASSERT(IsUint6(rotate));
|
||||
|
||||
Emit(0xce800000 | Rd(vd) | Rn(vn) | Rm(vm) | rotate << 10);
|
||||
}
|
||||
|
||||
void Assembler::rax1(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kSHA3));
|
||||
VIXL_ASSERT(vd.Is2D() && vn.Is2D() && vm.Is2D());
|
||||
|
||||
Emit(0xce608c00 | Rd(vd) | Rn(vn) | Rm(vm));
|
||||
}
|
||||
|
||||
void Assembler::sha1c(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kSHA1));
|
||||
VIXL_ASSERT(vd.IsQ() && vn.IsS() && vm.Is4S());
|
||||
|
||||
Emit(0x5e000000 | Rd(vd) | Rn(vn) | Rm(vm));
|
||||
}
|
||||
|
||||
void Assembler::sha1h(const VRegister& sd, const VRegister& sn) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kSHA1));
|
||||
VIXL_ASSERT(sd.IsS() && sn.IsS());
|
||||
|
||||
Emit(0x5e280800 | Rd(sd) | Rn(sn));
|
||||
}
|
||||
|
||||
void Assembler::sha1m(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kSHA1));
|
||||
VIXL_ASSERT(vd.IsQ() && vn.IsS() && vm.Is4S());
|
||||
|
||||
Emit(0x5e002000 | Rd(vd) | Rn(vn) | Rm(vm));
|
||||
}
|
||||
|
||||
void Assembler::sha1p(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kSHA1));
|
||||
VIXL_ASSERT(vd.IsQ() && vn.IsS() && vm.Is4S());
|
||||
|
||||
Emit(0x5e001000 | Rd(vd) | Rn(vn) | Rm(vm));
|
||||
}
|
||||
|
||||
void Assembler::sha1su0(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kSHA1));
|
||||
VIXL_ASSERT(vd.Is4S() && vn.Is4S() && vm.Is4S());
|
||||
|
||||
Emit(0x5e003000 | Rd(vd) | Rn(vn) | Rm(vm));
|
||||
}
|
||||
|
||||
void Assembler::sha1su1(const VRegister& vd, const VRegister& vn) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kSHA1));
|
||||
VIXL_ASSERT(vd.Is4S() && vn.Is4S());
|
||||
|
||||
Emit(0x5e281800 | Rd(vd) | Rn(vn));
|
||||
}
|
||||
|
||||
void Assembler::sha256h(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kSHA2));
|
||||
VIXL_ASSERT(vd.IsQ() && vn.IsQ() && vm.Is4S());
|
||||
|
||||
Emit(0x5e004000 | Rd(vd) | Rn(vn) | Rm(vm));
|
||||
}
|
||||
|
||||
void Assembler::sha256h2(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kSHA2));
|
||||
VIXL_ASSERT(vd.IsQ() && vn.IsQ() && vm.Is4S());
|
||||
|
||||
Emit(0x5e005000 | Rd(vd) | Rn(vn) | Rm(vm));
|
||||
}
|
||||
|
||||
void Assembler::sha256su0(const VRegister& vd, const VRegister& vn) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kSHA2));
|
||||
VIXL_ASSERT(vd.Is4S() && vn.Is4S());
|
||||
|
||||
Emit(0x5e282800 | Rd(vd) | Rn(vn));
|
||||
}
|
||||
|
||||
void Assembler::sha256su1(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kSHA2));
|
||||
VIXL_ASSERT(vd.Is4S() && vn.Is4S() && vm.Is4S());
|
||||
|
||||
Emit(0x5e006000 | Rd(vd) | Rn(vn) | Rm(vm));
|
||||
}
|
||||
|
||||
void Assembler::sha512h(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kSHA512));
|
||||
VIXL_ASSERT(vd.IsQ() && vn.IsQ() && vm.Is2D());
|
||||
|
||||
Emit(0xce608000 | Rd(vd) | Rn(vn) | Rm(vm));
|
||||
}
|
||||
|
||||
void Assembler::sha512h2(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kSHA512));
|
||||
VIXL_ASSERT(vd.IsQ() && vn.IsQ() && vm.Is2D());
|
||||
|
||||
Emit(0xce608400 | Rd(vd) | Rn(vn) | Rm(vm));
|
||||
}
|
||||
|
||||
void Assembler::sha512su0(const VRegister& vd, const VRegister& vn) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kSHA512));
|
||||
VIXL_ASSERT(vd.Is2D() && vn.Is2D());
|
||||
|
||||
Emit(0xcec08000 | Rd(vd) | Rn(vn));
|
||||
}
|
||||
|
||||
void Assembler::sha512su1(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kSHA512));
|
||||
VIXL_ASSERT(vd.Is2D() && vn.Is2D() && vm.Is2D());
|
||||
|
||||
Emit(0xce608800 | Rd(vd) | Rn(vn) | Rm(vm));
|
||||
}
|
||||
|
||||
void Assembler::aesd(const VRegister& vd, const VRegister& vn) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kAES));
|
||||
VIXL_ASSERT(vd.Is16B() && vn.Is16B());
|
||||
|
||||
Emit(0x4e285800 | Rd(vd) | Rn(vn));
|
||||
}
|
||||
|
||||
void Assembler::aese(const VRegister& vd, const VRegister& vn) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kAES));
|
||||
VIXL_ASSERT(vd.Is16B() && vn.Is16B());
|
||||
|
||||
Emit(0x4e284800 | Rd(vd) | Rn(vn));
|
||||
}
|
||||
|
||||
void Assembler::aesimc(const VRegister& vd, const VRegister& vn) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kAES));
|
||||
VIXL_ASSERT(vd.Is16B() && vn.Is16B());
|
||||
|
||||
Emit(0x4e287800 | Rd(vd) | Rn(vn));
|
||||
}
|
||||
|
||||
void Assembler::aesmc(const VRegister& vd, const VRegister& vn) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kAES));
|
||||
VIXL_ASSERT(vd.Is16B() && vn.Is16B());
|
||||
|
||||
Emit(0x4e286800 | Rd(vd) | Rn(vn));
|
||||
}
|
||||
|
||||
void Assembler::sm3partw1(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kSM3));
|
||||
VIXL_ASSERT(vd.Is4S() && vn.Is4S() && vm.Is4S());
|
||||
|
||||
Emit(0xce60c000 | Rd(vd) | Rn(vn) | Rm(vm));
|
||||
}
|
||||
|
||||
void Assembler::sm3partw2(const VRegister& vd, const VRegister& vn, const VRegister& vm) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kSM3));
|
||||
VIXL_ASSERT(vd.Is4S() && vn.Is4S() && vm.Is4S());
|
||||
|
||||
Emit(0xce60c400 | Rd(vd) | Rn(vn) | Rm(vm));
|
||||
}
|
||||
|
||||
void Assembler::sm3ss1(const VRegister& vd, const VRegister& vn, const VRegister& vm, const VRegister& va) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kSM3));
|
||||
VIXL_ASSERT(vd.Is4S() && vn.Is4S() && vm.Is4S() && va.Is4S());
|
||||
|
||||
Emit(0xce400000 | Rd(vd) | Rn(vn) | Rm(vm) | Ra(va));
|
||||
}
|
||||
|
||||
void Assembler::sm3tt1a(const VRegister& vd, const VRegister& vn, const VRegister& vm, int index) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kSM3));
|
||||
VIXL_ASSERT(vd.Is4S() && vn.Is4S() && vm.Is4S());
|
||||
VIXL_ASSERT(IsUint2(index));
|
||||
|
||||
Instr i = static_cast<uint32_t>(index) << 12;
|
||||
Emit(0xce408000 | Rd(vd) | Rn(vn) | Rm(vm) | i);
|
||||
}
|
||||
|
||||
void Assembler::sm3tt1b(const VRegister& vd, const VRegister& vn, const VRegister& vm, int index) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kSM3));
|
||||
VIXL_ASSERT(vd.Is4S() && vn.Is4S() && vm.Is4S());
|
||||
VIXL_ASSERT(IsUint2(index));
|
||||
|
||||
Instr i = static_cast<uint32_t>(index) << 12;
|
||||
Emit(0xce408400 | Rd(vd) | Rn(vn) | Rm(vm) | i);
|
||||
}
|
||||
|
||||
void Assembler::sm3tt2a(const VRegister& vd, const VRegister& vn, const VRegister& vm, int index) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kSM3));
|
||||
VIXL_ASSERT(vd.Is4S() && vn.Is4S() && vm.Is4S());
|
||||
VIXL_ASSERT(IsUint2(index));
|
||||
|
||||
Instr i = static_cast<uint32_t>(index) << 12;
|
||||
Emit(0xce408800 | Rd(vd) | Rn(vn) | Rm(vm) | i);
|
||||
}
|
||||
|
||||
void Assembler::sm3tt2b(const VRegister& vd, const VRegister& vn, const VRegister& vm, int index) {
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kNEON));
|
||||
VIXL_ASSERT(CPUHas(CPUFeatures::kSM3));
|
||||
VIXL_ASSERT(vd.Is4S() && vn.Is4S() && vm.Is4S());
|
||||
VIXL_ASSERT(IsUint2(index));
|
||||
|
||||
Instr i = static_cast<uint32_t>(index) << 12;
|
||||
Emit(0xce408c00 | Rd(vd) | Rn(vn) | Rm(vm) | i);
|
||||
}
|
||||
|
||||
// Note:
|
||||
// For all ToImm instructions below, a difference in case
|
||||
// for the same letter indicates a negated bit.
|
||||
@@ -6005,15 +6293,13 @@ void Assembler::AddSub(const Register& rd,
|
||||
rn,
|
||||
operand.ToExtendedRegister(),
|
||||
S,
|
||||
static_cast<Instr>(AddSubExtendedFixed) | static_cast<Instr>(op));
|
||||
AddSubExtendedFixed | op);
|
||||
} else {
|
||||
DataProcShiftedRegister(rd, rn, operand, S,
|
||||
static_cast<Instr>(AddSubShiftedFixed) | static_cast<Instr>(op));
|
||||
DataProcShiftedRegister(rd, rn, operand, S, AddSubShiftedFixed | op);
|
||||
}
|
||||
} else {
|
||||
VIXL_ASSERT(operand.IsExtendedRegister());
|
||||
DataProcExtendedRegister(rd, rn, operand, S,
|
||||
static_cast<Instr>(AddSubExtendedFixed) | static_cast<Instr>(op));
|
||||
DataProcExtendedRegister(rd, rn, operand, S, AddSubExtendedFixed | op);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6079,7 +6365,7 @@ void Assembler::Logical(const Register& rd,
|
||||
} else {
|
||||
VIXL_ASSERT(operand.IsShiftedRegister());
|
||||
VIXL_ASSERT(operand.GetRegister().GetSizeInBits() == rd.GetSizeInBits());
|
||||
Instr dp_op = static_cast<Instr>(op) | static_cast<Instr>(LogicalShiftedFixed);
|
||||
Instr dp_op = static_cast<Instr>(op | LogicalShiftedFixed);
|
||||
DataProcShiftedRegister(rd, rn, operand, LeaveFlags, dp_op);
|
||||
}
|
||||
}
|
||||
@@ -6108,14 +6394,11 @@ void Assembler::ConditionalCompare(const Register& rn,
|
||||
if (operand.IsImmediate()) {
|
||||
int64_t immediate = operand.GetImmediate();
|
||||
VIXL_ASSERT(IsImmConditionalCompare(immediate));
|
||||
ccmpop = static_cast<Instr>(ConditionalCompareImmediateFixed) |
|
||||
static_cast<Instr>(op) |
|
||||
ccmpop = ConditionalCompareImmediateFixed | op |
|
||||
ImmCondCmp(static_cast<unsigned>(immediate));
|
||||
} else {
|
||||
VIXL_ASSERT(operand.IsShiftedRegister() && (operand.GetShiftAmount() == 0));
|
||||
ccmpop = static_cast<Instr>(ConditionalCompareRegisterFixed) |
|
||||
static_cast<Instr>(op) |
|
||||
Rm(operand.GetRegister());
|
||||
ccmpop = ConditionalCompareRegisterFixed | op | Rm(operand.GetRegister());
|
||||
}
|
||||
Emit(SF(rn) | ccmpop | Cond(cond) | Rn(rn) | Nzcv(nzcv));
|
||||
}
|
||||
|
||||
@@ -24,12 +24,13 @@
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "cpu-features-auditor-aarch64.h"
|
||||
|
||||
#include "cpu-features.h"
|
||||
#include "globals-vixl.h"
|
||||
#include "utils-vixl.h"
|
||||
#include "decoder-aarch64.h"
|
||||
|
||||
#include "cpu-features-auditor-aarch64.h"
|
||||
#include "decoder-aarch64.h"
|
||||
|
||||
namespace vixl {
|
||||
namespace aarch64 {
|
||||
@@ -246,16 +247,41 @@ void CPUFeaturesAuditor::VisitConditionalSelect(const Instruction* instr) {
|
||||
|
||||
void CPUFeaturesAuditor::VisitCrypto2RegSHA(const Instruction* instr) {
|
||||
RecordInstructionFeaturesScope scope(this);
|
||||
if (form_hash_ == "sha256su0_vv_cryptosha2"_h) {
|
||||
scope.Record(CPUFeatures::kNEON, CPUFeatures::kSHA2);
|
||||
} else {
|
||||
scope.Record(CPUFeatures::kNEON, CPUFeatures::kSHA1);
|
||||
}
|
||||
USE(instr);
|
||||
}
|
||||
|
||||
void CPUFeaturesAuditor::VisitCrypto3RegSHA(const Instruction* instr) {
|
||||
RecordInstructionFeaturesScope scope(this);
|
||||
switch (form_hash_) {
|
||||
case "sha1c_qsv_cryptosha3"_h:
|
||||
case "sha1m_qsv_cryptosha3"_h:
|
||||
case "sha1p_qsv_cryptosha3"_h:
|
||||
case "sha1su0_vvv_cryptosha3"_h:
|
||||
scope.Record(CPUFeatures::kNEON, CPUFeatures::kSHA1);
|
||||
break;
|
||||
case "sha256h_qqv_cryptosha3"_h:
|
||||
case "sha256h2_qqv_cryptosha3"_h:
|
||||
case "sha256su1_vvv_cryptosha3"_h:
|
||||
scope.Record(CPUFeatures::kNEON, CPUFeatures::kSHA2);
|
||||
break;
|
||||
}
|
||||
USE(instr);
|
||||
}
|
||||
|
||||
void CPUFeaturesAuditor::VisitCryptoAES(const Instruction* instr) {
|
||||
RecordInstructionFeaturesScope scope(this);
|
||||
scope.Record(CPUFeatures::kNEON, CPUFeatures::kAES);
|
||||
USE(instr);
|
||||
}
|
||||
|
||||
void CPUFeaturesAuditor::VisitCryptoSM3(const Instruction* instr) {
|
||||
RecordInstructionFeaturesScope scope(this);
|
||||
scope.Record(CPUFeatures::kNEON, CPUFeatures::kSM3);
|
||||
USE(instr);
|
||||
}
|
||||
|
||||
@@ -735,6 +761,12 @@ void CPUFeaturesAuditor::VisitNEON3Different(const Instruction* instr) {
|
||||
RecordInstructionFeaturesScope scope(this);
|
||||
// All of these instructions require NEON.
|
||||
scope.Record(CPUFeatures::kNEON);
|
||||
if (form_hash_ == "pmull_asimddiff_l"_h) {
|
||||
if (instr->GetNEONSize() == 3) {
|
||||
// Source is 1D or 2D, destination is 1Q.
|
||||
scope.Record(CPUFeatures::kPmull1Q);
|
||||
}
|
||||
}
|
||||
USE(instr);
|
||||
}
|
||||
|
||||
@@ -1269,91 +1301,93 @@ VIXL_SIMPLE_SVE_VISITOR_LIST(VIXL_DEFINE_SIMPLE_SVE_VISITOR)
|
||||
|
||||
void CPUFeaturesAuditor::VisitSystem(const Instruction* instr) {
|
||||
RecordInstructionFeaturesScope scope(this);
|
||||
if (instr->Mask(SystemHintFMask) == SystemHintFixed) {
|
||||
CPUFeatures required;
|
||||
switch (instr->GetInstructionBits()) {
|
||||
case PACIA1716:
|
||||
case PACIB1716:
|
||||
case AUTIA1716:
|
||||
case AUTIB1716:
|
||||
case PACIAZ:
|
||||
case PACIASP:
|
||||
case PACIBZ:
|
||||
case PACIBSP:
|
||||
case AUTIAZ:
|
||||
case AUTIASP:
|
||||
case AUTIBZ:
|
||||
case AUTIBSP:
|
||||
case XPACLRI:
|
||||
required.Combine(CPUFeatures::kPAuth);
|
||||
break;
|
||||
default:
|
||||
switch (instr->GetImmHint()) {
|
||||
case ESB:
|
||||
required.Combine(CPUFeatures::kRAS);
|
||||
break;
|
||||
case BTI:
|
||||
case BTI_j:
|
||||
case BTI_c:
|
||||
case BTI_jc:
|
||||
required.Combine(CPUFeatures::kBTI);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// These are all HINT instructions, and behave as NOPs if the corresponding
|
||||
// features are not implemented, so we record the corresponding features
|
||||
// only if they are available.
|
||||
if (available_.Has(required)) scope.Record(required);
|
||||
} else if (instr->Mask(SystemSysMask) == SYS) {
|
||||
switch (instr->GetSysOp()) {
|
||||
// DC instruction variants.
|
||||
case CGVAC:
|
||||
case CGDVAC:
|
||||
case CGVAP:
|
||||
case CGDVAP:
|
||||
case CIGVAC:
|
||||
case CIGDVAC:
|
||||
case GVA:
|
||||
case GZVA:
|
||||
scope.Record(CPUFeatures::kMTE);
|
||||
break;
|
||||
case CVAP:
|
||||
scope.Record(CPUFeatures::kDCPoP);
|
||||
break;
|
||||
case CVADP:
|
||||
scope.Record(CPUFeatures::kDCCVADP);
|
||||
break;
|
||||
case IVAU:
|
||||
case CVAC:
|
||||
case CVAU:
|
||||
case CIVAC:
|
||||
case ZVA:
|
||||
// No special CPU features.
|
||||
break;
|
||||
}
|
||||
} else if (instr->Mask(SystemPStateFMask) == SystemPStateFixed) {
|
||||
switch (instr->Mask(SystemPStateMask)) {
|
||||
case CFINV:
|
||||
scope.Record(CPUFeatures::kFlagM);
|
||||
break;
|
||||
case AXFLAG:
|
||||
case XAFLAG:
|
||||
scope.Record(CPUFeatures::kAXFlag);
|
||||
break;
|
||||
}
|
||||
} else if (instr->Mask(SystemSysRegFMask) == SystemSysRegFixed) {
|
||||
if (instr->Mask(SystemSysRegMask) == MRS) {
|
||||
CPUFeatures required;
|
||||
switch (form_hash_) {
|
||||
case "pacib1716_hi_hints"_h:
|
||||
case "pacia1716_hi_hints"_h:
|
||||
case "pacibsp_hi_hints"_h:
|
||||
case "paciasp_hi_hints"_h:
|
||||
case "pacibz_hi_hints"_h:
|
||||
case "paciaz_hi_hints"_h:
|
||||
case "autib1716_hi_hints"_h:
|
||||
case "autia1716_hi_hints"_h:
|
||||
case "autibsp_hi_hints"_h:
|
||||
case "autiasp_hi_hints"_h:
|
||||
case "autibz_hi_hints"_h:
|
||||
case "autiaz_hi_hints"_h:
|
||||
case "xpaclri_hi_hints"_h:
|
||||
required.Combine(CPUFeatures::kPAuth);
|
||||
break;
|
||||
case "esb_hi_hints"_h:
|
||||
required.Combine(CPUFeatures::kRAS);
|
||||
break;
|
||||
case "bti_hb_hints"_h:
|
||||
required.Combine(CPUFeatures::kBTI);
|
||||
break;
|
||||
}
|
||||
|
||||
// The instructions above are all HINTs and behave as NOPs if the
|
||||
// corresponding features are not implemented, so we record the corresponding
|
||||
// features only if they are available.
|
||||
if (available_.Has(required)) scope.Record(required);
|
||||
|
||||
switch (form_hash_) {
|
||||
case "cfinv_m_pstate"_h:
|
||||
scope.Record(CPUFeatures::kFlagM);
|
||||
break;
|
||||
case "axflag_m_pstate"_h:
|
||||
case "xaflag_m_pstate"_h:
|
||||
scope.Record(CPUFeatures::kAXFlag);
|
||||
break;
|
||||
case "mrs_rs_systemmove"_h:
|
||||
switch (instr->GetImmSystemRegister()) {
|
||||
case RNDR:
|
||||
case RNDRRS:
|
||||
scope.Record(CPUFeatures::kRNG);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "sys_cr_systeminstrs"_h:
|
||||
switch (instr->GetSysOp()) {
|
||||
// DC instruction variants.
|
||||
case CGVAC:
|
||||
case CGDVAC:
|
||||
case CGVAP:
|
||||
case CGDVAP:
|
||||
case CIGVAC:
|
||||
case CIGDVAC:
|
||||
case GVA:
|
||||
case GZVA:
|
||||
scope.Record(CPUFeatures::kMTE);
|
||||
break;
|
||||
case CVAP:
|
||||
scope.Record(CPUFeatures::kDCPoP);
|
||||
break;
|
||||
case CVADP:
|
||||
scope.Record(CPUFeatures::kDCCVADP);
|
||||
break;
|
||||
case IVAU:
|
||||
case CVAC:
|
||||
case CVAU:
|
||||
case CIVAC:
|
||||
case ZVA:
|
||||
// No special CPU features.
|
||||
break;
|
||||
case GCSPUSHM:
|
||||
case GCSSS1:
|
||||
scope.Record(CPUFeatures::kGCS);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "sysl_rc_systeminstrs"_h:
|
||||
switch (instr->GetSysOp()) {
|
||||
case GCSPOPM:
|
||||
case GCSSS2:
|
||||
scope.Record(CPUFeatures::kGCS);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1407,9 +1441,9 @@ void CPUFeaturesAuditor::VisitUnimplemented(const Instruction* instr) {
|
||||
void CPUFeaturesAuditor::Visit(Metadata* metadata, const Instruction* instr) {
|
||||
VIXL_ASSERT(metadata->count("form") > 0);
|
||||
const std::string& form = (*metadata)["form"];
|
||||
uint32_t form_hash = Hash(form.c_str());
|
||||
form_hash_ = Hash(form.c_str());
|
||||
const FormToVisitorFnMap* fv = CPUFeaturesAuditor::GetFormToVisitorFnMap();
|
||||
FormToVisitorFnMap::const_iterator it = fv->find(form_hash);
|
||||
FormToVisitorFnMap::const_iterator it = fv->find(form_hash_);
|
||||
if (it == fv->end()) {
|
||||
RecordInstructionFeaturesScope scope(this);
|
||||
std::map<uint32_t, const CPUFeatures> features = {
|
||||
@@ -1826,10 +1860,26 @@ void CPUFeaturesAuditor::Visit(Metadata* metadata, const Instruction* instr) {
|
||||
{"umax_64u_minmax_imm"_h, CPUFeatures::kCSSC},
|
||||
{"umin_32u_minmax_imm"_h, CPUFeatures::kCSSC},
|
||||
{"umin_64u_minmax_imm"_h, CPUFeatures::kCSSC},
|
||||
{"bcax_vvv16_crypto4"_h,
|
||||
CPUFeatures(CPUFeatures::kNEON, CPUFeatures::kSHA3)},
|
||||
{"eor3_vvv16_crypto4"_h,
|
||||
CPUFeatures(CPUFeatures::kNEON, CPUFeatures::kSHA3)},
|
||||
{"rax1_vvv2_cryptosha512_3"_h,
|
||||
CPUFeatures(CPUFeatures::kNEON, CPUFeatures::kSHA3)},
|
||||
{"xar_vvv2_crypto3_imm6"_h,
|
||||
CPUFeatures(CPUFeatures::kNEON, CPUFeatures::kSHA3)},
|
||||
{"sha512h_qqv_cryptosha512_3"_h,
|
||||
CPUFeatures(CPUFeatures::kNEON, CPUFeatures::kSHA512)},
|
||||
{"sha512h2_qqv_cryptosha512_3"_h,
|
||||
CPUFeatures(CPUFeatures::kNEON, CPUFeatures::kSHA512)},
|
||||
{"sha512su0_vv2_cryptosha512_2"_h,
|
||||
CPUFeatures(CPUFeatures::kNEON, CPUFeatures::kSHA512)},
|
||||
{"sha512su1_vvv2_cryptosha512_3"_h,
|
||||
CPUFeatures(CPUFeatures::kNEON, CPUFeatures::kSHA512)},
|
||||
};
|
||||
|
||||
if (features.count(form_hash) > 0) {
|
||||
scope.Record(features[form_hash]);
|
||||
if (features.count(form_hash_) > 0) {
|
||||
scope.Record(features[form_hash_]);
|
||||
}
|
||||
} else {
|
||||
(it->second)(this, instr);
|
||||
|
||||
3
3rdparty/vixl/src/aarch64/decoder-aarch64.cc
vendored
3
3rdparty/vixl/src/aarch64/decoder-aarch64.cc
vendored
@@ -24,12 +24,13 @@
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "decoder-aarch64.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "../globals-vixl.h"
|
||||
#include "../utils-vixl.h"
|
||||
|
||||
#include "decoder-aarch64.h"
|
||||
#include "decoder-constants-aarch64.h"
|
||||
|
||||
namespace vixl {
|
||||
|
||||
165
3rdparty/vixl/src/aarch64/disasm-aarch64.cc
vendored
165
3rdparty/vixl/src/aarch64/disasm-aarch64.cc
vendored
@@ -24,12 +24,12 @@
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "disasm-aarch64.h"
|
||||
|
||||
#include <bitset>
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
|
||||
#include "disasm-aarch64.h"
|
||||
|
||||
namespace vixl {
|
||||
namespace aarch64 {
|
||||
|
||||
@@ -330,6 +330,7 @@ const Disassembler::FormToVisitorFnMap *Disassembler::GetFormToVisitorFnMap() {
|
||||
{"frsqrte_asisdmisc_r"_h, &Disassembler::DisassembleNEONFPScalar2RegMisc},
|
||||
{"scvtf_asisdmisc_r"_h, &Disassembler::DisassembleNEONFPScalar2RegMisc},
|
||||
{"ucvtf_asisdmisc_r"_h, &Disassembler::DisassembleNEONFPScalar2RegMisc},
|
||||
{"pmull_asimddiff_l"_h, &Disassembler::DisassembleNEONPolynomialMul},
|
||||
{"adclb_z_zzz"_h, &Disassembler::DisassembleSVEAddSubCarry},
|
||||
{"adclt_z_zzz"_h, &Disassembler::DisassembleSVEAddSubCarry},
|
||||
{"addhnb_z_zz"_h, &Disassembler::DisassembleSVEAddSubHigh},
|
||||
@@ -752,6 +753,14 @@ const Disassembler::FormToVisitorFnMap *Disassembler::GetFormToVisitorFnMap() {
|
||||
{"umax_64u_minmax_imm"_h, &Disassembler::DisassembleMinMaxImm},
|
||||
{"umin_32u_minmax_imm"_h, &Disassembler::DisassembleMinMaxImm},
|
||||
{"umin_64u_minmax_imm"_h, &Disassembler::DisassembleMinMaxImm},
|
||||
{"bcax_vvv16_crypto4"_h, &Disassembler::DisassembleNEON4Same},
|
||||
{"eor3_vvv16_crypto4"_h, &Disassembler::DisassembleNEON4Same},
|
||||
{"xar_vvv2_crypto3_imm6"_h, &Disassembler::DisassembleNEONXar},
|
||||
{"rax1_vvv2_cryptosha512_3"_h, &Disassembler::DisassembleNEONRax1},
|
||||
{"sha512h2_qqv_cryptosha512_3"_h, &Disassembler::DisassembleSHA512},
|
||||
{"sha512h_qqv_cryptosha512_3"_h, &Disassembler::DisassembleSHA512},
|
||||
{"sha512su0_vv2_cryptosha512_2"_h, &Disassembler::DisassembleSHA512},
|
||||
{"sha512su1_vvv2_cryptosha512_3"_h, &Disassembler::DisassembleSHA512},
|
||||
};
|
||||
return &form_to_visitor;
|
||||
} // NOLINT(readability/fn_size)
|
||||
@@ -2017,7 +2026,7 @@ void Disassembler::DisassembleNoArgs(const Instruction *instr) {
|
||||
|
||||
void Disassembler::VisitSystem(const Instruction *instr) {
|
||||
const char *mnemonic = mnemonic_.c_str();
|
||||
const char *form = "(System)";
|
||||
const char *form = "";
|
||||
const char *suffix = NULL;
|
||||
|
||||
switch (form_hash_) {
|
||||
@@ -2046,6 +2055,10 @@ void Disassembler::VisitSystem(const Instruction *instr) {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "chkfeat_hf_hints"_h:
|
||||
mnemonic = "chkfeat";
|
||||
form = "x16";
|
||||
break;
|
||||
case "hint_hm_hints"_h:
|
||||
form = "'IH";
|
||||
break;
|
||||
@@ -2066,9 +2079,6 @@ void Disassembler::VisitSystem(const Instruction *instr) {
|
||||
break;
|
||||
}
|
||||
case Hash("sys_cr_systeminstrs"): {
|
||||
mnemonic = "dc";
|
||||
suffix = ", 'Xt";
|
||||
|
||||
const std::map<uint32_t, const char *> dcop = {
|
||||
{IVAU, "ivau"},
|
||||
{CVAC, "cvac"},
|
||||
@@ -2091,17 +2101,36 @@ void Disassembler::VisitSystem(const Instruction *instr) {
|
||||
if (dcop.count(sysop)) {
|
||||
if (sysop == IVAU) {
|
||||
mnemonic = "ic";
|
||||
} else {
|
||||
mnemonic = "dc";
|
||||
}
|
||||
form = dcop.at(sysop);
|
||||
suffix = ", 'Xt";
|
||||
} else if (sysop == GCSSS1) {
|
||||
mnemonic = "gcsss1";
|
||||
form = "'Xt";
|
||||
} else if (sysop == GCSPUSHM) {
|
||||
mnemonic = "gcspushm";
|
||||
form = "'Xt";
|
||||
} else {
|
||||
mnemonic = "sys";
|
||||
form = "'G1, 'Kn, 'Km, 'G2";
|
||||
if (instr->GetRt() == 31) {
|
||||
suffix = NULL;
|
||||
if (instr->GetRt() < 31) {
|
||||
suffix = ", 'Xt";
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "sysl_rc_systeminstrs"_h:
|
||||
uint32_t sysop = instr->GetSysOp();
|
||||
if (sysop == GCSPOPM) {
|
||||
mnemonic = "gcspopm";
|
||||
form = (instr->GetRt() == 31) ? "" : "'Xt";
|
||||
} else if (sysop == GCSSS2) {
|
||||
mnemonic = "gcsss2";
|
||||
form = "'Xt";
|
||||
}
|
||||
break;
|
||||
}
|
||||
Format(instr, mnemonic, form, suffix);
|
||||
}
|
||||
@@ -2147,17 +2176,64 @@ void Disassembler::VisitException(const Instruction *instr) {
|
||||
|
||||
|
||||
void Disassembler::VisitCrypto2RegSHA(const Instruction *instr) {
|
||||
VisitUnimplemented(instr);
|
||||
const char *form = "'Vd.4s, 'Vn.4s";
|
||||
if (form_hash_ == "sha1h_ss_cryptosha2"_h) {
|
||||
form = "'Sd, 'Sn";
|
||||
}
|
||||
FormatWithDecodedMnemonic(instr, form);
|
||||
}
|
||||
|
||||
|
||||
void Disassembler::VisitCrypto3RegSHA(const Instruction *instr) {
|
||||
VisitUnimplemented(instr);
|
||||
const char *form = "'Qd, 'Sn, 'Vm.4s";
|
||||
switch (form_hash_) {
|
||||
case "sha1su0_vvv_cryptosha3"_h:
|
||||
case "sha256su1_vvv_cryptosha3"_h:
|
||||
form = "'Vd.4s, 'Vn.4s, 'Vm.4s";
|
||||
break;
|
||||
case "sha256h_qqv_cryptosha3"_h:
|
||||
case "sha256h2_qqv_cryptosha3"_h:
|
||||
form = "'Qd, 'Qn, 'Vm.4s";
|
||||
break;
|
||||
}
|
||||
FormatWithDecodedMnemonic(instr, form);
|
||||
}
|
||||
|
||||
|
||||
void Disassembler::VisitCryptoAES(const Instruction *instr) {
|
||||
VisitUnimplemented(instr);
|
||||
FormatWithDecodedMnemonic(instr, "'Vd.16b, 'Vn.16b");
|
||||
}
|
||||
|
||||
void Disassembler::VisitCryptoSM3(const Instruction *instr) {
|
||||
const char *form = "'Vd.4s, 'Vn.4s, 'Vm.";
|
||||
const char *suffix = "4s";
|
||||
|
||||
switch (form_hash_) {
|
||||
case "sm3ss1_vvv4_crypto4"_h:
|
||||
suffix = "4s, 'Va.4s";
|
||||
break;
|
||||
case "sm3tt1a_vvv4_crypto3_imm2"_h:
|
||||
case "sm3tt1b_vvv4_crypto3_imm2"_h:
|
||||
case "sm3tt2a_vvv4_crypto3_imm2"_h:
|
||||
case "sm3tt2b_vvv_crypto3_imm2"_h:
|
||||
suffix = "s['u1312]";
|
||||
break;
|
||||
}
|
||||
|
||||
FormatWithDecodedMnemonic(instr, form, suffix);
|
||||
}
|
||||
|
||||
void Disassembler::DisassembleSHA512(const Instruction *instr) {
|
||||
const char *form = "'Qd, 'Qn, 'Vm.2d";
|
||||
const char *suffix = NULL;
|
||||
switch (form_hash_) {
|
||||
case "sha512su1_vvv2_cryptosha512_3"_h:
|
||||
suffix = ", 'Vm.2d";
|
||||
VIXL_FALLTHROUGH();
|
||||
case "sha512su0_vv2_cryptosha512_2"_h:
|
||||
form = "'Vd.2d, 'Vn.2d";
|
||||
}
|
||||
FormatWithDecodedMnemonic(instr, form, suffix);
|
||||
}
|
||||
|
||||
void Disassembler::DisassembleNEON2RegAddlp(const Instruction *instr) {
|
||||
@@ -2373,13 +2449,19 @@ void Disassembler::VisitNEON3SameFP16(const Instruction *instr) {
|
||||
}
|
||||
|
||||
void Disassembler::VisitNEON3SameExtra(const Instruction *instr) {
|
||||
static const NEONFormatMap map_usdot = {{30}, {NF_8B, NF_16B}};
|
||||
static const NEONFormatMap map_dot =
|
||||
{{23, 22, 30}, {NF_UNDEF, NF_UNDEF, NF_UNDEF, NF_UNDEF, NF_2S, NF_4S}};
|
||||
static const NEONFormatMap map_fc =
|
||||
{{23, 22, 30},
|
||||
{NF_UNDEF, NF_UNDEF, NF_4H, NF_8H, NF_2S, NF_4S, NF_UNDEF, NF_2D}};
|
||||
static const NEONFormatMap map_rdm =
|
||||
{{23, 22, 30}, {NF_UNDEF, NF_UNDEF, NF_4H, NF_8H, NF_2S, NF_4S}};
|
||||
|
||||
const char *mnemonic = mnemonic_.c_str();
|
||||
const char *form = "'Vd.%s, 'Vn.%s, 'Vm.%s";
|
||||
const char *suffix = NULL;
|
||||
|
||||
NEONFormatDecoder nfd(instr);
|
||||
NEONFormatDecoder nfd(instr, &map_fc);
|
||||
|
||||
switch (form_hash_) {
|
||||
case "fcmla_asimdsame2_c"_h:
|
||||
@@ -2392,17 +2474,28 @@ void Disassembler::VisitNEON3SameExtra(const Instruction *instr) {
|
||||
case "sdot_asimdsame2_d"_h:
|
||||
case "udot_asimdsame2_d"_h:
|
||||
case "usdot_asimdsame2_d"_h:
|
||||
nfd.SetFormatMap(1, &map_usdot);
|
||||
nfd.SetFormatMap(2, &map_usdot);
|
||||
nfd.SetFormatMaps(nfd.LogicalFormatMap());
|
||||
nfd.SetFormatMap(0, &map_dot);
|
||||
break;
|
||||
default:
|
||||
// sqrdml[as]h - nothing to do.
|
||||
nfd.SetFormatMaps(&map_rdm);
|
||||
break;
|
||||
}
|
||||
|
||||
Format(instr, mnemonic, nfd.Substitute(form), suffix);
|
||||
}
|
||||
|
||||
void Disassembler::DisassembleNEON4Same(const Instruction *instr) {
|
||||
FormatWithDecodedMnemonic(instr, "'Vd.16b, 'Vn.16b, 'Vm.16b, 'Va.16b");
|
||||
}
|
||||
|
||||
void Disassembler::DisassembleNEONXar(const Instruction *instr) {
|
||||
FormatWithDecodedMnemonic(instr, "'Vd.2d, 'Vn.2d, 'Vm.2d, #'u1510");
|
||||
}
|
||||
|
||||
void Disassembler::DisassembleNEONRax1(const Instruction *instr) {
|
||||
FormatWithDecodedMnemonic(instr, "'Vd.2d, 'Vn.2d, 'Vm.2d");
|
||||
}
|
||||
|
||||
void Disassembler::VisitNEON3Different(const Instruction *instr) {
|
||||
const char *mnemonic = mnemonic_.c_str();
|
||||
@@ -2425,11 +2518,6 @@ void Disassembler::VisitNEON3Different(const Instruction *instr) {
|
||||
nfd.SetFormatMaps(nfd.LongIntegerFormatMap());
|
||||
nfd.SetFormatMap(0, nfd.IntegerFormatMap());
|
||||
break;
|
||||
case "pmull_asimddiff_l"_h:
|
||||
if (nfd.GetVectorFormat(0) != kFormat8H) {
|
||||
mnemonic = NULL;
|
||||
}
|
||||
break;
|
||||
case "sqdmlal_asimddiff_l"_h:
|
||||
case "sqdmlsl_asimddiff_l"_h:
|
||||
case "sqdmull_asimddiff_l"_h:
|
||||
@@ -2441,6 +2529,22 @@ void Disassembler::VisitNEON3Different(const Instruction *instr) {
|
||||
Format(instr, nfd.Mnemonic(mnemonic), nfd.Substitute(form));
|
||||
}
|
||||
|
||||
void Disassembler::DisassembleNEONPolynomialMul(const Instruction *instr) {
|
||||
const char *mnemonic = instr->ExtractBit(30) ? "pmull2" : "pmull";
|
||||
const char *form = NULL;
|
||||
int size = instr->ExtractBits(23, 22);
|
||||
if (size == 0) {
|
||||
// Bits 30:27 of the instruction are x001, where x is the Q bit. Map
|
||||
// this to "8" and "16" by adding 7.
|
||||
form = "'Vd.8h, 'Vn.'u3127+7b, 'Vm.'u3127+7b";
|
||||
} else if (size == 3) {
|
||||
form = "'Vd.1q, 'Vn.'?30:21d, 'Vm.'?30:21d";
|
||||
} else {
|
||||
mnemonic = NULL;
|
||||
}
|
||||
Format(instr, mnemonic, form);
|
||||
}
|
||||
|
||||
void Disassembler::DisassembleNEONFPAcrossLanes(const Instruction *instr) {
|
||||
const char *mnemonic = mnemonic_.c_str();
|
||||
const char *form = "'Sd, 'Vn.4s";
|
||||
@@ -3298,6 +3402,8 @@ void Disassembler::VisitNEONScalar3Same(const Instruction *instr) {
|
||||
break;
|
||||
case "sqdmulh_asisdsame_only"_h:
|
||||
case "sqrdmulh_asisdsame_only"_h:
|
||||
case "sqrdmlah_asisdsame2_only"_h:
|
||||
case "sqrdmlsh_asisdsame2_only"_h:
|
||||
if ((vform == kFormatB) || (vform == kFormatD)) {
|
||||
mnemonic = NULL;
|
||||
}
|
||||
@@ -3916,8 +4022,7 @@ static bool SVEMoveMaskPreferred(uint64_t value, int lane_bytes_log2) {
|
||||
}
|
||||
|
||||
// Check 0x0000pq00_0000pq00 or 0xffffpq00_ffffpq00.
|
||||
uint64_t rotvalue = RotateRight(value, 32, 64);
|
||||
if (value == rotvalue) {
|
||||
if (AllWordsMatch(value)) {
|
||||
generic_value &= 0xffffffff;
|
||||
if ((generic_value == 0xffff) || (generic_value == UINT32_MAX)) {
|
||||
return false;
|
||||
@@ -3925,8 +4030,7 @@ static bool SVEMoveMaskPreferred(uint64_t value, int lane_bytes_log2) {
|
||||
}
|
||||
|
||||
// Check 0xpq00pq00_pq00pq00.
|
||||
rotvalue = RotateRight(value, 16, 64);
|
||||
if (value == rotvalue) {
|
||||
if (AllHalfwordsMatch(value)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
@@ -3940,8 +4044,7 @@ static bool SVEMoveMaskPreferred(uint64_t value, int lane_bytes_log2) {
|
||||
}
|
||||
|
||||
// Check 0x000000pq_000000pq or 0xffffffpq_ffffffpq.
|
||||
uint64_t rotvalue = RotateRight(value, 32, 64);
|
||||
if (value == rotvalue) {
|
||||
if (AllWordsMatch(value)) {
|
||||
generic_value &= 0xffffffff;
|
||||
if ((generic_value == 0xff) || (generic_value == UINT32_MAX)) {
|
||||
return false;
|
||||
@@ -3949,8 +4052,7 @@ static bool SVEMoveMaskPreferred(uint64_t value, int lane_bytes_log2) {
|
||||
}
|
||||
|
||||
// Check 0x00pq00pq_00pq00pq or 0xffpqffpq_ffpqffpq.
|
||||
rotvalue = RotateRight(value, 16, 64);
|
||||
if (value == rotvalue) {
|
||||
if (AllHalfwordsMatch(value)) {
|
||||
generic_value &= 0xffff;
|
||||
if ((generic_value == 0xff) || (generic_value == UINT16_MAX)) {
|
||||
return false;
|
||||
@@ -3958,8 +4060,7 @@ static bool SVEMoveMaskPreferred(uint64_t value, int lane_bytes_log2) {
|
||||
}
|
||||
|
||||
// Check 0xpqpqpqpq_pqpqpqpq.
|
||||
rotvalue = RotateRight(value, 8, 64);
|
||||
if (value == rotvalue) {
|
||||
if (AllBytesMatch(value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "instructions-aarch64.h"
|
||||
|
||||
#include "assembler-aarch64.h"
|
||||
|
||||
namespace vixl {
|
||||
@@ -1010,6 +1011,8 @@ VectorFormat VectorFormatHalfWidth(VectorFormat vform) {
|
||||
return kFormat4H;
|
||||
case kFormat2D:
|
||||
return kFormat2S;
|
||||
case kFormat1Q:
|
||||
return kFormat1D;
|
||||
case kFormatH:
|
||||
return kFormatB;
|
||||
case kFormatS:
|
||||
@@ -1094,6 +1097,8 @@ VectorFormat VectorFormatHalfWidthDoubleLanes(VectorFormat vform) {
|
||||
return kFormat2S;
|
||||
case kFormat2D:
|
||||
return kFormat4S;
|
||||
case kFormat1Q:
|
||||
return kFormat2D;
|
||||
case kFormatVnH:
|
||||
return kFormatVnB;
|
||||
case kFormatVnS:
|
||||
@@ -1245,6 +1250,7 @@ unsigned RegisterSizeInBitsFromFormat(VectorFormat vform) {
|
||||
case kFormat8H:
|
||||
case kFormat4S:
|
||||
case kFormat2D:
|
||||
case kFormat1Q:
|
||||
return kQRegSize;
|
||||
default:
|
||||
VIXL_UNREACHABLE();
|
||||
@@ -1282,6 +1288,7 @@ unsigned LaneSizeInBitsFromFormat(VectorFormat vform) {
|
||||
case kFormat2D:
|
||||
case kFormatVnD:
|
||||
return 64;
|
||||
case kFormat1Q:
|
||||
case kFormatVnQ:
|
||||
return 128;
|
||||
case kFormatVnO:
|
||||
@@ -1347,6 +1354,7 @@ int LaneCountFromFormat(VectorFormat vform) {
|
||||
case kFormat2D:
|
||||
return 2;
|
||||
case kFormat1D:
|
||||
case kFormat1Q:
|
||||
case kFormatB:
|
||||
case kFormatH:
|
||||
case kFormatS:
|
||||
|
||||
1005
3rdparty/vixl/src/aarch64/logic-aarch64.cc
vendored
1005
3rdparty/vixl/src/aarch64/logic-aarch64.cc
vendored
File diff suppressed because it is too large
Load Diff
@@ -24,10 +24,10 @@
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <cctype>
|
||||
|
||||
#include "macro-assembler-aarch64.h"
|
||||
|
||||
#include <cctype>
|
||||
|
||||
namespace vixl {
|
||||
namespace aarch64 {
|
||||
|
||||
@@ -194,9 +194,8 @@ void VeneerPool::Reset() {
|
||||
|
||||
void VeneerPool::Release() {
|
||||
if (--monitor_ == 0) {
|
||||
VIXL_ASSERT(IsEmpty() ||
|
||||
masm_->GetCursorOffset() <
|
||||
unresolved_branches_.GetFirstLimit());
|
||||
VIXL_ASSERT(IsEmpty() || masm_->GetCursorOffset() <
|
||||
unresolved_branches_.GetFirstLimit());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,6 +312,48 @@ void VeneerPool::Emit(EmitOption option, size_t amount) {
|
||||
}
|
||||
|
||||
|
||||
MacroAssembler::MacroAssembler(PositionIndependentCodeOption pic)
|
||||
: Assembler(pic),
|
||||
#ifdef VIXL_DEBUG
|
||||
allow_macro_instructions_(true),
|
||||
#endif
|
||||
generate_simulator_code_(VIXL_AARCH64_GENERATE_SIMULATOR_CODE),
|
||||
sp_(sp),
|
||||
tmp_list_(ip0, ip1),
|
||||
v_tmp_list_(d31),
|
||||
p_tmp_list_(CPURegList::Empty(CPURegister::kPRegister)),
|
||||
current_scratch_scope_(NULL),
|
||||
literal_pool_(this),
|
||||
veneer_pool_(this),
|
||||
recommended_checkpoint_(Pool::kNoCheckpointRequired),
|
||||
fp_nan_propagation_(NoFPMacroNaNPropagationSelected) {
|
||||
checkpoint_ = GetNextCheckPoint();
|
||||
#ifndef VIXL_DEBUG
|
||||
USE(allow_macro_instructions_);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
MacroAssembler::MacroAssembler(size_t capacity,
|
||||
PositionIndependentCodeOption pic)
|
||||
: Assembler(capacity, pic),
|
||||
#ifdef VIXL_DEBUG
|
||||
allow_macro_instructions_(true),
|
||||
#endif
|
||||
generate_simulator_code_(VIXL_AARCH64_GENERATE_SIMULATOR_CODE),
|
||||
sp_(sp),
|
||||
tmp_list_(ip0, ip1),
|
||||
v_tmp_list_(d31),
|
||||
p_tmp_list_(CPURegList::Empty(CPURegister::kPRegister)),
|
||||
current_scratch_scope_(NULL),
|
||||
literal_pool_(this),
|
||||
veneer_pool_(this),
|
||||
recommended_checkpoint_(Pool::kNoCheckpointRequired),
|
||||
fp_nan_propagation_(NoFPMacroNaNPropagationSelected) {
|
||||
checkpoint_ = GetNextCheckPoint();
|
||||
}
|
||||
|
||||
|
||||
MacroAssembler::MacroAssembler(byte* buffer,
|
||||
size_t capacity,
|
||||
PositionIndependentCodeOption pic)
|
||||
@@ -363,7 +404,7 @@ void MacroAssembler::FinalizeCode(FinalizeOption option) {
|
||||
|
||||
void MacroAssembler::CheckEmitFor(size_t amount) {
|
||||
CheckEmitPoolsFor(amount);
|
||||
VIXL_ASSERT(GetBuffer()->HasSpaceFor(amount));
|
||||
GetBuffer()->EnsureSpaceFor(amount);
|
||||
}
|
||||
|
||||
|
||||
@@ -1108,11 +1149,14 @@ void MacroAssembler::Ccmp(const Register& rn,
|
||||
StatusFlags nzcv,
|
||||
Condition cond) {
|
||||
VIXL_ASSERT(allow_macro_instructions_);
|
||||
if (operand.IsImmediate() && (operand.GetImmediate() < 0)) {
|
||||
ConditionalCompareMacro(rn, -operand.GetImmediate(), nzcv, cond, CCMN);
|
||||
} else {
|
||||
ConditionalCompareMacro(rn, operand, nzcv, cond, CCMP);
|
||||
if (operand.IsImmediate()) {
|
||||
int64_t imm = operand.GetImmediate();
|
||||
if ((imm < 0) && CanBeNegated(imm)) {
|
||||
ConditionalCompareMacro(rn, -imm, nzcv, cond, CCMN);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ConditionalCompareMacro(rn, operand, nzcv, cond, CCMP);
|
||||
}
|
||||
|
||||
|
||||
@@ -1121,11 +1165,14 @@ void MacroAssembler::Ccmn(const Register& rn,
|
||||
StatusFlags nzcv,
|
||||
Condition cond) {
|
||||
VIXL_ASSERT(allow_macro_instructions_);
|
||||
if (operand.IsImmediate() && (operand.GetImmediate() < 0)) {
|
||||
ConditionalCompareMacro(rn, -operand.GetImmediate(), nzcv, cond, CCMP);
|
||||
} else {
|
||||
ConditionalCompareMacro(rn, operand, nzcv, cond, CCMN);
|
||||
if (operand.IsImmediate()) {
|
||||
int64_t imm = operand.GetImmediate();
|
||||
if ((imm < 0) && CanBeNegated(imm)) {
|
||||
ConditionalCompareMacro(rn, -imm, nzcv, cond, CCMP);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ConditionalCompareMacro(rn, operand, nzcv, cond, CCMN);
|
||||
}
|
||||
|
||||
|
||||
@@ -1359,8 +1406,7 @@ void MacroAssembler::Add(const Register& rd,
|
||||
VIXL_ASSERT(allow_macro_instructions_);
|
||||
if (operand.IsImmediate()) {
|
||||
int64_t imm = operand.GetImmediate();
|
||||
if ((imm < 0) && (imm != std::numeric_limits<int64_t>::min()) &&
|
||||
IsImmAddSub(-imm)) {
|
||||
if ((imm < 0) && CanBeNegated(imm) && IsImmAddSub(-imm)) {
|
||||
AddSubMacro(rd, rn, -imm, S, SUB);
|
||||
return;
|
||||
}
|
||||
@@ -1447,8 +1493,7 @@ void MacroAssembler::Sub(const Register& rd,
|
||||
VIXL_ASSERT(allow_macro_instructions_);
|
||||
if (operand.IsImmediate()) {
|
||||
int64_t imm = operand.GetImmediate();
|
||||
if ((imm < 0) && (imm != std::numeric_limits<int64_t>::min()) &&
|
||||
IsImmAddSub(-imm)) {
|
||||
if ((imm < 0) && CanBeNegated(imm) && IsImmAddSub(-imm)) {
|
||||
AddSubMacro(rd, rn, -imm, S, ADD);
|
||||
return;
|
||||
}
|
||||
@@ -1609,7 +1654,7 @@ void MacroAssembler::Fmov(VRegister vd, Float16 imm) {
|
||||
|
||||
void MacroAssembler::Neg(const Register& rd, const Operand& operand) {
|
||||
VIXL_ASSERT(allow_macro_instructions_);
|
||||
if (operand.IsImmediate()) {
|
||||
if (operand.IsImmediate() && CanBeNegated(operand.GetImmediate())) {
|
||||
Mov(rd, -operand.GetImmediate());
|
||||
} else {
|
||||
Sub(rd, AppropriateZeroRegFor(rd), operand);
|
||||
@@ -1925,6 +1970,22 @@ void MacroAssembler::Setf16(const Register& wn) {
|
||||
setf16(wn);
|
||||
}
|
||||
|
||||
void MacroAssembler::Chkfeat(const Register& xdn) {
|
||||
VIXL_ASSERT(allow_macro_instructions_);
|
||||
MacroEmissionCheckScope guard(this);
|
||||
if (xdn.Is(x16)) {
|
||||
chkfeat(xdn);
|
||||
} else {
|
||||
UseScratchRegisterScope temps(this);
|
||||
if (temps.TryAcquire(x16)) {
|
||||
Mov(x16, xdn);
|
||||
chkfeat(x16);
|
||||
Mov(xdn, x16);
|
||||
} else {
|
||||
VIXL_ABORT();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define DEFINE_FUNCTION(FN, REGTYPE, REG, OP) \
|
||||
void MacroAssembler::FN(const REGTYPE REG, const MemOperand& addr) { \
|
||||
|
||||
@@ -465,5 +465,5 @@ bool GenericOperand::Equals(const GenericOperand& other) const {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} // namespace vixl::aarch64
|
||||
} // namespace aarch64
|
||||
} // namespace vixl
|
||||
|
||||
@@ -26,10 +26,10 @@
|
||||
|
||||
#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
|
||||
|
||||
#include "simulator-aarch64.h"
|
||||
|
||||
#include "utils-vixl.h"
|
||||
|
||||
#include "simulator-aarch64.h"
|
||||
|
||||
namespace vixl {
|
||||
namespace aarch64 {
|
||||
|
||||
@@ -151,7 +151,7 @@ uint64_t Simulator::AuthPAC(uint64_t ptr,
|
||||
|
||||
uint64_t pac = ComputePAC(original_ptr, context, key);
|
||||
|
||||
uint64_t error_code = 1 << key.number;
|
||||
uint64_t error_code = uint64_t{1} << key.number;
|
||||
if ((pac & pac_mask) == (ptr & pac_mask)) {
|
||||
return original_ptr;
|
||||
} else {
|
||||
|
||||
11
3rdparty/vixl/src/aarch64/registers-aarch64.cc
vendored
11
3rdparty/vixl/src/aarch64/registers-aarch64.cc
vendored
@@ -24,11 +24,11 @@
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "registers-aarch64.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "registers-aarch64.h"
|
||||
|
||||
namespace vixl {
|
||||
namespace aarch64 {
|
||||
|
||||
@@ -153,7 +153,8 @@ VIXL_CPUREG_COERCION_LIST(VIXL_DEFINE_CPUREG_COERCION)
|
||||
V(2, S) \
|
||||
V(4, S) \
|
||||
V(1, D) \
|
||||
V(2, D)
|
||||
V(2, D) \
|
||||
V(1, Q)
|
||||
#define VIXL_DEFINE_CPUREG_NEON_COERCION(LANES, LANE_TYPE) \
|
||||
VRegister VRegister::V##LANES##LANE_TYPE() const { \
|
||||
VIXL_ASSERT(IsVRegister()); \
|
||||
@@ -317,5 +318,5 @@ bool AreSameLaneSize(const CPURegister& reg1,
|
||||
!reg4.IsValid() || (reg4.GetLaneSizeInBits() == reg1.GetLaneSizeInBits());
|
||||
return match;
|
||||
}
|
||||
}
|
||||
} // namespace vixl::aarch64
|
||||
} // namespace aarch64
|
||||
} // namespace vixl
|
||||
|
||||
98
3rdparty/vixl/src/code-buffer-vixl.cc
vendored
98
3rdparty/vixl/src/code-buffer-vixl.cc
vendored
@@ -24,14 +24,51 @@
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifdef VIXL_CODE_BUFFER_MMAP
|
||||
extern "C" {
|
||||
#include <sys/mman.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "code-buffer-vixl.h"
|
||||
#include "utils-vixl.h"
|
||||
|
||||
namespace vixl {
|
||||
|
||||
|
||||
CodeBuffer::CodeBuffer(size_t capacity)
|
||||
: buffer_(NULL),
|
||||
managed_(true),
|
||||
cursor_(NULL),
|
||||
dirty_(false),
|
||||
capacity_(capacity) {
|
||||
if (capacity_ == 0) {
|
||||
return;
|
||||
}
|
||||
#ifdef VIXL_CODE_BUFFER_MALLOC
|
||||
buffer_ = reinterpret_cast<byte*>(malloc(capacity_));
|
||||
#elif defined(VIXL_CODE_BUFFER_MMAP)
|
||||
buffer_ = reinterpret_cast<byte*>(mmap(NULL,
|
||||
capacity,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
-1,
|
||||
0));
|
||||
#else
|
||||
#error Unknown code buffer allocator.
|
||||
#endif
|
||||
VIXL_CHECK(buffer_ != NULL);
|
||||
// Aarch64 instructions must be word aligned, we assert the default allocator
|
||||
// always returns word align memory.
|
||||
VIXL_ASSERT(IsWordAligned(buffer_));
|
||||
|
||||
cursor_ = buffer_;
|
||||
}
|
||||
|
||||
|
||||
CodeBuffer::CodeBuffer(byte* buffer, size_t capacity)
|
||||
: buffer_(reinterpret_cast<byte*>(buffer)),
|
||||
managed_(false),
|
||||
cursor_(reinterpret_cast<byte*>(buffer)),
|
||||
dirty_(false),
|
||||
capacity_(capacity) {
|
||||
@@ -41,6 +78,39 @@ CodeBuffer::CodeBuffer(byte* buffer, size_t capacity)
|
||||
|
||||
CodeBuffer::~CodeBuffer() VIXL_NEGATIVE_TESTING_ALLOW_EXCEPTION {
|
||||
VIXL_ASSERT(!IsDirty());
|
||||
if (managed_) {
|
||||
#ifdef VIXL_CODE_BUFFER_MALLOC
|
||||
free(buffer_);
|
||||
#elif defined(VIXL_CODE_BUFFER_MMAP)
|
||||
munmap(buffer_, capacity_);
|
||||
#else
|
||||
#error Unknown code buffer allocator.
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CodeBuffer::SetExecutable() {
|
||||
#ifdef VIXL_CODE_BUFFER_MMAP
|
||||
int ret = mprotect(buffer_, capacity_, PROT_READ | PROT_EXEC);
|
||||
VIXL_CHECK(ret == 0);
|
||||
#else
|
||||
// This requires page-aligned memory blocks, which we can only guarantee with
|
||||
// mmap.
|
||||
VIXL_UNIMPLEMENTED();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void CodeBuffer::SetWritable() {
|
||||
#ifdef VIXL_CODE_BUFFER_MMAP
|
||||
int ret = mprotect(buffer_, capacity_, PROT_READ | PROT_WRITE);
|
||||
VIXL_CHECK(ret == 0);
|
||||
#else
|
||||
// This requires page-aligned memory blocks, which we can only guarantee with
|
||||
// mmap.
|
||||
VIXL_UNIMPLEMENTED();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -78,16 +148,42 @@ void CodeBuffer::Align() {
|
||||
}
|
||||
|
||||
void CodeBuffer::EmitZeroedBytes(int n) {
|
||||
VIXL_ASSERT(HasSpaceFor(n));
|
||||
EnsureSpaceFor(n);
|
||||
dirty_ = true;
|
||||
memset(cursor_, 0, n);
|
||||
cursor_ += n;
|
||||
}
|
||||
|
||||
void CodeBuffer::Reset() {
|
||||
#ifdef VIXL_DEBUG
|
||||
if (managed_) {
|
||||
// Fill with zeros (there is no useful value common to A32 and T32).
|
||||
memset(buffer_, 0, capacity_);
|
||||
}
|
||||
#endif
|
||||
cursor_ = buffer_;
|
||||
SetClean();
|
||||
}
|
||||
|
||||
|
||||
void CodeBuffer::Grow(size_t new_capacity) {
|
||||
VIXL_ASSERT(managed_);
|
||||
VIXL_ASSERT(new_capacity > capacity_);
|
||||
ptrdiff_t cursor_offset = GetCursorOffset();
|
||||
#ifdef VIXL_CODE_BUFFER_MALLOC
|
||||
buffer_ = static_cast<byte*>(realloc(buffer_, new_capacity));
|
||||
VIXL_CHECK(buffer_ != NULL);
|
||||
#elif defined(VIXL_CODE_BUFFER_MMAP)
|
||||
buffer_ = static_cast<byte*>(
|
||||
mremap(buffer_, capacity_, new_capacity, MREMAP_MAYMOVE));
|
||||
VIXL_CHECK(buffer_ != MAP_FAILED);
|
||||
#else
|
||||
#error Unknown code buffer allocator.
|
||||
#endif
|
||||
|
||||
cursor_ = buffer_ + cursor_offset;
|
||||
capacity_ = new_capacity;
|
||||
}
|
||||
|
||||
|
||||
} // namespace vixl
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "compiler-intrinsics-vixl.h"
|
||||
|
||||
#include "utils-vixl.h"
|
||||
|
||||
namespace vixl {
|
||||
|
||||
3
3rdparty/vixl/src/cpu-features.cc
vendored
3
3rdparty/vixl/src/cpu-features.cc
vendored
@@ -24,9 +24,10 @@
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "cpu-features.h"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include "cpu-features.h"
|
||||
#include "globals-vixl.h"
|
||||
#include "utils-vixl.h"
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user