[vte] emulation: Simplify sequence matching



commit 0d1f50109740931d9547ed49f5b744438a4157cc
Author: Christian Persch <chpe src gnome org>
Date:   Tue Nov 21 18:36:48 2017 +0100

    emulation: Simplify sequence matching
    
    Instead of returning a string from the matcher that is then used
    to lookup a handler, just return the function pointer directly
    from the matcher.

 configure.ac              |    8 -
 doc/reference/Makefile.am |    3 +-
 src/Makefile.am           |   83 +-----------
 src/caps-list.hh          |  318 +++++++++++++++++++++++++++++++++++++++++++++
 src/caps.cc               |  306 -------------------------------------------
 src/interpret.cc          |  171 ------------------------
 src/matcher.cc            |   43 +++----
 src/matcher.hh            |   46 +++++--
 src/table.cc              |  277 ++++++++++-----------------------------
 src/table.hh              |   22 ++-
 src/vte.cc                |   52 +++++---
 src/vteinternal.hh        |    8 +-
 src/vteseq-list.hh        |  156 ++++++++++++++++++++++
 src/vteseq-n.gperf        |  175 -------------------------
 src/vteseq.cc             |  125 ++++++++++++------
 15 files changed, 738 insertions(+), 1055 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 1d8daaf..bf163ba 100644
--- a/configure.ac
+++ b/configure.ac
@@ -399,14 +399,6 @@ if test -z "$GLIB_COMPILE_RESOURCES"; then
   fi
 fi
 
-AC_ARG_VAR([GPERF],[the gperf programme])
-if test -z "$GPERF"; then
-  AC_PATH_PROG([GPERF],[gperf],[])
-  if test -z "$GPERF"; then
-    AC_MSG_ERROR([gperf not found])
-  fi
-fi
-
 AC_ARG_VAR([XMLLINT],[the xmllint programme])
 if test -z "$XMLLINT"; then
   AC_PATH_PROG([XMLLINT],[xmllint],[])
diff --git a/doc/reference/Makefile.am b/doc/reference/Makefile.am
index d6429b0..7126f18 100644
--- a/doc/reference/Makefile.am
+++ b/doc/reference/Makefile.am
@@ -78,7 +78,8 @@ EXTRA_HFILES =
 IGNORE_HFILES = \
        config.h \
        buffer.h \
-       caps.h \
+       caps.hh \
+       caps-list.hh \
        debug.h \
        iso2022.h \
        keymap.h \
diff --git a/src/Makefile.am b/src/Makefile.am
index 66e5295..b6af4ab 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -32,8 +32,6 @@ lib_LTLIBRARIES = libvte-@VTE_API_MAJOR_VERSION@.@VTE_API_MINOR_VERSION@.la
 EXTRA_libvte_@VTE_API_MAJOR_VERSION@_@VTE_API_MINOR_VERSION@_la_SOURCES = \
        box_drawing_generate.sh \
        marshal.list \
-       vteseq-n.gperf \
-       vteseq-n.cc \
        vtetypebuiltins.cc.template \
        vtetypebuiltins.h.template \
        $(NULL)
@@ -48,8 +46,8 @@ libvte_@VTE_API_MAJOR_VERSION@_@VTE_API_MINOR_VERSION@_la_SOURCES = \
        vte/vteregex.h \
        vte/vteterminal.h \
        buffer.h \
-       caps.cc \
-       caps.h \
+       caps.hh \
+       caps-list.hh \
        debug.cc \
        debug.h \
        iso2022.cc \
@@ -85,7 +83,7 @@ libvte_@VTE_API_MAJOR_VERSION@_@VTE_API_MINOR_VERSION@_la_SOURCES = \
        vtespawn.cc \
        vtespawn.hh \
        vteseq.cc \
-       vteseq-list.h \
+       vteseq-list.hh \
        vtestream.cc \
        vtestream.h \
        vtestream-base.h \
@@ -141,8 +139,6 @@ BUILT_SOURCES = \
        vtetypebuiltins.cc \
        vte/vtetypebuiltins.h \
        vteresources.cc \
-       vteseq-list.h \
-       vteseq-n.cc \
        $(NULL)
 EXTRA_DIST += box_drawing.txt box_drawing_generate.sh iso2022.txt
 CLEANFILES += $(BUILT_SOURCES) stamp-vtetypebuiltins.h
@@ -170,21 +166,12 @@ vtetypebuiltins.cc: vtetypebuiltins.cc.template vte/vteenums.h vte/vtedeprecated
        && (cmp -s xgen-vtbc vtetypebuiltins.cc || cp xgen-vtbc vtetypebuiltins.cc ) \
        && rm -f xgen-vtbc
 
-vteseq-n.cc: vteseq-n.gperf
-       $(AM_V_GEN) $(top_srcdir)/missing --run $(GPERF) -m 100 $< > $@.tmp && \
-       mv -f $@.tmp $@
-
-vteseq-list.h: vteseq-n.gperf
-       $(AM_V_GEN) echo '/* Generated file.  Do not edit */' > $@.tmp && \
-       cat $^ | grep -v '^#' | grep '\<VTE_SEQUENCE_HANDLER\>'| sed 's/.*, //' | LANG=C sort -u >> $@.tmp && 
\
-       mv -f $@.tmp $@
-
 vteresources.cc: vte.gresource.xml Makefile $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies 
vte.gresource.xml)
        $(AM_V_GEN)$(GLIB_COMPILE_RESOURCES) --target $@ --sourcedir . --generate-source --c-name _vte $<
 
 # Misc unit tests and utilities
 
-noinst_PROGRAMS += interpret slowcat
+noinst_PROGRAMS += slowcat
 noinst_SCRIPTS = decset osc window
 EXTRA_DIST += $(noinst_SCRIPTS)
 
@@ -193,7 +180,6 @@ check_PROGRAMS = \
        reaper \
        reflect-text-view \
        reflect-vte mev \
-       table \
        xticker \
        vteconv \
        vtestream-file \
@@ -207,7 +193,6 @@ dist_check_SCRIPTS = \
 
 TESTS = \
        reaper \
-       table \
        test-vtetypes \
        vteconv \
        vtestream-file \
@@ -240,41 +225,6 @@ reflect_vte_CFLAGS = $(VTE_CFLAGS) $(AM_CFLAGS)
 reflect_vte_SOURCES = reflect.c
 reflect_vte_LDADD = libvte-$(VTE_API_VERSION).la $(VTE_LIBS)
 
-interpret_SOURCES = \
-       buffer.h \
-       caps.cc \
-       caps.h \
-       debug.cc \
-       debug.h \
-       iso2022.cc \
-       iso2022.h \
-       matcher.cc \
-       matcher.hh \
-       table.cc \
-       table.hh \
-       vteconv.cc \
-       vteconv.h \
-       interpret.cc
-interpret_CPPFLAGS = \
-       -DINTERPRET_MAIN \
-       -DVTE_API_VERSION=\"$(VTE_API_VERSION)\" \
-       -I$(builddir) \
-       -I$(srcdir) \
-       $(AM_CPPFLAGS)
-interpret_CFLAGS = \
-       $(GLIB_CFLAGS) \
-       $(GOBJECT_CFLAGS) \
-       $(GTK_CFLAGS) \
-       $(AM_CFLAGS)
-interpret_CXXFLAGS = \
-       $(GLIB_CFLAGS) \
-       $(GOBJECT_CFLAGS) \
-       $(GTK_CFLAGS) \
-       $(AM_CXXFLAGS)
-interpret_LDADD = \
-       $(GLIB_LIBS) \
-       $(GOBJECT_LIBS)
-
 slowcat_SOURCES = \
        slowcat.c \
        $(NULL)
@@ -282,31 +232,6 @@ slowcat_CPPFLAGS = -I$(builddir) -I$(srcdir) $(AM_CPPFLAGS)
 slowcat_CFLAGS = $(GLIB_CFLAGS) $(AM_CFLAGS)
 slowcat_LDADD = $(GLIB_LIBS)
 
-table_SOURCES = \
-       buffer.h \
-       caps.cc \
-       caps.h \
-       debug.cc \
-       debug.h \
-       matcher.cc \
-       matcher.hh \
-       table.cc \
-       table.hh \
-       vteconv.cc \
-       vteconv.h \
-       $(NULL)
-table_CPPFLAGS = \
-       -DTABLE_MAIN \
-       -I$(builddir) \
-       -I$(srcdir) \
-       $(AM_CPPFLAGS)
-table_CXXFLAGS = \
-       $(GLIB_CFLAGS) \
-       $(AM_CXXFLAGS)
-table_LDADD = \
-       $(GLIB_LIBS) \
-       $(GOBJECT_LIBS)
-
 test_vtetypes_SOURCES = \
        vtetypes.cc \
        vtetypes.hh \
