mirror of
https://github.com/tstack/lnav.git
synced 2024-09-11 13:05:51 +03:00
[build] some tidying up of the headers
This commit is contained in:
parent
8df83d562a
commit
0361ed5700
@ -532,6 +532,7 @@ add_library(
|
||||
spectro_impls.hh
|
||||
spectro_source.hh
|
||||
sqlitepp.hh
|
||||
sql_execute.hh
|
||||
sql_help.hh
|
||||
sql_util.hh
|
||||
static_file_vtab.hh
|
||||
|
@ -291,6 +291,7 @@ noinst_HEADERS = \
|
||||
spectro_source.hh \
|
||||
sqlitepp.hh \
|
||||
sqlitepp.client.hh \
|
||||
sql_execute.hh \
|
||||
sql_help.hh \
|
||||
sql_util.hh \
|
||||
sqlite-extension-func.hh \
|
||||
|
@ -4,6 +4,7 @@ add_library(
|
||||
ansi_scrubber.cc
|
||||
attr_line.cc
|
||||
attr_line.builder.cc
|
||||
auto_fd.cc
|
||||
auto_pid.cc
|
||||
date_time_scanner.cc
|
||||
fs_util.cc
|
||||
@ -25,6 +26,7 @@ add_library(
|
||||
time_util.cc
|
||||
|
||||
ansi_scrubber.hh
|
||||
ansi_vars.hh
|
||||
attr_line.hh
|
||||
attr_line.builder.hh
|
||||
auto_fd.hh
|
||||
@ -57,6 +59,7 @@ add_library(
|
||||
string_attr_type.hh
|
||||
strnatcmp.h
|
||||
time_util.hh
|
||||
types.hh
|
||||
|
||||
../third-party/xxHash/xxhash.h
|
||||
../third-party/xxHash/xxhash.c
|
||||
|
@ -22,6 +22,7 @@ noinst_LIBRARIES = libbase.a
|
||||
|
||||
noinst_HEADERS = \
|
||||
ansi_scrubber.hh \
|
||||
ansi_vars.hh \
|
||||
attr_line.hh \
|
||||
attr_line.builder.hh \
|
||||
auto_fd.hh \
|
||||
@ -58,12 +59,14 @@ noinst_HEADERS = \
|
||||
string_attr_type.hh \
|
||||
string_util.hh \
|
||||
strnatcmp.h \
|
||||
time_util.hh
|
||||
time_util.hh \
|
||||
types.hh
|
||||
|
||||
libbase_a_SOURCES = \
|
||||
ansi_scrubber.cc \
|
||||
attr_line.cc \
|
||||
attr_line.builder.cc \
|
||||
auto_fd.cc \
|
||||
auto_pid.cc \
|
||||
date_time_scanner.cc \
|
||||
fs_util.cc \
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
#include "ansi_scrubber.hh"
|
||||
|
||||
#include "ansi_vars.hh"
|
||||
#include "base/opt_util.hh"
|
||||
#include "config.h"
|
||||
#include "pcrepp/pcre2pp.hh"
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include <string>
|
||||
|
||||
#include "attr_line.hh"
|
||||
#include "shlex.resolver.hh"
|
||||
|
||||
#define ANSI_CSI "\x1b["
|
||||
#define ANSI_CHAR_ATTR "m"
|
||||
@ -66,10 +65,4 @@ void scrub_ansi_string(std::string& str, string_attrs_t* sa);
|
||||
|
||||
size_t erase_ansi_escapes(string_fragment input);
|
||||
|
||||
/**
|
||||
* Populate a variable map with strings that contain escape sequences that
|
||||
* might be useful to script writers.
|
||||
*/
|
||||
void add_ansi_vars(std::map<std::string, scoped_value_t>& vars);
|
||||
|
||||
#endif
|
||||
|
41
src/base/ansi_vars.hh
Normal file
41
src/base/ansi_vars.hh
Normal file
@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Copyright (c) 2023, Timothy Stack
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of Timothy Stack nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lnav_ansi_vars_hh
|
||||
#define lnav_ansi_vars_hh
|
||||
|
||||
#include "shlex.resolver.hh"
|
||||
|
||||
/**
|
||||
* Populate a variable map with strings that contain escape sequences that
|
||||
* might be useful to script writers.
|
||||
*/
|
||||
void add_ansi_vars(std::map<std::string, scoped_value_t>& vars);
|
||||
|
||||
#endif
|
206
src/base/auto_fd.cc
Normal file
206
src/base/auto_fd.cc
Normal file
@ -0,0 +1,206 @@
|
||||
/**
|
||||
* Copyright (c) 2023, Timothy Stack
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of Timothy Stack nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @file auto_fd.cc
|
||||
*/
|
||||
|
||||
#include "auto_fd.hh"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "lnav_log.hh"
|
||||
|
||||
int
|
||||
auto_fd::pipe(auto_fd* af)
|
||||
{
|
||||
int retval, fd[2];
|
||||
|
||||
require(af != nullptr);
|
||||
|
||||
if ((retval = ::pipe(fd)) == 0) {
|
||||
af[0] = fd[0];
|
||||
af[1] = fd[1];
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
auto_fd
|
||||
auto_fd::dup_of(int fd)
|
||||
{
|
||||
if (fd == -1) {
|
||||
return auto_fd{};
|
||||
}
|
||||
|
||||
auto new_fd = ::dup(fd);
|
||||
|
||||
if (new_fd == -1) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
return auto_fd(new_fd);
|
||||
}
|
||||
|
||||
auto_fd::auto_fd(int fd) : af_fd(fd)
|
||||
{
|
||||
require(fd >= -1);
|
||||
}
|
||||
|
||||
auto_fd::auto_fd(auto_fd&& af) noexcept : af_fd(af.release()) {}
|
||||
|
||||
auto_fd
|
||||
auto_fd::dup() const
|
||||
{
|
||||
int new_fd;
|
||||
|
||||
if (this->af_fd == -1 || (new_fd = ::dup(this->af_fd)) == -1) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
return auto_fd{new_fd};
|
||||
}
|
||||
|
||||
auto_fd::~auto_fd()
|
||||
{
|
||||
this->reset();
|
||||
}
|
||||
|
||||
void
|
||||
auto_fd::reset(int fd)
|
||||
{
|
||||
require(fd >= -1);
|
||||
|
||||
if (this->af_fd != fd) {
|
||||
if (this->af_fd != -1) {
|
||||
switch (this->af_fd) {
|
||||
case STDIN_FILENO:
|
||||
case STDOUT_FILENO:
|
||||
case STDERR_FILENO:
|
||||
break;
|
||||
default:
|
||||
close(this->af_fd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this->af_fd = fd;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
auto_fd::close_on_exec() const
|
||||
{
|
||||
if (this->af_fd == -1) {
|
||||
return;
|
||||
}
|
||||
log_perror(fcntl(this->af_fd, F_SETFD, FD_CLOEXEC));
|
||||
}
|
||||
|
||||
auto_fd&
|
||||
auto_fd::operator=(int fd)
|
||||
{
|
||||
require(fd >= -1);
|
||||
|
||||
this->reset(fd);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Result<auto_pipe, std::string>
|
||||
auto_pipe::for_child_fd(int child_fd)
|
||||
{
|
||||
auto_pipe retval(child_fd);
|
||||
|
||||
if (retval.open() == -1) {
|
||||
return Err(std::string(strerror(errno)));
|
||||
}
|
||||
|
||||
return Ok(std::move(retval));
|
||||
}
|
||||
|
||||
auto_pipe::auto_pipe(int child_fd, int child_flags)
|
||||
: ap_child_flags(child_flags), ap_child_fd(child_fd)
|
||||
{
|
||||
switch (child_fd) {
|
||||
case STDIN_FILENO:
|
||||
this->ap_child_flags = O_RDONLY;
|
||||
break;
|
||||
case STDOUT_FILENO:
|
||||
case STDERR_FILENO:
|
||||
this->ap_child_flags = O_WRONLY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
auto_pipe::after_fork(pid_t child_pid)
|
||||
{
|
||||
int new_fd;
|
||||
|
||||
switch (child_pid) {
|
||||
case -1:
|
||||
this->close();
|
||||
break;
|
||||
case 0:
|
||||
if (this->ap_child_flags == O_RDONLY) {
|
||||
this->write_end().reset();
|
||||
if (this->read_end().get() == -1) {
|
||||
this->read_end() = ::open("/dev/null", O_RDONLY);
|
||||
}
|
||||
new_fd = this->read_end().get();
|
||||
} else {
|
||||
this->read_end().reset();
|
||||
if (this->write_end().get() == -1) {
|
||||
this->write_end() = ::open("/dev/null", O_WRONLY);
|
||||
}
|
||||
new_fd = this->write_end().get();
|
||||
}
|
||||
if (this->ap_child_fd != -1) {
|
||||
if (new_fd != this->ap_child_fd) {
|
||||
dup2(new_fd, this->ap_child_fd);
|
||||
this->close();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (this->ap_child_flags == O_RDONLY) {
|
||||
this->read_end().reset();
|
||||
} else {
|
||||
this->write_end().reset();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
auto_pipe::open()
|
||||
{
|
||||
int retval = auto_fd::pipe(this->ap_fd);
|
||||
this->ap_fd[0].close_on_exec();
|
||||
this->ap_fd[1].close_on_exec();
|
||||
return retval;
|
||||
}
|
@ -32,16 +32,10 @@
|
||||
#ifndef auto_fd_hh
|
||||
#define auto_fd_hh
|
||||
|
||||
#include <exception>
|
||||
#include <new>
|
||||
#include <string>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/select.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "base/lnav_log.hh"
|
||||
#include "base/result.h"
|
||||
|
||||
/**
|
||||
@ -59,19 +53,7 @@ public:
|
||||
* contains the reader end of the pipe and the second contains the writer.
|
||||
* @return The result of the pipe(2) function.
|
||||
*/
|
||||
static int pipe(auto_fd* af)
|
||||
{
|
||||
int retval, fd[2];
|
||||
|
||||
require(af != nullptr);
|
||||
|
||||
if ((retval = ::pipe(fd)) == 0) {
|
||||
af[0] = fd[0];
|
||||
af[1] = fd[1];
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
static int pipe(auto_fd* af);
|
||||
|
||||
/**
|
||||
* dup(2) the given file descriptor and wrap it in an auto_fd.
|
||||
@ -79,27 +61,14 @@ public:
|
||||
* @param fd The file descriptor to duplicate.
|
||||
* @return A new auto_fd that contains the duplicated file descriptor.
|
||||
*/
|
||||
static auto_fd dup_of(int fd)
|
||||
{
|
||||
if (fd == -1) {
|
||||
return auto_fd{};
|
||||
}
|
||||
|
||||
auto new_fd = ::dup(fd);
|
||||
|
||||
if (new_fd == -1) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
return auto_fd(new_fd);
|
||||
}
|
||||
static auto_fd dup_of(int fd);
|
||||
|
||||
/**
|
||||
* Construct an auto_fd to manage the given file descriptor.
|
||||
*
|
||||
* @param fd The file descriptor to be managed.
|
||||
*/
|
||||
explicit auto_fd(int fd = -1) : af_fd(fd) { require(fd >= -1); }
|
||||
explicit auto_fd(int fd = -1);
|
||||
|
||||
/**
|
||||
* Non-const copy constructor. Management of the file descriptor will be
|
||||
@ -108,7 +77,7 @@ public:
|
||||
*
|
||||
* @param af The source of the file descriptor.
|
||||
*/
|
||||
auto_fd(auto_fd&& af) noexcept : af_fd(af.release()) {}
|
||||
auto_fd(auto_fd&& af) noexcept;
|
||||
|
||||
/**
|
||||
* Const copy constructor. The file descriptor from the source will be
|
||||
@ -118,21 +87,12 @@ public:
|
||||
*/
|
||||
auto_fd(const auto_fd& af) = delete;
|
||||
|
||||
auto_fd dup() const
|
||||
{
|
||||
int new_fd;
|
||||
|
||||
if (this->af_fd == -1 || (new_fd = ::dup(this->af_fd)) == -1) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
return auto_fd{new_fd};
|
||||
}
|
||||
auto_fd dup() const;
|
||||
|
||||
/**
|
||||
* Destructor that will close the file descriptor managed by this object.
|
||||
*/
|
||||
~auto_fd() { this->reset(); }
|
||||
~auto_fd();
|
||||
|
||||
/** @return The file descriptor as a plain integer. */
|
||||
operator int() const { return this->af_fd; }
|
||||
@ -144,13 +104,7 @@ public:
|
||||
* @param fd The file descriptor to store in this object.
|
||||
* @return *this
|
||||
*/
|
||||
auto_fd& operator=(int fd)
|
||||
{
|
||||
require(fd >= -1);
|
||||
|
||||
this->reset(fd);
|
||||
return *this;
|
||||
}
|
||||
auto_fd& operator=(int fd);
|
||||
|
||||
/**
|
||||
* Transfer management of the given file descriptor to this object.
|
||||
@ -202,33 +156,9 @@ public:
|
||||
*
|
||||
* @param fd The new file descriptor to be managed.
|
||||
*/
|
||||
void reset(int fd = -1)
|
||||
{
|
||||
require(fd >= -1);
|
||||
void reset(int fd = -1);
|
||||
|
||||
if (this->af_fd != fd) {
|
||||
if (this->af_fd != -1) {
|
||||
switch (this->af_fd) {
|
||||
case STDIN_FILENO:
|
||||
case STDOUT_FILENO:
|
||||
case STDERR_FILENO:
|
||||
break;
|
||||
default:
|
||||
close(this->af_fd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this->af_fd = fd;
|
||||
}
|
||||
}
|
||||
|
||||
void close_on_exec() const
|
||||
{
|
||||
if (this->af_fd == -1) {
|
||||
return;
|
||||
}
|
||||
log_perror(fcntl(this->af_fd, F_SETFD, FD_CLOEXEC));
|
||||
}
|
||||
void close_on_exec() const;
|
||||
|
||||
private:
|
||||
int af_fd; /*< The managed file descriptor. */
|
||||
@ -236,38 +166,11 @@ private:
|
||||
|
||||
class auto_pipe {
|
||||
public:
|
||||
static Result<auto_pipe, std::string> for_child_fd(int child_fd)
|
||||
{
|
||||
auto_pipe retval(child_fd);
|
||||
static Result<auto_pipe, std::string> for_child_fd(int child_fd);
|
||||
|
||||
if (retval.open() == -1) {
|
||||
return Err(std::string(strerror(errno)));
|
||||
}
|
||||
explicit auto_pipe(int child_fd = -1, int child_flags = O_RDONLY);
|
||||
|
||||
return Ok(std::move(retval));
|
||||
}
|
||||
|
||||
explicit auto_pipe(int child_fd = -1, int child_flags = O_RDONLY)
|
||||
: ap_child_flags(child_flags), ap_child_fd(child_fd)
|
||||
{
|
||||
switch (child_fd) {
|
||||
case STDIN_FILENO:
|
||||
this->ap_child_flags = O_RDONLY;
|
||||
break;
|
||||
case STDOUT_FILENO:
|
||||
case STDERR_FILENO:
|
||||
this->ap_child_flags = O_WRONLY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int open()
|
||||
{
|
||||
int retval = auto_fd::pipe(this->ap_fd);
|
||||
this->ap_fd[0].close_on_exec();
|
||||
this->ap_fd[1].close_on_exec();
|
||||
return retval;
|
||||
}
|
||||
int open();
|
||||
|
||||
void close()
|
||||
{
|
||||
@ -279,44 +182,7 @@ public:
|
||||
|
||||
auto_fd& write_end() { return this->ap_fd[1]; }
|
||||
|
||||
void after_fork(pid_t child_pid)
|
||||
{
|
||||
int new_fd;
|
||||
|
||||
switch (child_pid) {
|
||||
case -1:
|
||||
this->close();
|
||||
break;
|
||||
case 0:
|
||||
if (this->ap_child_flags == O_RDONLY) {
|
||||
this->write_end().reset();
|
||||
if (this->read_end().get() == -1) {
|
||||
this->read_end() = ::open("/dev/null", O_RDONLY);
|
||||
}
|
||||
new_fd = this->read_end().get();
|
||||
} else {
|
||||
this->read_end().reset();
|
||||
if (this->write_end().get() == -1) {
|
||||
this->write_end() = ::open("/dev/null", O_WRONLY);
|
||||
}
|
||||
new_fd = this->write_end().get();
|
||||
}
|
||||
if (this->ap_child_fd != -1) {
|
||||
if (new_fd != this->ap_child_fd) {
|
||||
dup2(new_fd, this->ap_child_fd);
|
||||
this->close();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (this->ap_child_flags == O_RDONLY) {
|
||||
this->read_end().reset();
|
||||
} else {
|
||||
this->write_end().reset();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
void after_fork(pid_t child_pid);
|
||||
|
||||
int ap_child_flags;
|
||||
int ap_child_fd;
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "auto_fd.hh"
|
||||
#include "optional.hpp"
|
||||
#include "result.h"
|
||||
|
||||
namespace network {
|
||||
|
35
src/base/types.hh
Normal file
35
src/base/types.hh
Normal file
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright (c) 2023, Timothy Stack
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of Timothy Stack nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lnav_base_types_hh
|
||||
#define lnav_base_types_hh
|
||||
|
||||
struct null_value_t {};
|
||||
|
||||
#endif
|
@ -41,11 +41,6 @@ template<typename T>
|
||||
struct big_array {
|
||||
static const size_t DEFAULT_INCREMENT = 100 * 1000;
|
||||
|
||||
big_array()
|
||||
: ba_ptr(nullptr), ba_size(0), ba_capacity(0){
|
||||
|
||||
};
|
||||
|
||||
bool reserve(size_t size)
|
||||
{
|
||||
if (size < this->ba_capacity) {
|
||||
@ -71,17 +66,11 @@ struct big_array {
|
||||
this->ba_ptr = (T*) result;
|
||||
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
this->ba_size = 0;
|
||||
};
|
||||
void clear() { this->ba_size = 0; }
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
return this->ba_size;
|
||||
};
|
||||
size_t size() const { return this->ba_size; }
|
||||
|
||||
void shrink_to(size_t new_size)
|
||||
{
|
||||
@ -90,47 +79,29 @@ struct big_array {
|
||||
this->ba_size = new_size;
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return this->ba_size == 0;
|
||||
};
|
||||
bool empty() const { return this->ba_size == 0; }
|
||||
|
||||
void push_back(const T& val)
|
||||
{
|
||||
this->ba_ptr[this->ba_size] = val;
|
||||
this->ba_size += 1;
|
||||
};
|
||||
|
||||
T& operator[](size_t index)
|
||||
{
|
||||
return this->ba_ptr[index];
|
||||
};
|
||||
|
||||
const T& operator[](size_t index) const
|
||||
{
|
||||
return this->ba_ptr[index];
|
||||
};
|
||||
|
||||
T& back()
|
||||
{
|
||||
return this->ba_ptr[this->ba_size - 1];
|
||||
}
|
||||
|
||||
typedef T* iterator;
|
||||
T& operator[](size_t index) { return this->ba_ptr[index]; }
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
return this->ba_ptr;
|
||||
};
|
||||
const T& operator[](size_t index) const { return this->ba_ptr[index]; }
|
||||
|
||||
iterator end()
|
||||
{
|
||||
return this->ba_ptr + this->ba_size;
|
||||
};
|
||||
T& back() { return this->ba_ptr[this->ba_size - 1]; }
|
||||
|
||||
T* ba_ptr;
|
||||
size_t ba_size;
|
||||
size_t ba_capacity;
|
||||
using iterator = T*;
|
||||
|
||||
iterator begin() { return this->ba_ptr; }
|
||||
|
||||
iterator end() { return this->ba_ptr + this->ba_size; }
|
||||
|
||||
T* ba_ptr{nullptr};
|
||||
size_t ba_size{0};
|
||||
size_t ba_capacity{0};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "command_executor.hh"
|
||||
|
||||
#include "base/ansi_scrubber.hh"
|
||||
#include "base/ansi_vars.hh"
|
||||
#include "base/fs_util.hh"
|
||||
#include "base/injector.hh"
|
||||
#include "base/itertools.hh"
|
||||
@ -608,7 +609,7 @@ execute_file(exec_context& ec, const std::string& path_and_args, bool multiline)
|
||||
|
||||
log_info("Executing file: %s", path_and_args.c_str());
|
||||
|
||||
if (!lexer.split(split_args, ec.ec_local_vars.top())) {
|
||||
if (!lexer.split(split_args, scoped_resolver{&ec.ec_local_vars.top()})) {
|
||||
return ec.make_error("unable to parse path");
|
||||
}
|
||||
if (split_args.empty()) {
|
||||
@ -1021,7 +1022,7 @@ add_global_vars(exec_context& ec)
|
||||
shlex subber(iter.second);
|
||||
std::string str;
|
||||
|
||||
if (!subber.eval(str, ec.ec_global_vars)) {
|
||||
if (!subber.eval(str, scoped_resolver{&ec.ec_global_vars})) {
|
||||
log_error("Unable to evaluate global variable value: %s",
|
||||
iter.second.c_str());
|
||||
continue;
|
||||
|
@ -38,7 +38,6 @@
|
||||
|
||||
#include "base/auto_fd.hh"
|
||||
#include "base/lnav.console.hh"
|
||||
#include "bookmarks.hh"
|
||||
#include "fmt/format.h"
|
||||
#include "ghc/filesystem.hpp"
|
||||
#include "help_text.hh"
|
||||
|
@ -50,7 +50,7 @@ public:
|
||||
}
|
||||
|
||||
void logline_new_lines(const logfile& lf,
|
||||
logfile::const_iterator ll_begin,
|
||||
logfile::const_iterator ll_baegin,
|
||||
logfile::const_iterator ll_end,
|
||||
const shared_buffer_ref& sbr) override;
|
||||
|
||||
|
@ -46,7 +46,6 @@
|
||||
#include "base/auto_mem.hh"
|
||||
#include "base/file_range.hh"
|
||||
#include "base/is_utf8.hh"
|
||||
#include "base/lnav_log.hh"
|
||||
#include "base/result.h"
|
||||
#include "log_level.hh"
|
||||
#include "safe/safe.h"
|
||||
|
@ -75,6 +75,7 @@
|
||||
|
||||
#include "all_logs_vtab.hh"
|
||||
#include "base/ansi_scrubber.hh"
|
||||
#include "base/ansi_vars.hh"
|
||||
#include "base/fs_util.hh"
|
||||
#include "base/func_util.hh"
|
||||
#include "base/future_util.hh"
|
||||
|
@ -1877,7 +1877,7 @@ detect_mime_type(const ghc::filesystem::path& filename)
|
||||
|
||||
auto hexbuf = auto_buffer::alloc(buffer_size * 2);
|
||||
|
||||
for (int lpc = 0; lpc < buffer_size; lpc++) {
|
||||
for (size_t lpc = 0; lpc < buffer_size; lpc++) {
|
||||
fmt::format_to(
|
||||
std::back_inserter(hexbuf), FMT_STRING("{:02x}"), buffer[lpc]);
|
||||
}
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include "fmt/format.h"
|
||||
#include "lnav_config.hh"
|
||||
#include "log_format_ext.hh"
|
||||
#include "sql_execute.hh"
|
||||
#include "sql_util.hh"
|
||||
#include "yajlpp/yajlpp.hh"
|
||||
#include "yajlpp/yajlpp_def.hh"
|
||||
|
@ -35,8 +35,7 @@
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include "base/ansi_scrubber.hh"
|
||||
#include "base/humanize.time.hh"
|
||||
#include "base/injector.hh"
|
||||
#include "base/ansi_vars.hh"
|
||||
#include "base/itertools.hh"
|
||||
#include "base/string_util.hh"
|
||||
#include "bound_tags.hh"
|
||||
@ -140,6 +139,30 @@ logfile_sub_source::find(const char* fn, content_line_t& line_base)
|
||||
return retval;
|
||||
}
|
||||
|
||||
struct filtered_logline_cmp {
|
||||
filtered_logline_cmp(const logfile_sub_source& lc) : llss_controller(lc) {}
|
||||
|
||||
bool operator()(const uint32_t& lhs, const uint32_t& rhs) const
|
||||
{
|
||||
content_line_t cl_lhs = (content_line_t) llss_controller.lss_index[lhs];
|
||||
content_line_t cl_rhs = (content_line_t) llss_controller.lss_index[rhs];
|
||||
logline* ll_lhs = this->llss_controller.find_line(cl_lhs);
|
||||
logline* ll_rhs = this->llss_controller.find_line(cl_rhs);
|
||||
|
||||
return (*ll_lhs) < (*ll_rhs);
|
||||
}
|
||||
|
||||
bool operator()(const uint32_t& lhs, const struct timeval& rhs) const
|
||||
{
|
||||
content_line_t cl_lhs = (content_line_t) llss_controller.lss_index[lhs];
|
||||
logline* ll_lhs = this->llss_controller.find_line(cl_lhs);
|
||||
|
||||
return (*ll_lhs) < rhs;
|
||||
}
|
||||
|
||||
const logfile_sub_source& llss_controller;
|
||||
};
|
||||
|
||||
nonstd::optional<vis_line_t>
|
||||
logfile_sub_source::find_from_time(const struct timeval& start) const
|
||||
{
|
||||
@ -596,6 +619,53 @@ logfile_sub_source::text_attrs_for_line(textview_curses& lv,
|
||||
}
|
||||
}
|
||||
|
||||
struct logline_cmp {
|
||||
logline_cmp(logfile_sub_source& lc) : llss_controller(lc) {}
|
||||
|
||||
bool operator()(const content_line_t& lhs, const content_line_t& rhs) const
|
||||
{
|
||||
logline* ll_lhs = this->llss_controller.find_line(lhs);
|
||||
logline* ll_rhs = this->llss_controller.find_line(rhs);
|
||||
|
||||
return (*ll_lhs) < (*ll_rhs);
|
||||
}
|
||||
|
||||
bool operator()(const uint32_t& lhs, const uint32_t& rhs) const
|
||||
{
|
||||
content_line_t cl_lhs = (content_line_t) llss_controller.lss_index[lhs];
|
||||
content_line_t cl_rhs = (content_line_t) llss_controller.lss_index[rhs];
|
||||
logline* ll_lhs = this->llss_controller.find_line(cl_lhs);
|
||||
logline* ll_rhs = this->llss_controller.find_line(cl_rhs);
|
||||
|
||||
return (*ll_lhs) < (*ll_rhs);
|
||||
}
|
||||
#if 0
|
||||
bool operator()(const indexed_content &lhs, const indexed_content &rhs)
|
||||
{
|
||||
logline *ll_lhs = this->llss_controller.find_line(lhs.ic_value);
|
||||
logline *ll_rhs = this->llss_controller.find_line(rhs.ic_value);
|
||||
|
||||
return (*ll_lhs) < (*ll_rhs);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool operator()(const content_line_t& lhs, const time_t& rhs) const
|
||||
{
|
||||
logline* ll_lhs = this->llss_controller.find_line(lhs);
|
||||
|
||||
return *ll_lhs < rhs;
|
||||
}
|
||||
|
||||
bool operator()(const content_line_t& lhs, const struct timeval& rhs) const
|
||||
{
|
||||
logline* ll_lhs = this->llss_controller.find_line(lhs);
|
||||
|
||||
return *ll_lhs < rhs;
|
||||
}
|
||||
|
||||
logfile_sub_source& llss_controller;
|
||||
};
|
||||
|
||||
logfile_sub_source::rebuild_result
|
||||
logfile_sub_source::rebuild_index(
|
||||
nonstd::optional<ui_clock::time_point> deadline)
|
||||
@ -1211,6 +1281,24 @@ logfile_sub_source::get_grepper()
|
||||
(grep_proc_sink<vis_line_t>*) &this->lss_meta_grepper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Functor for comparing the ld_file field of the logfile_data struct.
|
||||
*/
|
||||
struct logfile_data_eq {
|
||||
explicit logfile_data_eq(std::shared_ptr<logfile> lf)
|
||||
: lde_file(std::move(lf))
|
||||
{
|
||||
}
|
||||
|
||||
bool operator()(
|
||||
const std::unique_ptr<logfile_sub_source::logfile_data>& ld) const
|
||||
{
|
||||
return this->lde_file == ld->get_file();
|
||||
}
|
||||
|
||||
std::shared_ptr<logfile> lde_file;
|
||||
};
|
||||
|
||||
bool
|
||||
logfile_sub_source::insert_file(const std::shared_ptr<logfile>& lf)
|
||||
{
|
||||
@ -2418,3 +2506,113 @@ logfile_sub_source::clear_bookmark_metadata()
|
||||
ld->get_file_ptr()->get_bookmark_metadata().clear();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
logfile_sub_source::increase_line_context()
|
||||
{
|
||||
auto old_flags = this->lss_flags;
|
||||
|
||||
if (this->lss_flags & F_FILENAME) {
|
||||
// Nothing to do
|
||||
} else if (this->lss_flags & F_BASENAME) {
|
||||
this->lss_flags &= ~F_NAME_MASK;
|
||||
this->lss_flags |= F_FILENAME;
|
||||
} else {
|
||||
this->lss_flags |= F_BASENAME;
|
||||
}
|
||||
if (old_flags != this->lss_flags) {
|
||||
this->clear_line_size_cache();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
logfile_sub_source::decrease_line_context()
|
||||
{
|
||||
auto old_flags = this->lss_flags;
|
||||
|
||||
if (this->lss_flags & F_FILENAME) {
|
||||
this->lss_flags &= ~F_NAME_MASK;
|
||||
this->lss_flags |= F_BASENAME;
|
||||
} else if (this->lss_flags & F_BASENAME) {
|
||||
this->lss_flags &= ~F_NAME_MASK;
|
||||
}
|
||||
if (old_flags != this->lss_flags) {
|
||||
this->clear_line_size_cache();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t
|
||||
logfile_sub_source::get_filename_offset() const
|
||||
{
|
||||
if (this->lss_flags & F_FILENAME) {
|
||||
return this->lss_filename_width;
|
||||
} else if (this->lss_flags & F_BASENAME) {
|
||||
return this->lss_basename_width;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
logfile_sub_source::clear_min_max_log_times()
|
||||
{
|
||||
if (this->lss_min_log_time.tv_sec != 0
|
||||
|| this->lss_min_log_time.tv_usec != 0
|
||||
|| this->lss_max_log_time.tv_sec != std::numeric_limits<time_t>::max()
|
||||
|| this->lss_max_log_time.tv_usec != 0)
|
||||
{
|
||||
memset(&this->lss_min_log_time, 0, sizeof(this->lss_min_log_time));
|
||||
this->lss_max_log_time.tv_sec = std::numeric_limits<time_t>::max();
|
||||
this->lss_max_log_time.tv_usec = 0;
|
||||
this->text_filters_changed();
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
logfile_sub_source::file_count() const
|
||||
{
|
||||
size_t retval = 0;
|
||||
const_iterator iter;
|
||||
|
||||
for (iter = this->cbegin(); iter != this->cend(); ++iter) {
|
||||
if (*iter != nullptr && (*iter)->get_file() != nullptr) {
|
||||
retval += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
size_t
|
||||
logfile_sub_source::text_size_for_line(textview_curses& tc,
|
||||
int row,
|
||||
text_sub_source::line_flags_t flags)
|
||||
{
|
||||
size_t index = row % LINE_SIZE_CACHE_SIZE;
|
||||
|
||||
if (this->lss_line_size_cache[index].first != row) {
|
||||
std::string value;
|
||||
|
||||
this->text_value_for_line(tc, row, value, flags);
|
||||
this->lss_line_size_cache[index].second = value.size();
|
||||
this->lss_line_size_cache[index].first = row;
|
||||
}
|
||||
return this->lss_line_size_cache[index].second;
|
||||
}
|
||||
|
||||
int
|
||||
logfile_sub_source::get_filtered_count_for(size_t filter_index) const
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
for (const auto& ld : this->lss_files) {
|
||||
retval += ld->ld_filter_state.lfo_filter_state
|
||||
.tfs_filter_hits[filter_index];
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -253,52 +253,11 @@ public:
|
||||
|
||||
~logfile_sub_source() = default;
|
||||
|
||||
void increase_line_context()
|
||||
{
|
||||
auto old_flags = this->lss_flags;
|
||||
void increase_line_context();
|
||||
|
||||
if (this->lss_flags & F_FILENAME) {
|
||||
// Nothing to do
|
||||
} else if (this->lss_flags & F_BASENAME) {
|
||||
this->lss_flags &= ~F_NAME_MASK;
|
||||
this->lss_flags |= F_FILENAME;
|
||||
} else {
|
||||
this->lss_flags |= F_BASENAME;
|
||||
}
|
||||
if (old_flags != this->lss_flags) {
|
||||
this->clear_line_size_cache();
|
||||
}
|
||||
}
|
||||
bool decrease_line_context();
|
||||
|
||||
bool decrease_line_context()
|
||||
{
|
||||
auto old_flags = this->lss_flags;
|
||||
|
||||
if (this->lss_flags & F_FILENAME) {
|
||||
this->lss_flags &= ~F_NAME_MASK;
|
||||
this->lss_flags |= F_BASENAME;
|
||||
} else if (this->lss_flags & F_BASENAME) {
|
||||
this->lss_flags &= ~F_NAME_MASK;
|
||||
}
|
||||
if (old_flags != this->lss_flags) {
|
||||
this->clear_line_size_cache();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t get_filename_offset() const
|
||||
{
|
||||
if (this->lss_flags & F_FILENAME) {
|
||||
return this->lss_filename_width;
|
||||
} else if (this->lss_flags & F_BASENAME) {
|
||||
return this->lss_basename_width;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
size_t get_filename_offset() const;
|
||||
|
||||
bool is_filename_enabled() const
|
||||
{
|
||||
@ -353,20 +312,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void clear_min_max_log_times()
|
||||
{
|
||||
if (this->lss_min_log_time.tv_sec != 0
|
||||
|| this->lss_min_log_time.tv_usec != 0
|
||||
|| this->lss_max_log_time.tv_sec
|
||||
!= std::numeric_limits<time_t>::max()
|
||||
|| this->lss_max_log_time.tv_usec != 0)
|
||||
{
|
||||
memset(&this->lss_min_log_time, 0, sizeof(this->lss_min_log_time));
|
||||
this->lss_max_log_time.tv_sec = std::numeric_limits<time_t>::max();
|
||||
this->lss_max_log_time.tv_usec = 0;
|
||||
this->text_filters_changed();
|
||||
}
|
||||
}
|
||||
void clear_min_max_log_times();
|
||||
|
||||
bool list_input_handle_key(listview_curses& lv, int ch);
|
||||
|
||||
@ -387,19 +333,7 @@ public:
|
||||
return this->lss_longest_line;
|
||||
}
|
||||
|
||||
size_t file_count() const
|
||||
{
|
||||
size_t retval = 0;
|
||||
const_iterator iter;
|
||||
|
||||
for (iter = this->cbegin(); iter != this->cend(); ++iter) {
|
||||
if (*iter != nullptr && (*iter)->get_file() != nullptr) {
|
||||
retval += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
size_t file_count() const;
|
||||
|
||||
bool empty() const { return this->lss_filtered_index.empty(); }
|
||||
|
||||
@ -412,19 +346,7 @@ public:
|
||||
int row,
|
||||
string_attrs_t& value_out);
|
||||
|
||||
size_t text_size_for_line(textview_curses& tc, int row, line_flags_t flags)
|
||||
{
|
||||
size_t index = row % LINE_SIZE_CACHE_SIZE;
|
||||
|
||||
if (this->lss_line_size_cache[index].first != row) {
|
||||
std::string value;
|
||||
|
||||
this->text_value_for_line(tc, row, value, flags);
|
||||
this->lss_line_size_cache[index].second = value.size();
|
||||
this->lss_line_size_cache[index].first = row;
|
||||
}
|
||||
return this->lss_line_size_cache[index].second;
|
||||
}
|
||||
size_t text_size_for_line(textview_curses& tc, int row, line_flags_t flags);
|
||||
|
||||
void text_mark(const bookmark_type_t* bm, vis_line_t line, bool added);
|
||||
|
||||
@ -485,17 +407,7 @@ public:
|
||||
return this->lss_index.size() - this->lss_filtered_index.size();
|
||||
}
|
||||
|
||||
int get_filtered_count_for(size_t filter_index) const
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
for (const auto& ld : this->lss_files) {
|
||||
retval += ld->ld_filter_state.lfo_filter_state
|
||||
.tfs_filter_hits[filter_index];
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
int get_filtered_count_for(size_t filter_index) const;
|
||||
|
||||
Result<void, lnav::console::user_message> set_sql_filter(
|
||||
std::string stmt_str, sqlite3_stmt* stmt);
|
||||
@ -813,6 +725,21 @@ public:
|
||||
|
||||
void quiesce();
|
||||
|
||||
struct __attribute__((__packed__)) indexed_content {
|
||||
indexed_content() = default;
|
||||
|
||||
indexed_content(content_line_t cl) : ic_value(cl) {}
|
||||
|
||||
operator content_line_t() const
|
||||
{
|
||||
return content_line_t(this->ic_value);
|
||||
}
|
||||
|
||||
uint64_t ic_value : 40;
|
||||
};
|
||||
|
||||
big_array<indexed_content> lss_index;
|
||||
|
||||
protected:
|
||||
void text_accel_display_changed() { this->clear_line_size_cache(); }
|
||||
|
||||
@ -838,116 +765,6 @@ private:
|
||||
F_NAME_MASK = (F_FILENAME | F_BASENAME),
|
||||
};
|
||||
|
||||
struct __attribute__((__packed__)) indexed_content {
|
||||
indexed_content() = default;
|
||||
|
||||
indexed_content(content_line_t cl) : ic_value(cl) {}
|
||||
|
||||
operator content_line_t() const
|
||||
{
|
||||
return content_line_t(this->ic_value);
|
||||
}
|
||||
|
||||
uint64_t ic_value : 40;
|
||||
};
|
||||
|
||||
struct logline_cmp {
|
||||
logline_cmp(logfile_sub_source& lc) : llss_controller(lc) {}
|
||||
|
||||
bool operator()(const content_line_t& lhs,
|
||||
const content_line_t& rhs) const
|
||||
{
|
||||
logline* ll_lhs = this->llss_controller.find_line(lhs);
|
||||
logline* ll_rhs = this->llss_controller.find_line(rhs);
|
||||
|
||||
return (*ll_lhs) < (*ll_rhs);
|
||||
}
|
||||
|
||||
bool operator()(const uint32_t& lhs, const uint32_t& rhs) const
|
||||
{
|
||||
content_line_t cl_lhs
|
||||
= (content_line_t) llss_controller.lss_index[lhs];
|
||||
content_line_t cl_rhs
|
||||
= (content_line_t) llss_controller.lss_index[rhs];
|
||||
logline* ll_lhs = this->llss_controller.find_line(cl_lhs);
|
||||
logline* ll_rhs = this->llss_controller.find_line(cl_rhs);
|
||||
|
||||
return (*ll_lhs) < (*ll_rhs);
|
||||
}
|
||||
#if 0
|
||||
bool operator()(const indexed_content &lhs, const indexed_content &rhs)
|
||||
{
|
||||
logline *ll_lhs = this->llss_controller.find_line(lhs.ic_value);
|
||||
logline *ll_rhs = this->llss_controller.find_line(rhs.ic_value);
|
||||
|
||||
return (*ll_lhs) < (*ll_rhs);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool operator()(const content_line_t& lhs, const time_t& rhs) const
|
||||
{
|
||||
logline* ll_lhs = this->llss_controller.find_line(lhs);
|
||||
|
||||
return *ll_lhs < rhs;
|
||||
}
|
||||
|
||||
bool operator()(const content_line_t& lhs,
|
||||
const struct timeval& rhs) const
|
||||
{
|
||||
logline* ll_lhs = this->llss_controller.find_line(lhs);
|
||||
|
||||
return *ll_lhs < rhs;
|
||||
}
|
||||
|
||||
logfile_sub_source& llss_controller;
|
||||
};
|
||||
|
||||
struct filtered_logline_cmp {
|
||||
filtered_logline_cmp(const logfile_sub_source& lc) : llss_controller(lc)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator()(const uint32_t& lhs, const uint32_t& rhs) const
|
||||
{
|
||||
content_line_t cl_lhs
|
||||
= (content_line_t) llss_controller.lss_index[lhs];
|
||||
content_line_t cl_rhs
|
||||
= (content_line_t) llss_controller.lss_index[rhs];
|
||||
logline* ll_lhs = this->llss_controller.find_line(cl_lhs);
|
||||
logline* ll_rhs = this->llss_controller.find_line(cl_rhs);
|
||||
|
||||
return (*ll_lhs) < (*ll_rhs);
|
||||
}
|
||||
|
||||
bool operator()(const uint32_t& lhs, const struct timeval& rhs) const
|
||||
{
|
||||
content_line_t cl_lhs
|
||||
= (content_line_t) llss_controller.lss_index[lhs];
|
||||
logline* ll_lhs = this->llss_controller.find_line(cl_lhs);
|
||||
|
||||
return (*ll_lhs) < rhs;
|
||||
}
|
||||
|
||||
const logfile_sub_source& llss_controller;
|
||||
};
|
||||
|
||||
/**
|
||||
* Functor for comparing the ld_file field of the logfile_data struct.
|
||||
*/
|
||||
struct logfile_data_eq {
|
||||
explicit logfile_data_eq(std::shared_ptr<logfile> lf)
|
||||
: lde_file(std::move(lf))
|
||||
{
|
||||
}
|
||||
|
||||
bool operator()(const std::unique_ptr<logfile_data>& ld) const
|
||||
{
|
||||
return this->lde_file == ld->get_file();
|
||||
}
|
||||
|
||||
std::shared_ptr<logfile> lde_file;
|
||||
};
|
||||
|
||||
void clear_line_size_cache()
|
||||
{
|
||||
this->lss_line_size_cache.fill(std::make_pair(0, 0));
|
||||
@ -962,7 +779,6 @@ private:
|
||||
bool lss_force_rebuild{false};
|
||||
std::vector<std::unique_ptr<logfile_data>> lss_files;
|
||||
|
||||
big_array<indexed_content> lss_index;
|
||||
std::vector<uint32_t> lss_filtered_index;
|
||||
auto_mem<sqlite3_stmt> lss_preview_filter_stmt{sqlite3_finalize};
|
||||
|
||||
|
@ -52,12 +52,12 @@ write_timestamp(int fd, log_level_t level, off_t woff)
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, nullptr);
|
||||
snprintf(time_str,
|
||||
sizeof(time_str),
|
||||
"%ld.%d:%c;",
|
||||
tv.tv_sec,
|
||||
tv.tv_usec,
|
||||
level_names[level][0]);
|
||||
fmt::format_to_n(time_str,
|
||||
sizeof(time_str),
|
||||
FMT_STRING("{}.{}:{};"),
|
||||
tv.tv_sec,
|
||||
tv.tv_usec,
|
||||
level_names[level][0]);
|
||||
|
||||
return pwrite(fd, time_str, strlen(time_str), woff);
|
||||
}
|
||||
|
@ -235,10 +235,10 @@ readline_context::completion_generator(const char* text_in, int state)
|
||||
|
||||
if (arg_needs_shlex) {
|
||||
shlex arg_lexer(text_str);
|
||||
std::map<std::string, std::string> scope;
|
||||
std::map<std::string, scoped_value_t> scope;
|
||||
std::string result;
|
||||
|
||||
if (arg_lexer.eval(result, scope)) {
|
||||
if (arg_lexer.eval(result, scoped_resolver{&scope})) {
|
||||
text_str = result;
|
||||
}
|
||||
}
|
||||
@ -381,11 +381,11 @@ readline_context::attempted_completion(const char* text, int start, int end)
|
||||
point -= 1;
|
||||
}
|
||||
shlex lexer(rl_line_buffer, point);
|
||||
std::map<std::string, std::string> scope;
|
||||
std::map<std::string, scoped_value_t> scope;
|
||||
|
||||
arg_possibilities = nullptr;
|
||||
rl_completion_append_character = 0;
|
||||
if (lexer.split(prefix, scope)) {
|
||||
if (lexer.split(prefix, scoped_resolver{&scope})) {
|
||||
auto prefix2
|
||||
= fmt::format(FMT_STRING("{}"), fmt::join(prefix, "\x1f"));
|
||||
auto prefix_iter = loaded_context->rc_prefixes.find(prefix2);
|
||||
@ -425,7 +425,7 @@ readline_context::attempted_completion(const char* text, int start, int end)
|
||||
shlex fn_lexer(rl_line_buffer, rl_point);
|
||||
std::vector<std::string> fn_list;
|
||||
|
||||
fn_lexer.split(fn_list, scope);
|
||||
fn_lexer.split(fn_list, scoped_resolver{&scope});
|
||||
|
||||
const auto& last_fn = fn_list.size() <= 1 ? ""
|
||||
: fn_list.back();
|
||||
@ -450,7 +450,7 @@ readline_context::attempted_completion(const char* text, int start, int end)
|
||||
std::vector<std::string> fn_list;
|
||||
int found = 0;
|
||||
|
||||
fn_lexer.split(fn_list, scope);
|
||||
fn_lexer.split(fn_list, scoped_resolver{&scope});
|
||||
|
||||
const auto& last_fn = fn_list.size() <= 1 ? ""
|
||||
: fn_list.back();
|
||||
|
@ -194,20 +194,6 @@ public:
|
||||
std::vector<shared_buffer_ref*> sb_refs;
|
||||
};
|
||||
|
||||
struct tmp_shared_buffer {
|
||||
explicit tmp_shared_buffer(const char* str, size_t len = -1)
|
||||
{
|
||||
if (len == (size_t) -1) {
|
||||
len = strlen(str);
|
||||
}
|
||||
|
||||
this->tsb_ref.share(this->tsb_manager, (char*) str, len);
|
||||
};
|
||||
|
||||
shared_buffer tsb_manager;
|
||||
shared_buffer_ref tsb_ref;
|
||||
};
|
||||
|
||||
inline std::string
|
||||
to_string(const shared_buffer_ref& sbr)
|
||||
{
|
||||
|
122
src/shlex.cc
122
src/shlex.cc
@ -216,3 +216,125 @@ shlex::resolve_home_dir(std::string& result, string_fragment cap) const
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
shlex::eval(std::string& result, const scoped_resolver& vars)
|
||||
{
|
||||
result.clear();
|
||||
|
||||
string_fragment cap;
|
||||
shlex_token_t token;
|
||||
int last_index = 0;
|
||||
|
||||
while (this->tokenize(cap, token)) {
|
||||
result.append(&this->s_str[last_index], cap.sf_begin - last_index);
|
||||
switch (token) {
|
||||
case shlex_token_t::ST_ERROR:
|
||||
return false;
|
||||
case shlex_token_t::ST_ESCAPE:
|
||||
result.append(1, this->s_str[cap.sf_begin + 1]);
|
||||
break;
|
||||
case shlex_token_t::ST_WHITESPACE:
|
||||
result.append(&this->s_str[cap.sf_begin], cap.length());
|
||||
break;
|
||||
case shlex_token_t::ST_VARIABLE_REF:
|
||||
case shlex_token_t::ST_QUOTED_VARIABLE_REF: {
|
||||
int extra = token == shlex_token_t::ST_VARIABLE_REF ? 0 : 1;
|
||||
const std::string var_name(
|
||||
&this->s_str[cap.sf_begin + 1 + extra],
|
||||
cap.length() - 1 - extra * 2);
|
||||
auto local_var = vars.find(var_name);
|
||||
const char* var_value = getenv(var_name.c_str());
|
||||
|
||||
if (local_var != vars.end()) {
|
||||
result.append(fmt::to_string(local_var->second));
|
||||
} else if (var_value != nullptr) {
|
||||
result.append(var_value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case shlex_token_t::ST_TILDE:
|
||||
this->resolve_home_dir(result, cap);
|
||||
break;
|
||||
case shlex_token_t::ST_DOUBLE_QUOTE_START:
|
||||
case shlex_token_t::ST_DOUBLE_QUOTE_END:
|
||||
result.append("\"");
|
||||
break;
|
||||
case shlex_token_t::ST_SINGLE_QUOTE_START:
|
||||
case shlex_token_t::ST_SINGLE_QUOTE_END:
|
||||
result.append("'");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
last_index = cap.sf_end;
|
||||
}
|
||||
|
||||
result.append(&this->s_str[last_index], this->s_len - last_index);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
shlex::split(std::vector<std::string>& result, const scoped_resolver& vars)
|
||||
{
|
||||
result.clear();
|
||||
|
||||
string_fragment cap;
|
||||
shlex_token_t token;
|
||||
int last_index = 0;
|
||||
bool start_new = true;
|
||||
|
||||
while (isspace(this->s_str[this->s_index])) {
|
||||
this->s_index += 1;
|
||||
}
|
||||
while (this->tokenize(cap, token)) {
|
||||
if (start_new) {
|
||||
result.emplace_back("");
|
||||
start_new = false;
|
||||
}
|
||||
result.back().append(&this->s_str[last_index],
|
||||
cap.sf_begin - last_index);
|
||||
switch (token) {
|
||||
case shlex_token_t::ST_ERROR:
|
||||
return false;
|
||||
case shlex_token_t::ST_ESCAPE:
|
||||
result.back().append(1, this->s_str[cap.sf_begin + 1]);
|
||||
break;
|
||||
case shlex_token_t::ST_WHITESPACE:
|
||||
start_new = true;
|
||||
break;
|
||||
case shlex_token_t::ST_VARIABLE_REF:
|
||||
case shlex_token_t::ST_QUOTED_VARIABLE_REF: {
|
||||
int extra = token == shlex_token_t::ST_VARIABLE_REF ? 0 : 1;
|
||||
std::string var_name(&this->s_str[cap.sf_begin + 1 + extra],
|
||||
cap.length() - 1 - extra * 2);
|
||||
auto local_var = vars.find(var_name);
|
||||
const char* var_value = getenv(var_name.c_str());
|
||||
|
||||
if (local_var != vars.end()) {
|
||||
result.back().append(fmt::to_string(local_var->second));
|
||||
} else if (var_value != nullptr) {
|
||||
result.back().append(var_value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case shlex_token_t::ST_TILDE:
|
||||
this->resolve_home_dir(result.back(), cap);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
last_index = cap.sf_end;
|
||||
}
|
||||
|
||||
if (last_index < this->s_len) {
|
||||
if (start_new || result.empty()) {
|
||||
result.emplace_back("");
|
||||
}
|
||||
result.back().append(&this->s_str[last_index],
|
||||
this->s_len - last_index);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
121
src/shlex.hh
121
src/shlex.hh
@ -75,126 +75,9 @@ public:
|
||||
|
||||
bool tokenize(string_fragment& cap_out, shlex_token_t& token_out);
|
||||
|
||||
template<typename Resolver = scoped_resolver>
|
||||
bool eval(std::string& result, const Resolver& vars)
|
||||
{
|
||||
result.clear();
|
||||
bool eval(std::string& result, const scoped_resolver& vars);
|
||||
|
||||
string_fragment cap;
|
||||
shlex_token_t token;
|
||||
int last_index = 0;
|
||||
|
||||
while (this->tokenize(cap, token)) {
|
||||
result.append(&this->s_str[last_index], cap.sf_begin - last_index);
|
||||
switch (token) {
|
||||
case shlex_token_t::ST_ERROR:
|
||||
return false;
|
||||
case shlex_token_t::ST_ESCAPE:
|
||||
result.append(1, this->s_str[cap.sf_begin + 1]);
|
||||
break;
|
||||
case shlex_token_t::ST_WHITESPACE:
|
||||
result.append(&this->s_str[cap.sf_begin], cap.length());
|
||||
break;
|
||||
case shlex_token_t::ST_VARIABLE_REF:
|
||||
case shlex_token_t::ST_QUOTED_VARIABLE_REF: {
|
||||
int extra = token == shlex_token_t::ST_VARIABLE_REF ? 0 : 1;
|
||||
std::string var_name(&this->s_str[cap.sf_begin + 1 + extra],
|
||||
cap.length() - 1 - extra * 2);
|
||||
auto local_var = vars.find(var_name);
|
||||
const char* var_value = getenv(var_name.c_str());
|
||||
|
||||
if (local_var != vars.end()) {
|
||||
result.append(fmt::to_string(local_var->second));
|
||||
} else if (var_value != nullptr) {
|
||||
result.append(var_value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case shlex_token_t::ST_TILDE:
|
||||
this->resolve_home_dir(result, cap);
|
||||
break;
|
||||
case shlex_token_t::ST_DOUBLE_QUOTE_START:
|
||||
case shlex_token_t::ST_DOUBLE_QUOTE_END:
|
||||
result.append("\"");
|
||||
break;
|
||||
case shlex_token_t::ST_SINGLE_QUOTE_START:
|
||||
case shlex_token_t::ST_SINGLE_QUOTE_END:
|
||||
result.append("'");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
last_index = cap.sf_end;
|
||||
}
|
||||
|
||||
result.append(&this->s_str[last_index], this->s_len - last_index);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename Resolver>
|
||||
bool split(std::vector<std::string>& result, const Resolver& vars)
|
||||
{
|
||||
result.clear();
|
||||
|
||||
string_fragment cap;
|
||||
shlex_token_t token;
|
||||
int last_index = 0;
|
||||
bool start_new = true;
|
||||
|
||||
while (isspace(this->s_str[this->s_index])) {
|
||||
this->s_index += 1;
|
||||
}
|
||||
while (this->tokenize(cap, token)) {
|
||||
if (start_new) {
|
||||
result.emplace_back("");
|
||||
start_new = false;
|
||||
}
|
||||
result.back().append(&this->s_str[last_index],
|
||||
cap.sf_begin - last_index);
|
||||
switch (token) {
|
||||
case shlex_token_t::ST_ERROR:
|
||||
return false;
|
||||
case shlex_token_t::ST_ESCAPE:
|
||||
result.back().append(1, this->s_str[cap.sf_begin + 1]);
|
||||
break;
|
||||
case shlex_token_t::ST_WHITESPACE:
|
||||
start_new = true;
|
||||
break;
|
||||
case shlex_token_t::ST_VARIABLE_REF:
|
||||
case shlex_token_t::ST_QUOTED_VARIABLE_REF: {
|
||||
int extra = token == shlex_token_t::ST_VARIABLE_REF ? 0 : 1;
|
||||
std::string var_name(&this->s_str[cap.sf_begin + 1 + extra],
|
||||
cap.length() - 1 - extra * 2);
|
||||
auto local_var = vars.find(var_name);
|
||||
const char* var_value = getenv(var_name.c_str());
|
||||
|
||||
if (local_var != vars.end()) {
|
||||
result.back().append(fmt::to_string(local_var->second));
|
||||
} else if (var_value != nullptr) {
|
||||
result.back().append(var_value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case shlex_token_t::ST_TILDE:
|
||||
this->resolve_home_dir(result.back(), cap);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
last_index = cap.sf_end;
|
||||
}
|
||||
|
||||
if (last_index < this->s_len) {
|
||||
if (start_new || result.empty()) {
|
||||
result.emplace_back("");
|
||||
}
|
||||
result.back().append(&this->s_str[last_index],
|
||||
this->s_len - last_index);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
bool split(std::vector<std::string>& result, const scoped_resolver& vars);
|
||||
|
||||
void reset()
|
||||
{
|
||||
|
@ -37,10 +37,10 @@
|
||||
#include <vector>
|
||||
|
||||
#include "base/intern_string.hh"
|
||||
#include "base/types.hh"
|
||||
#include "fmt/format.h"
|
||||
#include "mapbox/variant.hpp"
|
||||
|
||||
struct null_value_t {};
|
||||
using scoped_value_t = mapbox::util::
|
||||
variant<std::string, string_fragment, int64_t, double, null_value_t>;
|
||||
|
||||
@ -65,7 +65,7 @@ struct formatter<scoped_value_t> : formatter<std::string> {
|
||||
class scoped_resolver {
|
||||
public:
|
||||
scoped_resolver(
|
||||
std::initializer_list<std::map<std::string, scoped_value_t>*> l)
|
||||
std::initializer_list<const std::map<std::string, scoped_value_t>*> l)
|
||||
{
|
||||
this->sr_stack.insert(this->sr_stack.end(), l.begin(), l.end());
|
||||
}
|
||||
|
47
src/sql_execute.hh
Normal file
47
src/sql_execute.hh
Normal file
@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Copyright (c) 2023, Timothy Stack
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of Timothy Stack nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lnav_sql_execute_hh
|
||||
#define lnav_sql_execute_hh
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include "base/lnav.console.hh"
|
||||
#include "shlex.resolver.hh"
|
||||
|
||||
void sql_execute_script(
|
||||
sqlite3* db,
|
||||
const std::map<std::string, scoped_value_t>& global_vars,
|
||||
const char* src_name,
|
||||
const char* script,
|
||||
std::vector<lnav::console::user_message>& errors);
|
||||
|
||||
#endif
|
@ -36,7 +36,6 @@
|
||||
#include "sql_util.hh"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "base/auto_mem.hh"
|
||||
@ -50,7 +49,7 @@
|
||||
#include "pcrepp/pcre2pp.hh"
|
||||
#include "readline_context.hh"
|
||||
#include "readline_highlighters.hh"
|
||||
#include "shlex.resolver.hh"
|
||||
#include "sql_execute.hh"
|
||||
#include "sql_help.hh"
|
||||
#include "sqlite-extension-func.hh"
|
||||
|
||||
|
@ -109,13 +109,6 @@ char* sql_quote_ident(const char* ident);
|
||||
|
||||
std::string sql_safe_ident(const string_fragment& ident);
|
||||
|
||||
void sql_execute_script(
|
||||
sqlite3* db,
|
||||
const std::map<std::string, scoped_value_t>& global_vars,
|
||||
const char* src_name,
|
||||
const char* script,
|
||||
std::vector<lnav::console::user_message>& errors);
|
||||
|
||||
int guess_type_from_pcre(const std::string& pattern, std::string& collator);
|
||||
|
||||
const char* sqlite3_type_to_string(int type);
|
||||
|
@ -37,8 +37,9 @@
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include "base/auto_mem.hh"
|
||||
#include "base/intern_string.hh"
|
||||
#include "base/types.hh"
|
||||
#include "optional.hpp"
|
||||
#include "shlex.resolver.hh"
|
||||
|
||||
/* XXX figure out how to do this with the template */
|
||||
void sqlite_close_wrapper(void* mem);
|
||||
|
@ -208,11 +208,13 @@ textview_curses::reload_config(error_reporter& reporter)
|
||||
iter = this->tc_highlights.erase(iter);
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> vars;
|
||||
std::map<std::string, scoped_value_t> vars;
|
||||
auto curr_theme_iter
|
||||
= lnav_config.lc_ui_theme_defs.find(lnav_config.lc_ui_theme);
|
||||
if (curr_theme_iter != lnav_config.lc_ui_theme_defs.end()) {
|
||||
vars = curr_theme_iter->second.lt_vars;
|
||||
for (const auto& vpair : curr_theme_iter->second.lt_vars) {
|
||||
vars[vpair.first] = vpair.second;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& theme_name : {DEFAULT_THEME_NAME, lnav_config.lc_ui_theme})
|
||||
@ -247,8 +249,8 @@ textview_curses::reload_config(error_reporter& reporter)
|
||||
|
||||
fg1 = sc.sc_color;
|
||||
bg1 = sc.sc_background_color;
|
||||
shlex(fg1).eval(fg_color, vars);
|
||||
shlex(bg1).eval(bg_color, vars);
|
||||
shlex(fg1).eval(fg_color, scoped_resolver{&vars});
|
||||
shlex(bg1).eval(bg_color, scoped_resolver{&vars});
|
||||
|
||||
auto fg = styling::color_unit::from_str(fg_color).unwrapOrElse(
|
||||
[&](const auto& msg) {
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include "md2attr_line.hh"
|
||||
#include "md4cpp.hh"
|
||||
#include "shlex.hh"
|
||||
#include "shlex.resolver.hh"
|
||||
#include "sql_util.hh"
|
||||
#include "sqlitepp.client.hh"
|
||||
#include "top_status_source.cfg.hh"
|
||||
@ -99,7 +98,8 @@ top_status_source::update_user_msg()
|
||||
std::string user_note;
|
||||
|
||||
lexer.with_ignore_quotes(true).eval(
|
||||
user_note, lnav_data.ld_exec_context.ec_global_vars);
|
||||
user_note,
|
||||
scoped_resolver{&lnav_data.ld_exec_context.ec_global_vars});
|
||||
|
||||
md2attr_line mdal;
|
||||
auto parse_res = md4cpp::parse(user_note, mdal);
|
||||
|
@ -619,8 +619,12 @@ view_colors::to_attrs(const lnav_theme& lt,
|
||||
|
||||
fg1 = sc.sc_color;
|
||||
bg1 = sc.sc_background_color;
|
||||
shlex(fg1).eval(fg_color, lt.lt_vars);
|
||||
shlex(bg1).eval(bg_color, lt.lt_vars);
|
||||
std::map<std::string, scoped_value_t> vars;
|
||||
for (const auto& vpair : lt.lt_vars) {
|
||||
vars[vpair.first] = vpair.second;
|
||||
}
|
||||
shlex(fg1).eval(fg_color, scoped_resolver{&vars});
|
||||
shlex(bg1).eval(bg_color, scoped_resolver{&vars});
|
||||
|
||||
auto fg = styling::color_unit::from_str(fg_color).unwrapOrElse(
|
||||
[&](const auto& msg) {
|
||||
|
@ -461,7 +461,8 @@ build_all_help_text()
|
||||
std::string sub_help_text;
|
||||
|
||||
lexer.with_ignore_quotes(true).eval(
|
||||
sub_help_text, lnav_data.ld_exec_context.ec_global_vars);
|
||||
sub_help_text,
|
||||
scoped_resolver{&lnav_data.ld_exec_context.ec_global_vars});
|
||||
|
||||
md2attr_line mdal;
|
||||
auto parse_res = md4cpp::parse(sub_help_text, mdal);
|
||||
|
@ -41,11 +41,11 @@
|
||||
#include "base/lnav.console.hh"
|
||||
#include "base/lnav_log.hh"
|
||||
#include "base/string_util.hh"
|
||||
#include "base/types.hh"
|
||||
#include "fmt/format.h"
|
||||
#include "help_text_formatter.hh"
|
||||
#include "mapbox/variant.hpp"
|
||||
#include "optional.hpp"
|
||||
#include "shlex.resolver.hh"
|
||||
#include "sqlite-extension-func.hh"
|
||||
|
||||
lnav::console::user_message sqlite3_error_to_user_message(sqlite3*);
|
||||
@ -67,10 +67,7 @@ struct sqlite_func_error : std::exception {
|
||||
{
|
||||
}
|
||||
|
||||
const char* what() const noexcept override
|
||||
{
|
||||
return this->e_what.c_str();
|
||||
}
|
||||
const char* what() const noexcept override { return this->e_what.c_str(); }
|
||||
|
||||
const std::string e_what;
|
||||
};
|
||||
@ -83,12 +80,10 @@ struct nullable {
|
||||
};
|
||||
|
||||
template<typename>
|
||||
struct is_nullable : std::false_type {
|
||||
};
|
||||
struct is_nullable : std::false_type {};
|
||||
|
||||
template<typename T>
|
||||
struct is_nullable<nullable<T>> : std::true_type {
|
||||
};
|
||||
struct is_nullable<nullable<T>> : std::true_type {};
|
||||
|
||||
} // namespace vtab_types
|
||||
|
||||
@ -296,7 +291,7 @@ to_sqlite(sqlite3_context* ctx, double val)
|
||||
inline void
|
||||
to_sqlite(sqlite3_context* ctx, auto_mem<char> str)
|
||||
{
|
||||
auto free_func = str.get_free_func<void(*)(void*)>();
|
||||
auto free_func = str.get_free_func<void (*)(void*)>();
|
||||
sqlite3_result_text(ctx, str.release(), -1, free_func);
|
||||
}
|
||||
|
||||
@ -372,8 +367,7 @@ struct optional_counter<Arg> {
|
||||
};
|
||||
|
||||
template<typename Arg1, typename... Args>
|
||||
struct optional_counter<Arg1, Args...> : optional_counter<Args...> {
|
||||
};
|
||||
struct optional_counter<Arg1, Args...> : optional_counter<Args...> {};
|
||||
|
||||
template<typename... Args>
|
||||
struct variadic_counter {
|
||||
@ -391,8 +385,7 @@ struct variadic_counter<Arg> {
|
||||
};
|
||||
|
||||
template<typename Arg1, typename... Args>
|
||||
struct variadic_counter<Arg1, Args...> : variadic_counter<Args...> {
|
||||
};
|
||||
struct variadic_counter<Arg1, Args...> : variadic_counter<Args...> {};
|
||||
|
||||
template<typename F, F f>
|
||||
struct sqlite_func_adapter;
|
||||
@ -821,10 +814,7 @@ struct vtab_module : public vtab_module_base {
|
||||
return sqlite3_exec(db, create_stmt.c_str(), nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
int create(sqlite3* db) override
|
||||
{
|
||||
return this->create(db, T::NAME);
|
||||
}
|
||||
int create(sqlite3* db) override { return this->create(db, T::NAME); }
|
||||
|
||||
sqlite3_module vm_module;
|
||||
T vm_impl;
|
||||
|
@ -80,12 +80,13 @@ main(int argc, char* argv[])
|
||||
|
||||
lexer.reset();
|
||||
std::string result;
|
||||
if (lexer.eval(result, map<string, string>())) {
|
||||
std::map<std::string, scoped_value_t> vars;
|
||||
if (lexer.eval(result, scoped_resolver{&vars})) {
|
||||
printf("eval -- %s\n", result.c_str());
|
||||
}
|
||||
lexer.reset();
|
||||
std::vector<std::string> sresult;
|
||||
if (lexer.split(sresult, map<string, string>())) {
|
||||
if (lexer.split(sresult, scoped_resolver{&vars})) {
|
||||
printf("split:\n");
|
||||
for (size_t lpc = 0; lpc < sresult.size(); lpc++) {
|
||||
printf(" %zu -- %s\n", lpc, sresult[lpc].c_str());
|
||||
|
Loading…
Reference in New Issue
Block a user