diff options
Diffstat (limited to 'trio')
-rw-r--r-- | trio/CHANGES | 22 | ||||
-rw-r--r-- | trio/Makefile.in | 32 | ||||
-rw-r--r-- | trio/configure.in | 56 | ||||
-rw-r--r-- | trio/regression.c | 7 | ||||
-rw-r--r-- | trio/trio.c | 55 | ||||
-rw-r--r-- | trio/trio.h | 29 | ||||
-rw-r--r-- | trio/triodef.h | 25 | ||||
-rw-r--r-- | trio/triop.h | 6 | ||||
-rw-r--r-- | trio/triostr.c | 200 | ||||
-rw-r--r-- | trio/triostr.h | 9 |
10 files changed, 292 insertions, 149 deletions
diff --git a/trio/CHANGES b/trio/CHANGES index da7b76ca..fec2926f 100644 --- a/trio/CHANGES +++ b/trio/CHANGES @@ -4,8 +4,28 @@ CHANGES -- trio The changes listed without a name attributed to them were most likely done by Bjorn Reese and/or Daniel Stenberg. -Version 1.14 - 2009/05/31 +Version 1.14 - 2010/01/26 ------------------------- +* David Byron + Added trio_xstring_append_max. + +* Fixed compilation problem on Cygwin due to lack of long double math + (reported by Matthias Andree). + +* David Boyce + Added #undef of standard stdio function names before assigning trio functions + to them. + +* Matthias Andree + Upgraded configure.in to use new macros instead of obsoleted macros. + +* Matthias Andree + Added VPATH to Makefile.in + +* Tom Honermann + Fixed problem with subnormal numbers which caused an infinite loop outputting + leading spaces. + * Adam McLaurin Improved parsing performance by avoiding memset() and memcpy() on character arrays. diff --git a/trio/Makefile.in b/trio/Makefile.in index f57f16ba..4f3b9692 100644 --- a/trio/Makefile.in +++ b/trio/Makefile.in @@ -10,9 +10,11 @@ RANLIB = @RANLIB@ ERASE = rm -f MKDIR = mkdir -p GENDOC = doxygen - -PURIFY = purify -PURIFYOPTIONS = -chain-length=16 -first-only=YES +srcdir = @srcdir@ +# VPATH doesn't seem to work with /usr/xpg4/bin/make on Solaris +# (use /usr/ccs/bin/make), and doesn't work on older Solaris make +# such as Solaris 2.6. +VPATH = @srcdir@ # Installation settings INSTALL = @INSTALL@ @@ -22,9 +24,22 @@ exec_prefix = @exec_prefix@ includedir = @includedir@ libdir = @libdir@ -all: $(TARGETLIB) $(TARGET) regression +all: $(TARGETLIB) $(TARGET) + +.PHONY: all check test install doc clean + +$(srcdir)/configure: configure.in + cd $(srcdir) && autoconf -test: all +Makefile: Makefile.in config.status + CONFIG_COMMANDS= CONFIG_LINKS= CONFIG_HEADERS= \ + CONFIG_FILES=Makefile ./config.status + +config.status: configure + ./config.status --recheck + +check: test +test: regression ./regression install: $(TARGETLIB) @@ -32,12 +47,9 @@ install: $(TARGETLIB) $(MKDIR) $(includedir) $(INSTALL_DATA) $(TARGETLIB) $(libdir)/$(TARGETLIB) for i in $(TARGETINCS);do \ - (set -x;$(INSTALL_DATA) $$i $(includedir)); \ + (set -x;$(INSTALL_DATA) $(srcdir)/$$i $(includedir)); \ done -pure: $(TOBJS) $(OBJS) - $(PURIFY) $(PURIFYOPTIONS) $(CC) $(CFLAGS) $^ $(LDFLAGS) - regression: regression.o $(TARGETLIB) $(CC) $(CFLAGS) regression.o $(LDFLAGS) -o $@ @@ -55,7 +67,7 @@ $(TARGETLIB): $(OBJS) $(RANLIB) $(TARGETLIB) doc:: - $(GENDOC) doc/trio.cfg + (cd $(srcdir) && $(GENDOC) doc/trio.cfg) clean: $(ERASE) *~ core core.* regression example $(TOBJS) $(OBJS) $(TARGET) $(TARGETLIB) example.o regression.o diff --git a/trio/configure.in b/trio/configure.in index 212684d5..f1ed7659 100644 --- a/trio/configure.in +++ b/trio/configure.in @@ -2,11 +2,13 @@ dnl dnl Configuration for trio dnl -AC_INIT(triodef.h) +AC_INIT +AC_CONFIG_SRCDIR([triodef.h]) +AC_PREREQ(2.55) dnl autoconf 2.55 was released in 2002 AC_PROG_CC ifdef([AC_PROG_CC_STDC], [AC_PROG_CC_STDC]) -AC_LANG_C +AC_LANG([C]) AC_PROG_INSTALL AC_PROG_RANLIB @@ -17,32 +19,36 @@ dnl AC_MSG_CHECKING(for IEEE compilation options) AC_CACHE_VAL(ac_cv_ieee_option, [ -AC_TRY_COMPILE(,[ -#if !(defined(__alpha) && (defined(__DECC) || defined(__DECCXX) || (defined(__osf__) && defined(__LANGUAGE_C__))) && (defined(VMS) || defined(__VMS))) -# error "Option needed" -typedef int option_needed[-1]; -#endif -],ac_cv_ieee_option="/IEEE_MODE=UNDERFLOW_TO_ZERO/FLOAT=IEEE", -AC_TRY_COMPILE(,[ -#if !(defined(__alpha) && (defined(__DECC) || defined(__DECCXX) || (defined(__osf__) && defined(__LANGUAGE_C__) && !defined(__GNUC__))) && !(defined(VMS) || defined(__VMS)) && !defined(_CFE)) -# error "Option needed" -typedef int option_needed[-1]; -#endif -],ac_cv_ieee_option="-ieee", -AC_TRY_COMPILE(,[ -#if !(defined(__alpha) && (defined(__GNUC__) && (defined(__osf__) || defined(__linux__)))) -# error "Option needed" -typedef int option_needed[-1]; -#endif -],ac_cv_ieee_option="-mieee", -ac_cv_ieee_option="none" -) -) -) + AC_COMPILE_IFELSE(AC_LANG_PROGRAM(,[[[ + #if !(defined(__alpha) && (defined(__DECC) || defined(__DECCXX) || (defined(__osf__) && defined(__LANGUAGE_C__))) && (defined(VMS) || defined(__VMS))) + # error "Option needed" + typedef int option_needed[-1]; + #endif + ]]]), + ac_cv_ieee_option="/IEEE_MODE=UNDERFLOW_TO_ZERO/FLOAT=IEEE", + AC_COMPILE_IFELSE(AC_LANG_PROGRAM(,[[[ + #if !(defined(__alpha) && (defined(__DECC) || defined(__DECCXX) || (defined(__osf__) && defined(__LANGUAGE_C__) && !defined(__GNUC__))) && !(defined(VMS) || defined(__VMS)) && !defined(_CFE)) + # error "Option needed" + typedef int option_needed[-1]; + #endif + ]]]), + ac_cv_ieee_option="-ieee", + AC_COMPILE_IFELSE(AC_LANG_PROGRAM(,[[[ + #if !(defined(__alpha) && (defined(__GNUC__) && (defined(__osf__) || defined(__linux__)))) + # error "Option needed" + typedef int option_needed[-1]; + #endif + ]]]), + ac_cv_ieee_option="-mieee", + ac_cv_ieee_option="none" + ) + ) + ) ]) AC_MSG_RESULT($ac_cv_ieee_option) if test $ac_cv_ieee_option != none; then CFLAGS="${CFLAGS} ${ac_cv_ieee_option}" fi -AC_OUTPUT(Makefile) +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/trio/regression.c b/trio/regression.c index 0716cc63..57c0347e 100644 --- a/trio/regression.c +++ b/trio/regression.c @@ -43,7 +43,7 @@ #define DOUBLE_EQUAL(x,y) (((x)>(y)-DBL_EPSILON) && ((x)<(y)+DBL_EPSILON)) #define FLOAT_EQUAL(x,y) (((x)>(y)-FLT_EPSILON) && ((x)<(y)+FLT_EPSILON)) -static TRIO_CONST char rcsid[] = "@(#)$Id: regression.c,v 1.65 2009/06/07 15:14:31 breese Exp $"; +static TRIO_CONST char rcsid[] = "@(#)$Id: regression.c,v 1.67 2010/01/26 13:02:02 breese Exp $"; #if defined(TRIO_EMBED_NAN) # include "trionan.c" @@ -1208,6 +1208,7 @@ TRIO_ARGS5((file, line, expected, format, original), char data[512]; trio_snprintf(data, sizeof(data), "%s", original); + string[0] = 0; trio_sscanf(data, format, string); return Verify(file, line, expected, "%s", string); } @@ -1534,6 +1535,7 @@ VerifyDynamicStrings(TRIO_NOARGS) int nerrors = 0; #if !defined(TRIO_MINIMAL) trio_string_t *string; + const char no_terminate[5] = { 'h', 'e', 'l', 'l', 'o' }; string = trio_xstring_duplicate("Find me now"); if (string == NULL) { @@ -1553,6 +1555,9 @@ VerifyDynamicStrings(TRIO_NOARGS) nerrors++; if (trio_xstring_match_case(string, "* ME *")) nerrors++; + if (!trio_xstring_append_max(string, no_terminate, 5) || + !trio_xstring_equal(string, "FIND ME NOW AND AGAINhello")) + nerrors++; error: if (string) diff --git a/trio/trio.c b/trio/trio.c index 8c9d36e2..61d7c40b 100644 --- a/trio/trio.c +++ b/trio/trio.c @@ -1,6 +1,6 @@ /************************************************************************* * - * $Id: trio.c,v 1.125 2009/06/23 15:46:21 breese Exp $ + * $Id: trio.c,v 1.129 2009/09/20 11:37:15 breese Exp $ * * Copyright (C) 1998, 2009 Bjorn Reese and Daniel Stenberg. * @@ -141,19 +141,19 @@ #if TRIO_FEATURE_FLOAT # if defined(PREDEF_STANDARD_C99) \ || defined(PREDEF_STANDARD_UNIX03) -# if !defined(HAVE_FLOORL) +# if !defined(HAVE_FLOORL) && !defined(TRIO_NO_FLOORL) # define HAVE_FLOORL # endif -# if !defined(HAVE_CEILL) +# if !defined(HAVE_CEILL) && !defined(TRIO_NO_CEILL) # define HAVE_CEILL # endif -# if !defined(HAVE_POWL) +# if !defined(HAVE_POWL) && !defined(TRIO_NO_POWL) # define HAVE_POWL # endif -# if !defined(HAVE_FMODL) +# if !defined(HAVE_FMODL) && !defined(TRIO_NO_FMODL) # define HAVE_FMODL # endif -# if !defined(HAVE_LOG10L) +# if !defined(HAVE_LOG10L) && !defined(TRIO_NO_LOG10L) # define HAVE_LOG10L # endif # endif @@ -897,7 +897,7 @@ typedef struct _trio_userdef_t { * *************************************************************************/ -static TRIO_CONST char rcsid[] = "@(#)$Id: trio.c,v 1.125 2009/06/23 15:46:21 breese Exp $"; +static TRIO_CONST char rcsid[] = "@(#)$Id: trio.c,v 1.129 2009/09/20 11:37:15 breese Exp $"; #if TRIO_FEATURE_FLOAT /* @@ -3086,14 +3086,14 @@ TRIO_ARGS6((self, number, flags, width, precision, base), } reprocess: - + if (flags & FLAGS_FLOAT_G) { if (precision == 0) precision = 1; - if ( (number < 1.0E-4) || - (number >= trio_pow(base, (trio_long_double_t)precision)) ) + if ( (number < TRIO_SUFFIX_LONG(1.0E-4)) || + (number >= TrioPower(base, (trio_long_double_t)precision)) ) { /* Use scientific notation */ flags |= FLAGS_FLOAT_E; @@ -3127,15 +3127,20 @@ TRIO_ARGS6((self, number, flags, width, precision, base), else { exponent = (int)trio_floor(workNumber); + workNumber = number; /* * The expression A * 10^-B is equivalent to A / 10^B but the former * usually gives better accuracy. */ - workNumber = number * trio_pow(dblBase, (trio_long_double_t)-exponent); - if (trio_isinf(workNumber)) - { - workNumber = number / trio_pow(dblBase, (trio_long_double_t)exponent); - } + workNumber *= TrioPower(dblBase, (trio_long_double_t)-exponent); + if (trio_isinf(workNumber)) { + /* + * Scaling is done it two steps to avoid problems with subnormal + * numbers. + */ + workNumber /= TrioPower(dblBase, (trio_long_double_t)(exponent / 2)); + workNumber /= TrioPower(dblBase, (trio_long_double_t)(exponent - (exponent / 2))); + } number = workNumber; isExponentNegative = (exponent < 0); uExponent = (isExponentNegative) ? -exponent : exponent; @@ -3150,7 +3155,7 @@ TRIO_ARGS6((self, number, flags, width, precision, base), integerNumber = trio_floor(number); fractionNumber = number - integerNumber; - + /* * Truncated number. * @@ -3180,7 +3185,7 @@ TRIO_ARGS6((self, number, flags, width, precision, base), if (integerNumber < 1.0) { - workNumber = number * dblFractionBase + 0.5; + workNumber = number * dblFractionBase + TRIO_SUFFIX_LONG(0.5); if (trio_floor(number * dblFractionBase) != trio_floor(workNumber)) { adjustNumber = TRUE; @@ -3194,7 +3199,7 @@ TRIO_ARGS6((self, number, flags, width, precision, base), } else { - workNumber = number + 0.5 / dblFractionBase; + workNumber = number + TRIO_SUFFIX_LONG(0.5) / dblFractionBase; adjustNumber = (trio_floor(number) != trio_floor(workNumber)); } if (adjustNumber) @@ -3202,8 +3207,8 @@ TRIO_ARGS6((self, number, flags, width, precision, base), if ((flags & FLAGS_FLOAT_G) && !(flags & FLAGS_FLOAT_E)) { /* The adjustment may require a change to scientific notation */ - if ( (workNumber < 1.0E-4) || - (workNumber >= trio_pow(base, (trio_long_double_t)precision)) ) + if ( (workNumber < TRIO_SUFFIX_LONG(1.0E-4)) || + (workNumber >= TrioPower(base, (trio_long_double_t)precision)) ) { /* Use scientific notation */ flags |= FLAGS_FLOAT_E; @@ -3217,7 +3222,7 @@ TRIO_ARGS6((self, number, flags, width, precision, base), if (integerDigits == workDigits) { /* Adjust if the same number of digits are used */ - number += 0.5 / dblFractionBase; + number += TRIO_SUFFIX_LONG(0.5) / dblFractionBase; integerNumber = trio_floor(number); fractionNumber = number - integerNumber; } @@ -3229,7 +3234,7 @@ TRIO_ARGS6((self, number, flags, width, precision, base), uExponent = (isExponentNegative) ? -exponent : exponent; if (isHex) uExponent *= 4; /* log16(2) */ - workNumber = (number + 0.5 / dblFractionBase) / dblBase; + workNumber = (number + TRIO_SUFFIX_LONG(0.5) / dblFractionBase) / dblBase; integerNumber = trio_floor(workNumber); fractionNumber = workNumber - integerNumber; } @@ -3283,7 +3288,7 @@ TRIO_ARGS6((self, number, flags, width, precision, base), } /* Estimate accuracy */ - integerAdjust = fractionAdjust = 0.5; + integerAdjust = fractionAdjust = TRIO_SUFFIX_LONG(0.5); # if TRIO_FEATURE_ROUNDING if (flags & FLAGS_ROUNDING) { @@ -5021,7 +5026,7 @@ TRIO_ARGS1((ref), /************************************************************************* * trio_get_argument [public] */ -trio_pointer_t +TRIO_CONST trio_pointer_t trio_get_argument TRIO_ARGS1((ref), trio_pointer_t ref) @@ -5029,7 +5034,7 @@ TRIO_ARGS1((ref), #if TRIO_FEATURE_USER_DEFINED assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED); #endif - + return ((trio_reference_t *)ref)->parameter->data.pointer; } diff --git a/trio/trio.h b/trio/trio.h index ad29222d..f7cac345 100644 --- a/trio/trio.h +++ b/trio/trio.h @@ -1,6 +1,6 @@ /************************************************************************* * - * $Id: trio.h,v 1.18 2008/11/09 10:52:26 breese Exp $ + * $Id: trio.h,v 1.19 2009/09/13 10:12:22 breese Exp $ * * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg. * @@ -24,6 +24,10 @@ #if !defined(WITHOUT_TRIO) +#if WANT_FETCHMAIL_CONFIG_H_FOR_TRIO - 0 +/* if used as part of fetchmail, do not include config.h, as that would break + * the regression test. */ + /* * Use autoconf defines if present. Packages using trio must define * HAVE_CONFIG_H as a compiler option themselves. @@ -31,6 +35,7 @@ #if defined(HAVE_CONFIG_H) # include <config.h> #endif +#endif #include "triop.h" @@ -152,55 +157,77 @@ void trio_locale_set_grouping TRIO_PROTO((char *grouping)); #ifdef TRIO_REPLACE_STDIO /* Replace the <stdio.h> functions */ #ifndef HAVE_PRINTF +# undef printf # define printf trio_printf #endif #ifndef HAVE_VPRINTF +# undef vprintf # define vprintf trio_vprintf #endif #ifndef HAVE_FPRINTF +# undef fprintf # define fprintf trio_fprintf #endif #ifndef HAVE_VFPRINTF +# undef vfprintf # define vfprintf trio_vfprintf #endif #ifndef HAVE_SPRINTF +# undef sprintf # define sprintf trio_sprintf #endif #ifndef HAVE_VSPRINTF +# undef vsprintf # define vsprintf trio_vsprintf #endif #ifndef HAVE_SNPRINTF +# undef snprintf # define snprintf trio_snprintf #endif #ifndef HAVE_VSNPRINTF +# undef vsnprintf # define vsnprintf trio_vsnprintf #endif #ifndef HAVE_SCANF +# undef scanf # define scanf trio_scanf #endif #ifndef HAVE_VSCANF +# undef vscanf # define vscanf trio_vscanf #endif #ifndef HAVE_FSCANF +# undef fscanf # define fscanf trio_fscanf #endif #ifndef HAVE_VFSCANF +# undef vfscanf # define vfscanf trio_vfscanf #endif #ifndef HAVE_SSCANF +# undef sscanf # define sscanf trio_sscanf #endif #ifndef HAVE_VSSCANF +# undef vsscanf # define vsscanf trio_vsscanf #endif /* These aren't stdio functions, but we make them look similar */ +#undef dprintf #define dprintf trio_dprintf +#undef vdprintf #define vdprintf trio_vdprintf +#undef aprintf #define aprintf trio_aprintf +#undef vaprintf #define vaprintf trio_vaprintf +#undef asprintf #define asprintf trio_asprintf +#undef vasprintf #define vasprintf trio_vasprintf +#undef dscanf #define dscanf trio_dscanf +#undef vdscanf #define vdscanf trio_vdscanf #endif diff --git a/trio/triodef.h b/trio/triodef.h index 2ce12b8b..95d41d11 100644 --- a/trio/triodef.h +++ b/trio/triodef.h @@ -1,6 +1,6 @@ /************************************************************************* * - * $Id: triodef.h,v 1.33 2009/05/24 11:39:24 breese Exp $ + * $Id: triodef.h,v 1.35 2009/09/20 11:37:14 breese Exp $ * * Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net> * @@ -148,7 +148,7 @@ #if defined(__STDC__) \ || defined(_MSC_EXTENSIONS) \ - || defined(TRIO_COMPILER_BORLAND) + || defined(TRIO_COMPILER_BCB) # define PREDEF_STANDARD_C89 #endif #if defined(__STDC_VERSION__) @@ -311,4 +311,25 @@ typedef void * trio_pointer_t; # define TRIO_COMPILER_SUPPORTS_LL #endif +#if defined(__CYGWIN__) +/* + * Cygwin defines the macros for hosted C99, but does not support certain + * long double math functions. + */ +# include <cygwin/version.h> +# define TRIO_CYGWIN_VERSION_API CYGWIN_VERSION_API_MAJOR * 1000 + \ + CYGWIN_VERSION_API_MINOR +/* + * Please change the version number below when the Cygwin API supports + * long double math functions (powl, fmodl, etc.) + */ +# if TRIO_CYGWIN_VERSION_API < 99999999 +# define TRIO_NO_FLOORL 1 +# define TRIO_NO_CEILL 1 +# define TRIO_NO_POWL 1 +# define TRIO_NO_FMODL 1 +# define TRIO_NO_LOG10L 1 +# endif +#endif + #endif /* TRIO_TRIODEF_H */ diff --git a/trio/triop.h b/trio/triop.h index bc8c5808..fecc37bd 100644 --- a/trio/triop.h +++ b/trio/triop.h @@ -1,6 +1,6 @@ /************************************************************************* * - * $Id: triop.h,v 1.17 2009/05/21 12:52:14 breese Exp $ + * $Id: triop.h,v 1.18 2009/07/05 10:14:07 breese Exp $ * * Copyright (C) 2000 Bjorn Reese and Daniel Stenberg. * @@ -404,7 +404,7 @@ trio_pointer_t trio_register TRIO_PROTO((trio_callback_t callback, const char *n 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)); +TRIO_CONST trio_pointer_t trio_get_argument TRIO_PROTO((trio_pointer_t ref)); /* Modifiers */ int trio_get_width TRIO_PROTO((trio_pointer_t ref)); @@ -429,7 +429,7 @@ 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) */ +int trio_get_spacing TRIO_PROTO((trio_pointer_t ref)); /* (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)); diff --git a/trio/triostr.c b/trio/triostr.c index 069e9225..ce5cc74e 100644 --- a/trio/triostr.c +++ b/trio/triostr.c @@ -1,6 +1,6 @@ /************************************************************************* * - * $Id: triostr.c,v 1.34 2008/11/09 12:17:39 breese Exp $ + * $Id: triostr.c,v 1.36 2010/01/26 13:02:02 breese Exp $ * * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg. * @@ -114,7 +114,7 @@ # endif #endif -#if defined(USE_MATH) +#if defined(USE_MATH) && !defined(TRIO_NO_POWL) # if !defined(HAVE_POWL) # if defined(PREDEF_STANDARD_C99) \ || defined(PREDEF_STANDARD_UNIX03) @@ -160,7 +160,7 @@ struct _trio_string_t */ #if !defined(TRIO_EMBED_STRING) -static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c,v 1.34 2008/11/09 12:17:39 breese Exp $"; +static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c,v 1.36 2010/01/26 13:02:02 breese Exp $"; #endif /************************************************************************* @@ -215,7 +215,7 @@ TRIO_PRIVATE_STRING trio_string_t * internal_string_alloc(TRIO_NOARGS) { trio_string_t *self; - + self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t)); if (self) { @@ -252,7 +252,7 @@ TRIO_ARGS2((self, delta), 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) { @@ -273,7 +273,8 @@ TRIO_ARGS2((self, delta), * used (that is, the size of the string is never decreased). */ #if defined(TRIO_FUNC_STRING_APPEND) \ - || defined(TRIO_FUNC_XSTRING_APPEND) + || defined(TRIO_FUNC_XSTRING_APPEND) \ + || defined(TRIO_FUNC_XSTRING_APPEND_MAX) TRIO_PRIVATE_STRING BOOLEAN_T internal_string_grow_to @@ -297,16 +298,16 @@ TRIO_ARGS1((source), int source) { # if defined(HAVE_TOUPPER) - + return toupper(source); - + # else /* Does not handle locales or non-contiguous alphabetic characters */ return ((source >= (int)'a') && (source <= (int)'z')) ? source - 'a' + 'A' : source; - + # endif } @@ -376,7 +377,7 @@ TRIO_ARGS1((string), @param max Maximum number of characters to count. @return The maximum value of @p max and number of characters in @p string. */ -#if defined(TRIO_FUNC_LENGTH) +#if defined(TRIO_FUNC_LENGTH_MAX) TRIO_PUBLIC_STRING size_t trio_length_max @@ -398,11 +399,11 @@ TRIO_ARGS2((string, max), /** 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 @@ -419,7 +420,7 @@ TRIO_ARGS2((target, source), { assert(target); assert(source); - + return (strcat(target, source) != NULL); } @@ -427,12 +428,12 @@ TRIO_ARGS2((target, source), /** 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). @@ -450,12 +451,12 @@ TRIO_ARGS3((target, max, source), TRIO_CONST char *source) { size_t length; - + assert(target); assert(source); length = trio_length(target); - + if (max > length) { strncat(target, source, max - length - 1); @@ -482,7 +483,7 @@ TRIO_ARGS2((string, substring), { assert(string); assert(substring); - + return (0 != strstr(string, substring)); } @@ -490,11 +491,11 @@ TRIO_ARGS2((string, substring), /** Copy @p source to @p target. - + @param target Target string. @param source Source string. @return Boolean value indicating success or failure. - + @pre @p target must point to a memory chunk with sufficient room to contain the @p source string. @pre No boundary checking is performed, so insufficient memory will @@ -511,7 +512,7 @@ TRIO_ARGS2((target, source), { assert(target); assert(source); - + (void)strcpy(target, source); return TRUE; } @@ -519,15 +520,19 @@ TRIO_ARGS2((target, source), #endif /** - Copy at most @p max characters from @p source to @p target. - + Copy at most @p max - 1 characters from @p source to @p target. + @param target Target string. - @param max Maximum number of characters to append. + @param max Maximum number of characters to append (one of which is + a NUL terminator). In other words @p source must point to at least + @p max - 1 bytes, but @p target must point to at least @p max + bytes. @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). + contain the @p source string and a NUL terminator (at most @p max + bytes total). @pre No boundary checking is performed, so insufficient memory will result in a buffer overrun. @post @p target will be zero terminated. @@ -554,10 +559,10 @@ TRIO_ARGS3((target, max, source), /** Duplicate @p source. - + @param source Source string. @return A copy of the @p source string. - + @post @p target will be zero terminated. */ #if defined(TRIO_FUNC_DUPLICATE) @@ -574,11 +579,11 @@ TRIO_ARGS1((source), /** Duplicate at most @p max characters of @p source. - + @param source Source string. @param max Maximum number of characters to duplicate. @return A copy of the @p source string. - + @post @p target will be zero terminated. */ #if defined(TRIO_FUNC_DUPLICATE_MAX) @@ -606,11 +611,11 @@ TRIO_ARGS2((source, max), /** 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. */ #if defined(TRIO_FUNC_EQUAL) @@ -648,11 +653,11 @@ TRIO_ARGS2((first, second), /** 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. */ #if defined(TRIO_FUNC_EQUAL_CASE) @@ -677,12 +682,12 @@ TRIO_ARGS2((first, second), /** 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. */ #if defined(TRIO_FUNC_EQUAL_CASE_MAX) @@ -708,7 +713,7 @@ TRIO_ARGS3((first, max, second), /** 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. @@ -737,12 +742,12 @@ TRIO_ARGS2((first, second), /** 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. */ #if defined(TRIO_FUNC_EQUAL_MAX) @@ -796,7 +801,7 @@ TRIO_ARGS1((error_number), int error_number) { # if defined(USE_STRERROR) - + return strerror(error_number); # else @@ -808,9 +813,9 @@ TRIO_ARGS1((error_number), return ((error_number < 0) || (error_number >= sys_nerr)) ? "unknown" : sys_errlist[error_number]; - + # else - + return "unknown"; # endif @@ -873,7 +878,7 @@ TRIO_ARGS2((string, type), char ch; assert(string); - + switch (type) { case TRIO_HASH_PLAIN: @@ -964,7 +969,7 @@ TRIO_ARGS1((target), @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. @@ -979,7 +984,7 @@ TRIO_ARGS2((string, pattern), { assert(string); assert(pattern); - + for (; ('*' != *pattern); ++pattern, ++string) { if (NIL == *string) @@ -1004,7 +1009,7 @@ TRIO_ARGS2((string, pattern), } } while (*string++); - + return FALSE; } @@ -1018,7 +1023,7 @@ TRIO_ARGS2((string, pattern), @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. @@ -1033,7 +1038,7 @@ TRIO_ARGS2((string, pattern), { assert(string); assert(pattern); - + for (; ('*' != *pattern); ++pattern, ++string) { if (NIL == *string) @@ -1058,7 +1063,7 @@ TRIO_ARGS2((string, pattern), } } while (*string++); - + return FALSE; } @@ -1086,7 +1091,7 @@ TRIO_ARGS3((target, source, Function), assert(target); assert(source); assert(Function); - + while (*source != NIL) { *target++ = Function(*source++); @@ -1145,7 +1150,7 @@ TRIO_ARGS3((string, max, substring), assert(string); assert(substring); - + size = trio_length(substring); if (size <= max) { @@ -1181,7 +1186,7 @@ TRIO_ARGS2((string, delimiters), TRIO_CONST char *delimiters) { assert(delimiters); - + return strtok(string, delimiters); } @@ -1318,7 +1323,7 @@ TRIO_ARGS2((source, endp), } } } - + value = integer + fraction; if (exponent != 0) { @@ -1408,7 +1413,7 @@ TRIO_ARGS3((string, endp, base), { assert(string); assert((base >= 2) && (base <= 36)); - + return strtol(string, endp, base); } @@ -1428,16 +1433,16 @@ TRIO_ARGS1((source), int source) { # if defined(HAVE_TOLOWER) - + return tolower(source); - + # else /* Does not handle locales or non-contiguous alphabetic characters */ return ((source >= (int)'A') && (source <= (int)'Z')) ? source - 'A' + 'a' : source; - + # endif } @@ -1461,7 +1466,7 @@ TRIO_ARGS3((string, endp, base), { assert(string); assert((base >= 2) && (base <= 36)); - + return strtoul(string, endp, base); } @@ -1521,7 +1526,7 @@ TRIO_ARGS1((target), /** Create a new dynamic string. - + @param initial_size Initial size of the buffer. @return Newly allocated dynamic string, or NULL if memory allocation failed. */ @@ -1556,7 +1561,7 @@ TRIO_ARGS1((initial_size), /** Deallocate the dynamic string and its contents. - + @param self Dynamic string */ #if defined(TRIO_FUNC_STRING_DESTROY) @@ -1567,7 +1572,7 @@ TRIO_ARGS1((self), trio_string_t *self) { assert(self); - + if (self) { trio_destroy(self->content); @@ -1579,11 +1584,11 @@ TRIO_ARGS1((self), /** Get a pointer to the content. - + @param self Dynamic string. @param offset Offset into content. @return Pointer to the content. - + @p Offset can be zero, positive, or negative. If @p offset is zero, then the start of the content will be returned. If @p offset is positive, then a pointer to @p offset number of characters from the beginning of the @@ -1591,7 +1596,7 @@ TRIO_ARGS1((self), number of characters from the ending of the string, starting at the terminating zero, is returned. */ -#if defined(TRIO_FUNCT_STRING_GET) +#if defined(TRIO_FUNC_STRING_GET) TRIO_PUBLIC_STRING char * trio_string_get @@ -1600,7 +1605,7 @@ TRIO_ARGS2((self, offset), int offset) { char *result = NULL; - + assert(self); if (self->content != NULL) @@ -1633,10 +1638,10 @@ TRIO_ARGS2((self, offset), /** 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. */ @@ -1648,7 +1653,7 @@ TRIO_ARGS1((self), trio_string_t *self) { char *result; - + assert(self); result = self->content; @@ -1662,13 +1667,13 @@ TRIO_ARGS1((self), /** 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. @@ -1723,7 +1728,7 @@ TRIO_ARGS1((self), /** 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. @@ -1737,7 +1742,7 @@ TRIO_ARGS2((self, other), trio_string_t *other) { size_t length; - + assert(self); assert(other); @@ -1747,7 +1752,7 @@ TRIO_ARGS2((self, other), trio_copy(&self->content[self->length], other->content); self->length = length; return TRUE; - + error: return FALSE; } @@ -1767,7 +1772,7 @@ TRIO_ARGS2((self, other), TRIO_CONST char *other) { size_t length; - + assert(self); assert(other); @@ -1777,7 +1782,7 @@ TRIO_ARGS2((self, other), trio_copy(&self->content[self->length], other); self->length = length; return TRUE; - + error: return FALSE; } @@ -1805,7 +1810,42 @@ TRIO_ARGS2((self, character), self->content[self->length] = character; self->length++; return TRUE; - + + error: + return FALSE; +} + +#endif + +/* + * trio_xstring_append_max + */ +#if defined(TRIO_FUNC_XSTRING_APPEND_MAX) + +TRIO_PUBLIC_STRING int +trio_xstring_append_max +TRIO_ARGS3((self, other, max), + trio_string_t *self, + TRIO_CONST char *other, + size_t max) +{ + size_t length; + + assert(self); + assert(other); + + length = self->length + trio_length_max(other, max); + if (!internal_string_grow_to(self, length)) + goto error; + + /* + * Pass max + 1 since trio_copy_max copies one character less than + * this from the source to make room for a terminating zero. + */ + trio_copy_max(&self->content[self->length], max + 1, other); + self->length = length; + return TRUE; + error: return FALSE; } @@ -1814,7 +1854,7 @@ TRIO_ARGS2((self, character), /** 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. @@ -1906,7 +1946,7 @@ TRIO_ARGS1((other), trio_string_t *other) { trio_string_t *self; - + assert(other); self = internal_string_alloc(); @@ -1939,7 +1979,7 @@ TRIO_ARGS1((other), TRIO_CONST char *other) { trio_string_t *self; - + assert(other); self = internal_string_alloc(); diff --git a/trio/triostr.h b/trio/triostr.h index 357d192b..847fb723 100644 --- a/trio/triostr.h +++ b/trio/triostr.h @@ -1,6 +1,6 @@ /************************************************************************* * - * $Id: triostr.h,v 1.17 2007/11/11 13:21:49 breese Exp $ + * $Id: triostr.h,v 1.18 2010/01/26 13:02:02 breese Exp $ * * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg. * @@ -206,6 +206,7 @@ enum { # define TRIO_FUNC_XSTRING_APPEND # define TRIO_FUNC_XSTRING_APPEND_CHAR +# define TRIO_FUNC_XSTRING_APPEND_MAX # define TRIO_FUNC_XSTRING_CONTAINS # define TRIO_FUNC_XSTRING_COPY # define TRIO_FUNC_XSTRING_DUPLICATE @@ -601,6 +602,12 @@ trio_xstring_append_char TRIO_PROTO((trio_string_t *self, char character)); #endif +#if defined(TRIO_FUNC_XSTRING_APPEND_MAX) +TRIO_PUBLIC_STRING int +trio_xstring_append_max +TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other, size_t max)); +#endif + #if defined(TRIO_FUNC_XSTRING_CONTAINS) TRIO_PUBLIC_STRING int trio_xstring_contains |