blob: 30d13ac0624176632f87fadcd32f9ca0fcef6f45 [file] [log] [blame]
Bjorn Reese026d29f2002-01-19 15:40:18 +00001/*************************************************************************
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
Bjorn Reese026d29f2002-01-19 15:40:18 +000018/*************************************************************************
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>
Daniel Veillardb7c29c32002-09-25 22:44:43 +000027#include "triodef.h"
Bjorn Reese026d29f2002-01-19 15:40:18 +000028#include "triostr.h"
29
30/*************************************************************************
31 * Definitions
32 */
33
Daniel Veillardb7c29c32002-09-25 22:44:43 +000034#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)
Bjorn Reese026d29f2002-01-19 15:40:18 +000042# define NULL 0
43#endif
Daniel Veillardb7c29c32002-09-25 22:44:43 +000044#if !defined(NIL)
45# define NIL ((char)0)
46#endif
47#if !defined(FALSE)
Bjorn Reese026d29f2002-01-19 15:40:18 +000048# define FALSE (1 == 0)
49# define TRUE (! FALSE)
50#endif
Daniel Veillardb7c29c32002-09-25 22:44:43 +000051#if !defined(BOOLEAN_T)
52# define BOOLEAN_T int
53#endif
Bjorn Reese026d29f2002-01-19 15:40:18 +000054
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
Daniel Veillarda48ed3d2003-04-03 15:28:28 +000065# if defined(TRIO_PLATFORM_SUNOS)
66# define USE_SYS_ERRLIST
67# else
68# define USE_STRERROR
69# endif
Bjorn Reese026d29f2002-01-19 15:40:18 +000070# 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
Daniel Veillard59d3ed82007-04-17 12:44:58 +000076# if defined(_WIN32_WCE)
77# define strcasecmp(x,y) _stricmp(x,y)
78# else
79# define strcasecmp(x,y) strcmpi(x,y)
80# endif
Bjorn Reese026d29f2002-01-19 15:40:18 +000081#endif
82
Daniel Veillarda48ed3d2003-04-03 15:28:28 +000083#if !(defined(TRIO_PLATFORM_SUNOS))
84# define USE_TOLOWER
85# define USE_TOUPPER
86#endif
87
Bjorn Reese026d29f2002-01-19 15:40:18 +000088/*************************************************************************
89 * Structures
90 */
91
92struct _trio_string_t
93{
94 char *content;
95 size_t length;
96 size_t allocated;
97};
98
99/*************************************************************************
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000100 * Constants
101 */
102
103#if !defined(TRIO_MINIMAL)
104static TRIO_CONST char rcsid[] = "@(#)$Id$";
105#endif
106
107/*************************************************************************
Bjorn Reese026d29f2002-01-19 15:40:18 +0000108 * 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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000124TRIO_STRING_PUBLIC char *
125trio_create
126TRIO_ARGS1((size),
127 size_t size)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000128{
129 return (char *)TRIO_MALLOC(size);
130}
131
132
133/**
134 Destroy string.
135
136 @param string String to be freed.
137*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000138TRIO_STRING_PUBLIC void
139trio_destroy
140TRIO_ARGS1((string),
141 char *string)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000142{
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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000156TRIO_STRING_PUBLIC size_t
157trio_length
158TRIO_ARGS1((string),
159 TRIO_CONST char *string)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000160{
161 return strlen(string);
162}
163
164
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000165#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*/
179TRIO_STRING_PUBLIC int
180trio_append
181TRIO_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*/
208TRIO_STRING_PUBLIC int
209trio_append_max
210TRIO_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*/
239TRIO_STRING_PUBLIC int
240trio_contains
241TRIO_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*/
267TRIO_STRING_PUBLIC int
268trio_copy
269TRIO_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*/
296TRIO_STRING_PUBLIC int
297trio_copy_max
298TRIO_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
Bjorn Reese026d29f2002-01-19 15:40:18 +0000313/*
314 * TrioDuplicateMax
315 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000316TRIO_STRING_PRIVATE char *
317TrioDuplicateMax
318TRIO_ARGS2((source, size),
319 TRIO_CONST char *source,
320 size_t size)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000321{
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/**
Bjorn Reese026d29f2002-01-19 15:40:18 +0000338 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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000345TRIO_STRING_PUBLIC char *
346trio_duplicate
347TRIO_ARGS1((source),
348 TRIO_CONST char *source)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000349{
350 return TrioDuplicateMax(source, trio_length(source));
351}
352
353
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000354#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000355/**
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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000364TRIO_STRING_PUBLIC char *
365trio_duplicate_max TRIO_ARGS2((source, max),
366 TRIO_CONST char *source,
367 size_t max)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000368{
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}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000381#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000382
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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000393TRIO_STRING_PUBLIC int
394trio_equal
395TRIO_ARGS2((first, second),
396 TRIO_CONST char *first,
397 TRIO_CONST char *second)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000398{
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 {
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000409 if (trio_to_upper(*first) != trio_to_upper(*second))
Bjorn Reese026d29f2002-01-19 15:40:18 +0000410 {
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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000432TRIO_STRING_PUBLIC int
433trio_equal_case
434TRIO_ARGS2((first, second),
435 TRIO_CONST char *first,
436 TRIO_CONST char *second)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000437{
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
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000449#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000450/**
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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000460TRIO_STRING_PUBLIC int
461trio_equal_case_max
462TRIO_ARGS3((first, max, second),
463 TRIO_CONST char *first,
464 size_t max,
465 TRIO_CONST char *second)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000466{
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}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000476#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000477
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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000488TRIO_STRING_PUBLIC int
489trio_equal_locale
490TRIO_ARGS2((first, second),
491 TRIO_CONST char *first,
492 TRIO_CONST char *second)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000493{
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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000515TRIO_STRING_PUBLIC int
516trio_equal_max
517TRIO_ARGS3((first, max, second),
518 TRIO_CONST char *first,
519 size_t max,
520 TRIO_CONST char *second)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000521{
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 {
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000534 if (trio_to_upper(*first) != trio_to_upper(*second))
Bjorn Reese026d29f2002-01-19 15:40:18 +0000535 {
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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000555TRIO_STRING_PUBLIC TRIO_CONST char *
556trio_error
557TRIO_ARGS1((error_number),
558 int error_number)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000559{
560#if defined(USE_STRERROR)
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000561
Bjorn Reese026d29f2002-01-19 15:40:18 +0000562 return strerror(error_number);
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000563
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
Bjorn Reese026d29f2002-01-19 15:40:18 +0000573#else
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000574
Bjorn Reese026d29f2002-01-19 15:40:18 +0000575 return "unknown";
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000576
Bjorn Reese026d29f2002-01-19 15:40:18 +0000577#endif
578}
579
580
Daniel Veillard59d3ed82007-04-17 12:44:58 +0000581#if !defined(TRIO_MINIMAL) && !defined(_WIN32_WCE)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000582/**
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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000594TRIO_STRING_PUBLIC size_t
595trio_format_date_max
596TRIO_ARGS4((target, max, format, datetime),
597 char *target,
598 size_t max,
599 TRIO_CONST char *format,
600 TRIO_CONST struct tm *datetime)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000601{
602 assert(target);
603 assert(format);
604 assert(datetime);
605 assert(max > 0);
606
607 return strftime(target, max, format, datetime);
608}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000609#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000610
611
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000612#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000613/**
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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000623TRIO_STRING_PUBLIC unsigned long
624trio_hash
625TRIO_ARGS2((string, type),
626 TRIO_CONST char *string,
627 int type)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000628{
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}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000649#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000650
651
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000652#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000653/**
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 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000660TRIO_STRING_PUBLIC char *
661trio_index
662TRIO_ARGS2((string, character),
663 TRIO_CONST char *string,
664 int character)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000665{
666 assert(string);
667
668 return strchr(string, character);
669}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000670#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000671
672
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000673#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000674/**
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 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000681TRIO_STRING_PUBLIC char *
682trio_index_last
683TRIO_ARGS2((string, character),
684 TRIO_CONST char *string,
685 int character)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000686{
687 assert(string);
688
689 return strchr(string, character);
690}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000691#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000692
693
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000694#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000695/**
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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000701TRIO_STRING_PUBLIC int
702trio_lower
703TRIO_ARGS1((target),
704 char *target)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000705{
706 assert(target);
707
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000708 return trio_span_function(target, target, trio_to_lower);
Bjorn Reese026d29f2002-01-19 15:40:18 +0000709}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000710#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000711
712
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000713#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000714/**
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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000727TRIO_STRING_PUBLIC int
728trio_match
729TRIO_ARGS2((string, pattern),
730 TRIO_CONST char *string,
731 TRIO_CONST char *pattern)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000732{
733 assert(string);
734 assert(pattern);
735
736 for (; ('*' != *pattern); ++pattern, ++string)
737 {
738 if (NIL == *string)
739 {
740 return (NIL == *pattern);
741 }
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000742 if ((trio_to_upper((int)*string) != trio_to_upper((int)*pattern))
Bjorn Reese026d29f2002-01-19 15:40:18 +0000743 && ('?' != *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}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000763#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000764
765
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000766#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000767/**
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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000780TRIO_STRING_PUBLIC int
781trio_match_case
782TRIO_ARGS2((string, pattern),
783 TRIO_CONST char *string,
784 TRIO_CONST char *pattern)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000785{
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}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000816#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000817
818
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000819#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000820/**
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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000828TRIO_STRING_PUBLIC size_t
829trio_span_function
830TRIO_ARGS3((target, source, Function),
831 char *target,
832 TRIO_CONST char *source,
833 int (*Function) TRIO_PROTO((int)))
Bjorn Reese026d29f2002-01-19 15:40:18 +0000834{
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}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000848#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000849
850
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000851#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000852/**
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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000860TRIO_STRING_PUBLIC char *
861trio_substring
862TRIO_ARGS2((string, substring),
863 TRIO_CONST char *string,
864 TRIO_CONST char *substring)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000865{
866 assert(string);
867 assert(substring);
868
869 return strstr(string, substring);
870}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000871#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000872
873
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000874#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000875/**
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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000884TRIO_STRING_PUBLIC char *
885trio_substring_max
886TRIO_ARGS3((string, max, substring),
887 TRIO_CONST char *string,
888 size_t max,
889 TRIO_CONST char *substring)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000890{
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}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000912#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000913
914
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000915#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000916/**
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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000925TRIO_STRING_PUBLIC char *
926trio_tokenize
927TRIO_ARGS2((string, delimiters),
928 char *string,
929 TRIO_CONST char *delimiters)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000930{
931 assert(delimiters);
932
933 return strtok(string, delimiters);
934}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000935#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000936
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 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000960TRIO_STRING_PUBLIC trio_long_double_t
961trio_to_long_double
962TRIO_ARGS2((source, endp),
963 TRIO_CONST char *source,
964 char **endp)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000965{
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000966#if defined(USE_STRTOLD)
967 return strtold(source, endp);
Bjorn Reese026d29f2002-01-19 15:40:18 +0000968#else
Bjorn Reese026d29f2002-01-19 15:40:18 +0000969 int isNegative = FALSE;
970 int isExponentNegative = FALSE;
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000971 trio_long_double_t integer = 0.0;
972 trio_long_double_t fraction = 0.0;
Bjorn Reese026d29f2002-01-19 15:40:18 +0000973 unsigned long exponent = 0;
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000974 trio_long_double_t base;
975 trio_long_double_t fracdiv = 1.0;
976 trio_long_double_t value = 0.0;
Bjorn Reese026d29f2002-01-19 15:40:18 +0000977
978 /* First try hex-floats */
979 if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X')))
980 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000981 base = 16.0;
Bjorn Reese026d29f2002-01-19 15:40:18 +0000982 source += 2;
983 while (isxdigit((int)*source))
984 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000985 integer *= base;
Bjorn Reese026d29f2002-01-19 15:40:18 +0000986 integer += (isdigit((int)*source)
987 ? (*source - '0')
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000988 : 10 + (trio_to_upper((int)*source) - 'A'));
Bjorn Reese026d29f2002-01-19 15:40:18 +0000989 source++;
990 }
991 if (*source == '.')
992 {
993 source++;
994 while (isxdigit((int)*source))
995 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000996 fracdiv /= base;
997 fraction += fracdiv * (isdigit((int)*source)
998 ? (*source - '0')
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000999 : 10 + (trio_to_upper((int)*source) - 'A'));
Bjorn Reese026d29f2002-01-19 15:40:18 +00001000 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 {
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001012 exponent *= 10;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001013 exponent += (*source - '0');
1014 source++;
1015 }
1016 }
1017 }
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001018 /* For later use with exponent */
1019 base = 2.0;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001020 }
1021 else /* Then try normal decimal floats */
1022 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001023 base = 10.0;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001024 isNegative = (*source == '-');
1025 /* Skip sign */
1026 if ((*source == '+') || (*source == '-'))
1027 source++;
1028
1029 /* Integer part */
1030 while (isdigit((int)*source))
1031 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001032 integer *= base;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001033 integer += (*source - '0');
1034 source++;
1035 }
1036
1037 if (*source == '.')
1038 {
1039 source++; /* skip decimal point */
1040 while (isdigit((int)*source))
1041 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001042 fracdiv /= base;
1043 fraction += (*source - '0') * fracdiv;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001044 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 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001061 exponent *= (int)base;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001062 exponent += (*source - '0');
1063 source++;
1064 }
1065 }
1066 }
1067
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001068 value = integer + fraction;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001069 if (exponent != 0)
1070 {
1071 if (isExponentNegative)
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001072 value /= pow(base, (double)exponent);
Bjorn Reese026d29f2002-01-19 15:40:18 +00001073 else
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001074 value *= pow(base, (double)exponent);
Bjorn Reese026d29f2002-01-19 15:40:18 +00001075 }
1076 if (isNegative)
1077 value = -value;
1078
1079 if (endp)
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001080 *endp = (char *)source;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001081 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
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001093 See @ref trio_to_long_double.
Bjorn Reese026d29f2002-01-19 15:40:18 +00001094*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001095TRIO_STRING_PUBLIC double
1096trio_to_double
1097TRIO_ARGS2((source, endp),
1098 TRIO_CONST char *source,
1099 char **endp)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001100{
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001101#if defined(USE_STRTOD)
1102 return strtod(source, endp);
Bjorn Reese026d29f2002-01-19 15:40:18 +00001103#else
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001104 return (double)trio_to_long_double(source, endp);
Bjorn Reese026d29f2002-01-19 15:40:18 +00001105#endif
1106}
1107
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001108#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*/
1118TRIO_STRING_PUBLIC float
1119trio_to_float
1120TRIO_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
Bjorn Reese026d29f2002-01-19 15:40:18 +00001132
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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001140TRIO_STRING_PUBLIC long
1141trio_to_long
1142TRIO_ARGS3((string, endp, base),
1143 TRIO_CONST char *string,
1144 char **endp,
1145 int base)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001146{
1147 assert(string);
1148 assert((base >= 2) && (base <= 36));
1149
1150 return strtol(string, endp, base);
1151}
1152
1153
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001154#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001155/**
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001156 Convert one alphabetic letter to lower-case.
1157
1158 @param source The letter to be converted.
1159 @return The converted letter.
1160*/
1161TRIO_STRING_PUBLIC int
1162trio_to_lower
1163TRIO_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/**
Bjorn Reese026d29f2002-01-19 15:40:18 +00001183 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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001189TRIO_STRING_PUBLIC unsigned long
1190trio_to_unsigned_long
1191TRIO_ARGS3((string, endp, base),
1192 TRIO_CONST char *string,
1193 char **endp,
1194 int base)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001195{
1196 assert(string);
1197 assert((base >= 2) && (base <= 36));
1198
1199 return strtoul(string, endp, base);
1200}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001201#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001202
1203
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001204/**
1205 Convert one alphabetic letter to upper-case.
1206
1207 @param source The letter to be converted.
1208 @return The converted letter.
1209*/
1210TRIO_STRING_PUBLIC int
1211trio_to_upper
1212TRIO_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
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001229#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001230/**
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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001236TRIO_STRING_PUBLIC int
1237trio_upper
1238TRIO_ARGS1((target),
1239 char *target)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001240{
1241 assert(target);
1242
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001243 return trio_span_function(target, target, trio_to_upper);
Bjorn Reese026d29f2002-01-19 15:40:18 +00001244}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001245#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001246
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 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001265TRIO_STRING_PRIVATE trio_string_t *
1266TrioStringAlloc(TRIO_NOARGS)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001267{
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 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001287TRIO_STRING_PRIVATE BOOLEAN_T
1288TrioStringGrow
1289TRIO_ARGS2((self, delta),
1290 trio_string_t *self,
1291 size_t delta)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001292{
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
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001312#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001313/*
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 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001320TRIO_STRING_PRIVATE BOOLEAN_T
1321TrioStringGrowTo
1322TRIO_ARGS2((self, length),
1323 trio_string_t *self,
1324 size_t length)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001325{
1326 length++; /* Room for terminating zero */
1327 return (self->allocated < length)
1328 ? TrioStringGrow(self, length - self->allocated)
1329 : TRUE;
1330}
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001331#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001332
1333
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001334#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001335/**
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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001341TRIO_STRING_PUBLIC trio_string_t *
1342trio_string_create
1343TRIO_ARGS1((initial_size),
1344 int initial_size)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001345{
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}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001365#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001366
1367
1368/**
1369 Deallocate the dynamic string and its contents.
1370
1371 @param self Dynamic string
1372*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001373TRIO_STRING_PUBLIC void
1374trio_string_destroy
1375TRIO_ARGS1((self),
1376 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001377{
1378 assert(self);
1379
1380 if (self)
1381 {
1382 trio_destroy(self->content);
1383 TRIO_FREE(self);
1384 }
1385}
1386
1387
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001388#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001389/**
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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001403TRIO_STRING_PUBLIC char *
1404trio_string_get
1405TRIO_ARGS2((self, offset),
1406 trio_string_t *self,
1407 int offset)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001408{
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 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001421 if (offset > (int)self->length)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001422 {
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}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001438#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001439
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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001450TRIO_STRING_PUBLIC char *
1451trio_string_extract
1452TRIO_ARGS1((self),
1453 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001454{
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
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001467#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001468/**
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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001481TRIO_STRING_PUBLIC void
1482trio_xstring_set
1483TRIO_ARGS2((self, buffer),
1484 trio_string_t *self,
1485 char *buffer)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001486{
1487 assert(self);
1488
1489 trio_destroy(self->content);
1490 self->content = trio_duplicate(buffer);
1491}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001492#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001493
1494
1495/*
1496 * trio_string_size
1497 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001498TRIO_STRING_PUBLIC int
1499trio_string_size
1500TRIO_ARGS1((self),
1501 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001502{
1503 assert(self);
1504
1505 return self->allocated;
1506}
1507
1508
1509/*
1510 * trio_string_terminate
1511 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001512TRIO_STRING_PUBLIC void
1513trio_string_terminate
1514TRIO_ARGS1((self),
1515 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001516{
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001517 trio_xstring_append_char(self, 0);
Bjorn Reese026d29f2002-01-19 15:40:18 +00001518}
1519
1520
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001521#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001522/**
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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001529TRIO_STRING_PUBLIC int
1530trio_string_append
1531TRIO_ARGS2((self, other),
1532 trio_string_t *self,
1533 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001534{
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}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001550#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001551
1552
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001553#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001554/*
1555 * trio_xstring_append
1556 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001557TRIO_STRING_PUBLIC int
1558trio_xstring_append
1559TRIO_ARGS2((self, other),
1560 trio_string_t *self,
1561 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001562{
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}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001578#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001579
1580
1581/*
1582 * trio_xstring_append_char
1583 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001584TRIO_STRING_PUBLIC int
1585trio_xstring_append_char
1586TRIO_ARGS2((self, character),
1587 trio_string_t *self,
1588 char character)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001589{
1590 assert(self);
1591
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001592 if ((int)self->length >= trio_string_size(self))
Bjorn Reese026d29f2002-01-19 15:40:18 +00001593 {
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
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001606#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001607/**
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*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001614TRIO_STRING_PUBLIC int
1615trio_string_contains
1616TRIO_ARGS2((self, other),
1617 trio_string_t *self,
1618 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001619{
1620 assert(self);
1621 assert(other);
1622
1623 return trio_contains(self->content, other->content);
1624}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001625#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001626
1627
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001628#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001629/*
1630 * trio_xstring_contains
1631 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001632TRIO_STRING_PUBLIC int
1633trio_xstring_contains
1634TRIO_ARGS2((self, other),
1635 trio_string_t *self,
1636 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001637{
1638 assert(self);
1639 assert(other);
1640
1641 return trio_contains(self->content, other);
1642}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001643#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001644
1645
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001646#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001647/*
1648 * trio_string_copy
1649 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001650TRIO_STRING_PUBLIC int
1651trio_string_copy
1652TRIO_ARGS2((self, other),
1653 trio_string_t *self,
1654 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001655{
1656 assert(self);
1657 assert(other);
1658
1659 self->length = 0;
1660 return trio_string_append(self, other);
1661}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001662#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001663
1664
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001665#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001666/*
1667 * trio_xstring_copy
1668 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001669TRIO_STRING_PUBLIC int
1670trio_xstring_copy
1671TRIO_ARGS2((self, other),
1672 trio_string_t *self,
1673 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001674{
1675 assert(self);
1676 assert(other);
1677
1678 self->length = 0;
1679 return trio_xstring_append(self, other);
1680}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001681#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001682
1683
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001684#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001685/*
1686 * trio_string_duplicate
1687 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001688TRIO_STRING_PUBLIC trio_string_t *
1689trio_string_duplicate
1690TRIO_ARGS1((other),
1691 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001692{
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}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001713#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001714
1715
1716/*
1717 * trio_xstring_duplicate
1718 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001719TRIO_STRING_PUBLIC trio_string_t *
1720trio_xstring_duplicate
1721TRIO_ARGS1((other),
1722 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001723{
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
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001746#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001747/*
1748 * trio_string_equal
1749 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001750TRIO_STRING_PUBLIC int
1751trio_string_equal
1752TRIO_ARGS2((self, other),
1753 trio_string_t *self,
1754 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001755{
1756 assert(self);
1757 assert(other);
1758
1759 return trio_equal(self->content, other->content);
1760}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001761#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001762
1763
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001764#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001765/*
1766 * trio_xstring_equal
1767 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001768TRIO_STRING_PUBLIC int
1769trio_xstring_equal
1770TRIO_ARGS2((self, other),
1771 trio_string_t *self,
1772 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001773{
1774 assert(self);
1775 assert(other);
1776
1777 return trio_equal(self->content, other);
1778}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001779#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001780
1781
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001782#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001783/*
1784 * trio_string_equal_max
1785 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001786TRIO_STRING_PUBLIC int
1787trio_string_equal_max
1788TRIO_ARGS3((self, max, other),
1789 trio_string_t *self,
1790 size_t max,
1791 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001792{
1793 assert(self);
1794 assert(other);
1795
1796 return trio_equal_max(self->content, max, other->content);
1797}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001798#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001799
1800
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001801#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001802/*
1803 * trio_xstring_equal_max
1804 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001805TRIO_STRING_PUBLIC int
1806trio_xstring_equal_max
1807TRIO_ARGS3((self, max, other),
1808 trio_string_t *self,
1809 size_t max,
1810 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001811{
1812 assert(self);
1813 assert(other);
1814
1815 return trio_equal_max(self->content, max, other);
1816}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001817#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001818
1819
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001820#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001821/*
1822 * trio_string_equal_case
1823 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001824TRIO_STRING_PUBLIC int
1825trio_string_equal_case
1826TRIO_ARGS2((self, other),
1827 trio_string_t *self,
1828 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001829{
1830 assert(self);
1831 assert(other);
1832
1833 return trio_equal_case(self->content, other->content);
1834}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001835#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001836
1837
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001838#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001839/*
1840 * trio_xstring_equal_case
1841 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001842TRIO_STRING_PUBLIC int
1843trio_xstring_equal_case
1844TRIO_ARGS2((self, other),
1845 trio_string_t *self,
1846 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001847{
1848 assert(self);
1849 assert(other);
1850
1851 return trio_equal_case(self->content, other);
1852}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001853#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001854
1855
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001856#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001857/*
1858 * trio_string_equal_case_max
1859 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001860TRIO_STRING_PUBLIC int
1861trio_string_equal_case_max
1862TRIO_ARGS3((self, max, other),
1863 trio_string_t *self,
1864 size_t max,
1865 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001866{
1867 assert(self);
1868 assert(other);
1869
1870 return trio_equal_case_max(self->content, max, other->content);
1871}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001872#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001873
1874
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001875#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001876/*
1877 * trio_xstring_equal_case_max
1878 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001879TRIO_STRING_PUBLIC int
1880trio_xstring_equal_case_max
1881TRIO_ARGS3((self, max, other),
1882 trio_string_t *self,
1883 size_t max,
1884 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001885{
1886 assert(self);
1887 assert(other);
1888
1889 return trio_equal_case_max(self->content, max, other);
1890}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001891#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001892
1893
Daniel Veillard59d3ed82007-04-17 12:44:58 +00001894#if !defined(TRIO_MINIMAL) && !defined(_WIN32_WCE)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001895/*
1896 * trio_string_format_data_max
1897 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001898TRIO_STRING_PUBLIC size_t
1899trio_string_format_date_max
1900TRIO_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)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001905{
1906 assert(self);
1907
1908 return trio_format_date_max(self->content, max, format, datetime);
1909}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001910#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001911
1912
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001913#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001914/*
1915 * trio_string_index
1916 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001917TRIO_STRING_PUBLIC char *
1918trio_string_index
1919TRIO_ARGS2((self, character),
1920 trio_string_t *self,
1921 int character)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001922{
1923 assert(self);
1924
1925 return trio_index(self->content, character);
1926}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001927#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001928
1929
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001930#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001931/*
1932 * trio_string_index_last
1933 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001934TRIO_STRING_PUBLIC char *
1935trio_string_index_last
1936TRIO_ARGS2((self, character),
1937 trio_string_t *self,
1938 int character)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001939{
1940 assert(self);
1941
1942 return trio_index_last(self->content, character);
1943}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001944#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001945
1946
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001947#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001948/*
1949 * trio_string_length
1950 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001951TRIO_STRING_PUBLIC int
1952trio_string_length
1953TRIO_ARGS1((self),
1954 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001955{
1956 assert(self);
1957
1958 if (self->length == 0)
1959 {
1960 self->length = trio_length(self->content);
1961 }
1962 return self->length;
1963}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001964#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001965
1966
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001967#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001968/*
1969 * trio_string_lower
1970 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001971TRIO_STRING_PUBLIC int
1972trio_string_lower
1973TRIO_ARGS1((self),
1974 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001975{
1976 assert(self);
1977
1978 return trio_lower(self->content);
1979}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001980#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001981
1982
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001983#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001984/*
1985 * trio_string_match
1986 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001987TRIO_STRING_PUBLIC int
1988trio_string_match
1989TRIO_ARGS2((self, other),
1990 trio_string_t *self,
1991 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001992{
1993 assert(self);
1994 assert(other);
1995
1996 return trio_match(self->content, other->content);
1997}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001998#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001999
2000
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002001#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002002/*
2003 * trio_xstring_match
2004 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002005TRIO_STRING_PUBLIC int
2006trio_xstring_match
2007TRIO_ARGS2((self, other),
2008 trio_string_t *self,
2009 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002010{
2011 assert(self);
2012 assert(other);
2013
2014 return trio_match(self->content, other);
2015}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002016#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002017
2018
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002019#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002020/*
2021 * trio_string_match_case
2022 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002023TRIO_STRING_PUBLIC int
2024trio_string_match_case
2025TRIO_ARGS2((self, other),
2026 trio_string_t *self,
2027 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002028{
2029 assert(self);
2030 assert(other);
2031
2032 return trio_match_case(self->content, other->content);
2033}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002034#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002035
2036
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002037#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002038/*
2039 * trio_xstring_match_case
2040 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002041TRIO_STRING_PUBLIC int
2042trio_xstring_match_case
2043TRIO_ARGS2((self, other),
2044 trio_string_t *self,
2045 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002046{
2047 assert(self);
2048 assert(other);
2049
2050 return trio_match_case(self->content, other);
2051}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002052#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002053
2054
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002055#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002056/*
2057 * trio_string_substring
2058 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002059TRIO_STRING_PUBLIC char *
2060trio_string_substring
2061TRIO_ARGS2((self, other),
2062 trio_string_t *self,
2063 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002064{
2065 assert(self);
2066 assert(other);
2067
2068 return trio_substring(self->content, other->content);
2069}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002070#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002071
2072
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002073#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002074/*
2075 * trio_xstring_substring
2076 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002077TRIO_STRING_PUBLIC char *
2078trio_xstring_substring
2079TRIO_ARGS2((self, other),
2080 trio_string_t *self,
2081 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002082{
2083 assert(self);
2084 assert(other);
2085
2086 return trio_substring(self->content, other);
2087}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002088#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002089
2090
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002091#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002092/*
2093 * trio_string_upper
2094 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002095TRIO_STRING_PUBLIC int
2096trio_string_upper
2097TRIO_ARGS1((self),
2098 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002099{
2100 assert(self);
2101
2102 return trio_upper(self->content);
2103}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002104#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002105
2106/** @} End of DynamicStrings */