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 Service 5a9772
#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 Service 5a9772
#define USE_MATH
Packit 1fb8d4
#endif
Packit 1fb8d4
#if defined(USE_MATH)
Packit Service 5a9772
#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 Service 5a9772
#define TRIO_PUBLIC_STRING TRIO_PUBLIC
Packit 1fb8d4
#endif
Packit 1fb8d4
#if !defined(TRIO_PRIVATE_STRING)
Packit Service 5a9772
#define TRIO_PRIVATE_STRING TRIO_PRIVATE
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if !defined(NULL)
Packit Service 5a9772
#define NULL 0
Packit 1fb8d4
#endif
Packit 1fb8d4
#if !defined(NIL)
Packit Service 5a9772
#define NIL ((char)0)
Packit 1fb8d4
#endif
Packit 1fb8d4
#if !defined(FALSE)
Packit Service 5a9772
#define FALSE (1 == 0)
Packit Service 5a9772
#define TRUE (!FALSE)
Packit 1fb8d4
#endif
Packit 1fb8d4
#if !defined(BOOLEAN_T)
Packit Service 5a9772
#define BOOLEAN_T int
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if defined(USE_MATH)
Packit Service 5a9772
#if defined(PREDEF_STANDARD_C99)
Packit Service 5a9772
#if defined(TRIO_COMPILER_DECC)
Packit Service 5a9772
#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 Service 5a9772
#define USE_STRTOD
Packit Service 5a9772
#define USE_STRTOF
Packit Service 5a9772
#endif
Packit Service 5a9772
#else
Packit Service 5a9772
#define USE_STRTOD
Packit Service 5a9772
#define USE_STRTOF
Packit Service 5a9772
#endif
Packit Service 5a9772
#else
Packit Service 5a9772
#if defined(TRIO_COMPILER_VISUALC)
Packit Service 5a9772
#define USE_STRTOD
Packit Service 5a9772
#endif
Packit 1fb8d4
#endif
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if defined(TRIO_PLATFORM_UNIX)
Packit Service 5a9772
#if defined(PREDEF_STANDARD_UNIX95)
Packit Service 5a9772
#define USE_STRCASECMP
Packit Service 5a9772
#define USE_STRNCASECMP
Packit Service 5a9772
#endif
Packit Service 5a9772
#if defined(TRIO_PLATFORM_SUNOS)
Packit Service 5a9772
#define USE_SYS_ERRLIST
Packit Service 5a9772
#else
Packit Service 5a9772
#define USE_STRERROR
Packit Service 5a9772
#endif
Packit Service 5a9772
#if defined(TRIO_PLATFORM_QNX)
Packit Service 5a9772
#define strcasecmp(x, y) stricmp(x, y)
Packit Service 5a9772
#define strncasecmp(x, y, n) strnicmp(x, y, n)
Packit Service 5a9772
#endif
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if defined(TRIO_PLATFORM_WIN32)
Packit Service 5a9772
#define USE_STRCASECMP
Packit Service 5a9772
#if defined(TRIO_PLATFORM_WINCE)
Packit Service 5a9772
#define strcasecmp(x, y) _stricmp(x, y)
Packit Service 5a9772
#else
Packit Service 5a9772
#define strcasecmp(x, y) _stricmp(x, y)
Packit Service 5a9772
#endif
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if !defined(HAVE_CONFIG_H)
Packit Service 5a9772
#if !(defined(TRIO_PLATFORM_SUNOS))
Packit Service 5a9772
#define HAVE_TOLOWER
Packit Service 5a9772
#define HAVE_TOUPPER
Packit Service 5a9772
#endif
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if defined(USE_MATH) && !defined(TRIO_NO_POWL)
Packit Service 5a9772
#if !defined(HAVE_POWL)
Packit Service 5a9772
#if defined(PREDEF_STANDARD_C99) || defined(PREDEF_STANDARD_UNIX03)
Packit Service 5a9772
#define HAVE_POWL
Packit Service 5a9772
#else
Packit Service 5a9772
#if defined(TRIO_COMPILER_VISUALC)
Packit Service 5a9772
#if defined(powl)
Packit Service 5a9772
#define HAVE_POWL
Packit Service 5a9772
#endif
Packit Service 5a9772
#endif
Packit Service 5a9772
#endif
Packit Service 5a9772
#endif
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if defined(HAVE_POWL)
Packit Service 5a9772
#define trio_powl(x, y) powl((x), (y))
Packit 1fb8d4
#else
Packit Service 5a9772
#define trio_powl(x, y) pow((double)(x), (double)(y))
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit Service 5a9772
#if defined(TRIO_FUNC_TO_UPPER) || (defined(TRIO_FUNC_EQUAL) && !defined(USE_STRCASECMP)) ||   \
Packit Service 5a9772
    (defined(TRIO_FUNC_EQUAL_MAX) && !defined(USE_STRNCASECMP)) || defined(TRIO_FUNC_MATCH) || \
Packit Service 5a9772
    defined(TRIO_FUNC_TO_LONG_DOUBLE) || defined(TRIO_FUNC_UPPER)
Packit Service 5a9772
#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 Service 5a9772
	char* content;
Packit Service 5a9772
	size_t length;
Packit Service 5a9772
	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 Service 5a9772
#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 Service 5a9772
#if defined(TRIO_FUNC_DUPLICATE) || defined(TRIO_FUNC_DUPLICATE_MAX) || \
Packit Service 5a9772
    defined(TRIO_FUNC_STRING_DUPLICATE) || defined(TRIO_FUNC_XSTRING_DUPLICATE)
Packit 1fb8d4
Packit Service 5a9772
TRIO_PRIVATE_STRING char* internal_duplicate_max TRIO_ARGS2((source, size), TRIO_CONST char* source,
Packit Service 5a9772
                                                            size_t size)
