Blame winpr/libwinpr/utils/trio/triostr.c

Packit 1fb8d4
/*************************************************************************
Packit 1fb8d4
 *
Packit 1fb8d4
 * $Id: triostr.c,v 1.36 2010/01/26 13:02:02 breese Exp $
Packit 1fb8d4
 *
Packit 1fb8d4
 * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
Packit 1fb8d4
 *
Packit 1fb8d4
 * Permission to use, copy, modify, and distribute this software for any
Packit 1fb8d4
 * purpose with or without fee is hereby granted, provided that the above
Packit 1fb8d4
 * copyright notice and this permission notice appear in all copies.
Packit 1fb8d4
 *
Packit 1fb8d4
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
Packit 1fb8d4
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
Packit 1fb8d4
 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
Packit 1fb8d4
 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
Packit 1fb8d4
 *
Packit 1fb8d4
 ************************************************************************/
Packit 1fb8d4
Packit 1fb8d4
/*************************************************************************
Packit 1fb8d4
 * Include files
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#if defined(HAVE_CONFIG_H)
Packit 1fb8d4
# include <config.h>
Packit 1fb8d4
#endif
Packit 1fb8d4
#include <assert.h>
Packit 1fb8d4
#include <stdlib.h>
Packit 1fb8d4
#include <string.h>
Packit 1fb8d4
#include <ctype.h>
Packit 1fb8d4
#include "triodef.h"
Packit 1fb8d4
#include "triostr.h"
Packit 1fb8d4
#if defined(TRIO_FUNC_TO_LONG_DOUBLE)
Packit 1fb8d4
# define USE_MATH
Packit 1fb8d4
#endif
Packit 1fb8d4
#if defined(USE_MATH)
Packit 1fb8d4
# include <math.h>
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*************************************************************************
Packit 1fb8d4
 * Definitions
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#if !defined(TRIO_PUBLIC_STRING)
Packit 1fb8d4
# define TRIO_PUBLIC_STRING TRIO_PUBLIC
Packit 1fb8d4
#endif
Packit 1fb8d4
#if !defined(TRIO_PRIVATE_STRING)
Packit 1fb8d4
# define TRIO_PRIVATE_STRING TRIO_PRIVATE
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if !defined(NULL)
Packit 1fb8d4
# define NULL 0
Packit 1fb8d4
#endif
Packit 1fb8d4
#if !defined(NIL)
Packit 1fb8d4
# define NIL ((char)0)
Packit 1fb8d4
#endif
Packit 1fb8d4
#if !defined(FALSE)
Packit 1fb8d4
# define FALSE (1 == 0)
Packit 1fb8d4
# define TRUE (! FALSE)
Packit 1fb8d4
#endif
Packit 1fb8d4
#if !defined(BOOLEAN_T)
Packit 1fb8d4
# define BOOLEAN_T int
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if defined(USE_MATH)
Packit 1fb8d4
# if defined(PREDEF_STANDARD_C99)
Packit 1fb8d4
#  if defined(TRIO_COMPILER_DECC)
Packit 1fb8d4
#   if (TRIO_COMPILER_DECC - 0 > 80000000)
Packit 1fb8d4
/*
Packit 1fb8d4
 * The OSF/1 runtime that comes with the DECC compiler does not support
Packit 1fb8d4
 * hexfloats conversion.
Packit 1fb8d4
 */
Packit 1fb8d4
#    define USE_STRTOD
Packit 1fb8d4
#    define USE_STRTOF
Packit 1fb8d4
#   endif
Packit 1fb8d4
#  else
Packit 1fb8d4
#   define USE_STRTOD
Packit 1fb8d4
#   define USE_STRTOF
Packit 1fb8d4
#  endif
Packit 1fb8d4
# else
Packit 1fb8d4
#  if defined(TRIO_COMPILER_VISUALC)
Packit 1fb8d4
#   define USE_STRTOD
Packit 1fb8d4
#  endif
Packit 1fb8d4
#endif
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if defined(TRIO_PLATFORM_UNIX)
Packit 1fb8d4
# if defined(PREDEF_STANDARD_UNIX95)
Packit 1fb8d4
#  define USE_STRCASECMP
Packit 1fb8d4
#  define USE_STRNCASECMP
Packit 1fb8d4
# endif
Packit 1fb8d4
# if defined(TRIO_PLATFORM_SUNOS)
Packit 1fb8d4
#  define USE_SYS_ERRLIST
Packit 1fb8d4
# else
Packit 1fb8d4
#  define USE_STRERROR
Packit 1fb8d4
# endif
Packit 1fb8d4
# if defined(TRIO_PLATFORM_QNX)
Packit 1fb8d4
#  define strcasecmp(x,y) stricmp(x,y)
Packit 1fb8d4
#  define strncasecmp(x,y,n) strnicmp(x,y,n)
Packit 1fb8d4
# endif
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if defined(TRIO_PLATFORM_WIN32)
Packit 1fb8d4
# define USE_STRCASECMP
Packit 1fb8d4
# if defined(TRIO_PLATFORM_WINCE)
Packit 1fb8d4
#  define strcasecmp(x,y) _stricmp(x,y)
Packit 1fb8d4
# else
Packit 1fb8d4
#  define strcasecmp(x,y) _stricmp(x,y)
Packit 1fb8d4
# endif
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if !defined(HAVE_CONFIG_H)
Packit 1fb8d4
# if !(defined(TRIO_PLATFORM_SUNOS))
Packit 1fb8d4
#  define HAVE_TOLOWER
Packit 1fb8d4
#  define HAVE_TOUPPER
Packit 1fb8d4
# endif
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if defined(USE_MATH) && !defined(TRIO_NO_POWL)
Packit 1fb8d4
# if !defined(HAVE_POWL)
Packit 1fb8d4
#  if defined(PREDEF_STANDARD_C99) \
Packit 1fb8d4
   || defined(PREDEF_STANDARD_UNIX03)
Packit 1fb8d4
#   define HAVE_POWL
Packit 1fb8d4
#  else
Packit 1fb8d4
#   if defined(TRIO_COMPILER_VISUALC)
Packit 1fb8d4
#    if defined(powl)
Packit 1fb8d4
#     define HAVE_POWL
Packit 1fb8d4
#    endif
Packit 1fb8d4
#   endif
Packit 1fb8d4
#  endif
Packit 1fb8d4
# endif
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if defined(HAVE_POWL)
Packit 1fb8d4
# define trio_powl(x,y) powl((x),(y))
Packit 1fb8d4
#else
Packit 1fb8d4
# define trio_powl(x,y) pow((double)(x),(double)(y))
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if defined(TRIO_FUNC_TO_UPPER) \
Packit 1fb8d4
 || (defined(TRIO_FUNC_EQUAL) && !defined(USE_STRCASECMP)) \
Packit 1fb8d4
 || (defined(TRIO_FUNC_EQUAL_MAX) && !defined(USE_STRNCASECMP)) \
Packit 1fb8d4
 || defined(TRIO_FUNC_MATCH) \
Packit 1fb8d4
 || defined(TRIO_FUNC_TO_LONG_DOUBLE) \
Packit 1fb8d4
 || defined(TRIO_FUNC_UPPER)
Packit 1fb8d4
# define TRIO_FUNC_INTERNAL_TO_UPPER
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*************************************************************************
Packit 1fb8d4
 * Structures
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
struct _trio_string_t
Packit 1fb8d4
{
Packit 1fb8d4
  char *content;
Packit 1fb8d4
  size_t length;
Packit 1fb8d4
  size_t allocated;
Packit 1fb8d4
};
Packit 1fb8d4
Packit 1fb8d4
/*************************************************************************
Packit 1fb8d4
 * Constants
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#if !defined(TRIO_EMBED_STRING)
Packit 1fb8d4
/* Unused but kept for reference */
Packit 1fb8d4
/* static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c,v 1.36 2010/01/26 13:02:02 breese Exp $"; */
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*************************************************************************
Packit 1fb8d4
 * Static String Functions
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#if defined(TRIO_DOCUMENTATION)
Packit 1fb8d4
# include "doc/doc_static.h"
Packit 1fb8d4
#endif
Packit 1fb8d4
/** @addtogroup StaticStrings
Packit 1fb8d4
    @{
Packit 1fb8d4
*/
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * internal_duplicate_max
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_DUPLICATE) \
Packit 1fb8d4
 || defined(TRIO_FUNC_DUPLICATE_MAX) \
Packit 1fb8d4
 || defined(TRIO_FUNC_STRING_DUPLICATE) \
Packit 1fb8d4
 || defined(TRIO_FUNC_XSTRING_DUPLICATE)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PRIVATE_STRING char *
Packit 1fb8d4
internal_duplicate_max
Packit 1fb8d4
TRIO_ARGS2((source, size),
Packit 1fb8d4
	   TRIO_CONST char *source,
Packit 1fb8d4
	   size_t size)
Packit 1fb8d4
{
Packit 1fb8d4
  char *target;
Packit 1fb8d4
Packit 1fb8d4
  assert(source);
Packit 1fb8d4
Packit 1fb8d4
  /* Make room for string plus a terminating zero */
Packit 1fb8d4
  size++;
Packit 1fb8d4
  target = trio_create(size);
Packit 1fb8d4
  if (target)
Packit 1fb8d4
    {
Packit 1fb8d4
      trio_copy_max(target, size, source);
Packit 1fb8d4
    }
Packit 1fb8d4
  return target;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * internal_string_alloc
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_CREATE) \
Packit 1fb8d4
 || defined(TRIO_FUNC_STRING_DUPLICATE) \
Packit 1fb8d4
 || defined(TRIO_FUNC_XSTRING_DUPLICATE)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PRIVATE_STRING trio_string_t *
