@@ -139,13 +139,13 @@ class Reader : public Command {
139139 read_ = &Reader::readFloat;
140140 break ;
141141 case checktestdataParser::STRING:
142+ string_ = std::move (*value);
143+ read_ = &Reader::readString;
142144 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);
146147 read_ = &Reader::readRegex;
147148 break ;
148- }
149149 default :
150150 throw std::logic_error (" unimplemented read statement " +
151151 std::to_string (ctx->type ->getType ()));
@@ -158,8 +158,26 @@ class Reader : public Command {
158158 }
159159
160160 private:
161+ Expression string_;
162+ const void * last_string_value_ = nullptr ;
161163 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+
162175 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+ }
163181 const char * before = in.data ();
164182 if (!RE2::Consume (&in, *regex_)) {
165183 throw InputMismatch{absl::StrCat (" did not match regex " ,
@@ -210,10 +228,12 @@ class Reader : public Command {
210228 if (peek (in) == ' -' ) get (in);
211229 bool fail = true ;
212230 int decimals = 0 ;
231+ int digits = 0 ;
213232 bool scientific = false ;
214233 while (peek (in) >= ' 0' && peek (in) <= ' 9' ) {
215234 fail = false ;
216235 get (in);
236+ ++digits;
217237 }
218238 if (!fail && peek (in) == ' .' ) {
219239 get (in);
@@ -232,11 +252,17 @@ class Reader : public Command {
232252 get (in);
233253 }
234254 }
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+ }
240266 }
241267 if (scientific_ && *scientific_ != scientific) {
242268 throw std::logic_error{" wrong float format" };
@@ -538,11 +564,13 @@ int main(int argc, char** argv) {
538564 checktestdataLexer lexer (&input);
539565 CommonTokenStream tokens (&lexer);
540566 checktestdataParser parser (&tokens);
541- if (parser.getNumberOfSyntaxErrors ()) {
542- throw std::runtime_error{" failed to compile ctd" };
543- }
544567 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;
546574 std::vector<std::thread> threads;
547575 for (int i = 2 ; i == 2 || i < argc; ++i) {
548576 threads.emplace_back ([tree, i, argc, argv]() {
0 commit comments