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);
}
signature.asc
Description: This is a digitally signed message part