Packit 1fb8d4
internal_string_alloc(TRIO_NOARGS)
Packit 1fb8d4
{
Packit 1fb8d4
  trio_string_t *self;
Packit 1fb8d4
  
Packit 1fb8d4
  self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t));
Packit 1fb8d4
  if (self)
Packit 1fb8d4
    {
Packit 1fb8d4
      self->content = NULL;
Packit 1fb8d4
      self->length = 0;
Packit 1fb8d4
      self->allocated = 0;
Packit 1fb8d4
    }
Packit 1fb8d4
  return self;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * internal_string_grow
Packit 1fb8d4
 *
Packit 1fb8d4
 * The size of the string will be increased by 'delta' characters. If
Packit 1fb8d4
 * 'delta' is zero, the size will be doubled.
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_CREATE) \
Packit 1fb8d4
 || defined(TRIO_FUNC_STRING_APPEND) \
Packit 1fb8d4
 || defined(TRIO_FUNC_XSTRING_APPEND) \
Packit 1fb8d4
 || defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PRIVATE_STRING BOOLEAN_T
Packit 1fb8d4
internal_string_grow
Packit 1fb8d4
TRIO_ARGS2((self, delta),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   size_t delta)
Packit 1fb8d4
{
Packit 1fb8d4
  BOOLEAN_T status = FALSE;
Packit 1fb8d4
  char *new_content;
Packit 1fb8d4
  size_t new_size;
Packit 1fb8d4
Packit 1fb8d4
  new_size = (delta == 0)
Packit 1fb8d4
    ? ( (self->allocated == 0) ? 1 : self->allocated * 2 )
Packit 1fb8d4
    : self->allocated + delta;
Packit 1fb8d4
  
Packit 1fb8d4
  new_content = (char *)TRIO_REALLOC(self->content, new_size);
Packit 1fb8d4
  if (new_content)
Packit 1fb8d4
    {
Packit 1fb8d4
      self->content = new_content;
Packit 1fb8d4
      self->allocated = new_size;
Packit 1fb8d4
      status = TRUE;
Packit 1fb8d4
    }
Packit 1fb8d4
  return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * internal_string_grow_to
Packit 1fb8d4
 *
Packit 1fb8d4
 * The size of the string will be increased to 'length' plus one characters.
Packit 1fb8d4
 * If 'length' is less than the original size, the original size will be
Packit 1fb8d4
 * used (that is, the size of the string is never decreased).
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_APPEND) \
Packit 1fb8d4
 || defined(TRIO_FUNC_XSTRING_APPEND) \
Packit 1fb8d4
 || defined(TRIO_FUNC_XSTRING_APPEND_MAX)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PRIVATE_STRING BOOLEAN_T
Packit 1fb8d4
internal_string_grow_to
Packit 1fb8d4
TRIO_ARGS2((self, length),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   size_t length)
Packit 1fb8d4
{
Packit 1fb8d4
  length++; /* Room for terminating zero */
Packit 1fb8d4
  return (self->allocated < length)
Packit 1fb8d4
    ? internal_string_grow(self, length - self->allocated)
Packit 1fb8d4
    : TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if defined(TRIO_FUNC_INTERNAL_TO_UPPER)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PRIVATE_STRING TRIO_INLINE int
Packit 1fb8d4
internal_to_upper
Packit 1fb8d4
TRIO_ARGS1((source),
Packit 1fb8d4
	   int source)
Packit 1fb8d4
{
Packit 1fb8d4
# if defined(HAVE_TOUPPER)
Packit 1fb8d4
  
Packit 1fb8d4
  return toupper(source);
Packit 1fb8d4
  
Packit 1fb8d4
# else
Packit 1fb8d4
Packit 1fb8d4
  /* Does not handle locales or non-contiguous alphabetic characters */
Packit 1fb8d4
  return ((source >= (int)'a') && (source <= (int)'z'))
Packit 1fb8d4
    ? source - 'a' + 'A'
Packit 1fb8d4
    : source;
Packit 1fb8d4
  
Packit 1fb8d4
# endif
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Create new string.
Packit 1fb8d4
Packit 1fb8d4
   @param size Size of new string.
Packit 1fb8d4
   @return Pointer to string, or NULL if allocation failed.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_CREATE)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING char *
Packit 1fb8d4
trio_create
Packit 1fb8d4
TRIO_ARGS1((size),
Packit 1fb8d4
	   size_t size)
Packit 1fb8d4
{
Packit 1fb8d4
  return (char *)TRIO_MALLOC(size);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Destroy string.
Packit 1fb8d4
Packit 1fb8d4
   @param string String to be freed.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_DESTROY)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING void
Packit 1fb8d4
trio_destroy
Packit 1fb8d4
TRIO_ARGS1((string),
Packit 1fb8d4
	   char *string)
Packit 1fb8d4
{
Packit 1fb8d4
  if (string)
Packit 1fb8d4
    {
Packit 1fb8d4
      TRIO_FREE(string);
Packit 1fb8d4
    }
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Count the number of characters in a string.
Packit 1fb8d4
Packit 1fb8d4
   @param string String to measure.
Packit 1fb8d4
   @return Number of characters in @p string.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_LENGTH)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING size_t
Packit 1fb8d4
trio_length
Packit 1fb8d4
TRIO_ARGS1((string),
Packit 1fb8d4
	   TRIO_CONST char *string)
Packit 1fb8d4
{
Packit 1fb8d4
  return strlen(string);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Count at most @p max characters in a string.
Packit 1fb8d4
Packit 1fb8d4
   @param string String to measure.
Packit 1fb8d4
   @param max Maximum number of characters to count.
Packit 1fb8d4
   @return The maximum value of @p max and number of characters in @p string.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_LENGTH_MAX)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING size_t
Packit 1fb8d4
trio_length_max
Packit 1fb8d4
TRIO_ARGS2((string, max),
Packit 1fb8d4
	   TRIO_CONST char *string,
Packit 1fb8d4
	   size_t max)
Packit 1fb8d4
{
Packit 1fb8d4
  size_t i;
Packit 1fb8d4
Packit 1fb8d4
  for (i = 0; i < max; ++i)
Packit 1fb8d4
    {
Packit 1fb8d4
      if (string[i] == 0)
Packit 1fb8d4
	break;
Packit 1fb8d4
    }
Packit 1fb8d4
  return i;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Append @p source at the end of @p target.
Packit 1fb8d4
   
Packit 1fb8d4
   @param target Target string.
Packit 1fb8d4
   @param source Source string.
Packit 1fb8d4
   @return Boolean value indicating success or failure.
Packit 1fb8d4
   
Packit 1fb8d4
   @pre @p target must point to a memory chunk with sufficient room to
Packit 1fb8d4
   contain the @p target string and @p source string.
Packit 1fb8d4
   @pre No boundary checking is performed, so insufficient memory will
Packit 1fb8d4
   result in a buffer overrun.
Packit 1fb8d4
   @post @p target will be zero terminated.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_APPEND)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_append
Packit 1fb8d4
TRIO_ARGS2((target, source),
Packit 1fb8d4
	   char *target,
Packit 1fb8d4
	   TRIO_CONST char *source)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(target);
Packit 1fb8d4
  assert(source);
Packit 1fb8d4
  
Packit 1fb8d4
  return (strcat(target, source) != NULL);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Append at most @p max characters from @p source to @p target.
Packit 1fb8d4
   
Packit 1fb8d4
   @param target Target string.
Packit 1fb8d4
   @param max Maximum number of characters to append.
Packit 1fb8d4
   @param source Source string.
Packit 1fb8d4
   @return Boolean value indicating success or failure.
Packit 1fb8d4
   
Packit 1fb8d4
   @pre @p target must point to a memory chuck with sufficient room to
Packit 1fb8d4
   contain the @p target string and the @p source string (at most @p max
Packit 1fb8d4
   characters).
Packit 1fb8d4
   @pre No boundary checking is performed, so insufficient memory will
Packit 1fb8d4
   result in a buffer overrun.
Packit 1fb8d4
   @post @p target will be zero terminated.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_APPEND_MAX)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_append_max
Packit 1fb8d4
TRIO_ARGS3((target, max, source),
Packit 1fb8d4
	   char *target,
Packit 1fb8d4
	   size_t max,
Packit 1fb8d4
	   TRIO_CONST char *source)
Packit 1fb8d4
{
Packit 1fb8d4
  size_t length;
Packit 1fb8d4
  
Packit 1fb8d4
  assert(target);
Packit 1fb8d4
  assert(source);
Packit 1fb8d4
Packit 1fb8d4
  length = trio_length(target);
Packit 1fb8d4
  
Packit 1fb8d4
  if (max > length)
Packit 1fb8d4
    {
Packit 1fb8d4
      strncat(target, source, max - length - 1);
Packit 1fb8d4
    }
Packit 1fb8d4
  return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Determine if a string contains a substring.
Packit 1fb8d4
Packit 1fb8d4
   @param string String to be searched.
Packit 1fb8d4
   @param substring String to be found.
Packit 1fb8d4
   @return Boolean value indicating success or failure.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_CONTAINS)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_contains
Packit 1fb8d4
TRIO_ARGS2((string, substring),
Packit 1fb8d4
	   TRIO_CONST char *string,
Packit 1fb8d4
	   TRIO_CONST char *substring)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(string);
Packit 1fb8d4
  assert(substring);
Packit 1fb8d4
  
Packit 1fb8d4
  return (0 != strstr(string, substring));
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Copy @p source to @p target.
Packit 1fb8d4
   
Packit 1fb8d4
   @param target Target string.
Packit 1fb8d4
   @param source Source string.
Packit 1fb8d4
   @return Boolean value indicating success or failure.
