From 5e2d8118299bbfa87c9ea9ee9c221abde2dfadcd Mon Sep 17 00:00:00 2001 From: Daniel Carl Date: Wed, 4 Feb 2015 23:26:44 +0100 Subject: [PATCH] Use more g_string_* function in map processing (#160). The use of these function makes it easier to see what's done compared to the character moving in the loops. --- src/map.c | 39 +++++++++++++++++---------------------- tests/test-map.c | 36 +++++++++++++++++++++--------------- 2 files changed, 38 insertions(+), 37 deletions(-) diff --git a/src/map.c b/src/map.c index f2317f7..12c3f4d 100644 --- a/src/map.c +++ b/src/map.c @@ -203,9 +203,6 @@ MapState map_handle_keys(const guchar *keys, int keylen, gboolean use_map) if (keylen > 0) { g_string_overwrite_len(map.queue, map.qlen, (char*)keys, keylen); map.qlen += keylen; - } else { - /* Shrink the queue to free some memory. */ - g_string_truncate(map.queue, map.qlen); } /* try to resolve keys against the map */ @@ -299,30 +296,28 @@ MapState map_handle_keys(const guchar *keys, int keylen, gboolean use_map) } } - /* replace the matched chars from queue by the cooked string that - * is the result of the mapping */ + /* Replace the matched chars from queue by the cooked string that + * is the result of the mapping. */ if (match) { - int i, j; - /* flush the show command to make room for possible mapped command - * chars to show for example if :nmap foo 12g is use we want to - * display the incomplete 12g command */ + /* Flush the show command to make room for possible mapped command + * chars to show. For example if :nmap foo 12g is use we want to + * display the incomplete 12g command. */ showcmd(0); showlen = 0; - if (match->inlen < match->mappedlen) { - /* make some space within the queue */ - for (i = map.qlen + match->mappedlen - match->inlen, j = map.qlen; j > match->inlen; ) { - map.queue->str[--i] = map.queue->str[--j]; - } - } else if (match->inlen > match->mappedlen) { - /* delete some keys */ - for (i = match->mappedlen, j = match->inlen; i < map.qlen; ) { - map.queue->str[i++] = map.queue->str[j++]; - } + /* Replace the matching input chars by the mapped chars. */ + if (match->inlen == match->mappedlen) { + /* If inlen and mappedlen are the same - replace the inlin + * chars with the mapped chars. This case could also be + * handled by the later string erase and prepend, but handling + * it special avoids unneded function call. */ + g_string_overwrite_len(map.queue, 0, match->mapped, match->mappedlen); + } else { + /* Remove all the chars that where matched and prepend the + * mapped chars to the queue. */ + g_string_erase(map.queue, 0, match->inlen); + g_string_prepend_len(map.queue, match->mapped, match->mappedlen); } - - /* copy the mapped string into the queue */ - g_string_overwrite_len(map.queue, 0, match->mapped, match->mappedlen); map.qlen += match->mappedlen - match->inlen; /* without remap the mapped chars are resolved now */ diff --git a/tests/test-map.c b/tests/test-map.c index e2cb3c3..2333d54 100644 --- a/tests/test-map.c +++ b/tests/test-map.c @@ -23,7 +23,7 @@ #include #include -static char queue[10]; /* receives the keypresses */ +static char queue[20]; /* receives the keypresses */ static int qpos = 0; /* points to the queue entry for the next keypress */ #define QUEUE_APPEND(c) { \ @@ -55,12 +55,16 @@ static void test_handle_string_simple(void) /* test simple mappings */ ASSERT_MAPPING("a", "[a]"); ASSERT_MAPPING("b", "[b]"); + ASSERT_MAPPING("[c]", "c"); ASSERT_MAPPING("", "[tab]"); ASSERT_MAPPING("", "[shift-tab]"); ASSERT_MAPPING("", "[ctrl-f]"); ASSERT_MAPPING("", "[ctrl-f]"); ASSERT_MAPPING("", "[cr]"); ASSERT_MAPPING("foobar", "[baz]"); + + /* key sequences that are not changed by mappings */ + ASSERT_MAPPING("fghi", "fghi"); } static void test_handle_string_alias(void) @@ -70,20 +74,11 @@ static void test_handle_string_alias(void) ASSERT_MAPPING("", "[cr]"); } -static void test_handle_string_multiple(void) -{ - /* test multiple mappings together */ - ASSERT_MAPPING("ba", "[b][a]"); - - /* incomplete ambiguous sequences are not matched jet */ - ASSERT_MAPPING("foob", ""); - ASSERT_MAPPING("ar", "[baz]"); -} - static void test_handle_string_remapped(void) { /* test multiple mappings together */ ASSERT_MAPPING("ba", "[b][a]"); + ASSERT_MAPPING("ab12345[c]", "[a][b]12345c"); /* incomplete ambiguous sequences are not matched jet */ ASSERT_MAPPING("foob", ""); @@ -94,6 +89,17 @@ static void test_handle_string_remapped(void) ASSERT_MAPPING("c", "[b][a]z[a]"); map_insert("d", "cki", 't', true); ASSERT_MAPPING("d", "[b][a]z[a]ki"); + + /* remove the no more needed mappings */ + map_delete("c", 't'); + map_delete("d", 't'); +} + +static void test_handle_string_overrule(void) +{ + /* add another map for 'a' and check if this overrules the previous set */ + map_insert("a", "overruled", 't', false); + ASSERT_MAPPING("a", "overruled"); } static void test_remove(void) @@ -147,21 +153,21 @@ int main(int argc, char *argv[]) g_test_add_func("/test-map/handle_string/simple", test_handle_string_simple); g_test_add_func("/test-map/handle_string/alias", test_handle_string_alias); - g_test_add_func("/test-map/handle_string/multi", test_handle_string_multiple); g_test_add_func("/test-map/handle_string/remapped", test_handle_string_remapped); + g_test_add_func("/test-map/handle_string/overrule", test_handle_string_overrule); g_test_add_func("/test-map/remove", test_remove); g_test_add_func("/test-map/keypress/single-char", test_keypress_single); g_test_add_func("/test-map/keypress/sequence", test_keypress_sequence); /* add some mappings to test */ - map_insert("a", "[a]", 't', false); + map_insert("a", "[a]", 't', false); /* inlen < mappedlen */ map_insert("b", "[b]", 't', false); + map_insert("[c]", "c", 't', false); /* inlen > mappedlen */ + map_insert("foobar", "[baz]", 't', false); map_insert("", "[tab]", 't', false); map_insert("", "[shift-tab]", 't', false); map_insert("", "[ctrl-f]", 't', false); map_insert("", "[cr]", 't', false); - /* map long sequence to shorter result */ - map_insert("foobar", "[baz]", 't', false); result = g_test_run(); map_cleanup(); -- 2.20.1