Skip to content

Commit

Permalink
Cell highlighting v2 (#302)
Browse files Browse the repository at this point in the history
* add mysheet_extension + cell_attrs example: type 'v' to generate simple pivot table
* committing without tests due to possible impact on other work
* TO DO
  - remove Row # from pivot table
  - add drill-down
  - further clean up / polish
  - check invalid-sql error handling
  - (low priority): sql injection guard
  - add tests
  • Loading branch information
liquidaty authored Nov 25, 2024
1 parent 2c46756 commit ebee34c
Show file tree
Hide file tree
Showing 25 changed files with 525 additions and 142 deletions.
4 changes: 2 additions & 2 deletions app/builtin/register.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ static int main_register_aux(int argc, const char *argv[]) {
fprintf(stderr, "No extension id provided\n"), err = 1;
else if (!strcmp(extension_id, "--help") || !strcmp(extension_id, "-h"))
return register_help(do_register);
else if (strlen(extension_id) != 2)
fprintf(stderr, "Extension id must be exactly two characters\n"), err = 1;
else if (strlen(extension_id) < ZSV_EXTENSION_ID_MIN_LEN || strlen(extension_id) > ZSV_EXTENSION_ID_MAX_LEN)
fprintf(stderr, "Extension id must be 1 to 8 bytes\n"), err = 1;
else if (config_init(&config, !do_register, 1, 1))
config_free(&config); // unable to init config
else {
Expand Down
6 changes: 5 additions & 1 deletion app/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#endif
#include "sheet/procedure.h"
#include "sheet/key-bindings.h"
#include "sql_internal.h"

struct cli_config {
struct zsv_ext *extensions;
Expand Down Expand Up @@ -385,11 +386,15 @@ static struct zsv_ext_callbacks *zsv_ext_callbacks_init(struct zsv_ext_callbacks
e->ext_parser_opts = ext_parser_opts;
e->ext_opts_used = ext_opts_used;

e->ext_sqlite3_add_csv = zsv_sqlite3_add_csv;
e->ext_sqlite3_db_delete = zsv_sqlite3_db_delete;
e->ext_sqlite3_db_new = zsv_sqlite3_db_new;
#ifdef ZSVSHEET_BUILD
e->ext_sheet_keypress = zsvsheet_ext_keypress;
e->ext_sheet_prompt = zsvsheet_ext_prompt;
e->ext_sheet_buffer_set_ctx = zsvsheet_buffer_set_ctx;
e->ext_sheet_buffer_get_ctx = zsvsheet_buffer_get_ctx;
e->ext_sheet_buffer_set_cell_attrs = zsvsheet_buffer_set_cell_attrs;
e->ext_sheet_buffer_get_zsv_opts = zsvsheet_buffer_get_zsv_opts;
e->ext_sheet_set_status = zsvsheet_set_status;
e->ext_sheet_buffer_current = zsvsheet_buffer_current;
Expand Down Expand Up @@ -509,7 +514,6 @@ static struct builtin_cmd *find_builtin(const char *cmd_name) {
#include "builtin/version.c"
#include "builtin/register.c"

#define ZSV_EXTENSION_ID_MAX_LEN 8
static const char *extension_cmd_from_arg(const char *arg) {
const char *dash = strchr(arg, '-');
if (dash && dash < arg + ZSV_EXTENSION_ID_MAX_LEN && dash[1] != '\0')
Expand Down
18 changes: 13 additions & 5 deletions app/cli_ini.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <zsv/utils/string.h>
#include <zsv/utils/os.h>
#include <zsv/utils/dirs.h>
#include <zsv/utils/mem.h>

#define INI_HANDLER_LINENO 1
#define INI_CALL_HANDLER_ON_NEW_SECTION 1
Expand Down Expand Up @@ -104,8 +105,14 @@ static struct zsv_ext *load_extension_dl(const unsigned char *extension_id, char
// load an extension and if successful, add to config->extensions head
static int add_extension(const char *id, struct zsv_ext **exts, char ignore_err, char verbose) {
int err = 0;
size_t len = 2;
unsigned char *extension_id = zsv_strtolowercase((const unsigned char *)id, &len);
const char *dash = strchr(id, '-');
unsigned char *extension_id = NULL;
size_t len;
if (dash)
len = dash - id;
else
len = strlen(id);
extension_id = zsv_strtolowercase((const unsigned char *)id, &len);
if (extension_id) {
struct zsv_ext *ext = NULL;
if (!extension_id_ok(extension_id))
Expand Down Expand Up @@ -133,8 +140,9 @@ static int config_ini_handler(void *ctx, const char *section, const char *name,
if (section) {
if (!name && !value) { // initialize section
if (zsv_stricmp((const unsigned char *)section, (const unsigned char *)"default")) {
if (strlen(section) != 2) {
fprintf(stderr, "Invalid extension id: %s\n", section);
if (!(strlen(section) >= ZSV_EXTENSION_ID_MIN_LEN && strlen(section) <= ZSV_EXTENSION_ID_MAX_LEN)) {
fprintf(stderr, "Invalid extension id: %s. Length must be between %i and %i\n", section,
ZSV_EXTENSION_ID_MIN_LEN, ZSV_EXTENSION_ID_MAX_LEN);
err = 1;
} else {
struct zsv_ext *ext = find_extension(config, section);
Expand Down Expand Up @@ -168,7 +176,7 @@ static int parse_extensions_ini(struct cli_config *config, char err_if_not_found
if (!(f = fopen(config->filepath, "r"))) {
if (err_if_not_found) {
err = -1;
fprintf(stderr, "No extensions configured%s%s\n", verbose ? "or file not found: " : "",
fprintf(stderr, "No extensions configured%s%s\n", verbose ? " or file not found: " : "",
verbose ? config->filepath : "");
}
} else {
Expand Down
3 changes: 3 additions & 0 deletions app/compare.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,8 @@ static void zsv_compare_print_row(struct zsv_compare_data *data,
static void zsv_compare_input_free(struct zsv_compare_input *input) {
zsv_delete(input->parser);
zsv_compare_unique_colnames_delete(&input->colnames);
if (input->added)
sqlite3_zsv_list_remove(input->path);
free(input->out2in);
if (input->stream)
fclose(input->stream);
Expand Down Expand Up @@ -447,6 +449,7 @@ static void zsv_compare_set_sorted_callbacks(struct zsv_compare_data *data) {

static enum zsv_compare_status zsv_compare_init_sorted(struct zsv_compare_data *data) {
int rc;
// to do: use sql_internal.h interface
const char *db_url = data->sort_in_memory ? "file::memory:" : "";
if ((rc = sqlite3_open_v2(db_url, &data->sort_db, SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE, NULL)) == SQLITE_OK &&
data->sort_db && (rc = sqlite3_create_module(data->sort_db, "csv", &CsvModule, 0) == SQLITE_OK)) {
Expand Down
3 changes: 2 additions & 1 deletion app/compare_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ struct zsv_compare_input {
unsigned char row_loaded : 1;
unsigned char missing : 1;
unsigned char done : 1;
unsigned char _ : 5;
unsigned char added : 1;
unsigned char _ : 4;
};

struct zsv_compare_key {
Expand Down
24 changes: 11 additions & 13 deletions app/compare_sort.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,17 @@
* To implement sorting, we will use sqlite, create a table for each CSV file and run "select * order by ..."
*/

#include "external/sqlite3/sqlite3_csv_vtab-mem.h"

static int zsv_compare_sort_prep_table(struct zsv_compare_data *data, const char *fname, const char *opts_used,
int max_columns, char **err_msg, unsigned int table_ix) {
char **err_msg, unsigned int table_ix) {
#define ZSV_COMPARE_MAX_TABLES 1000
char *sql = NULL;
if (table_ix > ZSV_COMPARE_MAX_TABLES)
return -1;

if (max_columns == 0)
max_columns = 2048;

sql = sqlite3_mprintf("CREATE VIRTUAL TABLE data%i USING csv(filename=%Q,options_used=%Q,max_columns=%i)", table_ix,
fname, opts_used, max_columns);
sql = sqlite3_mprintf("CREATE VIRTUAL TABLE data%i USING csv(filename=%Q,options_used=%Q)", table_ix, fname,
opts_used); //, max_columns);
if (!sql)
return -1;

Expand All @@ -22,9 +21,7 @@ static int zsv_compare_sort_prep_table(struct zsv_compare_data *data, const char
return rc;
}

static int zsv_compare_sort_stmt_prep(sqlite3 *db, sqlite3_stmt **stmtp,
// struct zsv_compare_sort *sort,
struct zsv_compare_key *keys, unsigned ix) {
static int zsv_compare_sort_stmt_prep(sqlite3 *db, sqlite3_stmt **stmtp, struct zsv_compare_key *keys, unsigned ix) {
sqlite3_str *select_clause = sqlite3_str_new(db);
if (!select_clause) {
fprintf(stderr, "Out of memory!\n");
Expand All @@ -43,12 +40,13 @@ static int zsv_compare_sort_stmt_prep(sqlite3 *db, sqlite3_stmt **stmtp,
}

static enum zsv_compare_status input_init_sorted(struct zsv_compare_data *data, struct zsv_compare_input *input,
struct zsv_opts *_opts, struct zsv_prop_handler *_prop_handler,
struct zsv_opts *opts, struct zsv_prop_handler *custom_prop_handler,
const char *opts_used) {
(void)(_opts);
(void)(_prop_handler);
char *err_msg = NULL;
int rc = zsv_compare_sort_prep_table(data, input->path, opts_used, 0, &err_msg, input->index);
if (!sqlite3_zsv_list_add(input->path, opts, custom_prop_handler))
input->added = 1;
int rc = zsv_compare_sort_prep_table(data, input->path, opts_used, &err_msg, input->index);

if (err_msg) {
fprintf(stderr, "%s\n", err_msg);
sqlite3_free(err_msg);
Expand Down
15 changes: 15 additions & 0 deletions app/curses.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#if defined(WIN32) || defined(_WIN32)
#ifdef HAVE_NCURSESW
#include <ncursesw/ncurses.h>
#else
#include <ncurses/ncurses.h>
#endif // HAVE_NCURSESW
#else
#if __has_include(<curses.h>)
#include <curses.h>
#elif __has_include(<ncursesw/curses.h>)
#include <ncursesw/curses.h>
#else
#error Cannot find ncurses include file!
#endif
#endif
21 changes: 14 additions & 7 deletions app/ext_example/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Makefile for use with GNU make
#Makefile for use with GNU make

THIS_MAKEFILE_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
THIS_DIR:=$(shell basename "${THIS_MAKEFILE_DIR}")
Expand Down Expand Up @@ -65,6 +65,7 @@ THIS_LIB_BASE=$(shell cd ../.. && pwd)
CCBN=$(shell basename ${CC})
BUILD_DIR=${THIS_LIB_BASE}/build/${BUILD_SUBDIR}/${CCBN}
TARGET=${BUILD_DIR}/bin/zsvextmy.${SO}
TARGET_SHEET=${BUILD_DIR}/bin/zsvextmysheet.${SO}

COLOR_NONE=\033[0m
COLOR_GREEN=\033[1;32m
Expand All @@ -88,15 +89,16 @@ endif
UTILS1+=writer
UTILS=$(addprefix ${BUILD_DIR}/objs/utils/,$(addsuffix .o,${UTILS1}))

CFLAGS+= -I${THIS_LIB_BASE}/include
CFLAGS+= -I${THIS_LIB_BASE}/include -I${PREFIX}/include

all: ${TARGET}
all: ${TARGET} ${TARGET_SHEET}
@echo Built ${TARGET}
@echo Built ${TARGET_SHEET}

ifneq ($(findstring emcc,$(CC)),) # emcc
install: ${INSTALLED_EXTENSION}

${INSTALLED_EXTENSION}: ${TARGET}
${INSTALLED_EXTENSION}: ${TARGET} ${TARGET_SHEET}
@mkdir -p `dirname "$@"`
cp -p $< $@
endif
Expand Down Expand Up @@ -179,13 +181,18 @@ test-thirdparty: test-%: ${CLI} ${TARGET}
@cmp /tmp/zsvext-$@.out test/expected/zsvext-$@.out && ${TEST_PASS} || ${TEST_FAIL}

clean:
@rm -f ${TARGET} /tmp/zsvext-test*.out
@rm -f ${TARGET} ${TARGET_SHEET} /tmp/zsvext-test*.out

${BUILD_DIR}/objs/%.o : ${THIS_LIB_BASE}/src/%.c ${PARSER_DEPS}
${MAKE} -C ${THIS_LIB_BASE}/src CONFIGFILE=${CONFIGFILEPATH} DEBUG=${DEBUG} WIN=${WIN} $@

${TARGET}: my_extension.c ${UTILS}

YAJL_SRC_DIR=${THIS_MAKEFILE_DIR}/../external/yajl
YAJL_INCLUDE=-I${YAJL_SRC_DIR}/build/yajl-2.1.1/include
YAJL_HELPER_INCLUDE=-I${THIS_MAKEFILE_DIR}/../external/yajl_helper
${TARGET_SHEET}: LIBS="../external/sqlite3/sqlite3.c" -lzsv -lzsvutil -L${PREFIX}/lib
${TARGET} ${TARGET_SHEET}: ${BUILD_DIR}/bin/zsvext%.${SO} : %_extension.c ${UTILS}
@mkdir -p `dirname "$@"`
${CC} ${CFLAGS} ${CFLAGS_SHARED} $< ${UTILS} -o $@
${CC} ${CFLAGS} ${CFLAGS_SHARED} $< ${UTILS} -o $@ ${LIBS} ${YAJL_INCLUDE} ${YAJL_HELPER_INCLUDE}

.PHONY: all test test-% clean install
Loading

0 comments on commit ebee34c

Please sign in to comment.