json: fix handling of 32-bit parameters
See YosysHQ/yosys#1671 for rationale. Also, added some validation to our parser, so that out-of-range values are reported and the user knows they should update yosys.
This commit is contained in:
parent
85f4452b0a
commit
24e3f8417e
11
3rdparty/json11/json11.cpp
vendored
11
3rdparty/json11/json11.cpp
vendored
@ -24,7 +24,8 @@
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <limits>
|
||||
#include <climits>
|
||||
#include <cerrno>
|
||||
|
||||
namespace json11 {
|
||||
|
||||
@ -589,9 +590,11 @@ struct JsonParser final {
|
||||
return fail("invalid " + esc(str[i]) + " in number");
|
||||
}
|
||||
|
||||
if (str[i] != '.' && str[i] != 'e' && str[i] != 'E'
|
||||
&& (i - start_pos) <= static_cast<size_t>(std::numeric_limits<int>::digits10)) {
|
||||
return std::atoi(str.c_str() + start_pos);
|
||||
if (str[i] != '.' && str[i] != 'e' && str[i] != 'E') {
|
||||
errno = 0;
|
||||
long val = std::strtol(str.c_str() + start_pos, nullptr, 0);
|
||||
if (!errno && val >= INT_MIN && val <= INT_MAX)
|
||||
return int(val);
|
||||
}
|
||||
|
||||
// Decimal part
|
||||
|
@ -105,11 +105,15 @@ struct JsonFrontendImpl
|
||||
|
||||
Property parse_property(const Json &val) const
|
||||
{
|
||||
if (val.is_number())
|
||||
if (val.is_number()) {
|
||||
if (val.int_value() != val.number_value())
|
||||
log_error("Found an out-of-range integer parameter in the JSON file.\n"
|
||||
"Please regenerate the input file with an up-to-date version of yosys.\n");
|
||||
return Property(val.int_value(), 32);
|
||||
else
|
||||
} else {
|
||||
return Property::from_string(val.string_value());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TFunc> void foreach_attr(const Json &obj, TFunc Func) const
|
||||
{
|
||||
|
@ -45,15 +45,6 @@ std::string get_string(std::string str)
|
||||
|
||||
std::string get_name(IdString name, Context *ctx) { return get_string(name.c_str(ctx)); }
|
||||
|
||||
void write_parameter_value(std::ostream &f, const Property &value)
|
||||
{
|
||||
if (value.size() == 32 && value.is_fully_def()) {
|
||||
f << stringf("%d", value.as_int64());
|
||||
} else {
|
||||
f << get_string(value.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
void write_parameters(std::ostream &f, Context *ctx, const std::unordered_map<IdString, Property> ¶meters,
|
||||
bool for_module = false)
|
||||
{
|
||||
@ -61,7 +52,7 @@ void write_parameters(std::ostream &f, Context *ctx, const std::unordered_map<Id
|
||||
for (auto ¶m : parameters) {
|
||||
f << stringf("%s\n", first ? "" : ",");
|
||||
f << stringf(" %s%s: ", for_module ? "" : " ", get_name(param.first, ctx).c_str());
|
||||
write_parameter_value(f, param.second);
|
||||
f << get_string(param.second.to_string());
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user