Comments (2)
Bustache wasn't designed to be a lint, so I didn't consider rich error info. Probably the best we can do is to add a format_error::position()
which returns the offset from the source, and let the users compute col/row and format the error msg themselves. I think the non-human-readable parts can be removed from format_error::what()
(I probably mimics the MSVC STL style).
from bustache.
The pull request implements format_error::position()
as you proposed.
Just in case anyone else needs this, I now use the following wrappers to augment formatting errors with line/column info by nesting exceptions:
// bustache-format.hpp
#ifndef INCLUDED_BUSTACHE_FORMAT_HPP_
#define INCLUDED_BUSTACHE_FORMAT_HPP_
#include <cstddef> // for size_t, ptrdiff_t
#include <utility> // for forward<>()
#include <stdexcept> // for runtime_error
#include <bustache/format.hpp>
enum class FormatTemplateType
{
string,
multilineString
};
class BustacheFormatError : public std::runtime_error
{
private:
bustache::format_error error_;
std::ptrdiff_t line_;
std::ptrdiff_t column_;
public:
BustacheFormatError(const bustache::format_error& _error);
BustacheFormatError(const bustache::format_error& _error, std::ptrdiff_t _line, std::ptrdiff_t _column);
std::ptrdiff_t line(void) const noexcept { return line_; }
std::ptrdiff_t column(void) const noexcept { return column_; }
};
namespace detail
{
[[noreturn]] void throwBustacheFormatErrorWithPosition(FormatTemplateType templateType, const char* data, const bustache::format_error& error);
} // namespace detail
inline bustache::format bustacheFormat(const char* first, const char* last, FormatTemplateType templateType)
{
try
{
return bustache::format(first, last);
}
catch (const bustache::format_error& error)
{
detail::throwBustacheFormatErrorWithPosition(templateType, first, error);
}
}
template <typename SourceT>
bustache::format bustacheFormat(SourceT&& source, FormatTemplateType templateType)
{
try
{
return bustache::format(std::forward<SourceT>(source));
}
catch (const bustache::format_error& error)
{
detail::throwBustacheFormatErrorWithPosition(templateType, source.data(), error);
}
}
template <std::size_t N>
bustache::format bustacheFormat(const char (&source)[N], FormatTemplateType templateType)
{
try
{
return bustache::format(source);
}
catch (const bustache::format_error& error)
{
detail::throwBustacheFormatErrorWithPosition(templateType, source, error);
}
}
#endif // INCLUDED_BUSTACHE_FORMAT_HPP_
// bustache-format.cpp
#include <string>
#include <sstream>
#include <utility> // for pair<>
#include <exception> // for throw_with_nested()
#include "bustache-format.hpp"
static std::string makePositionMessage(std::ptrdiff_t line, std::ptrdiff_t column)
{
// We use 1-based indices in human-readable error messages.
std::ostringstream sstr;
if (line >= 0 && column >= 0)
sstr << "in line " << (line + 1) << ", column " << (column + 1) << ":";
else if (column >= 0)
sstr << "at position " << (column + 1) << ":";
else
sstr << "at unknown position:";
return sstr.str();
}
BustacheFormatError::BustacheFormatError(const bustache::format_error& _error)
: std::runtime_error(makePositionMessage(-1, _error.position())), error_(_error), line_(-1), column_(_error.position())
{
}
BustacheFormatError::BustacheFormatError(const bustache::format_error& _error, std::ptrdiff_t _line, std::ptrdiff_t _column)
: std::runtime_error(makePositionMessage(_line, _column)), error_(_error), line_(_line), column_(_column)
{
}
namespace detail
{
template <typename I, typename D>
static std::pair<D, D> determineLineAndColumn(I data, D position)
{
if (position < 0)
return std::make_pair(-1, -1);
D line = 0;
I i0 = data;
for (I i = data, e = data + position; i < e; ++i)
{
if (*i == '\n')
{
++line;
i0 = i + 1;
}
}
D column = (data + position) - i0;
return std::make_pair(line, column);
}
void throwBustacheFormatErrorWithPosition(FormatTemplateType templateType, const char* data, const bustache::format_error& error)
{
if (error.position() < 0)
throw;
switch (templateType)
{
case FormatTemplateType::string:
std::throw_with_nested(BustacheFormatError(error));
case FormatTemplateType::multilineString:
{
auto [line, column] = determineLineAndColumn(data, error.position());
std::throw_with_nested(BustacheFormatError(error, line, column));
}
}
std::terminate();
}
} // namespace detail
from bustache.
Related Issues (20)
- Compilation error with C++17 variant conflict
- Insert a template into another template? HOT 2
- `boost::unordered_map<>` vs `std::unordered_map<>` HOT 1
- Improve CMake package integration HOT 1
- Bustache RVO HOT 1
- How to search Bustache Object for data? HOT 2
- Search Bustache Object for data - enhansement HOT 2
- thank you and may I have some more, please HOT 2
- Empty string on one case but not a similar other one HOT 1
- Is interface for Bustache C++20 incomplete? HOT 10
- Bustache compiles fine using nlohmann::json but not with nlohmann::ordered_json containers HOT 2
- Is it possible to execute a function when a specific replacement tag is rendered? HOT 1
- Bustache data adapter for Nlohmann Json? HOT 2
- Cannot compile with clang 14 HOT 3
- New kid on the block HOT 4
- Examples using headers from test HOT 1
- Compiling Error HOT 1
- Trouble getting Partials (embedded templates) working when using the Nlohmann Json adapter. HOT 5
- Will latest versions of Bustache compile on gcc 7.4? HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from bustache.