ucx/string.c

2 weeks ago

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Tue, 25 Feb 2025 21:11:00 +0100 (2 weeks ago)
changeset 102
64ded9f6a6c6
parent 101
7b3a3130be44
permissions
-rw-r--r--

update libs (ucx, toolkit, libidav)

0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1 /*
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
3 *
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
5 *
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
6 * Redistribution and use in source and binary forms, with or without
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
7 * modification, are permitted provided that the following conditions are met:
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
8 *
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
9 * 1. Redistributions of source code must retain the above copyright
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
10 * notice, this list of conditions and the following disclaimer.
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
11 *
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
12 * 2. Redistributions in binary form must reproduce the above copyright
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
13 * notice, this list of conditions and the following disclaimer in the
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
14 * documentation and/or other materials provided with the distribution.
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
15 *
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
26 * POSSIBILITY OF SUCH DAMAGE.
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
27 */
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
28 #include "cx/string.h"
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
29
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
30 #include <string.h>
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
31 #include <stdarg.h>
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
32 #include <assert.h>
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
33 #include <errno.h>
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
34 #include <limits.h>
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
35 #include <float.h>
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
36
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
37 #ifdef _WIN32
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
38 #define cx_strcasecmp_impl _strnicmp
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
39 #else
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
40 #include <strings.h>
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
41 #define cx_strcasecmp_impl strncasecmp
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
42 #endif
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
43
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
44 cxmutstr cx_mutstr(char *cstring) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
45 return (cxmutstr) {cstring, strlen(cstring)};
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
46 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
47
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
48 cxmutstr cx_mutstrn(
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
49 char *cstring,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
50 size_t length
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
51 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
52 return (cxmutstr) {cstring, length};
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
53 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
54
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
55 cxstring cx_str(const char *cstring) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
56 return (cxstring) {cstring, strlen(cstring)};
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
57 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
58
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
59 cxstring cx_strn(
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
60 const char *cstring,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
61 size_t length
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
62 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
63 return (cxstring) {cstring, length};
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
64 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
65
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
66 void cx_strfree(cxmutstr *str) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
67 if (str == NULL) return;
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
68 free(str->ptr);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
69 str->ptr = NULL;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
70 str->length = 0;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
71 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
72
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
73 void cx_strfree_a(
49
2f71f4ee247a update toolkit, ucx, libidav
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 2
diff changeset
74 const CxAllocator *alloc,
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
75 cxmutstr *str
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
76 ) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
77 if (str == NULL) return;
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
78 cxFree(alloc, str->ptr);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
79 str->ptr = NULL;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
80 str->length = 0;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
81 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
82
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
83 size_t cx_strlen(
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
84 size_t count,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
85 ...
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
86 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
87 if (count == 0) return 0;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
88
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
89 va_list ap;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
90 va_start(ap, count);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
91 size_t size = 0;
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
92 for (size_t i = 0; i < count; i++) {
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
93 cxstring str = va_arg(ap, cxstring);
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
94 if (size > SIZE_MAX - str.length) errno = EOVERFLOW;
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
95 size += str.length;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
96 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
97 va_end(ap);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
98
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
99 return size;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
100 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
101
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
102 cxmutstr cx_strcat_ma(
49
2f71f4ee247a update toolkit, ucx, libidav
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 2
diff changeset
103 const CxAllocator *alloc,
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
104 cxmutstr str,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
105 size_t count,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
106 ...
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
107 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
108 if (count == 0) return str;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
109
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
110 cxstring strings_stack[8];
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
111 cxstring *strings;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
112 if (count > 8) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
113 strings = calloc(count, sizeof(cxstring));
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
114 if (strings == NULL) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
115 return (cxmutstr) {NULL, 0};
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
116 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
117 } else {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
118 strings = strings_stack;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
119 }
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
120
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
121 va_list ap;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
122 va_start(ap, count);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
123
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
124 // get all args and overall length
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
125 bool overflow = false;
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
126 size_t slen = str.length;
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
127 for (size_t i = 0; i < count; i++) {
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
128 cxstring s = va_arg (ap, cxstring);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
129 strings[i] = s;
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
130 if (slen > SIZE_MAX - str.length) overflow = true;
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
131 slen += s.length;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
132 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
133 va_end(ap);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
134
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
135 // abort in case of overflow
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
136 if (overflow) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
137 errno = EOVERFLOW;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
138 if (strings != strings_stack) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
139 free(strings);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
140 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
141 return (cxmutstr) { NULL, 0 };
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
142 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
143
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
144 // reallocate or create new string
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
145 char *newstr;
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
146 if (str.ptr == NULL) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
147 newstr = cxMalloc(alloc, slen + 1);
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
148 } else {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
149 newstr = cxRealloc(alloc, str.ptr, slen + 1);
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
150 }
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
151 if (newstr == NULL) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
152 if (strings != strings_stack) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
153 free(strings);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
154 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
155 return (cxmutstr) {NULL, 0};
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
156 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
157 str.ptr = newstr;
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
158
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
159 // concatenate strings
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
160 size_t pos = str.length;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
161 str.length = slen;
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
162 for (size_t i = 0; i < count; i++) {
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
163 cxstring s = strings[i];
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
164 memcpy(str.ptr + pos, s.ptr, s.length);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
165 pos += s.length;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
166 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
167
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
168 // terminate string
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
169 str.ptr[str.length] = '\0';
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
170
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
171 // free temporary array
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
172 if (strings != strings_stack) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
173 free(strings);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
174 }
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
175
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
176 return str;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
177 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
178
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
179 cxstring cx_strsubs(
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
180 cxstring string,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
181 size_t start
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
182 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
183 return cx_strsubsl(string, start, string.length - start);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
184 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
185
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
186 cxmutstr cx_strsubs_m(
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
187 cxmutstr string,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
188 size_t start
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
189 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
190 return cx_strsubsl_m(string, start, string.length - start);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
191 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
192
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
193 cxstring cx_strsubsl(
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
194 cxstring string,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
195 size_t start,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
196 size_t length
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
197 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
198 if (start > string.length) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
199 return (cxstring) {NULL, 0};
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
200 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
201
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
202 size_t rem_len = string.length - start;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
203 if (length > rem_len) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
204 length = rem_len;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
205 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
206
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
207 return (cxstring) {string.ptr + start, length};
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
208 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
209
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
210 cxmutstr cx_strsubsl_m(
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
211 cxmutstr string,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
212 size_t start,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
213 size_t length
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
214 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
215 cxstring result = cx_strsubsl(cx_strcast(string), start, length);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
216 return (cxmutstr) {(char *) result.ptr, result.length};
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
217 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
218
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
219 cxstring cx_strchr(
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
220 cxstring string,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
221 int chr
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
222 ) {
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
223 char *ret = memchr(string.ptr, 0xFF & chr, string.length);
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
224 if (ret == NULL) return (cxstring) {NULL, 0};
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
225 return (cxstring) {ret, string.length - (ret - string.ptr)};
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
226 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
227
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
228 cxmutstr cx_strchr_m(
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
229 cxmutstr string,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
230 int chr
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
231 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
232 cxstring result = cx_strchr(cx_strcast(string), chr);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
233 return (cxmutstr) {(char *) result.ptr, result.length};
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
234 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
235
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
236 cxstring cx_strrchr(
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
237 cxstring string,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
238 int chr
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
239 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
240 chr = 0xFF & chr;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
241 size_t i = string.length;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
242 while (i > 0) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
243 i--;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
244 // TODO: improve by comparing multiple bytes at once
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
245 if (string.ptr[i] == chr) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
246 return cx_strsubs(string, i);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
247 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
248 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
249 return (cxstring) {NULL, 0};
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
250 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
251
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
252 cxmutstr cx_strrchr_m(
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
253 cxmutstr string,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
254 int chr
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
255 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
256 cxstring result = cx_strrchr(cx_strcast(string), chr);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
257 return (cxmutstr) {(char *) result.ptr, result.length};
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
258 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
259
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
260 #ifndef CX_STRSTR_SBO_SIZE
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
261 #define CX_STRSTR_SBO_SIZE 128
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
262 #endif
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
263 const unsigned cx_strstr_sbo_size = CX_STRSTR_SBO_SIZE;
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
264
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
265 cxstring cx_strstr(
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
266 cxstring haystack,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
267 cxstring needle
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
268 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
269 if (needle.length == 0) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
270 return haystack;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
271 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
272
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
273 // optimize for single-char needles
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
274 if (needle.length == 1) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
275 return cx_strchr(haystack, *needle.ptr);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
276 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
277
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
278 /*
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
279 * IMPORTANT:
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
280 * Our prefix table contains the prefix length PLUS ONE
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
281 * this is our decision, because we want to use the full range of size_t.
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
282 * The original algorithm needs a (-1) at one single place,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
283 * and we want to avoid that.
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
284 */
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
285
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
286 // local prefix table
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
287 size_t s_prefix_table[CX_STRSTR_SBO_SIZE];
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
288
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
289 // check needle length and use appropriate prefix table
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
290 // if the pattern exceeds static prefix table, allocate on the heap
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
291 const bool useheap = needle.length >= CX_STRSTR_SBO_SIZE;
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
292 register size_t *ptable = useheap ? calloc(needle.length + 1,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
293 sizeof(size_t)) : s_prefix_table;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
294
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
295 // keep counter in registers
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
296 register size_t i, j;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
297
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
298 // fill prefix table
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
299 i = 0;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
300 j = 0;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
301 ptable[i] = j;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
302 while (i < needle.length) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
303 while (j >= 1 && needle.ptr[j - 1] != needle.ptr[i]) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
304 j = ptable[j - 1];
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
305 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
306 i++;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
307 j++;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
308 ptable[i] = j;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
309 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
310
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
311 // search
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
312 cxstring result = {NULL, 0};
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
313 i = 0;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
314 j = 1;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
315 while (i < haystack.length) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
316 while (j >= 1 && haystack.ptr[i] != needle.ptr[j - 1]) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
317 j = ptable[j - 1];
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
318 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
319 i++;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
320 j++;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
321 if (j - 1 == needle.length) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
322 size_t start = i - needle.length;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
323 result.ptr = haystack.ptr + start;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
324 result.length = haystack.length - start;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
325 break;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
326 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
327 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
328
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
329 // if prefix table was allocated on the heap, free it
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
330 if (useheap) {
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
331 free(ptable);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
332 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
333
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
334 return result;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
335 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
336
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
337 cxmutstr cx_strstr_m(
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
338 cxmutstr haystack,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
339 cxstring needle
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
340 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
341 cxstring result = cx_strstr(cx_strcast(haystack), needle);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
342 return (cxmutstr) {(char *) result.ptr, result.length};
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
343 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
344
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
345 size_t cx_strsplit(
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
346 cxstring string,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
347 cxstring delim,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
348 size_t limit,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
349 cxstring *output
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
350 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
351 // special case: output limit is zero
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
352 if (limit == 0) return 0;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
353
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
354 // special case: delimiter is empty
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
355 if (delim.length == 0) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
356 output[0] = string;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
357 return 1;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
358 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
359
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
360 // special cases: delimiter is at least as large as the string
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
361 if (delim.length >= string.length) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
362 // exact match
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
363 if (cx_strcmp(string, delim) == 0) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
364 output[0] = cx_strn(string.ptr, 0);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
365 output[1] = cx_strn(string.ptr + string.length, 0);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
366 return 2;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
367 } else {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
368 // no match possible
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
369 output[0] = string;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
370 return 1;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
371 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
372 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
373
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
374 size_t n = 0;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
375 cxstring curpos = string;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
376 while (1) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
377 ++n;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
378 cxstring match = cx_strstr(curpos, delim);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
379 if (match.length > 0) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
380 // is the limit reached?
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
381 if (n < limit) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
382 // copy the current string to the array
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
383 cxstring item = cx_strn(curpos.ptr, match.ptr - curpos.ptr);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
384 output[n - 1] = item;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
385 size_t processed = item.length + delim.length;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
386 curpos.ptr += processed;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
387 curpos.length -= processed;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
388 } else {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
389 // limit reached, copy the _full_ remaining string
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
390 output[n - 1] = curpos;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
391 break;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
392 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
393 } else {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
394 // no more matches, copy last string
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
395 output[n - 1] = curpos;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
396 break;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
397 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
398 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
399
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
400 return n;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
401 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
402
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
403 size_t cx_strsplit_a(
49
2f71f4ee247a update toolkit, ucx, libidav
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 2
diff changeset
404 const CxAllocator *allocator,
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
405 cxstring string,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
406 cxstring delim,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
407 size_t limit,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
408 cxstring **output
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
409 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
410 // find out how many splits we're going to make and allocate memory
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
411 size_t n = 0;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
412 cxstring curpos = string;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
413 while (1) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
414 ++n;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
415 cxstring match = cx_strstr(curpos, delim);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
416 if (match.length > 0) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
417 // is the limit reached?
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
418 if (n < limit) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
419 size_t processed = match.ptr - curpos.ptr + delim.length;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
420 curpos.ptr += processed;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
421 curpos.length -= processed;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
422 } else {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
423 // limit reached
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
424 break;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
425 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
426 } else {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
427 // no more matches
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
428 break;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
429 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
430 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
431 *output = cxCalloc(allocator, n, sizeof(cxstring));
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
432 return cx_strsplit(string, delim, n, *output);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
433 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
434
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
435 size_t cx_strsplit_m(
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
436 cxmutstr string,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
437 cxstring delim,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
438 size_t limit,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
439 cxmutstr *output
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
440 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
441 return cx_strsplit(cx_strcast(string),
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
442 delim, limit, (cxstring *) output);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
443 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
444
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
445 size_t cx_strsplit_ma(
49
2f71f4ee247a update toolkit, ucx, libidav
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 2
diff changeset
446 const CxAllocator *allocator,
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
447 cxmutstr string,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
448 cxstring delim,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
449 size_t limit,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
450 cxmutstr **output
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
451 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
452 return cx_strsplit_a(allocator, cx_strcast(string),
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
453 delim, limit, (cxstring **) output);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
454 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
455
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
456 int cx_strcmp(
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
457 cxstring s1,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
458 cxstring s2
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
459 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
460 if (s1.length == s2.length) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
461 return strncmp(s1.ptr, s2.ptr, s1.length);
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
462 } else if (s1.length > s2.length) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
463 int r = strncmp(s1.ptr, s2.ptr, s2.length);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
464 if (r != 0) return r;
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
465 return 1;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
466 } else {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
467 int r = strncmp(s1.ptr, s2.ptr, s1.length);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
468 if (r != 0) return r;
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
469 return -1;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
470 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
471 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
472
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
473 int cx_strcasecmp(
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
474 cxstring s1,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
475 cxstring s2
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
476 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
477 if (s1.length == s2.length) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
478 return cx_strcasecmp_impl(s1.ptr, s2.ptr, s1.length);
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
479 } else if (s1.length > s2.length) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
480 int r = cx_strcasecmp_impl(s1.ptr, s2.ptr, s2.length);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
481 if (r != 0) return r;
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
482 return 1;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
483 } else {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
484 int r = cx_strcasecmp_impl(s1.ptr, s2.ptr, s1.length);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
485 if (r != 0) return r;
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
486 return -1;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
487 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
488 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
489
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
490 int cx_strcmp_p(
49
2f71f4ee247a update toolkit, ucx, libidav
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 2
diff changeset
491 const void *s1,
2f71f4ee247a update toolkit, ucx, libidav
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 2
diff changeset
492 const void *s2
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
493 ) {
49
2f71f4ee247a update toolkit, ucx, libidav
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 2
diff changeset
494 const cxstring *left = s1;
2f71f4ee247a update toolkit, ucx, libidav
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 2
diff changeset
495 const cxstring *right = s2;
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
496 return cx_strcmp(*left, *right);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
497 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
498
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
499 int cx_strcasecmp_p(
49
2f71f4ee247a update toolkit, ucx, libidav
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 2
diff changeset
500 const void *s1,
2f71f4ee247a update toolkit, ucx, libidav
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 2
diff changeset
501 const void *s2
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
502 ) {
49
2f71f4ee247a update toolkit, ucx, libidav
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 2
diff changeset
503 const cxstring *left = s1;
2f71f4ee247a update toolkit, ucx, libidav
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 2
diff changeset
504 const cxstring *right = s2;
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
505 return cx_strcasecmp(*left, *right);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
506 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
507
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
508 cxmutstr cx_strdup_a_(
49
2f71f4ee247a update toolkit, ucx, libidav
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 2
diff changeset
509 const CxAllocator *allocator,
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
510 cxstring string
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
511 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
512 cxmutstr result = {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
513 cxMalloc(allocator, string.length + 1),
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
514 string.length
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
515 };
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
516 if (result.ptr == NULL) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
517 result.length = 0;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
518 return result;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
519 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
520 memcpy(result.ptr, string.ptr, string.length);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
521 result.ptr[string.length] = '\0';
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
522 return result;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
523 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
524
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
525 static bool str_isspace(char c) {
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
526 // TODO: remove once UCX has public API for this
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
527 return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\v' || c == '\f';
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
528 }
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
529
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
530 cxstring cx_strtrim(cxstring string) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
531 cxstring result = string;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
532 // TODO: optimize by comparing multiple bytes at once
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
533 while (result.length > 0 && str_isspace(*result.ptr)) {
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
534 result.ptr++;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
535 result.length--;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
536 }
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
537 while (result.length > 0 && str_isspace(result.ptr[result.length - 1])) {
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
538 result.length--;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
539 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
540 return result;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
541 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
542
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
543 cxmutstr cx_strtrim_m(cxmutstr string) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
544 cxstring result = cx_strtrim(cx_strcast(string));
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
545 return (cxmutstr) {(char *) result.ptr, result.length};
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
546 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
547
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
548 bool cx_strprefix(
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
549 cxstring string,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
550 cxstring prefix
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
551 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
552 if (string.length < prefix.length) return false;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
553 return memcmp(string.ptr, prefix.ptr, prefix.length) == 0;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
554 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
555
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
556 bool cx_strsuffix(
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
557 cxstring string,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
558 cxstring suffix
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
559 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
560 if (string.length < suffix.length) return false;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
561 return memcmp(string.ptr + string.length - suffix.length,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
562 suffix.ptr, suffix.length) == 0;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
563 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
564
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
565 bool cx_strcaseprefix(
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
566 cxstring string,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
567 cxstring prefix
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
568 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
569 if (string.length < prefix.length) return false;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
570 #ifdef _WIN32
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
571 return _strnicmp(string.ptr, prefix.ptr, prefix.length) == 0;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
572 #else
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
573 return strncasecmp(string.ptr, prefix.ptr, prefix.length) == 0;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
574 #endif
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
575 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
576
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
577 bool cx_strcasesuffix(
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
578 cxstring string,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
579 cxstring suffix
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
580 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
581 if (string.length < suffix.length) return false;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
582 #ifdef _WIN32
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
583 return _strnicmp(string.ptr+string.length-suffix.length,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
584 suffix.ptr, suffix.length) == 0;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
585 #else
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
586 return strncasecmp(string.ptr + string.length - suffix.length,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
587 suffix.ptr, suffix.length) == 0;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
588 #endif
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
589 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
590
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
591 #ifndef CX_STRREPLACE_INDEX_BUFFER_SIZE
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
592 #define CX_STRREPLACE_INDEX_BUFFER_SIZE 64
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
593 #endif
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
594
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
595 struct cx_strreplace_ibuf {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
596 size_t *buf;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
597 struct cx_strreplace_ibuf *next;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
598 unsigned int len;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
599 };
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
600
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
601 static void cx_strrepl_free_ibuf(struct cx_strreplace_ibuf *buf) {
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
602 // remember, the first data is on the stack!
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
603 buf = buf->next;
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
604 while (buf) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
605 struct cx_strreplace_ibuf *next = buf->next;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
606 free(buf->buf);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
607 free(buf);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
608 buf = next;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
609 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
610 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
611
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
612 cxmutstr cx_strreplacen_a(
49
2f71f4ee247a update toolkit, ucx, libidav
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 2
diff changeset
613 const CxAllocator *allocator,
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
614 cxstring str,
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
615 cxstring search,
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
616 cxstring replacement,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
617 size_t replmax
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
618 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
619
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
620 if (search.length == 0 || search.length > str.length || replmax == 0)
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
621 return cx_strdup_a(allocator, str);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
622
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
623 // Compute expected buffer length
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
624 size_t ibufmax = str.length / search.length;
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
625 size_t ibuflen = replmax < ibufmax ? replmax : ibufmax;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
626 if (ibuflen > CX_STRREPLACE_INDEX_BUFFER_SIZE) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
627 ibuflen = CX_STRREPLACE_INDEX_BUFFER_SIZE;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
628 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
629
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
630 // First index buffer can be on the stack
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
631 struct cx_strreplace_ibuf ibuf, *curbuf = &ibuf;
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
632 size_t ibuf_sbo[CX_STRREPLACE_INDEX_BUFFER_SIZE];
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
633 ibuf.buf = ibuf_sbo;
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
634 ibuf.next = NULL;
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
635 ibuf.len = 0;
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
636
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
637 // Search occurrences
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
638 cxstring searchstr = str;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
639 size_t found = 0;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
640 do {
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
641 cxstring match = cx_strstr(searchstr, search);
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
642 if (match.length > 0) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
643 // Allocate next buffer in chain, if required
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
644 if (curbuf->len == ibuflen) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
645 struct cx_strreplace_ibuf *nextbuf =
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
646 calloc(1, sizeof(struct cx_strreplace_ibuf));
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
647 if (!nextbuf) {
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
648 cx_strrepl_free_ibuf(&ibuf);
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
649 return cx_mutstrn(NULL, 0);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
650 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
651 nextbuf->buf = calloc(ibuflen, sizeof(size_t));
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
652 if (!nextbuf->buf) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
653 free(nextbuf);
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
654 cx_strrepl_free_ibuf(&ibuf);
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
655 return cx_mutstrn(NULL, 0);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
656 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
657 curbuf->next = nextbuf;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
658 curbuf = nextbuf;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
659 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
660
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
661 // Record match index
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
662 found++;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
663 size_t idx = match.ptr - str.ptr;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
664 curbuf->buf[curbuf->len++] = idx;
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
665 searchstr.ptr = match.ptr + search.length;
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
666 searchstr.length = str.length - idx - search.length;
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
667 } else {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
668 break;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
669 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
670 } while (searchstr.length > 0 && found < replmax);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
671
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
672 // Allocate result string
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
673 cxmutstr result;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
674 {
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
675 long long adjlen = (long long) replacement.length - (long long) search.length;
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
676 size_t rcount = 0;
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
677 curbuf = &ibuf;
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
678 do {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
679 rcount += curbuf->len;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
680 curbuf = curbuf->next;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
681 } while (curbuf);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
682 result.length = str.length + rcount * adjlen;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
683 result.ptr = cxMalloc(allocator, result.length + 1);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
684 if (!result.ptr) {
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
685 cx_strrepl_free_ibuf(&ibuf);
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
686 return cx_mutstrn(NULL, 0);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
687 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
688 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
689
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
690 // Build result string
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
691 curbuf = &ibuf;
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
692 size_t srcidx = 0;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
693 char *destptr = result.ptr;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
694 do {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
695 for (size_t i = 0; i < curbuf->len; i++) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
696 // Copy source part up to next match
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
697 size_t idx = curbuf->buf[i];
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
698 size_t srclen = idx - srcidx;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
699 if (srclen > 0) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
700 memcpy(destptr, str.ptr + srcidx, srclen);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
701 destptr += srclen;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
702 srcidx += srclen;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
703 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
704
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
705 // Copy the replacement and skip the source pattern
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
706 srcidx += search.length;
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
707 memcpy(destptr, replacement.ptr, replacement.length);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
708 destptr += replacement.length;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
709 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
710 curbuf = curbuf->next;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
711 } while (curbuf);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
712 memcpy(destptr, str.ptr + srcidx, str.length - srcidx);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
713
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
714 // Result is guaranteed to be zero-terminated
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
715 result.ptr[result.length] = '\0';
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
716
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
717 // Free index buffer
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
718 cx_strrepl_free_ibuf(&ibuf);
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
719
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
720 return result;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
721 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
722
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
723 CxStrtokCtx cx_strtok_(
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
724 cxstring str,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
725 cxstring delim,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
726 size_t limit
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
727 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
728 CxStrtokCtx ctx;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
729 ctx.str = str;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
730 ctx.delim = delim;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
731 ctx.limit = limit;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
732 ctx.pos = 0;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
733 ctx.next_pos = 0;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
734 ctx.delim_pos = 0;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
735 ctx.found = 0;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
736 ctx.delim_more = NULL;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
737 ctx.delim_more_count = 0;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
738 return ctx;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
739 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
740
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
741 bool cx_strtok_next(
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
742 CxStrtokCtx *ctx,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
743 cxstring *token
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
744 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
745 // abortion criteria
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
746 if (ctx->found >= ctx->limit || ctx->delim_pos >= ctx->str.length) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
747 return false;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
748 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
749
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
750 // determine the search start
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
751 cxstring haystack = cx_strsubs(ctx->str, ctx->next_pos);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
752
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
753 // search the next delimiter
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
754 cxstring delim = cx_strstr(haystack, ctx->delim);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
755
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
756 // if found, make delim capture exactly the delimiter
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
757 if (delim.length > 0) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
758 delim.length = ctx->delim.length;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
759 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
760
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
761 // if more delimiters are specified, check them now
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
762 if (ctx->delim_more_count > 0) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
763 for (size_t i = 0; i < ctx->delim_more_count; i++) {
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
764 cxstring d = cx_strstr(haystack, ctx->delim_more[i]);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
765 if (d.length > 0 && (delim.length == 0 || d.ptr < delim.ptr)) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
766 delim.ptr = d.ptr;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
767 delim.length = ctx->delim_more[i].length;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
768 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
769 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
770 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
771
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
772 // store the token information and adjust the context
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
773 ctx->found++;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
774 ctx->pos = ctx->next_pos;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
775 token->ptr = &ctx->str.ptr[ctx->pos];
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
776 ctx->delim_pos = delim.length == 0 ?
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
777 ctx->str.length : (size_t) (delim.ptr - ctx->str.ptr);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
778 token->length = ctx->delim_pos - ctx->pos;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
779 ctx->next_pos = ctx->delim_pos + delim.length;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
780
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
781 return true;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
782 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
783
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
784 bool cx_strtok_next_m(
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
785 CxStrtokCtx *ctx,
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
786 cxmutstr *token
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
787 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
788 return cx_strtok_next(ctx, (cxstring *) token);
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
789 }
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
790
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
791 void cx_strtok_delim(
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
792 CxStrtokCtx *ctx,
49
2f71f4ee247a update toolkit, ucx, libidav
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 2
diff changeset
793 const cxstring *delim,
0
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
794 size_t count
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
795 ) {
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
796 ctx->delim_more = delim;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
797 ctx->delim_more_count = count;
2483f517c562 add existing toolkit code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
798 }
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
799
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
800 #define cx_strtoX_signed_impl(rtype, rmin, rmax) \
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
801 long long result; \
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
802 if (cx_strtoll_lc(str, &result, base, groupsep)) { \
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
803 return -1; \
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
804 } \
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
805 if (result < rmin || result > rmax) { \
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
806 errno = ERANGE; \
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
807 return -1; \
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
808 } \
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
809 *output = (rtype) result; \
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
810 return 0
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
811
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
812 int cx_strtos_lc_(cxstring str, short *output, int base, const char *groupsep) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
813 cx_strtoX_signed_impl(short, SHRT_MIN, SHRT_MAX);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
814 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
815
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
816 int cx_strtoi_lc_(cxstring str, int *output, int base, const char *groupsep) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
817 cx_strtoX_signed_impl(int, INT_MIN, INT_MAX);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
818 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
819
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
820 int cx_strtol_lc_(cxstring str, long *output, int base, const char *groupsep) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
821 cx_strtoX_signed_impl(long, LONG_MIN, LONG_MAX);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
822 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
823
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
824 int cx_strtoll_lc_(cxstring str, long long *output, int base, const char *groupsep) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
825 // strategy: parse as unsigned, check range, negate if required
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
826 bool neg = false;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
827 size_t start_unsigned = 0;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
828
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
829 // emptiness check
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
830 if (str.length == 0) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
831 errno = EINVAL;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
832 return -1;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
833 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
834
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
835 // test if we have a negative sign character
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
836 if (str.ptr[start_unsigned] == '-') {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
837 neg = true;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
838 start_unsigned++;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
839 // must not be followed by positive sign character
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
840 if (str.length == 1 || str.ptr[start_unsigned] == '+') {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
841 errno = EINVAL;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
842 return -1;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
843 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
844 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
845
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
846 // now parse the number with strtoull
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
847 unsigned long long v;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
848 cxstring ustr = start_unsigned == 0 ? str
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
849 : cx_strn(str.ptr + start_unsigned, str.length - start_unsigned);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
850 int ret = cx_strtoull_lc(ustr, &v, base, groupsep);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
851 if (ret != 0) return ret;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
852 if (neg) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
853 if (v - 1 > LLONG_MAX) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
854 errno = ERANGE;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
855 return -1;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
856 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
857 *output = -(long long) v;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
858 return 0;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
859 } else {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
860 if (v > LLONG_MAX) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
861 errno = ERANGE;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
862 return -1;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
863 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
864 *output = (long long) v;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
865 return 0;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
866 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
867 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
868
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
869 int cx_strtoi8_lc_(cxstring str, int8_t *output, int base, const char *groupsep) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
870 cx_strtoX_signed_impl(int8_t, INT8_MIN, INT8_MAX);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
871 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
872
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
873 int cx_strtoi16_lc_(cxstring str, int16_t *output, int base, const char *groupsep) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
874 cx_strtoX_signed_impl(int16_t, INT16_MIN, INT16_MAX);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
875 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
876
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
877 int cx_strtoi32_lc_(cxstring str, int32_t *output, int base, const char *groupsep) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
878 cx_strtoX_signed_impl(int32_t, INT32_MIN, INT32_MAX);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
879 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
880
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
881 int cx_strtoi64_lc_(cxstring str, int64_t *output, int base, const char *groupsep) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
882 assert(sizeof(long long) == sizeof(int64_t)); // should be true on all platforms
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
883 return cx_strtoll_lc(str, (long long*) output, base, groupsep);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
884 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
885
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
886 #define cx_strtoX_unsigned_impl(rtype, rmax) \
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
887 uint64_t result; \
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
888 if (cx_strtou64_lc(str, &result, base, groupsep)) { \
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
889 return -1; \
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
890 } \
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
891 if (result > rmax) { \
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
892 errno = ERANGE; \
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
893 return -1; \
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
894 } \
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
895 *output = (rtype) result; \
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
896 return 0
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
897
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
898 int cx_strtous_lc_(cxstring str, unsigned short *output, int base, const char *groupsep) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
899 cx_strtoX_unsigned_impl(unsigned short, USHRT_MAX);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
900 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
901
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
902 int cx_strtou_lc_(cxstring str, unsigned int *output, int base, const char *groupsep) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
903 cx_strtoX_unsigned_impl(unsigned int, UINT_MAX);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
904 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
905
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
906 int cx_strtoul_lc_(cxstring str, unsigned long *output, int base, const char *groupsep) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
907 cx_strtoX_unsigned_impl(unsigned long, ULONG_MAX);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
908 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
909
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
910 int cx_strtoull_lc_(cxstring str, unsigned long long *output, int base, const char *groupsep) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
911 // some sanity checks
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
912 if (str.length == 0) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
913 errno = EINVAL;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
914 return -1;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
915 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
916 if (!(base == 2 || base == 8 || base == 10 || base == 16)) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
917 errno = EINVAL;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
918 return -1;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
919 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
920 if (groupsep == NULL) groupsep = "";
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
921
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
922 // find the actual start of the number
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
923 if (str.ptr[0] == '+') {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
924 str.ptr++;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
925 str.length--;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
926 if (str.length == 0) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
927 errno = EINVAL;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
928 return -1;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
929 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
930 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
931 size_t start = 0;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
932
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
933 // if base is 2 or 16, some leading stuff may appear
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
934 if (base == 2) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
935 if ((str.ptr[0] | 32) == 'b') {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
936 start = 1;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
937 } else if (str.ptr[0] == '0' && str.length > 1) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
938 if ((str.ptr[1] | 32) == 'b') {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
939 start = 2;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
940 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
941 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
942 } else if (base == 16) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
943 if ((str.ptr[0] | 32) == 'x' || str.ptr[0] == '#') {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
944 start = 1;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
945 } else if (str.ptr[0] == '0' && str.length > 1) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
946 if ((str.ptr[1] | 32) == 'x') {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
947 start = 2;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
948 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
949 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
950 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
951
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
952 // check if there are digits left
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
953 if (start >= str.length) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
954 errno = EINVAL;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
955 return -1;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
956 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
957
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
958 // now parse the number
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
959 unsigned long long result = 0;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
960 for (size_t i = start; i < str.length; i++) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
961 // ignore group separators
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
962 if (strchr(groupsep, str.ptr[i])) continue;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
963
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
964 // determine the digit value of the character
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
965 unsigned char c = str.ptr[i];
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
966 if (c >= 'a') c = 10 + (c - 'a');
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
967 else if (c >= 'A') c = 10 + (c - 'A');
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
968 else if (c >= '0') c = c - '0';
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
969 else c = 255;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
970 if (c >= base) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
971 errno = EINVAL;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
972 return -1;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
973 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
974
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
975 // now combine the digit with what we already have
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
976 unsigned long right = (result & 0xff) * base + c;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
977 unsigned long long left = (result >> 8) * base + (right >> 8);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
978 if (left > (ULLONG_MAX >> 8)) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
979 errno = ERANGE;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
980 return -1;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
981 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
982 result = (left << 8) + (right & 0xff);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
983 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
984
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
985 *output = result;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
986 return 0;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
987 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
988
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
989 int cx_strtou8_lc_(cxstring str, uint8_t *output, int base, const char *groupsep) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
990 cx_strtoX_unsigned_impl(uint8_t, UINT8_MAX);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
991 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
992
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
993 int cx_strtou16_lc_(cxstring str, uint16_t *output, int base, const char *groupsep) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
994 cx_strtoX_unsigned_impl(uint16_t, UINT16_MAX);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
995 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
996
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
997 int cx_strtou32_lc_(cxstring str, uint32_t *output, int base, const char *groupsep) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
998 cx_strtoX_unsigned_impl(uint32_t, UINT32_MAX);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
999 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1000
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
1001 int cx_strtou64_lc_(cxstring str, uint64_t *output, int base, const char *groupsep) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1002 assert(sizeof(unsigned long long) == sizeof(uint64_t)); // should be true on all platforms
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1003 return cx_strtoull_lc(str, (unsigned long long*) output, base, groupsep);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1004 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1005
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
1006 int cx_strtoz_lc_(cxstring str, size_t *output, int base, const char *groupsep) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1007 #if SIZE_MAX == UINT32_MAX
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
1008 return cx_strtou32_lc_(str, (uint32_t*) output, base, groupsep);
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1009 #elif SIZE_MAX == UINT64_MAX
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
1010 return cx_strtoull_lc_(str, (unsigned long long *) output, base, groupsep);
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1011 #else
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1012 #error "unsupported size_t size"
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1013 #endif
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1014 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1015
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
1016 int cx_strtof_lc_(cxstring str, float *output, char decsep, const char *groupsep) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1017 // use string to double and add a range check
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1018 double d;
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
1019 int ret = cx_strtod_lc_(str, &d, decsep, groupsep);
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1020 if (ret != 0) return ret;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1021 // note: FLT_MIN is the smallest POSITIVE number that can be represented
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1022 double test = d < 0 ? -d : d;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1023 if (test < FLT_MIN || test > FLT_MAX) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1024 errno = ERANGE;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1025 return -1;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1026 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1027 *output = (float) d;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1028 return 0;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1029 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1030
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
1031 static bool str_isdigit(char c) {
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
1032 // TODO: remove once UCX has public API for this
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
1033 return c >= '0' && c <= '9';
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
1034 }
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
1035
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
1036 int cx_strtod_lc_(cxstring str, double *output, char decsep, const char *groupsep) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1037 // TODO: overflow check
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1038 // TODO: increase precision
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1039
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
1040 // emptiness check
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1041 if (str.length == 0) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1042 errno = EINVAL;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1043 return -1;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1044 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1045
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1046 double result = 0.;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1047 int sign = 1;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1048
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1049 // check if there is a sign
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1050 if (str.ptr[0] == '-') {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1051 sign = -1;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1052 str.ptr++;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1053 str.length--;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1054 } else if (str.ptr[0] == '+') {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1055 str.ptr++;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1056 str.length--;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1057 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1058
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1059 // there must be at least one char to parse
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1060 if (str.length == 0) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1061 errno = EINVAL;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1062 return -1;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1063 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1064
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1065 // parse all digits until we find the decsep
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1066 size_t pos = 0;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1067 do {
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
1068 if (str_isdigit(str.ptr[pos])) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1069 result = result * 10 + (str.ptr[pos] - '0');
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1070 } else if (strchr(groupsep, str.ptr[pos]) == NULL) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1071 break;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1072 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1073 } while (++pos < str.length);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1074
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1075 // already done?
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1076 if (pos == str.length) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1077 *output = result * sign;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1078 return 0;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1079 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1080
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1081 // is the next char the decsep?
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1082 if (str.ptr[pos] == decsep) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1083 pos++;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1084 // it may end with the decsep, if it did not start with it
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1085 if (pos == str.length) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1086 if (str.length == 1) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1087 errno = EINVAL;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1088 return -1;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1089 } else {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1090 *output = result * sign;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1091 return 0;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1092 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1093 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1094 // parse everything until exponent or end
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1095 double factor = 1.;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1096 do {
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
1097 if (str_isdigit(str.ptr[pos])) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1098 factor *= 0.1;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1099 result = result + factor * (str.ptr[pos] - '0');
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1100 } else if (strchr(groupsep, str.ptr[pos]) == NULL) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1101 break;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1102 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1103 } while (++pos < str.length);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1104 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1105
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1106 // no exponent?
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1107 if (pos == str.length) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1108 *output = result * sign;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1109 return 0;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1110 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1111
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1112 // now the next separator MUST be the exponent separator
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1113 // and at least one char must follow
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1114 if ((str.ptr[pos] | 32) != 'e' || str.length <= pos + 1) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1115 errno = EINVAL;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1116 return -1;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1117 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1118 pos++;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1119
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1120 // check if we have a sign for the exponent
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1121 double factor = 10.;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1122 if (str.ptr[pos] == '-') {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1123 factor = .1;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1124 pos++;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1125 } else if (str.ptr[pos] == '+') {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1126 pos++;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1127 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1128
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1129 // at least one digit must follow
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1130 if (pos == str.length) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1131 errno = EINVAL;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1132 return -1;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1133 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1134
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1135 // parse the exponent
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1136 unsigned int exp = 0;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1137 do {
102
64ded9f6a6c6 update libs (ucx, toolkit, libidav)
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 101
diff changeset
1138 if (str_isdigit(str.ptr[pos])) {
101
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1139 exp = 10 * exp + (str.ptr[pos] - '0');
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1140 } else if (strchr(groupsep, str.ptr[pos]) == NULL) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1141 errno = EINVAL;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1142 return -1;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1143 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1144 } while (++pos < str.length);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1145
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1146 // apply the exponent by fast exponentiation
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1147 do {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1148 if (exp & 1) {
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1149 result *= factor;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1150 }
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1151 factor *= factor;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1152 } while ((exp >>= 1) > 0);
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1153
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1154 // store the result and exit
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1155 *output = result * sign;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1156 return 0;
7b3a3130be44 update ucx, toolkit
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 49
diff changeset
1157 }

mercurial