|
4 | 4 | #include <libdbc/utils/utils.hpp> |
5 | 5 |
|
6 | 6 | #include <regex> |
| 7 | +#include <vector> |
7 | 8 |
|
8 | 9 | namespace libdbc { |
9 | 10 |
|
@@ -52,136 +53,13 @@ struct VALObject { |
52 | 53 | std::vector<Signal::SignalValueDescriptions> vd; |
53 | 54 | }; |
54 | 55 |
|
55 | | -static bool parse_value(const std::string& str, VALObject& obj); |
56 | | - |
57 | | -bool parse_value(const std::string& str, VALObject& obj) { |
58 | | - obj.signal_name = ""; |
59 | | - obj.vd.clear(); |
60 | | - auto state = Identifier; |
61 | | - const char* value_data = str.data(); |
62 | | - Signal::SignalValueDescriptions value_description; |
63 | | - for (;;) { |
64 | | - switch (state) { |
65 | | - case Identifier: { |
66 | | - if (*value_data != 'V') { |
67 | | - return false; |
68 | | - } |
69 | | - value_data++; |
70 | | - if (*value_data != 'A') { |
71 | | - return false; |
72 | | - } |
73 | | - value_data++; |
74 | | - if (*value_data != 'L') { |
75 | | - return false; |
76 | | - } |
77 | | - value_data++; |
78 | | - if (*value_data != '_') { |
79 | | - return false; |
80 | | - } |
81 | | - value_data++; |
82 | | - if (*value_data != ' ') { |
83 | | - return false; |
84 | | - } |
85 | | - value_data++; // skip whitespace |
86 | | - state = CANId; |
87 | | - break; |
88 | | - } |
89 | | - case CANId: { |
90 | | - std::string can_id_str; |
91 | | - while (*value_data >= '0' && *value_data <= '9') { |
92 | | - can_id_str += *value_data; |
93 | | - value_data++; |
94 | | - } |
95 | | - if (can_id_str.empty()) { |
96 | | - return false; |
97 | | - } |
98 | | - obj.can_id = static_cast<uint32_t>(std::stoul(can_id_str)); |
99 | | - if (*value_data != ' ') { |
100 | | - return false; |
101 | | - } |
102 | | - value_data++; // skip whitespace |
103 | | - state = SignalName; |
104 | | - break; |
105 | | - } |
106 | | - case SignalName: { |
107 | | - if ((*value_data >= 'a' && *value_data <= 'z') || (*value_data >= 'A' && *value_data <= 'Z') || *value_data == '_') { |
108 | | - obj.signal_name += *value_data; |
109 | | - } else { |
110 | | - return false; |
111 | | - } |
112 | | - value_data++; |
113 | | - while ((*value_data >= 'a' && *value_data <= 'z') || (*value_data >= 'A' && *value_data <= 'Z') || *value_data == '_' |
114 | | - || (*value_data >= '0' && *value_data <= '9')) { |
115 | | - obj.signal_name += *value_data; |
116 | | - value_data++; |
117 | | - } |
118 | | - if (*value_data != ' ') { |
119 | | - return false; |
120 | | - } |
121 | | - value_data++; // skip whitespace |
122 | | - state = Value; |
123 | | - break; |
124 | | - } |
125 | | - case Value: { |
126 | | - std::string value_str; |
127 | | - while (*value_data >= '0' && *value_data <= '9') { |
128 | | - value_str += *value_data; |
129 | | - value_data++; |
130 | | - } |
131 | | - if (*value_data == ';') { |
132 | | - if (value_str.empty()) { |
133 | | - return true; |
134 | | - } |
135 | | - return false; |
136 | | - } |
137 | | - if (value_str.empty()) { |
138 | | - return false; |
139 | | - } |
140 | | - |
141 | | - if (*value_data != ' ') { |
142 | | - return false; |
143 | | - } |
144 | | - value_data++; // skip whitespace |
145 | | - value_description.value = (uint32_t)std::stoul(value_str); |
146 | | - state = Description; |
147 | | - break; |
148 | | - } |
149 | | - case Description: { |
150 | | - std::string desc; |
151 | | - if (*value_data != '"') { |
152 | | - return false; |
153 | | - } |
154 | | - value_data++; |
155 | | - while (*value_data != '"' && *value_data != 0) { |
156 | | - desc += *value_data; |
157 | | - value_data++; |
158 | | - } |
159 | | - if (*value_data == 0) { |
160 | | - return false; |
161 | | - } |
162 | | - value_data++; |
163 | | - if (*value_data != ' ') { |
164 | | - return false; |
165 | | - } |
166 | | - value_data++; // skip whitespace |
167 | | - |
168 | | - value_description.description = desc; |
169 | | - obj.vd.push_back(value_description); |
170 | | - |
171 | | - state = Value; |
172 | | - break; |
173 | | - } |
174 | | - } |
175 | | - } |
176 | | - return false; |
177 | | -} |
178 | | - |
179 | 56 | DbcParser::DbcParser() |
180 | 57 | : version_re("^(VERSION)\\s\"(.*)\"") |
181 | 58 | , bit_timing_re("^(BS_:)") |
182 | 59 | , name_space_re("^(NS_)\\s\\:") |
183 | 60 | , node_re("^(BU_:)\\s((?:[\\w]+?\\s?)*)") |
184 | 61 | , message_re("^(BO_)\\s(\\d+)\\s(\\w+)\\:\\s(\\d+)\\s(\\w+|Vector__XXX)") |
| 62 | + , value_re("^(VAL_)\\s(\\d+)\\s(\\w+)((?:\\s(\\d+)\\s\"([^\"]*)\")+)\\s;$") |
185 | 63 | , |
186 | 64 | // NOTE: No multiplex support yet |
187 | 65 | signal_re(std::string("^") + whiteSpace + signalIdentifierPattern + whiteSpace + namePattern + whiteSpace + "\\:" + whiteSpace + bitStartPattern + "\\|" |
@@ -271,7 +149,6 @@ void DbcParser::parse_dbc_messages(const std::vector<std::string>& lines) { |
271 | 149 |
|
272 | 150 | std::vector<VALObject> signal_value; |
273 | 151 |
|
274 | | - VALObject obj{}; |
275 | 152 | for (const auto& line : lines) { |
276 | 153 | if (std::regex_search(line, match, message_re)) { |
277 | 154 | uint32_t message_id = static_cast<uint32_t>(std::stoul(match.str(MESSAGE_ID_GROUP))); |
@@ -308,7 +185,29 @@ void DbcParser::parse_dbc_messages(const std::vector<std::string>& lines) { |
308 | 185 | continue; |
309 | 186 | } |
310 | 187 |
|
311 | | - if (parse_value(line, obj)) { |
| 188 | + if (std::regex_search(line, match, value_re)) { |
| 189 | + uint32_t message_id = static_cast<uint32_t>(std::stoul(match.str(2))); |
| 190 | + std::string signal_name = match.str(3); |
| 191 | + |
| 192 | + // Loop over the rest of the descriptions |
| 193 | + std::string rest_of_descriptions = match.str(4); |
| 194 | + std::regex description_re("\\s(\\d+)\\s\"([^\"]*)\""); |
| 195 | + |
| 196 | + std::sregex_iterator desc_iter(rest_of_descriptions.begin(), rest_of_descriptions.end(), description_re); |
| 197 | + std::sregex_iterator desc_end; |
| 198 | + |
| 199 | + std::vector<Signal::SignalValueDescriptions> values{}; |
| 200 | + while (desc_iter != desc_end) { |
| 201 | + std::smatch desc_match = *desc_iter; |
| 202 | + uint32_t number = static_cast<uint32_t>(std::stoul(desc_match.str(1))); |
| 203 | + std::string text = desc_match.str(2); |
| 204 | + |
| 205 | + values.push_back(Signal::SignalValueDescriptions{number, text}); |
| 206 | + ++desc_iter; |
| 207 | + } |
| 208 | + |
| 209 | + VALObject obj{message_id, signal_name, values}; |
| 210 | + |
312 | 211 | signal_value.push_back(obj); |
313 | 212 | continue; |
314 | 213 | } |
|
0 commit comments