diff options
Diffstat (limited to '')
-rw-r--r-- | src/yajlpp/yajlpp.cc | 82 |
1 files changed, 67 insertions, 15 deletions
diff --git a/src/yajlpp/yajlpp.cc b/src/yajlpp/yajlpp.cc index b1362ab..0fc0001 100644 --- a/src/yajlpp/yajlpp.cc +++ b/src/yajlpp/yajlpp.cc @@ -34,8 +34,6 @@ #include "yajlpp.hh" -#include "base/fs_util.hh" -#include "base/snippet_highlighters.hh" #include "config.h" #include "fmt/format.h" #include "ghc/filesystem.hpp" @@ -213,10 +211,7 @@ json_path_handler_base::gen(yajlpp_gen_context& ygc, yajl_gen handle) const if (this->jph_children) { for (const auto& lpath : local_paths) { - std::string full_path = lpath; - if (this->jph_path_provider) { - full_path += "/"; - } + std::string full_path = json_ptr::encode_str(lpath); int start_depth = ygc.ygc_depth; yajl_gen_string(handle, lpath); @@ -455,8 +450,8 @@ json_path_handler_base::gen_schema_type(yajlpp_gen_context& ygc) const void json_path_handler_base::walk( - const std::function< - void(const json_path_handler_base&, const std::string&, void*)>& cb, + const std::function<void( + const json_path_handler_base&, const std::string&, const void*)>& cb, void* root, const std::string& base) const { @@ -465,11 +460,11 @@ json_path_handler_base::walk( if (this->jph_path_provider) { this->jph_path_provider(root, local_paths); - for (auto& lpath : local_paths) { + for (const auto& lpath : local_paths) { cb(*this, fmt::format(FMT_STRING("{}{}{}"), base, - lpath, + json_ptr::encode_str(lpath), this->jph_children ? "/" : ""), nullptr); } @@ -477,6 +472,12 @@ json_path_handler_base::walk( local_paths.clear(); this->jph_path_provider(root, local_paths); } + if (this->jph_field_getter) { + const auto* field = this->jph_field_getter(root, nonstd::nullopt); + if (field != nullptr) { + cb(*this, base, field); + } + } } else { local_paths.emplace_back(this->jph_property); @@ -484,6 +485,7 @@ json_path_handler_base::walk( if (this->jph_children) { full_path += "/"; } + cb(*this, full_path, nullptr); } @@ -493,7 +495,7 @@ json_path_handler_base::walk( static const intern_string_t POSS_SRC = intern_string::lookup("possibilities"); - std::string full_path = base + lpath; + std::string full_path = base + json_ptr::encode_str(lpath); if (this->jph_children) { full_path += "/"; } @@ -509,13 +511,18 @@ json_path_handler_base::walk( static thread_local auto md = lnav::pcre2pp::match_data::unitialized(); - std::string full_path = lpath + "/"; + const auto short_path = json_ptr::encode_str(lpath) + "/"; - if (!this->jph_regex->capture_from(full_path) + if (!this->jph_regex->capture_from(short_path) .into(md) .matches() .ignore_error()) { + log_error( + "path-handler regex (%s) does not match path: " + "%s", + this->jph_regex->get_pattern().c_str(), + full_path.c_str()); ensure(false); } child_root = this->jph_obj_provider( @@ -527,7 +534,7 @@ json_path_handler_base::walk( } } else { for (auto& lpath : local_paths) { - void* field = nullptr; + const void* field = nullptr; if (this->jph_field_getter) { field = this->jph_field_getter(root, lpath); @@ -1370,6 +1377,33 @@ json_path_handler_base::report_pattern_error(yajlpp_parse_context* ypc, .with_help(this->get_help_text(ypc))); } +void +json_path_handler_base::report_tz_error(yajlpp_parse_context* ypc, + const std::string& value_str, + const char* msg) const +{ + auto help_al = attr_line_t() + .append(lnav::roles::h2("Available time zones")) + .append("\n"); + + try { + for (const auto& tz : date::get_tzdb().zones) { + help_al.append(" ") + .append(lnav::roles::symbol(tz.name())) + .append("\n"); + } + } catch (const std::runtime_error& e) { + log_error("unable to load timezones: %s", e.what()); + } + + ypc->report_error(lnav::console::user_message::error( + attr_line_t().append_quoted(value_str).append( + " is not a valid timezone")) + .with_snippet(ypc->get_snippet()) + .with_reason(msg) + .with_help(help_al)); +} + attr_line_t json_path_handler_base::get_help_text(const std::string& full_path) const { @@ -1495,6 +1529,7 @@ json_path_container::gen_schema(yajlpp_gen_context& ygc) const void json_path_container::gen_properties(yajlpp_gen_context& ygc) const { + static const auto FWD_SLASH = lnav::pcre2pp::code::from_const(R"(\[\^/\])"); auto pattern_count = count_if( this->jpc_children.begin(), this->jpc_children.end(), [](auto& jph) { return jph.jph_is_pattern_property; @@ -1524,7 +1559,10 @@ json_path_container::gen_properties(yajlpp_gen_context& ygc) const if (!child_handler.jph_is_pattern_property) { continue; } - properties.gen(child_handler.jph_property); + + auto pattern = child_handler.jph_property; + pattern = FWD_SLASH.replace(pattern, "."); + properties.gen(fmt::format(FMT_STRING("^{}$"), pattern)); child_handler.gen_schema(ygc); } } @@ -1572,3 +1610,17 @@ yajlpp_gen::to_string_fragment() return string_fragment::from_bytes(buf, len); } + +namespace yajlpp { + +auto_mem<yajl_handle_t> +alloc_handle(const yajl_callbacks* cb, void* cu) +{ + auto_mem<yajl_handle_t> retval(yajl_free); + + retval = yajl_alloc(cb, nullptr, cu); + + return retval; +} + +} // namespace yajlpp
\ No newline at end of file |