diff --git a/src/caps-list.hh b/src/caps-list.hh
new file mode 100644
index 0000000..cc75191
--- /dev/null
+++ b/src/caps-list.hh
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2001,2002 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#define ESC _VTE_CAP_ESC
+#define CSI _VTE_CAP_CSI
+#define ST  _VTE_CAP_ST
+#define OSC _VTE_CAP_OSC
+#define PM  _VTE_CAP_PM
+#define APC _VTE_CAP_APC
+
+#define ENQ "\005"
+#define BEL "\007"
+#define BS  "\010"
+#define TAB "\011"
+#define LF  "\012"
+#define VT  "\013"
+#define FF  "\014"
+#define CR  "\015"
+#define SO  "\016"
+#define SI  "\017"
+#define DEL "\177"
+
+#define ENTRY(str,handler) { str, &VteTerminalPrivate::seq_ ## handler }
+
+/* From some really old XTerm docs we had at the office, and an updated
+ * version at Moy, Gildea, and Dickey. */
+static const vte_matcher_entry_t entries[] = {
+        ENTRY(ENQ, return_terminal_status),
+        ENTRY(BEL, bell),
+        ENTRY(BS,  backspace),
+        ENTRY(TAB, tab),
+        ENTRY(LF,  line_feed),
+        ENTRY(VT,  vertical_tab),
+        ENTRY(FF,  form_feed),
+        ENTRY(CR,  carriage_return),
+        ENTRY(SO,  shift_out),
+        ENTRY(SI,  shift_in),
+        ENTRY(DEL, nop),
+
+        ENTRY(ESC " F", seven_bit_controls),
+        ENTRY(ESC " G", eight_bit_controls),
+        ENTRY(ESC " L", ansi_conformance_level_1),
+        ENTRY(ESC " M", ansi_conformance_level_2),
+        ENTRY(ESC " N", ansi_conformance_level_3),
+        ENTRY(ESC "#3", double_height_top_half),
+        ENTRY(ESC "#4", double_height_bottom_half),
+        ENTRY(ESC "#5", single_width),
+        ENTRY(ESC "#6", double_width),
+        ENTRY(ESC "#8", screen_alignment_test),
+
+        /* These are actually designate_other_coding_system from ECMA 35,
+         * but we don't support the full repertoire.  Actually, we don't
+         * know what the full repertoire looks like.
+         */
+        ENTRY(ESC "%%@", default_character_set),
+        ENTRY(ESC "%%G", utf_8_character_set),
+
+        ENTRY(ESC "(0", designate_g0_line_drawing),
+        ENTRY(ESC "(A", designate_g0_british),
+        ENTRY(ESC "(B", designate_g0_plain),
+        ENTRY(ESC ")0", designate_g1_line_drawing),
+        ENTRY(ESC ")A", designate_g1_british),
+        ENTRY(ESC ")B", designate_g1_plain),
+
+        ENTRY(ESC "7", save_cursor),
+        ENTRY(ESC "8", restore_cursor),
+        ENTRY(ESC "=", application_keypad),
+        ENTRY(ESC ">", normal_keypad),
+        ENTRY(ESC "D", index),
+        ENTRY(ESC "E", next_line),
+        ENTRY(ESC "F", cursor_lower_left),
+        ENTRY(ESC "H", tab_set),
+        ENTRY(ESC "M", reverse_index),
+        ENTRY(ESC "N", single_shift_g2),
+        ENTRY(ESC "O", single_shift_g3),
+        ENTRY(ESC "P%s" ST, device_control_string),
+        ENTRY(ESC "V", start_of_guarded_area),
+        ENTRY(ESC "W", end_of_guarded_area),
+        ENTRY(ESC "X%s" ST, start_or_end_of_string),
+        ENTRY(ESC "Z", return_terminal_id),
+        ENTRY(ESC "c", full_reset),
+        ENTRY(ESC "l", memory_lock),
+        ENTRY(ESC "m", memory_unlock),
+        ENTRY(ESC "n", invoke_g2_character_set),
+        ENTRY(ESC "o", invoke_g3_character_set),
+        ENTRY(ESC "|", invoke_g3_character_set_as_gr),
+        ENTRY(ESC "}", invoke_g2_character_set_as_gr),
+        ENTRY(ESC "~", invoke_g1_character_set_as_gr),
+
+        /* APC stuff omitted. */
+
+        /* DCS stuff omitted. */
+
+        ENTRY(CSI "@", insert_blank_characters),
+        ENTRY(CSI "%d@", insert_blank_characters),
+        ENTRY(CSI "A", cursor_up),
+        ENTRY(CSI "%dA", cursor_up),
+        ENTRY(CSI "B", cursor_down),
+        ENTRY(CSI "%dB", cursor_down),
+        ENTRY(CSI "C", cursor_forward),
+        ENTRY(CSI "%dC", cursor_forward),
+        ENTRY(CSI "D", cursor_backward),
+        ENTRY(CSI "%dD", cursor_backward),
+        ENTRY(CSI "E", cursor_next_line),
+        ENTRY(CSI "%dE", cursor_next_line),
+        ENTRY(CSI "F", cursor_preceding_line),
+        ENTRY(CSI "%dF", cursor_preceding_line),
+        ENTRY(CSI "G", cursor_character_absolute),
+        ENTRY(CSI "%dG", cursor_character_absolute),
+        ENTRY(CSI "H", cursor_position),
+        ENTRY(CSI ";H", cursor_position),
+        ENTRY(CSI "%dH", cursor_position),
+        ENTRY(CSI "%d;H", cursor_position),
+        ENTRY(CSI ";%dH", cursor_position_top_row),
+        ENTRY(CSI "%d;%dH", cursor_position),
+        ENTRY(CSI "I", cursor_forward_tabulation),
+        ENTRY(CSI "%dI", cursor_forward_tabulation),
+        ENTRY(CSI "%mJ", erase_in_display),
+        ENTRY(CSI "?%mJ", selective_erase_in_display),
+        ENTRY(CSI "%mK", erase_in_line),
+        ENTRY(CSI "?%mK", selective_erase_in_line),
+        ENTRY(CSI "L", insert_lines),
+        ENTRY(CSI "%dL", insert_lines),
+        ENTRY(CSI "M", delete_lines),
+        ENTRY(CSI "%dM", delete_lines),
+        ENTRY(CSI "P", delete_characters),
+        ENTRY(CSI "%dP", delete_characters),
+        ENTRY(CSI "S", scroll_up),
+        ENTRY(CSI "%dS", scroll_up),
+        ENTRY(CSI "T", scroll_down),
+        ENTRY(CSI "%dT", scroll_down),
+        ENTRY(CSI "%d;%d;%d;%d;%dT", initiate_hilite_mouse_tracking),
+        ENTRY(CSI "X", erase_characters),
+        ENTRY(CSI "%dX", erase_characters),
+        ENTRY(CSI "Z", cursor_back_tab),
+        ENTRY(CSI "%dZ", cursor_back_tab),
+
+        ENTRY(CSI "`", character_position_absolute),
+        ENTRY(CSI "%d`", character_position_absolute),
+        ENTRY(CSI "b", repeat),
+        ENTRY(CSI "%db", repeat),
+        ENTRY(CSI "c", send_primary_device_attributes),
+        ENTRY(CSI "%dc", send_primary_device_attributes),
+        ENTRY(CSI ">c", send_secondary_device_attributes),
+        ENTRY(CSI ">%dc", send_secondary_device_attributes),
+        ENTRY(CSI "=c", send_tertiary_device_attributes),
+        ENTRY(CSI "=%dc", send_tertiary_device_attributes),
+        ENTRY(CSI "?%mc", linux_console_cursor_attributes),
+        ENTRY(CSI "d", line_position_absolute),
+        ENTRY(CSI "%dd", line_position_absolute),
+        ENTRY(CSI "f", cursor_position),
+        ENTRY(CSI ";f", cursor_position),
+        ENTRY(CSI "%df", cursor_position),
+        ENTRY(CSI "%d;f", cursor_position),
+        ENTRY(CSI ";%df", cursor_position_top_row),
+        ENTRY(CSI "%d;%df", cursor_position),
+        ENTRY(CSI "g", tab_clear),
+        ENTRY(CSI "%dg", tab_clear),
+
+        ENTRY(CSI "%mh", set_mode),
+        ENTRY(CSI "?%mh", decset),
+
+        ENTRY(CSI "%mi", media_copy),
+        ENTRY(CSI "?%mi", dec_media_copy),
+
+        ENTRY(CSI "%ml", reset_mode),
+        ENTRY(CSI "?%ml", decreset),
+
+        ENTRY(CSI "%mm", character_attributes),
+
+        ENTRY(CSI "%dn", device_status_report),
+        ENTRY(CSI "?%dn", dec_device_status_report),
+        ENTRY(CSI "!p", soft_reset),
+        ENTRY(CSI "%d;%d\"p", set_conformance_level),
+        ENTRY(CSI " q", set_cursor_style),
+        ENTRY(CSI "%d q", set_cursor_style),
+        ENTRY(CSI "%d\"q", select_character_protection),
+
+        ENTRY(CSI "r", set_scrolling_region),
+        ENTRY(CSI ";r", set_scrolling_region),
+        ENTRY(CSI ";%dr", set_scrolling_region_from_start),
+        ENTRY(CSI "%dr", set_scrolling_region_to_end),
+        ENTRY(CSI "%d;r", set_scrolling_region_to_end),
+        ENTRY(CSI "%d;%dr", set_scrolling_region),
+
+        ENTRY(CSI "?%mr", restore_mode),
+        ENTRY(CSI "s", save_cursor),
+        ENTRY(CSI "?%ms", save_mode),
+        ENTRY(CSI "u", restore_cursor),
+
+        ENTRY(CSI "%mt", window_manipulation),
+
+        ENTRY(CSI "%d;%d;%d;%dw", enable_filter_rectangle),
+        ENTRY(CSI "%dx", request_terminal_parameters),
+        ENTRY(CSI "%d;%d'z", enable_locator_reporting),
+        ENTRY(CSI "%m'{", select_locator_events),
+        ENTRY(CSI "%d'|", request_locator_position),
+
+        /* Set text parameters, BEL_terminated versions. */
+        ENTRY(OSC ";%s" BEL, set_icon_and_window_title), /* undocumented default */
+        ENTRY(OSC "0;%s" BEL, set_icon_and_window_title),
+        ENTRY(OSC "1;%s" BEL, set_icon_title),
+        ENTRY(OSC "2;%s" BEL, set_window_title),
+        ENTRY(OSC "3;%s" BEL, set_xproperty),
+        ENTRY(OSC "4;%s" BEL, change_color_bel),
+        ENTRY(OSC "6;%s" BEL, set_current_file_uri),
+        ENTRY(OSC "7;%s" BEL, set_current_directory_uri),
+        ENTRY(OSC "8;%s;%s" BEL, set_current_hyperlink),
+        ENTRY(OSC "10;%s" BEL, change_foreground_color_bel),
+        ENTRY(OSC "11;%s" BEL, change_background_color_bel),
+        ENTRY(OSC "12;%s" BEL, change_cursor_background_color_bel),
+        ENTRY(OSC "13;%s" BEL, change_mouse_cursor_foreground_color_bel),
+        ENTRY(OSC "14;%s" BEL, change_mouse_cursor_background_color_bel),
+        ENTRY(OSC "15;%s" BEL, change_tek_foreground_color_bel),
+        ENTRY(OSC "16;%s" BEL, change_tek_background_color_bel),
+        ENTRY(OSC "17;%s" BEL, change_highlight_background_color_bel),
+        ENTRY(OSC "18;%s" BEL, change_tek_cursor_color_bel),
+        ENTRY(OSC "19;%s" BEL, change_highlight_foreground_color_bel),
+        ENTRY(OSC "46;%s" BEL, change_logfile),
+        ENTRY(OSC "50;#%d" BEL, change_font_number),
+        ENTRY(OSC "50;%s" BEL, change_font_name),
+        ENTRY(OSC "104" BEL, reset_color),
+        ENTRY(OSC "104;%m" BEL, reset_color),
+        ENTRY(OSC "110" BEL, reset_foreground_color),
+        ENTRY(OSC "111" BEL, reset_background_color),
+        ENTRY(OSC "112" BEL, reset_cursor_background_color),
+        ENTRY(OSC "113" BEL, reset_mouse_cursor_foreground_color),
+        ENTRY(OSC "114" BEL, reset_mouse_cursor_background_color),
+        ENTRY(OSC "115" BEL, reset_tek_foreground_color),
+        ENTRY(OSC "116" BEL, reset_tek_background_color),
+        ENTRY(OSC "117" BEL, reset_highlight_background_color),
+        ENTRY(OSC "118" BEL, reset_tek_cursor_color),
+        ENTRY(OSC "119" BEL, reset_highlight_foreground_color),
+        ENTRY(OSC "133;%s" BEL, iterm2_133),
+        ENTRY(OSC "777;%s" BEL, urxvt_777),
+        ENTRY(OSC "1337;%s" BEL, iterm2_1337),
+
+        /* Set text parameters, ST_terminated versions. */
+        ENTRY(OSC ";%s" ST, set_icon_and_window_title), /* undocumented default */
+        ENTRY(OSC "0;%s" ST, set_icon_and_window_title),
+        ENTRY(OSC "1;%s" ST, set_icon_title),
+        ENTRY(OSC "2;%s" ST, set_window_title),
+        ENTRY(OSC "3;%s" ST, set_xproperty),
+        ENTRY(OSC "4;%s" ST, change_color_st),
+        ENTRY(OSC "6;%s" ST, set_current_file_uri),
+        ENTRY(OSC "7;%s" ST, set_current_directory_uri),
+        ENTRY(OSC "8;%s;%s" ST, set_current_hyperlink),
+        ENTRY(OSC "10;%s" ST, change_foreground_color_st),
+        ENTRY(OSC "11;%s" ST, change_background_color_st),
+        ENTRY(OSC "12;%s" ST, change_cursor_background_color_st),
+        ENTRY(OSC "13;%s" ST, change_mouse_cursor_foreground_color_st),
+        ENTRY(OSC "14;%s" ST, change_mouse_cursor_background_color_st),
+        ENTRY(OSC "15;%s" ST, change_tek_foreground_color_st),
+        ENTRY(OSC "16;%s" ST, change_tek_background_color_st),
+        ENTRY(OSC "17;%s" ST, change_highlight_background_color_st),
+        ENTRY(OSC "18;%s" ST, change_tek_cursor_color_st),
+        ENTRY(OSC "19;%s" ST, change_highlight_foreground_color_st),
+        ENTRY(OSC "46;%s" ST, change_logfile),
+        ENTRY(OSC "50;#%d" ST, change_font_number),
+        ENTRY(OSC "50;%s" ST, change_font_name),
+        ENTRY(OSC "104" ST, reset_color),
+        ENTRY(OSC "104;%m" ST, reset_color),
+        ENTRY(OSC "110" ST, reset_foreground_color),
+        ENTRY(OSC "111" ST, reset_background_color),
+        ENTRY(OSC "112" ST, reset_cursor_background_color),
+        ENTRY(OSC "113" ST, reset_mouse_cursor_foreground_color),
+        ENTRY(OSC "114" ST, reset_mouse_cursor_background_color),
+        ENTRY(OSC "115" ST, reset_tek_foreground_color),
+        ENTRY(OSC "116" ST, reset_tek_background_color),
+        ENTRY(OSC "117" ST, reset_highlight_background_color),
+        ENTRY(OSC "118" ST, reset_tek_cursor_color),
+        ENTRY(OSC "119" ST, reset_highlight_foreground_color),
+        ENTRY(OSC "133;%s" ST, iterm2_133),
+        ENTRY(OSC "777;%s" ST, urxvt_777),
+        ENTRY(OSC "1337;%s" ST, iterm2_1337),
+
+        /* These may be bogus, I can't find docs for them anywhere (#104154). */
+        ENTRY(OSC "21;%s" BEL, set_text_property_21),
+        ENTRY(OSC "2L;%s" BEL, set_text_property_2L),
+        ENTRY(OSC "21;%s" ST, set_text_property_21),
+        ENTRY(OSC "2L;%s" ST, set_text_property_2L),
+};
+
+#undef ENTRY
+
+#undef ESC
+#undef CSI
+#undef ST
+#undef OSC
+#undef PM
+#undef APC
+
+#undef ENQ
+#undef BEL
+#undef BS
+#undef TAB
+#undef LF
+#undef VT
+#undef FF
+#undef CR
+#undef SO
+#undef SI
+#undef DEL
diff --git a/src/matcher.cc b/src/matcher.cc
index f8028b8..3ce99ce 100644
--- a/src/matcher.cc
+++ b/src/matcher.cc
@@ -43,25 +43,24 @@ static struct _vte_matcher_impl dummy_vte_matcher_table = {
 /* Add a string to the matcher. */
 static void
 _vte_matcher_add(const struct _vte_matcher *matcher,
-                const char *pattern, gssize length,
-                const char *result)
+                const char *pattern,
+                 gssize length,
+                 sequence_handler_t handler)
 {
-       matcher->impl->klass->add(matcher->impl, pattern, length, result);
+       matcher->impl->klass->add(matcher->impl, pattern, length, handler);
 }
 
 /* Loads all sequences into matcher */
 static void
 _vte_matcher_init(struct _vte_matcher *matcher)
 {
-       const char *code, *value;
-        char *c1;
-        int i, k, n, variants;
-
        _vte_debug_print(VTE_DEBUG_LIFECYCLE, "_vte_matcher_init()\n");
 
-        code = _vte_xterm_capability_strings;
-        do {
-                value = strchr(code, '\0') + 1;
+        unsigned int n_entries;
+        auto entries = _vte_get_matcher_entries(&n_entries);
+
+        for (unsigned int e = 0; e < n_entries; e++) {
+                char const* code = entries[e].seq;
 
                 /* Escape sequences from \e@ to \e_ have a C1 counterpart
                  * with the eighth bit set instead of a preceding '\x1b'.
@@ -78,16 +77,16 @@ _vte_matcher_init(struct _vte_matcher *matcher)
                  * we create 2^N variants, by replacing every subset of them
                  * with their C1 counterpart.
                  */
-                variants = 1;
-                for (i = 0; code[i] != '\0'; i++) {
+                int variants = 1;
+                for (int i = 0; code[i] != '\0'; i++) {
                         if (code[i] == '\x1B' && code[i + 1] >= '@' && code[i + 1] <= '_') {
                                 variants <<= 1;
                         }
                 }
-                for (n = 0; n < variants; n++) {
-                        c1 = g_strdup(code);
-                        k = 0;
-                        for (i = 0; c1[i] != '\0'; i++) {
+                for (int n = 0; n < variants; n++) {
+                        char* c1 = g_strdup(code);
+                        int k = 0;
+                        for (int i = 0; c1[i] != '\0'; i++) {
                                 if (c1[i] == '\x1B' && c1[i + 1] >= '@' && c1[i + 1] <= '_') {
                                         if (n & (1 << k)) {
                                                 memmove(c1 + i, c1 + i + 1, strlen(c1 + i + 1) + 1);
@@ -96,12 +95,10 @@ _vte_matcher_init(struct _vte_matcher *matcher)
                                         k++;
                                 }
                         }
-                        _vte_matcher_add(matcher, c1, strlen(c1), value);
+                        _vte_matcher_add(matcher, c1, strlen(c1), entries[e].handler);
                         g_free(c1);
                 }
-
-                code = strchr(value, '\0') + 1;
-        } while (*code);
+        }
 
        _VTE_DEBUG_IF(VTE_DEBUG_MATCHER) {
                g_printerr("Matcher contents:\n");
@@ -176,11 +173,11 @@ _vte_matcher_free(struct _vte_matcher *matcher)
 }
 
 /* Check if a string matches a sequence the matcher knows about. */
-const char *
+vte_matcher_result_t
 _vte_matcher_match(struct _vte_matcher *matcher,
                   const gunichar *pattern,
                    gssize length,
-                  const char **res,
+                   sequence_handler_t *handler,
                    const gunichar **consumed,
                   GValueArray **array)
 {
@@ -189,7 +186,7 @@ _vte_matcher_match(struct _vte_matcher *matcher,
                matcher->free_params = NULL;
        }
        return matcher->match(matcher->impl, pattern, length,
-                                       res, consumed, array);
+                              handler, consumed, array);
 }
 
 /* Dump out the contents of a matcher, mainly for debugging. */
diff --git a/src/matcher.hh b/src/matcher.hh
index 4b088c7..b3befae 100644
--- a/src/matcher.hh
+++ b/src/matcher.hh
@@ -22,6 +22,11 @@
 
 #include <glib-object.h>
 
+class VteTerminalPrivate;
+namespace vte { namespace parser { struct Params; } }
+
+typedef void (VteTerminalPrivate::* sequence_handler_t)(vte::parser::Params const&);
+
 struct _vte_matcher;
 
 struct _vte_matcher_impl {
@@ -29,16 +34,29 @@ struct _vte_matcher_impl {
        /* private */
 };
 
+typedef enum {
+        VTE_MATCHER_RESULT_NO_MATCH,
+        VTE_MATCHER_RESULT_MATCH,
+        VTE_MATCHER_RESULT_PARTIAL
+} vte_matcher_result_t;
+
+struct vte_matcher_entry_t {
+        char seq[20];
+        sequence_handler_t handler;
+};
+
+vte_matcher_entry_t const* _vte_get_matcher_entries(unsigned int* n_entries);
+
 typedef struct _vte_matcher_impl *(*_vte_matcher_create_func)(void);
-typedef const char *(*_vte_matcher_match_func)(struct _vte_matcher_impl *impl,
-                                               const gunichar *pattern,
-                                               gssize length,
-                                               const char **res,
-                                               const gunichar **consumed,
-                                               GValueArray **array);
+typedef vte_matcher_result_t (*_vte_matcher_match_func)(struct _vte_matcher_impl *impl,
+                                                        const gunichar *pattern,
+                                                        gssize length,
+                                                        sequence_handler_t *handler,
+                                                        const gunichar **consumed,
+                                                        GValueArray **array);
 typedef void (*_vte_matcher_add_func)(struct _vte_matcher_impl *impl,
-               const char *pattern, gssize length,
-               const char *result);
+                                      const char *pattern, gssize length,
+                                      sequence_handler_t handler);
 typedef void (*_vte_matcher_print_func)(struct _vte_matcher_impl *impl);
 typedef void (*_vte_matcher_destroy_func)(struct _vte_matcher_impl *impl);
 struct _vte_matcher_class{
@@ -56,12 +74,12 @@ struct _vte_matcher *_vte_matcher_new(void);
 void _vte_matcher_free(struct _vte_matcher *matcher);
 
 /* Check if a string matches a sequence the matcher knows about. */
-const char *_vte_matcher_match(struct _vte_matcher *matcher,
-                              const gunichar *pattern,
-                               gssize length,
-                              const char **res,
-                               const gunichar **consumed,
-                              GValueArray **array);
+vte_matcher_result_t _vte_matcher_match(struct _vte_matcher *matcher,
+                                        const gunichar *pattern,
+                                        gssize length,
+                                        sequence_handler_t *handler,
+                                        const gunichar **consumed,
+                                        GValueArray **array);
 
 /* Dump out the contents of a matcher, mainly for debugging. */
 void _vte_matcher_print(struct _vte_matcher *matcher);
diff --git a/src/table.cc b/src/table.cc
index c9bddd9..9621dfe 100644
--- a/src/table.cc
+++ b/src/table.cc
@@ -40,7 +40,7 @@
 
 struct _vte_table {
        struct _vte_matcher_impl impl;
-       const char *result;
+        sequence_handler_t handler;
        unsigned char *original;
        gssize original_length;
        struct _vte_table *table_string;
@@ -189,9 +189,11 @@ _vte_table_free(struct _vte_table *table)
 
 static void
 _vte_table_addi(struct _vte_table *table,
-               const unsigned char *original, gssize original_length,
-               const char *pattern, gssize length,
-               const char *result)
+               const unsigned char *original,
+                gssize original_length,
+               const char *pattern,
+                gssize length,
+                sequence_handler_t handler)
 {
        int i;
        guint8 check;
@@ -206,22 +208,18 @@ _vte_table_addi(struct _vte_table *table,
 
        /* If this is the terminal node, set the result. */
        if (length == 0) {
-               if (table->result != NULL)
+               if (table->handler)
                         _VTE_DEBUG_IF (VTE_DEBUG_PARSE) {
-                                g_printerr ("'%s' => '%s'",
+                                g_printerr ("'%s'",
                                             _vte_debug_sequence_to_string ((const char *)table->original,
-                                                                           table->original_length),
-                                            table->result);
-                                g_printerr (" and '%s' => '%s' are indistinguishable.\n",
+                                                                           table->original_length));
+                                g_printerr (" and '%s' are indistinguishable.\n",
                                             _vte_debug_sequence_to_string ((const char *)original,
-                                                                           original_length),
-                                            result);
+                                                                           original_length));
                         }
 
-               table->result = g_intern_string(result);
-               if (table->original != NULL) {
-                       g_free(table->original);
-               }
+                table->handler = handler;
+                g_free(table->original);
                table->original = (unsigned char *) g_memdup(original, original_length);
                table->original_length = original_length;
                return;
@@ -241,7 +239,7 @@ _vte_table_addi(struct _vte_table *table,
                        /* Add the rest of the string to the subtable. */
                        _vte_table_addi(subtable, original, original_length,
                                        pattern + 2, length - 2,
-                                       result);
+                                       handler);
                        return;
                }
 
@@ -262,7 +260,7 @@ _vte_table_addi(struct _vte_table *table,
                                _vte_table_addi(table, b->data, b->len,
                                                (const char *)b->data + initial,
                                                b->len - initial,
-                                               result);
+                                               handler);
                                g_byte_array_free(b, TRUE);
                        }
                        /* Create a new subtable. */
@@ -275,7 +273,7 @@ _vte_table_addi(struct _vte_table *table,
                        /* Add the rest of the string to the subtable. */
                        _vte_table_addi(subtable, original, original_length,
                                        pattern + 2, length - 2,
-                                       result);
+                                       handler);
                        return;
                }
 
@@ -293,7 +291,7 @@ _vte_table_addi(struct _vte_table *table,
                        /* Add the rest of the string to the subtable. */
                        _vte_table_addi(subtable, original, original_length,
                                        pattern + 2, length - 2,
-                                       result);
+                                       handler);
                        return;
                }
 
@@ -314,7 +312,7 @@ _vte_table_addi(struct _vte_table *table,
                        /* Add the rest of the string to the subtable. */
                        _vte_table_addi(subtable, original, original_length,
                                        pattern + 2, length - 2,
-                                       result);
+                                       handler);
                        return;
                }
 
@@ -341,7 +339,7 @@ _vte_table_addi(struct _vte_table *table,
                                _vte_table_addi(subtable,
                                                original, original_length,
                                                pattern + 3, length - 3,
-                                               result);
+                                               handler);
                        }
                        /* Also add a subtable for higher characters. */
                        if (table->table == NULL) {
@@ -358,7 +356,7 @@ _vte_table_addi(struct _vte_table *table,
                        /* Add the rest of the string to the subtable. */
                        _vte_table_addi(subtable, original, original_length,
                                        pattern + 3, length - 3,
-                                       result);
+                                       handler);
                        return;
                }
        }
