diff options
| -rw-r--r-- | src/cmdline.c | 3 | ||||
| -rw-r--r-- | src/cmdline.h | 2 | ||||
| -rw-r--r-- | src/core-commands.c | 39 | ||||
| -rw-r--r-- | src/core-commands.h | 33 | ||||
| -rw-r--r-- | src/glob.c | 12 | ||||
| -rw-r--r-- | src/glob.h | 2 | ||||
| -rw-r--r-- | src/goto-commands.c | 28 | ||||
| -rw-r--r-- | src/goto-commands.h | 4 | ||||
| -rw-r--r-- | src/help.c | 3 | ||||
| -rw-r--r-- | src/help.h | 2 | ||||
| -rw-r--r-- | src/parser.c | 89 | ||||
| -rw-r--r-- | src/parser.h | 33 | ||||
| -rw-r--r-- | src/qreg-commands.c | 64 | ||||
| -rw-r--r-- | src/qreg-commands.h | 44 | ||||
| -rw-r--r-- | src/qreg.c | 34 | ||||
| -rw-r--r-- | src/ring.c | 11 | ||||
| -rw-r--r-- | src/ring.h | 6 | ||||
| -rw-r--r-- | src/sciteco.h | 10 | ||||
| -rw-r--r-- | src/search.c | 61 | ||||
| -rw-r--r-- | src/search.h | 14 | ||||
| -rw-r--r-- | src/spawn.c | 6 | ||||
| -rw-r--r-- | src/spawn.h | 4 | ||||
| -rw-r--r-- | src/stdio-commands.c | 9 | ||||
| -rw-r--r-- | src/stdio-commands.h | 4 | ||||
| -rw-r--r-- | src/symbols.c | 12 | ||||
| -rw-r--r-- | src/symbols.h | 2 |
26 files changed, 300 insertions, 231 deletions
diff --git a/src/cmdline.c b/src/cmdline.c index e1a4628..d06b8c2 100644 --- a/src/cmdline.c +++ b/src/cmdline.c @@ -1504,5 +1504,6 @@ teco_state_save_cmdline_got_register(teco_machine_main_t *ctx, teco_qreg_t *qreg * Q-Register <q>. */ TECO_DEFINE_STATE_EXPECTQREG(teco_state_save_cmdline, - .expectqreg.type = TECO_QREG_OPTIONAL_INIT + .expectqreg.type = TECO_QREG_OPTIONAL_INIT, + .expectqreg.got_register_cb = teco_state_save_cmdline_got_register ); diff --git a/src/cmdline.h b/src/cmdline.h index 9123358..e8d69d5 100644 --- a/src/cmdline.h +++ b/src/cmdline.h @@ -120,4 +120,4 @@ void teco_cmdline_cleanup(void); * Command states */ -TECO_DECLARE_STATE(teco_state_save_cmdline); +extern teco_state_t teco_state_save_cmdline; diff --git a/src/core-commands.c b/src/core-commands.c index e756eab..86a4b85 100644 --- a/src/core-commands.c +++ b/src/core-commands.c @@ -643,7 +643,7 @@ teco_state_start_input(teco_machine_main_t *ctx, gunichar chr, GError **error) ['"'] = {&teco_state_condcommand}, ['E'] = {&teco_state_ecommand, .modifier_at = TRUE, .modifier_colon = 2}, - ['I'] = {&teco_state_insert_plain, + ['I'] = {&teco_state_insert, .modifier_at = TRUE}, ['?'] = {&teco_state_help, .modifier_at = TRUE}, @@ -915,7 +915,9 @@ teco_state_start_input(teco_machine_main_t *ctx, gunichar chr, GError **error) teco_ascii_toupper(chr), error); } -TECO_DEFINE_STATE_START(teco_state_start); +TECO_DEFINE_STATE_START(teco_state_start, + .input_cb = (teco_state_input_cb_t)teco_state_start_input +); /*$ "F<" ":F<" * F< -- Go to loop start or jump to beginning of macro @@ -1080,7 +1082,9 @@ teco_state_fcommand_input(teco_machine_main_t *ctx, gunichar chr, GError **error teco_ascii_toupper(chr), error); } -TECO_DEFINE_STATE_COMMAND(teco_state_fcommand); +TECO_DEFINE_STATE_COMMAND(teco_state_fcommand, + .input_cb = (teco_state_input_cb_t)teco_state_fcommand_input +); static void teco_undo_change_dir_action(gchar **dir, gboolean run) @@ -1172,7 +1176,9 @@ teco_state_changedir_done(teco_machine_main_t *ctx, const teco_string_t *str, GE * String-building characters are enabled on this * command and directories can be tab-completed. */ -TECO_DEFINE_STATE_EXPECTDIR(teco_state_changedir); +TECO_DEFINE_STATE_EXPECTDIR(teco_state_changedir, + .expectstring.done_cb = teco_state_changedir_done +); static teco_state_t * teco_state_condcommand_input(teco_machine_main_t *ctx, gunichar chr, GError **error) @@ -1287,7 +1293,8 @@ teco_state_condcommand_input(teco_machine_main_t *ctx, gunichar chr, GError **er } TECO_DEFINE_STATE_COMMAND(teco_state_condcommand, - .style = SCE_SCITECO_OPERATOR + .style = SCE_SCITECO_OPERATOR, + .input_cb = (teco_state_input_cb_t)teco_state_condcommand_input ); /*$ ^_ negate @@ -1701,7 +1708,9 @@ teco_state_control_input(teco_machine_main_t *ctx, gunichar chr, GError **error) teco_ascii_toupper(chr), error); } -TECO_DEFINE_STATE_COMMAND(teco_state_control); +TECO_DEFINE_STATE_COMMAND(teco_state_control, + .input_cb = (teco_state_input_cb_t)teco_state_control_input +); static teco_state_t * teco_state_ascii_input(teco_machine_main_t *ctx, gunichar chr, GError **error) @@ -1724,7 +1733,9 @@ teco_state_ascii_input(teco_machine_main_t *ctx, gunichar chr, GError **error) * Note that this command can be typed CTRL+Caret or * Caret-Caret. */ -TECO_DEFINE_STATE(teco_state_ascii); +TECO_DEFINE_STATE(teco_state_ascii, + .input_cb = (teco_state_input_cb_t)teco_state_ascii_input +); /*$ ^[^[ ^[$ $$ ^C terminate return * [a1,a2,...]$$ -- Terminate command line or return from macro @@ -1858,6 +1869,7 @@ teco_state_escape_end_of_macro(teco_machine_t *ctx, GError **error) } TECO_DEFINE_STATE_START(teco_state_escape, + .input_cb = (teco_state_input_cb_t)teco_state_escape_input, .end_of_macro_cb = teco_state_escape_end_of_macro ); @@ -1892,7 +1904,8 @@ teco_state_ctlc_initial(teco_machine_main_t *ctx, GError **error) } TECO_DEFINE_STATE_START(teco_state_ctlc, - .initial_cb = (teco_state_initial_cb_t)teco_state_ctlc_initial + .initial_cb = (teco_state_initial_cb_t)teco_state_ctlc_initial, + .input_cb = (teco_state_input_cb_t)teco_state_ctlc_input ); static teco_state_t * @@ -1947,7 +1960,9 @@ teco_state_ctlc_control_input(teco_machine_main_t *ctx, gunichar chr, GError **e * This state is necessary, so that you can type ^C^C exclusively with carets. * Otherwise it would be very cumbersome to cause exits with ASCII characters only. */ -TECO_DEFINE_STATE_COMMAND(teco_state_ctlc_control); +TECO_DEFINE_STATE_COMMAND(teco_state_ctlc_control, + .input_cb = (teco_state_input_cb_t)teco_state_ctlc_control_input +); /*$ ED flags * flags ED -- Set and get ED-flags @@ -2843,7 +2858,9 @@ teco_state_ecommand_input(teco_machine_main_t *ctx, gunichar chr, GError **error teco_ascii_toupper(chr), error); } -TECO_DEFINE_STATE_COMMAND(teco_state_ecommand); +TECO_DEFINE_STATE_COMMAND(teco_state_ecommand, + .input_cb = (teco_state_input_cb_t)teco_state_ecommand_input +); gboolean teco_state_insert_initial(teco_machine_main_t *ctx, GError **error) @@ -2962,7 +2979,7 @@ teco_state_insert_done(teco_machine_main_t *ctx, const teco_string_t *str, GErro * may be better, since it has string building characters * disabled. */ -TECO_DEFINE_STATE_INSERT(teco_state_insert_plain); +TECO_DEFINE_STATE_INSERT(teco_state_insert); static gboolean teco_state_insert_indent_initial(teco_machine_main_t *ctx, GError **error) diff --git a/src/core-commands.h b/src/core-commands.h index 4cc8747..425379e 100644 --- a/src/core-commands.h +++ b/src/core-commands.h @@ -55,15 +55,15 @@ gboolean teco_state_command_process_edit_cmd(teco_machine_main_t *ctx, teco_mach * FIXME: Most of these states can probably be private/static * as they are only referenced from teco_state_start. */ -TECO_DECLARE_STATE(teco_state_fcommand); +extern teco_state_t teco_state_fcommand; void teco_undo_change_dir_to_current(void); -TECO_DECLARE_STATE(teco_state_changedir); +extern teco_state_t teco_state_changedir; -TECO_DECLARE_STATE(teco_state_condcommand); -TECO_DECLARE_STATE(teco_state_control); -TECO_DECLARE_STATE(teco_state_ascii); -TECO_DECLARE_STATE(teco_state_ecommand); +extern teco_state_t teco_state_condcommand; +extern teco_state_t teco_state_control; +extern teco_state_t teco_state_ascii; +extern teco_state_t teco_state_ecommand; typedef struct { teco_int_t from; /*< start position in glyphs */ @@ -88,23 +88,18 @@ gboolean teco_state_insert_process_edit_cmd(teco_machine_main_t *ctx, teco_machi * @ingroup states * * @note Also serves as a base class of the replace-insertion commands. - * @fixme Generating the done_cb could be avoided if there simply were a default. */ #define TECO_DEFINE_STATE_INSERT(NAME, ...) \ - static teco_state_t * \ - NAME##_done(teco_machine_main_t *ctx, const teco_string_t *str, GError **error) \ - { \ - return teco_state_insert_done(ctx, str, error); \ - } \ TECO_DEFINE_STATE_EXPECTSTRING(NAME, \ .initial_cb = (teco_state_initial_cb_t)teco_state_insert_initial, \ .process_edit_cmd_cb = (teco_state_process_edit_cmd_cb_t)teco_state_insert_process_edit_cmd, \ .expectstring.process_cb = teco_state_insert_process, \ + .expectstring.done_cb = teco_state_insert_done, \ ##__VA_ARGS__ \ ) -TECO_DECLARE_STATE(teco_state_insert_plain); -TECO_DECLARE_STATE(teco_state_insert_indent); +extern teco_state_t teco_state_insert; +extern teco_state_t teco_state_insert_indent; /** * @class TECO_DEFINE_STATE_START @@ -124,8 +119,8 @@ TECO_DECLARE_STATE(teco_state_insert_indent); teco_state_t *teco_state_start_input(teco_machine_main_t *ctx, gunichar chr, GError **error); -TECO_DECLARE_STATE(teco_state_start); -TECO_DECLARE_STATE(teco_state_control); -TECO_DECLARE_STATE(teco_state_escape); -TECO_DECLARE_STATE(teco_state_ctlc); -TECO_DECLARE_STATE(teco_state_ctlc_control); +extern teco_state_t teco_state_start; +extern teco_state_t teco_state_control; +extern teco_state_t teco_state_escape; +extern teco_state_t teco_state_ctlc; +extern teco_state_t teco_state_ctlc_control; @@ -38,10 +38,7 @@ #include "undo.h" #include "glob.h" -/* - * FIXME: This state could be static. - */ -TECO_DECLARE_STATE(teco_state_glob_filename); +static teco_state_t teco_state_glob_filename; /** @memberof teco_globber_t */ void @@ -454,7 +451,8 @@ teco_state_glob_pattern_done(teco_machine_main_t *ctx, const teco_string_t *str, * have to edit that register anyway. */ TECO_DEFINE_STATE_EXPECTGLOB(teco_state_glob_pattern, - .expectstring.last = FALSE + .expectstring.last = FALSE, + .expectstring.done_cb = teco_state_glob_pattern_done ); static teco_state_t * @@ -593,4 +591,6 @@ teco_state_glob_filename_done(teco_machine_main_t *ctx, const teco_string_t *str return &teco_state_start; } -TECO_DEFINE_STATE_EXPECTFILE(teco_state_glob_filename); +static TECO_DEFINE_STATE_EXPECTFILE(teco_state_glob_filename, + .expectstring.done_cb = teco_state_glob_filename_done +); @@ -68,4 +68,4 @@ gboolean teco_state_expectglob_insert_completion(teco_machine_main_t *ctx, const * Command states */ -TECO_DECLARE_STATE(teco_state_glob_pattern); +extern teco_state_t teco_state_glob_pattern; diff --git a/src/goto-commands.c b/src/goto-commands.c index 05d495f..6fdaffc 100644 --- a/src/goto-commands.c +++ b/src/goto-commands.c @@ -35,8 +35,8 @@ #include "goto.h" #include "goto-commands.h" -TECO_DECLARE_STATE(teco_state_blockcomment); -TECO_DECLARE_STATE(teco_state_eolcomment); +static teco_state_t teco_state_blockcomment; +static teco_state_t teco_state_eolcomment; /** * In TECO_MODE_PARSE_ONLY_GOTO mode, we remain in parse-only mode @@ -113,7 +113,8 @@ teco_state_label_input(teco_machine_main_t *ctx, gunichar chr, GError **error) } TECO_DEFINE_STATE(teco_state_label, - .style = SCE_SCITECO_LABEL + .style = SCE_SCITECO_LABEL, + .input_cb = (teco_state_input_cb_t)teco_state_label_input ); static teco_state_t * @@ -221,7 +222,8 @@ gboolean teco_state_goto_insert_completion(teco_machine_main_t *ctx, const teco_ */ TECO_DEFINE_STATE_EXPECTSTRING(teco_state_goto, .process_edit_cmd_cb = (teco_state_process_edit_cmd_cb_t)teco_state_goto_process_edit_cmd, - .insert_completion_cb = (teco_state_insert_completion_cb_t)teco_state_goto_insert_completion + .insert_completion_cb = (teco_state_insert_completion_cb_t)teco_state_goto_insert_completion, + .expectstring.done_cb = teco_state_goto_done ); /** @@ -242,28 +244,34 @@ TECO_DEFINE_STATE_EXPECTSTRING(teco_state_goto, ) static teco_state_t * -teco_state_blockcomment_star_input(teco_machine_main_t *ctx, gunichar chr, GError **error) +teco_state_blockcomment_star_input(teco_machine_t *ctx, gunichar chr, GError **error) { return chr == '!' ? &teco_state_start : &teco_state_blockcomment; } -TECO_DEFINE_STATE_COMMENT(teco_state_blockcomment_star); +static TECO_DEFINE_STATE_COMMENT(teco_state_blockcomment_star, + .input_cb = teco_state_blockcomment_star_input +); static teco_state_t * -teco_state_blockcomment_input(teco_machine_main_t *ctx, gunichar chr, GError **error) +teco_state_blockcomment_input(teco_machine_t *ctx, gunichar chr, GError **error) { return chr == '*' ? &teco_state_blockcomment_star : &teco_state_blockcomment; } -TECO_DEFINE_STATE_COMMENT(teco_state_blockcomment); +static TECO_DEFINE_STATE_COMMENT(teco_state_blockcomment, + .input_cb = teco_state_blockcomment_input +); /* * `!!` line comments are inspired by TECO-64. */ static teco_state_t * -teco_state_eolcomment_input(teco_machine_main_t *ctx, gunichar chr, GError **error) +teco_state_eolcomment_input(teco_machine_t *ctx, gunichar chr, GError **error) { return chr == '\n' ? &teco_state_start : &teco_state_eolcomment; } -TECO_DEFINE_STATE_COMMENT(teco_state_eolcomment); +static TECO_DEFINE_STATE_COMMENT(teco_state_eolcomment, + .input_cb = teco_state_eolcomment_input +); diff --git a/src/goto-commands.h b/src/goto-commands.h index 45c68e9..ba60f93 100644 --- a/src/goto-commands.h +++ b/src/goto-commands.h @@ -24,5 +24,5 @@ extern teco_string_t teco_goto_skip_label; extern gssize teco_goto_backup_pc; -TECO_DECLARE_STATE(teco_state_label); -TECO_DECLARE_STATE(teco_state_goto); +extern teco_state_t teco_state_label; +extern teco_state_t teco_state_goto; @@ -388,5 +388,6 @@ TECO_DEFINE_STATE_EXPECTSTRING(teco_state_help, .initial_cb = (teco_state_initial_cb_t)teco_state_help_initial, .process_edit_cmd_cb = (teco_state_process_edit_cmd_cb_t)teco_state_help_process_edit_cmd, .insert_completion_cb = (teco_state_insert_completion_cb_t)teco_state_help_insert_completion, - .expectstring.string_building = FALSE + .expectstring.string_building = FALSE, + .expectstring.done_cb = teco_state_help_done ); @@ -27,4 +27,4 @@ gboolean teco_help_auto_complete(const gchar *topic_name, teco_string_t *insert) * Command states */ -TECO_DECLARE_STATE(teco_state_help); +extern teco_state_t teco_state_help; diff --git a/src/parser.c b/src/parser.c index a5e6e4f..0cf6031 100644 --- a/src/parser.c +++ b/src/parser.c @@ -476,27 +476,24 @@ teco_machine_stringbuilding_append_c(teco_machine_stringbuilding_t *ctx, teco_in return TRUE; } -/* - * FIXME: All teco_state_stringbuilding_* states could be static? - */ static teco_state_t *teco_state_stringbuilding_ctl_input(teco_machine_stringbuilding_t *ctx, gunichar chr, GError **error); -TECO_DECLARE_STATE(teco_state_stringbuilding_ctl); +static teco_state_t teco_state_stringbuilding_ctl; static teco_state_t *teco_state_stringbuilding_escaped_input(teco_machine_stringbuilding_t *ctx, gunichar chr, GError **error); -TECO_DECLARE_STATE(teco_state_stringbuilding_escaped); +static teco_state_t teco_state_stringbuilding_escaped; -TECO_DECLARE_STATE(teco_state_stringbuilding_lower); -TECO_DECLARE_STATE(teco_state_stringbuilding_upper); +static teco_state_t teco_state_stringbuilding_lower; +static teco_state_t teco_state_stringbuilding_upper; -TECO_DECLARE_STATE(teco_state_stringbuilding_ctle); -TECO_DECLARE_STATE(teco_state_stringbuilding_ctle_num); -TECO_DECLARE_STATE(teco_state_stringbuilding_ctle_u); -TECO_DECLARE_STATE(teco_state_stringbuilding_ctle_code); -TECO_DECLARE_STATE(teco_state_stringbuilding_ctle_q); -TECO_DECLARE_STATE(teco_state_stringbuilding_ctle_quote); -TECO_DECLARE_STATE(teco_state_stringbuilding_ctle_n); +static teco_state_t teco_state_stringbuilding_ctle; +static teco_state_t teco_state_stringbuilding_ctle_num; +static teco_state_t teco_state_stringbuilding_ctle_u; +static teco_state_t teco_state_stringbuilding_ctle_code; +static teco_state_t teco_state_stringbuilding_ctle_q; +static teco_state_t teco_state_stringbuilding_ctle_quote; +static teco_state_t teco_state_stringbuilding_ctle_n; static teco_state_t * teco_state_stringbuilding_start_input(teco_machine_stringbuilding_t *ctx, gunichar chr, GError **error) @@ -526,12 +523,13 @@ gboolean teco_state_stringbuilding_start_process_edit_cmd(teco_machine_stringbui gunichar key, GError **error); gboolean teco_state_stringbuilding_insert_completion(teco_machine_stringbuilding_t *ctx, const teco_string_t *str, GError **error); -TECO_DEFINE_STATE(teco_state_stringbuilding_start, - .is_start = TRUE, - .process_edit_cmd_cb = (teco_state_process_edit_cmd_cb_t) - teco_state_stringbuilding_start_process_edit_cmd, - .insert_completion_cb = (teco_state_insert_completion_cb_t) - teco_state_stringbuilding_insert_completion +static TECO_DEFINE_STATE(teco_state_stringbuilding_start, + .is_start = TRUE, + .input_cb = (teco_state_input_cb_t)teco_state_stringbuilding_start_input, + .process_edit_cmd_cb = (teco_state_process_edit_cmd_cb_t) + teco_state_stringbuilding_start_process_edit_cmd, + .insert_completion_cb = (teco_state_insert_completion_cb_t) + teco_state_stringbuilding_insert_completion ); static teco_state_t * @@ -581,7 +579,9 @@ teco_state_stringbuilding_ctl_input(teco_machine_stringbuilding_t *ctx, gunichar return &teco_state_stringbuilding_start; } -TECO_DEFINE_STATE_CASEINSENSITIVE(teco_state_stringbuilding_ctl); +static TECO_DEFINE_STATE_CASEINSENSITIVE(teco_state_stringbuilding_ctl, + .input_cb = (teco_state_input_cb_t)teco_state_stringbuilding_ctl_input, +); static teco_state_t * teco_state_stringbuilding_escaped_input(teco_machine_stringbuilding_t *ctx, gunichar chr, GError **error) @@ -613,7 +613,8 @@ teco_state_stringbuilding_escaped_input(teco_machine_stringbuilding_t *ctx, guni gboolean teco_state_stringbuilding_escaped_process_edit_cmd(teco_machine_stringbuilding_t *ctx, teco_machine_t *parent_ctx, gunichar key, GError **error); -TECO_DEFINE_STATE(teco_state_stringbuilding_escaped, +static TECO_DEFINE_STATE(teco_state_stringbuilding_escaped, + .input_cb = (teco_state_input_cb_t)teco_state_stringbuilding_escaped_input, .process_edit_cmd_cb = (teco_state_process_edit_cmd_cb_t) teco_state_stringbuilding_escaped_process_edit_cmd ); @@ -639,7 +640,9 @@ teco_state_stringbuilding_lower_ctl_input(teco_machine_stringbuilding_t *ctx, gu return &teco_state_stringbuilding_start; } -TECO_DEFINE_STATE_CASEINSENSITIVE(teco_state_stringbuilding_lower_ctl); +static TECO_DEFINE_STATE_CASEINSENSITIVE(teco_state_stringbuilding_lower_ctl, + .input_cb = (teco_state_input_cb_t)teco_state_stringbuilding_lower_ctl_input +); static teco_state_t * teco_state_stringbuilding_lower_input(teco_machine_stringbuilding_t *ctx, gunichar chr, GError **error) @@ -657,7 +660,9 @@ teco_state_stringbuilding_lower_input(teco_machine_stringbuilding_t *ctx, gunich return &teco_state_stringbuilding_start; } -TECO_DEFINE_STATE(teco_state_stringbuilding_lower); +static TECO_DEFINE_STATE(teco_state_stringbuilding_lower, + .input_cb = (teco_state_input_cb_t)teco_state_stringbuilding_lower_input +); static teco_state_t * teco_state_stringbuilding_upper_ctl_input(teco_machine_stringbuilding_t *ctx, gunichar chr, GError **error) @@ -680,7 +685,9 @@ teco_state_stringbuilding_upper_ctl_input(teco_machine_stringbuilding_t *ctx, gu return &teco_state_stringbuilding_start; } -TECO_DEFINE_STATE_CASEINSENSITIVE(teco_state_stringbuilding_upper_ctl); +static TECO_DEFINE_STATE_CASEINSENSITIVE(teco_state_stringbuilding_upper_ctl, + .input_cb = (teco_state_input_cb_t)teco_state_stringbuilding_upper_ctl_input +); static teco_state_t * teco_state_stringbuilding_upper_input(teco_machine_stringbuilding_t *ctx, gunichar chr, GError **error) @@ -698,7 +705,9 @@ teco_state_stringbuilding_upper_input(teco_machine_stringbuilding_t *ctx, gunich return &teco_state_stringbuilding_start; } -TECO_DEFINE_STATE(teco_state_stringbuilding_upper); +static TECO_DEFINE_STATE(teco_state_stringbuilding_upper, + .input_cb = (teco_state_input_cb_t)teco_state_stringbuilding_upper_input +); static teco_state_t * teco_state_stringbuilding_ctle_input(teco_machine_stringbuilding_t *ctx, gunichar chr, GError **error) @@ -731,7 +740,9 @@ teco_state_stringbuilding_ctle_input(teco_machine_stringbuilding_t *ctx, gunicha return next; } -TECO_DEFINE_STATE_CASEINSENSITIVE(teco_state_stringbuilding_ctle); +static TECO_DEFINE_STATE_CASEINSENSITIVE(teco_state_stringbuilding_ctle, + .input_cb = (teco_state_input_cb_t)teco_state_stringbuilding_ctle_input +); /* in cmdline.c */ gboolean teco_state_stringbuilding_qreg_process_edit_cmd(teco_machine_stringbuilding_t *ctx, teco_machine_t *parent_ctx, @@ -782,7 +793,9 @@ teco_state_stringbuilding_ctle_num_input(teco_machine_stringbuilding_t *ctx, gun return &teco_state_stringbuilding_start; } -TECO_DEFINE_STATE_STRINGBUILDING_QREG(teco_state_stringbuilding_ctle_num); +static TECO_DEFINE_STATE_STRINGBUILDING_QREG(teco_state_stringbuilding_ctle_num, + .input_cb = (teco_state_input_cb_t)teco_state_stringbuilding_ctle_num_input +); static teco_state_t * teco_state_stringbuilding_ctle_u_input(teco_machine_stringbuilding_t *ctx, gunichar chr, GError **error) @@ -817,7 +830,9 @@ teco_state_stringbuilding_ctle_u_input(teco_machine_stringbuilding_t *ctx, gunic return &teco_state_stringbuilding_start; } -TECO_DEFINE_STATE_STRINGBUILDING_QREG(teco_state_stringbuilding_ctle_u); +static TECO_DEFINE_STATE_STRINGBUILDING_QREG(teco_state_stringbuilding_ctle_u, + .input_cb = (teco_state_input_cb_t)teco_state_stringbuilding_ctle_u_input +); static teco_state_t * teco_state_stringbuilding_ctle_code_input(teco_machine_stringbuilding_t *ctx, gunichar chr, GError **error) @@ -869,7 +884,9 @@ teco_state_stringbuilding_ctle_code_input(teco_machine_stringbuilding_t *ctx, gu return &teco_state_stringbuilding_ctle_code; } -TECO_DEFINE_STATE(teco_state_stringbuilding_ctle_code); +static TECO_DEFINE_STATE(teco_state_stringbuilding_ctle_code, + .input_cb = (teco_state_input_cb_t)teco_state_stringbuilding_ctle_code_input +); static teco_state_t * teco_state_stringbuilding_ctle_q_input(teco_machine_stringbuilding_t *ctx, gunichar chr, GError **error) @@ -897,7 +914,9 @@ teco_state_stringbuilding_ctle_q_input(teco_machine_stringbuilding_t *ctx, gunic return &teco_state_stringbuilding_start; } -TECO_DEFINE_STATE_STRINGBUILDING_QREG(teco_state_stringbuilding_ctle_q); +static TECO_DEFINE_STATE_STRINGBUILDING_QREG(teco_state_stringbuilding_ctle_q, + .input_cb = (teco_state_input_cb_t)teco_state_stringbuilding_ctle_q_input +); static teco_state_t * teco_state_stringbuilding_ctle_quote_input(teco_machine_stringbuilding_t *ctx, gunichar chr, GError **error) @@ -940,7 +959,9 @@ teco_state_stringbuilding_ctle_quote_input(teco_machine_stringbuilding_t *ctx, g return &teco_state_stringbuilding_start; } -TECO_DEFINE_STATE_STRINGBUILDING_QREG(teco_state_stringbuilding_ctle_quote); +static TECO_DEFINE_STATE_STRINGBUILDING_QREG(teco_state_stringbuilding_ctle_quote, + .input_cb = (teco_state_input_cb_t)teco_state_stringbuilding_ctle_quote_input +); static teco_state_t * teco_state_stringbuilding_ctle_n_input(teco_machine_stringbuilding_t *ctx, gunichar chr, GError **error) @@ -977,7 +998,9 @@ teco_state_stringbuilding_ctle_n_input(teco_machine_stringbuilding_t *ctx, gunic return &teco_state_stringbuilding_start; } -TECO_DEFINE_STATE_STRINGBUILDING_QREG(teco_state_stringbuilding_ctle_n); +static TECO_DEFINE_STATE_STRINGBUILDING_QREG(teco_state_stringbuilding_ctle_n, + .input_cb = (teco_state_input_cb_t)teco_state_stringbuilding_ctle_n_input +); void teco_machine_stringbuilding_init(teco_machine_stringbuilding_t *ctx, gunichar escape_char, diff --git a/src/parser.h b/src/parser.h index 2308925..4ab4d25 100644 --- a/src/parser.h +++ b/src/parser.h @@ -248,15 +248,18 @@ gboolean teco_state_process_edit_cmd(teco_machine_t *ctx, teco_machine_t *parent * @implements teco_state_t * @ingroup states * - * @todo Should we eliminate required callbacks, this could be turned into a - * struct initializer TECO_INIT_STATE() and TECO_DECLARE_STATE() would become pointless. - * This would also ease declaring static states. + * Base class of all states. + * + * Since states are constant, you can append static assertions for required callbacks + * and other conditions. + * You should use TECO_ASSERT_SAFE(), but it won't be checked on all supported compilers. + * You should not put anything in front of the definition, though, so you + * can write `static TECO_DEFINE_STATE(...)`. */ #define TECO_DEFINE_STATE(NAME, ...) \ /** @ingroup states */ \ teco_state_t NAME = { \ .initial_cb = NULL, /* do nothing */ \ - .input_cb = (teco_state_input_cb_t)NAME##_input, /* always required */ \ .refresh_cb = NULL, /* do nothing */ \ .end_of_macro_cb = teco_state_end_of_macro, \ .process_edit_cmd_cb = teco_state_process_edit_cmd, \ @@ -265,11 +268,8 @@ gboolean teco_state_process_edit_cmd(teco_machine_t *ctx, teco_machine_t *parent .keymacro_mask = TECO_KEYMACRO_MASK_DEFAULT, \ .style = SCE_SCITECO_DEFAULT, \ ##__VA_ARGS__ \ - } - -/** @ingroup states */ -#define TECO_DECLARE_STATE(NAME) \ - extern teco_state_t NAME + }; \ + TECO_ASSERT_SAFE(NAME.input_cb != NULL) /* in cmdline.c */ gboolean teco_state_caseinsensitive_process_edit_cmd(teco_machine_t *ctx, teco_machine_t *parent_ctx, gunichar chr, GError **error); @@ -610,18 +610,11 @@ gboolean teco_state_expectstring_insert_completion(teco_machine_main_t *ctx, con * Super-class for states accepting string arguments * Opaquely cares about alternative-escape characters, * string building commands and accumulation into a string - * - * @note Generating the input_cb could be avoided if there were a default - * implementation. */ #define TECO_DEFINE_STATE_EXPECTSTRING(NAME, ...) \ - static teco_state_t * \ - NAME##_input(teco_machine_main_t *ctx, gunichar chr, GError **error) \ - { \ - return teco_state_expectstring_input(ctx, chr, error); \ - } \ TECO_DEFINE_STATE(NAME, \ .initial_cb = (teco_state_initial_cb_t)teco_state_expectstring_initial, \ + .input_cb = (teco_state_input_cb_t)teco_state_expectstring_input, \ .refresh_cb = (teco_state_refresh_cb_t)teco_state_expectstring_refresh, \ .process_edit_cmd_cb = (teco_state_process_edit_cmd_cb_t) \ teco_state_expectstring_process_edit_cmd, \ @@ -631,10 +624,10 @@ gboolean teco_state_expectstring_insert_completion(teco_machine_main_t *ctx, con .style = SCE_SCITECO_STRING, \ .expectstring.string_building = TRUE, \ .expectstring.last = TRUE, \ - .expectstring.process_cb = NULL, /* do nothing */ \ - .expectstring.done_cb = NAME##_done, /* always required */ \ + .expectstring.process_cb = NULL, /* do nothing */ \ ##__VA_ARGS__ \ - ) + ); \ + TECO_ASSERT_SAFE(NAME.expectstring.done_cb != NULL) gboolean teco_state_expectfile_process(teco_machine_main_t *ctx, const teco_string_t *str, gsize new_chars, GError **error); diff --git a/src/qreg-commands.c b/src/qreg-commands.c index 83a45b1..5efb140 100644 --- a/src/qreg-commands.c +++ b/src/qreg-commands.c @@ -91,7 +91,9 @@ teco_state_pushqreg_got_register(teco_machine_main_t *ctx, teco_qreg_t *qreg, * Save Q-Register <q> contents on the global Q-Register push-down * stack. */ -TECO_DEFINE_STATE_EXPECTQREG(teco_state_pushqreg); +TECO_DEFINE_STATE_EXPECTQREG(teco_state_pushqreg, + .expectqreg.got_register_cb = teco_state_pushqreg_got_register +); static teco_state_t * teco_state_popqreg_got_register(teco_machine_main_t *ctx, teco_qreg_t *qreg, @@ -128,7 +130,8 @@ teco_state_popqreg_got_register(teco_machine_main_t *ctx, teco_qreg_t *qreg, * Memory is reclaimed on command-line termination. */ TECO_DEFINE_STATE_EXPECTQREG(teco_state_popqreg, - .expectqreg.type = TECO_QREG_OPTIONAL_INIT + .expectqreg.type = TECO_QREG_OPTIONAL_INIT, + .expectqreg.got_register_cb = teco_state_popqreg_got_register ); static teco_state_t * @@ -142,7 +145,8 @@ teco_state_eqcommand_got_register(teco_machine_main_t *ctx, teco_qreg_t *qreg, } TECO_DEFINE_STATE_EXPECTQREG(teco_state_eqcommand, - .expectqreg.type = TECO_QREG_OPTIONAL_INIT + .expectqreg.type = TECO_QREG_OPTIONAL_INIT, + .expectqreg.got_register_cb = teco_state_eqcommand_got_register ); static teco_state_t * @@ -187,7 +191,9 @@ teco_state_loadqreg_done(teco_machine_main_t *ctx, const teco_string_t *str, GEr * Undefined Q-Registers will be defined. * The command fails if <file> could not be read. */ -TECO_DEFINE_STATE_EXPECTFILE(teco_state_loadqreg); +TECO_DEFINE_STATE_EXPECTFILE(teco_state_loadqreg, + .expectstring.done_cb = teco_state_loadqreg_done +); static teco_state_t * teco_state_epctcommand_got_register(teco_machine_main_t *ctx, teco_qreg_t *qreg, @@ -199,7 +205,9 @@ teco_state_epctcommand_got_register(teco_machine_main_t *ctx, teco_qreg_t *qreg, return &teco_state_saveqreg; } -TECO_DEFINE_STATE_EXPECTQREG(teco_state_epctcommand); +TECO_DEFINE_STATE_EXPECTQREG(teco_state_epctcommand, + .expectqreg.got_register_cb = teco_state_epctcommand_got_register +); static teco_state_t * teco_state_saveqreg_done(teco_machine_main_t *ctx, const teco_string_t *str, GError **error) @@ -231,7 +239,9 @@ teco_state_saveqreg_done(teco_machine_main_t *ctx, const teco_string_t *str, GEr * File names may also be tab-completed and string building * characters are enabled by default. */ -TECO_DEFINE_STATE_EXPECTFILE(teco_state_saveqreg); +TECO_DEFINE_STATE_EXPECTFILE(teco_state_saveqreg, + .expectstring.done_cb = teco_state_saveqreg_done +); static gboolean teco_state_queryqreg_initial(teco_machine_main_t *ctx, GError **error) @@ -346,7 +356,8 @@ teco_state_queryqreg_got_register(teco_machine_main_t *ctx, teco_qreg_t *qreg, * boolean. */ TECO_DEFINE_STATE_EXPECTQREG(teco_state_queryqreg, - .initial_cb = (teco_state_initial_cb_t)teco_state_queryqreg_initial + .initial_cb = (teco_state_initial_cb_t)teco_state_queryqreg_initial, + .expectqreg.got_register_cb = teco_state_queryqreg_got_register ); static teco_state_t * @@ -360,7 +371,8 @@ teco_state_ctlucommand_got_register(teco_machine_main_t *ctx, teco_qreg_t *qreg, } TECO_DEFINE_STATE_EXPECTQREG(teco_state_ctlucommand, - .expectqreg.type = TECO_QREG_OPTIONAL_INIT + .expectqreg.type = TECO_QREG_OPTIONAL_INIT, + .expectqreg.got_register_cb = teco_state_ctlucommand_got_register ); static teco_state_t * @@ -474,7 +486,8 @@ teco_state_setqregstring_nobuilding_done(teco_machine_main_t *ctx, * is desired. */ TECO_DEFINE_STATE_EXPECTSTRING(teco_state_setqregstring_nobuilding, - .expectstring.string_building = FALSE + .expectstring.string_building = FALSE, + .expectstring.done_cb = teco_state_setqregstring_nobuilding_done ); static teco_state_t * @@ -488,7 +501,8 @@ teco_state_eucommand_got_register(teco_machine_main_t *ctx, teco_qreg_t *qreg, } TECO_DEFINE_STATE_EXPECTQREG(teco_state_eucommand, - .expectqreg.type = TECO_QREG_OPTIONAL_INIT + .expectqreg.type = TECO_QREG_OPTIONAL_INIT, + .expectqreg.got_register_cb = teco_state_eucommand_got_register ); static gboolean @@ -511,12 +525,6 @@ teco_state_setqregstring_building_initial(teco_machine_main_t *ctx, GError **err return TRUE; } -static teco_state_t * -teco_state_setqregstring_building_done(teco_machine_main_t *ctx, const teco_string_t *str, GError **error) -{ - return teco_state_setqregstring_nobuilding_done(ctx, str, error); -} - /*$ "EU" "EUq" ":EUq" * [c1,c2,...]EUq[string]$ -- Set or append to Q-Register string with string building characters * [c1,c2,...]:EUq[string]$ @@ -529,7 +537,8 @@ teco_state_setqregstring_building_done(teco_machine_main_t *ctx, const teco_stri */ TECO_DEFINE_STATE_EXPECTSTRING(teco_state_setqregstring_building, .initial_cb = (teco_state_initial_cb_t)teco_state_setqregstring_building_initial, - .expectstring.string_building = TRUE + .expectstring.string_building = TRUE, + .expectstring.done_cb = teco_state_setqregstring_nobuilding_done ); static teco_state_t * @@ -582,7 +591,9 @@ teco_state_getqregstring_got_register(teco_machine_main_t *ctx, teco_qreg_t *qre * * Specifying an undefined <q> yields an error. */ -TECO_DEFINE_STATE_EXPECTQREG(teco_state_getqregstring); +TECO_DEFINE_STATE_EXPECTQREG(teco_state_getqregstring, + .expectqreg.got_register_cb = teco_state_getqregstring_got_register +); static teco_state_t * teco_state_setqreginteger_got_register(teco_machine_main_t *ctx, teco_qreg_t *qreg, @@ -631,7 +642,8 @@ teco_state_setqreginteger_got_register(teco_machine_main_t *ctx, teco_qreg_t *qr * The register is defined if it does not exist. */ TECO_DEFINE_STATE_EXPECTQREG(teco_state_setqreginteger, - .expectqreg.type = TECO_QREG_OPTIONAL_INIT + .expectqreg.type = TECO_QREG_OPTIONAL_INIT, + .expectqreg.got_register_cb = teco_state_setqreginteger_got_register ); static teco_state_t * @@ -665,7 +677,8 @@ teco_state_increaseqreg_got_register(teco_machine_main_t *ctx, teco_qreg_t *qreg * <q> will be defined if it does not exist. */ TECO_DEFINE_STATE_EXPECTQREG(teco_state_increaseqreg, - .expectqreg.type = TECO_QREG_OPTIONAL_INIT + .expectqreg.type = TECO_QREG_OPTIONAL_INIT, + .expectqreg.got_register_cb = teco_state_increaseqreg_got_register ); static teco_state_t * @@ -724,7 +737,9 @@ teco_state_macro_got_register(teco_machine_main_t *ctx, teco_qreg_t *qreg, * (as reported by \fBEE\fP), its contents must be and are checked to be in * valid UTF-8. */ -TECO_DEFINE_STATE_EXPECTQREG(teco_state_macro); +TECO_DEFINE_STATE_EXPECTQREG(teco_state_macro, + .expectqreg.got_register_cb = teco_state_macro_got_register +); static teco_state_t * teco_state_indirect_done(teco_machine_main_t *ctx, const teco_string_t *str, GError **error) @@ -762,7 +777,9 @@ teco_state_indirect_done(teco_machine_main_t *ctx, const teco_string_t *str, GEr * As all \*(ST code, the contents of <file> must be in valid UTF-8 * even if operating in the \(lqdefault ANSI\(rq mode as configured by \fBED\fP. */ -TECO_DEFINE_STATE_EXPECTFILE(teco_state_indirect); +TECO_DEFINE_STATE_EXPECTFILE(teco_state_indirect, + .expectstring.done_cb = teco_state_indirect_done +); static teco_state_t * teco_state_copytoqreg_got_register(teco_machine_main_t *ctx, teco_qreg_t *qreg, @@ -865,5 +882,6 @@ teco_state_copytoqreg_got_register(teco_machine_main_t *ctx, teco_qreg_t *qreg, * Register <q> will be created if it is undefined. */ TECO_DEFINE_STATE_EXPECTQREG(teco_state_copytoqreg, - .expectqreg.type = TECO_QREG_OPTIONAL_INIT + .expectqreg.type = TECO_QREG_OPTIONAL_INIT, + .expectqreg.got_register_cb = teco_state_copytoqreg_got_register ); diff --git a/src/qreg-commands.h b/src/qreg-commands.h index e224797..d0f6990 100644 --- a/src/qreg-commands.h +++ b/src/qreg-commands.h @@ -51,48 +51,44 @@ gboolean teco_state_expectqreg_insert_completion(teco_machine_main_t *ctx, const * Super class for states accepting Q-Register specifications. */ #define TECO_DEFINE_STATE_EXPECTQREG(NAME, ...) \ - static teco_state_t * \ - NAME##_input(teco_machine_main_t *ctx, gunichar chr, GError **error) \ - { \ - return teco_state_expectqreg_input(ctx, chr, error); \ - } \ TECO_DEFINE_STATE(NAME, \ .initial_cb = (teco_state_initial_cb_t)teco_state_expectqreg_initial, \ + .input_cb = (teco_state_input_cb_t)teco_state_expectqreg_input, \ .process_edit_cmd_cb = (teco_state_process_edit_cmd_cb_t) \ teco_state_expectqreg_process_edit_cmd, \ .insert_completion_cb = (teco_state_insert_completion_cb_t) \ teco_state_expectqreg_insert_completion, \ .style = SCE_SCITECO_QREG, \ .expectqreg.type = TECO_QREG_REQUIRED, \ - .expectqreg.got_register_cb = NAME##_got_register, /* always required */ \ ##__VA_ARGS__ \ - ) + ); \ + TECO_ASSERT_SAFE(NAME.expectqreg.got_register_cb != NULL) /* * FIXME: Some of these states are referenced only in qreg-commands.c, * so they should be moved there? */ -TECO_DECLARE_STATE(teco_state_pushqreg); -TECO_DECLARE_STATE(teco_state_popqreg); +extern teco_state_t teco_state_pushqreg; +extern teco_state_t teco_state_popqreg; -TECO_DECLARE_STATE(teco_state_eqcommand); -TECO_DECLARE_STATE(teco_state_loadqreg); +extern teco_state_t teco_state_eqcommand; +extern teco_state_t teco_state_loadqreg; -TECO_DECLARE_STATE(teco_state_epctcommand); -TECO_DECLARE_STATE(teco_state_saveqreg); +extern teco_state_t teco_state_epctcommand; +extern teco_state_t teco_state_saveqreg; -TECO_DECLARE_STATE(teco_state_queryqreg); +extern teco_state_t teco_state_queryqreg; -TECO_DECLARE_STATE(teco_state_ctlucommand); -TECO_DECLARE_STATE(teco_state_setqregstring_nobuilding); -TECO_DECLARE_STATE(teco_state_eucommand); -TECO_DECLARE_STATE(teco_state_setqregstring_building); +extern teco_state_t teco_state_ctlucommand; +extern teco_state_t teco_state_setqregstring_nobuilding; +extern teco_state_t teco_state_eucommand; +extern teco_state_t teco_state_setqregstring_building; -TECO_DECLARE_STATE(teco_state_getqregstring); -TECO_DECLARE_STATE(teco_state_setqreginteger); -TECO_DECLARE_STATE(teco_state_increaseqreg); +extern teco_state_t teco_state_getqregstring; +extern teco_state_t teco_state_setqreginteger; +extern teco_state_t teco_state_increaseqreg; -TECO_DECLARE_STATE(teco_state_macro); -TECO_DECLARE_STATE(teco_state_indirect); +extern teco_state_t teco_state_macro; +extern teco_state_t teco_state_indirect; -TECO_DECLARE_STATE(teco_state_copytoqreg); +extern teco_state_t teco_state_copytoqreg; @@ -1377,15 +1377,12 @@ TECO_DEFINE_UNDO_SCALAR(teco_machine_qregspec_flags_t); #define teco_undo_qregspec_flags(VAR) \ (*teco_undo_object_teco_machine_qregspec_flags_t_push(&(VAR))) -/* - * FIXME: All teco_state_qregspec_* states could be static? - */ -TECO_DECLARE_STATE(teco_state_qregspec_start); -TECO_DECLARE_STATE(teco_state_qregspec_start_global); -TECO_DECLARE_STATE(teco_state_qregspec_caret); -TECO_DECLARE_STATE(teco_state_qregspec_firstchar); -TECO_DECLARE_STATE(teco_state_qregspec_secondchar); -TECO_DECLARE_STATE(teco_state_qregspec_string); +static teco_state_t teco_state_qregspec_start; +static teco_state_t teco_state_qregspec_start_global; +static teco_state_t teco_state_qregspec_caret; +static teco_state_t teco_state_qregspec_firstchar; +static teco_state_t teco_state_qregspec_secondchar; +static teco_state_t teco_state_qregspec_string; static teco_state_t *teco_state_qregspec_start_global_input(teco_machine_qregspec_t *ctx, gunichar chr, GError **error); @@ -1445,8 +1442,9 @@ gboolean teco_state_qregspec_process_edit_cmd(teco_machine_qregspec_t *ctx, teco gboolean teco_state_qregspec_insert_completion(teco_machine_qregspec_t *ctx, const teco_string_t *str, GError **error); -TECO_DEFINE_STATE(teco_state_qregspec_start, +static TECO_DEFINE_STATE(teco_state_qregspec_start, .is_start = TRUE, + .input_cb = (teco_state_input_cb_t)teco_state_qregspec_start_input, .process_edit_cmd_cb = (teco_state_process_edit_cmd_cb_t)teco_state_qregspec_process_edit_cmd, .insert_completion_cb = (teco_state_insert_completion_cb_t)teco_state_qregspec_insert_completion ); @@ -1482,7 +1480,8 @@ teco_state_qregspec_start_global_input(teco_machine_qregspec_t *ctx, gunichar ch * Alternatively, we'd have to introduce a teco_machine_qregspec_t::status attribute. * Or even better, why not use special pointers like ((teco_state_t *)"teco_state_qregspec_done")? */ -TECO_DEFINE_STATE(teco_state_qregspec_start_global, +static TECO_DEFINE_STATE(teco_state_qregspec_start_global, + .input_cb = (teco_state_input_cb_t)teco_state_qregspec_start_global_input, .process_edit_cmd_cb = (teco_state_process_edit_cmd_cb_t)teco_state_qregspec_process_edit_cmd ); @@ -1503,7 +1502,9 @@ teco_state_qregspec_caret_input(teco_machine_qregspec_t *ctx, gunichar chr, GErr return teco_state_qregspec_done(ctx, error); } -TECO_DEFINE_STATE_CASEINSENSITIVE(teco_state_qregspec_caret); +static TECO_DEFINE_STATE_CASEINSENSITIVE(teco_state_qregspec_caret, + .input_cb = (teco_state_input_cb_t)teco_state_qregspec_caret_input +); static teco_state_t * teco_state_qregspec_firstchar_input(teco_machine_qregspec_t *ctx, gunichar chr, GError **error) @@ -1519,7 +1520,8 @@ teco_state_qregspec_firstchar_input(teco_machine_qregspec_t *ctx, gunichar chr, return &teco_state_qregspec_secondchar; } -TECO_DEFINE_STATE(teco_state_qregspec_firstchar, +static TECO_DEFINE_STATE(teco_state_qregspec_firstchar, + .input_cb = (teco_state_input_cb_t)teco_state_qregspec_firstchar_input, .process_edit_cmd_cb = (teco_state_process_edit_cmd_cb_t)teco_state_qregspec_process_edit_cmd ); @@ -1537,7 +1539,8 @@ teco_state_qregspec_secondchar_input(teco_machine_qregspec_t *ctx, gunichar chr, return teco_state_qregspec_done(ctx, error); } -TECO_DEFINE_STATE(teco_state_qregspec_secondchar, +static TECO_DEFINE_STATE(teco_state_qregspec_secondchar, + .input_cb = (teco_state_input_cb_t)teco_state_qregspec_secondchar_input, .process_edit_cmd_cb = (teco_state_process_edit_cmd_cb_t)teco_state_qregspec_process_edit_cmd ); @@ -1587,7 +1590,8 @@ gboolean teco_state_qregspec_string_process_edit_cmd(teco_machine_qregspec_t *ct gboolean teco_state_qregspec_string_insert_completion(teco_machine_qregspec_t *ctx, const teco_string_t *str, GError **error); -TECO_DEFINE_STATE(teco_state_qregspec_string, +static TECO_DEFINE_STATE(teco_state_qregspec_string, + .input_cb = (teco_state_input_cb_t)teco_state_qregspec_string_input, .process_edit_cmd_cb = (teco_state_process_edit_cmd_cb_t)teco_state_qregspec_string_process_edit_cmd, .insert_completion_cb = (teco_state_insert_completion_cb_t)teco_state_qregspec_string_insert_completion ); @@ -639,7 +639,8 @@ teco_state_edit_file_done(teco_machine_main_t *ctx, const teco_string_t *str, GE */ TECO_DEFINE_STATE_EXPECTGLOB(teco_state_edit_file, .initial_cb = (teco_state_initial_cb_t)teco_state_edit_file_initial, - .expectstring.process_cb = teco_state_edit_file_process + .expectstring.process_cb = teco_state_edit_file_process, + .expectstring.done_cb = teco_state_edit_file_done ); static teco_state_t * @@ -714,7 +715,9 @@ teco_state_save_file_done(teco_machine_main_t *ctx, const teco_string_t *str, GE * File names may also be tab-completed and string building * characters are enabled by default. */ -TECO_DEFINE_STATE_EXPECTFILE(teco_state_save_file); +TECO_DEFINE_STATE_EXPECTFILE(teco_state_save_file, + .expectstring.done_cb = teco_state_save_file_done +); static teco_state_t * teco_state_read_file_done(teco_machine_main_t *ctx, const teco_string_t *str, GError **error) @@ -748,7 +751,9 @@ teco_state_read_file_done(teco_machine_main_t *ctx, const teco_string_t *str, GE /* * NOTE: Video TECO allows glob patterns as an argument. */ -TECO_DEFINE_STATE_EXPECTFILE(teco_state_read_file); +TECO_DEFINE_STATE_EXPECTFILE(teco_state_read_file, + .expectstring.done_cb = teco_state_read_file_done +); /*$ "EF" ":EF" close * [n]EF -- Remove buffer from ring @@ -114,9 +114,9 @@ void teco_ring_cleanup(void); * Command states */ -TECO_DECLARE_STATE(teco_state_edit_file); -TECO_DECLARE_STATE(teco_state_save_file); -TECO_DECLARE_STATE(teco_state_read_file); +extern teco_state_t teco_state_edit_file; +extern teco_state_t teco_state_save_file; +extern teco_state_t teco_state_read_file; void teco_state_ecommand_close(teco_machine_main_t *ctx, GError **error); diff --git a/src/sciteco.h b/src/sciteco.h index 388d6c4..2e6ced2 100644 --- a/src/sciteco.h +++ b/src/sciteco.h @@ -117,6 +117,16 @@ extern volatile sig_atomic_t teco_interrupted; */ G_DEFINE_AUTOPTR_CLEANUP_FUNC(FILE, fclose); +/** + * A "safe" compile-time assertion, which also passes if the expression is not constant. + * + * Can be useful since different compilers have different ideas about what's a constant expression. + * In particular GCC does not treat `static const` objects as constant (in the way it qualifies + * for _Static_assert()), while constexpr is only available since C23. + */ +#define TECO_ASSERT_SAFE(EXPR) \ + G_STATIC_ASSERT(!__builtin_constant_p(EXPR) || (EXPR)) + /* * BEWARE DRAGONS! */ diff --git a/src/search.c b/src/search.c index 0875a9a..2a39b59 100644 --- a/src/search.c +++ b/src/search.c @@ -882,7 +882,6 @@ teco_state_search_done(teco_machine_main_t *ctx, const teco_string_t *str, GErro TECO_DEFINE_STATE_EXPECTSTRING(NAME, \ .initial_cb = (teco_state_initial_cb_t)teco_state_search_initial, \ .expectstring.process_cb = teco_state_search_process, \ - .expectstring.done_cb = NAME##_done, \ ##__VA_ARGS__ \ ) @@ -956,7 +955,9 @@ teco_state_search_done(teco_machine_main_t *ctx, const teco_string_t *str, GErro * Changing the <pattern> results in the search being reperformed * from the beginning. */ -TECO_DEFINE_STATE_SEARCH(teco_state_search); +TECO_DEFINE_STATE_SEARCH(teco_state_search, + .expectstring.done_cb = teco_state_search_done +); static gboolean teco_state_search_all_initial(teco_machine_main_t *ctx, GError **error) @@ -1074,7 +1075,8 @@ teco_state_search_all_done(teco_machine_main_t *ctx, const teco_string_t *str, G * This is probably not very useful in practice, so it's not documented. */ TECO_DEFINE_STATE_SEARCH(teco_state_search_all, - .initial_cb = (teco_state_initial_cb_t)teco_state_search_all_initial + .initial_cb = (teco_state_initial_cb_t)teco_state_search_all_initial, + .expectstring.done_cb = teco_state_search_all_done ); static teco_state_t * @@ -1157,7 +1159,9 @@ teco_state_search_kill_done(teco_machine_main_t *ctx, const teco_string_t *str, /* * ::FK is possible but doesn't make much sense, so it's undocumented. */ -TECO_DEFINE_STATE_SEARCH(teco_state_search_kill); +TECO_DEFINE_STATE_SEARCH(teco_state_search_kill, + .expectstring.done_cb = teco_state_search_kill_done +); static teco_state_t * teco_state_search_delete_done(teco_machine_main_t *ctx, const teco_string_t *str, GError **error) @@ -1200,7 +1204,9 @@ teco_state_search_delete_done(teco_machine_main_t *ctx, const teco_string_t *str * Searches for <pattern> just like the regular search command * (\fBS\fP) but when found deletes the entire occurrence. */ -TECO_DEFINE_STATE_SEARCH(teco_state_search_delete); +TECO_DEFINE_STATE_SEARCH(teco_state_search_delete, + .expectstring.done_cb = teco_state_search_delete_done +); static gboolean teco_state_replace_insert_initial(teco_machine_main_t *ctx, GError **error) @@ -1226,10 +1232,7 @@ teco_state_replace_insert_initial(teco_machine_main_t *ctx, GError **error) return TRUE; } -/* - * FIXME: Could be static - */ -TECO_DEFINE_STATE_INSERT(teco_state_replace_insert, +static TECO_DEFINE_STATE_INSERT(teco_state_replace_insert, .initial_cb = (teco_state_initial_cb_t)teco_state_replace_insert_initial ); @@ -1239,10 +1242,9 @@ teco_state_replace_ignore_done(teco_machine_main_t *ctx, const teco_string_t *st return &teco_state_start; } -/* - * FIXME: Could be static - */ -TECO_DEFINE_STATE_EXPECTSTRING(teco_state_replace_ignore); +static TECO_DEFINE_STATE_EXPECTSTRING(teco_state_replace_ignore, + .expectstring.done_cb = teco_state_replace_ignore_done +); static teco_state_t * teco_state_replace_done(teco_machine_main_t *ctx, const teco_string_t *str, GError **error) @@ -1285,19 +1287,12 @@ teco_state_replace_done(teco_machine_main_t *ctx, const teco_string_t *str, GErr * immediately and interactively. */ TECO_DEFINE_STATE_SEARCH(teco_state_replace, - .expectstring.last = FALSE + .expectstring.last = FALSE, + .expectstring.done_cb = teco_state_replace_done ); -/* - * FIXME: TECO_DEFINE_STATE_INSERT() already defines a done_cb(), - * so we had to name this differently. - * Perhaps it simply shouldn't define it. - * Even better, we should perhaps avoid generating "required" callback - * names (e.g. in TECO_DEFINE_STATE_EXPECTSTRING()) as it does more harm - * than it helps and only spreads confusion. - */ static teco_state_t * -teco_state_replace_default_insert_done_overwrite(teco_machine_main_t *ctx, const teco_string_t *str, GError **error) +teco_state_replace_default_insert_done(teco_machine_main_t *ctx, const teco_string_t *str, GError **error) { if (ctx->flags.mode > TECO_MODE_NORMAL) return &teco_state_start; @@ -1323,12 +1318,9 @@ teco_state_replace_default_insert_done_overwrite(teco_machine_main_t *ctx, const return &teco_state_start; } -/* - * FIXME: Could be static - */ -TECO_DEFINE_STATE_INSERT(teco_state_replace_default_insert, +static TECO_DEFINE_STATE_INSERT(teco_state_replace_default_insert, .initial_cb = (teco_state_initial_cb_t)teco_state_replace_insert_initial, - .expectstring.done_cb = teco_state_replace_default_insert_done_overwrite + .expectstring.done_cb = teco_state_replace_default_insert_done ); static teco_state_t * @@ -1349,10 +1341,9 @@ teco_state_replace_default_ignore_done(teco_machine_main_t *ctx, const teco_stri return &teco_state_start; } -/* - * FIXME: Could be static - */ -TECO_DEFINE_STATE_EXPECTSTRING(teco_state_replace_default_ignore); +static TECO_DEFINE_STATE_EXPECTSTRING(teco_state_replace_default_ignore, + .expectstring.done_cb = teco_state_replace_default_ignore_done +); static teco_state_t * teco_state_replace_default_done(teco_machine_main_t *ctx, const teco_string_t *str, GError **error) @@ -1394,7 +1385,8 @@ teco_state_replace_default_done(teco_machine_main_t *ctx, const teco_string_t *s * register is implied instead. */ TECO_DEFINE_STATE_SEARCH(teco_state_replace_default, - .expectstring.last = FALSE + .expectstring.last = FALSE, + .expectstring.done_cb = teco_state_replace_default_done ); static teco_state_t * @@ -1437,6 +1429,7 @@ teco_state_replace_default_all_done(teco_machine_main_t *ctx, const teco_string_ * <to>. */ TECO_DEFINE_STATE_SEARCH(teco_state_replace_default_all, + .initial_cb = (teco_state_initial_cb_t)teco_state_search_all_initial, .expectstring.last = FALSE, - .initial_cb = (teco_state_initial_cb_t)teco_state_search_all_initial + .expectstring.done_cb = teco_state_replace_default_all_done ); diff --git a/src/search.h b/src/search.h index 222ca6c..8c93f9c 100644 --- a/src/search.h +++ b/src/search.h @@ -22,10 +22,10 @@ void teco_state_control_search_mode(teco_machine_main_t *ctx, GError **error); -TECO_DECLARE_STATE(teco_state_search); -TECO_DECLARE_STATE(teco_state_search_all); -TECO_DECLARE_STATE(teco_state_search_kill); -TECO_DECLARE_STATE(teco_state_search_delete); -TECO_DECLARE_STATE(teco_state_replace); -TECO_DECLARE_STATE(teco_state_replace_default); -TECO_DECLARE_STATE(teco_state_replace_default_all); +extern teco_state_t teco_state_search; +extern teco_state_t teco_state_search_all; +extern teco_state_t teco_state_search_kill; +extern teco_state_t teco_state_search_delete; +extern teco_state_t teco_state_replace; +extern teco_state_t teco_state_replace_default; +extern teco_state_t teco_state_replace_default_all; diff --git a/src/spawn.c b/src/spawn.c index 73f389e..6745b4f 100644 --- a/src/spawn.c +++ b/src/spawn.c @@ -605,7 +605,8 @@ gboolean teco_state_execute_process_edit_cmd(teco_machine_main_t *ctx, teco_mach */ TECO_DEFINE_STATE_EXPECTSTRING(teco_state_execute, .initial_cb = (teco_state_initial_cb_t)teco_state_execute_initial, - .process_edit_cmd_cb = (teco_state_process_edit_cmd_cb_t)teco_state_execute_process_edit_cmd + .process_edit_cmd_cb = (teco_state_process_edit_cmd_cb_t)teco_state_execute_process_edit_cmd, + .expectstring.done_cb = teco_state_execute_done ); static teco_state_t * @@ -647,7 +648,8 @@ teco_state_egcommand_got_register(teco_machine_main_t *ctx, teco_qreg_t *qreg, * The register <q> is defined if it does not already exist. */ TECO_DEFINE_STATE_EXPECTQREG(teco_state_egcommand, - .expectqreg.type = TECO_QREG_OPTIONAL_INIT + .expectqreg.type = TECO_QREG_OPTIONAL_INIT, + .expectqreg.got_register_cb = teco_state_egcommand_got_register ); /* diff --git a/src/spawn.h b/src/spawn.h index ef210e9..f1c087b 100644 --- a/src/spawn.h +++ b/src/spawn.h @@ -18,5 +18,5 @@ #include "parser.h" -TECO_DECLARE_STATE(teco_state_execute); -TECO_DECLARE_STATE(teco_state_egcommand); +extern teco_state_t teco_state_execute; +extern teco_state_t teco_state_egcommand; diff --git a/src/stdio-commands.c b/src/stdio-commands.c index 565f442..bd28049 100644 --- a/src/stdio-commands.c +++ b/src/stdio-commands.c @@ -118,7 +118,7 @@ teco_print(teco_machine_main_t *ctx, guint radix, GError **error) * then octal and finally in hexadecimal. * This won't happen e.g. in a loop that is closed on the command-line. */ -TECO_DECLARE_STATE(teco_state_print_octal); +static teco_state_t teco_state_print_octal; static gboolean teco_state_print_decimal_initial(teco_machine_main_t *ctx, GError **error) @@ -168,6 +168,7 @@ teco_state_print_decimal_end_of_macro(teco_machine_main_t *ctx, GError **error) TECO_DEFINE_STATE_START(teco_state_print_decimal, .initial_cb = (teco_state_initial_cb_t)teco_state_print_decimal_initial, + .input_cb = (teco_state_input_cb_t)teco_state_print_decimal_input, .end_of_macro_cb = (teco_state_end_of_macro_cb_t) teco_state_print_decimal_end_of_macro ); @@ -224,8 +225,9 @@ teco_state_print_octal_end_of_macro(teco_machine_main_t *ctx, GError **error) return TRUE; } -TECO_DEFINE_STATE_START(teco_state_print_octal, +static TECO_DEFINE_STATE_START(teco_state_print_octal, .initial_cb = (teco_state_initial_cb_t)teco_state_print_octal_initial, + .input_cb = (teco_state_input_cb_t)teco_state_print_octal_input, .end_of_macro_cb = (teco_state_end_of_macro_cb_t) teco_state_print_octal_end_of_macro ); @@ -282,7 +284,8 @@ teco_state_print_string_done(teco_machine_main_t *ctx, const teco_string_t *str, * ^EUq, ^E<...> and case folding. */ TECO_DEFINE_STATE_EXPECTSTRING(teco_state_print_string, - .initial_cb = (teco_state_initial_cb_t)teco_state_print_string_initial + .initial_cb = (teco_state_initial_cb_t)teco_state_print_string_initial, + .expectstring.done_cb = teco_state_print_string_done ); /*$ T type typeout diff --git a/src/stdio-commands.h b/src/stdio-commands.h index 985d1ac..fd973dc 100644 --- a/src/stdio-commands.h +++ b/src/stdio-commands.h @@ -26,5 +26,5 @@ void teco_state_control_typeout(teco_machine_main_t *ctx, GError **error); /* * Command states */ -TECO_DECLARE_STATE(teco_state_print_decimal); -TECO_DECLARE_STATE(teco_state_print_string); +extern teco_state_t teco_state_print_decimal; +extern teco_state_t teco_state_print_string; diff --git a/src/symbols.c b/src/symbols.c index 9cf1c35..caae09a 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -174,10 +174,7 @@ teco_scintilla_ssm(unsigned int iMessage, uptr_t wParam, sptr_t lParam) iMessage, wParam, lParam); } -/* - * FIXME: This state could be static. - */ -TECO_DECLARE_STATE(teco_state_scintilla_lparam); +static teco_state_t teco_state_scintilla_lparam; static gboolean teco_scintilla_parse_symbols(teco_machine_scintilla_t *scintilla, const teco_string_t *str, GError **error) @@ -355,7 +352,8 @@ gboolean teco_state_scintilla_symbols_insert_completion(teco_machine_main_t *ctx TECO_DEFINE_STATE_EXPECTSTRING(teco_state_scintilla_symbols, .process_edit_cmd_cb = (teco_state_process_edit_cmd_cb_t)teco_state_scintilla_symbols_process_edit_cmd, .insert_completion_cb = (teco_state_insert_completion_cb_t)teco_state_scintilla_symbols_insert_completion, - .expectstring.last = FALSE + .expectstring.last = FALSE, + .expectstring.done_cb = teco_state_scintilla_symbols_done ); #ifdef HAVE_LEXILLA @@ -512,4 +510,6 @@ teco_state_scintilla_lparam_done(teco_machine_main_t *ctx, const teco_string_t * return &teco_state_start; } -TECO_DEFINE_STATE_EXPECTSTRING(teco_state_scintilla_lparam); +static TECO_DEFINE_STATE_EXPECTSTRING(teco_state_scintilla_lparam, + .expectstring.done_cb = teco_state_scintilla_lparam_done +); diff --git a/src/symbols.h b/src/symbols.h index 1d0af12..885479d 100644 --- a/src/symbols.h +++ b/src/symbols.h @@ -61,4 +61,4 @@ extern teco_symbol_list_t teco_symbol_list_scilexer; * Command states */ -TECO_DECLARE_STATE(teco_state_scintilla_symbols); +extern teco_state_t teco_state_scintilla_symbols; |
