From 99c1688c2e8272cb6678751e62d18853a366d595 Mon Sep 17 00:00:00 2001 From: Timothy Stack Date: Thu, 31 Mar 2022 23:21:59 -0700 Subject: [PATCH] [attr_line] use variant instead of a union for attribute values --- CMakeLists.txt | 10 +- aminclude_static.am | 2 +- m4/ax_cxx_compile_stdcxx_17.m4 | 35 ++++++ src/ansi_scrubber.cc | 8 +- src/attr_line.cc | 7 +- src/attr_line.hh | 202 +++++++++++++++---------------- src/base/opt_util.hh | 1 - src/bottom_status_source.cc | 8 +- src/db_sub_source.cc | 16 +-- src/field_overlay_source.cc | 98 +++++++-------- src/field_overlay_source.hh | 6 +- src/files_sub_source.cc | 42 ++++--- src/filter_status_source.cc | 4 +- src/filter_sub_source.cc | 28 +++-- src/help_text_formatter.cc | 118 +++++++++--------- src/highlighter.cc | 13 +- src/hist_source.hh | 2 +- src/hotkeys.cc | 8 +- src/lnav_commands.cc | 10 +- src/log_format.cc | 43 +++---- src/log_format_fwd.hh | 14 +-- src/log_format_impls.cc | 17 ++- src/logfile_sub_source.cc | 86 +++++++------ src/optional.hpp | 15 ++- src/readline_callbacks.cc | 2 +- src/readline_highlighters.cc | 150 +++++++++++------------ src/spectro_source.cc | 8 +- src/sql_help.hh | 16 +-- src/sql_util.cc | 24 ++-- src/state-extension-functions.cc | 6 +- src/statusview_curses.cc | 17 +-- src/string_attr_type.cc | 15 ++- src/string_attr_type.hh | 53 ++++---- src/term_extra.hh | 7 +- src/textfile_sub_source.cc | 2 +- src/textview_curses.cc | 9 +- src/top_status_source.cc | 13 +- src/view_curses.cc | 90 ++++++-------- src/view_curses.hh | 18 +-- src/views_vtab.cc | 6 +- test/drive_mvwattrline.cc | 33 ++--- test/drive_view_colors.cc | 13 +- test/test_ansi_scrubber.cc | 4 +- 43 files changed, 651 insertions(+), 628 deletions(-) create mode 100644 m4/ax_cxx_compile_stdcxx_17.m4 diff --git a/CMakeLists.txt b/CMakeLists.txt index eb497dab..f61645d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,11 +4,11 @@ include(cmake/prelude.cmake) set(CMAKE_CXX_STANDARD 14) project( - lnav - VERSION 0.10.2 - DESCRIPTION "An advanced log file viewer for the small-scale." - HOMEPAGE_URL "https://lnav.org/" - LANGUAGES CXX C + lnav + VERSION 0.10.2 + DESCRIPTION "An advanced log file viewer for the small-scale." + HOMEPAGE_URL "https://lnav.org/" + LANGUAGES CXX C ) include(cmake/project-is-top-level.cmake) diff --git a/aminclude_static.am b/aminclude_static.am index 01f5023f..587f7b11 100644 --- a/aminclude_static.am +++ b/aminclude_static.am @@ -1,6 +1,6 @@ # aminclude_static.am generated automatically by Autoconf -# from AX_AM_MACROS_STATIC on Tue Mar 22 21:37:32 PDT 2022 +# from AX_AM_MACROS_STATIC on Thu Mar 31 15:28:54 PDT 2022 # Code coverage diff --git a/m4/ax_cxx_compile_stdcxx_17.m4 b/m4/ax_cxx_compile_stdcxx_17.m4 new file mode 100644 index 00000000..a6834171 --- /dev/null +++ b/m4/ax_cxx_compile_stdcxx_17.m4 @@ -0,0 +1,35 @@ +# ============================================================================= +# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_17.html +# ============================================================================= +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX_17([ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the C++17 +# standard; if necessary, add switches to CXX and CXXCPP to enable +# support. +# +# This macro is a convenience alias for calling the AX_CXX_COMPILE_STDCXX +# macro with the version set to C++17. The two optional arguments are +# forwarded literally as the second and third argument respectively. +# Please see the documentation for the AX_CXX_COMPILE_STDCXX macro for +# more information. If you want to use this macro, you also need to +# download the ax_cxx_compile_stdcxx.m4 file. +# +# LICENSE +# +# Copyright (c) 2015 Moritz Klammler +# Copyright (c) 2016 Krzesimir Nowak +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 2 + +AX_REQUIRE_DEFINED([AX_CXX_COMPILE_STDCXX]) +AC_DEFUN([AX_CXX_COMPILE_STDCXX_17], [AX_CXX_COMPILE_STDCXX([17], [$1], [$2])]) diff --git a/src/ansi_scrubber.cc b/src/ansi_scrubber.cc index d20110e7..844e3a64 100644 --- a/src/ansi_scrubber.cc +++ b/src/ansi_scrubber.cc @@ -158,16 +158,16 @@ scrub_ansi_string(std::string& str, string_attrs_t& sa) lr.lr_start = caps[0].c_begin; lr.lr_end = -1; if (attrs) { - sa.emplace_back(lr, &view_curses::VC_STYLE, attrs); + sa.emplace_back(lr, view_curses::VC_STYLE.value(attrs)); } role | [&lr, &sa](int r) { - sa.emplace_back(lr, &view_curses::VC_ROLE, r); + sa.emplace_back(lr, view_curses::VC_ROLE.value(r)); }; fg | [&lr, &sa](int color) { - sa.emplace_back(lr, &view_curses::VC_FOREGROUND, color); + sa.emplace_back(lr, view_curses::VC_FOREGROUND.value(color)); }; bg | [&lr, &sa](int color) { - sa.emplace_back(lr, &view_curses::VC_BACKGROUND, color); + sa.emplace_back(lr, view_curses::VC_BACKGROUND.value(color)); }; } diff --git a/src/attr_line.cc b/src/attr_line.cc index 543c1d25..d395bb1f 100644 --- a/src/attr_line.cc +++ b/src/attr_line.cc @@ -181,15 +181,14 @@ attr_line_t::subline(size_t start, size_t len) const attr_line_t retval; retval.al_string = this->al_string.substr(start, len); - for (auto& sa : this->al_attrs) { + for (const auto& sa : this->al_attrs) { if (!lr.intersects(sa.sa_range)) { continue; } retval.al_attrs.emplace_back( lr.intersection(sa.sa_range).shift(lr.lr_start, -lr.lr_start), - sa.sa_type, - sa.sa_value); + std::make_pair(sa.sa_type, sa.sa_value)); line_range& last_lr = retval.al_attrs.back().sa_range; @@ -267,7 +266,7 @@ attr_line_t::apply_hide() this->al_string.replace(lr.lr_start, lr.length(), "\xE2\x8B\xAE"); shift_string_attrs(sa, lr.lr_start + 1, -(lr.length() - 3)); sattr.sa_type = &view_curses::VC_ROLE; - sattr.sa_value.sav_int = view_colors::VCR_HIDDEN; + sattr.sa_value = view_colors::VCR_HIDDEN; lr.lr_end = lr.lr_start + 3; } } diff --git a/src/attr_line.hh b/src/attr_line.hh index 84e21f21..2a33e083 100644 --- a/src/attr_line.hh +++ b/src/attr_line.hh @@ -32,6 +32,7 @@ #ifndef attr_line_hh #define attr_line_hh +#include #include #include @@ -60,22 +61,27 @@ struct line_range { int length() const { return this->lr_end == -1 ? INT_MAX : this->lr_end - this->lr_start; - }; + } + + int end_for_string(const std::string& str) const + { + return this->lr_end == -1 ? str.length() : this->lr_end; + } bool contains(int pos) const { return this->lr_start <= pos && pos < this->lr_end; - }; + } bool contains(const struct line_range& other) const { return this->contains(other.lr_start) && other.lr_end <= this->lr_end; - }; + } bool intersects(const struct line_range& other) const { return this->contains(other.lr_start) || this->contains(other.lr_end); - }; + } line_range intersection(const struct line_range& other) const; @@ -86,7 +92,7 @@ struct line_range { while (this->lr_start < this->lr_end && isspace(str[this->lr_start])) { this->lr_start += 1; } - }; + } bool operator<(const struct line_range& rhs) const { @@ -104,12 +110,12 @@ struct line_range { return true; } return false; - }; + } bool operator==(const struct line_range& rhs) const { return (this->lr_start == rhs.lr_start && this->lr_end == rhs.lr_end); - }; + } const char* substr(const std::string& str) const { @@ -140,76 +146,35 @@ typedef union { } string_attr_value_t; struct string_attr { - string_attr(const struct line_range& lr, string_attr_type_t type, void* val) - : sa_range(lr), sa_type(type) - { - require(lr.is_valid()); - require(type); - this->sa_value.sav_ptr = val; - }; - - string_attr(const struct line_range& lr, - string_attr_type_t type, - std::string val) - : sa_range(lr), sa_type(type), sa_str_value(std::move(val)) - { - require(lr.is_valid()); - require(type); - }; - - string_attr(const struct line_range& lr, - string_attr_type_t type, - intern_string_t val) - : sa_range(lr), sa_type(type) - { - require(lr.is_valid()); - require(type); - this->sa_value.sav_ptr = val.unwrap(); - }; - - string_attr(const struct line_range& lr, - string_attr_type_t type, - int64_t val = 0) - : sa_range(lr), sa_type(type) - { - require(lr.is_valid()); - require(type); - this->sa_value.sav_int = val; - }; - - string_attr(const struct line_range& lr, - string_attr_type_t type, - string_attr_value_t val) - : sa_range(lr), sa_type(type), sa_value(val) - { - require(lr.is_valid()); - require(type); - }; - - string_attr(const struct line_range& lr, - std::pair value) - : sa_range(lr), sa_type2(value.first), sa_value2(value.second) + string_attr( + const struct line_range& lr, + const std::pair& value) + : sa_range(lr), sa_type(value.first), sa_value(value.second) { } - string_attr() : sa_type(nullptr){}; + string_attr() = default; bool operator<(const struct string_attr& rhs) const { return this->sa_range < rhs.sa_range; - }; - - intern_string_t to_string() const - { - return {(const intern_string*) this->sa_value.sav_ptr}; - }; + } struct line_range sa_range; - string_attr_type_t sa_type; - string_attr_value_t sa_value; - std::string sa_str_value; - string_attr_type_base* sa_type2; - string_attr_value sa_value2; + const string_attr_type_base* sa_type{nullptr}; + string_attr_value sa_value; +}; + +template +struct string_attr_wrapper { + explicit string_attr_wrapper(const string_attr* sa) : saw_string_attr(sa) {} + + const T& get() const + { + return this->saw_string_attr->sa_value.template get(); + } + + const string_attr* saw_string_attr; }; /** A map of line ranges to attributes for that range. */ @@ -217,7 +182,7 @@ using string_attrs_t = std::vector; inline string_attrs_t::const_iterator find_string_attr(const string_attrs_t& sa, - string_attr_type_t type, + const string_attr_type_base* type, int start = 0) { string_attrs_t::const_iterator iter; @@ -233,7 +198,7 @@ find_string_attr(const string_attrs_t& sa, inline nonstd::optional get_string_attr(const string_attrs_t& sa, - string_attr_type_t type, + const string_attr_type_base* type, int start = 0) { auto iter = find_string_attr(sa, type, start); @@ -245,10 +210,25 @@ get_string_attr(const string_attrs_t& sa, return nonstd::make_optional(&(*iter)); } +template +inline nonstd::optional> +get_string_attr(const string_attrs_t& sa, + const string_attr_type& type, + int start = 0) +{ + auto iter = find_string_attr(sa, &type, start); + + if (iter == sa.end()) { + return nonstd::nullopt; + } + + return nonstd::make_optional(string_attr_wrapper(&(*iter))); +} + template inline string_attrs_t::const_iterator find_string_attr_containing(const string_attrs_t& sa, - string_attr_type_t type, + const string_attr_type_base* type, T x) { string_attrs_t::const_iterator iter; @@ -328,7 +308,7 @@ rfind_string_attr_if(const string_attrs_t& sa, ssize_t near, T predicate) } inline struct line_range -find_string_attr_range(const string_attrs_t& sa, string_attr_type_t type) +find_string_attr_range(const string_attrs_t& sa, string_attr_type_base* type) { auto iter = find_string_attr(sa, type); @@ -350,7 +330,7 @@ remove_string_attr(string_attrs_t& sa, const struct line_range& lr) } inline void -remove_string_attr(string_attrs_t& sa, string_attr_type_t type) +remove_string_attr(string_attrs_t& sa, string_attr_type_base* type) { for (auto iter = sa.begin(); iter != sa.end();) { if (iter->sa_type == type) { @@ -374,13 +354,13 @@ struct text_wrap_settings { { this->tws_indent = indent; return *this; - }; + } text_wrap_settings& with_width(int width) { this->tws_width = width; return *this; - }; + } int tws_indent{2}; int tws_width{80}; @@ -394,46 +374,46 @@ public: attr_line_t() { this->al_attrs.reserve(RESERVE_SIZE); - }; + } attr_line_t(std::string str) : al_string(std::move(str)) { this->al_attrs.reserve(RESERVE_SIZE); - }; + } attr_line_t(const char* str) : al_string(str) { this->al_attrs.reserve(RESERVE_SIZE); - }; + } static inline attr_line_t from_ansi_str(const char* str) { attr_line_t retval; return retval.with_ansi_string("%s", str); - }; + } /** @return The string itself. */ std::string& get_string() { return this->al_string; - }; + } const std::string& get_string() const { return this->al_string; - }; + } /** @return The attributes for the string. */ string_attrs_t& get_attrs() { return this->al_attrs; - }; + } const string_attrs_t& get_attrs() const { return this->al_attrs; - }; + } attr_line_t& with_string(const std::string& str) { @@ -449,7 +429,7 @@ public: { this->al_attrs.push_back(sa); return *this; - }; + } attr_line_t& ensure_space() { @@ -460,28 +440,37 @@ public: } return *this; - }; + } - template - attr_line_t& append(S str, string_attr_type_t type = nullptr, T val = T()) + template + attr_line_t& append( + S str, + const std::pair& value) { size_t start_len = this->al_string.length(); this->al_string.append(str); - if (type != nullptr) { - line_range lr{(int) start_len, (int) this->al_string.length()}; - this->al_attrs.emplace_back(lr, type, val); - } + line_range lr{(int) start_len, (int) this->al_string.length()}; + + this->al_attrs.emplace_back(lr, value); + return *this; - }; + } + + template + attr_line_t& append(S str) + { + this->al_string.append(str); + return *this; + } attr_line_t& append(const char* str, size_t len) { this->al_string.append(str, len); return *this; - }; + } attr_line_t& insert(size_t index, const attr_line_t& al, @@ -491,13 +480,13 @@ public: text_wrap_settings* tws = nullptr) { return this->insert(this->al_string.length(), al, tws); - }; + } attr_line_t& append(size_t len, char c) { this->al_string.append(len, c); return *this; - }; + } attr_line_t& insert(size_t index, size_t len, char c) { @@ -524,7 +513,7 @@ public: shift_string_attrs(this->al_attrs, pos, -((int32_t) len)); return *this; - }; + } attr_line_t& erase_utf8_chars(size_t start) { @@ -532,7 +521,7 @@ public: this->erase(byte_index); return *this; - }; + } attr_line_t& right_justify(unsigned long width); @@ -548,15 +537,22 @@ public: } return retval; - }; + } std::string get_substring(const line_range& lr) const { if (!lr.is_valid()) { return ""; } - return this->al_string.substr(lr.lr_start, lr.length()); - }; + return this->al_string.substr(lr.lr_start, lr.sublen(this->al_string)); + } + + string_fragment to_string_fragment(string_attrs_t::const_iterator iter) + { + return string_fragment(this->al_string.c_str(), + iter->sa_range.lr_start, + iter->sa_range.end_for_string(this->al_string)); + } string_attrs_t::const_iterator find_attr(size_t near) const { @@ -567,12 +563,12 @@ public: } return find_string_attr(this->al_attrs, near); - }; + } bool empty() const { return this->length() == 0; - }; + } /** Clear the string and the attributes for the string. */ attr_line_t& clear() @@ -581,7 +577,7 @@ public: this->al_attrs.clear(); return *this; - }; + } attr_line_t subline(size_t start, size_t len = std::string::npos) const; diff --git a/src/base/opt_util.hh b/src/base/opt_util.hh index 3c28596d..aea038ef 100644 --- a/src/base/opt_util.hh +++ b/src/base/opt_util.hh @@ -32,7 +32,6 @@ #include -#include "intern_string.hh" #include "optional.hpp" namespace detail { diff --git a/src/bottom_status_source.cc b/src/bottom_status_source.cc index d7dccf8d..2a0b4e3d 100644 --- a/src/bottom_status_source.cc +++ b/src/bottom_status_source.cc @@ -74,10 +74,10 @@ bottom_status_source::update_line_number(listview_curses* lc) lc->get_data_source()->listview_value_for_rows( *lc, lc->get_top(), rows); - auto& sa = rows[0].get_attrs(); - auto iter = find_string_attr(sa, &SA_ERROR); - if (iter != sa.end()) { - this->bss_line_error.set_value(iter->sa_str_value); + const auto& sa = rows[0].get_attrs(); + auto error_wrapper = get_string_attr(sa, SA_ERROR); + if (error_wrapper) { + this->bss_line_error.set_value(error_wrapper.value().get()); } else { this->bss_line_error.clear(); } diff --git a/src/db_sub_source.cc b/src/db_sub_source.cc index 606a7873..9b73c25c 100644 --- a/src/db_sub_source.cc +++ b/src/db_sub_source.cc @@ -112,11 +112,11 @@ 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, &view_curses::VC_STYLE, A_BOLD); + sa.emplace_back(lr2, view_curses::VC_STYLE.value(A_BOLD)); } lr.lr_start += this->dls_cell_width[lpc]; lr.lr_end = lr.lr_start + 1; - sa.emplace_back(lr, &view_curses::VC_GRAPHIC, ACS_VLINE); + sa.emplace_back(lr, view_curses::VC_GRAPHIC.value(ACS_VLINE)); lr.lr_start += 1; } @@ -344,10 +344,10 @@ db_overlay_source::list_overlay_count(const listview_curses& lv) string_attrs_t& sa = this->dos_lines.back().get_attrs(); struct line_range lr(1, 2); - sa.emplace_back(lr, &view_curses::VC_GRAPHIC, ACS_LTEE); + sa.emplace_back(lr, view_curses::VC_GRAPHIC.value(ACS_LTEE)); lr.lr_start = 3 + jpw_value.wt_ptr.size() + 3; lr.lr_end = -1; - sa.emplace_back(lr, &view_curses::VC_STYLE, A_BOLD); + sa.emplace_back(lr, view_curses::VC_STYLE.value(A_BOLD)); double num_value = 0.0; @@ -390,10 +390,10 @@ db_overlay_source::list_overlay_count(const listview_curses& lv) string_attrs_t& sa = this->dos_lines.back().get_attrs(); struct line_range lr(1, 2); - sa.emplace_back(lr, &view_curses::VC_GRAPHIC, ACS_LLCORNER); + sa.emplace_back(lr, view_curses::VC_GRAPHIC.value(ACS_LLCORNER)); lr.lr_start = 2; lr.lr_end = -1; - sa.emplace_back(lr, &view_curses::VC_GRAPHIC, ACS_HLINE); + sa.emplace_back(lr, view_curses::VC_GRAPHIC.value(ACS_HLINE)); retval += 1; } @@ -443,12 +443,12 @@ db_overlay_source::list_value_for_overlay(const listview_curses& lv, if (!this->dos_labels->dls_headers[lpc].hm_graphable) { attrs = A_UNDERLINE; } - sa.emplace_back(header_range, &view_curses::VC_STYLE, attrs); + sa.emplace_back(header_range, view_curses::VC_STYLE.value(attrs)); } struct line_range lr(0); - sa.emplace_back(lr, &view_curses::VC_STYLE, A_BOLD | A_UNDERLINE); + sa.emplace_back(lr, view_curses::VC_STYLE.value(A_BOLD | A_UNDERLINE)); return true; } else if (this->dos_active && y >= 2 && ((size_t) y) < (this->dos_lines.size() + 2)) diff --git a/src/field_overlay_source.cc b/src/field_overlay_source.cc index d799cf78..3cef0fba 100644 --- a/src/field_overlay_source.cc +++ b/src/field_overlay_source.cc @@ -167,20 +167,18 @@ field_overlay_source::build_summary_lines(const listview_curses& lv) .with_attr(string_attr( line_range(sum_msg.find("Error rate"), sum_msg.find("Error rate") + rate_len), - &view_curses::VC_STYLE, - A_REVERSE)) + view_curses::VC_STYLE.value(A_REVERSE))) + .with_attr( + string_attr(line_range(1, 2), + view_curses::VC_GRAPHIC.value(ACS_ULCORNER))) .with_attr(string_attr( - line_range(1, 2), &view_curses::VC_GRAPHIC, ACS_ULCORNER)) - .with_attr(string_attr( - line_range(2, 6), &view_curses::VC_GRAPHIC, ACS_HLINE)) + line_range(2, 6), view_curses::VC_GRAPHIC.value(ACS_HLINE))) .with_attr(string_attr( line_range(sum_msg.length() + 1, sum_msg.length() + 5), - &view_curses::VC_GRAPHIC, - ACS_HLINE)) + view_curses::VC_GRAPHIC.value(ACS_HLINE))) .with_attr(string_attr( line_range(sum_msg.length() + 5, sum_msg.length() + 6), - &view_curses::VC_GRAPHIC, - ACS_URCORNER)) + view_curses::VC_GRAPHIC.value(ACS_URCORNER))) .right_justify(width - 2); } } @@ -230,15 +228,17 @@ field_overlay_source::build_field_lines(const listview_curses& lv) continue; } - auto emsg = fmt::format(FMT_STRING(" Invalid log message: {}"), - (const char*) sattr.sa_value.sav_ptr); + auto emsg = fmt::format( + FMT_STRING(" Invalid log message: {}"), + sattr.sa_value.get()); auto al = attr_line_t(emsg) - .with_attr(string_attr(line_range{1, 2}, - &view_curses::VC_GRAPHIC, - ACS_LLCORNER)) - .with_attr(string_attr(line_range{0, 22}, - &view_curses::VC_ROLE, - view_colors::VCR_INVALID_MSG)); + .with_attr(string_attr( + line_range{1, 2}, + view_curses::VC_GRAPHIC.value(ACS_LLCORNER))) + .with_attr( + string_attr(line_range{0, 22}, + view_curses::VC_ROLE.value( + view_colors::VCR_INVALID_MSG))); this->fos_lines.emplace_back(al); } } @@ -259,12 +259,12 @@ field_overlay_source::build_field_lines(const listview_curses& lv) time_lr.lr_start = 1; time_lr.lr_end = 2; time_line.with_attr( - string_attr(time_lr, &view_curses::VC_GRAPHIC, ACS_LLCORNER)); + string_attr(time_lr, view_curses::VC_GRAPHIC.value(ACS_LLCORNER))); time_str.append(" Out-Of-Time-Order Message"); time_lr.lr_start = 3; time_lr.lr_end = time_str.length(); time_line.with_attr(string_attr( - time_lr, &view_curses::VC_ROLE, view_colors::VCR_SKEWED_TIME)); + time_lr, view_curses::VC_ROLE.value(view_colors::VCR_SKEWED_TIME))); time_str.append(" --"); } @@ -272,14 +272,16 @@ field_overlay_source::build_field_lines(const listview_curses& lv) time_lr.lr_start = time_str.length(); time_str.append(curr_timestamp); time_lr.lr_end = time_str.length(); - time_line.with_attr(string_attr(time_lr, &view_curses::VC_STYLE, A_BOLD)); + time_line.with_attr( + string_attr(time_lr, view_curses::VC_STYLE.value(A_BOLD))); time_str.append(" -- "); time_lr.lr_start = time_str.length(); time_str.append(humanize::time::point::from_tv(ll->get_timeval()) .with_convert_to_local(true) .as_precise_time_ago()); time_lr.lr_end = time_str.length(); - time_line.with_attr(string_attr(time_lr, &view_curses::VC_STYLE, A_BOLD)); + time_line.with_attr( + string_attr(time_lr, view_curses::VC_STYLE.value(A_BOLD))); struct line_range time_range = find_string_attr_range( this->fos_log_helper.ldh_line_attrs, &logline::L_TIMESTAMP); @@ -309,7 +311,8 @@ field_overlay_source::build_field_lines(const listview_curses& lv) time_str.append(orig_timestamp); time_lr.lr_end = time_str.length(); time_line.with_attr(string_attr( - time_lr, &view_curses::VC_ROLE, view_colors::VCR_SKEWED_TIME)); + time_lr, + view_curses::VC_ROLE.value(view_colors::VCR_SKEWED_TIME))); timersub(&curr_tv, &actual_tv, &diff_tv); time_str.append("; Diff: "); @@ -318,7 +321,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, &view_curses::VC_STYLE, A_BOLD)); + string_attr(time_lr, view_curses::VC_STYLE.value(A_BOLD))); } } @@ -405,8 +408,8 @@ field_overlay_source::build_field_lines(const listview_curses& lv) continue; } - auto curr_format = lv.lv_meta.lvm_format.value(); - auto curr_elf = dynamic_cast(curr_format); + auto* curr_format = lv.lv_meta.lvm_format.value(); + auto* curr_elf = dynamic_cast(curr_format); const auto format_name = curr_format->get_name().to_string(); attr_line_t al; std::string str, value_str = lv.to_string(); @@ -414,10 +417,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()), - &view_curses::VC_STYLE, - vc.attrs_for_ident(format_name) | A_BOLD)); + this->fos_lines.back().with_attr(string_attr( + line_range(32, 32 + format_name.length()), + view_curses::VC_STYLE.value(vc.attrs_for_ident(format_name) + | A_BOLD))); last_format = curr_format; } @@ -452,13 +455,13 @@ field_overlay_source::build_field_lines(const listview_curses& lv) auto prefix_len = field_name.length() - orig_field_name.length(); al.with_attr(string_attr( line_range(3 + prefix_len, 3 + prefix_len + field_name.size()), - &view_curses::VC_STYLE, - vc.attrs_for_ident(orig_field_name))); + view_curses::VC_STYLE.value( + vc.attrs_for_ident(orig_field_name)))); } else { al.with_attr(string_attr( line_range(8, 8 + lv.lv_meta.lvm_struct_name.size()), - &view_curses::VC_STYLE, - vc.attrs_for_ident(lv.lv_meta.lvm_struct_name))); + view_curses::VC_STYLE.value( + vc.attrs_for_ident(lv.lv_meta.lvm_struct_name)))); } this->fos_lines.emplace_back(al); @@ -470,8 +473,8 @@ field_overlay_source::build_field_lines(const listview_curses& lv) al.clear() .append(" extract(") .append(lv.lv_meta.lvm_name.get(), - &view_curses::VC_STYLE, - vc.attrs_for_ident(lv.lv_meta.lvm_name)) + view_curses::VC_STYLE.value( + vc.attrs_for_ident(lv.lv_meta.lvm_name))) .append(")") .append(this->fos_known_key_size - lv.lv_meta.lvm_name.size() - 9 + 3, @@ -531,15 +534,14 @@ field_overlay_source::build_field_lines(const listview_curses& lv) } else { this->fos_lines.emplace_back( " Discovered fields for logline table from message format: "); - this->fos_lines.back().with_attr( - string_attr(line_range(23, 23 + 7), - &view_curses::VC_STYLE, - vc.attrs_for_ident("logline"))); + this->fos_lines.back().with_attr(string_attr( + line_range(23, 23 + 7), + view_curses::VC_STYLE.value(vc.attrs_for_ident("logline")))); auto& al = this->fos_lines.back(); auto& disc_str = al.get_string(); - al.with_attr(string_attr( - line_range(disc_str.length(), -1), &view_curses::VC_STYLE, A_BOLD)); + al.with_attr(string_attr(line_range(disc_str.length(), -1), + view_curses::VC_STYLE.value(A_BOLD))); disc_str.append(this->fos_log_helper.ldh_msg_format); } @@ -552,9 +554,9 @@ field_overlay_source::build_field_lines(const listview_curses& lv) iter->e_sub_elements->back()); attr_line_t al(fmt::format(FMT_STRING(" {} = {}"), name, val)); - al.with_attr(string_attr(line_range(3, 3 + name.length()), - &view_curses::VC_STYLE, - vc.attrs_for_ident(name))); + al.with_attr( + string_attr(line_range(3, 3 + name.length()), + view_curses::VC_STYLE.value(vc.attrs_for_ident(name)))); this->fos_lines.emplace_back(al); this->add_key_line_attrs( @@ -583,8 +585,8 @@ field_overlay_source::build_meta_line(const listview_curses& lv, al.with_string(" + ") .with_attr(string_attr( line_range(1, 2), - &view_curses::VC_GRAPHIC, - line_meta.bm_tags.empty() ? ACS_LLCORNER : ACS_LTEE)) + view_curses::VC_GRAPHIC.value( + line_meta.bm_tags.empty() ? ACS_LLCORNER : ACS_LTEE))) .append(line_meta.bm_comment); al.insert(0, filename_width, ' '); dst.emplace_back(al); @@ -593,10 +595,10 @@ field_overlay_source::build_meta_line(const listview_curses& lv, attr_line_t al; al.with_string(" +").with_attr(string_attr( - line_range(1, 2), &view_curses::VC_GRAPHIC, ACS_LLCORNER)); + line_range(1, 2), view_curses::VC_GRAPHIC.value(ACS_LLCORNER))); for (const auto& str : line_meta.bm_tags) { al.append(1, ' ').append( - str, &view_curses::VC_STYLE, vc.attrs_for_ident(str)); + str, view_curses::VC_STYLE.value(vc.attrs_for_ident(str))); } const auto* tc = dynamic_cast(&lv); diff --git a/src/field_overlay_source.hh b/src/field_overlay_source.hh index 2ad839fe..e9b75c77 100644 --- a/src/field_overlay_source.hh +++ b/src/field_overlay_source.hh @@ -50,12 +50,12 @@ public: { string_attrs_t& sa = this->fos_lines.back().get_attrs(); struct line_range lr(1, 2); - sa.emplace_back( - lr, &view_curses::VC_GRAPHIC, last_line ? ACS_LLCORNER : ACS_LTEE); + int64_t graphic = (int64_t) (last_line ? ACS_LLCORNER : ACS_LTEE); + sa.emplace_back(lr, view_curses::VC_GRAPHIC.value(graphic)); lr.lr_start = 3 + key_size + 3; lr.lr_end = -1; - sa.emplace_back(lr, &view_curses::VC_STYLE, A_BOLD); + sa.emplace_back(lr, view_curses::VC_STYLE.value(A_BOLD)); }; bool list_value_for_overlay(const listview_curses& lv, diff --git a/src/files_sub_source.cc b/src/files_sub_source.cc index c2b95b3f..543428d8 100644 --- a/src/files_sub_source.cc +++ b/src/files_sub_source.cc @@ -307,33 +307,33 @@ files_sub_source::text_attrs_for_line(textview_curses& tc, std::max((size_t) 40, (size_t) dim.second - 30)); if (selected) { - value_out.emplace_back( - line_range{0, 1}, &view_curses::VC_GRAPHIC, ACS_RARROW); + value_out.emplace_back(line_range{0, 1}, + view_curses::VC_GRAPHIC.value(ACS_RARROW)); } if (line < fc.fc_name_to_errors.size()) { if (selected) { - value_out.emplace_back(line_range{0, -1}, - &view_curses::VC_ROLE, - view_colors::VCR_DISABLED_FOCUSED); + value_out.emplace_back( + line_range{0, -1}, + view_curses::VC_ROLE.value(view_colors::VCR_DISABLED_FOCUSED)); } - value_out.emplace_back(line_range{4 + (int) filename_width, -1}, - &view_curses::VC_ROLE_FG, - view_colors::VCR_ERROR); + value_out.emplace_back( + line_range{4 + (int) filename_width, -1}, + view_curses::VC_ROLE_FG.value(view_colors::VCR_ERROR)); return; } line -= fc.fc_name_to_errors.size(); if (line < fc.fc_other_files.size()) { if (selected) { - value_out.emplace_back(line_range{0, -1}, - &view_curses::VC_ROLE, - view_colors::VCR_DISABLED_FOCUSED); + value_out.emplace_back( + line_range{0, -1}, + view_curses::VC_ROLE.value(view_colors::VCR_DISABLED_FOCUSED)); } if (line == fc.fc_other_files.size() - 1) { - value_out.emplace_back( - line_range{0, -1}, &view_curses::VC_STYLE, A_UNDERLINE); + value_out.emplace_back(line_range{0, -1}, + view_curses::VC_STYLE.value(A_UNDERLINE)); } return; } @@ -342,7 +342,8 @@ files_sub_source::text_attrs_for_line(textview_curses& tc, if (selected) { value_out.emplace_back( - line_range{0, -1}, &view_curses::VC_ROLE, view_colors::VCR_FOCUSED); + line_range{0, -1}, + view_curses::VC_ROLE.value(view_colors::VCR_FOCUSED)); } auto& lss = lnav_data.ld_log_source; @@ -353,24 +354,25 @@ files_sub_source::text_attrs_for_line(textview_curses& tc, if (ld_opt && !ld_opt.value()->ld_visible) { visible = ' '; } - value_out.emplace_back(line_range{2, 3}, &view_curses::VC_GRAPHIC, visible); + value_out.emplace_back(line_range{2, 3}, + view_curses::VC_GRAPHIC.value(visible)); if (visible == ACS_DIAMOND) { value_out.emplace_back(line_range{2, 3}, - &view_curses::VC_FOREGROUND, - vcolors.ansi_to_theme_color(COLOR_GREEN)); + view_curses::VC_FOREGROUND.value( + vcolors.ansi_to_theme_color(COLOR_GREEN))); } auto lr = line_range{ (int) filename_width + 3 + 4, (int) filename_width + 3 + 10, }; - value_out.emplace_back(lr, &view_curses::VC_STYLE, A_BOLD); + value_out.emplace_back(lr, view_curses::VC_STYLE.value(A_BOLD)); lr.lr_start = this->fss_last_line_len; lr.lr_end = -1; value_out.emplace_back(lr, - &view_curses::VC_FOREGROUND, - vcolors.ansi_to_theme_color(COLOR_YELLOW)); + view_curses::VC_FOREGROUND.value( + vcolors.ansi_to_theme_color(COLOR_YELLOW))); } size_t diff --git a/src/filter_status_source.cc b/src/filter_status_source.cc index bd8a0f94..723317f7 100644 --- a/src/filter_status_source.cc +++ b/src/filter_status_source.cc @@ -210,8 +210,8 @@ filter_status_source::update_filtered(text_sub_source* tss) if (timer.fade_diff(this->bss_filter_counter) == 0) { this->tss_fields[TSF_FILTERED].set_role( view_colors::VCR_STATUS); - al.with_attr(string_attr( - line_range{0, -1}, &view_curses::VC_STYLE, A_BOLD)); + al.with_attr(string_attr(line_range{0, -1}, + view_curses::VC_STYLE.value(A_BOLD))); } } else { this->tss_fields[TSF_FILTERED].set_role( diff --git a/src/filter_sub_source.cc b/src/filter_sub_source.cc index 889d9393..fe0ae96b 100644 --- a/src/filter_sub_source.cc +++ b/src/filter_sub_source.cc @@ -352,33 +352,37 @@ filter_sub_source::text_attrs_for_line(textview_curses& tc, = lnav_data.ld_mode == LNM_FILTER && line == tc.get_selection(); if (selected) { - value_out.emplace_back( - line_range{0, 1}, &view_curses::VC_GRAPHIC, ACS_RARROW); + value_out.emplace_back(line_range{0, 1}, + view_curses::VC_GRAPHIC.value(ACS_RARROW)); } chtype enabled = tf->is_enabled() ? ACS_DIAMOND : ' '; line_range lr{2, 3}; - value_out.emplace_back(lr, &view_curses::VC_GRAPHIC, enabled); + value_out.emplace_back(lr, view_curses::VC_GRAPHIC.value(enabled)); if (tf->is_enabled()) { value_out.emplace_back(lr, - &view_curses::VC_FOREGROUND, - vcolors.ansi_to_theme_color(COLOR_GREEN)); + view_curses::VC_FOREGROUND.value( + vcolors.ansi_to_theme_color(COLOR_GREEN))); } int fg_role = tf->get_type() == text_filter::INCLUDE ? view_colors::VCR_OK : view_colors::VCR_ERROR; - value_out.emplace_back(line_range{4, 7}, &view_curses::VC_ROLE_FG, fg_role); - value_out.emplace_back(line_range{4, 7}, &view_curses::VC_STYLE, A_BOLD); + value_out.emplace_back(line_range{4, 7}, + view_curses::VC_ROLE_FG.value(fg_role)); + value_out.emplace_back(line_range{4, 7}, + view_curses::VC_STYLE.value(A_BOLD)); - value_out.emplace_back(line_range{8, 17}, &view_curses::VC_STYLE, A_BOLD); - value_out.emplace_back( - line_range{23, 24}, &view_curses::VC_GRAPHIC, ACS_VLINE); + value_out.emplace_back(line_range{8, 17}, + view_curses::VC_STYLE.value(A_BOLD)); + value_out.emplace_back(line_range{23, 24}, + view_curses::VC_GRAPHIC.value(ACS_VLINE)); if (selected) { value_out.emplace_back( - line_range{0, -1}, &view_curses::VC_ROLE, view_colors::VCR_FOCUSED); + line_range{0, -1}, + view_curses::VC_ROLE.value(view_colors::VCR_FOCUSED)); } attr_line_t content{tf->get_id()}; @@ -620,7 +624,7 @@ filter_sub_source::rl_display_matches(readline_curses* rc) for (auto& match : matches) { if (match == current_match) { - al.append(match, &view_curses::VC_STYLE, A_REVERSE); + al.append(match, view_curses::VC_STYLE.value(A_REVERSE)); selected_line = line; } else { al.append(match); diff --git a/src/help_text_formatter.cc b/src/help_text_formatter.cc index bcff631c..720b1379 100644 --- a/src/help_text_formatter.cc +++ b/src/help_text_formatter.cc @@ -91,28 +91,29 @@ format_help_text_for_term(const help_text& ht, switch (ht.ht_context) { case help_context_t::HC_COMMAND: { - out.append("Synopsis", &view_curses::VC_STYLE, A_UNDERLINE) + out.append("Synopsis", view_curses::VC_STYLE.value(A_UNDERLINE)) .append("\n") .append(body_indent, ' ') .append(":") - .append(ht.ht_name, &view_curses::VC_STYLE, A_BOLD); + .append(ht.ht_name, view_curses::VC_STYLE.value(A_BOLD)); for (const auto& param : ht.ht_parameters) { out.append(" "); if (param.ht_nargs == help_nargs_t::HN_OPTIONAL) { out.append("["); } - out.append(param.ht_name, &view_curses::VC_STYLE, A_UNDERLINE); + out.append(param.ht_name, + view_curses::VC_STYLE.value(A_UNDERLINE)); if (param.ht_nargs == help_nargs_t::HN_OPTIONAL) { out.append("]"); } if (param.ht_nargs == help_nargs_t::HN_ONE_OR_MORE) { - out.append("1", &view_curses::VC_STYLE, A_UNDERLINE); + out.append("1", view_curses::VC_STYLE.value(A_UNDERLINE)); out.append(" ["); - out.append("...", &view_curses::VC_STYLE, A_UNDERLINE); + out.append("...", view_curses::VC_STYLE.value(A_UNDERLINE)); out.append(" "); - out.append( - param.ht_name, &view_curses::VC_STYLE, A_UNDERLINE); - out.append("N", &view_curses::VC_STYLE, A_UNDERLINE); + out.append(param.ht_name, + view_curses::VC_STYLE.value(A_UNDERLINE)); + out.append("N", view_curses::VC_STYLE.value(A_UNDERLINE)); out.append("]"); } } @@ -129,13 +130,13 @@ format_help_text_for_term(const help_text& ht, bool needs_comma = false; if (!synopsis_only) { - out.append("Synopsis", &view_curses::VC_STYLE, A_UNDERLINE) + out.append("Synopsis", view_curses::VC_STYLE.value(A_UNDERLINE)) .append("\n"); } line_start = out.length(); out.append(body_indent, ' ') - .append(ht.ht_name, &view_curses::VC_STYLE, A_BOLD) + .append(ht.ht_name, view_curses::VC_STYLE.value(A_BOLD)) .append("("); for (const auto& param : ht.ht_parameters) { if (!param.ht_flag_name && needs_comma) { @@ -152,14 +153,15 @@ format_help_text_for_term(const help_text& ht, } if (param.ht_flag_name) { out.append(" ") - .append( - param.ht_flag_name, &view_curses::VC_STYLE, A_BOLD) + .append(param.ht_flag_name, + view_curses::VC_STYLE.value(A_BOLD)) .append(" "); } if (param.ht_nargs == help_nargs_t::HN_OPTIONAL) { out.append("["); } - out.append(param.ht_name, &view_curses::VC_STYLE, A_UNDERLINE); + out.append(param.ht_name, + view_curses::VC_STYLE.value(A_UNDERLINE)); if (param.ht_nargs == help_nargs_t::HN_OPTIONAL) { out.append("]"); } @@ -181,28 +183,29 @@ format_help_text_for_term(const help_text& ht, break; } case help_context_t::HC_SQL_COMMAND: { - out.append("Synopsis", &view_curses::VC_STYLE, A_UNDERLINE) + out.append("Synopsis", view_curses::VC_STYLE.value(A_UNDERLINE)) .append("\n") .append(body_indent, ' ') .append(";") - .append(ht.ht_name, &view_curses::VC_STYLE, A_BOLD); + .append(ht.ht_name, view_curses::VC_STYLE.value(A_BOLD)); for (const auto& param : ht.ht_parameters) { out.append(" "); if (param.ht_nargs == help_nargs_t::HN_OPTIONAL) { out.append("["); } - out.append(param.ht_name, &view_curses::VC_STYLE, A_UNDERLINE); + out.append(param.ht_name, + view_curses::VC_STYLE.value(A_UNDERLINE)); if (param.ht_nargs == help_nargs_t::HN_OPTIONAL) { out.append("]"); } if (param.ht_nargs == help_nargs_t::HN_ONE_OR_MORE) { - out.append("1", &view_curses::VC_STYLE, A_UNDERLINE); + out.append("1", view_curses::VC_STYLE.value(A_UNDERLINE)); out.append(" ["); - out.append("...", &view_curses::VC_STYLE, A_UNDERLINE); + out.append("...", view_curses::VC_STYLE.value(A_UNDERLINE)); out.append(" "); - out.append( - param.ht_name, &view_curses::VC_STYLE, A_UNDERLINE); - out.append("N", &view_curses::VC_STYLE, A_UNDERLINE); + out.append(param.ht_name, + view_curses::VC_STYLE.value(A_UNDERLINE)); + out.append("N", view_curses::VC_STYLE.value(A_UNDERLINE)); out.append("]"); } } @@ -219,12 +222,12 @@ format_help_text_for_term(const help_text& ht, bool is_infix = ht.ht_context == help_context_t::HC_SQL_INFIX; if (!synopsis_only) { - out.append("Synopsis", &view_curses::VC_STYLE, A_UNDERLINE) + out.append("Synopsis", view_curses::VC_STYLE.value(A_UNDERLINE)) .append("\n"); } out.append(body_indent, ' ') - .append( - ht.ht_name, &view_curses::VC_STYLE, is_infix ? 0 : A_BOLD); + .append(ht.ht_name, + view_curses::VC_STYLE.value(is_infix ? 0 : A_BOLD)); for (const auto& param : ht.ht_parameters) { if (break_all || (int) (out.get_string().length() - start_index @@ -246,32 +249,33 @@ format_help_text_for_term(const help_text& ht, } if (param.ht_flag_name) { out.ensure_space().append( - param.ht_flag_name, &view_curses::VC_STYLE, A_BOLD); + param.ht_flag_name, + view_curses::VC_STYLE.value(A_BOLD)); } if (param.ht_group_start) { out.ensure_space().append( - param.ht_group_start, &view_curses::VC_STYLE, A_BOLD); + param.ht_group_start, + view_curses::VC_STYLE.value(A_BOLD)); } if (param.ht_name[0]) { out.ensure_space().append( - param.ht_name, &view_curses::VC_STYLE, A_UNDERLINE); + param.ht_name, + view_curses::VC_STYLE.value(A_UNDERLINE)); if (!param.ht_parameters.empty()) { if (param.ht_nargs == help_nargs_t::HN_ZERO_OR_MORE || param.ht_nargs == help_nargs_t::HN_ONE_OR_MORE) { out.append( - "1", &view_curses::VC_STYLE, A_UNDERLINE); + "1", view_curses::VC_STYLE.value(A_UNDERLINE)); } if (param.ht_parameters[0].ht_flag_name) { out.append(" ") .append(param.ht_parameters[0].ht_flag_name, - &view_curses::VC_STYLE, - A_BOLD) + view_curses::VC_STYLE.value(A_BOLD)) .append(" "); } out.append(param.ht_parameters[0].ht_name, - &view_curses::VC_STYLE, - A_UNDERLINE); + view_curses::VC_STYLE.value(A_UNDERLINE)); } } if (param.ht_nargs == help_nargs_t::HN_ZERO_OR_MORE @@ -280,7 +284,7 @@ format_help_text_for_term(const help_text& ht, bool needs_comma = param.ht_parameters.empty() || !param.ht_flag_name; - out.append("1", &view_curses::VC_STYLE, A_UNDERLINE) + out.append("1", view_curses::VC_STYLE.value(A_UNDERLINE)) .append(" [") .append(needs_comma ? ", " : "") .append("...") @@ -288,31 +292,30 @@ format_help_text_for_term(const help_text& ht, .append((needs_comma || !param.ht_flag_name) ? "" : param.ht_flag_name, - &view_curses::VC_STYLE, - A_BOLD) + view_curses::VC_STYLE.value(A_BOLD)) .append(" ") - .append( - param.ht_name, &view_curses::VC_STYLE, A_UNDERLINE) - .append("N", &view_curses::VC_STYLE, A_UNDERLINE); + .append(param.ht_name, + view_curses::VC_STYLE.value(A_UNDERLINE)) + .append("N", view_curses::VC_STYLE.value(A_UNDERLINE)); if (!param.ht_parameters.empty()) { if (param.ht_parameters[0].ht_flag_name) { out.append(" ") .append(param.ht_parameters[0].ht_flag_name, - &view_curses::VC_STYLE, - A_BOLD) + view_curses::VC_STYLE.value(A_BOLD)) .append(" "); } out.append(param.ht_parameters[0].ht_name, - &view_curses::VC_STYLE, - A_UNDERLINE) - .append("N", &view_curses::VC_STYLE, A_UNDERLINE); + view_curses::VC_STYLE.value(A_UNDERLINE)) + .append("N", + view_curses::VC_STYLE.value(A_UNDERLINE)); } out.append("]"); } if (param.ht_group_end) { out.ensure_space().append( - param.ht_group_end, &view_curses::VC_STYLE, A_BOLD); + param.ht_group_end, + view_curses::VC_STYLE.value(A_BOLD)); } if (param.ht_nargs == help_nargs_t::HN_ZERO_OR_MORE || param.ht_nargs == help_nargs_t::HN_OPTIONAL) @@ -343,8 +346,7 @@ format_help_text_for_term(const help_text& ht, } out.append(ht.ht_parameters.size() == 1 ? "Parameter" : "Parameters", - &view_curses::VC_STYLE, - A_UNDERLINE) + view_curses::VC_STYLE.value(A_UNDERLINE)) .append("\n"); for (const auto& param : ht.ht_parameters) { @@ -353,9 +355,10 @@ format_help_text_for_term(const help_text& ht, } out.append(body_indent, ' ') - .append(param.ht_name, - &view_curses::VC_STYLE, - vc.attrs_for_role(view_colors::VCR_VARIABLE) | A_BOLD) + .append( + param.ht_name, + view_curses::VC_STYLE.value( + vc.attrs_for_role(view_colors::VCR_VARIABLE) | A_BOLD)) .append(max_param_name_width - strlen(param.ht_name), ' ') .append(" ") .append(attr_line_t::from_ansi_str(param.ht_summary), @@ -372,8 +375,7 @@ format_help_text_for_term(const help_text& ht, } out.append(ht.ht_results.size() == 1 ? "Result" : "Results", - &view_curses::VC_STYLE, - A_UNDERLINE) + view_curses::VC_STYLE.value(A_UNDERLINE)) .append("\n"); for (const auto& result : ht.ht_results) { @@ -382,9 +384,10 @@ format_help_text_for_term(const help_text& ht, } out.append(body_indent, ' ') - .append(result.ht_name, - &view_curses::VC_STYLE, - vc.attrs_for_role(view_colors::VCR_VARIABLE) | A_BOLD) + .append( + result.ht_name, + view_curses::VC_STYLE.value( + vc.attrs_for_role(view_colors::VCR_VARIABLE) | A_BOLD)) .append(max_result_name_width - strlen(result.ht_name), ' ') .append(" ") .append(attr_line_t::from_ansi_str(result.ht_summary), @@ -413,7 +416,7 @@ format_help_text_for_term(const help_text& ht, } stable_sort(related_refs.begin(), related_refs.end()); - out.append("See Also", &view_curses::VC_STYLE, A_UNDERLINE) + out.append("See Also", view_curses::VC_STYLE.value(A_UNDERLINE)) .append("\n") .append(body_indent, ' '); @@ -427,7 +430,7 @@ format_help_text_for_term(const help_text& ht, out.append("\n").append(body_indent, ' '); line_start = out.length(); } - out.append(ref, &view_curses::VC_STYLE, A_BOLD); + out.append(ref, view_curses::VC_STYLE.value(A_BOLD)); first = false; } } @@ -447,8 +450,7 @@ format_example_text_for_term(const help_text& ht, int count = 1; out.append(ht.ht_example.size() == 1 ? "Example" : "Examples", - &view_curses::VC_STYLE, - A_UNDERLINE) + view_curses::VC_STYLE.value(A_UNDERLINE)) .append("\n"); for (const auto& ex : ht.ht_example) { attr_line_t ex_line(ex.he_cmd); diff --git a/src/highlighter.cc b/src/highlighter.cc index 3156df61..69623183 100644 --- a/src/highlighter.cc +++ b/src/highlighter.cc @@ -142,19 +142,20 @@ highlighter::annotate(attr_line_t& al, int start) const } if (!this->h_fg.empty()) { sa.emplace_back(lr, - &view_curses::VC_FOREGROUND, - vc.match_color(this->h_fg)); + view_curses::VC_FOREGROUND.value( + vc.match_color(this->h_fg))); } if (!this->h_bg.empty()) { sa.emplace_back(lr, - &view_curses::VC_BACKGROUND, - vc.match_color(this->h_bg)); + view_curses::VC_BACKGROUND.value( + vc.match_color(this->h_bg))); } if (this->h_role != view_colors::VCR_NONE) { - sa.emplace_back(lr, &view_curses::VC_ROLE, this->h_role); + sa.emplace_back(lr, + view_curses::VC_ROLE.value(this->h_role)); } if (attrs) { - sa.emplace_back(lr, &view_curses::VC_STYLE, attrs); + sa.emplace_back(lr, view_curses::VC_STYLE.value(attrs)); } off = matches[1]; diff --git a/src/hist_source.hh b/src/hist_source.hh index 04337217..7b59bd2c 100644 --- a/src/hist_source.hh +++ b/src/hist_source.hh @@ -228,7 +228,7 @@ public: if (ci.ci_attrs != 0) { value_out.emplace_back( - lr, &view_curses::VC_STYLE, ci.ci_attrs | A_REVERSE); + lr, view_curses::VC_STYLE.value(ci.ci_attrs | A_REVERSE)); } }; diff --git a/src/hotkeys.cc b/src/hotkeys.cc index 2f506463..1a367ffc 100644 --- a/src/hotkeys.cc +++ b/src/hotkeys.cc @@ -827,17 +827,15 @@ handle_paging_key(int ch) lnav_data.ld_filter_view.reload_data(); lnav_data.ld_files_view.reload_data(); if (tc->get_inner_height() > 0_vl) { - string_attrs_t::const_iterator line_attr; std::vector rows(1); tc->get_data_source()->listview_value_for_rows( *tc, tc->get_top(), rows); string_attrs_t& sa = rows[0].get_attrs(); - line_attr = find_string_attr(sa, &logline::L_FILE); - if (line_attr != sa.end()) { + auto line_attr_opt = get_string_attr(sa, logline::L_FILE); + if (line_attr_opt) { const auto& fc = lnav_data.ld_active_files; - auto lf = ((logfile*) line_attr->sa_value.sav_ptr) - ->shared_from_this(); + auto lf = line_attr_opt.value().get(); auto iter = find(fc.fc_files.begin(), fc.fc_files.end(), lf); if (iter != fc.fc_files.end()) { diff --git a/src/lnav_commands.cc b/src/lnav_commands.cc index da222e65..193ee8b3 100644 --- a/src/lnav_commands.cc +++ b/src/lnav_commands.cc @@ -832,7 +832,7 @@ write_line_to(FILE* outfile, const attr_line_t& al) { const auto& al_attrs = al.get_attrs(); auto lr = find_string_attr_range(al_attrs, &SA_ORIGINAL_LINE); - const auto& line_meta = find_string_attr(al_attrs, &logline::L_META); + const auto line_meta_opt = get_string_attr(al_attrs, logline::L_META); if (lr.lr_start > 1) { // If the line is prefixed with some extra information, include that @@ -843,9 +843,8 @@ write_line_to(FILE* outfile, const attr_line_t& al) fwrite(lr.substr(al.get_string()), 1, lr.sublen(al.get_string()), outfile); fwrite("\n", 1, 1, outfile); - if (line_meta != al_attrs.end()) { - auto bm = static_cast( - line_meta->sa_value.sav_ptr); + if (line_meta_opt) { + auto bm = line_meta_opt.value().get(); if (!bm->bm_comment.empty()) { fprintf(outfile, " // %s\n", bm->bm_comment.c_str()); @@ -2420,8 +2419,7 @@ com_open(exec_context& ec, std::string cmdline, std::vector& args) if (gl->gl_pathc > 10) { al.append(" ... ") .append(std::to_string(gl->gl_pathc - 10), - &view_curses::VC_STYLE, - A_BOLD) + view_curses::VC_STYLE.value(A_BOLD)) .append(" files not shown ..."); } lnav_data.ld_preview_status_source.get_description() diff --git a/src/log_format.cc b/src/log_format.cc index 0c75c032..1562e704 100644 --- a/src/log_format.cc +++ b/src/log_format.cc @@ -47,13 +47,14 @@ #include "yajlpp/yajlpp_def.hh" static auto intern_lifetime = intern_string::get_table_lifetime(); -string_attr_type logline::L_PREFIX("prefix"); -string_attr_type logline::L_TIMESTAMP("timestamp"); -string_attr_type logline::L_FILE("file"); -string_attr_type logline::L_PARTITION("partition"); -string_attr_type logline::L_MODULE("module"); -string_attr_type logline::L_OPID("opid"); -string_attr_type logline::L_META("meta"); + +string_attr_type logline::L_PREFIX("prefix"); +string_attr_type logline::L_TIMESTAMP("timestamp"); +string_attr_type> logline::L_FILE("file"); +string_attr_type logline::L_PARTITION("partition"); +string_attr_type logline::L_MODULE("module"); +string_attr_type logline::L_OPID("opid"); +string_attr_type logline::L_META("meta"); external_log_format::mod_map_t external_log_format::MODULE_FORMATS; std::vector> @@ -1007,12 +1008,12 @@ external_log_format::annotate(uint64_t line_number, // A continued line still needs a body. lr.lr_start = 0; lr.lr_end = line.length(); - sa.emplace_back(lr, &SA_BODY); + sa.emplace_back(lr, SA_BODY.value()); if (!this->lf_multiline) { auto len = pat.p_pcre->match_partial(pi); - sa.emplace_back(line_range{(int) len, -1}, - &SA_INVALID, - (void*) "Log line does not match any pattern"); + sa.emplace_back( + line_range{(int) len, -1}, + SA_INVALID.value("Log line does not match any pattern")); } return; } @@ -1022,7 +1023,7 @@ external_log_format::annotate(uint64_t line_number, if (cap->is_valid()) { lr.lr_start = cap->c_begin; lr.lr_end = cap->c_end; - sa.emplace_back(lr, &logline::L_TIMESTAMP); + sa.emplace_back(lr, logline::L_TIMESTAMP.value()); } if (pat.p_module_field_index != -1) { @@ -1030,7 +1031,7 @@ external_log_format::annotate(uint64_t line_number, if (module_cap != nullptr && module_cap->is_valid()) { lr.lr_start = module_cap->c_begin; lr.lr_end = module_cap->c_end; - sa.emplace_back(lr, &logline::L_MODULE); + sa.emplace_back(lr, logline::L_MODULE.value()); } } @@ -1038,7 +1039,7 @@ external_log_format::annotate(uint64_t line_number, if (cap != nullptr && cap->is_valid()) { lr.lr_start = cap->c_begin; lr.lr_end = cap->c_end; - sa.emplace_back(lr, &logline::L_OPID); + sa.emplace_back(lr, logline::L_OPID.value()); } } @@ -1115,7 +1116,7 @@ external_log_format::annotate(uint64_t line_number, lr.lr_start = line.length(); lr.lr_end = line.length(); } - sa.emplace_back(lr, &SA_BODY); + sa.emplace_back(lr, SA_BODY.value()); } } @@ -1351,8 +1352,7 @@ external_log_format::get_subline(const logline& ll, this->jlf_line_values.clear(); this->jlf_line_attrs.emplace_back( line_range{0, -1}, - &SA_INVALID, - (void*) "JSON line failed to parse"); + SA_INVALID.value("JSON line failed to parse")); } else { std::vector::iterator lv_iter; bool used_values[this->jlf_line_values.size()]; @@ -1444,14 +1444,15 @@ external_log_format::get_subline(const logline& ll, if (lv_iter->lv_meta.lvm_name == this->lf_timestamp_field) { this->jlf_line_attrs.emplace_back( - lr, &logline::L_TIMESTAMP); + lr, logline::L_TIMESTAMP.value()); } else if (lv_iter->lv_meta.lvm_name == this->elf_body_field) { - this->jlf_line_attrs.emplace_back(lr, &SA_BODY); + this->jlf_line_attrs.emplace_back( + lr, SA_BODY.value()); } else if (lv_iter->lv_meta.lvm_name == this->elf_opid_field) { this->jlf_line_attrs.emplace_back( - lr, &logline::L_OPID); + lr, logline::L_OPID.value()); } lv_iter->lv_origin = lr; used_values[distance(this->jlf_line_values.begin(), @@ -1478,7 +1479,7 @@ external_log_format::get_subline(const logline& ll, this->json_append_to_cache(ts, ts_len); lr.lr_end = this->jlf_cached_line.size(); this->jlf_line_attrs.emplace_back( - lr, &logline::L_TIMESTAMP); + lr, logline::L_TIMESTAMP.value()); lv_iter = find_if( this->jlf_line_values.begin(), diff --git a/src/log_format_fwd.hh b/src/log_format_fwd.hh index 7a07be6e..d6fce685 100644 --- a/src/log_format_fwd.hh +++ b/src/log_format_fwd.hh @@ -46,13 +46,13 @@ class log_format; */ class logline { public: - static string_attr_type L_PREFIX; - static string_attr_type L_TIMESTAMP; - static string_attr_type L_FILE; - static string_attr_type L_PARTITION; - static string_attr_type L_MODULE; - static string_attr_type L_OPID; - static string_attr_type L_META; + static string_attr_type L_PREFIX; + static string_attr_type L_TIMESTAMP; + static string_attr_type> L_FILE; + static string_attr_type L_PARTITION; + static string_attr_type L_MODULE; + static string_attr_type L_OPID; + static string_attr_type L_META; /** * Construct a logline object with the given values. diff --git a/src/log_format_impls.cc b/src/log_format_impls.cc index a729308c..c70086cc 100644 --- a/src/log_format_impls.cc +++ b/src/log_format_impls.cc @@ -215,7 +215,7 @@ class generic_log_format : public log_format { lr.lr_start = pc[0]->c_begin; lr.lr_end = pc[0]->c_end; - sa.emplace_back(lr, &logline::L_TIMESTAMP); + sa.emplace_back(lr, logline::L_TIMESTAMP.value()); const char* level = &line.get_data()[pc[1]->c_begin]; @@ -227,11 +227,11 @@ class generic_log_format : public log_format { lr.lr_start = 0; lr.lr_end = prefix_len; - sa.emplace_back(lr, &logline::L_PREFIX); + sa.emplace_back(lr, logline::L_PREFIX.value()); lr.lr_start = prefix_len; lr.lr_end = line.length(); - sa.emplace_back(lr, &SA_BODY); + sa.emplace_back(lr, SA_BODY.value()); }; std::shared_ptr specialized(int fmt_lock) override @@ -696,9 +696,9 @@ public: auto lr = line_range(sf.sf_begin, sf.sf_end); if (fd.fd_meta.lvm_name == TS) { - sa.emplace_back(lr, &logline::L_TIMESTAMP); + sa.emplace_back(lr, logline::L_TIMESTAMP.value()); } else if (fd.fd_meta.lvm_name == UID) { - sa.emplace_back(lr, &logline::L_OPID); + sa.emplace_back(lr, logline::L_OPID.value()); } if (lr.is_valid()) { @@ -1270,8 +1270,7 @@ public: if (iter.index() >= this->wlf_field_defs.size()) { sa.emplace_back(line_range{sf.sf_begin, -1}, - &SA_INVALID, - (void*) "extra fields detected"); + SA_INVALID.value("extra fields detected")); return; } @@ -1732,10 +1731,10 @@ public: = line_range{value_frag.sf_begin, value_frag.sf_end}; if (kvp.first == "time" || kvp.first == "ts") { - sa.emplace_back(value_lr, &logline::L_TIMESTAMP); + sa.emplace_back(value_lr, logline::L_TIMESTAMP.value()); } else if (kvp.first == "level") { } else if (kvp.first == "msg") { - sa.emplace_back(value_lr, &SA_BODY); + sa.emplace_back(value_lr, SA_BODY.value()); } else if (!kvp.second.is() && !kvp.second.is()) { diff --git a/src/logfile_sub_source.cc b/src/logfile_sub_source.cc index 2b17db4a..5f09ed64 100644 --- a/src/logfile_sub_source.cc +++ b/src/logfile_sub_source.cc @@ -208,7 +208,8 @@ logfile_sub_source::text_value_for_line(textview_curses& tc, this->lss_token_value.size()); if (this->lss_token_line->is_continued()) { this->lss_token_attrs.emplace_back( - line_range{0, (int) this->lss_token_value.length()}, &SA_BODY); + line_range{0, (int) this->lss_token_value.length()}, + SA_BODY.value()); } else { format->annotate( line, sbr, this->lss_token_attrs, this->lss_token_values); @@ -356,12 +357,12 @@ logfile_sub_source::text_attrs_for_line(textview_curses& lv, lr.lr_start = 0; lr.lr_end = this->lss_token_value.length(); - value_out.emplace_back(lr, &SA_ORIGINAL_LINE); + value_out.emplace_back(lr, SA_ORIGINAL_LINE.value()); lr.lr_start = time_offset_end; lr.lr_end = -1; - value_out.emplace_back(lr, &view_curses::VC_STYLE, attrs); + value_out.emplace_back(lr, view_curses::VC_STYLE.value(attrs)); if (this->lss_token_line->get_msg_level() == log_level_t::LEVEL_INVALID) { for (auto& token_attr : this->lss_token_attrs) { @@ -369,9 +370,9 @@ logfile_sub_source::text_attrs_for_line(textview_curses& lv, continue; } - value_out.emplace_back(token_attr.sa_range, - &view_curses::VC_ROLE, - view_colors::VCR_INVALID_MSG); + value_out.emplace_back( + token_attr.sa_range, + view_curses::VC_ROLE.value(view_colors::VCR_INVALID_MSG)); } } @@ -385,7 +386,7 @@ logfile_sub_source::text_attrs_for_line(textview_curses& lv, } if (line_value.lv_meta.is_hidden()) { - value_out.emplace_back(line_value.lv_origin, &SA_HIDDEN); + value_out.emplace_back(line_value.lv_origin, SA_HIDDEN.value()); } if (!line_value.lv_meta.lvm_identifier @@ -400,7 +401,8 @@ logfile_sub_source::text_attrs_for_line(textview_curses& lv, } value_out.emplace_back( - ident_range, &view_curses::VC_ROLE, view_colors::VCR_IDENTIFIER); + ident_range, + view_curses::VC_ROLE.value(view_colors::VCR_IDENTIFIER)); } if (this->lss_token_shift_size) { @@ -430,7 +432,7 @@ logfile_sub_source::text_attrs_for_line(textview_curses& lv, } else if (is_last_for_file) { graph = ACS_LLCORNER; } - value_out.push_back(string_attr(lr, &view_curses::VC_GRAPHIC, graph)); + value_out.emplace_back(lr, view_curses::VC_GRAPHIC.value(graph)); if (!(this->lss_token_flags & RF_FULL)) { bookmark_vector& bv_search @@ -441,15 +443,15 @@ 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, &view_curses::VC_STYLE, A_REVERSE); + value_out.emplace_back(lr, + view_curses::VC_STYLE.value(A_REVERSE)); } } } - value_out.emplace_back( - lr, - &view_curses::VC_STYLE, - vc.attrs_for_ident(this->lss_token_file->get_filename())); + value_out.emplace_back(lr, + view_curses::VC_STYLE.value(vc.attrs_for_ident( + this->lss_token_file->get_filename()))); if (this->lss_flags & F_FILENAME || this->lss_flags & F_BASENAME) { size_t file_offset_end = (this->lss_flags & F_FILENAME) @@ -460,10 +462,9 @@ logfile_sub_source::text_attrs_for_line(textview_curses& lv, lr.lr_start = 0; lr.lr_end = file_offset_end + 1; - value_out.emplace_back( - lr, - &view_curses::VC_STYLE, - vc.attrs_for_ident(this->lss_token_file->get_filename())); + value_out.emplace_back(lr, + view_curses::VC_STYLE.value(vc.attrs_for_ident( + this->lss_token_file->get_filename()))); } if (this->lss_flags & F_TIME_OFFSET) { @@ -474,9 +475,9 @@ logfile_sub_source::text_attrs_for_line(textview_curses& lv, shift_string_attrs(value_out, 0, time_offset_end); value_out.emplace_back( - lr, &view_curses::VC_ROLE, view_colors::VCR_OFFSET_TIME); - value_out.emplace_back( - line_range(12, 13), &view_curses::VC_GRAPHIC, ACS_VLINE); + lr, view_curses::VC_ROLE.value(view_colors::VCR_OFFSET_TIME)); + value_out.emplace_back(line_range(12, 13), + view_curses::VC_GRAPHIC.value(ACS_VLINE)); view_colors::role_t bar_role = view_colors::VCR_NONE; @@ -491,19 +492,16 @@ logfile_sub_source::text_attrs_for_line(textview_curses& lv, break; } if (bar_role != view_colors::VCR_NONE) { - value_out.emplace_back( - line_range(12, 13), &view_curses::VC_ROLE, bar_role); + value_out.emplace_back(line_range(12, 13), + view_curses::VC_ROLE.value(bar_role)); } } lr.lr_start = 0; lr.lr_end = -1; - value_out.emplace_back(lr, &logline::L_FILE, this->lss_token_file.get()); + value_out.emplace_back(lr, logline::L_FILE.value(this->lss_token_file)); value_out.emplace_back( - lr, &SA_FORMAT, this->lss_token_file->get_format()->get_name()); - - value_out.emplace_back( - lr, SA_FORMAT2.value(this->lss_token_file->get_format()->get_name())); + lr, SA_FORMAT.value(this->lss_token_file->get_format()->get_name())); { const auto& bv = lv.get_bookmarks()[&textview_curses::BM_META]; @@ -522,7 +520,7 @@ logfile_sub_source::text_attrs_for_line(textview_curses& lv, lr.lr_start = 0; lr.lr_end = -1; value_out.emplace_back( - lr, &logline::L_PARTITION, &bm_iter->second); + lr, logline::L_PARTITION.value(&bm_iter->second)); } } @@ -532,7 +530,7 @@ logfile_sub_source::text_attrs_for_line(textview_curses& lv, if (bm_iter != this->lss_user_mark_metadata.end()) { lr.lr_start = 0; lr.lr_end = -1; - value_out.emplace_back(lr, &logline::L_META, &bm_iter->second); + value_out.emplace_back(lr, logline::L_META.value(&bm_iter->second)); } } @@ -541,9 +539,9 @@ logfile_sub_source::text_attrs_for_line(textview_curses& lv, = find_string_attr_range(value_out, &logline::L_TIMESTAMP); if (time_range.lr_end != -1) { - value_out.emplace_back(time_range, - &view_curses::VC_ROLE, - view_colors::VCR_ADJUSTED_TIME); + value_out.emplace_back( + time_range, + view_curses::VC_ROLE.value(view_colors::VCR_ADJUSTED_TIME)); } } @@ -552,9 +550,9 @@ logfile_sub_source::text_attrs_for_line(textview_curses& lv, = find_string_attr_range(value_out, &logline::L_TIMESTAMP); if (time_range.lr_end != -1) { - value_out.emplace_back(time_range, - &view_curses::VC_ROLE, - view_colors::VCR_SKEWED_TIME); + value_out.emplace_back( + time_range, + view_curses::VC_ROLE.value(view_colors::VCR_SKEWED_TIME)); } } @@ -567,8 +565,8 @@ logfile_sub_source::text_attrs_for_line(textview_curses& lv, this->lss_token_line); if (eval_res.isErr()) { color = COLOR_YELLOW; - value_out.emplace_back( - line_range{0, -1}, &SA_ERROR, eval_res.unwrapErr()); + value_out.emplace_back(line_range{0, -1}, + SA_ERROR.value(eval_res.unwrapErr())); } else { auto matched = eval_res.unwrap(); @@ -577,11 +575,11 @@ logfile_sub_source::text_attrs_for_line(textview_curses& lv, } else { color = COLOR_RED; value_out.emplace_back( - line_range{0, 1}, &view_curses::VC_STYLE, A_BLINK); + line_range{0, 1}, view_curses::VC_STYLE.value(A_BLINK)); } } - value_out.emplace_back( - line_range{0, 1}, &view_curses::VC_BACKGROUND, color); + value_out.emplace_back(line_range{0, 1}, + view_curses::VC_BACKGROUND.value(color)); } auto sql_filter_opt = this->get_sql_filter(); @@ -597,9 +595,9 @@ logfile_sub_source::text_attrs_for_line(textview_curses& lv, "filter expression evaluation failed with -- {}"), eval_res.unwrapErr()); auto color = COLOR_YELLOW; - value_out.emplace_back(line_range{0, -1}, &SA_ERROR, msg); - value_out.emplace_back( - line_range{0, 1}, &view_curses::VC_BACKGROUND, color); + value_out.emplace_back(line_range{0, -1}, SA_ERROR.value(msg)); + value_out.emplace_back(line_range{0, 1}, + view_curses::VC_BACKGROUND.value(color)); } } } diff --git a/src/optional.hpp b/src/optional.hpp index aa54e936..d837ae40 100644 --- a/src/optional.hpp +++ b/src/optional.hpp @@ -4,18 +4,21 @@ // https://github.com/martinmoene/optional-lite // // Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// (See accompanying file LICENSE.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) #pragma once #ifndef NONSTD_OPTIONAL_LITE_HPP -#define NONSTD_OPTIONAL_LITE_HPP +# define NONSTD_OPTIONAL_LITE_HPP -#define optional_lite_MAJOR 3 -#define optional_lite_MINOR 4 -#define optional_lite_PATCH 0 +# define optional_lite_MAJOR 3 +# define optional_lite_MINOR 4 +# define optional_lite_PATCH 0 -#define optional_lite_VERSION optional_STRINGIFY(optional_lite_MAJOR) "." optional_STRINGIFY(optional_lite_MINOR) "." optional_STRINGIFY(optional_lite_PATCH) +# define optional_lite_VERSION \ + optional_STRINGIFY(optional_lite_MAJOR) "." optional_STRINGIFY( \ + optional_lite_MINOR) "." optional_STRINGIFY(optional_lite_PATCH) #define optional_STRINGIFY( x ) optional_STRINGIFY_( x ) #define optional_STRINGIFY_( x ) #x diff --git a/src/readline_callbacks.cc b/src/readline_callbacks.cc index 3cb9b951..df65a643 100644 --- a/src/readline_callbacks.cc +++ b/src/readline_callbacks.cc @@ -766,7 +766,7 @@ rl_display_matches(readline_curses* rc) add_nl = false; } if (match == current_match) { - al.append(match, &view_curses::VC_STYLE, A_REVERSE); + al.append(match, view_curses::VC_STYLE.value(A_REVERSE)); } else { al.append(match); } diff --git a/src/readline_highlighters.cc b/src/readline_highlighters.cc index 944da6ef..9cc121f0 100644 --- a/src/readline_highlighters.cc +++ b/src/readline_highlighters.cc @@ -89,9 +89,9 @@ find_matching_bracket(attr_line_t& al, int x, char left, char right) depth += 1; } else if (line[lpc] == left && is_bracket(line, lpc, is_lit)) { if (depth == 0) { - al.get_attrs().emplace_back(line_range(lpc, lpc + 1), - &view_curses::VC_STYLE, - matching_bracket_attrs); + al.get_attrs().emplace_back( + line_range(lpc, lpc + 1), + view_curses::VC_STYLE.value(matching_bracket_attrs)); break; } else { depth -= 1; @@ -106,9 +106,9 @@ find_matching_bracket(attr_line_t& al, int x, char left, char right) depth += 1; } else if (line[lpc] == right && is_bracket(line, lpc, is_lit)) { if (depth == 0) { - al.get_attrs().emplace_back(line_range(lpc, lpc + 1), - &view_curses::VC_STYLE, - matching_bracket_attrs); + al.get_attrs().emplace_back( + line_range(lpc, lpc + 1), + view_curses::VC_STYLE.value(matching_bracket_attrs)); break; } else { depth -= 1; @@ -133,8 +133,7 @@ find_matching_bracket(attr_line_t& al, int x, char left, char right) } else { al.get_attrs().emplace_back( line_range(is_lit ? lpc - 1 : lpc, lpc + 1), - &view_curses::VC_STYLE, - missing_bracket_attrs); + view_curses::VC_STYLE.value(missing_bracket_attrs)); } } } @@ -142,8 +141,7 @@ find_matching_bracket(attr_line_t& al, int x, char left, char right) if (depth > 0) { al.get_attrs().emplace_back( line_range(is_lit ? first_left - 1 : first_left, first_left + 1), - &view_curses::VC_STYLE, - missing_bracket_attrs); + view_curses::VC_STYLE.value(missing_bracket_attrs)); } } @@ -188,15 +186,15 @@ readline_regex_highlighter_int(attr_line_t& al, int x, int skip) case '+': case '|': case '.': - al.get_attrs().emplace_back(line_range(lpc, lpc + 1), - &view_curses::VC_STYLE, - special_char); + al.get_attrs().emplace_back( + line_range(lpc, lpc + 1), + view_curses::VC_STYLE.value(special_char)); if ((line[lpc] == '*' || line[lpc] == '+') && check_re_prev(line, lpc)) { - al.get_attrs().emplace_back(line_range(lpc - 1, lpc), - &view_curses::VC_STYLE, - repeated_char_attrs); + al.get_attrs().emplace_back( + line_range(lpc - 1, lpc), + view_curses::VC_STYLE.value(repeated_char_attrs)); } break; case '?': { @@ -213,16 +211,16 @@ readline_regex_highlighter_int(attr_line_t& al, int x, int skip) break; } al.get_attrs().emplace_back( - lr, &view_curses::VC_STYLE, bracket_attrs); + lr, view_curses::VC_STYLE.value(bracket_attrs)); } else { al.get_attrs().emplace_back( - lr, &view_curses::VC_STYLE, special_char); + lr, view_curses::VC_STYLE.value(special_char)); if (check_re_prev(line, lpc)) { al.get_attrs().emplace_back( line_range(lpc - 1, lpc), - &view_curses::VC_STYLE, - repeated_char_attrs); + view_curses::VC_STYLE.value( + repeated_char_attrs)); } } break; @@ -234,9 +232,9 @@ readline_regex_highlighter_int(attr_line_t& al, int x, int skip) case '}': case '[': case ']': - al.get_attrs().emplace_back(line_range(lpc, lpc + 1), - &view_curses::VC_STYLE, - bracket_attrs); + al.get_attrs().emplace_back( + line_range(lpc, lpc + 1), + view_curses::VC_STYLE.value(bracket_attrs)); break; } } @@ -248,9 +246,9 @@ readline_regex_highlighter_int(attr_line_t& al, int x, int skip) switch (line[lpc]) { case '\\': backslash_is_quoted = true; - al.with_attr(string_attr(line_range(lpc - 1, lpc + 1), - &view_curses::VC_STYLE, - special_char)); + al.with_attr( + string_attr(line_range(lpc - 1, lpc + 1), + view_curses::VC_STYLE.value(special_char))); break; case 'd': case 'D': @@ -272,45 +270,44 @@ readline_regex_highlighter_int(attr_line_t& al, int x, int skip) case 'G': case 'Z': case 'z': - al.get_attrs().emplace_back(line_range(lpc - 1, lpc + 1), - &view_curses::VC_STYLE, - class_attrs); + al.get_attrs().emplace_back( + line_range(lpc - 1, lpc + 1), + view_curses::VC_STYLE.value(class_attrs)); break; case ' ': - al.get_attrs().emplace_back(line_range(lpc - 1, lpc + 1), - &view_curses::VC_STYLE, - error_attrs); + al.get_attrs().emplace_back( + line_range(lpc - 1, lpc + 1), + view_curses::VC_STYLE.value(error_attrs)); break; case '0': case 'x': if (safe_read(line, lpc + 1) == '{') { - al.with_attr(string_attr(line_range(lpc - 1, lpc + 1), - &view_curses::VC_STYLE, - special_char)); + al.with_attr(string_attr( + line_range(lpc - 1, lpc + 1), + view_curses::VC_STYLE.value(special_char))); } else if (isdigit(safe_read(line, lpc + 1)) && isdigit(safe_read(line, lpc + 2))) { - al.with_attr(string_attr(line_range(lpc - 1, lpc + 3), - &view_curses::VC_STYLE, - special_char)); + al.with_attr(string_attr( + line_range(lpc - 1, lpc + 3), + view_curses::VC_STYLE.value(special_char))); } else { - al.with_attr(string_attr(line_range(lpc - 1, lpc + 1), - &view_curses::VC_STYLE, - error_attrs)); + al.with_attr(string_attr( + line_range(lpc - 1, lpc + 1), + view_curses::VC_STYLE.value(error_attrs))); } break; case 'Q': case 'E': - al.with_attr(string_attr(line_range(lpc - 1, lpc + 1), - &view_curses::VC_STYLE, - bracket_attrs)); + al.with_attr(string_attr( + line_range(lpc - 1, lpc + 1), + view_curses::VC_STYLE.value(bracket_attrs))); break; default: if (isdigit(line[lpc])) { al.get_attrs().emplace_back( line_range(lpc - 1, lpc + 1), - &view_curses::VC_STYLE, - special_char); + view_curses::VC_STYLE.value(special_char)); } break; } @@ -351,8 +348,8 @@ readline_command_highlighter(attr_line_t& al, int x) ws_index = line.find(' '); auto command = line.substr(0, ws_index); if (ws_index != std::string::npos) { - al.get_attrs().emplace_back( - line_range(1, ws_index), &view_curses::VC_STYLE, keyword_attrs); + al.get_attrs().emplace_back(line_range(1, ws_index), + view_curses::VC_STYLE.value(keyword_attrs)); } if (RE_PREFIXES.match(pc, pi)) { readline_regex_highlighter_int(al, x, 1 + pc[0]->length()); @@ -376,8 +373,8 @@ readline_command_highlighter(attr_line_t& al, int x) .then([&](const auto& rgb_fg) { al.get_attrs().emplace_back( line_range{cap->c_begin, cap->c_begin + 1}, - &view_curses::VC_ROLE, - view_colors::VCR_COLOR_HINT); + view_curses::VC_ROLE.value( + view_colors::VCR_COLOR_HINT)); }); } } @@ -405,7 +402,7 @@ readline_command_highlighter(attr_line_t& al, int x) value = "#" + value; } al.get_attrs().emplace_back( - lr, &view_curses::VC_STYLE, vc.attrs_for_ident(value)); + lr, view_curses::VC_STYLE.value(vc.attrs_for_ident(value))); } start = last; @@ -447,7 +444,8 @@ readline_sqlite_highlighter_int(attr_line_t& al, int x, int skip) if (space != std::string::npos) { lr.lr_end = space; } - al.get_attrs().emplace_back(lr, &view_curses::VC_STYLE, keyword_attrs); + al.get_attrs().emplace_back(lr, + view_curses::VC_STYLE.value(keyword_attrs)); return; } @@ -458,7 +456,7 @@ readline_sqlite_highlighter_int(attr_line_t& al, int x, int skip) if (line[cap->c_end] == '(') { } else if (!lr.contains(x) && !lr.contains(x - 1)) { - al.get_attrs().emplace_back(lr, &view_curses::VC_STYLE, attrs); + al.get_attrs().emplace_back(lr, view_curses::VC_STYLE.value(attrs)); } } @@ -468,8 +466,7 @@ readline_sqlite_highlighter_int(attr_line_t& al, int x, int skip) pcre_context::capture_t* cap = pc.all(); al.get_attrs().emplace_back(line_range(cap->c_begin, cap->c_end), - &view_curses::VC_STYLE, - keyword_attrs); + view_curses::VC_STYLE.value(keyword_attrs)); } for (size_t lpc = skip; lpc < line.length(); lpc++) { @@ -481,9 +478,9 @@ readline_sqlite_highlighter_int(attr_line_t& al, int x, int skip) case '!': case '-': case '+': - al.get_attrs().emplace_back(line_range(lpc, lpc + 1), - &view_curses::VC_STYLE, - symbol_attrs); + al.get_attrs().emplace_back( + line_range(lpc, lpc + 1), + view_curses::VC_STYLE.value(symbol_attrs)); break; } } @@ -499,11 +496,10 @@ readline_sqlite_highlighter_int(attr_line_t& al, int x, int skip) if (line[cap->c_end - 1] != '\'') { sa.emplace_back(line_range(cap->c_begin, cap->c_begin + 1), - &view_curses::VC_STYLE, - error_attrs); + view_curses::VC_STYLE.value(error_attrs)); lr.lr_start += 1; } - sa.emplace_back(lr, &view_curses::VC_STYLE, string_attrs); + sa.emplace_back(lr, view_curses::VC_STYLE.value(string_attrs)); } for (int lpc = 0; brackets[lpc]; lpc++) { @@ -533,15 +529,15 @@ readline_shlex_highlighter(attr_line_t& al, int x) while (lexer.tokenize(cap, token)) { switch (token) { case shlex_token_t::ST_ERROR: - al.with_attr(string_attr(line_range(cap.c_begin, cap.c_end), - &view_curses::VC_STYLE, - error_attrs)); + al.with_attr( + string_attr(line_range(cap.c_begin, cap.c_end), + view_curses::VC_STYLE.value(error_attrs))); break; case shlex_token_t::ST_TILDE: case shlex_token_t::ST_ESCAPE: - al.with_attr(string_attr(line_range(cap.c_begin, cap.c_end), - &view_curses::VC_STYLE, - special_char)); + al.with_attr( + string_attr(line_range(cap.c_begin, cap.c_end), + view_curses::VC_STYLE.value(special_char))); break; case shlex_token_t::ST_DOUBLE_QUOTE_START: case shlex_token_t::ST_SINGLE_QUOTE_START: @@ -549,9 +545,9 @@ readline_shlex_highlighter(attr_line_t& al, int x) break; case shlex_token_t::ST_DOUBLE_QUOTE_END: case shlex_token_t::ST_SINGLE_QUOTE_END: - al.with_attr(string_attr(line_range(quote_start, cap.c_end), - &view_curses::VC_STYLE, - string_attrs)); + al.with_attr( + string_attr(line_range(quote_start, cap.c_end), + view_curses::VC_STYLE.value(string_attrs))); quote_start = -1; break; case shlex_token_t::ST_VARIABLE_REF: @@ -563,17 +559,16 @@ readline_shlex_highlighter(attr_line_t& al, int x) al.with_attr(string_attr( line_range(cap.c_begin, cap.c_begin + 1 + extra), - &view_curses::VC_STYLE, - special_char)); + view_curses::VC_STYLE.value(special_char))); al.with_attr(string_attr( line_range(cap.c_begin + 1 + extra, cap.c_end - extra), - &view_curses::VC_STYLE, - x == cap.c_end || cap.contains(x) ? special_char : attrs)); + view_curses::VC_STYLE.value( + x == cap.c_end || cap.contains(x) ? special_char + : attrs))); if (extra) { al.with_attr( string_attr(line_range(cap.c_end - 1, cap.c_end), - &view_curses::VC_STYLE, - special_char)); + view_curses::VC_STYLE.value(special_char))); } break; } @@ -584,7 +579,6 @@ readline_shlex_highlighter(attr_line_t& al, int x) if (quote_start != -1) { al.with_attr(string_attr(line_range(quote_start, quote_start + 1), - &view_curses::VC_STYLE, - error_attrs)); + view_curses::VC_STYLE.value(error_attrs))); } } diff --git a/src/spectro_source.cc b/src/spectro_source.cc index 00738e81..de20b216 100644 --- a/src/spectro_source.cc +++ b/src/spectro_source.cc @@ -184,8 +184,8 @@ spectrogram_source::list_value_for_overlay(const listview_curses& lv, line.append(width - strlen(buf) - line.length() - 2, ' '); line.append(buf); - value_out.with_attr( - string_attr(line_range(0, -1), &view_curses::VC_STYLE, A_UNDERLINE)); + value_out.with_attr(string_attr(line_range(0, -1), + view_curses::VC_STYLE.value(A_UNDERLINE))); return true; } @@ -321,8 +321,8 @@ spectrogram_source::text_attrs_for_line(textview_curses& tc, color = COLOR_RED; } value_out.emplace_back(line_range(lpc, lpc + 1), - &view_curses::VC_STYLE, - vc.ansi_color_pair(COLOR_BLACK, color)); + view_curses::VC_STYLE.value( + vc.ansi_color_pair(COLOR_BLACK, color))); } } diff --git a/src/sql_help.hh b/src/sql_help.hh index d25a2c27..90c4b135 100644 --- a/src/sql_help.hh +++ b/src/sql_help.hh @@ -37,14 +37,14 @@ #include "attr_line.hh" #include "help_text.hh" -extern string_attr_type SQL_COMMAND_ATTR; -extern string_attr_type SQL_KEYWORD_ATTR; -extern string_attr_type SQL_IDENTIFIER_ATTR; -extern string_attr_type SQL_FUNCTION_ATTR; -extern string_attr_type SQL_STRING_ATTR; -extern string_attr_type SQL_OPERATOR_ATTR; -extern string_attr_type SQL_PAREN_ATTR; -extern string_attr_type SQL_GARBAGE_ATTR; +extern string_attr_type SQL_COMMAND_ATTR; +extern string_attr_type SQL_KEYWORD_ATTR; +extern string_attr_type SQL_IDENTIFIER_ATTR; +extern string_attr_type SQL_FUNCTION_ATTR; +extern string_attr_type SQL_STRING_ATTR; +extern string_attr_type SQL_OPERATOR_ATTR; +extern string_attr_type SQL_PAREN_ATTR; +extern string_attr_type SQL_GARBAGE_ATTR; void annotate_sql_statement(attr_line_t& al_inout); diff --git a/src/sql_util.cc b/src/sql_util.cc index d98810af..51531064 100644 --- a/src/sql_util.cc +++ b/src/sql_util.cc @@ -881,15 +881,15 @@ sql_keyword_re() return retval; } -string_attr_type SQL_COMMAND_ATTR("sql_command"); -string_attr_type SQL_KEYWORD_ATTR("sql_keyword"); -string_attr_type SQL_IDENTIFIER_ATTR("sql_ident"); -string_attr_type SQL_FUNCTION_ATTR("sql_func"); -string_attr_type SQL_STRING_ATTR("sql_string"); -string_attr_type SQL_OPERATOR_ATTR("sql_oper"); -string_attr_type SQL_PAREN_ATTR("sql_paren"); -string_attr_type SQL_COMMA_ATTR("sql_comma"); -string_attr_type SQL_GARBAGE_ATTR("sql_garbage"); +string_attr_type SQL_COMMAND_ATTR("sql_command"); +string_attr_type SQL_KEYWORD_ATTR("sql_keyword"); +string_attr_type SQL_IDENTIFIER_ATTR("sql_ident"); +string_attr_type SQL_FUNCTION_ATTR("sql_func"); +string_attr_type SQL_STRING_ATTR("sql_string"); +string_attr_type SQL_OPERATOR_ATTR("sql_oper"); +string_attr_type SQL_PAREN_ATTR("sql_paren"); +string_attr_type SQL_COMMA_ATTR("sql_comma"); +string_attr_type SQL_GARBAGE_ATTR("sql_garbage"); void annotate_sql_statement(attr_line_t& al) @@ -898,7 +898,7 @@ annotate_sql_statement(attr_line_t& al) static struct { pcrepp re; - string_attr_type_t type; + string_attr_type* type; } PATTERNS[] = { {pcrepp{R"(^(\.\w+))"}, &SQL_COMMAND_ATTR}, {pcrepp{R"(\A,)"}, &SQL_COMMA_ATTR}, @@ -928,7 +928,7 @@ annotate_sql_statement(attr_line_t& al) pcre_context::capture_t* cap = pc.all(); struct line_range lr(cap->c_begin, cap->c_end); - sa.emplace_back(lr, pat.type); + sa.emplace_back(lr, pat.type->value()); break; } } @@ -974,7 +974,7 @@ annotate_sql_statement(attr_line_t& al) } else { func_range.lr_end = piter->sa_range.lr_end - 1; } - sa.emplace_back(func_range, &SQL_FUNCTION_ATTR); + sa.emplace_back(func_range, SQL_FUNCTION_ATTR.value()); } start = iter->sa_range.lr_end; diff --git a/src/state-extension-functions.cc b/src/state-extension-functions.cc index da689b7a..3c3b9907 100644 --- a/src/state-extension-functions.cc +++ b/src/state-extension-functions.cc @@ -83,9 +83,9 @@ sql_lnav_top_file() auto top_view = top_view_opt.value(); return top_view->map_top_row([](const auto& al) { - return get_string_attr(al.get_attrs(), &logline::L_FILE) | - [](const auto* sa) { - auto lf = (logfile*) sa->sa_value.sav_ptr; + return get_string_attr(al.get_attrs(), logline::L_FILE) | + [](const auto wrapper) { + auto lf = wrapper.get(); return nonstd::make_optional(lf->get_filename()); }; diff --git a/src/statusview_curses.cc b/src/statusview_curses.cc index 2e0fb466..8d9680b1 100644 --- a/src/statusview_curses.cc +++ b/src/statusview_curses.cc @@ -63,8 +63,8 @@ status_field::do_cylon() sa.emplace_back( lr, - &view_curses::VC_STYLE, - vc.attrs_for_role(view_colors::VCR_ACTIVE_STATUS) | A_REVERSE); + view_curses::VC_STYLE.value( + vc.attrs_for_role(view_colors::VCR_ACTIVE_STATUS) | A_REVERSE)); this->sf_cylon_pos += 1; if (this->sf_cylon_pos > this->sf_width) { @@ -81,10 +81,10 @@ status_field::set_stitch_value(view_colors::role_t left, this->sf_value.get_string() = "::"; sa.clear(); - sa.emplace_back(lr, &view_curses::VC_ROLE, left); + sa.emplace_back(lr, view_curses::VC_ROLE.value(left)); lr.lr_start = 1; lr.lr_end = 2; - sa.emplace_back(lr, &view_curses::VC_ROLE, right); + sa.emplace_back(lr, view_curses::VC_ROLE.value(right)); } void @@ -126,14 +126,15 @@ statusview_curses::do_update() if (!this->sc_enabled) { for (auto& sa : val.get_attrs()) { if (sa.sa_type == &view_curses::VC_STYLE) { - sa.sa_value.sav_int &= ~(A_REVERSE | A_COLOR); + sa.sa_value = sa.sa_value.get() + & ~(A_REVERSE | A_COLOR); } else if (sa.sa_type == &view_curses::VC_ROLE) { - if (sa.sa_value.sav_int + if (sa.sa_value.get() == view_colors::VCR_ALERT_STATUS) { - sa.sa_value.sav_int + sa.sa_value.get() = view_colors::VCR_INACTIVE_ALERT_STATUS; } else { - sa.sa_value.sav_int = view_colors::VCR_NONE; + sa.sa_value = view_colors::VCR_NONE; } } } diff --git a/src/string_attr_type.cc b/src/string_attr_type.cc index 0c75e889..c8e4c485 100644 --- a/src/string_attr_type.cc +++ b/src/string_attr_type.cc @@ -31,11 +31,10 @@ #include "config.h" -string_attr_type SA_ORIGINAL_LINE("original_line"); -string_attr_type SA_BODY("body"); -string_attr_type SA_HIDDEN("hidden"); -string_attr_type SA_FORMAT("format"); -string_attr_type2 SA_FORMAT2("format"); -string_attr_type SA_REMOVED("removed"); -string_attr_type SA_INVALID("invalid"); -string_attr_type SA_ERROR("error"); +string_attr_type SA_ORIGINAL_LINE("original_line"); +string_attr_type SA_BODY("body"); +string_attr_type SA_HIDDEN("hidden"); +string_attr_type SA_FORMAT("format"); +string_attr_type SA_REMOVED("removed"); +string_attr_type SA_INVALID("invalid"); +string_attr_type SA_ERROR("error"); diff --git a/src/string_attr_type.hh b/src/string_attr_type.hh index 99a730f3..a2331911 100644 --- a/src/string_attr_type.hh +++ b/src/string_attr_type.hh @@ -30,6 +30,7 @@ #ifndef lnav_string_attr_type_hh #define lnav_string_attr_type_hh +#include #include #include @@ -37,17 +38,14 @@ #include "base/intern_string.hh" #include "mapbox/variant.hpp" -class string_attr_type { -public: - explicit string_attr_type(const char* name = nullptr) noexcept - : sat_name(name){}; +class logfile; +struct bookmark_metadata; - const char* sat_name; -}; -using string_attr_type_t = string_attr_type*; - -using string_attr_value - = mapbox::util::variant; +using string_attr_value = mapbox::util::variant, + bookmark_metadata*>; class string_attr_type_base { public: @@ -59,27 +57,38 @@ public: }; template -class string_attr_type2 : public string_attr_type_base { +class string_attr_type : public string_attr_type_base { public: - explicit string_attr_type2(const char* name) noexcept + using value_type = T; + + explicit string_attr_type(const char* name) noexcept : string_attr_type_base(name) { } - std::pair value(const T& val) + template + std::enable_if_t::value, + std::pair> + value(const U& val) const { return std::make_pair(this, val); } + + template + std::enable_if_t::value, + std::pair> + value() const + { + return std::make_pair(this, string_attr_value{}); + } }; -extern string_attr_type SA_ORIGINAL_LINE; -extern string_attr_type SA_BODY; -extern string_attr_type SA_HIDDEN; -extern string_attr_type SA_FORMAT; -class intern_string; -extern string_attr_type2 SA_FORMAT2; -extern string_attr_type SA_REMOVED; -extern string_attr_type SA_INVALID; -extern string_attr_type SA_ERROR; +extern string_attr_type SA_ORIGINAL_LINE; +extern string_attr_type SA_BODY; +extern string_attr_type SA_HIDDEN; +extern string_attr_type SA_FORMAT; +extern string_attr_type SA_REMOVED; +extern string_attr_type SA_INVALID; +extern string_attr_type SA_ERROR; #endif diff --git a/src/term_extra.hh b/src/term_extra.hh index bd36ca9b..61b9a8c9 100644 --- a/src/term_extra.hh +++ b/src/term_extra.hh @@ -76,15 +76,14 @@ public: } if (lc->get_inner_height() > 0) { - string_attrs_t::const_iterator line_attr; std::vector rows(1); lc->get_data_source()->listview_value_for_rows( *lc, lc->get_top(), rows); string_attrs_t& sa = rows[0].get_attrs(); - line_attr = find_string_attr(sa, &logline::L_FILE); - if (line_attr != sa.end()) { - logfile* lf = (logfile*) line_attr->sa_value.sav_ptr; + auto line_attr_opt = get_string_attr(sa, logline::L_FILE); + if (line_attr_opt) { + auto lf = line_attr_opt.value().get(); const std::string& filename = lf->get_unique_path(); if (filename != this->te_last_title) { diff --git a/src/textfile_sub_source.cc b/src/textfile_sub_source.cc index 037ad682..65252e80 100644 --- a/src/textfile_sub_source.cc +++ b/src/textfile_sub_source.cc @@ -77,7 +77,7 @@ textfile_sub_source::text_attrs_for_line(textview_curses& tc, lr.lr_start = 0; lr.lr_end = -1; - value_out.emplace_back(lr, &logline::L_FILE, this->current_file().get()); + value_out.emplace_back(lr, logline::L_FILE.value(this->current_file())); } size_t diff --git a/src/textview_curses.cc b/src/textview_curses.cc index 1b44e75b..a6fd6847 100644 --- a/src/textview_curses.cc +++ b/src/textview_curses.cc @@ -450,9 +450,9 @@ textview_curses::textview_value_for_row(vis_line_t row, attr_line_t& value_out) orig_line.lr_end = str.size(); } - auto sa_iter = find_string_attr(sa, &SA_FORMAT); - if (sa_iter != sa.end()) { - format_name = sa_iter->to_string(); + auto format_attr_opt = get_string_attr(sa, SA_FORMAT); + if (format_attr_opt) { + format_name = format_attr_opt.value().get(); } for (auto& tc_highlight : this->tc_highlights) { @@ -546,8 +546,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}, - &view_curses::VC_STYLE, - A_REVERSE); + view_curses::VC_STYLE.value(A_REVERSE)); } } diff --git a/src/top_status_source.cc b/src/top_status_source.cc index f9d02c91..3ff86db7 100644 --- a/src/top_status_source.cc +++ b/src/top_status_source.cc @@ -90,15 +90,14 @@ top_status_source::update_filename(listview_curses* lc) auto& sf_filename = this->tss_fields[TSF_FILENAME]; if (lc->get_inner_height() > 0) { - string_attrs_t::const_iterator line_attr; std::vector rows(1); lc->get_data_source()->listview_value_for_rows( *lc, lc->get_top(), rows); auto& sa = rows[0].get_attrs(); - line_attr = find_string_attr(sa, &logline::L_FILE); - if (line_attr != sa.end()) { - logfile* lf = (logfile*) line_attr->sa_value.sav_ptr; + auto file_attr_opt = get_string_attr(sa, logline::L_FILE); + if (file_attr_opt) { + auto lf = file_attr_opt.value().get(); if (lf->get_format()) { sf_format.set_value("% 13s", @@ -120,9 +119,9 @@ top_status_source::update_filename(listview_curses* lc) sf_filename.clear(); } - line_attr = find_string_attr(sa, &logline::L_PARTITION); - if (line_attr != sa.end()) { - auto bm = (bookmark_metadata*) line_attr->sa_value.sav_ptr; + auto part_attr_opt = get_string_attr(sa, logline::L_PARTITION); + if (part_attr_opt) { + auto bm = part_attr_opt.value().get(); sf_partition.set_value(bm->bm_name.c_str()); } else { diff --git a/src/view_curses.cc b/src/view_curses.cc index 0bda3d4e..e4649186 100644 --- a/src/view_curses.cc +++ b/src/view_curses.cc @@ -48,13 +48,12 @@ using namespace std::chrono_literals; -string_attr_type view_curses::VC_ROLE("role"); -string_attr_type view_curses::VC_ROLE_FG("role-fg"); -string_attr_type view_curses::VC_STYLE("style"); -string_attr_type view_curses::VC_GRAPHIC("graphic"); -string_attr_type view_curses::VC_SELECTED("selected"); -string_attr_type view_curses::VC_FOREGROUND("foreground"); -string_attr_type view_curses::VC_BACKGROUND("background"); +string_attr_type view_curses::VC_ROLE("role"); +string_attr_type view_curses::VC_ROLE_FG("role-fg"); +string_attr_type view_curses::VC_STYLE("style"); +string_attr_type view_curses::VC_GRAPHIC("graphic"); +string_attr_type view_curses::VC_FOREGROUND("foreground"); +string_attr_type view_curses::VC_BACKGROUND("background"); const struct itimerval ui_periodic_timer::INTERVAL = { {0, std::chrono::duration_cast(350ms).count()}, @@ -124,23 +123,16 @@ view_curses::mvwattrline(WINDOW* window, const struct line_range& lr_chars, view_colors::role_t base_role) { - attr_t text_attrs, attrs; - int line_width_chars; - string_attrs_t& sa = al.get_attrs(); - std::string& line = al.get_string(); - string_attrs_t::const_iterator iter; + auto& sa = al.get_attrs(); + auto& line = al.get_string(); std::vector utf_adjustments; - int tab_count = 0; - char* expanded_line; - int exp_index = 0; int exp_offset = 0; std::string full_line; require(lr_chars.lr_end >= 0); - line_width_chars = lr_chars.length(); - tab_count = count(line.begin(), line.end(), '\t'); - expanded_line = (char*) alloca(line.size() + tab_count * 8 + 1); + auto line_width_chars = lr_chars.length(); + std::string expanded_line; short* fg_color = (short*) alloca(line_width_chars * sizeof(short)); bool has_fg = false; @@ -150,24 +142,22 @@ view_curses::mvwattrline(WINDOW* window, int char_index = 0; for (size_t lpc = 0; lpc < line.size(); lpc++) { - int exp_start_index = exp_index; - unsigned char ch = static_cast(line[lpc]); + int exp_start_index = expanded_line.size(); + auto ch = static_cast(line[lpc]); switch (ch) { case '\t': do { - expanded_line[exp_index] = ' '; - exp_index += 1; + expanded_line.push_back(' '); char_index += 1; - } while (exp_index % 8); - utf_adjustments.emplace_back(lpc, - exp_index - exp_start_index - 1); + } while (expanded_line.size() % 8); + utf_adjustments.emplace_back( + lpc, expanded_line.size() - exp_start_index - 1); break; case '\r': case '\n': - expanded_line[exp_index] = ' '; - exp_index += 1; + expanded_line.push_back(' '); char_index += 1; break; @@ -177,13 +167,11 @@ view_curses::mvwattrline(WINDOW* window, }); if (size_result.isErr()) { - expanded_line[exp_index] = '?'; - exp_index += 1; + expanded_line.push_back('?'); } else { auto offset = 1 - (int) size_result.unwrap(); - expanded_line[exp_index] = line[lpc]; - exp_index += 1; + expanded_line.push_back(ch); if (offset) { if (char_index < lr_chars.lr_start) { lr_bytes.lr_start += abs(offset); @@ -195,8 +183,7 @@ view_curses::mvwattrline(WINDOW* window, utf_adjustments.emplace_back(lpc, offset); for (; offset && (lpc + 1) < line.size(); lpc++, offset++) { - expanded_line[exp_index] = line[lpc + 1]; - exp_index += 1; + expanded_line.push_back(line[lpc + 1]); } } } @@ -206,12 +193,11 @@ view_curses::mvwattrline(WINDOW* window, } } - expanded_line[exp_index] = '\0'; - full_line = std::string(expanded_line); + full_line = expanded_line; - view_colors& vc = view_colors::singleton(); - text_attrs = vc.attrs_for_role(base_role); - attrs = text_attrs; + auto& vc = view_colors::singleton(); + auto text_attrs = vc.attrs_for_role(base_role); + auto attrs = text_attrs; wmove(window, y, x); wattron(window, attrs); if (lr_bytes.lr_start < (int) full_line.size()) { @@ -224,7 +210,7 @@ view_curses::mvwattrline(WINDOW* window, wattroff(window, attrs); stable_sort(sa.begin(), sa.end()); - for (iter = sa.begin(); iter != sa.end(); ++iter) { + for (auto iter = sa.begin(); iter != sa.end(); ++iter) { struct line_range attr_range = iter->sa_range; require(attr_range.lr_start >= 0); @@ -273,10 +259,9 @@ view_curses::mvwattrline(WINDOW* window, if (!has_fg) { memset(fg_color, -1, line_width_chars * sizeof(short)); } - short attr_fg = iter->sa_value.sav_int; + short attr_fg = iter->sa_value.get(); if (attr_fg == view_colors::MATCH_COLOR_SEMANTIC) { - attr_fg = vc.color_for_ident(&line[iter->sa_range.lr_start], - iter->sa_range.sublen(line)); + attr_fg = vc.color_for_ident(al.to_string_fragment(iter)); } std::fill(&fg_color[attr_range.lr_start], &fg_color[attr_range.lr_end], @@ -289,10 +274,9 @@ view_curses::mvwattrline(WINDOW* window, if (!has_bg) { memset(bg_color, -1, line_width_chars * sizeof(short)); } - short attr_bg = iter->sa_value.sav_int; + short attr_bg = iter->sa_value.get(); if (attr_bg == view_colors::MATCH_COLOR_SEMANTIC) { - attr_bg = vc.color_for_ident(&line[iter->sa_range.lr_start], - iter->sa_range.sublen(line)); + attr_bg = vc.color_for_ident(al.to_string_fragment(iter)); } std::fill(bg_color + attr_range.lr_start, bg_color + attr_range.lr_end, @@ -307,19 +291,19 @@ view_curses::mvwattrline(WINDOW* window, short color_pair = 0; if (iter->sa_type == &VC_GRAPHIC) { - graphic = iter->sa_value.sav_int; + graphic = iter->sa_value.get(); } else if (iter->sa_type == &VC_STYLE) { - attrs = iter->sa_value.sav_int & ~A_COLOR; - color_pair = PAIR_NUMBER(iter->sa_value.sav_int); + attrs = iter->sa_value.get() & ~A_COLOR; + color_pair = PAIR_NUMBER(iter->sa_value.get()); } else if (iter->sa_type == &VC_ROLE) { attrs = vc.attrs_for_role( - (view_colors::role_t) iter->sa_value.sav_int); + (view_colors::role_t) iter->sa_value.get()); color_pair = PAIR_NUMBER(attrs); attrs = attrs & ~A_COLOR; } else if (iter->sa_type == &VC_ROLE_FG) { short role_fg, role_bg; attrs = vc.attrs_for_role( - (view_colors::role_t) iter->sa_value.sav_int); + (view_colors::role_t) iter->sa_value.get()); color_pair = PAIR_NUMBER(attrs); pair_content(color_pair, &role_fg, &role_bg); attrs = attrs & ~A_COLOR; @@ -345,13 +329,11 @@ view_curses::mvwattrline(WINDOW* window, pair_content(color_pair, &pair_fg, &pair_bg); if (attrs & A_LEFT) { pair_fg - = vc.color_for_ident(&line[iter->sa_range.lr_start], - iter->sa_range.sublen(line)); + = vc.color_for_ident(al.to_string_fragment(iter)); } if (attrs & A_RIGHT) { pair_bg - = vc.color_for_ident(&line[iter->sa_range.lr_start], - iter->sa_range.sublen(line)); + = vc.color_for_ident(al.to_string_fragment(iter)); } color_pair = vc.ensure_color_pair(pair_fg, pair_bg); diff --git a/src/view_curses.hh b/src/view_curses.hh index 35eb1c9b..c164f141 100644 --- a/src/view_curses.hh +++ b/src/view_curses.hh @@ -297,6 +297,11 @@ public: int color_for_ident(const char* str, size_t len) const; + int 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); attr_t attrs_for_ident(intern_string_t str) @@ -467,13 +472,12 @@ public: return this->vc_width; } - static string_attr_type VC_ROLE; - static string_attr_type VC_ROLE_FG; - static string_attr_type VC_STYLE; - static string_attr_type VC_GRAPHIC; - static string_attr_type VC_SELECTED; - static string_attr_type VC_FOREGROUND; - static string_attr_type VC_BACKGROUND; + static string_attr_type VC_ROLE; + static string_attr_type VC_ROLE_FG; + static string_attr_type VC_STYLE; + static string_attr_type VC_GRAPHIC; + static string_attr_type VC_FOREGROUND; + static string_attr_type VC_BACKGROUND; static void awaiting_user_input(); diff --git a/src/views_vtab.cc b/src/views_vtab.cc index 928f2856..93779b13 100644 --- a/src/views_vtab.cc +++ b/src/views_vtab.cc @@ -201,9 +201,9 @@ CREATE TABLE lnav_views ( } case 6: { to_sqlite(ctx, tc.map_top_row([](const auto& al) { - return get_string_attr(al.get_attrs(), &logline::L_FILE) | - [](const auto* sa) { - auto lf = (logfile*) sa->sa_value.sav_ptr; + return get_string_attr(al.get_attrs(), logline::L_FILE) | + [](const auto wrapper) { + auto lf = wrapper.get(); return nonstd::make_optional(lf->get_filename()); }; diff --git a/test/drive_mvwattrline.cc b/test/drive_mvwattrline.cc index b8dcf615..e60912f8 100644 --- a/test/drive_mvwattrline.cc +++ b/test/drive_mvwattrline.cc @@ -68,44 +68,45 @@ main(int argc, char* argv[]) al.clear() .with_string("\tLeading tab") - .with_attr(string_attr( - line_range(0, 1), &view_curses::VC_STYLE, A_REVERSE)); + .with_attr(string_attr(line_range(0, 1), + view_curses::VC_STYLE.value(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), &view_curses::VC_STYLE, A_REVERSE)); + .with_attr(string_attr(line_range(1, 4), + view_curses::VC_STYLE.value(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), &view_curses::VC_STYLE, A_REVERSE)); + .with_attr(string_attr(line_range(3, 4), + view_curses::VC_STYLE.value(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), &view_curses::VC_STYLE, A_REVERSE)) - .with_attr(string_attr( - line_range(9, 13), &view_curses::VC_STYLE, A_REVERSE)); + .with_attr(string_attr(line_range(4, 6), + view_curses::VC_STYLE.value(A_REVERSE))) + .with_attr(string_attr(line_range(9, 13), + view_curses::VC_STYLE.value(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), - &view_curses::VC_STYLE, - view_colors::ansi_color_pair(COLOR_RED, COLOR_BLACK))) - .with_attr(string_attr( - line_range(7, 12), &view_curses::VC_STYLE, A_REVERSE)); + view_curses::VC_STYLE.value( + view_colors::ansi_color_pair(COLOR_RED, COLOR_BLACK)))) + .with_attr(string_attr(line_range(7, 12), + view_curses::VC_STYLE.value(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), &view_curses::VC_STYLE, A_REVERSE)); + al.clear().with_string(text).with_attr( + string_attr(line_range(offset, offset + 4), + view_curses::VC_STYLE.value(A_REVERSE))); view_curses::mvwattrline(win, y++, 0, al, lr); wmove(win, y, 0); diff --git a/test/drive_view_colors.cc b/test/drive_view_colors.cc index 48bc3e48..6f7574fd 100644 --- a/test/drive_view_colors.cc +++ b/test/drive_view_colors.cc @@ -52,8 +52,8 @@ public: snprintf(label, sizeof(label), "This is line: %d", lpc); attrs = vc.attrs_for_ident(label); al = label; - al.get_attrs().emplace_back( - line_range(0, -1), &view_curses::VC_STYLE, attrs); + al.get_attrs().emplace_back(line_range(0, -1), + view_curses::VC_STYLE.value(attrs)); lr.lr_start = 0; lr.lr_end = 40; test_colors::mvwattrline(this->tc_window, lpc, 0, al, lr); @@ -63,11 +63,10 @@ public: line_range lr{0, 40}; al = "before <123> after"; - al.with_attr( - {line_range{8, 11}, - &VC_STYLE, - (int64_t) view_colors::ansi_color_pair(COLOR_CYAN, COLOR_BLACK)}); - al.with_attr({line_range{8, 11}, &VC_STYLE, A_REVERSE}); + 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)}); test_colors::mvwattrline(this->tc_window, lpc, 0, al, lr); }; diff --git a/test/test_ansi_scrubber.cc b/test/test_ansi_scrubber.cc index 26ad57ef..a6ee5d84 100644 --- a/test/test_ansi_scrubber.cc +++ b/test/test_ansi_scrubber.cc @@ -61,10 +61,10 @@ 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 == &view_curses::VC_BACKGROUND); - assert(sa[0].sa_value.sav_int == COLOR_BLUE); + assert(sa[0].sa_value.get() == COLOR_BLUE); assert(sa[1].sa_range.lr_start == 7); assert(sa[1].sa_range.lr_end == 12); assert(sa[1].sa_type == &view_curses::VC_FOREGROUND); - assert(sa[1].sa_value.sav_int == COLOR_YELLOW); + assert(sa[1].sa_value.get() == COLOR_YELLOW); }