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