mirror of
https://github.com/tstack/lnav
synced 2024-11-03 23:15:38 +00:00
parent
d12769cd70
commit
71aa54ad4d
@ -162,15 +162,21 @@ string execute_sql(exec_context &ec, const string &sql, string &alt_msg)
|
||||
SQLITE_TRANSIENT);
|
||||
}
|
||||
else if (name[0] == '$') {
|
||||
map<string, string> &vars = ec.ec_local_vars.top();
|
||||
map<string, string>::iterator local_var;
|
||||
map<string, string> &lvars = ec.ec_local_vars.top();
|
||||
map<string, string> &gvars = ec.ec_global_vars;
|
||||
map<string, string>::iterator local_var, global_var;
|
||||
const char *env_value;
|
||||
|
||||
if ((local_var = vars.find(&name[1])) != vars.end()) {
|
||||
if ((local_var = lvars.find(&name[1])) != lvars.end()) {
|
||||
sqlite3_bind_text(stmt.in(), lpc + 1,
|
||||
local_var->second.c_str(), -1,
|
||||
SQLITE_TRANSIENT);
|
||||
}
|
||||
else if ((global_var = gvars.find(&name[1])) != gvars.end()) {
|
||||
sqlite3_bind_text(stmt.in(), lpc + 1,
|
||||
global_var->second.c_str(), -1,
|
||||
SQLITE_TRANSIENT);
|
||||
}
|
||||
else if ((env_value = getenv(&name[1])) != NULL) {
|
||||
sqlite3_bind_text(stmt.in(), lpc + 1, env_value, -1, SQLITE_STATIC);
|
||||
}
|
||||
|
@ -58,6 +58,7 @@ struct exec_context {
|
||||
std::map<std::string, std::string> ec_override;
|
||||
std::vector<logline_value> *ec_line_values;
|
||||
std::stack<std::map<std::string, std::string> > ec_local_vars;
|
||||
std::map<std::string, std::string> ec_global_vars;
|
||||
std::stack<std::string> ec_path_stack;
|
||||
|
||||
std::string ec_accumulator;
|
||||
|
@ -299,24 +299,6 @@ void handle_paging_key(int ch)
|
||||
lnav_data.ld_rl_view->set_value("Cleared bookmarks");
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
moveto_cluster(&bookmark_vector<vis_line_t>::next,
|
||||
&logfile_sub_source::BM_ERRORS,
|
||||
tc->get_top());
|
||||
lnav_data.ld_rl_view->set_alt_value(HELP_MSG_2(
|
||||
w, W,
|
||||
"to move forward/backward through warning messages"));
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
moveto_cluster(&bookmark_vector<vis_line_t>::prev,
|
||||
&logfile_sub_source::BM_ERRORS,
|
||||
tc->get_top());
|
||||
lnav_data.ld_rl_view->set_alt_value(HELP_MSG_2(
|
||||
w, W,
|
||||
"to move forward/backward through warning messages"));
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
moveto_cluster(&bookmark_vector<vis_line_t>::next,
|
||||
&logfile_sub_source::BM_WARNINGS,
|
||||
@ -335,24 +317,6 @@ void handle_paging_key(int ch)
|
||||
"to move to next/previous hour boundary"));
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
moveto_cluster(&bookmark_vector<vis_line_t>::next,
|
||||
&textview_curses::BM_SEARCH,
|
||||
search_forward_from(tc));
|
||||
lnav_data.ld_bottom_source.grep_error("");
|
||||
lnav_data.ld_rl_view->set_alt_value(
|
||||
"Press '" ANSI_BOLD(">") "' or '" ANSI_BOLD("<")
|
||||
"' to scroll horizontally to a search result");
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
previous_cluster(&textview_curses::BM_SEARCH, tc);
|
||||
lnav_data.ld_bottom_source.grep_error("");
|
||||
lnav_data.ld_rl_view->set_alt_value(
|
||||
"Press '" ANSI_BOLD(">") "' or '" ANSI_BOLD("<")
|
||||
"' to scroll horizontally to a search result");
|
||||
break;
|
||||
|
||||
case 'y':
|
||||
tc->set_top(bm[&BM_QUERY].next(tc->get_top()));
|
||||
break;
|
||||
@ -502,17 +466,6 @@ void handle_paging_key(int ch)
|
||||
break;
|
||||
}
|
||||
|
||||
case 'm':
|
||||
lnav_data.ld_last_user_mark[tc] = tc->get_top();
|
||||
tc->toggle_user_mark(&textview_curses::BM_USER,
|
||||
vis_line_t(lnav_data.ld_last_user_mark[tc]));
|
||||
tc->reload_data();
|
||||
|
||||
lnav_data.ld_rl_view->set_alt_value(HELP_MSG_2(
|
||||
u, U,
|
||||
"to move forward/backward through user bookmarks"));
|
||||
break;
|
||||
|
||||
case 'J':
|
||||
if (lnav_data.ld_last_user_mark.find(tc) ==
|
||||
lnav_data.ld_last_user_mark.end() ||
|
||||
|
@ -1,8 +1,36 @@
|
||||
{
|
||||
"global": {
|
||||
"keymap_def_alt_warning": "Press ${ansi_bold}w${ansi_norm}/${ansi_bold}W${ansi_norm} to move forward/backward through ${ansi_yellow}warning${ansi_norm} messages",
|
||||
"keymap_def_scroll_horiz": "Press \\'${ansi_bold}>${ansi_norm}\\' or \\'${ansi_bold}<${ansi_norm}\\' to scroll horizontally to a search result",
|
||||
"keymap_def_next_user_mark": "Press ${ansi_bold}u${ansi_norm}/${ansi_bold}U${ansi_norm} to move forward/backward through user bookmarks"
|
||||
},
|
||||
"keymap_def": {
|
||||
"default": {
|
||||
"x67": ":goto 0",
|
||||
"x50": ":switch-to-view pretty"
|
||||
"x45": [
|
||||
":prev-mark error",
|
||||
":eval :alt-msg ${keymap_def_alt_warning}"
|
||||
],
|
||||
"x65": [
|
||||
":next-mark error",
|
||||
":eval :alt-msg ${keymap_def_alt_warning}"
|
||||
],
|
||||
|
||||
"x67": [":goto 0"],
|
||||
"x6d": [
|
||||
":mark",
|
||||
":eval :alt-msg ${keymap_def_next_user_mark}"
|
||||
],
|
||||
|
||||
"x4e": [
|
||||
":prev-mark search",
|
||||
":eval :alt-msg ${keymap_def_scroll_horiz}"
|
||||
],
|
||||
"x6e": [
|
||||
":next-mark search",
|
||||
":eval :alt-msg ${keymap_def_scroll_horiz}"
|
||||
],
|
||||
|
||||
"x50": [":switch-to-view pretty"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
31
src/lnav.cc
31
src/lnav.cc
@ -134,6 +134,7 @@
|
||||
#include "field_overlay_source.hh"
|
||||
#include "url_loader.hh"
|
||||
#include "log_search_table.hh"
|
||||
#include "shlex.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -241,6 +242,22 @@ public:
|
||||
};
|
||||
};
|
||||
|
||||
static void add_global_vars(exec_context &ec)
|
||||
{
|
||||
for (const auto &iter : lnav_config.lc_global_vars) {
|
||||
shlex subber(iter.second);
|
||||
string str;
|
||||
|
||||
if (!subber.eval(str, ec.ec_global_vars)) {
|
||||
log_error("Unable to evaluate global variable value: %s",
|
||||
iter.second.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
ec.ec_global_vars[iter.first] = str;
|
||||
}
|
||||
}
|
||||
|
||||
bool setup_logline_table()
|
||||
{
|
||||
// Hidden columns don't show up in the table_info pragma.
|
||||
@ -791,7 +808,8 @@ static void open_pretty_view(void)
|
||||
|
||||
format->annotate(sbr, sa, values);
|
||||
exec_context ec(&values, pretty_sql_callback, pretty_pipe_callback);
|
||||
add_ansi_vars(ec.ec_local_vars.top());
|
||||
add_ansi_vars(ec.ec_global_vars);
|
||||
add_global_vars(ec);
|
||||
format->rewrite(ec, sbr, sa, rewritten_line);
|
||||
|
||||
data_scanner ds(rewritten_line);
|
||||
@ -1699,9 +1717,11 @@ static void handle_key(int ch) {
|
||||
|
||||
const auto &iter = km.km_seq_to_cmd.find(keyseq);
|
||||
if (iter != km.km_seq_to_cmd.end()) {
|
||||
log_debug("executing key sequence x%02x: %s",
|
||||
keyseq, iter->second.c_str());
|
||||
execute_any(lnav_data.ld_exec_context, iter->second);
|
||||
for (string cmd : iter->second) {
|
||||
log_debug("executing key sequence x%02x: %s",
|
||||
keyseq, cmd.c_str());
|
||||
execute_any(lnav_data.ld_exec_context, cmd);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -2524,7 +2544,7 @@ int main(int argc, char *argv[])
|
||||
lnav_data.ld_exec_context.ec_pipe_callback = pipe_callback;
|
||||
|
||||
lnav_data.ld_program_name = argv[0];
|
||||
add_ansi_vars(ec.ec_local_vars.top());
|
||||
add_ansi_vars(ec.ec_global_vars);
|
||||
|
||||
rl_readline_name = "lnav";
|
||||
|
||||
@ -2666,6 +2686,7 @@ int main(int argc, char *argv[])
|
||||
print_errors(config_errors);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
add_global_vars(ec);
|
||||
|
||||
string formats_path = dotlnav_path("formats/");
|
||||
|
||||
|
@ -348,6 +348,23 @@ static string com_relative_goto(exec_context &ec, string cmdline, vector<string>
|
||||
return retval;
|
||||
}
|
||||
|
||||
static string com_mark(exec_context &ec, string cmdline, vector<string> &args)
|
||||
{
|
||||
string retval = "";
|
||||
|
||||
if (args.empty()) {
|
||||
|
||||
} else {
|
||||
textview_curses *tc = lnav_data.ld_view_stack.top();
|
||||
lnav_data.ld_last_user_mark[tc] = tc->get_top();
|
||||
tc->toggle_user_mark(&textview_curses::BM_USER,
|
||||
vis_line_t(lnav_data.ld_last_user_mark[tc]));
|
||||
tc->reload_data();
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static string com_goto_mark(exec_context &ec, string cmdline, vector<string> &args)
|
||||
{
|
||||
string retval = "";
|
||||
@ -368,11 +385,14 @@ static string com_goto_mark(exec_context &ec, string cmdline, vector<string> &ar
|
||||
retval = "error: unknown bookmark type";
|
||||
}
|
||||
else {
|
||||
moveto_cluster(args[0] == "next-mark" ?
|
||||
&bookmark_vector<vis_line_t>::next :
|
||||
&bookmark_vector<vis_line_t>::prev,
|
||||
bt,
|
||||
tc->get_top());
|
||||
if (args[0] == "next-mark") {
|
||||
moveto_cluster(&bookmark_vector<vis_line_t>::next,
|
||||
bt,
|
||||
search_forward_from(tc));
|
||||
} else {
|
||||
previous_cluster(bt, tc);
|
||||
}
|
||||
lnav_data.ld_bottom_source.grep_error("");
|
||||
}
|
||||
}
|
||||
|
||||
@ -466,8 +486,12 @@ static string com_save_to(exec_context &ec, string cmdline, vector<string> &args
|
||||
|
||||
vector<string> split_args;
|
||||
shlex lexer(fn);
|
||||
scoped_resolver scopes = {
|
||||
&ec.ec_local_vars.top(),
|
||||
&ec.ec_global_vars,
|
||||
};
|
||||
|
||||
if (!lexer.split(split_args, ec.ec_local_vars.top())) {
|
||||
if (!lexer.split(split_args, scopes)) {
|
||||
return "error: unable to parse arguments";
|
||||
}
|
||||
if (split_args.size() > 1) {
|
||||
@ -1313,8 +1337,12 @@ static string com_open(exec_context &ec, string cmdline, vector<string> &args)
|
||||
|
||||
vector<string> split_args;
|
||||
shlex lexer(pat);
|
||||
scoped_resolver scopes = {
|
||||
&ec.ec_local_vars.top(),
|
||||
&ec.ec_global_vars,
|
||||
};
|
||||
|
||||
if (!lexer.split(split_args, ec.ec_local_vars.top())) {
|
||||
if (!lexer.split(split_args, scopes)) {
|
||||
return "error: unable to parse arguments";
|
||||
}
|
||||
|
||||
@ -2279,6 +2307,31 @@ static string com_echo(exec_context &ec, string cmdline, vector<string> &args)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static string com_alt_msg(exec_context &ec, string cmdline, vector<string> &args)
|
||||
{
|
||||
string retval = "error: expecting a message";
|
||||
|
||||
if (args.empty()) {
|
||||
|
||||
}
|
||||
else if (args.size() == 1) {
|
||||
if (lnav_data.ld_rl_view != NULL) {
|
||||
lnav_data.ld_rl_view->set_alt_value("");
|
||||
}
|
||||
}
|
||||
else {
|
||||
string msg = remaining_args(cmdline, args);
|
||||
|
||||
if (lnav_data.ld_rl_view != NULL) {
|
||||
lnav_data.ld_rl_view->set_alt_value(msg);
|
||||
}
|
||||
|
||||
retval = "";
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static string com_eval(exec_context &ec, string cmdline, vector<string> &args)
|
||||
{
|
||||
string retval = "error: expecting a command or query to evaluate";
|
||||
@ -2292,7 +2345,10 @@ static string com_eval(exec_context &ec, string cmdline, vector<string> &args)
|
||||
shlex lexer(all_args.c_str(), all_args.size());
|
||||
|
||||
log_debug("Evaluating: %s", all_args.c_str());
|
||||
if (!lexer.eval(expanded_cmd, ec.ec_local_vars.top())) {
|
||||
if (!lexer.eval(expanded_cmd, {
|
||||
&ec.ec_local_vars.top(),
|
||||
&ec.ec_global_vars,
|
||||
})) {
|
||||
return "error: invalid arguments";
|
||||
}
|
||||
log_debug("Expanded command to evaluate: %s", expanded_cmd.c_str());
|
||||
@ -2821,6 +2877,12 @@ readline_context::command_t STD_COMMANDS[] = {
|
||||
"Move the current view up or down by the given amount",
|
||||
com_relative_goto,
|
||||
},
|
||||
{
|
||||
"mark",
|
||||
NULL,
|
||||
"Toggle the bookmark state for the top line in the current view",
|
||||
com_mark,
|
||||
},
|
||||
{
|
||||
"next-mark",
|
||||
"error|warning|search|user|file|partition",
|
||||
@ -3095,6 +3157,12 @@ readline_context::command_t STD_COMMANDS[] = {
|
||||
"Echo the given message",
|
||||
com_echo,
|
||||
},
|
||||
{
|
||||
"alt-msg",
|
||||
"<msg>",
|
||||
"Display a message in the alternate command position",
|
||||
com_alt_msg,
|
||||
},
|
||||
{
|
||||
"eval",
|
||||
"<msg>",
|
||||
|
@ -238,7 +238,7 @@ struct userdata {
|
||||
};
|
||||
|
||||
static struct json_path_handler keymap_def_handlers[] = {
|
||||
json_path_handler("(?<key_seq>(x[0-9a-f]{2})+)")
|
||||
json_path_handler("(?<key_seq>(x[0-9a-f]{2})+)#")
|
||||
.with_synopsis("<command>")
|
||||
.with_description("The command to execute for the given key sequence")
|
||||
.with_pattern("[:|;].*")
|
||||
@ -270,10 +270,25 @@ static struct json_path_handler keymap_defs_handlers[] = {
|
||||
json_path_handler()
|
||||
};
|
||||
|
||||
static struct json_path_handler global_var_handlers[] = {
|
||||
json_path_handler("(?<var_name>\\w+)")
|
||||
.with_synopsis("<name>")
|
||||
.with_description("A global variable definition")
|
||||
.with_path_provider<_lnav_config>([](struct _lnav_config *cfg, vector<string> &paths_out) {
|
||||
for (const auto &iter : cfg->lc_global_vars) {
|
||||
paths_out.push_back(iter.first);
|
||||
}
|
||||
})
|
||||
.for_field(&nullobj<_lnav_config>()->lc_global_vars),
|
||||
};
|
||||
|
||||
static struct json_path_handler root_config_handlers[] = {
|
||||
json_path_handler("/keymap_def/")
|
||||
.with_children(keymap_defs_handlers),
|
||||
|
||||
json_path_handler("/global/")
|
||||
.with_children(global_var_handlers),
|
||||
|
||||
json_path_handler()
|
||||
};
|
||||
|
||||
|
@ -90,7 +90,7 @@ void install_git_format(const char *repo);
|
||||
void install_extra_formats();
|
||||
|
||||
struct key_map {
|
||||
std::map<std::string, std::string> km_seq_to_cmd;
|
||||
std::map<std::string, std::vector<std::string>> km_seq_to_cmd;
|
||||
};
|
||||
|
||||
struct _lnav_config {
|
||||
@ -99,6 +99,7 @@ struct _lnav_config {
|
||||
std::string lc_ui_keymap;
|
||||
std::unordered_map<std::string, key_map> lc_ui_keymaps;
|
||||
std::map<std::string, std::string> lc_ui_key_overrides;
|
||||
std::map<std::string, std::string> lc_global_vars;
|
||||
};
|
||||
|
||||
extern struct _lnav_config lnav_config;
|
||||
|
35
src/shlex.hh
35
src/shlex.hh
@ -33,6 +33,8 @@
|
||||
#define LNAV_SHLEX_HH_H
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "pcrepp.hh"
|
||||
|
||||
@ -49,6 +51,33 @@ enum shlex_token_t {
|
||||
ST_TILDE,
|
||||
};
|
||||
|
||||
class scoped_resolver {
|
||||
public:
|
||||
scoped_resolver(std::initializer_list<std::map<std::string, std::string> *> l) {
|
||||
this->sr_stack.insert(this->sr_stack.end(), l.begin(), l.end());
|
||||
};
|
||||
|
||||
typedef std::map<std::string, std::string>::const_iterator const_iterator;
|
||||
|
||||
const_iterator find(const std::string &str) const {
|
||||
const_iterator retval;
|
||||
|
||||
for (auto scope : this->sr_stack) {
|
||||
if ((retval = scope->find(str)) != scope->end()) {
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
return this->end();
|
||||
};
|
||||
|
||||
const_iterator end() const {
|
||||
return this->sr_stack.back()->end();
|
||||
}
|
||||
|
||||
std::vector<const std::map<std::string, std::string> *> sr_stack;
|
||||
};
|
||||
|
||||
class shlex {
|
||||
public:
|
||||
shlex(const char *str, size_t len)
|
||||
@ -165,7 +194,8 @@ public:
|
||||
return false;
|
||||
};
|
||||
|
||||
bool eval(std::string &result, const std::map<std::string, std::string> &vars) {
|
||||
template <typename Resolver = scoped_resolver>
|
||||
bool eval(std::string &result, const Resolver &vars) {
|
||||
result.clear();
|
||||
|
||||
pcre_context::capture_t cap;
|
||||
@ -220,7 +250,8 @@ public:
|
||||
return true;
|
||||
};
|
||||
|
||||
bool split(std::vector<std::string> &result, const std::map<std::string, std::string> &vars) {
|
||||
template <typename Resolver>
|
||||
bool split(std::vector<std::string> &result, const Resolver &vars) {
|
||||
result.clear();
|
||||
|
||||
pcre_context::capture_t cap;
|
||||
|
@ -85,10 +85,19 @@ int yajlpp_static_string(yajlpp_parse_context *ypc, const unsigned char *str, si
|
||||
|
||||
int yajlpp_static_string_vector(yajlpp_parse_context *ypc, const unsigned char *str, size_t len)
|
||||
{
|
||||
vector<string> &field_ptr = resolve_root<vector<string>>(ypc);
|
||||
const json_path_handler_base *jph = ypc->ypc_current_handler;
|
||||
|
||||
field_ptr.push_back(string((const char *) str, len));
|
||||
yajlpp_validator_for_string(*ypc, *ypc->ypc_current_handler);
|
||||
if (jph->jph_kv_pair) {
|
||||
map<string, vector<string>> &field_ptr = resolve_root<map<string, vector<string>>>(ypc);
|
||||
|
||||
field_ptr[ypc->get_path_fragment(-2)].push_back(string((const char *) str, len));
|
||||
} else {
|
||||
vector<string> &field_ptr = resolve_root<vector<string>>(ypc);
|
||||
|
||||
field_ptr.push_back(string((const char *) str, len));
|
||||
}
|
||||
|
||||
yajlpp_validator_for_string_vector(*ypc, *ypc->ypc_current_handler);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -180,6 +189,43 @@ yajl_gen_status yajlpp_static_gen_string(yajlpp_gen_context &ygc,
|
||||
}
|
||||
}
|
||||
|
||||
yajl_gen_status yajlpp_static_gen_string_vector(yajlpp_gen_context &ygc,
|
||||
const json_path_handler_base &jph,
|
||||
yajl_gen handle)
|
||||
{
|
||||
if (jph.jph_kv_pair) {
|
||||
map<string, vector<string>> *default_field_ptr = resolve_root<map<string, vector<string>>>(
|
||||
ygc.ygc_default_stack, jph);
|
||||
map<string, vector<string>> *field_ptr = resolve_root<map<string, vector<string>>>(
|
||||
ygc.ygc_obj_stack, jph);
|
||||
const string &base_name = ygc.ygc_base_name;
|
||||
|
||||
if (default_field_ptr != NULL &&
|
||||
((*default_field_ptr)[base_name] == (*field_ptr)[base_name])) {
|
||||
return yajl_gen_status_ok;
|
||||
}
|
||||
|
||||
if (ygc.ygc_depth) {
|
||||
yajl_gen_string(handle, base_name);
|
||||
}
|
||||
|
||||
{
|
||||
yajlpp_array arr(handle);
|
||||
|
||||
for (string str : (*field_ptr)[base_name]) {
|
||||
yajl_gen_string(handle, str);
|
||||
}
|
||||
}
|
||||
|
||||
return yajl_gen_status_ok;
|
||||
}
|
||||
else {
|
||||
ensure(0);
|
||||
|
||||
return yajl_gen_status_ok;
|
||||
}
|
||||
}
|
||||
|
||||
void yajlpp_validator_for_string(yajlpp_parse_context &ypc,
|
||||
const json_path_handler_base &jph)
|
||||
{
|
||||
@ -197,6 +243,25 @@ void yajlpp_validator_for_string(yajlpp_parse_context &ypc,
|
||||
}
|
||||
}
|
||||
|
||||
void yajlpp_validator_for_string_vector(yajlpp_parse_context &ypc,
|
||||
const json_path_handler_base &jph)
|
||||
{
|
||||
if (jph.jph_kv_pair) {
|
||||
return; // XXX
|
||||
}
|
||||
|
||||
vector<string> &field_ptr = resolve_root<vector<string>>(&ypc);
|
||||
|
||||
for (string str : field_ptr) {
|
||||
if (str.empty() && jph.jph_min_length > 0) {
|
||||
ypc.report_error("value must not be empty");
|
||||
} else if (str.size() < jph.jph_min_length) {
|
||||
ypc.report_error("value must be at least %lu characters long",
|
||||
jph.jph_min_length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void yajlpp_validator_for_intern_string(yajlpp_parse_context &ypc,
|
||||
const json_path_handler_base &jph)
|
||||
{
|
||||
|
@ -158,8 +158,13 @@ int yajlpp_static_enum(yajlpp_parse_context *, const unsigned char *, size_t);
|
||||
yajl_gen_status yajlpp_static_gen_string(yajlpp_gen_context &ygc,
|
||||
const json_path_handler_base &,
|
||||
yajl_gen);
|
||||
yajl_gen_status yajlpp_static_gen_string_vector(yajlpp_gen_context &ygc,
|
||||
const json_path_handler_base &,
|
||||
yajl_gen);
|
||||
void yajlpp_validator_for_string(yajlpp_parse_context &ypc,
|
||||
const json_path_handler_base &jph);
|
||||
void yajlpp_validator_for_string_vector(yajlpp_parse_context &ypc,
|
||||
const json_path_handler_base &jph);
|
||||
void yajlpp_validator_for_intern_string(yajlpp_parse_context &ypc,
|
||||
const json_path_handler_base &jph);
|
||||
void yajlpp_validator_for_int(yajlpp_parse_context &ypc,
|
||||
@ -318,6 +323,15 @@ struct json_path_handler : public json_path_handler_base {
|
||||
return *this;
|
||||
};
|
||||
|
||||
json_path_handler &for_field(std::map<std::string, std::vector<std::string>> *field) {
|
||||
this->add_cb(yajlpp_static_string_vector);
|
||||
this->jph_kv_pair = true;
|
||||
this->jph_simple_offset = field;
|
||||
this->jph_gen_callback = yajlpp_static_gen_string_vector;
|
||||
this->jph_validator = yajlpp_validator_for_string_vector;
|
||||
return *this;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
json_path_handler &for_enum(T *field) {
|
||||
this->add_cb(yajlpp_static_enum);
|
||||
|
Loading…
Reference in New Issue
Block a user