aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/cmdline.c3
-rw-r--r--src/cmdline.h2
-rw-r--r--src/core-commands.c39
-rw-r--r--src/core-commands.h33
-rw-r--r--src/glob.c12
-rw-r--r--src/glob.h2
-rw-r--r--src/goto-commands.c28
-rw-r--r--src/goto-commands.h4
-rw-r--r--src/help.c3
-rw-r--r--src/help.h2
-rw-r--r--src/parser.c89
-rw-r--r--src/parser.h33
-rw-r--r--src/qreg-commands.c64
-rw-r--r--src/qreg-commands.h44
-rw-r--r--src/qreg.c34
-rw-r--r--src/ring.c11
-rw-r--r--src/ring.h6
-rw-r--r--src/sciteco.h10
-rw-r--r--src/search.c61
-rw-r--r--src/search.h14
-rw-r--r--src/spawn.c6
-rw-r--r--src/spawn.h4
-rw-r--r--src/stdio-commands.c9
-rw-r--r--src/stdio-commands.h4
-rw-r--r--src/symbols.c12
-rw-r--r--src/symbols.h2
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;
diff --git a/src/glob.c b/src/glob.c
index 9621f1a..d2bf713 100644
--- a/src/glob.c
+++ b/src/glob.c
@@ -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
+);
diff --git a/src/glob.h b/src/glob.h
index d11fbce..af52060 100644
--- a/src/glob.h
+++ b/src/glob.h
@@ -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;
diff --git a/src/help.c b/src/help.c
index 0bbbc54..74b9ecb 100644
--- a/src/help.c
+++ b/src/help.c
@@ -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
);
diff --git a/src/help.h b/src/help.h
index 3148e01..91a0368 100644
--- a/src/help.h
+++ b/src/help.h
@@ -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;
diff --git a/src/qreg.c b/src/qreg.c
index 8fca9e2..0ca463a 100644
--- a/src/qreg.c
+++ b/src/qreg.c
@@ -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
);
diff --git a/src/ring.c b/src/ring.c
index 22db7ce..926ee72 100644
--- a/src/ring.c
+++ b/src/ring.c
@@ -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
diff --git a/src/ring.h b/src/ring.h
index e6b0658..8b8beaa 100644
--- a/src/ring.h
+++ b/src/ring.h
@@ -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;