[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: win32 diff (GNU diffutils) 2.8.1 "--ignore-file-name-case" switch do
From: |
Eli Zaretskii |
Subject: |
Re: win32 diff (GNU diffutils) 2.8.1 "--ignore-file-name-case" switch doesn't work |
Date: |
Sat, 10 Jan 2004 15:48:12 +0200 |
> From: Paul Eggert <address@hidden>
> Date: 10 Jan 2004 01:48:01 -0800
>
> Please report that bug to the people who generated your diffutils
> executables.
Does that mean you, Paul and Stepan, cannot reproduce this problem
with Diffutils 2.8.4 on a GNU/Linux system? Because for me, this
problem exists in both the GNU/Linux build of Diffutils 2.8.4 on
address@hidden:~/diffutils-2.8.4$ uname -a
Linux fencepost 2.4.20-28.9smp #1 SMP Thu Dec 18 13:37:36 EST 2003 i686
unknown
and in the DJGPP builds of Diffutils 2.8 and 2.8.4 running on a
vanilla Windows 98 box. Here's a transcript of a session from the
GNU/Linux box:
address@hidden:~/diffutils-2.8.4$ mkdir ~/fold1
address@hidden:~/diffutils-2.8.4$ touch ~/fold1/fold1.c
address@hidden:~/diffutils-2.8.4$ mkdir ~/fold2
address@hidden:~/diffutils-2.8.4$ touch ~/fold2/fold2.c
address@hidden:~/diffutils-2.8.4$ cat > ~/fold1/TEST.Txt
1
2
3
4
5
^D
address@hidden:~/diffutils-2.8.4$ cat > ~/fold2/test.txt
1
2
3
4
^D
address@hidden:~/diffutils-2.8.4$ ./src/diff --ignore-file-name-case ~/fold1
~/fold2
Only in /home/e/eliz/fold1: fold1.c
Only in /home/e/eliz/fold2: fold2.c
Only in /home/e/eliz/fold1: TEST.Txt
Only in /home/e/eliz/fold2: test.txt
Note that the sort order of the two directories did use a
case-insensitive comparison (thus TEST.Txt is not the first file to
be compared), but the rest of the program somehow ignored the
"--ignore-file-name-case" option.
After some tinkering with GDB, I believe I've found the reason for
this. `dir.c' has this fragment:
if (val == EXIT_SUCCESS)
{
char const **volatile names[2];
names[0] = dirdata[0].names;
names[1] = dirdata[1].names;
/* Use locale-specific sorting if possible, else native byte order. */
locale_specific_sorting = 1;
if (setjmp (failed_strcoll))
locale_specific_sorting = 0;
where locale_specific_sorting is set to 1. Later, when the file
names are compared to determine the value of `nameorder'
/* Loop while files remain in one or both dirs. */
while (*names[0] || *names[1])
{
/* Compare next name in dir 0 with next name in dir 1.
At the end of a dir,
pretend the "next name" in that dir is very large. */
int nameorder = (!*names[0] ? 1 : !*names[1] ? -1
: compare_names (*names[0], *names[1]));
int v1 = (*handle_file) (cmp,
0 < nameorder ? 0 : *names[0]++,
nameorder < 0 ? 0 : *names[1]++);
compare_names is called and does this:
static int
compare_names (char const *name1, char const *name2)
{
if (ignore_file_name_case)
{
int r = strcasecmp (name1, name2);
if (r)
return r;
}
if (locale_specific_sorting)
{
int r;
errno = 0;
r = strcoll (name1, name2);
if (errno)
{
error (0, errno, _("cannot compare file names `%s' and `%s'"),
name1, name2);
longjmp (failed_strcoll, 1);
}
if (r)
return r;
}
strcasecmp returns zero for "TEST.Txt" and "test.txt", so the code
proceeds to the comparison via strcoll, which is case-sensitive.
Therefore, compare_names returns a non-zero value, and this fragment
from `dir.c':
int v1 = (*handle_file) (cmp,
0 < nameorder ? 0 : *names[0]++,
nameorder < 0 ? 0 : *names[1]++);
calls compare_files with the second arg a NULL pointer instead of
*names[1], which causes the "Only in ..." message instead of the
expected diff of TEST.Txt against test.txt.
I don't really understand why does the code set
locale_specific_sorting to a non-zero value unconditionally. Isn't
that a bug to use strcoll if strcasecmp compared the file names to be
equal? Doesn't it seem to defeat the purpose of having the
"--ignore-file-name-case" option in the first place?