emacs-devel
[Top][All Lists]
Advanced

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

Re: File name completion with non-ascii filenames


From: Eli Zaretskii
Subject: Re: File name completion with non-ascii filenames
Date: Tue, 18 Dec 2001 15:34:56 +0200 (IST)

On 18 Dec 2001, Niels =?iso-8859-1?q?M=F6ller?= wrote:

>     {
>       int match = len - l;  /* !Here match is assigned 3 */
> 
>       /* Now *--S1 is the unmatching byte.  If it is in the middle of
>          multi-byte form, we must say that the multi-byte character
>          there doesn't match.  */
>       while (match && *--s1 >= 0xA0) match--;
>       /* ! But now it's only 2 */
>       return match;
>     }
> 
> So the bug is that scmp assumes that its argument are multibyte MULE
> strings, and file_name_completion calls it with arguments that are
> latin-1 strings.

Thanks for the footwork.

Handa-san, I think scmp (reproduced in its entirety below) is totally 
inappropriate for comparing multibyte strings: it walks bytes instead of 
characters, it downcases bytes instead of characters, and does the wrong 
thing in the above fragment.  No code except dired.c calls scmp nowadays, 
and dired.c does that for unibyte strings (except for one call which 
needs to be fixed by encoding one of the two strings).

So I think we should declare it suitable for unibyte strings only, remove 
the fragment which caused this specific bug, and update the comment which 
documents the function's purpose accordingly.  Do you agree?


/* Compare exactly LEN chars of strings at S1 and S2,
   ignoring case if appropriate.
   Return -1 if strings match,
   else number of chars that match at the beginning.  */

int
scmp (s1, s2, len)
     register unsigned char *s1, *s2;
     int len;
{
  register int l = len;

  if (completion_ignore_case)
    {
      while (l && DOWNCASE (*s1++) == DOWNCASE (*s2++))
        l--;
    }
  else
    {
      while (l && *s1++ == *s2++)
        l--;
    }
  if (l == 0)
    return -1;
  else
    {
      int match = len - l;

      /* Now *--S1 is the unmatching byte.  If it is in the middle of
         multi-byte form, we must say that the multi-byte character
         there doesn't match.  */
      while (match && *--s1 >= 0xA0) match--;
      return match;
    }
}



reply via email to

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