ReactOS  r76032
triostr.c
Go to the documentation of this file.
1 /*************************************************************************
2  *
3  * $Id$
4  *
5  * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
12  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
13  * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
14  * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
15  *
16  ************************************************************************/
17 
18 /*************************************************************************
19  * Include files
20  */
21 
22 #include <assert.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26 #include <math.h>
27 #include "triodef.h"
28 #include "triostr.h"
29 
30 /*************************************************************************
31  * Definitions
32  */
33 
34 #if !defined(TRIO_STRING_PUBLIC)
35 # define TRIO_STRING_PUBLIC TRIO_PUBLIC
36 #endif
37 #if !defined(TRIO_STRING_PRIVATE)
38 # define TRIO_STRING_PRIVATE TRIO_PRIVATE
39 #endif
40 
41 #if !defined(NULL)
42 # define NULL 0
43 #endif
44 #if !defined(NIL)
45 # define NIL ((char)0)
46 #endif
47 #if !defined(FALSE)
48 # define FALSE (1 == 0)
49 # define TRUE (! FALSE)
50 #endif
51 #if !defined(BOOLEAN_T)
52 # define BOOLEAN_T int
53 #endif
54 
55 #ifdef __VMS
56 # define USE_STRTOD
57 #elif defined(TRIO_COMPILER_SUPPORTS_C99)
58 # define USE_STRTOD
59 # define USE_STRTOF
60 #elif defined(TRIO_COMPILER_MSVC)
61 # define USE_STRTOD
62 #endif
63 
64 #if defined(TRIO_PLATFORM_UNIX)
65 # define USE_STRCASECMP
66 # define USE_STRNCASECMP
67 # if defined(TRIO_PLATFORM_SUNOS)
68 # define USE_SYS_ERRLIST
69 # else
70 # define USE_STRERROR
71 # endif
72 # if defined(TRIO_PLATFORM_QNX)
73 # define strcasecmp(x,y) stricmp(x,y)
74 # define strncasecmp(x,y,n) strnicmp(x,y,n)
75 # endif
76 #elif defined(TRIO_PLATFORM_WIN32)
77 # define USE_STRCASECMP
78 # if defined(_WIN32_WCE)
79 # define strcasecmp(x,y) _stricmp(x,y)
80 # else
81 # define strcasecmp(x,y) strcmpi(x,y)
82 # endif
83 #elif defined(TRIO_PLATFORM_OS400)
84 # define USE_STRCASECMP
85 # define USE_STRNCASECMP
86 # include <strings.h>
87 #endif
88 
89 #if !(defined(TRIO_PLATFORM_SUNOS))
90 # define USE_TOLOWER
91 # define USE_TOUPPER
92 #endif
93 
94 /*************************************************************************
95  * Structures
96  */
97 
99 {
100  char *content;
101  size_t length;
102  size_t allocated;
103 };
104 
105 /*************************************************************************
106  * Constants
107  */
108 
109 #if !defined(TRIO_MINIMAL)
110 static TRIO_CONST char rcsid[] = "@(#)$Id$";
111 #endif
112 
113 /*************************************************************************
114  * Static String Functions
115  */
116 
117 #if defined(TRIO_DOCUMENTATION)
118 # include "doc/doc_static.h"
119 #endif
120 
130 TRIO_STRING_PUBLIC char *
131 trio_create
133  size_t size)
134 {
135  return (char *)TRIO_MALLOC(size);
136 }
137 
138 
145 trio_destroy
146 TRIO_ARGS1((string),
147  char *string)
148 {
149  if (string)
150  {
151  TRIO_FREE(string);
152  }
153 }
154 
155 
162 TRIO_STRING_PUBLIC size_t
163 trio_length
164 TRIO_ARGS1((string),
165  TRIO_CONST char *string)
166 {
167  return strlen(string);
168 }
169 
170 
171 #if !defined(TRIO_MINIMAL)
172 
186 trio_append
188  char *target,
189  TRIO_CONST char *source)
190 {
191  assert(target);
192  assert(source);
193 
194  return (strcat(target, source) != NULL);
195 }
196 #endif /* !defined(TRIO_MINIMAL) */
197 
198 #if !defined(TRIO_MINIMAL)
199 
215 trio_append_max
217  char *target,
218  size_t max,
219  TRIO_CONST char *source)
220 {
221  size_t length;
222 
223  assert(target);
224  assert(source);
225 
226  length = trio_length(target);
227 
228  if (max > length)
229  {
230  strncat(target, source, max - length - 1);
231  }
232  return TRUE;
233 }
234 #endif /* !defined(TRIO_MINIMAL) */
235 
236 
237 #if !defined(TRIO_MINIMAL)
238 
246 trio_contains
247 TRIO_ARGS2((string, substring),
248  TRIO_CONST char *string,
249  TRIO_CONST char *substring)
250 {
251  assert(string);
252  assert(substring);
253 
254  return (0 != strstr(string, substring));
255 }
256 #endif /* !defined(TRIO_MINIMAL) */
257 
258 
259 #if !defined(TRIO_MINIMAL)
260 
274 trio_copy
276  char *target,
277  TRIO_CONST char *source)
278 {
279  assert(target);
280  assert(source);
281 
282  (void)strcpy(target, source);
283  return TRUE;
284 }
285 #endif /* !defined(TRIO_MINIMAL) */
286 
287 
303 trio_copy_max
304 TRIO_ARGS3((target, max, source),
305  char *target,
306  size_t max,
307  TRIO_CONST char *source)
308 {
309  assert(target);
310  assert(source);
311  assert(max > 0); /* Includes != 0 */
312 
313  (void)strncpy(target, source, max - 1);
314  target[max - 1] = (char)0;
315  return TRUE;
316 }
317 
318 
319 /*
320  * TrioDuplicateMax
321  */
322 TRIO_STRING_PRIVATE char *
323 TrioDuplicateMax
324 TRIO_ARGS2((source, size),
325  TRIO_CONST char *source,
326  size_t size)
327 {
328  char *target;
329 
330  assert(source);
331 
332  /* Make room for string plus a terminating zero */
333  size++;
334  target = trio_create(size);
335  if (target)
336  {
337  trio_copy_max(target, size, source);
338  }
339  return target;
340 }
341 
342 
351 TRIO_STRING_PUBLIC char *
352 trio_duplicate
353 TRIO_ARGS1((source),
354  TRIO_CONST char *source)
355 {
356  return TrioDuplicateMax(source, trio_length(source));
357 }
358 
359 
360 #if !defined(TRIO_MINIMAL)
361 
370 TRIO_STRING_PUBLIC char *
371 trio_duplicate_max TRIO_ARGS2((source, max),
372  TRIO_CONST char *source,
373  size_t max)
374 {
375  size_t length;
376 
377  assert(source);
378  assert(max > 0);
379 
380  length = trio_length(source);
381  if (length > max)
382  {
383  length = max;
384  }
385  return TrioDuplicateMax(source, length);
386 }
387 #endif /* !defined(TRIO_MINIMAL) */
388 
389 
400 trio_equal
401 TRIO_ARGS2((first, second),
402  TRIO_CONST char *first,
403  TRIO_CONST char *second)
404 {
405  assert(first);
406  assert(second);
407 
408  if ((first != NULL) && (second != NULL))
409  {
410 #if defined(USE_STRCASECMP)
411  return (0 == strcasecmp(first, second));
412 #else
413  while ((*first != NIL) && (*second != NIL))
414  {
415  if (trio_to_upper(*first) != trio_to_upper(*second))
416  {
417  break;
418  }
419  first++;
420  second++;
421  }
422  return ((*first == NIL) && (*second == NIL));
423 #endif
424  }
425  return FALSE;
426 }
427 
428 
439 trio_equal_case
440 TRIO_ARGS2((first, second),
441  TRIO_CONST char *first,
442  TRIO_CONST char *second)
443 {
444  assert(first);
445  assert(second);
446 
447  if ((first != NULL) && (second != NULL))
448  {
449  return (0 == strcmp(first, second));
450  }
451  return FALSE;
452 }
453 
454 
455 #if !defined(TRIO_MINIMAL)
456 
467 trio_equal_case_max
468 TRIO_ARGS3((first, max, second),
469  TRIO_CONST char *first,
470  size_t max,
471  TRIO_CONST char *second)
472 {
473  assert(first);
474  assert(second);
475 
476  if ((first != NULL) && (second != NULL))
477  {
478  return (0 == strncmp(first, second, max));
479  }
480  return FALSE;
481 }
482 #endif /* !defined(TRIO_MINIMAL) */
483 
484 
495 trio_equal_locale
496 TRIO_ARGS2((first, second),
497  TRIO_CONST char *first,
498  TRIO_CONST char *second)
499 {
500  assert(first);
501  assert(second);
502 
503 #if defined(LC_COLLATE)
504  return (strcoll(first, second) == 0);
505 #else
506  return trio_equal(first, second);
507 #endif
508 }
509 
510 
522 trio_equal_max
523 TRIO_ARGS3((first, max, second),
524  TRIO_CONST char *first,
525  size_t max,
526  TRIO_CONST char *second)
527 {
528  assert(first);
529  assert(second);
530 
531  if ((first != NULL) && (second != NULL))
532  {
533 #if defined(USE_STRNCASECMP)
534  return (0 == strncasecmp(first, second, max));
535 #else
536  /* Not adequately tested yet */
537  size_t cnt = 0;
538  while ((*first != NIL) && (*second != NIL) && (cnt <= max))
539  {
540  if (trio_to_upper(*first) != trio_to_upper(*second))
541  {
542  break;
543  }
544  first++;
545  second++;
546  cnt++;
547  }
548  return ((cnt == max) || ((*first == NIL) && (*second == NIL)));
549 #endif
550  }
551  return FALSE;
552 }
553 
554 
562 trio_error
563 TRIO_ARGS1((error_number),
564  int error_number)
565 {
566 #if defined(USE_STRERROR)
567 
568  return strerror(error_number);
569 
570 #elif defined(USE_SYS_ERRLIST)
571 
572  extern char *sys_errlist[];
573  extern int sys_nerr;
574 
575  return ((error_number < 0) || (error_number >= sys_nerr))
576  ? "unknown"
577  : sys_errlist[error_number];
578 
579 #else
580 
581  return "unknown";
582 
583 #endif
584 }
585 
586 
587 #if !defined(TRIO_MINIMAL) && !defined(_WIN32_WCE)
588 
600 TRIO_STRING_PUBLIC size_t
601 trio_format_date_max
602 TRIO_ARGS4((target, max, format, datetime),
603  char *target,
604  size_t max,
605  TRIO_CONST char *format,
606  TRIO_CONST struct tm *datetime)
607 {
608  assert(target);
609  assert(format);
610  assert(datetime);
611  assert(max > 0);
612 
613  return strftime(target, max, format, datetime);
614 }
615 #endif /* !defined(TRIO_MINIMAL) */
616 
617 
618 #if !defined(TRIO_MINIMAL)
619 
629 TRIO_STRING_PUBLIC unsigned long
630 trio_hash
631 TRIO_ARGS2((string, type),
632  TRIO_CONST char *string,
633  int type)
634 {
635  unsigned long value = 0L;
636  char ch;
637 
638  assert(string);
639 
640  switch (type)
641  {
642  case TRIO_HASH_PLAIN:
643  while ( (ch = *string++) != NIL )
644  {
645  value *= 31;
646  value += (unsigned long)ch;
647  }
648  break;
649  default:
650  assert(FALSE);
651  break;
652  }
653  return value;
654 }
655 #endif /* !defined(TRIO_MINIMAL) */
656 
657 
658 #if !defined(TRIO_MINIMAL)
659 
666 TRIO_STRING_PUBLIC char *
667 trio_index
668 TRIO_ARGS2((string, character),
669  TRIO_CONST char *string,
670  int character)
671 {
672  assert(string);
673 
674  return strchr(string, character);
675 }
676 #endif /* !defined(TRIO_MINIMAL) */
677 
678 
679 #if !defined(TRIO_MINIMAL)
680 
687 TRIO_STRING_PUBLIC char *
688 trio_index_last
689 TRIO_ARGS2((string, character),
690  TRIO_CONST char *string,
691  int character)
692 {
693  assert(string);
694 
695  return strchr(string, character);
696 }
697 #endif /* !defined(TRIO_MINIMAL) */
698 
699 
700 #if !defined(TRIO_MINIMAL)
701 
708 trio_lower
709 TRIO_ARGS1((target),
710  char *target)
711 {
712  assert(target);
713 
714  return trio_span_function(target, target, trio_to_lower);
715 }
716 #endif /* !defined(TRIO_MINIMAL) */
717 
718 
719 #if !defined(TRIO_MINIMAL)
720 
734 trio_match
735 TRIO_ARGS2((string, pattern),
736  TRIO_CONST char *string,
737  TRIO_CONST char *pattern)
738 {
739  assert(string);
740  assert(pattern);
741 
742  for (; ('*' != *pattern); ++pattern, ++string)
743  {
744  if (NIL == *string)
745  {
746  return (NIL == *pattern);
747  }
748  if ((trio_to_upper((int)*string) != trio_to_upper((int)*pattern))
749  && ('?' != *pattern))
750  {
751  return FALSE;
752  }
753  }
754  /* two-line patch to prevent *too* much recursiveness: */
755  while ('*' == pattern[1])
756  pattern++;
757 
758  do
759  {
760  if ( trio_match(string, &pattern[1]) )
761  {
762  return TRUE;
763  }
764  }
765  while (*string++);
766 
767  return FALSE;
768 }
769 #endif /* !defined(TRIO_MINIMAL) */
770 
771 
772 #if !defined(TRIO_MINIMAL)
773 
787 trio_match_case
788 TRIO_ARGS2((string, pattern),
789  TRIO_CONST char *string,
790  TRIO_CONST char *pattern)
791 {
792  assert(string);
793  assert(pattern);
794 
795  for (; ('*' != *pattern); ++pattern, ++string)
796  {
797  if (NIL == *string)
798  {
799  return (NIL == *pattern);
800  }
801  if ((*string != *pattern)
802  && ('?' != *pattern))
803  {
804  return FALSE;
805  }
806  }
807  /* two-line patch to prevent *too* much recursiveness: */
808  while ('*' == pattern[1])
809  pattern++;
810 
811  do
812  {
813  if ( trio_match_case(string, &pattern[1]) )
814  {
815  return TRUE;
816  }
817  }
818  while (*string++);
819 
820  return FALSE;
821 }
822 #endif /* !defined(TRIO_MINIMAL) */
823 
824 
825 #if !defined(TRIO_MINIMAL)
826 
834 TRIO_STRING_PUBLIC size_t
835 trio_span_function
836 TRIO_ARGS3((target, source, Function),
837  char *target,
838  TRIO_CONST char *source,
839  int (*Function) TRIO_PROTO((int)))
840 {
841  size_t count = 0;
842 
843  assert(target);
844  assert(source);
845  assert(Function);
846 
847  while (*source != NIL)
848  {
849  *target++ = Function(*source++);
850  count++;
851  }
852  return count;
853 }
854 #endif /* !defined(TRIO_MINIMAL) */
855 
856 
857 #if !defined(TRIO_MINIMAL)
858 
866 TRIO_STRING_PUBLIC char *
867 trio_substring
868 TRIO_ARGS2((string, substring),
869  TRIO_CONST char *string,
870  TRIO_CONST char *substring)
871 {
872  assert(string);
873  assert(substring);
874 
875  return strstr(string, substring);
876 }
877 #endif /* !defined(TRIO_MINIMAL) */
878 
879 
880 #if !defined(TRIO_MINIMAL)
881 
890 TRIO_STRING_PUBLIC char *
891 trio_substring_max
892 TRIO_ARGS3((string, max, substring),
893  TRIO_CONST char *string,
894  size_t max,
895  TRIO_CONST char *substring)
896 {
897  size_t count;
898  size_t size;
899  char *result = NULL;
900 
901  assert(string);
902  assert(substring);
903 
904  size = trio_length(substring);
905  if (size <= max)
906  {
907  for (count = 0; count <= max - size; count++)
908  {
909  if (trio_equal_max(substring, size, &string[count]))
910  {
911  result = (char *)&string[count];
912  break;
913  }
914  }
915  }
916  return result;
917 }
918 #endif /* !defined(TRIO_MINIMAL) */
919 
920 
921 #if !defined(TRIO_MINIMAL)
922 
931 TRIO_STRING_PUBLIC char *
932 trio_tokenize
933 TRIO_ARGS2((string, delimiters),
934  char *string,
935  TRIO_CONST char *delimiters)
936 {
937  assert(delimiters);
938 
939  return strtok(string, delimiters);
940 }
941 #endif /* !defined(TRIO_MINIMAL) */
942 
943 
965 /* FIXME: Add EBNF for hex-floats */
967 trio_to_long_double
968 TRIO_ARGS2((source, endp),
969  TRIO_CONST char *source,
970  char **endp)
971 {
972 #if defined(USE_STRTOLD)
973  return strtold(source, endp);
974 #else
975  int isNegative = FALSE;
976  int isExponentNegative = FALSE;
977  trio_long_double_t integer = 0.0;
978  trio_long_double_t fraction = 0.0;
979  unsigned long exponent = 0;
981  trio_long_double_t fracdiv = 1.0;
983 
984  /* First try hex-floats */
985  if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X')))
986  {
987  base = 16.0;
988  source += 2;
989  while (isxdigit((int)*source))
990  {
991  integer *= base;
992  integer += (isdigit((int)*source)
993  ? (*source - '0')
994  : 10 + (trio_to_upper((int)*source) - 'A'));
995  source++;
996  }
997  if (*source == '.')
998  {
999  source++;
1000  while (isxdigit((int)*source))
1001  {
1002  fracdiv /= base;
1003  fraction += fracdiv * (isdigit((int)*source)
1004  ? (*source - '0')
1005  : 10 + (trio_to_upper((int)*source) - 'A'));
1006  source++;
1007  }
1008  if ((*source == 'p') || (*source == 'P'))
1009  {
1010  source++;
1011  if ((*source == '+') || (*source == '-'))
1012  {
1013  isExponentNegative = (*source == '-');
1014  source++;
1015  }
1016  while (isdigit((int)*source))
1017  {
1018  exponent *= 10;
1019  exponent += (*source - '0');
1020  source++;
1021  }
1022  }
1023  }
1024  /* For later use with exponent */
1025  base = 2.0;
1026  }
1027  else /* Then try normal decimal floats */
1028  {
1029  base = 10.0;
1030  isNegative = (*source == '-');
1031  /* Skip sign */
1032  if ((*source == '+') || (*source == '-'))
1033  source++;
1034 
1035  /* Integer part */
1036  while (isdigit((int)*source))
1037  {
1038  integer *= base;
1039  integer += (*source - '0');
1040  source++;
1041  }
1042 
1043  if (*source == '.')
1044  {
1045  source++; /* skip decimal point */
1046  while (isdigit((int)*source))
1047  {
1048  fracdiv /= base;
1049  fraction += (*source - '0') * fracdiv;
1050  source++;
1051  }
1052  }
1053  if ((*source == 'e')
1054  || (*source == 'E')
1055 #if TRIO_MICROSOFT
1056  || (*source == 'd')
1057  || (*source == 'D')
1058 #endif
1059  )
1060  {
1061  source++; /* Skip exponential indicator */
1062  isExponentNegative = (*source == '-');
1063  if ((*source == '+') || (*source == '-'))
1064  source++;
1065  while (isdigit((int)*source))
1066  {
1067  exponent *= (int)base;
1068  exponent += (*source - '0');
1069  source++;
1070  }
1071  }
1072  }
1073 
1074  value = integer + fraction;
1075  if (exponent != 0)
1076  {
1077  if (isExponentNegative)
1078  value /= pow(base, (double)exponent);
1079  else
1080  value *= pow(base, (double)exponent);
1081  }
1082  if (isNegative)
1083  value = -value;
1084 
1085  if (endp)
1086  *endp = (char *)source;
1087  return value;
1088 #endif
1089 }
1090 
1091 
1101 TRIO_STRING_PUBLIC double
1102 trio_to_double
1103 TRIO_ARGS2((source, endp),
1104  TRIO_CONST char *source,
1105  char **endp)
1106 {
1107 #if defined(USE_STRTOD)
1108  return strtod(source, endp);
1109 #else
1110  return (double)trio_to_long_double(source, endp);
1111 #endif
1112 }
1113 
1114 #if !defined(TRIO_MINIMAL)
1115 
1124 TRIO_STRING_PUBLIC float
1125 trio_to_float
1126 TRIO_ARGS2((source, endp),
1127  TRIO_CONST char *source,
1128  char **endp)
1129 {
1130 #if defined(USE_STRTOF)
1131  return strtof(source, endp);
1132 #else
1133  return (float)trio_to_long_double(source, endp);
1134 #endif
1135 }
1136 #endif /* !defined(TRIO_MINIMAL) */
1137 
1138 
1146 TRIO_STRING_PUBLIC long
1147 trio_to_long
1148 TRIO_ARGS3((string, endp, base),
1149  TRIO_CONST char *string,
1150  char **endp,
1151  int base)
1152 {
1153  assert(string);
1154  assert((base >= 2) && (base <= 36));
1155 
1156  return strtol(string, endp, base);
1157 }
1158 
1159 
1160 #if !defined(TRIO_MINIMAL)
1161 
1168 trio_to_lower
1169 TRIO_ARGS1((source),
1170  int source)
1171 {
1172 #if defined(USE_TOLOWER)
1173 
1174  return tolower(source);
1175 
1176 #else
1177 
1178  /* Does not handle locales or non-contiguous alphabetic characters */
1179  return ((source >= (int)'A') && (source <= (int)'Z'))
1180  ? source - 'A' + 'a'
1181  : source;
1182 
1183 #endif
1184 }
1185 #endif /* !defined(TRIO_MINIMAL) */
1186 
1187 #if !defined(TRIO_MINIMAL)
1188 
1195 TRIO_STRING_PUBLIC unsigned long
1196 trio_to_unsigned_long
1197 TRIO_ARGS3((string, endp, base),
1198  TRIO_CONST char *string,
1199  char **endp,
1200  int base)
1201 {
1202  assert(string);
1203  assert((base >= 2) && (base <= 36));
1204 
1205  return strtoul(string, endp, base);
1206 }
1207 #endif /* !defined(TRIO_MINIMAL) */
1208 
1209 
1217 trio_to_upper
1218 TRIO_ARGS1((source),
1219  int source)
1220 {
1221 #if defined(USE_TOUPPER)
1222 
1223  return toupper(source);
1224 
1225 #else
1226 
1227  /* Does not handle locales or non-contiguous alphabetic characters */
1228  return ((source >= (int)'a') && (source <= (int)'z'))
1229  ? source - 'a' + 'A'
1230  : source;
1231 
1232 #endif
1233 }
1234 
1235 #if !defined(TRIO_MINIMAL)
1236 
1243 trio_upper
1244 TRIO_ARGS1((target),
1245  char *target)
1246 {
1247  assert(target);
1248 
1249  return trio_span_function(target, target, trio_to_upper);
1250 }
1251 #endif /* !defined(TRIO_MINIMAL) */
1252 
1253 
1257 /*************************************************************************
1258  * Dynamic String Functions
1259  */
1260 
1261 #if defined(TRIO_DOCUMENTATION)
1262 # include "doc/doc_dynamic.h"
1263 #endif
1264 
1268 /*
1269  * TrioStringAlloc
1270  */
1273 {
1274  trio_string_t *self;
1275 
1276  self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t));
1277  if (self)
1278  {
1279  self->content = NULL;
1280  self->length = 0;
1281  self->allocated = 0;
1282  }
1283  return self;
1284 }
1285 
1286 
1287 /*
1288  * TrioStringGrow
1289  *
1290  * The size of the string will be increased by 'delta' characters. If
1291  * 'delta' is zero, the size will be doubled.
1292  */
1294 TrioStringGrow
1295 TRIO_ARGS2((self, delta),
1296  trio_string_t *self,
1297  size_t delta)
1298 {
1300  char *new_content;
1301  size_t new_size;
1302 
1303  new_size = (delta == 0)
1304  ? ( (self->allocated == 0) ? 1 : self->allocated * 2 )
1305  : self->allocated + delta;
1306 
1307  new_content = (char *)TRIO_REALLOC(self->content, new_size);
1308  if (new_content)
1309  {
1310  self->content = new_content;
1311  self->allocated = new_size;
1312  status = TRUE;
1313  }
1314  return status;
1315 }
1316 
1317 
1318 #if !defined(TRIO_MINIMAL)
1319 /*
1320  * TrioStringGrowTo
1321  *
1322  * The size of the string will be increased to 'length' plus one characters.
1323  * If 'length' is less than the original size, the original size will be
1324  * used (that is, the size of the string is never decreased).
1325  */
1327 TrioStringGrowTo
1329  trio_string_t *self,
1330  size_t length)
1331 {
1332  length++; /* Room for terminating zero */
1333  return (self->allocated < length)
1334  ? TrioStringGrow(self, length - self->allocated)
1335  : TRUE;
1336 }
1337 #endif /* !defined(TRIO_MINIMAL) */
1338 
1339 
1340 #if !defined(TRIO_MINIMAL)
1341 
1348 trio_string_create
1349 TRIO_ARGS1((initial_size),
1350  int initial_size)
1351 {
1352  trio_string_t *self;
1353 
1354  self = TrioStringAlloc();
1355  if (self)
1356  {
1357  if (TrioStringGrow(self,
1358  (size_t)((initial_size > 0) ? initial_size : 1)))
1359  {
1360  self->content[0] = (char)0;
1361  self->allocated = initial_size;
1362  }
1363  else
1364  {
1365  trio_string_destroy(self);
1366  self = NULL;
1367  }
1368  }
1369  return self;
1370 }
1371 #endif /* !defined(TRIO_MINIMAL) */
1372 
1373 
1379 TRIO_STRING_PUBLIC void
1380 trio_string_destroy
1381 TRIO_ARGS1((self),
1382  trio_string_t *self)
1383 {
1384  assert(self);
1385 
1386  if (self)
1387  {
1388  trio_destroy(self->content);
1389  TRIO_FREE(self);
1390  }
1391 }
1392 
1393 
1394 #if !defined(TRIO_MINIMAL)
1395 
1409 TRIO_STRING_PUBLIC char *
1410 trio_string_get
1412  trio_string_t *self,
1413  int offset)
1414 {
1415  char *result = NULL;
1416 
1417  assert(self);
1418 
1419  if (self->content != NULL)
1420  {
1421  if (self->length == 0)
1422  {
1423  (void)trio_string_length(self);
1424  }
1425  if (offset >= 0)
1426  {
1427  if (offset > (int)self->length)
1428  {
1429  offset = self->length;
1430  }
1431  }
1432  else
1433  {
1434  offset += self->length + 1;
1435  if (offset < 0)
1436  {
1437  offset = 0;
1438  }
1439  }
1440  result = &(self->content[offset]);
1441  }
1442  return result;
1443 }
1444 #endif /* !defined(TRIO_MINIMAL) */
1445 
1446 
1456 TRIO_STRING_PUBLIC char *
1457 trio_string_extract
1458 TRIO_ARGS1((self),
1459  trio_string_t *self)
1460 {
1461  char *result;
1462 
1463  assert(self);
1464 
1465  result = self->content;
1466  /* FIXME: Allocate new empty buffer? */
1467  self->content = NULL;
1468  self->length = self->allocated = 0;
1469  return result;
1470 }
1471 
1472 
1473 #if !defined(TRIO_MINIMAL)
1474 
1487 TRIO_STRING_PUBLIC void
1488 trio_xstring_set
1490  trio_string_t *self,
1491  char *buffer)
1492 {
1493  assert(self);
1494 
1495  trio_destroy(self->content);
1496  self->content = trio_duplicate(buffer);
1497 }
1498 #endif /* !defined(TRIO_MINIMAL) */
1499 
1500 
1501 /*
1502  * trio_string_size
1503  */
1505 trio_string_size
1506 TRIO_ARGS1((self),
1507  trio_string_t *self)
1508 {
1509  assert(self);
1510 
1511  return self->allocated;
1512 }
1513 
1514 
1515 /*
1516  * trio_string_terminate
1517  */
1518 TRIO_STRING_PUBLIC void
1519 trio_string_terminate
1520 TRIO_ARGS1((self),
1521  trio_string_t *self)
1522 {
1523  trio_xstring_append_char(self, 0);
1524 }
1525 
1526 
1527 #if !defined(TRIO_MINIMAL)
1528 
1536 trio_string_append
1538  trio_string_t *self,
1540 {
1541  size_t length;
1542 
1543  assert(self);
1544  assert(other);
1545 
1546  length = self->length + other->length;
1547  if (!TrioStringGrowTo(self, length))
1548  goto error;
1549  trio_copy(&self->content[self->length], other->content);
1550  self->length = length;
1551  return TRUE;
1552 
1553  error:
1554  return FALSE;
1555 }
1556 #endif /* !defined(TRIO_MINIMAL) */
1557 
1558 
1559 #if !defined(TRIO_MINIMAL)
1560 /*
1561  * trio_xstring_append
1562  */
1564 trio_xstring_append
1566  trio_string_t *self,
1567  TRIO_CONST char *other)
1568 {
1569  size_t length;
1570 
1571  assert(self);
1572  assert(other);
1573 
1574  length = self->length + trio_length(other);
1575  if (!TrioStringGrowTo(self, length))
1576  goto error;
1577  trio_copy(&self->content[self->length], other);
1578  self->length = length;
1579  return TRUE;
1580 
1581  error:
1582  return FALSE;
1583 }
1584 #endif /* !defined(TRIO_MINIMAL) */
1585 
1586 
1587 /*
1588  * trio_xstring_append_char
1589  */
1591 trio_xstring_append_char
1592 TRIO_ARGS2((self, character),
1593  trio_string_t *self,
1594  char character)
1595 {
1596  assert(self);
1597 
1598  if ((int)self->length >= trio_string_size(self))
1599  {
1600  if (!TrioStringGrow(self, 0))
1601  goto error;
1602  }
1603  self->content[self->length] = character;
1604  self->length++;
1605  return TRUE;
1606 
1607  error:
1608  return FALSE;
1609 }
1610 
1611 
1612 #if !defined(TRIO_MINIMAL)
1613 
1621 trio_string_contains
1622 TRIO_ARGS2((self, other),
1623  trio_string_t *self,
1625 {
1626  assert(self);
1627  assert(other);
1628 
1629  return trio_contains(self->content, other->content);
1630 }
1631 #endif /* !defined(TRIO_MINIMAL) */
1632 
1633 
1634 #if !defined(TRIO_MINIMAL)
1635 /*
1636  * trio_xstring_contains
1637  */
1639 trio_xstring_contains
1640 TRIO_ARGS2((self, other),
1641  trio_string_t *self,
1642  TRIO_CONST char *other)
1643 {
1644  assert(self);
1645  assert(other);
1646 
1647  return trio_contains(self->content, other);
1648 }
1649 #endif /* !defined(TRIO_MINIMAL) */
1650 
1651 
1652 #if !defined(TRIO_MINIMAL)
1653 /*
1654  * trio_string_copy
1655  */
1657 trio_string_copy
1658 TRIO_ARGS2((self, other),
1659  trio_string_t *self,
1661 {
1662  assert(self);
1663  assert(other);
1664 
1665  self->length = 0;
1666  return trio_string_append(self, other);
1667 }
1668 #endif /* !defined(TRIO_MINIMAL) */
1669 
1670 
1671 #if !defined(TRIO_MINIMAL)
1672 /*
1673  * trio_xstring_copy
1674  */
1676 trio_xstring_copy
1677 TRIO_ARGS2((self, other),
1678  trio_string_t *self,
1679  TRIO_CONST char *other)
1680 {
1681  assert(self);
1682  assert(other);
1683 
1684  self->length = 0;
1685  return trio_xstring_append(self, other);
1686 }
1687 #endif /* !defined(TRIO_MINIMAL) */
1688 
1689 
1690 #if !defined(TRIO_MINIMAL)
1691 /*
1692  * trio_string_duplicate
1693  */
1695 trio_string_duplicate
1698 {
1699  trio_string_t *self;
1700 
1701  assert(other);
1702 
1703  self = TrioStringAlloc();
1704  if (self)
1705  {
1706  self->content = TrioDuplicateMax(other->content, other->length);
1707  if (self->content)
1708  {
1709  self->length = other->length;
1710  self->allocated = self->length + 1;
1711  }
1712  else
1713  {
1714  self->length = self->allocated = 0;
1715  }
1716  }
1717  return self;
1718 }
1719 #endif /* !defined(TRIO_MINIMAL) */
1720 
1721 
1722 /*
1723  * trio_xstring_duplicate
1724  */
1726 trio_xstring_duplicate
1728  TRIO_CONST char *other)
1729 {
1730  trio_string_t *self;
1731 
1732  assert(other);
1733 
1734  self = TrioStringAlloc();
1735  if (self)
1736  {
1737  self->content = TrioDuplicateMax(other, trio_length(other));
1738  if (self->content)
1739  {
1740  self->length = trio_length(self->content);
1741  self->allocated = self->length + 1;
1742  }
1743  else
1744  {
1745  self->length = self->allocated = 0;
1746  }
1747  }
1748  return self;
1749 }
1750 
1751 
1752 #if !defined(TRIO_MINIMAL)
1753 /*
1754  * trio_string_equal
1755  */
1757 trio_string_equal
1758 TRIO_ARGS2((self, other),
1759  trio_string_t *self,
1761 {
1762  assert(self);
1763  assert(other);
1764 
1765  return trio_equal(self->content, other->content);
1766 }
1767 #endif /* !defined(TRIO_MINIMAL) */
1768 
1769 
1770 #if !defined(TRIO_MINIMAL)
1771 /*
1772  * trio_xstring_equal
1773  */
1775 trio_xstring_equal
1776 TRIO_ARGS2((self, other),
1777  trio_string_t *self,
1778  TRIO_CONST char *other)
1779 {
1780  assert(self);
1781  assert(other);
1782 
1783  return trio_equal(self->content, other);
1784 }
1785 #endif /* !defined(TRIO_MINIMAL) */
1786 
1787 
1788 #if !defined(TRIO_MINIMAL)
1789 /*
1790  * trio_string_equal_max
1791  */
1793 trio_string_equal_max
1794 TRIO_ARGS3((self, max, other),
1795  trio_string_t *self,
1796  size_t max,
1798 {
1799  assert(self);
1800  assert(other);
1801 
1802  return trio_equal_max(self->content, max, other->content);
1803 }
1804 #endif /* !defined(TRIO_MINIMAL) */
1805 
1806 
1807 #if !defined(TRIO_MINIMAL)
1808 /*
1809  * trio_xstring_equal_max
1810  */
1812 trio_xstring_equal_max
1813 TRIO_ARGS3((self, max, other),
1814  trio_string_t *self,
1815  size_t max,
1816  TRIO_CONST char *other)
1817 {
1818  assert(self);
1819  assert(other);
1820 
1821  return trio_equal_max(self->content, max, other);
1822 }
1823 #endif /* !defined(TRIO_MINIMAL) */
1824 
1825 
1826 #if !defined(TRIO_MINIMAL)
1827 /*
1828  * trio_string_equal_case
1829  */
1831 trio_string_equal_case
1832 TRIO_ARGS2((self, other),
1833  trio_string_t *self,
1835 {
1836  assert(self);
1837  assert(other);
1838 
1839  return trio_equal_case(self->content, other->content);
1840 }
1841 #endif /* !defined(TRIO_MINIMAL) */
1842 
1843 
1844 #if !defined(TRIO_MINIMAL)
1845 /*
1846  * trio_xstring_equal_case
1847  */
1849 trio_xstring_equal_case
1850 TRIO_ARGS2((self, other),
1851  trio_string_t *self,
1852  TRIO_CONST char *other)
1853 {
1854  assert(self);
1855  assert(other);
1856 
1857  return trio_equal_case(self->content, other);
1858 }
1859 #endif /* !defined(TRIO_MINIMAL) */
1860 
1861 
1862 #if !defined(TRIO_MINIMAL)
1863 /*
1864  * trio_string_equal_case_max
1865  */
1867 trio_string_equal_case_max
1868 TRIO_ARGS3((self, max, other),
1869  trio_string_t *self,
1870  size_t max,
1872 {
1873  assert(self);
1874  assert(other);
1875 
1876  return trio_equal_case_max(self->content, max, other->content);
1877 }
1878 #endif /* !defined(TRIO_MINIMAL) */
1879 
1880 
1881 #if !defined(TRIO_MINIMAL)
1882 /*
1883  * trio_xstring_equal_case_max
1884  */
1886 trio_xstring_equal_case_max
1887 TRIO_ARGS3((self, max, other),
1888  trio_string_t *self,
1889  size_t max,
1890  TRIO_CONST char *other)
1891 {
1892  assert(self);
1893  assert(other);
1894 
1895  return trio_equal_case_max(self->content, max, other);
1896 }
1897 #endif /* !defined(TRIO_MINIMAL) */
1898 
1899 
1900 #if !defined(TRIO_MINIMAL) && !defined(_WIN32_WCE)
1901 /*
1902  * trio_string_format_data_max
1903  */
1904 TRIO_STRING_PUBLIC size_t
1905 trio_string_format_date_max
1906 TRIO_ARGS4((self, max, format, datetime),
1907  trio_string_t *self,
1908  size_t max,
1909  TRIO_CONST char *format,
1910  TRIO_CONST struct tm *datetime)
1911 {
1912  assert(self);
1913 
1914  return trio_format_date_max(self->content, max, format, datetime);
1915 }
1916 #endif /* !defined(TRIO_MINIMAL) */
1917 
1918 
1919 #if !defined(TRIO_MINIMAL)
1920 /*
1921  * trio_string_index
1922  */
1923 TRIO_STRING_PUBLIC char *
1924 trio_string_index
1925 TRIO_ARGS2((self, character),
1926  trio_string_t *self,
1927  int character)
1928 {
1929  assert(self);
1930 
1931  return trio_index(self->content, character);
1932 }
1933 #endif /* !defined(TRIO_MINIMAL) */
1934 
1935 
1936 #if !defined(TRIO_MINIMAL)
1937 /*
1938  * trio_string_index_last
1939  */
1940 TRIO_STRING_PUBLIC char *
1941 trio_string_index_last
1942 TRIO_ARGS2((self, character),
1943  trio_string_t *self,
1944  int character)
1945 {
1946  assert(self);
1947 
1948  return trio_index_last(self->content, character);
1949 }
1950 #endif /* !defined(TRIO_MINIMAL) */
1951 
1952 
1953 #if !defined(TRIO_MINIMAL)
1954 /*
1955  * trio_string_length
1956  */
1958 trio_string_length
1959 TRIO_ARGS1((self),
1960  trio_string_t *self)
1961 {
1962  assert(self);
1963 
1964  if (self->length == 0)
1965  {
1966  self->length = trio_length(self->content);
1967  }
1968  return self->length;
1969 }
1970 #endif /* !defined(TRIO_MINIMAL) */
1971 
1972 
1973 #if !defined(TRIO_MINIMAL)
1974 /*
1975  * trio_string_lower
1976  */
1978 trio_string_lower
1979 TRIO_ARGS1((self),
1980  trio_string_t *self)
1981 {
1982  assert(self);
1983 
1984  return trio_lower(self->content);
1985 }
1986 #endif /* !defined(TRIO_MINIMAL) */
1987 
1988 
1989 #if !defined(TRIO_MINIMAL)
1990 /*
1991  * trio_string_match
1992  */
1994 trio_string_match
1995 TRIO_ARGS2((self, other),
1996  trio_string_t *self,
1998 {
1999  assert(self);
2000  assert(other);
2001 
2002  return trio_match(self->content, other->content);
2003 }
2004 #endif /* !defined(TRIO_MINIMAL) */
2005 
2006 
2007 #if !defined(TRIO_MINIMAL)
2008 /*
2009  * trio_xstring_match
2010  */
2012 trio_xstring_match
2013 TRIO_ARGS2((self, other),
2014  trio_string_t *self,
2015  TRIO_CONST char *other)
2016 {
2017  assert(self);
2018  assert(other);
2019 
2020  return trio_match(self->content, other);
2021 }
2022 #endif /* !defined(TRIO_MINIMAL) */
2023 
2024 
2025 #if !defined(TRIO_MINIMAL)
2026 /*
2027  * trio_string_match_case
2028  */
2030 trio_string_match_case
2031 TRIO_ARGS2((self, other),
2032  trio_string_t *self,
2034 {
2035  assert(self);
2036  assert(other);
2037 
2038  return trio_match_case(self->content, other->content);
2039 }
2040 #endif /* !defined(TRIO_MINIMAL) */
2041 
2042 
2043 #if !defined(TRIO_MINIMAL)
2044 /*
2045  * trio_xstring_match_case
2046  */
2048 trio_xstring_match_case
2049 TRIO_ARGS2((self, other),
2050  trio_string_t *self,
2051  TRIO_CONST char *other)
2052 {
2053  assert(self);
2054  assert(other);
2055 
2056  return trio_match_case(self->content, other);
2057 }
2058 #endif /* !defined(TRIO_MINIMAL) */
2059 
2060 
2061 #if !defined(TRIO_MINIMAL)
2062 /*
2063  * trio_string_substring
2064  */
2065 TRIO_STRING_PUBLIC char *
2066 trio_string_substring
2067 TRIO_ARGS2((self, other),
2068  trio_string_t *self,
2070 {
2071  assert(self);
2072  assert(other);
2073 
2074  return trio_substring(self->content, other->content);
2075 }
2076 #endif /* !defined(TRIO_MINIMAL) */
2077 
2078 
2079 #if !defined(TRIO_MINIMAL)
2080 /*
2081  * trio_xstring_substring
2082  */
2083 TRIO_STRING_PUBLIC char *
2084 trio_xstring_substring
2085 TRIO_ARGS2((self, other),
2086  trio_string_t *self,
2087  TRIO_CONST char *other)
2088 {
2089  assert(self);
2090  assert(other);
2091 
2092  return trio_substring(self->content, other);
2093 }
2094 #endif /* !defined(TRIO_MINIMAL) */
2095 
2096 
2097 #if !defined(TRIO_MINIMAL)
2098 /*
2099  * trio_string_upper
2100  */
2102 trio_string_upper
2103 TRIO_ARGS1((self),
2104  trio_string_t *self)
2105 {
2106  assert(self);
2107 
2108  return trio_upper(self->content);
2109 }
2110 #endif /* !defined(TRIO_MINIMAL) */
2111 
#define max(a, b)
Definition: svc.c:63
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
Definition: get.c:139
double trio_long_double_t
Definition: triodef.h:132
#define error(str)
Definition: mkdosfs.c:1605
char * strncat(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:605
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
#define strcasecmp
Definition: fake.h:9
Definition: bidi.c:75
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
_Check_return_ double __cdecl strtod(_In_z_ const char *_Str, _Out_opt_ _Deref_post_z_ char **_EndPtr)
TRIO_STRING_PUBLIC char *trio_create TRIO_ARGS1((size), size_t size)
Definition: triostr.c:132
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
IN OUT PIRP IN ULONG IN WMIENABLEDISABLECONTROL Function
Definition: wmilib.h:37
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
int other
Definition: msacm.c:1364
const GLint * first
Definition: glext.h:5794
#define TRIO_CONST
Definition: triodef.h:129
int sys_nerr
#define TRIO_REALLOC(x, n)
Definition: triop.h:74
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define assert(x)
Definition: debug.h:53
GLuint buffer
Definition: glext.h:5915
size_t length
Definition: triostr.c:101
const char * strerror(int err)
Definition: compat_str.c:23
TRIO_STRING_PUBLIC int trio_append_max TRIO_ARGS3((target, max, source), char *target, size_t max, TRIO_CONST char *source)
Definition: triostr.c:216
TRIO_STRING_PRIVATE trio_string_t * TrioStringAlloc(TRIO_NOARGS)
Definition: triostr.c:1272
const XML_Char int const XML_Char int const XML_Char * base
Definition: expat.h:331
#define TRIO_PROTO(x)
Definition: triodef.h:135
TRIO_STRING_PUBLIC int trio_append TRIO_ARGS2((target, source), char *target, TRIO_CONST char *source)
Definition: triostr.c:187
float pow(float __x, int __y)
Definition: _cmath.h:458
#define strcoll
Definition: util.h:34
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:47
#define strncasecmp
Definition: fake.h:10
unsigned char
Definition: typeof.h:27
unsigned long
Definition: typeof.h:99
#define isdigit(c)
Definition: acclib.h:68
size_t CDECL strftime(char *str, size_t max, const char *format, const struct tm *mstm)
Definition: strftime.c:293
size_t allocated
Definition: triostr.c:102
#define TRIO_STRING_PRIVATE
Definition: triostr.c:38
int toupper(int c)
Definition: utclib.c:881
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
static TRIO_CONST char rcsid[]
Definition: triostr.c:110
#define TRIO_NOARGS
Definition: triodef.h:136
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
#define BOOLEAN_T
Definition: triostr.c:52
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define FALSE
Definition: triostr.c:48
#define TRUE
Definition: triostr.c:49
#define TRIO_STRING_PUBLIC
Definition: triostr.h:38
#define NULL
Definition: triostr.c:42
#define NIL
Definition: triostr.c:45
Definition: time.h:76
GLsizei const GLfloat * value
Definition: glext.h:6069
#define TRIO_FREE(x)
Definition: triop.h:77
char string[160]
Definition: util.h:11
#define TRIO_MALLOC(n)
Definition: triop.h:71
float __cdecl strtof(const char *nptr, char **endptr)
GLsizei GLsizei GLchar * source
Definition: glext.h:6048
GLsizeiptr size
Definition: glext.h:5919
char * sys_errlist[]
char * strtok(char *String, const char *Delimiters)
Definition: utclib.c:338
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define isxdigit(c)
Definition: acclib.h:70
_Check_return_ long __cdecl strtol(_In_z_ const char *_Str, _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix)
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
GLenum target
Definition: glext.h:7315
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
char * content
Definition: triostr.c:100
TRIO_STRING_PUBLIC size_t trio_format_date_max TRIO_ARGS4((target, max, format, datetime), char *target, size_t max, TRIO_CONST char *format, TRIO_CONST struct tm *datetime)
Definition: triostr.c:602
#define TRIO_MICROSOFT
Definition: triop.h:58
long double __cdecl strtold(const char *__restrict__, char **__restrict__)
GLuint64EXT * result
Definition: glext.h:11304
int tolower(int c)
Definition: utclib.c:902
static SERVICE_STATUS status
Definition: service.c:26
GLubyte * pattern
Definition: glext.h:7787
GLintptr offset
Definition: glext.h:5920
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:29
Definition: ps.c:97