[uClibc]uClibc : strcasecmp() behaviour incorrect

Brian Stafford brian.stafford at office-logic.com
Tue Feb 12 12:38:14 UTC 2002


On Tue, 12 February 11:15 Mark Robson wrote:
> On Tuesday 12 February 2002  9:19 am, Brian Stafford wrote:
> > On Mon, 11 February 21:30 Mark Robson wrote:
> > > strcasecmp() does not behave in the same manner as in glibc, and probably
> > > incorrectly.
> >
> > I've just checked my copy of SUSv2.  It states
> >
> >      Upon completion, strcasecmp() returns an integer greater than, equal
> >      to or less than 0, if the string pointed to by s1 is, ignoring case,
> >      greater than, equal to or less than the string pointed to by s2
> >      respectively.
> 
> Brian,
> 	This is the problem.
> 
> In the program I sent, the third test case, "goodbye" and "Hello" , the
> behaviour is wrong
> 
> the string "goodbye" should come earlier in the alphabet, so be considered
> "less", so it should return a negative value. Nevertheless, it returns a
> positive value.

oops, sorry ... my last message was a bit vague.  I didn't mean to imply that 
your diagnosis was wrong - on the contrary, I had intended to back you up with 
the normative text from SUSv2.

As it happens, I checked my own implementation of strcasecmp() and 
strncasecmp() from another project in light of your comments and SUS and found 
that I'd made a similar error to the uClibc functions.

I've corrected my own implementation as follows :-

int
strcasecmp (const char *a, const char *b)
{
   register int n;

   while (*a == *b || (n = tolower (*a) - tolower (*b)) == 0)
     {
       if (*a == '\0')
         return 0;
       a++, b++;
     }
   return n;
}


int
strncasecmp (const char *a, const char *b, size_t len)
{
   register int n;

   if (len < 1)
     return 0;
   while (*a == *b || (n = tolower (*a) - tolower (*b)) == 0)
     {
       if (*a == '\0' || --len < 1)
         return 0;
       a++, b++;
     }
   return n;
}

I believe these functions to be correct wrt SUSv2 and my minimal testing so 
far returns the correct results as far as I can tell.  Since I released the 
original versions of these under the LGPL, there would be no problem about 
using these in uClibc.

A final comment: SUSv2 says that strn?casecmp has defined behaviour only for 
the POSIX locale.  I am given to wonder if Tinyfugue is wrong to use 
strcasecmp at all and whether it should use strcoll instead.  strcoll does not 
ignore case but *does* provide dictionary order sorting (at least in some 
locales, e.g. en_GB and en_US but not POSIX).  That is "abc Def Abc" will sort 
in the order "Abc abc Def", providing of course that setlocale (LC_COLLATE, 
""); has been called beforehand.

Regards
Brian Stafford



More information about the uClibc mailing list