Skip to content

Commit

Permalink
begin to set up sheet handling plugin structures (#228)
Browse files Browse the repository at this point in the history
* begin to set up sheet handling plugin structures
* TO DO: exec built-in command registration before custom. add manual correction/edit plug-in
  • Loading branch information
liquidaty authored Oct 15, 2024
1 parent f8c794d commit 3d0af38
Show file tree
Hide file tree
Showing 17 changed files with 567 additions and 124 deletions.
34 changes: 26 additions & 8 deletions app/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
#include "cli_internal.h"
#include "cli_const.h"
#include "cli_export.h"
#ifdef ZSVSHEET_BUILD
#include "sheet/sheet_internal.h"
#include "sheet/handlers_internal.h"
#endif

struct cli_config {
struct zsv_ext *extensions;
Expand All @@ -43,6 +47,7 @@ struct builtin_cmd {
zsv_cmd *cmd;
};

static int config_init(struct cli_config *c, char err_if_dl_not_found, char do_init, char verbose);
#include "zsv_main.h"

#define CLI_BUILTIN_DECL(x) int main_##x(int argc, const char *argv[])
Expand Down Expand Up @@ -81,15 +86,17 @@ ZSV_MAIN_NO_OPTIONS_DECL(mv);
ZSV_MAIN_NO_OPTIONS_DECL(jq);
#endif

#define CLI_BUILTIN_CMD(x) \
{ .name = #x, .main = main_##x, .cmd = NULL }
#define CLI_BUILTIN_COMMAND(x) \
{ .name = #x, .main = NULL, .cmd = ZSV_MAIN_FUNC(x) }
#define CLI_BUILTIN_NO_OPTIONS_COMMAND(x) \
{ .name = #x, .main = ZSV_MAIN_NO_OPTIONS_FUNC(x), .cmd = NULL }

// clang-format off

#define CLI_BUILTIN_CMD(x) {.name = #x, .main = main_##x, .cmd = NULL}
#define CLI_BUILTIN_COMMAND(x) {.name = #x, .main = NULL, .cmd = ZSV_MAIN_FUNC(x)}
#define CLI_BUILTIN_COMMANDEXT(x) {.name = #x, .main = NULL, .cmd = ZSV_MAINEXT_FUNC(x)}
#define CLI_BUILTIN_NO_OPTIONS_COMMAND(x) {.name = #x, .main = ZSV_MAIN_NO_OPTIONS_FUNC(x), .cmd = NULL}

#ifdef ZSVSHEET_BUILD
ZSV_MAINEXT_FUNC_DEFINE(sheet);
#endif

struct builtin_cmd builtin_cmds[] = {
CLI_BUILTIN_CMD(license),
CLI_BUILTIN_CMD(thirdparty),
Expand All @@ -112,7 +119,7 @@ struct builtin_cmd builtin_cmds[] = {
CLI_BUILTIN_COMMAND(2db),
CLI_BUILTIN_COMMAND(compare),
#ifdef ZSVSHEET_BUILD
CLI_BUILTIN_COMMAND(sheet),
CLI_BUILTIN_COMMANDEXT(sheet),
#endif
CLI_BUILTIN_COMMAND(echo),
CLI_BUILTIN_NO_OPTIONS_COMMAND(prop),
Expand Down Expand Up @@ -356,6 +363,17 @@ static struct zsv_ext_callbacks *zsv_ext_callbacks_init(struct zsv_ext_callbacks
e->ext_parse_all = ext_parse_all;
e->ext_parser_opts = ext_parser_opts;
e->ext_opts_used = ext_opts_used;

#ifdef ZSVSHEET_BUILD
e->ext_sheet_handler_key = zsvsheet_handler_key;
e->ext_sheet_subcommand_prompt = zsvsheet_subcommand_prompt;
e->ext_sheet_handler_set_status = zsvsheet_handler_set_status;
e->ext_sheet_handler_buffer_current = zsvsheet_handler_buffer_current;
e->ext_sheet_handler_buffer_prior = zsvsheet_handler_buffer_prior;
e->ext_sheet_handler_buffer_filename = zsvsheet_handler_buffer_filename;
e->ext_sheet_handler_open_file = zsvsheet_handler_open_file;
e->ext_sheet_register_command = zsvsheet_register_command;
#endif
}
return e;
}
Expand Down
43 changes: 41 additions & 2 deletions app/ext_example/my_extension.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include <stdlib.h>
#include <string.h>
#include <zsv/ext/implementation.h>
// #include <zsv/ext/sheet.h>
#include "../../include/zsv/ext/sheet.h"
#include <zsv/utils/writer.h>

/**
Expand Down Expand Up @@ -44,7 +46,7 @@
/**
* *Required*: define our extension id, which must be two characters in length
*/
const char *zsv_ext_id() {
const char *zsv_ext_id(void) {
return "my";
}

Expand All @@ -66,6 +68,41 @@ enum zsv_ext_status count_main(zsv_execution_context ctx, int argc, const char *
static enum zsv_ext_status echo_main(zsv_execution_context ctx, int argc, const char *argv[], struct zsv_opts *opts,
const char *opts_used);

/**
* Here we define a custom command for the zsv `sheet` feature
*/
zsvsheet_handler_status my_sheet_subcommand_handler(zsvsheet_subcommand_handler_context_t ctx) {
int ch = zsv_cb.ext_sheet_handler_key(ctx);
zsv_cb.ext_sheet_subcommand_prompt(ctx, "You pressed %c. Now enter something here", (char)ch);
return zsvsheet_handler_status_ok;
}

zsvsheet_handler_status my_sheet_handler(zsvsheet_handler_context_t ctx) {
const char *temp_filename = "/tmp/zsvsheet_extension_example.csv";
FILE *f = fopen(temp_filename, "wb");
if (!f)
zsv_cb.ext_sheet_handler_set_status(ctx, "Unable to open for write: %s", temp_filename);
else {
fprintf(f, "buffer #,file name\n");
// get a count of open buffers
int i = 0;
for (zsvsheet_handler_buffer_t buff = zsv_cb.ext_sheet_handler_buffer_current(ctx); buff;
buff = zsv_cb.ext_sheet_handler_buffer_prior(buff), i++)
;

// print a list of open buffers and filenames
for (zsvsheet_handler_buffer_t buff = zsv_cb.ext_sheet_handler_buffer_current(ctx); buff;
buff = zsv_cb.ext_sheet_handler_buffer_prior(buff), i--) {
const char *buff_filename = zsv_cb.ext_sheet_handler_buffer_filename(buff);
if (buff_filename)
fprintf(f, "%i,%s\n", i, buff_filename); // assumes no need for quoting or escaping buff_filename...
}
fclose(f);
return zsv_cb.ext_sheet_handler_open_file(ctx, temp_filename, NULL);
}
return zsvsheet_handler_status_ok;
}

/**
* *Required*. Initialization is called when our extension is loaded. Our
* initialization routine uses `ext_add_command` to register our commands and
Expand All @@ -92,14 +129,16 @@ enum zsv_ext_status zsv_ext_init(struct zsv_ext_callbacks *cb, zsv_execution_con
zsv_cb.ext_set_thirdparty(ctx, third_party_licenses);
zsv_cb.ext_add_command(ctx, "count", "print the number of rows", count_main);
zsv_cb.ext_add_command(ctx, "echo", "print the input data back to stdout", echo_main);

zsv_cb.ext_sheet_register_command('t', "my-test-command", my_sheet_subcommand_handler, my_sheet_handler);
return zsv_ext_status_ok;
}

/**
* exit: called once by zsv before the library is unloaded, if `zsv_ext_init()` was
* previously called
*/
enum zsv_ext_status zsv_ext_exit() {
enum zsv_ext_status zsv_ext_exit(void) {
fprintf(stderr, "Exiting extension example!\n");
return zsv_ext_status_ok;
}
Expand Down
141 changes: 76 additions & 65 deletions app/sheet.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#include <signal.h>

#include <zsv.h>
#include "sheet/sheet_internal.h"

#if defined(WIN32) || defined(_WIN32)
#include <ncurses/ncurses.h>
Expand All @@ -36,6 +35,8 @@
#define ZSV_COMMAND sheet
#include "zsv_command.h"

#include "../include/zsv/ext/sheet.h"
#include "sheet/sheet_internal.h"
#include "sheet/buffer.h"
#include "sheet/buffer.c"

Expand All @@ -55,7 +56,7 @@ struct zsvsheet_opts {
void display_buffer_subtable(struct zsvsheet_ui_buffer *ui_buffer, size_t rownum_col_offset, size_t input_header_span,
struct zsvsheet_display_dimensions *ddims);

void zsvsheet_set_status(struct zsvsheet_display_dimensions *ddims, int overwrite, const char *fmt, ...);
void zsvsheet_set_status(const struct zsvsheet_display_dimensions *ddims, int overwrite, const char *fmt, ...);

void get_subcommand(const char *prompt, char *buff, size_t buffsize, int footer_row) {
*buff = '\0';
Expand Down Expand Up @@ -103,11 +104,10 @@ size_t zsvsheet_get_input_raw_row(struct zsvsheet_rowcol *input_offset, struct z
#include "sheet/cursor.c"

// zsvsheet_handle_find_next: return non-zero if a result was found
char zsvsheet_handle_find_next(struct zsvsheet_ui_buffer *uib, const char *needle, const struct zsv_opts *zsv_opts,
struct zsvsheet_opts *zsvsheet_opts, size_t header_span,
struct zsvsheet_display_dimensions *ddims, int *update_buffer,
char zsvsheet_handle_find_next(struct zsvsheet_ui_buffer *uib, const char *needle, struct zsvsheet_opts *zsvsheet_opts,
size_t header_span, struct zsvsheet_display_dimensions *ddims, int *update_buffer,
struct zsv_prop_handler *custom_prop_handler, const char *opts_used) {
if (zsvsheet_find_next(uib, needle, zsv_opts, zsvsheet_opts, header_span, custom_prop_handler, opts_used) > 0) {
if (zsvsheet_find_next(uib, needle, zsvsheet_opts, header_span, custom_prop_handler, opts_used) > 0) {
*update_buffer = zsvsheet_goto_input_raw_row(uib, zsvsheet_opts->found_rownum, header_span, ddims, (size_t)-1);
return 1;
}
Expand Down Expand Up @@ -138,14 +138,7 @@ size_t display_data_rowcount(struct zsvsheet_display_dimensions *dims) {
}

char zsvsheet_status_text[256] = {0};
void zsvsheet_set_status(struct zsvsheet_display_dimensions *ddims, int overwrite, const char *fmt, ...) {
if (overwrite || !*zsvsheet_status_text) {
va_list argv;
va_start(argv, fmt);
vsnprintf(zsvsheet_status_text, sizeof(zsvsheet_status_text), fmt, argv);
va_end(argv);
// note: if (n < (int)sizeof(zsvsheet_status_text)), then we just ignore
}
static void zsvsheet_display_status_text(const struct zsvsheet_display_dimensions *ddims) {
// clear the entire line
mvprintw(ddims->rows - ddims->footer_span, 0, "%-*s", (int)sizeof(zsvsheet_status_text), "");

Expand All @@ -155,35 +148,55 @@ void zsvsheet_set_status(struct zsvsheet_display_dimensions *ddims, int overwrit
attroff(A_REVERSE);
}

void zsvsheet_set_status(const struct zsvsheet_display_dimensions *ddims, int overwrite, const char *fmt, ...) {
if (overwrite || !*zsvsheet_status_text) {
va_list argv;
va_start(argv, fmt);
vsnprintf(zsvsheet_status_text, sizeof(zsvsheet_status_text), fmt, argv);
va_end(argv);
// note: if (n < (int)sizeof(zsvsheet_status_text)), then we just ignore
}
zsvsheet_display_status_text(ddims);
}

#include "sheet/terminfo.c"
#include "sheet/handlers_internal.h"
#include "sheet/handlers.c"
#include "sheet/file.c"
#include "sheet/usage.c"

int zsvsheet_ui_buffer_open_file(const char *filename, const struct zsv_opts *zsv_optsp, const char *row_filter,
struct zsv_prop_handler *custom_prop_handler, const char *opts_used,
struct zsvsheet_ui_buffer **ui_buffer_stack_bottom,
struct zsvsheet_ui_buffer **ui_buffer_stack_top) {
struct zsvsheet_buffer_opts bopts = {0};
struct zsvsheet_ui_buffer_opts uibopts = {0};
uibopts.filename = filename;
uibopts.buff_opts = &bopts;
struct zsvsheet_opts zsvsheet_opts = {0};
struct zsv_opts opts = *zsv_optsp;
int err = 0;
struct zsvsheet_ui_buffer *tmp_ui_buffer = NULL;
uibopts.row_filter = row_filter;
if ((err = read_data(&tmp_ui_buffer, &uibopts, &opts, 0, 0, 0, NULL, &zsvsheet_opts, custom_prop_handler,
opts_used)) != 0 ||
!tmp_ui_buffer || !tmp_ui_buffer->buff_used_rows) {
zsvsheet_ui_buffer_delete(tmp_ui_buffer);
if (err)
return err;
return -1;
enum zsvsheet_status zsvsheet_key_handler(struct zsvsheet_key_handler_data *khd, int ch, char *cmdbuff,
size_t cmdbuff_sz, // subcommand buffer
struct zsvsheet_ui_buffer **base_ui_buffer,
struct zsvsheet_ui_buffer **current_ui_buffer,
const struct zsvsheet_display_dimensions *display_dims,
struct zsv_prop_handler *custom_prop_handler, const char *opts_used) {
struct zsvsheet_subcommand_handler_context sctx = {0};
sctx.ch = ch;
sctx.ui_buffers = *base_ui_buffer;
sctx.current_ui_buffer = *current_ui_buffer;
zsvsheet_handler_status status = khd->subcommand_handler(&sctx);
if (status == zsvsheet_handler_status_ok) {
get_subcommand(sctx.prompt, cmdbuff, cmdbuff_sz, (int)(display_dims->rows - display_dims->footer_span));
if (*cmdbuff == '\0')
return zsvsheet_status_continue;
struct zsvsheet_handler_context ctx = {.subcommand_value = cmdbuff,
.ch = ch,
.ui_buffers = {.base = base_ui_buffer, .current = current_ui_buffer},
.display_dims = display_dims,
.custom_prop_handler = custom_prop_handler,
.opts_used = opts_used};
status = khd->handler(&ctx);
}
tmp_ui_buffer->cursor_row = 1; // first row is header
zsvsheet_ui_buffer_push(ui_buffer_stack_bottom, ui_buffer_stack_top, tmp_ui_buffer);
return 0;
if (status == zsvsheet_handler_status_ok)
return zsvsheet_status_ok;
if (status == zsvsheet_handler_status_ignore)
return zsvsheet_status_continue;
return zsvsheet_status_error;
}

#include "sheet/usage.c"
struct zsvsheet_key_handler_data *zsvsheet_key_handlers = NULL;
struct zsvsheet_key_handler_data **zsvsheet_next_key_handler = &zsvsheet_key_handlers;

int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *optsp,
struct zsv_prop_handler *custom_prop_handler, const char *opts_used) {
Expand Down Expand Up @@ -244,7 +257,14 @@ int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *op
display_buffer_subtable(current_ui_buffer, rownum_col_offset, header_span, &display_dims);
char cmdbuff[256]; // subcommand buffer

while ((zsvsheetch = zsvsheet_key_binding(getch())) != zsvsheet_key_quit) {
// register built-in key handlers
zsvsheet_register_command_internal(zsvsheet_key_open_file, "open-file", zsvsheet_file_subcommand_handler,
zsvsheet_file_handler);
zsvsheet_register_command_internal(zsvsheet_key_filter, "filter", zsvsheet_file_subcommand_handler,
zsvsheet_file_handler);

int ch;
while ((zsvsheetch = zsvsheet_key_binding((ch = getch()))) != zsvsheet_key_quit) {
zsvsheet_set_status(&display_dims, 1, "");
int update_buffer = 0;
switch (zsvsheetch) {
Expand Down Expand Up @@ -353,7 +373,7 @@ int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *op
case zsvsheet_key_find_next:
if (find) {
struct zsvsheet_opts zsvsheet_opts = {0};
if (!zsvsheet_handle_find_next(current_ui_buffer, find, optsp, &zsvsheet_opts, header_span, &display_dims,
if (!zsvsheet_handle_find_next(current_ui_buffer, find, &zsvsheet_opts, header_span, &display_dims,
&update_buffer, custom_prop_handler, opts_used))
continue;
}
Expand All @@ -364,41 +384,31 @@ int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *op
free(find);
find = strdup(cmdbuff);
struct zsvsheet_opts zsvsheet_opts = {0};
if (!zsvsheet_handle_find_next(current_ui_buffer, find, optsp, &zsvsheet_opts, header_span, &display_dims,
if (!zsvsheet_handle_find_next(current_ui_buffer, find, &zsvsheet_opts, header_span, &display_dims,
&update_buffer, custom_prop_handler, opts_used))
continue;
}
break;
case zsvsheet_key_open_file:
case zsvsheet_key_filter:
get_subcommand(zsvsheetch == zsvsheet_key_filter ? "Filter" : "File to open", cmdbuff, sizeof(cmdbuff),
(int)(display_dims.rows - display_dims.footer_span));
if (*cmdbuff == '\0')
continue;

if ((err = zsvsheet_ui_buffer_open_file(zsvsheetch == zsvsheet_key_filter ? current_ui_buffer->filename : cmdbuff,
optsp, zsvsheetch == zsvsheet_key_filter ? cmdbuff : NULL,
custom_prop_handler, opts_used, &ui_buffers, &current_ui_buffer))) {
if (err > 0)
zsvsheet_set_status(&display_dims, 1, "%s: %s", current_ui_buffer->filename, strerror(err));
else if (err < 0)
zsvsheet_set_status(&display_dims, 1, "Unexpected error");
else
zsvsheet_set_status(&display_dims, 1, "Not found: %s", cmdbuff);
case zsvsheet_key_filter: {
struct zsvsheet_key_handler_data *zkhd = zsvsheet_get_registered_key_handler(ch, NULL, zsvsheet_key_handlers);
if (!zkhd || zsvsheet_key_handler(zkhd, ch, cmdbuff, sizeof(cmdbuff), &ui_buffers, &current_ui_buffer,
&display_dims, custom_prop_handler, opts_used) == zsvsheet_status_continue)
continue;
} else if (zsvsheetch == zsvsheet_key_filter && current_ui_buffer->dimensions.row_count < 2) {
zsvsheet_ui_buffer_pop(&ui_buffers, &current_ui_buffer, NULL);
zsvsheet_set_status(&display_dims, 1, "Not found: %s", cmdbuff);
}
break;
default:
}
default: {
struct zsvsheet_key_handler_data *zkhd = zsvsheet_get_registered_key_handler(ch, NULL, zsvsheet_key_handlers);
if (zkhd && zsvsheet_key_handler(zkhd, ch, cmdbuff, sizeof(cmdbuff), &ui_buffers, &current_ui_buffer,
&display_dims, custom_prop_handler, opts_used) != zsvsheet_status_continue)
break;
continue;
}
if (update_buffer) {
}
if (update_buffer && current_ui_buffer->filename) {
struct zsvsheet_opts zsvsheet_opts = {0};
if (read_data(&current_ui_buffer, NULL, optsp, current_ui_buffer->input_offset.row,
current_ui_buffer->input_offset.col, header_span, current_ui_buffer->dimensions.index,
&zsvsheet_opts, custom_prop_handler, opts_used)) {
if (read_data(&current_ui_buffer, NULL, current_ui_buffer->input_offset.row, current_ui_buffer->input_offset.col,
header_span, current_ui_buffer->dimensions.index, &zsvsheet_opts, custom_prop_handler, opts_used)) {
zsvsheet_set_status(&display_dims, 1, "Unexpected error!"); // to do: better error message
continue;
}
Expand All @@ -411,6 +421,7 @@ int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *op
endwin();
free(find);
zsvsheet_ui_buffers_delete(ui_buffers);
zsvsheet_key_handlers_delete(&zsvsheet_key_handlers, &zsvsheet_next_key_handler);
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion app/sheet/cursor.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
static size_t input_offset_top() {
static size_t input_offset_top(void) {
return 0;
}

Expand Down
Loading

0 comments on commit 3d0af38

Please sign in to comment.