@@ -139,13 +139,13 @@ class Reader : public Command {
139
139
read_ = &Reader::readFloat;
140
140
break ;
141
141
case checktestdataParser::STRING:
142
+ string_ = std::move (*value);
143
+ read_ = &Reader::readString;
142
144
break ;
143
- case checktestdataParser::REGEX: {
144
- const auto & str = std::get<Value::string>(value->eval ().value_ );
145
- regex_.emplace (str);
145
+ case checktestdataParser::REGEX:
146
+ string_ = std::move (*value);
146
147
read_ = &Reader::readRegex;
147
148
break ;
148
- }
149
149
default :
150
150
throw std::logic_error (" unimplemented read statement " +
151
151
std::to_string (ctx->type ->getType ()));
@@ -158,8 +158,26 @@ class Reader : public Command {
158
158
}
159
159
160
160
private:
161
+ Expression string_;
162
+ const void * last_string_value_ = nullptr ;
161
163
std::optional<RE2> regex_;
164
+
165
+ void readString (std::string_view& in) {
166
+ const auto & s = std::get<Value::string>(string_.eval ().value_ );
167
+ if (in.substr (0 , s.size ()) == s) {
168
+ in.remove_prefix (s.size ());
169
+ }
170
+ if (variable_) {
171
+ variable_->assign (Value{s});
172
+ }
173
+ }
174
+
162
175
void readRegex (std::string_view& in) {
176
+ const auto & s = std::get<Value::string>(string_.eval ().value_ );
177
+ if (&s != last_string_value_) {
178
+ last_string_value_ = &s;
179
+ regex_.emplace (s);
180
+ }
163
181
const char * before = in.data ();
164
182
if (!RE2::Consume (&in, *regex_)) {
165
183
throw InputMismatch{absl::StrCat (" did not match regex " ,
@@ -210,10 +228,12 @@ class Reader : public Command {
210
228
if (peek (in) == ' -' ) get (in);
211
229
bool fail = true ;
212
230
int decimals = 0 ;
231
+ int digits = 0 ;
213
232
bool scientific = false ;
214
233
while (peek (in) >= ' 0' && peek (in) <= ' 9' ) {
215
234
fail = false ;
216
235
get (in);
236
+ ++digits;
217
237
}
218
238
if (!fail && peek (in) == ' .' ) {
219
239
get (in);
@@ -232,11 +252,17 @@ class Reader : public Command {
232
252
get (in);
233
253
}
234
254
}
235
- if ((mindecimals_ &&
236
- std::get<int64_t >(mindecimals_->eval ().value_ ) > decimals) ||
237
- (maxdecimals_ &&
238
- std::get<int64_t >(maxdecimals_->eval ().value_ ) < decimals)) {
239
- throw std::logic_error{" wrong number of decimal places in input" };
255
+ if (mindecimals_) {
256
+ int64_t mindecimals = mindecimals_->eval ().toInt <uint32_t >();
257
+ int64_t maxdecimals = maxdecimals_->eval ().toInt <uint32_t >();
258
+ if (scientific && (digits != 1 || before[0 ] == ' 0' )) {
259
+ throw std::logic_error{
260
+ " In the FLOATP case a floating point number in scientific notation "
261
+ " must have exactly one nonzero digit before the decimal point." };
262
+ }
263
+ if (mindecimals > decimals || maxdecimals < decimals) {
264
+ throw std::logic_error{" wrong number of decimal places in input" };
265
+ }
240
266
}
241
267
if (scientific_ && *scientific_ != scientific) {
242
268
throw std::logic_error{" wrong float format" };
@@ -538,11 +564,13 @@ int main(int argc, char** argv) {
538
564
checktestdataLexer lexer (&input);
539
565
CommonTokenStream tokens (&lexer);
540
566
checktestdataParser parser (&tokens);
541
- if (parser.getNumberOfSyntaxErrors ()) {
542
- throw std::runtime_error{" failed to compile ctd" };
543
- }
544
567
tree::ParseTree* tree = parser.main ();
545
- // std::cout << tree->toStringTree(&parser) << std::endl;
568
+ if (!lexer.hitEOF || parser.getNumberOfSyntaxErrors ()) {
569
+ throw std::runtime_error{absl::StrCat (" failed to compile ctd " ,
570
+ lexer.hitEOF , " " ,
571
+ parser.getNumberOfSyntaxErrors ())};
572
+ }
573
+ // std::cerr << tree->toStringTree(&parser) << std::endl;
546
574
std::vector<std::thread> threads;
547
575
for (int i = 2 ; i == 2 || i < argc; ++i) {
548
576
threads.emplace_back ([tree, i, argc, argv]() {
0 commit comments