aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/qreg-commands.c
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2024-08-30 04:15:36 +0200
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2024-09-09 18:22:21 +0200
commit7507ad3e1816f3bc9004dceb39bb303804287438 (patch)
tree3c4b2746b56a0538564dbf0416745012b51228fa /src/qreg-commands.c
parent90bad24f96deeaaa2255f0ad89ece21d5397b78b (diff)
downloadsciteco-7507ad3e1816f3bc9004dceb39bb303804287438.tar.gz
Unicode support for the Q-Register commands (refs #5)
* this required adding several Q-Register vtable methods * it should still be investigated whether the repeated calling of SCI_ALLOCATELINECHARACTERINDEX causes any overhead.
Diffstat (limited to 'src/qreg-commands.c')
-rw-r--r--src/qreg-commands.c47
1 files changed, 32 insertions, 15 deletions
diff --git a/src/qreg-commands.c b/src/qreg-commands.c
index 34f3164..089f2a5 100644
--- a/src/qreg-commands.c
+++ b/src/qreg-commands.c
@@ -259,9 +259,9 @@ teco_state_queryqreg_got_register(teco_machine_main_t *ctx, teco_qreg_t *qreg,
if (teco_machine_main_eval_colon(ctx)) {
/* Query Q-Register's existence or string size */
if (qreg) {
- gsize len;
-
- if (!qreg->vtable->get_string(qreg, NULL, &len, error))
+ /* get_string() would return the size in bytes */
+ teco_int_t len = qreg->vtable->get_length(qreg, error);
+ if (len < 0)
return NULL;
teco_expressions_push(len);
} else {
@@ -281,10 +281,9 @@ teco_state_queryqreg_got_register(teco_machine_main_t *ctx, teco_qreg_t *qreg,
return NULL;
}
- gint c = qreg->vtable->get_character(qreg, pos, error);
- if (c < 0)
+ teco_int_t c;
+ if (!qreg->vtable->get_character(qreg, pos, &c, error))
return NULL;
-
teco_expressions_push(c);
} else {
/* Query integer */
@@ -311,6 +310,8 @@ teco_state_queryqreg_got_register(teco_machine_main_t *ctx, teco_qreg_t *qreg,
* Positions are handled like buffer positions \(em they
* begin at 0 up to the length of the string minus 1.
* An error is thrown for invalid positions.
+ * If <q> is Unicode-encoded, -1 or -2 could be returned for
+ * invalid byte sequences.
* Both non-colon-modified forms of Q require register <q>
* to be defined and fail otherwise.
*
@@ -369,24 +370,40 @@ teco_state_setqregstring_nobuilding_done(teco_machine_main_t *ctx,
gint args = teco_expressions_args();
if (args > 0) {
- g_autofree gchar *buffer = g_malloc(args);
-
- for (gint i = args; i > 0; i--) {
- teco_int_t v;
- if (!teco_expressions_pop_num_calc(&v, 0, error))
- return NULL;
- buffer[i-1] = (gchar)v;
+ g_autofree gchar *buffer = NULL;
+ gsize len = 0;
+
+ if (qreg->vtable->get_codepage(qreg) == SC_CP_UTF8) {
+ buffer = g_malloc(6*args);
+ for (gint i = args; i > 0; i--) {
+ teco_int_t v;
+ if (!teco_expressions_pop_num_calc(&v, 0, error))
+ return NULL;
+ if (!g_unichar_validate(v)) {
+ teco_error_codepoint_set(error, "^U");
+ return NULL;
+ }
+ len += g_unichar_to_utf8(v, buffer+len);
+ }
+ } else {
+ buffer = g_malloc(args);
+ for (gint i = args; i > 0; i--) {
+ teco_int_t v;
+ if (!teco_expressions_pop_num_calc(&v, 0, error))
+ return NULL;
+ buffer[len++] = v;
+ }
}
if (colon_modified) {
/* append to register */
if (!qreg->vtable->undo_append_string(qreg, error) ||
- !qreg->vtable->append_string(qreg, buffer, args, error))
+ !qreg->vtable->append_string(qreg, buffer, len, error))
return NULL;
} else {
/* set register */
if (!qreg->vtable->undo_set_string(qreg, error) ||
- !qreg->vtable->set_string(qreg, buffer, args, error))
+ !qreg->vtable->set_string(qreg, buffer, len, error))
return NULL;
}
}