diff options
-rw-r--r-- | cpp/011load.cc | 4 | ||||
-rw-r--r-- | cpp/tangle/030tangle.cc | 43 | ||||
-rw-r--r-- | cpp/tangle/030tangle.test.cc | 14 |
3 files changed, 45 insertions, 16 deletions
diff --git a/cpp/011load.cc b/cpp/011load.cc index df64cae7..35a9bf23 100644 --- a/cpp/011load.cc +++ b/cpp/011load.cc @@ -202,7 +202,9 @@ for (size_t i = 0; i < recently_added_recipes.size(); ++i) { recently_added_recipes.clear(); :(scenario parse_comment_outside_recipe) -# comment +# this comment will be dropped by the tangler, so we need a dummy recipe to stop that +recipe f1 [ ] +# this comment will go through to 'load' recipe main [ 1:integer <- copy 23:literal ] diff --git a/cpp/tangle/030tangle.cc b/cpp/tangle/030tangle.cc index fd01deba..5e25c742 100644 --- a/cpp/tangle/030tangle.cc +++ b/cpp/tangle/030tangle.cc @@ -100,6 +100,7 @@ void process_next_hunk(istream& in, const string& directive, const string& filen // first slurp all lines until next directive list<Line> hunk; + bool end_of_scenario_input = false; { string curr_line; while (!in.eof()) { @@ -114,15 +115,21 @@ void process_next_hunk(istream& in, const string& directive, const string& filen ++line_number; continue; } - if (cmd == "scenario" && starts_with(curr_line, "#")) { - // scenarios can contain mu comments - ++line_number; - continue; - } - if (cmd == "scenario" && trim(curr_line).empty()) { - // ignore empty lines in scenarios - ++line_number; - continue; + if (cmd == "scenario") { + // ignore mu comments in scenarios, but only after the end of input + if (!starts_with(curr_line, "#") && !is_input(curr_line)) { + // remaining lines are checks + end_of_scenario_input = true; + } + else if (end_of_scenario_input && starts_with(curr_line, "#")) { + ++line_number; + continue; + } + if (trim(curr_line).empty()) { + // ignore empty lines in scenarios, whether in input of after + ++line_number; + continue; + } } hunk.push_back(Line(curr_line, filename, line_number)); ++line_number; @@ -282,15 +289,23 @@ list<Line>::iterator balancing_curly(list<Line>::iterator curr) { } // A scenario is one or more sessions separated by calls to CLEAR_TRACE ('===') -// A session is one or more lines of input, followed optionally by (in order): -// one or more lines expected in trace in order ('+') -// one or more lines trace shouldn't include ('-') -// one or more lines expressing counts of specific layers emitted in trace ('$') -// a directive to print the trace just for debugging ('?') +// A session is: +// one or more lines of escaped setup in C/C++ ('%') +// followed by one or more lines of input, +// followed optionally by (in order): +// one or more lines expected in trace in order ('+') +// one or more lines trace shouldn't include ('-') +// one or more lines expressing counts of specific layers emitted in trace ('$') +// a directive to print the trace just for debugging ('?') // Remember to update is_input below if you add to this format. void emit_test(const string& name, list<Line>& lines, list<Line>& result) { result.push_back(Line("TEST("+name+")", front(lines).filename, front(lines).line_number-1)); // use line number of directive while (!lines.empty()) { + // hack: drop mu comments at the start, just in case there's a '%' line after them + // So the tangler only passes through mu comments inside scenarios between + // the first input line and the last input line. + while (!lines.empty() && starts_with(front(lines).contents, "#")) + lines.pop_front(); while (!lines.empty() && starts_with(front(lines).contents, "% ")) { result.push_back(Line(" "+front(lines).contents.substr(strlen("% ")), front(lines))); lines.pop_front(); diff --git a/cpp/tangle/030tangle.test.cc b/cpp/tangle/030tangle.test.cc index c811881d..0d4da899 100644 --- a/cpp/tangle/030tangle.test.cc +++ b/cpp/tangle/030tangle.test.cc @@ -307,7 +307,7 @@ void test_tangle_can_handle_mu_comments_in_scenario() { list<Line> lines; tangle(in, lines); CHECK_EQ(lines.front().contents, "TEST(does_bar)"); lines.pop_front(); - CHECK_EQ(lines.front().contents, " run(\"abc def\\n efg\\n\");"); lines.pop_front(); + CHECK_EQ(lines.front().contents, " run(\"abc def\\n# comment1\\n efg\\n # indented comment 2\\n\");"); lines.pop_front(); CHECK_EQ(lines.front().contents, " CHECK_TRACE_CONTENTS(\"layer1: pqrlayer1: xyz\");"); lines.pop_front(); CHECK_EQ(lines.front().contents, " CHECK_TRACE_DOESNT_CONTAIN(\"layer1: z\");"); lines.pop_front(); CHECK_EQ(lines.front().contents, " CHECK_EQ(trace_count(\"layer1\"), 2);"); lines.pop_front(); @@ -315,6 +315,18 @@ void test_tangle_can_handle_mu_comments_in_scenario() { CHECK(lines.empty()); } +void test_tangle_can_handle_escaped_setup_after_mu_comments() { + istringstream in(":(scenario does_bar)\n# comment\n% int x = 1;\nabc\n+layer1: pqr\n"); + list<Line> lines; + tangle(in, lines); + CHECK_EQ(lines.front().contents, "TEST(does_bar)"); lines.pop_front(); + CHECK_EQ(lines.front().contents, " int x = 1;"); lines.pop_front(); + CHECK_EQ(lines.front().contents, " run(\"abc\\n\");"); lines.pop_front(); + CHECK_EQ(lines.front().contents, " CHECK_TRACE_CONTENTS(\"layer1: pqr\");"); lines.pop_front(); + CHECK_EQ(lines.front().contents, "}"); lines.pop_front(); + CHECK(lines.empty()); +} + void test_trim() { |