Merge pull request #388 from YosysHQ/mwk/json-fixes

json: fix handling of 32-bit parameters
This commit is contained in:
David Shah 2020-02-01 16:26:58 +00:00 committed by GitHub
commit a0091eb44b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 14 additions and 16 deletions

View File

@ -24,7 +24,8 @@
#include <cmath> #include <cmath>
#include <cstdlib> #include <cstdlib>
#include <cstdio> #include <cstdio>
#include <limits> #include <climits>
#include <cerrno>
namespace json11 { namespace json11 {
@ -589,9 +590,11 @@ struct JsonParser final {
return fail("invalid " + esc(str[i]) + " in number"); return fail("invalid " + esc(str[i]) + " in number");
} }
if (str[i] != '.' && str[i] != 'e' && str[i] != 'E' if (str[i] != '.' && str[i] != 'e' && str[i] != 'E') {
&& (i - start_pos) <= static_cast<size_t>(std::numeric_limits<int>::digits10)) { errno = 0;
return std::atoi(str.c_str() + start_pos); long val = std::strtol(str.c_str() + start_pos, nullptr, 0);
if (!errno && val >= INT_MIN && val <= INT_MAX)
return int(val);
} }
// Decimal part // Decimal part

View File

@ -105,10 +105,14 @@ struct JsonFrontendImpl
Property parse_property(const Json &val) const 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); return Property(val.int_value(), 32);
else } else {
return Property::from_string(val.string_value()); return Property::from_string(val.string_value());
}
} }
template <typename TFunc> void foreach_attr(const Json &obj, TFunc Func) const template <typename TFunc> void foreach_attr(const Json &obj, TFunc Func) const

View File

@ -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)); } 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> &parameters, void write_parameters(std::ostream &f, Context *ctx, const std::unordered_map<IdString, Property> &parameters,
bool for_module = false) bool for_module = false)
{ {
@ -61,7 +52,7 @@ void write_parameters(std::ostream &f, Context *ctx, const std::unordered_map<Id
for (auto &param : parameters) { for (auto &param : parameters) {
f << stringf("%s\n", first ? "" : ","); f << stringf("%s\n", first ? "" : ",");
f << stringf(" %s%s: ", for_module ? "" : " ", get_name(param.first, ctx).c_str()); 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; first = false;
} }
} }