2003-05-02 15:46:14

by Nat Ersoz

[permalink] [raw]
Subject: strsep() question/modification

(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;
}



2003-05-02 16:50:10

by Ulrich Drepper

[permalink] [raw]
Subject: Re: strsep() question/modification

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Nat Ersoz wrote:

> strsep() looks a bit busted to to me.

It is not. This is the expected behavior.

- --
- --------------. ,-. 444 Castro Street
Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA
Red Hat `--' drepper at redhat.com `---------------------------
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)

iD8DBQE+sqRo2ijCOnn/RHQRAsu8AJwNb8TS3uWcc7YZcEc61PNsMKjyFQCgr41w
AROeQLbWcywNV78cgKJPOvw=
=vk1s
-----END PGP SIGNATURE-----