Blame triostr.c

Packit 21b7a2
/*************************************************************************
Packit 21b7a2
 *
Packit 21b7a2
 * $Id$
Packit 21b7a2
 *
Packit 21b7a2
 * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
Packit 21b7a2
 *
Packit 21b7a2
 * Permission to use, copy, modify, and distribute this software for any
Packit 21b7a2
 * purpose with or without fee is hereby granted, provided that the above
Packit 21b7a2
 * copyright notice and this permission notice appear in all copies.
Packit 21b7a2
 *
Packit 21b7a2
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
Packit 21b7a2
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
Packit 21b7a2
 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
Packit 21b7a2
 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
Packit 21b7a2
 *
Packit 21b7a2
 ************************************************************************/
Packit 21b7a2
Packit 21b7a2
/*************************************************************************
Packit 21b7a2
 * Include files
Packit 21b7a2
 */
Packit 21b7a2
Packit 21b7a2
#include <assert.h>
Packit 21b7a2
#include <stdlib.h>
Packit 21b7a2
#include <string.h>
Packit 21b7a2
#include <ctype.h>
Packit 21b7a2
#include <math.h>
Packit 21b7a2
#include "triodef.h"
Packit 21b7a2
#include "triostr.h"
Packit 21b7a2
Packit 21b7a2
/*************************************************************************
Packit 21b7a2
 * Definitions
Packit 21b7a2
 */
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_STRING_PUBLIC)
Packit 21b7a2
# define TRIO_STRING_PUBLIC TRIO_PUBLIC
Packit 21b7a2
#endif
Packit 21b7a2
#if !defined(TRIO_STRING_PRIVATE)
Packit 21b7a2
# define TRIO_STRING_PRIVATE TRIO_PRIVATE
Packit 21b7a2
#endif
Packit 21b7a2
Packit 21b7a2
#if !defined(NULL)
Packit 21b7a2
# define NULL 0
Packit 21b7a2
#endif
Packit 21b7a2
#if !defined(NIL)
Packit 21b7a2
# define NIL ((char)0)
Packit 21b7a2
#endif
Packit 21b7a2
#if !defined(FALSE)
Packit 21b7a2
# define FALSE (1 == 0)
Packit 21b7a2
# define TRUE (! FALSE)
Packit 21b7a2
#endif
Packit 21b7a2
#if !defined(BOOLEAN_T)
Packit 21b7a2
# define BOOLEAN_T int
Packit 21b7a2
#endif
Packit 21b7a2
Packit 21b7a2
#ifdef __VMS
Packit 21b7a2
# define USE_STRTOD
Packit 21b7a2
#elif defined(TRIO_COMPILER_SUPPORTS_C99)
Packit 21b7a2
# define USE_STRTOD
Packit 21b7a2
# define USE_STRTOF
Packit 21b7a2
#elif defined(TRIO_COMPILER_MSVC)
Packit 21b7a2
# define USE_STRTOD
Packit 21b7a2
#endif
Packit 21b7a2
Packit 21b7a2
#if defined(TRIO_PLATFORM_UNIX)
Packit 21b7a2
# define USE_STRCASECMP
Packit 21b7a2
# define USE_STRNCASECMP
Packit 21b7a2
# if defined(TRIO_PLATFORM_SUNOS)
Packit 21b7a2
#  define USE_SYS_ERRLIST
Packit 21b7a2
# else
Packit 21b7a2
#  define USE_STRERROR
Packit 21b7a2
# endif
Packit 21b7a2
# if defined(TRIO_PLATFORM_QNX)
Packit 21b7a2
#  define strcasecmp(x,y) stricmp(x,y)
Packit 21b7a2
#  define strncasecmp(x,y,n) strnicmp(x,y,n)
Packit 21b7a2
# endif
Packit 21b7a2
#elif defined(TRIO_PLATFORM_WIN32)
Packit 21b7a2
# define USE_STRCASECMP
Packit 21b7a2
# if defined(_WIN32_WCE)
Packit 21b7a2
#  define strcasecmp(x,y) _stricmp(x,y)
Packit 21b7a2
# else
Packit 21b7a2
#  define strcasecmp(x,y) strcmpi(x,y)
Packit 21b7a2
# endif
Packit 21b7a2
#elif defined(TRIO_PLATFORM_OS400)
Packit 21b7a2
# define USE_STRCASECMP
Packit 21b7a2
# define USE_STRNCASECMP
Packit 21b7a2
# include <strings.h>
Packit 21b7a2
#endif
Packit 21b7a2
Packit 21b7a2
#if !(defined(TRIO_PLATFORM_SUNOS))
Packit 21b7a2
# define USE_TOLOWER
Packit 21b7a2
# define USE_TOUPPER
Packit 21b7a2
#endif
Packit 21b7a2
Packit 21b7a2
/*************************************************************************
Packit 21b7a2
 * Structures
Packit 21b7a2
 */
Packit 21b7a2
Packit 21b7a2
struct _trio_string_t
Packit 21b7a2
{
Packit 21b7a2
  char *content;
Packit 21b7a2
  size_t length;
Packit 21b7a2
  size_t allocated;
Packit 21b7a2
};
Packit 21b7a2
Packit 21b7a2
/*************************************************************************
Packit 21b7a2
 * Constants
Packit 21b7a2
 */
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
static TRIO_CONST char rcsid[] = "@(#)$Id$";
Packit 21b7a2
#endif
Packit 21b7a2
Packit 21b7a2
/*************************************************************************
Packit 21b7a2
 * Static String Functions
Packit 21b7a2
 */
