diff --git a/.circleci/config.yml b/.circleci/config.yml
index 957f3979b110..fe4e6dabaffd 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -8,11 +8,11 @@ parameters:
distribution-scripts-version:
description: "Git ref for version of https://github.com/crystal-lang/distribution-scripts/"
type: string
- default: "e15cbd3b6b3e1bac1b16905f1b1a15ba6ae4e554"
+ default: "535aedb8b09d77caaa1583700f371cd04343b7e8"
previous_crystal_base_url:
description: "Prefix for URLs to Crystal bootstrap compiler"
type: string
- default: "https://github.com/crystal-lang/crystal/releases/download/1.10.1/crystal-1.10.1-1"
+ default: "https://github.com/crystal-lang/crystal/releases/download/1.11.2/crystal-1.11.2-1"
defaults:
environment: &env
@@ -39,7 +39,7 @@ defaults:
jobs:
test_linux:
machine:
- image: ubuntu-2004:202201-02
+ image: default
environment:
<<: *env
TRAVIS_OS_NAME: linux
@@ -70,7 +70,7 @@ jobs:
test_alpine:
machine:
- image: ubuntu-2004:202201-02
+ image: default
environment:
<<: *env
TRAVIS_OS_NAME: linux
@@ -115,7 +115,8 @@ jobs:
test_preview_mt:
machine:
- image: ubuntu-2004:202201-02
+ image: default
+ resource_class: large
environment:
<<: *env
TRAVIS_OS_NAME: linux
@@ -263,7 +264,7 @@ jobs:
dist_linux:
machine:
- image: ubuntu-2004:202201-02
+ image: default
steps:
- attach_workspace:
at: /tmp/workspace
@@ -346,7 +347,7 @@ jobs:
dist_docker:
machine:
- image: ubuntu-2004:202201-02
+ image: default
steps:
- attach_workspace:
at: /tmp/workspace
@@ -362,7 +363,7 @@ jobs:
publish_docker:
machine:
- image: ubuntu-2004:202201-02
+ image: default
steps:
- attach_workspace:
at: /tmp/workspace
@@ -417,7 +418,7 @@ jobs:
dist_docs:
machine:
- image: ubuntu-2004:202201-02
+ image: default
steps:
- attach_workspace:
at: /tmp/workspace
@@ -463,7 +464,7 @@ jobs:
test_dist_linux_on_docker:
machine:
- image: ubuntu-2004:202201-02
+ image: default
environment:
<<: *env
TRAVIS_OS_NAME: linux
diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md
index 756c4cfd2816..e6665a621eaa 100644
--- a/.github/ISSUE_TEMPLATE/feature-request.md
+++ b/.github/ISSUE_TEMPLATE/feature-request.md
@@ -10,3 +10,7 @@ labels: kind:feature
- Describe the feature you would like, optionally illustrated by examples, and how it will solve the above problem.
- Describe considered alternative solutions, and the reasons why you have not proposed them as a solution here.
- Does it break backward compatibility, if yes then what's the migration path?
+
+In case this proposal includes a substantial change to the language, we ask you to go through an [RFC process](https://github.com/crystal-lang/rfcs).
+
+The best place to start an open discussion about potential changes is the [Crystal forum](https://forum.crystal-lang.org/c/crystal-contrib/6).
diff --git a/.github/renovate.json b/.github/renovate.json
index 4e18234dc0ec..39932ec1f648 100644
--- a/.github/renovate.json
+++ b/.github/renovate.json
@@ -12,5 +12,6 @@
"matchManagers": ["github-actions"],
"schedule": ["after 5am and before 8am on Wednesday"]
}
- ]
+ ],
+ "labels": ["topic:infrastructure/ci"]
}
diff --git a/.github/workflows/aarch64.yml b/.github/workflows/aarch64.yml
index 2671fe5d61d6..da252904fa37 100644
--- a/.github/workflows/aarch64.yml
+++ b/.github/workflows/aarch64.yml
@@ -18,7 +18,7 @@ jobs:
with:
args: make crystal
- name: Upload Crystal executable
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: crystal-aarch64-musl
path: |
@@ -32,7 +32,7 @@ jobs:
- name: Download Crystal source
uses: actions/checkout@v4
- name: Download Crystal executable
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: crystal-aarch64-musl
- name: Mark downloaded compiler as executable
@@ -49,7 +49,7 @@ jobs:
- name: Download Crystal source
uses: actions/checkout@v4
- name: Download Crystal executable
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: crystal-aarch64-musl
- name: Mark downloaded compiler as executable
@@ -69,7 +69,7 @@ jobs:
with:
args: make crystal
- name: Upload Crystal executable
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: crystal-aarch64-gnu
path: |
@@ -83,7 +83,7 @@ jobs:
- name: Download Crystal source
uses: actions/checkout@v4
- name: Download Crystal executable
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: crystal-aarch64-gnu
- name: Mark downloaded compiler as executable
@@ -100,7 +100,7 @@ jobs:
- name: Download Crystal source
uses: actions/checkout@v4
- name: Download Crystal executable
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: crystal-aarch64-gnu
- name: Mark downloaded compiler as executable
diff --git a/.github/workflows/interpreter.yml b/.github/workflows/interpreter.yml
index bf9dc3808479..81b7b8ec05ba 100644
--- a/.github/workflows/interpreter.yml
+++ b/.github/workflows/interpreter.yml
@@ -13,7 +13,7 @@ jobs:
test-interpreter_spec:
runs-on: ubuntu-22.04
container:
- image: crystallang/crystal:1.10.1-build
+ image: crystallang/crystal:1.11.2-build
name: "Test Interpreter"
steps:
- uses: actions/checkout@v4
@@ -24,7 +24,7 @@ jobs:
build-interpreter:
runs-on: ubuntu-22.04
container:
- image: crystallang/crystal:1.10.1-build
+ image: crystallang/crystal:1.11.2-build
name: Build interpreter
steps:
- uses: actions/checkout@v4
@@ -33,7 +33,7 @@ jobs:
run: make interpreter=1 release=1
- name: Upload compiler artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: crystal-interpreter
path: |
@@ -44,7 +44,7 @@ jobs:
runs-on: ubuntu-22.04
timeout-minutes: 15
container:
- image: crystallang/crystal:1.10.1-build
+ image: crystallang/crystal:1.11.2-build
strategy:
matrix:
part: [0, 1, 2, 3]
@@ -53,7 +53,7 @@ jobs:
- uses: actions/checkout@v4
- name: Download compiler artifact
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: crystal-interpreter
path: .build/
diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
index 9ef73a9fe23c..3d85af22e5a3 100644
--- a/.github/workflows/linux.yml
+++ b/.github/workflows/linux.yml
@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
- crystal_bootstrap_version: [1.7.3, 1.8.2, 1.9.2, 1.10.1]
+ crystal_bootstrap_version: [1.7.3, 1.8.2, 1.9.2, 1.10.1, 1.11.2]
flags: [""]
include:
# libffi is only available starting from the 1.2.2 build images
diff --git a/.github/workflows/llvm.yml b/.github/workflows/llvm.yml
index f361896768d8..887ede290fe3 100644
--- a/.github/workflows/llvm.yml
+++ b/.github/workflows/llvm.yml
@@ -33,7 +33,7 @@ jobs:
- name: Cache LLVM
id: cache-llvm
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: ./llvm
key: llvm-${{ matrix.llvm_version }}
@@ -56,7 +56,7 @@ jobs:
- name: Install Crystal
uses: crystal-lang/install-crystal@v1
with:
- crystal: "1.10.1"
+ crystal: "1.11.2"
- name: Build libllvm_ext
run: make -B deps
diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml
index dbab5f5bc93c..765595ce2d09 100644
--- a/.github/workflows/macos.yml
+++ b/.github/workflows/macos.yml
@@ -17,12 +17,12 @@ jobs:
- name: Download Crystal source
uses: actions/checkout@v4
- - uses: cachix/install-nix-action@v24
+ - uses: cachix/install-nix-action@v25
with:
install_url: https://releases.nixos.org/nix/nix-2.9.2/install
extra_nix_config: |
experimental-features = nix-command
- - uses: cachix/cachix-action@v13
+ - uses: cachix/cachix-action@v14
with:
name: crystal-ci
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
diff --git a/.github/workflows/openssl.yml b/.github/workflows/openssl.yml
index 07e2d7e94558..65766c6325c2 100644
--- a/.github/workflows/openssl.yml
+++ b/.github/workflows/openssl.yml
@@ -10,7 +10,7 @@ jobs:
openssl3:
runs-on: ubuntu-latest
name: "OpenSSL 3.0"
- container: crystallang/crystal:1.10.1-alpine
+ container: crystallang/crystal:1.11.2-alpine
steps:
- name: Download Crystal source
uses: actions/checkout@v4
@@ -27,7 +27,7 @@ jobs:
openssl111:
runs-on: ubuntu-latest
name: "OpenSSL 1.1.1"
- container: crystallang/crystal:1.10.1-alpine
+ container: crystallang/crystal:1.11.2-alpine
steps:
- name: Download Crystal source
uses: actions/checkout@v4
@@ -42,7 +42,7 @@ jobs:
libressl34:
runs-on: ubuntu-latest
name: "LibreSSL 3.4"
- container: crystallang/crystal:1.10.1-alpine
+ container: crystallang/crystal:1.11.2-alpine
steps:
- name: Download Crystal source
uses: actions/checkout@v4
diff --git a/.github/workflows/regex-engine.yml b/.github/workflows/regex-engine.yml
index a7ad3afbbb65..d7d9c2655584 100644
--- a/.github/workflows/regex-engine.yml
+++ b/.github/workflows/regex-engine.yml
@@ -10,7 +10,7 @@ jobs:
pcre:
runs-on: ubuntu-latest
name: "PCRE"
- container: crystallang/crystal:1.10.1-alpine
+ container: crystallang/crystal:1.11.2-alpine
steps:
- name: Download Crystal source
uses: actions/checkout@v4
@@ -25,7 +25,7 @@ jobs:
pcre2:
runs-on: ubuntu-latest
name: "PCRE2"
- container: crystallang/crystal:1.10.1-alpine
+ container: crystallang/crystal:1.11.2-alpine
steps:
- name: Download Crystal source
uses: actions/checkout@v4
diff --git a/.github/workflows/wasm32.yml b/.github/workflows/wasm32.yml
index 0d4f32f4c044..c8f2058ebea0 100644
--- a/.github/workflows/wasm32.yml
+++ b/.github/workflows/wasm32.yml
@@ -12,7 +12,7 @@ env:
jobs:
wasm32-test:
runs-on: ubuntu-latest
- container: crystallang/crystal:1.10.1-build
+ container: crystallang/crystal:1.11.2-build
steps:
- name: Download Crystal source
uses: actions/checkout@v4
diff --git a/.github/workflows/win.yml b/.github/workflows/win.yml
index 90ed0e0c980d..3ef4cccb8739 100644
--- a/.github/workflows/win.yml
+++ b/.github/workflows/win.yml
@@ -7,7 +7,7 @@ concurrency:
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
env:
- CI_LLVM_VERSION: "17.0.2"
+ CI_LLVM_VERSION: "18.1.0-rc1"
jobs:
x86_64-windows-libs:
@@ -18,14 +18,14 @@ jobs:
git config --global core.autocrlf false
- name: Enable Developer Command Prompt
- uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1
+ uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0
- name: Download Crystal source
uses: actions/checkout@v4
- name: Cache libraries
id: cache-libs
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: | # openssl and llvm take much longer to build so they are cached separately
libs/pcre.lib
@@ -68,7 +68,7 @@ jobs:
- name: Cache OpenSSL
id: cache-openssl
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: |
libs/crypto.lib
@@ -77,7 +77,7 @@ jobs:
key: win-openssl-libs-3.1.0-${{ hashFiles('etc/win-ci/build-openssl.ps1') }}-msvc
- name: Set up NASM
if: steps.cache-openssl.outputs.cache-hit != 'true'
- uses: ilammy/setup-nasm@321e6ed62a1fc77024a3bd853deb33645e8b22c4 # v1.4.0
+ uses: ilammy/setup-nasm@13cbeb366c45c4379d3478cdcbadd8295feb5028 # v1.5.1
- name: Build OpenSSL
if: steps.cache-openssl.outputs.cache-hit != 'true'
run: .\etc\win-ci\build-openssl.ps1 -BuildTree deps\openssl -Version 3.1.0
@@ -90,14 +90,14 @@ jobs:
git config --global core.autocrlf false
- name: Enable Developer Command Prompt
- uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1
+ uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0
- name: Download Crystal source
uses: actions/checkout@v4
- name: Cache libraries
id: cache-dlls
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: | # openssl and llvm take much longer to build so they are cached separately
libs/pcre-dynamic.lib
@@ -149,7 +149,7 @@ jobs:
- name: Cache OpenSSL
id: cache-openssl-dlls
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: |
libs/crypto-dynamic.lib
@@ -159,7 +159,7 @@ jobs:
key: win-openssl-dlls-3.1.0-${{ hashFiles('etc/win-ci/build-openssl.ps1') }}-msvc
- name: Set up NASM
if: steps.cache-openssl-dlls.outputs.cache-hit != 'true'
- uses: ilammy/setup-nasm@321e6ed62a1fc77024a3bd853deb33645e8b22c4 # v1.4.0
+ uses: ilammy/setup-nasm@13cbeb366c45c4379d3478cdcbadd8295feb5028 # v1.5.1
- name: Build OpenSSL
if: steps.cache-openssl-dlls.outputs.cache-hit != 'true'
run: .\etc\win-ci\build-openssl.ps1 -BuildTree deps\openssl -Version 3.1.0 -Dynamic
@@ -168,39 +168,22 @@ jobs:
runs-on: windows-2022
steps:
- name: Enable Developer Command Prompt
- uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1
+ uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0
- name: Cache LLVM
id: cache-llvm-libs
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: llvm
key: llvm-libs-${{ env.CI_LLVM_VERSION }}-msvc
- - name: Download LLVM
- if: steps.cache-llvm-libs.outputs.cache-hit != 'true'
- run: |
- iwr https://github.com/llvm/llvm-project/releases/download/llvmorg-${{ env.CI_LLVM_VERSION }}/llvm-${{ env.CI_LLVM_VERSION }}.src.tar.xz -OutFile llvm.tar.xz
- (Get-FileHash -Algorithm SHA256 .\llvm.tar.xz).hash -eq "D820E63BC3A6F4F833EC69A1EF49A2E81992E90BC23989F98946914B061AB6C7"
- 7z x llvm.tar.xz
- 7z x llvm.tar
- mv llvm-* llvm-src
-
- - name: Download LLVM's CMake files
- if: steps.cache-llvm-libs.outputs.cache-hit != 'true'
- run: |
- iwr https://github.com/llvm/llvm-project/releases/download/llvmorg-${{ env.CI_LLVM_VERSION }}/cmake-${{ env.CI_LLVM_VERSION }}.src.tar.xz -OutFile cmake.tar.xz
- (Get-FileHash -Algorithm SHA256 .\cmake.tar.xz).hash -eq "B6D83C91F12757030D8361DEDC5DD84357B3EDB8DA406B5D0850DF8B6F7798B1"
- 7z x cmake.tar.xz
- 7z x cmake.tar
- mv cmake-* cmake
-
- name: Build LLVM
if: steps.cache-llvm-libs.outputs.cache-hit != 'true'
run: |
+ git clone --config core.autocrlf=false -b llvmorg-${{ env.CI_LLVM_VERSION }} --depth 1 https://github.com/llvm/llvm-project.git
mkdir llvm-build
cd llvm-build
- cmake ..\llvm-src -Thost=x64 -DLLVM_TARGETS_TO_BUILD="X86;AArch64" -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DBUILD_SHARED_LIBS=OFF -DCMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH=OFF -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_ENABLE_ZSTD=OFF
+ cmake ..\llvm-project\llvm -Thost=x64 -DLLVM_TARGETS_TO_BUILD="X86;AArch64" -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DBUILD_SHARED_LIBS=OFF -DCMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH=OFF -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_ENABLE_ZSTD=OFF
cmake --build . --config Release
cmake "-DCMAKE_INSTALL_PREFIX=$(pwd)\..\llvm" -P cmake_install.cmake
@@ -212,14 +195,14 @@ jobs:
git config --global core.autocrlf false
- name: Enable Developer Command Prompt
- uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1
+ uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0
- name: Download Crystal source
uses: actions/checkout@v4
- name: Cache LLVM
id: cache-llvm-dlls
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: |
libs/llvm_VERSION
@@ -235,7 +218,7 @@ jobs:
uses: ./.github/workflows/win_build_portable.yml
with:
release: false
- llvm_version: "17.0.2"
+ llvm_version: "18.1.0-rc1"
x86_64-windows-test:
runs-on: windows-2022
@@ -246,19 +229,19 @@ jobs:
git config --global core.autocrlf false
- name: Enable Developer Command Prompt
- uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1
+ uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0
- name: Download Crystal source
uses: actions/checkout@v4
- name: Download Crystal executable
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: crystal
path: build
- name: Restore LLVM
- uses: actions/cache/restore@v3
+ uses: actions/cache/restore@v4
with:
path: llvm
key: llvm-libs-${{ env.CI_LLVM_VERSION }}-msvc
@@ -288,7 +271,7 @@ jobs:
uses: ./.github/workflows/win_build_portable.yml
with:
release: true
- llvm_version: "17.0.2"
+ llvm_version: "18.1.0-rc1"
x86_64-windows-installer:
if: github.repository_owner == 'crystal-lang' && (startsWith(github.ref, 'refs/tags/') || startsWith(github.ref, 'refs/heads/ci/'))
@@ -303,13 +286,13 @@ jobs:
uses: actions/checkout@v4
- name: Download Crystal executable
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: crystal-release
path: etc/win-ci/portable
- name: Restore LLVM
- uses: actions/cache/restore@v3
+ uses: actions/cache/restore@v4
with:
path: llvm
key: llvm-libs-${{ env.CI_LLVM_VERSION }}-msvc
@@ -329,7 +312,7 @@ jobs:
iscc.exe crystal.iss
- name: Upload Crystal installer
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: crystal-installer
path: etc/win-ci/Output/crystal-setup.exe
diff --git a/.github/workflows/win_build_portable.yml b/.github/workflows/win_build_portable.yml
index 18eea4f1f317..bab89e04685e 100644
--- a/.github/workflows/win_build_portable.yml
+++ b/.github/workflows/win_build_portable.yml
@@ -19,18 +19,18 @@ jobs:
git config --global core.autocrlf false
- name: Enable Developer Command Prompt
- uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1
+ uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0
- name: Install Crystal
uses: crystal-lang/install-crystal@v1
with:
- crystal: "1.10.1"
+ crystal: "1.11.2"
- name: Download Crystal source
uses: actions/checkout@v4
- name: Restore libraries
- uses: actions/cache/restore@v3
+ uses: actions/cache/restore@v4
with:
path: |
libs/pcre.lib
@@ -45,7 +45,7 @@ jobs:
key: win-libs-${{ hashFiles('.github/workflows/win.yml', 'etc/win-ci/*.ps1') }}-msvc
fail-on-cache-miss: true
- name: Restore OpenSSL
- uses: actions/cache/restore@v3
+ uses: actions/cache/restore@v4
with:
path: |
libs/crypto.lib
@@ -54,7 +54,7 @@ jobs:
key: win-openssl-libs-3.1.0-${{ hashFiles('etc/win-ci/build-openssl.ps1') }}-msvc
fail-on-cache-miss: true
- name: Restore DLLs
- uses: actions/cache/restore@v3
+ uses: actions/cache/restore@v4
with:
path: |
libs/pcre-dynamic.lib
@@ -78,7 +78,7 @@ jobs:
key: win-dlls-${{ hashFiles('.github/workflows/win.yml', 'etc/win-ci/*.ps1') }}-msvc
fail-on-cache-miss: true
- name: Restore OpenSSL DLLs
- uses: actions/cache/restore@v3
+ uses: actions/cache/restore@v4
with:
path: |
libs/crypto-dynamic.lib
@@ -88,13 +88,13 @@ jobs:
key: win-openssl-dlls-3.1.0-${{ hashFiles('etc/win-ci/build-openssl.ps1') }}-msvc
fail-on-cache-miss: true
- name: Restore LLVM
- uses: actions/cache/restore@v3
+ uses: actions/cache/restore@v4
with:
path: llvm
key: llvm-libs-${{ inputs.llvm_version }}-msvc
fail-on-cache-miss: true
- name: Restore LLVM DLLs
- uses: actions/cache/restore@v3
+ uses: actions/cache/restore@v4
with:
path: |
libs/llvm_VERSION
@@ -120,7 +120,7 @@ jobs:
uses: actions/checkout@v4
with:
repository: crystal-lang/shards
- ref: v0.17.3
+ ref: v0.17.4
path: shards
- name: Download molinillo release
@@ -144,7 +144,7 @@ jobs:
cp README.md crystal/
- name: Upload Crystal binaries
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: ${{ inputs.release && 'crystal-release' || 'crystal' }}
path: crystal
diff --git a/.gitignore b/.gitignore
index 5d74450c533f..987e8a649620 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
# Build artifacts
/.build/
+/samples/.build/
/docs/
/src/llvm/ext/llvm_ext.o
/src/llvm/ext/llvm_ext.obj
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5d2c17878c9d..4e152e9ad2d4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,297 @@
# Changelog
+## [1.11.2] (2024-01-18)
+
+[1.11.2]: https://github.com/crystal-lang/crystal/releases/1.11.2
+
+### Bugfixes
+
+#### stdlib
+
+- *(files)* Fix missing `cause` parameter from `IO::Error#initialize` ([#14242](https://github.com/crystal-lang/crystal/pull/14242), thanks @straight-shoota)
+- *(runtime)* Always use `%p` for pointers in `Crystal::System.print_error` ([#14186](https://github.com/crystal-lang/crystal/pull/14186), thanks @HertzDevil)
+- *(runtime)* Fixup for always use `%p` for pointers in `Crystal::System.print_error` ([#14221](https://github.com/crystal-lang/crystal/pull/14221), thanks @HertzDevil)
+
+### Infrastructure
+
+- Changelog for 1.11.2 ([#14249](https://github.com/crystal-lang/crystal/pull/14249), thanks @straight-shoota)
+
+## [1.11.1] (2024-01-11)
+
+[1.11.1]: https://github.com/crystal-lang/crystal/releases/1.11.1
+
+### Bugfixes
+
+#### stdlib
+
+- *(crypto)* Revert "Fix OpenSSL error handling for EOF (support for OpenSSL 3.2) (#14169)" ([#14217](https://github.com/crystal-lang/crystal/pull/14217), thanks @straight-shoota)
+
+#### compiler
+
+- *(interpreter)* Remove pkg-config name for libgc as workaround for interpreter loader ([#14198](https://github.com/crystal-lang/crystal/pull/14198), thanks @straight-shoota)
+- *(semantic)* Revert "Add `ReferenceStorage` for manual allocation of references (#14106)" ([#14207](https://github.com/crystal-lang/crystal/pull/14207), thanks @straight-shoota)
+
+### Infrastructure
+
+- Changelog for 1.11.1 ([#14208](https://github.com/crystal-lang/crystal/pull/14208), thanks @straight-shoota)
+- Bump VERSION to 1.11.1-dev ([#14197](https://github.com/crystal-lang/crystal/pull/14197), thanks @straight-shoota)
+
+## [1.11.0] (2024-01-08)
+
+[1.11.0]: https://github.com/crystal-lang/crystal/releases/1.11.0
+
+### Features
+
+#### lang
+
+- **[breaking]** Support `alignof` and `instance_alignof` ([#14087](https://github.com/crystal-lang/crystal/pull/14087), thanks @HertzDevil)
+- *(annotations)* Support `dll` parameter in `@[Link]` ([#14131](https://github.com/crystal-lang/crystal/pull/14131), thanks @HertzDevil)
+- *(macros)* Expose macro `Call` context via new `@caller` macro ivar ([#14048](https://github.com/crystal-lang/crystal/pull/14048), thanks @Blacksmoke16)
+
+#### stdlib
+
+- *(collection)* Add `Enumerable#present?` ([#13866](https://github.com/crystal-lang/crystal/pull/13866), thanks @straight-shoota)
+- *(collection)* Add `Enumerable#each_step` and `Iterable#each_step` ([#13610](https://github.com/crystal-lang/crystal/pull/13610), thanks @baseballlover723)
+- *(collection)* Add `Enumerable(T)#to_set(& : T -> U) : Set(U) forall U` ([#12654](https://github.com/crystal-lang/crystal/pull/12654), thanks @caspiano)
+- *(collection)* Add `Enumerable(T)#to_a(& : T -> U) forall U` ([#12653](https://github.com/crystal-lang/crystal/pull/12653), thanks @caspiano)
+- *(files)* Add `IO::Error#target` ([#13865](https://github.com/crystal-lang/crystal/pull/13865), thanks @straight-shoota)
+- *(llvm)* Add `LLVM::OperandBundleDef#dispose` ([#14095](https://github.com/crystal-lang/crystal/pull/14095), thanks @HertzDevil)
+- *(llvm)* Windows: Use local configuration for LLVM when linking dynamically ([#14101](https://github.com/crystal-lang/crystal/pull/14101), thanks @HertzDevil)
+- *(macros)* Add `CharLiteral#ord` ([#13910](https://github.com/crystal-lang/crystal/pull/13910), thanks @refi64)
+- *(macros)* Add macro methods for `MacroIf` and `MacroFor` nodes ([#13902](https://github.com/crystal-lang/crystal/pull/13902), thanks @sbsoftware)
+- *(macros)* Expose doc comments on `ASTNode` when generating docs ([#14050](https://github.com/crystal-lang/crystal/pull/14050), thanks @Blacksmoke16)
+- *(macros)* Add macro methods for `ModuleDef` ([#14063](https://github.com/crystal-lang/crystal/pull/14063), thanks @HertzDevil)
+- *(macros)* Add macro methods for `Include` and `Extend` ([#14064](https://github.com/crystal-lang/crystal/pull/14064), thanks @HertzDevil)
+- *(macros)* Add macro methods for `ClassDef`, `EnumDef`, `AnnotationDef` ([#14072](https://github.com/crystal-lang/crystal/pull/14072), thanks @HertzDevil)
+- *(numeric)* Implement `BigRational`'s rounding modes ([#13871](https://github.com/crystal-lang/crystal/pull/13871), thanks @HertzDevil)
+- *(numeric)* Support full exponent range in `BigFloat#**(BigInt)` ([#13881](https://github.com/crystal-lang/crystal/pull/13881), thanks @HertzDevil)
+- *(numeric)* Add `Math.fma` ([#13934](https://github.com/crystal-lang/crystal/pull/13934), thanks @HertzDevil)
+- *(numeric)* Add `Number#integer?` ([#13936](https://github.com/crystal-lang/crystal/pull/13936), thanks @HertzDevil)
+- *(numeric)* Publish `Int::Primitive#abs_unsigned` and `#neg_signed` ([#13938](https://github.com/crystal-lang/crystal/pull/13938), thanks @HertzDevil)
+- *(numeric)* Add `Int::Primitive#to_signed`, `#to_signed!`, `#to_unsigned`, `#to_unsigned!` ([#13960](https://github.com/crystal-lang/crystal/pull/13960), thanks @HertzDevil)
+- *(numeric)* Support `BigFloat#**` for all `Int::Primitive` arguments ([#13971](https://github.com/crystal-lang/crystal/pull/13971), thanks @HertzDevil)
+- *(numeric)* Add `Float32::MIN_SUBNORMAL` and `Float64::MIN_SUBNORMAL` ([#13961](https://github.com/crystal-lang/crystal/pull/13961), thanks @HertzDevil)
+- *(numeric)* Add `Float::Primitive.parse_hexfloat`, `.parse_hexfloat?`, `#to_hexfloat` ([#14027](https://github.com/crystal-lang/crystal/pull/14027), thanks @HertzDevil)
+- *(numeric)* Implement `sprintf "%f"` in Crystal using Ryu Printf ([#14067](https://github.com/crystal-lang/crystal/pull/14067), thanks @HertzDevil)
+- *(numeric)* Implement `sprintf "%e"` in Crystal ([#14084](https://github.com/crystal-lang/crystal/pull/14084), thanks @HertzDevil)
+- *(numeric)* Implement `sprintf "%a"` in Crystal ([#14102](https://github.com/crystal-lang/crystal/pull/14102), thanks @HertzDevil)
+- *(numeric)* Implement `sprintf "%g"` in Crystal ([#14123](https://github.com/crystal-lang/crystal/pull/14123), thanks @HertzDevil)
+- *(runtime)* Add `Crystal::HOST_TRIPLE` and `TARGET_TRIPLE` ([#13823](https://github.com/crystal-lang/crystal/pull/13823), thanks @HertzDevil)
+- *(runtime)* **[experimental]** Add `Reference.pre_initialize` and `.unsafe_construct` ([#14108](https://github.com/crystal-lang/crystal/pull/14108), thanks @HertzDevil)
+- *(runtime)* **[experimental]** Add `ReferenceStorage` for manual allocation of references ([#14106](https://github.com/crystal-lang/crystal/pull/14106), thanks @HertzDevil)
+- *(serialization)* Fix `StaticArray#to_json` ([#14104](https://github.com/crystal-lang/crystal/pull/14104), thanks @Vendicated)
+- *(specs)* Add `crystal spec --dry-run` ([#13804](https://github.com/crystal-lang/crystal/pull/13804), thanks @nobodywasishere)
+- *(specs)* Add `crystal spec --list-tags` ([#13616](https://github.com/crystal-lang/crystal/pull/13616), thanks @baseballlover723)
+- *(system)* Respect Windows `Path` directory separators in `File.match?` ([#13912](https://github.com/crystal-lang/crystal/pull/13912), thanks @HertzDevil)
+- *(text)* Support Unicode 15.1.0 ([#13812](https://github.com/crystal-lang/crystal/pull/13812), thanks @HertzDevil)
+- *(text)* Add `UUID.v1`, `.v2`, `.v3`, `.v4`, `.v5` ([#13693](https://github.com/crystal-lang/crystal/pull/13693), thanks @threez)
+- *(text)* Add `String` and `Char` patterns to `StringScanner` ([#13806](https://github.com/crystal-lang/crystal/pull/13806), thanks @funny-falcon)
+- *(text)* Add `EOL`constant (End-Of-Line) ([#11303](https://github.com/crystal-lang/crystal/pull/11303), thanks @postmodern)
+- *(text)* Add `Char::Reader#current_char?`, `#next_char?`, `#previous_char?` ([#14012](https://github.com/crystal-lang/crystal/pull/14012), thanks @HertzDevil)
+- *(text)* Add `String#matches_full?` ([#13968](https://github.com/crystal-lang/crystal/pull/13968), thanks @straight-shoota)
+- *(text)* Change `Regex::MatchData#to_s` to return matched substring ([#14115](https://github.com/crystal-lang/crystal/pull/14115), thanks @Vendicated)
+
+#### compiler
+
+- *(codegen)* Add incremental optimization levels ([#13464](https://github.com/crystal-lang/crystal/pull/13464), thanks @kostya)
+- *(debugger)* Support debug information for 64-bit or unsigned enums ([#14081](https://github.com/crystal-lang/crystal/pull/14081), thanks @HertzDevil)
+- *(interpreter)* Support `instance_sizeof(T)` in the interpreter ([#14031](https://github.com/crystal-lang/crystal/pull/14031), thanks @HertzDevil)
+- *(interpreter)* Support `-dynamic.lib` in Windows interpreter ([#14143](https://github.com/crystal-lang/crystal/pull/14143), thanks @HertzDevil)
+- *(interpreter)* Support absolute paths in `CRYSTAL_INTERPRETER_LOADER_INFO` ([#14147](https://github.com/crystal-lang/crystal/pull/14147), thanks @HertzDevil)
+- *(interpreter)* Add `Crystal::Repl#parse_and_interpret` ([#14138](https://github.com/crystal-lang/crystal/pull/14138), thanks @bcardiff)
+- *(semantic)* Change short_reference for top-level methods to `::foo` ([#14071](https://github.com/crystal-lang/crystal/pull/14071), thanks @keshavbiswa)
+
+#### tools
+
+- *(docs-generator)* Expose inherited macros in generated API docs ([#13810](https://github.com/crystal-lang/crystal/pull/13810), thanks @Blacksmoke16)
+- *(docs-generator)* Order macros below class methods in generated docs ([#14024](https://github.com/crystal-lang/crystal/pull/14024), thanks @Blacksmoke16)
+- *(formatter)* Do not remove trailing comma from multi-line macro/def parameters (not yet enabled) ([#14075](https://github.com/crystal-lang/crystal/pull/14075), thanks @Blacksmoke16)
+- *(unreachable)* Add `--check` flag to `crystal tool unreachable` ([#13930](https://github.com/crystal-lang/crystal/pull/13930), thanks @straight-shoota)
+- *(unreachable)* Add annotations to output of `crystal tool unreachable` ([#13927](https://github.com/crystal-lang/crystal/pull/13927), thanks @straight-shoota)
+- *(unreachable)* Print relative paths in `crystal tool unreachable` ([#13929](https://github.com/crystal-lang/crystal/pull/13929), thanks @straight-shoota)
+- *(unreachable)* Add CSV output format to `crystal tool unreachable` ([#13926](https://github.com/crystal-lang/crystal/pull/13926), thanks @straight-shoota)
+- *(unreachable)* Add `--tallies` option to `crystal tool unreachable` ([#13969](https://github.com/crystal-lang/crystal/pull/13969), thanks @straight-shoota)
+
+### Bugfixes
+
+#### stdlib
+
+- Fix `Box(T?)` crashing on `nil` ([#13893](https://github.com/crystal-lang/crystal/pull/13893), thanks @HertzDevil)
+- Fix typos in src ([#14053](https://github.com/crystal-lang/crystal/pull/14053), thanks @kojix2)
+- *(collection)* Fix `Indexable#each_repeated_combination(n)` when `n > size` ([#14092](https://github.com/crystal-lang/crystal/pull/14092), thanks @HertzDevil)
+- *(concurrency)* Make `Process#wait` asynchronous on Windows ([#13908](https://github.com/crystal-lang/crystal/pull/13908), thanks @HertzDevil)
+- *(concurrency)* Fix math overflow after spawning `Int32::MAX + 1` fibers ([#14096](https://github.com/crystal-lang/crystal/pull/14096), thanks @ysbaddaden)
+- *(concurrency)* Fix `can't resume a running fiber` ([#14128](https://github.com/crystal-lang/crystal/pull/14128), thanks @ysbaddaden)
+- *(crypto)* Fix OpenSSL error handling for EOF (support for OpenSSL 3.2) ([#14169](https://github.com/crystal-lang/crystal/pull/14169), thanks @straight-shoota)
+- *(files)* Fix `Globber.constant_entry?` matching patterns ([#13955](https://github.com/crystal-lang/crystal/pull/13955), thanks @GeopJr)
+- *(files)* Fix `String::Buffer` and `IO::Memory` capacity to grow beyond 1GB ([#13989](https://github.com/crystal-lang/crystal/pull/13989), thanks @straight-shoota)
+- *(llvm)* Fix a typo ([#13914](https://github.com/crystal-lang/crystal/pull/13914), thanks @kojix2)
+- *(numeric)* Make `String#to_f(whitespace: false)` work with infinity and NaN ([#13875](https://github.com/crystal-lang/crystal/pull/13875), thanks @HertzDevil)
+- *(numeric)* Use `LibGMP::SI` and `UI` for size checks, not `Long` and `ULong` ([#13874](https://github.com/crystal-lang/crystal/pull/13874), thanks @HertzDevil)
+- *(numeric)* Fix integral part extraction in `Number#format` ([#14061](https://github.com/crystal-lang/crystal/pull/14061), thanks @HertzDevil)
+- *(numeric)* Fix out-of-bounds access in `Int128::MIN.to_s(base: 2)` ([#14119](https://github.com/crystal-lang/crystal/pull/14119), thanks @HertzDevil)
+- *(numeric)* Avoid double rounding in `Float#format` for nonnegative `decimal_place` ([#14129](https://github.com/crystal-lang/crystal/pull/14129), thanks @HertzDevil)
+- *(runtime)* Avoid `@[ThreadLocal]` on Android ([#14025](https://github.com/crystal-lang/crystal/pull/14025), thanks @HertzDevil)
+- *(runtime)* Never use string interpolation in `Crystal::System.print_error` ([#14114](https://github.com/crystal-lang/crystal/pull/14114), thanks @HertzDevil)
+- *(runtime)* Fix segfault with next boehm gc (after v8.2.4) ([#14130](https://github.com/crystal-lang/crystal/pull/14130), thanks @ysbaddaden)
+- *(specs)* Skip spec execution on error exit ([#13986](https://github.com/crystal-lang/crystal/pull/13986), thanks @straight-shoota)
+- *(system)* Fix `FileUtils.ln_sf` to override special file types ([#13896](https://github.com/crystal-lang/crystal/pull/13896), thanks @straight-shoota)
+- *(system)* Fix `Process.exists?` throwing errors on EPERM ([#13911](https://github.com/crystal-lang/crystal/pull/13911), thanks @refi64)
+- *(system)* Fix portable shell command arguments in `Process#prepare_args` ([#13942](https://github.com/crystal-lang/crystal/pull/13942), thanks @GeopJr)
+- *(system)* Windows: Do not close process handle in `Process#close` ([#13997](https://github.com/crystal-lang/crystal/pull/13997), thanks @HertzDevil)
+- *(system)* Windows: clear `Crystal::System::Process#@completion_key` after use ([#14068](https://github.com/crystal-lang/crystal/pull/14068), thanks @HertzDevil)
+- *(system)* Fix UTF-8 console input on Windows ([#13758](https://github.com/crystal-lang/crystal/pull/13758), thanks @erdian718)
+- *(text)* Fix invalid UTF-8 handling in `Char::Reader#previous_char` ([#14013](https://github.com/crystal-lang/crystal/pull/14013), thanks @HertzDevil)
+- *(text)* Fix `options` parameter for `String#split`, `#scan` ([#14183](https://github.com/crystal-lang/crystal/pull/14183), thanks @straight-shoota)
+- *(time)* Fix time span overflow on `Int#milliseconds` and `Int#microseconds` ([#14105](https://github.com/crystal-lang/crystal/pull/14105), thanks @bcardiff)
+
+#### compiler
+
+- *(cli)* Remove unnecessary file check for CLI arguments ([#13853](https://github.com/crystal-lang/crystal/pull/13853), thanks @straight-shoota)
+- *(cli)* Check for invalid integers in compiler's CLI ([#13959](https://github.com/crystal-lang/crystal/pull/13959), thanks @HertzDevil)
+- *(cli)* Fix compiler error message for invalid source file ([#14157](https://github.com/crystal-lang/crystal/pull/14157), thanks @straight-shoota)
+- *(codegen)* Fix a typo in compiler source ([#14054](https://github.com/crystal-lang/crystal/pull/14054), thanks @kojix2)
+- *(codegen)* Fix codegen error when discarding `is_a?` or `responds_to?`'s result ([#14148](https://github.com/crystal-lang/crystal/pull/14148), thanks @HertzDevil)
+- *(interpreter)* Fix element alignment of `Tuple` and `NamedTuple` casts ([#14040](https://github.com/crystal-lang/crystal/pull/14040), thanks @HertzDevil)
+- *(interpreter)* `Crystal::Loader`: Skip second linker member on Windows if absent ([#14111](https://github.com/crystal-lang/crystal/pull/14111), thanks @HertzDevil)
+- *(parser)* Support `%r` and `%x` when not followed by delimiter start ([#13933](https://github.com/crystal-lang/crystal/pull/13933), thanks @HertzDevil)
+- *(parser)* Fix location of global `Path` nodes in certain constructs ([#13932](https://github.com/crystal-lang/crystal/pull/13932), thanks @HertzDevil)
+- *(parser)* Fix `ToSVisitor` for expanded string interpolation in backticks ([#13943](https://github.com/crystal-lang/crystal/pull/13943), thanks @straight-shoota)
+- *(parser)* Fix location for "invalid trailing comma in call" errors ([#13964](https://github.com/crystal-lang/crystal/pull/13964), thanks @HertzDevil)
+- *(semantic)* Fix check for file type ([#13760](https://github.com/crystal-lang/crystal/pull/13760), thanks @straight-shoota)
+- *(semantic)* Fix private type definitions with namespaced `Path`s ([#13931](https://github.com/crystal-lang/crystal/pull/13931), thanks @HertzDevil)
+- *(semantic)* Fix missing param count in compilation error message ([#13985](https://github.com/crystal-lang/crystal/pull/13985), thanks @koffeinfrei)
+- *(semantic)* Fix `ReadInstanceVar` on typedefs ([#14044](https://github.com/crystal-lang/crystal/pull/14044), thanks @HertzDevil)
+- *(semantic)* Fix global `Path` lookup inside macro when def has free variables ([#14073](https://github.com/crystal-lang/crystal/pull/14073), thanks @HertzDevil)
+- *(semantic)* Add location information to implicit flag enum members ([#14127](https://github.com/crystal-lang/crystal/pull/14127), thanks @Blacksmoke16)
+
+#### tools
+
+- *(docs-generator)* Fix `crystal docs` check `File.exists?` for `shard.yml` ([#13937](https://github.com/crystal-lang/crystal/pull/13937), thanks @straight-shoota)
+- *(docs-generator)* Fix version sorting in API docs ([#13994](https://github.com/crystal-lang/crystal/pull/13994), thanks @m-o-e)
+- *(docs-generator)* Strip whitespace in doc comment before determining summary line ([#14049](https://github.com/crystal-lang/crystal/pull/14049), thanks @Blacksmoke16)
+- *(docs-generator)* Skip `Crystal::Macros` unless generating docs ([#13970](https://github.com/crystal-lang/crystal/pull/13970), thanks @straight-shoota)
+- *(init)* Fix tool init error message when target exists but not a dir ([#13869](https://github.com/crystal-lang/crystal/pull/13869), thanks @straight-shoota)
+- *(unreachable)* Fix infinite recursion of expanded nodes in `UnreachableVisitor` ([#13922](https://github.com/crystal-lang/crystal/pull/13922), thanks @straight-shoota)
+
+### Chores
+
+#### lang
+
+- *(macros)* **[deprecation]** Deprecate the splat operators in macro expressions ([#13939](https://github.com/crystal-lang/crystal/pull/13939), thanks @HertzDevil)
+
+#### stdlib
+
+- *(llvm)* **[deprecation]** Deprecate `LLVM.start_multithreaded` and `.stop_multithreaded` ([#13949](https://github.com/crystal-lang/crystal/pull/13949), thanks @HertzDevil)
+
+### Performance
+
+#### stdlib
+
+- *(concurrency)* Skip indirections in `Crystal::Scheduler` ([#14098](https://github.com/crystal-lang/crystal/pull/14098), thanks @ysbaddaden)
+- *(numeric)* Optimize `BigInt#&`, `#|`, `#^` with `Int::Primitive` arguments ([#14006](https://github.com/crystal-lang/crystal/pull/14006), thanks @HertzDevil)
+- *(numeric)* Optimize `BigInt#bit` ([#13980](https://github.com/crystal-lang/crystal/pull/13980), thanks @HertzDevil)
+- *(numeric)* Use `#trailing_zeros_count` in `Int#gcd` ([#14069](https://github.com/crystal-lang/crystal/pull/14069), thanks @HertzDevil)
+- *(serialization)* Optimize `JSON::Builder#string` with byte-based algorithm ([#13915](https://github.com/crystal-lang/crystal/pull/13915), thanks @straight-shoota)
+- *(serialization)* Improve performance of `JSON::Builder#string` with direct stringification ([#13950](https://github.com/crystal-lang/crystal/pull/13950), thanks @straight-shoota)
+- *(text)* Refactor `HTML.unescape` in native Crystal ([#13844](https://github.com/crystal-lang/crystal/pull/13844), thanks @straight-shoota)
+- *(text)* Refactor some uses of the blockless `String#split` ([#14001](https://github.com/crystal-lang/crystal/pull/14001), thanks @HertzDevil)
+
+### Refactor
+
+#### stdlib
+
+- *(concurrency)* Add `Crystal::System::Thread` ([#13814](https://github.com/crystal-lang/crystal/pull/13814), thanks @HertzDevil)
+- *(concurrency)* Move `Thread#set_current_thread` to `Fiber` ([#14099](https://github.com/crystal-lang/crystal/pull/14099), thanks @ysbaddaden)
+- *(files)* Use `IO.copy` in `IO#gets_to_end` ([#13990](https://github.com/crystal-lang/crystal/pull/13990), thanks @straight-shoota)
+- *(files)* Do not use `pointerof(Path)` in the standard library ([#14144](https://github.com/crystal-lang/crystal/pull/14144), thanks @HertzDevil)
+- *(llvm)* **[deprecation]** Remove `LLVMExtSetCurrentDebugLocation` from `llvm_ext.cc` for LLVM 9+ ([#13965](https://github.com/crystal-lang/crystal/pull/13965), thanks @HertzDevil)
+- *(llvm)* Replace some deprecated LLVM bindings ([#13953](https://github.com/crystal-lang/crystal/pull/13953), thanks @HertzDevil)
+- *(llvm)* Split `LibLLVM` by C headers ([#13948](https://github.com/crystal-lang/crystal/pull/13948), thanks @HertzDevil)
+- *(llvm)* Support `LLVMSetTargetMachineGlobalISel` from LLVM 18 ([#14079](https://github.com/crystal-lang/crystal/pull/14079), thanks @HertzDevil)
+- *(llvm)* Support the operand bundle API from LLVM 18 ([#14082](https://github.com/crystal-lang/crystal/pull/14082), thanks @HertzDevil)
+- *(numeric)* Simplify `String::Formatter` when Ryu Printf is available ([#14132](https://github.com/crystal-lang/crystal/pull/14132), thanks @HertzDevil)
+- *(runtime)* Implement most of `Crystal::System.print_error` in native Crystal ([#14116](https://github.com/crystal-lang/crystal/pull/14116), thanks @HertzDevil)
+- *(text)* Drop `Char::Reader#@end` ([#13920](https://github.com/crystal-lang/crystal/pull/13920), thanks @straight-shoota)
+- *(text)* Generate `src/html/entities.cr` automatically ([#13998](https://github.com/crystal-lang/crystal/pull/13998), thanks @HertzDevil)
+- *(time)* Refactor leap year to use `divisible_by?` ([#13982](https://github.com/crystal-lang/crystal/pull/13982), thanks @meatball133)
+
+#### compiler
+
+- Remove relative path to vendored shards `markd` and `reply` ([#13992](https://github.com/crystal-lang/crystal/pull/13992), thanks @nobodywasishere)
+- *(cli)* Generalize allowed values for compiler CLI `--format` option ([#13940](https://github.com/crystal-lang/crystal/pull/13940), thanks @straight-shoota)
+- *(parser)* Use `Char#to_i?` in lexer ([#13841](https://github.com/crystal-lang/crystal/pull/13841), thanks @straight-shoota)
+
+#### tools
+
+- *(unreachable)* Refactor `UnreachablePresenter` ([#13941](https://github.com/crystal-lang/crystal/pull/13941), thanks @straight-shoota)
+
+### Documentation
+
+#### lang
+
+- *(macros)* Add reference to book how merging macro expansion and call docs ([#14139](https://github.com/crystal-lang/crystal/pull/14139), thanks @Blacksmoke16)
+
+#### stdlib
+
+- *(collection)* Fix documentation of `Hash#put_if_absent` ([#13898](https://github.com/crystal-lang/crystal/pull/13898), thanks @ilmanzo)
+- *(collection)* Improve docs on initial/default values passed to `Array.new` and `Hash.new` ([#13962](https://github.com/crystal-lang/crystal/pull/13962), thanks @straight-shoota)
+- *(collection)* Improve docs for `Iterator` step-by-step iteration ([#13967](https://github.com/crystal-lang/crystal/pull/13967), thanks @straight-shoota)
+- *(macros)* Document `Crystal::Macros::MagicConstant` ([#14070](https://github.com/crystal-lang/crystal/pull/14070), thanks @HertzDevil)
+- *(serialization)* Add docs and explicit type restriction for indent parameter of `JSON.build` ([#14140](https://github.com/crystal-lang/crystal/pull/14140), thanks @syeopite)
+- *(text)* Add note about `Char::Reader`'s value semantics ([#14008](https://github.com/crystal-lang/crystal/pull/14008), thanks @HertzDevil)
+- *(text)* Fix documentation for `String#index!` ([#14038](https://github.com/crystal-lang/crystal/pull/14038), thanks @gettalong)
+
+#### compiler
+
+- *(cli)* Add optimization levels to manpage ([#14162](https://github.com/crystal-lang/crystal/pull/14162), thanks @straight-shoota)
+- *(cli)* Add `unreachable` options to manpage ([#14164](https://github.com/crystal-lang/crystal/pull/14164), thanks @straight-shoota)
+- *(cli)* Fix formatting in manpage ([#14163](https://github.com/crystal-lang/crystal/pull/14163), thanks @straight-shoota)
+
+### Specs
+
+#### stdlib
+
+- Add `pending_wasm32` ([#14086](https://github.com/crystal-lang/crystal/pull/14086), thanks @HertzDevil)
+- *(concurrency)* Workaround regular timeouts in `HTTP::Server` specs with MT ([#14097](https://github.com/crystal-lang/crystal/pull/14097), thanks @ysbaddaden)
+- *(files)* Fix `File::AccessDeniedError` expectations in `File` specs ([#14029](https://github.com/crystal-lang/crystal/pull/14029), thanks @HertzDevil)
+- *(text)* Refactor specs for `HTML.unescape` ([#13842](https://github.com/crystal-lang/crystal/pull/13842), thanks @straight-shoota)
+- *(text)* Fix spec for `String#encode` and `String.new` on DragonFlyBSD ([#13944](https://github.com/crystal-lang/crystal/pull/13944), thanks @GeopJr)
+
+#### compiler
+
+- *(codegen)* Remove `LLVMExtCreateMCJITCompilerForModule` from `llvm_ext.cc` ([#13966](https://github.com/crystal-lang/crystal/pull/13966), thanks @HertzDevil)
+- *(interpreter)* Disable `mkfifo` spec for interpreter ([#14051](https://github.com/crystal-lang/crystal/pull/14051), thanks @HertzDevil)
+- *(interpreter)* Fix interpreter specs on Windows ([#14145](https://github.com/crystal-lang/crystal/pull/14145), thanks @HertzDevil)
+
+#### tools
+
+- *(docs-generator)* Use `top_level_semantic` in doc spec instead of `semantic` ([#9352](https://github.com/crystal-lang/crystal/pull/9352), thanks @makenowjust)
+
+### Infrastructure
+
+- Changelog for 1.11.0 ([#14158](https://github.com/crystal-lang/crystal/pull/14158), thanks @straight-shoota)
+- Update previous Crystal release - 1.10.0 ([#13878](https://github.com/crystal-lang/crystal/pull/13878), thanks @straight-shoota)
+- Allow to specify git fork of distribution-scripts in CI ([#13976](https://github.com/crystal-lang/crystal/pull/13976), thanks @miry)
+- Extract `generate_data` to separate Makefile ([#14015](https://github.com/crystal-lang/crystal/pull/14015), thanks @straight-shoota)
+- Windows: Run specs in random order by default ([#14041](https://github.com/crystal-lang/crystal/pull/14041), thanks @HertzDevil)
+- Update shards 0.17.4 ([#14133](https://github.com/crystal-lang/crystal/pull/14133), thanks @straight-shoota)
+- Update distribution-scripts ([#14136](https://github.com/crystal-lang/crystal/pull/14136), thanks @straight-shoota)
+- Update GH Actions to v4 ([#14120](https://github.com/crystal-lang/crystal/pull/14120), thanks @renovate)
+- Embed logo image into repository and upgrade to SVG ([#14137](https://github.com/crystal-lang/crystal/pull/14137), thanks @straight-shoota)
+- Improvements for `github-changelog` script ([#14160](https://github.com/crystal-lang/crystal/pull/14160), thanks @straight-shoota)
+- Add `scripts/generate_llvm_version_info.cr` ([#14112](https://github.com/crystal-lang/crystal/pull/14112), thanks @HertzDevil)
+- Fix `make clean` to remove zipped manpages ([#14135](https://github.com/crystal-lang/crystal/pull/14135), thanks @straight-shoota)
+- Make `scripts/*.cr` all executable ([#13999](https://github.com/crystal-lang/crystal/pull/13999), thanks @HertzDevil)
+- Reformat changelog release headings ([#13663](https://github.com/crystal-lang/crystal/pull/13663), thanks @straight-shoota)
+- Merge `samples/.gitignore` into `.gitignore` ([#14134](https://github.com/crystal-lang/crystal/pull/14134), thanks @straight-shoota)
+- *(ci)* Update GH Actions ([#13801](https://github.com/crystal-lang/crystal/pull/13801), thanks @renovate)
+- *(ci)* Update LLVM patch version to LLVM 17.0.6 ([#14080](https://github.com/crystal-lang/crystal/pull/14080), thanks @straight-shoota)
+- *(ci)* Configure Renovate Bot to add label `topic:infrastructure/ci` on PRs ([#14166](https://github.com/crystal-lang/crystal/pull/14166), thanks @straight-shoota)
+- *(ci)* Update GH Actions ([#14165](https://github.com/crystal-lang/crystal/pull/14165), thanks @renovate)
+- *(ci)* Distribute LLVM DLLs on Windows CI ([#14110](https://github.com/crystal-lang/crystal/pull/14110), thanks @HertzDevil)
+- *(ci)* Use `CMAKE_MSVC_RUNTIME_LIBRARY` flag in win.yml ([#13900](https://github.com/crystal-lang/crystal/pull/13900), thanks @HertzDevil)
+
## [1.10.1] (2023-10-13)
[1.10.1]: https://github.com/crystal-lang/crystal/releases/1.10.1
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 77ad67860f4b..640c980909ee 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -15,6 +15,10 @@ there's no more room for discussion. We'll anyway close the issue after some day
If something is missing from the language it might be that it's not yet implemented or that it was purposely left out. If in doubt, just ask.
+Substantial changes go through an [RFC process](https://github.com/crystal-lang/rfcs).
+
+The best place to start an open discussion about potential changes is the [Crystal forum](https://forum.crystal-lang.org/c/crystal-contrib/6).
+
### What's needed right now
You can find a list of tasks that we consider suitable for a first time contribution at
diff --git a/Makefile b/Makefile
index 7e8070d16921..461ee56bd5e5 100644
--- a/Makefile
+++ b/Makefile
@@ -127,6 +127,7 @@ samples: ## Build example programs
docs: ## Generate standard library documentation
$(call check_llvm_config)
./bin/crystal docs src/docs_main.cr $(DOCS_OPTIONS) --project-name=Crystal --project-version=$(CRYSTAL_VERSION) --source-refname=$(CRYSTAL_CONFIG_BUILD_COMMIT)
+ cp -av doc/ docs/
.PHONY: crystal
crystal: $(O)/crystal ## Build the compiler
@@ -182,7 +183,6 @@ install_docs: docs ## Install docs at DESTDIR
cp -av docs "$(DATADIR)/docs"
cp -av samples "$(DATADIR)/examples"
- rm -rf "$(DATADIR)/examples/.gitignore"
.PHONY: uninstall_docs
uninstall_docs: ## Uninstall docs from DESTDIR
@@ -230,6 +230,7 @@ man/%.gz: man/%
.PHONY: clean
clean: clean_crystal ## Clean up built directories and files
rm -rf $(LLVM_EXT_OBJ)
+ rm -rf man/*.gz
.PHONY: clean_crystal
clean_crystal: ## Clean up crystal built files
diff --git a/Makefile.win b/Makefile.win
index e2b18741657e..da1d9fc8328a 100644
--- a/Makefile.win
+++ b/Makefile.win
@@ -171,7 +171,6 @@ install_docs: docs ## Install docs at prefix
$(call MKDIR,"$(DATADIR)")
$(call INSTALLDIR,docs,"$(DATADIR)\docs")
$(call INSTALLDIR,samples,"$(DATADIR)\examples")
- $(call RM,"$(DATADIR)\examples\.gitignore")
.PHONY: uninstall_docs
uninstall_docs: ## Uninstall docs from prefix
diff --git a/README.md b/README.md
index 67bf031ed038..19d8e09ee853 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@
---
-[![Crystal - Born and raised at Manas](https://cloud.githubusercontent.com/assets/209371/13291809/022e2360-daf8-11e5-8be7-d02c1c8b38fb.png)](https://manas.tech/)
+[![Crystal - Born and raised at Manas](doc/assets/crystal-born-and-raised.svg)](https://manas.tech/)
Crystal is a programming language with the following goals:
@@ -40,7 +40,7 @@ Project Status
Within a major version, language features won't be removed or changed in any way that could prevent a Crystal program written with that version from compiling and working. The built-in standard library might be enriched, but it will always be done with backwards compatibility in mind.
-Development of the Crystal language is possible thanks to the community's effort and the continued support of [84codes](https://www.84codes.com/), [Nikola Motor Company](https://nikolamotor.com/) and every other [sponsor](https://crystal-lang.org/sponsors).
+Development of the Crystal language is possible thanks to the community's effort and the continued support of [84codes](https://www.84codes.com/) and every other [sponsor](https://crystal-lang.org/sponsors).
Installing
----------
diff --git a/bin/ci b/bin/ci
index 8e9f7a5ddadf..9d0b73507f24 100755
--- a/bin/ci
+++ b/bin/ci
@@ -135,8 +135,8 @@ format() {
prepare_build() {
on_linux verify_linux_environment
- on_osx curl -L https://github.com/crystal-lang/crystal/releases/download/1.10.1/crystal-1.10.1-1-darwin-universal.tar.gz -o ~/crystal.tar.gz
- on_osx 'pushd ~;gunzip -c ~/crystal.tar.gz | tar xopf -;mv crystal-1.10.1-1 crystal;popd'
+ on_osx curl -L https://github.com/crystal-lang/crystal/releases/download/1.11.2/crystal-1.11.2-1-darwin-universal.tar.gz -o ~/crystal.tar.gz
+ on_osx 'pushd ~;gunzip -c ~/crystal.tar.gz | tar xopf -;mv crystal-1.11.2-1 crystal;popd'
# These commands may take a few minutes to run due to the large size of the repositories.
# This restriction has been made on GitHub's request because updating shallow
@@ -189,7 +189,7 @@ with_build_env() {
on_linux verify_linux_environment
- export DOCKER_TEST_PREFIX="${DOCKER_TEST_PREFIX:=crystallang/crystal:1.10.1}"
+ export DOCKER_TEST_PREFIX="${DOCKER_TEST_PREFIX:=crystallang/crystal:1.11.2}"
case $ARCH in
x86_64)
diff --git a/doc/assets/crystal-born-and-raised.svg b/doc/assets/crystal-born-and-raised.svg
new file mode 100644
index 000000000000..98e85d9b46b2
--- /dev/null
+++ b/doc/assets/crystal-born-and-raised.svg
@@ -0,0 +1,248 @@
+
diff --git a/etc/completion.bash b/etc/completion.bash
index d8731c65bff7..9263289b5b4e 100644
--- a/etc/completion.bash
+++ b/etc/completion.bash
@@ -66,7 +66,7 @@ _crystal()
_crystal_compgen_options "${opts}" "${cur}"
else
if [[ "${prev}" == "tool" ]] ; then
- local subcommands="context dependencies format hierarchy implementations types"
+ local subcommands="context dependencies flags format hierarchy implementations types"
_crystal_compgen_options "${subcommands}" "${cur}"
else
_crystal_compgen_sources "${cur}"
diff --git a/etc/completion.fish b/etc/completion.fish
index 150dd37108d8..64fc6a97b45a 100644
--- a/etc/completion.fish
+++ b/etc/completion.fish
@@ -1,5 +1,5 @@
set -l crystal_commands init build clear_cache docs env eval i interactive play run spec tool help version
-set -l tool_subcommands context expand format hierarchy implementations types
+set -l tool_subcommands context expand flags format hierarchy implementations types
complete -c crystal -s h -l help -d "Show help" -x
@@ -173,6 +173,8 @@ complete -c crystal -n "__fish_seen_subcommand_from expand" -s p -l progress -d
complete -c crystal -n "__fish_seen_subcommand_from expand" -s t -l time -d "Enable execution time output"
complete -c crystal -n "__fish_seen_subcommand_from expand" -l stdin-filename -d "Source file name to be read from STDIN"
+complete -c crystal -n "__fish_seen_subcommand_from tool; and not __fish_seen_subcommand_from $tool_subcommands" -a "flags" -d "print all macro 'flag?' values" -x
+
complete -c crystal -n "__fish_seen_subcommand_from tool; and not __fish_seen_subcommand_from $tool_subcommands" -a "format" -d "format project, directories and/or files" -x
complete -c crystal -n "__fish_seen_subcommand_from format" -l check -d "Checks that formatting code produces no changes"
complete -c crystal -n "__fish_seen_subcommand_from format" -s i -l include -d "Include path"
diff --git a/etc/completion.zsh b/etc/completion.zsh
index bf57d80208df..ffa12798ca18 100644
--- a/etc/completion.zsh
+++ b/etc/completion.zsh
@@ -165,6 +165,7 @@ _crystal-tool() {
"context:show context for given location"
"dependencies:show tree of required source files"
"expand:show macro expansion for given location"
+ "flags:print all macro 'flag?' values"
"format:format project, directories and/or files"
"hierarchy:show type hierarchy"
"implementations:show implementations for given call in location"
@@ -211,6 +212,12 @@ _crystal-tool() {
$cursor_args
;;
+ (flags)
+ _arguments \
+ $programfile \
+ $help_args
+ ;;
+
(format)
_arguments \
$programfile \
diff --git a/etc/win-ci/build-llvm.ps1 b/etc/win-ci/build-llvm.ps1
index b544e9eba784..9335cfe9abe4 100644
--- a/etc/win-ci/build-llvm.ps1
+++ b/etc/win-ci/build-llvm.ps1
@@ -16,7 +16,7 @@ if (-not $Dynamic) {
Setup-Git -Path $BuildTree -Url https://github.com/llvm/llvm-project.git -Ref llvmorg-$Version
Run-InDirectory $BuildTree\build {
- $args = "-Thost=x64 -DLLVM_TARGETS_TO_BUILD=""$($TargetsToBuild -join ';')"" -DCMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH=OFF -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_ENABLE_ZSTD=OFF"
+ $args = "-Thost=x64 -DLLVM_TARGETS_TO_BUILD=$($TargetsToBuild -join ';') -DCMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH=OFF -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_ENABLE_ZSTD=OFF"
if ($Dynamic) {
$args = "-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDLL $args"
} else {
diff --git a/man/crystal.1 b/man/crystal.1
index 5f08ce29d07e..15fed461c26c 100644
--- a/man/crystal.1
+++ b/man/crystal.1
@@ -117,6 +117,8 @@ Generate the output without any symbolic debug symbols.
Define a compile-time flag. This is useful to conditionally define types, methods, or commands based on flags available at compile time. The default flags are from the target triple given with --target-triple or the hosts default, if none is given.
.It Fl -emit Op asm|llvm-bc|llvm-ir|obj
Comma separated list of types of output for the compiler to emit. You can use this to see the generated LLVM IR, LLVM bitcode, assembly, and object files.
+.It Fl -frame-pointers Op auto|always|non-leaf
+Control the preservation of frame pointers. The default value, --frame-pointers=auto, will preserve frame pointers on debug builds and try to omit them on release builds (certain platforms require them to stay enabled). --frame-pointers=always will always preserve them, and non-leaf will only force their preservation on non-leaf functions.
.It Fl f Ar text|json, Fl -format Ar text|json
Format of output. Defaults to text. The json format can be used to get a more parser-friendly output.
.It Fl -error-trace
@@ -130,7 +132,7 @@ Specify a specific CPU to generate code for. This will pass a -mcpu flag to LLVM
Passing --mcpu native will pass the host CPU name to tune performance for the host.
.It Fl -mattr Ar CPU
Override or control specific attributes of the target, such as whether SIMD operations are enabled or not. The default set of attributes is set by the current CPU. This will pass a -mattr flag to LLVM, and is only intended to be used for cross-compilation. For a list of available attributes, invoke "llvm-as < /dev/null | llc -march=xyz -mattr=help".
-.It Fl -mcmodel default|kernel|small|medium|large
+.It Fl -mcmodel Ar default|kernel|small|medium|large
Specifies a specific code model to generate code for. This will pass a --code-model flag to LLVM.
.It Fl -no-color
Disable colored output.
@@ -140,8 +142,14 @@ Don't do code generation, just parse the file.
Specify filename of output.
.It Fl -prelude
Specify prelude to use. The default one initializes the garbage collector. You can also use --prelude=empty to use no preludes. This can be useful for checking code generation for a specific source code file.
+.It Fl O Ar LEVEL
+Optimization mode: 0 (default), 1, 2, 3. See
+.Sy OPTIMIZATIONS
+for details.
.It Fl -release
-Turn on optimizations for the generated code, which are disabled by default.
+Compile in release mode. Equivalent to
+.Fl O3
+.Fl -single-module
.It Fl -error-trace
Show full stack trace. Disabled by default, as the full trace usually makes error messages less readable and not always deliver relevant information.
.It Fl s, -stats
@@ -152,6 +160,9 @@ Print statistics about the progress for the current build.
Print statistics about the execution time.
.It Fl -single-module
Generate a single LLVM module.
+By default, one LLVM module is created for each type in a program.
+.Fl -release
+implies this option.
.It Fl -threads Ar NUM
Maximum number of threads to use for code generation. The default is 8 threads.
.It Fl -target Ar TRIPLE
@@ -265,8 +276,14 @@ Generate the output without any symbolic debug symbols.
Define a compile-time flag. This is useful to conditionally define types, methods, or commands based on flags available at compile time. The default flags are from the target triple given with --target-triple or the hosts default, if none is given.
.It Fl -error-trace
Show full error trace.
+.It Fl O Ar LEVEL
+Optimization mode: 0 (default), 1, 2, 3. See
+.Sy OPTIMIZATIONS
+for details.
.It Fl -release
-Turn on optimizations for the generated code, which are disabled by default.
+Compile in release mode. Equivalent to
+.Fl O3
+.Fl -single-module
.It Fl s, -stats
Print statistics about the different compiler stages for the current build. Output time and used memory for each compiler process.
.It Fl p, -progress
@@ -326,8 +343,14 @@ Generate the output without any symbolic debug symbols.
Define a compile-time flag. This is useful to conditionally define types, methods, or commands based on flags available at compile time. The default flags are from the target triple given with --target-triple or the hosts default, if none is given.
.It Fl -error-trace
Show full error trace.
+.It Fl O Ar LEVEL
+Optimization mode: 0 (default), 1, 2, 3. See
+.Sy OPTIMIZATIONS
+for details.
.It Fl -release
-Turn on optimizations for the generated code, which are disabled by default.
+Compile in release mode. Equivalent to
+.Fl O3
+.Fl -single-module
.It Fl s, -stats
Print statistics about the different compiler stages for the current build. Output time and used memory for each compiler process.
.It Fl p, -progress
@@ -346,7 +369,7 @@ Disable colored output.
.Op --
.Op arguments
.Pp
-Run a tool. The available tools are: context, dependencies, format, hierarchy, implementations, and types.
+Run a tool. The available tools are: context, dependencies, flags, format, hierarchy, implementations, and types.
.Pp
Tools:
.Bl -tag -offset indent
@@ -375,6 +398,8 @@ Show skipped and heads of filtered paths
.El
.It Cm expand
Show macro expansion for given location.
+.It Cm flags
+Print all macro 'flag?' values
.It Cm format
Format project, directories and/or files with the coding style used in the standard library. You can use the
.Fl -check
@@ -386,13 +411,53 @@ flag.
.It Cm implementations
Show implementations for a given call. Use
.Fl -cursor
-to specify the cursor position. The format for the cursor position is file:line:column.
+ to specify the cursor position. The format for the cursor position is file:line:column.
.It Cm types
Show type of main variables of file.
.It Cm unreachable
-Show methods that are never called. The output is a list of lines with columns
-separated by tab. The first column is the location of the def, the second column
-its reference name and the third column is the length in lines.
+Show methods that are never called. The text output is a list of lines with columns
+separated by tab.
+
+.Pp
+Output fields:
+
+.Bl -tag -width "1234567890" -compact
+.Pp
+.It Cm count
+sum of all calls to this method (only with
+.Fl -tallies
+ option; otherwise skipped)
+.It Cm location
+pathname, line and column, all separated by colon
+.It Cm name
+.It Cm lines
+length of the def in lines
+.It Cm annotations
+.El
+
+.Pp
+Options:
+.Bl -tag -width "12345678" -compact
+.Pp
+.It Fl D Ar FLAG, Fl -define= Ar FLAG
+Define a compile-time flag. This is useful to conditionally define types, methods, or commands based on flags available at compile time. The default flags are from the target triple given with --target-triple or the hosts default, if none is given.
+.It Fl f Ar FORMAT, Fl -format= Ar FORMAT
+Output format 'text' (default), 'json', or 'csv'.
+.It Fl -tallies
+Print reachable methods and their call counts as well.
+.It Fl -check
+Exit with error if there is any unreachable code.
+.It Fl i Ar PATH, Fl -include= Ar PATH
+Include path in output.
+.It Fl e Ar PATH, Fl -exclude= Ar PATH
+Exclude path in output (default:
+.Sy lib
+).
+.It Fl -error-trace
+Show full error trace.
+.It Fl -prelude
+Specify prelude to use. The default one initializes the garbage collector. You can also use --prelude=empty to use no preludes. This can be useful for checking code generation for a specific source code file.
+.El
.El
.Pp
.It
@@ -410,7 +475,29 @@ Show help. Option --help or -h can also be added to each command for command-spe
Show version.
.El
.
-.Sh ENVIRONMENT VARIABLES
+.Sh OPTIMIZATIONS
+.Bl -tag -width "12345678" -compact
+.Pp
+The optimization level specifies the codegen effort for producing optimal code.
+It's a trade-off between compilation performance (decreasing per optimization level) and runtime performance (increasing per optimization level).
+.Pp
+Production builds should usually have the highest optimization level.
+Best results are achieved with
+.Fl -release
+ which also implies
+.Fl -single-module
+.Pp
+.It
+.It Fl O0
+No optimization (default)
+.It Fl O1
+Low optimization
+.It Fl O2
+Middle optimization
+.It Fl O3
+High optimization
+.
+.Sh ENVIRONMENT\ VARIABLES
.Bl -tag -width "12345678" -compact
.Pp
.It
diff --git a/samples/.gitignore b/samples/.gitignore
deleted file mode 100644
index 0e03e15f2420..000000000000
--- a/samples/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/.build/
diff --git a/samples/compiler/visitor_example.cr b/samples/compiler/visitor_example.cr
index ec063a832efa..d9be4da91baf 100644
--- a/samples/compiler/visitor_example.cr
+++ b/samples/compiler/visitor_example.cr
@@ -15,6 +15,7 @@ class Counter < Crystal::Visitor
def visit(node : Crystal::NumberLiteral)
@count += 1
+ false
end
def visit(node : Crystal::ASTNode)
diff --git a/scripts/github-changelog.cr b/scripts/github-changelog.cr
index b46adb9c656b..f2d277f258e7 100755
--- a/scripts/github-changelog.cr
+++ b/scripts/github-changelog.cr
@@ -31,6 +31,10 @@ def query_prs(api_token, repository, milestone)
repository(owner: $owner, name: $repository) {
milestones(query: $milestone, first: 1) {
nodes {
+ closedAt
+ description
+ dueOn
+ title
pullRequests(first: 300) {
nodes {
number
@@ -81,6 +85,28 @@ module LabelNameConverter
end
end
+record Milestone,
+ closed_at : Time?,
+ description : String,
+ due_on : Time?,
+ title : String,
+ pull_requests : Array(PullRequest) do
+ include JSON::Serializable
+
+ @[JSON::Field(key: "dueOn")]
+ @due_on : Time?
+
+ @[JSON::Field(key: "closedAt")]
+ @closed_at : Time?
+
+ @[JSON::Field(key: "pullRequests", root: "nodes")]
+ @pull_requests : Array(PullRequest)
+
+ def release_date
+ closed_at || due_on
+ end
+end
+
record PullRequest,
number : Int32,
title : String,
@@ -110,10 +136,13 @@ record PullRequest,
if labels.includes?("breaking-change")
io << "**[breaking]** "
end
+ if experimental?
+ io << "**[experimental]** "
+ end
if deprecated?
io << "**[deprecation]** "
end
- io << title.sub(/^#{type}: /i, "") << " ("
+ io << title.sub(/^\[?(?:#{type}|#{sub_topic})(?::|\]:?) /i, "") << " ("
io << "[#" << number << "](" << permalink << ")"
if author = self.author
io << ", thanks @" << author
@@ -152,9 +181,26 @@ record PullRequest,
end
def topic
- labels.find { |label|
- label.starts_with?("topic:") && label != "topic:multithreading"
- }.try(&.lchop("topic:").split(/:|\//))
+ topics.fetch(0) do
+ STDERR.puts "Missing topic for ##{number}"
+ nil
+ end
+ end
+
+ def topics
+ topics = labels.compact_map { |label|
+ label.lchop?("topic:").try(&.split(/:|\//))
+ }
+ topics.reject! &.[0].==("multithreading")
+
+ topics.sort_by! { |parts|
+ topic_priority = case parts[0]
+ when "tools" then 2
+ when "lang" then 1
+ else 0
+ end
+ {-topic_priority, parts[0]}
+ }
end
def deprecated?
@@ -165,6 +211,10 @@ record PullRequest,
labels.includes?("kind:breaking")
end
+ def experimental?
+ labels.includes?("experimental")
+ end
+
def feature?
labels.includes?("kind:feature")
end
@@ -173,6 +223,10 @@ record PullRequest,
labels.includes?("kind:bug")
end
+ def chore?
+ labels.includes?("kind:chore")
+ end
+
def refactor?
labels.includes?("kind:refactor")
end
@@ -196,9 +250,10 @@ record PullRequest,
def type
case
when feature? then "feature"
- when fix? then "fix"
when docs? then "docs"
when specs? then "specs"
+ when fix? then "fix"
+ when chore? then "chore"
when performance? then "performance"
when refactor? then "refactor"
else nil
@@ -216,42 +271,46 @@ end
response = query_prs(api_token, repository, milestone)
parser = JSON::PullParser.new(response.body)
-array = parser.on_key! "data" do
+milestone = parser.on_key! "data" do
parser.on_key! "repository" do
parser.on_key! "milestones" do
parser.on_key! "nodes" do
parser.read_begin_array
- a = parser.on_key! "pullRequests" do
- parser.on_key! "nodes" do
- Array(PullRequest).new(parser)
- end
- end
+ milestone = Milestone.new(parser)
parser.read_end_array
- a
+ milestone
end
end
end
end
-changelog = File.read("CHANGELOG.md")
-array.select! { |pr| pr.merged_at && !changelog.index(pr.permalink) }
-
-sections = array.group_by(&.section)
+sections = milestone.pull_requests.group_by(&.section)
SECTION_TITLES = {
"breaking" => "Breaking changes",
"feature" => "Features",
"fix" => "Bugfixes",
+ "chore" => "Chores",
"performance" => "Performance",
"refactor" => "Refactor",
"docs" => "Documentation",
"specs" => "Specs",
"infra" => "Infrastructure",
- "" => "Chores",
+ "" => "other",
}
TOPIC_ORDER = %w[lang stdlib compiler tools other]
+puts "## [#{milestone.title}] (#{milestone.release_date.try(&.to_s("%F")) || "unreleased"})"
+if description = milestone.description.presence
+ puts
+ print "_", description
+ puts "_"
+end
+puts
+puts "[#{milestone.title}]: https://github.com/crystal-lang/crystal/releases/#{milestone.title}"
+puts
+
SECTION_TITLES.each do |id, title|
prs = sections[id]? || next
puts "### #{title}"
diff --git a/shell.nix b/shell.nix
index ab90080aca13..aef4211f280a 100644
--- a/shell.nix
+++ b/shell.nix
@@ -52,18 +52,18 @@ let
# Hashes obtained using `nix-prefetch-url --unpack `
latestCrystalBinary = genericBinary ({
x86_64-darwin = {
- url = "https://github.com/crystal-lang/crystal/releases/download/1.10.1/crystal-1.10.1-1-darwin-universal.tar.gz";
- sha256 = "sha256:08k8sixhnk9ld99nyrya11rkpp34zamsg3lk9h50ppbmzfixjyyc";
+ url = "https://github.com/crystal-lang/crystal/releases/download/1.11.2/crystal-1.11.2-1-darwin-universal.tar.gz";
+ sha256 = "sha256:0qcdr8yl6k7il0x63z2gyqbkjp89m77nq7x1h3m80y1imfg0z1q9";
};
aarch64-darwin = {
- url = "https://github.com/crystal-lang/crystal/releases/download/1.10.1/crystal-1.10.1-1-darwin-universal.tar.gz";
- sha256 = "sha256:08k8sixhnk9ld99nyrya11rkpp34zamsg3lk9h50ppbmzfixjyyc";
+ url = "https://github.com/crystal-lang/crystal/releases/download/1.11.2/crystal-1.11.2-1-darwin-universal.tar.gz";
+ sha256 = "sha256:0qcdr8yl6k7il0x63z2gyqbkjp89m77nq7x1h3m80y1imfg0z1q9";
};
x86_64-linux = {
- url = "https://github.com/crystal-lang/crystal/releases/download/1.10.1/crystal-1.10.1-1-linux-x86_64.tar.gz";
- sha256 = "sha256:02hzslzgv0xxsal3fkbcdrnrrnzf9lraamy36p36sjf8n14v45a2";
+ url = "https://github.com/crystal-lang/crystal/releases/download/1.11.2/crystal-1.11.2-1-linux-x86_64.tar.gz";
+ sha256 = "sha256:01l9cq8d3p7p3ijkrg0xpchj0l21z3sjvd5f6zw1pnms647a6hdr";
};
}.${pkgs.stdenv.system});
diff --git a/spec/compiler/codegen/asm_spec.cr b/spec/compiler/codegen/asm_spec.cr
index 2c6b0707699e..05eb3b895032 100644
--- a/spec/compiler/codegen/asm_spec.cr
+++ b/spec/compiler/codegen/asm_spec.cr
@@ -3,6 +3,14 @@ require "../../spec_helper"
describe "Code gen: asm" do
# TODO: arm asm tests
{% if flag?(:i386) || flag?(:x86_64) %}
+ it "passes correct string length to LLVM" do
+ run <<-CRYSTAL
+ asm("// 😂😂
+ nop
+ nop")
+ CRYSTAL
+ end
+
it "codegens without inputs" do
run(%(
dst = uninitialized Int32
@@ -44,5 +52,13 @@ describe "Code gen: asm" do
c
)).to_i.should eq(42)
end
+
+ it "codegens with intel dialect" do
+ run(<<-CRYSTAL).to_i.should eq(1234)
+ dst = uninitialized Int32
+ asm("mov dword ptr [$0], 1234" :: "r"(pointerof(dst)) :: "intel")
+ dst
+ CRYSTAL
+ end
{% end %}
end
diff --git a/spec/compiler/codegen/cast_spec.cr b/spec/compiler/codegen/cast_spec.cr
index 32b265ea0415..dd6653f036c9 100644
--- a/spec/compiler/codegen/cast_spec.cr
+++ b/spec/compiler/codegen/cast_spec.cr
@@ -77,6 +77,68 @@ describe "Code gen: cast" do
)).to_b.should be_true
end
+ it "upcasts from union to union with different alignment" do
+ run(<<-CRYSTAL).to_i.should eq(1)
+ require "prelude"
+
+ a = 1 || 2_i64
+ a.as(Int32 | Int64 | Int128)
+ CRYSTAL
+ end
+
+ it "downcasts from union to union with different alignment" do
+ run(<<-CRYSTAL).to_i.should eq(1)
+ require "prelude"
+
+ a = 1 || 2_i64 || 3_i128
+ a.as(Int32 | Int64)
+ CRYSTAL
+ end
+
+ it "sidecasts from union to union with different alignment" do
+ run(<<-CRYSTAL).to_i.should eq(1)
+ require "prelude"
+
+ a = 1 || 2_i64
+ a.as(Int32 | Int128)
+ CRYSTAL
+ end
+
+ it "doesn't corrupt stack when downcasting union to union with different alignment (#14285)" do
+ run(<<-CRYSTAL).to_b.should be_true
+ struct Time2
+ def initialize(@seconds : Int64)
+ @nanoseconds = uninitialized UInt32[3]
+ end
+
+ def <(other : Time2) : Bool
+ @seconds < other.@seconds
+ end
+ end
+
+ class Constraints::Range
+ def initialize(@min : Int128 | Time2 | Nil)
+ end
+ end
+
+ def validate(value : Time2, constraint) : Bool
+ min = constraint.@min
+ if min.is_a?(Time2?)
+ if min
+ if value < min
+ return false
+ end
+ end
+ end
+ true
+ end
+
+ value = Time2.new(123)
+ constraint = Constraints::Range.new(Time2.new(45))
+ validate(value, constraint)
+ CRYSTAL
+ end
+
it "casts from virtual to single type" do
run(%(
require "prelude"
diff --git a/spec/compiler/codegen/is_a_spec.cr b/spec/compiler/codegen/is_a_spec.cr
index 97d72378be42..86ed570afe20 100644
--- a/spec/compiler/codegen/is_a_spec.cr
+++ b/spec/compiler/codegen/is_a_spec.cr
@@ -45,6 +45,16 @@ describe "Codegen: is_a?" do
run("1.is_a?(Object)").to_b.should be_true
end
+ it "doesn't error if result is discarded (#14113)" do
+ run(<<-CRYSTAL).to_i.should eq(1)
+ class Foo
+ end
+
+ (Foo.new || "").is_a?(Foo)
+ 1
+ CRYSTAL
+ end
+
it "evaluate method on filtered type" do
run("a = 1; a = 'a'; if a.is_a?(Char); a.ord; else; 0; end").to_i.chr.should eq('a')
end
diff --git a/spec/compiler/codegen/responds_to_spec.cr b/spec/compiler/codegen/responds_to_spec.cr
index e10f024f3682..0384c3e0d838 100644
--- a/spec/compiler/codegen/responds_to_spec.cr
+++ b/spec/compiler/codegen/responds_to_spec.cr
@@ -51,6 +51,18 @@ describe "Codegen: responds_to?" do
)).to_b.should be_false
end
+ it "doesn't error if result is discarded (#14113)" do
+ run(<<-CRYSTAL).to_i.should eq(1)
+ class Foo
+ def foo
+ end
+ end
+
+ (Foo.new || "").responds_to?(:foo)
+ 1
+ CRYSTAL
+ end
+
it "works with virtual type" do
run(%(
class Foo
diff --git a/spec/compiler/codegen/sizeof_spec.cr b/spec/compiler/codegen/sizeof_spec.cr
index 8139db8bc426..e90553d0b3c1 100644
--- a/spec/compiler/codegen/sizeof_spec.cr
+++ b/spec/compiler/codegen/sizeof_spec.cr
@@ -279,6 +279,16 @@ describe "Code gen: sizeof" do
alignof(Foo)
CRYSTAL
end
+
+ it "gets alignof union" do
+ run("alignof(Int32 | Int8)").to_i.should eq(8)
+ run("alignof(Int32 | Int64)").to_i.should eq(8)
+ end
+
+ it "alignof mixed union is not less than alignof its variant types" do
+ # NOTE: `alignof(Int128) == 16` is not guaranteed
+ run("alignof(Int32 | Int128) >= alignof(Int128)").to_b.should be_true
+ end
end
describe "instance_alignof" do
diff --git a/spec/compiler/crystal/tools/flags_spec.cr b/spec/compiler/crystal/tools/flags_spec.cr
new file mode 100644
index 000000000000..c295439e0547
--- /dev/null
+++ b/spec/compiler/crystal/tools/flags_spec.cr
@@ -0,0 +1,44 @@
+require "../../../spec_helper"
+include Crystal
+
+private def parse_flags(source)
+ Crystal::Command::FlagsVisitor.new.tap do |visitor|
+ Parser.parse(source).accept(visitor)
+ end
+end
+
+describe Crystal::Command::FlagsVisitor do
+ it "different flags" do
+ visitor = parse_flags <<-CRYSTAL
+ {%
+ flag?(:foo)
+ flag?("bar")
+ flag?(1)
+ flag?(true)
+ %}
+ CRYSTAL
+ visitor.flag_names.should eq %w[1 bar foo true]
+ end
+
+ it "unique flags" do
+ visitor = parse_flags <<-CRYSTAL
+ {%
+ flag?(:foo)
+ flag?("foo")
+ flag?(:foo)
+ %}
+ CRYSTAL
+ visitor.flag_names.should eq %w[foo]
+ end
+
+ it "only macro" do
+ visitor = parse_flags <<-CRYSTAL
+ flag?(:flag)
+ f.flag?(:foo)
+ F.flag?(:bar)
+ {% f.flag?(:baz) %}
+ {% f.flag?(:qux, other: true) %}
+ CRYSTAL
+ visitor.flag_names.should eq %w[]
+ end
+end
diff --git a/spec/compiler/crystal/tools/repl_spec.cr b/spec/compiler/crystal/tools/repl_spec.cr
new file mode 100644
index 000000000000..3a1e1275ef12
--- /dev/null
+++ b/spec/compiler/crystal/tools/repl_spec.cr
@@ -0,0 +1,20 @@
+{% skip_file if flag?(:without_interpreter) %}
+
+require "../../../spec_helper"
+
+private def success_value(result : Crystal::Repl::EvalResult) : Crystal::Repl::Value
+ result.warnings.infos.should be_empty
+ result.value.should_not be_nil
+end
+
+describe Crystal::Repl do
+ it "can parse and evaluate snippets" do
+ repl = Crystal::Repl.new
+ repl.prelude = "primitives"
+ repl.load_prelude
+
+ success_value(repl.parse_and_interpret("1 + 2")).value.should eq(3)
+ success_value(repl.parse_and_interpret("def foo; 1 + 2; end")).value.should eq(nil)
+ success_value(repl.parse_and_interpret("foo")).value.should eq(3)
+ end
+end
diff --git a/spec/compiler/crystal/tools/unreachable_spec.cr b/spec/compiler/crystal/tools/unreachable_spec.cr
index 6fffb17e4ca6..12ed82499740 100644
--- a/spec/compiler/crystal/tools/unreachable_spec.cr
+++ b/spec/compiler/crystal/tools/unreachable_spec.cr
@@ -15,28 +15,37 @@ def processed_unreachable_visitor(code)
end
private def assert_unreachable(code, file = __FILE__, line = __LINE__)
- expected_locations = [] of Location
+ expected = Hash(String, Int32).new
code.lines.each_with_index do |line, line_number_0|
- if column_number = line.index('༓')
- expected_locations << Location.new(".", line_number_0 + 1, column_number + 1)
+ if match = line.match(/༓(?:\[(\d+)\])?/)
+ location = Location.new(".", line_number_0 + 1, match.begin + 1)
+ expected[location.to_s] = (match[1]? || 0).to_i
end
end
- code = code.gsub('༓', "")
+ code = code.gsub(/༓(?:\[(\d+)\])?/, "")
- defs = processed_unreachable_visitor(code)
+ tallies = processed_unreachable_visitor(code)
- result_location = defs.try &.compact_map(&.location).sort_by! do |loc|
+ processed_results = [] of {Location, Int32}
+ tallies.each do |k, v|
+ location = k.location.not_nil!
+ next unless v.zero? || expected.has_key?(location.to_s)
+ processed_results << {location, v}
+ end
+
+ processed_results = processed_results.sort_by! do |loc, v|
{loc.filename.as(String), loc.line_number, loc.column_number}
- end.map(&.to_s)
+ end.map { |k, v| {k.to_s, v} }
- result_location.should eq(expected_locations.map(&.to_s)), file: file, line: line
+ processed_results.should eq(expected.to_a), file: file, line: line
end
# References
#
# ༓ marks the expected unreachable code to be found
+# ༓[n] marks the expected code to be called n times
#
describe "unreachable" do
it "finds top level methods" do
@@ -424,4 +433,23 @@ describe "unreachable" do
{% end %}
CRYSTAL
end
+
+ it "tallies calls" do
+ assert_unreachable <<-CRYSTAL
+ ༓def foo
+ 1
+ end
+
+ ༓[2]def bar
+ 2
+ end
+
+ ༓[1]def baz
+ bar
+ end
+
+ bar
+ baz
+ CRYSTAL
+ end
end
diff --git a/spec/compiler/ffi/ffi_spec.cr b/spec/compiler/ffi/ffi_spec.cr
index ac16cfc425f2..ec644e45870d 100644
--- a/spec/compiler/ffi/ffi_spec.cr
+++ b/spec/compiler/ffi/ffi_spec.cr
@@ -19,6 +19,22 @@ private record TestStruct,
d : Float64,
p : Pointer(Void)
+private def dll_search_paths
+ {% if flag?(:msvc) %}
+ [SPEC_CRYSTAL_LOADER_LIB_PATH]
+ {% else %}
+ nil
+ {% end %}
+end
+
+{% if flag?(:unix) %}
+ class Crystal::Loader
+ def self.new(search_paths : Array(String), *, dll_search_paths : Nil)
+ new(search_paths)
+ end
+ end
+{% end %}
+
describe Crystal::FFI::CallInterface do
before_all do
FileUtils.mkdir_p(SPEC_CRYSTAL_LOADER_LIB_PATH)
@@ -33,7 +49,7 @@ describe Crystal::FFI::CallInterface do
it "simple call" do
call_interface = Crystal::FFI::CallInterface.new Crystal::FFI::Type.sint64, [] of Crystal::FFI::Type
- loader = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH])
+ loader = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH], dll_search_paths: dll_search_paths)
loader.load_library "sum"
function_pointer = loader.find_symbol("answer")
return_value = 0_i64
@@ -48,7 +64,7 @@ describe Crystal::FFI::CallInterface do
Crystal::FFI::Type.sint32, Crystal::FFI::Type.sint32, Crystal::FFI::Type.sint32,
] of Crystal::FFI::Type
- loader = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH])
+ loader = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH], dll_search_paths: dll_search_paths)
loader.load_library "sum"
function_pointer = loader.find_symbol("sum")
@@ -71,7 +87,7 @@ describe Crystal::FFI::CallInterface do
Crystal::FFI::Type.pointer,
] of Crystal::FFI::Type
- loader = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH])
+ loader = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH], dll_search_paths: dll_search_paths)
loader.load_library "sum"
function_pointer = loader.find_symbol("sum_primitive_types")
@@ -109,7 +125,7 @@ describe Crystal::FFI::CallInterface do
]
call_interface = Crystal::FFI::CallInterface.new Crystal::FFI::Type.struct(struct_fields), struct_fields
- loader = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH])
+ loader = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH], dll_search_paths: dll_search_paths)
loader.load_library "sum"
function_pointer = loader.find_symbol("make_struct")
@@ -145,7 +161,7 @@ describe Crystal::FFI::CallInterface do
]),
] of Crystal::FFI::Type
- loader = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH])
+ loader = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH], dll_search_paths: dll_search_paths)
loader.load_library "sum"
function_pointer = loader.find_symbol("sum_struct")
@@ -183,7 +199,7 @@ describe Crystal::FFI::CallInterface do
]),
] of Crystal::FFI::Type
- loader = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH])
+ loader = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH], dll_search_paths: dll_search_paths)
loader.load_library "sum"
function_pointer = loader.find_symbol("sum_array")
@@ -208,7 +224,7 @@ describe Crystal::FFI::CallInterface do
it "basic" do
call_interface = Crystal::FFI::CallInterface.variadic Crystal::FFI::Type.sint64, [Crystal::FFI::Type.sint32, Crystal::FFI::Type.sint32, Crystal::FFI::Type.sint32, Crystal::FFI::Type.sint32] of Crystal::FFI::Type, 1
- loader = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH])
+ loader = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH], dll_search_paths: dll_search_paths)
loader.load_library "sum"
function_pointer = loader.find_symbol("sum_variadic")
@@ -224,7 +240,7 @@ describe Crystal::FFI::CallInterface do
it "zero varargs" do
call_interface = Crystal::FFI::CallInterface.variadic Crystal::FFI::Type.sint64, [Crystal::FFI::Type.sint32] of Crystal::FFI::Type, 1
- loader = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH])
+ loader = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH], dll_search_paths: dll_search_paths)
loader.load_library "sum"
function_pointer = loader.find_symbol("sum_variadic")
diff --git a/spec/compiler/formatter/formatter_spec.cr b/spec/compiler/formatter/formatter_spec.cr
index 4567638f0fd8..bd992b78fa4a 100644
--- a/spec/compiler/formatter/formatter_spec.cr
+++ b/spec/compiler/formatter/formatter_spec.cr
@@ -1629,6 +1629,14 @@ describe Crystal::Formatter do
assert_format "->( x : Int32 , y ) { x }", "->(x : Int32, y) { x }"
assert_format "->{}"
+ # #13232
+ assert_format "->{}", "-> { }", flags: %w[proc_literal_whitespace]
+ assert_format "->(){}", "-> { }", flags: %w[proc_literal_whitespace]
+ assert_format "->{1}", "-> { 1 }", flags: %w[proc_literal_whitespace]
+ assert_format "->(x : Int32) {}", "->(x : Int32) { }", flags: %w[proc_literal_whitespace]
+ assert_format "-> : Int32 {}", "-> : Int32 { }", flags: %w[proc_literal_whitespace]
+ assert_format "->do\nend", "-> do\nend", flags: %w[proc_literal_whitespace]
+
assert_format "-> : Int32 {}"
assert_format "-> : Int32 | String { 1 }"
assert_format "-> : Array(Int32) {}"
@@ -1687,6 +1695,44 @@ describe Crystal::Formatter do
assert_format %(asm("a" : "b"(c) : "d"(e)\n : "f",\n "g"))
assert_format %(asm("a" ::: "a"\n : "volatile",\n "intel"))
+ assert_format <<-CRYSTAL, <<-CRYSTAL
+ asm(
+ # foo
+ "nop"
+ # bar
+ )
+ CRYSTAL
+ asm(
+ # foo
+ "nop"
+ # bar
+ )
+ CRYSTAL
+
+ assert_format <<-CRYSTAL, <<-CRYSTAL
+ asm(
+ # the assembly template string, following the
+ # syntax for LLVM's integrated assembler
+ "nop" : # output operands
+ "=r"(foo), "=r"(bar) : # input operands
+ "r"(1), "r"(baz) : # names of clobbered registers
+ "eax", "memory" : # optional flags, corresponding to the LLVM IR
+ # sideeffect / alignstack / inteldialect / unwind attributes
+ "volatile", "alignstack", "intel", "unwind"
+ )
+ CRYSTAL
+ asm(
+ # the assembly template string, following the
+ # syntax for LLVM's integrated assembler
+ "nop" : # output operands
+ "=r"(foo), "=r"(bar) : # input operands
+ "r"(1), "r"(baz) : # names of clobbered registers
+ "eax", "memory" : # optional flags, corresponding to the LLVM IR
+ # sideeffect / alignstack / inteldialect / unwind attributes
+ "volatile", "alignstack", "intel", "unwind"
+ )
+ CRYSTAL
+
assert_format "1 # foo\n1234 # bar", "1 # foo\n1234 # bar"
assert_format "1234 # foo\n1 # bar", "1234 # foo\n1 # bar"
assert_format "1#foo", "1 # foo"
@@ -1953,6 +1999,13 @@ describe Crystal::Formatter do
assert_format "foo.[] = 1"
assert_format "foo.[1, 2] = 3"
+ %w(<= == >= != []= ===).each do |operator|
+ assert_format "1.#{operator} { 3 }"
+ assert_format "1.#{operator}() { 3 }"
+ assert_format "1.#{operator}(2) { 3 }"
+ assert_format "1.#{operator} do\nend"
+ end
+
assert_format "@foo : Int32 # comment\n\ndef foo\nend"
assert_format "getter foo # comment\n\ndef foo\nend"
assert_format "getter foo : Int32 # comment\n\ndef foo\nend"
diff --git a/spec/compiler/interpreter/lib_spec.cr b/spec/compiler/interpreter/lib_spec.cr
index 98e1da7fd294..2c1798645645 100644
--- a/spec/compiler/interpreter/lib_spec.cr
+++ b/spec/compiler/interpreter/lib_spec.cr
@@ -2,6 +2,22 @@
require "./spec_helper"
require "../loader/spec_helper"
+private def ldflags
+ {% if flag?(:win32) %}
+ "/LIBPATH:#{SPEC_CRYSTAL_LOADER_LIB_PATH} sum.lib"
+ {% else %}
+ "-L#{SPEC_CRYSTAL_LOADER_LIB_PATH} -lsum"
+ {% end %}
+end
+
+private def ldflags_with_backtick
+ {% if flag?(:win32) %}
+ "/LIBPATH:#{SPEC_CRYSTAL_LOADER_LIB_PATH} `powershell.exe -C Write-Host -NoNewline sum.lib`"
+ {% else %}
+ "-L#{SPEC_CRYSTAL_LOADER_LIB_PATH} -l`echo sum`"
+ {% end %}
+end
+
describe Crystal::Repl::Interpreter do
context "variadic calls" do
before_all do
@@ -11,7 +27,7 @@ describe Crystal::Repl::Interpreter do
it "promotes float" do
interpret(<<-CRYSTAL).should eq 3.5
- @[Link(ldflags: "-L#{SPEC_CRYSTAL_LOADER_LIB_PATH} -lsum")]
+ @[Link(ldflags: #{ldflags.inspect})]
lib LibSum
fun sum_float(count : Int32, ...) : Float32
end
@@ -22,7 +38,7 @@ describe Crystal::Repl::Interpreter do
it "promotes int" do
interpret(<<-CRYSTAL).should eq 5
- @[Link(ldflags: "-L#{SPEC_CRYSTAL_LOADER_LIB_PATH} -lsum")]
+ @[Link(ldflags: #{ldflags.inspect})]
lib LibSum
fun sum_int(count : Int32, ...) : Int32
end
@@ -33,7 +49,7 @@ describe Crystal::Repl::Interpreter do
it "promotes enum" do
interpret(<<-CRYSTAL).should eq 5
- @[Link(ldflags: "-L#{SPEC_CRYSTAL_LOADER_LIB_PATH} -lsum")]
+ @[Link(ldflags: #{ldflags.inspect})]
lib LibSum
fun sum_int(count : Int32, ...) : Int32
end
@@ -63,7 +79,7 @@ describe Crystal::Repl::Interpreter do
it "expands ldflags" do
interpret(<<-CRYSTAL).should eq 4
- @[Link(ldflags: "-L#{SPEC_CRYSTAL_LOADER_LIB_PATH} -l`echo sum`")]
+ @[Link(ldflags: #{ldflags_with_backtick.inspect})]
lib LibSum
fun simple_sum_int(a : Int32, b : Int32) : Int32
end
diff --git a/spec/compiler/interpreter/spec_helper.cr b/spec/compiler/interpreter/spec_helper.cr
index c3b0dcaca8cd..3c6f88ab1679 100644
--- a/spec/compiler/interpreter/spec_helper.cr
+++ b/spec/compiler/interpreter/spec_helper.cr
@@ -5,6 +5,7 @@ require "compiler/crystal/interpreter/*"
def interpret(code, *, prelude = "primitives", file = __FILE__, line = __LINE__)
if prelude == "primitives"
context, value = interpret_with_context(code)
+ context.loader?.try &.close_all
value.value
else
interpret_in_separate_process(code, prelude, file: file, line: line)
@@ -23,18 +24,20 @@ end
# In a nutshell, `interpret_in_separate_process` below calls this same process with an extra option that causes
# the interpretation of the code from stdin, reading the output from stdout. That string is used as the result of
# the program being tested.
-def Spec.option_parser
- option_parser = previous_def
- option_parser.on("", "--interpret-code PRELUDE", "Execute interpreted code") do |prelude|
- code = STDIN.gets_to_end
-
- repl = Crystal::Repl.new
- repl.prelude = prelude
-
- print repl.run_code(code)
- exit
+class Spec::CLI
+ def option_parser
+ option_parser = previous_def
+ option_parser.on("", "--interpret-code PRELUDE", "Execute interpreted code") do |prelude|
+ code = STDIN.gets_to_end
+
+ repl = Crystal::Repl.new
+ repl.prelude = prelude
+
+ print repl.run_code(code)
+ exit
+ end
+ option_parser
end
- option_parser
end
def interpret_in_separate_process(code, prelude, file = __FILE__, line = __LINE__)
diff --git a/spec/compiler/loader/msvc_spec.cr b/spec/compiler/loader/msvc_spec.cr
index fedb21c352c4..e62ba0bd620c 100644
--- a/spec/compiler/loader/msvc_spec.cr
+++ b/spec/compiler/loader/msvc_spec.cr
@@ -45,7 +45,7 @@ describe Crystal::Loader do
describe "#load_file?" do
it "finds function symbol" do
- loader = Crystal::Loader.new([] of String)
+ loader = Crystal::Loader.new([] of String, dll_search_paths: [SPEC_CRYSTAL_LOADER_LIB_PATH])
loader.load_file?(File.join(SPEC_CRYSTAL_LOADER_LIB_PATH, Crystal::Loader.library_filename("foo"))).should be_true
loader.find_symbol?("foo").should_not be_nil
ensure
@@ -55,7 +55,7 @@ describe Crystal::Loader do
describe "#load_library?" do
it "library name" do
- loader = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH] of String)
+ loader = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH], dll_search_paths: [SPEC_CRYSTAL_LOADER_LIB_PATH])
loader.load_library?("foo").should be_true
loader.find_symbol?("foo").should_not be_nil
ensure
@@ -63,7 +63,7 @@ describe Crystal::Loader do
end
it "full path" do
- loader = Crystal::Loader.new([] of String)
+ loader = Crystal::Loader.new([] of String, dll_search_paths: [SPEC_CRYSTAL_LOADER_LIB_PATH])
loader.load_library?(File.join(SPEC_CRYSTAL_LOADER_LIB_PATH, Crystal::Loader.library_filename("foo"))).should be_true
loader.find_symbol?("foo").should_not be_nil
ensure
@@ -72,7 +72,7 @@ describe Crystal::Loader do
it "does not implicitly find dependencies" do
build_c_dynlib(compiler_datapath("loader", "bar.c"))
- loader = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH] of String)
+ loader = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH], dll_search_paths: [SPEC_CRYSTAL_LOADER_LIB_PATH])
loader.load_library?("bar").should be_true
loader.find_symbol?("bar").should_not be_nil
loader.find_symbol?("foo").should be_nil
@@ -83,23 +83,23 @@ describe Crystal::Loader do
it "lookup in order" do
build_c_dynlib(compiler_datapath("loader", "foo2.c"))
- help_loader1 = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH] of String)
+ help_loader1 = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH], dll_search_paths: [SPEC_CRYSTAL_LOADER_LIB_PATH])
help_loader1.load_library?("foo").should be_true
foo_address = help_loader1.find_symbol?("foo").should_not be_nil
- help_loader2 = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH] of String)
+ help_loader2 = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH], dll_search_paths: [SPEC_CRYSTAL_LOADER_LIB_PATH])
help_loader2.load_library?("foo2").should be_true
foo2_address = help_loader2.find_symbol?("foo").should_not be_nil
foo_address.should_not eq foo2_address
- loader1 = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH] of String)
+ loader1 = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH], dll_search_paths: [SPEC_CRYSTAL_LOADER_LIB_PATH])
loader1.load_library("foo")
loader1.load_library("foo2")
loader1.find_symbol?("foo").should eq foo_address
- loader2 = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH] of String)
+ loader2 = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH], dll_search_paths: [SPEC_CRYSTAL_LOADER_LIB_PATH])
loader2.load_library("foo2")
loader2.load_library("foo")
@@ -114,15 +114,82 @@ describe Crystal::Loader do
end
it "does not find global symbols" do
- loader = Crystal::Loader.new([] of String)
+ loader = Crystal::Loader.new([] of String, dll_search_paths: [SPEC_CRYSTAL_LOADER_LIB_PATH])
loader.find_symbol?("__crystal_main").should be_nil
end
it "validate that lib handles are properly closed" do
- loader = Crystal::Loader.new([] of String)
+ loader = Crystal::Loader.new([] of String, dll_search_paths: [SPEC_CRYSTAL_LOADER_LIB_PATH])
expect_raises(Crystal::Loader::LoadError, "undefined reference to `foo'") do
loader.find_symbol("foo")
end
end
end
+
+ describe "dll_search_paths" do
+ it "supports an arbitrary path different from lib search path" do
+ with_tempfile("loader-dll_search_paths") do |path|
+ FileUtils.mkdir_p(SPEC_CRYSTAL_LOADER_LIB_PATH)
+ FileUtils.mkdir_p(path)
+
+ build_c_dynlib(compiler_datapath("loader", "foo.c"))
+ File.rename(File.join(SPEC_CRYSTAL_LOADER_LIB_PATH, "foo.dll"), File.join(path, "foo.dll"))
+
+ loader = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH] of String, dll_search_paths: [path])
+ loader.load_library?("foo").should be_true
+ ensure
+ loader.try &.close_all
+
+ FileUtils.rm_rf(path)
+ FileUtils.rm_rf(SPEC_CRYSTAL_LOADER_LIB_PATH)
+ end
+ end
+
+ it "doesn't load DLLs outside dll_search_path or Windows' default search paths" do
+ with_tempfile("loader-dll_search_paths") do |path|
+ FileUtils.mkdir_p(SPEC_CRYSTAL_LOADER_LIB_PATH)
+ FileUtils.mkdir_p(path)
+
+ build_c_dynlib(compiler_datapath("loader", "foo.c"))
+ File.rename(File.join(SPEC_CRYSTAL_LOADER_LIB_PATH, "foo.dll"), File.join(path, "foo.dll"))
+
+ loader1 = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH] of String, dll_search_paths: [SPEC_CRYSTAL_LOADER_LIB_PATH])
+ loader1.load_library?("foo").should be_false
+ loader2 = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH] of String)
+ loader2.load_library?("foo").should be_false
+ ensure
+ loader2.try &.close_all
+ loader1.try &.close_all
+
+ FileUtils.rm_rf(path)
+ FileUtils.rm_rf(SPEC_CRYSTAL_LOADER_LIB_PATH)
+ end
+ end
+ end
+
+ describe "lib suffix" do
+ before_all do
+ FileUtils.mkdir_p(SPEC_CRYSTAL_LOADER_LIB_PATH)
+ end
+
+ after_all do
+ FileUtils.rm_rf(SPEC_CRYSTAL_LOADER_LIB_PATH)
+ end
+
+ it "respects -dynamic" do
+ build_c_dynlib(compiler_datapath("loader", "foo.c"), lib_name: "foo-dynamic")
+ loader = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH], dll_search_paths: [SPEC_CRYSTAL_LOADER_LIB_PATH])
+ loader.load_library?("foo").should be_true
+ ensure
+ loader.close_all if loader
+ end
+
+ it "ignores -static" do
+ build_c_dynlib(compiler_datapath("loader", "foo.c"), lib_name: "bar-static")
+ loader = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH], dll_search_paths: [SPEC_CRYSTAL_LOADER_LIB_PATH])
+ loader.load_library?("bar").should be_false
+ ensure
+ loader.close_all if loader
+ end
+ end
end
diff --git a/spec/compiler/loader/spec_helper.cr b/spec/compiler/loader/spec_helper.cr
index 282af7871f81..0db69dc19752 100644
--- a/spec/compiler/loader/spec_helper.cr
+++ b/spec/compiler/loader/spec_helper.cr
@@ -2,8 +2,8 @@ require "spec"
SPEC_CRYSTAL_LOADER_LIB_PATH = File.join(SPEC_TEMPFILE_PATH, "loader")
-def build_c_dynlib(c_filename, target_dir = SPEC_CRYSTAL_LOADER_LIB_PATH)
- o_filename = File.join(target_dir, Crystal::Loader.library_filename(File.basename(c_filename, ".c")))
+def build_c_dynlib(c_filename, *, lib_name = nil, target_dir = SPEC_CRYSTAL_LOADER_LIB_PATH)
+ o_filename = File.join(target_dir, Crystal::Loader.library_filename(lib_name || File.basename(c_filename, ".c")))
{% if flag?(:msvc) %}
o_basename = o_filename.rchop(".lib")
diff --git a/spec/compiler/macro/macro_methods_spec.cr b/spec/compiler/macro/macro_methods_spec.cr
index 9d6304e81f01..76d5f795903c 100644
--- a/spec/compiler/macro/macro_methods_spec.cr
+++ b/spec/compiler/macro/macro_methods_spec.cr
@@ -1,4 +1,5 @@
require "../../spec_helper"
+require "../../support/env"
private def declare_class_var(container : ClassVarContainer, name, var_type : Type, annotations = nil)
var = MetaTypeVar.new(name)
@@ -2504,6 +2505,13 @@ module Crystal
end
end
+ describe Primitive do
+ it "executes name" do
+ assert_macro %({{x.name}}), %(:abc), {x: Primitive.new("abc")}
+ assert_macro %({{x.name}}), %(:"x.y.z"), {x: Primitive.new("x.y.z")}
+ end
+ end
+
describe "macro methods" do
it "executes name" do
assert_macro %({{x.name}}), "some_macro", {x: Macro.new("some_macro")}
@@ -2610,6 +2618,18 @@ module Crystal
end
end
+ describe Alias do
+ node = Alias.new("Foo".path, Generic.new(Path.new(["Bar", "Baz"], global: true), ["T".path] of ASTNode))
+
+ it "executes name" do
+ assert_macro %({{x.name}}), %(Foo), {x: node}
+ end
+
+ it "executes type" do
+ assert_macro %({{x.type}}), %(::Bar::Baz(T)), {x: node}
+ end
+ end
+
describe "visibility modifier methods" do
node = VisibilityModifier.new(Visibility::Protected, Def.new("some_def"))
@@ -2762,6 +2782,12 @@ module Crystal
end
end
+ describe TypeOf do
+ it "executes args" do
+ assert_macro %({{x.args}}), "[1, 'a', Foo]", {x: TypeOf.new([1.int32, CharLiteral.new('a'), "Foo".path])}
+ end
+ end
+
describe "case methods" do
describe "when" do
case_node = Case.new(1.int32, [When.new([2.int32, 3.int32] of ASTNode, 4.int32)], 5.int32, exhaustive: false)
@@ -3279,16 +3305,207 @@ module Crystal
end
end
+ describe LibDef do
+ lib_def = LibDef.new(Path.new("Foo", "Bar", global: true), FunDef.new("foo"))
+
+ it "executes kind" do
+ assert_macro %({{x.kind}}), %(lib), {x: lib_def}
+ end
+
+ it "executes name" do
+ assert_macro %({{x.name}}), %(::Foo::Bar), {x: lib_def}
+ assert_macro %({{x.name(generic_args: true)}}), %(::Foo::Bar), {x: lib_def}
+ assert_macro %({{x.name(generic_args: false)}}), %(::Foo::Bar), {x: lib_def}
+ assert_macro_error %({{x.name(generic_args: 99)}}), "named argument 'generic_args' to LibDef#name must be a BoolLiteral, not NumberLiteral", {x: lib_def}
+ end
+
+ it "executes body" do
+ assert_macro %({{x.body}}), %(fun foo), {x: lib_def}
+ end
+ end
+
+ describe CStructOrUnionDef do
+ c_struct_def = CStructOrUnionDef.new("Foo", TypeDeclaration.new("x".var, "Int".path))
+ c_union_def = CStructOrUnionDef.new("Bar", Include.new("Foo".path), union: true)
+
+ it "executes kind" do
+ assert_macro %({{x.kind}}), %(struct), {x: c_struct_def}
+ assert_macro %({{x.kind}}), %(union), {x: c_union_def}
+ end
+
+ it "executes name" do
+ assert_macro %({{x.name}}), %(Foo), {x: c_struct_def}
+ assert_macro %({{x.name(generic_args: true)}}), %(Foo), {x: c_struct_def}
+ assert_macro %({{x.name(generic_args: false)}}), %(Foo), {x: c_struct_def}
+ assert_macro_error %({{x.name(generic_args: 99)}}), "named argument 'generic_args' to CStructOrUnionDef#name must be a BoolLiteral, not NumberLiteral", {x: c_struct_def}
+ end
+
+ it "executes body" do
+ assert_macro %({{x.body}}), %(x : Int), {x: c_struct_def}
+ assert_macro %({{x.body}}), %(include Foo), {x: c_union_def}
+ end
+
+ it "executes union?" do
+ assert_macro %({{x.union?}}), %(false), {x: c_struct_def}
+ assert_macro %({{x.union?}}), %(true), {x: c_union_def}
+ end
+ end
+
+ describe FunDef do
+ lib_fun = FunDef.new("foo")
+ top_level_fun = FunDef.new("bar", [Arg.new("x", restriction: "Int32".path), Arg.new("", restriction: "Char".path)], "Void".path, true, 1.int32, "y.z")
+ top_level_fun2 = FunDef.new("baz", body: Nop.new)
+
+ it "executes name" do
+ assert_macro %({{x.name}}), %(foo), {x: lib_fun}
+ assert_macro %({{x.name}}), %(bar), {x: top_level_fun}
+ end
+
+ it "executes real_name" do
+ assert_macro %({{x.real_name}}), %(), {x: lib_fun}
+ assert_macro %({{x.real_name}}), %("y.z"), {x: top_level_fun}
+ end
+
+ it "executes args" do
+ assert_macro %({{x.args}}), %([]), {x: lib_fun}
+ assert_macro %({{x.args}}), %([x : Int32, : Char]), {x: top_level_fun}
+ end
+
+ it "executes variadic?" do
+ assert_macro %({{x.variadic?}}), %(false), {x: lib_fun}
+ assert_macro %({{x.variadic?}}), %(true), {x: top_level_fun}
+ end
+
+ it "executes return_type" do
+ assert_macro %({{x.return_type}}), %(), {x: lib_fun}
+ assert_macro %({{x.return_type}}), %(Void), {x: top_level_fun}
+ end
+
+ it "executes body" do
+ assert_macro %({{x.body}}), %(), {x: lib_fun}
+ assert_macro %({{x.body}}), %(1), {x: top_level_fun}
+ assert_macro %({{x.body}}), %(), {x: top_level_fun2}
+ end
+
+ it "executes has_body?" do
+ assert_macro %({{x.has_body?}}), %(false), {x: lib_fun}
+ assert_macro %({{x.has_body?}}), %(true), {x: top_level_fun}
+ assert_macro %({{x.has_body?}}), %(true), {x: top_level_fun2}
+ end
+ end
+
+ describe TypeDef do
+ type_def = TypeDef.new("Foo", Path.new("Bar", "Baz", global: true))
+
+ it "executes name" do
+ assert_macro %({{x.name}}), %(Foo), {x: type_def}
+ end
+
+ it "executes type" do
+ assert_macro %({{x.type}}), %(::Bar::Baz), {x: type_def}
+ end
+ end
+
+ describe ExternalVar do
+ external_var1 = ExternalVar.new("foo", Path.new("Bar", "Baz"))
+ external_var2 = ExternalVar.new("X", Generic.new(Path.global("Pointer"), ["Char".path] of ASTNode), real_name: "y.z")
+
+ it "executes name" do
+ assert_macro %({{x.name}}), %(foo), {x: external_var1}
+ assert_macro %({{x.name}}), %(X), {x: external_var2}
+ end
+
+ it "executes real_name" do
+ assert_macro %({{x.real_name}}), %(), {x: external_var1}
+ assert_macro %({{x.real_name}}), %("y.z"), {x: external_var2}
+ end
+
+ it "executes type" do
+ assert_macro %({{x.type}}), %(Bar::Baz), {x: external_var1}
+ assert_macro %({{x.type}}), %(::Pointer(Char)), {x: external_var2}
+ end
+ end
+
+ describe Asm do
+ asm1 = Asm.new("nop")
+ asm2 = Asm.new(
+ text: "foo",
+ outputs: [AsmOperand.new("=r", "x".var), AsmOperand.new("=r", "y".var)],
+ inputs: [AsmOperand.new("i", 1.int32), AsmOperand.new("r", 2.int32)],
+ clobbers: %w(rax memory),
+ volatile: true,
+ alignstack: true,
+ intel: true,
+ can_throw: true,
+ )
+
+ it "executes text" do
+ assert_macro %({{x.text}}), %("nop"), {x: asm1}
+ assert_macro %({{x.text}}), %("foo"), {x: asm2}
+ end
+
+ it "executes outputs" do
+ assert_macro %({{x.outputs}}), %([] of ::NoReturn), {x: asm1}
+ assert_macro %({{x.outputs}}), %(["=r"(x), "=r"(y)]), {x: asm2}
+ end
+
+ it "executes inputs" do
+ assert_macro %({{x.inputs}}), %([] of ::NoReturn), {x: asm1}
+ assert_macro %({{x.inputs}}), %(["i"(1), "r"(2)]), {x: asm2}
+ end
+
+ it "executes clobbers" do
+ assert_macro %({{x.clobbers}}), %([] of ::NoReturn), {x: asm1}
+ assert_macro %({{x.clobbers}}), %(["rax", "memory"]), {x: asm2}
+ end
+
+ it "executes volatile?" do
+ assert_macro %({{x.volatile?}}), %(false), {x: asm1}
+ assert_macro %({{x.volatile?}}), %(true), {x: asm2}
+ end
+
+ it "executes alignstack?" do
+ assert_macro %({{x.alignstack?}}), %(false), {x: asm1}
+ assert_macro %({{x.alignstack?}}), %(true), {x: asm2}
+ end
+
+ it "executes intel?" do
+ assert_macro %({{x.intel?}}), %(false), {x: asm1}
+ assert_macro %({{x.intel?}}), %(true), {x: asm2}
+ end
+
+ it "executes can_throw?" do
+ assert_macro %({{x.can_throw?}}), %(false), {x: asm1}
+ assert_macro %({{x.can_throw?}}), %(true), {x: asm2}
+ end
+ end
+
+ describe AsmOperand do
+ asm_operand1 = AsmOperand.new("=r", "x".var)
+ asm_operand2 = AsmOperand.new("i", 1.int32)
+
+ it "executes constraint" do
+ assert_macro %({{x.constraint}}), %("=r"), {x: asm_operand1}
+ assert_macro %({{x.constraint}}), %("i"), {x: asm_operand2}
+ end
+
+ it "executes exp" do
+ assert_macro %({{x.exp}}), %(x), {x: asm_operand1}
+ assert_macro %({{x.exp}}), %(1), {x: asm_operand2}
+ end
+ end
+
describe "env" do
it "has key" do
- ENV["FOO"] = "foo"
- assert_macro %({{env("FOO")}}), %("foo")
- ENV.delete "FOO"
+ with_env("FOO": "foo") do
+ assert_macro %({{env("FOO")}}), %("foo")
+ end
end
it "doesn't have key" do
- ENV.delete "FOO"
- assert_macro %({{env("FOO")}}), %(nil)
+ with_env("FOO": nil) do
+ assert_macro %({{env("FOO")}}), %(nil)
+ end
end
end
@@ -3565,7 +3782,7 @@ module Crystal
# there are no macro methods with required named parameters
it "uses correct name for top-level macro methods" do
- assert_macro_error %({{flag?}}), "wrong number of arguments for top-level macro 'flag?' (given 0, expected 1)"
+ assert_macro_error %({{flag?}}), "wrong number of arguments for macro '::flag?' (given 0, expected 1)"
end
end
diff --git a/spec/compiler/normalize/string_interpolation_spec.cr b/spec/compiler/normalize/string_interpolation_spec.cr
index 1347792170b0..f92e6c2a200f 100644
--- a/spec/compiler/normalize/string_interpolation_spec.cr
+++ b/spec/compiler/normalize/string_interpolation_spec.cr
@@ -52,43 +52,4 @@ describe "Normalize: string interpolation" do
string = node.should be_a(StringLiteral)
string.value.should eq("hello world")
end
-
- it "replaces char constant" do
- result = semantic(%(
- def String.interpolation(*args); ""; end
-
- OBJ = 'l'
-
- "hello wor\#{OBJ}d"
- ))
- node = result.node.as(Expressions).last
- string = node.should be_a(StringLiteral)
- string.value.should eq("hello world")
- end
-
- it "replaces number constant" do
- result = semantic(%(
- def String.interpolation(*args); ""; end
-
- OBJ = 9_f32
-
- "nine as a float: \#{OBJ}"
- ))
- node = result.node.as(Expressions).last
- string = node.should be_a(StringLiteral)
- string.value.should eq("nine as a float: 9.0")
- end
-
- it "replaces boolean constant" do
- result = semantic(%(
- def String.interpolation(*args); ""; end
-
- OBJ = false
-
- "boolean false: \#{OBJ}"
- ))
- node = result.node.as(Expressions).last
- string = node.should be_a(StringLiteral)
- string.value.should eq("boolean false: false")
- end
end
diff --git a/spec/compiler/parser/parser_spec.cr b/spec/compiler/parser/parser_spec.cr
index 41fad5cc3a89..ea230d4e36ac 100644
--- a/spec/compiler/parser/parser_spec.cr
+++ b/spec/compiler/parser/parser_spec.cr
@@ -290,9 +290,13 @@ module Crystal
assert_syntax_error "def foo=(*args); end", "setter method 'foo=' cannot have more than one parameter"
assert_syntax_error "def foo=(**kwargs); end", "setter method 'foo=' cannot have more than one parameter"
assert_syntax_error "def foo=(&block); end", "setter method 'foo=' cannot have a block"
- assert_syntax_error "def []=(&block); end", "setter method '[]=' cannot have a block"
- assert_syntax_error "f.[]= do |a| end", "setter method '[]=' cannot be called with a block"
- assert_syntax_error "f.[]= { |bar| }", "setter method '[]=' cannot be called with a block"
+
+ # #10397
+ %w(<= >= == != []= ===).each do |operator|
+ it_parses "def #{operator}(other, file = 1); end", Def.new(operator, ["other".arg, Arg.new("file", 1.int32)])
+ it_parses "def #{operator}(*args, **opts); end", Def.new(operator, ["args".arg], splat_index: 0, double_splat: "opts".arg)
+ it_parses "def #{operator}(*args, **opts, &); end", Def.new(operator, ["args".arg], splat_index: 0, double_splat: "opts".arg, block_arg: Arg.new(""), block_arity: 0)
+ end
# #5895, #6042, #5997
%w(
@@ -624,10 +628,12 @@ module Crystal
it_parses "->Foo.#{op}(Int32)", ProcPointer.new("Foo".path, op, ["Int32".path] of ASTNode)
end
- ["bar", "+", "-", "*", "/", "<", "<=", "==", ">", ">=", "%", "|", "&", "^", "**", "===", "=~", "!~"].each do |name|
+ ["bar", "+", "-", "*", "/", "<", "<=", "==", ">", ">=", "%", "|", "&", "^", "**", "===", "=~", "!=", "[]=", "!~"].each do |name|
it_parses "foo.#{name}", Call.new("foo".call, name)
it_parses "foo.#{name} 1, 2", Call.new("foo".call, name, 1.int32, 2.int32)
it_parses "foo.#{name}(1, 2)", Call.new("foo".call, name, 1.int32, 2.int32)
+ it_parses "foo.#{name}(1, 2) { 3 }", Call.new("foo".call, name, args: [1.int32, 2.int32] of ASTNode, block: Block.new(body: 3.int32))
+ it_parses "foo.#{name} do end", Call.new("foo".call, name, block: Block.new)
end
["+", "-", "*", "/", "//", "%", "|", "&", "^", "**", "<<", ">>", "&+", "&-", "&*"].each do |op|
@@ -2246,6 +2252,7 @@ module Crystal
assert_end_location "class Foo; end"
assert_end_location "struct Foo; end"
assert_end_location "module Foo; end"
+ assert_end_location "alias Foo = Bar"
assert_end_location "->{ }"
assert_end_location "macro foo;end"
assert_end_location "macro foo; 123; end"
@@ -2499,6 +2506,24 @@ module Crystal
name_location.column_number.should eq(12)
end
+ it "sets location of top-level fun name" do
+ parser = Parser.new("fun foo; end")
+ node = parser.parse.as(FunDef)
+
+ name_location = node.name_location.should_not be_nil
+ name_location.line_number.should eq(1)
+ name_location.column_number.should eq(5)
+ end
+
+ it "sets location of lib fun name" do
+ parser = Parser.new("lib Foo; fun foo; end")
+ node = parser.parse.as(LibDef).body.as(FunDef)
+
+ name_location = node.name_location.should_not be_nil
+ name_location.line_number.should eq(1)
+ name_location.column_number.should eq(14)
+ end
+
it "sets correct location of proc literal" do
parser = Parser.new("->(\n x : Int32,\n y : String\n) { }")
node = parser.parse.as(ProcLiteral)
diff --git a/spec/compiler/parser/to_s_spec.cr b/spec/compiler/parser/to_s_spec.cr
index 752bece45374..63da166aba45 100644
--- a/spec/compiler/parser/to_s_spec.cr
+++ b/spec/compiler/parser/to_s_spec.cr
@@ -143,10 +143,30 @@ describe "ASTNode#to_s" do
expect_to_s %(@[Foo(1, 2, a: 1, b: 2)])
expect_to_s %(lib Foo\nend)
expect_to_s %(lib LibC\n fun getchar(Int, Float)\nend)
- expect_to_s %(fun foo(a : Void, b : Void, ...) : Void\n\nend)
+ expect_to_s %(fun foo(a : Void, b : Void, ...) : Void\nend)
+ expect_to_s %(fun foo\nend)
expect_to_s %(lib Foo\n struct Foo\n a : Void\n b : Void\n end\nend)
expect_to_s %(lib Foo\n union Foo\n a : Int\n b : Int32\n end\nend)
expect_to_s %(lib Foo\n FOO = 0\nend)
+ expect_to_s <<-CRYSTAL, <<-CRYSTAL
+ lib Foo
+ A = Pointer(Void).new(0)
+ struct B
+ x : Void*
+ y : Int[1]
+ end
+ fun c(Void*) : Char[2]*
+ end
+ CRYSTAL
+ lib Foo
+ A = Pointer(Void).new(0)
+ struct B
+ x : ::Pointer(Void)
+ y : ::StaticArray(Int, 1)
+ end
+ fun c(::Pointer(Void)) : ::Pointer(::StaticArray(Char, 2))
+ end
+ CRYSTAL
expect_to_s %(lib LibC\n fun getch = "get.char"\nend)
expect_to_s %(lib Foo::Bar\nend)
expect_to_s %(enum Foo\n A = 0\n B\nend)
diff --git a/spec/compiler/semantic/doc_spec.cr b/spec/compiler/semantic/doc_spec.cr
index 9b38339b6485..3338f920a938 100644
--- a/spec/compiler/semantic/doc_spec.cr
+++ b/spec/compiler/semantic/doc_spec.cr
@@ -353,6 +353,24 @@ describe "Semantic: doc" do
a.locations.not_nil!.size.should eq(1)
end
+ it "stores location for implicit flag enum members" do
+ result = semantic %(
+ @[Flags]
+ enum Foo
+ A = 1
+ B = 2
+ end
+ ), wants_doc: true
+ program = result.program
+ foo = program.types["Foo"]
+
+ a_loc = foo.types["All"].locations.should_not be_nil
+ a_loc.should_not be_empty
+
+ b_loc = foo.types["None"].locations.should_not be_nil
+ b_loc.should_not be_empty
+ end
+
it "stores doc for constant" do
result = semantic %(
# Hello
diff --git a/spec/compiler/semantic/lib_spec.cr b/spec/compiler/semantic/lib_spec.cr
index 1ee3c7aa99c6..92526402177d 100644
--- a/spec/compiler/semantic/lib_spec.cr
+++ b/spec/compiler/semantic/lib_spec.cr
@@ -345,7 +345,55 @@ describe "Semantic: lib" do
lib LibFoo
end
),
- "unknown link argument: 'boo' (valid arguments are 'lib', 'ldflags', 'static', 'pkg_config', 'framework', and 'wasm_import_module')"
+ "unknown link argument: 'boo' (valid arguments are 'lib', 'ldflags', 'static', 'pkg_config', 'framework', 'wasm_import_module', and 'dll')"
+ end
+
+ it "allows dll argument" do
+ assert_no_errors <<-CRYSTAL
+ @[Link(dll: "foo.dll")]
+ lib LibFoo
+ end
+ CRYSTAL
+
+ assert_no_errors <<-CRYSTAL
+ @[Link(dll: "BAR.DLL")]
+ lib LibFoo
+ end
+ CRYSTAL
+ end
+
+ it "errors if dll argument contains directory separators" do
+ assert_error <<-CRYSTAL, "'dll' link argument must not include directory separators"
+ @[Link(dll: "foo/bar.dll")]
+ lib LibFoo
+ end
+ CRYSTAL
+
+ assert_error <<-CRYSTAL, "'dll' link argument must not include directory separators"
+ @[Link(dll: %q(foo\\bar.dll))]
+ lib LibFoo
+ end
+ CRYSTAL
+ end
+
+ it "errors if dll argument does not end with '.dll'" do
+ assert_error <<-CRYSTAL, "'dll' link argument must use a '.dll' file extension"
+ @[Link(dll: "foo")]
+ lib LibFoo
+ end
+ CRYSTAL
+
+ assert_error <<-CRYSTAL, "'dll' link argument must use a '.dll' file extension"
+ @[Link(dll: "foo.dylib")]
+ lib LibFoo
+ end
+ CRYSTAL
+
+ assert_error <<-CRYSTAL, "'dll' link argument must use a '.dll' file extension"
+ @[Link(dll: "")]
+ lib LibFoo
+ end
+ CRYSTAL
end
it "errors if lib already specified with positional argument" do
diff --git a/spec/compiler/semantic/reference_storage_spec.cr b/spec/compiler/semantic/reference_storage_spec.cr
new file mode 100644
index 000000000000..a0c0f2343260
--- /dev/null
+++ b/spec/compiler/semantic/reference_storage_spec.cr
@@ -0,0 +1,72 @@
+require "../../spec_helper"
+
+describe "Semantic: ReferenceStorage" do
+ it "errors if T is a struct type" do
+ assert_error <<-CRYSTAL, "Can't instantiate ReferenceStorage(T) with T = Foo (T must be a reference type)"
+ @[Primitive(:ReferenceStorageType)]
+ struct ReferenceStorage(T) < Value
+ end
+
+ struct Foo
+ @x = 1
+ end
+
+ ReferenceStorage(Foo)
+ CRYSTAL
+ end
+
+ it "errors if T is a value type" do
+ assert_error <<-CRYSTAL, "Can't instantiate ReferenceStorage(T) with T = Int32 (T must be a reference type)"
+ @[Primitive(:ReferenceStorageType)]
+ struct ReferenceStorage(T) < Value
+ end
+
+ ReferenceStorage(Int32)
+ CRYSTAL
+ end
+
+ it "errors if T is a union type" do
+ assert_error <<-CRYSTAL, "Can't instantiate ReferenceStorage(T) with T = (Bar | Foo) (T must be a reference type)"
+ @[Primitive(:ReferenceStorageType)]
+ struct ReferenceStorage(T) < Value
+ end
+
+ class Foo
+ end
+
+ class Bar
+ end
+
+ ReferenceStorage(Foo | Bar)
+ CRYSTAL
+ end
+
+ it "errors if T is a nilable type" do
+ assert_error <<-CRYSTAL, "Can't instantiate ReferenceStorage(T) with T = (Foo | Nil) (T must be a reference type)"
+ @[Primitive(:ReferenceStorageType)]
+ struct ReferenceStorage(T) < Value
+ end
+
+ class Foo
+ end
+
+ ReferenceStorage(Foo?)
+ CRYSTAL
+ end
+
+ it "allows a different name" do
+ assert_type(<<-CRYSTAL) { types["Foo"].metaclass }
+ @[Primitive(:ReferenceStorageType)]
+ struct MyRef(U) < Value
+ def u
+ U
+ end
+ end
+
+ class Foo
+ end
+
+ MyRef(Foo).new.u
+ CRYSTAL
+ end
+end
diff --git a/spec/compiler/semantic/restrictions_augmenter_spec.cr b/spec/compiler/semantic/restrictions_augmenter_spec.cr
index b3798dc257c0..5095f8613943 100644
--- a/spec/compiler/semantic/restrictions_augmenter_spec.cr
+++ b/spec/compiler/semantic/restrictions_augmenter_spec.cr
@@ -272,7 +272,7 @@ describe "Semantic: restrictions augmenter" do
it "augments typedef" do
before = <<-CRYSTAL
lib LibFoo
- type X = Void*
+ type X = Int32
end
class Foo
@x : LibFoo::X
@@ -284,7 +284,7 @@ describe "Semantic: restrictions augmenter" do
after = <<-CRYSTAL
lib LibFoo
- type X = Void*
+ type X = Int32
end
class Foo
@x : LibFoo::X
diff --git a/spec/interpreter_std_spec.cr b/spec/interpreter_std_spec.cr
index dee5e0fb75ad..318a4159facf 100644
--- a/spec/interpreter_std_spec.cr
+++ b/spec/interpreter_std_spec.cr
@@ -72,6 +72,7 @@ require "./std/env_spec.cr"
require "./std/errno_spec.cr"
# require "./std/exception/call_stack_spec.cr" (failed to run)
require "./std/exception_spec.cr"
+require "./std/fiber_spec.cr"
require "./std/file_spec.cr"
require "./std/file/tempfile_spec.cr"
require "./std/file_utils_spec.cr"
diff --git a/spec/primitives/reference_spec.cr b/spec/primitives/reference_spec.cr
index b73553748b65..52f179296ee8 100644
--- a/spec/primitives/reference_spec.cr
+++ b/spec/primitives/reference_spec.cr
@@ -43,9 +43,7 @@ describe "Primitives: reference" do
end
it "works when address is on the stack" do
- # suitably aligned, sufficient storage for type ID + i64 + ptr
- # TODO: use `ReferenceStorage` instead
- foo_buffer = uninitialized UInt64[3]
+ foo_buffer = uninitialized ReferenceStorage(Foo)
foo = Foo.pre_initialize(pointerof(foo_buffer))
pointerof(foo_buffer).as(typeof(Foo.crystal_instance_type_id)*).value.should eq(Foo.crystal_instance_type_id)
foo.str.should eq("abc")
diff --git a/spec/std/crystal/system_spec.cr b/spec/std/crystal/system_spec.cr
new file mode 100644
index 000000000000..06bc789055d4
--- /dev/null
+++ b/spec/std/crystal/system_spec.cr
@@ -0,0 +1,46 @@
+require "spec"
+
+private def print_error_to_s(format, *args)
+ io = IO::Memory.new
+ Crystal::System.print_error(format, *args) do |bytes|
+ io.write_string(bytes)
+ end
+ io.to_s
+end
+
+describe "Crystal::System" do
+ describe ".print_error" do
+ it "works" do
+ print_error_to_s("abcde").should eq("abcde")
+ end
+
+ it "supports %d" do
+ print_error_to_s("%d,%d,%d,%d,%d", 0, 1234, Int32::MAX, Int32::MIN, UInt64::MAX).should eq("0,1234,2147483647,-2147483648,-1")
+ end
+
+ it "supports %u" do
+ print_error_to_s("%u,%u,%u,%u,%u", 0, 1234, UInt32::MAX, Int32::MIN, UInt64::MAX).should eq("0,1234,4294967295,2147483648,4294967295")
+ end
+
+ it "supports %x" do
+ print_error_to_s("%x,%x,%x,%x,%x", 0, 0x1234, UInt32::MAX, Int32::MIN, UInt64::MAX).should eq("0,1234,ffffffff,80000000,ffffffff")
+ end
+
+ it "supports %p" do
+ print_error_to_s("%p,%p,%p", Pointer(Void).new(0x0), Pointer(Void).new(0x1234), Pointer(Void).new(UInt64::MAX)).should eq("0x0,0x1234,0xffffffffffffffff")
+ end
+
+ it "supports %s" do
+ print_error_to_s("%s,%s,%s", "abc\0def", "ghi".to_unsafe, Pointer(UInt8).null).should eq("abc\0def,ghi,(null)")
+ end
+
+ it "supports %l width" do
+ values = {LibC::Long::MIN, LibC::Long::MAX, LibC::LongLong::MIN, LibC::LongLong::MAX}
+ print_error_to_s("%ld,%ld,%lld,%lld", *values).should eq(values.join(','))
+
+ values = {LibC::ULong::MIN, LibC::ULong::MAX, LibC::ULongLong::MIN, LibC::ULongLong::MAX}
+ print_error_to_s("%lu,%lu,%llu,%llu", *values).should eq(values.join(','))
+ print_error_to_s("%lx,%lx,%llx,%llx", *values).should eq(values.join(',', &.to_s(16)))
+ end
+ end
+end
diff --git a/spec/std/dir_spec.cr b/spec/std/dir_spec.cr
index f0721ef66abb..f0c01d613570 100644
--- a/spec/std/dir_spec.cr
+++ b/spec/std/dir_spec.cr
@@ -3,25 +3,9 @@ require "../support/env"
private def unset_tempdir(&)
{% if flag?(:windows) %}
- old_tempdirs = {ENV["TMP"]?, ENV["TEMP"]?, ENV["USERPROFILE"]?}
- begin
- ENV.delete("TMP")
- ENV.delete("TEMP")
- ENV.delete("USERPROFILE")
-
- yield
- ensure
- ENV["TMP"], ENV["TEMP"], ENV["USERPROFILE"] = old_tempdirs
- end
+ with_env("TMP": nil, "TEMP": nil, "USERPROFILE": nil) { yield }
{% else %}
- begin
- old_tempdir = ENV["TMPDIR"]?
- ENV.delete("TMPDIR")
-
- yield
- ensure
- ENV["TMPDIR"] = old_tempdir
- end
+ with_env("TMPDIR": nil) { yield }
{% end %}
end
diff --git a/spec/std/enumerable_spec.cr b/spec/std/enumerable_spec.cr
index 04d46c7976a3..0bcbac725cb5 100644
--- a/spec/std/enumerable_spec.cr
+++ b/spec/std/enumerable_spec.cr
@@ -131,6 +131,16 @@ describe "Enumerable" do
end
end
+ describe "to_a" do
+ context "with a block" do
+ SpecEnumerable.new.to_a { |e| e*2 }.should eq [2, 4, 6]
+ end
+
+ context "without a block" do
+ SpecEnumerable.new.to_a.should eq [1, 2, 3]
+ end
+ end
+
describe "#to_set" do
context "without block" do
it "creates a Set from the unique elements of the collection" do
diff --git a/spec/std/env_spec.cr b/spec/std/env_spec.cr
index 8342494b10f6..038bdc74b9b1 100644
--- a/spec/std/env_spec.cr
+++ b/spec/std/env_spec.cr
@@ -2,6 +2,23 @@ require "spec"
require "./spec_helper"
describe "ENV" do
+ # Preserves the existing environment for each spec.
+ # To avoid potential circular definitions, this has to use the system methods
+ # directly, rather than `ENV` or `with_env`.
+ around_each do |example|
+ old_env = {} of String => String
+ Crystal::System::Env.each { |key, value| old_env[key] = value }
+
+ begin
+ example.run
+ ensure
+ keys = [] of String
+ Crystal::System::Env.each { |key| keys << key }
+ keys.each { |key| Crystal::System::Env.set(key, nil) }
+ old_env.each { |key, value| Crystal::System::Env.set(key, value) }
+ end
+ end
+
it "gets non existent key raises" do
expect_raises KeyError, "Missing ENV key: \"NON-EXISTENT\"" do
ENV["NON-EXISTENT"]
@@ -16,8 +33,6 @@ describe "ENV" do
(ENV["FOO"] = "1").should eq("1")
ENV["FOO"].should eq("1")
ENV["FOO"]?.should eq("1")
- ensure
- ENV.delete("FOO")
end
{% if flag?(:win32) %}
@@ -25,15 +40,11 @@ describe "ENV" do
(ENV["FOO"] = "1").should eq("1")
ENV["Foo"].should eq("1")
ENV["foo"]?.should eq("1")
- ensure
- ENV.delete("FOO")
end
{% else %}
it "sets and gets case-sensitive" do
ENV["FOO"] = "1"
ENV["foo"]?.should be_nil
- ensure
- ENV.delete("FOO")
end
{% end %}
@@ -47,16 +58,12 @@ describe "ENV" do
it "sets to empty string" do
(ENV["FOO_EMPTY"] = "").should eq ""
ENV["FOO_EMPTY"]?.should eq ""
- ensure
- ENV.delete("FOO_EMPTY")
end
it "does has_key?" do
ENV["FOO"] = "1"
ENV.has_key?("NON_EXISTENT").should be_false
ENV.has_key?("FOO").should be_true
- ensure
- ENV.delete("FOO")
end
it "deletes a key" do
@@ -70,9 +77,6 @@ describe "ENV" do
%w(FOO BAR).each { |k| ENV.keys.should_not contain(k) }
ENV["FOO"] = ENV["BAR"] = "1"
%w(FOO BAR).each { |k| ENV.keys.should contain(k) }
- ensure
- ENV.delete("FOO")
- ENV.delete("BAR")
end
it "does not have an empty key" do
@@ -86,9 +90,6 @@ describe "ENV" do
ENV["FOO"] = "SOMEVALUE_1"
ENV["BAR"] = "SOMEVALUE_2"
[1, 2].each { |i| ENV.values.should contain("SOMEVALUE_#{i}") }
- ensure
- ENV.delete("FOO")
- ENV.delete("BAR")
end
describe "[]=" do
@@ -115,16 +116,12 @@ describe "ENV" do
it "fetches with one argument" do
ENV["1"] = "2"
ENV.fetch("1").should eq("2")
- ensure
- ENV.delete("1")
end
it "fetches with default value" do
ENV["1"] = "2"
ENV.fetch("1", "3").should eq("2")
ENV.fetch("2", "3").should eq("3")
- ensure
- ENV.delete("1")
end
it "fetches with block" do
@@ -132,8 +129,6 @@ describe "ENV" do
ENV.fetch("1") { |k| k + "block" }.should eq("2")
ENV.fetch("2") { |k| k + "block" }.should eq("2block")
ENV.fetch("3") { 4 }.should eq(4)
- ensure
- ENV.delete("1")
end
it "fetches and raises" do
@@ -141,8 +136,6 @@ describe "ENV" do
expect_raises KeyError, "Missing ENV key: \"2\"" do
ENV.fetch("2")
end
- ensure
- ENV.delete("1")
end
end
@@ -162,16 +155,11 @@ describe "ENV" do
"TEST_UNICODE_1" => "bar\u{d7ff}\u{10000}",
"TEST_UNICODE_2" => "\u{1234}",
})
- ensure
- ENV.delete("TEST_UNICODE_1")
- ENV.delete("TEST_UNICODE_2")
end
it "#to_h" do
ENV["FOO"] = "foo"
ENV.to_h["FOO"].should eq "foo"
- ensure
- ENV.delete("FOO")
end
{% if flag?(:win32) %}
diff --git a/spec/std/fiber_spec.cr b/spec/std/fiber_spec.cr
new file mode 100644
index 000000000000..5c85d1a7475d
--- /dev/null
+++ b/spec/std/fiber_spec.cr
@@ -0,0 +1,21 @@
+require "spec"
+
+describe Fiber do
+ it "#resumable?" do
+ done = false
+ resumable = nil
+
+ fiber = spawn do
+ resumable = Fiber.current.resumable?
+ done = true
+ end
+
+ fiber.resumable?.should be_true
+
+ until done
+ Fiber.yield
+ end
+
+ resumable.should be_false
+ end
+end
diff --git a/spec/std/float_printer/ryu_printf_spec.cr b/spec/std/float_printer/ryu_printf_spec.cr
index d4ba77bffd94..02ac2944a37d 100644
--- a/spec/std/float_printer/ryu_printf_spec.cr
+++ b/spec/std/float_printer/ryu_printf_spec.cr
@@ -1,9 +1,9 @@
-# FIXME: this leads to an OOB on wasm32 (#13918)
-{% skip_file if flag?(:wasm32) %}
+{% skip_file unless String::Formatter::HAS_RYU_PRINTF %}
# This file contains test cases derived from:
#
# * https://github.com/ulfjack/ryu
+# * https://github.com/microsoft/STL/tree/main/tests/std/tests/P0067R5_charconv
#
# The following is their license:
#
@@ -25,6 +25,7 @@
# KIND, either express or implied.
require "spec"
+require "../../support/number"
require "float/printer/ryu_printf"
require "big"
require "./ryu_printf_test_cases"
@@ -118,6 +119,10 @@ private macro expect_exp(float, precision, string)
Float::Printer::RyuPrintf.d2exp({{ float }}, {{ precision }}).should eq({{ string }})
end
+private macro expect_gen(float, precision, string, *, file = __FILE__, line = __LINE__)
+ Float::Printer::RyuPrintf.d2gen({{ float }}, {{ precision }}).should eq({{ string }}), file: {{ file }}, line: {{ line }}
+end
+
describe Float::Printer::RyuPrintf do
describe ".d2fixed" do
it "Basic" do
@@ -491,4 +496,945 @@ describe Float::Printer::RyuPrintf do
expect_exp(1e+83, 1, "1.0e+83")
end
end
+
+ describe ".d2gen" do
+ it "Basic" do
+ expect_gen(0.0, 4, "0")
+ expect_gen(1.729, 4, "1.729")
+ end
+
+ it "corner cases" do
+ expect_gen(Float64::MIN_SUBNORMAL, 1000,
+ "4.940656458412465441765687928682213723650598026143247644255856825006755072702087518652998363616359923797965646954457177309266567103559397963987747960107818781263007131903114045278458171678489821036887186360569987307230500063874091535649843873124733972731696151400317153853980741262385655911710266585566867681870395603106249319452715914924553293054565444011274801297099995419319894090804165633245247571478690147267801593552386115501348035264934720193790268107107491703332226844753335720832431936092382893458368060106011506169809753078342277318329247904982524730776375927247874656084778203734469699533647017972677717585125660551199131504891101451037862738167250955837389733598993664809941164205702637090279242767544565229087538682506419718265533447265625e-324")
+ expect_gen(Float64::MIN_POSITIVE.prev_float, 1000,
+ "2.2250738585072008890245868760858598876504231122409594654935248025624400092282356951787758888037591552642309780950434312085877387158357291821993020294379224223559819827501242041788969571311791082261043971979604000454897391938079198936081525613113376149842043271751033627391549782731594143828136275113838604094249464942286316695429105080201815926642134996606517803095075913058719846423906068637102005108723282784678843631944515866135041223479014792369585208321597621066375401613736583044193603714778355306682834535634005074073040135602968046375918583163124224521599262546494300836851861719422417646455137135420132217031370496583210154654068035397417906022589503023501937519773030945763173210852507299305089761582519159720757232455434770912461317493580281734466552734375e-308")
+ expect_gen(Float64::MIN_POSITIVE, 1000,
+ "2.225073858507201383090232717332404064219215980462331830553327416887204434813918195854283159012511020564067339731035811005152434161553460108856012385377718821130777993532002330479610147442583636071921565046942503734208375250806650616658158948720491179968591639648500635908770118304874799780887753749949451580451605050915399856582470818645113537935804992115981085766051992433352114352390148795699609591288891602992641511063466313393663477586513029371762047325631781485664350872122828637642044846811407613911477062801689853244110024161447421618567166150540154285084716752901903161322778896729707373123334086988983175067838846926092773977972858659654941091369095406136467568702398678315290680984617210924625396728515625e-308")
+ expect_gen(Float64::MAX, 1000,
+ "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368")
+
+ expect_gen(Float64::MIN_SUBNORMAL, 6, "4.94066e-324")
+ expect_gen(Float64::MIN_POSITIVE.prev_float, 6, "2.22507e-308")
+ expect_gen(Float64::MIN_POSITIVE, 6, "2.22507e-308")
+ expect_gen(Float64::MAX, 6, "1.79769e+308")
+ end
+
+ it "maximum-length output" do
+ expect_gen(hexfloat("0x1.fffffffffffffp-1022"), 1000,
+ "4.4501477170144022721148195934182639518696390927032912960468522194496444440421538910330590478162701758282983178260792422137401728773891892910553144148156412434867599762821265346585071045737627442980259622449029037796981144446145705102663115100318287949527959668236039986479250965780342141637013812613333119898765515451440315261253813266652951306000184917766328660755595837392240989947807556594098101021612198814605258742579179000071675999344145086087205681577915435923018910334964869420614052182892431445797605163650903606514140377217442262561590244668525767372446430075513332450079650686719491377688478005309963967709758965844137894433796621993967316936280457084866613206797017728916080020698679408551343728867675409720757232455434770912461317493580281734466552734375e-308")
+ expect_gen(hexfloat("0x1.fffffffffffffp-14"), 1000,
+ "0.000122070312499999986447472843931194574906839989125728607177734375")
+ end
+
+ it "varying precision" do
+ expect_gen(hexfloat("0x1.b04p0"), 0, "2")
+ expect_gen(hexfloat("0x1.b04p0"), 1, "2") # fixed notation trims decimal point
+ expect_gen(hexfloat("0x1.b04p0"), 2, "1.7")
+ expect_gen(hexfloat("0x1.b04p0"), 3, "1.69")
+ expect_gen(hexfloat("0x1.b04p0"), 4, "1.688")
+ expect_gen(hexfloat("0x1.b04p0"), 5, "1.6885")
+ expect_gen(hexfloat("0x1.b04p0"), 6, "1.68848")
+ expect_gen(hexfloat("0x1.b04p0"), 7, "1.688477")
+ expect_gen(hexfloat("0x1.b04p0"), 8, "1.6884766")
+ expect_gen(hexfloat("0x1.b04p0"), 9, "1.68847656")
+ expect_gen(hexfloat("0x1.b04p0"), 10, "1.688476562") # round to even
+ expect_gen(hexfloat("0x1.b04p0"), 11, "1.6884765625") # exact
+ expect_gen(hexfloat("0x1.b04p0"), 12, "1.6884765625") # trim trailing zeros
+ expect_gen(hexfloat("0x1.b04p0"), 13, "1.6884765625")
+
+ expect_gen(hexfloat("0x1.8p-15"), 0, "5e-5")
+ expect_gen(hexfloat("0x1.8p-15"), 1, "5e-5") # scientific notation trims decimal point
+ expect_gen(hexfloat("0x1.8p-15"), 2, "4.6e-5")
+ expect_gen(hexfloat("0x1.8p-15"), 3, "4.58e-5")
+ expect_gen(hexfloat("0x1.8p-15"), 4, "4.578e-5")
+ expect_gen(hexfloat("0x1.8p-15"), 5, "4.5776e-5")
+ expect_gen(hexfloat("0x1.8p-15"), 6, "4.57764e-5")
+ expect_gen(hexfloat("0x1.8p-15"), 7, "4.577637e-5")
+ expect_gen(hexfloat("0x1.8p-15"), 8, "4.5776367e-5")
+ expect_gen(hexfloat("0x1.8p-15"), 9, "4.57763672e-5")
+ expect_gen(hexfloat("0x1.8p-15"), 10, "4.577636719e-5")
+ expect_gen(hexfloat("0x1.8p-15"), 11, "4.5776367188e-5") # round to even
+ expect_gen(hexfloat("0x1.8p-15"), 12, "4.57763671875e-5") # exact
+ expect_gen(hexfloat("0x1.8p-15"), 13, "4.57763671875e-5") # trim trailing zeros
+ expect_gen(hexfloat("0x1.8p-15"), 14, "4.57763671875e-5")
+ end
+
+ it "trim trailing zeros" do
+ expect_gen(hexfloat("0x1.80015p0"), 1, "2") # fixed notation trims decimal point
+ expect_gen(hexfloat("0x1.80015p0"), 2, "1.5")
+ expect_gen(hexfloat("0x1.80015p0"), 3, "1.5") # general trims trailing zeros
+ expect_gen(hexfloat("0x1.80015p0"), 4, "1.5")
+ expect_gen(hexfloat("0x1.80015p0"), 5, "1.5")
+ expect_gen(hexfloat("0x1.80015p0"), 6, "1.50002")
+ expect_gen(hexfloat("0x1.80015p0"), 7, "1.50002")
+ expect_gen(hexfloat("0x1.80015p0"), 8, "1.50002")
+ expect_gen(hexfloat("0x1.80015p0"), 9, "1.50002003")
+ expect_gen(hexfloat("0x1.80015p0"), 10, "1.500020027")
+ expect_gen(hexfloat("0x1.80015p0"), 11, "1.5000200272")
+ expect_gen(hexfloat("0x1.80015p0"), 12, "1.50002002716")
+ expect_gen(hexfloat("0x1.80015p0"), 13, "1.500020027161")
+ expect_gen(hexfloat("0x1.80015p0"), 14, "1.5000200271606")
+ expect_gen(hexfloat("0x1.80015p0"), 15, "1.50002002716064")
+ expect_gen(hexfloat("0x1.80015p0"), 16, "1.500020027160645")
+ expect_gen(hexfloat("0x1.80015p0"), 17, "1.5000200271606445")
+ expect_gen(hexfloat("0x1.80015p0"), 18, "1.50002002716064453")
+ expect_gen(hexfloat("0x1.80015p0"), 19, "1.500020027160644531")
+ expect_gen(hexfloat("0x1.80015p0"), 20, "1.5000200271606445312") # round to even
+ expect_gen(hexfloat("0x1.80015p0"), 21, "1.50002002716064453125") # exact
+ end
+
+ it "trim trailing zeros and decimal point" do
+ expect_gen(hexfloat("0x1.00015p0"), 1, "1") # fixed notation trims decimal point
+ expect_gen(hexfloat("0x1.00015p0"), 2, "1") # general trims decimal point and trailing zeros
+ expect_gen(hexfloat("0x1.00015p0"), 3, "1")
+ expect_gen(hexfloat("0x1.00015p0"), 4, "1")
+ expect_gen(hexfloat("0x1.00015p0"), 5, "1")
+ expect_gen(hexfloat("0x1.00015p0"), 6, "1.00002")
+ expect_gen(hexfloat("0x1.00015p0"), 7, "1.00002")
+ expect_gen(hexfloat("0x1.00015p0"), 8, "1.00002")
+ expect_gen(hexfloat("0x1.00015p0"), 9, "1.00002003")
+ expect_gen(hexfloat("0x1.00015p0"), 10, "1.000020027")
+ expect_gen(hexfloat("0x1.00015p0"), 11, "1.0000200272")
+ expect_gen(hexfloat("0x1.00015p0"), 12, "1.00002002716")
+ expect_gen(hexfloat("0x1.00015p0"), 13, "1.000020027161")
+ expect_gen(hexfloat("0x1.00015p0"), 14, "1.0000200271606")
+ expect_gen(hexfloat("0x1.00015p0"), 15, "1.00002002716064")
+ expect_gen(hexfloat("0x1.00015p0"), 16, "1.000020027160645")
+ expect_gen(hexfloat("0x1.00015p0"), 17, "1.0000200271606445")
+ expect_gen(hexfloat("0x1.00015p0"), 18, "1.00002002716064453")
+ expect_gen(hexfloat("0x1.00015p0"), 19, "1.000020027160644531")
+ expect_gen(hexfloat("0x1.00015p0"), 20, "1.0000200271606445312") # round to even
+ expect_gen(hexfloat("0x1.00015p0"), 21, "1.00002002716064453125") # exact
+ end
+
+ it "trim trailing zeros, scientific notation" do
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 1, "1e-6") # scientific notation trims decimal point
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 2, "1.3e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 3, "1.3e-6") # general trims trailing zeros
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 4, "1.3e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 5, "1.3e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 6, "1.3e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 7, "1.3e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 8, "1.3e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 9, "1.3e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 10, "1.3e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 11, "1.3e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 12, "1.3e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 13, "1.3e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 14, "1.3e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 15, "1.3e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 16, "1.3e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 17, "1.3e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 18, "1.30000000000000005e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 19, "1.300000000000000047e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 20, "1.3000000000000000471e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 21, "1.30000000000000004705e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 22, "1.300000000000000047052e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 23, "1.3000000000000000470517e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 24, "1.30000000000000004705166e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 25, "1.300000000000000047051664e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 26, "1.3000000000000000470516638e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 27, "1.30000000000000004705166378e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 28, "1.30000000000000004705166378e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 29, "1.3000000000000000470516637804e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 30, "1.30000000000000004705166378044e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 31, "1.30000000000000004705166378044e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 32, "1.3000000000000000470516637804397e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 33, "1.30000000000000004705166378043968e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 34, "1.300000000000000047051663780439679e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 35, "1.3000000000000000470516637804396787e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 36, "1.30000000000000004705166378043967867e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 37, "1.300000000000000047051663780439678675e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 38, "1.3000000000000000470516637804396786748e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 39, "1.30000000000000004705166378043967867484e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 40, "1.300000000000000047051663780439678674838e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 41, "1.3000000000000000470516637804396786748384e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 42, "1.30000000000000004705166378043967867483843e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 43, "1.300000000000000047051663780439678674838433e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 44, "1.3000000000000000470516637804396786748384329e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 45, "1.30000000000000004705166378043967867483843293e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 46, "1.300000000000000047051663780439678674838432926e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 47, "1.3000000000000000470516637804396786748384329258e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 48, "1.30000000000000004705166378043967867483843292575e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 49, "1.300000000000000047051663780439678674838432925753e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 50, "1.3000000000000000470516637804396786748384329257533e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 51, "1.3000000000000000470516637804396786748384329257533e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 52, "1.300000000000000047051663780439678674838432925753295e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 53, "1.3000000000000000470516637804396786748384329257532954e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 54, "1.30000000000000004705166378043967867483843292575329542e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 55, "1.300000000000000047051663780439678674838432925753295422e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 56, "1.3000000000000000470516637804396786748384329257532954216e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 57, "1.3000000000000000470516637804396786748384329257532954216e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 58, "1.3000000000000000470516637804396786748384329257532954216e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 59, "1.3000000000000000470516637804396786748384329257532954216003e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 60, "1.30000000000000004705166378043967867483843292575329542160034e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 61, "1.300000000000000047051663780439678674838432925753295421600342e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 62, "1.3000000000000000470516637804396786748384329257532954216003418e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 63, "1.3000000000000000470516637804396786748384329257532954216003418e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 64, "1.300000000000000047051663780439678674838432925753295421600341797e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 65, "1.3000000000000000470516637804396786748384329257532954216003417969e-6")
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 66, "1.30000000000000004705166378043967867483843292575329542160034179688e-6") # round to even
+ expect_gen(hexfloat("0x1.5cf751db94e6bp-20"), 67, "1.300000000000000047051663780439678674838432925753295421600341796875e-6") # exact
+ end
+
+ it "trim trailing zeros and decimal point, scientific notation" do
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 1, "3e-6") # scientific notation trims decimal point
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 2, "3e-6") # general trims decimal point and trailing zeros
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 3, "3e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 4, "3e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 5, "3e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 6, "3e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 7, "3e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 8, "3e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 9, "3e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 10, "3e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 11, "3e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 12, "3e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 13, "3e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 14, "3e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 15, "3e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 16, "3e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 17, "3.0000000000000001e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 18, "3.00000000000000008e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 19, "3.000000000000000076e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 20, "3.000000000000000076e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 21, "3.000000000000000076e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 22, "3.000000000000000076003e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 23, "3.0000000000000000760026e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 24, "3.00000000000000007600257e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 25, "3.000000000000000076002572e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 26, "3.0000000000000000760025723e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 27, "3.00000000000000007600257229e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 28, "3.000000000000000076002572291e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 29, "3.0000000000000000760025722912e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 30, "3.00000000000000007600257229123e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 31, "3.000000000000000076002572291234e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 32, "3.0000000000000000760025722912339e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 33, "3.00000000000000007600257229123386e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 34, "3.000000000000000076002572291233861e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 35, "3.0000000000000000760025722912338608e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 36, "3.00000000000000007600257229123386082e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 37, "3.000000000000000076002572291233860824e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 38, "3.0000000000000000760025722912338608239e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 39, "3.00000000000000007600257229123386082392e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 40, "3.000000000000000076002572291233860823922e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 41, "3.0000000000000000760025722912338608239224e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 42, "3.00000000000000007600257229123386082392244e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 43, "3.000000000000000076002572291233860823922441e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 44, "3.0000000000000000760025722912338608239224413e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 45, "3.00000000000000007600257229123386082392244134e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 46, "3.000000000000000076002572291233860823922441341e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 47, "3.000000000000000076002572291233860823922441341e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 48, "3.00000000000000007600257229123386082392244134098e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 49, "3.000000000000000076002572291233860823922441340983e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 50, "3.0000000000000000760025722912338608239224413409829e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 51, "3.00000000000000007600257229123386082392244134098291e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 52, "3.000000000000000076002572291233860823922441340982914e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 53, "3.000000000000000076002572291233860823922441340982914e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 54, "3.00000000000000007600257229123386082392244134098291397e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 55, "3.000000000000000076002572291233860823922441340982913971e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 56, "3.0000000000000000760025722912338608239224413409829139709e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 57, "3.00000000000000007600257229123386082392244134098291397095e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 58, "3.000000000000000076002572291233860823922441340982913970947e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 59, "3.0000000000000000760025722912338608239224413409829139709473e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 60, "3.00000000000000007600257229123386082392244134098291397094727e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 61, "3.000000000000000076002572291233860823922441340982913970947266e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 62, "3.0000000000000000760025722912338608239224413409829139709472656e-6")
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 63, "3.00000000000000007600257229123386082392244134098291397094726562e-6") # round to even
+ expect_gen(hexfloat("0x1.92a737110e454p-19"), 64, "3.000000000000000076002572291233860823922441340982913970947265625e-6") # exact
+ end
+
+ it "large precision with fixed notation and scientific notation" do
+ expect_gen(hexfloat("0x1.ba9fbe76c8b44p+0"), 5000, "1.72900000000000009237055564881302416324615478515625")
+ expect_gen(hexfloat("0x1.d01ff9abb93d1p-20"), 5000, "1.729000000000000090107283613749533657255597063340246677398681640625e-6")
+ end
+
+ it "transitions between fixed notation and scientific notation" do
+ expect_gen(5555555.0, 1, "6e+6")
+ expect_gen(555555.0, 1, "6e+5")
+ expect_gen(55555.0, 1, "6e+4")
+ expect_gen(5555.0, 1, "6e+3")
+ expect_gen(555.0, 1, "6e+2")
+ expect_gen(55.0, 1, "6e+1") # round to even
+ expect_gen(5.0, 1, "5")
+ expect_gen(hexfloat("0x1p-3"), 1, "0.1") # 0.125
+ expect_gen(hexfloat("0x1p-6"), 1, "0.02") # 0.015625
+ expect_gen(hexfloat("0x1p-9"), 1, "0.002") # 0.001953125
+ expect_gen(hexfloat("0x1p-13"), 1, "0.0001") # 0.0001220703125
+ expect_gen(hexfloat("0x1p-16"), 1, "2e-5") # 1.52587890625e-5
+ expect_gen(hexfloat("0x1p-19"), 1, "2e-6") # 1.9073486328125e-6
+
+ expect_gen(5555555.0, 2, "5.6e+6")
+ expect_gen(555555.0, 2, "5.6e+5")
+ expect_gen(55555.0, 2, "5.6e+4")
+ expect_gen(5555.0, 2, "5.6e+3")
+ expect_gen(555.0, 2, "5.6e+2") # round to even
+ expect_gen(55.0, 2, "55")
+ expect_gen(5.0, 2, "5")
+ expect_gen(hexfloat("0x1p-3"), 2, "0.12") # round to even
+ expect_gen(hexfloat("0x1p-6"), 2, "0.016")
+ expect_gen(hexfloat("0x1p-9"), 2, "0.002")
+ expect_gen(hexfloat("0x1p-13"), 2, "0.00012")
+ expect_gen(hexfloat("0x1p-16"), 2, "1.5e-5")
+ expect_gen(hexfloat("0x1p-19"), 2, "1.9e-6")
+
+ expect_gen(5555555.0, 3, "5.56e+6")
+ expect_gen(555555.0, 3, "5.56e+5")
+ expect_gen(55555.0, 3, "5.56e+4")
+ expect_gen(5555.0, 3, "5.56e+3") # round to even
+ expect_gen(555.0, 3, "555")
+ expect_gen(55.0, 3, "55")
+ expect_gen(5.0, 3, "5")
+ expect_gen(hexfloat("0x1p-3"), 3, "0.125")
+ expect_gen(hexfloat("0x1p-6"), 3, "0.0156")
+ expect_gen(hexfloat("0x1p-9"), 3, "0.00195")
+ expect_gen(hexfloat("0x1p-13"), 3, "0.000122")
+ expect_gen(hexfloat("0x1p-16"), 3, "1.53e-5")
+ expect_gen(hexfloat("0x1p-19"), 3, "1.91e-6")
+
+ expect_gen(5555555.0, 4, "5.556e+6")
+ expect_gen(555555.0, 4, "5.556e+5")
+ expect_gen(55555.0, 4, "5.556e+4") # round to even
+ expect_gen(5555.0, 4, "5555")
+ expect_gen(555.0, 4, "555")
+ expect_gen(55.0, 4, "55")
+ expect_gen(5.0, 4, "5")
+ expect_gen(hexfloat("0x1p-3"), 4, "0.125")
+ expect_gen(hexfloat("0x1p-6"), 4, "0.01562") # round to even
+ expect_gen(hexfloat("0x1p-9"), 4, "0.001953")
+ expect_gen(hexfloat("0x1p-13"), 4, "0.0001221")
+ expect_gen(hexfloat("0x1p-16"), 4, "1.526e-5")
+ expect_gen(hexfloat("0x1p-19"), 4, "1.907e-6")
+
+ expect_gen(5555555.0, 5, "5.5556e+6")
+ expect_gen(555555.0, 5, "5.5556e+5") # round to even
+ expect_gen(55555.0, 5, "55555")
+ expect_gen(5555.0, 5, "5555")
+ expect_gen(555.0, 5, "555")
+ expect_gen(55.0, 5, "55")
+ expect_gen(5.0, 5, "5")
+ expect_gen(hexfloat("0x1p-3"), 5, "0.125")
+ expect_gen(hexfloat("0x1p-6"), 5, "0.015625")
+ expect_gen(hexfloat("0x1p-9"), 5, "0.0019531")
+ expect_gen(hexfloat("0x1p-13"), 5, "0.00012207")
+ expect_gen(hexfloat("0x1p-16"), 5, "1.5259e-5")
+ expect_gen(hexfloat("0x1p-19"), 5, "1.9073e-6")
+ end
+
+ it "tricky corner cases" do
+ expect_gen(999.999, 1, "1e+3") # "%.0e" is "1e+3"; X == 3
+ expect_gen(999.999, 2, "1e+3") # "%.1e" is "1.0e+3"; X == 3
+ expect_gen(999.999, 3, "1e+3") # "%.2e" is "1.00e+3"; X == 3
+ expect_gen(999.999, 4, "1000") # "%.3e" is "1.000e+3"; X == 3
+ expect_gen(999.999, 5, "1000") # "%.4e" is "1.0000e+3"; X == 3
+ expect_gen(999.999, 6, "999.999") # "%.5e" is "9.99999e+2"; X == 2
+
+ expect_gen(999.99, 1, "1e+3")
+ expect_gen(999.99, 2, "1e+3")
+ expect_gen(999.99, 3, "1e+3")
+ expect_gen(999.99, 4, "1000")
+ expect_gen(999.99, 5, "999.99")
+ expect_gen(999.99, 6, "999.99")
+
+ # C11's Standardese is slightly vague about how to perform the trial formatting in scientific notation,
+ # but the intention is to use precision P - 1, which is what's used when scientific notation is actually chosen.
+ # This example verifies this behavior. Here, P == 3 performs trial formatting with "%.2e", triggering rounding.
+ # That increases X to 3, forcing scientific notation to be chosen.
+ # If P == 3 performed trial formatting with "%.3e", rounding wouldn't happen,
+ # X would be 2, and fixed notation would be chosen.
+ expect_gen(999.9, 1, "1e+3") # "%.0e" is "1e+3"; X == 3
+ expect_gen(999.9, 2, "1e+3") # "%.1e" is "1.0e+3"; X == 3
+ expect_gen(999.9, 3, "1e+3") # "%.2e" is "1.00e+3"; X == 3; SPECIAL CORNER CASE
+ expect_gen(999.9, 4, "999.9") # "%.3e" is "9.999e+2"; X == 2
+ expect_gen(999.9, 5, "999.9") # "%.4e" is "9.9990e+2"; X == 2
+ expect_gen(999.9, 6, "999.9") # "%.5e" is "9.99900e+2"; X == 2
+
+ expect_gen(999.0, 1, "1e+3")
+ expect_gen(999.0, 2, "1e+3")
+ expect_gen(999.0, 3, "999")
+ expect_gen(999.0, 4, "999")
+ expect_gen(999.0, 5, "999")
+ expect_gen(999.0, 6, "999")
+
+ expect_gen(99.9999, 1, "1e+2")
+ expect_gen(99.9999, 2, "1e+2")
+ expect_gen(99.9999, 3, "100")
+ expect_gen(99.9999, 4, "100")
+ expect_gen(99.9999, 5, "100")
+ expect_gen(99.9999, 6, "99.9999")
+
+ expect_gen(99.999, 1, "1e+2")
+ expect_gen(99.999, 2, "1e+2")
+ expect_gen(99.999, 3, "100")
+ expect_gen(99.999, 4, "100")
+ expect_gen(99.999, 5, "99.999")
+ expect_gen(99.999, 6, "99.999")
+
+ expect_gen(99.99, 1, "1e+2")
+ expect_gen(99.99, 2, "1e+2")
+ expect_gen(99.99, 3, "100")
+ expect_gen(99.99, 4, "99.99")
+ expect_gen(99.99, 5, "99.99")
+ expect_gen(99.99, 6, "99.99")
+
+ expect_gen(99.9, 1, "1e+2")
+ expect_gen(99.9, 2, "1e+2")
+ expect_gen(99.9, 3, "99.9")
+ expect_gen(99.9, 4, "99.9")
+ expect_gen(99.9, 5, "99.9")
+ expect_gen(99.9, 6, "99.9")
+
+ expect_gen(99.0, 1, "1e+2")
+ expect_gen(99.0, 2, "99")
+ expect_gen(99.0, 3, "99")
+ expect_gen(99.0, 4, "99")
+ expect_gen(99.0, 5, "99")
+ expect_gen(99.0, 6, "99")
+
+ expect_gen(9.99999, 1, "1e+1")
+ expect_gen(9.99999, 2, "10")
+ expect_gen(9.99999, 3, "10")
+ expect_gen(9.99999, 4, "10")
+ expect_gen(9.99999, 5, "10")
+ expect_gen(9.99999, 6, "9.99999")
+
+ expect_gen(9.9999, 1, "1e+1")
+ expect_gen(9.9999, 2, "10")
+ expect_gen(9.9999, 3, "10")
+ expect_gen(9.9999, 4, "10")
+ expect_gen(9.9999, 5, "9.9999")
+ expect_gen(9.9999, 6, "9.9999")
+
+ expect_gen(9.999, 1, "1e+1")
+ expect_gen(9.999, 2, "10")
+ expect_gen(9.999, 3, "10")
+ expect_gen(9.999, 4, "9.999")
+ expect_gen(9.999, 5, "9.999")
+ expect_gen(9.999, 6, "9.999")
+
+ expect_gen(9.99, 1, "1e+1")
+ expect_gen(9.99, 2, "10")
+ expect_gen(9.99, 3, "9.99")
+ expect_gen(9.99, 4, "9.99")
+ expect_gen(9.99, 5, "9.99")
+ expect_gen(9.99, 6, "9.99")
+
+ expect_gen(9.9, 1, "1e+1")
+ expect_gen(9.9, 2, "9.9")
+ expect_gen(9.9, 3, "9.9")
+ expect_gen(9.9, 4, "9.9")
+ expect_gen(9.9, 5, "9.9")
+ expect_gen(9.9, 6, "9.9")
+
+ expect_gen(9.0, 1, "9")
+ expect_gen(9.0, 2, "9")
+ expect_gen(9.0, 3, "9")
+ expect_gen(9.0, 4, "9")
+ expect_gen(9.0, 5, "9")
+ expect_gen(9.0, 6, "9")
+
+ expect_gen(0.999999, 1, "1")
+ expect_gen(0.999999, 2, "1")
+ expect_gen(0.999999, 3, "1")
+ expect_gen(0.999999, 4, "1")
+ expect_gen(0.999999, 5, "1")
+ expect_gen(0.999999, 6, "0.999999")
+
+ expect_gen(0.99999, 1, "1")
+ expect_gen(0.99999, 2, "1")
+ expect_gen(0.99999, 3, "1")
+ expect_gen(0.99999, 4, "1")
+ expect_gen(0.99999, 5, "0.99999")
+ expect_gen(0.99999, 6, "0.99999")
+
+ expect_gen(0.9999, 1, "1")
+ expect_gen(0.9999, 2, "1")
+ expect_gen(0.9999, 3, "1")
+ expect_gen(0.9999, 4, "0.9999")
+ expect_gen(0.9999, 5, "0.9999")
+ expect_gen(0.9999, 6, "0.9999")
+
+ expect_gen(0.999, 1, "1")
+ expect_gen(0.999, 2, "1")
+ expect_gen(0.999, 3, "0.999")
+ expect_gen(0.999, 4, "0.999")
+ expect_gen(0.999, 5, "0.999")
+ expect_gen(0.999, 6, "0.999")
+
+ expect_gen(0.99, 1, "1")
+ expect_gen(0.99, 2, "0.99")
+ expect_gen(0.99, 3, "0.99")
+ expect_gen(0.99, 4, "0.99")
+ expect_gen(0.99, 5, "0.99")
+ expect_gen(0.99, 6, "0.99")
+
+ expect_gen(0.9, 1, "0.9")
+ expect_gen(0.9, 2, "0.9")
+ expect_gen(0.9, 3, "0.9")
+ expect_gen(0.9, 4, "0.9")
+ expect_gen(0.9, 5, "0.9")
+ expect_gen(0.9, 6, "0.9")
+
+ expect_gen(0.0999999, 1, "0.1")
+ expect_gen(0.0999999, 2, "0.1")
+ expect_gen(0.0999999, 3, "0.1")
+ expect_gen(0.0999999, 4, "0.1")
+ expect_gen(0.0999999, 5, "0.1")
+ expect_gen(0.0999999, 6, "0.0999999")
+
+ expect_gen(0.099999, 1, "0.1")
+ expect_gen(0.099999, 2, "0.1")
+ expect_gen(0.099999, 3, "0.1")
+ expect_gen(0.099999, 4, "0.1")
+ expect_gen(0.099999, 5, "0.099999")
+ expect_gen(0.099999, 6, "0.099999")
+
+ expect_gen(0.09999, 1, "0.1")
+ expect_gen(0.09999, 2, "0.1")
+ expect_gen(0.09999, 3, "0.1")
+ expect_gen(0.09999, 4, "0.09999")
+ expect_gen(0.09999, 5, "0.09999")
+ expect_gen(0.09999, 6, "0.09999")
+
+ expect_gen(0.0999, 1, "0.1")
+ expect_gen(0.0999, 2, "0.1")
+ expect_gen(0.0999, 3, "0.0999")
+ expect_gen(0.0999, 4, "0.0999")
+ expect_gen(0.0999, 5, "0.0999")
+ expect_gen(0.0999, 6, "0.0999")
+
+ expect_gen(0.099, 1, "0.1")
+ expect_gen(0.099, 2, "0.099")
+ expect_gen(0.099, 3, "0.099")
+ expect_gen(0.099, 4, "0.099")
+ expect_gen(0.099, 5, "0.099")
+ expect_gen(0.099, 6, "0.099")
+
+ expect_gen(0.09, 1, "0.09")
+ expect_gen(0.09, 2, "0.09")
+ expect_gen(0.09, 3, "0.09")
+ expect_gen(0.09, 4, "0.09")
+ expect_gen(0.09, 5, "0.09")
+ expect_gen(0.09, 6, "0.09")
+
+ expect_gen(0.00999999, 1, "0.01")
+ expect_gen(0.00999999, 2, "0.01")
+ expect_gen(0.00999999, 3, "0.01")
+ expect_gen(0.00999999, 4, "0.01")
+ expect_gen(0.00999999, 5, "0.01")
+ expect_gen(0.00999999, 6, "0.00999999")
+
+ expect_gen(0.0099999, 1, "0.01")
+ expect_gen(0.0099999, 2, "0.01")
+ expect_gen(0.0099999, 3, "0.01")
+ expect_gen(0.0099999, 4, "0.01")
+ expect_gen(0.0099999, 5, "0.0099999")
+ expect_gen(0.0099999, 6, "0.0099999")
+
+ expect_gen(0.009999, 1, "0.01")
+ expect_gen(0.009999, 2, "0.01")
+ expect_gen(0.009999, 3, "0.01")
+ expect_gen(0.009999, 4, "0.009999")
+ expect_gen(0.009999, 5, "0.009999")
+ expect_gen(0.009999, 6, "0.009999")
+
+ expect_gen(0.00999, 1, "0.01")
+ expect_gen(0.00999, 2, "0.01")
+ expect_gen(0.00999, 3, "0.00999")
+ expect_gen(0.00999, 4, "0.00999")
+ expect_gen(0.00999, 5, "0.00999")
+ expect_gen(0.00999, 6, "0.00999")
+
+ expect_gen(0.0099, 1, "0.01")
+ expect_gen(0.0099, 2, "0.0099")
+ expect_gen(0.0099, 3, "0.0099")
+ expect_gen(0.0099, 4, "0.0099")
+ expect_gen(0.0099, 5, "0.0099")
+ expect_gen(0.0099, 6, "0.0099")
+
+ expect_gen(0.009, 1, "0.009")
+ expect_gen(0.009, 2, "0.009")
+ expect_gen(0.009, 3, "0.009")
+ expect_gen(0.009, 4, "0.009")
+ expect_gen(0.009, 5, "0.009")
+ expect_gen(0.009, 6, "0.009")
+
+ expect_gen(0.000999999, 1, "0.001")
+ expect_gen(0.000999999, 2, "0.001")
+ expect_gen(0.000999999, 3, "0.001")
+ expect_gen(0.000999999, 4, "0.001")
+ expect_gen(0.000999999, 5, "0.001")
+ expect_gen(0.000999999, 6, "0.000999999")
+
+ expect_gen(0.00099999, 1, "0.001")
+ expect_gen(0.00099999, 2, "0.001")
+ expect_gen(0.00099999, 3, "0.001")
+ expect_gen(0.00099999, 4, "0.001")
+ expect_gen(0.00099999, 5, "0.00099999")
+ expect_gen(0.00099999, 6, "0.00099999")
+
+ expect_gen(0.0009999, 1, "0.001")
+ expect_gen(0.0009999, 2, "0.001")
+ expect_gen(0.0009999, 3, "0.001")
+ expect_gen(0.0009999, 4, "0.0009999")
+ expect_gen(0.0009999, 5, "0.0009999")
+ expect_gen(0.0009999, 6, "0.0009999")
+
+ expect_gen(0.000999, 1, "0.001")
+ expect_gen(0.000999, 2, "0.001")
+ expect_gen(0.000999, 3, "0.000999")
+ expect_gen(0.000999, 4, "0.000999")
+ expect_gen(0.000999, 5, "0.000999")
+ expect_gen(0.000999, 6, "0.000999")
+
+ expect_gen(0.00099, 1, "0.001")
+ expect_gen(0.00099, 2, "0.00099")
+ expect_gen(0.00099, 3, "0.00099")
+ expect_gen(0.00099, 4, "0.00099")
+ expect_gen(0.00099, 5, "0.00099")
+ expect_gen(0.00099, 6, "0.00099")
+
+ expect_gen(0.0009, 1, "0.0009")
+ expect_gen(0.0009, 2, "0.0009")
+ expect_gen(0.0009, 3, "0.0009")
+ expect_gen(0.0009, 4, "0.0009")
+ expect_gen(0.0009, 5, "0.0009")
+ expect_gen(0.0009, 6, "0.0009")
+
+ # Having a scientific exponent X == -5 triggers scientific notation.
+ # If rounding adjusts this to X == -4, then fixed notation will be selected.
+ expect_gen(0.0000999999, 1, "0.0001")
+ expect_gen(0.0000999999, 2, "0.0001")
+ expect_gen(0.0000999999, 3, "0.0001")
+ expect_gen(0.0000999999, 4, "0.0001")
+ expect_gen(0.0000999999, 5, "0.0001")
+ expect_gen(0.0000999999, 6, "9.99999e-5")
+
+ expect_gen(0.000099999, 1, "0.0001")
+ expect_gen(0.000099999, 2, "0.0001")
+ expect_gen(0.000099999, 3, "0.0001")
+ expect_gen(0.000099999, 4, "0.0001")
+ expect_gen(0.000099999, 5, "9.9999e-5")
+ expect_gen(0.000099999, 6, "9.9999e-5")
+
+ expect_gen(0.00009999, 1, "0.0001")
+ expect_gen(0.00009999, 2, "0.0001")
+ expect_gen(0.00009999, 3, "0.0001")
+ expect_gen(0.00009999, 4, "9.999e-5")
+ expect_gen(0.00009999, 5, "9.999e-5")
+ expect_gen(0.00009999, 6, "9.999e-5")
+
+ expect_gen(0.0000999, 1, "0.0001")
+ expect_gen(0.0000999, 2, "0.0001")
+ expect_gen(0.0000999, 3, "9.99e-5")
+ expect_gen(0.0000999, 4, "9.99e-5")
+ expect_gen(0.0000999, 5, "9.99e-5")
+ expect_gen(0.0000999, 6, "9.99e-5")
+
+ expect_gen(0.000099, 1, "0.0001")
+ expect_gen(0.000099, 2, "9.9e-5")
+ expect_gen(0.000099, 3, "9.9e-5")
+ expect_gen(0.000099, 4, "9.9e-5")
+ expect_gen(0.000099, 5, "9.9e-5")
+ expect_gen(0.000099, 6, "9.9e-5")
+
+ expect_gen(0.00009, 1, "9e-5")
+ expect_gen(0.00009, 2, "9e-5")
+ expect_gen(0.00009, 3, "9e-5")
+ expect_gen(0.00009, 4, "9e-5")
+ expect_gen(0.00009, 5, "9e-5")
+ expect_gen(0.00009, 6, "9e-5")
+
+ # Rounding test cases without exponent-adjusting behavior.
+ expect_gen(2999.999, 1, "3e+3")
+ expect_gen(2999.999, 2, "3e+3")
+ expect_gen(2999.999, 3, "3e+3")
+ expect_gen(2999.999, 4, "3000")
+ expect_gen(2999.999, 5, "3000")
+ expect_gen(2999.999, 6, "3000")
+
+ expect_gen(2999.99, 1, "3e+3")
+ expect_gen(2999.99, 2, "3e+3")
+ expect_gen(2999.99, 3, "3e+3")
+ expect_gen(2999.99, 4, "3000")
+ expect_gen(2999.99, 5, "3000")
+ expect_gen(2999.99, 6, "2999.99")
+
+ expect_gen(2999.9, 1, "3e+3")
+ expect_gen(2999.9, 2, "3e+3")
+ expect_gen(2999.9, 3, "3e+3")
+ expect_gen(2999.9, 4, "3000")
+ expect_gen(2999.9, 5, "2999.9")
+ expect_gen(2999.9, 6, "2999.9")
+
+ expect_gen(2999.0, 1, "3e+3")
+ expect_gen(2999.0, 2, "3e+3")
+ expect_gen(2999.0, 3, "3e+3")
+ expect_gen(2999.0, 4, "2999")
+ expect_gen(2999.0, 5, "2999")
+ expect_gen(2999.0, 6, "2999")
+
+ expect_gen(299.999, 1, "3e+2")
+ expect_gen(299.999, 2, "3e+2")
+ expect_gen(299.999, 3, "300")
+ expect_gen(299.999, 4, "300")
+ expect_gen(299.999, 5, "300")
+ expect_gen(299.999, 6, "299.999")
+
+ expect_gen(299.99, 1, "3e+2")
+ expect_gen(299.99, 2, "3e+2")
+ expect_gen(299.99, 3, "300")
+ expect_gen(299.99, 4, "300")
+ expect_gen(299.99, 5, "299.99")
+ expect_gen(299.99, 6, "299.99")
+
+ expect_gen(299.9, 1, "3e+2")
+ expect_gen(299.9, 2, "3e+2")
+ expect_gen(299.9, 3, "300")
+ expect_gen(299.9, 4, "299.9")
+ expect_gen(299.9, 5, "299.9")
+ expect_gen(299.9, 6, "299.9")
+
+ expect_gen(299.0, 1, "3e+2")
+ expect_gen(299.0, 2, "3e+2")
+ expect_gen(299.0, 3, "299")
+ expect_gen(299.0, 4, "299")
+ expect_gen(299.0, 5, "299")
+ expect_gen(299.0, 6, "299")
+
+ expect_gen(29.999, 1, "3e+1")
+ expect_gen(29.999, 2, "30")
+ expect_gen(29.999, 3, "30")
+ expect_gen(29.999, 4, "30")
+ expect_gen(29.999, 5, "29.999")
+ expect_gen(29.999, 6, "29.999")
+
+ expect_gen(29.99, 1, "3e+1")
+ expect_gen(29.99, 2, "30")
+ expect_gen(29.99, 3, "30")
+ expect_gen(29.99, 4, "29.99")
+ expect_gen(29.99, 5, "29.99")
+ expect_gen(29.99, 6, "29.99")
+
+ expect_gen(29.9, 1, "3e+1")
+ expect_gen(29.9, 2, "30")
+ expect_gen(29.9, 3, "29.9")
+ expect_gen(29.9, 4, "29.9")
+ expect_gen(29.9, 5, "29.9")
+ expect_gen(29.9, 6, "29.9")
+
+ expect_gen(29.0, 1, "3e+1")
+ expect_gen(29.0, 2, "29")
+ expect_gen(29.0, 3, "29")
+ expect_gen(29.0, 4, "29")
+ expect_gen(29.0, 5, "29")
+ expect_gen(29.0, 6, "29")
+
+ expect_gen(2.999, 1, "3")
+ expect_gen(2.999, 2, "3")
+ expect_gen(2.999, 3, "3")
+ expect_gen(2.999, 4, "2.999")
+ expect_gen(2.999, 5, "2.999")
+ expect_gen(2.999, 6, "2.999")
+
+ expect_gen(2.99, 1, "3")
+ expect_gen(2.99, 2, "3")
+ expect_gen(2.99, 3, "2.99")
+ expect_gen(2.99, 4, "2.99")
+ expect_gen(2.99, 5, "2.99")
+ expect_gen(2.99, 6, "2.99")
+
+ expect_gen(2.9, 1, "3")
+ expect_gen(2.9, 2, "2.9")
+ expect_gen(2.9, 3, "2.9")
+ expect_gen(2.9, 4, "2.9")
+ expect_gen(2.9, 5, "2.9")
+ expect_gen(2.9, 6, "2.9")
+
+ expect_gen(2.0, 1, "2")
+ expect_gen(2.0, 2, "2")
+ expect_gen(2.0, 3, "2")
+ expect_gen(2.0, 4, "2")
+ expect_gen(2.0, 5, "2")
+ expect_gen(2.0, 6, "2")
+
+ expect_gen(0.2999, 1, "0.3")
+ expect_gen(0.2999, 2, "0.3")
+ expect_gen(0.2999, 3, "0.3")
+ expect_gen(0.2999, 4, "0.2999")
+ expect_gen(0.2999, 5, "0.2999")
+ expect_gen(0.2999, 6, "0.2999")
+
+ expect_gen(0.299, 1, "0.3")
+ expect_gen(0.299, 2, "0.3")
+ expect_gen(0.299, 3, "0.299")
+ expect_gen(0.299, 4, "0.299")
+ expect_gen(0.299, 5, "0.299")
+ expect_gen(0.299, 6, "0.299")
+
+ expect_gen(0.29, 1, "0.3")
+ expect_gen(0.29, 2, "0.29")
+ expect_gen(0.29, 3, "0.29")
+ expect_gen(0.29, 4, "0.29")
+ expect_gen(0.29, 5, "0.29")
+ expect_gen(0.29, 6, "0.29")
+
+ expect_gen(0.2, 1, "0.2")
+ expect_gen(0.2, 2, "0.2")
+ expect_gen(0.2, 3, "0.2")
+ expect_gen(0.2, 4, "0.2")
+ expect_gen(0.2, 5, "0.2")
+ expect_gen(0.2, 6, "0.2")
+
+ expect_gen(0.02999, 1, "0.03")
+ expect_gen(0.02999, 2, "0.03")
+ expect_gen(0.02999, 3, "0.03")
+ expect_gen(0.02999, 4, "0.02999")
+ expect_gen(0.02999, 5, "0.02999")
+ expect_gen(0.02999, 6, "0.02999")
+
+ expect_gen(0.0299, 1, "0.03")
+ expect_gen(0.0299, 2, "0.03")
+ expect_gen(0.0299, 3, "0.0299")
+ expect_gen(0.0299, 4, "0.0299")
+ expect_gen(0.0299, 5, "0.0299")
+ expect_gen(0.0299, 6, "0.0299")
+
+ expect_gen(0.029, 1, "0.03")
+ expect_gen(0.029, 2, "0.029")
+ expect_gen(0.029, 3, "0.029")
+ expect_gen(0.029, 4, "0.029")
+ expect_gen(0.029, 5, "0.029")
+ expect_gen(0.029, 6, "0.029")
+
+ expect_gen(0.02, 1, "0.02")
+ expect_gen(0.02, 2, "0.02")
+ expect_gen(0.02, 3, "0.02")
+ expect_gen(0.02, 4, "0.02")
+ expect_gen(0.02, 5, "0.02")
+ expect_gen(0.02, 6, "0.02")
+
+ expect_gen(0.002999, 1, "0.003")
+ expect_gen(0.002999, 2, "0.003")
+ expect_gen(0.002999, 3, "0.003")
+ expect_gen(0.002999, 4, "0.002999")
+ expect_gen(0.002999, 5, "0.002999")
+ expect_gen(0.002999, 6, "0.002999")
+
+ expect_gen(0.00299, 1, "0.003")
+ expect_gen(0.00299, 2, "0.003")
+ expect_gen(0.00299, 3, "0.00299")
+ expect_gen(0.00299, 4, "0.00299")
+ expect_gen(0.00299, 5, "0.00299")
+ expect_gen(0.00299, 6, "0.00299")
+
+ expect_gen(0.0029, 1, "0.003")
+ expect_gen(0.0029, 2, "0.0029")
+ expect_gen(0.0029, 3, "0.0029")
+ expect_gen(0.0029, 4, "0.0029")
+ expect_gen(0.0029, 5, "0.0029")
+ expect_gen(0.0029, 6, "0.0029")
+
+ expect_gen(0.002, 1, "0.002")
+ expect_gen(0.002, 2, "0.002")
+ expect_gen(0.002, 3, "0.002")
+ expect_gen(0.002, 4, "0.002")
+ expect_gen(0.002, 5, "0.002")
+ expect_gen(0.002, 6, "0.002")
+
+ expect_gen(0.0002999, 1, "0.0003")
+ expect_gen(0.0002999, 2, "0.0003")
+ expect_gen(0.0002999, 3, "0.0003")
+ expect_gen(0.0002999, 4, "0.0002999")
+ expect_gen(0.0002999, 5, "0.0002999")
+ expect_gen(0.0002999, 6, "0.0002999")
+
+ expect_gen(0.000299, 1, "0.0003")
+ expect_gen(0.000299, 2, "0.0003")
+ expect_gen(0.000299, 3, "0.000299")
+ expect_gen(0.000299, 4, "0.000299")
+ expect_gen(0.000299, 5, "0.000299")
+ expect_gen(0.000299, 6, "0.000299")
+
+ expect_gen(0.00029, 1, "0.0003")
+ expect_gen(0.00029, 2, "0.00029")
+ expect_gen(0.00029, 3, "0.00029")
+ expect_gen(0.00029, 4, "0.00029")
+ expect_gen(0.00029, 5, "0.00029")
+ expect_gen(0.00029, 6, "0.00029")
+
+ expect_gen(0.0002, 1, "0.0002")
+ expect_gen(0.0002, 2, "0.0002")
+ expect_gen(0.0002, 3, "0.0002")
+ expect_gen(0.0002, 4, "0.0002")
+ expect_gen(0.0002, 5, "0.0002")
+ expect_gen(0.0002, 6, "0.0002")
+
+ expect_gen(0.00002999, 1, "3e-5")
+ expect_gen(0.00002999, 2, "3e-5")
+ expect_gen(0.00002999, 3, "3e-5")
+ expect_gen(0.00002999, 4, "2.999e-5")
+ expect_gen(0.00002999, 5, "2.999e-5")
+ expect_gen(0.00002999, 6, "2.999e-5")
+
+ expect_gen(0.0000299, 1, "3e-5")
+ expect_gen(0.0000299, 2, "3e-5")
+ expect_gen(0.0000299, 3, "2.99e-5")
+ expect_gen(0.0000299, 4, "2.99e-5")
+ expect_gen(0.0000299, 5, "2.99e-5")
+ expect_gen(0.0000299, 6, "2.99e-5")
+
+ expect_gen(0.000029, 1, "3e-5")
+ expect_gen(0.000029, 2, "2.9e-5")
+ expect_gen(0.000029, 3, "2.9e-5")
+ expect_gen(0.000029, 4, "2.9e-5")
+ expect_gen(0.000029, 5, "2.9e-5")
+ expect_gen(0.000029, 6, "2.9e-5")
+
+ expect_gen(0.00002, 1, "2e-5")
+ expect_gen(0.00002, 2, "2e-5")
+ expect_gen(0.00002, 3, "2e-5")
+ expect_gen(0.00002, 4, "2e-5")
+ expect_gen(0.00002, 5, "2e-5")
+ expect_gen(0.00002, 6, "2e-5")
+ end
+
+ it "transitions between values of the scientific exponent X" do
+ {% for tc in GEN_TRANSITIONS %}
+ expect_gen(hexfloat({{ tc[0] }}), {{ tc[1] }}, {{ tc[2] }}, file: {{ tc.filename }}, line: {{ tc.line_number }})
+ {% end %}
+ end
+
+ it "UCRT had trouble with rounding this value" do
+ expect_gen(hexfloat("0x1.88e2d605edc3dp+345"), 105, "109995565999999994887854821710219658911365648587951921896774663603198787416706536331386569598149846892544")
+ expect_gen(hexfloat("0x1.88e2d605edc3dp+345"), 19, "1.099955659999999949e+104")
+ expect_gen(hexfloat("0x1.88e2d605edc3dp+345"), 18, "1.09995565999999995e+104")
+ expect_gen(hexfloat("0x1.88e2d605edc3dp+345"), 17, "1.0999556599999999e+104")
+ expect_gen(hexfloat("0x1.88e2d605edc3dp+345"), 16, "1.09995566e+104")
+ expect_gen(hexfloat("0x1.88e2d605edc3dp+345"), 15, "1.09995566e+104")
+ expect_gen(hexfloat("0x1.88e2d605edc3dp+345"), 14, "1.09995566e+104")
+ expect_gen(hexfloat("0x1.88e2d605edc3dp+345"), 13, "1.09995566e+104")
+ expect_gen(hexfloat("0x1.88e2d605edc3dp+345"), 12, "1.09995566e+104")
+ expect_gen(hexfloat("0x1.88e2d605edc3dp+345"), 11, "1.09995566e+104")
+ expect_gen(hexfloat("0x1.88e2d605edc3dp+345"), 10, "1.09995566e+104")
+ expect_gen(hexfloat("0x1.88e2d605edc3dp+345"), 9, "1.09995566e+104")
+ expect_gen(hexfloat("0x1.88e2d605edc3dp+345"), 8, "1.0999557e+104")
+ expect_gen(hexfloat("0x1.88e2d605edc3dp+345"), 7, "1.099956e+104")
+ expect_gen(hexfloat("0x1.88e2d605edc3dp+345"), 6, "1.09996e+104")
+ expect_gen(hexfloat("0x1.88e2d605edc3dp+345"), 5, "1.1e+104")
+ expect_gen(hexfloat("0x1.88e2d605edc3dp+345"), 4, "1.1e+104")
+ expect_gen(hexfloat("0x1.88e2d605edc3dp+345"), 3, "1.1e+104")
+ expect_gen(hexfloat("0x1.88e2d605edc3dp+345"), 2, "1.1e+104")
+ expect_gen(hexfloat("0x1.88e2d605edc3dp+345"), 1, "1e+104")
+ end
+
+ it "more cases that the UCRT had trouble with (e.g. DevCom-1093399)" do
+ expect_gen(hexfloat("0x1.8p+62"), 17, "6.9175290276410819e+18")
+ expect_gen(hexfloat("0x1.0a2742p+17"), 6, "136271")
+ expect_gen(hexfloat("0x1.f8b0f962cdffbp+205"), 14, "1.0137595739223e+62")
+ expect_gen(hexfloat("0x1.f8b0f962cdffbp+205"), 17, "1.0137595739222531e+62")
+ expect_gen(hexfloat("0x1.f8b0f962cdffbp+205"), 51, "1.01375957392225305727423222620636224221808910954041e+62")
+ expect_gen(hexfloat("0x1.f8b0f962cdffbp+205"), 55, "1.013759573922253057274232226206362242218089109540405973e+62")
+ end
+ end
end
diff --git a/spec/std/float_printer/ryu_printf_test_cases.cr b/spec/std/float_printer/ryu_printf_test_cases.cr
index 6c1a3a155692..32448af3bc4d 100644
--- a/spec/std/float_printer/ryu_printf_test_cases.cr
+++ b/spec/std/float_printer/ryu_printf_test_cases.cr
@@ -2695,3 +2695,1673 @@ ALL_BINARY_EXPONENTS = [
{6.123699292104195e+307, 0, 307},
{1.7026387749989901e+308, 0, 308},
] of _
+
+# For brevity, we avoid testing all possible combinations of P and X. Instead, we test:
+# * All values of P where some X can be affected by rounding. (For double, this is [1, 15].)
+# * P == 25, which is arbitrary.
+# * P == numeric_limits::max_exponent10 + 1. This selects fixed notation for numeric_limits::max(),
+# so it's the largest interesting value of P.
+# * Finally, we test the transitions around X == P - 1, ensuring that we can recognize every value of X.
+GEN_TRANSITIONS = [
+ {"0x1.8e757928e0c9dp-14", 1, "9e-5"},
+ {"0x1.8e757928e0c9ep-14", 1, "0.0001"},
+ {"0x1.f212d77318fc5p-11", 1, "0.0009"},
+ {"0x1.f212d77318fc6p-11", 1, "0.001"},
+ {"0x1.374bc6a7ef9dbp-7", 1, "0.009"},
+ {"0x1.374bc6a7ef9dcp-7", 1, "0.01"},
+ {"0x1.851eb851eb851p-4", 1, "0.09"},
+ {"0x1.851eb851eb852p-4", 1, "0.1"},
+ {"0x1.e666666666666p-1", 1, "0.9"},
+ {"0x1.e666666666667p-1", 1, "1"},
+ {"0x1.2ffffffffffffp+3", 1, "9"},
+ {"0x1.3000000000000p+3", 1, "1e+1"},
+ {"0x1.a1554fbdad751p-14", 2, "9.9e-5"},
+ {"0x1.a1554fbdad752p-14", 2, "0.0001"},
+ {"0x1.04d551d68c692p-10", 2, "0.00099"},
+ {"0x1.04d551d68c693p-10", 2, "0.001"},
+ {"0x1.460aa64c2f837p-7", 2, "0.0099"},
+ {"0x1.460aa64c2f838p-7", 2, "0.01"},
+ {"0x1.978d4fdf3b645p-4", 2, "0.099"},
+ {"0x1.978d4fdf3b646p-4", 2, "0.1"},
+ {"0x1.fd70a3d70a3d7p-1", 2, "0.99"},
+ {"0x1.fd70a3d70a3d8p-1", 2, "1"},
+ {"0x1.3e66666666666p+3", 2, "9.9"},
+ {"0x1.3e66666666667p+3", 2, "10"},
+ {"0x1.8dfffffffffffp+6", 2, "99"},
+ {"0x1.8e00000000000p+6", 2, "1e+2"},
+ {"0x1.a3387ecc8eb96p-14", 3, "9.99e-5"},
+ {"0x1.a3387ecc8eb97p-14", 3, "0.0001"},
+ {"0x1.06034f3fd933ep-10", 3, "0.000999"},
+ {"0x1.06034f3fd933fp-10", 3, "0.001"},
+ {"0x1.4784230fcf80dp-7", 3, "0.00999"},
+ {"0x1.4784230fcf80ep-7", 3, "0.01"},
+ {"0x1.99652bd3c3611p-4", 3, "0.0999"},
+ {"0x1.99652bd3c3612p-4", 3, "0.1"},
+ {"0x1.ffbe76c8b4395p-1", 3, "0.999"},
+ {"0x1.ffbe76c8b4396p-1", 3, "1"},
+ {"0x1.3fd70a3d70a3dp+3", 3, "9.99"},
+ {"0x1.3fd70a3d70a3ep+3", 3, "10"},
+ {"0x1.8fcccccccccccp+6", 3, "99.9"},
+ {"0x1.8fccccccccccdp+6", 3, "100"},
+ {"0x1.f3bffffffffffp+9", 3, "999"},
+ {"0x1.f3c0000000000p+9", 3, "1e+3"},
+ {"0x1.a368d04e0ba6ap-14", 4, "9.999e-5"},
+ {"0x1.a368d04e0ba6bp-14", 4, "0.0001"},
+ {"0x1.06218230c7482p-10", 4, "0.0009999"},
+ {"0x1.06218230c7483p-10", 4, "0.001"},
+ {"0x1.47a9e2bcf91a3p-7", 4, "0.009999"},
+ {"0x1.47a9e2bcf91a4p-7", 4, "0.01"},
+ {"0x1.99945b6c3760bp-4", 4, "0.09999"},
+ {"0x1.99945b6c3760cp-4", 4, "0.1"},
+ {"0x1.fff972474538ep-1", 4, "0.9999"},
+ {"0x1.fff972474538fp-1", 4, "1"},
+ {"0x1.3ffbe76c8b439p+3", 4, "9.999"},
+ {"0x1.3ffbe76c8b43ap+3", 4, "10"},
+ {"0x1.8ffae147ae147p+6", 4, "99.99"},
+ {"0x1.8ffae147ae148p+6", 4, "100"},
+ {"0x1.f3f9999999999p+9", 4, "999.9"},
+ {"0x1.f3f999999999ap+9", 4, "1000"},
+ {"0x1.387bfffffffffp+13", 4, "9999"},
+ {"0x1.387c000000000p+13", 4, "1e+4"},
+ {"0x1.a36da54164f19p-14", 5, "9.9999e-5"},
+ {"0x1.a36da54164f1ap-14", 5, "0.0001"},
+ {"0x1.06248748df16fp-10", 5, "0.00099999"},
+ {"0x1.06248748df170p-10", 5, "0.001"},
+ {"0x1.47ada91b16dcbp-7", 5, "0.0099999"},
+ {"0x1.47ada91b16dccp-7", 5, "0.01"},
+ {"0x1.99991361dc93ep-4", 5, "0.099999"},
+ {"0x1.99991361dc93fp-4", 5, "0.1"},
+ {"0x1.ffff583a53b8ep-1", 5, "0.99999"},
+ {"0x1.ffff583a53b8fp-1", 5, "1"},
+ {"0x1.3fff972474538p+3", 5, "9.9999"},
+ {"0x1.3fff972474539p+3", 5, "10"},
+ {"0x1.8fff7ced91687p+6", 5, "99.999"},
+ {"0x1.8fff7ced91688p+6", 5, "100"},
+ {"0x1.f3ff5c28f5c28p+9", 5, "999.99"},
+ {"0x1.f3ff5c28f5c29p+9", 5, "1000"},
+ {"0x1.387f999999999p+13", 5, "9999.9"},
+ {"0x1.387f99999999ap+13", 5, "10000"},
+ {"0x1.869f7ffffffffp+16", 5, "99999"},
+ {"0x1.869f800000000p+16", 5, "1e+5"},
+ {"0x1.a36e20f35445dp-14", 6, "9.99999e-5"},
+ {"0x1.a36e20f35445ep-14", 6, "0.0001"},
+ {"0x1.0624d49814abap-10", 6, "0.000999999"},
+ {"0x1.0624d49814abbp-10", 6, "0.001"},
+ {"0x1.47ae09be19d69p-7", 6, "0.00999999"},
+ {"0x1.47ae09be19d6ap-7", 6, "0.01"},
+ {"0x1.99998c2da04c3p-4", 6, "0.0999999"},
+ {"0x1.99998c2da04c4p-4", 6, "0.1"},
+ {"0x1.ffffef39085f4p-1", 6, "0.999999"},
+ {"0x1.ffffef39085f5p-1", 6, "1"},
+ {"0x1.3ffff583a53b8p+3", 6, "9.99999"},
+ {"0x1.3ffff583a53b9p+3", 6, "10"},
+ {"0x1.8ffff2e48e8a7p+6", 6, "99.9999"},
+ {"0x1.8ffff2e48e8a8p+6", 6, "100"},
+ {"0x1.f3ffef9db22d0p+9", 6, "999.999"},
+ {"0x1.f3ffef9db22d1p+9", 6, "1000"},
+ {"0x1.387ff5c28f5c2p+13", 6, "9999.99"},
+ {"0x1.387ff5c28f5c3p+13", 6, "10000"},
+ {"0x1.869ff33333333p+16", 6, "99999.9"},
+ {"0x1.869ff33333334p+16", 6, "100000"},
+ {"0x1.e847effffffffp+19", 6, "999999"},
+ {"0x1.e847f00000000p+19", 6, "1e+6"},
+ {"0x1.a36e2d51ec34bp-14", 7, "9.999999e-5"},
+ {"0x1.a36e2d51ec34cp-14", 7, "0.0001"},
+ {"0x1.0624dc5333a0ep-10", 7, "0.0009999999"},
+ {"0x1.0624dc5333a0fp-10", 7, "0.001"},
+ {"0x1.47ae136800892p-7", 7, "0.009999999"},
+ {"0x1.47ae136800893p-7", 7, "0.01"},
+ {"0x1.9999984200ab7p-4", 7, "0.09999999"},
+ {"0x1.9999984200ab8p-4", 7, "0.1"},
+ {"0x1.fffffe5280d65p-1", 7, "0.9999999"},
+ {"0x1.fffffe5280d66p-1", 7, "1"},
+ {"0x1.3ffffef39085fp+3", 7, "9.999999"},
+ {"0x1.3ffffef390860p+3", 7, "10"},
+ {"0x1.8ffffeb074a77p+6", 7, "99.99999"},
+ {"0x1.8ffffeb074a78p+6", 7, "100"},
+ {"0x1.f3fffe5c91d14p+9", 7, "999.9999"},
+ {"0x1.f3fffe5c91d15p+9", 7, "1000"},
+ {"0x1.387ffef9db22dp+13", 7, "9999.999"},
+ {"0x1.387ffef9db22ep+13", 7, "10000"},
+ {"0x1.869ffeb851eb8p+16", 7, "99999.99"},
+ {"0x1.869ffeb851eb9p+16", 7, "100000"},
+ {"0x1.e847fe6666666p+19", 7, "999999.9"},
+ {"0x1.e847fe6666667p+19", 7, "1000000"},
+ {"0x1.312cfefffffffp+23", 7, "9999999"},
+ {"0x1.312cff0000000p+23", 7, "1e+7"},
+ {"0x1.a36e2e8e94ffcp-14", 8, "9.9999999e-5"},
+ {"0x1.a36e2e8e94ffdp-14", 8, "0.0001"},
+ {"0x1.0624dd191d1fdp-10", 8, "0.00099999999"},
+ {"0x1.0624dd191d1fep-10", 8, "0.001"},
+ {"0x1.47ae145f6467dp-7", 8, "0.0099999999"},
+ {"0x1.47ae145f6467ep-7", 8, "0.01"},
+ {"0x1.999999773d81cp-4", 8, "0.099999999"},
+ {"0x1.999999773d81dp-4", 8, "0.1"},
+ {"0x1.ffffffd50ce23p-1", 8, "0.99999999"},
+ {"0x1.ffffffd50ce24p-1", 8, "1"},
+ {"0x1.3fffffe5280d6p+3", 8, "9.9999999"},
+ {"0x1.3fffffe5280d7p+3", 8, "10"},
+ {"0x1.8fffffde7210bp+6", 8, "99.999999"},
+ {"0x1.8fffffde7210cp+6", 8, "100"},
+ {"0x1.f3ffffd60e94ep+9", 8, "999.99999"},
+ {"0x1.f3ffffd60e94fp+9", 8, "1000"},
+ {"0x1.387fffe5c91d1p+13", 8, "9999.9999"},
+ {"0x1.387fffe5c91d2p+13", 8, "10000"},
+ {"0x1.869fffdf3b645p+16", 8, "99999.999"},
+ {"0x1.869fffdf3b646p+16", 8, "100000"},
+ {"0x1.e847ffd70a3d7p+19", 8, "999999.99"},
+ {"0x1.e847ffd70a3d8p+19", 8, "1000000"},
+ {"0x1.312cffe666666p+23", 8, "9999999.9"},
+ {"0x1.312cffe666667p+23", 8, "10000000"},
+ {"0x1.7d783fdffffffp+26", 8, "99999999"},
+ {"0x1.7d783fe000000p+26", 8, "1e+8"},
+ {"0x1.a36e2eae3f7a7p-14", 9, "9.99999999e-5"},
+ {"0x1.a36e2eae3f7a8p-14", 9, "0.0001"},
+ {"0x1.0624dd2ce7ac8p-10", 9, "0.000999999999"},
+ {"0x1.0624dd2ce7ac9p-10", 9, "0.001"},
+ {"0x1.47ae14782197bp-7", 9, "0.00999999999"},
+ {"0x1.47ae14782197cp-7", 9, "0.01"},
+ {"0x1.9999999629fd9p-4", 9, "0.0999999999"},
+ {"0x1.9999999629fdap-4", 9, "0.1"},
+ {"0x1.fffffffbb47d0p-1", 9, "0.999999999"},
+ {"0x1.fffffffbb47d1p-1", 9, "1"},
+ {"0x1.3ffffffd50ce2p+3", 9, "9.99999999"},
+ {"0x1.3ffffffd50ce3p+3", 9, "10"},
+ {"0x1.8ffffffca501ap+6", 9, "99.9999999"},
+ {"0x1.8ffffffca501bp+6", 9, "100"},
+ {"0x1.f3fffffbce421p+9", 9, "999.999999"},
+ {"0x1.f3fffffbce422p+9", 9, "1000"},
+ {"0x1.387ffffd60e94p+13", 9, "9999.99999"},
+ {"0x1.387ffffd60e95p+13", 9, "10000"},
+ {"0x1.869ffffcb923ap+16", 9, "99999.9999"},
+ {"0x1.869ffffcb923bp+16", 9, "100000"},
+ {"0x1.e847fffbe76c8p+19", 9, "999999.999"},
+ {"0x1.e847fffbe76c9p+19", 9, "1000000"},
+ {"0x1.312cfffd70a3dp+23", 9, "9999999.99"},
+ {"0x1.312cfffd70a3ep+23", 9, "10000000"},
+ {"0x1.7d783ffccccccp+26", 9, "99999999.9"},
+ {"0x1.7d783ffcccccdp+26", 9, "100000000"},
+ {"0x1.dcd64ffbfffffp+29", 9, "999999999"},
+ {"0x1.dcd64ffc00000p+29", 9, "1e+9"},
+ {"0x1.a36e2eb16a205p-14", 10, "9.999999999e-5"},
+ {"0x1.a36e2eb16a206p-14", 10, "0.0001"},
+ {"0x1.0624dd2ee2543p-10", 10, "0.0009999999999"},
+ {"0x1.0624dd2ee2544p-10", 10, "0.001"},
+ {"0x1.47ae147a9ae94p-7", 10, "0.009999999999"},
+ {"0x1.47ae147a9ae95p-7", 10, "0.01"},
+ {"0x1.9999999941a39p-4", 10, "0.09999999999"},
+ {"0x1.9999999941a3ap-4", 10, "0.1"},
+ {"0x1.ffffffff920c8p-1", 10, "0.9999999999"},
+ {"0x1.ffffffff920c9p-1", 10, "1"},
+ {"0x1.3fffffffbb47dp+3", 10, "9.999999999"},
+ {"0x1.3fffffffbb47ep+3", 10, "10"},
+ {"0x1.8fffffffaa19cp+6", 10, "99.99999999"},
+ {"0x1.8fffffffaa19dp+6", 10, "100"},
+ {"0x1.f3ffffff94a03p+9", 10, "999.9999999"},
+ {"0x1.f3ffffff94a04p+9", 10, "1000"},
+ {"0x1.387fffffbce42p+13", 10, "9999.999999"},
+ {"0x1.387fffffbce43p+13", 10, "10000"},
+ {"0x1.869fffffac1d2p+16", 10, "99999.99999"},
+ {"0x1.869fffffac1d3p+16", 10, "100000"},
+ {"0x1.e847ffff97247p+19", 10, "999999.9999"},
+ {"0x1.e847ffff97248p+19", 10, "1000000"},
+ {"0x1.312cffffbe76cp+23", 10, "9999999.999"},
+ {"0x1.312cffffbe76dp+23", 10, "10000000"},
+ {"0x1.7d783fffae147p+26", 10, "99999999.99"},
+ {"0x1.7d783fffae148p+26", 10, "100000000"},
+ {"0x1.dcd64fff99999p+29", 10, "999999999.9"},
+ {"0x1.dcd64fff9999ap+29", 10, "1000000000"},
+ {"0x1.2a05f1ffbffffp+33", 10, "9999999999"},
+ {"0x1.2a05f1ffc0000p+33", 10, "1e+10"},
+ {"0x1.a36e2eb1bb30fp-14", 11, "9.9999999999e-5"},
+ {"0x1.a36e2eb1bb310p-14", 11, "0.0001"},
+ {"0x1.0624dd2f14fe9p-10", 11, "0.00099999999999"},
+ {"0x1.0624dd2f14feap-10", 11, "0.001"},
+ {"0x1.47ae147ada3e3p-7", 11, "0.0099999999999"},
+ {"0x1.47ae147ada3e4p-7", 11, "0.01"},
+ {"0x1.9999999990cdcp-4", 11, "0.099999999999"},
+ {"0x1.9999999990cddp-4", 11, "0.1"},
+ {"0x1.fffffffff5014p-1", 11, "0.99999999999"},
+ {"0x1.fffffffff5015p-1", 11, "1"},
+ {"0x1.3ffffffff920cp+3", 11, "9.9999999999"},
+ {"0x1.3ffffffff920dp+3", 11, "10"},
+ {"0x1.8ffffffff768fp+6", 11, "99.999999999"},
+ {"0x1.8ffffffff7690p+6", 11, "100"},
+ {"0x1.f3fffffff5433p+9", 11, "999.99999999"},
+ {"0x1.f3fffffff5434p+9", 11, "1000"},
+ {"0x1.387ffffff94a0p+13", 11, "9999.9999999"},
+ {"0x1.387ffffff94a1p+13", 11, "10000"},
+ {"0x1.869ffffff79c8p+16", 11, "99999.999999"},
+ {"0x1.869ffffff79c9p+16", 11, "100000"},
+ {"0x1.e847fffff583ap+19", 11, "999999.99999"},
+ {"0x1.e847fffff583bp+19", 11, "1000000"},
+ {"0x1.312cfffff9724p+23", 11, "9999999.9999"},
+ {"0x1.312cfffff9725p+23", 11, "10000000"},
+ {"0x1.7d783ffff7cedp+26", 11, "99999999.999"},
+ {"0x1.7d783ffff7ceep+26", 11, "100000000"},
+ {"0x1.dcd64ffff5c28p+29", 11, "999999999.99"},
+ {"0x1.dcd64ffff5c29p+29", 11, "1000000000"},
+ {"0x1.2a05f1fff9999p+33", 11, "9999999999.9"},
+ {"0x1.2a05f1fff999ap+33", 11, "10000000000"},
+ {"0x1.74876e7ff7fffp+36", 11, "99999999999"},
+ {"0x1.74876e7ff8000p+36", 11, "1e+11"},
+ {"0x1.a36e2eb1c34c3p-14", 12, "9.99999999999e-5"},
+ {"0x1.a36e2eb1c34c4p-14", 12, "0.0001"},
+ {"0x1.0624dd2f1a0fap-10", 12, "0.000999999999999"},
+ {"0x1.0624dd2f1a0fbp-10", 12, "0.001"},
+ {"0x1.47ae147ae0938p-7", 12, "0.00999999999999"},
+ {"0x1.47ae147ae0939p-7", 12, "0.01"},
+ {"0x1.9999999998b86p-4", 12, "0.0999999999999"},
+ {"0x1.9999999998b87p-4", 12, "0.1"},
+ {"0x1.fffffffffee68p-1", 12, "0.999999999999"},
+ {"0x1.fffffffffee69p-1", 12, "1"},
+ {"0x1.3fffffffff501p+3", 12, "9.99999999999"},
+ {"0x1.3fffffffff502p+3", 12, "10"},
+ {"0x1.8fffffffff241p+6", 12, "99.9999999999"},
+ {"0x1.8fffffffff242p+6", 12, "100"},
+ {"0x1.f3fffffffeed1p+9", 12, "999.999999999"},
+ {"0x1.f3fffffffeed2p+9", 12, "1000"},
+ {"0x1.387fffffff543p+13", 12, "9999.99999999"},
+ {"0x1.387fffffff544p+13", 12, "10000"},
+ {"0x1.869fffffff294p+16", 12, "99999.9999999"},
+ {"0x1.869fffffff295p+16", 12, "100000"},
+ {"0x1.e847fffffef39p+19", 12, "999999.999999"},
+ {"0x1.e847fffffef3ap+19", 12, "1000000"},
+ {"0x1.312cffffff583p+23", 12, "9999999.99999"},
+ {"0x1.312cffffff584p+23", 12, "10000000"},
+ {"0x1.7d783fffff2e4p+26", 12, "99999999.9999"},
+ {"0x1.7d783fffff2e5p+26", 12, "100000000"},
+ {"0x1.dcd64ffffef9dp+29", 12, "999999999.999"},
+ {"0x1.dcd64ffffef9ep+29", 12, "1000000000"},
+ {"0x1.2a05f1ffff5c2p+33", 12, "9999999999.99"},
+ {"0x1.2a05f1ffff5c3p+33", 12, "10000000000"},
+ {"0x1.74876e7fff333p+36", 12, "99999999999.9"},
+ {"0x1.74876e7fff334p+36", 12, "100000000000"},
+ {"0x1.d1a94a1ffefffp+39", 12, "999999999999"},
+ {"0x1.d1a94a1fff000p+39", 12, "1e+12"},
+ {"0x1.a36e2eb1c41bbp-14", 13, "9.999999999999e-5"},
+ {"0x1.a36e2eb1c41bcp-14", 13, "0.0001"},
+ {"0x1.0624dd2f1a915p-10", 13, "0.0009999999999999"},
+ {"0x1.0624dd2f1a916p-10", 13, "0.001"},
+ {"0x1.47ae147ae135ap-7", 13, "0.009999999999999"},
+ {"0x1.47ae147ae135bp-7", 13, "0.01"},
+ {"0x1.9999999999831p-4", 13, "0.09999999999999"},
+ {"0x1.9999999999832p-4", 13, "0.1"},
+ {"0x1.ffffffffffe3dp-1", 13, "0.9999999999999"},
+ {"0x1.ffffffffffe3ep-1", 13, "1"},
+ {"0x1.3fffffffffee6p+3", 13, "9.999999999999"},
+ {"0x1.3fffffffffee7p+3", 13, "10"},
+ {"0x1.8fffffffffea0p+6", 13, "99.99999999999"},
+ {"0x1.8fffffffffea1p+6", 13, "100"},
+ {"0x1.f3ffffffffe48p+9", 13, "999.9999999999"},
+ {"0x1.f3ffffffffe49p+9", 13, "1000"},
+ {"0x1.387fffffffeedp+13", 13, "9999.999999999"},
+ {"0x1.387fffffffeeep+13", 13, "10000"},
+ {"0x1.869fffffffea8p+16", 13, "99999.99999999"},
+ {"0x1.869fffffffea9p+16", 13, "100000"},
+ {"0x1.e847ffffffe52p+19", 13, "999999.9999999"},
+ {"0x1.e847ffffffe53p+19", 13, "1000000"},
+ {"0x1.312cffffffef3p+23", 13, "9999999.999999"},
+ {"0x1.312cffffffef4p+23", 13, "10000000"},
+ {"0x1.7d783fffffeb0p+26", 13, "99999999.99999"},
+ {"0x1.7d783fffffeb1p+26", 13, "100000000"},
+ {"0x1.dcd64fffffe5cp+29", 13, "999999999.9999"},
+ {"0x1.dcd64fffffe5dp+29", 13, "1000000000"},
+ {"0x1.2a05f1ffffef9p+33", 13, "9999999999.999"},
+ {"0x1.2a05f1ffffefap+33", 13, "10000000000"},
+ {"0x1.74876e7fffeb8p+36", 13, "99999999999.99"},
+ {"0x1.74876e7fffeb9p+36", 13, "100000000000"},
+ {"0x1.d1a94a1fffe66p+39", 13, "999999999999.9"},
+ {"0x1.d1a94a1fffe67p+39", 13, "1000000000000"},
+ {"0x1.2309ce53ffeffp+43", 13, "9999999999999"},
+ {"0x1.2309ce53fff00p+43", 13, "1e+13"},
+ {"0x1.a36e2eb1c4307p-14", 14, "9.9999999999999e-5"},
+ {"0x1.a36e2eb1c4308p-14", 14, "0.0001"},
+ {"0x1.0624dd2f1a9e4p-10", 14, "0.00099999999999999"},
+ {"0x1.0624dd2f1a9e5p-10", 14, "0.001"},
+ {"0x1.47ae147ae145ep-7", 14, "0.0099999999999999"},
+ {"0x1.47ae147ae145fp-7", 14, "0.01"},
+ {"0x1.9999999999975p-4", 14, "0.099999999999999"},
+ {"0x1.9999999999976p-4", 14, "0.1"},
+ {"0x1.fffffffffffd2p-1", 14, "0.99999999999999"},
+ {"0x1.fffffffffffd3p-1", 14, "1"},
+ {"0x1.3ffffffffffe3p+3", 14, "9.9999999999999"},
+ {"0x1.3ffffffffffe4p+3", 14, "10"},
+ {"0x1.8ffffffffffdcp+6", 14, "99.999999999999"},
+ {"0x1.8ffffffffffddp+6", 14, "100"},
+ {"0x1.f3fffffffffd4p+9", 14, "999.99999999999"},
+ {"0x1.f3fffffffffd5p+9", 14, "1000"},
+ {"0x1.387ffffffffe4p+13", 14, "9999.9999999999"},
+ {"0x1.387ffffffffe5p+13", 14, "10000"},
+ {"0x1.869ffffffffddp+16", 14, "99999.999999999"},
+ {"0x1.869ffffffffdep+16", 14, "100000"},
+ {"0x1.e847fffffffd5p+19", 14, "999999.99999999"},
+ {"0x1.e847fffffffd6p+19", 14, "1000000"},
+ {"0x1.312cfffffffe5p+23", 14, "9999999.9999999"},
+ {"0x1.312cfffffffe6p+23", 14, "10000000"},
+ {"0x1.7d783ffffffdep+26", 14, "99999999.999999"},
+ {"0x1.7d783ffffffdfp+26", 14, "100000000"},
+ {"0x1.dcd64ffffffd6p+29", 14, "999999999.99999"},
+ {"0x1.dcd64ffffffd7p+29", 14, "1000000000"},
+ {"0x1.2a05f1fffffe5p+33", 14, "9999999999.9999"},
+ {"0x1.2a05f1fffffe6p+33", 14, "10000000000"},
+ {"0x1.74876e7ffffdfp+36", 14, "99999999999.999"},
+ {"0x1.74876e7ffffe0p+36", 14, "100000000000"},
+ {"0x1.d1a94a1ffffd7p+39", 14, "999999999999.99"},
+ {"0x1.d1a94a1ffffd8p+39", 14, "1000000000000"},
+ {"0x1.2309ce53fffe6p+43", 14, "9999999999999.9"},
+ {"0x1.2309ce53fffe7p+43", 14, "10000000000000"},
+ {"0x1.6bcc41e8fffdfp+46", 14, "99999999999999"},
+ {"0x1.6bcc41e8fffe0p+46", 14, "1e+14"},
+ {"0x1.a36e2eb1c4328p-14", 15, "9.99999999999999e-5"},
+ {"0x1.a36e2eb1c4329p-14", 15, "0.0001"},
+ {"0x1.0624dd2f1a9f9p-10", 15, "0.000999999999999999"},
+ {"0x1.0624dd2f1a9fap-10", 15, "0.001"},
+ {"0x1.47ae147ae1477p-7", 15, "0.00999999999999999"},
+ {"0x1.47ae147ae1478p-7", 15, "0.01"},
+ {"0x1.9999999999995p-4", 15, "0.0999999999999999"},
+ {"0x1.9999999999996p-4", 15, "0.1"},
+ {"0x1.ffffffffffffbp-1", 15, "0.999999999999999"},
+ {"0x1.ffffffffffffcp-1", 15, "1"},
+ {"0x1.3fffffffffffdp+3", 15, "9.99999999999999"},
+ {"0x1.3fffffffffffep+3", 15, "10"},
+ {"0x1.8fffffffffffcp+6", 15, "99.9999999999999"},
+ {"0x1.8fffffffffffdp+6", 15, "100"},
+ {"0x1.f3ffffffffffbp+9", 15, "999.999999999999"},
+ {"0x1.f3ffffffffffcp+9", 15, "1000"},
+ {"0x1.387fffffffffdp+13", 15, "9999.99999999999"},
+ {"0x1.387fffffffffep+13", 15, "10000"},
+ {"0x1.869fffffffffcp+16", 15, "99999.9999999999"},
+ {"0x1.869fffffffffdp+16", 15, "100000"},
+ {"0x1.e847ffffffffbp+19", 15, "999999.999999999"},
+ {"0x1.e847ffffffffcp+19", 15, "1000000"},
+ {"0x1.312cffffffffdp+23", 15, "9999999.99999999"},
+ {"0x1.312cffffffffep+23", 15, "10000000"},
+ {"0x1.7d783fffffffcp+26", 15, "99999999.9999999"},
+ {"0x1.7d783fffffffdp+26", 15, "100000000"},
+ {"0x1.dcd64fffffffbp+29", 15, "999999999.999999"},
+ {"0x1.dcd64fffffffcp+29", 15, "1000000000"},
+ {"0x1.2a05f1ffffffdp+33", 15, "9999999999.99999"},
+ {"0x1.2a05f1ffffffep+33", 15, "10000000000"},
+ {"0x1.74876e7fffffcp+36", 15, "99999999999.9999"},
+ {"0x1.74876e7fffffdp+36", 15, "100000000000"},
+ {"0x1.d1a94a1fffffbp+39", 15, "999999999999.999"},
+ {"0x1.d1a94a1fffffcp+39", 15, "1000000000000"},
+ {"0x1.2309ce53ffffdp+43", 15, "9999999999999.99"},
+ {"0x1.2309ce53ffffep+43", 15, "10000000000000"},
+ {"0x1.6bcc41e8ffffcp+46", 15, "99999999999999.9"},
+ {"0x1.6bcc41e8ffffdp+46", 15, "100000000000000"},
+ {"0x1.c6bf52633fffbp+49", 15, "999999999999999"},
+ {"0x1.c6bf52633fffcp+49", 15, "1e+15"},
+ {"0x1.1c37937e07fffp+53", 16, "9999999999999998"},
+ {"0x1.1c37937e08000p+53", 16, "1e+16"},
+ {"0x1.6345785d89fffp+56", 17, "99999999999999984"},
+ {"0x1.6345785d8a000p+56", 17, "1e+17"},
+ {"0x1.bc16d674ec7ffp+59", 18, "999999999999999872"},
+ {"0x1.bc16d674ec800p+59", 18, "1e+18"},
+ {"0x1.158e460913cffp+63", 19, "9999999999999997952"},
+ {"0x1.158e460913d00p+63", 19, "1e+19"},
+ {"0x1.5af1d78b58c3fp+66", 20, "99999999999999983616"},
+ {"0x1.5af1d78b58c40p+66", 20, "1e+20"},
+ {"0x1.b1ae4d6e2ef4fp+69", 21, "999999999999999868928"},
+ {"0x1.b1ae4d6e2ef50p+69", 21, "1e+21"},
+ {"0x1.0f0cf064dd591p+73", 22, "9999999999999997902848"},
+ {"0x1.0f0cf064dd592p+73", 22, "1e+22"},
+ {"0x1.52d02c7e14af6p+76", 23, "99999999999999991611392"},
+ {"0x1.52d02c7e14af7p+76", 23, "1.0000000000000000838861e+23"},
+ {"0x1.a784379d99db4p+79", 24, "999999999999999983222784"},
+ {"0x1.a784379d99db5p+79", 24, "1.00000000000000011744051e+24"},
+ {"0x1.a36e2eb1c432cp-14", 25, "9.999999999999999123964645e-5"},
+ {"0x1.a36e2eb1c432dp-14", 25, "0.0001000000000000000047921736"},
+ {"0x1.0624dd2f1a9fbp-10", 25, "0.0009999999999999998039762472"},
+ {"0x1.0624dd2f1a9fcp-10", 25, "0.001000000000000000020816682"},
+ {"0x1.47ae147ae147ap-7", 25, "0.009999999999999998473443341"},
+ {"0x1.47ae147ae147bp-7", 25, "0.01000000000000000020816682"},
+ {"0x1.9999999999999p-4", 25, "0.09999999999999999167332732"},
+ {"0x1.999999999999ap-4", 25, "0.1000000000000000055511151"},
+ {"0x1.fffffffffffffp-1", 25, "0.9999999999999998889776975"},
+ {"0x1.0000000000000p+0", 25, "1"},
+ {"0x1.3ffffffffffffp+3", 25, "9.999999999999998223643161"},
+ {"0x1.4000000000000p+3", 25, "10"},
+ {"0x1.8ffffffffffffp+6", 25, "99.99999999999998578914528"},
+ {"0x1.9000000000000p+6", 25, "100"},
+ {"0x1.f3fffffffffffp+9", 25, "999.9999999999998863131623"},
+ {"0x1.f400000000000p+9", 25, "1000"},
+ {"0x1.387ffffffffffp+13", 25, "9999.999999999998181010596"},
+ {"0x1.3880000000000p+13", 25, "10000"},
+ {"0x1.869ffffffffffp+16", 25, "99999.99999999998544808477"},
+ {"0x1.86a0000000000p+16", 25, "100000"},
+ {"0x1.e847fffffffffp+19", 25, "999999.9999999998835846782"},
+ {"0x1.e848000000000p+19", 25, "1000000"},
+ {"0x1.312cfffffffffp+23", 25, "9999999.999999998137354851"},
+ {"0x1.312d000000000p+23", 25, "10000000"},
+ {"0x1.7d783ffffffffp+26", 25, "99999999.99999998509883881"},
+ {"0x1.7d78400000000p+26", 25, "100000000"},
+ {"0x1.dcd64ffffffffp+29", 25, "999999999.9999998807907104"},
+ {"0x1.dcd6500000000p+29", 25, "1000000000"},
+ {"0x1.2a05f1fffffffp+33", 25, "9999999999.999998092651367"},
+ {"0x1.2a05f20000000p+33", 25, "10000000000"},
+ {"0x1.74876e7ffffffp+36", 25, "99999999999.99998474121094"},
+ {"0x1.74876e8000000p+36", 25, "100000000000"},
+ {"0x1.d1a94a1ffffffp+39", 25, "999999999999.9998779296875"},
+ {"0x1.d1a94a2000000p+39", 25, "1000000000000"},
+ {"0x1.2309ce53fffffp+43", 25, "9999999999999.998046875"},
+ {"0x1.2309ce5400000p+43", 25, "10000000000000"},
+ {"0x1.6bcc41e8fffffp+46", 25, "99999999999999.984375"},
+ {"0x1.6bcc41e900000p+46", 25, "100000000000000"},
+ {"0x1.c6bf52633ffffp+49", 25, "999999999999999.875"},
+ {"0x1.c6bf526340000p+49", 25, "1000000000000000"},
+ {"0x1.1c37937e07fffp+53", 25, "9999999999999998"},
+ {"0x1.1c37937e08000p+53", 25, "10000000000000000"},
+ {"0x1.6345785d89fffp+56", 25, "99999999999999984"},
+ {"0x1.6345785d8a000p+56", 25, "100000000000000000"},
+ {"0x1.bc16d674ec7ffp+59", 25, "999999999999999872"},
+ {"0x1.bc16d674ec800p+59", 25, "1000000000000000000"},
+ {"0x1.158e460913cffp+63", 25, "9999999999999997952"},
+ {"0x1.158e460913d00p+63", 25, "10000000000000000000"},
+ {"0x1.5af1d78b58c3fp+66", 25, "99999999999999983616"},
+ {"0x1.5af1d78b58c40p+66", 25, "100000000000000000000"},
+ {"0x1.b1ae4d6e2ef4fp+69", 25, "999999999999999868928"},
+ {"0x1.b1ae4d6e2ef50p+69", 25, "1000000000000000000000"},
+ {"0x1.0f0cf064dd591p+73", 25, "9999999999999997902848"},
+ {"0x1.0f0cf064dd592p+73", 25, "10000000000000000000000"},
+ {"0x1.52d02c7e14af6p+76", 25, "99999999999999991611392"},
+ {"0x1.52d02c7e14af7p+76", 25, "100000000000000008388608"},
+ {"0x1.a784379d99db4p+79", 25, "999999999999999983222784"},
+ {"0x1.a784379d99db5p+79", 25, "1000000000000000117440512"},
+ {"0x1.08b2a2c280290p+83", 25, "9999999999999998758486016"},
+ {"0x1.08b2a2c280291p+83", 25, "1.000000000000000090596966e+25"},
+ {"0x1.4adf4b7320334p+86", 26, "99999999999999987584860160"},
+ {"0x1.4adf4b7320335p+86", 26, "1.0000000000000000476472934e+26"},
+ {"0x1.9d971e4fe8401p+89", 27, "999999999999999875848601600"},
+ {"0x1.9d971e4fe8402p+89", 27, "1.00000000000000001328755507e+27"},
+ {"0x1.027e72f1f1281p+93", 28, "9999999999999999583119736832"},
+ {"0x1.027e72f1f1282p+93", 28, "1.000000000000000178214299238e+28"},
+ {"0x1.431e0fae6d721p+96", 29, "99999999999999991433150857216"},
+ {"0x1.431e0fae6d722p+96", 29, "1.0000000000000000902533690163e+29"},
+ {"0x1.93e5939a08ce9p+99", 30, "999999999999999879147136483328"},
+ {"0x1.93e5939a08ceap+99", 30, "1.00000000000000001988462483866e+30"},
+ {"0x1.f8def8808b024p+102", 31, "9999999999999999635896294965248"},
+ {"0x1.f8def8808b025p+102", 31, "1.000000000000000076179620180787e+31"},
+ {"0x1.3b8b5b5056e16p+106", 32, "99999999999999987351763694911488"},
+ {"0x1.3b8b5b5056e17p+106", 32, "1.0000000000000000536616220439347e+32"},
+ {"0x1.8a6e32246c99cp+109", 33, "999999999999999945575230987042816"},
+ {"0x1.8a6e32246c99dp+109", 33, "1.00000000000000008969041906289869e+33"},
+ {"0x1.ed09bead87c03p+112", 34, "9999999999999999455752309870428160"},
+ {"0x1.ed09bead87c04p+112", 34, "1.000000000000000060867381447727514e+34"},
+ {"0x1.3426172c74d82p+116", 35, "99999999999999996863366107917975552"},
+ {"0x1.3426172c74d83p+116", 35, "1.0000000000000001531011018162752717e+35"},
+ {"0x1.812f9cf7920e2p+119", 36, "999999999999999894846684784341549056"},
+ {"0x1.812f9cf7920e3p+119", 36, "1.00000000000000004242063737401796198e+36"},
+ {"0x1.e17b84357691bp+122", 37, "9999999999999999538762658202121142272"},
+ {"0x1.e17b84357691cp+122", 37, "1.00000000000000007193542789195324457e+37"},
+ {"0x1.2ced32a16a1b1p+126", 38, "99999999999999997748809823456034029568"},
+ {"0x1.2ced32a16a1b2p+126", 38, "1.0000000000000001663827575493461488435e+38"},
+ {"0x1.78287f49c4a1dp+129", 39, "999999999999999939709166371603178586112"},
+ {"0x1.78287f49c4a1ep+129", 39, "1.00000000000000009082489382343182542438e+39"},
+ {"0x1.d6329f1c35ca4p+132", 40, "9999999999999999094860208812374492184576"},
+ {"0x1.d6329f1c35ca5p+132", 40, "1.000000000000000030378602842700366689075e+40"},
+ {"0x1.25dfa371a19e6p+136", 41, "99999999999999981277195531206711524196352"},
+ {"0x1.25dfa371a19e7p+136", 41, "1.0000000000000000062000864504077831949517e+41"},
+ {"0x1.6f578c4e0a060p+139", 42, "999999999999999890143207767403382423158784"},
+ {"0x1.6f578c4e0a061p+139", 42, "1.00000000000000004488571267807591678554931e+42"},
+ {"0x1.cb2d6f618c878p+142", 43, "9999999999999998901432077674033824231587840"},
+ {"0x1.cb2d6f618c879p+142", 43, "1.000000000000000013937211695941409913071206e+43"},
+ {"0x1.1efc659cf7d4bp+146", 44, "99999999999999989014320776740338242315878400"},
+ {"0x1.1efc659cf7d4cp+146", 44, "1.0000000000000000882136140530642264070186598e+44"},
+ {"0x1.66bb7f0435c9ep+149", 45, "999999999999999929757289024535551219930759168"},
+ {"0x1.66bb7f0435c9fp+149", 45, "1.00000000000000008821361405306422640701865984e+45"},
+ {"0x1.c06a5ec5433c6p+152", 46, "9999999999999999931398190359470212947659194368"},
+ {"0x1.c06a5ec5433c7p+152", 46, "1.000000000000000119904879058769961444436239974e+46"},
+ {"0x1.18427b3b4a05bp+156", 47, "99999999999999984102174700855949311516153479168"},
+ {"0x1.18427b3b4a05cp+156", 47, "1.0000000000000000438458430450761973546340476518e+47"},
+ {"0x1.5e531a0a1c872p+159", 48, "999999999999999881586566215862833963056037363712"},
+ {"0x1.5e531a0a1c873p+159", 48, "1.00000000000000004384584304507619735463404765184e+48"},
+ {"0x1.b5e7e08ca3a8fp+162", 49, "9999999999999999464902769475481793196872414789632"},
+ {"0x1.b5e7e08ca3a90p+162", 49, "1.000000000000000076297698410918870032949649709466e+49"},
+ {"0x1.11b0ec57e6499p+166", 50, "99999999999999986860582406952576489172979654066176"},
+ {"0x1.11b0ec57e649ap+166", 50, "1.0000000000000000762976984109188700329496497094656e+50"},
+ {"0x1.561d276ddfdc0p+169", 51, "999999999999999993220948674361627976461708441944064"},
+ {"0x1.561d276ddfdc1p+169", 51, "1.00000000000000015937444814747611208943759097698714e+51"},
+ {"0x1.aba4714957d30p+172", 52, "9999999999999999932209486743616279764617084419440640"},
+ {"0x1.aba4714957d31p+172", 52, "1.000000000000000126143748252853215266842414469978522e+52"},
+ {"0x1.0b46c6cdd6e3ep+176", 53, "99999999999999999322094867436162797646170844194406400"},
+ {"0x1.0b46c6cdd6e3fp+176", 53, "1.0000000000000002058974279999481676410708380867991962e+53"},
+ {"0x1.4e1878814c9cdp+179", 54, "999999999999999908150356944127012110618056584002011136"},
+ {"0x1.4e1878814c9cep+179", 54, "1.00000000000000007829154040459624384230536029988611686e+54"},
+ {"0x1.a19e96a19fc40p+182", 55, "9999999999999998741221202520331657642805958408251899904"},
+ {"0x1.a19e96a19fc41p+182", 55, "1.000000000000000010235067020408551149630438813532474573e+55"},
+ {"0x1.05031e2503da8p+186", 56, "99999999999999987412212025203316576428059584082518999040"},
+ {"0x1.05031e2503da9p+186", 56, "1.0000000000000000919028350814337823808403445971568453222e+56"},
+ {"0x1.4643e5ae44d12p+189", 57, "999999999999999874122120252033165764280595840825189990400"},
+ {"0x1.4643e5ae44d13p+189", 57, "1.00000000000000004834669211555365905752839484589051425587e+57"},
+ {"0x1.97d4df19d6057p+192", 58, "9999999999999999438119489974413630815797154428513196965888"},
+ {"0x1.97d4df19d6058p+192", 58, "1.000000000000000083191606488257757716177954646903579108966e+58"},
+ {"0x1.fdca16e04b86dp+195", 59, "99999999999999997168788049560464200849936328366177157906432"},
+ {"0x1.fdca16e04b86ep+195", 59, "1.0000000000000000831916064882577577161779546469035791089664e+59"},
+ {"0x1.3e9e4e4c2f344p+199", 60, "999999999999999949387135297074018866963645011013410073083904"},
+ {"0x1.3e9e4e4c2f345p+199", 60, "1.00000000000000012779309688531900399924939119220030212092723e+60"},
+ {"0x1.8e45e1df3b015p+202", 61, "9999999999999999493871352970740188669636450110134100730839040"},
+ {"0x1.8e45e1df3b016p+202", 61, "1.000000000000000092111904567670006972792241955962923711358566e+61"},
+ {"0x1.f1d75a5709c1ap+205", 62, "99999999999999992084218144295482124579792562202350734542897152"},
+ {"0x1.f1d75a5709c1bp+205", 62, "1.0000000000000000350219968594316117304608031779831182560487014e+62"},
+ {"0x1.3726987666190p+209", 63, "999999999999999875170255276364105051932774599639662981181079552"},
+ {"0x1.3726987666191p+209", 63, "1.00000000000000005785795994272696982739337868917504043817264742e+63"},
+ {"0x1.84f03e93ff9f4p+212", 64, "9999999999999998751702552763641050519327745996396629811810795520"},
+ {"0x1.84f03e93ff9f5p+212", 64, "1.00000000000000002132041900945439687230125787126796494677433385e+64"},
+ {"0x1.e62c4e38ff872p+215", 65, "99999999999999999209038626283633850822756121694230455365568299008"},
+ {"0x1.e62c4e38ff873p+215", 65, "1.0000000000000001090105172493085719645223478342449461261302864282e+65"},
+ {"0x1.2fdbb0e39fb47p+219", 66, "999999999999999945322333868247445125709646570021247924665841614848"},
+ {"0x1.2fdbb0e39fb48p+219", 66, "1.00000000000000013239454344660301865578130515770547444062520711578e+66"},
+ {"0x1.7bd29d1c87a19p+222", 67, "9999999999999999827367757839185598317239782875580932278577147150336"},
+ {"0x1.7bd29d1c87a1ap+222", 67, "1.000000000000000132394543446603018655781305157705474440625207115776e+67"},
+ {"0x1.dac74463a989fp+225", 68, "99999999999999995280522225138166806691251291352861698530421623488512"},
+ {"0x1.dac74463a98a0p+225", 68, "1.000000000000000072531436381529235126158374409646521955518210155479e+68"},
+ {"0x1.28bc8abe49f63p+229", 69, "999999999999999880969493773293127831364996015857874003175819882528768"},
+ {"0x1.28bc8abe49f64p+229", 69, "1.00000000000000007253143638152923512615837440964652195551821015547904e+69"},
+ {"0x1.72ebad6ddc73cp+232", 70, "9999999999999999192818822949403492903236716946156035936442979371188224"},
+ {"0x1.72ebad6ddc73dp+232", 70, "1.00000000000000007253143638152923512615837440964652195551821015547904e+70"},
+ {"0x1.cfa698c95390bp+235", 71, "99999999999999991928188229494034929032367169461560359364429793711882240"},
+ {"0x1.cfa698c95390cp+235", 71, "1.0000000000000000418815255642114579589914338666403382831434277118069965e+71"},
+ {"0x1.21c81f7dd43a7p+239", 72, "999999999999999943801810948794571024057224129020550531544123892056457216"},
+ {"0x1.21c81f7dd43a8p+239", 72, "1.00000000000000013996124017962834489392564360426012603474273153155753574e+72"},
+ {"0x1.6a3a275d49491p+242", 73, "9999999999999999830336967949613257980309080240684656321838454199566729216"},
+ {"0x1.6a3a275d49492p+242", 73, "1.000000000000000139961240179628344893925643604260126034742731531557535744e+73"},
+ {"0x1.c4c8b1349b9b5p+245", 74, "99999999999999995164818811802792197885196090803013355167206819763650035712"},
+ {"0x1.c4c8b1349b9b6p+245", 74, "1.000000000000000077190222825761537255567749372183461873719177086917190615e+74"},
+ {"0x1.1afd6ec0e1411p+249", 75, "999999999999999926539781176481198923508803215199467887262646419780362305536"},
+ {"0x1.1afd6ec0e1412p+249", 75, "1.00000000000000012740703670885498336625406475784479320253802064262946671821e+75"},
+ {"0x1.61bcca7119915p+252", 76, "9999999999999998863663300700064420349597509066704028242075715752105414230016"},
+ {"0x1.61bcca7119916p+252", 76, "1.000000000000000047060134495905469589155960140786663076427870953489824953139e+76"},
+ {"0x1.ba2bfd0d5ff5bp+255", 77, "99999999999999998278261272554585856747747644714015897553975120217811154108416"},
+ {"0x1.ba2bfd0d5ff5cp+255", 77, "1.0000000000000001113376562662650806108344438344331671773159907048015383651942e+77"},
+ {"0x1.145b7e285bf98p+259", 78, "999999999999999802805551768538947706777722104929947493053015898505313987330048"},
+ {"0x1.145b7e285bf99p+259", 78, "1.00000000000000000849362143368970297614886992459876061589499910270279690590618e+78"},
+ {"0x1.59725db272f7fp+262", 79, "9999999999999999673560075006595519222746403606649979913266024618633003221909504"},
+ {"0x1.59725db272f80p+262", 79, "1.000000000000000131906463232780156137771558616400048489600189025221286657051853e+79"},
+ {"0x1.afcef51f0fb5ep+265", 80, "99999999999999986862573406138718939297648940722396769236245052384850852127440896"},
+ {"0x1.afcef51f0fb5fp+265", 80, "1.0000000000000000002660986470836727653740240118120080909813197745348975891631309e+80"},
+ {"0x1.0de1593369d1bp+269", 81, "999999999999999921281879895665782741935503249059183851809998224123064148429897728"},
+ {"0x1.0de1593369d1cp+269", 81, "1.0000000000000001319064632327801561377715586164000484896001890252212866570518528e+81"},
+ {"0x1.5159af8044462p+272", 82, "9999999999999999634067965630886574211027143225273567793680363843427086501542887424"},
+ {"0x1.5159af8044463p+272", 82, "1.0000000000000001319064632327801561377715586164000484896001890252212866570518528e+82"},
+ {"0x1.a5b01b605557ap+275", 83, "99999999999999989600692989521205793443517660497828009527517532799127744739526311936"},
+ {"0x1.a5b01b605557bp+275", 83, "1.0000000000000000308066632309652569077702520400764334634608974406941398529133143654e+83"},
+ {"0x1.078e111c3556cp+279", 84, "999999999999999842087036560910778345101146430939018748000886482910132485188042620928"},
+ {"0x1.078e111c3556dp+279", 84, "1.00000000000000005776660989811589670243726712709606413709804186323471233401692461466e+84"},
+ {"0x1.4971956342ac7p+282", 85, "9999999999999998420870365609107783451011464309390187480008864829101324851880426209280"},
+ {"0x1.4971956342ac8p+282", 85, "1.00000000000000001463069523067487303097004298786465505927861078716979636425114821591e+85"},
+ {"0x1.9bcdfabc13579p+285", 86, "99999999999999987659576829486359728227492574232414601025643134376206526100066373992448"},
+ {"0x1.9bcdfabc1357ap+285", 86, "1.0000000000000000146306952306748730309700429878646550592786107871697963642511482159104e+86"},
+ {"0x1.0160bcb58c16cp+289", 87, "999999999999999959416724456350362731491996089648451439669739009806703922950954425516032"},
+ {"0x1.0160bcb58c16dp+289", 87, "1.0000000000000001802726075536484039294041836825132659181052261192590736881517295870935e+87"},
+ {"0x1.41b8ebe2ef1c7p+292", 88, "9999999999999999594167244563503627314919960896484514396697390098067039229509544255160320"},
+ {"0x1.41b8ebe2ef1c8p+292", 88, "1.00000000000000013610143093418879568982174616394030302241812869736859973511157455477801e+88"},
+ {"0x1.922726dbaae39p+295", 89, "99999999999999999475366575191804932315794610450682175621941694731908308538307845136842752"},
+ {"0x1.922726dbaae3ap+295", 89, "1.0000000000000001361014309341887956898217461639403030224181286973685997351115745547780096e+89"},
+ {"0x1.f6b0f092959c7p+298", 90, "999999999999999966484112715463900049825186092620125502979674597309179755437379230686511104"},
+ {"0x1.f6b0f092959c8p+298", 90, "1.00000000000000007956232486128049714315622614016691051593864399734879307522017611341417677e+90"},
+ {"0x1.3a2e965b9d81cp+302", 91, "9999999999999998986371854279739417938265620640920544952042929572854117635677011010499117056"},
+ {"0x1.3a2e965b9d81dp+302", 91, "1.000000000000000079562324861280497143156226140166910515938643997348793075220176113414176768e+91"},
+ {"0x1.88ba3bf284e23p+305", 92, "99999999999999989863718542797394179382656206409205449520429295728541176356770110104991170560"},
+ {"0x1.88ba3bf284e24p+305", 92, "1.0000000000000000433772969746191860732902933249519393117917737893361168128896811109413237555e+92"},
+ {"0x1.eae8caef261acp+308", 93, "999999999999999927585207737302990649719308316264031458521789123695552773432097103028194115584"},
+ {"0x1.eae8caef261adp+308", 93, "1.00000000000000004337729697461918607329029332495193931179177378933611681288968111094132375552e+93"},
+ {"0x1.32d17ed577d0bp+312", 94, "9999999999999998349515363474500343108625203093137051759058013911831015418660298966976904036352"},
+ {"0x1.32d17ed577d0cp+312", 94, "1.000000000000000020218879127155946988576096323214357741137776856208004004998164309358697827533e+94"},
+ {"0x1.7f85de8ad5c4ep+315", 95, "99999999999999987200500490339121684640523551209383568895219648418808203449245677922989188841472"},
+ {"0x1.7f85de8ad5c4fp+315", 95, "1.0000000000000000202188791271559469885760963232143577411377768562080040049981643093586978275328e+95"},
+ {"0x1.df67562d8b362p+318", 96, "999999999999999931290554592897108903273579836542044509826428632996050822694739791281414264061952"},
+ {"0x1.df67562d8b363p+318", 96, "1.00000000000000004986165397190889301701026848543846215157489293061198839909930581538445901535642e+96"},
+ {"0x1.2ba095dc7701dp+322", 97, "9999999999999998838621148412923952577789043769834774531270429139496757921329133816401963635441664"},
+ {"0x1.2ba095dc7701ep+322", 97, "1.000000000000000073575873847711249839757606215217745679924585790135175914380219020205067965615309e+97"},
+ {"0x1.7688bb5394c25p+325", 98, "99999999999999999769037024514370800696612547992403838920556863966097586548129676477911932478685184"},
+ {"0x1.7688bb5394c26p+325", 98, "1.0000000000000001494613774502787916725490869505114529706436029406093759632791412756310166064437658e+98"},
+ {"0x1.d42aea2879f2ep+328", 99, "999999999999999967336168804116691273849533185806555472917961779471295845921727862608739868455469056"},
+ {"0x1.d42aea2879f2fp+328", 99, "1.00000000000000008875297456822475820631590236227648713806838922023001592416000347129025769378100019e+99"},
+ {"0x1.249ad2594c37cp+332", 100, "9999999999999998216360018871870109548898901740426374747374488505608317520357971321909184780648316928"},
+ {"0x1.249ad2594c37dp+332", 100, "1.00000000000000001590289110975991804683608085639452813897813275577478387721703810608134699858568151e+100"},
+ {"0x1.6dc186ef9f45cp+335", 101, "99999999999999997704951326524533662844684271992415000612999597473199345218078991130326129448151154688"},
+ {"0x1.6dc186ef9f45dp+335", 101, "1.000000000000000132463024643303662302003795265805662537522543098903155152325782690415604110898191401e+101"},
+ {"0x1.c931e8ab87173p+338", 102, "999999999999999977049513265245336628446842719924150006129995974731993452180789911303261294481511546880"},
+ {"0x1.c931e8ab87174p+338", 102, "1.00000000000000010138032236769199716729240475662936003124403367406892281229678413459313554761485543014e+102"},
+ {"0x1.1dbf316b346e7p+342", 103, "9999999999999998029863805218200118740630558685368559709703431956602923480183979986974373400948301103104"},
+ {"0x1.1dbf316b346e8p+342", 103, "1.000000000000000001915675085734668736215955127265192011152803514599379324203988755961236145108180323533e+103"},
+ {"0x1.652efdc6018a1p+345", 104, "99999999999999984277223943460294324649363572028252317900683525944810974325551615015019710109750015295488"},
+ {"0x1.652efdc6018a2p+345", 104, "1.0000000000000000019156750857346687362159551272651920111528035145993793242039887559612361451081803235328e+104"},
+ {"0x1.be7abd3781ecap+348", 105, "999999999999999938258300825281978540327027364472124478294416212538871491824599713636820527503908255301632"},
+ {"0x1.be7abd3781ecbp+348", 105, "1.00000000000000006557304934618735893210488289005825954401119081665988715658337779828565176271245239176397e+105"},
+ {"0x1.170cb642b133ep+352", 106, "9999999999999998873324014169198263836158851542376704520077063708904652259210884797772880334204906007166976"},
+ {"0x1.170cb642b133fp+352", 106, "1.000000000000000091035999050368435010460453995175486557154545737484090289535133415215418009754161219056435e+106"},
+ {"0x1.5ccfe3d35d80ep+355", 107, "99999999999999996881384047029926983435371269061279689406644211752791525136670645395254002395395884805259264"},
+ {"0x1.5ccfe3d35d80fp+355", 107, "1.0000000000000001317767185770581567358293677633630497781839136108028153022579424023030440050208953427243827e+107"},
+ {"0x1.b403dcc834e11p+358", 108, "999999999999999903628689227595715073763450661512695740419453520217955231010212074612338431527184250183876608"},
+ {"0x1.b403dcc834e12p+358", 108, "1.00000000000000003399899171300282459494397471971289804771343071483787527172320083329274161638073344592130867e+108"},
+ {"0x1.108269fd210cbp+362", 109, "9999999999999999818508707188399807864717650964328171247958398369899072554380053298205803424393137676263358464"},
+ {"0x1.108269fd210ccp+362", 109, "1.000000000000000190443354695491356020360603589553140816466203348381779320578787343709225438204992480806227149e+109"},
+ {"0x1.54a3047c694fdp+365", 110, "99999999999999985669538033284915564613846200056062290979362173015478401635353612148739328497990653971840106496"},
+ {"0x1.54a3047c694fep+365", 110, "1.0000000000000000235693675141702558332495327950568818631299125392682816684661617325983093615924495102623141069e+110"},
+ {"0x1.a9cbc59b83a3dp+368", 111, "999999999999999956819772641641815758405104477258378281795396215622882607621111488153942930947432322044748890112"},
+ {"0x1.a9cbc59b83a3ep+368", 111, "1.00000000000000009031896238669869590809396111285538544446442886291368072931121197704267579223746669847987932365e+111"},
+ {"0x1.0a1f5b8132466p+372", 112, "9999999999999999301199346926304397284673331501389768492615896861647229832830913903761963586894254467577228034048"},
+ {"0x1.0a1f5b8132467p+372", 112, "1.000000000000000143718638284721447967969503767094188309532041921829999977987252172598168936753480449053931497062e+112"},
+ {"0x1.4ca732617ed7fp+375", 113, "99999999999999984468045325579403643266646490335689226515340879189861218540142707748740732746380344583923932594176"},
+ {"0x1.4ca732617ed80p+375", 113, "1.0000000000000000155594161294668430242682013969210614333697705804308337811647557032649853899150474476762062808678e+113"},
+ {"0x1.9fd0fef9de8dfp+378", 114, "999999999999999878856245830528597750986812202069726098796681149605056504554092802642922939954052246206632716926976"},
+ {"0x1.9fd0fef9de8e0p+378", 114, "1.00000000000000001555941612946684302426820139692106143336977058043083378116475570326498538991504744767620628086784e+114"},
+ {"0x1.03e29f5c2b18bp+382", 115, "9999999999999997968343436511656505870179786851589248980528274911095901385876950622696854699774551253248885785624576"},
+ {"0x1.03e29f5c2b18cp+382", 115, "1.00000000000000001555941612946684302426820139692106143336977058043083378116475570326498538991504744767620628086784e+115"},
+ {"0x1.44db473335deep+385", 116, "99999999999999984057935814682588907446802322751135220511621610897383886710310719046874545396497358979515211902353408"},
+ {"0x1.44db473335defp+385", 116, "1.00000000000000001555941612946684302426820139692106143336977058043083378116475570326498538991504744767620628086784e+116"},
+ {"0x1.961219000356ap+388", 117, "999999999999999910571381339882270654388094495275235896417637897556636832727766595587241428345003132947573783761256448"},
+ {"0x1.961219000356bp+388", 117, "1.00000000000000005055542772599503381422823703080300327902048147472223276397708540582423337710506221925241711323670118e+117"},
+ {"0x1.fb969f40042c5p+391", 118, "9999999999999999665649998943273759183241515094863428494587753284228752052274941196820382078490267674695111155514343424"},
+ {"0x1.fb969f40042c6p+391", 118, "1.000000000000000078552237003217586446196265537908556755541050190155351950226949167871631766857074036513385779131790131e+118"},
+ {"0x1.3d3e2388029bbp+395", 119, "99999999999999994416755247254933381274972870380190006824232035607637985622760311004411949604741731366073618283536318464"},
+ {"0x1.3d3e2388029bcp+395", 119, "1.0000000000000001233471318467736706573451111492774423179739601348483426482267311871474691904602929441309356445639324467e+119"},
+ {"0x1.8c8dac6a0342ap+398", 120, "999999999999999980003468347394201181668805192897008518188648311830772414627428725464789434929992439754776075181077037056"},
+ {"0x1.8c8dac6a0342bp+398", 120, "1.00000000000000012334713184677367065734511114927744231797396013484834264822673118714746919046029294413093564456393244672e+120"},
+ {"0x1.efb1178484134p+401", 121, "9999999999999999226660029476424133913982828103448349982745235826237443211877077407917175327178722380043122474279348731904"},
+ {"0x1.efb1178484135p+401", 121, "1.000000000000000037340933747145988971939327575449182038102773041037800508067149710137861337142112641505239902934219200922e+121"},
+ {"0x1.35ceaeb2d28c0p+405", 122, "99999999999999983092605830803955292696544699826135736641192401589249937168415416531480248917847991520357012302290741100544"},
+ {"0x1.35ceaeb2d28c1p+405", 122, "1.0000000000000000144059475872452738558311186224283126301371231493549892706912613162686325762572645608050543718329623353754e+122"},
+ {"0x1.83425a5f872f1p+408", 123, "999999999999999977709969731404129670057984297594921577392083322662491290889839886077866558841507631684757522070951350501376"},
+ {"0x1.83425a5f872f2p+408", 123, "1.00000000000000012449388115476870641315052159692848578837224262943248321009552560684093062850453534816594492111899528999731e+123"},
+ {"0x1.e412f0f768fadp+411", 124, "9999999999999999483531874467312143214394768377282087351960514613084929070487027419252537449089020883885200422613425626021888"},
+ {"0x1.e412f0f768faep+411", 124, "1.000000000000000065780316585422875715913506677195060103980178906724486442413251318535705000639324261573469961499777714198938e+124"},
+ {"0x1.2e8bd69aa19ccp+415", 125, "99999999999999992486776161899288204254467086983483846143922597222529419997579302660316349376281765375153005841365553228283904"},
+ {"0x1.2e8bd69aa19cdp+415", 125, "1.0000000000000001127511682408995402737031186129818006514938298848908838565590707491798855029314931308474499291951517748376371e+125"},
+ {"0x1.7a2ecc414a03fp+418", 126, "999999999999999924867761618992882042544670869834838461439225972225294199975793026603163493762817653751530058413655532282839040"},
+ {"0x1.7a2ecc414a040p+418", 126, "1.0000000000000000751744869165182086274714290643524082134829091023577659252424152046645411010977580354282659550388525263266775e+126"},
+ {"0x1.d8ba7f519c84fp+421", 127, "9999999999999999549291066784979473595300225087383524118479625982517885450291174622154390152298057300868772377386949310916067328"},
+ {"0x1.d8ba7f519c850p+421", 127, "1.000000000000000075174486916518208627471429064352408213482909102357765925242415204664541101097758035428265955038852526326677504e+127"},
+ {"0x1.27748f9301d31p+425", 128, "99999999999999988278187853568579059876517857536991893086699469578820211690113881674597776370903434688204400735860037395056427008"},
+ {"0x1.27748f9301d32p+425", 128, "1.000000000000000075174486916518208627471429064352408213482909102357765925242415204664541101097758035428265955038852526326677504e+128"},
+ {"0x1.7151b377c247ep+428", 129, "999999999999999998217443564185241415988928868759412500436543339729940401905904649497115766142268560009777175966751665376232210432"},
+ {"0x1.7151b377c247fp+428", 129, "1.00000000000000015213153026885117583895392925994540392652927486498559144857892575983196643605324751084675473411095338727712279757e+129"},
+ {"0x1.cda62055b2d9dp+431", 130, "9999999999999999366518088823188676468029287122850159299994507296276799832366962053631754981778769796749861527090709766158759755776"},
+ {"0x1.cda62055b2d9ep+431", 130, "1.000000000000000059783078246051615185174929025233809070873635949832200820575113093631056034106660140344568199224432354136588445286e+130"},
+ {"0x1.2087d4358fc82p+435", 131, "99999999999999991202555500957231813912852864969525730182461368558677581576901282770959939099212034754106974340599870111173348163584"},
+ {"0x1.2087d4358fc83p+435", 131, "1.0000000000000001090355859915447142005237291504133263272233100379140091555104798489382082484781734046124010178305769051448734331699e+131"},
+ {"0x1.68a9c942f3ba3p+438", 132, "999999999999999990829567402361276563686608849982484911984092226517669151665599636201042933986541570369602253175829982724989462249472"},
+ {"0x1.68a9c942f3ba4p+438", 132, "1.00000000000000014843759218793919341280276925055694013230304930837945582345877325318393001997538401602666727271549254595150142347674e+132"},
+ {"0x1.c2d43b93b0a8bp+441", 133, "9999999999999998962647525310145264542169126096378117797927179774005971485896954660113106823932361029753632414520324447890822855131136"},
+ {"0x1.c2d43b93b0a8cp+441", 133, "1.000000000000000022351172359476859933509840930097375956047883642890026486024234359597620351184310059501015257083762495370291854494925e+133"},
+ {"0x1.19c4a53c4e697p+445", 134, "99999999999999992148203649670699315007549827372972461504375111049848301607660324472857261615145089428049364457837845490532419930947584"},
+ {"0x1.19c4a53c4e698p+445", 134, "1.0000000000000001232203082222467267169441835864650272970520161752815699559718654744666680862171692247215368695891465358352595096803738e+134"},
+ {"0x1.6035ce8b6203dp+448", 135, "999999999999999961829690841814939863449235336276785151445404123455100404055655690676191710164594560368702289580532071091311261383655424"},
+ {"0x1.6035ce8b6203ep+448", 135, "1.00000000000000012322030822224672671694418358646502729705201617528156995597186547446666808621716922472153686958914653583525950968037376e+135"},
+ {"0x1.b843422e3a84cp+451", 136, "9999999999999999295515673657285824927502456862391367223240817130898064936724137339180964349540796274981353735788091781425216117243117568"},
+ {"0x1.b843422e3a84dp+451", 136, "1.000000000000000058664061270074011975546204286389730438809371354550982135205381560950477535796139358980403037585700749937680210361686426e+136"},
+ {"0x1.132a095ce492fp+455", 137, "99999999999999982626157224225223890651347880611866174913584999992086598044603947229219155428043184231232124237329592070639473281441202176"},
+ {"0x1.132a095ce4930p+455", 137, "1.0000000000000000328415624892049260789870125663596116955123134262587470068987879955440013156277274126839495047843224355786484906342114918e+137"},
+ {"0x1.57f48bb41db7bp+458", 138, "999999999999999867577570291642776341008185558166851738411142685188442185736589176942553506549890956386646894855501223680845484378371915776"},
+ {"0x1.57f48bb41db7cp+458", 138, "1.00000000000000003284156248920492607898701256635961169551231342625874700689878799554400131562772741268394950478432243557864849063421149184e+138"},
+ {"0x1.adf1aea12525ap+461", 139, "9999999999999999006303687311552062886039509598054037298313768334025031499690289406628430683654582476461074168412654660604060856295398309888"},
+ {"0x1.adf1aea12525bp+461", 139, "1.00000000000000003284156248920492607898701256635961169551231342625874700689878799554400131562772741268394950478432243557864849063421149184e+139"},
+ {"0x1.0cb70d24b7378p+465", 140, "99999999999999984774589122793531837245072631718372054355900219626000560719712531871037976946055058163097058166404267825310912362767116664832"},
+ {"0x1.0cb70d24b7379p+465", 140, "1.0000000000000000592838012408148700370636248876704532886485007448299957782847398065202329650801812456915179223729338294822969716351458240102e+140"},
+ {"0x1.4fe4d06de5056p+468", 141, "999999999999999847745891227935318372450726317183720543559002196260005607197125318710379769460550581630970581664042678253109123627671166648320"},
+ {"0x1.4fe4d06de5057p+468", 141, "1.00000000000000001697621923823895970414104517357310673963060103511599774406721690895826232595625511287940845423115559923645940203365089253786e+141"},
+ {"0x1.a3de04895e46cp+471", 142, "9999999999999999154380224320567749051268538597394750219876417318024024619451619548095327920588323941303457306908878466464492349900630570041344"},
+ {"0x1.a3de04895e46dp+471", 142, "1.000000000000000050822284840299687970479108944850983978844920802887196171441235227007838837255396019129096028744578183433129457714846837715763e+142"},
+ {"0x1.066ac2d5daec3p+475", 143, "99999999999999980713061250546244445284504979165026785650181847493456749434830333705088795590158149413134549224793557721710505681023603243483136"},
+ {"0x1.066ac2d5daec4p+475", 143, "1.0000000000000000237454323586511053574086579278286821874734649886702374295420205725681776282160832941293459691338401160757934131698900815734374e+143"},
+ {"0x1.4805738b51a74p+478", 144, "999999999999999850453576476100176633757771418885950722696147777681701481387046784154345890364481854130945587625116484988842728082166842262552576"},
+ {"0x1.4805738b51a75p+478", 144, "1.00000000000000002374543235865110535740865792782868218747346498867023742954202057256817762821608329412934596913384011607579341316989008157343744e+144"},
+ {"0x1.9a06d06e26112p+481", 145, "9999999999999999890870611821409196126784806260401358945180015464725302399110258148854112806457630061296658928320953898584032761523454337112604672"},
+ {"0x1.9a06d06e26113p+481", 145, "1.000000000000000127720545888181662591599189833194321066339855315263358998435004845616476670927044158128386198039074294727963824222524025159968358e+145"},
+ {"0x1.00444244d7cabp+485", 146, "99999999999999993363366729972462242111019694317846182578926003895619873650143420259298512453325054533017777074930382791057905692427399713177731072"},
+ {"0x1.00444244d7cacp+485", 146, "1.0000000000000001554472428293898111873833316746251581007042260690215247501398006517626897489833003885281302590804700757018759338365597434497099366e+146"},
+ {"0x1.405552d60dbd6p+488", 147, "999999999999999977996382405657660174364823889467801080772253244969263939229107492426926049423260513969768268415537077468838432306731146395363835904"},
+ {"0x1.405552d60dbd7p+488", 147, "1.00000000000000015544724282938981118738333167462515810070422606902152475013980065176268974898330038852813025908047007570187593383655974344970993664e+147"},
+ {"0x1.906aa78b912cbp+491", 148, "9999999999999999070160382361647997691574207754048582727994641153483596148648302286926205695992445641464234721495638781756234316947997075736253956096"},
+ {"0x1.906aa78b912ccp+491", 148, "1.000000000000000048976726575150520579572227003530743888745042374590168263593384756161231529247276463793113064681510276762053432918662585217102276198e+148"},
+ {"0x1.f485516e7577ep+494", 149, "99999999999999993540817590396194393124038202103003539598857976719672134461054113418634276152885094407576139065595315789290943193957228310232077172736"},
+ {"0x1.f485516e7577fp+494", 149, "1.0000000000000000489767265751505205795722270035307438887450423745901682635933847561612315292472764637931130646815102767620534329186625852171022761984e+149"},
+ {"0x1.38d352e5096afp+498", 150, "999999999999999980835596172437374590573120014030318793091164810154100112203678582976298268616221151962702060266176005440567032331208403948233373515776"},
+ {"0x1.38d352e5096b0p+498", 150, "1.00000000000000016254527724633909722790407198603145238150150498198361518257622837813612029696570198351046473870706739563119743389775288733188378066944e+150"},
+ {"0x1.8708279e4bc5ap+501", 151, "9999999999999998718097875280963410081745488308296386400449607070563910699801487058804050516065326530340444532016411713261887913912817139180431292235776"},
+ {"0x1.8708279e4bc5bp+501", 151, "1.000000000000000017177532387217719118039310408430545510773232844520003126278188542008262674286117318272254595954354283478693112644517300624963454946509e+151"},
+ {"0x1.e8ca3185deb71p+504", 152, "99999999999999992995688547174489225212045346187000138833626956204183589249936464033154810067836651912932851030272641618719051989257594860081125951275008"},
+ {"0x1.e8ca3185deb72p+504", 152, "1.000000000000000046251081359041994740012262723950726884918887272012725537537796509233834198822034251319896624504896905909193976895164417966347520091095e+152"},
+ {"0x1.317e5ef3ab327p+508", 153, "999999999999999999733403004123153744855539019118436686285840188024369679522423761672919759564567158443669378824028710020392594094129030220133015859757056"},
+ {"0x1.317e5ef3ab328p+508", 153, "1.00000000000000018580411642379851772548243383844759748081802852397779311158391475191657751659443552994857836154750149357559812529827058120499103278510899e+153"},
+ {"0x1.7dddf6b095ff0p+511", 154, "9999999999999998880909749523179353564794021275209402095665271864523156202855291675267251053466461355407239891899450398872692753716440996292182057045458944"},
+ {"0x1.7dddf6b095ff1p+511", 154, "1.000000000000000036947545688058226540980917982984268845192277855215054365934721959721651310970540832744651175368723266731433700334957340417104619244827443e+154"},
+ {"0x1.dd55745cbb7ecp+514", 155, "99999999999999988809097495231793535647940212752094020956652718645231562028552916752672510534664613554072398918994503988726927537164409962921820570454589440"},
+ {"0x1.dd55745cbb7edp+514", 155, "1.0000000000000000071762315409101683040806148118916031180671277214625066168048834012826660698457618933038657381329676213626008153422946922595273365367711334e+155"},
+ {"0x1.2a5568b9f52f4p+518", 156, "999999999999999983359180223191721714560372275017470536367007614460468417501012554531477876945938741751237388344363105067534507348164573733465510370326085632"},
+ {"0x1.2a5568b9f52f5p+518", 156, "1.0000000000000001738955907649392944307223125700105311899679684704767740119319793285409834201445239541722641866531992354280649713012055219419601197018864681e+156"},
+ {"0x1.74eac2e8727b1p+521", 157, "9999999999999999833591802231917217145603722750174705363670076144604684175010125545314778769459387417512373883443631050675345073481645737334655103703260856320"},
+ {"0x1.74eac2e8727b2p+521", 157, "1.000000000000000135788308656589779887489924511011919059247776299273512893045785973739082311504806911688058826991432009355958878510597332300261197835574391603e+157"},
+ {"0x1.d22573a28f19dp+524", 158, "99999999999999995287335453651211007997446182781858083179085387749785952239205787068995699003416510776387310061494932420984963311567802202010637287727642443776"},
+ {"0x1.d22573a28f19ep+524", 158, "1.0000000000000000748166572832305566183181036166141396500954688253482951028278766060560405376812596437133302515326044476405891300456242288735429228494750692147e+158"},
+ {"0x1.2357684599702p+528", 159, "999999999999999928484693987168420772305733470059469068129930887927772406304894123616740280504746200573981670431418299523701733729688780649419062882836695482368"},
+ {"0x1.2357684599703p+528", 159, "1.0000000000000001235939783819179352336555603321323631774173148044884693350022041002024739567400974580931131118996664970128849288176027116149175428383545271255e+159"},
+ {"0x1.6c2d4256ffcc2p+531", 160, "9999999999999998504409802292686149877658027252303114244149773213034936348259701329824468100106056975663290938441190205280284556945232082632196709006295628251136"},
+ {"0x1.6c2d4256ffcc3p+531", 160, "1.000000000000000006528407745068226556845664214888626711844884454552051177783818114251033750998886703581634247018717578519375011764854353035618454865043828139622e+160"},
+ {"0x1.c73892ecbfbf3p+534", 161, "99999999999999991287595123558845961539774732109363753938694017460291665200910932548988158640591809997245115511395844372456707812265566617217918448639526895091712"},
+ {"0x1.c73892ecbfbf4p+534", 161, "1.0000000000000000377458932482281488706616365128202897693308658812017626863753877105047511391965429047846952776536372901176443229789205819900982116579266812025242e+161"},
+ {"0x1.1c835bd3f7d78p+538", 162, "999999999999999937849939638116397466450525159438967985375725315922685858882365002492855496964043060934899979621894213003182527093908649335762989920701551401238528"},
+ {"0x1.1c835bd3f7d79p+538", 162, "1.00000000000000013764184685833990027487274786620161155328600644648083951386841041851664678142904274863449057568538036723210611886393251464443343339515181100380979e+162"},
+ {"0x1.63a432c8f5cd6p+541", 163, "9999999999999999378499396381163974664505251594389679853757253159226858588823650024928554969640430609348999796218942130031825270939086493357629899207015514012385280"},
+ {"0x1.63a432c8f5cd7p+541", 163, "1.000000000000000097683465414295199713188303324849082839703950220369208782871201335311888524536042811094572456472683136386321400509927741582699344700261759083295539e+163"},
+ {"0x1.bc8d3f7b3340bp+544", 164, "99999999999999987391652932764487656775541389327492204364443535414407668928683046936524228593524316087103098888157864364992697772750101243698844800887746832841572352"},
+ {"0x1.bc8d3f7b3340cp+544", 164, "1.0000000000000000017833499485879183651456364256030139271070152777012950284778995356204687079928429609987689703622097823564380764603162862345375318325256344740613325e+164"},
+ {"0x1.15d847ad00087p+548", 165, "999999999999999899489893451833484927233458399740540420336951338855520357125044282616287570346763120896578585177704871391229197474064067196498264773607101557544845312"},
+ {"0x1.15d847ad00088p+548", 165, "1.00000000000000010407680644534235180305781445146548743387707921654706969983075478862464984563892280110095935554671469332164695544656850527257679889144416739057781965e+165"},
+ {"0x1.5b4e5998400a9p+551", 166, "9999999999999999404072760505352583023983296100855298230449769143938302256661863838179600254051950569374547392515068357773127490685649548117139715971745147241514401792"},
+ {"0x1.5b4e5998400aap+551", 166, "1.000000000000000104076806445342351803057814451465487433877079216547069699830754788624649845638922801100959355546714693321646955446568505272576798891444167390577819648e+166"},
+ {"0x1.b221effe500d3p+554", 167, "99999999999999990767336997157383960226643264180953830087855645396318233083327270285662206135844950810475381599246526426844590779296424471954140613832058419086616428544"},
+ {"0x1.b221effe500d4p+554", 167, "1.0000000000000000386089942874195144027940205149135043895442382956857739101649274267019739175454317034355575090286315503039132728953670850882316679737363063240072678605e+167"},
+ {"0x1.0f5535fef2084p+558", 168, "999999999999999933860494834742974562371950216430331518611692822307700646699603647625692432595845947170914554599698521475539380813444812793279458505403728617494385000448"},
+ {"0x1.0f5535fef2085p+558", 168, "1.00000000000000014335749374009605424321609081339667726047678376906384717363025120577825540249501745970020046345756457913228716497728935738318387744206888403052015072051e+168"},
+ {"0x1.532a837eae8a5p+561", 169, "9999999999999999338604948347429745623719502164303315186116928223077006466996036476256924325958459471709145545996985214755393808134448127932794585054037286174943850004480"},
+ {"0x1.532a837eae8a6p+561", 169, "1.000000000000000101458093959025438307047262694003408112103765579712617868244121694147742808515183157194343281685991367600937608144520448465202993654735852947914997576499e+169"},
+ {"0x1.a7f5245e5a2cep+564", 170, "99999999999999990034097500988648181343688772091571619991327827082671720239070003832128235741197850516622880918243995225045973534722968565889475147553730375141026248523776"},
+ {"0x1.a7f5245e5a2cfp+564", 170, "1.0000000000000000344190543093124528091771377029741774747069364767506509796263144755389226581474482731849717908514742291507783172120901941964335795950030032157467525460787e+170"},
+ {"0x1.08f936baf85c1p+568", 171, "999999999999999953972206729656870211732987713739100709830741553196290713284945813208338477706166412373726001850053663010587168093173889073910282723323583537144858509574144"},
+ {"0x1.08f936baf85c2p+568", 171, "1.00000000000000016849713360873842380491738768503263874950059468267458475686192891275656295888291804120371477252050850605109689907695070273397240771446870268008324260691968e+171"},
+ {"0x1.4b378469b6731p+571", 172, "9999999999999999110672213538405594930961077194803931018967709273006319045695491932986935814708160866077282477159626944024852218964185263418978577250945597085571816901050368"},
+ {"0x1.4b378469b6732p+571", 172, "1.000000000000000082687162857105802367643627696515223533632653430883267139431135672937273166412217389671719264252326568834893006683439977269947557718010655022907888967981466e+172"},
+ {"0x1.9e056584240fdp+574", 173, "99999999999999987674323305318751091818660372407342701554959442658410485759723189737097766448253582599493004440868991951600366493901423615628791772651134064568704023452975104"},
+ {"0x1.9e056584240fep+574", 173, "1.0000000000000000140391862557997052178246197057012913609383004294502130454865010810818413324356568684461228576377810190619298927686313968987276777208442168971676060568308941e+173"},
+ {"0x1.02c35f729689ep+578", 174, "999999999999999849284042412665072058259000527747854146471853226010883220019378060628804930891911617504691481762871699606818419373090804007799965727644765395390927070069522432"},
+ {"0x1.02c35f729689fp+578", 174, "1.0000000000000000689575675368445829376798260983524370990937828305966563206422087545661867996169052854265999829294174588803003839004782611957035817185773673977598323857513513e+174"},
+ {"0x1.4374374f3c2c6p+581", 175, "9999999999999999371534524623368764100273307559896873275206250678451924602685103382037576783819090846734548822294900033162112051840457868829614121240178061963384891963422539776"},
+ {"0x1.4374374f3c2c7p+581", 175, "1.000000000000000112892272561680485113563991212473353689618168751513810940766774893353663173361904019010981683162726610734996776805955752633284304916763887798233613448887717069e+175"},
+ {"0x1.945145230b377p+584", 176, "99999999999999986685792442259943292861266657339622078268160759437774506806920451614379548038991111093844416185619536034869697653528180058283225500691937355558043949532406874112"},
+ {"0x1.945145230b378p+584", 176, "1.0000000000000000074489805020743198914419949385831538723596425413126398524678161602637198763739070584084656026027846462837254338328097731830905692411162388370965388973604392141e+176"},
+ {"0x1.f965966bce055p+587", 177, "999999999999999894976135638494410321178532246433607400617214583764724024948926844967780359586710300432448450005513217535702667994787395102883917853758746611883659375731342835712"},
+ {"0x1.f965966bce056p+587", 177, "1.00000000000000000744898050207431989144199493858315387235964254131263985246781616026371987637390705840846560260278464628372543383280977318309056924111623883709653889736043921408e+177"},
+ {"0x1.3bdf7e0360c35p+591", 178, "9999999999999998724815666657784284071258397080036981062687289922551408594451489819085924562292709488372450194860589317860981148271829194868425875762872481668410834714055235600384"},
+ {"0x1.3bdf7e0360c36p+591", 178, "1.000000000000000052438118447506283719547380015442972461056613724331806183475371886382095683088785761598872463641693217782934540168018724415173229796059235727181690706012077765427e+178"},
+ {"0x1.8ad75d8438f43p+594", 179, "99999999999999998045549773481514159457876389246726271914145983150114005386328272459269439234497983649422148597943950338419997003168440244384097290815044070304544781216945608327168"},
+ {"0x1.8ad75d8438f44p+594", 179, "1.0000000000000001244207391601974258445159961384186822029717676171624723130874610481714969738325916867035234413039469321816691103043530463865054866839680307513179335998546994475827e+179"},
+ {"0x1.ed8d34e547313p+597", 180, "999999999999999894076352879585771044616424544896411028843275160104340698328775730445412843452412726368640312784735046105718485868083216078242264642659886674081956339558310064685056"},
+ {"0x1.ed8d34e547314p+597", 180, "1.00000000000000000924854601989159844456621034165754661590752138863340650570811838930845490864250220653608187704434098914369379808621813123237387566331395871269994496970650475613389e+180"},
+ {"0x1.3478410f4c7ecp+601", 181, "9999999999999999171107915076469365246063817042486381462561244058101538598046442622180212564904306224021286256366562347133135483117101991090685868467907010818055540655879490029748224"},
+ {"0x1.3478410f4c7edp+601", 181, "1.000000000000000101386300532136260364526038979066455085558918371456659151611592516398888560794573790670035128452025743574074047860726063355679164479837216343594335873825060509292954e+181"},
+ {"0x1.819651531f9e7p+604", 182, "99999999999999991711079150764693652460638170424863814625612440581015385980464426221802125649043062240212862563665623471331354831171019910906858684679070108180555406558794900297482240"},
+ {"0x1.819651531f9e8p+604", 182, "1.0000000000000000645311987272383955965421075241028916976983595783273580932502028655627150999337451570164538278889518418019219479509228905063570489532279132912365795121776382080293274e+182"},
+ {"0x1.e1fbe5a7e7861p+607", 183, "999999999999999946594872951565228338993526868219488856544571440313594706493755982886960025179093529324993666087115356131035228239552737388526279268078143523691759154905886843985723392"},
+ {"0x1.e1fbe5a7e7862p+607", 183, "1.00000000000000006453119872723839559654210752410289169769835957832735809325020286556271509993374515701645382788895184180192194795092289050635704895322791329123657951217763820802932736e+183"},
+ {"0x1.2d3d6f88f0b3cp+611", 184, "9999999999999998286585471758920610814449462123360860153907833022998313197373091002112049504244419016335335042852788704601485085281825842706955095829283737561469387976341354799421194240"},
+ {"0x1.2d3d6f88f0b3dp+611", 184, "1.000000000000000017356668416969128693522675261749530561236844323121852738547624112492413070031884505939869763168217247533567260066374829259224741079168005384218651369268937662411885773e+184"},
+ {"0x1.788ccb6b2ce0cp+614", 185, "99999999999999997961704416875371517110712945186684165206763211895744845478556111003617144611039598507860251139162957211888350975873638026151889477992007905860430885494197722591793250304"},
+ {"0x1.788ccb6b2ce0dp+614", 185, "1.0000000000000001305755411616153692607693126913975972887444809356150655898338131198611379417963500685236715184979802737776185109892901762523422799769117843610616789122498189718937455821e+185"},
+ {"0x1.d6affe45f818fp+617", 186, "999999999999999979617044168753715171107129451866841652067632118957448454785561110036171446110395985078602511391629572118883509758736380261518894779920079058604308854941977225917932503040"},
+ {"0x1.d6affe45f8190p+617", 186, "1.00000000000000010038384176304303844283687604349144616140911117228354216282416271789614464265915925183465771707671013344587151074317941705417760293751344330057020490078825062269858296627e+186"},
+ {"0x1.262dfeebbb0f9p+621", 187, "9999999999999999071569656121801212080692814968920789464627446869617922299624001453201875281811380250249693879805812353226907091680705581859236698853640605134247712274342131878495422251008"},
+ {"0x1.262dfeebbb0fap+621", 187, "1.000000000000000100383841763043038442836876043491446161409111172283542162824162717896144642659159251834657717076710133445871510743179417054177602937513443300570204900788250622698582966272e+187"},
+ {"0x1.6fb97ea6a9d37p+624", 188, "99999999999999986851159038200753776111576258757220550347347138989744224339004763080499610528553377966303172216135545569805454885304878641227288327493418395599568449276340570087973407686656"},
+ {"0x1.6fb97ea6a9d38p+624", 188, "1.0000000000000000230930913026978715489298382248516992754305645781548421896794576888657617968679507611107823854382585741965991901131358735068760297166536901857120314314466356487589666698035e+188"},
+ {"0x1.cba7de5054485p+627", 189, "999999999999999899427890566145604518678577715028104257864890027548922232647929642417149243602017175952581854816736079397763477105066203831193512563278085201938953880500051690455580595453952"},
+ {"0x1.cba7de5054486p+627", 189, "1.00000000000000002309309130269787154892983822485169927543056457815484218967945768886576179686795076111078238543825857419659919011313587350687602971665369018571203143144663564875896666980352e+189"},
+ {"0x1.1f48eaf234ad3p+631", 190, "9999999999999998746948504188351511126283256130633852543517551174277382412416240331274267329488304589209417486924315804379963345034522698960570091326029642051843383703107348987949033805840384"},
+ {"0x1.1f48eaf234ad4p+631", 190, "1.000000000000000072559171597318778361030342428781137282456834398397210172492068907445206818174324195174062597686867572116133475316363741377149036578003932179221262451825269232080321099543347e+190"},
+ {"0x1.671b25aec1d88p+634", 191, "99999999999999991426771465453187656230872897620693565997277097362163262749171300799098274999392920617156591849131877877362376266603456419227541462168315779999172318661364176545198692437590016"},
+ {"0x1.671b25aec1d89p+634", 191, "1.0000000000000000725591715973187783610303424287811372824568343983972101724920689074452068181743241951740625976868675721161334753163637413771490365780039321792212624518252692320803210995433472e+191"},
+ {"0x1.c0e1ef1a724eap+637", 192, "999999999999999914267714654531876562308728976206935659972770973621632627491713007990982749993929206171565918491318778773623762666034564192275414621683157799991723186613641765451986924375900160"},
+ {"0x1.c0e1ef1a724ebp+637", 192, "1.00000000000000004090088020876139800128601973826629695796002171344209466349199772755436200453824519737356326184775781344763153278629790594017431218673977730337535459878294373875465426450985779e+192"},
+ {"0x1.188d357087712p+641", 193, "9999999999999998636144484328400679867178126713831911407778706776934478130915991201656310481762028096907669811487431649040206546179292274931158555956605099986382706217459209761309199883223171072"},
+ {"0x1.188d357087713p+641", 193, "1.000000000000000066227513319607302289081477890678169217557471861406187070692054671467037855447108395613962730519045620382433086810350574289754091699751101204052080881216804133415187732536649318e+193"},
+ {"0x1.5eb082cca94d7p+644", 194, "99999999999999994465967438754696170766327875910118237148971115117854351613178134068619377108456504406004528089686414709538562749489776621177115003729674648080379472553427423904462708600804999168"},
+ {"0x1.5eb082cca94d8p+644", 194, "1.0000000000000001067501262969607491495542109345371648329133920981487349222121457817273192169012895127986018803931061114781155732488348436490817389205692194451348429331109807648720412813795157606e+194"},
+ {"0x1.b65ca37fd3a0dp+647", 195, "999999999999999977077764769429719196041465194188378863774447340572581797347854228894418860247909937807756600796112539971931616645685181699233267813951241073670004367049615544210109925082343145472"},
+ {"0x1.b65ca37fd3a0ep+647", 195, "1.00000000000000010675012629696074914955421093453716483291339209814873492221214578172731921690128951279860188039310611147811557324883484364908173892056921944513484293311098076487204128137951576064e+195"},
+ {"0x1.11f9e62fe4448p+651", 196, "9999999999999999511432924639235132053389160461186216699466583890573511723749959183278387889172340228095875448767138256706948253250552493092635735926276453993770366538373425000777236538229086224384"},
+ {"0x1.11f9e62fe4449p+651", 196, "1.000000000000000158619070907973161130959309230676679220568970001179196172157862402860479359562641342794939992231903540080589155890094708429021127363216410793720778359535526853136813823898384806707e+196"},
+ {"0x1.56785fbbdd55ap+654", 197, "99999999999999995114329246392351320533891604611862166994665838905735117237499591832783878891723402280958754487671382567069482532505524930926357359262764539937703665383734250007772365382290862243840"},
+ {"0x1.56785fbbdd55bp+654", 197, "1.0000000000000001171239152191632315458352305937650677104445076787548271722012891059539512454335598787978695027608655971986102897770868166050696166090986577148520300183958899825249957898832895698534e+197"},
+ {"0x1.ac1677aad4ab0p+657", 198, "999999999999999884751043361827625869140390227060043253747518673178360772444478643277393806310703680414274761723053117059528639544242622390941156386039240473187039308013923507098814799398756243472384"},
+ {"0x1.ac1677aad4ab1p+657", 198, "1.00000000000000001753554156601940054153744186517720008614579810493634157230551319337828377152376436520490032803037453428186101110586787622758599079921605032556703399966076149305663250824706100140442e+198"},
+ {"0x1.0b8e0acac4eaep+661", 199, "9999999999999998847510433618276258691403902270600432537475186731783607724444786432773938063107036804142747617230531170595286395442426223909411563860392404731870393080139235070988147993987562434723840"},
+ {"0x1.0b8e0acac4eafp+661", 199, "1.000000000000000097206240488534465344975672848047494185584765763991130052222133923438817750651600776079275667814767384615260434042843028529572891447122136236995030814648864284631323133556043856163635e+199"},
+ {"0x1.4e718d7d7625ap+664", 200, "99999999999999996973312221251036165947450327545502362648241750950346848435554075534196338404706251868027512415973882408182135734368278484639385041047239877871023591066789981811181813306167128854888448"},
+ {"0x1.4e718d7d7625bp+664", 200, "1.0000000000000001396972799138758332401427293722449843719522151821536839081776649794711025395197801952122758490331102381264067929425631097572992384593387153897566291159758524401378248003875013787018854e+200"},
+ {"0x1.a20df0dcd3af0p+667", 201, "999999999999999901747459131964173027207212836739039328294498440443382314826691065690307721857975448067474834210390258463987183104130654882031695190925872134291678628544718769301415466131339252487684096"},
+ {"0x1.a20df0dcd3af1p+667", 201, "1.00000000000000003771878529305655029174179371417100792467033657856355465388439044499361904623614958929307541410908738969965553158323491481075600563001892542312879319279108086692222079999200332461008486e+201"},
+ {"0x1.0548b68a044d6p+671", 202, "9999999999999999017474591319641730272072128367390393282944984404433823148266910656903077218579754480674748342103902584639871831041306548820316951909258721342916786285447187693014154661313392524876840960"},
+ {"0x1.0548b68a044d7p+671", 202, "1.000000000000000119301580989711976650462542240630189082495839461435658057319010072575605840863054074028435762048305668441056540670697470767990591893474757396431061931338898125494704000308401767883525325e+202"},
+ {"0x1.469ae42c8560cp+674", 203, "99999999999999998876910787506329447650934459829549922997503484884029261182361866844442696946000689845185920534555642245481492613075738123641525387194542623914743194966239051177873087980216425864602058752"},
+ {"0x1.469ae42c8560dp+674", 203, "1.0000000000000001628124053612615373751136081214084190333361076656341132058174738739526654646640697992206279476158887504364704121840108339451823712339845344488589385918977339967333617071438142709626935706e+203"},
+ {"0x1.98419d37a6b8fp+677", 204, "999999999999999988769107875063294476509344598295499229975034848840292611823618668444426969460006898451859205345556422454814926130757381236415253871945426239147431949662390511778730879802164258646020587520"},
+ {"0x1.98419d37a6b90p+677", 204, "1.00000000000000012800374586402188879539275541678583507266389310227534908701870283285101776562325721906687419916182228484013931497336014340342894776157671280691663726345066529974243554167548426849935897395e+204"},
+ {"0x1.fe52048590672p+680", 205, "9999999999999999052283250816881378851792981072012977243617198967792587267065681698004724917620567060828502090557969050236202928251957239362070375381666542984859087613894256390005080826781722527340175556608"},
+ {"0x1.fe52048590673p+680", 205, "1.000000000000000016616035472855013340286026761993566398512806499527303906862635501325745128692656962574862204108809594931879803899277933669817992649871683552701273012420045469371471812176828260616688264806e+205"},
+ {"0x1.3ef342d37a407p+684", 206, "99999999999999986067324092522138770313660664528439025470128525568004065464414123719036343698981660348604541103459182906031648839556284004276265549348464259679976306097717770685212259087870984958094927200256"},
+ {"0x1.3ef342d37a408p+684", 206, "1.0000000000000000388935775510883884313073724929520201333430238200769129428938489676307996560787770138732646031194121329135317061140943756165401836722126894035443458626261694354456645580765594621932224066355e+206"},
+ {"0x1.8eb0138858d09p+687", 207, "999999999999999896317308250394787848770759814817916230429632968559415112294082783278450680807608685563489249451555889830959531939269147157518161129230251958148679621306976052570830984318279772103403898929152"},
+ {"0x1.8eb0138858d0ap+687", 207, "1.00000000000000003889357755108838843130737249295202013334302382007691294289384896763079965607877701387326460311941213291353170611409437561654018367221268940354434586262616943544566455807655946219322240663552e+207"},
+ {"0x1.f25c186a6f04cp+690", 208, "9999999999999999818630698308109481982927274216983785721776674794699138106539424938898600659703096825493544616522696356805028364441642842329313746550197144253860793660984920822957311285732475861572950035529728"},
+ {"0x1.f25c186a6f04dp+690", 208, "1.000000000000000095924085271365828664322017564205661694508380160683912075133755441371739246187244345197174744586554630146560575784024467000148992689405664381702612359153846788595597987579871338229149809718067e+208"},
+ {"0x1.37798f428562fp+694", 209, "99999999999999989061425747836704382546929530769255207431309733449871519907009213590435672179676195243109823530484164010765664497227613801915728022751095446033285297165420831725583764136794858449981115862089728"},
+ {"0x1.37798f4285630p+694", 209, "1.0000000000000000731118821832548525711161595357042050700422376244411124222377928518753634101438574126676106879996976312533490279160524304467054690825284743904393057605427758473356246157785465878147788484850483e+209"},
+ {"0x1.8557f31326bbbp+697", 210, "999999999999999927113782419344605574598668153294882673458925392487194643703632279098558059466181044478400725843812838336795121561031396504666917998514458446354143529431921823271795036250068185162804696593727488"},
+ {"0x1.8557f31326bbcp+697", 210, "1.00000000000000007311188218325485257111615953570420507004223762444111242223779285187536341014385741266761068799969763125334902791605243044670546908252847439043930576054277584733562461577854658781477884848504832e+210"},
+ {"0x1.e6adefd7f06aap+700", 211, "9999999999999999563134023721266549739021664297767471527755878388779781994104643936539191296017163181162427182749897969201059028320356032930746282153172616351711759756540926280845609521557638656931995269719916544"},
+ {"0x1.e6adefd7f06abp+700", 211, "1.00000000000000007311188218325485257111615953570420507004223762444111242223779285187536341014385741266761068799969763125334902791605243044670546908252847439043930576054277584733562461577854658781477884848504832e+211"},
+ {"0x1.302cb5e6f642ap+704", 212, "99999999999999990959401044767537593501656918740576398586892792465272451027953301036534141738485988029569553038510666318680865279842887243162229186843277653306392406169861934038413548670665077684456779836676898816"},
+ {"0x1.302cb5e6f642bp+704", 212, "1.0000000000000000964715781454804920905589581568896966534955675815537392668032585435196522662522856315778842819446391981199976529328557958774316372559707169414929317175205124911858373485031031322390947127876596531e+212"},
+ {"0x1.7c37e360b3d35p+707", 213, "999999999999999984345037526797422397233524775199337052919583787413130412889023223627065756931830180808571031008919677160084252852199641809946030023447952696435527124027376600704816231425231719002378564135125254144"},
+ {"0x1.7c37e360b3d36p+707", 213, "1.00000000000000013384709168504151532166743595078648318702089551293394221810800365015051443602577078183432203225654570510663545295974118056659350633347830502317873324868489112134617772086239360331800009567183778611e+213"},
+ {"0x1.db45dc38e0c82p+710", 214, "9999999999999999544446266951486038123467425400819078260993214423089680518452271383223760211130420606034208307593944715707740128306913340586165347614418822310868858990958736965765439335377993421392542578277827477504"},
+ {"0x1.db45dc38e0c83p+710", 214, "1.000000000000000074046270021743878151893871480551624733380370822725617496020411479541134964388194541424021631757495293928014972916724565063934515809466164092481450798821885313089633125087528849591751483057152773325e+214"},
+ {"0x1.290ba9a38c7d1p+714", 215, "99999999999999990660396936451049407652789096389402106318690169014230827417515340183487244380298106827518051036015414262787762879627804165648934234223216948652905993920546904997130825691790753915825536773603473752064"},
+ {"0x1.290ba9a38c7d2p+714", 215, "1.0000000000000000979665986870629330198032972686455681148365806988089473848554483477848867530432250375881417919571154583994631649339312112649981120190710204647603637787670876363922509633974747510822509281030267784397e+215"},
+ {"0x1.734e940c6f9c5p+717", 216, "999999999999999868331443500000006287872809702943711652856965888408980452039094412644869581954932274412588254040761879473560521568747407734787588406864399290882799171293145332687119715621994096773456255662636329336832"},
+ {"0x1.734e940c6f9c6p+717", 216, "1.00000000000000002142154695804195744249313474674494929417670909534229174058333036940488102934712744986295727931833093209082895047886994342159460414833548007346784224294244020182387388080564786631265270395622996207206e+216"},
+ {"0x1.d022390f8b837p+720", 217, "9999999999999999601855055748251769806450047292244542376488118125689672251656359867008764503902493796828096692073033110439215789148209291468717978517470477604338250142827222541691722147321863584969741246387925089779712"},
+ {"0x1.d022390f8b838p+720", 217, "1.000000000000000082657588341258737904341264764265444350704606378115616256001024752108885608304005520043104889429358553137736322042918957696317410444923912386501859471602158149478575546879109374128331283273667415166157e+217"},
+ {"0x1.221563a9b7322p+724", 218, "99999999999999988670225591496504042642724870819986016981533507324097780666440272745607095564199569546663253707407016578763273303796211201720443029584092898479300433989106071698353021544403254911815982945786756526505984"},
+ {"0x1.221563a9b7323p+724", 218, "1.0000000000000000826575883412587379043412647642654443507046063781156162560010247521088856083040055200431048894293585531377363220429189576963174104449239123865018594716021581494785755468791093741283312832736674151661568e+218"},
+ {"0x1.6a9abc9424febp+727", 219, "999999999999999965084388885482519417592855130626093842171043595190833186399051537317196816706799625297221478016185520727674168639944850288849622355474122345476546392575499689981548348018063279122228410984187505225498624"},
+ {"0x1.6a9abc9424fecp+727", 219, "1.00000000000000012184865482651747739992406797547856118688246063909054394586834915703944853883640748495839935990041623060775703984391032683214000647474050906684363049794437763597758461316612473913036557403682738514637619e+219"},
+ {"0x1.c5416bb92e3e6p+730", 220, "9999999999999999964372420736895110140590976995965873111133270039707753382929110612616471611327211972294570543930316627036907428807379455975076991793273996897499632136492752791807556010476755711238558435947154812096741376"},
+ {"0x1.c5416bb92e3e7p+730", 220, "1.000000000000000121848654826517477399924067975478561186882460639090543945868349157039448538836407484958399359900416230607757039843910326832140006474740509066843630497944377635977584613166124739130365574036827385146376192e+220"},
+ {"0x1.1b48e353bce6fp+734", 221, "99999999999999984594354677029595135102113336853821866019036664182705300920238534632828550788829765195472628778417018121881118652493108811594893042483166843723756247249515245102456078650553656951604416706418119648563167232"},
+ {"0x1.1b48e353bce70p+734", 221, "1.0000000000000000466018071748206975684050858099493768614209804580186827813230862995727677122141957123210339765959854898653172616660068980913606220974926434405874301273673162218994872058950552383264597357715602427843549594e+221"},
+ {"0x1.621b1c28ac20bp+737", 222, "999999999999999886075198851200900594497923856820450300436489405065378963626525536977181948753477264027987825546533242948112401553146250111031268759363863437907536003469585205199546070383440303278127280805657005745376329728"},
+ {"0x1.621b1c28ac20cp+737", 222, "1.00000000000000004660180717482069756840508580994937686142098045801868278132308629957276771221419571232103397659598548986531726166600689809136062209749264344058743012736731622189948720589505523832645973577156024278435495936e+222"},
+ {"0x1.baa1e332d728ep+740", 223, "9999999999999999181805205159248599892793562474462356126333876156560397271658376894962991014456209536865970557564236923315533735757183797070971394269896194384435148282491314085395342974857632902877937717988376531531720556544"},
+ {"0x1.baa1e332d728fp+740", 223, "1.00000000000000004660180717482069756840508580994937686142098045801868278132308629957276771221419571232103397659598548986531726166600689809136062209749264344058743012736731622189948720589505523832645973577156024278435495936e+223"},
+ {"0x1.14a52dffc6799p+744", 224, "99999999999999996954903517948319502092964807244749211214842475260109694882873713352688654575305085714037182409224841134505892881183378706080253249519082903930108094789640533388351546084948006950326015738792668900564521713664"},
+ {"0x1.14a52dffc679ap+744", 224, "1.0000000000000001750230938337165351475308153724525181102085733003813258354803349096492363229827704709554708974355472873990811497562954164756241047679956674427313454264855010352594401143043471863651256997442828324155378630656e+224"},
+ {"0x1.59ce797fb817fp+747", 225, "999999999999999928454223448636526995609414612446486912536395043045051171498417578302416590307106934377352009423588636134254484622941461177838218040629861358615028052178586193608330530158506646130887048916655460323666687950848"},
+ {"0x1.59ce797fb8180p+747", 225, "1.00000000000000009283347037202319909689034845245050771098451388126923428081969579920029641209088262542943126809822773697747226137851076470969547585887373208135923963504986275470907025292240033962037948280174037505158080469402e+225"},
+ {"0x1.b04217dfa61dfp+750", 226, "9999999999999999613300728333138614158656013804472910722260188106898877933626732224819925546638620725877678611585164563028980399740553218842096696042786355031638703687528415058284784747112853848287855356936724432692495112994816"},
+ {"0x1.b04217dfa61e0p+750", 226, "1.000000000000000092833470372023199096890348452450507710984513881269234280819695799200296412090882625429431268098227736977472261378510764709695475858873732081359239635049862754709070252922400339620379482801740375051580804694016e+226"},
+ {"0x1.0e294eebc7d2bp+754", 227, "99999999999999988242803431008825880725075313724536108897092176834227990088845967645101024020764974088276981699468968789815350713138205618891818585152157755624664880897462875650012340778461641195382916742883168419985073526276096"},
+ {"0x1.0e294eebc7d2cp+754", 227, "1.000000000000000092833470372023199096890348452450507710984513881269234280819695799200296412090882625429431268098227736977472261378510764709695475858873732081359239635049862754709070252922400339620379482801740375051580804694016e+227"},
+ {"0x1.51b3a2a6b9c76p+757", 228, "999999999999999924509121522475246865178672200286390413373640190927670776874706901000867474584296317792102107215397297714017257980807797893073643852992008461269166974189675556141912776812173197487139230503413422370196749149011968"},
+ {"0x1.51b3a2a6b9c77p+757", 228, "1.000000000000000092833470372023199096890348452450507710984513881269234280819695799200296412090882625429431268098227736977472261378510764709695475858873732081359239635049862754709070252922400339620379482801740375051580804694016e+228"},
+ {"0x1.a6208b5068394p+760", 229, "9999999999999999918388610622944277578633427011520373324179896670642961784527024602806390495869308408470337715685294734193992593398889846197223766553446979093051960385337504355687757672562640543404353314227442034427503713670135808"},
+ {"0x1.a6208b5068395p+760", 229, "1.000000000000000126498340141932789543232683702883331170506688619337546981608693578840182199592199886956897100274793824830163262058051358073019842260050076805377254167221900194422501748144445768047027533261405765587857615803016806e+229"},
+ {"0x1.07d457124123cp+764", 230, "99999999999999988411127779858373832956786989976700226194703050524569553592790956543300452958271560395914310860351799229078805716535908585708440417158039479244754953558323062848579498254571868337516156995181495372666457581821100032"},
+ {"0x1.07d457124123dp+764", 230, "1.0000000000000000995664443260051171861588155025370724028889488288828968209774953551282735695911460777349244345335409545480104615144188833823603491391090010261628425414842702426517565519668094253057090928936734531588361669158161613e+230"},
+ {"0x1.49c96cd6d16cbp+767", 231, "999999999999999884111277798583738329567869899767002261947030505245695535927909565433004529582715603959143108603517992290788057165359085857084404171580394792447549535583230628485794982545718683375161569951814953726664575818211000320"},
+ {"0x1.49c96cd6d16ccp+767", 231, "1.00000000000000005647541102052084141484062638198305837470056516415545656396757819718921976158945998297976816934753636209656598064460692387730516014560327977941978394030406231981856423808259127691959958830530175327240184869629512909e+231"},
+ {"0x1.9c3bc80c85c7ep+770", 232, "9999999999999999185841044429711589466224211962102134844977374370276477415358432917842475759840644797632681207523216662519436418612086534611285553663849717898419964165273969667523488336530932020840491736225123136358120303938278260736"},
+ {"0x1.9c3bc80c85c7fp+770", 232, "1.000000000000000056475411020520841414840626381983058374700565164155456563967578197189219761589459982979768169347536362096565980644606923877305160145603279779419783940304062319818564238082591276919599588305301753272401848696295129088e+232"},
+ {"0x1.01a55d07d39cfp+774", 233, "99999999999999997374062707399103193390970327051935144057886852787877127050853725394623645022622268104986814019040754458979257737456796162759919727807229498567311142603806310797883499542489243201826933949562808949044795771481474727936"},
+ {"0x1.01a55d07d39d0p+774", 233, "1.0000000000000001943667175980705238830588315677559032649033928912832653863993131025941919471948554861962682179427510579411883194280051942934817649248215877689975714640807276728847796425120893517551500029880911929089916669987624321024e+233"},
+ {"0x1.420eb449c8842p+777", 234, "999999999999999841364972759543336764420226292177420345984153909836074800974071744757463152045042997962028093539001436578955132142505622028069656690022719315678435403212464369035268207172574280176140941400150227439321732144446136385536"},
+ {"0x1.420eb449c8843p+777", 234, "1.00000000000000001786584517880693032373952892996666180544377340055967009368669242367582754961994924207914815574087624726007172578525540816077571080742215354233800343364659602096002392484233181596564547219412071017415669957160428424397e+234"},
+ {"0x1.9292615c3aa53p+780", 235, "9999999999999999119653217272487741881479473472931169297680017061255129180591200163248089110750054956088761184197513608514017695996055364811520783369824930063422626153861170298051704942404772944919427537177384205332557191153093955289088"},
+ {"0x1.9292615c3aa54p+780", 235, "1.000000000000000053166019662659649035603389457524510097335697298704389152229216559459500429134930490902572168181251209396295044513805365387316921630902040387669917039733422351344975068376283323123546378352914806721123693057035913815654e+235"},
+ {"0x1.f736f9b3494e8p+783", 236, "99999999999999994020546131433094915763903576933939556328154082464128816489313932495174721468699049466761532837205133056038042458244550226238504699576640248260779350025557809411313140906763850021826347864477369777082931390365469918625792"},
+ {"0x1.f736f9b3494e9p+783", 236, "1.0000000000000000531660196626596490356033894575245100973356972987043891522292165594595004291349304909025721681812512093962950445138053653873169216309020403876699170397334223513449750683762833231235463783529148067211236930570359138156544e+236"},
+ {"0x1.3a825c100dd11p+787", 237, "999999999999999940205461314330949157639035769339395563281540824641288164893139324951747214686990494667615328372051330560380424582445502262385046995766402482607793500255578094113131409067638500218263478644773697770829313903654699186257920"},
+ {"0x1.3a825c100dd12p+787", 237, "1.00000000000000012094235467165686896238200167043557881776819118314224974463086290016415235780369448864354627206677113669784381647262128326227604641198342313070719116342012890568408126396147021686671611817779947209130032054906464259329229e+237"},
+ {"0x1.8922f31411455p+790", 238, "9999999999999999040580826428657651966904425891201589123842107529410958489455946099092661860636496958724291396331073693328877462044103460624068471125229983529879139676226679317989414380888721568885729507381685429067351125745727105048510464"},
+ {"0x1.8922f31411456p+790", 238, "1.000000000000000048647597328726501040484815309997105515973531039741865112735773470079190300557012891053173894588883214242858459716550970862319646645496614871467432098154308581055701322003937530207335062364589162363111917890900665230478541e+238"},
+ {"0x1.eb6bafd91596bp+793", 239, "99999999999999999081179145438220670296706622164632687453780292502155740721970192601122065475966761298087599260657287627887017431169472094235452683230716826407562484594165232135299736843791138087983021771402091458056119576436948334022754304"},
+ {"0x1.eb6bafd91596cp+793", 239, "1.0000000000000001064834032030707953780025643983478841574092591544621728182518450141471599463543581691254717965711935522068467451214072207822847664586860614788592393503669648407584052755699636795348399070151574101456626400174318471207295386e+239"},
+ {"0x1.33234de7ad7e2p+797", 240, "999999999999999828871535006218182557917368774264146678517764203804695831774701602620905646527100834378441867056103929979702975178097221166452191355376717763378564539746214794185426298453038162762816652692429820789419173810082174047524749312"},
+ {"0x1.33234de7ad7e3p+797", 240, "1.00000000000000001394611380411992443797416585698663833111209417090968048942613054363840851307860572420979515339949701146446548847363722091034057475758294690703234774682671482523407894986432184061083215557424821369358148461498195609632794214e+240"},
+ {"0x1.7fec216198ddbp+800", 241, "9999999999999999029013665253788793099400876073531433395554961906466896948352731790279067931477027903109831815934611625736079804963132210640075447162592094208400778225784148066048873590175516339020228538451571779510840981320420868670460264448"},
+ {"0x1.7fec216198ddcp+800", 241, "1.00000000000000005096102956370027281398552527353113666163096016433067742095641633184190908638890670217606581066817562776141799113274522085911825143802419273576310438824281483144380948014657857618043525615061189227441394677596191250608858071e+241"},
+ {"0x1.dfe729b9ff152p+803", 242, "99999999999999993251329913304315801074917514058874200397058898538348724005950180959070725179594357268399970740840405561116998262359962102302968606061220608382468313571129481157267178324335702235770533430624812081575006786082605199485453729792"},
+ {"0x1.dfe729b9ff153p+803", 242, "1.0000000000000000509610295637002728139855252735311366616309601643306774209564163318419090863889067021760658106681756277614179911327452208591182514380241927357631043882428148314438094801465785761804352561506118922744139467759619125060885807104e+242"},
+ {"0x1.2bf07a143f6d3p+807", 243, "999999999999999885134206960780312089454635087411784140906440513804611167700736000690226517958758320887173266104495426751070779219941381088594259909647411423049314634698686803624216704482068400828613365568502612232284516294771707790360919932928"},
+ {"0x1.2bf07a143f6d4p+807", 243, "1.0000000000000000746505756498316957746327953001196155931630344001201154571357992362921494533074993280744790313201299421914675928345743408263359645135065900661507886387491188354180370195272228869449812405194846465661467225589890846083353893929e+243"},
+ {"0x1.76ec98994f488p+810", 244, "9999999999999999230374806985905888264902671299533504313577592910677120255877486478106111050285065223246344191476223298391501419428679730361426008304192471516696094355087732099829807674910992980518869405586990190990569575476151831539558138249216"},
+ {"0x1.76ec98994f489p+810", 244, "1.000000000000000074650575649831695774632795300119615593163034400120115457135799236292149453307499328074479031320129942191467592834574340826335964513506590066150788638749118835418037019527222886944981240519484646566146722558989084608335389392896e+244"},
+ {"0x1.d4a7bebfa31aap+813", 245, "99999999999999992303748069859058882649026712995335043135775929106771202558774864781061110502850652232463441914762232983915014194286797303614260083041924715166960943550877320998298076749109929805188694055869901909905695754761518315395581382492160"},
+ {"0x1.d4a7bebfa31abp+813", 245, "1.0000000000000000443279566595834743850042896660863625608019793783096347708261891185958417836517007669245101088856284197210041026562330672682972917768891214832545527981010497103310257691199981691663623805273275210727287695567143043174594742793011e+245"},
+ {"0x1.24e8d737c5f0ap+817", 246, "999999999999999874521290314193434603084658115500145579580071256170942927492372459496518833579228824484684143252419893886408557657521935343280724451831297419035632090471862609843762766839539749606096764571247618309588232743975534688554349643169792"},
+ {"0x1.24e8d737c5f0bp+817", 246, "1.00000000000000006858605185178205149670709417331296498669082339575801931987387721275288791937633961584448524683322963769737489479890608611472822996618309634957154147061950501040063476944577794338925746852105322146746313195853412855016020637017702e+246"},
+ {"0x1.6e230d05b76cdp+820", 247, "9999999999999999521471949292288813605336325386252733424243721120057734844449743607990664678980731410286045846847437914107950925140755956518597266575720169912499958425309195700665115678820350271193610461511698595727381924297989722331966923339726848"},
+ {"0x1.6e230d05b76cep+820", 247, "1.00000000000000010739900415929977487543158138487552886811297382367543459835017816340416173653576177411644546754939158645956816222718291626901773106905345613567872334664903349051200916996702558214588960931101434209903811180144584732248137771557847e+247"},
+ {"0x1.c9abd04725480p+823", 248, "99999999999999992109683308321470265755404276937522223728665176967184126166393360027804741417053541441103640811181423240104047857145413152842812577527572916236425034170729678597741204746503691611405533351920096306747820855546959721533975525765152768"},
+ {"0x1.c9abd04725481p+823", 248, "1.0000000000000000452982804672714174694724018463754266578375331390075701527880966423621236290806863208813091144035324684400589343419399880221545293044608804779072323450017879223338101291330293601352781840470765490885181440527870972867675035629361562e+248"},
+ {"0x1.1e0b622c774d0p+827", 249, "999999999999999921096833083214702657554042769375222237286651769671841261663933600278047414170535414411036408111814232401040478571454131528428125775275729162364250341707296785977412047465036916114055333519200963067478208555469597215339755257651527680"},
+ {"0x1.1e0b622c774d1p+827", 249, "1.00000000000000011981914889770544635662341729257554931016806196060900748746259446761256935802677686476347273817856341006347000780423150191839037142197197126723302154697848260414764897813382482654801189436380190070114210535117759732962415254610693325e+249"},
+ {"0x1.658e3ab795204p+830", 250, "9999999999999999210968330832147026575540427693752222372866517696718412616639336002780474141705354144110364081118142324010404785714541315284281257752757291623642503417072967859774120474650369161140553335192009630674782085554695972153397552576515276800"},
+ {"0x1.658e3ab795205p+830", 250, "1.000000000000000080074685734807297616809542387935483895591779922421574242302862294145664969255528574692985472165213574530984101957676027840397922292632722846259267305924245440513601592000067244461220582194881713174409325992035997306767273088415852134e+250"},
+ {"0x1.bef1c9657a685p+833", 251, "99999999999999992109683308321470265755404276937522223728665176967184126166393360027804741417053541441103640811181423240104047857145413152842812577527572916236425034170729678597741204746503691611405533351920096306747820855546959721533975525765152768000"},
+ {"0x1.bef1c9657a686p+833", 251, "1.0000000000000000482791152044887786249584424642234315639307542918716276461750765553721414582385299426365956593545337061049953772804316485780039629891613241094802639130808557096063636830930611787917875324597455631530231025047227172884817695222629872435e+251"},
+ {"0x1.17571ddf6c813p+837", 252, "999999999999999895660376658959887464073162830405580371957831265231883984761705009259228605356936508765924557863270337660249498829658628118512958332498610172941047627432585001251621720339432063578508893731092043050369229765618973200711352404729235767296"},
+ {"0x1.17571ddf6c814p+837", 252, "1.00000000000000009915202805299840901192020234216271529458839530075154219997953373740977907586572775392681935985162149558657733676402265539783429787471556208832666934163027927905794433734427088386288041203596340318724106008442396531773857522810757106893e+252"},
+ {"0x1.5d2ce55747a18p+840", 253, "9999999999999999363587069377675917736425707327570073564839440723358156278052707548893386994586947577981035182609405692455150664165314335743772262409420005560181719702721238568128862437403998276353831973920663150777435958293799716241167969694049028276224"},
+ {"0x1.5d2ce55747a19p+840", 253, "1.000000000000000099152028052998409011920202342162715294588395300751542199979533737409779075865727753926819359851621495586577336764022655397834297874715562088326669341630279279057944337344270883862880412035963403187241060084423965317738575228107571068928e+253"},
+ {"0x1.b4781ead1989ep+843", 254, "99999999999999993635870693776759177364257073275700735648394407233581562780527075488933869945869475779810351826094056924551506641653143357437722624094200055601817197027212385681288624374039982763538319739206631507774359582937997162411679696940490282762240"},
+ {"0x1.b4781ead1989fp+843", 254, "1.0000000000000000665933638299522455642646760202815737069675050550683968855446811409056910005843211547010761915334853103183648826945244110331428835479608497818649698673586481946089327186234966726173809691071839855653415672334151665790142195763670374206669e+254"},
+ {"0x1.10cb132c2ff63p+847", 255, "999999999999999988452569694641453289891412847766833896677368465428848130901034909295879619908945316559292587569958465674654992927728624557883489163749540246356891129106733591931304833693638565628182306078113383272782784390994049606075766012189756664840192"},
+ {"0x1.10cb132c2ff64p+847", 255, "1.00000000000000019682802072213689935488678130780614005745106603780097814328409152692204330170994755160404886480603005139121469897251738849190854085497969900771176776444517253240497919350659351759937874082230165605293953863745036153391164218332917201371136e+255"},
+ {"0x1.54fdd7f73bf3bp+850", 256, "9999999999999998634272990781441856508941917717432502002131499220055701234712009387201814108283439755324388212283155142447191693008553661974684581490114449895439651479036702276471002178058655944454644452316004196046887318431202624493742403095061074555174912"},
+ {"0x1.54fdd7f73bf3cp+850", 256, "1.000000000000000030127659900140542502890486539774695128832107979903274133377646232821112356269145763568243843017172782817966934136686377344688499501995571998627866456174421380026039705656229556022421593026951037828814135240285311991642941246417639734614426e+256"},
+ {"0x1.aa3d4df50af0ap+853", 257, "99999999999999989676737124254345702129345072534953918593694153358511092545248999754036759991650433313959982558608696795936872226802156842691246641960827039136074540955782045812288811537593838676085587479067054324951381252255327235782798049688841391133687808"},
+ {"0x1.aa3d4df50af0bp+853", 257, "1.0000000000000000301276599001405425028904865397746951288321079799032741333776462328211123562691457635682438430171727828179669341366863773446884995019955719986278664561744213800260397056562295560224215930269510378288141352402853119916429412464176397346144256e+257"},
+ {"0x1.0a6650b926d66p+857", 258, "999999999999999843423255779504622828654636399579476808778874955057845642282427503428069697375447760968142218613652642015929437520555644859802053186653349748453896990911180089361627479263821919056229587496158345417793683435460456504301996197076723582025859072"},
+ {"0x1.0a6650b926d67p+857", 258, "1.0000000000000000567997176316599595992098937026597263174111412691669067749626774798772613075396740496539726465033899457896865765104193391282437061184730323200812906654977415644066700237122877898747347366742071367446741997838317199184059333963234848992699351e+258"},
+ {"0x1.4cffe4e7708c0p+860", 259, "9999999999999999287738405203667575368767393208115766122317814807014700953545274940077463414411382764424743897695475635254322931165011225671787143593812227771048544607458046793796444970432082673836316471673778619485458899748089618699435710767754281089234894848"},
+ {"0x1.4cffe4e7708c1p+860", 259, "1.00000000000000009947501000209102695332094516327577621913759453198871900149872747516709962957251930739113873208133740654443800430839207798193203670483696883440676940041505385941567853260198096403843576650981689501005030305350597260122672083617283716271875031e+259"},
+ {"0x1.a03fde214caf0p+863", 260, "99999999999999992877384052036675753687673932081157661223178148070147009535452749400774634144113827644247438976954756352543229311650112256717871435938122277710485446074580467937964449704320826738363164716737786194854588997480896186994357107677542810892348948480"},
+ {"0x1.a03fde214caf1p+863", 260, "1.0000000000000000653347761057461730700321039947829362977564319217312692202698874789352289719462431012014058636189794379406368620700138868989813722357458196229463864124812040234084717254902264247074749426413290883977494204377665704549700908842933553519596981453e+260"},
+ {"0x1.0427ead4cfed6p+867", 261, "999999999999999928773840520366757536876739320811576612231781480701470095354527494007746341441138276442474389769547563525432293116501122567178714359381222777104854460745804679379644497043208267383631647167377861948545889974808961869943571076775428108923489484800"},
+ {"0x1.0427ead4cfed7p+867", 261, "1.00000000000000014727133745697382238992532279916575210907122218634914869521910346989171855024930599605676474792863856258975960344212154549806296696156457773045130558352244362982576806255843731910178091992569982426727153871554113560598600276880411169778142334157e+261"},
+ {"0x1.4531e58a03e8bp+870", 262, "9999999999999998413748417457239315956573059294699064134960051984423986554086971036541574579178711885967582465059111638997013689862529533948250133185078807957662740116351490992011950708371166466963719380640490770210556304785160923755265983999639546733803159420928"},
+ {"0x1.4531e58a03e8cp+870", 262, "1.000000000000000016172839295009583478096172712153246810967557762960541535300357884361335224964405364288190533033183963151163217246749291739532415400254564758443434909856460259558093923249299888070891356270706646876036149471101831364360543753586901544466663027507e+262"},
+ {"0x1.967e5eec84e2ep+873", 263, "99999999999999987633444125558106197214507928600657449299031571134602723138702925979559301132717802373504470381136572374999373863835222106376649373485721758830170619127941133127257484131955329497127582170538059099205173427703324017329338747068854404759758535917568"},
+ {"0x1.967e5eec84e2fp+873", 263, "1.0000000000000000161728392950095834780961727121532468109675577629605415353003578843613352249644053642881905330331839631511632172467492917395324154002545647584434349098564602595580939232492998880708913562707066468760361494711018313643605437535869015444666630275072e+263"},
+ {"0x1.fc1df6a7a61bap+876", 264, "999999999999999932269800471352470574525516656465243420181212531991832952952360709621889896782068959956303035500093019510461530081711049334072862401016156456358397678710230902586782474091451932211122035531511013345645500354660676649720249983847887046345216426508288"},
+ {"0x1.fc1df6a7a61bbp+876", 264, "1.0000000000000000441405189028952877792863913973825812745630061732834443960830236092744836676918508323988196988775476110313971129684287058746855997333340341924717806535718700452151977396352492066908144631837718580528330325099155496025739750101665730438404785611735e+264"},
+ {"0x1.3d92ba28c7d14p+880", 265, "9999999999999998875215130987353436926211667600983082784284950754751883757000955497608523884181562109792963701491111829020872969270239867178277674680890053619130444887655752455354163678739330224192450644706066754627704874925587274685787599733204126473471115726422016"},
+ {"0x1.3d92ba28c7d15p+880", 265, "1.000000000000000066514662589203851220238566345566048845439364901541766684709156189205002421873807206887323031553038529335584229545772237182808147199797609739694457248544197873740880792744008661586752948714224026994270538940966524193144720015430310243339530988106547e+265"},
+ {"0x1.8cf768b2f9c59p+883", 266, "99999999999999988752151309873534369262116676009830827842849507547518837570009554976085238841815621097929637014911118290208729692702398671782776746808900536191304448876557524553541636787393302241924506447060667546277048749255872746857875997332041264734711157264220160"},
+ {"0x1.8cf768b2f9c5ap+883", 266, "1.0000000000000000307160326911101497147150864284725007320371909363284510229073440613161724151826770077057176992722530600488848430220225870898120712534558888641381746965884733480997879077699935337532513718655005566879705286512849648482315280070083307241410471050136781e+266"},
+ {"0x1.f03542dfb8370p+886", 267, "999999999999999973438224854160227305877518561122823750593712591987145964024444656694044404476868689015149167622996309190165824584023146941018349739309135463248122613459314107074039291811569329219648848907543004197890512187794469896370420793533163493423472892065087488"},
+ {"0x1.f03542dfb8371p+886", 267, "1.00000000000000008799384052806007212355265429582217771348066928066975608179024346593830042588848532639628623092150981090760386146002202723860579276760264226502822677971763258912553652372841773828685389482345810917805054511477545980009263522048349795485862131796226867e+267"},
+ {"0x1.362149cbd3226p+890", 268, "9999999999999999734382248541602273058775185611228237505937125919871459640244446566940444044768686890151491676229963091901658245840231469410183497393091354632481226134593141070740392918115693292196488489075430041978905121877944698963704207935331634934234728920650874880"},
+ {"0x1.362149cbd3227p+890", 268, "1.000000000000000156727209932399979014157735736641790091212843293879322152449722751484854038735455308824968468900617911938066683585621355417158258584578746346096289279472623678356434862878526783727176922373007172166146564870964053742325963876653698631719710373500577382e+268"},
+ {"0x1.83a99c3ec7eafp+893", 269, "99999999999999990012263082286432662256543169091523721434606031123027548865433341877772055077343404109122144711194766809100548098338386355056238620120129111010885594705399027856108106338478634741663761952135733701058809111452663635798820356028494943810497789949089153024"},
+ {"0x1.83a99c3ec7eb0p+893", 269, "1.0000000000000000467538188854561279891896054313304102868413648727440164393945558946103682581803033369390768881340449502893261681846624303314743132774169798163873892798646379355869975202383523110226600782937286713851929332610623034347526380267813775487419678846392834458e+269"},
+ {"0x1.e494034e79e5bp+896", 270, "999999999999999929448868435382686895890266438998271828845121223533023678802377913944250092254807900260792535316367124530669618423639576906744771616444428851364562613616119809966264354755499540137842111275831603885509059543833769773341090453584235060232375896520569913344"},
+ {"0x1.e494034e79e5cp+896", 270, "1.00000000000000004675381888545612798918960543133041028684136487274401643939455589461036825818030333693907688813404495028932616818466243033147431327741697981638738927986463793558699752023835231102266007829372867138519293326106230343475263802678137754874196788463928344576e+270"},
+ {"0x1.2edc82110c2f9p+900", 271, "9999999999999999529098585253973751145501342374646995204443699533752222309208135100774737254399069875964494058799026896824009283758441475916906799486389390443691279468658234350904109878520700943148057046794110173854458342872794765056233999682236635579342942941443126198272"},
+ {"0x1.2edc82110c2fap+900", 271, "1.000000000000000140597779245514880863829076625196121053238359792112810647868298279143262790920699686281704370388187210896251407993480713071257946606195020588405650612863452436083584052624634527730514451908046325384940032234845130363881876085339091539549641475134254271693e+271"},
+ {"0x1.7a93a2954f3b7p+903", 272, "99999999999999991537227438137387396469434575991841521388557198562770454753131655626431591234374844785939841297824578543963083245231683449577722661712772273556182341366629763489177637489755720763166395523368395578554699469776634573397170474480057796161122485794632428945408"},
+ {"0x1.7a93a2954f3b8p+903", 272, "1.0000000000000000655226109574678785641174996701035524401207638566177752810893043715169471647283826068076023845848734024107112161464260868794310399431725879707910415464644008356863148267156087543642309530165922021851423530558188688205784856384929203469035026027382776109466e+272"},
+ {"0x1.d9388b3aa30a5p+906", 273, "999999999999999945402341696592674884578976541955442659132610359825718694242914119314842162820675279649039207299571308833846909191138684972507989282336695782607667040225918275050684065261167516978177354790265605065466066369376850351293060923539046438669680406904714953752576"},
+ {"0x1.d9388b3aa30a6p+906", 273, "1.00000000000000006552261095746787856411749967010355244012076385661777528108930437151694716472838260680760238458487340241071121614642608687943103994317258797079104154646440083568631482671560875436423095301659220218514235305581886882057848563849292034690350260273827761094656e+273"},
+ {"0x1.27c35704a5e67p+910", 274, "9999999999999999213782878444176341486712719163258207029349796604673073768736360688744211624391338142173265718425108901184740478000812045911233791501695173449709921389782217629235579129702792695009666351450002856415308090320884466574359759805482716570229159677380024223137792"},
+ {"0x1.27c35704a5e68p+910", 274, "1.000000000000000113570718661817960035932908921362796352516025255334597915827860472397789165491465537671027655498994239841456938928541047642200260207506944846064391348959793859940567131297385249318652392307122841033012867730395676208292655524474469910197031481071702673824154e+274"},
+ {"0x1.71b42cc5cf601p+913", 275, "99999999999999995981677400789769932612359931733321583285118877944076548466448094957909476304960015890806678857380756006307062602577317320133875536163700284518967198097453618232695975663570046546450378657742479671982722077174989256760731188933351130765773907040474247261585408"},
+ {"0x1.71b42cc5cf602p+913", 275, "1.0000000000000001135707186618179600359329089213627963525160252553345979158278604723977891654914655376710276554989942398414569389285410476422002602075069448460643913489597938599405671312973852493186523923071228410330128677303956762082926555244744699101970314810717026738241536e+275"},
+ {"0x1.ce2137f743381p+916", 276, "999999999999999929065985077113647184161737396527299728918221484261998998431805045015355882561227083155474615188770224107393363445219598313166454392463014445014728107377484646804238281703363508693674065431485187857190091380020735839470243162305319587149880588271350432374194176"},
+ {"0x1.ce2137f743382p+916", 276, "1.00000000000000005206914080024985575200918507975096414465009066497706494336250866327031140451471938616584330872891956793010241376743389786585565826915896804571450360176569078889512418143271133577699295001524362330773860894693736275201851807041808646918131451680491859334083379e+276"},
+ {"0x1.20d4c2fa8a030p+920", 277, "9999999999999998060628293539774386163142897133036353131863523035469330535011014267604003606077347801451059216486208802846843131230052987604772505157670608443149526129892785047133523819740156816103551808477267524066415738131041089269219682541925527051184466597377822714075545600"},
+ {"0x1.20d4c2fa8a031p+920", 277, "1.000000000000000002867878510995372324870206006461498378357342992691038565390227215968329195733322464961695831312859830401018793638548178044779976718480586605434593404010408332058769821540972204943665396181740249127519201920170711986999208107172979716368740945391491328954177946e+277"},
+ {"0x1.6909f3b92c83dp+923", 278, "99999999999999996350686867959178558315902274782992576532314485486221746301240205812674342870820492799837784938001204037775189753543960218791943147793788145321066524580618236658968633362758090027700335311493754978334367629875739137498376013657689431411868208826074951744485326848"},
+ {"0x1.6909f3b92c83ep+923", 278, "1.000000000000000120950908005206132550003755782356216217459937406177501872523702689493086496808675075851649777111403200470819481947873905615361612440108702062106377878623086228466020285281146118943651525382148347160045778784410673823045552018961235923118917516783716763482151977e+278"},
+ {"0x1.c34c70a777a4cp+926", 279, "999999999999999932018060814468916189790076140924667674895786344599160581110141931853474815088110898427723463833733808359138380652952741502430995285503717331431522719242801594214419543296867856543673718661495390308003255801626734885371401760100025992318635002556156068237393526784"},
+ {"0x1.c34c70a777a4dp+926", 279, "1.00000000000000005797329227496039376326586256854570003660522038565138810871918243694654926956848701671034100601884673643359244818290018424438474005524037381854809282549632468371548670461972003147699225647526402820936493779014936084382083526600749927951882334537452986506723249357e+279"},
+ {"0x1.1a0fc668aac6fp+930", 280, "9999999999999998312538756460757341310094469988278417855282391117573785590229095277790152515038100038016294300856434658995751266289947873088679994697143921417382666342399831226135658142385861165970188884104804799869139102108086341186118549553740473625584843283014570307735223533568"},
+ {"0x1.1a0fc668aac70p+930", 280, "1.000000000000000032782245982862098248570705283021493564263333577440942603197374335927934378672411793053817497581824150818701634676910695695993991101293042521124778804245620065815273272355149596490328548912510300629092601392444835652130948564826004622078785676810855105701264700211e+280"},
+ {"0x1.6093b802d578bp+933", 281, "99999999999999987155954971343300695452169865566657214127525800489409136785780248940879907693753036165206704358487960288340042823857796898629319779603012221761556906824111051125390730586189881257568082051088644411534964844713587442531567367726443881446254459800333664575907082272768"},
+ {"0x1.6093b802d578cp+933", 281, "1.0000000000000000327822459828620982485707052830214935642633335774409426031973743359279343786724117930538174975818241508187016346769106956959939911012930425211247788042456200658152732723551495964903285489125103006290926013924448356521309485648260046220787856768108551057012647002112e+281"},
+ {"0x1.b8b8a6038ad6ep+936", 282, "999999999999999903804088967318825213331499981137556425872873119403461614925716858712626137284506647932417134384268512470460669526244514328233356457082706278317411015442012422166180499160548969358610366191211215418098239036197666670678728654776751975985792813764840337747509598224384"},
+ {"0x1.b8b8a6038ad6fp+936", 282, "1.0000000000000000327822459828620982485707052830214935642633335774409426031973743359279343786724117930538174975818241508187016346769106956959939911012930425211247788042456200658152732723551495964903285489125103006290926013924448356521309485648260046220787856768108551057012647002112e+282"},
+ {"0x1.137367c236c65p+940", 283, "9999999999999999553953517735361344274271821018911312812290573026184540102343798495987494338396687059809772796632907678097570555865109868753376103147668407754403581309634554796258176084383892202112976392797308495024959839786965342632596166187964530344229899589832462449290116390191104"},
+ {"0x1.137367c236c66p+940", 283, "1.000000000000000161760402998405371283809910584905430702653794035478423591469031813143242620060316938175217860779379789166942599827576877063754625745503378763932146593049227709464366045549750223622046731633809385840086963748692004633583168474875257268171778539856869873655019802198016e+283"},
+ {"0x1.585041b2c477ep+943", 284, "99999999999999991412234152856228705615063640528827139694410995604646009398744945688985079659553905954212916344007296353831994673829780883765420722861953317774200043854630103365810792101611701952914782080891514223497778802469744018919490624758069218767323224280852151918381000638332928"},
+ {"0x1.585041b2c477fp+943", 284, "1.0000000000000000792143825084576765412568191916997109340838993423344357589751710277254453455720576452975216283329441806240683821311505209883878195732087635685354312082149188175289466707052058222577470946921779713050505718406938164854537477324437355746722631075074204221646165369264538e+284"},
+ {"0x1.ae64521f7595ep+946", 285, "999999999999999980159157920520442850193109519852847211800025710561650359982538085224088616186146493844286149397221450372619320895438893697947652166455225334059372746413748147206443420891752540620587530362220273863006901551095990707698442841525909542472844588688081080376132618600579072"},
+ {"0x1.ae64521f7595fp+946", 285, "1.00000000000000011223279070443675443827805574898199884151185721959203089197271534189256425536736136244860012131151842404121806920972106341853454204212660964669411736214864237430311442064302358280346694946883053711906512860389309174470551602941634425207206928044720020276077784303507866e+285"},
+ {"0x1.0cfeb353a97dap+950", 286, "9999999999999998216707985798208689444911740448978652561458278997251937215943253772219178491686886515191093831000650819703008229183002900332433843156495641588976792075318750746904382211902272900011322274342879579557370290877394694632899550160573878909537749585771381335145583492791795712"},
+ {"0x1.0cfeb353a97dbp+950", 286, "1.000000000000000032988611034086967485427088011504507863684758314173802572778608987891478871858632441286011738162940239840058820221151761586182408116723779059113270592707705838045111820792260957493739298004864379165430192372214831122501272116682083426312534465391728729329990708374378906e+286"},
+ {"0x1.503e602893dd1p+953", 287, "99999999999999990619792356152730836086553963154052229916140006550463726206803882148974225824466616742587032512521514511820402183944087865441899383607925011898391576160220738003230766103104075699817505566251852643961429440152961412697448185630726610509727876130297437184073129291725930496"},
+ {"0x1.503e602893dd2p+953", 287, "1.0000000000000000752521735249401871936142708048258363851925443970635243430154657100253910763966211992393922091755152714140104196817220558967702128769386220391563888697428719907160465407126676909922607121189796634073688250291099034543435355368070225333842863667546468484930771801934187725e+287"},
+ {"0x1.a44df832b8d45p+956", 288, "999999999999999872387073568844732594315793396883459481955171199192859845878553443782612494614275161063165948315155119859042742270984643205948750027907375734949421139974074457895559885094715370199357924371226299046063388276013556261500671120207314819439877240212639876510262115462027411456"},
+ {"0x1.a44df832b8d46p+956", 288, "1.00000000000000000763047353957503566051477833551171075078008666443996951063649495461113154913583918651398345555539522089568786054480958499982972526059487327108739962648660614644255098884001691739462644953639520862026701277807778772339591406460711996206948332457397785783213882528295498547e+288"},
+ {"0x1.06b0bb1fb384bp+960", 289, "9999999999999998453383935746986719810759964091578092281901881061434379129269651416169086837099623559730024468671070996517137186162196548471725549813698762277218254426715681201861616643456550607603042193381925171312226633756007099691216225313273537909139560233403722802458867734978418966528"},
+ {"0x1.06b0bb1fb384cp+960", 289, "1.000000000000000061727833527867156886994372310963011258310052850538813376539671558942539170944464796694310458451491261310345907854339561717382115353669872285542591021091618821861347430338137536272733859602462772449948462578903480308154011242367042019121325758318513050360889509211326015078e+289"},
+ {"0x1.485ce9e7a065ep+963", 290, "99999999999999988861628156533236896225967158951884963421416105502251300564950642508203478115686284411726404918398393198344015646384363622121446705582987543928597855835557826052119881754415155586279014739104656819496782321626126403692810027353529143655542997033600043426888732064053872033792"},
+ {"0x1.485ce9e7a065fp+963", 290, "1.0000000000000000617278335278671568869943723109630112583100528505388133765396715589425391709444647966943104584514912613103459078543395617173821153536698722855425910210916188218613474303381375362727338596024627724499484625789034803081540112423670420191213257583185130503608895092113260150784e+290"},
+ {"0x1.9a742461887f6p+966", 291, "999999999999999957860902350346284132153551878096514283852517773229033154005572478626236537071903625148082612890986863714202457020042006419681526374965874177788623543449994485057258262661745948026767632275613049896960078961318150545418464661067991669581788285529005480705688196068853638234112"},
+ {"0x1.9a742461887f7p+966", 291, "1.0000000000000000963501439203741144719413124552518435831292312096420734507177045857146400489019851872097197403049927271757270581324387468166156450132378716547939135136388269341293771528969347323547226020447460133009445904514319235623991934361333921356345049159150155735792899469254834740265e+291"},
+ {"0x1.008896bcf54f9p+970", 292, "9999999999999997916738124663128877244082391855101191247204616495333847979510139501201523228758057506741180599941798275603729356851659179433605840090394772053822755792233955461707155943795194068332216685526534938121786651731816229250415901309895111103185283290657933692573660950408978352832512"},
+ {"0x1.008896bcf54fap+970", 292, "1.000000000000000013256598978357416268068656108958646003563203147794249272690425321461597941803936249972737463856589209098812297465000702578455173830274673168590739531525527464686105818755821461757949620183266235258553883557363659752210756171094151856002874937683409517855128896411505572551066e+292"},
+ {"0x1.40aabc6c32a38p+973", 293, "99999999999999992462348437353960485060448933957923525202610654848990348279466077292501969423268405025328970231162545648343655275306678872441733790178059478330735395060467469727994972900530063978805843953102113868000379620369084502134308975505229555772913629423636305841602377586326247764393984"},
+ {"0x1.40aabc6c32a39p+973", 293, "1.0000000000000001018897135831752276855328228783380567551002997470985950625861898699981761893751884496921852254015529617141880421769346164324930097587687515538741251124463802320922619085063422837278408008355113318371039709110364744830784225871360081542766135811304559772942340169597486674581914e+293"},
+ {"0x1.90d56b873f4c6p+976", 294, "999999999999999924623484373539604850604489339579235252026106548489903482794660772925019694232684050253289702311625456483436552753066788724417337901780594783307353950604674697279949729005300639788058439531021138680003796203690845021343089755052295557729136294236363058416023775863262477643939840"},
+ {"0x1.90d56b873f4c7p+976", 294, "1.00000000000000006643646774124810311854715617058629245448546110737685674662788405058354489034668756980440612078356746066803774429216105089087787538737112019976077088007803912512979947260613395493988432857461329320568393596956734859073135602071926563496711812375163739351859196874045142949534106e+294"},
+ {"0x1.f50ac6690f1f8p+979", 295, "9999999999999999813486777206230041577815560719820581330098483720446847883279500839884297726782854580737362697004022581572770293687044935910015528960168049498887207223940204684198896264456339658487887951484580004902758521100414464490983962613190835886243290260424727924570510530141380583845003264"},
+ {"0x1.f50ac6690f1f9p+979", 295, "1.000000000000000094799064414789802772135689536787703894977332019154247399394528706115249929569488273714629404477955861504957982599979903324169982884489225283051454265972712010699769421326300617970249506383331724110819963922742649304609009273852659650414714489654692260539105607315889219865621299e+295"},
+ {"0x1.3926bc01a973bp+983", 296, "99999999999999998134867772062300415778155607198205813300984837204468478832795008398842977267828545807373626970040225815727702936870449359100155289601680494988872072239402046841988962644563396584878879514845800049027585211004144644909839626131908358862432902604247279245705105301413805838450032640"},
+ {"0x1.3926bc01a973cp+983", 296, "1.0000000000000001628692964312898819407481696156710913521578222074199849660344758793913420237042099630991652853444880235135665545387451491640710408775726774829490943921199269360676972982547006092431259331242559582831464310103633710179153770813728052874889457678220239413883383398969399167542938829e+296"},
+ {"0x1.87706b0213d09p+986", 297, "999999999999999872436306494222877488001587945768638201521064070819504681704034606746682422062730755058478860313950798943503314266680100247159860107083281430052496520558476587831205023360193979812186512362979225814553504769848291707808207769286850569305558980974742103098278680884456943362624192512"},
+ {"0x1.87706b0213d0ap+986", 297, "1.0000000000000000176528014627563797143748787807198647768394431391197448238692552430690122228834703590788220728292194112285349344027126247056154504923279794565007954563392017619494511608074472945276562227436175920488499678901058313628617924253298279283972523743983830222433085103906984300584590377e+297"},
+ {"0x1.e94c85c298c4cp+989", 298, "9999999999999999595662034753429788238255624467393741467120915117996487670031669885400803025551745174706847878231119663145222863482996149222332143382301002459214758820269116923021527058285459686414683385913622455551313826420028155008403585629126369847605750170289266545852965785882018353801250996224"},
+ {"0x1.e94c85c298c4dp+989", 298, "1.00000000000000007573939945016978060492419511470035540696679476643984088073534349759794414321176620068695935783532685614254758245712563448899768664642585866708011503065149183159674961578634862041384410689587293854256855313820884722488322628774701887203392973176783938990132044219319502473679297577e+298"},
+ {"0x1.31cfd3999f7afp+993", 299, "99999999999999986662764669548153739894665631237058913850832890808749507601742578129378923002990117089766513181334005445210204946123879926882163649167349350899456456312724758086647517786230384722356772394775369116518164624503799012160606438304513147494189124523779646633247748770420728389479079870464"},
+ {"0x1.31cfd3999f7b0p+993", 299, "1.0000000000000000525047602552044202487044685811081591549158541155118024579889081957863713750804478640437044438328838781769425232353604305756447921847867069828483872009265758037378302337947880900593689532349707999450811190389676408800746527427801424945792587888200568428381156694721963868654594005402e+299"},
+ {"0x1.7e43c8800759bp+996", 300, "999999999999999903803069407426113968898218766118103141789833949572356552411722264192305659040010509526872994217248819197070144216063125530186267630296136203765329090687113225440746189048800695790727969805197112921161540803823920273299782054992133678869364753954248541633605124057805104488924519071744"},
+ {"0x1.7e43c8800759cp+996", 300, "1.00000000000000005250476025520442024870446858110815915491585411551180245798890819578637137508044786404370444383288387817694252323536043057564479218478670698284838720092657580373783023379478809005936895323497079994508111903896764088007465274278014249457925878882005684283811566947219638686545940054016e+300"},
+ {"0x1.ddd4baa009302p+999", 301, "9999999999999999335434075769817752248594687291161143444150379827602457335271594505111188022480979804302392841403758309930446200199225865392779725411942503595819407127350057411001629979979981746444561664911518503259454564508526643946547561925497354420113435609274102018745072331406833609642314953654272"},
+ {"0x1.ddd4baa009303p+999", 301, "1.00000000000000005250476025520442024870446858110815915491585411551180245798890819578637137508044786404370444383288387817694252323536043057564479218478670698284838720092657580373783023379478809005936895323497079994508111903896764088007465274278014249457925878882005684283811566947219638686545940054016e+301"},
+ {"0x1.2aa4f4a405be1p+1003", 302, "99999999999999988595886650569271721532146878831929642021471152965962304374245995240101777311515802698485322026337261211948545873374744892473124468375726771027536211745837771604509610367928220847849105179362427047829119141560667380048679757245757262098417746977035154548906385860807815060374033329553408"},
+ {"0x1.2aa4f4a405be2p+1003", 302, "1.0000000000000000762970307908489492534734685515065681170160173420621138028812579448414218896469178407663974757713854876137221038784479993829181561135051983075016764985648898162653636809541460731423515105837345898689082515565906361771586320528262239050928418343985861710308373567384989920457049815751066e+302"},
+ {"0x1.754e31cd072d9p+1006", 303, "999999999999999847891233648661470807691068835681842080854450367179124891914700353912936949808806064228544369161770037020638129704807338833093862397807681590830099241237075296001042588224309435545718960035602206600167779387409881325152430676383842364162444596844704620380709158981993982315347403639619584"},
+ {"0x1.754e31cd072dap+1006", 303, "1.00000000000000000016176507678645643821266864623165943829549501710111749922573874786526024303421391525377977356818033741602744582056777919964339154160602606861115074612228497617725665004420052727680732706769046211266142750019705122648989826067876339144937608854729232081412795748633065546891912226327757e+303"},
+ {"0x1.d2a1be4048f90p+1009", 304, "9999999999999999392535525055364621860040287220117324953190771571323204563013233902843309257440507748436856118056162172578717193742636030530235798840866882774987301441682011041067710253162440905843719802548551599076639682550821832659549112269607949805346034918662572406407604380845959862074904348138143744"},
+ {"0x1.d2a1be4048f91p+1009", 304, "1.000000000000000061069977648036450690421308570451586381271912877069914542150154105446189560324377055663873935330744457574183172266871955346263203199125363859723571348076368848247742274772156963969242673880525764317658886745311919187024885294396731802364148685228327400987495476888065324730347809712740762e+304"},
+ {"0x1.23a516e82d9bap+1013", 305, "99999999999999993925355250553646218600402872201173249531907715713232045630132339028433092574405077484368561180561621725787171937426360305302357988408668827749873014416820110410677102531624409058437198025485515990766396825508218326595491122696079498053460349186625724064076043808459598620749043481381437440"},
+ {"0x1.23a516e82d9bbp+1013", 305, "1.0000000000000001341598327335364437930716764795154987128436143090324709936594525345433047410725728241559869294458214017639700440024369667222069771881485692090584760704212694947323250244457046880001650900559281269636558378394497607396668697348582938954618758012455694971955365001701469278440622346520965939e+305"},
+ {"0x1.6c8e5ca239028p+1016", 306, "999999999999999861291040414336469543176969619010226008309262296372260241358071732580741399612641955118765084749534143455432389522994257585350220962461935904874831773666973747856549425664459851618054736334425973085267220421335152276470127823801795414563694568114532338018850013250375609552861714878501486592"},
+ {"0x1.6c8e5ca239029p+1016", 306, "1.00000000000000001721606459673645482883108782501323898232889201789238067124457504798792045187545959456860613886169829106031104922553294852069693880571144065012262851466942846035699262496802832955068922417528434673006071608882921425543969463011979454650551241561798214326267086291881636286211915474912726221e+306"},
+ {"0x1.c7b1f3cac7433p+1019", 307, "9999999999999999860310597602564577717002641838126363875249660735883565852672743849064846414228960666786379280392654615393353172850252103336275952370615397010730691664689375178569039851073146339641623266071126720011020169553304018596457812688561947201171488461172921822139066929851282122002676667750021070848"},
+ {"0x1.c7b1f3cac7434p+1019", 307, "1.000000000000000110771079106176446000223558748615046766740669850804452929176477037232227883233150178238510771328996779623238245047056163081904969511661143497271306559270901287857258544550169416310269916879799370916936813489325651442821434713910594025670603124120052026408963372719880814847673618671502727578e+307"},
+ {"0x1.1ccf385ebc89fp+1023", 308, "99999999999999981139503267596847425176765179308926185662298078548582170379439067165044410288854031049481594743364161622187121841818187648603927125262209438639553681654618823985640760188731793867961170022535129351893330180773705244319986644578003569234231285691342840034082734135647456849389933411990123839488"},
+ {"0x1.1ccf385ebc8a0p+1023", 308, "1.0000000000000000109790636294404554174049230967731184633681068290315758540491149153716332897849468889906124966972117251561159028374314008832830700919814604603127166450293302718569748969958855904333838446616500117842689762621294517762809119578670745812278397017178441510529180289320787327297488571543022311834e+308"},
+ {"0x1.a36e2eb1c432cp-14", 309, "9.99999999999999912396464463171241732197813689708709716796875e-5"},
+ {"0x1.a36e2eb1c432dp-14", 309, "0.000100000000000000004792173602385929598312941379845142364501953125"},
+ {"0x1.0624dd2f1a9fbp-10", 309, "0.00099999999999999980397624721462079833145253360271453857421875"},
+ {"0x1.0624dd2f1a9fcp-10", 309, "0.001000000000000000020816681711721685132943093776702880859375"},
+ {"0x1.47ae147ae147ap-7", 309, "0.0099999999999999984734433411404097569175064563751220703125"},
+ {"0x1.47ae147ae147bp-7", 309, "0.01000000000000000020816681711721685132943093776702880859375"},
+ {"0x1.9999999999999p-4", 309, "0.09999999999999999167332731531132594682276248931884765625"},
+ {"0x1.999999999999ap-4", 309, "0.1000000000000000055511151231257827021181583404541015625"},
+ {"0x1.fffffffffffffp-1", 309, "0.99999999999999988897769753748434595763683319091796875"},
+ {"0x1.0000000000000p+0", 309, "1"},
+ {"0x1.3ffffffffffffp+3", 309, "9.9999999999999982236431605997495353221893310546875"},
+ {"0x1.4000000000000p+3", 309, "10"},
+ {"0x1.8ffffffffffffp+6", 309, "99.9999999999999857891452847979962825775146484375"},
+ {"0x1.9000000000000p+6", 309, "100"},
+ {"0x1.f3fffffffffffp+9", 309, "999.9999999999998863131622783839702606201171875"},
+ {"0x1.f400000000000p+9", 309, "1000"},
+ {"0x1.387ffffffffffp+13", 309, "9999.999999999998181010596454143524169921875"},
+ {"0x1.3880000000000p+13", 309, "10000"},
+ {"0x1.869ffffffffffp+16", 309, "99999.999999999985448084771633148193359375"},
+ {"0x1.86a0000000000p+16", 309, "100000"},
+ {"0x1.e847fffffffffp+19", 309, "999999.999999999883584678173065185546875"},
+ {"0x1.e848000000000p+19", 309, "1000000"},
+ {"0x1.312cfffffffffp+23", 309, "9999999.99999999813735485076904296875"},
+ {"0x1.312d000000000p+23", 309, "10000000"},
+ {"0x1.7d783ffffffffp+26", 309, "99999999.99999998509883880615234375"},
+ {"0x1.7d78400000000p+26", 309, "100000000"},
+ {"0x1.dcd64ffffffffp+29", 309, "999999999.99999988079071044921875"},
+ {"0x1.dcd6500000000p+29", 309, "1000000000"},
+ {"0x1.2a05f1fffffffp+33", 309, "9999999999.9999980926513671875"},
+ {"0x1.2a05f20000000p+33", 309, "10000000000"},
+ {"0x1.74876e7ffffffp+36", 309, "99999999999.9999847412109375"},
+ {"0x1.74876e8000000p+36", 309, "100000000000"},
+ {"0x1.d1a94a1ffffffp+39", 309, "999999999999.9998779296875"},
+ {"0x1.d1a94a2000000p+39", 309, "1000000000000"},
+ {"0x1.2309ce53fffffp+43", 309, "9999999999999.998046875"},
+ {"0x1.2309ce5400000p+43", 309, "10000000000000"},
+ {"0x1.6bcc41e8fffffp+46", 309, "99999999999999.984375"},
+ {"0x1.6bcc41e900000p+46", 309, "100000000000000"},
+ {"0x1.c6bf52633ffffp+49", 309, "999999999999999.875"},
+ {"0x1.c6bf526340000p+49", 309, "1000000000000000"},
+ {"0x1.1c37937e07fffp+53", 309, "9999999999999998"},
+ {"0x1.1c37937e08000p+53", 309, "10000000000000000"},
+ {"0x1.6345785d89fffp+56", 309, "99999999999999984"},
+ {"0x1.6345785d8a000p+56", 309, "100000000000000000"},
+ {"0x1.bc16d674ec7ffp+59", 309, "999999999999999872"},
+ {"0x1.bc16d674ec800p+59", 309, "1000000000000000000"},
+ {"0x1.158e460913cffp+63", 309, "9999999999999997952"},
+ {"0x1.158e460913d00p+63", 309, "10000000000000000000"},
+ {"0x1.5af1d78b58c3fp+66", 309, "99999999999999983616"},
+ {"0x1.5af1d78b58c40p+66", 309, "100000000000000000000"},
+ {"0x1.b1ae4d6e2ef4fp+69", 309, "999999999999999868928"},
+ {"0x1.b1ae4d6e2ef50p+69", 309, "1000000000000000000000"},
+ {"0x1.0f0cf064dd591p+73", 309, "9999999999999997902848"},
+ {"0x1.0f0cf064dd592p+73", 309, "10000000000000000000000"},
+ {"0x1.52d02c7e14af6p+76", 309, "99999999999999991611392"},
+ {"0x1.52d02c7e14af7p+76", 309, "100000000000000008388608"},
+ {"0x1.a784379d99db4p+79", 309, "999999999999999983222784"},
+ {"0x1.a784379d99db5p+79", 309, "1000000000000000117440512"},
+ {"0x1.08b2a2c280290p+83", 309, "9999999999999998758486016"},
+ {"0x1.08b2a2c280291p+83", 309, "10000000000000000905969664"},
+ {"0x1.4adf4b7320334p+86", 309, "99999999999999987584860160"},
+ {"0x1.4adf4b7320335p+86", 309, "100000000000000004764729344"},
+ {"0x1.9d971e4fe8401p+89", 309, "999999999999999875848601600"},
+ {"0x1.9d971e4fe8402p+89", 309, "1000000000000000013287555072"},
+ {"0x1.027e72f1f1281p+93", 309, "9999999999999999583119736832"},
+ {"0x1.027e72f1f1282p+93", 309, "10000000000000001782142992384"},
+ {"0x1.431e0fae6d721p+96", 309, "99999999999999991433150857216"},
+ {"0x1.431e0fae6d722p+96", 309, "100000000000000009025336901632"},
+ {"0x1.93e5939a08ce9p+99", 309, "999999999999999879147136483328"},
+ {"0x1.93e5939a08ceap+99", 309, "1000000000000000019884624838656"},
+ {"0x1.f8def8808b024p+102", 309, "9999999999999999635896294965248"},
+ {"0x1.f8def8808b025p+102", 309, "10000000000000000761796201807872"},
+ {"0x1.3b8b5b5056e16p+106", 309, "99999999999999987351763694911488"},
+ {"0x1.3b8b5b5056e17p+106", 309, "100000000000000005366162204393472"},
+ {"0x1.8a6e32246c99cp+109", 309, "999999999999999945575230987042816"},
+ {"0x1.8a6e32246c99dp+109", 309, "1000000000000000089690419062898688"},
+ {"0x1.ed09bead87c03p+112", 309, "9999999999999999455752309870428160"},
+ {"0x1.ed09bead87c04p+112", 309, "10000000000000000608673814477275136"},
+ {"0x1.3426172c74d82p+116", 309, "99999999999999996863366107917975552"},
+ {"0x1.3426172c74d83p+116", 309, "100000000000000015310110181627527168"},
+ {"0x1.812f9cf7920e2p+119", 309, "999999999999999894846684784341549056"},
+ {"0x1.812f9cf7920e3p+119", 309, "1000000000000000042420637374017961984"},
+ {"0x1.e17b84357691bp+122", 309, "9999999999999999538762658202121142272"},
+ {"0x1.e17b84357691cp+122", 309, "10000000000000000719354278919532445696"},
+ {"0x1.2ced32a16a1b1p+126", 309, "99999999999999997748809823456034029568"},
+ {"0x1.2ced32a16a1b2p+126", 309, "100000000000000016638275754934614884352"},
+ {"0x1.78287f49c4a1dp+129", 309, "999999999999999939709166371603178586112"},
+ {"0x1.78287f49c4a1ep+129", 309, "1000000000000000090824893823431825424384"},
+ {"0x1.d6329f1c35ca4p+132", 309, "9999999999999999094860208812374492184576"},
+ {"0x1.d6329f1c35ca5p+132", 309, "10000000000000000303786028427003666890752"},
+ {"0x1.25dfa371a19e6p+136", 309, "99999999999999981277195531206711524196352"},
+ {"0x1.25dfa371a19e7p+136", 309, "100000000000000000620008645040778319495168"},
+ {"0x1.6f578c4e0a060p+139", 309, "999999999999999890143207767403382423158784"},
+ {"0x1.6f578c4e0a061p+139", 309, "1000000000000000044885712678075916785549312"},
+ {"0x1.cb2d6f618c878p+142", 309, "9999999999999998901432077674033824231587840"},
+ {"0x1.cb2d6f618c879p+142", 309, "10000000000000000139372116959414099130712064"},
+ {"0x1.1efc659cf7d4bp+146", 309, "99999999999999989014320776740338242315878400"},
+ {"0x1.1efc659cf7d4cp+146", 309, "100000000000000008821361405306422640701865984"},
+ {"0x1.66bb7f0435c9ep+149", 309, "999999999999999929757289024535551219930759168"},
+ {"0x1.66bb7f0435c9fp+149", 309, "1000000000000000088213614053064226407018659840"},
+ {"0x1.c06a5ec5433c6p+152", 309, "9999999999999999931398190359470212947659194368"},
+ {"0x1.c06a5ec5433c7p+152", 309, "10000000000000001199048790587699614444362399744"},
+ {"0x1.18427b3b4a05bp+156", 309, "99999999999999984102174700855949311516153479168"},
+ {"0x1.18427b3b4a05cp+156", 309, "100000000000000004384584304507619735463404765184"},
+ {"0x1.5e531a0a1c872p+159", 309, "999999999999999881586566215862833963056037363712"},
+ {"0x1.5e531a0a1c873p+159", 309, "1000000000000000043845843045076197354634047651840"},
+ {"0x1.b5e7e08ca3a8fp+162", 309, "9999999999999999464902769475481793196872414789632"},
+ {"0x1.b5e7e08ca3a90p+162", 309, "10000000000000000762976984109188700329496497094656"},
+ {"0x1.11b0ec57e6499p+166", 309, "99999999999999986860582406952576489172979654066176"},
+ {"0x1.11b0ec57e649ap+166", 309, "100000000000000007629769841091887003294964970946560"},
+ {"0x1.561d276ddfdc0p+169", 309, "999999999999999993220948674361627976461708441944064"},
+ {"0x1.561d276ddfdc1p+169", 309, "1000000000000000159374448147476112089437590976987136"},
+ {"0x1.aba4714957d30p+172", 309, "9999999999999999932209486743616279764617084419440640"},
+ {"0x1.aba4714957d31p+172", 309, "10000000000000001261437482528532152668424144699785216"},
+ {"0x1.0b46c6cdd6e3ep+176", 309, "99999999999999999322094867436162797646170844194406400"},
+ {"0x1.0b46c6cdd6e3fp+176", 309, "100000000000000020589742799994816764107083808679919616"},
+ {"0x1.4e1878814c9cdp+179", 309, "999999999999999908150356944127012110618056584002011136"},
+ {"0x1.4e1878814c9cep+179", 309, "1000000000000000078291540404596243842305360299886116864"},
+ {"0x1.a19e96a19fc40p+182", 309, "9999999999999998741221202520331657642805958408251899904"},
+ {"0x1.a19e96a19fc41p+182", 309, "10000000000000000102350670204085511496304388135324745728"},
+ {"0x1.05031e2503da8p+186", 309, "99999999999999987412212025203316576428059584082518999040"},
+ {"0x1.05031e2503da9p+186", 309, "100000000000000009190283508143378238084034459715684532224"},
+ {"0x1.4643e5ae44d12p+189", 309, "999999999999999874122120252033165764280595840825189990400"},
+ {"0x1.4643e5ae44d13p+189", 309, "1000000000000000048346692115553659057528394845890514255872"},
+ {"0x1.97d4df19d6057p+192", 309, "9999999999999999438119489974413630815797154428513196965888"},
+ {"0x1.97d4df19d6058p+192", 309, "10000000000000000831916064882577577161779546469035791089664"},
+ {"0x1.fdca16e04b86dp+195", 309, "99999999999999997168788049560464200849936328366177157906432"},
+ {"0x1.fdca16e04b86ep+195", 309, "100000000000000008319160648825775771617795464690357910896640"},
+ {"0x1.3e9e4e4c2f344p+199", 309, "999999999999999949387135297074018866963645011013410073083904"},
+ {"0x1.3e9e4e4c2f345p+199", 309, "1000000000000000127793096885319003999249391192200302120927232"},
+ {"0x1.8e45e1df3b015p+202", 309, "9999999999999999493871352970740188669636450110134100730839040"},
+ {"0x1.8e45e1df3b016p+202", 309, "10000000000000000921119045676700069727922419559629237113585664"},
+ {"0x1.f1d75a5709c1ap+205", 309, "99999999999999992084218144295482124579792562202350734542897152"},
+ {"0x1.f1d75a5709c1bp+205", 309, "100000000000000003502199685943161173046080317798311825604870144"},
+ {"0x1.3726987666190p+209", 309, "999999999999999875170255276364105051932774599639662981181079552"},
+ {"0x1.3726987666191p+209", 309, "1000000000000000057857959942726969827393378689175040438172647424"},
+ {"0x1.84f03e93ff9f4p+212", 309, "9999999999999998751702552763641050519327745996396629811810795520"},
+ {"0x1.84f03e93ff9f5p+212", 309, "10000000000000000213204190094543968723012578712679649467743338496"},
+ {"0x1.e62c4e38ff872p+215", 309, "99999999999999999209038626283633850822756121694230455365568299008"},
+ {"0x1.e62c4e38ff873p+215", 309, "100000000000000010901051724930857196452234783424494612613028642816"},
+ {"0x1.2fdbb0e39fb47p+219", 309, "999999999999999945322333868247445125709646570021247924665841614848"},
+ {"0x1.2fdbb0e39fb48p+219", 309, "1000000000000000132394543446603018655781305157705474440625207115776"},
+ {"0x1.7bd29d1c87a19p+222", 309, "9999999999999999827367757839185598317239782875580932278577147150336"},
+ {"0x1.7bd29d1c87a1ap+222", 309, "10000000000000001323945434466030186557813051577054744406252071157760"},
+ {"0x1.dac74463a989fp+225", 309, "99999999999999995280522225138166806691251291352861698530421623488512"},
+ {"0x1.dac74463a98a0p+225", 309, "100000000000000007253143638152923512615837440964652195551821015547904"},
+ {"0x1.28bc8abe49f63p+229", 309, "999999999999999880969493773293127831364996015857874003175819882528768"},
+ {"0x1.28bc8abe49f64p+229", 309, "1000000000000000072531436381529235126158374409646521955518210155479040"},
+ {"0x1.72ebad6ddc73cp+232", 309, "9999999999999999192818822949403492903236716946156035936442979371188224"},
+ {"0x1.72ebad6ddc73dp+232", 309, "10000000000000000725314363815292351261583744096465219555182101554790400"},
+ {"0x1.cfa698c95390bp+235", 309, "99999999999999991928188229494034929032367169461560359364429793711882240"},
+ {"0x1.cfa698c95390cp+235", 309, "100000000000000004188152556421145795899143386664033828314342771180699648"},
+ {"0x1.21c81f7dd43a7p+239", 309, "999999999999999943801810948794571024057224129020550531544123892056457216"},
+ {"0x1.21c81f7dd43a8p+239", 309, "1000000000000000139961240179628344893925643604260126034742731531557535744"},
+ {"0x1.6a3a275d49491p+242", 309, "9999999999999999830336967949613257980309080240684656321838454199566729216"},
+ {"0x1.6a3a275d49492p+242", 309, "10000000000000001399612401796283448939256436042601260347427315315575357440"},
+ {"0x1.c4c8b1349b9b5p+245", 309, "99999999999999995164818811802792197885196090803013355167206819763650035712"},
+ {"0x1.c4c8b1349b9b6p+245", 309, "100000000000000007719022282576153725556774937218346187371917708691719061504"},
+ {"0x1.1afd6ec0e1411p+249", 309, "999999999999999926539781176481198923508803215199467887262646419780362305536"},
+ {"0x1.1afd6ec0e1412p+249", 309, "1000000000000000127407036708854983366254064757844793202538020642629466718208"},
+ {"0x1.61bcca7119915p+252", 309, "9999999999999998863663300700064420349597509066704028242075715752105414230016"},
+ {"0x1.61bcca7119916p+252", 309, "10000000000000000470601344959054695891559601407866630764278709534898249531392"},
+ {"0x1.ba2bfd0d5ff5bp+255", 309, "99999999999999998278261272554585856747747644714015897553975120217811154108416"},
+ {"0x1.ba2bfd0d5ff5cp+255", 309, "100000000000000011133765626626508061083444383443316717731599070480153836519424"},
+ {"0x1.145b7e285bf98p+259", 309, "999999999999999802805551768538947706777722104929947493053015898505313987330048"},
+ {"0x1.145b7e285bf99p+259", 309, "1000000000000000008493621433689702976148869924598760615894999102702796905906176"},
+ {"0x1.59725db272f7fp+262", 309, "9999999999999999673560075006595519222746403606649979913266024618633003221909504"},
+ {"0x1.59725db272f80p+262", 309, "10000000000000001319064632327801561377715586164000484896001890252212866570518528"},
+ {"0x1.afcef51f0fb5ep+265", 309, "99999999999999986862573406138718939297648940722396769236245052384850852127440896"},
+ {"0x1.afcef51f0fb5fp+265", 309, "100000000000000000026609864708367276537402401181200809098131977453489758916313088"},
+ {"0x1.0de1593369d1bp+269", 309, "999999999999999921281879895665782741935503249059183851809998224123064148429897728"},
+ {"0x1.0de1593369d1cp+269", 309, "1000000000000000131906463232780156137771558616400048489600189025221286657051852800"},
+ {"0x1.5159af8044462p+272", 309, "9999999999999999634067965630886574211027143225273567793680363843427086501542887424"},
+ {"0x1.5159af8044463p+272", 309, "10000000000000001319064632327801561377715586164000484896001890252212866570518528000"},
+ {"0x1.a5b01b605557ap+275", 309, "99999999999999989600692989521205793443517660497828009527517532799127744739526311936"},
+ {"0x1.a5b01b605557bp+275", 309, "100000000000000003080666323096525690777025204007643346346089744069413985291331436544"},
+ {"0x1.078e111c3556cp+279", 309, "999999999999999842087036560910778345101146430939018748000886482910132485188042620928"},
+ {"0x1.078e111c3556dp+279", 309, "1000000000000000057766609898115896702437267127096064137098041863234712334016924614656"},
+ {"0x1.4971956342ac7p+282", 309, "9999999999999998420870365609107783451011464309390187480008864829101324851880426209280"},
+ {"0x1.4971956342ac8p+282", 309, "10000000000000000146306952306748730309700429878646550592786107871697963642511482159104"},
+ {"0x1.9bcdfabc13579p+285", 309, "99999999999999987659576829486359728227492574232414601025643134376206526100066373992448"},
+ {"0x1.9bcdfabc1357ap+285", 309, "100000000000000001463069523067487303097004298786465505927861078716979636425114821591040"},
+ {"0x1.0160bcb58c16cp+289", 309, "999999999999999959416724456350362731491996089648451439669739009806703922950954425516032"},
+ {"0x1.0160bcb58c16dp+289", 309, "1000000000000000180272607553648403929404183682513265918105226119259073688151729587093504"},
+ {"0x1.41b8ebe2ef1c7p+292", 309, "9999999999999999594167244563503627314919960896484514396697390098067039229509544255160320"},
+ {"0x1.41b8ebe2ef1c8p+292", 309, "10000000000000001361014309341887956898217461639403030224181286973685997351115745547780096"},
+ {"0x1.922726dbaae39p+295", 309, "99999999999999999475366575191804932315794610450682175621941694731908308538307845136842752"},
+ {"0x1.922726dbaae3ap+295", 309, "100000000000000013610143093418879568982174616394030302241812869736859973511157455477800960"},
+ {"0x1.f6b0f092959c7p+298", 309, "999999999999999966484112715463900049825186092620125502979674597309179755437379230686511104"},
+ {"0x1.f6b0f092959c8p+298", 309, "1000000000000000079562324861280497143156226140166910515938643997348793075220176113414176768"},
+ {"0x1.3a2e965b9d81cp+302", 309, "9999999999999998986371854279739417938265620640920544952042929572854117635677011010499117056"},
+ {"0x1.3a2e965b9d81dp+302", 309, "10000000000000000795623248612804971431562261401669105159386439973487930752201761134141767680"},
+ {"0x1.88ba3bf284e23p+305", 309, "99999999999999989863718542797394179382656206409205449520429295728541176356770110104991170560"},
+ {"0x1.88ba3bf284e24p+305", 309, "100000000000000004337729697461918607329029332495193931179177378933611681288968111094132375552"},
+ {"0x1.eae8caef261acp+308", 309, "999999999999999927585207737302990649719308316264031458521789123695552773432097103028194115584"},
+ {"0x1.eae8caef261adp+308", 309, "1000000000000000043377296974619186073290293324951939311791773789336116812889681110941323755520"},
+ {"0x1.32d17ed577d0bp+312", 309, "9999999999999998349515363474500343108625203093137051759058013911831015418660298966976904036352"},
+ {"0x1.32d17ed577d0cp+312", 309, "10000000000000000202188791271559469885760963232143577411377768562080040049981643093586978275328"},
+ {"0x1.7f85de8ad5c4ep+315", 309, "99999999999999987200500490339121684640523551209383568895219648418808203449245677922989188841472"},
+ {"0x1.7f85de8ad5c4fp+315", 309, "100000000000000002021887912715594698857609632321435774113777685620800400499816430935869782753280"},
+ {"0x1.df67562d8b362p+318", 309, "999999999999999931290554592897108903273579836542044509826428632996050822694739791281414264061952"},
+ {"0x1.df67562d8b363p+318", 309, "1000000000000000049861653971908893017010268485438462151574892930611988399099305815384459015356416"},
+ {"0x1.2ba095dc7701dp+322", 309, "9999999999999998838621148412923952577789043769834774531270429139496757921329133816401963635441664"},
+ {"0x1.2ba095dc7701ep+322", 309, "10000000000000000735758738477112498397576062152177456799245857901351759143802190202050679656153088"},
+ {"0x1.7688bb5394c25p+325", 309, "99999999999999999769037024514370800696612547992403838920556863966097586548129676477911932478685184"},
+ {"0x1.7688bb5394c26p+325", 309, "100000000000000014946137745027879167254908695051145297064360294060937596327914127563101660644376576"},
+ {"0x1.d42aea2879f2ep+328", 309, "999999999999999967336168804116691273849533185806555472917961779471295845921727862608739868455469056"},
+ {"0x1.d42aea2879f2fp+328", 309, "1000000000000000088752974568224758206315902362276487138068389220230015924160003471290257693781000192"},
+ {"0x1.249ad2594c37cp+332", 309, "9999999999999998216360018871870109548898901740426374747374488505608317520357971321909184780648316928"},
+ {"0x1.249ad2594c37dp+332", 309, "10000000000000000159028911097599180468360808563945281389781327557747838772170381060813469985856815104"},
+ {"0x1.6dc186ef9f45cp+335", 309, "99999999999999997704951326524533662844684271992415000612999597473199345218078991130326129448151154688"},
+ {"0x1.6dc186ef9f45dp+335", 309, "100000000000000013246302464330366230200379526580566253752254309890315515232578269041560411089819140096"},
+ {"0x1.c931e8ab87173p+338", 309, "999999999999999977049513265245336628446842719924150006129995974731993452180789911303261294481511546880"},
+ {"0x1.c931e8ab87174p+338", 309, "1000000000000000101380322367691997167292404756629360031244033674068922812296784134593135547614855430144"},
+ {"0x1.1dbf316b346e7p+342", 309, "9999999999999998029863805218200118740630558685368559709703431956602923480183979986974373400948301103104"},
+ {"0x1.1dbf316b346e8p+342", 309, "10000000000000000019156750857346687362159551272651920111528035145993793242039887559612361451081803235328"},
+ {"0x1.652efdc6018a1p+345", 309, "99999999999999984277223943460294324649363572028252317900683525944810974325551615015019710109750015295488"},
+ {"0x1.652efdc6018a2p+345", 309, "100000000000000000191567508573466873621595512726519201115280351459937932420398875596123614510818032353280"},
+ {"0x1.be7abd3781ecap+348", 309, "999999999999999938258300825281978540327027364472124478294416212538871491824599713636820527503908255301632"},
+ {"0x1.be7abd3781ecbp+348", 309, "1000000000000000065573049346187358932104882890058259544011190816659887156583377798285651762712452391763968"},
+ {"0x1.170cb642b133ep+352", 309, "9999999999999998873324014169198263836158851542376704520077063708904652259210884797772880334204906007166976"},
+ {"0x1.170cb642b133fp+352", 309, "10000000000000000910359990503684350104604539951754865571545457374840902895351334152154180097541612190564352"},
+ {"0x1.5ccfe3d35d80ep+355", 309, "99999999999999996881384047029926983435371269061279689406644211752791525136670645395254002395395884805259264"},
+ {"0x1.5ccfe3d35d80fp+355", 309, "100000000000000013177671857705815673582936776336304977818391361080281530225794240230304400502089534272438272"},
+ {"0x1.b403dcc834e11p+358", 309, "999999999999999903628689227595715073763450661512695740419453520217955231010212074612338431527184250183876608"},
+ {"0x1.b403dcc834e12p+358", 309, "1000000000000000033998991713002824594943974719712898047713430714837875271723200833292741616380733445921308672"},
+ {"0x1.108269fd210cbp+362", 309, "9999999999999999818508707188399807864717650964328171247958398369899072554380053298205803424393137676263358464"},
+ {"0x1.108269fd210ccp+362", 309, "10000000000000001904433546954913560203606035895531408164662033483817793205787873437092254382049924808062271488"},
+ {"0x1.54a3047c694fdp+365", 309, "99999999999999985669538033284915564613846200056062290979362173015478401635353612148739328497990653971840106496"},
+ {"0x1.54a3047c694fep+365", 309, "100000000000000002356936751417025583324953279505688186312991253926828166846616173259830936159244951026231410688"},
+ {"0x1.a9cbc59b83a3dp+368", 309, "999999999999999956819772641641815758405104477258378281795396215622882607621111488153942930947432322044748890112"},
+ {"0x1.a9cbc59b83a3ep+368", 309, "1000000000000000090318962386698695908093961112855385444464428862913680729311211977042675792237466698479879323648"},
+ {"0x1.0a1f5b8132466p+372", 309, "9999999999999999301199346926304397284673331501389768492615896861647229832830913903761963586894254467577228034048"},
+ {"0x1.0a1f5b8132467p+372", 309, "10000000000000001437186382847214479679695037670941883095320419218299999779872521725981689367534804490539314970624"},
+ {"0x1.4ca732617ed7fp+375", 309, "99999999999999984468045325579403643266646490335689226515340879189861218540142707748740732746380344583923932594176"},
+ {"0x1.4ca732617ed80p+375", 309, "100000000000000001555941612946684302426820139692106143336977058043083378116475570326498538991504744767620628086784"},
+ {"0x1.9fd0fef9de8dfp+378", 309, "999999999999999878856245830528597750986812202069726098796681149605056504554092802642922939954052246206632716926976"},
+ {"0x1.9fd0fef9de8e0p+378", 309, "1000000000000000015559416129466843024268201396921061433369770580430833781164755703264985389915047447676206280867840"},
+ {"0x1.03e29f5c2b18bp+382", 309, "9999999999999997968343436511656505870179786851589248980528274911095901385876950622696854699774551253248885785624576"},
+ {"0x1.03e29f5c2b18cp+382", 309, "10000000000000000155594161294668430242682013969210614333697705804308337811647557032649853899150474476762062808678400"},
+ {"0x1.44db473335deep+385", 309, "99999999999999984057935814682588907446802322751135220511621610897383886710310719046874545396497358979515211902353408"},
+ {"0x1.44db473335defp+385", 309, "100000000000000001555941612946684302426820139692106143336977058043083378116475570326498538991504744767620628086784000"},
+ {"0x1.961219000356ap+388", 309, "999999999999999910571381339882270654388094495275235896417637897556636832727766595587241428345003132947573783761256448"},
+ {"0x1.961219000356bp+388", 309, "1000000000000000050555427725995033814228237030803003279020481474722232763977085405824233377105062219252417113236701184"},
+ {"0x1.fb969f40042c5p+391", 309, "9999999999999999665649998943273759183241515094863428494587753284228752052274941196820382078490267674695111155514343424"},
+ {"0x1.fb969f40042c6p+391", 309, "10000000000000000785522370032175864461962655379085567555410501901553519502269491678716317668570740365133857791317901312"},
+ {"0x1.3d3e2388029bbp+395", 309, "99999999999999994416755247254933381274972870380190006824232035607637985622760311004411949604741731366073618283536318464"},
+ {"0x1.3d3e2388029bcp+395", 309, "100000000000000012334713184677367065734511114927744231797396013484834264822673118714746919046029294413093564456393244672"},
+ {"0x1.8c8dac6a0342ap+398", 309, "999999999999999980003468347394201181668805192897008518188648311830772414627428725464789434929992439754776075181077037056"},
+ {"0x1.8c8dac6a0342bp+398", 309, "1000000000000000123347131846773670657345111149277442317973960134848342648226731187147469190460292944130935644563932446720"},
+ {"0x1.efb1178484134p+401", 309, "9999999999999999226660029476424133913982828103448349982745235826237443211877077407917175327178722380043122474279348731904"},
+ {"0x1.efb1178484135p+401", 309, "10000000000000000373409337471459889719393275754491820381027730410378005080671497101378613371421126415052399029342192009216"},
+ {"0x1.35ceaeb2d28c0p+405", 309, "99999999999999983092605830803955292696544699826135736641192401589249937168415416531480248917847991520357012302290741100544"},
+ {"0x1.35ceaeb2d28c1p+405", 309, "100000000000000001440594758724527385583111862242831263013712314935498927069126131626863257625726456080505437183296233537536"},
+ {"0x1.83425a5f872f1p+408", 309, "999999999999999977709969731404129670057984297594921577392083322662491290889839886077866558841507631684757522070951350501376"},
+ {"0x1.83425a5f872f2p+408", 309, "1000000000000000124493881154768706413150521596928485788372242629432483210095525606840930628504535348165944921118995289997312"},
+ {"0x1.e412f0f768fadp+411", 309, "9999999999999999483531874467312143214394768377282087351960514613084929070487027419252537449089020883885200422613425626021888"},
+ {"0x1.e412f0f768faep+411", 309, "10000000000000000657803165854228757159135066771950601039801789067244864424132513185357050006393242615734699614997777141989376"},
+ {"0x1.2e8bd69aa19ccp+415", 309, "99999999999999992486776161899288204254467086983483846143922597222529419997579302660316349376281765375153005841365553228283904"},
+ {"0x1.2e8bd69aa19cdp+415", 309, "100000000000000011275116824089954027370311861298180065149382988489088385655907074917988550293149313084744992919515177483763712"},
+ {"0x1.7a2ecc414a03fp+418", 309, "999999999999999924867761618992882042544670869834838461439225972225294199975793026603163493762817653751530058413655532282839040"},
+ {"0x1.7a2ecc414a040p+418", 309, "1000000000000000075174486916518208627471429064352408213482909102357765925242415204664541101097758035428265955038852526326677504"},
+ {"0x1.d8ba7f519c84fp+421", 309, "9999999999999999549291066784979473595300225087383524118479625982517885450291174622154390152298057300868772377386949310916067328"},
+ {"0x1.d8ba7f519c850p+421", 309, "10000000000000000751744869165182086274714290643524082134829091023577659252424152046645411010977580354282659550388525263266775040"},
+ {"0x1.27748f9301d31p+425", 309, "99999999999999988278187853568579059876517857536991893086699469578820211690113881674597776370903434688204400735860037395056427008"},
+ {"0x1.27748f9301d32p+425", 309, "100000000000000007517448691651820862747142906435240821348290910235776592524241520466454110109775803542826595503885252632667750400"},
+ {"0x1.7151b377c247ep+428", 309, "999999999999999998217443564185241415988928868759412500436543339729940401905904649497115766142268560009777175966751665376232210432"},
+ {"0x1.7151b377c247fp+428", 309, "1000000000000000152131530268851175838953929259945403926529274864985591448578925759831966436053247510846754734110953387277122797568"},
+ {"0x1.cda62055b2d9dp+431", 309, "9999999999999999366518088823188676468029287122850159299994507296276799832366962053631754981778769796749861527090709766158759755776"},
+ {"0x1.cda62055b2d9ep+431", 309, "10000000000000000597830782460516151851749290252338090708736359498322008205751130936310560341066601403445681992244323541365884452864"},
+ {"0x1.2087d4358fc82p+435", 309, "99999999999999991202555500957231813912852864969525730182461368558677581576901282770959939099212034754106974340599870111173348163584"},
+ {"0x1.2087d4358fc83p+435", 309, "100000000000000010903558599154471420052372915041332632722331003791400915551047984893820824847817340461240101783057690514487343316992"},
+ {"0x1.68a9c942f3ba3p+438", 309, "999999999999999990829567402361276563686608849982484911984092226517669151665599636201042933986541570369602253175829982724989462249472"},
+ {"0x1.68a9c942f3ba4p+438", 309, "1000000000000000148437592187939193412802769250556940132303049308379455823458773253183930019975384016026667272715492545951501423476736"},
+ {"0x1.c2d43b93b0a8bp+441", 309, "9999999999999998962647525310145264542169126096378117797927179774005971485896954660113106823932361029753632414520324447890822855131136"},
+ {"0x1.c2d43b93b0a8cp+441", 309, "10000000000000000223511723594768599335098409300973759560478836428900264860242343595976203511843100595010152570837624953702918544949248"},
+ {"0x1.19c4a53c4e697p+445", 309, "99999999999999992148203649670699315007549827372972461504375111049848301607660324472857261615145089428049364457837845490532419930947584"},
+ {"0x1.19c4a53c4e698p+445", 309, "100000000000000012322030822224672671694418358646502729705201617528156995597186547446666808621716922472153686958914653583525950968037376"},
+ {"0x1.6035ce8b6203dp+448", 309, "999999999999999961829690841814939863449235336276785151445404123455100404055655690676191710164594560368702289580532071091311261383655424"},
+ {"0x1.6035ce8b6203ep+448", 309, "1000000000000000123220308222246726716944183586465027297052016175281569955971865474466668086217169224721536869589146535835259509680373760"},
+ {"0x1.b843422e3a84cp+451", 309, "9999999999999999295515673657285824927502456862391367223240817130898064936724137339180964349540796274981353735788091781425216117243117568"},
+ {"0x1.b843422e3a84dp+451", 309, "10000000000000000586640612700740119755462042863897304388093713545509821352053815609504775357961393589804030375857007499376802103616864256"},
+ {"0x1.132a095ce492fp+455", 309, "99999999999999982626157224225223890651347880611866174913584999992086598044603947229219155428043184231232124237329592070639473281441202176"},
+ {"0x1.132a095ce4930p+455", 309, "100000000000000003284156248920492607898701256635961169551231342625874700689878799554400131562772741268394950478432243557864849063421149184"},
+ {"0x1.57f48bb41db7bp+458", 309, "999999999999999867577570291642776341008185558166851738411142685188442185736589176942553506549890956386646894855501223680845484378371915776"},
+ {"0x1.57f48bb41db7cp+458", 309, "1000000000000000032841562489204926078987012566359611695512313426258747006898787995544001315627727412683949504784322435578648490634211491840"},
+ {"0x1.adf1aea12525ap+461", 309, "9999999999999999006303687311552062886039509598054037298313768334025031499690289406628430683654582476461074168412654660604060856295398309888"},
+ {"0x1.adf1aea12525bp+461", 309, "10000000000000000328415624892049260789870125663596116955123134262587470068987879955440013156277274126839495047843224355786484906342114918400"},
+ {"0x1.0cb70d24b7378p+465", 309, "99999999999999984774589122793531837245072631718372054355900219626000560719712531871037976946055058163097058166404267825310912362767116664832"},
+ {"0x1.0cb70d24b7379p+465", 309, "100000000000000005928380124081487003706362488767045328864850074482999577828473980652023296508018124569151792237293382948229697163514582401024"},
+ {"0x1.4fe4d06de5056p+468", 309, "999999999999999847745891227935318372450726317183720543559002196260005607197125318710379769460550581630970581664042678253109123627671166648320"},
+ {"0x1.4fe4d06de5057p+468", 309, "1000000000000000016976219238238959704141045173573106739630601035115997744067216908958262325956255112879408454231155599236459402033650892537856"},
+ {"0x1.a3de04895e46cp+471", 309, "9999999999999999154380224320567749051268538597394750219876417318024024619451619548095327920588323941303457306908878466464492349900630570041344"},
+ {"0x1.a3de04895e46dp+471", 309, "10000000000000000508222848402996879704791089448509839788449208028871961714412352270078388372553960191290960287445781834331294577148468377157632"},
+ {"0x1.066ac2d5daec3p+475", 309, "99999999999999980713061250546244445284504979165026785650181847493456749434830333705088795590158149413134549224793557721710505681023603243483136"},
+ {"0x1.066ac2d5daec4p+475", 309, "100000000000000002374543235865110535740865792782868218747346498867023742954202057256817762821608329412934596913384011607579341316989008157343744"},
+ {"0x1.4805738b51a74p+478", 309, "999999999999999850453576476100176633757771418885950722696147777681701481387046784154345890364481854130945587625116484988842728082166842262552576"},
+ {"0x1.4805738b51a75p+478", 309, "1000000000000000023745432358651105357408657927828682187473464988670237429542020572568177628216083294129345969133840116075793413169890081573437440"},
+ {"0x1.9a06d06e26112p+481", 309, "9999999999999999890870611821409196126784806260401358945180015464725302399110258148854112806457630061296658928320953898584032761523454337112604672"},
+ {"0x1.9a06d06e26113p+481", 309, "10000000000000001277205458881816625915991898331943210663398553152633589984350048456164766709270441581283861980390742947279638242225240251599683584"},
+ {"0x1.00444244d7cabp+485", 309, "99999999999999993363366729972462242111019694317846182578926003895619873650143420259298512453325054533017777074930382791057905692427399713177731072"},
+ {"0x1.00444244d7cacp+485", 309, "100000000000000015544724282938981118738333167462515810070422606902152475013980065176268974898330038852813025908047007570187593383655974344970993664"},
+ {"0x1.405552d60dbd6p+488", 309, "999999999999999977996382405657660174364823889467801080772253244969263939229107492426926049423260513969768268415537077468838432306731146395363835904"},
+ {"0x1.405552d60dbd7p+488", 309, "1000000000000000155447242829389811187383331674625158100704226069021524750139800651762689748983300388528130259080470075701875933836559743449709936640"},
+ {"0x1.906aa78b912cbp+491", 309, "9999999999999999070160382361647997691574207754048582727994641153483596148648302286926205695992445641464234721495638781756234316947997075736253956096"},
+ {"0x1.906aa78b912ccp+491", 309, "10000000000000000489767265751505205795722270035307438887450423745901682635933847561612315292472764637931130646815102767620534329186625852171022761984"},
+ {"0x1.f485516e7577ep+494", 309, "99999999999999993540817590396194393124038202103003539598857976719672134461054113418634276152885094407576139065595315789290943193957228310232077172736"},
+ {"0x1.f485516e7577fp+494", 309, "100000000000000004897672657515052057957222700353074388874504237459016826359338475616123152924727646379311306468151027676205343291866258521710227619840"},
+ {"0x1.38d352e5096afp+498", 309, "999999999999999980835596172437374590573120014030318793091164810154100112203678582976298268616221151962702060266176005440567032331208403948233373515776"},
+ {"0x1.38d352e5096b0p+498", 309, "1000000000000000162545277246339097227904071986031452381501504981983615182576228378136120296965701983510464738707067395631197433897752887331883780669440"},
+ {"0x1.8708279e4bc5ap+501", 309, "9999999999999998718097875280963410081745488308296386400449607070563910699801487058804050516065326530340444532016411713261887913912817139180431292235776"},
+ {"0x1.8708279e4bc5bp+501", 309, "10000000000000000171775323872177191180393104084305455107732328445200031262781885420082626742861173182722545959543542834786931126445173006249634549465088"},
+ {"0x1.e8ca3185deb71p+504", 309, "99999999999999992995688547174489225212045346187000138833626956204183589249936464033154810067836651912932851030272641618719051989257594860081125951275008"},
+ {"0x1.e8ca3185deb72p+504", 309, "100000000000000004625108135904199474001226272395072688491888727201272553753779650923383419882203425131989662450489690590919397689516441796634752009109504"},
+ {"0x1.317e5ef3ab327p+508", 309, "999999999999999999733403004123153744855539019118436686285840188024369679522423761672919759564567158443669378824028710020392594094129030220133015859757056"},
+ {"0x1.317e5ef3ab328p+508", 309, "1000000000000000185804116423798517725482433838447597480818028523977793111583914751916577516594435529948578361547501493575598125298270581204991032785108992"},
+ {"0x1.7dddf6b095ff0p+511", 309, "9999999999999998880909749523179353564794021275209402095665271864523156202855291675267251053466461355407239891899450398872692753716440996292182057045458944"},
+ {"0x1.7dddf6b095ff1p+511", 309, "10000000000000000369475456880582265409809179829842688451922778552150543659347219597216513109705408327446511753687232667314337003349573404171046192448274432"},
+ {"0x1.dd55745cbb7ecp+514", 309, "99999999999999988809097495231793535647940212752094020956652718645231562028552916752672510534664613554072398918994503988726927537164409962921820570454589440"},
+ {"0x1.dd55745cbb7edp+514", 309, "100000000000000000717623154091016830408061481189160311806712772146250661680488340128266606984576189330386573813296762136260081534229469225952733653677113344"},
+ {"0x1.2a5568b9f52f4p+518", 309, "999999999999999983359180223191721714560372275017470536367007614460468417501012554531477876945938741751237388344363105067534507348164573733465510370326085632"},
+ {"0x1.2a5568b9f52f5p+518", 309, "1000000000000000173895590764939294430722312570010531189967968470476774011931979328540983420144523954172264186653199235428064971301205521941960119701886468096"},
+ {"0x1.74eac2e8727b1p+521", 309, "9999999999999999833591802231917217145603722750174705363670076144604684175010125545314778769459387417512373883443631050675345073481645737334655103703260856320"},
+ {"0x1.74eac2e8727b2p+521", 309, "10000000000000001357883086565897798874899245110119190592477762992735128930457859737390823115048069116880588269914320093559588785105973323002611978355743916032"},
+ {"0x1.d22573a28f19dp+524", 309, "99999999999999995287335453651211007997446182781858083179085387749785952239205787068995699003416510776387310061494932420984963311567802202010637287727642443776"},
+ {"0x1.d22573a28f19ep+524", 309, "100000000000000007481665728323055661831810361661413965009546882534829510282787660605604053768125964371333025153260444764058913004562422887354292284947506921472"},
+ {"0x1.2357684599702p+528", 309, "999999999999999928484693987168420772305733470059469068129930887927772406304894123616740280504746200573981670431418299523701733729688780649419062882836695482368"},
+ {"0x1.2357684599703p+528", 309, "1000000000000000123593978381917935233655560332132363177417314804488469335002204100202473956740097458093113111899666497012884928817602711614917542838354527125504"},
+ {"0x1.6c2d4256ffcc2p+531", 309, "9999999999999998504409802292686149877658027252303114244149773213034936348259701329824468100106056975663290938441190205280284556945232082632196709006295628251136"},
+ {"0x1.6c2d4256ffcc3p+531", 309, "10000000000000000065284077450682265568456642148886267118448844545520511777838181142510337509988867035816342470187175785193750117648543530356184548650438281396224"},
+ {"0x1.c73892ecbfbf3p+534", 309, "99999999999999991287595123558845961539774732109363753938694017460291665200910932548988158640591809997245115511395844372456707812265566617217918448639526895091712"},
+ {"0x1.c73892ecbfbf4p+534", 309, "100000000000000003774589324822814887066163651282028976933086588120176268637538771050475113919654290478469527765363729011764432297892058199009821165792668120252416"},
+ {"0x1.1c835bd3f7d78p+538", 309, "999999999999999937849939638116397466450525159438967985375725315922685858882365002492855496964043060934899979621894213003182527093908649335762989920701551401238528"},
+ {"0x1.1c835bd3f7d79p+538", 309, "1000000000000000137641846858339900274872747866201611553286006446480839513868410418516646781429042748634490575685380367232106118863932514644433433395151811003809792"},
+ {"0x1.63a432c8f5cd6p+541", 309, "9999999999999999378499396381163974664505251594389679853757253159226858588823650024928554969640430609348999796218942130031825270939086493357629899207015514012385280"},
+ {"0x1.63a432c8f5cd7p+541", 309, "10000000000000000976834654142951997131883033248490828397039502203692087828712013353118885245360428110945724564726831363863214005099277415826993447002617590832955392"},
+ {"0x1.bc8d3f7b3340bp+544", 309, "99999999999999987391652932764487656775541389327492204364443535414407668928683046936524228593524316087103098888157864364992697772750101243698844800887746832841572352"},
+ {"0x1.bc8d3f7b3340cp+544", 309, "100000000000000000178334994858791836514563642560301392710701527770129502847789953562046870799284296099876897036220978235643807646031628623453753183252563447406133248"},
+ {"0x1.15d847ad00087p+548", 309, "999999999999999899489893451833484927233458399740540420336951338855520357125044282616287570346763120896578585177704871391229197474064067196498264773607101557544845312"},
+ {"0x1.15d847ad00088p+548", 309, "1000000000000000104076806445342351803057814451465487433877079216547069699830754788624649845638922801100959355546714693321646955446568505272576798891444167390577819648"},
+ {"0x1.5b4e5998400a9p+551", 309, "9999999999999999404072760505352583023983296100855298230449769143938302256661863838179600254051950569374547392515068357773127490685649548117139715971745147241514401792"},
+ {"0x1.5b4e5998400aap+551", 309, "10000000000000001040768064453423518030578144514654874338770792165470696998307547886246498456389228011009593555467146933216469554465685052725767988914441673905778196480"},
+ {"0x1.b221effe500d3p+554", 309, "99999999999999990767336997157383960226643264180953830087855645396318233083327270285662206135844950810475381599246526426844590779296424471954140613832058419086616428544"},
+ {"0x1.b221effe500d4p+554", 309, "100000000000000003860899428741951440279402051491350438954423829568577391016492742670197391754543170343555750902863155030391327289536708508823166797373630632400726786048"},
+ {"0x1.0f5535fef2084p+558", 309, "999999999999999933860494834742974562371950216430331518611692822307700646699603647625692432595845947170914554599698521475539380813444812793279458505403728617494385000448"},
+ {"0x1.0f5535fef2085p+558", 309, "1000000000000000143357493740096054243216090813396677260476783769063847173630251205778255402495017459700200463457564579132287164977289357383183877442068884030520150720512"},
+ {"0x1.532a837eae8a5p+561", 309, "9999999999999999338604948347429745623719502164303315186116928223077006466996036476256924325958459471709145545996985214755393808134448127932794585054037286174943850004480"},
+ {"0x1.532a837eae8a6p+561", 309, "10000000000000001014580939590254383070472626940034081121037655797126178682441216941477428085151831571943432816859913676009376081445204484652029936547358529479149975764992"},
+ {"0x1.a7f5245e5a2cep+564", 309, "99999999999999990034097500988648181343688772091571619991327827082671720239070003832128235741197850516622880918243995225045973534722968565889475147553730375141026248523776"},
+ {"0x1.a7f5245e5a2cfp+564", 309, "100000000000000003441905430931245280917713770297417747470693647675065097962631447553892265814744827318497179085147422915077831721209019419643357959500300321574675254607872"},
+ {"0x1.08f936baf85c1p+568", 309, "999999999999999953972206729656870211732987713739100709830741553196290713284945813208338477706166412373726001850053663010587168093173889073910282723323583537144858509574144"},
+ {"0x1.08f936baf85c2p+568", 309, "1000000000000000168497133608738423804917387685032638749500594682674584756861928912756562958882918041203714772520508506051096899076950702733972407714468702680083242606919680"},
+ {"0x1.4b378469b6731p+571", 309, "9999999999999999110672213538405594930961077194803931018967709273006319045695491932986935814708160866077282477159626944024852218964185263418978577250945597085571816901050368"},
+ {"0x1.4b378469b6732p+571", 309, "10000000000000000826871628571058023676436276965152235336326534308832671394311356729372731664122173896717192642523265688348930066834399772699475577180106550229078889679814656"},
+ {"0x1.9e056584240fdp+574", 309, "99999999999999987674323305318751091818660372407342701554959442658410485759723189737097766448253582599493004440868991951600366493901423615628791772651134064568704023452975104"},
+ {"0x1.9e056584240fep+574", 309, "100000000000000001403918625579970521782461970570129136093830042945021304548650108108184133243565686844612285763778101906192989276863139689872767772084421689716760605683089408"},
+ {"0x1.02c35f729689ep+578", 309, "999999999999999849284042412665072058259000527747854146471853226010883220019378060628804930891911617504691481762871699606818419373090804007799965727644765395390927070069522432"},
+ {"0x1.02c35f729689fp+578", 309, "1000000000000000068957567536844582937679826098352437099093782830596656320642208754566186799616905285426599982929417458880300383900478261195703581718577367397759832385751351296"},
+ {"0x1.4374374f3c2c6p+581", 309, "9999999999999999371534524623368764100273307559896873275206250678451924602685103382037576783819090846734548822294900033162112051840457868829614121240178061963384891963422539776"},
+ {"0x1.4374374f3c2c7p+581", 309, "10000000000000001128922725616804851135639912124733536896181687515138109407667748933536631733619040190109816831627266107349967768059557526332843049167638877982336134488877170688"},
+ {"0x1.945145230b377p+584", 309, "99999999999999986685792442259943292861266657339622078268160759437774506806920451614379548038991111093844416185619536034869697653528180058283225500691937355558043949532406874112"},
+ {"0x1.945145230b378p+584", 309, "100000000000000000744898050207431989144199493858315387235964254131263985246781616026371987637390705840846560260278464628372543383280977318309056924111623883709653889736043921408"},
+ {"0x1.f965966bce055p+587", 309, "999999999999999894976135638494410321178532246433607400617214583764724024948926844967780359586710300432448450005513217535702667994787395102883917853758746611883659375731342835712"},
+ {"0x1.f965966bce056p+587", 309, "1000000000000000007448980502074319891441994938583153872359642541312639852467816160263719876373907058408465602602784646283725433832809773183090569241116238837096538897360439214080"},
+ {"0x1.3bdf7e0360c35p+591", 309, "9999999999999998724815666657784284071258397080036981062687289922551408594451489819085924562292709488372450194860589317860981148271829194868425875762872481668410834714055235600384"},
+ {"0x1.3bdf7e0360c36p+591", 309, "10000000000000000524381184475062837195473800154429724610566137243318061834753718863820956830887857615988724636416932177829345401680187244151732297960592357271816907060120777654272"},
+ {"0x1.8ad75d8438f43p+594", 309, "99999999999999998045549773481514159457876389246726271914145983150114005386328272459269439234497983649422148597943950338419997003168440244384097290815044070304544781216945608327168"},
+ {"0x1.8ad75d8438f44p+594", 309, "100000000000000012442073916019742584451599613841868220297176761716247231308746104817149697383259168670352344130394693218166911030435304638650548668396803075131793359985469944758272"},
+ {"0x1.ed8d34e547313p+597", 309, "999999999999999894076352879585771044616424544896411028843275160104340698328775730445412843452412726368640312784735046105718485868083216078242264642659886674081956339558310064685056"},
+ {"0x1.ed8d34e547314p+597", 309, "1000000000000000009248546019891598444566210341657546615907521388633406505708118389308454908642502206536081877044340989143693798086218131232373875663313958712699944969706504756133888"},
+ {"0x1.3478410f4c7ecp+601", 309, "9999999999999999171107915076469365246063817042486381462561244058101538598046442622180212564904306224021286256366562347133135483117101991090685868467907010818055540655879490029748224"},
+ {"0x1.3478410f4c7edp+601", 309, "10000000000000001013863005321362603645260389790664550855589183714566591516115925163988885607945737906700351284520257435740740478607260633556791644798372163435943358738250605092929536"},
+ {"0x1.819651531f9e7p+604", 309, "99999999999999991711079150764693652460638170424863814625612440581015385980464426221802125649043062240212862563665623471331354831171019910906858684679070108180555406558794900297482240"},
+ {"0x1.819651531f9e8p+604", 309, "100000000000000006453119872723839559654210752410289169769835957832735809325020286556271509993374515701645382788895184180192194795092289050635704895322791329123657951217763820802932736"},
+ {"0x1.e1fbe5a7e7861p+607", 309, "999999999999999946594872951565228338993526868219488856544571440313594706493755982886960025179093529324993666087115356131035228239552737388526279268078143523691759154905886843985723392"},
+ {"0x1.e1fbe5a7e7862p+607", 309, "1000000000000000064531198727238395596542107524102891697698359578327358093250202865562715099933745157016453827888951841801921947950922890506357048953227913291236579512177638208029327360"},
+ {"0x1.2d3d6f88f0b3cp+611", 309, "9999999999999998286585471758920610814449462123360860153907833022998313197373091002112049504244419016335335042852788704601485085281825842706955095829283737561469387976341354799421194240"},
+ {"0x1.2d3d6f88f0b3dp+611", 309, "10000000000000000173566684169691286935226752617495305612368443231218527385476241124924130700318845059398697631682172475335672600663748292592247410791680053842186513692689376624118857728"},
+ {"0x1.788ccb6b2ce0cp+614", 309, "99999999999999997961704416875371517110712945186684165206763211895744845478556111003617144611039598507860251139162957211888350975873638026151889477992007905860430885494197722591793250304"},
+ {"0x1.788ccb6b2ce0dp+614", 309, "100000000000000013057554116161536926076931269139759728874448093561506558983381311986113794179635006852367151849798027377761851098929017625234227997691178436106167891224981897189374558208"},
+ {"0x1.d6affe45f818fp+617", 309, "999999999999999979617044168753715171107129451866841652067632118957448454785561110036171446110395985078602511391629572118883509758736380261518894779920079058604308854941977225917932503040"},
+ {"0x1.d6affe45f8190p+617", 309, "1000000000000000100383841763043038442836876043491446161409111172283542162824162717896144642659159251834657717076710133445871510743179417054177602937513443300570204900788250622698582966272"},
+ {"0x1.262dfeebbb0f9p+621", 309, "9999999999999999071569656121801212080692814968920789464627446869617922299624001453201875281811380250249693879805812353226907091680705581859236698853640605134247712274342131878495422251008"},
+ {"0x1.262dfeebbb0fap+621", 309, "10000000000000001003838417630430384428368760434914461614091111722835421628241627178961446426591592518346577170767101334458715107431794170541776029375134433005702049007882506226985829662720"},
+ {"0x1.6fb97ea6a9d37p+624", 309, "99999999999999986851159038200753776111576258757220550347347138989744224339004763080499610528553377966303172216135545569805454885304878641227288327493418395599568449276340570087973407686656"},
+ {"0x1.6fb97ea6a9d38p+624", 309, "100000000000000002309309130269787154892983822485169927543056457815484218967945768886576179686795076111078238543825857419659919011313587350687602971665369018571203143144663564875896666980352"},
+ {"0x1.cba7de5054485p+627", 309, "999999999999999899427890566145604518678577715028104257864890027548922232647929642417149243602017175952581854816736079397763477105066203831193512563278085201938953880500051690455580595453952"},
+ {"0x1.cba7de5054486p+627", 309, "1000000000000000023093091302697871548929838224851699275430564578154842189679457688865761796867950761110782385438258574196599190113135873506876029716653690185712031431446635648758966669803520"},
+ {"0x1.1f48eaf234ad3p+631", 309, "9999999999999998746948504188351511126283256130633852543517551174277382412416240331274267329488304589209417486924315804379963345034522698960570091326029642051843383703107348987949033805840384"},
+ {"0x1.1f48eaf234ad4p+631", 309, "10000000000000000725591715973187783610303424287811372824568343983972101724920689074452068181743241951740625976868675721161334753163637413771490365780039321792212624518252692320803210995433472"},
+ {"0x1.671b25aec1d88p+634", 309, "99999999999999991426771465453187656230872897620693565997277097362163262749171300799098274999392920617156591849131877877362376266603456419227541462168315779999172318661364176545198692437590016"},
+ {"0x1.671b25aec1d89p+634", 309, "100000000000000007255917159731877836103034242878113728245683439839721017249206890744520681817432419517406259768686757211613347531636374137714903657800393217922126245182526923208032109954334720"},
+ {"0x1.c0e1ef1a724eap+637", 309, "999999999999999914267714654531876562308728976206935659972770973621632627491713007990982749993929206171565918491318778773623762666034564192275414621683157799991723186613641765451986924375900160"},
+ {"0x1.c0e1ef1a724ebp+637", 309, "1000000000000000040900880208761398001286019738266296957960021713442094663491997727554362004538245197373563261847757813447631532786297905940174312186739777303375354598782943738754654264509857792"},
+ {"0x1.188d357087712p+641", 309, "9999999999999998636144484328400679867178126713831911407778706776934478130915991201656310481762028096907669811487431649040206546179292274931158555956605099986382706217459209761309199883223171072"},
+ {"0x1.188d357087713p+641", 309, "10000000000000000662275133196073022890814778906781692175574718614061870706920546714670378554471083956139627305190456203824330868103505742897540916997511012040520808812168041334151877325366493184"},
+ {"0x1.5eb082cca94d7p+644", 309, "99999999999999994465967438754696170766327875910118237148971115117854351613178134068619377108456504406004528089686414709538562749489776621177115003729674648080379472553427423904462708600804999168"},
+ {"0x1.5eb082cca94d8p+644", 309, "100000000000000010675012629696074914955421093453716483291339209814873492221214578172731921690128951279860188039310611147811557324883484364908173892056921944513484293311098076487204128137951576064"},
+ {"0x1.b65ca37fd3a0dp+647", 309, "999999999999999977077764769429719196041465194188378863774447340572581797347854228894418860247909937807756600796112539971931616645685181699233267813951241073670004367049615544210109925082343145472"},
+ {"0x1.b65ca37fd3a0ep+647", 309, "1000000000000000106750126296960749149554210934537164832913392098148734922212145781727319216901289512798601880393106111478115573248834843649081738920569219445134842933110980764872041281379515760640"},
+ {"0x1.11f9e62fe4448p+651", 309, "9999999999999999511432924639235132053389160461186216699466583890573511723749959183278387889172340228095875448767138256706948253250552493092635735926276453993770366538373425000777236538229086224384"},
+ {"0x1.11f9e62fe4449p+651", 309, "10000000000000001586190709079731611309593092306766792205689700011791961721578624028604793595626413427949399922319035400805891558900947084290211273632164107937207783595355268531368138238983848067072"},
+ {"0x1.56785fbbdd55ap+654", 309, "99999999999999995114329246392351320533891604611862166994665838905735117237499591832783878891723402280958754487671382567069482532505524930926357359262764539937703665383734250007772365382290862243840"},
+ {"0x1.56785fbbdd55bp+654", 309, "100000000000000011712391521916323154583523059376506771044450767875482717220128910595395124543355987879786950276086559719861028977708681660506961660909865771485203001839588998252499578988328956985344"},
+ {"0x1.ac1677aad4ab0p+657", 309, "999999999999999884751043361827625869140390227060043253747518673178360772444478643277393806310703680414274761723053117059528639544242622390941156386039240473187039308013923507098814799398756243472384"},
+ {"0x1.ac1677aad4ab1p+657", 309, "1000000000000000017535541566019400541537441865177200086145798104936341572305513193378283771523764365204900328030374534281861011105867876227585990799216050325567033999660761493056632508247061001404416"},
+ {"0x1.0b8e0acac4eaep+661", 309, "9999999999999998847510433618276258691403902270600432537475186731783607724444786432773938063107036804142747617230531170595286395442426223909411563860392404731870393080139235070988147993987562434723840"},
+ {"0x1.0b8e0acac4eafp+661", 309, "10000000000000000972062404885344653449756728480474941855847657639911300522221339234388177506516007760792756678147673846152604340428430285295728914471221362369950308146488642846313231335560438561636352"},
+ {"0x1.4e718d7d7625ap+664", 309, "99999999999999996973312221251036165947450327545502362648241750950346848435554075534196338404706251868027512415973882408182135734368278484639385041047239877871023591066789981811181813306167128854888448"},
+ {"0x1.4e718d7d7625bp+664", 309, "100000000000000013969727991387583324014272937224498437195221518215368390817766497947110253951978019521227584903311023812640679294256310975729923845933871538975662911597585244013782480038750137870188544"},
+ {"0x1.a20df0dcd3af0p+667", 309, "999999999999999901747459131964173027207212836739039328294498440443382314826691065690307721857975448067474834210390258463987183104130654882031695190925872134291678628544718769301415466131339252487684096"},
+ {"0x1.a20df0dcd3af1p+667", 309, "1000000000000000037718785293056550291741793714171007924670336578563554653884390444993619046236149589293075414109087389699655531583234914810756005630018925423128793192791080866922220799992003324610084864"},
+ {"0x1.0548b68a044d6p+671", 309, "9999999999999999017474591319641730272072128367390393282944984404433823148266910656903077218579754480674748342103902584639871831041306548820316951909258721342916786285447187693014154661313392524876840960"},
+ {"0x1.0548b68a044d7p+671", 309, "10000000000000001193015809897119766504625422406301890824958394614356580573190100725756058408630540740284357620483056684410565406706974707679905918934747573964310619313388981254947040003084017678835253248"},
+ {"0x1.469ae42c8560cp+674", 309, "99999999999999998876910787506329447650934459829549922997503484884029261182361866844442696946000689845185920534555642245481492613075738123641525387194542623914743194966239051177873087980216425864602058752"},
+ {"0x1.469ae42c8560dp+674", 309, "100000000000000016281240536126153737511360812140841903333610766563411320581747387395266546466406979922062794761588875043647041218401083394518237123398453444885893859189773399673336170714381427096269357056"},
+ {"0x1.98419d37a6b8fp+677", 309, "999999999999999988769107875063294476509344598295499229975034848840292611823618668444426969460006898451859205345556422454814926130757381236415253871945426239147431949662390511778730879802164258646020587520"},
+ {"0x1.98419d37a6b90p+677", 309, "1000000000000000128003745864021888795392755416785835072663893102275349087018702832851017765623257219066874199161822284840139314973360143403428947761576712806916637263450665299742435541675484268499358973952"},
+ {"0x1.fe52048590672p+680", 309, "9999999999999999052283250816881378851792981072012977243617198967792587267065681698004724917620567060828502090557969050236202928251957239362070375381666542984859087613894256390005080826781722527340175556608"},
+ {"0x1.fe52048590673p+680", 309, "10000000000000000166160354728550133402860267619935663985128064995273039068626355013257451286926569625748622041088095949318798038992779336698179926498716835527012730124200454693714718121768282606166882648064"},
+ {"0x1.3ef342d37a407p+684", 309, "99999999999999986067324092522138770313660664528439025470128525568004065464414123719036343698981660348604541103459182906031648839556284004276265549348464259679976306097717770685212259087870984958094927200256"},
+ {"0x1.3ef342d37a408p+684", 309, "100000000000000003889357755108838843130737249295202013334302382007691294289384896763079965607877701387326460311941213291353170611409437561654018367221268940354434586262616943544566455807655946219322240663552"},
+ {"0x1.8eb0138858d09p+687", 309, "999999999999999896317308250394787848770759814817916230429632968559415112294082783278450680807608685563489249451555889830959531939269147157518161129230251958148679621306976052570830984318279772103403898929152"},
+ {"0x1.8eb0138858d0ap+687", 309, "1000000000000000038893577551088388431307372492952020133343023820076912942893848967630799656078777013873264603119412132913531706114094375616540183672212689403544345862626169435445664558076559462193222406635520"},
+ {"0x1.f25c186a6f04cp+690", 309, "9999999999999999818630698308109481982927274216983785721776674794699138106539424938898600659703096825493544616522696356805028364441642842329313746550197144253860793660984920822957311285732475861572950035529728"},
+ {"0x1.f25c186a6f04dp+690", 309, "10000000000000000959240852713658286643220175642056616945083801606839120751337554413717392461872443451971747445865546301465605757840244670001489926894056643817026123591538467885955979875798713382291498097180672"},
+ {"0x1.37798f428562fp+694", 309, "99999999999999989061425747836704382546929530769255207431309733449871519907009213590435672179676195243109823530484164010765664497227613801915728022751095446033285297165420831725583764136794858449981115862089728"},
+ {"0x1.37798f4285630p+694", 309, "100000000000000007311188218325485257111615953570420507004223762444111242223779285187536341014385741266761068799969763125334902791605243044670546908252847439043930576054277584733562461577854658781477884848504832"},
+ {"0x1.8557f31326bbbp+697", 309, "999999999999999927113782419344605574598668153294882673458925392487194643703632279098558059466181044478400725843812838336795121561031396504666917998514458446354143529431921823271795036250068185162804696593727488"},
+ {"0x1.8557f31326bbcp+697", 309, "1000000000000000073111882183254852571116159535704205070042237624441112422237792851875363410143857412667610687999697631253349027916052430446705469082528474390439305760542775847335624615778546587814778848485048320"},
+ {"0x1.e6adefd7f06aap+700", 309, "9999999999999999563134023721266549739021664297767471527755878388779781994104643936539191296017163181162427182749897969201059028320356032930746282153172616351711759756540926280845609521557638656931995269719916544"},
+ {"0x1.e6adefd7f06abp+700", 309, "10000000000000000731118821832548525711161595357042050700422376244411124222377928518753634101438574126676106879996976312533490279160524304467054690825284743904393057605427758473356246157785465878147788484850483200"},
+ {"0x1.302cb5e6f642ap+704", 309, "99999999999999990959401044767537593501656918740576398586892792465272451027953301036534141738485988029569553038510666318680865279842887243162229186843277653306392406169861934038413548670665077684456779836676898816"},
+ {"0x1.302cb5e6f642bp+704", 309, "100000000000000009647157814548049209055895815688969665349556758155373926680325854351965226625228563157788428194463919811999765293285579587743163725597071694149293171752051249118583734850310313223909471278765965312"},
+ {"0x1.7c37e360b3d35p+707", 309, "999999999999999984345037526797422397233524775199337052919583787413130412889023223627065756931830180808571031008919677160084252852199641809946030023447952696435527124027376600704816231425231719002378564135125254144"},
+ {"0x1.7c37e360b3d36p+707", 309, "1000000000000000133847091685041515321667435950786483187020895512933942218108003650150514436025770781834322032256545705106635452959741180566593506333478305023178733248684891121346177720862393603318000095671837786112"},
+ {"0x1.db45dc38e0c82p+710", 309, "9999999999999999544446266951486038123467425400819078260993214423089680518452271383223760211130420606034208307593944715707740128306913340586165347614418822310868858990958736965765439335377993421392542578277827477504"},
+ {"0x1.db45dc38e0c83p+710", 309, "10000000000000000740462700217438781518938714805516247333803708227256174960204114795411349643881945414240216317574952939280149729167245650639345158094661640924814507988218853130896331250875288495917514830571527733248"},
+ {"0x1.290ba9a38c7d1p+714", 309, "99999999999999990660396936451049407652789096389402106318690169014230827417515340183487244380298106827518051036015414262787762879627804165648934234223216948652905993920546904997130825691790753915825536773603473752064"},
+ {"0x1.290ba9a38c7d2p+714", 309, "100000000000000009796659868706293301980329726864556811483658069880894738485544834778488675304322503758814179195711545839946316493393121126499811201907102046476036377876708763639225096339747475108225092810302677843968"},
+ {"0x1.734e940c6f9c5p+717", 309, "999999999999999868331443500000006287872809702943711652856965888408980452039094412644869581954932274412588254040761879473560521568747407734787588406864399290882799171293145332687119715621994096773456255662636329336832"},
+ {"0x1.734e940c6f9c6p+717", 309, "1000000000000000021421546958041957442493134746744949294176709095342291740583330369404881029347127449862957279318330932090828950478869943421594604148335480073467842242942440201823873880805647866312652703956229962072064"},
+ {"0x1.d022390f8b837p+720", 309, "9999999999999999601855055748251769806450047292244542376488118125689672251656359867008764503902493796828096692073033110439215789148209291468717978517470477604338250142827222541691722147321863584969741246387925089779712"},
+ {"0x1.d022390f8b838p+720", 309, "10000000000000000826575883412587379043412647642654443507046063781156162560010247521088856083040055200431048894293585531377363220429189576963174104449239123865018594716021581494785755468791093741283312832736674151661568"},
+ {"0x1.221563a9b7322p+724", 309, "99999999999999988670225591496504042642724870819986016981533507324097780666440272745607095564199569546663253707407016578763273303796211201720443029584092898479300433989106071698353021544403254911815982945786756526505984"},
+ {"0x1.221563a9b7323p+724", 309, "100000000000000008265758834125873790434126476426544435070460637811561625600102475210888560830400552004310488942935855313773632204291895769631741044492391238650185947160215814947857554687910937412833128327366741516615680"},
+ {"0x1.6a9abc9424febp+727", 309, "999999999999999965084388885482519417592855130626093842171043595190833186399051537317196816706799625297221478016185520727674168639944850288849622355474122345476546392575499689981548348018063279122228410984187505225498624"},
+ {"0x1.6a9abc9424fecp+727", 309, "1000000000000000121848654826517477399924067975478561186882460639090543945868349157039448538836407484958399359900416230607757039843910326832140006474740509066843630497944377635977584613166124739130365574036827385146376192"},
+ {"0x1.c5416bb92e3e6p+730", 309, "9999999999999999964372420736895110140590976995965873111133270039707753382929110612616471611327211972294570543930316627036907428807379455975076991793273996897499632136492752791807556010476755711238558435947154812096741376"},
+ {"0x1.c5416bb92e3e7p+730", 309, "10000000000000001218486548265174773999240679754785611868824606390905439458683491570394485388364074849583993599004162306077570398439103268321400064747405090668436304979443776359775846131661247391303655740368273851463761920"},
+ {"0x1.1b48e353bce6fp+734", 309, "99999999999999984594354677029595135102113336853821866019036664182705300920238534632828550788829765195472628778417018121881118652493108811594893042483166843723756247249515245102456078650553656951604416706418119648563167232"},
+ {"0x1.1b48e353bce70p+734", 309, "100000000000000004660180717482069756840508580994937686142098045801868278132308629957276771221419571232103397659598548986531726166600689809136062209749264344058743012736731622189948720589505523832645973577156024278435495936"},
+ {"0x1.621b1c28ac20bp+737", 309, "999999999999999886075198851200900594497923856820450300436489405065378963626525536977181948753477264027987825546533242948112401553146250111031268759363863437907536003469585205199546070383440303278127280805657005745376329728"},
+ {"0x1.621b1c28ac20cp+737", 309, "1000000000000000046601807174820697568405085809949376861420980458018682781323086299572767712214195712321033976595985489865317261666006898091360622097492643440587430127367316221899487205895055238326459735771560242784354959360"},
+ {"0x1.baa1e332d728ep+740", 309, "9999999999999999181805205159248599892793562474462356126333876156560397271658376894962991014456209536865970557564236923315533735757183797070971394269896194384435148282491314085395342974857632902877937717988376531531720556544"},
+ {"0x1.baa1e332d728fp+740", 309, "10000000000000000466018071748206975684050858099493768614209804580186827813230862995727677122141957123210339765959854898653172616660068980913606220974926434405874301273673162218994872058950552383264597357715602427843549593600"},
+ {"0x1.14a52dffc6799p+744", 309, "99999999999999996954903517948319502092964807244749211214842475260109694882873713352688654575305085714037182409224841134505892881183378706080253249519082903930108094789640533388351546084948006950326015738792668900564521713664"},
+ {"0x1.14a52dffc679ap+744", 309, "100000000000000017502309383371653514753081537245251811020857330038132583548033490964923632298277047095547089743554728739908114975629541647562410476799566744273134542648550103525944011430434718636512569974428283241553786306560"},
+ {"0x1.59ce797fb817fp+747", 309, "999999999999999928454223448636526995609414612446486912536395043045051171498417578302416590307106934377352009423588636134254484622941461177838218040629861358615028052178586193608330530158506646130887048916655460323666687950848"},
+ {"0x1.59ce797fb8180p+747", 309, "1000000000000000092833470372023199096890348452450507710984513881269234280819695799200296412090882625429431268098227736977472261378510764709695475858873732081359239635049862754709070252922400339620379482801740375051580804694016"},
+ {"0x1.b04217dfa61dfp+750", 309, "9999999999999999613300728333138614158656013804472910722260188106898877933626732224819925546638620725877678611585164563028980399740553218842096696042786355031638703687528415058284784747112853848287855356936724432692495112994816"},
+ {"0x1.b04217dfa61e0p+750", 309, "10000000000000000928334703720231990968903484524505077109845138812692342808196957992002964120908826254294312680982277369774722613785107647096954758588737320813592396350498627547090702529224003396203794828017403750515808046940160"},
+ {"0x1.0e294eebc7d2bp+754", 309, "99999999999999988242803431008825880725075313724536108897092176834227990088845967645101024020764974088276981699468968789815350713138205618891818585152157755624664880897462875650012340778461641195382916742883168419985073526276096"},
+ {"0x1.0e294eebc7d2cp+754", 309, "100000000000000009283347037202319909689034845245050771098451388126923428081969579920029641209088262542943126809822773697747226137851076470969547585887373208135923963504986275470907025292240033962037948280174037505158080469401600"},
+ {"0x1.51b3a2a6b9c76p+757", 309, "999999999999999924509121522475246865178672200286390413373640190927670776874706901000867474584296317792102107215397297714017257980807797893073643852992008461269166974189675556141912776812173197487139230503413422370196749149011968"},
+ {"0x1.51b3a2a6b9c77p+757", 309, "1000000000000000092833470372023199096890348452450507710984513881269234280819695799200296412090882625429431268098227736977472261378510764709695475858873732081359239635049862754709070252922400339620379482801740375051580804694016000"},
+ {"0x1.a6208b5068394p+760", 309, "9999999999999999918388610622944277578633427011520373324179896670642961784527024602806390495869308408470337715685294734193992593398889846197223766553446979093051960385337504355687757672562640543404353314227442034427503713670135808"},
+ {"0x1.a6208b5068395p+760", 309, "10000000000000001264983401419327895432326837028833311705066886193375469816086935788401821995921998869568971002747938248301632620580513580730198422600500768053772541672219001944225017481444457680470275332614057655878576158030168064"},
+ {"0x1.07d457124123cp+764", 309, "99999999999999988411127779858373832956786989976700226194703050524569553592790956543300452958271560395914310860351799229078805716535908585708440417158039479244754953558323062848579498254571868337516156995181495372666457581821100032"},
+ {"0x1.07d457124123dp+764", 309, "100000000000000009956644432600511718615881550253707240288894882888289682097749535512827356959114607773492443453354095454801046151441888338236034913910900102616284254148427024265175655196680942530570909289367345315883616691581616128"},
+ {"0x1.49c96cd6d16cbp+767", 309, "999999999999999884111277798583738329567869899767002261947030505245695535927909565433004529582715603959143108603517992290788057165359085857084404171580394792447549535583230628485794982545718683375161569951814953726664575818211000320"},
+ {"0x1.49c96cd6d16ccp+767", 309, "1000000000000000056475411020520841414840626381983058374700565164155456563967578197189219761589459982979768169347536362096565980644606923877305160145603279779419783940304062319818564238082591276919599588305301753272401848696295129088"},
+ {"0x1.9c3bc80c85c7ep+770", 309, "9999999999999999185841044429711589466224211962102134844977374370276477415358432917842475759840644797632681207523216662519436418612086534611285553663849717898419964165273969667523488336530932020840491736225123136358120303938278260736"},
+ {"0x1.9c3bc80c85c7fp+770", 309, "10000000000000000564754110205208414148406263819830583747005651641554565639675781971892197615894599829797681693475363620965659806446069238773051601456032797794197839403040623198185642380825912769195995883053017532724018486962951290880"},
+ {"0x1.01a55d07d39cfp+774", 309, "99999999999999997374062707399103193390970327051935144057886852787877127050853725394623645022622268104986814019040754458979257737456796162759919727807229498567311142603806310797883499542489243201826933949562808949044795771481474727936"},
+ {"0x1.01a55d07d39d0p+774", 309, "100000000000000019436671759807052388305883156775590326490339289128326538639931310259419194719485548619626821794275105794118831942800519429348176492482158776899757146408072767288477964251208935175515000298809119290899166699876243210240"},
+ {"0x1.420eb449c8842p+777", 309, "999999999999999841364972759543336764420226292177420345984153909836074800974071744757463152045042997962028093539001436578955132142505622028069656690022719315678435403212464369035268207172574280176140941400150227439321732144446136385536"},
+ {"0x1.420eb449c8843p+777", 309, "1000000000000000017865845178806930323739528929966661805443773400559670093686692423675827549619949242079148155740876247260071725785255408160775710807422153542338003433646596020960023924842331815965645472194120710174156699571604284243968"},
+ {"0x1.9292615c3aa53p+780", 309, "9999999999999999119653217272487741881479473472931169297680017061255129180591200163248089110750054956088761184197513608514017695996055364811520783369824930063422626153861170298051704942404772944919427537177384205332557191153093955289088"},
+ {"0x1.9292615c3aa54p+780", 309, "10000000000000000531660196626596490356033894575245100973356972987043891522292165594595004291349304909025721681812512093962950445138053653873169216309020403876699170397334223513449750683762833231235463783529148067211236930570359138156544"},
+ {"0x1.f736f9b3494e8p+783", 309, "99999999999999994020546131433094915763903576933939556328154082464128816489313932495174721468699049466761532837205133056038042458244550226238504699576640248260779350025557809411313140906763850021826347864477369777082931390365469918625792"},
+ {"0x1.f736f9b3494e9p+783", 309, "100000000000000005316601966265964903560338945752451009733569729870438915222921655945950042913493049090257216818125120939629504451380536538731692163090204038766991703973342235134497506837628332312354637835291480672112369305703591381565440"},
+ {"0x1.3a825c100dd11p+787", 309, "999999999999999940205461314330949157639035769339395563281540824641288164893139324951747214686990494667615328372051330560380424582445502262385046995766402482607793500255578094113131409067638500218263478644773697770829313903654699186257920"},
+ {"0x1.3a825c100dd12p+787", 309, "1000000000000000120942354671656868962382001670435578817768191183142249744630862900164152357803694488643546272066771136697843816472621283262276046411983423130707191163420128905684081263961470216866716118177799472091300320549064642593292288"},
+ {"0x1.8922f31411455p+790", 309, "9999999999999999040580826428657651966904425891201589123842107529410958489455946099092661860636496958724291396331073693328877462044103460624068471125229983529879139676226679317989414380888721568885729507381685429067351125745727105048510464"},
+ {"0x1.8922f31411456p+790", 309, "10000000000000000486475973287265010404848153099971055159735310397418651127357734700791903005570128910531738945888832142428584597165509708623196466454966148714674320981543085810557013220039375302073350623645891623631119178909006652304785408"},
+ {"0x1.eb6bafd91596bp+793", 309, "99999999999999999081179145438220670296706622164632687453780292502155740721970192601122065475966761298087599260657287627887017431169472094235452683230716826407562484594165232135299736843791138087983021771402091458056119576436948334022754304"},
+ {"0x1.eb6bafd91596cp+793", 309, "100000000000000010648340320307079537800256439834788415740925915446217281825184501414715994635435816912547179657119355220684674512140722078228476645868606147885923935036696484075840527556996367953483990701515741014566264001743184712072953856"},
+ {"0x1.33234de7ad7e2p+797", 309, "999999999999999828871535006218182557917368774264146678517764203804695831774701602620905646527100834378441867056103929979702975178097221166452191355376717763378564539746214794185426298453038162762816652692429820789419173810082174047524749312"},
+ {"0x1.33234de7ad7e3p+797", 309, "1000000000000000013946113804119924437974165856986638331112094170909680489426130543638408513078605724209795153399497011464465488473637220910340574757582946907032347746826714825234078949864321840610832155574248213693581484614981956096327942144"},
+ {"0x1.7fec216198ddbp+800", 309, "9999999999999999029013665253788793099400876073531433395554961906466896948352731790279067931477027903109831815934611625736079804963132210640075447162592094208400778225784148066048873590175516339020228538451571779510840981320420868670460264448"},
+ {"0x1.7fec216198ddcp+800", 309, "10000000000000000509610295637002728139855252735311366616309601643306774209564163318419090863889067021760658106681756277614179911327452208591182514380241927357631043882428148314438094801465785761804352561506118922744139467759619125060885807104"},
+ {"0x1.dfe729b9ff152p+803", 309, "99999999999999993251329913304315801074917514058874200397058898538348724005950180959070725179594357268399970740840405561116998262359962102302968606061220608382468313571129481157267178324335702235770533430624812081575006786082605199485453729792"},
+ {"0x1.dfe729b9ff153p+803", 309, "100000000000000005096102956370027281398552527353113666163096016433067742095641633184190908638890670217606581066817562776141799113274522085911825143802419273576310438824281483144380948014657857618043525615061189227441394677596191250608858071040"},
+ {"0x1.2bf07a143f6d3p+807", 309, "999999999999999885134206960780312089454635087411784140906440513804611167700736000690226517958758320887173266104495426751070779219941381088594259909647411423049314634698686803624216704482068400828613365568502612232284516294771707790360919932928"},
+ {"0x1.2bf07a143f6d4p+807", 309, "1000000000000000074650575649831695774632795300119615593163034400120115457135799236292149453307499328074479031320129942191467592834574340826335964513506590066150788638749118835418037019527222886944981240519484646566146722558989084608335389392896"},
+ {"0x1.76ec98994f488p+810", 309, "9999999999999999230374806985905888264902671299533504313577592910677120255877486478106111050285065223246344191476223298391501419428679730361426008304192471516696094355087732099829807674910992980518869405586990190990569575476151831539558138249216"},
+ {"0x1.76ec98994f489p+810", 309, "10000000000000000746505756498316957746327953001196155931630344001201154571357992362921494533074993280744790313201299421914675928345743408263359645135065900661507886387491188354180370195272228869449812405194846465661467225589890846083353893928960"},
+ {"0x1.d4a7bebfa31aap+813", 309, "99999999999999992303748069859058882649026712995335043135775929106771202558774864781061110502850652232463441914762232983915014194286797303614260083041924715166960943550877320998298076749109929805188694055869901909905695754761518315395581382492160"},
+ {"0x1.d4a7bebfa31abp+813", 309, "100000000000000004432795665958347438500428966608636256080197937830963477082618911859584178365170076692451010888562841972100410265623306726829729177688912148325455279810104971033102576911999816916636238052732752107272876955671430431745947427930112"},
+ {"0x1.24e8d737c5f0ap+817", 309, "999999999999999874521290314193434603084658115500145579580071256170942927492372459496518833579228824484684143252419893886408557657521935343280724451831297419035632090471862609843762766839539749606096764571247618309588232743975534688554349643169792"},
+ {"0x1.24e8d737c5f0bp+817", 309, "1000000000000000068586051851782051496707094173312964986690823395758019319873877212752887919376339615844485246833229637697374894798906086114728229966183096349571541470619505010400634769445777943389257468521053221467463131958534128550160206370177024"},
+ {"0x1.6e230d05b76cdp+820", 309, "9999999999999999521471949292288813605336325386252733424243721120057734844449743607990664678980731410286045846847437914107950925140755956518597266575720169912499958425309195700665115678820350271193610461511698595727381924297989722331966923339726848"},
+ {"0x1.6e230d05b76cep+820", 309, "10000000000000001073990041592997748754315813848755288681129738236754345983501781634041617365357617741164454675493915864595681622271829162690177310690534561356787233466490334905120091699670255821458896093110143420990381118014458473224813777155784704"},
+ {"0x1.c9abd04725480p+823", 309, "99999999999999992109683308321470265755404276937522223728665176967184126166393360027804741417053541441103640811181423240104047857145413152842812577527572916236425034170729678597741204746503691611405533351920096306747820855546959721533975525765152768"},
+ {"0x1.c9abd04725481p+823", 309, "100000000000000004529828046727141746947240184637542665783753313900757015278809664236212362908068632088130911440353246844005893434193998802215452930446088047790723234500178792233381012913302936013527818404707654908851814405278709728676750356293615616"},
+ {"0x1.1e0b622c774d0p+827", 309, "999999999999999921096833083214702657554042769375222237286651769671841261663933600278047414170535414411036408111814232401040478571454131528428125775275729162364250341707296785977412047465036916114055333519200963067478208555469597215339755257651527680"},
+ {"0x1.1e0b622c774d1p+827", 309, "1000000000000000119819148897705446356623417292575549310168061960609007487462594467612569358026776864763472738178563410063470007804231501918390371421971971267233021546978482604147648978133824826548011894363801900701142105351177597329624152546106933248"},
+ {"0x1.658e3ab795204p+830", 309, "9999999999999999210968330832147026575540427693752222372866517696718412616639336002780474141705354144110364081118142324010404785714541315284281257752757291623642503417072967859774120474650369161140553335192009630674782085554695972153397552576515276800"},
+ {"0x1.658e3ab795205p+830", 309, "10000000000000000800746857348072976168095423879354838955917799224215742423028622941456649692555285746929854721652135745309841019576760278403979222926327228462592673059242454405136015920000672444612205821948817131744093259920359973067672730884158521344"},
+ {"0x1.bef1c9657a685p+833", 309, "99999999999999992109683308321470265755404276937522223728665176967184126166393360027804741417053541441103640811181423240104047857145413152842812577527572916236425034170729678597741204746503691611405533351920096306747820855546959721533975525765152768000"},
+ {"0x1.bef1c9657a686p+833", 309, "100000000000000004827911520448877862495844246422343156393075429187162764617507655537214145823852994263659565935453370610499537728043164857800396298916132410948026391308085570960636368309306117879178753245974556315302310250472271728848176952226298724352"},
+ {"0x1.17571ddf6c813p+837", 309, "999999999999999895660376658959887464073162830405580371957831265231883984761705009259228605356936508765924557863270337660249498829658628118512958332498610172941047627432585001251621720339432063578508893731092043050369229765618973200711352404729235767296"},
+ {"0x1.17571ddf6c814p+837", 309, "1000000000000000099152028052998409011920202342162715294588395300751542199979533737409779075865727753926819359851621495586577336764022655397834297874715562088326669341630279279057944337344270883862880412035963403187241060084423965317738575228107571068928"},
+ {"0x1.5d2ce55747a18p+840", 309, "9999999999999999363587069377675917736425707327570073564839440723358156278052707548893386994586947577981035182609405692455150664165314335743772262409420005560181719702721238568128862437403998276353831973920663150777435958293799716241167969694049028276224"},
+ {"0x1.5d2ce55747a19p+840", 309, "10000000000000000991520280529984090119202023421627152945883953007515421999795337374097790758657277539268193598516214955865773367640226553978342978747155620883266693416302792790579443373442708838628804120359634031872410600844239653177385752281075710689280"},
+ {"0x1.b4781ead1989ep+843", 309, "99999999999999993635870693776759177364257073275700735648394407233581562780527075488933869945869475779810351826094056924551506641653143357437722624094200055601817197027212385681288624374039982763538319739206631507774359582937997162411679696940490282762240"},
+ {"0x1.b4781ead1989fp+843", 309, "100000000000000006659336382995224556426467602028157370696750505506839688554468114090569100058432115470107619153348531031836488269452441103314288354796084978186496986735864819460893271862349667261738096910718398556534156723341516657901421957636703742066688"},
+ {"0x1.10cb132c2ff63p+847", 309, "999999999999999988452569694641453289891412847766833896677368465428848130901034909295879619908945316559292587569958465674654992927728624557883489163749540246356891129106733591931304833693638565628182306078113383272782784390994049606075766012189756664840192"},
+ {"0x1.10cb132c2ff64p+847", 309, "1000000000000000196828020722136899354886781307806140057451066037800978143284091526922043301709947551604048864806030051391214698972517388491908540854979699007711767764445172532404979193506593517599378740822301656052939538637450361533911642183329172013711360"},
+ {"0x1.54fdd7f73bf3bp+850", 309, "9999999999999998634272990781441856508941917717432502002131499220055701234712009387201814108283439755324388212283155142447191693008553661974684581490114449895439651479036702276471002178058655944454644452316004196046887318431202624493742403095061074555174912"},
+ {"0x1.54fdd7f73bf3cp+850", 309, "10000000000000000301276599001405425028904865397746951288321079799032741333776462328211123562691457635682438430171727828179669341366863773446884995019955719986278664561744213800260397056562295560224215930269510378288141352402853119916429412464176397346144256"},
+ {"0x1.aa3d4df50af0ap+853", 309, "99999999999999989676737124254345702129345072534953918593694153358511092545248999754036759991650433313959982558608696795936872226802156842691246641960827039136074540955782045812288811537593838676085587479067054324951381252255327235782798049688841391133687808"},
+ {"0x1.aa3d4df50af0bp+853", 309, "100000000000000003012765990014054250289048653977469512883210797990327413337764623282111235626914576356824384301717278281796693413668637734468849950199557199862786645617442138002603970565622955602242159302695103782881413524028531199164294124641763973461442560"},
+ {"0x1.0a6650b926d66p+857", 309, "999999999999999843423255779504622828654636399579476808778874955057845642282427503428069697375447760968142218613652642015929437520555644859802053186653349748453896990911180089361627479263821919056229587496158345417793683435460456504301996197076723582025859072"},
+ {"0x1.0a6650b926d67p+857", 309, "1000000000000000056799717631659959599209893702659726317411141269166906774962677479877261307539674049653972646503389945789686576510419339128243706118473032320081290665497741564406670023712287789874734736674207136744674199783831719918405933396323484899269935104"},
+ {"0x1.4cffe4e7708c0p+860", 309, "9999999999999999287738405203667575368767393208115766122317814807014700953545274940077463414411382764424743897695475635254322931165011225671787143593812227771048544607458046793796444970432082673836316471673778619485458899748089618699435710767754281089234894848"},
+ {"0x1.4cffe4e7708c1p+860", 309, "10000000000000000994750100020910269533209451632757762191375945319887190014987274751670996295725193073911387320813374065444380043083920779819320367048369688344067694004150538594156785326019809640384357665098168950100503030535059726012267208361728371627187503104"},
+ {"0x1.a03fde214caf0p+863", 309, "99999999999999992877384052036675753687673932081157661223178148070147009535452749400774634144113827644247438976954756352543229311650112256717871435938122277710485446074580467937964449704320826738363164716737786194854588997480896186994357107677542810892348948480"},
+ {"0x1.a03fde214caf1p+863", 309, "100000000000000006533477610574617307003210399478293629775643192173126922026988747893522897194624310120140586361897943794063686207001388689898137223574581962294638641248120402340847172549022642470747494264132908839774942043776657045497009088429335535195969814528"},
+ {"0x1.0427ead4cfed6p+867", 309, "999999999999999928773840520366757536876739320811576612231781480701470095354527494007746341441138276442474389769547563525432293116501122567178714359381222777104854460745804679379644497043208267383631647167377861948545889974808961869943571076775428108923489484800"},
+ {"0x1.0427ead4cfed7p+867", 309, "1000000000000000147271337456973822389925322799165752109071222186349148695219103469891718550249305996056764747928638562589759603442121545498062966961564577730451305583522443629825768062558437319101780919925699824267271538715541135605986002768804111697781423341568"},
+ {"0x1.4531e58a03e8bp+870", 309, "9999999999999998413748417457239315956573059294699064134960051984423986554086971036541574579178711885967582465059111638997013689862529533948250133185078807957662740116351490992011950708371166466963719380640490770210556304785160923755265983999639546733803159420928"},
+ {"0x1.4531e58a03e8cp+870", 309, "10000000000000000161728392950095834780961727121532468109675577629605415353003578843613352249644053642881905330331839631511632172467492917395324154002545647584434349098564602595580939232492998880708913562707066468760361494711018313643605437535869015444666630275072"},
+ {"0x1.967e5eec84e2ep+873", 309, "99999999999999987633444125558106197214507928600657449299031571134602723138702925979559301132717802373504470381136572374999373863835222106376649373485721758830170619127941133127257484131955329497127582170538059099205173427703324017329338747068854404759758535917568"},
+ {"0x1.967e5eec84e2fp+873", 309, "100000000000000001617283929500958347809617271215324681096755776296054153530035788436133522496440536428819053303318396315116321724674929173953241540025456475844343490985646025955809392324929988807089135627070664687603614947110183136436054375358690154446666302750720"},
+ {"0x1.fc1df6a7a61bap+876", 309, "999999999999999932269800471352470574525516656465243420181212531991832952952360709621889896782068959956303035500093019510461530081711049334072862401016156456358397678710230902586782474091451932211122035531511013345645500354660676649720249983847887046345216426508288"},
+ {"0x1.fc1df6a7a61bbp+876", 309, "1000000000000000044140518902895287779286391397382581274563006173283444396083023609274483667691850832398819698877547611031397112968428705874685599733334034192471780653571870045215197739635249206690814463183771858052833032509915549602573975010166573043840478561173504"},
+ {"0x1.3d92ba28c7d14p+880", 309, "9999999999999998875215130987353436926211667600983082784284950754751883757000955497608523884181562109792963701491111829020872969270239867178277674680890053619130444887655752455354163678739330224192450644706066754627704874925587274685787599733204126473471115726422016"},
+ {"0x1.3d92ba28c7d15p+880", 309, "10000000000000000665146625892038512202385663455660488454393649015417666847091561892050024218738072068873230315530385293355842295457722371828081471997976097396944572485441978737408807927440086615867529487142240269942705389409665241931447200154303102433395309881065472"},
+ {"0x1.8cf768b2f9c59p+883", 309, "99999999999999988752151309873534369262116676009830827842849507547518837570009554976085238841815621097929637014911118290208729692702398671782776746808900536191304448876557524553541636787393302241924506447060667546277048749255872746857875997332041264734711157264220160"},
+ {"0x1.8cf768b2f9c5ap+883", 309, "100000000000000003071603269111014971471508642847250073203719093632845102290734406131617241518267700770571769927225306004888484302202258708981207125345588886413817469658847334809978790776999353375325137186550055668797052865128496484823152800700833072414104710501367808"},
+ {"0x1.f03542dfb8370p+886", 309, "999999999999999973438224854160227305877518561122823750593712591987145964024444656694044404476868689015149167622996309190165824584023146941018349739309135463248122613459314107074039291811569329219648848907543004197890512187794469896370420793533163493423472892065087488"},
+ {"0x1.f03542dfb8371p+886", 309, "1000000000000000087993840528060072123552654295822177713480669280669756081790243465938300425888485326396286230921509810907603861460022027238605792767602642265028226779717632589125536523728417738286853894823458109178050545114775459800092635220483497954858621317962268672"},
+ {"0x1.362149cbd3226p+890", 309, "9999999999999999734382248541602273058775185611228237505937125919871459640244446566940444044768686890151491676229963091901658245840231469410183497393091354632481226134593141070740392918115693292196488489075430041978905121877944698963704207935331634934234728920650874880"},
+ {"0x1.362149cbd3227p+890", 309, "10000000000000001567272099323999790141577357366417900912128432938793221524497227514848540387354553088249684689006179119380666835856213554171582585845787463460962892794726236783564348628785267837271769223730071721661465648709640537423259638766536986317197103735005773824"},
+ {"0x1.83a99c3ec7eafp+893", 309, "99999999999999990012263082286432662256543169091523721434606031123027548865433341877772055077343404109122144711194766809100548098338386355056238620120129111010885594705399027856108106338478634741663761952135733701058809111452663635798820356028494943810497789949089153024"},
+ {"0x1.83a99c3ec7eb0p+893", 309, "100000000000000004675381888545612798918960543133041028684136487274401643939455589461036825818030333693907688813404495028932616818466243033147431327741697981638738927986463793558699752023835231102266007829372867138519293326106230343475263802678137754874196788463928344576"},
+ {"0x1.e494034e79e5bp+896", 309, "999999999999999929448868435382686895890266438998271828845121223533023678802377913944250092254807900260792535316367124530669618423639576906744771616444428851364562613616119809966264354755499540137842111275831603885509059543833769773341090453584235060232375896520569913344"},
+ {"0x1.e494034e79e5cp+896", 309, "1000000000000000046753818885456127989189605431330410286841364872744016439394555894610368258180303336939076888134044950289326168184662430331474313277416979816387389279864637935586997520238352311022660078293728671385192933261062303434752638026781377548741967884639283445760"},
+ {"0x1.2edc82110c2f9p+900", 309, "9999999999999999529098585253973751145501342374646995204443699533752222309208135100774737254399069875964494058799026896824009283758441475916906799486389390443691279468658234350904109878520700943148057046794110173854458342872794765056233999682236635579342942941443126198272"},
+ {"0x1.2edc82110c2fap+900", 309, "10000000000000001405977792455148808638290766251961210532383597921128106478682982791432627909206996862817043703881872108962514079934807130712579466061950205884056506128634524360835840526246345277305144519080463253849400322348451303638818760853390915395496414751342542716928"},
+ {"0x1.7a93a2954f3b7p+903", 309, "99999999999999991537227438137387396469434575991841521388557198562770454753131655626431591234374844785939841297824578543963083245231683449577722661712772273556182341366629763489177637489755720763166395523368395578554699469776634573397170474480057796161122485794632428945408"},
+ {"0x1.7a93a2954f3b8p+903", 309, "100000000000000006552261095746787856411749967010355244012076385661777528108930437151694716472838260680760238458487340241071121614642608687943103994317258797079104154646440083568631482671560875436423095301659220218514235305581886882057848563849292034690350260273827761094656"},
+ {"0x1.d9388b3aa30a5p+906", 309, "999999999999999945402341696592674884578976541955442659132610359825718694242914119314842162820675279649039207299571308833846909191138684972507989282336695782607667040225918275050684065261167516978177354790265605065466066369376850351293060923539046438669680406904714953752576"},
+ {"0x1.d9388b3aa30a6p+906", 309, "1000000000000000065522610957467878564117499670103552440120763856617775281089304371516947164728382606807602384584873402410711216146426086879431039943172587970791041546464400835686314826715608754364230953016592202185142353055818868820578485638492920346903502602738277610946560"},
+ {"0x1.27c35704a5e67p+910", 309, "9999999999999999213782878444176341486712719163258207029349796604673073768736360688744211624391338142173265718425108901184740478000812045911233791501695173449709921389782217629235579129702792695009666351450002856415308090320884466574359759805482716570229159677380024223137792"},
+ {"0x1.27c35704a5e68p+910", 309, "10000000000000001135707186618179600359329089213627963525160252553345979158278604723977891654914655376710276554989942398414569389285410476422002602075069448460643913489597938599405671312973852493186523923071228410330128677303956762082926555244744699101970314810717026738241536"},
+ {"0x1.71b42cc5cf601p+913", 309, "99999999999999995981677400789769932612359931733321583285118877944076548466448094957909476304960015890806678857380756006307062602577317320133875536163700284518967198097453618232695975663570046546450378657742479671982722077174989256760731188933351130765773907040474247261585408"},
+ {"0x1.71b42cc5cf602p+913", 309, "100000000000000011357071866181796003593290892136279635251602525533459791582786047239778916549146553767102765549899423984145693892854104764220026020750694484606439134895979385994056713129738524931865239230712284103301286773039567620829265552447446991019703148107170267382415360"},
+ {"0x1.ce2137f743381p+916", 309, "999999999999999929065985077113647184161737396527299728918221484261998998431805045015355882561227083155474615188770224107393363445219598313166454392463014445014728107377484646804238281703363508693674065431485187857190091380020735839470243162305319587149880588271350432374194176"},
+ {"0x1.ce2137f743382p+916", 309, "1000000000000000052069140800249855752009185079750964144650090664977064943362508663270311404514719386165843308728919567930102413767433897865855658269158968045714503601765690788895124181432711335776992950015243623307738608946937362752018518070418086469181314516804918593340833792"},
+ {"0x1.20d4c2fa8a030p+920", 309, "9999999999999998060628293539774386163142897133036353131863523035469330535011014267604003606077347801451059216486208802846843131230052987604772505157670608443149526129892785047133523819740156816103551808477267524066415738131041089269219682541925527051184466597377822714075545600"},
+ {"0x1.20d4c2fa8a031p+920", 309, "10000000000000000028678785109953723248702060064614983783573429926910385653902272159683291957333224649616958313128598304010187936385481780447799767184805866054345934040104083320587698215409722049436653961817402491275192019201707119869992081071729797163687409453914913289541779456"},
+ {"0x1.6909f3b92c83dp+923", 309, "99999999999999996350686867959178558315902274782992576532314485486221746301240205812674342870820492799837784938001204037775189753543960218791943147793788145321066524580618236658968633362758090027700335311493754978334367629875739137498376013657689431411868208826074951744485326848"},
+ {"0x1.6909f3b92c83ep+923", 309, "100000000000000012095090800520613255000375578235621621745993740617750187252370268949308649680867507585164977711140320047081948194787390561536161244010870206210637787862308622846602028528114611894365152538214834716004577878441067382304555201896123592311891751678371676348215197696"},
+ {"0x1.c34c70a777a4cp+926", 309, "999999999999999932018060814468916189790076140924667674895786344599160581110141931853474815088110898427723463833733808359138380652952741502430995285503717331431522719242801594214419543296867856543673718661495390308003255801626734885371401760100025992318635002556156068237393526784"},
+ {"0x1.c34c70a777a4dp+926", 309, "1000000000000000057973292274960393763265862568545700036605220385651388108719182436946549269568487016710341006018846736433592448182900184244384740055240373818548092825496324683715486704619720031476992256475264028209364937790149360843820835266007499279518823345374529865067232493568"},
+ {"0x1.1a0fc668aac6fp+930", 309, "9999999999999998312538756460757341310094469988278417855282391117573785590229095277790152515038100038016294300856434658995751266289947873088679994697143921417382666342399831226135658142385861165970188884104804799869139102108086341186118549553740473625584843283014570307735223533568"},
+ {"0x1.1a0fc668aac70p+930", 309, "10000000000000000327822459828620982485707052830214935642633335774409426031973743359279343786724117930538174975818241508187016346769106956959939911012930425211247788042456200658152732723551495964903285489125103006290926013924448356521309485648260046220787856768108551057012647002112"},
+ {"0x1.6093b802d578bp+933", 309, "99999999999999987155954971343300695452169865566657214127525800489409136785780248940879907693753036165206704358487960288340042823857796898629319779603012221761556906824111051125390730586189881257568082051088644411534964844713587442531567367726443881446254459800333664575907082272768"},
+ {"0x1.6093b802d578cp+933", 309, "100000000000000003278224598286209824857070528302149356426333357744094260319737433592793437867241179305381749758182415081870163467691069569599399110129304252112477880424562006581527327235514959649032854891251030062909260139244483565213094856482600462207878567681085510570126470021120"},
+ {"0x1.b8b8a6038ad6ep+936", 309, "999999999999999903804088967318825213331499981137556425872873119403461614925716858712626137284506647932417134384268512470460669526244514328233356457082706278317411015442012422166180499160548969358610366191211215418098239036197666670678728654776751975985792813764840337747509598224384"},
+ {"0x1.b8b8a6038ad6fp+936", 309, "1000000000000000032782245982862098248570705283021493564263333577440942603197374335927934378672411793053817497581824150818701634676910695695993991101293042521124778804245620065815273272355149596490328548912510300629092601392444835652130948564826004622078785676810855105701264700211200"},
+ {"0x1.137367c236c65p+940", 309, "9999999999999999553953517735361344274271821018911312812290573026184540102343798495987494338396687059809772796632907678097570555865109868753376103147668407754403581309634554796258176084383892202112976392797308495024959839786965342632596166187964530344229899589832462449290116390191104"},
+ {"0x1.137367c236c66p+940", 309, "10000000000000001617604029984053712838099105849054307026537940354784235914690318131432426200603169381752178607793797891669425998275768770637546257455033787639321465930492277094643660455497502236220467316338093858400869637486920046335831684748752572681717785398568698736550198021980160"},
+ {"0x1.585041b2c477ep+943", 309, "99999999999999991412234152856228705615063640528827139694410995604646009398744945688985079659553905954212916344007296353831994673829780883765420722861953317774200043854630103365810792101611701952914782080891514223497778802469744018919490624758069218767323224280852151918381000638332928"},
+ {"0x1.585041b2c477fp+943", 309, "100000000000000007921438250845767654125681919169971093408389934233443575897517102772544534557205764529752162833294418062406838213115052098838781957320876356853543120821491881752894667070520582225774709469217797130505057184069381648545374773244373557467226310750742042216461653692645376"},
+ {"0x1.ae64521f7595ep+946", 309, "999999999999999980159157920520442850193109519852847211800025710561650359982538085224088616186146493844286149397221450372619320895438893697947652166455225334059372746413748147206443420891752540620587530362220273863006901551095990707698442841525909542472844588688081080376132618600579072"},
+ {"0x1.ae64521f7595fp+946", 309, "1000000000000000112232790704436754438278055748981998841511857219592030891972715341892564255367361362448600121311518424041218069209721063418534542042126609646694117362148642374303114420643023582803466949468830537119065128603893091744705516029416344252072069280447200202760777843035078656"},
+ {"0x1.0cfeb353a97dap+950", 309, "9999999999999998216707985798208689444911740448978652561458278997251937215943253772219178491686886515191093831000650819703008229183002900332433843156495641588976792075318750746904382211902272900011322274342879579557370290877394694632899550160573878909537749585771381335145583492791795712"},
+ {"0x1.0cfeb353a97dbp+950", 309, "10000000000000000329886110340869674854270880115045078636847583141738025727786089878914788718586324412860117381629402398400588202211517615861824081167237790591132705927077058380451118207922609574937392980048643791654301923722148311225012721166820834263125344653917287293299907083743789056"},
+ {"0x1.503e602893dd1p+953", 309, "99999999999999990619792356152730836086553963154052229916140006550463726206803882148974225824466616742587032512521514511820402183944087865441899383607925011898391576160220738003230766103104075699817505566251852643961429440152961412697448185630726610509727876130297437184073129291725930496"},
+ {"0x1.503e602893dd2p+953", 309, "100000000000000007525217352494018719361427080482583638519254439706352434301546571002539107639662119923939220917551527141401041968172205589677021287693862203915638886974287199071604654071266769099226071211897966340736882502910990345434353553680702253338428636675464684849307718019341877248"},
+ {"0x1.a44df832b8d45p+956", 309, "999999999999999872387073568844732594315793396883459481955171199192859845878553443782612494614275161063165948315155119859042742270984643205948750027907375734949421139974074457895559885094715370199357924371226299046063388276013556261500671120207314819439877240212639876510262115462027411456"},
+ {"0x1.a44df832b8d46p+956", 309, "1000000000000000007630473539575035660514778335511710750780086664439969510636494954611131549135839186513983455555395220895687860544809584999829725260594873271087399626486606146442550988840016917394626449536395208620267012778077787723395914064607119962069483324573977857832138825282954985472"},
+ {"0x1.06b0bb1fb384bp+960", 309, "9999999999999998453383935746986719810759964091578092281901881061434379129269651416169086837099623559730024468671070996517137186162196548471725549813698762277218254426715681201861616643456550607603042193381925171312226633756007099691216225313273537909139560233403722802458867734978418966528"},
+ {"0x1.06b0bb1fb384cp+960", 309, "10000000000000000617278335278671568869943723109630112583100528505388133765396715589425391709444647966943104584514912613103459078543395617173821153536698722855425910210916188218613474303381375362727338596024627724499484625789034803081540112423670420191213257583185130503608895092113260150784"},
+ {"0x1.485ce9e7a065ep+963", 309, "99999999999999988861628156533236896225967158951884963421416105502251300564950642508203478115686284411726404918398393198344015646384363622121446705582987543928597855835557826052119881754415155586279014739104656819496782321626126403692810027353529143655542997033600043426888732064053872033792"},
+ {"0x1.485ce9e7a065fp+963", 309, "100000000000000006172783352786715688699437231096301125831005285053881337653967155894253917094446479669431045845149126131034590785433956171738211535366987228554259102109161882186134743033813753627273385960246277244994846257890348030815401124236704201912132575831851305036088950921132601507840"},
+ {"0x1.9a742461887f6p+966", 309, "999999999999999957860902350346284132153551878096514283852517773229033154005572478626236537071903625148082612890986863714202457020042006419681526374965874177788623543449994485057258262661745948026767632275613049896960078961318150545418464661067991669581788285529005480705688196068853638234112"},
+ {"0x1.9a742461887f7p+966", 309, "1000000000000000096350143920374114471941312455251843583129231209642073450717704585714640048901985187209719740304992727175727058132438746816615645013237871654793913513638826934129377152896934732354722602044746013300944590451431923562399193436133392135634504915915015573579289946925483474026496"},
+ {"0x1.008896bcf54f9p+970", 309, "9999999999999997916738124663128877244082391855101191247204616495333847979510139501201523228758057506741180599941798275603729356851659179433605840090394772053822755792233955461707155943795194068332216685526534938121786651731816229250415901309895111103185283290657933692573660950408978352832512"},
+ {"0x1.008896bcf54fap+970", 309, "10000000000000000132565989783574162680686561089586460035632031477942492726904253214615979418039362499727374638565892090988122974650007025784551738302746731685907395315255274646861058187558214617579496201832662352585538835573636597522107561710941518560028749376834095178551288964115055725510656"},
+ {"0x1.40aabc6c32a38p+973", 309, "99999999999999992462348437353960485060448933957923525202610654848990348279466077292501969423268405025328970231162545648343655275306678872441733790178059478330735395060467469727994972900530063978805843953102113868000379620369084502134308975505229555772913629423636305841602377586326247764393984"},
+ {"0x1.40aabc6c32a39p+973", 309, "100000000000000010188971358317522768553282287833805675510029974709859506258618986999817618937518844969218522540155296171418804217693461643249300975876875155387412511244638023209226190850634228372784080083551133183710397091103647448307842258713600815427661358113045597729423401695974866745819136"},
+ {"0x1.90d56b873f4c6p+976", 309, "999999999999999924623484373539604850604489339579235252026106548489903482794660772925019694232684050253289702311625456483436552753066788724417337901780594783307353950604674697279949729005300639788058439531021138680003796203690845021343089755052295557729136294236363058416023775863262477643939840"},
+ {"0x1.90d56b873f4c7p+976", 309, "1000000000000000066436467741248103118547156170586292454485461107376856746627884050583544890346687569804406120783567460668037744292161050890877875387371120199760770880078039125129799472606133954939884328574613293205683935969567348590731356020719265634967118123751637393518591968740451429495341056"},
+ {"0x1.f50ac6690f1f8p+979", 309, "9999999999999999813486777206230041577815560719820581330098483720446847883279500839884297726782854580737362697004022581572770293687044935910015528960168049498887207223940204684198896264456339658487887951484580004902758521100414464490983962613190835886243290260424727924570510530141380583845003264"},
+ {"0x1.f50ac6690f1f9p+979", 309, "10000000000000000947990644147898027721356895367877038949773320191542473993945287061152499295694882737146294044779558615049579825999799033241699828844892252830514542659727120106997694213263006179702495063833317241108199639227426493046090092738526596504147144896546922605391056073158892198656212992"},
+ {"0x1.3926bc01a973bp+983", 309, "99999999999999998134867772062300415778155607198205813300984837204468478832795008398842977267828545807373626970040225815727702936870449359100155289601680494988872072239402046841988962644563396584878879514845800049027585211004144644909839626131908358862432902604247279245705105301413805838450032640"},
+ {"0x1.3926bc01a973cp+983", 309, "100000000000000016286929643128988194074816961567109135215782220741998496603447587939134202370420996309916528534448802351356655453874514916407104087757267748294909439211992693606769729825470060924312593312425595828314643101036337101791537708137280528748894576782202394138833833989693991675429388288"},
+ {"0x1.87706b0213d09p+986", 309, "999999999999999872436306494222877488001587945768638201521064070819504681704034606746682422062730755058478860313950798943503314266680100247159860107083281430052496520558476587831205023360193979812186512362979225814553504769848291707808207769286850569305558980974742103098278680884456943362624192512"},
+ {"0x1.87706b0213d0ap+986", 309, "1000000000000000017652801462756379714374878780719864776839443139119744823869255243069012222883470359078822072829219411228534934402712624705615450492327979456500795456339201761949451160807447294527656222743617592048849967890105831362861792425329827928397252374398383022243308510390698430058459037696"},
+ {"0x1.e94c85c298c4cp+989", 309, "9999999999999999595662034753429788238255624467393741467120915117996487670031669885400803025551745174706847878231119663145222863482996149222332143382301002459214758820269116923021527058285459686414683385913622455551313826420028155008403585629126369847605750170289266545852965785882018353801250996224"},
+ {"0x1.e94c85c298c4dp+989", 309, "10000000000000000757393994501697806049241951147003554069667947664398408807353434975979441432117662006869593578353268561425475824571256344889976866464258586670801150306514918315967496157863486204138441068958729385425685531382088472248832262877470188720339297317678393899013204421931950247367929757696"},
+ {"0x1.31cfd3999f7afp+993", 309, "99999999999999986662764669548153739894665631237058913850832890808749507601742578129378923002990117089766513181334005445210204946123879926882163649167349350899456456312724758086647517786230384722356772394775369116518164624503799012160606438304513147494189124523779646633247748770420728389479079870464"},
+ {"0x1.31cfd3999f7b0p+993", 309, "100000000000000005250476025520442024870446858110815915491585411551180245798890819578637137508044786404370444383288387817694252323536043057564479218478670698284838720092657580373783023379478809005936895323497079994508111903896764088007465274278014249457925878882005684283811566947219638686545940054016"},
+ {"0x1.7e43c8800759bp+996", 309, "999999999999999903803069407426113968898218766118103141789833949572356552411722264192305659040010509526872994217248819197070144216063125530186267630296136203765329090687113225440746189048800695790727969805197112921161540803823920273299782054992133678869364753954248541633605124057805104488924519071744"},
+ {"0x1.7e43c8800759cp+996", 309, "1000000000000000052504760255204420248704468581108159154915854115511802457988908195786371375080447864043704443832883878176942523235360430575644792184786706982848387200926575803737830233794788090059368953234970799945081119038967640880074652742780142494579258788820056842838115669472196386865459400540160"},
+ {"0x1.ddd4baa009302p+999", 309, "9999999999999999335434075769817752248594687291161143444150379827602457335271594505111188022480979804302392841403758309930446200199225865392779725411942503595819407127350057411001629979979981746444561664911518503259454564508526643946547561925497354420113435609274102018745072331406833609642314953654272"},
+ {"0x1.ddd4baa009303p+999", 309, "10000000000000000525047602552044202487044685811081591549158541155118024579889081957863713750804478640437044438328838781769425232353604305756447921847867069828483872009265758037378302337947880900593689532349707999450811190389676408800746527427801424945792587888200568428381156694721963868654594005401600"},
+ {"0x1.2aa4f4a405be1p+1003", 309, "99999999999999988595886650569271721532146878831929642021471152965962304374245995240101777311515802698485322026337261211948545873374744892473124468375726771027536211745837771604509610367928220847849105179362427047829119141560667380048679757245757262098417746977035154548906385860807815060374033329553408"},
+ {"0x1.2aa4f4a405be2p+1003", 309, "100000000000000007629703079084894925347346855150656811701601734206211380288125794484142188964691784076639747577138548761372210387844799938291815611350519830750167649856488981626536368095414607314235151058373458986890825155659063617715863205282622390509284183439858617103083735673849899204570498157510656"},
+ {"0x1.754e31cd072d9p+1006", 309, "999999999999999847891233648661470807691068835681842080854450367179124891914700353912936949808806064228544369161770037020638129704807338833093862397807681590830099241237075296001042588224309435545718960035602206600167779387409881325152430676383842364162444596844704620380709158981993982315347403639619584"},
+ {"0x1.754e31cd072dap+1006", 309, "1000000000000000000161765076786456438212668646231659438295495017101117499225738747865260243034213915253779773568180337416027445820567779199643391541606026068611150746122284976177256650044200527276807327067690462112661427500197051226489898260678763391449376088547292320814127957486330655468919122263277568"},
+ {"0x1.d2a1be4048f90p+1009", 309, "9999999999999999392535525055364621860040287220117324953190771571323204563013233902843309257440507748436856118056162172578717193742636030530235798840866882774987301441682011041067710253162440905843719802548551599076639682550821832659549112269607949805346034918662572406407604380845959862074904348138143744"},
+ {"0x1.d2a1be4048f91p+1009", 309, "10000000000000000610699776480364506904213085704515863812719128770699145421501541054461895603243770556638739353307444575741831722668719553462632031991253638597235713480763688482477422747721569639692426738805257643176588867453119191870248852943967318023641486852283274009874954768880653247303478097127407616"},
+ {"0x1.23a516e82d9bap+1013", 309, "99999999999999993925355250553646218600402872201173249531907715713232045630132339028433092574405077484368561180561621725787171937426360305302357988408668827749873014416820110410677102531624409058437198025485515990766396825508218326595491122696079498053460349186625724064076043808459598620749043481381437440"},
+ {"0x1.23a516e82d9bbp+1013", 309, "100000000000000013415983273353644379307167647951549871284361430903247099365945253454330474107257282415598692944582140176397004400243696672220697718814856920905847607042126949473232502444570468800016509005592812696365583783944976073966686973485829389546187580124556949719553650017014692784406223465209659392"},
+ {"0x1.6c8e5ca239028p+1016", 309, "999999999999999861291040414336469543176969619010226008309262296372260241358071732580741399612641955118765084749534143455432389522994257585350220962461935904874831773666973747856549425664459851618054736334425973085267220421335152276470127823801795414563694568114532338018850013250375609552861714878501486592"},
+ {"0x1.6c8e5ca239029p+1016", 309, "1000000000000000017216064596736454828831087825013238982328892017892380671244575047987920451875459594568606138861698291060311049225532948520696938805711440650122628514669428460356992624968028329550689224175284346730060716088829214255439694630119794546505512415617982143262670862918816362862119154749127262208"},
+ {"0x1.c7b1f3cac7433p+1019", 309, "9999999999999999860310597602564577717002641838126363875249660735883565852672743849064846414228960666786379280392654615393353172850252103336275952370615397010730691664689375178569039851073146339641623266071126720011020169553304018596457812688561947201171488461172921822139066929851282122002676667750021070848"},
+ {"0x1.c7b1f3cac7434p+1019", 309, "10000000000000001107710791061764460002235587486150467667406698508044529291764770372322278832331501782385107713289967796232382450470561630819049695116611434972713065592709012878572585445501694163102699168797993709169368134893256514428214347139105940256706031241200520264089633727198808148476736186715027275776"},
+ {"0x1.1ccf385ebc89fp+1023", 309, "99999999999999981139503267596847425176765179308926185662298078548582170379439067165044410288854031049481594743364161622187121841818187648603927125262209438639553681654618823985640760188731793867961170022535129351893330180773705244319986644578003569234231285691342840034082734135647456849389933411990123839488"},
+ {"0x1.1ccf385ebc8a0p+1023", 309, "100000000000000001097906362944045541740492309677311846336810682903157585404911491537163328978494688899061249669721172515611590283743140088328307009198146046031271664502933027185697489699588559043338384466165001178426897626212945177628091195786707458122783970171784415105291802893207873272974885715430223118336"},
+ {"0x1.fffffffffffffp+1023", 309, "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368"},
+] of _
diff --git a/spec/std/http/server/server_spec.cr b/spec/std/http/server/server_spec.cr
index e5aa0ec261a7..f5a82a514e0b 100644
--- a/spec/std/http/server/server_spec.cr
+++ b/spec/std/http/server/server_spec.cr
@@ -45,12 +45,9 @@ describe HTTP::Server do
server = HTTP::Server.new { }
server.bind_unused_port
- spawn do
+ run_server(server) do
server.close
- sleep 0.001
end
-
- server.listen
end
it "closes the server" do
diff --git a/spec/std/http/spec_helper.cr b/spec/std/http/spec_helper.cr
index 410e211e4dbe..18ec9e0bab46 100644
--- a/spec/std/http/spec_helper.cr
+++ b/spec/std/http/spec_helper.cr
@@ -46,6 +46,11 @@ def run_server(server, &)
wait_for { server.listening? }
wait_until_blocked f
+ {% if flag?(:preview_mt) %}
+ # avoids fiber synchronization issues in specs, like closing the server
+ # before we properly listen, ...
+ sleep 0.001
+ {% end %}
yield server_done
ensure
server.close unless server.closed?
diff --git a/spec/std/humanize_spec.cr b/spec/std/humanize_spec.cr
index 841fde6cb2ba..c909417aca36 100644
--- a/spec/std/humanize_spec.cr
+++ b/spec/std/humanize_spec.cr
@@ -99,6 +99,14 @@ describe Number do
assert_prints 1.9999998.format, "1.9999998"
assert_prints 1111111.999999998.format, "1,111,111.999999998"
end
+
+ it "does not perform double rounding when decimal places are given" do
+ assert_prints 1.2345.format(decimal_places: 24), "1.234499999999999930722083"
+ assert_prints 1.2345.format(decimal_places: 65), "1.23449999999999993072208326339023187756538391113281250000000000000"
+ assert_prints 1.2345.format(decimal_places: 71), "1.23449999999999993072208326339023187756538391113281250000000000000000000"
+ assert_prints 1.2345.format(decimal_places: 83), "1.23449999999999993072208326339023187756538391113281250000000000000000000000000000000"
+ assert_prints 1.2345.format(decimal_places: 99), "1.234499999999999930722083263390231877565383911132812500000000000000000000000000000000000000000000000"
+ end
end
describe "#humanize" do
diff --git a/spec/std/io/io_spec.cr b/spec/std/io/io_spec.cr
index e2c065ecebf0..2c53df75205e 100644
--- a/spec/std/io/io_spec.cr
+++ b/spec/std/io/io_spec.cr
@@ -1013,4 +1013,14 @@ describe IO do
typeof(STDIN.cooked!)
typeof(STDIN.raw { })
typeof(STDIN.raw!)
+
+ describe IO::Error do
+ describe ".new" do
+ it "accepts `cause` argument (#14241)" do
+ cause = Exception.new("cause")
+ error = IO::Error.new("foo", cause: cause)
+ error.cause.should be cause
+ end
+ end
+ end
end
diff --git a/spec/std/io/memory_spec.cr b/spec/std/io/memory_spec.cr
index 37ff01e3421d..7d51c09483ed 100644
--- a/spec/std/io/memory_spec.cr
+++ b/spec/std/io/memory_spec.cr
@@ -18,6 +18,17 @@ describe IO::Memory do
io.gets_to_end.should eq(s)
end
+ it "write raises EOFError" do
+ io = IO::Memory.new
+ initial_capacity = io.@capacity
+ expect_raises(IO::EOFError) do
+ io.write Slice.new(Pointer(UInt8).null, Int32::MAX)
+ end
+ # nothing get's written
+ io.bytesize.should eq 0
+ io.@capacity.should eq initial_capacity
+ end
+
it "reads byte" do
io = IO::Memory.new("abc")
io.read_byte.should eq('a'.ord)
@@ -494,4 +505,26 @@ describe IO::Memory do
end
end
{% end %}
+
+ it "allocates for > 1 GB", tags: %w[slow] do
+ io = IO::Memory.new
+ mbstring = "a" * 1024 * 1024
+ 1024.times { io << mbstring }
+
+ io.bytesize.should eq(1 << 30)
+ io.@capacity.should eq 1 << 30
+
+ io << mbstring
+
+ io.bytesize.should eq (1 << 30) + (1 << 20)
+ io.@capacity.should eq Int32::MAX
+
+ 1022.times { io << mbstring }
+
+ io.write mbstring.to_slice[0..-4]
+ io << "a"
+ expect_raises(IO::EOFError) do
+ io << "a"
+ end
+ end
end
diff --git a/spec/std/log/env_config_spec.cr b/spec/std/log/env_config_spec.cr
index 7bfdfb0f239a..5ddc2941b82a 100644
--- a/spec/std/log/env_config_spec.cr
+++ b/spec/std/log/env_config_spec.cr
@@ -10,7 +10,7 @@ end
describe "Log.setup_from_env" do
after_all do
# Setup logging in specs (again) since these specs perform Log.setup
- Spec.log_setup
+ Spec.cli.log_setup
end
describe "backend" do
diff --git a/spec/std/object_spec.cr b/spec/std/object_spec.cr
index 3df134513ae2..43d1c009a19e 100644
--- a/spec/std/object_spec.cr
+++ b/spec/std/object_spec.cr
@@ -11,6 +11,8 @@ private class StringWrapper
end
end
+private EQ_OPERATORS = %w(<= >= == != []= ===)
+
private class TestObject
getter getter1
getter getter2 : Int32
@@ -113,6 +115,19 @@ private class TestObject
{key, value}
end
+ # NOTE: these methods are a syntax error in older versions
+ {% if compare_versions(Crystal::VERSION, "1.12.0-dev") >= 0 %}
+ {% for op in EQ_OPERATORS %}
+ def {{ op.id }}(*args, **opts)
+ [args, opts]
+ end
+
+ def {{ op.id }}(*args, **opts, &)
+ [args, opts, yield]
+ end
+ {% end %}
+ {% end %}
+
annotation TestAnnotation
end
@@ -130,7 +145,10 @@ end
private class DelegatedTestObject
delegate :property1=, to: @test_object
- delegate :[]=, to: @test_object
+
+ {% for op in EQ_OPERATORS %}
+ delegate {{ op.id.symbolize }}, to: @test_object
+ {% end %}
def initialize(@test_object : TestObject)
end
@@ -206,6 +224,22 @@ describe Object do
delegated = DelegatedTestObject.new(test_object)
(delegated["foo"] = "bar").should eq({"foo", "bar"})
end
+
+ {% if compare_versions(Crystal::VERSION, "1.12.0-dev") >= 0 %}
+ {% for op in EQ_OPERATORS %}
+ it "forwards \#{{ op.id }} with multiple parameters" do
+ test_object = TestObject.new
+ delegated = DelegatedTestObject.new(test_object)
+ delegated.{{ op.id }}(1, 2, a: 3, b: 4).should eq [{1, 2}, {a: 3, b: 4}]
+ end
+
+ it "forwards \#{{ op.id }} with multiple parameters and block parameter" do
+ test_object = TestObject.new
+ delegated = DelegatedTestObject.new(test_object)
+ delegated.{{ op.id }}(1, 2, a: 3, b: 4) { 5 }.should eq [{1, 2}, {a: 3, b: 4}, 5]
+ end
+ {% end %}
+ {% end %}
end
describe "getter" do
diff --git a/spec/std/openssl/ssl/socket_spec.cr b/spec/std/openssl/ssl/socket_spec.cr
index ccf1046b6949..bbc5b11e4b9b 100644
--- a/spec/std/openssl/ssl/socket_spec.cr
+++ b/spec/std/openssl/ssl/socket_spec.cr
@@ -160,20 +160,26 @@ describe OpenSSL::SSL::Socket do
server_context, client_context = ssl_context_pair
server_context.disable_session_resume_tickets # avoid Broken pipe
- server_finished_reading = Channel(String).new
+ server_finished_reading = Channel(String | Exception).new
spawn do
OpenSSL::SSL::Server.open(tcp_server, server_context, sync_close: true) do |server|
server_socket = server.accept
received = server_socket.gets_to_end # interprets underlying socket close as a graceful EOF
server_finished_reading.send(received)
end
+ rescue exc
+ server_finished_reading.send exc
end
+
socket = TCPSocket.new(tcp_server.local_address.address, tcp_server.local_address.port)
socket_ssl = OpenSSL::SSL::Socket::Client.new(socket, client_context, hostname: "example.com", sync_close: true)
socket_ssl.print "hello"
socket_ssl.flush # needed today see #5375
socket.close # close underlying socket without gracefully shutting down SSL at all
server_received = server_finished_reading.receive
+ if server_received.is_a?(Exception)
+ raise server_received
+ end
server_received.should eq("hello")
end
end
diff --git a/spec/std/process_spec.cr b/spec/std/process_spec.cr
index 94b8ec18a915..9734ec5ea99c 100644
--- a/spec/std/process_spec.cr
+++ b/spec/std/process_spec.cr
@@ -3,6 +3,7 @@
require "spec"
require "process"
require "./spec_helper"
+require "../support/env"
private def exit_code_command(code)
{% if flag?(:win32) %}
@@ -267,68 +268,62 @@ describe Process do
end
it "deletes existing environment variable" do
- ENV["FOO"] = "bar"
- value = Process.run(*print_env_command, env: {"FOO" => nil}) do |proc|
- proc.output.gets_to_end
+ with_env("FOO": "bar") do
+ value = Process.run(*print_env_command, env: {"FOO" => nil}) do |proc|
+ proc.output.gets_to_end
+ end
+ value.should_not match /(*ANYCRLF)^FOO=/m
end
- value.should_not match /(*ANYCRLF)^FOO=/m
- ensure
- ENV.delete("FOO")
end
{% if flag?(:win32) %}
it "deletes existing environment variable case-insensitive" do
- ENV["FOO"] = "bar"
- value = Process.run(*print_env_command, env: {"foo" => nil}) do |proc|
- proc.output.gets_to_end
+ with_env("FOO": "bar") do
+ value = Process.run(*print_env_command, env: {"foo" => nil}) do |proc|
+ proc.output.gets_to_end
+ end
+ value.should_not match /(*ANYCRLF)^FOO=/mi
end
- value.should_not match /(*ANYCRLF)^FOO=/mi
- ensure
- ENV.delete("FOO")
end
{% end %}
it "preserves existing environment variable" do
- ENV["FOO"] = "bar"
- value = Process.run(*print_env_command) do |proc|
- proc.output.gets_to_end
+ with_env("FOO": "bar") do
+ value = Process.run(*print_env_command) do |proc|
+ proc.output.gets_to_end
+ end
+ value.should match /(*ANYCRLF)^FOO=bar$/m
end
- value.should match /(*ANYCRLF)^FOO=bar$/m
- ensure
- ENV.delete("FOO")
end
it "preserves and sets an environment variable" do
- ENV["FOO"] = "bar"
- value = Process.run(*print_env_command, env: {"FOO2" => "bar2"}) do |proc|
- proc.output.gets_to_end
+ with_env("FOO": "bar") do
+ value = Process.run(*print_env_command, env: {"FOO2" => "bar2"}) do |proc|
+ proc.output.gets_to_end
+ end
+ value.should match /(*ANYCRLF)^FOO=bar$/m
+ value.should match /(*ANYCRLF)^FOO2=bar2$/m
end
- value.should match /(*ANYCRLF)^FOO=bar$/m
- value.should match /(*ANYCRLF)^FOO2=bar2$/m
- ensure
- ENV.delete("FOO")
end
it "overrides existing environment variable" do
- ENV["FOO"] = "bar"
- value = Process.run(*print_env_command, env: {"FOO" => "different"}) do |proc|
- proc.output.gets_to_end
+ with_env("FOO": "bar") do
+ value = Process.run(*print_env_command, env: {"FOO" => "different"}) do |proc|
+ proc.output.gets_to_end
+ end
+ value.should match /(*ANYCRLF)^FOO=different$/m
end
- value.should match /(*ANYCRLF)^FOO=different$/m
- ensure
- ENV.delete("FOO")
end
{% if flag?(:win32) %}
it "overrides existing environment variable case-insensitive" do
- ENV["FOO"] = "bar"
- value = Process.run(*print_env_command, env: {"fOo" => "different"}) do |proc|
- proc.output.gets_to_end
+ with_env("FOO": "bar") do
+ value = Process.run(*print_env_command, env: {"fOo" => "different"}) do |proc|
+ proc.output.gets_to_end
+ end
+ value.should_not match /(*ANYCRLF)^FOO=/m
+ value.should match /(*ANYCRLF)^fOo=different$/m
end
- value.should_not match /(*ANYCRLF)^FOO=/m
- value.should match /(*ANYCRLF)^fOo=different$/m
- ensure
- ENV.delete("FOO")
end
{% end %}
end
diff --git a/spec/std/signal_spec.cr b/spec/std/signal_spec.cr
index e92b74a6370c..d1d3aa3f1643 100644
--- a/spec/std/signal_spec.cr
+++ b/spec/std/signal_spec.cr
@@ -29,6 +29,8 @@ describe "Signal" do
sleep 0.1
end
ran.should be_true
+ ensure
+ Signal::USR1.reset
end
it "ignores a signal" do
@@ -36,6 +38,26 @@ describe "Signal" do
Process.signal Signal::USR2, Process.pid
end
+ it "allows chaining of signals" do
+ ran_first = false
+ ran_second = false
+
+ Signal::USR1.trap { ran_first = true }
+ existing = Signal::USR1.trap_handler?
+
+ Signal::USR1.trap do |signal|
+ existing.try &.call(signal)
+ ran_second = true
+ end
+
+ Process.signal Signal::USR1, Process.pid
+ sleep 0.1
+ ran_first.should be_true
+ ran_second.should be_true
+ ensure
+ Signal::USR1.reset
+ end
+
it "CHLD.reset sets default Crystal child handler" do
Signal::CHLD.reset
child = Process.new("true", shell: true)
diff --git a/spec/std/sprintf_spec.cr b/spec/std/sprintf_spec.cr
index f37384d3a70c..67cc1ac1604c 100644
--- a/spec/std/sprintf_spec.cr
+++ b/spec/std/sprintf_spec.cr
@@ -378,597 +378,802 @@ describe "::sprintf" do
assert_sprintf "1\u{0}%i\u{0}3", 2, "1\u00002\u00003"
end
- describe "floats" do
- context "fixed format" do
- it "works" do
- assert_sprintf "%f", 123, "123.000000"
-
- assert_sprintf "%12f", 123.45, " 123.450000"
- assert_sprintf "%-12f", 123.45, "123.450000 "
- assert_sprintf "% f", 123.45, " 123.450000"
- assert_sprintf "%+f", 123, "+123.000000"
- assert_sprintf "%012f", 123, "00123.000000"
- assert_sprintf "%.f", 1234.56, "1235"
- assert_sprintf "%.2f", 1234.5678, "1234.57"
- assert_sprintf "%10.2f", 1234.5678, " 1234.57"
- assert_sprintf "%*.2f", [10, 1234.5678], " 1234.57"
- assert_sprintf "%*.*f", [10, 2, 1234.5678], " 1234.57"
- assert_sprintf "%.2f", 2.536_f32, "2.54"
- assert_sprintf "%+0*.*f", [10, 2, 2.536_f32], "+000002.54"
- assert_sprintf "%#.0f", 1234.56, "1235."
- assert_sprintf "%#.1f", 1234.56, "1234.6"
-
- expect_raises(ArgumentError, "Expected dynamic value '*' to be an Int - \"not a number\" (String)") do
- sprintf("%*f", ["not a number", 2.536_f32])
+ if String::Formatter::HAS_RYU_PRINTF
+ describe "floats" do
+ context "fixed format" do
+ it "works" do
+ assert_sprintf "%f", 123, "123.000000"
+
+ assert_sprintf "%12f", 123.45, " 123.450000"
+ assert_sprintf "%-12f", 123.45, "123.450000 "
+ assert_sprintf "% f", 123.45, " 123.450000"
+ assert_sprintf "%+f", 123, "+123.000000"
+ assert_sprintf "%012f", 123, "00123.000000"
+ assert_sprintf "%.f", 1234.56, "1235"
+ assert_sprintf "%.2f", 1234.5678, "1234.57"
+ assert_sprintf "%10.2f", 1234.5678, " 1234.57"
+ assert_sprintf "%*.2f", [10, 1234.5678], " 1234.57"
+ assert_sprintf "%*.*f", [10, 2, 1234.5678], " 1234.57"
+ assert_sprintf "%.2f", 2.536_f32, "2.54"
+ assert_sprintf "%+0*.*f", [10, 2, 2.536_f32], "+000002.54"
+ assert_sprintf "%#.0f", 1234.56, "1235."
+ assert_sprintf "%#.1f", 1234.56, "1234.6"
+
+ expect_raises(ArgumentError, "Expected dynamic value '*' to be an Int - \"not a number\" (String)") do
+ sprintf("%*f", ["not a number", 2.536_f32])
+ end
+
+ assert_sprintf "%12.2f %12.2f %6.2f %.2f", [2.0, 3.0, 4.0, 5.0], " 2.00 3.00 4.00 5.00"
+
+ assert_sprintf "%f", 1e15, "1000000000000000.000000"
end
-
- assert_sprintf "%12.2f %12.2f %6.2f %.2f", [2.0, 3.0, 4.0, 5.0], " 2.00 3.00 4.00 5.00"
-
- assert_sprintf "%f", 1e15, "1000000000000000.000000"
end
- end
- context "scientific format" do
- it "works" do
- assert_sprintf "%e", 123.45, "1.234500e+2"
- assert_sprintf "%E", 123.45, "1.234500E+2"
-
- assert_sprintf "%e", Float64::MAX, "1.797693e+308"
- assert_sprintf "%e", Float64::MIN_POSITIVE, "2.225074e-308"
- assert_sprintf "%e", Float64::MIN_SUBNORMAL, "4.940656e-324"
- assert_sprintf "%e", 0.0, "0.000000e+0"
- assert_sprintf "%e", -0.0, "-0.000000e+0"
- assert_sprintf "%e", -Float64::MIN_SUBNORMAL, "-4.940656e-324"
- assert_sprintf "%e", -Float64::MIN_POSITIVE, "-2.225074e-308"
- assert_sprintf "%e", Float64::MIN, "-1.797693e+308"
- end
+ context "scientific format" do
+ it "works" do
+ assert_sprintf "%e", 123.45, "1.234500e+2"
+ assert_sprintf "%E", 123.45, "1.234500E+2"
+
+ assert_sprintf "%e", Float64::MAX, "1.797693e+308"
+ assert_sprintf "%e", Float64::MIN_POSITIVE, "2.225074e-308"
+ assert_sprintf "%e", Float64::MIN_SUBNORMAL, "4.940656e-324"
+ assert_sprintf "%e", 0.0, "0.000000e+0"
+ assert_sprintf "%e", -0.0, "-0.000000e+0"
+ assert_sprintf "%e", -Float64::MIN_SUBNORMAL, "-4.940656e-324"
+ assert_sprintf "%e", -Float64::MIN_POSITIVE, "-2.225074e-308"
+ assert_sprintf "%e", Float64::MIN, "-1.797693e+308"
+ end
- context "width specifier" do
- it "sets the minimum length of the string" do
- assert_sprintf "%20e", 123.45, " 1.234500e+2"
- assert_sprintf "%20e", -123.45, " -1.234500e+2"
- assert_sprintf "%+20e", 123.45, " +1.234500e+2"
+ context "width specifier" do
+ it "sets the minimum length of the string" do
+ assert_sprintf "%20e", 123.45, " 1.234500e+2"
+ assert_sprintf "%20e", -123.45, " -1.234500e+2"
+ assert_sprintf "%+20e", 123.45, " +1.234500e+2"
- assert_sprintf "%12e", 123.45, " 1.234500e+2"
- assert_sprintf "%12e", -123.45, "-1.234500e+2"
- assert_sprintf "%+12e", 123.45, "+1.234500e+2"
+ assert_sprintf "%12e", 123.45, " 1.234500e+2"
+ assert_sprintf "%12e", -123.45, "-1.234500e+2"
+ assert_sprintf "%+12e", 123.45, "+1.234500e+2"
- assert_sprintf "%11e", 123.45, "1.234500e+2"
- assert_sprintf "%11e", -123.45, "-1.234500e+2"
- assert_sprintf "%+11e", 123.45, "+1.234500e+2"
+ assert_sprintf "%11e", 123.45, "1.234500e+2"
+ assert_sprintf "%11e", -123.45, "-1.234500e+2"
+ assert_sprintf "%+11e", 123.45, "+1.234500e+2"
- assert_sprintf "%2e", 123.45, "1.234500e+2"
- assert_sprintf "%2e", -123.45, "-1.234500e+2"
- assert_sprintf "%+2e", 123.45, "+1.234500e+2"
- end
+ assert_sprintf "%2e", 123.45, "1.234500e+2"
+ assert_sprintf "%2e", -123.45, "-1.234500e+2"
+ assert_sprintf "%+2e", 123.45, "+1.234500e+2"
+ end
- it "left-justifies on negative width" do
- assert_sprintf "%*e", [-20, 123.45], "1.234500e+2 "
+ it "left-justifies on negative width" do
+ assert_sprintf "%*e", [-20, 123.45], "1.234500e+2 "
+ end
end
- end
- context "precision specifier" do
- it "sets the minimum length of the fractional part" do
- assert_sprintf "%.0e", 2.0, "2e+0"
- assert_sprintf "%.0e", 2.5.prev_float, "2e+0"
- assert_sprintf "%.0e", 2.5, "2e+0"
- assert_sprintf "%.0e", 2.5.next_float, "3e+0"
- assert_sprintf "%.0e", 3.0, "3e+0"
- assert_sprintf "%.0e", 3.5.prev_float, "3e+0"
- assert_sprintf "%.0e", 3.5, "4e+0"
- assert_sprintf "%.0e", 3.5.next_float, "4e+0"
- assert_sprintf "%.0e", 4.0, "4e+0"
-
- assert_sprintf "%.0e", 9.5, "1e+1"
-
- assert_sprintf "%.100e", 1.1, "1.1000000000000000888178419700125232338905334472656250000000000000000000000000000000000000000000000000e+0"
-
- assert_sprintf "%.10000e", 1.0, "1.#{"0" * 10000}e+0"
-
- assert_sprintf "%.1000e", Float64::MIN_POSITIVE.prev_float,
- "2.2250738585072008890245868760858598876504231122409594654935248025624400092282356951" \
- "787758888037591552642309780950434312085877387158357291821993020294379224223559819827" \
- "501242041788969571311791082261043971979604000454897391938079198936081525613113376149" \
- "842043271751033627391549782731594143828136275113838604094249464942286316695429105080" \
- "201815926642134996606517803095075913058719846423906068637102005108723282784678843631" \
- "944515866135041223479014792369585208321597621066375401613736583044193603714778355306" \
- "682834535634005074073040135602968046375918583163124224521599262546494300836851861719" \
- "422417646455137135420132217031370496583210154654068035397417906022589503023501937519" \
- "773030945763173210852507299305089761582519159720757232455434770912461317493580281734" \
- "466552734375000000000000000000000000000000000000000000000000000000000000000000000000" \
- "000000000000000000000000000000000000000000000000000000000000000000000000000000000000" \
- "000000000000000000000000000000000000000000000000000000000000000000000000000000e-308"
+ context "precision specifier" do
+ it "sets the minimum length of the fractional part" do
+ assert_sprintf "%.0e", 2.0, "2e+0"
+ assert_sprintf "%.0e", 2.5.prev_float, "2e+0"
+ assert_sprintf "%.0e", 2.5, "2e+0"
+ assert_sprintf "%.0e", 2.5.next_float, "3e+0"
+ assert_sprintf "%.0e", 3.0, "3e+0"
+ assert_sprintf "%.0e", 3.5.prev_float, "3e+0"
+ assert_sprintf "%.0e", 3.5, "4e+0"
+ assert_sprintf "%.0e", 3.5.next_float, "4e+0"
+ assert_sprintf "%.0e", 4.0, "4e+0"
+
+ assert_sprintf "%.0e", 9.5, "1e+1"
+
+ assert_sprintf "%.100e", 1.1, "1.1000000000000000888178419700125232338905334472656250000000000000000000000000000000000000000000000000e+0"
+
+ assert_sprintf "%.10000e", 1.0, "1.#{"0" * 10000}e+0"
+
+ assert_sprintf "%.1000e", Float64::MIN_POSITIVE.prev_float,
+ "2.2250738585072008890245868760858598876504231122409594654935248025624400092282356951" \
+ "787758888037591552642309780950434312085877387158357291821993020294379224223559819827" \
+ "501242041788969571311791082261043971979604000454897391938079198936081525613113376149" \
+ "842043271751033627391549782731594143828136275113838604094249464942286316695429105080" \
+ "201815926642134996606517803095075913058719846423906068637102005108723282784678843631" \
+ "944515866135041223479014792369585208321597621066375401613736583044193603714778355306" \
+ "682834535634005074073040135602968046375918583163124224521599262546494300836851861719" \
+ "422417646455137135420132217031370496583210154654068035397417906022589503023501937519" \
+ "773030945763173210852507299305089761582519159720757232455434770912461317493580281734" \
+ "466552734375000000000000000000000000000000000000000000000000000000000000000000000000" \
+ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000" \
+ "000000000000000000000000000000000000000000000000000000000000000000000000000000e-308"
+ end
+
+ it "can be used with width" do
+ assert_sprintf "%20.12e", 123.45, " 1.234500000000e+2"
+ assert_sprintf "%20.12e", -123.45, " -1.234500000000e+2"
+ assert_sprintf "%20.12e", 0.0, " 0.000000000000e+0"
+
+ assert_sprintf "%-20.12e", 123.45, "1.234500000000e+2 "
+ assert_sprintf "%-20.12e", -123.45, "-1.234500000000e+2 "
+ assert_sprintf "%-20.12e", 0.0, "0.000000000000e+0 "
+
+ assert_sprintf "%8.12e", 123.45, "1.234500000000e+2"
+ assert_sprintf "%8.12e", -123.45, "-1.234500000000e+2"
+ assert_sprintf "%8.12e", 0.0, "0.000000000000e+0"
+ end
+
+ it "is ignored if precision argument is negative" do
+ assert_sprintf "%.*e", [-2, 123.45], "1.234500e+2"
+ end
end
- it "can be used with width" do
- assert_sprintf "%20.12e", 123.45, " 1.234500000000e+2"
- assert_sprintf "%20.12e", -123.45, " -1.234500000000e+2"
- assert_sprintf "%20.12e", 0.0, " 0.000000000000e+0"
-
- assert_sprintf "%-20.12e", 123.45, "1.234500000000e+2 "
- assert_sprintf "%-20.12e", -123.45, "-1.234500000000e+2 "
- assert_sprintf "%-20.12e", 0.0, "0.000000000000e+0 "
-
- assert_sprintf "%8.12e", 123.45, "1.234500000000e+2"
- assert_sprintf "%8.12e", -123.45, "-1.234500000000e+2"
- assert_sprintf "%8.12e", 0.0, "0.000000000000e+0"
+ context "sharp flag" do
+ it "prints a decimal point even if no digits follow" do
+ assert_sprintf "%#.0e", 1.0, "1.e+0"
+ assert_sprintf "%#.0e", 10000.0, "1.e+4"
+ assert_sprintf "%#.0e", 1.0e+23, "1.e+23"
+ assert_sprintf "%#.0e", 1.0e-100, "1.e-100"
+ assert_sprintf "%#.0e", 0.0, "0.e+0"
+ assert_sprintf "%#.0e", -0.0, "-0.e+0"
+ end
end
- it "is ignored if precision argument is negative" do
- assert_sprintf "%.*e", [-2, 123.45], "1.234500e+2"
+ context "plus flag" do
+ it "writes a plus sign for positive values" do
+ assert_sprintf "%+e", 123.45, "+1.234500e+2"
+ assert_sprintf "%+e", -123.45, "-1.234500e+2"
+ assert_sprintf "%+e", 0.0, "+0.000000e+0"
+ end
+
+ it "writes plus sign after left space-padding" do
+ assert_sprintf "%+20e", 123.45, " +1.234500e+2"
+ assert_sprintf "%+20e", -123.45, " -1.234500e+2"
+ assert_sprintf "%+20e", 0.0, " +0.000000e+0"
+ end
+
+ it "writes plus sign before left zero-padding" do
+ assert_sprintf "%+020e", 123.45, "+000000001.234500e+2"
+ assert_sprintf "%+020e", -123.45, "-000000001.234500e+2"
+ assert_sprintf "%+020e", 0.0, "+000000000.000000e+0"
+ end
end
- end
- context "sharp flag" do
- it "prints a decimal point even if no digits follow" do
- assert_sprintf "%#.0e", 1.0, "1.e+0"
- assert_sprintf "%#.0e", 10000.0, "1.e+4"
- assert_sprintf "%#.0e", 1.0e+23, "1.e+23"
- assert_sprintf "%#.0e", 1.0e-100, "1.e-100"
- assert_sprintf "%#.0e", 0.0, "0.e+0"
- assert_sprintf "%#.0e", -0.0, "-0.e+0"
+ context "space flag" do
+ it "writes a space for positive values" do
+ assert_sprintf "% e", 123.45, " 1.234500e+2"
+ assert_sprintf "% e", -123.45, "-1.234500e+2"
+ assert_sprintf "% e", 0.0, " 0.000000e+0"
+ end
+
+ it "writes space before left space-padding" do
+ assert_sprintf "% 20e", 123.45, " 1.234500e+2"
+ assert_sprintf "% 20e", -123.45, " -1.234500e+2"
+ assert_sprintf "% 20e", 0.0, " 0.000000e+0"
+
+ assert_sprintf "% 020e", 123.45, " 000000001.234500e+2"
+ assert_sprintf "% 020e", -123.45, "-000000001.234500e+2"
+ assert_sprintf "% 020e", 0.0, " 000000000.000000e+0"
+ end
+
+ it "is ignored if plus flag is also specified" do
+ assert_sprintf "% +e", 123.45, "+1.234500e+2"
+ assert_sprintf "%+ e", -123.45, "-1.234500e+2"
+ end
end
- end
- context "plus flag" do
- it "writes a plus sign for positive values" do
- assert_sprintf "%+e", 123.45, "+1.234500e+2"
- assert_sprintf "%+e", -123.45, "-1.234500e+2"
- assert_sprintf "%+e", 0.0, "+0.000000e+0"
+ context "zero flag" do
+ it "left-pads the result with zeros" do
+ assert_sprintf "%020e", 123.45, "0000000001.234500e+2"
+ assert_sprintf "%020e", -123.45, "-000000001.234500e+2"
+ assert_sprintf "%020e", 0.0, "0000000000.000000e+0"
+ end
+
+ it "is ignored if string is left-justified" do
+ assert_sprintf "%-020e", 123.45, "1.234500e+2 "
+ assert_sprintf "%-020e", -123.45, "-1.234500e+2 "
+ assert_sprintf "%-020e", 0.0, "0.000000e+0 "
+ end
+
+ it "can be used with precision" do
+ assert_sprintf "%020.12e", 123.45, "0001.234500000000e+2"
+ assert_sprintf "%020.12e", -123.45, "-001.234500000000e+2"
+ assert_sprintf "%020.12e", 0.0, "0000.000000000000e+0"
+ end
end
- it "writes plus sign after left space-padding" do
- assert_sprintf "%+20e", 123.45, " +1.234500e+2"
- assert_sprintf "%+20e", -123.45, " -1.234500e+2"
- assert_sprintf "%+20e", 0.0, " +0.000000e+0"
- end
-
- it "writes plus sign before left zero-padding" do
- assert_sprintf "%+020e", 123.45, "+000000001.234500e+2"
- assert_sprintf "%+020e", -123.45, "-000000001.234500e+2"
- assert_sprintf "%+020e", 0.0, "+000000000.000000e+0"
+ context "minus flag" do
+ it "left-justifies the string" do
+ assert_sprintf "%-20e", 123.45, "1.234500e+2 "
+ assert_sprintf "%-20e", -123.45, "-1.234500e+2 "
+ assert_sprintf "%-20e", 0.0, "0.000000e+0 "
+ end
end
end
- context "space flag" do
- it "writes a space for positive values" do
- assert_sprintf "% e", 123.45, " 1.234500e+2"
- assert_sprintf "% e", -123.45, "-1.234500e+2"
- assert_sprintf "% e", 0.0, " 0.000000e+0"
+ context "general format" do
+ it "works" do
+ assert_sprintf "%g", 123.45, "123.45"
+ assert_sprintf "%G", 123.45, "123.45"
+
+ assert_sprintf "%g", 1.2345e-5, "1.2345e-5"
+ assert_sprintf "%G", 1.2345e-5, "1.2345E-5"
+
+ assert_sprintf "%g", 1.2345e+25, "1.2345e+25"
+ assert_sprintf "%G", 1.2345e+25, "1.2345E+25"
+
+ assert_sprintf "%g", Float64::MAX, "1.79769e+308"
+ assert_sprintf "%g", Float64::MIN_POSITIVE, "2.22507e-308"
+ assert_sprintf "%g", Float64::MIN_SUBNORMAL, "4.94066e-324"
+ assert_sprintf "%g", 0.0, "0"
+ assert_sprintf "%g", -0.0, "-0"
+ assert_sprintf "%g", -Float64::MIN_SUBNORMAL, "-4.94066e-324"
+ assert_sprintf "%g", -Float64::MIN_POSITIVE, "-2.22507e-308"
+ assert_sprintf "%g", Float64::MIN, "-1.79769e+308"
end
- it "writes space before left space-padding" do
- assert_sprintf "% 20e", 123.45, " 1.234500e+2"
- assert_sprintf "% 20e", -123.45, " -1.234500e+2"
- assert_sprintf "% 20e", 0.0, " 0.000000e+0"
+ context "width specifier" do
+ it "sets the minimum length of the string" do
+ assert_sprintf "%10g", 123.45, " 123.45"
+ assert_sprintf "%10g", -123.45, " -123.45"
+ assert_sprintf "%+10g", 123.45, " +123.45"
- assert_sprintf "% 020e", 123.45, " 000000001.234500e+2"
- assert_sprintf "% 020e", -123.45, "-000000001.234500e+2"
- assert_sprintf "% 020e", 0.0, " 000000000.000000e+0"
- end
-
- it "is ignored if plus flag is also specified" do
- assert_sprintf "% +e", 123.45, "+1.234500e+2"
- assert_sprintf "%+ e", -123.45, "-1.234500e+2"
- end
- end
+ assert_sprintf "%7g", 123.45, " 123.45"
+ assert_sprintf "%7g", -123.45, "-123.45"
+ assert_sprintf "%+7g", 123.45, "+123.45"
- context "zero flag" do
- it "left-pads the result with zeros" do
- assert_sprintf "%020e", 123.45, "0000000001.234500e+2"
- assert_sprintf "%020e", -123.45, "-000000001.234500e+2"
- assert_sprintf "%020e", 0.0, "0000000000.000000e+0"
- end
+ assert_sprintf "%6g", 123.45, "123.45"
+ assert_sprintf "%6g", -123.45, "-123.45"
+ assert_sprintf "%+6g", 123.45, "+123.45"
- it "is ignored if string is left-justified" do
- assert_sprintf "%-020e", 123.45, "1.234500e+2 "
- assert_sprintf "%-020e", -123.45, "-1.234500e+2 "
- assert_sprintf "%-020e", 0.0, "0.000000e+0 "
- end
+ assert_sprintf "%2g", 123.45, "123.45"
+ assert_sprintf "%2g", -123.45, "-123.45"
+ assert_sprintf "%+2g", 123.45, "+123.45"
+ end
- it "can be used with precision" do
- assert_sprintf "%020.12e", 123.45, "0001.234500000000e+2"
- assert_sprintf "%020.12e", -123.45, "-001.234500000000e+2"
- assert_sprintf "%020.12e", 0.0, "0000.000000000000e+0"
+ it "left-justifies on negative width" do
+ assert_sprintf "%*g", [-10, 123.45], "123.45 "
+ end
end
- end
- context "minus flag" do
- it "left-justifies the string" do
- assert_sprintf "%-20e", 123.45, "1.234500e+2 "
- assert_sprintf "%-20e", -123.45, "-1.234500e+2 "
- assert_sprintf "%-20e", 0.0, "0.000000e+0 "
+ context "precision specifier" do
+ it "sets the precision of the value" do
+ assert_sprintf "%.0g", 123.45, "1e+2"
+ assert_sprintf "%.1g", 123.45, "1e+2"
+ assert_sprintf "%.2g", 123.45, "1.2e+2"
+ assert_sprintf "%.3g", 123.45, "123"
+ assert_sprintf "%.4g", 123.45, "123.5"
+ assert_sprintf "%.5g", 123.45, "123.45"
+ assert_sprintf "%.6g", 123.45, "123.45"
+ assert_sprintf "%.7g", 123.45, "123.45"
+ assert_sprintf "%.8g", 123.45, "123.45"
+
+ assert_sprintf "%.1000g", 123.45, "123.4500000000000028421709430404007434844970703125"
+
+ assert_sprintf "%.0g", 1.23e-45, "1e-45"
+ assert_sprintf "%.1g", 1.23e-45, "1e-45"
+ assert_sprintf "%.2g", 1.23e-45, "1.2e-45"
+ assert_sprintf "%.3g", 1.23e-45, "1.23e-45"
+ assert_sprintf "%.4g", 1.23e-45, "1.23e-45"
+ assert_sprintf "%.5g", 1.23e-45, "1.23e-45"
+ assert_sprintf "%.6g", 1.23e-45, "1.23e-45"
+
+ assert_sprintf "%.1000g", 1e-5, "1.0000000000000000818030539140313095458623138256371021270751953125e-5"
+ end
+
+ it "can be used with width" do
+ assert_sprintf "%10.1g", 123.45, " 1e+2"
+ assert_sprintf "%10.2g", 123.45, " 1.2e+2"
+ assert_sprintf "%10.3g", 123.45, " 123"
+ assert_sprintf "%10.4g", 123.45, " 123.5"
+ assert_sprintf "%10.5g", 123.45, " 123.45"
+ assert_sprintf "%10.1g", -123.45, " -1e+2"
+ assert_sprintf "%10.2g", -123.45, " -1.2e+2"
+ assert_sprintf "%10.3g", -123.45, " -123"
+ assert_sprintf "%10.4g", -123.45, " -123.5"
+ assert_sprintf "%10.5g", -123.45, " -123.45"
+ assert_sprintf "%10.5g", 0, " 0"
+
+ assert_sprintf "%-10.1g", 123.45, "1e+2 "
+ assert_sprintf "%-10.2g", 123.45, "1.2e+2 "
+ assert_sprintf "%-10.3g", 123.45, "123 "
+ assert_sprintf "%-10.4g", 123.45, "123.5 "
+ assert_sprintf "%-10.5g", 123.45, "123.45 "
+ assert_sprintf "%-10.1g", -123.45, "-1e+2 "
+ assert_sprintf "%-10.2g", -123.45, "-1.2e+2 "
+ assert_sprintf "%-10.3g", -123.45, "-123 "
+ assert_sprintf "%-10.4g", -123.45, "-123.5 "
+ assert_sprintf "%-10.5g", -123.45, "-123.45 "
+ assert_sprintf "%-10.5g", 0, "0 "
+
+ assert_sprintf "%3.1g", 123.45, "1e+2"
+ assert_sprintf "%3.2g", 123.45, "1.2e+2"
+ assert_sprintf "%3.3g", 123.45, "123"
+ assert_sprintf "%3.4g", 123.45, "123.5"
+ assert_sprintf "%3.5g", 123.45, "123.45"
+ assert_sprintf "%3.1g", -123.45, "-1e+2"
+ assert_sprintf "%3.2g", -123.45, "-1.2e+2"
+ assert_sprintf "%3.3g", -123.45, "-123"
+ assert_sprintf "%3.4g", -123.45, "-123.5"
+ assert_sprintf "%3.5g", -123.45, "-123.45"
+
+ assert_sprintf "%1000.800g", 123.45, "#{" " * 950}123.4500000000000028421709430404007434844970703125"
+ end
+
+ it "is ignored if precision argument is negative" do
+ assert_sprintf "%.*g", [-2, 123.45], "123.45"
+ end
end
- end
- end
-
- context "general format" do
- pending_win32 "works" do
- assert_sprintf "%g", 123, "123"
- assert_sprintf "%G", 12345678.45, "1.23457E+07"
- assert_sprintf "%100.50g", 123.45, " 123.4500000000000028421709430404007434844970703125"
- assert_sprintf "%#.12g", 12345.0, "12345.0000000"
- end
- end
-
- context "hex format" do
- it "works" do
- assert_sprintf "%a", 1194684.0, "0x1.23abcp+20"
- assert_sprintf "%A", 1194684.0, "0X1.23ABCP+20"
- assert_sprintf "%a", 12345678.45, "0x1.78c29ce666666p+23"
- assert_sprintf "%A", 12345678.45, "0X1.78C29CE666666P+23"
-
- assert_sprintf "%a", Float64::MAX, "0x1.fffffffffffffp+1023"
- assert_sprintf "%a", Float64::MIN_POSITIVE, "0x1p-1022"
- assert_sprintf "%a", Float64::MIN_SUBNORMAL, "0x0.0000000000001p-1022"
- assert_sprintf "%a", 0.0, "0x0p+0"
- assert_sprintf "%a", -0.0, "-0x0p+0"
- assert_sprintf "%a", -Float64::MIN_SUBNORMAL, "-0x0.0000000000001p-1022"
- assert_sprintf "%a", -Float64::MIN_POSITIVE, "-0x1p-1022"
- assert_sprintf "%a", Float64::MIN, "-0x1.fffffffffffffp+1023"
- end
- context "width specifier" do
- it "sets the minimum length of the string" do
- assert_sprintf "%20a", hexfloat("0x1p+0"), " 0x1p+0"
- assert_sprintf "%20a", hexfloat("0x1.2p+0"), " 0x1.2p+0"
- assert_sprintf "%20a", hexfloat("0x1.23p+0"), " 0x1.23p+0"
- assert_sprintf "%20a", hexfloat("0x1.234p+0"), " 0x1.234p+0"
- assert_sprintf "%20a", hexfloat("0x1.2345p+0"), " 0x1.2345p+0"
- assert_sprintf "%20a", hexfloat("0x1.23456p+0"), " 0x1.23456p+0"
- assert_sprintf "%20a", hexfloat("0x1.234567p+0"), " 0x1.234567p+0"
- assert_sprintf "%20a", hexfloat("0x1.2345678p+0"), " 0x1.2345678p+0"
- assert_sprintf "%20a", hexfloat("0x1.23456789p+0"), " 0x1.23456789p+0"
- assert_sprintf "%20a", hexfloat("0x1.23456789ap+0"), " 0x1.23456789ap+0"
- assert_sprintf "%20a", hexfloat("0x1.23456789abp+0"), " 0x1.23456789abp+0"
- assert_sprintf "%20a", hexfloat("0x1.23456789abcp+0"), " 0x1.23456789abcp+0"
-
- assert_sprintf "%20a", hexfloat("-0x1p+0"), " -0x1p+0"
- assert_sprintf "%20a", hexfloat("-0x1.2p+0"), " -0x1.2p+0"
- assert_sprintf "%20a", hexfloat("-0x1.23p+0"), " -0x1.23p+0"
- assert_sprintf "%20a", hexfloat("-0x1.234p+0"), " -0x1.234p+0"
- assert_sprintf "%20a", hexfloat("-0x1.2345p+0"), " -0x1.2345p+0"
- assert_sprintf "%20a", hexfloat("-0x1.23456p+0"), " -0x1.23456p+0"
- assert_sprintf "%20a", hexfloat("-0x1.234567p+0"), " -0x1.234567p+0"
- assert_sprintf "%20a", hexfloat("-0x1.2345678p+0"), " -0x1.2345678p+0"
- assert_sprintf "%20a", hexfloat("-0x1.23456789p+0"), " -0x1.23456789p+0"
- assert_sprintf "%20a", hexfloat("-0x1.23456789ap+0"), " -0x1.23456789ap+0"
- assert_sprintf "%20a", hexfloat("-0x1.23456789abp+0"), " -0x1.23456789abp+0"
- assert_sprintf "%20a", hexfloat("-0x1.23456789abcp+0"), " -0x1.23456789abcp+0"
-
- assert_sprintf "%+20a", 1194684.0, " +0x1.23abcp+20"
-
- assert_sprintf "%14a", 1194684.0, " 0x1.23abcp+20"
- assert_sprintf "%14a", -1194684.0, "-0x1.23abcp+20"
- assert_sprintf "%+14a", 1194684.0, "+0x1.23abcp+20"
-
- assert_sprintf "%13a", 1194684.0, "0x1.23abcp+20"
- assert_sprintf "%13a", -1194684.0, "-0x1.23abcp+20"
- assert_sprintf "%+13a", 1194684.0, "+0x1.23abcp+20"
-
- assert_sprintf "%2a", 1194684.0, "0x1.23abcp+20"
- assert_sprintf "%2a", -1194684.0, "-0x1.23abcp+20"
- assert_sprintf "%+2a", 1194684.0, "+0x1.23abcp+20"
+ context "sharp flag" do
+ it "prints decimal point and trailing zeros" do
+ assert_sprintf "%#.0g", 12345, "1.e+4"
+ assert_sprintf "%#.6g", 12345, "12345.0"
+ assert_sprintf "%#.10g", 12345, "12345.00000"
+ assert_sprintf "%#.100g", 12345, "12345.#{"0" * 95}"
+ assert_sprintf "%#.1000g", 12345, "12345.#{"0" * 995}"
+
+ assert_sprintf "%#.0g", 1e-5, "1.e-5"
+ assert_sprintf "%#.6g", 1e-5, "1.00000e-5"
+ assert_sprintf "%#.10g", 1e-5, "1.000000000e-5"
+ assert_sprintf "%#.100g", 1e-5, "1.0000000000000000818030539140313095458623138256371021270751953125#{"0" * 35}e-5"
+ assert_sprintf "%#.1000g", 1e-5, "1.0000000000000000818030539140313095458623138256371021270751953125#{"0" * 935}e-5"
+
+ assert_sprintf "%#15.0g", 12345, " 1.e+4"
+ assert_sprintf "%#15.6g", 12345, " 12345.0"
+ assert_sprintf "%#15.10g", 12345, " 12345.00000"
+ end
end
- it "left-justifies on negative width" do
- assert_sprintf "%*a", [-20, 1194684.0], "0x1.23abcp+20 "
+ context "plus flag" do
+ it "writes a plus sign for positive values" do
+ assert_sprintf "%+g", 123.45, "+123.45"
+ assert_sprintf "%+g", -123.45, "-123.45"
+ assert_sprintf "%+g", 0.0, "+0"
+ end
+
+ it "writes plus sign after left space-padding" do
+ assert_sprintf "%+10g", 123.45, " +123.45"
+ assert_sprintf "%+10g", -123.45, " -123.45"
+ assert_sprintf "%+10g", 0.0, " +0"
+ end
+
+ it "writes plus sign before left zero-padding" do
+ assert_sprintf "%+010g", 123.45, "+000123.45"
+ assert_sprintf "%+010g", -123.45, "-000123.45"
+ assert_sprintf "%+010g", 0.0, "+000000000"
+ end
end
- end
- context "precision specifier" do
- it "sets the minimum length of the fractional part" do
- assert_sprintf "%.0a", 0.0, "0x0p+0"
-
- assert_sprintf "%.0a", (Float64::MIN_POSITIVE / 2).prev_float, "0x0p-1022"
- assert_sprintf "%.0a", Float64::MIN_POSITIVE / 2, "0x0p-1022"
- assert_sprintf "%.0a", (Float64::MIN_POSITIVE / 2).next_float, "0x1p-1022"
- assert_sprintf "%.0a", Float64::MIN_POSITIVE.prev_float, "0x1p-1022"
- assert_sprintf "%.0a", Float64::MIN_POSITIVE, "0x1p-1022"
-
- assert_sprintf "%.0a", 0.0625, "0x1p-4"
- assert_sprintf "%.0a", 0.0625.next_float, "0x1p-4"
- assert_sprintf "%.0a", 0.09375.prev_float, "0x1p-4"
- assert_sprintf "%.0a", 0.09375, "0x2p-4"
- assert_sprintf "%.0a", 0.09375.next_float, "0x2p-4"
- assert_sprintf "%.0a", 0.125.prev_float, "0x2p-4"
- assert_sprintf "%.0a", 0.125, "0x1p-3"
-
- assert_sprintf "%.1a", 2.0, "0x1.0p+1"
- assert_sprintf "%.1a", 2.0.next_float, "0x1.0p+1"
- assert_sprintf "%.1a", 2.0625.prev_float, "0x1.0p+1"
- assert_sprintf "%.1a", 2.0625, "0x1.0p+1"
- assert_sprintf "%.1a", 2.0625.next_float, "0x1.1p+1"
- assert_sprintf "%.1a", 2.125.prev_float, "0x1.1p+1"
- assert_sprintf "%.1a", 2.125, "0x1.1p+1"
- assert_sprintf "%.1a", 2.125.next_float, "0x1.1p+1"
- assert_sprintf "%.1a", 2.1875.prev_float, "0x1.1p+1"
- assert_sprintf "%.1a", 2.1875, "0x1.2p+1"
- assert_sprintf "%.1a", 2.1875.next_float, "0x1.2p+1"
- assert_sprintf "%.1a", 2.25.prev_float, "0x1.2p+1"
- assert_sprintf "%.1a", 2.25, "0x1.2p+1"
-
- assert_sprintf "%.1a", 60.0, "0x1.ep+5"
- assert_sprintf "%.1a", 60.0.next_float, "0x1.ep+5"
- assert_sprintf "%.1a", 61.0.prev_float, "0x1.ep+5"
- assert_sprintf "%.1a", 61.0, "0x1.ep+5"
- assert_sprintf "%.1a", 61.0.next_float, "0x1.fp+5"
- assert_sprintf "%.1a", 62.0.prev_float, "0x1.fp+5"
- assert_sprintf "%.1a", 62.0, "0x1.fp+5"
- assert_sprintf "%.1a", 62.0.next_float, "0x1.fp+5"
- assert_sprintf "%.1a", 63.0.prev_float, "0x1.fp+5"
- assert_sprintf "%.1a", 63.0, "0x2.0p+5"
- assert_sprintf "%.1a", 63.0.next_float, "0x2.0p+5"
- assert_sprintf "%.1a", 64.0.prev_float, "0x2.0p+5"
- assert_sprintf "%.1a", 64.0, "0x1.0p+6"
-
- assert_sprintf "%.4a", 65536.0, "0x1.0000p+16"
- assert_sprintf "%.4a", 65536.0.next_float, "0x1.0000p+16"
- assert_sprintf "%.4a", 65536.5.prev_float, "0x1.0000p+16"
- assert_sprintf "%.4a", 65536.5, "0x1.0000p+16"
- assert_sprintf "%.4a", 65536.5.next_float, "0x1.0001p+16"
- assert_sprintf "%.4a", 65537.0.prev_float, "0x1.0001p+16"
- assert_sprintf "%.4a", 65537.0, "0x1.0001p+16"
- assert_sprintf "%.4a", 65537.0.next_float, "0x1.0001p+16"
- assert_sprintf "%.4a", 65537.5.prev_float, "0x1.0001p+16"
- assert_sprintf "%.4a", 65537.5, "0x1.0002p+16"
- assert_sprintf "%.4a", 65537.5.next_float, "0x1.0002p+16"
- assert_sprintf "%.4a", 65538.0.prev_float, "0x1.0002p+16"
- assert_sprintf "%.4a", 65538.0, "0x1.0002p+16"
-
- assert_sprintf "%.4a", 131070.0, "0x1.fffep+16"
- assert_sprintf "%.4a", 131070.0.next_float, "0x1.fffep+16"
- assert_sprintf "%.4a", 131070.5.prev_float, "0x1.fffep+16"
- assert_sprintf "%.4a", 131070.5, "0x1.fffep+16"
- assert_sprintf "%.4a", 131070.5.next_float, "0x1.ffffp+16"
- assert_sprintf "%.4a", 131071.0.prev_float, "0x1.ffffp+16"
- assert_sprintf "%.4a", 131071.0, "0x1.ffffp+16"
- assert_sprintf "%.4a", 131071.0.next_float, "0x1.ffffp+16"
- assert_sprintf "%.4a", 131071.5.prev_float, "0x1.ffffp+16"
- assert_sprintf "%.4a", 131071.5, "0x2.0000p+16"
- assert_sprintf "%.4a", 131071.5.next_float, "0x2.0000p+16"
- assert_sprintf "%.4a", 131072.0.prev_float, "0x2.0000p+16"
- assert_sprintf "%.4a", 131072.0, "0x1.0000p+17"
-
- assert_sprintf "%.12a", Float64::MIN_SUBNORMAL * 0x01, "0x0.000000000000p-1022"
- assert_sprintf "%.12a", Float64::MIN_SUBNORMAL * 0x07, "0x0.000000000000p-1022"
- assert_sprintf "%.12a", Float64::MIN_SUBNORMAL * 0x08, "0x0.000000000000p-1022"
- assert_sprintf "%.12a", Float64::MIN_SUBNORMAL * 0x09, "0x0.000000000001p-1022"
- assert_sprintf "%.12a", Float64::MIN_SUBNORMAL * 0x0f, "0x0.000000000001p-1022"
- assert_sprintf "%.12a", Float64::MIN_SUBNORMAL * 0x10, "0x0.000000000001p-1022"
- assert_sprintf "%.12a", Float64::MIN_SUBNORMAL * 0x11, "0x0.000000000001p-1022"
- assert_sprintf "%.12a", Float64::MIN_SUBNORMAL * 0x17, "0x0.000000000001p-1022"
- assert_sprintf "%.12a", Float64::MIN_SUBNORMAL * 0x18, "0x0.000000000002p-1022"
- assert_sprintf "%.12a", Float64::MIN_SUBNORMAL * 0x19, "0x0.000000000002p-1022"
- assert_sprintf "%.12a", Float64::MIN_SUBNORMAL * 0x1f, "0x0.000000000002p-1022"
- assert_sprintf "%.12a", Float64::MIN_SUBNORMAL * 0x20, "0x0.000000000002p-1022"
-
- assert_sprintf "%.17a", Float64::MAX, "0x1.fffffffffffff0000p+1023"
- assert_sprintf "%.16a", Float64::MAX, "0x1.fffffffffffff000p+1023"
- assert_sprintf "%.15a", Float64::MAX, "0x1.fffffffffffff00p+1023"
- assert_sprintf "%.14a", Float64::MAX, "0x1.fffffffffffff0p+1023"
- assert_sprintf "%.13a", Float64::MAX, "0x1.fffffffffffffp+1023"
- assert_sprintf "%.12a", Float64::MAX, "0x2.000000000000p+1023"
- assert_sprintf "%.11a", Float64::MAX, "0x2.00000000000p+1023"
- assert_sprintf "%.10a", Float64::MAX, "0x2.0000000000p+1023"
- assert_sprintf "%.9a", Float64::MAX, "0x2.000000000p+1023"
- assert_sprintf "%.8a", Float64::MAX, "0x2.00000000p+1023"
- assert_sprintf "%.7a", Float64::MAX, "0x2.0000000p+1023"
- assert_sprintf "%.6a", Float64::MAX, "0x2.000000p+1023"
- assert_sprintf "%.5a", Float64::MAX, "0x2.00000p+1023"
- assert_sprintf "%.4a", Float64::MAX, "0x2.0000p+1023"
- assert_sprintf "%.3a", Float64::MAX, "0x2.000p+1023"
- assert_sprintf "%.2a", Float64::MAX, "0x2.00p+1023"
- assert_sprintf "%.1a", Float64::MAX, "0x2.0p+1023"
- assert_sprintf "%.0a", Float64::MAX, "0x2p+1023"
-
- assert_sprintf "%.1000a", 1194684.0, "0x1.23abc#{"0" * 995}p+20"
+ context "space flag" do
+ it "writes a space for positive values" do
+ assert_sprintf "% g", 123.45, " 123.45"
+ assert_sprintf "% g", -123.45, "-123.45"
+ assert_sprintf "% g", 0.0, " 0"
+ end
+
+ it "writes space before left space-padding" do
+ assert_sprintf "% 10g", 123.45, " 123.45"
+ assert_sprintf "% 10g", -123.45, " -123.45"
+ assert_sprintf "% 10g", 0.0, " 0"
+
+ assert_sprintf "% 010g", 123.45, " 000123.45"
+ assert_sprintf "% 010g", -123.45, "-000123.45"
+ assert_sprintf "% 010g", 0.0, " 000000000"
+ end
+
+ it "is ignored if plus flag is also specified" do
+ assert_sprintf "% +g", 123.45, "+123.45"
+ assert_sprintf "%+ g", -123.45, "-123.45"
+ end
end
- it "can be used with width" do
- assert_sprintf "%20.8a", 1194684.0, " 0x1.23abc000p+20"
- assert_sprintf "%20.8a", -1194684.0, " -0x1.23abc000p+20"
- assert_sprintf "%20.8a", 0.0, " 0x0.00000000p+0"
-
- assert_sprintf "%-20.8a", 1194684.0, "0x1.23abc000p+20 "
- assert_sprintf "%-20.8a", -1194684.0, "-0x1.23abc000p+20 "
- assert_sprintf "%-20.8a", 0.0, "0x0.00000000p+0 "
-
- assert_sprintf "%4.8a", 1194684.0, "0x1.23abc000p+20"
- assert_sprintf "%4.8a", -1194684.0, "-0x1.23abc000p+20"
- assert_sprintf "%4.8a", 0.0, "0x0.00000000p+0"
+ context "zero flag" do
+ it "left-pads the result with zeros" do
+ assert_sprintf "%010g", 123.45, "0000123.45"
+ assert_sprintf "%010g", -123.45, "-000123.45"
+ assert_sprintf "%010g", 0.0, "0000000000"
+ end
+
+ it "is ignored if string is left-justified" do
+ assert_sprintf "%-010g", 123.45, "123.45 "
+ assert_sprintf "%-010g", -123.45, "-123.45 "
+ assert_sprintf "%-010g", 0.0, "0 "
+ end
+
+ it "can be used with precision" do
+ assert_sprintf "%010.2g", 123.45, "00001.2e+2"
+ assert_sprintf "%010.2g", -123.45, "-0001.2e+2"
+ assert_sprintf "%010.2g", 0.0, "0000000000"
+ end
end
- it "is ignored if precision argument is negative" do
- assert_sprintf "%.*a", [-2, 1194684.0], "0x1.23abcp+20"
- end
- end
+ context "minus flag" do
+ it "left-justifies the string" do
+ assert_sprintf "%-10g", 123.45, "123.45 "
+ assert_sprintf "%-10g", -123.45, "-123.45 "
+ assert_sprintf "%-10g", 0.0, "0 "
- context "sharp flag" do
- it "prints a decimal point even if no digits follow" do
- assert_sprintf "%#a", 1.0, "0x1.p+0"
- assert_sprintf "%#a", Float64::MIN_POSITIVE, "0x1.p-1022"
- assert_sprintf "%#a", 2.0 ** -234, "0x1.p-234"
- assert_sprintf "%#a", 2.0 ** 1021, "0x1.p+1021"
- assert_sprintf "%#a", 0.0, "0x0.p+0"
- assert_sprintf "%#a", -0.0, "-0x0.p+0"
-
- assert_sprintf "%#.0a", 1.0, "0x1.p+0"
- assert_sprintf "%#.0a", Float64::MIN_POSITIVE, "0x1.p-1022"
- assert_sprintf "%#.0a", 2.0 ** -234, "0x1.p-234"
- assert_sprintf "%#.0a", 2.0 ** 1021, "0x1.p+1021"
- assert_sprintf "%#.0a", 1194684.0, "0x1.p+20"
- assert_sprintf "%#.0a", 0.0, "0x0.p+0"
- assert_sprintf "%#.0a", -0.0, "-0x0.p+0"
+ assert_sprintf "%- 10g", 123.45, " 123.45 "
+ assert_sprintf "%- 10g", -123.45, "-123.45 "
+ assert_sprintf "%- 10g", 0.0, " 0 "
+ end
end
end
- context "plus flag" do
- it "writes a plus sign for positive values" do
- assert_sprintf "%+a", 1194684.0, "+0x1.23abcp+20"
- assert_sprintf "%+a", -1194684.0, "-0x1.23abcp+20"
- assert_sprintf "%+a", 0.0, "+0x0p+0"
+ context "hex format" do
+ it "works" do
+ assert_sprintf "%a", 1194684.0, "0x1.23abcp+20"
+ assert_sprintf "%A", 1194684.0, "0X1.23ABCP+20"
+ assert_sprintf "%a", 12345678.45, "0x1.78c29ce666666p+23"
+ assert_sprintf "%A", 12345678.45, "0X1.78C29CE666666P+23"
+
+ assert_sprintf "%a", Float64::MAX, "0x1.fffffffffffffp+1023"
+ assert_sprintf "%a", Float64::MIN_POSITIVE, "0x1p-1022"
+ assert_sprintf "%a", Float64::MIN_SUBNORMAL, "0x0.0000000000001p-1022"
+ assert_sprintf "%a", 0.0, "0x0p+0"
+ assert_sprintf "%a", -0.0, "-0x0p+0"
+ assert_sprintf "%a", -Float64::MIN_SUBNORMAL, "-0x0.0000000000001p-1022"
+ assert_sprintf "%a", -Float64::MIN_POSITIVE, "-0x1p-1022"
+ assert_sprintf "%a", Float64::MIN, "-0x1.fffffffffffffp+1023"
end
- it "writes plus sign after left space-padding" do
- assert_sprintf "%+20a", 1194684.0, " +0x1.23abcp+20"
- assert_sprintf "%+20a", -1194684.0, " -0x1.23abcp+20"
- assert_sprintf "%+20a", 0.0, " +0x0p+0"
+ context "width specifier" do
+ it "sets the minimum length of the string" do
+ assert_sprintf "%20a", hexfloat("0x1p+0"), " 0x1p+0"
+ assert_sprintf "%20a", hexfloat("0x1.2p+0"), " 0x1.2p+0"
+ assert_sprintf "%20a", hexfloat("0x1.23p+0"), " 0x1.23p+0"
+ assert_sprintf "%20a", hexfloat("0x1.234p+0"), " 0x1.234p+0"
+ assert_sprintf "%20a", hexfloat("0x1.2345p+0"), " 0x1.2345p+0"
+ assert_sprintf "%20a", hexfloat("0x1.23456p+0"), " 0x1.23456p+0"
+ assert_sprintf "%20a", hexfloat("0x1.234567p+0"), " 0x1.234567p+0"
+ assert_sprintf "%20a", hexfloat("0x1.2345678p+0"), " 0x1.2345678p+0"
+ assert_sprintf "%20a", hexfloat("0x1.23456789p+0"), " 0x1.23456789p+0"
+ assert_sprintf "%20a", hexfloat("0x1.23456789ap+0"), " 0x1.23456789ap+0"
+ assert_sprintf "%20a", hexfloat("0x1.23456789abp+0"), " 0x1.23456789abp+0"
+ assert_sprintf "%20a", hexfloat("0x1.23456789abcp+0"), " 0x1.23456789abcp+0"
+
+ assert_sprintf "%20a", hexfloat("-0x1p+0"), " -0x1p+0"
+ assert_sprintf "%20a", hexfloat("-0x1.2p+0"), " -0x1.2p+0"
+ assert_sprintf "%20a", hexfloat("-0x1.23p+0"), " -0x1.23p+0"
+ assert_sprintf "%20a", hexfloat("-0x1.234p+0"), " -0x1.234p+0"
+ assert_sprintf "%20a", hexfloat("-0x1.2345p+0"), " -0x1.2345p+0"
+ assert_sprintf "%20a", hexfloat("-0x1.23456p+0"), " -0x1.23456p+0"
+ assert_sprintf "%20a", hexfloat("-0x1.234567p+0"), " -0x1.234567p+0"
+ assert_sprintf "%20a", hexfloat("-0x1.2345678p+0"), " -0x1.2345678p+0"
+ assert_sprintf "%20a", hexfloat("-0x1.23456789p+0"), " -0x1.23456789p+0"
+ assert_sprintf "%20a", hexfloat("-0x1.23456789ap+0"), " -0x1.23456789ap+0"
+ assert_sprintf "%20a", hexfloat("-0x1.23456789abp+0"), " -0x1.23456789abp+0"
+ assert_sprintf "%20a", hexfloat("-0x1.23456789abcp+0"), " -0x1.23456789abcp+0"
+
+ assert_sprintf "%+20a", 1194684.0, " +0x1.23abcp+20"
+
+ assert_sprintf "%14a", 1194684.0, " 0x1.23abcp+20"
+ assert_sprintf "%14a", -1194684.0, "-0x1.23abcp+20"
+ assert_sprintf "%+14a", 1194684.0, "+0x1.23abcp+20"
+
+ assert_sprintf "%13a", 1194684.0, "0x1.23abcp+20"
+ assert_sprintf "%13a", -1194684.0, "-0x1.23abcp+20"
+ assert_sprintf "%+13a", 1194684.0, "+0x1.23abcp+20"
+
+ assert_sprintf "%2a", 1194684.0, "0x1.23abcp+20"
+ assert_sprintf "%2a", -1194684.0, "-0x1.23abcp+20"
+ assert_sprintf "%+2a", 1194684.0, "+0x1.23abcp+20"
+ end
+
+ it "left-justifies on negative width" do
+ assert_sprintf "%*a", [-20, 1194684.0], "0x1.23abcp+20 "
+ end
end
- it "writes plus sign before left zero-padding" do
- assert_sprintf "%+020a", 1194684.0, "+0x0000001.23abcp+20"
- assert_sprintf "%+020a", -1194684.0, "-0x0000001.23abcp+20"
- assert_sprintf "%+020a", 0.0, "+0x00000000000000p+0"
+ context "precision specifier" do
+ it "sets the minimum length of the fractional part" do
+ assert_sprintf "%.0a", 0.0, "0x0p+0"
+
+ assert_sprintf "%.0a", (Float64::MIN_POSITIVE / 2).prev_float, "0x0p-1022"
+ assert_sprintf "%.0a", Float64::MIN_POSITIVE / 2, "0x0p-1022"
+ assert_sprintf "%.0a", (Float64::MIN_POSITIVE / 2).next_float, "0x1p-1022"
+ assert_sprintf "%.0a", Float64::MIN_POSITIVE.prev_float, "0x1p-1022"
+ assert_sprintf "%.0a", Float64::MIN_POSITIVE, "0x1p-1022"
+
+ assert_sprintf "%.0a", 0.0625, "0x1p-4"
+ assert_sprintf "%.0a", 0.0625.next_float, "0x1p-4"
+ assert_sprintf "%.0a", 0.09375.prev_float, "0x1p-4"
+ assert_sprintf "%.0a", 0.09375, "0x2p-4"
+ assert_sprintf "%.0a", 0.09375.next_float, "0x2p-4"
+ assert_sprintf "%.0a", 0.125.prev_float, "0x2p-4"
+ assert_sprintf "%.0a", 0.125, "0x1p-3"
+
+ assert_sprintf "%.1a", 2.0, "0x1.0p+1"
+ assert_sprintf "%.1a", 2.0.next_float, "0x1.0p+1"
+ assert_sprintf "%.1a", 2.0625.prev_float, "0x1.0p+1"
+ assert_sprintf "%.1a", 2.0625, "0x1.0p+1"
+ assert_sprintf "%.1a", 2.0625.next_float, "0x1.1p+1"
+ assert_sprintf "%.1a", 2.125.prev_float, "0x1.1p+1"
+ assert_sprintf "%.1a", 2.125, "0x1.1p+1"
+ assert_sprintf "%.1a", 2.125.next_float, "0x1.1p+1"
+ assert_sprintf "%.1a", 2.1875.prev_float, "0x1.1p+1"
+ assert_sprintf "%.1a", 2.1875, "0x1.2p+1"
+ assert_sprintf "%.1a", 2.1875.next_float, "0x1.2p+1"
+ assert_sprintf "%.1a", 2.25.prev_float, "0x1.2p+1"
+ assert_sprintf "%.1a", 2.25, "0x1.2p+1"
+
+ assert_sprintf "%.1a", 60.0, "0x1.ep+5"
+ assert_sprintf "%.1a", 60.0.next_float, "0x1.ep+5"
+ assert_sprintf "%.1a", 61.0.prev_float, "0x1.ep+5"
+ assert_sprintf "%.1a", 61.0, "0x1.ep+5"
+ assert_sprintf "%.1a", 61.0.next_float, "0x1.fp+5"
+ assert_sprintf "%.1a", 62.0.prev_float, "0x1.fp+5"
+ assert_sprintf "%.1a", 62.0, "0x1.fp+5"
+ assert_sprintf "%.1a", 62.0.next_float, "0x1.fp+5"
+ assert_sprintf "%.1a", 63.0.prev_float, "0x1.fp+5"
+ assert_sprintf "%.1a", 63.0, "0x2.0p+5"
+ assert_sprintf "%.1a", 63.0.next_float, "0x2.0p+5"
+ assert_sprintf "%.1a", 64.0.prev_float, "0x2.0p+5"
+ assert_sprintf "%.1a", 64.0, "0x1.0p+6"
+
+ assert_sprintf "%.4a", 65536.0, "0x1.0000p+16"
+ assert_sprintf "%.4a", 65536.0.next_float, "0x1.0000p+16"
+ assert_sprintf "%.4a", 65536.5.prev_float, "0x1.0000p+16"
+ assert_sprintf "%.4a", 65536.5, "0x1.0000p+16"
+ assert_sprintf "%.4a", 65536.5.next_float, "0x1.0001p+16"
+ assert_sprintf "%.4a", 65537.0.prev_float, "0x1.0001p+16"
+ assert_sprintf "%.4a", 65537.0, "0x1.0001p+16"
+ assert_sprintf "%.4a", 65537.0.next_float, "0x1.0001p+16"
+ assert_sprintf "%.4a", 65537.5.prev_float, "0x1.0001p+16"
+ assert_sprintf "%.4a", 65537.5, "0x1.0002p+16"
+ assert_sprintf "%.4a", 65537.5.next_float, "0x1.0002p+16"
+ assert_sprintf "%.4a", 65538.0.prev_float, "0x1.0002p+16"
+ assert_sprintf "%.4a", 65538.0, "0x1.0002p+16"
+
+ assert_sprintf "%.4a", 131070.0, "0x1.fffep+16"
+ assert_sprintf "%.4a", 131070.0.next_float, "0x1.fffep+16"
+ assert_sprintf "%.4a", 131070.5.prev_float, "0x1.fffep+16"
+ assert_sprintf "%.4a", 131070.5, "0x1.fffep+16"
+ assert_sprintf "%.4a", 131070.5.next_float, "0x1.ffffp+16"
+ assert_sprintf "%.4a", 131071.0.prev_float, "0x1.ffffp+16"
+ assert_sprintf "%.4a", 131071.0, "0x1.ffffp+16"
+ assert_sprintf "%.4a", 131071.0.next_float, "0x1.ffffp+16"
+ assert_sprintf "%.4a", 131071.5.prev_float, "0x1.ffffp+16"
+ assert_sprintf "%.4a", 131071.5, "0x2.0000p+16"
+ assert_sprintf "%.4a", 131071.5.next_float, "0x2.0000p+16"
+ assert_sprintf "%.4a", 131072.0.prev_float, "0x2.0000p+16"
+ assert_sprintf "%.4a", 131072.0, "0x1.0000p+17"
+
+ assert_sprintf "%.12a", Float64::MIN_SUBNORMAL * 0x01, "0x0.000000000000p-1022"
+ assert_sprintf "%.12a", Float64::MIN_SUBNORMAL * 0x07, "0x0.000000000000p-1022"
+ assert_sprintf "%.12a", Float64::MIN_SUBNORMAL * 0x08, "0x0.000000000000p-1022"
+ assert_sprintf "%.12a", Float64::MIN_SUBNORMAL * 0x09, "0x0.000000000001p-1022"
+ assert_sprintf "%.12a", Float64::MIN_SUBNORMAL * 0x0f, "0x0.000000000001p-1022"
+ assert_sprintf "%.12a", Float64::MIN_SUBNORMAL * 0x10, "0x0.000000000001p-1022"
+ assert_sprintf "%.12a", Float64::MIN_SUBNORMAL * 0x11, "0x0.000000000001p-1022"
+ assert_sprintf "%.12a", Float64::MIN_SUBNORMAL * 0x17, "0x0.000000000001p-1022"
+ assert_sprintf "%.12a", Float64::MIN_SUBNORMAL * 0x18, "0x0.000000000002p-1022"
+ assert_sprintf "%.12a", Float64::MIN_SUBNORMAL * 0x19, "0x0.000000000002p-1022"
+ assert_sprintf "%.12a", Float64::MIN_SUBNORMAL * 0x1f, "0x0.000000000002p-1022"
+ assert_sprintf "%.12a", Float64::MIN_SUBNORMAL * 0x20, "0x0.000000000002p-1022"
+
+ assert_sprintf "%.17a", Float64::MAX, "0x1.fffffffffffff0000p+1023"
+ assert_sprintf "%.16a", Float64::MAX, "0x1.fffffffffffff000p+1023"
+ assert_sprintf "%.15a", Float64::MAX, "0x1.fffffffffffff00p+1023"
+ assert_sprintf "%.14a", Float64::MAX, "0x1.fffffffffffff0p+1023"
+ assert_sprintf "%.13a", Float64::MAX, "0x1.fffffffffffffp+1023"
+ assert_sprintf "%.12a", Float64::MAX, "0x2.000000000000p+1023"
+ assert_sprintf "%.11a", Float64::MAX, "0x2.00000000000p+1023"
+ assert_sprintf "%.10a", Float64::MAX, "0x2.0000000000p+1023"
+ assert_sprintf "%.9a", Float64::MAX, "0x2.000000000p+1023"
+ assert_sprintf "%.8a", Float64::MAX, "0x2.00000000p+1023"
+ assert_sprintf "%.7a", Float64::MAX, "0x2.0000000p+1023"
+ assert_sprintf "%.6a", Float64::MAX, "0x2.000000p+1023"
+ assert_sprintf "%.5a", Float64::MAX, "0x2.00000p+1023"
+ assert_sprintf "%.4a", Float64::MAX, "0x2.0000p+1023"
+ assert_sprintf "%.3a", Float64::MAX, "0x2.000p+1023"
+ assert_sprintf "%.2a", Float64::MAX, "0x2.00p+1023"
+ assert_sprintf "%.1a", Float64::MAX, "0x2.0p+1023"
+ assert_sprintf "%.0a", Float64::MAX, "0x2p+1023"
+
+ assert_sprintf "%.1000a", 1194684.0, "0x1.23abc#{"0" * 995}p+20"
+ end
+
+ it "can be used with width" do
+ assert_sprintf "%20.8a", 1194684.0, " 0x1.23abc000p+20"
+ assert_sprintf "%20.8a", -1194684.0, " -0x1.23abc000p+20"
+ assert_sprintf "%20.8a", 0.0, " 0x0.00000000p+0"
+
+ assert_sprintf "%-20.8a", 1194684.0, "0x1.23abc000p+20 "
+ assert_sprintf "%-20.8a", -1194684.0, "-0x1.23abc000p+20 "
+ assert_sprintf "%-20.8a", 0.0, "0x0.00000000p+0 "
+
+ assert_sprintf "%4.8a", 1194684.0, "0x1.23abc000p+20"
+ assert_sprintf "%4.8a", -1194684.0, "-0x1.23abc000p+20"
+ assert_sprintf "%4.8a", 0.0, "0x0.00000000p+0"
+ end
+
+ it "is ignored if precision argument is negative" do
+ assert_sprintf "%.*a", [-2, 1194684.0], "0x1.23abcp+20"
+ end
end
- end
- context "space flag" do
- it "writes a space for positive values" do
- assert_sprintf "% a", 1194684.0, " 0x1.23abcp+20"
- assert_sprintf "% a", -1194684.0, "-0x1.23abcp+20"
- assert_sprintf "% a", 0.0, " 0x0p+0"
+ context "sharp flag" do
+ it "prints a decimal point even if no digits follow" do
+ assert_sprintf "%#a", 1.0, "0x1.p+0"
+ assert_sprintf "%#a", Float64::MIN_POSITIVE, "0x1.p-1022"
+ assert_sprintf "%#a", 2.0 ** -234, "0x1.p-234"
+ assert_sprintf "%#a", 2.0 ** 1021, "0x1.p+1021"
+ assert_sprintf "%#a", 0.0, "0x0.p+0"
+ assert_sprintf "%#a", -0.0, "-0x0.p+0"
+
+ assert_sprintf "%#.0a", 1.0, "0x1.p+0"
+ assert_sprintf "%#.0a", Float64::MIN_POSITIVE, "0x1.p-1022"
+ assert_sprintf "%#.0a", 2.0 ** -234, "0x1.p-234"
+ assert_sprintf "%#.0a", 2.0 ** 1021, "0x1.p+1021"
+ assert_sprintf "%#.0a", 1194684.0, "0x1.p+20"
+ assert_sprintf "%#.0a", 0.0, "0x0.p+0"
+ assert_sprintf "%#.0a", -0.0, "-0x0.p+0"
+ end
end
- it "writes space before left space-padding" do
- assert_sprintf "% 20a", 1194684.0, " 0x1.23abcp+20"
- assert_sprintf "% 20a", -1194684.0, " -0x1.23abcp+20"
- assert_sprintf "% 20a", 0.0, " 0x0p+0"
-
- assert_sprintf "% 020a", 1194684.0, " 0x0000001.23abcp+20"
- assert_sprintf "% 020a", -1194684.0, "-0x0000001.23abcp+20"
- assert_sprintf "% 020a", 0.0, " 0x00000000000000p+0"
+ context "plus flag" do
+ it "writes a plus sign for positive values" do
+ assert_sprintf "%+a", 1194684.0, "+0x1.23abcp+20"
+ assert_sprintf "%+a", -1194684.0, "-0x1.23abcp+20"
+ assert_sprintf "%+a", 0.0, "+0x0p+0"
+ end
+
+ it "writes plus sign after left space-padding" do
+ assert_sprintf "%+20a", 1194684.0, " +0x1.23abcp+20"
+ assert_sprintf "%+20a", -1194684.0, " -0x1.23abcp+20"
+ assert_sprintf "%+20a", 0.0, " +0x0p+0"
+ end
+
+ it "writes plus sign before left zero-padding" do
+ assert_sprintf "%+020a", 1194684.0, "+0x0000001.23abcp+20"
+ assert_sprintf "%+020a", -1194684.0, "-0x0000001.23abcp+20"
+ assert_sprintf "%+020a", 0.0, "+0x00000000000000p+0"
+ end
end
- it "is ignored if plus flag is also specified" do
- assert_sprintf "% +a", 1194684.0, "+0x1.23abcp+20"
- assert_sprintf "%+ a", -1194684.0, "-0x1.23abcp+20"
- end
- end
-
- context "zero flag" do
- it "left-pads the result with zeros" do
- assert_sprintf "%020a", 1194684.0, "0x00000001.23abcp+20"
- assert_sprintf "%020a", -1194684.0, "-0x0000001.23abcp+20"
- assert_sprintf "%020a", 0.0, "0x000000000000000p+0"
+ context "space flag" do
+ it "writes a space for positive values" do
+ assert_sprintf "% a", 1194684.0, " 0x1.23abcp+20"
+ assert_sprintf "% a", -1194684.0, "-0x1.23abcp+20"
+ assert_sprintf "% a", 0.0, " 0x0p+0"
+ end
+
+ it "writes space before left space-padding" do
+ assert_sprintf "% 20a", 1194684.0, " 0x1.23abcp+20"
+ assert_sprintf "% 20a", -1194684.0, " -0x1.23abcp+20"
+ assert_sprintf "% 20a", 0.0, " 0x0p+0"
+
+ assert_sprintf "% 020a", 1194684.0, " 0x0000001.23abcp+20"
+ assert_sprintf "% 020a", -1194684.0, "-0x0000001.23abcp+20"
+ assert_sprintf "% 020a", 0.0, " 0x00000000000000p+0"
+ end
+
+ it "is ignored if plus flag is also specified" do
+ assert_sprintf "% +a", 1194684.0, "+0x1.23abcp+20"
+ assert_sprintf "%+ a", -1194684.0, "-0x1.23abcp+20"
+ end
end
- it "is ignored if string is left-justified" do
- assert_sprintf "%-020a", 1194684.0, "0x1.23abcp+20 "
- assert_sprintf "%-020a", -1194684.0, "-0x1.23abcp+20 "
- assert_sprintf "%-020a", 0.0, "0x0p+0 "
+ context "zero flag" do
+ it "left-pads the result with zeros" do
+ assert_sprintf "%020a", 1194684.0, "0x00000001.23abcp+20"
+ assert_sprintf "%020a", -1194684.0, "-0x0000001.23abcp+20"
+ assert_sprintf "%020a", 0.0, "0x000000000000000p+0"
+ end
+
+ it "is ignored if string is left-justified" do
+ assert_sprintf "%-020a", 1194684.0, "0x1.23abcp+20 "
+ assert_sprintf "%-020a", -1194684.0, "-0x1.23abcp+20 "
+ assert_sprintf "%-020a", 0.0, "0x0p+0 "
+ end
+
+ it "can be used with precision" do
+ assert_sprintf "%020.8a", 1194684.0, "0x00001.23abc000p+20"
+ assert_sprintf "%020.8a", -1194684.0, "-0x0001.23abc000p+20"
+ assert_sprintf "%020.8a", 0.0, "0x000000.00000000p+0"
+ end
end
- it "can be used with precision" do
- assert_sprintf "%020.8a", 1194684.0, "0x00001.23abc000p+20"
- assert_sprintf "%020.8a", -1194684.0, "-0x0001.23abc000p+20"
- assert_sprintf "%020.8a", 0.0, "0x000000.00000000p+0"
+ context "minus flag" do
+ it "left-justifies the string" do
+ assert_sprintf "%-20a", 1194684.0, "0x1.23abcp+20 "
+ assert_sprintf "%-20a", -1194684.0, "-0x1.23abcp+20 "
+ assert_sprintf "%-20a", 0.0, "0x0p+0 "
+ end
end
end
- context "minus flag" do
- it "left-justifies the string" do
- assert_sprintf "%-20a", 1194684.0, "0x1.23abcp+20 "
- assert_sprintf "%-20a", -1194684.0, "-0x1.23abcp+20 "
- assert_sprintf "%-20a", 0.0, "0x0p+0 "
+ [Float32, Float64].each do |float|
+ it "infinities" do
+ pos_inf = float.new(1) / float.new(0)
+ neg_inf = float.new(-1) / float.new(0)
+
+ assert_sprintf "%f", pos_inf, "inf"
+ assert_sprintf "%a", pos_inf, "inf"
+ assert_sprintf "%e", pos_inf, "inf"
+ assert_sprintf "%g", pos_inf, "inf"
+ assert_sprintf "%A", pos_inf, "INF"
+ assert_sprintf "%E", pos_inf, "INF"
+ assert_sprintf "%G", pos_inf, "INF"
+
+ assert_sprintf "%f", neg_inf, "-inf"
+ assert_sprintf "%G", neg_inf, "-INF"
+
+ assert_sprintf "%2f", pos_inf, "inf"
+ assert_sprintf "%4f", pos_inf, " inf"
+ assert_sprintf "%6f", pos_inf, " inf"
+ assert_sprintf "%2f", neg_inf, "-inf"
+ assert_sprintf "%4f", neg_inf, "-inf"
+ assert_sprintf "%6f", neg_inf, " -inf"
+
+ assert_sprintf "% f", pos_inf, " inf"
+ assert_sprintf "% 2f", pos_inf, " inf"
+ assert_sprintf "% 4f", pos_inf, " inf"
+ assert_sprintf "% 6f", pos_inf, " inf"
+ assert_sprintf "% f", neg_inf, "-inf"
+ assert_sprintf "% 2f", neg_inf, "-inf"
+ assert_sprintf "% 4f", neg_inf, "-inf"
+ assert_sprintf "% 6f", neg_inf, " -inf"
+
+ assert_sprintf "%+f", pos_inf, "+inf"
+ assert_sprintf "%+2f", pos_inf, "+inf"
+ assert_sprintf "%+4f", pos_inf, "+inf"
+ assert_sprintf "%+6f", pos_inf, " +inf"
+ assert_sprintf "%+f", neg_inf, "-inf"
+ assert_sprintf "%+2f", neg_inf, "-inf"
+ assert_sprintf "%+4f", neg_inf, "-inf"
+ assert_sprintf "%+6f", neg_inf, " -inf"
+
+ assert_sprintf "%+ f", pos_inf, "+inf"
+
+ assert_sprintf "%-4f", pos_inf, "inf "
+ assert_sprintf "%-6f", pos_inf, "inf "
+ assert_sprintf "%-4f", neg_inf, "-inf"
+ assert_sprintf "%-6f", neg_inf, "-inf "
+
+ assert_sprintf "% -4f", pos_inf, " inf"
+ assert_sprintf "% -6f", pos_inf, " inf "
+ assert_sprintf "% -4f", neg_inf, "-inf"
+ assert_sprintf "% -6f", neg_inf, "-inf "
+
+ assert_sprintf "%-+4f", pos_inf, "+inf"
+ assert_sprintf "%-+6f", pos_inf, "+inf "
+ assert_sprintf "%-+4f", neg_inf, "-inf"
+ assert_sprintf "%-+6f", neg_inf, "-inf "
+
+ assert_sprintf "%-+ 6f", pos_inf, "+inf "
+
+ assert_sprintf "%06f", pos_inf, " inf"
+ assert_sprintf "%-06f", pos_inf, "inf "
+ assert_sprintf "%06f", neg_inf, " -inf"
+ assert_sprintf "%-06f", neg_inf, "-inf "
+
+ assert_sprintf "%.1f", pos_inf, "inf"
+
+ assert_sprintf "%#f", pos_inf, "inf"
end
- end
- end
- [Float32, Float64].each do |float|
- it "infinities" do
- pos_inf = float.new(1) / float.new(0)
- neg_inf = float.new(-1) / float.new(0)
-
- assert_sprintf "%f", pos_inf, "inf"
- assert_sprintf "%a", pos_inf, "inf"
- assert_sprintf "%e", pos_inf, "inf"
- assert_sprintf "%g", pos_inf, "inf"
- assert_sprintf "%A", pos_inf, "INF"
- assert_sprintf "%E", pos_inf, "INF"
- assert_sprintf "%G", pos_inf, "INF"
-
- assert_sprintf "%f", neg_inf, "-inf"
- assert_sprintf "%G", neg_inf, "-INF"
-
- assert_sprintf "%2f", pos_inf, "inf"
- assert_sprintf "%4f", pos_inf, " inf"
- assert_sprintf "%6f", pos_inf, " inf"
- assert_sprintf "%2f", neg_inf, "-inf"
- assert_sprintf "%4f", neg_inf, "-inf"
- assert_sprintf "%6f", neg_inf, " -inf"
-
- assert_sprintf "% f", pos_inf, " inf"
- assert_sprintf "% 2f", pos_inf, " inf"
- assert_sprintf "% 4f", pos_inf, " inf"
- assert_sprintf "% 6f", pos_inf, " inf"
- assert_sprintf "% f", neg_inf, "-inf"
- assert_sprintf "% 2f", neg_inf, "-inf"
- assert_sprintf "% 4f", neg_inf, "-inf"
- assert_sprintf "% 6f", neg_inf, " -inf"
-
- assert_sprintf "%+f", pos_inf, "+inf"
- assert_sprintf "%+2f", pos_inf, "+inf"
- assert_sprintf "%+4f", pos_inf, "+inf"
- assert_sprintf "%+6f", pos_inf, " +inf"
- assert_sprintf "%+f", neg_inf, "-inf"
- assert_sprintf "%+2f", neg_inf, "-inf"
- assert_sprintf "%+4f", neg_inf, "-inf"
- assert_sprintf "%+6f", neg_inf, " -inf"
-
- assert_sprintf "%+ f", pos_inf, "+inf"
-
- assert_sprintf "%-4f", pos_inf, "inf "
- assert_sprintf "%-6f", pos_inf, "inf "
- assert_sprintf "%-4f", neg_inf, "-inf"
- assert_sprintf "%-6f", neg_inf, "-inf "
-
- assert_sprintf "% -4f", pos_inf, " inf"
- assert_sprintf "% -6f", pos_inf, " inf "
- assert_sprintf "% -4f", neg_inf, "-inf"
- assert_sprintf "% -6f", neg_inf, "-inf "
-
- assert_sprintf "%-+4f", pos_inf, "+inf"
- assert_sprintf "%-+6f", pos_inf, "+inf "
- assert_sprintf "%-+4f", neg_inf, "-inf"
- assert_sprintf "%-+6f", neg_inf, "-inf "
-
- assert_sprintf "%-+ 6f", pos_inf, "+inf "
-
- assert_sprintf "%06f", pos_inf, " inf"
- assert_sprintf "%-06f", pos_inf, "inf "
- assert_sprintf "%06f", neg_inf, " -inf"
- assert_sprintf "%-06f", neg_inf, "-inf "
-
- assert_sprintf "%.1f", pos_inf, "inf"
-
- assert_sprintf "%#f", pos_inf, "inf"
- end
-
- it "not-a-numbers" do
- pos_nan = Math.copysign(float.new(0) / float.new(0), 1)
- neg_nan = Math.copysign(float.new(0) / float.new(0), -1)
-
- assert_sprintf "%f", pos_nan, "nan"
- assert_sprintf "%a", pos_nan, "nan"
- assert_sprintf "%e", pos_nan, "nan"
- assert_sprintf "%g", pos_nan, "nan"
- assert_sprintf "%A", pos_nan, "NAN"
- assert_sprintf "%E", pos_nan, "NAN"
- assert_sprintf "%G", pos_nan, "NAN"
-
- assert_sprintf "%f", neg_nan, "nan"
- assert_sprintf "%a", neg_nan, "nan"
- assert_sprintf "%e", neg_nan, "nan"
- assert_sprintf "%g", neg_nan, "nan"
- assert_sprintf "%A", neg_nan, "NAN"
- assert_sprintf "%E", neg_nan, "NAN"
- assert_sprintf "%G", neg_nan, "NAN"
-
- assert_sprintf "%+f", pos_nan, "+nan"
- assert_sprintf "%+f", neg_nan, "+nan"
+ it "not-a-numbers" do
+ pos_nan = Math.copysign(float.new(0) / float.new(0), 1)
+ neg_nan = Math.copysign(float.new(0) / float.new(0), -1)
+
+ assert_sprintf "%f", pos_nan, "nan"
+ assert_sprintf "%a", pos_nan, "nan"
+ assert_sprintf "%e", pos_nan, "nan"
+ assert_sprintf "%g", pos_nan, "nan"
+ assert_sprintf "%A", pos_nan, "NAN"
+ assert_sprintf "%E", pos_nan, "NAN"
+ assert_sprintf "%G", pos_nan, "NAN"
+
+ assert_sprintf "%f", neg_nan, "nan"
+ assert_sprintf "%a", neg_nan, "nan"
+ assert_sprintf "%e", neg_nan, "nan"
+ assert_sprintf "%g", neg_nan, "nan"
+ assert_sprintf "%A", neg_nan, "NAN"
+ assert_sprintf "%E", neg_nan, "NAN"
+ assert_sprintf "%G", neg_nan, "NAN"
+
+ assert_sprintf "%+f", pos_nan, "+nan"
+ assert_sprintf "%+f", neg_nan, "+nan"
+ end
end
end
+ else
+ pending "floats"
end
context "strings" do
diff --git a/spec/std/string_builder_spec.cr b/spec/std/string_builder_spec.cr
index 2b5f62c6c03c..250a4b0239f2 100644
--- a/spec/std/string_builder_spec.cr
+++ b/spec/std/string_builder_spec.cr
@@ -40,4 +40,43 @@ describe String::Builder do
str.chomp!(44).to_s.should eq("a,b,c")
end
end
+
+ it "raises EOFError" do
+ builder = String::Builder.new
+ initial_capacity = builder.capacity
+ expect_raises(IO::EOFError) do
+ builder.write Slice.new(Pointer(UInt8).null, Int32::MAX)
+ end
+ # nothing get's written
+ builder.bytesize.should eq 0
+ builder.capacity.should eq initial_capacity
+ end
+
+ # FIXME(wasm32): https://github.com/crystal-lang/crystal/issues/14057
+ {% if flag?(:wasm32) %}
+ pending "allocation for > 1 GB"
+ {% else %}
+ it "allocates for > 1 GB", tags: %w[slow] do
+ String::Builder.build do |str|
+ mbstring = "a" * 1024 * 1024
+ 1023.times { str << mbstring }
+
+ str.bytesize.should eq (1 << 30) - (1 << 20)
+ str.capacity.should eq 1 << 30
+
+ str << mbstring
+
+ str.bytesize.should eq 1 << 30
+ str.capacity.should eq Int32::MAX
+
+ 1023.times { str << mbstring }
+
+ str.write mbstring.to_slice[0..(-4 - String::HEADER_SIZE)]
+ str << "a"
+ expect_raises(IO::EOFError) do
+ str << "a"
+ end
+ end
+ end
+ {% end %}
end
diff --git a/spec/std/string_spec.cr b/spec/std/string_spec.cr
index 0d60b3ac2466..ebebcd2c6561 100644
--- a/spec/std/string_spec.cr
+++ b/spec/std/string_spec.cr
@@ -1416,6 +1416,7 @@ describe "String" do
it { "=".split(/\=/, 2).should eq(["", ""]) }
it { "=".split(/\=/, 2, remove_empty: true).should eq([] of String) }
it { ",".split(/(?:(x)|(,))/).should eq(["", ",", ""]) }
+ it { "ba".split(/a/, options: :anchored).should eq ["ba"] }
it "keeps groups" do
s = "split on the word on okay?"
@@ -2322,6 +2323,10 @@ describe "String" do
it "does with number and string" do
"1ab4".scan(/\d+/).map(&.[0]).should eq(["1", "4"])
end
+
+ it "options parameter" do
+ "ba".scan(/a/, options: :anchored).map(&.[0]).should eq [] of String
+ end
end
it "has match" do
diff --git a/spec/std/thread_spec.cr b/spec/std/thread_spec.cr
index 599a1968f52f..136026667137 100644
--- a/spec/std/thread_spec.cr
+++ b/spec/std/thread_spec.cr
@@ -49,4 +49,17 @@ describe Thread do
thread.join
end
+
+ it "names the thread" do
+ Thread.current.name.should be_nil
+ name = nil
+
+ thread = Thread.new(name: "some-name") do
+ name = Thread.current.name
+ end
+ thread.name.should eq("some-name")
+
+ thread.join
+ name.should eq("some-name")
+ end
end
diff --git a/spec/std/time/location_spec.cr b/spec/std/time/location_spec.cr
index bcf7595cffd8..78e27a230fde 100644
--- a/spec/std/time/location_spec.cr
+++ b/spec/std/time/location_spec.cr
@@ -67,9 +67,7 @@ class Time::Location
with_zoneinfo do
Location.load("UTC").should eq Location::UTC
Location.load("").should eq Location::UTC
-
- # Etc/UTC could be pointing to anything
- Location.load("Etc/UTC").should_not eq Location::UTC
+ Location.load("Etc/UTC").should eq Location::UTC
end
end
diff --git a/spec/std/xml/reader_spec.cr b/spec/std/xml/reader_spec.cr
index 54183dd8742d..d89593620970 100644
--- a/spec/std/xml/reader_spec.cr
+++ b/spec/std/xml/reader_spec.cr
@@ -359,6 +359,11 @@ module XML
reader.value.should eq("2")
reader.read.should be_false
end
+
+ it "raises if attribute contains null byte" do
+ reader = Reader.new("")
+ expect_raises(Exception) { reader.move_to_attribute("\0") }
+ end
end
describe "#[]" do
@@ -378,6 +383,11 @@ module XML
reader.read #
reader["id"].should eq("1")
end
+
+ it "raises if attribute contains null byte" do
+ reader = Reader.new("")
+ expect_raises(Exception) { reader["\0"] }
+ end
end
describe "#[]?" do
@@ -397,6 +407,11 @@ module XML
reader.read #
reader["id"]?.should eq("1")
end
+
+ it "raises if attribute contains null byte" do
+ reader = Reader.new("")
+ expect_raises(Exception) { reader["\0"]? }
+ end
end
describe "#move_to_element" do
diff --git a/src/VERSION b/src/VERSION
index 1f724bf455d7..381cf02417c4 100644
--- a/src/VERSION
+++ b/src/VERSION
@@ -1 +1 @@
-1.11.0-dev
+1.12.0-dev
diff --git a/src/annotations.cr b/src/annotations.cr
index c906f61b9b79..929ed73533f9 100644
--- a/src/annotations.cr
+++ b/src/annotations.cr
@@ -27,7 +27,7 @@ end
annotation Flags
end
-# A `lib` can be marked with `@[Link(lib : String, *, ldflags : String, framework : String, pkg_config : String)]`
+# A `lib` can be marked with `@[Link(lib : String, *, ldflags : String, static : Bool, framework : String, pkg_config : String, wasm_import_module : String, dll : String)]`
# to declare the library that should be linked when compiling the program.
#
# At least one of the *lib*, *ldflags*, *framework* arguments needs to be specified.
@@ -45,6 +45,13 @@ end
#
# `@[Link(framework: "Cocoa")]` will pass `-framework Cocoa` to the linker.
#
+# `@[Link(dll: "gc.dll")]` will copy `gc.dll` to any built program. The DLL name
+# must use `.dll` as its file extension and cannot contain any directory
+# separators. The actual DLL is searched among `CRYSTAL_LIBRARY_PATH`, the
+# compiler's own directory, and `PATH` in that order; a warning is printed if
+# the DLL isn't found, although it might still run correctly if the DLLs are
+# available in other DLL search paths on the system.
+#
# When an `-l` option is passed to the linker, it will lookup the libraries in
# paths passed with the `-L` option. Any paths in `CRYSTAL_LIBRARY_PATH` are
# added by default. Custom paths can be passed using `ldflags`:
diff --git a/src/colorize.cr b/src/colorize.cr
index 48975c8a451f..83fd82c3935e 100644
--- a/src/colorize.cr
+++ b/src/colorize.cr
@@ -129,8 +129,7 @@ module Colorize
# "hello".colorize.red.to_s # => "hello"
# ```
#
- # NOTE: This is by default disabled on non-TTY devices because they likely don't support ANSI escape codes.
- # This will also be disabled if the environment variable `TERM` is "dumb" or `NO_COLOR` contains any value.
+ # NOTE: This is by default disabled if the environment variable `NO_COLOR` contains any value.
class_property? enabled : Bool { !ENV.has_key?("NO_COLOR") }
# Makes `Colorize.enabled` `true` if and only if both of `STDOUT.tty?`
diff --git a/src/compiler/crystal/codegen/asm.cr b/src/compiler/crystal/codegen/asm.cr
index f0b3e2f088ab..107d63f19ecf 100644
--- a/src/compiler/crystal/codegen/asm.cr
+++ b/src/compiler/crystal/codegen/asm.cr
@@ -53,7 +53,7 @@ class Crystal::CodeGenVisitor
fun_type = LLVM::Type.function(input_types, output_type)
constraints = constraints.to_s
- value = fun_type.inline_asm(node.text, constraints, node.volatile?, node.alignstack?, node.can_throw?)
+ value = fun_type.inline_asm(node.text, constraints, node.volatile?, node.alignstack?, node.can_throw?, node.dialect)
value = LLVM::Function.from_value(value)
asm_value = call LLVMTypedFunction.new(fun_type, value), input_values
diff --git a/src/compiler/crystal/codegen/ast.cr b/src/compiler/crystal/codegen/ast.cr
index 816958844dd9..ab4fa76d4e16 100644
--- a/src/compiler/crystal/codegen/ast.cr
+++ b/src/compiler/crystal/codegen/ast.cr
@@ -138,4 +138,10 @@ module Crystal
found_extern
end
end
+
+ class Asm
+ def dialect : LLVM::InlineAsmDialect
+ intel? ? LLVM::InlineAsmDialect::Intel : LLVM::InlineAsmDialect::ATT
+ end
+ end
end
diff --git a/src/compiler/crystal/codegen/codegen.cr b/src/compiler/crystal/codegen/codegen.cr
index f5c35db9d65a..441f3cfa09ae 100644
--- a/src/compiler/crystal/codegen/codegen.cr
+++ b/src/compiler/crystal/codegen/codegen.cr
@@ -69,8 +69,10 @@ module Crystal
end
end
- def codegen(node, single_module = false, debug = Debug::Default)
- visitor = CodeGenVisitor.new self, node, single_module: single_module, debug: debug
+ def codegen(node, single_module = false, debug = Debug::Default,
+ frame_pointers = FramePointers::Auto)
+ visitor = CodeGenVisitor.new self, node, single_module: single_module,
+ debug: debug, frame_pointers: frame_pointers
visitor.accept node
visitor.process_finished_hooks
visitor.finish
@@ -190,7 +192,10 @@ module Crystal
@c_malloc_fun : LLVMTypedFunction?
@c_realloc_fun : LLVMTypedFunction?
- def initialize(@program : Program, @node : ASTNode, @single_module : Bool = false, @debug = Debug::Default)
+ def initialize(@program : Program, @node : ASTNode,
+ @single_module : Bool = false,
+ @debug = Debug::Default,
+ @frame_pointers : FramePointers = :auto)
@abi = @program.target_machine.abi
@llvm_context = LLVM::Context.new
# LLVM::Context.register(@llvm_context, "main")
@@ -496,18 +501,22 @@ module Crystal
def visit(node : Nop)
@last = llvm_nil
+ false
end
def visit(node : NilLiteral)
@last = llvm_nil
+ false
end
def visit(node : BoolLiteral)
@last = int1(node.value ? 1 : 0)
+ false
end
def visit(node : CharLiteral)
@last = int32(node.value.ord)
+ false
end
def visit(node : NumberLiteral)
@@ -537,14 +546,17 @@ module Crystal
in .f64?
@last = float64(node.value)
end
+ false
end
def visit(node : StringLiteral)
@last = build_string_constant(node.value, node.value)
+ false
end
def visit(node : SymbolLiteral)
@last = int(@symbols[node.value])
+ false
end
def visit(node : TupleLiteral)
@@ -1087,7 +1099,7 @@ module Crystal
request_value(value)
- return if value.no_returns?
+ return false if value.no_returns?
last = @last
@@ -1101,7 +1113,7 @@ module Crystal
read_class_var_ptr(target)
when Var
# Can't assign void
- return if target.type.void?
+ return false if target.type.void?
# If assigning to a special variable in a method that yields,
# assign to that variable too.
@@ -1279,6 +1291,7 @@ module Crystal
else
node.raise "BUG: missing context var: #{node.name}"
end
+ false
end
def visit(node : Global)
@@ -1287,6 +1300,7 @@ module Crystal
def visit(node : ClassVar)
@last = read_class_var(node)
+ false
end
def visit(node : InstanceVar)
@@ -1398,7 +1412,7 @@ module Crystal
unless filtered_type
@last = upcast llvm_nil, resulting_type, @program.nil
- return
+ return false
end
non_nilable_type = node.non_nilable_type
@@ -1471,12 +1485,15 @@ module Crystal
def codegen_type_filter(node, &)
accept node.obj
- obj_type = node.obj.type
- type_id = type_id @last, obj_type
- filtered_type = yield(obj_type).not_nil!
+ if @needs_value
+ obj_type = node.obj.type
- @last = match_type_id obj_type, filtered_type, type_id
+ type_id = type_id @last, obj_type
+ filtered_type = yield(obj_type).not_nil!
+
+ @last = match_type_id obj_type, filtered_type, type_id
+ end
false
end
@@ -1656,6 +1673,7 @@ module Crystal
def visit(node : Unreachable)
builder.unreachable
+ false
end
def check_proc_is_not_closure(value, type)
@@ -2041,6 +2059,7 @@ module Crystal
def unreachable(file = __FILE__, line = __LINE__)
debug_codegen_log(file, line) { "Reached the unreachable!" }
builder.unreachable
+ false
end
def allocate_aggregate(type)
@@ -2234,11 +2253,11 @@ module Crystal
res
end
- def memcpy(dest, src, len, align, volatile)
+ def memcpy(dest, src, len, align, volatile, *, src_align = align)
res = call c_memcpy_fun, [dest, src, len, volatile]
LibLLVM.set_instr_param_alignment(res, 1, align)
- LibLLVM.set_instr_param_alignment(res, 2, align)
+ LibLLVM.set_instr_param_alignment(res, 2, src_align)
res
end
diff --git a/src/compiler/crystal/codegen/debug.cr b/src/compiler/crystal/codegen/debug.cr
index 58d139ef2b3c..72555d074bb0 100644
--- a/src/compiler/crystal/codegen/debug.cr
+++ b/src/compiler/crystal/codegen/debug.cr
@@ -47,14 +47,6 @@ module Crystal
"CodeView",
mod.context.int32.const_int(1)
)
- elsif @program.has_flag?("osx") || @program.has_flag?("android")
- # DebugInfo generation in LLVM by default uses a higher version of dwarf
- # than OS X currently understands. Android has the same problem.
- mod.add_flag(
- LibLLVM::ModuleFlagBehavior::Warning,
- "Dwarf Version",
- mod.context.int32.const_int(2)
- )
end
mod.add_flag(
diff --git a/src/compiler/crystal/codegen/fun.cr b/src/compiler/crystal/codegen/fun.cr
index 9a8e51df3175..784eba83b9b9 100644
--- a/src/compiler/crystal/codegen/fun.cr
+++ b/src/compiler/crystal/codegen/fun.cr
@@ -101,9 +101,13 @@ class Crystal::CodeGenVisitor
context.fun.add_attribute LLVM::Attribute::UWTable, value: @program.has_flag?("aarch64") ? LLVM::UWTableKind::Sync : LLVM::UWTableKind::Async
{% end %}
- if @program.has_flag?("darwin")
+ if @frame_pointers.always?
+ context.fun.add_attribute "frame-pointer", value: "all"
+ elsif @program.has_flag?("darwin")
# Disable frame pointer elimination in Darwin, as it causes issues during stack unwind
context.fun.add_target_dependent_attribute "frame-pointer", "all"
+ elsif @frame_pointers.non_leaf?
+ context.fun.add_attribute "frame-pointer", value: "non-leaf"
end
new_entry_block
diff --git a/src/compiler/crystal/codegen/link.cr b/src/compiler/crystal/codegen/link.cr
index 7ef2ab85f92c..d9910d64c7a8 100644
--- a/src/compiler/crystal/codegen/link.cr
+++ b/src/compiler/crystal/codegen/link.cr
@@ -5,8 +5,9 @@ module Crystal
getter ldflags : String?
getter framework : String?
getter wasm_import_module : String?
+ getter dll : String?
- def initialize(@lib = nil, @pkg_config = @lib, @ldflags = nil, @static = false, @framework = nil, @wasm_import_module = nil)
+ def initialize(@lib = nil, @pkg_config = @lib, @ldflags = nil, @static = false, @framework = nil, @wasm_import_module = nil, @dll = nil)
end
def static?
@@ -27,6 +28,7 @@ module Crystal
lib_pkg_config = nil
lib_framework = nil
lib_wasm_import_module = nil
+ lib_dll = nil
count = 0
args.each do |arg|
@@ -76,12 +78,21 @@ module Crystal
when "wasm_import_module"
named_arg.raise "'wasm_import_module' link argument must be a String" unless value.is_a?(StringLiteral)
lib_wasm_import_module = value.value
+ when "dll"
+ named_arg.raise "'dll' link argument must be a String" unless value.is_a?(StringLiteral)
+ lib_dll = value.value
+ unless lib_dll.size >= 4 && lib_dll[-4..].compare(".dll", case_insensitive: true) == 0
+ named_arg.raise "'dll' link argument must use a '.dll' file extension"
+ end
+ if ::Path.separators(::Path::Kind::WINDOWS).any? { |separator| lib_dll.includes?(separator) }
+ named_arg.raise "'dll' link argument must not include directory separators"
+ end
else
- named_arg.raise "unknown link argument: '#{named_arg.name}' (valid arguments are 'lib', 'ldflags', 'static', 'pkg_config', 'framework', and 'wasm_import_module')"
+ named_arg.raise "unknown link argument: '#{named_arg.name}' (valid arguments are 'lib', 'ldflags', 'static', 'pkg_config', 'framework', 'wasm_import_module', and 'dll')"
end
end
- new(lib_name, lib_pkg_config, lib_ldflags, lib_static, lib_framework, lib_wasm_import_module)
+ new(lib_name, lib_pkg_config, lib_ldflags, lib_static, lib_framework, lib_wasm_import_module, lib_dll)
end
end
@@ -221,6 +232,46 @@ module Crystal
flags.join(" ")
end
+ # Searches among CRYSTAL_LIBRARY_PATH, the compiler's directory, and PATH
+ # for every DLL specified in the used `@[Link]` annotations. Yields the
+ # absolute path and `true` if found, the base name and `false` if not found.
+ # The directories should match `Crystal::Repl::Context#dll_search_paths`
+ def each_dll_path(& : String, Bool ->)
+ executable_path = nil
+ compiler_origin = nil
+ paths = nil
+
+ link_annotations.each do |ann|
+ next unless dll = ann.dll
+
+ dll_path = CrystalLibraryPath.paths.each do |path|
+ full_path = File.join(path, dll)
+ break full_path if File.file?(full_path)
+ end
+
+ unless dll_path
+ executable_path ||= Process.executable_path
+ compiler_origin ||= File.dirname(executable_path) if executable_path
+
+ if compiler_origin
+ full_path = File.join(compiler_origin, dll)
+ dll_path = full_path if File.file?(full_path)
+ end
+ end
+
+ unless dll_path
+ paths ||= ENV["PATH"]?.try &.split(Process::PATH_DELIMITER, remove_empty: true)
+
+ dll_path = paths.try &.each do |path|
+ full_path = File.join(path, dll)
+ break full_path if File.file?(full_path)
+ end
+ end
+
+ yield dll_path || dll, !dll_path.nil?
+ end
+ end
+
PKG_CONFIG_PATH = Process.find_executable("pkg-config")
# Returns the result of running `pkg-config mod` but returns nil if
diff --git a/src/compiler/crystal/codegen/llvm_typer.cr b/src/compiler/crystal/codegen/llvm_typer.cr
index d20fbd59fa9a..d72a25ecd3cb 100644
--- a/src/compiler/crystal/codegen/llvm_typer.cr
+++ b/src/compiler/crystal/codegen/llvm_typer.cr
@@ -245,6 +245,10 @@ module Crystal
llvm_type(type.remove_alias, wants_size)
end
+ private def create_llvm_type(type : ReferenceStorageType, wants_size)
+ llvm_struct_type(type.reference_type, wants_size)
+ end
+
private def create_llvm_type(type : NonGenericModuleType | GenericClassType, wants_size)
# This can only be reached if the module or generic class don't have implementors
@llvm_context.int1
diff --git a/src/compiler/crystal/codegen/primitives.cr b/src/compiler/crystal/codegen/primitives.cr
index 9ed05c0009f2..80ba7d832a41 100644
--- a/src/compiler/crystal/codegen/primitives.cr
+++ b/src/compiler/crystal/codegen/primitives.cr
@@ -11,6 +11,8 @@ class Crystal::CodeGenVisitor
else
raise "BUG: unhandled primitive in codegen visit: #{node.name}"
end
+
+ false
end
def codegen_primitive(call, node, target_def, call_args)
diff --git a/src/compiler/crystal/codegen/unions.cr b/src/compiler/crystal/codegen/unions.cr
index 1f29763d504a..bcef273a8010 100644
--- a/src/compiler/crystal/codegen/unions.cr
+++ b/src/compiler/crystal/codegen/unions.cr
@@ -28,20 +28,19 @@ module Crystal
@structs[llvm_name] = a_struct
end
- max_size = 0
+ max_size = 0_u64
+ max_alignment = pointer_size.to_u32!
+
type.expand_union_types.each do |subtype|
unless subtype.void?
- size = size_of(llvm_type(subtype, wants_size: true))
- max_size = size if size > max_size
+ llvm_type = llvm_type(subtype, wants_size: true)
+ max_size = {size_of(llvm_type), max_size}.max
+ max_alignment = {align_of(llvm_type), max_alignment}.max
end
end
- max_size /= pointer_size.to_f
- max_size = max_size.ceil.to_i
-
- max_size = 1 if max_size == 0
-
- llvm_value_type = size_t.array(max_size)
+ value_size = {(max_size + (max_alignment - 1)) // max_alignment, 1_u64}.max
+ llvm_value_type = @llvm_context.int(max_alignment * 8).array(value_size)
[@llvm_context.int32, llvm_value_type]
end
@@ -109,23 +108,64 @@ module Crystal
store type_id(@program.void), union_type_id(struct_type, union_pointer)
end
- def assign_distinct_union_types(target_pointer, target_type, value_type, value)
+ # this is needed if `union_type` and `value_type` have different alignments,
+ # i.e. their `#union_value`s do not have the same offsets
+ def store_union_in_union(union_type, union_pointer, value_type, value)
+ to_llvm_type = llvm_type(union_type)
+ from_llvm_type = llvm_type(value_type)
+ to_value_type = to_llvm_type.struct_element_types[1]
+ from_value_type = from_llvm_type.struct_element_types[1]
+
+ store type_id(value, value_type), union_type_id(to_llvm_type, union_pointer)
+
+ size = {
+ @llvm_typer.size_of(from_value_type),
+ @llvm_typer.size_of(to_value_type),
+ }.min
+ size = @program.bits64? ? int64(size) : int32(size)
+ memcpy(
+ cast_to_void_pointer(union_value(to_llvm_type, union_pointer)),
+ cast_to_void_pointer(union_value(from_llvm_type, value)),
+ size,
+ align: @llvm_typer.align_of(to_value_type),
+ src_align: @llvm_typer.align_of(from_value_type),
+ volatile: int1(0),
+ )
+ end
+
+ def assign_distinct_union_types(to_pointer, to_type, from_type, from_pointer)
# If we have:
- # - target_pointer: Pointer(A | B | C)
- # - target_type: A | B | C
- # - value_type: A | B
- # - value: Pointer(A | B)
+ # - to_pointer: Pointer(A | B | C)
+ # - to_type: A | B | C
+ # - from_type: A | B
+ # - from_pointer: Pointer(A | B)
#
- # Then we:
- # - load the value, we get A | B
- # - cast the target pointer to Pointer(A | B)
- # - store the A | B from the first pointer into the casted target pointer
- casted_target_pointer = cast_to_pointer target_pointer, value_type
- store load(llvm_type(value_type), value), casted_target_pointer
+ # Then it might happen that from_type and to_type have the same alignment.
+ # In this case, the two pointers are interchangeable, so we can simply:
+ if align_of(to_type) == align_of(from_type)
+ # - load the value, we get A | B
+ # - cast the target pointer to Pointer(A | B)
+ # - store the A | B from the value pointer into the casted target pointer
+ casted_target_pointer = cast_to_pointer to_pointer, from_type
+ store load(llvm_type(from_type), from_pointer), casted_target_pointer
+ else
+ # Otherwise, the type ID and the value must be stored separately
+ store_union_in_union to_type, to_pointer, from_type, from_pointer
+ end
end
def downcast_distinct_union_types(value, to_type : MixedUnionType, from_type : MixedUnionType)
- cast_to_pointer value, to_type
+ # If from_type and to_type have the same alignment, we don't need a
+ # separate value; just cast the larger value pointer to the smaller one
+ if align_of(to_type) == align_of(from_type)
+ cast_to_pointer value, to_type
+ else
+ # This is the same as upcasting and we need that separate, newly aligned
+ # union value
+ target_pointer = alloca llvm_type(to_type)
+ store_union_in_union to_type, target_pointer, from_type, value
+ target_pointer
+ end
end
def upcast_distinct_union_types(value, to_type : MixedUnionType, from_type : MixedUnionType)
diff --git a/src/compiler/crystal/command.cr b/src/compiler/crystal/command.cr
index 2c5492445e0b..b51f9405c4e6 100644
--- a/src/compiler/crystal/command.cr
+++ b/src/compiler/crystal/command.cr
@@ -41,6 +41,7 @@ class Crystal::Command
Tool:
context show context for given location
expand show macro expansion for given location
+ flags print all macro `flag?` values
format format project, directories and/or files
hierarchy show type hierarchy
dependencies show file dependency tree
@@ -58,7 +59,7 @@ class Crystal::Command
@compiler : Compiler?
def initialize(@options : Array(String))
- @color = ENV["TERM"]? != "dumb"
+ @color = ENV["TERM"]? != "dumb" && !ENV.has_key?("NO_COLOR")
@error_trace = false
@progress_tracker = ProgressTracker.new
end
@@ -177,6 +178,9 @@ class Crystal::Command
when "format".starts_with?(tool)
options.shift
format
+ when "flags" == tool
+ options.shift
+ flags
when "expand".starts_with?(tool)
options.shift
expand
@@ -349,7 +353,8 @@ class Crystal::Command
includes : Array(String),
excludes : Array(String),
verbose : Bool,
- check : Bool do
+ check : Bool,
+ tallies : Bool do
def compile(output_filename = self.output_filename)
compiler.emit_base_filename = emit_base_filename || output_filename.rchop(File.extname(output_filename))
compiler.compile sources, output_filename, combine_rpath: combine_rpath
@@ -367,6 +372,7 @@ class Crystal::Command
allowed_formats = ["text", "json"])
compiler = new_compiler
compiler.progress_tracker = @progress_tracker
+ compiler.no_codegen = no_codegen
link_flags = [] of String
filenames = [] of String
has_stdin_filename = false
@@ -381,6 +387,7 @@ class Crystal::Command
includes = [] of String
verbose = false
check = false
+ tallies = false
option_parser = parse_with_crystal_opts do |opts|
opts.banner = "Usage: crystal #{command} [options] [programfile] [--] [arguments]\n\nOptions:"
@@ -397,6 +404,14 @@ class Crystal::Command
opts.on("--no-debug", "Skip any symbolic debug info") do
compiler.debug = Crystal::Debug::None
end
+
+ opts.on("--frame-pointers auto|always|non-leaf", "Control the preservation of frame pointers") do |value|
+ if frame_pointers = FramePointers.parse?(value)
+ compiler.frame_pointers = frame_pointers
+ else
+ error "Invalid value `#{value}` for frame-pointers"
+ end
+ end
end
opts.on("-D FLAG", "--define FLAG", "Define a compile-time flag") do |flag|
@@ -443,6 +458,10 @@ class Crystal::Command
end
if unreachable_command
+ opts.on("--tallies", "Print reachable methods and their call counts as well") do
+ tallies = true
+ end
+
opts.on("--check", "Exits with error if there is any unreachable code") do |f|
check = true
end
@@ -590,7 +609,7 @@ class Crystal::Command
output_filename = "#{::Path[first_filename].stem}#{output_extension}"
# Check if we'll overwrite the main source file
- if !no_codegen && !run && first_filename == File.expand_path(output_filename)
+ if !compiler.no_codegen? && !run && first_filename == File.expand_path(output_filename)
error "compilation will overwrite source file '#{Crystal.relative_filename(first_filename)}', either change its extension to '.cr' or specify an output file with '-o'"
end
end
@@ -602,7 +621,7 @@ class Crystal::Command
error "maximum number of threads cannot be lower than 1" if compiler.n_threads < 1
- if !no_codegen && !run && Dir.exists?(output_filename)
+ if !compiler.no_codegen? && !run && Dir.exists?(output_filename)
error "can't use `#{output_filename}` as output filename because it's a directory"
end
@@ -610,10 +629,10 @@ class Crystal::Command
emit_base_filename = ::Path[sources.first.filename].stem
end
- combine_rpath = run && !no_codegen
+ combine_rpath = run && !compiler.no_codegen?
@config = CompilerConfig.new compiler, sources, output_filename, emit_base_filename,
arguments, specified_output, hierarchy_exp, cursor_location, output_format.not_nil!,
- combine_rpath, includes, excludes, verbose, check
+ combine_rpath, includes, excludes, verbose, check, tallies
end
private def gather_sources(filenames)
@@ -621,6 +640,8 @@ class Crystal::Command
filename = File.expand_path(filename)
Compiler::Source.new(filename, File.read(filename))
end
+ rescue exc : IO::Error
+ error exc
end
private def setup_simple_compiler_options(compiler, opts)
@@ -727,7 +748,7 @@ class Crystal::Command
private def error(msg, exit_code = 1)
# This is for the case where the main command is wrong
- @color = false if ARGV.includes?("--no-color") || ENV["TERM"]? == "dumb"
+ @color = false if ARGV.includes?("--no-color") || ENV["TERM"]? == "dumb" || ENV.has_key?("NO_COLOR")
Crystal.error msg, @color, exit_code: exit_code
end
diff --git a/src/compiler/crystal/command/spec.cr b/src/compiler/crystal/command/spec.cr
index ff8f47b11859..ce34b2ac4155 100644
--- a/src/compiler/crystal/command/spec.cr
+++ b/src/compiler/crystal/command/spec.cr
@@ -24,7 +24,7 @@ class Crystal::Command
puts opts
puts
- runtime_options = Spec.option_parser
+ runtime_options = Spec::CLI.new.option_parser
runtime_options.banner = "Runtime options (passed to spec runner):"
puts runtime_options
exit
diff --git a/src/compiler/crystal/compiler.cr b/src/compiler/crystal/compiler.cr
index 237783c2ed8c..899ef242f318 100644
--- a/src/compiler/crystal/compiler.cr
+++ b/src/compiler/crystal/compiler.cr
@@ -16,6 +16,12 @@ module Crystal
Default = LineNumbers
end
+ enum FramePointers
+ Auto
+ Always
+ NonLeaf
+ end
+
# Main interface to the compiler.
#
# A Compiler parses source code, type checks it and
@@ -45,6 +51,9 @@ module Crystal
# code by the `flag?(...)` macro method.
property flags = [] of String
+ # Controls generation of frame pointers.
+ property frame_pointers = FramePointers::Auto
+
# If `true`, the executable will be generated with debug code
# that can be understood by `gdb` and `lldb`.
property debug = Debug::Default
@@ -297,7 +306,8 @@ module Crystal
private def codegen(program, node : ASTNode, sources, output_filename)
llvm_modules = @progress_tracker.stage("Codegen (crystal)") do
- program.codegen node, debug: debug, single_module: @single_module || @cross_compile || !@emit_targets.none?
+ program.codegen node, debug: debug, frame_pointers: frame_pointers,
+ single_module: @single_module || @cross_compile || !@emit_targets.none?
end
output_dir = CacheDir.instance.directory_for(sources)
@@ -321,6 +331,10 @@ module Crystal
{% if flag?(:darwin) %}
run_dsymutil(output_filename) unless debug.none?
{% end %}
+
+ {% if flag?(:windows) %}
+ copy_dlls(program, output_filename) if program.has_flag?("preview_dll")
+ {% end %}
end
CacheDir.instance.cleanup if @cleanup
@@ -345,6 +359,25 @@ module Crystal
end
end
+ private def copy_dlls(program, output_filename)
+ not_found = nil
+ output_directory = File.dirname(output_filename)
+
+ program.each_dll_path do |path, found|
+ if found
+ FileUtils.cp(path, output_directory)
+ else
+ not_found ||= [] of String
+ not_found << path
+ end
+ end
+
+ if not_found
+ stderr << "Warning: The following DLLs are required at run time, but Crystal is unable to locate them in CRYSTAL_LIBRARY_PATH, the compiler's directory, or PATH: "
+ not_found.sort!.join(stderr, ", ")
+ end
+ end
+
private def cross_compile(program, units, output_filename)
unit = units.first
llvm_mod = unit.llvm_mod
diff --git a/src/compiler/crystal/ffi/lib_ffi.cr b/src/compiler/crystal/ffi/lib_ffi.cr
index 699a0c125468..97163c989ee5 100644
--- a/src/compiler/crystal/ffi/lib_ffi.cr
+++ b/src/compiler/crystal/ffi/lib_ffi.cr
@@ -1,5 +1,8 @@
module Crystal
@[Link("ffi")]
+ {% if compare_versions(Crystal::VERSION, "1.11.0-dev") >= 0 %}
+ @[Link(dll: "libffi.dll")]
+ {% end %}
lib LibFFI
{% begin %}
enum ABI
diff --git a/src/compiler/crystal/interpreter/compiler.cr b/src/compiler/crystal/interpreter/compiler.cr
index bfd1514b419f..04fc885fce7e 100644
--- a/src/compiler/crystal/interpreter/compiler.cr
+++ b/src/compiler/crystal/interpreter/compiler.cr
@@ -762,7 +762,7 @@ class Crystal::Repl::Compiler < Crystal::Visitor
# particularly when outside of a method.
if is_self && !scope.is_a?(Program) && !scope.passed_as_self?
put_type scope, node: node
- return
+ return false
end
local_var = lookup_local_var_or_closured_var(node.name)
@@ -1687,7 +1687,7 @@ class Crystal::Repl::Compiler < Crystal::Visitor
if node.upcast?
upcast node.obj, obj_type, node.non_nilable_type
upcast node.obj, node.non_nilable_type, node.type
- return
+ return false
end
# Check if obj is a `to_type`
@@ -3158,6 +3158,7 @@ class Crystal::Repl::Compiler < Crystal::Visitor
{% end %}
call compiled_def, node: node
+ false
end
def visit(node : ASTNode)
diff --git a/src/compiler/crystal/interpreter/context.cr b/src/compiler/crystal/interpreter/context.cr
index f4a4444e105c..2d5da06dcf15 100644
--- a/src/compiler/crystal/interpreter/context.cr
+++ b/src/compiler/crystal/interpreter/context.cr
@@ -46,6 +46,9 @@ class Crystal::Repl::Context
def initialize(@program : Program)
@program.flags << "interpreted"
+ {% if flag?(:win32) %}
+ @program.flags << "preview_dll"
+ {% end %}
@gc_references = [] of Void*
@@ -392,6 +395,8 @@ class Crystal::Repl::Context
@id_to_type[id]
end
+ getter? loader : Loader?
+
getter(loader : Loader) {
lib_flags = program.lib_flags
# Execute and expand `subcommands`.
@@ -404,14 +409,7 @@ class Crystal::Repl::Context
# (MSVC doesn't seem to have this issue)
args.delete("-lgc")
- Crystal::Loader.parse(args).tap do |loader|
- if ENV["CRYSTAL_INTERPRETER_LOADER_INFO"]?.presence
- STDERR.puts "Crystal::Loader loaded libraries:"
- loader.loaded_libraries.each do |path|
- STDERR.puts " #{path}"
- end
- end
-
+ Crystal::Loader.parse(args, dll_search_paths: dll_search_paths).tap do |loader|
# FIXME: Part 2: This is a workaround for initial integration of the interpreter:
# We append a handle to the current executable (i.e. the compiler program)
# to the loader's handle list. This gives the loader access to all the symbols in the compiler program,
@@ -421,11 +419,35 @@ class Crystal::Repl::Context
loader.load_current_program_handle
if ENV["CRYSTAL_INTERPRETER_LOADER_INFO"]?.presence
- STDERR.puts " current program handle"
+ STDERR.puts "Crystal::Loader loaded libraries:"
+ loader.loaded_libraries.each do |path|
+ STDERR.puts " #{path}"
+ end
end
end
}
+ # Extra DLL search paths to mimic compiled code's DLL-copying behavior
+ # regarding `@[Link]` annotations. These directories should match the ones
+ # used in `Crystal::Program#each_dll_path`
+ private def dll_search_paths
+ {% if flag?(:msvc) %}
+ paths = CrystalLibraryPath.paths
+
+ if executable_path = Process.executable_path
+ paths << File.dirname(executable_path)
+ end
+
+ ENV["PATH"]?.try &.split(Process::PATH_DELIMITER, remove_empty: true) do |path|
+ paths << path
+ end
+
+ paths
+ {% else %}
+ nil
+ {% end %}
+ end
+
def c_function(name : String)
loader.find_symbol(name)
end
diff --git a/src/compiler/crystal/interpreter/instructions.cr b/src/compiler/crystal/interpreter/instructions.cr
index 67966277bf15..f2b8abcb9a51 100644
--- a/src/compiler/crystal/interpreter/instructions.cr
+++ b/src/compiler/crystal/interpreter/instructions.cr
@@ -1649,6 +1649,11 @@ require "./repl"
pop_values: [current_context : Void*, new_context : Void*],
code: swapcontext(current_context, new_context),
},
+ interpreter_fiber_resumable: {
+ pop_values: [context : Void*],
+ push: true,
+ code: fiber_resumable(context),
+ },
{% if flag?(:bits64) %}
interpreter_intrinsics_memcpy: {
diff --git a/src/compiler/crystal/interpreter/interpreter.cr b/src/compiler/crystal/interpreter/interpreter.cr
index 608fb6d85d1a..eca73ecae6bc 100644
--- a/src/compiler/crystal/interpreter/interpreter.cr
+++ b/src/compiler/crystal/interpreter/interpreter.cr
@@ -1154,6 +1154,7 @@ class Crystal::Repl::Interpreter
nil
end
end
+ spawned_fiber.@context.resumable = 1
spawned_fiber.as(Void*)
end
@@ -1161,11 +1162,17 @@ class Crystal::Repl::Interpreter
# current_fiber = current_context.as(Fiber*).value
new_fiber = new_context.as(Fiber*).value
- # We directly resume the next fiber.
- # TODO: is this okay? We totally ignore the scheduler here!
+ # delegates the context switch to the interpreter's scheduler, so we update
+ # the current fiber reference, set the GC stack bottom, and so on (aka
+ # there's more to switching context than `Fiber.swapcontext`):
new_fiber.resume
end
+ private def fiber_resumable(context : Void*) : LibC::Long
+ fiber = context.as(Fiber*).value
+ fiber.@context.resumable
+ end
+
private def pry(ip, instructions, stack_bottom, stack)
offset = (ip - instructions.instructions.to_unsafe).to_i32
node = instructions.nodes[offset]?
diff --git a/src/compiler/crystal/interpreter/primitives.cr b/src/compiler/crystal/interpreter/primitives.cr
index 1d50568c5d62..968361fb6c1d 100644
--- a/src/compiler/crystal/interpreter/primitives.cr
+++ b/src/compiler/crystal/interpreter/primitives.cr
@@ -402,6 +402,9 @@ class Crystal::Repl::Compiler
when "interpreter_fiber_swapcontext"
accept_call_args(node)
interpreter_fiber_swapcontext(node: node)
+ when "interpreter_fiber_resumable"
+ accept_call_args(node)
+ interpreter_fiber_resumable(node: node)
when "interpreter_intrinsics_memcpy"
accept_call_args(node)
interpreter_intrinsics_memcpy(node: node)
diff --git a/src/compiler/crystal/interpreter/repl.cr b/src/compiler/crystal/interpreter/repl.cr
index 93b3a6cef65c..2c009a89e87d 100644
--- a/src/compiler/crystal/interpreter/repl.cr
+++ b/src/compiler/crystal/interpreter/repl.cr
@@ -22,15 +22,13 @@ class Crystal::Repl
when "exit"
break
when .presence
- parser = new_parser(expression)
- parser.warnings.report(STDOUT)
+ result = parse_and_interpret(expression)
+ result.warnings.report(STDOUT)
- node = parser.parse
- next unless node
+ next unless result.value
- value = interpret(node)
print " => "
- puts SyntaxHighlighter::Colorize.highlight!(value.to_s)
+ puts SyntaxHighlighter::Colorize.highlight!(result.value.to_s)
end
rescue ex : EscapingException
print "Unhandled exception: "
@@ -44,6 +42,18 @@ class Crystal::Repl
end
end
+ record EvalResult, value : Value?, warnings : WarningCollection
+
+ def parse_and_interpret(expression : String) : EvalResult
+ parser = new_parser(expression)
+
+ node = parser.parse
+ return EvalResult.new(value: nil, warnings: parser.warnings) unless node
+
+ value = interpret(node)
+ return EvalResult.new(value: value, warnings: parser.warnings)
+ end
+
def run_file(filename, argv)
@interpreter.argv = argv
@@ -68,7 +78,7 @@ class Crystal::Repl
interpret(exps)
end
- private def load_prelude
+ def load_prelude
node = parse_prelude
interpret_and_exit_on_error(node)
diff --git a/src/compiler/crystal/loader.cr b/src/compiler/crystal/loader.cr
index d7d0133cc993..5a147dad590f 100644
--- a/src/compiler/crystal/loader.cr
+++ b/src/compiler/crystal/loader.cr
@@ -14,6 +14,7 @@ class Crystal::Loader
class LoadError < Exception
property args : Array(String)?
property search_paths : Array(String)?
+ property dll_search_paths : Array(String)?
def message
String.build do |io|
@@ -26,28 +27,26 @@ class Crystal::Loader
io << "\nSearch path: "
search_paths.join(io, Process::PATH_DELIMITER)
end
+ if dll_search_paths = @dll_search_paths
+ io << "\nDLL search path: "
+ dll_search_paths.join(io, Process::PATH_DELIMITER)
+ end
end
end
end
- def self.new(search_paths : Array(String), libnames : Array(String), file_paths : Array(String)) : self
- loader = new(search_paths)
-
+ def load_all(libnames : Array(String), file_paths : Array(String))
file_paths.each do |path|
- loader.load_file(::Path[path].expand)
+ load_file(::Path[path].expand)
end
libnames.each do |libname|
- loader.load_library(libname)
+ load_library(libname)
end
- loader
end
getter search_paths : Array(String)
getter loaded_libraries = [] of String
-
- def initialize(@search_paths : Array(String))
- @handles = [] of Handle
- end
+ @handles = [] of Handle
# def self.library_filename(libname : String) : String
# raise NotImplementedError.new("library_filename")
diff --git a/src/compiler/crystal/loader/msvc.cr b/src/compiler/crystal/loader/msvc.cr
index bf0b5c74a36f..60aca1aae333 100644
--- a/src/compiler/crystal/loader/msvc.cr
+++ b/src/compiler/crystal/loader/msvc.cr
@@ -5,9 +5,9 @@ require "crystal/system/win32/library_archive"
# `link.exe`, using the Win32 DLL API.
#
# * Only dynamic libraries can be loaded. Static libraries and object files
-# are unsupported. in particular, `LibC.printf` and `LibC.snprintf`are inline
-# functions in `legacy-stdio_definitions.lib` since VS2015, so they are never
-# found by the loader.
+# are unsupported. For example, `LibC.printf` and `LibC.snprintf` are inline
+# functions in `legacy_stdio_definitions.lib` since VS2015, so they are never
+# found by the loader (this is why stdlib no longer uses those functions).
# * Unlike the Unix counterpart, symbols in the current module do not clash with
# the ones in DLLs or their corresponding import libraries.
@@ -18,16 +18,28 @@ class Crystal::Loader
include SystemError
end
+ getter dll_search_paths : Array(String)?
+
+ def initialize(@search_paths : Array(String), @dll_search_paths : Array(String)? = nil)
+ end
+
# Parses linker arguments in the style of `link.exe`.
- def self.parse(args : Array(String), *, search_paths : Array(String) = default_search_paths) : self
+ #
+ # The directories in *dll_search_paths* are tried before Windows' search order
+ # when looking for DLLs corresponding to an import library. The compiler uses
+ # this to mimic `@[Link]`'s DLL-copying behavior for compiled code.
+ def self.parse(args : Array(String), *, search_paths : Array(String) = default_search_paths, dll_search_paths : Array(String)? = nil) : self
search_paths, libnames = parse_args(args, search_paths)
file_paths = [] of String
begin
- self.new(search_paths, libnames, file_paths)
+ loader = new(search_paths, dll_search_paths)
+ loader.load_all(libnames, file_paths)
+ loader
rescue exc : LoadError
exc.args = args
exc.search_paths = search_paths
+ exc.dll_search_paths = dll_search_paths
raise exc
end
end
@@ -60,7 +72,7 @@ class Crystal::Loader
result
end
- private def self.search_library(libname, search_paths, extra_suffix)
+ protected def self.search_library(libname, search_paths, extra_suffix)
if ::Path::SEPARATORS.any? { |separator| libname.includes?(separator) }
libname = File.expand_path(libname)
library_path = library_filename(libname)
@@ -106,7 +118,7 @@ class Crystal::Loader
end
def self.library_filename(libname : String) : String
- "#{libname}.lib"
+ "#{libname.rchop(".lib")}.lib"
end
def find_symbol?(name : String) : Handle?
@@ -127,19 +139,24 @@ class Crystal::Loader
# files, whose base names may not match the library's. Thus it is necessary
# to extract this information from the library archive itself.
System::LibraryArchive.imported_dlls(path).each do |dll|
- # always consider the `.dll` in the same directory as the `.lib` first,
- # regardless of the search order
- first_path = File.join(File.dirname(path), dll)
- dll = first_path if File.file?(first_path)
+ dll_full_path = @dll_search_paths.try &.each do |search_path|
+ full_path = File.join(search_path, dll)
+ break full_path if File.file?(full_path)
+ end
+ dll = dll_full_path || dll
# TODO: `dll` is an unqualified name, e.g. `SHELL32.dll`, so the default
- # DLL search order is used; consider getting rid of the cwd
+ # DLL search order is used if *dll_full_path* is nil; consider getting rid
+ # of the current working directory altogether
# (https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order)
+ #
+ # Note that the compiler's directory and PATH are effectively searched
+ # twice when coming from the interpreter
handle = open_library(dll)
return false unless handle
@handles << handle
- @loaded_libraries << dll
+ @loaded_libraries << (module_filename(handle) || dll)
end
true
@@ -149,14 +166,20 @@ class Crystal::Loader
load_library?(libname) || raise LoadError.from_winerror "cannot find #{Loader.library_filename(libname)}"
end
+ def load_library?(libname : String) : Bool
+ library_path = Loader.search_library(libname, @search_paths, "-dynamic")
+ !library_path.nil? && load_file?(library_path)
+ end
+
private def open_library(path : String)
- # TODO: respect Crystal::LIBRARY_RPATH (#13490)
+ # TODO: respect Crystal::LIBRARY_RPATH (#13490), or `@[Link(dll:)]`'s search order
LibC.LoadLibraryExW(System.to_wstr(path), nil, 0)
end
def load_current_program_handle
if LibC.GetModuleHandleExW(0, nil, out hmodule) != 0
@handles << hmodule
+ @loaded_libraries << (Process.executable_path || "current program handle")
end
end
@@ -167,6 +190,19 @@ class Crystal::Loader
@handles.clear
end
+ private def module_filename(handle)
+ Crystal::System.retry_wstr_buffer do |buffer, small_buf|
+ len = LibC.GetModuleFileNameW(handle, buffer, buffer.size)
+ if 0 < len < buffer.size
+ break String.from_utf16(buffer[0, len])
+ elsif small_buf && len == buffer.size
+ next 32767 # big enough. 32767 is the maximum total path length of UNC path.
+ else
+ break nil
+ end
+ end
+ end
+
# Returns a list of directories used as the default search paths.
#
# For MSVC this is simply the contents of the `LIB` environment variable,
diff --git a/src/compiler/crystal/loader/unix.cr b/src/compiler/crystal/loader/unix.cr
index 4c202231d7e6..46bca67341cc 100644
--- a/src/compiler/crystal/loader/unix.cr
+++ b/src/compiler/crystal/loader/unix.cr
@@ -35,8 +35,16 @@ class Crystal::Loader
end
end
+ def initialize(@search_paths : Array(String))
+ end
+
# Parses linker arguments in the style of `ld`.
- def self.parse(args : Array(String), *, search_paths : Array(String) = default_search_paths) : self
+ #
+ # *dll_search_paths* has no effect. (Technically speaking, `LD_LIBRARY_PATH`
+ # goes here and `LIBRARY_PATH` goes into *search_paths*, but there is little
+ # point in doing so since the same library files are used at both compile and
+ # run time.)
+ def self.parse(args : Array(String), *, search_paths : Array(String) = default_search_paths, dll_search_paths : Array(String)? = nil) : self
libnames = [] of String
file_paths = [] of String
@@ -73,7 +81,9 @@ class Crystal::Loader
search_paths = extra_search_paths + search_paths
begin
- self.new(search_paths, libnames, file_paths)
+ loader = new(search_paths)
+ loader.load_all(libnames, file_paths)
+ loader
rescue exc : LoadError
exc.args = args
exc.search_paths = search_paths
@@ -120,6 +130,7 @@ class Crystal::Loader
def load_current_program_handle
if program_handle = LibC.dlopen(nil, LibC::RTLD_LAZY | LibC::RTLD_GLOBAL)
@handles << program_handle
+ @loaded_libraries << (Process.executable_path || "current program handle")
end
end
diff --git a/src/compiler/crystal/macros.cr b/src/compiler/crystal/macros.cr
index 983af69ae4b7..3ec6243ffd62 100644
--- a/src/compiler/crystal/macros.cr
+++ b/src/compiler/crystal/macros.cr
@@ -442,6 +442,8 @@ module Crystal::Macros
# Returns a `MacroId` that contains the documentation comments attached to this node, or an empty `MacroId` if there are none.
# Each line is prefixed with a `#` character to allow the output to be used directly within another node's documentation comment.
#
+ # A common use case is combining this method with the `@caller` macro instance variable in order to allow [merging macro expansion and call comments](https://crystal-lang.org/reference/syntax_and_semantics/macros/index.html#merging-expansion-and-call-comments).
+ #
# WARNING: The return value will be empty when executed outside of the `crystal docs` command.
def doc_comment : MacroId
end
@@ -1405,6 +1407,27 @@ module Crystal::Macros
end
end
+ # A fictitious node representing the body of a `Def` marked with
+ # `@[Primitive]`.
+ class Primitive < ASTNode
+ # Returns the name of the primitive.
+ #
+ # This is identical to the argument to the associated `@[Primitive]`
+ # annotation.
+ #
+ # ```
+ # module Foo
+ # @[Primitive(:abc)]
+ # def foo
+ # end
+ # end
+ #
+ # {{ Foo.methods.first.body.name }} # => :abc
+ # ```
+ def name : SymbolLiteral
+ end
+ end
+
# A macro definition.
class Macro < ASTNode
# Returns the name of this macro.
@@ -1804,6 +1827,185 @@ module Crystal::Macros
end
end
+ # A lib definition.
+ #
+ # Every lib definition `node` is equivalent to:
+ #
+ # ```
+ # {% begin %}
+ # {{ node.kind }} {{ node.name }}
+ # {{ node.body }}
+ # end
+ # {% end %}
+ # ```
+ class LibDef < ASTNode
+ # Returns the keyword used to define this type.
+ #
+ # For `LibDef` this is always `lib`.
+ def kind : MacroId
+ end
+
+ # Returns the name of this type definition.
+ #
+ # *generic_args* has no effect. It exists solely to match the interface of
+ # other related AST nodes.
+ def name(*, generic_args : BoolLiteral = true) : Path
+ end
+
+ # Returns the body of this type definition.
+ def body : ASTNode
+ end
+ end
+
+ # A struct or union definition inside a lib.
+ #
+ # Every type definition `node` is equivalent to:
+ #
+ # ```
+ # {% begin %}
+ # {{ node.kind }} {{ node.name }}
+ # {{ node.body }}
+ # end
+ # {% end %}
+ # ```
+ class CStructOrUnionDef < ASTNode
+ # Returns whether this node defines a C union.
+ def union? : BoolLiteral
+ end
+
+ # Returns the keyword used to define this type.
+ #
+ # For `CStructOrUnionDef` this is either `struct` or `union`.
+ def kind : MacroId
+ end
+
+ # Returns the name of this type definition.
+ #
+ # *generic_args* has no effect. It exists solely to match the interface of
+ # other related AST nodes.
+ def name(*, generic_args : BoolLiteral = true) : Path
+ end
+
+ # Returns the body of this type definition.
+ def body : ASTNode
+ end
+ end
+
+ # A function declaration inside a lib, or a top-level C function definition.
+ #
+ # Every function `node` is equivalent to:
+ #
+ # ```
+ # fun {{ node.name }} {% if real_name = node.real_name %}= {{ real_name }}{% end %}(
+ # {% for arg in node.args %} {{ arg }}, {% end %}
+ # {% if node.variadic? %} ... {% end %}
+ # ) {% if return_type = node.return_type %}: {{ return_type }}{% end %}
+ # {% if node.has_body? %}
+ # {{ body }}
+ # end
+ # {% end %}
+ # ```
+ class FunDef < ASTNode
+ # Returns the name of the function in Crystal.
+ def name : MacroId
+ end
+
+ # Returns the real C name of the function, if any.
+ def real_name : StringLiteral | Nop
+ end
+
+ # Returns the parameters of the function.
+ #
+ # This does not include the variadic parameter.
+ def args : ArrayLiteral(Arg)
+ end
+
+ # Returns whether the function is variadic.
+ def variadic? : BoolLiteral
+ end
+
+ # Returns the return type of the function, if specified.
+ def return_type : ASTNode | Nop
+ end
+
+ # Returns the body of the function, if any.
+ #
+ # Both top-level funs and lib funs may return a `Nop`. Instead, `#has_body?`
+ # can be used to distinguish between the two.
+ #
+ # ```
+ # macro body_class(x)
+ # {{ (x.is_a?(LibDef) ? x.body : x).body.class_name }}
+ # end
+ #
+ # body_class(lib MyLib
+ # fun foo
+ # end) # => "Nop"
+ #
+ # body_class(fun foo
+ # end) # => "Nop"
+ # ```
+ def body : ASTNode | Nop
+ end
+
+ # Returns whether this function has a body.
+ #
+ # Top-level funs have a body, whereas lib funs do not.
+ #
+ # ```
+ # macro has_body(x)
+ # {{ (x.is_a?(LibDef) ? x.body : x).has_body? }}
+ # end
+ #
+ # has_body(lib MyLib
+ # fun foo
+ # end) # => false
+ #
+ # has_body(fun foo
+ # end) # => true
+ # ```
+ def has_body? : BoolLiteral
+ end
+ end
+
+ # A typedef inside a lib.
+ #
+ # Every typedef `node` is equivalent to:
+ #
+ # ```
+ # type {{ node.name }} = {{ node.type }}
+ # ```
+ class TypeDef < ASTNode
+ # Returns the name of the typedef.
+ def name : Path
+ end
+
+ # Returns the name of the type this typedef is equivalent to.
+ def type : ASTNode
+ end
+ end
+
+ # An external variable declaration inside a lib.
+ #
+ # Every variable `node` is equivalent to:
+ #
+ # ```
+ # ${{ node.name }} {% if real_name = node.real_name %}= {{ real_name }}{% end %} : {{ node.type }}
+ # ```
+ class ExternalVar < ASTNode
+ # Returns the name of the variable in Crystal, without the preceding `$`.
+ def name : MacroId
+ end
+
+ # Returns the real C name of the variable, if any.
+ def real_name : StringLiteral | Nop
+ end
+
+ # Returns the name of the variable's type.
+ def type : ASTNode
+ end
+ end
+
# A `while` expression
class While < ASTNode
# Returns this while's condition.
@@ -2032,29 +2234,22 @@ module Crystal::Macros
end
end
- # class LibDef < ASTNode
- # end
-
- # class FunDef < ASTNode
- # end
-
- # class TypeDef < ASTNode
- # end
-
- # abstract class CStructOrUnionDef < ASTNode
- # end
-
- # class StructDef < CStructOrUnionDef
- # end
-
- # class UnionDef < CStructOrUnionDef
- # end
-
- # class ExternalVar < ASTNode
- # end
+ # An `alias` statement.
+ #
+ # Every statement `node` is equivalent to:
+ #
+ # ```
+ # alias {{ node.name }} = {{ node.type }}
+ # ```
+ class Alias < ASTNode
+ # Returns the name of the alias.
+ def name : Path
+ end
- # class Alias < ASTNode
- # end
+ # Returns the name of the type this alias is equivalent to.
+ def type : ASTNode
+ end
+ end
# A metaclass in a type expression: `T.class`
class Metaclass < ASTNode
@@ -2095,8 +2290,18 @@ module Crystal::Macros
end
end
- # class TypeOf < ASTNode
- # end
+ # A `typeof` expression.
+ #
+ # Every expression *node* is equivalent to:
+ #
+ # ```
+ # typeof({{ node.args.splat }})
+ # ```
+ class TypeOf < ASTNode
+ # Returns the arguments to this `typeof`.
+ def args : ArrayLiteral(ASTNode)
+ end
+ end
# A macro expression,
# surrounded by {{ ... }} (output = true)
@@ -2172,6 +2377,75 @@ module Crystal::Macros
class MagicConstant < ASTNode
end
+ # An inline assembly expression.
+ #
+ # Every assembly `node` is equivalent to:
+ #
+ # ```
+ # asm(
+ # {{ node.text }} :
+ # {{ node.outputs.splat }} :
+ # {{ node.inputs.splat }} :
+ # {{ node.clobbers.splat }} :
+ # {% if node.volatile? %} "volatile", {% end %}
+ # {% if node.alignstack? %} "alignstack", {% end %}
+ # {% if node.intel? %} "intel", {% end %}
+ # {% if node.can_throw? %} "unwind", {% end %}
+ # )
+ # ```
+ class Asm < ASTNode
+ # Returns the template string for this assembly expression.
+ def text : StringLiteral
+ end
+
+ # Returns an array of output operands for this assembly expression.
+ def outputs : ArrayLiteral(AsmOperand)
+ end
+
+ # Returns an array of input operands for this assembly expression.
+ def inputs : ArrayLiteral(AsmOperand)
+ end
+
+ # Returns an array of clobbered register names for this assembly expression.
+ def clobbers : ArrayLiteral(StringLiteral)
+ end
+
+ # Returns whether the assembly expression contains side effects that are
+ # not listed in `#outputs`, `#inputs`, and `#clobbers`.
+ def volatile? : BoolLiteral
+ end
+
+ # Returns whether the assembly expression requires stack alignment code.
+ def alignstack? : BoolLiteral
+ end
+
+ # Returns `true` if the template string uses the Intel syntax, `false` if it
+ # uses the AT&T syntax.
+ def intel? : BoolLiteral
+ end
+
+ # Returns whether the assembly expression might unwind the stack.
+ def can_throw? : BoolLiteral
+ end
+ end
+
+ # An output or input operand for an `Asm` node.
+ #
+ # Every operand `node` is equivalent to:
+ #
+ # ```
+ # {{ node.constraint }}({{ node.exp }})
+ # ```
+ class AsmOperand < ASTNode
+ # Returns the constraint string of this operand.
+ def constraint : StringLiteral
+ end
+
+ # Returns the associated output or input argument of this operand.
+ def exp : ASTNode
+ end
+ end
+
# A fictitious node representing an identifier like, `foo`, `Bar` or `something_else`.
#
# The parser doesn't create these nodes. Instead, you create them by invoking `id`
diff --git a/src/compiler/crystal/macros/interpreter.cr b/src/compiler/crystal/macros/interpreter.cr
index 5bc7cd0117ca..1e18e92b7545 100644
--- a/src/compiler/crystal/macros/interpreter.cr
+++ b/src/compiler/crystal/macros/interpreter.cr
@@ -118,6 +118,7 @@ module Crystal
def visit(node : MacroLiteral)
@str << node.value
+ false
end
def visit(node : MacroVerbatim)
@@ -135,7 +136,8 @@ module Crystal
def visit(node : Var)
var = @vars[node.name]?
if var
- return @last = var
+ @last = var
+ return false
end
# Try to consider the var as a top-level macro call.
@@ -150,7 +152,8 @@ module Crystal
# and in this case the parser has no idea about this, so the only
# solution is to do it now.
if value = interpret_top_level_call?(Call.new(nil, node.name))
- return @last = value
+ @last = value
+ return false
end
node.raise "undefined macro variable '#{node.name}'"
@@ -549,6 +552,7 @@ module Crystal
else
node.raise "unknown macro instance var: '#{node.name}'"
end
+ false
end
def visit(node : TupleLiteral)
diff --git a/src/compiler/crystal/macros/methods.cr b/src/compiler/crystal/macros/methods.cr
index 24d3d8bbd14d..9891c4cc2b2a 100644
--- a/src/compiler/crystal/macros/methods.cr
+++ b/src/compiler/crystal/macros/methods.cr
@@ -300,7 +300,7 @@ module Crystal
def interpret_run(node)
if node.args.size == 0
- node.wrong_number_of_arguments "top-level macro 'run'", 0, "1+"
+ node.wrong_number_of_arguments "macro '::run'", 0, "1+"
end
node.args.first.accept self
@@ -1459,6 +1459,17 @@ module Crystal
end
end
+ class Primitive
+ def interpret(method : String, args : Array(ASTNode), named_args : Hash(String, ASTNode)?, block : Crystal::Block?, interpreter : Crystal::MacroInterpreter, name_loc : Location?)
+ case method
+ when "name"
+ interpret_check_args { SymbolLiteral.new(@name) }
+ else
+ super
+ end
+ end
+ end
+
class Macro
def interpret(method : String, args : Array(ASTNode), named_args : Hash(String, ASTNode)?, block : Crystal::Block?, interpreter : Crystal::MacroInterpreter, name_loc : Location?)
case method
@@ -1549,6 +1560,19 @@ module Crystal
end
end
+ class Alias
+ def interpret(method : String, args : Array(ASTNode), named_args : Hash(String, ASTNode)?, block : Crystal::Block?, interpreter : Crystal::MacroInterpreter, name_loc : Location?)
+ case method
+ when "name"
+ interpret_check_args { @name }
+ when "type"
+ interpret_check_args { @value }
+ else
+ super
+ end
+ end
+ end
+
class OffsetOf
def interpret(method : String, args : Array(ASTNode), named_args : Hash(String, ASTNode)?, block : Crystal::Block?, interpreter : Crystal::MacroInterpreter, name_loc : Location?)
case method
@@ -1629,6 +1653,62 @@ module Crystal
end
end
+ class Asm
+ def interpret(method : String, args : Array(ASTNode), named_args : Hash(String, ASTNode)?, block : Crystal::Block?, interpreter : Crystal::MacroInterpreter, name_loc : Location?)
+ case method
+ when "text"
+ interpret_check_args { StringLiteral.new(@text) }
+ when "outputs"
+ interpret_check_args do
+ if outputs = @outputs
+ ArrayLiteral.map(outputs, &.itself)
+ else
+ empty_no_return_array
+ end
+ end
+ when "inputs"
+ interpret_check_args do
+ if inputs = @inputs
+ ArrayLiteral.map(inputs, &.itself)
+ else
+ empty_no_return_array
+ end
+ end
+ when "clobbers"
+ interpret_check_args do
+ if clobbers = @clobbers
+ ArrayLiteral.map(clobbers) { |clobber| StringLiteral.new(clobber) }
+ else
+ empty_no_return_array
+ end
+ end
+ when "volatile?"
+ interpret_check_args { BoolLiteral.new(@volatile) }
+ when "alignstack?"
+ interpret_check_args { BoolLiteral.new(@alignstack) }
+ when "intel?"
+ interpret_check_args { BoolLiteral.new(@intel) }
+ when "can_throw?"
+ interpret_check_args { BoolLiteral.new(@can_throw) }
+ else
+ super
+ end
+ end
+ end
+
+ class AsmOperand
+ def interpret(method : String, args : Array(ASTNode), named_args : Hash(String, ASTNode)?, block : Crystal::Block?, interpreter : Crystal::MacroInterpreter, name_loc : Location?)
+ case method
+ when "constraint"
+ interpret_check_args { StringLiteral.new(@constraint) }
+ when "exp"
+ interpret_check_args { @exp }
+ else
+ super
+ end
+ end
+ end
+
class MacroId
def interpret(method : String, args : Array(ASTNode), named_args : Hash(String, ASTNode)?, block : Crystal::Block?, interpreter : Crystal::MacroInterpreter, name_loc : Location?)
case method
@@ -2351,6 +2431,17 @@ module Crystal
end
end
+ class TypeOf
+ def interpret(method : String, args : Array(ASTNode), named_args : Hash(String, ASTNode)?, block : Crystal::Block?, interpreter : Crystal::MacroInterpreter, name_loc : Location?)
+ case method
+ when "args"
+ interpret_check_args { ArrayLiteral.map(@expressions, &.itself) }
+ else
+ super
+ end
+ end
+ end
+
class Generic
def interpret(method : String, args : Array(ASTNode), named_args : Hash(String, ASTNode)?, block : Crystal::Block?, interpreter : Crystal::MacroInterpreter, name_loc : Location?)
case method
@@ -2522,6 +2613,97 @@ module Crystal
end
end
end
+
+ class LibDef
+ def interpret(method : String, args : Array(ASTNode), named_args : Hash(String, ASTNode)?, block : Crystal::Block?, interpreter : Crystal::MacroInterpreter, name_loc : Location?)
+ case method
+ when "kind"
+ interpret_check_args { MacroId.new("lib") }
+ when "name"
+ interpret_check_args(named_params: ["generic_args"]) do
+ # parse the argument, but ignore it otherwise
+ parse_generic_args_argument(self, method, named_args, default: true)
+ @name
+ end
+ when "body"
+ interpret_check_args { @body }
+ else
+ super
+ end
+ end
+ end
+
+ class CStructOrUnionDef
+ def interpret(method : String, args : Array(ASTNode), named_args : Hash(String, ASTNode)?, block : Crystal::Block?, interpreter : Crystal::MacroInterpreter, name_loc : Location?)
+ case method
+ when "kind"
+ interpret_check_args { MacroId.new(@union ? "union" : "struct") }
+ when "name"
+ interpret_check_args(named_params: ["generic_args"]) do
+ # parse the argument, but ignore it otherwise
+ parse_generic_args_argument(self, method, named_args, default: true)
+ Path.new(@name)
+ end
+ when "body"
+ interpret_check_args { @body }
+ when "union?"
+ interpret_check_args { BoolLiteral.new(@union) }
+ else
+ super
+ end
+ end
+ end
+
+ class FunDef
+ def interpret(method : String, args : Array(ASTNode), named_args : Hash(String, ASTNode)?, block : Crystal::Block?, interpreter : Crystal::MacroInterpreter, name_loc : Location?)
+ case method
+ when "name"
+ interpret_check_args { MacroId.new(@name) }
+ when "real_name"
+ interpret_check_args { @real_name != @name ? StringLiteral.new(@real_name) : Nop.new }
+ when "args"
+ interpret_check_args { ArrayLiteral.map(@args, &.itself) }
+ when "variadic?"
+ interpret_check_args { BoolLiteral.new(@varargs) }
+ when "return_type"
+ interpret_check_args { @return_type || Nop.new }
+ when "body"
+ interpret_check_args { @body || Nop.new }
+ when "has_body?"
+ interpret_check_args { BoolLiteral.new(!@body.nil?) }
+ else
+ super
+ end
+ end
+ end
+
+ class TypeDef
+ def interpret(method : String, args : Array(ASTNode), named_args : Hash(String, ASTNode)?, block : Crystal::Block?, interpreter : Crystal::MacroInterpreter, name_loc : Location?)
+ case method
+ when "name"
+ interpret_check_args { Path.new(@name).at(@name_location) }
+ when "type"
+ interpret_check_args { @type_spec }
+ else
+ super
+ end
+ end
+ end
+
+ class ExternalVar
+ def interpret(method : String, args : Array(ASTNode), named_args : Hash(String, ASTNode)?, block : Crystal::Block?, interpreter : Crystal::MacroInterpreter, name_loc : Location?)
+ case method
+ when "name"
+ interpret_check_args { MacroId.new(@name) }
+ when "real_name"
+ interpret_check_args { (real_name = @real_name) ? StringLiteral.new(real_name) : Nop.new }
+ when "type"
+ interpret_check_args { @type_spec }
+ else
+ super
+ end
+ end
+ end
end
private def get_named_annotation_args(object)
@@ -2841,7 +3023,7 @@ end
private def full_macro_name(node, method, top_level)
if top_level
- "top-level macro '#{method}'"
+ "macro '::#{method}'"
else
"macro '#{node.class_desc}##{method}'"
end
diff --git a/src/compiler/crystal/program.cr b/src/compiler/crystal/program.cr
index 936fc6a0a270..675202ee0144 100644
--- a/src/compiler/crystal/program.cr
+++ b/src/compiler/crystal/program.cr
@@ -275,36 +275,77 @@ module Crystal
# Defines a predefined constant in the Crystal module, such as BUILD_DATE and VERSION.
private def define_crystal_constants
if build_commit = Crystal::Config.build_commit
- define_crystal_string_constant "BUILD_COMMIT", build_commit
+ build_commit_const = define_crystal_string_constant "BUILD_COMMIT", build_commit
else
- define_crystal_nil_constant "BUILD_COMMIT"
+ build_commit_const = define_crystal_nil_constant "BUILD_COMMIT"
end
-
- define_crystal_string_constant "BUILD_DATE", Crystal::Config.date
- define_crystal_string_constant "CACHE_DIR", CacheDir.instance.dir
- define_crystal_string_constant "DEFAULT_PATH", Crystal::Config.path
- define_crystal_string_constant "DESCRIPTION", Crystal::Config.description
- define_crystal_string_constant "PATH", Crystal::CrystalPath.default_path
- define_crystal_string_constant "LIBRARY_PATH", Crystal::CrystalLibraryPath.default_path
- define_crystal_string_constant "LIBRARY_RPATH", Crystal::CrystalLibraryPath.default_rpath
- define_crystal_string_constant "VERSION", Crystal::Config.version
- define_crystal_string_constant "LLVM_VERSION", Crystal::Config.llvm_version
- define_crystal_string_constant "HOST_TRIPLE", Crystal::Config.host_target.to_s
- define_crystal_string_constant "TARGET_TRIPLE", Crystal::Config.host_target.to_s
- end
-
- private def define_crystal_string_constant(name, value)
- define_crystal_constant name, StringLiteral.new(value).tap(&.set_type(string))
- end
-
- private def define_crystal_nil_constant(name)
- define_crystal_constant name, NilLiteral.new.tap(&.set_type(self.nil))
- end
-
- private def define_crystal_constant(name, value)
+ build_commit_const.doc = <<-MD if wants_doc?
+ The build commit identifier of the Crystal compiler.
+ MD
+
+ define_crystal_string_constant "BUILD_DATE", Crystal::Config.date, <<-MD
+ The build date of the Crystal compiler.
+ MD
+ define_crystal_string_constant "CACHE_DIR", CacheDir.instance.dir, <<-MD
+ The cache directory configured for the Crystal compiler.
+
+ The value is defined by the environment variable `CRYSTAL_CACHE_DIR` and
+ defaults to the user's configured cache directory.
+ MD
+ define_crystal_string_constant "DEFAULT_PATH", Crystal::Config.path, <<-MD
+ The default Crystal path configured in the compiler. This value is baked
+ into the compiler and usually points to the accompanying version of the
+ standard library.
+ MD
+ define_crystal_string_constant "DESCRIPTION", Crystal::Config.description, <<-MD
+ Full version information of the Crystal compiler. Equivalent to `crystal --version`.
+ MD
+ define_crystal_string_constant "PATH", Crystal::CrystalPath.default_path, <<-MD
+ Colon-separated paths where the compiler searches for required source files.
+
+ The value is defined by the environment variable `CRYSTAL_PATH`
+ and defaults to `DEFAULT_PATH`.
+ MD
+ define_crystal_string_constant "LIBRARY_PATH", Crystal::CrystalLibraryPath.default_path, <<-MD
+ Colon-separated paths where the compiler searches for (binary) libraries.
+
+ The value is defined by the environment variables `CRYSTAL_LIBRARY_PATH`.
+ MD
+ define_crystal_string_constant "LIBRARY_RPATH", Crystal::CrystalLibraryPath.default_rpath, <<-MD
+ Colon-separated paths where the loader searches for dynamic libraries at runtime.
+
+ The value is defined by the environment variables `CRYSTAL_LIBRARY_RPATH`.
+ MD
+ define_crystal_string_constant "VERSION", Crystal::Config.version, <<-MD
+ The version of the Crystal compiler.
+ MD
+ define_crystal_string_constant "LLVM_VERSION", Crystal::Config.llvm_version, <<-MD
+ The version of LLVM used by the Crystal compiler.
+ MD
+ define_crystal_string_constant "HOST_TRIPLE", Crystal::Config.host_target.to_s, <<-MD
+ The LLVM target triple of the host system (the machine that the compiler runs on).
+ MD
+ define_crystal_string_constant "TARGET_TRIPLE", Crystal::Config.host_target.to_s, <<-MD
+ The LLVM target triple of the target system (the machine that the compiler builds for).
+ MD
+ end
+
+ private def define_crystal_string_constant(name, value, doc = nil)
+ define_crystal_constant name, StringLiteral.new(value).tap(&.set_type(string)), doc
+ end
+
+ private def define_crystal_nil_constant(name, doc = nil)
+ define_crystal_constant name, NilLiteral.new.tap(&.set_type(self.nil)), doc
+ end
+
+ private def define_crystal_constant(name, value, doc = nil) : Const
crystal.types[name] = const = Const.new self, crystal, name, value
const.no_init_flag = true
+ if doc && wants_doc?
+ const.doc = doc
+ end
predefined_constants << const
+ const
end
property(target_machine : LLVM::TargetMachine) { codegen_target.to_target_machine }
diff --git a/src/compiler/crystal/semantic/cleanup_transformer.cr b/src/compiler/crystal/semantic/cleanup_transformer.cr
index ad1b570f0cbd..541e0f51d662 100644
--- a/src/compiler/crystal/semantic/cleanup_transformer.cr
+++ b/src/compiler/crystal/semantic/cleanup_transformer.cr
@@ -256,28 +256,35 @@ module Crystal
end
def transform(node : StringInterpolation)
- string = node.expressions.join do |exp|
- if !(transformed_piece = solve_string_interpolation_expression(exp)).nil?
- # Valid piece, continue joining
- next transformed_piece
- elsif expanded = node.expanded
- # Invalid piece, transform expansion and exit early
- return expanded.transform(self)
- else
- # No expansion, return self
- return node
- end
+ # See if we can solve all the pieces to string literals.
+ # If that's the case, we can replace the entire interpolation
+ # with a single string literal.
+ pieces = node.expressions.dup
+ solve_string_interpolation_expressions(pieces)
+
+ if pieces.all?(StringLiteral)
+ string = pieces.join(&.as(StringLiteral).value)
+ string_literal = StringLiteral.new(string).at(node)
+ string_literal.type = @program.string
+ return string_literal
end
- string_literal = StringLiteral.new(string).at(node)
- string_literal.type = @program.string
- string_literal
+
+ if expanded = node.expanded
+ return expanded.transform(self)
+ end
+ node
end
- # Returns the solved piece for string interpolation, if it can find one.
- # For example, this returns a String when given a StringLiteral.
- private def solve_string_interpolation_expression(piece : ASTNode) : String | Char | Number::Primitive | Bool | Nil
- # Check for ExpandableNode happens first in case any nodes below are
- # updated to be ExpandableNodes themselves.
+ private def solve_string_interpolation_expressions(pieces : Array(ASTNode))
+ pieces.each_with_index do |piece, i|
+ replacement = solve_string_interpolation_expression(piece)
+ next unless replacement
+
+ pieces[i] = replacement
+ end
+ end
+
+ private def solve_string_interpolation_expression(piece : ASTNode) : StringLiteral?
if piece.is_a?(ExpandableNode)
if expanded = piece.expanded
return solve_string_interpolation_expression(expanded)
@@ -287,13 +294,13 @@ module Crystal
case piece
when Path
if target_const = piece.target_const
- solve_string_interpolation_expression(target_const.value)
+ return solve_string_interpolation_expression(target_const.value)
end
- when StringLiteral then piece.value
- when CharLiteral then piece.value
- when NumberLiteral then piece.to_number
- when BoolLiteral then piece.value
+ when StringLiteral
+ return piece
end
+
+ nil
end
def transform(node : ExpandableNode)
@@ -628,10 +635,12 @@ module Crystal
if @a_def.vars.try &.[node.name]?.try &.closured?
@vars << node
end
+ false
end
def visit(node : InstanceVar)
@vars << node
+ false
end
def visit(node : ASTNode)
diff --git a/src/compiler/crystal/semantic/main_visitor.cr b/src/compiler/crystal/semantic/main_visitor.cr
index 37218e7a34dc..61d1aa508a46 100644
--- a/src/compiler/crystal/semantic/main_visitor.cr
+++ b/src/compiler/crystal/semantic/main_visitor.cr
@@ -226,6 +226,8 @@ module Crystal
node.syntax_replacement = type
node.bind_to type
end
+
+ false
end
def visit(node : Generic)
@@ -353,6 +355,7 @@ module Crystal
def visit(node : Self)
node.type = the_self(node).instance_type
+ false
end
def visit(node : Var)
@@ -394,6 +397,7 @@ module Crystal
else
node.raise "read before assignment to local variable '#{node.name}'"
end
+ false
end
def visit(node : TypeDeclaration)
@@ -628,6 +632,8 @@ module Crystal
ivar.nil_reason ||= NilReason.new(node.name, :used_before_initialized, [node] of ASTNode)
ivar.bind_to program.nil_var
end
+
+ false
end
def visit(node : ReadInstanceVar)
@@ -1007,7 +1013,7 @@ module Crystal
end
def visit(node : Block)
- return if node.visited?
+ return false if node.visited?
node.visited = true
node.context = current_non_block_context
@@ -1630,6 +1636,7 @@ module Crystal
ivars[node.name] = node_in_callstack(node)
end
end
+ false
end
def visit(node : Var)
@@ -1761,7 +1768,7 @@ module Crystal
comp.accept self
node.syntax_replacement = comp
node.bind_to comp
- return
+ return false
end
if needs_type_filters? && (var = get_expression_var(node.obj))
@@ -2060,7 +2067,7 @@ module Crystal
unless node.has_breaks?
if endless_while
node.type = program.no_return
- return
+ return false
end
filter_vars TypeFilters.not(cond_type_filters)
@@ -2325,6 +2332,8 @@ module Crystal
else
node.raise "BUG: unhandled primitive in MainVisitor: #{node.name}"
end
+
+ false
end
def visit_va_arg(node)
@@ -3042,31 +3051,38 @@ module Crystal
def visit(node : Nop)
node.type = @program.nil
+ false
end
def visit(node : NilLiteral)
node.type = @program.nil
+ false
end
def visit(node : BoolLiteral)
node.type = program.bool
+ false
end
def visit(node : NumberLiteral)
node.type = program.type_from_literal_kind node.kind
+ false
end
def visit(node : CharLiteral)
node.type = program.char
+ false
end
def visit(node : SymbolLiteral)
node.type = program.symbol
program.symbols.add node.value
+ false
end
def visit(node : StringLiteral)
node.type = program.string
+ false
end
def visit(node : RegexLiteral)
diff --git a/src/compiler/crystal/semantic/restrictions_augmenter.cr b/src/compiler/crystal/semantic/restrictions_augmenter.cr
index a627f27f5fe0..5b3e31056110 100644
--- a/src/compiler/crystal/semantic/restrictions_augmenter.cr
+++ b/src/compiler/crystal/semantic/restrictions_augmenter.cr
@@ -59,7 +59,8 @@ module Crystal
def visit(node : Call)
if expanded = node.expanded
- return expanded.accept self
+ expanded.accept self
+ return false
end
node.obj.try &.accept self
diff --git a/src/compiler/crystal/semantic/to_s.cr b/src/compiler/crystal/semantic/to_s.cr
index 8c91426bc379..13e8203efe1d 100644
--- a/src/compiler/crystal/semantic/to_s.cr
+++ b/src/compiler/crystal/semantic/to_s.cr
@@ -44,14 +44,17 @@ module Crystal
def visit(node : Primitive)
@str << "# primitive: "
@str << node.name
+ false
end
def visit(node : MetaVar)
@str << node.name
+ false
end
def visit(node : MetaMacroVar)
@str << node.name
+ false
end
def visit(node : TypeFilteredNode)
diff --git a/src/compiler/crystal/semantic/top_level_visitor.cr b/src/compiler/crystal/semantic/top_level_visitor.cr
index 5d0cbc477260..98ceb23df6b3 100644
--- a/src/compiler/crystal/semantic/top_level_visitor.cr
+++ b/src/compiler/crystal/semantic/top_level_visitor.cr
@@ -41,6 +41,11 @@ class Crystal::TopLevelVisitor < Crystal::SemanticVisitor
@last_doc : String?
+ # special types recognized for `@[Primitive]`
+ private enum PrimitiveType
+ ReferenceStorageType
+ end
+
def visit(node : ClassDef)
check_outside_exp node, "declare class"
@@ -48,6 +53,27 @@ class Crystal::TopLevelVisitor < Crystal::SemanticVisitor
annotations = read_annotations
+ special_type = nil
+ process_annotations(annotations) do |annotation_type, ann|
+ case annotation_type
+ when @program.primitive_annotation
+ if ann.args.size != 1
+ ann.raise "expected Primitive annotation to have one argument"
+ end
+
+ arg = ann.args.first
+ unless arg.is_a?(SymbolLiteral)
+ arg.raise "expected Primitive argument to be a symbol literal"
+ end
+
+ value = arg.value
+ special_type = PrimitiveType.parse?(value)
+ unless special_type
+ arg.raise "BUG: Unknown primitive type #{value.inspect}"
+ end
+ end
+ end
+
created_new_type = false
if type
@@ -70,14 +96,34 @@ class Crystal::TopLevelVisitor < Crystal::SemanticVisitor
end
else
created_new_type = true
- if type_vars = node.type_vars
- type = GenericClassType.new @program, scope, name, nil, type_vars, false
- type.splat_index = node.splat_index
- else
- type = NonGenericClassType.new @program, scope, name, nil, false
+ case special_type
+ in Nil
+ if type_vars = node.type_vars
+ type = GenericClassType.new @program, scope, name, nil, type_vars, false
+ type.splat_index = node.splat_index
+ else
+ type = NonGenericClassType.new @program, scope, name, nil, false
+ end
+ type.abstract = node.abstract?
+ type.struct = node.struct?
+ in .reference_storage_type?
+ type_vars = node.type_vars
+ case
+ when !node.struct?
+ node.raise "BUG: Expected ReferenceStorageType to be a struct type"
+ when node.abstract?
+ node.raise "BUG: Expected ReferenceStorageType to be a non-abstract type"
+ when !type_vars
+ node.raise "BUG: Expected ReferenceStorageType to be a generic type"
+ when type_vars.size != 1
+ node.raise "BUG: Expected ReferenceStorageType to have a single generic type parameter"
+ when node.splat_index
+ node.raise "BUG: Expected ReferenceStorageType to have no splat parameter"
+ end
+ type = GenericReferenceStorageType.new @program, scope, name, @program.value, type_vars
+ type.declare_instance_var("@type_id", @program.int32)
+ type.can_be_stored = false
end
- type.abstract = node.abstract?
- type.struct = node.struct?
end
type.private = true if node.visibility.private?
@@ -133,6 +179,10 @@ class Crystal::TopLevelVisitor < Crystal::SemanticVisitor
if superclass.struct? && !superclass.abstract?
node.raise "can't extend non-abstract struct #{superclass}"
end
+
+ if type.is_a?(GenericReferenceStorageType) && superclass != @program.value
+ node.raise "BUG: Expected reference_storage_type to inherit from Value"
+ end
end
if created_new_type
@@ -375,7 +425,7 @@ class Crystal::TopLevelVisitor < Crystal::SemanticVisitor
process_def_annotations(node, annotations) do |annotation_type, ann|
if annotation_type == @program.primitive_annotation
- process_primitive_annotation(node, ann)
+ process_def_primitive_annotation(node, ann)
end
node.add_annotation(annotation_type, ann)
@@ -460,7 +510,7 @@ class Crystal::TopLevelVisitor < Crystal::SemanticVisitor
false
end
- private def process_primitive_annotation(node, ann)
+ private def process_def_primitive_annotation(node, ann)
if ann.args.size != 1
ann.raise "expected Primitive annotation to have one argument"
end
@@ -598,6 +648,7 @@ class Crystal::TopLevelVisitor < Crystal::SemanticVisitor
typed_def_type = lookup_type(node.type_spec)
typed_def_type = check_allowed_in_lib node.type_spec, typed_def_type
current_type.types[node.name] = TypeDefType.new @program, current_type, node.name, typed_def_type
+ false
end
end
@@ -655,16 +706,27 @@ class Crystal::TopLevelVisitor < Crystal::SemanticVisitor
if enum_type.flags?
unless enum_type.types.has_key?("None")
- enum_type.add_constant("None", 0)
+ none_member = enum_type.add_constant("None", 0)
+
+ if node_location = node.location
+ none_member.add_location node_location
+ end
+
define_enum_none_question_method(enum_type, node)
end
unless enum_type.types.has_key?("All")
all_value = enum_type.base_type.kind.cast(0).as(Int::Primitive)
+
enum_type.types.each_value do |member|
all_value |= interpret_enum_value(member.as(Const).value, enum_type.base_type)
end
- enum_type.add_constant("All", all_value)
+
+ all_member = enum_type.add_constant("All", all_value)
+
+ if node_location = node.location
+ all_member.add_location node_location
+ end
end
end
@@ -907,13 +969,14 @@ class Crystal::TopLevelVisitor < Crystal::SemanticVisitor
end
external = External.new(node.name, external_args, node.body, node.real_name).at(node)
+ external.name_location = node.name_location
call_convention = nil
process_def_annotations(external, annotations) do |annotation_type, ann|
if annotation_type == @program.call_convention_annotation
call_convention = parse_call_convention(ann, call_convention)
elsif annotation_type == @program.primitive_annotation
- process_primitive_annotation(external, ann)
+ process_def_primitive_annotation(external, ann)
else
ann.raise "funs can only be annotated with: NoInline, AlwaysInline, Naked, ReturnsTwice, Raises, CallConvention"
end
diff --git a/src/compiler/crystal/semantic/type_guess_visitor.cr b/src/compiler/crystal/semantic/type_guess_visitor.cr
index 693cade2906b..612390db8e21 100644
--- a/src/compiler/crystal/semantic/type_guess_visitor.cr
+++ b/src/compiler/crystal/semantic/type_guess_visitor.cr
@@ -86,6 +86,7 @@ module Crystal
end
check_var_is_self(node)
+ false
end
def visit(node : UninitializedVar)
@@ -114,6 +115,7 @@ module Crystal
# TODO: can this be reached?
end
end
+ false
end
def visit(node : Assign)
@@ -1353,6 +1355,7 @@ module Crystal
if node.name == "self"
@has_self = true
end
+ false
end
def visit(node : ASTNode)
diff --git a/src/compiler/crystal/syntax/ast.cr b/src/compiler/crystal/syntax/ast.cr
index d0be18606714..9c0ffcf0d7e5 100644
--- a/src/compiler/crystal/syntax/ast.cr
+++ b/src/compiler/crystal/syntax/ast.cr
@@ -1954,6 +1954,7 @@ module Crystal
property real_name : String
property doc : String?
property? varargs : Bool
+ property name_location : Location?
def initialize(@name, @args = [] of Arg, @return_type = nil, @varargs = false, @body = nil, @real_name = name)
end
@@ -1965,7 +1966,13 @@ module Crystal
end
def clone_without_location
- FunDef.new(@name, @args.clone, @return_type.clone, @varargs, @body.clone, @real_name)
+ clone = FunDef.new(@name, @args.clone, @return_type.clone, @varargs, @body.clone, @real_name)
+ clone.name_location = name_location
+ clone
+ end
+
+ def name_size
+ @name.size
end
def_equals_and_hash @name, @args, @return_type, @varargs, @body, @real_name
diff --git a/src/compiler/crystal/syntax/parser.cr b/src/compiler/crystal/syntax/parser.cr
index 751608468cd5..5d80b28ed20b 100644
--- a/src/compiler/crystal/syntax/parser.cr
+++ b/src/compiler/crystal/syntax/parser.cr
@@ -788,12 +788,6 @@ module Crystal
end
block = parse_block(block, stop_on_do: @stop_on_do)
- if block || block_arg
- if name == "[]="
- raise "setter method '[]=' cannot be called with a block"
- end
- end
-
atomic = Call.new atomic, name, (args || [] of ASTNode), block, block_arg, named_args
atomic.has_parentheses = has_parentheses
atomic.name_location = name_location
@@ -3658,8 +3652,8 @@ module Crystal
end_location = token_end_location
- if name.ends_with?('=')
- if name != "[]=" && (params.size > 1 || found_splat || found_double_splat)
+ if Lexer.setter?(name)
+ if params.size > 1 || found_splat || found_double_splat
raise "setter method '#{name}' cannot have more than one parameter"
elsif found_block
raise "setter method '#{name}' cannot have a block"
@@ -5732,6 +5726,7 @@ module Crystal
with_isolated_var_scope(require_body) do
next_token_skip_space_or_newline
+ name_location = @token.location
name = if top_level
check_ident
else
@@ -5835,6 +5830,7 @@ module Crystal
end
fun_def = FunDef.new name, params, return_type, varargs, body, real_name
+ fun_def.name_location = name_location
fun_def.doc = doc
fun_def.at(location).at_end(end_location)
end
@@ -5852,9 +5848,10 @@ module Crystal
next_token_skip_space_or_newline
value = parse_bare_proc_type
+ end_location = value.end_location
skip_space
- alias_node = Alias.new(name, value)
+ alias_node = Alias.new(name, value).at_end(end_location)
alias_node.doc = doc
alias_node
end
diff --git a/src/compiler/crystal/syntax/to_s.cr b/src/compiler/crystal/syntax/to_s.cr
index 8ea364d3f991..3ea146d15c3e 100644
--- a/src/compiler/crystal/syntax/to_s.cr
+++ b/src/compiler/crystal/syntax/to_s.cr
@@ -28,7 +28,6 @@ module Crystal
def initialize(@str = IO::Memory.new, @macro_expansion_pragmas = nil, @emit_doc = false)
@indent = 0
@inside_macro = 0
- @inside_lib = false
end
def visit_any(node)
@@ -50,10 +49,12 @@ module Crystal
end
def visit(node : Nop)
+ false
end
def visit(node : BoolLiteral)
@str << (node.value ? "true" : "false")
+ false
end
def visit(node : NumberLiteral)
@@ -63,6 +64,8 @@ module Crystal
@str << '_'
@str << node.kind.to_s
end
+
+ false
end
def needs_suffix?(node : NumberLiteral)
@@ -84,10 +87,12 @@ module Crystal
def visit(node : CharLiteral)
node.value.inspect(@str)
+ false
end
def visit(node : SymbolLiteral)
visit_symbol_literal_value node.value
+ false
end
def visit_symbol_literal_value(value : String)
@@ -101,6 +106,7 @@ module Crystal
def visit(node : StringLiteral)
node.value.inspect(@str)
+ false
end
def visit(node : StringInterpolation)
@@ -190,6 +196,7 @@ module Crystal
def visit(node : NilLiteral)
@str << "nil"
+ false
end
def visit(node : Expressions)
@@ -574,6 +581,7 @@ module Crystal
def visit(node : Var)
@str << node.name
+ false
end
def visit(node : ProcLiteral)
@@ -837,35 +845,18 @@ module Crystal
def visit(node : Self)
@str << "self"
+ false
end
def visit(node : Path)
@str << "::" if node.global?
node.names.join(@str, "::")
+ false
end
def visit(node : Generic)
name = node.name
- if @inside_lib && (name.is_a?(Path) && name.names.size == 1)
- case name.names.first
- when "Pointer"
- node.type_vars.first.accept self
- @str << '*'
- return false
- when "StaticArray"
- if node.type_vars.size == 2
- node.type_vars[0].accept self
- @str << '['
- node.type_vars[1].accept self
- @str << ']'
- return false
- end
- else
- # Not a special type
- end
- end
-
node.name.accept self
printed_arg = false
@@ -927,6 +918,7 @@ module Crystal
def visit(node : InstanceVar)
@str << node.name
+ false
end
def visit(node : ReadInstanceVar)
@@ -938,6 +930,7 @@ module Crystal
def visit(node : ClassVar)
@str << node.name
+ false
end
def visit(node : Yield)
@@ -1125,15 +1118,14 @@ module Crystal
def visit(node : Global)
@str << node.name
+ false
end
def visit(node : LibDef)
@str << "lib "
node.name.accept self
newline
- @inside_lib = true
accept_with_indent(node.body)
- @inside_lib = false
append_indent
@str << "end"
false
@@ -1170,7 +1162,6 @@ module Crystal
if body = node.body
newline
accept_with_indent body
- newline
append_indent
@str << "end"
end
@@ -1472,6 +1463,7 @@ module Crystal
def visit(node : MagicConstant)
@str << node.name
+ false
end
def visit(node : Asm)
diff --git a/src/compiler/crystal/tools/expand.cr b/src/compiler/crystal/tools/expand.cr
index 365fc2b3f865..792d60869bd3 100644
--- a/src/compiler/crystal/tools/expand.cr
+++ b/src/compiler/crystal/tools/expand.cr
@@ -144,6 +144,8 @@ module Crystal
else
contains_target(node)
end
+ else
+ false
end
end
@@ -156,6 +158,8 @@ module Crystal
else
contains_target(node)
end
+ else
+ false
end
end
diff --git a/src/compiler/crystal/tools/flags.cr b/src/compiler/crystal/tools/flags.cr
new file mode 100644
index 000000000000..17bb15007021
--- /dev/null
+++ b/src/compiler/crystal/tools/flags.cr
@@ -0,0 +1,104 @@
+require "colorize"
+require "../syntax/ast"
+
+class Crystal::Command
+ private def flags
+ OptionParser.parse(@options) do |opts|
+ opts.banner = "Usage: crystal tool flags [path...]\n\nOptions:"
+
+ opts.on("-h", "--help", "Show this message") do
+ puts opts
+ exit
+ end
+
+ opts.on("--no-color", "Disable colored output") do
+ @color = false
+ end
+ end
+
+ visitor = FlagsVisitor.new
+ find_sources(options) do |source|
+ Parser.parse(source.code).accept(visitor)
+ end
+ visitor.flag_names.each do |flag|
+ puts flag
+ end
+ end
+
+ def find_sources(
+ paths : Array(String),
+ stdin : IO = STDIN,
+ & : Compiler::Source ->
+ ) : Nil
+ stdin_content = nil
+ paths.each do |path|
+ if path == "-"
+ stdin_content ||= stdin.gets_to_end
+ yield Compiler::Source.new(path, stdin_content)
+ elsif File.file?(path)
+ yield Compiler::Source.new(path, File.read(path))
+ elsif Dir.exists?(path)
+ Dir.glob(::Path[path].to_posix.join("**/*.cr")) do |dir_path|
+ if File.file?(dir_path)
+ yield Compiler::Source.new(path, File.read(dir_path))
+ end
+ end
+ else
+ Crystal.error "file or directory does not exist: #{path}", @color, leading_error: false
+ end
+ end
+ end
+
+ class FlagsVisitor < Visitor
+ @in_macro_expression = false
+
+ getter all_flags = [] of ASTNode
+
+ def initialize(@flag_name : String = "flag?")
+ end
+
+ def flag_names
+ all_flags.map { |flag| string_flag(flag) }.uniq!.sort!
+ end
+
+ private def string_flag(node)
+ case node
+ when StringLiteral, SymbolLiteral
+ node.value
+ else
+ node.to_s
+ end
+ end
+
+ def visit(node)
+ true
+ end
+
+ def visit(node : Crystal::MacroExpression | Crystal::MacroIf | Crystal::MacroFor)
+ @in_macro_expression = true
+
+ true
+ end
+
+ def end_visit(node : Crystal::MacroExpression | Crystal::MacroIf | Crystal::MacroFor)
+ @in_macro_expression = false
+ end
+
+ def visit(node : Crystal::Call)
+ check_call(node)
+ true
+ end
+
+ private def check_call(node)
+ return unless @in_macro_expression
+ return unless node.name == @flag_name
+ return unless node.obj.nil? && node.block.nil? && node.named_args.nil?
+
+ args = node.args
+ return unless args.size == 1
+ arg = args[0]
+
+ all_flags << arg
+ end
+ end
+end
diff --git a/src/compiler/crystal/tools/formatter.cr b/src/compiler/crystal/tools/formatter.cr
index fc3be7a4cf66..f7ebf63be7d2 100644
--- a/src/compiler/crystal/tools/formatter.cr
+++ b/src/compiler/crystal/tools/formatter.cr
@@ -4256,7 +4256,7 @@ module Crystal
skip_space_or_newline
end
- write " " unless a_def.args.empty? && !return_type
+ write " " if a_def.args.present? || return_type || flag?("proc_literal_whitespace")
is_do = false
if @token.keyword?(:do)
@@ -4264,6 +4264,7 @@ module Crystal
is_do = true
else
write_token :OP_LCURLY
+ write " " if a_def.body.is_a?(Nop) && flag?("proc_literal_whitespace")
end
skip_space
@@ -4369,6 +4370,7 @@ module Crystal
skip_space
if @token.type.newline?
+ @indent += 2
consume_newlines
has_newlines = true
end
@@ -4377,7 +4379,7 @@ module Crystal
string = StringLiteral.new(node.text)
if has_newlines
- write_indent(@indent + 2, string)
+ write_indent(@indent, string)
else
indent(@column, string)
end
@@ -4385,8 +4387,8 @@ module Crystal
skip_space
if @token.type.newline?
+ consume_newlines
if node.outputs || node.inputs
- consume_newlines
column += 4
write_indent(column)
end
@@ -4418,7 +4420,8 @@ module Crystal
write_token :OP_COLON
part_index += 1
end
- skip_space_or_newline
+ skip_space
+ consume_newlines
case part_index
when 1
@@ -4456,7 +4459,9 @@ module Crystal
skip_space_or_newline
if has_newlines
- write_line
+ @indent -= 2
+
+ write_line unless @wrote_newline
write_indent
end
@@ -4479,7 +4484,12 @@ module Crystal
end
def visit_asm_parts(parts, colon_column, &) : Nil
- write " "
+ if @wrote_newline
+ write_indent
+ else
+ write " "
+ end
+
column = @column
parts.each_with_index do |part, i|
diff --git a/src/compiler/crystal/tools/implementations.cr b/src/compiler/crystal/tools/implementations.cr
index f4f3a390f0eb..e2dbee001346 100644
--- a/src/compiler/crystal/tools/implementations.cr
+++ b/src/compiler/crystal/tools/implementations.cr
@@ -114,6 +114,7 @@ module Crystal
@locations << target_def.location.not_nil!
end
end
+ false
end
def visit(node : Path)
@@ -123,6 +124,7 @@ module Crystal
target.try &.locations.try &.each do |loc|
@locations << loc
end
+ false
end
def visit(node)
diff --git a/src/compiler/crystal/tools/print_types_visitor.cr b/src/compiler/crystal/tools/print_types_visitor.cr
index 6ffc533a4b0f..0744dc17febd 100644
--- a/src/compiler/crystal/tools/print_types_visitor.cr
+++ b/src/compiler/crystal/tools/print_types_visitor.cr
@@ -39,10 +39,12 @@ module Crystal
def visit(node : Var)
output_name node
+ false
end
def visit(node : Global)
output_name node
+ false
end
def visit(node : TypeDeclaration)
@@ -50,6 +52,7 @@ module Crystal
if var.is_a?(Var)
output_name var
end
+ false
end
def visit(node : UninitializedVar)
@@ -57,6 +60,7 @@ module Crystal
if var.is_a?(Var)
output_name var
end
+ false
end
def output_name(node)
diff --git a/src/compiler/crystal/tools/unreachable.cr b/src/compiler/crystal/tools/unreachable.cr
index f89f90e4c37d..a8886fecf596 100644
--- a/src/compiler/crystal/tools/unreachable.cr
+++ b/src/compiler/crystal/tools/unreachable.cr
@@ -15,8 +15,8 @@ module Crystal
unreachable.excludes.concat CrystalPath.default_paths.map { |path| ::Path[path].expand.to_posix.to_s }
unreachable.excludes.concat config.excludes.map { |path| ::Path[path].expand.to_posix.to_s }
- defs = unreachable.process(result)
- defs.sort_by! do |a_def|
+ tallies = unreachable.process(result)
+ tallies.sort_by! do |a_def, _|
location = a_def.location.not_nil!
{
location.filename.as(String),
@@ -25,15 +25,15 @@ module Crystal
}
end
- UnreachablePresenter.new(defs, format: config.output_format).to_s(STDOUT)
+ UnreachablePresenter.new(tallies, format: config.output_format, print_tallies: config.tallies).to_s(STDOUT)
if config.check
- exit 1 unless defs.empty?
+ exit 1 if tallies.any?(&.[1].zero?)
end
end
end
- record UnreachablePresenter, defs : Array(Def), format : String? do
+ record UnreachablePresenter, tallies : Array({Def, Int32}), format : String?, print_tallies : Bool do
include JSON::Serializable
def to_s(io)
@@ -49,16 +49,19 @@ module Crystal
def each(&)
current_dir = Dir.current
- defs.each do |a_def|
+ tallies.each do |a_def, count|
+ next unless print_tallies || count.zero?
+
location = a_def.location.not_nil!
filename = ::Path[location.filename.as(String)].relative_to(current_dir).to_s
location = Location.new(filename, location.line_number, location.column_number)
- yield a_def, location
+ yield a_def, location, count
end
end
def to_text(io)
- each do |a_def, location|
+ each do |a_def, location, count|
+ io << count << "\t" if print_tallies
io << location << "\t"
io << a_def.short_reference << "\t"
io << a_def.length << " lines"
@@ -72,13 +75,14 @@ module Crystal
def to_json(builder : JSON::Builder)
builder.array do
- each do |a_def, location|
+ each do |a_def, location, count|
builder.object do
builder.field "name", a_def.short_reference
builder.field "location", location.to_s
if lines = a_def.length
builder.field "lines", lines
end
+ builder.field "count", count if print_tallies
if annotations = a_def.all_annotations
builder.field "annotations", annotations.map(&.to_s)
end
@@ -89,9 +93,14 @@ module Crystal
def to_csv(io)
CSV.build(io) do |builder|
- builder.row %w[name file line column length annotations]
- each do |a_def, location|
+ builder.row do |row|
+ row << "count" if print_tallies
+ row.concat %w[name file line column length annotations]
+ end
+
+ each do |a_def, location, count|
builder.row do |row|
+ row << count if print_tallies
row << a_def.short_reference
row << location.filename
row << location.line_number
@@ -111,8 +120,8 @@ module Crystal
# Then it traverses all types and their defs and reports those that are not
# in `@used_def_locations` (and match the filter).
class UnreachableVisitor < Visitor
- @used_def_locations = Set(Location).new
- @defs : Set(Def) = Set(Def).new.compare_by_identity
+ @used_def_locations = Hash(Location, Int32).new(0)
+ @tallies : Hash(Def, Int32) = Hash(Def, Int32).new.compare_by_identity
@visited : Set(ASTNode) = Set(ASTNode).new.compare_by_identity
property includes = [] of String
@@ -130,14 +139,14 @@ module Crystal
process_type(type.metaclass) if type.metaclass != type
end
- def process(result : Compiler::Result) : Array(Def)
- @defs.clear
+ def process(result : Compiler::Result) : Array({Def, Int32})
+ @tallies.clear
result.node.accept(self)
process_type(result.program)
- @defs.to_a
+ @tallies.to_a
end
def visit(node)
@@ -163,7 +172,7 @@ module Crystal
node.target_defs.try &.each do |a_def|
if (location = a_def.location)
- @used_def_locations << location if interested_in(location)
+ @used_def_locations.update(location, &.+(1)) if interested_in(location)
end
if @visited.add?(a_def)
@@ -199,11 +208,10 @@ module Crystal
check_def(previous) if previous && !a_def.calls_previous_def?
- return if @used_def_locations.includes?(a_def.location)
-
- check_def(previous) if previous && a_def.calls_previous_def?
+ tally = @used_def_locations[a_def.location]
+ @tallies[a_def] = tally
- @defs << a_def
+ check_def(previous) if previous && a_def.calls_previous_def? && tally == 0
end
private def interested_in(location)
diff --git a/src/compiler/crystal/types.cr b/src/compiler/crystal/types.cr
index ad9f3d391fa6..5d903b763050 100644
--- a/src/compiler/crystal/types.cr
+++ b/src/compiler/crystal/types.cr
@@ -555,7 +555,7 @@ module Crystal
program.tuple, program.named_tuple,
program.pointer, program.static_array,
program.union, program.enum, program.proc,
- PrimitiveType
+ PrimitiveType, GenericReferenceStorageType
false
else
true
@@ -2642,6 +2642,33 @@ module Crystal
end
end
+ # The non-instantiated ReferenceStorage(T) type.
+ class GenericReferenceStorageType < GenericClassType
+ @struct = true
+
+ def new_generic_instance(program, generic_type, type_vars)
+ type_param = self.type_vars.first
+ t = type_vars[type_param].type
+
+ unless t.is_a?(TypeParameter) || (t.class? && !t.struct?)
+ raise TypeException.new "Can't instantiate ReferenceStorage(#{type_param}) with #{type_param} = #{t} (#{type_param} must be a reference type)"
+ end
+
+ ReferenceStorageType.new program, t, self, type_param
+ end
+ end
+
+ class ReferenceStorageType < GenericClassInstanceType
+ getter reference_type : Type
+
+ def initialize(program, @reference_type, generic_type, type_param)
+ t_var = Var.new("T", @reference_type)
+ t_var.bind_to t_var
+
+ super(program, generic_type, program.value, {type_param => t_var} of String => ASTNode)
+ end
+ end
+
# A lib type, like `lib LibC`.
class LibType < ModuleType
getter link_annotations : Array(LinkAnnotation)?
diff --git a/src/crystal/interpreter.cr b/src/crystal/interpreter.cr
index 2a9a6b23c5f8..d3b3589d50cb 100644
--- a/src/crystal/interpreter.cr
+++ b/src/crystal/interpreter.cr
@@ -19,5 +19,10 @@ module Crystal
@[Primitive(:interpreter_spawn)]
def self.spawn(fiber : Fiber, fiber_main : Void*) : Void*
end
+
+ # Returns the resumable value from the interpreter's fiber.
+ @[Primitive(:interpreter_fiber_resumable)]
+ def self.fiber_resumable(context) : LibC::Long
+ end
end
end
diff --git a/src/crystal/lib_iconv.cr b/src/crystal/lib_iconv.cr
index a180a770a67a..5f1506758454 100644
--- a/src/crystal/lib_iconv.cr
+++ b/src/crystal/lib_iconv.cr
@@ -5,6 +5,9 @@ require "c/stddef"
{% end %}
@[Link("iconv")]
+{% if compare_versions(Crystal::VERSION, "1.11.0-dev") >= 0 %}
+ @[Link(dll: "libiconv.dll")]
+{% end %}
lib LibIconv
type IconvT = Void*
diff --git a/src/crystal/scheduler.cr b/src/crystal/scheduler.cr
index ce06e3c60275..1728a9b7f335 100644
--- a/src/crystal/scheduler.cr
+++ b/src/crystal/scheduler.cr
@@ -2,6 +2,7 @@ require "crystal/system/event_loop"
require "crystal/system/print_error"
require "./fiber_channel"
require "fiber"
+require "fiber/stack_pool"
require "crystal/system/thread"
# :nodoc:
@@ -13,6 +14,11 @@ require "crystal/system/thread"
# protected and must never be called directly.
class Crystal::Scheduler
@event_loop = Crystal::EventLoop.create
+ @stack_pool = Fiber::StackPool.new
+
+ def self.stack_pool : Fiber::StackPool
+ Thread.current.scheduler.@stack_pool
+ end
def self.event_loop
Thread.current.scheduler.@event_loop
@@ -83,15 +89,8 @@ class Crystal::Scheduler
{% end %}
end
- {% if flag?(:preview_mt) %}
- def self.enqueue_free_stack(stack : Void*) : Nil
- Thread.current.scheduler.enqueue_free_stack(stack)
- end
- {% end %}
-
{% if flag?(:preview_mt) %}
private getter(fiber_channel : Crystal::FiberChannel) { Crystal::FiberChannel.new }
- @free_stacks = Deque(Void*).new
{% end %}
@main : Fiber
@@ -126,14 +125,6 @@ class Crystal::Scheduler
{% end %}
current, @current = @current, fiber
-
- {% if flag?(:interpreted) %}
- # TODO: ideally we could set this in the interpreter if the
- # @context had a pointer back to the fiber.
- # I also wonder why this isn't done always like that instead of in asm.
- current.@context.resumable = 1
- {% end %}
-
Fiber.swapcontext(pointerof(current.@context), pointerof(fiber.@context))
{% if flag?(:preview_mt) %}
@@ -157,18 +148,6 @@ class Crystal::Scheduler
exit 1
end
- {% if flag?(:preview_mt) %}
- protected def enqueue_free_stack(stack)
- @free_stacks.push stack
- end
-
- private def release_free_stacks
- while stack = @free_stacks.shift?
- Fiber.stack_pool.release stack
- end
- end
- {% end %}
-
protected def reschedule : Nil
loop do
if runnable = @lock.sync { @runnables.shift? }
@@ -178,10 +157,6 @@ class Crystal::Scheduler
@event_loop.run_once
end
end
-
- {% if flag?(:preview_mt) %}
- release_free_stacks
- {% end %}
end
protected def sleep(time : Time::Span) : Nil
@@ -207,6 +182,8 @@ class Crystal::Scheduler
end
def run_loop
+ spawn_stack_pool_collector
+
fiber_channel = self.fiber_channel
loop do
@lock.lock
@@ -239,7 +216,7 @@ class Crystal::Scheduler
@lock.unlock
end
- def self.init_workers
+ def self.init : Nil
count = worker_count
pending = Atomic(Int32).new(count - 1)
@@workers = Array(Thread).new(count) do |i|
@@ -249,7 +226,7 @@ class Crystal::Scheduler
Thread.current.scheduler.enqueue worker_loop
Thread.current
else
- Thread.new do
+ Thread.new(name: "CRYSTAL-MT-#{i}") do
scheduler = Thread.current.scheduler
pending.sub(1)
scheduler.run_loop
@@ -281,5 +258,18 @@ class Crystal::Scheduler
4
end
end
+ {% else %}
+ def self.init : Nil
+ {% unless flag?(:interpreted) %}
+ Thread.current.scheduler.spawn_stack_pool_collector
+ {% end %}
+ end
{% end %}
+
+ # Background loop to cleanup unused fiber stacks.
+ def spawn_stack_pool_collector
+ fiber = Fiber.new(name: "Stack pool collector", &->@stack_pool.collect_loop)
+ {% if flag?(:preview_mt) %} fiber.set_current_thread {% end %}
+ enqueue(fiber)
+ end
end
diff --git a/src/crystal/system/print_error.cr b/src/crystal/system/print_error.cr
index 18f68d923507..3832eed5d9f4 100644
--- a/src/crystal/system/print_error.cr
+++ b/src/crystal/system/print_error.cr
@@ -1,15 +1,152 @@
module Crystal::System
- # Prints directly to stderr without going through an IO.
+ # Prints directly to stderr without going through an `IO::FileDescriptor`.
# This is useful for error messages from components that are required for
# IO to work (fibers, scheduler, event_loop).
def self.print_error(message, *args)
- {% if flag?(:unix) %}
- LibC.dprintf 2, message, *args
- {% elsif flag?(:win32) %}
- buffer = StaticArray(UInt8, 512).new(0_u8)
- len = LibC.snprintf(buffer, buffer.size, message, *args)
- LibC._write 2, buffer, len
- {% end %}
+ print_error(message, *args) do |bytes|
+ {% if flag?(:unix) || flag?(:wasm32) %}
+ LibC.write 2, bytes, bytes.size
+ {% elsif flag?(:win32) %}
+ LibC._write 2, bytes, bytes.size
+ {% end %}
+ end
+ end
+
+ # Minimal drop-in replacement for a C `printf` function. Yields successive
+ # non-empty `Bytes` to the block, which should do the actual printing.
+ #
+ # *format* only supports the `%(l|ll)?[dpsux]` format specifiers; more should
+ # be added only when we need them or an external library passes its own format
+ # string to here. *format* must also be null-terminated.
+ #
+ # Since this method may be called under low memory conditions or even with a
+ # corrupted heap, its implementation should be as low-level as possible,
+ # avoiding memory allocations.
+ #
+ # NOTE: C's `printf` is incompatible with Crystal's `sprintf`, because the
+ # latter does not support argument width specifiers nor `%p`.
+ def self.print_error(format, *args, &)
+ format = to_string_slice(format)
+ format_len = format.size
+ ptr = format.to_unsafe
+ finish = ptr + format_len
+ arg_index = 0
+
+ while ptr < finish
+ next_percent = ptr
+ while next_percent < finish && !(next_percent.value === '%')
+ next_percent += 1
+ end
+ unless next_percent == ptr
+ yield Slice.new(ptr, next_percent - ptr)
+ end
+
+ fmt_ptr = next_percent + 1
+ width = 0
+ if fmt_ptr.value === 'l'
+ width = 1
+ fmt_ptr += 1
+ if fmt_ptr.value === 'l'
+ width = 2
+ fmt_ptr += 1
+ end
+ end
+
+ break unless fmt_ptr < finish
+
+ case fmt_ptr.value
+ when 's'
+ read_arg(String | Pointer(UInt8)) do |arg|
+ yield to_string_slice(arg)
+ end
+ when 'd'
+ read_arg(Int::Primitive) do |arg|
+ to_int_slice(arg, 10, true, width) { |bytes| yield bytes }
+ end
+ when 'u'
+ read_arg(Int::Primitive) do |arg|
+ to_int_slice(arg, 10, false, width) { |bytes| yield bytes }
+ end
+ when 'x'
+ read_arg(Int::Primitive) do |arg|
+ to_int_slice(arg, 16, false, width) { |bytes| yield bytes }
+ end
+ when 'p'
+ read_arg(Pointer(Void)) do |arg|
+ # NOTE: MSVC uses `%X` rather than `0x%x`, we follow the latter on all platforms
+ yield "0x".to_slice
+ to_int_slice(arg.address, 16, false, 2) { |bytes| yield bytes }
+ end
+ else
+ yield Slice.new(next_percent, fmt_ptr + 1 - next_percent)
+ end
+
+ ptr = fmt_ptr + 1
+ end
+ end
+
+ private macro read_arg(type, &block)
+ {{ block.args[0] }} = args[arg_index].as?({{ type }})
+ if !{{ block.args[0] }}.nil?
+ {{ block.body }}
+ else
+ yield "(???)".to_slice
+ end
+ arg_index += 1
+ end
+
+ private def self.to_string_slice(str)
+ if str.is_a?(UInt8*)
+ if str.null?
+ "(null)".to_slice
+ else
+ Slice.new(str, LibC.strlen(str))
+ end
+ else
+ str.to_s.to_slice
+ end
+ end
+
+ # simplified version of `Int#internal_to_s`
+ private def self.to_int_slice(num, base, signed, width, &)
+ if num == 0
+ yield "0".to_slice
+ return
+ end
+
+ # Given sizeof(num) <= 64 bits, we need at most 20 bytes for `%d` or `%u`
+ # note that `chars` does not have to be null-terminated, since we are
+ # only yielding a `Bytes`
+ chars = uninitialized UInt8[20]
+ ptr_end = chars.to_unsafe + 20
+ ptr = ptr_end
+
+ num = case {signed, width}
+ when {true, 2} then LibC::LongLong.new!(num)
+ when {true, 1} then LibC::Long.new!(num)
+ when {true, 0} then LibC::Int.new!(num)
+ when {false, 2} then LibC::ULongLong.new!(num)
+ when {false, 1} then LibC::ULong.new!(num)
+ else LibC::UInt.new!(num)
+ end
+
+ neg = num < 0
+
+ # do not assume Crystal constant initialization succeeds, hence not `DIGITS`
+ digits = "0123456789abcdef".to_unsafe
+
+ while num != 0
+ ptr -= 1
+ ptr.value = digits[num.remainder(base).abs]
+ num = num.tdiv(base)
+ end
+
+ if neg
+ ptr -= 1
+ ptr.value = '-'.ord.to_u8
+ end
+
+ yield Slice.new(ptr, ptr_end - ptr)
end
def self.print_exception(message, ex)
diff --git a/src/crystal/system/signal.cr b/src/crystal/system/signal.cr
index b5ba591b2ec5..a5e3eca885da 100644
--- a/src/crystal/system/signal.cr
+++ b/src/crystal/system/signal.cr
@@ -2,6 +2,9 @@ module Crystal::System::Signal
# Sets the handler for this signal to the passed function.
# def self.trap(signal, handler) : Nil
+ # Returns any existing handler set on the signal
+ # def self.trap_handler?(signal)
+
# Resets the handler for this signal to the OS default.
# def self.reset(signal) : Nil
diff --git a/src/crystal/system/thread.cr b/src/crystal/system/thread.cr
index 88784ed68330..b40a7dceb32b 100644
--- a/src/crystal/system/thread.cr
+++ b/src/crystal/system/thread.cr
@@ -17,6 +17,8 @@ module Crystal::System::Thread
# private def system_close
# private def stack_address : Void*
+
+ # private def system_name=(String) : String
end
{% if flag?(:wasi) %}
@@ -49,12 +51,14 @@ class Thread
# :nodoc:
property previous : Thread?
+ getter name : String?
+
def self.unsafe_each(&)
threads.unsafe_each { |thread| yield thread }
end
# Creates and starts a new system thread.
- def initialize(&@func : ->)
+ def initialize(@name : String? = nil, &@func : ->)
@system_handle = uninitialized Crystal::System::Thread::Handle
init_handle
end
@@ -104,6 +108,12 @@ class Thread
Crystal::System::Thread.yield_current
end
+ # Changes the name of the current thread.
+ def self.name=(name : String) : String
+ thread = Thread.current
+ thread.name = name
+ end
+
# :nodoc:
getter scheduler : Crystal::Scheduler { Crystal::Scheduler.new(self) }
@@ -112,6 +122,10 @@ class Thread
Thread.current = self
@main_fiber = fiber = Fiber.new(stack_address, self)
+ if name = @name
+ self.system_name = name
+ end
+
begin
@func.call
rescue ex
@@ -123,6 +137,10 @@ class Thread
end
end
+ protected def name=(@name : String)
+ self.system_name = name
+ end
+
# Holds the GC thread handler
property gc_thread_handler : Void* = Pointer(Void).null
end
diff --git a/src/crystal/system/unix/fiber.cr b/src/crystal/system/unix/fiber.cr
index 17cbe5c07fdb..2a06b3d3d1a1 100644
--- a/src/crystal/system/unix/fiber.cr
+++ b/src/crystal/system/unix/fiber.cr
@@ -3,7 +3,7 @@ require "c/sys/mman"
module Crystal::System::Fiber
def self.allocate_stack(stack_size) : Void*
flags = LibC::MAP_PRIVATE | LibC::MAP_ANON
- {% if flag?(:openbsd) && !flag?(:"openbsd6.2") %}
+ {% if flag?(:openbsd) %}
flags |= LibC::MAP_STACK
{% end %}
diff --git a/src/crystal/system/unix/pthread.cr b/src/crystal/system/unix/pthread.cr
index ca16080621e3..5d6e2a332adc 100644
--- a/src/crystal/system/unix/pthread.cr
+++ b/src/crystal/system/unix/pthread.cr
@@ -112,6 +112,23 @@ module Crystal::System::Thread
address
end
+
+ # Warning: must be called from the current thread itself, because Darwin
+ # doesn't allow to set the name of any thread but the current one!
+ private def system_name=(name : String) : String
+ {% if flag?(:darwin) %}
+ LibC.pthread_setname_np(name)
+ {% elsif flag?(:netbsd) %}
+ LibC.pthread_setname_np(@system_handle, name, nil)
+ {% elsif LibC.has_method?(:pthread_setname_np) %}
+ LibC.pthread_setname_np(@system_handle, name)
+ {% elsif LibC.has_method?(:pthread_set_name_np) %}
+ LibC.pthread_set_name_np(@system_handle, name)
+ {% else %}
+ {% raise "No `Crystal::System::Thread#system_name` implementation available" %}
+ {% end %}
+ name
+ end
end
# In musl (alpine) the calls to unwind API segfaults
diff --git a/src/crystal/system/unix/signal.cr b/src/crystal/system/unix/signal.cr
index 06422e36f7b6..dfb1c1af8cb8 100644
--- a/src/crystal/system/unix/signal.cr
+++ b/src/crystal/system/unix/signal.cr
@@ -15,7 +15,7 @@ module Crystal::System::Signal
@@pipe = IO.pipe(read_blocking: false, write_blocking: true)
@@handlers = {} of ::Signal => Handler
@@sigset = Sigset.new
- class_setter child_handler : Handler?
+ class_property child_handler : Handler?
@@mutex = Mutex.new(:unchecked)
def self.trap(signal, handler) : Nil
@@ -30,6 +30,10 @@ module Crystal::System::Signal
end
end
+ def self.trap_handler?(signal)
+ @@mutex.synchronize { @@handlers[signal]? }
+ end
+
def self.reset(signal) : Nil
set(signal, LibC::SIG_DFL)
end
@@ -149,7 +153,7 @@ module Crystal::System::Signal
if is_stack_overflow
Crystal::System.print_error "Stack overflow (e.g., infinite or very deep recursion)\n"
else
- Crystal::System.print_error "Invalid memory access (signal %d) at address 0x%lx\n", sig, addr
+ Crystal::System.print_error "Invalid memory access (signal %d) at address %p\n", sig, addr
end
Exception::CallStack.print_backtrace
diff --git a/src/crystal/system/wasi/signal.cr b/src/crystal/system/wasi/signal.cr
index d66b9c22c5cd..35675ce14f34 100644
--- a/src/crystal/system/wasi/signal.cr
+++ b/src/crystal/system/wasi/signal.cr
@@ -3,6 +3,10 @@ module Crystal::System::Signal
raise NotImplementedError.new("Crystal::System::Signal.trap")
end
+ def self.trap_handler?(signal)
+ raise NotImplementedError.new("Crystal::System::Signal.trap_handler?")
+ end
+
def self.reset(signal) : Nil
raise NotImplementedError.new("Crystal::System::Signal.reset")
end
diff --git a/src/crystal/system/win32/file_descriptor.cr b/src/crystal/system/win32/file_descriptor.cr
index 6e4f42d46b17..109c353c0325 100644
--- a/src/crystal/system/win32/file_descriptor.cr
+++ b/src/crystal/system/win32/file_descriptor.cr
@@ -11,7 +11,10 @@ module Crystal::System::FileDescriptor
@system_blocking = true
private def unbuffered_read(slice : Bytes)
- if system_blocking?
+ handle = windows_handle
+ if ConsoleUtils.console?(handle)
+ ConsoleUtils.read(handle, slice)
+ elsif system_blocking?
bytes_read = LibC._read(fd, slice, slice.size)
if bytes_read == -1
if Errno.value == Errno::EBADF
@@ -22,7 +25,6 @@ module Crystal::System::FileDescriptor
end
bytes_read
else
- handle = windows_handle
overlapped_operation(handle, "ReadFile", read_timeout) do |overlapped|
ret = LibC.ReadFile(handle, slice, slice.size, out byte_count, overlapped)
{ret, byte_count}
@@ -276,6 +278,71 @@ module Crystal::System::FileDescriptor
end
end
+private module ConsoleUtils
+ # N UTF-16 code units correspond to no more than 3*N UTF-8 code units.
+ # NOTE: For very large buffers, `ReadConsoleW` may fail.
+ private BUFFER_SIZE = 10000
+ @@utf8_buffer = Slice(UInt8).new(3 * BUFFER_SIZE)
+
+ # `@@buffer` points to part of `@@utf8_buffer`.
+ # It represents data that has not been read yet.
+ @@buffer : Bytes = @@utf8_buffer[0, 0]
+
+ # Remaining UTF-16 code unit.
+ @@remaining_unit : UInt16?
+
+ # Determines if *handle* is a console.
+ def self.console?(handle : LibC::HANDLE) : Bool
+ LibC.GetConsoleMode(handle, out _) != 0
+ end
+
+ # Reads to *slice* from the console specified by *handle*,
+ # and return the actual number of bytes read.
+ def self.read(handle : LibC::HANDLE, slice : Bytes) : Int32
+ return 0 if slice.empty?
+ fill_buffer(handle) if @@buffer.empty?
+
+ bytes_read = {slice.size, @@buffer.size}.min
+ @@buffer[0, bytes_read].copy_to(slice)
+ @@buffer += bytes_read
+ bytes_read
+ end
+
+ private def self.fill_buffer(handle : LibC::HANDLE) : Nil
+ utf16_buffer = uninitialized UInt16[BUFFER_SIZE]
+ remaining_unit = @@remaining_unit
+ if remaining_unit
+ utf16_buffer[0] = remaining_unit
+ index = read_console(handle, utf16_buffer.to_slice + 1)
+ else
+ index = read_console(handle, utf16_buffer.to_slice) - 1
+ end
+
+ if index >= 0 && utf16_buffer[index] & 0xFC00 == 0xD800
+ @@remaining_unit = utf16_buffer[index]
+ index -= 1
+ else
+ @@remaining_unit = nil
+ end
+ return if index < 0
+
+ appender = @@utf8_buffer.to_unsafe.appender
+ String.each_utf16_char(utf16_buffer.to_slice[..index]) do |char|
+ char.each_byte do |byte|
+ appender << byte
+ end
+ end
+ @@buffer = @@utf8_buffer[0, appender.size]
+ end
+
+ private def self.read_console(handle : LibC::HANDLE, slice : Slice(UInt16)) : Int32
+ if 0 == LibC.ReadConsoleW(handle, slice, slice.size, out units_read, nil)
+ raise IO::Error.from_winerror("ReadConsoleW")
+ end
+ units_read.to_i32
+ end
+end
+
# Enable UTF-8 console I/O for the duration of program execution
if LibC.IsValidCodePage(LibC::CP_UTF8) != 0
old_input_cp = LibC.GetConsoleCP
diff --git a/src/crystal/system/win32/path.cr b/src/crystal/system/win32/path.cr
index a5e60db82576..06f9346a2bae 100644
--- a/src/crystal/system/win32/path.cr
+++ b/src/crystal/system/win32/path.cr
@@ -6,12 +6,16 @@ module Crystal::System::Path
def self.home : String
if home_path = ENV["USERPROFILE"]?.presence
home_path
- elsif LibC.SHGetKnownFolderPath(pointerof(LibC::FOLDERID_Profile), 0, nil, out path_ptr) == 0
- home_path, _ = String.from_utf16(path_ptr)
- LibC.CoTaskMemFree(path_ptr)
- home_path
else
- raise RuntimeError.from_winerror("SHGetKnownFolderPath")
+ # TODO: interpreter doesn't implement pointerof(Path)` yet
+ folderid = LibC::FOLDERID_Profile
+ if LibC.SHGetKnownFolderPath(pointerof(folderid), 0, nil, out path_ptr) == 0
+ home_path, _ = String.from_utf16(path_ptr)
+ LibC.CoTaskMemFree(path_ptr)
+ home_path
+ else
+ raise RuntimeError.from_winerror("SHGetKnownFolderPath")
+ end
end
end
end
diff --git a/src/crystal/system/win32/signal.cr b/src/crystal/system/win32/signal.cr
index 8f5541c7599b..d805ea4fd1ab 100644
--- a/src/crystal/system/win32/signal.cr
+++ b/src/crystal/system/win32/signal.cr
@@ -5,6 +5,10 @@ module Crystal::System::Signal
raise NotImplementedError.new("Crystal::System::Signal.trap")
end
+ def self.trap_handler?(signal)
+ raise NotImplementedError.new("Crystal::System::Signal.trap_handler?")
+ end
+
def self.reset(signal) : Nil
raise NotImplementedError.new("Crystal::System::Signal.reset")
end
diff --git a/src/crystal/system/win32/thread.cr b/src/crystal/system/win32/thread.cr
index 9a13bfb4dc03..2b44f66c28ce 100644
--- a/src/crystal/system/win32/thread.cr
+++ b/src/crystal/system/win32/thread.cr
@@ -12,13 +12,24 @@ module Crystal::System::Thread
@system_handle = GC.beginthreadex(
security: Pointer(Void).null,
stack_size: LibC::UInt.zero,
- start_address: ->(data : Void*) { data.as(::Thread).start; LibC::UInt.zero },
+ start_address: ->Thread.thread_proc(Void*),
arglist: self.as(Void*),
initflag: LibC::UInt.zero,
thrdaddr: Pointer(LibC::UInt).null,
)
end
+ def self.thread_proc(data : Void*) : LibC::UInt
+ # ensure that even in the case of stack overflow there is enough reserved
+ # stack space for recovery (for the main thread this is done in
+ # `Exception::CallStack.setup_crash_handler`)
+ stack_size = Crystal::System::Fiber::RESERVED_STACK_SIZE
+ LibC.SetThreadStackGuarantee(pointerof(stack_size))
+
+ data.as(::Thread).start
+ LibC::UInt.zero
+ end
+
def self.current_handle : Handle
# `GetCurrentThread` returns a _constant_ and is only meaningful as an
# argument to Win32 APIs; to uniquely identify it we must duplicate the handle
@@ -61,4 +72,11 @@ module Crystal::System::Thread
low_limit
{% end %}
end
+
+ private def system_name=(name : String) : String
+ {% if LibC.has_method?(:SetThreadDescription) %}
+ LibC.SetThreadDescription(@system_handle, System.to_wstr(name))
+ {% end %}
+ name
+ end
end
diff --git a/src/enumerable.cr b/src/enumerable.cr
index c7b566e647e4..9a1aad3debd0 100644
--- a/src/enumerable.cr
+++ b/src/enumerable.cr
@@ -636,11 +636,7 @@ module Enumerable(T)
h = Hash(U, Array(T)).new
each do |e|
v = yield e
- if h.has_key?(v)
- h[v].push(e)
- else
- h[v] = [e]
- end
+ h.put_if_absent(v) { Array(T).new } << e
end
h
end
@@ -1997,9 +1993,18 @@ module Enumerable(T)
# ```
# (1..5).to_a # => [1, 2, 3, 4, 5]
# ```
- def to_a
- ary = [] of T
- each { |e| ary << e }
+ def to_a : Array(T)
+ to_a(&.itself)
+ end
+
+ # Returns an `Array` with the results of running *block* against each element of the collection.
+ #
+ # ```
+ # (1..5).to_a { |i| i * 2 } # => [2, 4, 6, 8, 10]
+ # ```
+ def to_a(& : T -> U) : Array(U) forall U
+ ary = [] of U
+ each { |e| ary << yield e }
ary
end
diff --git a/src/exception/call_stack/libunwind.cr b/src/exception/call_stack/libunwind.cr
index 220db21b71f0..9f17512491fe 100644
--- a/src/exception/call_stack/libunwind.cr
+++ b/src/exception/call_stack/libunwind.cr
@@ -102,7 +102,7 @@ struct Exception::CallStack
end
private def self.print_frame(repeated_frame)
- Crystal::System.print_error "[0x%llx] ", repeated_frame.ip.address.to_u64
+ Crystal::System.print_error "[%p] ", repeated_frame.ip
print_frame_location(repeated_frame)
Crystal::System.print_error " (%d times)", repeated_frame.count + 1 unless repeated_frame.count == 0
Crystal::System.print_error "\n"
diff --git a/src/exception/call_stack/stackwalk.cr b/src/exception/call_stack/stackwalk.cr
index f49c87fae623..47b78e0ee0df 100644
--- a/src/exception/call_stack/stackwalk.cr
+++ b/src/exception/call_stack/stackwalk.cr
@@ -37,7 +37,7 @@ struct Exception::CallStack
case exception_info.value.exceptionRecord.value.exceptionCode
when LibC::EXCEPTION_ACCESS_VIOLATION
addr = exception_info.value.exceptionRecord.value.exceptionInformation[1]
- Crystal::System.print_error "Invalid memory access (C0000005) at address 0x%llx\n", addr
+ Crystal::System.print_error "Invalid memory access (C0000005) at address %p\n", Pointer(Void).new(addr)
print_backtrace(exception_info)
LibC._exit(1)
when LibC::EXCEPTION_STACK_OVERFLOW
@@ -51,7 +51,8 @@ struct Exception::CallStack
end)
# ensure that even in the case of stack overflow there is enough reserved
- # stack space for recovery
+ # stack space for recovery (for other threads this is done in
+ # `Crystal::System::Thread.thread_proc`)
stack_size = Crystal::System::Fiber::RESERVED_STACK_SIZE
LibC.SetThreadStackGuarantee(pointerof(stack_size))
end
@@ -150,7 +151,7 @@ struct Exception::CallStack
end
private def self.print_frame(repeated_frame)
- Crystal::System.print_error "[0x%llx] ", repeated_frame.ip.address.to_u64
+ Crystal::System.print_error "[%p] ", repeated_frame.ip
print_frame_location(repeated_frame)
Crystal::System.print_error " (%d times)", repeated_frame.count + 1 unless repeated_frame.count == 0
Crystal::System.print_error "\n"
diff --git a/src/fiber.cr b/src/fiber.cr
index aa2af7bf2229..049b7e9bb0c0 100644
--- a/src/fiber.cr
+++ b/src/fiber.cr
@@ -1,6 +1,5 @@
require "crystal/system/thread_linked_list"
require "./fiber/context"
-require "./fiber/stack_pool"
# :nodoc:
@[NoInline]
@@ -47,9 +46,6 @@ class Fiber
# :nodoc:
protected class_getter(fibers) { Thread::LinkedList(Fiber).new }
- # :nodoc:
- class_getter stack_pool = StackPool.new
-
@context : Context
@stack : Void*
@resume_event : Crystal::EventLoop::Event?
@@ -89,10 +85,9 @@ class Fiber
@context = Context.new
@stack, @stack_bottom =
{% if flag?(:interpreted) %}
- # For interpreted mode we don't need a new stack, the stack is held by the interpreter
{Pointer(Void).null, Pointer(Void).null}
{% else %}
- Fiber.stack_pool.checkout
+ Crystal::Scheduler.stack_pool.checkout
{% end %}
fiber_main = ->(f : Fiber) { f.run }
@@ -145,22 +140,22 @@ class Fiber
GC.unlock_read
@proc.call
rescue ex
+ io = {% if flag?(:preview_mt) %}
+ IO::Memory.new(4096) # PIPE_BUF
+ {% else %}
+ STDERR
+ {% end %}
if name = @name
- STDERR.print "Unhandled exception in spawn(name: #{name}): "
+ io << "Unhandled exception in spawn(name: " << name << "): "
else
- STDERR.print "Unhandled exception in spawn: "
+ io << "Unhandled exception in spawn: "
end
- ex.inspect_with_backtrace(STDERR)
- STDERR.flush
- ensure
+ ex.inspect_with_backtrace(io)
{% if flag?(:preview_mt) %}
- Crystal::Scheduler.enqueue_free_stack @stack
- {% elsif flag?(:interpreted) %}
- # For interpreted mode we don't need a new stack, the stack is held by the interpreter
- {% else %}
- Fiber.stack_pool.release(@stack)
+ STDERR.write(io.to_slice)
{% end %}
-
+ STDERR.flush
+ ensure
# Remove the current fiber from the linked list
Fiber.inactive(self)
@@ -170,6 +165,9 @@ class Fiber
@timeout_select_action = nil
@alive = false
+ {% unless flag?(:interpreted) %}
+ Crystal::Scheduler.stack_pool.release(@stack)
+ {% end %}
Crystal::Scheduler.reschedule
end
diff --git a/src/fiber/context.cr b/src/fiber/context.cr
index 28b54458fe66..eab06d886de6 100644
--- a/src/fiber/context.cr
+++ b/src/fiber/context.cr
@@ -7,10 +7,26 @@ class Fiber
@[Extern]
struct Context
property stack_top : Void*
- property resumable : LibC::Long
+
+ {% if flag?(:interpreted) %}
+ # In interpreted mode, the interpreted fibers will be backed by a real
+ # fiber run by the interpreter. The fiber context is thus fake.
+ #
+ # The `stack_top` property is actually a pointer to the real Fiber
+ # running in the interpreter.
+ #
+ # The `resumable` property is also delegated to the real fiber. Only the
+ # getter is defined (so we know the real state of the fiber); we don't
+ # declare a setter because only the interpreter can manipulate it (in the
+ # `makecontext` and `swapcontext` primitives).
+ def resumable : LibC::Long
+ Crystal::Interpreter.fiber_resumable(pointerof(@stack_top))
+ end
+ {% else %}
+ property resumable : LibC::Long = 0
+ {% end %}
def initialize(@stack_top = Pointer(Void).null)
- @resumable = 0
end
end
diff --git a/src/fiber/context/interpreted.cr b/src/fiber/context/interpreted.cr
index 55b9354a1a57..900ad6f3111c 100644
--- a/src/fiber/context/interpreted.cr
+++ b/src/fiber/context/interpreted.cr
@@ -5,9 +5,9 @@ require "crystal/interpreter"
class Fiber
# :nodoc:
def makecontext(stack_ptr, fiber_main) : Nil
- # In interpreted mode the stack_top variable actually points to a fiber
+ # In interpreted mode the stack_top variable actually points to the actual
+ # fiber running on the interpreter
@context.stack_top = Crystal::Interpreter.spawn(self, fiber_main.pointer)
- @context.resumable = 1
end
# :nodoc:
diff --git a/src/fiber/stack_pool.cr b/src/fiber/stack_pool.cr
index 54d03e4ffa5f..aebd82a0870f 100644
--- a/src/fiber/stack_pool.cr
+++ b/src/fiber/stack_pool.cr
@@ -7,14 +7,13 @@ class Fiber
def initialize
@deque = Deque(Void*).new
- @mutex = Thread::Mutex.new
end
# Removes and frees at most *count* stacks from the top of the pool,
# returning memory to the operating system.
def collect(count = lazy_size // 2) : Nil
count.times do
- if stack = @mutex.synchronize { @deque.shift? }
+ if stack = @deque.shift?
Crystal::System::Fiber.free_stack(stack, STACK_SIZE)
else
return
@@ -22,21 +21,28 @@ class Fiber
end
end
+ def collect_loop(every = 5.seconds) : Nil
+ loop do
+ sleep every
+ collect
+ end
+ end
+
# Removes a stack from the bottom of the pool, or allocates a new one.
def checkout : {Void*, Void*}
- stack = @mutex.synchronize { @deque.pop? } || Crystal::System::Fiber.allocate_stack(STACK_SIZE)
+ stack = @deque.pop? || Crystal::System::Fiber.allocate_stack(STACK_SIZE)
{stack, stack + STACK_SIZE}
end
# Appends a stack to the bottom of the pool.
def release(stack) : Nil
- @mutex.synchronize { @deque.push(stack) }
+ @deque.push(stack)
end
# Returns the approximated size of the pool. It may be equal or slightly
# bigger or smaller than the actual size.
def lazy_size : Int32
- @mutex.synchronize { @deque.size }
+ @deque.size
end
end
end
diff --git a/src/float/printer/ryu_printf.cr b/src/float/printer/ryu_printf.cr
index d44a2fa8739b..feffb98fdb0e 100644
--- a/src/float/printer/ryu_printf.cr
+++ b/src/float/printer/ryu_printf.cr
@@ -1,5 +1,4 @@
-# FIXME: this leads to an OOB on wasm32 (#13918)
-{% skip_file if flag?(:wasm32) %}
+{% skip_file unless String::Formatter::HAS_RYU_PRINTF %}
require "./ryu_printf_table"
@@ -613,6 +612,76 @@ module Float::Printer::RyuPrintf
index
end
+ private MAX_FIXED_PRECISION = 66_u32
+ private MAX_SCI_PRECISION = 766_u32
+
+ # Source port of Microsoft STL's `std::to_chars` based on:
+ #
+ # * https://github.com/ulfjack/ryu/pull/185/files
+ # * https://github.com/microsoft/STL/blob/a8888806c6960f1687590ffd4244794c753aa819/stl/inc/charconv#L2324
+ # * https://github.com/llvm/llvm-project/blob/701f64790520790f75b1f948a752472d421ddaa3/libcxx/src/include/to_chars_floating_point.h#L836
+ def self.d2gen_buffered_n(d : Float64, precision : UInt32, result : UInt8*, alternative : Bool = false)
+ if d == 0
+ result[0] = '0'.ord.to_u8!
+ return {1, 0}
+ end
+
+ precision = precision.clamp(1_u32, 1000000_u32)
+ if precision <= MAX_SPECIAL_P
+ table_begin = SPECIAL_X.to_unsafe + (precision &- 1) * (precision &+ 10) // 2
+ table_length = precision.to_i32! &+ 5
+ else
+ table_begin = ORDINARY_X.to_unsafe
+ table_length = {precision, MAX_ORDINARY_P}.min.to_i32! &+ 5
+ end
+
+ bits = d.unsafe_as(UInt64)
+ index = 0
+ while index < table_length
+ break if bits <= table_begin[index]
+ index &+= 1
+ end
+
+ sci_exp_x = index &- 5
+ use_fixed_notation = precision > sci_exp_x && sci_exp_x >= -4
+
+ significand_last = exponent_first = exponent_last = Pointer(UInt8).null
+
+ # Write into the local buffer.
+ if use_fixed_notation
+ effective_precision = precision &- 1 &- sci_exp_x
+ max_precision = MAX_FIXED_PRECISION
+ len = d2fixed_buffered_n(d, {effective_precision, max_precision}.min, result)
+ significand_last = result + len
+ else
+ effective_precision = precision &- 1
+ max_precision = MAX_SCI_PRECISION
+ len = d2exp_buffered_n(d, {effective_precision, max_precision}.min, result)
+ exponent_first = result + Slice.new(result, len).fast_index('e'.ord.to_u8!, 0).not_nil!
+ significand_last = exponent_first
+ exponent_last = result + len
+ end
+
+ # If we printed a decimal point followed by digits, perform zero-trimming.
+ if effective_precision > 0 && !alternative
+ while significand_last[-1] === '0' # will stop at '.' or a nonzero digit
+ significand_last -= 1
+ end
+
+ if significand_last[-1] === '.'
+ significand_last -= 1
+ end
+ end
+
+ # Copy the exponent to the output range.
+ unless use_fixed_notation
+ exponent_first.move_to(significand_last, exponent_last - exponent_first)
+ end
+
+ extra_zeros = effective_precision > max_precision ? effective_precision &- max_precision : 0_u32
+ {(significand_last - result + (exponent_last - exponent_first)).to_i32!, extra_zeros.to_i32!}
+ end
+
def self.d2fixed(d : Float64, precision : Int)
String.new(2000) do |buffer|
len = d2fixed_buffered_n(d, precision.to_u32, buffer)
@@ -626,4 +695,11 @@ module Float::Printer::RyuPrintf
{len, len}
end
end
+
+ def self.d2gen(d : Float64, precision : Int)
+ String.new(773) do |buffer|
+ len, _ = d2gen_buffered_n(d, precision.to_u32, buffer)
+ {len, len}
+ end
+ end
end
diff --git a/src/float/printer/ryu_printf_table.cr b/src/float/printer/ryu_printf_table.cr
index dc733c492991..b9db3363f072 100644
--- a/src/float/printer/ryu_printf_table.cr
+++ b/src/float/printer/ryu_printf_table.cr
@@ -1,5 +1,4 @@
-# FIXME: this leads to an OOB on wasm32 (#13918)
-{% skip_file if flag?(:wasm32) %}
+{% skip_file unless String::Formatter::HAS_RYU_PRINTF %}
module Float::Printer::RyuPrintf
{% begin %}
@@ -16,6 +15,533 @@ module Float::Printer::RyuPrintf
array << values
end
+ # Special constants for `%g` formatting; for details refer to
+ # https://github.com/ulfjack/ryu/pull/185/files or
+ # https://github.com/microsoft/STL/blob/a8888806c6960f1687590ffd4244794c753aa819/stl/inc/xcharconv_tables.h
+
+ private MAX_SPECIAL_P = 15_u32
+
+ private SPECIAL_X = begin
+ data = Array(UInt64).new(195)
+ put(data, 0x3F18E757928E0C9Du64)
+ put(data, 0x3F4F212D77318FC5u64)
+ put(data, 0x3F8374BC6A7EF9DBu64)
+ put(data, 0x3FB851EB851EB851u64)
+ put(data, 0x3FEE666666666666u64)
+ put(data, 0x4022FFFFFFFFFFFFu64)
+ put(data, 0x3F1A1554FBDAD751u64)
+ put(data, 0x3F504D551D68C692u64)
+ put(data, 0x3F8460AA64C2F837u64)
+ put(data, 0x3FB978D4FDF3B645u64)
+ put(data, 0x3FEFD70A3D70A3D7u64)
+ put(data, 0x4023E66666666666u64)
+ put(data, 0x4058DFFFFFFFFFFFu64)
+ put(data, 0x3F1A3387ECC8EB96u64)
+ put(data, 0x3F506034F3FD933Eu64)
+ put(data, 0x3F84784230FCF80Du64)
+ put(data, 0x3FB99652BD3C3611u64)
+ put(data, 0x3FEFFBE76C8B4395u64)
+ put(data, 0x4023FD70A3D70A3Du64)
+ put(data, 0x4058FCCCCCCCCCCCu64)
+ put(data, 0x408F3BFFFFFFFFFFu64)
+ put(data, 0x3F1A368D04E0BA6Au64)
+ put(data, 0x3F506218230C7482u64)
+ put(data, 0x3F847A9E2BCF91A3u64)
+ put(data, 0x3FB99945B6C3760Bu64)
+ put(data, 0x3FEFFF972474538Eu64)
+ put(data, 0x4023FFBE76C8B439u64)
+ put(data, 0x4058FFAE147AE147u64)
+ put(data, 0x408F3F9999999999u64)
+ put(data, 0x40C387BFFFFFFFFFu64)
+ put(data, 0x3F1A36DA54164F19u64)
+ put(data, 0x3F506248748DF16Fu64)
+ put(data, 0x3F847ADA91B16DCBu64)
+ put(data, 0x3FB99991361DC93Eu64)
+ put(data, 0x3FEFFFF583A53B8Eu64)
+ put(data, 0x4023FFF972474538u64)
+ put(data, 0x4058FFF7CED91687u64)
+ put(data, 0x408F3FF5C28F5C28u64)
+ put(data, 0x40C387F999999999u64)
+ put(data, 0x40F869F7FFFFFFFFu64)
+ put(data, 0x3F1A36E20F35445Du64)
+ put(data, 0x3F50624D49814ABAu64)
+ put(data, 0x3F847AE09BE19D69u64)
+ put(data, 0x3FB99998C2DA04C3u64)
+ put(data, 0x3FEFFFFEF39085F4u64)
+ put(data, 0x4023FFFF583A53B8u64)
+ put(data, 0x4058FFFF2E48E8A7u64)
+ put(data, 0x408F3FFEF9DB22D0u64)
+ put(data, 0x40C387FF5C28F5C2u64)
+ put(data, 0x40F869FF33333333u64)
+ put(data, 0x412E847EFFFFFFFFu64)
+ put(data, 0x3F1A36E2D51EC34Bu64)
+ put(data, 0x3F50624DC5333A0Eu64)
+ put(data, 0x3F847AE136800892u64)
+ put(data, 0x3FB9999984200AB7u64)
+ put(data, 0x3FEFFFFFE5280D65u64)
+ put(data, 0x4023FFFFEF39085Fu64)
+ put(data, 0x4058FFFFEB074A77u64)
+ put(data, 0x408F3FFFE5C91D14u64)
+ put(data, 0x40C387FFEF9DB22Du64)
+ put(data, 0x40F869FFEB851EB8u64)
+ put(data, 0x412E847FE6666666u64)
+ put(data, 0x416312CFEFFFFFFFu64)
+ put(data, 0x3F1A36E2E8E94FFCu64)
+ put(data, 0x3F50624DD191D1FDu64)
+ put(data, 0x3F847AE145F6467Du64)
+ put(data, 0x3FB999999773D81Cu64)
+ put(data, 0x3FEFFFFFFD50CE23u64)
+ put(data, 0x4023FFFFFE5280D6u64)
+ put(data, 0x4058FFFFFDE7210Bu64)
+ put(data, 0x408F3FFFFD60E94Eu64)
+ put(data, 0x40C387FFFE5C91D1u64)
+ put(data, 0x40F869FFFDF3B645u64)
+ put(data, 0x412E847FFD70A3D7u64)
+ put(data, 0x416312CFFE666666u64)
+ put(data, 0x4197D783FDFFFFFFu64)
+ put(data, 0x3F1A36E2EAE3F7A7u64)
+ put(data, 0x3F50624DD2CE7AC8u64)
+ put(data, 0x3F847AE14782197Bu64)
+ put(data, 0x3FB9999999629FD9u64)
+ put(data, 0x3FEFFFFFFFBB47D0u64)
+ put(data, 0x4023FFFFFFD50CE2u64)
+ put(data, 0x4058FFFFFFCA501Au64)
+ put(data, 0x408F3FFFFFBCE421u64)
+ put(data, 0x40C387FFFFD60E94u64)
+ put(data, 0x40F869FFFFCB923Au64)
+ put(data, 0x412E847FFFBE76C8u64)
+ put(data, 0x416312CFFFD70A3Du64)
+ put(data, 0x4197D783FFCCCCCCu64)
+ put(data, 0x41CDCD64FFBFFFFFu64)
+ put(data, 0x3F1A36E2EB16A205u64)
+ put(data, 0x3F50624DD2EE2543u64)
+ put(data, 0x3F847AE147A9AE94u64)
+ put(data, 0x3FB9999999941A39u64)
+ put(data, 0x3FEFFFFFFFF920C8u64)
+ put(data, 0x4023FFFFFFFBB47Du64)
+ put(data, 0x4058FFFFFFFAA19Cu64)
+ put(data, 0x408F3FFFFFF94A03u64)
+ put(data, 0x40C387FFFFFBCE42u64)
+ put(data, 0x40F869FFFFFAC1D2u64)
+ put(data, 0x412E847FFFF97247u64)
+ put(data, 0x416312CFFFFBE76Cu64)
+ put(data, 0x4197D783FFFAE147u64)
+ put(data, 0x41CDCD64FFF99999u64)
+ put(data, 0x4202A05F1FFBFFFFu64)
+ put(data, 0x3F1A36E2EB1BB30Fu64)
+ put(data, 0x3F50624DD2F14FE9u64)
+ put(data, 0x3F847AE147ADA3E3u64)
+ put(data, 0x3FB9999999990CDCu64)
+ put(data, 0x3FEFFFFFFFFF5014u64)
+ put(data, 0x4023FFFFFFFF920Cu64)
+ put(data, 0x4058FFFFFFFF768Fu64)
+ put(data, 0x408F3FFFFFFF5433u64)
+ put(data, 0x40C387FFFFFF94A0u64)
+ put(data, 0x40F869FFFFFF79C8u64)
+ put(data, 0x412E847FFFFF583Au64)
+ put(data, 0x416312CFFFFF9724u64)
+ put(data, 0x4197D783FFFF7CEDu64)
+ put(data, 0x41CDCD64FFFF5C28u64)
+ put(data, 0x4202A05F1FFF9999u64)
+ put(data, 0x42374876E7FF7FFFu64)
+ put(data, 0x3F1A36E2EB1C34C3u64)
+ put(data, 0x3F50624DD2F1A0FAu64)
+ put(data, 0x3F847AE147AE0938u64)
+ put(data, 0x3FB9999999998B86u64)
+ put(data, 0x3FEFFFFFFFFFEE68u64)
+ put(data, 0x4023FFFFFFFFF501u64)
+ put(data, 0x4058FFFFFFFFF241u64)
+ put(data, 0x408F3FFFFFFFEED1u64)
+ put(data, 0x40C387FFFFFFF543u64)
+ put(data, 0x40F869FFFFFFF294u64)
+ put(data, 0x412E847FFFFFEF39u64)
+ put(data, 0x416312CFFFFFF583u64)
+ put(data, 0x4197D783FFFFF2E4u64)
+ put(data, 0x41CDCD64FFFFEF9Du64)
+ put(data, 0x4202A05F1FFFF5C2u64)
+ put(data, 0x42374876E7FFF333u64)
+ put(data, 0x426D1A94A1FFEFFFu64)
+ put(data, 0x3F1A36E2EB1C41BBu64)
+ put(data, 0x3F50624DD2F1A915u64)
+ put(data, 0x3F847AE147AE135Au64)
+ put(data, 0x3FB9999999999831u64)
+ put(data, 0x3FEFFFFFFFFFFE3Du64)
+ put(data, 0x4023FFFFFFFFFEE6u64)
+ put(data, 0x4058FFFFFFFFFEA0u64)
+ put(data, 0x408F3FFFFFFFFE48u64)
+ put(data, 0x40C387FFFFFFFEEDu64)
+ put(data, 0x40F869FFFFFFFEA8u64)
+ put(data, 0x412E847FFFFFFE52u64)
+ put(data, 0x416312CFFFFFFEF3u64)
+ put(data, 0x4197D783FFFFFEB0u64)
+ put(data, 0x41CDCD64FFFFFE5Cu64)
+ put(data, 0x4202A05F1FFFFEF9u64)
+ put(data, 0x42374876E7FFFEB8u64)
+ put(data, 0x426D1A94A1FFFE66u64)
+ put(data, 0x42A2309CE53FFEFFu64)
+ put(data, 0x3F1A36E2EB1C4307u64)
+ put(data, 0x3F50624DD2F1A9E4u64)
+ put(data, 0x3F847AE147AE145Eu64)
+ put(data, 0x3FB9999999999975u64)
+ put(data, 0x3FEFFFFFFFFFFFD2u64)
+ put(data, 0x4023FFFFFFFFFFE3u64)
+ put(data, 0x4058FFFFFFFFFFDCu64)
+ put(data, 0x408F3FFFFFFFFFD4u64)
+ put(data, 0x40C387FFFFFFFFE4u64)
+ put(data, 0x40F869FFFFFFFFDDu64)
+ put(data, 0x412E847FFFFFFFD5u64)
+ put(data, 0x416312CFFFFFFFE5u64)
+ put(data, 0x4197D783FFFFFFDEu64)
+ put(data, 0x41CDCD64FFFFFFD6u64)
+ put(data, 0x4202A05F1FFFFFE5u64)
+ put(data, 0x42374876E7FFFFDFu64)
+ put(data, 0x426D1A94A1FFFFD7u64)
+ put(data, 0x42A2309CE53FFFE6u64)
+ put(data, 0x42D6BCC41E8FFFDFu64)
+ put(data, 0x3F1A36E2EB1C4328u64)
+ put(data, 0x3F50624DD2F1A9F9u64)
+ put(data, 0x3F847AE147AE1477u64)
+ put(data, 0x3FB9999999999995u64)
+ put(data, 0x3FEFFFFFFFFFFFFBu64)
+ put(data, 0x4023FFFFFFFFFFFDu64)
+ put(data, 0x4058FFFFFFFFFFFCu64)
+ put(data, 0x408F3FFFFFFFFFFBu64)
+ put(data, 0x40C387FFFFFFFFFDu64)
+ put(data, 0x40F869FFFFFFFFFCu64)
+ put(data, 0x412E847FFFFFFFFBu64)
+ put(data, 0x416312CFFFFFFFFDu64)
+ put(data, 0x4197D783FFFFFFFCu64)
+ put(data, 0x41CDCD64FFFFFFFBu64)
+ put(data, 0x4202A05F1FFFFFFDu64)
+ put(data, 0x42374876E7FFFFFCu64)
+ put(data, 0x426D1A94A1FFFFFBu64)
+ put(data, 0x42A2309CE53FFFFDu64)
+ put(data, 0x42D6BCC41E8FFFFCu64)
+ put(data, 0x430C6BF52633FFFBu64)
+ data
+ end
+
+ private MAX_ORDINARY_P = 309_u32
+
+ private ORDINARY_X = begin
+ data = Array(UInt64).new(314)
+ put(data, 0x3F1A36E2EB1C432Cu64)
+ put(data, 0x3F50624DD2F1A9FBu64)
+ put(data, 0x3F847AE147AE147Au64)
+ put(data, 0x3FB9999999999999u64)
+ put(data, 0x3FEFFFFFFFFFFFFFu64)
+ put(data, 0x4023FFFFFFFFFFFFu64)
+ put(data, 0x4058FFFFFFFFFFFFu64)
+ put(data, 0x408F3FFFFFFFFFFFu64)
+ put(data, 0x40C387FFFFFFFFFFu64)
+ put(data, 0x40F869FFFFFFFFFFu64)
+ put(data, 0x412E847FFFFFFFFFu64)
+ put(data, 0x416312CFFFFFFFFFu64)
+ put(data, 0x4197D783FFFFFFFFu64)
+ put(data, 0x41CDCD64FFFFFFFFu64)
+ put(data, 0x4202A05F1FFFFFFFu64)
+ put(data, 0x42374876E7FFFFFFu64)
+ put(data, 0x426D1A94A1FFFFFFu64)
+ put(data, 0x42A2309CE53FFFFFu64)
+ put(data, 0x42D6BCC41E8FFFFFu64)
+ put(data, 0x430C6BF52633FFFFu64)
+ put(data, 0x4341C37937E07FFFu64)
+ put(data, 0x4376345785D89FFFu64)
+ put(data, 0x43ABC16D674EC7FFu64)
+ put(data, 0x43E158E460913CFFu64)
+ put(data, 0x4415AF1D78B58C3Fu64)
+ put(data, 0x444B1AE4D6E2EF4Fu64)
+ put(data, 0x4480F0CF064DD591u64)
+ put(data, 0x44B52D02C7E14AF6u64)
+ put(data, 0x44EA784379D99DB4u64)
+ put(data, 0x45208B2A2C280290u64)
+ put(data, 0x4554ADF4B7320334u64)
+ put(data, 0x4589D971E4FE8401u64)
+ put(data, 0x45C027E72F1F1281u64)
+ put(data, 0x45F431E0FAE6D721u64)
+ put(data, 0x46293E5939A08CE9u64)
+ put(data, 0x465F8DEF8808B024u64)
+ put(data, 0x4693B8B5B5056E16u64)
+ put(data, 0x46C8A6E32246C99Cu64)
+ put(data, 0x46FED09BEAD87C03u64)
+ put(data, 0x4733426172C74D82u64)
+ put(data, 0x476812F9CF7920E2u64)
+ put(data, 0x479E17B84357691Bu64)
+ put(data, 0x47D2CED32A16A1B1u64)
+ put(data, 0x48078287F49C4A1Du64)
+ put(data, 0x483D6329F1C35CA4u64)
+ put(data, 0x48725DFA371A19E6u64)
+ put(data, 0x48A6F578C4E0A060u64)
+ put(data, 0x48DCB2D6F618C878u64)
+ put(data, 0x4911EFC659CF7D4Bu64)
+ put(data, 0x49466BB7F0435C9Eu64)
+ put(data, 0x497C06A5EC5433C6u64)
+ put(data, 0x49B18427B3B4A05Bu64)
+ put(data, 0x49E5E531A0A1C872u64)
+ put(data, 0x4A1B5E7E08CA3A8Fu64)
+ put(data, 0x4A511B0EC57E6499u64)
+ put(data, 0x4A8561D276DDFDC0u64)
+ put(data, 0x4ABABA4714957D30u64)
+ put(data, 0x4AF0B46C6CDD6E3Eu64)
+ put(data, 0x4B24E1878814C9CDu64)
+ put(data, 0x4B5A19E96A19FC40u64)
+ put(data, 0x4B905031E2503DA8u64)
+ put(data, 0x4BC4643E5AE44D12u64)
+ put(data, 0x4BF97D4DF19D6057u64)
+ put(data, 0x4C2FDCA16E04B86Du64)
+ put(data, 0x4C63E9E4E4C2F344u64)
+ put(data, 0x4C98E45E1DF3B015u64)
+ put(data, 0x4CCF1D75A5709C1Au64)
+ put(data, 0x4D03726987666190u64)
+ put(data, 0x4D384F03E93FF9F4u64)
+ put(data, 0x4D6E62C4E38FF872u64)
+ put(data, 0x4DA2FDBB0E39FB47u64)
+ put(data, 0x4DD7BD29D1C87A19u64)
+ put(data, 0x4E0DAC74463A989Fu64)
+ put(data, 0x4E428BC8ABE49F63u64)
+ put(data, 0x4E772EBAD6DDC73Cu64)
+ put(data, 0x4EACFA698C95390Bu64)
+ put(data, 0x4EE21C81F7DD43A7u64)
+ put(data, 0x4F16A3A275D49491u64)
+ put(data, 0x4F4C4C8B1349B9B5u64)
+ put(data, 0x4F81AFD6EC0E1411u64)
+ put(data, 0x4FB61BCCA7119915u64)
+ put(data, 0x4FEBA2BFD0D5FF5Bu64)
+ put(data, 0x502145B7E285BF98u64)
+ put(data, 0x50559725DB272F7Fu64)
+ put(data, 0x508AFCEF51F0FB5Eu64)
+ put(data, 0x50C0DE1593369D1Bu64)
+ put(data, 0x50F5159AF8044462u64)
+ put(data, 0x512A5B01B605557Au64)
+ put(data, 0x516078E111C3556Cu64)
+ put(data, 0x5194971956342AC7u64)
+ put(data, 0x51C9BCDFABC13579u64)
+ put(data, 0x5200160BCB58C16Cu64)
+ put(data, 0x52341B8EBE2EF1C7u64)
+ put(data, 0x526922726DBAAE39u64)
+ put(data, 0x529F6B0F092959C7u64)
+ put(data, 0x52D3A2E965B9D81Cu64)
+ put(data, 0x53088BA3BF284E23u64)
+ put(data, 0x533EAE8CAEF261ACu64)
+ put(data, 0x53732D17ED577D0Bu64)
+ put(data, 0x53A7F85DE8AD5C4Eu64)
+ put(data, 0x53DDF67562D8B362u64)
+ put(data, 0x5412BA095DC7701Du64)
+ put(data, 0x5447688BB5394C25u64)
+ put(data, 0x547D42AEA2879F2Eu64)
+ put(data, 0x54B249AD2594C37Cu64)
+ put(data, 0x54E6DC186EF9F45Cu64)
+ put(data, 0x551C931E8AB87173u64)
+ put(data, 0x5551DBF316B346E7u64)
+ put(data, 0x558652EFDC6018A1u64)
+ put(data, 0x55BBE7ABD3781ECAu64)
+ put(data, 0x55F170CB642B133Eu64)
+ put(data, 0x5625CCFE3D35D80Eu64)
+ put(data, 0x565B403DCC834E11u64)
+ put(data, 0x569108269FD210CBu64)
+ put(data, 0x56C54A3047C694FDu64)
+ put(data, 0x56FA9CBC59B83A3Du64)
+ put(data, 0x5730A1F5B8132466u64)
+ put(data, 0x5764CA732617ED7Fu64)
+ put(data, 0x5799FD0FEF9DE8DFu64)
+ put(data, 0x57D03E29F5C2B18Bu64)
+ put(data, 0x58044DB473335DEEu64)
+ put(data, 0x583961219000356Au64)
+ put(data, 0x586FB969F40042C5u64)
+ put(data, 0x58A3D3E2388029BBu64)
+ put(data, 0x58D8C8DAC6A0342Au64)
+ put(data, 0x590EFB1178484134u64)
+ put(data, 0x59435CEAEB2D28C0u64)
+ put(data, 0x59783425A5F872F1u64)
+ put(data, 0x59AE412F0F768FADu64)
+ put(data, 0x59E2E8BD69AA19CCu64)
+ put(data, 0x5A17A2ECC414A03Fu64)
+ put(data, 0x5A4D8BA7F519C84Fu64)
+ put(data, 0x5A827748F9301D31u64)
+ put(data, 0x5AB7151B377C247Eu64)
+ put(data, 0x5AECDA62055B2D9Du64)
+ put(data, 0x5B22087D4358FC82u64)
+ put(data, 0x5B568A9C942F3BA3u64)
+ put(data, 0x5B8C2D43B93B0A8Bu64)
+ put(data, 0x5BC19C4A53C4E697u64)
+ put(data, 0x5BF6035CE8B6203Du64)
+ put(data, 0x5C2B843422E3A84Cu64)
+ put(data, 0x5C6132A095CE492Fu64)
+ put(data, 0x5C957F48BB41DB7Bu64)
+ put(data, 0x5CCADF1AEA12525Au64)
+ put(data, 0x5D00CB70D24B7378u64)
+ put(data, 0x5D34FE4D06DE5056u64)
+ put(data, 0x5D6A3DE04895E46Cu64)
+ put(data, 0x5DA066AC2D5DAEC3u64)
+ put(data, 0x5DD4805738B51A74u64)
+ put(data, 0x5E09A06D06E26112u64)
+ put(data, 0x5E400444244D7CABu64)
+ put(data, 0x5E7405552D60DBD6u64)
+ put(data, 0x5EA906AA78B912CBu64)
+ put(data, 0x5EDF485516E7577Eu64)
+ put(data, 0x5F138D352E5096AFu64)
+ put(data, 0x5F48708279E4BC5Au64)
+ put(data, 0x5F7E8CA3185DEB71u64)
+ put(data, 0x5FB317E5EF3AB327u64)
+ put(data, 0x5FE7DDDF6B095FF0u64)
+ put(data, 0x601DD55745CBB7ECu64)
+ put(data, 0x6052A5568B9F52F4u64)
+ put(data, 0x60874EAC2E8727B1u64)
+ put(data, 0x60BD22573A28F19Du64)
+ put(data, 0x60F2357684599702u64)
+ put(data, 0x6126C2D4256FFCC2u64)
+ put(data, 0x615C73892ECBFBF3u64)
+ put(data, 0x6191C835BD3F7D78u64)
+ put(data, 0x61C63A432C8F5CD6u64)
+ put(data, 0x61FBC8D3F7B3340Bu64)
+ put(data, 0x62315D847AD00087u64)
+ put(data, 0x6265B4E5998400A9u64)
+ put(data, 0x629B221EFFE500D3u64)
+ put(data, 0x62D0F5535FEF2084u64)
+ put(data, 0x630532A837EAE8A5u64)
+ put(data, 0x633A7F5245E5A2CEu64)
+ put(data, 0x63708F936BAF85C1u64)
+ put(data, 0x63A4B378469B6731u64)
+ put(data, 0x63D9E056584240FDu64)
+ put(data, 0x64102C35F729689Eu64)
+ put(data, 0x6444374374F3C2C6u64)
+ put(data, 0x647945145230B377u64)
+ put(data, 0x64AF965966BCE055u64)
+ put(data, 0x64E3BDF7E0360C35u64)
+ put(data, 0x6518AD75D8438F43u64)
+ put(data, 0x654ED8D34E547313u64)
+ put(data, 0x6583478410F4C7ECu64)
+ put(data, 0x65B819651531F9E7u64)
+ put(data, 0x65EE1FBE5A7E7861u64)
+ put(data, 0x6622D3D6F88F0B3Cu64)
+ put(data, 0x665788CCB6B2CE0Cu64)
+ put(data, 0x668D6AFFE45F818Fu64)
+ put(data, 0x66C262DFEEBBB0F9u64)
+ put(data, 0x66F6FB97EA6A9D37u64)
+ put(data, 0x672CBA7DE5054485u64)
+ put(data, 0x6761F48EAF234AD3u64)
+ put(data, 0x679671B25AEC1D88u64)
+ put(data, 0x67CC0E1EF1A724EAu64)
+ put(data, 0x680188D357087712u64)
+ put(data, 0x6835EB082CCA94D7u64)
+ put(data, 0x686B65CA37FD3A0Du64)
+ put(data, 0x68A11F9E62FE4448u64)
+ put(data, 0x68D56785FBBDD55Au64)
+ put(data, 0x690AC1677AAD4AB0u64)
+ put(data, 0x6940B8E0ACAC4EAEu64)
+ put(data, 0x6974E718D7D7625Au64)
+ put(data, 0x69AA20DF0DCD3AF0u64)
+ put(data, 0x69E0548B68A044D6u64)
+ put(data, 0x6A1469AE42C8560Cu64)
+ put(data, 0x6A498419D37A6B8Fu64)
+ put(data, 0x6A7FE52048590672u64)
+ put(data, 0x6AB3EF342D37A407u64)
+ put(data, 0x6AE8EB0138858D09u64)
+ put(data, 0x6B1F25C186A6F04Cu64)
+ put(data, 0x6B537798F428562Fu64)
+ put(data, 0x6B88557F31326BBBu64)
+ put(data, 0x6BBE6ADEFD7F06AAu64)
+ put(data, 0x6BF302CB5E6F642Au64)
+ put(data, 0x6C27C37E360B3D35u64)
+ put(data, 0x6C5DB45DC38E0C82u64)
+ put(data, 0x6C9290BA9A38C7D1u64)
+ put(data, 0x6CC734E940C6F9C5u64)
+ put(data, 0x6CFD022390F8B837u64)
+ put(data, 0x6D3221563A9B7322u64)
+ put(data, 0x6D66A9ABC9424FEBu64)
+ put(data, 0x6D9C5416BB92E3E6u64)
+ put(data, 0x6DD1B48E353BCE6Fu64)
+ put(data, 0x6E0621B1C28AC20Bu64)
+ put(data, 0x6E3BAA1E332D728Eu64)
+ put(data, 0x6E714A52DFFC6799u64)
+ put(data, 0x6EA59CE797FB817Fu64)
+ put(data, 0x6EDB04217DFA61DFu64)
+ put(data, 0x6F10E294EEBC7D2Bu64)
+ put(data, 0x6F451B3A2A6B9C76u64)
+ put(data, 0x6F7A6208B5068394u64)
+ put(data, 0x6FB07D457124123Cu64)
+ put(data, 0x6FE49C96CD6D16CBu64)
+ put(data, 0x7019C3BC80C85C7Eu64)
+ put(data, 0x70501A55D07D39CFu64)
+ put(data, 0x708420EB449C8842u64)
+ put(data, 0x70B9292615C3AA53u64)
+ put(data, 0x70EF736F9B3494E8u64)
+ put(data, 0x7123A825C100DD11u64)
+ put(data, 0x7158922F31411455u64)
+ put(data, 0x718EB6BAFD91596Bu64)
+ put(data, 0x71C33234DE7AD7E2u64)
+ put(data, 0x71F7FEC216198DDBu64)
+ put(data, 0x722DFE729B9FF152u64)
+ put(data, 0x7262BF07A143F6D3u64)
+ put(data, 0x72976EC98994F488u64)
+ put(data, 0x72CD4A7BEBFA31AAu64)
+ put(data, 0x73024E8D737C5F0Au64)
+ put(data, 0x7336E230D05B76CDu64)
+ put(data, 0x736C9ABD04725480u64)
+ put(data, 0x73A1E0B622C774D0u64)
+ put(data, 0x73D658E3AB795204u64)
+ put(data, 0x740BEF1C9657A685u64)
+ put(data, 0x74417571DDF6C813u64)
+ put(data, 0x7475D2CE55747A18u64)
+ put(data, 0x74AB4781EAD1989Eu64)
+ put(data, 0x74E10CB132C2FF63u64)
+ put(data, 0x75154FDD7F73BF3Bu64)
+ put(data, 0x754AA3D4DF50AF0Au64)
+ put(data, 0x7580A6650B926D66u64)
+ put(data, 0x75B4CFFE4E7708C0u64)
+ put(data, 0x75EA03FDE214CAF0u64)
+ put(data, 0x7620427EAD4CFED6u64)
+ put(data, 0x7654531E58A03E8Bu64)
+ put(data, 0x768967E5EEC84E2Eu64)
+ put(data, 0x76BFC1DF6A7A61BAu64)
+ put(data, 0x76F3D92BA28C7D14u64)
+ put(data, 0x7728CF768B2F9C59u64)
+ put(data, 0x775F03542DFB8370u64)
+ put(data, 0x779362149CBD3226u64)
+ put(data, 0x77C83A99C3EC7EAFu64)
+ put(data, 0x77FE494034E79E5Bu64)
+ put(data, 0x7832EDC82110C2F9u64)
+ put(data, 0x7867A93A2954F3B7u64)
+ put(data, 0x789D9388B3AA30A5u64)
+ put(data, 0x78D27C35704A5E67u64)
+ put(data, 0x79071B42CC5CF601u64)
+ put(data, 0x793CE2137F743381u64)
+ put(data, 0x79720D4C2FA8A030u64)
+ put(data, 0x79A6909F3B92C83Du64)
+ put(data, 0x79DC34C70A777A4Cu64)
+ put(data, 0x7A11A0FC668AAC6Fu64)
+ put(data, 0x7A46093B802D578Bu64)
+ put(data, 0x7A7B8B8A6038AD6Eu64)
+ put(data, 0x7AB137367C236C65u64)
+ put(data, 0x7AE585041B2C477Eu64)
+ put(data, 0x7B1AE64521F7595Eu64)
+ put(data, 0x7B50CFEB353A97DAu64)
+ put(data, 0x7B8503E602893DD1u64)
+ put(data, 0x7BBA44DF832B8D45u64)
+ put(data, 0x7BF06B0BB1FB384Bu64)
+ put(data, 0x7C2485CE9E7A065Eu64)
+ put(data, 0x7C59A742461887F6u64)
+ put(data, 0x7C9008896BCF54F9u64)
+ put(data, 0x7CC40AABC6C32A38u64)
+ put(data, 0x7CF90D56B873F4C6u64)
+ put(data, 0x7D2F50AC6690F1F8u64)
+ put(data, 0x7D63926BC01A973Bu64)
+ put(data, 0x7D987706B0213D09u64)
+ put(data, 0x7DCE94C85C298C4Cu64)
+ put(data, 0x7E031CFD3999F7AFu64)
+ put(data, 0x7E37E43C8800759Bu64)
+ put(data, 0x7E6DDD4BAA009302u64)
+ put(data, 0x7EA2AA4F4A405BE1u64)
+ put(data, 0x7ED754E31CD072D9u64)
+ put(data, 0x7F0D2A1BE4048F90u64)
+ put(data, 0x7F423A516E82D9BAu64)
+ put(data, 0x7F76C8E5CA239028u64)
+ put(data, 0x7FAC7B1F3CAC7433u64)
+ put(data, 0x7FE1CCF385EBC89Fu64)
+ put(data, 0x7FEFFFFFFFFFFFFFu64)
+ data
+ end
+
private POW10_OFFSET = [
0, 2, 5, 8, 12, 16, 21, 26, 32, 39,
46, 54, 62, 71, 80, 90, 100, 111, 122, 134,
diff --git a/src/gc/boehm.cr b/src/gc/boehm.cr
index b4dfb0061900..609f71189795 100644
--- a/src/gc/boehm.cr
+++ b/src/gc/boehm.cr
@@ -21,11 +21,24 @@
{% if flag?(:freebsd) || flag?(:dragonfly) %}
@[Link("gc-threaded")]
-{% else %}
+{% elsif flag?(:interpreted) %}
+ # FIXME: We're not using the pkg-config name here because that would resolve the
+ # lib flags for libgc including `-lpthread` which the interpreter is not able
+ # to load on systems with modern libc where libpthread is only available as an
+ # (empty) static library.
@[Link("gc")]
+{% else %}
+ @[Link("gc", pkg_config: "bdw-gc")]
{% end %}
+{% if compare_versions(Crystal::VERSION, "1.11.0-dev") >= 0 %}
+ @[Link(dll: "gc.dll")]
+{% end %}
lib LibGC
+ {% unless flag?(:win32) %}
+ VERSION = {{ `pkg-config bdw-gc --silence-errors --modversion || printf "0.0.0"`.chomp.stringify }}
+ {% end %}
+
alias Int = LibC::Int
alias SizeT = LibC::SizeT
{% if flag?(:win32) && flag?(:bits64) %}
@@ -93,7 +106,7 @@ lib LibGC
fun push_all_eager = GC_push_all_eager(bottom : Void*, top : Void*)
- {% if flag?(:preview_mt) || flag?(:win32) %}
+ {% if flag?(:preview_mt) || flag?(:win32) || compare_versions(VERSION, "8.2.0") >= 0 %}
fun get_my_stackbottom = GC_get_my_stackbottom(sb : StackBase*) : ThreadHandle
fun set_stackbottom = GC_set_stackbottom(th : ThreadHandle, sb : StackBase*) : ThreadHandle
{% else %}
@@ -274,10 +287,11 @@ module GC
# :nodoc:
def self.current_thread_stack_bottom
- {% if flag?(:preview_mt) || flag?(:win32) %}
+ {% if LibGC.has_method?(:get_my_stackbottom) %}
th = LibGC.get_my_stackbottom(out sb)
{th, sb.mem_base}
{% else %}
+ # support for legacy gc releases
{Pointer(Void).null, LibGC.stackbottom}
{% end %}
end
@@ -289,10 +303,11 @@ module GC
sb.mem_base = stack_bottom
LibGC.set_stackbottom(thread_handle, pointerof(sb))
end
- {% elsif flag?(:win32) %}
+ {% elsif LibGC.has_method?(:set_stackbottom) %}
# this is necessary because Boehm GC does _not_ use `GC_stackbottom` on
- # Windows when pushing all threads' stacks; instead `GC_set_stackbottom`
- # must be used to associate the new bottom with the running thread
+ # Windows when pushing all threads' stacks; it also started crashing on
+ # Linux with libgc after v8.2.4; instead `GC_set_stackbottom` must be used
+ # to associate the new bottom with the running thread
def self.set_stackbottom(stack_bottom : Void*)
sb = LibGC::StackBase.new
sb.mem_base = stack_bottom
@@ -300,6 +315,7 @@ module GC
LibGC.set_stackbottom(nil, pointerof(sb))
end
{% else %}
+ # support for legacy gc releases
def self.set_stackbottom(stack_bottom : Void*)
LibGC.stackbottom = stack_bottom
end
diff --git a/src/hash.cr b/src/hash.cr
index 8d8ccea22a0b..082f2a0a80e0 100644
--- a/src/hash.cr
+++ b/src/hash.cr
@@ -2055,16 +2055,30 @@ class Hash(K, V)
pp.text "{...}" unless executed
end
- # Returns an array of tuples with key and values belonging to this Hash.
+ # Returns an `Array` of `Tuple(K, V)` with key and values belonging to this Hash.
#
# ```
# h = {1 => 'a', 2 => 'b', 3 => 'c'}
# h.to_a # => [{1, 'a'}, {2, 'b'}, {3, 'c'}]
# ```
+ #
# The order of the array follows the order the keys were inserted in the Hash.
def to_a : Array({K, V})
+ to_a(&.itself)
+ end
+
+ # Returns an `Array` with the results of running *block* against tuples with key and values
+ # belonging to this Hash.
+ #
+ # ```
+ # h = {"first_name" => "foo", "last_name" => "bar"}
+ # h.to_a { |_k, v| v.capitalize } # => ["Foo", "Bar"]
+ # ```
+ #
+ # The order of the array follows the order the keys were inserted in the Hash.
+ def to_a(&block : {K, V} -> U) : Array(U) forall U
to_a_impl do |entry|
- {entry.key, entry.value}
+ yield ({entry.key, entry.value})
end
end
diff --git a/src/humanize.cr b/src/humanize.cr
index e0c69a37b3ad..bb285fe3a07d 100644
--- a/src/humanize.cr
+++ b/src/humanize.cr
@@ -20,7 +20,7 @@ struct Number
def format(io : IO, separator = '.', delimiter = ',', decimal_places : Int? = nil, *, group : Int = 3, only_significant : Bool = false) : Nil
number = self
# TODO: Optimize implementation for Int
- if decimal_places
+ if decimal_places && (decimal_places < 0 || !number.is_a?(Float))
number = number.round(decimal_places)
end
diff --git a/src/indexable.cr b/src/indexable.cr
index 3725c1552e38..7496a95e0df0 100644
--- a/src/indexable.cr
+++ b/src/indexable.cr
@@ -693,14 +693,14 @@ module Indexable(T)
end
end
- # Returns an `Array` with all the elements in the collection.
+ # Returns an `Array` with the results of running *block* against each element of the collection.
#
# ```
- # {1, 2, 3}.to_a # => [1, 2, 3]
+ # {1, 2, 3}.to_a { |i| i * 2 } # => [2, 4, 6]
# ```
- def to_a : Array(T)
- ary = Array(T).new(size)
- each { |e| ary << e }
+ def to_a(& : T -> U) : Array(U) forall U
+ ary = Array(U).new(size)
+ each { |e| ary << yield e }
ary
end
diff --git a/src/int.cr b/src/int.cr
index 005d2c625c7b..b36ddba14e9e 100644
--- a/src/int.cr
+++ b/src/int.cr
@@ -567,6 +567,20 @@ struct Int
end
# Calls the given block with each integer value from self down to `to`.
+ #
+ # ```
+ # 3.downto(1) do |i|
+ # puts i
+ # end
+ # ```
+ #
+ # Prints:
+ #
+ # ```text
+ # 3
+ # 2
+ # 1
+ # ```
def downto(to, &block : self ->) : Nil
return unless self >= to
x = self
diff --git a/src/io/error.cr b/src/io/error.cr
index 4c6d30952f13..ec0374040699 100644
--- a/src/io/error.cr
+++ b/src/io/error.cr
@@ -16,10 +16,10 @@ class IO
"#{message} (#{target})"
end
- def initialize(message : String? = nil, *, target = nil)
+ def initialize(message : String? = nil, cause : Exception? = nil, *, target = nil)
@target = target.try(&.to_s)
- super message
+ super message, cause
end
end
diff --git a/src/io/memory.cr b/src/io/memory.cr
index d0b925df1d70..bd486f0cbdc2 100644
--- a/src/io/memory.cr
+++ b/src/io/memory.cr
@@ -90,11 +90,7 @@ class IO::Memory < IO
return if count == 0
- new_bytesize = @pos + count
- if new_bytesize > @capacity
- check_resizeable
- resize_to_capacity(Math.pw2ceil(new_bytesize))
- end
+ increase_capacity_by(count)
slice.copy_to(@buffer + @pos, count)
@@ -112,11 +108,7 @@ class IO::Memory < IO
check_writeable
check_open
- new_bytesize = @pos + 1
- if new_bytesize > @capacity
- check_resizeable
- resize_to_capacity(Math.pw2ceil(new_bytesize))
- end
+ increase_capacity_by(1)
(@buffer + @pos).value = byte
@@ -458,6 +450,28 @@ class IO::Memory < IO
end
end
+ private def increase_capacity_by(count)
+ raise IO::EOFError.new if count >= Int32::MAX - bytesize
+
+ new_bytesize = @pos + count
+ return if new_bytesize <= @capacity
+
+ check_resizeable
+
+ new_capacity = calculate_new_capacity(new_bytesize)
+ resize_to_capacity(new_capacity)
+ end
+
+ private def calculate_new_capacity(new_bytesize : Int32)
+ # If the new bytesize is bigger than 1 << 30, the next power of two would
+ # be 1 << 31, which is out of range for Int32.
+ # So we limit the capacity to Int32::MAX in order to be able to use the
+ # range (1 << 30) < new_bytesize < Int32::MAX
+ return Int32::MAX if new_bytesize > 1 << 30
+
+ Math.pw2ceil(new_bytesize)
+ end
+
private def resize_to_capacity(capacity)
@capacity = capacity
@buffer = GC.realloc(@buffer, @capacity)
diff --git a/src/json/builder.cr b/src/json/builder.cr
index 9bc074f7c6ef..c1dc2c39c8e8 100644
--- a/src/json/builder.cr
+++ b/src/json/builder.cr
@@ -430,7 +430,10 @@ module JSON
# end
# string # => %<{"name":"foo","values":[1,2,3]}>
# ```
- def self.build(indent = nil, &)
+ #
+ # Accepts an indent parameter which can either be an `Int` (number of spaces to indent)
+ # or a `String`, which will prefix each level with the string a corresponding amount of times.
+ def self.build(indent : String | Int | Nil = nil, &)
String.build do |str|
build(str, indent) do |json|
yield json
@@ -439,7 +442,7 @@ module JSON
end
# Writes JSON into the given `IO`. A `JSON::Builder` is yielded to the block.
- def self.build(io : IO, indent = nil, &) : Nil
+ def self.build(io : IO, indent : String | Int | Nil = nil, &) : Nil
builder = JSON::Builder.new(io)
builder.indent = indent if indent
builder.document do
diff --git a/src/kernel.cr b/src/kernel.cr
index c3b3106ccae3..d3817ee11661 100644
--- a/src/kernel.cr
+++ b/src/kernel.cr
@@ -563,14 +563,6 @@ end
{% end %}
{% unless flag?(:interpreted) || flag?(:wasm32) %}
- # Background loop to cleanup unused fiber stacks.
- spawn(name: "Fiber Clean Loop") do
- loop do
- sleep 5
- Fiber.stack_pool.collect
- end
- end
-
{% if flag?(:win32) %}
Crystal::System::Process.start_interrupt_loop
{% else %}
@@ -586,7 +578,5 @@ end
Exception::CallStack.load_debug_info if ENV["CRYSTAL_LOAD_DEBUG_INFO"]? == "1"
Exception::CallStack.setup_crash_handler
- {% if flag?(:preview_mt) %}
- Crystal::Scheduler.init_workers
- {% end %}
+ Crystal::Scheduler.init
{% end %}
diff --git a/src/lib_c/aarch64-android/c/pthread.cr b/src/lib_c/aarch64-android/c/pthread.cr
index d761bcb3ceb2..fbab59bd07d7 100644
--- a/src/lib_c/aarch64-android/c/pthread.cr
+++ b/src/lib_c/aarch64-android/c/pthread.cr
@@ -38,6 +38,7 @@ lib LibC
fun pthread_mutex_unlock(__mutex : PthreadMutexT*) : Int
fun pthread_self : PthreadT
+ fun pthread_setname_np(__key : PthreadT, __name : Char*) : Int
fun pthread_setspecific(__key : PthreadKeyT, __value : Void*) : Int
end
diff --git a/src/lib_c/aarch64-darwin/c/pthread.cr b/src/lib_c/aarch64-darwin/c/pthread.cr
index dd262f7d9c12..d146e227197f 100644
--- a/src/lib_c/aarch64-darwin/c/pthread.cr
+++ b/src/lib_c/aarch64-darwin/c/pthread.cr
@@ -25,4 +25,5 @@ lib LibC
fun pthread_mutex_trylock(x0 : PthreadMutexT*) : Int
fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
fun pthread_self : PthreadT
+ fun pthread_setname_np(Char*) : Int
end
diff --git a/src/lib_c/aarch64-linux-gnu/c/pthread.cr b/src/lib_c/aarch64-linux-gnu/c/pthread.cr
index 643fca7c015a..5d9f7b94e225 100644
--- a/src/lib_c/aarch64-linux-gnu/c/pthread.cr
+++ b/src/lib_c/aarch64-linux-gnu/c/pthread.cr
@@ -36,4 +36,5 @@ lib LibC
fun pthread_mutex_trylock(mutex : PthreadMutexT*) : Int
fun pthread_mutex_unlock(mutex : PthreadMutexT*) : Int
fun pthread_self : PthreadT
+ fun pthread_setname_np(PthreadT, Char*) : Int
end
diff --git a/src/lib_c/aarch64-linux-musl/c/pthread.cr b/src/lib_c/aarch64-linux-musl/c/pthread.cr
index c318bb5f4357..6ee1a20d90a6 100644
--- a/src/lib_c/aarch64-linux-musl/c/pthread.cr
+++ b/src/lib_c/aarch64-linux-musl/c/pthread.cr
@@ -27,4 +27,5 @@ lib LibC
fun pthread_mutex_trylock(x0 : PthreadMutexT*) : Int
fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
fun pthread_self : PthreadT
+ fun pthread_setname_np(PthreadT, Char*) : Int
end
diff --git a/src/lib_c/arm-linux-gnueabihf/c/pthread.cr b/src/lib_c/arm-linux-gnueabihf/c/pthread.cr
index 643fca7c015a..5d9f7b94e225 100644
--- a/src/lib_c/arm-linux-gnueabihf/c/pthread.cr
+++ b/src/lib_c/arm-linux-gnueabihf/c/pthread.cr
@@ -36,4 +36,5 @@ lib LibC
fun pthread_mutex_trylock(mutex : PthreadMutexT*) : Int
fun pthread_mutex_unlock(mutex : PthreadMutexT*) : Int
fun pthread_self : PthreadT
+ fun pthread_setname_np(PthreadT, Char*) : Int
end
diff --git a/src/lib_c/i386-linux-gnu/c/pthread.cr b/src/lib_c/i386-linux-gnu/c/pthread.cr
index ab943b23587d..33274a6cf51d 100644
--- a/src/lib_c/i386-linux-gnu/c/pthread.cr
+++ b/src/lib_c/i386-linux-gnu/c/pthread.cr
@@ -35,4 +35,5 @@ lib LibC
fun pthread_mutex_trylock(mutex : PthreadMutexT*) : Int
fun pthread_mutex_unlock(mutex : PthreadMutexT*) : Int
fun pthread_self : PthreadT
+ fun pthread_setname_np(PthreadT, Char*) : Int
end
diff --git a/src/lib_c/i386-linux-musl/c/pthread.cr b/src/lib_c/i386-linux-musl/c/pthread.cr
index c318bb5f4357..6ee1a20d90a6 100644
--- a/src/lib_c/i386-linux-musl/c/pthread.cr
+++ b/src/lib_c/i386-linux-musl/c/pthread.cr
@@ -27,4 +27,5 @@ lib LibC
fun pthread_mutex_trylock(x0 : PthreadMutexT*) : Int
fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
fun pthread_self : PthreadT
+ fun pthread_setname_np(PthreadT, Char*) : Int
end
diff --git a/src/lib_c/x86_64-darwin/c/pthread.cr b/src/lib_c/x86_64-darwin/c/pthread.cr
index dd262f7d9c12..d146e227197f 100644
--- a/src/lib_c/x86_64-darwin/c/pthread.cr
+++ b/src/lib_c/x86_64-darwin/c/pthread.cr
@@ -25,4 +25,5 @@ lib LibC
fun pthread_mutex_trylock(x0 : PthreadMutexT*) : Int
fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
fun pthread_self : PthreadT
+ fun pthread_setname_np(Char*) : Int
end
diff --git a/src/lib_c/x86_64-dragonfly/c/pthread.cr b/src/lib_c/x86_64-dragonfly/c/pthread.cr
index 87ae8c05c358..90bf0c6285a0 100644
--- a/src/lib_c/x86_64-dragonfly/c/pthread.cr
+++ b/src/lib_c/x86_64-dragonfly/c/pthread.cr
@@ -29,4 +29,5 @@ lib LibC
fun pthread_mutex_trylock(x0 : PthreadMutexT*) : Int
fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
fun pthread_self : PthreadT
+ fun pthread_setname_np(PthreadT, Char*) : Int
end
diff --git a/src/lib_c/x86_64-freebsd/c/pthread.cr b/src/lib_c/x86_64-freebsd/c/pthread.cr
index 87ae8c05c358..9cc78c2f2850 100644
--- a/src/lib_c/x86_64-freebsd/c/pthread.cr
+++ b/src/lib_c/x86_64-freebsd/c/pthread.cr
@@ -29,4 +29,5 @@ lib LibC
fun pthread_mutex_trylock(x0 : PthreadMutexT*) : Int
fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
fun pthread_self : PthreadT
+ fun pthread_set_name_np(PthreadT, Char*)
end
diff --git a/src/lib_c/x86_64-linux-gnu/c/pthread.cr b/src/lib_c/x86_64-linux-gnu/c/pthread.cr
index ab943b23587d..33274a6cf51d 100644
--- a/src/lib_c/x86_64-linux-gnu/c/pthread.cr
+++ b/src/lib_c/x86_64-linux-gnu/c/pthread.cr
@@ -35,4 +35,5 @@ lib LibC
fun pthread_mutex_trylock(mutex : PthreadMutexT*) : Int
fun pthread_mutex_unlock(mutex : PthreadMutexT*) : Int
fun pthread_self : PthreadT
+ fun pthread_setname_np(PthreadT, Char*) : Int
end
diff --git a/src/lib_c/x86_64-linux-musl/c/pthread.cr b/src/lib_c/x86_64-linux-musl/c/pthread.cr
index c318bb5f4357..6ee1a20d90a6 100644
--- a/src/lib_c/x86_64-linux-musl/c/pthread.cr
+++ b/src/lib_c/x86_64-linux-musl/c/pthread.cr
@@ -27,4 +27,5 @@ lib LibC
fun pthread_mutex_trylock(x0 : PthreadMutexT*) : Int
fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
fun pthread_self : PthreadT
+ fun pthread_setname_np(PthreadT, Char*) : Int
end
diff --git a/src/lib_c/x86_64-netbsd/c/pthread.cr b/src/lib_c/x86_64-netbsd/c/pthread.cr
index 133d4922c57f..e0f477018777 100644
--- a/src/lib_c/x86_64-netbsd/c/pthread.cr
+++ b/src/lib_c/x86_64-netbsd/c/pthread.cr
@@ -35,5 +35,6 @@ lib LibC
fun pthread_mutex_trylock(x0 : PthreadMutexT*) : Int
fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
fun pthread_self : PthreadT
+ fun pthread_setname_np(PthreadT, Char*, Void*) : Int
fun pthread_setspecific(PthreadKeyT, Void*) : Int
end
diff --git a/src/lib_c/x86_64-openbsd/c/pthread.cr b/src/lib_c/x86_64-openbsd/c/pthread.cr
index 788823c40a31..15773336f239 100644
--- a/src/lib_c/x86_64-openbsd/c/pthread.cr
+++ b/src/lib_c/x86_64-openbsd/c/pthread.cr
@@ -30,6 +30,7 @@ lib LibC
fun pthread_mutex_trylock(x0 : PthreadMutexT*) : Int
fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
fun pthread_self : PthreadT
+ fun pthread_set_name_np(PthreadT, Char*)
fun pthread_setspecific(PthreadKeyT, Void*) : Int
fun pthread_stackseg_np(PthreadT, StackT*) : Int
end
diff --git a/src/lib_c/x86_64-windows-msvc/c/consoleapi.cr b/src/lib_c/x86_64-windows-msvc/c/consoleapi.cr
index 680e199be2ab..796369c65a85 100644
--- a/src/lib_c/x86_64-windows-msvc/c/consoleapi.cr
+++ b/src/lib_c/x86_64-windows-msvc/c/consoleapi.cr
@@ -14,6 +14,14 @@ lib LibC
fun GetConsoleCP : DWORD
fun GetConsoleOutputCP : DWORD
+ fun ReadConsoleW(
+ hConsoleInput : HANDLE,
+ lpBuffer : Void*,
+ nNumberOfCharsToRead : DWORD,
+ lpNumberOfCharsRead : DWORD*,
+ pInputControl : Void*
+ ) : BOOL
+
CTRL_C_EVENT = 0
CTRL_BREAK_EVENT = 1
diff --git a/src/lib_c/x86_64-windows-msvc/c/processthreadsapi.cr b/src/lib_c/x86_64-windows-msvc/c/processthreadsapi.cr
index 9c22d4530c81..efa684075162 100644
--- a/src/lib_c/x86_64-windows-msvc/c/processthreadsapi.cr
+++ b/src/lib_c/x86_64-windows-msvc/c/processthreadsapi.cr
@@ -50,6 +50,9 @@ lib LibC
bInheritHandles : BOOL, dwCreationFlags : DWORD,
lpEnvironment : Void*, lpCurrentDirectory : LPWSTR,
lpStartupInfo : STARTUPINFOW*, lpProcessInformation : PROCESS_INFORMATION*) : BOOL
+ {% if LibC::WIN32_WINNT >= LibC::WIN32_WINNT_WIN10 %}
+ fun SetThreadDescription(hThread : HANDLE, lpThreadDescription : LPWSTR) : LONG
+ {% end %}
fun SetThreadStackGuarantee(stackSizeInBytes : DWORD*) : BOOL
fun GetProcessTimes(hProcess : HANDLE, lpCreationTime : FILETIME*, lpExitTime : FILETIME*,
lpKernelTime : FILETIME*, lpUserTime : FILETIME*) : BOOL
diff --git a/src/lib_z/lib_z.cr b/src/lib_z/lib_z.cr
index e261cde29683..1c88cb67bba8 100644
--- a/src/lib_z/lib_z.cr
+++ b/src/lib_z/lib_z.cr
@@ -1,4 +1,7 @@
@[Link("z")]
+{% if compare_versions(Crystal::VERSION, "1.11.0-dev") >= 0 %}
+ @[Link(dll: "zlib1.dll")]
+{% end %}
lib LibZ
alias Char = LibC::Char
alias Int = LibC::Int
diff --git a/src/llvm/enums.cr b/src/llvm/enums.cr
index b8e06fb46f89..ac23fa711560 100644
--- a/src/llvm/enums.cr
+++ b/src/llvm/enums.cr
@@ -440,6 +440,11 @@ module LLVM
LittleEndian = 1 << 28
end
+ enum InlineAsmDialect
+ ATT
+ Intel
+ end
+
struct Value
enum Kind
Argument
diff --git a/src/llvm/ext/llvm-versions.txt b/src/llvm/ext/llvm-versions.txt
index 7c8773c02212..92ae5ecbaa5a 100644
--- a/src/llvm/ext/llvm-versions.txt
+++ b/src/llvm/ext/llvm-versions.txt
@@ -1 +1 @@
-17.0 16.0 15.0 14.0 13.0 12.0 11.1 11.0 10.0 9.0 8.0
+18.1 17.0 16.0 15.0 14.0 13.0 12.0 11.1 11.0 10.0 9.0 8.0
diff --git a/src/llvm/function.cr b/src/llvm/function.cr
index a586cd6fdde5..d643e74d758b 100644
--- a/src/llvm/function.cr
+++ b/src/llvm/function.cr
@@ -28,6 +28,13 @@ struct LLVM::Function
end
end
+ def add_attribute(attribute : String, index = AttributeIndex::FunctionIndex, *, value : String)
+ context = LibLLVM.get_module_context(LibLLVM.get_global_parent(self))
+ attribute_ref = LibLLVM.create_string_attribute(context, attribute, attribute.bytesize,
+ value, value.bytesize)
+ LibLLVM.add_attribute_at_index(self, index, attribute_ref)
+ end
+
def add_attribute(attribute : Attribute, index = AttributeIndex::FunctionIndex, *, value)
return if attribute.value == 0
diff --git a/src/llvm/lib_llvm.cr b/src/llvm/lib_llvm.cr
index ee18eddfbce3..b68e212d2052 100644
--- a/src/llvm/lib_llvm.cr
+++ b/src/llvm/lib_llvm.cr
@@ -15,6 +15,9 @@
{% llvm_ldflags = lines[2] %}
@[Link("llvm")]
+ {% if compare_versions(Crystal::VERSION, "1.11.0-dev") >= 0 %}
+ @[Link(dll: "LLVM-C.dll")]
+ {% end %}
lib LibLLVM
end
{% else %}
@@ -32,7 +35,7 @@
@[Link(ldflags: {{ llvm_ldflags }})]
lib LibLLVM
- VERSION = {{ llvm_version.strip.gsub(/git/, "") }}
+ VERSION = {{ llvm_version.strip.gsub(/git/, "").gsub(/rc.*/, "") }}
BUILT_TARGETS = {{ llvm_targets.strip.downcase.split(' ').map(&.id.symbolize) }}
end
{% end %}
diff --git a/src/llvm/lib_llvm/core.cr b/src/llvm/lib_llvm/core.cr
index 0645441f8a70..c865baaa55a5 100644
--- a/src/llvm/lib_llvm/core.cr
+++ b/src/llvm/lib_llvm/core.cr
@@ -4,11 +4,6 @@ lib LibLLVM
# NOTE: the following C enums usually have different values from their C++
# counterparts (e.g. `LLVMModuleFlagBehavior` v.s. `LLVM::Module::ModFlagBehavior`)
- enum InlineAsmDialect
- ATT
- Intel
- end
-
enum ModuleFlagBehavior
Warning = 1
end
@@ -25,6 +20,7 @@ lib LibLLVM
fun get_enum_attribute_kind_for_name = LLVMGetEnumAttributeKindForName(name : Char*, s_len : SizeT) : UInt
fun get_last_enum_attribute_kind = LLVMGetLastEnumAttributeKind : UInt
fun create_enum_attribute = LLVMCreateEnumAttribute(c : ContextRef, kind_id : UInt, val : UInt64) : AttributeRef
+ fun create_string_attribute = LLVMCreateStringAttribute(c : ContextRef, k : Char*, k_length : UInt, v : Char*, v_length : UInt) : AttributeRef
{% unless LibLLVM::IS_LT_120 %}
fun create_type_attribute = LLVMCreateTypeAttribute(c : ContextRef, kind_id : UInt, type_ref : TypeRef) : AttributeRef
{% end %}
@@ -38,9 +34,9 @@ lib LibLLVM
fun print_module_to_file = LLVMPrintModuleToFile(m : ModuleRef, filename : Char*, error_message : Char**) : Bool
fun print_module_to_string = LLVMPrintModuleToString(m : ModuleRef) : Char*
{% if !LibLLVM::IS_LT_130 %}
- fun get_inline_asm = LLVMGetInlineAsm(ty : TypeRef, asm_string : Char*, asm_string_size : SizeT, constraints : Char*, constraints_size : SizeT, has_side_effects : Bool, is_align_stack : Bool, dialect : InlineAsmDialect, can_throw : Bool) : ValueRef
+ fun get_inline_asm = LLVMGetInlineAsm(ty : TypeRef, asm_string : Char*, asm_string_size : SizeT, constraints : Char*, constraints_size : SizeT, has_side_effects : Bool, is_align_stack : Bool, dialect : LLVM::InlineAsmDialect, can_throw : Bool) : ValueRef
{% else %}
- fun get_inline_asm = LLVMGetInlineAsm(t : TypeRef, asm_string : Char*, asm_string_size : SizeT, constraints : Char*, constraints_size : SizeT, has_side_effects : Bool, is_align_stack : Bool, dialect : InlineAsmDialect) : ValueRef
+ fun get_inline_asm = LLVMGetInlineAsm(t : TypeRef, asm_string : Char*, asm_string_size : SizeT, constraints : Char*, constraints_size : SizeT, has_side_effects : Bool, is_align_stack : Bool, dialect : LLVM::InlineAsmDialect) : ValueRef
{% end %}
fun get_module_context = LLVMGetModuleContext(m : ModuleRef) : ContextRef
diff --git a/src/llvm/parameter_collection.cr b/src/llvm/parameter_collection.cr
index 937d9ec2edcc..dd9a7eae91d7 100644
--- a/src/llvm/parameter_collection.cr
+++ b/src/llvm/parameter_collection.cr
@@ -8,7 +8,7 @@ struct LLVM::ParameterCollection
LibLLVM.get_count_params(@function).to_i
end
- def to_a
+ def to_a : Array(LLVM::Value)
param_size = size()
Array(LLVM::Value).build(param_size) do |buffer|
LibLLVM.get_params(@function, buffer.as(LibLLVM::ValueRef*))
diff --git a/src/llvm/type.cr b/src/llvm/type.cr
index 06c36ff5796d..42d1a314c118 100644
--- a/src/llvm/type.cr
+++ b/src/llvm/type.cr
@@ -173,29 +173,29 @@ struct LLVM::Type
Value.new LibLLVM.const_array(self, (values.to_unsafe.as(LibLLVM::ValueRef*)), values.size)
end
- def inline_asm(asm_string, constraints, has_side_effects = false, is_align_stack = false, can_throw = false)
+ def inline_asm(asm_string, constraints, has_side_effects = false, is_align_stack = false, can_throw = false, dialect : InlineAsmDialect = InlineAsmDialect::ATT)
value =
{% if LibLLVM::IS_LT_130 %}
LibLLVM.get_inline_asm(
self,
asm_string,
- asm_string.size,
+ asm_string.bytesize,
constraints,
- constraints.size,
+ constraints.bytesize,
(has_side_effects ? 1 : 0),
(is_align_stack ? 1 : 0),
- LibLLVM::InlineAsmDialect::ATT
+ dialect,
)
{% else %}
LibLLVM.get_inline_asm(
self,
asm_string,
- asm_string.size,
+ asm_string.bytesize,
constraints,
- constraints.size,
+ constraints.bytesize,
(has_side_effects ? 1 : 0),
(is_align_stack ? 1 : 0),
- LibLLVM::InlineAsmDialect::ATT,
+ dialect,
(can_throw ? 1 : 0)
)
{% end %}
diff --git a/src/mutex.cr b/src/mutex.cr
index 6bdd9a98fd25..83dd4bb53429 100644
--- a/src/mutex.cr
+++ b/src/mutex.cr
@@ -107,6 +107,9 @@ class Mutex
@mutex_fiber = nil
end
+ {% if flag?(:aarch64) %}
+ Atomic::Ops.fence :sequentially_consistent, false
+ {% end %}
@state.lazy_set(0)
if @queue_count.get == 0
diff --git a/src/named_tuple.cr b/src/named_tuple.cr
index 7cceb568a260..4ea9df02fd20 100644
--- a/src/named_tuple.cr
+++ b/src/named_tuple.cr
@@ -588,12 +588,25 @@ struct NamedTuple
#
# NOTE: `to_a` on an empty named tuple produces an `Array(Tuple(Symbol, NoReturn))`
def to_a
+ to_a(&.itself)
+ end
+
+ # Returns an `Array` with the results of running *block* against tuples with key and values belonging
+ # to this `NamedTuple`.
+ #
+ # ```
+ # tuple = {first_name: "foo", last_name: "bar"}
+ # tuple.to_a(&.last.capitalize) # => ["Foo", "Bar"]
+ # ```
+ #
+ # NOTE: `to_a` on an empty named tuple produces an `Array(Tuple(Symbol, NoReturn))`
+ def to_a(&)
{% if T.size == 0 %}
[] of {Symbol, NoReturn}
{% else %}
[
{% for key in T %}
- { {{key.symbolize}}, self[{{key.symbolize}}] },
+ yield({ {{key.symbolize}}, self[{{key.symbolize}}] }),
{% end %}
]
{% end %}
diff --git a/src/object.cr b/src/object.cr
index 6687e19f424a..ba818ac2979e 100644
--- a/src/object.cr
+++ b/src/object.cr
@@ -1293,17 +1293,18 @@ class Object
# wrapper.capitalize # => "Hello"
# ```
macro delegate(*methods, to object)
- {% for method in methods %}
- {% if method.id.ends_with?('=') && method.id != "[]=" %}
- def {{method.id}}(arg)
- {{object.id}}.{{method.id}} arg
- end
- {% else %}
- def {{method.id}}(*args, **options)
- {{object.id}}.{{method.id}}(*args, **options)
- end
+ {% if compare_versions(Crystal::VERSION, "1.12.0-dev") >= 0 %}
+ {% eq_operators = %w(<= >= == != []= ===) %}
+ {% for method in methods %}
+ {% if method.id.ends_with?('=') && !eq_operators.includes?(method.id.stringify) %}
+ def {{method.id}}(arg)
+ {{object.id}}.{{method.id}} arg
+ end
+ {% else %}
+ def {{method.id}}(*args, **options)
+ {{object.id}}.{{method.id}}(*args, **options)
+ end
- {% if method.id != "[]=" %}
def {{method.id}}(*args, **options)
{{object.id}}.{{method.id}}(*args, **options) do |*yield_args|
yield *yield_args
@@ -1311,6 +1312,26 @@ class Object
end
{% end %}
{% end %}
+ {% else %}
+ {% for method in methods %}
+ {% if method.id.ends_with?('=') && method.id != "[]=" %}
+ def {{method.id}}(arg)
+ {{object.id}}.{{method.id}} arg
+ end
+ {% else %}
+ def {{method.id}}(*args, **options)
+ {{object.id}}.{{method.id}}(*args, **options)
+ end
+
+ {% if method.id != "[]=" %}
+ def {{method.id}}(*args, **options)
+ {{object.id}}.{{method.id}}(*args, **options) do |*yield_args|
+ yield *yield_args
+ end
+ end
+ {% end %}
+ {% end %}
+ {% end %}
{% end %}
end
diff --git a/src/openssl/lib_crypto.cr b/src/openssl/lib_crypto.cr
index c783aa7903a9..caca9c11c520 100644
--- a/src/openssl/lib_crypto.cr
+++ b/src/openssl/lib_crypto.cr
@@ -36,6 +36,10 @@
{% else %}
@[Link(ldflags: "`command -v pkg-config > /dev/null && pkg-config --libs --silence-errors libcrypto || printf %s '-lcrypto'`")]
{% end %}
+{% if compare_versions(Crystal::VERSION, "1.11.0-dev") >= 0 %}
+ # TODO: if someone brings their own OpenSSL 1.x.y on Windows, will this have a different name?
+ @[Link(dll: "libcrypto-3-x64.dll")]
+{% end %}
lib LibCrypto
alias Char = LibC::Char
alias Int = LibC::Int
diff --git a/src/openssl/lib_ssl.cr b/src/openssl/lib_ssl.cr
index 37a4cea3a161..27faf9bbe185 100644
--- a/src/openssl/lib_ssl.cr
+++ b/src/openssl/lib_ssl.cr
@@ -43,6 +43,11 @@ require "./lib_crypto"
{% else %}
@[Link(ldflags: "`command -v pkg-config > /dev/null && pkg-config --libs --silence-errors libssl || printf %s '-lssl -lcrypto'`")]
{% end %}
+{% if compare_versions(Crystal::VERSION, "1.11.0-dev") >= 0 %}
+ # TODO: if someone brings their own OpenSSL 1.x.y on Windows, will this have a different name?
+ @[Link(dll: "libssl-3-x64.dll")]
+ @[Link(dll: "libcrypto-3-x64.dll")]
+{% end %}
lib LibSSL
alias Int = LibC::Int
alias Char = LibC::Char
diff --git a/src/prelude.cr b/src/prelude.cr
index f06f5bc87015..f84bb86cb3c1 100644
--- a/src/prelude.cr
+++ b/src/prelude.cr
@@ -65,6 +65,7 @@ require "raise"
require "random"
require "range"
require "reference"
+require "reference_storage"
require "regex"
require "set"
{% unless flag?(:wasm32) %}
diff --git a/src/reference_storage.cr b/src/reference_storage.cr
new file mode 100644
index 000000000000..2ca3edc171aa
--- /dev/null
+++ b/src/reference_storage.cr
@@ -0,0 +1,55 @@
+# `ReferenceStorage(T)` provides the minimum storage for the instance data of
+# an object of type `T`. The compiler guarantees that
+# `sizeof(ReferenceStorage(T)) == instance_sizeof(T)` and
+# `alignof(ReferenceStorage(T)) == instance_alignof(T)` always hold, which means
+# `Pointer(ReferenceStorage(T))` and `T` are binary-compatible.
+#
+# `T` must be a non-union reference type.
+#
+# WARNING: `ReferenceStorage` is only necessary for manual memory management,
+# such as creating instances of `T` with a non-default allocator. Therefore,
+# this type is unsafe and no public constructors are defined.
+#
+# WARNING: `ReferenceStorage` is unsuitable when instances of `T` require more
+# than `instance_sizeof(T)` bytes, such as `String` and `Log::Metadata`.
+@[Experimental("This type's API is still under development. Join the discussion about custom reference allocation at [#13481](https://github.com/crystal-lang/crystal/issues/13481).")]
+@[Primitive(:ReferenceStorageType)]
+struct ReferenceStorage(T) < Value
+ private def initialize
+ end
+
+ # Returns whether `self` and *other* are bytewise equal.
+ #
+ # NOTE: This does not call `T#==`, so it works even if `self` or *other* does
+ # not represent a valid instance of `T`. If validity is guaranteed, call
+ # `to_reference == other.to_reference` instead to use `T#==`.
+ def ==(other : ReferenceStorage(T)) : Bool
+ to_bytes == other.to_bytes
+ end
+
+ def ==(other) : Bool
+ false
+ end
+
+ def hash(hasher)
+ to_bytes.hash(hasher)
+ end
+
+ def to_s(io : IO) : Nil
+ io << "ReferenceStorage(#<" << T << ":0x"
+ pointerof(@type_id).address.to_s(io, 16)
+ io << ">)"
+ end
+
+ # Returns a `T` whose instance data refers to `self`.
+ #
+ # WARNING: The caller is responsible for ensuring that the instance data is
+ # correctly initialized and outlives the returned `T`.
+ def to_reference : T
+ pointerof(@type_id).as(T)
+ end
+
+ protected def to_bytes
+ Slice.new(pointerof(@type_id).as(UInt8*), instance_sizeof(T))
+ end
+end
diff --git a/src/regex/lib_pcre.cr b/src/regex/lib_pcre.cr
index 5f110eba0ce7..647a172a9d43 100644
--- a/src/regex/lib_pcre.cr
+++ b/src/regex/lib_pcre.cr
@@ -1,4 +1,7 @@
@[Link("pcre")]
+{% if compare_versions(Crystal::VERSION, "1.11.0-dev") >= 0 %}
+ @[Link(dll: "pcre.dll")]
+{% end %}
lib LibPCRE
alias Int = LibC::Int
diff --git a/src/regex/lib_pcre2.cr b/src/regex/lib_pcre2.cr
index a04761cbe07e..71a0fd4b6639 100644
--- a/src/regex/lib_pcre2.cr
+++ b/src/regex/lib_pcre2.cr
@@ -1,4 +1,7 @@
@[Link("pcre2-8")]
+{% if compare_versions(Crystal::VERSION, "1.11.0-dev") >= 0 %}
+ @[Link(dll: "pcre2-8.dll")]
+{% end %}
lib LibPCRE2
alias Int = LibC::Int
diff --git a/src/set.cr b/src/set.cr
index 091352302c7d..40425e9aa032 100644
--- a/src/set.cr
+++ b/src/set.cr
@@ -382,6 +382,19 @@ struct Set(T)
@hash.keys
end
+ # Returns an `Array` with the results of running *block* against each element of the collection.
+ #
+ # ```
+ # Set{1, 2, 3, 4, 5}.to_a { |i| i // 2 } # => [0, 1, 2]
+ # ```
+ def to_a(& : T -> U) : Array(U) forall U
+ array = Array(U).new(size)
+ @hash.each_key do |key|
+ array << key
+ end
+ array
+ end
+
# Alias of `#to_s`.
def inspect(io : IO) : Nil
to_s(io)
diff --git a/src/signal.cr b/src/signal.cr
index 60eba5b8e7f3..2e085b92311e 100644
--- a/src/signal.cr
+++ b/src/signal.cr
@@ -117,6 +117,24 @@ enum Signal : Int32
Crystal::System::Signal.trap(self, handler)
end
+ # Returns any existing handler for this signal
+ #
+ # ```
+ # Signal::USR1.trap { }
+ # prev_handler = Signal::USR1.trap_handler?
+ #
+ # Signal::USR1.trap do |signal|
+ # prev_handler.try &.call(signal)
+ # # ...
+ # end
+ # ```
+ def trap_handler?
+ {% if @type.has_constant?("CHLD") %}
+ return Crystal::System::Signal.child_handler if self == CHLD
+ {% end %}
+ Crystal::System::Signal.trap_handler?(self)
+ end
+
# Resets the handler for this signal to the OS default.
#
# Note that trying to reset `CHLD` will actually set the default crystal
diff --git a/src/spec.cr b/src/spec.cr
index e9cf5d448efd..c51ee8831de4 100644
--- a/src/spec.cr
+++ b/src/spec.cr
@@ -91,45 +91,51 @@ require "./spec/cli"
# value can be used to rerun the specs in that same order by passing the seed
# value to `--order`.
module Spec
-end
+ # :nodoc:
+ class CLI
+ # :nodoc:
+ #
+ # Implement formatter configuration.
+ def configure_formatter(formatter, output_path = nil)
+ case formatter
+ when "junit"
+ junit_formatter = Spec::JUnitFormatter.file(Path.new(output_path.not_nil!))
+ add_formatter(junit_formatter)
+ when "verbose"
+ override_default_formatter(Spec::VerboseFormatter.new)
+ when "tap"
+ override_default_formatter(Spec::TAPFormatter.new)
+ end
+ end
-Colorize.on_tty_only!
+ def main(args)
+ Colorize.on_tty_only!
-# :nodoc:
-#
-# Implement formatter configuration.
-def Spec.configure_formatter(formatter, output_path = nil)
- case formatter
- when "junit"
- junit_formatter = Spec::JUnitFormatter.file(Path.new(output_path.not_nil!))
- Spec.add_formatter(junit_formatter)
- when "verbose"
- Spec.override_default_formatter(Spec::VerboseFormatter.new)
- when "tap"
- Spec.override_default_formatter(Spec::TAPFormatter.new)
- end
-end
+ begin
+ option_parser.parse(args)
+ rescue e : OptionParser::InvalidOption
+ abort("Error: #{e.message}")
+ end
-begin
- Spec.option_parser.parse(ARGV)
-rescue e : OptionParser::InvalidOption
- abort("Error: #{e.message}")
-end
+ unless args.empty?
+ STDERR.puts "Error: unknown argument '#{args.first}'"
+ exit 1
+ end
-unless ARGV.empty?
- STDERR.puts "Error: unknown argument '#{ARGV.first}'"
- exit 1
-end
+ if ENV["SPEC_VERBOSE"]? == "1"
+ override_default_formatter(Spec::VerboseFormatter.new)
+ end
-if ENV["SPEC_VERBOSE"]? == "1"
- Spec.override_default_formatter(Spec::VerboseFormatter.new)
-end
+ add_split_filter ENV["SPEC_SPLIT"]?
-Spec.add_split_filter ENV["SPEC_SPLIT"]?
+ {% unless flag?(:wasm32) %}
+ # TODO(wasm): Enable this once `Process.on_interrupt` is implemented
+ Process.on_interrupt { abort! }
+ {% end %}
-{% unless flag?(:wasm32) %}
- # TODO(wasm): Enable this once `Process.on_interrupt` is implemented
- Process.on_interrupt { Spec.abort! }
-{% end %}
+ run
+ end
+ end
+end
-Spec.run
+Spec.cli.main(ARGV)
diff --git a/src/spec/cli.cr b/src/spec/cli.cr
index e17f59206123..4f57c3d4adbb 100644
--- a/src/spec/cli.cr
+++ b/src/spec/cli.cr
@@ -1,139 +1,130 @@
require "option_parser"
+require "colorize"
# This file is included in the compiler to add usage instructions for the
# spec runner on `crystal spec --help`.
module Spec
# :nodoc:
- class_property pattern : Regex?
-
- # :nodoc:
- class_property line : Int32?
-
- # :nodoc:
- class_property slowest : Int32?
-
- # :nodoc:
- class_property? fail_fast = false
-
- # :nodoc:
- class_property? focus = false
-
- # :nodoc:
- class_property? dry_run = false
-
- # :nodoc:
- class_property? list_tags = false
-
- # :nodoc:
- def self.add_location(file, line)
- locations = @@locations ||= {} of String => Array(Int32)
- locations.put_if_absent(File.expand_path(file)) { [] of Int32 } << line
- end
+ #
+ # Configuration for a spec runner. More global state is defined in `./dsl.cr`.
+ class CLI
+ getter pattern : Regex?
+ getter line : Int32?
+ getter slowest : Int32?
+ getter? fail_fast = false
+ property? focus = false
+ getter? dry_run = false
+ getter? list_tags = false
- # :nodoc:
- def self.add_tag(tag)
- if anti_tag = tag.lchop?('~')
- (@@anti_tags ||= Set(String).new) << anti_tag
- else
- (@@tags ||= Set(String).new) << tag
+ def add_location(file, line)
+ locations = @locations ||= {} of String => Array(Int32)
+ locations.put_if_absent(File.expand_path(file)) { [] of Int32 } << line
end
- end
-
- # :nodoc:
- class_getter randomizer_seed : UInt64?
- class_getter randomizer : Random::PCG32?
- # :nodoc:
- def self.order=(mode)
- seed =
- case mode
- when "default"
- nil
- when "random"
- Random::Secure.rand(1..99999).to_u64 # 5 digits or less for simplicity
- when UInt64
- mode
+ def add_tag(tag)
+ if anti_tag = tag.lchop?('~')
+ (@anti_tags ||= Set(String).new) << anti_tag
else
- raise ArgumentError.new("Order must be either 'default', 'random', or a numeric seed value")
+ (@tags ||= Set(String).new) << tag
end
+ end
- @@randomizer_seed = seed
- @@randomizer = seed ? Random::PCG32.new(seed) : nil
- end
+ getter randomizer_seed : UInt64?
+ getter randomizer : Random::PCG32?
- # :nodoc:
- class_property option_parser : OptionParser = begin
- OptionParser.new do |opts|
- opts.banner = "crystal spec runner"
- opts.on("-e", "--example STRING", "run examples whose full nested names include STRING") do |pattern|
- Spec.pattern = Regex.new(Regex.escape(pattern))
- end
- opts.on("-l", "--line LINE", "run examples whose line matches LINE") do |line|
- Spec.line = line.to_i
- end
- opts.on("-p", "--profile", "Print the 10 slowest specs") do
- Spec.slowest = 10
- end
- opts.on("--fail-fast", "abort the run on first failure") do
- Spec.fail_fast = true
- end
- opts.on("--location file:line", "run example at line 'line' in file 'file', multiple allowed") do |location|
- if location =~ /\A(.+?)\:(\d+)\Z/
- Spec.add_location $1, $2.to_i
+ def order=(mode)
+ seed =
+ case mode
+ when "default"
+ nil
+ when "random"
+ Random::Secure.rand(1..99999).to_u64 # 5 digits or less for simplicity
+ when UInt64
+ mode
else
- STDERR.puts "location #{location} must be file:line"
- exit 1
+ raise ArgumentError.new("Order must be either 'default', 'random', or a numeric seed value")
end
- end
- opts.on("--tag TAG", "run examples with the specified TAG, or exclude examples by adding ~ before the TAG.") do |tag|
- Spec.add_tag tag
- end
- opts.on("--list-tags", "lists all the tags used.") do
- Spec.list_tags = true
- end
- opts.on("--order MODE", "run examples in random order by passing MODE as 'random' or to a specific seed by passing MODE as the seed value") do |mode|
- if mode.in?("default", "random")
- Spec.order = mode
- elsif seed = mode.to_u64?
- Spec.order = seed
- else
- abort("order must be either 'default', 'random', or a numeric seed value")
+
+ @randomizer_seed = seed
+ @randomizer = seed ? Random::PCG32.new(seed) : nil
+ end
+
+ def option_parser : OptionParser
+ @option_parser ||= OptionParser.new do |opts|
+ opts.banner = "crystal spec runner"
+ opts.on("-e", "--example STRING", "run examples whose full nested names include STRING") do |pattern|
+ @pattern = Regex.new(Regex.escape(pattern))
+ end
+ opts.on("-l", "--line LINE", "run examples whose line matches LINE") do |line|
+ @line = line.to_i
+ end
+ opts.on("-p", "--profile", "Print the 10 slowest specs") do
+ @slowest = 10
+ end
+ opts.on("--fail-fast", "abort the run on first failure") do
+ @fail_fast = true
+ end
+ opts.on("--location file:line", "run example at line 'line' in file 'file', multiple allowed") do |location|
+ if location =~ /\A(.+?)\:(\d+)\Z/
+ add_location $1, $2.to_i
+ else
+ STDERR.puts "location #{location} must be file:line"
+ exit 1
+ end
+ end
+ opts.on("--tag TAG", "run examples with the specified TAG, or exclude examples by adding ~ before the TAG.") do |tag|
+ add_tag tag
+ end
+ opts.on("--list-tags", "lists all the tags used.") do
+ @list_tags = true
+ end
+ opts.on("--order MODE", "run examples in random order by passing MODE as 'random' or to a specific seed by passing MODE as the seed value") do |mode|
+ if mode.in?("default", "random")
+ self.order = mode
+ elsif seed = mode.to_u64?
+ self.order = seed
+ else
+ abort("order must be either 'default', 'random', or a numeric seed value")
+ end
+ end
+ opts.on("--junit_output OUTPUT_PATH", "generate JUnit XML output within the given OUTPUT_PATH") do |output_path|
+ configure_formatter("junit", output_path)
+ end
+ opts.on("-h", "--help", "show this help") do |pattern|
+ puts opts
+ exit
+ end
+ opts.on("-v", "--verbose", "verbose output") do
+ configure_formatter("verbose")
+ end
+ opts.on("--tap", "Generate TAP output (Test Anything Protocol)") do
+ configure_formatter("tap")
+ end
+ opts.on("--color", "Enabled ANSI colored output") do
+ Colorize.enabled = true
+ end
+ opts.on("--no-color", "Disable ANSI colored output") do
+ Colorize.enabled = false
+ end
+ opts.on("--dry-run", "Pass all tests without execution") do
+ @dry_run = true
+ end
+ opts.unknown_args do |args|
end
- end
- opts.on("--junit_output OUTPUT_PATH", "generate JUnit XML output within the given OUTPUT_PATH") do |output_path|
- configure_formatter("junit", output_path)
- end
- opts.on("-h", "--help", "show this help") do |pattern|
- puts opts
- exit
- end
- opts.on("-v", "--verbose", "verbose output") do
- configure_formatter("verbose")
- end
- opts.on("--tap", "Generate TAP output (Test Anything Protocol)") do
- configure_formatter("tap")
- end
- opts.on("--color", "Enabled ANSI colored output") do
- Colorize.enabled = true
- end
- opts.on("--no-color", "Disable ANSI colored output") do
- Colorize.enabled = false
- end
- opts.on("--dry-run", "Pass all tests without execution") do
- Spec.dry_run = true
- end
- opts.unknown_args do |args|
end
end
+
+ # Blank implementation to reduce the interface of spec's option parser for
+ # inclusion in the compiler. This avoids depending on more of `Spec`
+ # module.
+ # The real implementation in `../spec.cr` overrides this for actual use.
+ def configure_formatter(formatter, output_path = nil)
+ end
end
- # :nodoc:
- #
- # Blank implementation to reduce the interface of spec's option parser for
- # inclusion in the compiler. This avoids depending on more of `Spec`
- # module.
- # The real implementation in `../spec.cr` overrides this for actual use.
- def self.configure_formatter(formatter, output_path = nil)
+ @[Deprecated("This is an internal API.")]
+ def self.randomizer : Random::PCG32?
+ @@cli.randomizer
end
end
diff --git a/src/spec/context.cr b/src/spec/context.cr
index 0a1109c12b92..c18836fe0455 100644
--- a/src/spec/context.cr
+++ b/src/spec/context.cr
@@ -126,13 +126,15 @@ module Spec
exception : Exception?
# :nodoc:
- def self.root_context
- RootContext.instance
- end
+ class CLI
+ def root_context
+ RootContext.instance
+ end
- # :nodoc:
- def self.current_context : Context
- RootContext.current_context
+ # :nodoc:
+ def current_context : Context
+ RootContext.current_context
+ end
end
# :nodoc:
@@ -167,7 +169,7 @@ module Spec
end
def report_formatters(result)
- Spec.formatters.each(&.report(result))
+ Spec.cli.formatters.each(&.report(result))
end
def succeeded
@@ -175,8 +177,8 @@ module Spec
end
def finish(elapsed_time, aborted = false)
- Spec.formatters.each(&.finish(elapsed_time, aborted))
- Spec.formatters.each(&.print_results(elapsed_time, aborted))
+ Spec.cli.formatters.each(&.finish(elapsed_time, aborted))
+ Spec.cli.formatters.each(&.print_results(elapsed_time, aborted))
end
def print_results(elapsed_time, aborted = false)
@@ -223,13 +225,13 @@ module Spec
end
end
- if Spec.slowest
+ if Spec.cli.slowest
puts
results = results_for(:success) + results_for(:fail)
- top_n = results.sort_by { |res| -res.elapsed.not_nil!.to_f }[0..Spec.slowest.not_nil!]
+ top_n = results.sort_by { |res| -res.elapsed.not_nil!.to_f }[0..Spec.cli.slowest.not_nil!]
top_n_time = top_n.sum &.elapsed.not_nil!.total_seconds
percent = (top_n_time * 100) / elapsed_time.total_seconds
- puts "Top #{Spec.slowest} slowest examples (#{top_n_time.humanize} seconds, #{percent.round(2)}% of total time):"
+ puts "Top #{Spec.cli.slowest} slowest examples (#{top_n_time.humanize} seconds, #{percent.round(2)}% of total time):"
top_n.each do |res|
puts " #{res.description}"
res_elapsed = res.elapsed.not_nil!.total_seconds.humanize
@@ -252,7 +254,7 @@ module Spec
puts "Aborted!".colorize.red if aborted
puts "Finished in #{Spec.to_human(elapsed_time)}"
puts Spec.color("#{total} examples, #{failures.size} failures, #{errors.size} errors, #{pendings.size} pending", final_status)
- puts Spec.color("Only running `focus: true`", :focus) if Spec.focus?
+ puts Spec.color("Only running `focus: true`", :focus) if Spec.cli.focus?
unless failures_and_errors.empty?
puts
@@ -268,13 +270,13 @@ module Spec
end
def print_order_message
- if randomizer_seed = Spec.randomizer_seed
+ if randomizer_seed = Spec.cli.randomizer_seed
puts Spec.color("Randomized with seed: #{randomizer_seed}", :order)
end
end
def describe(description, file, line, end_line, focus, tags, &block)
- Spec.focus = true if focus
+ Spec.cli.focus = true if focus
context = Spec::ExampleGroup.new(@@current_context, description, file, line, end_line, focus, tags)
@@current_context.children << context
@@ -298,7 +300,7 @@ module Spec
private def add_example(description, file, line, end_line, focus, tags, block)
check_nesting_spec(file, line) do
- Spec.focus = true if focus
+ Spec.cli.focus = true if focus
@@current_context.children <<
Example.new(@@current_context, description, file, line, end_line, focus, tags, block)
end
@@ -334,12 +336,12 @@ module Spec
# :nodoc:
def run
- Spec.formatters.each(&.push(self))
+ Spec.cli.formatters.each(&.push(self))
ran = run_around_all_hooks(ExampleGroup::Procsy.new(self) { internal_run })
ran || internal_run
- Spec.formatters.each(&.pop)
+ Spec.cli.formatters.each(&.pop)
end
protected def report(status : Status, description, file, line, elapsed = nil, ex = nil)
diff --git a/src/spec/dsl.cr b/src/spec/dsl.cr
index 065b31e7aff4..578076b86d69 100644
--- a/src/spec/dsl.cr
+++ b/src/spec/dsl.cr
@@ -2,6 +2,10 @@ require "colorize"
require "option_parser"
module Spec
+ # :nodoc:
+ # The default spec runner.
+ class_getter cli = CLI.new
+
# :nodoc:
enum InfoKind
Comment
@@ -61,14 +65,6 @@ module Spec
class NestingSpecError < SpecError
end
- @@aborted = false
-
- # :nodoc:
- def self.abort!
- @@aborted = true
- finish_run
- end
-
# :nodoc:
def self.to_human(span : Time::Span)
total_milliseconds = span.total_milliseconds
@@ -92,17 +88,6 @@ module Spec
record SplitFilter, remainder : Int32, quotient : Int32
- @@split_filter : SplitFilter? = nil
-
- def self.add_split_filter(filter)
- if filter
- r, _, m = filter.partition('%')
- @@split_filter = SplitFilter.new(remainder: r.to_i, quotient: m.to_i)
- else
- @@split_filter = nil
- end
- end
-
# Instructs the spec runner to execute the given block
# before each spec in the spec suite.
#
@@ -118,7 +103,7 @@ module Spec
#
# will print, just before each spec, 1 and then 2.
def self.before_each(&block)
- root_context.before_each(&block)
+ @@cli.root_context.before_each(&block)
end
# Instructs the spec runner to execute the given block
@@ -136,7 +121,7 @@ module Spec
#
# will print, just after each spec, 2 and then 1.
def self.after_each(&block)
- root_context.after_each(&block)
+ @@cli.root_context.after_each(&block)
end
# Instructs the spec runner to execute the given block
@@ -154,7 +139,7 @@ module Spec
#
# will print, just before the spec suite starts, 1 and then 2.
def self.before_suite(&block)
- root_context.before_all(&block)
+ @@cli.root_context.before_all(&block)
end
# Instructs the spec runner to execute the given block
@@ -172,7 +157,7 @@ module Spec
#
# will print, just after the spec suite ends, 2 and then 1.
def self.after_suite(&block)
- root_context.after_all(&block)
+ @@cli.root_context.after_all(&block)
end
# Instructs the spec runner to execute the given block when each spec in the
@@ -196,129 +181,157 @@ module Spec
# it { }
# ```
def self.around_each(&block : Example::Procsy ->)
- root_context.around_each(&block)
+ @@cli.root_context.around_each(&block)
end
- @@start_time : Time::Span? = nil
-
# :nodoc:
- def self.run
- @@start_time = Time.monotonic
-
- at_exit do |status|
- # Do not run specs if the process is exiting on an error
- next unless status == 0
-
- begin
- if Spec.list_tags?
- execute_list_tags
- else
- execute_examples
+ class CLI
+ @aborted = false
+
+ def abort!
+ @aborted = true
+ finish_run
+ end
+
+ @split_filter : SplitFilter? = nil
+
+ def add_split_filter(filter)
+ if filter
+ r, _, m = filter.partition('%')
+ @split_filter = SplitFilter.new(remainder: r.to_i, quotient: m.to_i)
+ else
+ @split_filter = nil
+ end
+ end
+
+ @start_time : Time::Span? = nil
+
+ def run
+ @start_time = Time.monotonic
+
+ at_exit do |status|
+ # Do not run specs if the process is exiting on an error
+ next unless status == 0
+
+ begin
+ if list_tags?
+ execute_list_tags
+ else
+ execute_examples
+ end
+ rescue ex
+ STDERR.print "Unhandled exception: "
+ ex.inspect_with_backtrace(STDERR)
+ STDERR.flush
+ @aborted = true
+ ensure
+ finish_run unless list_tags?
end
- rescue ex
- STDERR.print "Unhandled exception: "
- ex.inspect_with_backtrace(STDERR)
- STDERR.flush
- @@aborted = true
- ensure
- finish_run unless Spec.list_tags?
end
end
- end
- # :nodoc:
- def self.execute_examples
- log_setup
- maybe_randomize
- run_filters
- root_context.run
- end
+ def execute_examples
+ log_setup
+ maybe_randomize
+ run_filters
+ root_context.run
+ end
- # :nodoc:
- def self.execute_list_tags
- run_filters
- tag_counts = collect_tags(root_context)
- print_list_tags(tag_counts)
- end
+ def execute_list_tags
+ run_filters
+ tag_counts = collect_tags(root_context)
+ print_list_tags(tag_counts)
+ end
- private def self.collect_tags(context) : Hash(String, Int32)
- tag_counts = Hash(String, Int32).new(0)
- collect_tags(tag_counts, context, Set(String).new)
- tag_counts
- end
+ private def collect_tags(context) : Hash(String, Int32)
+ tag_counts = Hash(String, Int32).new(0)
+ collect_tags(tag_counts, context, Set(String).new)
+ tag_counts
+ end
- private def self.collect_tags(tag_counts, context : Context, tags)
- if context.responds_to?(:tags) && (context_tags = context.tags)
- tags += context_tags
+ private def collect_tags(tag_counts, context : Context, tags)
+ if context.responds_to?(:tags) && (context_tags = context.tags)
+ tags += context_tags
+ end
+ context.children.each do |child|
+ collect_tags(tag_counts, child, tags)
+ end
end
- context.children.each do |child|
- collect_tags(tag_counts, child, tags)
+
+ private def collect_tags(tag_counts, example : Example, tags)
+ if example_tags = example.tags
+ tags += example_tags
+ end
+ if tags.empty?
+ tag_counts.update("untagged") { |count| count + 1 }
+ else
+ tags.tally(tag_counts)
+ end
end
- end
- private def self.collect_tags(tag_counts, example : Example, tags)
- if example_tags = example.tags
- tags += example_tags
+ private def print_list_tags(tag_counts : Hash(String, Int32)) : Nil
+ return if tag_counts.empty?
+ longest_name_size = tag_counts.keys.max_of(&.size)
+ tag_counts.to_a.sort_by! { |k, v| {-v, k} }.each do |tag_name, count|
+ puts "#{tag_name.rjust(longest_name_size)}: #{count}"
+ end
end
- if tags.empty?
- tag_counts.update("untagged") { |count| count + 1 }
- else
- tags.tally(tag_counts)
+
+ # :nodoc:
+ #
+ # Workaround for #8914
+ private macro defined?(t)
+ {% if t.resolve? %}
+ {{ yield }}
+ {% end %}
end
- end
- private def self.print_list_tags(tag_counts : Hash(String, Int32)) : Nil
- return if tag_counts.empty?
- longest_name_size = tag_counts.keys.max_of(&.size)
- tag_counts.to_a.sort_by! { |k, v| {-v, k} }.each do |tag_name, count|
- puts "#{tag_name.rjust(longest_name_size)}: #{count}"
+ # :nodoc:
+ def log_setup
end
- end
- # :nodoc:
- #
- # Workaround for #8914
- private macro defined?(t)
- {% if t.resolve? %}
- {{ yield }}
- {% end %}
- end
+ # :nodoc:
+ macro finished
+ # :nodoc:
+ #
+ # Initialized the log module for the specs.
+ # If the "log" module is required it is configured to emit no entries by default.
+ def log_setup
+ defined?(::Log) do
+ if Log.responds_to?(:setup)
+ Log.setup_from_env(default_level: :none)
+ end
+ end
+ end
+ end
- # :nodoc:
- def self.log_setup
- end
+ def finish_run
+ elapsed_time = Time.monotonic - @start_time.not_nil!
+ root_context.finish(elapsed_time, @aborted)
+ exit 1 if !root_context.succeeded || @aborted || (focus? && ENV["SPEC_FOCUS_NO_FAIL"]? != "1")
+ end
- # :nodoc:
- macro finished
# :nodoc:
- #
- # Initialized the log module for the specs.
- # If the "log" module is required it is configured to emit no entries by default.
- def self.log_setup
- defined?(::Log) do
- if Log.responds_to?(:setup)
- Log.setup_from_env(default_level: :none)
- end
+ def maybe_randomize
+ if randomizer = @randomizer
+ root_context.randomize(randomizer)
end
end
- end
- def self.finish_run
- elapsed_time = Time.monotonic - @@start_time.not_nil!
- root_context.finish(elapsed_time, @@aborted)
- exit 1 if !root_context.succeeded || @@aborted || (focus? && ENV["SPEC_FOCUS_NO_FAIL"]? != "1")
+ # :nodoc:
+ def run_filters
+ root_context.run_filters(@pattern, @line, @locations, @split_filter, @focus, @tags, @anti_tags)
+ end
end
- # :nodoc:
- def self.maybe_randomize
- if randomizer = @@randomizer
- root_context.randomize(randomizer)
- end
+ @[Deprecated("This is an internal API.")]
+ def self.finish_run
+ @@cli.finish_run
end
- # :nodoc:
- def self.run_filters
- root_context.run_filters(@@pattern, @@line, @@locations, @@split_filter, @@focus, @@tags, @@anti_tags)
+ @[Deprecated("This is an internal API.")]
+ def self.add_split_filter(filter)
+ @@cli.add_split_filter(filter)
end
end
diff --git a/src/spec/example.cr b/src/spec/example.cr
index e6ae51942a38..72bffd6c0e07 100644
--- a/src/spec/example.cr
+++ b/src/spec/example.cr
@@ -18,10 +18,10 @@ module Spec
# :nodoc:
def run
- Spec.root_context.check_nesting_spec(file, line) do
- Spec.formatters.each(&.before_example(description))
+ Spec.cli.root_context.check_nesting_spec(file, line) do
+ Spec.cli.formatters.each(&.before_example(description))
- if Spec.dry_run?
+ if Spec.cli.dry_run?
@parent.report(:success, description, file, line)
return
end
@@ -51,12 +51,12 @@ module Spec
@parent.report(:success, description, file, line, Time.monotonic - start)
rescue ex : Spec::AssertionFailed
@parent.report(:fail, description, file, line, Time.monotonic - start, ex)
- Spec.abort! if Spec.fail_fast?
+ Spec.cli.abort! if Spec.cli.fail_fast?
rescue ex : Spec::ExamplePending
@parent.report(:pending, description, file, line, Time.monotonic - start)
rescue ex
@parent.report(:error, description, file, line, Time.monotonic - start, ex)
- Spec.abort! if Spec.fail_fast?
+ Spec.cli.abort! if Spec.cli.fail_fast?
ensure
@parent.run_after_each_hooks
end
diff --git a/src/spec/formatter.cr b/src/spec/formatter.cr
index 51b355ec075f..cfd88f2b5a6a 100644
--- a/src/spec/formatter.cr
+++ b/src/spec/formatter.cr
@@ -55,7 +55,7 @@ module Spec
end
def print_results(elapsed_time : Time::Span, aborted : Bool)
- Spec.root_context.print_results(elapsed_time, aborted)
+ Spec.cli.root_context.print_results(elapsed_time, aborted)
end
end
@@ -111,22 +111,34 @@ module Spec
end
def print_results(elapsed_time : Time::Span, aborted : Bool)
- Spec.root_context.print_results(elapsed_time, aborted)
+ Spec.cli.root_context.print_results(elapsed_time, aborted)
end
end
- @@formatters = [Spec::DotFormatter.new] of Spec::Formatter
-
# :nodoc:
- def self.formatters
- @@formatters
+ class CLI
+ @formatters = [Spec::DotFormatter.new] of Spec::Formatter
+
+ def formatters
+ @formatters
+ end
+
+ def override_default_formatter(formatter)
+ @formatters[0] = formatter
+ end
+
+ def add_formatter(formatter)
+ @formatters << formatter
+ end
end
+ @[Deprecated("This is an internal API.")]
def self.override_default_formatter(formatter)
- @@formatters[0] = formatter
+ @@cli.override_default_formatter(formatter)
end
+ @[Deprecated("This is an internal API.")]
def self.add_formatter(formatter)
- @@formatters << formatter
+ @@cli.add_formatter(formatter)
end
end
diff --git a/src/spec/methods.cr b/src/spec/methods.cr
index f98326be0ed3..54b8de34b9bb 100644
--- a/src/spec/methods.cr
+++ b/src/spec/methods.cr
@@ -17,7 +17,7 @@ module Spec::Methods
#
# If `focus` is `true`, only this `describe`, and others marked with `focus: true`, will run.
def describe(description = nil, file = __FILE__, line = __LINE__, end_line = __END_LINE__, focus : Bool = false, tags : String | Enumerable(String) | Nil = nil, &block)
- Spec.root_context.describe(description.to_s, file, line, end_line, focus, tags, &block)
+ Spec.cli.root_context.describe(description.to_s, file, line, end_line, focus, tags, &block)
end
# Defines an example group that establishes a specific context,
@@ -46,7 +46,7 @@ module Spec::Methods
#
# If `focus` is `true`, only this test, and others marked with `focus: true`, will run.
def it(description = "assert", file = __FILE__, line = __LINE__, end_line = __END_LINE__, focus : Bool = false, tags : String | Enumerable(String) | Nil = nil, &block)
- Spec.root_context.it(description.to_s, file, line, end_line, focus, tags, &block)
+ Spec.cli.root_context.it(description.to_s, file, line, end_line, focus, tags, &block)
end
# Defines a pending test case.
@@ -72,7 +72,7 @@ module Spec::Methods
#
# If `focus` is `true`, only this test, and others marked with `focus: true`, will run.
def pending(description = "assert", file = __FILE__, line = __LINE__, end_line = __END_LINE__, focus : Bool = false, tags : String | Enumerable(String) | Nil = nil)
- Spec.root_context.pending(description.to_s, file, line, end_line, focus, tags)
+ Spec.cli.root_context.pending(description.to_s, file, line, end_line, focus, tags)
end
# Fails an example.
@@ -124,10 +124,10 @@ module Spec::Methods
# end
# ```
def before_each(&block)
- if Spec.current_context.is_a?(RootContext)
+ if Spec.cli.current_context.is_a?(RootContext)
raise "Can't call `before_each` outside of a describe/context"
end
- Spec.current_context.before_each(&block)
+ Spec.cli.current_context.before_each(&block)
end
# Executes the given block after each spec in the current context runs.
@@ -154,10 +154,10 @@ module Spec::Methods
# end
# ```
def after_each(&block)
- if Spec.current_context.is_a?(RootContext)
+ if Spec.cli.current_context.is_a?(RootContext)
raise "Can't call `after_each` outside of a describe/context"
end
- Spec.current_context.after_each(&block)
+ Spec.cli.current_context.after_each(&block)
end
# Executes the given block before the first spec in the current context runs.
@@ -184,10 +184,10 @@ module Spec::Methods
# end
# ```
def before_all(&block)
- if Spec.current_context.is_a?(RootContext)
+ if Spec.cli.current_context.is_a?(RootContext)
raise "Can't call `before_all` outside of a describe/context"
end
- Spec.current_context.before_all(&block)
+ Spec.cli.current_context.before_all(&block)
end
# Executes the given block after the last spec in the current context runs.
@@ -214,10 +214,10 @@ module Spec::Methods
# end
# ```
def after_all(&block)
- if Spec.current_context.is_a?(RootContext)
+ if Spec.cli.current_context.is_a?(RootContext)
raise "Can't call `after_all` outside of a describe/context"
end
- Spec.current_context.after_all(&block)
+ Spec.cli.current_context.after_all(&block)
end
# Executes the given block when each spec in the current context runs.
@@ -252,10 +252,10 @@ module Spec::Methods
# end
# ```
def around_each(&block : Example::Procsy ->)
- if Spec.current_context.is_a?(RootContext)
+ if Spec.cli.current_context.is_a?(RootContext)
raise "Can't call `around_each` outside of a describe/context"
end
- Spec.current_context.around_each(&block)
+ Spec.cli.current_context.around_each(&block)
end
# Executes the given block when the current context runs.
@@ -297,10 +297,10 @@ module Spec::Methods
# end
# ```
def around_all(&block : ExampleGroup::Procsy ->)
- if Spec.current_context.is_a?(RootContext)
+ if Spec.cli.current_context.is_a?(RootContext)
raise "Can't call `around_all` outside of a describe/context"
end
- Spec.current_context.around_all(&block)
+ Spec.cli.current_context.around_all(&block)
end
end
diff --git a/src/string.cr b/src/string.cr
index 98b7ec3884fd..4004f0d34929 100644
--- a/src/string.cr
+++ b/src/string.cr
@@ -4198,7 +4198,6 @@ class String
count = 0
match_offset = slice_offset = 0
- options = Regex::MatchOptions::None
while match = separator.match_at_byte_index(self, match_offset, options: options)
index = match.byte_begin(0)
match_bytesize = match.byte_end(0) - index
@@ -4744,7 +4743,6 @@ class String
def scan(pattern : Regex, *, options : Regex::MatchOptions = Regex::MatchOptions::None, &) : self
byte_offset = 0
- options = Regex::MatchOptions::None
while match = pattern.match_at_byte_index(self, byte_offset, options: options)
index = match.byte_begin(0)
$~ = match
diff --git a/src/string/builder.cr b/src/string/builder.cr
index 0fb77f4ca41b..a06644b831d1 100644
--- a/src/string/builder.cr
+++ b/src/string/builder.cr
@@ -41,21 +41,14 @@ class String::Builder < IO
return if slice.empty?
count = slice.size
- new_bytesize = real_bytesize + count
- if new_bytesize > @capacity
- resize_to_capacity(Math.pw2ceil(new_bytesize))
- end
+ increase_capacity_by count
slice.copy_to(@buffer + real_bytesize, count)
@bytesize += count
end
def write_byte(byte : UInt8) : Nil
- new_bytesize = real_bytesize + 1
- if new_bytesize > @capacity
- resize_to_capacity(Math.pw2ceil(new_bytesize))
- end
-
+ increase_capacity_by 1
@buffer[real_bytesize] = byte
@bytesize += 1
@@ -108,17 +101,18 @@ class String::Builder < IO
raise "Can only invoke 'to_s' once on String::Builder" if @finished
@finished = true
- write_byte 0_u8
+ real_bytesize = real_bytesize()
+ @buffer[real_bytesize] = 0_u8
+ real_bytesize += 1
# Try to reclaim some memory if capacity is bigger than what we need
- real_bytesize = real_bytesize()
if @capacity > real_bytesize
resize_to_capacity(real_bytesize)
end
String.set_crystal_type_id(@buffer)
str = @buffer.as(String)
- str.initialize_header((bytesize - 1).to_i)
+ str.initialize_header(bytesize)
str
end
@@ -126,6 +120,26 @@ class String::Builder < IO
@bytesize + String::HEADER_SIZE
end
+ private def increase_capacity_by(count)
+ raise IO::EOFError.new if count >= Int32::MAX - real_bytesize
+
+ new_bytesize = real_bytesize + count
+ return if new_bytesize <= @capacity
+
+ new_capacity = calculate_new_capacity(new_bytesize)
+ resize_to_capacity(new_capacity)
+ end
+
+ private def calculate_new_capacity(new_bytesize)
+ # If the new bytesize is bigger than 1 << 30, the next power of two would
+ # be 1 << 31, which is out of range for Int32.
+ # So we limit the capacity to Int32::MAX in order to be able to use the
+ # range (1 << 30) < new_bytesize < Int32::MAX
+ return Int32::MAX if new_bytesize > 1 << 30
+
+ Math.pw2ceil(new_bytesize)
+ end
+
private def resize_to_capacity(capacity)
@capacity = capacity
@buffer = GC.realloc(@buffer, @capacity)
diff --git a/src/string/formatter.cr b/src/string/formatter.cr
index e85322f39d2e..b5f80d2aee87 100644
--- a/src/string/formatter.cr
+++ b/src/string/formatter.cr
@@ -2,6 +2,13 @@ require "c/stdio"
# :nodoc:
struct String::Formatter(A)
+ # FIXME: wasm32 appears to run out of memory if we use Ryu Printf, which
+ # initializes very large lookup tables, so we fall back to `LibC.snprintf` for
+ # the floating-point format specifiers (#13918)
+ {% begin %}
+ HAS_RYU_PRINTF = {{ !flag?(:wasm32) }}
+ {% end %}
+
private enum Mode
None
@@ -15,15 +22,19 @@ struct String::Formatter(A)
Named
end
- @format_buf = Pointer(UInt8).null
- @temp_buf = Pointer(UInt8).null
+ {% unless HAS_RYU_PRINTF %}
+ @format_buf = Pointer(UInt8).null
+ @format_buf_len = 0
+
+ @temp_buf = Pointer(UInt8).null
+ @temp_buf_len = 0
+ {% end %}
+
@arg_mode : Mode = :none
def initialize(string, @args : A, @io : IO)
@reader = Char::Reader.new(string)
@arg_index = 0
- @temp_buf_len = 0
- @format_buf_len = 0
end
def format : Nil
@@ -118,13 +129,17 @@ struct String::Formatter(A)
next
else
flags.width = val
- flags.width_size = size
+ {% unless HAS_RYU_PRINTF %}
+ flags.width_size = size
+ {% end %}
break
end
when '*'
val = consume_dynamic_value
flags.width = val
- flags.width_size = val.to_s.size
+ {% unless HAS_RYU_PRINTF %}
+ flags.width_size = val.to_s.size
+ {% end %}
break
else
break
@@ -141,16 +156,22 @@ struct String::Formatter(A)
when '0'..'9'
num, size = consume_number
flags.precision = num
- flags.precision_size = size
+ {% unless HAS_RYU_PRINTF %}
+ flags.precision_size = size
+ {% end %}
when '*'
val = consume_dynamic_value
if val >= 0
flags.precision = val
- flags.precision_size = val.to_s.size
+ {% unless HAS_RYU_PRINTF %}
+ flags.precision_size = val.to_s.size
+ {% end %}
end
else
flags.precision = 0
- flags.precision_size = 1
+ {% unless HAS_RYU_PRINTF %}
+ flags.precision_size = 1
+ {% end %}
end
end
flags
@@ -307,12 +328,7 @@ struct String::Formatter(A)
elsif float.nan?
float_special("nan", 1, flags)
else
- # FIXME: wasm32 appears to run out of memory if we use Ryu Printf, which
- # initializes very large lookup tables, so we always fall back to
- # `LibC.snprintf` (#13918)
- {% if flag?(:wasm32) %}
- float_fallback(float, flags)
- {% else %}
+ {% if HAS_RYU_PRINTF %}
case flags.type
when 'f'
float_fixed(float, flags)
@@ -325,6 +341,8 @@ struct String::Formatter(A)
else
raise "BUG: Unknown format type '#{flags.type}'"
end
+ {% else %}
+ float_fallback(float, flags)
{% end %}
end
else
@@ -346,7 +364,7 @@ struct String::Formatter(A)
pad(str_size, flags) if flags.right_padding?
end
- {% unless flag?(:wasm32) %}
+ {% if HAS_RYU_PRINTF %}
# Formats floats with `%f`
private def float_fixed(float, flags)
# the longest string possible is due to `Float64::MIN_SUBNORMAL`, which
@@ -430,8 +448,37 @@ struct String::Formatter(A)
# Formats floats with `%g` or `%G`
private def float_general(float, flags)
- # TODO: implement using `Float::Printer::RyuPrintf`
- float_fallback(float, flags)
+ # `d2gen_buffered_n` will always take care of trailing zeros and return
+ # the number of stripped digits
+ precision = flags.precision.try(&.to_u32) || 6_u32
+
+ printf_buf = uninitialized UInt8[773]
+ printf_size, trailing_zeros =
+ Float::Printer::RyuPrintf.d2gen_buffered_n(float.abs, precision, printf_buf.to_unsafe, flags.sharp)
+ printf_slice = printf_buf.to_slice[0, printf_size]
+ dot_index = printf_slice.index('.'.ord)
+ e_index = printf_slice.rindex('e'.ord)
+ sign = Math.copysign(1.0, float)
+
+ printf_slice[e_index] = 'E'.ord.to_u8! if e_index && flags.uppercase?
+
+ str_size = printf_size
+ str_size += 1 if sign < 0 || flags.plus || flags.space
+ str_size += (dot_index.nil? ? 1 : 0) + trailing_zeros if flags.sharp
+
+ pad(str_size, flags) if flags.left_padding? && flags.padding_char != '0'
+
+ # this preserves -0.0's sign correctly
+ write_plus_or_space(sign, flags)
+ @io << '-' if sign < 0
+
+ pad(str_size, flags) if flags.left_padding? && flags.padding_char == '0'
+ @io.write_string(printf_slice[0...e_index])
+ trailing_zeros.times { @io << '0' } if flags.sharp
+ @io << '.' if flags.sharp && dot_index.nil?
+ @io.write_string(printf_slice[e_index..]) if e_index
+
+ pad(str_size, flags) if flags.right_padding?
end
# Formats floats with `%a` or `%A`
@@ -456,50 +503,78 @@ struct String::Formatter(A)
pad(str_size, flags) if flags.right_padding?
end
- {% end %}
+ {% else %}
+ # Delegate to `LibC.snprintf` for float formats if Ryu Printf is unavailable
+ private def float_fallback(float, flags)
+ format_buf = recreate_float_format_string(flags)
- # Delegate to `LibC.snprintf` for float formats not yet ported to Crystal
- private def float_fallback(float, flags)
- format_buf = recreate_float_format_string(flags)
+ len = LibC.snprintf(nil, 0, format_buf, float) + 1
+ temp_buf = temp_buf(len)
+ LibC.snprintf(temp_buf, len, format_buf, float)
- len = LibC.snprintf(nil, 0, format_buf, float) + 1
- temp_buf = temp_buf(len)
- LibC.snprintf(temp_buf, len, format_buf, float)
+ @io.write_string Slice.new(temp_buf, len - 1)
+ end
- @io.write_string Slice.new(temp_buf, len - 1)
- end
+ # Here we rebuild the original format string, like %f or %.2g and use snprintf
+ private def recreate_float_format_string(flags)
+ capacity = 3 # percent + type + \0
+ capacity += flags.width_size
+ capacity += flags.precision_size + 1 # size + .
+ capacity += 1 if flags.sharp
+ capacity += 1 if flags.plus
+ capacity += 1 if flags.minus
+ capacity += 1 if flags.zero
+ capacity += 1 if flags.space
+
+ format_buf = format_buf(capacity)
+ original_format_buf = format_buf
+
+ io = IO::Memory.new(Bytes.new(format_buf, capacity))
+ io << '%'
+ io << '#' if flags.sharp
+ io << '+' if flags.plus
+ io << '-' if flags.minus
+ io << '0' if flags.zero
+ io << ' ' if flags.space
+ io << flags.width if flags.width > 0
+ if precision = flags.precision
+ io << '.'
+ io << precision if precision != 0
+ end
+ io << flags.type
+ io.write_byte 0_u8
- # Here we rebuild the original format string, like %f or %.2g and use snprintf
- def recreate_float_format_string(flags)
- capacity = 3 # percent + type + \0
- capacity += flags.width_size
- capacity += flags.precision_size + 1 # size + .
- capacity += 1 if flags.sharp
- capacity += 1 if flags.plus
- capacity += 1 if flags.minus
- capacity += 1 if flags.zero
- capacity += 1 if flags.space
-
- format_buf = format_buf(capacity)
- original_format_buf = format_buf
-
- io = IO::Memory.new(Bytes.new(format_buf, capacity))
- io << '%'
- io << '#' if flags.sharp
- io << '+' if flags.plus
- io << '-' if flags.minus
- io << '0' if flags.zero
- io << ' ' if flags.space
- io << flags.width if flags.width > 0
- if precision = flags.precision
- io << '.'
- io << precision if precision != 0
+ original_format_buf
end
- io << flags.type
- io.write_byte 0_u8
- original_format_buf
- end
+ # We reuse a temporary buffer for snprintf
+ private def temp_buf(len)
+ temp_buf = @temp_buf
+ if temp_buf
+ if len > @temp_buf_len
+ @temp_buf_len = len
+ @temp_buf = temp_buf = temp_buf.realloc(len)
+ end
+ temp_buf
+ else
+ @temp_buf = Pointer(UInt8).malloc(len)
+ end
+ end
+
+ # We reuse a temporary buffer for the float format string
+ private def format_buf(len)
+ format_buf = @format_buf
+ if format_buf
+ if len > @format_buf_len
+ @format_buf_len = len
+ @format_buf = format_buf = format_buf.realloc(len)
+ end
+ format_buf
+ else
+ @format_buf = Pointer(UInt8).malloc(len)
+ end
+ end
+ {% end %} # HAS_RYU_PRINTF
def pad(consumed, flags) : Nil
padding_char = flags.padding_char
@@ -557,48 +632,23 @@ struct String::Formatter(A)
@reader.next_char
end
- # We reuse a temporary buffer for snprintf
- private def temp_buf(len)
- temp_buf = @temp_buf
- if temp_buf
- if len > @temp_buf_len
- @temp_buf_len = len
- @temp_buf = temp_buf = temp_buf.realloc(len)
- end
- temp_buf
- else
- @temp_buf = Pointer(UInt8).malloc(len)
- end
- end
-
- # We reuse a temporary buffer for the float format string
- private def format_buf(len)
- format_buf = @format_buf
- if format_buf
- if len > @format_buf_len
- @format_buf_len = len
- @format_buf = format_buf = format_buf.realloc(len)
- end
- format_buf
- else
- @format_buf = Pointer(UInt8).malloc(len)
- end
- end
-
struct Flags
property space : Bool, sharp : Bool, plus : Bool, minus : Bool, zero : Bool, float : Bool, base : Int32
- property width : Int32, width_size : Int32
- property type : Char, precision : Int32?, precision_size : Int32
+ property width : Int32
+ property type : Char, precision : Int32?
property index : Int32?
+ {% unless HAS_RYU_PRINTF %}
+ property width_size : Int32 = 0
+ property precision_size : Int32 = 0
+ {% end %}
+
def initialize
@space = @sharp = @plus = @minus = @zero = @float = false
@width = 0
- @width_size = 0
@base = 10
@type = ' '
@precision = nil
- @precision_size = 0
end
def left_padding? : Bool
diff --git a/src/string/utf16.cr b/src/string/utf16.cr
index b3fdc09301af..042391cca15d 100644
--- a/src/string/utf16.cr
+++ b/src/string/utf16.cr
@@ -128,8 +128,10 @@ class String
{string, pointer + 1}
end
+ # :nodoc:
+ #
# Yields each decoded char in the given slice.
- private def self.each_utf16_char(slice : Slice(UInt16), &)
+ def self.each_utf16_char(slice : Slice(UInt16), &)
i = 0
while i < slice.size
byte = slice[i].to_i
diff --git a/src/time/location.cr b/src/time/location.cr
index d84c1ab14218..7e0e8f160cb9 100644
--- a/src/time/location.cr
+++ b/src/time/location.cr
@@ -236,7 +236,7 @@ class Time::Location
#
# *name* is understood to be a location name in the IANA Time
# Zone database, such as `"America/New_York"`. As special cases,
- # `"UTC"` and empty string (`""`) return `Location::UTC`, and
+ # `"UTC"`, `"Etc/UTC"` and empty string (`""`) return `Location::UTC`, and
# `"Local"` returns `Location.local`.
#
# The implementation uses a list of system-specific paths to look for a time
@@ -277,7 +277,11 @@ class Time::Location
# `Location`, unless the time zone database has been updated in between.
def self.load(name : String) : Location
case name
- when "", "UTC"
+ when "", "UTC", "Etc/UTC"
+ # `UTC` is a special identifier, empty string represents a fallback mechanism.
+ # `Etc/UTC` is technically a tzdb identifier which could potentially point to anything.
+ # But we map it to `Location::UTC` directly for convenience which allows it to work
+ # without a copy of the database.
UTC
when "Local"
local
@@ -339,7 +343,7 @@ class Time::Location
# The environment variable `ENV["TZ"]` is consulted for finding the time zone
# to use.
#
- # * `"UTC"` and empty string (`""`) return `Location::UTC`
+ # * `"UTC"`, `"Etc/UTC"` and empty string (`""`) return `Location::UTC`
# * Any other value (such as `"Europe/Berlin"`) is tried to be resolved using
# `Location.load`.
# * If `ENV["TZ"]` is not set, the system's local time zone data will be used
@@ -348,7 +352,7 @@ class Time::Location
# `Location::UTC` is returned.
def self.load_local : Location
case tz = ENV["TZ"]?
- when "", "UTC"
+ when "", "UTC", "Etc/UTC"
return UTC
when Nil
if localtime = Crystal::System::Time.load_localtime
diff --git a/src/tuple.cr b/src/tuple.cr
index d67578271363..2f9cde352e4f 100644
--- a/src/tuple.cr
+++ b/src/tuple.cr
@@ -539,10 +539,28 @@ struct Tuple
to_s
end
- def to_a
+ # Returns an `Array` with all the elements in the tuple.
+ #
+ # ```
+ # {1, 2, 3, 4, 5}.to_a # => [1, 2, 3, 4, 5]
+ # ```
+ def to_a : Array(Union(*T))
+ {% if compare_versions(Crystal::VERSION, "1.1.0") < 0 %}
+ to_a(&.itself.as(Union(*T)))
+ {% else %}
+ to_a(&.itself)
+ {% end %}
+ end
+
+ # Returns an `Array` with the results of running *block* against each element of the tuple.
+ #
+ # ```
+ # {1, 2, 3, 4, 5}).to_a { |i| i * 2 } # => [2, 4, 6, 8, 10]
+ # ```
+ def to_a(& : Union(*T) -> _)
Array(Union(*T)).build(size) do |buffer|
{% for i in 0...T.size %}
- buffer[{{i}}] = self[{{i}}]
+ buffer[{{i}}] = yield self[{{i}}]
{% end %}
size
end
diff --git a/src/xml/libxml2.cr b/src/xml/libxml2.cr
index 68c9943425d2..feea8a1ba6d7 100644
--- a/src/xml/libxml2.cr
+++ b/src/xml/libxml2.cr
@@ -5,12 +5,16 @@ require "./html_parser_options"
require "./save_options"
@[Link("xml2", pkg_config: "libxml-2.0")]
+{% if compare_versions(Crystal::VERSION, "1.11.0-dev") >= 0 %}
+ @[Link(dll: "libxml2.dll")]
+{% end %}
lib LibXML
alias Int = LibC::Int
+ fun xmlInitParser
+
# TODO: check if other platforms also support per-thread globals
{% if flag?(:win32) %}
- fun xmlInitParser
fun __xmlIndentTreeOutput : Int*
fun __xmlTreeIndentString : UInt8**
{% else %}
@@ -321,9 +325,7 @@ lib LibXML
fun xmlValidateNameValue(value : UInt8*) : Int
end
-{% if flag?(:win32) %}
- LibXML.xmlInitParser
-{% end %}
+LibXML.xmlInitParser
LibXML.xmlGcMemSetup(
->GC.free,
diff --git a/src/xml/reader.cr b/src/xml/reader.cr
index 9d1de3ed4c9e..decdd8468185 100644
--- a/src/xml/reader.cr
+++ b/src/xml/reader.cr
@@ -119,6 +119,7 @@ class XML::Reader
# Moves to the `XML::Reader::Type::ATTRIBUTE` with the specified name.
def move_to_attribute(name : String) : Bool
+ check_no_null_byte(name)
LibXML.xmlTextReaderMoveToAttribute(@reader, name) == 1
end
@@ -131,6 +132,7 @@ class XML::Reader
# Gets the attribute content for the *attribute* given by name.
# Returns `nil` if attribute is not found.
def []?(attribute : String) : String?
+ check_no_null_byte(attribute)
value = LibXML.xmlTextReaderGetAttribute(@reader, attribute)
String.new(value) if value
end
@@ -200,4 +202,10 @@ class XML::Reader
Error.add_errors(@errors)
end
end
+
+ private def check_no_null_byte(attribute)
+ if attribute.byte_index(0)
+ raise XML::Error.new("Invalid attribute name: #{attribute.inspect} (contains null character)", 0)
+ end
+ end
end
diff --git a/src/yaml/lib_yaml.cr b/src/yaml/lib_yaml.cr
index 4c0d329f8f36..0b4248afc793 100644
--- a/src/yaml/lib_yaml.cr
+++ b/src/yaml/lib_yaml.cr
@@ -1,6 +1,9 @@
require "./enums"
@[Link("yaml", pkg_config: "yaml-0.1")]
+{% if compare_versions(Crystal::VERSION, "1.11.0-dev") >= 0 %}
+ @[Link(dll: "yaml.dll")]
+{% end %}
lib LibYAML
alias Int = LibC::Int