Compare commits

...

5 Commits

Author SHA1 Message Date
Tim Stack 8aa84ad143 [build] more optional 1 month ago
Tim Stack e732267cfe [build] missing functional include 1 month ago
Tim Stack bf6b64c4ea [build] missing optional includes 1 month ago
Tim Stack 11c9952e03 [build] missing include 1 month ago
Tim Stack 46b2a9f1ee [piper] start support for demux
... and other misc things:

* Bump to C++17
* Add zookeeper_log
1 month ago

@ -2,10 +2,10 @@ cmake_minimum_required(VERSION 3.14)
include(cmake/prelude.cmake) include(cmake/prelude.cmake)
set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD 17)
project( project(
lnav lnav
VERSION 0.12.2 VERSION 0.12.3
DESCRIPTION "An advanced log file viewer for the terminal." DESCRIPTION "An advanced log file viewer for the terminal."
HOMEPAGE_URL "https://lnav.org/" HOMEPAGE_URL "https://lnav.org/"
LANGUAGES CXX C LANGUAGES CXX C

@ -1,3 +1,20 @@
## lnav v0.12.3
Features:
* Files that contain a mixture of log messages from separate
services (e.g. docker logs) can now be automatically
de-multiplexed into separate files that lnav can digest.
Bug Fixes:
* Log messages in formats with custom timestamp formats were
not being converted to the local timezone.
* The timezone offset is now shown in the parser details
overlay for log messages.
Maintenance:
* Upgrade to C++17
## lnav v0.12.2 ## lnav v0.12.2
Features: Features:

@ -1,4 +1,4 @@
AC_INIT([lnav],[0.12.2],[lnav@googlegroups.com],[lnav],[http://lnav.org]) AC_INIT([lnav],[0.12.3],[lnav@googlegroups.com],[lnav],[http://lnav.org])
AC_CONFIG_SRCDIR([src/lnav.cc]) AC_CONFIG_SRCDIR([src/lnav.cc])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([foreign subdir-objects]) AM_INIT_AUTOMAKE([foreign subdir-objects])
@ -17,7 +17,7 @@ CXX="$PTHREAD_CXX"
CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS" CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
AC_LANG(C++) AC_LANG(C++)
AX_CXX_COMPILE_STDCXX_14([noext], [mandatory]) AX_CXX_COMPILE_STDCXX_17([noext], [mandatory])
dnl abssrcdir is the absolute path to the source base (regardless of where dnl abssrcdir is the absolute path to the source base (regardless of where
dnl you are building it) dnl you are building it)

@ -899,6 +899,27 @@
} }
}, },
"additionalProperties": false "additionalProperties": false
},
"demux": {
"description": "Demultiplexer definitions",
"title": "/log/demux",
"type": "object",
"patternProperties": {
"^([\\w\\-\\.]+)$": {
"description": "The definition of a demultiplexer",
"title": "/log/demux/<name>",
"type": "object",
"properties": {
"pattern": {
"title": "/log/demux/<name>/pattern",
"description": "A regular expression to match a line in a multiplexed file",
"type": "string"
}
},
"additionalProperties": false
}
},
"additionalProperties": false
} }
}, },
"additionalProperties": false "additionalProperties": false

@ -306,11 +306,42 @@ standard input. The handler should then generate the annotation
content on the standard output. The output is treated as Markdown, content on the standard output. The output is treated as Markdown,
so the content can be styled as desired. so the content can be styled as desired.
Demultiplexing (v0.12.3+)
^^^^^^^^^^^^^^^^^^^^^^^^^
Files that are a mix of content from different sources, like
the output of :code:`docker compose logs`, can be automatically
demultiplexed so that *lnav* can process them correctly. Each
line of the input file must have a unique identifier that can
be used to determine which service the line belongs to. The
lines are then distributed to separate files based on the
identifier. A demultiplexer is a regular expression that
extracts the identifier, the log message, and an optional
timestamp.
Demultiplexers are defined in the main configuration under
the :code:`/log/demux` path. The pattern for the demuxer
has the following known capture names:
:mux_id: (required) Captures the unique identifier.
:body: (required) Captures the body of the log message
that should be written to the file.
:timestamp: (optional) The timestamp for the log message.
If this is available and the log message does not have
it's own timestamp, this will be used instead.
If there are additional captures, they will be included
in the file metadata that can be accessed by the
:code:`lnav_file_metadata` table.
Reference Reference
^^^^^^^^^ ^^^^^^^^^
.. jsonschema:: ../schemas/config-v1.schema.json#/properties/log/properties/watch-expressions/patternProperties/^([\w\.\-]+)$ .. jsonschema:: ../schemas/config-v1.schema.json#/properties/log/properties/watch-expressions/patternProperties/^([\w\.\-]+)$
.. jsonschema:: ../schemas/config-v1.schema.json#/properties/log/properties/annotations/patternProperties/^([\w\.\-]+)$ .. jsonschema:: ../schemas/config-v1.schema.json#/properties/log/properties/annotations/patternProperties/^([\w\.\-]+)$
.. jsonschema:: ../schemas/config-v1.schema.json#/properties/log/properties/demux/patternProperties/^([\w\-\.]+)$
.. _tuning: .. _tuning:

@ -570,7 +570,6 @@ add_library(
logfile_stats.hh logfile_stats.hh
md2attr_line.hh md2attr_line.hh
md4cpp.hh md4cpp.hh
optional.hpp
file_converter_manager.hh file_converter_manager.hh
plain_text_source.hh plain_text_source.hh
pretty_printer.hh pretty_printer.hh

@ -302,7 +302,6 @@ noinst_HEADERS = \
mapbox/variant_visitor.hpp \ mapbox/variant_visitor.hpp \
md2attr_line.hh \ md2attr_line.hh \
md4cpp.hh \ md4cpp.hh \
optional.hpp \
piper.looper.hh \ piper.looper.hh \
piper.looper.cfg.hh \ piper.looper.cfg.hh \
plain_text_source.hh \ plain_text_source.hh \

@ -124,8 +124,8 @@ describe(const fs::path& filename)
archive_entry_strmode(entry), archive_entry_strmode(entry),
archive_entry_mtime(entry), archive_entry_mtime(entry),
archive_entry_size_is_set(entry) archive_entry_size_is_set(entry)
? nonstd::make_optional(archive_entry_size(entry)) ? std::make_optional(archive_entry_size(entry))
: nonstd::nullopt, : std::nullopt,
}); });
} while (archive_read_next_header(arc, &entry) == ARCHIVE_OK); } while (archive_read_next_header(arc, &entry) == ARCHIVE_OK);

