summaryrefslogtreecommitdiff
path: root/src/trie.c
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin@src.gnome.org>2002-05-14 22:02:40 +0000
committerNalin Dahyabhai <nalin@src.gnome.org>2002-05-14 22:02:40 +0000
commit9820fa1c0b0e3dfaed6a460f9c88610aad4e1b3e (patch)
tree5e50f2a28e91959a8678e21b8ea46b2d7ba3ed31 /src/trie.c
parentb961d28996f665464d679c54373d1256169ac331 (diff)
Don't send motion-tracking events to the child unless we're dragging. Fixvte_0_3_15
* src/vte.c: Don't send motion-tracking events to the child unless we're dragging. Fix ce so that it works even right after startup. Make sure that repainting the entire window actually exposes the visible parts of the window. Fix tab clearing to also allow removal of the current tabstop. Implement save-mode and restore-mode. Start on reverse-video mode. Don't scroll on modifier keypress events. Rework part of clipboard copy. * termcaps/xterm: Add missing F11/F12/End keysyms to bundled xterm termcap.
Diffstat (limited to 'src/trie.c')
-rw-r--r--src/trie.c96
1 files changed, 95 insertions, 1 deletions
diff --git a/src/trie.c b/src/trie.c
index d958aa4..a6dd060 100644
--- a/src/trie.c
+++ b/src/trie.c
@@ -73,6 +73,11 @@ struct char_class {
/* Extract a parameter. */
};
+/* A table to hold shortcuts. */
+struct vte_trie_table {
+ struct trie_path *paths[128];
+};
+
/* A trie to hold control sequences. */
struct vte_trie {
const char *result; /* If this is a terminal node, then this
@@ -80,12 +85,14 @@ struct vte_trie {
GQuark quark; /* The quark for the value of the
result. */
size_t trie_path_count; /* Number of children of this node. */
- struct {
+ struct trie_path {
struct char_class *cclass;
struct char_class_data data;
struct vte_trie *trie; /* The child node corresponding to this
character. */
} *trie_paths;
+ struct vte_trie_table *table; /* A table filled with pointers to the
+ child nodes. */
};
/* Functions for checking if a particular character is part of a class, and
@@ -342,6 +349,10 @@ vte_trie_free(struct vte_trie *trie)
if (trie->trie_path_count > 0) {
g_free(trie->trie_paths);
}
+ if (trie->table != NULL) {
+ g_free(trie->table);
+ trie->table = NULL;
+ }
g_free(trie);
}
@@ -486,6 +497,8 @@ vte_trie_matchx(struct vte_trie *trie, const wchar_t *pattern, size_t length,
unsigned int i;
const char *hres;
enum cclass cc;
+ ssize_t partial;
+ struct trie_path *path;
const char *best = NULL;
GValueArray *bestarray = NULL;
GQuark bestquark = 0;
@@ -518,6 +531,36 @@ vte_trie_matchx(struct vte_trie *trie, const wchar_t *pattern, size_t length,
}
}
+ /* Try the precomputed table. */
+ if ((trie->table != NULL) &&
+ (pattern[0] < G_N_ELEMENTS(trie->table->paths))) {
+ if (trie->table->paths[pattern[0]] != NULL) {
+ path = trie->table->paths[pattern[0]];
+ if (path->cclass->multiple) {
+ for (partial = 0; partial < length; partial++) {
+ if (trie->table->paths[pattern[partial]] != path) {
+ break;
+ }
+ }
+ } else {
+ partial = 1;
+ }
+ if (partial > 0) {
+ path->cclass->extract(pattern,
+ partial,
+ &path->data,
+ array);
+ return vte_trie_matchx(path->trie,
+ pattern + partial,
+ length - partial,
+ res,
+ consumed,
+ quark,
+ array);
+ }
+ }
+ }
+
/* Now figure out which (if any) subtrees to search. First, see
* which character class this character matches. */
for (cc = exact; cc < invalid; cc++)
@@ -595,6 +638,52 @@ vte_trie_matchx(struct vte_trie *trie, const wchar_t *pattern, size_t length,
return *res;
}
+/* Attempt to precompute all of the paths we might take when passing this
+ * node, and use that information to fill in a table. */
+TRIE_MAYBE_STATIC void
+vte_trie_precompute(struct vte_trie *trie)
+{
+ struct vte_trie_table *table;
+ enum cclass cc;
+ int i;
+ wchar_t c;
+
+ /* Free the precomputed table (if there is one). */
+ if (trie->table != NULL) {
+ g_free(trie->table);
+ trie->table = NULL;
+ }
+
+ /* If there are no child nodes, then there's nothing for us to do. */
+ if (trie->trie_path_count == 0) {
+ return;
+ }
+
+ /* Create a new table and clear it. */
+ table = trie->table = g_malloc(sizeof(*table));
+ for (c = 0; c < G_N_ELEMENTS(trie->table->paths); c++) {
+ trie->table->paths[c] = NULL;
+ }
+
+ /* Decide which path a given character would cause us to take, and
+ * store it at a fixed offset in the table. */
+ for (cc = exact; cc < invalid; cc++)
+ for (i = 0; i < trie->trie_path_count; i++) {
+ struct char_class *cclass = trie->trie_paths[i].cclass;
+ if (cclass->type == cc)
+ for (c = 0; c < G_N_ELEMENTS(trie->table->paths); c++)
+ if (trie->table->paths[c] == NULL)
+ if (cclass->check(c, &trie->trie_paths[i].data)) {
+ trie->table->paths[c] = &trie->trie_paths[i];
+ }
+ }
+
+ /* Precompute the node's children. */
+ for (i = 0; i < trie->trie_path_count; i++) {
+ vte_trie_precompute(trie->trie_paths[i].trie);
+ }
+}
+
/* Check if the given pattern matches part of the given trie, returning an
* empty string on a partial initial match, a NULL if there's no match in the
* works, and the result string if we have an exact match. */
@@ -810,6 +899,11 @@ main(int argc, char **argv)
g_quark_from_string("multimatch"));
vte_trie_add(trie, "<esc>]2;%sh", 11, "decset-title",
g_quark_from_string("decset-title"));
+ if (argc > 1) {
+ if (strcmp(argv[1], "--precompute") == 0) {
+ vte_trie_precompute(trie);
+ }
+ }
vte_trie_print(trie);
g_print("\n");