1 /*************************************************************************
3 * $Id: triostr.c,v 1.19 2003/03/01 15:34: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 /*************************************************************************
30 /*************************************************************************
34 #if !defined(TRIO_STRING_PUBLIC)
35 # define TRIO_STRING_PUBLIC TRIO_PUBLIC
37 #if !defined(TRIO_STRING_PRIVATE)
38 # define TRIO_STRING_PRIVATE TRIO_PRIVATE
45 # define NIL ((char)0)
48 # define FALSE (1 == 0)
49 # define TRUE (! FALSE)
51 #if !defined(BOOLEAN_T)
52 # define BOOLEAN_T int
55 #if defined(TRIO_COMPILER_SUPPORTS_C99)
58 #elif defined(TRIO_COMPILER_MSVC)
62 #if defined(TRIO_PLATFORM_UNIX)
63 # define USE_STRCASECMP
64 # define USE_STRNCASECMP
65 # if defined(TRIO_PLATFORM_SUNOS)
66 # define USE_SYS_ERRLIST
70 # if defined(TRIO_PLATFORM_QNX)
71 # define strcasecmp(x,y) stricmp(x,y)
72 # define strncasecmp(x,y,n) strnicmp(x,y,n)
74 #elif defined(TRIO_PLATFORM_WIN32)
75 # define USE_STRCASECMP
76 # define strcasecmp(x,y) strcmpi(x,y)
79 #if !(defined(TRIO_PLATFORM_SUNOS))
84 /*************************************************************************
95 /*************************************************************************
99 #if !defined(TRIO_MINIMAL)
100 static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c,v 1.19 2003/03/01 15:34:02 breese Exp $";
103 /*************************************************************************
104 * Static String Functions
107 #if defined(TRIO_DOCUMENTATION)
108 # include "doc/doc_static.h"
110 /** @addtogroup StaticStrings
117 @param size Size of new string.
118 @return Pointer to string, or NULL if allocation failed.
120 TRIO_STRING_PUBLIC char *
125 return (char *)TRIO_MALLOC(size);
132 @param string String to be freed.
134 TRIO_STRING_PUBLIC void
147 Count the number of characters in a string.
149 @param string String to measure.
150 @return Number of characters in @string.
152 TRIO_STRING_PUBLIC size_t
155 TRIO_CONST char *string)
157 return strlen(string);
161 #if !defined(TRIO_MINIMAL)
163 Append @p source at the end of @p target.
165 @param target Target string.
166 @param source Source string.
167 @return Boolean value indicating success or failure.
169 @pre @p target must point to a memory chunk with sufficient room to
170 contain the @p target string and @p source string.
171 @pre No boundary checking is performed, so insufficient memory will
172 result in a buffer overrun.
173 @post @p target will be zero terminated.
175 TRIO_STRING_PUBLIC int
177 TRIO_ARGS2((target, source),
179 TRIO_CONST char *source)
184 return (strcat(target, source) != NULL);
186 #endif /* !defined(TRIO_MINIMAL) */
188 #if !defined(TRIO_MINIMAL)
190 Append at most @p max characters from @p source to @p target.
192 @param target Target string.
193 @param max Maximum number of characters to append.
194 @param source Source string.
195 @return Boolean value indicating success or failure.
197 @pre @p target must point to a memory chuck with sufficient room to
198 contain the @p target string and the @p source string (at most @p max
200 @pre No boundary checking is performed, so insufficient memory will
201 result in a buffer overrun.
202 @post @p target will be zero terminated.
204 TRIO_STRING_PUBLIC int
206 TRIO_ARGS3((target, max, source),
209 TRIO_CONST char *source)
216 length = trio_length(target);
220 strncat(target, source, max - length - 1);
224 #endif /* !defined(TRIO_MINIMAL) */
227 #if !defined(TRIO_MINIMAL)
229 Determine if a string contains a substring.
231 @param string String to be searched.
232 @param substring String to be found.
233 @return Boolean value indicating success or failure.
235 TRIO_STRING_PUBLIC int
237 TRIO_ARGS2((string, substring),
238 TRIO_CONST char *string,
239 TRIO_CONST char *substring)
244 return (0 != strstr(string, substring));
246 #endif /* !defined(TRIO_MINIMAL) */
249 #if !defined(TRIO_MINIMAL)
251 Copy @p source to @p target.
253 @param target Target string.
254 @param source Source string.
255 @return Boolean value indicating success or failure.
257 @pre @p target must point to a memory chunk with sufficient room to
258 contain the @p source string.
259 @pre No boundary checking is performed, so insufficient memory will
260 result in a buffer overrun.
261 @post @p target will be zero terminated.
263 TRIO_STRING_PUBLIC int
265 TRIO_ARGS2((target, source),
267 TRIO_CONST char *source)
272 (void)strcpy(target, source);
275 #endif /* !defined(TRIO_MINIMAL) */
279 Copy at most @p max characters from @p source to @p target.
281 @param target Target string.
282 @param max Maximum number of characters to append.
283 @param source Source string.
284 @return Boolean value indicating success or failure.
286 @pre @p target must point to a memory chunk with sufficient room to
287 contain the @p source string (at most @p max characters).
288 @pre No boundary checking is performed, so insufficient memory will
289 result in a buffer overrun.
290 @post @p target will be zero terminated.
292 TRIO_STRING_PUBLIC int
294 TRIO_ARGS3((target, max, source),
297 TRIO_CONST char *source)
301 assert(max > 0); /* Includes != 0 */
303 (void)strncpy(target, source, max - 1);
304 target[max - 1] = (char)0;
312 TRIO_STRING_PRIVATE char *
314 TRIO_ARGS2((source, size),
315 TRIO_CONST char *source,
322 /* Make room for string plus a terminating zero */
324 target = trio_create(size);
327 trio_copy_max(target, size, source);
336 @param source Source string.
337 @return A copy of the @p source string.
339 @post @p target will be zero terminated.
341 TRIO_STRING_PUBLIC char *
344 TRIO_CONST char *source)
346 return TrioDuplicateMax(source, trio_length(source));
350 #if !defined(TRIO_MINIMAL)
352 Duplicate at most @p max characters of @p source.
354 @param source Source string.
355 @param max Maximum number of characters to duplicate.
356 @return A copy of the @p source string.
358 @post @p target will be zero terminated.
360 TRIO_STRING_PUBLIC char *
361 trio_duplicate_max TRIO_ARGS2((source, max),
362 TRIO_CONST char *source,
370 length = trio_length(source);
375 return TrioDuplicateMax(source, length);
377 #endif /* !defined(TRIO_MINIMAL) */
381 Compare if two strings are equal.
383 @param first First string.
384 @param second Second string.
385 @return Boolean indicating whether the two strings are equal or not.
387 Case-insensitive comparison.
389 TRIO_STRING_PUBLIC int
391 TRIO_ARGS2((first, second),
392 TRIO_CONST char *first,
393 TRIO_CONST char *second)
398 if ((first != NULL) && (second != NULL))
400 #if defined(USE_STRCASECMP)
401 return (0 == strcasecmp(first, second));
403 while ((*first != NIL) && (*second != NIL))
405 if (trio_to_upper(*first) != trio_to_upper(*second))
412 return ((*first == NIL) && (*second == NIL));
420 Compare if two strings are equal.
422 @param first First string.
423 @param second Second string.
424 @return Boolean indicating whether the two strings are equal or not.
426 Case-sensitive comparison.
428 TRIO_STRING_PUBLIC int
430 TRIO_ARGS2((first, second),
431 TRIO_CONST char *first,
432 TRIO_CONST char *second)
437 if ((first != NULL) && (second != NULL))
439 return (0 == strcmp(first, second));
445 #if !defined(TRIO_MINIMAL)
447 Compare if two strings up until the first @p max characters are equal.
449 @param first First string.
450 @param max Maximum number of characters to compare.
451 @param second Second string.
452 @return Boolean indicating whether the two strings are equal or not.
454 Case-sensitive comparison.
456 TRIO_STRING_PUBLIC int
458 TRIO_ARGS3((first, max, second),
459 TRIO_CONST char *first,
461 TRIO_CONST char *second)
466 if ((first != NULL) && (second != NULL))
468 return (0 == strncmp(first, second, max));
472 #endif /* !defined(TRIO_MINIMAL) */
476 Compare if two strings are equal.
478 @param first First string.
479 @param second Second string.
480 @return Boolean indicating whether the two strings are equal or not.
482 Collating characters are considered equal.
484 TRIO_STRING_PUBLIC int
486 TRIO_ARGS2((first, second),
487 TRIO_CONST char *first,
488 TRIO_CONST char *second)
493 #if defined(LC_COLLATE)
494 return (strcoll(first, second) == 0);
496 return trio_equal(first, second);
502 Compare if two strings up until the first @p max characters are equal.
504 @param first First string.
505 @param max Maximum number of characters to compare.
506 @param second Second string.
507 @return Boolean indicating whether the two strings are equal or not.
509 Case-insensitive comparison.
511 TRIO_STRING_PUBLIC int
513 TRIO_ARGS3((first, max, second),
514 TRIO_CONST char *first,
516 TRIO_CONST char *second)
521 if ((first != NULL) && (second != NULL))
523 #if defined(USE_STRNCASECMP)
524 return (0 == strncasecmp(first, second, max));
526 /* Not adequately tested yet */
528 while ((*first != NIL) && (*second != NIL) && (cnt <= max))
530 if (trio_to_upper(*first) != trio_to_upper(*second))
538 return ((cnt == max) || ((*first == NIL) && (*second == NIL)));
546 Provide a textual description of an error code (errno).
548 @param error_number Error number.
549 @return Textual description of @p error_number.
551 TRIO_STRING_PUBLIC TRIO_CONST char *
553 TRIO_ARGS1((error_number),
556 #if defined(USE_STRERROR)
558 return strerror(error_number);
560 #elif defined(USE_SYS_ERRLIST)
562 extern char *sys_errlist[];
565 return ((error_number < 0) || (error_number >= sys_nerr))
567 : sys_errlist[error_number];
577 #if !defined(TRIO_MINIMAL)
579 Format the date/time according to @p format.
581 @param target Target string.
582 @param max Maximum number of characters to format.
583 @param format Formatting string.
584 @param datetime Date/time structure.
585 @return Number of formatted characters.
587 The formatting string accepts the same specifiers as the standard C
590 TRIO_STRING_PUBLIC size_t
592 TRIO_ARGS4((target, max, format, datetime),
595 TRIO_CONST char *format,
596 TRIO_CONST struct tm *datetime)
603 return strftime(target, max, format, datetime);
605 #endif /* !defined(TRIO_MINIMAL) */
608 #if !defined(TRIO_MINIMAL)
610 Calculate a hash value for a string.
612 @param string String to be calculated on.
613 @param type Hash function.
614 @return Calculated hash value.
616 @p type can be one of the following
617 @li @c TRIO_HASH_PLAIN Plain hash function.
619 TRIO_STRING_PUBLIC unsigned long
621 TRIO_ARGS2((string, type),
622 TRIO_CONST char *string,
625 unsigned long value = 0L;
632 case TRIO_HASH_PLAIN:
633 while ( (ch = *string++) != NIL )
636 value += (unsigned long)ch;
645 #endif /* !defined(TRIO_MINIMAL) */
648 #if !defined(TRIO_MINIMAL)
650 Find first occurrence of a character in a string.
652 @param string String to be searched.
653 @param character Character to be found.
654 @param A pointer to the found character, or NULL if character was not found.
656 TRIO_STRING_PUBLIC char *
658 TRIO_ARGS2((string, character),
659 TRIO_CONST char *string,
664 return strchr(string, character);
666 #endif /* !defined(TRIO_MINIMAL) */
669 #if !defined(TRIO_MINIMAL)
671 Find last occurrence of a character in a string.
673 @param string String to be searched.
674 @param character Character to be found.
675 @param A pointer to the found character, or NULL if character was not found.
677 TRIO_STRING_PUBLIC char *
679 TRIO_ARGS2((string, character),
680 TRIO_CONST char *string,
685 return strchr(string, character);
687 #endif /* !defined(TRIO_MINIMAL) */
690 #if !defined(TRIO_MINIMAL)
692 Convert the alphabetic letters in the string to lower-case.
694 @param target String to be converted.
695 @return Number of processed characters (converted or not).
697 TRIO_STRING_PUBLIC int
704 return trio_span_function(target, target, trio_to_lower);
706 #endif /* !defined(TRIO_MINIMAL) */
709 #if !defined(TRIO_MINIMAL)
711 Compare two strings using wildcards.
713 @param string String to be searched.
714 @param pattern Pattern, including wildcards, to search for.
715 @return Boolean value indicating success or failure.
717 Case-insensitive comparison.
719 The following wildcards can be used
720 @li @c * Match any number of characters.
721 @li @c ? Match a single character.
723 TRIO_STRING_PUBLIC int
725 TRIO_ARGS2((string, pattern),
726 TRIO_CONST char *string,
727 TRIO_CONST char *pattern)
732 for (; ('*' != *pattern); ++pattern, ++string)
736 return (NIL == *pattern);
738 if ((trio_to_upper((int)*string) != trio_to_upper((int)*pattern))
739 && ('?' != *pattern))
744 /* two-line patch to prevent *too* much recursiveness: */
745 while ('*' == pattern[1])
750 if ( trio_match(string, &pattern[1]) )
759 #endif /* !defined(TRIO_MINIMAL) */
762 #if !defined(TRIO_MINIMAL)
764 Compare two strings using wildcards.
766 @param string String to be searched.
767 @param pattern Pattern, including wildcards, to search for.
768 @return Boolean value indicating success or failure.
770 Case-sensitive comparison.
772 The following wildcards can be used
773 @li @c * Match any number of characters.
774 @li @c ? Match a single character.
776 TRIO_STRING_PUBLIC int
778 TRIO_ARGS2((string, pattern),
779 TRIO_CONST char *string,
780 TRIO_CONST char *pattern)
785 for (; ('*' != *pattern); ++pattern, ++string)
789 return (NIL == *pattern);
791 if ((*string != *pattern)
792 && ('?' != *pattern))
797 /* two-line patch to prevent *too* much recursiveness: */
798 while ('*' == pattern[1])
803 if ( trio_match_case(string, &pattern[1]) )
812 #endif /* !defined(TRIO_MINIMAL) */
815 #if !defined(TRIO_MINIMAL)
817 Execute a function on each character in string.
819 @param target Target string.
820 @param source Source string.
821 @param Function Function to be executed.
822 @return Number of processed characters.
824 TRIO_STRING_PUBLIC size_t
826 TRIO_ARGS3((target, source, Function),
828 TRIO_CONST char *source,
829 int (*Function) TRIO_PROTO((int)))
837 while (*source != NIL)
839 *target++ = Function(*source++);
844 #endif /* !defined(TRIO_MINIMAL) */
847 #if !defined(TRIO_MINIMAL)
849 Search for a substring in a string.
851 @param string String to be searched.
852 @param substring String to be found.
853 @return Pointer to first occurrence of @p substring in @p string, or NULL
854 if no match was found.
856 TRIO_STRING_PUBLIC char *
858 TRIO_ARGS2((string, substring),
859 TRIO_CONST char *string,
860 TRIO_CONST char *substring)
865 return strstr(string, substring);
867 #endif /* !defined(TRIO_MINIMAL) */
870 #if !defined(TRIO_MINIMAL)
872 Search for a substring in the first @p max characters of a string.
874 @param string String to be searched.
875 @param max Maximum characters to be searched.
876 @param substring String to be found.
877 @return Pointer to first occurrence of @p substring in @p string, or NULL
878 if no match was found.
880 TRIO_STRING_PUBLIC char *
882 TRIO_ARGS3((string, max, substring),
883 TRIO_CONST char *string,
885 TRIO_CONST char *substring)
894 size = trio_length(substring);
897 for (count = 0; count <= max - size; count++)
899 if (trio_equal_max(substring, size, &string[count]))
901 result = (char *)&string[count];
908 #endif /* !defined(TRIO_MINIMAL) */
911 #if !defined(TRIO_MINIMAL)
915 @param string String to be tokenized.
916 @param tokens String containing list of delimiting characters.
917 @return Start of new token.
919 @warning @p string will be destroyed.
921 TRIO_STRING_PUBLIC char *
923 TRIO_ARGS2((string, delimiters),
925 TRIO_CONST char *delimiters)
929 return strtok(string, delimiters);
931 #endif /* !defined(TRIO_MINIMAL) */
935 Convert string to floating-point number.
937 @param source String to be converted.
938 @param endp Pointer to end of the converted string.
939 @return A floating-point number.
941 The following Extended Backus-Naur form is used
943 double ::= [ <sign> ]
945 <number> <decimal_point> <number> |
946 <decimal_point> <number> )
947 [ <exponential> [ <sign> ] <number> ]
948 number ::= 1*( <digit> )
949 digit ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )
950 exponential ::= ( 'e' | 'E' )
951 sign ::= ( '-' | '+' )
952 decimal_point ::= '.'
955 /* FIXME: Add EBNF for hex-floats */
956 TRIO_STRING_PUBLIC trio_long_double_t
958 TRIO_ARGS2((source, endp),
959 TRIO_CONST char *source,
962 #if defined(USE_STRTOLD)
963 return strtold(source, endp);
965 int isNegative = FALSE;
966 int isExponentNegative = FALSE;
967 trio_long_double_t integer = 0.0;
968 trio_long_double_t fraction = 0.0;
969 unsigned long exponent = 0;
970 trio_long_double_t base;
971 trio_long_double_t fracdiv = 1.0;
972 trio_long_double_t value = 0.0;
974 /* First try hex-floats */
975 if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X')))
979 while (isxdigit((int)*source))
982 integer += (isdigit((int)*source)
984 : 10 + (trio_to_upper((int)*source) - 'A'));
990 while (isxdigit((int)*source))
993 fraction += fracdiv * (isdigit((int)*source)
995 : 10 + (trio_to_upper((int)*source) - 'A'));
998 if ((*source == 'p') || (*source == 'P'))
1001 if ((*source == '+') || (*source == '-'))
1003 isExponentNegative = (*source == '-');
1006 while (isdigit((int)*source))
1009 exponent += (*source - '0');
1014 /* For later use with exponent */
1017 else /* Then try normal decimal floats */
1020 isNegative = (*source == '-');
1022 if ((*source == '+') || (*source == '-'))
1026 while (isdigit((int)*source))
1029 integer += (*source - '0');
1035 source++; /* skip decimal point */
1036 while (isdigit((int)*source))
1039 fraction += (*source - '0') * fracdiv;
1043 if ((*source == 'e')
1051 source++; /* Skip exponential indicator */
1052 isExponentNegative = (*source == '-');
1053 if ((*source == '+') || (*source == '-'))
1055 while (isdigit((int)*source))
1057 exponent *= (int)base;
1058 exponent += (*source - '0');
1064 value = integer + fraction;
1067 if (isExponentNegative)
1068 value /= pow(base, (double)exponent);
1070 value *= pow(base, (double)exponent);
1076 *endp = (char *)source;
1083 Convert string to floating-point number.
1085 @param source String to be converted.
1086 @param endp Pointer to end of the converted string.
1087 @return A floating-point number.
1089 See @ref trio_to_long_double.
1091 TRIO_STRING_PUBLIC double
1093 TRIO_ARGS2((source, endp),
1094 TRIO_CONST char *source,
1097 #if defined(USE_STRTOD)
1098 return strtod(source, endp);
1100 return (double)trio_to_long_double(source, endp);
1104 #if !defined(TRIO_MINIMAL)
1106 Convert string to floating-point number.
1108 @param source String to be converted.
1109 @param endp Pointer to end of the converted string.
1110 @return A floating-point number.
1112 See @ref trio_to_long_double.
1114 TRIO_STRING_PUBLIC float
1116 TRIO_ARGS2((source, endp),
1117 TRIO_CONST char *source,
1120 #if defined(USE_STRTOF)
1121 return strtof(source, endp);
1123 return (float)trio_to_long_double(source, endp);
1126 #endif /* !defined(TRIO_MINIMAL) */
1130 Convert string to signed integer.
1132 @param string String to be converted.
1133 @param endp Pointer to end of converted string.
1134 @param base Radix number of number.
1136 TRIO_STRING_PUBLIC long
1138 TRIO_ARGS3((string, endp, base),
1139 TRIO_CONST char *string,
1144 assert((base >= 2) && (base <= 36));
1146 return strtol(string, endp, base);
1150 #if !defined(TRIO_MINIMAL)
1152 Convert one alphabetic letter to lower-case.
1154 @param source The letter to be converted.
1155 @return The converted letter.
1157 TRIO_STRING_PUBLIC int
1159 TRIO_ARGS1((source),
1162 #if defined(USE_TOLOWER)
1164 return tolower(source);
1168 /* Does not handle locales or non-contiguous alphabetic characters */
1169 return ((source >= (int)'A') && (source <= (int)'Z'))
1170 ? source - 'A' + 'a'
1175 #endif /* !defined(TRIO_MINIMAL) */
1177 #if !defined(TRIO_MINIMAL)
1179 Convert string to unsigned integer.
1181 @param string String to be converted.
1182 @param endp Pointer to end of converted string.
1183 @param base Radix number of number.
1185 TRIO_STRING_PUBLIC unsigned long
1186 trio_to_unsigned_long
1187 TRIO_ARGS3((string, endp, base),
1188 TRIO_CONST char *string,
1193 assert((base >= 2) && (base <= 36));
1195 return strtoul(string, endp, base);
1197 #endif /* !defined(TRIO_MINIMAL) */
1201 Convert one alphabetic letter to upper-case.
1203 @param source The letter to be converted.
1204 @return The converted letter.
1206 TRIO_STRING_PUBLIC int
1208 TRIO_ARGS1((source),
1211 #if defined(USE_TOUPPER)
1213 return toupper(source);
1217 /* Does not handle locales or non-contiguous alphabetic characters */
1218 return ((source >= (int)'a') && (source <= (int)'z'))
1219 ? source - 'a' + 'A'
1225 #if !defined(TRIO_MINIMAL)
1227 Convert the alphabetic letters in the string to upper-case.
1229 @param target The string to be converted.
1230 @return The number of processed characters (converted or not).
1232 TRIO_STRING_PUBLIC int
1234 TRIO_ARGS1((target),
1239 return trio_span_function(target, target, trio_to_upper);
1241 #endif /* !defined(TRIO_MINIMAL) */
1244 /** @} End of StaticStrings */
1247 /*************************************************************************
1248 * Dynamic String Functions
1251 #if defined(TRIO_DOCUMENTATION)
1252 # include "doc/doc_dynamic.h"
1254 /** @addtogroup DynamicStrings
1261 TRIO_STRING_PRIVATE trio_string_t *
1262 TrioStringAlloc(TRIO_NOARGS)
1264 trio_string_t *self;
1266 self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t));
1269 self->content = NULL;
1271 self->allocated = 0;
1280 * The size of the string will be increased by 'delta' characters. If
1281 * 'delta' is zero, the size will be doubled.
1283 TRIO_STRING_PRIVATE BOOLEAN_T
1285 TRIO_ARGS2((self, delta),
1286 trio_string_t *self,
1289 BOOLEAN_T status = FALSE;
1293 new_size = (delta == 0)
1294 ? ( (self->allocated == 0) ? 1 : self->allocated * 2 )
1295 : self->allocated + delta;
1297 new_content = (char *)TRIO_REALLOC(self->content, new_size);
1300 self->content = new_content;
1301 self->allocated = new_size;
1308 #if !defined(TRIO_MINIMAL)
1312 * The size of the string will be increased to 'length' plus one characters.
1313 * If 'length' is less than the original size, the original size will be
1314 * used (that is, the size of the string is never decreased).
1316 TRIO_STRING_PRIVATE BOOLEAN_T
1318 TRIO_ARGS2((self, length),
1319 trio_string_t *self,
1322 length++; /* Room for terminating zero */
1323 return (self->allocated < length)
1324 ? TrioStringGrow(self, length - self->allocated)
1327 #endif /* !defined(TRIO_MINIMAL) */
1330 #if !defined(TRIO_MINIMAL)
1332 Create a new dynamic string.
1334 @param initial_size Initial size of the buffer.
1335 @return Newly allocated dynamic string, or NULL if memory allocation failed.
1337 TRIO_STRING_PUBLIC trio_string_t *
1339 TRIO_ARGS1((initial_size),
1342 trio_string_t *self;
1344 self = TrioStringAlloc();
1347 if (TrioStringGrow(self,
1348 (size_t)((initial_size > 0) ? initial_size : 1)))
1350 self->content[0] = (char)0;
1351 self->allocated = initial_size;
1355 trio_string_destroy(self);
1361 #endif /* !defined(TRIO_MINIMAL) */
1365 Deallocate the dynamic string and its contents.
1367 @param self Dynamic string
1369 TRIO_STRING_PUBLIC void
1372 trio_string_t *self)
1378 trio_destroy(self->content);
1384 #if !defined(TRIO_MINIMAL)
1386 Get a pointer to the content.
1388 @param self Dynamic string.
1389 @param offset Offset into content.
1390 @return Pointer to the content.
1392 @p Offset can be zero, positive, or negative. If @p offset is zero,
1393 then the start of the content will be returned. If @p offset is positive,
1394 then a pointer to @p offset number of characters from the beginning of the
1395 content is returned. If @p offset is negative, then a pointer to @p offset
1396 number of characters from the ending of the string, starting at the
1397 terminating zero, is returned.
1399 TRIO_STRING_PUBLIC char *
1401 TRIO_ARGS2((self, offset),
1402 trio_string_t *self,
1405 char *result = NULL;
1409 if (self->content != NULL)
1411 if (self->length == 0)
1413 (void)trio_string_length(self);
1417 if (offset > (int)self->length)
1419 offset = self->length;
1424 offset += self->length + 1;
1430 result = &(self->content[offset]);
1434 #endif /* !defined(TRIO_MINIMAL) */
1438 Extract the content.
1440 @param self Dynamic String
1441 @return Content of dynamic string.
1443 The content is removed from the dynamic string. This enables destruction
1444 of the dynamic string without deallocation of the content.
1446 TRIO_STRING_PUBLIC char *
1449 trio_string_t *self)
1455 result = self->content;
1456 /* FIXME: Allocate new empty buffer? */
1457 self->content = NULL;
1458 self->length = self->allocated = 0;
1463 #if !defined(TRIO_MINIMAL)
1465 Set the content of the dynamic string.
1467 @param self Dynamic String
1468 @param buffer The new content.
1470 Sets the content of the dynamic string to a copy @p buffer.
1471 An existing content will be deallocated first, if necessary.
1474 This function will make a copy of @p buffer.
1475 You are responsible for deallocating @p buffer yourself.
1477 TRIO_STRING_PUBLIC void
1479 TRIO_ARGS2((self, buffer),
1480 trio_string_t *self,
1485 trio_destroy(self->content);
1486 self->content = trio_duplicate(buffer);
1488 #endif /* !defined(TRIO_MINIMAL) */
1494 TRIO_STRING_PUBLIC int
1497 trio_string_t *self)
1501 return self->allocated;
1506 * trio_string_terminate
1508 TRIO_STRING_PUBLIC void
1509 trio_string_terminate
1511 trio_string_t *self)
1513 trio_xstring_append_char(self, 0);
1517 #if !defined(TRIO_MINIMAL)
1519 Append the second string to the first.
1521 @param self Dynamic string to be modified.
1522 @param other Dynamic string to copy from.
1523 @return Boolean value indicating success or failure.
1525 TRIO_STRING_PUBLIC int
1527 TRIO_ARGS2((self, other),
1528 trio_string_t *self,
1529 trio_string_t *other)
1536 length = self->length + other->length;
1537 if (!TrioStringGrowTo(self, length))
1539 trio_copy(&self->content[self->length], other->content);
1540 self->length = length;
1546 #endif /* !defined(TRIO_MINIMAL) */
1549 #if !defined(TRIO_MINIMAL)
1551 * trio_xstring_append
1553 TRIO_STRING_PUBLIC int
1555 TRIO_ARGS2((self, other),
1556 trio_string_t *self,
1557 TRIO_CONST char *other)
1564 length = self->length + trio_length(other);
1565 if (!TrioStringGrowTo(self, length))
1567 trio_copy(&self->content[self->length], other);
1568 self->length = length;
1574 #endif /* !defined(TRIO_MINIMAL) */
1578 * trio_xstring_append_char
1580 TRIO_STRING_PUBLIC int
1581 trio_xstring_append_char
1582 TRIO_ARGS2((self, character),
1583 trio_string_t *self,
1588 if ((int)self->length >= trio_string_size(self))
1590 if (!TrioStringGrow(self, 0))
1593 self->content[self->length] = character;
1602 #if !defined(TRIO_MINIMAL)
1604 Search for the first occurrence of second parameter in the first.
1606 @param self Dynamic string to be modified.
1607 @param other Dynamic string to copy from.
1608 @return Boolean value indicating success or failure.
1610 TRIO_STRING_PUBLIC int
1611 trio_string_contains
1612 TRIO_ARGS2((self, other),
1613 trio_string_t *self,
1614 trio_string_t *other)
1619 return trio_contains(self->content, other->content);
1621 #endif /* !defined(TRIO_MINIMAL) */
1624 #if !defined(TRIO_MINIMAL)
1626 * trio_xstring_contains
1628 TRIO_STRING_PUBLIC int
1629 trio_xstring_contains
1630 TRIO_ARGS2((self, other),
1631 trio_string_t *self,
1632 TRIO_CONST char *other)
1637 return trio_contains(self->content, other);
1639 #endif /* !defined(TRIO_MINIMAL) */
1642 #if !defined(TRIO_MINIMAL)
1646 TRIO_STRING_PUBLIC int
1648 TRIO_ARGS2((self, other),
1649 trio_string_t *self,
1650 trio_string_t *other)
1656 return trio_string_append(self, other);
1658 #endif /* !defined(TRIO_MINIMAL) */
1661 #if !defined(TRIO_MINIMAL)
1665 TRIO_STRING_PUBLIC int
1667 TRIO_ARGS2((self, other),
1668 trio_string_t *self,
1669 TRIO_CONST char *other)
1675 return trio_xstring_append(self, other);
1677 #endif /* !defined(TRIO_MINIMAL) */
1680 #if !defined(TRIO_MINIMAL)
1682 * trio_string_duplicate
1684 TRIO_STRING_PUBLIC trio_string_t *
1685 trio_string_duplicate
1687 trio_string_t *other)
1689 trio_string_t *self;
1693 self = TrioStringAlloc();
1696 self->content = TrioDuplicateMax(other->content, other->length);
1699 self->length = other->length;
1700 self->allocated = self->length + 1;
1704 self->length = self->allocated = 0;
1709 #endif /* !defined(TRIO_MINIMAL) */
1713 * trio_xstring_duplicate
1715 TRIO_STRING_PUBLIC trio_string_t *
1716 trio_xstring_duplicate
1718 TRIO_CONST char *other)
1720 trio_string_t *self;
1724 self = TrioStringAlloc();
1727 self->content = TrioDuplicateMax(other, trio_length(other));
1730 self->length = trio_length(self->content);
1731 self->allocated = self->length + 1;
1735 self->length = self->allocated = 0;
1742 #if !defined(TRIO_MINIMAL)
1746 TRIO_STRING_PUBLIC int
1748 TRIO_ARGS2((self, other),
1749 trio_string_t *self,
1750 trio_string_t *other)
1755 return trio_equal(self->content, other->content);
1757 #endif /* !defined(TRIO_MINIMAL) */
1760 #if !defined(TRIO_MINIMAL)
1762 * trio_xstring_equal
1764 TRIO_STRING_PUBLIC int
1766 TRIO_ARGS2((self, other),
1767 trio_string_t *self,
1768 TRIO_CONST char *other)
1773 return trio_equal(self->content, other);
1775 #endif /* !defined(TRIO_MINIMAL) */
1778 #if !defined(TRIO_MINIMAL)
1780 * trio_string_equal_max
1782 TRIO_STRING_PUBLIC int
1783 trio_string_equal_max
1784 TRIO_ARGS3((self, max, other),
1785 trio_string_t *self,
1787 trio_string_t *other)
1792 return trio_equal_max(self->content, max, other->content);
1794 #endif /* !defined(TRIO_MINIMAL) */
1797 #if !defined(TRIO_MINIMAL)
1799 * trio_xstring_equal_max
1801 TRIO_STRING_PUBLIC int
1802 trio_xstring_equal_max
1803 TRIO_ARGS3((self, max, other),
1804 trio_string_t *self,
1806 TRIO_CONST char *other)
1811 return trio_equal_max(self->content, max, other);
1813 #endif /* !defined(TRIO_MINIMAL) */
1816 #if !defined(TRIO_MINIMAL)
1818 * trio_string_equal_case
1820 TRIO_STRING_PUBLIC int
1821 trio_string_equal_case
1822 TRIO_ARGS2((self, other),
1823 trio_string_t *self,
1824 trio_string_t *other)
1829 return trio_equal_case(self->content, other->content);
1831 #endif /* !defined(TRIO_MINIMAL) */
1834 #if !defined(TRIO_MINIMAL)
1836 * trio_xstring_equal_case
1838 TRIO_STRING_PUBLIC int
1839 trio_xstring_equal_case
1840 TRIO_ARGS2((self, other),
1841 trio_string_t *self,
1842 TRIO_CONST char *other)
1847 return trio_equal_case(self->content, other);
1849 #endif /* !defined(TRIO_MINIMAL) */
1852 #if !defined(TRIO_MINIMAL)
1854 * trio_string_equal_case_max
1856 TRIO_STRING_PUBLIC int
1857 trio_string_equal_case_max
1858 TRIO_ARGS3((self, max, other),
1859 trio_string_t *self,
1861 trio_string_t *other)
1866 return trio_equal_case_max(self->content, max, other->content);
1868 #endif /* !defined(TRIO_MINIMAL) */
1871 #if !defined(TRIO_MINIMAL)
1873 * trio_xstring_equal_case_max
1875 TRIO_STRING_PUBLIC int
1876 trio_xstring_equal_case_max
1877 TRIO_ARGS3((self, max, other),
1878 trio_string_t *self,
1880 TRIO_CONST char *other)
1885 return trio_equal_case_max(self->content, max, other);
1887 #endif /* !defined(TRIO_MINIMAL) */
1890 #if !defined(TRIO_MINIMAL)
1892 * trio_string_format_data_max
1894 TRIO_STRING_PUBLIC size_t
1895 trio_string_format_date_max
1896 TRIO_ARGS4((self, max, format, datetime),
1897 trio_string_t *self,
1899 TRIO_CONST char *format,
1900 TRIO_CONST struct tm *datetime)
1904 return trio_format_date_max(self->content, max, format, datetime);
1906 #endif /* !defined(TRIO_MINIMAL) */
1909 #if !defined(TRIO_MINIMAL)
1913 TRIO_STRING_PUBLIC char *
1915 TRIO_ARGS2((self, character),
1916 trio_string_t *self,
1921 return trio_index(self->content, character);
1923 #endif /* !defined(TRIO_MINIMAL) */
1926 #if !defined(TRIO_MINIMAL)
1928 * trio_string_index_last
1930 TRIO_STRING_PUBLIC char *
1931 trio_string_index_last
1932 TRIO_ARGS2((self, character),
1933 trio_string_t *self,
1938 return trio_index_last(self->content, character);
1940 #endif /* !defined(TRIO_MINIMAL) */
1943 #if !defined(TRIO_MINIMAL)
1945 * trio_string_length
1947 TRIO_STRING_PUBLIC int
1950 trio_string_t *self)
1954 if (self->length == 0)
1956 self->length = trio_length(self->content);
1958 return self->length;
1960 #endif /* !defined(TRIO_MINIMAL) */
1963 #if !defined(TRIO_MINIMAL)
1967 TRIO_STRING_PUBLIC int
1970 trio_string_t *self)
1974 return trio_lower(self->content);
1976 #endif /* !defined(TRIO_MINIMAL) */
1979 #if !defined(TRIO_MINIMAL)
1983 TRIO_STRING_PUBLIC int
1985 TRIO_ARGS2((self, other),
1986 trio_string_t *self,
1987 trio_string_t *other)
1992 return trio_match(self->content, other->content);
1994 #endif /* !defined(TRIO_MINIMAL) */
1997 #if !defined(TRIO_MINIMAL)
1999 * trio_xstring_match
2001 TRIO_STRING_PUBLIC int
2003 TRIO_ARGS2((self, other),
2004 trio_string_t *self,
2005 TRIO_CONST char *other)
2010 return trio_match(self->content, other);
2012 #endif /* !defined(TRIO_MINIMAL) */
2015 #if !defined(TRIO_MINIMAL)
2017 * trio_string_match_case
2019 TRIO_STRING_PUBLIC int
2020 trio_string_match_case
2021 TRIO_ARGS2((self, other),
2022 trio_string_t *self,
2023 trio_string_t *other)
2028 return trio_match_case(self->content, other->content);
2030 #endif /* !defined(TRIO_MINIMAL) */
2033 #if !defined(TRIO_MINIMAL)
2035 * trio_xstring_match_case
2037 TRIO_STRING_PUBLIC int
2038 trio_xstring_match_case
2039 TRIO_ARGS2((self, other),
2040 trio_string_t *self,
2041 TRIO_CONST char *other)
2046 return trio_match_case(self->content, other);
2048 #endif /* !defined(TRIO_MINIMAL) */
2051 #if !defined(TRIO_MINIMAL)
2053 * trio_string_substring
2055 TRIO_STRING_PUBLIC char *
2056 trio_string_substring
2057 TRIO_ARGS2((self, other),
2058 trio_string_t *self,
2059 trio_string_t *other)
2064 return trio_substring(self->content, other->content);
2066 #endif /* !defined(TRIO_MINIMAL) */
2069 #if !defined(TRIO_MINIMAL)
2071 * trio_xstring_substring
2073 TRIO_STRING_PUBLIC char *
2074 trio_xstring_substring
2075 TRIO_ARGS2((self, other),
2076 trio_string_t *self,
2077 TRIO_CONST char *other)
2082 return trio_substring(self->content, other);
2084 #endif /* !defined(TRIO_MINIMAL) */
2087 #if !defined(TRIO_MINIMAL)
2091 TRIO_STRING_PUBLIC int
2094 trio_string_t *self)
2098 return trio_upper(self->content);
2100 #endif /* !defined(TRIO_MINIMAL) */
2102 /** @} End of DynamicStrings */