/*  STRUTIL.C	16-May-00 15:26:19 by Kevin D. Quitt

    String utils missing from pSOS's pREPC
*/
#include    <stdio.h>
#include    <string.h>
#include    <ctype.h>
#include    <stdlib.h>
#include    <errno.h>

#include    "inputdemo.h"
#include    "strutil.h"

#ifdef	LINUX
/*  Case-insensitive, length-limited string compare
*/
int strnicmp( const char *s1, const char *s2, ulong maxlen )
  {
    int	    c	= 0;

    if ( !s1  ||  !s2 )
	return	c;

    while ( maxlen--  &&  *s1  &&  *s2  &&  !c )
	c   = toupper( *s1++ ) - toupper( *s2++ );

    if ( maxlen  ==  (ulong)-1)
	return	c;

    if ( !c )
      {
	if ( *s1 )			/* Anything left in S1? */
	    c++;			/* if so, it must be > */
	if ( *s2 )			/* Similar for s2 */
	    c--;			/* If both or neither end, c=0 */
      }

    return  c;
  }


/*  Case-insensitive, unlimited-length string compare
*/
int stricmp( const char *s1, const char *s2 )
  {
    return  strnicmp( s1, s2, 0xFFFFFFFF );
  }
#endif


/*  Return the pointer to the first non-whitespace character, or NULL if
    none.
*/
char   *skipWhite( char *in )
  {
    while ( !isEmptyString( in )  &&  isspace( *in ))
	in++;

    if ( isEmptyString( in ))
	in  = NULL;

    return  in;
  }

/*  Return the pointer to the first whitespace character, or NULL if none.
*/
char   *toWhite( char *in )
  {
    while ( !isEmptyString( in )  &&  !isspace( *in ))
	in++;

    if ( isEmptyString( in ))
	in  = NULL;

    return  in;
  }


/*  Return the pointer to the first non-whitespace character following
    whitespace, or NULL if none.
*/
char   *pastNextWhite( char *in )
  {
    return  skipWhite( toWhite( in ));
  }


char   *toEOL( char *in )
  {
    if ( in )
	in  += strcspn( in, EOL );

    if ( isEmptyString( in ))
	in  = NULL;

    return  in;
  }


/*  Return the pointer to the first non-whitespace character following
    whitespace, or NULL if none.  The input string is NUL-terminated at the
    first whitespace character.

    This is used to split space-separated paramters in a line.
*/
char   *splitLine( char *in )
  {
    char   *split;

    split   = toWhite( in );
    if ( split )
	*split++    = '\0';

    return  skipWhite( split );
  }

/*  Safety plays for printing strings.
*/
char   *strVal( char *string )
  {
    if ( !string )
	return	"<NULL>";

    return  string;
  }


void	stripComment( char *string )
  {
    int	    quoted  = FALSE;
    int	    ch;

    if ( !string )
	return;

    for ( ; *string; string++ )
      {
	ch  = *string;
	if ( quoted )
	  {
	    if ( ch  ==  '"' )
		quoted	= FALSE;
	    continue;
	  }
	if ( ch  ==  '"' )
	  {
	    quoted	= TRUE;
	    continue;
	  }
	if ((ch  ==  '#')  ||  (ch  ==  '\''))
	  {
	    *string = '\0';
	    return;
	  }
      }
  }

void	stripTerminalWhitespace( char *string )
  {
    size_t  len;

    if ( !string  ||  !*string )  return;

    len	= strlen( string ) - 1;

    while ( len  &&  isspace( string[ len ]))
	string[ len-- ]   = '\0';
  }


int boolVal( char *TrueFalse, int defaultValue )
  {
    int	ch;

    if ( TrueFalse )
      {
	ch  = toupper( *TrueFalse );
	switch( ch )
	  {
	    case    'T':		/* True				*/
	    case    'Y':		/* Yes				*/
	    case    '1':		/* 1				*/
	      {
		return	TRUE;
	      }

	    case    'F':		/* False			*/
	    case    'N':		/* No				*/
	    case    '0':		/* 0				*/
	      {
		return	FALSE;
	      }

	    case    'O':
	      {
		ch  = toupper( TrueFalse[ 1 ] );
		switch( ch )
		  {
		    case    'N':	/* ON				*/
		      {
			return	TRUE;
		      }
		    case    'F':	/* OFf				*/
		      {
			return	FALSE;
		      }
		    default:
		      {
			return	defaultValue;
		      }
		  }
	      }

	    default:
	      {
		return	defaultValue;
	      }

	  }
      }

    return  defaultValue;
  }


int isBoolVal( char *TrueFalse )
  {
    return  boolVal( TrueFalse, 99 )  !=  99;
  }


char   *boolString( int val )
  {
    if ( val )
	return	"TRUE";

    return  "FALSE";
  }






/*  Token/value utilities.

    A token/value string starts with zero or more whitespace characters.
    The token starts at the first non-whitespace character and continues up
    to the first TVBREAK character (or terminating NUL).  The value starts
    at the first non-TVBREAK character and continues to
*/

/*  Return the pointer to the first character that indicates a break in a
    token value pair.  Return NULL if none are found.
*/
char    *toTVBreak( char *in )
  {
    if ( !in )	return	NULL;

    if ( in )
	in  = strpbrk( in, TVBREAK );

    if ( !*in )
	in  = NULL;

    return  in;
  }


/*  Return the pointer to the first character past the break in a token
    value pair, or NULL if we are already at the end of the line.
*/
char    *pastTVBreak( char *in )
  {

    char   *past    = in;

    if ( !in  ||  !*in )		/* If no string or empty string	    */
	return	NULL;			/*  there is no past		    */

    past    += strspn( past, TVBREAK EOL );/* Skip over break, even to NUL  */

    return  past;
  }


/*  It's a token value pair optionally has a token, followed by one or more
    TVBREAK characters (space, tab, equal, comma), optionally followed by
    non-whitespace characters.
*/
int isTVPair( char *tvstring )
  {
    if ( !tvstring )
	return	0;

    return  !!strpbrk( tvstring, TVBREAK );
  }






/*  Split the input string into its token and value strings.  The original
    string is modified by writing NULs to terminate the token and value
    strings.

    If the string is not a TV pair, point the token to the string and NULL
    the pointer to the value.
*/
int	splitTVPair( char *tvpair, char **token, char **value )
  {
    char   *endt, *endv;
    int	quoted	= FALSE;

    if ( !token  ||  !value )
	return	FALSE;

    *token  = NULL;
    *value  = NULL;

    if ( !isTVPair( tvpair ))
      {
	*token	= tvpair;
	return	TRUE;
      }

    endt    = toTVBreak( tvpair );	/* Is there a token?		    */
    if ( endt  !=  tvpair )		/* Apparently so		    */
      {
	*token	= tvpair;		/* Start of token		    */
	tvpair	= endt;
      }
    else
	endt	= NULL;

    tvpair  = pastTVBreak( tvpair );	/* Start of value		    */
    if ( *tvpair  ==  '"' )
      {
	quoted	= TRUE;
	tvpair++;
      }
    *value  = tvpair;
    endv    = toEOL( tvpair );

    if ( endt )
	*endt	= NUL;			/* NUL terminate token string	    */
    if ( endv )
	*endv	= NUL;			/* NUL terminate value string	    */

    if ( quoted )			/* Unquote			    */
      {
	char   *toquote	= *value;
	int len	= strlen( toquote ) - 1;
	if ( toquote[ len ]  ==  '"' )
	    toquote[ len ]  = NUL;
      }

    return  TRUE;
  }