Packit 1fb8d4
   
Packit 1fb8d4
   @pre @p target must point to a memory chunk with sufficient room to
Packit 1fb8d4
   contain the @p source string.
Packit 1fb8d4
   @pre No boundary checking is performed, so insufficient memory will
Packit 1fb8d4
   result in a buffer overrun.
Packit 1fb8d4
   @post @p target will be zero terminated.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_COPY)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_copy
Packit 1fb8d4
TRIO_ARGS2((target, source),
Packit 1fb8d4
	   char *target,
Packit 1fb8d4
	   TRIO_CONST char *source)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(target);
Packit 1fb8d4
  assert(source);
Packit 1fb8d4
     
Packit 1fb8d4
  (void)strcpy(target, source);
Packit 1fb8d4
  return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Copy at most @p max - 1 characters from @p source to @p target.
Packit 1fb8d4
   
Packit 1fb8d4
   @param target Target string.
Packit 1fb8d4
   @param max Maximum number of characters to append (one of which is
Packit 1fb8d4
   a NUL terminator).  In other words @p source must point to at least
Packit 1fb8d4
   @p max - 1 bytes, but @p target must point to at least @p max
Packit 1fb8d4
   bytes.
Packit 1fb8d4
   @param source Source string.
Packit 1fb8d4
   @return Boolean value indicating success or failure.
Packit 1fb8d4
   
Packit 1fb8d4
   @pre @p target must point to a memory chunk with sufficient room to
Packit 1fb8d4
   contain the @p source string and a NUL terminator (at most @p max
Packit 1fb8d4
   bytes total).
Packit 1fb8d4
   @pre No boundary checking is performed, so insufficient memory will
Packit 1fb8d4
   result in a buffer overrun.
Packit 1fb8d4
   @post @p target will be zero terminated.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_COPY_MAX)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_copy_max
Packit 1fb8d4
TRIO_ARGS3((target, max, source),
Packit 1fb8d4
	   char *target,
Packit 1fb8d4
	   size_t max,
Packit 1fb8d4
	   TRIO_CONST char *source)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(target);
Packit 1fb8d4
  assert(source);
Packit 1fb8d4
  assert(max > 0); /* Includes != 0 */
Packit 1fb8d4
Packit 1fb8d4
  (void)strncpy(target, source, max - 1);
Packit 1fb8d4
  target[max - 1] = (char)0;
Packit 1fb8d4
  return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Duplicate @p source.
Packit 1fb8d4
   
Packit 1fb8d4
   @param source Source string.
Packit 1fb8d4
   @return A copy of the @p source string.
Packit 1fb8d4
   
Packit 1fb8d4
   @post @p target will be zero terminated.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_DUPLICATE)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING char *
Packit 1fb8d4
trio_duplicate
Packit 1fb8d4
TRIO_ARGS1((source),
Packit 1fb8d4
	   TRIO_CONST char *source)
Packit 1fb8d4
{
Packit 1fb8d4
  return internal_duplicate_max(source, trio_length(source));
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Duplicate at most @p max characters of @p source.
Packit 1fb8d4
   
Packit 1fb8d4
   @param source Source string.
Packit 1fb8d4
   @param max Maximum number of characters to duplicate.
Packit 1fb8d4
   @return A copy of the @p source string.
Packit 1fb8d4
   
Packit 1fb8d4
   @post @p target will be zero terminated.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_DUPLICATE_MAX)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING char *
Packit 1fb8d4
trio_duplicate_max
Packit 1fb8d4
TRIO_ARGS2((source, max),
Packit 1fb8d4
	   TRIO_CONST char *source,
Packit 1fb8d4
	   size_t max)
Packit 1fb8d4
{
Packit 1fb8d4
  size_t length;
Packit 1fb8d4
Packit 1fb8d4
  assert(source);
Packit 1fb8d4
  assert(max > 0);
Packit 1fb8d4
Packit 1fb8d4
  length = trio_length(source);
Packit 1fb8d4
  if (length > max)
Packit 1fb8d4
    {
Packit 1fb8d4
      length = max;
Packit 1fb8d4
    }
Packit 1fb8d4
  return internal_duplicate_max(source, length);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Compare if two strings are equal.
Packit 1fb8d4
   
Packit 1fb8d4
   @param first First string.
Packit 1fb8d4
   @param second Second string.
Packit 1fb8d4
   @return Boolean indicating whether the two strings are equal or not.
Packit 1fb8d4
   
Packit 1fb8d4
   Case-insensitive comparison.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_EQUAL)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_equal
Packit 1fb8d4
TRIO_ARGS2((first, second),
Packit 1fb8d4
	   TRIO_CONST char *first,
Packit 1fb8d4
	   TRIO_CONST char *second)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(first);
Packit 1fb8d4
  assert(second);
Packit 1fb8d4
Packit 1fb8d4
  if ((first != NULL) && (second != NULL))
Packit 1fb8d4
    {
Packit 1fb8d4
# if defined(USE_STRCASECMP)
Packit 1fb8d4
      return (0 == strcasecmp(first, second));
Packit 1fb8d4
# else
Packit 1fb8d4
      while ((*first != NIL) && (*second != NIL))
Packit 1fb8d4
	{
Packit 1fb8d4
	  if (internal_to_upper(*first) != internal_to_upper(*second))
Packit 1fb8d4
	    {
Packit 1fb8d4
	      break;
Packit 1fb8d4
	    }
Packit 1fb8d4
	  first++;
Packit 1fb8d4
	  second++;
Packit 1fb8d4
	}
Packit 1fb8d4
      return ((*first == NIL) && (*second == NIL));
Packit 1fb8d4
# endif
Packit 1fb8d4
    }
Packit 1fb8d4
  return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Compare if two strings are equal.
Packit 1fb8d4
   
Packit 1fb8d4
   @param first First string.
Packit 1fb8d4
   @param second Second string.
Packit 1fb8d4
   @return Boolean indicating whether the two strings are equal or not.
Packit 1fb8d4
   
Packit 1fb8d4
   Case-sensitive comparison.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_EQUAL_CASE)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_equal_case
Packit 1fb8d4
TRIO_ARGS2((first, second),
Packit 1fb8d4
	   TRIO_CONST char *first,
Packit 1fb8d4
	   TRIO_CONST char *second)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(first);
Packit 1fb8d4
  assert(second);
Packit 1fb8d4
Packit 1fb8d4
  if ((first != NULL) && (second != NULL))
Packit 1fb8d4
    {
Packit 1fb8d4
      return (0 == strcmp(first, second));
Packit 1fb8d4
    }
Packit 1fb8d4
  return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Compare if two strings up until the first @p max characters are equal.
Packit 1fb8d4
   
Packit 1fb8d4
   @param first First string.
Packit 1fb8d4
   @param max Maximum number of characters to compare.
Packit 1fb8d4
   @param second Second string.
Packit 1fb8d4
   @return Boolean indicating whether the two strings are equal or not.
Packit 1fb8d4
   
Packit 1fb8d4
   Case-sensitive comparison.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_EQUAL_CASE_MAX)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_equal_case_max
Packit 1fb8d4
TRIO_ARGS3((first, max, second),
Packit 1fb8d4
	   TRIO_CONST char *first,
Packit 1fb8d4
	   size_t max,
Packit 1fb8d4
	   TRIO_CONST char *second)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(first);
Packit 1fb8d4
  assert(second);
Packit 1fb8d4
Packit 1fb8d4
  if ((first != NULL) && (second != NULL))
Packit 1fb8d4
    {
Packit 1fb8d4
      return (0 == strncmp(first, second, max));
Packit 1fb8d4
    }
Packit 1fb8d4
  return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Compare if two strings are equal.
Packit 1fb8d4
   
Packit 1fb8d4
   @param first First string.
Packit 1fb8d4
   @param second Second string.
Packit 1fb8d4
   @return Boolean indicating whether the two strings are equal or not.
Packit 1fb8d4
Packit 1fb8d4
   Collating characters are considered equal.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_EQUAL_LOCALE)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_equal_locale
Packit 1fb8d4
TRIO_ARGS2((first, second),
Packit 1fb8d4
	   TRIO_CONST char *first,
Packit 1fb8d4
	   TRIO_CONST char *second)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(first);
Packit 1fb8d4
  assert(second);
Packit 1fb8d4
Packit 1fb8d4
# if defined(LC_COLLATE)
Packit 1fb8d4
  return (strcoll(first, second) == 0);
Packit 1fb8d4
# else
Packit 1fb8d4
  return trio_equal(first, second);
Packit 1fb8d4
# endif
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Compare if two strings up until the first @p max characters are equal.
Packit 1fb8d4
   
Packit 1fb8d4
   @param first First string.
Packit 1fb8d4
   @param max Maximum number of characters to compare.
Packit 1fb8d4
   @param second Second string.
Packit 1fb8d4
   @return Boolean indicating whether the two strings are equal or not.
Packit 1fb8d4
   
Packit 1fb8d4
   Case-insensitive comparison.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_EQUAL_MAX)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_equal_max
Packit 1fb8d4
TRIO_ARGS3((first, max, second),
Packit 1fb8d4
	   TRIO_CONST char *first,
Packit 1fb8d4
	   size_t max,
Packit 1fb8d4
	   TRIO_CONST char *second)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(first);
Packit 1fb8d4
  assert(second);
Packit 1fb8d4
Packit 1fb8d4
  if ((first != NULL) && (second != NULL))
