[easytag/wip/application-window: 18/18] Improved scanner functions and added test cases
- From: David King <davidk src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [easytag/wip/application-window: 18/18] Improved scanner functions and added test cases
- Date: Thu, 3 Apr 2014 21:31:54 +0000 (UTC)
commit 1be2f850a10017b4c64d68cba4a2b26a5873a37e
Author: Abhinav <abhijangda hotmail com>
Date: Wed Mar 12 01:21:42 2014 +0530
Improved scanner functions and added test cases
https://bugzilla.gnome.org/show_bug.cgi?id=726108
Makefile.am | 21 ++++++
src/application_window.c | 40 +++++-----
src/scan.c | 154 +++++++++++++++++----------------------
src/scan.h | 8 +-
src/scan_dialog.c | 33 +++++++--
tests/test-scan.c | 180 ++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 319 insertions(+), 117 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index e6d56cc..041b463 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -277,7 +277,28 @@ tests/test-desktop-file-validate.sh: Makefile tests/.dstamp
check_SCRIPTS = \
tests/test-desktop-file-validate.sh
+check_PROGRAMS = \
+ tests/test-scan
+
+tests_test_scan_CPPFLAGS = \
+ -I$(top_srcdir)/src \
+ -I$(top_builddir) \
+ $(DEPRECATED_CPPFLAGS)
+
+tests_test_scan_CFLAGS = \
+ $(WARN_CFLAGS) \
+ $(EASYTAG_CFLAGS)
+
+tests_test_scan_SOURCES = \
+ tests/test-scan.c \
+ src/scan.c
+
+tests_test_scan_LDADD = \
+ $(EASYTAG_LIBS)
+
+# TODO: Use the GLib test runner
TESTS = \
+ $(check_PROGRAMS) \
$(check_SCRIPTS)
endif
diff --git a/src/application_window.c b/src/application_window.c
index a8dc391..ad7c57f 100644
--- a/src/application_window.c
+++ b/src/application_window.c
@@ -137,31 +137,34 @@ Convert_Space_Into_Underscore (GtkWidget *entry)
static void
Convert_All_Uppercase (GtkWidget *entry)
{
- gchar *string = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
+ gchar *res;
+ const gchar *string = gtk_entry_get_text (GTK_ENTRY (entry));
- Scan_Process_Fields_All_Uppercase (string);
- gtk_entry_set_text (GTK_ENTRY (entry), string);
- g_free (string);
+ res = Scan_Process_Fields_All_Uppercase (string);
+ gtk_entry_set_text (GTK_ENTRY (entry), res);
+ g_free (res);
}
static void
Convert_All_Lowercase (GtkWidget *entry)
{
- gchar *string = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
+ gchar *res;
+ const gchar *string = gtk_entry_get_text (GTK_ENTRY (entry));
- Scan_Process_Fields_All_Downcase (string);
- gtk_entry_set_text (GTK_ENTRY (entry), string);
- g_free (string);
+ res = Scan_Process_Fields_All_Downcase (string);
+ gtk_entry_set_text (GTK_ENTRY (entry), res);
+ g_free (res);
}
static void
Convert_Letter_Uppercase (GtkWidget *entry)
{
- gchar *string = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
+ gchar *res;
+ const gchar *string = gtk_entry_get_text (GTK_ENTRY (entry));
- Scan_Process_Fields_Letter_Uppercase (string);
- gtk_entry_set_text (GTK_ENTRY (entry), string);
- g_free (string);
+ res = Scan_Process_Fields_Letter_Uppercase (string);
+ gtk_entry_set_text (GTK_ENTRY (entry), res);
+ g_free (res);
}
static void
@@ -191,15 +194,12 @@ Convert_Remove_Space (GtkWidget *entry)
static void
Convert_Insert_Space (GtkWidget *entry)
{
- // FIX ME : we suppose that it will not grow more than 2 times its size...
- gsize string_length = 2 * strlen (gtk_entry_get_text (GTK_ENTRY (entry)));
- gchar *string = g_malloc (string_length + 1);
- strncpy (string, gtk_entry_get_text (GTK_ENTRY (entry)), string_length);
- string[string_length] = '\0';
+ gchar *res;
+ const gchar *string = (gtk_entry_get_text (GTK_ENTRY (entry)));
- Scan_Process_Fields_Insert_Space (&string);
- gtk_entry_set_text (GTK_ENTRY (entry), string);
- g_free (string);
+ res = Scan_Process_Fields_Insert_Space (string);
+ gtk_entry_set_text (GTK_ENTRY (entry), res);
+ g_free (res);
}
static void
diff --git a/src/scan.c b/src/scan.c
index 54d6d15..e74b8c8 100644
--- a/src/scan.c
+++ b/src/scan.c
@@ -66,39 +66,36 @@ Scan_Process_Fields_Remove_Space (gchar *string)
}
/*
- * The function inserts a space before an uppercase letter
- * It is needed to realloc the memory!
+ * Scan_Process_Fields_Insert_Space:
+ * @string: Input string
+ *
+ * This function will insert space before every uppercase character.
+ *
+ * Returns: A newly allocated string.
*/
-void
-Scan_Process_Fields_Insert_Space (gchar **string)
+gchar *
+Scan_Process_Fields_Insert_Space (const gchar *string)
{
gchar *iter;
gunichar c;
- gint j;
- guint string_length;
- gchar *string1;
-
- // FIX ME : we suppose that it will not grow more than 2 times its size...
- string_length = 2 * strlen(*string);
- //string1 = g_realloc(*string, string_length+1);
- string1 = g_malloc(string_length+1);
- strncpy(string1,*string,string_length);
- string1[string_length]='\0';
- g_free(*string);
- *string = string1;
-
- for (iter = g_utf8_next_char(*string); *iter; iter = g_utf8_next_char(iter)) // At start :
g_utf8_next_char to not consider first "uppercase" letter
+ GString *string1;
+
+ string1 = g_string_new ("");
+ g_string_append_c (string1, *string);
+
+ for (iter = g_utf8_next_char (string); *iter; iter = g_utf8_next_char (iter))
{
- c = g_utf8_get_char(iter);
+ c = g_utf8_get_char (iter);
- if (g_unichar_isupper(c))
+ if (g_unichar_isupper (c))
{
- for (j = strlen(iter); j > 0; j--)
- *(iter + j) = *(iter + j - 1);
- *iter = ' ';
- iter++;
+ g_string_append_c (string1, ' ');
}
+
+ g_string_append_unichar (string1, c);
}
+
+ return g_string_free (string1, FALSE);
}
/*
@@ -148,88 +145,69 @@ Scan_Remove_Spaces (gchar *string)
}
}
-void
-Scan_Process_Fields_All_Uppercase (gchar *string)
+/* Returns a newly-allocated string. */
+gchar *
+Scan_Process_Fields_All_Uppercase (const gchar *string)
{
- gchar *temp;
- gchar temp2[6]; // Must have at least 6 bytes of space
- gunichar c;
-
- for (temp = string; *temp; temp = g_utf8_next_char(temp))
- {
- c = g_utf8_get_char(temp);
- if (g_unichar_islower(c))
- strncpy(temp, temp2, g_unichar_to_utf8(g_unichar_toupper(c), temp2));
- }
+ return g_utf8_strup (string, -1);
}
-void
-Scan_Process_Fields_All_Downcase (gchar *string)
+/* Returns a newly-allocated string. */
+gchar *
+Scan_Process_Fields_All_Downcase (const gchar *string)
{
- gchar *temp;
- gchar temp2[6];
- gunichar c;
-
- for (temp = string; *temp; temp = g_utf8_next_char(temp))
- {
- c = g_utf8_get_char(temp);
- if (g_unichar_isupper(c))
- strncpy(temp, temp2, g_unichar_to_utf8(g_unichar_tolower(c), temp2));
- }
+ return g_utf8_strdown (string, -1);
}
-void
-Scan_Process_Fields_Letter_Uppercase (gchar *string)
+/* Returns a newly-allocated string. */
+gchar *
+Scan_Process_Fields_Letter_Uppercase (const gchar *string)
{
- gchar *temp;
+ const gchar *temp;
gchar temp2[6];
gboolean set_to_upper_case = TRUE;
gunichar c;
- gchar utf8_character[6];
- gchar *word, *word1, *word2;
+ GString *string1;
+
+ string1 = g_string_new ("");
- for (temp = string; *temp; temp = g_utf8_next_char(temp))
+ for (temp = string; *temp; temp = g_utf8_next_char (temp))
{
- c = g_utf8_get_char(temp);
- if (set_to_upper_case && g_unichar_islower(c))
- strncpy(temp, temp2, g_unichar_to_utf8(g_unichar_toupper(c), temp2));
- else if (!set_to_upper_case && g_unichar_isupper(c))
- strncpy(temp, temp2, g_unichar_to_utf8(g_unichar_tolower(c), temp2));
- set_to_upper_case = FALSE; // After the first time, all will be down case
- }
+ gchar *temp3;
+ int l;
- temp = string;
+ c = g_utf8_get_char (temp);
+ l = g_unichar_to_utf8 (c, temp2);
- // Uppercase again the word 'I' in english
- while ( temp )
- {
- word = temp; // Needed if there is only one word
- word1 = g_utf8_strchr(temp,-1,' ');
- word2 = g_utf8_strchr(temp,-1,'_');
-
- // Take the first string found (near beginning of string)
- if (word1 && word2)
- word = MIN(word1,word2);
- else if (word1)
- word = word1;
- else if (word2)
- word = word2;
+ if (set_to_upper_case && g_unichar_islower(c))
+ {
+ temp3 = g_utf8_strup (temp2, l);
+ g_string_append (string1, temp3);
+ g_free (temp3);
+ }
+ else if (!set_to_upper_case && g_unichar_isupper(c))
+ {
+ temp3 = g_utf8_strdown (temp2, l);
+ g_string_append (string1, temp3);
+ g_free (temp3);
+ }
else
- // Last word of the string
- break;
-
- // Go to first character of the word (char. after ' ' or '_')
- word = word+1;
+ {
+ g_string_append_len (string1, temp2, l);
+ }
- // Set uppercase word 'I'
- if (g_ascii_strncasecmp("I ", word, strlen("I ")) == 0)
+ /* Uppercase the word 'I' in english */
+ if (!set_to_upper_case &&
+ (*(temp - 1) == ' ' || *(temp - 1) == '_') &&
+ (*temp == 'i' || *temp == 'I') &&
+ (*(temp + 1) == ' ' || *(temp + 1) == '_'))
{
- c = g_utf8_get_char(word);
- strncpy(word, utf8_character, g_unichar_to_utf8(g_unichar_toupper(c), utf8_character));
+ string1->str [string1->len - 1] = 'I';
}
- temp = word;
+ /* After the first time, all will be lower case. */
+ set_to_upper_case = FALSE;
}
-}
-
+ return g_string_free (string1, FALSE);
+}
diff --git a/src/scan.h b/src/scan.h
index 4ad7b63..b5a9c3d 100644
--- a/src/scan.h
+++ b/src/scan.h
@@ -9,12 +9,12 @@ void Scan_Convert_Underscore_Into_Space (gchar *string);
void Scan_Convert_P20_Into_Space (gchar *string);
void Scan_Convert_Space_Into_Underscore (gchar *string);
void Scan_Process_Fields_Remove_Space (gchar *string);
-void Scan_Process_Fields_Insert_Space (gchar **string);
+gchar* Scan_Process_Fields_Insert_Space (const gchar *string);
void Scan_Process_Fields_Keep_One_Space (gchar *string);
void Scan_Remove_Spaces (gchar *string);
-void Scan_Process_Fields_All_Uppercase (gchar *string);
-void Scan_Process_Fields_All_Downcase (gchar *string);
-void Scan_Process_Fields_Letter_Uppercase (gchar *string);
+gchar* Scan_Process_Fields_All_Uppercase (const gchar *string);
+gchar* Scan_Process_Fields_All_Downcase (const gchar *string);
+gchar* Scan_Process_Fields_Letter_Uppercase (const gchar *string);
G_END_DECLS
diff --git a/src/scan_dialog.c b/src/scan_dialog.c
index 66b8c68..53d1cd0 100644
--- a/src/scan_dialog.c
+++ b/src/scan_dialog.c
@@ -1097,7 +1097,12 @@ Scan_Process_Fields_Functions (EtScanDialog *self, gchar **string)
Scan_Convert_Space_Into_Underscore (*string);
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->process_insert_space_toggle)))
- Scan_Process_Fields_Insert_Space(string);
+ {
+ gchar *res;
+ res = Scan_Process_Fields_Insert_Space (*string);
+ g_free (*string);
+ *string = res;
+ }
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->process_insert_one_space_toggle)))
Scan_Process_Fields_Keep_One_Space(*string);
@@ -1106,13 +1111,28 @@ Scan_Process_Fields_Functions (EtScanDialog *self, gchar **string)
Scan_Convert_Character (self, string);
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->process_all_uppercase_toggle)))
- Scan_Process_Fields_All_Uppercase(*string);
+ {
+ gchar *res;
+ res = Scan_Process_Fields_All_Uppercase (*string);
+ g_free (*string);
+ *string = res;
+ }
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->process_all_lowercase_toggle)))
- Scan_Process_Fields_All_Downcase(*string);
+ {
+ gchar *res;
+ res = Scan_Process_Fields_All_Downcase (*string);
+ g_free (*string);
+ *string = res;
+ }
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->process_first_uppercase_toggle)))
- Scan_Process_Fields_Letter_Uppercase(*string);
+ {
+ gchar *res;
+ res = Scan_Process_Fields_Letter_Uppercase (*string);
+ g_free (*string);
+ *string = res;
+ }
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->process_first_style_uppercase_toggle)))
Scan_Process_Fields_First_Letters_Uppercase (self, *string);
@@ -1859,7 +1879,10 @@ Scan_Process_Fields_First_Letters_Uppercase (EtScanDialog *self, gchar *string)
{
exempt[0] = NULL;
}
- Scan_Process_Fields_All_Downcase(string);
+
+ temp = Scan_Process_Fields_All_Downcase (string);
+ g_free (string);
+ string = temp;
if (!g_utf8_validate(string,-1,NULL))
{
diff --git a/tests/test-scan.c b/tests/test-scan.c
new file mode 100644
index 0000000..b870e83
--- /dev/null
+++ b/tests/test-scan.c
@@ -0,0 +1,180 @@
+#include "scan.h"
+
+/* TODO: Add more test strings, and possibly some performance tests. */
+
+static void
+check_string (gchar *cases, gchar *result)
+{
+ gchar *string1, *string2;
+
+ string1 = g_utf8_normalize (cases, -1, G_NORMALIZE_ALL);
+ string2 = g_utf8_normalize (result, -1, G_NORMALIZE_ALL);
+
+ g_assert_cmpstr (string1, ==, string2);
+
+ g_free (string1);
+ g_free (string2);
+}
+
+static void
+scan_underscore_to_space (void)
+{
+ gsize i;
+ gchar *cases[] = {" ်0STRING ်0_A_B"};
+ gchar *results[] = {" ်0STRING ်0 A B"};
+
+ for (i = 0; i < G_N_ELEMENTS (cases); i++)
+ {
+ gchar *string;
+
+ string = g_strdup (cases[i]);
+ Scan_Convert_Underscore_Into_Space (string);
+ check_string (string, results[i]);
+
+ g_free (string);
+ }
+}
+
+static void
+scan_remove_space (void)
+{
+ gsize i;
+ gchar *cases[] = { " STR ING A B " };
+ gchar *results[] = { "STRINGAB" };
+
+ for (i = 0; i < G_N_ELEMENTS (cases); i++)
+ {
+ gchar *string;
+
+ string = g_strdup (cases[i]);
+ Scan_Process_Fields_Remove_Space (string);
+ check_string (string, results[i]);
+
+ g_free (string);
+ }
+}
+
+static void
+scan_p20_to_space (void)
+{
+ gsize i;
+ gchar *cases[] = { "S%20T%20R%20", "%20ă b %20c", "STЂR%20ING%20A%20B" };
+ gchar *results[] = { "S T R ", " ă b c", "STЂR ING A B" };
+
+ for (i = 0; i < G_N_ELEMENTS (cases); i++)
+ {
+ gchar *string;
+
+ string = g_strdup (cases[i]);
+ Scan_Convert_P20_Into_Space (string);
+ check_string (string, results[i]);
+
+ g_free (string);
+ }
+}
+
+static void
+scan_insert_space (void)
+{
+ gsize i;
+ gchar *cases[] = { "STRINGAB", "StRiNgAb", "tRßiNgAb", "AՄՆ", "bՄԵ", "cՄԻ",
+ "dՎՆ", "eՄԽ", "fꜲ"};
+ gchar *results[] = { "S T R I N G A B", "St Ri Ng Ab", "t Rßi Ng Ab",
+ "A Մ Ն", "b Մ Ե", "c Մ Ի", "d Վ Ն", "e Մ Խ", "f Ꜳ" };
+
+ for (i = 0; i < G_N_ELEMENTS (cases); i++)
+ {
+ gchar *string, *res;
+
+ string = g_strdup (cases[i]);
+ res = Scan_Process_Fields_Insert_Space (string);
+ check_string (res, results[i]);
+
+ g_free (string);
+ g_free (res);
+ }
+}
+
+static void
+scan_all_uppercase (void)
+{
+ gsize i;
+ gchar *cases[] = { "stringab", "tRßiNgAb", "aʼnbcd", "lowΐer", "uppΰer",
+ "sTRINGև", "ᾖᾀ", "pᾖp", "sAfflAs" };
+ gchar *results[] = { "STRINGAB", "TRSSINGAB", "AʼNBCD", "LOWΪ́ER", "UPPΫ́ER",
+ "STRINGԵՒ", "ἮΙἈΙ", "PἮΙP", "SAFFLAS" };
+
+ for (i = 0; i < G_N_ELEMENTS (cases); i++)
+ {
+ gchar *string, *res;
+
+ string = g_strdup (cases[i]);
+ res = Scan_Process_Fields_All_Uppercase (string);
+ check_string (res, results[i]);
+
+ g_free (string);
+ g_free (res);
+ }
+}
+
+static void
+scan_all_lowercase (void)
+{
+ gsize i;
+ gchar *cases[] = { "STRINGAB", "tRßiNgAb", "SMALLß", "AAAԵՒBB", "ʼN",
+ "PΪ́E", "ἮΙ", "Ϋ́E" };
+ gchar *results[] = { "stringab", "trßingab", "smallß", "aaaեւbb", "ʼn",
+ "pΐe", "ἦι", "ΰe" };
+
+ for (i = 0; i < G_N_ELEMENTS (cases); i++)
+ {
+ gchar *string, *res;
+
+ string = g_strdup (cases[i]);
+ res = Scan_Process_Fields_All_Downcase (string);
+ check_string (res, results[i]);
+
+ g_free (string);
+ g_free (res);
+ }
+}
+
+static void
+scan_letter_uppercase (void)
+{
+ gsize i;
+ gchar *cases[] = { "st ri ng in ab", "tr ßi ng ab", "ßr ßi ng ab",
+ "ßr i ng ab", "ßr mi ng ab", "I I ng ab", "ß I ng ab",
+ "ßi ng ab" };
+ gchar *results[] = { "St ri ng in ab", "Tr ßi ng ab", "SSr ßi ng ab",
+ "SSr I ng ab", "SSr mi ng ab", "I I ng ab",
+ "SS I ng ab", "SSi ng ab" };
+
+ for (i = 0; i < G_N_ELEMENTS (cases); i++)
+ {
+ gchar *string, *res;
+
+ string = g_strdup (cases [i]);
+ res = Scan_Process_Fields_Letter_Uppercase (string);
+ check_string (res, results [i]);
+
+ g_free (string);
+ g_free (res);
+ }
+}
+
+int
+main (int argc, char** argv)
+{
+ g_test_init (&argc, &argv, NULL);
+
+ g_test_add_func ("/scan/underscore-to-space", scan_underscore_to_space);
+ g_test_add_func ("/scan/remove-space", scan_remove_space);
+ g_test_add_func ("/scan/P20-to-space", scan_p20_to_space);
+ g_test_add_func ("/scan/insert-space", scan_insert_space);
+ g_test_add_func ("/scan/all-uppercase", scan_all_uppercase);
+ g_test_add_func ("/scan/all-lowercase", scan_all_lowercase);
+ g_test_add_func ("/scan/letter-uppercase", scan_letter_uppercase);
+
+ return g_test_run ();
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]