summaryrefslogtreecommitdiff
path: root/src/command_manager.cc
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2012-11-21 13:56:52 +0100
committerMaxime Coste <frrrwww@gmail.com>2012-11-21 13:56:52 +0100
commit9d04c773c19cabbec5205a737a212c0d6d6a04a3 (patch)
tree00c2edf6d10f2b48609e7069e800c83e0ed2b49a /src/command_manager.cc
parent6bbbd2543a035f3130dd73686f9f4357d900ad88 (diff)
CommandManager: diagnose unterminated strings
Diffstat (limited to 'src/command_manager.cc')
-rw-r--r--src/command_manager.cc22
1 files changed, 21 insertions, 1 deletions
diff --git a/src/command_manager.cc b/src/command_manager.cc
index 3998693d..8a30d9d2 100644
--- a/src/command_manager.cc
+++ b/src/command_manager.cc
@@ -31,6 +31,10 @@ void CommandManager::register_commands(const memoryview<String>& command_names,
register_command(command_name, command, completer);
}
+parse_error::parse_error(const String& error)
+ : runtime_error{"parse error: " + error} {}
+
+
namespace
{
@@ -73,8 +77,16 @@ bool is_horizontal_blank(char c)
return c == ' ' or c == '\t';
}
+struct unterminated_string : parse_error
+{
+ unterminated_string(const String& open, const String& close, int nest = 0)
+ : parse_error{"unterminated string '" + open + "..." + close + "'" +
+ (nest > 0 ? "(nesting: " + int_to_str(nest) + ")" : "")}
+ {}
+};
+
TokenList parse(const String& line,
- TokenPosList* opt_token_pos_info = NULL)
+ TokenPosList* opt_token_pos_info = nullptr)
{
TokenList result;
@@ -109,6 +121,8 @@ TokenList parse(const String& line,
while ((line[pos] != delimiter or line[pos-1] == '\\') and
pos != length)
++pos;
+ if (pos == length)
+ throw unterminated_string(String{delimiter}, String{delimiter});
}
else if (line[pos] == '%')
{
@@ -149,12 +163,18 @@ TokenList parse(const String& line,
}
++pos;
}
+ if (pos == length)
+ throw unterminated_string("%" + type_name + opening_delimiter,
+ String{closing_delimiter}, level);
}
else
{
while (pos != length and
(line[pos] != opening_delimiter or line[pos-1] == '\\'))
++pos;
+ if (pos == length)
+ throw unterminated_string("%" + type_name + opening_delimiter,
+ String{opening_delimiter});
}
}
else