This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[RFC] Adding strcasecmp/strncasecmp... functionality to unaligned strcmp
- From: OndÅej BÃlka <neleai at seznam dot cz>
- To: libc-alpha at sourceware dot org
- Date: Fri, 13 Sep 2013 22:53:03 +0200
- Subject: [RFC] Adding strcasecmp/strncasecmp... functionality to unaligned strcmp
- Authentication-results: sourceware.org; auth=none
- References: <20130913200552 dot GA31992 at domone>
Hi,
I tried to gather data also for strcasecmp/strncasecmp and I got
that they are used rarely on my system.
My theory is that when there is difference it would be rare that it is
only difference in case. Tools that I used support that but I do not
have program that spends substantial time in strcasecmp.
If assumptions above are true in general then best course of action
is to do minimal modifications in strcasecmp. A strcmp first produces
bitmask of different characters, then returns differene of first
characters:
if (m) {
return a[ffs (m) - b[ffs (m)];
}
which I would replace by enumerating over all characters as it is likely
we stop at second one.
while (m) {
if (tolower(a[ffs (m)) != tolower(b[ffs (m)))
return tolower(a[ffs (m)) - tolower(b[ffs (m));
if (!a[ffs (m)]) return 0;
m = m & (m-1);
}
A dynamic switching when frequency of false posives is high would be
possible but I require program that would benefit from swiching to write it.
Data? Comments?
For strcasecmp LD_PRELOAD library with following
#include <stdio.h>
int strcasecmp(unsigned char *x,unsigned char *y){
int casecmp=0;
int i=0;
while(1) {
if (x[i]!=y[i])
if (tolower(x[i])==tolower(y[i]))
casecmp++;
else
{fprintf(stderr,"dif chars %i tolower_needed %i\n", i, casecmp+1); return tolower(x[i])-tolower(y[i]);}
if (!x[i]) {fprintf(stderr,"same chars %i tolower_needed %i \n",i, casecmp); return 0;}
i++;
}
return 0;
}
And for strncasecmp LD_PRELOAD library with following
#include <stdio.h>
int strncasecmp(unsigned char *x,unsigned char *y, long n){
int casecmp=0;
int i=0;
for(i=0;i<n;i++) {
if (x[i]!=y[i])
if (tolower(x[i])==tolower(y[i]))
casecmp++;
else
{fprintf(stderr,"dif chars %i tolower_needed %i\n", i, casecmp+1); return tolower(x[i])-tolower(y[i]);}
if (!x[i]) {fprintf(stderr,"same chars %i tolower_needed %i \n",i, casecmp); return 0;}
}
fprintf(stderr,"size chars %i tolower_needed %i \n",i, casecmp);
return 0;
}