summaryrefslogtreecommitdiff
path: root/src/io
diff options
context:
space:
mode:
authorBen Longbons <b.r.longbons@gmail.com>2014-03-16 14:55:57 -0700
committerBen Longbons <b.r.longbons@gmail.com>2014-03-24 19:27:09 -0700
commitfe3d4ce758822d65a0a5d617b7b77df2dbc972d8 (patch)
treed048a7e356ba542ebc5647b1aedfce4b8257daa2 /src/io
parentc812c92d1a1835f0bda783e709481188c8d92225 (diff)
downloadtmwa-fe3d4ce758822d65a0a5d617b7b77df2dbc972d8.tar.gz
tmwa-fe3d4ce758822d65a0a5d617b7b77df2dbc972d8.tar.bz2
tmwa-fe3d4ce758822d65a0a5d617b7b77df2dbc972d8.tar.xz
tmwa-fe3d4ce758822d65a0a5d617b7b77df2dbc972d8.zip
Implement new magic frontend using sexpr
Diffstat (limited to 'src/io')
-rw-r--r--src/io/line.cpp43
-rw-r--r--src/io/line.hpp21
-rw-r--r--src/io/line_test.cpp47
3 files changed, 104 insertions, 7 deletions
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("<span>", 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"),
+ "<span>: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"),
+ "<span>:1:2: note: foo\n"
+ "Hello\n"
+ " ^\n"
+ );
+ EXPECT_EQ(span.end.message_str("warning", "bar"),
+ "<span>:2:3: warning: bar\n"
+ "World\n"
+ " ^\n"
+ );
+ EXPECT_EQ(span.message_str("error", "qux"),
+ "<span>:1:2: error: qux\n"
+ "Hello\n"
+ " ^~~~ ...\n"
+ "World\n"
+ "~~~\n"
+ );
+}