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
57 #elif defined(TRIO_COMPILER_SUPPORTS_C99)
60 #elif defined(TRIO_COMPILER_MSVC)
64 #if defined(TRIO_PLATFORM_UNIX)
65 # define USE_STRCASECMP
66 # define USE_STRNCASECMP
67 # if defined(TRIO_PLATFORM_SUNOS)
68 # define USE_SYS_ERRLIST
72 # if defined(TRIO_PLATFORM_QNX)
73 # define strcasecmp(x,y) stricmp(x,y)
74 # define strncasecmp(x,y,n) strnicmp(x,y,n)
76 #elif defined(TRIO_PLATFORM_WIN32)
77 # define USE_STRCASECMP
78 # if defined(_WIN32_WCE)
79 # define strcasecmp(x,y) _stricmp(x,y)
81 # define strcasecmp(x,y) strcmpi(x,y)
83 #elif defined(TRIO_PLATFORM_OS400)
84 # define USE_STRCASECMP
85 # define USE_STRNCASECMP
89 #if !(defined(TRIO_PLATFORM_SUNOS))
94 /*************************************************************************
105 /*************************************************************************
109 #if !defined(TRIO_MINIMAL)
110 static TRIO_CONST
char rcsid
[] = "@(#)$Id$";
113 /*************************************************************************
114 * Static String Functions
117 #if defined(TRIO_DOCUMENTATION)
118 # include "doc/doc_static.h"
120 /** @addtogroup StaticStrings
127 @param size Size of new string.
128 @return Pointer to string, or NULL if allocation failed.
130 TRIO_STRING_PUBLIC
char *
135 return (char *)TRIO_MALLOC(size
);
142 @param string String to be freed.
144 TRIO_STRING_PUBLIC
void
157 Count the number of characters in a string.
159 @param string String to measure.
160 @return Number of characters in @string.
162 TRIO_STRING_PUBLIC
size_t
165 TRIO_CONST
char *string
)
167 return strlen(string
);
171 #if !defined(TRIO_MINIMAL)
173 Append @p source at the end of @p target.
175 @param target Target string.
176 @param source Source string.
177 @return Boolean value indicating success or failure.
179 @pre @p target must point to a memory chunk with sufficient room to
180 contain the @p target string and @p source string.
181 @pre No boundary checking is performed, so insufficient memory will
182 result in a buffer overrun.
183 @post @p target will be zero terminated.
185 TRIO_STRING_PUBLIC
int
187 TRIO_ARGS2((target
, source
),
189 TRIO_CONST
char *source
)
194 return (strcat(target
, source
) != NULL
);
196 #endif /* !defined(TRIO_MINIMAL) */
198 #if !defined(TRIO_MINIMAL)
200 Append at most @p max characters from @p source to @p target.
202 @param target Target string.
203 @param max Maximum number of characters to append.
204 @param source Source string.
205 @return Boolean value indicating success or failure.
207 @pre @p target must point to a memory chuck with sufficient room to
208 contain the @p target string and the @p source string (at most @p max
210 @pre No boundary checking is performed, so insufficient memory will
211 result in a buffer overrun.
212 @post @p target will be zero terminated.
214 TRIO_STRING_PUBLIC
int
216 TRIO_ARGS3((target
, max
, source
),
219 TRIO_CONST
char *source
)
226 length
= trio_length(target
);
230 strncat(target
, source
, max
- length
- 1);
234 #endif /* !defined(TRIO_MINIMAL) */
237 #if !defined(TRIO_MINIMAL)
239 Determine if a string contains a substring.
241 @param string String to be searched.
242 @param substring String to be found.
243 @return Boolean value indicating success or failure.
245 TRIO_STRING_PUBLIC
int
247 TRIO_ARGS2((string
, substring
),
248 TRIO_CONST
char *string
,
249 TRIO_CONST
char *substring
)
254 return (0 != strstr(string
, substring
));
256 #endif /* !defined(TRIO_MINIMAL) */
259 #if !defined(TRIO_MINIMAL)
261 Copy @p source to @p target.
263 @param target Target string.
264 @param source Source string.
265 @return Boolean value indicating success or failure.
267 @pre @p target must point to a memory chunk with sufficient room to
268 contain the @p source string.
269 @pre No boundary checking is performed, so insufficient memory will
270 result in a buffer overrun.
271 @post @p target will be zero terminated.
273 TRIO_STRING_PUBLIC
int
275 TRIO_ARGS2((target
, source
),
277 TRIO_CONST
char *source
)
282 (void)strcpy(target
, source
);
285 #endif /* !defined(TRIO_MINIMAL) */
289 Copy at most @p max characters from @p source to @p target.
291 @param target Target string.
292 @param max Maximum number of characters to append.
293 @param source Source string.
294 @return Boolean value indicating success or failure.
296 @pre @p target must point to a memory chunk with sufficient room to
297 contain the @p source string (at most @p max characters).
298 @pre No boundary checking is performed, so insufficient memory will
299 result in a buffer overrun.
300 @post @p target will be zero terminated.
302 TRIO_STRING_PUBLIC
int
304 TRIO_ARGS3((target
, max
, source
),
307 TRIO_CONST
char *source
)
311 assert(max
> 0); /* Includes != 0 */
313 (void)strncpy(target
, source
, max
- 1);
314 target
[max
- 1] = (char)0;
322 TRIO_STRING_PRIVATE
char *
324 TRIO_ARGS2((source
, size
),
325 TRIO_CONST
char *source
,
332 /* Make room for string plus a terminating zero */
334 target
= trio_create(size
);
337 trio_copy_max(target
, size
, source
);
346 @param source Source string.
347 @return A copy of the @p source string.
349 @post @p target will be zero terminated.
351 TRIO_STRING_PUBLIC
char *
354 TRIO_CONST
char *source
)
356 return TrioDuplicateMax(source
, trio_length(source
));
360 #if !defined(TRIO_MINIMAL)
362 Duplicate at most @p max characters of @p source.
364 @param source Source string.
365 @param max Maximum number of characters to duplicate.
366 @return A copy of the @p source string.
368 @post @p target will be zero terminated.
370 TRIO_STRING_PUBLIC
char *
371 trio_duplicate_max
TRIO_ARGS2((source
, max
),
372 TRIO_CONST
char *source
,
380 length
= trio_length(source
);
385 return TrioDuplicateMax(source
, length
);
387 #endif /* !defined(TRIO_MINIMAL) */
391 Compare if two strings are equal.
393 @param first First string.
394 @param second Second string.
395 @return Boolean indicating whether the two strings are equal or not.
397 Case-insensitive comparison.
399 TRIO_STRING_PUBLIC
int
401 TRIO_ARGS2((first
, second
),
402 TRIO_CONST
char *first
,
403 TRIO_CONST
char *second
)
408 if ((first
!= NULL
) && (second
!= NULL
))
410 #if defined(USE_STRCASECMP)
411 return (0 == strcasecmp(first
, second
));
413 while ((*first
!= NIL
) && (*second
!= NIL
))
415 if (trio_to_upper(*first
) != trio_to_upper(*second
))
422 return ((*first
== NIL
) && (*second
== NIL
));
430 Compare if two strings are equal.
432 @param first First string.
433 @param second Second string.
434 @return Boolean indicating whether the two strings are equal or not.
436 Case-sensitive comparison.
438 TRIO_STRING_PUBLIC
int
440 TRIO_ARGS2((first
, second
),
441 TRIO_CONST
char *first
,
442 TRIO_CONST
char *second
)
447 if ((first
!= NULL
) && (second
!= NULL
))
449 return (0 == strcmp(first
, second
));
455 #if !defined(TRIO_MINIMAL)
457 Compare if two strings up until the first @p max characters are equal.
459 @param first First string.
460 @param max Maximum number of characters to compare.
461 @param second Second string.
462 @return Boolean indicating whether the two strings are equal or not.
464 Case-sensitive comparison.
466 TRIO_STRING_PUBLIC
int
468 TRIO_ARGS3((first
, max
, second
),
469 TRIO_CONST
char *first
,
471 TRIO_CONST
char *second
)
476 if ((first
!= NULL
) && (second
!= NULL
))
478 return (0 == strncmp(first
, second
, max
));
482 #endif /* !defined(TRIO_MINIMAL) */
486 Compare if two strings are equal.
488 @param first First string.
489 @param second Second string.
490 @return Boolean indicating whether the two strings are equal or not.
492 Collating characters are considered equal.
494 TRIO_STRING_PUBLIC
int
496 TRIO_ARGS2((first
, second
),
497 TRIO_CONST
char *first
,
498 TRIO_CONST
char *second
)
503 #if defined(LC_COLLATE)
504 return (strcoll(first
, second
) == 0);
506 return trio_equal(first
, second
);
512 Compare if two strings up until the first @p max characters are equal.
514 @param first First string.
515 @param max Maximum number of characters to compare.
516 @param second Second string.
517 @return Boolean indicating whether the two strings are equal or not.
519 Case-insensitive comparison.
521 TRIO_STRING_PUBLIC
int
523 TRIO_ARGS3((first
, max
, second
),
524 TRIO_CONST
char *first
,
526 TRIO_CONST
char *second
)
531 if ((first
!= NULL
) && (second
!= NULL
))
533 #if defined(USE_STRNCASECMP)
534 return (0 == strncasecmp(first
, second
, max
));
536 /* Not adequately tested yet */
538 while ((*first
!= NIL
) && (*second
!= NIL
) && (cnt
<= max
))
540 if (trio_to_upper(*first
) != trio_to_upper(*second
))
548 return ((cnt
== max
) || ((*first
== NIL
) && (*second
== NIL
)));
556 Provide a textual description of an error code (errno).
558 @param error_number Error number.
559 @return Textual description of @p error_number.
561 TRIO_STRING_PUBLIC TRIO_CONST
char *
563 TRIO_ARGS1((error_number
),
566 #if defined(USE_STRERROR)
568 return strerror(error_number
);
570 #elif defined(USE_SYS_ERRLIST)
572 extern char *sys_errlist
[];
575 return ((error_number
< 0) || (error_number
>= sys_nerr
))
577 : sys_errlist
[error_number
];
587 #if !defined(TRIO_MINIMAL) && !defined(_WIN32_WCE)
589 Format the date/time according to @p format.
591 @param target Target string.
592 @param max Maximum number of characters to format.
593 @param format Formatting string.
594 @param datetime Date/time structure.
595 @return Number of formatted characters.
597 The formatting string accepts the same specifiers as the standard C
600 TRIO_STRING_PUBLIC
size_t
602 TRIO_ARGS4((target
, max
, format
, datetime
),
605 TRIO_CONST
char *format
,
606 TRIO_CONST
struct tm
*datetime
)
613 return strftime(target
, max
, format
, datetime
);
615 #endif /* !defined(TRIO_MINIMAL) */
618 #if !defined(TRIO_MINIMAL)
620 Calculate a hash value for a string.
622 @param string String to be calculated on.
623 @param type Hash function.
624 @return Calculated hash value.
626 @p type can be one of the following
627 @li @c TRIO_HASH_PLAIN Plain hash function.
629 TRIO_STRING_PUBLIC
unsigned long
631 TRIO_ARGS2((string
, type
),
632 TRIO_CONST
char *string
,
635 unsigned long value
= 0L;
642 case TRIO_HASH_PLAIN
:
643 while ( (ch
= *string
++) != NIL
)
646 value
+= (unsigned long)ch
;
655 #endif /* !defined(TRIO_MINIMAL) */
658 #if !defined(TRIO_MINIMAL)
660 Find first occurrence of a character in a string.
662 @param string String to be searched.
663 @param character Character to be found.
664 @param A pointer to the found character, or NULL if character was not found.
666 TRIO_STRING_PUBLIC
char *
668 TRIO_ARGS2((string
, character
),
669 TRIO_CONST
char *string
,
674 return strchr(string
, character
);
676 #endif /* !defined(TRIO_MINIMAL) */
679 #if !defined(TRIO_MINIMAL)
681 Find last occurrence of a character in a string.
683 @param string String to be searched.
684 @param character Character to be found.
685 @param A pointer to the found character, or NULL if character was not found.
687 TRIO_STRING_PUBLIC
char *
689 TRIO_ARGS2((string
, character
),
690 TRIO_CONST
char *string
,
695 return strchr(string
, character
);
697 #endif /* !defined(TRIO_MINIMAL) */
700 #if !defined(TRIO_MINIMAL)
702 Convert the alphabetic letters in the string to lower-case.
704 @param target String to be converted.
705 @return Number of processed characters (converted or not).
707 TRIO_STRING_PUBLIC
int
714 return trio_span_function(target
, target
, trio_to_lower
);
716 #endif /* !defined(TRIO_MINIMAL) */
719 #if !defined(TRIO_MINIMAL)
721 Compare two strings using wildcards.
723 @param string String to be searched.
724 @param pattern Pattern, including wildcards, to search for.
725 @return Boolean value indicating success or failure.
727 Case-insensitive comparison.
729 The following wildcards can be used
730 @li @c * Match any number of characters.
731 @li @c ? Match a single character.
733 TRIO_STRING_PUBLIC
int
735 TRIO_ARGS2((string
, pattern
),
736 TRIO_CONST
char *string
,
737 TRIO_CONST
char *pattern
)
742 for (; ('*' != *pattern
); ++pattern
, ++string
)
746 return (NIL
== *pattern
);
748 if ((trio_to_upper((int)*string
) != trio_to_upper((int)*pattern
))
749 && ('?' != *pattern
))
754 /* two-line patch to prevent *too* much recursiveness: */
755 while ('*' == pattern
[1])
760 if ( trio_match(string
, &pattern
[1]) )
769 #endif /* !defined(TRIO_MINIMAL) */
772 #if !defined(TRIO_MINIMAL)
774 Compare two strings using wildcards.
776 @param string String to be searched.
777 @param pattern Pattern, including wildcards, to search for.
778 @return Boolean value indicating success or failure.
780 Case-sensitive comparison.
782 The following wildcards can be used
783 @li @c * Match any number of characters.
784 @li @c ? Match a single character.
786 TRIO_STRING_PUBLIC
int
788 TRIO_ARGS2((string
, pattern
),
789 TRIO_CONST
char *string
,
790 TRIO_CONST
char *pattern
)
795 for (; ('*' != *pattern
); ++pattern
, ++string
)
799 return (NIL
== *pattern
);
801 if ((*string
!= *pattern
)
802 && ('?' != *pattern
))
807 /* two-line patch to prevent *too* much recursiveness: */
808 while ('*' == pattern
[1])
813 if ( trio_match_case(string
, &pattern
[1]) )
822 #endif /* !defined(TRIO_MINIMAL) */
825 #if !defined(TRIO_MINIMAL)
827 Execute a function on each character in string.
829 @param target Target string.
830 @param source Source string.
831 @param Function Function to be executed.
832 @return Number of processed characters.
834 TRIO_STRING_PUBLIC
size_t
836 TRIO_ARGS3((target
, source
, Function
),
838 TRIO_CONST
char *source
,
839 int (*Function
) TRIO_PROTO((int)))
847 while (*source
!= NIL
)
849 *target
++ = Function(*source
++);
854 #endif /* !defined(TRIO_MINIMAL) */
857 #if !defined(TRIO_MINIMAL)
859 Search for a substring in a string.
861 @param string String to be searched.
862 @param substring String to be found.
863 @return Pointer to first occurrence of @p substring in @p string, or NULL
864 if no match was found.
866 TRIO_STRING_PUBLIC
char *
868 TRIO_ARGS2((string
, substring
),
869 TRIO_CONST
char *string
,
870 TRIO_CONST
char *substring
)
875 return strstr(string
, substring
);
877 #endif /* !defined(TRIO_MINIMAL) */
880 #if !defined(TRIO_MINIMAL)
882 Search for a substring in the first @p max characters of a string.
884 @param string String to be searched.
885 @param max Maximum characters to be searched.
886 @param substring String to be found.
887 @return Pointer to first occurrence of @p substring in @p string, or NULL
888 if no match was found.
890 TRIO_STRING_PUBLIC
char *
892 TRIO_ARGS3((string
, max
, substring
),
893 TRIO_CONST
char *string
,
895 TRIO_CONST
char *substring
)
904 size
= trio_length(substring
);
907 for (count
= 0; count
<= max
- size
; count
++)
909 if (trio_equal_max(substring
, size
, &string
[count
]))
911 result
= (char *)&string
[count
];
918 #endif /* !defined(TRIO_MINIMAL) */
921 #if !defined(TRIO_MINIMAL)
925 @param string String to be tokenized.
926 @param tokens String containing list of delimiting characters.
927 @return Start of new token.
929 @warning @p string will be destroyed.
931 TRIO_STRING_PUBLIC
char *
933 TRIO_ARGS2((string
, delimiters
),
935 TRIO_CONST
char *delimiters
)
939 return strtok(string
, delimiters
);
941 #endif /* !defined(TRIO_MINIMAL) */
945 Convert string to floating-point number.
947 @param source String to be converted.
948 @param endp Pointer to end of the converted string.
949 @return A floating-point number.
951 The following Extended Backus-Naur form is used
953 double ::= [ <sign> ]
955 <number> <decimal_point> <number> |
956 <decimal_point> <number> )
957 [ <exponential> [ <sign> ] <number> ]
958 number ::= 1*( <digit> )
959 digit ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )
960 exponential ::= ( 'e' | 'E' )
961 sign ::= ( '-' | '+' )
962 decimal_point ::= '.'
965 /* FIXME: Add EBNF for hex-floats */
966 TRIO_STRING_PUBLIC trio_long_double_t
968 TRIO_ARGS2((source
, endp
),
969 TRIO_CONST
char *source
,
972 #if defined(USE_STRTOLD)
973 return strtold(source
, endp
);
975 int isNegative
= FALSE
;
976 int isExponentNegative
= FALSE
;
977 trio_long_double_t integer
= 0.0;
978 trio_long_double_t fraction
= 0.0;
979 unsigned long exponent
= 0;
980 trio_long_double_t base
;
981 trio_long_double_t fracdiv
= 1.0;
982 trio_long_double_t value
= 0.0;
984 /* First try hex-floats */
985 if ((source
[0] == '0') && ((source
[1] == 'x') || (source
[1] == 'X')))
989 while (isxdigit((int)*source
))
992 integer
+= (isdigit((int)*source
)
994 : 10 + (trio_to_upper((int)*source
) - 'A'));
1000 while (isxdigit((int)*source
))
1003 fraction
+= fracdiv
* (isdigit((int)*source
)
1005 : 10 + (trio_to_upper((int)*source
) - 'A'));
1008 if ((*source
== 'p') || (*source
== 'P'))
1011 if ((*source
== '+') || (*source
== '-'))
1013 isExponentNegative
= (*source
== '-');
1016 while (isdigit((int)*source
))
1019 exponent
+= (*source
- '0');
1024 /* For later use with exponent */
1027 else /* Then try normal decimal floats */
1030 isNegative
= (*source
== '-');
1032 if ((*source
== '+') || (*source
== '-'))
1036 while (isdigit((int)*source
))
1039 integer
+= (*source
- '0');
1045 source
++; /* skip decimal point */
1046 while (isdigit((int)*source
))
1049 fraction
+= (*source
- '0') * fracdiv
;
1053 if ((*source
== 'e')
1061 source
++; /* Skip exponential indicator */
1062 isExponentNegative
= (*source
== '-');
1063 if ((*source
== '+') || (*source
== '-'))
1065 while (isdigit((int)*source
))
1067 exponent
*= (int)base
;
1068 exponent
+= (*source
- '0');
1074 value
= integer
+ fraction
;
1077 if (isExponentNegative
)
1078 value
/= pow(base
, (double)exponent
);
1080 value
*= pow(base
, (double)exponent
);
1086 *endp
= (char *)source
;
1093 Convert string to floating-point number.
1095 @param source String to be converted.
1096 @param endp Pointer to end of the converted string.
1097 @return A floating-point number.
1099 See @ref trio_to_long_double.
1101 TRIO_STRING_PUBLIC
double
1103 TRIO_ARGS2((source
, endp
),
1104 TRIO_CONST
char *source
,
1107 #if defined(USE_STRTOD)
1108 return strtod(source
, endp
);
1110 return (double)trio_to_long_double(source
, endp
);
1114 #if !defined(TRIO_MINIMAL)
1116 Convert string to floating-point number.
1118 @param source String to be converted.
1119 @param endp Pointer to end of the converted string.
1120 @return A floating-point number.
1122 See @ref trio_to_long_double.
1124 TRIO_STRING_PUBLIC
float
1126 TRIO_ARGS2((source
, endp
),
1127 TRIO_CONST
char *source
,
1130 #if defined(USE_STRTOF)
1131 return strtof(source
, endp
);
1133 return (float)trio_to_long_double(source
, endp
);
1136 #endif /* !defined(TRIO_MINIMAL) */
1140 Convert string to signed integer.
1142 @param string String to be converted.
1143 @param endp Pointer to end of converted string.
1144 @param base Radix number of number.
1146 TRIO_STRING_PUBLIC
long
1148 TRIO_ARGS3((string
, endp
, base
),
1149 TRIO_CONST
char *string
,
1154 assert((base
>= 2) && (base
<= 36));
1156 return strtol(string
, endp
, base
);
1160 #if !defined(TRIO_MINIMAL)
1162 Convert one alphabetic letter to lower-case.
1164 @param source The letter to be converted.
1165 @return The converted letter.
1167 TRIO_STRING_PUBLIC
int
1169 TRIO_ARGS1((source
),
1172 #if defined(USE_TOLOWER)
1174 return tolower(source
);
1178 /* Does not handle locales or non-contiguous alphabetic characters */
1179 return ((source
>= (int)'A') && (source
<= (int)'Z'))
1180 ? source
- 'A' + 'a'
1185 #endif /* !defined(TRIO_MINIMAL) */
1187 #if !defined(TRIO_MINIMAL)
1189 Convert string to unsigned integer.
1191 @param string String to be converted.
1192 @param endp Pointer to end of converted string.
1193 @param base Radix number of number.
1195 TRIO_STRING_PUBLIC
unsigned long
1196 trio_to_unsigned_long
1197 TRIO_ARGS3((string
, endp
, base
),
1198 TRIO_CONST
char *string
,
1203 assert((base
>= 2) && (base
<= 36));
1205 return strtoul(string
, endp
, base
);
1207 #endif /* !defined(TRIO_MINIMAL) */
1211 Convert one alphabetic letter to upper-case.
1213 @param source The letter to be converted.
1214 @return The converted letter.
1216 TRIO_STRING_PUBLIC
int
1218 TRIO_ARGS1((source
),
1221 #if defined(USE_TOUPPER)
1223 return toupper(source
);
1227 /* Does not handle locales or non-contiguous alphabetic characters */
1228 return ((source
>= (int)'a') && (source
<= (int)'z'))
1229 ? source
- 'a' + 'A'
1235 #if !defined(TRIO_MINIMAL)
1237 Convert the alphabetic letters in the string to upper-case.
1239 @param target The string to be converted.
1240 @return The number of processed characters (converted or not).
1242 TRIO_STRING_PUBLIC
int
1244 TRIO_ARGS1((target
),
1249 return trio_span_function(target
, target
, trio_to_upper
);
1251 #endif /* !defined(TRIO_MINIMAL) */
1254 /** @} End of StaticStrings */
1257 /*************************************************************************
1258 * Dynamic String Functions
1261 #if defined(TRIO_DOCUMENTATION)
1262 # include "doc/doc_dynamic.h"
1264 /** @addtogroup DynamicStrings
1271 TRIO_STRING_PRIVATE trio_string_t
*
1272 TrioStringAlloc(TRIO_NOARGS
)
1274 trio_string_t
*self
;
1276 self
= (trio_string_t
*)TRIO_MALLOC(sizeof(trio_string_t
));
1279 self
->content
= NULL
;
1281 self
->allocated
= 0;
1290 * The size of the string will be increased by 'delta' characters. If
1291 * 'delta' is zero, the size will be doubled.
1293 TRIO_STRING_PRIVATE BOOLEAN_T
1295 TRIO_ARGS2((self
, delta
),
1296 trio_string_t
*self
,
1299 BOOLEAN_T status
= FALSE
;
1303 new_size
= (delta
== 0)
1304 ? ( (self
->allocated
== 0) ? 1 : self
->allocated
* 2 )
1305 : self
->allocated
+ delta
;
1307 new_content
= (char *)TRIO_REALLOC(self
->content
, new_size
);
1310 self
->content
= new_content
;
1311 self
->allocated
= new_size
;
1318 #if !defined(TRIO_MINIMAL)
1322 * The size of the string will be increased to 'length' plus one characters.
1323 * If 'length' is less than the original size, the original size will be
1324 * used (that is, the size of the string is never decreased).
1326 TRIO_STRING_PRIVATE BOOLEAN_T
1328 TRIO_ARGS2((self
, length
),
1329 trio_string_t
*self
,
1332 length
++; /* Room for terminating zero */
1333 return (self
->allocated
< length
)
1334 ? TrioStringGrow(self
, length
- self
->allocated
)
1337 #endif /* !defined(TRIO_MINIMAL) */
1340 #if !defined(TRIO_MINIMAL)
1342 Create a new dynamic string.
1344 @param initial_size Initial size of the buffer.
1345 @return Newly allocated dynamic string, or NULL if memory allocation failed.
1347 TRIO_STRING_PUBLIC trio_string_t
*
1349 TRIO_ARGS1((initial_size
),
1352 trio_string_t
*self
;
1354 self
= TrioStringAlloc();
1357 if (TrioStringGrow(self
,
1358 (size_t)((initial_size
> 0) ? initial_size
: 1)))
1360 self
->content
[0] = (char)0;
1361 self
->allocated
= initial_size
;
1365 trio_string_destroy(self
);
1371 #endif /* !defined(TRIO_MINIMAL) */
1375 Deallocate the dynamic string and its contents.
1377 @param self Dynamic string
1379 TRIO_STRING_PUBLIC
void
1382 trio_string_t
*self
)
1388 trio_destroy(self
->content
);
1394 #if !defined(TRIO_MINIMAL)
1396 Get a pointer to the content.
1398 @param self Dynamic string.
1399 @param offset Offset into content.
1400 @return Pointer to the content.
1402 @p Offset can be zero, positive, or negative. If @p offset is zero,
1403 then the start of the content will be returned. If @p offset is positive,
1404 then a pointer to @p offset number of characters from the beginning of the
1405 content is returned. If @p offset is negative, then a pointer to @p offset
1406 number of characters from the ending of the string, starting at the
1407 terminating zero, is returned.
1409 TRIO_STRING_PUBLIC
char *
1411 TRIO_ARGS2((self
, offset
),
1412 trio_string_t
*self
,
1415 char *result
= NULL
;
1419 if (self
->content
!= NULL
)
1421 if (self
->length
== 0)
1423 (void)trio_string_length(self
);
1427 if (offset
> (int)self
->length
)
1429 offset
= self
->length
;
1434 offset
+= self
->length
+ 1;
1440 result
= &(self
->content
[offset
]);
1444 #endif /* !defined(TRIO_MINIMAL) */
1448 Extract the content.
1450 @param self Dynamic String
1451 @return Content of dynamic string.
1453 The content is removed from the dynamic string. This enables destruction
1454 of the dynamic string without deallocation of the content.
1456 TRIO_STRING_PUBLIC
char *
1459 trio_string_t
*self
)
1465 result
= self
->content
;
1466 /* FIXME: Allocate new empty buffer? */
1467 self
->content
= NULL
;
1468 self
->length
= self
->allocated
= 0;
1473 #if !defined(TRIO_MINIMAL)
1475 Set the content of the dynamic string.
1477 @param self Dynamic String
1478 @param buffer The new content.
1480 Sets the content of the dynamic string to a copy @p buffer.
1481 An existing content will be deallocated first, if necessary.
1484 This function will make a copy of @p buffer.
1485 You are responsible for deallocating @p buffer yourself.
1487 TRIO_STRING_PUBLIC
void
1489 TRIO_ARGS2((self
, buffer
),
1490 trio_string_t
*self
,
1495 trio_destroy(self
->content
);
1496 self
->content
= trio_duplicate(buffer
);
1498 #endif /* !defined(TRIO_MINIMAL) */
1504 TRIO_STRING_PUBLIC
int
1507 trio_string_t
*self
)
1511 return self
->allocated
;
1516 * trio_string_terminate
1518 TRIO_STRING_PUBLIC
void
1519 trio_string_terminate
1521 trio_string_t
*self
)
1523 trio_xstring_append_char(self
, 0);
1527 #if !defined(TRIO_MINIMAL)
1529 Append the second string to the first.
1531 @param self Dynamic string to be modified.
1532 @param other Dynamic string to copy from.
1533 @return Boolean value indicating success or failure.
1535 TRIO_STRING_PUBLIC
int
1537 TRIO_ARGS2((self
, other
),
1538 trio_string_t
*self
,
1539 trio_string_t
*other
)
1546 length
= self
->length
+ other
->length
;
1547 if (!TrioStringGrowTo(self
, length
))
1549 trio_copy(&self
->content
[self
->length
], other
->content
);
1550 self
->length
= length
;
1556 #endif /* !defined(TRIO_MINIMAL) */
1559 #if !defined(TRIO_MINIMAL)
1561 * trio_xstring_append
1563 TRIO_STRING_PUBLIC
int
1565 TRIO_ARGS2((self
, other
),
1566 trio_string_t
*self
,
1567 TRIO_CONST
char *other
)
1574 length
= self
->length
+ trio_length(other
);
1575 if (!TrioStringGrowTo(self
, length
))
1577 trio_copy(&self
->content
[self
->length
], other
);
1578 self
->length
= length
;
1584 #endif /* !defined(TRIO_MINIMAL) */
1588 * trio_xstring_append_char
1590 TRIO_STRING_PUBLIC
int
1591 trio_xstring_append_char
1592 TRIO_ARGS2((self
, character
),
1593 trio_string_t
*self
,
1598 if ((int)self
->length
>= trio_string_size(self
))
1600 if (!TrioStringGrow(self
, 0))
1603 self
->content
[self
->length
] = character
;
1612 #if !defined(TRIO_MINIMAL)
1614 Search for the first occurrence of second parameter in the first.
1616 @param self Dynamic string to be modified.
1617 @param other Dynamic string to copy from.
1618 @return Boolean value indicating success or failure.
1620 TRIO_STRING_PUBLIC
int
1621 trio_string_contains
1622 TRIO_ARGS2((self
, other
),
1623 trio_string_t
*self
,
1624 trio_string_t
*other
)
1629 return trio_contains(self
->content
, other
->content
);
1631 #endif /* !defined(TRIO_MINIMAL) */
1634 #if !defined(TRIO_MINIMAL)
1636 * trio_xstring_contains
1638 TRIO_STRING_PUBLIC
int
1639 trio_xstring_contains
1640 TRIO_ARGS2((self
, other
),
1641 trio_string_t
*self
,
1642 TRIO_CONST
char *other
)
1647 return trio_contains(self
->content
, other
);
1649 #endif /* !defined(TRIO_MINIMAL) */
1652 #if !defined(TRIO_MINIMAL)
1656 TRIO_STRING_PUBLIC
int
1658 TRIO_ARGS2((self
, other
),
1659 trio_string_t
*self
,
1660 trio_string_t
*other
)
1666 return trio_string_append(self
, other
);
1668 #endif /* !defined(TRIO_MINIMAL) */
1671 #if !defined(TRIO_MINIMAL)
1675 TRIO_STRING_PUBLIC
int
1677 TRIO_ARGS2((self
, other
),
1678 trio_string_t
*self
,
1679 TRIO_CONST
char *other
)
1685 return trio_xstring_append(self
, other
);
1687 #endif /* !defined(TRIO_MINIMAL) */
1690 #if !defined(TRIO_MINIMAL)
1692 * trio_string_duplicate
1694 TRIO_STRING_PUBLIC trio_string_t
*
1695 trio_string_duplicate
1697 trio_string_t
*other
)
1699 trio_string_t
*self
;
1703 self
= TrioStringAlloc();
1706 self
->content
= TrioDuplicateMax(other
->content
, other
->length
);
1709 self
->length
= other
->length
;
1710 self
->allocated
= self
->length
+ 1;
1714 self
->length
= self
->allocated
= 0;
1719 #endif /* !defined(TRIO_MINIMAL) */
1723 * trio_xstring_duplicate
1725 TRIO_STRING_PUBLIC trio_string_t
*
1726 trio_xstring_duplicate
1728 TRIO_CONST
char *other
)
1730 trio_string_t
*self
;
1734 self
= TrioStringAlloc();
1737 self
->content
= TrioDuplicateMax(other
, trio_length(other
));
1740 self
->length
= trio_length(self
->content
);
1741 self
->allocated
= self
->length
+ 1;
1745 self
->length
= self
->allocated
= 0;
1752 #if !defined(TRIO_MINIMAL)
1756 TRIO_STRING_PUBLIC
int
1758 TRIO_ARGS2((self
, other
),
1759 trio_string_t
*self
,
1760 trio_string_t
*other
)
1765 return trio_equal(self
->content
, other
->content
);
1767 #endif /* !defined(TRIO_MINIMAL) */
1770 #if !defined(TRIO_MINIMAL)
1772 * trio_xstring_equal
1774 TRIO_STRING_PUBLIC
int
1776 TRIO_ARGS2((self
, other
),
1777 trio_string_t
*self
,
1778 TRIO_CONST
char *other
)
1783 return trio_equal(self
->content
, other
);
1785 #endif /* !defined(TRIO_MINIMAL) */
1788 #if !defined(TRIO_MINIMAL)
1790 * trio_string_equal_max
1792 TRIO_STRING_PUBLIC
int
1793 trio_string_equal_max
1794 TRIO_ARGS3((self
, max
, other
),
1795 trio_string_t
*self
,
1797 trio_string_t
*other
)
1802 return trio_equal_max(self
->content
, max
, other
->content
);
1804 #endif /* !defined(TRIO_MINIMAL) */
1807 #if !defined(TRIO_MINIMAL)
1809 * trio_xstring_equal_max
1811 TRIO_STRING_PUBLIC
int
1812 trio_xstring_equal_max
1813 TRIO_ARGS3((self
, max
, other
),
1814 trio_string_t
*self
,
1816 TRIO_CONST
char *other
)
1821 return trio_equal_max(self
->content
, max
, other
);
1823 #endif /* !defined(TRIO_MINIMAL) */
1826 #if !defined(TRIO_MINIMAL)
1828 * trio_string_equal_case
1830 TRIO_STRING_PUBLIC
int
1831 trio_string_equal_case
1832 TRIO_ARGS2((self
, other
),
1833 trio_string_t
*self
,
1834 trio_string_t
*other
)
1839 return trio_equal_case(self
->content
, other
->content
);
1841 #endif /* !defined(TRIO_MINIMAL) */
1844 #if !defined(TRIO_MINIMAL)
1846 * trio_xstring_equal_case
1848 TRIO_STRING_PUBLIC
int
1849 trio_xstring_equal_case
1850 TRIO_ARGS2((self
, other
),
1851 trio_string_t
*self
,
1852 TRIO_CONST
char *other
)
1857 return trio_equal_case(self
->content
, other
);
1859 #endif /* !defined(TRIO_MINIMAL) */
1862 #if !defined(TRIO_MINIMAL)
1864 * trio_string_equal_case_max
1866 TRIO_STRING_PUBLIC
int
1867 trio_string_equal_case_max
1868 TRIO_ARGS3((self
, max
, other
),
1869 trio_string_t
*self
,
1871 trio_string_t
*other
)
1876 return trio_equal_case_max(self
->content
, max
, other
->content
);
1878 #endif /* !defined(TRIO_MINIMAL) */
1881 #if !defined(TRIO_MINIMAL)
1883 * trio_xstring_equal_case_max
1885 TRIO_STRING_PUBLIC
int
1886 trio_xstring_equal_case_max
1887 TRIO_ARGS3((self
, max
, other
),
1888 trio_string_t
*self
,
1890 TRIO_CONST
char *other
)
1895 return trio_equal_case_max(self
->content
, max
, other
);
1897 #endif /* !defined(TRIO_MINIMAL) */
1900 #if !defined(TRIO_MINIMAL) && !defined(_WIN32_WCE)
1902 * trio_string_format_data_max
1904 TRIO_STRING_PUBLIC
size_t
1905 trio_string_format_date_max
1906 TRIO_ARGS4((self
, max
, format
, datetime
),
1907 trio_string_t
*self
,
1909 TRIO_CONST
char *format
,
1910 TRIO_CONST
struct tm
*datetime
)
1914 return trio_format_date_max(self
->content
, max
, format
, datetime
);
1916 #endif /* !defined(TRIO_MINIMAL) */
1919 #if !defined(TRIO_MINIMAL)
1923 TRIO_STRING_PUBLIC
char *
1925 TRIO_ARGS2((self
, character
),
1926 trio_string_t
*self
,
1931 return trio_index(self
->content
, character
);
1933 #endif /* !defined(TRIO_MINIMAL) */
1936 #if !defined(TRIO_MINIMAL)
1938 * trio_string_index_last
1940 TRIO_STRING_PUBLIC
char *
1941 trio_string_index_last
1942 TRIO_ARGS2((self
, character
),
1943 trio_string_t
*self
,
1948 return trio_index_last(self
->content
, character
);
1950 #endif /* !defined(TRIO_MINIMAL) */
1953 #if !defined(TRIO_MINIMAL)
1955 * trio_string_length
1957 TRIO_STRING_PUBLIC
int
1960 trio_string_t
*self
)
1964 if (self
->length
== 0)
1966 self
->length
= trio_length(self
->content
);
1968 return self
->length
;
1970 #endif /* !defined(TRIO_MINIMAL) */
1973 #if !defined(TRIO_MINIMAL)
1977 TRIO_STRING_PUBLIC
int
1980 trio_string_t
*self
)
1984 return trio_lower(self
->content
);
1986 #endif /* !defined(TRIO_MINIMAL) */
1989 #if !defined(TRIO_MINIMAL)
1993 TRIO_STRING_PUBLIC
int
1995 TRIO_ARGS2((self
, other
),
1996 trio_string_t
*self
,
1997 trio_string_t
*other
)
2002 return trio_match(self
->content
, other
->content
);
2004 #endif /* !defined(TRIO_MINIMAL) */
2007 #if !defined(TRIO_MINIMAL)
2009 * trio_xstring_match
2011 TRIO_STRING_PUBLIC
int
2013 TRIO_ARGS2((self
, other
),
2014 trio_string_t
*self
,
2015 TRIO_CONST
char *other
)
2020 return trio_match(self
->content
, other
);
2022 #endif /* !defined(TRIO_MINIMAL) */
2025 #if !defined(TRIO_MINIMAL)
2027 * trio_string_match_case
2029 TRIO_STRING_PUBLIC
int
2030 trio_string_match_case
2031 TRIO_ARGS2((self
, other
),
2032 trio_string_t
*self
,
2033 trio_string_t
*other
)
2038 return trio_match_case(self
->content
, other
->content
);
2040 #endif /* !defined(TRIO_MINIMAL) */
2043 #if !defined(TRIO_MINIMAL)
2045 * trio_xstring_match_case
2047 TRIO_STRING_PUBLIC
int
2048 trio_xstring_match_case
2049 TRIO_ARGS2((self
, other
),
2050 trio_string_t
*self
,
2051 TRIO_CONST
char *other
)
2056 return trio_match_case(self
->content
, other
);
2058 #endif /* !defined(TRIO_MINIMAL) */
2061 #if !defined(TRIO_MINIMAL)
2063 * trio_string_substring
2065 TRIO_STRING_PUBLIC
char *
2066 trio_string_substring
2067 TRIO_ARGS2((self
, other
),
2068 trio_string_t
*self
,
2069 trio_string_t
*other
)
2074 return trio_substring(self
->content
, other
->content
);
2076 #endif /* !defined(TRIO_MINIMAL) */
2079 #if !defined(TRIO_MINIMAL)
2081 * trio_xstring_substring
2083 TRIO_STRING_PUBLIC
char *
2084 trio_xstring_substring
2085 TRIO_ARGS2((self
, other
),
2086 trio_string_t
*self
,
2087 TRIO_CONST
char *other
)
2092 return trio_substring(self
->content
, other
);
2094 #endif /* !defined(TRIO_MINIMAL) */
2097 #if !defined(TRIO_MINIMAL)
2101 TRIO_STRING_PUBLIC
int
2104 trio_string_t
*self
)
2108 return trio_upper(self
->content
);
2110 #endif /* !defined(TRIO_MINIMAL) */
2112 /** @} End of DynamicStrings */