simlyfy
This commit is contained in:
1 parent
849ce31e2f
commit
a55d1c58ed
272 files changed
+41866
-261
No files matched your search
+20
-29
@@ -104,7 +104,8 @@ namespace {
|
||||
throw std::runtime_error("Unsupported attribute scope: " + text);
|
||||
}
|
||||
|
||||
std::int64_t Integer(const std::string &text) {
|
||||
template<class Numeric>
|
||||
Numeric ParseNumber(const std::string &text) {
|
||||
const char *begin = text.data();
|
||||
const char *end = begin + text.size();
|
||||
if (begin != end && *begin == '+') {
|
||||
@@ -112,22 +113,7 @@ namespace {
|
||||
if (begin != end && (*begin == '-' || *begin == '+'))
|
||||
throw std::runtime_error("Invalid attribute number: " + text);
|
||||
}
|
||||
std::int64_t value = 0;
|
||||
const std::from_chars_result parsed = std::from_chars(begin, end, value);
|
||||
if (begin == end || parsed.ec != std::errc() || parsed.ptr != end)
|
||||
throw std::runtime_error("Invalid attribute integer: " + text);
|
||||
return value;
|
||||
}
|
||||
|
||||
double Number(const std::string &text) {
|
||||
const char *begin = text.data();
|
||||
const char *end = begin + text.size();
|
||||
if (begin != end && *begin == '+') {
|
||||
++begin;
|
||||
if (begin != end && (*begin == '-' || *begin == '+'))
|
||||
throw std::runtime_error("Invalid attribute number: " + text);
|
||||
}
|
||||
double value = 0.0;
|
||||
Numeric value = 0;
|
||||
const std::from_chars_result parsed = std::from_chars(begin, end, value);
|
||||
if (begin == end || parsed.ec != std::errc() || parsed.ptr != end || !std::isfinite(value))
|
||||
throw std::runtime_error("Invalid attribute number: " + text);
|
||||
@@ -148,12 +134,12 @@ namespace {
|
||||
}
|
||||
if (token.quoted) throw std::runtime_error("Numeric attribute requires an unquoted number.");
|
||||
if (definition.type == AttributeType::Float) {
|
||||
const double value = Number(token.text);
|
||||
const double value = ParseNumber<double>(token.text);
|
||||
if (value < definition.minimum || value > definition.maximum)
|
||||
throw std::runtime_error("Attribute FLOAT value outside definition range.");
|
||||
return value;
|
||||
}
|
||||
const std::int64_t value = Integer(token.text);
|
||||
const std::int64_t value = ParseNumber<std::int64_t>(token.text);
|
||||
if (value < definition.integerMinimum || value > definition.integerMaximum)
|
||||
throw std::runtime_error("Attribute integer/ENUM value outside definition range.");
|
||||
return value;
|
||||
@@ -171,14 +157,14 @@ namespace {
|
||||
const std::string type = tokens.Word();
|
||||
if (type == "INT" || type == "HEX") {
|
||||
definition.type = type == "INT" ? AttributeType::Integer : AttributeType::Hex;
|
||||
definition.integerMinimum = Integer(tokens.Word());
|
||||
definition.integerMaximum = Integer(tokens.Word());
|
||||
definition.integerMinimum = ParseNumber<std::int64_t>(tokens.Word());
|
||||
definition.integerMaximum = ParseNumber<std::int64_t>(tokens.Word());
|
||||
if (definition.integerMinimum > definition.integerMaximum)
|
||||
throw std::runtime_error("Reversed attribute integer range.");
|
||||
} else if (type == "FLOAT") {
|
||||
definition.type = AttributeType::Float;
|
||||
definition.minimum = Number(tokens.Word());
|
||||
definition.maximum = Number(tokens.Word());
|
||||
definition.minimum = ParseNumber<double>(tokens.Word());
|
||||
definition.maximum = ParseNumber<double>(tokens.Word());
|
||||
if (definition.minimum > definition.maximum)
|
||||
throw std::runtime_error("Reversed attribute FLOAT range.");
|
||||
} else if (type == "STRING") {
|
||||
@@ -217,7 +203,7 @@ namespace {
|
||||
}
|
||||
|
||||
void ParseId(const std::string &text, AttributeAssignment &assignment) {
|
||||
const std::int64_t raw = Integer(text);
|
||||
const std::int64_t raw = ParseNumber<std::int64_t>(text);
|
||||
if (raw < 0 || raw > std::numeric_limits<std::uint32_t>::max() || (raw & 0x60000000U) != 0)
|
||||
throw std::runtime_error("Invalid attribute CAN ID.");
|
||||
const std::uint32_t id = static_cast<std::uint32_t>(raw);
|
||||
@@ -247,7 +233,12 @@ namespace {
|
||||
|
||||
void ApplyDefault(DbcDatabase &database, const std::string &name, const AttributeDefinition &definition) {
|
||||
if (!definition.defaultValue) return;
|
||||
if (definition.scope == AttributeScope::Database) database.attributes[name] = *definition.defaultValue;
|
||||
if (definition.scope == AttributeScope::Database) {
|
||||
database.attributes[name] = *definition.defaultValue;
|
||||
return;
|
||||
}
|
||||
if (definition.scope != AttributeScope::Frame && definition.scope != AttributeScope::Signal)
|
||||
return;
|
||||
for (FrameInfo &frame: database.frames) {
|
||||
if (definition.scope == AttributeScope::Frame) frame.attributes[name] = *definition.defaultValue;
|
||||
if (definition.scope == AttributeScope::Signal) {
|
||||
@@ -266,20 +257,20 @@ void DbcParseContext::ResolveAttributes(const std::string &filePath, std::vector
|
||||
std::vector<std::size_t> assignmentLines;
|
||||
// Resolve each phase independently of source ordering.
|
||||
const char *keywords[] = {"BA_DEF_", "BA_DEF_DEF_", "BA_"};
|
||||
for (int phase = 0; phase < 3; ++phase) {
|
||||
for (const char *phase: keywords) {
|
||||
for (const PendingAttribute &pending: pendingAttributes) {
|
||||
const std::string keyword = pending.statement.substr(0U, pending.statement.find_first_of(" \t"));
|
||||
if (keyword != keywords[phase]) continue;
|
||||
if (keyword != phase) continue;
|
||||
try {
|
||||
AttributeTokens tokens(pending.statement);
|
||||
tokens.Word();
|
||||
if (phase == 0) {
|
||||
if (keyword == "BA_DEF_") {
|
||||
Define(tokens, database);
|
||||
continue;
|
||||
}
|
||||
const std::string name = tokens.Quoted();
|
||||
AttributeDefinition &definition = FindDefinition(database, name);
|
||||
if (phase == 1) {
|
||||
if (keyword == "BA_DEF_DEF_") {
|
||||
if (definition.defaultValue) throw std::runtime_error("Duplicate attribute default: " + name);
|
||||
definition.defaultValue = Value(tokens.Take(), definition, true);
|
||||
ValidateCycleTime(name, *definition.defaultValue);
|
||||
|
||||
Reference in new issue
Block a user