diff options
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/tangle/030tangle.cc | 17 | ||||
-rw-r--r-- | cpp/tangle/030tangle.test.cc | 25 |
2 files changed, 42 insertions, 0 deletions
diff --git a/cpp/tangle/030tangle.cc b/cpp/tangle/030tangle.cc index 088ba7e8..59533ce8 100644 --- a/cpp/tangle/030tangle.cc +++ b/cpp/tangle/030tangle.cc @@ -1,9 +1,13 @@ #include<sys/param.h> +size_t Line_number = 0; +string Filename; + int tangle(int argc, const char* argv[]) { list<string> result; for (int i = 1; i < argc; ++i) { ifstream in(argv[i]); + Filename = argv[i]; tangle(in, result); } for (list<string>::iterator p = result.begin(); p != result.end(); ++p) @@ -12,9 +16,11 @@ int tangle(int argc, const char* argv[]) { } void tangle(istream& in, list<string>& out) { + Line_number = 1; string curr_line; while (!in.eof()) { getline(in, curr_line); + Line_number++; if (starts_with(curr_line, ":(")) process_next_hunk(in, trim(curr_line), out); else @@ -27,6 +33,14 @@ string Toplevel = "run"; void process_next_hunk(istream& in, const string& directive, list<string>& out) { list<string> hunk; + { + ostringstream line_directive; + if (Filename.empty()) + line_directive << "#line " << Line_number; + else + line_directive << "#line " << Line_number << " \"" << Filename << '"'; + hunk.push_back(line_directive.str()); + } string curr_line; while (!in.eof()) { std::streampos old = in.tellg(); @@ -36,6 +50,7 @@ void process_next_hunk(istream& in, const string& directive, list<string>& out) break; } else { + ++Line_number; hunk.push_back(curr_line); } } @@ -56,6 +71,8 @@ void process_next_hunk(istream& in, const string& directive, list<string>& out) if (cmd == "scenario") { list<string> result; string name = next_tangle_token(directive_stream); + result.push_back(hunk.front()); // line number directive + hunk.pop_front(); emit_test(name, hunk, result); out.insert(out.end(), result.begin(), result.end()); return; diff --git a/cpp/tangle/030tangle.test.cc b/cpp/tangle/030tangle.test.cc index 18fe62ad..4bc9fd6f 100644 --- a/cpp/tangle/030tangle.test.cc +++ b/cpp/tangle/030tangle.test.cc @@ -5,6 +5,22 @@ void test_tangle() { CHECK_TRACE_CONTENTS("tangle", "adbc"); } +void test_tangle_with_linenumber() { + istringstream in("a\nb\nc\n:(before b)\nd\n"); + list<string> dummy; + tangle(in, dummy); + CHECK_TRACE_CONTENTS("tangle", "a#line 5dbc"); +} + +void test_tangle_with_filename() { + istringstream in("a\nb\nc\n:(before b)\nd\n"); + list<string> dummy; + Filename = "foo"; + tangle(in, dummy); + Filename = ""; + CHECK_TRACE_CONTENTS("tangle", "a#line 5 \"foo\"dbc"); +} + void test_tangle2() { istringstream in("a\nb\nc\n:(after b)\nd\n"); list<string> dummy; @@ -98,6 +114,7 @@ void test_tangle_supports_scenarios() { istringstream in(":(scenario does_bar)\nabc def\n+layer1: pqr\n+layer2: xyz"); list<string> lines; tangle(in, lines); + CHECK_EQ(lines.front(), "#line 2"); lines.pop_front(); CHECK_EQ(lines.front(), "TEST(does_bar)"); lines.pop_front(); CHECK_EQ(lines.front(), " run(\"abc def\\n\");"); lines.pop_front(); CHECK_EQ(lines.front(), " CHECK_TRACE_CONTENTS(\"layer1: pqrlayer2: xyz\");"); lines.pop_front(); @@ -109,6 +126,7 @@ void test_tangle_supports_configurable_toplevel() { istringstream in(":(scenarios foo)\n:(scenario does_bar)\nabc def\n+layer1: pqr"); list<string> lines; tangle(in, lines); + CHECK_EQ(lines.front(), "#line 3"); lines.pop_front(); CHECK_EQ(lines.front(), "TEST(does_bar)"); lines.pop_front(); CHECK_EQ(lines.front(), " foo(\"abc def\\n\");"); lines.pop_front(); CHECK_EQ(lines.front(), " CHECK_TRACE_CONTENTS(\"layer1: pqr\");"); lines.pop_front(); @@ -123,6 +141,7 @@ void test_tangle_can_hide_warnings_in_scenarios() { istringstream in(":(scenario does_bar)\nhide warnings\nabc def\n+layer1: pqr\n+layer2: xyz"); list<string> lines; tangle(in, lines); + CHECK_EQ(lines.front(), "#line 2"); lines.pop_front(); CHECK_EQ(lines.front(), "TEST(does_bar)"); lines.pop_front(); CHECK_EQ(lines.front(), " Hide_warnings = true;"); lines.pop_front(); CHECK_EQ(lines.front(), " run(\"abc def\\n\");"); lines.pop_front(); @@ -135,6 +154,7 @@ void test_tangle_supports_strings_in_scenarios() { istringstream in(":(scenario does_bar)\nabc \"def\"\n+layer1: pqr\n+layer2: \"xyz\""); list<string> lines; tangle(in, lines); + CHECK_EQ(lines.front(), "#line 2"); lines.pop_front(); CHECK_EQ(lines.front(), "TEST(does_bar)"); lines.pop_front(); CHECK_EQ(lines.front(), " run(\"abc \\\"def\\\"\\n\");"); lines.pop_front(); CHECK_EQ(lines.front(), " CHECK_TRACE_CONTENTS(\"layer1: pqrlayer2: \\\"xyz\\\"\");"); lines.pop_front(); @@ -146,6 +166,7 @@ void test_tangle_supports_strings_in_scenarios2() { istringstream in(":(scenario does_bar)\nabc \"\"\n+layer1: pqr\n+layer2: \"\""); list<string> lines; tangle(in, lines); + CHECK_EQ(lines.front(), "#line 2"); lines.pop_front(); CHECK_EQ(lines.front(), "TEST(does_bar)"); lines.pop_front(); CHECK_EQ(lines.front(), " run(\"abc \\\"\\\"\\n\");"); lines.pop_front(); CHECK_EQ(lines.front(), " CHECK_TRACE_CONTENTS(\"layer1: pqrlayer2: \\\"\\\"\");"); lines.pop_front(); @@ -157,6 +178,7 @@ void test_tangle_supports_multiline_input_in_scenarios() { istringstream in(":(scenario does_bar)\nabc def\n efg\n+layer1: pqr\n+layer2: \"\""); list<string> lines; tangle(in, lines); + CHECK_EQ(lines.front(), "#line 2"); lines.pop_front(); CHECK_EQ(lines.front(), "TEST(does_bar)"); lines.pop_front(); CHECK_EQ(lines.front(), " run(\"abc def\\n efg\\n\");"); lines.pop_front(); CHECK_EQ(lines.front(), " CHECK_TRACE_CONTENTS(\"layer1: pqrlayer2: \\\"\\\"\");"); lines.pop_front(); @@ -168,6 +190,7 @@ void test_tangle_supports_reset_in_scenarios() { istringstream in(":(scenario does_bar)\nabc def\n===\nefg\n+layer1: pqr\n+layer2: \"\""); list<string> lines; tangle(in, lines); + CHECK_EQ(lines.front(), "#line 2"); lines.pop_front(); CHECK_EQ(lines.front(), "TEST(does_bar)"); lines.pop_front(); CHECK_EQ(lines.front(), " run(\"abc def\\n\");"); lines.pop_front(); CHECK_EQ(lines.front(), " CLEAR_TRACE;"); lines.pop_front(); @@ -181,6 +204,7 @@ void test_tangle_can_check_for_absence_at_end_of_scenarios() { istringstream in(":(scenario does_bar)\nabc def\n efg\n+layer1: pqr\n-layer1: xyz"); list<string> lines; tangle(in, lines); + CHECK_EQ(lines.front(), "#line 2"); lines.pop_front(); CHECK_EQ(lines.front(), "TEST(does_bar)"); lines.pop_front(); CHECK_EQ(lines.front(), " run(\"abc def\\n efg\\n\");"); lines.pop_front(); CHECK_EQ(lines.front(), " CHECK_TRACE_CONTENTS(\"layer1: pqr\");"); lines.pop_front(); @@ -193,6 +217,7 @@ void test_tangle_can_check_for_absence_at_end_of_scenarios2() { istringstream in(":(scenario does_bar)\nabc def\n efg\n-layer1: pqr\n-layer1: xyz"); list<string> lines; tangle(in, lines); + CHECK_EQ(lines.front(), "#line 2"); lines.pop_front(); CHECK_EQ(lines.front(), "TEST(does_bar)"); lines.pop_front(); CHECK_EQ(lines.front(), " run(\"abc def\\n efg\\n\");"); lines.pop_front(); CHECK_EQ(lines.front(), " CHECK_TRACE_DOESNT_CONTAIN(\"layer1: pqr\");"); lines.pop_front(); |