Packit 1fb8d4
{
Packit Service 5a9772
	char* target;
Packit 1fb8d4
Packit Service 5a9772
	assert(source);
Packit 1fb8d4
Packit Service 5a9772
	/* Make room for string plus a terminating zero */
Packit Service 5a9772
	size++;
Packit Service 5a9772
	target = trio_create(size);
Packit Service 5a9772
	if (target)
Packit Service 5a9772
	{
Packit Service 5a9772
		trio_copy_max(target, size, source);
Packit Service 5a9772
	}
Packit Service 5a9772
	return target;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * internal_string_alloc
Packit 1fb8d4
 */
Packit Service 5a9772
#if defined(TRIO_FUNC_STRING_CREATE) || defined(TRIO_FUNC_STRING_DUPLICATE) || \
Packit Service 5a9772
    defined(TRIO_FUNC_XSTRING_DUPLICATE)
Packit 1fb8d4
Packit Service 5a9772
TRIO_PRIVATE_STRING trio_string_t* internal_string_alloc(TRIO_NOARGS)
Packit 1fb8d4
{
Packit Service 5a9772
	trio_string_t* self;
Packit Service 5a9772
Packit Service 5a9772
	self = (trio_string_t*)TRIO_MALLOC(sizeof(trio_string_t));
Packit Service 5a9772
	if (self)
Packit Service 5a9772
	{
Packit Service 5a9772
		self->content = NULL;
Packit Service 5a9772
		self->length = 0;
Packit Service 5a9772
		self->allocated = 0;
Packit Service 5a9772
	}
Packit Service 5a9772
	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 Service 5a9772
#if defined(TRIO_FUNC_STRING_CREATE) || defined(TRIO_FUNC_STRING_APPEND) || \
Packit Service 5a9772
    defined(TRIO_FUNC_XSTRING_APPEND) || defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
Packit 1fb8d4
Packit Service 5a9772
TRIO_PRIVATE_STRING BOOLEAN_T internal_string_grow TRIO_ARGS2((self, delta), trio_string_t* self,
Packit Service 5a9772
                                                              size_t delta)
Packit 1fb8d4
{
Packit Service 5a9772
	BOOLEAN_T status = FALSE;
Packit Service 5a9772
	char* new_content;
Packit Service 5a9772
	size_t new_size;
Packit Service 5a9772
Packit Service 5a9772
	new_size =
Packit Service 5a9772
	    (delta == 0) ? ((self->allocated == 0) ? 1 : self->allocated * 2) : self->allocated + delta;
Packit 1fb8d4
Packit Service 5a9772
	new_content = (char*)TRIO_REALLOC(self->content, new_size);
Packit Service 5a9772
	if (new_content)
Packit Service 5a9772
	{
Packit Service 5a9772
		self->content = new_content;
Packit Service 5a9772
		self->allocated = new_size;
Packit Service 5a9772
		status = TRUE;
Packit Service 5a9772
	}
Packit Service 5a9772
	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 Service 5a9772
#if defined(TRIO_FUNC_STRING_APPEND) || defined(TRIO_FUNC_XSTRING_APPEND) || \
Packit Service 5a9772
    defined(TRIO_FUNC_XSTRING_APPEND_MAX)
Packit 1fb8d4
Packit Service 5a9772
TRIO_PRIVATE_STRING BOOLEAN_T internal_string_grow_to TRIO_ARGS2((self, length),
Packit Service 5a9772
                                                                 trio_string_t* self, size_t length)
Packit 1fb8d4
{
Packit Service 5a9772
	length++; /* Room for terminating zero */
Packit Service 5a9772
	return (self->allocated < length) ? internal_string_grow(self, length - self->allocated) : TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#if defined(TRIO_FUNC_INTERNAL_TO_UPPER)
Packit 1fb8d4
Packit Service 5a9772
TRIO_PRIVATE_STRING TRIO_INLINE int internal_to_upper TRIO_ARGS1((source), int source)
Packit 1fb8d4
{
Packit Service 5a9772
#if defined(HAVE_TOUPPER)
Packit 1fb8d4
Packit Service 5a9772
	return toupper(source);
Packit Service 5a9772
Packit Service 5a9772
#else
Packit Service 5a9772
Packit Service 5a9772
	/* Does not handle locales or non-contiguous alphabetic characters */
Packit Service 5a9772
	return ((source >= (int)'a') && (source <= (int)'z')) ? source - 'a' + 'A' : source;
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit Service 5a9772
}
Packit 1fb8d4
Packit Service 5a9772
#endif
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 Service 5a9772
TRIO_PUBLIC_STRING char* trio_create TRIO_ARGS1((size), size_t size)
Packit 1fb8d4
{
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING void trio_destroy TRIO_ARGS1((string), char* string)
Packit 1fb8d4
{
Packit Service 5a9772
	if (string)
Packit Service 5a9772
	{
Packit Service 5a9772
		TRIO_FREE(string);
Packit Service 5a9772
	}
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 Service 5a9772
TRIO_PUBLIC_STRING size_t trio_length TRIO_ARGS1((string), TRIO_CONST char* string)
Packit 1fb8d4
{
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING size_t trio_length_max TRIO_ARGS2((string, max), TRIO_CONST char* string,
Packit Service 5a9772
                                                     size_t max)
Packit 1fb8d4
{
Packit Service 5a9772
	size_t i;
Packit 1fb8d4
Packit Service 5a9772
	for (i = 0; i < max; ++i)
Packit Service 5a9772
	{
Packit Service 5a9772
		if (string[i] == 0)
Packit Service 5a9772
			break;
Packit Service 5a9772
	}
Packit Service 5a9772
	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 Service 5a9772
Packit 1fb8d4
   @param target Target string.
Packit 1fb8d4
   @param source Source string.
Packit 1fb8d4
   @return Boolean value indicating success or failure.
Packit Service 5a9772
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 Service 5a9772
TRIO_PUBLIC_STRING int trio_append TRIO_ARGS2((target, source), char* target,
Packit Service 5a9772
                                              TRIO_CONST char* source)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(target);
Packit Service 5a9772
	assert(source);
Packit Service 5a9772
Packit Service 5a9772
	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 Service 5a9772
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 Service 5a9772
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 Service 5a9772
TRIO_PUBLIC_STRING int trio_append_max TRIO_ARGS3((target, max, source), char* target, size_t max,
Packit Service 5a9772
                                                  TRIO_CONST char* source)
Packit 1fb8d4
{
Packit Service 5a9772
	size_t length;
Packit Service 5a9772
Packit Service 5a9772
	assert(target);
Packit Service 5a9772
	assert(source);
Packit 1fb8d4
Packit Service 5a9772
	length = trio_length(target);
Packit Service 5a9772
Packit Service 5a9772
	if (max > length)
Packit Service 5a9772
	{
Packit Service 5a9772
		strncat(target, source, max - length - 1);
Packit Service 5a9772
	}
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING int trio_contains TRIO_ARGS2((string, substring), TRIO_CONST char* string,
Packit Service 5a9772
                                                TRIO_CONST char* substring)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(string);
Packit Service 5a9772
	assert(substring);
Packit Service 5a9772
Packit Service 5a9772
	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 Service 5a9772
Packit 1fb8d4
   @param target Target string.
Packit 1fb8d4
   @param source Source string.
Packit 1fb8d4
   @return Boolean value indicating success or failure.
Packit Service 5a9772
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 Service 5a9772
TRIO_PUBLIC_STRING int trio_copy TRIO_ARGS2((target, source), char* target, TRIO_CONST char* source)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(target);
Packit Service 5a9772
	assert(source);
Packit Service 5a9772
Packit Service 5a9772
	(void)strcpy(target, source);
Packit Service 5a9772
	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 Service 5a9772
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 Service 5a9772
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 Service 5a9772
TRIO_PUBLIC_STRING int trio_copy_max TRIO_ARGS3((target, max, source), char* target, size_t max,
Packit Service 5a9772
                                                TRIO_CONST char* source)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(target);
Packit Service 5a9772
	assert(source);
Packit Service 5a9772
	assert(max > 0); /* Includes != 0 */
Packit 1fb8d4
Packit Service 5a9772
	(void)strncpy(target, source, max - 1);
Packit Service 5a9772
	target[max - 1] = (char)0;
Packit Service 5a9772
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Duplicate @p source.
Packit Service 5a9772
Packit 1fb8d4
   @param source Source string.
Packit 1fb8d4
   @return A copy of the @p source string.
Packit Service 5a9772
Packit 1fb8d4
   @post @p target will be zero terminated.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_DUPLICATE)
Packit 1fb8d4
Packit Service 5a9772
TRIO_PUBLIC_STRING char* trio_duplicate TRIO_ARGS1((source), TRIO_CONST char* source)
Packit 1fb8d4
{
Packit Service 5a9772
	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 Service 5a9772
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 Service 5a9772
Packit 1fb8d4
   @post @p target will be zero terminated.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_DUPLICATE_MAX)
Packit 1fb8d4
Packit Service 5a9772
TRIO_PUBLIC_STRING char* trio_duplicate_max TRIO_ARGS2((source, max), TRIO_CONST char* source,
Packit Service 5a9772
                                                       size_t max)
Packit 1fb8d4
{
Packit Service 5a9772
	size_t length;
Packit 1fb8d4
Packit Service 5a9772
	assert(source);
Packit Service 5a9772
	assert(max > 0);
Packit 1fb8d4
Packit Service 5a9772
	length = trio_length(source);
Packit Service 5a9772
	if (length > max)
Packit Service 5a9772
	{
Packit Service 5a9772
		length = max;
Packit Service 5a9772
	}
Packit Service 5a9772
	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 Service 5a9772
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 Service 5a9772
Packit 1fb8d4
   Case-insensitive comparison.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_EQUAL)
Packit 1fb8d4
Packit Service 5a9772
TRIO_PUBLIC_STRING int trio_equal TRIO_ARGS2((first, second), TRIO_CONST char* first,
Packit Service 5a9772
                                             TRIO_CONST char* second)
Packit Service 5a9772
{
Packit Service 5a9772
	assert(first);
Packit Service 5a9772
	assert(second);
Packit Service 5a9772
Packit Service 5a9772
	if ((first != NULL) && (second != NULL))
Packit 1fb8d4
	{
Packit Service 5a9772
#if defined(USE_STRCASECMP)
Packit Service 5a9772
		return (0 == strcasecmp(first, second));
Packit Service 5a9772
#else
Packit Service 5a9772
		while ((*first != NIL) && (*second != NIL))
Packit Service 5a9772
		{
Packit Service 5a9772
			if (internal_to_upper(*first) != internal_to_upper(*second))
Packit Service 5a9772
			{
Packit Service 5a9772
				break;
Packit Service 5a9772
			}
Packit Service 5a9772
			first++;
Packit Service 5a9772
			second++;
Packit Service 5a9772
		}
Packit Service 5a9772
		return ((*first == NIL) && (*second == NIL));
Packit Service 5a9772
#endif
Packit 1fb8d4
	}
Packit Service 5a9772
	return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Compare if two strings are equal.
Packit Service 5a9772
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 Service 5a9772
Packit 1fb8d4
   Case-sensitive comparison.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_EQUAL_CASE)
Packit 1fb8d4
Packit Service 5a9772
TRIO_PUBLIC_STRING int trio_equal_case TRIO_ARGS2((first, second), TRIO_CONST char* first,
Packit Service 5a9772
                                                  TRIO_CONST char* second)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(first);
Packit Service 5a9772
	assert(second);
Packit 1fb8d4
Packit Service 5a9772
	if ((first != NULL) && (second != NULL))
Packit Service 5a9772
	{
Packit Service 5a9772
		return (0 == strcmp(first, second));
Packit Service 5a9772
	}
Packit Service 5a9772
	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 Service 5a9772
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 Service 5a9772
Packit 1fb8d4
   Case-sensitive comparison.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_EQUAL_CASE_MAX)
Packit 1fb8d4
Packit Service 5a9772
TRIO_PUBLIC_STRING int trio_equal_case_max TRIO_ARGS3((first, max, second), TRIO_CONST char* first,
Packit Service 5a9772
                                                      size_t max, TRIO_CONST char* second)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(first);
Packit Service 5a9772
	assert(second);
Packit 1fb8d4
Packit Service 5a9772
	if ((first != NULL) && (second != NULL))
Packit Service 5a9772
	{
Packit Service 5a9772
		return (0 == strncmp(first, second, max));
Packit Service 5a9772
	}
Packit Service 5a9772
	return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Compare if two strings are equal.
Packit Service 5a9772
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 Service 5a9772
TRIO_PUBLIC_STRING int trio_equal_locale TRIO_ARGS2((first, second), TRIO_CONST char* first,
Packit Service 5a9772
                                                    TRIO_CONST char* second)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(first);
Packit Service 5a9772
	assert(second);
Packit 1fb8d4
Packit Service 5a9772
#if defined(LC_COLLATE)
Packit Service 5a9772
	return (strcoll(first, second) == 0);
Packit Service 5a9772
#else
Packit Service 5a9772
	return trio_equal(first, second);
Packit Service 5a9772
#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 Service 5a9772
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 Service 5a9772
Packit 1fb8d4
   Case-insensitive comparison.
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_EQUAL_MAX)
Packit 1fb8d4
Packit Service 5a9772
TRIO_PUBLIC_STRING int trio_equal_max TRIO_ARGS3((first, max, second), TRIO_CONST char* first,
Packit Service 5a9772
                                                 size_t max, TRIO_CONST char* second)
Packit Service 5a9772
{
Packit Service 5a9772
	assert(first);
Packit Service 5a9772
	assert(second);
Packit Service 5a9772
Packit Service 5a9772
	if ((first != NULL) && (second != NULL))
Packit 1fb8d4
	{
Packit Service 5a9772
#if defined(USE_STRNCASECMP)
Packit Service 5a9772
		return (0 == strncasecmp(first, second, max));
Packit Service 5a9772
#else
Packit Service 5a9772
		/* Not adequately tested yet */
Packit Service 5a9772
		size_t cnt = 0;
Packit Service 5a9772
		while ((*first != NIL) && (*second != NIL) && (cnt <= max))
Packit Service 5a9772
		{
Packit Service 5a9772
			if (internal_to_upper(*first) != internal_to_upper(*second))
Packit Service 5a9772
			{
Packit Service 5a9772
				break;
Packit Service 5a9772
			}
Packit Service 5a9772
			first++;
Packit Service 5a9772
			second++;
Packit Service 5a9772
			cnt++;
Packit Service 5a9772
		}
Packit Service 5a9772
		return ((cnt == max) || ((*first == NIL) && (*second == NIL)));
Packit Service 5a9772
#endif
Packit 1fb8d4
	}
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING TRIO_CONST char* trio_error TRIO_ARGS1((error_number), int error_number)
Packit 1fb8d4
{
Packit Service 5a9772
#if defined(USE_STRERROR)
Packit 1fb8d4
Packit Service 5a9772
	return strerror(error_number);
Packit Service 5a9772
Packit Service 5a9772
#else
Packit Service 5a9772
#if defined(USE_SYS_ERRLIST)
Packit 1fb8d4
Packit Service 5a9772
	extern char* sys_errlist[];
Packit Service 5a9772
	extern int sys_nerr;
Packit Service 5a9772
Packit Service 5a9772
	return ((error_number < 0) || (error_number >= sys_nerr)) ? "unknown"
Packit Service 5a9772
	                                                          : sys_errlist[error_number];
Packit Service 5a9772
Packit Service 5a9772
#else
Packit 1fb8d4
Packit Service 5a9772
	return "unknown";
Packit 1fb8d4
Packit Service 5a9772
#endif
Packit Service 5a9772
#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 Service 5a9772
TRIO_PUBLIC_STRING size_t trio_format_date_max TRIO_ARGS4((target, max, format, datetime),
Packit Service 5a9772
                                                          char* target, size_t max,
Packit Service 5a9772
                                                          TRIO_CONST char* format,
Packit Service 5a9772
                                                          TRIO_CONST struct tm* datetime)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(target);
Packit Service 5a9772
	assert(format);
Packit Service 5a9772
	assert(datetime);
Packit Service 5a9772
	assert(max > 0);
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING unsigned long trio_hash TRIO_ARGS2((string, type), TRIO_CONST char* string,
Packit Service 5a9772
                                                      int type)
Packit Service 5a9772
{
Packit Service 5a9772
	unsigned long value = 0L;
Packit Service 5a9772
	char ch;
Packit Service 5a9772
Packit Service 5a9772
	assert(string);
Packit Service 5a9772
Packit Service 5a9772
	switch (type)
Packit 1fb8d4
	{
Packit Service 5a9772
		case TRIO_HASH_PLAIN:
Packit Service 5a9772
			while ((ch = *string++) != NIL)
Packit Service 5a9772
			{
Packit Service 5a9772
				value *= 31;
Packit Service 5a9772
				value += (unsigned long)ch;
Packit Service 5a9772
			}
Packit Service 5a9772
			break;
Packit Service 5a9772
		default:
Packit Service 5a9772
			assert(FALSE);
Packit Service 5a9772
			break;
Packit 1fb8d4
	}
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING char* trio_index TRIO_ARGS2((string, character), TRIO_CONST char* string,
Packit Service 5a9772
                                               int character)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(string);
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING char* trio_index_last TRIO_ARGS2((string, character), TRIO_CONST char* string,
Packit Service 5a9772
                                                    int character)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(string);
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING int trio_lower TRIO_ARGS1((target), char* target)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(target);
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
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 Service 5a9772
TRIO_PUBLIC_STRING int trio_match TRIO_ARGS2((string, pattern), TRIO_CONST char* string,
Packit Service 5a9772
                                             TRIO_CONST char* pattern)
Packit Service 5a9772
{
Packit Service 5a9772
	assert(string);
Packit Service 5a9772
	assert(pattern);
Packit Service 5a9772
Packit Service 5a9772
	for (; ('*' != *pattern); ++pattern, ++string)
Packit 1fb8d4
	{
Packit Service 5a9772
		if (NIL == *string)
Packit Service 5a9772
		{
Packit Service 5a9772
			return (NIL == *pattern);
Packit Service 5a9772
		}
Packit Service 5a9772
		if ((internal_to_upper((int)*string) != internal_to_upper((int)*pattern)) &&
Packit Service 5a9772
		    ('?' != *pattern))
Packit Service 5a9772
		{
Packit Service 5a9772
			return FALSE;
Packit Service 5a9772
		}
Packit 1fb8d4
	}
Packit Service 5a9772
	/* two-line patch to prevent *too* much recursiveness: */
Packit Service 5a9772
	while ('*' == pattern[1])
Packit Service 5a9772
		pattern++;
Packit Service 5a9772
Packit Service 5a9772
	do
Packit 1fb8d4
	{
Packit Service 5a9772
		if (trio_match(string, &pattern[1]))
Packit Service 5a9772
		{
Packit Service 5a9772
			return TRUE;
Packit Service 5a9772
		}
Packit Service 5a9772
	} while (*string++);
Packit Service 5a9772
Packit Service 5a9772
	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 Service 5a9772
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 Service 5a9772
TRIO_PUBLIC_STRING int trio_match_case TRIO_ARGS2((string, pattern), TRIO_CONST char* string,
Packit Service 5a9772
                                                  TRIO_CONST char* pattern)
Packit Service 5a9772
{
Packit Service 5a9772
	assert(string);
Packit Service 5a9772
	assert(pattern);
Packit Service 5a9772
Packit Service 5a9772
	for (; ('*' != *pattern); ++pattern, ++string)
Packit 1fb8d4
	{
Packit Service 5a9772
		if (NIL == *string)
Packit Service 5a9772
		{
Packit Service 5a9772
			return (NIL == *pattern);
Packit Service 5a9772
		}
Packit Service 5a9772
		if ((*string != *pattern) && ('?' != *pattern))
Packit Service 5a9772
		{
Packit Service 5a9772
			return FALSE;
Packit Service 5a9772
		}
Packit 1fb8d4
	}
Packit Service 5a9772
	/* two-line patch to prevent *too* much recursiveness: */
Packit Service 5a9772
	while ('*' == pattern[1])
Packit Service 5a9772
		pattern++;
Packit Service 5a9772
Packit Service 5a9772
	do
Packit 1fb8d4
	{
Packit Service 5a9772
		if (trio_match_case(string, &pattern[1]))
Packit Service 5a9772
		{
Packit Service 5a9772
			return TRUE;
Packit Service 5a9772
		}
Packit Service 5a9772
	} while (*string++);
Packit Service 5a9772
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING size_t trio_span_function TRIO_ARGS3((target, source, Function), char* target,
Packit Service 5a9772
                                                        TRIO_CONST char* source,
Packit Service 5a9772
                                                        int(*Function) TRIO_PROTO((int)))
Packit 1fb8d4
{
Packit Service 5a9772
	size_t count = 0;
Packit Service 5a9772
Packit Service 5a9772
	assert(target);
Packit Service 5a9772
	assert(source);
Packit Service 5a9772
	assert(Function);
Packit 1fb8d4
Packit Service 5a9772
	while (*source != NIL)
Packit Service 5a9772
	{
Packit Service 5a9772
		*target++ = Function(*source++);
Packit Service 5a9772
		count++;
Packit Service 5a9772
	}
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING char* trio_substring TRIO_ARGS2((string, substring), TRIO_CONST char* string,
Packit Service 5a9772
                                                   TRIO_CONST char* substring)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(string);
Packit Service 5a9772
	assert(substring);
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING char* trio_substring_max TRIO_ARGS3((string, max, substring),
Packit Service 5a9772
                                                       TRIO_CONST char* string, size_t max,
Packit Service 5a9772
                                                       TRIO_CONST char* substring)
Packit Service 5a9772
{
Packit Service 5a9772
	size_t count;
Packit Service 5a9772
	size_t size;
Packit Service 5a9772
	char* result = NULL;
Packit Service 5a9772
Packit Service 5a9772
	assert(string);
Packit Service 5a9772
	assert(substring);
Packit Service 5a9772
Packit Service 5a9772
	size = trio_length(substring);
Packit Service 5a9772
	if (size <= max)
Packit 1fb8d4
	{
Packit Service 5a9772
		for (count = 0; count <= max - size; count++)
Packit Service 5a9772
		{
Packit Service 5a9772
			if (trio_equal_max(substring, size, &string[count]))
Packit Service 5a9772
			{
Packit Service 5a9772
				result = (char*)&string[count];
Packit Service 5a9772
				break;
Packit Service 5a9772
			}
Packit Service 5a9772
		}
Packit 1fb8d4
	}
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING char* trio_tokenize TRIO_ARGS2((string, delimiters), char* string,
Packit Service 5a9772
                                                  TRIO_CONST char* delimiters)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(delimiters);
Packit Service 5a9772
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING trio_long_double_t trio_to_long_double TRIO_ARGS2((source, endp),
Packit Service 5a9772
                                                                     TRIO_CONST char* source,
Packit Service 5a9772
                                                                     char** endp)
Packit Service 5a9772
{
Packit Service 5a9772
#if defined(USE_STRTOLD)
Packit Service 5a9772
	return strtold(source, endp);
Packit Service 5a9772
#else
Packit Service 5a9772
	int isNegative = FALSE;
Packit Service 5a9772
	int isExponentNegative = FALSE;
Packit Service 5a9772
	trio_long_double_t integer = 0.0;
Packit Service 5a9772
	trio_long_double_t fraction = 0.0;
Packit Service 5a9772
	unsigned long exponent = 0;
Packit Service 5a9772
	trio_long_double_t base;
Packit Service 5a9772
	trio_long_double_t fracdiv = 1.0;
Packit Service 5a9772
	trio_long_double_t value = 0.0;
Packit Service 5a9772
Packit Service 5a9772
	/* First try hex-floats */
Packit Service 5a9772
	if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X')))
Packit 1fb8d4
	{
Packit Service 5a9772
		base = 16.0;
Packit Service 5a9772
		source += 2;
Packit Service 5a9772
		while (isxdigit((int)*source))
Packit 1fb8d4
		{
Packit Service 5a9772
			integer *= base;
Packit Service 5a9772
			integer += (isdigit((int)*source) ? (*source - '0')
Packit Service 5a9772
			                                  : 10 + (internal_to_upper((int)*source) - 'A'));
Packit Service 5a9772
			source++;
Packit 1fb8d4
		}
Packit Service 5a9772
		if (*source == '.')
Packit 1fb8d4
		{
Packit Service 5a9772
			source++;
Packit Service 5a9772
			while (isxdigit((int)*source))
Packit Service 5a9772
			{
Packit Service 5a9772
				fracdiv /= base;
Packit Service 5a9772
				fraction += fracdiv * (isdigit((int)*source)
Packit Service 5a9772
				                           ? (*source - '0')
Packit Service 5a9772
				                           : 10 + (internal_to_upper((int)*source) - 'A'));
Packit Service 5a9772
				source++;
Packit Service 5a9772
			}
Packit Service 5a9772
			if ((*source == 'p') || (*source == 'P'))
Packit Service 5a9772
			{
Packit Service 5a9772
				source++;
Packit Service 5a9772
				if ((*source == '+') || (*source == '-'))
Packit Service 5a9772
				{
Packit Service 5a9772
					isExponentNegative = (*source == '-');
Packit Service 5a9772
					source++;
Packit Service 5a9772
				}
Packit Service 5a9772
				while (isdigit((int)*source))
Packit Service 5a9772
				{
Packit Service 5a9772
					exponent *= 10;
Packit Service 5a9772
					exponent += (*source - '0');
Packit Service 5a9772
					source++;
Packit Service 5a9772
				}
Packit Service 5a9772
			}
Packit 1fb8d4
		}
Packit Service 5a9772
		/* For later use with exponent */
Packit Service 5a9772
		base = 2.0;
Packit 1fb8d4
	}
Packit Service 5a9772
	else /* Then try normal decimal floats */
Packit 1fb8d4
	{
Packit Service 5a9772
		base = 10.0;
Packit Service 5a9772
		isNegative = (*source == '-');
Packit Service 5a9772
		/* Skip sign */
Packit Service 5a9772
		if ((*source == '+') || (*source == '-'))
Packit Service 5a9772
			source++;
Packit Service 5a9772
Packit Service 5a9772
		/* Integer part */
Packit Service 5a9772
		while (isdigit((int)*source))
Packit Service 5a9772
		{
Packit Service 5a9772
			integer *= base;
Packit Service 5a9772
			integer += (*source - '0');
Packit Service 5a9772
			source++;
Packit Service 5a9772
		}
Packit 1fb8d4
Packit Service 5a9772
		if (*source == '.')
Packit Service 5a9772
		{
Packit Service 5a9772
			source++; /* skip decimal point */
Packit Service 5a9772
			while (isdigit((int)*source))
Packit Service 5a9772
			{
Packit Service 5a9772
				fracdiv /= base;
Packit Service 5a9772
				fraction += (*source - '0') * fracdiv;
Packit Service 5a9772
				source++;
Packit Service 5a9772
			}
Packit Service 5a9772
		}
Packit Service 5a9772
		if ((*source == 'e') || (*source == 'E')
Packit Service 5a9772
#if TRIO_MICROSOFT
Packit Service 5a9772
		    || (*source == 'd') || (*source == 'D')
Packit Service 5a9772
#endif
Packit Service 5a9772
		)
Packit Service 5a9772
		{
Packit Service 5a9772
			source++; /* Skip exponential indicator */
Packit Service 5a9772
			isExponentNegative = (*source == '-');
Packit Service 5a9772
			if ((*source == '+') || (*source == '-'))
Packit Service 5a9772
				source++;
Packit Service 5a9772
			while (isdigit((int)*source))
Packit Service 5a9772
			{
Packit Service 5a9772
				exponent *= (int)base;
Packit Service 5a9772
				exponent += (*source - '0');
Packit Service 5a9772
				source++;
Packit Service 5a9772
			}
Packit Service 5a9772
		}
Packit 1fb8d4
	}
Packit Service 5a9772
Packit Service 5a9772
	value = integer + fraction;
Packit Service 5a9772
	if (exponent != 0)
Packit 1fb8d4
	{
Packit Service 5a9772
		if (isExponentNegative)
Packit Service 5a9772
			value /= trio_powl(base, (trio_long_double_t)exponent);
Packit Service 5a9772
		else
Packit Service 5a9772
			value *= trio_powl(base, (trio_long_double_t)exponent);
Packit 1fb8d4
	}
Packit Service 5a9772
	if (isNegative)
Packit Service 5a9772
		value = -value;
Packit 1fb8d4
Packit Service 5a9772
	if (endp)
Packit Service 5a9772
		*endp = (char*)source;
Packit Service 5a9772
	return value;
Packit Service 5a9772
#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 Service 5a9772
TRIO_PUBLIC_STRING double trio_to_double TRIO_ARGS2((source, endp), TRIO_CONST char* source,
Packit Service 5a9772
                                                    char** endp)
Packit 1fb8d4
{
Packit 1fb8d4
#if defined(USE_STRTOD)
Packit Service 5a9772
	return strtod(source, endp);
Packit 1fb8d4
#else
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING float trio_to_float TRIO_ARGS2((source, endp), TRIO_CONST char* source,
Packit Service 5a9772
                                                  char** endp)
Packit 1fb8d4
{
Packit Service 5a9772
#if defined(USE_STRTOF)
Packit Service 5a9772
	return strtof(source, endp);
Packit Service 5a9772
#else
Packit Service 5a9772
	return (float)trio_to_long_double(source, endp);
Packit Service 5a9772
#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 Service 5a9772
TRIO_PUBLIC_STRING long trio_to_long TRIO_ARGS3((string, endp, base), TRIO_CONST char* string,
Packit Service 5a9772
                                                char** endp, int base)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(string);
Packit Service 5a9772
	assert((base >= 2) && (base <= 36));
Packit Service 5a9772
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING int trio_to_lower TRIO_ARGS1((source), int source)
Packit 1fb8d4
{
Packit Service 5a9772
#if defined(HAVE_TOLOWER)
Packit Service 5a9772
Packit Service 5a9772
	return tolower(source);
Packit 1fb8d4
Packit Service 5a9772
#else
Packit Service 5a9772
Packit Service 5a9772
	/* Does not handle locales or non-contiguous alphabetic characters */
Packit Service 5a9772
	return ((source >= (int)'A') && (source <= (int)'Z')) ? source - 'A' + 'a' : source;
Packit Service 5a9772
Packit Service 5a9772
#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 Service 5a9772
TRIO_PUBLIC_STRING unsigned long trio_to_unsigned_long TRIO_ARGS3((string, endp, base),
Packit Service 5a9772
                                                                  TRIO_CONST char* string,
Packit Service 5a9772
                                                                  char** endp, int base)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(string);
Packit Service 5a9772
	assert((base >= 2) && (base <= 36));
Packit Service 5a9772
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING int trio_to_upper TRIO_ARGS1((source), int source)
Packit 1fb8d4
{
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING int trio_upper TRIO_ARGS1((target), char* target)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(target);
Packit 1fb8d4
Packit Service 5a9772
	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
 * Dynamic String Functions
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#if defined(TRIO_DOCUMENTATION)
Packit Service 5a9772
#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 Service 5a9772
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 Service 5a9772
TRIO_PUBLIC_STRING trio_string_t* trio_string_create TRIO_ARGS1((initial_size), int initial_size)
Packit 1fb8d4
{
Packit Service 5a9772
	trio_string_t* self;
Packit 1fb8d4
Packit Service 5a9772
	self = internal_string_alloc();
Packit Service 5a9772
	if (self)
Packit 1fb8d4
	{
Packit Service 5a9772
		if (internal_string_grow(self, (size_t)((initial_size > 0) ? initial_size : 1)))
Packit Service 5a9772
		{
Packit Service 5a9772
			self->content[0] = (char)0;
Packit Service 5a9772
			self->allocated = initial_size;
Packit Service 5a9772
		}
Packit Service 5a9772
		else
Packit Service 5a9772
		{
Packit Service 5a9772
			trio_string_destroy(self);
Packit Service 5a9772
			self = NULL;
Packit Service 5a9772
		}
Packit 1fb8d4
	}
Packit Service 5a9772
	return self;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Deallocate the dynamic string and its contents.
Packit Service 5a9772
Packit 1fb8d4
   @param self Dynamic string
Packit 1fb8d4
*/
Packit 1fb8d4
#if defined(TRIO_FUNC_STRING_DESTROY)
Packit 1fb8d4
Packit Service 5a9772
TRIO_PUBLIC_STRING void trio_string_destroy TRIO_ARGS1((self), trio_string_t* self)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit Service 5a9772
Packit Service 5a9772
	if (self)
Packit Service 5a9772
	{
Packit Service 5a9772
		trio_destroy(self->content);
Packit Service 5a9772
		TRIO_FREE(self);
Packit Service 5a9772
	}
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Get a pointer to the content.
Packit Service 5a9772
Packit 1fb8d4
   @param self Dynamic string.
Packit 1fb8d4
   @param offset Offset into content.
Packit 1fb8d4
   @return Pointer to the content.
Packit Service 5a9772
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 Service 5a9772
TRIO_PUBLIC_STRING char* trio_string_get TRIO_ARGS2((self, offset), trio_string_t* self, int offset)
Packit 1fb8d4
{
Packit Service 5a9772
	char* result = NULL;
Packit 1fb8d4
Packit Service 5a9772
	assert(self);
Packit Service 5a9772
Packit Service 5a9772
	if (self->content != NULL)
Packit 1fb8d4
	{
Packit Service 5a9772
		if (self->length == 0)
Packit Service 5a9772
		{
Packit Service 5a9772
			(void)trio_string_length(self);
Packit Service 5a9772
		}
Packit Service 5a9772
		if (offset >= 0)
Packit Service 5a9772
		{
Packit Service 5a9772
			if (offset > (int)self->length)
Packit Service 5a9772
			{
Packit Service 5a9772
				offset = self->length;
Packit Service 5a9772
			}
Packit Service 5a9772
		}
Packit Service 5a9772
		else
Packit Service 5a9772
		{
Packit Service 5a9772
			offset += self->length + 1;
Packit Service 5a9772
			if (offset < 0)
Packit Service 5a9772
			{
Packit Service 5a9772
				offset = 0;
Packit Service 5a9772
			}
Packit Service 5a9772
		}
Packit Service 5a9772
		result = &(self->content[offset]);
Packit 1fb8d4
	}
Packit Service 5a9772
	return result;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Extract the content.
Packit Service 5a9772
Packit 1fb8d4
   @param self Dynamic String
Packit 1fb8d4
   @return Content of dynamic string.
Packit Service 5a9772
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 Service 5a9772
TRIO_PUBLIC_STRING char* trio_string_extract TRIO_ARGS1((self), trio_string_t* self)
Packit 1fb8d4
{
Packit Service 5a9772
	char* result;
Packit Service 5a9772
Packit Service 5a9772
	assert(self);
Packit 1fb8d4
Packit Service 5a9772
	result = self->content;
Packit Service 5a9772
	/* FIXME: Allocate new empty buffer? */
Packit Service 5a9772
	self->content = NULL;
Packit Service 5a9772
	self->length = self->allocated = 0;
Packit Service 5a9772
	return result;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
   Set the content of the dynamic string.
Packit Service 5a9772
Packit 1fb8d4
   @param self Dynamic String
Packit 1fb8d4
   @param buffer The new content.
Packit Service 5a9772
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 Service 5a9772
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 Service 5a9772
TRIO_PUBLIC_STRING void trio_xstring_set TRIO_ARGS2((self, buffer), trio_string_t* self,
Packit Service 5a9772
                                                    char* buffer)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit 1fb8d4
Packit Service 5a9772
	trio_destroy(self->content);
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING int trio_string_size TRIO_ARGS1((self), trio_string_t* self)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING void trio_string_terminate TRIO_ARGS1((self), trio_string_t* self)
Packit 1fb8d4
{
Packit Service 5a9772
	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 Service 5a9772
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 Service 5a9772
TRIO_PUBLIC_STRING int trio_string_append TRIO_ARGS2((self, other), trio_string_t* self,
Packit Service 5a9772
                                                     trio_string_t* other)
Packit 1fb8d4
{
Packit Service 5a9772
	size_t length;
Packit 1fb8d4
Packit Service 5a9772
	assert(self);
Packit Service 5a9772
	assert(other);
Packit Service 5a9772
Packit Service 5a9772
	length = self->length + other->length;
Packit Service 5a9772
	if (!internal_string_grow_to(self, length))
Packit Service 5a9772
		goto error;
Packit Service 5a9772
	trio_copy(&self->content[self->length], other->content);
Packit Service 5a9772
	self->length = length;
Packit Service 5a9772
	return TRUE;
Packit Service 5a9772
Packit Service 5a9772
error:
Packit Service 5a9772
	return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_xstring_append
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_XSTRING_APPEND)
Packit 1fb8d4
Packit Service 5a9772
TRIO_PUBLIC_STRING int trio_xstring_append TRIO_ARGS2((self, other), trio_string_t* self,
Packit Service 5a9772
                                                      TRIO_CONST char* other)
Packit 1fb8d4
{
Packit Service 5a9772
	size_t length;
Packit 1fb8d4
Packit Service 5a9772
	assert(self);
Packit Service 5a9772
	assert(other);
Packit Service 5a9772
Packit Service 5a9772
	length = self->length + trio_length(other);
Packit Service 5a9772
	if (!internal_string_grow_to(self, length))
Packit Service 5a9772
		goto error;
Packit Service 5a9772
	trio_copy(&self->content[self->length], other);
Packit Service 5a9772
	self->length = length;
Packit Service 5a9772
	return TRUE;
Packit Service 5a9772
Packit Service 5a9772
error:
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING int trio_xstring_append_char TRIO_ARGS2((self, character), trio_string_t* self,
Packit Service 5a9772
                                                           char character)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit 1fb8d4
Packit Service 5a9772
	if ((int)self->length >= trio_string_size(self))
Packit Service 5a9772
	{
Packit Service 5a9772
		if (!internal_string_grow(self, 0))
Packit Service 5a9772
			goto error;
Packit Service 5a9772
	}
Packit Service 5a9772
	self->content[self->length] = character;
Packit Service 5a9772
	self->length++;
Packit Service 5a9772
	return TRUE;
Packit Service 5a9772
Packit Service 5a9772
error:
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING int trio_xstring_append_max TRIO_ARGS3((self, other, max), trio_string_t* self,
Packit Service 5a9772
                                                          TRIO_CONST char* other, size_t max)
Packit 1fb8d4
{
Packit Service 5a9772
	size_t length;
Packit Service 5a9772
Packit Service 5a9772
	assert(self);
Packit Service 5a9772
	assert(other);
Packit Service 5a9772
Packit Service 5a9772
	length = self->length + trio_length_max(other, max);
Packit Service 5a9772
	if (!internal_string_grow_to(self, length))
Packit Service 5a9772
		goto error;
Packit 1fb8d4
Packit Service 5a9772
	/*
Packit Service 5a9772
	 * Pass max + 1 since trio_copy_max copies one character less than
Packit Service 5a9772
	 * this from the source to make room for a terminating zero.
Packit Service 5a9772
	 */
Packit Service 5a9772
	trio_copy_max(&self->content[self->length], max + 1, other);
Packit Service 5a9772
	self->length = length;
Packit Service 5a9772
	return TRUE;
Packit 1fb8d4
Packit Service 5a9772
error:
Packit Service 5a9772
	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 Service 5a9772
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 Service 5a9772
TRIO_PUBLIC_STRING int trio_string_contains TRIO_ARGS2((self, other), trio_string_t* self,
Packit Service 5a9772
                                                       trio_string_t* other)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit Service 5a9772
	assert(other);
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING int trio_xstring_contains TRIO_ARGS2((self, other), trio_string_t* self,
Packit Service 5a9772
                                                        TRIO_CONST char* other)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit Service 5a9772
	assert(other);
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING int trio_string_copy TRIO_ARGS2((self, other), trio_string_t* self,
Packit Service 5a9772
                                                   trio_string_t* other)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit Service 5a9772
	assert(other);
Packit 1fb8d4
Packit Service 5a9772
	self->length = 0;
Packit Service 5a9772
	return trio_string_append(self, other);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_xstring_copy
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_XSTRING_COPY)
Packit 1fb8d4
Packit Service 5a9772
TRIO_PUBLIC_STRING int trio_xstring_copy TRIO_ARGS2((self, other), trio_string_t* self,
Packit Service 5a9772
                                                    TRIO_CONST char* other)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit Service 5a9772
	assert(other);
Packit 1fb8d4
Packit Service 5a9772
	self->length = 0;
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING trio_string_t* trio_string_duplicate TRIO_ARGS1((other), trio_string_t* other)
Packit 1fb8d4
{
Packit Service 5a9772
	trio_string_t* self;
Packit 1fb8d4
Packit Service 5a9772
	assert(other);
Packit Service 5a9772
Packit Service 5a9772
	self = internal_string_alloc();
Packit Service 5a9772
	if (self)
Packit 1fb8d4
	{
Packit Service 5a9772
		self->content = internal_duplicate_max(other->content, other->length);
Packit Service 5a9772
		if (self->content)
Packit Service 5a9772
		{
Packit Service 5a9772
			self->length = other->length;
Packit Service 5a9772
			self->allocated = self->length + 1;
Packit Service 5a9772
		}
Packit Service 5a9772
		else
Packit Service 5a9772
		{
Packit Service 5a9772
			self->length = self->allocated = 0;
Packit Service 5a9772
		}
Packit 1fb8d4
	}
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING trio_string_t* trio_xstring_duplicate TRIO_ARGS1((other), TRIO_CONST char* other)
Packit 1fb8d4
{
Packit Service 5a9772
	trio_string_t* self;
Packit 1fb8d4
Packit Service 5a9772
	assert(other);
Packit Service 5a9772
Packit Service 5a9772
	self = internal_string_alloc();
Packit Service 5a9772
	if (self)
Packit 1fb8d4
	{
Packit Service 5a9772
		self->content = internal_duplicate_max(other, trio_length(other));
Packit Service 5a9772
		if (self->content)
Packit Service 5a9772
		{
Packit Service 5a9772
			self->length = trio_length(self->content);
Packit Service 5a9772
			self->allocated = self->length + 1;
Packit Service 5a9772
		}
Packit Service 5a9772
		else
Packit Service 5a9772
		{
Packit Service 5a9772
			self->length = self->allocated = 0;
Packit Service 5a9772
		}
Packit 1fb8d4
	}
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING int trio_string_equal TRIO_ARGS2((self, other), trio_string_t* self,
Packit Service 5a9772
                                                    trio_string_t* other)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit Service 5a9772
	assert(other);
Packit 1fb8d4
Packit Service 5a9772
	return trio_equal(self->content, other->content);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * trio_xstring_equal
Packit 1fb8d4
 */
Packit 1fb8d4
#if defined(TRIO_FUNC_XSTRING_EQUAL)
Packit 1fb8d4
Packit Service 5a9772
TRIO_PUBLIC_STRING int trio_xstring_equal TRIO_ARGS2((self, other), trio_string_t* self,
Packit Service 5a9772
                                                     TRIO_CONST char* other)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit Service 5a9772
	assert(other);
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING int trio_string_equal_max TRIO_ARGS3((self, max, other), trio_string_t* self,
Packit Service 5a9772
                                                        size_t max, trio_string_t* other)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit Service 5a9772
	assert(other);
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING int trio_xstring_equal_max TRIO_ARGS3((self, max, other), trio_string_t* self,
Packit Service 5a9772
                                                         size_t max, TRIO_CONST char* other)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit Service 5a9772
	assert(other);
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING int trio_string_equal_case TRIO_ARGS2((self, other), trio_string_t* self,
Packit Service 5a9772
                                                         trio_string_t* other)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit Service 5a9772
	assert(other);
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING int trio_xstring_equal_case TRIO_ARGS2((self, other), trio_string_t* self,
Packit Service 5a9772
                                                          TRIO_CONST char* other)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit Service 5a9772
	assert(other);
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING int trio_string_equal_case_max TRIO_ARGS3((self, max, other),
Packit Service 5a9772
                                                             trio_string_t* self, size_t max,
Packit Service 5a9772
                                                             trio_string_t* other)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit Service 5a9772
	assert(other);
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING int trio_xstring_equal_case_max TRIO_ARGS3((self, max, other),
Packit Service 5a9772
                                                              trio_string_t* self, size_t max,
Packit Service 5a9772
                                                              TRIO_CONST char* other)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit Service 5a9772
	assert(other);
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING size_t trio_string_format_date_max TRIO_ARGS4((self, max, format, datetime),
Packit Service 5a9772
                                                                 trio_string_t* self, size_t max,
Packit Service 5a9772
                                                                 TRIO_CONST char* format,
Packit Service 5a9772
                                                                 TRIO_CONST struct tm* datetime)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING char* trio_string_index TRIO_ARGS2((self, character), trio_string_t* self,
Packit Service 5a9772
                                                      int character)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING char* trio_string_index_last TRIO_ARGS2((self, character), trio_string_t* self,
Packit Service 5a9772
                                                           int character)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING int trio_string_length TRIO_ARGS1((self), trio_string_t* self)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit 1fb8d4
Packit Service 5a9772
	if (self->length == 0)
Packit Service 5a9772
	{
Packit Service 5a9772
		self->length = trio_length(self->content);
Packit Service 5a9772
	}
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING int trio_string_lower TRIO_ARGS1((self), trio_string_t* self)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING int trio_string_match TRIO_ARGS2((self, other), trio_string_t* self,
Packit Service 5a9772
                                                    trio_string_t* other)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit Service 5a9772
	assert(other);
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING int trio_xstring_match TRIO_ARGS2((self, other), trio_string_t* self,
Packit Service 5a9772
                                                     TRIO_CONST char* other)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit Service 5a9772
	assert(other);
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING int trio_string_match_case TRIO_ARGS2((self, other), trio_string_t* self,
Packit Service 5a9772
                                                         trio_string_t* other)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit Service 5a9772
	assert(other);
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING int trio_xstring_match_case TRIO_ARGS2((self, other), trio_string_t* self,
Packit Service 5a9772
                                                          TRIO_CONST char* other)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit Service 5a9772
	assert(other);
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING char* trio_string_substring TRIO_ARGS2((self, other), trio_string_t* self,
Packit Service 5a9772
                                                          trio_string_t* other)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit Service 5a9772
	assert(other);
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING char* trio_xstring_substring TRIO_ARGS2((self, other), trio_string_t* self,
Packit Service 5a9772
                                                           TRIO_CONST char* other)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit Service 5a9772
	assert(other);
Packit 1fb8d4
Packit Service 5a9772
	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 Service 5a9772
TRIO_PUBLIC_STRING int trio_string_upper TRIO_ARGS1((self), trio_string_t* self)
Packit 1fb8d4
{
Packit Service 5a9772
	assert(self);
Packit 1fb8d4
Packit Service 5a9772
	return trio_upper(self->content);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/** @} End of DynamicStrings */