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