Hi,

I had a report that --ignore-file-name-case doesn't work as expected:
  https://bugzilla.redhat.com/show_bug.cgi?id=719001

Here's a patch against 2.8.1 that works for me.  There are two changes:

1. Make compare_names() return 0 if the filenames match
case-insensitively, but keep compare_names_for_qsort() stable.

2. When one argument is a directory and another is not, search within
the directory for a case-insensitive filename match.

Does this approach look acceptable?  If so I can port the patch to 3.0.

Tim.
*/

diff -up diffutils-2.8.1/src/diff.h.ignore-file-name-case diffutils-2.8.1/src/diff.h
--- diffutils-2.8.1/src/diff.h.ignore-file-name-case	2011-08-04 14:21:36.323824356 +0100
+++ diffutils-2.8.1/src/diff.h	2011-08-04 14:21:36.372823480 +0100
@@ -336,6 +336,7 @@ void print_context_script (struct change
 
 /* dir.c */
 int diff_dirs (struct comparison const *, int (*) (struct comparison const *, char const *, char const *));
+char *find_dir_file_pathname (char const *, char const *, bool);
 
 /* ed.c */
 void print_ed_script (struct change *);
diff -up diffutils-2.8.1/src/dir.c.ignore-file-name-case diffutils-2.8.1/src/dir.c
--- diffutils-2.8.1/src/dir.c.ignore-file-name-case	2002-03-01 07:44:17.000000000 +0000
+++ diffutils-2.8.1/src/dir.c	2011-08-04 14:27:48.141180524 +0100
@@ -146,11 +146,7 @@ static int
 compare_names (char const *name1, char const *name2)
 {
   if (ignore_file_name_case)
-    {
-      int r = strcasecmp (name1, name2);
-      if (r)
-	return r;
-    }
+    return strcasecmp (name1, name2);
 
   if (locale_specific_sorting)
     {
@@ -177,7 +173,17 @@ compare_names_for_qsort (void const *fil
 {
   char const *const *f1 = file1;
   char const *const *f2 = file2;
-  return compare_names (*f1, *f2);
+  int r = compare_names (*f1, *f2);
+  if (!r && ignore_file_name_case)
+    {
+      /* Make sure we have a stable sort.  */
+      if (locale_specific_sorting)
+	r = strcoll (*f1, *f2);
+      else
+	r = file_name_cmp (*f1, *f2);
+    }
+
+  return r;
 }
 
 /* Compare the contents of two directories named in CMP.
@@ -287,3 +293,32 @@ dir_loop (struct comparison const *cmp, 
       return 1;
   return 0;
 }
+
+/* Find a matching filename in a directory.  */
+
+char *
+find_dir_file_pathname (char const *dir, char const *file, bool omit_slash)
+{
+  struct file_data filedata;
+  struct dirdata dirdata;
+  char *val = NULL;
+  int i;
+
+  filedata.name = dir;
+  filedata.desc = 0;
+  if (! dir_read (&filedata, &dirdata))
+    return NULL;
+
+  for (i = 0; i < dirdata.nnames; i++)
+    if (compare_names (dirdata.names[i], file) == 0)
+      {
+	val = concat (dir, "/" + omit_slash, dirdata.names[i]);
+	break;
+      }
+
+  if (dirdata.names)
+    free (dirdata.names);
+  if (dirdata.data)
+    free (dirdata.data);
+  return val;
+}
diff -up diffutils-2.8.1/src/util.c.ignore-file-name-case diffutils-2.8.1/src/util.c
--- diffutils-2.8.1/src/util.c.ignore-file-name-case	2011-08-04 14:21:36.331824213 +0100
+++ diffutils-2.8.1/src/util.c	2011-08-04 14:21:36.374823444 +0100
@@ -1023,6 +1023,9 @@ dir_file_pathname (char const *dir, char
 {
   char const *base = base_name (dir);
   bool omit_slash = !*base || base[strlen (base) - 1] == '/';
+  if (ignore_file_name_case)
+    return find_dir_file_pathname (dir, file, omit_slash);
+
   return concat (dir, "/" + omit_slash, file);
 }
 

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to