Packit 1fb8d4
    {
Packit 1fb8d4
# if defined(USE_STRNCASECMP)
Packit 1fb8d4
      return (0 == strncasecmp(first, second, max));
Packit 1fb8d4
# else
Packit 1fb8d4
      /* Not adequately tested yet */
Packit 1fb8d4
      size_t cnt = 0;
Packit 1fb8d4
      while ((*first != NIL) && (*second != NIL) && (cnt <= max))
Packit 1fb8d4
	{
Packit 1fb8d4
	  if (internal_to_upper(*first) != internal_to_upper(*second))
Packit 1fb8d4
	    {
Packit 1fb8d4
	      break;
Packit 1fb8d4
	    }
Packit 1fb8d4
	  first++;
Packit 1fb8d4
	  second++;
Packit 1fb8d4
	  cnt++;
Packit 1fb8d4
	}
Packit 1fb8d4
      return ((cnt == max) || ((*first == NIL) && (*second == NIL)));
Packit 1fb8d4
# endif
Packit 1fb8d4
    }
Packit 1fb8d4
  return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Provide a textual description of an error code (errno).
Packit 1fb8d4
Packit 1fb8d4
   @param error_number Error number.
Packit 1fb8d4
   @return Textual description of @p error_number.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_ERROR)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING TRIO_CONST char *
Packit 1fb8d4
trio_error
Packit 1fb8d4
TRIO_ARGS1((error_number),
Packit 1fb8d4
	   int error_number)
Packit 1fb8d4
{
Packit 1fb8d4
# if defined(USE_STRERROR)
Packit 1fb8d4
  
Packit 1fb8d4
  return strerror(error_number);
Packit 1fb8d4
Packit 1fb8d4
# else
Packit 1fb8d4
#  if defined(USE_SYS_ERRLIST)
Packit 1fb8d4
Packit 1fb8d4
  extern char *sys_errlist[];
Packit 1fb8d4
  extern int sys_nerr;
Packit 1fb8d4
Packit 1fb8d4
  return ((error_number < 0) || (error_number >= sys_nerr))
Packit 1fb8d4
    ? "unknown"
Packit 1fb8d4
    : sys_errlist[error_number];
Packit 1fb8d4
 
Packit 1fb8d4
#  else
Packit 1fb8d4
  
Packit 1fb8d4
  return "unknown";
Packit 1fb8d4
Packit 1fb8d4
#  endif
Packit 1fb8d4
# endif
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Format the date/time according to @p format.
Packit 1fb8d4
Packit 1fb8d4
   @param target Target string.
Packit 1fb8d4
   @param max Maximum number of characters to format.
Packit 1fb8d4
   @param format Formatting string.
Packit 1fb8d4
   @param datetime Date/time structure.
Packit 1fb8d4
   @return Number of formatted characters.
Packit 1fb8d4
Packit 1fb8d4
   The formatting string accepts the same specifiers as the standard C
Packit 1fb8d4
   function strftime.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_FORMAT_DATE_MAX)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING size_t
Packit 1fb8d4
trio_format_date_max
Packit 1fb8d4
TRIO_ARGS4((target, max, format, datetime),
Packit 1fb8d4
	   char *target,
Packit 1fb8d4
	   size_t max,
Packit 1fb8d4
	   TRIO_CONST char *format,
Packit 1fb8d4
	   TRIO_CONST struct tm *datetime)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(target);
Packit 1fb8d4
  assert(format);
Packit 1fb8d4
  assert(datetime);
Packit 1fb8d4
  assert(max > 0);
Packit 1fb8d4
Packit 1fb8d4
  return strftime(target, max, format, datetime);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Calculate a hash value for a string.
Packit 1fb8d4
Packit 1fb8d4
   @param string String to be calculated on.
Packit 1fb8d4
   @param type Hash function.
Packit 1fb8d4
   @return Calculated hash value.
Packit 1fb8d4
Packit 1fb8d4
   @p type can be one of the following
Packit 1fb8d4
   @li @c TRIO_HASH_PLAIN Plain hash function.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_HASH)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING unsigned long
Packit 1fb8d4
trio_hash
Packit 1fb8d4
TRIO_ARGS2((string, type),
Packit 1fb8d4
	   TRIO_CONST char *string,
Packit 1fb8d4
	   int type)
Packit 1fb8d4
{
Packit 1fb8d4
  unsigned long value = 0L;
Packit 1fb8d4
  char ch;
Packit 1fb8d4
Packit 1fb8d4
  assert(string);
Packit 1fb8d4
  
Packit 1fb8d4
  switch (type)
Packit 1fb8d4
    {
Packit 1fb8d4
    case TRIO_HASH_PLAIN:
Packit 1fb8d4
      while ( (ch = *string++) != NIL )
Packit 1fb8d4
	{
Packit 1fb8d4
	  value *= 31;
Packit 1fb8d4
	  value += (unsigned long)ch;
Packit 1fb8d4
	}
Packit 1fb8d4
      break;
Packit 1fb8d4
    default:
Packit 1fb8d4
      assert(FALSE);
Packit 1fb8d4
      break;
Packit 1fb8d4
    }
Packit 1fb8d4
  return value;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Find first occurrence of a character in a string.
Packit 1fb8d4
Packit 1fb8d4
   @param string String to be searched.
Packit 1fb8d4
   @param character Character to be found.
Packit 1fb8d4
   @return A pointer to the found character, or NULL if character was not found.
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_INDEX)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING char *
Packit 1fb8d4
trio_index
Packit 1fb8d4
TRIO_ARGS2((string, character),
Packit 1fb8d4
	   TRIO_CONST char *string,
Packit 1fb8d4
	   int character)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(string);
Packit 1fb8d4
Packit 1fb8d4
  return strchr(string, character);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Find last occurrence of a character in a string.
Packit 1fb8d4
Packit 1fb8d4
   @param string String to be searched.
Packit 1fb8d4
   @param character Character to be found.
Packit 1fb8d4
   @return A pointer to the found character, or NULL if character was not found.
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_INDEX_LAST)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING char *
Packit 1fb8d4
trio_index_last
Packit 1fb8d4
TRIO_ARGS2((string, character),
Packit 1fb8d4
	   TRIO_CONST char *string,
Packit 1fb8d4
	   int character)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(string);
Packit 1fb8d4
Packit 1fb8d4
  return strchr(string, character);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Convert the alphabetic letters in the string to lower-case.
Packit 1fb8d4
Packit 1fb8d4
   @param target String to be converted.
Packit 1fb8d4
   @return Number of processed characters (converted or not).
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_LOWER)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_lower
Packit 1fb8d4
TRIO_ARGS1((target),
Packit 1fb8d4
	   char *target)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(target);
Packit 1fb8d4
Packit 1fb8d4
  return trio_span_function(target, target, trio_to_lower);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Compare two strings using wildcards.
Packit 1fb8d4
Packit 1fb8d4
   @param string String to be searched.
Packit 1fb8d4
   @param pattern Pattern, including wildcards, to search for.
Packit 1fb8d4
   @return Boolean value indicating success or failure.
Packit 1fb8d4
Packit 1fb8d4
   Case-insensitive comparison.
Packit 1fb8d4
   
Packit 1fb8d4
   The following wildcards can be used
Packit 1fb8d4
   @li @c * Match any number of characters.
Packit 1fb8d4
   @li @c ? Match a single character.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_MATCH)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_match
Packit 1fb8d4
TRIO_ARGS2((string, pattern),
Packit 1fb8d4
	   TRIO_CONST char *string,
Packit 1fb8d4
	   TRIO_CONST char *pattern)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(string);
Packit 1fb8d4
  assert(pattern);
Packit 1fb8d4
  
Packit 1fb8d4
  for (; ('*' != *pattern); ++pattern, ++string)
Packit 1fb8d4
    {
Packit 1fb8d4
      if (NIL == *string)
Packit 1fb8d4
	{
Packit 1fb8d4
	  return (NIL == *pattern);
Packit 1fb8d4
	}
Packit 1fb8d4
      if ((internal_to_upper((int)*string) != internal_to_upper((int)*pattern))
Packit 1fb8d4
	  && ('?' != *pattern))
Packit 1fb8d4
	{
Packit 1fb8d4
	  return FALSE;
Packit 1fb8d4
	}
Packit 1fb8d4
    }
Packit 1fb8d4
  /* two-line patch to prevent *too* much recursiveness: */
Packit 1fb8d4
  while ('*' == pattern[1])
Packit 1fb8d4
    pattern++;
Packit 1fb8d4
Packit 1fb8d4
  do
Packit 1fb8d4
    {
Packit 1fb8d4
      if ( trio_match(string, &pattern[1]) )
Packit 1fb8d4
	{
Packit 1fb8d4
	  return TRUE;
Packit 1fb8d4
	}
Packit 1fb8d4
    }
Packit 1fb8d4
  while (*string++);
Packit 1fb8d4
  
Packit 1fb8d4
  return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Compare two strings using wildcards.
Packit 1fb8d4
Packit 1fb8d4
   @param string String to be searched.
Packit 1fb8d4
   @param pattern Pattern, including wildcards, to search for.
Packit 1fb8d4
   @return Boolean value indicating success or failure.
Packit 1fb8d4
Packit 1fb8d4
   Case-sensitive comparison.
Packit 1fb8d4
   
Packit 1fb8d4
   The following wildcards can be used
Packit 1fb8d4
   @li @c * Match any number of characters.
Packit 1fb8d4
   @li @c ? Match a single character.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_MATCH_CASE)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_match_case
Packit 1fb8d4
TRIO_ARGS2((string, pattern),
Packit 1fb8d4
	   TRIO_CONST char *string,
Packit 1fb8d4
	   TRIO_CONST char *pattern)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(string);
Packit 1fb8d4
  assert(pattern);
Packit 1fb8d4
  
Packit 1fb8d4
  for (; ('*' != *pattern); ++pattern, ++string)