Packit 21b7a2
Packit 21b7a2
#if defined(TRIO_DOCUMENTATION)
Packit 21b7a2
# include "doc/doc_static.h"
Packit 21b7a2
#endif
Packit 21b7a2
/** @addtogroup StaticStrings
Packit 21b7a2
    @{
Packit 21b7a2
*/
Packit 21b7a2
Packit 21b7a2
/**
Packit 21b7a2
   Create new string.
Packit 21b7a2
Packit 21b7a2
   @param size Size of new string.
Packit 21b7a2
   @return Pointer to string, or NULL if allocation failed.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC char *
Packit 21b7a2
trio_create
Packit 21b7a2
TRIO_ARGS1((size),
Packit 21b7a2
	   size_t size)
Packit 21b7a2
{
Packit 21b7a2
  return (char *)TRIO_MALLOC(size);
Packit 21b7a2
}
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
/**
Packit 21b7a2
   Destroy string.
Packit 21b7a2
Packit 21b7a2
   @param string String to be freed.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC void
Packit 21b7a2
trio_destroy
Packit 21b7a2
TRIO_ARGS1((string),
Packit 21b7a2
	   char *string)
Packit 21b7a2
{
Packit 21b7a2
  if (string)
Packit 21b7a2
    {
Packit 21b7a2
      TRIO_FREE(string);
Packit 21b7a2
    }
Packit 21b7a2
}
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
/**
Packit 21b7a2
   Count the number of characters in a string.
Packit 21b7a2
Packit 21b7a2
   @param string String to measure.
Packit 21b7a2
   @return Number of characters in @string.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC size_t
Packit 21b7a2
trio_length
Packit 21b7a2
TRIO_ARGS1((string),
Packit 21b7a2
	   TRIO_CONST char *string)
Packit 21b7a2
{
Packit 21b7a2
  return strlen(string);
Packit 21b7a2
}
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/**
Packit 21b7a2
   Append @p source at the end of @p target.
Packit 21b7a2
Packit 21b7a2
   @param target Target string.
Packit 21b7a2
   @param source Source string.
Packit 21b7a2
   @return Boolean value indicating success or failure.
Packit 21b7a2
Packit 21b7a2
   @pre @p target must point to a memory chunk with sufficient room to
Packit 21b7a2
   contain the @p target string and @p source string.
Packit 21b7a2
   @pre No boundary checking is performed, so insufficient memory will
Packit 21b7a2
   result in a buffer overrun.
Packit 21b7a2
   @post @p target will be zero terminated.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_append
Packit 21b7a2
TRIO_ARGS2((target, source),
Packit 21b7a2
	   char *target,
Packit 21b7a2
	   TRIO_CONST char *source)
Packit 21b7a2
{
Packit 21b7a2
  assert(target);
Packit 21b7a2
  assert(source);
Packit 21b7a2
Packit 21b7a2
  return (strcat(target, source) != NULL);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/**
Packit 21b7a2
   Append at most @p max characters from @p source to @p target.
Packit 21b7a2
Packit 21b7a2
   @param target Target string.
Packit 21b7a2
   @param max Maximum number of characters to append.
Packit 21b7a2
   @param source Source string.
Packit 21b7a2
   @return Boolean value indicating success or failure.
Packit 21b7a2
Packit 21b7a2
   @pre @p target must point to a memory chuck with sufficient room to
Packit 21b7a2
   contain the @p target string and the @p source string (at most @p max
Packit 21b7a2
   characters).
Packit 21b7a2
   @pre No boundary checking is performed, so insufficient memory will
Packit 21b7a2
   result in a buffer overrun.
Packit 21b7a2
   @post @p target will be zero terminated.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_append_max
Packit 21b7a2
TRIO_ARGS3((target, max, source),
Packit 21b7a2
	   char *target,
Packit 21b7a2
	   size_t max,
Packit 21b7a2
	   TRIO_CONST char *source)
Packit 21b7a2
{
Packit 21b7a2
  size_t length;
Packit 21b7a2
Packit 21b7a2
  assert(target);
Packit 21b7a2
  assert(source);
Packit 21b7a2
Packit 21b7a2
  length = trio_length(target);
Packit 21b7a2
Packit 21b7a2
  if (max > length)
Packit 21b7a2
    {
Packit 21b7a2
      strncat(target, source, max - length - 1);
Packit 21b7a2
    }
Packit 21b7a2
  return TRUE;
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/**
Packit 21b7a2
   Determine if a string contains a substring.
Packit 21b7a2
Packit 21b7a2
   @param string String to be searched.
Packit 21b7a2
   @param substring String to be found.
Packit 21b7a2
   @return Boolean value indicating success or failure.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_contains
Packit 21b7a2
TRIO_ARGS2((string, substring),
Packit 21b7a2
	   TRIO_CONST char *string,
Packit 21b7a2
	   TRIO_CONST char *substring)
Packit 21b7a2
{
Packit 21b7a2
  assert(string);
Packit 21b7a2
  assert(substring);
Packit 21b7a2
Packit 21b7a2
  return (0 != strstr(string, substring));
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/**
Packit 21b7a2
   Copy @p source to @p target.
Packit 21b7a2
Packit 21b7a2
   @param target Target string.
Packit 21b7a2
   @param source Source string.
Packit 21b7a2
   @return Boolean value indicating success or failure.
Packit 21b7a2
Packit 21b7a2
   @pre @p target must point to a memory chunk with sufficient room to
Packit 21b7a2
   contain the @p source string.
Packit 21b7a2
   @pre No boundary checking is performed, so insufficient memory will
Packit 21b7a2
   result in a buffer overrun.
Packit 21b7a2
   @post @p target will be zero terminated.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_copy
Packit 21b7a2
TRIO_ARGS2((target, source),
Packit 21b7a2
	   char *target,
Packit 21b7a2
	   TRIO_CONST char *source)
Packit 21b7a2
{
Packit 21b7a2
  assert(target);
Packit 21b7a2
  assert(source);
Packit 21b7a2
Packit 21b7a2
  (void)strcpy(target, source);
Packit 21b7a2
  return TRUE;
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
/**
Packit 21b7a2
   Copy at most @p max characters from @p source to @p target.
Packit 21b7a2
Packit 21b7a2
   @param target Target string.
Packit 21b7a2
   @param max Maximum number of characters to append.
Packit 21b7a2
   @param source Source string.
Packit 21b7a2
   @return Boolean value indicating success or failure.
Packit 21b7a2
Packit 21b7a2
   @pre @p target must point to a memory chunk with sufficient room to
Packit 21b7a2
   contain the @p source string (at most @p max characters).
Packit 21b7a2
   @pre No boundary checking is performed, so insufficient memory will
Packit 21b7a2
   result in a buffer overrun.
Packit 21b7a2
   @post @p target will be zero terminated.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_copy_max
Packit 21b7a2
TRIO_ARGS3((target, max, source),
Packit 21b7a2
	   char *target,
Packit 21b7a2
	   size_t max,
Packit 21b7a2
	   TRIO_CONST char *source)
Packit 21b7a2
{
Packit 21b7a2
  assert(target);
Packit 21b7a2
  assert(source);
Packit 21b7a2
  assert(max > 0); /* Includes != 0 */
Packit 21b7a2
Packit 21b7a2
  (void)strncpy(target, source, max - 1);
Packit 21b7a2
  target[max - 1] = (char)0;
Packit 21b7a2
  return TRUE;
Packit 21b7a2
}
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
/*
Packit 21b7a2
 * TrioDuplicateMax
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PRIVATE char *
Packit 21b7a2
TrioDuplicateMax
Packit 21b7a2
TRIO_ARGS2((source, size),
Packit 21b7a2
	   TRIO_CONST char *source,
Packit 21b7a2
	   size_t size)
Packit 21b7a2
{
Packit 21b7a2
  char *target;
Packit 21b7a2
Packit 21b7a2
  assert(source);
Packit 21b7a2
Packit 21b7a2
  /* Make room for string plus a terminating zero */
Packit 21b7a2
  size++;
Packit 21b7a2
  target = trio_create(size);
Packit 21b7a2
  if (target)
Packit 21b7a2
    {
Packit 21b7a2
      trio_copy_max(target, size, source);
Packit 21b7a2
    }
Packit 21b7a2
  return target;
Packit 21b7a2
}
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
/**
Packit 21b7a2
   Duplicate @p source.
Packit 21b7a2
Packit 21b7a2
   @param source Source string.
Packit 21b7a2
   @return A copy of the @p source string.
Packit 21b7a2
Packit 21b7a2
   @post @p target will be zero terminated.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC char *
Packit 21b7a2
trio_duplicate
Packit 21b7a2
TRIO_ARGS1((source),
Packit 21b7a2
	   TRIO_CONST char *source)
Packit 21b7a2
{
Packit 21b7a2
  return TrioDuplicateMax(source, trio_length(source));
Packit 21b7a2
}
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/**
Packit 21b7a2
   Duplicate at most @p max characters of @p source.
Packit 21b7a2
Packit 21b7a2
   @param source Source string.
Packit 21b7a2
   @param max Maximum number of characters to duplicate.
Packit 21b7a2
   @return A copy of the @p source string.
Packit 21b7a2
Packit 21b7a2
   @post @p target will be zero terminated.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC char *
Packit 21b7a2
trio_duplicate_max TRIO_ARGS2((source, max),
Packit 21b7a2
			      TRIO_CONST char *source,
Packit 21b7a2
			      size_t max)
Packit 21b7a2
{
Packit 21b7a2
  size_t length;
Packit 21b7a2
Packit 21b7a2
  assert(source);
Packit 21b7a2
  assert(max > 0);
Packit 21b7a2
Packit 21b7a2
  length = trio_length(source);
Packit 21b7a2
  if (length > max)
Packit 21b7a2
    {
Packit 21b7a2
      length = max;
Packit 21b7a2
    }
Packit 21b7a2
  return TrioDuplicateMax(source, length);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
/**
Packit 21b7a2
   Compare if two strings are equal.
Packit 21b7a2
Packit 21b7a2
   @param first First string.
Packit 21b7a2
   @param second Second string.
Packit 21b7a2
   @return Boolean indicating whether the two strings are equal or not.
Packit 21b7a2
Packit 21b7a2
   Case-insensitive comparison.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_equal
Packit 21b7a2
TRIO_ARGS2((first, second),
Packit 21b7a2
	   TRIO_CONST char *first,
Packit 21b7a2
	   TRIO_CONST char *second)
Packit 21b7a2
{
Packit 21b7a2
  assert(first);
Packit 21b7a2
  assert(second);
Packit 21b7a2
Packit 21b7a2
  if ((first != NULL) && (second != NULL))
Packit 21b7a2
    {
Packit 21b7a2
#if defined(USE_STRCASECMP)
Packit 21b7a2
      return (0 == strcasecmp(first, second));
Packit 21b7a2
#else
Packit 21b7a2
      while ((*first != NIL) && (*second != NIL))
Packit 21b7a2
	{
Packit 21b7a2
	  if (trio_to_upper(*first) != trio_to_upper(*second))
Packit 21b7a2
	    {
Packit 21b7a2
	      break;
Packit 21b7a2
	    }
Packit 21b7a2
	  first++;
Packit 21b7a2
	  second++;
Packit 21b7a2
	}
Packit 21b7a2
      return ((*first == NIL) && (*second == NIL));
Packit 21b7a2
#endif
Packit 21b7a2
    }
Packit 21b7a2
  return FALSE;
Packit 21b7a2
}
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
/**
Packit 21b7a2
   Compare if two strings are equal.
Packit 21b7a2
Packit 21b7a2
   @param first First string.
Packit 21b7a2
   @param second Second string.
Packit 21b7a2
   @return Boolean indicating whether the two strings are equal or not.
Packit 21b7a2
Packit 21b7a2
   Case-sensitive comparison.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_equal_case
Packit 21b7a2
TRIO_ARGS2((first, second),
Packit 21b7a2
	   TRIO_CONST char *first,
Packit 21b7a2
	   TRIO_CONST char *second)
Packit 21b7a2
{
Packit 21b7a2
  assert(first);
Packit 21b7a2
  assert(second);
Packit 21b7a2
Packit 21b7a2
  if ((first != NULL) && (second != NULL))
Packit 21b7a2
    {
Packit 21b7a2
      return (0 == strcmp(first, second));
Packit 21b7a2
    }
Packit 21b7a2
  return FALSE;
Packit 21b7a2
}
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/**
Packit 21b7a2
   Compare if two strings up until the first @p max characters are equal.
Packit 21b7a2
Packit 21b7a2
   @param first First string.
Packit 21b7a2
   @param max Maximum number of characters to compare.
Packit 21b7a2
   @param second Second string.
Packit 21b7a2
   @return Boolean indicating whether the two strings are equal or not.
Packit 21b7a2
Packit 21b7a2
   Case-sensitive comparison.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_equal_case_max
Packit 21b7a2
TRIO_ARGS3((first, max, second),
Packit 21b7a2
	   TRIO_CONST char *first,
Packit 21b7a2
	   size_t max,
Packit 21b7a2
	   TRIO_CONST char *second)
Packit 21b7a2
{
Packit 21b7a2
  assert(first);
Packit 21b7a2
  assert(second);
Packit 21b7a2
Packit 21b7a2
  if ((first != NULL) && (second != NULL))
Packit 21b7a2
    {
Packit 21b7a2
      return (0 == strncmp(first, second, max));
Packit 21b7a2
    }
Packit 21b7a2
  return FALSE;
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
/**
Packit 21b7a2
   Compare if two strings are equal.
Packit 21b7a2
Packit 21b7a2
   @param first First string.
Packit 21b7a2
   @param second Second string.
Packit 21b7a2
   @return Boolean indicating whether the two strings are equal or not.
Packit 21b7a2
Packit 21b7a2
   Collating characters are considered equal.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_equal_locale
Packit 21b7a2
TRIO_ARGS2((first, second),
Packit 21b7a2
	   TRIO_CONST char *first,
Packit 21b7a2
	   TRIO_CONST char *second)
Packit 21b7a2
{
Packit 21b7a2
  assert(first);
Packit 21b7a2
  assert(second);
Packit 21b7a2
Packit 21b7a2
#if defined(LC_COLLATE)
Packit 21b7a2
  return (strcoll(first, second) == 0);
Packit 21b7a2
#else
Packit 21b7a2
  return trio_equal(first, second);
Packit 21b7a2
#endif
Packit 21b7a2
}
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
/**
Packit 21b7a2
   Compare if two strings up until the first @p max characters are equal.
Packit 21b7a2
Packit 21b7a2
   @param first First string.
Packit 21b7a2
   @param max Maximum number of characters to compare.
Packit 21b7a2
   @param second Second string.
Packit 21b7a2
   @return Boolean indicating whether the two strings are equal or not.
Packit 21b7a2
Packit 21b7a2
   Case-insensitive comparison.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_equal_max
Packit 21b7a2
TRIO_ARGS3((first, max, second),
Packit 21b7a2
	   TRIO_CONST char *first,
Packit 21b7a2
	   size_t max,
Packit 21b7a2
	   TRIO_CONST char *second)
Packit 21b7a2
{
Packit 21b7a2
  assert(first);
Packit 21b7a2
  assert(second);
Packit 21b7a2
Packit 21b7a2
  if ((first != NULL) && (second != NULL))
Packit 21b7a2
    {
Packit 21b7a2
#if defined(USE_STRNCASECMP)
Packit 21b7a2
      return (0 == strncasecmp(first, second, max));
Packit 21b7a2
#else
Packit 21b7a2
      /* Not adequately tested yet */
