From fe3d4ce758822d65a0a5d617b7b77df2dbc972d8 Mon Sep 17 00:00:00 2001 From: Ben Longbons Date: Sun, 16 Mar 2014 14:55:57 -0700 Subject: Implement new magic frontend using sexpr --- src/io/line.cpp | 43 +++++++++++++++++++++++++++++++++++++++++-- src/io/line.hpp | 21 ++++++++++++++++----- src/io/line_test.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 7 deletions(-) (limited to 'src/io') diff --git a/src/io/line.cpp b/src/io/line.cpp index fb73f45..8173398 100644 --- a/src/io/line.cpp +++ b/src/io/line.cpp @@ -32,7 +32,7 @@ namespace io { - AString Line::message_str(ZString cat, ZString msg) + AString Line::message_str(ZString cat, ZString msg) const { MString out; if (column) @@ -46,7 +46,7 @@ namespace io return AString(out); } - void Line::message(ZString cat, ZString msg) + void Line::message(ZString cat, ZString msg) const { if (column) FPRINTF(stderr, "%s:%u:%u: %s: %s\n", @@ -58,6 +58,45 @@ namespace io FPRINTF(stderr, "%*c\n", column, '^'); } + AString LineSpan::message_str(ZString cat, ZString msg) const + { + assert (begin.column); + assert (end.column); + assert (begin.column <= end.column); + + MString out; + if (begin.line == end.line) + { + out += STRPRINTF("%s:%u:%u: %s: %s\n", + begin.filename, begin.line, begin.column, cat, msg); + out += STRPRINTF("%s\n", begin.text); + out += STRPRINTF("%*c", begin.column, '^'); + for (unsigned c = begin.column; c != end.column; ++c) + out += '~'; + out += '\n'; + } + else + { + out += STRPRINTF("%s:%u:%u: %s: %s\n", + begin.filename, begin.line, begin.column, cat, msg); + out += STRPRINTF("%s\n", begin.text); + out += STRPRINTF("%*c", begin.column, '^'); + for (unsigned c = begin.column; c != begin.text.size(); ++c) + out += '~'; + out += " ...\n"; + out += STRPRINTF("%s\n", end.text); + for (unsigned c = 0; c != end.column; ++c) + out += '~'; + out += '\n'; + } + return AString(out); + } + + void LineSpan::message(ZString cat, ZString msg) const + { + FPRINTF(stderr, "%s", message_str(cat, msg)); + } + LineReader::LineReader(ZString name) : filename(name), line(0), column(0), rf(name) {} diff --git a/src/io/line.hpp b/src/io/line.hpp index 321cdf7..a9e8944 100644 --- a/src/io/line.hpp +++ b/src/io/line.hpp @@ -40,11 +40,11 @@ namespace io // 1-based uint16_t line, column; - AString message_str(ZString cat, ZString msg); - void message(ZString cat, ZString msg); - void note(ZString msg) { message("note", msg); } - void warning(ZString msg) { message("warning", msg); } - void error(ZString msg) { message("error", msg); } + AString message_str(ZString cat, ZString msg) const; + void message(ZString cat, ZString msg) const; + void note(ZString msg) const { message("note", msg); } + void warning(ZString msg) const { message("warning", msg); } + void error(ZString msg) const { message("error", msg); } }; // psst, don't tell anyone @@ -59,6 +59,17 @@ namespace io } }; + struct LineSpan + { + LineChar begin, end; + + AString message_str(ZString cat, ZString msg) const; + void message(ZString cat, ZString msg) const; + void note(ZString msg) const { message("note", msg); } + void warning(ZString msg) const { message("warning", msg); } + void error(ZString msg) const { message("error", msg); } + }; + class LineReader { protected: diff --git a/src/io/line_test.cpp b/src/io/line_test.cpp index ae316c6..6f0706f 100644 --- a/src/io/line_test.cpp +++ b/src/io/line_test.cpp @@ -348,3 +348,50 @@ TEST(io, linechar5) lr.adv(); EXPECT_FALSE(lr.get(c)); } + +TEST(io, linespan) +{ + io::LineCharReader lr("", string_pipe("Hello\nWorld\n")); + io::LineSpan span; + do + { + lr.get(span.begin); + lr.adv(); + } + while (span.begin.ch() != 'e'); + do + { + lr.get(span.end); + lr.adv(); + } + while (span.end.ch() != 'o'); + EXPECT_EQ(span.message_str("info", "meh"), + ":1:2: info: meh\n" + "Hello\n" + " ^~~~\n" + ); + do + { + lr.get(span.end); + lr.adv(); + } + while (span.end.ch() != 'r'); + + EXPECT_EQ(span.begin.message_str("note", "foo"), + ":1:2: note: foo\n" + "Hello\n" + " ^\n" + ); + EXPECT_EQ(span.end.message_str("warning", "bar"), + ":2:3: warning: bar\n" + "World\n" + " ^\n" + ); + EXPECT_EQ(span.message_str("error", "qux"), + ":1:2: error: qux\n" + "Hello\n" + " ^~~~ ...\n" + "World\n" + "~~~\n" + ); +} -- cgit v1.2.3-70-g09d2