Packit 1fb8d4
    {
Packit 1fb8d4
      if (NIL == *string)
Packit 1fb8d4
	{
Packit 1fb8d4
	  return (NIL == *pattern);
Packit 1fb8d4
	}
Packit 1fb8d4
      if ((*string != *pattern)
Packit 1fb8d4
	  && ('?' != *pattern))
Packit 1fb8d4
	{
Packit 1fb8d4
	  return FALSE;
Packit 1fb8d4
	}
Packit 1fb8d4
    }
Packit 1fb8d4
  /* two-line patch to prevent *too* much recursiveness: */
Packit 1fb8d4
  while ('*' == pattern[1])
Packit 1fb8d4
    pattern++;
Packit 1fb8d4
Packit 1fb8d4
  do
Packit 1fb8d4
    {
Packit 1fb8d4
      if ( trio_match_case(string, &pattern[1]) )
Packit 1fb8d4
	{
Packit 1fb8d4
	  return TRUE;
Packit 1fb8d4
	}
Packit 1fb8d4
    }
Packit 1fb8d4
  while (*string++);
Packit 1fb8d4
  
Packit 1fb8d4
  return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Execute a function on each character in string.
Packit 1fb8d4
Packit 1fb8d4
   @param target Target string.
Packit 1fb8d4
   @param source Source string.
Packit 1fb8d4
   @param Function Function to be executed.
Packit 1fb8d4
   @return Number of processed characters.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_SPAN_FUNCTION)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING size_t
Packit 1fb8d4
trio_span_function
Packit 1fb8d4
TRIO_ARGS3((target, source, Function),
Packit 1fb8d4
	   char *target,
Packit 1fb8d4
	   TRIO_CONST char *source,
Packit 1fb8d4
	   int (*Function) TRIO_PROTO((int)))
Packit 1fb8d4
{
Packit 1fb8d4
  size_t count = 0;
Packit 1fb8d4
Packit 1fb8d4
  assert(target);
Packit 1fb8d4
  assert(source);
Packit 1fb8d4
  assert(Function);
Packit 1fb8d4
  
Packit 1fb8d4
  while (*source != NIL)
Packit 1fb8d4
    {
Packit 1fb8d4
      *target++ = Function(*source++);
Packit 1fb8d4
      count++;
Packit 1fb8d4
    }
Packit 1fb8d4
  return count;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Search for a substring in a string.
Packit 1fb8d4
Packit 1fb8d4
   @param string String to be searched.
Packit 1fb8d4
   @param substring String to be found.
Packit 1fb8d4
   @return Pointer to first occurrence of @p substring in @p string, or NULL
Packit 1fb8d4
   if no match was found.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_SUBSTRING)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING char *
Packit 1fb8d4
trio_substring
Packit 1fb8d4
TRIO_ARGS2((string, substring),
Packit 1fb8d4
	   TRIO_CONST char *string,
Packit 1fb8d4
	   TRIO_CONST char *substring)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(string);
Packit 1fb8d4
  assert(substring);
Packit 1fb8d4
Packit 1fb8d4
  return strstr(string, substring);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Search for a substring in the first @p max characters of a string.
Packit 1fb8d4
Packit 1fb8d4
   @param string String to be searched.
Packit 1fb8d4
   @param max Maximum characters to be searched.
Packit 1fb8d4
   @param substring String to be found.
Packit 1fb8d4
   @return Pointer to first occurrence of @p substring in @p string, or NULL
Packit 1fb8d4
   if no match was found.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_SUBSTRING_MAX)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING char *
Packit 1fb8d4
trio_substring_max
Packit 1fb8d4
TRIO_ARGS3((string, max, substring),
Packit 1fb8d4
	   TRIO_CONST char *string,
Packit 1fb8d4
	   size_t max,
Packit 1fb8d4
	   TRIO_CONST char *substring)
Packit 1fb8d4
{
Packit 1fb8d4
  size_t count;
Packit 1fb8d4
  size_t size;
Packit 1fb8d4
  char *result = NULL;
Packit 1fb8d4
Packit 1fb8d4
  assert(string);
Packit 1fb8d4
  assert(substring);
Packit 1fb8d4
  
Packit 1fb8d4
  size = trio_length(substring);
Packit 1fb8d4
  if (size <= max)
Packit 1fb8d4
    {
Packit 1fb8d4
      for (count = 0; count <= max - size; count++)
Packit 1fb8d4
	{
Packit 1fb8d4
	  if (trio_equal_max(substring, size, &string[count]))
Packit 1fb8d4
	    {
Packit 1fb8d4
	      result = (char *)&string[count];
Packit 1fb8d4
	      break;
Packit 1fb8d4
	    }
Packit 1fb8d4
	}
Packit 1fb8d4
    }
Packit 1fb8d4
  return result;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Tokenize string.
Packit 1fb8d4
Packit 1fb8d4
   @param string String to be tokenized.
Packit 1fb8d4
   @param delimiters String containing list of delimiting characters.
Packit 1fb8d4
   @return Start of new token.
Packit 1fb8d4
Packit 1fb8d4
   @warning @p string will be destroyed.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_TOKENIZE)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING char *
Packit 1fb8d4
trio_tokenize
Packit 1fb8d4
TRIO_ARGS2((string, delimiters),
Packit 1fb8d4
	   char *string,
Packit 1fb8d4
	   TRIO_CONST char *delimiters)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(delimiters);
Packit 1fb8d4
  
Packit 1fb8d4
  return strtok(string, delimiters);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Convert string to floating-point number.
Packit 1fb8d4
Packit 1fb8d4
   @param source String to be converted.
Packit 1fb8d4
   @param endp Pointer to end of the converted string.
Packit 1fb8d4
   @return A floating-point number.
Packit 1fb8d4
Packit 1fb8d4
   The following Extended Backus-Naur form is used
Packit 1fb8d4
   @verbatim
Packit 1fb8d4
   double        ::= [ <sign> ]
Packit 1fb8d4
                     ( <number> |
Packit 1fb8d4
                       <number> <decimal_point> <number> |
Packit 1fb8d4
                       <decimal_point> <number> )
Packit 1fb8d4
                     [ <exponential> [ <sign> ] <number> ]
Packit 1fb8d4
   number        ::= 1*( <digit> )
Packit 1fb8d4
   digit         ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )
Packit 1fb8d4
   exponential   ::= ( 'e' | 'E' )
Packit 1fb8d4
   sign          ::= ( '-' | '+' )
Packit 1fb8d4
   decimal_point ::= '.'
Packit 1fb8d4
   @endverbatim
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_TO_LONG_DOUBLE)
Packit 1fb8d4
Packit 1fb8d4
/* FIXME: Add EBNF for hex-floats */
Packit 1fb8d4
TRIO_PUBLIC_STRING trio_long_double_t
Packit 1fb8d4
trio_to_long_double
Packit 1fb8d4
TRIO_ARGS2((source, endp),
Packit 1fb8d4
	   TRIO_CONST char *source,
Packit 1fb8d4
	   char **endp)
