mirror of
https://github.com/tstack/lnav
synced 2024-11-15 18:13:10 +00:00
[fini] fix a destruction ordering issue
This commit is contained in:
parent
59ec0b4794
commit
93a53c4224
@ -12,7 +12,7 @@ install:
|
|||||||
- C:\%cygwin%\%cygsetup% -qnNdOX -R C:/%cygwin% -l C:/%cygwin%/var/cache/setup -P libpcre2-devel -P libncurses-devel -P libreadline-devel -P zlib-devel -P libbz2-devel -P libsqlite3-devel -P libcurl-devel -P libarchive-devel
|
- C:\%cygwin%\%cygsetup% -qnNdOX -R C:/%cygwin% -l C:/%cygwin%/var/cache/setup -P libpcre2-devel -P libncurses-devel -P libreadline-devel -P zlib-devel -P libbz2-devel -P libsqlite3-devel -P libcurl-devel -P libarchive-devel
|
||||||
|
|
||||||
build_script:
|
build_script:
|
||||||
- C:\%cygwin%\bin\sh -lc "uname -a && gcc --version && cd /cygdrive/c/projects/lnav && ./autogen.sh && ./configure && make && strip src/lnav.exe && ldd src/lnav.exe"
|
- C:\%cygwin%\bin\sh -lc "uname -a && gcc --version && cd /cygdrive/c/projects/lnav && ./autogen.sh && ./configure && make -j4 && strip src/lnav.exe && ldd src/lnav.exe"
|
||||||
|
|
||||||
artifacts:
|
artifacts:
|
||||||
- path: src\lnav.exe
|
- path: src\lnav.exe
|
||||||
|
@ -310,6 +310,7 @@ noinst_HEADERS = \
|
|||||||
time_T.hh \
|
time_T.hh \
|
||||||
timer.hh \
|
timer.hh \
|
||||||
top_status_source.hh \
|
top_status_source.hh \
|
||||||
|
top_status_source.cfg.hh \
|
||||||
unique_path.hh \
|
unique_path.hh \
|
||||||
url_loader.hh \
|
url_loader.hh \
|
||||||
view_curses.hh \
|
view_curses.hh \
|
||||||
|
@ -68,6 +68,54 @@ struct noop_func {
|
|||||||
namespace lnav {
|
namespace lnav {
|
||||||
namespace func {
|
namespace func {
|
||||||
|
|
||||||
|
class scoped_cb {
|
||||||
|
public:
|
||||||
|
class guard {
|
||||||
|
public:
|
||||||
|
explicit guard(scoped_cb* owner) : g_owner(owner) {}
|
||||||
|
|
||||||
|
guard(const guard&) = delete;
|
||||||
|
guard& operator=(const guard&) = delete;
|
||||||
|
|
||||||
|
guard(guard&& gu) noexcept : g_owner(std::exchange(gu.g_owner, nullptr))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
guard& operator=(guard&& gu) noexcept
|
||||||
|
{
|
||||||
|
this->g_owner = std::exchange(gu.g_owner, nullptr);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~guard()
|
||||||
|
{
|
||||||
|
if (this->g_owner != nullptr) {
|
||||||
|
this->g_owner->s_callback = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
scoped_cb* g_owner;
|
||||||
|
};
|
||||||
|
|
||||||
|
guard install(std::function<void()> cb)
|
||||||
|
{
|
||||||
|
this->s_callback = std::move(cb);
|
||||||
|
|
||||||
|
return guard{this};
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()()
|
||||||
|
{
|
||||||
|
if (s_callback) {
|
||||||
|
s_callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::function<void()> s_callback;
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Fn,
|
template<typename Fn,
|
||||||
typename... Args,
|
typename... Args,
|
||||||
std::enable_if_t<std::is_member_pointer<std::decay_t<Fn>>{}, int> = 0>
|
std::enable_if_t<std::is_member_pointer<std::decay_t<Fn>>{}, int> = 0>
|
||||||
|
@ -90,6 +90,28 @@ struct bind : singleton_storage<T, Annotations...> {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct lifetime {
|
||||||
|
~lifetime()
|
||||||
|
{
|
||||||
|
singleton_storage<T, Annotations...>::ss_owner = nullptr;
|
||||||
|
singleton_storage<T, Annotations...>::ss_data = nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename I = T,
|
||||||
|
std::enable_if_t<has_injectable<I>::value, bool> = true>
|
||||||
|
static lifetime to_scoped_singleton() noexcept
|
||||||
|
{
|
||||||
|
typename I::injectable* i = nullptr;
|
||||||
|
singleton_storage<T, Annotations...>::ss_owner
|
||||||
|
= create_from_injectable<I>(i)();
|
||||||
|
singleton_storage<T, Annotations...>::ss_data
|
||||||
|
= singleton_storage<T, Annotations...>::ss_owner.get();
|
||||||
|
singleton_storage<T, Annotations...>::ss_scope = scope::singleton;
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
static bool to_instance(T* (*f)(Args...)) noexcept
|
static bool to_instance(T* (*f)(Args...)) noexcept
|
||||||
{
|
{
|
||||||
|
@ -55,16 +55,21 @@ void force_linking(Annotation anno);
|
|||||||
template<class...>
|
template<class...>
|
||||||
using void_t = void;
|
using void_t = void;
|
||||||
|
|
||||||
template<class, class = void>
|
template<typename T, typename... Annotations>
|
||||||
struct has_injectable : std::false_type {
|
struct with_annotations {
|
||||||
|
T value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class, class = void>
|
||||||
|
struct has_injectable : std::false_type {};
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct has_injectable<T, void_t<typename T::injectable>> : std::true_type {
|
struct has_injectable<T, void_t<typename T::injectable>> : std::true_type {};
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T, typename... Annotations>
|
template<typename T, typename... Annotations>
|
||||||
struct singleton_storage {
|
struct singleton_storage {
|
||||||
|
static scope get_scope() { return ss_scope; }
|
||||||
|
|
||||||
static T* get()
|
static T* get()
|
||||||
{
|
{
|
||||||
static int _[] = {0, (force_linking(Annotations{}), 0)...};
|
static int _[] = {0, (force_linking(Annotations{}), 0)...};
|
||||||
@ -158,20 +163,16 @@ get()
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct is_shared_ptr : std::false_type {
|
struct is_shared_ptr : std::false_type {};
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct is_shared_ptr<std::shared_ptr<T>> : std::true_type {
|
struct is_shared_ptr<std::shared_ptr<T>> : std::true_type {};
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct is_vector : std::false_type {
|
struct is_vector : std::false_type {};
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct is_vector<std::vector<T>> : std::true_type {
|
struct is_vector<std::vector<T>> : std::true_type {};
|
||||||
};
|
|
||||||
|
|
||||||
template<typename I, typename R, typename... IArgs, typename... Args>
|
template<typename I, typename R, typename... IArgs, typename... Args>
|
||||||
std::function<std::shared_ptr<I>()> create_from_injectable(R (*)(IArgs...),
|
std::function<std::shared_ptr<I>()> create_from_injectable(R (*)(IArgs...),
|
||||||
@ -179,21 +180,27 @@ std::function<std::shared_ptr<I>()> create_from_injectable(R (*)(IArgs...),
|
|||||||
|
|
||||||
template<typename T,
|
template<typename T,
|
||||||
typename... Args,
|
typename... Args,
|
||||||
std::enable_if_t<has_injectable<typename T::element_type>::value,
|
std::enable_if_t<has_injectable<typename T::element_type>::value, bool>
|
||||||
bool> = true,
|
= true,
|
||||||
std::enable_if_t<is_shared_ptr<T>::value, bool> = true>
|
std::enable_if_t<is_shared_ptr<T>::value, bool> = true>
|
||||||
T
|
T
|
||||||
get(Args&... args)
|
get(Args&... args)
|
||||||
{
|
{
|
||||||
typename T::element_type::injectable* i = nullptr;
|
typename T::element_type::injectable* i = nullptr;
|
||||||
|
|
||||||
|
if (singleton_storage<typename T::element_type>::get_scope()
|
||||||
|
== scope::singleton)
|
||||||
|
{
|
||||||
|
return singleton_storage<typename T::element_type>::get_owner();
|
||||||
|
}
|
||||||
return create_from_injectable<typename T::element_type>(i, args...)();
|
return create_from_injectable<typename T::element_type>(i, args...)();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T,
|
template<
|
||||||
|
typename T,
|
||||||
typename... Annotations,
|
typename... Annotations,
|
||||||
std::enable_if_t<!has_injectable<typename T::element_type>::value,
|
std::enable_if_t<!has_injectable<typename T::element_type>::value, bool>
|
||||||
bool> = true,
|
= true,
|
||||||
std::enable_if_t<is_shared_ptr<T>::value, bool> = true>
|
std::enable_if_t<is_shared_ptr<T>::value, bool> = true>
|
||||||
T
|
T
|
||||||
get()
|
get()
|
||||||
|
@ -34,8 +34,6 @@
|
|||||||
|
|
||||||
struct last_relative_time_tag {};
|
struct last_relative_time_tag {};
|
||||||
|
|
||||||
struct sqlite_db_tag {};
|
|
||||||
|
|
||||||
struct sql_cmd_map_tag {};
|
struct sql_cmd_map_tag {};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -66,8 +66,6 @@ SELECT count(*) AS total, min(log_line) AS log_line, log_msg_format
|
|||||||
int
|
int
|
||||||
sql_progress(const struct log_cursor& lc)
|
sql_progress(const struct log_cursor& lc)
|
||||||
{
|
{
|
||||||
static sig_atomic_t sql_counter = 0;
|
|
||||||
|
|
||||||
ssize_t total = lnav_data.ld_log_source.text_line_count();
|
ssize_t total = lnav_data.ld_log_source.text_line_count();
|
||||||
off_t off = lc.lc_curr_line;
|
off_t off = lc.lc_curr_line;
|
||||||
|
|
||||||
@ -83,42 +81,11 @@ sql_progress(const struct log_cursor& lc)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static sig_atomic_t sql_counter = 0;
|
||||||
|
|
||||||
if (ui_periodic_timer::singleton().time_to_update(sql_counter)) {
|
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_bottom_source.update_loading(off, total);
|
||||||
lnav_data.ld_top_source.update_time();
|
lnav_data.ld_status_refresher();
|
||||||
lnav_data.ld_status[LNS_TOP].do_update();
|
|
||||||
lnav_data.ld_status[LNS_BOTTOM].do_update();
|
|
||||||
lnav_data.ld_rl_view->do_update();
|
|
||||||
if (handle_winch()) {
|
|
||||||
layout_views();
|
|
||||||
lnav_data.ld_view_stack.do_update();
|
|
||||||
}
|
|
||||||
refresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -132,9 +99,7 @@ sql_progress_finished()
|
|||||||
}
|
}
|
||||||
|
|
||||||
lnav_data.ld_bottom_source.update_loading(0, 0);
|
lnav_data.ld_bottom_source.update_loading(0, 0);
|
||||||
lnav_data.ld_top_source.update_time();
|
lnav_data.ld_status_refresher();
|
||||||
lnav_data.ld_status[LNS_TOP].do_update();
|
|
||||||
lnav_data.ld_status[LNS_BOTTOM].do_update();
|
|
||||||
lnav_data.ld_views[LNV_DB].redo_search();
|
lnav_data.ld_views[LNV_DB].redo_search();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
101
src/lnav.cc
101
src/lnav.cc
@ -230,8 +230,7 @@ static auto bound_active_files = injector::bind<file_collection>::to_instance(
|
|||||||
+[]() { return &lnav_data.ld_active_files; });
|
+[]() { return &lnav_data.ld_active_files; });
|
||||||
|
|
||||||
static auto bound_sqlite_db
|
static auto bound_sqlite_db
|
||||||
= injector::bind<auto_mem<sqlite3, sqlite_close_wrapper>,
|
= injector::bind<auto_sqlite3>::to_instance(&lnav_data.ld_db);
|
||||||
sqlite_db_tag>::to_instance(&lnav_data.ld_db);
|
|
||||||
|
|
||||||
static auto bound_lnav_flags
|
static auto bound_lnav_flags
|
||||||
= injector::bind<unsigned long, lnav_flags_tag>::to_instance(
|
= injector::bind<unsigned long, lnav_flags_tag>::to_instance(
|
||||||
@ -264,12 +263,6 @@ force_linking(last_relative_time_tag anno)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
|
||||||
void
|
|
||||||
force_linking(sqlite_db_tag anno)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void
|
void
|
||||||
force_linking(lnav_flags_tag anno)
|
force_linking(lnav_flags_tag anno)
|
||||||
@ -1005,6 +998,55 @@ wait_for_pipers()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct refresh_status_bars {
|
||||||
|
refresh_status_bars(std::shared_ptr<top_status_source> top_source)
|
||||||
|
: rsb_top_source(std::move(top_source))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
using injectable
|
||||||
|
= refresh_status_bars(std::shared_ptr<top_status_source> top_source);
|
||||||
|
|
||||||
|
void doit() const
|
||||||
|
{
|
||||||
|
struct timeval current_time {};
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
gettimeofday(¤t_time, nullptr);
|
||||||
|
while ((ch = getch()) != ERR) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->rsb_top_source->update_time(current_time);
|
||||||
|
for (auto& sc : lnav_data.ld_status) {
|
||||||
|
sc.do_update();
|
||||||
|
}
|
||||||
|
lnav_data.ld_rl_view->do_update();
|
||||||
|
if (handle_winch()) {
|
||||||
|
layout_views();
|
||||||
|
lnav_data.ld_view_stack.do_update();
|
||||||
|
}
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<top_status_source> rsb_top_source;
|
||||||
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
looper()
|
looper()
|
||||||
{
|
{
|
||||||
@ -1340,10 +1382,15 @@ looper()
|
|||||||
lnav_data.ld_spectro_source->ss_exec_context
|
lnav_data.ld_spectro_source->ss_exec_context
|
||||||
= &lnav_data.ld_exec_context;
|
= &lnav_data.ld_exec_context;
|
||||||
|
|
||||||
|
auto top_status_lifetime
|
||||||
|
= injector::bind<top_status_source>::to_scoped_singleton();
|
||||||
|
|
||||||
|
auto top_source = injector::get<std::shared_ptr<top_status_source>>();
|
||||||
|
|
||||||
lnav_data.ld_status[LNS_TOP].set_top(0);
|
lnav_data.ld_status[LNS_TOP].set_top(0);
|
||||||
lnav_data.ld_status[LNS_TOP].set_default_role(
|
lnav_data.ld_status[LNS_TOP].set_default_role(
|
||||||
role_t::VCR_INACTIVE_STATUS);
|
role_t::VCR_INACTIVE_STATUS);
|
||||||
lnav_data.ld_status[LNS_TOP].set_data_source(&lnav_data.ld_top_source);
|
lnav_data.ld_status[LNS_TOP].set_data_source(top_source.get());
|
||||||
lnav_data.ld_status[LNS_BOTTOM].set_top(-(rlc->get_height() + 1));
|
lnav_data.ld_status[LNS_BOTTOM].set_top(-(rlc->get_height() + 1));
|
||||||
for (auto& stat_bar : lnav_data.ld_status) {
|
for (auto& stat_bar : lnav_data.ld_status) {
|
||||||
stat_bar.set_window(lnav_data.ld_window);
|
stat_bar.set_window(lnav_data.ld_window);
|
||||||
@ -1381,7 +1428,7 @@ looper()
|
|||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
input_dispatcher& id = lnav_data.ld_input_dispatcher;
|
auto& id = lnav_data.ld_input_dispatcher;
|
||||||
|
|
||||||
id.id_escape_matcher = match_escape_seq;
|
id.id_escape_matcher = match_escape_seq;
|
||||||
id.id_escape_handler = handle_keyseq;
|
id.id_escape_handler = handle_keyseq;
|
||||||
@ -1412,7 +1459,15 @@ looper()
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
ui_periodic_timer& timer = ui_periodic_timer::singleton();
|
auto refresher_lifetime
|
||||||
|
= injector::bind<refresh_status_bars>::to_scoped_singleton();
|
||||||
|
|
||||||
|
auto refresher = injector::get<std::shared_ptr<refresh_status_bars>>();
|
||||||
|
|
||||||
|
auto refresh_guard = lnav_data.ld_status_refresher.install(
|
||||||
|
[refresher]() { refresher->doit(); });
|
||||||
|
|
||||||
|
auto& timer = ui_periodic_timer::singleton();
|
||||||
struct timeval current_time;
|
struct timeval current_time;
|
||||||
|
|
||||||
static sig_atomic_t index_counter;
|
static sig_atomic_t index_counter;
|
||||||
@ -1450,7 +1505,7 @@ looper()
|
|||||||
|
|
||||||
gettimeofday(¤t_time, nullptr);
|
gettimeofday(¤t_time, nullptr);
|
||||||
|
|
||||||
lnav_data.ld_top_source.update_time(current_time);
|
top_source->update_time(current_time);
|
||||||
lnav_data.ld_preview_view.set_needs_update();
|
lnav_data.ld_preview_view.set_needs_update();
|
||||||
|
|
||||||
layout_views();
|
layout_views();
|
||||||
@ -1562,7 +1617,7 @@ looper()
|
|||||||
lnav_data.ld_user_message_view.do_update();
|
lnav_data.ld_user_message_view.do_update();
|
||||||
if (ui_clock::now() >= next_status_update_time) {
|
if (ui_clock::now() >= next_status_update_time) {
|
||||||
echo_views_stmt.execute();
|
echo_views_stmt.execute();
|
||||||
lnav_data.ld_top_source.update_user_msg();
|
top_source->update_user_msg();
|
||||||
for (auto& sc : lnav_data.ld_status) {
|
for (auto& sc : lnav_data.ld_status) {
|
||||||
sc.do_update();
|
sc.do_update();
|
||||||
}
|
}
|
||||||
@ -2150,6 +2205,26 @@ SELECT tbl_name FROM sqlite_master WHERE sql LIKE 'CREATE VIRTUAL TABLE%'
|
|||||||
} while (!done);
|
} while (!done);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XXX
|
||||||
|
lnav_data.ld_log_source.set_preview_sql_filter(nullptr);
|
||||||
|
lnav_data.ld_log_source.set_sql_filter("", nullptr);
|
||||||
|
lnav_data.ld_log_source.set_sql_marker("", nullptr);
|
||||||
|
lnav_config_listener::unload_all();
|
||||||
|
|
||||||
|
{
|
||||||
|
sqlite3_stmt* stmt_iter = nullptr;
|
||||||
|
|
||||||
|
do {
|
||||||
|
stmt_iter = sqlite3_next_stmt(lnav_data.ld_db.in(), stmt_iter);
|
||||||
|
if (stmt_iter != nullptr) {
|
||||||
|
const auto* stmt_sql = sqlite3_sql(stmt_iter);
|
||||||
|
|
||||||
|
log_warning("unfinalized SQL statement: %s", stmt_sql);
|
||||||
|
ensure(false);
|
||||||
|
}
|
||||||
|
} while (stmt_iter != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& drop_stmt : tables_to_drop) {
|
for (auto& drop_stmt : tables_to_drop) {
|
||||||
sqlite3_exec(lnav_data.ld_db.in(),
|
sqlite3_exec(lnav_data.ld_db.in(),
|
||||||
drop_stmt.c_str(),
|
drop_stmt.c_str(),
|
||||||
|
@ -71,7 +71,6 @@
|
|||||||
#include "sql_util.hh"
|
#include "sql_util.hh"
|
||||||
#include "statusview_curses.hh"
|
#include "statusview_curses.hh"
|
||||||
#include "textfile_sub_source.hh"
|
#include "textfile_sub_source.hh"
|
||||||
#include "top_status_source.hh"
|
|
||||||
#include "view_helpers.hh"
|
#include "view_helpers.hh"
|
||||||
|
|
||||||
class spectrogram_source;
|
class spectrogram_source;
|
||||||
@ -184,7 +183,6 @@ struct lnav_data_t {
|
|||||||
ln_mode_t ld_last_config_mode{ln_mode_t::FILTER};
|
ln_mode_t ld_last_config_mode{ln_mode_t::FILTER};
|
||||||
|
|
||||||
statusview_curses ld_status[LNS__MAX];
|
statusview_curses ld_status[LNS__MAX];
|
||||||
top_status_source ld_top_source;
|
|
||||||
bottom_status_source ld_bottom_source;
|
bottom_status_source ld_bottom_source;
|
||||||
filter_status_source ld_filter_status_source;
|
filter_status_source ld_filter_status_source;
|
||||||
filter_help_status_source ld_filter_help_status_source;
|
filter_help_status_source ld_filter_help_status_source;
|
||||||
@ -259,6 +257,8 @@ struct lnav_data_t {
|
|||||||
bool ld_initial_build{false};
|
bool ld_initial_build{false};
|
||||||
bool ld_show_help_view{false};
|
bool ld_show_help_view{false};
|
||||||
|
|
||||||
|
lnav::func::scoped_cb ld_status_refresher;
|
||||||
|
|
||||||
ghc::filesystem::file_time_type ld_last_dot_lnav_time;
|
ghc::filesystem::file_time_type ld_last_dot_lnav_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -85,10 +85,7 @@ do_observer_update(const std::shared_ptr<logfile>& lf)
|
|||||||
if (isendwin()) {
|
if (isendwin()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lnav_data.ld_top_source.update_time();
|
lnav_data.ld_status_refresher();
|
||||||
for (auto& sc : lnav_data.ld_status) {
|
|
||||||
sc.do_update();
|
|
||||||
}
|
|
||||||
if (lf && lnav_data.ld_mode == ln_mode_t::FILES
|
if (lf && lnav_data.ld_mode == ln_mode_t::FILES
|
||||||
&& !lnav_data.ld_initial_build)
|
&& !lnav_data.ld_initial_build)
|
||||||
{
|
{
|
||||||
@ -437,15 +434,7 @@ rescan_files(bool req)
|
|||||||
if (!done && !(lnav_data.ld_flags & LNF_HEADLESS)) {
|
if (!done && !(lnav_data.ld_flags & LNF_HEADLESS)) {
|
||||||
lnav_data.ld_files_view.set_needs_update();
|
lnav_data.ld_files_view.set_needs_update();
|
||||||
lnav_data.ld_files_view.do_update();
|
lnav_data.ld_files_view.do_update();
|
||||||
lnav_data.ld_top_source.update_time();
|
lnav_data.ld_status_refresher();
|
||||||
lnav_data.ld_status[LNS_TOP].do_update();
|
|
||||||
lnav_data.ld_status[LNS_BOTTOM].do_update();
|
|
||||||
lnav_data.ld_rl_view->do_update();
|
|
||||||
if (handle_winch()) {
|
|
||||||
layout_views();
|
|
||||||
lnav_data.ld_view_stack.do_update();
|
|
||||||
}
|
|
||||||
refresh();
|
|
||||||
}
|
}
|
||||||
} while (!done && lnav_data.ld_looping);
|
} while (!done && lnav_data.ld_looping);
|
||||||
return true;
|
return true;
|
||||||
|
@ -96,6 +96,9 @@ static auto scc = injector::bind<sysclip::config>::to_instance(
|
|||||||
static auto lsc = injector::bind<logfile_sub_source_ns::config>::to_instance(
|
static auto lsc = injector::bind<logfile_sub_source_ns::config>::to_instance(
|
||||||
+[]() { return &lnav_config.lc_log_source; });
|
+[]() { return &lnav_config.lc_log_source; });
|
||||||
|
|
||||||
|
static auto tssc = injector::bind<top_status_source_cfg>::to_instance(
|
||||||
|
+[]() { return &lnav_config.lc_top_status_cfg; });
|
||||||
|
|
||||||
bool
|
bool
|
||||||
check_experimental(const char* feature_name)
|
check_experimental(const char* feature_name)
|
||||||
{
|
{
|
||||||
@ -961,7 +964,8 @@ static const struct json_path_container ui_handlers = {
|
|||||||
.with_description("The format for the clock displayed in "
|
.with_description("The format for the clock displayed in "
|
||||||
"the top-left corner using strftime(3) conversions")
|
"the top-left corner using strftime(3) conversions")
|
||||||
.with_example("%a %b %d %H:%M:%S %Z")
|
.with_example("%a %b %d %H:%M:%S %Z")
|
||||||
.for_field(&_lnav_config::lc_ui_clock_format),
|
.for_field(&_lnav_config::lc_top_status_cfg,
|
||||||
|
&top_status_source_cfg::tssc_clock_format),
|
||||||
yajlpp::property_handler("dim-text")
|
yajlpp::property_handler("dim-text")
|
||||||
.with_synopsis("bool")
|
.with_synopsis("bool")
|
||||||
.with_description("Reduce the brightness of text (useful for xterms). "
|
.with_description("Reduce the brightness of text (useful for xterms). "
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
#include "styling.hh"
|
#include "styling.hh"
|
||||||
#include "sysclip.cfg.hh"
|
#include "sysclip.cfg.hh"
|
||||||
#include "tailer/tailer.looper.cfg.hh"
|
#include "tailer/tailer.looper.cfg.hh"
|
||||||
|
#include "top_status_source.cfg.hh"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if an experimental feature should be enabled by
|
* Check if an experimental feature should be enabled by
|
||||||
@ -85,7 +86,7 @@ struct key_map {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct _lnav_config {
|
struct _lnav_config {
|
||||||
std::string lc_ui_clock_format;
|
top_status_source_cfg lc_top_status_cfg;
|
||||||
bool lc_ui_dim_text;
|
bool lc_ui_dim_text;
|
||||||
bool lc_ui_default_colors{true};
|
bool lc_ui_default_colors{true};
|
||||||
std::string lc_ui_keymap;
|
std::string lc_ui_keymap;
|
||||||
|
@ -52,6 +52,16 @@ public:
|
|||||||
|
|
||||||
virtual void reload_config(error_reporter& reporter) {}
|
virtual void reload_config(error_reporter& reporter) {}
|
||||||
|
|
||||||
|
virtual void unload_config() {}
|
||||||
|
|
||||||
|
static void unload_all() {
|
||||||
|
auto* lcl = LISTENER_LIST;
|
||||||
|
while (lcl != nullptr) {
|
||||||
|
lcl->unload_config();
|
||||||
|
lcl = lcl->lcl_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static lnav_config_listener* LISTENER_LIST;
|
static lnav_config_listener* LISTENER_LIST;
|
||||||
|
|
||||||
lnav_config_listener* lcl_next;
|
lnav_config_listener* lcl_next;
|
||||||
|
@ -52,8 +52,7 @@ struct compiled_watch_expr {
|
|||||||
struct expressions : public lnav_config_listener {
|
struct expressions : public lnav_config_listener {
|
||||||
void reload_config(error_reporter& reporter) override
|
void reload_config(error_reporter& reporter) override
|
||||||
{
|
{
|
||||||
auto& lnav_db = injector::get<auto_mem<sqlite3, sqlite_close_wrapper>&,
|
auto& lnav_db = injector::get<auto_sqlite3&>();
|
||||||
sqlite_db_tag>();
|
|
||||||
|
|
||||||
if (lnav_db.in() == nullptr) {
|
if (lnav_db.in() == nullptr) {
|
||||||
log_warning("db not initialized yet!");
|
log_warning("db not initialized yet!");
|
||||||
@ -99,6 +98,10 @@ struct expressions : public lnav_config_listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void unload_config() override {
|
||||||
|
this->e_watch_exprs.clear();
|
||||||
|
}
|
||||||
|
|
||||||
std::map<std::string, compiled_watch_expr> e_watch_exprs;
|
std::map<std::string, compiled_watch_expr> e_watch_exprs;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -114,9 +117,7 @@ eval_with(logfile& lf, logfile::iterator ll)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto& lnav_db
|
static auto& lnav_db = injector::get<auto_sqlite3&>();
|
||||||
= injector::get<auto_mem<sqlite3, sqlite_close_wrapper>&,
|
|
||||||
sqlite_db_tag>();
|
|
||||||
|
|
||||||
char timestamp_buffer[64] = "";
|
char timestamp_buffer[64] = "";
|
||||||
shared_buffer_ref raw_sbr;
|
shared_buffer_ref raw_sbr;
|
||||||
|
@ -1334,12 +1334,17 @@ logfile_sub_source::set_sql_marker(std::string stmt_str, sqlite3_stmt* stmt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->lss_marker_stmt_text = std::move(stmt_str);
|
||||||
|
this->lss_marker_stmt = stmt;
|
||||||
|
|
||||||
|
if (this->tss_view == nullptr) {
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
|
||||||
auto& vis_bm = this->tss_view->get_bookmarks();
|
auto& vis_bm = this->tss_view->get_bookmarks();
|
||||||
auto& expr_marks_bv = vis_bm[&textview_curses::BM_USER_EXPR];
|
auto& expr_marks_bv = vis_bm[&textview_curses::BM_USER_EXPR];
|
||||||
|
|
||||||
expr_marks_bv.clear();
|
expr_marks_bv.clear();
|
||||||
this->lss_marker_stmt_text = std::move(stmt_str);
|
|
||||||
this->lss_marker_stmt = stmt;
|
|
||||||
if (this->lss_index_delegate) {
|
if (this->lss_index_delegate) {
|
||||||
this->lss_index_delegate->index_start(*this);
|
this->lss_index_delegate->index_start(*this);
|
||||||
}
|
}
|
||||||
|
@ -175,9 +175,7 @@ replace_home_dir(std::string path)
|
|||||||
Result<void, lnav::console::user_message>
|
Result<void, lnav::console::user_message>
|
||||||
export_to(FILE* file)
|
export_to(FILE* file)
|
||||||
{
|
{
|
||||||
static auto& lnav_db
|
static auto& lnav_db = injector::get<auto_sqlite3&>();
|
||||||
= injector::get<auto_mem<sqlite3, sqlite_close_wrapper>&,
|
|
||||||
sqlite_db_tag>();
|
|
||||||
|
|
||||||
static const char* BOOKMARK_QUERY = R"(
|
static const char* BOOKMARK_QUERY = R"(
|
||||||
SELECT log_time_msecs, log_format, log_mark, log_comment, log_tags, log_line_hash
|
SELECT log_time_msecs, log_format, log_mark, log_comment, log_tags, log_line_hash
|
||||||
|
@ -45,9 +45,7 @@ sql_cmd_dump(exec_context& ec,
|
|||||||
std::string cmdline,
|
std::string cmdline,
|
||||||
std::vector<std::string>& args)
|
std::vector<std::string>& args)
|
||||||
{
|
{
|
||||||
static auto& lnav_db
|
static auto& lnav_db = injector::get<auto_sqlite3&>();
|
||||||
= injector::get<auto_mem<sqlite3, sqlite_close_wrapper>&,
|
|
||||||
sqlite_db_tag>();
|
|
||||||
static auto& lnav_flags = injector::get<unsigned long&, lnav_flags_tag>();
|
static auto& lnav_flags = injector::get<unsigned long&, lnav_flags_tag>();
|
||||||
|
|
||||||
std::string retval;
|
std::string retval;
|
||||||
@ -90,9 +88,7 @@ sql_cmd_read(exec_context& ec,
|
|||||||
std::string cmdline,
|
std::string cmdline,
|
||||||
std::vector<std::string>& args)
|
std::vector<std::string>& args)
|
||||||
{
|
{
|
||||||
static auto& lnav_db
|
static auto& lnav_db = injector::get<auto_sqlite3&>();
|
||||||
= injector::get<auto_mem<sqlite3, sqlite_close_wrapper>&,
|
|
||||||
sqlite_db_tag>();
|
|
||||||
static auto& lnav_flags = injector::get<unsigned long&, lnav_flags_tag>();
|
static auto& lnav_flags = injector::get<unsigned long&, lnav_flags_tag>();
|
||||||
|
|
||||||
std::string retval;
|
std::string retval;
|
||||||
|
@ -43,6 +43,8 @@
|
|||||||
/* XXX figure out how to do this with the template */
|
/* XXX figure out how to do this with the template */
|
||||||
void sqlite_close_wrapper(void* mem);
|
void sqlite_close_wrapper(void* mem);
|
||||||
|
|
||||||
|
using auto_sqlite3 = auto_mem<sqlite3, sqlite_close_wrapper>;
|
||||||
|
|
||||||
namespace sqlitepp {
|
namespace sqlitepp {
|
||||||
|
|
||||||
inline auto_mem<char>
|
inline auto_mem<char>
|
||||||
|
@ -455,9 +455,7 @@ textfile_sub_source::rescan_files(
|
|||||||
textfile_sub_source::scan_callback& callback,
|
textfile_sub_source::scan_callback& callback,
|
||||||
nonstd::optional<ui_clock::time_point> deadline)
|
nonstd::optional<ui_clock::time_point> deadline)
|
||||||
{
|
{
|
||||||
static auto& lnav_db
|
static auto& lnav_db = injector::get<auto_sqlite3&>();
|
||||||
= injector::get<auto_mem<sqlite3, sqlite_close_wrapper>&,
|
|
||||||
sqlite_db_tag>();
|
|
||||||
|
|
||||||
file_iterator iter;
|
file_iterator iter;
|
||||||
bool retval = false;
|
bool retval = false;
|
||||||
|
@ -29,22 +29,31 @@
|
|||||||
|
|
||||||
#include "top_status_source.hh"
|
#include "top_status_source.hh"
|
||||||
|
|
||||||
#include <sqlite3.h>
|
|
||||||
|
|
||||||
#include "base/injector.hh"
|
#include "base/injector.hh"
|
||||||
#include "bound_tags.hh"
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "lnav.hh"
|
#include "lnav.hh"
|
||||||
#include "lnav_config.hh"
|
|
||||||
#include "logfile_sub_source.hh"
|
|
||||||
#include "md2attr_line.hh"
|
#include "md2attr_line.hh"
|
||||||
#include "md4cpp.hh"
|
#include "md4cpp.hh"
|
||||||
#include "shlex.hh"
|
#include "shlex.hh"
|
||||||
#include "shlex.resolver.hh"
|
#include "shlex.resolver.hh"
|
||||||
#include "sql_util.hh"
|
#include "sql_util.hh"
|
||||||
#include "sqlitepp.client.hh"
|
#include "sqlitepp.client.hh"
|
||||||
|
#include "top_status_source.cfg.hh"
|
||||||
|
|
||||||
top_status_source::top_status_source()
|
static const char* MSG_QUERY = R"(
|
||||||
|
SELECT message FROM lnav_user_notifications
|
||||||
|
WHERE message IS NOT NULL AND
|
||||||
|
(expiration IS NULL OR expiration > datetime('now')) AND
|
||||||
|
(views IS NULL OR
|
||||||
|
json_contains(views, (SELECT name FROM lnav_top_view)))
|
||||||
|
ORDER BY priority DESC
|
||||||
|
LIMIT 1
|
||||||
|
)";
|
||||||
|
|
||||||
|
top_status_source::top_status_source(auto_sqlite3& db,
|
||||||
|
const top_status_source_cfg& cfg)
|
||||||
|
: tss_config(cfg),
|
||||||
|
tss_user_msgs_stmt(prepare_stmt(db.in(), MSG_QUERY).unwrap())
|
||||||
{
|
{
|
||||||
this->tss_fields[TSF_TIME].set_width(28);
|
this->tss_fields[TSF_TIME].set_width(28);
|
||||||
this->tss_fields[TSF_TIME].set_role(role_t::VCR_STATUS_INFO);
|
this->tss_fields[TSF_TIME].set_role(role_t::VCR_STATUS_INFO);
|
||||||
@ -62,7 +71,7 @@ top_status_source::update_time(const timeval& current_time)
|
|||||||
buffer[0] = ' ';
|
buffer[0] = ' ';
|
||||||
strftime(&buffer[1],
|
strftime(&buffer[1],
|
||||||
sizeof(buffer) - 1,
|
sizeof(buffer) - 1,
|
||||||
lnav_config.lc_ui_clock_format.c_str(),
|
this->tss_config.tssc_clock_format.c_str(),
|
||||||
localtime(¤t_time.tv_sec));
|
localtime(¤t_time.tv_sec));
|
||||||
sf.set_value(buffer);
|
sf.set_value(buffer);
|
||||||
}
|
}
|
||||||
@ -76,40 +85,14 @@ top_status_source::update_time()
|
|||||||
this->update_time(tv);
|
this->update_time(tv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* MSG_QUERY = R"(
|
|
||||||
SELECT message FROM lnav_user_notifications
|
|
||||||
WHERE message IS NOT NULL AND
|
|
||||||
(expiration IS NULL OR expiration > datetime('now')) AND
|
|
||||||
(views IS NULL OR
|
|
||||||
json_contains(views, (SELECT name FROM lnav_top_view)))
|
|
||||||
ORDER BY priority DESC
|
|
||||||
LIMIT 1
|
|
||||||
)";
|
|
||||||
|
|
||||||
struct user_msg_stmt {
|
|
||||||
user_msg_stmt()
|
|
||||||
: ums_stmt(
|
|
||||||
prepare_stmt(injector::get<auto_mem<sqlite3, sqlite_close_wrapper>&,
|
|
||||||
sqlite_db_tag>()
|
|
||||||
.in(),
|
|
||||||
MSG_QUERY)
|
|
||||||
.unwrap())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
prepared_stmt ums_stmt;
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
void
|
||||||
top_status_source::update_user_msg()
|
top_status_source::update_user_msg()
|
||||||
{
|
{
|
||||||
static thread_local user_msg_stmt um_stmt;
|
|
||||||
|
|
||||||
auto& al = this->tss_fields[TSF_USER_MSG].get_value();
|
auto& al = this->tss_fields[TSF_USER_MSG].get_value();
|
||||||
al.clear();
|
al.clear();
|
||||||
|
|
||||||
um_stmt.ums_stmt.reset();
|
this->tss_user_msgs_stmt.reset();
|
||||||
auto fetch_res = um_stmt.ums_stmt.fetch_row<std::string>();
|
auto fetch_res = this->tss_user_msgs_stmt.fetch_row<std::string>();
|
||||||
fetch_res.match(
|
fetch_res.match(
|
||||||
[&al](const std::string& value) {
|
[&al](const std::string& value) {
|
||||||
shlex lexer(value);
|
shlex lexer(value);
|
||||||
|
37
src/top_status_source.cfg.hh
Normal file
37
src/top_status_source.cfg.hh
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2022, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef lnav_top_status_source_cfg_hh
|
||||||
|
#define lnav_top_status_source_cfg_hh
|
||||||
|
|
||||||
|
struct top_status_source_cfg {
|
||||||
|
std::string tssc_clock_format;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -32,19 +32,30 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <sqlite3.h>
|
||||||
|
|
||||||
|
#include "base/injector.hh"
|
||||||
|
#include "bound_tags.hh"
|
||||||
#include "listview_curses.hh"
|
#include "listview_curses.hh"
|
||||||
|
#include "sql_util.hh"
|
||||||
|
#include "sqlitepp.client.hh"
|
||||||
#include "statusview_curses.hh"
|
#include "statusview_curses.hh"
|
||||||
|
#include "top_status_source.cfg.hh"
|
||||||
|
|
||||||
class top_status_source : public status_data_source {
|
class top_status_source : public status_data_source {
|
||||||
public:
|
public:
|
||||||
typedef enum {
|
enum field_t {
|
||||||
TSF_TIME,
|
TSF_TIME,
|
||||||
TSF_USER_MSG,
|
TSF_USER_MSG,
|
||||||
|
|
||||||
TSF__MAX
|
TSF__MAX
|
||||||
} field_t;
|
};
|
||||||
|
|
||||||
top_status_source();
|
explicit top_status_source(auto_sqlite3& db,
|
||||||
|
const top_status_source_cfg& cfg);
|
||||||
|
|
||||||
|
using injectable
|
||||||
|
= top_status_source(auto_sqlite3& db, const top_status_source_cfg& cfg);
|
||||||
|
|
||||||
size_t statusview_fields() override { return TSF__MAX; }
|
size_t statusview_fields() override { return TSF__MAX; }
|
||||||
|
|
||||||
@ -60,7 +71,9 @@ public:
|
|||||||
void update_user_msg();
|
void update_user_msg();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
const top_status_source_cfg& tss_config;
|
||||||
status_field tss_fields[TSF__MAX];
|
status_field tss_fields[TSF__MAX];
|
||||||
|
prepared_stmt tss_user_msgs_stmt;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -294,6 +294,8 @@ EXPECTED_FILES = \
|
|||||||
$(srcdir)/%reldir%/test_logfile.sh_09bd16e044302f6b121092534708594bdad11b5a.out \
|
$(srcdir)/%reldir%/test_logfile.sh_09bd16e044302f6b121092534708594bdad11b5a.out \
|
||||||
$(srcdir)/%reldir%/test_logfile.sh_1c6eee38f66356fcd9a9f0faedaea6dbcc901060.err \
|
$(srcdir)/%reldir%/test_logfile.sh_1c6eee38f66356fcd9a9f0faedaea6dbcc901060.err \
|
||||||
$(srcdir)/%reldir%/test_logfile.sh_1c6eee38f66356fcd9a9f0faedaea6dbcc901060.out \
|
$(srcdir)/%reldir%/test_logfile.sh_1c6eee38f66356fcd9a9f0faedaea6dbcc901060.out \
|
||||||
|
$(srcdir)/%reldir%/test_logfile.sh_218ecb88b4753010c4264b3ac351260b4811612f.err \
|
||||||
|
$(srcdir)/%reldir%/test_logfile.sh_218ecb88b4753010c4264b3ac351260b4811612f.out \
|
||||||
$(srcdir)/%reldir%/test_logfile.sh_290a3c49e53c2229a7400c107338fa0bb38375e2.err \
|
$(srcdir)/%reldir%/test_logfile.sh_290a3c49e53c2229a7400c107338fa0bb38375e2.err \
|
||||||
$(srcdir)/%reldir%/test_logfile.sh_290a3c49e53c2229a7400c107338fa0bb38375e2.out \
|
$(srcdir)/%reldir%/test_logfile.sh_290a3c49e53c2229a7400c107338fa0bb38375e2.out \
|
||||||
$(srcdir)/%reldir%/test_logfile.sh_3fc6bfd8a6160817211f3e14fde957af75b9dbe7.err \
|
$(srcdir)/%reldir%/test_logfile.sh_3fc6bfd8a6160817211f3e14fde957af75b9dbe7.err \
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
[1m[4mbasename(filepath) [0m[1m[4m descriptor [0m[1m[4m mimetype [0m[1m[4m content [0m
|
||||||
|
[1mlogfile_syslog.1.gz[0m[1m [0m[1mnet.zlib.gzip.header[0m[1m [0m[1mapplication/json[0m[1m [0m[1m{"name":"logfile_syslog.1","mtime":"2007-11-03T16:23:00.000","comment":""} [0m
|
@ -697,5 +697,5 @@ run_cap_test ${lnav_test} -n \
|
|||||||
${test_dir}/logfile_ansi.1
|
${test_dir}/logfile_ansi.1
|
||||||
|
|
||||||
run_cap_test ${lnav_test} -n \
|
run_cap_test ${lnav_test} -n \
|
||||||
-c ';SELECT * FROM lnav_file_metadata' \
|
-c ';SELECT basename(filepath),descriptor,mimetype,content FROM lnav_file_metadata' \
|
||||||
logfile_syslog.1.gz
|
logfile_syslog.1.gz
|
||||||
|
@ -72,11 +72,6 @@ rebuild_indexes_repeatedly()
|
|||||||
readline_context::command_map_t lnav_commands;
|
readline_context::command_map_t lnav_commands;
|
||||||
|
|
||||||
namespace injector {
|
namespace injector {
|
||||||
template<>
|
|
||||||
void
|
|
||||||
force_linking(sqlite_db_tag anno)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void
|
void
|
||||||
|
@ -51,7 +51,15 @@ main(int argc, char* argv[])
|
|||||||
{
|
{
|
||||||
int retval = EXIT_SUCCESS;
|
int retval = EXIT_SUCCESS;
|
||||||
|
|
||||||
top_status_source tss;
|
auto_sqlite3 db;
|
||||||
|
|
||||||
|
if (sqlite3_open(":memory:", db.out()) != SQLITE_OK) {
|
||||||
|
fprintf(stderr, "error: unable to create sqlite memory database\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
top_status_source_cfg cfg;
|
||||||
|
top_status_source tss(db, cfg);
|
||||||
|
|
||||||
setenv("HOME", "/", 1);
|
setenv("HOME", "/", 1);
|
||||||
|
|
||||||
@ -72,7 +80,7 @@ main(int argc, char* argv[])
|
|||||||
tss.update_time();
|
tss.update_time();
|
||||||
assert(val.get_string() != sf.get_value().get_string());
|
assert(val.get_string() != sf.get_value().get_string());
|
||||||
|
|
||||||
lnav_config.lc_ui_clock_format = "abc";
|
cfg.tssc_clock_format = "abc";
|
||||||
tss.update_time();
|
tss.update_time();
|
||||||
val = sf.get_value();
|
val = sf.get_value();
|
||||||
assert(val.get_string() == " abc");
|
assert(val.get_string() == " abc");
|
||||||
|
Loading…
Reference in New Issue
Block a user