diff options
author | Bjorn Reese <breese@src.gnome.org> | 2002-01-19 15:40:18 +0000 |
---|---|---|
committer | Bjorn Reese <breese@src.gnome.org> | 2002-01-19 15:40:18 +0000 |
commit | 026d29f41e252619bcc5655865c9548642cd93f7 (patch) | |
tree | 1d0a4d98052a7e4517a1f941abd3d588e6716fcb | |
parent | 572577e094bd436b2124aa0ef44df3d57f97d793 (diff) | |
download | libxml2-026d29f41e252619bcc5655865c9548642cd93f7.tar.gz |
Upgraded to trio baseline 1.6
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | Makefile.am | 4 | ||||
-rw-r--r-- | strio.c | 581 | ||||
-rw-r--r-- | strio.h | 227 | ||||
-rw-r--r-- | trio.c | 1383 | ||||
-rw-r--r-- | trio.h | 24 | ||||
-rw-r--r-- | triodef.h | 42 | ||||
-rw-r--r-- | trionan.c | 106 | ||||
-rw-r--r-- | trionan.h | 28 | ||||
-rw-r--r-- | triop.h | 9 | ||||
-rw-r--r-- | triostr.c | 1753 | ||||
-rw-r--r-- | triostr.h | 119 |
12 files changed, 2832 insertions, 1450 deletions
@@ -1,3 +1,9 @@ +Sat Jan 19 16:36:21 CET 2002 Bjorn Reese <breese@users.sourceforge.net> + + * trio.h trio.c triodef.h triop.h trionan.h trionan.c Makefile.am: + Upgraded to trio baseline 1.6 + * strio.h strio.c: Replaced by triostr.h and triostr.c + Fri Jan 18 17:22:50 CET 2002 Daniel Veillard <daniel@veillard.com> * globals.c xmlIO.c xmlcatalog.c: removed the last occurences diff --git a/Makefile.am b/Makefile.am index 0b6d011e..1b726b89 100644 --- a/Makefile.am +++ b/Makefile.am @@ -21,7 +21,7 @@ libxml2_la_SOURCES = SAX.c entities.c encoding.c error.c parserInternals.c \ parser.c tree.c hash.c list.c xmlIO.c xmlmemory.c uri.c \ valid.c xlink.c HTMLparser.c HTMLtree.c debugXML.c xpath.c \ xpointer.c xinclude.c nanohttp.c nanoftp.c DOCBparser.c \ - catalog.c globals.c threads.c strio.c trio.c + catalog.c globals.c threads.c triostr.c trio.c else libxml2_la_SOURCES = SAX.c entities.c encoding.c error.c parserInternals.c \ @@ -568,7 +568,7 @@ EXTRA_DIST = xml2-config.in xml2Conf.sh.in libxml.spec.in libxml.spec \ libxml.m4 \ example/Makefile.am example/gjobread.c example/gjobs.xml \ $(man_MANS) libxml-2.0.pc.in \ - trionan.c trionan.h strio.c strio.h trio.c trio.h \ + trionan.c trionan.h triostr.c triostr.h trio.c trio.h \ triop.h triodef.h libxml.h \ testThreadsWin32.c diff --git a/strio.c b/strio.c deleted file mode 100644 index 58a9a263..00000000 --- a/strio.c +++ /dev/null @@ -1,581 +0,0 @@ -/************************************************************************* - * - * $Id$ - * - * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************/ - -/* - * TODO - * - StrToLongDouble - */ - -static const char rcsid[] = "@(#)$Id$"; - -#if defined(unix) || defined(__xlC__) || defined(__QNX__) || defined(__CYGWIN__) -# define PLATFORM_UNIX -#elif defined(WIN32) || defined(_WIN32) -# define PLATFORM_WIN32 -#elif defined(AMIGA) && defined(__GNUC__) -# define PLATFORM_UNIX -#endif - -#if defined(__STDC__) && (__STDC_VERSION__ >= 199901L) -# define TRIO_C99 -#endif - -#include "strio.h" -#include <string.h> -#include <locale.h> -#include <ctype.h> -#include <stdarg.h> -#include <time.h> -#include <math.h> -#ifndef DEBUG -# define NDEBUG -#endif -#include <assert.h> - -#ifndef NULL -# define NULL 0 -#endif -#define NIL ((char)0) -#ifndef FALSE -# define FALSE (1 == 0) -# define TRUE (! FALSE) -#endif - -#define VALID(x) (NULL != (x)) -#define INVALID(x) (NULL == (x)) - -#if defined(PLATFORM_UNIX) -# define USE_STRCASECMP -# define USE_STRNCASECMP -# define USE_STRERROR -# if defined(__QNX__) -# define strcasecmp(x,y) stricmp(x,y) -# define strncasecmp(x,y,n) strnicmp(x,y,n) -# endif -#elif defined(PLATFORM_WIN32) -# define USE_STRCASECMP -# define strcasecmp(x,y) strcmpi(x,y) -#endif - -/************************************************************************* - * StrAppendMax - */ -char *StrAppendMax(char *target, size_t max, const char *source) -{ - assert(VALID(target)); - assert(VALID(source)); - assert(max > 0); - - max -= StrLength(target) + 1; - return (max > 0) ? strncat(target, source, max) : target; -} - -/************************************************************************* - * StrCopyMax - */ -char *StrCopyMax(char *target, size_t max, const char *source) -{ - assert(VALID(target)); - assert(VALID(source)); - assert(max > 0); /* Includes != 0 */ - - target = strncpy(target, source, max - 1); - target[max - 1] = (char)0; - return target; -} - -/************************************************************************* - * StrDuplicate - */ -char *StrDuplicate(const char *source) -{ - char *target; - - assert(VALID(source)); - - target = StrAlloc(StrLength(source) + 1); - if (target) - { - StrCopy(target, source); - } - return target; -} - -/************************************************************************* - * StrDuplicateMax - */ -char *StrDuplicateMax(const char *source, size_t max) -{ - char *target; - size_t len; - - assert(VALID(source)); - assert(max > 0); - - /* Make room for string plus a terminating zero */ - len = StrLength(source) + 1; - if (len > max) - { - len = max; - } - target = StrAlloc(len); - if (target) - { - StrCopyMax(target, len, source); - } - return target; -} - -/************************************************************************* - * StrEqual - */ -int StrEqual(const char *first, const char *second) -{ - assert(VALID(first)); - assert(VALID(second)); - - if (VALID(first) && VALID(second)) - { -#if defined(USE_STRCASECMP) - return (0 == strcasecmp(first, second)); -#else - while ((*first != NIL) && (*second != NIL)) - { - if (toupper(*first) != toupper(*second)) - { - break; - } - first++; - second++; - } - return ((*first == NIL) && (*second == NIL)); -#endif - } - return FALSE; -} - -/************************************************************************* - * StrEqualCase - */ -int StrEqualCase(const char *first, const char *second) -{ - assert(VALID(first)); - assert(VALID(second)); - - if (VALID(first) && VALID(second)) - { - return (0 == strcmp(first, second)); - } - return FALSE; -} - -/************************************************************************* - * StrEqualCaseMax - */ -int StrEqualCaseMax(const char *first, size_t max, const char *second) -{ - assert(VALID(first)); - assert(VALID(second)); - - if (VALID(first) && VALID(second)) - { - return (0 == strncmp(first, second, max)); - } - return FALSE; -} - -/************************************************************************* - * StrEqualLocale - */ -int StrEqualLocale(const char *first, const char *second) -{ - assert(VALID(first)); - assert(VALID(second)); - -#if defined(LC_COLLATE) - return (strcoll(first, second) == 0); -#else - return StrEqual(first, second); -#endif -} - -/************************************************************************* - * StrEqualMax - */ -int StrEqualMax(const char *first, size_t max, const char *second) -{ - assert(VALID(first)); - assert(VALID(second)); - - if (VALID(first) && VALID(second)) - { -#if defined(USE_STRNCASECMP) - return (0 == strncasecmp(first, second, max)); -#else - /* Not adequately tested yet */ - size_t cnt = 0; - while ((*first != NIL) && (*second != NIL) && (cnt <= max)) - { - if (toupper(*first) != toupper(*second)) - { - break; - } - first++; - second++; - cnt++; - } - return ((cnt == max) || ((*first == NIL) && (*second == NIL))); -#endif - } - return FALSE; -} - -/************************************************************************* - * StrError - */ -const char *StrError(int errorNumber) -{ -#if defined(USE_STRERROR) - return strerror(errorNumber); -#else - return "unknown"; -#endif -} - -/************************************************************************* - * StrFormatDate - */ -size_t StrFormatDateMax(char *target, - size_t max, - const char *format, - const struct tm *datetime) -{ - assert(VALID(target)); - assert(VALID(format)); - assert(VALID(datetime)); - assert(max > 0); - - return strftime(target, max, format, datetime); -} - -/************************************************************************* - * StrHash - */ -unsigned long StrHash(const char *string, int type) -{ - unsigned long value = 0L; - char ch; - - assert(VALID(string)); - - switch (type) - { - case STRIO_HASH_PLAIN: - while ( (ch = *string++) != NIL ) - { - value *= 31; - value += (unsigned long)ch; - } - break; - default: - assert(FALSE); - break; - } - return value; -} - -/************************************************************************* - * StrMatch - */ -int StrMatch(char *string, char *pattern) -{ - assert(VALID(string)); - assert(VALID(pattern)); - - for (; ('*' != *pattern); ++pattern, ++string) - { - if (NIL == *string) - { - return (NIL == *pattern); - } - if ((toupper((int)*string) != toupper((int)*pattern)) - && ('?' != *pattern)) - { - return FALSE; - } - } - /* two-line patch to prevent *too* much recursiveness: */ - while ('*' == pattern[1]) - pattern++; - - do - { - if ( StrMatch(string, &pattern[1]) ) - { - return TRUE; - } - } - while (*string++); - - return FALSE; -} - -/************************************************************************* - * StrMatchCase - */ -int StrMatchCase(char *string, char *pattern) -{ - assert(VALID(string)); - assert(VALID(pattern)); - - for (; ('*' != *pattern); ++pattern, ++string) - { - if (NIL == *string) - { - return (NIL == *pattern); - } - if ((*string != *pattern) - && ('?' != *pattern)) - { - return FALSE; - } - } - /* two-line patch to prevent *too* much recursiveness: */ - while ('*' == pattern[1]) - pattern++; - - do - { - if ( StrMatchCase(string, &pattern[1]) ) - { - return TRUE; - } - } - while (*string++); - - return FALSE; -} - -/************************************************************************* - * StrSpanFunction - * - * Untested - */ -size_t StrSpanFunction(char *source, int (*Function)(int)) -{ - size_t count = 0; - - assert(VALID(source)); - assert(VALID(Function)); - - while (*source != NIL) - { - if (Function(*source)) - break; /* while */ - source++; - count++; - } - return count; -} - -/************************************************************************* - * StrSubstringMax - */ -char *StrSubstringMax(const char *string, size_t max, const char *find) -{ - size_t count; - size_t size; - char *result = NULL; - - assert(VALID(string)); - assert(VALID(find)); - - size = StrLength(find); - if (size <= max) - { - for (count = 0; count <= max - size; count++) - { - if (StrEqualMax(find, size, &string[count])) - { - result = (char *)&string[count]; - break; - } - } - } - return result; -} - -/************************************************************************* - * StrToDouble - * - * double ::= [ <sign> ] - * ( <number> | - * <number> <decimal_point> <number> | - * <decimal_point> <number> ) - * [ <exponential> [ <sign> ] <number> ] - * number ::= 1*( <digit> ) - * digit ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' ) - * exponential ::= ( 'e' | 'E' ) - * sign ::= ( '-' | '+' ) - * decimal_point ::= '.' - */ -double StrToDouble(const char *source, const char **endp) -{ -#if defined(TRIO_C99) - return strtod(source, endp); -#else - /* Preliminary code */ - int isNegative = FALSE; - int isExponentNegative = FALSE; - unsigned long integer = 0; - unsigned long fraction = 0; - unsigned long fracdiv = 1; - unsigned long exponent = 0; - double value = 0.0; - - /* First try hex-floats */ - if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X'))) - { - source += 2; - while (isxdigit((int)*source)) - { - integer *= 16; - integer += (isdigit((int)*source) - ? (*source - '0') - : 10 + (toupper((int)*source) - 'A')); - source++; - } - if (*source == '.') - { - source++; - while (isxdigit((int)*source)) - { - fraction *= 16; - fraction += (isdigit((int)*source) - ? (*source - '0') - : 10 + (toupper((int)*source) - 'A')); - fracdiv *= 16; - source++; - } - if ((*source == 'p') || (*source == 'P')) - { - source++; - if ((*source == '+') || (*source == '-')) - { - isExponentNegative = (*source == '-'); - source++; - } - while (isdigit((int)*source)) - { - exponent *= 10; - exponent += (*source - '0'); - source++; - } - } - } - } - else /* Then try normal decimal floats */ - { - isNegative = (*source == '-'); - /* Skip sign */ - if ((*source == '+') || (*source == '-')) - source++; - - /* Integer part */ - while (isdigit((int)*source)) - { - integer *= 10; - integer += (*source - '0'); - source++; - } - - if (*source == '.') - { - source++; /* skip decimal point */ - while (isdigit((int)*source)) - { - fraction *= 10; - fraction += (*source - '0'); - fracdiv *= 10; - source++; - } - } - if ((*source == 'e') || (*source == 'E')) - { - source++; /* Skip exponential indicator */ - isExponentNegative = (*source == '-'); - if ((*source == '+') || (*source == '-')) - source++; - while (isdigit((int)*source)) - { - exponent *= 10; - exponent += (*source - '0'); - source++; - } - } - } - - value = (double)integer; - if (fraction != 0) - { - value += (double)fraction / (double)fracdiv; - } - if (exponent != 0) - { - if (isExponentNegative) - value /= pow((double)10, (double)exponent); - else - value *= pow((double)10, (double)exponent); - } - if (isNegative) - value = -value; - - if (endp) - *endp = source; - return value; -#endif -} - -/************************************************************************* - * StrToFloat - */ -float StrToFloat(const char *source, const char **endp) -{ -#if defined(TRIO_C99) - return strtof(source, endp); -#else - return (float)StrToDouble(source, endp); -#endif -} - -/************************************************************************* - * StrToUpper - */ -int StrToUpper(char *target) -{ - int i = 0; - - assert(VALID(target)); - - while (NIL != *target) - { - *target = toupper((int)*target); - target++; - i++; - } - return i; -} diff --git a/strio.h b/strio.h deleted file mode 100644 index 68845a38..00000000 --- a/strio.h +++ /dev/null @@ -1,227 +0,0 @@ -/************************************************************************* - * - * $Id$ - * - * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************/ - -#ifndef TRIO_STRIO_H -#define TRIO_STRIO_H - -#if !(defined(DEBUG) || defined(NDEBUG)) -# define NDEBUG -#endif -#include <assert.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#ifndef STRIO_MALLOC -# define STRIO_MALLOC(n) malloc(n) -#endif -#ifndef STRIO_FREE -# define STRIO_FREE(x) free(x) -#endif - -/* - * StrAppend(target, source) - * StrAppendMax(target, maxsize, source) - * - * Append 'source' to 'target' - * - * target = StrAlloc(size) - * - * Allocate a new string - * - * StrContains(target, substring) - * - * Find out if the string 'substring' is - * contained in the string 'target' - * - * StrCopy(target, source) - * StrCopyMax(target, maxsize, source) - * - * Copy 'source' to 'target' - * - * target = StrDuplicate(source) - * target = StrDuplicateMax(source, maxsize) - * - * Allocate and copy 'source' to 'target' - * - * StrEqual(first, second) - * StrEqualMax(first, maxsize, second) - * - * Compare if 'first' is equal to 'second'. - * Case-independent. - * - * StrEqualCase(first, second) - * StrEqualCaseMax(first, maxsize, second) - * - * Compare if 'first' is equal to 'second' - * Case-dependent. Please note that the use of the - * word 'case' has the opposite meaning as that of - * strcasecmp(). - * - * StrFormat(target, format, ...) - * StrFormatMax(target, maxsize, format, ...) - * - * Build 'target' according to 'format' and succesive - * arguments. This is equal to the sprintf() and - * snprintf() functions. - * - * StrFormatDate(target, format, ...) - * - * StrFree(target) - * - * De-allocates a string - * - * StrHash(string, type) - * - * Calculates the hash value of 'string' based on the - * 'type'. - * - * StrIndex(target, character) - * StrIndexLast(target, character) - * - * Find the first/last occurrence of 'character' in - * 'target' - * - * StrLength(target) - * - * Return the length of 'target' - * - * StrMatch(string, pattern) - * StrMatchCase(string, pattern) - * - * Find 'pattern' within 'string'. 'pattern' may contain - * wildcards such as * (asterics) and ? (question mark) - * which matches zero or more characters and exactly - * on character respectively - * - * StrScan(source, format, ...) - * - * Equal to sscanf() - * - * StrSubstring(target, substring) - * - * Find the first occurrence of the string 'substring' - * within the string 'target' - * - * StrTokenize(target, list) - * - * Split 'target' into the first token delimited by - * one of the characters in 'list'. If 'target' is - * NULL then next token will be returned. - * - * StrToUpper(target) - * - * Convert all lower case characters in 'target' into - * upper case characters. - */ - -enum { - STRIO_HASH_NONE = 0, - STRIO_HASH_PLAIN, - STRIO_HASH_TWOSIGNED -}; - -#if !defined(DEBUG) || defined(__DECC) -#define StrAlloc(n) (char *)STRIO_MALLOC(n) -#define StrAppend(x,y) strcat((x), (y)) -#define StrContains(x,y) (0 != strstr((x), (y))) -#define StrCopy(x,y) strcpy((x), (y)) -#define StrIndex(x,y) strchr((x), (y)) -#define StrIndexLast(x,y) strrchr((x), (y)) -#define StrFree(x) STRIO_FREE(x) -#define StrLength(x) strlen((x)) -#define StrSubstring(x,y) strstr((x), (y)) -#define StrTokenize(x,y) strtok((x), (y)) -#define StrToLong(x,y,n) strtol((x), (y), (n)) -#define StrToUnsignedLong(x,y,n) strtoul((x), (y), (n)) -#else /* DEBUG */ - /* - * To be able to use these macros everywhere, including in - * if() sentences, the assertions are put first in a comma - * seperated list. - * - * Unfortunately the DECC compiler does not seem to like this - * so it will use the un-asserted functions above for the - * debugging case too. - */ -#define StrAlloc(n) \ - (assert((n) > 0),\ - (char *)STRIO_MALLOC(n)) -#define StrAppend(x,y) \ - (assert((x) != NULL),\ - assert((y) != NULL),\ - strcat((x), (y))) -#define StrContains(x,y) \ - (assert((x) != NULL),\ - assert((y) != NULL),\ - (0 != strstr((x), (y)))) -#define StrCopy(x,y) \ - (assert((x) != NULL),\ - assert((y) != NULL),\ - strcpy((x), (y))) -#define StrIndex(x,c) \ - (assert((x) != NULL),\ - strchr((x), (c))) -#define StrIndexLast(x,c) \ - (assert((x) != NULL),\ - strrchr((x), (c))) -#define StrFree(x) \ - (assert((x) != NULL),\ - STRIO_FREE(x)) -#define StrLength(x) \ - (assert((x) != NULL),\ - strlen((x))) -#define StrSubstring(x,y) \ - (assert((x) != NULL),\ - assert((y) != NULL),\ - strstr((x), (y))) -#define StrTokenize(x,y) \ - (assert((y) != NULL),\ - strtok((x), (y))) -#define StrToLong(x,y,n) \ - (assert((x) != NULL),\ - assert((y) != NULL),\ - assert((n) >= 2 && (n) <= 36),\ - strtol((x), (y), (n))) -#define StrToUnsignedLong(x,y,n) \ - (assert((x) != NULL),\ - assert((y) != NULL),\ - assert((n) >= 2 && (n) <= 36),\ - strtoul((x), (y), (n))) -#endif /* DEBUG */ - -char *StrAppendMax(char *target, size_t max, const char *source); -char *StrCopyMax(char *target, size_t max, const char *source); -char *StrDuplicate(const char *source); -char *StrDuplicateMax(const char *source, size_t max); -int StrEqual(const char *first, const char *second); -int StrEqualCase(const char *first, const char *second); -int StrEqualCaseMax(const char *first, size_t max, const char *second); -int StrEqualLocale(const char *first, const char *second); -int StrEqualMax(const char *first, size_t max, const char *second); -const char *StrError(int); -size_t StrFormatDateMax(char *target, size_t max, const char *format, const struct tm *datetime); -unsigned long StrHash(const char *string, int type); -int StrMatch(char *string, char *pattern); -int StrMatchCase(char *string, char *pattern); -size_t StrSpanFunction(char *source, int (*Function)(int)); -char *StrSubstringMax(const char *string, size_t max, const char *find); -float StrToFloat(const char *source, const char **target); -double StrToDouble(const char *source, const char **target); -int StrToUpper(char *target); - -#endif /* TRIO_STRIO_H */ @@ -41,16 +41,14 @@ * - Scanning of collating symbols. */ -static const char rcsid[] = "@(#)$Id$"; - /************************************************************************* * Trio include files */ #include "triodef.h" #include "trio.h" #include "triop.h" +#include "triostr.h" #include "trionan.h" -#include "strio.h" /* * Encode the error code and the position. This is decoded @@ -110,17 +108,20 @@ static const char rcsid[] = "@(#)$Id$"; /************************************************************************* * Platform specific definitions */ -#if defined(PLATFORM_UNIX) +#if defined(TRIO_PLATFORM_UNIX) # include <unistd.h> # include <signal.h> # include <locale.h> # define USE_LOCALE -#endif /* PLATFORM_UNIX */ -#if defined(PLATFORM_WIN32) +#endif /* TRIO_PLATFORM_UNIX */ +#if defined(TRIO_PLATFORM_VMS) +# include <unistd.h> +#endif +#if defined(TRIO_PLATFORM_WIN32) # include <io.h> # define read _read # define write _write -#endif /* PLATFORM_WIN32 */ +#endif /* TRIO_PLATFORM_WIN32 */ #define TRIO_MSVC_VERSION_5 1100 @@ -131,6 +132,7 @@ static const char rcsid[] = "@(#)$Id$"; # else typedef char wchar_t; typedef int wint_t; +# define WCONST(x) L ## x # define WEOF EOF # define iswalnum(x) isalnum(x) # define iswalpha(x) isalpha(x) @@ -155,9 +157,9 @@ typedef int wint_t; /* Support for long long */ #ifndef __cplusplus # if !defined(USE_LONGLONG) -# if defined(__GNUC__) && !defined(__STRICT_ANSI__) +# if defined(TRIO_COMPILER_GCC) && !defined(__STRICT_ANSI__) # define USE_LONGLONG -# elif defined(__SUNPRO_C) +# elif defined(TRIO_COMPILER_SUNPRO) # define USE_LONGLONG # elif defined(_LONG_LONG) || defined(_LONGLONG) # define USE_LONGLONG @@ -169,7 +171,7 @@ typedef int wint_t; #if defined(USE_LONGLONG) typedef signed long long int trio_longlong_t; typedef unsigned long long int trio_ulonglong_t; -#elif defined(_MSC_VER) +#elif defined(TRIO_COMPILER_MSVC) # if (_MSC_VER >= TRIO_MSVC_VERSION_5) typedef signed __int64 trio_longlong_t; typedef unsigned __int64 trio_ulonglong_t; @@ -199,7 +201,7 @@ typedef int8_t trio_int8_t; typedef int16_t trio_int16_t; typedef int32_t trio_int32_t; typedef int64_t trio_int64_t; -#elif defined(_MSC_VER) && (_MSC_VER >= TRIO_MSVC_5) +#elif defined(TRIO_COMPILER_MSVC) && (_MSC_VER >= TRIO_MSVC_VERSION_5) typedef trio_longlong_t trio_intmax_t; typedef trio_ulonglong_t trio_uintmax_t; typedef __int8 trio_int8_t; @@ -319,7 +321,7 @@ enum { /* Maximal number of allowed parameters */ MAX_PARAMETERS = 64, /* Maximal number of characters in class */ - MAX_CHARACTER_CLASS = UCHAR_MAX, + MAX_CHARACTER_CLASS = UCHAR_MAX + 1, /* Maximal string lengths for user-defined specifiers */ MAX_USER_NAME = 64, @@ -328,7 +330,10 @@ enum { /* Maximal length of locale separator strings */ MAX_LOCALE_SEPARATOR_LENGTH = MB_LEN_MAX, /* Maximal number of integers in grouping */ - MAX_LOCALE_GROUPS = 64 + MAX_LOCALE_GROUPS = 64, + + /* Initial size of asprintf buffer */ + DYNAMIC_START_SIZE = 32 }; #define NO_GROUPING ((int)CHAR_MAX) @@ -359,6 +364,7 @@ enum { /* Character class expressions */ #define CLASS_ALNUM ":alnum:" #define CLASS_ALPHA ":alpha:" +#define CLASS_BLANK ":blank:" #define CLASS_CNTRL ":cntrl:" #define CLASS_DIGIT ":digit:" #define CLASS_GRAPH ":graph:" @@ -571,13 +577,21 @@ enum { /* Parameters */ typedef struct { + /* An indication of which entry in the data union is used */ int type; + /* The flags */ unsigned long flags; + /* The width qualifier */ int width; + /* The precision qualifier */ int precision; + /* The base qualifier */ int base; + /* The size for the variable size qualifier */ int varsize; + /* The marker of the end of the specifier */ int indexAfterSpecifier; + /* The data from the argument list */ union { char *string; #if TRIO_WIDECHAR @@ -597,50 +611,77 @@ typedef struct { /* For the user-defined specifier */ char user_name[MAX_USER_NAME]; char user_data[MAX_USER_DATA]; -} parameter_T; +} trio_parameter_t; /* General trio "class" */ -typedef struct _trio_T { +typedef struct _trio_class_t { + /* + * The function to write characters to a stream. + */ + void (*OutStream)(struct _trio_class_t *, int); + /* + * The function to read characters from a stream. + */ + void (*InStream)(struct _trio_class_t *, int *); + /* + * The current location in the stream. + */ void *location; - void (*OutStream)(struct _trio_T *, int); - void (*InStream)(struct _trio_T *, int *); /* - * The number of characters that would have been written/read if - * there had been sufficient space. + * The character currently being processed. + */ + int current; + /* + * The number of characters that would have been written/read + * if there had been sufficient space. */ int processed; /* * The number of characters that are actually written/read. - * Processed and committed with only differ for the *nprintf + * Processed and committed will only differ for the *nprintf * and *nscanf functions. */ int committed; + /* + * The upper limit of characters that may be written/read. + */ int max; - int current; -} trio_T; + /* + * The last output error that was detected. + */ + int error; +} trio_class_t; /* References (for user-defined callbacks) */ -typedef struct _reference_T { - trio_T *data; - parameter_T *parameter; -} reference_T; +typedef struct _trio_reference_t { + trio_class_t *data; + trio_parameter_t *parameter; +} trio_reference_t; /* Registered entries (for user-defined callbacks) */ -typedef struct _userdef_T { - struct _userdef_T *next; +typedef struct _trio_userdef_t { + struct _trio_userdef_t *next; trio_callback_t callback; char *name; -} userdef_T; +} trio_userdef_t; /************************************************************************* * Internal variables */ -#if defined(PLATFORM_UNIX) -extern int errno; +static TRIO_CONST char rcsid[] = "@(#)$Id$"; + +/* + * Need this to workaround a parser bug in HP C/iX compiler that fails + * to resolves macro definitions that includes type 'long double', + * e.g: va_arg(arg_ptr, long double) + */ +#if defined(TRIO_PLATFORM_MPEIX) +static TRIO_CONST long double ___dummy_long_double = 0; #endif -static const char null[] = "(nil)"; + +static TRIO_CONST char internalNullString[] = "(nil)"; #if defined(USE_LOCALE) static struct lconv *internalLocaleValues = NULL; @@ -654,8 +695,8 @@ static char internalDecimalPoint[MAX_LOCALE_SEPARATOR_LENGTH + 1] = "."; static char internalThousandSeparator[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ","; static char internalGrouping[MAX_LOCALE_GROUPS] = { (char)NO_GROUPING }; -static const char internalDigitsLower[] = "0123456789abcdefghijklmnopqrstuvwxyz"; -static const char internalDigitsUpper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +static TRIO_CONST char internalDigitsLower[] = "0123456789abcdefghijklmnopqrstuvwxyz"; +static TRIO_CONST char internalDigitsUpper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; static BOOLEAN_T internalDigitsUnconverted = TRUE; static int internalDigitArray[128]; #if TRIO_EXTENSION @@ -663,15 +704,16 @@ static BOOLEAN_T internalCollationUnconverted = TRUE; static char internalCollationArray[MAX_CHARACTER_CLASS][MAX_CHARACTER_CLASS]; #endif -static volatile trio_callback_t internalEnterCriticalRegion = NULL; -static volatile trio_callback_t internalLeaveCriticalRegion = NULL; -static userdef_T *internalUserDef = NULL; +static TRIO_VOLATILE trio_callback_t internalEnterCriticalRegion = NULL; +static TRIO_VOLATILE trio_callback_t internalLeaveCriticalRegion = NULL; +static trio_userdef_t *internalUserDef = NULL; /************************************************************************* - * trio_strerror [public] + * trio_strerror */ -const char *trio_strerror(int errorcode) +TRIO_PUBLIC TRIO_CONST char * +trio_strerror(int errorcode) { /* Textual versions of the error codes */ switch (TRIO_ERROR_CODE(errorcode)) @@ -696,14 +738,14 @@ const char *trio_strerror(int errorcode) } /************************************************************************* - * TrioIsQualifier [private] + * TrioIsQualifier * * Description: * Remember to add all new qualifiers to this function. * QUALIFIER_POSITION must not be added. */ -static BOOLEAN_T -TrioIsQualifier(const char ch) +TRIO_PRIVATE BOOLEAN_T +TrioIsQualifier(TRIO_CONST char ch) { /* QUALIFIER_POSITION is not included */ switch (ch) @@ -760,10 +802,10 @@ TrioIsQualifier(const char ch) } /************************************************************************* - * TrioSetLocale [private] + * TrioSetLocale */ #if defined(USE_LOCALE) -static void +TRIO_PUBLIC void TrioSetLocale(void) { internalLocaleValues = (struct lconv *)localeconv(); @@ -772,42 +814,42 @@ TrioSetLocale(void) if ((internalLocaleValues->decimal_point) && (internalLocaleValues->decimal_point[0] != NIL)) { - StrCopyMax(internalDecimalPoint, - sizeof(internalDecimalPoint), - internalLocaleValues->decimal_point); + trio_copy_max(internalDecimalPoint, + sizeof(internalDecimalPoint), + internalLocaleValues->decimal_point); } if ((internalLocaleValues->thousands_sep) && (internalLocaleValues->thousands_sep[0] != NIL)) { - StrCopyMax(internalThousandSeparator, - sizeof(internalThousandSeparator), - internalLocaleValues->thousands_sep); + trio_copy_max(internalThousandSeparator, + sizeof(internalThousandSeparator), + internalLocaleValues->thousands_sep); } if ((internalLocaleValues->grouping) && (internalLocaleValues->grouping[0] != NIL)) { - StrCopyMax(internalGrouping, - sizeof(internalGrouping), - internalLocaleValues->grouping); + trio_copy_max(internalGrouping, + sizeof(internalGrouping), + internalLocaleValues->grouping); } } } #endif /* defined(USE_LOCALE) */ /************************************************************************* - * TrioGetPosition [private] + * TrioGetPosition * * Get the %n$ position. */ -static int -TrioGetPosition(const char *format, +TRIO_PRIVATE int +TrioGetPosition(TRIO_CONST char *format, int *indexPointer) { char *tmpformat; int number = 0; int index = *indexPointer; - number = (int)StrToLong(&format[index], &tmpformat, BASE_DECIMAL); + number = (int)trio_to_long(&format[index], &tmpformat, BASE_DECIMAL); index = (int)(tmpformat - format); if ((number != 0) && (QUALIFIER_POSITION == format[index++])) { @@ -822,15 +864,15 @@ TrioGetPosition(const char *format, } /************************************************************************* - * TrioFindNamespace [private] + * TrioFindNamespace * * Find registered user-defined specifier. - * The prev argument is used for optimization only. + * The prev argument is used for optimisation only. */ -static userdef_T * -TrioFindNamespace(const char *name, userdef_T **prev) +TRIO_PRIVATE trio_userdef_t * +TrioFindNamespace(TRIO_CONST char *name, trio_userdef_t **prev) { - userdef_T *def; + trio_userdef_t *def; if (internalEnterCriticalRegion) (void)internalEnterCriticalRegion(NULL); @@ -838,7 +880,7 @@ TrioFindNamespace(const char *name, userdef_T **prev) for (def = internalUserDef; def; def = def->next) { /* Case-sensitive string comparison */ - if (StrEqualCase(def->name, name)) + if (trio_equal_case(def->name, name)) break; if (prev) @@ -852,17 +894,17 @@ TrioFindNamespace(const char *name, userdef_T **prev) } /************************************************************************* - * TrioPreprocess [private] + * TrioParse * * Description: * Parse the format string */ -static int -TrioPreprocess(int type, - const char *format, - parameter_T *parameters, - va_list arglist, - void **argarray) +TRIO_PRIVATE int +TrioParse(int type, + TRIO_CONST char *format, + trio_parameter_t *parameters, + va_list arglist, + void **argarray) { #if TRIO_ERRORS /* Count the number of times a parameter is referenced */ @@ -890,7 +932,9 @@ TrioPreprocess(int type, int pos = 0; /* Various variables */ char ch; +#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) int charlen; +#endif int i = -1; int num; char *tmpformat; @@ -1020,7 +1064,9 @@ TrioPreprocess(int type, } else { - precision = StrToLong(&format[index], &tmpformat, BASE_DECIMAL); + precision = trio_to_long(&format[index], + &tmpformat, + BASE_DECIMAL); index = (int)(tmpformat - format); } } @@ -1059,7 +1105,9 @@ TrioPreprocess(int type, } else { - base = StrToLong(&format[index], &tmpformat, BASE_DECIMAL); + base = trio_to_long(&format[index], + &tmpformat, + BASE_DECIMAL); if (base > MAX_BASE) return TRIO_ERROR_RETURN(TRIO_EINVAL, index); index = (int)(tmpformat - format); @@ -1120,7 +1168,9 @@ TrioPreprocess(int type, /* &format[index - 1] is used to "rewind" the read * character from format */ - width = StrToLong(&format[index - 1], &tmpformat, BASE_DECIMAL); + width = trio_to_long(&format[index - 1], + &tmpformat, + BASE_DECIMAL); index = (int)(tmpformat - format); break; @@ -1278,6 +1328,7 @@ TrioPreprocess(int type, usedEntries[width] += 1; #endif parameters[pos].type = FORMAT_PARAMETER; + parameters[pos].flags = 0; indices[width] = pos; width = pos++; } @@ -1287,6 +1338,7 @@ TrioPreprocess(int type, usedEntries[precision] += 1; #endif parameters[pos].type = FORMAT_PARAMETER; + parameters[pos].flags = 0; indices[precision] = pos; precision = pos++; } @@ -1296,6 +1348,7 @@ TrioPreprocess(int type, usedEntries[base] += 1; #endif parameters[pos].type = FORMAT_PARAMETER; + parameters[pos].flags = 0; indices[base] = pos; base = pos++; } @@ -1305,6 +1358,7 @@ TrioPreprocess(int type, usedEntries[varsize] += 1; #endif parameters[pos].type = FORMAT_PARAMETER; + parameters[pos].flags = 0; indices[varsize] = pos; varsize = pos++; } @@ -1499,9 +1553,9 @@ TrioPreprocess(int type, max = (unsigned int)(&format[index] - tmpformat); if (max > MAX_USER_DATA) max = MAX_USER_DATA; - StrCopyMax(parameters[pos].user_data, - max, - tmpformat); + trio_copy_max(parameters[pos].user_data, + max, + tmpformat); break; /* while */ } if (ch == SPECIFIER_USER_DEFINED_SEPARATOR) @@ -1511,9 +1565,9 @@ TrioPreprocess(int type, max = (int)(&format[index] - tmpformat); if (max > MAX_USER_NAME) max = MAX_USER_NAME; - StrCopyMax(parameters[pos].user_name, - max, - tmpformat); + trio_copy_max(parameters[pos].user_name, + max, + tmpformat); tmpformat = (char *)&format[index]; } } @@ -1666,8 +1720,8 @@ TrioPreprocess(int type, else { #if defined(QUALIFIER_VARSIZE) || defined(QUALIFIER_FIXED_SIZE) - if ((parameters[i].flags & FLAGS_VARSIZE_PARAMETER) || - (parameters[i].flags & FLAGS_FIXED_SIZE)) + if (parameters[i].flags + & (FLAGS_VARSIZE_PARAMETER | FLAGS_FIXED_SIZE)) { if (parameters[i].flags & FLAGS_VARSIZE_PARAMETER) { @@ -1797,13 +1851,16 @@ TrioPreprocess(int type, else { if (argarray == NULL) - parameters[i].data.longdoubleNumber = (long double)va_arg(arglist, double); + parameters[i].data.longdoubleNumber = + (long double)va_arg(arglist, double); else { if (parameters[i].flags & FLAGS_SHORT) - parameters[i].data.longdoubleNumber = (long double)(*((float *)argarray[num])); + parameters[i].data.longdoubleNumber = + (long double)(*((float *)argarray[num])); else - parameters[i].data.longdoubleNumber = (long double)(long double)(*((double *)argarray[num])); + parameters[i].data.longdoubleNumber = + (long double)(long double)(*((double *)argarray[num])); } } } @@ -1825,22 +1882,22 @@ TrioPreprocess(int type, /************************************************************************* * - * @FORMATTING + * FORMATTING * ************************************************************************/ /************************************************************************* - * TrioWriteNumber [private] + * TrioWriteNumber * * Description: * Output a number. * The complexity of this function is a result of the complexity * of the dependencies of the flags. */ -static void -TrioWriteNumber(trio_T *self, - trio_intmax_t snumber, +TRIO_PRIVATE void +TrioWriteNumber(trio_class_t *self, + trio_uintmax_t number, unsigned long flags, int width, int precision, @@ -1850,8 +1907,7 @@ TrioWriteNumber(trio_T *self, char buffer[MAX_CHARS_IN(trio_uintmax_t) * (1 + MAX_LOCALE_SEPARATOR_LENGTH) + 1]; char *bufferend; char *pointer; - const char *digits; - trio_uintmax_t number; + TRIO_CONST char *digits; int i; int length; char *p; @@ -1861,14 +1917,15 @@ TrioWriteNumber(trio_T *self, assert(VALID(self)); assert(VALID(self->OutStream)); - assert((base >= MIN_BASE && base <= MAX_BASE) || (base == NO_BASE)); + assert(((base >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE)); digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower; isNegative = (flags & FLAGS_UNSIGNED) ? FALSE - : (snumber < 0); - number = (isNegative) ? -snumber : snumber; + : ((trio_intmax_t)number < 0); + if (isNegative) + number = -number; if (flags & FLAGS_QUAD) number &= (trio_ulonglong_t)-1; @@ -1898,7 +1955,7 @@ TrioWriteNumber(trio_T *self, * to the most significant digit, so we have to copy the * thousand separator backwards */ - length = StrLength(internalThousandSeparator); + length = trio_length(internalThousandSeparator); if (((int)(pointer - buffer) - length) > 0) { p = &internalThousandSeparator[length - 1]; @@ -2019,13 +2076,13 @@ TrioWriteNumber(trio_T *self, } /************************************************************************* - * TrioWriteStringCharacter [private] + * TrioWriteStringCharacter * * Description: * Output a single character of a string */ -static void -TrioWriteStringCharacter(trio_T *self, +TRIO_PRIVATE void +TrioWriteStringCharacter(trio_class_t *self, int ch, unsigned long flags) { @@ -2073,14 +2130,14 @@ TrioWriteStringCharacter(trio_T *self, } /************************************************************************* - * TrioWriteString [private] + * TrioWriteString * * Description: * Output a string */ -static void -TrioWriteString(trio_T *self, - const char *string, +TRIO_PRIVATE void +TrioWriteString(trio_class_t *self, + TRIO_CONST char *string, unsigned long flags, int width, int precision) @@ -2093,15 +2150,15 @@ TrioWriteString(trio_T *self, if (string == NULL) { - string = null; - length = sizeof(null) - 1; + string = internalNullString; + length = sizeof(internalNullString) - 1; /* Disable quoting for the null pointer */ flags &= (~FLAGS_QUOTE); width = 0; } else { - length = StrLength(string); + length = trio_length(string); } if ((NO_PRECISION != precision) && (precision < length)) @@ -2136,14 +2193,14 @@ TrioWriteString(trio_T *self, } /************************************************************************* - * TrioWriteWideStringCharacter [private] + * TrioWriteWideStringCharacter * * Description: * Output a wide string as a multi-byte sequence */ #if TRIO_WIDECHAR -static int -TrioWriteWideStringCharacter(trio_T *self, +TRIO_PRIVATE int +TrioWriteWideStringCharacter(trio_class_t *self, wchar_t wch, unsigned long flags, int width) @@ -2174,15 +2231,15 @@ TrioWriteWideStringCharacter(trio_T *self, #endif /* TRIO_WIDECHAR */ /************************************************************************* - * TrioWriteString [private] + * TrioWriteWideString * * Description: * Output a wide character string as a multi-byte string */ #if TRIO_WIDECHAR -static void -TrioWriteWideString(trio_T *self, - const wchar_t *wstring, +TRIO_PRIVATE void +TrioWriteWideString(trio_class_t *self, + TRIO_CONST wchar_t *wstring, unsigned long flags, int width, int precision) @@ -2241,10 +2298,10 @@ TrioWriteWideString(trio_T *self, #endif /* TRIO_WIDECHAR */ /************************************************************************* - * TrioWriteDouble [private] + * TrioWriteDouble */ -static void -TrioWriteDouble(trio_T *self, +TRIO_PRIVATE void +TrioWriteDouble(trio_class_t *self, long double longdoubleNumber, unsigned long flags, int width, @@ -2265,7 +2322,7 @@ TrioWriteDouble(trio_T *self, BOOLEAN_T isNegative; BOOLEAN_T isExponentNegative = FALSE; BOOLEAN_T isHex; - const char *digits; + TRIO_CONST char *digits; char numberBuffer[MAX_MANTISSA_DIGITS * (1 + MAX_LOCALE_SEPARATOR_LENGTH) + 1]; char *numberPointer; @@ -2433,7 +2490,7 @@ TrioWriteDouble(trio_T *self, /* Insert decimal point */ if ((flags & FLAGS_ALTERNATIVE) || ((fractionDigits > 0) && !onlyzero)) { - i = StrLength(internalDecimalPoint); + i = trio_length(internalDecimalPoint); while (i> 0) { *(--numberPointer) = internalDecimalPoint[--i]; @@ -2459,7 +2516,7 @@ TrioWriteDouble(trio_T *self, * to the most significant digit, so we have to copy the * thousand separator backwards */ - length = StrLength(internalThousandSeparator); + length = trio_length(internalThousandSeparator); integerDigits += length; if (((int)(numberPointer - numberBuffer) - length) > 0) { @@ -2504,7 +2561,7 @@ TrioWriteDouble(trio_T *self, * sign + integer part + thousands separators + decimal point * + fraction + exponent */ - expectedWidth = StrLength(numberPointer); + expectedWidth = trio_length(numberPointer); if (isNegative || (flags & FLAGS_SHOWSIGN)) expectedWidth += sizeof("-") - 1; if (exponentDigits > 0) @@ -2588,19 +2645,22 @@ TrioWriteDouble(trio_T *self, } /************************************************************************* - * TrioFormatProcess [private] + * TrioFormatProcess + * + * Description: + * This is the main engine for formatting output */ -static int -TrioFormatProcess(trio_T *data, - const char *format, - parameter_T *parameters) +TRIO_PRIVATE int +TrioFormatProcess(trio_class_t *data, + TRIO_CONST char *format, + trio_parameter_t *parameters) { #if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) int charlen; #endif int i; - const char *string; + TRIO_CONST char *string; void *pointer; unsigned long flags; int width; @@ -2693,9 +2753,11 @@ TrioFormatProcess(trio_T *data, } else #endif - TrioWriteStringCharacter(data, - (int)parameters[i].data.number.as_signed, - flags); + { + TrioWriteStringCharacter(data, + (int)parameters[i].data.number.as_signed, + flags); + } if (flags & FLAGS_LEFTADJUST) { @@ -2752,7 +2814,7 @@ TrioFormatProcess(trio_T *data, case FORMAT_POINTER: { - reference_T reference; + trio_reference_t reference; reference.data = data; reference.parameter = ¶meters[i]; @@ -2808,7 +2870,7 @@ TrioFormatProcess(trio_T *data, #if defined(FORMAT_ERRNO) case FORMAT_ERRNO: - string = StrError(parameters[i].data.errorNumber); + string = trio_error(parameters[i].data.errorNumber); if (string) { TrioWriteString(data, @@ -2833,15 +2895,15 @@ TrioFormatProcess(trio_T *data, #if defined(FORMAT_USER_DEFINED) case FORMAT_USER_DEFINED: { - reference_T reference; - userdef_T *def = NULL; + trio_reference_t reference; + trio_userdef_t *def = NULL; if (parameters[i].user_name[0] == NIL) { /* Use handle */ if ((i > 0) || (parameters[i - 1].type == FORMAT_PARAMETER)) - def = (userdef_T *)parameters[i - 1].data.pointer; + def = (trio_userdef_t *)parameters[i - 1].data.pointer; } else { @@ -2875,41 +2937,43 @@ TrioFormatProcess(trio_T *data, } /************************************************************************* - * TrioFormatRef [private] + * TrioFormatRef */ -static int -TrioFormatRef(reference_T *reference, - const char *format, - va_list arglist, - void **argarray) +TRIO_PRIVATE int +TrioFormatRef(trio_reference_t *reference, + TRIO_CONST char *format, + va_list arglist, + void **argarray) { int status; - parameter_T parameters[MAX_PARAMETERS]; + trio_parameter_t parameters[MAX_PARAMETERS]; - status = TrioPreprocess(TYPE_PRINT, format, parameters, arglist, argarray); + status = TrioParse(TYPE_PRINT, format, parameters, arglist, argarray); if (status < 0) return status; - return TrioFormatProcess(reference->data, format, parameters); + status = TrioFormatProcess(reference->data, format, parameters); + if (reference->data->error != 0) + { + status = reference->data->error; + } + return status; } /************************************************************************* - * TrioFormat [private] - * - * Description: - * This is the main engine for formatting output + * TrioFormat */ -static int +TRIO_PRIVATE int TrioFormat(void *destination, size_t destinationSize, - void (*OutStream)(trio_T *, int), - const char *format, + void (*OutStream)(trio_class_t *, int), + TRIO_CONST char *format, va_list arglist, void **argarray) { int status; - trio_T data; - parameter_T parameters[MAX_PARAMETERS]; + trio_class_t data; + trio_parameter_t parameters[MAX_PARAMETERS]; assert(VALID(OutStream)); assert(VALID(format)); @@ -2918,6 +2982,7 @@ TrioFormat(void *destination, data.OutStream = OutStream; data.location = destination; data.max = destinationSize; + data.error = 0; #if defined(USE_LOCALE) if (NULL == internalLocaleValues) @@ -2926,18 +2991,23 @@ TrioFormat(void *destination, } #endif - status = TrioPreprocess(TYPE_PRINT, format, parameters, arglist, argarray); + status = TrioParse(TYPE_PRINT, format, parameters, arglist, argarray); if (status < 0) return status; - return TrioFormatProcess(&data, format, parameters); + status = TrioFormatProcess(&data, format, parameters); + if (data.error != 0) + { + status = data.error; + } + return status; } /************************************************************************* - * TrioOutStreamFile [private] + * TrioOutStreamFile */ -static void -TrioOutStreamFile(trio_T *self, +TRIO_PRIVATE void +TrioOutStreamFile(trio_class_t *self, int output) { FILE *file = (FILE *)self->location; @@ -2946,15 +3016,21 @@ TrioOutStreamFile(trio_T *self, assert(VALID(file)); self->processed++; - self->committed++; - (void)fputc(output, file); + if (fputc(output, file) == EOF) + { + self->error = TRIO_ERROR_RETURN(TRIO_EOF, 0); + } + else + { + self->committed++; + } } /************************************************************************* - * TrioOutStreamFileDescriptor [private] + * TrioOutStreamFileDescriptor */ -static void -TrioOutStreamFileDescriptor(trio_T *self, +TRIO_PRIVATE void +TrioOutStreamFileDescriptor(trio_class_t *self, int output) { int fd = *((int *)self->location); @@ -2963,16 +3039,22 @@ TrioOutStreamFileDescriptor(trio_T *self, assert(VALID(self)); ch = (char)output; - (void)write(fd, &ch, sizeof(char)); self->processed++; - self->committed++; + if (write(fd, &ch, sizeof(char)) == -1) + { + self->error = TRIO_ERROR_RETURN(TRIO_ERRNO, 0); + } + else + { + self->committed++; + } } /************************************************************************* - * TrioOutStreamString [private] + * TrioOutStreamString */ -static void -TrioOutStreamString(trio_T *self, +TRIO_PRIVATE void +TrioOutStreamString(trio_class_t *self, int output) { char **buffer = (char **)self->location; @@ -2987,10 +3069,10 @@ TrioOutStreamString(trio_T *self, } /************************************************************************* - * TrioOutStreamStringMax [private] + * TrioOutStreamStringMax */ -static void -TrioOutStreamStringMax(trio_T *self, +TRIO_PRIVATE void +TrioOutStreamStringMax(trio_class_t *self, int output) { char **buffer; @@ -3009,63 +3091,51 @@ TrioOutStreamStringMax(trio_T *self, } /************************************************************************* - * TrioOutStreamStringDynamic [private] + * TrioOutStreamStringDynamic */ -#define DYNAMIC_START_SIZE 32 -struct dynamicBuffer { - char *buffer; - size_t length; - size_t allocated; -}; - -static void -TrioOutStreamStringDynamic(trio_T *self, +TRIO_PRIVATE void +TrioOutStreamStringDynamic(trio_class_t *self, int output) { - struct dynamicBuffer *infop; - assert(VALID(self)); assert(VALID(self->location)); - infop = (struct dynamicBuffer *)self->location; - - if (infop->buffer == NULL) - { - /* Start with a reasonable size */ - infop->buffer = (char *)TRIO_MALLOC(DYNAMIC_START_SIZE); - if (infop->buffer == NULL) - return; /* fail */ - - infop->allocated = DYNAMIC_START_SIZE; - self->processed = 0; - self->committed = 0; - } - else if (self->committed + sizeof(NIL) >= infop->allocated) + if (self->error == 0) { - char *newptr; - - /* Allocate increasing chunks */ - newptr = (char *)TRIO_REALLOC(infop->buffer, infop->allocated * 2); - - if (newptr == NULL) - return; - - infop->buffer = newptr; - infop->allocated *= 2; + trio_xstring_append_char((trio_string_t *)self->location, + (char)output); + self->committed++; } - - infop->buffer[self->committed] = (char)output; - self->committed++; + /* The processed variable must always be increased */ self->processed++; - - infop->length = self->committed; } /************************************************************************* + * + * Formatted printing functions + * + ************************************************************************/ + +#if defined(TRIO_DOCUMENTATION) +# include "doc/doc_printf.h" +#endif +/** @addtogroup Printf + @{ +*/ + +/************************************************************************* * printf */ -int -trio_printf(const char *format, + +/** + Print to standard output stream. + + @param format Formatting string. + @param ... Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int +trio_printf(TRIO_CONST char *format, ...) { int status; @@ -3079,8 +3149,15 @@ trio_printf(const char *format, return status; } -int -trio_vprintf(const char *format, +/** + Print to standard output stream. + + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int +trio_vprintf(TRIO_CONST char *format, va_list args) { assert(VALID(format)); @@ -3088,8 +3165,15 @@ trio_vprintf(const char *format, return TrioFormat(stdout, 0, TrioOutStreamFile, format, args, NULL); } -int -trio_printfv(const char *format, +/** + Print to standard output stream. + + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int +trio_printfv(TRIO_CONST char *format, void ** args) { va_list dummy; @@ -3102,9 +3186,18 @@ trio_printfv(const char *format, /************************************************************************* * fprintf */ -int + +/** + Print to file. + + @param file File pointer. + @param format Formatting string. + @param ... Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int trio_fprintf(FILE *file, - const char *format, + TRIO_CONST char *format, ...) { int status; @@ -3119,9 +3212,17 @@ trio_fprintf(FILE *file, return status; } -int +/** + Print to file. + + @param file File pointer. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int trio_vfprintf(FILE *file, - const char *format, + TRIO_CONST char *format, va_list args) { assert(VALID(file)); @@ -3130,9 +3231,17 @@ trio_vfprintf(FILE *file, return TrioFormat(file, 0, TrioOutStreamFile, format, args, NULL); } -int +/** + Print to file. + + @param file File pointer. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int trio_fprintfv(FILE *file, - const char *format, + TRIO_CONST char *format, void ** args) { va_list dummy; @@ -3146,9 +3255,18 @@ trio_fprintfv(FILE *file, /************************************************************************* * dprintf */ -int + +/** + Print to file descriptor. + + @param fd File descriptor. + @param format Formatting string. + @param ... Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int trio_dprintf(int fd, - const char *format, + TRIO_CONST char *format, ...) { int status; @@ -3162,9 +3280,17 @@ trio_dprintf(int fd, return status; } -int +/** + Print to file descriptor. + + @param fd File descriptor. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int trio_vdprintf(int fd, - const char *format, + TRIO_CONST char *format, va_list args) { assert(VALID(format)); @@ -3172,9 +3298,17 @@ trio_vdprintf(int fd, return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, args, NULL); } -int +/** + Print to file descriptor. + + @param fd File descriptor. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int trio_dprintfv(int fd, - const char *format, + TRIO_CONST char *format, void **args) { va_list dummy; @@ -3187,9 +3321,18 @@ trio_dprintfv(int fd, /************************************************************************* * sprintf */ -int + +/** + Print to string. + + @param buffer Output string. + @param format Formatting string. + @param ... Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int trio_sprintf(char *buffer, - const char *format, + TRIO_CONST char *format, ...) { int status; @@ -3205,9 +3348,17 @@ trio_sprintf(char *buffer, return status; } -int +/** + Print to string. + + @param buffer Output string. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int trio_vsprintf(char *buffer, - const char *format, + TRIO_CONST char *format, va_list args) { int status; @@ -3220,9 +3371,17 @@ trio_vsprintf(char *buffer, return status; } -int +/** + Print to string. + + @param buffer Output string. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int trio_sprintfv(char *buffer, - const char *format, + TRIO_CONST char *format, void **args) { int status; @@ -3239,10 +3398,20 @@ trio_sprintfv(char *buffer, /************************************************************************* * snprintf */ -int + +/** + Print at most @p max characters to string. + + @param buffer Output string. + @param max Maximum number of characters to print. + @param format Formatting string. + @param ... Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int trio_snprintf(char *buffer, - size_t bufferSize, - const char *format, + size_t max, + TRIO_CONST char *format, ...) { int status; @@ -3252,18 +3421,27 @@ trio_snprintf(char *buffer, assert(VALID(format)); va_start(args, format); - status = TrioFormat(&buffer, bufferSize > 0 ? bufferSize - 1 : 0, + status = TrioFormat(&buffer, max > 0 ? max - 1 : 0, TrioOutStreamStringMax, format, args, NULL); - if (bufferSize > 0) + if (max > 0) *buffer = NIL; va_end(args); return status; } -int +/** + Print at most @p max characters to string. + + @param buffer Output string. + @param max Maximum number of characters to print. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int trio_vsnprintf(char *buffer, - size_t bufferSize, - const char *format, + size_t max, + TRIO_CONST char *format, va_list args) { int status; @@ -3271,17 +3449,26 @@ trio_vsnprintf(char *buffer, assert(VALID(buffer)); assert(VALID(format)); - status = TrioFormat(&buffer, bufferSize > 0 ? bufferSize - 1 : 0, + status = TrioFormat(&buffer, max > 0 ? max - 1 : 0, TrioOutStreamStringMax, format, args, NULL); - if (bufferSize > 0) + if (max > 0) *buffer = NIL; return status; } -int +/** + Print at most @p max characters to string. + + @param buffer Output string. + @param max Maximum number of characters to print. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int trio_snprintfv(char *buffer, - size_t bufferSize, - const char *format, + size_t max, + TRIO_CONST char *format, void **args) { int status; @@ -3290,9 +3477,9 @@ trio_snprintfv(char *buffer, assert(VALID(buffer)); assert(VALID(format)); - status = TrioFormat(&buffer, bufferSize > 0 ? bufferSize - 1 : 0, + status = TrioFormat(&buffer, max > 0 ? max - 1 : 0, TrioOutStreamStringMax, format, dummy, args); - if (bufferSize > 0) + if (max > 0) *buffer = NIL; return status; } @@ -3302,10 +3489,10 @@ trio_snprintfv(char *buffer, * Appends the new string to the buffer string overwriting the '\0' * character at the end of buffer. */ -int +TRIO_PUBLIC int trio_snprintfcat(char *buffer, - size_t bufferSize, - const char *format, + size_t max, + TRIO_CONST char *format, ...) { int status; @@ -3317,20 +3504,20 @@ trio_snprintfcat(char *buffer, assert(VALID(buffer)); assert(VALID(format)); - buf_len = strlen(buffer); + buf_len = trio_length(buffer); buffer = &buffer[buf_len]; - status = TrioFormat(&buffer, bufferSize - 1 - buf_len, + status = TrioFormat(&buffer, max - 1 - buf_len, TrioOutStreamStringMax, format, args, NULL); va_end(args); *buffer = NIL; return status; } -int +TRIO_PUBLIC int trio_vsnprintfcat(char *buffer, - size_t bufferSize, - const char *format, + size_t max, + TRIO_CONST char *format, va_list args) { int status; @@ -3338,9 +3525,9 @@ trio_vsnprintfcat(char *buffer, assert(VALID(buffer)); assert(VALID(format)); - buf_len = strlen(buffer); + buf_len = trio_length(buffer); buffer = &buffer[buf_len]; - status = TrioFormat(&buffer, bufferSize - 1 - buf_len, + status = TrioFormat(&buffer, max - 1 - buf_len, TrioOutStreamStringMax, format, args, NULL); *buffer = NIL; return status; @@ -3351,141 +3538,152 @@ trio_vsnprintfcat(char *buffer, */ /* Deprecated */ -char * -trio_aprintf(const char *format, +TRIO_PUBLIC char * +trio_aprintf(TRIO_CONST char *format, ...) { va_list args; - struct dynamicBuffer info; + trio_string_t *info; + char *result = NULL; assert(VALID(format)); - info.buffer = NULL; - info.length = 0; - info.allocated = 0; - - va_start(args, format); - (void)TrioFormat(&info, 0, TrioOutStreamStringDynamic, format, args, NULL); - va_end(args); - if (info.length) { - info.buffer[info.length] = NIL; /* we terminate this with a zero byte */ - return info.buffer; - } - else - return NULL; + info = trio_xstring_duplicate(""); + if (info) + { + va_start(args, format); + (void)TrioFormat(info, 0, TrioOutStreamStringDynamic, + format, args, NULL); + va_end(args); + + trio_string_terminate(info); + result = trio_string_extract(info); + trio_string_destroy(info); + } + return result; } /* Deprecated */ -char * -trio_vaprintf(const char *format, +TRIO_PUBLIC char * +trio_vaprintf(TRIO_CONST char *format, va_list args) { - struct dynamicBuffer info; - + trio_string_t *info; + char *result = NULL; + assert(VALID(format)); - info.buffer = NULL; - info.length = 0; - info.allocated = 0; - - (void)TrioFormat(&info, 0, TrioOutStreamStringDynamic, format, args, NULL); - if (info.length) { - info.buffer[info.length] = NIL; /* we terminate this with a zero byte */ - return info.buffer; - } - else - return NULL; + info = trio_xstring_duplicate(""); + if (info) + { + (void)TrioFormat(info, 0, TrioOutStreamStringDynamic, + format, args, NULL); + trio_string_terminate(info); + result = trio_string_extract(info); + trio_string_destroy(info); + } + return result; } -int +TRIO_PUBLIC int trio_asprintf(char **result, - const char *format, + TRIO_CONST char *format, ...) { va_list args; int status; - struct dynamicBuffer info; + trio_string_t *info; assert(VALID(format)); - info.buffer = NULL; - info.length = 0; - info.allocated = 0; - - va_start(args, format); - status = TrioFormat(&info, 0, TrioOutStreamStringDynamic, format, args, NULL); - va_end(args); - if (status < 0) { - *result = NULL; - return status; - } - if (info.length == 0) { - /* - * If the length is zero, no characters have been written and therefore - * no memory has been allocated, but we must to allocate and return an - * empty string. - */ - info.buffer = (char *)TRIO_MALLOC(sizeof(char)); - if (info.buffer == NULL) { - *result = NULL; - return TRIO_ERROR_RETURN(TRIO_ENOMEM, 0); - } - } - info.buffer[info.length] = NIL; /* we terminate this with a zero byte */ - *result = info.buffer; + *result = NULL; + info = trio_xstring_duplicate(""); + if (info == NULL) + { + status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0); + } + else + { + va_start(args, format); + status = TrioFormat(info, 0, TrioOutStreamStringDynamic, + format, args, NULL); + va_end(args); + if (status >= 0) + { + trio_string_terminate(info); + *result = trio_string_extract(info); + } + trio_string_destroy(info); + } return status; } -int +TRIO_PUBLIC int trio_vasprintf(char **result, - const char *format, + TRIO_CONST char *format, va_list args) { int status; - struct dynamicBuffer info; - + trio_string_t *info; + assert(VALID(format)); - info.buffer = NULL; - info.length = 0; - info.allocated = 0; - - status = TrioFormat(&info, 0, TrioOutStreamStringDynamic, format, args, NULL); - if (status < 0) { - *result = NULL; - return status; - } - if (info.length == 0) { - info.buffer = (char *)TRIO_MALLOC(sizeof(char)); - if (info.buffer == NULL) { - *result = NULL; - return TRIO_ERROR_RETURN(TRIO_ENOMEM, 0); - } - } - info.buffer[info.length] = NIL; /* we terminate this with a zero byte */ - *result = info.buffer; + *result = NULL; + info = trio_xstring_duplicate(""); + if (info == NULL) + { + status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0); + } + else + { + status = TrioFormat(info, 0, TrioOutStreamStringDynamic, + format, args, NULL); + if (status >= 0) + { + trio_string_terminate(info); + *result = trio_string_extract(info); + } + trio_string_destroy(info); + } return status; } +/** @} End of Printf documentation module */ /************************************************************************* * - * @CALLBACK + * CALLBACK * ************************************************************************/ +#if defined(TRIO_DOCUMENTATION) +# include "doc/doc_register.h" +#endif +/** + @addtogroup UserDefined + @{ +*/ + /************************************************************************* - * trio_register [public] + * trio_register */ -void * + +/** + Register new user-defined specifier. + + @param callback + @param name + @return Handle. + */ +TRIO_PUBLIC void * trio_register(trio_callback_t callback, - const char *name) + TRIO_CONST char *name) { - userdef_T *def; - userdef_T *prev = NULL; + trio_userdef_t *def; + trio_userdef_t *prev = NULL; if (callback == NULL) return NULL; @@ -3495,11 +3693,11 @@ trio_register(trio_callback_t callback, /* Handle built-in namespaces */ if (name[0] == ':') { - if (StrEqual(name, ":enter")) + if (trio_equal(name, ":enter")) { internalEnterCriticalRegion = callback; } - else if (StrEqual(name, ":leave")) + else if (trio_equal(name, ":leave")) { internalLeaveCriticalRegion = callback; } @@ -3507,7 +3705,7 @@ trio_register(trio_callback_t callback, } /* Bail out if namespace is too long */ - if (StrLength(name) >= MAX_USER_NAME) + if (trio_length(name) >= MAX_USER_NAME) return NULL; /* Bail out if namespace already is registered */ @@ -3516,7 +3714,7 @@ trio_register(trio_callback_t callback, return NULL; } - def = (userdef_T *)TRIO_MALLOC(sizeof(userdef_T)); + def = (trio_userdef_t *)TRIO_MALLOC(sizeof(trio_userdef_t)); if (def) { if (internalEnterCriticalRegion) @@ -3534,7 +3732,7 @@ trio_register(trio_callback_t callback, def->callback = callback; def->name = (name == NULL) ? NULL - : StrDuplicate(name); + : trio_duplicate(name); def->next = NULL; if (internalLeaveCriticalRegion) @@ -3549,9 +3747,9 @@ trio_register(trio_callback_t callback, void trio_unregister(void *handle) { - userdef_T *self = (userdef_T *)handle; - userdef_T *def; - userdef_T *prev = NULL; + trio_userdef_t *self = (trio_userdef_t *)handle; + trio_userdef_t *def; + trio_userdef_t *prev = NULL; assert(VALID(self)); @@ -3571,7 +3769,7 @@ trio_unregister(void *handle) if (internalLeaveCriticalRegion) (void)internalLeaveCriticalRegion(NULL); } - StrFree(self->name); + trio_destroy(self->name); } TRIO_FREE(self); } @@ -3579,12 +3777,12 @@ trio_unregister(void *handle) /************************************************************************* * trio_get_format [public] */ -const char * +TRIO_CONST char * trio_get_format(void *ref) { - assert(((reference_T *)ref)->parameter->type == FORMAT_USER_DEFINED); + assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED); - return (((reference_T *)ref)->parameter->user_data); + return (((trio_reference_t *)ref)->parameter->user_data); } /************************************************************************* @@ -3593,9 +3791,9 @@ trio_get_format(void *ref) void * trio_get_argument(void *ref) { - assert(((reference_T *)ref)->parameter->type == FORMAT_USER_DEFINED); + assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED); - return ((reference_T *)ref)->parameter->data.pointer; + return ((trio_reference_t *)ref)->parameter->data.pointer; } /************************************************************************* @@ -3604,14 +3802,14 @@ trio_get_argument(void *ref) int trio_get_width(void *ref) { - return ((reference_T *)ref)->parameter->width; + return ((trio_reference_t *)ref)->parameter->width; } void trio_set_width(void *ref, int width) { - ((reference_T *)ref)->parameter->width = width; + ((trio_reference_t *)ref)->parameter->width = width; } /************************************************************************* @@ -3620,14 +3818,14 @@ trio_set_width(void *ref, int trio_get_precision(void *ref) { - return (((reference_T *)ref)->parameter->precision); + return (((trio_reference_t *)ref)->parameter->precision); } void trio_set_precision(void *ref, int precision) { - ((reference_T *)ref)->parameter->precision = precision; + ((trio_reference_t *)ref)->parameter->precision = precision; } /************************************************************************* @@ -3636,14 +3834,14 @@ trio_set_precision(void *ref, int trio_get_base(void *ref) { - return (((reference_T *)ref)->parameter->base); + return (((trio_reference_t *)ref)->parameter->base); } void trio_set_base(void *ref, int base) { - ((reference_T *)ref)->parameter->base = base; + ((trio_reference_t *)ref)->parameter->base = base; } /************************************************************************* @@ -3652,7 +3850,7 @@ trio_set_base(void *ref, int trio_get_long(void *ref) { - return (((reference_T *)ref)->parameter->flags & FLAGS_LONG); + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONG); } void @@ -3660,9 +3858,9 @@ trio_set_long(void *ref, int is_long) { if (is_long) - ((reference_T *)ref)->parameter->flags |= FLAGS_LONG; + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LONG; else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_LONG; + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LONG; } /************************************************************************* @@ -3671,7 +3869,7 @@ trio_set_long(void *ref, int trio_get_longlong(void *ref) { - return (((reference_T *)ref)->parameter->flags & FLAGS_QUAD); + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUAD); } void @@ -3679,9 +3877,9 @@ trio_set_longlong(void *ref, int is_longlong) { if (is_longlong) - ((reference_T *)ref)->parameter->flags |= FLAGS_QUAD; + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_QUAD; else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_QUAD; + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_QUAD; } /************************************************************************* @@ -3690,7 +3888,7 @@ trio_set_longlong(void *ref, int trio_get_longdouble(void *ref) { - return (((reference_T *)ref)->parameter->flags & FLAGS_LONGDOUBLE); + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONGDOUBLE); } void @@ -3698,9 +3896,9 @@ trio_set_longdouble(void *ref, int is_longdouble) { if (is_longdouble) - ((reference_T *)ref)->parameter->flags |= FLAGS_LONGDOUBLE; + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LONGDOUBLE; else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_LONGDOUBLE; + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LONGDOUBLE; } /************************************************************************* @@ -3709,7 +3907,7 @@ trio_set_longdouble(void *ref, int trio_get_short(void *ref) { - return (((reference_T *)ref)->parameter->flags & FLAGS_SHORT); + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORT); } void @@ -3717,9 +3915,9 @@ trio_set_short(void *ref, int is_short) { if (is_short) - ((reference_T *)ref)->parameter->flags |= FLAGS_SHORT; + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHORT; else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_SHORT; + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHORT; } /************************************************************************* @@ -3728,7 +3926,7 @@ trio_set_short(void *ref, int trio_get_shortshort(void *ref) { - return (((reference_T *)ref)->parameter->flags & FLAGS_SHORTSHORT); + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORTSHORT); } void @@ -3736,9 +3934,9 @@ trio_set_shortshort(void *ref, int is_shortshort) { if (is_shortshort) - ((reference_T *)ref)->parameter->flags |= FLAGS_SHORTSHORT; + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHORTSHORT; else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_SHORTSHORT; + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHORTSHORT; } /************************************************************************* @@ -3747,7 +3945,7 @@ trio_set_shortshort(void *ref, int trio_get_alternative(void *ref) { - return (((reference_T *)ref)->parameter->flags & FLAGS_ALTERNATIVE); + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_ALTERNATIVE); } void @@ -3755,9 +3953,9 @@ trio_set_alternative(void *ref, int is_alternative) { if (is_alternative) - ((reference_T *)ref)->parameter->flags |= FLAGS_ALTERNATIVE; + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_ALTERNATIVE; else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_ALTERNATIVE; + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_ALTERNATIVE; } /************************************************************************* @@ -3766,7 +3964,7 @@ trio_set_alternative(void *ref, int trio_get_alignment(void *ref) { - return (((reference_T *)ref)->parameter->flags & FLAGS_LEFTADJUST); + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LEFTADJUST); } void @@ -3774,9 +3972,9 @@ trio_set_alignment(void *ref, int is_leftaligned) { if (is_leftaligned) - ((reference_T *)ref)->parameter->flags |= FLAGS_LEFTADJUST; + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LEFTADJUST; else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_LEFTADJUST; + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LEFTADJUST; } /************************************************************************* @@ -3785,7 +3983,7 @@ trio_set_alignment(void *ref, int trio_get_spacing(void *ref) { - return (((reference_T *)ref)->parameter->flags & FLAGS_SPACE); + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SPACE); } void @@ -3793,9 +3991,9 @@ trio_set_spacing(void *ref, int is_space) { if (is_space) - ((reference_T *)ref)->parameter->flags |= FLAGS_SPACE; + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SPACE; else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_SPACE; + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SPACE; } /************************************************************************* @@ -3804,7 +4002,7 @@ trio_set_spacing(void *ref, int trio_get_sign(void *ref) { - return (((reference_T *)ref)->parameter->flags & FLAGS_SHOWSIGN); + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHOWSIGN); } void @@ -3812,9 +4010,9 @@ trio_set_sign(void *ref, int is_sign) { if (is_sign) - ((reference_T *)ref)->parameter->flags |= FLAGS_SHOWSIGN; + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHOWSIGN; else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_SHOWSIGN; + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHOWSIGN; } /************************************************************************* @@ -3823,7 +4021,7 @@ trio_set_sign(void *ref, int trio_get_padding(void *ref) { - return (((reference_T *)ref)->parameter->flags & FLAGS_NILPADDING); + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_NILPADDING); } void @@ -3831,9 +4029,9 @@ trio_set_padding(void *ref, int is_padding) { if (is_padding) - ((reference_T *)ref)->parameter->flags |= FLAGS_NILPADDING; + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_NILPADDING; else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_NILPADDING; + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_NILPADDING; } /************************************************************************* @@ -3842,7 +4040,7 @@ trio_set_padding(void *ref, int trio_get_quote(void *ref) { - return (((reference_T *)ref)->parameter->flags & FLAGS_QUOTE); + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUOTE); } void @@ -3850,9 +4048,9 @@ trio_set_quote(void *ref, int is_quote) { if (is_quote) - ((reference_T *)ref)->parameter->flags |= FLAGS_QUOTE; + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_QUOTE; else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_QUOTE; + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_QUOTE; } /************************************************************************* @@ -3861,7 +4059,7 @@ trio_set_quote(void *ref, int trio_get_upper(void *ref) { - return (((reference_T *)ref)->parameter->flags & FLAGS_UPPER); + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_UPPER); } void @@ -3869,9 +4067,9 @@ trio_set_upper(void *ref, int is_upper) { if (is_upper) - ((reference_T *)ref)->parameter->flags |= FLAGS_UPPER; + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_UPPER; else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_UPPER; + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_UPPER; } /************************************************************************* @@ -3881,7 +4079,7 @@ trio_set_upper(void *ref, int trio_get_largest(void *ref) { - return (((reference_T *)ref)->parameter->flags & FLAGS_INTMAX_T); + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_INTMAX_T); } void @@ -3889,9 +4087,9 @@ trio_set_largest(void *ref, int is_largest) { if (is_largest) - ((reference_T *)ref)->parameter->flags |= FLAGS_INTMAX_T; + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_INTMAX_T; else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_INTMAX_T; + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_INTMAX_T; } #endif @@ -3901,7 +4099,7 @@ trio_set_largest(void *ref, int trio_get_ptrdiff(void *ref) { - return (((reference_T *)ref)->parameter->flags & FLAGS_PTRDIFF_T); + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_PTRDIFF_T); } void @@ -3909,9 +4107,9 @@ trio_set_ptrdiff(void *ref, int is_ptrdiff) { if (is_ptrdiff) - ((reference_T *)ref)->parameter->flags |= FLAGS_PTRDIFF_T; + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_PTRDIFF_T; else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_PTRDIFF_T; + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_PTRDIFF_T; } /************************************************************************* @@ -3921,7 +4119,7 @@ trio_set_ptrdiff(void *ref, int trio_get_size(void *ref) { - return (((reference_T *)ref)->parameter->flags & FLAGS_SIZE_T); + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SIZE_T); } void @@ -3929,9 +4127,9 @@ trio_set_size(void *ref, int is_size) { if (is_size) - ((reference_T *)ref)->parameter->flags |= FLAGS_SIZE_T; + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SIZE_T; else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_SIZE_T; + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SIZE_T; } #endif @@ -3942,7 +4140,7 @@ void trio_print_int(void *ref, int number) { - reference_T *self = (reference_T *)ref; + trio_reference_t *self = (trio_reference_t *)ref; TrioWriteNumber(self->data, (trio_intmax_t)number, @@ -3959,7 +4157,7 @@ void trio_print_uint(void *ref, unsigned int number) { - reference_T *self = (reference_T *)ref; + trio_reference_t *self = (trio_reference_t *)ref; TrioWriteNumber(self->data, (trio_intmax_t)number, @@ -3976,7 +4174,7 @@ void trio_print_double(void *ref, double number) { - reference_T *self = (reference_T *)ref; + trio_reference_t *self = (trio_reference_t *)ref; TrioWriteDouble(self->data, number, @@ -3993,7 +4191,7 @@ void trio_print_string(void *ref, char *string) { - reference_T *self = (reference_T *)ref; + trio_reference_t *self = (trio_reference_t *)ref; TrioWriteString(self->data, string, @@ -4009,13 +4207,13 @@ void trio_print_pointer(void *ref, void *pointer) { - reference_T *self = (reference_T *)ref; + trio_reference_t *self = (trio_reference_t *)ref; unsigned long flags; trio_uintmax_t number; if (NULL == pointer) { - const char *string = null; + TRIO_CONST char *string = internalNullString; while (*string) self->data->OutStream(self->data, *string++); } @@ -4025,7 +4223,7 @@ trio_print_pointer(void *ref, * The subtraction of the null pointer is a workaround * to avoid a compiler warning. The performance overhead * is negligible (and likely to be removed by an - * optimizing compiler). The (char *) casting is done + * optimising compiler). The (char *) casting is done * to please ANSI C++. */ number = (trio_uintmax_t)((char *)pointer - (char *)0); @@ -4048,7 +4246,7 @@ trio_print_pointer(void *ref, */ int trio_print_ref(void *ref, - const char *format, + TRIO_CONST char *format, ...) { int status; @@ -4057,7 +4255,7 @@ trio_print_ref(void *ref, assert(VALID(format)); va_start(arglist, format); - status = TrioFormatRef((reference_T *)ref, format, arglist, NULL); + status = TrioFormatRef((trio_reference_t *)ref, format, arglist, NULL); va_end(arglist); return status; } @@ -4067,12 +4265,12 @@ trio_print_ref(void *ref, */ int trio_vprint_ref(void *ref, - const char *format, + TRIO_CONST char *format, va_list arglist) { assert(VALID(format)); - return TrioFormatRef((reference_T *)ref, format, arglist, NULL); + return TrioFormatRef((trio_reference_t *)ref, format, arglist, NULL); } /************************************************************************* @@ -4080,29 +4278,30 @@ trio_vprint_ref(void *ref, */ int trio_printv_ref(void *ref, - const char *format, + TRIO_CONST char *format, void **argarray) { va_list dummy; assert(VALID(format)); - return TrioFormatRef((reference_T *)ref, format, dummy, argarray); + return TrioFormatRef((trio_reference_t *)ref, format, dummy, argarray); } +/** @} End of UserDefined documentation module */ /************************************************************************* * - * @SCANNING + * SCANNING * ************************************************************************/ /************************************************************************* - * TrioSkipWhitespaces [private] + * TrioSkipWhitespaces */ -static int -TrioSkipWhitespaces(trio_T *self) +TRIO_PRIVATE int +TrioSkipWhitespaces(trio_class_t *self) { int ch; @@ -4115,11 +4314,11 @@ TrioSkipWhitespaces(trio_T *self) } /************************************************************************* - * TrioGetCollation [private] + * TrioGetCollation */ #if TRIO_EXTENSION -static void -TrioGetCollation() +TRIO_PRIVATE void +TrioGetCollation(void) { int i; int j; @@ -4137,7 +4336,7 @@ TrioGetCollation() for (j = 0; j < MAX_CHARACTER_CLASS; j++) { second[0] = (char)j; - if (StrEqualLocale(first, second)) + if (trio_equal_locale(first, second)) internalCollationArray[i][k++] = (char)j; } internalCollationArray[i][k] = NIL; @@ -4146,13 +4345,13 @@ TrioGetCollation() #endif /************************************************************************* - * TrioGetCharacterClass [private] + * TrioGetCharacterClass * * FIXME: * multibyte */ -static int -TrioGetCharacterClass(const char *format, +TRIO_PRIVATE int +TrioGetCharacterClass(TRIO_CONST char *format, int *indexPointer, unsigned long *flagsPointer, int *characterclass) @@ -4264,7 +4463,7 @@ TrioGetCharacterClass(const char *format, if (internalCollationUnconverted) { - /* Lazy evaluation of collation array */ + /* Lazy evalutation of collation array */ TrioGetCollation(); internalCollationUnconverted = FALSE; } @@ -4292,88 +4491,88 @@ TrioGetCharacterClass(const char *format, case QUALIFIER_COLON: /* Character class expressions */ - if (StrEqualMax(CLASS_ALNUM, sizeof(CLASS_ALNUM) - 1, - &format[index])) + if (trio_equal_max(CLASS_ALNUM, sizeof(CLASS_ALNUM) - 1, + &format[index])) { for (i = 0; i < MAX_CHARACTER_CLASS; i++) if (isalnum(i)) characterclass[i]++; index += sizeof(CLASS_ALNUM) - 1; } - else if (StrEqualMax(CLASS_ALPHA, sizeof(CLASS_ALPHA) - 1, - &format[index])) + else if (trio_equal_max(CLASS_ALPHA, sizeof(CLASS_ALPHA) - 1, + &format[index])) { for (i = 0; i < MAX_CHARACTER_CLASS; i++) if (isalpha(i)) characterclass[i]++; index += sizeof(CLASS_ALPHA) - 1; } - else if (StrEqualMax(CLASS_CNTRL, sizeof(CLASS_CNTRL) - 1, - &format[index])) + else if (trio_equal_max(CLASS_CNTRL, sizeof(CLASS_CNTRL) - 1, + &format[index])) { for (i = 0; i < MAX_CHARACTER_CLASS; i++) if (iscntrl(i)) characterclass[i]++; index += sizeof(CLASS_CNTRL) - 1; } - else if (StrEqualMax(CLASS_DIGIT, sizeof(CLASS_DIGIT) - 1, - &format[index])) + else if (trio_equal_max(CLASS_DIGIT, sizeof(CLASS_DIGIT) - 1, + &format[index])) { for (i = 0; i < MAX_CHARACTER_CLASS; i++) if (isdigit(i)) characterclass[i]++; index += sizeof(CLASS_DIGIT) - 1; } - else if (StrEqualMax(CLASS_GRAPH, sizeof(CLASS_GRAPH) - 1, - &format[index])) + else if (trio_equal_max(CLASS_GRAPH, sizeof(CLASS_GRAPH) - 1, + &format[index])) { for (i = 0; i < MAX_CHARACTER_CLASS; i++) if (isgraph(i)) characterclass[i]++; index += sizeof(CLASS_GRAPH) - 1; } - else if (StrEqualMax(CLASS_LOWER, sizeof(CLASS_LOWER) - 1, - &format[index])) + else if (trio_equal_max(CLASS_LOWER, sizeof(CLASS_LOWER) - 1, + &format[index])) { for (i = 0; i < MAX_CHARACTER_CLASS; i++) if (islower(i)) characterclass[i]++; index += sizeof(CLASS_LOWER) - 1; } - else if (StrEqualMax(CLASS_PRINT, sizeof(CLASS_PRINT) - 1, - &format[index])) + else if (trio_equal_max(CLASS_PRINT, sizeof(CLASS_PRINT) - 1, + &format[index])) { for (i = 0; i < MAX_CHARACTER_CLASS; i++) if (isprint(i)) characterclass[i]++; index += sizeof(CLASS_PRINT) - 1; } - else if (StrEqualMax(CLASS_PUNCT, sizeof(CLASS_PUNCT) - 1, - &format[index])) + else if (trio_equal_max(CLASS_PUNCT, sizeof(CLASS_PUNCT) - 1, + &format[index])) { for (i = 0; i < MAX_CHARACTER_CLASS; i++) if (ispunct(i)) characterclass[i]++; index += sizeof(CLASS_PUNCT) - 1; } - else if (StrEqualMax(CLASS_SPACE, sizeof(CLASS_SPACE) - 1, - &format[index])) + else if (trio_equal_max(CLASS_SPACE, sizeof(CLASS_SPACE) - 1, + &format[index])) { for (i = 0; i < MAX_CHARACTER_CLASS; i++) if (isspace(i)) characterclass[i]++; index += sizeof(CLASS_SPACE) - 1; } - else if (StrEqualMax(CLASS_UPPER, sizeof(CLASS_UPPER) - 1, - &format[index])) + else if (trio_equal_max(CLASS_UPPER, sizeof(CLASS_UPPER) - 1, + &format[index])) { for (i = 0; i < MAX_CHARACTER_CLASS; i++) if (isupper(i)) characterclass[i]++; index += sizeof(CLASS_UPPER) - 1; } - else if (StrEqualMax(CLASS_XDIGIT, sizeof(CLASS_XDIGIT) - 1, - &format[index])) + else if (trio_equal_max(CLASS_XDIGIT, sizeof(CLASS_XDIGIT) - 1, + &format[index])) { for (i = 0; i < MAX_CHARACTER_CLASS; i++) if (isxdigit(i)) @@ -4403,13 +4602,13 @@ TrioGetCharacterClass(const char *format, } /************************************************************************* - * TrioReadNumber [private] + * TrioReadNumber * * We implement our own number conversion in preference of strtol and * strtoul, because we must handle 'long long' and thousand separators. */ -static BOOLEAN_T -TrioReadNumber(trio_T *self, +TRIO_PRIVATE BOOLEAN_T +TrioReadNumber(trio_class_t *self, trio_uintmax_t *target, unsigned long flags, int width, @@ -4532,10 +4731,10 @@ TrioReadNumber(trio_T *self, } /************************************************************************* - * TrioReadChar [private] + * TrioReadChar */ -static int -TrioReadChar(trio_T *self, +TRIO_PRIVATE int +TrioReadChar(trio_class_t *self, char *target, unsigned long flags, int width) @@ -4596,10 +4795,10 @@ TrioReadChar(trio_T *self, } /************************************************************************* - * TrioReadString [private] + * TrioReadString */ -static BOOLEAN_T -TrioReadString(trio_T *self, +TRIO_PRIVATE BOOLEAN_T +TrioReadString(trio_class_t *self, char *target, unsigned long flags, int width) @@ -4629,11 +4828,11 @@ TrioReadString(trio_T *self, } /************************************************************************* - * TrioReadWideChar [private] + * TrioReadWideChar */ #if TRIO_WIDECHAR -static int -TrioReadWideChar(trio_T *self, +TRIO_PRIVATE int +TrioReadWideChar(trio_class_t *self, wchar_t *target, unsigned long flags, int width) @@ -4688,11 +4887,11 @@ TrioReadWideChar(trio_T *self, #endif /* TRIO_WIDECHAR */ /************************************************************************* - * TrioReadWideString [private] + * TrioReadWideString */ #if TRIO_WIDECHAR -static BOOLEAN_T -TrioReadWideString(trio_T *self, +TRIO_PRIVATE BOOLEAN_T +TrioReadWideString(trio_class_t *self, wchar_t *target, unsigned long flags, int width) @@ -4725,18 +4924,18 @@ TrioReadWideString(trio_T *self, i += size; } if (target) - target[i] = L'\0'; + target[i] = WCONST('\0'); return TRUE; } #endif /* TRIO_WIDECHAR */ /************************************************************************* - * TrioReadGroup [private] + * TrioReadGroup * * FIXME: characterclass does not work with multibyte characters */ -static BOOLEAN_T -TrioReadGroup(trio_T *self, +TRIO_PRIVATE BOOLEAN_T +TrioReadGroup(trio_class_t *self, char *target, int *characterclass, unsigned long flags, @@ -4766,13 +4965,13 @@ TrioReadGroup(trio_T *self, } /************************************************************************* - * TrioReadDouble [private] + * TrioReadDouble * * FIXME: * add long double */ -static BOOLEAN_T -TrioReadDouble(trio_T *self, +TRIO_PRIVATE BOOLEAN_T +TrioReadDouble(trio_class_t *self, double *target, unsigned long flags, int width) @@ -4790,8 +4989,8 @@ TrioReadDouble(trio_T *self, TrioSkipWhitespaces(self); /* - * Read entire double number from stream. StrToDouble requires a - * string as input, but InStream can be anything, so we have to + * Read entire double number from stream. trio_to_double requires + * a string as input, but InStream can be anything, so we have to * collect all characters. */ ch = self->current; @@ -4822,17 +5021,17 @@ TrioReadDouble(trio_T *self, doubleString[index] = NIL; /* Case insensitive string comparison */ - if (StrEqual(&doubleString[start], INFINITE_UPPER) || - StrEqual(&doubleString[start], LONG_INFINITE_UPPER)) + if (trio_equal(&doubleString[start], INFINITE_UPPER) || + trio_equal(&doubleString[start], LONG_INFINITE_UPPER)) { *target = ((start == 1 && doubleString[0] == '-')) ? trio_ninf() : trio_pinf(); return TRUE; } - if (StrEqual(doubleString, NAN_LOWER)) + if (trio_equal(doubleString, NAN_UPPER)) { - /* NaN must not have a preceding + nor - */ + /* NaN must not have a preceeding + nor - */ *target = trio_nan(); return TRUE; } @@ -4913,25 +5112,25 @@ TrioReadDouble(trio_T *self, return FALSE; if (flags & FLAGS_LONGDOUBLE) -/* *longdoublePointer = StrToLongDouble()*/ +/* *longdoublePointer = trio_to_long_double()*/ return FALSE; /* FIXME: Remove when long double is implemented */ else { - *target = StrToDouble(doubleString, NULL); + *target = trio_to_double(doubleString, NULL); } return TRUE; } /************************************************************************* - * TrioReadPointer [private] + * TrioReadPointer */ -static BOOLEAN_T -TrioReadPointer(trio_T *self, +TRIO_PRIVATE BOOLEAN_T +TrioReadPointer(trio_class_t *self, void **target, unsigned long flags) { trio_uintmax_t number; - char buffer[sizeof(null)]; + char buffer[sizeof(internalNullString)]; flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE | FLAGS_NILPADDING); @@ -4954,9 +5153,9 @@ TrioReadPointer(trio_T *self, ? NULL : buffer, 0, - sizeof(null) - 1)) + sizeof(internalNullString) - 1)) { - if (StrEqualCase(buffer, null)) + if (trio_equal_case(buffer, internalNullString)) { if (target) *target = NULL; @@ -4967,26 +5166,19 @@ TrioReadPointer(trio_T *self, } /************************************************************************* - * TrioScan [private] + * TrioScanProcess */ -static int -TrioScan(const void *source, - size_t sourceSize, - void (*InStream)(trio_T *, int *), - const char *format, - va_list arglist, - void **argarray) +TRIO_PRIVATE int +TrioScanProcess(trio_class_t *data, + TRIO_CONST char *format, + trio_parameter_t *parameters) { #if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) int charlen; + int cnt; #endif - int status; int assignment; - parameter_T parameters[MAX_PARAMETERS]; - trio_T internalData; - trio_T *data; int ch; - int cnt; int index; /* Index of format string */ int i; /* Index of current parameter */ unsigned long flags; @@ -4994,26 +5186,6 @@ TrioScan(const void *source, int base; void *pointer; - assert(VALID(InStream)); - assert(VALID(format)); - - memset(&internalData, 0, sizeof(internalData)); - data = &internalData; - data->InStream = InStream; - data->location = (void *)source; - data->max = sourceSize; - -#if defined(USE_LOCALE) - if (NULL == internalLocaleValues) - { - TrioSetLocale(); - } -#endif - - status = TrioPreprocess(TYPE_SCAN, format, parameters, arglist, argarray); - if (status < 0) - return status; - assignment = 0; i = 0; index = 0; @@ -5292,7 +5464,7 @@ TrioScan(const void *source, data->InStream(data, &ch); } else - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); + return assignment; index++; } @@ -5301,10 +5473,53 @@ TrioScan(const void *source, } /************************************************************************* - * TrioInStreamFile [private] + * TrioScan + */ +TRIO_PRIVATE int +TrioScan(TRIO_CONST void *source, + size_t sourceSize, + void (*InStream)(trio_class_t *, int *), + TRIO_CONST char *format, + va_list arglist, + void **argarray) +{ + int status; + trio_parameter_t parameters[MAX_PARAMETERS]; + trio_class_t data; + + assert(VALID(InStream)); + assert(VALID(format)); + + memset(&data, 0, sizeof(data)); + data.InStream = InStream; + data.location = (void *)source; + data.max = sourceSize; + data.error = 0; + +#if defined(USE_LOCALE) + if (NULL == internalLocaleValues) + { + TrioSetLocale(); + } +#endif + + status = TrioParse(TYPE_SCAN, format, parameters, arglist, argarray); + if (status < 0) + return status; + + status = TrioScanProcess(&data, format, parameters); + if (data.error != 0) + { + status = data.error; + } + return status; +} + +/************************************************************************* + * TrioInStreamFile */ -static void -TrioInStreamFile(trio_T *self, +TRIO_PRIVATE void +TrioInStreamFile(trio_class_t *self, int *intPointer) { FILE *file = (FILE *)self->location; @@ -5313,6 +5528,12 @@ TrioInStreamFile(trio_T *self, assert(VALID(file)); self->current = fgetc(file); + if (self->current == EOF) + { + self->error = (ferror(file)) + ? TRIO_ERROR_RETURN(TRIO_ERRNO, 0) + : TRIO_ERROR_RETURN(TRIO_EOF, 0); + } self->processed++; self->committed++; @@ -5323,10 +5544,10 @@ TrioInStreamFile(trio_T *self, } /************************************************************************* - * TrioInStreamFileDescriptor [private] + * TrioInStreamFileDescriptor */ -static void -TrioInStreamFileDescriptor(trio_T *self, +TRIO_PRIVATE void +TrioInStreamFileDescriptor(trio_class_t *self, int *intPointer) { int fd = *((int *)self->location); @@ -5336,9 +5557,17 @@ TrioInStreamFileDescriptor(trio_T *self, assert(VALID(self)); size = read(fd, &input, sizeof(char)); - self->current = (size == 0) ? EOF : input; - self->processed++; + if (size == -1) + { + self->error = TRIO_ERROR_RETURN(TRIO_ERRNO, 0); + self->current = EOF; + } + else + { + self->current = (size == 0) ? EOF : input; + } self->committed++; + self->processed++; if (VALID(intPointer)) { @@ -5347,10 +5576,10 @@ TrioInStreamFileDescriptor(trio_T *self, } /************************************************************************* - * TrioInStreamString [private] + * TrioInStreamString */ -static void -TrioInStreamString(trio_T *self, +TRIO_PRIVATE void +TrioInStreamString(trio_class_t *self, int *intPointer) { unsigned char **buffer; @@ -5374,10 +5603,31 @@ TrioInStreamString(trio_T *self, } /************************************************************************* + * + * Formatted scanning functions + * + ************************************************************************/ + +#if defined(TRIO_DOCUMENTATION) +# include "doc/doc_scanf.h" +#endif +/** @addtogroup Scanf + @{ +*/ + +/************************************************************************* * scanf */ -int -trio_scanf(const char *format, + +/** + Scan characters from standard input stream. + + @param format Formatting string. + @param ... Arguments. + @return Number of scanned characters. + */ +TRIO_PUBLIC int +trio_scanf(TRIO_CONST char *format, ...) { int status; @@ -5391,8 +5641,8 @@ trio_scanf(const char *format, return status; } -int -trio_vscanf(const char *format, +TRIO_PUBLIC int +trio_vscanf(TRIO_CONST char *format, va_list args) { assert(VALID(format)); @@ -5400,8 +5650,8 @@ trio_vscanf(const char *format, return TrioScan(stdin, 0, TrioInStreamFile, format, args, NULL); } -int -trio_scanfv(const char *format, +TRIO_PUBLIC int +trio_scanfv(TRIO_CONST char *format, void **args) { va_list dummy; @@ -5414,9 +5664,9 @@ trio_scanfv(const char *format, /************************************************************************* * fscanf */ -int +TRIO_PUBLIC int trio_fscanf(FILE *file, - const char *format, + TRIO_CONST char *format, ...) { int status; @@ -5431,9 +5681,9 @@ trio_fscanf(FILE *file, return status; } -int +TRIO_PUBLIC int trio_vfscanf(FILE *file, - const char *format, + TRIO_CONST char *format, va_list args) { assert(VALID(file)); @@ -5442,9 +5692,9 @@ trio_vfscanf(FILE *file, return TrioScan(file, 0, TrioInStreamFile, format, args, NULL); } -int +TRIO_PUBLIC int trio_fscanfv(FILE *file, - const char *format, + TRIO_CONST char *format, void **args) { va_list dummy; @@ -5458,9 +5708,9 @@ trio_fscanfv(FILE *file, /************************************************************************* * dscanf */ -int +TRIO_PUBLIC int trio_dscanf(int fd, - const char *format, + TRIO_CONST char *format, ...) { int status; @@ -5474,9 +5724,9 @@ trio_dscanf(int fd, return status; } -int +TRIO_PUBLIC int trio_vdscanf(int fd, - const char *format, + TRIO_CONST char *format, va_list args) { assert(VALID(format)); @@ -5484,9 +5734,9 @@ trio_vdscanf(int fd, return TrioScan(&fd, 0, TrioInStreamFileDescriptor, format, args, NULL); } -int +TRIO_PUBLIC int trio_dscanfv(int fd, - const char *format, + TRIO_CONST char *format, void **args) { va_list dummy; @@ -5499,9 +5749,9 @@ trio_dscanfv(int fd, /************************************************************************* * sscanf */ -int -trio_sscanf(const char *buffer, - const char *format, +TRIO_PUBLIC int +trio_sscanf(TRIO_CONST char *buffer, + TRIO_CONST char *format, ...) { int status; @@ -5516,9 +5766,9 @@ trio_sscanf(const char *buffer, return status; } -int -trio_vsscanf(const char *buffer, - const char *format, +TRIO_PUBLIC int +trio_vsscanf(TRIO_CONST char *buffer, + TRIO_CONST char *format, va_list args) { assert(VALID(buffer)); @@ -5527,9 +5777,9 @@ trio_vsscanf(const char *buffer, return TrioScan(&buffer, 0, TrioInStreamString, format, args, NULL); } -int -trio_sscanfv(const char *buffer, - const char *format, +TRIO_PUBLIC int +trio_sscanfv(TRIO_CONST char *buffer, + TRIO_CONST char *format, void **args) { va_list dummy; @@ -5540,3 +5790,4 @@ trio_sscanfv(const char *buffer, return TrioScan(&buffer, 0, TrioInStreamString, format, dummy, args); } +/** @} End of Scanf documentation module */ @@ -13,6 +13,10 @@ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. * + ************************************************************************* + * + * http://ctrio.sourceforge.net/ + * ************************************************************************/ #ifndef TRIO_TRIO_H @@ -41,6 +45,11 @@ extern "C" { # define isascii ((unsigned)(x) < 0x80) #endif +/* Error macros */ +#define TRIO_ERROR_CODE(x) ((-(x)) & 0x00FF) +#define TRIO_ERROR_POSITION(x) ((-(x)) >> 8) +#define TRIO_ERROR_NAME(x) trio_strerror(x) + /* * Error codes. * @@ -53,14 +62,10 @@ enum { TRIO_EDBLREF = 4, TRIO_EGAP = 5, TRIO_ENOMEM = 6, - TRIO_ERANGE = 7 + TRIO_ERANGE = 7, + TRIO_ERRNO = 8 }; -/* Error macros */ -#define TRIO_ERROR_CODE(x) ((-(x)) & 0x00FF) -#define TRIO_ERROR_POSITION(x) ((-(x)) >> 8) -#define TRIO_ERROR_NAME(x) trio_strerror(x) - const char *trio_strerror(int); /************************************************************************* @@ -183,13 +188,6 @@ int trio_sscanfv(const char *buffer, const char *format, void **args); #define vdscanf trio_vdscanf #endif -/* strio compatible names */ -#define StrScan trio_sscanf -#define StrFormat trio_sprintf -#define StrFormatMax trio_snprintf -#define StrFormatAlloc trio_aprintf -#define StrFormatAppendMax trio_snprintfcat - #ifdef __cplusplus } /* extern "C" */ #endif @@ -15,8 +15,8 @@ * ************************************************************************/ -#ifndef __TRIO_TRIODEF_H__ -#define __TRIO_TRIODEF_H__ +#ifndef TRIO_TRIODEF_H +#define TRIO_TRIODEF_H /************************************************************************* * Platform and compiler support detection @@ -48,12 +48,17 @@ # define TRIO_PLATFORM_UNIX #elif defined(__QNX__) # define TRIO_PLATFORM_UNIX +# define TRIO_PLATFORM_QNX #elif defined(__CYGWIN__) # define TRIO_PLATFORM_UNIX #elif defined(AMIGA) && defined(TRIO_COMPILER_GCC) # define TRIO_PLATFORM_UNIX #elif defined(TRIO_COMPILER_MSVC) || defined(WIN32) || defined(_WIN32) # define TRIO_PLATFORM_WIN32 +#elif defined(VMS) || defined(__VMS) +# define TRIO_PLATFORM_VMS +#elif defined(mpeix) || defined(__mpexl) +# define TRIO_PLATFORM_MPEIX #endif #if defined(__STDC__) @@ -81,4 +86,35 @@ # endif #endif -#endif /* __TRIO_TRIODEF_H__ */ +/************************************************************************* + * Generic defines + */ + +#if !defined(TRIO_PUBLIC) +# define TRIO_PUBLIC +#endif +#if !defined(TRIO_PRIVATE) +# define TRIO_PRIVATE static +#endif + +#if defined(TRIO_COMPILER_SUPPORTS_C90) || defined(__cplusplus) +# define TRIO_CONST const +# define TRIO_VOLATILE volatile +# define TRIO_POINTER void * +# define TRIO_PROTO(x) x +#else +# define TRIO_CONST +# define TRIO_VOLATILE +# define TRIO_POINTER char * +# define TRIO_PROTO(x) () +#endif + +#if defined(TRIO_COMPILER_SUPPORTS_C99) || defined(__cplusplus) +# define TRIO_INLINE inline +#elif defined(TRIO_COMPILER_GCC) +# define TRIO_INLINE __inline__ +#else +# define TRIO_INLINE +#endif + +#endif /* TRIO_TRIODEF_H */ @@ -50,6 +50,7 @@ * NetBSD 1.4 x86 gcc * NetBSD 1.4 StrongARM gcc * NetBSD 1.5 Alpha gcc + * OpenVMS 7.1 Alpha DEC C 6.0 * RISC OS 4 StrongARM Norcroft C * Solaris 2.5.1 x86 gcc * Solaris 2.5.1 Sparc gcc @@ -63,7 +64,6 @@ static const char rcsid[] = "@(#)$Id$"; - /************************************************************************* * Include files */ @@ -77,15 +77,17 @@ static const char rcsid[] = "@(#)$Id$"; #if defined(TRIO_PLATFORM_UNIX) # include <signal.h> #endif +#if defined(TRIO_COMPILER_DECC) +# include <fp_class.h> +#endif #include <assert.h> -#ifdef __STDC__ -# define CONST const -# define VOLATILE volatile -#else -# define CONST -# define VOLATILE +#if defined(TRIO_DOCUMENTATION) +# include "doc/doc_nan.h" #endif +/** @addtogroup SpecialQuantities + @{ +*/ /************************************************************************* * Definitions @@ -94,7 +96,11 @@ static const char rcsid[] = "@(#)$Id$"; /* We must enable IEEE floating-point on Alpha */ #if defined(__alpha) && !defined(_IEEE_FP) # if defined(TRIO_COMPILER_DECC) -# error "Must be compiled with option -ieee" +# if defined(TRIO_PLATFORM_VMS) +# error "Must be compiled with option /IEEE_MODE=UNDERFLOW_TO_ZERO/FLOAT=IEEE" +# else +# error "Must be compiled with option -ieee" +# endif # elif defined(TRIO_COMPILER_GCC) && (defined(__osf__) || defined(__linux__)) # error "Must be compiled with option -mieee" # endif @@ -128,57 +134,61 @@ static const char rcsid[] = "@(#)$Id$"; * Endian-agnostic indexing macro. * * The value of internalEndianMagic, when converted into a 64-bit - * integer, becomes 0x0001020304050607 (we could have used a 64-bit + * integer, becomes 0x0706050403020100 (we could have used a 64-bit * integer value instead of a double, but not all platforms supports * that type). The value is automatically encoded with the correct * endianess by the compiler, which means that we can support any * kind of endianess. The individual bytes are then used as an index * for the IEEE 754 bit-patterns and masks. */ -#define TRIO_DOUBLE_INDEX(x) (((unsigned char *)&internalEndianMagic)[(x)]) +#define TRIO_DOUBLE_INDEX(x) (((unsigned char *)&internalEndianMagic)[7-(x)]) -static CONST double internalEndianMagic = 1.4015997730788920e-309; +static TRIO_CONST double internalEndianMagic = 7.949928895127363e-275; /* Mask for the exponent */ -static CONST unsigned char ieee_754_exponent_mask[] = { +static TRIO_CONST unsigned char ieee_754_exponent_mask[] = { 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /* Mask for the mantissa */ -static CONST unsigned char ieee_754_mantissa_mask[] = { +static TRIO_CONST unsigned char ieee_754_mantissa_mask[] = { 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; /* Bit-pattern for infinity */ -static CONST unsigned char ieee_754_infinity_array[] = { +static TRIO_CONST unsigned char ieee_754_infinity_array[] = { 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /* Bit-pattern for quiet NaN */ -static CONST unsigned char ieee_754_qnan_array[] = { +static TRIO_CONST unsigned char ieee_754_qnan_array[] = { 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /************************************************************************* + * Functions + */ + +/* * trio_make_double */ -static double -trio_make_double(CONST unsigned char *values) +TRIO_PRIVATE double +trio_make_double(TRIO_CONST unsigned char *values) { - VOLATILE double result; + TRIO_VOLATILE double result; int i; for (i = 0; i < (int)sizeof(double); i++) { - ((VOLATILE unsigned char *)&result)[TRIO_DOUBLE_INDEX(i)] = values[i]; + ((TRIO_VOLATILE unsigned char *)&result)[TRIO_DOUBLE_INDEX(i)] = values[i]; } return result; } -/************************************************************************* +/* * trio_examine_double */ -static int +TRIO_PRIVATE int trio_is_special_quantity(double number, int *has_mantissa) { @@ -200,9 +210,11 @@ trio_is_special_quantity(double number, #endif /* USE_IEEE_754 */ -/************************************************************************* - * trio_pinf - */ +/** + Generate positive infinity. + + @return Floating-point representation of positive infinity. +*/ TRIO_PUBLIC double trio_pinf(void) { @@ -242,9 +254,11 @@ trio_pinf(void) return result; } -/************************************************************************* - * trio_ninf - */ +/** + Generate negative infinity. + + @return Floating-point value of negative infinity. +*/ TRIO_PUBLIC double trio_ninf(void) { @@ -261,9 +275,11 @@ trio_ninf(void) return result; } -/************************************************************************* - * trio_nan - */ +/** + Generate NaN. + + @return Floating-point representation of NaN. +*/ TRIO_PUBLIC double trio_nan(void) { @@ -306,11 +322,14 @@ trio_nan(void) return result; } -/************************************************************************* - * trio_isnan - */ +/** + Check for NaN. + + @param number An arbitrary floating-point number. + @return Boolean value indicating whether or not the number is a NaN. +*/ TRIO_PUBLIC int -trio_isnan(VOLATILE double number) +trio_isnan(TRIO_VOLATILE double number) { #if defined(isnan) || defined(TRIO_COMPILER_SUPPORTS_UNIX95) /* @@ -370,11 +389,14 @@ trio_isnan(VOLATILE double number) #endif } -/************************************************************************* - * trio_isinf - */ +/** + Check for infinity. + + @param number An arbitrary floating-point number. + @return 1 if positive infinity, -1 if negative infinity, 0 otherwise. +*/ TRIO_PUBLIC int -trio_isinf(VOLATILE double number) +trio_isinf(TRIO_VOLATILE double number) { #if defined(TRIO_COMPILER_DECC) /* @@ -438,7 +460,15 @@ trio_isinf(VOLATILE double number) #endif } +/** @} SpecialQuantities */ + /************************************************************************* + * For test purposes. + * + * Add the following compiler option to include this test code. + * + * Unix : -DSTANDALONE + * VMS : /DEFINE=(STANDALONE) */ #if defined(STANDALONE) # include <stdio.h> @@ -15,50 +15,42 @@ * ************************************************************************/ -#ifndef __TRIO_NAN_H__ -#define __TRIO_NAN_H__ +#ifndef TRIO_NAN_H +#define TRIO_NAN_H + +#include "triodef.h" #ifdef __cplusplus extern "C" { #endif - -#ifndef TRIO_PUBLIC -#define TRIO_PUBLIC -#endif - /* * Return NaN (Not-a-Number). */ -TRIO_PUBLIC -double trio_nan(void); +TRIO_PUBLIC double trio_nan(void); /* * Return positive infinity. */ -TRIO_PUBLIC -double trio_pinf(void); +TRIO_PUBLIC double trio_pinf(void); /* * Return negative infinity. */ -TRIO_PUBLIC -double trio_ninf(void); +TRIO_PUBLIC double trio_ninf(void); /* * If number is a NaN return non-zero, otherwise return zero. */ -TRIO_PUBLIC -int trio_isnan(double number); +TRIO_PUBLIC int trio_isnan(double number); /* * If number is positive infinity return 1, if number is negative * infinity return -1, otherwise return 0. */ -TRIO_PUBLIC -int trio_isinf(double number); +TRIO_PUBLIC int trio_isinf(double number); #ifdef __cplusplus } #endif -#endif /* __TRIO_NAN_H__ */ +#endif /* TRIO_NAN_H */ @@ -27,6 +27,7 @@ #define TRIO_TRIOP_H #include <stdlib.h> +#include <stdarg.h> #ifdef __cplusplus extern "C" { @@ -53,7 +54,7 @@ extern "C" { #ifndef TRIO_EXTENSION # define TRIO_EXTENSION 1 #endif -#ifndef TRIO_WIDECHAR +#ifndef TRIO_WIDECHAR /* Does not work yet. Do not enable */ # define TRIO_WIDECHAR 0 #endif #ifndef TRIO_ERRORS @@ -70,7 +71,11 @@ extern "C" { # define TRIO_FREE(x) free(x) #endif -typedef int (*trio_callback_t)(void *ref); +/************************************************************************* + * User-defined specifiers + */ + +typedef int (*trio_callback_t)(void *); void *trio_register(trio_callback_t callback, const char *name); void trio_unregister(void *handle); diff --git a/triostr.c b/triostr.c new file mode 100644 index 00000000..760be55c --- /dev/null +++ b/triostr.c @@ -0,0 +1,1753 @@ +/************************************************************************* + * + * $Id$ + * + * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. + * + ************************************************************************/ + +static const char rcsid[] = "@(#)$Id$"; + +/************************************************************************* + * Include files + */ + +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <math.h> +#include "triostr.h" + +/************************************************************************* + * Definitions + */ + +#ifndef NULL +# define NULL 0 +#endif +#define NIL ((char)0) +#ifndef FALSE +# define FALSE (1 == 0) +# define TRUE (! FALSE) +#endif +#define BOOLEAN_T int + +#if defined(TRIO_COMPILER_SUPPORTS_C99) +# define USE_STRTOD +# define USE_STRTOF +#elif defined(TRIO_COMPILER_MSVC) +# define USE_STRTOD +#endif + +#if defined(TRIO_PLATFORM_UNIX) +# define USE_STRCASECMP +# define USE_STRNCASECMP +# define USE_STRERROR +# if defined(TRIO_PLATFORM_QNX) +# define strcasecmp(x,y) stricmp(x,y) +# define strncasecmp(x,y,n) strnicmp(x,y,n) +# endif +#elif defined(TRIO_PLATFORM_WIN32) +# define USE_STRCASECMP +# define strcasecmp(x,y) strcmpi(x,y) +#endif + +/************************************************************************* + * Structures + */ + +struct _trio_string_t +{ + char *content; + size_t length; + size_t allocated; +}; + +/************************************************************************* + * Static String Functions + */ + +#if defined(TRIO_DOCUMENTATION) +# include "doc/doc_static.h" +#endif +/** @addtogroup StaticStrings + @{ +*/ + +/** + Create new string. + + @param size Size of new string. + @return Pointer to string, or NULL if allocation failed. +*/ +TRIO_PUBLIC TRIO_INLINE char * +trio_create(size_t size) +{ + return (char *)TRIO_MALLOC(size); +} + + +/** + Destroy string. + + @param string String to be freed. +*/ +TRIO_PUBLIC TRIO_INLINE void +trio_destroy(char *string) +{ + if (string) + { + TRIO_FREE(string); + } +} + + +/** + Count the number of characters in a string. + + @param string String to measure. + @return Number of characters in @string. +*/ +TRIO_PUBLIC TRIO_INLINE size_t +trio_length(const char *string) +{ + return strlen(string); +} + + +/* + * TrioDuplicateMax + */ +TRIO_PRIVATE char * +TrioDuplicateMax(const char *source, size_t size) +{ + char *target; + + assert(source); + + /* Make room for string plus a terminating zero */ + size++; + target = trio_create(size); + if (target) + { + trio_copy_max(target, size, source); + } + return target; +} + + +/** + Append @p source at the end of @p target. + + @param target Target string. + @param source Source string. + @return Boolean value indicating success or failure. + + @pre @p target must point to a memory chunk with sufficient room to + contain the @p target string and @p source string. + @pre No boundary checking is performed, so insufficient memory will + result in a buffer overrun. + @post @p target will be zero terminated. +*/ +TRIO_PUBLIC int +trio_append(char *target, + const char *source) +{ + assert(target); + assert(source); + + return (strcat(target, source) != NULL); +} + + +/** + Append at most @p max characters from @p source to @p target. + + @param target Target string. + @param max Maximum number of characters to append. + @param source Source string. + @return Boolean value indicating success or failure. + + @pre @p target must point to a memory chuck with sufficient room to + contain the @p target string and the @p source string (at most @p max + characters). + @pre No boundary checking is performed, so insufficient memory will + result in a buffer overrun. + @post @p target will be zero terminated. +*/ +TRIO_PUBLIC int +trio_append_max(char *target, + size_t max, + const char *source) +{ + size_t length; + + assert(target); + assert(source); + + length = trio_length(target); + + if (max > length) + { + strncat(target, source, max - length - 1); + } + return TRUE; +} + + +/** + Determine if a string contains a substring. + + @param string String to be searched. + @param substring String to be found. + @return Boolean value indicating success or failure. +*/ +TRIO_PUBLIC TRIO_INLINE int +trio_contains(const char *string, + const char *substring) +{ + assert(string); + assert(substring); + + return (0 != strstr(string, substring)); +} + + +/** + Copy @p source to @p target. + + @param target Target string. + @param source Source string. + @return Boolean value indicating success or failure. + + @pre @p target must point to a memory chunk with sufficient room to + contain the @p source string. + @pre No boundary checking is performed, so insufficient memory will + result in a buffer overrun. + @post @p target will be zero terminated. +*/ +TRIO_PUBLIC int +trio_copy(char *target, + const char *source) +{ + assert(target); + assert(source); + + (void)strcpy(target, source); + return TRUE; +} + + +/** + Copy at most @p max characters from @p source to @p target. + + @param target Target string. + @param max Maximum number of characters to append. + @param source Source string. + @return Boolean value indicating success or failure. + + @pre @p target must point to a memory chunk with sufficient room to + contain the @p source string (at most @p max characters). + @pre No boundary checking is performed, so insufficient memory will + result in a buffer overrun. + @post @p target will be zero terminated. +*/ +TRIO_PUBLIC int +trio_copy_max(char *target, + size_t max, + const char *source) +{ + assert(target); + assert(source); + assert(max > 0); /* Includes != 0 */ + + (void)strncpy(target, source, max - 1); + target[max - 1] = (char)0; + return TRUE; +} + + +/** + Duplicate @p source. + + @param source Source string. + @return A copy of the @p source string. + + @post @p target will be zero terminated. +*/ +TRIO_PUBLIC char * +trio_duplicate(const char *source) +{ + return TrioDuplicateMax(source, trio_length(source)); +} + + +/** + Duplicate at most @p max characters of @p source. + + @param source Source string. + @param max Maximum number of characters to duplicate. + @return A copy of the @p source string. + + @post @p target will be zero terminated. +*/ +TRIO_PUBLIC char * +trio_duplicate_max(const char *source, + size_t max) +{ + size_t length; + + assert(source); + assert(max > 0); + + length = trio_length(source); + if (length > max) + { + length = max; + } + return TrioDuplicateMax(source, length); +} + + +/** + Compare if two strings are equal. + + @param first First string. + @param second Second string. + @return Boolean indicating whether the two strings are equal or not. + + Case-insensitive comparison. +*/ +TRIO_PUBLIC int +trio_equal(const char *first, + const char *second) +{ + assert(first); + assert(second); + + if ((first != NULL) && (second != NULL)) + { +#if defined(USE_STRCASECMP) + return (0 == strcasecmp(first, second)); +#else + while ((*first != NIL) && (*second != NIL)) + { + if (toupper(*first) != toupper(*second)) + { + break; + } + first++; + second++; + } + return ((*first == NIL) && (*second == NIL)); +#endif + } + return FALSE; +} + + +/** + Compare if two strings are equal. + + @param first First string. + @param second Second string. + @return Boolean indicating whether the two strings are equal or not. + + Case-sensitive comparison. +*/ +TRIO_PUBLIC int +trio_equal_case(const char *first, + const char *second) +{ + assert(first); + assert(second); + + if ((first != NULL) && (second != NULL)) + { + return (0 == strcmp(first, second)); + } + return FALSE; +} + + +/** + Compare if two strings up until the first @p max characters are equal. + + @param first First string. + @param max Maximum number of characters to compare. + @param second Second string. + @return Boolean indicating whether the two strings are equal or not. + + Case-sensitive comparison. +*/ +TRIO_PUBLIC int +trio_equal_case_max(const char *first, + size_t max, + const char *second) +{ + assert(first); + assert(second); + + if ((first != NULL) && (second != NULL)) + { + return (0 == strncmp(first, second, max)); + } + return FALSE; +} + + +/** + Compare if two strings are equal. + + @param first First string. + @param second Second string. + @return Boolean indicating whether the two strings are equal or not. + + Collating characters are considered equal. +*/ +TRIO_PUBLIC int +trio_equal_locale(const char *first, + const char *second) +{ + assert(first); + assert(second); + +#if defined(LC_COLLATE) + return (strcoll(first, second) == 0); +#else + return trio_equal(first, second); +#endif +} + + +/** + Compare if two strings up until the first @p max characters are equal. + + @param first First string. + @param max Maximum number of characters to compare. + @param second Second string. + @return Boolean indicating whether the two strings are equal or not. + + Case-insensitive comparison. +*/ +TRIO_PUBLIC int +trio_equal_max(const char *first, + size_t max, + const char *second) +{ + assert(first); + assert(second); + + if ((first != NULL) && (second != NULL)) + { +#if defined(USE_STRNCASECMP) + return (0 == strncasecmp(first, second, max)); +#else + /* Not adequately tested yet */ + size_t cnt = 0; + while ((*first != NIL) && (*second != NIL) && (cnt <= max)) + { + if (toupper(*first) != toupper(*second)) + { + break; + } + first++; + second++; + cnt++; + } + return ((cnt == max) || ((*first == NIL) && (*second == NIL))); +#endif + } + return FALSE; +} + + +/** + Provide a textual description of an error code (errno). + + @param error_number Error number. + @return Textual description of @p error_number. +*/ +TRIO_PUBLIC const char * +trio_error(int error_number) +{ +#if defined(USE_STRERROR) + return strerror(error_number); +#else + return "unknown"; +#endif +} + + +/** + Format the date/time according to @p format. + + @param target Target string. + @param max Maximum number of characters to format. + @param format Formatting string. + @param datetime Date/time structure. + @return Number of formatted characters. + + The formatting string accepts the same specifiers as the standard C + function strftime. +*/ +TRIO_PUBLIC size_t +trio_format_date_max(char *target, + size_t max, + const char *format, + const struct tm *datetime) +{ + assert(target); + assert(format); + assert(datetime); + assert(max > 0); + + return strftime(target, max, format, datetime); +} + + +/** + Calculate a hash value for a string. + + @param string String to be calculated on. + @param type Hash function. + @return Calculated hash value. + + @p type can be one of the following + @li @c TRIO_HASH_PLAIN Plain hash function. +*/ +TRIO_PUBLIC unsigned long +trio_hash(const char *string, + int type) +{ + unsigned long value = 0L; + char ch; + + assert(string); + + switch (type) + { + case TRIO_HASH_PLAIN: + while ( (ch = *string++) != NIL ) + { + value *= 31; + value += (unsigned long)ch; + } + break; + default: + assert(FALSE); + break; + } + return value; +} + + +/** + Find first occurrence of a character in a string. + + @param string String to be searched. + @param character Character to be found. + @param A pointer to the found character, or NULL if character was not found. + */ +TRIO_PUBLIC TRIO_INLINE char * +trio_index(const char *string, + char character) +{ + assert(string); + + return strchr(string, character); +} + + +/** + Find last occurrence of a character in a string. + + @param string String to be searched. + @param character Character to be found. + @param A pointer to the found character, or NULL if character was not found. + */ +TRIO_PUBLIC TRIO_INLINE char * +trio_index_last(const char *string, + char character) +{ + assert(string); + + return strchr(string, character); +} + + +/** + Convert the alphabetic letters in the string to lower-case. + + @param target String to be converted. + @return Number of processed characters (converted or not). +*/ +TRIO_PUBLIC TRIO_INLINE int +trio_lower(char *target) +{ + assert(target); + + return trio_span_function(target, target, tolower); +} + + +/** + Compare two strings using wildcards. + + @param string String to be searched. + @param pattern Pattern, including wildcards, to search for. + @return Boolean value indicating success or failure. + + Case-insensitive comparison. + + The following wildcards can be used + @li @c * Match any number of characters. + @li @c ? Match a single character. +*/ +TRIO_PUBLIC int +trio_match(const char *string, + const char *pattern) +{ + assert(string); + assert(pattern); + + for (; ('*' != *pattern); ++pattern, ++string) + { + if (NIL == *string) + { + return (NIL == *pattern); + } + if ((toupper((int)*string) != toupper((int)*pattern)) + && ('?' != *pattern)) + { + return FALSE; + } + } + /* two-line patch to prevent *too* much recursiveness: */ + while ('*' == pattern[1]) + pattern++; + + do + { + if ( trio_match(string, &pattern[1]) ) + { + return TRUE; + } + } + while (*string++); + + return FALSE; +} + + +/** + Compare two strings using wildcards. + + @param string String to be searched. + @param pattern Pattern, including wildcards, to search for. + @return Boolean value indicating success or failure. + + Case-sensitive comparison. + + The following wildcards can be used + @li @c * Match any number of characters. + @li @c ? Match a single character. +*/ +TRIO_PUBLIC int +trio_match_case(const char *string, + const char *pattern) +{ + assert(string); + assert(pattern); + + for (; ('*' != *pattern); ++pattern, ++string) + { + if (NIL == *string) + { + return (NIL == *pattern); + } + if ((*string != *pattern) + && ('?' != *pattern)) + { + return FALSE; + } + } + /* two-line patch to prevent *too* much recursiveness: */ + while ('*' == pattern[1]) + pattern++; + + do + { + if ( trio_match_case(string, &pattern[1]) ) + { + return TRUE; + } + } + while (*string++); + + return FALSE; +} + + +/** + Execute a function on each character in string. + + @param target Target string. + @param source Source string. + @param Function Function to be executed. + @return Number of processed characters. +*/ +TRIO_PUBLIC size_t +trio_span_function(char *target, + const char *source, + int (*Function)(int)) +{ + size_t count = 0; + + assert(target); + assert(source); + assert(Function); + + while (*source != NIL) + { + *target++ = Function(*source++); + count++; + } + return count; +} + + +/** + Search for a substring in a string. + + @param string String to be searched. + @param substring String to be found. + @return Pointer to first occurrence of @p substring in @p string, or NULL + if no match was found. +*/ +TRIO_PUBLIC TRIO_INLINE char * +trio_substring(const char *string, + const char *substring) +{ + assert(string); + assert(substring); + + return strstr(string, substring); +} + + +/** + Search for a substring in the first @p max characters of a string. + + @param string String to be searched. + @param max Maximum characters to be searched. + @param substring String to be found. + @return Pointer to first occurrence of @p substring in @p string, or NULL + if no match was found. +*/ +TRIO_PUBLIC char * +trio_substring_max(const char *string, + size_t max, + const char *substring) +{ + size_t count; + size_t size; + char *result = NULL; + + assert(string); + assert(substring); + + size = trio_length(substring); + if (size <= max) + { + for (count = 0; count <= max - size; count++) + { + if (trio_equal_max(substring, size, &string[count])) + { + result = (char *)&string[count]; + break; + } + } + } + return result; +} + + +/** + Tokenize string. + + @param string String to be tokenized. + @param tokens String containing list of delimiting characters. + @return Start of new token. + + @warning @p string will be destroyed. +*/ +TRIO_PUBLIC TRIO_INLINE char * +trio_tokenize(char *string, const char *delimiters) +{ + assert(delimiters); + + return strtok(string, delimiters); +} + + +/** + Convert string to floating-point number. + + @param source String to be converted. + @param endp Pointer to end of the converted string. + @return A floating-point number. + + The following Extended Backus-Naur form is used + @verbatim + double ::= [ <sign> ] + ( <number> | + <number> <decimal_point> <number> | + <decimal_point> <number> ) + [ <exponential> [ <sign> ] <number> ] + number ::= 1*( <digit> ) + digit ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' ) + exponential ::= ( 'e' | 'E' ) + sign ::= ( '-' | '+' ) + decimal_point ::= '.' + @endverbatim +*/ +/* FIXME: Add EBNF for hex-floats */ +TRIO_PUBLIC double +trio_to_double(const char *source, + const char **endp) +{ +#if defined(USE_STRTOD) + return strtod(source, (char **)endp); +#else + /* Preliminary code */ + int isNegative = FALSE; + int isExponentNegative = FALSE; + unsigned long integer = 0; + unsigned long fraction = 0; + unsigned long fracdiv = 1; + unsigned long exponent = 0; + double value = 0.0; + + /* First try hex-floats */ + if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X'))) + { + source += 2; + while (isxdigit((int)*source)) + { + integer *= 16; + integer += (isdigit((int)*source) + ? (*source - '0') + : 10 + (toupper((int)*source) - 'A')); + source++; + } + if (*source == '.') + { + source++; + while (isxdigit((int)*source)) + { + fraction *= 16; + fraction += (isdigit((int)*source) + ? (*source - '0') + : 10 + (toupper((int)*source) - 'A')); + fracdiv *= 16; + source++; + } + if ((*source == 'p') || (*source == 'P')) + { + source++; + if ((*source == '+') || (*source == '-')) + { + isExponentNegative = (*source == '-'); + source++; + } + while (isdigit((int)*source)) + { + exponent *= 10; + exponent += (*source - '0'); + source++; + } + } + } + } + else /* Then try normal decimal floats */ + { + isNegative = (*source == '-'); + /* Skip sign */ + if ((*source == '+') || (*source == '-')) + source++; + + /* Integer part */ + while (isdigit((int)*source)) + { + integer *= 10; + integer += (*source - '0'); + source++; + } + + if (*source == '.') + { + source++; /* skip decimal point */ + while (isdigit((int)*source)) + { + fraction *= 10; + fraction += (*source - '0'); + fracdiv *= 10; + source++; + } + } + if ((*source == 'e') + || (*source == 'E') +#if TRIO_MICROSOFT + || (*source == 'd') + || (*source == 'D') +#endif + ) + { + source++; /* Skip exponential indicator */ + isExponentNegative = (*source == '-'); + if ((*source == '+') || (*source == '-')) + source++; + while (isdigit((int)*source)) + { + exponent *= 10; + exponent += (*source - '0'); + source++; + } + } + } + + value = (double)integer; + if (fraction != 0) + { + value += (double)fraction / (double)fracdiv; + } + if (exponent != 0) + { + if (isExponentNegative) + value /= pow((double)10, (double)exponent); + else + value *= pow((double)10, (double)exponent); + } + if (isNegative) + value = -value; + + if (endp) + *endp = source; + return value; +#endif +} + + +/** + Convert string to floating-point number. + + @param source String to be converted. + @param endp Pointer to end of the converted string. + @return A floating-point number. + + See @ref trio_to_double. +*/ +TRIO_PUBLIC TRIO_INLINE float +trio_to_float(const char *source, + const char **endp) +{ +#if defined(USE_STRTOF) + return strtof(source, (char **)endp); +#else + return (float)trio_to_double(source, endp); +#endif +} + + +/** + Convert string to signed integer. + + @param string String to be converted. + @param endp Pointer to end of converted string. + @param base Radix number of number. +*/ +TRIO_PUBLIC TRIO_INLINE long +trio_to_long(const char *string, + char **endp, + int base) +{ + assert(string); + assert((base >= 2) && (base <= 36)); + + return strtol(string, endp, base); +} + + +/** + Convert string to unsigned integer. + + @param string String to be converted. + @param endp Pointer to end of converted string. + @param base Radix number of number. +*/ +TRIO_PUBLIC TRIO_INLINE unsigned long +trio_to_unsigned_long(const char *string, + char **endp, + int base) +{ + assert(string); + assert((base >= 2) && (base <= 36)); + + return strtoul(string, endp, base); +} + + +/** + Convert the alphabetic letters in the string to upper-case. + + @param target The string to be converted. + @return The number of processed characters (converted or not). +*/ +TRIO_PUBLIC TRIO_INLINE int +trio_upper(char *target) +{ + assert(target); + + return trio_span_function(target, target, toupper); +} + + +/** @} End of StaticStrings */ + + +/************************************************************************* + * Dynamic String Functions + */ + +#if defined(TRIO_DOCUMENTATION) +# include "doc/doc_dynamic.h" +#endif +/** @addtogroup DynamicStrings + @{ +*/ + +/* + * TrioStringAlloc + */ +TRIO_PRIVATE trio_string_t * +TrioStringAlloc(void) +{ + trio_string_t *self; + + self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t)); + if (self) + { + self->content = NULL; + self->length = 0; + self->allocated = 0; + } + return self; +} + + +/* + * TrioStringGrow + * + * The size of the string will be increased by 'delta' characters. If + * 'delta' is zero, the size will be doubled. + */ +TRIO_PRIVATE BOOLEAN_T +TrioStringGrow(trio_string_t *self, + size_t delta) +{ + BOOLEAN_T status = FALSE; + char *new_content; + size_t new_size; + + new_size = (delta == 0) + ? ( (self->allocated == 0) ? 1 : self->allocated * 2 ) + : self->allocated + delta; + + new_content = (char *)TRIO_REALLOC(self->content, new_size); + if (new_content) + { + self->content = new_content; + self->allocated = new_size; + status = TRUE; + } + return status; +} + + +/* + * TrioStringGrowTo + * + * The size of the string will be increased to 'length' plus one characters. + * If 'length' is less than the original size, the original size will be + * used (that is, the size of the string is never decreased). + */ +TRIO_PRIVATE BOOLEAN_T +TrioStringGrowTo(trio_string_t *self, + size_t length) +{ + length++; /* Room for terminating zero */ + return (self->allocated < length) + ? TrioStringGrow(self, length - self->allocated) + : TRUE; +} + + +/** + Create a new dynamic string. + + @param initial_size Initial size of the buffer. + @return Newly allocated dynamic string, or NULL if memory allocation failed. +*/ +TRIO_PUBLIC trio_string_t * +trio_string_create(int initial_size) +{ + trio_string_t *self; + + self = TrioStringAlloc(); + if (self) + { + if (TrioStringGrow(self, + (size_t)((initial_size > 0) ? initial_size : 1))) + { + self->content[0] = (char)0; + self->allocated = initial_size; + } + else + { + trio_string_destroy(self); + self = NULL; + } + } + return self; +} + + +/** + Deallocate the dynamic string and its contents. + + @param self Dynamic string +*/ +TRIO_PUBLIC void +trio_string_destroy(trio_string_t *self) +{ + assert(self); + + if (self) + { + trio_destroy(self->content); + TRIO_FREE(self); + } +} + + +/** + Get a pointer to the content. + + @param self Dynamic string. + @param offset Offset into content. + @return Pointer to the content. + + @p Offset can be zero, positive, or negative. If @p offset is zero, + then the start of the content will be returned. If @p offset is positive, + then a pointer to @p offset number of characters from the beginning of the + content is returned. If @p offset is negative, then a pointer to @p offset + number of characters from the ending of the string, starting at the + terminating zero, is returned. +*/ +TRIO_PUBLIC char * +trio_string_get(trio_string_t *self, int offset) +{ + char *result = NULL; + + assert(self); + + if (self->content != NULL) + { + if (self->length == 0) + { + (void)trio_string_length(self); + } + if (offset >= 0) + { + if (offset > self->length) + { + offset = self->length; + } + } + else + { + offset += self->length + 1; + if (offset < 0) + { + offset = 0; + } + } + result = &(self->content[offset]); + } + return result; +} + + +/** + Extract the content. + + @param self Dynamic String + @return Content of dynamic string. + + The content is removed from the dynamic string. This enables destruction + of the dynamic string without deallocation of the content. +*/ +TRIO_PUBLIC char * +trio_string_extract(trio_string_t *self) +{ + char *result; + + assert(self); + + result = self->content; + /* FIXME: Allocate new empty buffer? */ + self->content = NULL; + self->length = self->allocated = 0; + return result; +} + + +/** + Set the content of the dynamic string. + + @param self Dynamic String + @param buffer The new content. + + Sets the content of the dynamic string to a copy @p buffer. + An existing content will be deallocated first, if necessary. + + @remark + This function will make a copy of @p buffer. + You are responsible for deallocating @p buffer yourself. +*/ +TRIO_PUBLIC void +trio_xstring_set(trio_string_t *self, + char *buffer) +{ + assert(self); + + trio_destroy(self->content); + self->content = trio_duplicate(buffer); +} + + +/* + * trio_string_size + */ +TRIO_PUBLIC int +trio_string_size(trio_string_t *self) +{ + assert(self); + + return self->allocated; +} + + +/* + * trio_string_terminate + */ +TRIO_PUBLIC void +trio_string_terminate(trio_string_t *self) +{ + char *end; + + assert(self); + + end = trio_string_get(self, -1); + if (end) + { + *end = NIL; + } +} + + +/** + Append the second string to the first. + + @param self Dynamic string to be modified. + @param other Dynamic string to copy from. + @return Boolean value indicating success or failure. +*/ +TRIO_PUBLIC int +trio_string_append(trio_string_t *self, + trio_string_t *other) +{ + size_t length; + + assert(self); + assert(other); + + length = self->length + other->length; + if (!TrioStringGrowTo(self, length)) + goto error; + trio_copy(&self->content[self->length], other->content); + self->length = length; + return TRUE; + + error: + return FALSE; +} + + +/* + * trio_xstring_append + */ +TRIO_PUBLIC int +trio_xstring_append(trio_string_t *self, + const char *other) +{ + size_t length; + + assert(self); + assert(other); + + length = self->length + trio_length(other); + if (!TrioStringGrowTo(self, length)) + goto error; + trio_copy(&self->content[self->length], other); + self->length = length; + return TRUE; + + error: + return FALSE; +} + + +/* + * trio_xstring_append_char + */ +TRIO_PUBLIC int +trio_xstring_append_char(trio_string_t *self, + char character) +{ + assert(self); + + if (self->length >= trio_string_size(self)) + { + if (!TrioStringGrow(self, 0)) + goto error; + } + self->content[self->length] = character; + self->length++; + return TRUE; + + error: + return FALSE; +} + + +/** + Search for the first occurrence of second parameter in the first. + + @param self Dynamic string to be modified. + @param other Dynamic string to copy from. + @return Boolean value indicating success or failure. +*/ +TRIO_PUBLIC int +trio_string_contains(trio_string_t *self, + trio_string_t *other) +{ + assert(self); + assert(other); + + return trio_contains(self->content, other->content); +} + + +/* + * trio_xstring_contains + */ +TRIO_PUBLIC int +trio_xstring_contains(trio_string_t *self, + const char *other) +{ + assert(self); + assert(other); + + return trio_contains(self->content, other); +} + + +/* + * trio_string_copy + */ +TRIO_PUBLIC int +trio_string_copy(trio_string_t *self, + trio_string_t *other) +{ + assert(self); + assert(other); + + self->length = 0; + return trio_string_append(self, other); +} + + +/* + * trio_xstring_copy + */ +TRIO_PUBLIC int +trio_xstring_copy(trio_string_t *self, + const char *other) +{ + assert(self); + assert(other); + + self->length = 0; + return trio_xstring_append(self, other); +} + + +/* + * trio_string_duplicate + */ +TRIO_PUBLIC trio_string_t * +trio_string_duplicate(trio_string_t *other) +{ + trio_string_t *self; + + assert(other); + + self = TrioStringAlloc(); + if (self) + { + self->content = TrioDuplicateMax(other->content, other->length); + if (self->content) + { + self->length = other->length; + self->allocated = self->length + 1; + } + else + { + self->length = self->allocated = 0; + } + } + return self; +} + + +/* + * trio_xstring_duplicate + */ +TRIO_PUBLIC trio_string_t * +trio_xstring_duplicate(const char *other) +{ + trio_string_t *self; + + assert(other); + + self = TrioStringAlloc(); + if (self) + { + self->content = TrioDuplicateMax(other, trio_length(other)); + if (self->content) + { + self->length = trio_length(self->content); + self->allocated = self->length + 1; + } + else + { + self->length = self->allocated = 0; + } + } + return self; +} + + +/* + * trio_string_equal + */ +TRIO_PUBLIC int +trio_string_equal(trio_string_t *self, + trio_string_t *other) +{ + assert(self); + assert(other); + + return trio_equal(self->content, other->content); +} + + +/* + * trio_xstring_equal + */ +TRIO_PUBLIC int +trio_xstring_equal(trio_string_t *self, + const char *other) +{ + assert(self); + assert(other); + + return trio_equal(self->content, other); +} + + +/* + * trio_string_equal_max + */ +TRIO_PUBLIC int +trio_string_equal_max(trio_string_t *self, + size_t max, + trio_string_t *other) +{ + assert(self); + assert(other); + + return trio_equal_max(self->content, max, other->content); +} + + +/* + * trio_xstring_equal_max + */ +TRIO_PUBLIC int +trio_xstring_equal_max(trio_string_t *self, + size_t max, + const char *other) +{ + assert(self); + assert(other); + + return trio_equal_max(self->content, max, other); +} + + +/* + * trio_string_equal_case + */ +TRIO_PUBLIC int +trio_string_equal_case(trio_string_t *self, + trio_string_t *other) +{ + assert(self); + assert(other); + + return trio_equal_case(self->content, other->content); +} + + +/* + * trio_xstring_equal_case + */ +TRIO_PUBLIC int +trio_xstring_equal_case(trio_string_t *self, + const char *other) +{ + assert(self); + assert(other); + + return trio_equal_case(self->content, other); +} + + +/* + * trio_string_equal_case_max + */ +TRIO_PUBLIC int +trio_string_equal_case_max(trio_string_t *self, + size_t max, + trio_string_t *other) +{ + assert(self); + assert(other); + + return trio_equal_case_max(self->content, max, other->content); +} + + +/* + * trio_xstring_equal_case_max + */ +TRIO_PUBLIC int +trio_xstring_equal_case_max(trio_string_t *self, + size_t max, + const char *other) +{ + assert(self); + assert(other); + + return trio_equal_case_max(self->content, max, other); +} + + +/* + * trio_string_format_data_max + */ +TRIO_PUBLIC size_t +trio_string_format_date_max(trio_string_t *self, + size_t max, + const char *format, + const struct tm *datetime) +{ + assert(self); + + return trio_format_date_max(self->content, max, format, datetime); +} + + +/* + * trio_string_index + */ +TRIO_PUBLIC char * +trio_string_index(trio_string_t *self, + int character) +{ + assert(self); + + return trio_index(self->content, character); +} + + +/* + * trio_string_index_last + */ +TRIO_PUBLIC char * +trio_string_index_last(trio_string_t *self, + int character) +{ + assert(self); + + return trio_index_last(self->content, character); +} + + +/* + * trio_string_length + */ +TRIO_PUBLIC int +trio_string_length(trio_string_t *self) +{ + assert(self); + + if (self->length == 0) + { + self->length = trio_length(self->content); + } + return self->length; +} + + +/* + * trio_string_lower + */ +TRIO_PUBLIC int +trio_string_lower(trio_string_t *self) +{ + assert(self); + + return trio_lower(self->content); +} + + +/* + * trio_string_match + */ +TRIO_PUBLIC int +trio_string_match(trio_string_t *self, + trio_string_t *other) +{ + assert(self); + assert(other); + + return trio_match(self->content, other->content); +} + + +/* + * trio_xstring_match + */ +TRIO_PUBLIC int +trio_xstring_match(trio_string_t *self, + const char *other) +{ + assert(self); + assert(other); + + return trio_match(self->content, other); +} + + +/* + * trio_string_match_case + */ +TRIO_PUBLIC int +trio_string_match_case(trio_string_t *self, + trio_string_t *other) +{ + assert(self); + assert(other); + + return trio_match_case(self->content, other->content); +} + + +/* + * trio_xstring_match_case + */ +TRIO_PUBLIC int +trio_xstring_match_case(trio_string_t *self, + const char *other) +{ + assert(self); + assert(other); + + return trio_match_case(self->content, other); +} + + +/* + * trio_string_substring + */ +TRIO_PUBLIC char * +trio_string_substring(trio_string_t *self, + trio_string_t *other) +{ + assert(self); + assert(other); + + return trio_substring(self->content, other->content); +} + + +/* + * trio_xstring_substring + */ +TRIO_PUBLIC char * +trio_xstring_substring(trio_string_t *self, + const char *other) +{ + assert(self); + assert(other); + + return trio_substring(self->content, other); +} + + +/* + * trio_string_upper + */ +TRIO_PUBLIC int +trio_string_upper(trio_string_t *self) +{ + assert(self); + + return trio_upper(self->content); +} + +/** @} End of DynamicStrings */ diff --git a/triostr.h b/triostr.h new file mode 100644 index 00000000..94b01eef --- /dev/null +++ b/triostr.h @@ -0,0 +1,119 @@ +/************************************************************************* + * + * $Id$ + * + * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. + * + ************************************************************************/ + +#ifndef TRIO_TRIOSTR_H +#define TRIO_TRIOSTR_H + +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include "triodef.h" +#include "triop.h" + +enum { + TRIO_HASH_NONE = 0, + TRIO_HASH_PLAIN, + TRIO_HASH_TWOSIGNED +}; + +/************************************************************************* + * String functions + */ + +int trio_append(char *target, const char *source); +int trio_append_max(char *target, size_t max, const char *source); +int trio_contains(const char *string, const char *substring); +int trio_copy(char *target, const char *source); +int trio_copy_max(char *target, size_t max, const char *source); +char *trio_create(size_t size); +void trio_destroy(char *string); +char *trio_duplicate(const char *source); +char *trio_duplicate_max(const char *source, size_t max); +int trio_equal(const char *first, const char *second); +int trio_equal_case(const char *first, const char *second); +int trio_equal_case_max(const char *first, size_t max, const char *second); +int trio_equal_locale(const char *first, const char *second); +int trio_equal_max(const char *first, size_t max, const char *second); +const char *trio_error(int); +size_t trio_format_date_max(char *target, size_t max, const char *format, const struct tm *datetime); +unsigned long trio_hash(const char *string, int type); +char *trio_index(const char *string, char character); +char *trio_index_last(const char *string, char character); +size_t trio_length(const char *string); +int trio_lower(char *target); +int trio_match(const char *string, const char *pattern); +int trio_match_case(const char *string, const char *pattern); +size_t trio_span_function(char *target, const char *source, int (*Function)(int)); +char *trio_substring(const char *string, const char *substring); +char *trio_substring_max(const char *string, size_t max, const char *substring); +char *trio_tokenize(char *string, const char *delimiters); +float trio_to_float(const char *source, const char **endp); +double trio_to_double(const char *source, const char **endp); +long trio_to_long(const char *source, char **endp, int base); +unsigned long trio_to_unsigned_long(const char *source, char **endp, int base); +int trio_upper(char *target); + +/************************************************************************* + * Dynamic string functions + */ + +/* + * Opaque type for dynamic strings + */ +typedef struct _trio_string_t trio_string_t; + +trio_string_t *trio_string_create(int initial_size); +void trio_string_destroy(trio_string_t *self); +char *trio_string_get(trio_string_t *self, int offset); +void trio_xstring_set(trio_string_t *self, char *buffer); +char *trio_string_extract(trio_string_t *self); +int trio_string_size(trio_string_t *self); +void trio_string_terminate(trio_string_t *self); + +int trio_string_append(trio_string_t *self, trio_string_t *other); +int trio_string_contains(trio_string_t *self, trio_string_t *other); +int trio_string_copy(trio_string_t *self, trio_string_t *other); +trio_string_t *trio_string_duplicate(trio_string_t *other); +int trio_string_equal(trio_string_t *self, trio_string_t *other); +int trio_string_equal_max(trio_string_t *self, size_t max, trio_string_t *second); +int trio_string_equal_case(trio_string_t *self, trio_string_t *other); +int trio_string_equal_case_max(trio_string_t *self, size_t max, trio_string_t *other); +size_t trio_string_format_date_max(trio_string_t *self, size_t max, const char *format, const struct tm *datetime); +char *trio_string_index(trio_string_t *self, int character); +char *trio_string_index_last(trio_string_t *self, int character); +int trio_string_length(trio_string_t *self); +int trio_string_lower(trio_string_t *self); +int trio_string_match(trio_string_t *self, trio_string_t *other); +int trio_string_match_case(trio_string_t *self, trio_string_t *other); +char *trio_string_substring(trio_string_t *self, trio_string_t *other); +int trio_string_upper(trio_string_t *self); + +int trio_xstring_append_char(trio_string_t *self, char character); +int trio_xstring_append(trio_string_t *self, const char *other); +int trio_xstring_contains(trio_string_t *self, const char *other); +int trio_xstring_copy(trio_string_t *self, const char *other); +trio_string_t *trio_xstring_duplicate(const char *other); +int trio_xstring_equal(trio_string_t *self, const char *other); +int trio_xstring_equal_max(trio_string_t *self, size_t max, const char *other); +int trio_xstring_equal_case(trio_string_t *self, const char *other); +int trio_xstring_equal_case_max(trio_string_t *self, size_t max, const char *other); +int trio_xstring_match(trio_string_t *self, const char *other); +int trio_xstring_match_case(trio_string_t *self, const char *other); +char *trio_xstring_substring(trio_string_t *self, const char *other); + +#endif /* TRIO_TRIOSTR_H */ |