Packit 21b7a2
      size_t cnt = 0;
Packit 21b7a2
      while ((*first != NIL) && (*second != NIL) && (cnt <= max))
Packit 21b7a2
	{
Packit 21b7a2
	  if (trio_to_upper(*first) != trio_to_upper(*second))
Packit 21b7a2
	    {
Packit 21b7a2
	      break;
Packit 21b7a2
	    }
Packit 21b7a2
	  first++;
Packit 21b7a2
	  second++;
Packit 21b7a2
	  cnt++;
Packit 21b7a2
	}
Packit 21b7a2
      return ((cnt == max) || ((*first == NIL) && (*second == NIL)));
Packit 21b7a2
#endif
Packit 21b7a2
    }
Packit 21b7a2
  return FALSE;
Packit 21b7a2
}
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
/**
Packit 21b7a2
   Provide a textual description of an error code (errno).
Packit 21b7a2
Packit 21b7a2
   @param error_number Error number.
Packit 21b7a2
   @return Textual description of @p error_number.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC TRIO_CONST char *
Packit 21b7a2
trio_error
Packit 21b7a2
TRIO_ARGS1((error_number),
Packit 21b7a2
	   int error_number)
Packit 21b7a2
{
Packit 21b7a2
#if defined(USE_STRERROR)
Packit 21b7a2
Packit 21b7a2
  return strerror(error_number);
Packit 21b7a2
Packit 21b7a2
#elif defined(USE_SYS_ERRLIST)
Packit 21b7a2
Packit 21b7a2
  extern char *sys_errlist[];
Packit 21b7a2
  extern int sys_nerr;
Packit 21b7a2
Packit 21b7a2
  return ((error_number < 0) || (error_number >= sys_nerr))
Packit 21b7a2
    ? "unknown"
Packit 21b7a2
    : sys_errlist[error_number];
Packit 21b7a2
Packit 21b7a2
#else
Packit 21b7a2
Packit 21b7a2
  return "unknown";
Packit 21b7a2
Packit 21b7a2
#endif
Packit 21b7a2
}
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL) && !defined(_WIN32_WCE)
Packit 21b7a2
/**
Packit 21b7a2
   Format the date/time according to @p format.
Packit 21b7a2
Packit 21b7a2
   @param target Target string.
Packit 21b7a2
   @param max Maximum number of characters to format.
Packit 21b7a2
   @param format Formatting string.
Packit 21b7a2
   @param datetime Date/time structure.
Packit 21b7a2
   @return Number of formatted characters.
Packit 21b7a2
Packit 21b7a2
   The formatting string accepts the same specifiers as the standard C
Packit 21b7a2
   function strftime.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC size_t
Packit 21b7a2
trio_format_date_max
Packit 21b7a2
TRIO_ARGS4((target, max, format, datetime),
Packit 21b7a2
	   char *target,
Packit 21b7a2
	   size_t max,
Packit 21b7a2
	   TRIO_CONST char *format,
Packit 21b7a2
	   TRIO_CONST struct tm *datetime)
Packit 21b7a2
{
Packit 21b7a2
  assert(target);
Packit 21b7a2
  assert(format);
Packit 21b7a2
  assert(datetime);
Packit 21b7a2
  assert(max > 0);
Packit 21b7a2
Packit 21b7a2
  return strftime(target, max, format, datetime);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/**
Packit 21b7a2
   Calculate a hash value for a string.
Packit 21b7a2
Packit 21b7a2
   @param string String to be calculated on.
Packit 21b7a2
   @param type Hash function.
Packit 21b7a2
   @return Calculated hash value.
Packit 21b7a2
Packit 21b7a2
   @p type can be one of the following
Packit 21b7a2
   @li @c TRIO_HASH_PLAIN Plain hash function.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC unsigned long
Packit 21b7a2
trio_hash
Packit 21b7a2
TRIO_ARGS2((string, type),
Packit 21b7a2
	   TRIO_CONST char *string,
Packit 21b7a2
	   int type)
Packit 21b7a2
{
Packit 21b7a2
  unsigned long value = 0L;
Packit 21b7a2
  char ch;
Packit 21b7a2
Packit 21b7a2
  assert(string);
Packit 21b7a2
Packit 21b7a2
  switch (type)
Packit 21b7a2
    {
Packit 21b7a2
    case TRIO_HASH_PLAIN:
Packit 21b7a2
      while ( (ch = *string++) != NIL )
Packit 21b7a2
	{
Packit 21b7a2
	  value *= 31;
Packit 21b7a2
	  value += (unsigned long)ch;
Packit 21b7a2
	}
Packit 21b7a2
      break;
Packit 21b7a2
    default:
Packit 21b7a2
      assert(FALSE);
Packit 21b7a2
      break;
Packit 21b7a2
    }
Packit 21b7a2
  return value;
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/**
Packit 21b7a2
   Find first occurrence of a character in a string.
Packit 21b7a2
Packit 21b7a2
   @param string String to be searched.
Packit 21b7a2
   @param character Character to be found.
Packit 21b7a2
   @param A pointer to the found character, or NULL if character was not found.
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC char *
Packit 21b7a2
trio_index
Packit 21b7a2
TRIO_ARGS2((string, character),
Packit 21b7a2
	   TRIO_CONST char *string,
Packit 21b7a2
	   int character)
Packit 21b7a2
{
Packit 21b7a2
  assert(string);
Packit 21b7a2
Packit 21b7a2
  return strchr(string, character);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/**
Packit 21b7a2
   Find last occurrence of a character in a string.
Packit 21b7a2
Packit 21b7a2
   @param string String to be searched.
Packit 21b7a2
   @param character Character to be found.
Packit 21b7a2
   @param A pointer to the found character, or NULL if character was not found.
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC char *
Packit 21b7a2
trio_index_last
Packit 21b7a2
TRIO_ARGS2((string, character),
Packit 21b7a2
	   TRIO_CONST char *string,
Packit 21b7a2
	   int character)
Packit 21b7a2
{
Packit 21b7a2
  assert(string);
Packit 21b7a2
Packit 21b7a2
  return strchr(string, character);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/**
Packit 21b7a2
   Convert the alphabetic letters in the string to lower-case.
Packit 21b7a2
Packit 21b7a2
   @param target String to be converted.
Packit 21b7a2
   @return Number of processed characters (converted or not).
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_lower
Packit 21b7a2
TRIO_ARGS1((target),
Packit 21b7a2
	   char *target)
Packit 21b7a2
{
Packit 21b7a2
  assert(target);
Packit 21b7a2
Packit 21b7a2
  return trio_span_function(target, target, trio_to_lower);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/**
Packit 21b7a2
   Compare two strings using wildcards.
Packit 21b7a2
Packit 21b7a2
   @param string String to be searched.
Packit 21b7a2
   @param pattern Pattern, including wildcards, to search for.
Packit 21b7a2
   @return Boolean value indicating success or failure.
Packit 21b7a2
Packit 21b7a2
   Case-insensitive comparison.
Packit 21b7a2
Packit 21b7a2
   The following wildcards can be used
Packit 21b7a2
   @li @c * Match any number of characters.
Packit 21b7a2
   @li @c ? Match a single character.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_match
Packit 21b7a2
TRIO_ARGS2((string, pattern),
Packit 21b7a2
	   TRIO_CONST char *string,
Packit 21b7a2
	   TRIO_CONST char *pattern)
Packit 21b7a2
{
Packit 21b7a2
  assert(string);
Packit 21b7a2
  assert(pattern);
Packit 21b7a2
Packit 21b7a2
  for (; ('*' != *pattern); ++pattern, ++string)
Packit 21b7a2
    {
Packit 21b7a2
      if (NIL == *string)
Packit 21b7a2
	{
Packit 21b7a2
	  return (NIL == *pattern);
Packit 21b7a2
	}
Packit 21b7a2
      if ((trio_to_upper((int)*string) != trio_to_upper((int)*pattern))
Packit 21b7a2
	  && ('?' != *pattern))
Packit 21b7a2
	{
Packit 21b7a2
	  return FALSE;
Packit 21b7a2
	}
Packit 21b7a2
    }
Packit 21b7a2
  /* two-line patch to prevent *too* much recursiveness: */