Packit 1fb8d4
{
Packit 1fb8d4
# if defined(USE_STRTOLD)
Packit 1fb8d4
  return strtold(source, endp);
Packit 1fb8d4
# else
Packit 1fb8d4
  int isNegative = FALSE;
Packit 1fb8d4
  int isExponentNegative = FALSE;
Packit 1fb8d4
  trio_long_double_t integer = 0.0;
Packit 1fb8d4
  trio_long_double_t fraction = 0.0;
Packit 1fb8d4
  unsigned long exponent = 0;
Packit 1fb8d4
  trio_long_double_t base;
Packit 1fb8d4
  trio_long_double_t fracdiv = 1.0;
Packit 1fb8d4
  trio_long_double_t value = 0.0;
Packit 1fb8d4
Packit 1fb8d4
  /* First try hex-floats */
Packit 1fb8d4
  if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X')))
Packit 1fb8d4
    {
Packit 1fb8d4
      base = 16.0;
Packit 1fb8d4
      source += 2;
Packit 1fb8d4
      while (isxdigit((int)*source))
Packit 1fb8d4
	{
Packit 1fb8d4
	  integer *= base;
Packit 1fb8d4
	  integer += (isdigit((int)*source)
Packit 1fb8d4
		      ? (*source - '0')
Packit 1fb8d4
		      : 10 + (internal_to_upper((int)*source) - 'A'));
Packit 1fb8d4
	  source++;
Packit 1fb8d4
	}
Packit 1fb8d4
      if (*source == '.')
Packit 1fb8d4
	{
Packit 1fb8d4
	  source++;
Packit 1fb8d4
	  while (isxdigit((int)*source))
Packit 1fb8d4
	    {
Packit 1fb8d4
	      fracdiv /= base;
Packit 1fb8d4
	      fraction += fracdiv * (isdigit((int)*source)
Packit 1fb8d4
				     ? (*source - '0')
Packit 1fb8d4
				     : 10 + (internal_to_upper((int)*source) - 'A'));
Packit 1fb8d4
	      source++;
Packit 1fb8d4
	    }
Packit 1fb8d4
	  if ((*source == 'p') || (*source == 'P'))
Packit 1fb8d4
	    {
Packit 1fb8d4
	      source++;
Packit 1fb8d4
	      if ((*source == '+') || (*source == '-'))
Packit 1fb8d4
		{
Packit 1fb8d4
		  isExponentNegative = (*source == '-');
Packit 1fb8d4
		  source++;
Packit 1fb8d4
		}
Packit 1fb8d4
	      while (isdigit((int)*source))
Packit 1fb8d4
		{
Packit 1fb8d4
		  exponent *= 10;
Packit 1fb8d4
		  exponent += (*source - '0');
Packit 1fb8d4
		  source++;
Packit 1fb8d4
		}
Packit 1fb8d4
	    }
Packit 1fb8d4
	}
Packit 1fb8d4
      /* For later use with exponent */
Packit 1fb8d4
      base = 2.0;
Packit 1fb8d4
    }
Packit 1fb8d4
  else /* Then try normal decimal floats */
Packit 1fb8d4
    {
Packit 1fb8d4
      base = 10.0;
Packit 1fb8d4
      isNegative = (*source == '-');
Packit 1fb8d4
      /* Skip sign */
Packit 1fb8d4
      if ((*source == '+') || (*source == '-'))
Packit 1fb8d4
	source++;
Packit 1fb8d4
Packit 1fb8d4
      /* Integer part */
Packit 1fb8d4
      while (isdigit((int)*source))
Packit 1fb8d4
	{
Packit 1fb8d4
	  integer *= base;
Packit 1fb8d4
	  integer += (*source - '0');
Packit 1fb8d4
	  source++;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
      if (*source == '.')
Packit 1fb8d4
	{
Packit 1fb8d4
	  source++; /* skip decimal point */
Packit 1fb8d4
	  while (isdigit((int)*source))
Packit 1fb8d4
	    {
Packit 1fb8d4
	      fracdiv /= base;
Packit 1fb8d4
	      fraction += (*source - '0') * fracdiv;
Packit 1fb8d4
	      source++;
Packit 1fb8d4
	    }
Packit 1fb8d4
	}
Packit 1fb8d4
      if ((*source == 'e')
Packit 1fb8d4
	  || (*source == 'E')
Packit 1fb8d4
#  if TRIO_MICROSOFT
Packit 1fb8d4
	  || (*source == 'd')
Packit 1fb8d4
	  || (*source == 'D')
Packit 1fb8d4
#  endif
Packit 1fb8d4
	  )
Packit 1fb8d4
	{
Packit 1fb8d4
	  source++; /* Skip exponential indicator */
Packit 1fb8d4
	  isExponentNegative = (*source == '-');
Packit 1fb8d4
	  if ((*source == '+') || (*source == '-'))
Packit 1fb8d4
	    source++;
Packit 1fb8d4
	  while (isdigit((int)*source))
Packit 1fb8d4
	    {
Packit 1fb8d4
	      exponent *= (int)base;
Packit 1fb8d4
	      exponent += (*source - '0');
Packit 1fb8d4
	      source++;
Packit 1fb8d4
	    }
Packit 1fb8d4
	}
Packit 1fb8d4
    }
Packit 1fb8d4
  
Packit 1fb8d4
  value = integer + fraction;
Packit 1fb8d4
  if (exponent != 0)
Packit 1fb8d4
    {
Packit 1fb8d4
      if (isExponentNegative)
Packit 1fb8d4
	value /= trio_powl(base, (trio_long_double_t)exponent);
Packit 1fb8d4
      else
Packit 1fb8d4
	value *= trio_powl(base, (trio_long_double_t)exponent);
Packit 1fb8d4
    }
Packit 1fb8d4
  if (isNegative)
Packit 1fb8d4
    value = -value;
Packit 1fb8d4
Packit 1fb8d4
  if (endp)
Packit 1fb8d4
    *endp = (char *)source;
Packit 1fb8d4
  return value;
Packit 1fb8d4
# endif
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Convert string to floating-point number.
Packit 1fb8d4
Packit 1fb8d4
   @param source String to be converted.
Packit 1fb8d4
   @param endp Pointer to end of the converted string.
Packit 1fb8d4
   @return A floating-point number.
Packit 1fb8d4
Packit 1fb8d4
   See @ref trio_to_long_double.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_TO_DOUBLE)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING double
Packit 1fb8d4
trio_to_double
Packit 1fb8d4
TRIO_ARGS2((source, endp),
Packit 1fb8d4
	   TRIO_CONST char *source,
Packit 1fb8d4
	   char **endp)
Packit 1fb8d4
{
Packit 1fb8d4
#if defined(USE_STRTOD)
Packit 1fb8d4
  return strtod(source, endp);
Packit 1fb8d4
#else
Packit 1fb8d4
  return (double)trio_to_long_double(source, endp);
Packit 1fb8d4
#endif
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Convert string to floating-point number.
Packit 1fb8d4
Packit 1fb8d4
   @param source String to be converted.
Packit 1fb8d4
   @param endp Pointer to end of the converted string.
Packit 1fb8d4
   @return A floating-point number.
Packit 1fb8d4
Packit 1fb8d4
   See @ref trio_to_long_double.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_TO_FLOAT)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING float
Packit 1fb8d4
trio_to_float
Packit 1fb8d4
TRIO_ARGS2((source, endp),
Packit 1fb8d4
	   TRIO_CONST char *source,
Packit 1fb8d4
	   char **endp)
Packit 1fb8d4
{
Packit 1fb8d4
#  if defined(USE_STRTOF)
Packit 1fb8d4
  return strtof(source, endp);
Packit 1fb8d4
#  else
Packit 1fb8d4
  return (float)trio_to_long_double(source, endp);
Packit 1fb8d4
#  endif
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Convert string to signed integer.
Packit 1fb8d4
Packit 1fb8d4
   @param string String to be converted.
Packit 1fb8d4
   @param endp Pointer to end of converted string.
Packit 1fb8d4
   @param base Radix number of number.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_TO_LONG)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING long
Packit 1fb8d4
trio_to_long
Packit 1fb8d4
TRIO_ARGS3((string, endp, base),
Packit 1fb8d4
	   TRIO_CONST char *string,
Packit 1fb8d4
	   char **endp,
Packit 1fb8d4
	   int base)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(string);
Packit 1fb8d4
  assert((base >= 2) && (base <= 36));
Packit 1fb8d4
  
Packit 1fb8d4
  return strtol(string, endp, base);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Convert one alphabetic letter to lower-case.
Packit 1fb8d4
Packit 1fb8d4
   @param source The letter to be converted.
Packit 1fb8d4
   @return The converted letter.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_TO_LOWER)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_to_lower
Packit 1fb8d4
TRIO_ARGS1((source),
Packit 1fb8d4
	   int source)
Packit 1fb8d4
{
Packit 1fb8d4
# if defined(HAVE_TOLOWER)
Packit 1fb8d4
  
Packit 1fb8d4
  return tolower(source);
Packit 1fb8d4
  
Packit 1fb8d4
# else
Packit 1fb8d4
Packit 1fb8d4
  /* Does not handle locales or non-contiguous alphabetic characters */
Packit 1fb8d4
  return ((source >= (int)'A') && (source <= (int)'Z'))
Packit 1fb8d4
    ? source - 'A' + 'a'
Packit 1fb8d4
    : source;
Packit 1fb8d4
  
Packit 1fb8d4
# endif
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Convert string to unsigned integer.
Packit 1fb8d4
Packit 1fb8d4
   @param string String to be converted.
Packit 1fb8d4
   @param endp Pointer to end of converted string.
Packit 1fb8d4
   @param base Radix number of number.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_TO_UNSIGNED_LONG)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING unsigned long
Packit 1fb8d4
trio_to_unsigned_long
Packit 1fb8d4
TRIO_ARGS3((string, endp, base),
Packit 1fb8d4
	   TRIO_CONST char *string,
Packit 1fb8d4
	   char **endp,
Packit 1fb8d4
	   int base)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(string);
Packit 1fb8d4
  assert((base >= 2) && (base <= 36));
Packit 1fb8d4
  
Packit 1fb8d4
  return strtoul(string, endp, base);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Convert one alphabetic letter to upper-case.
Packit 1fb8d4
Packit 1fb8d4
   @param source The letter to be converted.
Packit 1fb8d4
   @return The converted letter.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_TO_UPPER)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_to_upper
Packit 1fb8d4
TRIO_ARGS1((source),
Packit 1fb8d4
	   int source)
Packit 1fb8d4
{
Packit 1fb8d4
  return internal_to_upper(source);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Convert the alphabetic letters in the string to upper-case.
Packit 1fb8d4
Packit 1fb8d4
   @param target The string to be converted.
Packit 1fb8d4
   @return The number of processed characters (converted or not).
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_UPPER)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_upper
Packit 1fb8d4
TRIO_ARGS1((target),
Packit 1fb8d4
	   char *target)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(target);
Packit 1fb8d4
Packit 1fb8d4
  return trio_span_function(target, target, internal_to_upper);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/** @} End of StaticStrings */
Packit 1fb8d4
Packit 1fb8d4
Packit 1fb8d4
/*************************************************************************
Packit 1fb8d4
 * Dynamic String Functions
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#if defined(TRIO_DOCUMENTATION)
Packit 1fb8d4
# include "doc/doc_dynamic.h"
Packit 1fb8d4
#endif
Packit 1fb8d4
/** @addtogroup DynamicStrings
Packit 1fb8d4
    @{
Packit 1fb8d4
*/
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Create a new dynamic string.
Packit 1fb8d4
   
Packit 1fb8d4
   @param initial_size Initial size of the buffer.
Packit 1fb8d4
   @return Newly allocated dynamic string, or NULL if memory allocation failed.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_CREATE)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING trio_string_t *
Packit 1fb8d4
trio_string_create
Packit 1fb8d4
TRIO_ARGS1((initial_size),
Packit 1fb8d4
	   int initial_size)
