blob: 3c5c667ac95f369e76949e355a083185fe73e0b7 [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
Patrick Monneratca9fc432013-12-12 15:11:40 +080081#elif defined(TRIO_PLATFORM_OS400)
82# define USE_STRCASECMP
83# define USE_STRNCASECMP
84# include <strings.h>
Bjorn Reese026d29f2002-01-19 15:40:18 +000085#endif
86
Daniel Veillarda48ed3d2003-04-03 15:28:28 +000087#if !(defined(TRIO_PLATFORM_SUNOS))
88# define USE_TOLOWER
89# define USE_TOUPPER
90#endif
91
Bjorn Reese026d29f2002-01-19 15:40:18 +000092/*************************************************************************
93 * Structures
94 */
95
96struct _trio_string_t
97{
98 char *content;
99 size_t length;
100 size_t allocated;
101};
102
103/*************************************************************************
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000104 * Constants
105 */
106
107#if !defined(TRIO_MINIMAL)
108static TRIO_CONST char rcsid[] = "@(#)$Id$";
109#endif
110
111/*************************************************************************
Bjorn Reese026d29f2002-01-19 15:40:18 +0000112 * Static String Functions
113 */
114
115#if defined(TRIO_DOCUMENTATION)
116# include "doc/doc_static.h"
117#endif
118/** @addtogroup StaticStrings
119 @{
120*/
121
122/**
123 Create new string.
124
125 @param size Size of new string.
126 @return Pointer to string, or NULL if allocation failed.
127*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000128TRIO_STRING_PUBLIC char *
129trio_create
130TRIO_ARGS1((size),
131 size_t size)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000132{
133 return (char *)TRIO_MALLOC(size);
134}
135
136
137/**
138 Destroy string.
139
140 @param string String to be freed.
141*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000142TRIO_STRING_PUBLIC void
143trio_destroy
144TRIO_ARGS1((string),
145 char *string)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000146{
147 if (string)
148 {
149 TRIO_FREE(string);
150 }
151}
152
153
154/**
155 Count the number of characters in a string.
156
157 @param string String to measure.
158 @return Number of characters in @string.
159*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000160TRIO_STRING_PUBLIC size_t
161trio_length
162TRIO_ARGS1((string),
163 TRIO_CONST char *string)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000164{
165 return strlen(string);
166}
167
168
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000169#if !defined(TRIO_MINIMAL)
170/**
171 Append @p source at the end of @p target.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800172
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000173 @param target Target string.
174 @param source Source string.
175 @return Boolean value indicating success or failure.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800176
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000177 @pre @p target must point to a memory chunk with sufficient room to
178 contain the @p target string and @p source string.
179 @pre No boundary checking is performed, so insufficient memory will
180 result in a buffer overrun.
181 @post @p target will be zero terminated.
182*/
183TRIO_STRING_PUBLIC int
184trio_append
185TRIO_ARGS2((target, source),
186 char *target,
187 TRIO_CONST char *source)
188{
189 assert(target);
190 assert(source);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800191
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000192 return (strcat(target, source) != NULL);
193}
194#endif /* !defined(TRIO_MINIMAL) */
195
196#if !defined(TRIO_MINIMAL)
197/**
198 Append at most @p max characters from @p source to @p target.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800199
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000200 @param target Target string.
201 @param max Maximum number of characters to append.
202 @param source Source string.
203 @return Boolean value indicating success or failure.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800204
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000205 @pre @p target must point to a memory chuck with sufficient room to
206 contain the @p target string and the @p source string (at most @p max
207 characters).
208 @pre No boundary checking is performed, so insufficient memory will
209 result in a buffer overrun.
210 @post @p target will be zero terminated.
211*/
212TRIO_STRING_PUBLIC int
213trio_append_max
214TRIO_ARGS3((target, max, source),
215 char *target,
216 size_t max,
217 TRIO_CONST char *source)
218{
219 size_t length;
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800220
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000221 assert(target);
222 assert(source);
223
224 length = trio_length(target);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800225
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000226 if (max > length)
227 {
228 strncat(target, source, max - length - 1);
229 }
230 return TRUE;
231}
232#endif /* !defined(TRIO_MINIMAL) */
233
234
235#if !defined(TRIO_MINIMAL)
236/**
237 Determine if a string contains a substring.
238
239 @param string String to be searched.
240 @param substring String to be found.
241 @return Boolean value indicating success or failure.
242*/
243TRIO_STRING_PUBLIC int
244trio_contains
245TRIO_ARGS2((string, substring),
246 TRIO_CONST char *string,
247 TRIO_CONST char *substring)
248{
249 assert(string);
250 assert(substring);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800251
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000252 return (0 != strstr(string, substring));
253}
254#endif /* !defined(TRIO_MINIMAL) */
255
256
257#if !defined(TRIO_MINIMAL)
258/**
259 Copy @p source to @p target.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800260
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000261 @param target Target string.
262 @param source Source string.
263 @return Boolean value indicating success or failure.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800264
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000265 @pre @p target must point to a memory chunk with sufficient room to
266 contain the @p source string.
267 @pre No boundary checking is performed, so insufficient memory will
268 result in a buffer overrun.
269 @post @p target will be zero terminated.
270*/
271TRIO_STRING_PUBLIC int
272trio_copy
273TRIO_ARGS2((target, source),
274 char *target,
275 TRIO_CONST char *source)
276{
277 assert(target);
278 assert(source);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800279
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000280 (void)strcpy(target, source);
281 return TRUE;
282}
283#endif /* !defined(TRIO_MINIMAL) */
284
285
286/**
287 Copy at most @p max characters from @p source to @p target.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800288
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000289 @param target Target string.
290 @param max Maximum number of characters to append.
291 @param source Source string.
292 @return Boolean value indicating success or failure.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800293
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000294 @pre @p target must point to a memory chunk with sufficient room to
295 contain the @p source string (at most @p max characters).
296 @pre No boundary checking is performed, so insufficient memory will
297 result in a buffer overrun.
298 @post @p target will be zero terminated.
299*/
300TRIO_STRING_PUBLIC int
301trio_copy_max
302TRIO_ARGS3((target, max, source),
303 char *target,
304 size_t max,
305 TRIO_CONST char *source)
306{
307 assert(target);
308 assert(source);
309 assert(max > 0); /* Includes != 0 */
310
311 (void)strncpy(target, source, max - 1);
312 target[max - 1] = (char)0;
313 return TRUE;
314}
315
316
Bjorn Reese026d29f2002-01-19 15:40:18 +0000317/*
318 * TrioDuplicateMax
319 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000320TRIO_STRING_PRIVATE char *
321TrioDuplicateMax
322TRIO_ARGS2((source, size),
323 TRIO_CONST char *source,
324 size_t size)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000325{
326 char *target;
327
328 assert(source);
329
330 /* Make room for string plus a terminating zero */
331 size++;
332 target = trio_create(size);
333 if (target)
334 {
335 trio_copy_max(target, size, source);
336 }
337 return target;
338}
339
340
341/**
Bjorn Reese026d29f2002-01-19 15:40:18 +0000342 Duplicate @p source.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800343
Bjorn Reese026d29f2002-01-19 15:40:18 +0000344 @param source Source string.
345 @return A copy of the @p source string.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800346
Bjorn Reese026d29f2002-01-19 15:40:18 +0000347 @post @p target will be zero terminated.
348*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000349TRIO_STRING_PUBLIC char *
350trio_duplicate
351TRIO_ARGS1((source),
352 TRIO_CONST char *source)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000353{
354 return TrioDuplicateMax(source, trio_length(source));
355}
356
357
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000358#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000359/**
360 Duplicate at most @p max characters of @p source.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800361
Bjorn Reese026d29f2002-01-19 15:40:18 +0000362 @param source Source string.
363 @param max Maximum number of characters to duplicate.
364 @return A copy of the @p source string.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800365
Bjorn Reese026d29f2002-01-19 15:40:18 +0000366 @post @p target will be zero terminated.
367*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000368TRIO_STRING_PUBLIC char *
369trio_duplicate_max TRIO_ARGS2((source, max),
370 TRIO_CONST char *source,
371 size_t max)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000372{
373 size_t length;
374
375 assert(source);
376 assert(max > 0);
377
378 length = trio_length(source);
379 if (length > max)
380 {
381 length = max;
382 }
383 return TrioDuplicateMax(source, length);
384}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000385#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000386
387
388/**
389 Compare if two strings are equal.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800390
Bjorn Reese026d29f2002-01-19 15:40:18 +0000391 @param first First string.
392 @param second Second string.
393 @return Boolean indicating whether the two strings are equal or not.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800394
Bjorn Reese026d29f2002-01-19 15:40:18 +0000395 Case-insensitive comparison.
396*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000397TRIO_STRING_PUBLIC int
398trio_equal
399TRIO_ARGS2((first, second),
400 TRIO_CONST char *first,
401 TRIO_CONST char *second)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000402{
403 assert(first);
404 assert(second);
405
406 if ((first != NULL) && (second != NULL))
407 {
408#if defined(USE_STRCASECMP)
409 return (0 == strcasecmp(first, second));
410#else
411 while ((*first != NIL) && (*second != NIL))
412 {
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000413 if (trio_to_upper(*first) != trio_to_upper(*second))
Bjorn Reese026d29f2002-01-19 15:40:18 +0000414 {
415 break;
416 }
417 first++;
418 second++;
419 }
420 return ((*first == NIL) && (*second == NIL));
421#endif
422 }
423 return FALSE;
424}
425
426
427/**
428 Compare if two strings are equal.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800429
Bjorn Reese026d29f2002-01-19 15:40:18 +0000430 @param first First string.
431 @param second Second string.
432 @return Boolean indicating whether the two strings are equal or not.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800433
Bjorn Reese026d29f2002-01-19 15:40:18 +0000434 Case-sensitive comparison.
435*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000436TRIO_STRING_PUBLIC int
437trio_equal_case
438TRIO_ARGS2((first, second),
439 TRIO_CONST char *first,
440 TRIO_CONST char *second)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000441{
442 assert(first);
443 assert(second);
444
445 if ((first != NULL) && (second != NULL))
446 {
447 return (0 == strcmp(first, second));
448 }
449 return FALSE;
450}
451
452
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000453#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000454/**
455 Compare if two strings up until the first @p max characters are equal.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800456
Bjorn Reese026d29f2002-01-19 15:40:18 +0000457 @param first First string.
458 @param max Maximum number of characters to compare.
459 @param second Second string.
460 @return Boolean indicating whether the two strings are equal or not.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800461
Bjorn Reese026d29f2002-01-19 15:40:18 +0000462 Case-sensitive comparison.
463*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000464TRIO_STRING_PUBLIC int
465trio_equal_case_max
466TRIO_ARGS3((first, max, second),
467 TRIO_CONST char *first,
468 size_t max,
469 TRIO_CONST char *second)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000470{
471 assert(first);
472 assert(second);
473
474 if ((first != NULL) && (second != NULL))
475 {
476 return (0 == strncmp(first, second, max));
477 }
478 return FALSE;
479}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000480#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000481
482
483/**
484 Compare if two strings are equal.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800485
Bjorn Reese026d29f2002-01-19 15:40:18 +0000486 @param first First string.
487 @param second Second string.
488 @return Boolean indicating whether the two strings are equal or not.
489
490 Collating characters are considered equal.
491*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000492TRIO_STRING_PUBLIC int
493trio_equal_locale
494TRIO_ARGS2((first, second),
495 TRIO_CONST char *first,
496 TRIO_CONST char *second)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000497{
498 assert(first);
499 assert(second);
500
501#if defined(LC_COLLATE)
502 return (strcoll(first, second) == 0);
503#else
504 return trio_equal(first, second);
505#endif
506}
507
508
509/**
510 Compare if two strings up until the first @p max characters are equal.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800511
Bjorn Reese026d29f2002-01-19 15:40:18 +0000512 @param first First string.
513 @param max Maximum number of characters to compare.
514 @param second Second string.
515 @return Boolean indicating whether the two strings are equal or not.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800516
Bjorn Reese026d29f2002-01-19 15:40:18 +0000517 Case-insensitive comparison.
518*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000519TRIO_STRING_PUBLIC int
520trio_equal_max
521TRIO_ARGS3((first, max, second),
522 TRIO_CONST char *first,
523 size_t max,
524 TRIO_CONST char *second)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000525{
526 assert(first);
527 assert(second);
528
529 if ((first != NULL) && (second != NULL))
530 {
531#if defined(USE_STRNCASECMP)
532 return (0 == strncasecmp(first, second, max));
533#else
534 /* Not adequately tested yet */
535 size_t cnt = 0;
536 while ((*first != NIL) && (*second != NIL) && (cnt <= max))
537 {
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000538 if (trio_to_upper(*first) != trio_to_upper(*second))
Bjorn Reese026d29f2002-01-19 15:40:18 +0000539 {
540 break;
541 }
542 first++;
543 second++;
544 cnt++;
545 }
546 return ((cnt == max) || ((*first == NIL) && (*second == NIL)));
547#endif
548 }
549 return FALSE;
550}
551
552
553/**
554 Provide a textual description of an error code (errno).
555
556 @param error_number Error number.
557 @return Textual description of @p error_number.
558*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000559TRIO_STRING_PUBLIC TRIO_CONST char *
560trio_error
561TRIO_ARGS1((error_number),
562 int error_number)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000563{
564#if defined(USE_STRERROR)
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800565
Bjorn Reese026d29f2002-01-19 15:40:18 +0000566 return strerror(error_number);
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000567
568#elif defined(USE_SYS_ERRLIST)
569
570 extern char *sys_errlist[];
571 extern int sys_nerr;
572
573 return ((error_number < 0) || (error_number >= sys_nerr))
574 ? "unknown"
575 : sys_errlist[error_number];
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800576
Bjorn Reese026d29f2002-01-19 15:40:18 +0000577#else
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800578
Bjorn Reese026d29f2002-01-19 15:40:18 +0000579 return "unknown";
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800580
Bjorn Reese026d29f2002-01-19 15:40:18 +0000581#endif
582}
583
584
Daniel Veillard59d3ed82007-04-17 12:44:58 +0000585#if !defined(TRIO_MINIMAL) && !defined(_WIN32_WCE)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000586/**
587 Format the date/time according to @p format.
588
589 @param target Target string.
590 @param max Maximum number of characters to format.
591 @param format Formatting string.
592 @param datetime Date/time structure.
593 @return Number of formatted characters.
594
595 The formatting string accepts the same specifiers as the standard C
596 function strftime.
597*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000598TRIO_STRING_PUBLIC size_t
599trio_format_date_max
600TRIO_ARGS4((target, max, format, datetime),
601 char *target,
602 size_t max,
603 TRIO_CONST char *format,
604 TRIO_CONST struct tm *datetime)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000605{
606 assert(target);
607 assert(format);
608 assert(datetime);
609 assert(max > 0);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800610
Bjorn Reese026d29f2002-01-19 15:40:18 +0000611 return strftime(target, max, format, datetime);
612}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000613#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000614
615
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000616#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000617/**
618 Calculate a hash value for a string.
619
620 @param string String to be calculated on.
621 @param type Hash function.
622 @return Calculated hash value.
623
624 @p type can be one of the following
625 @li @c TRIO_HASH_PLAIN Plain hash function.
626*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000627TRIO_STRING_PUBLIC unsigned long
628trio_hash
629TRIO_ARGS2((string, type),
630 TRIO_CONST char *string,
631 int type)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000632{
633 unsigned long value = 0L;
634 char ch;
635
636 assert(string);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800637
Bjorn Reese026d29f2002-01-19 15:40:18 +0000638 switch (type)
639 {
640 case TRIO_HASH_PLAIN:
641 while ( (ch = *string++) != NIL )
642 {
643 value *= 31;
644 value += (unsigned long)ch;
645 }
646 break;
647 default:
648 assert(FALSE);
649 break;
650 }
651 return value;
652}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000653#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000654
655
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000656#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000657/**
658 Find first occurrence of a character in a string.
659
660 @param string String to be searched.
661 @param character Character to be found.
662 @param A pointer to the found character, or NULL if character was not found.
663 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000664TRIO_STRING_PUBLIC char *
665trio_index
666TRIO_ARGS2((string, character),
667 TRIO_CONST char *string,
668 int character)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000669{
670 assert(string);
671
672 return strchr(string, character);
673}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000674#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000675
676
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000677#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000678/**
679 Find last occurrence of a character in a string.
680
681 @param string String to be searched.
682 @param character Character to be found.
683 @param A pointer to the found character, or NULL if character was not found.
684 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000685TRIO_STRING_PUBLIC char *
686trio_index_last
687TRIO_ARGS2((string, character),
688 TRIO_CONST char *string,
689 int character)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000690{
691 assert(string);
692
693 return strchr(string, character);
694}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000695#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000696
697
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000698#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000699/**
700 Convert the alphabetic letters in the string to lower-case.
701
702 @param target String to be converted.
703 @return Number of processed characters (converted or not).
704*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000705TRIO_STRING_PUBLIC int
706trio_lower
707TRIO_ARGS1((target),
708 char *target)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000709{
710 assert(target);
711
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000712 return trio_span_function(target, target, trio_to_lower);
Bjorn Reese026d29f2002-01-19 15:40:18 +0000713}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000714#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000715
716
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000717#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000718/**
719 Compare two strings using wildcards.
720
721 @param string String to be searched.
722 @param pattern Pattern, including wildcards, to search for.
723 @return Boolean value indicating success or failure.
724
725 Case-insensitive comparison.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800726
Bjorn Reese026d29f2002-01-19 15:40:18 +0000727 The following wildcards can be used
728 @li @c * Match any number of characters.
729 @li @c ? Match a single character.
730*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000731TRIO_STRING_PUBLIC int
732trio_match
733TRIO_ARGS2((string, pattern),
734 TRIO_CONST char *string,
735 TRIO_CONST char *pattern)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000736{
737 assert(string);
738 assert(pattern);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800739
Bjorn Reese026d29f2002-01-19 15:40:18 +0000740 for (; ('*' != *pattern); ++pattern, ++string)
741 {
742 if (NIL == *string)
743 {
744 return (NIL == *pattern);
745 }
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000746 if ((trio_to_upper((int)*string) != trio_to_upper((int)*pattern))
Bjorn Reese026d29f2002-01-19 15:40:18 +0000747 && ('?' != *pattern))
748 {
749 return FALSE;
750 }
751 }
752 /* two-line patch to prevent *too* much recursiveness: */
753 while ('*' == pattern[1])
754 pattern++;
755
756 do
757 {
758 if ( trio_match(string, &pattern[1]) )
759 {
760 return TRUE;
761 }
762 }
763 while (*string++);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800764
Bjorn Reese026d29f2002-01-19 15:40:18 +0000765 return FALSE;
766}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000767#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000768
769
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000770#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000771/**
772 Compare two strings using wildcards.
773
774 @param string String to be searched.
775 @param pattern Pattern, including wildcards, to search for.
776 @return Boolean value indicating success or failure.
777
778 Case-sensitive comparison.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800779
Bjorn Reese026d29f2002-01-19 15:40:18 +0000780 The following wildcards can be used
781 @li @c * Match any number of characters.
782 @li @c ? Match a single character.
783*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000784TRIO_STRING_PUBLIC int
785trio_match_case
786TRIO_ARGS2((string, pattern),
787 TRIO_CONST char *string,
788 TRIO_CONST char *pattern)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000789{
790 assert(string);
791 assert(pattern);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800792
Bjorn Reese026d29f2002-01-19 15:40:18 +0000793 for (; ('*' != *pattern); ++pattern, ++string)
794 {
795 if (NIL == *string)
796 {
797 return (NIL == *pattern);
798 }
799 if ((*string != *pattern)
800 && ('?' != *pattern))
801 {
802 return FALSE;
803 }
804 }
805 /* two-line patch to prevent *too* much recursiveness: */
806 while ('*' == pattern[1])
807 pattern++;
808
809 do
810 {
811 if ( trio_match_case(string, &pattern[1]) )
812 {
813 return TRUE;
814 }
815 }
816 while (*string++);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800817
Bjorn Reese026d29f2002-01-19 15:40:18 +0000818 return FALSE;
819}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000820#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000821
822
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000823#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000824/**
825 Execute a function on each character in string.
826
827 @param target Target string.
828 @param source Source string.
829 @param Function Function to be executed.
830 @return Number of processed characters.
831*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000832TRIO_STRING_PUBLIC size_t
833trio_span_function
834TRIO_ARGS3((target, source, Function),
835 char *target,
836 TRIO_CONST char *source,
837 int (*Function) TRIO_PROTO((int)))
Bjorn Reese026d29f2002-01-19 15:40:18 +0000838{
839 size_t count = 0;
840
841 assert(target);
842 assert(source);
843 assert(Function);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800844
Bjorn Reese026d29f2002-01-19 15:40:18 +0000845 while (*source != NIL)
846 {
847 *target++ = Function(*source++);
848 count++;
849 }
850 return count;
851}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000852#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000853
854
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000855#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000856/**
857 Search for a substring in a string.
858
859 @param string String to be searched.
860 @param substring String to be found.
861 @return Pointer to first occurrence of @p substring in @p string, or NULL
862 if no match was found.
863*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000864TRIO_STRING_PUBLIC char *
865trio_substring
866TRIO_ARGS2((string, substring),
867 TRIO_CONST char *string,
868 TRIO_CONST char *substring)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000869{
870 assert(string);
871 assert(substring);
872
873 return strstr(string, substring);
874}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000875#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000876
877
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000878#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000879/**
880 Search for a substring in the first @p max characters of a string.
881
882 @param string String to be searched.
883 @param max Maximum characters to be searched.
884 @param substring String to be found.
885 @return Pointer to first occurrence of @p substring in @p string, or NULL
886 if no match was found.
887*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000888TRIO_STRING_PUBLIC char *
889trio_substring_max
890TRIO_ARGS3((string, max, substring),
891 TRIO_CONST char *string,
892 size_t max,
893 TRIO_CONST char *substring)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000894{
895 size_t count;
896 size_t size;
897 char *result = NULL;
898
899 assert(string);
900 assert(substring);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800901
Bjorn Reese026d29f2002-01-19 15:40:18 +0000902 size = trio_length(substring);
903 if (size <= max)
904 {
905 for (count = 0; count <= max - size; count++)
906 {
907 if (trio_equal_max(substring, size, &string[count]))
908 {
909 result = (char *)&string[count];
910 break;
911 }
912 }
913 }
914 return result;
915}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000916#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000917
918
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000919#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000920/**
921 Tokenize string.
922
923 @param string String to be tokenized.
924 @param tokens String containing list of delimiting characters.
925 @return Start of new token.
926
927 @warning @p string will be destroyed.
928*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000929TRIO_STRING_PUBLIC char *
930trio_tokenize
931TRIO_ARGS2((string, delimiters),
932 char *string,
933 TRIO_CONST char *delimiters)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000934{
935 assert(delimiters);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800936
Bjorn Reese026d29f2002-01-19 15:40:18 +0000937 return strtok(string, delimiters);
938}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000939#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000940
941
942/**
943 Convert string to floating-point number.
944
945 @param source String to be converted.
946 @param endp Pointer to end of the converted string.
947 @return A floating-point number.
948
949 The following Extended Backus-Naur form is used
950 @verbatim
951 double ::= [ <sign> ]
952 ( <number> |
953 <number> <decimal_point> <number> |
954 <decimal_point> <number> )
955 [ <exponential> [ <sign> ] <number> ]
956 number ::= 1*( <digit> )
957 digit ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )
958 exponential ::= ( 'e' | 'E' )
959 sign ::= ( '-' | '+' )
960 decimal_point ::= '.'
961 @endverbatim
962*/
963/* FIXME: Add EBNF for hex-floats */
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000964TRIO_STRING_PUBLIC trio_long_double_t
965trio_to_long_double
966TRIO_ARGS2((source, endp),
967 TRIO_CONST char *source,
968 char **endp)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000969{
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000970#if defined(USE_STRTOLD)
971 return strtold(source, endp);
Bjorn Reese026d29f2002-01-19 15:40:18 +0000972#else
Bjorn Reese026d29f2002-01-19 15:40:18 +0000973 int isNegative = FALSE;
974 int isExponentNegative = FALSE;
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000975 trio_long_double_t integer = 0.0;
976 trio_long_double_t fraction = 0.0;
Bjorn Reese026d29f2002-01-19 15:40:18 +0000977 unsigned long exponent = 0;
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000978 trio_long_double_t base;
979 trio_long_double_t fracdiv = 1.0;
980 trio_long_double_t value = 0.0;
Bjorn Reese026d29f2002-01-19 15:40:18 +0000981
982 /* First try hex-floats */
983 if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X')))
984 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000985 base = 16.0;
Bjorn Reese026d29f2002-01-19 15:40:18 +0000986 source += 2;
987 while (isxdigit((int)*source))
988 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000989 integer *= base;
Bjorn Reese026d29f2002-01-19 15:40:18 +0000990 integer += (isdigit((int)*source)
991 ? (*source - '0')
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000992 : 10 + (trio_to_upper((int)*source) - 'A'));
Bjorn Reese026d29f2002-01-19 15:40:18 +0000993 source++;
994 }
995 if (*source == '.')
996 {
997 source++;
998 while (isxdigit((int)*source))
999 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001000 fracdiv /= base;
1001 fraction += fracdiv * (isdigit((int)*source)
1002 ? (*source - '0')
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001003 : 10 + (trio_to_upper((int)*source) - 'A'));
Bjorn Reese026d29f2002-01-19 15:40:18 +00001004 source++;
1005 }
1006 if ((*source == 'p') || (*source == 'P'))
1007 {
1008 source++;
1009 if ((*source == '+') || (*source == '-'))
1010 {
1011 isExponentNegative = (*source == '-');
1012 source++;
1013 }
1014 while (isdigit((int)*source))
1015 {
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001016 exponent *= 10;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001017 exponent += (*source - '0');
1018 source++;
1019 }
1020 }
1021 }
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001022 /* For later use with exponent */
1023 base = 2.0;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001024 }
1025 else /* Then try normal decimal floats */
1026 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001027 base = 10.0;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001028 isNegative = (*source == '-');
1029 /* Skip sign */
1030 if ((*source == '+') || (*source == '-'))
1031 source++;
1032
1033 /* Integer part */
1034 while (isdigit((int)*source))
1035 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001036 integer *= base;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001037 integer += (*source - '0');
1038 source++;
1039 }
1040
1041 if (*source == '.')
1042 {
1043 source++; /* skip decimal point */
1044 while (isdigit((int)*source))
1045 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001046 fracdiv /= base;
1047 fraction += (*source - '0') * fracdiv;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001048 source++;
1049 }
1050 }
1051 if ((*source == 'e')
1052 || (*source == 'E')
1053#if TRIO_MICROSOFT
1054 || (*source == 'd')
1055 || (*source == 'D')
1056#endif
1057 )
1058 {
1059 source++; /* Skip exponential indicator */
1060 isExponentNegative = (*source == '-');
1061 if ((*source == '+') || (*source == '-'))
1062 source++;
1063 while (isdigit((int)*source))
1064 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001065 exponent *= (int)base;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001066 exponent += (*source - '0');
1067 source++;
1068 }
1069 }
1070 }
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001071
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001072 value = integer + fraction;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001073 if (exponent != 0)
1074 {
1075 if (isExponentNegative)
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001076 value /= pow(base, (double)exponent);
Bjorn Reese026d29f2002-01-19 15:40:18 +00001077 else
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001078 value *= pow(base, (double)exponent);
Bjorn Reese026d29f2002-01-19 15:40:18 +00001079 }
1080 if (isNegative)
1081 value = -value;
1082
1083 if (endp)
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001084 *endp = (char *)source;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001085 return value;
1086#endif
1087}
1088
1089
1090/**
1091 Convert string to floating-point number.
1092
1093 @param source String to be converted.
1094 @param endp Pointer to end of the converted string.
1095 @return A floating-point number.
1096
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001097 See @ref trio_to_long_double.
Bjorn Reese026d29f2002-01-19 15:40:18 +00001098*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001099TRIO_STRING_PUBLIC double
1100trio_to_double
1101TRIO_ARGS2((source, endp),
1102 TRIO_CONST char *source,
1103 char **endp)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001104{
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001105#if defined(USE_STRTOD)
1106 return strtod(source, endp);
Bjorn Reese026d29f2002-01-19 15:40:18 +00001107#else
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001108 return (double)trio_to_long_double(source, endp);
Bjorn Reese026d29f2002-01-19 15:40:18 +00001109#endif
1110}
1111
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001112#if !defined(TRIO_MINIMAL)
1113/**
1114 Convert string to floating-point number.
1115
1116 @param source String to be converted.
1117 @param endp Pointer to end of the converted string.
1118 @return A floating-point number.
1119
1120 See @ref trio_to_long_double.
1121*/
1122TRIO_STRING_PUBLIC float
1123trio_to_float
1124TRIO_ARGS2((source, endp),
1125 TRIO_CONST char *source,
1126 char **endp)
1127{
1128#if defined(USE_STRTOF)
1129 return strtof(source, endp);
1130#else
1131 return (float)trio_to_long_double(source, endp);
1132#endif
1133}
1134#endif /* !defined(TRIO_MINIMAL) */
1135
Bjorn Reese026d29f2002-01-19 15:40:18 +00001136
1137/**
1138 Convert string to signed integer.
1139
1140 @param string String to be converted.
1141 @param endp Pointer to end of converted string.
1142 @param base Radix number of number.
1143*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001144TRIO_STRING_PUBLIC long
1145trio_to_long
1146TRIO_ARGS3((string, endp, base),
1147 TRIO_CONST char *string,
1148 char **endp,
1149 int base)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001150{
1151 assert(string);
1152 assert((base >= 2) && (base <= 36));
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001153
Bjorn Reese026d29f2002-01-19 15:40:18 +00001154 return strtol(string, endp, base);
1155}
1156
1157
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001158#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001159/**
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001160 Convert one alphabetic letter to lower-case.
1161
1162 @param source The letter to be converted.
1163 @return The converted letter.
1164*/
1165TRIO_STRING_PUBLIC int
1166trio_to_lower
1167TRIO_ARGS1((source),
1168 int source)
1169{
1170#if defined(USE_TOLOWER)
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001171
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001172 return tolower(source);
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001173
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001174#else
1175
1176 /* Does not handle locales or non-contiguous alphabetic characters */
1177 return ((source >= (int)'A') && (source <= (int)'Z'))
1178 ? source - 'A' + 'a'
1179 : source;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001180
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001181#endif
1182}
1183#endif /* !defined(TRIO_MINIMAL) */
1184
1185#if !defined(TRIO_MINIMAL)
1186/**
Bjorn Reese026d29f2002-01-19 15:40:18 +00001187 Convert string to unsigned integer.
1188
1189 @param string String to be converted.
1190 @param endp Pointer to end of converted string.
1191 @param base Radix number of number.
1192*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001193TRIO_STRING_PUBLIC unsigned long
1194trio_to_unsigned_long
1195TRIO_ARGS3((string, endp, base),
1196 TRIO_CONST char *string,
1197 char **endp,
1198 int base)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001199{
1200 assert(string);
1201 assert((base >= 2) && (base <= 36));
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001202
Bjorn Reese026d29f2002-01-19 15:40:18 +00001203 return strtoul(string, endp, base);
1204}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001205#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001206
1207
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001208/**
1209 Convert one alphabetic letter to upper-case.
1210
1211 @param source The letter to be converted.
1212 @return The converted letter.
1213*/
1214TRIO_STRING_PUBLIC int
1215trio_to_upper
1216TRIO_ARGS1((source),
1217 int source)
1218{
1219#if defined(USE_TOUPPER)
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001220
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001221 return toupper(source);
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001222
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001223#else
1224
1225 /* Does not handle locales or non-contiguous alphabetic characters */
1226 return ((source >= (int)'a') && (source <= (int)'z'))
1227 ? source - 'a' + 'A'
1228 : source;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001229
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001230#endif
1231}
1232
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001233#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001234/**
1235 Convert the alphabetic letters in the string to upper-case.
1236
1237 @param target The string to be converted.
1238 @return The number of processed characters (converted or not).
1239*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001240TRIO_STRING_PUBLIC int
1241trio_upper
1242TRIO_ARGS1((target),
1243 char *target)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001244{
1245 assert(target);
1246
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001247 return trio_span_function(target, target, trio_to_upper);
Bjorn Reese026d29f2002-01-19 15:40:18 +00001248}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001249#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001250
1251
1252/** @} End of StaticStrings */
1253
1254
1255/*************************************************************************
1256 * Dynamic String Functions
1257 */
1258
1259#if defined(TRIO_DOCUMENTATION)
1260# include "doc/doc_dynamic.h"
1261#endif
1262/** @addtogroup DynamicStrings
1263 @{
1264*/
1265
1266/*
1267 * TrioStringAlloc
1268 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001269TRIO_STRING_PRIVATE trio_string_t *
1270TrioStringAlloc(TRIO_NOARGS)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001271{
1272 trio_string_t *self;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001273
Bjorn Reese026d29f2002-01-19 15:40:18 +00001274 self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t));
1275 if (self)
1276 {
1277 self->content = NULL;
1278 self->length = 0;
1279 self->allocated = 0;
1280 }
1281 return self;
1282}
1283
1284
1285/*
1286 * TrioStringGrow
1287 *
1288 * The size of the string will be increased by 'delta' characters. If
1289 * 'delta' is zero, the size will be doubled.
1290 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001291TRIO_STRING_PRIVATE BOOLEAN_T
1292TrioStringGrow
1293TRIO_ARGS2((self, delta),
1294 trio_string_t *self,
1295 size_t delta)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001296{
1297 BOOLEAN_T status = FALSE;
1298 char *new_content;
1299 size_t new_size;
1300
1301 new_size = (delta == 0)
1302 ? ( (self->allocated == 0) ? 1 : self->allocated * 2 )
1303 : self->allocated + delta;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001304
Bjorn Reese026d29f2002-01-19 15:40:18 +00001305 new_content = (char *)TRIO_REALLOC(self->content, new_size);
1306 if (new_content)
1307 {
1308 self->content = new_content;
1309 self->allocated = new_size;
1310 status = TRUE;
1311 }
1312 return status;
1313}
1314
1315
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001316#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001317/*
1318 * TrioStringGrowTo
1319 *
1320 * The size of the string will be increased to 'length' plus one characters.
1321 * If 'length' is less than the original size, the original size will be
1322 * used (that is, the size of the string is never decreased).
1323 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001324TRIO_STRING_PRIVATE BOOLEAN_T
1325TrioStringGrowTo
1326TRIO_ARGS2((self, length),
1327 trio_string_t *self,
1328 size_t length)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001329{
1330 length++; /* Room for terminating zero */
1331 return (self->allocated < length)
1332 ? TrioStringGrow(self, length - self->allocated)
1333 : TRUE;
1334}
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001335#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001336
1337
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001338#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001339/**
1340 Create a new dynamic string.
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001341
Bjorn Reese026d29f2002-01-19 15:40:18 +00001342 @param initial_size Initial size of the buffer.
1343 @return Newly allocated dynamic string, or NULL if memory allocation failed.
1344*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001345TRIO_STRING_PUBLIC trio_string_t *
1346trio_string_create
1347TRIO_ARGS1((initial_size),
1348 int initial_size)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001349{
1350 trio_string_t *self;
1351
1352 self = TrioStringAlloc();
1353 if (self)
1354 {
1355 if (TrioStringGrow(self,
1356 (size_t)((initial_size > 0) ? initial_size : 1)))
1357 {
1358 self->content[0] = (char)0;
1359 self->allocated = initial_size;
1360 }
1361 else
1362 {
1363 trio_string_destroy(self);
1364 self = NULL;
1365 }
1366 }
1367 return self;
1368}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001369#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001370
1371
1372/**
1373 Deallocate the dynamic string and its contents.
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001374
Bjorn Reese026d29f2002-01-19 15:40:18 +00001375 @param self Dynamic string
1376*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001377TRIO_STRING_PUBLIC void
1378trio_string_destroy
1379TRIO_ARGS1((self),
1380 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001381{
1382 assert(self);
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001383
Bjorn Reese026d29f2002-01-19 15:40:18 +00001384 if (self)
1385 {
1386 trio_destroy(self->content);
1387 TRIO_FREE(self);
1388 }
1389}
1390
1391
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001392#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001393/**
1394 Get a pointer to the content.
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001395
Bjorn Reese026d29f2002-01-19 15:40:18 +00001396 @param self Dynamic string.
1397 @param offset Offset into content.
1398 @return Pointer to the content.
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001399
Bjorn Reese026d29f2002-01-19 15:40:18 +00001400 @p Offset can be zero, positive, or negative. If @p offset is zero,
1401 then the start of the content will be returned. If @p offset is positive,
1402 then a pointer to @p offset number of characters from the beginning of the
1403 content is returned. If @p offset is negative, then a pointer to @p offset
1404 number of characters from the ending of the string, starting at the
1405 terminating zero, is returned.
1406*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001407TRIO_STRING_PUBLIC char *
1408trio_string_get
1409TRIO_ARGS2((self, offset),
1410 trio_string_t *self,
1411 int offset)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001412{
1413 char *result = NULL;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001414
Bjorn Reese026d29f2002-01-19 15:40:18 +00001415 assert(self);
1416
1417 if (self->content != NULL)
1418 {
1419 if (self->length == 0)
1420 {
1421 (void)trio_string_length(self);
1422 }
1423 if (offset >= 0)
1424 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001425 if (offset > (int)self->length)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001426 {
1427 offset = self->length;
1428 }
1429 }
1430 else
1431 {
1432 offset += self->length + 1;
1433 if (offset < 0)
1434 {
1435 offset = 0;
1436 }
1437 }
1438 result = &(self->content[offset]);
1439 }
1440 return result;
1441}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001442#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001443
1444
1445/**
1446 Extract the content.
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001447
Bjorn Reese026d29f2002-01-19 15:40:18 +00001448 @param self Dynamic String
1449 @return Content of dynamic string.
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001450
Bjorn Reese026d29f2002-01-19 15:40:18 +00001451 The content is removed from the dynamic string. This enables destruction
1452 of the dynamic string without deallocation of the content.
1453*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001454TRIO_STRING_PUBLIC char *
1455trio_string_extract
1456TRIO_ARGS1((self),
1457 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001458{
1459 char *result;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001460
Bjorn Reese026d29f2002-01-19 15:40:18 +00001461 assert(self);
1462
1463 result = self->content;
1464 /* FIXME: Allocate new empty buffer? */
1465 self->content = NULL;
1466 self->length = self->allocated = 0;
1467 return result;
1468}
1469
1470
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001471#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001472/**
1473 Set the content of the dynamic string.
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001474
Bjorn Reese026d29f2002-01-19 15:40:18 +00001475 @param self Dynamic String
1476 @param buffer The new content.
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001477
Bjorn Reese026d29f2002-01-19 15:40:18 +00001478 Sets the content of the dynamic string to a copy @p buffer.
1479 An existing content will be deallocated first, if necessary.
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001480
Bjorn Reese026d29f2002-01-19 15:40:18 +00001481 @remark
1482 This function will make a copy of @p buffer.
1483 You are responsible for deallocating @p buffer yourself.
1484*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001485TRIO_STRING_PUBLIC void
1486trio_xstring_set
1487TRIO_ARGS2((self, buffer),
1488 trio_string_t *self,
1489 char *buffer)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001490{
1491 assert(self);
1492
1493 trio_destroy(self->content);
1494 self->content = trio_duplicate(buffer);
1495}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001496#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001497
1498
1499/*
1500 * trio_string_size
1501 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001502TRIO_STRING_PUBLIC int
1503trio_string_size
1504TRIO_ARGS1((self),
1505 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001506{
1507 assert(self);
1508
1509 return self->allocated;
1510}
1511
1512
1513/*
1514 * trio_string_terminate
1515 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001516TRIO_STRING_PUBLIC void
1517trio_string_terminate
1518TRIO_ARGS1((self),
1519 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001520{
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001521 trio_xstring_append_char(self, 0);
Bjorn Reese026d29f2002-01-19 15:40:18 +00001522}
1523
1524
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001525#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001526/**
1527 Append the second string to the first.
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001528
Bjorn Reese026d29f2002-01-19 15:40:18 +00001529 @param self Dynamic string to be modified.
1530 @param other Dynamic string to copy from.
1531 @return Boolean value indicating success or failure.
1532*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001533TRIO_STRING_PUBLIC int
1534trio_string_append
1535TRIO_ARGS2((self, other),
1536 trio_string_t *self,
1537 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001538{
1539 size_t length;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001540
Bjorn Reese026d29f2002-01-19 15:40:18 +00001541 assert(self);
1542 assert(other);
1543
1544 length = self->length + other->length;
1545 if (!TrioStringGrowTo(self, length))
1546 goto error;
1547 trio_copy(&self->content[self->length], other->content);
1548 self->length = length;
1549 return TRUE;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001550
Bjorn Reese026d29f2002-01-19 15:40:18 +00001551 error:
1552 return FALSE;
1553}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001554#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001555
1556
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001557#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001558/*
1559 * trio_xstring_append
1560 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001561TRIO_STRING_PUBLIC int
1562trio_xstring_append
1563TRIO_ARGS2((self, other),
1564 trio_string_t *self,
1565 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001566{
1567 size_t length;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001568
Bjorn Reese026d29f2002-01-19 15:40:18 +00001569 assert(self);
1570 assert(other);
1571
1572 length = self->length + trio_length(other);
1573 if (!TrioStringGrowTo(self, length))
1574 goto error;
1575 trio_copy(&self->content[self->length], other);
1576 self->length = length;
1577 return TRUE;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001578
Bjorn Reese026d29f2002-01-19 15:40:18 +00001579 error:
1580 return FALSE;
1581}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001582#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001583
1584
1585/*
1586 * trio_xstring_append_char
1587 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001588TRIO_STRING_PUBLIC int
1589trio_xstring_append_char
1590TRIO_ARGS2((self, character),
1591 trio_string_t *self,
1592 char character)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001593{
1594 assert(self);
1595
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001596 if ((int)self->length >= trio_string_size(self))
Bjorn Reese026d29f2002-01-19 15:40:18 +00001597 {
1598 if (!TrioStringGrow(self, 0))
1599 goto error;
1600 }
1601 self->content[self->length] = character;
1602 self->length++;
1603 return TRUE;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001604
Bjorn Reese026d29f2002-01-19 15:40:18 +00001605 error:
1606 return FALSE;
1607}
1608
1609
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001610#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001611/**
1612 Search for the first occurrence of second parameter in the first.
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001613
Bjorn Reese026d29f2002-01-19 15:40:18 +00001614 @param self Dynamic string to be modified.
1615 @param other Dynamic string to copy from.
1616 @return Boolean value indicating success or failure.
1617*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001618TRIO_STRING_PUBLIC int
1619trio_string_contains
1620TRIO_ARGS2((self, other),
1621 trio_string_t *self,
1622 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001623{
1624 assert(self);
1625 assert(other);
1626
1627 return trio_contains(self->content, other->content);
1628}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001629#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001630
1631
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001632#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001633/*
1634 * trio_xstring_contains
1635 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001636TRIO_STRING_PUBLIC int
1637trio_xstring_contains
1638TRIO_ARGS2((self, other),
1639 trio_string_t *self,
1640 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001641{
1642 assert(self);
1643 assert(other);
1644
1645 return trio_contains(self->content, other);
1646}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001647#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001648
1649
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001650#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001651/*
1652 * trio_string_copy
1653 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001654TRIO_STRING_PUBLIC int
1655trio_string_copy
1656TRIO_ARGS2((self, other),
1657 trio_string_t *self,
1658 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001659{
1660 assert(self);
1661 assert(other);
1662
1663 self->length = 0;
1664 return trio_string_append(self, other);
1665}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001666#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001667
1668
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001669#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001670/*
1671 * trio_xstring_copy
1672 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001673TRIO_STRING_PUBLIC int
1674trio_xstring_copy
1675TRIO_ARGS2((self, other),
1676 trio_string_t *self,
1677 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001678{
1679 assert(self);
1680 assert(other);
1681
1682 self->length = 0;
1683 return trio_xstring_append(self, other);
1684}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001685#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001686
1687
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001688#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001689/*
1690 * trio_string_duplicate
1691 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001692TRIO_STRING_PUBLIC trio_string_t *
1693trio_string_duplicate
1694TRIO_ARGS1((other),
1695 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001696{
1697 trio_string_t *self;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001698
Bjorn Reese026d29f2002-01-19 15:40:18 +00001699 assert(other);
1700
1701 self = TrioStringAlloc();
1702 if (self)
1703 {
1704 self->content = TrioDuplicateMax(other->content, other->length);
1705 if (self->content)
1706 {
1707 self->length = other->length;
1708 self->allocated = self->length + 1;
1709 }
1710 else
1711 {
1712 self->length = self->allocated = 0;
1713 }
1714 }
1715 return self;
1716}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001717#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001718
1719
1720/*
1721 * trio_xstring_duplicate
1722 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001723TRIO_STRING_PUBLIC trio_string_t *
1724trio_xstring_duplicate
1725TRIO_ARGS1((other),
1726 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001727{
1728 trio_string_t *self;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001729
Bjorn Reese026d29f2002-01-19 15:40:18 +00001730 assert(other);
1731
1732 self = TrioStringAlloc();
1733 if (self)
1734 {
1735 self->content = TrioDuplicateMax(other, trio_length(other));
1736 if (self->content)
1737 {
1738 self->length = trio_length(self->content);
1739 self->allocated = self->length + 1;
1740 }
1741 else
1742 {
1743 self->length = self->allocated = 0;
1744 }
1745 }
1746 return self;
1747}
1748
1749
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001750#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001751/*
1752 * trio_string_equal
1753 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001754TRIO_STRING_PUBLIC int
1755trio_string_equal
1756TRIO_ARGS2((self, other),
1757 trio_string_t *self,
1758 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001759{
1760 assert(self);
1761 assert(other);
1762
1763 return trio_equal(self->content, other->content);
1764}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001765#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001766
1767
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001768#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001769/*
1770 * trio_xstring_equal
1771 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001772TRIO_STRING_PUBLIC int
1773trio_xstring_equal
1774TRIO_ARGS2((self, other),
1775 trio_string_t *self,
1776 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001777{
1778 assert(self);
1779 assert(other);
1780
1781 return trio_equal(self->content, other);
1782}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001783#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001784
1785
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001786#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001787/*
1788 * trio_string_equal_max
1789 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001790TRIO_STRING_PUBLIC int
1791trio_string_equal_max
1792TRIO_ARGS3((self, max, other),
1793 trio_string_t *self,
1794 size_t max,
1795 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001796{
1797 assert(self);
1798 assert(other);
1799
1800 return trio_equal_max(self->content, max, other->content);
1801}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001802#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001803
1804
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001805#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001806/*
1807 * trio_xstring_equal_max
1808 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001809TRIO_STRING_PUBLIC int
1810trio_xstring_equal_max
1811TRIO_ARGS3((self, max, other),
1812 trio_string_t *self,
1813 size_t max,
1814 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001815{
1816 assert(self);
1817 assert(other);
1818
1819 return trio_equal_max(self->content, max, other);
1820}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001821#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001822
1823
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001824#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001825/*
1826 * trio_string_equal_case
1827 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001828TRIO_STRING_PUBLIC int
1829trio_string_equal_case
1830TRIO_ARGS2((self, other),
1831 trio_string_t *self,
1832 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001833{
1834 assert(self);
1835 assert(other);
1836
1837 return trio_equal_case(self->content, other->content);
1838}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001839#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001840
1841
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001842#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001843/*
1844 * trio_xstring_equal_case
1845 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001846TRIO_STRING_PUBLIC int
1847trio_xstring_equal_case
1848TRIO_ARGS2((self, other),
1849 trio_string_t *self,
1850 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001851{
1852 assert(self);
1853 assert(other);
1854
1855 return trio_equal_case(self->content, other);
1856}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001857#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001858
1859
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001860#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001861/*
1862 * trio_string_equal_case_max
1863 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001864TRIO_STRING_PUBLIC int
1865trio_string_equal_case_max
1866TRIO_ARGS3((self, max, other),
1867 trio_string_t *self,
1868 size_t max,
1869 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001870{
1871 assert(self);
1872 assert(other);
1873
1874 return trio_equal_case_max(self->content, max, other->content);
1875}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001876#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001877
1878
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001879#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001880/*
1881 * trio_xstring_equal_case_max
1882 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001883TRIO_STRING_PUBLIC int
1884trio_xstring_equal_case_max
1885TRIO_ARGS3((self, max, other),
1886 trio_string_t *self,
1887 size_t max,
1888 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001889{
1890 assert(self);
1891 assert(other);
1892
1893 return trio_equal_case_max(self->content, max, other);
1894}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001895#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001896
1897
Daniel Veillard59d3ed82007-04-17 12:44:58 +00001898#if !defined(TRIO_MINIMAL) && !defined(_WIN32_WCE)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001899/*
1900 * trio_string_format_data_max
1901 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001902TRIO_STRING_PUBLIC size_t
1903trio_string_format_date_max
1904TRIO_ARGS4((self, max, format, datetime),
1905 trio_string_t *self,
1906 size_t max,
1907 TRIO_CONST char *format,
1908 TRIO_CONST struct tm *datetime)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001909{
1910 assert(self);
1911
1912 return trio_format_date_max(self->content, max, format, datetime);
1913}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001914#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001915
1916
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001917#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001918/*
1919 * trio_string_index
1920 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001921TRIO_STRING_PUBLIC char *
1922trio_string_index
1923TRIO_ARGS2((self, character),
1924 trio_string_t *self,
1925 int character)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001926{
1927 assert(self);
1928
1929 return trio_index(self->content, character);
1930}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001931#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001932
1933
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001934#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001935/*
1936 * trio_string_index_last
1937 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001938TRIO_STRING_PUBLIC char *
1939trio_string_index_last
1940TRIO_ARGS2((self, character),
1941 trio_string_t *self,
1942 int character)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001943{
1944 assert(self);
1945
1946 return trio_index_last(self->content, character);
1947}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001948#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001949
1950
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001951#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001952/*
1953 * trio_string_length
1954 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001955TRIO_STRING_PUBLIC int
1956trio_string_length
1957TRIO_ARGS1((self),
1958 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001959{
1960 assert(self);
1961
1962 if (self->length == 0)
1963 {
1964 self->length = trio_length(self->content);
1965 }
1966 return self->length;
1967}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001968#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001969
1970
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001971#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001972/*
1973 * trio_string_lower
1974 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001975TRIO_STRING_PUBLIC int
1976trio_string_lower
1977TRIO_ARGS1((self),
1978 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001979{
1980 assert(self);
1981
1982 return trio_lower(self->content);
1983}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001984#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001985
1986
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001987#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001988/*
1989 * trio_string_match
1990 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001991TRIO_STRING_PUBLIC int
1992trio_string_match
1993TRIO_ARGS2((self, other),
1994 trio_string_t *self,
1995 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001996{
1997 assert(self);
1998 assert(other);
1999
2000 return trio_match(self->content, other->content);
2001}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002002#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002003
2004
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002005#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002006/*
2007 * trio_xstring_match
2008 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002009TRIO_STRING_PUBLIC int
2010trio_xstring_match
2011TRIO_ARGS2((self, other),
2012 trio_string_t *self,
2013 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002014{
2015 assert(self);
2016 assert(other);
2017
2018 return trio_match(self->content, other);
2019}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002020#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002021
2022
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002023#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002024/*
2025 * trio_string_match_case
2026 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002027TRIO_STRING_PUBLIC int
2028trio_string_match_case
2029TRIO_ARGS2((self, other),
2030 trio_string_t *self,
2031 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002032{
2033 assert(self);
2034 assert(other);
2035
2036 return trio_match_case(self->content, other->content);
2037}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002038#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002039
2040
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002041#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002042/*
2043 * trio_xstring_match_case
2044 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002045TRIO_STRING_PUBLIC int
2046trio_xstring_match_case
2047TRIO_ARGS2((self, other),
2048 trio_string_t *self,
2049 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002050{
2051 assert(self);
2052 assert(other);
2053
2054 return trio_match_case(self->content, other);
2055}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002056#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002057
2058
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002059#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002060/*
2061 * trio_string_substring
2062 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002063TRIO_STRING_PUBLIC char *
2064trio_string_substring
2065TRIO_ARGS2((self, other),
2066 trio_string_t *self,
2067 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002068{
2069 assert(self);
2070 assert(other);
2071
2072 return trio_substring(self->content, other->content);
2073}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002074#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002075
2076
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002077#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002078/*
2079 * trio_xstring_substring
2080 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002081TRIO_STRING_PUBLIC char *
2082trio_xstring_substring
2083TRIO_ARGS2((self, other),
2084 trio_string_t *self,
2085 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002086{
2087 assert(self);
2088 assert(other);
2089
2090 return trio_substring(self->content, other);
2091}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002092#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002093
2094
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002095#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002096/*
2097 * trio_string_upper
2098 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002099TRIO_STRING_PUBLIC int
2100trio_string_upper
2101TRIO_ARGS1((self),
2102 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002103{
2104 assert(self);
2105
2106 return trio_upper(self->content);
2107}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002108#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002109
2110/** @} End of DynamicStrings */