1 /*************************************************************************
3 * $Id: triostr.c,v 1.36 2010/01/26 13:02:02 breese Exp $
5 * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
13 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
14 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
16 ************************************************************************/
18 /*************************************************************************
22 #if defined(HAVE_CONFIG_H)
31 #if defined(TRIO_FUNC_TO_LONG_DOUBLE)
38 /*************************************************************************
42 #if !defined(TRIO_PUBLIC_STRING)
43 # define TRIO_PUBLIC_STRING TRIO_PUBLIC
45 #if !defined(TRIO_PRIVATE_STRING)
46 # define TRIO_PRIVATE_STRING TRIO_PRIVATE
53 # define NIL ((char)0)
56 # define FALSE (1 == 0)
57 # define TRUE (! FALSE)
59 #if !defined(BOOLEAN_T)
60 # define BOOLEAN_T int
64 # if defined(PREDEF_STANDARD_C99)
65 # if defined(TRIO_COMPILER_DECC)
66 # if (TRIO_COMPILER_DECC - 0 > 80000000)
68 * The OSF/1 runtime that comes with the DECC compiler does not support
69 * hexfloats conversion.
79 # if defined(TRIO_COMPILER_VISUALC)
85 #if defined(TRIO_PLATFORM_UNIX)
86 # if defined(PREDEF_STANDARD_UNIX95)
87 # define USE_STRCASECMP
88 # define USE_STRNCASECMP
90 # if defined(TRIO_PLATFORM_SUNOS)
91 # define USE_SYS_ERRLIST
95 # if defined(TRIO_PLATFORM_QNX)
96 # define strcasecmp(x,y) stricmp(x,y)
97 # define strncasecmp(x,y,n) strnicmp(x,y,n)
101 #if defined(TRIO_PLATFORM_WIN32)
102 # define USE_STRCASECMP
103 # if defined(TRIO_PLATFORM_WINCE)
104 # define strcasecmp(x,y) _stricmp(x,y)
106 # define strcasecmp(x,y) strcmpi(x,y)
110 #if !defined(HAVE_CONFIG_H)
111 # if !(defined(TRIO_PLATFORM_SUNOS))
112 # define HAVE_TOLOWER
113 # define HAVE_TOUPPER
117 #if defined(USE_MATH) && !defined(TRIO_NO_POWL)
118 # if !defined(HAVE_POWL)
119 # if defined(PREDEF_STANDARD_C99) \
120 || defined(PREDEF_STANDARD_UNIX03)
123 # if defined(TRIO_COMPILER_VISUALC)
132 #if defined(HAVE_POWL)
133 # define trio_powl(x,y) powl((x),(y))
135 # define trio_powl(x,y) pow((double)(x),(double)(y))
138 #if defined(TRIO_FUNC_TO_UPPER) \
139 || (defined(TRIO_FUNC_EQUAL) && !defined(USE_STRCASECMP)) \
140 || (defined(TRIO_FUNC_EQUAL_MAX) && !defined(USE_STRNCASECMP)) \
141 || defined(TRIO_FUNC_MATCH) \
142 || defined(TRIO_FUNC_TO_LONG_DOUBLE) \
143 || defined(TRIO_FUNC_UPPER)
144 # define TRIO_FUNC_INTERNAL_TO_UPPER
147 /*************************************************************************
151 struct _trio_string_t
158 /*************************************************************************
162 #if !defined(TRIO_EMBED_STRING)
163 static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c,v 1.36 2010/01/26 13:02:02 breese Exp $";
166 /*************************************************************************
167 * Static String Functions
170 #if defined(TRIO_DOCUMENTATION)
171 # include "doc/doc_static.h"
173 /** @addtogroup StaticStrings
178 * internal_duplicate_max
180 #if defined(TRIO_FUNC_DUPLICATE) \
181 || defined(TRIO_FUNC_DUPLICATE_MAX) \
182 || defined(TRIO_FUNC_STRING_DUPLICATE) \
183 || defined(TRIO_FUNC_XSTRING_DUPLICATE)
185 TRIO_PRIVATE_STRING char *
186 internal_duplicate_max
187 TRIO_ARGS2((source, size),
188 TRIO_CONST char *source,
195 /* Make room for string plus a terminating zero */
197 target = trio_create(size);
200 trio_copy_max(target, size, source);
208 * internal_string_alloc
210 #if defined(TRIO_FUNC_STRING_CREATE) \
211 || defined(TRIO_FUNC_STRING_DUPLICATE) \
212 || defined(TRIO_FUNC_XSTRING_DUPLICATE)
214 TRIO_PRIVATE_STRING trio_string_t *
215 internal_string_alloc(TRIO_NOARGS)
219 self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t));
222 self->content = NULL;
232 * internal_string_grow
234 * The size of the string will be increased by 'delta' characters. If
235 * 'delta' is zero, the size will be doubled.
237 #if defined(TRIO_FUNC_STRING_CREATE) \
238 || defined(TRIO_FUNC_STRING_APPEND) \
239 || defined(TRIO_FUNC_XSTRING_APPEND) \
240 || defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
242 TRIO_PRIVATE_STRING BOOLEAN_T
244 TRIO_ARGS2((self, delta),
248 BOOLEAN_T status = FALSE;
252 new_size = (delta == 0)
253 ? ( (self->allocated == 0) ? 1 : self->allocated * 2 )
254 : self->allocated + delta;
256 new_content = (char *)TRIO_REALLOC(self->content, new_size);
259 self->content = new_content;
260 self->allocated = new_size;
269 * internal_string_grow_to
271 * The size of the string will be increased to 'length' plus one characters.
272 * If 'length' is less than the original size, the original size will be
273 * used (that is, the size of the string is never decreased).
275 #if defined(TRIO_FUNC_STRING_APPEND) \
276 || defined(TRIO_FUNC_XSTRING_APPEND) \
277 || defined(TRIO_FUNC_XSTRING_APPEND_MAX)
279 TRIO_PRIVATE_STRING BOOLEAN_T
280 internal_string_grow_to
281 TRIO_ARGS2((self, length),
285 length++; /* Room for terminating zero */
286 return (self->allocated < length)
287 ? internal_string_grow(self, length - self->allocated)
293 #if defined(TRIO_FUNC_INTERNAL_TO_UPPER)
295 TRIO_PRIVATE_STRING TRIO_INLINE int
300 # if defined(HAVE_TOUPPER)
302 return toupper(source);
306 /* Does not handle locales or non-contiguous alphabetic characters */
307 return ((source >= (int)'a') && (source <= (int)'z'))
320 @param size Size of new string.
321 @return Pointer to string, or NULL if allocation failed.
323 #if defined(TRIO_FUNC_CREATE)
325 TRIO_PUBLIC_STRING char *
330 return (char *)TRIO_MALLOC(size);
338 @param string String to be freed.
340 #if defined(TRIO_FUNC_DESTROY)
342 TRIO_PUBLIC_STRING void
356 Count the number of characters in a string.
358 @param string String to measure.
359 @return Number of characters in @p string.
361 #if defined(TRIO_FUNC_LENGTH)
363 TRIO_PUBLIC_STRING size_t
366 TRIO_CONST char *string)
368 return strlen(string);
374 Count at most @p max characters in a string.
376 @param string String to measure.
377 @param max Maximum number of characters to count.
378 @return The maximum value of @p max and number of characters in @p string.
380 #if defined(TRIO_FUNC_LENGTH_MAX)
382 TRIO_PUBLIC_STRING size_t
384 TRIO_ARGS2((string, max),
385 TRIO_CONST char *string,
390 for (i = 0; i < max; ++i)
401 Append @p source at the end of @p target.
403 @param target Target string.
404 @param source Source string.
405 @return Boolean value indicating success or failure.
407 @pre @p target must point to a memory chunk with sufficient room to
408 contain the @p target string and @p source string.
409 @pre No boundary checking is performed, so insufficient memory will
410 result in a buffer overrun.
411 @post @p target will be zero terminated.
413 #if defined(TRIO_FUNC_APPEND)
415 TRIO_PUBLIC_STRING int
417 TRIO_ARGS2((target, source),
419 TRIO_CONST char *source)
424 return (strcat(target, source) != NULL);
430 Append at most @p max characters from @p source to @p target.
432 @param target Target string.
433 @param max Maximum number of characters to append.
434 @param source Source string.
435 @return Boolean value indicating success or failure.
437 @pre @p target must point to a memory chuck with sufficient room to
438 contain the @p target string and the @p source string (at most @p max
440 @pre No boundary checking is performed, so insufficient memory will
441 result in a buffer overrun.
442 @post @p target will be zero terminated.
444 #if defined(TRIO_FUNC_APPEND_MAX)
446 TRIO_PUBLIC_STRING int
448 TRIO_ARGS3((target, max, source),
451 TRIO_CONST char *source)
458 length = trio_length(target);
462 strncat(target, source, max - length - 1);
470 Determine if a string contains a substring.
472 @param string String to be searched.
473 @param substring String to be found.
474 @return Boolean value indicating success or failure.
476 #if defined(TRIO_FUNC_CONTAINS)
478 TRIO_PUBLIC_STRING int
480 TRIO_ARGS2((string, substring),
481 TRIO_CONST char *string,
482 TRIO_CONST char *substring)
487 return (0 != strstr(string, substring));
493 Copy @p source to @p target.
495 @param target Target string.
496 @param source Source string.
497 @return Boolean value indicating success or failure.
499 @pre @p target must point to a memory chunk with sufficient room to
500 contain the @p source string.
501 @pre No boundary checking is performed, so insufficient memory will
502 result in a buffer overrun.
503 @post @p target will be zero terminated.
505 #if defined(TRIO_FUNC_COPY)
507 TRIO_PUBLIC_STRING int
509 TRIO_ARGS2((target, source),
511 TRIO_CONST char *source)
516 (void)strcpy(target, source);
523 Copy at most @p max - 1 characters from @p source to @p target.
525 @param target Target string.
526 @param max Maximum number of characters to append (one of which is
527 a NUL terminator). In other words @p source must point to at least
528 @p max - 1 bytes, but @p target must point to at least @p max
530 @param source Source string.
531 @return Boolean value indicating success or failure.
533 @pre @p target must point to a memory chunk with sufficient room to
534 contain the @p source string and a NUL terminator (at most @p max
536 @pre No boundary checking is performed, so insufficient memory will
537 result in a buffer overrun.
538 @post @p target will be zero terminated.
540 #if defined(TRIO_FUNC_COPY_MAX)
542 TRIO_PUBLIC_STRING int
544 TRIO_ARGS3((target, max, source),
547 TRIO_CONST char *source)
551 assert(max > 0); /* Includes != 0 */
553 (void)strncpy(target, source, max - 1);
554 target[max - 1] = (char)0;
563 @param source Source string.
564 @return A copy of the @p source string.
566 @post @p target will be zero terminated.
568 #if defined(TRIO_FUNC_DUPLICATE)
570 TRIO_PUBLIC_STRING char *
573 TRIO_CONST char *source)
575 return internal_duplicate_max(source, trio_length(source));
581 Duplicate at most @p max characters of @p source.
583 @param source Source string.
584 @param max Maximum number of characters to duplicate.
585 @return A copy of the @p source string.
587 @post @p target will be zero terminated.
589 #if defined(TRIO_FUNC_DUPLICATE_MAX)
591 TRIO_PUBLIC_STRING char *
593 TRIO_ARGS2((source, max),
594 TRIO_CONST char *source,
602 length = trio_length(source);
607 return internal_duplicate_max(source, length);
613 Compare if two strings are equal.
615 @param first First string.
616 @param second Second string.
617 @return Boolean indicating whether the two strings are equal or not.
619 Case-insensitive comparison.
621 #if defined(TRIO_FUNC_EQUAL)
623 TRIO_PUBLIC_STRING int
625 TRIO_ARGS2((first, second),
626 TRIO_CONST char *first,
627 TRIO_CONST char *second)
632 if ((first != NULL) && (second != NULL))
634 # if defined(USE_STRCASECMP)
635 return (0 == strcasecmp(first, second));
637 while ((*first != NIL) && (*second != NIL))
639 if (internal_to_upper(*first) != internal_to_upper(*second))
646 return ((*first == NIL) && (*second == NIL));
655 Compare if two strings are equal.
657 @param first First string.
658 @param second Second string.
659 @return Boolean indicating whether the two strings are equal or not.
661 Case-sensitive comparison.
663 #if defined(TRIO_FUNC_EQUAL_CASE)
665 TRIO_PUBLIC_STRING int
667 TRIO_ARGS2((first, second),
668 TRIO_CONST char *first,
669 TRIO_CONST char *second)
674 if ((first != NULL) && (second != NULL))
676 return (0 == strcmp(first, second));
684 Compare if two strings up until the first @p max characters are equal.
686 @param first First string.
687 @param max Maximum number of characters to compare.
688 @param second Second string.
689 @return Boolean indicating whether the two strings are equal or not.
691 Case-sensitive comparison.
693 #if defined(TRIO_FUNC_EQUAL_CASE_MAX)
695 TRIO_PUBLIC_STRING int
697 TRIO_ARGS3((first, max, second),
698 TRIO_CONST char *first,
700 TRIO_CONST char *second)
705 if ((first != NULL) && (second != NULL))
707 return (0 == strncmp(first, second, max));
715 Compare if two strings are equal.
717 @param first First string.
718 @param second Second string.
719 @return Boolean indicating whether the two strings are equal or not.
721 Collating characters are considered equal.
723 #if defined(TRIO_FUNC_EQUAL_LOCALE)
725 TRIO_PUBLIC_STRING int
727 TRIO_ARGS2((first, second),
728 TRIO_CONST char *first,
729 TRIO_CONST char *second)
734 # if defined(LC_COLLATE)
735 return (strcoll(first, second) == 0);
737 return trio_equal(first, second);
744 Compare if two strings up until the first @p max characters are equal.
746 @param first First string.
747 @param max Maximum number of characters to compare.
748 @param second Second string.
749 @return Boolean indicating whether the two strings are equal or not.
751 Case-insensitive comparison.
753 #if defined(TRIO_FUNC_EQUAL_MAX)
755 TRIO_PUBLIC_STRING int
757 TRIO_ARGS3((first, max, second),
758 TRIO_CONST char *first,
760 TRIO_CONST char *second)
765 if ((first != NULL) && (second != NULL))
767 # if defined(USE_STRNCASECMP)
768 return (0 == strncasecmp(first, second, max));
770 /* Not adequately tested yet */
772 while ((*first != NIL) && (*second != NIL) && (cnt <= max))
774 if (internal_to_upper(*first) != internal_to_upper(*second))
782 return ((cnt == max) || ((*first == NIL) && (*second == NIL)));
791 Provide a textual description of an error code (errno).
793 @param error_number Error number.
794 @return Textual description of @p error_number.
796 #if defined(TRIO_FUNC_ERROR)
798 TRIO_PUBLIC_STRING TRIO_CONST char *
800 TRIO_ARGS1((error_number),
803 # if defined(USE_STRERROR)
805 return strerror(error_number);
808 # if defined(USE_SYS_ERRLIST)
810 extern char *sys_errlist[];
813 return ((error_number < 0) || (error_number >= sys_nerr))
815 : sys_errlist[error_number];
828 Format the date/time according to @p format.
830 @param target Target string.
831 @param max Maximum number of characters to format.
832 @param format Formatting string.
833 @param datetime Date/time structure.
834 @return Number of formatted characters.
836 The formatting string accepts the same specifiers as the standard C
839 #if defined(TRIO_FUNC_FORMAT_DATE_MAX)
841 TRIO_PUBLIC_STRING size_t
843 TRIO_ARGS4((target, max, format, datetime),
846 TRIO_CONST char *format,
847 TRIO_CONST struct tm *datetime)
854 return strftime(target, max, format, datetime);
860 Calculate a hash value for a string.
862 @param string String to be calculated on.
863 @param type Hash function.
864 @return Calculated hash value.
866 @p type can be one of the following
867 @li @c TRIO_HASH_PLAIN Plain hash function.
869 #if defined(TRIO_FUNC_HASH)
871 TRIO_PUBLIC_STRING unsigned long
873 TRIO_ARGS2((string, type),
874 TRIO_CONST char *string,
877 unsigned long value = 0L;
884 case TRIO_HASH_PLAIN:
885 while ( (ch = *string++) != NIL )
888 value += (unsigned long)ch;
901 Find first occurrence of a character in a string.
903 @param string String to be searched.
904 @param character Character to be found.
905 @return A pointer to the found character, or NULL if character was not found.
907 #if defined(TRIO_FUNC_INDEX)
909 TRIO_PUBLIC_STRING char *
911 TRIO_ARGS2((string, character),
912 TRIO_CONST char *string,
917 return strchr(string, character);
923 Find last occurrence of a character in a string.
925 @param string String to be searched.
926 @param character Character to be found.
927 @return A pointer to the found character, or NULL if character was not found.
929 #if defined(TRIO_FUNC_INDEX_LAST)
931 TRIO_PUBLIC_STRING char *
933 TRIO_ARGS2((string, character),
934 TRIO_CONST char *string,
939 return strchr(string, character);
945 Convert the alphabetic letters in the string to lower-case.
947 @param target String to be converted.
948 @return Number of processed characters (converted or not).
950 #if defined(TRIO_FUNC_LOWER)
952 TRIO_PUBLIC_STRING int
959 return trio_span_function(target, target, trio_to_lower);
965 Compare two strings using wildcards.
967 @param string String to be searched.
968 @param pattern Pattern, including wildcards, to search for.
969 @return Boolean value indicating success or failure.
971 Case-insensitive comparison.
973 The following wildcards can be used
974 @li @c * Match any number of characters.
975 @li @c ? Match a single character.
977 #if defined(TRIO_FUNC_MATCH)
979 TRIO_PUBLIC_STRING int
981 TRIO_ARGS2((string, pattern),
982 TRIO_CONST char *string,
983 TRIO_CONST char *pattern)
988 for (; ('*' != *pattern); ++pattern, ++string)
992 return (NIL == *pattern);
994 if ((internal_to_upper((int)*string) != internal_to_upper((int)*pattern))
995 && ('?' != *pattern))
1000 /* two-line patch to prevent *too* much recursiveness: */
1001 while ('*' == pattern[1])
1006 if ( trio_match(string, &pattern[1]) )
1019 Compare two strings using wildcards.
1021 @param string String to be searched.
1022 @param pattern Pattern, including wildcards, to search for.
1023 @return Boolean value indicating success or failure.
1025 Case-sensitive comparison.
1027 The following wildcards can be used
1028 @li @c * Match any number of characters.
1029 @li @c ? Match a single character.
1031 #if defined(TRIO_FUNC_MATCH_CASE)
1033 TRIO_PUBLIC_STRING int
1035 TRIO_ARGS2((string, pattern),
1036 TRIO_CONST char *string,
1037 TRIO_CONST char *pattern)
1042 for (; ('*' != *pattern); ++pattern, ++string)
1046 return (NIL == *pattern);
1048 if ((*string != *pattern)
1049 && ('?' != *pattern))
1054 /* two-line patch to prevent *too* much recursiveness: */
1055 while ('*' == pattern[1])
1060 if ( trio_match_case(string, &pattern[1]) )
1073 Execute a function on each character in string.
1075 @param target Target string.
1076 @param source Source string.
1077 @param Function Function to be executed.
1078 @return Number of processed characters.
1080 #if defined(TRIO_FUNC_SPAN_FUNCTION)
1082 TRIO_PUBLIC_STRING size_t
1084 TRIO_ARGS3((target, source, Function),
1086 TRIO_CONST char *source,
1087 int (*Function) TRIO_PROTO((int)))
1095 while (*source != NIL)
1097 *target++ = Function(*source++);
1106 Search for a substring in a string.
1108 @param string String to be searched.
1109 @param substring String to be found.
1110 @return Pointer to first occurrence of @p substring in @p string, or NULL
1111 if no match was found.
1113 #if defined(TRIO_FUNC_SUBSTRING)
1115 TRIO_PUBLIC_STRING char *
1117 TRIO_ARGS2((string, substring),
1118 TRIO_CONST char *string,
1119 TRIO_CONST char *substring)
1124 return strstr(string, substring);
1130 Search for a substring in the first @p max characters of a string.
1132 @param string String to be searched.
1133 @param max Maximum characters to be searched.
1134 @param substring String to be found.
1135 @return Pointer to first occurrence of @p substring in @p string, or NULL
1136 if no match was found.
1138 #if defined(TRIO_FUNC_SUBSTRING_MAX)
1140 TRIO_PUBLIC_STRING char *
1142 TRIO_ARGS3((string, max, substring),
1143 TRIO_CONST char *string,
1145 TRIO_CONST char *substring)
1149 char *result = NULL;
1154 size = trio_length(substring);
1157 for (count = 0; count <= max - size; count++)
1159 if (trio_equal_max(substring, size, &string[count]))
1161 result = (char *)&string[count];
1174 @param string String to be tokenized.
1175 @param delimiters String containing list of delimiting characters.
1176 @return Start of new token.
1178 @warning @p string will be destroyed.
1180 #if defined(TRIO_FUNC_TOKENIZE)
1182 TRIO_PUBLIC_STRING char *
1184 TRIO_ARGS2((string, delimiters),
1186 TRIO_CONST char *delimiters)
1190 return strtok(string, delimiters);
1196 Convert string to floating-point number.
1198 @param source String to be converted.
1199 @param endp Pointer to end of the converted string.
1200 @return A floating-point number.
1202 The following Extended Backus-Naur form is used
1204 double ::= [ <sign> ]
1206 <number> <decimal_point> <number> |
1207 <decimal_point> <number> )
1208 [ <exponential> [ <sign> ] <number> ]
1209 number ::= 1*( <digit> )
1210 digit ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )
1211 exponential ::= ( 'e' | 'E' )
1212 sign ::= ( '-' | '+' )
1213 decimal_point ::= '.'
1216 #if defined(TRIO_FUNC_TO_LONG_DOUBLE)
1218 /* FIXME: Add EBNF for hex-floats */
1219 TRIO_PUBLIC_STRING trio_long_double_t
1221 TRIO_ARGS2((source, endp),
1222 TRIO_CONST char *source,
1225 # if defined(USE_STRTOLD)
1226 return strtold(source, endp);
1228 int isNegative = FALSE;
1229 int isExponentNegative = FALSE;
1230 trio_long_double_t integer = 0.0;
1231 trio_long_double_t fraction = 0.0;
1232 unsigned long exponent = 0;
1233 trio_long_double_t base;
1234 trio_long_double_t fracdiv = 1.0;
1235 trio_long_double_t value = 0.0;
1237 /* First try hex-floats */
1238 if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X')))
1242 while (isxdigit((int)*source))
1245 integer += (isdigit((int)*source)
1247 : 10 + (internal_to_upper((int)*source) - 'A'));
1253 while (isxdigit((int)*source))
1256 fraction += fracdiv * (isdigit((int)*source)
1258 : 10 + (internal_to_upper((int)*source) - 'A'));
1261 if ((*source == 'p') || (*source == 'P'))
1264 if ((*source == '+') || (*source == '-'))
1266 isExponentNegative = (*source == '-');
1269 while (isdigit((int)*source))
1272 exponent += (*source - '0');
1277 /* For later use with exponent */
1280 else /* Then try normal decimal floats */
1283 isNegative = (*source == '-');
1285 if ((*source == '+') || (*source == '-'))
1289 while (isdigit((int)*source))
1292 integer += (*source - '0');
1298 source++; /* skip decimal point */
1299 while (isdigit((int)*source))
1302 fraction += (*source - '0') * fracdiv;
1306 if ((*source == 'e')
1314 source++; /* Skip exponential indicator */
1315 isExponentNegative = (*source == '-');
1316 if ((*source == '+') || (*source == '-'))
1318 while (isdigit((int)*source))
1320 exponent *= (int)base;
1321 exponent += (*source - '0');
1327 value = integer + fraction;
1330 if (isExponentNegative)
1331 value /= trio_powl(base, (trio_long_double_t)exponent);
1333 value *= trio_powl(base, (trio_long_double_t)exponent);
1339 *endp = (char *)source;
1347 Convert string to floating-point number.
1349 @param source String to be converted.
1350 @param endp Pointer to end of the converted string.
1351 @return A floating-point number.
1353 See @ref trio_to_long_double.
1355 #if defined(TRIO_FUNC_TO_DOUBLE)
1357 TRIO_PUBLIC_STRING double
1359 TRIO_ARGS2((source, endp),
1360 TRIO_CONST char *source,
1363 #if defined(USE_STRTOD)
1364 return strtod(source, endp);
1366 return (double)trio_to_long_double(source, endp);
1373 Convert string to floating-point number.
1375 @param source String to be converted.
1376 @param endp Pointer to end of the converted string.
1377 @return A floating-point number.
1379 See @ref trio_to_long_double.
1381 #if defined(TRIO_FUNC_TO_FLOAT)
1383 TRIO_PUBLIC_STRING float
1385 TRIO_ARGS2((source, endp),
1386 TRIO_CONST char *source,
1389 # if defined(USE_STRTOF)
1390 return strtof(source, endp);
1392 return (float)trio_to_long_double(source, endp);
1399 Convert string to signed integer.
1401 @param string String to be converted.
1402 @param endp Pointer to end of converted string.
1403 @param base Radix number of number.
1405 #if defined(TRIO_FUNC_TO_LONG)
1407 TRIO_PUBLIC_STRING long
1409 TRIO_ARGS3((string, endp, base),
1410 TRIO_CONST char *string,
1415 assert((base >= 2) && (base <= 36));
1417 return strtol(string, endp, base);
1423 Convert one alphabetic letter to lower-case.
1425 @param source The letter to be converted.
1426 @return The converted letter.
1428 #if defined(TRIO_FUNC_TO_LOWER)
1430 TRIO_PUBLIC_STRING int
1432 TRIO_ARGS1((source),
1435 # if defined(HAVE_TOLOWER)
1437 return tolower(source);
1441 /* Does not handle locales or non-contiguous alphabetic characters */
1442 return ((source >= (int)'A') && (source <= (int)'Z'))
1443 ? source - 'A' + 'a'
1452 Convert string to unsigned integer.
1454 @param string String to be converted.
1455 @param endp Pointer to end of converted string.
1456 @param base Radix number of number.
1458 #if defined(TRIO_FUNC_TO_UNSIGNED_LONG)
1460 TRIO_PUBLIC_STRING unsigned long
1461 trio_to_unsigned_long
1462 TRIO_ARGS3((string, endp, base),
1463 TRIO_CONST char *string,
1468 assert((base >= 2) && (base <= 36));
1470 return strtoul(string, endp, base);
1476 Convert one alphabetic letter to upper-case.
1478 @param source The letter to be converted.
1479 @return The converted letter.
1481 #if defined(TRIO_FUNC_TO_UPPER)
1483 TRIO_PUBLIC_STRING int
1485 TRIO_ARGS1((source),
1488 return internal_to_upper(source);
1494 Convert the alphabetic letters in the string to upper-case.
1496 @param target The string to be converted.
1497 @return The number of processed characters (converted or not).
1499 #if defined(TRIO_FUNC_UPPER)
1501 TRIO_PUBLIC_STRING int
1503 TRIO_ARGS1((target),
1508 return trio_span_function(target, target, internal_to_upper);
1513 /** @} End of StaticStrings */
1516 /*************************************************************************
1517 * Dynamic String Functions
1520 #if defined(TRIO_DOCUMENTATION)
1521 # include "doc/doc_dynamic.h"
1523 /** @addtogroup DynamicStrings
1528 Create a new dynamic string.
1530 @param initial_size Initial size of the buffer.
1531 @return Newly allocated dynamic string, or NULL if memory allocation failed.
1533 #if defined(TRIO_FUNC_STRING_CREATE)
1535 TRIO_PUBLIC_STRING trio_string_t *
1537 TRIO_ARGS1((initial_size),
1540 trio_string_t *self;
1542 self = internal_string_alloc();
1545 if (internal_string_grow(self,
1546 (size_t)((initial_size > 0) ? initial_size : 1)))
1548 self->content[0] = (char)0;
1549 self->allocated = initial_size;
1553 trio_string_destroy(self);
1563 Deallocate the dynamic string and its contents.
1565 @param self Dynamic string
1567 #if defined(TRIO_FUNC_STRING_DESTROY)
1569 TRIO_PUBLIC_STRING void
1572 trio_string_t *self)
1578 trio_destroy(self->content);
1586 Get a pointer to the content.
1588 @param self Dynamic string.
1589 @param offset Offset into content.
1590 @return Pointer to the content.
1592 @p Offset can be zero, positive, or negative. If @p offset is zero,
1593 then the start of the content will be returned. If @p offset is positive,
1594 then a pointer to @p offset number of characters from the beginning of the
1595 content is returned. If @p offset is negative, then a pointer to @p offset
1596 number of characters from the ending of the string, starting at the
1597 terminating zero, is returned.
1599 #if defined(TRIO_FUNC_STRING_GET)
1601 TRIO_PUBLIC_STRING char *
1603 TRIO_ARGS2((self, offset),
1604 trio_string_t *self,
1607 char *result = NULL;
1611 if (self->content != NULL)
1613 if (self->length == 0)
1615 (void)trio_string_length(self);
1619 if (offset > (int)self->length)
1621 offset = self->length;
1626 offset += self->length + 1;
1632 result = &(self->content[offset]);
1640 Extract the content.
1642 @param self Dynamic String
1643 @return Content of dynamic string.
1645 The content is removed from the dynamic string. This enables destruction
1646 of the dynamic string without deallocation of the content.
1648 #if defined(TRIO_FUNC_STRING_EXTRACT)
1650 TRIO_PUBLIC_STRING char *
1653 trio_string_t *self)
1659 result = self->content;
1660 /* FIXME: Allocate new empty buffer? */
1661 self->content = NULL;
1662 self->length = self->allocated = 0;
1669 Set the content of the dynamic string.
1671 @param self Dynamic String
1672 @param buffer The new content.
1674 Sets the content of the dynamic string to a copy @p buffer.
1675 An existing content will be deallocated first, if necessary.
1678 This function will make a copy of @p buffer.
1679 You are responsible for deallocating @p buffer yourself.
1681 #if defined(TRIO_FUNC_XSTRING_SET)
1683 TRIO_PUBLIC_STRING void
1685 TRIO_ARGS2((self, buffer),
1686 trio_string_t *self,
1691 trio_destroy(self->content);
1692 self->content = trio_duplicate(buffer);
1700 #if defined(TRIO_FUNC_STRING_SIZE)
1702 TRIO_PUBLIC_STRING int
1705 trio_string_t *self)
1709 return self->allocated;
1715 * trio_string_terminate
1717 #if defined(TRIO_FUNC_STRING_TERMINATE)
1719 TRIO_PUBLIC_STRING void
1720 trio_string_terminate
1722 trio_string_t *self)
1724 trio_xstring_append_char(self, 0);
1730 Append the second string to the first.
1732 @param self Dynamic string to be modified.
1733 @param other Dynamic string to copy from.
1734 @return Boolean value indicating success or failure.
1736 #if defined(TRIO_FUNC_STRING_APPEND)
1738 TRIO_PUBLIC_STRING int
1740 TRIO_ARGS2((self, other),
1741 trio_string_t *self,
1742 trio_string_t *other)
1749 length = self->length + other->length;
1750 if (!internal_string_grow_to(self, length))
1752 trio_copy(&self->content[self->length], other->content);
1753 self->length = length;
1764 * trio_xstring_append
1766 #if defined(TRIO_FUNC_XSTRING_APPEND)
1768 TRIO_PUBLIC_STRING int
1770 TRIO_ARGS2((self, other),
1771 trio_string_t *self,
1772 TRIO_CONST char *other)
1779 length = self->length + trio_length(other);
1780 if (!internal_string_grow_to(self, length))
1782 trio_copy(&self->content[self->length], other);
1783 self->length = length;
1793 * trio_xstring_append_char
1795 #if defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
1797 TRIO_PUBLIC_STRING int
1798 trio_xstring_append_char
1799 TRIO_ARGS2((self, character),
1800 trio_string_t *self,
1805 if ((int)self->length >= trio_string_size(self))
1807 if (!internal_string_grow(self, 0))
1810 self->content[self->length] = character;
1821 * trio_xstring_append_max
1823 #if defined(TRIO_FUNC_XSTRING_APPEND_MAX)
1825 TRIO_PUBLIC_STRING int
1826 trio_xstring_append_max
1827 TRIO_ARGS3((self, other, max),
1828 trio_string_t *self,
1829 TRIO_CONST char *other,
1837 length = self->length + trio_length_max(other, max);
1838 if (!internal_string_grow_to(self, length))
1842 * Pass max + 1 since trio_copy_max copies one character less than
1843 * this from the source to make room for a terminating zero.
1845 trio_copy_max(&self->content[self->length], max + 1, other);
1846 self->length = length;
1856 Search for the first occurrence of second parameter in the first.
1858 @param self Dynamic string to be modified.
1859 @param other Dynamic string to copy from.
1860 @return Boolean value indicating success or failure.
1862 #if defined(TRIO_FUNC_STRING_CONTAINS)
1864 TRIO_PUBLIC_STRING int
1865 trio_string_contains
1866 TRIO_ARGS2((self, other),
1867 trio_string_t *self,
1868 trio_string_t *other)
1873 return trio_contains(self->content, other->content);
1879 * trio_xstring_contains
1881 #if defined(TRIO_FUNC_XSTRING_CONTAINS)
1883 TRIO_PUBLIC_STRING int
1884 trio_xstring_contains
1885 TRIO_ARGS2((self, other),
1886 trio_string_t *self,
1887 TRIO_CONST char *other)
1892 return trio_contains(self->content, other);
1900 #if defined(TRIO_FUNC_STRING_COPY)
1902 TRIO_PUBLIC_STRING int
1904 TRIO_ARGS2((self, other),
1905 trio_string_t *self,
1906 trio_string_t *other)
1912 return trio_string_append(self, other);
1921 #if defined(TRIO_FUNC_XSTRING_COPY)
1923 TRIO_PUBLIC_STRING int
1925 TRIO_ARGS2((self, other),
1926 trio_string_t *self,
1927 TRIO_CONST char *other)
1933 return trio_xstring_append(self, other);
1939 * trio_string_duplicate
1941 #if defined(TRIO_FUNC_STRING_DUPLICATE)
1943 TRIO_PUBLIC_STRING trio_string_t *
1944 trio_string_duplicate
1946 trio_string_t *other)
1948 trio_string_t *self;
1952 self = internal_string_alloc();
1955 self->content = internal_duplicate_max(other->content, other->length);
1958 self->length = other->length;
1959 self->allocated = self->length + 1;
1963 self->length = self->allocated = 0;
1972 * trio_xstring_duplicate
1974 #if defined(TRIO_FUNC_XSTRING_DUPLICATE)
1976 TRIO_PUBLIC_STRING trio_string_t *
1977 trio_xstring_duplicate
1979 TRIO_CONST char *other)
1981 trio_string_t *self;
1985 self = internal_string_alloc();
1988 self->content = internal_duplicate_max(other, trio_length(other));
1991 self->length = trio_length(self->content);
1992 self->allocated = self->length + 1;
1996 self->length = self->allocated = 0;
2007 #if defined(TRIO_FUNC_STRING_EQUAL)
2009 TRIO_PUBLIC_STRING int
2011 TRIO_ARGS2((self, other),
2012 trio_string_t *self,
2013 trio_string_t *other)
2018 return trio_equal(self->content, other->content);
2025 * trio_xstring_equal
2027 #if defined(TRIO_FUNC_XSTRING_EQUAL)
2029 TRIO_PUBLIC_STRING int
2031 TRIO_ARGS2((self, other),
2032 trio_string_t *self,
2033 TRIO_CONST char *other)
2038 return trio_equal(self->content, other);
2044 * trio_string_equal_max
2046 #if defined(TRIO_FUNC_STRING_EQUAL_MAX)
2048 TRIO_PUBLIC_STRING int
2049 trio_string_equal_max
2050 TRIO_ARGS3((self, max, other),
2051 trio_string_t *self,
2053 trio_string_t *other)
2058 return trio_equal_max(self->content, max, other->content);
2063 * trio_xstring_equal_max
2065 #if defined(TRIO_FUNC_XSTRING_EQUAL_MAX)
2067 TRIO_PUBLIC_STRING int
2068 trio_xstring_equal_max
2069 TRIO_ARGS3((self, max, other),
2070 trio_string_t *self,
2072 TRIO_CONST char *other)
2077 return trio_equal_max(self->content, max, other);
2083 * trio_string_equal_case
2085 #if defined(TRIO_FUNC_STRING_EQUAL_CASE)
2087 TRIO_PUBLIC_STRING int
2088 trio_string_equal_case
2089 TRIO_ARGS2((self, other),
2090 trio_string_t *self,
2091 trio_string_t *other)
2096 return trio_equal_case(self->content, other->content);
2102 * trio_xstring_equal_case
2104 #if defined(TRIO_FUNC_XSTRING_EQUAL_CASE)
2106 TRIO_PUBLIC_STRING int
2107 trio_xstring_equal_case
2108 TRIO_ARGS2((self, other),
2109 trio_string_t *self,
2110 TRIO_CONST char *other)
2115 return trio_equal_case(self->content, other);
2121 * trio_string_equal_case_max
2123 #if defined(TRIO_FUNC_STRING_EQUAL_CASE_MAX)
2125 TRIO_PUBLIC_STRING int
2126 trio_string_equal_case_max
2127 TRIO_ARGS3((self, max, other),
2128 trio_string_t *self,
2130 trio_string_t *other)
2135 return trio_equal_case_max(self->content, max, other->content);
2141 * trio_xstring_equal_case_max
2143 #if defined(TRIO_FUNC_XSTRING_EQUAL_CASE_MAX)
2145 TRIO_PUBLIC_STRING int
2146 trio_xstring_equal_case_max
2147 TRIO_ARGS3((self, max, other),
2148 trio_string_t *self,
2150 TRIO_CONST char *other)
2155 return trio_equal_case_max(self->content, max, other);
2161 * trio_string_format_data_max
2163 #if defined(TRIO_FUNC_STRING_FORMAT_DATE_MAX)
2165 TRIO_PUBLIC_STRING size_t
2166 trio_string_format_date_max
2167 TRIO_ARGS4((self, max, format, datetime),
2168 trio_string_t *self,
2170 TRIO_CONST char *format,
2171 TRIO_CONST struct tm *datetime)
2175 return trio_format_date_max(self->content, max, format, datetime);
2183 #if defined(TRIO_FUNC_STRING_INDEX)
2185 TRIO_PUBLIC_STRING char *
2187 TRIO_ARGS2((self, character),
2188 trio_string_t *self,
2193 return trio_index(self->content, character);
2199 * trio_string_index_last
2201 #if defined(TRIO_FUNC_STRING_INDEX_LAST)
2203 TRIO_PUBLIC_STRING char *
2204 trio_string_index_last
2205 TRIO_ARGS2((self, character),
2206 trio_string_t *self,
2211 return trio_index_last(self->content, character);
2217 * trio_string_length
2219 #if defined(TRIO_FUNC_STRING_LENGTH)
2221 TRIO_PUBLIC_STRING int
2224 trio_string_t *self)
2228 if (self->length == 0)
2230 self->length = trio_length(self->content);
2232 return self->length;
2240 #if defined(TRIO_FUNC_STRING_LOWER)
2242 TRIO_PUBLIC_STRING int
2245 trio_string_t *self)
2249 return trio_lower(self->content);
2257 #if defined(TRIO_FUNC_STRING_MATCH)
2259 TRIO_PUBLIC_STRING int
2261 TRIO_ARGS2((self, other),
2262 trio_string_t *self,
2263 trio_string_t *other)
2268 return trio_match(self->content, other->content);
2274 * trio_xstring_match
2276 #if defined(TRIO_FUNC_XSTRING_MATCH)
2278 TRIO_PUBLIC_STRING int
2280 TRIO_ARGS2((self, other),
2281 trio_string_t *self,
2282 TRIO_CONST char *other)
2287 return trio_match(self->content, other);
2293 * trio_string_match_case
2295 #if defined(TRIO_FUNC_STRING_MATCH_CASE)
2297 TRIO_PUBLIC_STRING int
2298 trio_string_match_case
2299 TRIO_ARGS2((self, other),
2300 trio_string_t *self,
2301 trio_string_t *other)
2306 return trio_match_case(self->content, other->content);
2312 * trio_xstring_match_case
2314 #if defined(TRIO_FUNC_XSTRING_MATCH_CASE)
2316 TRIO_PUBLIC_STRING int
2317 trio_xstring_match_case
2318 TRIO_ARGS2((self, other),
2319 trio_string_t *self,
2320 TRIO_CONST char *other)
2325 return trio_match_case(self->content, other);
2331 * trio_string_substring
2333 #if defined(TRIO_FUNC_STRING_SUBSTRING)
2335 TRIO_PUBLIC_STRING char *
2336 trio_string_substring
2337 TRIO_ARGS2((self, other),
2338 trio_string_t *self,
2339 trio_string_t *other)
2344 return trio_substring(self->content, other->content);
2350 * trio_xstring_substring
2352 #if defined(TRIO_FUNC_XSTRING_SUBSTRING)
2354 TRIO_PUBLIC_STRING char *
2355 trio_xstring_substring
2356 TRIO_ARGS2((self, other),
2357 trio_string_t *self,
2358 TRIO_CONST char *other)
2363 return trio_substring(self->content, other);
2371 #if defined(TRIO_FUNC_STRING_UPPER)
2373 TRIO_PUBLIC_STRING int
2376 trio_string_t *self)
2380 return trio_upper(self->content);
2385 /** @} End of DynamicStrings */