diff options
author | Nalin Dahyabhai <nalin@src.gnome.org> | 2002-08-22 02:02:40 +0000 |
---|---|---|
committer | Nalin Dahyabhai <nalin@src.gnome.org> | 2002-08-22 02:02:40 +0000 |
commit | 80cbf7e0367fe293c0b62a6412d5e068022e09af (patch) | |
tree | 345908f22a0406a28a30268f67b7c8f9e83415d3 | |
parent | 55bccdf14d96799d421659b1910213d3c1a2733b (diff) | |
download | vte-80cbf7e0367fe293c0b62a6412d5e068022e09af.tar.gz |
Take a vte_table as an additional argument, and don't mess with textvte_0_8_2
* src/iso2022.c(vte_iso2022_substitute): Take a vte_table as an additional
argument, and don't mess with text that's part of a control sequence,
fixing weird behaviors when we got control sequences in the middle of
shift-out text.
* src/table.c(vte_table_match): Speed up for the no-arguments-requested
case, which just became much more common.
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/interpret.c | 5 | ||||
-rw-r--r-- | src/iso2022.c | 549 | ||||
-rw-r--r-- | src/iso2022.h | 3 | ||||
-rw-r--r-- | src/table.c | 14 | ||||
-rw-r--r-- | src/vte.c | 3 | ||||
-rw-r--r-- | vte.spec | 5 |
8 files changed, 311 insertions, 278 deletions
@@ -1,4 +1,10 @@ 2002-08-21 nalin + * src/iso2022.c(vte_iso2022_substitute): Take a vte_table as an + additional argument, and don't mess with text that's part of a control + sequence, even if it's in shifted-out text. + * src/table.c(vte_table_match): Speed up for the no-arguments-requested + case, which just became much more common. +2002-08-21 nalin * src/vte.c(vte_terminal_draw_rows): Cap the maximum number of characters we draw in a single call to vte_terminal_draw_cells at a reasonable number. diff --git a/src/Makefile.am b/src/Makefile.am index 7cb93e35..654cb624 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -74,7 +74,9 @@ iso2022_SOURCES = \ debug.c \ debug.h \ iso2022.c \ - iso2022.h + iso2022.h \ + table.c \ + table.h iso2022_LDADD = @LIBS@ @GLIB_LIBS@ utf8echo_CFLAGS = @CFLAGS@ @GLIB_CFLAGS@ -DUTF8ECHO_MAIN diff --git a/src/interpret.c b/src/interpret.c index 8eb3141a..7fc2671d 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -134,7 +134,8 @@ main(int argc, char **argv) substlen = vte_iso2022_substitute(tmpsubst, ubuf, ubuflen / sizeof(gunichar), - ubuf); + ubuf, + table); if (substlen < 0) { /* Incomplete state-change. */ vte_iso2022_free(tmpsubst); @@ -196,7 +197,7 @@ main(int argc, char **argv) } for (j = 0; j < substlen; j++) { if (ubuf[j] < 32) { - printf("`^%c'\n", ubuf[j]); + printf("`^%c'\n", ubuf[j] + 64); } else if (ubuf[j] < 127) { printf("`%c'\n", ubuf[j]); diff --git a/src/iso2022.c b/src/iso2022.c index 6c039eaf..465ddc58 100644 --- a/src/iso2022.c +++ b/src/iso2022.c @@ -25,6 +25,7 @@ #include <glib-object.h> #include <gdk/gdkkeysyms.h> #include "debug.h" +#include "table.h" #include "iso2022.h" /* Maps which jive with XTerm's ESC ()*+ ? sequences and RFC 1468. */ @@ -412,7 +413,7 @@ vte_iso2022_map_get(gunichar mapname) gssize vte_iso2022_substitute(struct vte_iso2022 *outside_state, gunichar *instring, gssize length, - gunichar *outstring) + gunichar *outstring, struct vte_table *specials) { int i, j, k, g; struct vte_iso2022 state; @@ -420,6 +421,8 @@ vte_iso2022_substitute(struct vte_iso2022 *outside_state, gpointer ptr; gunichar *buf, current_map = '\0', last_map = '\0', result; unsigned int accumulator; + const char *match; + const gunichar *used; int chars_per_code = 1; g_return_val_if_fail(outside_state != NULL, 0); @@ -430,101 +433,65 @@ vte_iso2022_substitute(struct vte_iso2022 *outside_state, buf = g_malloc(sizeof(gunichar) * length); state = *outside_state; - for (i = j = 0; i < length; i++) - switch (instring[i]) { - case '': - /* SO/LS1 */ - state.current = 1; -#ifdef VTE_DEBUG - if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { - fprintf(stderr, "SO/LS1.\n"); - } -#endif - continue; - break; - case '': - /* SI/LS0 */ - state.current = 0; -#ifdef VTE_DEBUG - if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { - fprintf(stderr, "SI/LS0.\n"); - } -#endif - continue; - break; - case '\r': - case '\n': - /* Reset overrides. */ - state.override = '\0'; - goto plain; - case '': - /* Reset overrides. */ - state.override = '\0'; - /* Begins a control sequence. Make sure there's another - * character for us to read. */ - if (i + 1 >= length) { - g_free(buf); -#ifdef VTE_DEBUG - if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { - fprintf(stderr, - "Incomplete specifier: " - "need %d bytes, have " - "%d.\n", 1, length - i); - } -#endif - return -1; - } - switch (instring[i + 1]) { - case '(': /* Designate G0/GL. */ - case ')': /* Designate G1/GR. */ - case '*': /* Designate G2. */ - case '+': /* Designate G3. */ - g = -1; - if (instring[i + 1] == '(') { - g = 0; - } else - if (instring[i + 1] == ')') { - g = 1; - } else - if (instring[i + 2] == '*') { - g = 2; - } else - if (instring[i + 2] == '+') { - g = 3; + for (i = j = 0; i < length; i++) { + if ((specials != NULL) && + (vte_table_match(specials, instring + i, length - i, + &match, &used, NULL, NULL) != NULL)) { + if (strlen(match) > 0) { + /* Aaargh, SI/SO masquerade as capabilities. */ + if ((strcmp(match, "as") != 0) && + (strcmp(match, "ae") != 0)) { + memcpy(buf + j, instring + i, + sizeof(gunichar) * + (used - (instring + i))); + j += (used - (instring + i)); + i = (used - instring) - 1; + continue; + } } else { - g_assert_not_reached(); - } - /* Designate Gx. Must be another character here. */ - if (i + 2 >= length) { g_free(buf); #ifdef VTE_DEBUG if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { fprintf(stderr, - "Incomplete specifier: " - "need %d bytes, have " - "%d.\n", 2, length - i); + "Incomplete sequence: " + "need %d bytes,\n", length); } #endif return -1; } - /* We only handle maps we recognize. */ - if (strchr(NARROW_MAPS, instring[i + 2]) == NULL) { - continue; + } + switch (instring[i]) { + case '': + /* SO/LS1 */ + state.current = 1; +#ifdef VTE_DEBUG + if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { + fprintf(stderr, "SO/LS1.\n"); } - /* Set Gx. */ - state.g[g] = instring[i + 2]; - i += 2; +#endif + continue; + break; + case '': + /* SI/LS0 */ + state.current = 0; #ifdef VTE_DEBUG if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { - fprintf(stderr, "G%d set to `%c'.\n", - g, state.g[g]); + fprintf(stderr, "SI/LS0.\n"); } #endif continue; break; - case '$': - /* Designate Gx. Must be another character here. */ - if (i + 2 >= length) { + case '\r': + case '\n': + /* Reset overrides. */ + state.override = '\0'; + goto plain; + case '': + /* Reset overrides. */ + state.override = '\0'; + /* Begins a control sequence. Make sure there's another + * character for us to read. */ + if (i + 1 >= length) { g_free(buf); #ifdef VTE_DEBUG if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { @@ -536,29 +503,16 @@ vte_iso2022_substitute(struct vte_iso2022 *outside_state, #endif return -1; } - switch (instring[i + 2]) { - case '(': /* Designate G0/GL wide. */ - case ')': /* Designate G1/GR wide. */ - case '*': /* Designate G2 wide. */ - case '+': /* Designate G3 wide. */ - /* Need another character here. */ - if (i + 3 >= length) { - g_free(buf); -#ifdef VTE_DEBUG - if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { - fprintf(stderr, - "Incomplete specifier: " - "need %d bytes, have " - "%d.\n", 3, length - i); - } -#endif - return -1; - } + switch (instring[i + 1]) { + case '(': /* Designate G0/GL. */ + case ')': /* Designate G1/GR. */ + case '*': /* Designate G2. */ + case '+': /* Designate G3. */ g = -1; - if (instring[i + 2] == '(') { + if (instring[i + 1] == '(') { g = 0; } else - if (instring[i + 2] == ')') { + if (instring[i + 1] == ')') { g = 1; } else if (instring[i + 2] == '*') { @@ -569,203 +523,280 @@ vte_iso2022_substitute(struct vte_iso2022 *outside_state, } else { g_assert_not_reached(); } + /* Designate Gx. Must be another character here. */ + if (i + 2 >= length) { + g_free(buf); +#ifdef VTE_DEBUG + if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { + fprintf(stderr, + "Incomplete specifier: " + "need %d bytes, have " + "%d.\n", 3, length - i); + } +#endif + return -1; + } /* We only handle maps we recognize. */ - if (strchr(WIDE_GMAPS, instring[i + 3]) == NULL) { - continue; + if (strchr(NARROW_MAPS, instring[i + 2]) == NULL) { + goto plain; } /* Set Gx. */ - state.g[g] = instring[i + 3] + WIDE_FUDGE; - i += 3; + state.g[g] = instring[i + 2]; + i += 2; #ifdef VTE_DEBUG if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { - fprintf(stderr, - "G%d set to wide `%c'.\n", - g, state.g[g] - WIDE_FUDGE); + fprintf(stderr, "G%d set to `%c'.\n", + g, state.g[g]); } #endif continue; break; - default: - /* Override. */ - if (strchr(WIDE_MAPS, instring[i + 2]) == NULL) { + case '$': + /* Designate Gx. Must be another character here. */ + if (i + 2 >= length) { + g_free(buf); +#ifdef VTE_DEBUG + if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { + fprintf(stderr, + "Incomplete specifier: " + "need %d bytes, have " + "%d.\n", 3, length - i); + } +#endif + return -1; + } + switch (instring[i + 2]) { + case '(': /* Designate G0/GL wide. */ + case ')': /* Designate G1/GR wide. */ + case '*': /* Designate G2 wide. */ + case '+': /* Designate G3 wide. */ + /* Need another character here. */ + if (i + 3 >= length) { + g_free(buf); +#ifdef VTE_DEBUG + if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { + fprintf(stderr, + "Incomplete specifier: " + "need %d bytes, have " + "%d.\n", 4, length - i); + } +#endif + return -1; + } + g = -1; + if (instring[i + 2] == '(') { + g = 0; + } else + if (instring[i + 2] == ')') { + g = 1; + } else + if (instring[i + 2] == '*') { + g = 2; + } else + if (instring[i + 2] == '+') { + g = 3; + } else { + g_assert_not_reached(); + } + /* We only handle maps we recognize. */ + if (strchr(WIDE_GMAPS, instring[i + 3]) == NULL) { + goto plain; + } + /* Set Gx. */ + state.g[g] = instring[i + 3] + WIDE_FUDGE; + i += 3; +#ifdef VTE_DEBUG + if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { + fprintf(stderr, + "G%d set to wide `%c'.\n", + g, state.g[g] - WIDE_FUDGE); + } +#endif + continue; + break; + default: + /* Override. */ + if (strchr(WIDE_MAPS, instring[i + 2]) == NULL) { + goto plain; + } + /* Set the current map. */ + state.override = instring[i + 2] + WIDE_FUDGE; + i += 2; +#ifdef VTE_DEBUG + if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { + fprintf(stderr, + "Override set to wide `%c'.\n", + state.override - WIDE_FUDGE); + } +#endif continue; } - /* Set the current map. */ - state.override = instring[i + 2] + WIDE_FUDGE; - i += 2; + break; + + case 'n': + /* LS2 */ + state.current = 2; + i++; #ifdef VTE_DEBUG if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { - fprintf(stderr, - "Override set to wide `%c'.\n", - state.override - WIDE_FUDGE); + fprintf(stderr, "LS2.\n"); } #endif continue; - } - break; - - case 'n': - /* LS2 */ - state.current = 2; - i++; -#ifdef VTE_DEBUG - if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { - fprintf(stderr, "LS2.\n"); - } -#endif - continue; - break; - case 'o': - /* LS3 */ - state.current = 3; - i++; + break; + case 'o': + /* LS3 */ + state.current = 3; + i++; #ifdef VTE_DEBUG - if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { - fprintf(stderr, "LS3.\n"); - } + if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { + fprintf(stderr, "LS3.\n"); + } #endif - continue; - break; - case 'N': - /* SS2 */ - state.ss2 = TRUE; - i++; + continue; + break; + case 'N': + /* SS2 */ + state.ss2 = TRUE; + i++; #ifdef VTE_DEBUG - if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { - fprintf(stderr, "SS2.\n"); - } + if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { + fprintf(stderr, "SS2.\n"); + } #endif - continue; - break; - case 'O': - /* SS3 */ - state.ss3 = TRUE; - i++; + continue; + break; + case 'O': + /* SS3 */ + state.ss3 = TRUE; + i++; #ifdef VTE_DEBUG - if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { - fprintf(stderr, "SS3.\n"); - } + if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { + fprintf(stderr, "SS3.\n"); + } #endif - continue; - break; - /* default: - fall through */ - } - plain: - default: - /* Reset override maps. */ - switch (instring[i]) { - case '\n': - case '\r': - case '': - state.override = 0; - break; - } - /* Determine which map we should use here. */ - if (state.override != 0) { - current_map = state.override; - } else - if (state.ss2) { - current_map = state.g[2]; - state.ss2 = FALSE; - } else - if (state.ss3) { - current_map = state.g[3]; - state.ss3 = FALSE; - } else { - g_assert(state.current < G_N_ELEMENTS(state.g)); - current_map = state.g[state.current]; - } - /* Build. */ - if (current_map > WIDE_FUDGE) { - switch (current_map) { - case '@' + WIDE_FUDGE: - case 'A' + WIDE_FUDGE: - case 'B' + WIDE_FUDGE: - case 'C' + WIDE_FUDGE: - case 'D' + WIDE_FUDGE: - chars_per_code = 2; - break; - case 'G' + WIDE_FUDGE: - case 'H' + WIDE_FUDGE: - chars_per_code = 3; + continue; break; default: - chars_per_code = 1; + goto plain; break; } - } else { - chars_per_code = 1; - } - /* We need at least this many characters. */ - if (i + chars_per_code > length) { -#ifdef VTE_DEBUG - if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { - fprintf(stderr, "Incomplete multibyte sequence " - "at %d: need %d bytes, have %d.\n", - i, chars_per_code, length - i); + plain: + default: + /* Reset override maps. */ + switch (instring[i]) { + case '\n': + case '\r': + case '': + state.override = 0; + break; } -#endif - g_free(buf); - return -1; - } - /* Build up the character. */ - accumulator = 0; - for (k = 0; k < chars_per_code; k++) { - accumulator = (accumulator << 8) | instring[i + k]; - } - /* Load a new map if need be. */ - if (current_map != last_map) { -#ifdef VTE_DEBUG - if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { - if (last_map == '\0') { - fprintf(stderr, - "Charmap set to %s`%c'.\n", - (current_map > WIDE_FUDGE) ? - "wide " : "", - current_map % WIDE_FUDGE); - } else { - fprintf(stderr, - "Charmap changed to %s`%c'.\n", - (current_map > WIDE_FUDGE) ? - "wide " : "", - current_map % WIDE_FUDGE); + /* Determine which map we should use here. */ + if (state.override != 0) { + current_map = state.override; + } else + if (state.ss2) { + current_map = state.g[2]; + state.ss2 = FALSE; + } else + if (state.ss3) { + current_map = state.g[3]; + state.ss3 = FALSE; + } else { + g_assert(state.current < G_N_ELEMENTS(state.g)); + current_map = state.g[state.current]; + } + /* Build. */ + if (current_map > WIDE_FUDGE) { + switch (current_map) { + case '@' + WIDE_FUDGE: + case 'A' + WIDE_FUDGE: + case 'B' + WIDE_FUDGE: + case 'C' + WIDE_FUDGE: + case 'D' + WIDE_FUDGE: + chars_per_code = 2; + break; + case 'G' + WIDE_FUDGE: + case 'H' + WIDE_FUDGE: + chars_per_code = 3; + break; + default: + chars_per_code = 1; + break; } + } else { + chars_per_code = 1; } + /* We need at least this many characters. */ + if (i + chars_per_code > length) { +#ifdef VTE_DEBUG + if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { + fprintf(stderr, "Incomplete multibyte sequence " + "at %d: need %d bytes, have %d.\n", + i, chars_per_code, length - i); + } #endif - charmap = vte_iso2022_map_get(current_map); - last_map = current_map; - } - /* Translate. */ - if (charmap == NULL) { - result = accumulator; - } else { - ptr = GINT_TO_POINTER(accumulator); - result = GPOINTER_TO_INT(g_tree_lookup(charmap, ptr)); - if (result == 0) { - result = accumulator; + g_free(buf); + return -1; + } + /* Build up the character. */ + accumulator = 0; + for (k = 0; k < chars_per_code; k++) { + accumulator = (accumulator << 8) | instring[i + k]; + } + /* Load a new map if need be. */ + if (current_map != last_map) { #ifdef VTE_DEBUG - } else { if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { - if (accumulator != result) { + if (last_map == '\0') { + fprintf(stderr, + "Charmap set to %s`%c'.\n", + (current_map > WIDE_FUDGE) ? + "wide " : "", + current_map % WIDE_FUDGE); + } else { fprintf(stderr, - "0x%x -> 0x%x\n", - accumulator, result); + "Charmap changed to %s`%c'.\n", + (current_map > WIDE_FUDGE) ? + "wide " : "", + current_map % WIDE_FUDGE); } } #endif + charmap = vte_iso2022_map_get(current_map); + last_map = current_map; } - } - /* Store. */ - buf[j++] = result; - accumulator = 0; + /* Translate. */ + if (charmap == NULL) { + result = accumulator; + } else { + ptr = GINT_TO_POINTER(accumulator); + result = GPOINTER_TO_INT(g_tree_lookup(charmap, ptr)); + if (result == 0) { + result = accumulator; #ifdef VTE_DEBUG - if (vte_debug_on(VTE_DEBUG_SUBSTITUTION) && 0) { - fprintf(stderr, "`%c' (%d)\n", result, result); - } + } else { + if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) { + if (accumulator != result) { + fprintf(stderr, + "0x%x -> 0x%x\n", + accumulator, result); + } + } #endif - i += (chars_per_code - 1); - break; + } + } + /* Store. */ + buf[j++] = result; + accumulator = 0; +#ifdef VTE_DEBUG + if (vte_debug_on(VTE_DEBUG_SUBSTITUTION) && 0) { + fprintf(stderr, "`%c' (%d)\n", result, result); + } +#endif + i += (chars_per_code - 1); + break; + } } if (j > 0) { @@ -896,7 +927,7 @@ main(int argc, char **argv) #endif state = vte_iso2022_new(); debug_print(stderr, samples[i]); - length = vte_iso2022_substitute(state, sample, j, sample); + length = vte_iso2022_substitute(state, sample, j, sample, NULL); debug_printu(stderr, sample, length); vte_iso2022_free(state); g_free(sample); diff --git a/src/iso2022.h b/src/iso2022.h index 932916b4..18ab84c6 100644 --- a/src/iso2022.h +++ b/src/iso2022.h @@ -23,6 +23,7 @@ #include <glib.h> #include <glib-object.h> +#include "table.h" G_BEGIN_DECLS @@ -32,7 +33,7 @@ struct vte_iso2022 *vte_iso2022_copy(struct vte_iso2022 *original); void vte_iso2022_free(struct vte_iso2022 *p); gssize vte_iso2022_substitute(struct vte_iso2022 *state, gunichar *instring, gssize length, - gunichar *outstring); + gunichar *outstring, struct vte_table *specials); G_END_DECLS diff --git a/src/table.c b/src/table.c index 57169b40..e9d0b29d 100644 --- a/src/table.c +++ b/src/table.c @@ -445,7 +445,6 @@ vte_table_match(struct vte_table *table, const char *dummy_res = NULL; GQuark dummy_quark = 0; GValueArray *dummy_array = NULL; - GValue *value; const char *ret = NULL; unsigned char *original = NULL, *p = NULL; gssize original_length; @@ -512,7 +511,7 @@ vte_table_match(struct vte_table *table, *res = ret; /* If we got a match, extract the parameters. */ - if ((ret != NULL) && (strlen(ret) > 0)) { + if ((ret != NULL) && (strlen(ret) > 0) && (array != &dummy_array)) { tmp = params; g_assert(original != NULL); p = original; @@ -580,17 +579,6 @@ vte_table_match(struct vte_table *table, g_list_free(params); } - /* Clean up the array if the caller doesn't want it. */ - if (dummy_array != NULL) { - for (i = 0; i < dummy_array->n_values; i++) { - value = g_value_array_get_nth(dummy_array, i); - if (G_VALUE_HOLDS_POINTER(value)) { - g_free(g_value_get_pointer(value)); - } - } - g_value_array_free(dummy_array); - } - return ret; } @@ -5794,7 +5794,8 @@ vte_terminal_process_incoming(gpointer data) /* Perform ISO-2022 and XTerm national charset substitutions. */ substitutions = vte_iso2022_copy(terminal->pvt->substitutions); substitution_count = vte_iso2022_substitute(substitutions, - wbuf, wcount, wbuf); + wbuf, wcount, wbuf, + terminal->pvt->table); if (substitution_count < 0) { vte_iso2022_free(substitutions); g_free(obufptr); @@ -1,5 +1,5 @@ Name: vte -Version: 0.8.1 +Version: 0.8.2 Release: 1 Summary: An experimental terminal emulator. License: LGPL @@ -61,6 +61,9 @@ rm $RPM_BUILD_ROOT/%{_libdir}/lib%{name}.la %{_libdir}/pkgconfig/* %changelog +* Wed Aug 21 2002 Nalin Dahyabhai <nalin@redhat.com> 0.8.2-1 +- don't perform text substitution on text that is part of a control sequence + * Tue Aug 20 2002 Nalin Dahyabhai <nalin@redhat.com> 0.8.1-1 - dispose of the updated iso2022 context properly when processing incoming text |