summaryrefslogtreecommitdiffstats
path: root/src/yajlpp/yajlpp.cc
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/yajlpp/yajlpp.cc82
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