mirror of https://github.com/tstack/lnav.git
[build] compress data files embedded in the binary to save some space
Fixes #763
This commit is contained in:
parent
63c31838eb
commit
1d17ac7f29
|
@ -13,7 +13,8 @@ set(VCS_PACKAGE_STRING "test")
|
|||
|
||||
configure_file(config.cmake.h.in config.h)
|
||||
|
||||
add_executable(bin2c bin2c.h bin2c.c)
|
||||
add_executable(bin2c bin2c.hh bin2c.c)
|
||||
target_link_libraries(bin2c ZLIB::zlib)
|
||||
|
||||
add_executable(ptimec ptimec.hh ptimec.c)
|
||||
|
||||
|
@ -89,7 +90,7 @@ function(bin2c)
|
|||
|
||||
list(TRANSFORM BIN2C_UNPARSED_ARGUMENTS "\\." "-")
|
||||
add_custom_command(
|
||||
OUTPUT "${DST_FILE}.h" "${DST_FILE}.c"
|
||||
OUTPUT "${DST_FILE}.h" "${DST_FILE}.cc"
|
||||
COMMAND bin2c "${DST_FILE}" "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_TO_LINK}"
|
||||
DEPENDS bin2c "${FILE_TO_LINK}"
|
||||
)
|
||||
|
@ -102,14 +103,14 @@ foreach(FILE_TO_LINK
|
|||
init.sql)
|
||||
string(REPLACE "." "-" DST_FILE "${FILE_TO_LINK}")
|
||||
add_custom_command(
|
||||
OUTPUT "${DST_FILE}.h" "${DST_FILE}.c"
|
||||
OUTPUT "${DST_FILE}.h" "${DST_FILE}.cc"
|
||||
COMMAND bin2c "${DST_FILE}" "${CMAKE_CURRENT_SOURCE_DIR}/${FILE_TO_LINK}"
|
||||
DEPENDS bin2c "${FILE_TO_LINK}"
|
||||
)
|
||||
list(
|
||||
APPEND GEN_SRCS
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${DST_FILE}.h"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${DST_FILE}.c"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${DST_FILE}.cc"
|
||||
)
|
||||
endforeach(FILE_TO_LINK)
|
||||
|
||||
|
@ -156,11 +157,11 @@ set(FORMAT_FILE_PATHS ${FORMAT_FILES})
|
|||
list(TRANSFORM FORMAT_FILE_PATHS PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT default-formats.h default-formats.c
|
||||
OUTPUT default-formats.h default-formats.cc
|
||||
COMMAND bin2c -n lnav_format_json default-formats ${FORMAT_FILE_PATHS}
|
||||
DEPENDS bin2c ${FORMAT_FILES}
|
||||
)
|
||||
list(APPEND GEN_SRCS default-formats.h default-formats.c)
|
||||
list(APPEND GEN_SRCS default-formats.h default-formats.cc)
|
||||
|
||||
set(CONFIG_FILES
|
||||
root-config.json
|
||||
|
@ -182,11 +183,11 @@ set(CONFIG_FILE_PATHS ${CONFIG_FILES})
|
|||
list(TRANSFORM CONFIG_FILE_PATHS PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT default-config.h default-config.c
|
||||
OUTPUT default-config.h default-config.cc
|
||||
COMMAND bin2c -n lnav_config_json default-config ${CONFIG_FILE_PATHS}
|
||||
DEPENDS bin2c ${CONFIG_FILES}
|
||||
)
|
||||
list(APPEND GEN_SRCS default-config.h default-config.c)
|
||||
list(APPEND GEN_SRCS default-config.h default-config.cc)
|
||||
|
||||
|
||||
set(BUILTIN_LNAV_SCRIPTS
|
||||
|
@ -201,11 +202,11 @@ set(BUILTIN_LNAV_SCRIPT_PATHS ${BUILTIN_LNAV_SCRIPTS})
|
|||
list(TRANSFORM BUILTIN_LNAV_SCRIPT_PATHS PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT builtin-scripts.h builtin-scripts.c
|
||||
OUTPUT builtin-scripts.h builtin-scripts.cc
|
||||
COMMAND bin2c -n lnav_scripts builtin-scripts ${BUILTIN_LNAV_SCRIPT_PATHS}
|
||||
DEPENDS bin2c ${BUILTIN_LNAV_SCRIPTS}
|
||||
)
|
||||
list(APPEND GEN_SRCS builtin-scripts.h builtin-scripts.c)
|
||||
list(APPEND GEN_SRCS builtin-scripts.h builtin-scripts.cc)
|
||||
|
||||
set(BUILTIN_SH_SCRIPTS
|
||||
scripts/dhclient-summary.lnav
|
||||
|
@ -218,11 +219,11 @@ set(BUILTIN_SH_SCRIPT_PATHS ${BUILTIN_SH_SCRIPTS})
|
|||
list(TRANSFORM BUILTIN_SH_SCRIPT_PATHS PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT builtin-sh-scripts.h builtin-sh-scripts.c
|
||||
OUTPUT builtin-sh-scripts.h builtin-sh-scripts.cc
|
||||
COMMAND bin2c -n lnav_sh_scripts builtin-sh-scripts ${BUILTIN_SH_SCRIPT_PATHS}
|
||||
DEPENDS bin2c ${BUILTIN_SH_SCRIPTS}
|
||||
)
|
||||
list(APPEND GEN_SRCS builtin-sh-scripts.h builtin-sh-scripts.c)
|
||||
list(APPEND GEN_SRCS builtin-sh-scripts.h builtin-sh-scripts.cc)
|
||||
|
||||
add_library(diag STATIC
|
||||
${GEN_SRCS}
|
||||
|
@ -233,7 +234,7 @@ add_library(diag STATIC
|
|||
ansi_scrubber.cc
|
||||
archive_manager.cc
|
||||
attr_line.cc
|
||||
bin2c.h
|
||||
bin2c.hh
|
||||
bookmarks.cc
|
||||
bottom_status_source.cc
|
||||
collation-functions.cc
|
||||
|
|
|
@ -57,7 +57,7 @@ FORMAT_FILES = \
|
|||
$(srcdir)/formats/xmlrpc_log.json \
|
||||
$()
|
||||
|
||||
default-formats.h default-formats.c: bin2c$(BUILD_EXEEXT) $(FORMAT_FILES)
|
||||
default-formats.h default-formats.cc: bin2c$(BUILD_EXEEXT) $(FORMAT_FILES)
|
||||
$(BIN2C_V)./bin2c$(BUILD_EXEEXT) -n lnav_format_json default-formats $(FORMAT_FILES)
|
||||
|
||||
CONFIG_FILES = \
|
||||
|
@ -75,7 +75,7 @@ CONFIG_FILES = \
|
|||
$(srcdir)/themes/solarized-light.json \
|
||||
$()
|
||||
|
||||
default-config.h default-config.c: bin2c$(BUILD_EXEEXT) $(CONFIG_FILES)
|
||||
default-config.h default-config.cc: bin2c$(BUILD_EXEEXT) $(CONFIG_FILES)
|
||||
$(BIN2C_V)./bin2c$(BUILD_EXEEXT) -n lnav_config_json default-config $(CONFIG_FILES)
|
||||
|
||||
BUILTIN_LNAVSCRIPTS = \
|
||||
|
@ -86,29 +86,29 @@ BUILTIN_LNAVSCRIPTS = \
|
|||
$(srcdir)/scripts/search-for.lnav \
|
||||
$()
|
||||
|
||||
builtin-scripts.h builtin-scripts.c: bin2c$(BUILD_EXEEXT) $(BUILTIN_LNAVSCRIPTS)
|
||||
builtin-scripts.h builtin-scripts.cc: bin2c$(BUILD_EXEEXT) $(BUILTIN_LNAVSCRIPTS)
|
||||
$(BIN2C_V)./bin2c$(BUILD_EXEEXT) -n lnav_scripts builtin-scripts $(BUILTIN_LNAVSCRIPTS)
|
||||
|
||||
BUILTIN_SHSCRIPTS = \
|
||||
$(srcdir)/scripts/dump-pid.sh \
|
||||
$()
|
||||
|
||||
builtin-sh-scripts.h builtin-sh-scripts.c: bin2c$(BUILD_EXEEXT) $(BUILTIN_SHSCRIPTS)
|
||||
builtin-sh-scripts.h builtin-sh-scripts.cc: bin2c$(BUILD_EXEEXT) $(BUILTIN_SHSCRIPTS)
|
||||
$(BIN2C_V)./bin2c$(BUILD_EXEEXT) -n lnav_sh_scripts builtin-sh-scripts $(BUILTIN_SHSCRIPTS)
|
||||
|
||||
%-sh.c: $(srcdir)/%.sh bin2c$(BUILD_EXEEXT)
|
||||
%-sh.cc: $(srcdir)/%.sh bin2c$(BUILD_EXEEXT)
|
||||
$(BIN2C_V)./bin2c$(BUILD_EXEEXT) $(*)-sh $<
|
||||
|
||||
%-txt.c %-txt.h: $(srcdir)/%.txt bin2c$(BUILD_EXEEXT)
|
||||
%-txt.cc %-txt.h: $(srcdir)/%.txt bin2c$(BUILD_EXEEXT)
|
||||
$(BIN2C_V)./bin2c$(BUILD_EXEEXT) $(*)-txt $<
|
||||
|
||||
%-sql.c %-sql.h: $(srcdir)/%.sql bin2c$(BUILD_EXEEXT)
|
||||
%-sql.cc %-sql.h: $(srcdir)/%.sql bin2c$(BUILD_EXEEXT)
|
||||
$(BIN2C_V)./bin2c$(BUILD_EXEEXT) $(*)-sql $<
|
||||
|
||||
%-lnav.c %-lnav.h: $(srcdir)/%.lnav bin2c$(BUILD_EXEEXT)
|
||||
%-lnav.cc %-lnav.h: $(srcdir)/%.lnav bin2c$(BUILD_EXEEXT)
|
||||
$(BIN2C_V)./bin2c$(BUILD_EXEEXT) $(*)-lnav $<
|
||||
|
||||
%-json.c %-json.h: $(srcdir)/%.json bin2c$(BUILD_EXEEXT)
|
||||
%-json.cc %-json.h: $(srcdir)/%.json bin2c$(BUILD_EXEEXT)
|
||||
$(BIN2C_V)./bin2c$(BUILD_EXEEXT) $(*)-json $<
|
||||
|
||||
TIME_FORMATS = \
|
||||
|
@ -186,22 +186,22 @@ view_helpers.$(OBJEXT): help-txt.h
|
|||
|
||||
LNAV_BUILT_FILES = \
|
||||
ansi-palette-json.h \
|
||||
ansi-palette-json.c \
|
||||
ansi-palette-json.cc \
|
||||
builtin-scripts.h \
|
||||
builtin-scripts.c \
|
||||
builtin-scripts.cc \
|
||||
builtin-sh-scripts.h \
|
||||
builtin-sh-scripts.c \
|
||||
builtin-sh-scripts.cc \
|
||||
default-config.h \
|
||||
default-config.c \
|
||||
default-config.cc \
|
||||
default-formats.h \
|
||||
default-formats.c \
|
||||
default-formats.cc \
|
||||
help-txt.h \
|
||||
help-txt.c \
|
||||
help-txt.cc \
|
||||
init-sql.h \
|
||||
init-sql.c \
|
||||
init-sql.cc \
|
||||
time_fmts.cc \
|
||||
xterm-palette-json.h \
|
||||
xterm-palette-json.c
|
||||
xterm-palette-json.cc
|
||||
|
||||
AM_LDFLAGS = \
|
||||
$(STATIC_LDFLAGS) \
|
||||
|
@ -254,7 +254,7 @@ noinst_HEADERS = \
|
|||
auto_mem.hh \
|
||||
auto_pid.hh \
|
||||
big_array.hh \
|
||||
bin2c.h \
|
||||
bin2c.hh \
|
||||
bookmarks.hh \
|
||||
bottom_status_source.hh \
|
||||
byte_array.hh \
|
||||
|
@ -497,10 +497,10 @@ lnav_SOURCES = lnav.cc
|
|||
lnav_test_SOURCES = lnav.cc test_override.c
|
||||
|
||||
bin2c$(BUILD_EXEEXT): bin2c.c
|
||||
$(AM_V_CC) $(CC_FOR_BUILD) -o $@ $?
|
||||
$(AM_V_CC) $(CC_FOR_BUILD) -g3 -o $@ $? -lz
|
||||
|
||||
ptimec$(BUILD_EXEEXT): ptimec.c
|
||||
$(AM_V_CC) $(CC_FOR_BUILD) -o $@ $?
|
||||
$(AM_V_CC) $(CC_FOR_BUILD) -g3 -o $@ $?
|
||||
|
||||
if HAVE_RE2C
|
||||
RE2C_FILES = data_scanner_re.cc log_level_re.cc
|
||||
|
|
102
src/bin2c.c
102
src/bin2c.c
|
@ -8,13 +8,15 @@
|
|||
// worth it, you can buy me a beer in return. Sandro Sigala
|
||||
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#include "bin2c.h"
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 1024
|
||||
|
@ -26,15 +28,19 @@ static const char *HEADER_FMT =
|
|||
"#ifndef bin2c_%s_h\n"
|
||||
"#define bin2c_%s_h\n"
|
||||
"\n"
|
||||
"#include \"bin2c.h\"\n"
|
||||
"#include \"bin2c.hh\"\n"
|
||||
"\n"
|
||||
"extern \"C\" {\n"
|
||||
"extern struct bin_src_file %s%s;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"#endif\n"
|
||||
"\n";
|
||||
|
||||
struct file_meta {
|
||||
const char *fm_name;
|
||||
unsigned int fm_compressed_size;
|
||||
unsigned int fm_size;
|
||||
};
|
||||
|
||||
void symname(char *dst, const char *fname)
|
||||
{
|
||||
strcpy(dst, fname);
|
||||
|
@ -45,24 +51,40 @@ void symname(char *dst, const char *fname)
|
|||
}
|
||||
}
|
||||
|
||||
void process(struct bin_src_file *bsf, FILE *ofile)
|
||||
void process(struct file_meta *fm, FILE *ofile)
|
||||
{
|
||||
FILE *ifile;
|
||||
struct stat st;
|
||||
|
||||
ifile = fopen(bsf->bsf_name, "rb");
|
||||
if (ifile == NULL)
|
||||
{
|
||||
fprintf(stderr, "cannot open %s for reading\n", bsf->bsf_name);
|
||||
exit(1);
|
||||
}
|
||||
if (stat(fm->fm_name, &st) == -1) {
|
||||
perror("unable to stat file");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
unsigned char *buf = malloc(st.st_size);
|
||||
unsigned char *dest = malloc(st.st_size);
|
||||
|
||||
int fd = open(fm->fm_name, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
perror("unable to open file");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int rc;
|
||||
while ((rc = read(fd, &buf[fm->fm_size], (st.st_size - fm->fm_size))) > 0) {
|
||||
fm->fm_size += rc;
|
||||
}
|
||||
|
||||
uLongf destLen = st.st_size;
|
||||
compress(dest, &destLen, buf, st.st_size);
|
||||
fm->fm_compressed_size = destLen;
|
||||
|
||||
int c, col = 1;
|
||||
char sym[1024];
|
||||
|
||||
symname(sym, basename((char *) bsf->bsf_name));
|
||||
symname(sym, basename((char *) fm->fm_name));
|
||||
fprintf(ofile, "static const unsigned char %s_data[] = {\n", sym);
|
||||
while ((c = fgetc(ifile)) != EOF)
|
||||
{
|
||||
for (int lpc = 0; lpc < destLen; lpc++) {
|
||||
c = dest[lpc];
|
||||
if (col >= 78 - 6)
|
||||
{
|
||||
fputc('\n', ofile);
|
||||
|
@ -70,15 +92,15 @@ void process(struct bin_src_file *bsf, FILE *ofile)
|
|||
}
|
||||
fprintf(ofile, "0x%.2x, ", c);
|
||||
col += 6;
|
||||
bsf->bsf_size += 1;
|
||||
}
|
||||
fprintf(ofile, "0x00\n");
|
||||
fprintf(ofile, "\n};\n");
|
||||
|
||||
fclose(ifile);
|
||||
free(buf);
|
||||
free(dest);
|
||||
}
|
||||
|
||||
void usage(void)
|
||||
void usage()
|
||||
{
|
||||
fprintf(stderr, "usage: bin2c [-n name] <output_file> [input_file1 ...]\n");
|
||||
exit(1);
|
||||
|
@ -121,7 +143,7 @@ int main(int argc, char **argv)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
snprintf(cname, sizeof(cname), "%s.c", out_base_name);
|
||||
snprintf(cname, sizeof(cname), "%s.cc", out_base_name);
|
||||
FILE *cfile = fopen(cname, "wb");
|
||||
if (cfile == NULL)
|
||||
{
|
||||
|
@ -139,43 +161,53 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
int array = argc > 1 || name;
|
||||
char trailer[16];
|
||||
|
||||
if (array) {
|
||||
snprintf(trailer, sizeof(trailer), "[%d]", argc);
|
||||
} else {
|
||||
trailer[0] = '\0';
|
||||
}
|
||||
fprintf(hfile, HEADER_FMT,
|
||||
sym,
|
||||
sym,
|
||||
sym,
|
||||
array ? "[]" : "");
|
||||
sym,
|
||||
sym,
|
||||
sym,
|
||||
trailer);
|
||||
fclose(hfile);
|
||||
|
||||
fprintf(cfile, "#include \"bin2c.h\"\n");
|
||||
fprintf(cfile, "#include \"bin2c.hh\"\n");
|
||||
fprintf(cfile, "\n");
|
||||
|
||||
struct bin_src_file *meta = alloca(sizeof(struct bin_src_file) * argc);
|
||||
struct file_meta *meta = alloca(sizeof(struct file_meta) * argc);
|
||||
|
||||
memset(meta, 0, sizeof(struct bin_src_file) * argc);
|
||||
memset(meta, 0, sizeof(struct file_meta) * argc);
|
||||
for (int lpc = 0; lpc < argc; lpc++) {
|
||||
meta[lpc].bsf_name = argv[lpc];
|
||||
meta[lpc].fm_name = argv[lpc];
|
||||
process(&meta[lpc], cfile);
|
||||
}
|
||||
|
||||
fprintf(cfile, "struct bin_src_file %s%s = {\n", sym, array ? "[]" : "");
|
||||
fprintf(cfile,
|
||||
"struct bin_src_file %s%s = {\n",
|
||||
sym,
|
||||
trailer);
|
||||
for (int lpc = 0; lpc < argc; lpc++) {
|
||||
char sym[1024];
|
||||
|
||||
symname(sym, basename((char *) meta[lpc].bsf_name));
|
||||
symname(sym, basename((char *) meta[lpc].fm_name));
|
||||
fprintf(cfile, " ");
|
||||
if (array) {
|
||||
fprintf(cfile, "{ ");
|
||||
}
|
||||
fprintf(cfile, "\"%s\", %s_data, %d",
|
||||
basename((char *) meta[lpc].bsf_name), sym, meta[lpc].bsf_size);
|
||||
fprintf(cfile, "\"%s\", %s_data, %d, %d",
|
||||
basename((char *) meta[lpc].fm_name),
|
||||
sym,
|
||||
meta[lpc].fm_compressed_size,
|
||||
meta[lpc].fm_size);
|
||||
if (array) {
|
||||
fprintf(cfile, " },");
|
||||
}
|
||||
fprintf(cfile, "\n");
|
||||
}
|
||||
if (array) {
|
||||
fprintf(cfile, " { 0 }\n");
|
||||
}
|
||||
fprintf(cfile, "};\n");
|
||||
fclose(cfile);
|
||||
|
||||
|
|
11
src/bin2c.h
11
src/bin2c.h
|
@ -1,11 +0,0 @@
|
|||
|
||||
#ifndef lnav_bin2c_h
|
||||
#define lnav_bin2c_h
|
||||
|
||||
struct bin_src_file {
|
||||
const char *bsf_name;
|
||||
const unsigned char *bsf_data;
|
||||
unsigned int bsf_size;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,69 @@
|
|||
/**
|
||||
* Copyright (c) 2020, 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 bin2c.hh
|
||||
*/
|
||||
|
||||
#ifndef lnav_bin2c_hh
|
||||
#define lnav_bin2c_hh
|
||||
|
||||
#include <zlib.h>
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "base/intern_string.hh"
|
||||
|
||||
struct bin_src_file {
|
||||
bin_src_file(const char *name, const unsigned char *data,
|
||||
size_t compressed_size, size_t size)
|
||||
: bsf_name(name), bsf_data(new unsigned char[size + 1]), bsf_size(size)
|
||||
{
|
||||
uLongf zsize = size;
|
||||
auto rc = uncompress(this->bsf_data.get(), &zsize, data, compressed_size);
|
||||
assert(rc == Z_OK);
|
||||
assert(zsize == size);
|
||||
this->bsf_data[size] = '\0';
|
||||
};
|
||||
|
||||
string_fragment to_string_fragment() const
|
||||
{
|
||||
return string_fragment{this->bsf_data.get(), 0, (int) this->bsf_size};
|
||||
}
|
||||
|
||||
const char *get_name() const
|
||||
{
|
||||
return this->bsf_name;
|
||||
}
|
||||
|
||||
private:
|
||||
const char *bsf_name;
|
||||
std::unique_ptr<unsigned char[]> bsf_data;
|
||||
ssize_t bsf_size;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -6,11 +6,16 @@
|
|||
"url": "http://docs.openstack.org/openstack-ops/content/logging_monitoring.html",
|
||||
"regex": {
|
||||
"std": {
|
||||
"pattern": "^(?<timestamp>\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}.\\d{3}) (?<pid>\\d+) (?<level>\\w+) (?<logger>.+) \\[(?<tid>.+)\\] (?<body>.*)"
|
||||
"pattern": "^(?<timestamp>\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}.\\d{3}) (?<pid>\\d+) (?<level>\\w+) (?<logger>\\S+) \\[(?<tid>[^\\]]+)\\] (?<body>.*)"
|
||||
},
|
||||
"mod-std": {
|
||||
"module-format": true,
|
||||
"pattern": "^(?<level>\\w+) (?<logger>\\S+) \\[(?<tid>[^\\]]+)\\] (?<body>.*)"
|
||||
}
|
||||
},
|
||||
"level-field": "level",
|
||||
"level": {
|
||||
"critical": "CRITICAL",
|
||||
"error": "ERROR",
|
||||
"info": "INFO",
|
||||
"warning": "WARNING",
|
||||
|
|
|
@ -1331,7 +1331,7 @@ static void looper()
|
|||
define_key("\033Oc", KEY_END);
|
||||
|
||||
view_colors &vc = view_colors::singleton();
|
||||
vc.init();
|
||||
view_colors::init();
|
||||
|
||||
{
|
||||
setup_highlights(lnav_data.ld_views[LNV_LOG].get_highlights());
|
||||
|
@ -2197,7 +2197,7 @@ int main(int argc, char *argv[])
|
|||
auto_mem<char, sqlite3_free> errmsg;
|
||||
|
||||
if (sqlite3_exec(lnav_data.ld_db.in(),
|
||||
(const char *) init_sql.bsf_data,
|
||||
init_sql.to_string_fragment().data(),
|
||||
nullptr,
|
||||
nullptr,
|
||||
errmsg.out()) != SQLITE_OK) {
|
||||
|
@ -2611,6 +2611,7 @@ int main(int argc, char *argv[])
|
|||
textview_curses *log_tc, *text_tc, *tc;
|
||||
bool found_error = false;
|
||||
|
||||
view_colors::init();
|
||||
rescan_files(true);
|
||||
if (!lnav_data.ld_active_files.fc_name_to_errors.empty()) {
|
||||
for (const auto& pair : lnav_data.ld_active_files.fc_name_to_errors) {
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
#include "yajlpp/yajlpp.hh"
|
||||
#include "yajlpp/yajlpp_def.hh"
|
||||
#include "styling.hh"
|
||||
#include "bin2c.h"
|
||||
#include "bin2c.hh"
|
||||
#include "default-config.h"
|
||||
|
||||
using namespace std;
|
||||
|
@ -990,10 +990,10 @@ static void load_config_from(const ghc::filesystem::path &path, vector<string> &
|
|||
|
||||
static void load_default_config(struct _lnav_config &config_obj,
|
||||
const std::string &path,
|
||||
struct bin_src_file &bsf,
|
||||
const bin_src_file &bsf,
|
||||
vector<string> &errors)
|
||||
{
|
||||
yajlpp_parse_context ypc_builtin(bsf.bsf_name, &lnav_config_handlers);
|
||||
yajlpp_parse_context ypc_builtin(bsf.get_name(), &lnav_config_handlers);
|
||||
auto_mem<yajl_handle_t> handle(yajl_free);
|
||||
struct userdata ud(errors);
|
||||
|
||||
|
@ -1011,18 +1011,17 @@ static void load_default_config(struct _lnav_config &config_obj,
|
|||
|
||||
yajl_config(handle, yajl_allow_comments, 1);
|
||||
yajl_config(handle, yajl_allow_multiple_values, 1);
|
||||
if (ypc_builtin.parse(bsf.bsf_data, bsf.bsf_size) == yajl_status_ok) {
|
||||
if (ypc_builtin.parse(bsf.to_string_fragment()) == yajl_status_ok) {
|
||||
ypc_builtin.complete_parse();
|
||||
}
|
||||
}
|
||||
|
||||
static void load_default_configs(struct _lnav_config &config_obj,
|
||||
const std::string &path,
|
||||
struct bin_src_file bsf[],
|
||||
vector<string> &errors)
|
||||
{
|
||||
for (int lpc = 0; bsf[lpc].bsf_name; lpc++) {
|
||||
load_default_config(config_obj, path, bsf[lpc], errors);
|
||||
for (auto& bsf : lnav_config_json) {
|
||||
load_default_config(config_obj, path, bsf, errors);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1030,22 +1029,22 @@ void load_config(const vector<ghc::filesystem::path> &extra_paths, vector<string
|
|||
{
|
||||
auto user_config = dotlnav_path() / "config.json";
|
||||
|
||||
for (int lpc = 0; lnav_config_json[lpc].bsf_name; lpc++) {
|
||||
auto &bsf = lnav_config_json[lpc];
|
||||
for (auto& bsf : lnav_config_json) {
|
||||
auto sample_path = dotlnav_path() /
|
||||
"configs" /
|
||||
"default" /
|
||||
fmt::format("{}.sample", bsf.bsf_name);
|
||||
fmt::format("{}.sample", bsf.get_name());
|
||||
|
||||
auto fd = auto_fd(openp(sample_path, O_WRONLY|O_TRUNC|O_CREAT, 0644));
|
||||
if (fd == -1 || write(fd.get(), bsf.bsf_data, bsf.bsf_size) == -1) {
|
||||
auto sf = bsf.to_string_fragment();
|
||||
if (fd == -1 || write(fd.get(), sf.data(), sf.length()) == -1) {
|
||||
perror("error: unable to write default config file");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
load_default_configs(lnav_default_config, "*", lnav_config_json, errors);
|
||||
load_default_configs(lnav_config, "*", lnav_config_json, errors);
|
||||
load_default_configs(lnav_default_config, "*", errors);
|
||||
load_default_configs(lnav_config, "*", errors);
|
||||
|
||||
for (const auto &extra_path : extra_paths) {
|
||||
auto config_path = extra_path / "configs/*/*.json";
|
||||
|
@ -1080,7 +1079,7 @@ void reset_config(const std::string &path)
|
|||
{
|
||||
vector<string> errors;
|
||||
|
||||
load_default_configs(lnav_config, path, lnav_config_json, errors);
|
||||
load_default_configs(lnav_config, path, errors);
|
||||
|
||||
reload_config(errors);
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
#include "default-formats.h"
|
||||
|
||||
#include "log_format_loader.hh"
|
||||
#include "bin2c.h"
|
||||
#include "bin2c.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -756,50 +756,47 @@ struct json_path_container root_format_handler = json_path_container {
|
|||
|
||||
static void write_sample_file()
|
||||
{
|
||||
for (int lpc = 0; lnav_format_json[lpc].bsf_name; lpc++) {
|
||||
auto &bsf = lnav_format_json[lpc];
|
||||
for (const auto& bsf : lnav_format_json) {
|
||||
auto sample_path = dotlnav_path() /
|
||||
fmt::format("formats/default/{}.sample", bsf.bsf_name);
|
||||
fmt::format("formats/default/{}.sample", bsf.get_name());
|
||||
auto sf = bsf.to_string_fragment();
|
||||
auto_fd sample_fd;
|
||||
|
||||
if ((sample_fd = openp(sample_path,
|
||||
O_WRONLY | O_TRUNC | O_CREAT,
|
||||
0644)) == -1 ||
|
||||
(write(sample_fd.get(), bsf.bsf_data, bsf.bsf_size) == -1)) {
|
||||
(write(sample_fd.get(), sf.data(), sf.length()) == -1)) {
|
||||
perror("error: unable to write default format file");
|
||||
}
|
||||
}
|
||||
|
||||
for (int lpc = 0; lnav_sh_scripts[lpc].bsf_name; lpc++) {
|
||||
struct bin_src_file &bsf = lnav_sh_scripts[lpc];
|
||||
auto sh_path = dotlnav_path() / fmt::format("formats/default/{}", bsf.bsf_name);
|
||||
for (const auto& bsf : lnav_sh_scripts) {
|
||||
auto sh_path = dotlnav_path() / fmt::format("formats/default/{}", bsf.get_name());
|
||||
auto sf = bsf.to_string_fragment();
|
||||
auto_fd sh_fd;
|
||||
|
||||
if ((sh_fd = openp(sh_path, O_WRONLY|O_TRUNC|O_CREAT, 0755)) == -1 ||
|
||||
write(sh_fd.get(), bsf.bsf_data, strlen((const char *) bsf.bsf_data)) == -1) {
|
||||
write(sh_fd.get(), sf.data(), sf.length()) == -1) {
|
||||
perror("error: unable to write default text file");
|
||||
}
|
||||
}
|
||||
|
||||
for (int lpc = 0; lnav_scripts[lpc].bsf_name; lpc++) {
|
||||
for (const auto& bsf : lnav_scripts) {
|
||||
struct script_metadata meta;
|
||||
struct bin_src_file &bsf = lnav_scripts[lpc];
|
||||
const char *script_content = reinterpret_cast<const char *>(bsf.bsf_data);
|
||||
auto sf = bsf.to_string_fragment();
|
||||
auto_fd script_fd;
|
||||
char path[2048];
|
||||
size_t script_len;
|
||||
struct stat st;
|
||||
|
||||
script_len = strlen(script_content);
|
||||
extract_metadata(script_content, script_len, meta);
|
||||
extract_metadata(sf.data(), sf.length(), meta);
|
||||
snprintf(path, sizeof(path), "formats/default/%s.lnav", meta.sm_name.c_str());
|
||||
auto script_path = dotlnav_path() / path;
|
||||
if (statp(script_path, &st) == 0 && (size_t) st.st_size == script_len) {
|
||||
if (statp(script_path, &st) == 0 && (size_t) st.st_size == sf.length()) {
|
||||
// Assume it's the right contents and move on...
|
||||
continue;
|
||||
}
|
||||
if ((script_fd = openp(script_path, O_WRONLY|O_TRUNC|O_CREAT, 0755)) == -1 ||
|
||||
write(script_fd.get(), script_content, script_len) == -1) {
|
||||
write(script_fd.get(), sf.data(), sf.length()) == -1) {
|
||||
perror("error: unable to write default text file");
|
||||
}
|
||||
}
|
||||
|
@ -922,8 +919,7 @@ void load_formats(const std::vector<ghc::filesystem::path> &extra_paths,
|
|||
write_sample_file();
|
||||
|
||||
log_debug("Loading default formats");
|
||||
for (int lpc = 0; lnav_format_json[lpc].bsf_name; lpc++) {
|
||||
auto &bsf = lnav_format_json[lpc];
|
||||
for (const auto& bsf : lnav_format_json) {
|
||||
handle = yajl_alloc(&ypc_builtin.ypc_callbacks, nullptr, &ypc_builtin);
|
||||
ud.ud_format_names = &retval;
|
||||
ud.ud_errors = &errors;
|
||||
|
@ -933,11 +929,12 @@ void load_formats(const std::vector<ghc::filesystem::path> &extra_paths,
|
|||
.with_error_reporter(format_error_reporter)
|
||||
.ypc_userdata = &ud;
|
||||
yajl_config(handle, yajl_allow_comments, 1);
|
||||
if (ypc_builtin.parse(bsf.bsf_data, bsf.bsf_size) != yajl_status_ok) {
|
||||
auto sf = bsf.to_string_fragment();
|
||||
if (ypc_builtin.parse(sf) != yajl_status_ok) {
|
||||
errors.push_back("builtin: invalid json -- " +
|
||||
string((char *) yajl_get_error(handle, 1,
|
||||
bsf.bsf_data,
|
||||
bsf.bsf_size)));
|
||||
(const unsigned char *) sf.data(),
|
||||
sf.length())));
|
||||
}
|
||||
ypc_builtin.complete_parse();
|
||||
yajl_free(handle);
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "base/lnav_log.hh"
|
||||
#include "log_level.hh"
|
||||
|
||||
const char *level_names[LEVEL__MAX + 1] = {
|
||||
|
|
|
@ -88,6 +88,10 @@ public:
|
|||
s_len(len) {
|
||||
};
|
||||
|
||||
explicit shlex(const string_fragment &sf)
|
||||
: s_str(sf.data()), s_len(sf.length()) {
|
||||
}
|
||||
|
||||
explicit shlex(const std::string &str)
|
||||
: s_str(str.c_str()),
|
||||
s_len(str.size()) {
|
||||
|
|
|
@ -69,10 +69,19 @@ static struct json_path_container root_color_handler = {
|
|||
.with_children(term_color_handler)
|
||||
};
|
||||
|
||||
term_color_palette xterm_colors(xterm_palette_json.bsf_data);
|
||||
term_color_palette ansi_colors(ansi_palette_json.bsf_data);
|
||||
term_color_palette *xterm_colors()
|
||||
{
|
||||
static term_color_palette retval(xterm_palette_json.to_string_fragment());
|
||||
|
||||
term_color_palette *ACTIVE_PALETTE = &ansi_colors;
|
||||
return &retval;
|
||||
}
|
||||
|
||||
term_color_palette *ansi_colors()
|
||||
{
|
||||
static term_color_palette retval(ansi_palette_json.to_string_fragment());
|
||||
|
||||
return &retval;
|
||||
}
|
||||
|
||||
bool rgb_color::from_str(const string_fragment &color,
|
||||
rgb_color &rgb_out,
|
||||
|
@ -104,7 +113,7 @@ bool rgb_color::from_str(const string_fragment &color,
|
|||
return false;
|
||||
}
|
||||
|
||||
for (const auto &xc : xterm_colors.tc_palette) {
|
||||
for (const auto &xc : xterm_colors()->tc_palette) {
|
||||
if (color.iequal(xc.xc_name)) {
|
||||
rgb_out = xc.xc_color;
|
||||
return true;
|
||||
|
@ -156,7 +165,7 @@ bool rgb_color::operator!=(const rgb_color &rhs) const
|
|||
return !(rhs == *this);
|
||||
}
|
||||
|
||||
term_color_palette::term_color_palette(const unsigned char *json)
|
||||
term_color_palette::term_color_palette(const string_fragment& json)
|
||||
{
|
||||
yajlpp_parse_context ypc_xterm("palette.json", &root_color_handler);
|
||||
yajl_handle handle;
|
||||
|
@ -166,7 +175,7 @@ term_color_palette::term_color_palette(const unsigned char *json)
|
|||
.with_ignore_unused(true)
|
||||
.with_obj(this->tc_palette)
|
||||
.with_handle(handle);
|
||||
yajl_status st = ypc_xterm.parse(json, strlen((const char *) json));
|
||||
yajl_status st = ypc_xterm.parse(json);
|
||||
ensure(st == yajl_status_ok);
|
||||
st = ypc_xterm.complete_parse();
|
||||
ensure(st == yajl_status_ok);
|
||||
|
|
|
@ -108,7 +108,7 @@ struct term_color {
|
|||
};
|
||||
|
||||
struct term_color_palette {
|
||||
explicit term_color_palette(const unsigned char *json);
|
||||
explicit term_color_palette(const string_fragment& json);
|
||||
|
||||
short match_color(const lab_color &to_match);
|
||||
|
||||
|
@ -173,9 +173,7 @@ struct lnav_theme {
|
|||
std::map<std::string, highlighter_config> lt_highlights;
|
||||
};
|
||||
|
||||
extern term_color_palette xterm_colors;
|
||||
extern term_color_palette ansi_colors;
|
||||
|
||||
extern term_color_palette *ACTIVE_PALETTE;
|
||||
extern term_color_palette *xterm_colors();
|
||||
extern term_color_palette *ansi_colors();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -369,7 +369,8 @@ view_colors &view_colors::singleton()
|
|||
return s_vc;
|
||||
}
|
||||
|
||||
view_colors::view_colors() : vc_color_pair_end(0)
|
||||
view_colors::view_colors()
|
||||
: vc_color_pair_end(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -389,6 +390,10 @@ static string COLOR_NAMES[] = {
|
|||
class color_listener : public lnav_config_listener {
|
||||
public:
|
||||
void reload_config(error_reporter &reporter) override {
|
||||
if (!view_colors::initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto &vc = view_colors::singleton();
|
||||
|
||||
for (const auto &pair : lnav_config.lc_ui_theme_defs) {
|
||||
|
@ -412,9 +417,11 @@ public:
|
|||
};
|
||||
|
||||
static color_listener _COLOR_LISTENER;
|
||||
term_color_palette *view_colors::vc_active_palette;
|
||||
|
||||
void view_colors::init()
|
||||
{
|
||||
vc_active_palette = ansi_colors();
|
||||
if (has_colors()) {
|
||||
static int ansi_colors_to_curses[] = {
|
||||
COLOR_BLACK,
|
||||
|
@ -442,7 +449,7 @@ void view_colors::init()
|
|||
}
|
||||
}
|
||||
if (COLORS >= 256) {
|
||||
ACTIVE_PALETTE = &xterm_colors;
|
||||
vc_active_palette = xterm_colors();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -552,7 +559,7 @@ void view_colors::init_roles(const lnav_theme <,
|
|||
if (!rgb_color::from_str(bg_color, rgb_bg, errmsg)) {
|
||||
reporter(&ident_sc.sc_background_color, errmsg);
|
||||
}
|
||||
ident_bg = ACTIVE_PALETTE->match_color(lab_color(rgb_bg));
|
||||
ident_bg = vc_active_palette->match_color(lab_color(rgb_bg));
|
||||
}
|
||||
for (int z = 0; z < 6; z++) {
|
||||
for (int x = 1; x < 6; x += 2) {
|
||||
|
@ -599,8 +606,8 @@ void view_colors::init_roles(const lnav_theme <,
|
|||
return;
|
||||
}
|
||||
|
||||
short fg = ACTIVE_PALETTE->match_color(lab_color(rgb_fg));
|
||||
short bg = ACTIVE_PALETTE->match_color(lab_color(rgb_bg));
|
||||
short fg = vc_active_palette->match_color(lab_color(rgb_fg));
|
||||
short bg = vc_active_palette->match_color(lab_color(rgb_bg));
|
||||
|
||||
if (rgb_fg.empty()) {
|
||||
fg = ansi_fg;
|
||||
|
@ -837,7 +844,7 @@ int view_colors::ensure_color_pair(int &pair_base, short fg, short bg)
|
|||
fg == -1 ? def_fg : fg,
|
||||
bg == -1 ? def_bg : bg));
|
||||
|
||||
if (this->initialized) {
|
||||
if (initialized) {
|
||||
this->vc_dyn_pairs[index_pair] = retval;
|
||||
}
|
||||
|
||||
|
@ -858,7 +865,7 @@ int view_colors::match_color(const rgb_color &color)
|
|||
return -1;
|
||||
}
|
||||
|
||||
return ACTIVE_PALETTE->match_color(lab_color(color));
|
||||
return vc_active_palette->match_color(lab_color(color));
|
||||
}
|
||||
|
||||
attr_t view_colors::attrs_for_ident(const char *str, size_t len) const
|
||||
|
|
|
@ -332,6 +332,7 @@ public:
|
|||
static bool initialized;
|
||||
|
||||
private:
|
||||
static term_color_palette *vc_active_palette;
|
||||
|
||||
/** Private constructor that initializes the member fields. */
|
||||
view_colors();
|
||||
|
|
|
@ -167,7 +167,7 @@ static void build_all_help_text()
|
|||
}
|
||||
|
||||
attr_line_t all_help_text;
|
||||
shlex lexer((const char *) help_txt.bsf_data, help_txt.bsf_size);
|
||||
shlex lexer(help_txt.to_string_fragment());
|
||||
string sub_help_text;
|
||||
|
||||
lexer.with_ignore_quotes(true)
|
||||
|
|
|
@ -295,6 +295,10 @@ public:
|
|||
|
||||
yajl_status parse(const unsigned char *jsonText, size_t jsonTextLen);
|
||||
|
||||
yajl_status parse(const string_fragment& sf) {
|
||||
return this->parse((const unsigned char *) sf.data(), sf.length());
|
||||
}
|
||||
|
||||
int get_line_number() const;
|
||||
|
||||
yajl_status complete_parse();
|
||||
|
|
Loading…
Reference in New Issue