mirror of https://github.com/tstack/lnav.git
[log-view] in time-offset mode, show negative times for messages before the first mark
Prototype for #395
This commit is contained in:
parent
d61f2568d6
commit
b81b35c866
|
@ -2,5 +2,16 @@
|
|||
cmake_minimum_required (VERSION 2.6)
|
||||
SET(CMAKE_CXX_STANDARD 14)
|
||||
project (lnav)
|
||||
|
||||
|
||||
set(lnav_LIBS
|
||||
/usr/lib/libz.dylib
|
||||
/usr/lib/libbz2.dylib
|
||||
/usr/local/opt/sqlite/lib/libsqlite3.a
|
||||
/usr/local/opt/pcre/lib/libpcre.a
|
||||
/usr/local/opt/pcre/lib/libpcrecpp.a
|
||||
/usr/local/opt/readline/lib/libreadline.a
|
||||
/usr/local/opt/ncurses/lib/libncurses.a)
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(test)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
set(diag_STAT_SRCS
|
||||
add_library(diag STATIC
|
||||
ansi_scrubber.cc
|
||||
bookmarks.cc
|
||||
bottom_status_source.cc
|
||||
|
@ -67,6 +67,7 @@ set(diag_STAT_SRCS
|
|||
ptimec.cc
|
||||
sql_util.cc
|
||||
state-extension-functions.cc
|
||||
styling.cc
|
||||
base/string_util.cc
|
||||
strnatcmp.c
|
||||
text_format.cc
|
||||
|
@ -200,7 +201,13 @@ set(diag_STAT_SRCS
|
|||
fmtlib/fmt/format.h
|
||||
fmtlib/format.cc
|
||||
|
||||
log_level_re.cc
|
||||
|
||||
../../lbuild-debug/src/config.h
|
||||
../../lbuild-debug/src/time_fmts.cc
|
||||
../../lbuild-debug/src/default-config.c
|
||||
../../lbuild-debug/src/ansi-palette-json.c
|
||||
../../lbuild-debug/src/xterm-palette-json.c
|
||||
)
|
||||
|
||||
set(lnav_SRCS lnav.cc)
|
||||
|
@ -214,16 +221,10 @@ include_directories(
|
|||
fmtlib
|
||||
)
|
||||
include_directories(SYSTEM .)
|
||||
add_executable(lnav ${lnav_SRCS} ${diag_STAT_SRCS})
|
||||
add_executable(lnav ${lnav_SRCS})
|
||||
|
||||
target_link_libraries(lnav
|
||||
/usr/lib/libz.dylib
|
||||
/usr/lib/libbz2.dylib
|
||||
/usr/local/opt/curl/lib/libcurl.dylib
|
||||
/usr/local/opt/sqlite/lib/libsqlite3.a
|
||||
/usr/local/opt/pcre/lib/libpcre.a
|
||||
/usr/local/opt/pcre/lib/libpcrecpp.a
|
||||
/usr/local/opt/readline/lib/libreadline.a
|
||||
/usr/local/opt/ncurses/lib/libncurses.a)
|
||||
diag
|
||||
${lnav_LIBS})
|
||||
|
||||
add_executable(bin2c bin2c.c)
|
||||
|
|
|
@ -381,6 +381,7 @@ libdiag_a_SOURCES = \
|
|||
sqlite-extension-func.cc \
|
||||
statusview_curses.cc \
|
||||
string-extension-functions.cc \
|
||||
styling.cc \
|
||||
text_format.cc \
|
||||
timer.cc \
|
||||
piper_proc.cc \
|
||||
|
|
|
@ -74,9 +74,9 @@ void field_overlay_source::build_summary_lines(const listview_curses &lv)
|
|||
last_line = lss.find_line(lss.at(lv.get_bottom()));
|
||||
last_time = "Last message: " ANSI_BOLD_START + precise_time_ago(
|
||||
last_line->get_timeval(), true) + ANSI_NORM;
|
||||
str2reltime(last_line->get_time_in_millis() -
|
||||
first_line->get_time_in_millis(),
|
||||
time_span);
|
||||
duration2str(last_line->get_time_in_millis() -
|
||||
first_line->get_time_in_millis(),
|
||||
time_span);
|
||||
|
||||
time_t local_now = convert_log_time_to_local(now);
|
||||
time_t five_minutes_ago = local_now - (5 * 60 * 60);
|
||||
|
|
|
@ -299,22 +299,31 @@ void logfile_sub_source::text_value_for_line(textview_curses &tc,
|
|||
}
|
||||
|
||||
if (this->lss_flags & F_TIME_OFFSET) {
|
||||
int64_t start_millis, curr_millis;
|
||||
int64_t curr_millis, diff;
|
||||
|
||||
curr_millis = this->lss_token_line->get_time_in_millis();
|
||||
|
||||
vis_line_t prev_mark =
|
||||
tc.get_bookmarks()[&textview_curses::BM_USER].prev(vis_line_t(row));
|
||||
if (prev_mark == -1) {
|
||||
prev_mark = vis_line_t(0);
|
||||
}
|
||||
vis_line_t next_mark =
|
||||
tc.get_bookmarks()[&textview_curses::BM_USER].next(vis_line_t(row));
|
||||
if (prev_mark == -1 && next_mark != -1) {
|
||||
auto next_line = this->find_line(this->at(next_mark));
|
||||
|
||||
logline *first_line = this->find_line(this->at(prev_mark));
|
||||
start_millis = first_line->get_time_in_millis();
|
||||
curr_millis = this->lss_token_line->get_time_in_millis();
|
||||
int64_t diff = curr_millis - start_millis;
|
||||
diff = curr_millis - next_line->get_time_in_millis();
|
||||
} else {
|
||||
if (prev_mark == -1) {
|
||||
prev_mark = 0_vl;
|
||||
}
|
||||
|
||||
auto first_line = this->find_line(this->at(prev_mark));
|
||||
auto start_millis = first_line->get_time_in_millis();
|
||||
diff = curr_millis - start_millis;
|
||||
}
|
||||
|
||||
value_out = "|" + value_out;
|
||||
string relstr;
|
||||
size_t rel_length = str2reltime(diff, relstr);
|
||||
size_t rel_length = duration2str(diff, relstr);
|
||||
value_out.insert(0, relstr);
|
||||
if (rel_length < 12) {
|
||||
value_out.insert(0, 12 - rel_length, ' ');
|
||||
|
|
|
@ -505,7 +505,7 @@ std::string relative_time::to_string()
|
|||
return dst;
|
||||
}
|
||||
|
||||
size_t str2reltime(int64_t millis, std::string &value_out)
|
||||
size_t duration2str(int64_t millis, std::string &value_out)
|
||||
{
|
||||
/* 24h22m33s111 */
|
||||
|
||||
|
@ -523,7 +523,15 @@ size_t str2reltime(int64_t millis, std::string &value_out)
|
|||
};
|
||||
|
||||
struct rel_interval *curr_interval = intervals;
|
||||
size_t in_len = value_out.length(), retval = 0;
|
||||
size_t retval = 0;
|
||||
|
||||
if (millis < 0) {
|
||||
value_out.append(1, '-');
|
||||
millis = -millis;
|
||||
retval += 1;
|
||||
}
|
||||
|
||||
size_t in_len = value_out.length();
|
||||
|
||||
if (millis >= (10 * 60 * 1000)) {
|
||||
millis /= 1000;
|
||||
|
|
|
@ -314,11 +314,11 @@ public:
|
|||
int rt_absolute_field_end;
|
||||
};
|
||||
|
||||
size_t str2reltime(int64_t millis, std::string &value_out);
|
||||
size_t duration2str(int64_t millis, std::string &value_out);
|
||||
|
||||
inline
|
||||
size_t str2reltime(const struct timeval &tv, std::string &value_out) {
|
||||
return str2reltime(tv.tv_sec * 1000 + tv.tv_usec / 1000, value_out);
|
||||
return duration2str(tv.tv_sec * 1000 + tv.tv_usec / 1000, value_out);
|
||||
};
|
||||
|
||||
#endif //LNAV_RELATIVE_TIME_HH
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
/**
|
||||
* Copyright (c) 2019, Timothy Stack
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of Timothy Stack nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* 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
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "yajlpp/yajlpp.hh"
|
||||
#include "yajlpp/yajlpp_def.hh"
|
||||
#include "styling.hh"
|
||||
#include "ansi-palette-json.h"
|
||||
#include "xterm-palette-json.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static struct json_path_handler term_color_rgb_handler[] = {
|
||||
json_path_handler("r")
|
||||
.FOR_FIELD(rgb_color, rc_r),
|
||||
json_path_handler("g")
|
||||
.FOR_FIELD(rgb_color, rc_g),
|
||||
json_path_handler("b")
|
||||
.FOR_FIELD(rgb_color, rc_b),
|
||||
|
||||
json_path_handler()
|
||||
};
|
||||
|
||||
static struct json_path_handler term_color_handler[] = {
|
||||
json_path_handler("colorId")
|
||||
.FOR_FIELD(term_color, xc_id),
|
||||
json_path_handler("name")
|
||||
.FOR_FIELD(term_color, xc_name),
|
||||
json_path_handler("rgb/")
|
||||
.with_obj_provider<rgb_color, term_color>(
|
||||
[](const auto &pc, term_color *xc) { return &xc->xc_color; })
|
||||
.with_children(term_color_rgb_handler),
|
||||
|
||||
json_path_handler()
|
||||
};
|
||||
|
||||
static struct json_path_handler root_color_handler[] = {
|
||||
json_path_handler("#/")
|
||||
.with_obj_provider<term_color, vector<term_color>>(
|
||||
[](const yajlpp_provider_context &ypc, vector<term_color> *palette) {
|
||||
palette->resize(ypc.ypc_index + 1);
|
||||
return &((*palette)[ypc.ypc_index]);
|
||||
})
|
||||
.with_children(term_color_handler),
|
||||
|
||||
json_path_handler()
|
||||
};
|
||||
|
||||
term_color_palette xterm_colors(xterm_palette_json.bsf_data);
|
||||
term_color_palette ansi_colors(ansi_palette_json.bsf_data);
|
||||
|
||||
term_color_palette *ACTIVE_PALETTE = &ansi_colors;
|
||||
|
||||
bool rgb_color::from_str(const string_fragment &color,
|
||||
rgb_color &rgb_out,
|
||||
std::string &errmsg)
|
||||
{
|
||||
if (color.empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (color[0] == '#') {
|
||||
switch (color.length()) {
|
||||
case 4:
|
||||
if (sscanf(color.data(), "#%1hx%1hx%1hx",
|
||||
&rgb_out.rc_r, &rgb_out.rc_g, &rgb_out.rc_b) == 3) {
|
||||
rgb_out.rc_r |= rgb_out.rc_r << 4;
|
||||
rgb_out.rc_g |= rgb_out.rc_g << 4;
|
||||
rgb_out.rc_b |= rgb_out.rc_b << 4;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
if (sscanf(color.data(), "#%2hx%2hx%2hx",
|
||||
&rgb_out.rc_r, &rgb_out.rc_g, &rgb_out.rc_b) == 3) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
errmsg = "Could not parse color: " + color.to_string();
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto &xc : xterm_colors.tc_palette) {
|
||||
if (color.iequal(xc.xc_name)) {
|
||||
rgb_out = xc.xc_color;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
errmsg = "Unknown color: '" + color.to_string() +
|
||||
"'. See https://jonasjacek.github.io/colors/ for a list of supported color names";
|
||||
return false;
|
||||
}
|
||||
|
||||
term_color_palette::term_color_palette(const unsigned char *json)
|
||||
{
|
||||
yajlpp_parse_context ypc_xterm("palette.json", root_color_handler);
|
||||
yajl_handle handle;
|
||||
|
||||
handle = yajl_alloc(&ypc_xterm.ypc_callbacks, nullptr, &ypc_xterm);
|
||||
ypc_xterm
|
||||
.with_ignore_unused(true)
|
||||
.with_obj(this->tc_palette)
|
||||
.with_handle(handle);
|
||||
yajl_status st = ypc_xterm.parse(json, strlen((const char *) json));
|
||||
ensure(st == yajl_status_ok);
|
||||
st = ypc_xterm.complete_parse();
|
||||
ensure(st == yajl_status_ok);
|
||||
yajl_free(handle);
|
||||
|
||||
for (auto &xc : this->tc_palette) {
|
||||
xc.xc_lab_color = lab_color(xc.xc_color);
|
||||
}
|
||||
}
|
||||
|
||||
short term_color_palette::match_color(const lab_color &to_match)
|
||||
{
|
||||
double lowest = 1000.0;
|
||||
short lowest_id = -1;
|
||||
|
||||
for (auto &xc : this->tc_palette) {
|
||||
double xc_delta = xc.xc_lab_color.deltaE(to_match);
|
||||
|
||||
if (lowest_id == -1) {
|
||||
lowest = xc_delta;
|
||||
lowest_id = xc.xc_id;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (xc_delta < lowest) {
|
||||
lowest = xc_delta;
|
||||
lowest_id = xc.xc_id;
|
||||
}
|
||||
}
|
||||
|
||||
return lowest_id;
|
||||
}
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "log_level.hh"
|
||||
#include "intern_string.hh"
|
||||
|
@ -54,6 +55,42 @@ struct rgb_color {
|
|||
short rc_b;
|
||||
};
|
||||
|
||||
struct lab_color {
|
||||
lab_color() : lc_l(0), lc_a(0), lc_b(0) {
|
||||
};
|
||||
|
||||
explicit lab_color(const rgb_color &rgb);
|
||||
|
||||
double deltaE(const lab_color &other) const;
|
||||
|
||||
lab_color& operator=(const lab_color &other) {
|
||||
this->lc_l = other.lc_l;
|
||||
this->lc_a = other.lc_a;
|
||||
this->lc_b = other.lc_b;
|
||||
|
||||
return *this;
|
||||
};
|
||||
|
||||
double lc_l;
|
||||
double lc_a;
|
||||
double lc_b;
|
||||
};
|
||||
|
||||
struct term_color {
|
||||
short xc_id;
|
||||
std::string xc_name;
|
||||
rgb_color xc_color;
|
||||
lab_color xc_lab_color;
|
||||
};
|
||||
|
||||
struct term_color_palette {
|
||||
explicit term_color_palette(const unsigned char *json);
|
||||
|
||||
short match_color(const lab_color &to_match);
|
||||
|
||||
std::vector<term_color> tc_palette;
|
||||
};
|
||||
|
||||
struct style_config {
|
||||
std::string sc_color;
|
||||
std::string sc_background_color;
|
||||
|
@ -100,4 +137,9 @@ struct lnav_theme {
|
|||
std::map<log_level_t, style_config> lt_level_styles;
|
||||
};
|
||||
|
||||
extern term_color_palette xterm_colors;
|
||||
extern term_color_palette ansi_colors;
|
||||
|
||||
extern term_color_palette *ACTIVE_PALETTE;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -41,148 +41,11 @@
|
|||
#include "lnav_config.hh"
|
||||
#include "yajlpp/yajlpp.hh"
|
||||
#include "yajlpp/yajlpp_def.hh"
|
||||
#include "ansi-palette-json.h"
|
||||
#include "xterm-palette-json.h"
|
||||
#include "attr_line.hh"
|
||||
#include "shlex.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
struct term_color {
|
||||
short xc_id;
|
||||
string xc_name;
|
||||
rgb_color xc_color;
|
||||
lab_color xc_lab_color;
|
||||
};
|
||||
|
||||
static struct json_path_handler term_color_rgb_handler[] = {
|
||||
json_path_handler("r")
|
||||
.FOR_FIELD(rgb_color, rc_r),
|
||||
json_path_handler("g")
|
||||
.FOR_FIELD(rgb_color, rc_g),
|
||||
json_path_handler("b")
|
||||
.FOR_FIELD(rgb_color, rc_b),
|
||||
|
||||
json_path_handler()
|
||||
};
|
||||
|
||||
static struct json_path_handler term_color_handler[] = {
|
||||
json_path_handler("colorId")
|
||||
.FOR_FIELD(term_color, xc_id),
|
||||
json_path_handler("name")
|
||||
.FOR_FIELD(term_color, xc_name),
|
||||
json_path_handler("rgb/")
|
||||
.with_obj_provider<rgb_color, term_color>([](const auto &pc, term_color *xc) { return &xc->xc_color; })
|
||||
.with_children(term_color_rgb_handler),
|
||||
|
||||
json_path_handler()
|
||||
};
|
||||
|
||||
static struct json_path_handler root_color_handler[] = {
|
||||
json_path_handler("#/")
|
||||
.with_obj_provider<term_color, vector<term_color>>(
|
||||
[](const yajlpp_provider_context &ypc, vector<term_color> *palette) {
|
||||
palette->resize(ypc.ypc_index + 1);
|
||||
return &((*palette)[ypc.ypc_index]);
|
||||
})
|
||||
.with_children(term_color_handler),
|
||||
|
||||
json_path_handler()
|
||||
};
|
||||
|
||||
struct term_color_palette {
|
||||
term_color_palette(const unsigned char *json) {
|
||||
yajlpp_parse_context ypc_xterm("palette.json", root_color_handler);
|
||||
yajl_handle handle;
|
||||
|
||||
handle = yajl_alloc(&ypc_xterm.ypc_callbacks, nullptr, &ypc_xterm);
|
||||
ypc_xterm
|
||||
.with_ignore_unused(true)
|
||||
.with_obj(this->tc_palette)
|
||||
.with_handle(handle);
|
||||
yajl_status st = ypc_xterm.parse(json, strlen((const char *) json));
|
||||
ensure(st == yajl_status_ok);
|
||||
st = ypc_xterm.complete_parse();
|
||||
ensure(st == yajl_status_ok);
|
||||
yajl_free(handle);
|
||||
|
||||
for (auto &xc : this->tc_palette) {
|
||||
xc.xc_lab_color = lab_color(xc.xc_color);
|
||||
}
|
||||
};
|
||||
|
||||
short match_color(const lab_color &to_match) {
|
||||
double lowest = 1000.0;
|
||||
short lowest_id = -1;
|
||||
|
||||
for (auto &xc : this->tc_palette) {
|
||||
double xc_delta = xc.xc_lab_color.deltaE(to_match);
|
||||
|
||||
if (lowest_id == -1) {
|
||||
lowest = xc_delta;
|
||||
lowest_id = xc.xc_id;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (xc_delta < lowest) {
|
||||
lowest = xc_delta;
|
||||
lowest_id = xc.xc_id;
|
||||
}
|
||||
}
|
||||
|
||||
return lowest_id;
|
||||
};
|
||||
|
||||
vector<term_color> tc_palette;
|
||||
};
|
||||
|
||||
term_color_palette xterm_colors(xterm_palette_json.bsf_data);
|
||||
term_color_palette ansi_colors(ansi_palette_json.bsf_data);
|
||||
|
||||
term_color_palette *ACTIVE_PALETTE = &ansi_colors;
|
||||
|
||||
bool rgb_color::from_str(const string_fragment &color,
|
||||
rgb_color &rgb_out,
|
||||
std::string &errmsg)
|
||||
{
|
||||
if (color.empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (color[0] == '#') {
|
||||
switch (color.length()) {
|
||||
case 4:
|
||||
if (sscanf(color.data(), "#%1hx%1hx%1hx",
|
||||
&rgb_out.rc_r, &rgb_out.rc_g, &rgb_out.rc_b) == 3) {
|
||||
rgb_out.rc_r |= rgb_out.rc_r << 4;
|
||||
rgb_out.rc_g |= rgb_out.rc_g << 4;
|
||||
rgb_out.rc_b |= rgb_out.rc_b << 4;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
if (sscanf(color.data(), "#%2hx%2hx%2hx",
|
||||
&rgb_out.rc_r, &rgb_out.rc_g, &rgb_out.rc_b) == 3) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
errmsg = "Could not parse color: " + color.to_string();
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto &xc : xterm_colors.tc_palette) {
|
||||
if (color.iequal(xc.xc_name)) {
|
||||
rgb_out = xc.xc_color;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
errmsg = "Unknown color: '" + color.to_string() +
|
||||
"'. See https://jonasjacek.github.io/colors/ for a list of supported color names";
|
||||
return false;
|
||||
}
|
||||
|
||||
string_attr_type view_curses::VC_ROLE("role");
|
||||
string_attr_type view_curses::VC_STYLE("style");
|
||||
string_attr_type view_curses::VC_GRAPHIC("graphic");
|
||||
|
@ -190,7 +53,8 @@ string_attr_type view_curses::VC_SELECTED("selected");
|
|||
string_attr_type view_curses::VC_FOREGROUND("foreground");
|
||||
string_attr_type view_curses::VC_BACKGROUND("background");
|
||||
|
||||
const struct itimerval ui_periodic_timer::INTERVAL = { { 0, 350 * 1000 },
|
||||
const struct itimerval ui_periodic_timer::INTERVAL = {
|
||||
{ 0, 350 * 1000 },
|
||||
{ 0, 350 * 1000 }
|
||||
};
|
||||
|
||||
|
@ -821,7 +685,7 @@ void view_colors::init_roles(const lnav_theme <,
|
|||
if (!rgb_color::from_str(bg_color, rgb_bg, errmsg)) {
|
||||
reporter(&ident_sc.sc_background_color, errmsg);
|
||||
}
|
||||
ident_bg = ACTIVE_PALETTE->match_color(rgb_bg);
|
||||
ident_bg = ACTIVE_PALETTE->match_color(lab_color(rgb_bg));
|
||||
}
|
||||
for (int z = 0; z < 6; z++) {
|
||||
for (int x = 1; x < 6; x += 2) {
|
||||
|
@ -868,8 +732,8 @@ void view_colors::init_roles(const lnav_theme <,
|
|||
return;
|
||||
}
|
||||
|
||||
short fg = ACTIVE_PALETTE->match_color(rgb_fg);
|
||||
short bg = ACTIVE_PALETTE->match_color(rgb_bg);
|
||||
short fg = ACTIVE_PALETTE->match_color(lab_color(rgb_fg));
|
||||
short bg = ACTIVE_PALETTE->match_color(lab_color(rgb_bg));
|
||||
|
||||
if (rgb_fg.empty()) {
|
||||
fg = ansi_fg;
|
||||
|
@ -1072,8 +936,8 @@ int view_colors::ensure_color_pair(int &pair_base, const rgb_color &rgb_fg, cons
|
|||
{
|
||||
return attr_for_colors(
|
||||
pair_base,
|
||||
rgb_fg.empty() ? (short) COLOR_WHITE : ACTIVE_PALETTE->match_color(rgb_fg),
|
||||
rgb_bg.empty() ? (short) COLOR_BLACK : ACTIVE_PALETTE->match_color(rgb_bg));
|
||||
rgb_fg.empty() ? (short) COLOR_WHITE : ACTIVE_PALETTE->match_color(lab_color(rgb_fg)),
|
||||
rgb_bg.empty() ? (short) COLOR_BLACK : ACTIVE_PALETTE->match_color(lab_color(rgb_bg)));
|
||||
}
|
||||
|
||||
attr_t view_colors::attrs_for_ident(const char *str, size_t len) const
|
||||
|
|
|
@ -292,27 +292,6 @@ private:
|
|||
void (*va_invoker)(void *functor, _Sender *sender);
|
||||
};
|
||||
|
||||
struct lab_color {
|
||||
lab_color() : lc_l(0), lc_a(0), lc_b(0) {
|
||||
};
|
||||
|
||||
lab_color(const rgb_color &rgb);
|
||||
|
||||
double deltaE(const lab_color &other) const;
|
||||
|
||||
lab_color& operator=(const lab_color &other) {
|
||||
this->lc_l = other.lc_l;
|
||||
this->lc_a = other.lc_a;
|
||||
this->lc_b = other.lc_b;
|
||||
|
||||
return *this;
|
||||
};
|
||||
|
||||
double lc_l;
|
||||
double lc_a;
|
||||
double lc_b;
|
||||
};
|
||||
|
||||
/**
|
||||
* Singleton used to manage the colorspace.
|
||||
*/
|
||||
|
|
|
@ -9,12 +9,8 @@ include_directories(
|
|||
)
|
||||
|
||||
add_executable(lnav_doctests
|
||||
lnav_doctests.cc
|
||||
../src/relative_time.cc
|
||||
../../lbuild-debug/src/time_fmts.cc
|
||||
../src/ptimec_rt.cc
|
||||
../src/pcrepp/pcrepp.cc
|
||||
../src/base/lnav_log.cc)
|
||||
lnav_doctests.cc)
|
||||
target_link_libraries(lnav_doctests diag ${lnav_LIBS})
|
||||
add_executable(test_pcrepp test_pcrepp.cc ../src/base/lnav_log.cc ../src/pcrepp/pcrepp.cc)
|
||||
add_executable(test_line_buffer2
|
||||
test_line_buffer2.cc
|
||||
|
|
|
@ -39,23 +39,29 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
TEST_CASE("str2reltime") {
|
||||
TEST_CASE("duration2str") {
|
||||
string val;
|
||||
|
||||
str2reltime(25 * 60 * 60 * 1000 + 123, val);
|
||||
duration2str(25 * 60 * 60 * 1000 + 123, val);
|
||||
CHECK(val == "1d1h0m0s");
|
||||
val.clear();
|
||||
str2reltime(10 * 1000 + 123, val);
|
||||
duration2str(10 * 1000 + 123, val);
|
||||
CHECK(val == "10s123");
|
||||
val.clear();
|
||||
str2reltime(10 * 1000, val);
|
||||
duration2str(10 * 1000, val);
|
||||
CHECK(val == "10s000");
|
||||
val.clear();
|
||||
str2reltime(100, val);
|
||||
duration2str(100, val);
|
||||
CHECK(val == "100");
|
||||
val.clear();
|
||||
str2reltime(0, val);
|
||||
duration2str(0, val);
|
||||
CHECK(val == "");
|
||||
val.clear();
|
||||
duration2str(-10, val);
|
||||
CHECK(val == "-010");
|
||||
val.clear();
|
||||
duration2str(-10 * 1000, val);
|
||||
CHECK(val == "-10s000");
|
||||
}
|
||||
|
||||
TEST_CASE("ptime_fmt") {
|
||||
|
|
Loading…
Reference in New Issue