fix g_utf8_collate_key_for_filename



Hello,

I've made (or at least tried to) a fix for
g_utf8_collate_key_for_filename function which now sorts all strings
containing a number case-sensitively.
I'm new to all of this (C,Glib, even open source development) so I want
to ask you if it's ok.

Here is the patch:

From ae518c05b679300bede4425e7239209b222b1e03 Mon Sep 17 00:00:00 2001
From: hynner <hynner seznam cz>
Date: Sat, 16 May 2015 12:32:44 +0200
Subject: [PATCH] fix g_utf8_collate_key_for_filename case-sensitivness

g_utf_8_collate_key_for_filename doesn't handle collation's
case-sensitivness correctly. Since it concatenates g_utf8_collate_key
of substrings it effectively produces case-sensitive collation key
even for case-insensitive locales. This patch corrects that by
converting the input string to lowercase for case-insensitive locales
and working with that instead of the original string. To provide
additional case information even for case-insensitive collations it
appends g_utf8_collate_key of the original string at the end
of the result.

Behaviour for case-sensitive locales should stay the same.

Bug: https://bugzilla.gnome.org/show_bug.cgi?id=352237
---
 glib/gunicollate.c | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/glib/gunicollate.c b/glib/gunicollate.c
index f9d8b3d..eef82cc 100644
--- a/glib/gunicollate.c
+++ b/glib/gunicollate.c
@@ -507,9 +507,15 @@ g_utf8_collate_key_for_filename (const gchar *str,
   const gchar *p;
   const gchar *prev;
   const gchar *end;
+  gchar *work_str;
   gchar *collate_key;
   gint digits;
   gint leading_zeros;
+  /* find out whether current collation is case_sensitive */
+  gboolean case_sensitive = strcoll ("aa","Ab") > 0 || strcoll ("Aa",
"ab") > 0;
+
+  if (!case_sensitive)
+    work_str = g_utf8_strdown (str,len);
    /*
    * How it works:
@@ -563,10 +569,11 @@ g_utf8_collate_key_for_filename (const gchar *str,
   result = g_string_sized_new (len * 2);
   append = g_string_sized_new (0);
 -  end = str + len;
+  prev = p = ((case_sensitive) ? str : work_str);
+  end = prev + len;
    /* No need to use utf8 functions, since we're only looking for ascii
chars */
-  for (prev = p = str; p < end; p++)
+  for (; p < end; p++)
     {
       switch (*p)
     {
@@ -671,7 +678,13 @@ g_utf8_collate_key_for_filename (const gchar *str,
     g_string_append (result, append->str);
   g_string_free (append, TRUE);
-
+  if (!case_sensitive)
+  {
+    collate_key = g_utf8_collate_key (str,len);
+    g_string_append (result,collate_key);
+    g_free (collate_key);
+    g_free (work_str);
+  }
   return g_string_free (result, FALSE);
 #else /* HAVE_CARBON */
   return carbon_collate_key_for_filename (str, len);
-- 
2.1.0



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