1 /*************************************************************************
2  *
3  * $Id: triostr.c,v 1.36 2010/01/26 13:02:02 breese Exp $
4  *
5  * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
6  *
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.
10  *
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.
15  *
16  ************************************************************************/
17 
18 /*************************************************************************
19  * Include files
20  */
21 
22 #if defined(HAVE_CONFIG_H)
23 #include <config.h>
24 #endif
25 #include <assert.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <limits.h>
29 #include <ctype.h>
30 #include "triodef.h"
31 #include "triostr.h"
32 #if defined(TRIO_FUNC_TO_LONG_DOUBLE)
33 #define USE_MATH
34 #endif
35 #if defined(USE_MATH)
36 #include <math.h>
37 #endif
38 
39 /*************************************************************************
40  * Definitions
41  */
42 
43 #if !defined(TRIO_PUBLIC_STRING)
44 #define TRIO_PUBLIC_STRING TRIO_PUBLIC
45 #endif
46 #if !defined(TRIO_PRIVATE_STRING)
47 #define TRIO_PRIVATE_STRING TRIO_PRIVATE
48 #endif
49 
50 #if !defined(NULL)
51 #define NULL 0
52 #endif
53 #if !defined(NIL)
54 #define NIL ((char)0)
55 #endif
56 #if !defined(FALSE)
57 #define FALSE (1 == 0)
58 #define TRUE (!FALSE)
59 #endif
60 #if !defined(BOOLEAN_T)
61 #define BOOLEAN_T int
62 #endif
63 
64 #if defined(USE_MATH)
65 #if defined(PREDEF_STANDARD_C99)
66 #if defined(TRIO_COMPILER_DECC)
67 #if (TRIO_COMPILER_DECC - 0 > 80000000)
68 /*
69  * The OSF/1 runtime that comes with the DECC compiler does not support
70  * hexfloats conversion.
71  */
72 #define USE_STRTOD
73 #define USE_STRTOF
74 #endif
75 #else
76 #define USE_STRTOD
77 #define USE_STRTOF
78 #endif
79 #else
80 #if defined(TRIO_COMPILER_VISUALC)
81 #define USE_STRTOD
82 #endif
83 #endif
84 #endif
85 
86 #if defined(TRIO_PLATFORM_UNIX)
87 #if defined(PREDEF_STANDARD_UNIX95)
88 #define USE_STRCASECMP
89 #define USE_STRNCASECMP
90 #endif
91 #if defined(TRIO_PLATFORM_SUNOS)
92 #define USE_SYS_ERRLIST
93 #else
94 #define USE_STRERROR
95 #endif
96 #if defined(TRIO_PLATFORM_QNX)
97 #define strcasecmp(x, y) stricmp(x, y)
98 #define strncasecmp(x, y, n) strnicmp(x, y, n)
99 #endif
100 #endif
101 
102 #if defined(TRIO_PLATFORM_WIN32)
103 #define USE_STRCASECMP
104 #if defined(TRIO_PLATFORM_WINCE)
105 #define strcasecmp(x, y) _stricmp(x, y)
106 #else
107 #define strcasecmp(x, y) _stricmp(x, y)
108 #endif
109 #endif
110 
111 #if !defined(HAVE_CONFIG_H)
112 #if !(defined(TRIO_PLATFORM_SUNOS))
113 #define HAVE_TOLOWER
114 #define HAVE_TOUPPER
115 #endif
116 #endif
117 
118 #if defined(USE_MATH) && !defined(TRIO_NO_POWL)
119 #if !defined(HAVE_POWL)
120 #if defined(PREDEF_STANDARD_C99) || defined(PREDEF_STANDARD_UNIX03)
121 #define HAVE_POWL
122 #else
123 #if defined(TRIO_COMPILER_VISUALC)
124 #if defined(powl)
125 #define HAVE_POWL
126 #endif
127 #endif
128 #endif
129 #endif
130 #endif
131 
132 #if defined(HAVE_POWL)
133 #define trio_powl(x, y) powl((x), (y))
134 #else
135 #define trio_powl(x, y) pow((double)(x), (double)(y))
136 #endif
137 
138 #if defined(TRIO_FUNC_TO_UPPER) || (defined(TRIO_FUNC_EQUAL) && !defined(USE_STRCASECMP)) ||   \
139     (defined(TRIO_FUNC_EQUAL_MAX) && !defined(USE_STRNCASECMP)) || defined(TRIO_FUNC_MATCH) || \
140     defined(TRIO_FUNC_TO_LONG_DOUBLE) || defined(TRIO_FUNC_UPPER)
141 #define TRIO_FUNC_INTERNAL_TO_UPPER
142 #endif
143 
144 /*************************************************************************
145  * Structures
146  */
147 
148 struct _trio_string_t
149 {
150 	char* content;
151 	size_t length;
152 	size_t allocated;
153 };
154 
155 /*************************************************************************
156  * Constants
157  */
158 
159 #if !defined(TRIO_EMBED_STRING)
160 /* Unused but kept for reference */
161 /* static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c,v 1.36 2010/01/26 13:02:02 breese Exp $"; */
162 #endif
163 
164 /*************************************************************************
165  * Static String Functions
166  */
167 
168 #if defined(TRIO_DOCUMENTATION)
169 #include "doc/doc_static.h"
170 #endif
171 /** @addtogroup StaticStrings
172     @{
173 */
174 
175 /*
176  * internal_duplicate_max
177  */
178 #if defined(TRIO_FUNC_DUPLICATE) || defined(TRIO_FUNC_DUPLICATE_MAX) || \
179     defined(TRIO_FUNC_STRING_DUPLICATE) || defined(TRIO_FUNC_XSTRING_DUPLICATE)
180 
181 TRIO_PRIVATE_STRING char* internal_duplicate_max TRIO_ARGS2((source, size), TRIO_CONST char* source,
182                                                             size_t size)
183 {
184 	char* target;
185 
186 	assert(source);
187 
188 	/* Make room for string plus a terminating zero */
189 	size++;
190 	target = trio_create(size);
191 	if (target)
192 	{
193 		trio_copy_max(target, size, source);
194 	}
195 	return target;
196 }
197 
198 #endif
199 
200 /*
201  * internal_string_alloc
202  */
203 #if defined(TRIO_FUNC_STRING_CREATE) || defined(TRIO_FUNC_STRING_DUPLICATE) || \
204     defined(TRIO_FUNC_XSTRING_DUPLICATE)
205 
internal_string_alloc(TRIO_NOARGS)206 TRIO_PRIVATE_STRING trio_string_t* internal_string_alloc(TRIO_NOARGS)
207 {
208 	trio_string_t* self;
209 
210 	self = (trio_string_t*)TRIO_MALLOC(sizeof(trio_string_t));
211 	if (self)
212 	{
213 		self->content = NULL;
214 		self->length = 0;
215 		self->allocated = 0;
216 	}
217 	return self;
218 }
219 
220 #endif
221 
222 /*
223  * internal_string_grow
224  *
225  * The size of the string will be increased by 'delta' characters. If
226  * 'delta' is zero, the size will be doubled.
227  */
228 #if defined(TRIO_FUNC_STRING_CREATE) || defined(TRIO_FUNC_STRING_APPEND) || \
229     defined(TRIO_FUNC_XSTRING_APPEND) || defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
230 
231 TRIO_PRIVATE_STRING BOOLEAN_T internal_string_grow TRIO_ARGS2((self, delta), trio_string_t* self,
232                                                               size_t delta)
233 {
234 	BOOLEAN_T status = FALSE;
235 	char* new_content;
236 	size_t new_size;
237 
238 	new_size =
239 	    (delta == 0) ? ((self->allocated == 0) ? 1 : self->allocated * 2) : self->allocated + delta;
240 
241 	new_content = (char*)TRIO_REALLOC(self->content, new_size);
242 	if (new_content)
243 	{
244 		self->content = new_content;
245 		self->allocated = new_size;
246 		status = TRUE;
247 	}
248 	return status;
249 }
250 
251 #endif
252 
253 /*
254  * internal_string_grow_to
255  *
256  * The size of the string will be increased to 'length' plus one characters.
257  * If 'length' is less than the original size, the original size will be
258  * used (that is, the size of the string is never decreased).
259  */
260 #if defined(TRIO_FUNC_STRING_APPEND) || defined(TRIO_FUNC_XSTRING_APPEND) || \
261     defined(TRIO_FUNC_XSTRING_APPEND_MAX)
262 
263 TRIO_PRIVATE_STRING BOOLEAN_T internal_string_grow_to TRIO_ARGS2((self, length),
264                                                                  trio_string_t* self, size_t length)
265 {
266 	length++; /* Room for terminating zero */
267 	return (self->allocated < length) ? internal_string_grow(self, length - self->allocated) : TRUE;
268 }
269 
270 #endif
271 
272 #if defined(TRIO_FUNC_INTERNAL_TO_UPPER)
273 
274 TRIO_PRIVATE_STRING TRIO_INLINE int internal_to_upper TRIO_ARGS1((source), int source)
275 {
276 #if defined(HAVE_TOUPPER)
277 
278 	return toupper(source);
279 
280 #else
281 
282 	/* Does not handle locales or non-contiguous alphabetic characters */
283 	return ((source >= (int)'a') && (source <= (int)'z')) ? source - 'a' + 'A' : source;
284 
285 #endif
286 }
287 
288 #endif
289 
290 /**
291    Create new string.
292 
293    @param size Size of new string.
294    @return Pointer to string, or NULL if allocation failed.
295 */
296 #if defined(TRIO_FUNC_CREATE)
297 
298 TRIO_PUBLIC_STRING char* trio_create TRIO_ARGS1((size), size_t size)
299 {
300 	return (char*)TRIO_MALLOC(size);
301 }
302 
303 #endif
304 
305 /**
306    Destroy string.
307 
308    @param string String to be freed.
309 */
310 #if defined(TRIO_FUNC_DESTROY)
311 
312 TRIO_PUBLIC_STRING void trio_destroy TRIO_ARGS1((string), char* string)
313 {
314 	if (string)
315 	{
316 		TRIO_FREE(string);
317 	}
318 }
319 
320 #endif
321 
322 /**
323    Count the number of characters in a string.
324 
325    @param string String to measure.
326    @return Number of characters in @p string.
327 */
328 #if defined(TRIO_FUNC_LENGTH)
329 
330 TRIO_PUBLIC_STRING size_t trio_length TRIO_ARGS1((string), TRIO_CONST char* string)
331 {
332 	return trio_length_max(string, INT_MAX);
333 }
334 
335 #endif
336 
337 /**
338    Count at most @p max characters in a string.
339 
340    @param string String to measure.
341    @param max Maximum number of characters to count.
342    @return The maximum value of @p max and number of characters in @p string.
343 */
344 #if defined(TRIO_FUNC_LENGTH_MAX)
345 
346 TRIO_PUBLIC_STRING size_t trio_length_max TRIO_ARGS2((string, max), TRIO_CONST char* string,
347                                                      size_t max)
348 {
349 	size_t i;
350 
351 	for (i = 0; i < max; ++i)
352 	{
353 		if (string[i] == 0)
354 			break;
355 	}
356 	return i;
357 }
358 
359 #endif
360 
361 /**
362    Append @p source at the end of @p target.
363 
364    @param target Target string.
365    @param source Source string.
366    @return Boolean value indicating success or failure.
367 
368    @pre @p target must point to a memory chunk with sufficient room to
369    contain the @p target string and @p source string.
370    @pre No boundary checking is performed, so insufficient memory will
371    result in a buffer overrun.
372    @post @p target will be zero terminated.
373 */
374 #if defined(TRIO_FUNC_APPEND)
375 
376 TRIO_PUBLIC_STRING int trio_append TRIO_ARGS2((target, source), char* target,
377                                               TRIO_CONST char* source)
378 {
379 	assert(target);
380 	assert(source);
381 
382 	return (strcat(target, source) != NULL);
383 }
384 
385 #endif
386 
387 /**
388    Append at most @p max characters from @p source to @p target.
389 
390    @param target Target string.
391    @param max Maximum number of characters to append.
392    @param source Source string.
393    @return Boolean value indicating success or failure.
394 
395    @pre @p target must point to a memory chuck with sufficient room to
396    contain the @p target string and the @p source string (at most @p max
397    characters).
398    @pre No boundary checking is performed, so insufficient memory will
399    result in a buffer overrun.
400    @post @p target will be zero terminated.
401 */
402 #if defined(TRIO_FUNC_APPEND_MAX)
403 
404 TRIO_PUBLIC_STRING int trio_append_max TRIO_ARGS3((target, max, source), char* target, size_t max,
405                                                   TRIO_CONST char* source)
406 {
407 	size_t length;
408 
409 	assert(target);
410 	assert(source);
411 
412 	length = trio_length(target);
413 
414 	if (max > length)
415 	{
416 		strncat(target, source, max - length - 1);
417 	}
418 	return TRUE;
419 }
420 
421 #endif
422 
423 /**
424    Determine if a string contains a substring.
425 
426    @param string String to be searched.
427    @param substring String to be found.
428    @return Boolean value indicating success or failure.
429 */
430 #if defined(TRIO_FUNC_CONTAINS)
431 
432 TRIO_PUBLIC_STRING int trio_contains TRIO_ARGS2((string, substring), TRIO_CONST char* string,
433                                                 TRIO_CONST char* substring)
434 {
435 	assert(string);
436 	assert(substring);
437 
438 	return (0 != strstr(string, substring));
439 }
440 
441 #endif
442 
443 /**
444    Copy @p source to @p target.
445 
446    @param target Target string.
447    @param source Source string.
448    @return Boolean value indicating success or failure.
449 
450    @pre @p target must point to a memory chunk with sufficient room to
451    contain the @p source string.
452    @pre No boundary checking is performed, so insufficient memory will
453    result in a buffer overrun.
454    @post @p target will be zero terminated.
455 */
456 #if defined(TRIO_FUNC_COPY)
457 
458 TRIO_PUBLIC_STRING int trio_copy TRIO_ARGS2((target, source), char* target, TRIO_CONST char* source)
459 {
460 	assert(target);
461 	assert(source);
462 
463 	(void)strcpy(target, source);
464 	return TRUE;
465 }
466 
467 #endif
468 
469 /**
470    Copy at most @p max - 1 characters from @p source to @p target.
471 
472    @param target Target string.
473    @param max Maximum number of characters to append (one of which is
474    a NUL terminator).  In other words @p source must point to at least
475    @p max - 1 bytes, but @p target must point to at least @p max
476    bytes.
477    @param source Source string.
478    @return Boolean value indicating success or failure.
479 
480    @pre @p target must point to a memory chunk with sufficient room to
481    contain the @p source string and a NUL terminator (at most @p max
482    bytes total).
483    @pre No boundary checking is performed, so insufficient memory will
484    result in a buffer overrun.
485    @post @p target will be zero terminated.
486 */
487 #if defined(TRIO_FUNC_COPY_MAX)
488 
489 TRIO_PUBLIC_STRING int trio_copy_max TRIO_ARGS3((target, max, source), char* target, size_t max,
490                                                 TRIO_CONST char* source)
491 {
492 	assert(target);
493 	assert(source);
494 	assert(max > 0); /* Includes != 0 */
495 
496 	(void)strncpy(target, source, max - 1);
497 	target[max - 1] = (char)0;
498 	return TRUE;
499 }
500 
501 #endif
502 
503 /**
504    Duplicate @p source.
505 
506    @param source Source string.
507    @return A copy of the @p source string.
508 
509    @post @p target will be zero terminated.
510 */
511 #if defined(TRIO_FUNC_DUPLICATE)
512 
513 TRIO_PUBLIC_STRING char* trio_duplicate TRIO_ARGS1((source), TRIO_CONST char* source)
514 {
515 	return internal_duplicate_max(source, trio_length(source));
516 }
517 
518 #endif
519 
520 /**
521    Duplicate at most @p max characters of @p source.
522 
523    @param source Source string.
524    @param max Maximum number of characters to duplicate.
525    @return A copy of the @p source string.
526 
527    @post @p target will be zero terminated.
528 */
529 #if defined(TRIO_FUNC_DUPLICATE_MAX)
530 
531 TRIO_PUBLIC_STRING char* trio_duplicate_max TRIO_ARGS2((source, max), TRIO_CONST char* source,
532                                                        size_t max)
533 {
534 	size_t length;
535 
536 	assert(source);
537 	assert(max > 0);
538 
539 	length = trio_length(source);
540 	if (length > max)
541 	{
542 		length = max;
543 	}
544 	return internal_duplicate_max(source, length);
545 }
546 
547 #endif
548 
549 /**
550    Compare if two strings are equal.
551 
552    @param first First string.
553    @param second Second string.
554    @return Boolean indicating whether the two strings are equal or not.
555 
556    Case-insensitive comparison.
557 */
558 #if defined(TRIO_FUNC_EQUAL)
559 
560 TRIO_PUBLIC_STRING int trio_equal TRIO_ARGS2((first, second), TRIO_CONST char* first,
561                                              TRIO_CONST char* second)
562 {
563 	assert(first);
564 	assert(second);
565 
566 	if ((first != NULL) && (second != NULL))
567 	{
568 #if defined(USE_STRCASECMP)
569 		return (0 == strcasecmp(first, second));
570 #else
571 		while ((*first != NIL) && (*second != NIL))
572 		{
573 			if (internal_to_upper(*first) != internal_to_upper(*second))
574 			{
575 				break;
576 			}
577 			first++;
578 			second++;
579 		}
580 		return ((*first == NIL) && (*second == NIL));
581 #endif
582 	}
583 	return FALSE;
584 }
585 
586 #endif
587 
588 /**
589    Compare if two strings are equal.
590 
591    @param first First string.
592    @param second Second string.
593    @return Boolean indicating whether the two strings are equal or not.
594 
595    Case-sensitive comparison.
596 */
597 #if defined(TRIO_FUNC_EQUAL_CASE)
598 
599 TRIO_PUBLIC_STRING int trio_equal_case TRIO_ARGS2((first, second), TRIO_CONST char* first,
600                                                   TRIO_CONST char* second)
601 {
602 	assert(first);
603 	assert(second);
604 
605 	if ((first != NULL) && (second != NULL))
606 	{
607 		return (0 == strcmp(first, second));
608 	}
609 	return FALSE;
610 }
611 
612 #endif
613 
614 /**
615    Compare if two strings up until the first @p max characters are equal.
616 
617    @param first First string.
618    @param max Maximum number of characters to compare.
619    @param second Second string.
620    @return Boolean indicating whether the two strings are equal or not.
621 
622    Case-sensitive comparison.
623 */
624 #if defined(TRIO_FUNC_EQUAL_CASE_MAX)
625 
626 TRIO_PUBLIC_STRING int trio_equal_case_max TRIO_ARGS3((first, max, second), TRIO_CONST char* first,
627                                                       size_t max, TRIO_CONST char* second)
628 {
629 	assert(first);
630 	assert(second);
631 
632 	if ((first != NULL) && (second != NULL))
633 	{
634 		return (0 == strncmp(first, second, max));
635 	}
636 	return FALSE;
637 }
638 
639 #endif
640 
641 /**
642    Compare if two strings are equal.
643 
644    @param first First string.
645    @param second Second string.
646    @return Boolean indicating whether the two strings are equal or not.
647 
648    Collating characters are considered equal.
649 */
650 #if defined(TRIO_FUNC_EQUAL_LOCALE)
651 
652 TRIO_PUBLIC_STRING int trio_equal_locale TRIO_ARGS2((first, second), TRIO_CONST char* first,
653                                                     TRIO_CONST char* second)
654 {
655 	assert(first);
656 	assert(second);
657 
658 #if defined(LC_COLLATE)
659 	return (strcoll(first, second) == 0);
660 #else
661 	return trio_equal(first, second);
662 #endif
663 }
664 
665 #endif
666 
667 /**
668    Compare if two strings up until the first @p max characters are equal.
669 
670    @param first First string.
671    @param max Maximum number of characters to compare.
672    @param second Second string.
673    @return Boolean indicating whether the two strings are equal or not.
674 
675    Case-insensitive comparison.
676 */
677 #if defined(TRIO_FUNC_EQUAL_MAX)
678 
679 TRIO_PUBLIC_STRING int trio_equal_max TRIO_ARGS3((first, max, second), TRIO_CONST char* first,
680                                                  size_t max, TRIO_CONST char* second)
681 {
682 	assert(first);
683 	assert(second);
684 
685 	if ((first != NULL) && (second != NULL))
686 	{
687 #if defined(USE_STRNCASECMP)
688 		return (0 == strncasecmp(first, second, max));
689 #else
690 		/* Not adequately tested yet */
691 		size_t cnt = 0;
692 		while ((*first != NIL) && (*second != NIL) && (cnt <= max))
693 		{
694 			if (internal_to_upper(*first) != internal_to_upper(*second))
695 			{
696 				break;
697 			}
698 			first++;
699 			second++;
700 			cnt++;
701 		}
702 		return ((cnt == max) || ((*first == NIL) && (*second == NIL)));
703 #endif
704 	}
705 	return FALSE;
706 }
707 
708 #endif
709 
710 /**
711    Provide a textual description of an error code (errno).
712 
713    @param error_number Error number.
714    @return Textual description of @p error_number.
715 */
716 #if defined(TRIO_FUNC_ERROR)
717 
718 TRIO_PUBLIC_STRING TRIO_CONST char* trio_error TRIO_ARGS1((error_number), int error_number)
719 {
720 #if defined(USE_STRERROR)
721 
722 	return strerror(error_number);
723 
724 #else
725 #if defined(USE_SYS_ERRLIST)
726 
727 	extern char* sys_errlist[];
728 	extern int sys_nerr;
729 
730 	return ((error_number < 0) || (error_number >= sys_nerr)) ? "unknown"
731 	                                                          : sys_errlist[error_number];
732 
733 #else
734 
735 	return "unknown";
736 
737 #endif
738 #endif
739 }
740 
741 #endif
742 
743 /**
744    Format the date/time according to @p format.
745 
746    @param target Target string.
747    @param max Maximum number of characters to format.
748    @param format Formatting string.
749    @param datetime Date/time structure.
750    @return Number of formatted characters.
751 
752    The formatting string accepts the same specifiers as the standard C
753    function strftime.
754 */
755 #if defined(TRIO_FUNC_FORMAT_DATE_MAX)
756 
757 TRIO_PUBLIC_STRING size_t trio_format_date_max TRIO_ARGS4((target, max, format, datetime),
758                                                           char* target, size_t max,
759                                                           TRIO_CONST char* format,
760                                                           TRIO_CONST struct tm* datetime)
761 {
762 	assert(target);
763 	assert(format);
764 	assert(datetime);
765 	assert(max > 0);
766 
767 	return strftime(target, max, format, datetime);
768 }
769 
770 #endif
771 
772 /**
773    Calculate a hash value for a string.
774 
775    @param string String to be calculated on.
776    @param type Hash function.
777    @return Calculated hash value.
778 
779    @p type can be one of the following
780    @li @c TRIO_HASH_PLAIN Plain hash function.
781 */
782 #if defined(TRIO_FUNC_HASH)
783 
784 TRIO_PUBLIC_STRING unsigned long trio_hash TRIO_ARGS2((string, type), TRIO_CONST char* string,
785                                                       int type)
786 {
787 	unsigned long value = 0L;
788 	char ch;
789 
790 	assert(string);
791 
792 	switch (type)
793 	{
794 		case TRIO_HASH_PLAIN:
795 			while ((ch = *string++) != NIL)
796 			{
797 				value *= 31;
798 				value += (unsigned long)ch;
799 			}
800 			break;
801 		default:
802 			assert(FALSE);
803 			break;
804 	}
805 	return value;
806 }
807 
808 #endif
809 
810 /**
811    Find first occurrence of a character in a string.
812 
813    @param string String to be searched.
814    @param character Character to be found.
815    @return A pointer to the found character, or NULL if character was not found.
816  */
817 #if defined(TRIO_FUNC_INDEX)
818 
819 TRIO_PUBLIC_STRING char* trio_index TRIO_ARGS2((string, character), TRIO_CONST char* string,
820                                                int character)
821 {
822 	assert(string);
823 
824 	return strchr(string, character);
825 }
826 
827 #endif
828 
829 /**
830    Find last occurrence of a character in a string.
831 
832    @param string String to be searched.
833    @param character Character to be found.
834    @return A pointer to the found character, or NULL if character was not found.
835  */
836 #if defined(TRIO_FUNC_INDEX_LAST)
837 
838 TRIO_PUBLIC_STRING char* trio_index_last TRIO_ARGS2((string, character), TRIO_CONST char* string,
839                                                     int character)
840 {
841 	assert(string);
842 
843 	return strchr(string, character);
844 }
845 
846 #endif
847 
848 /**
849    Convert the alphabetic letters in the string to lower-case.
850 
851    @param target String to be converted.
852    @return Number of processed characters (converted or not).
853 */
854 #if defined(TRIO_FUNC_LOWER)
855 
856 TRIO_PUBLIC_STRING int trio_lower TRIO_ARGS1((target), char* target)
857 {
858 	assert(target);
859 
860 	return trio_span_function(target, target, trio_to_lower);
861 }
862 
863 #endif
864 
865 /**
866    Compare two strings using wildcards.
867 
868    @param string String to be searched.
869    @param pattern Pattern, including wildcards, to search for.
870    @return Boolean value indicating success or failure.
871 
872    Case-insensitive comparison.
873 
874    The following wildcards can be used
875    @li @c * Match any number of characters.
876    @li @c ? Match a single character.
877 */
878 #if defined(TRIO_FUNC_MATCH)
879 
880 TRIO_PUBLIC_STRING int trio_match TRIO_ARGS2((string, pattern), TRIO_CONST char* string,
881                                              TRIO_CONST char* pattern)
882 {
883 	assert(string);
884 	assert(pattern);
885 
886 	for (; ('*' != *pattern); ++pattern, ++string)
887 	{
888 		if (NIL == *string)
889 		{
890 			return (NIL == *pattern);
891 		}
892 		if ((internal_to_upper((int)*string) != internal_to_upper((int)*pattern)) &&
893 		    ('?' != *pattern))
894 		{
895 			return FALSE;
896 		}
897 	}
898 	/* two-line patch to prevent *too* much recursiveness: */
899 	while ('*' == pattern[1])
900 		pattern++;
901 
902 	do
903 	{
904 		if (trio_match(string, &pattern[1]))
905 		{
906 			return TRUE;
907 		}
908 	} while (*string++);
909 
910 	return FALSE;
911 }
912 
913 #endif
914 
915 /**
916    Compare two strings using wildcards.
917 
918    @param string String to be searched.
919    @param pattern Pattern, including wildcards, to search for.
920    @return Boolean value indicating success or failure.
921 
922    Case-sensitive comparison.
923 
924    The following wildcards can be used
925    @li @c * Match any number of characters.
926    @li @c ? Match a single character.
927 */
928 #if defined(TRIO_FUNC_MATCH_CASE)
929 
930 TRIO_PUBLIC_STRING int trio_match_case TRIO_ARGS2((string, pattern), TRIO_CONST char* string,
931                                                   TRIO_CONST char* pattern)
932 {
933 	assert(string);
934 	assert(pattern);
935 
936 	for (; ('*' != *pattern); ++pattern, ++string)
937 	{
938 		if (NIL == *string)
939 		{
940 			return (NIL == *pattern);
941 		}
942 		if ((*string != *pattern) && ('?' != *pattern))
943 		{
944 			return FALSE;
945 		}
946 	}
947 	/* two-line patch to prevent *too* much recursiveness: */
948 	while ('*' == pattern[1])
949 		pattern++;
950 
951 	do
952 	{
953 		if (trio_match_case(string, &pattern[1]))
954 		{
955 			return TRUE;
956 		}
957 	} while (*string++);
958 
959 	return FALSE;
960 }
961 
962 #endif
963 
964 /**
965    Execute a function on each character in string.
966 
967    @param target Target string.
968    @param source Source string.
969    @param Function Function to be executed.
970    @return Number of processed characters.
971 */
972 #if defined(TRIO_FUNC_SPAN_FUNCTION)
973 
974 TRIO_PUBLIC_STRING size_t trio_span_function TRIO_ARGS3((target, source, Function), char* target,
975                                                         TRIO_CONST char* source,
976                                                         int(*Function) TRIO_PROTO((int)))
977 {
978 	size_t count = 0;
979 
980 	assert(target);
981 	assert(source);
982 	assert(Function);
983 
984 	while (*source != NIL)
985 	{
986 		*target++ = Function(*source++);
987 		count++;
988 	}
989 	return count;
990 }
991 
992 #endif
993 
994 /**
995    Search for a substring in a string.
996 
997    @param string String to be searched.
998    @param substring String to be found.
999    @return Pointer to first occurrence of @p substring in @p string, or NULL
1000    if no match was found.
1001 */
1002 #if defined(TRIO_FUNC_SUBSTRING)
1003 
1004 TRIO_PUBLIC_STRING char* trio_substring TRIO_ARGS2((string, substring), TRIO_CONST char* string,
1005                                                    TRIO_CONST char* substring)
1006 {
1007 	assert(string);
1008 	assert(substring);
1009 
1010 	return strstr(string, substring);
1011 }
1012 
1013 #endif
1014 
1015 /**
1016    Search for a substring in the first @p max characters of a string.
1017 
1018    @param string String to be searched.
1019    @param max Maximum characters to be searched.
1020    @param substring String to be found.
1021    @return Pointer to first occurrence of @p substring in @p string, or NULL
1022    if no match was found.
1023 */
1024 #if defined(TRIO_FUNC_SUBSTRING_MAX)
1025 
1026 TRIO_PUBLIC_STRING char* trio_substring_max TRIO_ARGS3((string, max, substring),
1027                                                        TRIO_CONST char* string, size_t max,
1028                                                        TRIO_CONST char* substring)
1029 {
1030 	size_t count;
1031 	size_t size;
1032 	char* result = NULL;
1033 
1034 	assert(string);
1035 	assert(substring);
1036 
1037 	size = trio_length(substring);
1038 	if (size <= max)
1039 	{
1040 		for (count = 0; count <= max - size; count++)
1041 		{
1042 			if (trio_equal_max(substring, size, &string[count]))
1043 			{
1044 				result = (char*)&string[count];
1045 				break;
1046 			}
1047 		}
1048 	}
1049 	return result;
1050 }
1051 
1052 #endif
1053 
1054 /**
1055    Tokenize string.
1056 
1057    @param string String to be tokenized.
1058    @param delimiters String containing list of delimiting characters.
1059    @return Start of new token.
1060 
1061    @warning @p string will be destroyed.
1062 */
1063 #if defined(TRIO_FUNC_TOKENIZE)
1064 
1065 TRIO_PUBLIC_STRING char* trio_tokenize TRIO_ARGS2((string, delimiters), char* string,
1066                                                   TRIO_CONST char* delimiters)
1067 {
1068 	assert(delimiters);
1069 
1070 	return strtok(string, delimiters);
1071 }
1072 
1073 #endif
1074 
1075 /**
1076    Convert string to floating-point number.
1077 
1078    @param source String to be converted.
1079    @param endp Pointer to end of the converted string.
1080    @return A floating-point number.
1081 
1082    The following Extended Backus-Naur form is used
1083    @verbatim
1084    double        ::= [ <sign> ]
1085                      ( <number> |
1086                        <number> <decimal_point> <number> |
1087                        <decimal_point> <number> )
1088                      [ <exponential> [ <sign> ] <number> ]
1089    number        ::= 1*( <digit> )
1090    digit         ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )
1091    exponential   ::= ( 'e' | 'E' )
1092    sign          ::= ( '-' | '+' )
1093    decimal_point ::= '.'
1094    @endverbatim
1095 */
1096 #if defined(TRIO_FUNC_TO_LONG_DOUBLE)
1097 
1098 /* FIXME: Add EBNF for hex-floats */
1099 TRIO_PUBLIC_STRING trio_long_double_t trio_to_long_double TRIO_ARGS2((source, endp),
1100                                                                      TRIO_CONST char* source,
1101                                                                      char** endp)
1102 {
1103 #if defined(USE_STRTOLD)
1104 	return strtold(source, endp);
1105 #else
1106 	int isNegative = FALSE;
1107 	int isExponentNegative = FALSE;
1108 	trio_long_double_t integer = 0.0;
1109 	trio_long_double_t fraction = 0.0;
1110 	unsigned long exponent = 0;
1111 	trio_long_double_t base;
1112 	trio_long_double_t fracdiv = 1.0;
1113 	trio_long_double_t value = 0.0;
1114 
1115 	/* First try hex-floats */
1116 	if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X')))
1117 	{
1118 		base = 16.0;
1119 		source += 2;
1120 		while (isxdigit((int)*source))
1121 		{
1122 			integer *= base;
1123 			integer += (isdigit((int)*source) ? (*source - '0')
1124 			                                  : 10 + (internal_to_upper((int)*source) - 'A'));
1125 			source++;
1126 		}
1127 		if (*source == '.')
1128 		{
1129 			source++;
1130 			while (isxdigit((int)*source))
1131 			{
1132 				fracdiv /= base;
1133 				fraction += fracdiv * (isdigit((int)*source)
1134 				                           ? (*source - '0')
1135 				                           : 10 + (internal_to_upper((int)*source) - 'A'));
1136 				source++;
1137 			}
1138 			if ((*source == 'p') || (*source == 'P'))
1139 			{
1140 				source++;
1141 				if ((*source == '+') || (*source == '-'))
1142 				{
1143 					isExponentNegative = (*source == '-');
1144 					source++;
1145 				}
1146 				while (isdigit((int)*source))
1147 				{
1148 					exponent *= 10;
1149 					exponent += (*source - '0');
1150 					source++;
1151 				}
1152 			}
1153 		}
1154 		/* For later use with exponent */
1155 		base = 2.0;
1156 	}
1157 	else /* Then try normal decimal floats */
1158 	{
1159 		base = 10.0;
1160 		isNegative = (*source == '-');
1161 		/* Skip sign */
1162 		if ((*source == '+') || (*source == '-'))
1163 			source++;
1164 
1165 		/* Integer part */
1166 		while (isdigit((int)*source))
1167 		{
1168 			integer *= base;
1169 			integer += (*source - '0');
1170 			source++;
1171 		}
1172 
1173 		if (*source == '.')
1174 		{
1175 			source++; /* skip decimal point */
1176 			while (isdigit((int)*source))
1177 			{
1178 				fracdiv /= base;
1179 				fraction += (*source - '0') * fracdiv;
1180 				source++;
1181 			}
1182 		}
1183 		if ((*source == 'e') || (*source == 'E')
1184 #if TRIO_MICROSOFT
1185 		    || (*source == 'd') || (*source == 'D')
1186 #endif
1187 		)
1188 		{
1189 			source++; /* Skip exponential indicator */
1190 			isExponentNegative = (*source == '-');
1191 			if ((*source == '+') || (*source == '-'))
1192 				source++;
1193 			while (isdigit((int)*source))
1194 			{
1195 				exponent *= (int)base;
1196 				exponent += (*source - '0');
1197 				source++;
1198 			}
1199 		}
1200 	}
1201 
1202 	value = integer + fraction;
1203 	if (exponent != 0)
1204 	{
1205 		if (isExponentNegative)
1206 			value /= trio_powl(base, (trio_long_double_t)exponent);
1207 		else
1208 			value *= trio_powl(base, (trio_long_double_t)exponent);
1209 	}
1210 	if (isNegative)
1211 		value = -value;
1212 
1213 	if (endp)
1214 		*endp = (char*)source;
1215 	return value;
1216 #endif
1217 }
1218 
1219 #endif
1220 
1221 /**
1222    Convert string to floating-point number.
1223 
1224    @param source String to be converted.
1225    @param endp Pointer to end of the converted string.
1226    @return A floating-point number.
1227 
1228    See @ref trio_to_long_double.
1229 */
1230 #if defined(TRIO_FUNC_TO_DOUBLE)
1231 
1232 TRIO_PUBLIC_STRING double trio_to_double TRIO_ARGS2((source, endp), TRIO_CONST char* source,
1233                                                     char** endp)
1234 {
1235 #if defined(USE_STRTOD)
1236 	return strtod(source, endp);
1237 #else
1238 	return (double)trio_to_long_double(source, endp);
1239 #endif
1240 }
1241 
1242 #endif
1243 
1244 /**
1245    Convert string to floating-point number.
1246 
1247    @param source String to be converted.
1248    @param endp Pointer to end of the converted string.
1249    @return A floating-point number.
1250 
1251    See @ref trio_to_long_double.
1252 */
1253 #if defined(TRIO_FUNC_TO_FLOAT)
1254 
1255 TRIO_PUBLIC_STRING float trio_to_float TRIO_ARGS2((source, endp), TRIO_CONST char* source,
1256                                                   char** endp)
1257 {
1258 #if defined(USE_STRTOF)
1259 	return strtof(source, endp);
1260 #else
1261 	return (float)trio_to_long_double(source, endp);
1262 #endif
1263 }
1264 
1265 #endif
1266 
1267 /**
1268    Convert string to signed integer.
1269 
1270    @param string String to be converted.
1271    @param endp Pointer to end of converted string.
1272    @param base Radix number of number.
1273 */
1274 #if defined(TRIO_FUNC_TO_LONG)
1275 
1276 TRIO_PUBLIC_STRING long trio_to_long TRIO_ARGS3((string, endp, base), TRIO_CONST char* string,
1277                                                 char** endp, int base)
1278 {
1279 	assert(string);
1280 	assert((base >= 2) && (base <= 36));
1281 
1282 	return strtol(string, endp, base);
1283 }
1284 
1285 #endif
1286 
1287 /**
1288    Convert one alphabetic letter to lower-case.
1289 
1290    @param source The letter to be converted.
1291    @return The converted letter.
1292 */
1293 #if defined(TRIO_FUNC_TO_LOWER)
1294 
1295 TRIO_PUBLIC_STRING int trio_to_lower TRIO_ARGS1((source), int source)
1296 {
1297 #if defined(HAVE_TOLOWER)
1298 
1299 	return tolower(source);
1300 
1301 #else
1302 
1303 	/* Does not handle locales or non-contiguous alphabetic characters */
1304 	return ((source >= (int)'A') && (source <= (int)'Z')) ? source - 'A' + 'a' : source;
1305 
1306 #endif
1307 }
1308 
1309 #endif
1310 
1311 /**
1312    Convert string to unsigned integer.
1313 
1314    @param string String to be converted.
1315    @param endp Pointer to end of converted string.
1316    @param base Radix number of number.
1317 */
1318 #if defined(TRIO_FUNC_TO_UNSIGNED_LONG)
1319 
1320 TRIO_PUBLIC_STRING unsigned long trio_to_unsigned_long TRIO_ARGS3((string, endp, base),
1321                                                                   TRIO_CONST char* string,
1322                                                                   char** endp, int base)
1323 {
1324 	assert(string);
1325 	assert((base >= 2) && (base <= 36));
1326 
1327 	return strtoul(string, endp, base);
1328 }
1329 
1330 #endif
1331 
1332 /**
1333    Convert one alphabetic letter to upper-case.
1334 
1335    @param source The letter to be converted.
1336    @return The converted letter.
1337 */
1338 #if defined(TRIO_FUNC_TO_UPPER)
1339 
1340 TRIO_PUBLIC_STRING int trio_to_upper TRIO_ARGS1((source), int source)
1341 {
1342 	return internal_to_upper(source);
1343 }
1344 
1345 #endif
1346 
1347 /**
1348    Convert the alphabetic letters in the string to upper-case.
1349 
1350    @param target The string to be converted.
1351    @return The number of processed characters (converted or not).
1352 */
1353 #if defined(TRIO_FUNC_UPPER)
1354 
1355 TRIO_PUBLIC_STRING int trio_upper TRIO_ARGS1((target), char* target)
1356 {
1357 	assert(target);
1358 
1359 	return trio_span_function(target, target, internal_to_upper);
1360 }
1361 
1362 #endif
1363 
1364 /** @} End of StaticStrings */
1365 
1366 /*************************************************************************
1367  * Dynamic String Functions
1368  */
1369 
1370 #if defined(TRIO_DOCUMENTATION)
1371 #include "doc/doc_dynamic.h"
1372 #endif
1373 /** @addtogroup DynamicStrings
1374     @{
1375 */
1376 
1377 /**
1378    Create a new dynamic string.
1379 
1380    @param initial_size Initial size of the buffer.
1381    @return Newly allocated dynamic string, or NULL if memory allocation failed.
1382 */
1383 #if defined(TRIO_FUNC_STRING_CREATE)
1384 
1385 TRIO_PUBLIC_STRING trio_string_t* trio_string_create TRIO_ARGS1((initial_size), int initial_size)
1386 {
1387 	trio_string_t* self;
1388 
1389 	self = internal_string_alloc();
1390 	if (self)
1391 	{
1392 		if (internal_string_grow(self, (size_t)((initial_size > 0) ? initial_size : 1)))
1393 		{
1394 			self->content[0] = (char)0;
1395 			self->allocated = initial_size;
1396 		}
1397 		else
1398 		{
1399 			trio_string_destroy(self);
1400 			self = NULL;
1401 		}
1402 	}
1403 	return self;
1404 }
1405 
1406 #endif
1407 
1408 /**
1409    Deallocate the dynamic string and its contents.
1410 
1411    @param self Dynamic string
1412 */
1413 #if defined(TRIO_FUNC_STRING_DESTROY)
1414 
1415 TRIO_PUBLIC_STRING void trio_string_destroy TRIO_ARGS1((self), trio_string_t* self)
1416 {
1417 	assert(self);
1418 
1419 	if (self)
1420 	{
1421 		trio_destroy(self->content);
1422 		TRIO_FREE(self);
1423 	}
1424 }
1425 
1426 #endif
1427 
1428 /**
1429    Get a pointer to the content.
1430 
1431    @param self Dynamic string.
1432    @param offset Offset into content.
1433    @return Pointer to the content.
1434 
1435    @p Offset can be zero, positive, or negative. If @p offset is zero,
1436    then the start of the content will be returned. If @p offset is positive,
1437    then a pointer to @p offset number of characters from the beginning of the
1438    content is returned. If @p offset is negative, then a pointer to @p offset
1439    number of characters from the ending of the string, starting at the
1440    terminating zero, is returned.
1441 */
1442 #if defined(TRIO_FUNC_STRING_GET)
1443 
1444 TRIO_PUBLIC_STRING char* trio_string_get TRIO_ARGS2((self, offset), trio_string_t* self, int offset)
1445 {
1446 	char* result = NULL;
1447 
1448 	assert(self);
1449 
1450 	if (self->content != NULL)
1451 	{
1452 		if (self->length == 0)
1453 		{
1454 			(void)trio_string_length(self);
1455 		}
1456 		if (offset >= 0)
1457 		{
1458 			if (offset > (int)self->length)
1459 			{
1460 				offset = self->length;
1461 			}
1462 		}
1463 		else
1464 		{
1465 			offset += self->length + 1;
1466 			if (offset < 0)
1467 			{
1468 				offset = 0;
1469 			}
1470 		}
1471 		result = &(self->content[offset]);
1472 	}
1473 	return result;
1474 }
1475 
1476 #endif
1477 
1478 /**
1479    Extract the content.
1480 
1481    @param self Dynamic String
1482    @return Content of dynamic string.
1483 
1484    The content is removed from the dynamic string. This enables destruction
1485    of the dynamic string without deallocation of the content.
1486 */
1487 #if defined(TRIO_FUNC_STRING_EXTRACT)
1488 
1489 TRIO_PUBLIC_STRING char* trio_string_extract TRIO_ARGS1((self), trio_string_t* self)
1490 {
1491 	char* result;
1492 
1493 	assert(self);
1494 
1495 	result = self->content;
1496 	/* FIXME: Allocate new empty buffer? */
1497 	self->content = NULL;
1498 	self->length = self->allocated = 0;
1499 	return result;
1500 }
1501 
1502 #endif
1503 
1504 /**
1505    Set the content of the dynamic string.
1506 
1507    @param self Dynamic String
1508    @param buffer The new content.
1509 
1510    Sets the content of the dynamic string to a copy @p buffer.
1511    An existing content will be deallocated first, if necessary.
1512 
1513    @remark
1514    This function will make a copy of @p buffer.
1515    You are responsible for deallocating @p buffer yourself.
1516 */
1517 #if defined(TRIO_FUNC_XSTRING_SET)
1518 
1519 TRIO_PUBLIC_STRING void trio_xstring_set TRIO_ARGS2((self, buffer), trio_string_t* self,
1520                                                     char* buffer)
1521 {
1522 	assert(self);
1523 
1524 	trio_destroy(self->content);
1525 	self->content = trio_duplicate(buffer);
1526 }
1527 
1528 #endif
1529 
1530 /*
1531  * trio_string_size
1532  */
1533 #if defined(TRIO_FUNC_STRING_SIZE)
1534 
1535 TRIO_PUBLIC_STRING int trio_string_size TRIO_ARGS1((self), trio_string_t* self)
1536 {
1537 	assert(self);
1538 
1539 	return self->allocated;
1540 }
1541 
1542 #endif
1543 
1544 /*
1545  * trio_string_terminate
1546  */
1547 #if defined(TRIO_FUNC_STRING_TERMINATE)
1548 
1549 TRIO_PUBLIC_STRING void trio_string_terminate TRIO_ARGS1((self), trio_string_t* self)
1550 {
1551 	trio_xstring_append_char(self, 0);
1552 }
1553 
1554 #endif
1555 
1556 /**
1557    Append the second string to the first.
1558 
1559    @param self Dynamic string to be modified.
1560    @param other Dynamic string to copy from.
1561    @return Boolean value indicating success or failure.
1562 */
1563 #if defined(TRIO_FUNC_STRING_APPEND)
1564 
1565 TRIO_PUBLIC_STRING int trio_string_append TRIO_ARGS2((self, other), trio_string_t* self,
1566                                                      trio_string_t* other)
1567 {
1568 	size_t length;
1569 
1570 	assert(self);
1571 	assert(other);
1572 
1573 	length = self->length + other->length;
1574 	if (!internal_string_grow_to(self, length))
1575 		goto error;
1576 	trio_copy(&self->content[self->length], other->content);
1577 	self->length = length;
1578 	return TRUE;
1579 
1580 error:
1581 	return FALSE;
1582 }
1583 
1584 #endif
1585 
1586 /*
1587  * trio_xstring_append
1588  */
1589 #if defined(TRIO_FUNC_XSTRING_APPEND)
1590 
1591 TRIO_PUBLIC_STRING int trio_xstring_append TRIO_ARGS2((self, other), trio_string_t* self,
1592                                                       TRIO_CONST char* other)
1593 {
1594 	size_t length;
1595 
1596 	assert(self);
1597 	assert(other);
1598 
1599 	length = self->length + trio_length(other);
1600 	if (!internal_string_grow_to(self, length))
1601 		goto error;
1602 	trio_copy(&self->content[self->length], other);
1603 	self->length = length;
1604 	return TRUE;
1605 
1606 error:
1607 	return FALSE;
1608 }
1609 
1610 #endif
1611 
1612 /*
1613  * trio_xstring_append_char
1614  */
1615 #if defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
1616 
1617 TRIO_PUBLIC_STRING int trio_xstring_append_char TRIO_ARGS2((self, character), trio_string_t* self,
1618                                                            char character)
1619 {
1620 	assert(self);
1621 
1622 	if ((int)self->length >= trio_string_size(self))
1623 	{
1624 		if (!internal_string_grow(self, 0))
1625 			goto error;
1626 	}
1627 	self->content[self->length] = character;
1628 	self->length++;
1629 	return TRUE;
1630 
1631 error:
1632 	return FALSE;
1633 }
1634 
1635 #endif
1636 
1637 /*
1638  * trio_xstring_append_max
1639  */
1640 #if defined(TRIO_FUNC_XSTRING_APPEND_MAX)
1641 
1642 TRIO_PUBLIC_STRING int trio_xstring_append_max TRIO_ARGS3((self, other, max), trio_string_t* self,
1643                                                           TRIO_CONST char* other, size_t max)
1644 {
1645 	size_t length;
1646 
1647 	assert(self);
1648 	assert(other);
1649 
1650 	length = self->length + trio_length_max(other, max);
1651 	if (!internal_string_grow_to(self, length))
1652 		goto error;
1653 
1654 	/*
1655 	 * Pass max + 1 since trio_copy_max copies one character less than
1656 	 * this from the source to make room for a terminating zero.
1657 	 */
1658 	trio_copy_max(&self->content[self->length], max + 1, other);
1659 	self->length = length;
1660 	return TRUE;
1661 
1662 error:
1663 	return FALSE;
1664 }
1665 
1666 #endif
1667 
1668 /**
1669    Search for the first occurrence of second parameter in the first.
1670 
1671    @param self Dynamic string to be modified.
1672    @param other Dynamic string to copy from.
1673    @return Boolean value indicating success or failure.
1674 */
1675 #if defined(TRIO_FUNC_STRING_CONTAINS)
1676 
1677 TRIO_PUBLIC_STRING int trio_string_contains TRIO_ARGS2((self, other), trio_string_t* self,
1678                                                        trio_string_t* other)
1679 {
1680 	assert(self);
1681 	assert(other);
1682 
1683 	return trio_contains(self->content, other->content);
1684 }
1685 
1686 #endif
1687 
1688 /*
1689  * trio_xstring_contains
1690  */
1691 #if defined(TRIO_FUNC_XSTRING_CONTAINS)
1692 
1693 TRIO_PUBLIC_STRING int trio_xstring_contains TRIO_ARGS2((self, other), trio_string_t* self,
1694                                                         TRIO_CONST char* other)
1695 {
1696 	assert(self);
1697 	assert(other);
1698 
1699 	return trio_contains(self->content, other);
1700 }
1701 
1702 #endif
1703 
1704 /*
1705  * trio_string_copy
1706  */
1707 #if defined(TRIO_FUNC_STRING_COPY)
1708 
1709 TRIO_PUBLIC_STRING int trio_string_copy TRIO_ARGS2((self, other), trio_string_t* self,
1710                                                    trio_string_t* other)
1711 {
1712 	assert(self);
1713 	assert(other);
1714 
1715 	self->length = 0;
1716 	return trio_string_append(self, other);
1717 }
1718 
1719 #endif
1720 
1721 /*
1722  * trio_xstring_copy
1723  */
1724 #if defined(TRIO_FUNC_XSTRING_COPY)
1725 
1726 TRIO_PUBLIC_STRING int trio_xstring_copy TRIO_ARGS2((self, other), trio_string_t* self,
1727                                                     TRIO_CONST char* other)
1728 {
1729 	assert(self);
1730 	assert(other);
1731 
1732 	self->length = 0;
1733 	return trio_xstring_append(self, other);
1734 }
1735 
1736 #endif
1737 
1738 /*
1739  * trio_string_duplicate
1740  */
1741 #if defined(TRIO_FUNC_STRING_DUPLICATE)
1742 
1743 TRIO_PUBLIC_STRING trio_string_t* trio_string_duplicate TRIO_ARGS1((other), trio_string_t* other)
1744 {
1745 	trio_string_t* self;
1746 
1747 	assert(other);
1748 
1749 	self = internal_string_alloc();
1750 	if (self)
1751 	{
1752 		self->content = internal_duplicate_max(other->content, other->length);
1753 		if (self->content)
1754 		{
1755 			self->length = other->length;
1756 			self->allocated = self->length + 1;
1757 		}
1758 		else
1759 		{
1760 			self->length = self->allocated = 0;
1761 		}
1762 	}
1763 	return self;
1764 }
1765 
1766 #endif
1767 
1768 /*
1769  * trio_xstring_duplicate
1770  */
1771 #if defined(TRIO_FUNC_XSTRING_DUPLICATE)
1772 
1773 TRIO_PUBLIC_STRING trio_string_t* trio_xstring_duplicate TRIO_ARGS1((other), TRIO_CONST char* other)
1774 {
1775 	trio_string_t* self;
1776 
1777 	assert(other);
1778 
1779 	self = internal_string_alloc();
1780 	if (self)
1781 	{
1782 		self->content = internal_duplicate_max(other, trio_length(other));
1783 		if (self->content)
1784 		{
1785 			self->length = trio_length(self->content);
1786 			self->allocated = self->length + 1;
1787 		}
1788 		else
1789 		{
1790 			self->length = self->allocated = 0;
1791 		}
1792 	}
1793 	return self;
1794 }
1795 
1796 #endif
1797 
1798 /*
1799  * trio_string_equal
1800  */
1801 #if defined(TRIO_FUNC_STRING_EQUAL)
1802 
1803 TRIO_PUBLIC_STRING int trio_string_equal TRIO_ARGS2((self, other), trio_string_t* self,
1804                                                     trio_string_t* other)
1805 {
1806 	assert(self);
1807 	assert(other);
1808 
1809 	return trio_equal(self->content, other->content);
1810 }
1811 
1812 #endif
1813 
1814 /*
1815  * trio_xstring_equal
1816  */
1817 #if defined(TRIO_FUNC_XSTRING_EQUAL)
1818 
1819 TRIO_PUBLIC_STRING int trio_xstring_equal TRIO_ARGS2((self, other), trio_string_t* self,
1820                                                      TRIO_CONST char* other)
1821 {
1822 	assert(self);
1823 	assert(other);
1824 
1825 	return trio_equal(self->content, other);
1826 }
1827 
1828 #endif
1829 
1830 /*
1831  * trio_string_equal_max
1832  */
1833 #if defined(TRIO_FUNC_STRING_EQUAL_MAX)
1834 
1835 TRIO_PUBLIC_STRING int trio_string_equal_max TRIO_ARGS3((self, max, other), trio_string_t* self,
1836                                                         size_t max, trio_string_t* other)
1837 {
1838 	assert(self);
1839 	assert(other);
1840 
1841 	return trio_equal_max(self->content, max, other->content);
1842 }
1843 #endif
1844 
1845 /*
1846  * trio_xstring_equal_max
1847  */
1848 #if defined(TRIO_FUNC_XSTRING_EQUAL_MAX)
1849 
1850 TRIO_PUBLIC_STRING int trio_xstring_equal_max TRIO_ARGS3((self, max, other), trio_string_t* self,
1851                                                          size_t max, TRIO_CONST char* other)
1852 {
1853 	assert(self);
1854 	assert(other);
1855 
1856 	return trio_equal_max(self->content, max, other);
1857 }
1858 
1859 #endif
1860 
1861 /*
1862  * trio_string_equal_case
1863  */
1864 #if defined(TRIO_FUNC_STRING_EQUAL_CASE)
1865 
1866 TRIO_PUBLIC_STRING int trio_string_equal_case TRIO_ARGS2((self, other), trio_string_t* self,
1867                                                          trio_string_t* other)
1868 {
1869 	assert(self);
1870 	assert(other);
1871 
1872 	return trio_equal_case(self->content, other->content);
1873 }
1874 
1875 #endif
1876 
1877 /*
1878  * trio_xstring_equal_case
1879  */
1880 #if defined(TRIO_FUNC_XSTRING_EQUAL_CASE)
1881 
1882 TRIO_PUBLIC_STRING int trio_xstring_equal_case TRIO_ARGS2((self, other), trio_string_t* self,
1883                                                           TRIO_CONST char* other)
1884 {
1885 	assert(self);
1886 	assert(other);
1887 
1888 	return trio_equal_case(self->content, other);
1889 }
1890 
1891 #endif
1892 
1893 /*
1894  * trio_string_equal_case_max
1895  */
1896 #if defined(TRIO_FUNC_STRING_EQUAL_CASE_MAX)
1897 
1898 TRIO_PUBLIC_STRING int trio_string_equal_case_max TRIO_ARGS3((self, max, other),
1899                                                              trio_string_t* self, size_t max,
1900                                                              trio_string_t* other)
1901 {
1902 	assert(self);
1903 	assert(other);
1904 
1905 	return trio_equal_case_max(self->content, max, other->content);
1906 }
1907 
1908 #endif
1909 
1910 /*
1911  * trio_xstring_equal_case_max
1912  */
1913 #if defined(TRIO_FUNC_XSTRING_EQUAL_CASE_MAX)
1914 
1915 TRIO_PUBLIC_STRING int trio_xstring_equal_case_max TRIO_ARGS3((self, max, other),
1916                                                               trio_string_t* self, size_t max,
1917                                                               TRIO_CONST char* other)
1918 {
1919 	assert(self);
1920 	assert(other);
1921 
1922 	return trio_equal_case_max(self->content, max, other);
1923 }
1924 
1925 #endif
1926 
1927 /*
1928  * trio_string_format_data_max
1929  */
1930 #if defined(TRIO_FUNC_STRING_FORMAT_DATE_MAX)
1931 
1932 TRIO_PUBLIC_STRING size_t trio_string_format_date_max TRIO_ARGS4((self, max, format, datetime),
1933                                                                  trio_string_t* self, size_t max,
1934                                                                  TRIO_CONST char* format,
1935                                                                  TRIO_CONST struct tm* datetime)
1936 {
1937 	assert(self);
1938 
1939 	return trio_format_date_max(self->content, max, format, datetime);
1940 }
1941 
1942 #endif
1943 
1944 /*
1945  * trio_string_index
1946  */
1947 #if defined(TRIO_FUNC_STRING_INDEX)
1948 
1949 TRIO_PUBLIC_STRING char* trio_string_index TRIO_ARGS2((self, character), trio_string_t* self,
1950                                                       int character)
1951 {
1952 	assert(self);
1953 
1954 	return trio_index(self->content, character);
1955 }
1956 
1957 #endif
1958 
1959 /*
1960  * trio_string_index_last
1961  */
1962 #if defined(TRIO_FUNC_STRING_INDEX_LAST)
1963 
1964 TRIO_PUBLIC_STRING char* trio_string_index_last TRIO_ARGS2((self, character), trio_string_t* self,
1965                                                            int character)
1966 {
1967 	assert(self);
1968 
1969 	return trio_index_last(self->content, character);
1970 }
1971 
1972 #endif
1973 
1974 /*
1975  * trio_string_length
1976  */
1977 #if defined(TRIO_FUNC_STRING_LENGTH)
1978 
1979 TRIO_PUBLIC_STRING int trio_string_length TRIO_ARGS1((self), trio_string_t* self)
1980 {
1981 	assert(self);
1982 
1983 	if (self->length == 0)
1984 	{
1985 		self->length = trio_length(self->content);
1986 	}
1987 	return self->length;
1988 }
1989 
1990 #endif
1991 
1992 /*
1993  * trio_string_lower
1994  */
1995 #if defined(TRIO_FUNC_STRING_LOWER)
1996 
1997 TRIO_PUBLIC_STRING int trio_string_lower TRIO_ARGS1((self), trio_string_t* self)
1998 {
1999 	assert(self);
2000 
2001 	return trio_lower(self->content);
2002 }
2003 
2004 #endif
2005 
2006 /*
2007  * trio_string_match
2008  */
2009 #if defined(TRIO_FUNC_STRING_MATCH)
2010 
2011 TRIO_PUBLIC_STRING int trio_string_match TRIO_ARGS2((self, other), trio_string_t* self,
2012                                                     trio_string_t* other)
2013 {
2014 	assert(self);
2015 	assert(other);
2016 
2017 	return trio_match(self->content, other->content);
2018 }
2019 
2020 #endif
2021 
2022 /*
2023  * trio_xstring_match
2024  */
2025 #if defined(TRIO_FUNC_XSTRING_MATCH)
2026 
2027 TRIO_PUBLIC_STRING int trio_xstring_match TRIO_ARGS2((self, other), trio_string_t* self,
2028                                                      TRIO_CONST char* other)
2029 {
2030 	assert(self);
2031 	assert(other);
2032 
2033 	return trio_match(self->content, other);
2034 }
2035 
2036 #endif
2037 
2038 /*
2039  * trio_string_match_case
2040  */
2041 #if defined(TRIO_FUNC_STRING_MATCH_CASE)
2042 
2043 TRIO_PUBLIC_STRING int trio_string_match_case TRIO_ARGS2((self, other), trio_string_t* self,
2044                                                          trio_string_t* other)
2045 {
2046 	assert(self);
2047 	assert(other);
2048 
2049 	return trio_match_case(self->content, other->content);
2050 }
2051 
2052 #endif
2053 
2054 /*
2055  * trio_xstring_match_case
2056  */
2057 #if defined(TRIO_FUNC_XSTRING_MATCH_CASE)
2058 
2059 TRIO_PUBLIC_STRING int trio_xstring_match_case TRIO_ARGS2((self, other), trio_string_t* self,
2060                                                           TRIO_CONST char* other)
2061 {
2062 	assert(self);
2063 	assert(other);
2064 
2065 	return trio_match_case(self->content, other);
2066 }
2067 
2068 #endif
2069 
2070 /*
2071  * trio_string_substring
2072  */
2073 #if defined(TRIO_FUNC_STRING_SUBSTRING)
2074 
2075 TRIO_PUBLIC_STRING char* trio_string_substring TRIO_ARGS2((self, other), trio_string_t* self,
2076                                                           trio_string_t* other)
2077 {
2078 	assert(self);
2079 	assert(other);
2080 
2081 	return trio_substring(self->content, other->content);
2082 }
2083 
2084 #endif
2085 
2086 /*
2087  * trio_xstring_substring
2088  */
2089 #if defined(TRIO_FUNC_XSTRING_SUBSTRING)
2090 
2091 TRIO_PUBLIC_STRING char* trio_xstring_substring TRIO_ARGS2((self, other), trio_string_t* self,
2092                                                            TRIO_CONST char* other)
2093 {
2094 	assert(self);
2095 	assert(other);
2096 
2097 	return trio_substring(self->content, other);
2098 }
2099 
2100 #endif
2101 
2102 /*
2103  * trio_string_upper
2104  */
2105 #if defined(TRIO_FUNC_STRING_UPPER)
2106 
2107 TRIO_PUBLIC_STRING int trio_string_upper TRIO_ARGS1((self), trio_string_t* self)
2108 {
2109 	assert(self);
2110 
2111 	return trio_upper(self->content);
2112 }
2113 
2114 #endif
2115 
2116 /** @} End of DynamicStrings */
2117