pocxxeci 0.30.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of pocxxeci might be problematic. Click here for more details.
- package/LICENSE +19 -0
- package/Makefile +18 -0
- package/README.md +52 -0
- package/binding.gyp +81 -0
- package/index.d.ts +273 -0
- package/index.js +45 -0
- package/lib/bindings.js +1 -0
- package/lib/document.js +122 -0
- package/lib/element.js +82 -0
- package/lib/sax_parser.js +38 -0
- package/package.json +70 -0
- package/src/html_document.cc +7 -0
- package/src/html_document.h +18 -0
- package/src/libxmljs.cc +252 -0
- package/src/libxmljs.h +53 -0
- package/src/xml_attribute.cc +173 -0
- package/src/xml_attribute.h +40 -0
- package/src/xml_comment.cc +117 -0
- package/src/xml_comment.h +30 -0
- package/src/xml_document.cc +810 -0
- package/src/xml_document.h +67 -0
- package/src/xml_element.cc +565 -0
- package/src/xml_element.h +61 -0
- package/src/xml_namespace.cc +158 -0
- package/src/xml_namespace.h +39 -0
- package/src/xml_node.cc +761 -0
- package/src/xml_node.h +73 -0
- package/src/xml_pi.cc +161 -0
- package/src/xml_pi.h +34 -0
- package/src/xml_sax_parser.cc +424 -0
- package/src/xml_sax_parser.h +73 -0
- package/src/xml_syntax_error.cc +66 -0
- package/src/xml_syntax_error.h +25 -0
- package/src/xml_text.cc +320 -0
- package/src/xml_text.h +48 -0
- package/src/xml_textwriter.cc +315 -0
- package/src/xml_textwriter.h +62 -0
- package/src/xml_xpath_context.cc +70 -0
- package/src/xml_xpath_context.h +23 -0
- package/vendor/libxml/Copyright +23 -0
- package/vendor/libxml/DOCBparser.c +305 -0
- package/vendor/libxml/HTMLparser.c +7287 -0
- package/vendor/libxml/HTMLtree.c +1200 -0
- package/vendor/libxml/Makefile +2983 -0
- package/vendor/libxml/SAX.c +180 -0
- package/vendor/libxml/SAX2.c +3036 -0
- package/vendor/libxml/buf.c +1351 -0
- package/vendor/libxml/buf.h +72 -0
- package/vendor/libxml/c14n.c +2234 -0
- package/vendor/libxml/catalog.c +3828 -0
- package/vendor/libxml/chvalid.c +336 -0
- package/vendor/libxml/config.h +294 -0
- package/vendor/libxml/config.h.gch +0 -0
- package/vendor/libxml/debugXML.c +3423 -0
- package/vendor/libxml/dict.c +1298 -0
- package/vendor/libxml/elfgcchack.h +17818 -0
- package/vendor/libxml/enc.h +32 -0
- package/vendor/libxml/encoding.c +3975 -0
- package/vendor/libxml/entities.c +1163 -0
- package/vendor/libxml/error.c +998 -0
- package/vendor/libxml/globals.c +1126 -0
- package/vendor/libxml/hash.c +1146 -0
- package/vendor/libxml/include/libxml/DOCBparser.h +96 -0
- package/vendor/libxml/include/libxml/HTMLparser.h +306 -0
- package/vendor/libxml/include/libxml/HTMLtree.h +147 -0
- package/vendor/libxml/include/libxml/Makefile +725 -0
- package/vendor/libxml/include/libxml/Makefile.am +54 -0
- package/vendor/libxml/include/libxml/Makefile.in +725 -0
- package/vendor/libxml/include/libxml/SAX.h +173 -0
- package/vendor/libxml/include/libxml/SAX2.h +178 -0
- package/vendor/libxml/include/libxml/c14n.h +128 -0
- package/vendor/libxml/include/libxml/catalog.h +182 -0
- package/vendor/libxml/include/libxml/chvalid.h +230 -0
- package/vendor/libxml/include/libxml/debugXML.h +217 -0
- package/vendor/libxml/include/libxml/dict.h +79 -0
- package/vendor/libxml/include/libxml/encoding.h +245 -0
- package/vendor/libxml/include/libxml/entities.h +151 -0
- package/vendor/libxml/include/libxml/globals.h +508 -0
- package/vendor/libxml/include/libxml/hash.h +236 -0
- package/vendor/libxml/include/libxml/list.h +137 -0
- package/vendor/libxml/include/libxml/nanoftp.h +163 -0
- package/vendor/libxml/include/libxml/nanohttp.h +81 -0
- package/vendor/libxml/include/libxml/parser.h +1243 -0
- package/vendor/libxml/include/libxml/parserInternals.h +644 -0
- package/vendor/libxml/include/libxml/pattern.h +100 -0
- package/vendor/libxml/include/libxml/relaxng.h +217 -0
- package/vendor/libxml/include/libxml/schemasInternals.h +958 -0
- package/vendor/libxml/include/libxml/schematron.h +142 -0
- package/vendor/libxml/include/libxml/threads.h +89 -0
- package/vendor/libxml/include/libxml/tree.h +1311 -0
- package/vendor/libxml/include/libxml/uri.h +94 -0
- package/vendor/libxml/include/libxml/valid.h +458 -0
- package/vendor/libxml/include/libxml/xinclude.h +129 -0
- package/vendor/libxml/include/libxml/xlink.h +189 -0
- package/vendor/libxml/include/libxml/xmlIO.h +368 -0
- package/vendor/libxml/include/libxml/xmlautomata.h +146 -0
- package/vendor/libxml/include/libxml/xmlerror.h +945 -0
- package/vendor/libxml/include/libxml/xmlexports.h +77 -0
- package/vendor/libxml/include/libxml/xmlmemory.h +224 -0
- package/vendor/libxml/include/libxml/xmlmodule.h +57 -0
- package/vendor/libxml/include/libxml/xmlreader.h +428 -0
- package/vendor/libxml/include/libxml/xmlregexp.h +222 -0
- package/vendor/libxml/include/libxml/xmlsave.h +88 -0
- package/vendor/libxml/include/libxml/xmlschemas.h +246 -0
- package/vendor/libxml/include/libxml/xmlschemastypes.h +151 -0
- package/vendor/libxml/include/libxml/xmlstring.h +140 -0
- package/vendor/libxml/include/libxml/xmlunicode.h +202 -0
- package/vendor/libxml/include/libxml/xmlversion.h +484 -0
- package/vendor/libxml/include/libxml/xmlwin32version.h +239 -0
- package/vendor/libxml/include/libxml/xmlwriter.h +488 -0
- package/vendor/libxml/include/libxml/xpath.h +564 -0
- package/vendor/libxml/include/libxml/xpathInternals.h +632 -0
- package/vendor/libxml/include/libxml/xpointer.h +114 -0
- package/vendor/libxml/include/win32config.h +122 -0
- package/vendor/libxml/include/wsockcompat.h +54 -0
- package/vendor/libxml/legacy.c +1343 -0
- package/vendor/libxml/libxml.h +134 -0
- package/vendor/libxml/list.c +779 -0
- package/vendor/libxml/nanoftp.c +2118 -0
- package/vendor/libxml/nanohttp.c +1899 -0
- package/vendor/libxml/parser.c +15553 -0
- package/vendor/libxml/parserInternals.c +2164 -0
- package/vendor/libxml/pattern.c +2621 -0
- package/vendor/libxml/relaxng.c +11101 -0
- package/vendor/libxml/rngparser.c +1595 -0
- package/vendor/libxml/runsuite.c +1157 -0
- package/vendor/libxml/save.h +36 -0
- package/vendor/libxml/schematron.c +1787 -0
- package/vendor/libxml/threads.c +1049 -0
- package/vendor/libxml/timsort.h +601 -0
- package/vendor/libxml/tree.c +10183 -0
- package/vendor/libxml/trio.c +6895 -0
- package/vendor/libxml/trio.h +230 -0
- package/vendor/libxml/triodef.h +228 -0
- package/vendor/libxml/trionan.c +914 -0
- package/vendor/libxml/trionan.h +84 -0
- package/vendor/libxml/triop.h +150 -0
- package/vendor/libxml/triostr.c +2112 -0
- package/vendor/libxml/triostr.h +144 -0
- package/vendor/libxml/uri.c +2561 -0
- package/vendor/libxml/valid.c +7138 -0
- package/vendor/libxml/xinclude.c +2657 -0
- package/vendor/libxml/xlink.c +183 -0
- package/vendor/libxml/xmlIO.c +4135 -0
- package/vendor/libxml/xmlcatalog.c +624 -0
- package/vendor/libxml/xmllint.c +3796 -0
- package/vendor/libxml/xmlmemory.c +1163 -0
- package/vendor/libxml/xmlmodule.c +468 -0
- package/vendor/libxml/xmlreader.c +6033 -0
- package/vendor/libxml/xmlregexp.c +8271 -0
- package/vendor/libxml/xmlsave.c +2735 -0
- package/vendor/libxml/xmlschemas.c +29173 -0
- package/vendor/libxml/xmlschemastypes.c +6276 -0
- package/vendor/libxml/xmlstring.c +1050 -0
- package/vendor/libxml/xmlunicode.c +3179 -0
- package/vendor/libxml/xmlwriter.c +4738 -0
- package/vendor/libxml/xpath.c +14734 -0
- package/vendor/libxml/xpointer.c +2969 -0
- package/vendor/libxml/xzlib.c +815 -0
- package/vendor/libxml/xzlib.h +19 -0
@@ -0,0 +1,2112 @@
|
|
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
|
+
* MERCHANTABILITY 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
|
+
|
98
|
+
struct _trio_string_t
|
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
|
+
/** @addtogroup StaticStrings
|
121
|
+
@{
|
122
|
+
*/
|
123
|
+
|
124
|
+
/**
|
125
|
+
Create new string.
|
126
|
+
|
127
|
+
@param size Size of new string.
|
128
|
+
@return Pointer to string, or NULL if allocation failed.
|
129
|
+
*/
|
130
|
+
TRIO_STRING_PUBLIC char *
|
131
|
+
trio_create
|
132
|
+
TRIO_ARGS1((size),
|
133
|
+
size_t size)
|
134
|
+
{
|
135
|
+
return (char *)TRIO_MALLOC(size);
|
136
|
+
}
|
137
|
+
|
138
|
+
|
139
|
+
/**
|
140
|
+
Destroy string.
|
141
|
+
|
142
|
+
@param string String to be freed.
|
143
|
+
*/
|
144
|
+
TRIO_STRING_PUBLIC void
|
145
|
+
trio_destroy
|
146
|
+
TRIO_ARGS1((string),
|
147
|
+
char *string)
|
148
|
+
{
|
149
|
+
if (string)
|
150
|
+
{
|
151
|
+
TRIO_FREE(string);
|
152
|
+
}
|
153
|
+
}
|
154
|
+
|
155
|
+
|
156
|
+
/**
|
157
|
+
Count the number of characters in a string.
|
158
|
+
|
159
|
+
@param string String to measure.
|
160
|
+
@return Number of characters in @string.
|
161
|
+
*/
|
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
|
+
/**
|
173
|
+
Append @p source at the end of @p target.
|
174
|
+
|
175
|
+
@param target Target string.
|
176
|
+
@param source Source string.
|
177
|
+
@return Boolean value indicating success or failure.
|
178
|
+
|
179
|
+
@pre @p target must point to a memory chunk with sufficient room to
|
180
|
+
contain the @p target string and @p source string.
|
181
|
+
@pre No boundary checking is performed, so insufficient memory will
|
182
|
+
result in a buffer overrun.
|
183
|
+
@post @p target will be zero terminated.
|
184
|
+
*/
|
185
|
+
TRIO_STRING_PUBLIC int
|
186
|
+
trio_append
|
187
|
+
TRIO_ARGS2((target, source),
|
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
|
+
/**
|
200
|
+
Append at most @p max characters from @p source to @p target.
|
201
|
+
|
202
|
+
@param target Target string.
|
203
|
+
@param max Maximum number of characters to append.
|
204
|
+
@param source Source string.
|
205
|
+
@return Boolean value indicating success or failure.
|
206
|
+
|
207
|
+
@pre @p target must point to a memory chuck with sufficient room to
|
208
|
+
contain the @p target string and the @p source string (at most @p max
|
209
|
+
characters).
|
210
|
+
@pre No boundary checking is performed, so insufficient memory will
|
211
|
+
result in a buffer overrun.
|
212
|
+
@post @p target will be zero terminated.
|
213
|
+
*/
|
214
|
+
TRIO_STRING_PUBLIC int
|
215
|
+
trio_append_max
|
216
|
+
TRIO_ARGS3((target, max, source),
|
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
|
+
/**
|
239
|
+
Determine if a string contains a substring.
|
240
|
+
|
241
|
+
@param string String to be searched.
|
242
|
+
@param substring String to be found.
|
243
|
+
@return Boolean value indicating success or failure.
|
244
|
+
*/
|
245
|
+
TRIO_STRING_PUBLIC int
|
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
|
+
/**
|
261
|
+
Copy @p source to @p target.
|
262
|
+
|
263
|
+
@param target Target string.
|
264
|
+
@param source Source string.
|
265
|
+
@return Boolean value indicating success or failure.
|
266
|
+
|
267
|
+
@pre @p target must point to a memory chunk with sufficient room to
|
268
|
+
contain the @p source string.
|
269
|
+
@pre No boundary checking is performed, so insufficient memory will
|
270
|
+
result in a buffer overrun.
|
271
|
+
@post @p target will be zero terminated.
|
272
|
+
*/
|
273
|
+
TRIO_STRING_PUBLIC int
|
274
|
+
trio_copy
|
275
|
+
TRIO_ARGS2((target, source),
|
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
|
+
|
288
|
+
/**
|
289
|
+
Copy at most @p max characters from @p source to @p target.
|
290
|
+
|
291
|
+
@param target Target string.
|
292
|
+
@param max Maximum number of characters to append.
|
293
|
+
@param source Source string.
|
294
|
+
@return Boolean value indicating success or failure.
|
295
|
+
|
296
|
+
@pre @p target must point to a memory chunk with sufficient room to
|
297
|
+
contain the @p source string (at most @p max characters).
|
298
|
+
@pre No boundary checking is performed, so insufficient memory will
|
299
|
+
result in a buffer overrun.
|
300
|
+
@post @p target will be zero terminated.
|
301
|
+
*/
|
302
|
+
TRIO_STRING_PUBLIC int
|
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
|
+
|
343
|
+
/**
|
344
|
+
Duplicate @p source.
|
345
|
+
|
346
|
+
@param source Source string.
|
347
|
+
@return A copy of the @p source string.
|
348
|
+
|
349
|
+
@post @p target will be zero terminated.
|
350
|
+
*/
|
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
|
+
/**
|
362
|
+
Duplicate at most @p max characters of @p source.
|
363
|
+
|
364
|
+
@param source Source string.
|
365
|
+
@param max Maximum number of characters to duplicate.
|
366
|
+
@return A copy of the @p source string.
|
367
|
+
|
368
|
+
@post @p target will be zero terminated.
|
369
|
+
*/
|
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
|
+
|
390
|
+
/**
|
391
|
+
Compare if two strings are equal.
|
392
|
+
|
393
|
+
@param first First string.
|
394
|
+
@param second Second string.
|
395
|
+
@return Boolean indicating whether the two strings are equal or not.
|
396
|
+
|
397
|
+
Case-insensitive comparison.
|
398
|
+
*/
|
399
|
+
TRIO_STRING_PUBLIC int
|
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
|
+
|
429
|
+
/**
|
430
|
+
Compare if two strings are equal.
|
431
|
+
|
432
|
+
@param first First string.
|
433
|
+
@param second Second string.
|
434
|
+
@return Boolean indicating whether the two strings are equal or not.
|
435
|
+
|
436
|
+
Case-sensitive comparison.
|
437
|
+
*/
|
438
|
+
TRIO_STRING_PUBLIC int
|
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
|
+
/**
|
457
|
+
Compare if two strings up until the first @p max characters are equal.
|
458
|
+
|
459
|
+
@param first First string.
|
460
|
+
@param max Maximum number of characters to compare.
|
461
|
+
@param second Second string.
|
462
|
+
@return Boolean indicating whether the two strings are equal or not.
|
463
|
+
|
464
|
+
Case-sensitive comparison.
|
465
|
+
*/
|
466
|
+
TRIO_STRING_PUBLIC int
|
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
|
+
|
485
|
+
/**
|
486
|
+
Compare if two strings are equal.
|
487
|
+
|
488
|
+
@param first First string.
|
489
|
+
@param second Second string.
|
490
|
+
@return Boolean indicating whether the two strings are equal or not.
|
491
|
+
|
492
|
+
Collating characters are considered equal.
|
493
|
+
*/
|
494
|
+
TRIO_STRING_PUBLIC int
|
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
|
+
|
511
|
+
/**
|
512
|
+
Compare if two strings up until the first @p max characters are equal.
|
513
|
+
|
514
|
+
@param first First string.
|
515
|
+
@param max Maximum number of characters to compare.
|
516
|
+
@param second Second string.
|
517
|
+
@return Boolean indicating whether the two strings are equal or not.
|
518
|
+
|
519
|
+
Case-insensitive comparison.
|
520
|
+
*/
|
521
|
+
TRIO_STRING_PUBLIC int
|
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
|
+
|
555
|
+
/**
|
556
|
+
Provide a textual description of an error code (errno).
|
557
|
+
|
558
|
+
@param error_number Error number.
|
559
|
+
@return Textual description of @p error_number.
|
560
|
+
*/
|
561
|
+
TRIO_STRING_PUBLIC TRIO_CONST char *
|
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
|
+
/**
|
589
|
+
Format the date/time according to @p format.
|
590
|
+
|
591
|
+
@param target Target string.
|
592
|
+
@param max Maximum number of characters to format.
|
593
|
+
@param format Formatting string.
|
594
|
+
@param datetime Date/time structure.
|
595
|
+
@return Number of formatted characters.
|
596
|
+
|
597
|
+
The formatting string accepts the same specifiers as the standard C
|
598
|
+
function strftime.
|
599
|
+
*/
|
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
|
+
/**
|
620
|
+
Calculate a hash value for a string.
|
621
|
+
|
622
|
+
@param string String to be calculated on.
|
623
|
+
@param type Hash function.
|
624
|
+
@return Calculated hash value.
|
625
|
+
|
626
|
+
@p type can be one of the following
|
627
|
+
@li @c TRIO_HASH_PLAIN Plain hash function.
|
628
|
+
*/
|
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
|
+
/**
|
660
|
+
Find first occurrence of a character in a string.
|
661
|
+
|
662
|
+
@param string String to be searched.
|
663
|
+
@param character Character to be found.
|
664
|
+
@param A pointer to the found character, or NULL if character was not found.
|
665
|
+
*/
|
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
|
+
/**
|
681
|
+
Find last occurrence of a character in a string.
|
682
|
+
|
683
|
+
@param string String to be searched.
|
684
|
+
@param character Character to be found.
|
685
|
+
@param A pointer to the found character, or NULL if character was not found.
|
686
|
+
*/
|
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
|
+
/**
|
702
|
+
Convert the alphabetic letters in the string to lower-case.
|
703
|
+
|
704
|
+
@param target String to be converted.
|
705
|
+
@return Number of processed characters (converted or not).
|
706
|
+
*/
|
707
|
+
TRIO_STRING_PUBLIC int
|
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
|
+
/**
|
721
|
+
Compare two strings using wildcards.
|
722
|
+
|
723
|
+
@param string String to be searched.
|
724
|
+
@param pattern Pattern, including wildcards, to search for.
|
725
|
+
@return Boolean value indicating success or failure.
|
726
|
+
|
727
|
+
Case-insensitive comparison.
|
728
|
+
|
729
|
+
The following wildcards can be used
|
730
|
+
@li @c * Match any number of characters.
|
731
|
+
@li @c ? Match a single character.
|
732
|
+
*/
|
733
|
+
TRIO_STRING_PUBLIC int
|
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
|
+
/**
|
774
|
+
Compare two strings using wildcards.
|
775
|
+
|
776
|
+
@param string String to be searched.
|
777
|
+
@param pattern Pattern, including wildcards, to search for.
|
778
|
+
@return Boolean value indicating success or failure.
|
779
|
+
|
780
|
+
Case-sensitive comparison.
|
781
|
+
|
782
|
+
The following wildcards can be used
|
783
|
+
@li @c * Match any number of characters.
|
784
|
+
@li @c ? Match a single character.
|
785
|
+
*/
|
786
|
+
TRIO_STRING_PUBLIC int
|
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
|
+
/**
|
827
|
+
Execute a function on each character in string.
|
828
|
+
|
829
|
+
@param target Target string.
|
830
|
+
@param source Source string.
|
831
|
+
@param Function Function to be executed.
|
832
|
+
@return Number of processed characters.
|
833
|
+
*/
|
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
|
+
/**
|
859
|
+
Search for a substring in a string.
|
860
|
+
|
861
|
+
@param string String to be searched.
|
862
|
+
@param substring String to be found.
|
863
|
+
@return Pointer to first occurrence of @p substring in @p string, or NULL
|
864
|
+
if no match was found.
|
865
|
+
*/
|
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
|
+
/**
|
882
|
+
Search for a substring in the first @p max characters of a string.
|
883
|
+
|
884
|
+
@param string String to be searched.
|
885
|
+
@param max Maximum characters to be searched.
|
886
|
+
@param substring String to be found.
|
887
|
+
@return Pointer to first occurrence of @p substring in @p string, or NULL
|
888
|
+
if no match was found.
|
889
|
+
*/
|
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
|
+
/**
|
923
|
+
Tokenize string.
|
924
|
+
|
925
|
+
@param string String to be tokenized.
|
926
|
+
@param tokens String containing list of delimiting characters.
|
927
|
+
@return Start of new token.
|
928
|
+
|
929
|
+
@warning @p string will be destroyed.
|
930
|
+
*/
|
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
|
+
|
944
|
+
/**
|
945
|
+
Convert string to floating-point number.
|
946
|
+
|
947
|
+
@param source String to be converted.
|
948
|
+
@param endp Pointer to end of the converted string.
|
949
|
+
@return A floating-point number.
|
950
|
+
|
951
|
+
The following Extended Backus-Naur form is used
|
952
|
+
@verbatim
|
953
|
+
double ::= [ <sign> ]
|
954
|
+
( <number> |
|
955
|
+
<number> <decimal_point> <number> |
|
956
|
+
<decimal_point> <number> )
|
957
|
+
[ <exponential> [ <sign> ] <number> ]
|
958
|
+
number ::= 1*( <digit> )
|
959
|
+
digit ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )
|
960
|
+
exponential ::= ( 'e' | 'E' )
|
961
|
+
sign ::= ( '-' | '+' )
|
962
|
+
decimal_point ::= '.'
|
963
|
+
@endverbatim
|
964
|
+
*/
|
965
|
+
/* FIXME: Add EBNF for hex-floats */
|
966
|
+
TRIO_STRING_PUBLIC trio_long_double_t
|
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;
|
980
|
+
trio_long_double_t base;
|
981
|
+
trio_long_double_t fracdiv = 1.0;
|
982
|
+
trio_long_double_t value = 0.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
|
+
|
1092
|
+
/**
|
1093
|
+
Convert string to floating-point number.
|
1094
|
+
|
1095
|
+
@param source String to be converted.
|
1096
|
+
@param endp Pointer to end of the converted string.
|
1097
|
+
@return A floating-point number.
|
1098
|
+
|
1099
|
+
See @ref trio_to_long_double.
|
1100
|
+
*/
|
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
|
+
/**
|
1116
|
+
Convert string to floating-point number.
|
1117
|
+
|
1118
|
+
@param source String to be converted.
|
1119
|
+
@param endp Pointer to end of the converted string.
|
1120
|
+
@return A floating-point number.
|
1121
|
+
|
1122
|
+
See @ref trio_to_long_double.
|
1123
|
+
*/
|
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
|
+
|
1139
|
+
/**
|
1140
|
+
Convert string to signed integer.
|
1141
|
+
|
1142
|
+
@param string String to be converted.
|
1143
|
+
@param endp Pointer to end of converted string.
|
1144
|
+
@param base Radix number of number.
|
1145
|
+
*/
|
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
|
+
/**
|
1162
|
+
Convert one alphabetic letter to lower-case.
|
1163
|
+
|
1164
|
+
@param source The letter to be converted.
|
1165
|
+
@return The converted letter.
|
1166
|
+
*/
|
1167
|
+
TRIO_STRING_PUBLIC int
|
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
|
+
/**
|
1189
|
+
Convert string to unsigned integer.
|
1190
|
+
|
1191
|
+
@param string String to be converted.
|
1192
|
+
@param endp Pointer to end of converted string.
|
1193
|
+
@param base Radix number of number.
|
1194
|
+
*/
|
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
|
+
|
1210
|
+
/**
|
1211
|
+
Convert one alphabetic letter to upper-case.
|
1212
|
+
|
1213
|
+
@param source The letter to be converted.
|
1214
|
+
@return The converted letter.
|
1215
|
+
*/
|
1216
|
+
TRIO_STRING_PUBLIC int
|
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
|
+
/**
|
1237
|
+
Convert the alphabetic letters in the string to upper-case.
|
1238
|
+
|
1239
|
+
@param target The string to be converted.
|
1240
|
+
@return The number of processed characters (converted or not).
|
1241
|
+
*/
|
1242
|
+
TRIO_STRING_PUBLIC int
|
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
|
+
|
1254
|
+
/** @} End of StaticStrings */
|
1255
|
+
|
1256
|
+
|
1257
|
+
/*************************************************************************
|
1258
|
+
* Dynamic String Functions
|
1259
|
+
*/
|
1260
|
+
|
1261
|
+
#if defined(TRIO_DOCUMENTATION)
|
1262
|
+
# include "doc/doc_dynamic.h"
|
1263
|
+
#endif
|
1264
|
+
/** @addtogroup DynamicStrings
|
1265
|
+
@{
|
1266
|
+
*/
|
1267
|
+
|
1268
|
+
/*
|
1269
|
+
* TrioStringAlloc
|
1270
|
+
*/
|
1271
|
+
TRIO_STRING_PRIVATE trio_string_t *
|
1272
|
+
TrioStringAlloc(TRIO_NOARGS)
|
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
|
+
*/
|
1293
|
+
TRIO_STRING_PRIVATE BOOLEAN_T
|
1294
|
+
TrioStringGrow
|
1295
|
+
TRIO_ARGS2((self, delta),
|
1296
|
+
trio_string_t *self,
|
1297
|
+
size_t delta)
|
1298
|
+
{
|
1299
|
+
BOOLEAN_T status = FALSE;
|
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
|
+
*/
|
1326
|
+
TRIO_STRING_PRIVATE BOOLEAN_T
|
1327
|
+
TrioStringGrowTo
|
1328
|
+
TRIO_ARGS2((self, length),
|
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
|
+
/**
|
1342
|
+
Create a new dynamic string.
|
1343
|
+
|
1344
|
+
@param initial_size Initial size of the buffer.
|
1345
|
+
@return Newly allocated dynamic string, or NULL if memory allocation failed.
|
1346
|
+
*/
|
1347
|
+
TRIO_STRING_PUBLIC trio_string_t *
|
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
|
+
|
1374
|
+
/**
|
1375
|
+
Deallocate the dynamic string and its contents.
|
1376
|
+
|
1377
|
+
@param self Dynamic string
|
1378
|
+
*/
|
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
|
+
/**
|
1396
|
+
Get a pointer to the content.
|
1397
|
+
|
1398
|
+
@param self Dynamic string.
|
1399
|
+
@param offset Offset into content.
|
1400
|
+
@return Pointer to the content.
|
1401
|
+
|
1402
|
+
@p Offset can be zero, positive, or negative. If @p offset is zero,
|
1403
|
+
then the start of the content will be returned. If @p offset is positive,
|
1404
|
+
then a pointer to @p offset number of characters from the beginning of the
|
1405
|
+
content is returned. If @p offset is negative, then a pointer to @p offset
|
1406
|
+
number of characters from the ending of the string, starting at the
|
1407
|
+
terminating zero, is returned.
|
1408
|
+
*/
|
1409
|
+
TRIO_STRING_PUBLIC char *
|
1410
|
+
trio_string_get
|
1411
|
+
TRIO_ARGS2((self, offset),
|
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
|
+
|
1447
|
+
/**
|
1448
|
+
Extract the content.
|
1449
|
+
|
1450
|
+
@param self Dynamic String
|
1451
|
+
@return Content of dynamic string.
|
1452
|
+
|
1453
|
+
The content is removed from the dynamic string. This enables destruction
|
1454
|
+
of the dynamic string without deallocation of the content.
|
1455
|
+
*/
|
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
|
+
/**
|
1475
|
+
Set the content of the dynamic string.
|
1476
|
+
|
1477
|
+
@param self Dynamic String
|
1478
|
+
@param buffer The new content.
|
1479
|
+
|
1480
|
+
Sets the content of the dynamic string to a copy @p buffer.
|
1481
|
+
An existing content will be deallocated first, if necessary.
|
1482
|
+
|
1483
|
+
@remark
|
1484
|
+
This function will make a copy of @p buffer.
|
1485
|
+
You are responsible for deallocating @p buffer yourself.
|
1486
|
+
*/
|
1487
|
+
TRIO_STRING_PUBLIC void
|
1488
|
+
trio_xstring_set
|
1489
|
+
TRIO_ARGS2((self, buffer),
|
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
|
+
*/
|
1504
|
+
TRIO_STRING_PUBLIC int
|
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
|
+
/**
|
1529
|
+
Append the second string to the first.
|
1530
|
+
|
1531
|
+
@param self Dynamic string to be modified.
|
1532
|
+
@param other Dynamic string to copy from.
|
1533
|
+
@return Boolean value indicating success or failure.
|
1534
|
+
*/
|
1535
|
+
TRIO_STRING_PUBLIC int
|
1536
|
+
trio_string_append
|
1537
|
+
TRIO_ARGS2((self, other),
|
1538
|
+
trio_string_t *self,
|
1539
|
+
trio_string_t *other)
|
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
|
+
*/
|
1563
|
+
TRIO_STRING_PUBLIC int
|
1564
|
+
trio_xstring_append
|
1565
|
+
TRIO_ARGS2((self, other),
|
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
|
+
*/
|
1590
|
+
TRIO_STRING_PUBLIC int
|
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
|
+
/**
|
1614
|
+
Search for the first occurrence of second parameter in the first.
|
1615
|
+
|
1616
|
+
@param self Dynamic string to be modified.
|
1617
|
+
@param other Dynamic string to copy from.
|
1618
|
+
@return Boolean value indicating success or failure.
|
1619
|
+
*/
|
1620
|
+
TRIO_STRING_PUBLIC int
|
1621
|
+
trio_string_contains
|
1622
|
+
TRIO_ARGS2((self, other),
|
1623
|
+
trio_string_t *self,
|
1624
|
+
trio_string_t *other)
|
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
|
+
*/
|
1638
|
+
TRIO_STRING_PUBLIC int
|
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
|
+
*/
|
1656
|
+
TRIO_STRING_PUBLIC int
|
1657
|
+
trio_string_copy
|
1658
|
+
TRIO_ARGS2((self, other),
|
1659
|
+
trio_string_t *self,
|
1660
|
+
trio_string_t *other)
|
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
|
+
*/
|
1675
|
+
TRIO_STRING_PUBLIC int
|
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
|
+
*/
|
1694
|
+
TRIO_STRING_PUBLIC trio_string_t *
|
1695
|
+
trio_string_duplicate
|
1696
|
+
TRIO_ARGS1((other),
|
1697
|
+
trio_string_t *other)
|
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
|
+
*/
|
1725
|
+
TRIO_STRING_PUBLIC trio_string_t *
|
1726
|
+
trio_xstring_duplicate
|
1727
|
+
TRIO_ARGS1((other),
|
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
|
+
*/
|
1756
|
+
TRIO_STRING_PUBLIC int
|
1757
|
+
trio_string_equal
|
1758
|
+
TRIO_ARGS2((self, other),
|
1759
|
+
trio_string_t *self,
|
1760
|
+
trio_string_t *other)
|
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
|
+
*/
|
1774
|
+
TRIO_STRING_PUBLIC int
|
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
|
+
*/
|
1792
|
+
TRIO_STRING_PUBLIC int
|
1793
|
+
trio_string_equal_max
|
1794
|
+
TRIO_ARGS3((self, max, other),
|
1795
|
+
trio_string_t *self,
|
1796
|
+
size_t max,
|
1797
|
+
trio_string_t *other)
|
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
|
+
*/
|
1811
|
+
TRIO_STRING_PUBLIC int
|
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
|
+
*/
|
1830
|
+
TRIO_STRING_PUBLIC int
|
1831
|
+
trio_string_equal_case
|
1832
|
+
TRIO_ARGS2((self, other),
|
1833
|
+
trio_string_t *self,
|
1834
|
+
trio_string_t *other)
|
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
|
+
*/
|
1848
|
+
TRIO_STRING_PUBLIC int
|
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
|
+
*/
|
1866
|
+
TRIO_STRING_PUBLIC int
|
1867
|
+
trio_string_equal_case_max
|
1868
|
+
TRIO_ARGS3((self, max, other),
|
1869
|
+
trio_string_t *self,
|
1870
|
+
size_t max,
|
1871
|
+
trio_string_t *other)
|
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
|
+
*/
|
1885
|
+
TRIO_STRING_PUBLIC int
|
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
|
+
*/
|
1957
|
+
TRIO_STRING_PUBLIC int
|
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
|
+
*/
|
1977
|
+
TRIO_STRING_PUBLIC int
|
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
|
+
*/
|
1993
|
+
TRIO_STRING_PUBLIC int
|
1994
|
+
trio_string_match
|
1995
|
+
TRIO_ARGS2((self, other),
|
1996
|
+
trio_string_t *self,
|
1997
|
+
trio_string_t *other)
|
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
|
+
*/
|
2011
|
+
TRIO_STRING_PUBLIC int
|
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
|
+
*/
|
2029
|
+
TRIO_STRING_PUBLIC int
|
2030
|
+
trio_string_match_case
|
2031
|
+
TRIO_ARGS2((self, other),
|
2032
|
+
trio_string_t *self,
|
2033
|
+
trio_string_t *other)
|
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
|
+
*/
|
2047
|
+
TRIO_STRING_PUBLIC int
|
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,
|
2069
|
+
trio_string_t *other)
|
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
|
+
*/
|
2101
|
+
TRIO_STRING_PUBLIC int
|
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
|
+
|
2112
|
+
/** @} End of DynamicStrings */
|