bug-gnu-utils
[Top][All Lists]
Advanced

[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?




reply via email to

[Prev in Thread] Current Thread [Next in Thread]