From 32122651bdb51006edce2be3586dd09179bed52f Mon Sep 17 00:00:00 2001 From: Robin Haberkorn Date: Sun, 23 Aug 2026 00:28:23 +0200 Subject: introduced helper functions teco_qreg_table_get_string() and teco_qreg_table_get_integer() * Simplifies the common task of querying an integer or string from a Q-Register table. * Undefined Q-Regs are reported as TECO_ERROR_QREGUNDEF, so you can theoretically handle this case. In practice however, it requires less boilerplating to just call teco_qreg_table_find() manually. * It also doesn't make sense to use these functions when getting and setting a register at the same time as you will want to avoid repeated lookups. --- src/cmdline.c | 6 ++---- src/core-commands.c | 9 +++------ src/error.h | 1 + src/file-utils.c | 9 ++------- src/help.c | 5 ++--- src/interface-curses/interface.c | 26 ++++++++------------------ src/interface-gtk/interface.c | 6 ++---- src/lsp.c | 15 ++++----------- src/qreg.h | 33 +++++++++++++++++++++++++++++++++ src/search.c | 25 ++++++------------------- src/spawn.c | 10 ++++------ 11 files changed, 67 insertions(+), 78 deletions(-) (limited to 'src') diff --git a/src/cmdline.c b/src/cmdline.c index 572b159..d2d9d04 100644 --- a/src/cmdline.c +++ b/src/cmdline.c @@ -173,11 +173,9 @@ teco_cmdline_insert(const gchar *data, gsize len, GError **error) */ g_clear_error(&tmp_error); - teco_qreg_t *cmdline_reg = teco_qreg_table_find(&teco_qreg_table_globals, "\e", 1); g_auto(teco_string_t) new_cmdline = {NULL, 0}; - - if (!cmdline_reg->vtable->get_string(cmdline_reg, &new_cmdline.data, &new_cmdline.len, - NULL, &tmp_error)) { + if (!teco_qreg_table_get_string(&teco_qreg_table_globals, "\e", + &new_cmdline.data, &new_cmdline.len, &tmp_error)) { teco_error_add_frame_toplevel(); teco_error_display_short(tmp_error); g_propagate_error(error, g_steal_pointer(&tmp_error)); diff --git a/src/core-commands.c b/src/core-commands.c index 8f84224..d01cbb9 100644 --- a/src/core-commands.c +++ b/src/core-commands.c @@ -461,10 +461,8 @@ teco_state_start_break(teco_machine_main_t *ctx, GError **error) return; } - teco_qreg_t *reg = teco_qreg_table_find(&teco_qreg_table_globals, "_", 1); - g_assert(reg != NULL); teco_int_t v; - if (!reg->vtable->get_integer(reg, &v, error)) + if (!teco_qreg_table_get_integer(&teco_qreg_table_globals, "_", &v, error)) return; teco_bool_t rc; @@ -1134,10 +1132,9 @@ teco_state_changedir_done(teco_machine_main_t *ctx, teco_string_t str, GError ** g_autofree gchar *dir = teco_file_expand_path(str.data); if (!*dir) { - teco_qreg_t *qreg = teco_qreg_table_find(&teco_qreg_table_globals, "$HOME", 5); - g_assert(qreg != NULL); teco_string_t home; - if (!qreg->vtable->get_string(qreg, &home.data, &home.len, NULL, error)) + if (!teco_qreg_table_get_string(&teco_qreg_table_globals, "$HOME", + &home.data, &home.len, error)) return NULL; /* diff --git a/src/error.h b/src/error.h index a848116..1306feb 100644 --- a/src/error.h +++ b/src/error.h @@ -50,6 +50,7 @@ typedef enum { TECO_ERROR_SUBPATTERN, TECO_ERROR_INVALIDBUF, TECO_ERROR_INVALIDQREG, + TECO_ERROR_QREGUNDEF, TECO_ERROR_QREGOPUNSUPPORTED, TECO_ERROR_QREGCONTAINSNULL, TECO_ERROR_EDITINGLOCALQREG, diff --git a/src/file-utils.c b/src/file-utils.c index 8555271..4bf5e6a 100644 --- a/src/file-utils.c +++ b/src/file-utils.c @@ -348,18 +348,13 @@ teco_file_expand_path(const gchar *path) * but this ensures that a proper path is constructed even if * it does (e.g. $HOME is changed later on). * - * FIXME: In the future, it might be possible to remove the entire register. - */ - teco_qreg_t *qreg = teco_qreg_table_find(&teco_qreg_table_globals, "$HOME", 5); - g_assert(qreg != NULL); - - /* * Getting the string should not possible to fail. * The $HOME register should not contain any null-bytes on startup, * but it may have been changed later on. */ g_auto(teco_string_t) home = {NULL, 0}; - if (!qreg->vtable->get_string(qreg, &home.data, &home.len, NULL, NULL) || + if (!teco_qreg_table_get_string(&teco_qreg_table_globals, "$HOME", + &home.data, &home.len, NULL) || teco_string_contains(home, '\0')) return g_strdup(path); g_assert(home.data != NULL); diff --git a/src/help.c b/src/help.c index b7b5fd0..db8a974 100644 --- a/src/help.c +++ b/src/help.c @@ -92,10 +92,9 @@ teco_help_init(GError **error) teco_help_chunk = g_string_chunk_new(32); rb3_reset_tree(&teco_help_tree); - teco_qreg_t *lib_reg = teco_qreg_table_find(&teco_qreg_table_globals, "$SCITECOPATH", 12); - g_assert(lib_reg != NULL); g_auto(teco_string_t) lib_path = {NULL, 0}; - if (!lib_reg->vtable->get_string(lib_reg, &lib_path.data, &lib_path.len, NULL, error)) + if (!teco_qreg_table_get_string(&teco_qreg_table_globals, "$SCITECOPATH", + &lib_path.data, &lib_path.len, error)) return FALSE; /* * FIXME: lib_path may contain null-bytes. diff --git a/src/interface-curses/interface.c b/src/interface-curses/interface.c index db996f5..fbac2cb 100644 --- a/src/interface-curses/interface.c +++ b/src/interface-curses/interface.c @@ -1527,17 +1527,12 @@ teco_interface_set_clipboard(const gchar *name, const gchar *str, gsize str_len, static const gchar reg_name[] = "$SCITECO_CLIPBOARD_SET"; - teco_qreg_t *reg = teco_qreg_table_find(&teco_qreg_table_globals, reg_name, strlen(reg_name)); - if (!reg) { - /* Q-Register could have been removed in the meantime */ - g_set_error(error, TECO_ERROR, TECO_ERROR_FAILED, - "Cannot set clipboard. %s is undefined.", reg_name); - return FALSE; - } - g_auto(teco_string_t) command = {NULL, 0}; - if (!reg->vtable->get_string(reg, &command.data, &command.len, NULL, error)) + if (!teco_qreg_table_get_string(&teco_qreg_table_globals, reg_name, + &command.data, &command.len, error)) { + g_prefix_error(error, "Cannot set clipboard: "); return FALSE; + } if (teco_string_contains(command, '\0')) { teco_error_qregcontainsnull_set(error, reg_name, strlen(reg_name), FALSE); return FALSE; @@ -1588,17 +1583,12 @@ teco_interface_get_clipboard(const gchar *name, gchar **str, gsize *len, GError static const gchar reg_name[] = "$SCITECO_CLIPBOARD_GET"; - teco_qreg_t *reg = teco_qreg_table_find(&teco_qreg_table_globals, reg_name, strlen(reg_name)); - if (!reg) { - /* Q-Register could have been removed in the meantime */ - g_set_error(error, TECO_ERROR, TECO_ERROR_FAILED, - "Cannot get clipboard. %s is undefined.", reg_name); - return FALSE; - } - g_auto(teco_string_t) command = {NULL, 0}; - if (!reg->vtable->get_string(reg, &command.data, &command.len, NULL, error)) + if (!teco_qreg_table_get_string(&teco_qreg_table_globals, reg_name, + &command.data, &command.len, error)) { + g_prefix_error(error, "Cannot get clipboard: "); return FALSE; + } if (teco_string_contains(command, '\0')) { teco_error_qregcontainsnull_set(error, reg_name, strlen(reg_name), FALSE); return FALSE; diff --git a/src/interface-gtk/interface.c b/src/interface-gtk/interface.c index 1f6259f..b2d4788 100644 --- a/src/interface-gtk/interface.c +++ b/src/interface-gtk/interface.c @@ -1210,11 +1210,9 @@ teco_interface_handle_scroll(GdkEventScroll *event, GError **error) gboolean teco_interface_event_loop(GError **error) { - teco_qreg_t *scitecoconfig_reg = teco_qreg_table_find(&teco_qreg_table_globals, "$SCITECOCONFIG", 14); - g_assert(scitecoconfig_reg != NULL); g_auto(teco_string_t) scitecoconfig = {NULL, 0}; - if (!scitecoconfig_reg->vtable->get_string(scitecoconfig_reg, - &scitecoconfig.data, &scitecoconfig.len, NULL, error)) + if (!teco_qreg_table_get_string(&teco_qreg_table_globals, "$SCITECOCONFIG", + &scitecoconfig.data, &scitecoconfig.len, error)) return FALSE; if (teco_string_contains(scitecoconfig, '\0')) { g_set_error_literal(error, TECO_ERROR, TECO_ERROR_FAILED, diff --git a/src/lsp.c b/src/lsp.c index 2c1f89b..ff7ddc7 100644 --- a/src/lsp.c +++ b/src/lsp.c @@ -444,16 +444,9 @@ teco_lsp_launch(GError **error) G_SPAWN_STDERR_TO_DEV_NULL; static const gchar lsp_reg_name[] = "$SCITECO_LSP"; - teco_qreg_t *reg = teco_qreg_table_find(&teco_qreg_table_globals, - lsp_reg_name, strlen(lsp_reg_name)); - if (!reg) { - g_set_error(error, TECO_ERROR, TECO_ERROR_FAILED, - "Q-Register %s is undefined.", lsp_reg_name); - return FALSE; - } - g_auto(teco_string_t) command = {NULL, 0}; - if (!reg->vtable->get_string(reg, &command.data, &command.len, NULL, error)) + if (!teco_qreg_table_get_string(&teco_qreg_table_globals, lsp_reg_name, + &command.data, &command.len, error)) return FALSE; if (teco_string_contains(command, '\0')) { teco_error_qregcontainsnull_set(error, lsp_reg_name, strlen(lsp_reg_name), FALSE); @@ -497,8 +490,8 @@ teco_lsp_launch(GError **error) g_auto(teco_string_t) root = {NULL, 0}; static const gchar root_reg_name[] = "$SCITECO_LSP_ROOT"; - reg = teco_qreg_table_find(&teco_qreg_table_globals, - root_reg_name, strlen(root_reg_name)); + teco_qreg_t *reg = teco_qreg_table_find(&teco_qreg_table_globals, + root_reg_name, strlen(root_reg_name)); if (reg) { if (!reg->vtable->get_string(reg, &root.data, &root.len, NULL, error)) return FALSE; diff --git a/src/qreg.h b/src/qreg.h index ca35e78..1eb2cf8 100644 --- a/src/qreg.h +++ b/src/qreg.h @@ -16,6 +16,8 @@ */ #pragma once +#include + #include //#include @@ -24,6 +26,7 @@ #include "view.h" #include "doc.h" #include "undo.h" +#include "error.h" #include "string-utils.h" #include "rb3str.h" @@ -212,6 +215,36 @@ teco_qreg_table_find(teco_qreg_table_t *table, const gchar *name, gsize len) return (teco_qreg_t *)teco_rb3str_find(&table->tree, TRUE, name, len); } +/** @memberof teco_qreg_table_t */ +static inline gboolean +teco_qreg_table_get_string(teco_qreg_table_t *table, const gchar *name, + gchar **str, gsize *len, GError **error) +{ + teco_qreg_t *reg = teco_qreg_table_find(table, name, strlen(name)); + if (!reg) { + g_set_error(error, TECO_ERROR, TECO_ERROR_QREGUNDEF, + "Q-Register \"%s\" is undefined.", name); + return FALSE; + } + + return reg->vtable->get_string(reg, str, len, NULL, error); +} + +/** @memberof teco_qreg_table_t */ +static inline gboolean +teco_qreg_table_get_integer(teco_qreg_table_t *table, const gchar *name, + teco_int_t *ret, GError **error) +{ + teco_qreg_t *reg = teco_qreg_table_find(table, name, strlen(name)); + if (!reg) { + g_set_error(error, TECO_ERROR, TECO_ERROR_QREGUNDEF, + "Q-Register \"%s\" is undefined.", name); + return FALSE; + } + + return reg->vtable->get_integer(reg, ret, error); +} + teco_qreg_t *teco_qreg_table_edit_name(teco_qreg_table_t *table, const gchar *name, gsize len, GError **error); diff --git a/src/search.c b/src/search.c index 357a0c0..2b2a696 100644 --- a/src/search.c +++ b/src/search.c @@ -928,10 +928,9 @@ teco_state_search_process(teco_machine_main_t *ctx, teco_string_t str, gsize new { gint cflags = REG_ADVANCED; - teco_qreg_t *reg = teco_qreg_table_find(ctx->qreg_table_locals, "\x18", 1); /* ^X */ - g_assert(reg != NULL); teco_bool_t search_mode; - if (!reg->vtable->get_integer(reg, &search_mode, error)) + if (!teco_qreg_table_get_integer(ctx->qreg_table_locals, "\x18", /* ^X */ + &search_mode, error)) return FALSE; if (teco_is_failure(search_mode)) cflags |= REG_ICASE; @@ -1344,12 +1343,9 @@ teco_state_search_kill_done(teco_machine_main_t *ctx, teco_string_t str, GError if (ctx->flags.mode > TECO_MODE_NORMAL) return &teco_state_start; - teco_qreg_t *search_reg = teco_qreg_table_find(&teco_qreg_table_globals, "_", 1); - g_assert(search_reg != NULL); - teco_int_t search_state; if (!teco_state_search_done(ctx, str, error) || - !search_reg->vtable->get_integer(search_reg, &search_state, error)) + !teco_qreg_table_get_integer(&teco_qreg_table_globals, "_", &search_state, error)) return NULL; if (teco_is_failure(search_state)) @@ -1433,12 +1429,9 @@ teco_state_search_delete_done(teco_machine_main_t *ctx, teco_string_t str, GErro if (ctx->flags.mode > TECO_MODE_NORMAL) return &teco_state_start; - teco_qreg_t *search_reg = teco_qreg_table_find(&teco_qreg_table_globals, "_", 1); - g_assert(search_reg != NULL); - teco_int_t search_state; if (!teco_state_search_done(ctx, str, error) || - !search_reg->vtable->get_integer(search_reg, &search_state, error)) + !teco_qreg_table_get_integer(&teco_qreg_table_globals, "_", &search_state, error)) return NULL; if (teco_is_success(search_state)) { @@ -1519,12 +1512,9 @@ teco_state_replace_done(teco_machine_main_t *ctx, teco_string_t str, GError **er if (ctx->flags.mode > TECO_MODE_NORMAL) return &teco_state_replace_ignore; - teco_qreg_t *search_reg = teco_qreg_table_find(&teco_qreg_table_globals, "_", 1); - g_assert(search_reg != NULL); - teco_int_t search_state; if (!teco_state_search_delete_done(ctx, str, error) || - !search_reg->vtable->get_integer(search_reg, &search_state, error)) + !teco_qreg_table_get_integer(&teco_qreg_table_globals, "_", &search_state, error)) return NULL; return teco_is_success(search_state) ? &teco_state_replace_insert @@ -1627,12 +1617,9 @@ teco_state_replace_default_done(teco_machine_main_t *ctx, teco_string_t str, GEr if (ctx->flags.mode > TECO_MODE_NORMAL) return &teco_state_replace_default_ignore; - teco_qreg_t *search_reg = teco_qreg_table_find(&teco_qreg_table_globals, "_", 1); - g_assert(search_reg != NULL); - teco_int_t search_state; if (!teco_state_search_delete_done(ctx, str, error) || - !search_reg->vtable->get_integer(search_reg, &search_state, error)) + !teco_qreg_table_get_integer(&teco_qreg_table_globals, "_", &search_state, error)) return NULL; return teco_is_success(search_state) ? &teco_state_replace_default_insert diff --git a/src/spawn.c b/src/spawn.c index 6289830..644bf31 100644 --- a/src/spawn.c +++ b/src/spawn.c @@ -125,10 +125,9 @@ teco_parse_shell_command_line(const gchar *cmdline, GError **error) #ifdef G_OS_WIN32 if (!(teco_ed & TECO_ED_SHELLEMU)) { - teco_qreg_t *reg = teco_qreg_table_find(&teco_qreg_table_globals, "$COMSPEC", 8); - g_assert(reg != NULL); teco_string_t comspec; - if (!reg->vtable->get_string(reg, &comspec.data, &comspec.len, NULL, error)) + if (!teco_qreg_table_get_string(&teco_qreg_table_globals, "$COMSPEC", + &comspec.data, &comspec.len, error)) return NULL; if (teco_string_contains(comspec, '\0')) { teco_string_clear(&comspec); @@ -145,10 +144,9 @@ teco_parse_shell_command_line(const gchar *cmdline, GError **error) } #elif defined(G_OS_UNIX) if (!(teco_ed & TECO_ED_SHELLEMU)) { - teco_qreg_t *reg = teco_qreg_table_find(&teco_qreg_table_globals, "$SHELL", 6); - g_assert(reg != NULL); teco_string_t shell; - if (!reg->vtable->get_string(reg, &shell.data, &shell.len, NULL, error)) + if (!teco_qreg_table_get_string(&teco_qreg_table_globals, "$SHELL", + &shell.data, &shell.len, error)) return NULL; if (teco_string_contains(shell, '\0')) { teco_string_clear(&shell); -- cgit v1.2.3