Skip to content

Commit

Permalink
format_error now tracks line/column position
Browse files Browse the repository at this point in the history
  • Loading branch information
mbeutel committed Jun 2, 2019
1 parent b917d54 commit 50d0904
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 15 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Expand Up @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.2 FATAL_ERROR)
#set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} )
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules/")

project(bustache VERSION 1.0.0 LANGUAGES CXX)
project(bustache VERSION 1.1.0 LANGUAGES CXX)

option(BUSTACHE_ENABLE_TESTING "Enable testing of the bustache library." OFF)
option(EXPORT_BUILD_DIR "Export build directory using CMake (enables external use without install)" OFF)
Expand Down
20 changes: 19 additions & 1 deletion include/bustache/format.hpp
Expand Up @@ -9,6 +9,7 @@

#include <bustache/ast.hpp>
#include <stdexcept>
#include <cstddef>
#include <memory>

namespace bustache
Expand Down Expand Up @@ -61,19 +62,36 @@ namespace bustache
error_badkey
};

const char* error_type_to_message(error_type err);

class format_error : public std::runtime_error
{
error_type _err;
std::ptrdiff_t _line;
std::ptrdiff_t _column;

public:
explicit format_error(error_type err);
explicit format_error(error_type err, std::ptrdiff_t line_, std::ptrdiff_t column_);

error_type code() const noexcept
{
return _err;
}

// 0-based line index where error occurred; -1 if not known
std::ptrdiff_t line() const noexcept
{
return _line;
}

// 0-based column index where error occurred; -1 if not known
std::ptrdiff_t column() const noexcept
{
return _column;
}
};

struct format
{
format() = default;
Expand Down
68 changes: 55 additions & 13 deletions src/format.cpp
Expand Up @@ -66,14 +66,14 @@ namespace bustache { namespace parser { namespace
{
attr.assign(i0, i1);
if (i0 == i1)
throw format_error(error_badkey);
throw error_badkey;
return;
}
}
if (i != e)
++i;
}
throw format_error(error_badkey);
throw error_badkey;
}

template<class I>
Expand Down Expand Up @@ -150,7 +150,7 @@ namespace bustache { namespace parser { namespace
while (!parse_lit(i, e, d.close))
{
if (i == e)
throw format_error(error_delim);
throw error_delim;
++i;
}
}
Expand All @@ -167,15 +167,15 @@ namespace bustache { namespace parser { namespace
++i;
}
if (i == e)
throw format_error(error_baddelim);
throw error_baddelim;
d.open.assign(i0, i);
skip(i, e);
i0 = i;
I i1 = i;
for (;; ++i)
{
if (i == e)
throw format_error(error_set_delim);
throw error_set_delim;
if (*i == '=')
{
i1 = i;
Expand All @@ -186,16 +186,16 @@ namespace bustache { namespace parser { namespace
i1 = i;
skip(++i, e);
if (i == e || *i != '=')
throw format_error(error_set_delim);
throw error_set_delim;
break;
}
}
if (i0 == i1)
throw format_error(error_baddelim);
throw error_baddelim;
std::string new_close(i0, i1);
skip(++i, e);
if (!parse_lit(i, e, d.close))
throw format_error(error_delim);
throw error_delim;
d.close = std::move(new_close);
}

Expand All @@ -215,7 +215,7 @@ namespace bustache { namespace parser { namespace
{
skip(i, e);
if (i == e)
throw format_error(error_badkey);
throw error_badkey;
tag_result ret{};
switch (*i)
{
Expand All @@ -231,10 +231,10 @@ namespace bustache { namespace parser { namespace
case '/':
skip(++i, e);
if (section.empty() || !parse_lit(i, e, section))
throw format_error(error_section);
throw error_section;
skip(i, e);
if (!parse_lit(i, e, d.close))
throw format_error(error_delim);
throw error_delim;
ret.check_standalone = pure;
ret.is_end_section = true;
break;
Expand Down Expand Up @@ -387,12 +387,51 @@ namespace bustache { namespace parser { namespace
{
delim d{"{{", "}}"};
bool pure = true;
parse_contents(i, i, e, d, pure, attr, {});
I start = i;
try
{
parse_contents(i, i, e, d, pure, attr, {});
}
catch (error_type err)
{
// Count lines and columns until current position.
std::ptrdiff_t line = 0;
I curLineStart = start;
for (I pos = start; pos < i; ++pos)
{
if (*pos == '\n')
{
++line;
curLineStart = pos + 1;
}
}
std::ptrdiff_t column = i - curLineStart;
throw format_error(err, line, column);
}
}
}}}

namespace bustache
{
const char* error_type_to_message(error_type err)
{
switch (err)
{
case error_set_delim:
return "mismatched '='";
case error_baddelim:
return "invalid delimiter";
case error_delim:
return "mismatched delimiter";
case error_section:
return "mismatched end section tag";
case error_badkey:
return "invalid key";
default:
return "??";
}
}

static char const* get_error_string(error_type err) noexcept
{
switch (err)
Expand All @@ -413,7 +452,10 @@ namespace bustache
}

format_error::format_error(error_type err)
: runtime_error(get_error_string(err)), _err(err)
: runtime_error(get_error_string(err)), _err(err), _line(-1), _column(-1)
{}
format_error::format_error(error_type err, std::ptrdiff_t line_, std::ptrdiff_t column_)
: runtime_error(get_error_string(err)), _err(err), _line(line_), _column(column_)
{}

void format::init(char const* begin, char const* end)
Expand Down

0 comments on commit 50d0904

Please sign in to comment.