diff --git a/xo-facet/include/xo/facet/FacetRegistry.hpp b/xo-facet/include/xo/facet/FacetRegistry.hpp index 2a3aa48c..aa481a0c 100644 --- a/xo-facet/include/xo/facet/FacetRegistry.hpp +++ b/xo-facet/include/xo/facet/FacetRegistry.hpp @@ -115,7 +115,7 @@ namespace xo { * obj foo * = ...; // Foo instance with variant impl * obj bar - * = FacetRegistry::variant(foo); + * = FacetRegistry::instance().variant(foo); * * // exception thrown if bar has null data * @@ -140,7 +140,7 @@ namespace xo { * obj foo * = ...; // Foo instance with variant impl * obj bar - * = FacetRegistry::try_variant(foo); + * = FacetRegistry::instance().try_variant(foo); * if (bar) { * // success * } else { diff --git a/xo-indentlog/include/xo/indentlog/print/ppconfig.hpp b/xo-indentlog/include/xo/indentlog/print/ppconfig.hpp index 67d1831a..10c89639 100644 --- a/xo-indentlog/include/xo/indentlog/print/ppconfig.hpp +++ b/xo-indentlog/include/xo/indentlog/print/ppconfig.hpp @@ -16,6 +16,21 @@ namespace xo { * Need one read-only instance of this to invoke pretty printer **/ struct ppconfig { + /** @defgroup ppconfig-ctors ppconfig constructors **/ + ///@{ + + /** config to use pretty printer in degenerate form: + * In this form right margin is absurdly far away, + * so should not be forced to use multiple lines. + * + * Note this won't prevent a printer from returning -1 + **/ + static inline ppconfig ugly() { + return ppconfig { .right_margin_ = 99999999, .indent_width_ = 0, .assert_indent_threshold = 10 }; + } + + ///@} + /** @defgroup ppconfig-instance-vars ppconfig instance variables **/ ///@{ diff --git a/xo-object2/include/xo/object2/DString.hpp b/xo-object2/include/xo/object2/DString.hpp index f35fe44f..eea8ea5c 100644 --- a/xo-object2/include/xo/object2/DString.hpp +++ b/xo-object2/include/xo/object2/DString.hpp @@ -279,6 +279,15 @@ namespace xo { ///@} }; + inline std::ostream & operator<<(std::ostream & os, const DString * x) { + if (x) { + os << std::string_view(*x); + } else { + os << "nullptr"; + } + return os; + } + inline bool operator==(const DString & lhs, const DString & rhs) { return DString::compare(lhs, rhs) == 0; } diff --git a/xo-reader2/include/xo/reader2/ParserResult.hpp b/xo-reader2/include/xo/reader2/ParserResult.hpp index 39f9c2d1..45064d32 100644 --- a/xo-reader2/include/xo/reader2/ParserResult.hpp +++ b/xo-reader2/include/xo/reader2/ParserResult.hpp @@ -7,6 +7,7 @@ #include #include +#include #include namespace xo { @@ -21,7 +22,18 @@ namespace xo { N }; + /** @return string representation for enum @p x **/ + const char * parser_result_type_descr(parser_result_type x); + + inline std::ostream & operator<<(std::ostream & os, parser_result_type x) { + os << parser_result_type_descr(x); + return os; + } + class ParserResult { + public: + using ppindentinfo = xo::print::ppindentinfo; + public: ParserResult() = default; ParserResult(parser_result_type type, @@ -44,15 +56,53 @@ namespace xo { bool is_expression() const { return result_type_ == parser_result_type::expression; } bool is_error() const { return result_type_ == parser_result_type::error; } + /** ordinary not-pretty printer **/ + void print(std::ostream & os) const; + /** pretty-printing support **/ + bool pretty(const ppindentinfo & ppii) const; + private: + /** none|expression|error_description + * + * @text + * result_type | error_src_function | error_description + * -------------+--------------------+------------------- + * none | nullptr | empty + * expression | nullptr | empty + * error | non-null | non-empty + * @endtext + **/ parser_result_type result_type_ = parser_result_type::none; + /** non-null iff @ref result_type_ is expression **/ obj result_expr_; + /** non-null iff @ref result_type_ is error. + * In which case gives parsing function detecting this error + **/ std::string_view error_src_fn_; + /** non-null iff @ref result_type_ is error + * Human-targeted error description. + **/ const DString * error_description_ = nullptr; }; + inline std::ostream & operator<<(std::ostream & os, const ParserResult & x) { + x.print(os); + return os; + } } /*namespace scm*/ + + namespace print { + /** pretty printer in relies on this specialization + * to handle ParserResult instances + **/ + template <> + struct ppdetail { + static inline bool print_pretty(const ppindentinfo & ppii, const xo::scm::ParserResult & x) { + return x.pretty(ppii); + } + }; + } } /*namespace xo*/ /* end ParserResult.hpp */ diff --git a/xo-reader2/src/reader2/ParserResult.cpp b/xo-reader2/src/reader2/ParserResult.cpp index 28553228..312538b1 100644 --- a/xo-reader2/src/reader2/ParserResult.cpp +++ b/xo-reader2/src/reader2/ParserResult.cpp @@ -4,9 +4,28 @@ **/ #include "ParserResult.hpp" +#include +#include namespace xo { + using xo::print::APrintable; + using xo::facet::FacetRegistry; + namespace scm { + + const char * + parser_result_type_descr(parser_result_type x) + { + switch (x) { + case parser_result_type::none: return "none"; + case parser_result_type::expression: return "expression"; + case parser_result_type::error: return "error"; + case parser_result_type::N: break; + } + + return "parser_result_type?"; + } + ParserResult::ParserResult(parser_result_type type, obj expr, std::string_view error_src_fn, @@ -26,6 +45,53 @@ namespace xo { ssm_name, errmsg); } + + void + ParserResult::print(std::ostream & os) const + { + os << ""; + } + + bool + ParserResult::pretty(const ppindentinfo & ppii) const + { + switch (result_type_) { + case parser_result_type::none: + return ppii.pps()->pretty_struct + (ppii, + "ParserResult", + refrtag("type", result_type_)); + case parser_result_type::expression: + { + auto expr = FacetRegistry::instance().variant(result_expr_); + + return ppii.pps()->pretty_struct + (ppii, + "ParserResult", + refrtag("type", result_type_), + refrtag("expr", expr)); + } + break; + case parser_result_type::error: + return ppii.pps()->pretty_struct + (ppii, + "ParserResult", + refrtag("type", result_type_), + refrtag("src_fn", error_src_fn_), + refrtag("error", error_description_)); + case parser_result_type::N: + assert(false); + break; + } + + return false; + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 259336cf..e2a9023e 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -71,6 +71,9 @@ namespace xo { TEST_CASE("SchematikaParser-batch-def", "[reader2][SchematikaParser]") { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + ArenaConfig config; config.name_ = "test-arena"; config.size_ = 16 * 1024; @@ -96,11 +99,12 @@ namespace xo { REQUIRE(parser.has_incomplete_expr() == true); REQUIRE(result.is_incomplete()); + + log && log(xtag("result", result)); } // define-expressions not properly implemented - //REQUIRE(result.error_description()); }