Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

begin to set up sheet handling plugin structures #228

Merged
merged 8 commits into from
Oct 15, 2024
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