Packit 21b7a2
  while ('*' == pattern[1])
Packit 21b7a2
    pattern++;
Packit 21b7a2
Packit 21b7a2
  do
Packit 21b7a2
    {
Packit 21b7a2
      if ( trio_match(string, &pattern[1]) )
Packit 21b7a2
	{
Packit 21b7a2
	  return TRUE;
Packit 21b7a2
	}
Packit 21b7a2
    }
Packit 21b7a2
  while (*string++);
Packit 21b7a2
Packit 21b7a2
  return FALSE;
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/**
Packit 21b7a2
   Compare two strings using wildcards.
Packit 21b7a2
Packit 21b7a2
   @param string String to be searched.
Packit 21b7a2
   @param pattern Pattern, including wildcards, to search for.
Packit 21b7a2
   @return Boolean value indicating success or failure.
Packit 21b7a2
Packit 21b7a2
   Case-sensitive comparison.
Packit 21b7a2
Packit 21b7a2
   The following wildcards can be used
Packit 21b7a2
   @li @c * Match any number of characters.
Packit 21b7a2
   @li @c ? Match a single character.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_match_case
Packit 21b7a2
TRIO_ARGS2((string, pattern),
Packit 21b7a2
	   TRIO_CONST char *string,
Packit 21b7a2
	   TRIO_CONST char *pattern)
Packit 21b7a2
{
Packit 21b7a2
  assert(string);
Packit 21b7a2
  assert(pattern);
Packit 21b7a2
Packit 21b7a2
  for (; ('*' != *pattern); ++pattern, ++string)
Packit 21b7a2
    {
Packit 21b7a2
      if (NIL == *string)
Packit 21b7a2
	{
Packit 21b7a2
	  return (NIL == *pattern);
Packit 21b7a2
	}
Packit 21b7a2
      if ((*string != *pattern)
Packit 21b7a2
	  && ('?' != *pattern))
Packit 21b7a2
	{
Packit 21b7a2
	  return FALSE;
Packit 21b7a2
	}
Packit 21b7a2
    }
Packit 21b7a2
  /* two-line patch to prevent *too* much recursiveness: */
Packit 21b7a2
  while ('*' == pattern[1])
Packit 21b7a2
    pattern++;
Packit 21b7a2
Packit 21b7a2
  do
Packit 21b7a2
    {
Packit 21b7a2
      if ( trio_match_case(string, &pattern[1]) )
Packit 21b7a2
	{
Packit 21b7a2
	  return TRUE;
Packit 21b7a2
	}
Packit 21b7a2
    }
Packit 21b7a2
  while (*string++);
Packit 21b7a2
Packit 21b7a2
  return FALSE;
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/**
Packit 21b7a2
   Execute a function on each character in string.
Packit 21b7a2
Packit 21b7a2
   @param target Target string.
Packit 21b7a2
   @param source Source string.
Packit 21b7a2
   @param Function Function to be executed.
Packit 21b7a2
   @return Number of processed characters.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC size_t
Packit 21b7a2
trio_span_function
Packit 21b7a2
TRIO_ARGS3((target, source, Function),
Packit 21b7a2
	   char *target,
Packit 21b7a2
	   TRIO_CONST char *source,
Packit 21b7a2
	   int (*Function) TRIO_PROTO((int)))
Packit 21b7a2
{
Packit 21b7a2
  size_t count = 0;
Packit 21b7a2
Packit 21b7a2
  assert(target);
Packit 21b7a2
  assert(source);
Packit 21b7a2
  assert(Function);
Packit 21b7a2
Packit 21b7a2
  while (*source != NIL)
Packit 21b7a2
    {
Packit 21b7a2
      *target++ = Function(*source++);
Packit 21b7a2
      count++;
Packit 21b7a2
    }
Packit 21b7a2
  return count;
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/**
Packit 21b7a2
   Search for a substring in a string.
Packit 21b7a2
Packit 21b7a2
   @param string String to be searched.
Packit 21b7a2
   @param substring String to be found.
Packit 21b7a2
   @return Pointer to first occurrence of @p substring in @p string, or NULL
Packit 21b7a2
   if no match was found.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC char *
Packit 21b7a2
trio_substring
Packit 21b7a2
TRIO_ARGS2((string, substring),
Packit 21b7a2
	   TRIO_CONST char *string,
Packit 21b7a2
	   TRIO_CONST char *substring)
Packit 21b7a2
{
Packit 21b7a2
  assert(string);
Packit 21b7a2
  assert(substring);
Packit 21b7a2
Packit 21b7a2
  return strstr(string, substring);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/**
Packit 21b7a2
   Search for a substring in the first @p max characters of a string.
Packit 21b7a2
Packit 21b7a2
   @param string String to be searched.
Packit 21b7a2
   @param max Maximum characters to be searched.
Packit 21b7a2
   @param substring String to be found.
Packit 21b7a2
   @return Pointer to first occurrence of @p substring in @p string, or NULL
Packit 21b7a2
   if no match was found.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC char *
Packit 21b7a2
trio_substring_max
Packit 21b7a2
TRIO_ARGS3((string, max, substring),
Packit 21b7a2
	   TRIO_CONST char *string,
Packit 21b7a2
	   size_t max,
Packit 21b7a2
	   TRIO_CONST char *substring)
Packit 21b7a2
{
Packit 21b7a2
  size_t count;
Packit 21b7a2
  size_t size;
Packit 21b7a2
  char *result = NULL;
Packit 21b7a2
Packit 21b7a2
  assert(string);
Packit 21b7a2
  assert(substring);
Packit 21b7a2
Packit 21b7a2
  size = trio_length(substring);
Packit 21b7a2
  if (size <= max)
Packit 21b7a2
    {
Packit 21b7a2
      for (count = 0; count <= max - size; count++)
Packit 21b7a2
	{
Packit 21b7a2
	  if (trio_equal_max(substring, size, &string[count]))
Packit 21b7a2
	    {
Packit 21b7a2
	      result = (char *)&string[count];
Packit 21b7a2
	      break;
Packit 21b7a2
	    }
Packit 21b7a2
	}
Packit 21b7a2
    }
Packit 21b7a2
  return result;
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/**
Packit 21b7a2
   Tokenize string.
Packit 21b7a2
Packit 21b7a2
   @param string String to be tokenized.
Packit 21b7a2
   @param tokens String containing list of delimiting characters.
Packit 21b7a2
   @return Start of new token.
Packit 21b7a2
Packit 21b7a2
   @warning @p string will be destroyed.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC char *
Packit 21b7a2
trio_tokenize
Packit 21b7a2
TRIO_ARGS2((string, delimiters),
Packit 21b7a2
	   char *string,
Packit 21b7a2
	   TRIO_CONST char *delimiters)
Packit 21b7a2
{
Packit 21b7a2
  assert(delimiters);
Packit 21b7a2
Packit 21b7a2
  return strtok(string, delimiters);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
/**
Packit 21b7a2
   Convert string to floating-point number.
Packit 21b7a2
Packit 21b7a2
   @param source String to be converted.
Packit 21b7a2
   @param endp Pointer to end of the converted string.
Packit 21b7a2
   @return A floating-point number.
Packit 21b7a2
Packit 21b7a2
   The following Extended Backus-Naur form is used
Packit 21b7a2
   @verbatim
Packit 21b7a2
   double        ::= [ <sign> ]
Packit 21b7a2
                     ( <number> |
Packit 21b7a2
                       <number> <decimal_point> <number> |
Packit 21b7a2
                       <decimal_point> <number> )
Packit 21b7a2
                     [ <exponential> [ <sign> ] <number> ]
Packit 21b7a2
   number        ::= 1*( <digit> )
Packit 21b7a2
   digit         ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )
Packit 21b7a2
   exponential   ::= ( 'e' | 'E' )
Packit 21b7a2
   sign          ::= ( '-' | '+' )
Packit 21b7a2
   decimal_point ::= '.'
Packit 21b7a2
   @endverbatim
Packit 21b7a2
*/
Packit 21b7a2
/* FIXME: Add EBNF for hex-floats */
Packit 21b7a2
TRIO_STRING_PUBLIC trio_long_double_t
Packit 21b7a2
trio_to_long_double
Packit 21b7a2
TRIO_ARGS2((source, endp),
Packit 21b7a2
	   TRIO_CONST char *source,
Packit 21b7a2
	   char **endp)