@@ -381,27 +379,28 @@ _vte_table_addi(struct _vte_table *table,
        /* Add the rest of the string to the subtable. */
        _vte_table_addi(subtable, original, original_length,
                        pattern + 1, length - 1,
-                       result);
+                       handler);
 }
 
 /* Add a string to the matching tree. */
 void
 _vte_table_add(struct _vte_table *table,
-              const char *pattern, gssize length,
-              const char *result)
+              const char *pattern,
+               gssize length,
+               sequence_handler_t handler)
 {
        _vte_table_addi(table,
                        (const unsigned char *) pattern, length,
                        pattern, length,
-                       result);
+                       handler);
 }
 
 /* Match a string in a subtree. */
-static const char *
+static vte_matcher_result_t
 _vte_table_matchi(struct _vte_table *table,
                  const gunichar *candidate,
                   gssize length,
-                 const char **res,
+                  sequence_handler_t *handler,
                   const gunichar **consumed,
                  unsigned char **original,
                   gssize *original_length,
@@ -412,19 +411,20 @@ _vte_table_matchi(struct _vte_table *table,
        struct _vte_table_arginfo *arginfo;
 
        /* Check if this is a result node. */
-       if (table->result != NULL) {
+       if (table->handler) {
                *consumed = candidate;
                *original = table->original;
                *original_length = table->original_length;
-               *res = table->result;
-               return table->result;
+                *handler = table->handler;
+               return VTE_MATCHER_RESULT_MATCH;
        }
 
        /* If we're out of data, but we still have children, return the empty
         * string. */
        if (G_UNLIKELY (length == 0)) {
                *consumed = candidate;
-               return "";
+                *handler = nullptr;
+               return VTE_MATCHER_RESULT_PARTIAL;
        }
 
        /* Check if this node has a string disposition. */
@@ -444,14 +444,13 @@ _vte_table_matchi(struct _vte_table *table,
                arginfo->length = i;
                /* Continue. */
                return _vte_table_matchi(subtable, candidate + i, length - i,
-                                        res, consumed,
+                                        handler, consumed,
                                         original, original_length, params);
        }
 
        /* Check if this could be a list. */
        if ((_vte_table_is_numeric_list(candidate[0])) &&
            (table->table_number_list != NULL)) {
-               const char *local_result;
 
                subtable = table->table_number_list;
                /* Iterate over all numeric characters, ';' and ':'. */
@@ -467,12 +466,12 @@ _vte_table_matchi(struct _vte_table *table,
                arginfo->length = i;
 
                /* Try and continue. */
-               local_result = _vte_table_matchi(subtable,
-                                        candidate + i, length - i,
-                                        res, consumed,
-                                        original, original_length,
-                                        params);
-               if (local_result != NULL) {
+               auto local_result = _vte_table_matchi(subtable,
+                                                      candidate + i, length - i,
+                                                      handler, consumed,
+                                                      original, original_length,
+                                                      params);
+               if (local_result != VTE_MATCHER_RESULT_NO_MATCH) {
                        return local_result;
                }
                _vte_table_arginfo_head_revert (params, arginfo);
@@ -497,7 +496,7 @@ _vte_table_matchi(struct _vte_table *table,
                arginfo->length = i;
                /* Continue. */
                return _vte_table_matchi(subtable, candidate + i, length - i,
-                                        res, consumed,
+                                        handler, consumed,
                                         original, original_length, params);
        }
 
@@ -512,14 +511,15 @@ _vte_table_matchi(struct _vte_table *table,
                arginfo->length = 1;
                /* Continue. */
                return _vte_table_matchi(subtable, candidate + 1, length - 1,
-                                        res, consumed,
+                                        handler, consumed,
                                         original, original_length, params);
        }
 
        /* If there's nothing else to do, then we can't go on.  Keep track of
         * where we are. */
        *consumed = candidate;
-       return NULL;
+        *handler = nullptr;
+       return VTE_MATCHER_RESULT_NO_MATCH;
 }
 
 static void
@@ -589,30 +589,29 @@ _vte_table_extract_string(GValueArray **array,
 }
 
 /* Check if a string matches something in the tree. */
-const char *
+vte_matcher_result_t
 _vte_table_match(struct _vte_table *table,
                 const gunichar *candidate,
                  gssize length,
-                const char **res,
+                 sequence_handler_t *handler,
                  const gunichar **consumed,
                 GValueArray **array)
 {
        struct _vte_table *head;
-       const char *ret;
        unsigned char *original, *p;
        gssize original_length;
        int i;
        struct _vte_table_arginfo_head params;
        struct _vte_table_arginfo *arginfo;
 
-        g_assert_nonnull(res);
+        g_assert_nonnull(handler);
         g_assert_nonnull(consumed);
-       *res = NULL;
        *consumed = candidate;
 
        /* Provide a fast path for the usual "not a sequence" cases. */
        if (G_LIKELY (length == 0 || candidate == NULL)) {
-               return NULL;
+                *handler = nullptr;
+               return VTE_MATCHER_RESULT_NO_MATCH;
        }
 
        /* If there's no literal path, and no generic path, and the numeric
@@ -625,7 +624,8 @@ _vte_table_match(struct _vte_table *table,
                                if (table->table_number_list == NULL ||
                                        !_vte_table_is_numeric_list(candidate[0])){
                                        /* No match. */
-                                       return NULL;
+                                        *handler = nullptr;
+                                       return VTE_MATCHER_RESULT_NO_MATCH;
                                }
                        }
                }
@@ -639,25 +639,24 @@ _vte_table_match(struct _vte_table *table,
                        head = head->table[_vte_table_map_literal(candidate[i])];
                }
        }
-       if (head != NULL && head->result != NULL) {
+       if (head != NULL && head->handler) {
                /* Got a literal match. */
                *consumed = candidate + i;
-               *res = head->result;
-               return *res;
+                *handler = head->handler;
+               return VTE_MATCHER_RESULT_MATCH;
        }
 
        _vte_table_arginfo_head_init (&params);
 
        /* Check for a pattern match. */
-       ret = _vte_table_matchi(table, candidate, length,
-                               res, consumed,
-                               &original, &original_length,
-                               &params);
-       *res = ret;
+       auto ret = _vte_table_matchi(table, candidate, length,
+                                     handler, consumed,
+                                     &original, &original_length,
+                                     &params);
 
        /* If we got a match, extract the parameters. */
-       if (ret != NULL && ret[0] != '\0' && array != nullptr) {
-               g_assert(original != NULL);
+       if (ret == VTE_MATCHER_RESULT_MATCH && array != nullptr) {
+               g_assert_nonnull(original);
                p = original;
                arginfo = _vte_table_arginfo_head_reverse (&params);
                do {
@@ -703,19 +702,21 @@ _vte_table_printi(struct _vte_table *table, const char *lead, int *count)
        (*count)++;
 
        /* Result? */
-       if (table->result != NULL) {
-               g_printerr("%s = `%s'\n", lead,
-                       table->result);
+       if (table->handler) {
+               g_printerr("%s => result\n", _vte_debug_sequence_to_string(lead, -1));
        }
 
        /* Literal? */
        for (i = 1; i < VTE_TABLE_MAX_LITERAL; i++) {
                if ((table->table != NULL) && (table->table[i] != NULL)) {
                        if (i < 32) {
-                               newlead = g_strdup_printf("%s^%c", lead,
+                               newlead = g_strdup_printf("%s^%c",
+                                                          _vte_debug_sequence_to_string(lead, -1),
                                                          i + 64);
                        } else {
-                               newlead = g_strdup_printf("%s%c", lead, i);
+                               newlead = g_strdup_printf("%s%c",
+                                                          _vte_debug_sequence_to_string(lead, -1),
+                                                          i);
                        }
                        _vte_table_printi(table->table[i], newlead, count);
                        g_free(newlead);
@@ -724,7 +725,8 @@ _vte_table_printi(struct _vte_table *table, const char *lead, int *count)
 
        /* String? */
        if (table->table_string != NULL) {
-               newlead = g_strdup_printf("%s{string}", lead);
+               newlead = g_strdup_printf("%s{string}",
+                                          _vte_debug_sequence_to_string(lead, -1));
                _vte_table_printi(table->table_string,
                                  newlead, count);
                g_free(newlead);
@@ -732,7 +734,8 @@ _vte_table_printi(struct _vte_table *table, const char *lead, int *count)
 
        /* Number(+)? */
        if (table->table_number != NULL) {
-               newlead = g_strdup_printf("%s{number}", lead);
+               newlead = g_strdup_printf("%s{number}",
+                                          _vte_debug_sequence_to_string(lead, -1));
                _vte_table_printi(table->table_number,
                                  newlead, count);
                g_free(newlead);
@@ -749,146 +752,6 @@ _vte_table_print(struct _vte_table *table)
                count, (long) count * sizeof(struct _vte_table));
 }
 
-#ifdef TABLE_MAIN
-/* Return an escaped version of a string suitable for printing. */
-static char *
-escape(const char *p)
-{
-       char *tmp;
-       GString *ret;
-       int i;
-       guint8 check;
-       ret = g_string_new(NULL);
-       for (i = 0; p[i] != '\0'; i++) {
-               tmp = NULL;
-               check = p[i];
-               if (check < 32) {
-                       tmp = g_strdup_printf("^%c", check + 64);
-               } else
-               if (check >= 0x80) {
-                       tmp = g_strdup_printf("{0x%x}", check);
-               } else {
-                       tmp = g_strdup_printf("%c", check);
-               }
-               g_string_append(ret, tmp);
-               g_free(tmp);
-       }
-       return g_string_free(ret, FALSE);
-}
-
-/* Spread out a narrow ASCII string into a wide-character string. */
-static gunichar *
-make_wide(const char *p)
-{
-       gunichar *ret;
-       guint8 check;
-       int i;
-       ret = (gunichar *)g_malloc((strlen(p) + 1) * sizeof(gunichar));
-       for (i = 0; p[i] != 0; i++) {
-               check = (guint8) p[i];
-               g_assert(check < 0x80);
-               ret[i] = check;
-       }
-       ret[i] = '\0';
-       return ret;
-}
-
-/* Print the contents of a GValueArray. */
-static void
-print_array(GValueArray *array)
-{
-       int i;
-       GValue *value;
-       if (array != NULL) {
-               printf(" (");
-               for (i = 0; i < array->n_values; i++) {
-                       value = g_value_array_get_nth(array, i);
-                       if (i > 0) {
-                               printf(", ");
-                       }
-                       if (G_VALUE_HOLDS_LONG(value)) {
-                               printf("%ld", g_value_get_long(value));
-                       } else
-                       if (G_VALUE_HOLDS_STRING(value)) {
-                               printf("\"%s\"", g_value_get_string(value));
-                       } else
-                       if (G_VALUE_HOLDS_POINTER(value)) {
-                               printf("\"%ls\"",
-                                      (wchar_t*) g_value_get_pointer(value));
-                       }
-                       if (G_VALUE_HOLDS_BOXED(value)) {
-                                print_array((GValueArray *)g_value_get_boxed(value));
-                       }
-               }
-               printf(")");
-               /* _vte_matcher_free_params_array(array); */
-       }
-}
-
-int
-main(int argc, char **argv)
-{
-       struct _vte_table *table;
-       int i;
-       const char *candidates[] = {
-               "ABCD",
-               "ABCDEF",
-               "]2;foo",
-               "]3;foo",
-               "]3;fook",
-               "oo",
-               "",
-               "",
-               "[3;5:42m",
-               "[3:5:42m",
-               "",
-               "[3;2:110:120:130m",
-               "[3:2:110:120:130m",
-               "k",
-               "k",
-               "",
-               "]3;3h",
-               "",
-               "j",
-               "s",
-       };
-       const char *result, *p;
-       const gunichar *consumed;
-       char *tmp;
-       gunichar *candidate;
-       GValueArray *array;
-       g_type_init();
-       table = _vte_table_new();
-       _vte_table_add(table, "ABCDEFG", 7, "ABCDEFG");
-       _vte_table_add(table, "ABCD", 4, "ABCD");
-       _vte_table_add(table, "ABCDEFH", 7, "ABCDEFH");
-       _vte_table_add(table, "ACDEFH", 6, "ACDEFH");
-       _vte_table_add(table, "ACDEF%sJ", 8, "ACDEF%sJ");
-       _vte_table_add(table, "[%mh", 5, "move-cursor");
-       _vte_table_add(table, "[%mm", 5, "character-attributes");
-       _vte_table_add(table, "]3;%s", 7, "set-icon-title");
-       _vte_table_add(table, "]4;%s", 7, "set-window-title");
-       printf("Table contents:\n");
-       _vte_table_print(table);
-       printf("\nTable matches:\n");
-       for (i = 0; i < G_N_ELEMENTS(candidates); i++) {
-               p = candidates[i];
-               candidate = make_wide(p);
-               array = NULL;
-               _vte_table_match(table, candidate, strlen(p),
-                                &result, &consumed, &array);
-               tmp = escape(p);
-               printf("`%s' => `%s'", tmp, (result ? result : "(NULL)"));
-               g_free(tmp);
-               print_array(array);
-               printf(" (%d chars)\n", (int) (consumed ? consumed - candidate: 0));
-               g_free(candidate);
-       }
-       _vte_table_free(table);
-       return 0;
-}
-#endif
-
 const struct _vte_matcher_class _vte_matcher_table = {
        (_vte_matcher_create_func)_vte_table_new,
        (_vte_matcher_add_func)_vte_table_add,
diff --git a/src/table.hh b/src/table.hh
index 8f80137..3e9171d 100644
--- a/src/table.hh
+++ b/src/table.hh
@@ -24,6 +24,11 @@
 
 struct _vte_table;
 
+class VteTerminalPrivate;
+namespace vte { namespace parser { struct Params; } }
+
+typedef void (VteTerminalPrivate::* sequence_handler_t)(vte::parser::Params const&);
+
 /* Create an empty, one-level table. */
 struct _vte_table *_vte_table_new(void);
 
@@ -32,16 +37,17 @@ void _vte_table_free(struct _vte_table *table);
 
 /* Add a string to the matching tree. */
 void _vte_table_add(struct _vte_table *table,
-                   const char *pattern, gssize length,
-                   const char *result);
+                   const char *pattern,
+                    gssize length,
+                    sequence_handler_t handler);
 
 /* Check if a string matches something in the tree. */
-const char *_vte_table_match(struct _vte_table *table,
-                            const gunichar *pattern,
-                             gssize length,
-                            const char **res,
-                             const gunichar **consumed,
-                            GValueArray **array);
+vte_matcher_result_t _vte_table_match(struct _vte_table *table,
+                                      const gunichar *pattern,
+                                      gssize length,
+                                      sequence_handler_t *handler,
+                                      const gunichar **consumed,
+                                      GValueArray **array);
 /* Dump out the contents of a tree. */
 void _vte_table_print(struct _vte_table *table);
 
diff --git a/src/vte.cc b/src/vte.cc
index 6f9f333..50c8a74 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -3613,27 +3613,29 @@ skip_chunk:
        bbox_topleft.x = bbox_topleft.y = G_MAXINT;
 
        while (start < wcount && !leftovers) {
-               const char *seq_match;
                const gunichar *next;
                 vte::parser::Params params{nullptr};
 
                /* Try to match any control sequences. */
-               _vte_matcher_match(m_matcher,
-                                  &wbuf[start],
-                                  wcount - start,
-                                  &seq_match,
-                                  &next,
-                                  &params.m_values);
+                sequence_handler_t handler = nullptr;
+                auto match_result = _vte_matcher_match(m_matcher,
+                                                       &wbuf[start],
+                                                       wcount - start,
+                                                       &handler,
+                                                       &next,
+                                                       &params.m_values);
+                switch (match_result) {
                /* We're in one of three possible situations now.
-                * First, the match string is a non-empty string and next
+                * First, the match returned a handler, and next
                 * points to the first character which isn't part of this
                 * sequence. */
-               if ((seq_match != NULL) && (seq_match[0] != '\0')) {
-                       gboolean new_in_scroll_region;
+                case VTE_MATCHER_RESULT_MATCH: {
+                        _VTE_DEBUG_IF(VTE_DEBUG_PARSE)
+                                params.print();
+
+                       /* Call the sequence handler */
+                        (this->*handler)(params);
 
-                       /* Call the right sequence handler for the requested
-                        * behavior. */
-                       handle_sequence(seq_match, params);
                         m_last_graphic_character = 0;
 
                        /* Skip over the proper number of unicode chars. */
@@ -3642,7 +3644,7 @@ skip_chunk:
 
                         // FIXME m_screen may be != previous_screen, check for that!
 
-                        new_in_scroll_region = m_scrolling_restricted
+                        gboolean new_in_scroll_region = m_scrolling_restricted
                             && (m_screen->cursor.row >= (m_screen->insert_delta + m_scrolling_region.start))
                             && (m_screen->cursor.row <= (m_screen->insert_delta + m_scrolling_region.end));
 
@@ -3680,27 +3682,30 @@ skip_chunk:
                        }
 
                        in_scroll_region = new_in_scroll_region;
-               } else
-               /* Second, we have a NULL match, and next points to the very
+
+                        break;
+               }
+               /* Second, we have no match, and next points to the very
                 * next character in the buffer.  Insert the character which
                 * we're currently examining into the screen. */
-               if (seq_match == NULL) {
+               case VTE_MATCHER_RESULT_NO_MATCH: {
                        c = wbuf[start];
                        /* If it's a control character, permute the order, per
                         * vttest. */
                        if ((c != *next) &&
                            ((*next & 0x1f) == *next) &&
+                            //FIXMEchpe what about C1 controls
                            (start + 1 < next - wbuf)) {
                                const gunichar *tnext = NULL;
-                               const char *tmatch = NULL;
                                gunichar ctrl;
                                int i;
                                /* We don't want to permute it if it's another
                                 * control sequence, so check if it is. */
+                                sequence_handler_t thandler;
                                _vte_matcher_match(m_matcher,
                                                   next,
                                                   wcount - (next - wbuf),
-                                                  &tmatch,
+                                                   &thandler,
                                                   &tnext,
                                                   NULL);
                                /* We only do this for non-control-sequence
@@ -3710,6 +3715,7 @@ skip_chunk:
                                        ctrl = *next;
                                        /* Move everything before it up a
                                         * slot.  */
+                                        // FIXMEchpe memmove!
                                        for (i = next - wbuf; i > start; i--) {
                                                wbuf[i] = wbuf[i - 1];
                                        }
@@ -3783,7 +3789,10 @@ skip_chunk:
                        /* We *don't* emit flush pending signals here. */
                        modified = TRUE;
                        start++;
-               } else {
+
+                        break;
+               }
+                case VTE_MATCHER_RESULT_PARTIAL: {
                        /* Case three: the read broke in the middle of a
                         * control sequence, so we're undecided with no more
                         * data to consult. If we have data following the
@@ -3802,7 +3811,10 @@ skip_chunk:
                                 * data before continuing. */
                                leftovers = TRUE;
                        }
+
+                        break;
                }
+                }
 
 #ifdef VTE_DEBUG
                /* Some safety checks: ensure the visible parts of the buffer
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index aec5b05..e9c18b4 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -266,6 +266,8 @@ struct Params {
 
         char* ucs4_to_utf8(gunichar const* str) const;
 
+        void print() const;
+
         inline unsigned int size() const
         {
                 return G_LIKELY(m_values != nullptr) ? m_values->n_values : 0;
@@ -1315,10 +1317,10 @@ public:
         void select_empty(vte::grid::column_t col,
                           vte::grid::row_t row);
 
-#define VTE_SEQUENCE_HANDLER(name) \
+#define SEQUENCE_HANDLER(name) \
        inline void seq_ ## name (vte::parser::Params const& params);
-#include "vteseq-list.h"
-#undef VTE_SEQUENCE_HANDLER
+#include "vteseq-list.hh"
+#undef SEQUENCE_HANDLER
 };
 
 extern GTimer *process_timer;
diff --git a/src/vteseq-list.hh b/src/vteseq-list.hh
new file mode 100644
index 0000000..1dda448
--- /dev/null
+++ b/src/vteseq-list.hh
@@ -0,0 +1,156 @@
+SEQUENCE_HANDLER(ansi_conformance_level_1)
+SEQUENCE_HANDLER(ansi_conformance_level_2)
+SEQUENCE_HANDLER(ansi_conformance_level_3)
+SEQUENCE_HANDLER(application_keypad)
+SEQUENCE_HANDLER(backspace)
+SEQUENCE_HANDLER(bell)
+SEQUENCE_HANDLER(carriage_return)
+SEQUENCE_HANDLER(change_background_color_bel)
+SEQUENCE_HANDLER(change_background_color_st)
+SEQUENCE_HANDLER(change_color_bel)
+SEQUENCE_HANDLER(change_color_st)
+SEQUENCE_HANDLER(change_cursor_background_color_bel)
+SEQUENCE_HANDLER(change_cursor_background_color_st)
+SEQUENCE_HANDLER(change_font_name)
+SEQUENCE_HANDLER(change_font_number)
+SEQUENCE_HANDLER(change_foreground_color_bel)
+SEQUENCE_HANDLER(change_foreground_color_st)
+SEQUENCE_HANDLER(change_highlight_background_color_bel)
+SEQUENCE_HANDLER(change_highlight_background_color_st)
+SEQUENCE_HANDLER(change_highlight_foreground_color_bel)
+SEQUENCE_HANDLER(change_highlight_foreground_color_st)
+SEQUENCE_HANDLER(change_logfile)
+SEQUENCE_HANDLER(change_mouse_cursor_background_color_bel)
+SEQUENCE_HANDLER(change_mouse_cursor_background_color_st)
+SEQUENCE_HANDLER(change_mouse_cursor_foreground_color_bel)
+SEQUENCE_HANDLER(change_mouse_cursor_foreground_color_st)
+SEQUENCE_HANDLER(change_tek_background_color_bel)
+SEQUENCE_HANDLER(change_tek_background_color_st)
+SEQUENCE_HANDLER(change_tek_cursor_color_bel)
+SEQUENCE_HANDLER(change_tek_cursor_color_st)
+SEQUENCE_HANDLER(change_tek_foreground_color_bel)
+SEQUENCE_HANDLER(change_tek_foreground_color_st)
+SEQUENCE_HANDLER(character_attributes)
+SEQUENCE_HANDLER(character_position_absolute)
+SEQUENCE_HANDLER(cursor_back_tab)
+SEQUENCE_HANDLER(cursor_backward)
+SEQUENCE_HANDLER(cursor_character_absolute)
+SEQUENCE_HANDLER(cursor_down)
+SEQUENCE_HANDLER(cursor_forward)
+SEQUENCE_HANDLER(cursor_forward_tabulation)
+SEQUENCE_HANDLER(cursor_lower_left)
+SEQUENCE_HANDLER(cursor_next_line)
+SEQUENCE_HANDLER(cursor_position)
+SEQUENCE_HANDLER(cursor_position_top_row)
+SEQUENCE_HANDLER(cursor_preceding_line)
+SEQUENCE_HANDLER(cursor_up)
+SEQUENCE_HANDLER(dec_device_status_report)
+SEQUENCE_HANDLER(dec_media_copy)
+SEQUENCE_HANDLER(decreset)
+SEQUENCE_HANDLER(decset)
+SEQUENCE_HANDLER(default_character_set)
+SEQUENCE_HANDLER(delete_characters)
+SEQUENCE_HANDLER(delete_lines)
+SEQUENCE_HANDLER(designate_g0_british)
+SEQUENCE_HANDLER(designate_g0_line_drawing)
+SEQUENCE_HANDLER(designate_g0_plain)
+SEQUENCE_HANDLER(designate_g1_british)
+SEQUENCE_HANDLER(designate_g1_line_drawing)
+SEQUENCE_HANDLER(designate_g1_plain)
+SEQUENCE_HANDLER(device_control_string)
+SEQUENCE_HANDLER(device_status_report)
+SEQUENCE_HANDLER(double_height_bottom_half)
+SEQUENCE_HANDLER(double_height_top_half)
+SEQUENCE_HANDLER(double_width)
+SEQUENCE_HANDLER(eight_bit_controls)
+SEQUENCE_HANDLER(enable_filter_rectangle)
+SEQUENCE_HANDLER(enable_locator_reporting)
+SEQUENCE_HANDLER(end_of_guarded_area)
+SEQUENCE_HANDLER(erase_characters)
+SEQUENCE_HANDLER(erase_in_display)
+SEQUENCE_HANDLER(erase_in_line)
+SEQUENCE_HANDLER(form_feed)
+SEQUENCE_HANDLER(full_reset)
+SEQUENCE_HANDLER(index)
+SEQUENCE_HANDLER(initiate_hilite_mouse_tracking)
+SEQUENCE_HANDLER(insert_blank_characters)
+SEQUENCE_HANDLER(insert_lines)
+SEQUENCE_HANDLER(invoke_g1_character_set_as_gr)
+SEQUENCE_HANDLER(invoke_g2_character_set)
+SEQUENCE_HANDLER(invoke_g2_character_set_as_gr)
+SEQUENCE_HANDLER(invoke_g3_character_set)
+SEQUENCE_HANDLER(invoke_g3_character_set_as_gr)
+SEQUENCE_HANDLER(iterm2_133)
+SEQUENCE_HANDLER(iterm2_1337)
+SEQUENCE_HANDLER(line_feed)
+SEQUENCE_HANDLER(line_position_absolute)
+SEQUENCE_HANDLER(linux_console_cursor_attributes)
+SEQUENCE_HANDLER(media_copy)
+SEQUENCE_HANDLER(memory_lock)
+SEQUENCE_HANDLER(memory_unlock)
+SEQUENCE_HANDLER(next_line)
+SEQUENCE_HANDLER(nop)
+SEQUENCE_HANDLER(normal_keypad)
+SEQUENCE_HANDLER(repeat)
+SEQUENCE_HANDLER(request_locator_position)
+SEQUENCE_HANDLER(request_terminal_parameters)
+SEQUENCE_HANDLER(reset_background_color)
+SEQUENCE_HANDLER(reset_color)
+SEQUENCE_HANDLER(reset_cursor_background_color)
+SEQUENCE_HANDLER(reset_foreground_color)
+SEQUENCE_HANDLER(reset_highlight_background_color)
+SEQUENCE_HANDLER(reset_highlight_foreground_color)
+SEQUENCE_HANDLER(reset_mode)
+SEQUENCE_HANDLER(reset_mouse_cursor_background_color)
+SEQUENCE_HANDLER(reset_mouse_cursor_foreground_color)
+SEQUENCE_HANDLER(reset_tek_background_color)
+SEQUENCE_HANDLER(reset_tek_cursor_color)
+SEQUENCE_HANDLER(reset_tek_foreground_color)
+SEQUENCE_HANDLER(restore_cursor)
+SEQUENCE_HANDLER(restore_mode)
+SEQUENCE_HANDLER(return_terminal_id)
+SEQUENCE_HANDLER(return_terminal_status)
+SEQUENCE_HANDLER(reverse_index)
+SEQUENCE_HANDLER(save_cursor)
+SEQUENCE_HANDLER(save_mode)
+SEQUENCE_HANDLER(screen_alignment_test)
+SEQUENCE_HANDLER(scroll_down)
+SEQUENCE_HANDLER(scroll_up)
+SEQUENCE_HANDLER(select_character_protection)
+SEQUENCE_HANDLER(select_locator_events)
+SEQUENCE_HANDLER(selective_erase_in_display)
+SEQUENCE_HANDLER(selective_erase_in_line)
+SEQUENCE_HANDLER(send_primary_device_attributes)
+SEQUENCE_HANDLER(send_secondary_device_attributes)
+SEQUENCE_HANDLER(send_tertiary_device_attributes)
+SEQUENCE_HANDLER(set_conformance_level)
+SEQUENCE_HANDLER(set_current_directory_uri)
+SEQUENCE_HANDLER(set_current_file_uri)
+SEQUENCE_HANDLER(set_current_hyperlink)
+SEQUENCE_HANDLER(set_cursor_style)
+SEQUENCE_HANDLER(set_icon_and_window_title)
+SEQUENCE_HANDLER(set_icon_title)
+SEQUENCE_HANDLER(set_mode)
+SEQUENCE_HANDLER(set_scrolling_region)
+SEQUENCE_HANDLER(set_scrolling_region_from_start)
+SEQUENCE_HANDLER(set_scrolling_region_to_end)
+SEQUENCE_HANDLER(set_text_property_21)
+SEQUENCE_HANDLER(set_text_property_2L)
+SEQUENCE_HANDLER(set_window_title)
+SEQUENCE_HANDLER(set_xproperty)
+SEQUENCE_HANDLER(seven_bit_controls)
+SEQUENCE_HANDLER(shift_in)
+SEQUENCE_HANDLER(shift_out)
+SEQUENCE_HANDLER(single_shift_g2)
+SEQUENCE_HANDLER(single_shift_g3)
+SEQUENCE_HANDLER(single_width)
+SEQUENCE_HANDLER(soft_reset)
+SEQUENCE_HANDLER(start_of_guarded_area)
+SEQUENCE_HANDLER(start_or_end_of_string)
+SEQUENCE_HANDLER(tab)
+SEQUENCE_HANDLER(tab_clear)
+SEQUENCE_HANDLER(tab_set)
+SEQUENCE_HANDLER(urxvt_777)
+SEQUENCE_HANDLER(utf_8_character_set)
+SEQUENCE_HANDLER(vertical_tab)
+SEQUENCE_HANDLER(window_manipulation)
diff --git a/src/vteseq.cc b/src/vteseq.cc
index ba5a938..cb2479e 100644
--- a/src/vteseq.cc
+++ b/src/vteseq.cc
@@ -40,14 +40,14 @@
 
 #include <algorithm>
 
-static void
-display_control_sequence(const char *name, vte::parser::Params const& params)
+void
+vte::parser::Params::print() const
 {
 #ifdef VTE_DEBUG
-        g_printerr("%s(", name);
-        auto n_params = params.size();
+        g_printerr("(");
+        auto n_params = size();
         for (unsigned int i = 0; i < n_params; i++) {
-                auto value = params.value_at_unchecked(i);
+                auto value = value_at_unchecked(i);
                 if (i > 0) {
                         g_printerr(", ");
                 }
@@ -62,7 +62,7 @@ display_control_sequence(const char *name, vte::parser::Params const& params)
                         g_printerr("WSTRING(\"%ls\")", (const wchar_t*) w);
                 } else if (G_VALUE_HOLDS_BOXED(value)) {
                         vte::parser::Params subparams{(GValueArray*)g_value_get_boxed(value)};
-                        display_control_sequence("", subparams);
+                        subparams.print();
                 }
        }
        g_printerr(")\n");
@@ -1501,12 +1501,6 @@ VteTerminalPrivate::seq_next_line(vte::parser::Params const& params)
         cursor_down(true);
 }
 
-/* No-op. */
-void
-VteTerminalPrivate::seq_linux_console_cursor_attributes(vte::parser::Params const& params)
-{
-}
-
 /* Scroll the text down N lines, but don't move the cursor. */
 void
 VteTerminalPrivate::seq_scroll_down(vte::parser::Params const& params)
@@ -3053,34 +3047,85 @@ VteTerminalPrivate::seq_iterm2_1337(vte::parser::Params const& params)
          */
 }
 
-/* Lookup tables */
-
-typedef void (VteTerminalPrivate::* sequence_handler_t)(vte::parser::Params const&);
-
-#define VTE_SEQUENCE_HANDLER(name) &VteTerminalPrivate::seq_##name
-#include "vteseq-n.cc"
-#undef VTE_SEQUENCE_HANDLER
-
-/* Handle a terminal control sequence and its parameters. */
-void
-VteTerminalPrivate::handle_sequence(char const* str,
-                                    vte::parser::Params const& params)
-{
-       _VTE_DEBUG_IF(VTE_DEBUG_PARSE)
-               display_control_sequence(str, params);
-
-       /* Find the handler for this control sequence. */
-        auto len = strlen(str);
-        if (G_LIKELY (len >= 2)) {
-                auto const* seqhandler = vteseq_n_hash::lookup(str, len);
-                if (seqhandler != nullptr) {
-                        /* Let the handler handle it. */
-                        (this->*seqhandler->handler)(params);
-                        return;
-                }
+#define UNIMPLEMENTED_SEQUENCE_HANDLER(name) \
+        void \
+        VteTerminalPrivate::seq_ ## name (vte::parser::Params const& params) \
+        { \
+                static bool warned = false; \
+                if (!warned) { \
+                        _vte_debug_print(VTE_DEBUG_PARSE, \
+                                         "Unimplemented handler for control sequence `%s'.\n", \
+                                         "name"); \
+                        warned = true; \
+                } \
         }
 
-        _vte_debug_print (VTE_DEBUG_MISC,
-                          "No handler for control sequence `%s' defined.\n",
-                          str);
+UNIMPLEMENTED_SEQUENCE_HANDLER(ansi_conformance_level_1)
+UNIMPLEMENTED_SEQUENCE_HANDLER(ansi_conformance_level_2)
+UNIMPLEMENTED_SEQUENCE_HANDLER(ansi_conformance_level_3)
+UNIMPLEMENTED_SEQUENCE_HANDLER(change_font_name)
+UNIMPLEMENTED_SEQUENCE_HANDLER(change_font_number)
+UNIMPLEMENTED_SEQUENCE_HANDLER(change_logfile)
+UNIMPLEMENTED_SEQUENCE_HANDLER(change_mouse_cursor_background_color_bel)
+UNIMPLEMENTED_SEQUENCE_HANDLER(change_mouse_cursor_background_color_st)
+UNIMPLEMENTED_SEQUENCE_HANDLER(change_mouse_cursor_foreground_color_bel)
+UNIMPLEMENTED_SEQUENCE_HANDLER(change_mouse_cursor_foreground_color_st)
+UNIMPLEMENTED_SEQUENCE_HANDLER(change_tek_background_color_bel)
+UNIMPLEMENTED_SEQUENCE_HANDLER(change_tek_background_color_st)
+UNIMPLEMENTED_SEQUENCE_HANDLER(change_tek_cursor_color_bel)
+UNIMPLEMENTED_SEQUENCE_HANDLER(change_tek_cursor_color_st)
+UNIMPLEMENTED_SEQUENCE_HANDLER(change_tek_foreground_color_bel)
+UNIMPLEMENTED_SEQUENCE_HANDLER(change_tek_foreground_color_st)
+UNIMPLEMENTED_SEQUENCE_HANDLER(cursor_lower_left)
+UNIMPLEMENTED_SEQUENCE_HANDLER(dec_media_copy)
+UNIMPLEMENTED_SEQUENCE_HANDLER(default_character_set)
+UNIMPLEMENTED_SEQUENCE_HANDLER(device_control_string)
+UNIMPLEMENTED_SEQUENCE_HANDLER(double_height_bottom_half)
+UNIMPLEMENTED_SEQUENCE_HANDLER(double_height_top_half)
+UNIMPLEMENTED_SEQUENCE_HANDLER(double_width)
+UNIMPLEMENTED_SEQUENCE_HANDLER(eight_bit_controls)
+UNIMPLEMENTED_SEQUENCE_HANDLER(enable_filter_rectangle)
+UNIMPLEMENTED_SEQUENCE_HANDLER(enable_locator_reporting)
+UNIMPLEMENTED_SEQUENCE_HANDLER(end_of_guarded_area)
+UNIMPLEMENTED_SEQUENCE_HANDLER(initiate_hilite_mouse_tracking)
+UNIMPLEMENTED_SEQUENCE_HANDLER(invoke_g1_character_set_as_gr)
+UNIMPLEMENTED_SEQUENCE_HANDLER(invoke_g2_character_set)
+UNIMPLEMENTED_SEQUENCE_HANDLER(invoke_g2_character_set_as_gr)
+UNIMPLEMENTED_SEQUENCE_HANDLER(invoke_g3_character_set)
+UNIMPLEMENTED_SEQUENCE_HANDLER(invoke_g3_character_set_as_gr)
+UNIMPLEMENTED_SEQUENCE_HANDLER(linux_console_cursor_attributes)
+UNIMPLEMENTED_SEQUENCE_HANDLER(media_copy)
+UNIMPLEMENTED_SEQUENCE_HANDLER(memory_lock)
+UNIMPLEMENTED_SEQUENCE_HANDLER(memory_unlock)
+UNIMPLEMENTED_SEQUENCE_HANDLER(request_locator_position)
+UNIMPLEMENTED_SEQUENCE_HANDLER(reset_mouse_cursor_foreground_color)
+UNIMPLEMENTED_SEQUENCE_HANDLER(reset_mouse_cursor_background_color)
+UNIMPLEMENTED_SEQUENCE_HANDLER(reset_tek_background_color)
+UNIMPLEMENTED_SEQUENCE_HANDLER(reset_tek_cursor_color)
+UNIMPLEMENTED_SEQUENCE_HANDLER(reset_tek_foreground_color)
+UNIMPLEMENTED_SEQUENCE_HANDLER(select_character_protection)
+UNIMPLEMENTED_SEQUENCE_HANDLER(select_locator_events)
+UNIMPLEMENTED_SEQUENCE_HANDLER(selective_erase_in_display)
+UNIMPLEMENTED_SEQUENCE_HANDLER(selective_erase_in_line)
+UNIMPLEMENTED_SEQUENCE_HANDLER(send_tertiary_device_attributes)
+UNIMPLEMENTED_SEQUENCE_HANDLER(set_conformance_level)
+UNIMPLEMENTED_SEQUENCE_HANDLER(set_text_property_21)
+UNIMPLEMENTED_SEQUENCE_HANDLER(set_text_property_2L)
+UNIMPLEMENTED_SEQUENCE_HANDLER(set_xproperty)
+UNIMPLEMENTED_SEQUENCE_HANDLER(seven_bit_controls)
+UNIMPLEMENTED_SEQUENCE_HANDLER(single_shift_g2)
+UNIMPLEMENTED_SEQUENCE_HANDLER(single_shift_g3)
+UNIMPLEMENTED_SEQUENCE_HANDLER(single_width)
+UNIMPLEMENTED_SEQUENCE_HANDLER(start_of_guarded_area)
+UNIMPLEMENTED_SEQUENCE_HANDLER(start_or_end_of_string)
+UNIMPLEMENTED_SEQUENCE_HANDLER(utf_8_character_set)
+
+#undef UNIMPLEMENTED_UNIMPLEMENTED_SEQUENCE_HANDLER
+
+vte_matcher_entry_t const*
+_vte_get_matcher_entries(unsigned int* n_entries)
+{
+#include "caps-list.hh"
+        *n_entries = G_N_ELEMENTS (entries);
+        return entries;
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]