aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/core-commands.c30
-rw-r--r--src/parser.h10
-rw-r--r--src/stdio-commands.c4
3 files changed, 24 insertions, 20 deletions
diff --git a/src/core-commands.c b/src/core-commands.c
index d01cbb9..d850c14 100644
--- a/src/core-commands.c
+++ b/src/core-commands.c
@@ -914,10 +914,8 @@ teco_state_start_input(teco_machine_main_t *ctx, gunichar chr, GError **error)
/*
* <CTRL/x> commands implemented in teco_state_control
*/
- if (TECO_IS_CTL(chr)) {
- teco_state_t *next = teco_state_control_input(ctx, TECO_CTL_ECHO(chr), error);
- TECO_RETURN(ctx, next, error);
- }
+ if (TECO_IS_CTL(chr))
+ TECO_TAIL return teco_state_control_input(ctx, TECO_CTL_ECHO(chr), error);
}
teco_state_t *next = teco_machine_main_transition_input(ctx, transitions, G_N_ELEMENTS(transitions),
@@ -1828,7 +1826,7 @@ TECO_DEFINE_STATE(teco_state_ascii,
* at the expense of yet another parser state.
*/
static teco_state_t *
-teco_return(teco_machine_main_t *ctx, GError **error)
+teco_throw_return(teco_machine_main_t *ctx, GError **error)
{
g_assert(ctx->flags.mode == TECO_MODE_NORMAL);
@@ -1871,9 +1869,11 @@ teco_return(teco_machine_main_t *ctx, GError **error)
static teco_state_t *
teco_state_escape_input(teco_machine_main_t *ctx, gunichar chr, GError **error)
{
- if (chr == '\e' || chr == '$')
- return ctx->flags.mode > TECO_MODE_NORMAL
- ? &teco_state_start : teco_return(ctx, error);
+ if (chr == '\e' || chr == '$') {
+ if (ctx->flags.mode > TECO_MODE_NORMAL)
+ TECO_RETURN(ctx, &teco_state_start, error);
+ return teco_throw_return(ctx, error);
+ }
/*
* Alternatives: ^[, <CTRL/[>, <ESC>, $ (dollar)
@@ -1900,7 +1900,7 @@ teco_state_escape_input(teco_machine_main_t *ctx, gunichar chr, GError **error)
if (ctx->flags.mode == TECO_MODE_NORMAL &&
!teco_expressions_discard_args(error))
return NULL;
- return teco_state_start_input(ctx, chr, error);
+ TECO_TAIL return teco_state_start_input(ctx, chr, error);
}
static gboolean
@@ -1940,12 +1940,13 @@ static teco_state_t *
teco_state_ctlc_input(teco_machine_main_t *ctx, gunichar chr, GError **error)
{
switch (chr) {
- case TECO_CTL_KEY('C'): return teco_state_ctlc_control_input(ctx, 'C', error);
+ case TECO_CTL_KEY('C'): TECO_TAIL return teco_state_ctlc_control_input(ctx, 'C', error);
case '^': TECO_RETURN(ctx, &teco_state_ctlc_control, error);
}
- return ctx->flags.mode > TECO_MODE_NORMAL
- ? teco_state_start_input(ctx, chr, error) : teco_return(ctx, error);
+ if (ctx->flags.mode > TECO_MODE_NORMAL)
+ TECO_TAIL return teco_state_start_input(ctx, chr, error);
+ return teco_throw_return(ctx, error);
}
static gboolean
@@ -2009,8 +2010,9 @@ teco_state_ctlc_control_input(teco_machine_main_t *ctx, gunichar chr, GError **e
return NULL;
}
- return ctx->flags.mode > TECO_MODE_NORMAL
- ? teco_state_control_input(ctx, chr, error) : teco_return(ctx, error);
+ if (ctx->flags.mode > TECO_MODE_NORMAL)
+ TECO_TAIL return teco_state_control_input(ctx, chr, error);
+ return teco_throw_return(ctx, error);
}
/*
diff --git a/src/parser.h b/src/parser.h
index 75a3432..0441a9c 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -557,6 +557,8 @@ gboolean teco_machine_main_step(teco_machine_main_t *ctx,
#if __has_attribute(musttail)
+#define TECO_TAIL __attribute__((musttail))
+
/**
* Transition from a teco_machine_main input_cb() to another state.
*
@@ -608,14 +610,14 @@ gboolean teco_machine_main_step(teco_machine_main_t *ctx,
\
/* the caller's signature will not line up exactly with input_cb */ \
typedef teco_state_t *(*caller_t)(teco_machine_main_t *, gunichar, GError **); \
- __attribute__((musttail)) return ((caller_t)__state->input_cb)(__ctx, chr, __error); \
+ TECO_TAIL return ((caller_t)__state->input_cb)(__ctx, chr, __error); \
} G_STMT_END
#else /* __has_attribute(musttail) */
-/*
- * This will effectively return into the teco_machine_main_step() loop.
- */
+/* leave it to the optimizer (may or may not tail call) */
+#define TECO_TAIL
+/* this will effectively return into the teco_machine_main_step() loop */
#define TECO_RETURN(CTX, STATE, ERROR) return (STATE)
#endif /* !__has_attribute(musttail) */
diff --git a/src/stdio-commands.c b/src/stdio-commands.c
index 94da3c7..52f1e3f 100644
--- a/src/stdio-commands.c
+++ b/src/stdio-commands.c
@@ -146,7 +146,7 @@ teco_state_print_decimal_input(teco_machine_main_t *ctx, gunichar chr, GError **
return NULL;
teco_expressions_pop_num(0);
}
- return teco_state_start_input(ctx, chr, error);
+ TECO_TAIL return teco_state_start_input(ctx, chr, error);
}
/*
@@ -205,7 +205,7 @@ teco_state_print_octal_input(teco_machine_main_t *ctx, gunichar chr, GError **er
return NULL;
teco_expressions_pop_num(0);
}
- return teco_state_start_input(ctx, chr, error);
+ TECO_TAIL return teco_state_start_input(ctx, chr, error);
}
/*