1 /*************************************************************************
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 # if defined(_WIN32_WCE)
77 # define strcasecmp(x,y) _stricmp(x,y)
79 # define strcasecmp(x,y) strcmpi(x,y)
83 #if !(defined(TRIO_PLATFORM_SUNOS))
88 /*************************************************************************
99 /*************************************************************************
103 #if !defined(TRIO_MINIMAL)
104 static TRIO_CONST
char rcsid
[] = "@(#)$Id$";
107 /*************************************************************************
108 * Static String Functions
111 #if defined(TRIO_DOCUMENTATION)
112 # include "doc/doc_static.h"
114 /** @addtogroup StaticStrings
121 @param size Size of new string.
122 @return Pointer to string, or NULL if allocation failed.
124 TRIO_STRING_PUBLIC
char *
129 return (char *)TRIO_MALLOC(size
);
136 @param string String to be freed.
138 TRIO_STRING_PUBLIC
void
151 Count the number of characters in a string.
153 @param string String to measure.
154 @return Number of characters in @string.
156 TRIO_STRING_PUBLIC
size_t
159 TRIO_CONST
char *string
)
161 return strlen(string
);
165 #if !defined(TRIO_MINIMAL)
167 Append @p source at the end of @p target.
169 @param target Target string.
170 @param source Source string.
171 @return Boolean value indicating success or failure.
173 @pre @p target must point to a memory chunk with sufficient room to
174 contain the @p target string and @p source string.
175 @pre No boundary checking is performed, so insufficient memory will
176 result in a buffer overrun.
177 @post @p target will be zero terminated.
179 TRIO_STRING_PUBLIC
int
181 TRIO_ARGS2((target
, source
),
183 TRIO_CONST
char *source
)
188 return (strcat(target
, source
) != NULL
);
190 #endif /* !defined(TRIO_MINIMAL) */
192 #if !defined(TRIO_MINIMAL)
194 Append at most @p max characters from @p source to @p target.
196 @param target Target string.
197 @param max Maximum number of characters to append.
198 @param source Source string.
199 @return Boolean value indicating success or failure.
201 @pre @p target must point to a memory chuck with sufficient room to
202 contain the @p target string and the @p source string (at most @p max
204 @pre No boundary checking is performed, so insufficient memory will
205 result in a buffer overrun.
206 @post @p target will be zero terminated.
208 TRIO_STRING_PUBLIC
int
210 TRIO_ARGS3((target
, max
, source
),
213 TRIO_CONST
char *source
)
220 length
= trio_length(target
);
224 strncat(target
, source
, max
- length
- 1);
228 #endif /* !defined(TRIO_MINIMAL) */
231 #if !defined(TRIO_MINIMAL)
233 Determine if a string contains a substring.
235 @param string String to be searched.
236 @param substring String to be found.
237 @return Boolean value indicating success or failure.
239 TRIO_STRING_PUBLIC
int
241 TRIO_ARGS2((string
, substring
),
242 TRIO_CONST
char *string
,
243 TRIO_CONST
char *substring
)
248 return (0 != strstr(string
, substring
));
250 #endif /* !defined(TRIO_MINIMAL) */
253 #if !defined(TRIO_MINIMAL)
255 Copy @p source to @p target.
257 @param target Target string.
258 @param source Source string.
259 @return Boolean value indicating success or failure.
261 @pre @p target must point to a memory chunk with sufficient room to
262 contain the @p source string.
263 @pre No boundary checking is performed, so insufficient memory will
264 result in a buffer overrun.
265 @post @p target will be zero terminated.
267 TRIO_STRING_PUBLIC
int
269 TRIO_ARGS2((target
, source
),
271 TRIO_CONST
char *source
)
276 (void)strcpy(target
, source
);
279 #endif /* !defined(TRIO_MINIMAL) */
283 Copy at most @p max characters from @p source to @p target.
285 @param target Target string.
286 @param max Maximum number of characters to append.
287 @param source Source string.
288 @return Boolean value indicating success or failure.
290 @pre @p target must point to a memory chunk with sufficient room to
291 contain the @p source string (at most @p max characters).
292 @pre No boundary checking is performed, so insufficient memory will
293 result in a buffer overrun.
294 @post @p target will be zero terminated.
296 TRIO_STRING_PUBLIC
int
298 TRIO_ARGS3((target
, max
, source
),
301 TRIO_CONST
char *source
)
305 assert(max
> 0); /* Includes != 0 */
307 (void)strncpy(target
, source
, max
- 1);
308 target
[max
- 1] = (char)0;
316 TRIO_STRING_PRIVATE
char *
318 TRIO_ARGS2((source
, size
),
319 TRIO_CONST
char *source
,
326 /* Make room for string plus a terminating zero */
328 target
= trio_create(size
);
331 trio_copy_max(target
, size
, source
);
340 @param source Source string.
341 @return A copy of the @p source string.
343 @post @p target will be zero terminated.
345 TRIO_STRING_PUBLIC
char *
348 TRIO_CONST
char *source
)
350 return TrioDuplicateMax(source
, trio_length(source
));
354 #if !defined(TRIO_MINIMAL)
356 Duplicate at most @p max characters of @p source.
358 @param source Source string.
359 @param max Maximum number of characters to duplicate.
360 @return A copy of the @p source string.
362 @post @p target will be zero terminated.
364 TRIO_STRING_PUBLIC
char *
365 trio_duplicate_max
TRIO_ARGS2((source
, max
),
366 TRIO_CONST
char *source
,
374 length
= trio_length(source
);
379 return TrioDuplicateMax(source
, length
);
381 #endif /* !defined(TRIO_MINIMAL) */
385 Compare if two strings are equal.
387 @param first First string.
388 @param second Second string.
389 @return Boolean indicating whether the two strings are equal or not.
391 Case-insensitive comparison.
393 TRIO_STRING_PUBLIC
int
395 TRIO_ARGS2((first
, second
),
396 TRIO_CONST
char *first
,
397 TRIO_CONST
char *second
)
402 if ((first
!= NULL
) && (second
!= NULL
))
404 #if defined(USE_STRCASECMP)
405 return (0 == strcasecmp(first
, second
));
407 while ((*first
!= NIL
) && (*second
!= NIL
))
409 if (trio_to_upper(*first
) != trio_to_upper(*second
))
416 return ((*first
== NIL
) && (*second
== NIL
));
424 Compare if two strings are equal.
426 @param first First string.
427 @param second Second string.
428 @return Boolean indicating whether the two strings are equal or not.
430 Case-sensitive comparison.
432 TRIO_STRING_PUBLIC
int
434 TRIO_ARGS2((first
, second
),
435 TRIO_CONST
char *first
,
436 TRIO_CONST
char *second
)
441 if ((first
!= NULL
) && (second
!= NULL
))
443 return (0 == strcmp(first
, second
));
449 #if !defined(TRIO_MINIMAL)
451 Compare if two strings up until the first @p max characters are equal.
453 @param first First string.
454 @param max Maximum number of characters to compare.
455 @param second Second string.
456 @return Boolean indicating whether the two strings are equal or not.
458 Case-sensitive comparison.
460 TRIO_STRING_PUBLIC
int
462 TRIO_ARGS3((first
, max
, second
),
463 TRIO_CONST
char *first
,
465 TRIO_CONST
char *second
)
470 if ((first
!= NULL
) && (second
!= NULL
))
472 return (0 == strncmp(first
, second
, max
));
476 #endif /* !defined(TRIO_MINIMAL) */
480 Compare if two strings are equal.
482 @param first First string.
483 @param second Second string.
484 @return Boolean indicating whether the two strings are equal or not.
486 Collating characters are considered equal.
488 TRIO_STRING_PUBLIC
int
490 TRIO_ARGS2((first
, second
),
491 TRIO_CONST
char *first
,
492 TRIO_CONST
char *second
)
497 #if defined(LC_COLLATE)
498 return (strcoll(first
, second
) == 0);
500 return trio_equal(first
, second
);
506 Compare if two strings up until the first @p max characters are equal.
508 @param first First string.
509 @param max Maximum number of characters to compare.
510 @param second Second string.
511 @return Boolean indicating whether the two strings are equal or not.
513 Case-insensitive comparison.
515 TRIO_STRING_PUBLIC
int
517 TRIO_ARGS3((first
, max
, second
),
518 TRIO_CONST
char *first
,
520 TRIO_CONST
char *second
)
525 if ((first
!= NULL
) && (second
!= NULL
))
527 #if defined(USE_STRNCASECMP)
528 return (0 == strncasecmp(first
, second
, max
));
530 /* Not adequately tested yet */
532 while ((*first
!= NIL
) && (*second
!= NIL
) && (cnt
<= max
))
534 if (trio_to_upper(*first
) != trio_to_upper(*second
))
542 return ((cnt
== max
) || ((*first
== NIL
) && (*second
== NIL
)));
550 Provide a textual description of an error code (errno).
552 @param error_number Error number.
553 @return Textual description of @p error_number.
555 TRIO_STRING_PUBLIC TRIO_CONST
char *
557 TRIO_ARGS1((error_number
),
560 #if defined(USE_STRERROR)
562 return strerror(error_number
);
564 #elif defined(USE_SYS_ERRLIST)
566 extern char *sys_errlist
[];
569 return ((error_number
< 0) || (error_number
>= sys_nerr
))
571 : sys_errlist
[error_number
];
581 #if !defined(TRIO_MINIMAL) && !defined(_WIN32_WCE)
583 Format the date/time according to @p format.
585 @param target Target string.
586 @param max Maximum number of characters to format.
587 @param format Formatting string.
588 @param datetime Date/time structure.
589 @return Number of formatted characters.
591 The formatting string accepts the same specifiers as the standard C
594 TRIO_STRING_PUBLIC
size_t
596 TRIO_ARGS4((target
, max
, format
, datetime
),
599 TRIO_CONST
char *format
,
600 TRIO_CONST
struct tm
*datetime
)
607 return strftime(target
, max
, format
, datetime
);
609 #endif /* !defined(TRIO_MINIMAL) */
612 #if !defined(TRIO_MINIMAL)
614 Calculate a hash value for a string.
616 @param string String to be calculated on.
617 @param type Hash function.
618 @return Calculated hash value.
620 @p type can be one of the following
621 @li @c TRIO_HASH_PLAIN Plain hash function.
623 TRIO_STRING_PUBLIC
unsigned long
625 TRIO_ARGS2((string
, type
),
626 TRIO_CONST
char *string
,
629 unsigned long value
= 0L;
636 case TRIO_HASH_PLAIN
:
637 while ( (ch
= *string
++) != NIL
)
640 value
+= (unsigned long)ch
;
649 #endif /* !defined(TRIO_MINIMAL) */
652 #if !defined(TRIO_MINIMAL)
654 Find first occurrence of a character in a string.
656 @param string String to be searched.
657 @param character Character to be found.
658 @param A pointer to the found character, or NULL if character was not found.
660 TRIO_STRING_PUBLIC
char *
662 TRIO_ARGS2((string
, character
),
663 TRIO_CONST
char *string
,
668 return strchr(string
, character
);
670 #endif /* !defined(TRIO_MINIMAL) */
673 #if !defined(TRIO_MINIMAL)
675 Find last occurrence of a character in a string.
677 @param string String to be searched.
678 @param character Character to be found.
679 @param A pointer to the found character, or NULL if character was not found.
681 TRIO_STRING_PUBLIC
char *
683 TRIO_ARGS2((string
, character
),
684 TRIO_CONST
char *string
,
689 return strchr(string
, character
);
691 #endif /* !defined(TRIO_MINIMAL) */
694 #if !defined(TRIO_MINIMAL)
696 Convert the alphabetic letters in the string to lower-case.
698 @param target String to be converted.
699 @return Number of processed characters (converted or not).
701 TRIO_STRING_PUBLIC
int
708 return trio_span_function(target
, target
, trio_to_lower
);
710 #endif /* !defined(TRIO_MINIMAL) */
713 #if !defined(TRIO_MINIMAL)
715 Compare two strings using wildcards.
717 @param string String to be searched.
718 @param pattern Pattern, including wildcards, to search for.
719 @return Boolean value indicating success or failure.
721 Case-insensitive comparison.
723 The following wildcards can be used
724 @li @c * Match any number of characters.
725 @li @c ? Match a single character.
727 TRIO_STRING_PUBLIC
int
729 TRIO_ARGS2((string
, pattern
),
730 TRIO_CONST
char *string
,
731 TRIO_CONST
char *pattern
)
736 for (; ('*' != *pattern
); ++pattern
, ++string
)
740 return (NIL
== *pattern
);
742 if ((trio_to_upper((int)*string
) != trio_to_upper((int)*pattern
))
743 && ('?' != *pattern
))
748 /* two-line patch to prevent *too* much recursiveness: */
749 while ('*' == pattern
[1])
754 if ( trio_match(string
, &pattern
[1]) )
763 #endif /* !defined(TRIO_MINIMAL) */
766 #if !defined(TRIO_MINIMAL)
768 Compare two strings using wildcards.
770 @param string String to be searched.
771 @param pattern Pattern, including wildcards, to search for.
772 @return Boolean value indicating success or failure.
774 Case-sensitive comparison.
776 The following wildcards can be used
777 @li @c * Match any number of characters.
778 @li @c ? Match a single character.
780 TRIO_STRING_PUBLIC
int
782 TRIO_ARGS2((string
, pattern
),
783 TRIO_CONST
char *string
,
784 TRIO_CONST
char *pattern
)
789 for (; ('*' != *pattern
); ++pattern
, ++string
)
793 return (NIL
== *pattern
);
795 if ((*string
!= *pattern
)
796 && ('?' != *pattern
))
801 /* two-line patch to prevent *too* much recursiveness: */
802 while ('*' == pattern
[1])
807 if ( trio_match_case(string
, &pattern
[1]) )
816 #endif /* !defined(TRIO_MINIMAL) */
819 #if !defined(TRIO_MINIMAL)
821 Execute a function on each character in string.
823 @param target Target string.
824 @param source Source string.
825 @param Function Function to be executed.
826 @return Number of processed characters.
828 TRIO_STRING_PUBLIC
size_t
830 TRIO_ARGS3((target
, source
, Function
),
832 TRIO_CONST
char *source
,
833 int (*Function
) TRIO_PROTO((int)))
841 while (*source
!= NIL
)
843 *target
++ = Function(*source
++);
848 #endif /* !defined(TRIO_MINIMAL) */
851 #if !defined(TRIO_MINIMAL)
853 Search for a substring in a string.
855 @param string String to be searched.
856 @param substring String to be found.
857 @return Pointer to first occurrence of @p substring in @p string, or NULL
858 if no match was found.
860 TRIO_STRING_PUBLIC
char *
862 TRIO_ARGS2((string
, substring
),
863 TRIO_CONST
char *string
,
864 TRIO_CONST
char *substring
)
869 return strstr(string
, substring
);
871 #endif /* !defined(TRIO_MINIMAL) */
874 #if !defined(TRIO_MINIMAL)
876 Search for a substring in the first @p max characters of a string.
878 @param string String to be searched.
879 @param max Maximum characters to be searched.
880 @param substring String to be found.
881 @return Pointer to first occurrence of @p substring in @p string, or NULL
882 if no match was found.
884 TRIO_STRING_PUBLIC
char *
886 TRIO_ARGS3((string
, max
, substring
),
887 TRIO_CONST
char *string
,
889 TRIO_CONST
char *substring
)
898 size
= trio_length(substring
);
901 for (count
= 0; count
<= max
- size
; count
++)
903 if (trio_equal_max(substring
, size
, &string
[count
]))
905 result
= (char *)&string
[count
];
912 #endif /* !defined(TRIO_MINIMAL) */
915 #if !defined(TRIO_MINIMAL)
919 @param string String to be tokenized.
920 @param tokens String containing list of delimiting characters.
921 @return Start of new token.
923 @warning @p string will be destroyed.
925 TRIO_STRING_PUBLIC
char *
927 TRIO_ARGS2((string
, delimiters
),
929 TRIO_CONST
char *delimiters
)
933 return strtok(string
, delimiters
);
935 #endif /* !defined(TRIO_MINIMAL) */
939 Convert string to floating-point number.
941 @param source String to be converted.
942 @param endp Pointer to end of the converted string.
943 @return A floating-point number.
945 The following Extended Backus-Naur form is used
947 double ::= [ <sign> ]
949 <number> <decimal_point> <number> |
950 <decimal_point> <number> )
951 [ <exponential> [ <sign> ] <number> ]
952 number ::= 1*( <digit> )
953 digit ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )
954 exponential ::= ( 'e' | 'E' )
955 sign ::= ( '-' | '+' )
956 decimal_point ::= '.'
959 /* FIXME: Add EBNF for hex-floats */
960 TRIO_STRING_PUBLIC trio_long_double_t
962 TRIO_ARGS2((source
, endp
),
963 TRIO_CONST
char *source
,
966 #if defined(USE_STRTOLD)
967 return strtold(source
, endp
);
969 int isNegative
= FALSE
;
970 int isExponentNegative
= FALSE
;
971 trio_long_double_t integer
= 0.0;
972 trio_long_double_t fraction
= 0.0;
973 unsigned long exponent
= 0;
974 trio_long_double_t base
;
975 trio_long_double_t fracdiv
= 1.0;
976 trio_long_double_t value
= 0.0;
978 /* First try hex-floats */
979 if ((source
[0] == '0') && ((source
[1] == 'x') || (source
[1] == 'X')))
983 while (isxdigit((int)*source
))
986 integer
+= (isdigit((int)*source
)
988 : 10 + (trio_to_upper((int)*source
) - 'A'));
994 while (isxdigit((int)*source
))
997 fraction
+= fracdiv
* (isdigit((int)*source
)
999 : 10 + (trio_to_upper((int)*source
) - 'A'));
1002 if ((*source
== 'p') || (*source
== 'P'))
1005 if ((*source
== '+') || (*source
== '-'))
1007 isExponentNegative
= (*source
== '-');
1010 while (isdigit((int)*source
))
1013 exponent
+= (*source
- '0');
1018 /* For later use with exponent */
1021 else /* Then try normal decimal floats */
1024 isNegative
= (*source
== '-');
1026 if ((*source
== '+') || (*source
== '-'))
1030 while (isdigit((int)*source
))
1033 integer
+= (*source
- '0');
1039 source
++; /* skip decimal point */
1040 while (isdigit((int)*source
))
1043 fraction
+= (*source
- '0') * fracdiv
;
1047 if ((*source
== 'e')
1055 source
++; /* Skip exponential indicator */
1056 isExponentNegative
= (*source
== '-');
1057 if ((*source
== '+') || (*source
== '-'))
1059 while (isdigit((int)*source
))
1061 exponent
*= (int)base
;
1062 exponent
+= (*source
- '0');
1068 value
= integer
+ fraction
;
1071 if (isExponentNegative
)
1072 value
/= pow(base
, (double)exponent
);
1074 value
*= pow(base
, (double)exponent
);
1080 *endp
= (char *)source
;
1087 Convert string to floating-point number.
1089 @param source String to be converted.
1090 @param endp Pointer to end of the converted string.
1091 @return A floating-point number.
1093 See @ref trio_to_long_double.
1095 TRIO_STRING_PUBLIC
double
1097 TRIO_ARGS2((source
, endp
),
1098 TRIO_CONST
char *source
,
1101 #if defined(USE_STRTOD)
1102 return strtod(source
, endp
);
1104 return (double)trio_to_long_double(source
, endp
);
1108 #if !defined(TRIO_MINIMAL)
1110 Convert string to floating-point number.
1112 @param source String to be converted.
1113 @param endp Pointer to end of the converted string.
1114 @return A floating-point number.
1116 See @ref trio_to_long_double.
1118 TRIO_STRING_PUBLIC
float
1120 TRIO_ARGS2((source
, endp
),
1121 TRIO_CONST
char *source
,
1124 #if defined(USE_STRTOF)
1125 return strtof(source
, endp
);
1127 return (float)trio_to_long_double(source
, endp
);
1130 #endif /* !defined(TRIO_MINIMAL) */
1134 Convert string to signed integer.
1136 @param string String to be converted.
1137 @param endp Pointer to end of converted string.
1138 @param base Radix number of number.
1140 TRIO_STRING_PUBLIC
long
1142 TRIO_ARGS3((string
, endp
, base
),
1143 TRIO_CONST
char *string
,
1148 assert((base
>= 2) && (base
<= 36));
1150 return strtol(string
, endp
, base
);
1154 #if !defined(TRIO_MINIMAL)
1156 Convert one alphabetic letter to lower-case.
1158 @param source The letter to be converted.
1159 @return The converted letter.
1161 TRIO_STRING_PUBLIC
int
1163 TRIO_ARGS1((source
),
1166 #if defined(USE_TOLOWER)
1168 return tolower(source
);
1172 /* Does not handle locales or non-contiguous alphabetic characters */
1173 return ((source
>= (int)'A') && (source
<= (int)'Z'))
1174 ? source
- 'A' + 'a'
1179 #endif /* !defined(TRIO_MINIMAL) */
1181 #if !defined(TRIO_MINIMAL)
1183 Convert string to unsigned integer.
1185 @param string String to be converted.
1186 @param endp Pointer to end of converted string.
1187 @param base Radix number of number.
1189 TRIO_STRING_PUBLIC
unsigned long
1190 trio_to_unsigned_long
1191 TRIO_ARGS3((string
, endp
, base
),
1192 TRIO_CONST
char *string
,
1197 assert((base
>= 2) && (base
<= 36));
1199 return strtoul(string
, endp
, base
);
1201 #endif /* !defined(TRIO_MINIMAL) */
1205 Convert one alphabetic letter to upper-case.
1207 @param source The letter to be converted.
1208 @return The converted letter.
1210 TRIO_STRING_PUBLIC
int
1212 TRIO_ARGS1((source
),
1215 #if defined(USE_TOUPPER)
1217 return toupper(source
);
1221 /* Does not handle locales or non-contiguous alphabetic characters */
1222 return ((source
>= (int)'a') && (source
<= (int)'z'))
1223 ? source
- 'a' + 'A'
1229 #if !defined(TRIO_MINIMAL)
1231 Convert the alphabetic letters in the string to upper-case.
1233 @param target The string to be converted.
1234 @return The number of processed characters (converted or not).
1236 TRIO_STRING_PUBLIC
int
1238 TRIO_ARGS1((target
),
1243 return trio_span_function(target
, target
, trio_to_upper
);
1245 #endif /* !defined(TRIO_MINIMAL) */
1248 /** @} End of StaticStrings */
1251 /*************************************************************************
1252 * Dynamic String Functions
1255 #if defined(TRIO_DOCUMENTATION)
1256 # include "doc/doc_dynamic.h"
1258 /** @addtogroup DynamicStrings
1265 TRIO_STRING_PRIVATE trio_string_t
*
1266 TrioStringAlloc(TRIO_NOARGS
)
1268 trio_string_t
*self
;
1270 self
= (trio_string_t
*)TRIO_MALLOC(sizeof(trio_string_t
));
1273 self
->content
= NULL
;
1275 self
->allocated
= 0;
1284 * The size of the string will be increased by 'delta' characters. If
1285 * 'delta' is zero, the size will be doubled.
1287 TRIO_STRING_PRIVATE BOOLEAN_T
1289 TRIO_ARGS2((self
, delta
),
1290 trio_string_t
*self
,
1293 BOOLEAN_T status
= FALSE
;
1297 new_size
= (delta
== 0)
1298 ? ( (self
->allocated
== 0) ? 1 : self
->allocated
* 2 )
1299 : self
->allocated
+ delta
;
1301 new_content
= (char *)TRIO_REALLOC(self
->content
, new_size
);
1304 self
->content
= new_content
;
1305 self
->allocated
= new_size
;
1312 #if !defined(TRIO_MINIMAL)
1316 * The size of the string will be increased to 'length' plus one characters.
1317 * If 'length' is less than the original size, the original size will be
1318 * used (that is, the size of the string is never decreased).
1320 TRIO_STRING_PRIVATE BOOLEAN_T
1322 TRIO_ARGS2((self
, length
),
1323 trio_string_t
*self
,
1326 length
++; /* Room for terminating zero */
1327 return (self
->allocated
< length
)
1328 ? TrioStringGrow(self
, length
- self
->allocated
)
1331 #endif /* !defined(TRIO_MINIMAL) */
1334 #if !defined(TRIO_MINIMAL)
1336 Create a new dynamic string.
1338 @param initial_size Initial size of the buffer.
1339 @return Newly allocated dynamic string, or NULL if memory allocation failed.
1341 TRIO_STRING_PUBLIC trio_string_t
*
1343 TRIO_ARGS1((initial_size
),
1346 trio_string_t
*self
;
1348 self
= TrioStringAlloc();
1351 if (TrioStringGrow(self
,
1352 (size_t)((initial_size
> 0) ? initial_size
: 1)))
1354 self
->content
[0] = (char)0;
1355 self
->allocated
= initial_size
;
1359 trio_string_destroy(self
);
1365 #endif /* !defined(TRIO_MINIMAL) */
1369 Deallocate the dynamic string and its contents.
1371 @param self Dynamic string
1373 TRIO_STRING_PUBLIC
void
1376 trio_string_t
*self
)
1382 trio_destroy(self
->content
);
1388 #if !defined(TRIO_MINIMAL)
1390 Get a pointer to the content.
1392 @param self Dynamic string.
1393 @param offset Offset into content.
1394 @return Pointer to the content.
1396 @p Offset can be zero, positive, or negative. If @p offset is zero,
1397 then the start of the content will be returned. If @p offset is positive,
1398 then a pointer to @p offset number of characters from the beginning of the
1399 content is returned. If @p offset is negative, then a pointer to @p offset
1400 number of characters from the ending of the string, starting at the
1401 terminating zero, is returned.
1403 TRIO_STRING_PUBLIC
char *
1405 TRIO_ARGS2((self
, offset
),
1406 trio_string_t
*self
,
1409 char *result
= NULL
;
1413 if (self
->content
!= NULL
)
1415 if (self
->length
== 0)
1417 (void)trio_string_length(self
);
1421 if (offset
> (int)self
->length
)
1423 offset
= self
->length
;
1428 offset
+= self
->length
+ 1;
1434 result
= &(self
->content
[offset
]);
1438 #endif /* !defined(TRIO_MINIMAL) */
1442 Extract the content.
1444 @param self Dynamic String
1445 @return Content of dynamic string.
1447 The content is removed from the dynamic string. This enables destruction
1448 of the dynamic string without deallocation of the content.
1450 TRIO_STRING_PUBLIC
char *
1453 trio_string_t
*self
)
1459 result
= self
->content
;
1460 /* FIXME: Allocate new empty buffer? */
1461 self
->content
= NULL
;
1462 self
->length
= self
->allocated
= 0;
1467 #if !defined(TRIO_MINIMAL)
1469 Set the content of the dynamic string.
1471 @param self Dynamic String
1472 @param buffer The new content.
1474 Sets the content of the dynamic string to a copy @p buffer.
1475 An existing content will be deallocated first, if necessary.
1478 This function will make a copy of @p buffer.
1479 You are responsible for deallocating @p buffer yourself.
1481 TRIO_STRING_PUBLIC
void
1483 TRIO_ARGS2((self
, buffer
),
1484 trio_string_t
*self
,
1489 trio_destroy(self
->content
);
1490 self
->content
= trio_duplicate(buffer
);
1492 #endif /* !defined(TRIO_MINIMAL) */
1498 TRIO_STRING_PUBLIC
int
1501 trio_string_t
*self
)
1505 return self
->allocated
;
1510 * trio_string_terminate
1512 TRIO_STRING_PUBLIC
void
1513 trio_string_terminate
1515 trio_string_t
*self
)
1517 trio_xstring_append_char(self
, 0);
1521 #if !defined(TRIO_MINIMAL)
1523 Append the second string to the first.
1525 @param self Dynamic string to be modified.
1526 @param other Dynamic string to copy from.
1527 @return Boolean value indicating success or failure.
1529 TRIO_STRING_PUBLIC
int
1531 TRIO_ARGS2((self
, other
),
1532 trio_string_t
*self
,
1533 trio_string_t
*other
)
1540 length
= self
->length
+ other
->length
;
1541 if (!TrioStringGrowTo(self
, length
))
1543 trio_copy(&self
->content
[self
->length
], other
->content
);
1544 self
->length
= length
;
1550 #endif /* !defined(TRIO_MINIMAL) */
1553 #if !defined(TRIO_MINIMAL)
1555 * trio_xstring_append
1557 TRIO_STRING_PUBLIC
int
1559 TRIO_ARGS2((self
, other
),
1560 trio_string_t
*self
,
1561 TRIO_CONST
char *other
)
1568 length
= self
->length
+ trio_length(other
);
1569 if (!TrioStringGrowTo(self
, length
))
1571 trio_copy(&self
->content
[self
->length
], other
);
1572 self
->length
= length
;
1578 #endif /* !defined(TRIO_MINIMAL) */
1582 * trio_xstring_append_char
1584 TRIO_STRING_PUBLIC
int
1585 trio_xstring_append_char
1586 TRIO_ARGS2((self
, character
),
1587 trio_string_t
*self
,
1592 if ((int)self
->length
>= trio_string_size(self
))
1594 if (!TrioStringGrow(self
, 0))
1597 self
->content
[self
->length
] = character
;
1606 #if !defined(TRIO_MINIMAL)
1608 Search for the first occurrence of second parameter in the first.
1610 @param self Dynamic string to be modified.
1611 @param other Dynamic string to copy from.
1612 @return Boolean value indicating success or failure.
1614 TRIO_STRING_PUBLIC
int
1615 trio_string_contains
1616 TRIO_ARGS2((self
, other
),
1617 trio_string_t
*self
,
1618 trio_string_t
*other
)
1623 return trio_contains(self
->content
, other
->content
);
1625 #endif /* !defined(TRIO_MINIMAL) */
1628 #if !defined(TRIO_MINIMAL)
1630 * trio_xstring_contains
1632 TRIO_STRING_PUBLIC
int
1633 trio_xstring_contains
1634 TRIO_ARGS2((self
, other
),
1635 trio_string_t
*self
,
1636 TRIO_CONST
char *other
)
1641 return trio_contains(self
->content
, other
);
1643 #endif /* !defined(TRIO_MINIMAL) */
1646 #if !defined(TRIO_MINIMAL)
1650 TRIO_STRING_PUBLIC
int
1652 TRIO_ARGS2((self
, other
),
1653 trio_string_t
*self
,
1654 trio_string_t
*other
)
1660 return trio_string_append(self
, other
);
1662 #endif /* !defined(TRIO_MINIMAL) */
1665 #if !defined(TRIO_MINIMAL)
1669 TRIO_STRING_PUBLIC
int
1671 TRIO_ARGS2((self
, other
),
1672 trio_string_t
*self
,
1673 TRIO_CONST
char *other
)
1679 return trio_xstring_append(self
, other
);
1681 #endif /* !defined(TRIO_MINIMAL) */
1684 #if !defined(TRIO_MINIMAL)
1686 * trio_string_duplicate
1688 TRIO_STRING_PUBLIC trio_string_t
*
1689 trio_string_duplicate
1691 trio_string_t
*other
)
1693 trio_string_t
*self
;
1697 self
= TrioStringAlloc();
1700 self
->content
= TrioDuplicateMax(other
->content
, other
->length
);
1703 self
->length
= other
->length
;
1704 self
->allocated
= self
->length
+ 1;
1708 self
->length
= self
->allocated
= 0;
1713 #endif /* !defined(TRIO_MINIMAL) */
1717 * trio_xstring_duplicate
1719 TRIO_STRING_PUBLIC trio_string_t
*
1720 trio_xstring_duplicate
1722 TRIO_CONST
char *other
)
1724 trio_string_t
*self
;
1728 self
= TrioStringAlloc();
1731 self
->content
= TrioDuplicateMax(other
, trio_length(other
));
1734 self
->length
= trio_length(self
->content
);
1735 self
->allocated
= self
->length
+ 1;
1739 self
->length
= self
->allocated
= 0;
1746 #if !defined(TRIO_MINIMAL)
1750 TRIO_STRING_PUBLIC
int
1752 TRIO_ARGS2((self
, other
),
1753 trio_string_t
*self
,
1754 trio_string_t
*other
)
1759 return trio_equal(self
->content
, other
->content
);
1761 #endif /* !defined(TRIO_MINIMAL) */
1764 #if !defined(TRIO_MINIMAL)
1766 * trio_xstring_equal
1768 TRIO_STRING_PUBLIC
int
1770 TRIO_ARGS2((self
, other
),
1771 trio_string_t
*self
,
1772 TRIO_CONST
char *other
)
1777 return trio_equal(self
->content
, other
);
1779 #endif /* !defined(TRIO_MINIMAL) */
1782 #if !defined(TRIO_MINIMAL)
1784 * trio_string_equal_max
1786 TRIO_STRING_PUBLIC
int
1787 trio_string_equal_max
1788 TRIO_ARGS3((self
, max
, other
),
1789 trio_string_t
*self
,
1791 trio_string_t
*other
)
1796 return trio_equal_max(self
->content
, max
, other
->content
);
1798 #endif /* !defined(TRIO_MINIMAL) */
1801 #if !defined(TRIO_MINIMAL)
1803 * trio_xstring_equal_max
1805 TRIO_STRING_PUBLIC
int
1806 trio_xstring_equal_max
1807 TRIO_ARGS3((self
, max
, other
),
1808 trio_string_t
*self
,
1810 TRIO_CONST
char *other
)
1815 return trio_equal_max(self
->content
, max
, other
);
1817 #endif /* !defined(TRIO_MINIMAL) */
1820 #if !defined(TRIO_MINIMAL)
1822 * trio_string_equal_case
1824 TRIO_STRING_PUBLIC
int
1825 trio_string_equal_case
1826 TRIO_ARGS2((self
, other
),
1827 trio_string_t
*self
,
1828 trio_string_t
*other
)
1833 return trio_equal_case(self
->content
, other
->content
);
1835 #endif /* !defined(TRIO_MINIMAL) */
1838 #if !defined(TRIO_MINIMAL)
1840 * trio_xstring_equal_case
1842 TRIO_STRING_PUBLIC
int
1843 trio_xstring_equal_case
1844 TRIO_ARGS2((self
, other
),
1845 trio_string_t
*self
,
1846 TRIO_CONST
char *other
)
1851 return trio_equal_case(self
->content
, other
);
1853 #endif /* !defined(TRIO_MINIMAL) */
1856 #if !defined(TRIO_MINIMAL)
1858 * trio_string_equal_case_max
1860 TRIO_STRING_PUBLIC
int
1861 trio_string_equal_case_max
1862 TRIO_ARGS3((self
, max
, other
),
1863 trio_string_t
*self
,
1865 trio_string_t
*other
)
1870 return trio_equal_case_max(self
->content
, max
, other
->content
);
1872 #endif /* !defined(TRIO_MINIMAL) */
1875 #if !defined(TRIO_MINIMAL)
1877 * trio_xstring_equal_case_max
1879 TRIO_STRING_PUBLIC
int
1880 trio_xstring_equal_case_max
1881 TRIO_ARGS3((self
, max
, other
),
1882 trio_string_t
*self
,
1884 TRIO_CONST
char *other
)
1889 return trio_equal_case_max(self
->content
, max
, other
);
1891 #endif /* !defined(TRIO_MINIMAL) */
1894 #if !defined(TRIO_MINIMAL) && !defined(_WIN32_WCE)
1896 * trio_string_format_data_max
1898 TRIO_STRING_PUBLIC
size_t
1899 trio_string_format_date_max
1900 TRIO_ARGS4((self
, max
, format
, datetime
),
1901 trio_string_t
*self
,
1903 TRIO_CONST
char *format
,
1904 TRIO_CONST
struct tm
*datetime
)
1908 return trio_format_date_max(self
->content
, max
, format
, datetime
);
1910 #endif /* !defined(TRIO_MINIMAL) */
1913 #if !defined(TRIO_MINIMAL)
1917 TRIO_STRING_PUBLIC
char *
1919 TRIO_ARGS2((self
, character
),
1920 trio_string_t
*self
,
1925 return trio_index(self
->content
, character
);
1927 #endif /* !defined(TRIO_MINIMAL) */
1930 #if !defined(TRIO_MINIMAL)
1932 * trio_string_index_last
1934 TRIO_STRING_PUBLIC
char *
1935 trio_string_index_last
1936 TRIO_ARGS2((self
, character
),
1937 trio_string_t
*self
,
1942 return trio_index_last(self
->content
, character
);
1944 #endif /* !defined(TRIO_MINIMAL) */
1947 #if !defined(TRIO_MINIMAL)
1949 * trio_string_length
1951 TRIO_STRING_PUBLIC
int
1954 trio_string_t
*self
)
1958 if (self
->length
== 0)
1960 self
->length
= trio_length(self
->content
);
1962 return self
->length
;
1964 #endif /* !defined(TRIO_MINIMAL) */
1967 #if !defined(TRIO_MINIMAL)
1971 TRIO_STRING_PUBLIC
int
1974 trio_string_t
*self
)
1978 return trio_lower(self
->content
);
1980 #endif /* !defined(TRIO_MINIMAL) */
1983 #if !defined(TRIO_MINIMAL)
1987 TRIO_STRING_PUBLIC
int
1989 TRIO_ARGS2((self
, other
),
1990 trio_string_t
*self
,
1991 trio_string_t
*other
)
1996 return trio_match(self
->content
, other
->content
);
1998 #endif /* !defined(TRIO_MINIMAL) */
2001 #if !defined(TRIO_MINIMAL)
2003 * trio_xstring_match
2005 TRIO_STRING_PUBLIC
int
2007 TRIO_ARGS2((self
, other
),
2008 trio_string_t
*self
,
2009 TRIO_CONST
char *other
)
2014 return trio_match(self
->content
, other
);
2016 #endif /* !defined(TRIO_MINIMAL) */
2019 #if !defined(TRIO_MINIMAL)
2021 * trio_string_match_case
2023 TRIO_STRING_PUBLIC
int
2024 trio_string_match_case
2025 TRIO_ARGS2((self
, other
),
2026 trio_string_t
*self
,
2027 trio_string_t
*other
)
2032 return trio_match_case(self
->content
, other
->content
);
2034 #endif /* !defined(TRIO_MINIMAL) */
2037 #if !defined(TRIO_MINIMAL)
2039 * trio_xstring_match_case
2041 TRIO_STRING_PUBLIC
int
2042 trio_xstring_match_case
2043 TRIO_ARGS2((self
, other
),
2044 trio_string_t
*self
,
2045 TRIO_CONST
char *other
)
2050 return trio_match_case(self
->content
, other
);
2052 #endif /* !defined(TRIO_MINIMAL) */
2055 #if !defined(TRIO_MINIMAL)
2057 * trio_string_substring
2059 TRIO_STRING_PUBLIC
char *
2060 trio_string_substring
2061 TRIO_ARGS2((self
, other
),
2062 trio_string_t
*self
,
2063 trio_string_t
*other
)
2068 return trio_substring(self
->content
, other
->content
);
2070 #endif /* !defined(TRIO_MINIMAL) */
2073 #if !defined(TRIO_MINIMAL)
2075 * trio_xstring_substring
2077 TRIO_STRING_PUBLIC
char *
2078 trio_xstring_substring
2079 TRIO_ARGS2((self
, other
),
2080 trio_string_t
*self
,
2081 TRIO_CONST
char *other
)
2086 return trio_substring(self
->content
, other
);
2088 #endif /* !defined(TRIO_MINIMAL) */
2091 #if !defined(TRIO_MINIMAL)
2095 TRIO_STRING_PUBLIC
int
2098 trio_string_t
*self
)
2102 return trio_upper(self
->content
);
2104 #endif /* !defined(TRIO_MINIMAL) */
2106 /** @} End of DynamicStrings */