strsep() question/modification

From: Nat Ersoz (nat.ersoz@myrio.com)
Date: Fri May 02 2003 - 10:56:20 EST


(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/



This archive was generated by hypermail 2b29 : Wed May 07 2003 - 22:00:16 EST