strsep() question/modification

Nat Ersoz (nat.ersoz@myrio.com)
02 May 2003 08:56:20 -0700


(Please reply to me also, I'm not an LKML subscriber)

strsep() looks a bit busted to to me. It fails to strip out preceeding
delimiters which may occur in front of the token(s) you're looking for.

I don't know if strsep() has been modified since 2.4.20 to fix this (or
perhaps someone will tell me this is the correct behaviour). The
following code is a small userland test app to illustrate the problem.

Thanks for reading,

Nat

=== simple usage:
#define STRSEP strsep /* pick one, to test functionality */
#define STRSEP strsep2

compile... gcc -o test test.c

./test ",,,4,,,5,,," /* STRSEP == strsep */
[1]',,4,,5,,': '' '' '4' '' '5' '' ''
/* note zero lenght tokens returned */

./test ",,4,,5,," /* STRSEP == strsep2 */
[1]' 4 5 ': '4' '5'
/* no more false zero len tokens */

=== code follows (apologies as importance/msglen approaches 0)
#include <stdio.h>

/* move past chars if found in set ct */
static char* strpbrkn(const char * cs,const char * ct)
{
const char *sc1,*sc2;

for( sc1 = cs; *sc1 != '\0'; ++sc1 ) {
for( sc2 = ct; *sc2 != '\0'; ++sc2 ) {
if( *sc1 == *sc2 )
break;
}
if( *sc2 == '\0' ) /* no chars in ct were found */
return(char*)sc1;
}
return NULL;
}

/* unchanged from kernel source string.c */
static char* strpbrk(const char * cs,const char * ct)
{
const char *sc1,*sc2;

for( sc1 = cs; *sc1 != '\0'; ++sc1 ) {
for( sc2 = ct; *sc2 != '\0'; ++sc2 ) {
if( *sc1 == *sc2 )
return(char *) sc1;
}
}
return NULL;
}

/* new strsep function */
char* strsep2(char **s, const char *ct)
{
char *beg = *s, *end;

if( beg == NULL )
return NULL;

beg = strpbrkn( beg, ct );
if( beg ) {
end = strpbrk( beg, ct );
if( end )
*end++ = '\0';
*s = end;
} else
*s = NULL;

return beg;
}

/* same old strsep */
char * strsep(char **s, const char *ct)
{
char *sbegin = *s, *end;

if (sbegin == NULL)
return NULL;

end = strpbrk(sbegin, ct);
if (end)
*end++ = '\0';
*s = end;

return sbegin;
}

#define STRSEP strsep

int main( int argc, char **argv )
{
int i;

const char *delim = " =\t\n\r,";

for( i = 1; i < argc; i++ ) {
char *tok, *ptr = argv[i];

printf( "[%d]'%s': ", i, ptr );

tok = STRSEP( &ptr, delim );
while( tok ) {
printf( "'%s' ", tok );
tok = STRSEP( &ptr, delim );
}
printf( "\n" );
fflush( stdout );
}

return 0;
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/