Commit 5b5257d4 authored by Nalin Dahyabhai's avatar Nalin Dahyabhai

Add. Use unitables. Remove sequences for designating character sets.

* src/mkunitables.sh,src/unitable.*: Add.
* src/iso2022.c, src/iso2022.h: Use unitables.
* src/caps.c: Remove sequences for designating character sets.  Switch to using
	a second passed-in buffer for storing results in case the caller doesn't
	want substitutions done in-place.
* src/interpret.c: Perform substitution.
* src/table.c, src/table.h: Use gssize instead of ssize_t.
* src/termcap.c, src/termcap.h: Use gssize instead of ssize_t.
* src/utf8echo.c: Use strtol, allowing users to specify code points in hex
	format.
parent 8deab9f5
2002-08-19 nalin
* src/mkunitables.sh,src/unitable.*: Add.
* src/iso2022.c, src/iso2022.h: Use unitables.
* src/caps.c: Remove sequences for designating character sets. Switch
to using a second passed-in buffer for storing results in case the
caller doesn't want substitutions done in-place.
* src/interpret.c: Perform substitution.
* src/table.c, src/table.h: Use gssize instead of ssize_t.
* src/termcap.c, src/termcap.h: Use gssize instead of ssize_t.
* src/utf8echo.c: Use strtol, allowing users to specify code points in
hex format.
2002-08-14 nalin
* src/vte.c(vte_terminal_configure_toplevel): repaint the entire window
to ensure that any overdraw area we're not paying attention to at least
......
......@@ -2,8 +2,16 @@ bin_PROGRAMS = vte
pkginclude_HEADERS = caps.h pty.h ring.h termcap.h trie.h vte.h vteaccess.h
lib_LTLIBRARIES = libvte.la
pkglib_PROGRAMS = interpret utf8echo utf8mode iso8859mode slowcat
EXTRA_PROGRAMS = pty reaper ring table termcap trie
EXTRA_DIST = marshal.list
noinst_PROGRAMS = iso2022 pty reaper ring table termcap trie
EXTRA_DIST = \
marshal.list \
unitable.CNS11643 \
unitable.GB12345 \
unitable.GB2312 \
unitable.JIS0201 \
unitable.JIS0208 \
unitable.JIS0212 \
unitable.KSC5601
CFLAGS = @CFLAGS@ @XFT_CFLAGS@ @GTK_CFLAGS@ @X_CFLAGS@
......@@ -12,6 +20,8 @@ libvte_la_SOURCES = \
caps.h \
debug.c \
debug.h \
iso2022.c \
iso2022.h \
marshal.c \
marshal.h \
pty.c \
......@@ -32,7 +42,7 @@ libvte_la_SOURCES = \
vteaccess.h
libvte_la_LIBADD = @LIBS@ @XFT_LIBS@ @GTK_LIBS@ @X_LIBS@
libvte_la_LDFLAGS = -version-info 5:0:3
libvte_la_LDFLAGS = -version-info 6:0:4
CLEANFILES = marshal.c marshal.h
......@@ -50,6 +60,8 @@ interpret_SOURCES = \
caps.h \
debug.c \
debug.h \
iso2022.c \
iso2022.h \
table.c \
table.h \
termcap.c \
......@@ -57,6 +69,14 @@ interpret_SOURCES = \
interpret.c
interpret_LDADD = @GLIB_LIBS@
iso2022_CFLAGS = @CFLAGS@ @GLIB_CFLAGS@ -DISO2022_MAIN
iso2022_SOURCES = \
debug.c \
debug.h \
iso2022.c \
iso2022.h
iso2022_LDADD = @LIBS@ @GLIB_LIBS@
utf8echo_CFLAGS = @CFLAGS@ @GLIB_CFLAGS@ -DUTF8ECHO_MAIN
utf8echo_SOURCES = \
debug.c \
......
......@@ -376,11 +376,6 @@ struct vte_capability_string vte_xterm_capability_strings[] = {
{ESC "%%@", "iso8859-1-character-set", 0},
{ESC "%%G", "utf-8-character-set", 0},
{ESC "(%+\\0", "designate-g0-character-set", 0},
{ESC ")%+\\0", "designate-g1-character-set", 0},
{ESC "*%+\\0", "designate-g2-character-set", 0},
{ESC "+%+\\0", "designate-g3-character-set", 0},
{ESC "7", "save-cursor", 0},
{ESC "8", "restore-cursor", 0},
{ESC "=", "application-keypad", 0},
......@@ -390,8 +385,8 @@ struct vte_capability_string vte_xterm_capability_strings[] = {
{ESC "F", "cursor-lower-left", 0},
{ESC "H", "tab-set", 0},
{ESC "M", "reverse-index", 0},
{ESC "N", "single-shift-g2", 0},
{ESC "O", "single-shift-g3", 0},
/* {ESC "N", "single-shift-g2", 0}, */
/* {ESC "O", "single-shift-g3", 0}, */
{ESC "P%s" ESC "\\", "device-control-string", 0},
{ESC "V", "start-of-guarded-area", 0},
{ESC "W", "end-of-guarded-area", 0},
......@@ -400,11 +395,11 @@ struct vte_capability_string vte_xterm_capability_strings[] = {
{ESC "c", "full-reset", 0},
{ESC "l", "memory-lock", 0},
{ESC "m", "memory-unlock", 0},
{ESC "n", "invoke-g2-character-set", 0},
{ESC "o", "invoke-g3-character-set", 0},
{ESC "|", "invoke-g3-character-set-as-gr", 0},
{ESC "}", "invoke-g2-character-set-as-gr", 0},
{ESC "~", "invoke-g1-character-set-as-gr", 0},
/* {ESC "n", "invoke-g2-character-set", 0}, */
/* {ESC "o", "invoke-g3-character-set", 0}, */
/* {ESC "|", "invoke-g3-character-set-as-gr", 0}, */
/* {ESC "}", "invoke-g2-character-set-as-gr", 0}, */
/* {ESC "~", "invoke-g1-character-set-as-gr", 0}, */
/* APC stuff omitted. */
......
......@@ -55,6 +55,9 @@ vte_debug_parse_string(const char *string)
} else
if (g_ascii_strcasecmp(flags[i], "SELECTION") == 0) {
vte_debug_flags |= VTE_DEBUG_SELECTION;
} else
if (g_ascii_strcasecmp(flags[i], "SUBSTITUTION") == 0) {
vte_debug_flags |= VTE_DEBUG_SUBSTITUTION;
}
}
g_strfreev(flags);
......
......@@ -31,6 +31,7 @@ typedef enum {
VTE_DEBUG_EVENTS = 1 << 4,
VTE_DEBUG_SIGNALS = 1 << 5,
VTE_DEBUG_SELECTION = 1 << 6,
VTE_DEBUG_SUBSTITUTION = 1 << 7,
} VteDebugFlags;
void vte_debug_parse_string(const char *string);
......
......@@ -32,6 +32,7 @@
#include <glib-object.h>
#include "caps.h"
#include "debug.h"
#include "iso2022.h"
#include "termcap.h"
#include "table.h"
......@@ -42,10 +43,17 @@ main(int argc, char **argv)
struct vte_table *table = NULL;
struct vte_termcap *termcap = NULL;
GByteArray *array = NULL;
int i;
int i, j;
char c;
GValue *value;
FILE *infile = NULL;
struct vte_iso2022 *substitutions, *tmpsubst;
const char *tmp;
GQuark quark;
GValueArray *values;
GError *error = NULL;
gunichar *ubuf;
gssize ubuflen, substlen;
vte_debug_parse_string(getenv("VTE_DEBUG_FLAGS"));
......@@ -99,15 +107,11 @@ main(int argc, char **argv)
g_quark_from_static_string(code));
}
substitutions = vte_iso2022_new();
while (fread(&c, 1, 1, infile) == 1) {
g_byte_array_append(array, &c, 1);
for (i = 1; i <= array->len; i++) {
const char *tmp;
GQuark quark;
GValueArray *values;
GError *error = NULL;
gunichar *ubuf;
gsize ubuflen;
ubuf = (gunichar*) g_convert(array->data, i,
vte_table_wide_encoding(),
"UTF-8",
......@@ -117,11 +121,34 @@ main(int argc, char **argv)
error->message ? error->message : "?");
g_clear_error(&error);
}
vte_table_match(table, ubuf, ubuflen / sizeof(gunichar),
tmpsubst = vte_iso2022_copy(substitutions);
substlen = vte_iso2022_substitute(tmpsubst,
ubuf,
ubuflen / sizeof(gunichar),
ubuf);
if (substlen < 0) {
/* Incomplete state-change. */
vte_iso2022_free(tmpsubst);
g_free(ubuf);
continue;
}
if (substlen == 0) {
/* State change. (We gave it more than one
* character, so that one's and all of the
* others have been consumed.) */
vte_iso2022_free(substitutions);
substitutions = tmpsubst;
while (array->len > 0) {
g_byte_array_remove_index(array, 0);
}
g_free(ubuf);
break;
}
vte_table_match(table, ubuf, substlen,
&tmp, NULL, &quark, &values);
if (tmp != NULL) {
if (strlen(tmp) > 0) {
int j;
printf("%s(", g_quark_to_string(quark));
for (j = 0; (values != NULL) && (j < values->n_values); j++) {
if (j > 0) {
......@@ -148,14 +175,28 @@ main(int argc, char **argv)
g_byte_array_remove_index(array, 0);
}
printf(")\n");
g_free(ubuf);
break;
} else {
g_free(ubuf);
continue;
}
} else {
while (array->len > 0) {
printf("`%c'\n", array->data[0]);
g_byte_array_remove_index(array, 0);
}
for (j = 0; j < substlen; j++) {
if (ubuf[j] < 32) {
printf("`^%c'\n", ubuf[j]);
} else
if (ubuf[j] < 127) {
printf("`%c'\n", ubuf[j]);
} else {
printf("`0x%x'\n", ubuf[j]);
}
}
}
g_free(ubuf);
}
}
......@@ -163,6 +204,7 @@ main(int argc, char **argv)
fclose(infile);
}
vte_iso2022_free(substitutions);
g_byte_array_free(array, TRUE);
vte_termcap_free(termcap);
vte_table_free(table);
......
......@@ -26,7 +26,15 @@
#include <gdk/gdkkeysyms.h>
#include "debug.h"
#include "iso2022.h"
#define WIDE94_FUDGE 0x100
/* Maps which jive with XTerm's ESC ()*+ ? sequences and RFC 1468. */
#define NARROW_MAPS "0AB4C5RQKYE6ZH7=" "J"
/* Maps which jive with RFC 1468's ESC $ ? sequences. */
#define WIDE_MAPS "@B"
/* Maps which jive with RFC 1557/1922/2237's ESC $ ()*+ ? sequences. */
#define WIDE_GMAPS "C" "AGH" "D"
/* Fudge factor we add to wide map identifiers to keep them distinct. */
#define WIDE_FUDGE 0x10000
struct vte_iso2022_map {
gunichar from, to;
......@@ -40,11 +48,11 @@ struct vte_iso2022 {
/* DEC Special Character and Line Drawing Set. VT100 and higher (per XTerm
* docs). */
static struct vte_iso2022_map vte_iso2022_map_0[] = {
static const struct vte_iso2022_map vte_iso2022_map_0[] = {
{ 96, 0x25c6}, /* diamond */
{'a', 0x2592}, /* checkerboard */
{'f', 0x00b0}, /* degree */
{'g', 0x00b1}, /* plus/minus */
{'f', GDK_degree}, /* degree */
{'g', GDK_plusminus}, /* plus/minus */
{'j', 0x2518}, /* downright corner */
{'k', 0x2510}, /* upright corner */
{'l', 0x250c}, /* upleft corner */
......@@ -59,14 +67,14 @@ static struct vte_iso2022_map vte_iso2022_map_0[] = {
{127, 0x00b7}, /* bullet */
};
/* United Kingdom. VT100 and higher (per XTerm docs). */
static struct vte_iso2022_map vte_iso2022_map_A[] = {
static const struct vte_iso2022_map vte_iso2022_map_A[] = {
{'$', GDK_sterling},
};
/* US-ASCII (no conversions). VT100 and higher (per XTerm docs). */
static struct vte_iso2022_map vte_iso2022_map_B[] = {
static const struct vte_iso2022_map vte_iso2022_map_B[] = {
};
/* Dutch. VT220 and higher (per XTerm docs). */
static struct vte_iso2022_map vte_iso2022_map_4[] = {
static const struct vte_iso2022_map vte_iso2022_map_4[] = {
{0x23, GDK_sterling},
{0x40, GDK_threequarters},
{0x5b, GDK_ydiaeresis},
......@@ -78,7 +86,7 @@ static struct vte_iso2022_map vte_iso2022_map_4[] = {
{0x7e, GDK_acute}
};
/* Finnish. VT220 and higher (per XTerm docs). */
static struct vte_iso2022_map vte_iso2022_map_C[] = {
static const struct vte_iso2022_map vte_iso2022_map_C[] = {
{0x5b, GDK_Adiaeresis},
{0x5c, GDK_Odiaeresis},
{0x5d, GDK_Aring},
......@@ -90,7 +98,7 @@ static struct vte_iso2022_map vte_iso2022_map_C[] = {
{0x7e, GDK_udiaeresis},
};
/* French. VT220 and higher (per XTerm docs). */
static struct vte_iso2022_map vte_iso2022_map_R[] = {
static const struct vte_iso2022_map vte_iso2022_map_R[] = {
{0x23, GDK_sterling},
{0x40, GDK_agrave},
{0x5b, GDK_degree},
......@@ -102,7 +110,7 @@ static struct vte_iso2022_map vte_iso2022_map_R[] = {
{0x7e, GDK_diaeresis},
};
/* French Canadian. VT220 and higher (per XTerm docs). */
static struct vte_iso2022_map vte_iso2022_map_Q[] = {
static const struct vte_iso2022_map vte_iso2022_map_Q[] = {
{0x40, GDK_agrave},
{0x5b, GDK_acircumflex},
{0x5c, GDK_ccedilla},
......@@ -115,7 +123,7 @@ static struct vte_iso2022_map vte_iso2022_map_Q[] = {
{0x7e, GDK_ucircumflex},
};
/* German. VT220 and higher (per XTerm docs). */
static struct vte_iso2022_map vte_iso2022_map_K[] = {
static const struct vte_iso2022_map vte_iso2022_map_K[] = {
{0x40, GDK_section},
{0x5b, GDK_Adiaeresis},
{0x5c, GDK_Odiaeresis},
......@@ -126,7 +134,7 @@ static struct vte_iso2022_map vte_iso2022_map_K[] = {
{0x7e, GDK_ssharp},
};
/* Italian. VT220 and higher (per XTerm docs). */
static struct vte_iso2022_map vte_iso2022_map_Y[] = {
static const struct vte_iso2022_map vte_iso2022_map_Y[] = {
{0x23, GDK_sterling},
{0x40, GDK_section},
{0x5b, GDK_degree},
......@@ -139,7 +147,7 @@ static struct vte_iso2022_map vte_iso2022_map_Y[] = {
{0x7e, GDK_igrave},
};
/* Norwegian and Danish. VT220 and higher (per XTerm docs). */
static struct vte_iso2022_map vte_iso2022_map_E[] = {
static const struct vte_iso2022_map vte_iso2022_map_E[] = {
{0x40, GDK_Adiaeresis},
{0x5b, GDK_AE},
{0x5c, GDK_Ooblique},
......@@ -152,7 +160,7 @@ static struct vte_iso2022_map vte_iso2022_map_E[] = {
{0x7e, GDK_udiaeresis},
};
/* Spanish. VT220 and higher (per XTerm docs). */
static struct vte_iso2022_map vte_iso2022_map_Z[] = {
static const struct vte_iso2022_map vte_iso2022_map_Z[] = {
{0x23, GDK_sterling},
{0x40, GDK_section},
{0x5b, GDK_exclamdown},
......@@ -163,7 +171,7 @@ static struct vte_iso2022_map vte_iso2022_map_Z[] = {
{0x7d, GDK_ccedilla},
};
/* Swedish. VT220 and higher (per XTerm docs). */
static struct vte_iso2022_map vte_iso2022_map_H[] = {
static const struct vte_iso2022_map vte_iso2022_map_H[] = {
{0x40, GDK_Eacute},
{0x5b, GDK_Adiaeresis},
{0x5c, GDK_Odiaeresis},
......@@ -176,7 +184,7 @@ static struct vte_iso2022_map vte_iso2022_map_H[] = {
{0x7e, GDK_udiaeresis},
};
/* Swiss. VT220 and higher (per XTerm docs). */
static struct vte_iso2022_map vte_iso2022_map_equal[] = {
static const struct vte_iso2022_map vte_iso2022_map_equal[] = {
{0x23, GDK_ugrave},
{0x40, GDK_agrave},
{0x5b, GDK_eacute},
......@@ -191,15 +199,37 @@ static struct vte_iso2022_map vte_iso2022_map_equal[] = {
{0x7e, GDK_ucircumflex},
};
/* Japanese. JIS X 0201-1976 ("Roman" set), per RFC 1468/2237. */
static struct vte_iso2022_map vte_iso2022_map_J[] = {
static const struct vte_iso2022_map vte_iso2022_map_J[] = {
{'\\', GDK_overline},
{'~', GDK_yen},
};
/* Japanese. JIS X 0208-1978, per RFC 1468/2237. */
static struct vte_iso2022_map vte_iso2022_map_dollar_at[] = {
static const struct vte_iso2022_map vte_iso2022_map_wide_at[] = {
#include "unitable.JIS0208"
};
/* Chinese. GB 2312-80, per RFC 1922. */
static const struct vte_iso2022_map vte_iso2022_map_wide_A[] = {
#include "unitable.GB2312"
};
/* Japanese. JIS X 0208-1983, per RFC 1468/2237. */
static struct vte_iso2022_map vte_iso2022_map_dollar_B[] = {
static const struct vte_iso2022_map vte_iso2022_map_wide_B[] = {
#include "unitable.JIS0208"
};
/* Korean. KSC 5601, per RFC 1557. */
static const struct vte_iso2022_map vte_iso2022_map_wide_C[] = {
#include "unitable.KSC5601"
};
/* Japanese. JIS X 0212-1990, per RFC 2237. */
static const struct vte_iso2022_map vte_iso2022_map_wide_D[] = {
#include "unitable.JIS0212"
};
/* Chinese. CNS 11643-plane-1, per RFC 1922. */
static const struct vte_iso2022_map vte_iso2022_map_wide_G[] = {
#include "unitable.CNS11643"
};
/* Chinese. CNS 11643-plane-2, per RFC 1922. */
static const struct vte_iso2022_map vte_iso2022_map_wide_H[] = {
#include "unitable.CNS11643"
};
struct vte_iso2022 *
......@@ -245,7 +275,7 @@ vte_direct_compare(gconstpointer a, gconstpointer b)
}
static GTree *
vte_iso2022_map_init(struct vte_iso2022_map *map, gssize length)
vte_iso2022_map_init(const struct vte_iso2022_map *map, gssize length)
{
GTree *ret;
int i;
......@@ -337,13 +367,33 @@ vte_iso2022_map_get(gunichar mapname)
ret = vte_iso2022_map_init(vte_iso2022_map_J,
G_N_ELEMENTS(vte_iso2022_map_J));
break;
case '@' + WIDE94_FUDGE:
ret = vte_iso2022_map_init(vte_iso2022_map_dollar_at,
G_N_ELEMENTS(vte_iso2022_map_dollar_at));
case '@' + WIDE_FUDGE:
ret = vte_iso2022_map_init(vte_iso2022_map_wide_at,
G_N_ELEMENTS(vte_iso2022_map_wide_at));
break;
case 'B' + WIDE94_FUDGE:
ret = vte_iso2022_map_init(vte_iso2022_map_dollar_B,
G_N_ELEMENTS(vte_iso2022_map_dollar_B));
case 'A' + WIDE_FUDGE:
ret = vte_iso2022_map_init(vte_iso2022_map_wide_A,
G_N_ELEMENTS(vte_iso2022_map_wide_A));
break;
case 'B' + WIDE_FUDGE:
ret = vte_iso2022_map_init(vte_iso2022_map_wide_B,
G_N_ELEMENTS(vte_iso2022_map_wide_B));
break;
case 'C' + WIDE_FUDGE:
ret = vte_iso2022_map_init(vte_iso2022_map_wide_C,
G_N_ELEMENTS(vte_iso2022_map_wide_C));
break;
case 'D' + WIDE_FUDGE:
ret = vte_iso2022_map_init(vte_iso2022_map_wide_D,
G_N_ELEMENTS(vte_iso2022_map_wide_D));
break;
case 'G' + WIDE_FUDGE:
ret = vte_iso2022_map_init(vte_iso2022_map_wide_G,
G_N_ELEMENTS(vte_iso2022_map_wide_G));
break;
case 'H' + WIDE_FUDGE:
ret = vte_iso2022_map_init(vte_iso2022_map_wide_H,
G_N_ELEMENTS(vte_iso2022_map_wide_H));
break;
default:
ret = NULL;
......@@ -359,23 +409,27 @@ vte_iso2022_map_get(gunichar mapname)
gssize
vte_iso2022_substitute(struct vte_iso2022 *outside_state,
gunichar *string, gssize length)
gunichar *instring, gssize length,
gunichar *outstring)
{
int i, j;
int i, j, k, g;
struct vte_iso2022 state;
GTree *charmap = NULL;
gpointer ptr;
gunichar *buf, current_map = '\0', last_map = '\0', result;
unsigned int accumulator;
int chars_per_code = 1;
g_return_val_if_fail(outside_state != NULL, 0);
g_return_val_if_fail(string != NULL, 0);
g_return_val_if_fail(instring != NULL, 0);
g_return_val_if_fail(outstring != NULL, 0);
g_return_val_if_fail(length != 0, 0);
buf = g_malloc(sizeof(gunichar) * length);
state = *outside_state;
for (i = j = 0; i < length; i++)
switch (string[i]) {
switch (instring[i]) {
case '':
/* SO/LS1 */
state.current = 1;
......@@ -403,87 +457,113 @@ vte_iso2022_substitute(struct vte_iso2022 *outside_state,
g_free(buf);
return -1;
}
switch (string[i + 1]) {
case '(':
/* Designate G0. Must be another character here. */
if (i + 2 >= length) {
g_free(buf);
return -1;
}
state.g[0] = string[i + 2];
i += 2;
#ifdef VTE_DEBUG
if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) {
fprintf(stderr, "G0 set to `%c'.\n",
state.g[0]);
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;
} else {
g_assert_not_reached();
}
#endif
continue;
break;
case '$':
/* Designate G0. Must be another character here. */
/* Designate Gx. Must be another character here. */
if (i + 2 >= length) {
g_free(buf);
return -1;
}
state.g[0] = string[i + 2] + WIDE94_FUDGE;
i += 2;
#ifdef VTE_DEBUG
if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) {
fprintf(stderr, "G0 set to wide `%c'.\n",
state.g[0] & 0xFF);
}
#endif
continue;
break;
case ')':
/* Designate G1. Must be another character here. */
if (i + 2 >= length) {
g_free(buf);
return -1;
/* We only handle maps we recognize. */
if (strchr(NARROW_MAPS, instring[i + 2]) == NULL) {
continue;
}
state.g[1] = string[i + 2];
/* Set Gx. */
state.g[g] = instring[i + 2];
i += 2;
#ifdef VTE_DEBUG
if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) {
fprintf(stderr, "G1 set to `%c'.\n",
state.g[1]);
fprintf(stderr, "G%d set to `%c'.\n",
g, state.g[g]);
}
#endif
continue;
break;
case '*':
/* Designate G2. Must be another character here. */
case '$':
/* Designate Gx. Must be another character here. */
if (i + 2 >= length) {
g_free(buf);
return -1;
}
state.g[2] = string[i + 2];
i += 2;
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);
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) {
continue;
}
/* Set Gx. */
state.g[g] = instring[i + 3] + WIDE_FUDGE;
i += 3;
#ifdef VTE_DEBUG
if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) {
fprintf(stderr, "G2 set to `%c'.\n",
state.g[2]);
}
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;
case '+':
/* Designate G3. Must be another character here. */
if (i + 2 >= length) {
g_free(buf);
return -1;
}
state.g[3] = string[i + 2];
i += 2;
continue;
break;
default:
/* New designation for G0; we only handle maps
* we recognize. */
if (strchr(WIDE_MAPS, instring[i + 2]) == NULL) {
continue;
}
/* Set G0. */
state.g[0] = instring[i + 2] + WIDE_FUDGE;
i += 2;
#ifdef VTE_DEBUG
if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) {
fprintf(stderr, "G3 set to `%c'.\n",
state.g[3]);
}
if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) {
fprintf(stderr,
"G0 set to wide `%c'.\n",
state.g[0] - WIDE_FUDGE);
}
#endif
continue;
continue;
}
break;
case 'n':
/* LS2 */
state.current = 2;
......@@ -544,18 +624,53 @@ vte_iso2022_substitute(struct vte_iso2022 *outside_state,
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) {
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 `%c'.\n",
current_map);
"Charmap set to %s`%c'.\n",
(current_map > WIDE_FUDGE) ?
"wide " : "",
current_map % WIDE_FUDGE);
} else {
fprintf(stderr,
"Charmap changed to `%c'.\n",
current_map);
"Charmap changed to %s`%c'.\n",
(current_map > WIDE_FUDGE) ?
"wide " : "",
current_map % WIDE_FUDGE);
}
}
#endif
......@@ -564,18 +679,19 @@ vte_iso2022_substitute(struct vte_iso2022 *outside_state,
}
/* Translate. */
if (charmap == NULL) {
result = string[i];
result = accumulator;
} else {
ptr = GINT_TO_POINTER(string[i]);
ptr = GINT_TO_POINTER(accumulator);
result = GPOINTER_TO_INT(g_tree_lookup(charmap, ptr));
if (result == 0) {
result = string[i];
result = accumulator;
#ifdef VTE_DEBUG
} else {
if (vte_debug_on(VTE_DEBUG_SUBSTITUTION)) {
if (string[i] != result) {
fprintf(stderr, "%d -> 0x%x\n",
string[i], result);
if (accumulator != result) {
fprintf(stderr,
"0x%x -> 0x%x\n",
accumulator, result);
}