Packit 21b7a2
{
Packit 21b7a2
#if defined(USE_STRTOLD)
Packit 21b7a2
  return strtold(source, endp);
Packit 21b7a2
#else
Packit 21b7a2
  int isNegative = FALSE;
Packit 21b7a2
  int isExponentNegative = FALSE;
Packit 21b7a2
  trio_long_double_t integer = 0.0;
Packit 21b7a2
  trio_long_double_t fraction = 0.0;
Packit 21b7a2
  unsigned long exponent = 0;
Packit 21b7a2
  trio_long_double_t base;
Packit 21b7a2
  trio_long_double_t fracdiv = 1.0;
Packit 21b7a2
  trio_long_double_t value = 0.0;
Packit 21b7a2
Packit 21b7a2
  /* First try hex-floats */
Packit 21b7a2
  if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X')))
Packit 21b7a2
    {
Packit 21b7a2
      base = 16.0;
Packit 21b7a2
      source += 2;
Packit 21b7a2
      while (isxdigit((int)*source))
Packit 21b7a2
	{
Packit 21b7a2
	  integer *= base;
Packit 21b7a2
	  integer += (isdigit((int)*source)
Packit 21b7a2
		      ? (*source - '0')
Packit 21b7a2
		      : 10 + (trio_to_upper((int)*source) - 'A'));
Packit 21b7a2
	  source++;
Packit 21b7a2
	}
Packit 21b7a2
      if (*source == '.')
Packit 21b7a2
	{
Packit 21b7a2
	  source++;
Packit 21b7a2
	  while (isxdigit((int)*source))
Packit 21b7a2
	    {
Packit 21b7a2
	      fracdiv /= base;
Packit 21b7a2
	      fraction += fracdiv * (isdigit((int)*source)
Packit 21b7a2
				     ? (*source - '0')
Packit 21b7a2
				     : 10 + (trio_to_upper((int)*source) - 'A'));
Packit 21b7a2
	      source++;
Packit 21b7a2
	    }
Packit 21b7a2
	  if ((*source == 'p') || (*source == 'P'))
Packit 21b7a2
	    {
Packit 21b7a2
	      source++;
Packit 21b7a2
	      if ((*source == '+') || (*source == '-'))
Packit 21b7a2
		{
Packit 21b7a2
		  isExponentNegative = (*source == '-');
Packit 21b7a2
		  source++;
Packit 21b7a2
		}
Packit 21b7a2
	      while (isdigit((int)*source))
Packit 21b7a2
		{
Packit 21b7a2
		  exponent *= 10;
Packit 21b7a2
		  exponent += (*source - '0');
Packit 21b7a2
		  source++;
Packit 21b7a2
		}
Packit 21b7a2
	    }
Packit 21b7a2
	}
Packit 21b7a2
      /* For later use with exponent */
Packit 21b7a2
      base = 2.0;
Packit 21b7a2
    }
Packit 21b7a2
  else /* Then try normal decimal floats */
Packit 21b7a2
    {
Packit 21b7a2
      base = 10.0;
Packit 21b7a2
      isNegative = (*source == '-');
Packit 21b7a2
      /* Skip sign */
Packit 21b7a2
      if ((*source == '+') || (*source == '-'))
Packit 21b7a2
	source++;
Packit 21b7a2
Packit 21b7a2
      /* Integer part */
Packit 21b7a2
      while (isdigit((int)*source))
Packit 21b7a2
	{
Packit 21b7a2
	  integer *= base;
Packit 21b7a2
	  integer += (*source - '0');
Packit 21b7a2
	  source++;
Packit 21b7a2
	}
Packit 21b7a2
Packit 21b7a2
      if (*source == '.')
Packit 21b7a2
	{
Packit 21b7a2
	  source++; /* skip decimal point */
Packit 21b7a2
	  while (isdigit((int)*source))
Packit 21b7a2
	    {
Packit 21b7a2
	      fracdiv /= base;
Packit 21b7a2
	      fraction += (*source - '0') * fracdiv;
Packit 21b7a2
	      source++;
Packit 21b7a2
	    }
Packit 21b7a2
	}
Packit 21b7a2
      if ((*source == 'e')
Packit 21b7a2
	  || (*source == 'E')
Packit 21b7a2
#if TRIO_MICROSOFT
Packit 21b7a2
	  || (*source == 'd')
Packit 21b7a2
	  || (*source == 'D')
Packit 21b7a2
#endif
Packit 21b7a2
	  )
Packit 21b7a2
	{
Packit 21b7a2
	  source++; /* Skip exponential indicator */
Packit 21b7a2
	  isExponentNegative = (*source == '-');
Packit 21b7a2
	  if ((*source == '+') || (*source == '-'))
Packit 21b7a2
	    source++;
Packit 21b7a2
	  while (isdigit((int)*source))
Packit 21b7a2
	    {
Packit 21b7a2
	      exponent *= (int)base;
Packit 21b7a2
	      exponent += (*source - '0');
Packit 21b7a2
	      source++;
Packit 21b7a2
	    }
Packit 21b7a2
	}
Packit 21b7a2
    }
Packit 21b7a2
Packit 21b7a2
  value = integer + fraction;
Packit 21b7a2
  if (exponent != 0)
Packit 21b7a2
    {
Packit 21b7a2
      if (isExponentNegative)
Packit 21b7a2
	value /= pow(base, (double)exponent);
Packit 21b7a2
      else
Packit 21b7a2
	value *= pow(base, (double)exponent);
Packit 21b7a2
    }
Packit 21b7a2
  if (isNegative)
Packit 21b7a2
    value = -value;
Packit 21b7a2
Packit 21b7a2
  if (endp)
Packit 21b7a2
    *endp = (char *)source;
Packit 21b7a2
  return value;
Packit 21b7a2
#endif
Packit 21b7a2
}
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
/**
Packit 21b7a2
   Convert string to floating-point number.
Packit 21b7a2
Packit 21b7a2
   @param source String to be converted.
Packit 21b7a2
   @param endp Pointer to end of the converted string.
Packit 21b7a2
   @return A floating-point number.
Packit 21b7a2
Packit 21b7a2
   See @ref trio_to_long_double.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC double
Packit 21b7a2
trio_to_double
Packit 21b7a2
TRIO_ARGS2((source, endp),
Packit 21b7a2
	   TRIO_CONST char *source,
Packit 21b7a2
	   char **endp)
Packit 21b7a2
{
Packit 21b7a2
#if defined(USE_STRTOD)
Packit 21b7a2
  return strtod(source, endp);
Packit 21b7a2
#else
Packit 21b7a2
  return (double)trio_to_long_double(source, endp);
Packit 21b7a2
#endif
Packit 21b7a2
}
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/**
Packit 21b7a2
   Convert string to floating-point number.
Packit 21b7a2
Packit 21b7a2
   @param source String to be converted.
Packit 21b7a2
   @param endp Pointer to end of the converted string.
Packit 21b7a2
   @return A floating-point number.
Packit 21b7a2
Packit 21b7a2
   See @ref trio_to_long_double.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC float
Packit 21b7a2
trio_to_float
Packit 21b7a2
TRIO_ARGS2((source, endp),
Packit 21b7a2
	   TRIO_CONST char *source,
Packit 21b7a2
	   char **endp)
Packit 21b7a2
{
Packit 21b7a2
#if defined(USE_STRTOF)
Packit 21b7a2
  return strtof(source, endp);
Packit 21b7a2
#else
Packit 21b7a2
  return (float)trio_to_long_double(source, endp);
Packit 21b7a2
#endif
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
/**
Packit 21b7a2
   Convert string to signed integer.
Packit 21b7a2
Packit 21b7a2
   @param string String to be converted.
Packit 21b7a2
   @param endp Pointer to end of converted string.
Packit 21b7a2
   @param base Radix number of number.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC long
Packit 21b7a2
trio_to_long
Packit 21b7a2
TRIO_ARGS3((string, endp, base),
Packit 21b7a2
	   TRIO_CONST char *string,
Packit 21b7a2
	   char **endp,
Packit 21b7a2
	   int base)
Packit 21b7a2
{
Packit 21b7a2
  assert(string);
Packit 21b7a2
  assert((base >= 2) && (base <= 36));
Packit 21b7a2
Packit 21b7a2
  return strtol(string, endp, base);
Packit 21b7a2
}
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/**
Packit 21b7a2
   Convert one alphabetic letter to lower-case.
Packit 21b7a2
Packit 21b7a2
   @param source The letter to be converted.
Packit 21b7a2
   @return The converted letter.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_to_lower
Packit 21b7a2
TRIO_ARGS1((source),
Packit 21b7a2
	   int source)
Packit 21b7a2
{
Packit 21b7a2
#if defined(USE_TOLOWER)
Packit 21b7a2
Packit 21b7a2
  return tolower(source);
Packit 21b7a2
Packit 21b7a2
#else
Packit 21b7a2
Packit 21b7a2
  /* Does not handle locales or non-contiguous alphabetic characters */