Packit 1fb8d4
{
Packit 1fb8d4
  trio_string_t *self;
Packit 1fb8d4
Packit 1fb8d4
  self = internal_string_alloc();
Packit 1fb8d4
  if (self)
Packit 1fb8d4
    {
Packit 1fb8d4
      if (internal_string_grow(self,
Packit 1fb8d4
			 (size_t)((initial_size > 0) ? initial_size : 1)))
Packit 1fb8d4
	{
Packit 1fb8d4
	  self->content[0] = (char)0;
Packit 1fb8d4
	  self->allocated = initial_size;
Packit 1fb8d4
	}
Packit 1fb8d4
      else
Packit 1fb8d4
	{
Packit 1fb8d4
	  trio_string_destroy(self);
Packit 1fb8d4
	  self = NULL;
Packit 1fb8d4
	}
Packit 1fb8d4
    }
Packit 1fb8d4
  return self;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Deallocate the dynamic string and its contents.
Packit 1fb8d4
   
Packit 1fb8d4
   @param self Dynamic string
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_DESTROY)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING void
Packit 1fb8d4
trio_string_destroy
Packit 1fb8d4
TRIO_ARGS1((self),
Packit 1fb8d4
	   trio_string_t *self)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
  
Packit 1fb8d4
  if (self)
Packit 1fb8d4
    {
Packit 1fb8d4
      trio_destroy(self->content);
Packit 1fb8d4
      TRIO_FREE(self);
Packit 1fb8d4
    }
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Get a pointer to the content.
Packit 1fb8d4
   
Packit 1fb8d4
   @param self Dynamic string.
Packit 1fb8d4
   @param offset Offset into content.
Packit 1fb8d4
   @return Pointer to the content.
Packit 1fb8d4
   
Packit 1fb8d4
   @p Offset can be zero, positive, or negative. If @p offset is zero,
Packit 1fb8d4
   then the start of the content will be returned. If @p offset is positive,
Packit 1fb8d4
   then a pointer to @p offset number of characters from the beginning of the
Packit 1fb8d4
   content is returned. If @p offset is negative, then a pointer to @p offset
Packit 1fb8d4
   number of characters from the ending of the string, starting at the
Packit 1fb8d4
   terminating zero, is returned.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_GET)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING char *
Packit 1fb8d4
trio_string_get
Packit 1fb8d4
TRIO_ARGS2((self, offset),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   int offset)
Packit 1fb8d4
{
Packit 1fb8d4
  char *result = NULL;
Packit 1fb8d4
  
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
Packit 1fb8d4
  if (self->content != NULL)
Packit 1fb8d4
    {
Packit 1fb8d4
      if (self->length == 0)
Packit 1fb8d4
	{
Packit 1fb8d4
	  (void)trio_string_length(self);
Packit 1fb8d4
	}
Packit 1fb8d4
      if (offset >= 0)
Packit 1fb8d4
	{
Packit 1fb8d4
	  if (offset > (int)self->length)
Packit 1fb8d4
	    {
Packit 1fb8d4
	      offset = self->length;
Packit 1fb8d4
	    }
Packit 1fb8d4
	}
Packit 1fb8d4
      else
Packit 1fb8d4
	{
Packit 1fb8d4
	  offset += self->length + 1;
Packit 1fb8d4
	  if (offset < 0)
Packit 1fb8d4
	    {
Packit 1fb8d4
	      offset = 0;
Packit 1fb8d4
	    }
Packit 1fb8d4
	}
Packit 1fb8d4
      result = &(self->content[offset]);
Packit 1fb8d4
    }
Packit 1fb8d4
  return result;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Extract the content.
Packit 1fb8d4
   
Packit 1fb8d4
   @param self Dynamic String
Packit 1fb8d4
   @return Content of dynamic string.
Packit 1fb8d4
   
Packit 1fb8d4
   The content is removed from the dynamic string. This enables destruction
Packit 1fb8d4
   of the dynamic string without deallocation of the content.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_EXTRACT)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING char *
Packit 1fb8d4
trio_string_extract
Packit 1fb8d4
TRIO_ARGS1((self),
Packit 1fb8d4
	   trio_string_t *self)
Packit 1fb8d4
{
Packit 1fb8d4
  char *result;
Packit 1fb8d4
  
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
Packit 1fb8d4
  result = self->content;
Packit 1fb8d4
  /* FIXME: Allocate new empty buffer? */
Packit 1fb8d4
  self->content = NULL;
Packit 1fb8d4
  self->length = self->allocated = 0;
Packit 1fb8d4
  return result;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Set the content of the dynamic string.
Packit 1fb8d4
   
Packit 1fb8d4
   @param self Dynamic String
Packit 1fb8d4
   @param buffer The new content.
Packit 1fb8d4
   
Packit 1fb8d4
   Sets the content of the dynamic string to a copy @p buffer.
Packit 1fb8d4
   An existing content will be deallocated first, if necessary.
Packit 1fb8d4
   
Packit 1fb8d4
   @remark
Packit 1fb8d4
   This function will make a copy of @p buffer.
Packit 1fb8d4
   You are responsible for deallocating @p buffer yourself.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_XSTRING_SET)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING void
Packit 1fb8d4
trio_xstring_set
Packit 1fb8d4
TRIO_ARGS2((self, buffer),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   char *buffer)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
Packit 1fb8d4
  trio_destroy(self->content);
Packit 1fb8d4
  self->content = trio_duplicate(buffer);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_string_size
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_SIZE)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_string_size
Packit 1fb8d4
TRIO_ARGS1((self),
Packit 1fb8d4
	   trio_string_t *self)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
Packit 1fb8d4
  return self->allocated;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_string_terminate
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_TERMINATE)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING void
Packit 1fb8d4
trio_string_terminate
Packit 1fb8d4
TRIO_ARGS1((self),
Packit 1fb8d4
	   trio_string_t *self)
Packit 1fb8d4
{
Packit 1fb8d4
  trio_xstring_append_char(self, 0);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Append the second string to the first.
Packit 1fb8d4
   
Packit 1fb8d4
   @param self Dynamic string to be modified.
Packit 1fb8d4
   @param other Dynamic string to copy from.
Packit 1fb8d4
   @return Boolean value indicating success or failure.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_APPEND)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_string_append
Packit 1fb8d4
TRIO_ARGS2((self, other),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   trio_string_t *other)
Packit 1fb8d4
{
Packit 1fb8d4
  size_t length;
Packit 1fb8d4
  
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
  assert(other);
Packit 1fb8d4
Packit 1fb8d4
  length = self->length + other->length;
Packit 1fb8d4
  if (!internal_string_grow_to(self, length))
Packit 1fb8d4
    goto error;
Packit 1fb8d4
  trio_copy(&self->content[self->length], other->content);
Packit 1fb8d4
  self->length = length;
Packit 1fb8d4
  return TRUE;
Packit 1fb8d4
  
Packit 1fb8d4
 error:
Packit 1fb8d4
  return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_xstring_append
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_XSTRING_APPEND)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_xstring_append
Packit 1fb8d4
TRIO_ARGS2((self, other),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   TRIO_CONST char *other)
Packit 1fb8d4
{
Packit 1fb8d4
  size_t length;
Packit 1fb8d4
  
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
  assert(other);
Packit 1fb8d4
Packit 1fb8d4
  length = self->length + trio_length(other);
Packit 1fb8d4
  if (!internal_string_grow_to(self, length))
Packit 1fb8d4
    goto error;
Packit 1fb8d4
  trio_copy(&self->content[self->length], other);
Packit 1fb8d4
  self->length = length;
Packit 1fb8d4
  return TRUE;
Packit 1fb8d4
  
Packit 1fb8d4
 error:
Packit 1fb8d4
  return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_xstring_append_char
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_xstring_append_char
Packit 1fb8d4
TRIO_ARGS2((self, character),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   char character)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
Packit 1fb8d4
  if ((int)self->length >= trio_string_size(self))
Packit 1fb8d4
    {
Packit 1fb8d4
      if (!internal_string_grow(self, 0))
Packit 1fb8d4
	goto error;
Packit 1fb8d4
    }
Packit 1fb8d4
  self->content[self->length] = character;
Packit 1fb8d4
  self->length++;
Packit 1fb8d4
  return TRUE;
Packit 1fb8d4
  
Packit 1fb8d4
 error:
Packit 1fb8d4
  return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_xstring_append_max
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_XSTRING_APPEND_MAX)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_xstring_append_max
Packit 1fb8d4
TRIO_ARGS3((self, other, max),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   TRIO_CONST char *other,
Packit 1fb8d4
           size_t max)
Packit 1fb8d4
{
Packit 1fb8d4
  size_t length;
Packit 1fb8d4
  
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
  assert(other);
Packit 1fb8d4
Packit 1fb8d4
  length = self->length + trio_length_max(other, max);
Packit 1fb8d4
  if (!internal_string_grow_to(self, length))
Packit 1fb8d4
    goto error;
Packit 1fb8d4
Packit 1fb8d4
  /*
Packit 1fb8d4
   * Pass max + 1 since trio_copy_max copies one character less than
Packit 1fb8d4
   * this from the source to make room for a terminating zero.
Packit 1fb8d4
   */
Packit 1fb8d4
  trio_copy_max(&self->content[self->length], max + 1, other);
Packit 1fb8d4
  self->length = length;
Packit 1fb8d4
  return TRUE;
Packit 1fb8d4
  
Packit 1fb8d4
 error:
Packit 1fb8d4
  return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Search for the first occurrence of second parameter in the first.
Packit 1fb8d4
   
Packit 1fb8d4
   @param self Dynamic string to be modified.
Packit 1fb8d4
   @param other Dynamic string to copy from.
Packit 1fb8d4
   @return Boolean value indicating success or failure.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_CONTAINS)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_string_contains
Packit 1fb8d4
TRIO_ARGS2((self, other),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   trio_string_t *other)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
  assert(other);
Packit 1fb8d4
Packit 1fb8d4
  return trio_contains(self->content, other->content);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_xstring_contains
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_XSTRING_CONTAINS)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_xstring_contains
Packit 1fb8d4
TRIO_ARGS2((self, other),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   TRIO_CONST char *other)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
  assert(other);
