mirror of
https://github.com/tstack/lnav.git
synced 2024-10-05 17:17:37 +03:00
[line_buffer] add some performance counters for tracking SQL perf
Also, check for keyboard input during SQL execution so we can cancel. Fixes #894
This commit is contained in:
parent
0f2d38df50
commit
8ef581177c
4
NEWS
4
NEWS
@ -30,6 +30,8 @@ lnav v0.11.0:
|
||||
that range. You can then press TAB to focus on the detail view
|
||||
and scroll around.
|
||||
* Add initial support for pcap(3) files using tshark(1).
|
||||
* SQL statement execution can now be canceled by pressing CTRL+]
|
||||
(same as canceling out of a prompt).
|
||||
* To make it possible to automate some operations, there is now an
|
||||
"lnav_events" table that is updated when internal events occur
|
||||
within lnav (e.g. opening a file, format is detected). You
|
||||
@ -105,6 +107,8 @@ lnav v0.11.0:
|
||||
* Fix a crash related to long lines that are word wrapped.
|
||||
* Multiple SQL statements in a SQL block of a script are now
|
||||
executed instead of just the first one.
|
||||
* In cases where there were many different colors on screen, some
|
||||
text would be colored incorrectly.
|
||||
|
||||
lnav v0.10.1:
|
||||
Features:
|
||||
|
@ -269,6 +269,11 @@
|
||||
"title": "/ui/theme-defs/<theme_name>/styles/ok",
|
||||
"$ref": "#/definitions/style"
|
||||
},
|
||||
"info": {
|
||||
"description": "Styling for informational messages",
|
||||
"title": "/ui/theme-defs/<theme_name>/styles/info",
|
||||
"$ref": "#/definitions/style"
|
||||
},
|
||||
"warning": {
|
||||
"description": "Styling for warning messages",
|
||||
"title": "/ui/theme-defs/<theme_name>/styles/warning",
|
||||
|
@ -50,7 +50,7 @@ void
|
||||
scrub_ansi_string(std::string& str, string_attrs_t& sa)
|
||||
{
|
||||
pcre_context_static<60> context;
|
||||
pcrepp& regex = ansi_regex();
|
||||
auto& regex = ansi_regex();
|
||||
pcre_input pi(str);
|
||||
|
||||
replace(str.begin(), str.end(), '\0', ' ');
|
||||
@ -58,9 +58,7 @@ scrub_ansi_string(std::string& str, string_attrs_t& sa)
|
||||
pcre_context::capture_t* caps = context.all();
|
||||
struct line_range lr;
|
||||
bool has_attrs = false;
|
||||
attr_t attrs = 0;
|
||||
auto bg = nonstd::optional<int>();
|
||||
auto fg = nonstd::optional<int>();
|
||||
text_attrs attrs;
|
||||
auto role = nonstd::optional<role_t>();
|
||||
size_t lpc;
|
||||
|
||||
@ -74,29 +72,29 @@ scrub_ansi_string(std::string& str, string_attrs_t& sa)
|
||||
if (sscanf(&(str[lpc]), "%d", &ansi_code) == 1) {
|
||||
if (90 <= ansi_code && ansi_code <= 97) {
|
||||
ansi_code -= 60;
|
||||
attrs |= A_STANDOUT;
|
||||
attrs.ta_attrs |= A_STANDOUT;
|
||||
}
|
||||
if (30 <= ansi_code && ansi_code <= 37) {
|
||||
fg = ansi_code - 30;
|
||||
attrs.ta_fg_color = ansi_code - 30;
|
||||
}
|
||||
if (40 <= ansi_code && ansi_code <= 47) {
|
||||
bg = ansi_code - 40;
|
||||
attrs.ta_bg_color = ansi_code - 40;
|
||||
}
|
||||
switch (ansi_code) {
|
||||
case 1:
|
||||
attrs |= A_BOLD;
|
||||
attrs.ta_attrs |= A_BOLD;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
attrs |= A_DIM;
|
||||
attrs.ta_attrs |= A_DIM;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
attrs |= A_UNDERLINE;
|
||||
attrs.ta_attrs |= A_UNDERLINE;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
attrs |= A_REVERSE;
|
||||
attrs.ta_attrs |= A_REVERSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -160,17 +158,11 @@ scrub_ansi_string(std::string& str, string_attrs_t& sa)
|
||||
}
|
||||
lr.lr_start = caps[0].c_begin;
|
||||
lr.lr_end = -1;
|
||||
if (attrs) {
|
||||
if (attrs.ta_attrs || attrs.ta_fg_color || attrs.ta_bg_color) {
|
||||
sa.emplace_back(lr, VC_STYLE.value(attrs));
|
||||
}
|
||||
role |
|
||||
[&lr, &sa](role_t r) { sa.emplace_back(lr, VC_ROLE.value(r)); };
|
||||
fg | [&lr, &sa](int color) {
|
||||
sa.emplace_back(lr, VC_FOREGROUND.value(color));
|
||||
};
|
||||
bg | [&lr, &sa](int color) {
|
||||
sa.emplace_back(lr, VC_BACKGROUND.value(color));
|
||||
};
|
||||
}
|
||||
|
||||
pi.reset(str);
|
||||
|
@ -101,7 +101,7 @@ consume(const string_fragment text)
|
||||
pcre_input pi(text);
|
||||
pcre_context_static<30> pc;
|
||||
|
||||
if (WORD_RE.match(pc, pi)) {
|
||||
if (WORD_RE.match(pc, pi, PCRE_NO_UTF8_CHECK)) {
|
||||
auto split_res = text.split_n(pc.all()->length()).value();
|
||||
|
||||
return word{split_res.first, split_res.second};
|
||||
@ -113,7 +113,7 @@ consume(const string_fragment text)
|
||||
return space{split_res.first, split_res.second};
|
||||
}
|
||||
|
||||
if (SPACE_RE.match(pc, pi)) {
|
||||
if (SPACE_RE.match(pc, pi, PCRE_NO_UTF8_CHECK)) {
|
||||
auto split_res = text.split_n(pc.all()->length()).value();
|
||||
|
||||
return space{split_res.first, split_res.second};
|
||||
@ -195,8 +195,8 @@ attr_line_t::insert(size_t index,
|
||||
|
||||
const ssize_t usable_width = tws->tws_width - tws->tws_indent;
|
||||
|
||||
auto text_to_wrap
|
||||
= string_fragment{this->al_string.data(), (int) starting_line_index};
|
||||
auto text_to_wrap = string_fragment::from_str_range(
|
||||
this->al_string, starting_line_index, this->al_string.length());
|
||||
string_fragment last_word;
|
||||
ssize_t line_ch_count = 0;
|
||||
auto needs_indent = false;
|
||||
@ -225,7 +225,8 @@ attr_line_t::insert(size_t index,
|
||||
|
||||
text_to_wrap = chunk.match(
|
||||
[&](text_stream::word word) {
|
||||
auto ch_count = word.w_word.utf8_length().unwrap();
|
||||
auto ch_count
|
||||
= word.w_word.utf8_length().unwrapOr(word.w_word.length());
|
||||
|
||||
if ((line_ch_count + ch_count) > usable_width
|
||||
&& find_string_attr_containing(this->al_attrs,
|
||||
@ -272,7 +273,8 @@ attr_line_t::insert(size_t index,
|
||||
}
|
||||
|
||||
if (line_ch_count > 0) {
|
||||
auto ch_count = space.s_value.utf8_length().unwrap();
|
||||
auto ch_count = space.s_value.utf8_length().unwrapOr(
|
||||
space.s_value.length());
|
||||
|
||||
if ((line_ch_count + ch_count) > usable_width
|
||||
&& find_string_attr_containing(this->al_attrs,
|
||||
|
@ -47,15 +47,71 @@
|
||||
struct string_fragment {
|
||||
using iterator = const char*;
|
||||
|
||||
static string_fragment from_c_str(const char* str)
|
||||
{
|
||||
return string_fragment{str, 0, (int) strlen(str)};
|
||||
}
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
static string_fragment from_const(const T (&str)[N])
|
||||
{
|
||||
return string_fragment{str, 0, (int) N - 1};
|
||||
}
|
||||
|
||||
static string_fragment from_str(const std::string& str)
|
||||
{
|
||||
return string_fragment{str.c_str(), 0, (int) str.size()};
|
||||
}
|
||||
|
||||
static string_fragment from_substr(const std::string& str,
|
||||
size_t offset,
|
||||
size_t length)
|
||||
{
|
||||
return string_fragment{
|
||||
str.c_str(), (int) offset, (int) (offset + length)};
|
||||
}
|
||||
|
||||
static string_fragment from_str_range(const std::string& str,
|
||||
size_t begin,
|
||||
size_t end)
|
||||
{
|
||||
return string_fragment{str.c_str(), (int) begin, (int) end};
|
||||
}
|
||||
|
||||
static string_fragment from_bytes(const char* bytes, size_t len)
|
||||
{
|
||||
return string_fragment{bytes, 0, (int) len};
|
||||
}
|
||||
|
||||
static string_fragment from_bytes(const unsigned char* bytes, size_t len)
|
||||
{
|
||||
return string_fragment{(const char*) bytes, 0, (int) len};
|
||||
}
|
||||
|
||||
static string_fragment from_memory_buffer(const fmt::memory_buffer& buf)
|
||||
{
|
||||
return string_fragment{buf.data(), 0, (int) buf.size()};
|
||||
}
|
||||
|
||||
static string_fragment from_byte_range(const char* bytes,
|
||||
size_t begin,
|
||||
size_t end)
|
||||
{
|
||||
return string_fragment{bytes, (int) begin, (int) end};
|
||||
}
|
||||
|
||||
explicit string_fragment(const char* str = "", int begin = 0, int end = -1)
|
||||
: sf_string(str), sf_begin(begin),
|
||||
sf_end(end == -1 ? strlen(str) : end){};
|
||||
: sf_string(str), sf_begin(begin), sf_end(end == -1 ? strlen(str) : end)
|
||||
{
|
||||
}
|
||||
|
||||
explicit string_fragment(const unsigned char* str,
|
||||
int begin = 0,
|
||||
int end = -1)
|
||||
: sf_string((const char*) str), sf_begin(begin),
|
||||
sf_end(end == -1 ? strlen((const char*) str) : end){};
|
||||
sf_end(end == -1 ? strlen((const char*) str) : end)
|
||||
{
|
||||
}
|
||||
|
||||
string_fragment(const std::string& str)
|
||||
: sf_string(str.c_str()), sf_begin(0), sf_end(str.length())
|
||||
|
@ -60,14 +60,18 @@
|
||||
error.
|
||||
*/
|
||||
ssize_t
|
||||
is_utf8(unsigned char* str, size_t len, const char** message, int* faulty_bytes)
|
||||
is_utf8(const unsigned char* str,
|
||||
size_t len,
|
||||
const char** message,
|
||||
int* faulty_bytes,
|
||||
nonstd::optional<unsigned char> terminator)
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
*message = nullptr;
|
||||
*faulty_bytes = 0;
|
||||
while (i < len) {
|
||||
if (str[i] == '\n') {
|
||||
if (terminator && str[i] == terminator.value()) {
|
||||
*message = nullptr;
|
||||
return i;
|
||||
}
|
||||
|
@ -31,9 +31,12 @@
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
ssize_t is_utf8(unsigned char* str,
|
||||
#include "optional.hpp"
|
||||
|
||||
ssize_t is_utf8(const unsigned char* str,
|
||||
size_t len,
|
||||
const char** message,
|
||||
int* faulty_bytes);
|
||||
int* faulty_bytes,
|
||||
nonstd::optional<unsigned char> terminator = nonstd::nullopt);
|
||||
|
||||
#endif /* _IS_UTF8_H */
|
||||
|
@ -588,6 +588,18 @@ operator|(nonstd::optional<T> in,
|
||||
lnav::func::invoke(eacher.fe_func, in.value());
|
||||
}
|
||||
|
||||
template<typename T,
|
||||
typename F,
|
||||
std::enable_if_t<lnav::func::is_invocable<F, T>::value, int> = 0>
|
||||
void
|
||||
operator|(std::vector<std::shared_ptr<T>>& in,
|
||||
const lnav::itertools::details::for_eacher<F>& eacher)
|
||||
{
|
||||
for (auto& elem : in) {
|
||||
lnav::func::invoke(eacher.fe_func, *elem);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T,
|
||||
typename F,
|
||||
std::enable_if_t<lnav::func::is_invocable<F, T>::value, int> = 0>
|
||||
|
@ -110,7 +110,7 @@ user_message::to_attr_line(std::set<render_flags> flags) const
|
||||
retval.append(lnav::roles::ok("\u2714 "));
|
||||
break;
|
||||
case level::info:
|
||||
retval.append(lnav::roles::status("\u24d8 info")).append(": ");
|
||||
retval.append("\u24d8 info"_info).append(": ");
|
||||
break;
|
||||
case level::warning:
|
||||
retval.append(lnav::roles::warning("\u26a0 warning"))
|
||||
@ -293,15 +293,31 @@ println(FILE* file, const attr_line_t& al)
|
||||
fg_style = fmt::fg(color_opt.value());
|
||||
}
|
||||
} else if (attr.sa_type == &VC_STYLE) {
|
||||
auto saw = string_attr_wrapper<int64_t>(&attr);
|
||||
auto saw = string_attr_wrapper<text_attrs>(&attr);
|
||||
auto style = saw.get();
|
||||
|
||||
if (style & A_REVERSE) {
|
||||
if (style.ta_attrs & A_REVERSE) {
|
||||
line_style |= fmt::emphasis::reverse;
|
||||
}
|
||||
if (style & A_BOLD) {
|
||||
if (style.ta_attrs & A_BOLD) {
|
||||
line_style |= fmt::emphasis::bold;
|
||||
}
|
||||
if (style.ta_fg_color) {
|
||||
auto color_opt = curses_color_to_terminal_color(
|
||||
style.ta_fg_color.value());
|
||||
|
||||
if (color_opt) {
|
||||
fg_style = fmt::fg(color_opt.value());
|
||||
}
|
||||
}
|
||||
if (style.ta_bg_color) {
|
||||
auto color_opt = curses_color_to_terminal_color(
|
||||
style.ta_bg_color.value());
|
||||
|
||||
if (color_opt) {
|
||||
line_style |= fmt::bg(color_opt.value());
|
||||
}
|
||||
}
|
||||
} else if (attr.sa_type == &SA_LEVEL) {
|
||||
auto level = static_cast<log_level_t>(
|
||||
attr.sa_value.get<int64_t>());
|
||||
@ -341,6 +357,7 @@ println(FILE* file, const attr_line_t& al)
|
||||
line_style |= fmt::emphasis::bold
|
||||
| fmt::fg(fmt::terminal_color::green);
|
||||
break;
|
||||
case role_t::VCR_INFO:
|
||||
case role_t::VCR_STATUS:
|
||||
line_style |= fmt::emphasis::bold
|
||||
| fmt::fg(fmt::terminal_color::magenta);
|
||||
|
@ -68,7 +68,7 @@ find_matching_bracket(
|
||||
} else if (line[lpc] == left && is_bracket(line, lpc, is_lit)) {
|
||||
if (depth == 0) {
|
||||
alb.overlay_attr_for_char(
|
||||
lpc, VC_STYLE.value(A_BOLD | A_REVERSE));
|
||||
lpc, VC_STYLE.value(text_attrs{A_BOLD | A_REVERSE}));
|
||||
alb.overlay_attr_for_char(lpc,
|
||||
VC_ROLE.value(role_t::VCR_OK));
|
||||
break;
|
||||
@ -85,7 +85,7 @@ find_matching_bracket(
|
||||
} else if (line[lpc] == right && is_bracket(line, lpc, is_lit)) {
|
||||
if (depth == 0) {
|
||||
alb.overlay_attr_for_char(
|
||||
lpc, VC_STYLE.value(A_BOLD | A_REVERSE));
|
||||
lpc, VC_STYLE.value(text_attrs{A_BOLD | A_REVERSE}));
|
||||
alb.overlay_attr_for_char(lpc,
|
||||
VC_ROLE.value(role_t::VCR_OK));
|
||||
break;
|
||||
@ -110,7 +110,8 @@ find_matching_bracket(
|
||||
depth -= 1;
|
||||
} else {
|
||||
auto lr = line_range(is_lit ? lpc - 1 : lpc, lpc + 1);
|
||||
alb.overlay_attr(lr, VC_STYLE.value(A_BOLD | A_REVERSE));
|
||||
alb.overlay_attr(
|
||||
lr, VC_STYLE.value(text_attrs{A_BOLD | A_REVERSE}));
|
||||
alb.overlay_attr(lr, VC_ROLE.value(role_t::VCR_ERROR));
|
||||
}
|
||||
}
|
||||
@ -120,7 +121,7 @@ find_matching_bracket(
|
||||
auto lr
|
||||
= line_range(is_lit ? first_left.value() - 1 : first_left.value(),
|
||||
first_left.value() + 1);
|
||||
alb.overlay_attr(lr, VC_STYLE.value(A_BOLD | A_REVERSE));
|
||||
alb.overlay_attr(lr, VC_STYLE.value(text_attrs{A_BOLD | A_REVERSE}));
|
||||
alb.overlay_attr(lr, VC_ROLE.value(role_t::VCR_ERROR));
|
||||
}
|
||||
}
|
||||
@ -189,7 +190,8 @@ regex_highlighter(attr_line_t& al, int x, line_range sub)
|
||||
|
||||
if (lpc == sub.lr_start || (lpc - sub.lr_start) == 0) {
|
||||
alb.overlay_attr_for_char(
|
||||
lpc, VC_STYLE.value(A_BOLD | A_REVERSE));
|
||||
lpc,
|
||||
VC_STYLE.value(text_attrs{A_BOLD | A_REVERSE}));
|
||||
alb.overlay_attr_for_char(
|
||||
lpc, VC_ROLE.value(role_t::VCR_ERROR));
|
||||
} else if (line[lpc - 1] == '(') {
|
||||
@ -220,10 +222,11 @@ regex_highlighter(attr_line_t& al, int x, line_range sub)
|
||||
case '>': {
|
||||
static const pcrepp CAP_RE(R"(\(\?\<\w+$)");
|
||||
|
||||
auto sf = string_fragment{
|
||||
line.c_str(), sub.lr_start, (int) lpc};
|
||||
auto capture_start = sf.find_left_boundary(
|
||||
lpc - sub.lr_start - 1, string_fragment::tag1{'('});
|
||||
auto capture_start
|
||||
= string_fragment::from_str_range(
|
||||
line, sub.lr_start, lpc)
|
||||
.find_left_boundary(lpc - sub.lr_start - 1,
|
||||
string_fragment::tag1{'('});
|
||||
pcre_context_static<30> pc;
|
||||
pcre_input pi(capture_start);
|
||||
|
||||
@ -280,8 +283,9 @@ regex_highlighter(attr_line_t& al, int x, line_range sub)
|
||||
VC_ROLE.value(role_t::VCR_SYMBOL));
|
||||
break;
|
||||
case ' ':
|
||||
alb.overlay_attr(line_range(lpc - 1, lpc + 1),
|
||||
VC_STYLE.value(A_BOLD | A_REVERSE));
|
||||
alb.overlay_attr(
|
||||
line_range(lpc - 1, lpc + 1),
|
||||
VC_STYLE.value(text_attrs{A_BOLD | A_REVERSE}));
|
||||
alb.overlay_attr(line_range(lpc - 1, lpc + 1),
|
||||
VC_ROLE.value(role_t::VCR_ERROR));
|
||||
break;
|
||||
@ -296,8 +300,9 @@ regex_highlighter(attr_line_t& al, int x, line_range sub)
|
||||
alb.overlay_attr(line_range(lpc - 1, lpc + 3),
|
||||
VC_ROLE.value(role_t::VCR_RE_SPECIAL));
|
||||
} else {
|
||||
alb.overlay_attr(line_range(lpc - 1, lpc + 1),
|
||||
VC_STYLE.value(A_BOLD | A_REVERSE));
|
||||
alb.overlay_attr(
|
||||
line_range(lpc - 1, lpc + 1),
|
||||
VC_STYLE.value(text_attrs{A_BOLD | A_REVERSE}));
|
||||
alb.overlay_attr(line_range(lpc - 1, lpc + 1),
|
||||
VC_ROLE.value(role_t::VCR_ERROR));
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ string_attr_type<int64_t> SA_LEVEL("level");
|
||||
|
||||
string_attr_type<role_t> VC_ROLE("role");
|
||||
string_attr_type<role_t> VC_ROLE_FG("role-fg");
|
||||
string_attr_type<int64_t> VC_STYLE("style");
|
||||
string_attr_type<text_attrs> VC_STYLE("style");
|
||||
string_attr_type<int64_t> VC_GRAPHIC("graphic");
|
||||
string_attr_type<int64_t> VC_FOREGROUND("foreground");
|
||||
string_attr_type<int64_t> VC_BACKGROUND("background");
|
||||
|
@ -49,6 +49,7 @@ enum class role_t : int32_t {
|
||||
VCR_IDENTIFIER,
|
||||
VCR_SEARCH, /*< A search hit. */
|
||||
VCR_OK,
|
||||
VCR_INFO,
|
||||
VCR_ERROR, /*< An error message. */
|
||||
VCR_WARNING, /*< A warning message. */
|
||||
VCR_ALT_ROW, /*< Highlight for alternating rows in a list */
|
||||
@ -127,8 +128,29 @@ enum class role_t : int32_t {
|
||||
VCR__MAX
|
||||
};
|
||||
|
||||
struct text_attrs {
|
||||
bool empty() const
|
||||
{
|
||||
return this->ta_attrs == 0 && !this->ta_fg_color && !this->ta_bg_color;
|
||||
}
|
||||
|
||||
text_attrs operator|(const text_attrs& other) const
|
||||
{
|
||||
return text_attrs{
|
||||
this->ta_attrs | other.ta_attrs,
|
||||
this->ta_fg_color ? this->ta_fg_color : other.ta_fg_color,
|
||||
this->ta_bg_color ? this->ta_bg_color : other.ta_bg_color,
|
||||
};
|
||||
}
|
||||
|
||||
int32_t ta_attrs{0};
|
||||
nonstd::optional<short> ta_fg_color;
|
||||
nonstd::optional<short> ta_bg_color;
|
||||
};
|
||||
|
||||
using string_attr_value = mapbox::util::variant<int64_t,
|
||||
role_t,
|
||||
text_attrs,
|
||||
const intern_string_t,
|
||||
std::string,
|
||||
std::shared_ptr<logfile>,
|
||||
@ -183,7 +205,7 @@ extern string_attr_type<int64_t> SA_LEVEL;
|
||||
|
||||
extern string_attr_type<role_t> VC_ROLE;
|
||||
extern string_attr_type<role_t> VC_ROLE_FG;
|
||||
extern string_attr_type<int64_t> VC_STYLE;
|
||||
extern string_attr_type<text_attrs> VC_STYLE;
|
||||
extern string_attr_type<int64_t> VC_GRAPHIC;
|
||||
extern string_attr_type<int64_t> VC_FOREGROUND;
|
||||
extern string_attr_type<int64_t> VC_BACKGROUND;
|
||||
@ -455,6 +477,13 @@ h6(S str)
|
||||
|
||||
namespace literals {
|
||||
|
||||
inline std::pair<std::string, string_attr_pair> operator"" _info(
|
||||
const char* str, std::size_t len)
|
||||
{
|
||||
return std::make_pair(std::string(str, len),
|
||||
VC_ROLE.template value(role_t::VCR_INFO));
|
||||
}
|
||||
|
||||
inline std::pair<std::string, string_attr_pair> operator"" _symbol(
|
||||
const char* str, std::size_t len)
|
||||
{
|
||||
@ -483,6 +512,13 @@ inline std::pair<std::string, string_attr_pair> operator"" _comment(
|
||||
VC_ROLE.template value(role_t::VCR_COMMENT));
|
||||
}
|
||||
|
||||
inline std::pair<std::string, string_attr_pair> operator"" _hotkey(
|
||||
const char* str, std::size_t len)
|
||||
{
|
||||
return std::make_pair(std::string(str, len),
|
||||
VC_ROLE.template value(role_t::VCR_STATUS_HOTKEY));
|
||||
}
|
||||
|
||||
inline std::pair<std::string, string_attr_pair> operator"" _h1(const char* str,
|
||||
std::size_t len)
|
||||
{
|
||||
|
@ -90,7 +90,7 @@ breadcrumb_curses::do_update()
|
||||
- crumb.c_display_value.length()),
|
||||
(int) crumbs_line.length(),
|
||||
},
|
||||
VC_STYLE.template value(A_REVERSE));
|
||||
VC_STYLE.template value(text_attrs{A_REVERSE}));
|
||||
}
|
||||
crumb_index += 1;
|
||||
crumbs_line.append("\u276d"_breadcrumb);
|
||||
@ -385,7 +385,7 @@ breadcrumb_curses::search_overlay_source::list_value_for_overlay(
|
||||
| lnav::itertools::unwrap_or(
|
||||
breadcrumb::crumb::expected_input_t::exact);
|
||||
|
||||
value_out.with_attr_for_all(VC_STYLE.value(A_UNDERLINE));
|
||||
value_out.with_attr_for_all(VC_STYLE.value(text_attrs{A_UNDERLINE}));
|
||||
|
||||
if (!parent->bc_current_search.empty()) {
|
||||
value_out = parent->bc_current_search;
|
||||
|
@ -38,7 +38,7 @@
|
||||
#include "config.h"
|
||||
#include "sql_util.hh"
|
||||
|
||||
const char* column_namer::BUILTIN_COL = "col";
|
||||
const char column_namer::BUILTIN_COL[] = "col";
|
||||
|
||||
column_namer::column_namer(language lang) : cn_language(lang) {}
|
||||
|
||||
@ -79,7 +79,7 @@ column_namer::add_column(const string_fragment& in_name)
|
||||
int num = 0;
|
||||
|
||||
if (in_name.empty()) {
|
||||
base_name = string_fragment{BUILTIN_COL};
|
||||
base_name = string_fragment::from_const(BUILTIN_COL);
|
||||
} else {
|
||||
base_name = in_name;
|
||||
}
|
||||
@ -90,7 +90,7 @@ column_namer::add_column(const string_fragment& in_name)
|
||||
num = ++counter_iter->second;
|
||||
fmt::format_to(
|
||||
std::back_inserter(buf), FMT_STRING("{}_{}"), base_name, num);
|
||||
retval = string_fragment{buf.data(), 0, (int) buf.size()};
|
||||
retval = string_fragment::from_memory_buffer(buf);
|
||||
}
|
||||
|
||||
while (this->existing_name(retval)) {
|
||||
@ -103,7 +103,7 @@ column_namer::add_column(const string_fragment& in_name)
|
||||
"column name already exists: %.*s", retval.length(), retval.data());
|
||||
fmt::format_to(
|
||||
std::back_inserter(buf), FMT_STRING("{}_{}"), base_name, num);
|
||||
retval = string_fragment{buf.data(), 0, (int) buf.size()};
|
||||
retval = string_fragment::from_memory_buffer(buf);
|
||||
num += 1;
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ public:
|
||||
|
||||
string_fragment add_column(const string_fragment& in_name);
|
||||
|
||||
static const char* BUILTIN_COL;
|
||||
static const char BUILTIN_COL[];
|
||||
|
||||
ArenaAlloc::Alloc<char> cn_alloc;
|
||||
language cn_language;
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "base/ansi_scrubber.hh"
|
||||
#include "base/fs_util.hh"
|
||||
#include "base/injector.hh"
|
||||
#include "base/itertools.hh"
|
||||
#include "base/string_util.hh"
|
||||
#include "bound_tags.hh"
|
||||
#include "config.h"
|
||||
@ -51,6 +52,8 @@
|
||||
#include "vtab_module.hh"
|
||||
#include "yajlpp/json_ptr.hh"
|
||||
|
||||
using namespace lnav::roles::literals;
|
||||
|
||||
exec_context INIT_EXEC_CONTEXT;
|
||||
|
||||
static const std::string MSG_FORMAT_STMT = R"(
|
||||
@ -123,10 +126,36 @@ sql_progress(const struct log_cursor& lc)
|
||||
}
|
||||
|
||||
if (ui_periodic_timer::singleton().time_to_update(sql_counter)) {
|
||||
struct timeval current_time = {0, 0};
|
||||
int ch;
|
||||
|
||||
while ((ch = getch()) != ERR) {
|
||||
if (current_time.tv_sec == 0) {
|
||||
gettimeofday(¤t_time, nullptr);
|
||||
}
|
||||
lnav_data.ld_user_message_source.clear();
|
||||
|
||||
alerter::singleton().new_input(ch);
|
||||
|
||||
lnav_data.ld_input_dispatcher.new_input(current_time, ch);
|
||||
|
||||
lnav_data.ld_view_stack.top() | [ch](auto tc) {
|
||||
lnav_data.ld_key_repeat_history.update(ch, tc->get_top());
|
||||
};
|
||||
|
||||
if (!lnav_data.ld_looping) {
|
||||
// No reason to keep processing input after the
|
||||
// user has quit. The view stack will also be
|
||||
// empty, which will cause issues.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lnav_data.ld_bottom_source.update_loading(off, total);
|
||||
lnav_data.ld_top_source.update_time();
|
||||
lnav_data.ld_status[LNS_TOP].do_update();
|
||||
lnav_data.ld_status[LNS_BOTTOM].do_update();
|
||||
lnav_data.ld_rl_view->do_update();
|
||||
refresh();
|
||||
}
|
||||
|
||||
@ -316,6 +345,9 @@ execute_sql(exec_context& ec, const std::string& sql, std::string& alt_msg)
|
||||
|
||||
log_info("Executing SQL: %s", sql.c_str());
|
||||
|
||||
auto old_mode = lnav_data.ld_mode;
|
||||
lnav_data.ld_mode = ln_mode_t::BUSY;
|
||||
auto mode_fin = finally([old_mode]() { lnav_data.ld_mode = old_mode; });
|
||||
lnav_data.ld_bottom_source.grep_error("");
|
||||
|
||||
if (startswith(stmt_str, ".")) {
|
||||
@ -400,7 +432,15 @@ execute_sql(exec_context& ec, const std::string& sql, std::string& alt_msg)
|
||||
|
||||
auto bound_values = TRY(bind_sql_parameters(ec, stmt.in()));
|
||||
if (lnav_data.ld_rl_view != nullptr) {
|
||||
lnav_data.ld_rl_view->set_value("Executing query: " + sql + " ...");
|
||||
if (lnav_data.ld_rl_view) {
|
||||
lnav_data.ld_rl_view->set_attr_value(
|
||||
lnav::console::user_message::info(
|
||||
attr_line_t("executing SQL statement, press ")
|
||||
.append("CTRL+]"_hotkey)
|
||||
.append(" to cancel"))
|
||||
.to_attr_line());
|
||||
lnav_data.ld_rl_view->do_update();
|
||||
}
|
||||
}
|
||||
|
||||
ec.ec_sql_callback(ec, stmt.in());
|
||||
@ -473,6 +513,8 @@ execute_sql(exec_context& ec, const std::string& sql, std::string& alt_msg)
|
||||
lnav_data.ld_views[LNV_DB].reload_data();
|
||||
lnav_data.ld_views[LNV_DB].set_left(0);
|
||||
|
||||
lnav_data.ld_active_files.fc_files
|
||||
| lnav::itertools::for_each(&logfile::dump_stats);
|
||||
if (!ec.ec_accumulator->empty()) {
|
||||
retval = ec.ec_accumulator->get_string();
|
||||
} else if (!dls.dls_rows.empty()) {
|
||||
@ -853,8 +895,8 @@ sql_callback(exec_context& ec, sqlite3_stmt* stmt)
|
||||
return 0;
|
||||
}
|
||||
|
||||
stacked_bar_chart<std::string>& chart = dls.dls_chart;
|
||||
view_colors& vc = view_colors::singleton();
|
||||
auto& chart = dls.dls_chart;
|
||||
auto& vc = view_colors::singleton();
|
||||
int ncols = sqlite3_column_count(stmt);
|
||||
int row_number;
|
||||
int lpc, retval = 0;
|
||||
@ -875,7 +917,7 @@ sql_callback(exec_context& ec, sqlite3_stmt* stmt)
|
||||
|
||||
dls.push_header(colname, type, graphable);
|
||||
if (graphable) {
|
||||
int attrs = vc.attrs_for_ident(colname);
|
||||
auto attrs = vc.attrs_for_ident(colname);
|
||||
chart.with_attrs_for_ident(colname, attrs);
|
||||
}
|
||||
}
|
||||
@ -898,11 +940,9 @@ sql_callback(exec_context& ec, sqlite3_stmt* stmt)
|
||||
value = null_value_t{};
|
||||
break;
|
||||
default:
|
||||
value = string_fragment{
|
||||
value = string_fragment::from_bytes(
|
||||
sqlite3_value_text(raw_value),
|
||||
0,
|
||||
sqlite3_value_bytes(raw_value),
|
||||
};
|
||||
sqlite3_value_bytes(raw_value));
|
||||
break;
|
||||
}
|
||||
dls.push_column(value);
|
||||
|
@ -37,7 +37,7 @@
|
||||
#include "config.h"
|
||||
#include "yajlpp/json_ptr.hh"
|
||||
|
||||
const char* db_label_source::NULL_STR = "<NULL>";
|
||||
const char db_label_source::NULL_STR[] = "<NULL>";
|
||||
|
||||
constexpr size_t MAX_COLUMN_WIDTH = 120;
|
||||
constexpr size_t MAX_JSON_WIDTH = 16 * 1024;
|
||||
@ -93,7 +93,7 @@ db_label_source::text_attrs_for_line(textview_curses& tc,
|
||||
}
|
||||
for (size_t lpc = 0; lpc < this->dls_headers.size() - 1; lpc++) {
|
||||
if (row % 2 == 0) {
|
||||
sa.emplace_back(lr2, VC_STYLE.value(A_BOLD));
|
||||
sa.emplace_back(lr2, VC_STYLE.value(text_attrs{A_BOLD}));
|
||||
}
|
||||
lr.lr_start += this->dls_cell_width[lpc];
|
||||
lr.lr_end = lr.lr_start + 1;
|
||||
@ -166,7 +166,7 @@ db_label_source::push_column(const scoped_value_t& sv)
|
||||
double num_value = 0.0;
|
||||
|
||||
auto col_sf = sv.match(
|
||||
[](const std::string& str) { return string_fragment{str}; },
|
||||
[](const std::string& str) { return string_fragment::from_str(str); },
|
||||
[this](const string_fragment& sf) {
|
||||
return sf.to_owned(*this->dls_allocator);
|
||||
},
|
||||
@ -174,17 +174,17 @@ db_label_source::push_column(const scoped_value_t& sv)
|
||||
fmt::memory_buffer buf;
|
||||
|
||||
fmt::format_to(std::back_inserter(buf), FMT_STRING("{}"), i);
|
||||
return string_fragment{buf.data(), 0, (int) buf.size()}.to_owned(
|
||||
return string_fragment::from_memory_buffer(buf).to_owned(
|
||||
*this->dls_allocator);
|
||||
},
|
||||
[this](double d) {
|
||||
fmt::memory_buffer buf;
|
||||
|
||||
fmt::format_to(std::back_inserter(buf), FMT_STRING("{}"), d);
|
||||
return string_fragment{buf.data(), 0, (int) buf.size()}.to_owned(
|
||||
return string_fragment::from_memory_buffer(buf).to_owned(
|
||||
*this->dls_allocator);
|
||||
},
|
||||
[](null_value_t) { return string_fragment{NULL_STR}; });
|
||||
[](null_value_t) { return string_fragment::from_const(NULL_STR); });
|
||||
|
||||
if (index == this->dls_time_column_index) {
|
||||
date_time_scanner dts;
|
||||
@ -332,7 +332,7 @@ db_overlay_source::list_overlay_count(const listview_curses& lv)
|
||||
sa.emplace_back(lr, VC_GRAPHIC.value(ACS_LTEE));
|
||||
lr.lr_start = 3 + jpw_value.wt_ptr.size() + 3;
|
||||
lr.lr_end = -1;
|
||||
sa.emplace_back(lr, VC_STYLE.value(A_BOLD));
|
||||
sa.emplace_back(lr, VC_STYLE.value(text_attrs{A_BOLD}));
|
||||
|
||||
double num_value = 0.0;
|
||||
|
||||
@ -340,7 +340,7 @@ db_overlay_source::list_overlay_count(const listview_curses& lv)
|
||||
&& sscanf(jpw_value.wt_value.c_str(), "%lf", &num_value)
|
||||
== 1)
|
||||
{
|
||||
int attrs = vc.attrs_for_ident(jpw_value.wt_ptr);
|
||||
auto attrs = vc.attrs_for_ident(jpw_value.wt_ptr);
|
||||
|
||||
chart.add_value(jpw_value.wt_ptr, num_value);
|
||||
chart.with_attrs_for_ident(jpw_value.wt_ptr, attrs);
|
||||
@ -423,17 +423,19 @@ db_overlay_source::list_value_for_overlay(const listview_curses& lv,
|
||||
|
||||
struct line_range header_range(line_len_before, line.length());
|
||||
|
||||
int attrs
|
||||
= vc.attrs_for_ident(dls->dls_headers[lpc].hm_name) | A_REVERSE;
|
||||
if (!this->dos_labels->dls_headers[lpc].hm_graphable) {
|
||||
attrs = A_UNDERLINE;
|
||||
text_attrs attrs;
|
||||
if (this->dos_labels->dls_headers[lpc].hm_graphable) {
|
||||
attrs = vc.attrs_for_ident(dls->dls_headers[lpc].hm_name)
|
||||
| text_attrs{A_REVERSE};
|
||||
} else {
|
||||
attrs.ta_attrs = A_UNDERLINE;
|
||||
}
|
||||
sa.emplace_back(header_range, VC_STYLE.value(attrs));
|
||||
sa.emplace_back(header_range, VC_STYLE.value(text_attrs{attrs}));
|
||||
}
|
||||
|
||||
struct line_range lr(0);
|
||||
|
||||
sa.emplace_back(lr, VC_STYLE.value(A_BOLD | A_UNDERLINE));
|
||||
sa.emplace_back(lr, VC_STYLE.value(text_attrs{A_BOLD | A_UNDERLINE}));
|
||||
return true;
|
||||
} else if (this->dos_active && y >= 2
|
||||
&& ((size_t) y) < (this->dos_lines.size() + 2))
|
||||
|
@ -123,7 +123,7 @@ public:
|
||||
std::unique_ptr<ArenaAlloc::Alloc<char>> dls_allocator{
|
||||
std::make_unique<ArenaAlloc::Alloc<char>>(64 * 1024)};
|
||||
|
||||
static const char* NULL_STR;
|
||||
static const char NULL_STR[];
|
||||
};
|
||||
|
||||
class db_overlay_source : public list_overlay_source {
|
||||
|
@ -131,7 +131,7 @@ field_overlay_source::build_field_lines(const listview_curses& lv)
|
||||
time_str.append(curr_timestamp);
|
||||
time_lr.lr_end = time_str.length();
|
||||
time_line.with_attr(
|
||||
string_attr(time_lr, VC_STYLE.value(A_BOLD)));
|
||||
string_attr(time_lr, VC_STYLE.value(text_attrs{A_BOLD})));
|
||||
time_str.append(" -- ");
|
||||
time_lr.lr_start = time_str.length();
|
||||
time_str.append(humanize::time::point::from_tv(ll->get_timeval())
|
||||
@ -139,7 +139,7 @@ field_overlay_source::build_field_lines(const listview_curses& lv)
|
||||
.as_precise_time_ago());
|
||||
time_lr.lr_end = time_str.length();
|
||||
time_line.with_attr(
|
||||
string_attr(time_lr, VC_STYLE.value(A_BOLD)));
|
||||
string_attr(time_lr, VC_STYLE.value(text_attrs{A_BOLD})));
|
||||
|
||||
struct line_range time_range = find_string_attr_range(
|
||||
this->fos_log_helper.ldh_line_attrs, &logline::L_TIMESTAMP);
|
||||
@ -181,7 +181,7 @@ field_overlay_source::build_field_lines(const listview_curses& lv)
|
||||
humanize::time::duration::from_tv(diff_tv).to_string());
|
||||
time_lr.lr_end = time_str.length();
|
||||
time_line.with_attr(
|
||||
string_attr(time_lr, VC_STYLE.value(A_BOLD)));
|
||||
string_attr(time_lr, VC_STYLE.value(text_attrs{A_BOLD})));
|
||||
}
|
||||
}
|
||||
|
||||
@ -282,10 +282,10 @@ field_overlay_source::build_field_lines(const listview_curses& lv)
|
||||
if (curr_format != last_format) {
|
||||
this->fos_lines.emplace_back(" Known message fields for table "
|
||||
+ format_name + ":");
|
||||
this->fos_lines.back().with_attr(string_attr(
|
||||
line_range(32, 32 + format_name.length()),
|
||||
VC_STYLE.value(vc.attrs_for_ident(format_name)
|
||||
| A_BOLD)));
|
||||
this->fos_lines.back().with_attr(
|
||||
string_attr(line_range(32, 32 + format_name.length()),
|
||||
VC_STYLE.value(vc.attrs_for_ident(format_name)
|
||||
| text_attrs{A_BOLD})));
|
||||
last_format = curr_format;
|
||||
}
|
||||
|
||||
@ -344,8 +344,8 @@ field_overlay_source::build_field_lines(const listview_curses& lv)
|
||||
- 9 + 3,
|
||||
' ')
|
||||
.append(" = ")
|
||||
.append(string_fragment{
|
||||
(const char*) js.js_content.in(), 0, (int) js.js_len});
|
||||
.append(
|
||||
string_fragment::from_bytes(js.js_content.in(), js.js_len));
|
||||
this->fos_lines.emplace_back(al);
|
||||
this->add_key_line_attrs(this->fos_known_key_size);
|
||||
}
|
||||
@ -406,7 +406,7 @@ field_overlay_source::build_field_lines(const listview_curses& lv)
|
||||
auto& disc_str = al.get_string();
|
||||
|
||||
al.with_attr(string_attr(line_range(disc_str.length(), -1),
|
||||
VC_STYLE.value(A_BOLD)));
|
||||
VC_STYLE.value(text_attrs{A_BOLD})));
|
||||
disc_str.append(this->fos_log_helper.ldh_msg_format);
|
||||
}
|
||||
|
||||
@ -488,7 +488,7 @@ field_overlay_source::add_key_line_attrs(int key_size, bool last_line)
|
||||
|
||||
lr.lr_start = 3 + key_size + 3;
|
||||
lr.lr_end = -1;
|
||||
sa.emplace_back(lr, VC_STYLE.value(A_BOLD));
|
||||
sa.emplace_back(lr, VC_STYLE.value(text_attrs{A_BOLD}));
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -334,7 +334,7 @@ files_sub_source::text_attrs_for_line(textview_curses& tc,
|
||||
}
|
||||
if (line == fc.fc_other_files.size() - 1) {
|
||||
value_out.emplace_back(line_range{0, -1},
|
||||
VC_STYLE.value(A_UNDERLINE));
|
||||
VC_STYLE.value(text_attrs{A_UNDERLINE}));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -366,7 +366,7 @@ files_sub_source::text_attrs_for_line(textview_curses& tc,
|
||||
(int) filename_width + 3 + 4,
|
||||
(int) filename_width + 3 + 10,
|
||||
};
|
||||
value_out.emplace_back(lr, VC_STYLE.value(A_BOLD));
|
||||
value_out.emplace_back(lr, VC_STYLE.value(text_attrs{A_BOLD}));
|
||||
|
||||
lr.lr_start = this->fss_last_line_len;
|
||||
lr.lr_end = -1;
|
||||
|
@ -210,10 +210,9 @@ filter_status_source::update_filtered(text_sub_source* tss)
|
||||
|
||||
if (tss->get_filtered_count() == this->bss_last_filtered_count) {
|
||||
if (timer.fade_diff(this->bss_filter_counter) == 0) {
|
||||
this->tss_fields[TSF_FILTERED].set_role(
|
||||
role_t::VCR_STATUS);
|
||||
this->tss_fields[TSF_FILTERED].set_role(role_t::VCR_STATUS);
|
||||
al.with_attr(string_attr(line_range{0, -1},
|
||||
VC_STYLE.value(A_BOLD)));
|
||||
VC_STYLE.value(text_attrs{A_BOLD})));
|
||||
}
|
||||
} else {
|
||||
this->tss_fields[TSF_FILTERED].set_role(
|
||||
|
@ -298,9 +298,9 @@ filter_sub_source::text_value_for_line(textview_curses& tc,
|
||||
std::string& value_out,
|
||||
text_sub_source::line_flags_t flags)
|
||||
{
|
||||
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* top_view = *lnav_data.ld_view_stack.top();
|
||||
auto* tss = top_view->get_sub_source();
|
||||
auto& fs = tss->get_filters();
|
||||
auto tf = *(fs.begin() + line);
|
||||
|
||||
value_out = " ";
|
||||
@ -357,19 +357,21 @@ filter_sub_source::text_attrs_for_line(textview_curses& tc,
|
||||
value_out.emplace_back(lr, VC_FOREGROUND.value(COLOR_GREEN));
|
||||
}
|
||||
|
||||
role_t fg_role = tf->get_type() == text_filter::INCLUDE ? role_t::VCR_OK
|
||||
: role_t::VCR_ERROR;
|
||||
value_out.emplace_back(line_range{4, 7}, VC_ROLE.value(fg_role));
|
||||
value_out.emplace_back(line_range{4, 7}, VC_STYLE.value(A_BOLD));
|
||||
|
||||
value_out.emplace_back(line_range{8, 17}, VC_STYLE.value(A_BOLD));
|
||||
value_out.emplace_back(line_range{23, 24}, VC_GRAPHIC.value(ACS_VLINE));
|
||||
|
||||
if (selected) {
|
||||
value_out.emplace_back(line_range{0, -1},
|
||||
VC_ROLE.value(role_t::VCR_FOCUSED));
|
||||
}
|
||||
|
||||
role_t fg_role = tf->get_type() == text_filter::INCLUDE ? role_t::VCR_OK
|
||||
: role_t::VCR_ERROR;
|
||||
value_out.emplace_back(line_range{4, 7}, VC_ROLE.value(fg_role));
|
||||
value_out.emplace_back(line_range{4, 7},
|
||||
VC_STYLE.value(text_attrs{A_BOLD}));
|
||||
|
||||
value_out.emplace_back(line_range{8, 17},
|
||||
VC_STYLE.value(text_attrs{A_BOLD}));
|
||||
value_out.emplace_back(line_range{23, 24}, VC_GRAPHIC.value(ACS_VLINE));
|
||||
|
||||
attr_line_t content{tf->get_id()};
|
||||
auto& content_attrs = content.get_attrs();
|
||||
|
||||
@ -436,15 +438,11 @@ filter_sub_source::rl_change(readline_curses* rc)
|
||||
} else {
|
||||
auto& hm = top_view->get_highlights();
|
||||
highlighter hl(code.release());
|
||||
int color;
|
||||
|
||||
if (tf->get_type() == text_filter::EXCLUDE) {
|
||||
color = COLOR_RED;
|
||||
} else {
|
||||
color = COLOR_GREEN;
|
||||
}
|
||||
hl.with_attrs(view_colors::ansi_color_pair(COLOR_BLACK, color)
|
||||
| A_BLINK);
|
||||
auto role = tf->get_type() == text_filter::EXCLUDE
|
||||
? role_t::VCR_DIFF_DELETE
|
||||
: role_t::VCR_DIFF_ADD;
|
||||
hl.with_role(role);
|
||||
hl.with_attrs(text_attrs{A_BLINK | A_REVERSE});
|
||||
|
||||
hm[{highlight_source_t::PREVIEW, "preview"}] = hl;
|
||||
top_view->set_needs_update();
|
||||
@ -616,7 +614,7 @@ filter_sub_source::rl_display_matches(readline_curses* rc)
|
||||
|
||||
for (const auto& match : matches) {
|
||||
if (match == current_match) {
|
||||
al.append(match, VC_STYLE.value(A_REVERSE));
|
||||
al.append(match, VC_STYLE.value(text_attrs{A_REVERSE}));
|
||||
selected_line = line;
|
||||
} else {
|
||||
al.append(match);
|
||||
|
@ -21,26 +21,23 @@
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @file logfmt.parser.cc
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "base/string_util.hh"
|
||||
#include "logfmt.parser.hh"
|
||||
|
||||
logfmt::parser::parser(string_fragment sf)
|
||||
: p_next_input(sf)
|
||||
{
|
||||
#include "base/string_util.hh"
|
||||
#include "config.h"
|
||||
|
||||
}
|
||||
logfmt::parser::parser(string_fragment sf) : p_next_input(sf) {}
|
||||
|
||||
static bool is_not_eq(char ch)
|
||||
static bool
|
||||
is_not_eq(char ch)
|
||||
{
|
||||
return ch != '=';
|
||||
}
|
||||
@ -68,11 +65,13 @@ struct bare_value_predicate {
|
||||
float_state_t bvp_float_state{float_state_t::INIT};
|
||||
size_t bvp_index{0};
|
||||
|
||||
bool is_integer() const {
|
||||
bool is_integer() const
|
||||
{
|
||||
return this->bvp_int_state == int_state_t::DIGITS;
|
||||
}
|
||||
|
||||
bool is_float() const {
|
||||
bool is_float() const
|
||||
{
|
||||
switch (this->bvp_float_state) {
|
||||
case float_state_t::DIGITS:
|
||||
case float_state_t::FRACTION_DIGIT:
|
||||
@ -83,7 +82,8 @@ struct bare_value_predicate {
|
||||
}
|
||||
}
|
||||
|
||||
bool operator()(char ch) {
|
||||
bool operator()(char ch)
|
||||
{
|
||||
if (ch == ' ') {
|
||||
return false;
|
||||
}
|
||||
@ -169,7 +169,8 @@ struct bare_value_predicate {
|
||||
}
|
||||
};
|
||||
|
||||
logfmt::parser::step_result logfmt::parser::step()
|
||||
logfmt::parser::step_result
|
||||
logfmt::parser::step()
|
||||
{
|
||||
const static auto IS_DQ = string_fragment::tag1{'"'};
|
||||
|
||||
@ -209,48 +210,52 @@ logfmt::parser::step_result logfmt::parser::step()
|
||||
}
|
||||
|
||||
this->p_next_input = after_quote.value();
|
||||
return std::make_pair(key_frag, quoted_value{string_fragment{
|
||||
quoted_pair->first.sf_string,
|
||||
quoted_pair->first.sf_begin - 1,
|
||||
quoted_pair->first.sf_end + 1
|
||||
}});
|
||||
} else {
|
||||
bare_value_predicate bvp;
|
||||
auto value_pair = value_start.split_while(bvp);
|
||||
return std::make_pair(
|
||||
key_frag,
|
||||
quoted_value{string_fragment{quoted_pair->first.sf_string,
|
||||
quoted_pair->first.sf_begin - 1,
|
||||
quoted_pair->first.sf_end + 1}});
|
||||
}
|
||||
|
||||
if (value_pair) {
|
||||
static const auto TRUE_FRAG = string_fragment{"true"};
|
||||
static const auto FALSE_FRAG = string_fragment{"false"};
|
||||
bare_value_predicate bvp;
|
||||
auto value_pair = value_start.split_while(bvp);
|
||||
|
||||
this->p_next_input = value_pair->second;
|
||||
if (bvp.is_integer()) {
|
||||
int_value retval;
|
||||
if (value_pair) {
|
||||
static const auto TRUE_FRAG = string_fragment::from_const("true");
|
||||
static const auto FALSE_FRAG = string_fragment::from_const("false");
|
||||
|
||||
strtonum(retval.iv_value,
|
||||
value_pair->first.data(),
|
||||
value_pair->first.length());
|
||||
retval.iv_str_value = value_pair->first;
|
||||
this->p_next_input = value_pair->second;
|
||||
if (bvp.is_integer()) {
|
||||
int_value retval;
|
||||
|
||||
return std::make_pair(key_frag, retval);
|
||||
} else if (bvp.is_float()) {
|
||||
char float_copy[value_pair->first.length() + 1];
|
||||
float_value retval;
|
||||
strtonum(retval.iv_value,
|
||||
value_pair->first.data(),
|
||||
value_pair->first.length());
|
||||
retval.iv_str_value = value_pair->first;
|
||||
|
||||
strncpy(float_copy, value_pair->first.data(), value_pair->first.length());
|
||||
float_copy[value_pair->first.length()] = '\0';
|
||||
retval.fv_value = strtod(float_copy, nullptr);
|
||||
retval.fv_str_value = value_pair->first;
|
||||
return std::make_pair(key_frag, retval);
|
||||
} else if (bvp.is_float()) {
|
||||
char float_copy[value_pair->first.length() + 1];
|
||||
float_value retval;
|
||||
|
||||
return std::make_pair(key_frag, retval);
|
||||
} else if (value_pair->first.iequal(TRUE_FRAG)) {
|
||||
return std::make_pair(key_frag, bool_value{true, value_pair->first});
|
||||
} else if (value_pair->first.iequal(FALSE_FRAG)) {
|
||||
return std::make_pair(key_frag, bool_value{false, value_pair->first});
|
||||
}
|
||||
return std::make_pair(key_frag, unquoted_value{value_pair->first});
|
||||
} else {
|
||||
this->p_next_input = value_start;
|
||||
return std::make_pair(key_frag, unquoted_value{string_fragment{""}});
|
||||
strncpy(float_copy,
|
||||
value_pair->first.data(),
|
||||
value_pair->first.length());
|
||||
float_copy[value_pair->first.length()] = '\0';
|
||||
retval.fv_value = strtod(float_copy, nullptr);
|
||||
retval.fv_str_value = value_pair->first;
|
||||
|
||||
return std::make_pair(key_frag, retval);
|
||||
} else if (value_pair->first.iequal(TRUE_FRAG)) {
|
||||
return std::make_pair(key_frag,
|
||||
bool_value{true, value_pair->first});
|
||||
} else if (value_pair->first.iequal(FALSE_FRAG)) {
|
||||
return std::make_pair(key_frag,
|
||||
bool_value{false, value_pair->first});
|
||||
}
|
||||
return std::make_pair(key_frag, unquoted_value{value_pair->first});
|
||||
} else {
|
||||
this->p_next_input = value_start;
|
||||
return std::make_pair(key_frag, unquoted_value{string_fragment{}});
|
||||
}
|
||||
}
|
||||
|
@ -135,27 +135,25 @@ highlighter::annotate(attr_line_t& al, int start) const
|
||||
sa, &VC_STYLE, lr)
|
||||
== sa.end()))
|
||||
{
|
||||
int attrs = 0;
|
||||
|
||||
if (this->h_attrs != -1) {
|
||||
attrs = this->h_attrs;
|
||||
}
|
||||
if (!this->h_fg.empty()) {
|
||||
sa.emplace_back(lr,
|
||||
VC_FOREGROUND.value(
|
||||
vc.match_color(this->h_fg)));
|
||||
sa.emplace_back(
|
||||
lr,
|
||||
VC_FOREGROUND.value(
|
||||
vc.match_color(this->h_fg)
|
||||
.value_or(view_colors::MATCH_COLOR_DEFAULT)));
|
||||
}
|
||||
if (!this->h_bg.empty()) {
|
||||
sa.emplace_back(lr,
|
||||
VC_BACKGROUND.value(
|
||||
vc.match_color(this->h_bg)));
|
||||
sa.emplace_back(
|
||||
lr,
|
||||
VC_BACKGROUND.value(
|
||||
vc.match_color(this->h_bg)
|
||||
.value_or(view_colors::MATCH_COLOR_DEFAULT)));
|
||||
}
|
||||
if (this->h_role != role_t::VCR_NONE) {
|
||||
sa.emplace_back(lr,
|
||||
VC_ROLE.value(this->h_role));
|
||||
sa.emplace_back(lr, VC_ROLE.value(this->h_role));
|
||||
}
|
||||
if (attrs) {
|
||||
sa.emplace_back(lr, VC_STYLE.value(attrs));
|
||||
if (!this->h_attrs.empty()) {
|
||||
sa.emplace_back(lr, VC_STYLE.value(this->h_attrs));
|
||||
}
|
||||
|
||||
off = matches[1];
|
||||
|
@ -40,7 +40,7 @@
|
||||
#include "view_curses.hh"
|
||||
|
||||
struct highlighter {
|
||||
highlighter() : h_code(nullptr), h_code_extra(nullptr){};
|
||||
highlighter() : h_code(nullptr), h_code_extra(nullptr) {}
|
||||
|
||||
explicit highlighter(pcre* code) : h_code(code)
|
||||
{
|
||||
@ -77,7 +77,7 @@ struct highlighter {
|
||||
return *this;
|
||||
}
|
||||
|
||||
highlighter& with_attrs(int attrs)
|
||||
highlighter& with_attrs(text_attrs attrs)
|
||||
{
|
||||
this->h_attrs = attrs;
|
||||
|
||||
@ -113,12 +113,7 @@ struct highlighter {
|
||||
return *this;
|
||||
}
|
||||
|
||||
int get_attrs() const
|
||||
{
|
||||
ensure(this->h_attrs != -1);
|
||||
|
||||
return this->h_attrs;
|
||||
}
|
||||
text_attrs get_attrs() const { return this->h_attrs; }
|
||||
|
||||
void annotate(attr_line_t& al, int start) const;
|
||||
|
||||
@ -128,7 +123,7 @@ struct highlighter {
|
||||
styling::color_unit h_bg{styling::color_unit::make_empty()};
|
||||
pcre* h_code;
|
||||
pcre_extra* h_code_extra;
|
||||
int h_attrs{-1};
|
||||
text_attrs h_attrs;
|
||||
std::set<text_format_t> h_text_formats;
|
||||
intern_string_t h_format_name;
|
||||
bool h_nestable{true};
|
||||
|
@ -80,9 +80,9 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
stacked_bar_chart& with_attrs_for_ident(const T& ident, int attrs)
|
||||
stacked_bar_chart& with_attrs_for_ident(const T& ident, text_attrs attrs)
|
||||
{
|
||||
struct chart_ident& ci = this->find_ident(ident);
|
||||
auto& ci = this->find_ident(ident);
|
||||
ci.ci_attrs = attrs;
|
||||
return *this;
|
||||
}
|
||||
@ -221,8 +221,10 @@ public:
|
||||
}
|
||||
lr.lr_end = left = lr.lr_start + amount;
|
||||
|
||||
if (ci.ci_attrs != 0 && !lr.empty()) {
|
||||
value_out.emplace_back(lr, VC_STYLE.value(ci.ci_attrs | A_REVERSE));
|
||||
if (!ci.ci_attrs.empty() && !lr.empty()) {
|
||||
auto rev_attrs = ci.ci_attrs;
|
||||
rev_attrs.ta_attrs |= A_REVERSE;
|
||||
value_out.emplace_back(lr, VC_STYLE.value(rev_attrs));
|
||||
}
|
||||
}
|
||||
|
||||
@ -283,7 +285,7 @@ protected:
|
||||
explicit chart_ident(const T& ident) : ci_ident(ident) {}
|
||||
|
||||
T ci_ident;
|
||||
int ci_attrs{0};
|
||||
text_attrs ci_attrs;
|
||||
bucket_stats_t ci_stats;
|
||||
};
|
||||
|
||||
|
@ -122,12 +122,27 @@ key_sql_callback(exec_context& ec, sqlite3_stmt* stmt)
|
||||
if (sql_ident_needs_quote(column_name)) {
|
||||
continue;
|
||||
}
|
||||
if (sqlite3_column_type(stmt, lpc) == SQLITE_NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
vars[column_name]
|
||||
= std::string((const char*) sqlite3_column_text(stmt, lpc));
|
||||
auto* raw_value = sqlite3_column_value(stmt, lpc);
|
||||
auto value_type = sqlite3_column_type(stmt, lpc);
|
||||
scoped_value_t value;
|
||||
switch (value_type) {
|
||||
case SQLITE_INTEGER:
|
||||
value = (int64_t) sqlite3_value_int64(raw_value);
|
||||
break;
|
||||
case SQLITE_FLOAT:
|
||||
value = sqlite3_value_double(raw_value);
|
||||
break;
|
||||
case SQLITE_NULL:
|
||||
value = null_value_t{};
|
||||
break;
|
||||
default:
|
||||
value = string_fragment::from_bytes(
|
||||
sqlite3_value_text(raw_value),
|
||||
sqlite3_value_bytes(raw_value));
|
||||
break;
|
||||
}
|
||||
vars[column_name] = value;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -75,7 +75,7 @@ struct contains_userdata {
|
||||
static int
|
||||
contains_string(void* ctx, const unsigned char* str, size_t len)
|
||||
{
|
||||
auto sf = string_fragment{(const char*) str, 0, (int) len};
|
||||
auto sf = string_fragment::from_bytes(str, len);
|
||||
auto& cu = *((contains_userdata*) ctx);
|
||||
|
||||
if (cu.cu_depth <= 1 && cu.cu_match_value.get<string_fragment>() == sf) {
|
||||
@ -156,11 +156,8 @@ json_contains(vtab_types::nullable<const char> nullable_json_in,
|
||||
switch (sqlite3_value_type(value)) {
|
||||
case SQLITE3_TEXT:
|
||||
cb.yajl_string = contains_string;
|
||||
cu.cu_match_value = string_fragment{
|
||||
(const char*) sqlite3_value_text(value),
|
||||
0,
|
||||
sqlite3_value_bytes(value),
|
||||
};
|
||||
cu.cu_match_value = string_fragment::from_bytes(
|
||||
sqlite3_value_text(value), sqlite3_value_bytes(value));
|
||||
break;
|
||||
case SQLITE_INTEGER:
|
||||
cb.yajl_integer = contains_integer;
|
||||
|
@ -88,15 +88,9 @@ class lock_hack {
|
||||
public:
|
||||
class guard {
|
||||
public:
|
||||
guard() : g_lock(lock_hack::singleton())
|
||||
{
|
||||
this->g_lock.lock();
|
||||
};
|
||||
guard() : g_lock(lock_hack::singleton()) { this->g_lock.lock(); }
|
||||
|
||||
~guard()
|
||||
{
|
||||
this->g_lock.unlock();
|
||||
};
|
||||
~guard() { this->g_lock.unlock(); }
|
||||
|
||||
private:
|
||||
lock_hack& g_lock;
|
||||
@ -107,17 +101,11 @@ public:
|
||||
static lock_hack retval;
|
||||
|
||||
return retval;
|
||||
};
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
lockf(this->lh_fd, F_LOCK, 0);
|
||||
};
|
||||
void lock() { lockf(this->lh_fd, F_LOCK, 0); }
|
||||
|
||||
void unlock()
|
||||
{
|
||||
lockf(this->lh_fd, F_ULOCK, 0);
|
||||
};
|
||||
void unlock() { lockf(this->lh_fd, F_ULOCK, 0); }
|
||||
|
||||
private:
|
||||
lock_hack()
|
||||
@ -128,7 +116,7 @@ private:
|
||||
this->lh_fd = open(lockname, O_CREAT | O_RDWR, 0600);
|
||||
log_perror(fcntl(this->lh_fd, F_SETFD, FD_CLOEXEC));
|
||||
unlink(lockname);
|
||||
};
|
||||
}
|
||||
|
||||
auto_fd lh_fd;
|
||||
};
|
||||
@ -649,8 +637,11 @@ line_buffer::load_next_buffer()
|
||||
|
||||
auto before = line_start - this->lb_alt_buffer->begin();
|
||||
auto remaining = this->lb_alt_buffer.value().size() - before;
|
||||
auto utf8_end = is_utf8(
|
||||
(unsigned char*) line_start, remaining, &msg, &faulty_bytes);
|
||||
auto utf8_end = is_utf8((unsigned char*) line_start,
|
||||
remaining,
|
||||
&msg,
|
||||
&faulty_bytes,
|
||||
'\n');
|
||||
if (msg != nullptr) {
|
||||
lf = (char*) memchr(line_start, '\n', remaining);
|
||||
utf8_end = lf - line_start;
|
||||
@ -722,6 +713,7 @@ line_buffer::fill_range(file_off_t start, ssize_t max_length)
|
||||
this->lb_alt_line_starts.clear();
|
||||
this->lb_line_is_utf = std::move(this->lb_alt_line_is_utf);
|
||||
this->lb_alt_line_is_utf.clear();
|
||||
this->lb_stats.s_used_preloads += 1;
|
||||
}
|
||||
if (this->in_range(start) && this->in_range(start + max_length - 1)) {
|
||||
/* Cache already has the data, nothing to do. */
|
||||
@ -755,6 +747,7 @@ line_buffer::fill_range(file_off_t start, ssize_t max_length)
|
||||
#endif
|
||||
auto prom = std::make_shared<std::promise<bool>>();
|
||||
this->lb_loader_future = prom->get_future();
|
||||
this->lb_stats.s_requested_preloads += 1;
|
||||
isc::to<io_looper&, io_looper_tag>().send(
|
||||
[this, prom](auto& ioloop) mutable {
|
||||
prom->set_value(this->load_next_buffer());
|
||||
@ -777,6 +770,12 @@ line_buffer::fill_range(file_off_t start, ssize_t max_length)
|
||||
{
|
||||
rc = 0;
|
||||
} else {
|
||||
this->lb_stats.s_decompressions += 1;
|
||||
if (this->lb_last_line_offset > 0) {
|
||||
this->lb_stats.s_hist[(this->lb_file_offset * 10)
|
||||
/ this->lb_last_line_offset]
|
||||
+= 1;
|
||||
}
|
||||
rc = gi->read(this->lb_buffer.end(),
|
||||
this->lb_file_offset + this->lb_buffer.size(),
|
||||
this->lb_buffer.available());
|
||||
@ -852,6 +851,17 @@ line_buffer::fill_range(file_off_t start, ssize_t max_length)
|
||||
#endif
|
||||
else if (this->lb_seekable)
|
||||
{
|
||||
this->lb_stats.s_preads += 1;
|
||||
if (this->lb_last_line_offset > 0) {
|
||||
this->lb_stats.s_hist[(this->lb_file_offset * 10)
|
||||
/ this->lb_last_line_offset]
|
||||
+= 1;
|
||||
}
|
||||
#if 0
|
||||
log_debug("%d: pread %lld",
|
||||
this->lb_fd.get(),
|
||||
this->lb_file_offset + this->lb_buffer.size());
|
||||
#endif
|
||||
rc = pread(this->lb_fd,
|
||||
this->lb_buffer.end(),
|
||||
this->lb_buffer.available(),
|
||||
@ -943,6 +953,7 @@ line_buffer::fill_range(file_off_t start, ssize_t max_length)
|
||||
#endif
|
||||
auto prom = std::make_shared<std::promise<bool>>();
|
||||
this->lb_loader_future = prom->get_future();
|
||||
this->lb_stats.s_requested_preloads += 1;
|
||||
isc::to<io_looper&, io_looper_tag>().send(
|
||||
[this, prom](auto& ioloop) mutable {
|
||||
prom->set_value(this->load_next_buffer());
|
||||
@ -1018,7 +1029,8 @@ line_buffer::load_next_line(file_range prev_line)
|
||||
utf8_end = is_utf8((unsigned char*) line_start,
|
||||
retval.li_file_range.fr_size,
|
||||
&msg,
|
||||
&faulty_bytes);
|
||||
&faulty_bytes,
|
||||
'\n');
|
||||
if (msg != nullptr) {
|
||||
lf = (char*) memchr(
|
||||
line_start, '\n', retval.li_file_range.fr_size);
|
||||
|
@ -32,6 +32,7 @@
|
||||
#ifndef line_buffer_hh
|
||||
#define line_buffer_hh
|
||||
|
||||
#include <array>
|
||||
#include <exception>
|
||||
#include <future>
|
||||
#include <vector>
|
||||
@ -243,6 +244,31 @@ public:
|
||||
|
||||
void quiesce();
|
||||
|
||||
struct stats {
|
||||
bool empty() const
|
||||
{
|
||||
return this->s_decompressions == 0 && this->s_preads == 0
|
||||
&& this->s_requested_preloads == 0
|
||||
&& this->s_used_preloads == 0;
|
||||
}
|
||||
|
||||
uint32_t s_decompressions{0};
|
||||
uint32_t s_preads{0};
|
||||
uint32_t s_requested_preloads{0};
|
||||
uint32_t s_used_preloads{0};
|
||||
std::array<uint32_t, 10> s_hist{};
|
||||
};
|
||||
|
||||
struct stats consume_stats()
|
||||
{
|
||||
return std::exchange(this->lb_stats, {});
|
||||
}
|
||||
|
||||
size_t get_buffer_size() const
|
||||
{
|
||||
return this->lb_buffer.size();
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* @param off The file offset to check for in the buffer.
|
||||
@ -340,6 +366,7 @@ private:
|
||||
|
||||
std::vector<uint32_t> lb_line_starts;
|
||||
std::vector<bool> lb_line_is_utf;
|
||||
stats lb_stats;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -197,7 +197,7 @@ listview_curses::do_update()
|
||||
struct line_range lr;
|
||||
unsigned long width, wrap_width;
|
||||
int y = this->lv_y, bottom;
|
||||
attr_t role_attrs = vc.attrs_for_role(this->vc_default_role);
|
||||
auto role_attrs = vc.attrs_for_role(this->vc_default_role);
|
||||
|
||||
this->get_dimensions(height, width);
|
||||
|
||||
@ -254,9 +254,12 @@ listview_curses::do_update()
|
||||
&& lr.lr_start < (int) al.length());
|
||||
++row;
|
||||
} else {
|
||||
wattron(this->lv_window, role_attrs);
|
||||
wattr_set(this->lv_window,
|
||||
role_attrs.ta_attrs,
|
||||
vc.ensure_color_pair(role_attrs.ta_fg_color,
|
||||
role_attrs.ta_bg_color),
|
||||
nullptr);
|
||||
mvwhline(this->lv_window, y, this->lv_x, ' ', width);
|
||||
wattroff(this->lv_window, role_attrs);
|
||||
++y;
|
||||
}
|
||||
}
|
||||
@ -283,7 +286,7 @@ listview_curses::do_update()
|
||||
int range_start = 0, range_end;
|
||||
role_t role = this->vc_default_role;
|
||||
role_t bar_role = role_t::VCR_SCROLLBAR;
|
||||
int attrs;
|
||||
text_attrs attrs;
|
||||
chtype ch = ACS_VLINE;
|
||||
|
||||
if (row_count > 0) {
|
||||
@ -299,9 +302,12 @@ listview_curses::do_update()
|
||||
role = bar_role;
|
||||
}
|
||||
attrs = vc.attrs_for_role(role);
|
||||
wattron(this->lv_window, attrs);
|
||||
wattr_set(
|
||||
this->lv_window,
|
||||
attrs.ta_attrs,
|
||||
vc.ensure_color_pair(attrs.ta_fg_color, attrs.ta_bg_color),
|
||||
nullptr);
|
||||
mvwaddch(this->lv_window, gutter_y, this->lv_x + width - 1, ch);
|
||||
wattroff(this->lv_window, attrs);
|
||||
}
|
||||
wmove(this->lv_window, this->lv_y + height - 1, this->lv_x);
|
||||
}
|
||||
|
36
src/lnav.cc
36
src/lnav.cc
@ -82,6 +82,7 @@
|
||||
#include "base/humanize.time.hh"
|
||||
#include "base/injector.bind.hh"
|
||||
#include "base/isc.hh"
|
||||
#include "base/itertools.hh"
|
||||
#include "base/lnav.console.hh"
|
||||
#include "base/lnav_log.hh"
|
||||
#include "base/paths.hh"
|
||||
@ -906,6 +907,14 @@ handle_key(int ch)
|
||||
handle_rl_key(ch);
|
||||
break;
|
||||
|
||||
case ln_mode_t::BUSY:
|
||||
switch (ch) {
|
||||
case KEY_CTRL_RBRACKET:
|
||||
log_vtab_data.lvd_looping = false;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
require(0);
|
||||
break;
|
||||
@ -1133,10 +1142,8 @@ looper()
|
||||
|
||||
for (const auto& format : log_format::get_root_formats()) {
|
||||
for (auto& hl : format->lf_highlighters) {
|
||||
if (hl.h_fg.empty()) {
|
||||
hl.with_attrs(hl.h_attrs
|
||||
| vc.attrs_for_ident(hl.h_pattern));
|
||||
}
|
||||
hl.with_attrs(hl.h_attrs
|
||||
| vc.attrs_for_ident(hl.h_pattern));
|
||||
|
||||
lnav_data.ld_views[LNV_LOG].get_highlights()[{
|
||||
highlight_source_t::CONFIGURATION,
|
||||
@ -1174,7 +1181,7 @@ looper()
|
||||
&lnav_data.ld_bottom_source));
|
||||
sb.push_back(bind_mem(&bottom_status_source::update_marks,
|
||||
&lnav_data.ld_bottom_source));
|
||||
sb.push_back(
|
||||
vsb.push_back(
|
||||
bind_mem(&term_extra::update_title, injector::get<term_extra*>()));
|
||||
vsb.push_back([](listview_curses* lv) {
|
||||
auto* tc = dynamic_cast<textview_curses*>(lv);
|
||||
@ -1413,7 +1420,7 @@ UPDATE lnav_views_echo
|
||||
attr_line_t("restored session from ")
|
||||
.append(lnav::roles::number(ago))
|
||||
.append("; press ")
|
||||
.append("CTRL-R"_symbol)
|
||||
.append("CTRL-R"_hotkey)
|
||||
.append(" to reset session"));
|
||||
lnav_data.ld_rl_view->set_attr_value(um.to_attr_line());
|
||||
}
|
||||
@ -1621,6 +1628,7 @@ UPDATE lnav_views_echo
|
||||
case ln_mode_t::FILTER:
|
||||
case ln_mode_t::FILES:
|
||||
case ln_mode_t::SPECTRO_DETAILS:
|
||||
case ln_mode_t::BUSY:
|
||||
if (old_gen
|
||||
== lnav_data.ld_active_files
|
||||
.fc_files_generation) {
|
||||
@ -1772,7 +1780,8 @@ UPDATE lnav_views_echo
|
||||
}
|
||||
|
||||
if (session_stage == 1
|
||||
&& (lnav_data.ld_log_source.text_line_count() > 0
|
||||
&& (lnav_data.ld_active_files.fc_file_names.empty()
|
||||
|| lnav_data.ld_log_source.text_line_count() > 0
|
||||
|| lnav_data.ld_text_source.text_line_count() > 0
|
||||
|| !lnav_data.ld_active_files.fc_other_files.empty()))
|
||||
{
|
||||
@ -1791,6 +1800,9 @@ UPDATE lnav_views_echo
|
||||
{
|
||||
log_debug("switching to paging!");
|
||||
lnav_data.ld_mode = ln_mode_t::PAGING;
|
||||
lnav_data.ld_active_files.fc_files
|
||||
| lnav::itertools::for_each(
|
||||
&logfile::dump_stats);
|
||||
} else {
|
||||
lnav_data.ld_files_view.set_selection(0_vl);
|
||||
}
|
||||
@ -2071,9 +2083,6 @@ SELECT tbl_name FROM sqlite_master WHERE sql LIKE 'CREATE VIRTUAL TABLE%'
|
||||
static const std::string DEFAULT_DEBUG_LOG = "/dev/null";
|
||||
|
||||
lnav_data.ld_debug_log_name = DEFAULT_DEBUG_LOG;
|
||||
lnav_data.ld_config_paths.emplace_back("/etc/lnav");
|
||||
lnav_data.ld_config_paths.emplace_back(SYSCONFDIR "/lnav");
|
||||
lnav_data.ld_config_paths.emplace_back(lnav::paths::dotlnav());
|
||||
|
||||
std::vector<std::string> file_args;
|
||||
std::vector<lnav::console::user_message> arg_errors;
|
||||
@ -2228,6 +2237,13 @@ SELECT tbl_name FROM sqlite_master WHERE sql LIKE 'CREATE VIRTUAL TABLE%'
|
||||
return e.get_exit_code();
|
||||
}
|
||||
|
||||
lnav_data.ld_config_paths.insert(lnav_data.ld_config_paths.begin(),
|
||||
lnav::paths::dotlnav());
|
||||
lnav_data.ld_config_paths.insert(lnav_data.ld_config_paths.begin(),
|
||||
SYSCONFDIR "/lnav");
|
||||
lnav_data.ld_config_paths.insert(lnav_data.ld_config_paths.begin(),
|
||||
"/etc/lnav");
|
||||
|
||||
if (lnav_data.ld_debug_log_name != DEFAULT_DEBUG_LOG) {
|
||||
lnav_log_level = lnav_log_level_t::TRACE;
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ remaining_args_frag(const std::string& cmdline,
|
||||
|
||||
require(index_in_cmdline != std::string::npos);
|
||||
|
||||
return string_fragment{cmdline.c_str(), static_cast<int>(index_in_cmdline)};
|
||||
return string_fragment::from_str_range(cmdline, index_in_cmdline, cmdline.size());
|
||||
}
|
||||
|
||||
static nonstd::optional<std::string>
|
||||
@ -1606,10 +1606,10 @@ com_highlight(exec_context& ec,
|
||||
return Err(um);
|
||||
} else {
|
||||
highlighter hl(code.release());
|
||||
attr_t hl_attrs = view_colors::singleton().attrs_for_ident(args[1]);
|
||||
auto hl_attrs = view_colors::singleton().attrs_for_ident(args[1]);
|
||||
|
||||
if (ec.ec_dry_run) {
|
||||
hl_attrs |= A_BLINK;
|
||||
hl_attrs.ta_attrs |= A_BLINK;
|
||||
}
|
||||
|
||||
hl.with_attrs(hl_attrs);
|
||||
@ -1752,22 +1752,17 @@ com_filter(exec_context& ec,
|
||||
} else {
|
||||
auto& hm = tc->get_highlights();
|
||||
highlighter hl(code.release());
|
||||
int color;
|
||||
|
||||
if (args[0] == "filter-out") {
|
||||
color = COLOR_RED;
|
||||
} else {
|
||||
color = COLOR_GREEN;
|
||||
}
|
||||
hl.with_attrs(view_colors::ansi_color_pair(COLOR_BLACK, color)
|
||||
| A_BLINK);
|
||||
auto role = (args[0] == "filter-out") ?
|
||||
role_t::VCR_DIFF_DELETE :
|
||||
role_t::VCR_DIFF_ADD;
|
||||
hl.with_attrs(text_attrs{A_BLINK});
|
||||
|
||||
hm[{highlight_source_t::PREVIEW, "preview"}] = hl;
|
||||
tc->reload_data();
|
||||
|
||||
lnav_data.ld_preview_status_source.get_description().set_value(
|
||||
"Matches are highlighted in %s in the text view",
|
||||
color == COLOR_RED ? "red" : "green");
|
||||
role == role_t::VCR_DIFF_DELETE ? "red" : "green");
|
||||
|
||||
retval = "";
|
||||
}
|
||||
@ -2179,12 +2174,12 @@ com_create_search_table(exec_context& ec,
|
||||
auto tab_name = intern_string::lookup(args[1]);
|
||||
auto lst = std::make_shared<log_search_table>(re, tab_name);
|
||||
if (ec.ec_dry_run) {
|
||||
textview_curses* tc = &lnav_data.ld_views[LNV_LOG];
|
||||
auto* tc = &lnav_data.ld_views[LNV_LOG];
|
||||
auto& hm = tc->get_highlights();
|
||||
highlighter hl(re.p_code);
|
||||
|
||||
hl.with_attrs(view_colors::ansi_color_pair(COLOR_BLACK, COLOR_CYAN)
|
||||
| A_BLINK);
|
||||
hl.with_role(role_t::VCR_INFO);
|
||||
hl.with_attrs(text_attrs{A_BLINK});
|
||||
|
||||
hm[{highlight_source_t::PREVIEW, "preview"}] = hl;
|
||||
tc->reload_data();
|
||||
@ -2210,7 +2205,7 @@ com_create_search_table(exec_context& ec,
|
||||
errmsg = lnav_data.ld_vtab_manager->register_vtab(lst);
|
||||
if (errmsg.empty()) {
|
||||
custom_search_tables.insert(args[1]);
|
||||
if (lnav_data.ld_rl_view != NULL) {
|
||||
if (lnav_data.ld_rl_view != nullptr) {
|
||||
lnav_data.ld_rl_view->add_possibility(
|
||||
ln_mode_t::COMMAND, "search-table", args[1]);
|
||||
}
|
||||
@ -2556,8 +2551,7 @@ com_open(exec_context& ec, std::string cmdline, std::vector<std::string>& args)
|
||||
}
|
||||
if (gl->gl_pathc > 10) {
|
||||
al.append(" ... ")
|
||||
.append(std::to_string(gl->gl_pathc - 10),
|
||||
VC_STYLE.value(A_BOLD))
|
||||
.append(lnav::roles::number(std::to_string(gl->gl_pathc - 10)))
|
||||
.append(" files not shown ...");
|
||||
}
|
||||
lnav_data.ld_preview_status_source.get_description()
|
||||
|
@ -515,6 +515,10 @@ static const struct json_path_container theme_styles_handlers = {
|
||||
.with_description("Styling for success messages")
|
||||
.for_child(&lnav_theme::lt_style_ok)
|
||||
.with_children(style_config_handlers),
|
||||
yajlpp::property_handler("info")
|
||||
.with_description("Styling for informational messages")
|
||||
.for_child(&lnav_theme::lt_style_info)
|
||||
.with_children(style_config_handlers),
|
||||
yajlpp::property_handler("warning")
|
||||
.with_description("Styling for warning messages")
|
||||
.for_child(&lnav_theme::lt_style_warning)
|
||||
|
@ -144,6 +144,7 @@ to_json(yajlpp_gen& gen, const attr_line_t& al)
|
||||
},
|
||||
[&](const intern_string_t& str) { elem_map.gen(str); },
|
||||
[&](const std::string& str) { elem_map.gen(str); },
|
||||
[&](const text_attrs& ta) { elem_map.gen(""); },
|
||||
[&](const std::shared_ptr<logfile>& lf) {
|
||||
elem_map.gen("");
|
||||
},
|
||||
|
@ -123,8 +123,8 @@ logline_value::logline_value(logline_value_meta lvm,
|
||||
case value_kind_t::VALUE_W3C_QUOTED:
|
||||
case value_kind_t::VALUE_TIMESTAMP:
|
||||
require(origin.lr_end != -1);
|
||||
this->lv_frag = string_fragment{
|
||||
sbr.get_data(), origin.lr_start, origin.lr_end};
|
||||
this->lv_frag = string_fragment::from_byte_range(
|
||||
sbr.get_data(), origin.lr_start, origin.lr_end);
|
||||
break;
|
||||
|
||||
case value_kind_t::VALUE_NULL:
|
||||
@ -555,11 +555,9 @@ json_array_end(void* ctx)
|
||||
jlu->jlu_format->jlf_line_values.lvv_values.emplace_back(
|
||||
jlu->jlu_format->get_value_meta(field_name,
|
||||
value_kind_t::VALUE_JSON),
|
||||
string_fragment{
|
||||
jlu->jlu_shared_buffer.get_data(),
|
||||
(int) jlu->jlu_sub_start,
|
||||
(int) sub_end,
|
||||
});
|
||||
string_fragment::from_byte_range(jlu->jlu_shared_buffer.get_data(),
|
||||
jlu->jlu_sub_start,
|
||||
sub_end));
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -1324,11 +1322,10 @@ rewrite_json_field(yajlpp_parse_context* ypc,
|
||||
jlu->jlu_format->jlf_line_values.lvv_values.emplace_back(
|
||||
jlu->jlu_format->get_value_meta(body_name,
|
||||
value_kind_t::VALUE_TEXT),
|
||||
string_fragment{
|
||||
string_fragment::from_byte_range(
|
||||
jlu->jlu_shared_buffer.get_data(),
|
||||
str_offset,
|
||||
str_offset + (int) len,
|
||||
});
|
||||
str_offset + len));
|
||||
}
|
||||
if (!ypc->is_level(1) && !jlu->jlu_format->has_value_def(field_name)) {
|
||||
return 1;
|
||||
@ -1337,11 +1334,9 @@ rewrite_json_field(yajlpp_parse_context* ypc,
|
||||
jlu->jlu_format->jlf_line_values.lvv_values.emplace_back(
|
||||
jlu->jlu_format->get_value_meta(field_name,
|
||||
value_kind_t::VALUE_TEXT),
|
||||
string_fragment{
|
||||
jlu->jlu_shared_buffer.get_data(),
|
||||
str_offset,
|
||||
str_offset + (int) len,
|
||||
});
|
||||
string_fragment::from_byte_range(jlu->jlu_shared_buffer.get_data(),
|
||||
str_offset,
|
||||
str_offset + len));
|
||||
} else {
|
||||
if (field_name == jlu->jlu_format->elf_body_field) {
|
||||
jlu->jlu_format->jlf_line_values.lvv_values.emplace_back(
|
||||
@ -2265,7 +2260,8 @@ external_log_format::build(std::vector<lnav::console::user_message>& errors)
|
||||
const char* errptr;
|
||||
auto fg = styling::color_unit::make_empty();
|
||||
auto bg = styling::color_unit::make_empty();
|
||||
int eoff, attrs = 0;
|
||||
text_attrs attrs;
|
||||
int eoff;
|
||||
|
||||
if (!hd.hd_color.pp_value.empty()) {
|
||||
fg = styling::color_unit::from_str(hd.hd_color.pp_value)
|
||||
@ -2305,14 +2301,14 @@ external_log_format::build(std::vector<lnav::console::user_message>& errors)
|
||||
}
|
||||
|
||||
if (hd.hd_underline) {
|
||||
attrs |= A_UNDERLINE;
|
||||
attrs.ta_attrs |= A_UNDERLINE;
|
||||
}
|
||||
if (hd.hd_blink) {
|
||||
attrs |= A_BLINK;
|
||||
attrs.ta_attrs |= A_BLINK;
|
||||
}
|
||||
|
||||
if (hd.hd_pattern != nullptr) {
|
||||
pcre* code = pcre_compile(hd.hd_pattern->get_pattern().c_str(),
|
||||
auto* code = pcre_compile(hd.hd_pattern->get_pattern().c_str(),
|
||||
PCRE_CASELESS | PCRE_UTF8,
|
||||
&errptr,
|
||||
&eoff,
|
||||
|
@ -351,7 +351,7 @@ struct separated_string {
|
||||
|
||||
string_fragment operator*()
|
||||
{
|
||||
const separated_string& ss = this->i_parent;
|
||||
const auto& ss = this->i_parent;
|
||||
int end;
|
||||
|
||||
if (this->i_next_pos < (ss.ss_str + ss.ss_len)) {
|
||||
@ -359,7 +359,8 @@ struct separated_string {
|
||||
} else {
|
||||
end = this->i_next_pos - ss.ss_str;
|
||||
}
|
||||
return string_fragment(ss.ss_str, this->i_pos - ss.ss_str, end);
|
||||
return string_fragment::from_byte_range(
|
||||
ss.ss_str, this->i_pos - ss.ss_str, end);
|
||||
}
|
||||
|
||||
bool operator==(const iterator& other) const
|
||||
@ -1643,8 +1644,7 @@ public:
|
||||
shared_buffer_ref& sbr,
|
||||
scan_batch_context& sbc) override
|
||||
{
|
||||
auto p = logfmt::parser(
|
||||
string_fragment{sbr.get_data(), 0, (int) sbr.length()});
|
||||
auto p = logfmt::parser(sbr.to_string_fragment());
|
||||
scan_result_t retval = scan_result_t::SCAN_NO_MATCH;
|
||||
bool done = false;
|
||||
logfmt_pair_handler lph(this->lf_date_time);
|
||||
@ -1729,8 +1729,7 @@ public:
|
||||
static const auto FIELDS_NAME = intern_string::lookup("fields");
|
||||
|
||||
auto& sbr = values.lvv_sbr;
|
||||
auto p = logfmt::parser(
|
||||
string_fragment{sbr.get_data(), 0, (int) sbr.length()});
|
||||
auto p = logfmt::parser(sbr.to_string_fragment());
|
||||
bool done = false;
|
||||
|
||||
while (!done) {
|
||||
|
@ -70,8 +70,8 @@ log_search_table::get_columns_int(std::vector<vtab_column>& cols) const
|
||||
std::string colname;
|
||||
int sqlite_type = SQLITE3_TEXT;
|
||||
|
||||
colname = cn.add_column(
|
||||
string_fragment{this->lst_regex.name_for_capture(lpc)})
|
||||
colname = cn.add_column(string_fragment::from_c_str(
|
||||
this->lst_regex.name_for_capture(lpc)))
|
||||
.to_string();
|
||||
if (this->lst_regex.captures().size()
|
||||
== (size_t) this->lst_regex.get_capture_count())
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "logfile_sub_source.hh"
|
||||
#include "sql_util.hh"
|
||||
#include "vtab_module.hh"
|
||||
#include "vtab_module_json.hh"
|
||||
#include "yajlpp/json_op.hh"
|
||||
#include "yajlpp/yajlpp_def.hh"
|
||||
|
||||
@ -752,11 +753,7 @@ vt_column(sqlite3_vtab_cursor* cur, sqlite3_context* ctx, int col)
|
||||
}
|
||||
}
|
||||
|
||||
string_fragment sf = gen.to_string_fragment();
|
||||
|
||||
sqlite3_result_text(
|
||||
ctx, sf.data(), sf.length(), SQLITE_TRANSIENT);
|
||||
sqlite3_result_subtype(ctx, JSON_SUBTYPE);
|
||||
to_sqlite(ctx, json_string(gen));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -930,8 +927,7 @@ vt_column(sqlite3_vtab_cursor* cur, sqlite3_context* ctx, int col)
|
||||
line_hasher.update(sbr.get_data(), sbr.length())
|
||||
.update(cl)
|
||||
.to_string(outbuf);
|
||||
auto tab = text_auto_buffer{std::move(outbuf)};
|
||||
to_sqlite(ctx, tab);
|
||||
to_sqlite(ctx, text_auto_buffer{std::move(outbuf)});
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -2046,6 +2042,9 @@ progress_callback(void* ptr)
|
||||
if (log_vtab_data.lvd_progress != nullptr) {
|
||||
retval = log_vtab_data.lvd_progress(log_cursor_latest);
|
||||
}
|
||||
if (!log_vtab_data.lvd_looping) {
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -268,6 +268,7 @@ using sql_progress_callback_t = int (*)(const log_cursor&);
|
||||
using sql_progress_finished_callback_t = void (*)();
|
||||
|
||||
struct _log_vtab_data {
|
||||
bool lvd_looping{true};
|
||||
sql_progress_callback_t lvd_progress;
|
||||
sql_progress_finished_callback_t lvd_finished;
|
||||
source_location lvd_location;
|
||||
@ -283,6 +284,7 @@ public:
|
||||
source_location loc,
|
||||
const attr_line_t& content)
|
||||
{
|
||||
log_vtab_data.lvd_looping = true;
|
||||
log_vtab_data.lvd_progress = cb;
|
||||
log_vtab_data.lvd_finished = fcb;
|
||||
log_vtab_data.lvd_location = loc;
|
||||
@ -294,6 +296,7 @@ public:
|
||||
if (log_vtab_data.lvd_finished) {
|
||||
log_vtab_data.lvd_finished();
|
||||
}
|
||||
log_vtab_data.lvd_looping = true;
|
||||
log_vtab_data.lvd_progress = nullptr;
|
||||
log_vtab_data.lvd_finished = nullptr;
|
||||
log_vtab_data.lvd_location = source_location{};
|
||||
|
@ -962,3 +962,31 @@ logfile::line_for_offset(file_off_t off) const
|
||||
|
||||
return nonstd::make_optional(iter);
|
||||
}
|
||||
|
||||
void
|
||||
logfile::dump_stats()
|
||||
{
|
||||
const auto buf_stats = this->lf_line_buffer.consume_stats();
|
||||
|
||||
if (buf_stats.empty()) {
|
||||
return;
|
||||
}
|
||||
log_info("line buffer stats for file: %s", this->lf_filename.c_str());
|
||||
log_info(" file_size=%lld", this->lf_line_buffer.get_file_size());
|
||||
log_info(" buffer_size=%ld", this->lf_line_buffer.get_buffer_size());
|
||||
log_info(" read_hist=[%4lu %4lu %4lu %4lu %4lu %4lu %4lu %4lu %4lu %4lu]",
|
||||
buf_stats.s_hist[0],
|
||||
buf_stats.s_hist[1],
|
||||
buf_stats.s_hist[2],
|
||||
buf_stats.s_hist[3],
|
||||
buf_stats.s_hist[4],
|
||||
buf_stats.s_hist[5],
|
||||
buf_stats.s_hist[6],
|
||||
buf_stats.s_hist[7],
|
||||
buf_stats.s_hist[8],
|
||||
buf_stats.s_hist[9]);
|
||||
log_info(" decompressions=%lu", buf_stats.s_decompressions);
|
||||
log_info(" preads=%lu", buf_stats.s_preads);
|
||||
log_info(" requested_preloads=%lu", buf_stats.s_requested_preloads);
|
||||
log_info(" used_preloads=%lu", buf_stats.s_used_preloads);
|
||||
}
|
||||
|
@ -373,6 +373,8 @@ public:
|
||||
|
||||
void quiesce() { this->lf_line_buffer.quiesce(); }
|
||||
|
||||
void dump_stats();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Process a line from the file.
|
||||
|
@ -353,7 +353,7 @@ logfile_sub_source::text_attrs_for_line(textview_curses& lv,
|
||||
logline* next_line = nullptr;
|
||||
struct line_range lr;
|
||||
int time_offset_end = 0;
|
||||
int attrs = 0;
|
||||
text_attrs attrs;
|
||||
|
||||
value_out = this->lss_token_attrs;
|
||||
|
||||
@ -365,7 +365,7 @@ logfile_sub_source::text_attrs_for_line(textview_curses& lv,
|
||||
&& (day_num(next_line->get_time())
|
||||
> day_num(this->lss_token_line->get_time())))
|
||||
{
|
||||
attrs |= A_UNDERLINE;
|
||||
attrs.ta_attrs |= A_UNDERLINE;
|
||||
}
|
||||
|
||||
const auto& line_values = this->lss_token_values;
|
||||
@ -458,7 +458,8 @@ logfile_sub_source::text_attrs_for_line(textview_curses& lv,
|
||||
vis_line_t(row))) {
|
||||
lr.lr_start = 0;
|
||||
lr.lr_end = 1;
|
||||
value_out.emplace_back(lr, VC_STYLE.value(A_REVERSE));
|
||||
value_out.emplace_back(lr,
|
||||
VC_STYLE.value(text_attrs{A_REVERSE}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -586,7 +587,7 @@ logfile_sub_source::text_attrs_for_line(textview_curses& lv,
|
||||
} else {
|
||||
color = COLOR_RED;
|
||||
value_out.emplace_back(line_range{0, 1},
|
||||
VC_STYLE.value(A_BLINK));
|
||||
VC_STYLE.value(text_attrs{A_BLINK}));
|
||||
}
|
||||
}
|
||||
value_out.emplace_back(line_range{0, 1},
|
||||
|
@ -187,11 +187,8 @@ md2attr_line::leave_block(const md4cpp::event_handler::block& bl)
|
||||
|
||||
this->ml_code_depth -= 1;
|
||||
|
||||
auto lang_sf = string_fragment{
|
||||
code_detail->lang.text,
|
||||
0,
|
||||
(int) code_detail->lang.size,
|
||||
};
|
||||
auto lang_sf = string_fragment::from_bytes(code_detail->lang.text,
|
||||
code_detail->lang.size);
|
||||
if (lang_sf == "lnav") {
|
||||
readline_lnav_highlighter(block_text, block_text.length());
|
||||
}
|
||||
@ -398,7 +395,7 @@ md2attr_line::leave_span(const md4cpp::event_handler::span& sp)
|
||||
#if defined(A_ITALIC)
|
||||
last_block.with_attr({
|
||||
lr,
|
||||
VC_STYLE.value(A_ITALIC),
|
||||
VC_STYLE.value(text_attrs{(int32_t) A_ITALIC}),
|
||||
});
|
||||
#endif
|
||||
} else if (sp.is<span_strong>()) {
|
||||
@ -408,7 +405,7 @@ md2attr_line::leave_span(const md4cpp::event_handler::span& sp)
|
||||
};
|
||||
last_block.with_attr({
|
||||
lr,
|
||||
VC_STYLE.value(A_BOLD),
|
||||
VC_STYLE.value(text_attrs{A_BOLD}),
|
||||
});
|
||||
} else if (sp.is<MD_SPAN_A_DETAIL*>()) {
|
||||
auto* a_detail = sp.get<MD_SPAN_A_DETAIL*>();
|
||||
@ -464,12 +461,7 @@ md2attr_line::text(MD_TEXTTYPE tt, const string_fragment& sf)
|
||||
pcre_context_static<30> pc;
|
||||
|
||||
while (REPL_RE.match(pc, pi)) {
|
||||
auto prev = string_fragment{
|
||||
sf.sf_string,
|
||||
(int) pi.pi_offset,
|
||||
pc.all()->c_begin,
|
||||
};
|
||||
|
||||
auto prev = pi.get_up_to(pc.all());
|
||||
last_block.append(prev);
|
||||
|
||||
auto matched = pi.get_string_fragment(pc.all());
|
||||
@ -489,11 +481,7 @@ md2attr_line::text(MD_TEXTTYPE tt, const string_fragment& sf)
|
||||
}
|
||||
}
|
||||
|
||||
this->ml_blocks.back().append(string_fragment{
|
||||
sf.sf_string,
|
||||
(int) pi.pi_offset,
|
||||
sf.sf_end,
|
||||
});
|
||||
this->ml_blocks.back().append(sf.substr(pi.pi_offset));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -514,9 +502,9 @@ md2attr_line::append_url_footnote(std::string href_str)
|
||||
(int) this->ml_span_starts.back(),
|
||||
(int) last_block.length(),
|
||||
},
|
||||
VC_STYLE.value(A_UNDERLINE),
|
||||
VC_STYLE.value(text_attrs{A_UNDERLINE}),
|
||||
});
|
||||
if (this->ml_source_path && href_str.find(":") == std::string::npos) {
|
||||
if (this->ml_source_path && href_str.find(':') == std::string::npos) {
|
||||
auto link_path = ghc::filesystem::absolute(
|
||||
this->ml_source_path.value().parent_path() / href_str);
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include "md4cpp.hh"
|
||||
|
||||
#include "base/is_utf8.hh"
|
||||
#include "base/lnav_log.hh"
|
||||
#include "emojis-json.h"
|
||||
#include "xml-entities-json.h"
|
||||
@ -263,6 +264,20 @@ namespace details {
|
||||
Result<void, std::string>
|
||||
parse(const string_fragment& sf, event_handler& eh)
|
||||
{
|
||||
const char* utf8_errmsg = nullptr;
|
||||
int utf8_faulty_bytes = 0;
|
||||
|
||||
auto utf8_erroff = is_utf8((unsigned char*) sf.data(),
|
||||
sf.length(),
|
||||
&utf8_errmsg,
|
||||
&utf8_faulty_bytes);
|
||||
if (utf8_errmsg != nullptr) {
|
||||
return Err(
|
||||
fmt::format(FMT_STRING("file has invalid UTF-8 at offset {}: {}"),
|
||||
utf8_erroff,
|
||||
utf8_errmsg));
|
||||
}
|
||||
|
||||
MD_PARSER parser = {0};
|
||||
auto pu = parse_userdata{eh};
|
||||
|
||||
|
@ -237,11 +237,14 @@ public:
|
||||
|
||||
string_fragment get_string_fragment(pcre_context::const_iterator iter) const
|
||||
{
|
||||
return string_fragment{
|
||||
this->pi_string,
|
||||
iter->c_begin,
|
||||
iter->c_end,
|
||||
};
|
||||
return string_fragment::from_byte_range(
|
||||
this->pi_string, iter->c_begin, iter->c_end);
|
||||
}
|
||||
|
||||
string_fragment get_up_to(pcre_context::const_iterator iter) const
|
||||
{
|
||||
return string_fragment::from_byte_range(
|
||||
this->pi_string, this->pi_offset, iter->c_begin);
|
||||
}
|
||||
|
||||
nonstd::optional<std::string> get_substr_opt(
|
||||
|
@ -143,7 +143,8 @@ plain_text_source::text_attrs_for_line(textview_curses& tc,
|
||||
if (this->tds_reverse_selection && tc.is_selectable()
|
||||
&& tc.get_selection() == line)
|
||||
{
|
||||
value_out.emplace_back(line_range{0, -1}, VC_STYLE.value(A_REVERSE));
|
||||
value_out.emplace_back(line_range{0, -1},
|
||||
VC_STYLE.value(text_attrs{A_REVERSE}));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -508,6 +508,7 @@ rl_search_internal(readline_curses* rc, ln_mode_t mode, bool complete = false)
|
||||
case ln_mode_t::EXEC:
|
||||
case ln_mode_t::USER:
|
||||
case ln_mode_t::SPECTRO_DETAILS:
|
||||
case ln_mode_t::BUSY:
|
||||
return;
|
||||
}
|
||||
|
||||
@ -603,6 +604,7 @@ rl_callback_int(readline_curses* rc, bool is_alt)
|
||||
case ln_mode_t::FILTER:
|
||||
case ln_mode_t::FILES:
|
||||
case ln_mode_t::SPECTRO_DETAILS:
|
||||
case ln_mode_t::BUSY:
|
||||
require(0);
|
||||
break;
|
||||
|
||||
@ -830,7 +832,7 @@ rl_display_matches(readline_curses* rc)
|
||||
add_nl = false;
|
||||
}
|
||||
if (match == current_match) {
|
||||
al.append(match, VC_STYLE.value(A_REVERSE));
|
||||
al.append(match, VC_STYLE.value(text_attrs{A_REVERSE}));
|
||||
} else {
|
||||
al.append(match);
|
||||
}
|
||||
|
@ -1385,7 +1385,11 @@ readline_curses::do_update()
|
||||
view_colors& vc = view_colors::singleton();
|
||||
|
||||
wmove(this->vc_window, this->get_actual_y(), this->vc_left);
|
||||
wattron(this->vc_window, vc.attrs_for_role(role_t::VCR_TEXT));
|
||||
auto attrs = vc.attrs_for_role(role_t::VCR_TEXT);
|
||||
wattr_set(this->vc_window,
|
||||
attrs.ta_attrs,
|
||||
vc.ensure_color_pair(attrs.ta_fg_color, attrs.ta_bg_color),
|
||||
nullptr);
|
||||
whline(this->vc_window, ' ', this->vc_width);
|
||||
|
||||
if (time(nullptr) > this->rc_value_expiration) {
|
||||
|
@ -82,7 +82,7 @@ find_matching_bracket(
|
||||
} else if (line[lpc] == left && is_bracket(line, lpc, is_lit)) {
|
||||
if (depth == 0) {
|
||||
alb.overlay_attr_for_char(
|
||||
lpc, VC_STYLE.value(A_BOLD | A_REVERSE));
|
||||
lpc, VC_STYLE.value(text_attrs{A_BOLD | A_REVERSE}));
|
||||
alb.overlay_attr_for_char(lpc,
|
||||
VC_ROLE.value(role_t::VCR_OK));
|
||||
break;
|
||||
@ -99,7 +99,7 @@ find_matching_bracket(
|
||||
} else if (line[lpc] == right && is_bracket(line, lpc, is_lit)) {
|
||||
if (depth == 0) {
|
||||
alb.overlay_attr_for_char(
|
||||
lpc, VC_STYLE.value(A_BOLD | A_REVERSE));
|
||||
lpc, VC_STYLE.value(text_attrs{A_BOLD | A_REVERSE}));
|
||||
alb.overlay_attr_for_char(lpc,
|
||||
VC_ROLE.value(role_t::VCR_OK));
|
||||
break;
|
||||
@ -124,7 +124,8 @@ find_matching_bracket(
|
||||
depth -= 1;
|
||||
} else {
|
||||
auto lr = line_range(is_lit ? lpc - 1 : lpc, lpc + 1);
|
||||
alb.overlay_attr(lr, VC_STYLE.value(A_BOLD | A_REVERSE));
|
||||
alb.overlay_attr(
|
||||
lr, VC_STYLE.value(text_attrs{A_BOLD | A_REVERSE}));
|
||||
alb.overlay_attr(lr, VC_ROLE.value(role_t::VCR_ERROR));
|
||||
}
|
||||
}
|
||||
@ -134,7 +135,7 @@ find_matching_bracket(
|
||||
auto lr
|
||||
= line_range(is_lit ? first_left.value() - 1 : first_left.value(),
|
||||
first_left.value() + 1);
|
||||
alb.overlay_attr(lr, VC_STYLE.value(A_BOLD | A_REVERSE));
|
||||
alb.overlay_attr(lr, VC_STYLE.value(text_attrs{A_BOLD | A_REVERSE}));
|
||||
alb.overlay_attr(lr, VC_ROLE.value(role_t::VCR_ERROR));
|
||||
}
|
||||
}
|
||||
@ -189,7 +190,7 @@ readline_command_highlighter_int(attr_line_t& al, int x, line_range sub)
|
||||
if (COLOR_PREFIXES.match(pc, pi)) {
|
||||
pi.reset(&line[sub.lr_start], 0, sub.length());
|
||||
if (COLOR_RE.match(pc, pi)) {
|
||||
pcre_context::capture_t* cap = pc[0];
|
||||
auto* cap = pc[0];
|
||||
auto hash_color = pi.get_substr(cap);
|
||||
|
||||
styling::color_unit::from_str(hash_color)
|
||||
@ -278,8 +279,8 @@ readline_sqlite_highlighter_int(attr_line_t& al, int x, line_range sub)
|
||||
if (lr.length() > 1 && al.al_string[lr.lr_end - 1] == '\'') {
|
||||
alb.overlay_attr(lr, VC_ROLE.value(role_t::VCR_STRING));
|
||||
} else {
|
||||
alb.overlay_attr_for_char(lr.lr_start,
|
||||
VC_STYLE.value(A_REVERSE));
|
||||
alb.overlay_attr_for_char(
|
||||
lr.lr_start, VC_STYLE.value(text_attrs{A_REVERSE}));
|
||||
alb.overlay_attr_for_char(lr.lr_start,
|
||||
VC_ROLE.value(role_t::VCR_ERROR));
|
||||
}
|
||||
@ -317,7 +318,7 @@ readline_shlex_highlighter_int(attr_line_t& al, int x, line_range sub)
|
||||
case shlex_token_t::ST_ERROR:
|
||||
alb.overlay_attr(line_range(sub.lr_start + cap.c_begin,
|
||||
sub.lr_start + cap.c_end),
|
||||
VC_STYLE.value(A_REVERSE));
|
||||
VC_STYLE.value(text_attrs{A_REVERSE}));
|
||||
alb.overlay_attr(line_range(sub.lr_start + cap.c_begin,
|
||||
sub.lr_start + cap.c_end),
|
||||
VC_ROLE.value(role_t::VCR_ERROR));
|
||||
|
@ -123,7 +123,7 @@ public:
|
||||
|
||||
string_fragment to_string_fragment() const
|
||||
{
|
||||
return string_fragment{this->sb_data, 0, (int) this->length()};
|
||||
return string_fragment::from_bytes(this->sb_data, this->length());
|
||||
}
|
||||
|
||||
using narrow_result = std::pair<char*, size_t>;
|
||||
|
@ -309,8 +309,8 @@ spectrogram_source::list_value_for_overlay(const listview_curses& lv,
|
||||
}
|
||||
line.append(buf);
|
||||
|
||||
value_out.with_attr(
|
||||
string_attr(line_range(0, -1), VC_STYLE.value(A_UNDERLINE)));
|
||||
value_out.with_attr(string_attr(line_range(0, -1),
|
||||
VC_STYLE.value(text_attrs{A_UNDERLINE})));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -693,7 +693,7 @@ annotate_sql_with_error(sqlite3* db, const char* sql, const char* tail)
|
||||
} else {
|
||||
tail = tail_lf;
|
||||
}
|
||||
retval.append(string_fragment{sql, 0, (int) (tail - sql)});
|
||||
retval.append(string_fragment::from_bytes(sql, tail - sql));
|
||||
} else {
|
||||
retval.append(sql);
|
||||
}
|
||||
|
@ -63,9 +63,9 @@ status_field::do_cylon()
|
||||
struct line_range lr(std::max(start, 0L), stop);
|
||||
auto& vc = view_colors::singleton();
|
||||
|
||||
sa.emplace_back(lr,
|
||||
VC_STYLE.value(vc.attrs_for_role(role_t::VCR_ACTIVE_STATUS)
|
||||
| A_REVERSE));
|
||||
auto attrs = vc.attrs_for_role(role_t::VCR_ACTIVE_STATUS);
|
||||
attrs.ta_attrs |= A_REVERSE;
|
||||
sa.emplace_back(lr, VC_STYLE.value(attrs));
|
||||
|
||||
this->sf_cylon_pos += 1;
|
||||
}
|
||||
@ -88,7 +88,7 @@ status_field::set_stitch_value(role_t left,
|
||||
void
|
||||
statusview_curses::do_update()
|
||||
{
|
||||
int top, attrs, field, field_count, left = 0, right;
|
||||
int top, field, field_count, left = 0, right;
|
||||
auto& vc = view_colors::singleton();
|
||||
unsigned long width, height;
|
||||
|
||||
@ -101,15 +101,14 @@ statusview_curses::do_update()
|
||||
|
||||
top = this->sc_top < 0 ? height + this->sc_top : this->sc_top;
|
||||
right = width;
|
||||
attrs = vc.attrs_for_role(this->sc_enabled
|
||||
? role_t::VCR_STATUS
|
||||
: role_t::VCR_INACTIVE_STATUS);
|
||||
auto attrs = vc.attrs_for_role(
|
||||
this->sc_enabled ? role_t::VCR_STATUS : role_t::VCR_INACTIVE_STATUS);
|
||||
|
||||
wattron(this->sc_window, attrs);
|
||||
auto pair = vc.ensure_color_pair(attrs.ta_fg_color, attrs.ta_bg_color);
|
||||
wattr_set(this->sc_window, attrs.ta_attrs, pair, nullptr);
|
||||
wmove(this->sc_window, top, 0);
|
||||
wclrtoeol(this->sc_window);
|
||||
whline(this->sc_window, ' ', width);
|
||||
wattroff(this->sc_window, attrs);
|
||||
|
||||
if (this->sc_source != nullptr) {
|
||||
field_count = this->sc_source->statusview_fields();
|
||||
@ -125,8 +124,11 @@ statusview_curses::do_update()
|
||||
if (!this->sc_enabled) {
|
||||
for (auto& sa : val.get_attrs()) {
|
||||
if (sa.sa_type == &VC_STYLE) {
|
||||
sa.sa_value = sa.sa_value.get<int64_t>()
|
||||
& ~(A_REVERSE | A_COLOR);
|
||||
auto sa_attrs = sa.sa_value.get<text_attrs>();
|
||||
sa_attrs.ta_attrs &= ~(A_REVERSE | A_COLOR);
|
||||
sa_attrs.ta_fg_color = nonstd::nullopt;
|
||||
sa_attrs.ta_bg_color = nonstd::nullopt;
|
||||
sa.sa_value = sa_attrs;
|
||||
} else if (sa.sa_type == &VC_ROLE) {
|
||||
if (sa.sa_value.get<role_t>()
|
||||
== role_t::VCR_ALERT_STATUS) {
|
||||
|
@ -59,10 +59,11 @@ find_re(string_fragment re)
|
||||
|
||||
c.re2 = std::make_shared<pcrepp>(re.to_string());
|
||||
auto pair = cache.insert(
|
||||
std::make_pair(string_fragment{c.re2->get_pattern()}, c));
|
||||
std::make_pair(string_fragment::from_str(c.re2->get_pattern()), c));
|
||||
|
||||
for (int lpc = 0; lpc < c.re2->get_capture_count(); lpc++) {
|
||||
c.cn->add_column(string_fragment{c.re2->name_for_capture(lpc)});
|
||||
c.cn->add_column(
|
||||
string_fragment::from_c_str(c.re2->name_for_capture(lpc)));
|
||||
}
|
||||
|
||||
iter = pair.first;
|
||||
|
@ -168,6 +168,7 @@ struct lnav_theme {
|
||||
style_config lt_style_text;
|
||||
style_config lt_style_alt_text;
|
||||
style_config lt_style_ok;
|
||||
style_config lt_style_info;
|
||||
style_config lt_style_error;
|
||||
style_config lt_style_warning;
|
||||
style_config lt_style_popup;
|
||||
|
@ -34,6 +34,8 @@
|
||||
#include "config.h"
|
||||
#include "md2attr_line.hh"
|
||||
|
||||
using namespace lnav::roles::literals;
|
||||
|
||||
size_t
|
||||
textfile_sub_source::text_line_count()
|
||||
{
|
||||
@ -514,20 +516,24 @@ textfile_sub_source::rescan_files(
|
||||
|
||||
mdal.with_source_path(lf->get_actual_path());
|
||||
auto parse_res = md4cpp::parse(content_sf, mdal);
|
||||
|
||||
auto& rf = this->tss_rendered_files[lf->get_filename()];
|
||||
rf.rf_mtime = st.st_mtime;
|
||||
rf.rf_file_size = st.st_size;
|
||||
rf.rf_text_source = std::make_unique<plain_text_source>();
|
||||
rf.rf_text_source->register_view(this->tss_view);
|
||||
if (parse_res.isOk()) {
|
||||
auto& rf = this->tss_rendered_files[lf->get_filename()];
|
||||
rf.rf_mtime = st.st_mtime;
|
||||
rf.rf_file_size = st.st_size;
|
||||
rf.rf_text_source
|
||||
= std::make_unique<plain_text_source>();
|
||||
rf.rf_text_source->register_view(this->tss_view);
|
||||
rf.rf_text_source->replace_with(parse_res.unwrap());
|
||||
log_info("successfully rendered markdown file: %s",
|
||||
lf->get_filename().c_str());
|
||||
} else {
|
||||
log_error("unable to parse markdown file: %s -- %s",
|
||||
lf->get_filename().c_str(),
|
||||
parse_res.unwrapErr().c_str());
|
||||
auto view_content
|
||||
= lnav::console::user_message::error(
|
||||
"unable to parse markdown file")
|
||||
.with_reason(parse_res.unwrapErr())
|
||||
.to_attr_line();
|
||||
view_content.append("\n").append(
|
||||
attr_line_t::from_ansi_str(content.c_str()));
|
||||
|
||||
rf.rf_text_source->replace_with(view_content);
|
||||
}
|
||||
} else {
|
||||
log_error("unable to read markdown file: %s -- %s",
|
||||
|
@ -197,7 +197,7 @@ textview_curses::reload_config(error_reporter& reporter)
|
||||
const auto& sc = hl_pair.second.hc_style;
|
||||
std::string fg1, bg1, fg_color, bg_color, errmsg;
|
||||
bool invalid = false;
|
||||
int attrs = 0;
|
||||
text_attrs attrs;
|
||||
|
||||
fg1 = sc.sc_color;
|
||||
bg1 = sc.sc_background_color;
|
||||
@ -229,15 +229,15 @@ textview_curses::reload_config(error_reporter& reporter)
|
||||
}
|
||||
|
||||
if (sc.sc_bold) {
|
||||
attrs |= A_BOLD;
|
||||
attrs.ta_attrs |= A_BOLD;
|
||||
}
|
||||
if (sc.sc_underline) {
|
||||
attrs |= A_UNDERLINE;
|
||||
attrs.ta_attrs |= A_UNDERLINE;
|
||||
}
|
||||
this->tc_highlights[{highlight_source_t::THEME, hl_pair.first}]
|
||||
= highlighter(code)
|
||||
.with_pattern(hl_pair.second.hc_regex)
|
||||
.with_attrs(attrs != 0 ? attrs : -1)
|
||||
.with_attrs(attrs)
|
||||
.with_color(fg, bg);
|
||||
}
|
||||
}
|
||||
@ -555,7 +555,7 @@ textview_curses::textview_value_for_row(vis_line_t row, attr_line_t& value_out)
|
||||
|| binary_search(user_expr_marks.begin(), user_expr_marks.end(), row))
|
||||
{
|
||||
sa.emplace_back(line_range{orig_line.lr_start, -1},
|
||||
VC_STYLE.value(A_REVERSE));
|
||||
VC_STYLE.value(text_attrs{A_REVERSE}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -656,8 +656,7 @@ textview_curses::horiz_shift(vis_line_t start,
|
||||
int off_start,
|
||||
std::pair<int, int>& range_out)
|
||||
{
|
||||
highlighter& hl
|
||||
= this->tc_highlights[{highlight_source_t::PREVIEW, "search"}];
|
||||
auto& hl = this->tc_highlights[{highlight_source_t::PREVIEW, "search"}];
|
||||
int prev_hit = -1, next_hit = INT_MAX;
|
||||
|
||||
for (; start < end; ++start) {
|
||||
|
@ -185,7 +185,6 @@
|
||||
},
|
||||
"hotkey": {
|
||||
"color": "Purple",
|
||||
"background-color": "Silver",
|
||||
"underline": true,
|
||||
"bold": true
|
||||
}
|
||||
|
@ -115,7 +115,6 @@
|
||||
},
|
||||
"hotkey": {
|
||||
"color": "#fff",
|
||||
"background-color": "#353535",
|
||||
"underline": true
|
||||
},
|
||||
"text": {
|
||||
|
@ -31,6 +31,10 @@
|
||||
"color": "$green",
|
||||
"bold": true
|
||||
},
|
||||
"info": {
|
||||
"color": "$magenta",
|
||||
"bold": true
|
||||
},
|
||||
"error": {
|
||||
"color": "$red",
|
||||
"bold": true
|
||||
@ -215,7 +219,6 @@
|
||||
},
|
||||
"hotkey": {
|
||||
"color": "#fff",
|
||||
"background-color": "#353535",
|
||||
"underline": true
|
||||
},
|
||||
"text": {
|
||||
|
@ -183,7 +183,6 @@
|
||||
},
|
||||
"hotkey": {
|
||||
"color": "#2d5a80",
|
||||
"background-color": "#162d40",
|
||||
"bold": true,
|
||||
"underline": true
|
||||
},
|
||||
|
1004
src/view_curses.cc
1004
src/view_curses.cc
File diff suppressed because it is too large
Load Diff
@ -187,6 +187,11 @@ public:
|
||||
/** @return A reference to the singleton. */
|
||||
static view_colors& singleton();
|
||||
|
||||
view_colors(const view_colors&) = delete;
|
||||
view_colors(view_colors&&) = delete;
|
||||
view_colors& operator=(const view_colors&) = delete;
|
||||
view_colors& operator=(view_colors&&) = delete;
|
||||
|
||||
/**
|
||||
* Performs curses-specific initialization. The other methods can be
|
||||
* called before this method, but the returned attributes cannot be used
|
||||
@ -201,21 +206,21 @@ public:
|
||||
* @param role The role to retrieve character attributes for.
|
||||
* @return The attributes to use for the given role.
|
||||
*/
|
||||
attr_t attrs_for_role(role_t role, bool selected = false) const
|
||||
text_attrs attrs_for_role(role_t role, bool selected = false) const
|
||||
{
|
||||
if (role == role_t::VCR_NONE) {
|
||||
return 0;
|
||||
return {};
|
||||
}
|
||||
|
||||
require(role > role_t::VCR_NONE);
|
||||
require(role < role_t::VCR__MAX);
|
||||
|
||||
return selected
|
||||
? this->vc_role_colors[lnav::enums::to_underlying(role)].second
|
||||
: this->vc_role_colors[lnav::enums::to_underlying(role)].first;
|
||||
? this->vc_role_attrs[lnav::enums::to_underlying(role)].second
|
||||
: this->vc_role_attrs[lnav::enums::to_underlying(role)].first;
|
||||
}
|
||||
|
||||
attr_t reverse_attrs_for_role(role_t role) const
|
||||
text_attrs reverse_attrs_for_role(role_t role) const
|
||||
{
|
||||
require(role > role_t::VCR_NONE);
|
||||
require(role < role_t::VCR__MAX);
|
||||
@ -223,56 +228,45 @@ public:
|
||||
return this->vc_role_reverse_colors[lnav::enums::to_underlying(role)];
|
||||
}
|
||||
|
||||
int color_for_ident(const char* str, size_t len) const;
|
||||
nonstd::optional<short> color_for_ident(const char* str, size_t len) const;
|
||||
|
||||
int color_for_ident(const string_fragment& sf) const
|
||||
nonstd::optional<short> color_for_ident(const string_fragment& sf) const
|
||||
{
|
||||
return this->color_for_ident(sf.data(), sf.length());
|
||||
}
|
||||
|
||||
attr_t attrs_for_ident(const char* str, size_t len);
|
||||
text_attrs attrs_for_ident(const char* str, size_t len) const;
|
||||
|
||||
attr_t attrs_for_ident(intern_string_t str)
|
||||
text_attrs attrs_for_ident(intern_string_t str) const
|
||||
{
|
||||
return this->attrs_for_ident(str.get(), str.size());
|
||||
}
|
||||
|
||||
attr_t attrs_for_ident(const std::string& str)
|
||||
text_attrs attrs_for_ident(const std::string& str) const
|
||||
{
|
||||
return this->attrs_for_ident(str.c_str(), str.length());
|
||||
}
|
||||
|
||||
int ensure_color_pair(short fg, short bg);
|
||||
|
||||
int ensure_color_pair(nonstd::optional<short> fg,
|
||||
nonstd::optional<short> bg);
|
||||
|
||||
int ensure_color_pair(const styling::color_unit& fg,
|
||||
const styling::color_unit& bg);
|
||||
|
||||
static constexpr short MATCH_COLOR_DEFAULT = -1;
|
||||
static constexpr short MATCH_COLOR_SEMANTIC = -10;
|
||||
|
||||
short match_color(const styling::color_unit& color) const;
|
||||
nonstd::optional<short> match_color(const styling::color_unit& color) const;
|
||||
|
||||
static inline int ansi_color_pair_index(int fg, int bg)
|
||||
{
|
||||
return VC_ANSI_START + ((fg * 8) + bg);
|
||||
}
|
||||
|
||||
static inline attr_t ansi_color_pair(int fg, int bg)
|
||||
{
|
||||
return COLOR_PAIR(ansi_color_pair_index(fg, bg));
|
||||
}
|
||||
|
||||
static const int VC_ANSI_START = 0;
|
||||
static const int VC_ANSI_END = VC_ANSI_START + (8 * 8);
|
||||
|
||||
std::pair<attr_t, attr_t> to_attrs(
|
||||
int& pair_base,
|
||||
std::pair<text_attrs, text_attrs> to_attrs(
|
||||
const lnav_theme& lt,
|
||||
const style_config& sc,
|
||||
const style_config& fallback_sc,
|
||||
lnav_config_listener::error_reporter& reporter);
|
||||
|
||||
std::pair<attr_t, attr_t> vc_level_attrs[LEVEL__MAX];
|
||||
std::pair<text_attrs, text_attrs> vc_level_attrs[LEVEL__MAX];
|
||||
|
||||
short ansi_to_theme_color(short ansi_fg) const
|
||||
{
|
||||
@ -291,17 +285,16 @@ private:
|
||||
/** Private constructor that initializes the member fields. */
|
||||
view_colors();
|
||||
|
||||
view_colors(const view_colors&) = delete;
|
||||
|
||||
struct dyn_pair {
|
||||
int dp_color_pair;
|
||||
};
|
||||
|
||||
/** Map of role IDs to attribute values. */
|
||||
std::pair<attr_t, attr_t>
|
||||
vc_role_colors[lnav::enums::to_underlying(role_t::VCR__MAX)];
|
||||
std::pair<text_attrs, text_attrs>
|
||||
vc_role_attrs[lnav::enums::to_underlying(role_t::VCR__MAX)];
|
||||
/** Map of role IDs to reverse-video attribute values. */
|
||||
attr_t vc_role_reverse_colors[lnav::enums::to_underlying(role_t::VCR__MAX)];
|
||||
text_attrs
|
||||
vc_role_reverse_colors[lnav::enums::to_underlying(role_t::VCR__MAX)];
|
||||
short vc_ansi_to_theme[8];
|
||||
short vc_highlight_colors[HI_COLOR_COUNT];
|
||||
int vc_color_pair_end{0};
|
||||
@ -331,12 +324,11 @@ struct mouse_event {
|
||||
int y = -1)
|
||||
: me_button(button), me_state(state), me_x(x), me_y(y)
|
||||
{
|
||||
memset(&this->me_time, 0, sizeof(this->me_time));
|
||||
}
|
||||
|
||||
mouse_button_t me_button;
|
||||
mouse_button_state_t me_state;
|
||||
struct timeval me_time;
|
||||
struct timeval me_time {};
|
||||
int me_x;
|
||||
int me_y;
|
||||
};
|
||||
|
@ -71,6 +71,7 @@ enum class ln_mode_t : int {
|
||||
SQL,
|
||||
EXEC,
|
||||
USER,
|
||||
BUSY,
|
||||
};
|
||||
|
||||
extern const char* lnav_view_strings[LNV__MAX + 1];
|
||||
|
@ -327,8 +327,7 @@ CREATE TABLE lnav_views (
|
||||
crumb.c_search_placeholder,
|
||||
std::move(poss));
|
||||
}
|
||||
auto ret = top_line_meta_handlers.to_json_string(tlm);
|
||||
to_sqlite(ctx, ret);
|
||||
to_sqlite(ctx, top_line_meta_handlers.to_json_string(tlm));
|
||||
} else {
|
||||
sqlite3_result_null(ctx);
|
||||
}
|
||||
|
@ -159,11 +159,9 @@ template<>
|
||||
struct from_sqlite<string_fragment> {
|
||||
inline string_fragment operator()(int argc, sqlite3_value** val, int argi)
|
||||
{
|
||||
return string_fragment{
|
||||
(const unsigned char*) sqlite3_value_blob(val[argi]),
|
||||
0,
|
||||
sqlite3_value_bytes(val[argi]),
|
||||
};
|
||||
return string_fragment::from_bytes(
|
||||
(const char*) sqlite3_value_blob(val[argi]),
|
||||
sqlite3_value_bytes(val[argi]));
|
||||
}
|
||||
};
|
||||
|
||||
@ -237,14 +235,14 @@ to_sqlite(sqlite3_context* ctx, const char* str)
|
||||
}
|
||||
|
||||
inline void
|
||||
to_sqlite(sqlite3_context* ctx, text_auto_buffer& buf)
|
||||
to_sqlite(sqlite3_context* ctx, text_auto_buffer buf)
|
||||
{
|
||||
auto pair = buf.inner.release();
|
||||
sqlite3_result_text(ctx, pair.first, pair.second, free);
|
||||
}
|
||||
|
||||
inline void
|
||||
to_sqlite(sqlite3_context* ctx, blob_auto_buffer& buf)
|
||||
to_sqlite(sqlite3_context* ctx, blob_auto_buffer buf)
|
||||
{
|
||||
auto pair = buf.inner.release();
|
||||
sqlite3_result_blob(ctx, pair.first, pair.second, free);
|
||||
@ -306,10 +304,10 @@ to_sqlite(sqlite3_context* ctx, nonstd::optional<T>& val)
|
||||
|
||||
template<typename T>
|
||||
inline void
|
||||
to_sqlite(sqlite3_context* ctx, const nonstd::optional<T>& val)
|
||||
to_sqlite(sqlite3_context* ctx, nonstd::optional<T> val)
|
||||
{
|
||||
if (val.has_value()) {
|
||||
to_sqlite(ctx, val.value());
|
||||
to_sqlite(ctx, std::move(val.value()));
|
||||
} else {
|
||||
sqlite3_result_null(ctx);
|
||||
}
|
||||
@ -321,7 +319,7 @@ struct ToSqliteVisitor {
|
||||
template<typename T>
|
||||
void operator()(T&& t) const
|
||||
{
|
||||
to_sqlite(this->tsv_context, std::forward<T>(t));
|
||||
to_sqlite(this->tsv_context, std::move(t));
|
||||
}
|
||||
|
||||
sqlite3_context* tsv_context;
|
||||
@ -329,7 +327,7 @@ struct ToSqliteVisitor {
|
||||
|
||||
template<typename... Types>
|
||||
void
|
||||
to_sqlite(sqlite3_context* ctx, mapbox::util::variant<Types...>& val)
|
||||
to_sqlite(sqlite3_context* ctx, mapbox::util::variant<Types...>&& val)
|
||||
{
|
||||
ToSqliteVisitor visitor(ctx);
|
||||
|
||||
@ -402,7 +400,7 @@ struct sqlite_func_adapter<Return (*)(Args...), f> {
|
||||
try {
|
||||
Return retval = f(from_sqlite<Args>()(argc, argv, Idx)...);
|
||||
|
||||
to_sqlite(context, retval);
|
||||
to_sqlite(context, std::move(retval));
|
||||
} catch (from_sqlite_conversion_error& e) {
|
||||
char buffer[64];
|
||||
|
||||
|
@ -40,7 +40,7 @@ struct flattened_json_string : json_string {
|
||||
};
|
||||
|
||||
inline void
|
||||
to_sqlite(sqlite3_context* ctx, flattened_json_string& val)
|
||||
to_sqlite(sqlite3_context* ctx, flattened_json_string val)
|
||||
{
|
||||
sqlite3_result_text(
|
||||
ctx, (const char*) val.js_content.release(), val.js_len, free);
|
||||
@ -48,7 +48,7 @@ to_sqlite(sqlite3_context* ctx, flattened_json_string& val)
|
||||
}
|
||||
|
||||
inline void
|
||||
to_sqlite(sqlite3_context* ctx, json_string& val)
|
||||
to_sqlite(sqlite3_context* ctx, json_string val)
|
||||
{
|
||||
sqlite3_result_text(
|
||||
ctx, (const char*) val.js_content.release(), val.js_len, free);
|
||||
|
@ -1294,8 +1294,8 @@ yajlpp_parse_context::get_snippet() const
|
||||
if (line_end) {
|
||||
text_len_remaining = (line_end - line_start);
|
||||
}
|
||||
content.append(string_fragment{
|
||||
(const char*) line_start, 0, (int) text_len_remaining});
|
||||
content.append(
|
||||
string_fragment::from_bytes(line_start, text_len_remaining));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -460,6 +460,7 @@ DISTCLEANFILES = \
|
||||
test_pretty_in.* \
|
||||
tmp \
|
||||
unreadable.log \
|
||||
UTF-8-test.md \
|
||||
empty \
|
||||
scripts-empty
|
||||
|
||||
|
@ -69,44 +69,43 @@ main(int argc, char* argv[])
|
||||
al.clear()
|
||||
.with_string("\tLeading tab")
|
||||
.with_attr(string_attr(line_range(0, 1),
|
||||
VC_STYLE.value(A_REVERSE)));
|
||||
VC_STYLE.value(text_attrs{A_REVERSE})));
|
||||
view_curses::mvwattrline(win, y++, 0, al, lr);
|
||||
|
||||
al.clear()
|
||||
.with_string("Tab\twith text")
|
||||
.with_attr(string_attr(line_range(1, 4),
|
||||
VC_STYLE.value(A_REVERSE)));
|
||||
VC_STYLE.value(text_attrs{A_REVERSE})));
|
||||
view_curses::mvwattrline(win, y++, 0, al, lr);
|
||||
|
||||
al.clear()
|
||||
.with_string("Tab\twith text #2")
|
||||
.with_attr(string_attr(line_range(3, 4),
|
||||
VC_STYLE.value(A_REVERSE)));
|
||||
VC_STYLE.value(text_attrs{A_REVERSE})));
|
||||
view_curses::mvwattrline(win, y++, 0, al, lr);
|
||||
|
||||
al.clear()
|
||||
.with_string("Two\ttabs\twith text")
|
||||
.with_attr(string_attr(line_range(4, 6),
|
||||
VC_STYLE.value(A_REVERSE)))
|
||||
VC_STYLE.value(text_attrs{A_REVERSE})))
|
||||
.with_attr(string_attr(line_range(9, 13),
|
||||
VC_STYLE.value(A_REVERSE)));
|
||||
VC_STYLE.value(text_attrs{A_REVERSE})));
|
||||
view_curses::mvwattrline(win, y++, 0, al, lr);
|
||||
|
||||
al.clear()
|
||||
.with_string("Text with mixed attributes.")
|
||||
.with_attr(string_attr(
|
||||
line_range(5, 9),
|
||||
VC_STYLE.value(
|
||||
view_colors::ansi_color_pair(COLOR_RED, COLOR_BLACK))))
|
||||
VC_STYLE.value(text_attrs{0, COLOR_RED, COLOR_BLACK})))
|
||||
.with_attr(string_attr(line_range(7, 12),
|
||||
VC_STYLE.value(A_REVERSE)));
|
||||
VC_STYLE.value(text_attrs{A_REVERSE})));
|
||||
view_curses::mvwattrline(win, y++, 0, al, lr);
|
||||
|
||||
const char* text = u8"Text with unicode ▶ characters";
|
||||
int offset = strstr(text, "char") - text;
|
||||
al.clear().with_string(text).with_attr(
|
||||
string_attr(line_range(offset, offset + 4),
|
||||
VC_STYLE.value(A_REVERSE)));
|
||||
VC_STYLE.value(text_attrs{A_REVERSE})));
|
||||
view_curses::mvwattrline(win, y++, 0, al, lr);
|
||||
|
||||
wmove(win, y, 0);
|
||||
|
@ -40,11 +40,11 @@ public:
|
||||
|
||||
void do_update() override
|
||||
{
|
||||
view_colors& vc = view_colors::singleton();
|
||||
auto& vc = view_colors::singleton();
|
||||
int lpc;
|
||||
|
||||
for (lpc = 0; lpc < 16; lpc++) {
|
||||
int attrs;
|
||||
text_attrs attrs;
|
||||
char label[64];
|
||||
attr_line_t al;
|
||||
line_range lr;
|
||||
@ -64,9 +64,9 @@ public:
|
||||
|
||||
al = "before <123> after";
|
||||
al.with_attr({line_range{8, 11},
|
||||
VC_STYLE.value((int64_t) view_colors::ansi_color_pair(
|
||||
COLOR_CYAN, COLOR_BLACK))});
|
||||
al.with_attr({line_range{8, 11}, VC_STYLE.value(A_REVERSE)});
|
||||
VC_STYLE.value(text_attrs{0, COLOR_CYAN, COLOR_BLACK})});
|
||||
al.with_attr(
|
||||
{line_range{8, 11}, VC_STYLE.value(text_attrs{A_REVERSE})});
|
||||
test_colors::mvwattrline(this->tc_window, lpc, 0, al, lr);
|
||||
};
|
||||
|
||||
|
@ -926,6 +926,8 @@ EXPECTED_FILES = \
|
||||
$(srcdir)/%reldir%/test_text_file.sh_5b51b55dff7332c5bee2c9b797c401c5614d574a.out \
|
||||
$(srcdir)/%reldir%/test_text_file.sh_87943c6be50d701a03e901f16493314c839af1ab.err \
|
||||
$(srcdir)/%reldir%/test_text_file.sh_87943c6be50d701a03e901f16493314c839af1ab.out \
|
||||
$(srcdir)/%reldir%/test_text_file.sh_ac872aadda29b9a824361a2c711d62ec1c75d40f.err \
|
||||
$(srcdir)/%reldir%/test_text_file.sh_ac872aadda29b9a824361a2c711d62ec1c75d40f.out \
|
||||
$(srcdir)/%reldir%/test_text_file.sh_c2a346ca1da2da4346f1d310212e166767993ce9.err \
|
||||
$(srcdir)/%reldir%/test_text_file.sh_c2a346ca1da2da4346f1d310212e166767993ce9.out \
|
||||
$()
|
||||
|
@ -1,4 +1,4 @@
|
||||
[7m Thu Nov 03 09:20:00 [0m[1m[7m 1 normal 2 errors 0 warnings [0m 0 marks
|
||||
[7m Thu Nov 03 09:20:00 [0m[1m[7m[31m 1 normal 2 errors 0 warnings [0m 0 marks
|
||||
[7m Thu Nov 03 09:45:00 [0m 1 normal 0 errors 0 warnings 0 marks
|
||||
[1m[7m Fri Feb 03 09:20:00 [0m 0 normal 1 errors 0 warnings 0 marks
|
||||
[1m[7m[31m Fri Feb 03 09:20:00 [0m 0 normal 1 errors 0 warnings 0 marks
|
||||
[7m Wed Jan 03 09:20:00 [0m 1 normal 0 errors 0 warnings 0 marks
|
||||
|
@ -1,2 +1,2 @@
|
||||
[7m Sat Nov 03 09:20:0[0m[1m[7m0 1 normal 2 errors [0m[7m 0 warnings [0m 1 marks
|
||||
[7m Sat Nov 03 09:20:0[0m[1m[7m[31m0 1 normal 2 errors [0m[7m[34m 0 warnings [0m 1 marks
|
||||
[7m Sat Nov 03 09:45:0[0m0 1 normal 0 errors 0 warnings 0 marks
|
||||
|
@ -1 +1 @@
|
||||
[7m [0m[1m[7mS[0mat Nov 03 00:00:00 2 normal 2 errors 0 warnings 0 marks
|
||||
[7m [0m[1m[7m[31mS[0mat Nov 03 00:00:00 2 normal 2 errors 0 warnings 0 marks
|
||||
|
@ -1 +1 @@
|
||||
[7m [0m[1m[7mS[0mat Nov 03 08:00:00 2 normal 2 errors 0 warnings 0 marks
|
||||
[7m [0m[1m[7m[31mS[0mat Nov 03 08:00:00 2 normal 2 errors 0 warnings 0 marks
|
||||
|
@ -1 +1 @@
|
||||
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to readlink(path) failed","attrs":[{"start":8,"end":16,"type":"role","value":45},{"start":17,"end":21,"type":"role","value":44},{"start":8,"end":22,"type":"role","value":58}]},"reason":{"str":"unable to stat path: non-existent-link -- No such file or directory","attrs":[]},"snippets":[],"help":{"str":"","attrs":[]}}
|
||||
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to readlink(path) failed","attrs":[{"start":8,"end":16,"type":"role","value":46},{"start":17,"end":21,"type":"role","value":45},{"start":8,"end":22,"type":"role","value":59}]},"reason":{"str":"unable to stat path: non-existent-link -- No such file or directory","attrs":[]},"snippets":[],"help":{"str":"","attrs":[]}}
|
||||
|
@ -1 +1 @@
|
||||
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to realpath(path) failed","attrs":[{"start":8,"end":16,"type":"role","value":45},{"start":17,"end":21,"type":"role","value":44},{"start":8,"end":22,"type":"role","value":58}]},"reason":{"str":"Could not get real path for non-existent-path -- No such file or directory","attrs":[]},"snippets":[],"help":{"str":"","attrs":[]}}
|
||||
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to realpath(path) failed","attrs":[{"start":8,"end":16,"type":"role","value":46},{"start":17,"end":21,"type":"role","value":45},{"start":8,"end":22,"type":"role","value":59}]},"reason":{"str":"Could not get real path for non-existent-path -- No such file or directory","attrs":[]},"snippets":[],"help":{"str":"","attrs":[]}}
|
||||
|
@ -1 +1 @@
|
||||
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to json_contains(json, value) failed","attrs":[{"start":8,"end":21,"type":"role","value":45},{"start":22,"end":26,"type":"role","value":44},{"start":28,"end":33,"type":"role","value":44},{"start":8,"end":34,"type":"role","value":58}]},"reason":{"str":"parse error: premature EOF\n [\"hi\", \"bye\", \"solong]\n (right here) ------^","attrs":[]},"snippets":[],"help":{"str":"","attrs":[]}}
|
||||
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to json_contains(json, value) failed","attrs":[{"start":8,"end":21,"type":"role","value":46},{"start":22,"end":26,"type":"role","value":45},{"start":28,"end":33,"type":"role","value":45},{"start":8,"end":34,"type":"role","value":59}]},"reason":{"str":"parse error: premature EOF\n [\"hi\", \"bye\", \"solong]\n (right here) ------^","attrs":[]},"snippets":[],"help":{"str":"","attrs":[]}}
|
||||
|
@ -1 +1 @@
|
||||
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to regexp_match(re, str) failed","attrs":[{"start":8,"end":20,"type":"role","value":45},{"start":21,"end":23,"type":"role","value":44},{"start":25,"end":28,"type":"role","value":44},{"start":8,"end":29,"type":"role","value":58}]},"reason":{"str":"regular expression does not have any captures","attrs":[]},"snippets":[],"help":{"str":"","attrs":[]}}
|
||||
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to regexp_match(re, str) failed","attrs":[{"start":8,"end":20,"type":"role","value":46},{"start":21,"end":23,"type":"role","value":45},{"start":25,"end":28,"type":"role","value":45},{"start":8,"end":29,"type":"role","value":59}]},"reason":{"str":"regular expression does not have any captures","attrs":[]},"snippets":[],"help":{"str":"","attrs":[]}}
|
||||
|
@ -1 +1 @@
|
||||
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to timeslice(time, slice) failed","attrs":[{"start":8,"end":17,"type":"role","value":45},{"start":18,"end":22,"type":"role","value":44},{"start":24,"end":29,"type":"role","value":44},{"start":8,"end":30,"type":"role","value":58}]},"reason":{"str":"unable to parse time slice value: blah -- Unrecognized input","attrs":[]},"snippets":[],"help":{"str":"","attrs":[]}}
|
||||
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to timeslice(time, slice) failed","attrs":[{"start":8,"end":17,"type":"role","value":46},{"start":18,"end":22,"type":"role","value":45},{"start":24,"end":29,"type":"role","value":45},{"start":8,"end":30,"type":"role","value":59}]},"reason":{"str":"unable to parse time slice value: blah -- Unrecognized input","attrs":[]},"snippets":[],"help":{"str":"","attrs":[]}}
|
||||
|
@ -1 +1 @@
|
||||
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to timeslice(time, slice) failed","attrs":[{"start":8,"end":17,"type":"role","value":45},{"start":18,"end":22,"type":"role","value":44},{"start":24,"end":29,"type":"role","value":44},{"start":8,"end":30,"type":"role","value":58}]},"reason":{"str":"no time slice value given","attrs":[]},"snippets":[],"help":{"str":"","attrs":[]}}
|
||||
error: sqlite3_exec failed -- lnav-error:{"level":"error","message":{"str":"call to timeslice(time, slice) failed","attrs":[{"start":8,"end":17,"type":"role","value":46},{"start":18,"end":22,"type":"role","value":45},{"start":24,"end":29,"type":"role","value":45},{"start":8,"end":30,"type":"role","value":59}]},"reason":{"str":"no time slice value given","attrs":[]},"snippets":[],"help":{"str":"","attrs":[]}}
|
||||
|
@ -0,0 +1,74 @@
|
||||
[1m[31m✘ error[0m: unable to parse markdown file
|
||||
[1m[31mreason[0m: file has invalid UTF-8 at offset 4461: Expecting bytes in the following ranges: 00..7F C2..F4.
|
||||
|
||||
UTF-8 decoder capability and stress test
|
||||
----------------------------------------
|
||||
|
||||
Markus Kuhn <http://www.cl.cam.ac.uk/~mgk25/> - 2015-08-28 - CC BY 4.0
|
||||
|
||||
This test file can help you examine, how your UTF-8 decoder handles
|
||||
various types of correct, malformed, or otherwise interesting UTF-8
|
||||
sequences. This file is not meant to be a conformance test. It does
|
||||
not prescribe any particular outcome. Therefore, there is no way to
|
||||
[35m"pass"[0m or [35m"fail"[0m this test file, even though the text does suggest a
|
||||
preferable decoder behaviour at some places. Its aim is, instead, to
|
||||
help you think about, and test, the behaviour of your UTF-8 decoder on a
|
||||
systematic collection of unusual inputs. Experience so far suggests
|
||||
that most first-time authors of UTF-8 decoders find at least one
|
||||
serious problem in their decoder using this file.
|
||||
|
||||
The test lines below cover boundary conditions, malformed UTF-8
|
||||
sequences, as well as correctly encoded UTF-8 sequences of Unicode code
|
||||
points that should never occur in a correct UTF-8 file.
|
||||
|
||||
According to ISO 10646-1:2000, sections D.7 and 2.3c, a device
|
||||
receiving UTF-8 shall interpret a "malformed sequence in the same way
|
||||
that it interprets a character that is outside the adopted subset" and
|
||||
"characters that are not within the adopted subset shall be indicated
|
||||
to the user" by a receiving device. One commonly used approach in
|
||||
UTF-8 decoders is to replace any malformed UTF-8 sequence by a
|
||||
replacement character (U+FFFD), which looks a bit like an inverted
|
||||
question mark, or a similar symbol. It might be a good idea to
|
||||
visually distinguish a malformed UTF-8 sequence from a correctly
|
||||
encoded Unicode character that is just not available in the current
|
||||
font but otherwise fully legal, even though ISO 10646-1 doesn't
|
||||
mandate this. In any case, just ignoring malformed sequences or
|
||||
unavailable characters does not conform to ISO 10646, will make
|
||||
debugging more difficult, and can lead to user confusion.
|
||||
|
||||
Please check, whether a malformed UTF-8 sequence is (1) represented at
|
||||
all, (2) represented by exactly one single replacement character (or
|
||||
equivalent signal), and (3) the following quotation mark after an
|
||||
illegal UTF-8 sequence is correctly displayed, i.e. proper
|
||||
resynchronization takes place immediately after any malformed
|
||||
sequence. This file says [35m"THE END"[0m in the last line, so if you don't
|
||||
see that, your decoder crashed somehow before, which should always be
|
||||
cause for concern.
|
||||
|
||||
All lines in this file are exactly 79 characters long (plus the line
|
||||
feed). In addition, all lines end with [35m"|"[0m, except for the two test
|
||||
lines 2.1.1 and 2.2.1, which contain non-printable ASCII controls
|
||||
U+0000 and U+007F. If you display this file with a fixed-width font,
|
||||
these [35m"|"[0m characters should all line up in column 79 (right margin).
|
||||
This allows you to test quickly, whether your UTF-8 decoder finds the
|
||||
correct number of characters in every line, that is whether each
|
||||
malformed sequences is replaced by a single replacement character.
|
||||
|
||||
Note that, as an alternative to the notion of malformed sequence used
|
||||
here, it is also a perfectly acceptable (and in some situations even
|
||||
preferable) solution to represent each individual byte of a malformed
|
||||
sequence with a replacement character. If you follow this strategy in
|
||||
your decoder, then please ignore the [35m"|"[0m column.
|
||||
|
||||
|
||||
Here come the tests: |
|
||||
|
|
||||
1 Some correct UTF-8 text |
|
||||
|
|
||||
You should see the Greek word [35m'kosme'[0m: [35m"κόσμε"[0m |
|
||||
|
|
||||
2 Boundary condition test cases |
|
||||
|
|
||||
2.1 First possible sequence of a certain length |
|
||||
|
|
||||
2.1.1 1 byte (U-00000000): "
|
@ -60,11 +60,12 @@ main(int argc, char* argv[])
|
||||
|
||||
assert(sa[0].sa_range.lr_start == 5);
|
||||
assert(sa[0].sa_range.lr_end == 7);
|
||||
assert(sa[0].sa_type == &VC_BACKGROUND);
|
||||
assert(sa[0].sa_value.get<int64_t>() == COLOR_BLUE);
|
||||
assert(sa[0].sa_type == &VC_STYLE);
|
||||
assert(sa[0].sa_value.get<text_attrs>().ta_bg_color.value() == COLOR_BLUE);
|
||||
|
||||
assert(sa[1].sa_range.lr_start == 7);
|
||||
assert(sa[1].sa_range.lr_end == 12);
|
||||
assert(sa[1].sa_type == &VC_FOREGROUND);
|
||||
assert(sa[1].sa_value.get<int64_t>() == COLOR_YELLOW);
|
||||
assert(sa[1].sa_type == &VC_STYLE);
|
||||
assert(sa[1].sa_value.get<text_attrs>().ta_fg_color.value()
|
||||
== COLOR_YELLOW);
|
||||
}
|
||||
|
@ -14,3 +14,7 @@ run_cap_test ${lnav_test} -n \
|
||||
|
||||
run_cap_test ${lnav_test} -n \
|
||||
${top_srcdir}/src/log_level.cc
|
||||
|
||||
cp ${test_dir}/UTF-8-test.txt UTF-8-test.md
|
||||
run_cap_test ${lnav_test} -n \
|
||||
UTF-8-test.md
|
||||
|
@ -14,13 +14,34 @@ OSC Set window title: LOG
|
||||
S -1 ┋ ┋
|
||||
A └ normal, normal, normal
|
||||
CSI Erase all
|
||||
S 1 ┋ Thu Jun 06 1 :: :: LOG ┋
|
||||
A └ fg(#c0c0c0), bg(#008080)
|
||||
S 2 ┋ x┋
|
||||
A ···············································································├ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 1 ┋ 2013-06-06T12:13:20 PDT ┋
|
||||
A └ bg(#008080)
|
||||
S 16 ┋ Files :: Text Filters :: Press q to exit ┋
|
||||
A └ bg(#000080), bold │ ││
|
||||
A ·└ fg(#008080), bg(#000080), underline ││
|
||||
A ··└ normal, bg(#000080), bold ││
|
||||
A ·······└ normal, fg(#000000), bg(#000080) ││
|
||||
A ········└ fg(#000080), bg(#c0c0c0) ││
|
||||
A ·········└ fg(#000000), bg(#c0c0c0), bold ││
|
||||
A ··········└ fg(#800080), bg(#c0c0c0), underline ││
|
||||
A ···········└ normal, fg(#000000), bg(#c0c0c0), bold ││
|
||||
A ·······················└ normal, fg(#000000), bg(#c0c0c0) ││
|
||||
A ······································································└ bold
|
||||
A ·······································································└ normal, fg(#000000), bg(#c0c0c0)
|
||||
S 17 ┋ ┋
|
||||
S 23 ┋ L0 0% ?:View Help ┋
|
||||
A └ normal, bg(#008080)
|
||||
S 18 ┋ ┋
|
||||
A └ normal, normal
|
||||
S 1 ┋ Press ENTER to focus on the breadcrumb bar ┋
|
||||
A ·····································└ bg(#008080) │
|
||||
A ···············································································└ carriage-return
|
||||
S 2 ┋ LOG ❭ ┋
|
||||
A └ fg(#000000), bg(#000080), bold
|
||||
A ·····└ normal, fg(#008080), bg(#c0c0c0)
|
||||
A ······└ fg(#000000), bg(#c0c0c0)
|
||||
S 3 ┋ x┋
|
||||
A ···············································································├ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 4 ┋ x┋
|
||||
@ -59,39 +80,13 @@ A ····································
|
||||
S 15 ┋ x┋
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 16 ┋ x┋
|
||||
S 18 ┋ x┋
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 17 ┋ lqqqq No log messages; Files: 0; Error rate: 0.00/min; Time span: None qqqqk x┋
|
||||
A └----┛ alt │ │ │ │ │ │ │ ││ │││
|
||||
A ·······························└ bold │ │ │ │ ││ │││
|
||||
A ·································└ normal │ │ │ │ ││ │││
|
||||
A ···································└ fg(#800000), bold │ ││ │││
|
||||
A ·············································└ normal │ ││ │││
|
||||
A ···············································└ bold │ ││ │││
|
||||
A ···················································└ normal │ ││ │││
|
||||
A ····································································└ bold │││
|
||||
A ········································································└ normal│
|
||||
A ·········································································├ bold││
|
||||
A └----┛ alt
|
||||
A ··············································································└ normal
|
||||
S 19 ┋ x┋
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 18 ┋ Files :: Text Filters :: Press q to exit ┋
|
||||
A └ fg(#c0c0c0), bg(#000080), bold ││
|
||||
A ·└ fg(#008080), bg(#000080), underline ││
|
||||
A ··└ normal, fg(#c0c0c0), bg(#000080), bold ││
|
||||
A ·······└ normal, fg(#c0c0c0), bg(#000080) ││
|
||||
A ········└ fg(#000080), bg(#c0c0c0) ││
|
||||
A ·········└ fg(#000000), bg(#c0c0c0), bold ││
|
||||
A ··········└ fg(#800080), bg(#c0c0c0), underline ││
|
||||
A ···········└ normal, fg(#000000), bg(#c0c0c0), bold ││
|
||||
A ·······················└ normal, fg(#000000), bg(#c0c0c0) ││
|
||||
A ······································································└ bold
|
||||
A ·······································································└ normal, fg(#000000), bg(#c0c0c0)
|
||||
S 19 ┋ ┋
|
||||
S 20 ┋ x┋
|
||||
A ···············································································├ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 21 ┋ x┋
|
||||
@ -100,59 +95,61 @@ A ····································
|
||||
S 22 ┋ x┋
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 22 ┋ ┋
|
||||
A └ normal
|
||||
OSC Set window title: HELP
|
||||
S 2 ┋ HELP ❭⋯❭ ┋
|
||||
A ·└ fg(#000000), bg(#000080), bold
|
||||
A ······└ normal, fg(#008080), bg(#c0c0c0)
|
||||
A ·······└ fg(#000000), bg(#c0c0c0)
|
||||
A ········└ fg(#008080), bg(#c0c0c0)
|
||||
S 3 ┋ x┋
|
||||
A ···············································································└ normal, fg(#000000)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 4 ┋lnav ┋
|
||||
A └ fg(#000000), normal, underline
|
||||
A ····└ carriage-return
|
||||
S 6 ┋A fancy log file viewer for the terminal. ┋
|
||||
A └ normal │
|
||||
A ·········································└ carriage-return
|
||||
S 8 ┋Overview ┋
|
||||
A └ underline
|
||||
A ········└ carriage-return
|
||||
S 10 ┋The Logfile Navigator, lnav, is an enhanced log file viewer that takes ┋
|
||||
A └ normal │ │ │
|
||||
A ·······················└ bold │
|
||||
A ···························└ normal │
|
||||
A ······································································└ carriage-return
|
||||
S 11 ┋advantage of any semantic information that can be gleaned from the ┋
|
||||
A ··································································└ carriage-return
|
||||
S 12 ┋files being viewed, such as timestamps and log levels. Using this ┋
|
||||
A ·································································└ carriage-return
|
||||
S 13 ┋extra semantic information, lnav can do things like interleaving ┋
|
||||
A ································································└ carriage-return
|
||||
S 14 ┋messages from different files, generate histograms of messages over ┋
|
||||
A ···································································└ carriage-return
|
||||
S 15 ┋time, and providing hotkeys for navigating through the file. It is ┋
|
||||
A ··································································└ carriage-return
|
||||
S 16 ┋hoped that these features will allow the user to quickly and x┋
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 17 ┋efficiently zero in on problems. x┋
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 19 ┋Opening Paths/URLs ┋
|
||||
A └ underline │
|
||||
A ··················└ carriage-return
|
||||
S 21 ┋The main arguments to lnav are the local/remote files, directories, ┋
|
||||
A └ normal │
|
||||
A ···································································└ carriage-return
|
||||
S 22 ┋glob patterns, or URLs to be viewed. If no arguments are given, the ┋
|
||||
A ···································································└ carriage-return
|
||||
S 23 ┋ L0 0% ?:View Help ┋
|
||||
A └ fg(#000000), bg(#c0c0c0)
|
||||
S 22 ┋ ┋
|
||||
A └ normal, normal
|
||||
OSC Set window title: HELP
|
||||
S 1 ┋ Thu Jun 06 1 :: :: HELP ┋
|
||||
A └ fg(#000000), bg(#c0c0c0) │││ │││
|
||||
A ················································└ fg(#008080), bg(#c0c0c0)
|
||||
A ·················································└ fg(#c0c0c0), bg(#008080)
|
||||
A ··················································└ fg(#000000), bg(#008080)
|
||||
A ······································································└ fg(#000080), bg(#008080)
|
||||
A ·······································································└ fg(#008080), bg(#000080)
|
||||
A ········································································└ fg(#c0c0c0), bg(#000080), bold
|
||||
S 2 ┋ x┋
|
||||
A ···············································································└ normal, fg(#000000), bg(#c0c0c0)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 3 ┋ lnav - A fancy log file viewer ┋
|
||||
A ··└ fg(#000000), bg(#c0c0c0), normal
|
||||
A ································└ carriage-return
|
||||
S 5 ┋DESCRIPTION ┋
|
||||
A ···········└ carriage-return
|
||||
S 6 ┋=========== ┋
|
||||
A ···········└ carriage-return
|
||||
S 8 ┋The log file navigator, lnav, is an enhanced log file viewer that ┋
|
||||
A ·································································└ carriage-return
|
||||
S 9 ┋takes advantage of any semantic information that can be gleaned from ┋
|
||||
A ····································································└ carriage-return
|
||||
S 10 ┋the files being viewed, such as timestamps and log levels. Using this ┋
|
||||
A ······································································└ carriage-return
|
||||
S 11 ┋extra semantic information, lnav can do things like interleaving ┋
|
||||
A ································································└ carriage-return
|
||||
S 12 ┋messages from different files, generate histograms of messages over ┋
|
||||
A ···································································└ carriage-return
|
||||
S 13 ┋time, and providing hotkeys for navigating through the file. It is ┋
|
||||
A ···································································└ carriage-return
|
||||
S 14 ┋hoped that these features will allow the user to quickly and ┋
|
||||
A ····························································└ carriage-return
|
||||
S 15 ┋efficiently zero in on problems. ┋
|
||||
A ································└ carriage-return
|
||||
S 17 ┋ ┋
|
||||
A ··············································································└ carriage-return
|
||||
S 18 ┋OPENING PATHS/URLs x┋
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 19 ┋================== x┋
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 21 ┋The main arguments to lnav are the files, directories, glob patterns, ┋
|
||||
A ·····································································└ carriage-return
|
||||
S 22 ┋or URLs to be viewed. If no arguments are given, the default syslog ┋
|
||||
S 24 ┋ Press e/E to move forward/backward through error messags ┋
|
||||
A ·······················└ normal││ │
|
||||
A ·····························└ bold │
|
||||
A ······························└ normal │
|
||||
A ·······························└ bold │
|
||||
@ -167,65 +164,62 @@ A └ normal
|
||||
K 3a
|
||||
CSI Erase Below
|
||||
CSI Erase Below
|
||||
S 24 ┋ ┋
|
||||
S 24 ┋: ┋
|
||||
A └ normal
|
||||
A ·└ normal
|
||||
S 23 ┋ Enter an lnav command: (Press CTRL+] to abort) ┋
|
||||
A ·└ fg(#000000), bg(#c0c0c0) │ │
|
||||
A ·······························└ bold│
|
||||
A ·····································└ normal, fg(#000000), bg(#c0c0c0)
|
||||
S 23 ┋ ┋
|
||||
A ···································································└ carriage-return
|
||||
S 24 ┋: ┋
|
||||
A └ normal
|
||||
A ·└ normal
|
||||
K 65
|
||||
S 24 ┋ e ┋
|
||||
A ·└ normal, normal
|
||||
A ··└ normal
|
||||
K 63
|
||||
K 65
|
||||
S 24 ┋ c ┋
|
||||
A ···└ normal
|
||||
K 68
|
||||
K 63
|
||||
S 24 ┋ h ┋
|
||||
A ····└ normal
|
||||
K 6f
|
||||
K 68
|
||||
S 24 ┋ o ┋
|
||||
A ·····└ normal
|
||||
K 20
|
||||
K 6f
|
||||
S 24 ┋ echo ┋
|
||||
A ·····└ backspace
|
||||
A ····└ backspace
|
||||
A ···└ backspace
|
||||
A ··└ backspace
|
||||
A ·└ fg(#000080), bold
|
||||
A ·└ fg(#000080)
|
||||
A ······└ normal, normal
|
||||
K 68
|
||||
K 20
|
||||
S 24 ┋ h ┋
|
||||
A ·······└ normal
|
||||
K 69
|
||||
K 68
|
||||
S 24 ┋ i ┋
|
||||
A ········└ normal
|
||||
K 0d
|
||||
K 69
|
||||
S 24 ┋ ┋
|
||||
A ········└ carriage-return
|
||||
CSI Erase Below
|
||||
S 24 ┋ ┋
|
||||
S 24 ┋hi ┋
|
||||
A └ normal
|
||||
A ··└ normal
|
||||
K 0d
|
||||
S 23 ┋ L0 0% ┋
|
||||
A ··└ backspace
|
||||
A ·└ fg(#000000), bg(#c0c0c0)
|
||||
S 23 ┋ ?:View Help ┋
|
||||
A ···································································└ carriage-return
|
||||
S 24 ┋✔ hi ┋
|
||||
A └ normal, fg(#008000)
|
||||
A ·└ normal
|
||||
A ····└ carriage-return
|
||||
A └ normal
|
||||
K 71
|
||||
OSC Set window title: LOG
|
||||
S 1 ┋ LOG ┋
|
||||
A ···········································································└ fg(#c0c0c0), bg(#000080), bold
|
||||
A ···············································································└ carriage-return
|
||||
S 24 ┋ ┋
|
||||
A └ normal, normal
|
||||
A ··└ normal, normal
|
||||
K 71
|
||||
S 24 ┋ⓘ info: executing SQL statement, press CTRL+] to cancel ┋
|
||||
A ··└ carriage-return │ │ │
|
||||
A ·······································└ fg(#800080), bold, underline
|
||||
A ·············································└ normal │
|
||||
A ·······················································└ carriage-return
|
||||
A └ normal
|
||||
OSC Set window title: LOG
|
||||
CSI Erase all
|
||||
CSI Use normal screen buffer
|
||||
CTRL restore cursor
|
||||
|
@ -14,13 +14,34 @@ OSC Set window title: LOG
|
||||
S -1 ┋ ┋
|
||||
A └ normal, normal, normal
|
||||
CSI Erase all
|
||||
S 1 ┋ Thu Jun 06 1 :: :: LOG ┋
|
||||
A └ fg(#c0c0c0), bg(#008080)
|
||||
S 2 ┋ x┋
|
||||
A ···············································································├ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 1 ┋ 2013-06-06T12:13:20 PDT ┋
|
||||
A └ bg(#008080)
|
||||
S 16 ┋ Files :: Text Filters :: Press q to exit ┋
|
||||
A └ bg(#000080), bold │ ││
|
||||
A ·└ fg(#008080), bg(#000080), underline ││
|
||||
A ··└ normal, bg(#000080), bold ││
|
||||
A ·······└ normal, fg(#000000), bg(#000080) ││
|
||||
A ········└ fg(#000080), bg(#c0c0c0) ││
|
||||
A ·········└ fg(#000000), bg(#c0c0c0), bold ││
|
||||
A ··········└ fg(#800080), bg(#c0c0c0), underline ││
|
||||
A ···········└ normal, fg(#000000), bg(#c0c0c0), bold ││
|
||||
A ·······················└ normal, fg(#000000), bg(#c0c0c0) ││
|
||||
A ······································································└ bold
|
||||
A ·······································································└ normal, fg(#000000), bg(#c0c0c0)
|
||||
S 17 ┋ ┋
|
||||
S 23 ┋ L0 0% ?:View Help ┋
|
||||
A └ normal, bg(#008080)
|
||||
S 18 ┋ ┋
|
||||
A └ normal, normal
|
||||
S 1 ┋ Press ENTER to focus on the breadcrumb bar ┋
|
||||
A ·····································└ bg(#008080) │
|
||||
A ···············································································└ carriage-return
|
||||
S 2 ┋ LOG ❭ ┋
|
||||
A └ fg(#000000), bg(#000080), bold
|
||||
A ·····└ normal, fg(#008080), bg(#c0c0c0)
|
||||
A ······└ fg(#000000), bg(#c0c0c0)
|
||||
S 3 ┋ x┋
|
||||
A ···············································································├ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 4 ┋ x┋
|
||||
@ -59,39 +80,13 @@ A ····································
|
||||
S 15 ┋ x┋
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 16 ┋ x┋
|
||||
S 18 ┋ x┋
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 17 ┋ lqqqq No log messages; Files: 0; Error rate: 0.00/min; Time span: None qqqqk x┋
|
||||
A └----┛ alt │ │ │ │ │ │ │ ││ │││
|
||||
A ·······························└ bold │ │ │ │ ││ │││
|
||||
A ·································└ normal │ │ │ │ ││ │││
|
||||
A ···································└ fg(#800000), bold │ ││ │││
|
||||
A ·············································└ normal │ ││ │││
|
||||
A ···············································└ bold │ ││ │││
|
||||
A ···················································└ normal │ ││ │││
|
||||
A ····································································└ bold │││
|
||||
A ········································································└ normal│
|
||||
A ·········································································├ bold││
|
||||
A └----┛ alt
|
||||
A ··············································································└ normal
|
||||
S 19 ┋ x┋
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 18 ┋ Files :: Text Filters :: Press q to exit ┋
|
||||
A └ fg(#c0c0c0), bg(#000080), bold ││
|
||||
A ·└ fg(#008080), bg(#000080), underline ││
|
||||
A ··└ normal, fg(#c0c0c0), bg(#000080), bold ││
|
||||
A ·······└ normal, fg(#c0c0c0), bg(#000080) ││
|
||||
A ········└ fg(#000080), bg(#c0c0c0) ││
|
||||
A ·········└ fg(#000000), bg(#c0c0c0), bold ││
|
||||
A ··········└ fg(#800080), bg(#c0c0c0), underline ││
|
||||
A ···········└ normal, fg(#000000), bg(#c0c0c0), bold ││
|
||||
A ·······················└ normal, fg(#000000), bg(#c0c0c0) ││
|
||||
A ······································································└ bold
|
||||
A ·······································································└ normal, fg(#000000), bg(#c0c0c0)
|
||||
S 19 ┋ ┋
|
||||
S 20 ┋ x┋
|
||||
A ···············································································├ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 21 ┋ x┋
|
||||
@ -100,59 +95,61 @@ A ····································
|
||||
S 22 ┋ x┋
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 22 ┋ ┋
|
||||
A └ normal
|
||||
OSC Set window title: HELP
|
||||
S 2 ┋ HELP ❭⋯❭ ┋
|
||||
A ·└ fg(#000000), bg(#000080), bold
|
||||
A ······└ normal, fg(#008080), bg(#c0c0c0)
|
||||
A ·······└ fg(#000000), bg(#c0c0c0)
|
||||
A ········└ fg(#008080), bg(#c0c0c0)
|
||||
S 3 ┋ x┋
|
||||
A ···············································································└ normal, fg(#000000)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 4 ┋lnav ┋
|
||||
A └ fg(#000000), normal, underline
|
||||
A ····└ carriage-return
|
||||
S 6 ┋A fancy log file viewer for the terminal. ┋
|
||||
A └ normal │
|
||||
A ·········································└ carriage-return
|
||||
S 8 ┋Overview ┋
|
||||
A └ underline
|
||||
A ········└ carriage-return
|
||||
S 10 ┋The Logfile Navigator, lnav, is an enhanced log file viewer that takes ┋
|
||||
A └ normal │ │ │
|
||||
A ·······················└ bold │
|
||||
A ···························└ normal │
|
||||
A ······································································└ carriage-return
|
||||
S 11 ┋advantage of any semantic information that can be gleaned from the ┋
|
||||
A ··································································└ carriage-return
|
||||
S 12 ┋files being viewed, such as timestamps and log levels. Using this ┋
|
||||
A ·································································└ carriage-return
|
||||
S 13 ┋extra semantic information, lnav can do things like interleaving ┋
|
||||
A ································································└ carriage-return
|
||||
S 14 ┋messages from different files, generate histograms of messages over ┋
|
||||
A ···································································└ carriage-return
|
||||
S 15 ┋time, and providing hotkeys for navigating through the file. It is ┋
|
||||
A ··································································└ carriage-return
|
||||
S 16 ┋hoped that these features will allow the user to quickly and x┋
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 17 ┋efficiently zero in on problems. x┋
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 19 ┋Opening Paths/URLs ┋
|
||||
A └ underline │
|
||||
A ··················└ carriage-return
|
||||
S 21 ┋The main arguments to lnav are the local/remote files, directories, ┋
|
||||
A └ normal │
|
||||
A ···································································└ carriage-return
|
||||
S 22 ┋glob patterns, or URLs to be viewed. If no arguments are given, the ┋
|
||||
A ···································································└ carriage-return
|
||||
S 23 ┋ L0 0% ?:View Help ┋
|
||||
A └ fg(#000000), bg(#c0c0c0)
|
||||
S 22 ┋ ┋
|
||||
A └ normal, normal
|
||||
OSC Set window title: HELP
|
||||
S 1 ┋ Thu Jun 06 1 :: :: HELP ┋
|
||||
A └ fg(#000000), bg(#c0c0c0) │││ │││
|
||||
A ················································└ fg(#008080), bg(#c0c0c0)
|
||||
A ·················································└ fg(#c0c0c0), bg(#008080)
|
||||
A ··················································└ fg(#000000), bg(#008080)
|
||||
A ······································································└ fg(#000080), bg(#008080)
|
||||
A ·······································································└ fg(#008080), bg(#000080)
|
||||
A ········································································└ fg(#c0c0c0), bg(#000080), bold
|
||||
S 2 ┋ x┋
|
||||
A ···············································································└ normal, fg(#000000), bg(#c0c0c0)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 3 ┋ lnav - A fancy log file viewer ┋
|
||||
A ··└ fg(#000000), bg(#c0c0c0), normal
|
||||
A ································└ carriage-return
|
||||
S 5 ┋DESCRIPTION ┋
|
||||
A ···········└ carriage-return
|
||||
S 6 ┋=========== ┋
|
||||
A ···········└ carriage-return
|
||||
S 8 ┋The log file navigator, lnav, is an enhanced log file viewer that ┋
|
||||
A ·································································└ carriage-return
|
||||
S 9 ┋takes advantage of any semantic information that can be gleaned from ┋
|
||||
A ····································································└ carriage-return
|
||||
S 10 ┋the files being viewed, such as timestamps and log levels. Using this ┋
|
||||
A ······································································└ carriage-return
|
||||
S 11 ┋extra semantic information, lnav can do things like interleaving ┋
|
||||
A ································································└ carriage-return
|
||||
S 12 ┋messages from different files, generate histograms of messages over ┋
|
||||
A ···································································└ carriage-return
|
||||
S 13 ┋time, and providing hotkeys for navigating through the file. It is ┋
|
||||
A ···································································└ carriage-return
|
||||
S 14 ┋hoped that these features will allow the user to quickly and ┋
|
||||
A ····························································└ carriage-return
|
||||
S 15 ┋efficiently zero in on problems. ┋
|
||||
A ································└ carriage-return
|
||||
S 17 ┋ ┋
|
||||
A ··············································································└ carriage-return
|
||||
S 18 ┋OPENING PATHS/URLs x┋
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 19 ┋================== x┋
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 21 ┋The main arguments to lnav are the files, directories, glob patterns, ┋
|
||||
A ·····································································└ carriage-return
|
||||
S 22 ┋or URLs to be viewed. If no arguments are given, the default syslog ┋
|
||||
S 24 ┋ Press e/E to move forward/backward through error messags ┋
|
||||
A ·······················└ normal││ │
|
||||
A ·····························└ bold │
|
||||
A ······························└ normal │
|
||||
A ·······························└ bold │
|
||||
@ -166,11 +163,13 @@ A ····································
|
||||
A └ normal
|
||||
K 71
|
||||
OSC Set window title: LOG
|
||||
S 1 ┋ LOG ┋
|
||||
A ···········································································└ fg(#c0c0c0), bg(#000080), bold
|
||||
A ···············································································└ carriage-return
|
||||
S 24 ┋ⓘ info: executing SQL statement, press CTRL+] to cancel ┋
|
||||
A ·······································└ fg(#800080), bold, underline
|
||||
A ·············································└ normal
|
||||
CSI Erase to Right
|
||||
S 24 ┋ ┋
|
||||
A └ normal, normal
|
||||
A ·······················································└ carriage-return
|
||||
A └ normal
|
||||
CSI Erase all
|
||||
CSI Use normal screen buffer
|
||||
CTRL restore cursor
|
||||
|
582
test/xpath_tui.0
582
test/xpath_tui.0
@ -14,13 +14,14 @@ OSC Set window title: LOG
|
||||
S -1 ┋ ┋
|
||||
A └ normal, normal, normal
|
||||
CSI Erase all
|
||||
S 1 ┋ Thu Jun 06 1 :: :: LOG ┋
|
||||
A └ fg(#c0c0c0), bg(#008080)
|
||||
S 2 ┋ x┋
|
||||
A ···············································································├ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 1 ┋ 2013-06-06T12:13:20 PDT Press ENTER to focus on the breadcrumb bar ┋
|
||||
A └ bg(#008080)
|
||||
S 2 ┋ LOG ❭ ┋
|
||||
A └ fg(#000000), bg(#000080), bold
|
||||
A ·····└ normal, fg(#008080), bg(#c0c0c0)
|
||||
A ······└ fg(#000000), bg(#c0c0c0)
|
||||
S 3 ┋ x┋
|
||||
A ···············································································├ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 4 ┋ x┋
|
||||
@ -59,199 +60,111 @@ A ····································
|
||||
S 15 ┋ x┋
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 16 ┋ x┋
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 17 ┋ lqqqq No log messages; Log Files: 0; Text Files: 1; Error rate: 0.00/min; Tix┋
|
||||
A └----┛ alt │ │ │ │ │ │ │ │ ││
|
||||
A ···································└ bold │ │ │ │ │ │ ││
|
||||
A ·····································└ normal │ │ │ │ │ │ ││
|
||||
A ···················································└ bold │ │ │ ││
|
||||
A ·····················································└ normal │ │ │ ││
|
||||
A ·······················································└ fg(#800000), bold ││
|
||||
A ·································································└ normal ││
|
||||
A ···································································└ bold ││
|
||||
A ·······································································└ normal││
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 18 ┋ Files :: Text Filters :: Press q to exit ┋
|
||||
A └ fg(#c0c0c0), bg(#000080), bold ││
|
||||
S 16 ┋ Files :: Text Filters :: 0 of 1 enabled Press q to exit ┋
|
||||
A └ bg(#000080), bold │ ││ ││ ││
|
||||
A ·└ fg(#008080), bg(#000080), underline ││
|
||||
A ··└ normal, fg(#c0c0c0), bg(#000080), bold ││
|
||||
A ·······└ normal, fg(#c0c0c0), bg(#000080) ││
|
||||
A ··└ normal, bg(#000080), bold ││ ││
|
||||
A ·······└ normal, fg(#000000), bg(#000080) ││
|
||||
A ········└ fg(#000080), bg(#c0c0c0) ││
|
||||
A ·········└ fg(#000000), bg(#c0c0c0), bold ││
|
||||
A ··········└ fg(#800080), bg(#c0c0c0), underline ││
|
||||
A ···········└ normal, fg(#000000), bg(#c0c0c0), bold ││
|
||||
A ·······················└ normal, fg(#000000), bg(#c0c0c0) ││
|
||||
A ··························└ bold│ ││
|
||||
A ···························└ normal, fg(#000000), bg(#c0c0c0) ││
|
||||
A ·······························└ bold ││
|
||||
A ································└ normal, fg(#000000), bg(#c0c0c0) ││
|
||||
A ······································································└ bold
|
||||
A ·······································································└ normal, fg(#000000), bg(#c0c0c0)
|
||||
S 19 ┋ ┋
|
||||
S 20 ┋→ ` logfile_xml_msg.0 0.0 B — x┋
|
||||
A ··├ fg(#008000), bg(#c0c0c0) │ │
|
||||
A └┛ alt │ │ │
|
||||
A ···└ fg(#000000), bg(#c0c0c0) │ │
|
||||
A ························└ bold│ │
|
||||
A ······························└ normal, fg(#000000), bg(#c0c0c0) │
|
||||
S 17 ┋ ┋
|
||||
S 18 ┋→ ` logfile_xml_msg.0 0.0 B — x┋
|
||||
A ··├ fg(#008000), bg(#c0c0c0) │ │ ││
|
||||
A └┛ alt │ │ │ ││
|
||||
A ···└ fg(#000000), bg(#c0c0c0) │ │ ││
|
||||
A ························└ bold│ │ ││
|
||||
A ······························└ normal, fg(#000000), bg(#c0c0c0) ││
|
||||
A ······································└ fg(#808000), bg(#c0c0c0) ││
|
||||
A ···············································································└ normal, fg(#000000)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 19 ┋ x┋
|
||||
A ···············································································└ fg(#000000)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 20 ┋ x┋
|
||||
A ···············································································└ fg(#000000)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 21 ┋ x┋
|
||||
A ···············································································└ fg(#000000), bg(#c0c0c0)
|
||||
A ···············································································└ fg(#000000)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 22 ┋ x┋
|
||||
A ···············································································└ fg(#000000), bg(#c0c0c0)
|
||||
A ···············································································└ fg(#000000)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 23 ┋ L0 0% ?:View Help ┋
|
||||
A └ fg(#000000), bg(#c0c0c0)
|
||||
A └ fg(#000000), normal, bg(#008080)
|
||||
S 22 ┋ ┋
|
||||
A └ normal, normal
|
||||
S 19 ┋ SPC: Hide ENTER: Jump To ┋
|
||||
A ··└ fg(#000000), bg(#c0c0c0), bold
|
||||
A ·····└ normal, fg(#000000), bg(#c0c0c0)
|
||||
A ·············└ bold
|
||||
A ··················└ normal, fg(#000000), bg(#c0c0c0)
|
||||
S 20 ┋ 64.0 B 2020-12-10 06:56:41.061 — 2020-12-10 06:56:41. ┋
|
||||
A ···························└ backspace │
|
||||
A ··························└ bold │
|
||||
S 18 ┋ 64.0 B 2020-12-10 06:56:41.061 — 2020-12-10 06:56:41. ┋
|
||||
A ··························└ fg(#000000), bg(#c0c0c0), bold │
|
||||
A ······························└ normal, fg(#000000), bg(#c0c0c0) │
|
||||
A ···············································································└ carriage-return
|
||||
S 22 ┋ ┋
|
||||
A └ normal, normal
|
||||
S 20 ┋ 628 ┋
|
||||
S 18 ┋ 628 ┋
|
||||
A ·························└ fg(#000000), bg(#c0c0c0), bold
|
||||
A ····························└ carriage-return
|
||||
S 22 ┋ ┋
|
||||
A └ normal, normal
|
||||
OSC Set window title: logfile_xml_msg.0
|
||||
S 1 ┋ logfile_xml_msg.0 ┋
|
||||
A ·······························└ fg(#c0c0c0), bg(#008080)
|
||||
S 1 ┋ xml_msg_log ┋
|
||||
A ······································································└ carriage-return
|
||||
S 2 ┋x x ┋
|
||||
A └┛ alt│
|
||||
A ·└ normal
|
||||
A ······└ carriage-return
|
||||
S 3 ┋x </head> ┋
|
||||
A └┛ alt │
|
||||
A ·└ normal │
|
||||
A ··········└ carriage-return
|
||||
S 4 ┋x <reply id="2"> ┋
|
||||
A └┛ alt │ ││ ││
|
||||
A ·└ normal │ ││ ││
|
||||
A ··········└ fg(#008080)
|
||||
A ············└ normal
|
||||
A ·············└ fg(#008000), bold
|
||||
A ················└ normal
|
||||
A ·················└ carriage-return
|
||||
S 5 ┋x <status> ┋
|
||||
A └┛ alt │
|
||||
A ·└ normal │
|
||||
A ·············└ carriage-return
|
||||
S 6 ┋x <result>OK</result> ┋
|
||||
A ·└ normal │
|
||||
A └┛ alt │ │
|
||||
A ·└ normal │
|
||||
A ·······└ normal │
|
||||
A ··························└ carriage-return
|
||||
S 7 ┋x </status> ┋
|
||||
A └┛ alt │
|
||||
A ·└ normal │
|
||||
A ··············└ carriage-return
|
||||
S 8 ┋x <name> ┋
|
||||
A └┛ alt │
|
||||
A ·└ normal │
|
||||
A ···········└ carriage-return
|
||||
S 9 ┋x x ┋
|
||||
A ·└ normal
|
||||
A └┛ alt ││
|
||||
A ·└ normal
|
||||
A ·······└ normal
|
||||
A ········└ carriage-return
|
||||
S 10 ┋x </name> ┋
|
||||
A └┛ alt │
|
||||
A ·└ normal │
|
||||
A ············└ carriage-return
|
||||
S 11 ┋x </reply> x┋
|
||||
A └┛ alt ││
|
||||
A ·└ normal ││
|
||||
A ···············································································└ fg(#000000), bg(#c0c0c0)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 12 ┋x <technical-track> x┋
|
||||
A ├ fg(#000000), bg(#c0c0c0) ││
|
||||
A └┛ alt ││
|
||||
A ·└ normal ││
|
||||
A ···············································································└ fg(#000000), bg(#c0c0c0)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 13 ┋x x x┋
|
||||
A ├ fg(#000000), bg(#c0c0c0) ││
|
||||
A └┛ alt ││
|
||||
A ·└ normal ││
|
||||
A ···············································································└ fg(#000000), bg(#c0c0c0)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 14 ┋x </technical-track> x┋
|
||||
A ├ fg(#000000), bg(#c0c0c0) ││
|
||||
A └┛ alt ││
|
||||
A ·└ normal ││
|
||||
A ···············································································└ fg(#000000), bg(#c0c0c0)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 15 ┋x</a-reply> x┋
|
||||
A ├ fg(#000000), bg(#c0c0c0) ││
|
||||
A └┛ alt ││
|
||||
A ·└ normal ││
|
||||
A ···············································································└ fg(#000000), bg(#c0c0c0)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 16 ┋ x┋
|
||||
A ···············································································└ fg(#000000), bg(#c0c0c0)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 17 ┋ Last message: in the future; Files: 1; Error rate: 0.00/min; Time span:x┋
|
||||
A ·······└ fg(#000000), bg(#c0c0c0), normal │ │ │ │ │ │ ││
|
||||
A ·····················└ bold │ │ │ │ │ │ │ ││
|
||||
A ··································└ normal │ │ │ │ │ │ ││
|
||||
A ···········································└ bold │ │ │ ││
|
||||
A ·············································└ normal │ │ │ ││
|
||||
A ···············································└ fg(#800000), bold ││
|
||||
A ·························································└ normal ││
|
||||
A ···························································└ bold ││
|
||||
A ·······························································└ normal ││
|
||||
A ···············································································└ fg(#000000), bg(#c0c0c0)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 23 ┋ 22 10 ┋
|
||||
A ··└ fg(#000000), bg(#c0c0c0)
|
||||
S 16 ┋ 1 ┋
|
||||
A ··························└ fg(#000000), bg(#c0c0c0), bold
|
||||
S 23 ┋ 25 10 ┋
|
||||
A ··└ normal, bg(#008080)
|
||||
A ·············└ carriage-return
|
||||
S 22 ┋ ┋
|
||||
A └ normal, normal
|
||||
CSI Erase Below
|
||||
S 1 ┋ Thu Jun 06 1 logfile_xml_msg.0:: xml_msg_log:: LOG ┋
|
||||
A └ fg(#000000), bg(#c0c0c0) │││ │││
|
||||
A ················································└ fg(#008080), bg(#c0c0c0)
|
||||
A ·················································└ fg(#c0c0c0), bg(#008080)
|
||||
A ··················································└ fg(#000000), bg(#008080)
|
||||
A ······································································└ fg(#000080), bg(#008080)
|
||||
A ·······································································└ fg(#008080), bg(#000080)
|
||||
A ········································································└ fg(#c0c0c0), bg(#000080), bold
|
||||
S 2 ┋ [2020-12-10 06:56:41,092] DEBUG [connect.client:69] Full request text: ┋
|
||||
A ·└ normal │
|
||||
A ················································└ normal
|
||||
S 3 ┋ <?xml version='1.0' encoding='iso-8859-2'?> x┋
|
||||
S 2 ┋ 2020-12-10T06:56:41.061❭xml_msg_log❭logfile_xml_msg.0[0]❭ ┋
|
||||
A ······└ fg(#000000), bg(#c0c0c0) ││ ││
|
||||
A ·····························└ fg(#008080), bg(#c0c0c0) ││
|
||||
A ······························└ fg(#000000), bg(#c0c0c0) ││
|
||||
A ·········································└ fg(#008080), bg(#c0c0c0)
|
||||
A ··········································└ fg(#000000), bg(#c0c0c0)
|
||||
A ······························································└ fg(#008080), bg(#c0c0c0)
|
||||
A ·······························································└ carriage-return
|
||||
S 3 ┋l[2020-12-10 06:56:41,061] INFO [m:108] Calling 'x' with params: x┋
|
||||
A ├ normal │ │ ││
|
||||
A └┛ alt │ │ ││
|
||||
A ················································└ fg(#008000), bold ││
|
||||
A ···················································└ normal ││
|
||||
A ···············································································└ fg(#000000)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 4 ┋x x┋
|
||||
A ├ fg(#000000), normal ││
|
||||
A └┛ alt ││
|
||||
A ·└ normal ││
|
||||
A ···············································································└ fg(#000000)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 5 ┋x[2020-12-10 06:56:41,092] DEBUG [connect.client:69] Full request text: x┋
|
||||
A ├ fg(#000000), normal ││
|
||||
A └┛ alt ││
|
||||
A ···············································································└ fg(#000000)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 6 ┋x<?xml version='1.0' encoding='iso-8859-2'?> x┋
|
||||
A ├ fg(#000000), normal│ ││ │ ││
|
||||
A └┛ alt │ ││ ││ ││ │ ││
|
||||
A ·······└ fg(#008080)││ ││ │ ││
|
||||
A ··············└ normal ││ │ ││
|
||||
A ···············└ fg(#008000), bold │ ││
|
||||
@ -260,83 +173,134 @@ A ·····················└ fg(#008080) │
|
||||
A ·····························└ normal │ ││
|
||||
A ······························└ fg(#008000), bold ││
|
||||
A ··········································└ normal ││
|
||||
A ···············································································└ fg(#000000), bg(#c0c0c0)
|
||||
A ···············································································└ fg(#000000)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 4 ┋ <a-request> x┋
|
||||
A ·└ fg(#000000), bg(#c0c0c0), normal ││
|
||||
A ···············································································└ fg(#000000), bg(#c0c0c0)
|
||||
S 7 ┋x<a-request> x┋
|
||||
A ├ fg(#000000), normal ││
|
||||
A └┛ alt ││
|
||||
A ···············································································└ fg(#000000)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 5 ┋ <head> x┋
|
||||
A ···└ fg(#000000), bg(#c0c0c0), normal ││
|
||||
A ···············································································└ fg(#000000), bg(#c0c0c0)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 6 ┋ x x┋
|
||||
A ·····└ fg(#000000), bg(#c0c0c0), normal ││
|
||||
A ···············································································└ fg(#000000), bg(#c0c0c0)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 7 ┋ </head> x┋
|
||||
A ···└ fg(#000000), bg(#c0c0c0), normal ││
|
||||
A ···············································································└ fg(#000000), bg(#c0c0c0)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 8 ┋ <sourc x┋
|
||||
A ···└ fg(#000000), bg(#c0c0c0), normal ││
|
||||
A ···············································································└ fg(#000000), bg(#c0c0c0)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 9 ┋ x x┋
|
||||
A ·····└ fg(#000000), bg(#c0c0c0), normal ││
|
||||
A ···············································································└ fg(#000000), bg(#c0c0c0)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 10 ┋ </sourc x┋
|
||||
A ···└ fg(#000000), bg(#c0c0c0), normal ││
|
||||
A ···············································································└ fg(#000000), bg(#c0c0c0)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 11 ┋ request id="1"> ┋
|
||||
A ····└ fg(#000000), bg(#c0c0c0), normal
|
||||
S 8 ┋x <head> ┋
|
||||
A ├ fg(#000000), normal
|
||||
A └┛ alt │
|
||||
A ·········└ carriage-return
|
||||
S 9 ┋x x ┋
|
||||
A └┛ alt│
|
||||
A ······└ carriage-return
|
||||
S 10 ┋x </head> ┋
|
||||
A └┛ alt │
|
||||
A ··········└ carriage-return
|
||||
S 11 ┋x <source> ┋
|
||||
A └┛ alt │
|
||||
A ···········└ carriage-return
|
||||
S 12 ┋x x ┋
|
||||
A └┛ alt│
|
||||
A ······└ carriage-return
|
||||
S 13 ┋x </source> ┋
|
||||
A └┛ alt │
|
||||
A ············└ carriage-return
|
||||
S 14 ┋x <request id="1"> ┋
|
||||
A └┛ alt │ ││ ││
|
||||
A ············└ fg(#008080)
|
||||
A ··············└ normal
|
||||
A ···············└ fg(#008000), bold
|
||||
A ··················└ normal
|
||||
S 12 ┋ <name> ┋
|
||||
S 13 ┋ x ┋
|
||||
S 14 ┋ </name> ┋
|
||||
S 15 ┋ </request> x┋
|
||||
A ···················└ carriage-return
|
||||
S 15 ┋x <name> ┋
|
||||
A └┛ alt │
|
||||
A ···········└ carriage-return
|
||||
S 22 ┋ ┋
|
||||
A └ normal
|
||||
CSI set scrolling region 3-20
|
||||
S 3 ┋ ┋
|
||||
A └ [2M
|
||||
CSI set scrolling region 1-24
|
||||
CSI Erase Below
|
||||
S 2 ┋ 92 ┋
|
||||
A ···························└ fg(#000000), bg(#c0c0c0)
|
||||
S 2 ┋ 2]❭⋯❭ ┋
|
||||
A ······························································└ fg(#008080), bg(#c0c0c0)
|
||||
A ·······························································└ fg(#000000), bg(#c0c0c0)
|
||||
A ································································└ fg(#008080), bg(#c0c0c0)
|
||||
S 3 ┋ x┋
|
||||
A ···············································································├ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 16 ┋x</a-request> x┋
|
||||
S 6 ┋ x┋
|
||||
A ···············································································└ fg(#000000)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 7 ┋ x┋
|
||||
A ···············································································└ fg(#000000)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 8 ┋ x┋
|
||||
A ···············································································└ fg(#000000)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 9 ┋ x┋
|
||||
A ···············································································└ fg(#000000)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 10 ┋ x┋
|
||||
A ···············································································└ fg(#000000)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 11 ┋ x┋
|
||||
A ···············································································└ fg(#000000)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 12 ┋ x┋
|
||||
A ···············································································└ fg(#000000)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 13 ┋ x┋
|
||||
A ···············································································└ fg(#000000)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 14 ┋x x x┋
|
||||
A ├ fg(#000000), normal ││
|
||||
A └┛ alt ││
|
||||
A ···············································································└ fg(#000000)
|
||||
A ················································································└ normal
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 15 ┋x </name> x┋
|
||||
A ├ fg(#000000), normal ││
|
||||
A └┛ alt ││
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 16 ┋x </request> x┋
|
||||
A └┛ alt ││
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 17 ┋x</a-request> x┋
|
||||
A └┛ alt ││
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 18 ┋x x┋
|
||||
A └┛ alt ││
|
||||
A ·└ normal ││
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 17 ┋x x┋
|
||||
S 19 ┋x[2020-12-10 06:56:41,099] DEBUG [m:85] Full reply text: x┋
|
||||
A └┛ alt ││
|
||||
A ·└ normal ││
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 18 ┋x[2020-12-10 06:56:41,099] DEBUG [m:85] Full reply text: x┋
|
||||
A └┛ alt │ ││
|
||||
A ·└ normal │ ││
|
||||
A ···································└ normal ││
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 19 ┋x<?xml version='1.0' encoding='iso-8859-2'?> x┋
|
||||
S 20 ┋x<?xml version='1.0' encoding='iso-8859-2'?> x┋
|
||||
A └┛ alt │ ││ ││ ││ │ ││
|
||||
A ·└ normal ││ ││ ││ │ ││
|
||||
A ·······└ fg(#008080)││ ││ │ ││
|
||||
A ··············└ normal ││ │ ││
|
||||
A ···············└ fg(#008000), bold │ ││
|
||||
@ -347,127 +311,120 @@ A ······························└ fg(#00800
|
||||
A ··········································└ normal ││
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 20 ┋x<a-reply> x┋
|
||||
S 21 ┋x<a-reply> x┋
|
||||
A └┛ alt ││
|
||||
A ·└ normal ││
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 21 ┋x <head> x┋
|
||||
A └┛ alt ││
|
||||
A ·└ normal ││
|
||||
A └┛ alt
|
||||
A ················································································└ normal
|
||||
S 22 ┋ Files :: Text Filters :: Press TAB to edit ┋
|
||||
A └ fg(#c0c0c0), bg(#008080) │ │
|
||||
S 24 ┋ ┋
|
||||
A └ normal
|
||||
S 22 ┋ Files :: Text Filters :: 0 of 1 enabled Press TAB to edit ┋
|
||||
A └ bg(#008080) ││ ││ │ │
|
||||
A ··························└ bold│ │ │
|
||||
A ···························└ normal, bg(#008080) │ │
|
||||
A ·······························└ bold │ │
|
||||
A ································└ normal, bg(#008080) │ │
|
||||
A ····································································└ bold
|
||||
A ·······································································└ normal, fg(#c0c0c0), bg(#008080)
|
||||
S 23 ┋ 61 ┋
|
||||
A ···└ fg(#000000), bg(#c0c0c0)
|
||||
A ··············└ carriage-return
|
||||
A ·······································································└ normal, bg(#008080)
|
||||
S 23 ┋ L2 58% ?:View Help ┋
|
||||
A └ fg(#000000), bg(#c0c0c0)
|
||||
S 24 ┋ ┋
|
||||
A └ normal, normal
|
||||
K 70
|
||||
S 3 ┋ Received Time: 2020-12-10T06:56:41.092 -- in the future ┋
|
||||
S 4 ┋ Received Time: 2020-12-10T06:56:41.092 -- in the future ┋
|
||||
A ················└ bold │ │ │
|
||||
A ·······································└ normal │
|
||||
A ···········································└ bold │
|
||||
A ························································└ carriage-return
|
||||
S 4 ┋ Pattern: xml_msg_log/regex/std = ^\[(?<timestamp>\d{4}-\d{2}-\d{2} \d{2}:\d{2} ┋
|
||||
A └ normal ││ │ │ │ │││││ │││││ │││││ │││││ ││││
|
||||
A ··································└ fg(#008080), bold││││ │││││ │││││ │││││ ││││
|
||||
A ···································└ normal │ │││││ │││││ │││││ │││││ ││││
|
||||
A ·····································└ fg(#008000), bold│ │││││ │││││ │││││ ││││
|
||||
A ········································└ normal │ │││││ │││││ │││││ │││││ ││││
|
||||
A ··················································└ fg(#000080), bold │││││ ││││
|
||||
A ····················································└ fg(#008000)││││ │││││ ││││
|
||||
A ·····················································└ normal││ │││││ │││││ ││││
|
||||
A ······················································└ fg(#008000), bold││ ││││
|
||||
A ·······················································└ normal │││││ │││││ ││││
|
||||
A ························································└ fg(#000080), bold ││││
|
||||
A ··························································└ fg(#008000)││││ ││││
|
||||
A ···························································└ normal││ │││││ ││││
|
||||
A ····························································└ fg(#008000), bold│
|
||||
A ·····························································└ normal │││││ ││││
|
||||
A ······························································└ fg(#000080), bold
|
||||
A ································································└ fg(#008000)│││
|
||||
A ·································································└ normal││ ││││
|
||||
A ··································································└ fg(#008000), bold
|
||||
A ···································································└ normal ││││
|
||||
A ····································································└ fg(#000080), bold
|
||||
A ······································································└ fg(#008000)
|
||||
A ·······································································└ normal│
|
||||
A ········································································└ fg(#008000), bold
|
||||
A ·········································································└ normal
|
||||
A ··········································································└ fg(#000080), bold
|
||||
A ············································································└ fg(#008000)
|
||||
A ·············································································└ normal
|
||||
A ··············································································└ fg(#008000), bold
|
||||
S 5 ┋ Pattern: /xml_msg_log/regex/std = ^\[(?<timestamp>\d{4}-\d{2}-\d{2} \d{2}:\d{2 ┋
|
||||
A └ normal ││ │ ││ ││ │││││ │││││ │││││ │││││ │││
|
||||
A ···································└ fg(#008080) ││ │││││ │││││ │││││ │││││ │││
|
||||
A ····································└ normal ││ │││││ │││││ │││││ │││││ │││
|
||||
A ······································└ fg(#008000), bold│ │││││ │││││ │││││ │││
|
||||
A ········································└ normal, fg(#008080)│││ │││││ │││││ │││
|
||||
A ·········································└ normal ││ │││││ │││││ │││││ │││││ │││
|
||||
A ··················································└ fg(#008080)│ │││││ │││││ │││
|
||||
A ···················································└ fg(#000080) │││││ │││││ │││
|
||||
A ·····················································└ fg(#008000), bold││││ │││
|
||||
A ······················································└ normal││ │││││ │││││ │││
|
||||
A ·······················································└ fg(#008000), bold││ │││
|
||||
A ························································└ normal │││││ │││││ │││
|
||||
A ·························································└ fg(#000080) │││││ │││
|
||||
A ···························································└ fg(#008000), bold││
|
||||
A ····························································└ normal││ │││││ │││
|
||||
A ·····························································└ fg(#008000), bold
|
||||
A ······························································└ normal │││││ │││
|
||||
A ·······························································└ fg(#000080) │││
|
||||
A ·································································└ fg(#008000), bold
|
||||
A ··································································└ normal││ │││
|
||||
A ···································································└ fg(#008000), bold
|
||||
A ····································································└ normal │││
|
||||
A ·····································································└ fg(#000080)
|
||||
A ·······································································└ fg(#008000), bold
|
||||
A ········································································└ normal
|
||||
A ·········································································└ fg(#008000), bold
|
||||
A ··········································································└ normal
|
||||
A ···········································································└ fg(#000080)
|
||||
A ·············································································└ fg(#008000), bold
|
||||
A ··············································································└ normal
|
||||
A ···············································································└ carriage-return
|
||||
S 5 ┋ Known message fields for table xml_msg_log: ┋
|
||||
A └ normal │ ││
|
||||
S 6 ┋ Known message fields for table xml_msg_log: ┋
|
||||
A ································└ bold ││
|
||||
A ···········································└ normal
|
||||
A ············································└ carriage-return
|
||||
S 6 ┋ t timestamp = 2020-12-10 06:56:41,092 ┋
|
||||
A └┛ alt │ │ │
|
||||
A ············└ normal │
|
||||
S 7 ┋ t log_time = 2020-12-10 06:56:41,092 ┋
|
||||
A └┛ alt │ │
|
||||
A ···············└ bold │
|
||||
A ···············································································└ carriage-return
|
||||
S 7 ┋ t level = DEBUG ┋
|
||||
A └ normal│ │ │
|
||||
A └┛ alt │ │ │
|
||||
A ········└ normal │
|
||||
A ···············└ bold │
|
||||
A ···············································································└ carriage-return
|
||||
S 8 ┋ t module = connect.client ┋
|
||||
A └ normal │ │ │
|
||||
A └┛ alt │ │ │
|
||||
A ·········└ normal │
|
||||
A ···············└ bold │
|
||||
A ···············································································└ carriage-return
|
||||
S 9 ┋ t line = 69 ┋
|
||||
A └ normal │ │ │
|
||||
A └┛ alt │ │ │
|
||||
A ·············└ normal │
|
||||
A ···············└ bold │
|
||||
A ···············································································└ carriage-return
|
||||
S 10 ┋ t body = Full request text: ┋
|
||||
S 8 ┋ t level = DEBUG ┋
|
||||
A └ normal │ │
|
||||
A └┛ alt│ │ │
|
||||
A ·······└ normal│ │
|
||||
A └┛ alt │ │
|
||||
A ···············└ bold │
|
||||
A ···············································································└ carriage-return
|
||||
S 11 ┋ t msg_data = <?xml version='1.0' encoding='iso-8859-2'?> <a-request> <head> ┋
|
||||
A └ normal │ │ │
|
||||
A └┛ alt │ │ │
|
||||
A ···········└ normal │
|
||||
S 9 ┋ t module = connect.client ┋
|
||||
A └ normal │ │
|
||||
A └┛ alt │ │
|
||||
A ···············└ bold │
|
||||
A ···············································································└ carriage-return
|
||||
S 12 ┋ XML fields: ┋
|
||||
S 10 ┋ t line = 69 ┋
|
||||
A └ normal │ │
|
||||
A └┛ alt │ │
|
||||
A ···············└ bold │
|
||||
A ···············································································└ carriage-return
|
||||
S 11 ┋ t log_body = Full request text: ┋
|
||||
A └ normal │ │
|
||||
A └┛ alt │ │
|
||||
A ···············└ bold │
|
||||
A ···············································································└ carriage-return
|
||||
S 12 ┋ t msg_data = <?xml version='1.0' encoding='iso-8859-2'?> <a-request> <head> ┋
|
||||
A └ normal │ │
|
||||
A └┛ alt │ │
|
||||
A ···············└ bold │
|
||||
A ···············································································└ carriage-return
|
||||
S 13 ┋ XML fields: ┋
|
||||
A └ normal │
|
||||
A ············└ carriage-return
|
||||
S 13 ┋ t xpath('/a-request/head/text()', msg_data) = x ┋
|
||||
S 14 ┋ t xpath('/a-request/head/text()', msg_data) = x ┋
|
||||
A └┛ alt │
|
||||
A ······└ bold │
|
||||
A ···············································································└ carriage-return
|
||||
S 14 ┋ t xpath('/a-request/request/@id', msg_data) = 1 ┋
|
||||
S 15 ┋ t xpath('/a-request/request/@id', msg_data) = 1 ┋
|
||||
A └ normal │
|
||||
A └┛ alt │
|
||||
A ······└ bold │
|
||||
A ···············································································└ carriage-return
|
||||
S 15 ┋ t xpath('/a-request/request/name/text()', msg_data) = x ┋
|
||||
S 16 ┋ t xpath('/a-request/request/name/text()', msg_data) = x ┋
|
||||
A └ normal │
|
||||
A └┛ alt │
|
||||
A ······└ bold │
|
||||
A ···············································································└ carriage-return
|
||||
S 16 ┋ t xpath('/a-request/source/text()', msg_data) = x ┋
|
||||
S 17 ┋ t xpath('/a-request/source/text()', msg_data) = x ┋
|
||||
A └ normal │
|
||||
A └┛ alt │
|
||||
A ······└ bold │
|
||||
A ···············································································└ carriage-return
|
||||
S 17 ┋ No discovered message fields ┋
|
||||
S 18 ┋ No discovered message fields ┋
|
||||
A └ normal
|
||||
S 18 ┋ <?xml version='1.0' encoding='iso-8859-2'?> ┋
|
||||
S 19 ┋ <?xml version='1.0' encoding='iso-8859-2'?> ┋
|
||||
A ·······└ fg(#008080)││ ││ │
|
||||
A ··············└ normal ││ │
|
||||
A ···············└ fg(#008000), bold │
|
||||
@ -476,13 +433,22 @@ A ·····················└ fg(#008080) │
|
||||
A ·····························└ normal │
|
||||
A ······························└ fg(#008000), bold
|
||||
A ··········································└ normal
|
||||
S 19 ┋ a-request> ┋
|
||||
S 20 ┋ <head> ┋
|
||||
S 21 ┋ x ┋
|
||||
A ·········└ carriage-return
|
||||
S 20 ┋ a-request> ┋
|
||||
S 21 ┋ <head> ┋
|
||||
A ··········└ carriage-return
|
||||
S 24 ┋ ┋
|
||||
A └ normal
|
||||
K 71
|
||||
S 23 ┋ 0 ┋
|
||||
A ··└ fg(#000000), bg(#c0c0c0)
|
||||
S 23 ┋ 0 ┋
|
||||
A ··············└ carriage-return
|
||||
S 24 ┋ⓘ info: executing SQL statement, press CTRL+] to cancel ┋
|
||||
A └ normal │ │ │
|
||||
A ·······································└ fg(#800080), bold, underline
|
||||
A ·············································└ normal │
|
||||
A ·······················································└ carriage-return
|
||||
A └ normal
|
||||
CSI Erase all
|
||||
CSI Use normal screen buffer
|
||||
CTRL restore cursor
|
||||
|
Loading…
Reference in New Issue
Block a user