Packit 21b7a2
  return ((source >= (int)'A') && (source <= (int)'Z'))
Packit 21b7a2
    ? source - 'A' + 'a'
Packit 21b7a2
    : source;
Packit 21b7a2
Packit 21b7a2
#endif
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/**
Packit 21b7a2
   Convert string to unsigned integer.
Packit 21b7a2
Packit 21b7a2
   @param string String to be converted.
Packit 21b7a2
   @param endp Pointer to end of converted string.
Packit 21b7a2
   @param base Radix number of number.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC unsigned long
Packit 21b7a2
trio_to_unsigned_long
Packit 21b7a2
TRIO_ARGS3((string, endp, base),
Packit 21b7a2
	   TRIO_CONST char *string,
Packit 21b7a2
	   char **endp,
Packit 21b7a2
	   int base)
Packit 21b7a2
{
Packit 21b7a2
  assert(string);
Packit 21b7a2
  assert((base >= 2) && (base <= 36));
Packit 21b7a2
Packit 21b7a2
  return strtoul(string, endp, base);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
/**
Packit 21b7a2
   Convert one alphabetic letter to upper-case.
Packit 21b7a2
Packit 21b7a2
   @param source The letter to be converted.
Packit 21b7a2
   @return The converted letter.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_to_upper
Packit 21b7a2
TRIO_ARGS1((source),
Packit 21b7a2
	   int source)
Packit 21b7a2
{
Packit 21b7a2
#if defined(USE_TOUPPER)
Packit 21b7a2
Packit 21b7a2
  return toupper(source);
Packit 21b7a2
Packit 21b7a2
#else
Packit 21b7a2
Packit 21b7a2
  /* Does not handle locales or non-contiguous alphabetic characters */
Packit 21b7a2
  return ((source >= (int)'a') && (source <= (int)'z'))
Packit 21b7a2
    ? source - 'a' + 'A'
Packit 21b7a2
    : source;
Packit 21b7a2
Packit 21b7a2
#endif
Packit 21b7a2
}
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/**
Packit 21b7a2
   Convert the alphabetic letters in the string to upper-case.
Packit 21b7a2
Packit 21b7a2
   @param target The string to be converted.
Packit 21b7a2
   @return The number of processed characters (converted or not).
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_upper
Packit 21b7a2
TRIO_ARGS1((target),
Packit 21b7a2
	   char *target)
Packit 21b7a2
{
Packit 21b7a2
  assert(target);
Packit 21b7a2
Packit 21b7a2
  return trio_span_function(target, target, trio_to_upper);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
/** @} End of StaticStrings */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
/*************************************************************************
Packit 21b7a2
 * Dynamic String Functions
Packit 21b7a2
 */
Packit 21b7a2
Packit 21b7a2
#if defined(TRIO_DOCUMENTATION)
Packit 21b7a2
# include "doc/doc_dynamic.h"
Packit 21b7a2
#endif
Packit 21b7a2
/** @addtogroup DynamicStrings
Packit 21b7a2
    @{
Packit 21b7a2
*/
Packit 21b7a2
Packit 21b7a2
/*
Packit 21b7a2
 * TrioStringAlloc
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PRIVATE trio_string_t *
Packit 21b7a2
TrioStringAlloc(TRIO_NOARGS)
Packit 21b7a2
{
Packit 21b7a2
  trio_string_t *self;
Packit 21b7a2
Packit 21b7a2
  self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t));
Packit 21b7a2
  if (self)
Packit 21b7a2
    {
Packit 21b7a2
      self->content = NULL;
Packit 21b7a2
      self->length = 0;
Packit 21b7a2
      self->allocated = 0;
Packit 21b7a2
    }
Packit 21b7a2
  return self;
Packit 21b7a2
}
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
/*
Packit 21b7a2
 * TrioStringGrow
Packit 21b7a2
 *
Packit 21b7a2
 * The size of the string will be increased by 'delta' characters. If
Packit 21b7a2
 * 'delta' is zero, the size will be doubled.
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PRIVATE BOOLEAN_T
Packit 21b7a2
TrioStringGrow
Packit 21b7a2
TRIO_ARGS2((self, delta),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   size_t delta)
Packit 21b7a2
{
Packit 21b7a2
  BOOLEAN_T status = FALSE;
Packit 21b7a2
  char *new_content;
Packit 21b7a2
  size_t new_size;
Packit 21b7a2
Packit 21b7a2
  new_size = (delta == 0)
Packit 21b7a2
    ? ( (self->allocated == 0) ? 1 : self->allocated * 2 )
Packit 21b7a2
    : self->allocated + delta;
Packit 21b7a2
Packit 21b7a2
  new_content = (char *)TRIO_REALLOC(self->content, new_size);
Packit 21b7a2
  if (new_content)
Packit 21b7a2
    {
Packit 21b7a2
      self->content = new_content;
Packit 21b7a2
      self->allocated = new_size;
Packit 21b7a2
      status = TRUE;
Packit 21b7a2
    }
Packit 21b7a2
  return status;
Packit 21b7a2
}
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/*
Packit 21b7a2
 * TrioStringGrowTo
Packit 21b7a2
 *
Packit 21b7a2
 * The size of the string will be increased to 'length' plus one characters.
Packit 21b7a2
 * If 'length' is less than the original size, the original size will be
Packit 21b7a2
 * used (that is, the size of the string is never decreased).
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PRIVATE BOOLEAN_T
Packit 21b7a2
TrioStringGrowTo
Packit 21b7a2
TRIO_ARGS2((self, length),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   size_t length)
Packit 21b7a2
{
Packit 21b7a2
  length++; /* Room for terminating zero */
Packit 21b7a2
  return (self->allocated < length)
Packit 21b7a2
    ? TrioStringGrow(self, length - self->allocated)
