From e045e1ca344463769567f37ab1ac13f6567cbf3a Mon Sep 17 00:00:00 2001 From: Ernestas Kulik Date: Sat, 23 Dec 2017 17:28:00 +0200 Subject: file-utilities: rework common prefix computation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, the process for getting the common prefix of a list of file names is a tad too greedy: 1. Find the common prefix of all the strings. 2. Strip the extension from the prefix. 3. Strip trailing punctuation. Step 2 may strip dots if there’s trailing whitespace and step 3 may strip useful punctuation (e.g. parentheses). This commit reworks the process as such: 1. Strip the extension from all the file names. 2. Find the common prefix of all the strings. 3. Trim trailing whitespace. Fixes #174. --- eel/eel-string.c | 36 --------- eel/eel-string.h | 8 -- src/nautilus-file-utilities.c | 51 +++++++++++-- test/meson.build | 5 -- test/test-eel-string-rtrim-punctuation.c | 122 ------------------------------- 5 files changed, 46 insertions(+), 176 deletions(-) delete mode 100644 test/test-eel-string-rtrim-punctuation.c diff --git a/eel/eel-string.c b/eel/eel-string.c index 85c0841a4..0a41a0bf9 100644 --- a/eel/eel-string.c +++ b/eel/eel-string.c @@ -224,42 +224,6 @@ eel_str_replace_substring (const char *string, return result; } -char * -eel_str_rtrim_punctuation (char *str) -{ - int num_punctuation_chars; - int str_len; - int num_chars_left; - char *current_char_pos; - gunichar current_char; - - num_punctuation_chars = 0; - str_len = g_utf8_strlen (str, -1); - current_char_pos = g_utf8_offset_to_pointer (str, str_len); - - while (num_punctuation_chars <= str_len) - { - current_char_pos = g_utf8_prev_char (current_char_pos); - current_char = g_utf8_get_char (current_char_pos); - - if (!g_unichar_ispunct (current_char) && !g_unichar_isspace (current_char)) - { - break; - } - - ++num_punctuation_chars; - } - - if (num_punctuation_chars == 0) - { - return g_strdup (str); - } - - num_chars_left = str_len - num_punctuation_chars; - - return g_utf8_substring (str, 0, num_chars_left); -} - /** * get_common_prefix_length: * @str_a: first string diff --git a/eel/eel-string.h b/eel/eel-string.h index 98cca7e9f..5df4b6b2a 100644 --- a/eel/eel-string.h +++ b/eel/eel-string.h @@ -57,14 +57,6 @@ char * eel_str_strip_substring_and_after (const char *str, char * eel_str_replace_substring (const char *str, const char *substring, const char *replacement); -/** - * eel_str_rtrim_punctuation: - * @str: string - * - * Returns: a copy of str with trailing punctuation characters removed - */ -char * eel_str_rtrim_punctuation (char *str); - /** * eel_str_get_common_prefix: diff --git a/src/nautilus-file-utilities.c b/src/nautilus-file-utilities.c index 78d693eca..828b829aa 100644 --- a/src/nautilus-file-utilities.c +++ b/src/nautilus-file-utilities.c @@ -1315,26 +1315,67 @@ nautilus_get_common_filename_prefix (GList *file_list, return result; } +static char * +trim_whitespace (const gchar *string) +{ + glong space_count; + glong length; + gchar *offset; + + space_count = 0; + length = g_utf8_strlen (string, -1); + offset = g_utf8_offset_to_pointer (string, length); + + while (space_count <= length) + { + gunichar character; + + offset = g_utf8_prev_char (offset); + character = g_utf8_get_char (offset); + + if (!g_unichar_isspace (character)) + { + break; + } + + space_count++; + } + + if (space_count == 0) + { + return g_strdup (string); + } + + return g_utf8_substring (string, 0, length - space_count); +} + char * nautilus_get_common_filename_prefix_from_filenames (GList *filenames, int min_required_len) { + GList *stripped_filenames = NULL; char *common_prefix; char *truncated; int common_prefix_len; - common_prefix = eel_str_get_common_prefix (filenames, min_required_len); + for (GList *i = filenames; i != NULL; i = i->next) + { + gchar *stripped_filename; + + stripped_filename = eel_filename_strip_extension (i->data); + stripped_filenames = g_list_prepend (stripped_filenames, stripped_filename); + } + + common_prefix = eel_str_get_common_prefix (stripped_filenames, min_required_len); if (common_prefix == NULL) { return NULL; } - truncated = eel_filename_strip_extension (common_prefix); - g_free (common_prefix); - common_prefix = truncated; + g_list_free_full (stripped_filenames, g_free); - truncated = eel_str_rtrim_punctuation (common_prefix); + truncated = trim_whitespace (common_prefix); g_free (common_prefix); common_prefix_len = g_utf8_strlen (truncated, -1); diff --git a/test/meson.build b/test/meson.build index 0c7d830d5..f6ad5b007 100644 --- a/test/meson.build +++ b/test/meson.build @@ -16,10 +16,6 @@ test_file_utilities_get_common_filename_prefix = executable ('test-file-utilitie 'test-file-utilities-get-common-filename-prefix.c', dependencies: libnautilus_dep) -test_eel_string_rtrim_punctuation = executable ('test-eel-string-rtrim-punctuation', - 'test-eel-string-rtrim-punctuation.c', - dependencies: libnautilus_dep) - test_eel_string_get_common_prefix = executable ('test-eel-string-get-common-prefix', 'test-eel-string-get-common-prefix.c', dependencies: libnautilus_dep) @@ -27,5 +23,4 @@ test_eel_string_get_common_prefix = executable ('test-eel-string-get-common-pref test ('test-nautilus-search-engine', test_nautilus_search_engine) test ('test-nautilus-directory-async', test_nautilus_directory_async) test ('test-file-utilities-get-common-filename-prefix', test_file_utilities_get_common_filename_prefix) -test ('test-eel-string-rtrim-punctuation', test_eel_string_rtrim_punctuation) test ('test-eel-string-get-common-prefix', test_eel_string_get_common_prefix) diff --git a/test/test-eel-string-rtrim-punctuation.c b/test/test-eel-string-rtrim-punctuation.c deleted file mode 100644 index 526ac9fb4..000000000 --- a/test/test-eel-string-rtrim-punctuation.c +++ /dev/null @@ -1,122 +0,0 @@ -#include - -#include "eel/eel-string.h" - - -static void -test_single_punctuation_character_removed () -{ - char *actual; - actual = eel_str_rtrim_punctuation ("Yossarian-"); - g_assert_cmpstr ("Yossarian", ==, actual); - g_free (actual); -} - -static void -test_tailing_space_is_removed () -{ - char *actual; - actual = eel_str_rtrim_punctuation ("Yossarian "); - g_assert_cmpstr ("Yossarian", ==, actual); - g_free (actual); -} - -static void -test_multiple_punctuation_characters_removed () -{ - char *actual; - actual = eel_str_rtrim_punctuation ("Yossarian-$$!£"); - g_assert_cmpstr ("Yossarian", ==, actual); - g_free (actual); -} - -static void -test_multiple_punctuation_characters_removed_try_all_punctuation_characters () -{ - char *actual; - actual = eel_str_rtrim_punctuation ("Yossarian-`¬!\"£$%^&*()_+-= {}[]:@~;'#<>?,./\\"); - g_assert_cmpstr ("Yossarian", ==, actual); - g_free (actual); -} - -static void -test_punctuation_characters_removed_when_punctuation_in_middle_of_string () -{ - char *actual; - actual = eel_str_rtrim_punctuation ("Yoss,,arian-$$!£"); - g_assert_cmpstr ("Yoss,,arian", ==, actual); - g_free (actual); -} - -static void -test_punctuation_characters_removed_when_prefix_is_single_character () -{ - char *actual; - actual = eel_str_rtrim_punctuation ("Y-$$ !£"); - g_assert_cmpstr ("Y", ==, actual); - g_free (actual); -} - -static void -test_punctuation_characters_removed_when_unicode_characters_are_used () -{ - char *actual; - actual = eel_str_rtrim_punctuation ("Y✺ǨǨǨ-$$ !£"); - g_assert_cmpstr ("Y✺ǨǨǨ", ==, actual); - g_free (actual); -} - -static void -test_when_no_trailing_punctuation () -{ - char *actual; - actual = eel_str_rtrim_punctuation ("Yoss,,arian"); - g_assert_cmpstr ("Yoss,,arian", ==, actual); - g_free (actual); -} - -static void -test_when_single_character_and_no_trailing_punctuation () -{ - char *actual; - actual = eel_str_rtrim_punctuation ("t"); - g_assert_cmpstr ("t", ==, actual); - g_free (actual); -} - -static void -setup_test_suite () -{ - g_test_add_func ("/rtrim-punctuation/1.0", - test_single_punctuation_character_removed); - g_test_add_func ("/rtrim-punctuation/1.1", - test_tailing_space_is_removed); - g_test_add_func ("/rtrim-punctuation/1.2", - test_multiple_punctuation_characters_removed); - g_test_add_func ("/rtrim-punctuation/1.3", - test_multiple_punctuation_characters_removed_try_all_punctuation_characters); - g_test_add_func ("/rtrim-punctuation/1.4", - test_punctuation_characters_removed_when_punctuation_in_middle_of_string); - g_test_add_func ("/rtrim-punctuation/1.5", - test_punctuation_characters_removed_when_prefix_is_single_character); - g_test_add_func ("/rtrim-punctuation/1.6", - test_punctuation_characters_removed_when_unicode_characters_are_used); - - g_test_add_func ("/rtrim-punctuation/2.0", - test_when_no_trailing_punctuation); - g_test_add_func ("/rtrim-punctuation/2.1", - test_when_single_character_and_no_trailing_punctuation); -} - -int -main (int argc, - char *argv[]) -{ - g_test_init (&argc, &argv, NULL); - g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=747907"); - g_test_set_nonfatal_assertions (); - - setup_test_suite (); - - return g_test_run (); -} -- cgit v1.2.1