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