Packit 21b7a2
    : TRUE;
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/**
Packit 21b7a2
   Create a new dynamic string.
Packit 21b7a2
Packit 21b7a2
   @param initial_size Initial size of the buffer.
Packit 21b7a2
   @return Newly allocated dynamic string, or NULL if memory allocation failed.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC trio_string_t *
Packit 21b7a2
trio_string_create
Packit 21b7a2
TRIO_ARGS1((initial_size),
Packit 21b7a2
	   int initial_size)
Packit 21b7a2
{
Packit 21b7a2
  trio_string_t *self;
Packit 21b7a2
Packit 21b7a2
  self = TrioStringAlloc();
Packit 21b7a2
  if (self)
Packit 21b7a2
    {
Packit 21b7a2
      if (TrioStringGrow(self,
Packit 21b7a2
			 (size_t)((initial_size > 0) ? initial_size : 1)))
Packit 21b7a2
	{
Packit 21b7a2
	  self->content[0] = (char)0;
Packit 21b7a2
	  self->allocated = initial_size;
Packit 21b7a2
	}
Packit 21b7a2
      else
Packit 21b7a2
	{
Packit 21b7a2
	  trio_string_destroy(self);
Packit 21b7a2
	  self = NULL;
Packit 21b7a2
	}
Packit 21b7a2
    }
Packit 21b7a2
  return self;
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
/**
Packit 21b7a2
   Deallocate the dynamic string and its contents.
Packit 21b7a2
Packit 21b7a2
   @param self Dynamic string
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC void
Packit 21b7a2
trio_string_destroy
Packit 21b7a2
TRIO_ARGS1((self),
Packit 21b7a2
	   trio_string_t *self)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
Packit 21b7a2
  if (self)
Packit 21b7a2
    {
Packit 21b7a2
      trio_destroy(self->content);
Packit 21b7a2
      TRIO_FREE(self);
Packit 21b7a2
    }
Packit 21b7a2
}
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/**
Packit 21b7a2
   Get a pointer to the content.
Packit 21b7a2
Packit 21b7a2
   @param self Dynamic string.
Packit 21b7a2
   @param offset Offset into content.
Packit 21b7a2
   @return Pointer to the content.
Packit 21b7a2
Packit 21b7a2
   @p Offset can be zero, positive, or negative. If @p offset is zero,
Packit 21b7a2
   then the start of the content will be returned. If @p offset is positive,
Packit 21b7a2
   then a pointer to @p offset number of characters from the beginning of the
Packit 21b7a2
   content is returned. If @p offset is negative, then a pointer to @p offset
Packit 21b7a2
   number of characters from the ending of the string, starting at the
Packit 21b7a2
   terminating zero, is returned.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC char *
Packit 21b7a2
trio_string_get
Packit 21b7a2
TRIO_ARGS2((self, offset),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   int offset)
Packit 21b7a2
{
Packit 21b7a2
  char *result = NULL;
Packit 21b7a2
Packit 21b7a2
  assert(self);
Packit 21b7a2
Packit 21b7a2
  if (self->content != NULL)
Packit 21b7a2
    {
Packit 21b7a2
      if (self->length == 0)
Packit 21b7a2
	{
Packit 21b7a2
	  (void)trio_string_length(self);
Packit 21b7a2
	}
Packit 21b7a2
      if (offset >= 0)
Packit 21b7a2
	{
Packit 21b7a2
	  if (offset > (int)self->length)
Packit 21b7a2
	    {
Packit 21b7a2
	      offset = self->length;
Packit 21b7a2
	    }
Packit 21b7a2
	}
Packit 21b7a2
      else
Packit 21b7a2
	{
Packit 21b7a2
	  offset += self->length + 1;
Packit 21b7a2
	  if (offset < 0)
Packit 21b7a2
	    {
Packit 21b7a2
	      offset = 0;
Packit 21b7a2
	    }
Packit 21b7a2
	}
Packit 21b7a2
      result = &(self->content[offset]);
Packit 21b7a2
    }
Packit 21b7a2
  return result;
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
/**
Packit 21b7a2
   Extract the content.
Packit 21b7a2
Packit 21b7a2
   @param self Dynamic String
Packit 21b7a2
   @return Content of dynamic string.
Packit 21b7a2
Packit 21b7a2
   The content is removed from the dynamic string. This enables destruction
Packit 21b7a2
   of the dynamic string without deallocation of the content.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC char *
Packit 21b7a2
trio_string_extract
Packit 21b7a2
TRIO_ARGS1((self),
Packit 21b7a2
	   trio_string_t *self)
Packit 21b7a2
{
Packit 21b7a2
  char *result;
Packit 21b7a2
Packit 21b7a2
  assert(self);
Packit 21b7a2
Packit 21b7a2
  result = self->content;
Packit 21b7a2
  /* FIXME: Allocate new empty buffer? */
Packit 21b7a2
  self->content = NULL;
Packit 21b7a2
  self->length = self->allocated = 0;
Packit 21b7a2
  return result;
Packit 21b7a2
}
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/**
Packit 21b7a2
   Set the content of the dynamic string.
Packit 21b7a2
Packit 21b7a2
   @param self Dynamic String
Packit 21b7a2
   @param buffer The new content.
Packit 21b7a2
Packit 21b7a2
   Sets the content of the dynamic string to a copy @p buffer.
Packit 21b7a2
   An existing content will be deallocated first, if necessary.
Packit 21b7a2
Packit 21b7a2
   @remark
Packit 21b7a2
   This function will make a copy of @p buffer.
Packit 21b7a2
   You are responsible for deallocating @p buffer yourself.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC void
Packit 21b7a2
trio_xstring_set
Packit 21b7a2
TRIO_ARGS2((self, buffer),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   char *buffer)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
Packit 21b7a2
  trio_destroy(self->content);
Packit 21b7a2
  self->content = trio_duplicate(buffer);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
/*
Packit 21b7a2
 * trio_string_size
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_string_size
Packit 21b7a2
TRIO_ARGS1((self),
Packit 21b7a2
	   trio_string_t *self)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
Packit 21b7a2
  return self->allocated;
Packit 21b7a2
}
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
/*
Packit 21b7a2
 * trio_string_terminate
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC void
Packit 21b7a2
trio_string_terminate
Packit 21b7a2
TRIO_ARGS1((self),
Packit 21b7a2
	   trio_string_t *self)
Packit 21b7a2
{
Packit 21b7a2
  trio_xstring_append_char(self, 0);
Packit 21b7a2
}
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/**
Packit 21b7a2
   Append the second string to the first.
Packit 21b7a2
Packit 21b7a2
   @param self Dynamic string to be modified.
Packit 21b7a2
   @param other Dynamic string to copy from.
Packit 21b7a2
   @return Boolean value indicating success or failure.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_string_append
Packit 21b7a2
TRIO_ARGS2((self, other),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   trio_string_t *other)
Packit 21b7a2
{
Packit 21b7a2
  size_t length;
Packit 21b7a2
Packit 21b7a2
  assert(self);
Packit 21b7a2
  assert(other);
Packit 21b7a2
Packit 21b7a2
  length = self->length + other->length;
Packit 21b7a2
  if (!TrioStringGrowTo(self, length))
Packit 21b7a2
    goto error;
Packit 21b7a2
  trio_copy(&self->content[self->length], other->content);
Packit 21b7a2
  self->length = length;
Packit 21b7a2
  return TRUE;
Packit 21b7a2
Packit 21b7a2
 error:
Packit 21b7a2
  return FALSE;
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/*
Packit 21b7a2
 * trio_xstring_append
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_xstring_append
Packit 21b7a2
TRIO_ARGS2((self, other),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   TRIO_CONST char *other)
Packit 21b7a2
{
Packit 21b7a2
  size_t length;
Packit 21b7a2
Packit 21b7a2
  assert(self);
Packit 21b7a2
  assert(other);
Packit 21b7a2
Packit 21b7a2
  length = self->length + trio_length(other);
Packit 21b7a2
  if (!TrioStringGrowTo(self, length))
Packit 21b7a2
    goto error;
Packit 21b7a2
  trio_copy(&self->content[self->length], other);
Packit 21b7a2
  self->length = length;
Packit 21b7a2
  return TRUE;
Packit 21b7a2
Packit 21b7a2
 error:
Packit 21b7a2
  return FALSE;
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
/*
Packit 21b7a2
 * trio_xstring_append_char
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_xstring_append_char
Packit 21b7a2
TRIO_ARGS2((self, character),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   char character)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
Packit 21b7a2
  if ((int)self->length >= trio_string_size(self))
Packit 21b7a2
    {
Packit 21b7a2
      if (!TrioStringGrow(self, 0))
Packit 21b7a2
	goto error;
Packit 21b7a2
    }
Packit 21b7a2
  self->content[self->length] = character;
Packit 21b7a2
  self->length++;
Packit 21b7a2
  return TRUE;
Packit 21b7a2
Packit 21b7a2
 error:
Packit 21b7a2
  return FALSE;
Packit 21b7a2
}
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/**
Packit 21b7a2
   Search for the first occurrence of second parameter in the first.
Packit 21b7a2
Packit 21b7a2
   @param self Dynamic string to be modified.
Packit 21b7a2
   @param other Dynamic string to copy from.
Packit 21b7a2
   @return Boolean value indicating success or failure.
Packit 21b7a2
*/
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_string_contains
Packit 21b7a2
TRIO_ARGS2((self, other),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   trio_string_t *other)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
  assert(other);
