mirror of https://github.com/tstack/lnav.git
[debt] more tech debt
This commit is contained in:
parent
cb7a8904c1
commit
9d87cfa2f0
2
NEWS
2
NEWS
|
@ -15,6 +15,8 @@ lnav v0.9.1:
|
|||
pressing 'f' in the filter editor UI; executing the ':toggle-filtering'
|
||||
command; or by doing an UPDATE on the "filtering" column of the
|
||||
"lnav_views" SQLite table.
|
||||
* Themes can now include definitions for text highlights under:
|
||||
/ui/theme-defs/<theme_name>/highlights
|
||||
|
||||
Interface Changes:
|
||||
* When copying log lines, the file name and time offset will be included
|
||||
|
|
|
@ -124,8 +124,8 @@ inline ssize_t utf8_char_to_byte_index(const std::string &str, ssize_t ch_index)
|
|||
|
||||
while (ch_index > 0) {
|
||||
auto ch_len = ww898::utf::utf8::char_size([&str, retval]() {
|
||||
return str[retval];
|
||||
});
|
||||
return std::make_pair(str[retval], str.length() - retval - 1);
|
||||
}).unwrapOr(1);
|
||||
|
||||
retval += ch_len;
|
||||
ch_index -= 1;
|
||||
|
|
|
@ -58,8 +58,6 @@ public:
|
|||
|
||||
bottom_status_source();
|
||||
|
||||
virtual ~bottom_status_source() = default;
|
||||
|
||||
lv_functor_t line_number_wire;
|
||||
lv_functor_t percent_wire;
|
||||
lv_functor_t marks_wire;
|
||||
|
@ -71,12 +69,12 @@ public:
|
|||
this->bss_prompt.set_value(prompt);
|
||||
};
|
||||
|
||||
void grep_error(std::string msg)
|
||||
void grep_error(const std::string& msg) override
|
||||
{
|
||||
this->bss_error.set_value(msg);
|
||||
};
|
||||
|
||||
size_t statusview_fields()
|
||||
size_t statusview_fields() override
|
||||
{
|
||||
size_t retval;
|
||||
|
||||
|
@ -90,7 +88,7 @@ public:
|
|||
return retval;
|
||||
};
|
||||
|
||||
status_field &statusview_value_for_field(int field)
|
||||
status_field &statusview_value_for_field(int field) override
|
||||
{
|
||||
if (!this->bss_error.empty()) {
|
||||
return this->bss_error;
|
||||
|
|
|
@ -32,8 +32,6 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "spookyhash/SpookyV2.h"
|
||||
|
||||
#include <list>
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
|
|
|
@ -74,11 +74,11 @@ void db_label_source::text_attrs_for_line(textview_curses &tc, int row,
|
|||
}
|
||||
for (size_t lpc = 0; lpc < this->dls_headers.size() - 1; lpc++) {
|
||||
if (row % 2 == 0) {
|
||||
sa.push_back(string_attr(lr2, &view_curses::VC_STYLE, A_BOLD));
|
||||
sa.emplace_back(lr2, &view_curses::VC_STYLE, A_BOLD);
|
||||
}
|
||||
lr.lr_start += this->dls_headers[lpc].hm_column_size - 1;
|
||||
lr.lr_end = lr.lr_start + 1;
|
||||
sa.push_back(string_attr(lr, &view_curses::VC_GRAPHIC, ACS_VLINE));
|
||||
sa.emplace_back(lr, &view_curses::VC_GRAPHIC, ACS_VLINE);
|
||||
lr.lr_start += 1;
|
||||
}
|
||||
|
||||
|
@ -268,10 +268,10 @@ size_t db_overlay_source::list_overlay_count(const listview_curses &lv)
|
|||
string_attrs_t &sa = this->dos_lines.back().get_attrs();
|
||||
struct line_range lr(1, 2);
|
||||
|
||||
sa.push_back(string_attr(lr, &view_curses::VC_GRAPHIC, ACS_LTEE));
|
||||
sa.emplace_back(lr, &view_curses::VC_GRAPHIC, ACS_LTEE);
|
||||
lr.lr_start = 3 + jpw_value.wt_ptr.size() + 3;
|
||||
lr.lr_end = -1;
|
||||
sa.push_back(string_attr(lr, &view_curses::VC_STYLE, A_BOLD));
|
||||
sa.emplace_back(lr, &view_curses::VC_STYLE, A_BOLD);
|
||||
|
||||
double num_value = 0.0;
|
||||
|
||||
|
@ -309,10 +309,10 @@ size_t db_overlay_source::list_overlay_count(const listview_curses &lv)
|
|||
string_attrs_t &sa = this->dos_lines.back().get_attrs();
|
||||
struct line_range lr(1, 2);
|
||||
|
||||
sa.push_back(string_attr(lr, &view_curses::VC_GRAPHIC, ACS_LLCORNER));
|
||||
sa.emplace_back(lr, &view_curses::VC_GRAPHIC, ACS_LLCORNER);
|
||||
lr.lr_start = 2;
|
||||
lr.lr_end = -1;
|
||||
sa.push_back(string_attr(lr, &view_curses::VC_GRAPHIC, ACS_HLINE));
|
||||
sa.emplace_back(lr, &view_curses::VC_GRAPHIC, ACS_HLINE);
|
||||
|
||||
retval += 1;
|
||||
}
|
||||
|
@ -348,8 +348,7 @@ bool db_overlay_source::list_value_for_overlay(const listview_curses &lv, int y,
|
|||
if (!this->dos_labels->dls_headers[lpc].hm_graphable) {
|
||||
attrs = A_UNDERLINE;
|
||||
}
|
||||
sa.push_back(string_attr(header_range, &view_curses::VC_STYLE,
|
||||
attrs));
|
||||
sa.emplace_back(header_range, &view_curses::VC_STYLE, attrs);
|
||||
|
||||
before = total_fill / 2;
|
||||
total_fill -= before;
|
||||
|
@ -360,8 +359,7 @@ bool db_overlay_source::list_value_for_overlay(const listview_curses &lv, int y,
|
|||
|
||||
struct line_range lr(0);
|
||||
|
||||
sa.push_back(string_attr(lr, &view_curses::VC_STYLE,
|
||||
A_BOLD | A_UNDERLINE));
|
||||
sa.emplace_back(lr, &view_curses::VC_STYLE, A_BOLD | A_UNDERLINE);
|
||||
return true;
|
||||
}
|
||||
else if (this->dos_active && y >= 2 && ((size_t) y) < (this->dos_lines.size() + 2)) {
|
||||
|
|
|
@ -80,13 +80,6 @@ filter_status_source::filter_status_source()
|
|||
this->tss_fields[TSF_HELP].set_width(20);
|
||||
this->tss_fields[TSF_HELP].set_value(TOGGLE_MSG);
|
||||
this->tss_fields[TSF_HELP].set_left_pad(1);
|
||||
|
||||
this->tss_prompt.set_left_pad(1);
|
||||
this->tss_prompt.set_min_width(35);
|
||||
this->tss_prompt.set_share(1);
|
||||
this->tss_error.set_left_pad(1);
|
||||
this->tss_error.set_min_width(35);
|
||||
this->tss_error.set_share(1);
|
||||
}
|
||||
|
||||
size_t filter_status_source::statusview_fields()
|
||||
|
@ -142,54 +135,38 @@ size_t filter_status_source::statusview_fields()
|
|||
view_colors::VCR_STATUS_STITCH_NORMAL_TO_TITLE);
|
||||
}
|
||||
|
||||
if (this->tss_prompt.empty() && this->tss_error.empty()) {
|
||||
lnav_data.ld_view_stack.top() | [this] (auto tc) {
|
||||
text_sub_source *tss = tc->get_sub_source();
|
||||
if (tss == nullptr) {
|
||||
return;
|
||||
lnav_data.ld_view_stack.top() | [this](auto tc) {
|
||||
text_sub_source *tss = tc->get_sub_source();
|
||||
if (tss == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
filter_stack &fs = tss->get_filters();
|
||||
auto enabled_count = 0, filter_count = 0;
|
||||
|
||||
for (const auto &tf : fs) {
|
||||
if (tf->is_enabled()) {
|
||||
enabled_count += 1;
|
||||
}
|
||||
filter_count += 1;
|
||||
}
|
||||
if (filter_count == 0) {
|
||||
this->tss_fields[TSF_COUNT].set_value("");
|
||||
} else {
|
||||
this->tss_fields[TSF_COUNT].set_value(
|
||||
" " ANSI_BOLD("%d")
|
||||
" of " ANSI_BOLD("%d")
|
||||
" enabled ",
|
||||
enabled_count,
|
||||
filter_count);
|
||||
}
|
||||
};
|
||||
|
||||
filter_stack &fs = tss->get_filters();
|
||||
auto enabled_count = 0, filter_count = 0;
|
||||
|
||||
for (const auto &tf : fs) {
|
||||
if (tf->is_enabled()) {
|
||||
enabled_count += 1;
|
||||
}
|
||||
filter_count += 1;
|
||||
}
|
||||
if (filter_count == 0) {
|
||||
this->tss_fields[TSF_COUNT].set_value("");
|
||||
} else {
|
||||
this->tss_fields[TSF_COUNT].set_value(
|
||||
" " ANSI_BOLD("%d")
|
||||
" of " ANSI_BOLD("%d")
|
||||
" enabled ",
|
||||
enabled_count,
|
||||
filter_count);
|
||||
}
|
||||
};
|
||||
|
||||
return TSF__MAX;
|
||||
}
|
||||
|
||||
return 3;
|
||||
return TSF__MAX;
|
||||
}
|
||||
|
||||
status_field &filter_status_source::statusview_value_for_field(int field)
|
||||
{
|
||||
if (field <= 1) {
|
||||
return this->tss_fields[field];
|
||||
}
|
||||
|
||||
if (!this->tss_error.empty()) {
|
||||
return this->tss_error;
|
||||
}
|
||||
|
||||
if (!this->tss_prompt.empty()) {
|
||||
return this->tss_prompt;
|
||||
}
|
||||
|
||||
return this->tss_fields[field];
|
||||
}
|
||||
|
||||
|
@ -231,6 +208,12 @@ filter_help_status_source::filter_help_status_source()
|
|||
{
|
||||
this->fss_help.set_min_width(10);
|
||||
this->fss_help.set_share(1);
|
||||
this->fss_prompt.set_left_pad(1);
|
||||
this->fss_prompt.set_min_width(35);
|
||||
this->fss_prompt.set_share(1);
|
||||
this->fss_error.set_left_pad(22);
|
||||
this->fss_error.set_min_width(35);
|
||||
this->fss_error.set_share(1);
|
||||
}
|
||||
|
||||
size_t filter_help_status_source::statusview_fields()
|
||||
|
@ -311,5 +294,13 @@ size_t filter_help_status_source::statusview_fields()
|
|||
|
||||
status_field &filter_help_status_source::statusview_value_for_field(int field)
|
||||
{
|
||||
if (!this->fss_error.empty()) {
|
||||
return this->fss_error;
|
||||
}
|
||||
|
||||
if (!this->fss_prompt.empty()) {
|
||||
return this->fss_prompt;
|
||||
}
|
||||
|
||||
return this->fss_help;
|
||||
}
|
||||
|
|
|
@ -58,8 +58,6 @@ public:
|
|||
|
||||
void update_filtered(text_sub_source *tss);
|
||||
|
||||
status_field tss_error{1024, view_colors::VCR_ALERT_STATUS};
|
||||
status_field tss_prompt{1024, view_colors::VCR_STATUS};
|
||||
private:
|
||||
status_field tss_fields[TSF__MAX];
|
||||
int bss_last_filtered_count{0};
|
||||
|
@ -74,6 +72,9 @@ public:
|
|||
size_t statusview_fields() override;
|
||||
|
||||
status_field &statusview_value_for_field(int field) override;
|
||||
|
||||
status_field fss_prompt{1024, view_colors::VCR_STATUS};
|
||||
status_field fss_error{1024, view_colors::VCR_ALERT_STATUS};
|
||||
private:
|
||||
status_field fss_help;
|
||||
};
|
||||
|
|
|
@ -136,12 +136,15 @@ bool filter_sub_source::list_input_handle_key(listview_curses &lv, int ch)
|
|||
textview_curses *top_view = *lnav_data.ld_view_stack.top();
|
||||
text_sub_source *tss = top_view->get_sub_source();
|
||||
filter_stack &fs = tss->get_filters();
|
||||
auto filter_index = fs.next_index();
|
||||
|
||||
if (fs.full()) {
|
||||
if (!filter_index) {
|
||||
lnav_data.ld_filter_help_status_source.fss_error
|
||||
.set_value("error: too many filters");
|
||||
return true;
|
||||
}
|
||||
|
||||
auto ef = make_shared<empty_filter>(text_filter::type_t::INCLUDE, fs.next_index());
|
||||
auto ef = make_shared<empty_filter>(text_filter::type_t::INCLUDE, *filter_index);
|
||||
fs.add_filter(ef);
|
||||
lv.set_selection(vis_line_t(fs.size() - 1));
|
||||
lv.reload_data();
|
||||
|
@ -163,12 +166,15 @@ bool filter_sub_source::list_input_handle_key(listview_curses &lv, int ch)
|
|||
textview_curses *top_view = *lnav_data.ld_view_stack.top();
|
||||
text_sub_source *tss = top_view->get_sub_source();
|
||||
filter_stack &fs = tss->get_filters();
|
||||
auto filter_index = fs.next_index();
|
||||
|
||||
if (fs.full()) {
|
||||
if (!filter_index) {
|
||||
lnav_data.ld_filter_help_status_source.fss_error
|
||||
.set_value("error: too many filters");
|
||||
return true;
|
||||
}
|
||||
|
||||
auto ef = make_shared<empty_filter>(text_filter::type_t::EXCLUDE, fs.next_index());
|
||||
auto ef = make_shared<empty_filter>(text_filter::type_t::EXCLUDE, *filter_index);
|
||||
fs.add_filter(ef);
|
||||
lv.set_selection(vis_line_t(fs.size() - 1));
|
||||
lv.reload_data();
|
||||
|
@ -362,7 +368,7 @@ void filter_sub_source::rl_change(readline_curses *rc)
|
|||
&errptr,
|
||||
&eoff,
|
||||
nullptr)) == nullptr) {
|
||||
lnav_data.ld_filter_status_source.tss_error
|
||||
lnav_data.ld_filter_help_status_source.fss_error
|
||||
.set_value("error: %s", errptr);
|
||||
} else {
|
||||
textview_curses::highlight_map_t &hm = top_view->get_highlights();
|
||||
|
@ -379,7 +385,7 @@ void filter_sub_source::rl_change(readline_curses *rc)
|
|||
|
||||
hm[{highlight_source_t::PREVIEW, "preview"}] = hl;
|
||||
top_view->set_needs_update();
|
||||
lnav_data.ld_filter_status_source.tss_error.clear();
|
||||
lnav_data.ld_filter_help_status_source.fss_error.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -414,7 +420,7 @@ void filter_sub_source::rl_perform(readline_curses *rc)
|
|||
tss->text_filters_changed();
|
||||
}
|
||||
|
||||
lnav_data.ld_filter_status_source.tss_prompt.clear();
|
||||
lnav_data.ld_filter_help_status_source.fss_prompt.clear();
|
||||
this->fss_editing = false;
|
||||
this->fss_editor.set_visible(false);
|
||||
this->tss_view->reload_data();
|
||||
|
@ -428,8 +434,8 @@ void filter_sub_source::rl_abort(readline_curses *rc)
|
|||
auto iter = fs.begin() + this->tss_view->get_selection();
|
||||
shared_ptr<text_filter> tf = *iter;
|
||||
|
||||
lnav_data.ld_filter_status_source.tss_prompt.clear();
|
||||
lnav_data.ld_filter_status_source.tss_error.clear();
|
||||
lnav_data.ld_filter_help_status_source.fss_prompt.clear();
|
||||
lnav_data.ld_filter_help_status_source.fss_error.clear();
|
||||
top_view->get_highlights().erase({highlight_source_t::PREVIEW, "preview"});
|
||||
top_view->reload_data();
|
||||
fs.delete_filter("");
|
||||
|
|
|
@ -103,7 +103,7 @@ public:
|
|||
virtual ~grep_proc_control() = default;
|
||||
|
||||
/** @param msg The error encountered while attempting the grep. */
|
||||
virtual void grep_error(std::string msg) { };
|
||||
virtual void grep_error(const std::string& msg) { };
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -36,9 +36,12 @@
|
|||
#include "attr_line.hh"
|
||||
|
||||
using help_example_to_attr_line_fun_t =
|
||||
std::function<attr_line_t(const help_text &, const help_example &)>;
|
||||
std::function<attr_line_t(const help_text &, const help_example &)>;
|
||||
|
||||
void
|
||||
format_help_text_for_term(const help_text &ht, size_t width, attr_line_t &out,
|
||||
bool synopsis_only = false);
|
||||
|
||||
void format_help_text_for_term(const help_text &ht, size_t width, attr_line_t &out, bool synopsis_only = false);
|
||||
void format_example_text_for_term(
|
||||
const help_text &ht,
|
||||
help_example_to_attr_line_fun_t eval,
|
||||
|
|
|
@ -51,6 +51,8 @@ STRONG_INT_TYPE(int, bucket_group);
|
|||
STRONG_INT_TYPE(int, bucket_type);
|
||||
|
||||
struct stacked_bar_chart_base {
|
||||
virtual ~stacked_bar_chart_base() = default;
|
||||
|
||||
struct show_none {};
|
||||
struct show_all {};
|
||||
struct show_one {
|
||||
|
@ -78,8 +80,6 @@ public:
|
|||
|
||||
};
|
||||
|
||||
virtual ~stacked_bar_chart() { };
|
||||
|
||||
stacked_bar_chart &with_stacking_enabled(bool enabled) {
|
||||
this->sbc_do_stacking = enabled;
|
||||
return *this;
|
||||
|
|
|
@ -113,7 +113,10 @@ void input_dispatcher::new_input(const struct timeval ¤t_time, int ch)
|
|||
this->id_escape_index = 0;
|
||||
}
|
||||
} else {
|
||||
auto seq_size = utf::utf8::char_size([ch]() { return ch; });
|
||||
auto seq_size = utf::utf8::char_size([ch]() {
|
||||
return std::make_pair(ch, 16);
|
||||
})
|
||||
.unwrapOr(size_t{1});
|
||||
|
||||
if (seq_size == 1) {
|
||||
snprintf(keyseq.data(), keyseq.size(), "x%02x", ch & 0xff);
|
||||
|
|
|
@ -1020,6 +1020,7 @@ static bool handle_config_ui_key(int ch)
|
|||
{
|
||||
nonstd::optional<ln_mode_t> new_mode;
|
||||
|
||||
lnav_data.ld_filter_help_status_source.fss_error.clear();
|
||||
if (ch == 'F') {
|
||||
new_mode = LNM_FILES;
|
||||
} else if (ch == 'T') {
|
||||
|
|
|
@ -1317,7 +1317,11 @@ static Result<string, string> com_filter(exec_context &ec, string cmdline, vecto
|
|||
text_filter::type_t lt = (args[0] == "filter-out") ?
|
||||
text_filter::EXCLUDE :
|
||||
text_filter::INCLUDE;
|
||||
auto pf = make_shared<pcre_filter>(lt, args[1], fs.next_index(), code.release());
|
||||
auto filter_index = fs.next_index();
|
||||
if (!filter_index) {
|
||||
return ec.make_error("too many filters");
|
||||
}
|
||||
auto pf = make_shared<pcre_filter>(lt, args[1], *filter_index, code.release());
|
||||
|
||||
log_debug("%s [%d] %s", args[0].c_str(), pf->get_index(), args[1].c_str());
|
||||
fs.add_filter(pf);
|
||||
|
@ -2809,7 +2813,7 @@ static Result<string, string> com_add_test(exec_context &ec, string cmdline, vec
|
|||
snprintf(path, sizeof(path),
|
||||
"%s/test/log-samples/sample-%s.txt",
|
||||
getenv("LNAV_SRC"),
|
||||
hash_string(line).c_str());
|
||||
hasher().update(line).to_string().c_str());
|
||||
|
||||
if ((file = fopen(path, "w")) == nullptr) {
|
||||
perror("fopen failed");
|
||||
|
|
|
@ -127,21 +127,42 @@ inline mstime_t getmstime() {
|
|||
#error "off_t has unhandled size..."
|
||||
#endif
|
||||
|
||||
struct hash_updater {
|
||||
hash_updater(SpookyHash *context) : su_context(context) { };
|
||||
|
||||
void operator()(const std::string &str)
|
||||
{
|
||||
this->su_context->Update(str.c_str(), str.length());
|
||||
class hasher {
|
||||
public:
|
||||
hasher() {
|
||||
this->h_context.Init(0, 0);
|
||||
}
|
||||
|
||||
SpookyHash *su_context;
|
||||
hasher &update(const std::string &str) {
|
||||
this->h_context.Update(str.data(), str.length());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
hasher &update(const char *bits, size_t len) {
|
||||
this->h_context.Update(bits, len);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T,
|
||||
typename = std::enable_if<std::is_arithmetic<T>::value>>
|
||||
hasher &update(T value) {
|
||||
this->h_context.Update(&value, sizeof(value));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string to_string() {
|
||||
byte_array<2, uint64> bits;
|
||||
|
||||
this->h_context.Final(bits.out(0), bits.out(1));
|
||||
return bits.to_string();
|
||||
}
|
||||
private:
|
||||
SpookyHash h_context;
|
||||
};
|
||||
|
||||
std::string hash_string(const std::string &str);
|
||||
|
||||
std::string hash_bytes(const char *str1, size_t s1len, ...);
|
||||
|
||||
template<typename UnaryFunction, typename Member>
|
||||
struct object_field_t {
|
||||
object_field_t(UnaryFunction &func, Member &mem)
|
||||
|
|
|
@ -190,7 +190,7 @@ class generic_log_format : public log_format {
|
|||
|
||||
lr.lr_start = pc[0]->c_begin;
|
||||
lr.lr_end = pc[0]->c_end;
|
||||
sa.push_back(string_attr(lr, &logline::L_TIMESTAMP));
|
||||
sa.emplace_back(lr, &logline::L_TIMESTAMP);
|
||||
|
||||
const char *level = &line.get_data()[pc[1]->c_begin];
|
||||
|
||||
|
@ -203,11 +203,11 @@ class generic_log_format : public log_format {
|
|||
|
||||
lr.lr_start = 0;
|
||||
lr.lr_end = prefix_len;
|
||||
sa.push_back(string_attr(lr, &logline::L_PREFIX));
|
||||
sa.emplace_back(lr, &logline::L_PREFIX);
|
||||
|
||||
lr.lr_start = prefix_len;
|
||||
lr.lr_end = line.length();
|
||||
sa.push_back(string_attr(lr, &textview_curses::SA_BODY));
|
||||
sa.emplace_back(lr, &textview_curses::SA_BODY);
|
||||
};
|
||||
|
||||
unique_ptr<log_format> specialized(int fmt_lock)
|
||||
|
|
|
@ -98,7 +98,7 @@ logfile::logfile(const string &filename, logfile_open_options &loo)
|
|||
this->lf_valid_filename = false;
|
||||
}
|
||||
|
||||
this->lf_content_id = hash_string(this->lf_filename);
|
||||
this->lf_content_id = hasher().update(this->lf_filename).to_string();
|
||||
this->lf_line_buffer.set_fd(this->lf_options.loo_fd);
|
||||
this->lf_index.reserve(INDEX_RESERVE_INCREMENT);
|
||||
|
||||
|
@ -187,7 +187,9 @@ bool logfile::process_prefix(shared_buffer_ref &sbr, const line_info &li)
|
|||
|
||||
this->lf_format = (*iter)->specialized();
|
||||
this->set_format_base_time(this->lf_format.get());
|
||||
this->lf_content_id = hash_string(string(sbr.get_data(), sbr.length()));
|
||||
this->lf_content_id = hasher()
|
||||
.update(sbr.get_data(), sbr.length())
|
||||
.to_string();
|
||||
|
||||
/*
|
||||
* We'll go ahead and assume that any previous lines were
|
||||
|
|
|
@ -340,7 +340,7 @@ static void rl_search_internal(void *dummy, readline_curses *rc, ln_mode_t mode,
|
|||
const char *errmsg = sqlite3_errmsg(lnav_data.ld_db);
|
||||
|
||||
lnav_data.ld_bottom_source.
|
||||
grep_error(string("sql error: ") + string(errmsg));
|
||||
grep_error(fmt::format("sql error: {}", errmsg));
|
||||
} else {
|
||||
lnav_data.ld_bottom_source.grep_error("");
|
||||
}
|
||||
|
|
|
@ -36,8 +36,6 @@
|
|||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "spookyhash/SpookyV2.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <yajl/api/yajl_tree.h>
|
||||
|
@ -173,9 +171,10 @@ static bool bind_line(sqlite3 *db,
|
|||
}
|
||||
|
||||
auto line_hash = read_result.map([cl](auto sbr) {
|
||||
return hash_bytes(sbr.get_data(), sbr.length(),
|
||||
&cl, sizeof(cl),
|
||||
nullptr);
|
||||
return hasher()
|
||||
.update(sbr.get_data(), sbr.length())
|
||||
.update(cl)
|
||||
.to_string();
|
||||
}).unwrap();
|
||||
|
||||
return bind_values(stmt,
|
||||
|
@ -297,25 +296,21 @@ void init_session()
|
|||
|
||||
static nonstd::optional<std::string> compute_session_id()
|
||||
{
|
||||
byte_array<2, uint64> hash;
|
||||
SpookyHash context;
|
||||
bool has_files = false;
|
||||
hasher h;
|
||||
|
||||
context.Init(0, 0);
|
||||
hash_updater updater(&context);
|
||||
for (auto &ld_file_name : lnav_data.ld_active_files.fc_file_names) {
|
||||
if (!ld_file_name.second.loo_include_in_session) {
|
||||
continue;
|
||||
}
|
||||
has_files = true;
|
||||
updater(ld_file_name.first);
|
||||
h.update(ld_file_name.first);
|
||||
}
|
||||
if (!has_files) {
|
||||
return nonstd::nullopt;
|
||||
}
|
||||
context.Final(hash.out(0), hash.out(1));
|
||||
|
||||
return hash.to_string();
|
||||
return h.to_string();
|
||||
}
|
||||
|
||||
nonstd::optional<session_pair_t> scan_sessions()
|
||||
|
@ -504,9 +499,10 @@ void load_time_bookmarks()
|
|||
|
||||
auto sbr = read_result.unwrap();
|
||||
|
||||
string line_hash = hash_bytes(sbr.get_data(), sbr.length(),
|
||||
&cl, sizeof(cl),
|
||||
nullptr);
|
||||
string line_hash = hasher()
|
||||
.update(sbr.get_data(), sbr.length())
|
||||
.update(cl)
|
||||
.to_string();
|
||||
|
||||
if (line_hash == log_hash) {
|
||||
content_line_t line_cl = content_line_t(
|
||||
|
@ -671,7 +667,9 @@ void load_time_bookmarks()
|
|||
|
||||
auto sbr = read_result.unwrap();
|
||||
|
||||
string line_hash = hash_bytes(sbr.get_data(), sbr.length(), nullptr);
|
||||
string line_hash = hasher()
|
||||
.update(sbr.get_data(), sbr.length())
|
||||
.to_string();
|
||||
if (line_hash == log_hash) {
|
||||
int file_line = std::distance(lf->begin(), line_iter);
|
||||
content_line_t line_cl = content_line_t(
|
||||
|
@ -1241,7 +1239,9 @@ static void save_time_bookmarks()
|
|||
lf->original_line_time(line_iter),
|
||||
lf->get_format()->get_name(),
|
||||
read_result.map([](auto sbr) {
|
||||
return hash_bytes(sbr.get_data(), sbr.length(), nullptr);
|
||||
return hasher()
|
||||
.update(sbr.get_data(), sbr.length())
|
||||
.to_string();
|
||||
}).unwrap(),
|
||||
lnav_data.ld_session_time,
|
||||
offset.tv_sec,
|
||||
|
|
|
@ -404,11 +404,11 @@ public:
|
|||
else {
|
||||
color = COLOR_RED;
|
||||
}
|
||||
value_out.push_back(string_attr(
|
||||
value_out.emplace_back(
|
||||
line_range(lpc, lpc + 1),
|
||||
&view_curses::VC_STYLE,
|
||||
vc.ansi_color_pair(COLOR_BLACK, color)
|
||||
));
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ void textfile_sub_source::text_attrs_for_line(textview_curses &tc, int row,
|
|||
|
||||
lr.lr_start = 0;
|
||||
lr.lr_end = -1;
|
||||
value_out.push_back(string_attr(lr, &logline::L_FILE, this->current_file().get()));
|
||||
value_out.emplace_back(lr, &logline::L_FILE, this->current_file().get());
|
||||
}
|
||||
|
||||
size_t textfile_sub_source::text_size_for_line(textview_curses &tc, int line,
|
||||
|
|
|
@ -203,7 +203,7 @@ public:
|
|||
return this->fs_filters.size() == logfile_filter_state::MAX_FILTERS;
|
||||
}
|
||||
|
||||
size_t next_index() {
|
||||
nonstd::optional<size_t> next_index() {
|
||||
bool used[32];
|
||||
|
||||
memset(used, 0, sizeof(used));
|
||||
|
@ -223,7 +223,7 @@ public:
|
|||
return lpc;
|
||||
}
|
||||
}
|
||||
throw "No more filters";
|
||||
return nonstd::nullopt;
|
||||
};
|
||||
|
||||
void add_filter(const std::shared_ptr<text_filter> &filter) {
|
||||
|
|
|
@ -319,24 +319,32 @@ void view_curses::mvwattrline(WINDOW *window,
|
|||
break;
|
||||
|
||||
default: {
|
||||
auto offset = 1 - (int) ww898::utf::utf8::char_size([ch]() {
|
||||
return ch;
|
||||
auto size_result = ww898::utf::utf8::char_size([&line, lpc]() {
|
||||
return std::make_pair(line[lpc], line.length() - lpc - 1);
|
||||
});
|
||||
|
||||
expanded_line[exp_index] = line[lpc];
|
||||
exp_index += 1;
|
||||
if (offset) {
|
||||
if (char_index < lr_chars.lr_start) {
|
||||
lr_bytes.lr_start += abs(offset);
|
||||
}
|
||||
if (char_index < lr_chars.lr_end) {
|
||||
lr_bytes.lr_end += abs(offset);
|
||||
}
|
||||
exp_offset += offset;
|
||||
utf_adjustments.emplace_back(lpc, offset);
|
||||
for (; offset && (lpc + 1) < line.size(); lpc++, offset++) {
|
||||
expanded_line[exp_index] = line[lpc + 1];
|
||||
exp_index += 1;
|
||||
if (size_result.isErr()) {
|
||||
expanded_line[exp_index] = '?';
|
||||
exp_index += 1;
|
||||
} else {
|
||||
auto offset = 1 - (int) size_result.unwrap();
|
||||
|
||||
expanded_line[exp_index] = line[lpc];
|
||||
exp_index += 1;
|
||||
if (offset) {
|
||||
if (char_index < lr_chars.lr_start) {
|
||||
lr_bytes.lr_start += abs(offset);
|
||||
}
|
||||
if (char_index < lr_chars.lr_end) {
|
||||
lr_bytes.lr_end += abs(offset);
|
||||
}
|
||||
exp_offset += offset;
|
||||
utf_adjustments.emplace_back(lpc, offset);
|
||||
for (; offset &&
|
||||
(lpc + 1) < line.size(); lpc++, offset++) {
|
||||
expanded_line[exp_index] = line[lpc + 1];
|
||||
exp_index += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
char_index += 1;
|
||||
|
|
|
@ -462,10 +462,14 @@ CREATE TABLE lnav_view_filters (
|
|||
textview_curses &tc = lnav_data.ld_views[view_index];
|
||||
text_sub_source *tss = tc.get_sub_source();
|
||||
filter_stack &fs = tss->get_filters();
|
||||
auto filter_index = fs.next_index();
|
||||
if (!filter_index) {
|
||||
throw sqlite_func_error("Too many filters");
|
||||
}
|
||||
auto pf = make_shared<pcre_filter>(
|
||||
type.value_or(text_filter::type_t::EXCLUDE),
|
||||
pattern.first,
|
||||
fs.next_index(),
|
||||
*filter_index,
|
||||
pattern.second);
|
||||
fs.add_filter(pf);
|
||||
if (!enabled.value_or(true)) {
|
||||
|
|
|
@ -230,8 +230,9 @@ void vt52_curses::map_output(const char *output, int len)
|
|||
else {
|
||||
auto next_ch = output[lpc];
|
||||
auto seq_size = ww898::utf::utf8::char_size([next_ch]() {
|
||||
return next_ch;
|
||||
});
|
||||
return std::make_pair(next_ch, 16);
|
||||
})
|
||||
.unwrapOr(size_t{1});
|
||||
|
||||
if (seq_size > 1) {
|
||||
this->vc_escape[0] = next_ch;
|
||||
|
|
|
@ -25,8 +25,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "base/result.h"
|
||||
|
||||
namespace ww898 {
|
||||
namespace utf {
|
||||
|
||||
|
@ -47,24 +50,34 @@ struct utf8 final
|
|||
using char_type = uint8_t;
|
||||
|
||||
template<typename PeekFn>
|
||||
static size_t char_size(PeekFn && peek_fn)
|
||||
static Result<size_t, const char *> char_size(PeekFn && peek_fn)
|
||||
{
|
||||
char_type const ch0 = std::forward<PeekFn>(peek_fn)();
|
||||
if (ch0 < 0x80) // 0xxx_xxxx
|
||||
return 1;
|
||||
if (ch0 < 0xC0)
|
||||
throw std::runtime_error("The utf8 first char in sequence is incorrect");
|
||||
if (ch0 < 0xE0) // 110x_xxxx 10xx_xxxx
|
||||
return 2;
|
||||
if (ch0 < 0xF0) // 1110_xxxx 10xx_xxxx 10xx_xxxx
|
||||
return 3;
|
||||
if (ch0 < 0xF8) // 1111_0xxx 10xx_xxxx 10xx_xxxx 10xx_xxxx
|
||||
return 4;
|
||||
if (ch0 < 0xFC) // 1111_10xx 10xx_xxxx 10xx_xxxx 10xx_xxxx 10xx_xxxx
|
||||
return 5;
|
||||
if (ch0 < 0xFE) // 1111_110x 10xx_xxxx 10xx_xxxx 10xx_xxxx 10xx_xxxx 10xx_xxxx
|
||||
return 6;
|
||||
throw std::runtime_error("The utf8 first char in sequence is incorrect");
|
||||
const std::pair<char_type, size_t> peek_res = std::forward<PeekFn>(peek_fn)();
|
||||
const auto ch0 = peek_res.first;
|
||||
const auto remaining = peek_res.second;
|
||||
size_t retval = 0;
|
||||
|
||||
if (ch0 < 0x80) { // 0xxx_xxxx
|
||||
retval = 1;
|
||||
} else if (ch0 < 0xC0) {
|
||||
return Err("The utf8 first char in sequence is incorrect");
|
||||
} else if (ch0 < 0xE0) { // 110x_xxxx 10xx_xxxx
|
||||
retval = 2;
|
||||
} else if (ch0 < 0xF0) { // 1110_xxxx 10xx_xxxx 10xx_xxxx
|
||||
retval = 3;
|
||||
} else if (ch0 < 0xF8) { // 1111_0xxx 10xx_xxxx 10xx_xxxx 10xx_xxxx
|
||||
retval = 4;
|
||||
} else if (ch0 < 0xFC) { // 1111_10xx 10xx_xxxx 10xx_xxxx 10xx_xxxx 10xx_xxxx
|
||||
retval = 5;
|
||||
} else if (ch0 < 0xFE) { // 1111_110x 10xx_xxxx 10xx_xxxx 10xx_xxxx 10xx_xxxx 10xx_xxxx
|
||||
retval = 6;
|
||||
} else {
|
||||
return Err("The utf8 first char in sequence is incorrect");
|
||||
}
|
||||
if (retval - 1 > remaining) {
|
||||
return Err("Truncated utf8 sequence");
|
||||
}
|
||||
return Ok(retval);
|
||||
}
|
||||
|
||||
template<typename ReadFn>
|
||||
|
|
Loading…
Reference in New Issue