diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2025-07-27 18:14:35 +0300 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2025-07-27 18:14:35 +0300 |
commit | e94dce1f9770abde689314fb993a23800e2bcc9f (patch) | |
tree | 8560e117a799b6b48b9408c9cd9cc775663351af /src/qreg-commands.c | |
parent | 0ea082b74414696a7800455a437656fca2886f6d (diff) | |
download | sciteco-e94dce1f9770abde689314fb993a23800e2bcc9f.tar.gz |
fixed a,b,c^Uq...$: The arguments where written in the wrong (reverse) order
* When writing UTF-8, we must first peek in reverse order since we can
only write from left to right.
* When writing in raw ANSI, we can immediately pop the values from the stack
but must write in reverse.
Diffstat (limited to 'src/qreg-commands.c')
-rw-r--r-- | src/qreg-commands.c | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/src/qreg-commands.c b/src/qreg-commands.c index bec2ca8..83a45b1 100644 --- a/src/qreg-commands.c +++ b/src/qreg-commands.c @@ -387,39 +387,46 @@ teco_state_setqregstring_nobuilding_done(teco_machine_main_t *ctx, return NULL; g_autofree gchar *buffer = NULL; + const gchar *start; gsize len = 0; if (codepage == SC_CP_UTF8) { - /* the glib docs wrongly claim that one character can take 6 bytes */ - buffer = g_malloc(4*args); + /* 4 bytes should be enough for UTF-8, but we better follow the documentation */ + start = buffer = g_malloc(args*6); + for (gint i = args; i > 0; i--) { - teco_int_t v = teco_expressions_pop_num(0); - if (v < 0 || !g_unichar_validate(v)) { + teco_int_t chr = teco_expressions_peek_num(i-1); + if (chr < 0 || !g_unichar_validate(chr)) { teco_error_codepoint_set(error, "^U"); return NULL; } - len += g_unichar_to_utf8(v, buffer+len); + len += g_unichar_to_utf8(chr, buffer+len); } + /* we pop only now since we had to peek in reverse order */ + for (gint i = 0; i < args; i++) + teco_expressions_pop_num(0); } else { buffer = g_malloc(args); - for (gint i = args; i > 0; i--) { - teco_int_t v = teco_expressions_pop_num(0); - if (v < 0 || v > 0xFF) { + + for (gint i = 0; i < args; i++) { + teco_int_t chr = teco_expressions_pop_num(0); + if (chr < 0 || chr > 0xFF) { teco_error_codepoint_set(error, "^U"); return NULL; } - buffer[len++] = v; + buffer[args-(++len)] = chr; } + start = buffer+args-len; } if (colon_modified) { /* append to register */ - if (!qreg->vtable->append_string(qreg, buffer, len, error)) + if (!qreg->vtable->append_string(qreg, start, len, error)) return NULL; } else { /* set register */ if (!qreg->vtable->undo_set_string(qreg, error) || - !qreg->vtable->set_string(qreg, buffer, len, + !qreg->vtable->set_string(qreg, start, len, codepage, error)) return NULL; } |