Packit 21b7a2
Packit 21b7a2
  return trio_contains(self->content, other->content);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/*
Packit 21b7a2
 * trio_xstring_contains
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_xstring_contains
Packit 21b7a2
TRIO_ARGS2((self, other),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   TRIO_CONST char *other)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
  assert(other);
Packit 21b7a2
Packit 21b7a2
  return trio_contains(self->content, other);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/*
Packit 21b7a2
 * trio_string_copy
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_string_copy
Packit 21b7a2
TRIO_ARGS2((self, other),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   trio_string_t *other)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
  assert(other);
Packit 21b7a2
Packit 21b7a2
  self->length = 0;
Packit 21b7a2
  return trio_string_append(self, other);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/*
Packit 21b7a2
 * trio_xstring_copy
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_xstring_copy
Packit 21b7a2
TRIO_ARGS2((self, other),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   TRIO_CONST char *other)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
  assert(other);
Packit 21b7a2
Packit 21b7a2
  self->length = 0;
Packit 21b7a2
  return trio_xstring_append(self, other);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/*
Packit 21b7a2
 * trio_string_duplicate
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC trio_string_t *
Packit 21b7a2
trio_string_duplicate
Packit 21b7a2
TRIO_ARGS1((other),
Packit 21b7a2
	   trio_string_t *other)
Packit 21b7a2
{
Packit 21b7a2
  trio_string_t *self;
Packit 21b7a2
Packit 21b7a2
  assert(other);
Packit 21b7a2
Packit 21b7a2
  self = TrioStringAlloc();
Packit 21b7a2
  if (self)
Packit 21b7a2
    {
Packit 21b7a2
      self->content = TrioDuplicateMax(other->content, other->length);
Packit 21b7a2
      if (self->content)
Packit 21b7a2
	{
Packit 21b7a2
	  self->length = other->length;
Packit 21b7a2
	  self->allocated = self->length + 1;
Packit 21b7a2
	}
Packit 21b7a2
      else
Packit 21b7a2
	{
Packit 21b7a2
	  self->length = self->allocated = 0;
Packit 21b7a2
	}
Packit 21b7a2
    }
Packit 21b7a2
  return self;
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
/*
Packit 21b7a2
 * trio_xstring_duplicate
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC trio_string_t *
Packit 21b7a2
trio_xstring_duplicate
Packit 21b7a2
TRIO_ARGS1((other),
Packit 21b7a2
	   TRIO_CONST char *other)
Packit 21b7a2
{
Packit 21b7a2
  trio_string_t *self;
Packit 21b7a2
Packit 21b7a2
  assert(other);
Packit 21b7a2
Packit 21b7a2
  self = TrioStringAlloc();
Packit 21b7a2
  if (self)
Packit 21b7a2
    {
Packit 21b7a2
      self->content = TrioDuplicateMax(other, trio_length(other));
Packit 21b7a2
      if (self->content)
Packit 21b7a2
	{
Packit 21b7a2
	  self->length = trio_length(self->content);
Packit 21b7a2
	  self->allocated = self->length + 1;
Packit 21b7a2
	}
Packit 21b7a2
      else
Packit 21b7a2
	{
Packit 21b7a2
	  self->length = self->allocated = 0;
Packit 21b7a2
	}
Packit 21b7a2
    }
Packit 21b7a2
  return self;
Packit 21b7a2
}
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/*
Packit 21b7a2
 * trio_string_equal
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_string_equal
Packit 21b7a2
TRIO_ARGS2((self, other),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   trio_string_t *other)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
  assert(other);
Packit 21b7a2
Packit 21b7a2
  return trio_equal(self->content, other->content);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/*
Packit 21b7a2
 * trio_xstring_equal
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_xstring_equal
Packit 21b7a2
TRIO_ARGS2((self, other),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   TRIO_CONST char *other)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
  assert(other);
Packit 21b7a2
Packit 21b7a2
  return trio_equal(self->content, other);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/*
Packit 21b7a2
 * trio_string_equal_max
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_string_equal_max
Packit 21b7a2
TRIO_ARGS3((self, max, other),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   size_t max,
Packit 21b7a2
	   trio_string_t *other)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
  assert(other);
Packit 21b7a2
Packit 21b7a2
  return trio_equal_max(self->content, max, other->content);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/*
Packit 21b7a2
 * trio_xstring_equal_max
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_xstring_equal_max
Packit 21b7a2
TRIO_ARGS3((self, max, other),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   size_t max,
Packit 21b7a2
	   TRIO_CONST char *other)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
  assert(other);
Packit 21b7a2
Packit 21b7a2
  return trio_equal_max(self->content, max, other);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/*
Packit 21b7a2
 * trio_string_equal_case
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_string_equal_case
Packit 21b7a2
TRIO_ARGS2((self, other),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   trio_string_t *other)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
  assert(other);
Packit 21b7a2
Packit 21b7a2
  return trio_equal_case(self->content, other->content);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/*
Packit 21b7a2
 * trio_xstring_equal_case
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_xstring_equal_case
Packit 21b7a2
TRIO_ARGS2((self, other),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   TRIO_CONST char *other)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
  assert(other);
Packit 21b7a2
Packit 21b7a2
  return trio_equal_case(self->content, other);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/*
Packit 21b7a2
 * trio_string_equal_case_max
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_string_equal_case_max
Packit 21b7a2
TRIO_ARGS3((self, max, other),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   size_t max,
Packit 21b7a2
	   trio_string_t *other)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
  assert(other);
Packit 21b7a2
Packit 21b7a2
  return trio_equal_case_max(self->content, max, other->content);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/*
Packit 21b7a2
 * trio_xstring_equal_case_max
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_xstring_equal_case_max
Packit 21b7a2
TRIO_ARGS3((self, max, other),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   size_t max,
Packit 21b7a2
	   TRIO_CONST char *other)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
  assert(other);
Packit 21b7a2
Packit 21b7a2
  return trio_equal_case_max(self->content, max, other);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL) && !defined(_WIN32_WCE)
Packit 21b7a2
/*
Packit 21b7a2
 * trio_string_format_data_max
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC size_t
Packit 21b7a2
trio_string_format_date_max
Packit 21b7a2
TRIO_ARGS4((self, max, format, datetime),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   size_t max,
Packit 21b7a2
	   TRIO_CONST char *format,
Packit 21b7a2
	   TRIO_CONST struct tm *datetime)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
Packit 21b7a2
  return trio_format_date_max(self->content, max, format, datetime);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/*
Packit 21b7a2
 * trio_string_index
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC char *
Packit 21b7a2
trio_string_index
Packit 21b7a2
TRIO_ARGS2((self, character),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   int character)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
Packit 21b7a2
  return trio_index(self->content, character);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/*
Packit 21b7a2
 * trio_string_index_last
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC char *
Packit 21b7a2
trio_string_index_last
Packit 21b7a2
TRIO_ARGS2((self, character),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   int character)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
Packit 21b7a2
  return trio_index_last(self->content, character);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/*
Packit 21b7a2
 * trio_string_length
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_string_length
Packit 21b7a2
TRIO_ARGS1((self),
Packit 21b7a2
	   trio_string_t *self)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
Packit 21b7a2
  if (self->length == 0)
Packit 21b7a2
    {
Packit 21b7a2
      self->length = trio_length(self->content);
Packit 21b7a2
    }
Packit 21b7a2
  return self->length;
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/*
Packit 21b7a2
 * trio_string_lower
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_string_lower
Packit 21b7a2
TRIO_ARGS1((self),
Packit 21b7a2
	   trio_string_t *self)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
Packit 21b7a2
  return trio_lower(self->content);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/*
Packit 21b7a2
 * trio_string_match
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_string_match
Packit 21b7a2
TRIO_ARGS2((self, other),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   trio_string_t *other)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
  assert(other);
Packit 21b7a2
Packit 21b7a2
  return trio_match(self->content, other->content);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/*
Packit 21b7a2
 * trio_xstring_match
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_xstring_match
Packit 21b7a2
TRIO_ARGS2((self, other),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   TRIO_CONST char *other)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
  assert(other);
Packit 21b7a2
Packit 21b7a2
  return trio_match(self->content, other);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/*
Packit 21b7a2
 * trio_string_match_case
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_string_match_case
Packit 21b7a2
TRIO_ARGS2((self, other),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   trio_string_t *other)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
  assert(other);
Packit 21b7a2
Packit 21b7a2
  return trio_match_case(self->content, other->content);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/*
Packit 21b7a2
 * trio_xstring_match_case
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_xstring_match_case
Packit 21b7a2
TRIO_ARGS2((self, other),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   TRIO_CONST char *other)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
  assert(other);
Packit 21b7a2
Packit 21b7a2
  return trio_match_case(self->content, other);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/*
Packit 21b7a2
 * trio_string_substring
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC char *
Packit 21b7a2
trio_string_substring
Packit 21b7a2
TRIO_ARGS2((self, other),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   trio_string_t *other)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
  assert(other);
Packit 21b7a2
Packit 21b7a2
  return trio_substring(self->content, other->content);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/*
Packit 21b7a2
 * trio_xstring_substring
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC char *
Packit 21b7a2
trio_xstring_substring
Packit 21b7a2
TRIO_ARGS2((self, other),
Packit 21b7a2
	   trio_string_t *self,
Packit 21b7a2
	   TRIO_CONST char *other)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
  assert(other);
Packit 21b7a2
Packit 21b7a2
  return trio_substring(self->content, other);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
Packit 21b7a2
#if !defined(TRIO_MINIMAL)
Packit 21b7a2
/*
Packit 21b7a2
 * trio_string_upper
Packit 21b7a2
 */
Packit 21b7a2
TRIO_STRING_PUBLIC int
Packit 21b7a2
trio_string_upper
Packit 21b7a2
TRIO_ARGS1((self),
Packit 21b7a2
	   trio_string_t *self)
Packit 21b7a2
{
Packit 21b7a2
  assert(self);
Packit 21b7a2
Packit 21b7a2
  return trio_upper(self->content);
Packit 21b7a2
}
Packit 21b7a2
#endif /* !defined(TRIO_MINIMAL) */
Packit 21b7a2
Packit 21b7a2
/** @} End of DynamicStrings */