diff options
| author | Robin Haberkorn <rhaberkorn@fmsbw.de> | 2026-06-29 19:20:55 +0200 |
|---|---|---|
| committer | Robin Haberkorn <rhaberkorn@fmsbw.de> | 2026-06-29 19:20:55 +0200 |
| commit | 49587788101dce76111a8b16dfed0889c26b0e61 (patch) | |
| tree | 0d80d8a78efb514a47a25828880ada78a1143438 /src/search.c | |
| parent | 8601ccfb905a5cc6fe10f7d81a491155f9236f35 (diff) | |
regular expression matching can now be reliably interrupted using CTRL+CHEADmaster-fmsbw-cimaster
* The previous checks for interruptions only helped in a few corner cases
like for very high search-repeat counts or during backwards searches across
the entire buffer.
* But even with terex' more predictable runtime properties
a single regex execution can hang quite a long time.
E.g. `S^EM^X$` on a huge buffer or even more so with backreferences as in
`S^~(.*)\1$`.
* We now use the new tere_set_is_interrupted_cb() to register
teco_interface_is_interrupted(). Types should be compatible as long
as gboolean resolves to int.
* It's no longer necessary to manually check for teco_interface_is_interrupted()
since tere_exec() now returns REG_EINTR in case the callback returned TRUE
in which case it's handled by teco_error_regex_set().
Diffstat (limited to 'src/search.c')
| -rw-r--r-- | src/search.c | 23 |
1 files changed, 7 insertions, 16 deletions
diff --git a/src/search.c b/src/search.c index 491ddbb..1ab925c 100644 --- a/src/search.c +++ b/src/search.c @@ -708,14 +708,6 @@ teco_do_search_forward(regex_t *re, gsize from, gsize to, gint *count, GError ** 1+re->re_nsub, info, eflags)) == REG_OKAY && --(*count)) { buffer += info[0].rm_eo; from += info[0].rm_eo; - - /* - * FIXME: A single pathological match could already be excessively slow. - */ - if (G_UNLIKELY(teco_interface_is_interrupted())) { - teco_error_interrupted_set(error); - return FALSE; - } } if (rc == REG_OKAY) { @@ -810,14 +802,6 @@ teco_do_search_backwards(regex_t *re, gsize from, gsize to, gint *count, GError gint rc; for (;;) { - /* - * FIXME: A single pathological match could already be excessively slow. - */ - if (G_UNLIKELY(teco_interface_is_interrupted())) { - teco_error_interrupted_set(error); - return FALSE; - } - rc = tere_exec(re, (const chr *)buffer+from_block+offset, to_block-from_block-offset, &details, 1+re->re_nsub, info, eflags); if (rc != REG_OKAY) @@ -1000,6 +984,13 @@ teco_state_search_process(teco_machine_main_t *ctx, teco_string_t str, gsize new if (rc != REG_OKAY) goto failure; + /* + * Check for interruptions during matching since they can be quite slow + * especially when matching with regular expressions and backreferences + * (e.g. @S/^~(.*)\1/). + */ + tere_set_is_interrupted_cb(&re, teco_interface_is_interrupted); + if (!teco_qreg_current && teco_ring_current != teco_search_parameters.from_buffer) { teco_ring_undo_edit(); |
