From 352c03fd393df99d30ab4a2817d2ceebe18a33e7 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 28 Jul 2003 23:00:51 +0000 Subject: [PATCH] Remove trio printf(). --- glib/trio/Makefile.am | 28 - glib/trio/README | 27 - glib/trio/glibtrio.h | 166 -- glib/trio/makefile.msc | 16 - glib/trio/trio.c | 6761 ------------------------------------------------ glib/trio/trio.h | 216 -- glib/trio/triodef.h | 206 -- glib/trio/trionan.c | 926 ------- glib/trio/trionan.h | 81 - glib/trio/triop.h | 150 -- glib/trio/triostr.c | 2025 --------------- glib/trio/triostr.h | 127 - 12 files changed, 10729 deletions(-) delete mode 100644 glib/trio/Makefile.am delete mode 100644 glib/trio/README delete mode 100644 glib/trio/glibtrio.h delete mode 100644 glib/trio/makefile.msc delete mode 100644 glib/trio/trio.c delete mode 100644 glib/trio/trio.h delete mode 100644 glib/trio/triodef.h delete mode 100644 glib/trio/trionan.c delete mode 100644 glib/trio/trionan.h delete mode 100644 glib/trio/triop.h delete mode 100644 glib/trio/triostr.c delete mode 100644 glib/trio/triostr.h diff --git a/glib/trio/Makefile.am b/glib/trio/Makefile.am deleted file mode 100644 index 7907c64..0000000 --- a/glib/trio/Makefile.am +++ /dev/null @@ -1,28 +0,0 @@ -## Process this file with automake to produce Makefile.in - -noinst_LTLIBRARIES = libtrio.la - -libtrio_la_LIBADD = @TRIO_LIBS@ - -libtrio_la_SOURCES = \ - trio.c \ - trionan.c \ - triostr.c \ - trio.h \ - triodef.h \ - trionan.h \ - triop.h \ - triostr.h \ - glibtrio.h - -INCLUDES = -DTRIO_EXTENSION=0 - -EXTRA_DIST = README - - - - - - - - diff --git a/glib/trio/README b/glib/trio/README deleted file mode 100644 index 19f9355..0000000 --- a/glib/trio/README +++ /dev/null @@ -1,27 +0,0 @@ -The sources are derived from the trio package, version 1.9, by -Bjorn Reese and Daniel Stenberg, which can be found at: - - http://daniel.haxx.se/trio/ - http://sourceforge.net/projects/ctrio/ - -The license on the files taken from the trio package is reproduced -below. - -Matthias Clasen -20 November 2002 - -==== - - Copyright (C) 1998-2001 by Bjorn Reese and Daniel Stenberg. - - Permission to use, copy, modify, and distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - - - diff --git a/glib/trio/glibtrio.h b/glib/trio/glibtrio.h deleted file mode 100644 index d12b8f2..0000000 --- a/glib/trio/glibtrio.h +++ /dev/null @@ -1,166 +0,0 @@ -#define TrioCalcThousandSeparatorLength _GTrioCalcThousandSeparatorLength -#define TrioDuplicateMax _GTrioDuplicateMax -#define TrioFollowedBySeparator _GTrioFollowedBySeparator -#define TrioFormat _GTrioFormat -#define TrioFormatProcess _GTrioFormatProcess -#define TrioFormatRef _GTrioFormatRef -#define TrioGetCharacterClass _GTrioGetCharacterClass -#define TrioGetPosition _GTrioGetPosition -#define TrioInStreamCustom _GTrioInStreamCustom -#define TrioInStreamFile _GTrioInStreamFile -#define TrioInStreamFileDescriptor _GTrioInStreamFileDescriptor -#define TrioInStreamString _GTrioInStreamString -#define TrioIsQualifier _GTrioIsQualifier -#define TrioLogarithm _GTrioLogarithm -#define TrioLogarithmBase _GTrioLogarithmBase -#define TrioOutStreamCustom _GTrioOutStreamCustom -#define TrioOutStreamFile _GTrioOutStreamFile -#define TrioOutStreamFileDescriptor _GTrioOutStreamFileDescriptor -#define TrioOutStreamString _GTrioOutStreamString -#define TrioOutStreamStringDynamic _GTrioOutStreamStringDynamic -#define TrioOutStreamStringMax _GTrioOutStreamStringMax -#define TrioParse _GTrioParse -#define TrioPower _GTrioPower -#define TrioReadChar _GTrioReadChar -#define TrioReadDouble _GTrioReadDouble -#define TrioReadGroup _GTrioReadGroup -#define TrioReadNumber _GTrioReadNumber -#define TrioReadPointer _GTrioReadPointer -#define TrioReadString _GTrioReadString -#define TrioScan _GTrioScan -#define TrioScanProcess _GTrioScanProcess -#define TrioSetLocale _GTrioSetLocale -#define TrioSkipWhitespaces _GTrioSkipWhitespaces -#define TrioStringAlloc _GTrioStringAlloc -#define TrioStringGrow _GTrioStringGrow -#define TrioStringGrowTo _GTrioStringGrowTo -#define TrioWriteDouble _GTrioWriteDouble -#define TrioWriteNumber _GTrioWriteNumber -#define TrioWriteString _GTrioWriteString -#define TrioWriteStringCharacter _GTrioWriteStringCharacter -#define trio_append _g_trio_append -#define trio_append_max _g_trio_append_max -#define trio_aprintf _g_trio_aprintf -#define trio_asprintf _g_trio_asprintf -#define trio_contains _g_trio_contains -#define trio_copy _g_trio_copy -#define trio_copy_max _g_trio_copy_max -#define trio_cprintf _g_trio_cprintf -#define trio_cprintfv _g_trio_cprintfv -#define trio_create _g_trio_create -#define trio_cscanf _g_trio_cscanf -#define trio_cscanfv _g_trio_cscanfv -#define trio_destroy _g_trio_destroy -#define trio_dprintf _g_trio_dprintf -#define trio_dprintfv _g_trio_dprintfv -#define trio_dscanf _g_trio_dscanf -#define trio_dscanfv _g_trio_dscanfv -#define trio_duplicate _g_trio_duplicate -#define trio_duplicate_max _g_trio_duplicate_max -#define trio_equal _g_trio_equal -#define trio_equal_case _g_trio_equal_case -#define trio_equal_case_max _g_trio_equal_case_max -#define trio_equal_locale _g_trio_equal_locale -#define trio_equal_max _g_trio_equal_max -#define trio_error _g_trio_error -#define trio_format_date_max _g_trio_format_date_max -#define trio_fpclassify _g_trio_fpclassify -#define trio_fpclassify_and_signbit _g_trio_fpclassify_and_signbit -#define trio_fprintf _g_trio_fprintf -#define trio_fprintfv _g_trio_fprintfv -#define trio_fscanf _g_trio_fscanf -#define trio_fscanfv _g_trio_fscanfv -#define trio_hash _g_trio_hash -#define trio_index _g_trio_index -#define trio_index_last _g_trio_index_last -#define trio_is_negative _g_trio_is_negative -#define trio_is_special_quantity _g_trio_is_special_quantity -#define trio_isfinite _g_trio_isfinite -#define trio_isinf _g_trio_isinf -#define trio_isnan _g_trio_isnan -#define trio_length _g_trio_length -#define trio_locale_set_decimal_point _g_trio_locale_set_decimal_point -#define trio_locale_set_grouping _g_trio_locale_set_grouping -#define trio_locale_set_thousand_separator _g_trio_locale_set_thousand_separator -#define trio_lower _g_trio_lower -#define trio_make_double _g_trio_make_double -#define trio_match _g_trio_match -#define trio_match_case _g_trio_match_case -#define trio_nan _g_trio_nan -#define trio_ninf _g_trio_ninf -#define trio_nzero _g_trio_nzero -#define trio_pinf _g_trio_pinf -#define trio_print_pointer _g_trio_print_pointer -#define trio_printf _g_trio_printf -#define trio_printfv _g_trio_printfv -#define trio_scanf _g_trio_scanf -#define trio_scanfv _g_trio_scanfv -#define trio_signbit _g_trio_signbit -#define trio_snprintf _g_trio_snprintf -#define trio_snprintfcat _g_trio_snprintfcat -#define trio_snprintfv _g_trio_snprintfv -#define trio_span_function _g_trio_span_function -#define trio_sprintf _g_trio_sprintf -#define trio_sprintfv _g_trio_sprintfv -#define trio_sscanf _g_trio_sscanf -#define trio_sscanfv _g_trio_sscanfv -#define trio_strerror _g_trio_strerror -#define trio_string_append _g_trio_string_append -#define trio_string_contains _g_trio_string_contains -#define trio_string_copy _g_trio_string_copy -#define trio_string_create _g_trio_string_create -#define trio_string_destroy _g_trio_string_destroy -#define trio_string_duplicate _g_trio_string_duplicate -#define trio_string_equal _g_trio_string_equal -#define trio_string_equal_case _g_trio_string_equal_case -#define trio_string_equal_case_max _g_trio_string_equal_case_max -#define trio_string_equal_max _g_trio_string_equal_max -#define trio_string_extract _g_trio_string_extract -#define trio_string_format_date_max _g_trio_string_format_date_max -#define trio_string_get _g_trio_string_get -#define trio_string_index _g_trio_string_index -#define trio_string_index_last _g_trio_string_index_last -#define trio_string_length _g_trio_string_length -#define trio_string_lower _g_trio_string_lower -#define trio_string_match _g_trio_string_match -#define trio_string_match_case _g_trio_string_match_case -#define trio_string_size _g_trio_string_size -#define trio_string_substring _g_trio_string_substring -#define trio_string_terminate _g_trio_string_terminate -#define trio_string_upper _g_trio_string_upper -#define trio_substring _g_trio_substring -#define trio_substring_max _g_trio_substring_max -#define trio_to_double _g_trio_to_double -#define trio_to_float _g_trio_to_float -#define trio_to_long _g_trio_to_long -#define trio_to_long_double _g_trio_to_long_double -#define trio_to_unsigned_long _g_trio_to_unsigned_long -#define trio_tokenize _g_trio_tokenize -#define trio_upper _g_trio_upper -#define trio_vaprintf _g_trio_vaprintf -#define trio_vasprintf _g_trio_vasprintf -#define trio_vcprintf _g_trio_vcprintf -#define trio_vcscanf _g_trio_vcscanf -#define trio_vdprintf _g_trio_vdprintf -#define trio_vdscanf _g_trio_vdscanf -#define trio_vfprintf _g_trio_vfprintf -#define trio_vfscanf _g_trio_vfscanf -#define trio_vprintf _g_trio_vprintf -#define trio_vscanf _g_trio_vscanf -#define trio_vsnprintf _g_trio_vsnprintf -#define trio_vsnprintfcat _g_trio_vsnprintfcat -#define trio_vsprintf _g_trio_vsprintf -#define trio_vsscanf _g_trio_vsscanf -#define trio_xstring_append _g_trio_xstring_append -#define trio_xstring_append_char _g_trio_xstring_append_char -#define trio_xstring_contains _g_trio_xstring_contains -#define trio_xstring_copy _g_trio_xstring_copy -#define trio_xstring_duplicate _g_trio_xstring_duplicate -#define trio_xstring_equal _g_trio_xstring_equal -#define trio_xstring_equal_case _g_trio_xstring_equal_case -#define trio_xstring_equal_case_max _g_trio_xstring_equal_case_max -#define trio_xstring_equal_max _g_trio_xstring_equal_max -#define trio_xstring_match _g_trio_xstring_match -#define trio_xstring_match_case _g_trio_xstring_match_case -#define trio_xstring_set _g_trio_xstring_set -#define trio_xstring_substring _g_trio_xstring_substring diff --git a/glib/trio/makefile.msc b/glib/trio/makefile.msc deleted file mode 100644 index 9fdf120..0000000 --- a/glib/trio/makefile.msc +++ /dev/null @@ -1,16 +0,0 @@ -!IFDEF DEBUG -CRT=-MDd -!ELSE -CRT=-MD -!ENDIF - -OBJECTS = \ - trio.obj \ - trionan.obj \ - triostr.obj - -trio.lib : $(OBJECTS) - lib -out:trio.lib $(OBJECTS) - -.c.obj: - $(CC) $(CRT) -Ox -GD -c $< diff --git a/glib/trio/trio.c b/glib/trio/trio.c deleted file mode 100644 index 27e70be..0000000 --- a/glib/trio/trio.c +++ /dev/null @@ -1,6761 +0,0 @@ -/************************************************************************* - * - * $Id$ - * - * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************* - * - * A note to trio contributors: - * - * Avoid heap allocation at all costs to ensure that the trio functions - * are async-safe. The exceptions are the printf/fprintf functions, which - * uses fputc, and the asprintf functions and the modifier, which - * by design are required to allocate form the heap. - * - ************************************************************************/ - -/* - * TODO: - * - Scan is probably too permissive about its modifiers. - * - C escapes in %#[] ? - * - Multibyte characters (done for format parsing, except scan groups) - * - Complex numbers? (C99 _Complex) - * - Boolean values? (C99 _Bool) - * - C99 NaN(n-char-sequence) missing - * - Should we support the GNU %a alloc modifier? GNU has an ugly hack - * for %a, because C99 used %a for other purposes. If specified as - * %as or %a[ it is interpreted as the alloc modifier, otherwise as - * the C99 hex-float. This means that you cannot scan %as as a hex-float - * immediately followed by an 's'. - * - Scanning of collating symbols. - */ - -/************************************************************************* - * Trio include files - */ -#include "glibtrio.h" -#include "triodef.h" -#include "trio.h" -#include "triop.h" -#include "trionan.h" -#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) -# define MB_LEN_MAX 6 -# endif -#endif - -/************************************************************************* - * Generic definitions - */ - -#if !(defined(DEBUG) || defined(NDEBUG)) -# define NDEBUG -#endif -#include -#include -#if !defined(TRIO_COMPILER_SUPPORTS_C99) -# define isblank(x) (((x)==32) || ((x)==9)) -#endif -#include -#include -#include -#if defined(TRIO_COMPILER_ANCIENT) -# include -#else -# include -#endif -#include -#include - -#ifndef NULL -# define NULL 0 -#endif -#define NIL ((char)0) -#ifndef FALSE -# define FALSE (1 == 0) -# define TRUE (! FALSE) -#endif -#define BOOLEAN_T int - -/* mincore() can be used for debugging purposes */ -#define VALID(x) (NULL != (x)) - -#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 - - -/************************************************************************* - * Platform specific definitions - */ -#if defined(TRIO_PLATFORM_UNIX) -# include -# include -# include -# define USE_LOCALE -#endif /* TRIO_PLATFORM_UNIX */ -#if defined(TRIO_PLATFORM_VMS) -# include -#endif -#if defined(TRIO_PLATFORM_WIN32) -# include -# define read _read -# define write _write -#endif /* TRIO_PLATFORM_WIN32 */ - -#define TRIO_MSVC_VERSION_5 1100 - -#if TRIO_WIDECHAR -# if defined(TRIO_COMPILER_SUPPORTS_ISO94) -# include -# include -typedef wchar_t trio_wchar_t; -typedef wint_t trio_wint_t; -# else -typedef char trio_wchar_t; -typedef int trio_wint_t; -# define WCONST(x) L ## x -# define WEOF EOF -# define iswalnum(x) isalnum(x) -# define iswalpha(x) isalpha(x) -# define iswblank(x) isblank(x) -# define iswcntrl(x) iscntrl(x) -# define iswdigit(x) isdigit(x) -# define iswgraph(x) isgraph(x) -# define iswlower(x) islower(x) -# define iswprint(x) isprint(x) -# define iswpunct(x) ispunct(x) -# define iswspace(x) isspace(x) -# define iswupper(x) isupper(x) -# define iswxdigit(x) isxdigit(x) -# endif -#endif - - -/************************************************************************* - * Compiler dependent definitions - */ - -/* Support for long long */ -#ifndef __cplusplus -# if !defined(USE_LONGLONG) -# if defined(TRIO_COMPILER_GCC) && !defined(__STRICT_ANSI__) -# define USE_LONGLONG -# elif defined(TRIO_COMPILER_SUNPRO) -# define USE_LONGLONG -# elif defined(_LONG_LONG) || defined(_LONGLONG) -# define USE_LONGLONG -# endif -# endif -#endif - -/* The extra long numbers */ -#if defined(USE_LONGLONG) -typedef signed long long int trio_longlong_t; -typedef unsigned long long int trio_ulonglong_t; -#elif defined(TRIO_COMPILER_MSVC) -# if (_MSC_VER >= TRIO_MSVC_VERSION_5) -typedef signed __int64 trio_longlong_t; -typedef unsigned __int64 trio_ulonglong_t; -# else -typedef signed long int trio_longlong_t; -typedef unsigned long int trio_ulonglong_t; -# endif -#else -typedef TRIO_SIGNED long int trio_longlong_t; -typedef unsigned long int trio_ulonglong_t; -#endif - -/* Maximal and fixed integer types */ -#if defined(TRIO_COMPILER_SUPPORTS_C99) -# include -typedef intmax_t trio_intmax_t; -typedef uintmax_t trio_uintmax_t; -typedef int8_t trio_int8_t; -typedef int16_t trio_int16_t; -typedef int32_t trio_int32_t; -typedef int64_t trio_int64_t; -#elif defined(TRIO_COMPILER_SUPPORTS_UNIX98) -# include -typedef intmax_t trio_intmax_t; -typedef uintmax_t trio_uintmax_t; -typedef int8_t trio_int8_t; -typedef int16_t trio_int16_t; -typedef int32_t trio_int32_t; -typedef int64_t trio_int64_t; -#elif defined(TRIO_COMPILER_MSVC) && (_MSC_VER >= TRIO_MSVC_VERSION_5) -typedef trio_longlong_t trio_intmax_t; -typedef trio_ulonglong_t trio_uintmax_t; -typedef __int8 trio_int8_t; -typedef __int16 trio_int16_t; -typedef __int32 trio_int32_t; -typedef __int64 trio_int64_t; -#else -typedef trio_longlong_t trio_intmax_t; -typedef trio_ulonglong_t trio_uintmax_t; -# if defined(TRIO_INT8_T) -typedef TRIO_INT8_T trio_int8_t; -# else -typedef TRIO_SIGNED char trio_int8_t; -# endif -# if defined(TRIO_INT16_T) -typedef TRIO_INT16_T trio_int16_t; -# else -typedef TRIO_SIGNED short trio_int16_t; -# endif -# if defined(TRIO_INT32_T) -typedef TRIO_INT32_T trio_int32_t; -# else -typedef TRIO_SIGNED int trio_int32_t; -# endif -# if defined(TRIO_INT64_T) -typedef TRIO_INT64_T trio_int64_t; -# else -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 - */ - -#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 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(trio_pointer_t) * CHAR_BIT / 4) - -/* Infinite and Not-A-Number for floating-point */ -#define INFINITE_LOWER "inf" -#define INFINITE_UPPER "INF" -#define LONG_INFINITE_LOWER "infinite" -#define LONG_INFINITE_UPPER "INFINITE" -#define NAN_LOWER "nan" -#define NAN_UPPER "NAN" - -/* Various constants */ -enum { - TYPE_PRINT = 1, - TYPE_SCAN = 2, - - /* Flags. Use maximum 32 */ - FLAGS_NEW = 0, - FLAGS_STICKY = 1, - FLAGS_SPACE = 2 * FLAGS_STICKY, - FLAGS_SHOWSIGN = 2 * FLAGS_SPACE, - FLAGS_LEFTADJUST = 2 * FLAGS_SHOWSIGN, - FLAGS_ALTERNATIVE = 2 * FLAGS_LEFTADJUST, - FLAGS_SHORT = 2 * FLAGS_ALTERNATIVE, - FLAGS_SHORTSHORT = 2 * FLAGS_SHORT, - FLAGS_LONG = 2 * FLAGS_SHORTSHORT, - FLAGS_QUAD = 2 * FLAGS_LONG, - FLAGS_LONGDOUBLE = 2 * FLAGS_QUAD, - FLAGS_SIZE_T = 2 * FLAGS_LONGDOUBLE, - FLAGS_PTRDIFF_T = 2 * FLAGS_SIZE_T, - FLAGS_INTMAX_T = 2 * FLAGS_PTRDIFF_T, - FLAGS_NILPADDING = 2 * FLAGS_INTMAX_T, - FLAGS_UNSIGNED = 2 * FLAGS_NILPADDING, - FLAGS_UPPER = 2 * FLAGS_UNSIGNED, - FLAGS_WIDTH = 2 * FLAGS_UPPER, - FLAGS_WIDTH_PARAMETER = 2 * FLAGS_WIDTH, - FLAGS_PRECISION = 2 * FLAGS_WIDTH_PARAMETER, - FLAGS_PRECISION_PARAMETER = 2 * FLAGS_PRECISION, - FLAGS_BASE = 2 * FLAGS_PRECISION_PARAMETER, - FLAGS_BASE_PARAMETER = 2 * FLAGS_BASE, - FLAGS_FLOAT_E = 2 * FLAGS_BASE_PARAMETER, - FLAGS_FLOAT_G = 2 * FLAGS_FLOAT_E, - FLAGS_QUOTE = 2 * FLAGS_FLOAT_G, - FLAGS_WIDECHAR = 2 * FLAGS_QUOTE, - FLAGS_ALLOC = 2 * FLAGS_WIDECHAR, - FLAGS_IGNORE = 2 * FLAGS_ALLOC, - FLAGS_IGNORE_PARAMETER = 2 * FLAGS_IGNORE, - FLAGS_VARSIZE_PARAMETER = 2 * FLAGS_IGNORE_PARAMETER, - FLAGS_FIXED_SIZE = 2 * FLAGS_VARSIZE_PARAMETER, - /* 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, - - NO_POSITION = -1, - NO_WIDTH = 0, - NO_PRECISION = -1, - NO_SIZE = -1, - - /* Do not change these */ - NO_BASE = -1, - MIN_BASE = 2, - MAX_BASE = 36, - BASE_BINARY = 2, - BASE_OCTAL = 8, - BASE_DECIMAL = 10, - BASE_HEX = 16, - - /* Maximal number of allowed parameters */ - MAX_PARAMETERS = 64, - /* Maximal number of characters in class */ - MAX_CHARACTER_CLASS = UCHAR_MAX + 1, - - /* Maximal string lengths for user-defined specifiers */ - MAX_USER_NAME = 64, - MAX_USER_DATA = 256, - - /* Maximal length of locale separator strings */ - MAX_LOCALE_SEPARATOR_LENGTH = MB_LEN_MAX, - /* Maximal number of integers in grouping */ - MAX_LOCALE_GROUPS = 64, - - /* Initial size of asprintf buffer */ - DYNAMIC_START_SIZE = 32 -}; - -#define NO_GROUPING ((int)CHAR_MAX) - -/* Fundamental formatting parameter types */ -#define FORMAT_UNKNOWN 0 -#define FORMAT_INT 1 -#define FORMAT_DOUBLE 2 -#define FORMAT_CHAR 3 -#define FORMAT_STRING 4 -#define FORMAT_POINTER 5 -#define FORMAT_COUNT 6 -#define FORMAT_PARAMETER 7 -#define FORMAT_GROUP 8 -#if TRIO_GNU -# define FORMAT_ERRNO 9 -#endif -#if TRIO_EXTENSION -# define FORMAT_USER_DEFINED 10 -#endif - -/* Character constants */ -#define CHAR_IDENTIFIER '%' -#define CHAR_BACKSLASH '\\' -#define CHAR_QUOTE '\"' -#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:]" - -/* - * SPECIFIERS: - * - * - * a Hex-float - * A Hex-float - * c Character - * C Widechar character (wint_t) - * d Decimal - * e Float - * E Float - * F Float - * F Float - * g Float - * G Float - * i Integer - * m Error message - * n Count - * o Octal - * p Pointer - * s String - * S Widechar string (wchar_t *) - * u Unsigned - * x Hex - * X Hex - * [] Group - * <> User-defined - * - * Reserved: - * - * D Binary Coded Decimal %D(length,precision) (OS/390) - */ -#define SPECIFIER_CHAR 'c' -#define SPECIFIER_STRING 's' -#define SPECIFIER_DECIMAL 'd' -#define SPECIFIER_INTEGER 'i' -#define SPECIFIER_UNSIGNED 'u' -#define SPECIFIER_OCTAL 'o' -#define SPECIFIER_HEX 'x' -#define SPECIFIER_HEX_UPPER 'X' -#define SPECIFIER_FLOAT_E 'e' -#define SPECIFIER_FLOAT_E_UPPER 'E' -#define SPECIFIER_FLOAT_F 'f' -#define SPECIFIER_FLOAT_F_UPPER 'F' -#define SPECIFIER_FLOAT_G 'g' -#define SPECIFIER_FLOAT_G_UPPER 'G' -#define SPECIFIER_POINTER 'p' -#define SPECIFIER_GROUP '[' -#define SPECIFIER_UNGROUP ']' -#define SPECIFIER_COUNT 'n' -#if TRIO_UNIX98 -# define SPECIFIER_CHAR_UPPER 'C' -# define SPECIFIER_STRING_UPPER 'S' -#endif -#if TRIO_C99 -# define SPECIFIER_HEXFLOAT 'a' -# define SPECIFIER_HEXFLOAT_UPPER 'A' -#endif -#if TRIO_GNU -# define SPECIFIER_ERRNO 'm' -#endif -#if TRIO_EXTENSION -# define SPECIFIER_BINARY 'b' -# define SPECIFIER_BINARY_UPPER 'B' -# define SPECIFIER_USER_DEFINED_BEGIN '<' -# define SPECIFIER_USER_DEFINED_END '>' -# define SPECIFIER_USER_DEFINED_SEPARATOR ':' -#endif - -/* - * QUALIFIERS: - * - * - * Numbers = d,i,o,u,x,X - * Float = a,A,e,E,f,F,g,G - * String = s - * Char = c - * - * - * 9$ Position - * Use the 9th parameter. 9 can be any number between 1 and - * the maximal argument - * - * 9 Width - * Set width to 9. 9 can be any number, but must not be postfixed - * by '$' - * - * h Short - * Numbers: - * (unsigned) short int - * - * hh Short short - * Numbers: - * (unsigned) char - * - * l Long - * Numbers: - * (unsigned) long int - * String: - * as the S specifier - * Char: - * as the C specifier - * - * ll Long Long - * Numbers: - * (unsigned) long long int - * - * L Long Double - * Float - * long double - * - * # Alternative - * Float: - * Decimal-point is always present - * String: - * non-printable characters are handled as \number - * - * Spacing - * - * + Sign - * - * - Alignment - * - * . Precision - * - * * Parameter - * print: use parameter - * scan: no parameter (ignore) - * - * q Quad - * - * Z size_t - * - * w Widechar - * - * ' Thousands/quote - * Numbers: - * Integer part grouped in thousands - * Binary numbers: - * Number grouped in nibbles (4 bits) - * String: - * Quoted string - * - * j intmax_t - * t prtdiff_t - * z size_t - * - * ! Sticky - * @ Parameter (for both print and scan) - * - * I n-bit Integer - * Numbers: - * The following options exists - * I8 = 8-bit integer - * I16 = 16-bit integer - * I32 = 32-bit integer - * I64 = 64-bit integer - */ -#define QUALIFIER_POSITION '$' -#define QUALIFIER_SHORT 'h' -#define QUALIFIER_LONG 'l' -#define QUALIFIER_LONG_UPPER 'L' -#define QUALIFIER_ALTERNATIVE '#' -#define QUALIFIER_SPACE ' ' -#define QUALIFIER_PLUS '+' -#define QUALIFIER_MINUS '-' -#define QUALIFIER_DOT '.' -#define QUALIFIER_STAR '*' -#define QUALIFIER_CIRCUMFLEX '^' /* For scanlists */ -#if TRIO_C99 -# define QUALIFIER_SIZE_T 'z' -# define QUALIFIER_PTRDIFF_T 't' -# define QUALIFIER_INTMAX_T 'j' -#endif -#if TRIO_BSD || TRIO_GNU -# define QUALIFIER_QUAD 'q' -#endif -#if TRIO_GNU -# define QUALIFIER_SIZE_T_UPPER 'Z' -#endif -#if TRIO_MISC -# define QUALIFIER_WIDECHAR 'w' -#endif -#if TRIO_MICROSOFT -# define QUALIFIER_FIXED_SIZE 'I' -#endif -#if TRIO_EXTENSION -# define QUALIFIER_QUOTE '\'' -# define QUALIFIER_STICKY '!' -# define QUALIFIER_VARSIZE '&' /* This should remain undocumented */ -# define QUALIFIER_PARAM '@' /* Experimental */ -# define QUALIFIER_COLON ':' /* For scanlists */ -# define QUALIFIER_EQUAL '=' /* For scanlists */ -# define QUALIFIER_ROUNDING_UPPER 'R' -#endif - - -/************************************************************************* - * - * Internal Structures - * - *************************************************************************/ - -/* Parameters */ -typedef struct { - /* An indication of which entry in the data union is used */ - int type; - /* The flags */ - unsigned long flags; - /* The width qualifier */ - int width; - /* The precision qualifier */ - int precision; - /* The base qualifier */ - int base; - /* The size for the variable size qualifier */ - int varsize; - /* The marker of the end of the specifier */ - int indexAfterSpecifier; - /* The data from the argument list */ - union { - char *string; -#if TRIO_WIDECHAR - trio_wchar_t *wstring; -#endif - trio_pointer_t pointer; - union { - trio_intmax_t as_signed; - trio_uintmax_t as_unsigned; - } number; - double doubleNumber; - double *doublePointer; - trio_long_double_t longdoubleNumber; - trio_long_double_t *longdoublePointer; - int errorNumber; - } data; - /* For the user-defined specifier */ - char user_name[MAX_USER_NAME]; - 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) TRIO_PROTO((struct _trio_class_t *, int)); - /* - * The function to read characters from a stream. - */ - void (*InStream) TRIO_PROTO((struct _trio_class_t *, int *)); - /* - * The current location in the stream. - */ - trio_pointer_t location; - /* - * The character currently being processed. - */ - int current; - /* - * The number of characters that would have been written/read - * if there had been sufficient space. - */ - int processed; - /* - * The number of characters that are actually written/read. - * Processed and committed will only differ for the *nprintf - * and *nscanf functions. - */ - int committed; - /* - * The upper limit of characters that may be written/read. - */ - int max; - /* - * The last output error that was detected. - */ - int error; -} trio_class_t; - -/* References (for user-defined callbacks) */ -typedef struct _trio_reference_t { - trio_class_t *data; - trio_parameter_t *parameter; -} trio_reference_t; - -/* Registered entries (for user-defined callbacks) */ -typedef struct _trio_userdef_t { - struct _trio_userdef_t *next; - trio_callback_t callback; - char *name; -} trio_userdef_t; - - -/************************************************************************* - * - * Internal Variables - * - *************************************************************************/ - -static TRIO_CONST char rcsid[] = "@(#)$Id$"; - -/* - * Need this to workaround a parser bug in HP C/iX compiler that fails - * to resolves macro definitions that includes type 'long double', - * e.g: va_arg(arg_ptr, long double) - */ -#if defined(TRIO_PLATFORM_MPEIX) -static TRIO_CONST trio_long_double_t ___dummy_long_double = 0; -#endif - -static TRIO_CONST char internalNullString[] = "(nil)"; - -#if defined(USE_LOCALE) -static struct lconv *internalLocaleValues = NULL; -#endif - -/* - * UNIX98 says "in a locale where the radix character is not defined, - * the radix character defaults to a period (.)" - */ -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 }; - -static TRIO_CONST char internalDigitsLower[] = "0123456789abcdefghijklmnopqrstuvwxyz"; -static TRIO_CONST char internalDigitsUpper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; -static BOOLEAN_T internalDigitsUnconverted = TRUE; -static int internalDigitArray[128]; -#if TRIO_EXTENSION -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 - - -/************************************************************************* - * - * Internal Functions - * - ************************************************************************/ - -#if defined(TRIO_MINIMAL) -# define TRIO_STRING_PUBLIC static -# include "triostr.c" -#endif /* defined(TRIO_MINIMAL) */ - -/************************************************************************* - * TrioIsQualifier - * - * Description: - * Remember to add all new qualifiers to this function. - * QUALIFIER_POSITION must not be added. - */ -TRIO_PRIVATE BOOLEAN_T -TrioIsQualifier -TRIO_ARGS1((character), - TRIO_CONST char character) -{ - /* QUALIFIER_POSITION is not included */ - switch (character) - { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case QUALIFIER_PLUS: - case QUALIFIER_MINUS: - case QUALIFIER_SPACE: - case QUALIFIER_DOT: - case QUALIFIER_STAR: - case QUALIFIER_ALTERNATIVE: - case QUALIFIER_SHORT: - case QUALIFIER_LONG: - case QUALIFIER_LONG_UPPER: - case QUALIFIER_CIRCUMFLEX: -#if defined(QUALIFIER_SIZE_T) - case QUALIFIER_SIZE_T: -#endif -#if defined(QUALIFIER_PTRDIFF_T) - case QUALIFIER_PTRDIFF_T: -#endif -#if defined(QUALIFIER_INTMAX_T) - case QUALIFIER_INTMAX_T: -#endif -#if defined(QUALIFIER_QUAD) - case QUALIFIER_QUAD: -#endif -#if defined(QUALIFIER_SIZE_T_UPPER) - case QUALIFIER_SIZE_T_UPPER: -#endif -#if defined(QUALIFIER_WIDECHAR) - case QUALIFIER_WIDECHAR: -#endif -#if defined(QUALIFIER_QUOTE) - case QUALIFIER_QUOTE: -#endif -#if defined(QUALIFIER_STICKY) - case QUALIFIER_STICKY: -#endif -#if defined(QUALIFIER_VARSIZE) - case QUALIFIER_VARSIZE: -#endif -#if defined(QUALIFIER_PARAM) - case QUALIFIER_PARAM: -#endif -#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; - } -} - -/************************************************************************* - * TrioSetLocale - */ -#if defined(USE_LOCALE) -TRIO_PRIVATE void -TrioSetLocale(TRIO_NOARGS) -{ - internalLocaleValues = (struct lconv *)localeconv(); - if (internalLocaleValues) - { - if ((internalLocaleValues->decimal_point) && - (internalLocaleValues->decimal_point[0] != NIL)) - { - 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)) - { - trio_copy_max(internalThousandSeparator, - sizeof(internalThousandSeparator), - internalLocaleValues->thousands_sep); - internalThousandSeparatorLength = trio_length(internalThousandSeparator); - } - if ((internalLocaleValues->grouping) && - (internalLocaleValues->grouping[0] != NIL)) - { - trio_copy_max(internalGrouping, - sizeof(internalGrouping), - internalLocaleValues->grouping); - } - } -} -#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_ARGS2((format, indexPointer), - TRIO_CONST char *format, - int *indexPointer) -{ -#if TRIO_UNIX98 - char *tmpformat; - int number = 0; - int index = *indexPointer; - - number = (int)trio_to_long(&format[index], &tmpformat, BASE_DECIMAL); - index = (int)(tmpformat - format); - if ((number != 0) && (QUALIFIER_POSITION == format[index++])) - { - *indexPointer = index; - /* - * number is decreased by 1, because n$ starts from 1, whereas - * the array it is indexing starts from 0. - */ - return number - 1; - } -#endif - return NO_POSITION; -} - -#if TRIO_EXTENSION -/************************************************************************* - * TrioFindNamespace - * - * Find registered user-defined specifier. - * The prev argument is used for optimization only. - */ -TRIO_PRIVATE trio_userdef_t * -TrioFindNamespace -TRIO_ARGS2((name, prev), - TRIO_CONST char *name, - trio_userdef_t **prev) -{ - trio_userdef_t *def; - - if (internalEnterCriticalRegion) - (void)internalEnterCriticalRegion(NULL); - - for (def = internalUserDef; def; def = def->next) - { - /* Case-sensitive string comparison */ - if (trio_equal_case(def->name, name)) - break; - - if (prev) - *prev = def; - } - - if (internalLeaveCriticalRegion) - (void)internalLeaveCriticalRegion(NULL); - - 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 - * - * Description: - * Parse the format string - */ -TRIO_PRIVATE int -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) -{ - /* Count the number of times a parameter is referenced */ - unsigned short usedEntries[MAX_PARAMETERS]; - /* Parameter counters */ - int parameterPosition; - int currentParam; - int maxParam = -1; - /* Utility variables */ - unsigned long flags; - int width; - int precision; - int varsize; - int base; - 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 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) - */ - int indices[MAX_PARAMETERS]; - int pos = 0; - /* Various variables */ - char ch; -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - int charlen; -#endif - int save_errno; - int i = -1; - int num; - char *tmpformat; - - /* 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)); - - save_errno = errno; - index = 0; - parameterPosition = 0; -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - (void)mblen(NULL, 0); -#endif - - while (format[index]) - { -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - if (! isascii(format[index])) - { - /* - * Multibyte characters cannot be legal specifiers or - * modifiers, so we skip over them. - */ - charlen = mblen(&format[index], MB_LEN_MAX); - index += (charlen > 0) ? charlen : 1; - continue; /* while */ - } -#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */ - if (CHAR_IDENTIFIER == format[index++]) - { - if (CHAR_IDENTIFIER == format[index]) - { - index++; - continue; /* while */ - } - - flags = FLAGS_NEW; - dots = 0; - currentParam = TrioGetPosition(format, &index); - positional = (NO_POSITION != currentParam); - if (!positional) - { - /* We have no positional, get the next counter */ - currentParam = parameterPosition; - } - if(currentParam >= MAX_PARAMETERS) - { - /* Bail out completely to make the error more obvious */ - return TRIO_ERROR_RETURN(TRIO_ETOOMANY, index); - } - - if (currentParam > maxParam) - maxParam = currentParam; - - /* Default values */ - width = NO_WIDTH; - precision = NO_PRECISION; - base = NO_BASE; - varsize = NO_SIZE; - - while (TrioIsQualifier(format[index])) - { - ch = format[index++]; - - switch (ch) - { - case QUALIFIER_SPACE: - flags |= FLAGS_SPACE; - break; - - case QUALIFIER_PLUS: - flags |= FLAGS_SHOWSIGN; - break; - - case QUALIFIER_MINUS: - flags |= FLAGS_LEFTADJUST; - flags &= ~FLAGS_NILPADDING; - break; - - case QUALIFIER_ALTERNATIVE: - flags |= FLAGS_ALTERNATIVE; - break; - - case QUALIFIER_DOT: - if (dots == 0) /* Precision */ - { - dots++; - - /* Skip if no precision */ - if (QUALIFIER_DOT == format[index]) - break; - - /* After the first dot we have the precision */ - flags |= FLAGS_PRECISION; - if ((QUALIFIER_STAR == format[index]) -#if defined(QUALIFIER_PARAM) - || (QUALIFIER_PARAM == format[index]) -#endif - ) - { - index++; - flags |= FLAGS_PRECISION_PARAMETER; - - precision = TrioGetPosition(format, &index); - if (precision == NO_POSITION) - { - parameterPosition++; - if (positional) - precision = parameterPosition; - else - { - precision = currentParam; - currentParam = precision + 1; - } - } - else - { - if (! positional) - currentParam = precision + 1; - if (width > maxParam) - maxParam = precision; - } - if (currentParam > maxParam) - maxParam = currentParam; - } - else - { - precision = trio_to_long(&format[index], - &tmpformat, - BASE_DECIMAL); - index = (int)(tmpformat - format); - } - } - else if (dots == 1) /* Base */ - { - dots++; - - /* After the second dot we have the base */ - flags |= FLAGS_BASE; - if ((QUALIFIER_STAR == format[index]) -#if defined(QUALIFIER_PARAM) - || (QUALIFIER_PARAM == format[index]) -#endif - ) - { - index++; - flags |= FLAGS_BASE_PARAMETER; - base = TrioGetPosition(format, &index); - if (base == NO_POSITION) - { - parameterPosition++; - if (positional) - base = parameterPosition; - else - { - base = currentParam; - currentParam = base + 1; - } - } - else - { - if (! positional) - currentParam = base + 1; - if (base > maxParam) - maxParam = base; - } - if (currentParam > maxParam) - maxParam = currentParam; - } - else - { - base = trio_to_long(&format[index], - &tmpformat, - BASE_DECIMAL); - if (base > MAX_BASE) - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - index = (int)(tmpformat - format); - } - } - else - { - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - } - 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) - { - /* Read with from parameter */ - flags |= (FLAGS_WIDTH | FLAGS_WIDTH_PARAMETER); - width = TrioGetPosition(format, &index); - if (width == NO_POSITION) - { - parameterPosition++; - if (positional) - width = parameterPosition; - else - { - width = currentParam; - currentParam = width + 1; - } - } - else - { - if (! positional) - currentParam = width + 1; - if (width > maxParam) - maxParam = width; - } - if (currentParam > maxParam) - maxParam = currentParam; - } - else - { - /* Scan, but do not store result */ - flags |= FLAGS_IGNORE; - } - - break; /* QUALIFIER_STAR */ - - case '0': - if (! (flags & FLAGS_LEFTADJUST)) - flags |= FLAGS_NILPADDING; - /* FALLTHROUGH */ - case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - flags |= FLAGS_WIDTH; - /* &format[index - 1] is used to "rewind" the read - * character from format - */ - width = trio_to_long(&format[index - 1], - &tmpformat, - BASE_DECIMAL); - index = (int)(tmpformat - format); - break; - - case QUALIFIER_SHORT: - if (flags & FLAGS_SHORTSHORT) - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - else if (flags & FLAGS_SHORT) - flags |= FLAGS_SHORTSHORT; - else - flags |= FLAGS_SHORT; - break; - - case QUALIFIER_LONG: - if (flags & FLAGS_QUAD) - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - else if (flags & FLAGS_LONG) - flags |= FLAGS_QUAD; - else - flags |= FLAGS_LONG; - break; - - case QUALIFIER_LONG_UPPER: - flags |= FLAGS_LONGDOUBLE; - break; - -#if defined(QUALIFIER_SIZE_T) - case QUALIFIER_SIZE_T: - flags |= FLAGS_SIZE_T; - /* Modify flags for later truncation of number */ - if (sizeof(size_t) == sizeof(trio_ulonglong_t)) - flags |= FLAGS_QUAD; - else if (sizeof(size_t) == sizeof(long)) - flags |= FLAGS_LONG; - break; -#endif - -#if defined(QUALIFIER_PTRDIFF_T) - case QUALIFIER_PTRDIFF_T: - flags |= FLAGS_PTRDIFF_T; - if (sizeof(ptrdiff_t) == sizeof(trio_ulonglong_t)) - flags |= FLAGS_QUAD; - else if (sizeof(ptrdiff_t) == sizeof(long)) - flags |= FLAGS_LONG; - break; -#endif - -#if defined(QUALIFIER_INTMAX_T) - case QUALIFIER_INTMAX_T: - flags |= FLAGS_INTMAX_T; - if (sizeof(trio_intmax_t) == sizeof(trio_ulonglong_t)) - flags |= FLAGS_QUAD; - else if (sizeof(trio_intmax_t) == sizeof(long)) - flags |= FLAGS_LONG; - break; -#endif - -#if defined(QUALIFIER_QUAD) - case QUALIFIER_QUAD: - flags |= FLAGS_QUAD; - break; -#endif - -#if defined(QUALIFIER_FIXED_SIZE) - case QUALIFIER_FIXED_SIZE: - if (flags & FLAGS_FIXED_SIZE) - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - - if (flags & (FLAGS_ALL_SIZES | FLAGS_LONGDOUBLE | - FLAGS_WIDECHAR | FLAGS_VARSIZE_PARAMETER)) - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - - if ((format[index] == '6') && - (format[index + 1] == '4')) - { - varsize = sizeof(trio_int64_t); - index += 2; - } - else if ((format[index] == '3') && - (format[index + 1] == '2')) - { - varsize = sizeof(trio_int32_t); - index += 2; - } - else if ((format[index] == '1') && - (format[index + 1] == '6')) - { - varsize = sizeof(trio_int16_t); - index += 2; - } - else if (format[index] == '8') - { - varsize = sizeof(trio_int8_t); - index++; - } - else - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - - flags |= FLAGS_FIXED_SIZE; - break; -#endif - -#if defined(QUALIFIER_WIDECHAR) - case QUALIFIER_WIDECHAR: - flags |= FLAGS_WIDECHAR; - break; -#endif - -#if defined(QUALIFIER_SIZE_T_UPPER) - case QUALIFIER_SIZE_T_UPPER: - break; -#endif - -#if defined(QUALIFIER_QUOTE) - case QUALIFIER_QUOTE: - flags |= FLAGS_QUOTE; - break; -#endif - -#if defined(QUALIFIER_STICKY) - case QUALIFIER_STICKY: - flags |= FLAGS_STICKY; - gotSticky = TRUE; - break; -#endif - -#if defined(QUALIFIER_VARSIZE) - case QUALIFIER_VARSIZE: - flags |= FLAGS_VARSIZE_PARAMETER; - parameterPosition++; - if (positional) - varsize = parameterPosition; - else - { - varsize = currentParam; - currentParam = varsize + 1; - } - if (currentParam > maxParam) - maxParam = currentParam; - 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); - } - } /* while qualifier */ - - /* - * Parameters only need the type and value. The value is - * read later. - */ - if (flags & FLAGS_WIDTH_PARAMETER) - { - usedEntries[width] += 1; - parameters[pos].type = FORMAT_PARAMETER; - parameters[pos].flags = 0; - indices[width] = pos; - width = pos++; - } - if (flags & FLAGS_PRECISION_PARAMETER) - { - usedEntries[precision] += 1; - parameters[pos].type = FORMAT_PARAMETER; - parameters[pos].flags = 0; - indices[precision] = pos; - precision = pos++; - } - if (flags & FLAGS_BASE_PARAMETER) - { - usedEntries[base] += 1; - parameters[pos].type = FORMAT_PARAMETER; - parameters[pos].flags = 0; - indices[base] = pos; - base = pos++; - } - if (flags & FLAGS_VARSIZE_PARAMETER) - { - usedEntries[varsize] += 1; - parameters[pos].type = FORMAT_PARAMETER; - parameters[pos].flags = 0; - indices[varsize] = pos; - varsize = pos++; - } - - indices[currentParam] = pos; - - switch (format[index++]) - { -#if defined(SPECIFIER_CHAR_UPPER) - case SPECIFIER_CHAR_UPPER: - flags |= FLAGS_WIDECHAR; - /* FALLTHROUGH */ -#endif - case SPECIFIER_CHAR: - if (flags & FLAGS_LONG) - flags |= FLAGS_WIDECHAR; - else if (flags & FLAGS_SHORT) - flags &= ~FLAGS_WIDECHAR; - parameters[pos].type = FORMAT_CHAR; - break; - -#if defined(SPECIFIER_STRING_UPPER) - case SPECIFIER_STRING_UPPER: - flags |= FLAGS_WIDECHAR; - /* FALLTHROUGH */ -#endif - case SPECIFIER_STRING: - if (flags & FLAGS_LONG) - flags |= FLAGS_WIDECHAR; - else if (flags & FLAGS_SHORT) - flags &= ~FLAGS_WIDECHAR; - parameters[pos].type = FORMAT_STRING; - break; - - case SPECIFIER_GROUP: - if (TYPE_SCAN == type) - { - int depth = 1; - parameters[pos].type = FORMAT_GROUP; - if (format[index] == QUALIFIER_CIRCUMFLEX) - index++; - if (format[index] == SPECIFIER_UNGROUP) - index++; - if (format[index] == QUALIFIER_MINUS) - index++; - /* Skip nested brackets */ - while (format[index] != NIL) - { - if (format[index] == SPECIFIER_GROUP) - { - depth++; - } - else if (format[index] == SPECIFIER_UNGROUP) - { - if (--depth <= 0) - { - index++; - break; - } - } - index++; - } - } - break; - - case SPECIFIER_INTEGER: - parameters[pos].type = FORMAT_INT; - break; - - case SPECIFIER_UNSIGNED: - flags |= FLAGS_UNSIGNED; - parameters[pos].type = FORMAT_INT; - break; - - case SPECIFIER_DECIMAL: - /* Disable base modifier */ - flags &= ~FLAGS_BASE_PARAMETER; - base = BASE_DECIMAL; - parameters[pos].type = FORMAT_INT; - break; - - case SPECIFIER_OCTAL: - flags &= ~FLAGS_BASE_PARAMETER; - base = BASE_OCTAL; - parameters[pos].type = FORMAT_INT; - break; - -#if defined(SPECIFIER_BINARY) - case SPECIFIER_BINARY_UPPER: - flags |= FLAGS_UPPER; - /* FALLTHROUGH */ - case SPECIFIER_BINARY: - flags |= FLAGS_NILPADDING; - flags &= ~FLAGS_BASE_PARAMETER; - base = BASE_BINARY; - parameters[pos].type = FORMAT_INT; - break; -#endif - - case SPECIFIER_HEX_UPPER: - flags |= FLAGS_UPPER; - /* FALLTHROUGH */ - case SPECIFIER_HEX: - flags |= FLAGS_UNSIGNED; - flags &= ~FLAGS_BASE_PARAMETER; - base = BASE_HEX; - parameters[pos].type = FORMAT_INT; - break; - - case SPECIFIER_FLOAT_E_UPPER: - flags |= FLAGS_UPPER; - /* FALLTHROUGH */ - case SPECIFIER_FLOAT_E: - flags |= FLAGS_FLOAT_E; - parameters[pos].type = FORMAT_DOUBLE; - break; - - case SPECIFIER_FLOAT_G_UPPER: - flags |= FLAGS_UPPER; - /* FALLTHROUGH */ - case SPECIFIER_FLOAT_G: - flags |= FLAGS_FLOAT_G; - parameters[pos].type = FORMAT_DOUBLE; - break; - - case SPECIFIER_FLOAT_F_UPPER: - flags |= FLAGS_UPPER; - /* FALLTHROUGH */ - case SPECIFIER_FLOAT_F: - parameters[pos].type = FORMAT_DOUBLE; - 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; - - case SPECIFIER_COUNT: - parameters[pos].type = FORMAT_COUNT; - break; - -#if defined(SPECIFIER_HEXFLOAT) -# if defined(SPECIFIER_HEXFLOAT_UPPER) - case SPECIFIER_HEXFLOAT_UPPER: - flags |= FLAGS_UPPER; - /* FALLTHROUGH */ -# endif - case SPECIFIER_HEXFLOAT: - base = BASE_HEX; - parameters[pos].type = FORMAT_DOUBLE; - break; -#endif - -#if defined(FORMAT_ERRNO) - case SPECIFIER_ERRNO: - parameters[pos].type = FORMAT_ERRNO; - break; -#endif - -#if defined(SPECIFIER_USER_DEFINED_BEGIN) - case SPECIFIER_USER_DEFINED_BEGIN: - { - unsigned int max; - int without_namespace = TRUE; - - parameters[pos].type = FORMAT_USER_DEFINED; - parameters[pos].user_name[0] = NIL; - tmpformat = (char *)&format[index]; - - while ((ch = format[index])) - { - index++; - if (ch == SPECIFIER_USER_DEFINED_END) - { - if (without_namespace) - { - /* We must get the handle first */ - parameters[pos].type = FORMAT_PARAMETER; - parameters[pos].indexAfterSpecifier = index; - parameters[pos].flags = FLAGS_USER_DEFINED; - /* Adjust parameters for insertion of new one */ - pos++; - usedEntries[currentParam] += 1; - parameters[pos].type = FORMAT_USER_DEFINED; - currentParam++; - indices[currentParam] = pos; - if (currentParam > maxParam) - maxParam = currentParam; - } - /* Copy the user data */ - max = (unsigned int)(&format[index] - tmpformat); - if (max > MAX_USER_DATA) - max = MAX_USER_DATA; - trio_copy_max(parameters[pos].user_data, - max, - tmpformat); - break; /* while */ - } - if (ch == SPECIFIER_USER_DEFINED_SEPARATOR) - { - without_namespace = FALSE; - /* Copy the namespace for later looking-up */ - max = (int)(&format[index] - tmpformat); - if (max > MAX_USER_NAME) - max = MAX_USER_NAME; - trio_copy_max(parameters[pos].user_name, - max, - tmpformat); - tmpformat = (char *)&format[index]; - } - } - if (ch != SPECIFIER_USER_DEFINED_END) - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - } - break; -#endif /* defined(SPECIFIER_USER_DEFINED_BEGIN) */ - - default: - /* Bail out completely to make the error more obvious */ - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - } - - /* Count the number of times this entry has been used */ - usedEntries[currentParam] += 1; - - /* Find last sticky parameters */ - if (gotSticky && !(flags & FLAGS_STICKY)) - { - for (i = pos - 1; i >= 0; i--) - { - if (parameters[i].type == FORMAT_PARAMETER) - continue; - if ((parameters[i].flags & FLAGS_STICKY) && - (parameters[i].type == parameters[pos].type)) - { - /* Do not overwrite current qualifiers */ - flags |= (parameters[i].flags & (unsigned long)~FLAGS_STICKY); - if (width == NO_WIDTH) - width = parameters[i].width; - if (precision == NO_PRECISION) - precision = parameters[i].precision; - if (base == NO_BASE) - base = parameters[i].base; - break; - } - } - } - - parameters[pos].indexAfterSpecifier = index; - parameters[pos].flags = flags; - parameters[pos].width = width; - parameters[pos].precision = precision; - parameters[pos].base = (base == NO_BASE) ? BASE_DECIMAL : base; - parameters[pos].varsize = varsize; - pos++; - - if (! positional) - parameterPosition++; - - } /* if identifier */ - - } /* while format characters left */ - - for (num = 0; num <= maxParam; num++) - { - if (usedEntries[num] != 1) - { - if (usedEntries[num] == 0) /* gap detected */ - return TRIO_ERROR_RETURN(TRIO_EGAP, num); - else /* double references detected */ - return TRIO_ERROR_RETURN(TRIO_EDBLREF, num); - } - - i = indices[num]; - - /* - * FORMAT_PARAMETERS are only present if they must be read, - * so it makes no sense to check the ignore flag (besides, - * the flags variable is not set for that particular type) - */ - if ((parameters[i].type != FORMAT_PARAMETER) && - (parameters[i].flags & FLAGS_IGNORE)) - continue; /* for all arguments */ - - /* - * The stack arguments are read according to ANSI C89 - * default argument promotions: - * - * char = int - * short = int - * unsigned char = unsigned int - * unsigned short = unsigned int - * float = double - * - * In addition to the ANSI C89 these types are read (the - * default argument promotions of C99 has not been - * considered yet) - * - * long long - * long double - * size_t - * ptrdiff_t - * intmax_t - */ - switch (parameters[i].type) - { - case FORMAT_GROUP: - case FORMAT_STRING: -#if TRIO_WIDECHAR - if (flags & FLAGS_WIDECHAR) - { - parameters[i].data.wstring = (argarray == NULL) - ? va_arg(*arglist, trio_wchar_t *) - : (trio_wchar_t *)(argarray[num]); - } - else -#endif - { - parameters[i].data.string = (argarray == NULL) - ? 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_UNKNOWN: - parameters[i].data.pointer = (argarray == NULL) - ? va_arg(*arglist, trio_pointer_t ) - : argarray[num]; - break; - - case FORMAT_CHAR: - case FORMAT_INT: - if (TYPE_SCAN == type) - { - if (argarray == NULL) - parameters[i].data.pointer = - (trio_pointer_t)va_arg(*arglist, trio_pointer_t); - else - { - if (parameters[i].type == FORMAT_CHAR) - parameters[i].data.pointer = - (trio_pointer_t)((char *)argarray[num]); - else if (parameters[i].flags & FLAGS_SHORT) - parameters[i].data.pointer = - (trio_pointer_t)((short *)argarray[num]); - else - parameters[i].data.pointer = - (trio_pointer_t)((int *)argarray[num]); - } - } - else - { -#if defined(QUALIFIER_VARSIZE) || defined(QUALIFIER_FIXED_SIZE) - if (parameters[i].flags - & (FLAGS_VARSIZE_PARAMETER | FLAGS_FIXED_SIZE)) - { - if (parameters[i].flags & FLAGS_VARSIZE_PARAMETER) - { - /* - * Variable sizes are mapped onto the fixed sizes, in - * accordance with integer promotion. - * - * Please note that this may not be portable, as we - * only guess the size, not the layout of the numbers. - * For example, if int is little-endian, and long is - * big-endian, then this will fail. - */ - varsize = (int)parameters[parameters[i].varsize].data.number.as_unsigned; - } - else - { - /* Used for the I modifiers */ - varsize = parameters[i].varsize; - } - parameters[i].flags &= ~FLAGS_ALL_VARSIZES; - - if (varsize <= (int)sizeof(int)) - ; - else if (varsize <= (int)sizeof(long)) - parameters[i].flags |= FLAGS_LONG; -#if defined(QUALIFIER_INTMAX_T) - else if (varsize <= (int)sizeof(trio_longlong_t)) - parameters[i].flags |= FLAGS_QUAD; - else - parameters[i].flags |= FLAGS_INTMAX_T; -#else - else - parameters[i].flags |= FLAGS_QUAD; -#endif - } -#endif /* defined(QUALIFIER_VARSIZE) */ -#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)(*((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)(*((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)(*((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)(*((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)(*((long *)argarray[num])); - else - { - if (argarray == NULL) - parameters[i].data.number.as_unsigned = (trio_uintmax_t)va_arg(*arglist, int); - else - { - if (parameters[i].type == FORMAT_CHAR) - parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((char *)argarray[num])); - else if (parameters[i].flags & FLAGS_SHORT) - parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((short *)argarray[num])); - else - parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((int *)argarray[num])); - } - } - } - break; - - case FORMAT_PARAMETER: - /* - * The parameter for the user-defined specifier is a pointer, - * whereas the rest (width, precision, base) uses an integer. - */ - if (parameters[i].flags & FLAGS_USER_DEFINED) - parameters[i].data.pointer = (argarray == NULL) - ? 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)(*((int *)argarray[num])); - break; - - case FORMAT_DOUBLE: - if (TYPE_SCAN == type) - { - if (parameters[i].flags & FLAGS_LONGDOUBLE) - parameters[i].data.longdoublePointer = (argarray == NULL) - ? va_arg(*arglist, trio_long_double_t *) - : (trio_long_double_t *)argarray[num]; - else - { - 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_LONGDOUBLE) - parameters[i].data.longdoubleNumber = (argarray == NULL) - ? 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 = - (trio_long_double_t)va_arg(*arglist, double); - else - { - if (parameters[i].flags & FLAGS_SHORT) - parameters[i].data.longdoubleNumber = - (trio_long_double_t)(*((float *)argarray[num])); - else - parameters[i].data.longdoubleNumber = - (trio_long_double_t)(*((double *)argarray[num])); - } - } - } - break; - -#if defined(FORMAT_ERRNO) - case FORMAT_ERRNO: - parameters[i].data.errorNumber = save_errno; - break; -#endif - - default: - break; - } - } /* for all specifiers */ - return num; -} - - -/************************************************************************* - * - * FORMATTING - * - ************************************************************************/ - - -/************************************************************************* - * TrioWriteNumber - * - * Description: - * Output a number. - * The complexity of this function is a result of the complexity - * of the dependencies of the flags. - */ -TRIO_PRIVATE void -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]; - char *bufferend; - char *pointer; - TRIO_CONST char *digits; - int i; - int length; - char *p; - int count; - - assert(VALID(self)); - assert(VALID(self->OutStream)); - 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 = -((trio_intmax_t)number); - - if (flags & FLAGS_QUAD) - number &= (trio_ulonglong_t)-1; - else if (flags & FLAGS_LONG) - number &= (unsigned long)-1; - else - number &= (unsigned int)-1; - - /* Build number */ - pointer = bufferend = &buffer[sizeof(buffer) - 1]; - *pointer-- = NIL; - for (i = 1; i < (int)sizeof(buffer); i++) - { - *pointer-- = digits[number % base]; - number /= base; - if (number == 0) - break; - - 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 = internalThousandSeparatorLength; - if (((int)(pointer - buffer) - length) > 0) - { - p = &internalThousandSeparator[length - 1]; - while (length-- > 0) - *pointer-- = *p--; - } - } - } - - /* Adjust width */ - width -= (bufferend - pointer) - 1; - - /* Adjust precision */ - if (NO_PRECISION != precision) - { - precision -= (bufferend - pointer) - 1; - if (precision < 0) - precision = 0; - flags |= FLAGS_NILPADDING; - } - - /* Adjust width further */ - if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE)) - width--; - if (flags & FLAGS_ALTERNATIVE) - { - switch (base) - { - case BASE_BINARY: - case BASE_HEX: - width -= 2; - break; - case BASE_OCTAL: - width--; - break; - default: - break; - } - } - - /* Output prefixes spaces if needed */ - if (! ((flags & FLAGS_LEFTADJUST) || - ((flags & FLAGS_NILPADDING) && (precision == NO_PRECISION)))) - { - count = (precision == NO_PRECISION) ? 0 : precision; - while (width-- > count) - self->OutStream(self, CHAR_ADJUST); - } - - /* width has been adjusted for signs and alternatives */ - if (isNegative) - self->OutStream(self, '-'); - else if (flags & FLAGS_SHOWSIGN) - self->OutStream(self, '+'); - else if (flags & FLAGS_SPACE) - self->OutStream(self, ' '); - - if (flags & FLAGS_ALTERNATIVE) - { - switch (base) - { - case BASE_BINARY: - self->OutStream(self, '0'); - self->OutStream(self, (flags & FLAGS_UPPER) ? 'B' : 'b'); - break; - - case BASE_OCTAL: - self->OutStream(self, '0'); - break; - - case BASE_HEX: - self->OutStream(self, '0'); - self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x'); - break; - - default: - break; - } /* switch base */ - } - - /* Output prefixed zero padding if needed */ - if (flags & FLAGS_NILPADDING) - { - if (precision == NO_PRECISION) - precision = width; - while (precision-- > 0) - { - self->OutStream(self, '0'); - width--; - } - } - - /* Output the number itself */ - while (*(++pointer)) - { - self->OutStream(self, *pointer); - } - - /* Output trailing spaces if needed */ - if (flags & FLAGS_LEFTADJUST) - { - while (width-- > 0) - self->OutStream(self, CHAR_ADJUST); - } -} - -/************************************************************************* - * TrioWriteStringCharacter - * - * Description: - * Output a single character of a string - */ -TRIO_PRIVATE void -TrioWriteStringCharacter -TRIO_ARGS3((self, ch, flags), - trio_class_t *self, - int ch, - unsigned long flags) -{ - if (flags & FLAGS_ALTERNATIVE) - { - if (! isprint(ch)) - { - /* - * Non-printable characters are converted to C escapes or - * \number, if no C escape exists. - */ - self->OutStream(self, CHAR_BACKSLASH); - switch (ch) - { - case '\007': self->OutStream(self, 'a'); break; - case '\b': self->OutStream(self, 'b'); break; - case '\f': self->OutStream(self, 'f'); break; - case '\n': self->OutStream(self, 'n'); break; - case '\r': self->OutStream(self, 'r'); break; - case '\t': self->OutStream(self, 't'); break; - case '\v': self->OutStream(self, 'v'); break; - case '\\': self->OutStream(self, '\\'); break; - default: - self->OutStream(self, 'x'); - TrioWriteNumber(self, (trio_uintmax_t)ch, - FLAGS_UNSIGNED | FLAGS_NILPADDING, - 2, 2, BASE_HEX); - break; - } - } - else if (ch == CHAR_BACKSLASH) - { - self->OutStream(self, CHAR_BACKSLASH); - self->OutStream(self, CHAR_BACKSLASH); - } - else - { - self->OutStream(self, ch); - } - } - else - { - self->OutStream(self, ch); - } -} - -/************************************************************************* - * TrioWriteString - * - * Description: - * Output a string - */ -TRIO_PRIVATE void -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; - - assert(VALID(self)); - assert(VALID(self->OutStream)); - - if (string == NULL) - { - string = internalNullString; - length = sizeof(internalNullString) - 1; - /* Disable quoting for the null pointer */ - flags &= (~FLAGS_QUOTE); - width = 0; - } - else - { - length = trio_length(string); - } - if ((NO_PRECISION != precision) && - (precision < length)) - { - length = precision; - } - width -= length; - - if (flags & FLAGS_QUOTE) - self->OutStream(self, CHAR_QUOTE); - - if (! (flags & FLAGS_LEFTADJUST)) - { - while (width-- > 0) - self->OutStream(self, CHAR_ADJUST); - } - - while (length-- > 0) - { - /* The ctype parameters must be an unsigned char (or EOF) */ - ch = (int)((unsigned char)(*string++)); - TrioWriteStringCharacter(self, ch, flags); - } - - if (flags & FLAGS_LEFTADJUST) - { - while (width-- > 0) - self->OutStream(self, CHAR_ADJUST); - } - if (flags & FLAGS_QUOTE) - self->OutStream(self, CHAR_QUOTE); -} - -/************************************************************************* - * TrioWriteWideStringCharacter - * - * Description: - * Output a wide string as a multi-byte sequence - */ -#if TRIO_WIDECHAR -TRIO_PRIVATE int -TrioWriteWideStringCharacter -TRIO_ARGS4((self, wch, flags, width), - trio_class_t *self, - trio_wchar_t wch, - unsigned long flags, - int width) -{ - int size; - int i; - int ch; - char *string; - char buffer[MB_LEN_MAX + 1]; - - if (width == NO_WIDTH) - width = sizeof(buffer); - - size = wctomb(buffer, wch); - if ((size <= 0) || (size > width) || (buffer[0] == NIL)) - return 0; - - string = buffer; - i = size; - while ((width >= i) && (width-- > 0) && (i-- > 0)) - { - /* The ctype parameters must be an unsigned char (or EOF) */ - ch = (int)((unsigned char)(*string++)); - TrioWriteStringCharacter(self, ch, flags); - } - return size; -} -#endif /* TRIO_WIDECHAR */ - -/************************************************************************* - * TrioWriteWideString - * - * Description: - * Output a wide character string as a multi-byte string - */ -#if TRIO_WIDECHAR -TRIO_PRIVATE void -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; - - assert(VALID(self)); - assert(VALID(self->OutStream)); - -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - (void)mblen(NULL, 0); -#endif - - if (wstring == NULL) - { - TrioWriteString(self, NULL, flags, width, precision); - return; - } - - if (NO_PRECISION == precision) - { - length = INT_MAX; - } - else - { - length = precision; - width -= length; - } - - if (flags & FLAGS_QUOTE) - self->OutStream(self, CHAR_QUOTE); - - if (! (flags & FLAGS_LEFTADJUST)) - { - while (width-- > 0) - self->OutStream(self, CHAR_ADJUST); - } - - while (length > 0) - { - size = TrioWriteWideStringCharacter(self, *wstring++, flags, length); - if (size == 0) - break; /* while */ - length -= size; - } - - if (flags & FLAGS_LEFTADJUST) - { - while (width-- > 0) - self->OutStream(self, CHAR_ADJUST); - } - if (flags & FLAGS_QUOTE) - self->OutStream(self, CHAR_QUOTE); -} -#endif /* TRIO_WIDECHAR */ - -/************************************************************************* - * 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 - * " - */ -/* FIXME: handle all instances of constant long-double number (L) - * and *l() math functions. - */ -TRIO_PRIVATE void -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 = 0; - unsigned int uExponent = 0; - 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 *groupingPointer; - int i; - 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 >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE)); - - /* Determine sign and look for special quantities */ - switch (trio_fpclassify_and_signbit(number, &isNegative)) - { - case TRIO_FP_NAN: - TrioWriteString(self, - (flags & FLAGS_UPPER) - ? 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; - } - - /* Normal numbers */ - if (flags & FLAGS_LONGDOUBLE) - { - 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; - } - - digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower; - isHex = (base == BASE_HEX); - 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; - - if (isNegative) - number = -number; - - if (isHex) - flags |= FLAGS_FLOAT_E; - - if (flags & FLAGS_FLOAT_G) - { - if (precision == 0) - precision = 1; - - if ((number < 1.0E-4) || (number > powl(base, - (trio_long_double_t)precision))) - { - /* Use scientific notation */ - flags |= FLAGS_FLOAT_E; - } - else if (number < 1.0) - { - /* - * Use normal notation. If the integer part of the number is - * zero, then adjust the precision to include leading fractional - * zeros. - */ - workNumber = TrioLogarithm(number, base); - workNumber = TRIO_FABS(workNumber); - if (workNumber - floorl(workNumber) < 0.001) - workNumber--; - zeroes = (int)floorl(workNumber); - } - } - - if (flags & FLAGS_FLOAT_E) - { - /* Scale the number */ - workNumber = TrioLogarithm(number, base); - if (trio_isinf(workNumber) == -1) - { - exponent = 0; - /* Undo setting */ - if (flags & FLAGS_FLOAT_G) - flags &= ~FLAGS_FLOAT_E; - } - else - { - exponent = (int)floorl(workNumber); - number /= powl(dblBase, (trio_long_double_t)exponent); - isExponentNegative = (exponent < 0); - uExponent = (isExponentNegative) ? -exponent : exponent; - /* No thousand separators */ - flags &= ~FLAGS_QUOTE; - } - } - - integerNumber = floorl(number); - fractionNumber = number - integerNumber; - - /* - * Truncated number. - * - * Precision is number of significant digits for FLOAT_G - * and number of fractional digits for others. - */ - integerDigits = (integerNumber > epsilon) - ? 1 + (int)TrioLogarithm(integerNumber, base) - : 1; - fractionDigits = ((flags & FLAGS_FLOAT_G) && (zeroes == 0)) - ? precision - integerDigits - : zeroes + precision; - - dblFractionBase = TrioPower(base, 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++; - 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) */ - integerNumber = floorl(number + 0.5); - fractionNumber = 0.0; - integerDigits = (integerNumber > epsilon) - ? 1 + (int)TrioLogarithm(integerNumber, base) - : 1; - } - } - - /* Estimate accuracy */ - integerAdjust = fractionAdjust = 0.5; - if (flags & FLAGS_ROUNDING) - { - if (integerDigits > baseDigits) - { - integerThreshold = baseDigits; - fractionDigits = 0; - dblFractionBase = 1.0; - fractionThreshold = 0; - precision = 0; /* Disable decimal-point */ - integerAdjust = TrioPower(base, integerDigits - integerThreshold - 1); - fractionAdjust = 0.0; - } - else - { - integerThreshold = integerDigits; - fractionThreshold = fractionDigits - integerThreshold; - fractionAdjust = 1.0; - } - } - else - { - integerThreshold = INT_MAX; - fractionThreshold = INT_MAX; - } - - /* - * Calculate expected width. - * sign + integer part + thousands separators + decimal point - * + fraction + exponent - */ - 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 + - ((requireTwoDigitExponent ? sizeof("E+0") : sizeof("E+")) - 1); - if (isHex) - expectedWidth += sizeof("0X") - 1; - - /* Output prefixing */ - if (flags & FLAGS_NILPADDING) - { - /* Leading zeros must be after sign */ - if (isNegative) - 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'); - } - if (!(flags & FLAGS_LEFTADJUST)) - { - for (i = expectedWidth; i < width; i++) - { - self->OutStream(self, '0'); - } - } - } - else - { - /* Leading spaces must be before sign */ - if (!(flags & FLAGS_LEFTADJUST)) - { - for (i = expectedWidth; i < width; i++) - { - self->OutStream(self, CHAR_ADJUST); - } - } - if (isNegative) - 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 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) - { - while (trailingZeroes > 0) - { - self->OutStream(self, digits[0]); - trailingZeroes--; - } - } - - /* Output exponent */ - if (exponentDigits > 0) - { - self->OutStream(self, - isHex - ? ((flags & FLAGS_UPPER) ? 'P' : 'p') - : ((flags & FLAGS_UPPER) ? 'E' : 'e')); - self->OutStream(self, (isExponentNegative) ? '-' : '+'); - - /* The exponent must contain at least two digits */ - if (requireTwoDigitExponent) - self->OutStream(self, '0'); - - exponentBase = (int)TrioPower(base, exponentDigits - 1); - for (i = 0; i < exponentDigits; i++) - { - self->OutStream(self, digits[(uExponent / exponentBase) % base]); - exponentBase /= base; - } - } - /* Output trailing spaces */ - if (flags & FLAGS_LEFTADJUST) - { - for (i = expectedWidth; i < width; i++) - { - self->OutStream(self, CHAR_ADJUST); - } - } -} - -/************************************************************************* - * TrioFormatProcess - * - * Description: - * This is the main engine for formatting output - */ -TRIO_PRIVATE int -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; - trio_pointer_t pointer; - unsigned long flags; - int width; - int precision; - int base; - int index; - - index = 0; - i = 0; -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - (void)mblen(NULL, 0); -#endif - - while (format[index]) - { -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - if (! isascii(format[index])) - { - charlen = mblen(&format[index], MB_LEN_MAX); - /* - * Only valid multibyte characters are handled here. Invalid - * multibyte characters (charlen == -1) are handled as normal - * characters. - */ - if (charlen != -1) - { - while (charlen-- > 0) - { - data->OutStream(data, format[index++]); - } - continue; /* while characters left in formatting string */ - } - } -#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */ - if (CHAR_IDENTIFIER == format[index]) - { - if (CHAR_IDENTIFIER == format[index + 1]) - { - data->OutStream(data, CHAR_IDENTIFIER); - index += 2; - } - else - { - /* Skip the parameter entries */ - while (parameters[i].type == FORMAT_PARAMETER) - i++; - - flags = parameters[i].flags; - - /* Find width */ - width = parameters[i].width; - if (flags & FLAGS_WIDTH_PARAMETER) - { - /* Get width from parameter list */ - width = (int)parameters[width].data.number.as_signed; - } - - /* Find precision */ - if (flags & FLAGS_PRECISION) - { - precision = parameters[i].precision; - if (flags & FLAGS_PRECISION_PARAMETER) - { - /* Get precision from parameter list */ - precision = (int)parameters[precision].data.number.as_signed; - } - } - else - { - precision = NO_PRECISION; - } - - /* Find base */ - base = parameters[i].base; - if (flags & FLAGS_BASE_PARAMETER) - { - /* Get base from parameter list */ - base = (int)parameters[base].data.number.as_signed; - } - - switch (parameters[i].type) - { - case FORMAT_CHAR: - if (flags & FLAGS_QUOTE) - data->OutStream(data, CHAR_QUOTE); - if (! (flags & FLAGS_LEFTADJUST)) - { - while (--width > 0) - data->OutStream(data, CHAR_ADJUST); - } -#if TRIO_WIDECHAR - if (flags & FLAGS_WIDECHAR) - { - TrioWriteWideStringCharacter(data, - (trio_wchar_t)parameters[i].data.number.as_signed, - flags, - NO_WIDTH); - } - else -#endif - { - TrioWriteStringCharacter(data, - (int)parameters[i].data.number.as_signed, - flags); - } - - if (flags & FLAGS_LEFTADJUST) - { - while(--width > 0) - data->OutStream(data, CHAR_ADJUST); - } - if (flags & FLAGS_QUOTE) - data->OutStream(data, CHAR_QUOTE); - - break; /* FORMAT_CHAR */ - - case FORMAT_INT: - TrioWriteNumber(data, - parameters[i].data.number.as_unsigned, - flags, - width, - precision, - base); - - break; /* FORMAT_INT */ - - case FORMAT_DOUBLE: - TrioWriteDouble(data, - parameters[i].data.longdoubleNumber, - flags, - width, - precision, - base); - break; /* FORMAT_DOUBLE */ - - case FORMAT_STRING: -#if TRIO_WIDECHAR - if (flags & FLAGS_WIDECHAR) - { - TrioWriteWideString(data, - parameters[i].data.wstring, - flags, - width, - precision); - } - else -#endif - { - TrioWriteString(data, - parameters[i].data.string, - flags, - width, - precision); - } - break; /* FORMAT_STRING */ - - case FORMAT_POINTER: - { - trio_reference_t reference; - - reference.data = data; - reference.parameter = ¶meters[i]; - trio_print_pointer(&reference, parameters[i].data.pointer); - } - break; /* FORMAT_POINTER */ - - case FORMAT_COUNT: - pointer = parameters[i].data.pointer; - if (NULL != pointer) - { - /* - * C99 paragraph 7.19.6.1.8 says "the number of - * characters written to the output stream so far by - * this call", which is data->committed - */ -#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER) - if (flags & FLAGS_SIZE_T) - *(size_t *)pointer = (size_t)data->committed; - else -#endif -#if defined(QUALIFIER_PTRDIFF_T) - if (flags & FLAGS_PTRDIFF_T) - *(ptrdiff_t *)pointer = (ptrdiff_t)data->committed; - else -#endif -#if defined(QUALIFIER_INTMAX_T) - if (flags & FLAGS_INTMAX_T) - *(trio_intmax_t *)pointer = (trio_intmax_t)data->committed; - else -#endif - if (flags & FLAGS_QUAD) - { - *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)data->committed; - } - else if (flags & FLAGS_LONG) - { - *(long int *)pointer = (long int)data->committed; - } - else if (flags & FLAGS_SHORT) - { - *(short int *)pointer = (short int)data->committed; - } - else - { - *(int *)pointer = (int)data->committed; - } - } - break; /* FORMAT_COUNT */ - - case FORMAT_PARAMETER: - break; /* FORMAT_PARAMETER */ - -#if defined(FORMAT_ERRNO) - case FORMAT_ERRNO: - string = trio_error(parameters[i].data.errorNumber); - if (string) - { - TrioWriteString(data, - string, - flags, - width, - precision); - } - else - { - data->OutStream(data, '#'); - TrioWriteNumber(data, - (trio_uintmax_t)parameters[i].data.errorNumber, - flags, - width, - precision, - BASE_DECIMAL); - } - break; /* FORMAT_ERRNO */ -#endif /* defined(FORMAT_ERRNO) */ - -#if defined(FORMAT_USER_DEFINED) - case FORMAT_USER_DEFINED: - { - trio_reference_t reference; - trio_userdef_t *def = NULL; - - if (parameters[i].user_name[0] == NIL) - { - /* Use handle */ - if ((i > 0) || - (parameters[i - 1].type == FORMAT_PARAMETER)) - def = (trio_userdef_t *)parameters[i - 1].data.pointer; - } - else - { - /* Look up namespace */ - def = TrioFindNamespace(parameters[i].user_name, NULL); - } - if (def) { - reference.data = data; - reference.parameter = ¶meters[i]; - def->callback(&reference); - } - } - break; -#endif /* defined(FORMAT_USER_DEFINED) */ - - default: - break; - } /* switch parameter type */ - - /* Prepare for next */ - index = parameters[i].indexAfterSpecifier; - i++; - } - } - else /* not identifier */ - { - data->OutStream(data, format[index++]); - } - } - return data->processed; -} - -/************************************************************************* - * TrioFormatRef - */ -TRIO_PRIVATE int -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]; - - status = TrioParse(TYPE_PRINT, format, parameters, arglist, argarray); - if (status < 0) - return status; - - status = TrioFormatProcess(reference->data, format, parameters); - if (reference->data->error != 0) - { - status = reference->data->error; - } - return status; -} - -/************************************************************************* - * TrioFormat - */ -TRIO_PRIVATE int -TrioFormat -TRIO_ARGS6((destination, destinationSize, OutStream, format, arglist, argarray), - trio_pointer_t destination, - size_t destinationSize, - void (*OutStream) TRIO_PROTO((trio_class_t *, int)), - TRIO_CONST char *format, - va_list *arglist, - trio_pointer_t *argarray) -{ - int status; - trio_class_t data; - trio_parameter_t parameters[MAX_PARAMETERS]; - - assert(VALID(OutStream)); - assert(VALID(format)); - - memset(&data, 0, sizeof(data)); - data.OutStream = OutStream; - data.location = destination; - data.max = destinationSize; - data.error = 0; - -#if defined(USE_LOCALE) - if (NULL == internalLocaleValues) - { - TrioSetLocale(); - } -#endif - - status = TrioParse(TYPE_PRINT, format, parameters, arglist, argarray); - if (status < 0) - return status; - - status = TrioFormatProcess(&data, format, parameters); - if (data.error != 0) - { - status = data.error; - } - return status; -} - -/************************************************************************* - * TrioOutStreamFile - */ -TRIO_PRIVATE void -TrioOutStreamFile -TRIO_ARGS2((self, output), - trio_class_t *self, - int output) -{ - FILE *file; - - assert(VALID(self)); - assert(VALID(self->location)); - - file = (FILE *)self->location; - self->processed++; - if (fputc(output, file) == EOF) - { - self->error = TRIO_ERROR_RETURN(TRIO_EOF, 0); - } - else - { - self->committed++; - } -} - -/************************************************************************* - * TrioOutStreamFileDescriptor - */ -TRIO_PRIVATE void -TrioOutStreamFileDescriptor -TRIO_ARGS2((self, output), - trio_class_t *self, - int output) -{ - int fd; - char ch; - - assert(VALID(self)); - - fd = *((int *)self->location); - ch = (char)output; - self->processed++; - if (write(fd, &ch, sizeof(char)) == -1) - { - self->error = TRIO_ERROR_RETURN(TRIO_ERRNO, 0); - } - else - { - self->committed++; - } -} - -/************************************************************************* - * 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_ARGS2((self, output), - trio_class_t *self, - int output) -{ - char **buffer; - - assert(VALID(self)); - assert(VALID(self->location)); - - buffer = (char **)self->location; - **buffer = (char)output; - (*buffer)++; - self->processed++; - self->committed++; -} - -/************************************************************************* - * TrioOutStreamStringMax - */ -TRIO_PRIVATE void -TrioOutStreamStringMax -TRIO_ARGS2((self, output), - trio_class_t *self, - int output) -{ - char **buffer; - - assert(VALID(self)); - assert(VALID(self->location)); - - buffer = (char **)self->location; - - if (self->processed < self->max) - { - **buffer = (char)output; - (*buffer)++; - self->committed++; - } - self->processed++; -} - -/************************************************************************* - * TrioOutStreamStringDynamic - */ -TRIO_PRIVATE void -TrioOutStreamStringDynamic -TRIO_ARGS2((self, output), - trio_class_t *self, - int output) -{ - assert(VALID(self)); - assert(VALID(self->location)); - - if (self->error == 0) - { - trio_xstring_append_char((trio_string_t *)self->location, - (char)output); - self->committed++; - } - /* The processed variable must always be increased */ - self->processed++; -} - -/************************************************************************* - * - * Formatted printing functions - * - ************************************************************************/ - -#if defined(TRIO_DOCUMENTATION) -# include "doc/doc_printf.h" -#endif -/** @addtogroup Printf - @{ -*/ - -/************************************************************************* - * printf - */ - -/** - Print to standard output stream. - - @param format Formatting string. - @param ... Arguments. - @return Number of printed characters. - */ -TRIO_PUBLIC int -trio_printf -TRIO_VARGS2((format, va_alist), - TRIO_CONST char *format, - TRIO_VA_DECL) -{ - int status; - va_list args; - - assert(VALID(format)); - - TRIO_VA_START(args, format); - status = TrioFormat(stdout, 0, TrioOutStreamFile, format, &args, NULL); - TRIO_VA_END(args); - return status; -} - -/** - Print to standard output stream. - - @param format Formatting string. - @param args Arguments. - @return Number of printed characters. - */ -TRIO_PUBLIC int -trio_vprintf -TRIO_ARGS2((format, args), - TRIO_CONST char *format, - va_list args) -{ - assert(VALID(format)); - - return TrioFormat(stdout, 0, TrioOutStreamFile, format, &args, NULL); -} - -/** - Print to standard output stream. - - @param format Formatting string. - @param args Arguments. - @return Number of printed characters. - */ -TRIO_PUBLIC int -trio_printfv -TRIO_ARGS2((format, args), - TRIO_CONST char *format, - trio_pointer_t * args) -{ - assert(VALID(format)); - - return TrioFormat(stdout, 0, TrioOutStreamFile, format, NULL, args); -} - -/************************************************************************* - * fprintf - */ - -/** - Print to file. - - @param file File pointer. - @param format Formatting string. - @param ... Arguments. - @return Number of printed characters. - */ -TRIO_PUBLIC int -trio_fprintf -TRIO_VARGS3((file, format, va_alist), - FILE *file, - TRIO_CONST char *format, - TRIO_VA_DECL) -{ - int status; - va_list args; - - assert(VALID(file)); - assert(VALID(format)); - - TRIO_VA_START(args, format); - status = TrioFormat(file, 0, TrioOutStreamFile, format, &args, NULL); - TRIO_VA_END(args); - return status; -} - -/** - Print to file. - - @param file File pointer. - @param format Formatting string. - @param args Arguments. - @return Number of printed characters. - */ -TRIO_PUBLIC int -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); -} - -/** - Print to file. - - @param file File pointer. - @param format Formatting string. - @param args Arguments. - @return Number of printed characters. - */ -TRIO_PUBLIC int -trio_fprintfv -TRIO_ARGS3((file, format, args), - FILE *file, - TRIO_CONST char *format, - trio_pointer_t * args) -{ - assert(VALID(file)); - assert(VALID(format)); - - return TrioFormat(file, 0, TrioOutStreamFile, format, NULL, args); -} - -/************************************************************************* - * dprintf - */ - -/** - Print to file descriptor. - - @param fd File descriptor. - @param format Formatting string. - @param ... Arguments. - @return Number of printed characters. - */ -TRIO_PUBLIC int -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)); - - TRIO_VA_START(args, format); - status = TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, &args, NULL); - TRIO_VA_END(args); - return status; -} - -/** - Print to file descriptor. - - @param fd File descriptor. - @param format Formatting string. - @param args Arguments. - @return Number of printed characters. - */ -TRIO_PUBLIC int -trio_vdprintf -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); -} - -/** - Print to file descriptor. - - @param fd File descriptor. - @param format Formatting string. - @param args Arguments. - @return Number of printed characters. - */ -TRIO_PUBLIC int -trio_dprintfv -TRIO_ARGS3((fd, format, args), - int fd, - TRIO_CONST char *format, - trio_pointer_t *args) -{ - assert(VALID(format)); - - 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); -} - -/************************************************************************* - * sprintf - */ - -/** - Print to string. - - @param buffer Output string. - @param format Formatting string. - @param ... Arguments. - @return Number of printed characters. - */ -TRIO_PUBLIC int -trio_sprintf -TRIO_VARGS3((buffer, format, va_alist), - char *buffer, - TRIO_CONST char *format, - TRIO_VA_DECL) -{ - int status; - va_list args; - - assert(VALID(buffer)); - assert(VALID(format)); - - TRIO_VA_START(args, format); - status = TrioFormat(&buffer, 0, TrioOutStreamString, format, &args, NULL); - *buffer = NIL; /* Terminate with NIL character */ - TRIO_VA_END(args); - return status; -} - -/** - Print to string. - - @param buffer Output string. - @param format Formatting string. - @param args Arguments. - @return Number of printed characters. - */ -TRIO_PUBLIC int -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); - *buffer = NIL; - return status; -} - -/** - Print to string. - - @param buffer Output string. - @param format Formatting string. - @param args Arguments. - @return Number of printed characters. - */ -TRIO_PUBLIC int -trio_sprintfv -TRIO_ARGS3((buffer, format, args), - char *buffer, - TRIO_CONST char *format, - trio_pointer_t *args) -{ - int status; - - assert(VALID(buffer)); - assert(VALID(format)); - - status = TrioFormat(&buffer, 0, TrioOutStreamString, format, NULL, args); - *buffer = NIL; - return status; -} - -/************************************************************************* - * snprintf - */ - -/** - Print at most @p max characters to string. - - @param buffer Output string. - @param max Maximum number of characters to print. - @param format Formatting string. - @param ... Arguments. - @return Number of printed characters. - */ -TRIO_PUBLIC int -trio_snprintf -TRIO_VARGS4((buffer, max, format, va_alist), - char *buffer, - size_t max, - TRIO_CONST char *format, - TRIO_VA_DECL) -{ - int status; - va_list args; - - assert(VALID(buffer)); - assert(VALID(format)); - - TRIO_VA_START(args, format); - status = TrioFormat(&buffer, max > 0 ? max - 1 : 0, - TrioOutStreamStringMax, format, &args, NULL); - if (max > 0) - *buffer = NIL; - TRIO_VA_END(args); - return status; -} - -/** - Print at most @p max characters to string. - - @param buffer Output string. - @param max Maximum number of characters to print. - @param format Formatting string. - @param args Arguments. - @return Number of printed characters. - */ -TRIO_PUBLIC int -trio_vsnprintf -TRIO_ARGS4((buffer, max, format, args), - char *buffer, - size_t max, - TRIO_CONST char *format, - va_list args) -{ - int status; - - assert(VALID(buffer)); - assert(VALID(format)); - - status = TrioFormat(&buffer, max > 0 ? max - 1 : 0, - TrioOutStreamStringMax, format, &args, NULL); - if (max > 0) - *buffer = NIL; - return status; -} - -/** - Print at most @p max characters to string. - - @param buffer Output string. - @param max Maximum number of characters to print. - @param format Formatting string. - @param args Arguments. - @return Number of printed characters. - */ -TRIO_PUBLIC int -trio_snprintfv -TRIO_ARGS4((buffer, max, format, args), - char *buffer, - size_t max, - TRIO_CONST char *format, - trio_pointer_t *args) -{ - int status; - - assert(VALID(buffer)); - assert(VALID(format)); - - status = TrioFormat(&buffer, max > 0 ? max - 1 : 0, - TrioOutStreamStringMax, format, NULL, args); - if (max > 0) - *buffer = NIL; - return status; -} - -/************************************************************************* - * snprintfcat - * Appends the new string to the buffer string overwriting the '\0' - * character at the end of buffer. - */ -TRIO_PUBLIC int -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; - - TRIO_VA_START(args, format); - - 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); - TRIO_VA_END(args); - *buffer = NIL; - return status; -} - -TRIO_PUBLIC int -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); - *buffer = NIL; - return status; -} - -/************************************************************************* - * trio_aprintf - */ - -/* Deprecated */ -TRIO_PUBLIC char * -trio_aprintf -TRIO_VARGS2((format, va_alist), - TRIO_CONST char *format, - TRIO_VA_DECL) -{ - va_list args; - trio_string_t *info; - char *result = NULL; - - assert(VALID(format)); - - info = trio_xstring_duplicate(""); - if (info) - { - TRIO_VA_START(args, format); - (void)TrioFormat(info, 0, TrioOutStreamStringDynamic, - format, &args, NULL); - TRIO_VA_END(args); - - trio_string_terminate(info); - result = trio_string_extract(info); - trio_string_destroy(info); - } - return result; -} - -/* Deprecated */ -TRIO_PUBLIC char * -trio_vaprintf -TRIO_ARGS2((format, args), - TRIO_CONST char *format, - va_list args) -{ - trio_string_t *info; - char *result = NULL; - - assert(VALID(format)); - - info = trio_xstring_duplicate(""); - if (info) - { - (void)TrioFormat(info, 0, TrioOutStreamStringDynamic, - format, &args, NULL); - trio_string_terminate(info); - result = trio_string_extract(info); - trio_string_destroy(info); - } - return result; -} - -TRIO_PUBLIC int -trio_asprintf -TRIO_VARGS3((result, format, va_alist), - char **result, - TRIO_CONST char *format, - TRIO_VA_DECL) -{ - va_list args; - int status; - trio_string_t *info; - - assert(VALID(format)); - - *result = NULL; - - info = trio_xstring_duplicate(""); - if (info == NULL) - { - status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0); - } - else - { - TRIO_VA_START(args, format); - status = TrioFormat(info, 0, TrioOutStreamStringDynamic, - format, &args, NULL); - TRIO_VA_END(args); - if (status >= 0) - { - trio_string_terminate(info); - *result = trio_string_extract(info); - } - trio_string_destroy(info); - } - return status; -} - -TRIO_PUBLIC int -trio_vasprintf -TRIO_ARGS3((result, format, args), - char **result, - TRIO_CONST char *format, - va_list args) -{ - int status; - trio_string_t *info; - - assert(VALID(format)); - - *result = NULL; - - info = trio_xstring_duplicate(""); - if (info == NULL) - { - status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0); - } - else - { - status = TrioFormat(info, 0, TrioOutStreamStringDynamic, - format, &args, NULL); - if (status >= 0) - { - trio_string_terminate(info); - *result = trio_string_extract(info); - } - trio_string_destroy(info); - } - return status; -} - -/** @} End of Printf documentation module */ - -/************************************************************************* - * - * CALLBACK - * - ************************************************************************/ - -#if defined(TRIO_DOCUMENTATION) -# include "doc/doc_register.h" -#endif -/** - @addtogroup UserDefined - @{ -*/ - -#if TRIO_EXTENSION - -/************************************************************************* - * trio_register - */ - -/** - Register new user-defined specifier. - - @param callback - @param name - @return Handle. - */ -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; - - if (callback == NULL) - return NULL; - - if (name) - { - /* Handle built-in namespaces */ - if (name[0] == ':') - { - if (trio_equal(name, ":enter")) - { - internalEnterCriticalRegion = callback; - } - else if (trio_equal(name, ":leave")) - { - internalLeaveCriticalRegion = callback; - } - return NULL; - } - - /* Bail out if namespace is too long */ - if (trio_length(name) >= MAX_USER_NAME) - return NULL; - - /* Bail out if namespace already is registered */ - def = TrioFindNamespace(name, &prev); - if (def) - return NULL; - } - - def = (trio_userdef_t *)TRIO_MALLOC(sizeof(trio_userdef_t)); - if (def) - { - if (internalEnterCriticalRegion) - (void)internalEnterCriticalRegion(NULL); - - if (name) - { - /* Link into internal list */ - if (prev == NULL) - internalUserDef = def; - else - prev->next = def; - } - /* Initialize */ - def->callback = callback; - def->name = (name == NULL) - ? NULL - : trio_duplicate(name); - def->next = NULL; - - if (internalLeaveCriticalRegion) - (void)internalLeaveCriticalRegion(NULL); - } - return (trio_pointer_t)def; -} - -/** - Unregister an existing user-defined specifier. - - @param handle - */ -void -trio_unregister -TRIO_ARGS1((handle), - trio_pointer_t handle) -{ - trio_userdef_t *self = (trio_userdef_t *)handle; - trio_userdef_t *def; - trio_userdef_t *prev = NULL; - - assert(VALID(self)); - - if (self->name) - { - def = TrioFindNamespace(self->name, &prev); - if (def) - { - if (internalEnterCriticalRegion) - (void)internalEnterCriticalRegion(NULL); - - if (prev == NULL) - internalUserDef = NULL; - else - prev->next = def->next; - - if (internalLeaveCriticalRegion) - (void)internalLeaveCriticalRegion(NULL); - } - trio_destroy(self->name); - } - TRIO_FREE(self); -} - -/************************************************************************* - * trio_get_format [public] - */ -TRIO_CONST char * -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); -} - -/************************************************************************* - * trio_get_argument [public] - */ -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; -} - -/************************************************************************* - * trio_get_width / trio_set_width [public] - */ -int -trio_get_width -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return ((trio_reference_t *)ref)->parameter->width; -} - -void -trio_set_width -TRIO_ARGS2((ref, width), - trio_pointer_t ref, - int width) -{ - ((trio_reference_t *)ref)->parameter->width = width; -} - -/************************************************************************* - * trio_get_precision / trio_set_precision [public] - */ -int -trio_get_precision -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->precision); -} - -void -trio_set_precision -TRIO_ARGS2((ref, precision), - trio_pointer_t ref, - int precision) -{ - ((trio_reference_t *)ref)->parameter->precision = precision; -} - -/************************************************************************* - * trio_get_base / trio_set_base [public] - */ -int -trio_get_base -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->base); -} - -void -trio_set_base -TRIO_ARGS2((ref, base), - trio_pointer_t ref, - int base) -{ - ((trio_reference_t *)ref)->parameter->base = base; -} - -/************************************************************************* - * trio_get_long / trio_set_long [public] - */ -int -trio_get_long -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONG); -} - -void -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; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LONG; -} - -/************************************************************************* - * trio_get_longlong / trio_set_longlong [public] - */ -int -trio_get_longlong -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUAD); -} - -void -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; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_QUAD; -} - -/************************************************************************* - * trio_get_longdouble / trio_set_longdouble [public] - */ -int -trio_get_longdouble -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONGDOUBLE); -} - -void -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; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LONGDOUBLE; -} - -/************************************************************************* - * trio_get_short / trio_set_short [public] - */ -int -trio_get_short -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORT); -} - -void -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; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHORT; -} - -/************************************************************************* - * trio_get_shortshort / trio_set_shortshort [public] - */ -int -trio_get_shortshort -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORTSHORT); -} - -void -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; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHORTSHORT; -} - -/************************************************************************* - * trio_get_alternative / trio_set_alternative [public] - */ -int -trio_get_alternative -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_ALTERNATIVE); -} - -void -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; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_ALTERNATIVE; -} - -/************************************************************************* - * trio_get_alignment / trio_set_alignment [public] - */ -int -trio_get_alignment -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LEFTADJUST); -} - -void -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; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LEFTADJUST; -} - -/************************************************************************* - * trio_get_spacing /trio_set_spacing [public] - */ -int -trio_get_spacing -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SPACE); -} - -void -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; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SPACE; -} - -/************************************************************************* - * trio_get_sign / trio_set_sign [public] - */ -int -trio_get_sign -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHOWSIGN); -} - -void -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; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHOWSIGN; -} - -/************************************************************************* - * trio_get_padding / trio_set_padding [public] - */ -int -trio_get_padding -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_NILPADDING); -} - -void -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; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_NILPADDING; -} - -/************************************************************************* - * trio_get_quote / trio_set_quote [public] - */ -int -trio_get_quote -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUOTE); -} - -void -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; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_QUOTE; -} - -/************************************************************************* - * trio_get_upper / trio_set_upper [public] - */ -int -trio_get_upper -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_UPPER); -} - -void -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; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_UPPER; -} - -/************************************************************************* - * trio_get_largest / trio_set_largest [public] - */ -#if TRIO_C99 -int -trio_get_largest -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_INTMAX_T); -} - -void -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; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_INTMAX_T; -} -#endif - -/************************************************************************* - * trio_get_ptrdiff / trio_set_ptrdiff [public] - */ -int -trio_get_ptrdiff -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_PTRDIFF_T); -} - -void -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; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_PTRDIFF_T; -} - -/************************************************************************* - * trio_get_size / trio_set_size [public] - */ -#if TRIO_C99 -int -trio_get_size -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SIZE_T); -} - -void -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; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SIZE_T; -} -#endif - -/************************************************************************* - * trio_print_int [public] - */ -void -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_uintmax_t)number, - self->parameter->flags, - self->parameter->width, - self->parameter->precision, - self->parameter->base); -} - -/************************************************************************* - * trio_print_uint [public] - */ -void -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_uintmax_t)number, - self->parameter->flags | FLAGS_UNSIGNED, - self->parameter->width, - self->parameter->precision, - self->parameter->base); -} - -/************************************************************************* - * trio_print_double [public] - */ -void -trio_print_double -TRIO_ARGS2((ref, number), - trio_pointer_t ref, - double number) -{ - trio_reference_t *self = (trio_reference_t *)ref; - - TrioWriteDouble(self->data, - number, - self->parameter->flags, - self->parameter->width, - self->parameter->precision, - self->parameter->base); -} - -/************************************************************************* - * trio_print_string [public] - */ -void -trio_print_string -TRIO_ARGS2((ref, string), - trio_pointer_t ref, - char *string) -{ - trio_reference_t *self = (trio_reference_t *)ref; - - TrioWriteString(self->data, - string, - self->parameter->flags, - self->parameter->width, - self->parameter->precision); -} - -/************************************************************************* - * 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 -TRIO_ARGS2((ref, pointer), - trio_pointer_t ref, - trio_pointer_t pointer) -{ - trio_reference_t *self = (trio_reference_t *)ref; - unsigned long flags; - trio_uintmax_t number; - - if (NULL == pointer) - { - TRIO_CONST char *string = internalNullString; - while (*string) - self->data->OutStream(self->data, *string++); - } - else - { - /* - * The subtraction of the null pointer is a workaround - * to avoid a compiler warning. The performance overhead - * is negligible (and likely to be removed by an - * optimizing compiler). The (char *) casting is done - * to please ANSI C++. - */ - number = (trio_uintmax_t)((char *)pointer - (char *)0); - /* Shrink to size of pointer */ - number &= (trio_uintmax_t)-1; - flags = self->parameter->flags; - flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE | - FLAGS_NILPADDING); - TrioWriteNumber(self->data, - number, - flags, - POINTER_WIDTH, - NO_PRECISION, - BASE_HEX); - } -} - -/** @} End of UserDefined documentation module */ - -/************************************************************************* - * - * 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. - */ -TRIO_PUBLIC void -trio_locale_set_decimal_point -TRIO_ARGS1((decimalPoint), - char *decimalPoint) -{ -#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_locale_set_thousand_separator - * - * See trio_locale_set_decimal_point - */ -TRIO_PUBLIC void -trio_locale_set_thousand_separator -TRIO_ARGS1((thousandSeparator), - char *thousandSeparator) -{ -#if defined(USE_LOCALE) - if (NULL == internalLocaleValues) - { - TrioSetLocale(); - } -#endif - trio_copy_max(internalThousandSeparator, - sizeof(internalThousandSeparator), - thousandSeparator); - internalThousandSeparatorLength = trio_length(internalThousandSeparator); -} - -/************************************************************************* - * 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. - */ -TRIO_PUBLIC void -trio_locale_set_grouping -TRIO_ARGS1((grouping), - char *grouping) -{ -#if defined(USE_LOCALE) - if (NULL == internalLocaleValues) - { - TrioSetLocale(); - } -#endif - trio_copy_max(internalGrouping, - sizeof(internalGrouping), - grouping); -} - - -/************************************************************************* - * - * SCANNING - * - ************************************************************************/ - -/************************************************************************* - * TrioSkipWhitespaces - */ -TRIO_PRIVATE int -TrioSkipWhitespaces -TRIO_ARGS1((self), - trio_class_t *self) -{ - int ch; - - ch = self->current; - while (isspace(ch)) - { - self->InStream(self, &ch); - } - return ch; -} - -/************************************************************************* - * TrioGetCollation - */ -#if TRIO_EXTENSION -TRIO_PRIVATE void -TrioGetCollation(TRIO_NOARGS) -{ - int i; - int j; - int k; - char first[2]; - char second[2]; - - /* This is computational expensive */ - first[1] = NIL; - second[1] = NIL; - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - { - k = 0; - first[0] = (char)i; - for (j = 0; j < MAX_CHARACTER_CLASS; j++) - { - second[0] = (char)j; - if (trio_equal_locale(first, second)) - internalCollationArray[i][k++] = (char)j; - } - internalCollationArray[i][k] = NIL; - } -} -#endif - -/************************************************************************* - * TrioGetCharacterClass - * - * FIXME: - * multibyte - */ -TRIO_PRIVATE int -TrioGetCharacterClass -TRIO_ARGS4((format, indexPointer, flagsPointer, characterclass), - TRIO_CONST char *format, - int *indexPointer, - unsigned long *flagsPointer, - int *characterclass) -{ - int index = *indexPointer; - int i; - char ch; - char range_begin; - char range_end; - - *flagsPointer &= ~FLAGS_EXCLUDE; - - if (format[index] == QUALIFIER_CIRCUMFLEX) - { - *flagsPointer |= FLAGS_EXCLUDE; - index++; - } - /* - * If the ungroup character is at the beginning of the scanlist, - * it will be part of the class, and a second ungroup character - * must follow to end the group. - */ - if (format[index] == SPECIFIER_UNGROUP) - { - characterclass[(int)SPECIFIER_UNGROUP]++; - index++; - } - /* - * Minus is used to specify ranges. To include minus in the class, - * it must be at the beginning of the list - */ - if (format[index] == QUALIFIER_MINUS) - { - characterclass[(int)QUALIFIER_MINUS]++; - index++; - } - /* Collect characters */ - for (ch = format[index]; - (ch != SPECIFIER_UNGROUP) && (ch != NIL); - ch = format[++index]) - { - switch (ch) - { - case QUALIFIER_MINUS: /* Scanlist ranges */ - - /* - * Both C99 and UNIX98 describes ranges as implementation- - * defined. - * - * We support the following behaviour (although this may - * change as we become wiser) - * - only increasing ranges, ie. [a-b] but not [b-a] - * - transitive ranges, ie. [a-b-c] == [a-c] - * - trailing minus, ie. [a-] is interpreted as an 'a' - * and a '-' - * - duplicates (although we can easily convert these - * into errors) - */ - range_begin = format[index - 1]; - range_end = format[++index]; - if (range_end == SPECIFIER_UNGROUP) - { - /* Trailing minus is included */ - characterclass[(int)ch]++; - ch = range_end; - break; /* for */ - } - if (range_end == NIL) - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - if (range_begin > range_end) - return TRIO_ERROR_RETURN(TRIO_ERANGE, index); - - for (i = (int)range_begin; i <= (int)range_end; i++) - characterclass[i]++; - - ch = range_end; - break; - -#if TRIO_EXTENSION - - case SPECIFIER_GROUP: - - switch (format[index + 1]) - { - case QUALIFIER_DOT: /* Collating symbol */ - /* - * FIXME: This will be easier to implement when multibyte - * characters have been implemented. Until now, we ignore - * this feature. - */ - for (i = index + 2; ; i++) - { - if (format[i] == NIL) - /* Error in syntax */ - return -1; - else if (format[i] == QUALIFIER_DOT) - break; /* for */ - } - if (format[++i] != SPECIFIER_UNGROUP) - return -1; - - index = i; - break; - - case QUALIFIER_EQUAL: /* Equivalence class expressions */ - { - unsigned int j; - unsigned int k; - - if (internalCollationUnconverted) - { - /* Lazy evaluation of collation array */ - TrioGetCollation(); - internalCollationUnconverted = FALSE; - } - for (i = index + 2; ; i++) - { - if (format[i] == NIL) - /* Error in syntax */ - return -1; - else if (format[i] == QUALIFIER_EQUAL) - break; /* for */ - else - { - /* Mark any equivalent character */ - k = (unsigned int)format[i]; - for (j = 0; internalCollationArray[k][j] != NIL; j++) - characterclass[(int)internalCollationArray[k][j]]++; - } - } - if (format[++i] != SPECIFIER_UNGROUP) - return -1; - - index = i; - } - break; - - case QUALIFIER_COLON: /* Character class expressions */ - - if (trio_equal_max(CLASS_ALNUM, sizeof(CLASS_ALNUM) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isalnum(i)) - characterclass[i]++; - index += sizeof(CLASS_ALNUM) - 1; - } - else if (trio_equal_max(CLASS_ALPHA, sizeof(CLASS_ALPHA) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isalpha(i)) - characterclass[i]++; - index += sizeof(CLASS_ALPHA) - 1; - } - else if (trio_equal_max(CLASS_CNTRL, sizeof(CLASS_CNTRL) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (iscntrl(i)) - characterclass[i]++; - index += sizeof(CLASS_CNTRL) - 1; - } - else if (trio_equal_max(CLASS_DIGIT, sizeof(CLASS_DIGIT) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isdigit(i)) - characterclass[i]++; - index += sizeof(CLASS_DIGIT) - 1; - } - else if (trio_equal_max(CLASS_GRAPH, sizeof(CLASS_GRAPH) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isgraph(i)) - characterclass[i]++; - index += sizeof(CLASS_GRAPH) - 1; - } - else if (trio_equal_max(CLASS_LOWER, sizeof(CLASS_LOWER) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (islower(i)) - characterclass[i]++; - index += sizeof(CLASS_LOWER) - 1; - } - else if (trio_equal_max(CLASS_PRINT, sizeof(CLASS_PRINT) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isprint(i)) - characterclass[i]++; - index += sizeof(CLASS_PRINT) - 1; - } - else if (trio_equal_max(CLASS_PUNCT, sizeof(CLASS_PUNCT) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (ispunct(i)) - characterclass[i]++; - index += sizeof(CLASS_PUNCT) - 1; - } - else if (trio_equal_max(CLASS_SPACE, sizeof(CLASS_SPACE) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isspace(i)) - characterclass[i]++; - index += sizeof(CLASS_SPACE) - 1; - } - else if (trio_equal_max(CLASS_UPPER, sizeof(CLASS_UPPER) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isupper(i)) - characterclass[i]++; - index += sizeof(CLASS_UPPER) - 1; - } - else if (trio_equal_max(CLASS_XDIGIT, sizeof(CLASS_XDIGIT) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isxdigit(i)) - characterclass[i]++; - index += sizeof(CLASS_XDIGIT) - 1; - } - else - { - characterclass[(int)ch]++; - } - break; - - default: - characterclass[(int)ch]++; - break; - } - break; - -#endif /* TRIO_EXTENSION */ - - default: - characterclass[(int)ch]++; - break; - } - } - return 0; -} - -/************************************************************************* - * TrioReadNumber - * - * We implement our own number conversion in preference of strtol and - * strtoul, because we must handle 'long long' and thousand separators. - */ -TRIO_PRIVATE BOOLEAN_T -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)); - assert(VALID(self->InStream)); - assert((base >= MIN_BASE && base <= MAX_BASE) || (base == NO_BASE)); - - if (internalDigitsUnconverted) - { - /* Lazy evaluation of digits array */ - memset(internalDigitArray, -1, sizeof(internalDigitArray)); - for (j = 0; j < (int)sizeof(internalDigitsLower) - 1; j++) - { - internalDigitArray[(int)internalDigitsLower[j]] = j; - internalDigitArray[(int)internalDigitsUpper[j]] = j; - } - internalDigitsUnconverted = FALSE; - } - - TrioSkipWhitespaces(self); - - if (!(flags & FLAGS_UNSIGNED)) - { - /* Leading sign */ - if (self->current == '+') - { - self->InStream(self, NULL); - } - else if (self->current == '-') - { - self->InStream(self, NULL); - isNegative = TRUE; - } - } - - count = self->processed; - - if (flags & FLAGS_ALTERNATIVE) - { - switch (base) - { - case NO_BASE: - case BASE_OCTAL: - case BASE_HEX: - case BASE_BINARY: - if (self->current == '0') - { - self->InStream(self, NULL); - if (self->current) - { - if ((base == BASE_HEX) && - (toupper(self->current) == 'X')) - { - self->InStream(self, NULL); - } - else if ((base == BASE_BINARY) && - (toupper(self->current) == 'B')) - { - self->InStream(self, NULL); - } - } - } - else - return FALSE; - break; - default: - break; - } - } - - while (((width == NO_WIDTH) || (self->processed - count < width)) && - (! ((self->current == EOF) || isspace(self->current)))) - { - if (isascii(self->current)) - { - digit = internalDigitArray[self->current]; - /* Abort if digit is not allowed in the specified base */ - if ((digit == -1) || (digit >= base)) - break; - } - else if (flags & FLAGS_QUOTE) - { - /* Compare with thousands separator */ - for (j = 0; internalThousandSeparator[j] && self->current; j++) - { - if (internalThousandSeparator[j] != self->current) - break; - - self->InStream(self, NULL); - } - if (internalThousandSeparator[j]) - break; /* Mismatch */ - else - continue; /* Match */ - } - else - break; - - number *= base; - number += digit; - gotNumber = TRUE; /* we need at least one digit */ - - self->InStream(self, NULL); - } - - /* Was anything read at all? */ - if (!gotNumber) - return FALSE; - - if (target) - *target = (isNegative) ? -((trio_intmax_t)number) : number; - return TRUE; -} - -/************************************************************************* - * TrioReadChar - */ -TRIO_PRIVATE int -TrioReadChar -TRIO_ARGS4((self, target, flags, width), - trio_class_t *self, - char *target, - unsigned long flags, - int width) -{ - int i; - char ch; - trio_uintmax_t number; - - assert(VALID(self)); - assert(VALID(self->InStream)); - - for (i = 0; - (self->current != EOF) && (i < width); - i++) - { - ch = (char)self->current; - self->InStream(self, NULL); - if ((flags & FLAGS_ALTERNATIVE) && (ch == CHAR_BACKSLASH)) - { - switch (self->current) - { - case '\\': ch = '\\'; break; - case 'a': ch = '\007'; break; - case 'b': ch = '\b'; break; - case 'f': ch = '\f'; break; - case 'n': ch = '\n'; break; - case 'r': ch = '\r'; break; - case 't': ch = '\t'; break; - case 'v': ch = '\v'; break; - default: - if (isdigit(self->current)) - { - /* Read octal number */ - if (!TrioReadNumber(self, &number, 0, 3, BASE_OCTAL)) - return 0; - ch = (char)number; - } - else if (toupper(self->current) == 'X') - { - /* Read hexadecimal number */ - self->InStream(self, NULL); - if (!TrioReadNumber(self, &number, 0, 2, BASE_HEX)) - return 0; - ch = (char)number; - } - else - { - ch = (char)self->current; - } - break; - } - } - - if (target) - target[i] = ch; - } - return i + 1; -} - -/************************************************************************* - * TrioReadString - */ -TRIO_PRIVATE BOOLEAN_T -TrioReadString -TRIO_ARGS4((self, target, flags, width), - trio_class_t *self, - char *target, - unsigned long flags, - int width) -{ - int i; - - assert(VALID(self)); - assert(VALID(self->InStream)); - - TrioSkipWhitespaces(self); - - /* - * Continue until end of string is reached, a whitespace is encountered, - * or width is exceeded - */ - for (i = 0; - ((width == NO_WIDTH) || (i < width)) && - (! ((self->current == EOF) || isspace(self->current))); - i++) - { - if (TrioReadChar(self, (target ? &target[i] : 0), flags, 1) == 0) - break; /* for */ - } - if (target) - target[i] = NIL; - return TRUE; -} - -/************************************************************************* - * TrioReadWideChar - */ -#if TRIO_WIDECHAR -TRIO_PRIVATE int -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; - trio_wchar_t wch; - char buffer[MB_LEN_MAX + 1]; - - assert(VALID(self)); - assert(VALID(self->InStream)); - - for (i = 0; - (self->current != EOF) && (i < width); - i++) - { - if (isascii(self->current)) - { - if (TrioReadChar(self, buffer, flags, 1) == 0) - return 0; - buffer[1] = NIL; - } - else - { - /* - * Collect a multibyte character, by enlarging buffer until - * it contains a fully legal multibyte character, or the - * buffer is full. - */ - j = 0; - do - { - buffer[j++] = (char)self->current; - buffer[j] = NIL; - self->InStream(self, NULL); - } - while ((j < (int)sizeof(buffer)) && (mblen(buffer, (size_t)j) != j)); - } - if (target) - { - size = mbtowc(&wch, buffer, sizeof(buffer)); - if (size > 0) - target[i] = wch; - } - amount += size; - self->InStream(self, NULL); - } - return amount; -} -#endif /* TRIO_WIDECHAR */ - -/************************************************************************* - * TrioReadWideString - */ -#if TRIO_WIDECHAR -TRIO_PRIVATE BOOLEAN_T -TrioReadWideString -TRIO_ARGS4((self, target, flags, width), - trio_class_t *self, - trio_wchar_t *target, - unsigned long flags, - int width) -{ - int i; - int size; - - assert(VALID(self)); - assert(VALID(self->InStream)); - - TrioSkipWhitespaces(self); - -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - (void)mblen(NULL, 0); -#endif - - /* - * Continue until end of string is reached, a whitespace is encountered, - * or width is exceeded - */ - for (i = 0; - ((width == NO_WIDTH) || (i < width)) && - (! ((self->current == EOF) || isspace(self->current))); - ) - { - size = TrioReadWideChar(self, &target[i], flags, 1); - if (size == 0) - break; /* for */ - - i += size; - } - if (target) - target[i] = WCONST('\0'); - return TRUE; -} -#endif /* TRIO_WIDECHAR */ - -/************************************************************************* - * TrioReadGroup - * - * FIXME: characterclass does not work with multibyte characters - */ -TRIO_PRIVATE BOOLEAN_T -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; - - assert(VALID(self)); - assert(VALID(self->InStream)); - - ch = self->current; - for (i = 0; - ((width == NO_WIDTH) || (i < width)) && - (! ((ch == EOF) || - (((flags & FLAGS_EXCLUDE) != 0) ^ (characterclass[ch] == 0)))); - i++) - { - if (target) - target[i] = (char)ch; - self->InStream(self, &ch); - } - - if (target) - target[i] = NIL; - return TRUE; -} - -/************************************************************************* - * TrioReadDouble - * - * FIXME: - * add long double - * handle base - */ -TRIO_PRIVATE BOOLEAN_T -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]; - 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; - - TrioSkipWhitespaces(self); - - /* - * Read entire double number from stream. trio_to_double requires - * a string as input, but InStream can be anything, so we have to - * collect all characters. - */ - ch = self->current; - if ((ch == '+') || (ch == '-')) - { - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - width--; - } - - start = index; - switch (ch) - { - case 'n': - case 'N': - /* Not-a-number */ - if (index != 0) - break; - /* FALLTHROUGH */ - case 'i': - case 'I': - /* Infinity */ - while (isalpha(ch) && (index - start < width)) - { - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - } - doubleString[index] = NIL; - - /* Case insensitive string comparison */ - if (trio_equal(&doubleString[start], INFINITE_UPPER) || - trio_equal(&doubleString[start], LONG_INFINITE_UPPER)) - { - 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 - */ - if (flags & FLAGS_LONGDOUBLE) - { - *((trio_long_double_t *)target) = trio_nan(); - } - else - { - *((double *)target) = trio_nan(); - } - return TRUE; - } - return FALSE; - - case '0': - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - if (toupper(ch) == 'X') - { - isHex = TRUE; - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - } - break; - - default: - break; - } - - while ((ch != EOF) && (index - start < width)) - { - /* Integer part */ - if (isHex ? isxdigit(ch) : isdigit(ch)) - { - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - } - else if (flags & FLAGS_QUOTE) - { - /* Compare with thousands separator */ - for (j = 0; internalThousandSeparator[j] && self->current; j++) - { - if (internalThousandSeparator[j] != self->current) - break; - - self->InStream(self, &ch); - } - if (internalThousandSeparator[j]) - break; /* Mismatch */ - else - continue; /* Match */ - } - else - break; /* while */ - } - if (ch == '.') - { - /* Decimal part */ - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - while ((isHex ? isxdigit(ch) : isdigit(ch)) && - (index - start < width)) - { - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - } - if (isHex ? (toupper(ch) == 'P') : (toupper(ch) == 'E')) - { - /* Exponent */ - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - if ((ch == '+') || (ch == '-')) - { - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - } - while ((isHex ? isxdigit(ch) : isdigit(ch)) && - (index - start < width)) - { - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - } - } - } - - if ((index == start) || (*doubleString == NIL)) - return FALSE; - - doubleString[index] = 0; - - if (flags & FLAGS_LONGDOUBLE) - { - *((trio_long_double_t *)target) = trio_to_long_double(doubleString, NULL); - } - else - { - *((double *)target) = trio_to_double(doubleString, NULL); - } - return TRUE; -} - -/************************************************************************* - * TrioReadPointer - */ -TRIO_PRIVATE BOOLEAN_T -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)]; - - flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE | FLAGS_NILPADDING); - - if (TrioReadNumber(self, - &number, - flags, - POINTER_WIDTH, - BASE_HEX)) - { - /* - * The strange assignment of number is a workaround for a compiler - * warning - */ - if (target) - *target = (char *)0 + number; - return TRUE; - } - else if (TrioReadString(self, - (flags & FLAGS_IGNORE) - ? NULL - : buffer, - 0, - sizeof(internalNullString) - 1)) - { - if (trio_equal_case(buffer, internalNullString)) - { - if (target) - *target = NULL; - return TRUE; - } - } - return FALSE; -} - -/************************************************************************* - * TrioScanProcess - */ -TRIO_PRIVATE int -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; - int cnt; -#endif - int assignment; - int ch; - int index; /* Index of format string */ - int i; /* Index of current parameter */ - unsigned long flags; - int width; - int base; - trio_pointer_t pointer; - - assignment = 0; - i = 0; - index = 0; - data->InStream(data, &ch); - -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - (void)mblen(NULL, 0); -#endif - - while (format[index]) - { -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - if (! isascii(format[index])) - { - charlen = mblen(&format[index], MB_LEN_MAX); - if (charlen != -1) - { - /* Compare multibyte characters in format string */ - for (cnt = 0; cnt < charlen - 1; cnt++) - { - if (ch != format[index + cnt]) - { - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - } - data->InStream(data, &ch); - } - continue; /* while characters left in formatting string */ - } - } -#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */ - - if ((EOF == ch) && (parameters[i].type != FORMAT_COUNT)) - { - return (assignment > 0) ? assignment : EOF; - } - - if (CHAR_IDENTIFIER == format[index]) - { - if (CHAR_IDENTIFIER == format[index + 1]) - { - /* Two % in format matches one % in input stream */ - if (CHAR_IDENTIFIER == ch) - { - data->InStream(data, &ch); - index += 2; - continue; /* while format chars left */ - } - else - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - } - - /* Skip the parameter entries */ - while (parameters[i].type == FORMAT_PARAMETER) - i++; - - flags = parameters[i].flags; - /* Find width */ - width = parameters[i].width; - if (flags & FLAGS_WIDTH_PARAMETER) - { - /* Get width from parameter list */ - width = (int)parameters[width].data.number.as_signed; - } - /* Find base */ - base = parameters[i].base; - if (flags & FLAGS_BASE_PARAMETER) - { - /* Get base from parameter list */ - base = (int)parameters[base].data.number.as_signed; - } - - switch (parameters[i].type) - { - case FORMAT_INT: - { - trio_uintmax_t number; - - if (0 == base) - base = BASE_DECIMAL; - - if (!TrioReadNumber(data, - &number, - flags, - width, - base)) - return 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) - *(size_t *)pointer = (size_t)number; - else -#endif -#if defined(QUALIFIER_PTRDIFF_T) - if (flags & FLAGS_PTRDIFF_T) - *(ptrdiff_t *)pointer = (ptrdiff_t)number; - else -#endif -#if defined(QUALIFIER_INTMAX_T) - if (flags & FLAGS_INTMAX_T) - *(trio_intmax_t *)pointer = (trio_intmax_t)number; - else -#endif - if (flags & FLAGS_QUAD) - *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)number; - else if (flags & FLAGS_LONG) - *(long int *)pointer = (long int)number; - else if (flags & FLAGS_SHORT) - *(short int *)pointer = (short int)number; - else - *(int *)pointer = (int)number; - } - } - break; /* FORMAT_INT */ - - case FORMAT_STRING: -#if TRIO_WIDECHAR - if (flags & FLAGS_WIDECHAR) - { - if (!TrioReadWideString(data, - (flags & FLAGS_IGNORE) - ? NULL - : parameters[i].data.wstring, - flags, - width)) - return assignment; - } - else -#endif - { - if (!TrioReadString(data, - (flags & FLAGS_IGNORE) - ? NULL - : parameters[i].data.string, - flags, - width)) - return assignment; - } - if (!(flags & FLAGS_IGNORE)) - assignment++; - break; /* FORMAT_STRING */ - - case 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]; - int rc; - - /* Skip over modifiers */ - while (format[index] != SPECIFIER_GROUP) - { - index++; - } - /* Skip over group specifier */ - index++; - - memset(characterclass, 0, sizeof(characterclass)); - rc = TrioGetCharacterClass(format, - &index, - &flags, - characterclass); - if (rc < 0) - return rc; - - if (!TrioReadGroup(data, - (flags & FLAGS_IGNORE) - ? NULL - : parameters[i].data.string, - characterclass, - flags, - parameters[i].width)) - return 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)count; - else -#endif -#if defined(QUALIFIER_PTRDIFF_T) - if (flags & FLAGS_PTRDIFF_T) - *(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)count; - else -#endif - if (flags & FLAGS_QUAD) - { - *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)count; - } - else if (flags & FLAGS_LONG) - { - *(long int *)pointer = (long int)count; - } - else if (flags & FLAGS_SHORT) - { - *(short int *)pointer = (short int)count; - } - else - { - *(int *)pointer = (int)count; - } - } - break; /* FORMAT_COUNT */ - - case FORMAT_CHAR: -#if TRIO_WIDECHAR - if (flags & FLAGS_WIDECHAR) - { - if (TrioReadWideChar(data, - (flags & FLAGS_IGNORE) - ? NULL - : parameters[i].data.wstring, - flags, - (width == NO_WIDTH) ? 1 : width) == 0) - return assignment; - } - else -#endif - { - if (TrioReadChar(data, - (flags & FLAGS_IGNORE) - ? NULL - : parameters[i].data.string, - flags, - (width == NO_WIDTH) ? 1 : width) == 0) - return assignment; - } - if (!(flags & FLAGS_IGNORE)) - assignment++; - break; /* FORMAT_CHAR */ - - case FORMAT_POINTER: - if (!TrioReadPointer(data, - (flags & FLAGS_IGNORE) - ? NULL - : (trio_pointer_t *)parameters[i].data.pointer, - flags)) - return assignment; - if (!(flags & FLAGS_IGNORE)) - assignment++; - break; /* FORMAT_POINTER */ - - case FORMAT_PARAMETER: - break; /* FORMAT_PARAMETER */ - - default: - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - } - ch = data->current; - index = parameters[i].indexAfterSpecifier; - i++; - } - else /* Not an % identifier */ - { - if (isspace((int)format[index])) - { - /* Whitespaces may match any amount of whitespaces */ - ch = TrioSkipWhitespaces(data); - } - else if (ch == format[index]) - { - data->InStream(data, &ch); - } - else - return assignment; - - index++; - } - } - return assignment; -} - -/************************************************************************* - * TrioScan - */ -TRIO_PRIVATE int -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]; - trio_class_t data; - - assert(VALID(InStream)); - assert(VALID(format)); - - memset(&data, 0, sizeof(data)); - data.InStream = InStream; - data.location = (trio_pointer_t)source; - data.max = sourceSize; - data.error = 0; - -#if defined(USE_LOCALE) - if (NULL == internalLocaleValues) - { - TrioSetLocale(); - } -#endif - - status = TrioParse(TYPE_SCAN, format, parameters, arglist, argarray); - if (status < 0) - return status; - - status = TrioScanProcess(&data, format, parameters); - if (data.error != 0) - { - status = data.error; - } - return status; -} - -/************************************************************************* - * TrioInStreamFile - */ -TRIO_PRIVATE void -TrioInStreamFile -TRIO_ARGS2((self, intPointer), - trio_class_t *self, - int *intPointer) -{ - FILE *file = (FILE *)self->location; - - assert(VALID(self)); - assert(VALID(file)); - - self->current = fgetc(file); - if (self->current == EOF) - { - self->error = (ferror(file)) - ? TRIO_ERROR_RETURN(TRIO_ERRNO, 0) - : TRIO_ERROR_RETURN(TRIO_EOF, 0); - } - else - { - self->processed++; - self->committed++; - } - - if (VALID(intPointer)) - { - *intPointer = self->current; - } -} - -/************************************************************************* - * TrioInStreamFileDescriptor - */ -TRIO_PRIVATE void -TrioInStreamFileDescriptor -TRIO_ARGS2((self, intPointer), - trio_class_t *self, - int *intPointer) -{ - int fd = *((int *)self->location); - int size; - unsigned char input; - - assert(VALID(self)); - - size = read(fd, &input, sizeof(char)); - if (size == -1) - { - self->error = TRIO_ERROR_RETURN(TRIO_ERRNO, 0); - self->current = EOF; - } - else - { - self->current = (size == 0) ? EOF : input; - } - 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)) - { - *intPointer = self->current; - } -} - -/************************************************************************* - * TrioInStreamString - */ -TRIO_PRIVATE void -TrioInStreamString -TRIO_ARGS2((self, intPointer), - trio_class_t *self, - int *intPointer) -{ - unsigned char **buffer; - - assert(VALID(self)); - assert(VALID(self->location)); - - buffer = (unsigned char **)self->location; - self->current = (*buffer)[0]; - if (self->current == NIL) - { - self->current = EOF; - } - else - { - (*buffer)++; - self->processed++; - self->committed++; - } - - if (VALID(intPointer)) - { - *intPointer = self->current; - } -} - -/************************************************************************* - * - * Formatted scanning functions - * - ************************************************************************/ - -#if defined(TRIO_DOCUMENTATION) -# include "doc/doc_scanf.h" -#endif -/** @addtogroup Scanf - @{ -*/ - -/************************************************************************* - * scanf - */ - -/** - Scan characters from standard input stream. - - @param format Formatting string. - @param ... Arguments. - @return Number of scanned characters. - */ -TRIO_PUBLIC int -trio_scanf -TRIO_VARGS2((format, va_alist), - TRIO_CONST char *format, - TRIO_VA_DECL) -{ - int status; - va_list args; - - assert(VALID(format)); - - 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_ARGS2((format, args), - TRIO_CONST char *format, - va_list args) -{ - assert(VALID(format)); - - return TrioScan((trio_pointer_t)stdin, 0, - TrioInStreamFile, - format, &args, NULL); -} - -TRIO_PUBLIC int -trio_scanfv -TRIO_ARGS2((format, args), - TRIO_CONST char *format, - trio_pointer_t *args) -{ - assert(VALID(format)); - - return TrioScan((trio_pointer_t)stdin, 0, - TrioInStreamFile, - format, NULL, args); -} - -/************************************************************************* - * fscanf - */ -TRIO_PUBLIC int -trio_fscanf -TRIO_VARGS3((file, format, va_alist), - FILE *file, - TRIO_CONST char *format, - TRIO_VA_DECL) -{ - int status; - va_list args; - - assert(VALID(file)); - assert(VALID(format)); - - 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 -TRIO_ARGS3((file, format, args), - FILE *file, - TRIO_CONST char *format, - va_list args) -{ - assert(VALID(file)); - assert(VALID(format)); - - return TrioScan((trio_pointer_t)file, 0, - TrioInStreamFile, - format, &args, NULL); -} - -TRIO_PUBLIC int -trio_fscanfv -TRIO_ARGS3((file, format, args), - FILE *file, - TRIO_CONST char *format, - trio_pointer_t *args) -{ - assert(VALID(file)); - assert(VALID(format)); - - return TrioScan((trio_pointer_t)file, 0, - TrioInStreamFile, - format, NULL, args); -} - -/************************************************************************* - * dscanf - */ -TRIO_PUBLIC int -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)); - - 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 -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)); - - 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_vcscanf -TRIO_ARGS4((stream, closure, format, args), - trio_instream_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.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; - - 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_VARGS3((buffer, format, va_alist), - TRIO_CONST char *buffer, - TRIO_CONST char *format, - TRIO_VA_DECL) -{ - int status; - va_list args; - - assert(VALID(buffer)); - assert(VALID(format)); - - 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_ARGS3((buffer, format, args), - TRIO_CONST char *buffer, - TRIO_CONST char *format, - va_list args) -{ - assert(VALID(buffer)); - assert(VALID(format)); - - return TrioScan((trio_pointer_t)&buffer, 0, - TrioInStreamString, - format, &args, NULL); -} - -TRIO_PUBLIC int -trio_sscanfv -TRIO_ARGS3((buffer, format, args), - TRIO_CONST char *buffer, - TRIO_CONST char *format, - trio_pointer_t *args) -{ - assert(VALID(buffer)); - assert(VALID(format)); - - 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/glib/trio/trio.h b/glib/trio/trio.h deleted file mode 100644 index 770c6a6..0000000 --- a/glib/trio/trio.h +++ /dev/null @@ -1,216 +0,0 @@ -/************************************************************************* - * - * $Id$ - * - * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************* - * - * http://ctrio.sourceforge.net/ - * - ************************************************************************/ - -#ifndef TRIO_TRIO_H -#define TRIO_TRIO_H - -#include -#include -#if defined(TRIO_COMPILER_ANCIENT) -# include -#else -# include -#endif - -#if !defined(WITHOUT_TRIO) - -/* - * Use autoconf defines if present. Packages using trio must define - * HAVE_CONFIG_H as a compiler option themselves. - */ -#if defined(HAVE_CONFIG_H) -# include -#endif - -#include "triodef.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Error codes. - * - * Remember to add a textual description to trio_strerror. - */ -enum { - TRIO_EOF = 1, - TRIO_EINVAL = 2, - TRIO_ETOOMANY = 3, - TRIO_EDBLREF = 4, - TRIO_EGAP = 5, - TRIO_ENOMEM = 6, - TRIO_ERANGE = 7, - TRIO_ERRNO = 8, - TRIO_ECUSTOM = 9 -}; - -/* 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 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 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 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)); - -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 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 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 TRIO_PROTO((TRIO_CONST char *format, ...)); -char *trio_vaprintf TRIO_PROTO((TRIO_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 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_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_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 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 - */ -#ifdef TRIO_REPLACE_STDIO -/* Replace the functions */ -#ifndef HAVE_PRINTF -# define printf trio_printf -#endif -#ifndef HAVE_VPRINTF -# define vprintf trio_vprintf -#endif -#ifndef HAVE_FPRINTF -# define fprintf trio_fprintf -#endif -#ifndef HAVE_VFPRINTF -# define vfprintf trio_vfprintf -#endif -#ifndef HAVE_SPRINTF -# define sprintf trio_sprintf -#endif -#ifndef HAVE_VSPRINTF -# define vsprintf trio_vsprintf -#endif -#ifndef HAVE_SNPRINTF -# define snprintf trio_snprintf -#endif -#ifndef HAVE_VSNPRINTF -# define vsnprintf trio_vsnprintf -#endif -#ifndef HAVE_SCANF -# define scanf trio_scanf -#endif -#ifndef HAVE_VSCANF -# define vscanf trio_vscanf -#endif -#ifndef HAVE_FSCANF -# define fscanf trio_fscanf -#endif -#ifndef HAVE_VFSCANF -# define vfscanf trio_vfscanf -#endif -#ifndef HAVE_SSCANF -# define sscanf trio_sscanf -#endif -#ifndef HAVE_VSSCANF -# define vsscanf trio_vsscanf -#endif -/* These aren't stdio functions, but we make them look similar */ -#define dprintf trio_dprintf -#define vdprintf trio_vdprintf -#define aprintf trio_aprintf -#define vaprintf trio_vaprintf -#define asprintf trio_asprintf -#define vasprintf trio_vasprintf -#define dscanf trio_dscanf -#define vdscanf trio_vdscanf -#endif - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* WITHOUT_TRIO */ - -#endif /* TRIO_TRIO_H */ diff --git a/glib/trio/triodef.h b/glib/trio/triodef.h deleted file mode 100644 index f95b631..0000000 --- a/glib/trio/triodef.h +++ /dev/null @@ -1,206 +0,0 @@ -/************************************************************************* - * - * $Id$ - * - * Copyright (C) 2001 Bjorn Reese - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************/ - -#ifndef TRIO_TRIODEF_H -#define TRIO_TRIODEF_H - -/************************************************************************* - * Platform and compiler support detection - */ -#if defined(__GNUC__) -# define TRIO_COMPILER_GCC -#elif defined(__SUNPRO_C) -# define TRIO_COMPILER_SUNPRO -#elif defined(__SUNPRO_CC) -# define TRIO_COMPILER_SUNPRO -# define __SUNPRO_C __SUNPRO_CC -#elif defined(__xlC__) || defined(__IBMC__) || defined(__IBMCPP__) -# define TRIO_COMPILER_XLC -#elif defined(_AIX) && !defined(__GNUC__) -# 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(VMS) || defined(__VMS) -/* - * VMS is placed first to avoid identifying the platform as Unix - * based on the DECC compiler later on. - */ -# define TRIO_PLATFORM_VMS -#elif defined(unix) || defined(__unix) || defined(__unix__) -# define TRIO_PLATFORM_UNIX -#elif defined(TRIO_COMPILER_XLC) || defined(_AIX) -# define TRIO_PLATFORM_UNIX -#elif defined(TRIO_COMPILER_DECC) || defined(__osf___) -# define TRIO_PLATFORM_UNIX -#elif defined(__NetBSD__) -# define TRIO_PLATFORM_UNIX -#elif defined(__QNX__) -# define TRIO_PLATFORM_UNIX -# define TRIO_PLATFORM_QNX -#elif defined(__CYGWIN__) -# define TRIO_PLATFORM_UNIX -#elif defined(AMIGA) && defined(TRIO_COMPILER_GCC) -# define TRIO_PLATFORM_UNIX -#elif defined(TRIO_COMPILER_MSVC) || defined(WIN32) || defined(_WIN32) -# define TRIO_PLATFORM_WIN32 -#elif defined(mpeix) || defined(__mpexl) -# define TRIO_PLATFORM_MPEIX -#endif - -#if defined(_AIX) -# define TRIO_PLATFORM_AIX -#elif defined(__hpux) -# define TRIO_PLATFORM_HPUX -#endif - -#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 -# if (__STDC_VERSION__ >= 199901L) -# define TRIO_COMPILER_SUPPORTS_C99 -# endif -# elif defined(TRIO_COMPILER_SUNPRO) -# if (__SUNPRO_C >= 0x420) -# define TRIO_COMPILER_SUPPORTS_C94 -# endif -# endif -#endif - -#if defined(_XOPEN_SOURCE) -# if defined(_XOPEN_SOURCE_EXTENDED) -# define TRIO_COMPILER_SUPPORTS_UNIX95 -# endif -# if (_XOPEN_VERSION >= 500) -# define TRIO_COMPILER_SUPPORTS_UNIX98 -# endif -# if (_XOPEN_VERSION >= 600) -# define TRIO_COMPILER_SUPPORTS_UNIX01 -# endif -#endif - -/************************************************************************* - * Generic defines - */ - -#if !defined(TRIO_PUBLIC) -# define TRIO_PUBLIC -#endif -#if !defined(TRIO_PRIVATE) -# define TRIO_PRIVATE static -#endif - -#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_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 - -/************************************************************************* - * Workarounds - */ - -#if defined(TRIO_PLATFORM_VMS) -/* - * Computations done with constants at compile time can trigger these - * even when compiling with IEEE enabled. - */ -# pragma message disable (UNDERFLOW, FLOATOVERFL) - -# if (__CRTL_VER > 80000000) -/* - * Although the compiler supports C99 language constructs, the C - * run-time library does not contain all C99 functions. - * - * This was the case for 70300022. Update the 80000000 value when - * it has been accurately determined what version of the library - * supports C99. - */ -# if defined(TRIO_COMPILER_SUPPORTS_C99) -# undef TRIO_COMPILER_SUPPORTS_C99 -# endif -# endif -#endif - -#endif /* TRIO_TRIODEF_H */ diff --git a/glib/trio/trionan.c b/glib/trio/trionan.c deleted file mode 100644 index 90f1ae5..0000000 --- a/glib/trio/trionan.c +++ /dev/null @@ -1,926 +0,0 @@ -/************************************************************************* - * - * $Id$ - * - * Copyright (C) 2001 Bjorn Reese - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************ - * - * Functions to handle special quantities in floating-point numbers - * (that is, NaNs and infinity). They provide the capability to detect - * and fabricate special quantities. - * - * Although written to be as portable as possible, it can never be - * guaranteed to work on all platforms, as not all hardware supports - * special quantities. - * - * The approach used here (approximately) is to: - * - * 1. Use C99 functionality when available. - * 2. Use IEEE 754 bit-patterns if possible. - * 3. Use platform-specific techniques. - * - ************************************************************************/ - -/* - * TODO: - * o Put all the magic into trio_fpclassify_and_signbit(), and use this from - * trio_isnan() etc. - */ - -/************************************************************************* - * Include files - */ -#include "glibtrio.h" -#include "triodef.h" -#include "trionan.h" - -#include -#include -#include -#include -#if defined(TRIO_PLATFORM_UNIX) -# include -#endif -#if defined(TRIO_COMPILER_DECC) -# include -#endif -#include - -#if defined(TRIO_DOCUMENTATION) -# include "doc/doc_nan.h" -#endif -/** @addtogroup SpecialQuantities - @{ -*/ - -/************************************************************************* - * Definitions - */ - -#define TRIO_TRUE (1 == 1) -#define TRIO_FALSE (0 == 1) - -/* We must enable IEEE floating-point on Alpha */ -#if defined(__alpha) && !defined(_IEEE_FP) -# if defined(TRIO_COMPILER_DECC) -# if defined(TRIO_PLATFORM_VMS) -# error "Must be compiled with option /IEEE_MODE=UNDERFLOW_TO_ZERO/FLOAT=IEEE" -# else -# 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" -# endif -#endif /* __alpha && ! _IEEE_FP */ - -/* - * In ANSI/IEEE 754-1985 64-bits double format numbers have the - * following properties (amoungst others) - * - * o FLT_RADIX == 2: binary encoding - * o DBL_MAX_EXP == 1024: 11 bits exponent, where one bit is used - * to indicate special numbers (e.g. NaN and Infinity), so the - * maximum exponent is 10 bits wide (2^10 == 1024). - * o DBL_MANT_DIG == 53: The mantissa is 52 bits wide, but because - * numbers are normalized the initial binary 1 is represented - * implicitly (the so-called "hidden bit"), which leaves us with - * the ability to represent 53 bits wide mantissa. - */ -#if (FLT_RADIX == 2) && (DBL_MAX_EXP == 1024) && (DBL_MANT_DIG == 53) -# define USE_IEEE_754 -#endif - - -/************************************************************************* - * Constants - */ - -static TRIO_CONST char rcsid[] = "@(#)$Id$"; - -#if defined(USE_IEEE_754) - -/* - * Endian-agnostic indexing macro. - * - * The value of internalEndianMagic, when converted into a 64-bit - * integer, becomes 0x0706050403020100 (we could have used a 64-bit - * integer value instead of a double, but not all platforms supports - * that type). The value is automatically encoded with the correct - * endianess by the compiler, which means that we can support any - * kind of endianess. The individual bytes are then used as an index - * for the IEEE 754 bit-patterns and masks. - */ -#define TRIO_DOUBLE_INDEX(x) (((unsigned char *)&internalEndianMagic)[7-(x)]) - -static TRIO_CONST double internalEndianMagic = 7.949928895127363e-275; - -/* Mask for the exponent */ -static TRIO_CONST unsigned char ieee_754_exponent_mask[] = { - 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -/* Mask for the mantissa */ -static TRIO_CONST unsigned char ieee_754_mantissa_mask[] = { - 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF -}; - -/* Mask for the sign bit */ -static TRIO_CONST unsigned char ieee_754_sign_mask[] = { - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -/* Bit-pattern for negative zero */ -static TRIO_CONST unsigned char ieee_754_negzero_array[] = { - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -/* Bit-pattern for infinity */ -static TRIO_CONST unsigned char ieee_754_infinity_array[] = { - 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -/* Bit-pattern for quiet NaN */ -static TRIO_CONST unsigned char ieee_754_qnan_array[] = { - 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - - -/************************************************************************* - * Functions - */ - -/* - * trio_make_double - */ -TRIO_PRIVATE double -trio_make_double -TRIO_ARGS1((values), - TRIO_CONST unsigned char *values) -{ - TRIO_VOLATILE double result; - int i; - - for (i = 0; i < (int)sizeof(double); i++) { - ((TRIO_VOLATILE unsigned char *)&result)[TRIO_DOUBLE_INDEX(i)] = values[i]; - } - return result; -} - -/* - * trio_is_special_quantity - */ -TRIO_PRIVATE int -trio_is_special_quantity -TRIO_ARGS2((number, has_mantissa), - double number, - int *has_mantissa) -{ - unsigned int i; - unsigned char current; - int is_special_quantity = TRIO_TRUE; - - *has_mantissa = 0; - - for (i = 0; i < (unsigned int)sizeof(double); i++) { - current = ((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)]; - is_special_quantity - &= ((current & ieee_754_exponent_mask[i]) == ieee_754_exponent_mask[i]); - *has_mantissa |= (current & ieee_754_mantissa_mask[i]); - } - return is_special_quantity; -} - -/* - * trio_is_negative - */ -TRIO_PRIVATE int -trio_is_negative -TRIO_ARGS1((number), - double number) -{ - unsigned int i; - int is_negative = TRIO_FALSE; - - for (i = 0; i < (unsigned int)sizeof(double); i++) { - is_negative |= (((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)] - & ieee_754_sign_mask[i]); - } - return is_negative; -} - -#endif /* USE_IEEE_754 */ - - -/** - Generate negative zero. - - @return Floating-point representation of negative zero. -*/ -TRIO_PUBLIC double -trio_nzero(TRIO_NOARGS) -{ -#if defined(USE_IEEE_754) - return trio_make_double(ieee_754_negzero_array); -#else - TRIO_VOLATILE double zero = 0.0; - - return -zero; -#endif -} - -/** - Generate positive infinity. - - @return Floating-point representation of positive infinity. -*/ -TRIO_PUBLIC double -trio_pinf(TRIO_NOARGS) -{ - /* Cache the result */ - static double result = 0.0; - - if (result == 0.0) { - -#if defined(INFINITY) && defined(__STDC_IEC_559__) - result = (double)INFINITY; - -#elif defined(USE_IEEE_754) - result = trio_make_double(ieee_754_infinity_array); - -#else - /* - * If HUGE_VAL is different from DBL_MAX, then HUGE_VAL is used - * as infinity. Otherwise we have to resort to an overflow - * operation to generate infinity. - */ -# if defined(TRIO_PLATFORM_UNIX) - void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN); -# endif - - result = HUGE_VAL; - if (HUGE_VAL == DBL_MAX) { - /* Force overflow */ - result += HUGE_VAL; - } - -# if defined(TRIO_PLATFORM_UNIX) - signal(SIGFPE, signal_handler); -# endif - -#endif - } - return result; -} - -/** - Generate negative infinity. - - @return Floating-point value of negative infinity. -*/ -TRIO_PUBLIC double -trio_ninf(TRIO_NOARGS) -{ - static double result = 0.0; - - if (result == 0.0) { - /* - * Negative infinity is calculated by negating positive infinity, - * which can be done because it is legal to do calculations on - * infinity (for example, 1 / infinity == 0). - */ - result = -trio_pinf(); - } - return result; -} - -/** - Generate NaN. - - @return Floating-point representation of NaN. -*/ -TRIO_PUBLIC double -trio_nan(TRIO_NOARGS) -{ - /* Cache the result */ - static double result = 0.0; - - if (result == 0.0) { - -#if defined(TRIO_COMPILER_SUPPORTS_C99) - result = nan(""); - -#elif defined(NAN) && defined(__STDC_IEC_559__) - result = (double)NAN; - -#elif defined(USE_IEEE_754) - result = trio_make_double(ieee_754_qnan_array); - -#else - /* - * There are several ways to generate NaN. The one used here is - * to divide infinity by infinity. I would have preferred to add - * negative infinity to positive infinity, but that yields wrong - * result (infinity) on FreeBSD. - * - * This may fail if the hardware does not support NaN, or if - * the Invalid Operation floating-point exception is unmasked. - */ -# if defined(TRIO_PLATFORM_UNIX) - void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN); -# endif - - result = trio_pinf() / trio_pinf(); - -# if defined(TRIO_PLATFORM_UNIX) - signal(SIGFPE, signal_handler); -# endif - -#endif - } - return result; -} - -/** - Check for NaN. - - @param number An arbitrary floating-point number. - @return Boolean value indicating whether or not the number is a NaN. -*/ -TRIO_PUBLIC int -trio_isnan -TRIO_ARGS1((number), - double number) -{ -#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 - * is a bit tricky to detect with compiler defines, so we choose - * the conservative approach and only use it for UNIX95. - */ - return isnan(number); - -#elif defined(TRIO_COMPILER_MSVC) - /* - * MSVC has an _isnan() function - */ - return _isnan(number); - -#elif defined(USE_IEEE_754) - /* - * Examine IEEE 754 bit-pattern. A NaN must have a special exponent - * pattern, and a non-empty mantissa. - */ - int has_mantissa; - int is_special_quantity; - - is_special_quantity = trio_is_special_quantity(number, &has_mantissa); - - return (is_special_quantity && has_mantissa); - -#else - /* - * Fallback solution - */ - int status; - double integral, fraction; - -# if defined(TRIO_PLATFORM_UNIX) - void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN); -# endif - - status = (/* - * NaN is the only number which does not compare to itself - */ - ((TRIO_VOLATILE double)number != (TRIO_VOLATILE double)number) || - /* - * Fallback solution if NaN compares to NaN - */ - ((number != 0.0) && - (fraction = modf(number, &integral), - integral == fraction))); - -# if defined(TRIO_PLATFORM_UNIX) - signal(SIGFPE, signal_handler); -# endif - - return status; - -#endif -} - -/** - Check for infinity. - - @param number An arbitrary floating-point number. - @return 1 if positive infinity, -1 if negative infinity, 0 otherwise. -*/ -TRIO_PUBLIC int -trio_isinf -TRIO_ARGS1((number), - double number) -{ -#if defined(TRIO_COMPILER_DECC) - /* - * DECC has an isinf() macro, but it works differently than that - * of C99, so we use the fp_class() function instead. - */ - 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) - ? ((number > 0.0) ? 1 : -1) - : 0; - -#elif defined(TRIO_COMPILER_MSVC) - /* - * MSVC has an _fpclass() function that can be used to detect infinity. - */ - return ((_fpclass(number) == _FPCLASS_PINF) - ? 1 - : ((_fpclass(number) == _FPCLASS_NINF) ? -1 : 0)); - -#elif defined(USE_IEEE_754) - /* - * Examine IEEE 754 bit-pattern. Infinity must have a special exponent - * pattern, and an empty mantissa. - */ - int has_mantissa; - int is_special_quantity; - - is_special_quantity = trio_is_special_quantity(number, &has_mantissa); - - return (is_special_quantity && !has_mantissa) - ? ((number < 0.0) ? -1 : 1) - : 0; - -#else - /* - * Fallback solution. - */ - int status; - -# if defined(TRIO_PLATFORM_UNIX) - void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN); -# endif - - double infinity = trio_pinf(); - - status = ((number == infinity) - ? 1 - : ((number == -infinity) ? -1 : 0)); - -# if defined(TRIO_PLATFORM_UNIX) - signal(SIGFPE, signal_handler); -# endif - - return status; - -#endif -} - - -/** - Check for finity. - - @param number An arbitrary floating-point number. - @return Boolean value indicating whether or not the number is a finite. -*/ -TRIO_PUBLIC int -trio_isfinite -TRIO_ARGS1((number), - double number) -{ -#if defined(TRIO_COMPILER_SUPPORTS_C99) && defined(isfinite) - /* - * C99 defines isfinite() as a macro. - */ - return isfinite(number); - -#elif defined(TRIO_COMPILER_MSVC) - /* - * MSVC uses _finite(). - */ - return _finite(number); - -#elif defined(USE_IEEE_754) - /* - * Examine IEEE 754 bit-pattern. For finity we do not care about the - * mantissa. - */ - int dummy; - - return (! trio_is_special_quantity(number, &dummy)); - -#else - /* - * Fallback solution. - */ - return ((trio_isinf(number) == 0) && (trio_isnan(number) == 0)); - -#endif -} - -/* - * The sign of NaN is always false - */ -TRIO_PUBLIC int -trio_fpclassify_and_signbit -TRIO_ARGS2((number, is_negative), - double number, - int *is_negative) -{ -#if defined(fpclassify) && defined(signbit) - /* - * C99 defines fpclassify() and signbit() as a macros - */ - *is_negative = signbit(number); - switch (fpclassify(number)) { - case FP_NAN: - return TRIO_FP_NAN; - case FP_INFINITE: - return TRIO_FP_INFINITE; - case FP_SUBNORMAL: - return TRIO_FP_SUBNORMAL; - case FP_ZERO: - return TRIO_FP_ZERO; - default: - return TRIO_FP_NORMAL; - } - -#elif defined(TRIO_COMPILER_DECC) - /* - * DECC has an fp_class() function. - */ - switch (fp_class(number)) { - case FP_QNAN: - case FP_SNAN: - *is_negative = TRIO_FALSE; /* NaN has no sign */ - return TRIO_FP_NAN; - case FP_POS_INF: - *is_negative = TRIO_FALSE; - return TRIO_FP_INFINITE; - case FP_NEG_INF: - *is_negative = TRIO_TRUE; - return TRIO_FP_INFINITE; - case FP_POS_DENORM: - *is_negative = TRIO_FALSE; - return TRIO_FP_SUBNORMAL; - case FP_NEG_DENORM: - *is_negative = TRIO_TRUE; - return TRIO_FP_SUBNORMAL; - case FP_POS_ZERO: - *is_negative = TRIO_FALSE; - return TRIO_FP_ZERO; - case FP_NEG_ZERO: - *is_negative = TRIO_TRUE; - return TRIO_FP_ZERO; - case FP_POS_NORM: - *is_negative = TRIO_FALSE; - return TRIO_FP_NORMAL; - case FP_NEG_NORM: - *is_negative = TRIO_TRUE; - return TRIO_FP_NORMAL; - default: - /* Just in case... */ - *is_negative = (number < 0.0); - return TRIO_FP_NORMAL; - } - -#elif defined(TRIO_COMPILER_MSVC) - /* - * MSVC has an _fpclass() function. - */ - switch (_fpclass(number)) { - case _FPCLASS_QNAN: - case _FPCLASS_SNAN: - *is_negative = TRIO_FALSE; - return TRIO_FP_NAN; - case _FPCLASS_PINF: - *is_negative = TRIO_FALSE; - return TRIO_FP_INFINITE; - case _FPCLASS_NINF: - *is_negative = TRIO_TRUE; - return TRIO_FP_INFINITE; - case _FPCLASS_PD: - *is_negative = TRIO_FALSE; - return TRIO_FP_SUBNORMAL; - case _FPCLASS_ND: - *is_negative = TRIO_TRUE; - return TRIO_FP_SUBNORMAL; - case _FPCLASS_PZ: - *is_negative = TRIO_FALSE; - return TRIO_FP_ZERO; - case _FPCLASS_NZ: - *is_negative = TRIO_TRUE; - return TRIO_FP_ZERO; - case _FPCLASS_PN: - *is_negative = TRIO_FALSE; - return TRIO_FP_NORMAL; - case _FPCLASS_NN: - *is_negative = TRIO_TRUE; - return TRIO_FP_NORMAL; - default: - /* Just in case... */ - *is_negative = (number < 0.0); - return TRIO_FP_NORMAL; - } - -#elif defined(FP_PLUS_NORM) - - /* - * 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. - * - * AIX has class() for C, and _class() for C++, which returns the - * same values as the HP-UX fpclassify() function. - */ - -# if defined(TRIO_PLATFORM_AIX) -# if defined(__cplusplus) -# define fpclassify(x) _class(x) -# else -# define fpclassify(x) class(x) -# endif -# endif - - 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. - */ - int rc; - - if (number == 0.0) { - /* - * In IEEE 754 the sign of zero is ignored in comparisons, so we - * have to handle this as a special case by examining the sign bit - * directly. - */ -#if defined(USE_IEEE_754) - *is_negative = trio_is_negative(number); -#else - *is_negative = TRIO_FALSE; /* FIXME */ -#endif - return TRIO_FP_ZERO; - } - if (trio_isnan(number)) { - *is_negative = TRIO_FALSE; - return TRIO_FP_NAN; - } - if ((rc = trio_isinf(number))) { - *is_negative = (rc == -1); - return TRIO_FP_INFINITE; - } - if ((number > 0.0) && (number < DBL_MIN)) { - *is_negative = TRIO_FALSE; - return TRIO_FP_SUBNORMAL; - } - if ((number < 0.0) && (number > -DBL_MIN)) { - *is_negative = TRIO_TRUE; - return TRIO_FP_SUBNORMAL; - } - *is_negative = (number < 0.0); - return TRIO_FP_NORMAL; - -#endif -} - -/** - Examine the sign of a number. - - @param number An arbitrary floating-point number. - @return Boolean value indicating whether or not the number has the - sign bit set (i.e. is negative). -*/ -TRIO_PUBLIC int -trio_signbit -TRIO_ARGS1((number), - double number) -{ - int is_negative; - - (void)trio_fpclassify_and_signbit(number, &is_negative); - return is_negative; -} - -/** - Examine the class of a number. - - @param number An arbitrary floating-point number. - @return Enumerable value indicating the class of @p number -*/ -TRIO_PUBLIC int -trio_fpclassify -TRIO_ARGS1((number), - double number) -{ - int dummy; - - return trio_fpclassify_and_signbit(number, &dummy); -} - - -/** @} SpecialQuantities */ - -/************************************************************************* - * For test purposes. - * - * Add the following compiler option to include this test code. - * - * Unix : -DSTANDALONE - * VMS : /DEFINE=(STANDALONE) - */ -#if defined(STANDALONE) -# include - -static TRIO_CONST char * -getClassification -TRIO_ARGS1((type), - int type) -{ - switch (type) { - case TRIO_FP_INFINITE: - return "FP_INFINITE"; - case TRIO_FP_NAN: - return "FP_NAN"; - case TRIO_FP_NORMAL: - return "FP_NORMAL"; - case TRIO_FP_SUBNORMAL: - return "FP_SUBNORMAL"; - case TRIO_FP_ZERO: - return "FP_ZERO"; - default: - return "FP_UNKNOWN"; - } -} - -static void -print_class -TRIO_ARGS2((prefix, number), - TRIO_CONST char *prefix, - double number) -{ - printf("%-6s: %s %-15s %g\n", - prefix, - trio_signbit(number) ? "-" : "+", - getClassification(trio_fpclassify(number)), - number); -} - -int main(TRIO_NOARGS) -{ - double my_nan; - double my_pinf; - double my_ninf; -# if defined(TRIO_PLATFORM_UNIX) - void (*signal_handler) TRIO_PROTO((int)); -# endif - - my_nan = trio_nan(); - my_pinf = trio_pinf(); - my_ninf = trio_ninf(); - - print_class("Nan", my_nan); - print_class("PInf", my_pinf); - print_class("NInf", my_ninf); - print_class("PZero", 0.0); - print_class("NZero", -0.0); - print_class("PNorm", 1.0); - print_class("NNorm", -1.0); - print_class("PSub", 1.01e-307 - 1.00e-307); - print_class("NSub", 1.00e-307 - 1.01e-307); - - printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n", - my_nan, - ((unsigned char *)&my_nan)[0], - ((unsigned char *)&my_nan)[1], - ((unsigned char *)&my_nan)[2], - ((unsigned char *)&my_nan)[3], - ((unsigned char *)&my_nan)[4], - ((unsigned char *)&my_nan)[5], - ((unsigned char *)&my_nan)[6], - ((unsigned char *)&my_nan)[7], - trio_isnan(my_nan), trio_isinf(my_nan)); - printf("PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n", - my_pinf, - ((unsigned char *)&my_pinf)[0], - ((unsigned char *)&my_pinf)[1], - ((unsigned char *)&my_pinf)[2], - ((unsigned char *)&my_pinf)[3], - ((unsigned char *)&my_pinf)[4], - ((unsigned char *)&my_pinf)[5], - ((unsigned char *)&my_pinf)[6], - ((unsigned char *)&my_pinf)[7], - trio_isnan(my_pinf), trio_isinf(my_pinf)); - printf("NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n", - my_ninf, - ((unsigned char *)&my_ninf)[0], - ((unsigned char *)&my_ninf)[1], - ((unsigned char *)&my_ninf)[2], - ((unsigned char *)&my_ninf)[3], - ((unsigned char *)&my_ninf)[4], - ((unsigned char *)&my_ninf)[5], - ((unsigned char *)&my_ninf)[6], - ((unsigned char *)&my_ninf)[7], - trio_isnan(my_ninf), trio_isinf(my_ninf)); - -# if defined(TRIO_PLATFORM_UNIX) - signal_handler = signal(SIGFPE, SIG_IGN); -# endif - - my_pinf = DBL_MAX + DBL_MAX; - my_ninf = -my_pinf; - my_nan = my_pinf / my_pinf; - -# if defined(TRIO_PLATFORM_UNIX) - signal(SIGFPE, signal_handler); -# endif - - printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n", - my_nan, - ((unsigned char *)&my_nan)[0], - ((unsigned char *)&my_nan)[1], - ((unsigned char *)&my_nan)[2], - ((unsigned char *)&my_nan)[3], - ((unsigned char *)&my_nan)[4], - ((unsigned char *)&my_nan)[5], - ((unsigned char *)&my_nan)[6], - ((unsigned char *)&my_nan)[7], - trio_isnan(my_nan), trio_isinf(my_nan)); - printf("PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n", - my_pinf, - ((unsigned char *)&my_pinf)[0], - ((unsigned char *)&my_pinf)[1], - ((unsigned char *)&my_pinf)[2], - ((unsigned char *)&my_pinf)[3], - ((unsigned char *)&my_pinf)[4], - ((unsigned char *)&my_pinf)[5], - ((unsigned char *)&my_pinf)[6], - ((unsigned char *)&my_pinf)[7], - trio_isnan(my_pinf), trio_isinf(my_pinf)); - printf("NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n", - my_ninf, - ((unsigned char *)&my_ninf)[0], - ((unsigned char *)&my_ninf)[1], - ((unsigned char *)&my_ninf)[2], - ((unsigned char *)&my_ninf)[3], - ((unsigned char *)&my_ninf)[4], - ((unsigned char *)&my_ninf)[5], - ((unsigned char *)&my_ninf)[6], - ((unsigned char *)&my_ninf)[7], - trio_isnan(my_ninf), trio_isinf(my_ninf)); - - return 0; -} -#endif diff --git a/glib/trio/trionan.h b/glib/trio/trionan.h deleted file mode 100644 index bed0c12..0000000 --- a/glib/trio/trionan.h +++ /dev/null @@ -1,81 +0,0 @@ -/************************************************************************* - * - * $Id$ - * - * Copyright (C) 2001 Bjorn Reese - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************/ - -#ifndef TRIO_NAN_H -#define TRIO_NAN_H - -#include "triodef.h" - -#ifdef __cplusplus -extern "C" { -#endif - -enum { - TRIO_FP_INFINITE, - TRIO_FP_NAN, - TRIO_FP_NORMAL, - TRIO_FP_SUBNORMAL, - TRIO_FP_ZERO -}; - -/* - * Return NaN (Not-a-Number). - */ -TRIO_PUBLIC double trio_nan TRIO_PROTO((void)); - -/* - * Return positive infinity. - */ -TRIO_PUBLIC double trio_pinf TRIO_PROTO((void)); - -/* - * Return negative infinity. - */ -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 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 TRIO_PROTO((double number)); - -/* - * If number is finite return non-zero, otherwise return zero. - */ -TRIO_PUBLIC int trio_isfinite TRIO_PROTO((double number)); - -TRIO_PUBLIC int trio_signbit TRIO_PROTO((double number)); - -TRIO_PUBLIC int trio_fpclassify TRIO_PROTO((double number)); - -TRIO_PUBLIC int trio_fpclassify_and_signbit TRIO_PROTO((double number, int *is_negative)); - -#ifdef __cplusplus -} -#endif - -#endif /* TRIO_NAN_H */ diff --git a/glib/trio/triop.h b/glib/trio/triop.h deleted file mode 100644 index 8462c56..0000000 --- a/glib/trio/triop.h +++ /dev/null @@ -1,150 +0,0 @@ -/************************************************************************* - * - * $Id$ - * - * Copyright (C) 2000 Bjorn Reese and Daniel Stenberg. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************ - * - * Private functions, types, etc. used for callback functions. - * - * The ref pointer is an opaque type and should remain as such. - * Private data must only be accessible through the getter and - * setter functions. - * - ************************************************************************/ - -#ifndef TRIO_TRIOP_H -#define TRIO_TRIOP_H - -#include "triodef.h" - -#include -#if defined(TRIO_COMPILER_ANCIENT) -# include -#else -# include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef TRIO_C99 -# define TRIO_C99 1 -#endif -#ifndef TRIO_BSD -# define TRIO_BSD 1 -#endif -#ifndef TRIO_GNU -# define TRIO_GNU 1 -#endif -#ifndef TRIO_MISC -# define TRIO_MISC 1 -#endif -#ifndef TRIO_UNIX98 -# define TRIO_UNIX98 1 -#endif -#ifndef TRIO_MICROSOFT -# define TRIO_MICROSOFT 1 -#endif -#ifndef TRIO_EXTENSION -# define TRIO_EXTENSION 1 -#endif -#ifndef TRIO_WIDECHAR /* Does not work yet. Do not enable */ -# define TRIO_WIDECHAR 0 -#endif -#ifndef TRIO_ERRORS -# define TRIO_ERRORS 1 -#endif - -#ifndef TRIO_MALLOC -# define TRIO_MALLOC(n) malloc(n) -#endif -#ifndef TRIO_REALLOC -# define TRIO_REALLOC(x,n) realloc((x),(n)) -#endif -#ifndef TRIO_FREE -# define TRIO_FREE(x) free(x) -#endif - - -/************************************************************************* - * User-defined specifiers - */ - -typedef int (*trio_callback_t) TRIO_PROTO((trio_pointer_t)); - -trio_pointer_t trio_register TRIO_PROTO((trio_callback_t callback, const char *name)); -void trio_unregister TRIO_PROTO((trio_pointer_t handle)); - -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 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 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 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" */ -#endif - -#endif /* TRIO_TRIOP_H */ diff --git a/glib/trio/triostr.c b/glib/trio/triostr.c deleted file mode 100644 index 6d5fc43..0000000 --- a/glib/trio/triostr.c +++ /dev/null @@ -1,2025 +0,0 @@ -/************************************************************************* - * - * $Id$ - * - * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************/ - -/************************************************************************* - * Include files - */ - -#include "glibtrio.h" -#include -#include -#include -#include -#include -#include "triodef.h" -#include "triostr.h" - -/************************************************************************* - * Definitions - */ - -#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 -#if !defined(NIL) -# define NIL ((char)0) -#endif -#if !defined(FALSE) -# define FALSE (1 == 0) -# define TRUE (! FALSE) -#endif -#if !defined(BOOLEAN_T) -# define BOOLEAN_T int -#endif - -#if defined(TRIO_COMPILER_SUPPORTS_C99) -# define USE_STRTOD -# define USE_STRTOF -#elif defined(TRIO_COMPILER_MSVC) -# define USE_STRTOD -#endif - -#if defined(TRIO_PLATFORM_UNIX) -# define USE_STRCASECMP -# define USE_STRNCASECMP -# define USE_STRERROR -# if defined(TRIO_PLATFORM_QNX) -# define strcasecmp(x,y) stricmp(x,y) -# define strncasecmp(x,y,n) strnicmp(x,y,n) -# endif -#elif defined(TRIO_PLATFORM_WIN32) -# define USE_STRCASECMP -# define strcasecmp(x,y) strcmpi(x,y) -#endif - -/************************************************************************* - * Structures - */ - -struct _trio_string_t -{ - char *content; - size_t length; - size_t allocated; -}; - -/************************************************************************* - * Constants - */ - -#if !defined(TRIO_MINIMAL) -static TRIO_CONST char rcsid[] = "@(#)$Id$"; -#endif - -/************************************************************************* - * Static String Functions - */ - -#if defined(TRIO_DOCUMENTATION) -# include "doc/doc_static.h" -#endif -/** @addtogroup StaticStrings - @{ -*/ - -/** - Create new string. - - @param size Size of new string. - @return Pointer to string, or NULL if allocation failed. -*/ -TRIO_STRING_PUBLIC char * -trio_create -TRIO_ARGS1((size), - size_t size) -{ - return (char *)TRIO_MALLOC(size); -} - - -/** - Destroy string. - - @param string String to be freed. -*/ -TRIO_STRING_PUBLIC void -trio_destroy -TRIO_ARGS1((string), - char *string) -{ - if (string) - { - TRIO_FREE(string); - } -} - - -/** - Count the number of characters in a string. - - @param string String to measure. - @return Number of characters in @string. -*/ -TRIO_STRING_PUBLIC size_t -trio_length -TRIO_ARGS1((string), - TRIO_CONST char *string) -{ - return strlen(string); -} - - -#if !defined(TRIO_MINIMAL) -/** - Append @p source at the end of @p target. - - @param target Target string. - @param source Source string. - @return Boolean value indicating success or failure. - - @pre @p target must point to a memory chunk with sufficient room to - contain the @p target string and @p source string. - @pre No boundary checking is performed, so insufficient memory will - result in a buffer overrun. - @post @p target will be zero terminated. -*/ -TRIO_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. - - @param target Target string. - @param max Maximum number of characters to append. - @param source Source string. - @return Boolean value indicating success or failure. - - @pre @p target must point to a memory chuck with sufficient room to - contain the @p target string and the @p source string (at most @p max - characters). - @pre No boundary checking is performed, so insufficient memory will - result in a buffer overrun. - @post @p target will be zero terminated. -*/ -TRIO_STRING_PUBLIC int -trio_append_max -TRIO_ARGS3((target, max, source), - char *target, - size_t max, - TRIO_CONST char *source) -{ - size_t length; - - assert(target); - assert(source); - - length = trio_length(target); - - if (max > length) - { - strncat(target, source, max - length - 1); - } - return TRUE; -} -#endif /* !defined(TRIO_MINIMAL) */ - - -#if !defined(TRIO_MINIMAL) -/** - Determine if a string contains a substring. - - @param string String to be searched. - @param substring String to be found. - @return Boolean value indicating success or failure. -*/ -TRIO_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. - - @param target Target string. - @param source Source string. - @return Boolean value indicating success or failure. - - @pre @p target must point to a memory chunk with sufficient room to - contain the @p source string. - @pre No boundary checking is performed, so insufficient memory will - result in a buffer overrun. - @post @p target will be zero terminated. -*/ -TRIO_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) */ - - -/** - Copy at most @p max characters from @p source to @p target. - - @param target Target string. - @param max Maximum number of characters to append. - @param source Source string. - @return Boolean value indicating success or failure. - - @pre @p target must point to a memory chunk with sufficient room to - contain the @p source string (at most @p max characters). - @pre No boundary checking is performed, so insufficient memory will - result in a buffer overrun. - @post @p target will be zero terminated. -*/ -TRIO_STRING_PUBLIC int -trio_copy_max -TRIO_ARGS3((target, max, source), - char *target, - size_t max, - TRIO_CONST char *source) -{ - assert(target); - assert(source); - assert(max > 0); /* Includes != 0 */ - - (void)strncpy(target, source, max - 1); - target[max - 1] = (char)0; - return TRUE; -} - - -/* - * 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. - - @param source Source string. - @return A copy of the @p source string. - - @post @p target will be zero terminated. -*/ -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. - - @param source Source string. - @param max Maximum number of characters to duplicate. - @return A copy of the @p source string. - - @post @p target will be zero terminated. -*/ -TRIO_STRING_PUBLIC char * -trio_duplicate_max TRIO_ARGS2((source, max), - TRIO_CONST char *source, - size_t max) -{ - size_t length; - - assert(source); - assert(max > 0); - - length = trio_length(source); - if (length > max) - { - length = max; - } - return TrioDuplicateMax(source, length); -} -#endif /* !defined(TRIO_MINIMAL) */ - - -/** - Compare if two strings are equal. - - @param first First string. - @param second Second string. - @return Boolean indicating whether the two strings are equal or not. - - Case-insensitive comparison. -*/ -TRIO_STRING_PUBLIC int -trio_equal -TRIO_ARGS2((first, second), - TRIO_CONST char *first, - TRIO_CONST char *second) -{ - assert(first); - assert(second); - - if ((first != NULL) && (second != NULL)) - { -#if defined(USE_STRCASECMP) - return (0 == strcasecmp(first, second)); -#else - while ((*first != NIL) && (*second != NIL)) - { - if (toupper(*first) != toupper(*second)) - { - break; - } - first++; - second++; - } - return ((*first == NIL) && (*second == NIL)); -#endif - } - return FALSE; -} - - -/** - Compare if two strings are equal. - - @param first First string. - @param second Second string. - @return Boolean indicating whether the two strings are equal or not. - - Case-sensitive comparison. -*/ -TRIO_STRING_PUBLIC int -trio_equal_case -TRIO_ARGS2((first, second), - TRIO_CONST char *first, - TRIO_CONST char *second) -{ - assert(first); - assert(second); - - if ((first != NULL) && (second != NULL)) - { - return (0 == strcmp(first, second)); - } - return FALSE; -} - - -#if !defined(TRIO_MINIMAL) -/** - Compare if two strings up until the first @p max characters are equal. - - @param first First string. - @param max Maximum number of characters to compare. - @param second Second string. - @return Boolean indicating whether the two strings are equal or not. - - Case-sensitive comparison. -*/ -TRIO_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); - - if ((first != NULL) && (second != NULL)) - { - return (0 == strncmp(first, second, max)); - } - return FALSE; -} -#endif /* !defined(TRIO_MINIMAL) */ - - -/** - Compare if two strings are equal. - - @param first First string. - @param second Second string. - @return Boolean indicating whether the two strings are equal or not. - - Collating characters are considered equal. -*/ -TRIO_STRING_PUBLIC int -trio_equal_locale -TRIO_ARGS2((first, second), - TRIO_CONST char *first, - TRIO_CONST char *second) -{ - assert(first); - assert(second); - -#if defined(LC_COLLATE) - return (strcoll(first, second) == 0); -#else - return trio_equal(first, second); -#endif -} - - -/** - Compare if two strings up until the first @p max characters are equal. - - @param first First string. - @param max Maximum number of characters to compare. - @param second Second string. - @return Boolean indicating whether the two strings are equal or not. - - Case-insensitive comparison. -*/ -TRIO_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); - - if ((first != NULL) && (second != NULL)) - { -#if defined(USE_STRNCASECMP) - return (0 == strncasecmp(first, second, max)); -#else - /* Not adequately tested yet */ - size_t cnt = 0; - while ((*first != NIL) && (*second != NIL) && (cnt <= max)) - { - if (toupper(*first) != toupper(*second)) - { - break; - } - first++; - second++; - cnt++; - } - return ((cnt == max) || ((*first == NIL) && (*second == NIL))); -#endif - } - return FALSE; -} - - -/** - Provide a textual description of an error code (errno). - - @param error_number Error number. - @return Textual description of @p error_number. -*/ -TRIO_STRING_PUBLIC TRIO_CONST char * -trio_error -TRIO_ARGS1((error_number), - int error_number) -{ -#if defined(USE_STRERROR) - return strerror(error_number); -#else - return "unknown"; -#endif -} - - -#if !defined(TRIO_MINIMAL) -/** - Format the date/time according to @p format. - - @param target Target string. - @param max Maximum number of characters to format. - @param format Formatting string. - @param datetime Date/time structure. - @return Number of formatted characters. - - The formatting string accepts the same specifiers as the standard C - function strftime. -*/ -TRIO_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); - assert(datetime); - assert(max > 0); - - return strftime(target, max, format, datetime); -} -#endif /* !defined(TRIO_MINIMAL) */ - - -#if !defined(TRIO_MINIMAL) -/** - Calculate a hash value for a string. - - @param string String to be calculated on. - @param type Hash function. - @return Calculated hash value. - - @p type can be one of the following - @li @c TRIO_HASH_PLAIN Plain hash function. -*/ -TRIO_STRING_PUBLIC unsigned long -trio_hash -TRIO_ARGS2((string, type), - TRIO_CONST char *string, - int type) -{ - unsigned long value = 0L; - char ch; - - assert(string); - - switch (type) - { - case TRIO_HASH_PLAIN: - while ( (ch = *string++) != NIL ) - { - value *= 31; - value += (unsigned long)ch; - } - break; - default: - assert(FALSE); - break; - } - return value; -} -#endif /* !defined(TRIO_MINIMAL) */ - - -#if !defined(TRIO_MINIMAL) -/** - Find first occurrence of a character in a string. - - @param string String to be searched. - @param character Character to be found. - @param A pointer to the found character, or NULL if character was not found. - */ -TRIO_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. - - @param string String to be searched. - @param character Character to be found. - @param A pointer to the found character, or NULL if character was not found. - */ -TRIO_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_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. - - @param string String to be searched. - @param pattern Pattern, including wildcards, to search for. - @return Boolean value indicating success or failure. - - Case-insensitive comparison. - - The following wildcards can be used - @li @c * Match any number of characters. - @li @c ? Match a single character. -*/ -TRIO_STRING_PUBLIC int -trio_match -TRIO_ARGS2((string, pattern), - TRIO_CONST char *string, - TRIO_CONST char *pattern) -{ - assert(string); - assert(pattern); - - for (; ('*' != *pattern); ++pattern, ++string) - { - if (NIL == *string) - { - return (NIL == *pattern); - } - if ((toupper((int)*string) != toupper((int)*pattern)) - && ('?' != *pattern)) - { - return FALSE; - } - } - /* two-line patch to prevent *too* much recursiveness: */ - while ('*' == pattern[1]) - pattern++; - - do - { - if ( trio_match(string, &pattern[1]) ) - { - return TRUE; - } - } - while (*string++); - - return FALSE; -} -#endif /* !defined(TRIO_MINIMAL) */ - - -#if !defined(TRIO_MINIMAL) -/** - Compare two strings using wildcards. - - @param string String to be searched. - @param pattern Pattern, including wildcards, to search for. - @return Boolean value indicating success or failure. - - Case-sensitive comparison. - - The following wildcards can be used - @li @c * Match any number of characters. - @li @c ? Match a single character. -*/ -TRIO_STRING_PUBLIC int -trio_match_case -TRIO_ARGS2((string, pattern), - TRIO_CONST char *string, - TRIO_CONST char *pattern) -{ - assert(string); - assert(pattern); - - for (; ('*' != *pattern); ++pattern, ++string) - { - if (NIL == *string) - { - return (NIL == *pattern); - } - if ((*string != *pattern) - && ('?' != *pattern)) - { - return FALSE; - } - } - /* two-line patch to prevent *too* much recursiveness: */ - while ('*' == pattern[1]) - pattern++; - - do - { - if ( trio_match_case(string, &pattern[1]) ) - { - return TRUE; - } - } - while (*string++); - - return FALSE; -} -#endif /* !defined(TRIO_MINIMAL) */ - - -#if !defined(TRIO_MINIMAL) -/** - Execute a function on each character in string. - - @param target Target string. - @param source Source string. - @param Function Function to be executed. - @return Number of processed characters. -*/ -TRIO_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; - - assert(target); - assert(source); - assert(Function); - - while (*source != NIL) - { - *target++ = Function(*source++); - count++; - } - return count; -} -#endif /* !defined(TRIO_MINIMAL) */ - - -#if !defined(TRIO_MINIMAL) -/** - Search for a substring in a string. - - @param string String to be searched. - @param substring String to be found. - @return Pointer to first occurrence of @p substring in @p string, or NULL - if no match was found. -*/ -TRIO_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. - - @param string String to be searched. - @param max Maximum characters to be searched. - @param substring String to be found. - @return Pointer to first occurrence of @p substring in @p string, or NULL - if no match was found. -*/ -TRIO_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; - char *result = NULL; - - assert(string); - assert(substring); - - size = trio_length(substring); - if (size <= max) - { - for (count = 0; count <= max - size; count++) - { - if (trio_equal_max(substring, size, &string[count])) - { - result = (char *)&string[count]; - break; - } - } - } - return result; -} -#endif /* !defined(TRIO_MINIMAL) */ - - -#if !defined(TRIO_MINIMAL) -/** - Tokenize string. - - @param string String to be tokenized. - @param tokens String containing list of delimiting characters. - @return Start of new token. - - @warning @p string will be destroyed. -*/ -TRIO_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) */ - - -/** - Convert string to floating-point number. - - @param source String to be converted. - @param endp Pointer to end of the converted string. - @return A floating-point number. - - The following Extended Backus-Naur form is used - @verbatim - double ::= [ ] - ( | - | - ) - [ [ ] ] - number ::= 1*( ) - digit ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' ) - exponential ::= ( 'e' | 'E' ) - sign ::= ( '-' | '+' ) - decimal_point ::= '.' - @endverbatim -*/ -/* FIXME: Add EBNF for hex-floats */ -TRIO_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 - int isNegative = FALSE; - int isExponentNegative = FALSE; - trio_long_double_t integer = 0.0; - trio_long_double_t fraction = 0.0; - unsigned long exponent = 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 *= base; - integer += (isdigit((int)*source) - ? (*source - '0') - : 10 + (toupper((int)*source) - 'A')); - source++; - } - if (*source == '.') - { - source++; - while (isxdigit((int)*source)) - { - fracdiv /= base; - fraction += fracdiv * (isdigit((int)*source) - ? (*source - '0') - : 10 + (toupper((int)*source) - 'A')); - source++; - } - if ((*source == 'p') || (*source == 'P')) - { - source++; - if ((*source == '+') || (*source == '-')) - { - isExponentNegative = (*source == '-'); - source++; - } - while (isdigit((int)*source)) - { - exponent *= (int)base; - exponent += (*source - '0'); - source++; - } - } - } - } - else /* Then try normal decimal floats */ - { - base = 10.0; - isNegative = (*source == '-'); - /* Skip sign */ - if ((*source == '+') || (*source == '-')) - source++; - - /* Integer part */ - while (isdigit((int)*source)) - { - integer *= base; - integer += (*source - '0'); - source++; - } - - if (*source == '.') - { - source++; /* skip decimal point */ - while (isdigit((int)*source)) - { - fracdiv /= base; - fraction += (*source - '0') * fracdiv; - source++; - } - } - if ((*source == 'e') - || (*source == 'E') -#if TRIO_MICROSOFT - || (*source == 'd') - || (*source == 'D') -#endif - ) - { - source++; /* Skip exponential indicator */ - isExponentNegative = (*source == '-'); - if ((*source == '+') || (*source == '-')) - source++; - while (isdigit((int)*source)) - { - exponent *= (int)base; - exponent += (*source - '0'); - source++; - } - } - } - - value = integer + fraction; - if (exponent != 0) - { - if (isExponentNegative) - value /= pow(base, (double)exponent); - else - value *= pow(base, (double)exponent); - } - if (isNegative) - value = -value; - - if (endp) - *endp = (char *)source; - return value; -#endif -} - - -/** - Convert string to floating-point number. - - @param source String to be converted. - @param endp Pointer to end of the converted string. - @return A floating-point number. - - See @ref trio_to_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_STRING_PUBLIC float -trio_to_float -TRIO_ARGS2((source, endp), - TRIO_CONST char *source, - char **endp) -{ -#if defined(USE_STRTOF) - return strtof(source, endp); -#else - return (float)trio_to_long_double(source, endp); -#endif -} -#endif /* !defined(TRIO_MINIMAL) */ - - -/** - Convert string to signed integer. - - @param string String to be converted. - @param endp Pointer to end of converted string. - @param base Radix number of number. -*/ -TRIO_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)); - - return strtol(string, endp, base); -} - - -#if !defined(TRIO_MINIMAL) -/** - Convert string to unsigned integer. - - @param string String to be converted. - @param endp Pointer to end of converted string. - @param base Radix number of number. -*/ -TRIO_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_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 */ - - -/************************************************************************* - * Dynamic String Functions - */ - -#if defined(TRIO_DOCUMENTATION) -# include "doc/doc_dynamic.h" -#endif -/** @addtogroup DynamicStrings - @{ -*/ - -/* - * TrioStringAlloc - */ -TRIO_STRING_PRIVATE trio_string_t * -TrioStringAlloc(TRIO_NOARGS) -{ - trio_string_t *self; - - self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t)); - if (self) - { - self->content = NULL; - self->length = 0; - self->allocated = 0; - } - return self; -} - - -/* - * TrioStringGrow - * - * The size of the string will be increased by 'delta' characters. If - * 'delta' is zero, the size will be doubled. - */ -TRIO_STRING_PRIVATE BOOLEAN_T -TrioStringGrow -TRIO_ARGS2((self, delta), - trio_string_t *self, - size_t delta) -{ - BOOLEAN_T status = FALSE; - char *new_content; - size_t new_size; - - new_size = (delta == 0) - ? ( (self->allocated == 0) ? 1 : self->allocated * 2 ) - : self->allocated + delta; - - new_content = (char *)TRIO_REALLOC(self->content, new_size); - if (new_content) - { - self->content = new_content; - self->allocated = new_size; - status = TRUE; - } - return status; -} - - -/* - * TrioStringGrowTo - * - * The size of the string will be increased to 'length' plus one characters. - * If 'length' is less than the original size, the original size will be - * used (that is, the size of the string is never decreased). - */ -TRIO_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) - ? TrioStringGrow(self, length - self->allocated) - : TRUE; -} - - -#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_STRING_PUBLIC trio_string_t * -trio_string_create -TRIO_ARGS1((initial_size), - int initial_size) -{ - trio_string_t *self; - - self = TrioStringAlloc(); - if (self) - { - if (TrioStringGrow(self, - (size_t)((initial_size > 0) ? initial_size : 1))) - { - self->content[0] = (char)0; - self->allocated = initial_size; - } - else - { - trio_string_destroy(self); - self = NULL; - } - } - return self; -} -#endif /* !defined(TRIO_MINIMAL) */ - - -/** - Deallocate the dynamic string and its contents. - - @param self Dynamic string -*/ -TRIO_STRING_PUBLIC void -trio_string_destroy -TRIO_ARGS1((self), - trio_string_t *self) -{ - assert(self); - - if (self) - { - trio_destroy(self->content); - TRIO_FREE(self); - } -} - - -#if !defined(TRIO_MINIMAL) -/** - Get a pointer to the content. - - @param self Dynamic string. - @param offset Offset into content. - @return Pointer to the content. - - @p Offset can be zero, positive, or negative. If @p offset is zero, - then the start of the content will be returned. If @p offset is positive, - then a pointer to @p offset number of characters from the beginning of the - content is returned. If @p offset is negative, then a pointer to @p offset - number of characters from the ending of the string, starting at the - terminating zero, is returned. -*/ -TRIO_STRING_PUBLIC char * -trio_string_get -TRIO_ARGS2((self, offset), - trio_string_t *self, - int offset) -{ - char *result = NULL; - - assert(self); - - if (self->content != NULL) - { - if (self->length == 0) - { - (void)trio_string_length(self); - } - if (offset >= 0) - { - if (offset > (int)self->length) - { - offset = self->length; - } - } - else - { - offset += self->length + 1; - if (offset < 0) - { - offset = 0; - } - } - result = &(self->content[offset]); - } - return result; -} -#endif /* !defined(TRIO_MINIMAL) */ - - -/** - Extract the content. - - @param self Dynamic String - @return Content of dynamic string. - - The content is removed from the dynamic string. This enables destruction - of the dynamic string without deallocation of the content. -*/ -TRIO_STRING_PUBLIC char * -trio_string_extract -TRIO_ARGS1((self), - trio_string_t *self) -{ - char *result; - - assert(self); - - result = self->content; - /* FIXME: Allocate new empty buffer? */ - self->content = NULL; - self->length = self->allocated = 0; - return result; -} - - -#if !defined(TRIO_MINIMAL) -/** - Set the content of the dynamic string. - - @param self Dynamic String - @param buffer The new content. - - Sets the content of the dynamic string to a copy @p buffer. - An existing content will be deallocated first, if necessary. - - @remark - This function will make a copy of @p buffer. - You are responsible for deallocating @p buffer yourself. -*/ -TRIO_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_STRING_PUBLIC int -trio_string_size -TRIO_ARGS1((self), - trio_string_t *self) -{ - assert(self); - - return self->allocated; -} - - -/* - * trio_string_terminate - */ -TRIO_STRING_PUBLIC void -trio_string_terminate -TRIO_ARGS1((self), - trio_string_t *self) -{ - trio_xstring_append_char(self, 0); -} - - -#if !defined(TRIO_MINIMAL) -/** - Append the second string to the first. - - @param self Dynamic string to be modified. - @param other Dynamic string to copy from. - @return Boolean value indicating success or failure. -*/ -TRIO_STRING_PUBLIC int -trio_string_append -TRIO_ARGS2((self, other), - trio_string_t *self, - trio_string_t *other) -{ - size_t length; - - assert(self); - assert(other); - - length = self->length + other->length; - if (!TrioStringGrowTo(self, length)) - goto error; - trio_copy(&self->content[self->length], other->content); - self->length = length; - return TRUE; - - error: - return FALSE; -} -#endif /* !defined(TRIO_MINIMAL) */ - - -#if !defined(TRIO_MINIMAL) -/* - * trio_xstring_append - */ -TRIO_STRING_PUBLIC int -trio_xstring_append -TRIO_ARGS2((self, other), - trio_string_t *self, - TRIO_CONST char *other) -{ - size_t length; - - assert(self); - assert(other); - - length = self->length + trio_length(other); - if (!TrioStringGrowTo(self, length)) - goto error; - trio_copy(&self->content[self->length], other); - self->length = length; - return TRUE; - - error: - return FALSE; -} -#endif /* !defined(TRIO_MINIMAL) */ - - -/* - * trio_xstring_append_char - */ -TRIO_STRING_PUBLIC int -trio_xstring_append_char -TRIO_ARGS2((self, character), - trio_string_t *self, - char character) -{ - assert(self); - - if ((int)self->length >= trio_string_size(self)) - { - if (!TrioStringGrow(self, 0)) - goto error; - } - self->content[self->length] = character; - self->length++; - return TRUE; - - error: - return FALSE; -} - - -#if !defined(TRIO_MINIMAL) -/** - Search for the first occurrence of second parameter in the first. - - @param self Dynamic string to be modified. - @param other Dynamic string to copy from. - @return Boolean value indicating success or failure. -*/ -TRIO_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_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_STRING_PUBLIC int -trio_string_copy -TRIO_ARGS2((self, other), - trio_string_t *self, - trio_string_t *other) -{ - assert(self); - assert(other); - - self->length = 0; - return trio_string_append(self, other); -} -#endif /* !defined(TRIO_MINIMAL) */ - - -#if !defined(TRIO_MINIMAL) -/* - * trio_xstring_copy - */ -TRIO_STRING_PUBLIC int -trio_xstring_copy -TRIO_ARGS2((self, other), - trio_string_t *self, - TRIO_CONST char *other) -{ - assert(self); - assert(other); - - self->length = 0; - return trio_xstring_append(self, other); -} -#endif /* !defined(TRIO_MINIMAL) */ - - -#if !defined(TRIO_MINIMAL) -/* - * trio_string_duplicate - */ -TRIO_STRING_PUBLIC trio_string_t * -trio_string_duplicate -TRIO_ARGS1((other), - trio_string_t *other) -{ - trio_string_t *self; - - assert(other); - - self = TrioStringAlloc(); - if (self) - { - self->content = TrioDuplicateMax(other->content, other->length); - if (self->content) - { - self->length = other->length; - self->allocated = self->length + 1; - } - else - { - self->length = self->allocated = 0; - } - } - return self; -} -#endif /* !defined(TRIO_MINIMAL) */ - - -/* - * trio_xstring_duplicate - */ -TRIO_STRING_PUBLIC trio_string_t * -trio_xstring_duplicate -TRIO_ARGS1((other), - TRIO_CONST char *other) -{ - trio_string_t *self; - - assert(other); - - self = TrioStringAlloc(); - if (self) - { - self->content = TrioDuplicateMax(other, trio_length(other)); - if (self->content) - { - self->length = trio_length(self->content); - self->allocated = self->length + 1; - } - else - { - self->length = self->allocated = 0; - } - } - return self; -} - - -#if !defined(TRIO_MINIMAL) -/* - * trio_string_equal - */ -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_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_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_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_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_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_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_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_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_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_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_STRING_PUBLIC int -trio_string_length -TRIO_ARGS1((self), - trio_string_t *self) -{ - assert(self); - - if (self->length == 0) - { - self->length = trio_length(self->content); - } - return self->length; -} -#endif /* !defined(TRIO_MINIMAL) */ - - -#if !defined(TRIO_MINIMAL) -/* - * trio_string_lower - */ -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_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_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_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_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_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_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_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/glib/trio/triostr.h b/glib/trio/triostr.h deleted file mode 100644 index 083e2a5..0000000 --- a/glib/trio/triostr.h +++ /dev/null @@ -1,127 +0,0 @@ -/************************************************************************* - * - * $Id$ - * - * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************/ - -#ifndef TRIO_TRIOSTR_H -#define TRIO_TRIOSTR_H - -#include -#include -#include -#include -#include "triodef.h" -#include "triop.h" - -enum { - TRIO_HASH_NONE = 0, - TRIO_HASH_PLAIN, - 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 - */ - -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 - */ - -/* - * Opaque type for dynamic strings - */ -typedef struct _trio_string_t trio_string_t; - -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)); - -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)); - -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 */ -- 2.7.4