schemagen: accept integral exponent/decimal numbers for integer slots
CI / build (-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++, clang-arm64, ubuntu-latest-arm64, true) (push) Successful in 56s
CI / pre-commit (push) Successful in 59s
CI / build (-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++, gcc-arm64, ubuntu-latest-arm64, false) (push) Successful in 52s
CI / build (-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++, clang-amd64, ubuntu-latest-amd64, true) (push) Successful in 1m45s
CI / build (-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++, gcc-amd64, ubuntu-latest-amd64, false) (push) Successful in 1m24s
CI / build (-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++, clang-arm64, ubuntu-latest-arm64, true) (push) Successful in 56s
CI / pre-commit (push) Successful in 59s
CI / build (-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++, gcc-arm64, ubuntu-latest-arm64, false) (push) Successful in 52s
CI / build (-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++, clang-amd64, ubuntu-latest-amd64, true) (push) Successful in 1m45s
CI / build (-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++, gcc-amd64, ubuntu-latest-amd64, false) (push) Successful in 1m24s
JSON Schema's 'integer' type matches any number with a zero fractional part, but the generated builder rejected forms like 1e3 or 2.0 because it only ran std::from_chars<int64_t>. Keep that exact path for plain integer literals (so large values near INT64_MAX stay exact), and fall back to parsing as double for the rest, requiring an integral value within int64 range. Add <cmath> for std::trunc and cover the new cases in test_gen.
This commit is contained in:
@@ -487,6 +487,7 @@ class Emitter:
|
||||
#pragma once
|
||||
|
||||
#include <charconv>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@@ -928,8 +929,21 @@ private:
|
||||
if (si.cat == Cat::Int) {{
|
||||
int64_t v = 0;
|
||||
auto r = std::from_chars(b, e, v);
|
||||
if (r.ec != std::errc() || r.ptr != e) {{ reject(); return; }}
|
||||
*(int64_t *)p = v;
|
||||
if (r.ec == std::errc() && r.ptr == e) {{
|
||||
*(int64_t *)p = v; // plain integer literal: parsed exactly
|
||||
}} else {{
|
||||
// JSON Schema "integer" accepts any number with no fractional part,
|
||||
// including exponent/decimal forms like 1e3 or 2.0. Parse those as a
|
||||
// double and require an integral value within int64 range.
|
||||
double d = 0;
|
||||
auto rd = std::from_chars(b, e, d);
|
||||
if (rd.ec != std::errc() || rd.ptr != e || d != std::trunc(d) ||
|
||||
d < -9223372036854775808.0 || d >= 9223372036854775808.0) {{
|
||||
reject();
|
||||
return;
|
||||
}}
|
||||
*(int64_t *)p = (int64_t)d;
|
||||
}}
|
||||
}} else {{
|
||||
double v = 0;
|
||||
auto r = std::from_chars(b, e, v);
|
||||
|
||||
Reference in New Issue
Block a user