aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--doc/FAQ.html2
-rw-r--r--doc/downloads.html5
-rw-r--r--trio.c2591
-rw-r--r--trio.h133
-rw-r--r--triodef.h68
-rw-r--r--trionan.c185
-rw-r--r--trionan.h23
-rw-r--r--triop.h113
-rw-r--r--triostr.c831
-rw-r--r--triostr.h144
11 files changed, 2744 insertions, 1357 deletions
diff --git a/ChangeLog b/ChangeLog
index 24f596a9..fe4ae65a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Thu Sep 26 00:31:46 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+ * trio.c trio.h triodef.h trionan.c trionan.h triop.h
+ triostr.c triostr.h: applied a trio update patch from
+ Bjorn Reese which should work with MinGW
+
Thu Sep 26 00:21:18 CEST 2002 Daniel Veillard <daniel@veillard.com>
* tree.c: improving some documentation comments
diff --git a/doc/FAQ.html b/doc/FAQ.html
index 34e39f50..508ddf68 100644
--- a/doc/FAQ.html
+++ b/doc/FAQ.html
@@ -119,7 +119,7 @@ A:link, A:visited, A:active { text-decoration: underline }
Not Use libxml1</span></strong>, use libxml2</li>
<li>
<em>Where can I get libxml</em> ?
- <p>The original distribution comes from <a href="ftp://rpmfind.net/pub/libxml/">rpmfind.net</a> or <a href="ftp://ftp.gnome.org/pub/GNOME/stable/sources/libxml/">gnome.org</a>
+ <p>The original distribution comes from <a href="ftp://rpmfind.net/pub/libxml/">rpmfind.net</a> or <a href="ftp://ftp.gnome.org/pub/GNOME/sources/libxml2/2.4/">gnome.org</a>
</p>
<p>Most Linux and BSD distributions include libxml, this is probably the
safer way for end-users to use libxml.</p>
diff --git a/doc/downloads.html b/doc/downloads.html
index 7ee3639e..b04e9e99 100644
--- a/doc/downloads.html
+++ b/doc/downloads.html
@@ -89,9 +89,8 @@ A:link, A:visited, A:active { text-decoration: underline }
</td></tr></table></td>
<td valign="top" bgcolor="#8b7765"><table border="0" cellspacing="0" cellpadding="1" width="100%"><tr><td><table border="0" cellspacing="0" cellpadding="1" width="100%" bgcolor="#000000"><tr><td><table border="0" cellpadding="3" cellspacing="1" width="100%"><tr><td bgcolor="#fffacd">
<p>The latest versions of libxml can be found on <a href="ftp://xmlsoft.org/">xmlsoft.org</a> (<a href="ftp://speakeasy.rpmfind.net/pub/libxml/">Seattle</a>, <a href="ftp://fr.rpmfind.net/pub/libxml/">France</a>) or on the <a href="ftp://ftp.gnome.org/pub/GNOME/MIRRORS.html">Gnome FTP server</a> either
-as a <a href="ftp://ftp.gnome.org/pub/GNOME/stable/sources/libxml/">source
-archive</a> or <a href="ftp://ftp.gnome.org/pub/GNOME/stable/redhat/i386/libxml/">RPM
-packages</a>, Antonin Sprinzl also provide <a href="ftp://gd.tuwien.ac.at/pub/libxml/">a mirror in Austria</a>. (NOTE that
+as a <a href="ftp://ftp.gnome.org/pub/GNOME/sources/libxml2/2.4/">source
+archive</a>, Antonin Sprinzl also provide <a href="ftp://gd.tuwien.ac.at/pub/libxml/">a mirror in Austria</a>. (NOTE that
you need both the <a href="http://rpmfind.net/linux/RPM/libxml2.html">libxml(2)</a> and <a href="http://rpmfind.net/linux/RPM/libxml2-devel.html">libxml(2)-devel</a>
packages installed to compile applications using libxml.) <a href="mailto:igor@stud.fh-frankfurt.de">Igor Zlatkovic</a> is now the
maintainer of the Windows port, <a href="http://www.fh-frankfurt.de/~igor/projects/libxml/index.html">he
diff --git a/trio.c b/trio.c
index 1a844bcd..7593e581 100644
--- a/trio.c
+++ b/trio.c
@@ -28,7 +28,6 @@
* TODO:
* - Scan is probably too permissive about its modifiers.
* - C escapes in %#[] ?
- * - C99 support has not been properly tested.
* - Multibyte characters (done for format parsing, except scan groups)
* - Complex numbers? (C99 _Complex)
* - Boolean values? (C99 _Bool)
@@ -47,19 +46,17 @@
#include "triodef.h"
#include "trio.h"
#include "triop.h"
-#include "triostr.h"
#include "trionan.h"
-
-/*
- * Encode the error code and the position. This is decoded
- * with TRIO_ERROR_CODE and TRIO_ERROR_POSITION.
- */
-#if TRIO_ERRORS
-# define TRIO_ERROR_RETURN(x,y) (- ((x) + ((y) << 8)))
-#else
-# define TRIO_ERROR_RETURN(x,y) (-1)
+#if !defined(TRIO_MINIMAL)
+# include "triostr.h"
#endif
+/**************************************************************************
+ *
+ * Definitions
+ *
+ *************************************************************************/
+
#if defined(__STDC_ISO_10646__) || defined(MB_LEN_MAX) || defined(USE_MULTIBYTE) || TRIO_WIDECHAR
# define TRIO_COMPILER_SUPPORTS_MULTIBYTE
# if !defined(MB_LEN_MAX)
@@ -67,7 +64,6 @@
# endif
#endif
-
/*************************************************************************
* Generic definitions
*/
@@ -83,7 +79,11 @@
#include <math.h>
#include <limits.h>
#include <float.h>
-#include <stdarg.h>
+#if defined(TRIO_COMPILER_ANCIENT)
+# include <varargs.h>
+#else
+# include <stdarg.h>
+#endif
#include <stddef.h>
#include <errno.h>
@@ -100,9 +100,15 @@
/* mincore() can be used for debugging purposes */
#define VALID(x) (NULL != (x))
-/* xlC crashes on log10(0) */
-#define guarded_log10(x) (((x) == 0.0) ? trio_ninf() : log10(x))
-#define guarded_log16(x) (guarded_log10(x) / log10(16.0))
+#if TRIO_ERRORS
+ /*
+ * Encode the error code and the position. This is decoded
+ * with TRIO_ERROR_CODE and TRIO_ERROR_POSITION.
+ */
+# define TRIO_ERROR_RETURN(x,y) (- ((x) + ((y) << 8)))
+#else
+# define TRIO_ERROR_RETURN(x,y) (-1)
+#endif
/*************************************************************************
@@ -129,9 +135,11 @@
# if defined(TRIO_COMPILER_SUPPORTS_ISO94)
# include <wchar.h>
# include <wctype.h>
+typedef wchar_t trio_wchar_t;
+typedef wint_t trio_wint_t;
# else
-typedef char wchar_t;
-typedef int wint_t;
+typedef char trio_wchar_t;
+typedef int trio_wint_t;
# define WCONST(x) L ## x
# define WEOF EOF
# define iswalnum(x) isalnum(x)
@@ -180,7 +188,7 @@ typedef signed long int trio_longlong_t;
typedef unsigned long int trio_ulonglong_t;
# endif
#else
-typedef signed long int trio_longlong_t;
+typedef TRIO_SIGNED long int trio_longlong_t;
typedef unsigned long int trio_ulonglong_t;
#endif
@@ -214,17 +222,17 @@ typedef trio_ulonglong_t trio_uintmax_t;
# if defined(TRIO_INT8_T)
typedef TRIO_INT8_T trio_int8_t;
# else
-typedef signed char trio_int8_t;
+typedef TRIO_SIGNED char trio_int8_t;
# endif
# if defined(TRIO_INT16_T)
typedef TRIO_INT16_T trio_int16_t;
# else
-typedef signed short trio_int16_t;
+typedef TRIO_SIGNED short trio_int16_t;
# endif
# if defined(TRIO_INT32_T)
typedef TRIO_INT32_T trio_int32_t;
# else
-typedef signed int trio_int32_t;
+typedef TRIO_SIGNED int trio_int32_t;
# endif
# if defined(TRIO_INT64_T)
typedef TRIO_INT64_T trio_int64_t;
@@ -233,24 +241,47 @@ typedef trio_longlong_t trio_int64_t;
# endif
#endif
+#if !(defined(TRIO_COMPILER_SUPPORTS_C99) \
+ || defined(TRIO_COMPILER_SUPPORTS_UNIX01))
+# define floorl(x) floor((double)(x))
+# define fmodl(x,y) fmod((double)(x),(double)(y))
+# define powl(x,y) pow((double)(x),(double)(y))
+#endif
+
+#define TRIO_FABS(x) (((x) < 0.0) ? -(x) : (x))
/*************************************************************************
- * Internal definitions
+ * Internal Definitions
*/
+#ifndef DECIMAL_DIG
+# define DECIMAL_DIG DBL_DIG
+#endif
+
/* Long double sizes */
#ifdef LDBL_DIG
# define MAX_MANTISSA_DIGITS LDBL_DIG
# define MAX_EXPONENT_DIGITS 4
+# define MAX_DOUBLE_DIGITS LDBL_MAX_10_EXP
#else
-# define MAX_MANTISSA_DIGITS DBL_DIG
+# define MAX_MANTISSA_DIGITS DECIMAL_DIG
# define MAX_EXPONENT_DIGITS 3
+# define MAX_DOUBLE_DIGITS DBL_MAX_10_EXP
+#endif
+
+#if defined(TRIO_COMPILER_ANCIENT) || !defined(LDBL_DIG)
+# undef LDBL_DIG
+# undef LDBL_MANT_DIG
+# undef LDBL_EPSILON
+# define LDBL_DIG DBL_DIG
+# define LDBL_MANT_DIG DBL_MANT_DIG
+# define LDBL_EPSILON DBL_EPSILON
#endif
/* The maximal number of digits is for base 2 */
#define MAX_CHARS_IN(x) (sizeof(x) * CHAR_BIT)
/* The width of a pointer. The number of bits in a hex digit is 4 */
-#define POINTER_WIDTH ((sizeof("0x") - 1) + sizeof(void *) * CHAR_BIT / 4)
+#define POINTER_WIDTH ((sizeof("0x") - 1) + sizeof(trio_pointer_t) * CHAR_BIT / 4)
/* Infinite and Not-A-Number for floating-point */
#define INFINITE_LOWER "inf"
@@ -301,6 +332,7 @@ enum {
/* Reused flags */
FLAGS_EXCLUDE = FLAGS_SHORT,
FLAGS_USER_DEFINED = FLAGS_IGNORE,
+ FLAGS_ROUNDING = FLAGS_INTMAX_T,
/* Compounded flags */
FLAGS_ALL_VARSIZES = FLAGS_LONG | FLAGS_QUAD | FLAGS_INTMAX_T | FLAGS_PTRDIFF_T | FLAGS_SIZE_T,
FLAGS_ALL_SIZES = FLAGS_ALL_VARSIZES | FLAGS_SHORTSHORT | FLAGS_SHORT,
@@ -310,6 +342,7 @@ enum {
NO_PRECISION = -1,
NO_SIZE = -1,
+ /* Do not change these */
NO_BASE = -1,
MIN_BASE = 2,
MAX_BASE = 36,
@@ -362,18 +395,18 @@ enum {
#define CHAR_ADJUST ' '
/* 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:"
-#define CLASS_LOWER ":lower:"
-#define CLASS_PRINT ":print:"
-#define CLASS_PUNCT ":punct:"
-#define CLASS_SPACE ":space:"
-#define CLASS_UPPER ":upper:"
-#define CLASS_XDIGIT ":xdigit:"
+#define CLASS_ALNUM "[:alnum:]"
+#define CLASS_ALPHA "[:alpha:]"
+#define CLASS_BLANK "[:blank:]"
+#define CLASS_CNTRL "[:cntrl:]"
+#define CLASS_DIGIT "[:digit:]"
+#define CLASS_GRAPH "[:graph:]"
+#define CLASS_LOWER "[:lower:]"
+#define CLASS_PRINT "[:print:]"
+#define CLASS_PUNCT "[:punct:]"
+#define CLASS_SPACE "[:space:]"
+#define CLASS_UPPER "[:upper:]"
+#define CLASS_XDIGIT "[:xdigit:]"
/*
* SPECIFIERS:
@@ -543,7 +576,7 @@ enum {
#define QUALIFIER_MINUS '-'
#define QUALIFIER_DOT '.'
#define QUALIFIER_STAR '*'
-#define QUALIFIER_CIRCUMFLEX '^'
+#define QUALIFIER_CIRCUMFLEX '^' /* For scanlists */
#if TRIO_C99
# define QUALIFIER_SIZE_T 'z'
# define QUALIFIER_PTRDIFF_T 't'
@@ -568,12 +601,15 @@ enum {
# define QUALIFIER_PARAM '@' /* Experimental */
# define QUALIFIER_COLON ':' /* For scanlists */
# define QUALIFIER_EQUAL '=' /* For scanlists */
+# define QUALIFIER_ROUNDING_UPPER 'R'
#endif
/*************************************************************************
- * Internal structures
- */
+ *
+ * Internal Structures
+ *
+ *************************************************************************/
/* Parameters */
typedef struct {
@@ -595,17 +631,17 @@ typedef struct {
union {
char *string;
#if TRIO_WIDECHAR
- wchar_t *wstring;
+ trio_wchar_t *wstring;
#endif
- void *pointer;
+ trio_pointer_t pointer;
union {
- trio_uintmax_t as_signed;
- trio_intmax_t as_unsigned;
+ trio_intmax_t as_signed;
+ trio_uintmax_t as_unsigned;
} number;
double doubleNumber;
double *doublePointer;
- long double longdoubleNumber;
- long double *longdoublePointer;
+ trio_long_double_t longdoubleNumber;
+ trio_long_double_t *longdoublePointer;
int errorNumber;
} data;
/* For the user-defined specifier */
@@ -613,20 +649,29 @@ typedef struct {
char user_data[MAX_USER_DATA];
} trio_parameter_t;
+/* Container for customized functions */
+typedef struct {
+ union {
+ trio_outstream_t out;
+ trio_instream_t in;
+ } stream;
+ trio_pointer_t closure;
+} trio_custom_t;
+
/* General trio "class" */
typedef struct _trio_class_t {
/*
* The function to write characters to a stream.
*/
- void (*OutStream)(struct _trio_class_t *, int);
+ void (*OutStream) TRIO_PROTO((struct _trio_class_t *, int));
/*
* The function to read characters from a stream.
*/
- void (*InStream)(struct _trio_class_t *, int *);
+ void (*InStream) TRIO_PROTO((struct _trio_class_t *, int *));
/*
* The current location in the stream.
*/
- void *location;
+ trio_pointer_t location;
/*
* The character currently being processed.
*/
@@ -667,8 +712,10 @@ typedef struct _trio_userdef_t {
/*************************************************************************
- * Internal variables
- */
+ *
+ * Internal Variables
+ *
+ *************************************************************************/
static TRIO_CONST char rcsid[] = "@(#)$Id$";
@@ -678,7 +725,7 @@ static TRIO_CONST char rcsid[] = "@(#)$Id$";
* e.g: va_arg(arg_ptr, long double)
*/
#if defined(TRIO_PLATFORM_MPEIX)
-static TRIO_CONST long double ___dummy_long_double = 0;
+static TRIO_CONST trio_long_double_t ___dummy_long_double = 0;
#endif
static TRIO_CONST char internalNullString[] = "(nil)";
@@ -691,7 +738,10 @@ static struct lconv *internalLocaleValues = NULL;
* UNIX98 says "in a locale where the radix character is not defined,
* the radix character defaults to a period (.)"
*/
-static char internalDecimalPoint[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ".";
+static int internalDecimalPointLength = 1;
+static int internalThousandSeparatorLength = 1;
+static char internalDecimalPoint = '.';
+static char internalDecimalPointString[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ".";
static char internalThousandSeparator[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ",";
static char internalGrouping[MAX_LOCALE_GROUPS] = { (char)NO_GROUPING };
@@ -704,38 +754,23 @@ static BOOLEAN_T internalCollationUnconverted = TRUE;
static char internalCollationArray[MAX_CHARACTER_CLASS][MAX_CHARACTER_CLASS];
#endif
+#if TRIO_EXTENSION
static TRIO_VOLATILE trio_callback_t internalEnterCriticalRegion = NULL;
static TRIO_VOLATILE trio_callback_t internalLeaveCriticalRegion = NULL;
static trio_userdef_t *internalUserDef = NULL;
+#endif
/*************************************************************************
- * trio_strerror
- */
-TRIO_PUBLIC TRIO_CONST char *
-trio_strerror(int errorcode)
-{
- /* Textual versions of the error codes */
- switch (TRIO_ERROR_CODE(errorcode))
- {
- case TRIO_EOF:
- return "End of file";
- case TRIO_EINVAL:
- return "Invalid argument";
- case TRIO_ETOOMANY:
- return "Too many arguments";
- case TRIO_EDBLREF:
- return "Double reference";
- case TRIO_EGAP:
- return "Reference gap";
- case TRIO_ENOMEM:
- return "Out of memory";
- case TRIO_ERANGE:
- return "Invalid range";
- default:
- return "Unknown";
- }
-}
+ *
+ * Internal Functions
+ *
+ ************************************************************************/
+
+#if defined(TRIO_MINIMAL)
+# define TRIO_STRING_PUBLIC static
+# include "triostr.c"
+#endif /* defined(TRIO_MINIMAL) */
/*************************************************************************
* TrioIsQualifier
@@ -745,10 +780,12 @@ trio_strerror(int errorcode)
* QUALIFIER_POSITION must not be added.
*/
TRIO_PRIVATE BOOLEAN_T
-TrioIsQualifier(TRIO_CONST char ch)
+TrioIsQualifier
+TRIO_ARGS1((character),
+ TRIO_CONST char character)
{
/* QUALIFIER_POSITION is not included */
- switch (ch)
+ switch (character)
{
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
@@ -795,6 +832,9 @@ TrioIsQualifier(TRIO_CONST char ch)
#if defined(QUALIFIER_FIXED_SIZE)
case QUALIFIER_FIXED_SIZE:
#endif
+#if defined(QUALIFIER_ROUNDING_UPPER)
+ case QUALIFIER_ROUNDING_UPPER:
+#endif
return TRUE;
default:
return FALSE;
@@ -805,8 +845,8 @@ TrioIsQualifier(TRIO_CONST char ch)
* TrioSetLocale
*/
#if defined(USE_LOCALE)
-TRIO_PUBLIC void
-TrioSetLocale(void)
+TRIO_PRIVATE void
+TrioSetLocale(TRIO_NOARGS)
{
internalLocaleValues = (struct lconv *)localeconv();
if (internalLocaleValues)
@@ -814,9 +854,18 @@ TrioSetLocale(void)
if ((internalLocaleValues->decimal_point) &&
(internalLocaleValues->decimal_point[0] != NIL))
{
- trio_copy_max(internalDecimalPoint,
- sizeof(internalDecimalPoint),
- internalLocaleValues->decimal_point);
+ internalDecimalPointLength = trio_length(internalLocaleValues->decimal_point);
+ if (internalDecimalPointLength == 1)
+ {
+ internalDecimalPoint = internalLocaleValues->decimal_point[0];
+ }
+ else
+ {
+ internalDecimalPoint = NIL;
+ trio_copy_max(internalDecimalPointString,
+ sizeof(internalDecimalPointString),
+ internalLocaleValues->decimal_point);
+ }
}
if ((internalLocaleValues->thousands_sep) &&
(internalLocaleValues->thousands_sep[0] != NIL))
@@ -824,6 +873,7 @@ TrioSetLocale(void)
trio_copy_max(internalThousandSeparator,
sizeof(internalThousandSeparator),
internalLocaleValues->thousands_sep);
+ internalThousandSeparatorLength = trio_length(internalThousandSeparator);
}
if ((internalLocaleValues->grouping) &&
(internalLocaleValues->grouping[0] != NIL))
@@ -836,15 +886,91 @@ TrioSetLocale(void)
}
#endif /* defined(USE_LOCALE) */
+TRIO_PRIVATE int
+TrioCalcThousandSeparatorLength
+TRIO_ARGS1((digits),
+ int digits)
+{
+#if TRIO_EXTENSION
+ int count = 0;
+ int step = NO_GROUPING;
+ char *groupingPointer = internalGrouping;
+
+ while (digits > 0)
+ {
+ if (*groupingPointer == CHAR_MAX)
+ {
+ /* Disable grouping */
+ break; /* while */
+ }
+ else if (*groupingPointer == 0)
+ {
+ /* Repeat last group */
+ if (step == NO_GROUPING)
+ {
+ /* Error in locale */
+ break; /* while */
+ }
+ }
+ else
+ {
+ step = *groupingPointer++;
+ }
+ if (digits > step)
+ count += internalThousandSeparatorLength;
+ digits -= step;
+ }
+ return count;
+#else
+ return 0;
+#endif
+}
+
+TRIO_PRIVATE BOOLEAN_T
+TrioFollowedBySeparator
+TRIO_ARGS1((position),
+ int position)
+{
+#if TRIO_EXTENSION
+ int step = 0;
+ char *groupingPointer = internalGrouping;
+
+ position--;
+ if (position == 0)
+ return FALSE;
+ while (position > 0)
+ {
+ if (*groupingPointer == CHAR_MAX)
+ {
+ /* Disable grouping */
+ break; /* while */
+ }
+ else if (*groupingPointer != 0)
+ {
+ step = *groupingPointer++;
+ }
+ if (step == 0)
+ break;
+ position -= step;
+ }
+ return (position == 0);
+#else
+ return FALSE;
+#endif
+}
+
/*************************************************************************
* TrioGetPosition
*
* Get the %n$ position.
*/
TRIO_PRIVATE int
-TrioGetPosition(TRIO_CONST char *format,
- int *indexPointer)
+TrioGetPosition
+TRIO_ARGS2((format, indexPointer),
+ TRIO_CONST char *format,
+ int *indexPointer)
{
+#if TRIO_UNIX98
char *tmpformat;
int number = 0;
int index = *indexPointer;
@@ -860,17 +986,22 @@ TrioGetPosition(TRIO_CONST char *format,
*/
return number - 1;
}
+#endif
return NO_POSITION;
}
+#if TRIO_EXTENSION
/*************************************************************************
* TrioFindNamespace
*
* Find registered user-defined specifier.
- * The prev argument is used for optimisation only.
+ * The prev argument is used for optimization only.
*/
TRIO_PRIVATE trio_userdef_t *
-TrioFindNamespace(TRIO_CONST char *name, trio_userdef_t **prev)
+TrioFindNamespace
+TRIO_ARGS2((name, prev),
+ TRIO_CONST char *name,
+ trio_userdef_t **prev)
{
trio_userdef_t *def;
@@ -892,6 +1023,117 @@ TrioFindNamespace(TRIO_CONST char *name, trio_userdef_t **prev)
return def;
}
+#endif
+
+/*************************************************************************
+ * TrioPower
+ *
+ * Description:
+ * Calculate pow(base, exponent), where number and exponent are integers.
+ */
+TRIO_PRIVATE trio_long_double_t
+TrioPower
+TRIO_ARGS2((number, exponent),
+ int number,
+ int exponent)
+{
+ trio_long_double_t result;
+
+ if (number == 10)
+ {
+ switch (exponent)
+ {
+ /* Speed up calculation of common cases */
+ case 0:
+ result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E-1);
+ break;
+ case 1:
+ result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+0);
+ break;
+ case 2:
+ result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+1);
+ break;
+ case 3:
+ result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+2);
+ break;
+ case 4:
+ result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+3);
+ break;
+ case 5:
+ result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+4);
+ break;
+ case 6:
+ result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+5);
+ break;
+ case 7:
+ result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+6);
+ break;
+ case 8:
+ result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+7);
+ break;
+ case 9:
+ result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+8);
+ break;
+ default:
+ result = powl((trio_long_double_t)number,
+ (trio_long_double_t)exponent);
+ break;
+ }
+ }
+ else
+ {
+ return powl((trio_long_double_t)number, (trio_long_double_t)exponent);
+ }
+ return result;
+}
+
+/*************************************************************************
+ * TrioLogarithm
+ */
+TRIO_PRIVATE double
+TrioLogarithm
+TRIO_ARGS2((number, base),
+ double number,
+ int base)
+{
+ double result;
+
+ if (number <= 0.0)
+ {
+ /* xlC crashes on log(0) */
+ result = (number == 0.0) ? trio_ninf() : trio_nan();
+ }
+ else
+ {
+ if (base == 10)
+ {
+ result = log10(number);
+ }
+ else
+ {
+ result = log10(number) / log10((double)base);
+ }
+ }
+ return result;
+}
+
+/*************************************************************************
+ * TrioLogarithmBase
+ */
+TRIO_PRIVATE double
+TrioLogarithmBase
+TRIO_ARGS1((base),
+ int base)
+{
+ switch (base)
+ {
+ case BASE_BINARY : return 1.0;
+ case BASE_OCTAL : return 3.0;
+ case BASE_DECIMAL: return 3.321928094887362345;
+ case BASE_HEX : return 4.0;
+ default : return TrioLogarithm((double)base, 2);
+ }
+}
/*************************************************************************
* TrioParse
@@ -900,16 +1142,16 @@ TrioFindNamespace(TRIO_CONST char *name, trio_userdef_t **prev)
* Parse the format string
*/
TRIO_PRIVATE int
-TrioParse(int type,
- TRIO_CONST char *format,
- trio_parameter_t *parameters,
- va_list arglist,
- void **argarray)
+TrioParse
+TRIO_ARGS5((type, format, parameters, arglist, argarray),
+ int type,
+ TRIO_CONST char *format,
+ trio_parameter_t *parameters,
+ va_list *arglist,
+ trio_pointer_t *argarray)
{
-#if TRIO_ERRORS
/* Count the number of times a parameter is referenced */
unsigned short usedEntries[MAX_PARAMETERS];
-#endif
/* Parameter counters */
int parameterPosition;
int currentParam;
@@ -923,7 +1165,7 @@ TrioParse(int type,
int index; /* Index into formatting string */
int dots; /* Count number of dots in modifier part */
BOOLEAN_T positional; /* Does the specifier have a positional? */
- BOOLEAN_T got_sticky = FALSE; /* Are there any sticky modifiers at all? */
+ BOOLEAN_T gotSticky = FALSE; /* Are there any sticky modifiers at all? */
/*
* indices specifies the order in which the parameters must be
* read from the va_args (this is necessary to handle positionals)
@@ -935,23 +1177,25 @@ TrioParse(int type,
#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
int charlen;
#endif
+ int save_errno;
int i = -1;
int num;
char *tmpformat;
-
-#if TRIO_ERRORS
+ /* One and only one of arglist and argarray must be used */
+ assert((arglist != NULL) ^ (argarray != NULL));
+
/*
* The 'parameters' array is not initialized, but we need to
* know which entries we have used.
*/
memset(usedEntries, 0, sizeof(usedEntries));
-#endif
+ save_errno = errno;
index = 0;
parameterPosition = 0;
#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- mblen(NULL, 0);
+ (void)mblen(NULL, 0);
#endif
while (format[index])
@@ -1034,8 +1278,11 @@ TrioParse(int type,
/* After the first dot we have the precision */
flags |= FLAGS_PRECISION;
- if ((QUALIFIER_STAR == format[index]) ||
- (QUALIFIER_PARAM == format[index]))
+ if ((QUALIFIER_STAR == format[index])
+#if defined(QUALIFIER_PARAM)
+ || (QUALIFIER_PARAM == format[index])
+#endif
+ )
{
index++;
flags |= FLAGS_PRECISION_PARAMETER;
@@ -1076,8 +1323,11 @@ TrioParse(int type,
/* After the second dot we have the base */
flags |= FLAGS_BASE;
- if ((QUALIFIER_STAR == format[index]) ||
- (QUALIFIER_PARAM == format[index]))
+ if ((QUALIFIER_STAR == format[index])
+#if defined(QUALIFIER_PARAM)
+ || (QUALIFIER_PARAM == format[index])
+#endif
+ )
{
index++;
flags |= FLAGS_BASE_PARAMETER;
@@ -1119,9 +1369,11 @@ TrioParse(int type,
}
break; /* QUALIFIER_DOT */
+#if defined(QUALIFIER_PARAM)
case QUALIFIER_PARAM:
type = TYPE_PRINT;
/* FALLTHROUGH */
+#endif
case QUALIFIER_STAR:
/* This has different meanings for print and scan */
if (TYPE_PRINT == type)
@@ -1292,7 +1544,7 @@ TrioParse(int type,
#if defined(QUALIFIER_STICKY)
case QUALIFIER_STICKY:
flags |= FLAGS_STICKY;
- got_sticky = TRUE;
+ gotSticky = TRUE;
break;
#endif
@@ -1312,6 +1564,12 @@ TrioParse(int type,
break;
#endif
+#if defined(QUALIFIER_ROUNDING_UPPER)
+ case QUALIFIER_ROUNDING_UPPER:
+ flags |= FLAGS_ROUNDING;
+ break;
+#endif
+
default:
/* Bail out completely to make the error more obvious */
return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
@@ -1324,9 +1582,7 @@ TrioParse(int type,
*/
if (flags & FLAGS_WIDTH_PARAMETER)
{
-#if TRIO_ERRORS
usedEntries[width] += 1;
-#endif
parameters[pos].type = FORMAT_PARAMETER;
parameters[pos].flags = 0;
indices[width] = pos;
@@ -1334,9 +1590,7 @@ TrioParse(int type,
}
if (flags & FLAGS_PRECISION_PARAMETER)
{
-#if TRIO_ERRORS
usedEntries[precision] += 1;
-#endif
parameters[pos].type = FORMAT_PARAMETER;
parameters[pos].flags = 0;
indices[precision] = pos;
@@ -1344,9 +1598,7 @@ TrioParse(int type,
}
if (flags & FLAGS_BASE_PARAMETER)
{
-#if TRIO_ERRORS
usedEntries[base] += 1;
-#endif
parameters[pos].type = FORMAT_PARAMETER;
parameters[pos].flags = 0;
indices[base] = pos;
@@ -1354,9 +1606,7 @@ TrioParse(int type,
}
if (flags & FLAGS_VARSIZE_PARAMETER)
{
-#if TRIO_ERRORS
usedEntries[varsize] += 1;
-#endif
parameters[pos].type = FORMAT_PARAMETER;
parameters[pos].flags = 0;
indices[varsize] = pos;
@@ -1492,6 +1742,10 @@ TrioParse(int type,
break;
case SPECIFIER_POINTER:
+ if (sizeof(trio_pointer_t) == sizeof(trio_ulonglong_t))
+ flags |= FLAGS_QUAD;
+ else if (sizeof(trio_pointer_t) == sizeof(long))
+ flags |= FLAGS_LONG;
parameters[pos].type = FORMAT_POINTER;
break;
@@ -1540,9 +1794,7 @@ TrioParse(int type,
parameters[pos].flags = FLAGS_USER_DEFINED;
/* Adjust parameters for insertion of new one */
pos++;
-# if TRIO_ERRORS
usedEntries[currentParam] += 1;
-# endif
parameters[pos].type = FORMAT_USER_DEFINED;
currentParam++;
indices[currentParam] = pos;
@@ -1582,13 +1834,11 @@ TrioParse(int type,
return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
}
-#if TRIO_ERRORS
/* Count the number of times this entry has been used */
usedEntries[currentParam] += 1;
-#endif
/* Find last sticky parameters */
- if (got_sticky && !(flags & FLAGS_STICKY))
+ if (gotSticky && !(flags & FLAGS_STICKY))
{
for (i = pos - 1; i >= 0; i--)
{
@@ -1627,7 +1877,6 @@ TrioParse(int type,
for (num = 0; num <= maxParam; num++)
{
-#if TRIO_ERRORS
if (usedEntries[num] != 1)
{
if (usedEntries[num] == 0) /* gap detected */
@@ -1635,7 +1884,6 @@ TrioParse(int type,
else /* double references detected */
return TRIO_ERROR_RETURN(TRIO_EDBLREF, num);
}
-#endif
i = indices[num];
@@ -1676,24 +1924,26 @@ TrioParse(int type,
if (flags & FLAGS_WIDECHAR)
{
parameters[i].data.wstring = (argarray == NULL)
- ? va_arg(arglist, wchar_t *)
- : (wchar_t *)(argarray[num]);
+ ? va_arg(*arglist, trio_wchar_t *)
+ : (trio_wchar_t *)(argarray[num]);
}
else
#endif
{
parameters[i].data.string = (argarray == NULL)
- ? va_arg(arglist, char *)
+ ? va_arg(*arglist, char *)
: (char *)(argarray[num]);
}
break;
+#if defined(FORMAT_USER_DEFINED)
+ case FORMAT_USER_DEFINED:
+#endif
case FORMAT_POINTER:
case FORMAT_COUNT:
- case FORMAT_USER_DEFINED:
case FORMAT_UNKNOWN:
parameters[i].data.pointer = (argarray == NULL)
- ? va_arg(arglist, void *)
+ ? va_arg(*arglist, trio_pointer_t )
: argarray[num];
break;
@@ -1703,18 +1953,18 @@ TrioParse(int type,
{
if (argarray == NULL)
parameters[i].data.pointer =
- (trio_uintmax_t *)va_arg(arglist, void *);
+ (trio_pointer_t)va_arg(*arglist, trio_pointer_t);
else
{
if (parameters[i].type == FORMAT_CHAR)
parameters[i].data.pointer =
- (trio_uintmax_t *)((char *)argarray[num]);
+ (trio_pointer_t)((char *)argarray[num]);
else if (parameters[i].flags & FLAGS_SHORT)
parameters[i].data.pointer =
- (trio_uintmax_t *)((short *)argarray[num]);
+ (trio_pointer_t)((short *)argarray[num]);
else
parameters[i].data.pointer =
- (trio_uintmax_t *)((int *)argarray[num]);
+ (trio_pointer_t)((int *)argarray[num]);
}
}
else
@@ -1761,36 +2011,36 @@ TrioParse(int type,
#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER)
if (parameters[i].flags & FLAGS_SIZE_T)
parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(arglist, size_t)
+ ? (trio_uintmax_t)va_arg(*arglist, size_t)
: (trio_uintmax_t)(*((size_t *)argarray[num]));
else
#endif
#if defined(QUALIFIER_PTRDIFF_T)
if (parameters[i].flags & FLAGS_PTRDIFF_T)
parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(arglist, ptrdiff_t)
+ ? (trio_uintmax_t)va_arg(*arglist, ptrdiff_t)
: (trio_uintmax_t)(*((ptrdiff_t *)argarray[num]));
else
#endif
#if defined(QUALIFIER_INTMAX_T)
if (parameters[i].flags & FLAGS_INTMAX_T)
parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(arglist, trio_intmax_t)
+ ? (trio_uintmax_t)va_arg(*arglist, trio_intmax_t)
: (trio_uintmax_t)(*((trio_intmax_t *)argarray[num]));
else
#endif
if (parameters[i].flags & FLAGS_QUAD)
parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(arglist, trio_ulonglong_t)
+ ? (trio_uintmax_t)va_arg(*arglist, trio_ulonglong_t)
: (trio_uintmax_t)(*((trio_ulonglong_t *)argarray[num]));
else if (parameters[i].flags & FLAGS_LONG)
parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(arglist, long)
+ ? (trio_uintmax_t)va_arg(*arglist, long)
: (trio_uintmax_t)(*((long *)argarray[num]));
else
{
if (argarray == NULL)
- parameters[i].data.number.as_unsigned = (trio_uintmax_t)va_arg(arglist, int);
+ parameters[i].data.number.as_unsigned = (trio_uintmax_t)va_arg(*arglist, int);
else
{
if (parameters[i].type == FORMAT_CHAR)
@@ -1811,56 +2061,52 @@ TrioParse(int type,
*/
if (parameters[i].flags & FLAGS_USER_DEFINED)
parameters[i].data.pointer = (argarray == NULL)
- ? va_arg(arglist, void *)
+ ? va_arg(*arglist, trio_pointer_t )
: argarray[num];
else
parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(arglist, int)
+ ? (trio_uintmax_t)va_arg(*arglist, int)
: (trio_uintmax_t)(*((int *)argarray[num]));
break;
case FORMAT_DOUBLE:
if (TYPE_SCAN == type)
{
- if (parameters[i].flags & FLAGS_LONG)
+ if (parameters[i].flags & FLAGS_LONGDOUBLE)
parameters[i].data.longdoublePointer = (argarray == NULL)
- ? va_arg(arglist, long double *)
- : (long double *)((long double *)argarray[num]);
+ ? va_arg(*arglist, trio_long_double_t *)
+ : (trio_long_double_t *)argarray[num];
else
{
- if (argarray == NULL)
- parameters[i].data.doublePointer =
- va_arg(arglist, double *);
- else
- {
- if (parameters[i].flags & FLAGS_SHORT)
- parameters[i].data.doublePointer =
- (double *)((float *)argarray[num]);
- else
- parameters[i].data.doublePointer =
- (double *)((double *)argarray[num]);
- }
+ if (parameters[i].flags & FLAGS_LONG)
+ parameters[i].data.doublePointer = (argarray == NULL)
+ ? va_arg(*arglist, double *)
+ : (double *)argarray[num];
+ else
+ parameters[i].data.doublePointer = (argarray == NULL)
+ ? (double *)va_arg(*arglist, float *)
+ : (double *)((float *)argarray[num]);
}
}
else
{
- if (parameters[i].flags & FLAGS_LONG)
+ if (parameters[i].flags & FLAGS_LONGDOUBLE)
parameters[i].data.longdoubleNumber = (argarray == NULL)
- ? va_arg(arglist, long double)
- : (long double)(*((long double *)argarray[num]));
+ ? va_arg(*arglist, trio_long_double_t)
+ : (trio_long_double_t)(*((trio_long_double_t *)argarray[num]));
else
{
if (argarray == NULL)
parameters[i].data.longdoubleNumber =
- (long double)va_arg(arglist, double);
+ (trio_long_double_t)va_arg(*arglist, double);
else
{
if (parameters[i].flags & FLAGS_SHORT)
parameters[i].data.longdoubleNumber =
- (long double)(*((float *)argarray[num]));
+ (trio_long_double_t)(*((float *)argarray[num]));
else
parameters[i].data.longdoubleNumber =
- (long double)(long double)(*((double *)argarray[num]));
+ (trio_long_double_t)(*((double *)argarray[num]));
}
}
}
@@ -1868,7 +2114,7 @@ TrioParse(int type,
#if defined(FORMAT_ERRNO)
case FORMAT_ERRNO:
- parameters[i].data.errorNumber = errno;
+ parameters[i].data.errorNumber = save_errno;
break;
#endif
@@ -1896,12 +2142,14 @@ TrioParse(int type,
* of the dependencies of the flags.
*/
TRIO_PRIVATE void
-TrioWriteNumber(trio_class_t *self,
- trio_uintmax_t number,
- unsigned long flags,
- int width,
- int precision,
- int base)
+TrioWriteNumber
+TRIO_ARGS6((self, number, flags, width, precision, base),
+ trio_class_t *self,
+ trio_uintmax_t number,
+ unsigned long flags,
+ int width,
+ int precision,
+ int base)
{
BOOLEAN_T isNegative;
char buffer[MAX_CHARS_IN(trio_uintmax_t) * (1 + MAX_LOCALE_SEPARATOR_LENGTH) + 1];
@@ -1911,8 +2159,6 @@ TrioWriteNumber(trio_class_t *self,
int i;
int length;
char *p;
- int charsPerThousand;
- int groupingIndex;
int count;
assert(VALID(self));
@@ -1920,12 +2166,14 @@ TrioWriteNumber(trio_class_t *self,
assert(((base >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE));
digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower;
+ if (base == NO_BASE)
+ base = BASE_DECIMAL;
isNegative = (flags & FLAGS_UNSIGNED)
? FALSE
: ((trio_intmax_t)number < 0);
if (isNegative)
- number = -number;
+ number = -((trio_intmax_t)number);
if (flags & FLAGS_QUAD)
number &= (trio_ulonglong_t)-1;
@@ -1937,8 +2185,6 @@ TrioWriteNumber(trio_class_t *self,
/* Build number */
pointer = bufferend = &buffer[sizeof(buffer) - 1];
*pointer-- = NIL;
- charsPerThousand = (int)internalGrouping[0];
- groupingIndex = 1;
for (i = 1; i < (int)sizeof(buffer); i++)
{
*pointer-- = digits[number % base];
@@ -1946,35 +2192,20 @@ TrioWriteNumber(trio_class_t *self,
if (number == 0)
break;
- if ((flags & FLAGS_QUOTE)
- && (charsPerThousand != NO_GROUPING)
- && (i % charsPerThousand == 0))
+ if ((flags & FLAGS_QUOTE) && TrioFollowedBySeparator(i + 1))
{
/*
* We are building the number from the least significant
* to the most significant digit, so we have to copy the
* thousand separator backwards
*/
- length = trio_length(internalThousandSeparator);
+ length = internalThousandSeparatorLength;
if (((int)(pointer - buffer) - length) > 0)
{
p = &internalThousandSeparator[length - 1];
while (length-- > 0)
*pointer-- = *p--;
}
-
- /* Advance to next grouping number */
- switch (internalGrouping[groupingIndex])
- {
- case CHAR_MAX: /* Disable grouping */
- charsPerThousand = NO_GROUPING;
- break;
- case 0: /* Repeat last group */
- break;
- default:
- charsPerThousand = (int)internalGrouping[groupingIndex++];
- break;
- }
}
}
@@ -2082,13 +2313,15 @@ TrioWriteNumber(trio_class_t *self,
* Output a single character of a string
*/
TRIO_PRIVATE void
-TrioWriteStringCharacter(trio_class_t *self,
- int ch,
- unsigned long flags)
+TrioWriteStringCharacter
+TRIO_ARGS3((self, ch, flags),
+ trio_class_t *self,
+ int ch,
+ unsigned long flags)
{
if (flags & FLAGS_ALTERNATIVE)
{
- if (! (isprint(ch) || isspace(ch)))
+ if (! isprint(ch))
{
/*
* Non-printable characters are converted to C escapes or
@@ -2107,7 +2340,7 @@ TrioWriteStringCharacter(trio_class_t *self,
case '\\': self->OutStream(self, '\\'); break;
default:
self->OutStream(self, 'x');
- TrioWriteNumber(self, (trio_intmax_t)ch,
+ TrioWriteNumber(self, (trio_uintmax_t)ch,
FLAGS_UNSIGNED | FLAGS_NILPADDING,
2, 2, BASE_HEX);
break;
@@ -2136,11 +2369,13 @@ TrioWriteStringCharacter(trio_class_t *self,
* Output a string
*/
TRIO_PRIVATE void
-TrioWriteString(trio_class_t *self,
- TRIO_CONST char *string,
- unsigned long flags,
- int width,
- int precision)
+TrioWriteString
+TRIO_ARGS5((self, string, flags, width, precision),
+ trio_class_t *self,
+ TRIO_CONST char *string,
+ unsigned long flags,
+ int width,
+ int precision)
{
int length;
int ch;
@@ -2200,10 +2435,12 @@ TrioWriteString(trio_class_t *self,
*/
#if TRIO_WIDECHAR
TRIO_PRIVATE int
-TrioWriteWideStringCharacter(trio_class_t *self,
- wchar_t wch,
- unsigned long flags,
- int width)
+TrioWriteWideStringCharacter
+TRIO_ARGS4((self, wch, flags, width),
+ trio_class_t *self,
+ trio_wchar_t wch,
+ unsigned long flags,
+ int width)
{
int size;
int i;
@@ -2238,11 +2475,13 @@ TrioWriteWideStringCharacter(trio_class_t *self,
*/
#if TRIO_WIDECHAR
TRIO_PRIVATE void
-TrioWriteWideString(trio_class_t *self,
- TRIO_CONST wchar_t *wstring,
- unsigned long flags,
- int width,
- int precision)
+TrioWriteWideString
+TRIO_ARGS5((self, wstring, flags, width, precision),
+ trio_class_t *self,
+ TRIO_CONST trio_wchar_t *wstring,
+ unsigned long flags,
+ int width,
+ int precision)
{
int length;
int size;
@@ -2251,7 +2490,7 @@ TrioWriteWideString(trio_class_t *self,
assert(VALID(self->OutStream));
#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- mblen(NULL, 0);
+ (void)mblen(NULL, 0);
#endif
if (wstring == NULL)
@@ -2299,100 +2538,155 @@ TrioWriteWideString(trio_class_t *self,
/*************************************************************************
* TrioWriteDouble
+ *
+ * http://wwwold.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_211.htm
+ *
+ * "5.2.4.2.2 paragraph #4
+ *
+ * The accuracy [...] is implementation defined, as is the accuracy
+ * of the conversion between floating-point internal representations
+ * and string representations performed by the libray routine in
+ * <stdio.h>"
+ */
+/* FIXME: handle all instances of constant long-double number (L)
+ * and *l() math functions.
*/
TRIO_PRIVATE void
-TrioWriteDouble(trio_class_t *self,
- long double longdoubleNumber,
- unsigned long flags,
- int width,
- int precision,
- int base)
-{
- int charsPerThousand;
- int length;
- double number;
- double workNumber;
+TrioWriteDouble
+TRIO_ARGS6((self, number, flags, width, precision, base),
+ trio_class_t *self,
+ trio_long_double_t number,
+ unsigned long flags,
+ int width,
+ int precision,
+ int base)
+{
+ trio_long_double_t integerNumber;
+ trio_long_double_t fractionNumber;
+ trio_long_double_t workNumber;
int integerDigits;
int fractionDigits;
int exponentDigits;
+ int baseDigits;
+ int integerThreshold;
+ int fractionThreshold;
int expectedWidth;
- int exponent;
+ int exponent = 0;
unsigned int uExponent = 0;
- double dblBase;
+ int exponentBase;
+ trio_long_double_t dblBase;
+ trio_long_double_t dblIntegerBase;
+ trio_long_double_t dblFractionBase;
+ trio_long_double_t integerAdjust;
+ trio_long_double_t fractionAdjust;
BOOLEAN_T isNegative;
BOOLEAN_T isExponentNegative = FALSE;
+ BOOLEAN_T requireTwoDigitExponent;
BOOLEAN_T isHex;
TRIO_CONST char *digits;
- char numberBuffer[MAX_MANTISSA_DIGITS
- * (1 + MAX_LOCALE_SEPARATOR_LENGTH) + 1];
- char *numberPointer;
- char exponentBuffer[MAX_EXPONENT_DIGITS + 1];
- char *exponentPointer = NULL;
- int groupingIndex;
- char *work;
+ char *groupingPointer;
int i;
- BOOLEAN_T onlyzero;
+ int index;
+ BOOLEAN_T hasOnlyZeroes;
int zeroes = 0;
+ register int trailingZeroes;
+ BOOLEAN_T keepTrailingZeroes;
+ BOOLEAN_T keepDecimalPoint;
+ trio_long_double_t epsilon;
assert(VALID(self));
assert(VALID(self->OutStream));
- assert(base == BASE_DECIMAL || base == BASE_HEX);
+ assert(((base >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE));
- number = (double)longdoubleNumber;
-
- /* Look for infinite numbers and non-a-number first */
- switch (trio_isinf(number))
+ /* Determine sign and look for special quantities */
+ switch (trio_fpclassify_and_signbit(number, &isNegative))
{
- case 1:
- /* Positive infinity */
+ case TRIO_FP_NAN:
TrioWriteString(self,
(flags & FLAGS_UPPER)
- ? INFINITE_UPPER
- : INFINITE_LOWER,
- flags, width, precision);
- return;
-
- case -1:
- /* Negative infinity */
- TrioWriteString(self,
- (flags & FLAGS_UPPER)
- ? "-" INFINITE_UPPER
- : "-" INFINITE_LOWER,
+ ? NAN_UPPER
+ : NAN_LOWER,
flags, width, precision);
return;
+
+ case TRIO_FP_INFINITE:
+ if (isNegative)
+ {
+ /* Negative infinity */
+ TrioWriteString(self,
+ (flags & FLAGS_UPPER)
+ ? "-" INFINITE_UPPER
+ : "-" INFINITE_LOWER,
+ flags, width, precision);
+ return;
+ }
+ else
+ {
+ /* Positive infinity */
+ TrioWriteString(self,
+ (flags & FLAGS_UPPER)
+ ? INFINITE_UPPER
+ : INFINITE_LOWER,
+ flags, width, precision);
+ return;
+ }
default:
/* Finitude */
break;
}
- if (trio_isnan(number))
+
+ /* Normal numbers */
+ if (flags & FLAGS_LONGDOUBLE)
{
- TrioWriteString(self,
- (flags & FLAGS_UPPER)
- ? NAN_UPPER
- : NAN_LOWER,
- flags, width, precision);
- return;
+ baseDigits = (base == 10)
+ ? LDBL_DIG
+ : (int)floor(LDBL_MANT_DIG / TrioLogarithmBase(base));
+ epsilon = LDBL_EPSILON;
+ }
+ else if (flags & FLAGS_SHORT)
+ {
+ baseDigits = (base == BASE_DECIMAL)
+ ? FLT_DIG
+ : (int)floor(FLT_MANT_DIG / TrioLogarithmBase(base));
+ epsilon = FLT_EPSILON;
+ }
+ else
+ {
+ baseDigits = (base == BASE_DECIMAL)
+ ? DBL_DIG
+ : (int)floor(DBL_MANT_DIG / TrioLogarithmBase(base));
+ epsilon = DBL_EPSILON;
}
- /* Normal numbers */
digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower;
isHex = (base == BASE_HEX);
- dblBase = (double)base;
+ if (base == NO_BASE)
+ base = BASE_DECIMAL;
+ dblBase = (trio_long_double_t)base;
+ keepTrailingZeroes = !( (flags & FLAGS_ROUNDING) ||
+ ( (flags & FLAGS_FLOAT_G) &&
+ !(flags & FLAGS_ALTERNATIVE) ) );
+
+ if (flags & FLAGS_ROUNDING)
+ precision = baseDigits;
if (precision == NO_PRECISION)
precision = FLT_DIG;
- isNegative = (number < 0.0);
if (isNegative)
number = -number;
- if ((flags & FLAGS_FLOAT_G) || isHex)
+ if (isHex)
+ flags |= FLAGS_FLOAT_E;
+
+ if (flags & FLAGS_FLOAT_G)
{
if (precision == 0)
precision = 1;
- if ((number < 1.0e-4) || (number > pow(10.0, (double)precision)))
+ if ((number < 1.0E-4) || (number > powl(base,
+ (trio_long_double_t)precision)))
{
/* Use scientific notation */
flags |= FLAGS_FLOAT_E;
@@ -2404,17 +2698,18 @@ TrioWriteDouble(trio_class_t *self,
* zero, then adjust the precision to include leading fractional
* zeros.
*/
- workNumber = fabs(guarded_log10(number));
- if (workNumber - floor(workNumber) < 0.001)
+ workNumber = TrioLogarithm(number, base);
+ workNumber = TRIO_FABS(workNumber);
+ if (workNumber - floorl(workNumber) < 0.001)
workNumber--;
- zeroes = (int)floor(workNumber);
+ zeroes = (int)floorl(workNumber);
}
}
if (flags & FLAGS_FLOAT_E)
{
/* Scale the number */
- workNumber = guarded_log10(number);
+ workNumber = TrioLogarithm(number, base);
if (trio_isinf(workNumber) == -1)
{
exponent = 0;
@@ -2424,8 +2719,8 @@ TrioWriteDouble(trio_class_t *self,
}
else
{
- exponent = (int)floor(workNumber);
- number /= pow(10.0, (double)exponent);
+ exponent = (int)floorl(workNumber);
+ number /= powl(dblBase, (trio_long_double_t)exponent);
isExponentNegative = (exponent < 0);
uExponent = (isExponentNegative) ? -exponent : exponent;
/* No thousand separators */
@@ -2433,140 +2728,107 @@ TrioWriteDouble(trio_class_t *self,
}
}
+ integerNumber = floorl(number);
+ fractionNumber = number - integerNumber;
+
/*
* Truncated number.
*
- * precision is number of significant digits for FLOAT_G
- * and number of fractional digits for others
+ * Precision is number of significant digits for FLOAT_G
+ * and number of fractional digits for others.
*/
- integerDigits = (floor(number) > DBL_EPSILON)
- ? 1 + (int)guarded_log10(floor(number))
+ integerDigits = (integerNumber > epsilon)
+ ? 1 + (int)TrioLogarithm(integerNumber, base)
: 1;
fractionDigits = ((flags & FLAGS_FLOAT_G) && (zeroes == 0))
? precision - integerDigits
: zeroes + precision;
+
+ dblFractionBase = TrioPower(base, fractionDigits);
- number = floor(0.5 + number * pow(dblBase, (double)fractionDigits));
- workNumber = (isHex
- ? guarded_log16(0.5 + number)
- : guarded_log10(0.5 + number));
- if ((int)workNumber + 1 > integerDigits + fractionDigits)
+ workNumber = number + 0.5 / dblFractionBase;
+ if (floorl(number) != floorl(workNumber))
{
if (flags & FLAGS_FLOAT_E)
{
/* Adjust if number was rounded up one digit (ie. 0.99 to 1.00) */
- exponent--;
- uExponent -= (isExponentNegative) ? 1 : -1;
- number /= dblBase;
+ exponent++;
+ isExponentNegative = (exponent < 0);
+ uExponent = (isExponentNegative) ? -exponent : exponent;
+ workNumber = (number + 0.5 / dblFractionBase) / dblBase;
+ integerNumber = floorl(workNumber);
+ fractionNumber = workNumber - integerNumber;
}
else
{
/* Adjust if number was rounded up one digit (ie. 99 to 100) */
- integerDigits++;
+ integerNumber = floorl(number + 0.5);
+ fractionNumber = 0.0;
+ integerDigits = (integerNumber > epsilon)
+ ? 1 + (int)TrioLogarithm(integerNumber, base)
+ : 1;
}
}
-
- /* Build the fraction part */
- numberPointer = &numberBuffer[sizeof(numberBuffer) - 1];
- *numberPointer = NIL;
- onlyzero = TRUE;
- for (i = 0; i < fractionDigits; i++)
- {
- *(--numberPointer) = digits[(int)fmod(number, dblBase)];
- number = floor(number / dblBase);
-
- if ((flags & FLAGS_FLOAT_G) && !(flags & FLAGS_ALTERNATIVE))
- {
- /* Prune trailing zeroes */
- if (numberPointer[0] != digits[0])
- onlyzero = FALSE;
- else if (onlyzero && (numberPointer[0] == digits[0]))
- numberPointer++;
- }
- else
- onlyzero = FALSE;
- }
-
- /* Insert decimal point */
- if ((flags & FLAGS_ALTERNATIVE) || ((fractionDigits > 0) && !onlyzero))
+
+ /* Estimate accuracy */
+ integerAdjust = fractionAdjust = 0.5;
+ if (flags & FLAGS_ROUNDING)
{
- i = trio_length(internalDecimalPoint);
- while (i> 0)
+ if (integerDigits > baseDigits)
{
- *(--numberPointer) = internalDecimalPoint[--i];
+ integerThreshold = baseDigits;
+ fractionDigits = 0;
+ dblFractionBase = 1.0;
+ fractionThreshold = 0;
+ precision = 0; /* Disable decimal-point */
+ integerAdjust = TrioPower(base, integerDigits - integerThreshold - 1);
+ fractionAdjust = 0.0;
}
- }
- /* Insert the integer part and thousand separators */
- charsPerThousand = (int)internalGrouping[0];
- groupingIndex = 1;
- for (i = 1; i < integerDigits + 1; i++)
- {
- *(--numberPointer) = digits[(int)fmod(number, dblBase)];
- number = floor(number / dblBase);
- if (number < DBL_EPSILON)
- break;
-
- if ((i > 0)
- && ((flags & (FLAGS_FLOAT_E | FLAGS_QUOTE)) == FLAGS_QUOTE)
- && (charsPerThousand != NO_GROUPING)
- && (i % charsPerThousand == 0))
+ else
{
- /*
- * We are building the number from the least significant
- * to the most significant digit, so we have to copy the
- * thousand separator backwards
- */
- length = trio_length(internalThousandSeparator);
- integerDigits += length;
- if (((int)(numberPointer - numberBuffer) - length) > 0)
- {
- work = &internalThousandSeparator[length - 1];
- while (length-- > 0)
- *(--numberPointer) = *work--;
- }
-
- /* Advance to next grouping number */
- if (charsPerThousand != NO_GROUPING)
- {
- switch (internalGrouping[groupingIndex])
- {
- case CHAR_MAX: /* Disable grouping */
- charsPerThousand = NO_GROUPING;
- break;
- case 0: /* Repeat last group */
- break;
- default:
- charsPerThousand = (int)internalGrouping[groupingIndex++];
- break;
- }
- }
+ integerThreshold = integerDigits;
+ fractionThreshold = fractionDigits - integerThreshold;
+ fractionAdjust = 1.0;
}
}
-
- /* Build the exponent */
- exponentDigits = 0;
- if (flags & FLAGS_FLOAT_E)
+ else
{
- exponentPointer = &exponentBuffer[sizeof(exponentBuffer) - 1];
- *exponentPointer-- = NIL;
- do {
- *exponentPointer-- = digits[uExponent % base];
- uExponent /= base;
- exponentDigits++;
- } while (uExponent);
+ integerThreshold = INT_MAX;
+ fractionThreshold = INT_MAX;
}
-
+
/*
* Calculate expected width.
* sign + integer part + thousands separators + decimal point
* + fraction + exponent
*/
- expectedWidth = trio_length(numberPointer);
- if (isNegative || (flags & FLAGS_SHOWSIGN))
+ fractionAdjust /= dblFractionBase;
+ hasOnlyZeroes = (floorl((fractionNumber + fractionAdjust) * dblFractionBase) < epsilon);
+ keepDecimalPoint = ( (flags & FLAGS_ALTERNATIVE) ||
+ !((precision == 0) ||
+ (!keepTrailingZeroes && hasOnlyZeroes)) );
+ if (flags & FLAGS_FLOAT_E)
+ {
+ exponentDigits = (uExponent == 0)
+ ? 1
+ : (int)ceil(TrioLogarithm((double)(uExponent + 1), base));
+ }
+ else
+ exponentDigits = 0;
+ requireTwoDigitExponent = ((base == BASE_DECIMAL) && (exponentDigits == 1));
+
+ expectedWidth = integerDigits + fractionDigits
+ + (keepDecimalPoint
+ ? internalDecimalPointLength
+ : 0)
+ + ((flags & FLAGS_QUOTE)
+ ? TrioCalcThousandSeparatorLength(integerDigits)
+ : 0);
+ if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE))
expectedWidth += sizeof("-") - 1;
if (exponentDigits > 0)
expectedWidth += exponentDigits +
- ((exponentDigits > 1) ? sizeof("E+") : sizeof("E+0")) - 1;
+ ((requireTwoDigitExponent ? sizeof("E+0") : sizeof("E+")) - 1);
if (isHex)
expectedWidth += sizeof("0X") - 1;
@@ -2578,6 +2840,8 @@ TrioWriteDouble(trio_class_t *self,
self->OutStream(self, '-');
else if (flags & FLAGS_SHOWSIGN)
self->OutStream(self, '+');
+ else if (flags & FLAGS_SPACE)
+ self->OutStream(self, ' ');
if (isHex)
{
self->OutStream(self, '0');
@@ -2605,17 +2869,101 @@ TrioWriteDouble(trio_class_t *self,
self->OutStream(self, '-');
else if (flags & FLAGS_SHOWSIGN)
self->OutStream(self, '+');
+ else if (flags & FLAGS_SPACE)
+ self->OutStream(self, ' ');
if (isHex)
{
self->OutStream(self, '0');
self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x');
}
}
- /* Output number */
- for (i = 0; numberPointer[i]; i++)
+
+ /* Output the integer part and thousand separators */
+ dblIntegerBase = 1.0 / TrioPower(base, integerDigits - 1);
+ for (i = 0; i < integerDigits; i++)
+ {
+ workNumber = floorl(((integerNumber + integerAdjust) * dblIntegerBase));
+ if (i > integerThreshold)
+ {
+ /* Beyond accuracy */
+ self->OutStream(self, digits[0]);
+ }
+ else
+ {
+ self->OutStream(self, digits[(int)fmodl(workNumber, dblBase)]);
+ }
+ dblIntegerBase *= dblBase;
+
+ if (((flags & (FLAGS_FLOAT_E | FLAGS_QUOTE)) == FLAGS_QUOTE)
+ && TrioFollowedBySeparator(integerDigits - i))
+ {
+ for (groupingPointer = internalThousandSeparator;
+ *groupingPointer != NIL;
+ groupingPointer++)
+ {
+ self->OutStream(self, *groupingPointer);
+ }
+ }
+ }
+
+ /* Insert decimal point and build the fraction part */
+ trailingZeroes = 0;
+
+ if (keepDecimalPoint)
+ {
+ if (internalDecimalPoint)
+ {
+ self->OutStream(self, internalDecimalPoint);
+ }
+ else
+ {
+ for (i = 0; i < internalDecimalPointLength; i++)
+ {
+ self->OutStream(self, internalDecimalPointString[i]);
+ }
+ }
+ }
+
+ for (i = 0; i < fractionDigits; i++)
+ {
+ if ((integerDigits > integerThreshold) || (i > fractionThreshold))
+ {
+ /* Beyond accuracy */
+ trailingZeroes++;
+ }
+ else
+ {
+ fractionNumber *= dblBase;
+ fractionAdjust *= dblBase;
+ workNumber = floorl(fractionNumber + fractionAdjust);
+ fractionNumber -= workNumber;
+ index = (int)fmodl(workNumber, dblBase);
+ if (index == 0)
+ {
+ trailingZeroes++;
+ }
+ else
+ {
+ while (trailingZeroes > 0)
+ {
+ /* Not trailing zeroes after all */
+ self->OutStream(self, digits[0]);
+ trailingZeroes--;
+ }
+ self->OutStream(self, digits[index]);
+ }
+ }
+ }
+
+ if (keepTrailingZeroes)
{
- self->OutStream(self, numberPointer[i]);
+ while (trailingZeroes > 0)
+ {
+ self->OutStream(self, digits[0]);
+ trailingZeroes--;
+ }
}
+
/* Output exponent */
if (exponentDigits > 0)
{
@@ -2626,12 +2974,14 @@ TrioWriteDouble(trio_class_t *self,
self->OutStream(self, (isExponentNegative) ? '-' : '+');
/* The exponent must contain at least two digits */
- if (exponentDigits == 1)
+ if (requireTwoDigitExponent)
self->OutStream(self, '0');
+ exponentBase = (int)TrioPower(base, exponentDigits - 1);
for (i = 0; i < exponentDigits; i++)
{
- self->OutStream(self, exponentPointer[i + 1]);
+ self->OutStream(self, digits[(uExponent / exponentBase) % base]);
+ exponentBase /= base;
}
}
/* Output trailing spaces */
@@ -2651,17 +3001,18 @@ TrioWriteDouble(trio_class_t *self,
* This is the main engine for formatting output
*/
TRIO_PRIVATE int
-TrioFormatProcess(trio_class_t *data,
- TRIO_CONST char *format,
- trio_parameter_t *parameters)
-
+TrioFormatProcess
+TRIO_ARGS3((data, format, parameters),
+ trio_class_t *data,
+ TRIO_CONST char *format,
+ trio_parameter_t *parameters)
{
#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
int charlen;
#endif
int i;
TRIO_CONST char *string;
- void *pointer;
+ trio_pointer_t pointer;
unsigned long flags;
int width;
int precision;
@@ -2671,7 +3022,7 @@ TrioFormatProcess(trio_class_t *data,
index = 0;
i = 0;
#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- mblen(NULL, 0);
+ (void)mblen(NULL, 0);
#endif
while (format[index])
@@ -2680,11 +3031,19 @@ TrioFormatProcess(trio_class_t *data,
if (! isascii(format[index]))
{
charlen = mblen(&format[index], MB_LEN_MAX);
- while (charlen-- > 0)
+ /*
+ * Only valid multibyte characters are handled here. Invalid
+ * multibyte characters (charlen == -1) are handled as normal
+ * characters.
+ */
+ if (charlen != -1)
{
- data->OutStream(data, format[index++]);
+ while (charlen-- > 0)
+ {
+ data->OutStream(data, format[index++]);
+ }
+ continue; /* while characters left in formatting string */
}
- continue; /* while */
}
#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */
if (CHAR_IDENTIFIER == format[index])
@@ -2747,7 +3106,7 @@ TrioFormatProcess(trio_class_t *data,
if (flags & FLAGS_WIDECHAR)
{
TrioWriteWideStringCharacter(data,
- (wchar_t)parameters[i].data.number.as_signed,
+ (trio_wchar_t)parameters[i].data.number.as_signed,
flags,
NO_WIDTH);
}
@@ -2770,11 +3129,8 @@ TrioFormatProcess(trio_class_t *data,
break; /* FORMAT_CHAR */
case FORMAT_INT:
- if (base == NO_BASE)
- base = BASE_DECIMAL;
-
TrioWriteNumber(data,
- parameters[i].data.number.as_signed,
+ parameters[i].data.number.as_unsigned,
flags,
width,
precision,
@@ -2883,7 +3239,7 @@ TrioFormatProcess(trio_class_t *data,
{
data->OutStream(data, '#');
TrioWriteNumber(data,
- (trio_intmax_t)parameters[i].data.errorNumber,
+ (trio_uintmax_t)parameters[i].data.errorNumber,
flags,
width,
precision,
@@ -2940,10 +3296,12 @@ TrioFormatProcess(trio_class_t *data,
* TrioFormatRef
*/
TRIO_PRIVATE int
-TrioFormatRef(trio_reference_t *reference,
- TRIO_CONST char *format,
- va_list arglist,
- void **argarray)
+TrioFormatRef
+TRIO_ARGS4((reference, format, arglist, argarray),
+ trio_reference_t *reference,
+ TRIO_CONST char *format,
+ va_list *arglist,
+ trio_pointer_t *argarray)
{
int status;
trio_parameter_t parameters[MAX_PARAMETERS];
@@ -2964,12 +3322,14 @@ TrioFormatRef(trio_reference_t *reference,
* TrioFormat
*/
TRIO_PRIVATE int
-TrioFormat(void *destination,
+TrioFormat
+TRIO_ARGS6((destination, destinationSize, OutStream, format, arglist, argarray),
+ trio_pointer_t destination,
size_t destinationSize,
- void (*OutStream)(trio_class_t *, int),
+ void (*OutStream) TRIO_PROTO((trio_class_t *, int)),
TRIO_CONST char *format,
- va_list arglist,
- void **argarray)
+ va_list *arglist,
+ trio_pointer_t *argarray)
{
int status;
trio_class_t data;
@@ -3007,14 +3367,17 @@ TrioFormat(void *destination,
* TrioOutStreamFile
*/
TRIO_PRIVATE void
-TrioOutStreamFile(trio_class_t *self,
- int output)
+TrioOutStreamFile
+TRIO_ARGS2((self, output),
+ trio_class_t *self,
+ int output)
{
- FILE *file = (FILE *)self->location;
+ FILE *file;
assert(VALID(self));
- assert(VALID(file));
+ assert(VALID(self->location));
+ file = (FILE *)self->location;
self->processed++;
if (fputc(output, file) == EOF)
{
@@ -3030,14 +3393,17 @@ TrioOutStreamFile(trio_class_t *self,
* TrioOutStreamFileDescriptor
*/
TRIO_PRIVATE void
-TrioOutStreamFileDescriptor(trio_class_t *self,
- int output)
+TrioOutStreamFileDescriptor
+TRIO_ARGS2((self, output),
+ trio_class_t *self,
+ int output)
{
- int fd = *((int *)self->location);
+ int fd;
char ch;
assert(VALID(self));
+ fd = *((int *)self->location);
ch = (char)output;
self->processed++;
if (write(fd, &ch, sizeof(char)) == -1)
@@ -3051,17 +3417,54 @@ TrioOutStreamFileDescriptor(trio_class_t *self,
}
/*************************************************************************
+ * TrioOutStreamCustom
+ */
+TRIO_PRIVATE void
+TrioOutStreamCustom
+TRIO_ARGS2((self, output),
+ trio_class_t *self,
+ int output)
+{
+ int status;
+ trio_custom_t *data;
+
+ assert(VALID(self));
+ assert(VALID(self->location));
+
+ data = (trio_custom_t *)self->location;
+ if (data->stream.out)
+ {
+ status = (data->stream.out)(data->closure, output);
+ if (status >= 0)
+ {
+ self->committed++;
+ }
+ else
+ {
+ if (self->error == 0)
+ {
+ self->error = TRIO_ERROR_RETURN(TRIO_ECUSTOM, -status);
+ }
+ }
+ }
+ self->processed++;
+}
+
+/*************************************************************************
* TrioOutStreamString
*/
TRIO_PRIVATE void
-TrioOutStreamString(trio_class_t *self,
- int output)
+TrioOutStreamString
+TRIO_ARGS2((self, output),
+ trio_class_t *self,
+ int output)
{
- char **buffer = (char **)self->location;
+ char **buffer;
assert(VALID(self));
- assert(VALID(buffer));
+ assert(VALID(self->location));
+ buffer = (char **)self->location;
**buffer = (char)output;
(*buffer)++;
self->processed++;
@@ -3072,14 +3475,17 @@ TrioOutStreamString(trio_class_t *self,
* TrioOutStreamStringMax
*/
TRIO_PRIVATE void
-TrioOutStreamStringMax(trio_class_t *self,
- int output)
+TrioOutStreamStringMax
+TRIO_ARGS2((self, output),
+ trio_class_t *self,
+ int output)
{
char **buffer;
assert(VALID(self));
+ assert(VALID(self->location));
+
buffer = (char **)self->location;
- assert(VALID(buffer));
if (self->processed < self->max)
{
@@ -3094,8 +3500,10 @@ TrioOutStreamStringMax(trio_class_t *self,
* TrioOutStreamStringDynamic
*/
TRIO_PRIVATE void
-TrioOutStreamStringDynamic(trio_class_t *self,
- int output)
+TrioOutStreamStringDynamic
+TRIO_ARGS2((self, output),
+ trio_class_t *self,
+ int output)
{
assert(VALID(self));
assert(VALID(self->location));
@@ -3135,17 +3543,19 @@ TrioOutStreamStringDynamic(trio_class_t *self,
@return Number of printed characters.
*/
TRIO_PUBLIC int
-trio_printf(TRIO_CONST char *format,
- ...)
+trio_printf
+TRIO_VARGS2((format, va_alist),
+ TRIO_CONST char *format,
+ TRIO_VA_DECL)
{
int status;
va_list args;
assert(VALID(format));
- va_start(args, format);
- status = TrioFormat(stdout, 0, TrioOutStreamFile, format, args, NULL);
- va_end(args);
+ TRIO_VA_START(args, format);
+ status = TrioFormat(stdout, 0, TrioOutStreamFile, format, &args, NULL);
+ TRIO_VA_END(args);
return status;
}
@@ -3157,12 +3567,14 @@ trio_printf(TRIO_CONST char *format,
@return Number of printed characters.
*/
TRIO_PUBLIC int
-trio_vprintf(TRIO_CONST char *format,
- va_list args)
+trio_vprintf
+TRIO_ARGS2((format, args),
+ TRIO_CONST char *format,
+ va_list args)
{
assert(VALID(format));
- return TrioFormat(stdout, 0, TrioOutStreamFile, format, args, NULL);
+ return TrioFormat(stdout, 0, TrioOutStreamFile, format, &args, NULL);
}
/**
@@ -3173,14 +3585,14 @@ trio_vprintf(TRIO_CONST char *format,
@return Number of printed characters.
*/
TRIO_PUBLIC int
-trio_printfv(TRIO_CONST char *format,
- void ** args)
+trio_printfv
+TRIO_ARGS2((format, args),
+ TRIO_CONST char *format,
+ trio_pointer_t * args)
{
- va_list dummy;
-
assert(VALID(format));
- return TrioFormat(stdout, 0, TrioOutStreamFile, format, dummy, args);
+ return TrioFormat(stdout, 0, TrioOutStreamFile, format, NULL, args);
}
/*************************************************************************
@@ -3196,9 +3608,11 @@ trio_printfv(TRIO_CONST char *format,
@return Number of printed characters.
*/
TRIO_PUBLIC int
-trio_fprintf(FILE *file,
- TRIO_CONST char *format,
- ...)
+trio_fprintf
+TRIO_VARGS3((file, format, va_alist),
+ FILE *file,
+ TRIO_CONST char *format,
+ TRIO_VA_DECL)
{
int status;
va_list args;
@@ -3206,9 +3620,9 @@ trio_fprintf(FILE *file,
assert(VALID(file));
assert(VALID(format));
- va_start(args, format);
- status = TrioFormat(file, 0, TrioOutStreamFile, format, args, NULL);
- va_end(args);
+ TRIO_VA_START(args, format);
+ status = TrioFormat(file, 0, TrioOutStreamFile, format, &args, NULL);
+ TRIO_VA_END(args);
return status;
}
@@ -3221,14 +3635,16 @@ trio_fprintf(FILE *file,
@return Number of printed characters.
*/
TRIO_PUBLIC int
-trio_vfprintf(FILE *file,
- TRIO_CONST char *format,
- va_list args)
+trio_vfprintf
+TRIO_ARGS3((file, format, args),
+ FILE *file,
+ TRIO_CONST char *format,
+ va_list args)
{
assert(VALID(file));
assert(VALID(format));
- return TrioFormat(file, 0, TrioOutStreamFile, format, args, NULL);
+ return TrioFormat(file, 0, TrioOutStreamFile, format, &args, NULL);
}
/**
@@ -3240,16 +3656,16 @@ trio_vfprintf(FILE *file,
@return Number of printed characters.
*/
TRIO_PUBLIC int
-trio_fprintfv(FILE *file,
- TRIO_CONST char *format,
- void ** args)
+trio_fprintfv
+TRIO_ARGS3((file, format, args),
+ FILE *file,
+ TRIO_CONST char *format,
+ trio_pointer_t * args)
{
- va_list dummy;
-
assert(VALID(file));
assert(VALID(format));
- return TrioFormat(file, 0, TrioOutStreamFile, format, dummy, args);
+ return TrioFormat(file, 0, TrioOutStreamFile, format, NULL, args);
}
/*************************************************************************
@@ -3265,18 +3681,20 @@ trio_fprintfv(FILE *file,
@return Number of printed characters.
*/
TRIO_PUBLIC int
-trio_dprintf(int fd,
- TRIO_CONST char *format,
- ...)
+trio_dprintf
+TRIO_VARGS3((fd, format, va_alist),
+ int fd,
+ TRIO_CONST char *format,
+ TRIO_VA_DECL)
{
int status;
va_list args;
assert(VALID(format));
- va_start(args, format);
- status = TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, args, NULL);
- va_end(args);
+ TRIO_VA_START(args, format);
+ status = TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, &args, NULL);
+ TRIO_VA_END(args);
return status;
}
@@ -3289,13 +3707,15 @@ trio_dprintf(int fd,
@return Number of printed characters.
*/
TRIO_PUBLIC int
-trio_vdprintf(int fd,
- TRIO_CONST char *format,
- va_list args)
+trio_vdprintf
+TRIO_ARGS3((fd, format, args),
+ int fd,
+ TRIO_CONST char *format,
+ va_list args)
{
assert(VALID(format));
- return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, args, NULL);
+ return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, &args, NULL);
}
/**
@@ -3307,15 +3727,77 @@ trio_vdprintf(int fd,
@return Number of printed characters.
*/
TRIO_PUBLIC int
-trio_dprintfv(int fd,
- TRIO_CONST char *format,
- void **args)
+trio_dprintfv
+TRIO_ARGS3((fd, format, args),
+ int fd,
+ TRIO_CONST char *format,
+ trio_pointer_t *args)
{
- va_list dummy;
-
assert(VALID(format));
- return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, dummy, args);
+ return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, NULL, args);
+}
+
+/*************************************************************************
+ * cprintf
+ */
+TRIO_PUBLIC int
+trio_cprintf
+TRIO_VARGS4((stream, closure, format, va_alist),
+ trio_outstream_t stream,
+ trio_pointer_t closure,
+ TRIO_CONST char *format,
+ TRIO_VA_DECL)
+{
+ int status;
+ va_list args;
+ trio_custom_t data;
+
+ assert(VALID(stream));
+ assert(VALID(format));
+
+ TRIO_VA_START(args, format);
+ data.stream.out = stream;
+ data.closure = closure;
+ status = TrioFormat(&data, 0, TrioOutStreamCustom, format, &args, NULL);
+ TRIO_VA_END(args);
+ return status;
+}
+
+TRIO_PUBLIC int
+trio_vcprintf
+TRIO_ARGS4((stream, closure, format, args),
+ trio_outstream_t stream,
+ trio_pointer_t closure,
+ TRIO_CONST char *format,
+ va_list args)
+{
+ trio_custom_t data;
+
+ assert(VALID(stream));
+ assert(VALID(format));
+
+ data.stream.out = stream;
+ data.closure = closure;
+ return TrioFormat(&data, 0, TrioOutStreamCustom, format, &args, NULL);
+}
+
+TRIO_PUBLIC int
+trio_cprintfv
+TRIO_ARGS4((stream, closure, format, args),
+ trio_outstream_t stream,
+ trio_pointer_t closure,
+ TRIO_CONST char *format,
+ void **args)
+{
+ trio_custom_t data;
+
+ assert(VALID(stream));
+ assert(VALID(format));
+
+ data.stream.out = stream;
+ data.closure = closure;
+ return TrioFormat(&data, 0, TrioOutStreamCustom, format, NULL, args);
}
/*************************************************************************
@@ -3331,9 +3813,11 @@ trio_dprintfv(int fd,
@return Number of printed characters.
*/
TRIO_PUBLIC int
-trio_sprintf(char *buffer,
- TRIO_CONST char *format,
- ...)
+trio_sprintf
+TRIO_VARGS3((buffer, format, va_alist),
+ char *buffer,
+ TRIO_CONST char *format,
+ TRIO_VA_DECL)
{
int status;
va_list args;
@@ -3341,10 +3825,10 @@ trio_sprintf(char *buffer,
assert(VALID(buffer));
assert(VALID(format));
- va_start(args, format);
- status = TrioFormat(&buffer, 0, TrioOutStreamString, format, args, NULL);
+ TRIO_VA_START(args, format);
+ status = TrioFormat(&buffer, 0, TrioOutStreamString, format, &args, NULL);
*buffer = NIL; /* Terminate with NIL character */
- va_end(args);
+ TRIO_VA_END(args);
return status;
}
@@ -3357,16 +3841,18 @@ trio_sprintf(char *buffer,
@return Number of printed characters.
*/
TRIO_PUBLIC int
-trio_vsprintf(char *buffer,
- TRIO_CONST char *format,
- va_list args)
+trio_vsprintf
+TRIO_ARGS3((buffer, format, args),
+ char *buffer,
+ TRIO_CONST char *format,
+ va_list args)
{
int status;
assert(VALID(buffer));
assert(VALID(format));
- status = TrioFormat(&buffer, 0, TrioOutStreamString, format, args, NULL);
+ status = TrioFormat(&buffer, 0, TrioOutStreamString, format, &args, NULL);
*buffer = NIL;
return status;
}
@@ -3380,17 +3866,18 @@ trio_vsprintf(char *buffer,
@return Number of printed characters.
*/
TRIO_PUBLIC int
-trio_sprintfv(char *buffer,
- TRIO_CONST char *format,
- void **args)
+trio_sprintfv
+TRIO_ARGS3((buffer, format, args),
+ char *buffer,
+ TRIO_CONST char *format,
+ trio_pointer_t *args)
{
int status;
- va_list dummy;
assert(VALID(buffer));
assert(VALID(format));
- status = TrioFormat(&buffer, 0, TrioOutStreamString, format, dummy, args);
+ status = TrioFormat(&buffer, 0, TrioOutStreamString, format, NULL, args);
*buffer = NIL;
return status;
}
@@ -3409,10 +3896,12 @@ trio_sprintfv(char *buffer,
@return Number of printed characters.
*/
TRIO_PUBLIC int
-trio_snprintf(char *buffer,
- size_t max,
- TRIO_CONST char *format,
- ...)
+trio_snprintf
+TRIO_VARGS4((buffer, max, format, va_alist),
+ char *buffer,
+ size_t max,
+ TRIO_CONST char *format,
+ TRIO_VA_DECL)
{
int status;
va_list args;
@@ -3420,12 +3909,12 @@ trio_snprintf(char *buffer,
assert(VALID(buffer));
assert(VALID(format));
- va_start(args, format);
+ TRIO_VA_START(args, format);
status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
- TrioOutStreamStringMax, format, args, NULL);
+ TrioOutStreamStringMax, format, &args, NULL);
if (max > 0)
*buffer = NIL;
- va_end(args);
+ TRIO_VA_END(args);
return status;
}
@@ -3439,10 +3928,12 @@ trio_snprintf(char *buffer,
@return Number of printed characters.
*/
TRIO_PUBLIC int
-trio_vsnprintf(char *buffer,
- size_t max,
- TRIO_CONST char *format,
- va_list args)
+trio_vsnprintf
+TRIO_ARGS4((buffer, max, format, args),
+ char *buffer,
+ size_t max,
+ TRIO_CONST char *format,
+ va_list args)
{
int status;
@@ -3450,7 +3941,7 @@ trio_vsnprintf(char *buffer,
assert(VALID(format));
status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
- TrioOutStreamStringMax, format, args, NULL);
+ TrioOutStreamStringMax, format, &args, NULL);
if (max > 0)
*buffer = NIL;
return status;
@@ -3466,19 +3957,20 @@ trio_vsnprintf(char *buffer,
@return Number of printed characters.
*/
TRIO_PUBLIC int
-trio_snprintfv(char *buffer,
- size_t max,
- TRIO_CONST char *format,
- void **args)
+trio_snprintfv
+TRIO_ARGS4((buffer, max, format, args),
+ char *buffer,
+ size_t max,
+ TRIO_CONST char *format,
+ trio_pointer_t *args)
{
int status;
- va_list dummy;
assert(VALID(buffer));
assert(VALID(format));
status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
- TrioOutStreamStringMax, format, dummy, args);
+ TrioOutStreamStringMax, format, NULL, args);
if (max > 0)
*buffer = NIL;
return status;
@@ -3490,16 +3982,18 @@ trio_snprintfv(char *buffer,
* character at the end of buffer.
*/
TRIO_PUBLIC int
-trio_snprintfcat(char *buffer,
- size_t max,
- TRIO_CONST char *format,
- ...)
+trio_snprintfcat
+TRIO_VARGS4((buffer, max, format, va_alist),
+ char *buffer,
+ size_t max,
+ TRIO_CONST char *format,
+ TRIO_VA_DECL)
{
int status;
va_list args;
size_t buf_len;
- va_start(args, format);
+ TRIO_VA_START(args, format);
assert(VALID(buffer));
assert(VALID(format));
@@ -3508,27 +4002,30 @@ trio_snprintfcat(char *buffer,
buffer = &buffer[buf_len];
status = TrioFormat(&buffer, max - 1 - buf_len,
- TrioOutStreamStringMax, format, args, NULL);
- va_end(args);
+ TrioOutStreamStringMax, format, &args, NULL);
+ TRIO_VA_END(args);
*buffer = NIL;
return status;
}
TRIO_PUBLIC int
-trio_vsnprintfcat(char *buffer,
- size_t max,
- TRIO_CONST char *format,
- va_list args)
+trio_vsnprintfcat
+TRIO_ARGS4((buffer, max, format, args),
+ char *buffer,
+ size_t max,
+ TRIO_CONST char *format,
+ va_list args)
{
int status;
size_t buf_len;
+
assert(VALID(buffer));
assert(VALID(format));
buf_len = trio_length(buffer);
buffer = &buffer[buf_len];
status = TrioFormat(&buffer, max - 1 - buf_len,
- TrioOutStreamStringMax, format, args, NULL);
+ TrioOutStreamStringMax, format, &args, NULL);
*buffer = NIL;
return status;
}
@@ -3539,8 +4036,10 @@ trio_vsnprintfcat(char *buffer,
/* Deprecated */
TRIO_PUBLIC char *
-trio_aprintf(TRIO_CONST char *format,
- ...)
+trio_aprintf
+TRIO_VARGS2((format, va_alist),
+ TRIO_CONST char *format,
+ TRIO_VA_DECL)
{
va_list args;
trio_string_t *info;
@@ -3551,10 +4050,10 @@ trio_aprintf(TRIO_CONST char *format,
info = trio_xstring_duplicate("");
if (info)
{
- va_start(args, format);
+ TRIO_VA_START(args, format);
(void)TrioFormat(info, 0, TrioOutStreamStringDynamic,
- format, args, NULL);
- va_end(args);
+ format, &args, NULL);
+ TRIO_VA_END(args);
trio_string_terminate(info);
result = trio_string_extract(info);
@@ -3565,8 +4064,10 @@ trio_aprintf(TRIO_CONST char *format,
/* Deprecated */
TRIO_PUBLIC char *
-trio_vaprintf(TRIO_CONST char *format,
- va_list args)
+trio_vaprintf
+TRIO_ARGS2((format, args),
+ TRIO_CONST char *format,
+ va_list args)
{
trio_string_t *info;
char *result = NULL;
@@ -3577,7 +4078,7 @@ trio_vaprintf(TRIO_CONST char *format,
if (info)
{
(void)TrioFormat(info, 0, TrioOutStreamStringDynamic,
- format, args, NULL);
+ format, &args, NULL);
trio_string_terminate(info);
result = trio_string_extract(info);
trio_string_destroy(info);
@@ -3586,9 +4087,11 @@ trio_vaprintf(TRIO_CONST char *format,
}
TRIO_PUBLIC int
-trio_asprintf(char **result,
- TRIO_CONST char *format,
- ...)
+trio_asprintf
+TRIO_VARGS3((result, format, va_alist),
+ char **result,
+ TRIO_CONST char *format,
+ TRIO_VA_DECL)
{
va_list args;
int status;
@@ -3605,10 +4108,10 @@ trio_asprintf(char **result,
}
else
{
- va_start(args, format);
+ TRIO_VA_START(args, format);
status = TrioFormat(info, 0, TrioOutStreamStringDynamic,
- format, args, NULL);
- va_end(args);
+ format, &args, NULL);
+ TRIO_VA_END(args);
if (status >= 0)
{
trio_string_terminate(info);
@@ -3620,9 +4123,11 @@ trio_asprintf(char **result,
}
TRIO_PUBLIC int
-trio_vasprintf(char **result,
- TRIO_CONST char *format,
- va_list args)
+trio_vasprintf
+TRIO_ARGS3((result, format, args),
+ char **result,
+ TRIO_CONST char *format,
+ va_list args)
{
int status;
trio_string_t *info;
@@ -3639,7 +4144,7 @@ trio_vasprintf(char **result,
else
{
status = TrioFormat(info, 0, TrioOutStreamStringDynamic,
- format, args, NULL);
+ format, &args, NULL);
if (status >= 0)
{
trio_string_terminate(info);
@@ -3658,7 +4163,6 @@ trio_vasprintf(char **result,
*
************************************************************************/
-
#if defined(TRIO_DOCUMENTATION)
# include "doc/doc_register.h"
#endif
@@ -3667,6 +4171,8 @@ trio_vasprintf(char **result,
@{
*/
+#if TRIO_EXTENSION
+
/*************************************************************************
* trio_register
*/
@@ -3678,9 +4184,11 @@ trio_vasprintf(char **result,
@param name
@return Handle.
*/
-TRIO_PUBLIC void *
-trio_register(trio_callback_t callback,
- TRIO_CONST char *name)
+TRIO_PUBLIC trio_pointer_t
+trio_register
+TRIO_ARGS2((callback, name),
+ trio_callback_t callback,
+ TRIO_CONST char *name)
{
trio_userdef_t *def;
trio_userdef_t *prev = NULL;
@@ -3738,14 +4246,18 @@ trio_register(trio_callback_t callback,
if (internalLeaveCriticalRegion)
(void)internalLeaveCriticalRegion(NULL);
}
- return def;
+ return (trio_pointer_t)def;
}
-/*************************************************************************
- * trio_unregister [public]
+/**
+ Unregister an existing user-defined specifier.
+
+ @param handle
*/
void
-trio_unregister(void *handle)
+trio_unregister
+TRIO_ARGS1((handle),
+ trio_pointer_t handle)
{
trio_userdef_t *self = (trio_userdef_t *)handle;
trio_userdef_t *def;
@@ -3778,9 +4290,13 @@ trio_unregister(void *handle)
* trio_get_format [public]
*/
TRIO_CONST char *
-trio_get_format(void *ref)
+trio_get_format
+TRIO_ARGS1((ref),
+ trio_pointer_t ref)
{
+#if defined(FORMAT_USER_DEFINED)
assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED);
+#endif
return (((trio_reference_t *)ref)->parameter->user_data);
}
@@ -3788,10 +4304,14 @@ trio_get_format(void *ref)
/*************************************************************************
* trio_get_argument [public]
*/
-void *
-trio_get_argument(void *ref)
+trio_pointer_t
+trio_get_argument
+TRIO_ARGS1((ref),
+ trio_pointer_t ref)
{
+#if defined(FORMAT_USER_DEFINED)
assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED);
+#endif
return ((trio_reference_t *)ref)->parameter->data.pointer;
}
@@ -3800,14 +4320,18 @@ trio_get_argument(void *ref)
* trio_get_width / trio_set_width [public]
*/
int
-trio_get_width(void *ref)
+trio_get_width
+TRIO_ARGS1((ref),
+ trio_pointer_t ref)
{
return ((trio_reference_t *)ref)->parameter->width;
}
void
-trio_set_width(void *ref,
- int width)
+trio_set_width
+TRIO_ARGS2((ref, width),
+ trio_pointer_t ref,
+ int width)
{
((trio_reference_t *)ref)->parameter->width = width;
}
@@ -3816,14 +4340,18 @@ trio_set_width(void *ref,
* trio_get_precision / trio_set_precision [public]
*/
int
-trio_get_precision(void *ref)
+trio_get_precision
+TRIO_ARGS1((ref),
+ trio_pointer_t ref)
{
return (((trio_reference_t *)ref)->parameter->precision);
}
void
-trio_set_precision(void *ref,
- int precision)
+trio_set_precision
+TRIO_ARGS2((ref, precision),
+ trio_pointer_t ref,
+ int precision)
{
((trio_reference_t *)ref)->parameter->precision = precision;
}
@@ -3832,14 +4360,18 @@ trio_set_precision(void *ref,
* trio_get_base / trio_set_base [public]
*/
int
-trio_get_base(void *ref)
+trio_get_base
+TRIO_ARGS1((ref),
+ trio_pointer_t ref)
{
return (((trio_reference_t *)ref)->parameter->base);
}
void
-trio_set_base(void *ref,
- int base)
+trio_set_base
+TRIO_ARGS2((ref, base),
+ trio_pointer_t ref,
+ int base)
{
((trio_reference_t *)ref)->parameter->base = base;
}
@@ -3848,14 +4380,18 @@ trio_set_base(void *ref,
* trio_get_long / trio_set_long [public]
*/
int
-trio_get_long(void *ref)
+trio_get_long
+TRIO_ARGS1((ref),
+ trio_pointer_t ref)
{
return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONG);
}
void
-trio_set_long(void *ref,
- int is_long)
+trio_set_long
+TRIO_ARGS2((ref, is_long),
+ trio_pointer_t ref,
+ int is_long)
{
if (is_long)
((trio_reference_t *)ref)->parameter->flags |= FLAGS_LONG;
@@ -3867,14 +4403,18 @@ trio_set_long(void *ref,
* trio_get_longlong / trio_set_longlong [public]
*/
int
-trio_get_longlong(void *ref)
+trio_get_longlong
+TRIO_ARGS1((ref),
+ trio_pointer_t ref)
{
return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUAD);
}
void
-trio_set_longlong(void *ref,
- int is_longlong)
+trio_set_longlong
+TRIO_ARGS2((ref, is_longlong),
+ trio_pointer_t ref,
+ int is_longlong)
{
if (is_longlong)
((trio_reference_t *)ref)->parameter->flags |= FLAGS_QUAD;
@@ -3886,14 +4426,18 @@ trio_set_longlong(void *ref,
* trio_get_longdouble / trio_set_longdouble [public]
*/
int
-trio_get_longdouble(void *ref)
+trio_get_longdouble
+TRIO_ARGS1((ref),
+ trio_pointer_t ref)
{
return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONGDOUBLE);
}
void
-trio_set_longdouble(void *ref,
- int is_longdouble)
+trio_set_longdouble
+TRIO_ARGS2((ref, is_longdouble),
+ trio_pointer_t ref,
+ int is_longdouble)
{
if (is_longdouble)
((trio_reference_t *)ref)->parameter->flags |= FLAGS_LONGDOUBLE;
@@ -3905,14 +4449,18 @@ trio_set_longdouble(void *ref,
* trio_get_short / trio_set_short [public]
*/
int
-trio_get_short(void *ref)
+trio_get_short
+TRIO_ARGS1((ref),
+ trio_pointer_t ref)
{
return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORT);
}
void
-trio_set_short(void *ref,
- int is_short)
+trio_set_short
+TRIO_ARGS2((ref, is_short),
+ trio_pointer_t ref,
+ int is_short)
{
if (is_short)
((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHORT;
@@ -3924,14 +4472,18 @@ trio_set_short(void *ref,
* trio_get_shortshort / trio_set_shortshort [public]
*/
int
-trio_get_shortshort(void *ref)
+trio_get_shortshort
+TRIO_ARGS1((ref),
+ trio_pointer_t ref)
{
return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORTSHORT);
}
void
-trio_set_shortshort(void *ref,
- int is_shortshort)
+trio_set_shortshort
+TRIO_ARGS2((ref, is_shortshort),
+ trio_pointer_t ref,
+ int is_shortshort)
{
if (is_shortshort)
((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHORTSHORT;
@@ -3943,14 +4495,18 @@ trio_set_shortshort(void *ref,
* trio_get_alternative / trio_set_alternative [public]
*/
int
-trio_get_alternative(void *ref)
+trio_get_alternative
+TRIO_ARGS1((ref),
+ trio_pointer_t ref)
{
return (((trio_reference_t *)ref)->parameter->flags & FLAGS_ALTERNATIVE);
}
void
-trio_set_alternative(void *ref,
- int is_alternative)
+trio_set_alternative
+TRIO_ARGS2((ref, is_alternative),
+ trio_pointer_t ref,
+ int is_alternative)
{
if (is_alternative)
((trio_reference_t *)ref)->parameter->flags |= FLAGS_ALTERNATIVE;
@@ -3962,14 +4518,18 @@ trio_set_alternative(void *ref,
* trio_get_alignment / trio_set_alignment [public]
*/
int
-trio_get_alignment(void *ref)
+trio_get_alignment
+TRIO_ARGS1((ref),
+ trio_pointer_t ref)
{
return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LEFTADJUST);
}
void
-trio_set_alignment(void *ref,
- int is_leftaligned)
+trio_set_alignment
+TRIO_ARGS2((ref, is_leftaligned),
+ trio_pointer_t ref,
+ int is_leftaligned)
{
if (is_leftaligned)
((trio_reference_t *)ref)->parameter->flags |= FLAGS_LEFTADJUST;
@@ -3981,14 +4541,18 @@ trio_set_alignment(void *ref,
* trio_get_spacing /trio_set_spacing [public]
*/
int
-trio_get_spacing(void *ref)
+trio_get_spacing
+TRIO_ARGS1((ref),
+ trio_pointer_t ref)
{
return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SPACE);
}
void
-trio_set_spacing(void *ref,
- int is_space)
+trio_set_spacing
+TRIO_ARGS2((ref, is_space),
+ trio_pointer_t ref,
+ int is_space)
{
if (is_space)
((trio_reference_t *)ref)->parameter->flags |= FLAGS_SPACE;
@@ -4000,14 +4564,18 @@ trio_set_spacing(void *ref,
* trio_get_sign / trio_set_sign [public]
*/
int
-trio_get_sign(void *ref)
+trio_get_sign
+TRIO_ARGS1((ref),
+ trio_pointer_t ref)
{
return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHOWSIGN);
}
void
-trio_set_sign(void *ref,
- int is_sign)
+trio_set_sign
+TRIO_ARGS2((ref, is_sign),
+ trio_pointer_t ref,
+ int is_sign)
{
if (is_sign)
((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHOWSIGN;
@@ -4019,14 +4587,18 @@ trio_set_sign(void *ref,
* trio_get_padding / trio_set_padding [public]
*/
int
-trio_get_padding(void *ref)
+trio_get_padding
+TRIO_ARGS1((ref),
+ trio_pointer_t ref)
{
return (((trio_reference_t *)ref)->parameter->flags & FLAGS_NILPADDING);
}
void
-trio_set_padding(void *ref,
- int is_padding)
+trio_set_padding
+TRIO_ARGS2((ref, is_padding),
+ trio_pointer_t ref,
+ int is_padding)
{
if (is_padding)
((trio_reference_t *)ref)->parameter->flags |= FLAGS_NILPADDING;
@@ -4038,14 +4610,18 @@ trio_set_padding(void *ref,
* trio_get_quote / trio_set_quote [public]
*/
int
-trio_get_quote(void *ref)
+trio_get_quote
+TRIO_ARGS1((ref),
+ trio_pointer_t ref)
{
return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUOTE);
}
void
-trio_set_quote(void *ref,
- int is_quote)
+trio_set_quote
+TRIO_ARGS2((ref, is_quote),
+ trio_pointer_t ref,
+ int is_quote)
{
if (is_quote)
((trio_reference_t *)ref)->parameter->flags |= FLAGS_QUOTE;
@@ -4057,14 +4633,18 @@ trio_set_quote(void *ref,
* trio_get_upper / trio_set_upper [public]
*/
int
-trio_get_upper(void *ref)
+trio_get_upper
+TRIO_ARGS1((ref),
+ trio_pointer_t ref)
{
return (((trio_reference_t *)ref)->parameter->flags & FLAGS_UPPER);
}
void
-trio_set_upper(void *ref,
- int is_upper)
+trio_set_upper
+TRIO_ARGS2((ref, is_upper),
+ trio_pointer_t ref,
+ int is_upper)
{
if (is_upper)
((trio_reference_t *)ref)->parameter->flags |= FLAGS_UPPER;
@@ -4077,14 +4657,18 @@ trio_set_upper(void *ref,
*/
#if TRIO_C99
int
-trio_get_largest(void *ref)
+trio_get_largest
+TRIO_ARGS1((ref),
+ trio_pointer_t ref)
{
return (((trio_reference_t *)ref)->parameter->flags & FLAGS_INTMAX_T);
}
void
-trio_set_largest(void *ref,
- int is_largest)
+trio_set_largest
+TRIO_ARGS2((ref, is_largest),
+ trio_pointer_t ref,
+ int is_largest)
{
if (is_largest)
((trio_reference_t *)ref)->parameter->flags |= FLAGS_INTMAX_T;
@@ -4097,14 +4681,18 @@ trio_set_largest(void *ref,
* trio_get_ptrdiff / trio_set_ptrdiff [public]
*/
int
-trio_get_ptrdiff(void *ref)
+trio_get_ptrdiff
+TRIO_ARGS1((ref),
+ trio_pointer_t ref)
{
return (((trio_reference_t *)ref)->parameter->flags & FLAGS_PTRDIFF_T);
}
void
-trio_set_ptrdiff(void *ref,
- int is_ptrdiff)
+trio_set_ptrdiff
+TRIO_ARGS2((ref, is_ptrdiff),
+ trio_pointer_t ref,
+ int is_ptrdiff)
{
if (is_ptrdiff)
((trio_reference_t *)ref)->parameter->flags |= FLAGS_PTRDIFF_T;
@@ -4117,14 +4705,18 @@ trio_set_ptrdiff(void *ref,
*/
#if TRIO_C99
int
-trio_get_size(void *ref)
+trio_get_size
+TRIO_ARGS1((ref),
+ trio_pointer_t ref)
{
return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SIZE_T);
}
void
-trio_set_size(void *ref,
- int is_size)
+trio_set_size
+TRIO_ARGS2((ref, is_size),
+ trio_pointer_t ref,
+ int is_size)
{
if (is_size)
((trio_reference_t *)ref)->parameter->flags |= FLAGS_SIZE_T;
@@ -4137,13 +4729,15 @@ trio_set_size(void *ref,
* trio_print_int [public]
*/
void
-trio_print_int(void *ref,
- int number)
+trio_print_int
+TRIO_ARGS2((ref, number),
+ trio_pointer_t ref,
+ int number)
{
trio_reference_t *self = (trio_reference_t *)ref;
TrioWriteNumber(self->data,
- (trio_intmax_t)number,
+ (trio_uintmax_t)number,
self->parameter->flags,
self->parameter->width,
self->parameter->precision,
@@ -4154,13 +4748,15 @@ trio_print_int(void *ref,
* trio_print_uint [public]
*/
void
-trio_print_uint(void *ref,
- unsigned int number)
+trio_print_uint
+TRIO_ARGS2((ref, number),
+ trio_pointer_t ref,
+ unsigned int number)
{
trio_reference_t *self = (trio_reference_t *)ref;
TrioWriteNumber(self->data,
- (trio_intmax_t)number,
+ (trio_uintmax_t)number,
self->parameter->flags | FLAGS_UNSIGNED,
self->parameter->width,
self->parameter->precision,
@@ -4171,8 +4767,10 @@ trio_print_uint(void *ref,
* trio_print_double [public]
*/
void
-trio_print_double(void *ref,
- double number)
+trio_print_double
+TRIO_ARGS2((ref, number),
+ trio_pointer_t ref,
+ double number)
{
trio_reference_t *self = (trio_reference_t *)ref;
@@ -4188,8 +4786,10 @@ trio_print_double(void *ref,
* trio_print_string [public]
*/
void
-trio_print_string(void *ref,
- char *string)
+trio_print_string
+TRIO_ARGS2((ref, string),
+ trio_pointer_t ref,
+ char *string)
{
trio_reference_t *self = (trio_reference_t *)ref;
@@ -4201,11 +4801,66 @@ trio_print_string(void *ref,
}
/*************************************************************************
+ * trio_print_ref [public]
+ */
+int
+trio_print_ref
+TRIO_VARGS3((ref, format, va_alist),
+ trio_pointer_t ref,
+ TRIO_CONST char *format,
+ TRIO_VA_DECL)
+{
+ int status;
+ va_list arglist;
+
+ assert(VALID(format));
+
+ TRIO_VA_START(arglist, format);
+ status = TrioFormatRef((trio_reference_t *)ref, format, &arglist, NULL);
+ TRIO_VA_END(arglist);
+ return status;
+}
+
+/*************************************************************************
+ * trio_vprint_ref [public]
+ */
+int
+trio_vprint_ref
+TRIO_ARGS3((ref, format, arglist),
+ trio_pointer_t ref,
+ TRIO_CONST char *format,
+ va_list arglist)
+{
+ assert(VALID(format));
+
+ return TrioFormatRef((trio_reference_t *)ref, format, &arglist, NULL);
+}
+
+/*************************************************************************
+ * trio_printv_ref [public]
+ */
+int
+trio_printv_ref
+TRIO_ARGS3((ref, format, argarray),
+ trio_pointer_t ref,
+ TRIO_CONST char *format,
+ trio_pointer_t *argarray)
+{
+ assert(VALID(format));
+
+ return TrioFormatRef((trio_reference_t *)ref, format, NULL, argarray);
+}
+
+#endif /* TRIO_EXTENSION */
+
+/*************************************************************************
* trio_print_pointer [public]
*/
void
-trio_print_pointer(void *ref,
- void *pointer)
+trio_print_pointer
+TRIO_ARGS2((ref, pointer),
+ trio_pointer_t ref,
+ trio_pointer_t pointer)
{
trio_reference_t *self = (trio_reference_t *)ref;
unsigned long flags;
@@ -4223,7 +4878,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
- * optimising compiler). The (char *) casting is done
+ * optimizing compiler). The (char *) casting is done
* to please ANSI C++.
*/
number = (trio_uintmax_t)((char *)pointer - (char *)0);
@@ -4233,7 +4888,7 @@ trio_print_pointer(void *ref,
flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE |
FLAGS_NILPADDING);
TrioWriteNumber(self->data,
- (trio_intmax_t)number,
+ number,
flags,
POINTER_WIDTH,
NO_PRECISION,
@@ -4241,54 +4896,96 @@ trio_print_pointer(void *ref,
}
}
+/** @} End of UserDefined documentation module */
+
/*************************************************************************
- * trio_print_ref [public]
+ *
+ * LOCALES
+ *
+ ************************************************************************/
+
+/*************************************************************************
+ * trio_locale_set_decimal_point
+ *
+ * Decimal point can only be one character. The input argument is a
+ * string to enable multibyte characters. At most MB_LEN_MAX characters
+ * will be used.
*/
-int
-trio_print_ref(void *ref,
- TRIO_CONST char *format,
- ...)
+TRIO_PUBLIC void
+trio_locale_set_decimal_point
+TRIO_ARGS1((decimalPoint),
+ char *decimalPoint)
{
- int status;
- va_list arglist;
-
- assert(VALID(format));
-
- va_start(arglist, format);
- status = TrioFormatRef((trio_reference_t *)ref, format, arglist, NULL);
- va_end(arglist);
- return status;
+#if defined(USE_LOCALE)
+ if (NULL == internalLocaleValues)
+ {
+ TrioSetLocale();
+ }
+#endif
+ internalDecimalPointLength = trio_length(decimalPoint);
+ if (internalDecimalPointLength == 1)
+ {
+ internalDecimalPoint = *decimalPoint;
+ }
+ else
+ {
+ internalDecimalPoint = NIL;
+ trio_copy_max(internalDecimalPointString,
+ sizeof(internalDecimalPointString),
+ decimalPoint);
+ }
}
/*************************************************************************
- * trio_vprint_ref [public]
+ * trio_locale_set_thousand_separator
+ *
+ * See trio_locale_set_decimal_point
*/
-int
-trio_vprint_ref(void *ref,
- TRIO_CONST char *format,
- va_list arglist)
+TRIO_PUBLIC void
+trio_locale_set_thousand_separator
+TRIO_ARGS1((thousandSeparator),
+ char *thousandSeparator)
{
- assert(VALID(format));
-
- return TrioFormatRef((trio_reference_t *)ref, format, arglist, NULL);
+#if defined(USE_LOCALE)
+ if (NULL == internalLocaleValues)
+ {
+ TrioSetLocale();
+ }
+#endif
+ trio_copy_max(internalThousandSeparator,
+ sizeof(internalThousandSeparator),
+ thousandSeparator);
+ internalThousandSeparatorLength = trio_length(internalThousandSeparator);
}
/*************************************************************************
- * trio_printv_ref [public]
+ * trio_locale_set_grouping
+ *
+ * Array of bytes. Reversed order.
+ *
+ * CHAR_MAX : No further grouping
+ * 0 : Repeat last group for the remaining digits (not necessary
+ * as C strings are zero-terminated)
+ * n : Set current group to n
+ *
+ * Same order as the grouping attribute in LC_NUMERIC.
*/
-int
-trio_printv_ref(void *ref,
- TRIO_CONST char *format,
- void **argarray)
+TRIO_PUBLIC void
+trio_locale_set_grouping
+TRIO_ARGS1((grouping),
+ char *grouping)
{
- va_list dummy;
-
- assert(VALID(format));
-
- return TrioFormatRef((trio_reference_t *)ref, format, dummy, argarray);
+#if defined(USE_LOCALE)
+ if (NULL == internalLocaleValues)
+ {
+ TrioSetLocale();
+ }
+#endif
+ trio_copy_max(internalGrouping,
+ sizeof(internalGrouping),
+ grouping);
}
-/** @} End of UserDefined documentation module */
/*************************************************************************
*
@@ -4296,12 +4993,13 @@ trio_printv_ref(void *ref,
*
************************************************************************/
-
/*************************************************************************
* TrioSkipWhitespaces
*/
TRIO_PRIVATE int
-TrioSkipWhitespaces(trio_class_t *self)
+TrioSkipWhitespaces
+TRIO_ARGS1((self),
+ trio_class_t *self)
{
int ch;
@@ -4318,7 +5016,7 @@ TrioSkipWhitespaces(trio_class_t *self)
*/
#if TRIO_EXTENSION
TRIO_PRIVATE void
-TrioGetCollation(void)
+TrioGetCollation(TRIO_NOARGS)
{
int i;
int j;
@@ -4351,10 +5049,12 @@ TrioGetCollation(void)
* multibyte
*/
TRIO_PRIVATE int
-TrioGetCharacterClass(TRIO_CONST char *format,
- int *indexPointer,
- unsigned long *flagsPointer,
- int *characterclass)
+TrioGetCharacterClass
+TRIO_ARGS4((format, indexPointer, flagsPointer, characterclass),
+ TRIO_CONST char *format,
+ int *indexPointer,
+ unsigned long *flagsPointer,
+ int *characterclass)
{
int index = *indexPointer;
int i;
@@ -4463,7 +5163,7 @@ TrioGetCharacterClass(TRIO_CONST char *format,
if (internalCollationUnconverted)
{
- /* Lazy evalutation of collation array */
+ /* Lazy evaluation of collation array */
TrioGetCollation();
internalCollationUnconverted = FALSE;
}
@@ -4608,16 +5308,19 @@ TrioGetCharacterClass(TRIO_CONST char *format,
* strtoul, because we must handle 'long long' and thousand separators.
*/
TRIO_PRIVATE BOOLEAN_T
-TrioReadNumber(trio_class_t *self,
- trio_uintmax_t *target,
- unsigned long flags,
- int width,
- int base)
+TrioReadNumber
+TRIO_ARGS5((self, target, flags, width, base),
+ trio_class_t *self,
+ trio_uintmax_t *target,
+ unsigned long flags,
+ int width,
+ int base)
{
trio_uintmax_t number = 0;
int digit;
int count;
BOOLEAN_T isNegative = FALSE;
+ BOOLEAN_T gotNumber = FALSE;
int j;
assert(VALID(self));
@@ -4717,16 +5420,17 @@ TrioReadNumber(trio_class_t *self,
number *= base;
number += digit;
+ gotNumber = TRUE; /* we need at least one digit */
self->InStream(self, NULL);
}
/* Was anything read at all? */
- if (self->processed == count)
+ if (!gotNumber)
return FALSE;
if (target)
- *target = (isNegative) ? -number : number;
+ *target = (isNegative) ? -((trio_intmax_t)number) : number;
return TRUE;
}
@@ -4734,10 +5438,12 @@ TrioReadNumber(trio_class_t *self,
* TrioReadChar
*/
TRIO_PRIVATE int
-TrioReadChar(trio_class_t *self,
- char *target,
- unsigned long flags,
- int width)
+TrioReadChar
+TRIO_ARGS4((self, target, flags, width),
+ trio_class_t *self,
+ char *target,
+ unsigned long flags,
+ int width)
{
int i;
char ch;
@@ -4798,10 +5504,12 @@ TrioReadChar(trio_class_t *self,
* TrioReadString
*/
TRIO_PRIVATE BOOLEAN_T
-TrioReadString(trio_class_t *self,
- char *target,
- unsigned long flags,
- int width)
+TrioReadString
+TRIO_ARGS4((self, target, flags, width),
+ trio_class_t *self,
+ char *target,
+ unsigned long flags,
+ int width)
{
int i;
@@ -4819,7 +5527,7 @@ TrioReadString(trio_class_t *self,
(! ((self->current == EOF) || isspace(self->current)));
i++)
{
- if (TrioReadChar(self, &target[i], flags, 1) == 0)
+ if (TrioReadChar(self, (target ? &target[i] : 0), flags, 1) == 0)
break; /* for */
}
if (target)
@@ -4832,16 +5540,18 @@ TrioReadString(trio_class_t *self,
*/
#if TRIO_WIDECHAR
TRIO_PRIVATE int
-TrioReadWideChar(trio_class_t *self,
- wchar_t *target,
- unsigned long flags,
- int width)
+TrioReadWideChar
+TRIO_ARGS4((self, target, flags, width),
+ trio_class_t *self,
+ trio_wchar_t *target,
+ unsigned long flags,
+ int width)
{
int i;
int j;
int size;
int amount = 0;
- wchar_t wch;
+ trio_wchar_t wch;
char buffer[MB_LEN_MAX + 1];
assert(VALID(self));
@@ -4891,10 +5601,12 @@ TrioReadWideChar(trio_class_t *self,
*/
#if TRIO_WIDECHAR
TRIO_PRIVATE BOOLEAN_T
-TrioReadWideString(trio_class_t *self,
- wchar_t *target,
- unsigned long flags,
- int width)
+TrioReadWideString
+TRIO_ARGS4((self, target, flags, width),
+ trio_class_t *self,
+ trio_wchar_t *target,
+ unsigned long flags,
+ int width)
{
int i;
int size;
@@ -4905,7 +5617,7 @@ TrioReadWideString(trio_class_t *self,
TrioSkipWhitespaces(self);
#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- mblen(NULL, 0);
+ (void)mblen(NULL, 0);
#endif
/*
@@ -4935,11 +5647,13 @@ TrioReadWideString(trio_class_t *self,
* FIXME: characterclass does not work with multibyte characters
*/
TRIO_PRIVATE BOOLEAN_T
-TrioReadGroup(trio_class_t *self,
- char *target,
- int *characterclass,
- unsigned long flags,
- int width)
+TrioReadGroup
+TRIO_ARGS5((self, target, characterclass, flags, width),
+ trio_class_t *self,
+ char *target,
+ int *characterclass,
+ unsigned long flags,
+ int width)
{
int ch;
int i;
@@ -4969,20 +5683,25 @@ TrioReadGroup(trio_class_t *self,
*
* FIXME:
* add long double
+ * handle base
*/
TRIO_PRIVATE BOOLEAN_T
-TrioReadDouble(trio_class_t *self,
- double *target,
- unsigned long flags,
- int width)
+TrioReadDouble
+TRIO_ARGS4((self, target, flags, width),
+ trio_class_t *self,
+ trio_pointer_t target,
+ unsigned long flags,
+ int width)
{
int ch;
- char doubleString[512] = "";
+ char doubleString[512];
int index = 0;
int start;
int j;
BOOLEAN_T isHex = FALSE;
+ doubleString[0] = 0;
+
if ((width == NO_WIDTH) || (width > (int)sizeof(doubleString) - 1))
width = sizeof(doubleString) - 1;
@@ -5024,25 +5743,46 @@ TrioReadDouble(trio_class_t *self,
if (trio_equal(&doubleString[start], INFINITE_UPPER) ||
trio_equal(&doubleString[start], LONG_INFINITE_UPPER))
{
- *target = ((start == 1 && doubleString[0] == '-'))
- ? trio_ninf()
- : trio_pinf();
+ if (flags & FLAGS_LONGDOUBLE)
+ {
+ if ((start == 1) && (doubleString[0] == '-'))
+ {
+ *((trio_long_double_t *)target) = trio_ninf();
+ }
+ else
+ {
+ *((trio_long_double_t *)target) = trio_pinf();
+ }
+ }
+ else
+ {
+ if ((start == 1) && (doubleString[0] == '-'))
+ {
+ *((double *)target) = trio_ninf();
+ }
+ else
+ {
+ *((double *)target) = trio_pinf();
+ }
+ }
return TRUE;
}
if (trio_equal(doubleString, NAN_UPPER))
{
/* NaN must not have a preceeding + nor - */
- *target = trio_nan();
+ if (flags & FLAGS_LONGDOUBLE)
+ {
+ *((trio_long_double_t *)target) = trio_nan();
+ }
+ else
+ {
+ *((double *)target) = trio_nan();
+ }
return TRUE;
}
return FALSE;
-
- default:
- break;
- }
-
- if (ch == '0')
- {
+
+ case '0':
doubleString[index++] = (char)ch;
self->InStream(self, &ch);
if (toupper(ch) == 'X')
@@ -5051,7 +5791,12 @@ TrioReadDouble(trio_class_t *self,
doubleString[index++] = (char)ch;
self->InStream(self, &ch);
}
+ break;
+
+ default:
+ break;
}
+
while ((ch != EOF) && (index - start < width))
{
/* Integer part */
@@ -5110,13 +5855,16 @@ TrioReadDouble(trio_class_t *self,
if ((index == start) || (*doubleString == NIL))
return FALSE;
+
+ doubleString[index] = 0;
if (flags & FLAGS_LONGDOUBLE)
-/* *longdoublePointer = trio_to_long_double()*/
- return FALSE; /* FIXME: Remove when long double is implemented */
+ {
+ *((trio_long_double_t *)target) = trio_to_long_double(doubleString, NULL);
+ }
else
{
- *target = trio_to_double(doubleString, NULL);
+ *((double *)target) = trio_to_double(doubleString, NULL);
}
return TRUE;
}
@@ -5125,9 +5873,11 @@ TrioReadDouble(trio_class_t *self,
* TrioReadPointer
*/
TRIO_PRIVATE BOOLEAN_T
-TrioReadPointer(trio_class_t *self,
- void **target,
- unsigned long flags)
+TrioReadPointer
+TRIO_ARGS3((self, target, flags),
+ trio_class_t *self,
+ trio_pointer_t *target,
+ unsigned long flags)
{
trio_uintmax_t number;
char buffer[sizeof(internalNullString)];
@@ -5169,9 +5919,11 @@ TrioReadPointer(trio_class_t *self,
* TrioScanProcess
*/
TRIO_PRIVATE int
-TrioScanProcess(trio_class_t *data,
- TRIO_CONST char *format,
- trio_parameter_t *parameters)
+TrioScanProcess
+TRIO_ARGS3((data, format, parameters),
+ trio_class_t *data,
+ TRIO_CONST char *format,
+ trio_parameter_t *parameters)
{
#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
int charlen;
@@ -5184,7 +5936,7 @@ TrioScanProcess(trio_class_t *data,
unsigned long flags;
int width;
int base;
- void *pointer;
+ trio_pointer_t pointer;
assignment = 0;
i = 0;
@@ -5192,7 +5944,7 @@ TrioScanProcess(trio_class_t *data,
data->InStream(data, &ch);
#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- mblen(NULL, 0);
+ (void)mblen(NULL, 0);
#endif
while (format[index])
@@ -5201,20 +5953,26 @@ TrioScanProcess(trio_class_t *data,
if (! isascii(format[index]))
{
charlen = mblen(&format[index], MB_LEN_MAX);
- /* Compare multibyte characters in format string */
- for (cnt = 0; cnt < charlen - 1; cnt++)
+ if (charlen != -1)
{
- if (ch != format[index + cnt])
+ /* Compare multibyte characters in format string */
+ for (cnt = 0; cnt < charlen - 1; cnt++)
{
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
+ if (ch != format[index + cnt])
+ {
+ return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
+ }
+ data->InStream(data, &ch);
}
- data->InStream(data, &ch);
+ continue; /* while characters left in formatting string */
}
- continue; /* while */
}
#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */
- if (EOF == ch)
- return EOF;
+
+ if ((EOF == ch) && (parameters[i].type != FORMAT_COUNT))
+ {
+ return (assignment > 0) ? assignment : EOF;
+ }
if (CHAR_IDENTIFIER == format[index])
{
@@ -5266,10 +6024,11 @@ TrioScanProcess(trio_class_t *data,
width,
base))
return assignment;
- assignment++;
-
+
if (!(flags & FLAGS_IGNORE))
{
+ assignment++;
+
pointer = parameters[i].data.pointer;
#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER)
if (flags & FLAGS_SIZE_T)
@@ -5321,20 +6080,34 @@ TrioScanProcess(trio_class_t *data,
width))
return assignment;
}
- assignment++;
+ if (!(flags & FLAGS_IGNORE))
+ assignment++;
break; /* FORMAT_STRING */
-
+
case FORMAT_DOUBLE:
- if (!TrioReadDouble(data,
- (flags & FLAGS_IGNORE)
- ? NULL
- : parameters[i].data.doublePointer,
- flags,
- width))
- return assignment;
- assignment++;
- break; /* FORMAT_DOUBLE */
+ {
+ trio_pointer_t pointer;
+ if (flags & FLAGS_IGNORE)
+ {
+ pointer = NULL;
+ }
+ else
+ {
+ pointer = (flags & FLAGS_LONGDOUBLE)
+ ? (trio_pointer_t)parameters[i].data.longdoublePointer
+ : (trio_pointer_t)parameters[i].data.doublePointer;
+ }
+ if (!TrioReadDouble(data, pointer, flags, width))
+ {
+ return assignment;
+ }
+ if (!(flags & FLAGS_IGNORE))
+ {
+ assignment++;
+ }
+ break; /* FORMAT_DOUBLE */
+ }
case FORMAT_GROUP:
{
int characterclass[MAX_CHARACTER_CLASS + 1];
@@ -5364,44 +6137,48 @@ TrioScanProcess(trio_class_t *data,
flags,
parameters[i].width))
return assignment;
- assignment++;
+ if (!(flags & FLAGS_IGNORE))
+ assignment++;
}
break; /* FORMAT_GROUP */
-
+
case FORMAT_COUNT:
pointer = parameters[i].data.pointer;
if (NULL != pointer)
{
+ int count = data->committed;
+ if (ch != EOF)
+ count--; /* a character is read, but is not consumed yet */
#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER)
if (flags & FLAGS_SIZE_T)
- *(size_t *)pointer = (size_t)data->committed;
+ *(size_t *)pointer = (size_t)count;
else
#endif
#if defined(QUALIFIER_PTRDIFF_T)
if (flags & FLAGS_PTRDIFF_T)
- *(ptrdiff_t *)pointer = (ptrdiff_t)data->committed;
+ *(ptrdiff_t *)pointer = (ptrdiff_t)count;
else
#endif
#if defined(QUALIFIER_INTMAX_T)
if (flags & FLAGS_INTMAX_T)
- *(trio_intmax_t *)pointer = (trio_intmax_t)data->committed;
+ *(trio_intmax_t *)pointer = (trio_intmax_t)count;
else
#endif
if (flags & FLAGS_QUAD)
{
- *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)data->committed;
+ *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)count;
}
else if (flags & FLAGS_LONG)
{
- *(long int *)pointer = (long int)data->committed;
+ *(long int *)pointer = (long int)count;
}
else if (flags & FLAGS_SHORT)
{
- *(short int *)pointer = (short int)data->committed;
+ *(short int *)pointer = (short int)count;
}
else
{
- *(int *)pointer = (int)data->committed;
+ *(int *)pointer = (int)count;
}
}
break; /* FORMAT_COUNT */
@@ -5415,7 +6192,7 @@ TrioScanProcess(trio_class_t *data,
? NULL
: parameters[i].data.wstring,
flags,
- (width == NO_WIDTH) ? 1 : width) > 0)
+ (width == NO_WIDTH) ? 1 : width) == 0)
return assignment;
}
else
@@ -5426,25 +6203,27 @@ TrioScanProcess(trio_class_t *data,
? NULL
: parameters[i].data.string,
flags,
- (width == NO_WIDTH) ? 1 : width) > 0)
+ (width == NO_WIDTH) ? 1 : width) == 0)
return assignment;
}
- assignment++;
+ if (!(flags & FLAGS_IGNORE))
+ assignment++;
break; /* FORMAT_CHAR */
-
+
case FORMAT_POINTER:
if (!TrioReadPointer(data,
(flags & FLAGS_IGNORE)
? NULL
- : (void **)parameters[i].data.pointer,
+ : (trio_pointer_t *)parameters[i].data.pointer,
flags))
return assignment;
- assignment++;
+ if (!(flags & FLAGS_IGNORE))
+ assignment++;
break; /* FORMAT_POINTER */
-
+
case FORMAT_PARAMETER:
break; /* FORMAT_PARAMETER */
-
+
default:
return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
}
@@ -5476,12 +6255,14 @@ TrioScanProcess(trio_class_t *data,
* 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)
+TrioScan
+TRIO_ARGS6((source, sourceSize, InStream, format, arglist, argarray),
+ trio_pointer_t source,
+ size_t sourceSize,
+ void (*InStream) TRIO_PROTO((trio_class_t *, int *)),
+ TRIO_CONST char *format,
+ va_list *arglist,
+ trio_pointer_t *argarray)
{
int status;
trio_parameter_t parameters[MAX_PARAMETERS];
@@ -5492,7 +6273,7 @@ TrioScan(TRIO_CONST void *source,
memset(&data, 0, sizeof(data));
data.InStream = InStream;
- data.location = (void *)source;
+ data.location = (trio_pointer_t)source;
data.max = sourceSize;
data.error = 0;
@@ -5519,8 +6300,10 @@ TrioScan(TRIO_CONST void *source,
* TrioInStreamFile
*/
TRIO_PRIVATE void
-TrioInStreamFile(trio_class_t *self,
- int *intPointer)
+TrioInStreamFile
+TRIO_ARGS2((self, intPointer),
+ trio_class_t *self,
+ int *intPointer)
{
FILE *file = (FILE *)self->location;
@@ -5534,8 +6317,11 @@ TrioInStreamFile(trio_class_t *self,
? TRIO_ERROR_RETURN(TRIO_ERRNO, 0)
: TRIO_ERROR_RETURN(TRIO_EOF, 0);
}
- self->processed++;
- self->committed++;
+ else
+ {
+ self->processed++;
+ self->committed++;
+ }
if (VALID(intPointer))
{
@@ -5547,8 +6333,10 @@ TrioInStreamFile(trio_class_t *self,
* TrioInStreamFileDescriptor
*/
TRIO_PRIVATE void
-TrioInStreamFileDescriptor(trio_class_t *self,
- int *intPointer)
+TrioInStreamFileDescriptor
+TRIO_ARGS2((self, intPointer),
+ trio_class_t *self,
+ int *intPointer)
{
int fd = *((int *)self->location);
int size;
@@ -5566,8 +6354,47 @@ TrioInStreamFileDescriptor(trio_class_t *self,
{
self->current = (size == 0) ? EOF : input;
}
- self->committed++;
- self->processed++;
+ if (self->current != EOF)
+ {
+ self->committed++;
+ self->processed++;
+ }
+
+ if (VALID(intPointer))
+ {
+ *intPointer = self->current;
+ }
+}
+
+/*************************************************************************
+ * TrioInStreamCustom
+ */
+TRIO_PRIVATE void
+TrioInStreamCustom
+TRIO_ARGS2((self, intPointer),
+ trio_class_t *self,
+ int *intPointer)
+{
+ trio_custom_t *data;
+
+ assert(VALID(self));
+ assert(VALID(self->location));
+
+ data = (trio_custom_t *)self->location;
+
+ self->current = (data->stream.in == NULL)
+ ? NIL
+ : (data->stream.in)(data->closure);
+
+ if (self->current == NIL)
+ {
+ self->current = EOF;
+ }
+ else
+ {
+ self->processed++;
+ self->committed++;
+ }
if (VALID(intPointer))
{
@@ -5579,22 +6406,28 @@ TrioInStreamFileDescriptor(trio_class_t *self,
* TrioInStreamString
*/
TRIO_PRIVATE void
-TrioInStreamString(trio_class_t *self,
- int *intPointer)
+TrioInStreamString
+TRIO_ARGS2((self, intPointer),
+ trio_class_t *self,
+ int *intPointer)
{
unsigned char **buffer;
assert(VALID(self));
- assert(VALID(self->InStream));
assert(VALID(self->location));
buffer = (unsigned char **)self->location;
self->current = (*buffer)[0];
if (self->current == NIL)
- self->current = EOF;
- (*buffer)++;
- self->processed++;
- self->committed++;
+ {
+ self->current = EOF;
+ }
+ else
+ {
+ (*buffer)++;
+ self->processed++;
+ self->committed++;
+ }
if (VALID(intPointer))
{
@@ -5627,47 +6460,59 @@ TrioInStreamString(trio_class_t *self,
@return Number of scanned characters.
*/
TRIO_PUBLIC int
-trio_scanf(TRIO_CONST char *format,
- ...)
+trio_scanf
+TRIO_VARGS2((format, va_alist),
+ TRIO_CONST char *format,
+ TRIO_VA_DECL)
{
int status;
va_list args;
assert(VALID(format));
- va_start(args, format);
- status = TrioScan(stdin, 0, TrioInStreamFile, format, args, NULL);
- va_end(args);
+ TRIO_VA_START(args, format);
+ status = TrioScan((trio_pointer_t)stdin, 0,
+ TrioInStreamFile,
+ format, &args, NULL);
+ TRIO_VA_END(args);
return status;
}
TRIO_PUBLIC int
-trio_vscanf(TRIO_CONST char *format,
- va_list args)
+trio_vscanf
+TRIO_ARGS2((format, args),
+ TRIO_CONST char *format,
+ va_list args)
{
assert(VALID(format));
- return TrioScan(stdin, 0, TrioInStreamFile, format, args, NULL);
+ return TrioScan((trio_pointer_t)stdin, 0,
+ TrioInStreamFile,
+ format, &args, NULL);
}
TRIO_PUBLIC int
-trio_scanfv(TRIO_CONST char *format,
- void **args)
+trio_scanfv
+TRIO_ARGS2((format, args),
+ TRIO_CONST char *format,
+ trio_pointer_t *args)
{
- va_list dummy;
-
assert(VALID(format));
- return TrioScan(stdin, 0, TrioInStreamFile, format, dummy, args);
+ return TrioScan((trio_pointer_t)stdin, 0,
+ TrioInStreamFile,
+ format, NULL, args);
}
/*************************************************************************
* fscanf
*/
TRIO_PUBLIC int
-trio_fscanf(FILE *file,
+trio_fscanf
+TRIO_VARGS3((file, format, va_alist),
+ FILE *file,
TRIO_CONST char *format,
- ...)
+ TRIO_VA_DECL)
{
int status;
va_list args;
@@ -5675,84 +6520,166 @@ trio_fscanf(FILE *file,
assert(VALID(file));
assert(VALID(format));
- va_start(args, format);
- status = TrioScan(file, 0, TrioInStreamFile, format, args, NULL);
- va_end(args);
+ TRIO_VA_START(args, format);
+ status = TrioScan((trio_pointer_t)file, 0,
+ TrioInStreamFile,
+ format, &args, NULL);
+ TRIO_VA_END(args);
return status;
}
TRIO_PUBLIC int
-trio_vfscanf(FILE *file,
- TRIO_CONST char *format,
- va_list args)
+trio_vfscanf
+TRIO_ARGS3((file, format, args),
+ FILE *file,
+ TRIO_CONST char *format,
+ va_list args)
{
assert(VALID(file));
assert(VALID(format));
- return TrioScan(file, 0, TrioInStreamFile, format, args, NULL);
+ return TrioScan((trio_pointer_t)file, 0,
+ TrioInStreamFile,
+ format, &args, NULL);
}
TRIO_PUBLIC int
-trio_fscanfv(FILE *file,
- TRIO_CONST char *format,
- void **args)
+trio_fscanfv
+TRIO_ARGS3((file, format, args),
+ FILE *file,
+ TRIO_CONST char *format,
+ trio_pointer_t *args)
{
- va_list dummy;
-
assert(VALID(file));
assert(VALID(format));
- return TrioScan(file, 0, TrioInStreamFile, format, dummy, args);
+ return TrioScan((trio_pointer_t)file, 0,
+ TrioInStreamFile,
+ format, NULL, args);
}
/*************************************************************************
* dscanf
*/
TRIO_PUBLIC int
-trio_dscanf(int fd,
+trio_dscanf
+TRIO_VARGS3((fd, format, va_alist),
+ int fd,
TRIO_CONST char *format,
- ...)
+ TRIO_VA_DECL)
{
int status;
va_list args;
assert(VALID(format));
- va_start(args, format);
- status = TrioScan(&fd, 0, TrioInStreamFileDescriptor, format, args, NULL);
- va_end(args);
+ TRIO_VA_START(args, format);
+ status = TrioScan((trio_pointer_t)&fd, 0,
+ TrioInStreamFileDescriptor,
+ format, &args, NULL);
+ TRIO_VA_END(args);
return status;
}
TRIO_PUBLIC int
-trio_vdscanf(int fd,
- TRIO_CONST char *format,
- va_list args)
+trio_vdscanf
+TRIO_ARGS3((fd, format, args),
+ int fd,
+ TRIO_CONST char *format,
+ va_list args)
+{
+ assert(VALID(format));
+
+ return TrioScan((trio_pointer_t)&fd, 0,
+ TrioInStreamFileDescriptor,
+ format, &args, NULL);
+}
+
+TRIO_PUBLIC int
+trio_dscanfv
+TRIO_ARGS3((fd, format, args),
+ int fd,
+ TRIO_CONST char *format,
+ trio_pointer_t *args)
+{
+ assert(VALID(format));
+
+ return TrioScan((trio_pointer_t)&fd, 0,
+ TrioInStreamFileDescriptor,
+ format, NULL, args);
+}
+
+/*************************************************************************
+ * cscanf
+ */
+TRIO_PUBLIC int
+trio_cscanf
+TRIO_VARGS4((stream, closure, format, va_alist),
+ trio_instream_t stream,
+ trio_pointer_t closure,
+ TRIO_CONST char *format,
+ TRIO_VA_DECL)
{
+ int status;
+ va_list args;
+ trio_custom_t data;
+
+ assert(VALID(stream));
assert(VALID(format));
- return TrioScan(&fd, 0, TrioInStreamFileDescriptor, format, args, NULL);
+ TRIO_VA_START(args, format);
+ data.stream.in = stream;
+ data.closure = closure;
+ status = TrioScan(&data, 0, TrioInStreamCustom, format, &args, NULL);
+ TRIO_VA_END(args);
+ return status;
}
TRIO_PUBLIC int
-trio_dscanfv(int fd,
- TRIO_CONST char *format,
- void **args)
+trio_vcscanf
+TRIO_ARGS4((stream, closure, format, args),
+ trio_instream_t stream,
+ trio_pointer_t closure,
+ TRIO_CONST char *format,
+ va_list args)
{
- va_list dummy;
+ trio_custom_t data;
+ assert(VALID(stream));
assert(VALID(format));
+
+ data.stream.in = stream;
+ data.closure = closure;
+ return TrioScan(&data, 0, TrioInStreamCustom, format, &args, NULL);
+}
+
+TRIO_PUBLIC int
+trio_cscanfv
+TRIO_ARGS4((stream, closure, format, args),
+ trio_instream_t stream,
+ trio_pointer_t closure,
+ TRIO_CONST char *format,
+ trio_pointer_t *args)
+{
+ trio_custom_t data;
- return TrioScan(&fd, 0, TrioInStreamFileDescriptor, format, dummy, args);
+ assert(VALID(stream));
+ assert(VALID(format));
+
+ data.stream.in = stream;
+ data.closure = closure;
+ return TrioScan(&data, 0, TrioInStreamCustom, format, NULL, args);
}
/*************************************************************************
* sscanf
*/
TRIO_PUBLIC int
-trio_sscanf(TRIO_CONST char *buffer,
+trio_sscanf
+TRIO_VARGS3((buffer, format, va_alist),
+ TRIO_CONST char *buffer,
TRIO_CONST char *format,
- ...)
+ TRIO_VA_DECL)
{
int status;
va_list args;
@@ -5760,34 +6687,74 @@ trio_sscanf(TRIO_CONST char *buffer,
assert(VALID(buffer));
assert(VALID(format));
- va_start(args, format);
- status = TrioScan(&buffer, 0, TrioInStreamString, format, args, NULL);
- va_end(args);
+ TRIO_VA_START(args, format);
+ status = TrioScan((trio_pointer_t)&buffer, 0,
+ TrioInStreamString,
+ format, &args, NULL);
+ TRIO_VA_END(args);
return status;
}
TRIO_PUBLIC int
-trio_vsscanf(TRIO_CONST char *buffer,
- TRIO_CONST char *format,
- va_list args)
+trio_vsscanf
+TRIO_ARGS3((buffer, format, args),
+ TRIO_CONST char *buffer,
+ TRIO_CONST char *format,
+ va_list args)
{
assert(VALID(buffer));
assert(VALID(format));
- return TrioScan(&buffer, 0, TrioInStreamString, format, args, NULL);
+ return TrioScan((trio_pointer_t)&buffer, 0,
+ TrioInStreamString,
+ format, &args, NULL);
}
TRIO_PUBLIC int
-trio_sscanfv(TRIO_CONST char *buffer,
- TRIO_CONST char *format,
- void **args)
+trio_sscanfv
+TRIO_ARGS3((buffer, format, args),
+ TRIO_CONST char *buffer,
+ TRIO_CONST char *format,
+ trio_pointer_t *args)
{
- va_list dummy;
-
assert(VALID(buffer));
assert(VALID(format));
- return TrioScan(&buffer, 0, TrioInStreamString, format, dummy, args);
+ return TrioScan((trio_pointer_t)&buffer, 0,
+ TrioInStreamString,
+ format, NULL, args);
}
/** @} End of Scanf documentation module */
+
+/*************************************************************************
+ * trio_strerror
+ */
+TRIO_PUBLIC TRIO_CONST char *
+trio_strerror
+TRIO_ARGS1((errorcode),
+ int errorcode)
+{
+ /* Textual versions of the error codes */
+ switch (TRIO_ERROR_CODE(errorcode))
+ {
+ case TRIO_EOF:
+ return "End of file";
+ case TRIO_EINVAL:
+ return "Invalid argument";
+ case TRIO_ETOOMANY:
+ return "Too many arguments";
+ case TRIO_EDBLREF:
+ return "Double reference";
+ case TRIO_EGAP:
+ return "Reference gap";
+ case TRIO_ENOMEM:
+ return "Out of memory";
+ case TRIO_ERANGE:
+ return "Invalid range";
+ case TRIO_ECUSTOM:
+ return "Custom error";
+ default:
+ return "Unknown";
+ }
+}
diff --git a/trio.h b/trio.h
index 5a38f4a7..770c6a6f 100644
--- a/trio.h
+++ b/trio.h
@@ -23,8 +23,14 @@
#define TRIO_TRIO_H
#include <stdio.h>
-#include <stdarg.h>
#include <stdlib.h>
+#if defined(TRIO_COMPILER_ANCIENT)
+# include <varargs.h>
+#else
+# include <stdarg.h>
+#endif
+
+#if !defined(WITHOUT_TRIO)
/*
* Use autoconf defines if present. Packages using trio must define
@@ -34,22 +40,12 @@
# include <config.h>
#endif
-#if !defined(WITHOUT_TRIO)
+#include "triodef.h"
#ifdef __cplusplus
extern "C" {
#endif
-/* make utility and C++ compiler in Windows NT fails to find this symbol */
-#if defined(WIN32) && !defined(isascii)
-# 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.
*
@@ -63,72 +59,95 @@ enum {
TRIO_EGAP = 5,
TRIO_ENOMEM = 6,
TRIO_ERANGE = 7,
- TRIO_ERRNO = 8
+ TRIO_ERRNO = 8,
+ TRIO_ECUSTOM = 9
};
-const char *trio_strerror(int);
+/* Error macros */
+#define TRIO_ERROR_CODE(x) ((-(x)) & 0x00FF)
+#define TRIO_ERROR_POSITION(x) ((-(x)) >> 8)
+#define TRIO_ERROR_NAME(x) trio_strerror(x)
+
+typedef int (*trio_outstream_t) TRIO_PROTO((trio_pointer_t, int));
+typedef int (*trio_instream_t) TRIO_PROTO((trio_pointer_t));
+
+TRIO_CONST char *trio_strerror TRIO_PROTO((int));
/*************************************************************************
* Print Functions
*/
-int trio_printf(const char *format, ...);
-int trio_vprintf(const char *format, va_list args);
-int trio_printfv(const char *format, void **args);
+int trio_printf TRIO_PROTO((TRIO_CONST char *format, ...));
+int trio_vprintf TRIO_PROTO((TRIO_CONST char *format, va_list args));
+int trio_printfv TRIO_PROTO((TRIO_CONST char *format, void **args));
-int trio_fprintf(FILE *file, const char *format, ...);
-int trio_vfprintf(FILE *file, const char *format, va_list args);
-int trio_fprintfv(FILE *file, const char *format, void **args);
+int trio_fprintf TRIO_PROTO((FILE *file, TRIO_CONST char *format, ...));
+int trio_vfprintf TRIO_PROTO((FILE *file, TRIO_CONST char *format, va_list args));
+int trio_fprintfv TRIO_PROTO((FILE *file, TRIO_CONST char *format, void **args));
-int trio_dprintf(int fd, const char *format, ...);
-int trio_vdprintf(int fd, const char *format, va_list args);
-int trio_dprintfv(int fd, const char *format, void **args);
+int trio_dprintf TRIO_PROTO((int fd, TRIO_CONST char *format, ...));
+int trio_vdprintf TRIO_PROTO((int fd, TRIO_CONST char *format, va_list args));
+int trio_dprintfv TRIO_PROTO((int fd, TRIO_CONST char *format, void **args));
-/* trio_sprintf(target, format, ...)
- * trio_snprintf(target, maxsize, format, ...)
- *
- * Build 'target' according to 'format' and succesive
- * arguments. This is equal to the sprintf() and
- * snprintf() functions.
- */
-int trio_sprintf(char *buffer, const char *format, ...);
-int trio_vsprintf(char *buffer, const char *format, va_list args);
-int trio_sprintfv(char *buffer, const char *format, void **args);
+int trio_cprintf TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,
+ TRIO_CONST char *format, ...));
+int trio_vcprintf TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,
+ TRIO_CONST char *format, va_list args));
+int trio_cprintfv TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,
+ TRIO_CONST char *format, void **args));
+
+int trio_sprintf TRIO_PROTO((char *buffer, TRIO_CONST char *format, ...));
+int trio_vsprintf TRIO_PROTO((char *buffer, TRIO_CONST char *format, va_list args));
+int trio_sprintfv TRIO_PROTO((char *buffer, TRIO_CONST char *format, void **args));
-int trio_snprintf(char *buffer, size_t max, const char *format, ...);
-int trio_vsnprintf(char *buffer, size_t bufferSize, const char *format,
- va_list args);
-int trio_snprintfv(char *buffer, size_t bufferSize, const char *format,
- void **args);
+int trio_snprintf TRIO_PROTO((char *buffer, size_t max, TRIO_CONST char *format, ...));
+int trio_vsnprintf TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,
+ va_list args));
+int trio_snprintfv TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,
+ void **args));
-int trio_snprintfcat(char *buffer, size_t max, const char *format, ...);
-int trio_vsnprintfcat(char *buffer, size_t bufferSize, const char *format,
- va_list args);
+int trio_snprintfcat TRIO_PROTO((char *buffer, size_t max, TRIO_CONST char *format, ...));
+int trio_vsnprintfcat TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,
+ va_list args));
-char *trio_aprintf(const char *format, ...);
-char *trio_vaprintf(const char *format, va_list args);
+char *trio_aprintf TRIO_PROTO((TRIO_CONST char *format, ...));
+char *trio_vaprintf TRIO_PROTO((TRIO_CONST char *format, va_list args));
-int trio_asprintf(char **ret, const char *format, ...);
-int trio_vasprintf(char **ret, const char *format, va_list args);
+int trio_asprintf TRIO_PROTO((char **ret, TRIO_CONST char *format, ...));
+int trio_vasprintf TRIO_PROTO((char **ret, TRIO_CONST char *format, va_list args));
/*************************************************************************
* Scan Functions
*/
-int trio_scanf(const char *format, ...);
-int trio_vscanf(const char *format, va_list args);
-int trio_scanfv(const char *format, void **args);
+int trio_scanf TRIO_PROTO((TRIO_CONST char *format, ...));
+int trio_vscanf TRIO_PROTO((TRIO_CONST char *format, va_list args));
+int trio_scanfv TRIO_PROTO((TRIO_CONST char *format, void **args));
+
+int trio_fscanf TRIO_PROTO((FILE *file, TRIO_CONST char *format, ...));
+int trio_vfscanf TRIO_PROTO((FILE *file, TRIO_CONST char *format, va_list args));
+int trio_fscanfv TRIO_PROTO((FILE *file, TRIO_CONST char *format, void **args));
-int trio_fscanf(FILE *file, const char *format, ...);
-int trio_vfscanf(FILE *file, const char *format, va_list args);
-int trio_fscanfv(FILE *file, const char *format, void **args);
+int trio_dscanf TRIO_PROTO((int fd, TRIO_CONST char *format, ...));
+int trio_vdscanf TRIO_PROTO((int fd, TRIO_CONST char *format, va_list args));
+int trio_dscanfv TRIO_PROTO((int fd, TRIO_CONST char *format, void **args));
-int trio_dscanf(int fd, const char *format, ...);
-int trio_vdscanf(int fd, const char *format, va_list args);
-int trio_dscanfv(int fd, const char *format, void **args);
+int trio_cscanf TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,
+ TRIO_CONST char *format, ...));
+int trio_vcscanf TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,
+ TRIO_CONST char *format, va_list args));
+int trio_cscanfv TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,
+ TRIO_CONST char *format, void **args));
-int trio_sscanf(const char *buffer, const char *format, ...);
-int trio_vsscanf(const char *buffer, const char *format, va_list args);
-int trio_sscanfv(const char *buffer, const char *format, void **args);
+int trio_sscanf TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, ...));
+int trio_vsscanf TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, va_list args));
+int trio_sscanfv TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, void **args));
+
+/*************************************************************************
+ * Locale Functions
+ */
+void trio_locale_set_decimal_point TRIO_PROTO((char *decimalPoint));
+void trio_locale_set_thousand_separator TRIO_PROTO((char *thousandSeparator));
+void trio_locale_set_grouping TRIO_PROTO((char *grouping));
/*************************************************************************
* Renaming
diff --git a/triodef.h b/triodef.h
index 3e12cc4c..e9b62e59 100644
--- a/triodef.h
+++ b/triodef.h
@@ -34,8 +34,12 @@
# define TRIO_COMPILER_XLC /* Workaround for old xlc */
#elif defined(__DECC) || defined(__DECCXX)
# define TRIO_COMPILER_DECC
+#elif defined(__osf__) && defined(__LANGUAGE_C__)
+# define TRIO_COMPILER_DECC /* Workaround for old DEC C compilers */
#elif defined(_MSC_VER)
# define TRIO_COMPILER_MSVC
+#elif defined(__BORLANDC__)
+# define TRIO_COMPILER_BCB
#endif
#if defined(unix) || defined(__unix) || defined(__unix__)
@@ -61,9 +65,10 @@
# define TRIO_PLATFORM_MPEIX
#endif
-#if defined(__STDC__)
-# define TRIO_COMPILER_SUPPORTS_C90
+#if defined(__STDC__) || defined(TRIO_COMPILER_MSVC)
+# define TRIO_COMPILER_SUPPORTS_C89
# if defined(__STDC_VERSION__)
+# define TRIO_COMPILER_SUPPORTS_C90
# if (__STDC_VERSION__ >= 199409L)
# define TRIO_COMPILER_SUPPORTS_C94
# endif
@@ -84,6 +89,9 @@
# if (_XOPEN_VERSION >= 500)
# define TRIO_COMPILER_SUPPORTS_UNIX98
# endif
+# if (_XOPEN_VERSION >= 600)
+# define TRIO_COMPILER_SUPPORTS_UNIX01
+# endif
#endif
/*************************************************************************
@@ -97,22 +105,64 @@
# 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
+#if !(defined(TRIO_COMPILER_SUPPORTS_C89) || defined(__cplusplus))
+# define TRIO_COMPILER_ANCIENT
+#endif
+
+#if defined(TRIO_COMPILER_ANCIENT)
# define TRIO_CONST
# define TRIO_VOLATILE
-# define TRIO_POINTER char *
+# define TRIO_SIGNED
+typedef double trio_long_double_t;
+typedef char * trio_pointer_t;
+# define TRIO_SUFFIX_LONG(x) x
# define TRIO_PROTO(x) ()
+# define TRIO_NOARGS
+# define TRIO_ARGS1(list,a1) list a1;
+# define TRIO_ARGS2(list,a1,a2) list a1; a2;
+# define TRIO_ARGS3(list,a1,a2,a3) list a1; a2; a3;
+# define TRIO_ARGS4(list,a1,a2,a3,a4) list a1; a2; a3; a4;
+# define TRIO_ARGS5(list,a1,a2,a3,a4,a5) list a1; a2; a3; a4; a5;
+# define TRIO_ARGS6(list,a1,a2,a3,a4,a5,a6) list a1; a2; a3; a4; a5; a6;
+# define TRIO_VARGS2(list,a1,a2) list a1; a2
+# define TRIO_VARGS3(list,a1,a2,a3) list a1; a2; a3
+# define TRIO_VARGS4(list,a1,a2,a3,a4) list a1; a2; a3; a4
+# define TRIO_VARGS5(list,a1,a2,a3,a4,a5) list a1; a2; a3; a4; a5
+# define TRIO_VA_DECL va_dcl
+# define TRIO_VA_START(x,y) va_start((x))
+# define TRIO_VA_END(x) va_end(x)
+#else /* ANSI C */
+# define TRIO_CONST const
+# define TRIO_VOLATILE volatile
+# define TRIO_SIGNED signed
+typedef long double trio_long_double_t;
+typedef void * trio_pointer_t;
+# define TRIO_SUFFIX_LONG(x) x ## L
+# define TRIO_PROTO(x) x
+# define TRIO_NOARGS void
+# define TRIO_ARGS1(list,a1) (a1)
+# define TRIO_ARGS2(list,a1,a2) (a1,a2)
+# define TRIO_ARGS3(list,a1,a2,a3) (a1,a2,a3)
+# define TRIO_ARGS4(list,a1,a2,a3,a4) (a1,a2,a3,a4)
+# define TRIO_ARGS5(list,a1,a2,a3,a4,a5) (a1,a2,a3,a4,a5)
+# define TRIO_ARGS6(list,a1,a2,a3,a4,a5,a6) (a1,a2,a3,a4,a5,a6)
+# define TRIO_VARGS2 TRIO_ARGS2
+# define TRIO_VARGS3 TRIO_ARGS3
+# define TRIO_VARGS4 TRIO_ARGS4
+# define TRIO_VARGS5 TRIO_ARGS5
+# define TRIO_VA_DECL ...
+# define TRIO_VA_START(x,y) va_start((x),(y))
+# define TRIO_VA_END(x) va_end(x)
#endif
#if defined(TRIO_COMPILER_SUPPORTS_C99) || defined(__cplusplus)
# define TRIO_INLINE inline
#elif defined(TRIO_COMPILER_GCC)
# define TRIO_INLINE __inline__
+#elif defined(TRIO_COMPILER_MSVC)
+# define TRIO_INLINE _inline
+#elif defined(TRIO_COMPILER_BCB)
+# define TRIO_INLINE __inline
#else
# define TRIO_INLINE
#endif
diff --git a/trionan.c b/trionan.c
index 6f67c5be..5d63ad78 100644
--- a/trionan.c
+++ b/trionan.c
@@ -29,40 +29,13 @@
* 2. Use IEEE 754 bit-patterns if possible.
* 3. Use platform-specific techniques.
*
- * This program has been tested on the following platforms (in
- * alphabetic order)
- *
- * OS CPU Compiler
- * -------------------------------------------------
- * AIX 4.1.4 PowerPC gcc
- * Darwin 1.3.7 PowerPC gcc
- * FreeBSD 2.2 x86 gcc
- * FreeBSD 3.3 x86 gcc
- * FreeBSD 4.3 x86 gcc
- * FreeBSD 4.3 Alpha gcc
- * HP-UX 10.20 PA-RISC gcc
- * HP-UX 10.20 PA-RISC HP C++
- * IRIX 6.5 MIPS MIPSpro C
- * Linux 2.2 x86 gcc
- * Linux 2.2 Alpha gcc
- * Linux 2.4 IA64 gcc
- * Linux 2.4 StrongARM gcc
- * 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
- * Solaris 2.6 Sparc WorkShop 4.2
- * Solaris 8 Sparc Forte C 6
- * Tru64 4.0D Alpha gcc
- * Tru64 5.1 Alpha gcc
- * WinNT x86 MSVC 5.0 & 6.0
- *
************************************************************************/
-static const char rcsid[] = "@(#)$Id$";
+/*
+ * TODO:
+ * o Put all the magic into trio_fpclassify_and_signbit(), and use this from
+ * trio_isnan() etc.
+ */
/*************************************************************************
* Include files
@@ -102,7 +75,9 @@ static const char rcsid[] = "@(#)$Id$";
# 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"
+# if !defined(_CFE)
+# error "Must be compiled with option -ieee"
+# endif
# endif
# elif defined(TRIO_COMPILER_GCC) && (defined(__osf__) || defined(__linux__))
# error "Must be compiled with option -mieee"
@@ -128,9 +103,11 @@ static const char rcsid[] = "@(#)$Id$";
/*************************************************************************
- * Data
+ * Constants
*/
+static TRIO_CONST char rcsid[] = "@(#)$Id$";
+
#if defined(USE_IEEE_754)
/*
@@ -187,7 +164,9 @@ static TRIO_CONST unsigned char ieee_754_qnan_array[] = {
* trio_make_double
*/
TRIO_PRIVATE double
-trio_make_double(TRIO_CONST unsigned char *values)
+trio_make_double
+TRIO_ARGS1((values),
+ TRIO_CONST unsigned char *values)
{
TRIO_VOLATILE double result;
int i;
@@ -202,8 +181,10 @@ trio_make_double(TRIO_CONST unsigned char *values)
* trio_is_special_quantity
*/
TRIO_PRIVATE int
-trio_is_special_quantity(double number,
- int *has_mantissa)
+trio_is_special_quantity
+TRIO_ARGS2((number, has_mantissa),
+ double number,
+ int *has_mantissa)
{
unsigned int i;
unsigned char current;
@@ -224,7 +205,9 @@ trio_is_special_quantity(double number,
* trio_is_negative
*/
TRIO_PRIVATE int
-trio_is_negative(double number)
+trio_is_negative
+TRIO_ARGS1((number),
+ double number)
{
unsigned int i;
int is_negative = TRIO_FALSE;
@@ -236,14 +219,25 @@ trio_is_negative(double number)
return is_negative;
}
+#endif /* USE_IEEE_754 */
+
+
+/**
+ Generate negative zero.
+
+ @return Floating-point representation of negative zero.
+*/
TRIO_PUBLIC double
-trio_nzero(void)
+trio_nzero(TRIO_NOARGS)
{
+#if defined(USE_IEEE_754)
return trio_make_double(ieee_754_negzero_array);
-}
-
-#endif /* USE_IEEE_754 */
+#else
+ TRIO_VOLATILE double zero = 0.0;
+ return -zero;
+#endif
+}
/**
Generate positive infinity.
@@ -251,7 +245,7 @@ trio_nzero(void)
@return Floating-point representation of positive infinity.
*/
TRIO_PUBLIC double
-trio_pinf(void)
+trio_pinf(TRIO_NOARGS)
{
/* Cache the result */
static double result = 0.0;
@@ -295,7 +289,7 @@ trio_pinf(void)
@return Floating-point value of negative infinity.
*/
TRIO_PUBLIC double
-trio_ninf(void)
+trio_ninf(TRIO_NOARGS)
{
static double result = 0.0;
@@ -316,7 +310,7 @@ trio_ninf(void)
@return Floating-point representation of NaN.
*/
TRIO_PUBLIC double
-trio_nan(void)
+trio_nan(TRIO_NOARGS)
{
/* Cache the result */
static double result = 0.0;
@@ -364,9 +358,12 @@ trio_nan(void)
@return Boolean value indicating whether or not the number is a NaN.
*/
TRIO_PUBLIC int
-trio_isnan(TRIO_VOLATILE double number)
+trio_isnan
+TRIO_ARGS1((number),
+ double number)
{
-#if defined(isnan) || defined(TRIO_COMPILER_SUPPORTS_UNIX95)
+#if (defined(TRIO_COMPILER_SUPPORTS_C99) && defined(isnan)) \
+ || defined(TRIO_COMPILER_SUPPORTS_UNIX95)
/*
* C99 defines isnan() as a macro. UNIX95 defines isnan() as a
* function. This function was already present in XPG4, but this
@@ -407,7 +404,7 @@ trio_isnan(TRIO_VOLATILE double number)
status = (/*
* NaN is the only number which does not compare to itself
*/
- (number != number) ||
+ ((TRIO_VOLATILE double)number != (TRIO_VOLATILE double)number) ||
/*
* Fallback solution if NaN compares to NaN
*/
@@ -431,7 +428,9 @@ trio_isnan(TRIO_VOLATILE double number)
@return 1 if positive infinity, -1 if negative infinity, 0 otherwise.
*/
TRIO_PUBLIC int
-trio_isinf(TRIO_VOLATILE double number)
+trio_isinf
+TRIO_ARGS1((number),
+ double number)
{
#if defined(TRIO_COMPILER_DECC)
/*
@@ -441,12 +440,14 @@ trio_isinf(TRIO_VOLATILE double number)
return ((fp_class(number) == FP_POS_INF)
? 1
: ((fp_class(number) == FP_NEG_INF) ? -1 : 0));
-
+
#elif defined(isinf)
/*
* C99 defines isinf() as a macro.
*/
- return isinf(number);
+ return isinf(number)
+ ? ((number > 0.0) ? 1 : -1)
+ : 0;
#elif defined(TRIO_COMPILER_MSVC)
/*
@@ -503,9 +504,11 @@ trio_isinf(TRIO_VOLATILE double number)
@return Boolean value indicating whether or not the number is a finite.
*/
TRIO_PUBLIC int
-trio_isfinite(TRIO_VOLATILE double number)
+trio_isfinite
+TRIO_ARGS1((number),
+ double number)
{
-#if defined(isfinite)
+#if defined(TRIO_COMPILER_SUPPORTS_C99) && defined(isfinite)
/*
* C99 defines isfinite() as a macro.
*/
@@ -538,9 +541,11 @@ trio_isfinite(TRIO_VOLATILE double number)
/*
* The sign of NaN is always false
*/
-TRIO_PRIVATE int
-trio_fpclass(TRIO_VOLATILE double number,
- int *is_negative)
+TRIO_PUBLIC int
+trio_fpclassify_and_signbit
+TRIO_ARGS2((number, is_negative),
+ double number,
+ int *is_negative)
{
#if defined(fpclassify) && defined(signbit)
/*
@@ -637,7 +642,46 @@ trio_fpclass(TRIO_VOLATILE double number,
*is_negative = (number < 0.0);
return TRIO_FP_NORMAL;
}
-
+
+#elif defined(FP_PLUS_NORM) || defined(__hpux)
+
+ /*
+ * HP-UX 9.x and 10.x have an fpclassify() function, that is different
+ * from the C99 fpclassify() macro supported on HP-UX 11.x.
+ */
+ switch (fpclassify(number)) {
+ case FP_QNAN:
+ case FP_SNAN:
+ *is_negative = TRIO_FALSE;
+ return TRIO_FP_NAN;
+ case FP_PLUS_INF:
+ *is_negative = TRIO_FALSE;
+ return TRIO_FP_INFINITE;
+ case FP_MINUS_INF:
+ *is_negative = TRIO_TRUE;
+ return TRIO_FP_INFINITE;
+ case FP_PLUS_DENORM:
+ *is_negative = TRIO_FALSE;
+ return TRIO_FP_SUBNORMAL;
+ case FP_MINUS_DENORM:
+ *is_negative = TRIO_TRUE;
+ return TRIO_FP_SUBNORMAL;
+ case FP_PLUS_ZERO:
+ *is_negative = TRIO_FALSE;
+ return TRIO_FP_ZERO;
+ case FP_MINUS_ZERO:
+ *is_negative = TRIO_TRUE;
+ return TRIO_FP_ZERO;
+ case FP_PLUS_NORM:
+ *is_negative = TRIO_FALSE;
+ return TRIO_FP_NORMAL;
+ case FP_MINUS_NORM:
+ *is_negative = TRIO_TRUE;
+ return TRIO_FP_NORMAL;
+ default:
+ assert(0);
+ }
+
#else
/*
* Fallback solution.
@@ -687,11 +731,13 @@ trio_fpclass(TRIO_VOLATILE double number,
sign bit set (i.e. is negative).
*/
TRIO_PUBLIC int
-trio_signbit(TRIO_VOLATILE double number)
+trio_signbit
+TRIO_ARGS1((number),
+ double number)
{
int is_negative;
- (void)trio_fpclass(number, &is_negative);
+ (void)trio_fpclassify_and_signbit(number, &is_negative);
return is_negative;
}
@@ -702,11 +748,13 @@ trio_signbit(TRIO_VOLATILE double number)
@return Enumerable value indicating the class of @p number
*/
TRIO_PUBLIC int
-trio_fpclassify(TRIO_VOLATILE double number)
+trio_fpclassify
+TRIO_ARGS1((number),
+ double number)
{
int dummy;
- return trio_fpclass(number, &dummy);
+ return trio_fpclassify_and_signbit(number, &dummy);
}
@@ -723,7 +771,10 @@ trio_fpclassify(TRIO_VOLATILE double number)
#if defined(STANDALONE)
# include <stdio.h>
-static const char *getClassification(int type)
+static TRIO_CONST char *
+getClassification
+TRIO_ARGS1((type)
+ int type)
{
switch (type) {
case TRIO_FP_INFINITE:
@@ -741,7 +792,11 @@ static const char *getClassification(int type)
}
}
-static void print_class(const char *prefix, double number)
+static void
+print_class
+TRIO_ARGS2((prefix, number)
+ TRIO_CONST char *prefix,
+ double number)
{
printf("%-6s: %s %-15s %g\n",
prefix,
@@ -750,13 +805,13 @@ static void print_class(const char *prefix, double number)
number);
}
-int main(void)
+int main(TRIO_NOARGS)
{
double my_nan;
double my_pinf;
double my_ninf;
# if defined(TRIO_PLATFORM_UNIX)
- void (*signal_handler)(int);
+ void (*signal_handler) TRIO_PROTO((int));
# endif
my_nan = trio_nan();
diff --git a/trionan.h b/trionan.h
index ab2102d7..bed0c120 100644
--- a/trionan.h
+++ b/trionan.h
@@ -35,39 +35,44 @@ enum {
/*
* Return NaN (Not-a-Number).
*/
-TRIO_PUBLIC double trio_nan(void);
+TRIO_PUBLIC double trio_nan TRIO_PROTO((void));
/*
* Return positive infinity.
*/
-TRIO_PUBLIC double trio_pinf(void);
+TRIO_PUBLIC double trio_pinf TRIO_PROTO((void));
/*
* Return negative infinity.
*/
-TRIO_PUBLIC double trio_ninf(void);
+TRIO_PUBLIC double trio_ninf TRIO_PROTO((void));
/*
+ * Return negative zero.
+ */
+TRIO_PUBLIC double trio_nzero TRIO_PROTO((TRIO_NOARGS));
+
+/*
* If number is a NaN return non-zero, otherwise return zero.
*/
-TRIO_PUBLIC int trio_isnan(double number);
+TRIO_PUBLIC int trio_isnan TRIO_PROTO((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 TRIO_PROTO((double number));
/*
* If number is finite return non-zero, otherwise return zero.
*/
-TRIO_PUBLIC int trio_isfinite(double number);
+TRIO_PUBLIC int trio_isfinite TRIO_PROTO((double number));
-TRIO_PUBLIC int trio_signbit(double number);
+TRIO_PUBLIC int trio_signbit TRIO_PROTO((double number));
-TRIO_PUBLIC int trio_fpclassify(double number);
+TRIO_PUBLIC int trio_fpclassify TRIO_PROTO((double number));
-TRIO_PUBLIC double trio_nzero(void);
+TRIO_PUBLIC int trio_fpclassify_and_signbit TRIO_PROTO((double number, int *is_negative));
#ifdef __cplusplus
}
diff --git a/triop.h b/triop.h
index ead673a1..8462c56f 100644
--- a/triop.h
+++ b/triop.h
@@ -26,8 +26,14 @@
#ifndef TRIO_TRIOP_H
#define TRIO_TRIOP_H
+#include "triodef.h"
+
#include <stdlib.h>
-#include <stdarg.h>
+#if defined(TRIO_COMPILER_ANCIENT)
+# include <varargs.h>
+#else
+# include <stdarg.h>
+#endif
#ifdef __cplusplus
extern "C" {
@@ -71,70 +77,71 @@ extern "C" {
# define TRIO_FREE(x) free(x)
#endif
+
/*************************************************************************
* User-defined specifiers
*/
-typedef int (*trio_callback_t)(void *);
+typedef int (*trio_callback_t) TRIO_PROTO((trio_pointer_t));
-void *trio_register(trio_callback_t callback, const char *name);
-void trio_unregister(void *handle);
+trio_pointer_t trio_register TRIO_PROTO((trio_callback_t callback, const char *name));
+void trio_unregister TRIO_PROTO((trio_pointer_t handle));
-const char *trio_get_format(void *ref);
-void *trio_get_argument(void *ref);
+TRIO_CONST char *trio_get_format TRIO_PROTO((trio_pointer_t ref));
+trio_pointer_t trio_get_argument TRIO_PROTO((trio_pointer_t ref));
/* Modifiers */
-int trio_get_width(void *ref);
-void trio_set_width(void *ref, int width);
-int trio_get_precision(void *ref);
-void trio_set_precision(void *ref, int precision);
-int trio_get_base(void *ref);
-void trio_set_base(void *ref, int base);
-int trio_get_padding(void *ref);
-void trio_set_padding(void *ref, int is_padding);
-int trio_get_short(void *ref); /* h */
-void trio_set_shortshort(void *ref, int is_shortshort);
-int trio_get_shortshort(void *ref); /* hh */
-void trio_set_short(void *ref, int is_short);
-int trio_get_long(void *ref); /* l */
-void trio_set_long(void *ref, int is_long);
-int trio_get_longlong(void *ref); /* ll */
-void trio_set_longlong(void *ref, int is_longlong);
-int trio_get_longdouble(void *ref); /* L */
-void trio_set_longdouble(void *ref, int is_longdouble);
-int trio_get_alternative(void *ref); /* # */
-void trio_set_alternative(void *ref, int is_alternative);
-int trio_get_alignment(void *ref); /* - */
-void trio_set_alignment(void *ref, int is_leftaligned);
-int trio_get_spacing(void *ref); /* (space) */
-void trio_set_spacing(void *ref, int is_space);
-int trio_get_sign(void *ref); /* + */
-void trio_set_sign(void *ref, int is_showsign);
-int trio_get_quote(void *ref); /* ' */
-void trio_set_quote(void *ref, int is_quote);
-int trio_get_upper(void *ref);
-void trio_set_upper(void *ref, int is_upper);
+int trio_get_width TRIO_PROTO((trio_pointer_t ref));
+void trio_set_width TRIO_PROTO((trio_pointer_t ref, int width));
+int trio_get_precision TRIO_PROTO((trio_pointer_t ref));
+void trio_set_precision TRIO_PROTO((trio_pointer_t ref, int precision));
+int trio_get_base TRIO_PROTO((trio_pointer_t ref));
+void trio_set_base TRIO_PROTO((trio_pointer_t ref, int base));
+int trio_get_padding TRIO_PROTO((trio_pointer_t ref));
+void trio_set_padding TRIO_PROTO((trio_pointer_t ref, int is_padding));
+int trio_get_short TRIO_PROTO((trio_pointer_t ref)); /* h */
+void trio_set_shortshort TRIO_PROTO((trio_pointer_t ref, int is_shortshort));
+int trio_get_shortshort TRIO_PROTO((trio_pointer_t ref)); /* hh */
+void trio_set_short TRIO_PROTO((trio_pointer_t ref, int is_short));
+int trio_get_long TRIO_PROTO((trio_pointer_t ref)); /* l */
+void trio_set_long TRIO_PROTO((trio_pointer_t ref, int is_long));
+int trio_get_longlong TRIO_PROTO((trio_pointer_t ref)); /* ll */
+void trio_set_longlong TRIO_PROTO((trio_pointer_t ref, int is_longlong));
+int trio_get_longdouble TRIO_PROTO((trio_pointer_t ref)); /* L */
+void trio_set_longdouble TRIO_PROTO((trio_pointer_t ref, int is_longdouble));
+int trio_get_alternative TRIO_PROTO((trio_pointer_t ref)); /* # */
+void trio_set_alternative TRIO_PROTO((trio_pointer_t ref, int is_alternative));
+int trio_get_alignment TRIO_PROTO((trio_pointer_t ref)); /* - */
+void trio_set_alignment TRIO_PROTO((trio_pointer_t ref, int is_leftaligned));
+int trio_get_spacing TRIO_PROTO((trio_pointer_t ref)); /* TRIO_PROTO((space) */
+void trio_set_spacing TRIO_PROTO((trio_pointer_t ref, int is_space));
+int trio_get_sign TRIO_PROTO((trio_pointer_t ref)); /* + */
+void trio_set_sign TRIO_PROTO((trio_pointer_t ref, int is_showsign));
+int trio_get_quote TRIO_PROTO((trio_pointer_t ref)); /* ' */
+void trio_set_quote TRIO_PROTO((trio_pointer_t ref, int is_quote));
+int trio_get_upper TRIO_PROTO((trio_pointer_t ref));
+void trio_set_upper TRIO_PROTO((trio_pointer_t ref, int is_upper));
#if TRIO_C99
-int trio_get_largest(void *ref); /* j */
-void trio_set_largest(void *ref, int is_largest);
-int trio_get_ptrdiff(void *ref); /* t */
-void trio_set_ptrdiff(void *ref, int is_ptrdiff);
-int trio_get_size(void *ref); /* z / Z */
-void trio_set_size(void *ref, int is_size);
+int trio_get_largest TRIO_PROTO((trio_pointer_t ref)); /* j */
+void trio_set_largest TRIO_PROTO((trio_pointer_t ref, int is_largest));
+int trio_get_ptrdiff TRIO_PROTO((trio_pointer_t ref)); /* t */
+void trio_set_ptrdiff TRIO_PROTO((trio_pointer_t ref, int is_ptrdiff));
+int trio_get_size TRIO_PROTO((trio_pointer_t ref)); /* z / Z */
+void trio_set_size TRIO_PROTO((trio_pointer_t ref, int is_size));
#endif
/* Printing */
-int trio_print_ref(void *ref, const char *format, ...);
-int trio_vprint_ref(void *ref, const char *format, va_list args);
-int trio_printv_ref(void *ref, const char *format, void **args);
-
-void trio_print_int(void *ref, int number);
-void trio_print_uint(void *ref, unsigned int number);
-/* void trio_print_long(void *ref, long number); */
-/* void trio_print_ulong(void *ref, unsigned long number); */
-void trio_print_double(void *ref, double number);
-void trio_print_string(void *ref, char *string);
-void trio_print_pointer(void *ref, void *pointer);
+int trio_print_ref TRIO_PROTO((trio_pointer_t ref, const char *format, ...));
+int trio_vprint_ref TRIO_PROTO((trio_pointer_t ref, const char *format, va_list args));
+int trio_printv_ref TRIO_PROTO((trio_pointer_t ref, const char *format, trio_pointer_t *args));
+
+void trio_print_int TRIO_PROTO((trio_pointer_t ref, int number));
+void trio_print_uint TRIO_PROTO((trio_pointer_t ref, unsigned int number));
+/* void trio_print_long TRIO_PROTO((trio_pointer_t ref, long number)); */
+/* void trio_print_ulong TRIO_PROTO((trio_pointer_t ref, unsigned long number)); */
+void trio_print_double TRIO_PROTO((trio_pointer_t ref, double number));
+void trio_print_string TRIO_PROTO((trio_pointer_t ref, char *string));
+void trio_print_pointer TRIO_PROTO((trio_pointer_t ref, trio_pointer_t pointer));
#ifdef __cplusplus
} /* extern "C" */
diff --git a/triostr.c b/triostr.c
index 760be55c..43a30dad 100644
--- a/triostr.c
+++ b/triostr.c
@@ -15,8 +15,6 @@
*
************************************************************************/
-static const char rcsid[] = "@(#)$Id$";
-
/*************************************************************************
* Include files
*/
@@ -26,21 +24,33 @@ static const char rcsid[] = "@(#)$Id$";
#include <string.h>
#include <ctype.h>
#include <math.h>
+#include "triodef.h"
#include "triostr.h"
/*************************************************************************
* Definitions
*/
-#ifndef NULL
+#if !defined(TRIO_STRING_PUBLIC)
+# define TRIO_STRING_PUBLIC TRIO_PUBLIC
+#endif
+#if !defined(TRIO_STRING_PRIVATE)
+# define TRIO_STRING_PRIVATE TRIO_PRIVATE
+#endif
+
+#if !defined(NULL)
# define NULL 0
#endif
-#define NIL ((char)0)
-#ifndef FALSE
+#if !defined(NIL)
+# define NIL ((char)0)
+#endif
+#if !defined(FALSE)
# define FALSE (1 == 0)
# define TRUE (! FALSE)
#endif
-#define BOOLEAN_T int
+#if !defined(BOOLEAN_T)
+# define BOOLEAN_T int
+#endif
#if defined(TRIO_COMPILER_SUPPORTS_C99)
# define USE_STRTOD
@@ -74,6 +84,14 @@ struct _trio_string_t
};
/*************************************************************************
+ * Constants
+ */
+
+#if !defined(TRIO_MINIMAL)
+static TRIO_CONST char rcsid[] = "@(#)$Id$";
+#endif
+
+/*************************************************************************
* Static String Functions
*/
@@ -90,8 +108,10 @@ struct _trio_string_t
@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)
+TRIO_STRING_PUBLIC char *
+trio_create
+TRIO_ARGS1((size),
+ size_t size)
{
return (char *)TRIO_MALLOC(size);
}
@@ -102,8 +122,10 @@ trio_create(size_t size)
@param string String to be freed.
*/
-TRIO_PUBLIC TRIO_INLINE void
-trio_destroy(char *string)
+TRIO_STRING_PUBLIC void
+trio_destroy
+TRIO_ARGS1((string),
+ char *string)
{
if (string)
{
@@ -118,34 +140,16 @@ trio_destroy(char *string)
@param string String to measure.
@return Number of characters in @string.
*/
-TRIO_PUBLIC TRIO_INLINE size_t
-trio_length(const char *string)
+TRIO_STRING_PUBLIC size_t
+trio_length
+TRIO_ARGS1((string),
+ TRIO_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;
-}
-
-
+#if !defined(TRIO_MINIMAL)
/**
Append @p source at the end of @p target.
@@ -159,17 +163,20 @@ TrioDuplicateMax(const char *source, size_t size)
result in a buffer overrun.
@post @p target will be zero terminated.
*/
-TRIO_PUBLIC int
-trio_append(char *target,
- const char *source)
+TRIO_STRING_PUBLIC int
+trio_append
+TRIO_ARGS2((target, source),
+ char *target,
+ TRIO_CONST char *source)
{
assert(target);
assert(source);
return (strcat(target, source) != NULL);
}
+#endif /* !defined(TRIO_MINIMAL) */
-
+#if !defined(TRIO_MINIMAL)
/**
Append at most @p max characters from @p source to @p target.
@@ -185,10 +192,12 @@ trio_append(char *target,
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)
+TRIO_STRING_PUBLIC int
+trio_append_max
+TRIO_ARGS3((target, max, source),
+ char *target,
+ size_t max,
+ TRIO_CONST char *source)
{
size_t length;
@@ -203,8 +212,10 @@ trio_append_max(char *target,
}
return TRUE;
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/**
Determine if a string contains a substring.
@@ -212,17 +223,21 @@ trio_append_max(char *target,
@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)
+TRIO_STRING_PUBLIC int
+trio_contains
+TRIO_ARGS2((string, substring),
+ TRIO_CONST char *string,
+ TRIO_CONST char *substring)
{
assert(string);
assert(substring);
return (0 != strstr(string, substring));
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/**
Copy @p source to @p target.
@@ -236,16 +251,19 @@ trio_contains(const char *string,
result in a buffer overrun.
@post @p target will be zero terminated.
*/
-TRIO_PUBLIC int
-trio_copy(char *target,
- const char *source)
+TRIO_STRING_PUBLIC int
+trio_copy
+TRIO_ARGS2((target, source),
+ char *target,
+ TRIO_CONST char *source)
{
assert(target);
assert(source);
-
+
(void)strcpy(target, source);
return TRUE;
}
+#endif /* !defined(TRIO_MINIMAL) */
/**
@@ -262,10 +280,12 @@ trio_copy(char *target,
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)
+TRIO_STRING_PUBLIC int
+trio_copy_max
+TRIO_ARGS3((target, max, source),
+ char *target,
+ size_t max,
+ TRIO_CONST char *source)
{
assert(target);
assert(source);
@@ -277,6 +297,30 @@ trio_copy_max(char *target,
}
+/*
+ * TrioDuplicateMax
+ */
+TRIO_STRING_PRIVATE char *
+TrioDuplicateMax
+TRIO_ARGS2((source, size),
+ TRIO_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;
+}
+
+
/**
Duplicate @p source.
@@ -285,13 +329,16 @@ trio_copy_max(char *target,
@post @p target will be zero terminated.
*/
-TRIO_PUBLIC char *
-trio_duplicate(const char *source)
+TRIO_STRING_PUBLIC char *
+trio_duplicate
+TRIO_ARGS1((source),
+ TRIO_CONST char *source)
{
return TrioDuplicateMax(source, trio_length(source));
}
+#if !defined(TRIO_MINIMAL)
/**
Duplicate at most @p max characters of @p source.
@@ -301,9 +348,10 @@ trio_duplicate(const char *source)
@post @p target will be zero terminated.
*/
-TRIO_PUBLIC char *
-trio_duplicate_max(const char *source,
- size_t max)
+TRIO_STRING_PUBLIC char *
+trio_duplicate_max TRIO_ARGS2((source, max),
+ TRIO_CONST char *source,
+ size_t max)
{
size_t length;
@@ -317,6 +365,7 @@ trio_duplicate_max(const char *source,
}
return TrioDuplicateMax(source, length);
}
+#endif /* !defined(TRIO_MINIMAL) */
/**
@@ -328,9 +377,11 @@ trio_duplicate_max(const char *source,
Case-insensitive comparison.
*/
-TRIO_PUBLIC int
-trio_equal(const char *first,
- const char *second)
+TRIO_STRING_PUBLIC int
+trio_equal
+TRIO_ARGS2((first, second),
+ TRIO_CONST char *first,
+ TRIO_CONST char *second)
{
assert(first);
assert(second);
@@ -365,9 +416,11 @@ trio_equal(const char *first,
Case-sensitive comparison.
*/
-TRIO_PUBLIC int
-trio_equal_case(const char *first,
- const char *second)
+TRIO_STRING_PUBLIC int
+trio_equal_case
+TRIO_ARGS2((first, second),
+ TRIO_CONST char *first,
+ TRIO_CONST char *second)
{
assert(first);
assert(second);
@@ -380,6 +433,7 @@ trio_equal_case(const char *first,
}
+#if !defined(TRIO_MINIMAL)
/**
Compare if two strings up until the first @p max characters are equal.
@@ -390,10 +444,12 @@ trio_equal_case(const char *first,
Case-sensitive comparison.
*/
-TRIO_PUBLIC int
-trio_equal_case_max(const char *first,
- size_t max,
- const char *second)
+TRIO_STRING_PUBLIC int
+trio_equal_case_max
+TRIO_ARGS3((first, max, second),
+ TRIO_CONST char *first,
+ size_t max,
+ TRIO_CONST char *second)
{
assert(first);
assert(second);
@@ -404,6 +460,7 @@ trio_equal_case_max(const char *first,
}
return FALSE;
}
+#endif /* !defined(TRIO_MINIMAL) */
/**
@@ -415,9 +472,11 @@ trio_equal_case_max(const char *first,
Collating characters are considered equal.
*/
-TRIO_PUBLIC int
-trio_equal_locale(const char *first,
- const char *second)
+TRIO_STRING_PUBLIC int
+trio_equal_locale
+TRIO_ARGS2((first, second),
+ TRIO_CONST char *first,
+ TRIO_CONST char *second)
{
assert(first);
assert(second);
@@ -440,10 +499,12 @@ trio_equal_locale(const char *first,
Case-insensitive comparison.
*/
-TRIO_PUBLIC int
-trio_equal_max(const char *first,
- size_t max,
- const char *second)
+TRIO_STRING_PUBLIC int
+trio_equal_max
+TRIO_ARGS3((first, max, second),
+ TRIO_CONST char *first,
+ size_t max,
+ TRIO_CONST char *second)
{
assert(first);
assert(second);
@@ -478,8 +539,10 @@ trio_equal_max(const char *first,
@param error_number Error number.
@return Textual description of @p error_number.
*/
-TRIO_PUBLIC const char *
-trio_error(int error_number)
+TRIO_STRING_PUBLIC TRIO_CONST char *
+trio_error
+TRIO_ARGS1((error_number),
+ int error_number)
{
#if defined(USE_STRERROR)
return strerror(error_number);
@@ -489,6 +552,7 @@ trio_error(int error_number)
}
+#if !defined(TRIO_MINIMAL)
/**
Format the date/time according to @p format.
@@ -501,11 +565,13 @@ trio_error(int error_number)
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)
+TRIO_STRING_PUBLIC size_t
+trio_format_date_max
+TRIO_ARGS4((target, max, format, datetime),
+ char *target,
+ size_t max,
+ TRIO_CONST char *format,
+ TRIO_CONST struct tm *datetime)
{
assert(target);
assert(format);
@@ -514,8 +580,10 @@ trio_format_date_max(char *target,
return strftime(target, max, format, datetime);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/**
Calculate a hash value for a string.
@@ -526,9 +594,11 @@ trio_format_date_max(char *target,
@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)
+TRIO_STRING_PUBLIC unsigned long
+trio_hash
+TRIO_ARGS2((string, type),
+ TRIO_CONST char *string,
+ int type)
{
unsigned long value = 0L;
char ch;
@@ -550,8 +620,10 @@ trio_hash(const char *string,
}
return value;
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/**
Find first occurrence of a character in a string.
@@ -559,16 +631,20 @@ trio_hash(const char *string,
@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)
+TRIO_STRING_PUBLIC char *
+trio_index
+TRIO_ARGS2((string, character),
+ TRIO_CONST char *string,
+ int character)
{
assert(string);
return strchr(string, character);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/**
Find last occurrence of a character in a string.
@@ -576,31 +652,39 @@ trio_index(const char *string,
@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)
+TRIO_STRING_PUBLIC char *
+trio_index_last
+TRIO_ARGS2((string, character),
+ TRIO_CONST char *string,
+ int character)
{
assert(string);
return strchr(string, character);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/**
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)
+TRIO_STRING_PUBLIC int
+trio_lower
+TRIO_ARGS1((target),
+ char *target)
{
assert(target);
return trio_span_function(target, target, tolower);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/**
Compare two strings using wildcards.
@@ -614,9 +698,11 @@ trio_lower(char *target)
@li @c * Match any number of characters.
@li @c ? Match a single character.
*/
-TRIO_PUBLIC int
-trio_match(const char *string,
- const char *pattern)
+TRIO_STRING_PUBLIC int
+trio_match
+TRIO_ARGS2((string, pattern),
+ TRIO_CONST char *string,
+ TRIO_CONST char *pattern)
{
assert(string);
assert(pattern);
@@ -648,8 +734,10 @@ trio_match(const char *string,
return FALSE;
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/**
Compare two strings using wildcards.
@@ -663,9 +751,11 @@ trio_match(const char *string,
@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)
+TRIO_STRING_PUBLIC int
+trio_match_case
+TRIO_ARGS2((string, pattern),
+ TRIO_CONST char *string,
+ TRIO_CONST char *pattern)
{
assert(string);
assert(pattern);
@@ -697,8 +787,10 @@ trio_match_case(const char *string,
return FALSE;
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/**
Execute a function on each character in string.
@@ -707,10 +799,12 @@ trio_match_case(const char *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))
+TRIO_STRING_PUBLIC size_t
+trio_span_function
+TRIO_ARGS3((target, source, Function),
+ char *target,
+ TRIO_CONST char *source,
+ int (*Function) TRIO_PROTO((int)))
{
size_t count = 0;
@@ -725,8 +819,10 @@ trio_span_function(char *target,
}
return count;
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/**
Search for a substring in a string.
@@ -735,17 +831,21 @@ trio_span_function(char *target,
@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)
+TRIO_STRING_PUBLIC char *
+trio_substring
+TRIO_ARGS2((string, substring),
+ TRIO_CONST char *string,
+ TRIO_CONST char *substring)
{
assert(string);
assert(substring);
return strstr(string, substring);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/**
Search for a substring in the first @p max characters of a string.
@@ -755,10 +855,12 @@ trio_substring(const char *string,
@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)
+TRIO_STRING_PUBLIC char *
+trio_substring_max
+TRIO_ARGS3((string, max, substring),
+ TRIO_CONST char *string,
+ size_t max,
+ TRIO_CONST char *substring)
{
size_t count;
size_t size;
@@ -781,8 +883,10 @@ trio_substring_max(const char *string,
}
return result;
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/**
Tokenize string.
@@ -792,13 +896,17 @@ trio_substring_max(const char *string,
@warning @p string will be destroyed.
*/
-TRIO_PUBLIC TRIO_INLINE char *
-trio_tokenize(char *string, const char *delimiters)
+TRIO_STRING_PUBLIC char *
+trio_tokenize
+TRIO_ARGS2((string, delimiters),
+ char *string,
+ TRIO_CONST char *delimiters)
{
assert(delimiters);
return strtok(string, delimiters);
}
+#endif /* !defined(TRIO_MINIMAL) */
/**
@@ -823,29 +931,32 @@ trio_tokenize(char *string, const char *delimiters)
@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);
+TRIO_STRING_PUBLIC trio_long_double_t
+trio_to_long_double
+TRIO_ARGS2((source, endp),
+ TRIO_CONST char *source,
+ char **endp)
+{
+#if defined(USE_STRTOLD)
+ return strtold(source, endp);
#else
- /* Preliminary code */
int isNegative = FALSE;
int isExponentNegative = FALSE;
- unsigned long integer = 0;
- unsigned long fraction = 0;
- unsigned long fracdiv = 1;
+ trio_long_double_t integer = 0.0;
+ trio_long_double_t fraction = 0.0;
unsigned long exponent = 0;
- double value = 0.0;
+ trio_long_double_t base;
+ trio_long_double_t fracdiv = 1.0;
+ trio_long_double_t value = 0.0;
/* First try hex-floats */
if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X')))
{
+ base = 16.0;
source += 2;
while (isxdigit((int)*source))
{
- integer *= 16;
+ integer *= base;
integer += (isdigit((int)*source)
? (*source - '0')
: 10 + (toupper((int)*source) - 'A'));
@@ -856,11 +967,10 @@ trio_to_double(const char *source,
source++;
while (isxdigit((int)*source))
{
- fraction *= 16;
- fraction += (isdigit((int)*source)
- ? (*source - '0')
- : 10 + (toupper((int)*source) - 'A'));
- fracdiv *= 16;
+ fracdiv /= base;
+ fraction += fracdiv * (isdigit((int)*source)
+ ? (*source - '0')
+ : 10 + (toupper((int)*source) - 'A'));
source++;
}
if ((*source == 'p') || (*source == 'P'))
@@ -873,7 +983,7 @@ trio_to_double(const char *source,
}
while (isdigit((int)*source))
{
- exponent *= 10;
+ exponent *= (int)base;
exponent += (*source - '0');
source++;
}
@@ -882,6 +992,7 @@ trio_to_double(const char *source,
}
else /* Then try normal decimal floats */
{
+ base = 10.0;
isNegative = (*source == '-');
/* Skip sign */
if ((*source == '+') || (*source == '-'))
@@ -890,7 +1001,7 @@ trio_to_double(const char *source,
/* Integer part */
while (isdigit((int)*source))
{
- integer *= 10;
+ integer *= base;
integer += (*source - '0');
source++;
}
@@ -900,9 +1011,8 @@ trio_to_double(const char *source,
source++; /* skip decimal point */
while (isdigit((int)*source))
{
- fraction *= 10;
- fraction += (*source - '0');
- fracdiv *= 10;
+ fracdiv /= base;
+ fraction += (*source - '0') * fracdiv;
source++;
}
}
@@ -920,30 +1030,26 @@ trio_to_double(const char *source,
source++;
while (isdigit((int)*source))
{
- exponent *= 10;
+ exponent *= (int)base;
exponent += (*source - '0');
source++;
}
}
}
- value = (double)integer;
- if (fraction != 0)
- {
- value += (double)fraction / (double)fracdiv;
- }
+ value = integer + fraction;
if (exponent != 0)
{
if (isExponentNegative)
- value /= pow((double)10, (double)exponent);
+ value /= pow(base, (double)exponent);
else
- value *= pow((double)10, (double)exponent);
+ value *= pow(base, (double)exponent);
}
if (isNegative)
value = -value;
if (endp)
- *endp = source;
+ *endp = (char *)source;
return value;
#endif
}
@@ -956,18 +1062,44 @@ trio_to_double(const char *source,
@param endp Pointer to end of the converted string.
@return A floating-point number.
- See @ref trio_to_double.
+ See @ref trio_to_long_double.
+*/
+TRIO_STRING_PUBLIC double
+trio_to_double
+TRIO_ARGS2((source, endp),
+ TRIO_CONST char *source,
+ char **endp)
+{
+#if defined(USE_STRTOD)
+ return strtod(source, endp);
+#else
+ return (double)trio_to_long_double(source, endp);
+#endif
+}
+
+#if !defined(TRIO_MINIMAL)
+/**
+ 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_long_double.
*/
-TRIO_PUBLIC TRIO_INLINE float
-trio_to_float(const char *source,
- const char **endp)
+TRIO_STRING_PUBLIC float
+trio_to_float
+TRIO_ARGS2((source, endp),
+ TRIO_CONST char *source,
+ char **endp)
{
#if defined(USE_STRTOF)
- return strtof(source, (char **)endp);
+ return strtof(source, endp);
#else
- return (float)trio_to_double(source, endp);
+ return (float)trio_to_long_double(source, endp);
#endif
}
+#endif /* !defined(TRIO_MINIMAL) */
/**
@@ -977,10 +1109,12 @@ trio_to_float(const char *source,
@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)
+TRIO_STRING_PUBLIC long
+trio_to_long
+TRIO_ARGS3((string, endp, base),
+ TRIO_CONST char *string,
+ char **endp,
+ int base)
{
assert(string);
assert((base >= 2) && (base <= 36));
@@ -989,6 +1123,7 @@ trio_to_long(const char *string,
}
+#if !defined(TRIO_MINIMAL)
/**
Convert string to unsigned integer.
@@ -996,31 +1131,38 @@ trio_to_long(const char *string,
@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)
+TRIO_STRING_PUBLIC unsigned long
+trio_to_unsigned_long
+TRIO_ARGS3((string, endp, base),
+ TRIO_CONST char *string,
+ char **endp,
+ int base)
{
assert(string);
assert((base >= 2) && (base <= 36));
return strtoul(string, endp, base);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/**
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)
+TRIO_STRING_PUBLIC int
+trio_upper
+TRIO_ARGS1((target),
+ char *target)
{
assert(target);
return trio_span_function(target, target, toupper);
}
+#endif /* !defined(TRIO_MINIMAL) */
/** @} End of StaticStrings */
@@ -1040,8 +1182,8 @@ trio_upper(char *target)
/*
* TrioStringAlloc
*/
-TRIO_PRIVATE trio_string_t *
-TrioStringAlloc(void)
+TRIO_STRING_PRIVATE trio_string_t *
+TrioStringAlloc(TRIO_NOARGS)
{
trio_string_t *self;
@@ -1062,9 +1204,11 @@ TrioStringAlloc(void)
* 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)
+TRIO_STRING_PRIVATE BOOLEAN_T
+TrioStringGrow
+TRIO_ARGS2((self, delta),
+ trio_string_t *self,
+ size_t delta)
{
BOOLEAN_T status = FALSE;
char *new_content;
@@ -1092,9 +1236,11 @@ TrioStringGrow(trio_string_t *self,
* 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)
+TRIO_STRING_PRIVATE BOOLEAN_T
+TrioStringGrowTo
+TRIO_ARGS2((self, length),
+ trio_string_t *self,
+ size_t length)
{
length++; /* Room for terminating zero */
return (self->allocated < length)
@@ -1103,14 +1249,17 @@ TrioStringGrowTo(trio_string_t *self,
}
+#if !defined(TRIO_MINIMAL)
/**
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_PUBLIC trio_string_t *
+trio_string_create
+TRIO_ARGS1((initial_size),
+ int initial_size)
{
trio_string_t *self;
@@ -1131,6 +1280,7 @@ trio_string_create(int initial_size)
}
return self;
}
+#endif /* !defined(TRIO_MINIMAL) */
/**
@@ -1138,8 +1288,10 @@ trio_string_create(int initial_size)
@param self Dynamic string
*/
-TRIO_PUBLIC void
-trio_string_destroy(trio_string_t *self)
+TRIO_STRING_PUBLIC void
+trio_string_destroy
+TRIO_ARGS1((self),
+ trio_string_t *self)
{
assert(self);
@@ -1151,6 +1303,7 @@ trio_string_destroy(trio_string_t *self)
}
+#if !defined(TRIO_MINIMAL)
/**
Get a pointer to the content.
@@ -1165,8 +1318,11 @@ trio_string_destroy(trio_string_t *self)
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)
+TRIO_STRING_PUBLIC char *
+trio_string_get
+TRIO_ARGS2((self, offset),
+ trio_string_t *self,
+ int offset)
{
char *result = NULL;
@@ -1180,7 +1336,7 @@ trio_string_get(trio_string_t *self, int offset)
}
if (offset >= 0)
{
- if (offset > self->length)
+ if (offset > (int)self->length)
{
offset = self->length;
}
@@ -1197,6 +1353,7 @@ trio_string_get(trio_string_t *self, int offset)
}
return result;
}
+#endif /* !defined(TRIO_MINIMAL) */
/**
@@ -1208,8 +1365,10 @@ trio_string_get(trio_string_t *self, int offset)
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)
+TRIO_STRING_PUBLIC char *
+trio_string_extract
+TRIO_ARGS1((self),
+ trio_string_t *self)
{
char *result;
@@ -1223,6 +1382,7 @@ trio_string_extract(trio_string_t *self)
}
+#if !defined(TRIO_MINIMAL)
/**
Set the content of the dynamic string.
@@ -1236,22 +1396,27 @@ trio_string_extract(trio_string_t *self)
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)
+TRIO_STRING_PUBLIC void
+trio_xstring_set
+TRIO_ARGS2((self, buffer),
+ trio_string_t *self,
+ char *buffer)
{
assert(self);
trio_destroy(self->content);
self->content = trio_duplicate(buffer);
}
+#endif /* !defined(TRIO_MINIMAL) */
/*
* trio_string_size
*/
-TRIO_PUBLIC int
-trio_string_size(trio_string_t *self)
+TRIO_STRING_PUBLIC int
+trio_string_size
+TRIO_ARGS1((self),
+ trio_string_t *self)
{
assert(self);
@@ -1262,21 +1427,16 @@ trio_string_size(trio_string_t *self)
/*
* trio_string_terminate
*/
-TRIO_PUBLIC void
-trio_string_terminate(trio_string_t *self)
+TRIO_STRING_PUBLIC void
+trio_string_terminate
+TRIO_ARGS1((self),
+ trio_string_t *self)
{
- char *end;
-
- assert(self);
-
- end = trio_string_get(self, -1);
- if (end)
- {
- *end = NIL;
- }
+ trio_xstring_append_char(self, 0);
}
+#if !defined(TRIO_MINIMAL)
/**
Append the second string to the first.
@@ -1284,9 +1444,11 @@ trio_string_terminate(trio_string_t *self)
@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)
+TRIO_STRING_PUBLIC int
+trio_string_append
+TRIO_ARGS2((self, other),
+ trio_string_t *self,
+ trio_string_t *other)
{
size_t length;
@@ -1303,14 +1465,18 @@ trio_string_append(trio_string_t *self,
error:
return FALSE;
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/*
* trio_xstring_append
*/
-TRIO_PUBLIC int
-trio_xstring_append(trio_string_t *self,
- const char *other)
+TRIO_STRING_PUBLIC int
+trio_xstring_append
+TRIO_ARGS2((self, other),
+ trio_string_t *self,
+ TRIO_CONST char *other)
{
size_t length;
@@ -1327,18 +1493,21 @@ trio_xstring_append(trio_string_t *self,
error:
return FALSE;
}
+#endif /* !defined(TRIO_MINIMAL) */
/*
* trio_xstring_append_char
*/
-TRIO_PUBLIC int
-trio_xstring_append_char(trio_string_t *self,
- char character)
+TRIO_STRING_PUBLIC int
+trio_xstring_append_char
+TRIO_ARGS2((self, character),
+ trio_string_t *self,
+ char character)
{
assert(self);
- if (self->length >= trio_string_size(self))
+ if ((int)self->length >= trio_string_size(self))
{
if (!TrioStringGrow(self, 0))
goto error;
@@ -1352,6 +1521,7 @@ trio_xstring_append_char(trio_string_t *self,
}
+#if !defined(TRIO_MINIMAL)
/**
Search for the first occurrence of second parameter in the first.
@@ -1359,37 +1529,47 @@ trio_xstring_append_char(trio_string_t *self,
@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)
+TRIO_STRING_PUBLIC int
+trio_string_contains
+TRIO_ARGS2((self, other),
+ trio_string_t *self,
+ trio_string_t *other)
{
assert(self);
assert(other);
return trio_contains(self->content, other->content);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/*
* trio_xstring_contains
*/
-TRIO_PUBLIC int
-trio_xstring_contains(trio_string_t *self,
- const char *other)
+TRIO_STRING_PUBLIC int
+trio_xstring_contains
+TRIO_ARGS2((self, other),
+ trio_string_t *self,
+ TRIO_CONST char *other)
{
assert(self);
assert(other);
return trio_contains(self->content, other);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/*
* trio_string_copy
*/
-TRIO_PUBLIC int
-trio_string_copy(trio_string_t *self,
- trio_string_t *other)
+TRIO_STRING_PUBLIC int
+trio_string_copy
+TRIO_ARGS2((self, other),
+ trio_string_t *self,
+ trio_string_t *other)
{
assert(self);
assert(other);
@@ -1397,14 +1577,18 @@ trio_string_copy(trio_string_t *self,
self->length = 0;
return trio_string_append(self, other);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/*
* trio_xstring_copy
*/
-TRIO_PUBLIC int
-trio_xstring_copy(trio_string_t *self,
- const char *other)
+TRIO_STRING_PUBLIC int
+trio_xstring_copy
+TRIO_ARGS2((self, other),
+ trio_string_t *self,
+ TRIO_CONST char *other)
{
assert(self);
assert(other);
@@ -1412,13 +1596,17 @@ trio_xstring_copy(trio_string_t *self,
self->length = 0;
return trio_xstring_append(self, other);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/*
* trio_string_duplicate
*/
-TRIO_PUBLIC trio_string_t *
-trio_string_duplicate(trio_string_t *other)
+TRIO_STRING_PUBLIC trio_string_t *
+trio_string_duplicate
+TRIO_ARGS1((other),
+ trio_string_t *other)
{
trio_string_t *self;
@@ -1440,13 +1628,16 @@ trio_string_duplicate(trio_string_t *other)
}
return self;
}
+#endif /* !defined(TRIO_MINIMAL) */
/*
* trio_xstring_duplicate
*/
-TRIO_PUBLIC trio_string_t *
-trio_xstring_duplicate(const char *other)
+TRIO_STRING_PUBLIC trio_string_t *
+trio_xstring_duplicate
+TRIO_ARGS1((other),
+ TRIO_CONST char *other)
{
trio_string_t *self;
@@ -1470,168 +1661,215 @@ trio_xstring_duplicate(const char *other)
}
+#if !defined(TRIO_MINIMAL)
/*
* trio_string_equal
*/
-TRIO_PUBLIC int
-trio_string_equal(trio_string_t *self,
- trio_string_t *other)
+TRIO_STRING_PUBLIC int
+trio_string_equal
+TRIO_ARGS2((self, other),
+ trio_string_t *self,
+ trio_string_t *other)
{
assert(self);
assert(other);
return trio_equal(self->content, other->content);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/*
* trio_xstring_equal
*/
-TRIO_PUBLIC int
-trio_xstring_equal(trio_string_t *self,
- const char *other)
+TRIO_STRING_PUBLIC int
+trio_xstring_equal
+TRIO_ARGS2((self, other),
+ trio_string_t *self,
+ TRIO_CONST char *other)
{
assert(self);
assert(other);
return trio_equal(self->content, other);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/*
* trio_string_equal_max
*/
-TRIO_PUBLIC int
-trio_string_equal_max(trio_string_t *self,
- size_t max,
- trio_string_t *other)
+TRIO_STRING_PUBLIC int
+trio_string_equal_max
+TRIO_ARGS3((self, max, other),
+ trio_string_t *self,
+ size_t max,
+ trio_string_t *other)
{
assert(self);
assert(other);
return trio_equal_max(self->content, max, other->content);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/*
* trio_xstring_equal_max
*/
-TRIO_PUBLIC int
-trio_xstring_equal_max(trio_string_t *self,
- size_t max,
- const char *other)
+TRIO_STRING_PUBLIC int
+trio_xstring_equal_max
+TRIO_ARGS3((self, max, other),
+ trio_string_t *self,
+ size_t max,
+ TRIO_CONST char *other)
{
assert(self);
assert(other);
return trio_equal_max(self->content, max, other);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/*
* trio_string_equal_case
*/
-TRIO_PUBLIC int
-trio_string_equal_case(trio_string_t *self,
- trio_string_t *other)
+TRIO_STRING_PUBLIC int
+trio_string_equal_case
+TRIO_ARGS2((self, other),
+ trio_string_t *self,
+ trio_string_t *other)
{
assert(self);
assert(other);
return trio_equal_case(self->content, other->content);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/*
* trio_xstring_equal_case
*/
-TRIO_PUBLIC int
-trio_xstring_equal_case(trio_string_t *self,
- const char *other)
+TRIO_STRING_PUBLIC int
+trio_xstring_equal_case
+TRIO_ARGS2((self, other),
+ trio_string_t *self,
+ TRIO_CONST char *other)
{
assert(self);
assert(other);
return trio_equal_case(self->content, other);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/*
* trio_string_equal_case_max
*/
-TRIO_PUBLIC int
-trio_string_equal_case_max(trio_string_t *self,
- size_t max,
- trio_string_t *other)
+TRIO_STRING_PUBLIC int
+trio_string_equal_case_max
+TRIO_ARGS3((self, max, other),
+ 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);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/*
* trio_xstring_equal_case_max
*/
-TRIO_PUBLIC int
-trio_xstring_equal_case_max(trio_string_t *self,
- size_t max,
- const char *other)
+TRIO_STRING_PUBLIC int
+trio_xstring_equal_case_max
+TRIO_ARGS3((self, max, other),
+ trio_string_t *self,
+ size_t max,
+ TRIO_CONST char *other)
{
assert(self);
assert(other);
return trio_equal_case_max(self->content, max, other);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/*
* 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)
+TRIO_STRING_PUBLIC size_t
+trio_string_format_date_max
+TRIO_ARGS4((self, max, format, datetime),
+ trio_string_t *self,
+ size_t max,
+ TRIO_CONST char *format,
+ TRIO_CONST struct tm *datetime)
{
assert(self);
return trio_format_date_max(self->content, max, format, datetime);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/*
* trio_string_index
*/
-TRIO_PUBLIC char *
-trio_string_index(trio_string_t *self,
- int character)
+TRIO_STRING_PUBLIC char *
+trio_string_index
+TRIO_ARGS2((self, character),
+ trio_string_t *self,
+ int character)
{
assert(self);
return trio_index(self->content, character);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/*
* trio_string_index_last
*/
-TRIO_PUBLIC char *
-trio_string_index_last(trio_string_t *self,
- int character)
+TRIO_STRING_PUBLIC char *
+trio_string_index_last
+TRIO_ARGS2((self, character),
+ trio_string_t *self,
+ int character)
{
assert(self);
return trio_index_last(self->content, character);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/*
* trio_string_length
*/
-TRIO_PUBLIC int
-trio_string_length(trio_string_t *self)
+TRIO_STRING_PUBLIC int
+trio_string_length
+TRIO_ARGS1((self),
+ trio_string_t *self)
{
assert(self);
@@ -1641,113 +1879,146 @@ trio_string_length(trio_string_t *self)
}
return self->length;
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/*
* trio_string_lower
*/
-TRIO_PUBLIC int
-trio_string_lower(trio_string_t *self)
+TRIO_STRING_PUBLIC int
+trio_string_lower
+TRIO_ARGS1((self),
+ trio_string_t *self)
{
assert(self);
return trio_lower(self->content);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/*
* trio_string_match
*/
-TRIO_PUBLIC int
-trio_string_match(trio_string_t *self,
- trio_string_t *other)
+TRIO_STRING_PUBLIC int
+trio_string_match
+TRIO_ARGS2((self, other),
+ trio_string_t *self,
+ trio_string_t *other)
{
assert(self);
assert(other);
return trio_match(self->content, other->content);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/*
* trio_xstring_match
*/
-TRIO_PUBLIC int
-trio_xstring_match(trio_string_t *self,
- const char *other)
+TRIO_STRING_PUBLIC int
+trio_xstring_match
+TRIO_ARGS2((self, other),
+ trio_string_t *self,
+ TRIO_CONST char *other)
{
assert(self);
assert(other);
return trio_match(self->content, other);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/*
* trio_string_match_case
*/
-TRIO_PUBLIC int
-trio_string_match_case(trio_string_t *self,
- trio_string_t *other)
+TRIO_STRING_PUBLIC int
+trio_string_match_case
+TRIO_ARGS2((self, other),
+ trio_string_t *self,
+ trio_string_t *other)
{
assert(self);
assert(other);
return trio_match_case(self->content, other->content);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/*
* trio_xstring_match_case
*/
-TRIO_PUBLIC int
-trio_xstring_match_case(trio_string_t *self,
- const char *other)
+TRIO_STRING_PUBLIC int
+trio_xstring_match_case
+TRIO_ARGS2((self, other),
+ trio_string_t *self,
+ TRIO_CONST char *other)
{
assert(self);
assert(other);
return trio_match_case(self->content, other);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/*
* trio_string_substring
*/
-TRIO_PUBLIC char *
-trio_string_substring(trio_string_t *self,
- trio_string_t *other)
+TRIO_STRING_PUBLIC char *
+trio_string_substring
+TRIO_ARGS2((self, other),
+ trio_string_t *self,
+ trio_string_t *other)
{
assert(self);
assert(other);
return trio_substring(self->content, other->content);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/*
* trio_xstring_substring
*/
-TRIO_PUBLIC char *
-trio_xstring_substring(trio_string_t *self,
- const char *other)
+TRIO_STRING_PUBLIC char *
+trio_xstring_substring
+TRIO_ARGS2((self, other),
+ trio_string_t *self,
+ TRIO_CONST char *other)
{
assert(self);
assert(other);
return trio_substring(self->content, other);
}
+#endif /* !defined(TRIO_MINIMAL) */
+#if !defined(TRIO_MINIMAL)
/*
* trio_string_upper
*/
-TRIO_PUBLIC int
-trio_string_upper(trio_string_t *self)
+TRIO_STRING_PUBLIC int
+trio_string_upper
+TRIO_ARGS1((self),
+ trio_string_t *self)
{
assert(self);
return trio_upper(self->content);
}
+#endif /* !defined(TRIO_MINIMAL) */
/** @} End of DynamicStrings */
diff --git a/triostr.h b/triostr.h
index 94b01eef..083e2a52 100644
--- a/triostr.h
+++ b/triostr.h
@@ -31,42 +31,50 @@ enum {
TRIO_HASH_TWOSIGNED
};
+#if !defined(TRIO_STRING_PUBLIC)
+# if !defined(TRIO_PUBLIC)
+# define TRIO_PUBLIC
+# endif
+# define TRIO_STRING_PUBLIC TRIO_PUBLIC
+#endif
+
/*************************************************************************
* 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);
+TRIO_STRING_PUBLIC int trio_append TRIO_PROTO((char *target, const char *source));
+TRIO_STRING_PUBLIC int trio_append_max TRIO_PROTO((char *target, size_t max, const char *source));
+TRIO_STRING_PUBLIC int trio_contains TRIO_PROTO((const char *string, const char *substring));
+TRIO_STRING_PUBLIC int trio_copy TRIO_PROTO((char *target, const char *source));
+TRIO_STRING_PUBLIC int trio_copy_max TRIO_PROTO((char *target, size_t max, const char *source));
+TRIO_STRING_PUBLIC char *trio_create TRIO_PROTO((size_t size));
+TRIO_STRING_PUBLIC void trio_destroy TRIO_PROTO((char *string));
+TRIO_STRING_PUBLIC char *trio_duplicate TRIO_PROTO((const char *source));
+TRIO_STRING_PUBLIC char *trio_duplicate_max TRIO_PROTO((const char *source, size_t max));
+TRIO_STRING_PUBLIC int trio_equal TRIO_PROTO((const char *first, const char *second));
+TRIO_STRING_PUBLIC int trio_equal_case TRIO_PROTO((const char *first, const char *second));
+TRIO_STRING_PUBLIC int trio_equal_case_max TRIO_PROTO((const char *first, size_t max, const char *second));
+TRIO_STRING_PUBLIC int trio_equal_locale TRIO_PROTO((const char *first, const char *second));
+TRIO_STRING_PUBLIC int trio_equal_max TRIO_PROTO((const char *first, size_t max, const char *second));
+TRIO_STRING_PUBLIC TRIO_CONST char *trio_error TRIO_PROTO((int));
+TRIO_STRING_PUBLIC size_t trio_format_date_max TRIO_PROTO((char *target, size_t max, const char *format, const struct tm *datetime));
+TRIO_STRING_PUBLIC unsigned long trio_hash TRIO_PROTO((const char *string, int type));
+TRIO_STRING_PUBLIC char *trio_index TRIO_PROTO((const char *string, int character));
+TRIO_STRING_PUBLIC char *trio_index_last TRIO_PROTO((const char *string, int character));
+TRIO_STRING_PUBLIC size_t trio_length TRIO_PROTO((const char *string));
+TRIO_STRING_PUBLIC int trio_lower TRIO_PROTO((char *target));
+TRIO_STRING_PUBLIC int trio_match TRIO_PROTO((const char *string, const char *pattern));
+TRIO_STRING_PUBLIC int trio_match_case TRIO_PROTO((const char *string, const char *pattern));
+TRIO_STRING_PUBLIC size_t trio_span_function TRIO_PROTO((char *target, const char *source, int (*Function) TRIO_PROTO((int))));
+TRIO_STRING_PUBLIC char *trio_substring TRIO_PROTO((const char *string, const char *substring));
+TRIO_STRING_PUBLIC char *trio_substring_max TRIO_PROTO((const char *string, size_t max, const char *substring));
+TRIO_STRING_PUBLIC double trio_to_double TRIO_PROTO((const char *source, char **endp));
+TRIO_STRING_PUBLIC float trio_to_float TRIO_PROTO((const char *source, char **endp));
+TRIO_STRING_PUBLIC trio_long_double_t trio_to_long_double TRIO_PROTO((const char *source, char **endp));
+TRIO_STRING_PUBLIC long trio_to_long TRIO_PROTO((const char *source, char **endp, int base));
+TRIO_STRING_PUBLIC unsigned long trio_to_unsigned_long TRIO_PROTO((const char *source, char **endp, int base));
+TRIO_STRING_PUBLIC char *trio_tokenize TRIO_PROTO((char *string, const char *delimiters));
+TRIO_STRING_PUBLIC int trio_upper TRIO_PROTO((char *target));
/*************************************************************************
* Dynamic string functions
@@ -77,43 +85,43 @@ int trio_upper(char *target);
*/
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);
+TRIO_STRING_PUBLIC trio_string_t *trio_string_create TRIO_PROTO((int initial_size));
+TRIO_STRING_PUBLIC void trio_string_destroy TRIO_PROTO((trio_string_t *self));
+TRIO_STRING_PUBLIC char *trio_string_get TRIO_PROTO((trio_string_t *self, int offset));
+TRIO_STRING_PUBLIC void trio_xstring_set TRIO_PROTO((trio_string_t *self, char *buffer));
+TRIO_STRING_PUBLIC char *trio_string_extract TRIO_PROTO((trio_string_t *self));
+TRIO_STRING_PUBLIC int trio_string_size TRIO_PROTO((trio_string_t *self));
+TRIO_STRING_PUBLIC void trio_string_terminate TRIO_PROTO((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);
+TRIO_STRING_PUBLIC int trio_string_append TRIO_PROTO((trio_string_t *self, trio_string_t *other));
+TRIO_STRING_PUBLIC int trio_string_contains TRIO_PROTO((trio_string_t *self, trio_string_t *other));
+TRIO_STRING_PUBLIC int trio_string_copy TRIO_PROTO((trio_string_t *self, trio_string_t *other));
+TRIO_STRING_PUBLIC trio_string_t *trio_string_duplicate TRIO_PROTO((trio_string_t *other));
+TRIO_STRING_PUBLIC int trio_string_equal TRIO_PROTO((trio_string_t *self, trio_string_t *other));
+TRIO_STRING_PUBLIC int trio_string_equal_max TRIO_PROTO((trio_string_t *self, size_t max, trio_string_t *second));
+TRIO_STRING_PUBLIC int trio_string_equal_case TRIO_PROTO((trio_string_t *self, trio_string_t *other));
+TRIO_STRING_PUBLIC int trio_string_equal_case_max TRIO_PROTO((trio_string_t *self, size_t max, trio_string_t *other));
+TRIO_STRING_PUBLIC size_t trio_string_format_date_max TRIO_PROTO((trio_string_t *self, size_t max, const char *format, const struct tm *datetime));
+TRIO_STRING_PUBLIC char *trio_string_index TRIO_PROTO((trio_string_t *self, int character));
+TRIO_STRING_PUBLIC char *trio_string_index_last TRIO_PROTO((trio_string_t *self, int character));
+TRIO_STRING_PUBLIC int trio_string_length TRIO_PROTO((trio_string_t *self));
+TRIO_STRING_PUBLIC int trio_string_lower TRIO_PROTO((trio_string_t *self));
+TRIO_STRING_PUBLIC int trio_string_match TRIO_PROTO((trio_string_t *self, trio_string_t *other));
+TRIO_STRING_PUBLIC int trio_string_match_case TRIO_PROTO((trio_string_t *self, trio_string_t *other));
+TRIO_STRING_PUBLIC char *trio_string_substring TRIO_PROTO((trio_string_t *self, trio_string_t *other));
+TRIO_STRING_PUBLIC int trio_string_upper TRIO_PROTO((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);
+TRIO_STRING_PUBLIC int trio_xstring_append_char TRIO_PROTO((trio_string_t *self, char character));
+TRIO_STRING_PUBLIC int trio_xstring_append TRIO_PROTO((trio_string_t *self, const char *other));
+TRIO_STRING_PUBLIC int trio_xstring_contains TRIO_PROTO((trio_string_t *self, const char *other));
+TRIO_STRING_PUBLIC int trio_xstring_copy TRIO_PROTO((trio_string_t *self, const char *other));
+TRIO_STRING_PUBLIC trio_string_t *trio_xstring_duplicate TRIO_PROTO((const char *other));
+TRIO_STRING_PUBLIC int trio_xstring_equal TRIO_PROTO((trio_string_t *self, const char *other));
+TRIO_STRING_PUBLIC int trio_xstring_equal_max TRIO_PROTO((trio_string_t *self, size_t max, const char *other));
+TRIO_STRING_PUBLIC int trio_xstring_equal_case TRIO_PROTO((trio_string_t *self, const char *other));
+TRIO_STRING_PUBLIC int trio_xstring_equal_case_max TRIO_PROTO((trio_string_t *self, size_t max, const char *other));
+TRIO_STRING_PUBLIC int trio_xstring_match TRIO_PROTO((trio_string_t *self, const char *other));
+TRIO_STRING_PUBLIC int trio_xstring_match_case TRIO_PROTO((trio_string_t *self, const char *other));
+TRIO_STRING_PUBLIC char *trio_xstring_substring TRIO_PROTO((trio_string_t *self, const char *other));
#endif /* TRIO_TRIOSTR_H */