@ -41,7 +41,6 @@
#include "base/result.h" #include "base/result.h"
#include "ghc/filesystem.hpp" #include "ghc/filesystem.hpp"
#include "mapbox/variant.hpp" #include "mapbox/variant.hpp"
#include "optional.hpp"
namespace archive_manager { namespace archive_manager {
@ -64,7 +63,7 @@ struct archive_info {
ghc::filesystem::path e_name; ghc::filesystem::path e_name;
const char* e_mode; const char* e_mode;
time_t e_mtime; time_t e_mtime;
nonstd::optional<file_ssize_t> e_size; std::optional<file_ssize_t> e_size;
}; };
const char* ai_format_name; const char* ai_format_name;
std::vector<entry> ai_entries; std::vector<entry> ai_entries;

@ -56,7 +56,7 @@ erase_ansi_escapes(string_fragment input)
static thread_local auto md = lnav::pcre2pp::match_data::unitialized(); static thread_local auto md = lnav::pcre2pp::match_data::unitialized();
const auto& regex = ansi_regex(); const auto& regex = ansi_regex();
nonstd::optional<int> move_start; std::optional<int> move_start;
size_t fill_index = 0; size_t fill_index = 0;
auto matcher = regex.capture_from(input).into(md); auto matcher = regex.capture_from(input).into(md);
@ -125,7 +125,7 @@ scrub_ansi_string(std::string& str, string_attrs_t* sa)
static const auto semi_pred = string_fragment::tag1{';'}; static const auto semi_pred = string_fragment::tag1{';'};
const auto& regex = ansi_regex(); const auto& regex = ansi_regex();
nonstd::optional<std::string> href; std::optional<std::string> href;
size_t href_start = 0; size_t href_start = 0;
string_attrs_t tmp_sa; string_attrs_t tmp_sa;
size_t cp_dst = std::string::npos; size_t cp_dst = std::string::npos;
@ -267,7 +267,7 @@ scrub_ansi_string(std::string& str, string_attrs_t* sa)
struct line_range lr; struct line_range lr;
text_attrs attrs; text_attrs attrs;
bool has_attrs = false; bool has_attrs = false;
nonstd::optional<role_t> role; std::optional<role_t> role;
if (md[3]) { if (md[3]) {
auto osc_id = scn::scan_value<int32_t>(md[3]->to_string_view()); auto osc_id = scn::scan_value<int32_t>(md[3]->to_string_view());
@ -289,7 +289,7 @@ scrub_ansi_string(std::string& str, string_attrs_t* sa)
}, },
VC_HYPERLINK.value(href.value())); VC_HYPERLINK.value(href.value()));
} }
href = nonstd::nullopt; href = std::nullopt;
} }
if (!uri.empty()) { if (!uri.empty()) {
href = uri.to_string(); href = uri.to_string();

@ -37,7 +37,7 @@ attr_line_builder::append_as_hexdump(const string_fragment& sf)
if (byte_off == 8) { if (byte_off == 8) {
this->append(" "); this->append(" ");
} }
nonstd::optional<role_t> ro; std::optional<role_t> ro;
if (ch == '\0') { if (ch == '\0') {
ro = role_t::VCR_NULL; ro = role_t::VCR_NULL;
} else if (isspace(ch) || iscntrl(ch)) { } else if (isspace(ch) || iscntrl(ch)) {

@ -41,7 +41,7 @@ public:
class attr_guard { class attr_guard {
public: public:
explicit attr_guard(attr_line_t& al) explicit attr_guard(attr_line_t& al)
: ag_line(al), ag_start(nonstd::nullopt) : ag_line(al), ag_start(std::nullopt)
{ {
} }
@ -59,7 +59,7 @@ public:
: ag_line(other.ag_line), ag_start(std::move(other.ag_start)), : ag_line(other.ag_line), ag_start(std::move(other.ag_start)),
ag_attr(std::move(other.ag_attr)) ag_attr(std::move(other.ag_attr))
{ {
other.ag_start = nonstd::nullopt; other.ag_start = std::nullopt;
} }
~attr_guard() ~attr_guard()
@ -76,7 +76,7 @@ public:
private: private:
attr_line_t& ag_line; attr_line_t& ag_line;
nonstd::optional<int> ag_start; std::optional<int> ag_start;
string_attr_pair ag_attr; string_attr_pair ag_attr;
}; };

@ -356,6 +356,19 @@ attr_line_t::insert(size_t index,
return *this; return *this;
} }
attr_line_t&
attr_line_t::wrap_with(text_wrap_settings* tws)
{
attr_line_t tmp;
tmp.al_string = std::move(this->al_string);
tmp.al_attrs = std::move(this->al_attrs);
this->append(tmp, tws);
return *this;
}
attr_line_t attr_line_t
attr_line_t::subline(size_t start, size_t len) const attr_line_t::subline(size_t start, size_t len) const
{ {
@ -457,7 +470,7 @@ attr_line_t::apply_hide()
} }
attr_line_t& attr_line_t&
attr_line_t::rtrim(nonstd::optional<const char*> chars) attr_line_t::rtrim(std::optional<const char*> chars)
{ {
auto index = this->al_string.length(); auto index = this->al_string.length();
@ -701,7 +714,7 @@ find_string_attr(const string_attrs_t& sa,
return iter; return iter;
} }
nonstd::optional<const string_attr*> std::optional<const string_attr*>
get_string_attr(const string_attrs_t& sa, get_string_attr(const string_attrs_t& sa,
const string_attr_type_base* type, const string_attr_type_base* type,
int start) int start)
@ -709,8 +722,8 @@ get_string_attr(const string_attrs_t& sa,
auto iter = find_string_attr(sa, type, start); auto iter = find_string_attr(sa, type, start);
if (iter == sa.end()) { if (iter == sa.end()) {
return nonstd::nullopt; return std::nullopt;
} }
return nonstd::make_optional(&(*iter)); return std::make_optional(&(*iter));
} }

@ -33,6 +33,7 @@
#define attr_line_hh #define attr_line_hh
#include <new> #include <new>
#include <optional>
#include <string> #include <string>
#include <vector> #include <vector>
@ -97,11 +98,11 @@ using string_attrs_t = std::vector<string_attr>;
string_attrs_t::const_iterator find_string_attr( string_attrs_t::const_iterator find_string_attr(
const string_attrs_t& sa, const string_attr_type_base* type, int start = 0); const string_attrs_t& sa, const string_attr_type_base* type, int start = 0);
nonstd::optional<const string_attr*> get_string_attr( std::optional<const string_attr*> get_string_attr(
const string_attrs_t& sa, const string_attr_type_base* type, int start = 0); const string_attrs_t& sa, const string_attr_type_base* type, int start = 0);
template<typename T> template<typename T>
inline nonstd::optional<string_attr_wrapper<T>> inline std::optional<string_attr_wrapper<T>>
get_string_attr(const string_attrs_t& sa, get_string_attr(const string_attrs_t& sa,
const string_attr_type<T>& type, const string_attr_type<T>& type,
int start = 0) int start = 0)
@ -109,10 +110,10 @@ get_string_attr(const string_attrs_t& sa,
auto iter = find_string_attr(sa, &type, start); auto iter = find_string_attr(sa, &type, start);
if (iter == sa.end()) { if (iter == sa.end()) {
return nonstd::nullopt; return std::nullopt;
} }
return nonstd::make_optional(string_attr_wrapper<T>(&(*iter))); return std::make_optional(string_attr_wrapper<T>(&(*iter)));
} }
template<typename T> template<typename T>
@ -482,7 +483,7 @@ public:
attr_line_t& erase(size_t pos, size_t len = std::string::npos); attr_line_t& erase(size_t pos, size_t len = std::string::npos);
attr_line_t& rtrim(nonstd::optional<const char*> chars = nonstd::nullopt); attr_line_t& rtrim(std::optional<const char*> chars = std::nullopt);
attr_line_t& erase_utf8_chars(size_t start) attr_line_t& erase_utf8_chars(size_t start)
{ {
@ -579,6 +580,8 @@ public:
size_t nearest_text(size_t x) const; size_t nearest_text(size_t x) const;
attr_line_t& wrap_with(text_wrap_settings* tws);
void apply_hide(); void apply_hide();
std::string al_string; std::string al_string;

@ -223,7 +223,7 @@ public:
this->ab_capacity = 0; this->ab_capacity = 0;
} }
auto_buffer& operator=(auto_buffer&) = delete; auto_buffer& operator=(const auto_buffer&) = delete;
auto_buffer& operator=(auto_buffer&& other) noexcept auto_buffer& operator=(auto_buffer&& other) noexcept
{ {

@ -195,7 +195,6 @@ date_time_scanner::scan(const char* time_dest,
{ {
const auto sec_diff = tm_out->et_tm.tm_sec - last_tm.tm_sec; const auto sec_diff = tm_out->et_tm.tm_sec - last_tm.tm_sec;
// log_debug("diff %d", sec_diff);
tv_out = this->dts_last_tv; tv_out = this->dts_last_tv;
tv_out.tv_sec += sec_diff; tv_out.tv_sec += sec_diff;
tm_out->et_tm.tm_wday = last_tm.tm_wday; tm_out->et_tm.tm_wday = last_tm.tm_wday;
@ -231,20 +230,43 @@ date_time_scanner::scan(const char* time_dest,
if (convert_local if (convert_local
&& (this->dts_local_time && (this->dts_local_time
|| tm_out->et_flags & ETF_EPOCH_TIME || tm_out->et_flags & ETF_EPOCH_TIME
|| (tm_out->et_flags & ETF_ZONE_SET || ((tm_out->et_flags & ETF_ZONE_SET
|| this->dts_default_zone != nullptr)
&& this->dts_zoned_to_local))) && this->dts_zoned_to_local)))
{ {
time_t gmt = tm_out->to_timeval().tv_sec; time_t gmt = tm_out->to_timeval().tv_sec;
if (!(tm_out->et_flags & ETF_ZONE_SET)
&& !(tm_out->et_flags & ETF_EPOCH_TIME)
&& this->dts_default_zone != nullptr)
{
date::local_seconds stime;
stime += std::chrono::seconds{gmt};
auto ztime
= date::make_zoned(this->dts_default_zone, stime);
gmt = std::chrono::duration_cast<std::chrono::seconds>(
ztime.get_sys_time().time_since_epoch())
.count();
}
this->to_localtime(gmt, *tm_out); this->to_localtime(gmt, *tm_out);
#ifdef HAVE_STRUCT_TM_TM_ZONE
tm_out->et_tm.tm_zone = nullptr;
#endif
tm_out->et_tm.tm_isdst = 0;
} }
const auto& last_tm = this->dts_last_tm.et_tm;
if (last_tm.tm_year == tm_out->et_tm.tm_year
&& last_tm.tm_mon == tm_out->et_tm.tm_mon
&& last_tm.tm_mday == tm_out->et_tm.tm_mday
&& last_tm.tm_hour == tm_out->et_tm.tm_hour
&& last_tm.tm_min == tm_out->et_tm.tm_min)
{
const auto sec_diff = tm_out->et_tm.tm_sec - last_tm.tm_sec;
tv_out = tm_out->to_timeval(); tv_out = this->dts_last_tv;
secs2wday(tv_out, &tm_out->et_tm); tv_out.tv_sec += sec_diff;
tm_out->et_tm.tm_wday = last_tm.tm_wday;
} else {
tv_out = tm_out->to_timeval();
secs2wday(tv_out, &tm_out->et_tm);
}
tv_out.tv_usec = tm_out->et_nsec / 1000;
this->dts_fmt_lock = curr_time_fmt; this->dts_fmt_lock = curr_time_fmt;
this->dts_fmt_len = retval - time_dest; this->dts_fmt_len = retval - time_dest;

@ -40,6 +40,36 @@
namespace lnav { namespace lnav {
namespace filesystem { namespace filesystem {
std::string
escape_path(const ghc::filesystem::path& p)
{
auto p_str = p.string();
std::string retval;
for (const auto ch : p_str) {
switch (ch) {
case ' ':
case '$':
case '\\':
case ';':
case '&':
case '<':
case '>':
case '\'':
case '"':
case '*':
case '[':
case ']':
case '?':
retval.push_back('\\');
break;
}
retval.push_back(ch);
}
return retval;
}
Result<ghc::filesystem::path, std::string> Result<ghc::filesystem::path, std::string>
realpath(const ghc::filesystem::path& path) realpath(const ghc::filesystem::path& path)
{ {

@ -30,6 +30,7 @@
#ifndef lnav_fs_util_hh #ifndef lnav_fs_util_hh
#define lnav_fs_util_hh #define lnav_fs_util_hh
#include <optional>
#include <set> #include <set>
#include <string> #include <string>
#include <vector> #include <vector>
@ -50,6 +51,8 @@ is_glob(const std::string& fn)
|| fn.find('[') != std::string::npos); || fn.find('[') != std::string::npos);
} }
std::string escape_path(const ghc::filesystem::path& p);
inline int inline int
statp(const ghc::filesystem::path& path, struct stat* buf) statp(const ghc::filesystem::path& path, struct stat* buf)
{ {
@ -90,7 +93,7 @@ enum class write_file_options {
}; };
struct write_file_result { struct write_file_result {
nonstd::optional<ghc::filesystem::path> wfr_backup_path; std::optional<ghc::filesystem::path> wfr_backup_path;
}; };
Result<write_file_result, std::string> write_file( Result<write_file_result, std::string> write_file(
@ -144,8 +147,8 @@ public:
namespace fmt { namespace fmt {
template<> template<>
struct formatter<ghc::filesystem::path> : formatter<string_view> { struct formatter<ghc::filesystem::path> : formatter<string_view> {
auto format(const ghc::filesystem::path& p, format_context& ctx) auto format(const ghc::filesystem::path& p,
-> decltype(ctx.out()) const; format_context& ctx) -> decltype(ctx.out()) const;
}; };
} // namespace fmt } // namespace fmt

@ -77,7 +77,7 @@ file_size(file_ssize_t value, alignment align)
} }
const std::string& const std::string&
sparkline(double value, nonstd::optional<double> upper_opt) sparkline(double value, std::optional<double> upper_opt)
{ {
static const std::string ZERO = " "; static const std::string ZERO = " ";
static const std::string BARS[] = { static const std::string BARS[] = {

@ -51,7 +51,7 @@ enum class alignment {
*/ */
std::string file_size(file_ssize_t value, alignment align); std::string file_size(file_ssize_t value, alignment align);
const std::string& sparkline(double value, nonstd::optional<double> upper); const std::string& sparkline(double value, std::optional<double> upper);
} // namespace humanize } // namespace humanize

@ -30,13 +30,14 @@
#include "humanize.network.hh" #include "humanize.network.hh"
#include "config.h" #include "config.h"
#include "itertools.hh"
#include "pcrepp/pcre2pp.hh" #include "pcrepp/pcre2pp.hh"
namespace humanize { namespace humanize {
namespace network { namespace network {
namespace path { namespace path {
nonstd::optional<::network::path> std::optional<::network::path>
from_str(string_fragment sf) from_str(string_fragment sf)
{ {
static const auto REMOTE_PATTERN = lnav::pcre2pp::code::from_const( static const auto REMOTE_PATTERN = lnav::pcre2pp::code::from_const(
@ -52,11 +53,11 @@ from_str(string_fragment sf)
.ignore_error(); .ignore_error();
if (!match_res) { if (!match_res) {
return nonstd::nullopt; return std::nullopt;
} }
const auto username = REMOTE_MATCH_DATA["username"].map( const auto username = REMOTE_MATCH_DATA["username"]
[](auto sf) { return sf.to_string(); }); | lnav::itertools::map([](auto sf) { return sf.to_string(); });
const auto ipv6 = REMOTE_MATCH_DATA["ipv6"]; const auto ipv6 = REMOTE_MATCH_DATA["ipv6"];
const auto hostname = REMOTE_MATCH_DATA["hostname"]; const auto hostname = REMOTE_MATCH_DATA["hostname"];
const auto locality_hostname = ipv6 ? ipv6.value() : hostname.value(); const auto locality_hostname = ipv6 ? ipv6.value() : hostname.value();
@ -66,7 +67,7 @@ from_str(string_fragment sf)
path = string_fragment::from_const("."); path = string_fragment::from_const(".");
} }
return ::network::path{ return ::network::path{
{username, locality_hostname.to_string(), nonstd::nullopt}, {username, locality_hostname.to_string(), std::nullopt},
path.to_string(), path.to_string(),
}; };
} }

@ -35,7 +35,6 @@
#include "fmt/format.h" #include "fmt/format.h"
#include "intern_string.hh" #include "intern_string.hh"
#include "network.tcp.hh" #include "network.tcp.hh"
#include "optional.hpp"
namespace fmt { namespace fmt {
@ -100,7 +99,7 @@ namespace humanize {
namespace network { namespace network {
namespace path { namespace path {
nonstd::optional<::network::path> from_str(string_fragment sf); std::optional<::network::path> from_str(string_fragment sf);
} // namespace path } // namespace path
} // namespace network } // namespace network

@ -30,12 +30,11 @@
#ifndef lnav_humanize_time_hh #ifndef lnav_humanize_time_hh
#define lnav_humanize_time_hh #define lnav_humanize_time_hh
#include <optional>
#include <string> #include <string>
#include <sys/time.h> #include <sys/time.h>
#include "optional.hpp"
namespace humanize { namespace humanize {
namespace time { namespace time {
@ -66,7 +65,7 @@ private:
} }
struct timeval p_past_point; struct timeval p_past_point;
nonstd::optional<struct timeval> p_recent_point; std::optional<struct timeval> p_recent_point;
bool p_convert_to_local{false}; bool p_convert_to_local{false};
}; };

@ -32,6 +32,7 @@
#ifndef lnav_injector_hh #ifndef lnav_injector_hh
#define lnav_injector_hh #define lnav_injector_hh
#include <functional>
#include <map> #include <map>
#include <memory> #include <memory>
#include <type_traits> #include <type_traits>

@ -179,11 +179,11 @@ string_fragment::trim() const
return this->trim(" \t\r\n"); return this->trim(" \t\r\n");
} }
nonstd::optional<string_fragment> std::optional<string_fragment>
string_fragment::consume_n(int amount) const string_fragment::consume_n(int amount) const
{ {
if (amount > this->length()) { if (amount > this->length()) {
return nonstd::nullopt; return std::nullopt;
} }
return string_fragment{ return string_fragment{
@ -197,7 +197,7 @@ string_fragment::split_result
string_fragment::split_n(int amount) const string_fragment::split_n(int amount) const
{ {
if (amount > this->length()) { if (amount > this->length()) {
return nonstd::nullopt; return std::nullopt;
} }
return std::make_pair( return std::make_pair(
@ -391,8 +391,8 @@ string_fragment
string_fragment::sub_cell_range(int cell_start, int cell_end) const string_fragment::sub_cell_range(int cell_start, int cell_end) const
{ {
int byte_index = this->sf_begin; int byte_index = this->sf_begin;
nonstd::optional<int> byte_start; std::optional<int> byte_start;
nonstd::optional<int> byte_end; std::optional<int> byte_end;
int cell_index = 0; int cell_index = 0;
while (byte_index < this->sf_end) { while (byte_index < this->sf_end) {

@ -32,6 +32,7 @@
#ifndef intern_string_hh #ifndef intern_string_hh
#define intern_string_hh #define intern_string_hh
#include <optional>
#include <ostream> #include <ostream>
#include <vector> #include <vector>
@ -40,7 +41,6 @@
#include <sys/types.h> #include <sys/types.h>
#include "fmt/format.h" #include "fmt/format.h"
#include "optional.hpp"
#include "result.h" #include "result.h"
#include "scn/util/string_view.h" #include "scn/util/string_view.h"
#include "strnatcmp.h" #include "strnatcmp.h"
@ -302,7 +302,7 @@ struct string_fragment {
return retval; return retval;
} }
nonstd::optional<size_t> find(char ch) const std::optional<size_t> find(char ch) const
{ {
for (int lpc = this->sf_begin; lpc < this->sf_end; lpc++) { for (int lpc = this->sf_begin; lpc < this->sf_end; lpc++) {
if (this->sf_string[lpc] == ch) { if (this->sf_string[lpc] == ch) {
@ -310,7 +310,7 @@ struct string_fragment {
} }
} }
return nonstd::nullopt; return std::nullopt;
} }
template<typename P> template<typename P>
@ -374,21 +374,21 @@ struct string_fragment {
start - left.sf_begin, predicate, count); start - left.sf_begin, predicate, count);
} }
nonstd::optional<std::pair<uint32_t, string_fragment>> consume_codepoint() std::optional<std::pair<uint32_t, string_fragment>> consume_codepoint()
const const
{ {
auto cp = this->front_codepoint(); auto cp = this->front_codepoint();
auto index_res = this->codepoint_to_byte_index(1); auto index_res = this->codepoint_to_byte_index(1);
if (index_res.isErr()) { if (index_res.isErr()) {
return nonstd::nullopt; return std::nullopt;
} }
return std::make_pair(cp, this->substr(index_res.unwrap())); return std::make_pair(cp, this->substr(index_res.unwrap()));
} }
template<typename P> template<typename P>
nonstd::optional<string_fragment> consume(P predicate) const std::optional<string_fragment> consume(P predicate) const
{ {
int consumed = 0; int consumed = 0;
while (consumed < this->length()) { while (consumed < this->length()) {
@ -400,7 +400,7 @@ struct string_fragment {
} }
if (consumed == 0) { if (consumed == 0) {
return nonstd::nullopt; return std::nullopt;
} }
return string_fragment{ return string_fragment{
@ -410,7 +410,7 @@ struct string_fragment {
}; };
} }
nonstd::optional<string_fragment> consume_n(int amount) const; std::optional<string_fragment> consume_n(int amount) const;
template<typename P> template<typename P>
string_fragment skip(P predicate) const string_fragment skip(P predicate) const
@ -428,7 +428,7 @@ struct string_fragment {
} }
using split_result using split_result
= nonstd::optional<std::pair<string_fragment, string_fragment>>; = std::optional<std::pair<string_fragment, string_fragment>>;
template<typename P> template<typename P>
split_result split_while(P&& predicate) const split_result split_while(P&& predicate) const
@ -443,7 +443,7 @@ struct string_fragment {
} }
if (consumed == 0) { if (consumed == 0) {
return nonstd::nullopt; return std::nullopt;
} }
return std::make_pair( return std::make_pair(
@ -500,7 +500,7 @@ struct string_fragment {
} }
if (consumed == this->length()) { if (consumed == this->length()) {
return nonstd::nullopt; return std::nullopt;
} }
return std::make_pair( return std::make_pair(

@ -60,7 +60,7 @@
error. error.
*/ */
utf8_scan_result utf8_scan_result
is_utf8(string_fragment str, nonstd::optional<unsigned char> terminator) is_utf8(string_fragment str, std::optional<unsigned char> terminator)
{ {
const auto* ustr = str.udata(); const auto* ustr = str.udata();
utf8_scan_result retval; utf8_scan_result retval;

@ -32,13 +32,12 @@
#include <sys/types.h> #include <sys/types.h>
#include "intern_string.hh" #include "intern_string.hh"
#include "optional.hpp"
struct utf8_scan_result { struct utf8_scan_result {
const char* usr_message{nullptr}; const char* usr_message{nullptr};
size_t usr_faulty_bytes{0}; size_t usr_faulty_bytes{0};
string_fragment usr_valid_frag{string_fragment::invalid()}; string_fragment usr_valid_frag{string_fragment::invalid()};
nonstd::optional<string_fragment> usr_remaining; std::optional<string_fragment> usr_remaining;
bool usr_has_ansi{false}; bool usr_has_ansi{false};
size_t usr_column_width_guess{0}; size_t usr_column_width_guess{0};
@ -54,7 +53,7 @@ struct utf8_scan_result {
}; };
utf8_scan_result is_utf8(string_fragment frag, utf8_scan_result is_utf8(string_fragment frag,
nonstd::optional<unsigned char> terminator std::optional<unsigned char> terminator
= nonstd::nullopt); = std::nullopt);
#endif /* _IS_UTF8_H */ #endif /* _IS_UTF8_H */

@ -34,12 +34,12 @@
#include <deque> #include <deque>
#include <map> #include <map>
#include <memory> #include <memory>
#include <optional>
#include <set> #include <set>
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
#include "func_util.hh" #include "func_util.hh"
#include "optional.hpp"
namespace lnav { namespace lnav {
namespace itertools { namespace itertools {
@ -122,7 +122,7 @@ struct append {
}; };
struct nth { struct nth {
nonstd::optional<size_t> a_index; std::optional<size_t> a_index;
}; };
struct skip { struct skip {
@ -190,7 +190,7 @@ second()
} }
inline details::nth inline details::nth
nth(nonstd::optional<size_t> index) nth(std::optional<size_t> index)
{ {
return details::nth{ return details::nth{
index, index,
@ -340,7 +340,7 @@ sum()
} // namespace lnav } // namespace lnav
template<typename C, typename P> template<typename C, typename P>
nonstd::optional<std::conditional_t< std::optional<std::conditional_t<
std::is_const<typename std::remove_reference_t<C>>::value, std::is_const<typename std::remove_reference_t<C>>::value,
typename std::remove_reference_t<C>::const_iterator, typename std::remove_reference_t<C>::const_iterator,
typename std::remove_reference_t<C>::iterator>> typename std::remove_reference_t<C>::iterator>>
@ -348,44 +348,44 @@ operator|(C&& in, const lnav::itertools::details::find_if<P>& finder)
{ {
for (auto iter = in.begin(); iter != in.end(); ++iter) { for (auto iter = in.begin(); iter != in.end(); ++iter) {
if (lnav::func::invoke(finder.fi_predicate, *iter)) { if (lnav::func::invoke(finder.fi_predicate, *iter)) {
return nonstd::make_optional(iter); return std::make_optional(iter);
} }
} }
return nonstd::nullopt; return std::nullopt;
} }
template<typename C, typename T> template<typename C, typename T>
nonstd::optional<size_t> std::optional<size_t>
operator|(const C& in, const lnav::itertools::details::find<T>& finder) operator|(const C& in, const lnav::itertools::details::find<T>& finder)
{ {
size_t retval = 0; size_t retval = 0;
for (const auto& elem : in) { for (const auto& elem : in) {
if (elem == finder.f_value) { if (elem == finder.f_value) {
return nonstd::make_optional(retval); return std::make_optional(retval);
} }
retval += 1; retval += 1;
} }
return nonstd::nullopt; return std::nullopt;
} }
template<typename C> template<typename C>
nonstd::optional<typename C::const_iterator> std::optional<typename C::const_iterator>
operator|(const C& in, const lnav::itertools::details::nth indexer) operator|(const C& in, const lnav::itertools::details::nth indexer)
{ {
if (!indexer.a_index.has_value()) { if (!indexer.a_index.has_value()) {
return nonstd::nullopt; return std::nullopt;
} }
if (indexer.a_index.value() < in.size()) { if (indexer.a_index.value() < in.size()) {
auto iter = in.begin(); auto iter = in.begin();
std::advance(iter, indexer.a_index.value()); std::advance(iter, indexer.a_index.value());
return nonstd::make_optional(iter); return std::make_optional(iter);
} }
return nonstd::nullopt; return std::nullopt;
} }
template<typename C> template<typename C>
@ -402,10 +402,10 @@ operator|(const C& in, const lnav::itertools::details::first indexer)
} }
template<typename C> template<typename C>
nonstd::optional<typename C::value_type> std::optional<typename C::value_type>
operator|(const C& in, const lnav::itertools::details::max_value maxer) operator|(const C& in, const lnav::itertools::details::max_value maxer)
{ {
nonstd::optional<typename C::value_type> retval; std::optional<typename C::value_type> retval;
for (const auto& elem : in) { for (const auto& elem : in) {
if (!retval) { if (!retval) {
@ -572,13 +572,13 @@ template<typename T,
typename F, typename F,
std::enable_if_t<lnav::func::is_invocable<F, T>::value, int> = 0> std::enable_if_t<lnav::func::is_invocable<F, T>::value, int> = 0>
auto auto
operator|(nonstd::optional<T> in, operator|(std::optional<T> in,
const lnav::itertools::details::flat_mapper<F>& mapper) -> const lnav::itertools::details::flat_mapper<F>& mapper) ->
typename std::remove_const_t<typename std::remove_reference_t< typename std::remove_const_t<typename std::remove_reference_t<
decltype(lnav::func::invoke(mapper.fm_func, in.value()))>> decltype(lnav::func::invoke(mapper.fm_func, in.value()))>>
{ {
if (!in) { if (!in) {
return nonstd::nullopt; return std::nullopt;
} }
return lnav::func::invoke(mapper.fm_func, in.value()); return lnav::func::invoke(mapper.fm_func, in.value());
@ -588,7 +588,7 @@ template<typename T,
typename F, typename F,
std::enable_if_t<lnav::func::is_invocable<F, T>::value, int> = 0> std::enable_if_t<lnav::func::is_invocable<F, T>::value, int> = 0>
void void
operator|(nonstd::optional<T> in, operator|(std::optional<T> in,
const lnav::itertools::details::for_eacher<F>& eacher) const lnav::itertools::details::for_eacher<F>& eacher)
{ {
if (!in) { if (!in) {
@ -614,17 +614,17 @@ template<typename T,
typename F, typename F,
std::enable_if_t<lnav::func::is_invocable<F, T>::value, int> = 0> std::enable_if_t<lnav::func::is_invocable<F, T>::value, int> = 0>
auto auto
operator|(nonstd::optional<T> in, operator|(std::optional<T> in,
const lnav::itertools::details::mapper<F>& mapper) const lnav::itertools::details::mapper<F>& mapper)
-> nonstd::optional< -> std::optional<
typename std::remove_const_t<typename std::remove_reference_t< typename std::remove_const_t<typename std::remove_reference_t<
decltype(lnav::func::invoke(mapper.m_func, in.value()))>>> decltype(lnav::func::invoke(mapper.m_func, in.value()))>>>
{ {
if (!in) { if (!in) {
return nonstd::nullopt; return std::nullopt;
} }
return nonstd::make_optional(lnav::func::invoke(mapper.m_func, in.value())); return std::make_optional(lnav::func::invoke(mapper.m_func, in.value()));
} }
template<typename T, typename F> template<typename T, typename F>
@ -813,38 +813,38 @@ template<typename T,
typename F, typename F,
std::enable_if_t<!lnav::func::is_invocable<F, T>::value, int> = 0> std::enable_if_t<!lnav::func::is_invocable<F, T>::value, int> = 0>
auto auto
operator|(nonstd::optional<T> in, operator|(std::optional<T> in,
const lnav::itertools::details::mapper<F>& mapper) const lnav::itertools::details::mapper<F>& mapper)
-> nonstd::optional<typename std::remove_reference_t< -> std::optional<typename std::remove_reference_t<
typename std::remove_const_t<decltype(((in.value()).*mapper.m_func))>>> typename std::remove_const_t<decltype(((in.value()).*mapper.m_func))>>>
{ {
if (!in) { if (!in) {
return nonstd::nullopt; return std::nullopt;
} }
return nonstd::make_optional((in.value()).*mapper.m_func); return std::make_optional((in.value()).*mapper.m_func);
} }
template<typename T, template<typename T,
typename F, typename F,
std::enable_if_t<!lnav::func::is_invocable<F, T>::value, int> = 0> std::enable_if_t<!lnav::func::is_invocable<F, T>::value, int> = 0>
auto auto
operator|(nonstd::optional<T> in, operator|(std::optional<T> in,
const lnav::itertools::details::mapper<F>& mapper) const lnav::itertools::details::mapper<F>& mapper)
-> nonstd::optional< -> std::optional<
typename std::remove_const_t<typename std::remove_reference_t< typename std::remove_const_t<typename std::remove_reference_t<
decltype(((*in.value()).*mapper.m_func))>>> decltype(((*in.value()).*mapper.m_func))>>>
{ {
if (!in) { if (!in) {
return nonstd::nullopt; return std::nullopt;
} }
return nonstd::make_optional((*in.value()).*mapper.m_func); return std::make_optional((*in.value()).*mapper.m_func);
} }
template<typename T> template<typename T>
T T
operator|(nonstd::optional<T> in, operator|(std::optional<T> in,
const lnav::itertools::details::unwrap_or<T>& unwrapper) const lnav::itertools::details::unwrap_or<T>& unwrapper)
{ {
return in.value_or(unwrapper.uo_value); return in.value_or(unwrapper.uo_value);

@ -252,7 +252,7 @@ user_message::to_attr_line(std::set<render_flags> flags) const
return retval; return retval;
} }
static nonstd::optional<fmt::terminal_color> static std::optional<fmt::terminal_color>
curses_color_to_terminal_color(int curses_color) curses_color_to_terminal_color(int curses_color)
{ {
switch (curses_color) { switch (curses_color) {
@ -273,7 +273,7 @@ curses_color_to_terminal_color(int curses_color)
case COLOR_RED: case COLOR_RED:
return fmt::terminal_color::red; return fmt::terminal_color::red;
default: default:
return nonstd::nullopt; return std::nullopt;
} }
} }
@ -326,7 +326,7 @@ println(FILE* file, const attr_line_t& al)
} }
} }
nonstd::optional<size_t> last_point; std::optional<size_t> last_point;
for (const auto& point : points) { for (const auto& point : points) {
if (!last_point) { if (!last_point) {
last_point = point; last_point = point;
@ -337,7 +337,7 @@ println(FILE* file, const attr_line_t& al)
auto line_style = fmt::text_style{}; auto line_style = fmt::text_style{};
auto fg_style = fmt::text_style{}; auto fg_style = fmt::text_style{};
auto start = last_point.value(); auto start = last_point.value();
nonstd::optional<std::string> href; std::optional<std::string> href;
for (const auto& attr : al.get_attrs()) { for (const auto& attr : al.get_attrs()) {
if (!attr.sa_range.contains(start) if (!attr.sa_range.contains(start)

@ -103,10 +103,10 @@ static const char* CRASH_MSG
" %s\n" " %s\n"
"=========================\n"; "=========================\n";
nonstd::optional<FILE*> lnav_log_file; std::optional<FILE*> lnav_log_file;
lnav_log_level_t lnav_log_level = lnav_log_level_t::DEBUG; lnav_log_level_t lnav_log_level = lnav_log_level_t::DEBUG;
const char* lnav_log_crash_dir; const char* lnav_log_crash_dir;
nonstd::optional<const struct termios*> lnav_log_orig_termios; std::optional<const struct termios*> lnav_log_orig_termios;
// NOTE: This mutex is leaked so that it is not destroyed during exit. // NOTE: This mutex is leaked so that it is not destroyed during exit.
// Otherwise, any attempts to log will fail. // Otherwise, any attempts to log will fail.
static std::mutex* static std::mutex*

@ -33,6 +33,7 @@
#define lnav_log_hh #define lnav_log_hh
#include <cstdint> #include <cstdint>
#include <optional>
#include <string> #include <string>
#include <stdio.h> #include <stdio.h>
@ -43,8 +44,6 @@
# define lnav_dead2 __attribute__((noreturn)) # define lnav_dead2 __attribute__((noreturn))
#endif #endif
#include "optional.hpp"
struct termios; struct termios;
enum class lnav_log_level_t : uint32_t { enum class lnav_log_level_t : uint32_t {
@ -80,7 +79,7 @@ public:
virtual ~log_state_dumper(); virtual ~log_state_dumper();
virtual void log_state(){ virtual void log_state() {
}; };
@ -97,9 +96,9 @@ public:
virtual void log_crash_recover() = 0; virtual void log_crash_recover() = 0;
}; };
extern nonstd::optional<FILE*> lnav_log_file; extern std::optional<FILE*> lnav_log_file;
extern const char* lnav_log_crash_dir; extern const char* lnav_log_crash_dir;
extern nonstd::optional<const struct termios*> lnav_log_orig_termios; extern std::optional<const struct termios*> lnav_log_orig_termios;
extern enum lnav_log_level_t lnav_log_level; extern enum lnav_log_level_t lnav_log_level;
#define log_msg_wrapper(level, fmt...) \ #define log_msg_wrapper(level, fmt...) \
@ -146,15 +145,17 @@ extern enum lnav_log_level_t lnav_log_level;
((void) ((lhs >= rhs) \ ((void) ((lhs >= rhs) \
? 0 \ ? 0 \
: lnav_require_binary( \ : lnav_require_binary( \
#lhs " >= " #rhs, lhs, rhs, __FILE__, __LINE__))) #lhs " >= " #rhs, lhs, rhs, __FILE__, __LINE__)))
#define require_gt(lhs, rhs) \ #define require_gt(lhs, rhs) \
((void) ((lhs > rhs) ? 0 \ ((void) ((lhs > rhs) \
: lnav_require_binary( \ ? 0 \
#lhs " > " #rhs, lhs, rhs, __FILE__, __LINE__))) : lnav_require_binary( \
#lhs " > " #rhs, lhs, rhs, __FILE__, __LINE__)))
#define require_lt(lhs, rhs) \ #define require_lt(lhs, rhs) \
((void) ((lhs < rhs) ? 0 \ ((void) ((lhs < rhs) \
: lnav_require_binary( \ ? 0 \
#lhs " < " #rhs, lhs, rhs, __FILE__, __LINE__))) : lnav_require_binary( \
#lhs " < " #rhs, lhs, rhs, __FILE__, __LINE__)))
#define lnav_require_binary(e, lhs, rhs, file, line) \ #define lnav_require_binary(e, lhs, rhs, file, line) \
(log_msg(lnav_log_level_t::ERROR, \ (log_msg(lnav_log_level_t::ERROR, \

@ -1,4 +1,4 @@
/* /*
* File: lrucache.hpp * File: lrucache.hpp
* Author: Alexander Ponomarev * Author: Alexander Ponomarev
* *
@ -6,78 +6,75 @@
*/ */
#ifndef _LRUCACHE_HPP_INCLUDED_ #ifndef _LRUCACHE_HPP_INCLUDED_
#define _LRUCACHE_HPP_INCLUDED_ #define _LRUCACHE_HPP_INCLUDED_
#include <map>
#include <list>
#include <cstddef> #include <cstddef>
#include <list>
#include <map>
#include <optional>
#include <stdexcept> #include <stdexcept>
#include "optional.hpp"
namespace cache { namespace cache {
template<typename key_t, typename value_t> template<typename key_t, typename value_t>
class lru_cache { class lru_cache {
public: public:
typedef typename std::pair<key_t, value_t> key_value_pair_t; typedef typename std::pair<key_t, value_t> key_value_pair_t;
typedef typename std::list<key_value_pair_t>::iterator list_iterator_t; typedef typename std::list<key_value_pair_t>::iterator list_iterator_t;
lru_cache(size_t max_size) : lru_cache(size_t max_size) : _max_size(max_size) {}
_max_size(max_size) {
} void put(const key_t& key, const value_t& value)
{
void put(const key_t& key, const value_t& value) { auto it = _cache_items_map.find(key);
auto it = _cache_items_map.find(key); _cache_items_list.push_front(key_value_pair_t(key, value));
_cache_items_list.push_front(key_value_pair_t(key, value)); if (it != _cache_items_map.end()) {
if (it != _cache_items_map.end()) { _cache_items_list.erase(it->second);
_cache_items_list.erase(it->second); _cache_items_map.erase(it);
_cache_items_map.erase(it); }
} _cache_items_map[key] = _cache_items_list.begin();
_cache_items_map[key] = _cache_items_list.begin();
if (_cache_items_map.size() > _max_size) {
if (_cache_items_map.size() > _max_size) { auto last = _cache_items_list.end();
auto last = _cache_items_list.end(); last--;
last--; _cache_items_map.erase(last->first);
_cache_items_map.erase(last->first); _cache_items_list.pop_back();
_cache_items_list.pop_back(); }
} }
}
std::optional<value_t> get(const key_t& key)
nonstd::optional<value_t> get(const key_t& key) { {
auto it = _cache_items_map.find(key); auto it = _cache_items_map.find(key);
if (it == _cache_items_map.end()) { if (it == _cache_items_map.end()) {
return nonstd::nullopt; return std::nullopt;
} }
_cache_items_list.splice(_cache_items_list.begin(), _cache_items_list, it->second); _cache_items_list.splice(
_cache_items_list.begin(), _cache_items_list, it->second);
return it->second->second; return it->second->second;
} }
bool exists(const key_t& key) const { bool exists(const key_t& key) const
return _cache_items_map.find(key) != _cache_items_map.end(); {
} return _cache_items_map.find(key) != _cache_items_map.end();
}
size_t size() const {
return _cache_items_map.size(); size_t size() const { return _cache_items_map.size(); }
}
void set_max_size(size_t max_size) { this->_max_size = max_size; }
void set_max_size(size_t max_size) {
this->_max_size = max_size; void clear()
} {
this->_cache_items_map.clear();
void clear() { this->_cache_items_list.clear();
this->_cache_items_map.clear(); }
this->_cache_items_list.clear();
}
private: private:
std::list<key_value_pair_t> _cache_items_list; std::list<key_value_pair_t> _cache_items_list;
std::map<key_t, list_iterator_t> _cache_items_map; std::map<key_t, list_iterator_t> _cache_items_map;
size_t _max_size; size_t _max_size;
}; };
} // namespace cache } // namespace cache
#endif /* _LRUCACHE_HPP_INCLUDED_ */
#endif /* _LRUCACHE_HPP_INCLUDED_ */

@ -32,16 +32,15 @@
#include <functional> #include <functional>
#include <map> #include <map>
#include <optional>
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
#include "optional.hpp"
namespace lnav { namespace lnav {
namespace map { namespace map {
template<typename C> template<typename C>
nonstd::optional< std::optional<
std::reference_wrapper<std::conditional_t<std::is_const<C>::value, std::reference_wrapper<std::conditional_t<std::is_const<C>::value,
const typename C::mapped_type, const typename C::mapped_type,
typename C::mapped_type>>> typename C::mapped_type>>>
@ -49,10 +48,10 @@ find(C& container, const typename C::key_type& key)
{ {
auto iter = container.find(key); auto iter = container.find(key);
if (iter != container.end()) { if (iter != container.end()) {
return nonstd::make_optional(std::ref(iter->second)); return std::make_optional(std::ref(iter->second));
} }
return nonstd::nullopt; return std::nullopt;
} }
template<typename K, typename V, typename M = std::map<K, V>> template<typename K, typename V, typename M = std::map<K, V>>

@ -33,23 +33,22 @@
#include <string> #include <string>
#include "auto_fd.hh" #include "auto_fd.hh"
#include "optional.hpp"
#include "result.h" #include "result.h"
namespace network { namespace network {
struct locality { struct locality {
locality(nonstd::optional<std::string> username, locality(std::optional<std::string> username,
std::string hostname, std::string hostname,
nonstd::optional<std::string> service) std::optional<std::string> service)
: l_username(std::move(username)), l_hostname(std::move(hostname)), : l_username(std::move(username)), l_hostname(std::move(hostname)),
l_service(std::move(service)) l_service(std::move(service))
{ {
} }
nonstd::optional<std::string> l_username; std::optional<std::string> l_username;
std::string l_hostname; std::string l_hostname;
nonstd::optional<std::string> l_service; std::optional<std::string> l_service;
}; };
struct path { struct path {

@ -30,9 +30,9 @@
#ifndef lnav_opt_util_hh #ifndef lnav_opt_util_hh
#define lnav_opt_util_hh #define lnav_opt_util_hh
#include <stdlib.h> #include <optional>
#include "optional.hpp" #include <stdlib.h>
namespace detail { namespace detail {
@ -47,25 +47,22 @@ template<class T>
typename std::enable_if<not std::is_void<T>::value, T>::type typename std::enable_if<not std::is_void<T>::value, T>::type
void_or_nullopt() void_or_nullopt()
{ {
return nonstd::nullopt; return std::nullopt;
} }
template<class T> template<class T>
struct is_optional : std::false_type { struct is_optional : std::false_type {};
};
template<class T> template<class T>
struct is_optional<nonstd::optional<T>> : std::true_type { struct is_optional<std::optional<T>> : std::true_type {};
};
} // namespace detail } // namespace detail
template<class T, template<class T,
class F, class F,
std::enable_if_t<detail::is_optional<std::decay_t<T>>::value, int> = 0> std::enable_if_t<detail::is_optional<std::decay_t<T>>::value, int> = 0>
auto auto
operator|(T&& t, F f) operator|(T&& t, F f) -> decltype(detail::void_or_nullopt<decltype(f(
-> decltype(detail::void_or_nullopt<decltype(f(std::forward<T>(t). std::forward<T>(t).operator*()))>())
operator*()))>())
{ {
using return_type = decltype(f(std::forward<T>(t).operator*())); using return_type = decltype(f(std::forward<T>(t).operator*()));
if (t) if (t)
@ -75,28 +72,27 @@ operator|(T&& t, F f)
} }
template<class T> template<class T>
optional_constexpr nonstd::optional<typename std::decay<T>::type> constexpr std::optional<typename std::decay<T>::type>
make_optional_from_nullable(T&& v) make_optional_from_nullable(T&& v)
{ {
if (v != nullptr) { if (v != nullptr) {
return nonstd::optional<typename std::decay<T>::type>( return std::optional<typename std::decay<T>::type>(std::forward<T>(v));
std::forward<T>(v));
} }
return nonstd::nullopt; return std::nullopt;
} }
template<template<typename, typename...> class C, typename T> template<template<typename, typename...> class C, typename T>
nonstd::optional<T> std::optional<T>
cget(const C<T>& container, size_t index) cget(const C<T>& container, size_t index)
{ {
if (index < container.size()) { if (index < container.size()) {
return container[index]; return container[index];
} }
return nonstd::nullopt; return std::nullopt;
} }
inline nonstd::optional<const char*> inline std::optional<const char*>
getenv_opt(const char* name) getenv_opt(const char* name)
{ {
return make_optional_from_nullable(getenv(name)); return make_optional_from_nullable(getenv(name));

@ -32,8 +32,10 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include <unistd.h> #include <unistd.h>
#include "base/injector.hh"
#include "base/lnav_log.hh" #include "base/lnav_log.hh"
#include "base/paths.hh" #include "base/paths.hh"
#include "piper.looper.cfg.hh"
namespace lnav { namespace lnav {
namespace piper { namespace piper {
@ -48,7 +50,7 @@ storage_path()
return INSTANCE; return INSTANCE;
} }
nonstd::optional<auto_buffer> std::optional<auto_buffer>
read_header(int fd, const char* first8) read_header(int fd, const char* first8)
{ {
if (memcmp(first8, HEADER_MAGIC, sizeof(HEADER_MAGIC)) != 0) { if (memcmp(first8, HEADER_MAGIC, sizeof(HEADER_MAGIC)) != 0) {
@ -57,7 +59,7 @@ read_header(int fd, const char* first8)
first8[1], first8[1],
first8[2], first8[2],
first8[3]); first8[3]);
return nonstd::nullopt; return std::nullopt;
} }
uint32_t meta_size = ntohl(*((uint32_t*) &first8[4])); uint32_t meta_size = ntohl(*((uint32_t*) &first8[4]));
@ -65,17 +67,54 @@ read_header(int fd, const char* first8)
auto meta_buf = auto_buffer::alloc(meta_size); auto meta_buf = auto_buffer::alloc(meta_size);
if (meta_buf.in() == nullptr) { if (meta_buf.in() == nullptr) {
log_error("failed to alloc %d bytes for header", meta_size); log_error("failed to alloc %d bytes for header", meta_size);
return nonstd::nullopt; return std::nullopt;
} }
auto meta_prc = pread(fd, meta_buf.in(), meta_size, 8); auto meta_prc = pread(fd, meta_buf.in(), meta_size, 8);
if (meta_prc != meta_size) { if (meta_prc != meta_size) {
log_error("failed to read piper header: %s", strerror(errno)); log_error("failed to read piper header: %s", strerror(errno));
return nonstd::nullopt; return std::nullopt;
} }
meta_buf.resize(meta_size); meta_buf.resize(meta_size);
return meta_buf; return meta_buf;
} }
std::optional<std::string>
multiplex_id_for_line(string_fragment line)
{
const auto& cfg = injector::get<const config&>();
auto md = lnav::pcre2pp::match_data::unitialized();
for (const auto& demux_pair : cfg.c_demux_definitions) {
const auto& df = demux_pair.second;
if (!df.dd_enabled) {
continue;
}
log_info("attempting to demux using: %s", demux_pair.first.c_str());
md = df.dd_pattern.pp_value->create_match_data();
if (df.dd_pattern.pp_value->capture_from(line)
.into(md)
.matches()
.ignore_error())
{
log_info(" demuxer pattern matched");
if (!md[df.dd_muxid_capture_index].has_value()) {
log_info(" however, mux_id was not captured");
continue;
}
if (!md[df.dd_body_capture_index].has_value()) {
log_info(" however, body was not captured");
continue;
}
log_info(" and required captures were found, using demuxer");
return demux_pair.first;
}
}
return std::nullopt;
}
} // namespace piper } // namespace piper
} // namespace lnav } // namespace lnav

@ -31,13 +31,14 @@
#define lnav_piper_file_hh #define lnav_piper_file_hh
#include <map> #include <map>
#include <optional>
#include <string> #include <string>
#include <sys/time.h> #include <sys/time.h>
#include "auto_mem.hh" #include "auto_mem.hh"
#include "base/intern_string.hh"
#include "ghc/filesystem.hpp" #include "ghc/filesystem.hpp"
#include "optional.hpp"
#include "time_util.hh" #include "time_util.hh"
namespace lnav { namespace lnav {
@ -48,6 +49,8 @@ struct header {
std::string h_name; std::string h_name;
std::string h_cwd; std::string h_cwd;
std::map<std::string, std::string> h_env; std::map<std::string, std::string> h_env;
std::string h_timezone;
std::map<std::string, std::string> h_demux_meta;
bool operator<(const header& rhs) const bool operator<(const header& rhs) const
{ {
@ -68,7 +71,9 @@ const ghc::filesystem::path& storage_path();
constexpr size_t HEADER_SIZE = 8; constexpr size_t HEADER_SIZE = 8;
extern const char HEADER_MAGIC[4]; extern const char HEADER_MAGIC[4];
nonstd::optional<auto_buffer> read_header(int fd, const char* first8); std::optional<auto_buffer> read_header(int fd, const char* first8);
std::optional<std::string> multiplex_id_for_line(string_fragment line);
} // namespace piper } // namespace piper
} // namespace lnav } // namespace lnav

@ -99,7 +99,7 @@ find_matching_bracket(
} }
} }
nonstd::optional<int> first_left; std::optional<int> first_left;
depth = 0; depth = 0;

@ -164,8 +164,8 @@ struct text_attrs {
} }
int32_t ta_attrs{0}; int32_t ta_attrs{0};
nonstd::optional<short> ta_fg_color; std::optional<short> ta_fg_color;
nonstd::optional<short> ta_bg_color; std::optional<short> ta_bg_color;
}; };
struct block_elem_t { struct block_elem_t {

@ -375,7 +375,7 @@ is_meta(char ch)
} }
} }
static nonstd::optional<const char*> static std::optional<const char*>
char_escape_seq(char ch) char_escape_seq(char ch)
{ {
switch (ch) { switch (ch) {
@ -385,7 +385,7 @@ char_escape_seq(char ch)
return "\\n"; return "\\n";
} }
return nonstd::nullopt; return std::nullopt;
} }
std::string std::string

@ -38,7 +38,6 @@
#include "config.h" #include "config.h"
#include "lnav_log.hh" #include "lnav_log.hh"
#include "optional.hpp"
namespace lnav { namespace lnav {
@ -80,18 +79,18 @@ strftime_rfc3339(
return index; return index;
} }
static nonstd::optional<Posix::time_zone> static std::optional<Posix::time_zone>
get_posix_zone(const char* name) get_posix_zone(const char* name)
{ {
if (name == nullptr) { if (name == nullptr) {
return nonstd::nullopt; return std::nullopt;
} }
try { try {
return date::zoned_traits<Posix::time_zone>::locate_zone(name); return date::zoned_traits<Posix::time_zone>::locate_zone(name);
} catch (const std::runtime_error& e) { } catch (const std::runtime_error& e) {
log_error("invalid TZ value: %s -- %s", name, e.what()); log_error("invalid TZ value: %s -- %s", name, e.what());
return nonstd::nullopt; return std::nullopt;
} }
} }
@ -121,6 +120,8 @@ to_sys_time(date::local_seconds secs)
return TZ_POSIX_ZONE.value().to_sys(secs); return TZ_POSIX_ZONE.value().to_sys(secs);
} }
auto inf = TZ_DATE_ZONE->get_info(secs);
return TZ_DATE_ZONE->to_sys(secs); return TZ_DATE_ZONE->to_sys(secs);
} }
@ -138,6 +139,34 @@ to_local_time(date::sys_seconds secs)
return TZ_DATE_ZONE->to_local(secs); return TZ_DATE_ZONE->to_local(secs);
} }
date::sys_info
sys_time_to_info(date::sys_seconds secs)
{
static const auto* TZ = getenv("TZ");
static const auto TZ_POSIX_ZONE = get_posix_zone(TZ);
static const auto* TZ_DATE_ZONE = get_date_zone(TZ);
if (TZ_POSIX_ZONE) {
return TZ_POSIX_ZONE.value().get_info(secs);
}
return TZ_DATE_ZONE->get_info(secs);
}
date::local_info
local_time_to_info(date::local_seconds secs)
{
static const auto* TZ = getenv("TZ");
static const auto TZ_POSIX_ZONE = get_posix_zone(TZ);
static const auto* TZ_DATE_ZONE = get_date_zone(TZ);
if (TZ_POSIX_ZONE) {
return TZ_POSIX_ZONE.value().get_info(secs);
}
return TZ_DATE_ZONE->get_info(secs);
}
} // namespace lnav } // namespace lnav
static time_t BAD_DATE = -1; static time_t BAD_DATE = -1;

@ -40,6 +40,7 @@
#include "config.h" #include "config.h"
#include "date/date.h" #include "date/date.h"
#include "date/tz.h"
namespace lnav { namespace lnav {
@ -51,6 +52,10 @@ ssize_t strftime_rfc3339(char* buffer,
int millis, int millis,
char sep = ' '); char sep = ' ');
date::sys_info sys_time_to_info(date::sys_seconds secs);
date::local_info local_time_to_info(date::local_seconds secs);
date::sys_seconds to_sys_time(date::local_seconds secs); date::sys_seconds to_sys_time(date::local_seconds secs);
date::local_seconds to_local_time(date::sys_seconds secs); date::local_seconds to_local_time(date::sys_seconds secs);

@ -87,7 +87,7 @@ bookmark_metadata::clear()
this->bm_annotations.la_pairs.clear(); this->bm_annotations.la_pairs.clear();
} }
nonstd::optional<bookmark_type_t*> std::optional<bookmark_type_t*>
bookmark_type_t::find_type(const std::string& name) bookmark_type_t::find_type(const std::string& name)
{ {
return get_all_types() return get_all_types()

@ -153,7 +153,7 @@ public:
* the next bookmark is returned. If the 'start' value is not a * the next bookmark is returned. If the 'start' value is not a
* bookmark, the next highest value in the vector is returned. * bookmark, the next highest value in the vector is returned.
*/ */
nonstd::optional<LineType> next(LineType start) const; std::optional<LineType> next(LineType start) const;
/** /**
* @param start The value to start the search for the previous * @param start The value to start the search for the previous
@ -162,7 +162,7 @@ public:
* are no more prior bookmarks. * are no more prior bookmarks.
* @see next * @see next
*/ */
nonstd::optional<LineType> prev(LineType start) const; std::optional<LineType> prev(LineType start) const;
}; };
/** /**
@ -177,7 +177,7 @@ public:
static type_iterator type_end() { return get_all_types().end(); } static type_iterator type_end() { return get_all_types().end(); }
static nonstd::optional<bookmark_type_t*> find_type( static std::optional<bookmark_type_t*> find_type(
const std::string& name); const std::string& name);
static std::vector<bookmark_type_t*>& get_all_types(); static std::vector<bookmark_type_t*>& get_all_types();
@ -194,10 +194,10 @@ private:
}; };
template<typename LineType> template<typename LineType>
nonstd::optional<LineType> std::optional<LineType>
bookmark_vector<LineType>::next(LineType start) const bookmark_vector<LineType>::next(LineType start) const
{ {
nonstd::optional<LineType> retval; std::optional<LineType> retval;
require(start >= -1); require(start >= -1);
@ -212,10 +212,10 @@ bookmark_vector<LineType>::next(LineType start) const
} }
template<typename LineType> template<typename LineType>
nonstd::optional<LineType> std::optional<LineType>
bookmark_vector<LineType>::prev(LineType start) const bookmark_vector<LineType>::prev(LineType start) const
{ {
nonstd::optional<LineType> retval; std::optional<LineType> retval;
require(start >= 0); require(start >= 0);

@ -71,13 +71,13 @@ bottom_status_source::update_line_number(listview_curses* lc)
this->bss_line_error.set_value( this->bss_line_error.set_value(
lc->map_top_row([](const attr_line_t& top_row) lc->map_top_row([](const attr_line_t& top_row)
-> nonstd::optional<std::string> { -> std::optional<std::string> {
const auto& sa = top_row.get_attrs(); const auto& sa = top_row.get_attrs();
auto error_wrapper = get_string_attr(sa, SA_ERROR); auto error_wrapper = get_string_attr(sa, SA_ERROR);
if (error_wrapper) { if (error_wrapper) {
return error_wrapper.value().get(); return error_wrapper.value().get();
} }
return nonstd::nullopt; return std::nullopt;
}).value_or("")); }).value_or(""));
} }

@ -136,7 +136,7 @@ struct crumb {
attr_line_t c_display_value; attr_line_t c_display_value;
crumb_possibilities c_possibility_provider; crumb_possibilities c_possibility_provider;
perform c_performer; perform c_performer;
nonstd::optional<size_t> c_possible_range; std::optional<size_t> c_possible_range;
expected_input_t c_expected_input{expected_input_t::exact}; expected_input_t c_expected_input{expected_input_t::exact};
std::string c_search_placeholder; std::string c_search_placeholder;
}; };

@ -126,7 +126,7 @@ breadcrumb_curses::reload_data()
= this->bc_focused_crumbs[this->bc_selected_crumb.value()]; = this->bc_focused_crumbs[this->bc_selected_crumb.value()];
this->bc_possible_values = selected_crumb_ref.c_possibility_provider(); this->bc_possible_values = selected_crumb_ref.c_possibility_provider();
nonstd::optional<size_t> selected_value; std::optional<size_t> selected_value;
this->bc_similar_values = this->bc_possible_values this->bc_similar_values = this->bc_possible_values
| lnav::itertools::similar_to( | lnav::itertools::similar_to(
[](const auto& elem) { return elem.p_key; }, [](const auto& elem) { return elem.p_key; },
@ -210,7 +210,7 @@ breadcrumb_curses::blur()
{ {
this->bc_last_selected_crumb = this->bc_selected_crumb; this->bc_last_selected_crumb = this->bc_selected_crumb;
this->bc_focused_crumbs.clear(); this->bc_focused_crumbs.clear();
this->bc_selected_crumb = nonstd::nullopt; this->bc_selected_crumb = std::nullopt;
this->bc_current_search.clear(); this->bc_current_search.clear();
this->bc_match_view.set_height(0_vl); this->bc_match_view.set_height(0_vl);
this->bc_match_view.set_selection(-1_vl); this->bc_match_view.set_selection(-1_vl);

@ -92,8 +92,8 @@ private:
WINDOW* bc_window{nullptr}; WINDOW* bc_window{nullptr};
std::function<std::vector<breadcrumb::crumb>()> bc_line_source; std::function<std::vector<breadcrumb::crumb>()> bc_line_source;
std::vector<breadcrumb::crumb> bc_focused_crumbs; std::vector<breadcrumb::crumb> bc_focused_crumbs;
nonstd::optional<size_t> bc_selected_crumb; std::optional<size_t> bc_selected_crumb;
nonstd::optional<size_t> bc_last_selected_crumb; std::optional<size_t> bc_last_selected_crumb;
std::vector<breadcrumb::possibility> bc_possible_values; std::vector<breadcrumb::possibility> bc_possible_values;
std::vector<breadcrumb::possibility> bc_similar_values; std::vector<breadcrumb::possibility> bc_similar_values;
std::string bc_current_search; std::string bc_current_search;

@ -29,6 +29,7 @@
#ifndef byte_array_hh #ifndef byte_array_hh
#define byte_array_hh #define byte_array_hh
#include <optional>
#include <ostream> #include <ostream>
#include <string> #include <string>
@ -38,7 +39,6 @@
#include "base/lnav_log.hh" #include "base/lnav_log.hh"
#include "fmt/format.h" #include "fmt/format.h"
#include "optional.hpp"
template<size_t COUNT, typename T = unsigned char> template<size_t COUNT, typename T = unsigned char>
struct byte_array { struct byte_array {
@ -82,7 +82,7 @@ struct byte_array {
template<typename OutputIt> template<typename OutputIt>
void to_string(OutputIt out, void to_string(OutputIt out,
nonstd::optional<char> separator = nonstd::nullopt) const std::optional<char> separator = std::nullopt) const
{ {
for (size_t lpc = 0; lpc < BYTE_COUNT; lpc++) { for (size_t lpc = 0; lpc < BYTE_COUNT; lpc++) {
if (lpc > 0 && separator) { if (lpc > 0 && separator) {
@ -115,8 +115,7 @@ struct byte_array {
this->ba_data[15 % BYTE_COUNT]); this->ba_data[15 % BYTE_COUNT]);
} }
std::string to_string(nonstd::optional<char> separator std::string to_string(std::optional<char> separator = std::nullopt) const
= nonstd::nullopt) const
{ {
std::string retval; std::string retval;

@ -804,7 +804,7 @@ execute_any(exec_context& ec, const std::string& cmdline_with_mode)
(lnav_data.ld_flags & LNF_HEADLESS || ec.ec_path_stack.size() > 1)) (lnav_data.ld_flags & LNF_HEADLESS || ec.ec_path_stack.size() > 1))
{ {
rescan_files(); rescan_files();
wait_for_pipers(nonstd::nullopt); wait_for_pipers(std::nullopt);
rebuild_indexes_repeatedly(); rebuild_indexes_repeatedly();
} }
}); });
@ -842,7 +842,7 @@ execute_init_commands(
return; return;
} }
nonstd::optional<exec_context::output_t> ec_out; std::optional<exec_context::output_t> ec_out;
auto_fd fd_copy; auto_fd fd_copy;
if (!(lnav_data.ld_flags & LNF_HEADLESS)) { if (!(lnav_data.ld_flags & LNF_HEADLESS)) {
@ -1090,7 +1090,7 @@ pipe_callback(exec_context& ec, const std::string& cmdline, auto_fd& fd)
static int exec_count = 0; static int exec_count = 0;
auto desc auto desc
= fmt::format(FMT_STRING("[{}] Output of {}"), exec_count++, cmdline); = fmt::format(FMT_STRING("exec-{}-output {}"), exec_count++, cmdline);
lnav_data.ld_active_files.fc_file_names[tmp_pair.first] lnav_data.ld_active_files.fc_file_names[tmp_pair.first]
.with_filename(desc) .with_filename(desc)
.with_include_in_session(false) .with_include_in_session(false)
@ -1145,7 +1145,7 @@ exec_context::clear_output()
out.second(out.first); out.second(out.first);
} }
}; };
this->ec_output_stack.back() = std::make_pair("default", nonstd::nullopt); this->ec_output_stack.back() = std::make_pair("default", std::nullopt);
} }
exec_context::exec_context(logline_value_vector* line_values, exec_context::exec_context(logline_value_vector* line_values,
@ -1161,7 +1161,7 @@ exec_context::exec_context(logline_value_vector* line_values,
this->ec_path_stack.emplace_back("."); this->ec_path_stack.emplace_back(".");
this->ec_source.emplace_back( this->ec_source.emplace_back(
lnav::console::snippet::from(COMMAND_SRC, "").with_line(1)); lnav::console::snippet::from(COMMAND_SRC, "").with_line(1));
this->ec_output_stack.emplace_back("screen", nonstd::nullopt); this->ec_output_stack.emplace_back("screen", std::nullopt);
this->ec_error_callback_stack.emplace_back( this->ec_error_callback_stack.emplace_back(
[](const auto& um) { lnav::console::print(stderr, um); }); [](const auto& um) { lnav::console::print(stderr, um); });
} }
@ -1239,7 +1239,7 @@ exec_context::enter_source(intern_string_t path,
exec_context::output_guard::output_guard(exec_context& context, exec_context::output_guard::output_guard(exec_context& context,
std::string name, std::string name,
const nonstd::optional<output_t>& file) const std::optional<output_t>& file)
: sg_context(context) : sg_context(context)
{ {
if (file) { if (file) {

@ -31,6 +31,7 @@
#define LNAV_COMMAND_EXECUTOR_H #define LNAV_COMMAND_EXECUTOR_H
#include <future> #include <future>
#include <optional>
#include <stack> #include <stack>
#include <string> #include <string>
@ -42,7 +43,6 @@
#include "fmt/format.h" #include "fmt/format.h"
#include "ghc/filesystem.hpp" #include "ghc/filesystem.hpp"
#include "help_text.hh" #include "help_text.hh"
#include "optional.hpp"
#include "shlex.resolver.hh" #include "shlex.resolver.hh"
#include "vis_line.hh" #include "vis_line.hh"
@ -103,7 +103,7 @@ struct exec_context {
return Err(this->make_error_msg(format_str, args...)); return Err(this->make_error_msg(format_str, args...));
} }
nonstd::optional<FILE*> get_output() std::optional<FILE*> get_output()
{ {
for (auto iter = this->ec_output_stack.rbegin(); for (auto iter = this->ec_output_stack.rbegin();
iter != this->ec_output_stack.rend(); iter != this->ec_output_stack.rend();
@ -114,7 +114,7 @@ struct exec_context {
} }
} }
return nonstd::nullopt; return std::nullopt;
} }
void set_output(const std::string& name, FILE* file, int (*closer)(FILE*)); void set_output(const std::string& name, FILE* file, int (*closer)(FILE*));
@ -183,8 +183,8 @@ struct exec_context {
struct output_guard { struct output_guard {
explicit output_guard(exec_context& context, explicit output_guard(exec_context& context,
std::string name = "default", std::string name = "default",
const nonstd::optional<output_t>& file const std::optional<output_t>& file
= nonstd::nullopt); = std::nullopt);
~output_guard(); ~output_guard();
@ -282,7 +282,7 @@ struct exec_context {
} }
template<typename T> template<typename T>
nonstd::optional<T> get_provenance() const std::optional<T> get_provenance() const
{ {
for (const auto& elem : this->ec_provenance) { for (const auto& elem : this->ec_provenance) {
if (elem.is<T>()) { if (elem.is<T>()) {
@ -290,7 +290,7 @@ struct exec_context {
} }
} }
return nonstd::nullopt; return std::nullopt;
} }
vis_line_t ec_top_line{0_vl}; vis_line_t ec_top_line{0_vl};
@ -305,7 +305,7 @@ struct exec_context {
std::vector<lnav::console::snippet> ec_source; std::vector<lnav::console::snippet> ec_source;
help_text* ec_current_help{nullptr}; help_text* ec_current_help{nullptr};
std::vector<std::pair<std::string, nonstd::optional<output_t>>> std::vector<std::pair<std::string, std::optional<output_t>>>
ec_output_stack; ec_output_stack;
std::unique_ptr<attr_line_t> ec_accumulator; std::unique_ptr<attr_line_t> ec_accumulator;
@ -326,7 +326,7 @@ class multiline_executor {
public: public:
exec_context& me_exec_context; exec_context& me_exec_context;
std::string me_source; std::string me_source;
nonstd::optional<std::string> me_cmdline; std::optional<std::string> me_cmdline;
int me_line_number{0}; int me_line_number{0};
int me_starting_line_number{0}; int me_starting_line_number{0};
std::string me_last_result; std::string me_last_result;

@ -305,7 +305,7 @@ data_scanner::cleanup_end()
} }
} }
nonstd::optional<data_scanner::tokenize_result> std::optional<data_scanner::tokenize_result>
data_scanner::tokenize2(text_format_t tf) data_scanner::tokenize2(text_format_t tf)
{ {
auto retval = this->tokenize_int(tf); auto retval = this->tokenize_int(tf);
@ -340,7 +340,7 @@ data_scanner::tokenize2(text_format_t tf)
return retval; return retval;
} }
nonstd::optional<data_scanner::tokenize_result> std::optional<data_scanner::tokenize_result>
data_scanner::find_matching_bracket(text_format_t tf, tokenize_result tr) data_scanner::find_matching_bracket(text_format_t tf, tokenize_result tr)
{ {
switch (tr.tr_token) { switch (tr.tr_token) {
@ -401,5 +401,5 @@ data_scanner::find_matching_bracket(text_format_t tf, tokenize_result tr)
break; break;
} }
return nonstd::nullopt; return std::nullopt;
} }

@ -203,10 +203,10 @@ public:
} }
}; };
nonstd::optional<tokenize_result> tokenize2(text_format_t tf std::optional<tokenize_result> tokenize2(text_format_t tf
= text_format_t::TF_UNKNOWN); = text_format_t::TF_UNKNOWN);
nonstd::optional<tokenize_result> find_matching_bracket(text_format_t tf, std::optional<tokenize_result> find_matching_bracket(text_format_t tf,
tokenize_result tr); tokenize_result tr);
void reset() { this->ds_next_offset = this->ds_init_offset; } void reset() { this->ds_next_offset = this->ds_init_offset; }
@ -225,7 +225,7 @@ private:
bool is_credit_card(string_fragment frag) const; bool is_credit_card(string_fragment frag) const;
nonstd::optional<tokenize_result> tokenize_int(text_format_t tf std::optional<tokenize_result> tokenize_int(text_format_t tf
= text_format_t::TF_UNKNOWN); = text_format_t::TF_UNKNOWN);
std::string ds_line; std::string ds_line;

@ -48,7 +48,7 @@ enum YYCONDTYPE {
#line 38 "../../lnav/src/data_scanner_re.re" #line 38 "../../lnav/src/data_scanner_re.re"
nonstd::optional<data_scanner::tokenize_result> data_scanner::tokenize_int(text_format_t tf) std::optional<data_scanner::tokenize_result> data_scanner::tokenize_int(text_format_t tf)
{ {
data_token_t token_out = DT_INVALID; data_token_t token_out = DT_INVALID;
capture_t cap_all; capture_t cap_all;
@ -832,7 +832,7 @@ yyc_bol:
yy1: yy1:
++YYCURSOR; ++YYCURSOR;
#line 172 "../../lnav/src/data_scanner_re.re" #line 172 "../../lnav/src/data_scanner_re.re"
{ return nonstd::nullopt; } { return std::nullopt; }
#line 837 "../../lnav/src/data_scanner_re.cc" #line 837 "../../lnav/src/data_scanner_re.cc"
yy2: yy2:
++YYCURSOR; ++YYCURSOR;
@ -1955,7 +1955,7 @@ yy62:
++YYCURSOR; ++YYCURSOR;
yy63: yy63:
#line 173 "../../lnav/src/data_scanner_re.re" #line 173 "../../lnav/src/data_scanner_re.re"
{ return nonstd::nullopt; } { return std::nullopt; }
#line 1960 "../../lnav/src/data_scanner_re.cc" #line 1960 "../../lnav/src/data_scanner_re.cc"
yy64: yy64:
yych = *++YYCURSOR; yych = *++YYCURSOR;
@ -43435,7 +43435,7 @@ yyc_init:
yy1612: yy1612:
++YYCURSOR; ++YYCURSOR;
#line 172 "../../lnav/src/data_scanner_re.re" #line 172 "../../lnav/src/data_scanner_re.re"
{ return nonstd::nullopt; } { return std::nullopt; }
#line 43440 "../../lnav/src/data_scanner_re.cc" #line 43440 "../../lnav/src/data_scanner_re.cc"
yy1613: yy1613:
++YYCURSOR; ++YYCURSOR;
@ -44503,7 +44503,7 @@ yy1671:
++YYCURSOR; ++YYCURSOR;
yy1672: yy1672:
#line 173 "../../lnav/src/data_scanner_re.re" #line 173 "../../lnav/src/data_scanner_re.re"
{ return nonstd::nullopt; } { return std::nullopt; }
#line 44508 "../../lnav/src/data_scanner_re.cc" #line 44508 "../../lnav/src/data_scanner_re.cc"
yy1673: yy1673:
yych = *++YYCURSOR; yych = *++YYCURSOR;
@ -84403,7 +84403,7 @@ yy3116:
++YYCURSOR; ++YYCURSOR;
yy3117: yy3117:
#line 173 "../../lnav/src/data_scanner_re.re" #line 173 "../../lnav/src/data_scanner_re.re"
{ return nonstd::nullopt; } { return std::nullopt; }
#line 84408 "../../lnav/src/data_scanner_re.cc" #line 84408 "../../lnav/src/data_scanner_re.cc"
yy3118: yy3118:
++YYCURSOR; ++YYCURSOR;
@ -84475,5 +84475,5 @@ yy3125:
#line 478 "../../lnav/src/data_scanner_re.re" #line 478 "../../lnav/src/data_scanner_re.re"
return nonstd::nullopt; return std::nullopt;
} }

@ -37,7 +37,7 @@
/*!conditions:re2c*/ /*!conditions:re2c*/
nonstd::optional<data_scanner::tokenize_result> data_scanner::tokenize_int(text_format_t tf) std::optional<data_scanner::tokenize_result> data_scanner::tokenize_int(text_format_t tf)
{ {
data_token_t token_out = DT_INVALID; data_token_t token_out = DT_INVALID;
capture_t cap_all; capture_t cap_all;
@ -168,9 +168,9 @@ nonstd::optional<data_scanner::tokenize_result> data_scanner::tokenize_int(text_
); );
UNITS = (([mup]?("s"|"S"))|(([kKmMgG]"i"?)?[bB])|("m"|"min")); UNITS = (([mup]?("s"|"S"))|(([kKmMgG]"i"?)?[bB])|("m"|"min"));
<init, bol> EOF { return nonstd::nullopt; } <init, bol> EOF { return std::nullopt; }
<init, bol> [\x00] { return nonstd::nullopt; } <init, bol> [\x00] { return std::nullopt; }
<*> * { return nonstd::nullopt; } <*> * { return std::nullopt; }
<init, bol> SYN+ { <init, bol> SYN+ {
RET(DT_ZERO_WIDTH_SPACE); RET(DT_ZERO_WIDTH_SPACE);
} }
@ -477,5 +477,5 @@ nonstd::optional<data_scanner::tokenize_result> data_scanner::tokenize_int(text_
*/ */
return nonstd::nullopt; return std::nullopt;
} }

@ -299,13 +299,13 @@ db_label_source::clear()
this->dls_allocator = std::make_unique<ArenaAlloc::Alloc<char>>(64 * 1024); this->dls_allocator = std::make_unique<ArenaAlloc::Alloc<char>>(64 * 1024);
} }
nonstd::optional<size_t> std::optional<size_t>
db_label_source::column_name_to_index(const std::string& name) const db_label_source::column_name_to_index(const std::string& name) const
{ {
return this->dls_headers | lnav::itertools::find(name); return this->dls_headers | lnav::itertools::find(name);
} }
nonstd::optional<vis_line_t> std::optional<vis_line_t>
db_label_source::row_for_time(struct timeval time_bucket) db_label_source::row_for_time(struct timeval time_bucket)
{ {
std::vector<struct timeval>::iterator iter; std::vector<struct timeval>::iterator iter;
@ -316,20 +316,20 @@ db_label_source::row_for_time(struct timeval time_bucket)
if (iter != this->dls_time_column.end()) { if (iter != this->dls_time_column.end()) {
return vis_line_t(std::distance(this->dls_time_column.begin(), iter)); return vis_line_t(std::distance(this->dls_time_column.begin(), iter));
} }
return nonstd::nullopt; return std::nullopt;
} }
nonstd::optional<text_time_translator::row_info> std::optional<text_time_translator::row_info>
db_label_source::time_for_row(vis_line_t row) db_label_source::time_for_row(vis_line_t row)
{ {
if ((row < 0_vl) || (((size_t) row) >= this->dls_time_column.size())) { if ((row < 0_vl) || (((size_t) row) >= this->dls_time_column.size())) {
return nonstd::nullopt; return std::nullopt;
} }
return row_info{this->dls_time_column[row], row}; return row_info{this->dls_time_column[row], row};
} }
nonstd::optional<attr_line_t> std::optional<attr_line_t>
db_overlay_source::list_header_for_overlay(const listview_curses& lv, db_overlay_source::list_header_for_overlay(const listview_curses& lv,
vis_line_t line) vis_line_t line)
{ {

@ -31,6 +31,7 @@
#define db_sub_source_hh #define db_sub_source_hh
#include <iterator> #include <iterator>
#include <optional>
#include <string> #include <string>
#include <vector> #include <vector>
@ -83,13 +84,11 @@ public:
void clear(); void clear();
nonstd::optional<size_t> column_name_to_index( std::optional<size_t> column_name_to_index(const std::string& name) const;
const std::string& name) const;
nonstd::optional<vis_line_t> row_for_time( std::optional<vis_line_t> row_for_time(struct timeval time_bucket) override;
struct timeval time_bucket) override;
nonstd::optional<row_info> time_for_row(vis_line_t row) override; std::optional<row_info> time_for_row(vis_line_t row) override;
struct header_meta { struct header_meta {
explicit header_meta(std::string name) : hm_name(std::move(name)) {} explicit header_meta(std::string name) : hm_name(std::move(name)) {}
@ -114,7 +113,7 @@ public:
std::vector<struct timeval> dls_time_column; std::vector<struct timeval> dls_time_column;
std::vector<size_t> dls_cell_width; std::vector<size_t> dls_cell_width;
int dls_time_column_index{-1}; int dls_time_column_index{-1};
nonstd::optional<size_t> dls_time_column_invalidated_at; std::optional<size_t> dls_time_column_invalidated_at;
std::unique_ptr<ArenaAlloc::Alloc<char>> dls_allocator{ std::unique_ptr<ArenaAlloc::Alloc<char>> dls_allocator{
std::make_unique<ArenaAlloc::Alloc<char>>(64 * 1024)}; std::make_unique<ArenaAlloc::Alloc<char>>(64 * 1024)};
string_attrs_t dls_ansi_attrs; string_attrs_t dls_ansi_attrs;
@ -133,7 +132,7 @@ public:
vis_line_t line, vis_line_t line,
std::vector<attr_line_t>& value_out) override; std::vector<attr_line_t>& value_out) override;
nonstd::optional<attr_line_t> list_header_for_overlay( std::optional<attr_line_t> list_header_for_overlay(
const listview_curses& lv, vis_line_t line) override; const listview_curses& lv, vis_line_t line) override;
void set_show_details_in_overlay(bool val) override void set_show_details_in_overlay(bool val) override

@ -42,7 +42,7 @@
namespace lnav { namespace lnav {
namespace document { namespace document {
nonstd::optional<hier_node*> std::optional<hier_node*>
hier_node::lookup_child(section_key_t key) const hier_node::lookup_child(section_key_t key) const
{ {
return make_optional_from_nullable(key.match( return make_optional_from_nullable(key.match(
@ -62,7 +62,7 @@ hier_node::lookup_child(section_key_t key) const
})); }));
} }
nonstd::optional<size_t> std::optional<size_t>
hier_node::child_index(const hier_node* hn) const hier_node::child_index(const hier_node* hn) const
{ {
size_t retval = 0; size_t retval = 0;
@ -74,16 +74,16 @@ hier_node::child_index(const hier_node* hn) const
retval += 1; retval += 1;
} }
return nonstd::nullopt; return std::nullopt;
} }
nonstd::optional<hier_node::child_neighbors_result> std::optional<hier_node::child_neighbors_result>
hier_node::child_neighbors(const lnav::document::hier_node* hn, hier_node::child_neighbors(const lnav::document::hier_node* hn,
file_off_t offset) const file_off_t offset) const
{ {
auto index_opt = this->child_index(hn); auto index_opt = this->child_index(hn);
if (!index_opt) { if (!index_opt) {
return nonstd::nullopt; return std::nullopt;
} }
hier_node::child_neighbors_result retval; hier_node::child_neighbors_result retval;
@ -153,11 +153,11 @@ hier_node::child_neighbors(const lnav::document::hier_node* hn,
return retval; return retval;
} }
nonstd::optional<hier_node::child_neighbors_result> std::optional<hier_node::child_neighbors_result>
hier_node::line_neighbors(size_t ln) const hier_node::line_neighbors(size_t ln) const
{ {
if (this->hn_children.empty()) { if (this->hn_children.empty()) {
return nonstd::nullopt; return std::nullopt;
} }
hier_node::child_neighbors_result retval; hier_node::child_neighbors_result retval;
@ -173,7 +173,7 @@ hier_node::line_neighbors(size_t ln) const
return retval; return retval;
} }
nonstd::optional<const hier_node*> std::optional<const hier_node*>
hier_node::lookup_path(const hier_node* root, hier_node::lookup_path(const hier_node* root,
const std::vector<section_key_t>& path) const std::vector<section_key_t>& path)
{ {
@ -188,7 +188,7 @@ hier_node::lookup_path(const hier_node* root,
} }
if (!retval) { if (!retval) {
return nonstd::nullopt; return std::nullopt;
} }
return retval; return retval;
@ -484,7 +484,7 @@ public:
} }
if (term) { if (term) {
this->append_child_node(term); this->append_child_node(term);
term = nonstd::nullopt; term = std::nullopt;
} }
this->sw_interval_state.pop_back(); this->sw_interval_state.pop_back();
this->sw_hier_stage this->sw_hier_stage
@ -605,7 +605,7 @@ public:
found = true; found = true;
} }
this->append_child_node(term); this->append_child_node(term);
term = nonstd::nullopt; term = std::nullopt;
this->sw_depth -= 1; this->sw_depth -= 1;
this->sw_interval_state.pop_back(); this->sw_interval_state.pop_back();
this->sw_hier_stage this->sw_hier_stage
@ -758,15 +758,15 @@ private:
}; };
struct interval_state { struct interval_state {
nonstd::optional<file_off_t> is_start; std::optional<file_off_t> is_start;
size_t is_line_number{0}; size_t is_line_number{0};
std::string is_name; std::string is_name;
}; };
nonstd::optional<data_scanner::capture_t> flush_values() std::optional<data_scanner::capture_t> flush_values()
{ {
nonstd::optional<data_scanner::capture_t> last_key; std::optional<data_scanner::capture_t> last_key;
nonstd::optional<data_scanner::capture_t> retval; std::optional<data_scanner::capture_t> retval;
if (!this->sw_values.empty()) { if (!this->sw_values.empty()) {
if (!this->sw_interval_state.back().is_start) { if (!this->sw_interval_state.back().is_start) {
@ -799,7 +799,7 @@ private:
this->sw_interval_state.back().is_line_number this->sw_interval_state.back().is_line_number
= this->sw_line_number; = this->sw_line_number;
} }
last_key = nonstd::nullopt; last_key = std::nullopt;
} }
break; break;
default: default:
@ -812,11 +812,11 @@ private:
return retval; return retval;
} }
void append_child_node(nonstd::optional<data_scanner::capture_t> terminator) void append_child_node(std::optional<data_scanner::capture_t> terminator)
{ {
auto& ivstate = this->sw_interval_state.back(); auto& ivstate = this->sw_interval_state.back();
if (!ivstate.is_start || !terminator || this->sw_depth == 0) { if (!ivstate.is_start || !terminator || this->sw_depth == 0) {
ivstate.is_start = nonstd::nullopt; ivstate.is_start = std::nullopt;
ivstate.is_line_number = 0; ivstate.is_line_number = 0;
ivstate.is_name.clear(); ivstate.is_name.clear();
return; return;
@ -847,7 +847,7 @@ private:
} }
top_node->hn_children.emplace_back(std::move(new_node)); top_node->hn_children.emplace_back(std::move(new_node));
} }
ivstate.is_start = nonstd::nullopt; ivstate.is_start = std::nullopt;
ivstate.is_line_number = 0; ivstate.is_line_number = 0;
ivstate.is_name.clear(); ivstate.is_name.clear();
} }

@ -40,7 +40,6 @@
#include "breadcrumb.hh" #include "breadcrumb.hh"
#include "intervaltree/IntervalTree.h" #include "intervaltree/IntervalTree.h"
#include "mapbox/variant.hpp" #include "mapbox/variant.hpp"
#include "optional.hpp"
#include "text_format.hh" #include "text_format.hh"
namespace lnav { namespace lnav {
@ -67,37 +66,37 @@ struct hier_node {
std::multimap<std::string, hier_node*> hn_named_children; std::multimap<std::string, hier_node*> hn_named_children;
std::vector<std::unique_ptr<hier_node>> hn_children; std::vector<std::unique_ptr<hier_node>> hn_children;
nonstd::optional<hier_node*> lookup_child(section_key_t key) const; std::optional<hier_node*> lookup_child(section_key_t key) const;
nonstd::optional<size_t> child_index(const hier_node* hn) const; std::optional<size_t> child_index(const hier_node* hn) const;
struct child_neighbors_result { struct child_neighbors_result {
nonstd::optional<const hier_node*> cnr_previous; std::optional<const hier_node*> cnr_previous;
nonstd::optional<const hier_node*> cnr_next; std::optional<const hier_node*> cnr_next;
}; };
nonstd::optional<child_neighbors_result> child_neighbors( std::optional<child_neighbors_result> child_neighbors(
const hier_node* hn, file_off_t offset) const; const hier_node* hn, file_off_t offset) const;
nonstd::optional<child_neighbors_result> line_neighbors(size_t ln) const; std::optional<child_neighbors_result> line_neighbors(size_t ln) const;
nonstd::optional<size_t> find_line_number(const std::string& str) const std::optional<size_t> find_line_number(const std::string& str) const
{ {
auto iter = this->hn_named_children.find(str); auto iter = this->hn_named_children.find(str);
if (iter != this->hn_named_children.end()) { if (iter != this->hn_named_children.end()) {
return nonstd::make_optional(iter->second->hn_line_number); return std::make_optional(iter->second->hn_line_number);
} }
return nonstd::nullopt; return std::nullopt;
} }
nonstd::optional<size_t> find_line_number(size_t index) const std::optional<size_t> find_line_number(size_t index) const
{ {
if (index < this->hn_children.size()) { if (index < this->hn_children.size()) {
return nonstd::make_optional( return std::make_optional(
this->hn_children[index]->hn_line_number); this->hn_children[index]->hn_line_number);
} }
return nonstd::nullopt; return std::nullopt;
} }
bool is_named_only() const bool is_named_only() const
@ -105,7 +104,7 @@ struct hier_node {
return this->hn_children.size() == this->hn_named_children.size(); return this->hn_children.size() == this->hn_named_children.size();
} }
static nonstd::optional<const hier_node*> lookup_path( static std::optional<const hier_node*> lookup_path(
const hier_node* root, const std::vector<section_key_t>& path); const hier_node* root, const std::vector<section_key_t>& path);
template<typename F> template<typename F>

@ -110,12 +110,22 @@ field_overlay_source::build_field_lines(const listview_curses& lv,
attr_line_t time_line; attr_line_t time_line;
auto& time_str = time_line.get_string(); auto& time_str = time_line.get_string();
struct line_range time_lr; struct line_range time_lr;
off_t ts_len = sql_strftime(curr_timestamp,
sizeof(curr_timestamp),
ll->get_time(),
ll->get_millis(),
'T');
{
exttm tmptm;
sql_strftime(curr_timestamp, tmptm.et_flags |= ETF_ZONE_SET;
sizeof(curr_timestamp), tmptm.et_gmtoff
ll->get_time(), = lnav::local_time_to_info(
ll->get_millis(), date::local_seconds{std::chrono::seconds{ll->get_time()}})
'T'); .first.offset.count();
ftime_z(curr_timestamp, ts_len, sizeof(curr_timestamp), tmptm);
curr_timestamp[ts_len] = '\0';
}
if (ll->is_time_skewed()) { if (ll->is_time_skewed()) {
time_lr.lr_start = 1; time_lr.lr_start = 1;
@ -212,11 +222,13 @@ field_overlay_source::build_field_lines(const listview_curses& lv,
} }
time_line.append(" Format: ") time_line.append(" Format: ")
.append(lnav::roles::symbol( .append(lnav::roles::symbol(
ts_formats[format->lf_date_time.dts_fmt_lock])); ts_formats[format->lf_date_time.dts_fmt_lock]))
.append(" Default Zone: ");
if (format->lf_date_time.dts_default_zone != nullptr) { if (format->lf_date_time.dts_default_zone != nullptr) {
time_line.append(" Default Zone: ") time_line.append(lnav::roles::symbol(
.append(lnav::roles::symbol( format->lf_date_time.dts_default_zone->name()));
format->lf_date_time.dts_default_zone->name())); } else {
time_line.append("none"_comment);
} }
} }
@ -672,7 +684,7 @@ field_overlay_source::list_value_for_overlay(
this->build_meta_line(lv, value_out, row); this->build_meta_line(lv, value_out, row);
} }
nonstd::optional<attr_line_t> std::optional<attr_line_t>
field_overlay_source::list_header_for_overlay(const listview_curses& lv, field_overlay_source::list_header_for_overlay(const listview_curses& lv,
vis_line_t vl) vis_line_t vl)
{ {

@ -55,7 +55,7 @@ public:
this->fos_meta_lines.clear(); this->fos_meta_lines.clear();
} }
nonstd::optional<attr_line_t> list_header_for_overlay( std::optional<attr_line_t> list_header_for_overlay(
const listview_curses& lv, vis_line_t vl) override; const listview_curses& lv, vis_line_t vl) override;
void list_value_for_overlay(const listview_curses& lv, void list_value_for_overlay(const listview_curses& lv,

@ -66,7 +66,7 @@ child_poller::poll(file_collection& fc)
} }
auto poll_res = std::move(this->cp_child.value()).poll(); auto poll_res = std::move(this->cp_child.value()).poll();
this->cp_child = nonstd::nullopt; this->cp_child = std::nullopt;
return poll_res.match( return poll_res.match(
[this](auto_pid<process_state::running>& alive) { [this](auto_pid<process_state::running>& alive) {
this->cp_child = std::move(alive); this->cp_child = std::move(alive);
@ -178,6 +178,7 @@ file_collection::regenerate_unique_file_names()
switch (pair.second.ofd_format) { switch (pair.second.ofd_format) {
case file_format_t::UNKNOWN: case file_format_t::UNKNOWN:
case file_format_t::ARCHIVE: case file_format_t::ARCHIVE:
case file_format_t::MULTIPLEXED:
case file_format_t::SQLITE_DB: { case file_format_t::SQLITE_DB: {
auto bn = ghc::filesystem::path(pair.first).filename().string(); auto bn = ghc::filesystem::path(pair.first).filename().string();
if (bn.length() > this->fc_largest_path_length) { if (bn.length() > this->fc_largest_path_length) {
@ -218,8 +219,9 @@ file_collection::merge(file_collection& other)
errs->insert(new_errors.begin(), new_errors.end()); errs->insert(new_errors.begin(), new_errors.end());
} }
this->fc_file_names.insert(other.fc_file_names.begin(), for (const auto& fn_pair : other.fc_file_names) {
other.fc_file_names.end()); this->fc_file_names[fn_pair.first] = fn_pair.second;
}
if (!other.fc_files.empty()) { if (!other.fc_files.empty()) {
for (const auto& lf : other.fc_files) { for (const auto& lf : other.fc_files) {
this->fc_name_to_errors->writeAccess()->erase(lf->get_filename()); this->fc_name_to_errors->writeAccess()->erase(lf->get_filename());
@ -291,7 +293,7 @@ struct same_file {
* @param fd An already-opened descriptor for 'filename'. * @param fd An already-opened descriptor for 'filename'.
* @param required Specifies whether or not the file must exist and be valid. * @param required Specifies whether or not the file must exist and be valid.
*/ */
nonstd::optional<std::future<file_collection>> std::optional<std::future<file_collection>>
file_collection::watch_logfile(const std::string& filename, file_collection::watch_logfile(const std::string& filename,
logfile_open_options& loo, logfile_open_options& loo,
bool required) bool required)
@ -301,7 +303,7 @@ file_collection::watch_logfile(const std::string& filename,
auto filename_key = loo.loo_filename.empty() ? filename : loo.loo_filename; auto filename_key = loo.loo_filename.empty() ? filename : loo.loo_filename;
if (this->fc_closed_files.count(filename)) { if (this->fc_closed_files.count(filename)) {
return nonstd::nullopt; return std::nullopt;
} }
rc = stat(filename.c_str(), &st); rc = stat(filename.c_str(), &st);
@ -321,14 +323,14 @@ file_collection::watch_logfile(const std::string& filename,
.with_visible_size_limit(256 * 1024)); .with_visible_size_limit(256 * 1024));
return lnav::futures::make_ready_future(std::move(retval)); return lnav::futures::make_ready_future(std::move(retval));
} }
return nonstd::nullopt; return std::nullopt;
} }
if (!S_ISREG(st.st_mode)) { if (!S_ISREG(st.st_mode)) {
if (required) { if (required) {
rc = -1; rc = -1;
errno = EINVAL; errno = EINVAL;
} else { } else {
return nonstd::nullopt; return std::nullopt;
} }
} }
{ {
@ -357,7 +359,7 @@ file_collection::watch_logfile(const std::string& filename,
}); });
return lnav::futures::make_ready_future(std::move(retval)); return lnav::futures::make_ready_future(std::move(retval));
} }
return nonstd::nullopt; return std::nullopt;
} }
if (this->fc_new_stats | lnav::itertools::find_if([&st](const auto& elem) { if (this->fc_new_stats | lnav::itertools::find_if([&st](const auto& elem) {
@ -366,7 +368,7 @@ file_collection::watch_logfile(const std::string& filename,
{ {
// this file is probably a link that we have already scanned in this // this file is probably a link that we have already scanned in this
// pass. // pass.
return nonstd::nullopt; return std::nullopt;
} }
this->fc_new_stats.emplace_back(st); this->fc_new_stats.emplace_back(st);
@ -376,7 +378,7 @@ file_collection::watch_logfile(const std::string& filename,
if (file_iter == this->fc_files.end()) { if (file_iter == this->fc_files.end()) {
if (this->fc_other_files.find(filename) != this->fc_other_files.end()) { if (this->fc_other_files.find(filename) != this->fc_other_files.end()) {
return nonstd::nullopt; return std::nullopt;
} }
require(this->fc_progress.get() != nullptr); require(this->fc_progress.get() != nullptr);
@ -405,8 +407,33 @@ file_collection::watch_logfile(const std::string& filename,
retval.fc_other_files[filename].ofd_format = ff; retval.fc_other_files[filename].ofd_format = ff;
break; break;
case file_format_t::MULTIPLEXED: {
log_info("%s: file is multiplexed, creating piper",
filename.c_str());
auto open_res
= lnav::filesystem::open_file(filename, O_RDONLY);
if (open_res.isOk()) {
auto looper_options = lnav::piper::options{};
looper_options.with_tail(loo.loo_tail);
auto create_res
= lnav::piper::create_looper(filename,
open_res.unwrap(),
auto_fd{-1},
looper_options);
if (create_res.isOk()) {
retval.fc_other_files[filename] = ff;
retval.fc_file_names[filename] = loo;
retval.fc_file_names[filename].with_piper(
create_res.unwrap());
}
}
break;
}
case file_format_t::ARCHIVE: { case file_format_t::ARCHIVE: {
nonstd::optional< std::optional<
std::list<archive_manager::extract_progress>::iterator> std::list<archive_manager::extract_progress>::iterator>
prog_iter_opt; prog_iter_opt;
@ -530,6 +557,12 @@ file_collection::watch_logfile(const std::string& filename,
log_info("loading new file: filename=%s", filename.c_str()); log_info("loading new file: filename=%s", filename.c_str());
if (loo.loo_piper && !loo.loo_piper->get_demux_id().empty())
{
log_info(" treating demuxed file as a log");
loo.loo_text_format = text_format_t::TF_LOG;
}
auto open_res = logfile::open(filename_to_open, loo); auto open_res = logfile::open(filename_to_open, loo);
if (open_res.isOk()) { if (open_res.isOk()) {
retval.fc_files.push_back(open_res.unwrap()); retval.fc_files.push_back(open_res.unwrap());
@ -563,7 +596,7 @@ file_collection::watch_logfile(const std::string& filename,
return lnav::futures::make_ready_future(std::move(retval)); return lnav::futures::make_ready_future(std::move(retval));
} }
return nonstd::nullopt; return std::nullopt;
} }
/** /**

@ -92,7 +92,7 @@ enum class child_poll_result_t {
class child_poller { class child_poller {
public: public:
explicit child_poller( explicit child_poller(
nonstd::optional<std::string> filename, std::optional<std::string> filename,
auto_pid<process_state::running> child, auto_pid<process_state::running> child,
std::function<void(file_collection&, std::function<void(file_collection&,
auto_pid<process_state::finished>&)> finalizer) auto_pid<process_state::finished>&)> finalizer)
@ -126,7 +126,7 @@ public:
child_poller& operator=(const child_poller&) = delete; child_poller& operator=(const child_poller&) = delete;
const nonstd::optional<std::string>& get_filename() const const std::optional<std::string>& get_filename() const
{ {
return this->cp_filename; return this->cp_filename;
} }
@ -136,8 +136,8 @@ public:
child_poll_result_t poll(file_collection& fc); child_poll_result_t poll(file_collection& fc);
private: private:
nonstd::optional<std::string> cp_filename; std::optional<std::string> cp_filename;
nonstd::optional<auto_pid<process_state::running>> cp_child; std::optional<auto_pid<process_state::running>> cp_child;
std::function<void(file_collection&, auto_pid<process_state::finished>&)> std::function<void(file_collection&, auto_pid<process_state::finished>&)>
cp_finalizer; cp_finalizer;
}; };
@ -212,7 +212,7 @@ struct file_collection {
logfile_open_options& loo, logfile_open_options& loo,
bool required); bool required);
nonstd::optional<std::future<file_collection>> watch_logfile( std::optional<std::future<file_collection>> watch_logfile(
const std::string& filename, logfile_open_options& loo, bool required); const std::string& filename, logfile_open_options& loo, bool required);
void merge(file_collection& other); void merge(file_collection& other);

@ -37,6 +37,7 @@
#include "base/intern_string.hh" #include "base/intern_string.hh"
#include "base/lnav_log.hh" #include "base/lnav_log.hh"
#include "config.h" #include "config.h"
#include "line_buffer.hh"
file_format_t file_format_t
detect_file_format(const ghc::filesystem::path& filename) detect_file_format(const ghc::filesystem::path& filename)
@ -68,7 +69,30 @@ detect_file_format(const ghc::filesystem::path& filename)
auto header_frag = string_fragment::from_bytes(buffer, rc); auto header_frag = string_fragment::from_bytes(buffer, rc);
if (header_frag.startswith(SQLITE3_HEADER)) { if (header_frag.startswith(SQLITE3_HEADER)) {
log_info("%s: appears to be a SQLite DB", filename.c_str());
retval = file_format_t::SQLITE_DB; retval = file_format_t::SQLITE_DB;
} else {
file_range next_range;
line_buffer lb;
lb.set_fd(fd);
auto load_res = lb.load_next_line(next_range);
if (load_res.isOk() && lb.is_header_utf8()) {
auto li = load_res.unwrap();
auto read_res = lb.read_range(li.li_file_range);
if (read_res.isOk()) {
auto sbr = read_res.unwrap();
auto demux_id_opt = lnav::piper::multiplex_id_for_line(
sbr.to_string_fragment());
if (demux_id_opt) {
log_info("%s: is multiplexed using %s",
filename.c_str(),
demux_id_opt.value().c_str());
return file_format_t::MULTIPLEXED;
}
}
}
} }
} }
} }

@ -32,14 +32,16 @@
#ifndef lnav_file_format_hh #ifndef lnav_file_format_hh
#define lnav_file_format_hh #define lnav_file_format_hh
#include <optional>
#include "fmt/format.h" #include "fmt/format.h"
#include "ghc/filesystem.hpp" #include "ghc/filesystem.hpp"
#include "optional.hpp"
enum class file_format_t : int { enum class file_format_t : int {
UNKNOWN, UNKNOWN,
SQLITE_DB, SQLITE_DB,
ARCHIVE, ARCHIVE,
MULTIPLEXED,
REMOTE, REMOTE,
}; };
@ -51,7 +53,7 @@ struct external_file_format {
file_format_t detect_file_format(const ghc::filesystem::path& filename); file_format_t detect_file_format(const ghc::filesystem::path& filename);
nonstd::optional<external_file_format> detect_mime_type( std::optional<external_file_format> detect_mime_type(
const ghc::filesystem::path& filename); const ghc::filesystem::path& filename);
namespace fmt { namespace fmt {
@ -68,6 +70,9 @@ struct formatter<file_format_t> : formatter<string_view> {
case file_format_t::ARCHIVE: case file_format_t::ARCHIVE:
name = "\U0001F5C4 Archive"; name = "\U0001F5C4 Archive";
break; break;
case file_format_t::MULTIPLEXED:
name = "\u22fa Multiplexed";
break;
case file_format_t::REMOTE: case file_format_t::REMOTE:
name = "\U0001F5A5 Remote"; name = "\U0001F5A5 Remote";
break; break;

@ -89,7 +89,7 @@ file_options_collection::to_json() const
.to_string(); .to_string();
} }
nonstd::optional<std::pair<std::string, file_options>> std::optional<std::pair<std::string, file_options>>
file_options_collection::match(const std::string& path) const file_options_collection::match(const std::string& path) const
{ {
auto iter = this->foc_pattern_to_options.find(path); auto iter = this->foc_pattern_to_options.find(path);
@ -111,10 +111,10 @@ file_options_collection::match(const std::string& path) const
} }
} }
return nonstd::nullopt; return std::nullopt;
} }
nonstd::optional<std::pair<std::string, file_options>> std::optional<std::pair<std::string, file_options>>
file_options_hier::match(const ghc::filesystem::path& path) const file_options_hier::match(const ghc::filesystem::path& path) const
{ {
static const auto ROOT_PATH = ghc::filesystem::path("/"); static const auto ROOT_PATH = ghc::filesystem::path("/");
@ -138,7 +138,7 @@ file_options_hier::match(const ghc::filesystem::path& path) const
} }
lookup_path = next_lookup_path; lookup_path = next_lookup_path;
} }
return nonstd::nullopt; return std::nullopt;
} }
} // namespace lnav } // namespace lnav

@ -59,7 +59,7 @@ struct file_options_collection {
std::map<std::string, file_options> foc_pattern_to_options; std::map<std::string, file_options> foc_pattern_to_options;
nonstd::optional<std::pair<std::string, file_options>> match( std::optional<std::pair<std::string, file_options>> match(
const std::string& path) const; const std::string& path) const;
std::string to_json() const; std::string to_json() const;
@ -70,7 +70,7 @@ struct file_options_hier {
foh_path_to_collection; foh_path_to_collection;
size_t foh_generation{0}; size_t foh_generation{0};
nonstd::optional<std::pair<std::string, file_options>> match( std::optional<std::pair<std::string, file_options>> match(
const ghc::filesystem::path& path) const; const ghc::filesystem::path& path) const;
}; };

@ -290,14 +290,14 @@ size_t
filter_sub_source::text_line_count() filter_sub_source::text_line_count()
{ {
return (lnav_data.ld_view_stack.top() | return (lnav_data.ld_view_stack.top() |
[](auto tc) -> nonstd::optional<size_t> { [](auto tc) -> std::optional<size_t> {
text_sub_source* tss = tc->get_sub_source(); text_sub_source* tss = tc->get_sub_source();
if (tss == nullptr) { if (tss == nullptr) {
return nonstd::nullopt; return std::nullopt;
} }
auto& fs = tss->get_filters(); auto& fs = tss->get_filters();
return nonstd::make_optional(fs.size()); return std::make_optional(fs.size());
}) })
.value_or(0); .value_or(0);
} }

@ -5,7 +5,7 @@
"description": "Periodic dumps of ram sizes", "description": "Periodic dumps of ram sizes",
"regex": { "regex": {
"std": { "std": {
"pattern": "========== Start of cloudvm ram size dump at (?<timestamp>[^=]+) ==========(?<body>.*)" "pattern": "^========== Start of cloudvm ram size dump at (?<timestamp>[^=]+) ==========(?<body>.*)"
} }
}, },
"sample": [ "sample": [

@ -48,4 +48,5 @@ FORMAT_FILES = \
$(srcdir)/%reldir%/vmw_py_log.json \ $(srcdir)/%reldir%/vmw_py_log.json \
$(srcdir)/%reldir%/vpostgres_log.json \ $(srcdir)/%reldir%/vpostgres_log.json \
$(srcdir)/%reldir%/xmlrpc_log.json \ $(srcdir)/%reldir%/xmlrpc_log.json \
$(srcdir)/%reldir%/zookeeper_log.json \
$() $()

@ -6,22 +6,22 @@
"url": "http://www.haproxy.org/download/1.4/doc/configuration.txt", "url": "http://www.haproxy.org/download/1.4/doc/configuration.txt",
"regex": { "regex": {
"event_started": { "event_started": {
"pattern": "(?<timestamp>\\w{3} \\d{2} \\d{2}:\\d{2}:\\d{2}) (?<logging_host>[^ ]+) (?<process_name>\\w+)\\[(?<pid>\\d+)\\]: Proxy (?<frontend_name>[^ ]+) started." "pattern": "^(?<timestamp>\\w{3} \\d{2} \\d{2}:\\d{2}:\\d{2}) (?<logging_host>[^ ]+) (?<process_name>\\w+)\\[(?<pid>\\d+)\\]: Proxy (?<frontend_name>[^ ]+) started."
}, },
"event_stopping": { "event_stopping": {
"pattern": "(?<timestamp>\\w{3} \\d{2} \\d{2}:\\d{2}:\\d{2}) (?<logging_host>[^ ]+) (?<process_name>\\w+)\\[(?<pid>\\d+)\\]: Stopping frontend (?<frontend_name>[^ ]+) in (?<stopping_timeout>\\d+) ms." "pattern": "^(?<timestamp>\\w{3} \\d{2} \\d{2}:\\d{2}:\\d{2}) (?<logging_host>[^ ]+) (?<process_name>\\w+)\\[(?<pid>\\d+)\\]: Stopping frontend (?<frontend_name>[^ ]+) in (?<stopping_timeout>\\d+) ms."
}, },
"event_stopped": { "event_stopped": {
"pattern": "(?<timestamp>\\w{3} \\d{2} \\d{2}:\\d{2}:\\d{2}) (?<logging_host>[^ ]+) (?<process_name>\\w+)\\[(?<pid>\\d+)\\]: Proxy (?<frontend_name>[^ ]+) stopped \\(FE: (?<frontend_connections>\\d+) conns, BE: (?<backend_connections>\\d+) conns\\)." "pattern": "^(?<timestamp>\\w{3} \\d{2} \\d{2}:\\d{2}:\\d{2}) (?<logging_host>[^ ]+) (?<process_name>\\w+)\\[(?<pid>\\d+)\\]: Proxy (?<frontend_name>[^ ]+) stopped \\(FE: (?<frontend_connections>\\d+) conns, BE: (?<backend_connections>\\d+) conns\\)."
}, },
"tcp": { "tcp": {
"pattern": "(?<timestamp>\\w{3} \\d{2} \\d{2}:\\d{2}:\\d{2}) (?<logging_host>[^ ]+) (?<process_name>\\w+)\\[(?<pid>\\d+)\\]: (?<client_ip>[^:]+):(?<client_port>\\d+) \\[(?<accept_date>\\d{2}\\/\\w{3}\\/\\d{4}:\\d{2}:\\d{2}:\\d{2}.\\d{3})\\] (?<frontend_name>[^ ]+) (?<backend_name>[^ ]+)\\/(?<server_name>[^ ]+) (?<tw>\\d+)\\/(?<tc>\\d+)\\/(?<tt>\\d+) (?<bytes_read>\\d+) (?<termination_state>..) (?<actconn>\\d+)\\/(?<feconn>\\d+)\\/(?<beconn>\\d+)\\/(?<srv_conn>\\d+)\\/(?<retries>\\d+) (?<srv_queue>\\d+)\\/(?<backend_queue>\\d+)" "pattern": "^(?<timestamp>\\w{3} \\d{2} \\d{2}:\\d{2}:\\d{2}) (?<logging_host>[^ ]+) (?<process_name>\\w+)\\[(?<pid>\\d+)\\]: (?<client_ip>[^:]+):(?<client_port>\\d+) \\[(?<accept_date>\\d{2}\\/\\w{3}\\/\\d{4}:\\d{2}:\\d{2}:\\d{2}.\\d{3})\\] (?<frontend_name>[^ ]+) (?<backend_name>[^ ]+)\\/(?<server_name>[^ ]+) (?<tw>\\d+)\\/(?<tc>\\d+)\\/(?<tt>\\d+) (?<bytes_read>\\d+) (?<termination_state>..) (?<actconn>\\d+)\\/(?<feconn>\\d+)\\/(?<beconn>\\d+)\\/(?<srv_conn>\\d+)\\/(?<retries>\\d+) (?<srv_queue>\\d+)\\/(?<backend_queue>\\d+)"
}, },
"http": { "http": {
"pattern": "(?<timestamp>\\w{3} \\d{2} \\d{2}:\\d{2}:\\d{2}) (?<logging_host>[^ ]+) (?<process_name>\\w+)\\[(?<pid>\\d+)\\]: (?<client_ip>[^:]+):(?<client_port>\\d+) \\[(?<accept_date>\\d{2}\\/\\w{3}\\/\\d{4}:\\d{2}:\\d{2}:\\d{2}.\\d{3})\\] (?<frontend_name>[^ ]+)(?<ssl>~)? (?<backend_name>[^ ]+)\\/(?<server_name>[^ ]+) (?<tq>-?\\d+)\\/(?<tw>-?\\d+)\\/(?<tc>-?\\d+)\\/(?<tr>-?\\d+)\\/(?<tt>\\d+) (?<status_code>\\d{3}|-1) (?<bytes_read>\\d+) (?<captured_request_cookie>.*) (?<captured_response_cookie>.*) (?<termination_state>....) (?<actconn>\\d+)\\/(?<feconn>\\d+)\\/(?<beconn>\\d+)\\/(?<srv_conn>\\d+)\\/(?<retries>\\d+) (?<srv_queue>\\d+)\\/(?<backend_queue>\\d+) (?:\\{(?<captured_request_headers>.*)\\} \\{(?<captured_response_headers>.*)\\} )?\"(?<http_method>[A-Z<>]+)(?: (?<http_url>.*?))?(?: (?<http_version>HTTP\\/\\d+.\\d+))?\"?$" "pattern": "^(?<timestamp>\\w{3} \\d{2} \\d{2}:\\d{2}:\\d{2}) (?<logging_host>[^ ]+) (?<process_name>\\w+)\\[(?<pid>\\d+)\\]: (?<client_ip>[^:]+):(?<client_port>\\d+) \\[(?<accept_date>\\d{2}\\/\\w{3}\\/\\d{4}:\\d{2}:\\d{2}:\\d{2}.\\d{3})\\] (?<frontend_name>[^ ]+)(?<ssl>~)? (?<backend_name>[^ ]+)\\/(?<server_name>[^ ]+) (?<tq>-?\\d+)\\/(?<tw>-?\\d+)\\/(?<tc>-?\\d+)\\/(?<tr>-?\\d+)\\/(?<tt>\\d+) (?<status_code>\\d{3}|-1) (?<bytes_read>\\d+) (?<captured_request_cookie>.*) (?<captured_response_cookie>.*) (?<termination_state>....) (?<actconn>\\d+)\\/(?<feconn>\\d+)\\/(?<beconn>\\d+)\\/(?<srv_conn>\\d+)\\/(?<retries>\\d+) (?<srv_queue>\\d+)\\/(?<backend_queue>\\d+) (?:\\{(?<captured_request_headers>.*)\\} \\{(?<captured_response_headers>.*)\\} )?\"(?<http_method>[A-Z<>]+)(?: (?<http_url>.*?))?(?: (?<http_version>HTTP\\/\\d+.\\d+))?\"?$"
}, },
"ssl": { "ssl": {
"pattern": "(?<timestamp>\\w{3} \\d{2} \\d{2}:\\d{2}:\\d{2}) (?<logging_host>[^ ]+) (?<process_name>\\w+)\\[(?<pid>\\d+)\\]: (?<client_ip>[^:]+):(?<client_port>\\d+) \\[(?<accept_date>\\d{2}\\/\\w{3}\\/\\d{4}:\\d{2}:\\d{2}:\\d{2}.\\d{3})\\] (?<backend_name>[^ ]+)\\/(?<server_name>[^ ]+): (?<ssl_error>.+)$" "pattern": "^(?<timestamp>\\w{3} \\d{2} \\d{2}:\\d{2}:\\d{2}) (?<logging_host>[^ ]+) (?<process_name>\\w+)\\[(?<pid>\\d+)\\]: (?<client_ip>[^:]+):(?<client_port>\\d+) \\[(?<accept_date>\\d{2}\\/\\w{3}\\/\\d{4}:\\d{2}:\\d{2}:\\d{2}.\\d{3})\\] (?<backend_name>[^ ]+)\\/(?<server_name>[^ ]+): (?<ssl_error>.+)$"
} }
}, },
"json": false, "json": false,

@ -8,7 +8,7 @@
], ],
"regex": { "regex": {
"std": { "std": {
"pattern": "(?<timestamp>\\w{3}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{3}) \\[(?<thread>[^\\]]+)\\] (?<level>[^ ]+)\\s+(?<module>[^ ]+) - (?<body>.*)" "pattern": "^(?<timestamp>\\w{3}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{3}) \\[(?<thread>[^\\]]+)\\] (?<level>[^ ]+)\\s+(?<module>[^ ]+) - (?<body>.*)"
} }
}, },
"timestamp-format": [ "timestamp-format": [

@ -5,7 +5,7 @@
"description": "Periodic dumps of process state", "description": "Periodic dumps of process state",
"regex": { "regex": {
"std": { "std": {
"pattern": "========== Start of system state dump at (?<timestamp>[^=]+) ==========(?<body>.*)" "pattern": "^========== Start of system state dump at (?<timestamp>[^=]+) ==========(?<body>.*)"
} }
}, },
"sample": [ "sample": [

@ -9,13 +9,13 @@
"description": "The Redis database", "description": "The Redis database",
"regex": { "regex": {
"v2.x": { "v2.x": {
"pattern": "\\[(?<pid>\\d+)\\]\\s+(?<timestamp>\\d{1,2} [a-zA-Z]{3} \\d{2}:\\d{2}:\\d{2}\\.\\d{3})\\s+(?<level>[\\.\\-\\*\\#])\\s+(?<body>.*)" "pattern": "^\\[(?<pid>\\d+)\\]\\s+(?<timestamp>\\d{1,2} [a-zA-Z]{3} \\d{2}:\\d{2}:\\d{2}\\.\\d{3})\\s+(?<level>[\\.\\-\\*\\#])\\s+(?<body>.*)"
}, },
"v3.x": { "v3.x": {
"pattern": "(?<pid>\\d+):(?<role>[XCSM])\\s+(?<timestamp>\\d{1,2} [a-zA-Z]{3} \\d{4} \\d{2}:\\d{2}:\\d{2}\\.\\d{3})\\s+(?<level>[\\.\\*\\#\\-])\\s+(?<body>.*)" "pattern": "^(?<pid>\\d+):(?<role>[XCSM])\\s+(?<timestamp>\\d{1,2} [a-zA-Z]{3} \\d{4} \\d{2}:\\d{2}:\\d{2}\\.\\d{3})\\s+(?<level>[\\.\\*\\#\\-])\\s+(?<body>.*)"
}, },
"sig": { "sig": {
"pattern": "(?<pid>\\d+):(?<role>signal-handler) \\((?<timestamp>\\d+)\\) (?<body>.*)" "pattern": "^(?<pid>\\d+):(?<role>signal-handler) \\((?<timestamp>\\d+)\\) (?<body>.*)"
} }
}, },
"timestamp-format": [ "timestamp-format": [

@ -0,0 +1,44 @@
{
"$schema": "https://lnav.org/schemas/format-v1.schema.json",
"zookeeper_log": {
"title": "ZooKeeper log format",
"description": "Log format for the ZooKeeper coordination service",
"regex": {
"std": {
"pattern": "^(?<timestamp>\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2},\\d{3}) \\[myid:(?<myid>\\d+)?\\] - (?<level>\\w+)\\s+\\[(?<thread>.*):(?<logger>[\\w\\.\\$]+)@(?<line_number>\\d+)\\] - (?<body>.*)"
}
},
"value": {
"thread": {
"kind": "string",
"identifier": true
},
"level": {
"kind": "string"
},
"myid": {
"kind": "integer",
"identifier": true
},
"logger": {
"kind": "string",
"identifier": true
},
"line_number": {
"kind": "integer",
"foreign-key": true
}
},
"search-table": {
"zk_notifications": {
"level": "info",
"pattern": "Notification: my state:(?<my_state>\\w+); (?<nvalues>.*)"
}
},
"sample": [
{
"line": "2024-04-23 09:24:31,484 [myid:] - INFO [WorkerReceiver[myid=3]:o.a.z.s.q.FastLeaderElection$Messenger$WorkerReceiver@391] - Notification: my state:FOLLOWING; n.sid:1, n.state:LOOKING, n.leader:2, n.round:0x1, n.peerEpoch:0x1, n.zxid:0x100000057, message format version:0x2, n.config version:0x0"
}
]
}
}

@ -101,18 +101,18 @@ sql_dirname(const char* path_in)
return path_in[0] == '/' ? "/" : "."; return path_in[0] == '/' ? "/" : ".";
} }
static nonstd::optional<std::string> static std::optional<std::string>
sql_joinpath(const std::vector<const char*>& paths) sql_joinpath(const std::vector<const char*>& paths)
{ {
std::string full_path; std::string full_path;
if (paths.empty()) { if (paths.empty()) {
return nonstd::nullopt; return std::nullopt;
} }
for (auto& path_in : paths) { for (auto& path_in : paths) {
if (path_in == nullptr) { if (path_in == nullptr) {
return nonstd::nullopt; return std::nullopt;
} }
if (path_in[0] == '/' || path_in[0] == '\\') { if (path_in[0] == '/' || path_in[0] == '\\') {
@ -168,7 +168,7 @@ sql_realpath(const char* path)
} }
struct shell_exec_options { struct shell_exec_options {
std::map<std::string, nonstd::optional<std::string>> po_env; std::map<std::string, std::optional<std::string>> po_env;
}; };
static const json_path_container shell_exec_env_handlers = { static const json_path_container shell_exec_env_handlers = {
@ -183,8 +183,8 @@ static const typed_json_path_container<shell_exec_options>
static blob_auto_buffer static blob_auto_buffer
sql_shell_exec(const char* cmd, sql_shell_exec(const char* cmd,
nonstd::optional<string_fragment> input, std::optional<string_fragment> input,
nonstd::optional<string_fragment> opts_json) std::optional<string_fragment> opts_json)
{ {
static const intern_string_t SRC = intern_string::lookup("options"); static const intern_string_t SRC = intern_string::lookup("options");

@ -324,7 +324,7 @@ gantt_header_overlay::list_value_for_overlay(
VC_STYLE.value(ta_under)); VC_STYLE.value(ta_under));
} }
} }
nonstd::optional<attr_line_t> std::optional<attr_line_t>
gantt_header_overlay::list_header_for_overlay(const listview_curses& lv, gantt_header_overlay::list_header_for_overlay(const listview_curses& lv,
vis_line_t line) vis_line_t line)
{ {
@ -659,7 +659,7 @@ gantt_source::rebuild_indexes()
continue; continue;
} }
for (const auto sbr : {&sbr_opid, &sbr_desc}) { for (const auto sbr : {&sbr_opid, &sbr_desc}) {
if (filt->matches(nonstd::nullopt, *sbr)) { if (filt->matches(std::nullopt, *sbr)) {
this->gs_filter_hits[filt->get_index()] += 1; this->gs_filter_hits[filt->get_index()] += 1;
switch (filt->get_type()) { switch (filt->get_type()) {
case text_filter::INCLUDE: case text_filter::INCLUDE:
@ -731,13 +731,13 @@ gantt_source::rebuild_indexes()
this->tss_view->set_needs_update(); this->tss_view->set_needs_update();
} }
nonstd::optional<vis_line_t> std::optional<vis_line_t>
gantt_source::row_for_time(struct timeval time_bucket) gantt_source::row_for_time(struct timeval time_bucket)
{ {
auto iter = this->gs_time_order.begin(); auto iter = this->gs_time_order.begin();
while (true) { while (true) {
if (iter == this->gs_time_order.end()) { if (iter == this->gs_time_order.end()) {
return nonstd::nullopt; return std::nullopt;
} }
if (iter->get().or_value.otr_range.contains_inclusive(time_bucket)) { if (iter->get().or_value.otr_range.contains_inclusive(time_bucket)) {
@ -778,11 +778,11 @@ gantt_source::row_for_time(struct timeval time_bucket)
return vis_line_t(std::distance(this->gs_time_order.begin(), closest_iter)); return vis_line_t(std::distance(this->gs_time_order.begin(), closest_iter));
} }
nonstd::optional<text_time_translator::row_info> std::optional<text_time_translator::row_info>
gantt_source::time_for_row(vis_line_t row) gantt_source::time_for_row(vis_line_t row)
{ {
if (row >= this->gs_time_order.size()) { if (row >= this->gs_time_order.size()) {
return nonstd::nullopt; return std::nullopt;
} }
const auto& otr = this->gs_time_order[row].get().or_value; const auto& otr = this->gs_time_order[row].get().or_value;
@ -838,7 +838,7 @@ gantt_source::text_selection_changed(textview_curses& tc)
high_tv.tv_sec += 1; high_tv.tv_sec += 1;
auto low_vl = this->gs_lss.row_for_time(low_tv); auto low_vl = this->gs_lss.row_for_time(low_tv);
auto high_vl = this->gs_lss.row_for_time(high_tv).value_or( auto high_vl = this->gs_lss.row_for_time(high_tv).value_or(
this->gs_lss.text_line_count()); vis_line_t(this->gs_lss.text_line_count()));
if (!low_vl) { if (!low_vl) {
return; return;

@ -72,9 +72,9 @@ public:
void text_crumbs_for_line(int line, void text_crumbs_for_line(int line,
std::vector<breadcrumb::crumb>& crumbs) override; std::vector<breadcrumb::crumb>& crumbs) override;
nonstd::optional<vis_line_t> row_for_time( std::optional<vis_line_t> row_for_time(
struct timeval time_bucket) override; struct timeval time_bucket) override;
nonstd::optional<row_info> time_for_row(vis_line_t row) override; std::optional<row_info> time_for_row(vis_line_t row) override;
void rebuild_indexes(); void rebuild_indexes();
@ -174,7 +174,7 @@ public:
int bottom, int bottom,
attr_line_t& value_out) override; attr_line_t& value_out) override;
nonstd::optional<attr_line_t> list_header_for_overlay( std::optional<attr_line_t> list_header_for_overlay(
const listview_curses& lv, vis_line_t line) override; const listview_curses& lv, vis_line_t line) override;
void list_value_for_overlay(const listview_curses& lv, void list_value_for_overlay(const listview_curses& lv,

@ -33,7 +33,7 @@
#include "config.h" #include "config.h"
#include "fmt/chrono.h" #include "fmt/chrono.h"
nonstd::optional<vis_line_t> std::optional<vis_line_t>
hist_source2::row_for_time(struct timeval tv_bucket) hist_source2::row_for_time(struct timeval tv_bucket)
{ {
std::map<int64_t, struct bucket_block>::iterator iter; std::map<int64_t, struct bucket_block>::iterator iter;
@ -176,11 +176,11 @@ hist_source2::end_of_row()
} }
} }
nonstd::optional<text_time_translator::row_info> std::optional<text_time_translator::row_info>
hist_source2::time_for_row(vis_line_t row) hist_source2::time_for_row(vis_line_t row)
{ {
if (row < 0 || row > this->hs_line_count) { if (row < 0 || row > this->hs_line_count) {
return nonstd::nullopt; return std::nullopt;
} }
bucket_t& bucket = this->find_bucket(row); bucket_t& bucket = this->find_bucket(row);

@ -411,9 +411,9 @@ public:
return 0; return 0;
} }
nonstd::optional<row_info> time_for_row(vis_line_t row) override; std::optional<row_info> time_for_row(vis_line_t row) override;
nonstd::optional<vis_line_t> row_for_time( std::optional<vis_line_t> row_for_time(
struct timeval tv_bucket) override; struct timeval tv_bucket) override;
private: private:

@ -74,7 +74,7 @@ to_key_seq(A& dst, const char* src)
void void
input_dispatcher::new_input(const struct timeval& current_time, int ch) input_dispatcher::new_input(const struct timeval& current_time, int ch)
{ {
nonstd::optional<bool> handled = nonstd::nullopt; std::optional<bool> handled = std::nullopt;
std::array<char, 32 * 3 + 1> keyseq{0}; std::array<char, 32 * 3 + 1> keyseq{0};
switch (ch) { switch (ch) {

@ -43,7 +43,7 @@ namespace details {
template<typename F> template<typename F>
struct similar_to { struct similar_to {
nonstd::optional<F> st_mapper; std::optional<F> st_mapper;
std::string st_pattern; std::string st_pattern;
size_t st_count{5}; size_t st_count{5};
}; };

@ -490,7 +490,7 @@ concat_gen_elements(yajl_gen gen, const unsigned char* text, size_t len)
} }
static json_string static json_string
json_concat(nonstd::optional<const char*> json_in, json_concat(std::optional<const char*> json_in,
const std::vector<sqlite3_value*>& values) const std::vector<sqlite3_value*>& values)
{ {
yajlpp_gen gen; yajlpp_gen gen;

@ -768,13 +768,13 @@ line_buffer::fill_range(file_off_t start, ssize_t max_length)
start, start,
this->lb_loader_file_offset.value()); this->lb_loader_file_offset.value());
#endif #endif
nonstd::optional<std::chrono::system_clock::time_point> wait_start; std::optional<std::chrono::system_clock::time_point> wait_start;
if (this->lb_loader_future.wait_for(std::chrono::seconds(0)) if (this->lb_loader_future.wait_for(std::chrono::seconds(0))
!= std::future_status::ready) != std::future_status::ready)
{ {
wait_start wait_start
= nonstd::make_optional(std::chrono::system_clock::now()); = std::make_optional(std::chrono::system_clock::now());
} }
retval = this->lb_loader_future.get(); retval = this->lb_loader_future.get();
if (false && wait_start) { if (false && wait_start) {
@ -785,7 +785,7 @@ line_buffer::fill_range(file_off_t start, ssize_t max_length)
this->lb_loader_future = {}; this->lb_loader_future = {};
this->lb_share_manager.invalidate_refs(); this->lb_share_manager.invalidate_refs();
this->lb_file_offset = this->lb_loader_file_offset.value(); this->lb_file_offset = this->lb_loader_file_offset.value();
this->lb_loader_file_offset = nonstd::nullopt; this->lb_loader_file_offset = std::nullopt;
this->lb_buffer.swap(this->lb_alt_buffer.value()); this->lb_buffer.swap(this->lb_alt_buffer.value());
this->lb_alt_buffer.value().clear(); this->lb_alt_buffer.value().clear();
this->lb_line_starts = std::move(this->lb_alt_line_starts); this->lb_line_starts = std::move(this->lb_alt_line_starts);

@ -345,12 +345,12 @@ private:
file_ssize_t lb_piper_header_size{0}; file_ssize_t lb_piper_header_size{0};
auto_buffer lb_buffer{auto_buffer::alloc(DEFAULT_LINE_BUFFER_SIZE)}; auto_buffer lb_buffer{auto_buffer::alloc(DEFAULT_LINE_BUFFER_SIZE)};
nonstd::optional<auto_buffer> lb_alt_buffer; std::optional<auto_buffer> lb_alt_buffer;
std::vector<uint32_t> lb_alt_line_starts; std::vector<uint32_t> lb_alt_line_starts;
std::vector<bool> lb_alt_line_is_utf; std::vector<bool> lb_alt_line_is_utf;
std::vector<bool> lb_alt_line_has_ansi; std::vector<bool> lb_alt_line_has_ansi;
std::future<bool> lb_loader_future; std::future<bool> lb_loader_future;
nonstd::optional<file_off_t> lb_loader_file_offset; std::optional<file_off_t> lb_loader_file_offset;
file_off_t lb_compressed_offset{ file_off_t lb_compressed_offset{
0}; /*< The offset into the compressed file. */ 0}; /*< The offset into the compressed file. */
@ -375,7 +375,7 @@ private:
std::vector<bool> lb_line_has_ansi; std::vector<bool> lb_line_has_ansi;
stats lb_stats; stats lb_stats;
nonstd::optional<auto_fd> lb_cached_fd; std::optional<auto_fd> lb_cached_fd;
file_header_t lb_header{mapbox::util::no_init{}}; file_header_t lb_header{mapbox::util::no_init{}};
}; };

@ -1180,7 +1180,7 @@ listview_curses::get_overlay_height(size_t total, vis_line_t view_height)
} }
void void
listview_curses::set_overlay_selection(nonstd::optional<vis_line_t> sel) listview_curses::set_overlay_selection(std::optional<vis_line_t> sel)
{ {
if (sel) { if (sel) {
if (sel.value() == this->lv_focused_overlay_selection) { if (sel.value() == this->lv_focused_overlay_selection) {

@ -120,10 +120,10 @@ public:
return {}; return {};
} }
virtual nonstd::optional<attr_line_t> list_header_for_overlay( virtual std::optional<attr_line_t> list_header_for_overlay(
const listview_curses& lv, vis_line_t line) const listview_curses& lv, vis_line_t line)
{ {
return nonstd::nullopt; return std::nullopt;
} }
virtual void list_value_for_overlay(const listview_curses& lv, virtual void list_value_for_overlay(const listview_curses& lv,
@ -250,16 +250,16 @@ public:
return this->lv_top; return this->lv_top;
} }
nonstd::optional<vis_line_t> get_overlay_selection() const std::optional<vis_line_t> get_overlay_selection() const
{ {
if (this->lv_overlay_focused) { if (this->lv_overlay_focused) {
return this->lv_focused_overlay_selection; return this->lv_focused_overlay_selection;
} }
return nonstd::nullopt; return std::nullopt;
} }
void set_overlay_selection(nonstd::optional<vis_line_t> sel); void set_overlay_selection(std::optional<vis_line_t> sel);
void set_sync_selection_and_top(bool value) void set_sync_selection_and_top(bool value)
{ {
@ -299,7 +299,7 @@ public:
typename std::result_of<F(const attr_line_t&)>::type typename std::result_of<F(const attr_line_t&)>::type
{ {
if (this->lv_top >= this->get_inner_height()) { if (this->lv_top >= this->get_inner_height()) {
return nonstd::nullopt; return std::nullopt;
} }
std::vector<attr_line_t> top_line{1}; std::vector<attr_line_t> top_line{1};
@ -328,10 +328,10 @@ public:
/** @return The line number that is displayed at the top. */ /** @return The line number that is displayed at the top. */
vis_line_t get_top() const { return this->lv_top; } vis_line_t get_top() const { return this->lv_top; }
nonstd::optional<vis_line_t> get_top_opt() const std::optional<vis_line_t> get_top_opt() const
{ {
if (this->get_inner_height() == 0_vl) { if (this->get_inner_height() == 0_vl) {
return nonstd::nullopt; return std::nullopt;
} }
return this->lv_top; return this->lv_top;

@ -702,7 +702,7 @@ handle_config_ui_key(int ch, const char* keyseq)
return retval; return retval;
} }
nonstd::optional<ln_mode_t> new_mode; std::optional<ln_mode_t> new_mode;
lnav_data.ld_filter_help_status_source.fss_error.clear(); lnav_data.ld_filter_help_status_source.fss_error.clear();
if (ch == 'F') { if (ch == 'F') {
@ -868,7 +868,7 @@ gather_pipers()
} }
void void
wait_for_pipers(nonstd::optional<timeval> deadline) wait_for_pipers(std::optional<timeval> deadline)
{ {
static const auto MAX_SLEEP_TIME = std::chrono::milliseconds(300); static const auto MAX_SLEEP_TIME = std::chrono::milliseconds(300);
auto sleep_time = std::chrono::milliseconds(10); auto sleep_time = std::chrono::milliseconds(10);
@ -3108,7 +3108,8 @@ SELECT tbl_name FROM sqlite_master WHERE sql LIKE 'CREATE VIRTUAL TABLE%'
} else { } else {
lnav_data.ld_active_files.fc_file_names.emplace( lnav_data.ld_active_files.fc_file_names.emplace(
abspath.in(), abspath.in(),
logfile_open_options().with_init_location(file_loc)); logfile_open_options().with_init_location(file_loc).with_tail(
!(lnav_data.ld_flags & LNF_HEADLESS)));
if (file_loc.valid()) { if (file_loc.valid()) {
lnav_data.ld_files_to_front.emplace_back(abspath.in(), lnav_data.ld_files_to_front.emplace_back(abspath.in(),
file_loc); file_loc);
@ -3196,7 +3197,7 @@ SELECT tbl_name FROM sqlite_master WHERE sql LIKE 'CREATE VIRTUAL TABLE%'
retval = EXIT_FAILURE; retval = EXIT_FAILURE;
} }
nonstd::optional<std::string> stdin_url; std::optional<std::string> stdin_url;
ghc::filesystem::path stdin_dir; ghc::filesystem::path stdin_dir;
if (load_stdin && !isatty(STDIN_FILENO) && !is_dev_null(STDIN_FILENO) if (load_stdin && !isatty(STDIN_FILENO) && !is_dev_null(STDIN_FILENO)
&& !exec_stdin) && !exec_stdin)

@ -293,6 +293,6 @@ extern const ssize_t ZOOM_COUNT;
bool setup_logline_table(exec_context& ec); bool setup_logline_table(exec_context& ec);
void wait_for_children(); void wait_for_children();
void wait_for_pipers(nonstd::optional<timeval> deadline = nonstd::nullopt); void wait_for_pipers(std::optional<timeval> deadline = std::nullopt);
#endif #endif

@ -200,7 +200,7 @@ public:
}; };
rebuild_indexes_result_t rebuild_indexes_result_t
rebuild_indexes(nonstd::optional<ui_clock::time_point> deadline) rebuild_indexes(std::optional<ui_clock::time_point> deadline)
{ {
logfile_sub_source& lss = lnav_data.ld_log_source; logfile_sub_source& lss = lnav_data.ld_log_source;
textview_curses& log_view = lnav_data.ld_views[LNV_LOG]; textview_curses& log_view = lnav_data.ld_views[LNV_LOG];
@ -247,7 +247,7 @@ rebuild_indexes(nonstd::optional<ui_clock::time_point> deadline)
tss->to_front(cb.front_file); tss->to_front(cb.front_file);
} }
nonstd::optional<vis_line_t> new_top_opt; std::optional<vis_line_t> new_top_opt;
cb.front_top.match( cb.front_top.match(
[&new_top_opt](vis_line_t vl) { [&new_top_opt](vis_line_t vl) {
log_info("file open request to jump to line: %d", (int) vl); log_info("file open request to jump to line: %d", (int) vl);

@ -32,7 +32,6 @@
#include "file_collection.hh" #include "file_collection.hh"
#include "logfile_fwd.hh" #include "logfile_fwd.hh"
#include "optional.hpp"
void rebuild_hist(); void rebuild_hist();
@ -42,7 +41,7 @@ struct rebuild_indexes_result_t {
}; };
rebuild_indexes_result_t rebuild_indexes( rebuild_indexes_result_t rebuild_indexes(
nonstd::optional<ui_clock::time_point> deadline = nonstd::nullopt); std::optional<ui_clock::time_point> deadline = std::nullopt);
void rebuild_indexes_repeatedly(); void rebuild_indexes_repeatedly();
bool rescan_files(bool required = false); bool rescan_files(bool required = false);
bool update_active_files(file_collection& new_files); bool update_active_files(file_collection& new_files);

@ -59,10 +59,16 @@ struct no_subcmd_t {
CLI::App* ns_root_app{nullptr}; CLI::App* ns_root_app{nullptr};
}; };
static auto DEFAULT_WRAPPING
= text_wrap_settings{}.with_padding_indent(4).with_width(60);
inline attr_line_t& inline attr_line_t&
symbol_reducer(const std::string& elem, attr_line_t& accum) symbol_reducer(const std::string& elem, attr_line_t& accum)
{ {
return accum.append("\n ").append(lnav::roles::symbol(elem)); if (!accum.empty()) {
accum.append(", ");
}
return accum.append(lnav::roles::symbol(elem));
} }
inline attr_line_t& inline attr_line_t&
@ -209,7 +215,8 @@ struct subcmd_format_t {
| lnav::itertools::sort_with(intern_string_t::case_lt) | lnav::itertools::sort_with(intern_string_t::case_lt)
| lnav::itertools::map(&intern_string_t::to_string) | lnav::itertools::map(&intern_string_t::to_string)
| lnav::itertools::fold(symbol_reducer, attr_line_t{})) | lnav::itertools::fold(symbol_reducer, attr_line_t{}))
.add_header("the available formats are:")); .add_header("the available formats are: ")
.wrap_with(&DEFAULT_WRAPPING));
return Err(um); return Err(um);
} }
@ -225,7 +232,8 @@ struct subcmd_format_t {
| lnav::itertools::similar_to(this->sf_name) | lnav::itertools::similar_to(this->sf_name)
| lnav::itertools::map(&intern_string_t::to_string) | lnav::itertools::map(&intern_string_t::to_string)
| lnav::itertools::fold(symbol_reducer, attr_line_t{})) | lnav::itertools::fold(symbol_reducer, attr_line_t{}))
.add_header("did you mean one of the following?")); .add_header("did you mean one of the following?\n")
.wrap_with(&DEFAULT_WRAPPING));
return Err(um); return Err(um);
} }
@ -265,7 +273,8 @@ struct subcmd_format_t {
| lnav::itertools::map(&external_log_format::pattern::p_name) | lnav::itertools::map(&external_log_format::pattern::p_name)
| lnav::itertools::map(&intern_string_t::to_string) | lnav::itertools::map(&intern_string_t::to_string)
| lnav::itertools::fold( | lnav::itertools::fold(
symbol_reducer, attr_line_t{"the available regexes are:"})); symbol_reducer,
attr_line_t{"the available regexes are: "}));
return Err(um); return Err(um);
} }
@ -285,7 +294,7 @@ struct subcmd_format_t {
| lnav::itertools::map(&intern_string_t::to_string) | lnav::itertools::map(&intern_string_t::to_string)
| lnav::itertools::similar_to(this->sf_regex_name) | lnav::itertools::similar_to(this->sf_regex_name)
| lnav::itertools::fold(symbol_reducer, attr_line_t{})) | lnav::itertools::fold(symbol_reducer, attr_line_t{}))
.add_header("did you mean one of the following?")); .add_header("did you mean one of the following?\n"));
return Err(um); return Err(um);
} }
@ -784,7 +793,7 @@ struct subcmd_piper_t {
continue; continue;
} }
nonstd::optional<lnav::piper::header> hdr_opt; std::optional<lnav::piper::header> hdr_opt;
auto url = fmt::format(FMT_STRING("piper://{}"), auto url = fmt::format(FMT_STRING("piper://{}"),
instance_dir.path().filename().string()); instance_dir.path().filename().string());
file_size_t total_size{0}; file_size_t total_size{0};

@ -156,7 +156,7 @@ remaining_args_frag(const std::string& cmdline,
cmdline, index_in_cmdline, cmdline.size()); cmdline, index_in_cmdline, cmdline.size());
} }
static nonstd::optional<std::string> static std::optional<std::string>
find_arg(std::vector<std::string>& args, const std::string& flag) find_arg(std::vector<std::string>& args, const std::string& flag)
{ {
auto iter = find_if(args.begin(), args.end(), [&flag](const auto elem) { auto iter = find_if(args.begin(), args.end(), [&flag](const auto elem) {
@ -164,7 +164,7 @@ find_arg(std::vector<std::string>& args, const std::string& flag)
}); });
if (iter == args.end()) { if (iter == args.end()) {
return nonstd::nullopt; return std::nullopt;
} }
auto index = iter->find('='); auto index = iter->find('=');
@ -472,7 +472,7 @@ com_set_file_timezone_prompt(exec_context& ec, const std::string& cmdline)
auto match_res = options_hier->match(pattern_arg); auto match_res = options_hier->match(pattern_arg);
if (match_res) { if (match_res) {
file_zone = match_res->second.fo_default_zone.pp_value->name(); file_zone = match_res->second.fo_default_zone.pp_value->name();
pattern_arg = match_res->first; pattern_arg = lnav::filesystem::escape_path(match_res->first);
auto new_prompt = fmt::format(FMT_STRING("{} {} {}"), auto new_prompt = fmt::format(FMT_STRING("{} {} {}"),
trim(cmdline), trim(cmdline),
@ -488,7 +488,10 @@ com_set_file_timezone_prompt(exec_context& ec, const std::string& cmdline)
} }
} }
auto arg_path = ghc::filesystem::path(pattern_arg); auto arg_path = ghc::filesystem::path(pattern_arg);
auto arg_parent = arg_path.parent_path().string() + "/"; auto arg_parent = lnav::filesystem::escape_path(arg_path.parent_path());
if (!endswith(arg_parent, "/")) {
arg_parent += "/";
}
if (elems.size() == 2 && endswith(cmdline, " ")) { if (elems.size() == 2 && endswith(cmdline, " ")) {
return {"", arg_parent}; return {"", arg_parent};
} }
@ -698,7 +701,7 @@ com_goto(exec_context& ec, std::string cmdline, std::vector<std::string>& args)
} else if (args.size() > 1) { } else if (args.size() > 1) {
std::string all_args = remaining_args(cmdline, args); std::string all_args = remaining_args(cmdline, args);
auto* tc = *lnav_data.ld_view_stack.top(); auto* tc = *lnav_data.ld_view_stack.top();
nonstd::optional<vis_line_t> dst_vl; std::optional<vis_line_t> dst_vl;
auto is_location = false; auto is_location = false;
if (startswith(all_args, "#")) { if (startswith(all_args, "#")) {
@ -1136,7 +1139,7 @@ com_goto_mark(exec_context& ec,
} }
if (!ec.ec_dry_run) { if (!ec.ec_dry_run) {
nonstd::optional<vis_line_t> new_top; std::optional<vis_line_t> new_top;
if (args[0] == "next-mark") { if (args[0] == "next-mark") {
auto search_from_top = search_forward_from(tc); auto search_from_top = search_forward_from(tc);
@ -1806,7 +1809,7 @@ com_save_to(exec_context& ec,
line_count += 1; line_count += 1;
} }
} else if (tc == &lnav_data.ld_views[LNV_LOG]) { } else if (tc == &lnav_data.ld_views[LNV_LOG]) {
nonstd::optional<std::pair<logfile*, content_line_t>> last_line; std::optional<std::pair<logfile*, content_line_t>> last_line;
bookmark_vector<vis_line_t> visited; bookmark_vector<vis_line_t> visited;
auto& lss = lnav_data.ld_log_source; auto& lss = lnav_data.ld_log_source;
std::vector<attr_line_t> rows(1); std::vector<attr_line_t> rows(1);
@ -2191,8 +2194,6 @@ com_redirect_to(exec_context& ec,
return Ok("info: output will be redirected to -- " + split_args[0]); return Ok("info: output will be redirected to -- " + split_args[0]);
} }
nonstd::optional<FILE*> file;
if (split_args[0] == "-") { if (split_args[0] == "-") {
ec.clear_output(); ec.clear_output();
} else if (split_args[0] == "/dev/clipboard") { } else if (split_args[0] == "/dev/clipboard") {
@ -3455,7 +3456,7 @@ com_close(exec_context& ec, std::string cmdline, std::vector<std::string>& args)
} }
auto* tc = *lnav_data.ld_view_stack.top(); auto* tc = *lnav_data.ld_view_stack.top();
std::vector<nonstd::optional<ghc::filesystem::path>> actual_path_v; std::vector<std::optional<ghc::filesystem::path>> actual_path_v;
std::vector<std::string> fn_v; std::vector<std::string> fn_v;
if (args.size() > 1) { if (args.size() > 1) {
@ -4075,7 +4076,7 @@ com_clear_partition(exec_context& ec,
textview_curses& tc = lnav_data.ld_views[LNV_LOG]; textview_curses& tc = lnav_data.ld_views[LNV_LOG];
logfile_sub_source& lss = lnav_data.ld_log_source; logfile_sub_source& lss = lnav_data.ld_log_source;
auto& bv = tc.get_bookmarks()[&textview_curses::BM_PARTITION]; auto& bv = tc.get_bookmarks()[&textview_curses::BM_PARTITION];
nonstd::optional<vis_line_t> part_start; std::optional<vis_line_t> part_start;
if (binary_search(bv.begin(), bv.end(), tc.get_selection())) { if (binary_search(bv.begin(), bv.end(), tc.get_selection())) {
part_start = tc.get_selection(); part_start = tc.get_selection();
@ -4757,7 +4758,7 @@ com_hide_line(exec_context& ec,
auto& lss = lnav_data.ld_log_source; auto& lss = lnav_data.ld_log_source;
date_time_scanner dts; date_time_scanner dts;
struct timeval tv_abs; struct timeval tv_abs;
nonstd::optional<timeval> tv_opt; std::optional<timeval> tv_opt;
auto parse_res = relative_time::from_str(all_args); auto parse_res = relative_time::from_str(all_args);
if (parse_res.isOk()) { if (parse_res.isOk()) {
@ -4956,7 +4957,7 @@ com_sh(exec_context& ec, std::string cmdline, std::vector<std::string>& args)
static size_t EXEC_COUNT = 0; static size_t EXEC_COUNT = 0;
if (!ec.ec_dry_run) { if (!ec.ec_dry_run) {
nonstd::optional<std::string> name_flag; std::optional<std::string> name_flag;
shlex lexer(cmdline); shlex lexer(cmdline);
auto cmd_start = args[0].size(); auto cmd_start = args[0].size();
@ -5047,7 +5048,7 @@ com_sh(exec_context& ec, std::string cmdline, std::vector<std::string>& args)
display_name = name_flag.value(); display_name = name_flag.value();
} else { } else {
display_name display_name
= fmt::format(FMT_STRING("[{}] {}"), EXEC_COUNT++, carg); = fmt::format(FMT_STRING("sh-{} {}"), EXEC_COUNT++, carg);
} }
auto name_base = display_name; auto name_base = display_name;

@ -1195,6 +1195,23 @@ static const struct json_path_container archive_handlers = {
&archive_manager::config::amc_cache_ttl), &archive_manager::config::amc_cache_ttl),
}; };
static const struct typed_json_path_container<lnav::piper::demux_def>
demux_def_handlers = {
yajlpp::property_handler("pattern")
.with_synopsis("<regex>")
.with_description(
"A regular expression to match a line in a multiplexed file")
.for_field(&lnav::piper::demux_def::dd_pattern),
};
static const struct json_path_container demux_defs_handlers = {
yajlpp::pattern_property_handler("(?<name>[\\w\\-\\.]+)")
.with_description("The definition of a demultiplexer")
.with_children(demux_def_handlers)
.for_field(&_lnav_config::lc_piper,
&lnav::piper::config::c_demux_definitions),
};
static const struct json_path_container piper_handlers = { static const struct json_path_container piper_handlers = {
yajlpp::property_handler("max-size") yajlpp::property_handler("max-size")
.with_synopsis("<bytes>") .with_synopsis("<bytes>")
@ -1450,6 +1467,9 @@ static const struct json_path_container log_source_handlers = {
.with_description("Log message watch expressions") .with_description("Log message watch expressions")
.with_children(log_source_watch_handlers), .with_children(log_source_watch_handlers),
yajlpp::property_handler("annotations").with_children(annotations_handlers), yajlpp::property_handler("annotations").with_children(annotations_handlers),
yajlpp::property_handler("demux")
.with_description("Demultiplexer definitions")
.with_children(demux_defs_handlers),
}; };
static const struct json_path_container url_scheme_handlers = { static const struct json_path_container url_scheme_handlers = {

@ -54,7 +54,6 @@
#include "base/result.h" #include "base/result.h"
#include "config.h" #include "config.h"
#include "fmt/format.h" #include "fmt/format.h"
#include "optional.hpp"
#if SIZEOF_OFF_T == 8 #if SIZEOF_OFF_T == 8
# define FORMAT_OFF_T "%lld" # define FORMAT_OFF_T "%lld"

@ -198,7 +198,7 @@ log_opid_state::sub_op_in_use(ArenaAlloc::Alloc<char>& alloc,
} }
} }
nonstd::optional<std::string> std::optional<std::string>
log_format::opid_descriptor::matches(const string_fragment& sf) const log_format::opid_descriptor::matches(const string_fragment& sf) const
{ {
if (this->od_extractor.pp_value) { if (this->od_extractor.pp_value) {
@ -213,7 +213,7 @@ log_format::opid_descriptor::matches(const string_fragment& sf) const
return desc_md.to_string(); return desc_md.to_string();
} }
return nonstd::nullopt; return std::nullopt;
} }
return sf.to_string(); return sf.to_string();
} }
@ -461,7 +461,7 @@ external_log_format::update_op_description(
const pattern* fpat, const pattern* fpat,
const lnav::pcre2pp::match_data& md) const lnav::pcre2pp::match_data& md)
{ {
nonstd::optional<std::string> desc_elem_str; std::optional<std::string> desc_elem_str;
if (!lod.lod_id) { if (!lod.lod_id) {
for (const auto& desc_def_pair : desc_defs) { for (const auto& desc_def_pair : desc_defs) {
if (lod.lod_id) { if (lod.lod_id) {
@ -529,7 +529,7 @@ external_log_format::update_op_description(
found_desc->second.append(desc_elem_str.value()); found_desc->second.append(desc_elem_str.value());
} }
} }
desc_elem_str = nonstd::nullopt; desc_elem_str = std::nullopt;
} }
} }
} }
@ -539,7 +539,7 @@ external_log_format::update_op_description(
const std::map<intern_string_t, opid_descriptors>& desc_defs, const std::map<intern_string_t, opid_descriptors>& desc_defs,
log_op_description& lod) log_op_description& lod)
{ {
nonstd::optional<std::string> desc_elem_str; std::optional<std::string> desc_elem_str;
if (!lod.lod_id) { if (!lod.lod_id) {
for (const auto& desc_def_pair : desc_defs) { for (const auto& desc_def_pair : desc_defs) {
if (lod.lod_id) { if (lod.lod_id) {
@ -594,7 +594,7 @@ external_log_format::update_op_description(
found_desc->second.append(desc_elem_str.value()); found_desc->second.append(desc_elem_str.value());
} }
} }
desc_elem_str = nonstd::nullopt; desc_elem_str = std::nullopt;
} }
} }
} }
@ -650,7 +650,7 @@ log_format::log_scanf(uint32_t line_number,
struct timeval* tv_out, struct timeval* tv_out,
string_fragment* ts_out, string_fragment* ts_out,
nonstd::optional<string_fragment>* level_out) std::optional<string_fragment>* level_out)
{ {
int curr_fmt = -1; int curr_fmt = -1;
const char* retval = nullptr; const char* retval = nullptr;
@ -794,7 +794,7 @@ struct json_log_userdata {
void add_sub_lines_for(const intern_string_t ist, void add_sub_lines_for(const intern_string_t ist,
bool top_level, bool top_level,
nonstd::optional<double> val = nonstd::nullopt, std::optional<double> val = std::nullopt,
const unsigned char* str = nullptr, const unsigned char* str = nullptr,
ssize_t len = -1) ssize_t len = -1)
{ {
@ -821,8 +821,8 @@ struct json_log_userdata {
uint32_t jlu_quality{0}; uint32_t jlu_quality{0};
shared_buffer_ref& jlu_shared_buffer; shared_buffer_ref& jlu_shared_buffer;
scan_batch_context* jlu_batch_context; scan_batch_context* jlu_batch_context;
nonstd::optional<string_fragment> jlu_opid_frag; std::optional<string_fragment> jlu_opid_frag;
nonstd::optional<std::string> jlu_subid; std::optional<std::string> jlu_subid;
struct exttm jlu_exttm; struct exttm jlu_exttm;
}; };
@ -1293,7 +1293,7 @@ external_log_format::scan(logfile& lf,
this->update_op_description(*this->lf_opid_description_def, this->update_op_description(*this->lf_opid_description_def,
otr.otr_description); otr.otr_description);
} else { } else {
this->jlf_line_values.lvv_opid_value = nonstd::nullopt; this->jlf_line_values.lvv_opid_value = std::nullopt;
} }
jlu.jlu_sub_line_count += this->jlf_line_format_init_count; jlu.jlu_sub_line_count += this->jlf_line_format_init_count;
@ -1579,7 +1579,7 @@ external_log_format::scan(logfile& lf,
} }
} }
nonstd::optional<double> dvalue_opt; std::optional<double> dvalue_opt;
switch (vd.vd_meta.lvm_kind) { switch (vd.vd_meta.lvm_kind) {
case value_kind_t::VALUE_INTEGER: { case value_kind_t::VALUE_INTEGER: {
auto scan_res = scn::scan_value<int64_t>( auto scan_res = scn::scan_value<int64_t>(
@ -1630,7 +1630,7 @@ external_log_format::scan(logfile& lf,
} }
this->lf_pattern_locks.emplace_back(lock_line, curr_fmt); this->lf_pattern_locks.emplace_back(lock_line, curr_fmt);
} }
return log_format::scan_match{0}; return log_format::scan_match{1000};
} }
if (this->lf_specialized && !this->lf_multiline) { if (this->lf_specialized && !this->lf_multiline) {
@ -1764,7 +1764,7 @@ external_log_format::annotate(uint64_t line_number,
return; return;
} }
nonstd::optional<string_fragment> module_cap; std::optional<string_fragment> module_cap;
if (!pat.p_module_format) { if (!pat.p_module_format) {
auto ts_cap = md[pat.p_timestamp_field_index]; auto ts_cap = md[pat.p_timestamp_field_index];
if (ts_cap) { if (ts_cap) {
@ -2027,7 +2027,7 @@ read_json_field(yajlpp_parse_context* ypc, const unsigned char* str, size_t len)
} }
jlu->add_sub_lines_for( jlu->add_sub_lines_for(
field_name, ypc->is_level(1), nonstd::nullopt, str, len); field_name, ypc->is_level(1), std::nullopt, str, len);
return 1; return 1;
} }
@ -2592,7 +2592,7 @@ using safe_format_header_expressions = safe::Safe<format_header_expressions>;
static safe_format_header_expressions format_header_exprs; static safe_format_header_expressions format_header_exprs;
nonstd::optional<external_file_format> std::optional<external_file_format>
detect_mime_type(const ghc::filesystem::path& filename) detect_mime_type(const ghc::filesystem::path& filename)
{ {
uint8_t buffer[1024]; uint8_t buffer[1024];
@ -2602,13 +2602,13 @@ detect_mime_type(const ghc::filesystem::path& filename)
auto_fd fd; auto_fd fd;
if ((fd = lnav::filesystem::openp(filename, O_RDONLY)) == -1) { if ((fd = lnav::filesystem::openp(filename, O_RDONLY)) == -1) {
return nonstd::nullopt; return std::nullopt;
} }
ssize_t rc; ssize_t rc;
if ((rc = read(fd, buffer, sizeof(buffer))) == -1) { if ((rc = read(fd, buffer, sizeof(buffer))) == -1) {
return nonstd::nullopt; return std::nullopt;
} }
buffer_size = rc; buffer_size = rc;
} }
@ -2713,7 +2713,7 @@ detect_mime_type(const ghc::filesystem::path& filename)
} }
} }
return nonstd::nullopt; return std::nullopt;
} }
void void
@ -3604,7 +3604,7 @@ external_log_format::build(std::vector<lnav::console::user_message>& errors)
size_t value_def_index = 0; size_t value_def_index = 0;
for (auto& elf_value_def : this->elf_value_def_order) { for (auto& elf_value_def : this->elf_value_def_order) {
elf_value_def->vd_meta.lvm_values_index elf_value_def->vd_meta.lvm_values_index
= nonstd::make_optional(value_def_index++); = std::make_optional(value_def_index++);
if (elf_value_def->vd_meta.lvm_foreign_key if (elf_value_def->vd_meta.lvm_foreign_key
|| elf_value_def->vd_meta.lvm_identifier) || elf_value_def->vd_meta.lvm_identifier)
@ -4004,7 +4004,7 @@ external_log_format::match_name(const std::string& filename)
auto auto
external_log_format::value_line_count(const intern_string_t ist, external_log_format::value_line_count(const intern_string_t ist,
bool top_level, bool top_level,
nonstd::optional<double> val, std::optional<double> val,
const unsigned char* str, const unsigned char* str,
ssize_t len) -> value_line_count_result ssize_t len) -> value_line_count_result
{ {

@ -56,7 +56,6 @@
#include "line_buffer.hh" #include "line_buffer.hh"
#include "log_format_fwd.hh" #include "log_format_fwd.hh"
#include "log_level.hh" #include "log_level.hh"
#include "optional.hpp"
#include "pcrepp/pcre2pp.hh" #include "pcrepp/pcre2pp.hh"
#include "shared_buffer.hh" #include "shared_buffer.hh"
@ -136,8 +135,8 @@ struct logline_value_meta {
logline_value_meta(intern_string_t name, logline_value_meta(intern_string_t name,
value_kind_t kind, value_kind_t kind,
column_t col = external_column{}, column_t col = external_column{},
const nonstd::optional<log_format*>& format const std::optional<log_format*>& format
= nonstd::nullopt) = std::nullopt)
: lvm_name(name), lvm_kind(kind), lvm_column(col), lvm_format(format) : lvm_name(name), lvm_kind(kind), lvm_column(col), lvm_format(format)
{ {
} }
@ -161,14 +160,14 @@ struct logline_value_meta {
intern_string_t lvm_name; intern_string_t lvm_name;
value_kind_t lvm_kind; value_kind_t lvm_kind;
column_t lvm_column{external_column{}}; column_t lvm_column{external_column{}};
nonstd::optional<size_t> lvm_values_index; std::optional<size_t> lvm_values_index;
bool lvm_identifier{false}; bool lvm_identifier{false};
bool lvm_foreign_key{false}; bool lvm_foreign_key{false};
bool lvm_hidden{false}; bool lvm_hidden{false};
nonstd::optional<bool> lvm_user_hidden; std::optional<bool> lvm_user_hidden;
bool lvm_from_module{false}; bool lvm_from_module{false};
intern_string_t lvm_struct_name; intern_string_t lvm_struct_name;
nonstd::optional<log_format*> lvm_format; std::optional<log_format*> lvm_format;
}; };
class logline_value { class logline_value {
@ -269,7 +268,7 @@ public:
value_u(int64_t i) : i(i) {} value_u(int64_t i) : i(i) {}
value_u(double d) : d(d) {} value_u(double d) : d(d) {}
} lv_value; } lv_value;
nonstd::optional<std::string> lv_str; std::optional<std::string> lv_str;
string_fragment lv_frag; string_fragment lv_frag;
int lv_sub_offset{0}; int lv_sub_offset{0};
intern_string_t lv_intern_string; intern_string_t lv_intern_string;
@ -281,7 +280,7 @@ struct logline_value_vector {
{ {
this->lvv_values.clear(); this->lvv_values.clear();
this->lvv_sbr.disown(); this->lvv_sbr.disown();
this->lvv_opid_value = nonstd::nullopt; this->lvv_opid_value = std::nullopt;
} }
logline_value_vector() {} logline_value_vector() {}
@ -303,7 +302,7 @@ struct logline_value_vector {
shared_buffer_ref lvv_sbr; shared_buffer_ref lvv_sbr;
std::vector<logline_value> lvv_values; std::vector<logline_value> lvv_values;
nonstd::optional<std::string> lvv_opid_value; std::optional<std::string> lvv_opid_value;
}; };
struct logline_value_stats { struct logline_value_stats {
@ -332,7 +331,7 @@ struct logline_value_stats {
struct logline_value_cmp { struct logline_value_cmp {
explicit logline_value_cmp( explicit logline_value_cmp(
const intern_string_t* name = nullptr, const intern_string_t* name = nullptr,
nonstd::optional<logline_value_meta::column_t> col = nonstd::nullopt) std::optional<logline_value_meta::column_t> col = std::nullopt)
: lvc_name(name), lvc_column(col) : lvc_name(name), lvc_column(col)
{ {
} }
@ -353,7 +352,7 @@ struct logline_value_cmp {
} }
const intern_string_t* lvc_name; const intern_string_t* lvc_name;
nonstd::optional<logline_value_meta::column_t> lvc_column; std::optional<logline_value_meta::column_t> lvc_column;
}; };
class log_vtab_impl; class log_vtab_impl;
@ -577,7 +576,7 @@ public:
std::vector<pattern_for_lines> lf_pattern_locks; std::vector<pattern_for_lines> lf_pattern_locks;
intern_string_t lf_timestamp_field{intern_string::lookup("timestamp", -1)}; intern_string_t lf_timestamp_field{intern_string::lookup("timestamp", -1)};
intern_string_t lf_subsecond_field; intern_string_t lf_subsecond_field;
nonstd::optional<subsecond_unit> lf_subsecond_unit; std::optional<subsecond_unit> lf_subsecond_unit;
intern_string_t lf_time_field; intern_string_t lf_time_field;
std::vector<const char*> lf_timestamp_format; std::vector<const char*> lf_timestamp_format;
unsigned int lf_timestamp_flags{0}; unsigned int lf_timestamp_flags{0};
@ -587,7 +586,7 @@ public:
bool lf_is_self_describing{false}; bool lf_is_self_describing{false};
bool lf_time_ordered{true}; bool lf_time_ordered{true};
bool lf_specialized{false}; bool lf_specialized{false};
nonstd::optional<int64_t> lf_max_unrecognized_lines; std::optional<int64_t> lf_max_unrecognized_lines;
std::map<const intern_string_t, std::shared_ptr<format_tag_def>> std::map<const intern_string_t, std::shared_ptr<format_tag_def>>
lf_tag_defs; lf_tag_defs;
@ -601,7 +600,7 @@ public:
std::string od_suffix; std::string od_suffix;
std::string od_joiner{", "}; std::string od_joiner{", "};
nonstd::optional<std::string> matches(const string_fragment& sf) const; std::optional<std::string> matches(const string_fragment& sf) const;
}; };
struct opid_descriptors { struct opid_descriptors {
@ -666,7 +665,7 @@ protected:
struct timeval* tv_out, struct timeval* tv_out,
string_fragment* ts_out, string_fragment* ts_out,
nonstd::optional<string_fragment>* level_out); std::optional<string_fragment>* level_out);
}; };
#endif #endif

@ -287,8 +287,8 @@ public:
value_line_count_result value_line_count(const intern_string_t ist, value_line_count_result value_line_count(const intern_string_t ist,
bool top_level, bool top_level,
nonstd::optional<double> val std::optional<double> val
= nonstd::nullopt, = std::nullopt,
const unsigned char* str = nullptr, const unsigned char* str = nullptr,
ssize_t len = -1); ssize_t len = -1);

@ -58,7 +58,7 @@ struct log_level_stats {
}; };
struct log_op_description { struct log_op_description {
nonstd::optional<intern_string_t> lod_id; std::optional<intern_string_t> lod_id;
lnav::map::small<size_t, std::string> lod_elements; lnav::map::small<size_t, std::string> lod_elements;
log_op_description& operator|=(const log_op_description& rhs); log_op_description& operator|=(const log_op_description& rhs);

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save