Packit 1fb8d4
Packit 1fb8d4
  return trio_contains(self->content, other);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_string_copy
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_COPY)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_string_copy
Packit 1fb8d4
TRIO_ARGS2((self, other),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   trio_string_t *other)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
  assert(other);
Packit 1fb8d4
Packit 1fb8d4
  self->length = 0;
Packit 1fb8d4
  return trio_string_append(self, other);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_xstring_copy
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_XSTRING_COPY)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_xstring_copy
Packit 1fb8d4
TRIO_ARGS2((self, other),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   TRIO_CONST char *other)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
  assert(other);
Packit 1fb8d4
Packit 1fb8d4
  self->length = 0;
Packit 1fb8d4
  return trio_xstring_append(self, other);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_string_duplicate
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_DUPLICATE)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING trio_string_t *
Packit 1fb8d4
trio_string_duplicate
Packit 1fb8d4
TRIO_ARGS1((other),
Packit 1fb8d4
	   trio_string_t *other)
Packit 1fb8d4
{
Packit 1fb8d4
  trio_string_t *self;
Packit 1fb8d4
  
Packit 1fb8d4
  assert(other);
Packit 1fb8d4
Packit 1fb8d4
  self = internal_string_alloc();
Packit 1fb8d4
  if (self)
Packit 1fb8d4
    {
Packit 1fb8d4
      self->content = internal_duplicate_max(other->content, other->length);
Packit 1fb8d4
      if (self->content)
Packit 1fb8d4
	{
Packit 1fb8d4
	  self->length = other->length;
Packit 1fb8d4
	  self->allocated = self->length + 1;
Packit 1fb8d4
	}
Packit 1fb8d4
      else
Packit 1fb8d4
	{
Packit 1fb8d4
	  self->length = self->allocated = 0;
Packit 1fb8d4
	}
Packit 1fb8d4
    }
Packit 1fb8d4
  return self;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_xstring_duplicate
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_XSTRING_DUPLICATE)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING trio_string_t *
Packit 1fb8d4
trio_xstring_duplicate
Packit 1fb8d4
TRIO_ARGS1((other),
Packit 1fb8d4
	   TRIO_CONST char *other)
Packit 1fb8d4
{
Packit 1fb8d4
  trio_string_t *self;
Packit 1fb8d4
  
Packit 1fb8d4
  assert(other);
Packit 1fb8d4
Packit 1fb8d4
  self = internal_string_alloc();
Packit 1fb8d4
  if (self)
Packit 1fb8d4
    {
Packit 1fb8d4
      self->content = internal_duplicate_max(other, trio_length(other));
Packit 1fb8d4
      if (self->content)
Packit 1fb8d4
	{
Packit 1fb8d4
	  self->length = trio_length(self->content);
Packit 1fb8d4
	  self->allocated = self->length + 1;
Packit 1fb8d4
	}
Packit 1fb8d4
      else
Packit 1fb8d4
	{
Packit 1fb8d4
	  self->length = self->allocated = 0;
Packit 1fb8d4
	}
Packit 1fb8d4
    }
Packit 1fb8d4
  return self;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_string_equal
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_EQUAL)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_string_equal
Packit 1fb8d4
TRIO_ARGS2((self, other),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   trio_string_t *other)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
  assert(other);
Packit 1fb8d4
Packit 1fb8d4
  return trio_equal(self->content, other->content);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_xstring_equal
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_XSTRING_EQUAL)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_xstring_equal
Packit 1fb8d4
TRIO_ARGS2((self, other),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   TRIO_CONST char *other)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
  assert(other);
Packit 1fb8d4
Packit 1fb8d4
  return trio_equal(self->content, other);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_string_equal_max
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_EQUAL_MAX)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_string_equal_max
Packit 1fb8d4
TRIO_ARGS3((self, max, other),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   size_t max,
Packit 1fb8d4
	   trio_string_t *other)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
  assert(other);
Packit 1fb8d4
Packit 1fb8d4
  return trio_equal_max(self->content, max, other->content);
Packit 1fb8d4
}
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_xstring_equal_max
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_XSTRING_EQUAL_MAX)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_xstring_equal_max
Packit 1fb8d4
TRIO_ARGS3((self, max, other),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   size_t max,
Packit 1fb8d4
	   TRIO_CONST char *other)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
  assert(other);
Packit 1fb8d4
Packit 1fb8d4
  return trio_equal_max(self->content, max, other);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_string_equal_case
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_EQUAL_CASE)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_string_equal_case
Packit 1fb8d4
TRIO_ARGS2((self, other),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   trio_string_t *other)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
  assert(other);
Packit 1fb8d4
Packit 1fb8d4
  return trio_equal_case(self->content, other->content);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_xstring_equal_case
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_xstring_equal_case
Packit 1fb8d4
TRIO_ARGS2((self, other),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   TRIO_CONST char *other)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
  assert(other);
Packit 1fb8d4
Packit 1fb8d4
  return trio_equal_case(self->content, other);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_string_equal_case_max
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_EQUAL_CASE_MAX)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_string_equal_case_max
Packit 1fb8d4
TRIO_ARGS3((self, max, other),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   size_t max,
Packit 1fb8d4
	   trio_string_t *other)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
  assert(other);
Packit 1fb8d4
Packit 1fb8d4
  return trio_equal_case_max(self->content, max, other->content);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_xstring_equal_case_max
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE_MAX)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_xstring_equal_case_max
Packit 1fb8d4
TRIO_ARGS3((self, max, other),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   size_t max,
Packit 1fb8d4
	   TRIO_CONST char *other)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
  assert(other);
Packit 1fb8d4
Packit 1fb8d4
  return trio_equal_case_max(self->content, max, other);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_string_format_data_max
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_FORMAT_DATE_MAX)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING size_t
Packit 1fb8d4
trio_string_format_date_max
Packit 1fb8d4
TRIO_ARGS4((self, max, format, datetime),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   size_t max,
Packit 1fb8d4
	   TRIO_CONST char *format,
Packit 1fb8d4
	   TRIO_CONST struct tm *datetime)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
Packit 1fb8d4
  return trio_format_date_max(self->content, max, format, datetime);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_string_index
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_INDEX)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING char *
Packit 1fb8d4
trio_string_index
Packit 1fb8d4
TRIO_ARGS2((self, character),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   int character)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
Packit 1fb8d4
  return trio_index(self->content, character);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_string_index_last
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_INDEX_LAST)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING char *
Packit 1fb8d4
trio_string_index_last
Packit 1fb8d4
TRIO_ARGS2((self, character),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   int character)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
Packit 1fb8d4
  return trio_index_last(self->content, character);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_string_length
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_LENGTH)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_string_length
Packit 1fb8d4
TRIO_ARGS1((self),
Packit 1fb8d4
	   trio_string_t *self)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
Packit 1fb8d4
  if (self->length == 0)
Packit 1fb8d4
    {
Packit 1fb8d4
      self->length = trio_length(self->content);
Packit 1fb8d4
    }
Packit 1fb8d4
  return self->length;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_string_lower
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_LOWER)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_string_lower
Packit 1fb8d4
TRIO_ARGS1((self),
Packit 1fb8d4
	   trio_string_t *self)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
Packit 1fb8d4
  return trio_lower(self->content);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_string_match
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_MATCH)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_string_match
Packit 1fb8d4
TRIO_ARGS2((self, other),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   trio_string_t *other)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
  assert(other);
Packit 1fb8d4
Packit 1fb8d4
  return trio_match(self->content, other->content);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_xstring_match
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_XSTRING_MATCH)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_xstring_match
Packit 1fb8d4
TRIO_ARGS2((self, other),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   TRIO_CONST char *other)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
  assert(other);
Packit 1fb8d4
Packit 1fb8d4
  return trio_match(self->content, other);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_string_match_case
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_MATCH_CASE)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_string_match_case
Packit 1fb8d4
TRIO_ARGS2((self, other),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   trio_string_t *other)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
  assert(other);
Packit 1fb8d4
Packit 1fb8d4
  return trio_match_case(self->content, other->content);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_xstring_match_case
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_XSTRING_MATCH_CASE)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_xstring_match_case
Packit 1fb8d4
TRIO_ARGS2((self, other),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   TRIO_CONST char *other)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
  assert(other);
Packit 1fb8d4
Packit 1fb8d4
  return trio_match_case(self->content, other);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_string_substring
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_SUBSTRING)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING char *
Packit 1fb8d4
trio_string_substring
Packit 1fb8d4
TRIO_ARGS2((self, other),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   trio_string_t *other)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
  assert(other);
Packit 1fb8d4
Packit 1fb8d4
  return trio_substring(self->content, other->content);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_xstring_substring
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_XSTRING_SUBSTRING)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING char *
Packit 1fb8d4
trio_xstring_substring
Packit 1fb8d4
TRIO_ARGS2((self, other),
Packit 1fb8d4
	   trio_string_t *self,
Packit 1fb8d4
	   TRIO_CONST char *other)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
  assert(other);
Packit 1fb8d4
Packit 1fb8d4
  return trio_substring(self->content, other);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_string_upper
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_UPPER)
Packit 1fb8d4
Packit 1fb8d4
TRIO_PUBLIC_STRING int
Packit 1fb8d4
trio_string_upper
Packit 1fb8d4
TRIO_ARGS1((self),
Packit 1fb8d4
	   trio_string_t *self)
Packit 1fb8d4
{
Packit 1fb8d4
  assert(self);
Packit 1fb8d4
Packit 1fb8d4
  return trio_upper(self->content);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/** @} End of DynamicStrings */