src/string.c

Sun, 14 Jan 2024 13:50:17 +0100

author
Mike Becker <universe@uap-core.de>
date
Sun, 14 Jan 2024 13:50:17 +0100
changeset 806
e06249e09f99
parent 697
ebdce4bf262b
child 890
54565fd74e74
permissions
-rw-r--r--

add constant for reading out strstr sbo size - relates to #343

also fixes the related test which was working with the old SBO size of 256 and was broken after increasing it to 512

576
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
1 /*
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
3 *
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
5 *
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
6 * Redistribution and use in source and binary forms, with or without
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
7 * modification, are permitted provided that the following conditions are met:
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
8 *
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
9 * 1. Redistributions of source code must retain the above copyright
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
10 * notice, this list of conditions and the following disclaimer.
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
11 *
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
12 * 2. Redistributions in binary form must reproduce the above copyright
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
13 * notice, this list of conditions and the following disclaimer in the
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
14 * documentation and/or other materials provided with the distribution.
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
15 *
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
26 * POSSIBILITY OF SUCH DAMAGE.
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
27 */
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
28
ba0c4ff6698e first proposal for the string header
Mike Becker <universe@uap-core.de>
parents:
diff changeset
29 #include "cx/string.h"
579
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
30 #include "cx/utils.h"
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
31
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
32 #include <string.h>
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
33 #include <stdarg.h>
581
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
34 #include <ctype.h>
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
35
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
36 #ifndef _WIN32
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
37
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
38 #include <strings.h> // for strncasecmp()
581
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
39
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
40 #endif // _WIN32
579
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
41
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
42 cxmutstr cx_mutstr(char *cstring) {
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
43 return (cxmutstr) {cstring, strlen(cstring)};
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
44 }
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
45
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
46 cxmutstr cx_mutstrn(
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
47 char *cstring,
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
48 size_t length
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
49 ) {
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
50 return (cxmutstr) {cstring, length};
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
51 }
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
52
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
53 cxstring cx_str(const char *cstring) {
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
54 return (cxstring) {cstring, strlen(cstring)};
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
55 }
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
56
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
57 cxstring cx_strn(
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
58 const char *cstring,
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
59 size_t length
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
60 ) {
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
61 return (cxstring) {cstring, length};
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
62 }
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
63
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
64 cxstring cx_strcast(cxmutstr str) {
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
65 return (cxstring) {str.ptr, str.length};
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
66 }
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
67
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
68 void cx_strfree(cxmutstr *str) {
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
69 free(str->ptr);
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
70 str->ptr = NULL;
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
71 str->length = 0;
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
72 }
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
73
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
74 void cx_strfree_a(
693
494d9b20b99e fix missing const qualifier for allocator
Mike Becker <universe@uap-core.de>
parents: 657
diff changeset
75 CxAllocator const *alloc,
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
76 cxmutstr *str
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
77 ) {
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
78 cxFree(alloc, str->ptr);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
79 str->ptr = NULL;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
80 str->length = 0;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
81 }
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
82
579
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
83 size_t cx_strlen(
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
84 size_t count,
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
85 ...
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
86 ) {
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
87 if (count == 0) return 0;
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
88
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
89 va_list ap;
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
90 va_start(ap, count);
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
91 size_t size = 0;
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
92 cx_for_n(i, count) {
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
93 cxstring str = va_arg(ap, cxstring);
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
94 size += str.length;
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
95 }
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
96 va_end(ap);
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
97
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
98 return size;
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
99 }
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
100
697
ebdce4bf262b add cx_strcat_m() and cx_strcat_ma() for in-place concatenation
Mike Becker <universe@uap-core.de>
parents: 693
diff changeset
101 cxmutstr cx_strcat_ma(
693
494d9b20b99e fix missing const qualifier for allocator
Mike Becker <universe@uap-core.de>
parents: 657
diff changeset
102 CxAllocator const *alloc,
697
ebdce4bf262b add cx_strcat_m() and cx_strcat_ma() for in-place concatenation
Mike Becker <universe@uap-core.de>
parents: 693
diff changeset
103 cxmutstr str,
579
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
104 size_t count,
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
105 ...
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
106 ) {
697
ebdce4bf262b add cx_strcat_m() and cx_strcat_ma() for in-place concatenation
Mike Becker <universe@uap-core.de>
parents: 693
diff changeset
107 if (count == 0) return str;
ebdce4bf262b add cx_strcat_m() and cx_strcat_ma() for in-place concatenation
Mike Becker <universe@uap-core.de>
parents: 693
diff changeset
108
579
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
109 cxstring *strings = calloc(count, sizeof(cxstring));
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
110 if (!strings) abort();
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
111
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
112 va_list ap;
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
113 va_start(ap, count);
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
114
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
115 // get all args and overall length
697
ebdce4bf262b add cx_strcat_m() and cx_strcat_ma() for in-place concatenation
Mike Becker <universe@uap-core.de>
parents: 693
diff changeset
116 size_t slen = str.length;
579
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
117 cx_for_n(i, count) {
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
118 cxstring s = va_arg (ap, cxstring);
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
119 strings[i] = s;
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
120 slen += s.length;
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
121 }
697
ebdce4bf262b add cx_strcat_m() and cx_strcat_ma() for in-place concatenation
Mike Becker <universe@uap-core.de>
parents: 693
diff changeset
122 va_end(ap);
579
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
123
697
ebdce4bf262b add cx_strcat_m() and cx_strcat_ma() for in-place concatenation
Mike Becker <universe@uap-core.de>
parents: 693
diff changeset
124 // reallocate or create new string
ebdce4bf262b add cx_strcat_m() and cx_strcat_ma() for in-place concatenation
Mike Becker <universe@uap-core.de>
parents: 693
diff changeset
125 if (str.ptr == NULL) {
ebdce4bf262b add cx_strcat_m() and cx_strcat_ma() for in-place concatenation
Mike Becker <universe@uap-core.de>
parents: 693
diff changeset
126 str.ptr = cxMalloc(alloc, slen + 1);
ebdce4bf262b add cx_strcat_m() and cx_strcat_ma() for in-place concatenation
Mike Becker <universe@uap-core.de>
parents: 693
diff changeset
127 } else {
ebdce4bf262b add cx_strcat_m() and cx_strcat_ma() for in-place concatenation
Mike Becker <universe@uap-core.de>
parents: 693
diff changeset
128 str.ptr = cxRealloc(alloc, str.ptr, slen + 1);
ebdce4bf262b add cx_strcat_m() and cx_strcat_ma() for in-place concatenation
Mike Becker <universe@uap-core.de>
parents: 693
diff changeset
129 }
ebdce4bf262b add cx_strcat_m() and cx_strcat_ma() for in-place concatenation
Mike Becker <universe@uap-core.de>
parents: 693
diff changeset
130 if (str.ptr == NULL) abort();
579
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
131
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
132 // concatenate strings
697
ebdce4bf262b add cx_strcat_m() and cx_strcat_ma() for in-place concatenation
Mike Becker <universe@uap-core.de>
parents: 693
diff changeset
133 size_t pos = str.length;
ebdce4bf262b add cx_strcat_m() and cx_strcat_ma() for in-place concatenation
Mike Becker <universe@uap-core.de>
parents: 693
diff changeset
134 str.length = slen;
579
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
135 cx_for_n(i, count) {
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
136 cxstring s = strings[i];
697
ebdce4bf262b add cx_strcat_m() and cx_strcat_ma() for in-place concatenation
Mike Becker <universe@uap-core.de>
parents: 693
diff changeset
137 memcpy(str.ptr + pos, s.ptr, s.length);
579
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
138 pos += s.length;
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
139 }
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
140
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
141 // terminate string
697
ebdce4bf262b add cx_strcat_m() and cx_strcat_ma() for in-place concatenation
Mike Becker <universe@uap-core.de>
parents: 693
diff changeset
142 str.ptr[str.length] = '\0';
579
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
143
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
144 // free temporary array
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
145 free(strings);
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
146
697
ebdce4bf262b add cx_strcat_m() and cx_strcat_ma() for in-place concatenation
Mike Becker <universe@uap-core.de>
parents: 693
diff changeset
147 return str;
579
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
148 }
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
149
580
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
150 cxstring cx_strsubs(
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
151 cxstring string,
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
152 size_t start
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
153 ) {
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
154 return cx_strsubsl(string, start, string.length - start);
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
155 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
156
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
157 cxmutstr cx_strsubs_m(
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
158 cxmutstr string,
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
159 size_t start
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
160 ) {
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
161 return cx_strsubsl_m(string, start, string.length - start);
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
162 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
163
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
164 cxstring cx_strsubsl(
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
165 cxstring string,
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
166 size_t start,
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
167 size_t length
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
168 ) {
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
169 if (start > string.length) {
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
170 return (cxstring) {NULL, 0};
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
171 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
172
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
173 size_t rem_len = string.length - start;
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
174 if (length > rem_len) {
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
175 length = rem_len;
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
176 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
177
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
178 return (cxstring) {string.ptr + start, length};
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
179 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
180
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
181 cxmutstr cx_strsubsl_m(
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
182 cxmutstr string,
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
183 size_t start,
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
184 size_t length
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
185 ) {
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
186 cxstring result = cx_strsubsl(cx_strcast(string), start, length);
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
187 return (cxmutstr) {(char *) result.ptr, result.length};
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
188 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
189
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
190 cxstring cx_strchr(
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
191 cxstring string,
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
192 int chr
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
193 ) {
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
194 chr = 0xFF & chr;
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
195 // TODO: improve by comparing multiple bytes at once
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
196 cx_for_n(i, string.length) {
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
197 if (string.ptr[i] == chr) {
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
198 return cx_strsubs(string, i);
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
199 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
200 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
201 return (cxstring) {NULL, 0};
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
202 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
203
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
204 cxmutstr cx_strchr_m(
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
205 cxmutstr string,
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
206 int chr
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
207 ) {
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
208 cxstring result = cx_strchr(cx_strcast(string), chr);
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
209 return (cxmutstr) {(char *) result.ptr, result.length};
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
210 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
211
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
212 cxstring cx_strrchr(
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
213 cxstring string,
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
214 int chr
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
215 ) {
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
216 chr = 0xFF & chr;
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
217 size_t i = string.length;
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
218 while (i > 0) {
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
219 i--;
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
220 // TODO: improve by comparing multiple bytes at once
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
221 if (string.ptr[i] == chr) {
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
222 return cx_strsubs(string, i);
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
223 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
224 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
225 return (cxstring) {NULL, 0};
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
226 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
227
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
228 cxmutstr cx_strrchr_m(
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
229 cxmutstr string,
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
230 int chr
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
231 ) {
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
232 cxstring result = cx_strrchr(cx_strcast(string), chr);
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
233 return (cxmutstr) {(char *) result.ptr, result.length};
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
234 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
235
643
5700ba9154ab #228 make buffer sizes adjustable at compile time
Mike Becker <universe@uap-core.de>
parents: 628
diff changeset
236 #ifndef CX_STRSTR_SBO_SIZE
5700ba9154ab #228 make buffer sizes adjustable at compile time
Mike Becker <universe@uap-core.de>
parents: 628
diff changeset
237 #define CX_STRSTR_SBO_SIZE 512
5700ba9154ab #228 make buffer sizes adjustable at compile time
Mike Becker <universe@uap-core.de>
parents: 628
diff changeset
238 #endif
806
e06249e09f99 add constant for reading out strstr sbo size - relates to #343
Mike Becker <universe@uap-core.de>
parents: 697
diff changeset
239 unsigned const cx_strstr_sbo_size = CX_STRSTR_SBO_SIZE;
579
bbc46dcd5255 start implementing string functions
Mike Becker <universe@uap-core.de>
parents: 576
diff changeset
240
580
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
241 cxstring cx_strstr(
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
242 cxstring haystack,
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
243 cxstring needle
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
244 ) {
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
245 if (needle.length == 0) {
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
246 return haystack;
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
247 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
248
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
249 // optimize for single-char needles
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
250 if (needle.length == 1) {
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
251 return cx_strchr(haystack, *needle.ptr);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
252 }
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
253
580
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
254 /*
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
255 * IMPORTANT:
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
256 * Our prefix table contains the prefix length PLUS ONE
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
257 * this is our decision, because we want to use the full range of size_t.
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
258 * The original algorithm needs a (-1) at one single place,
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
259 * and we want to avoid that.
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
260 */
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
261
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
262 // local prefix table
643
5700ba9154ab #228 make buffer sizes adjustable at compile time
Mike Becker <universe@uap-core.de>
parents: 628
diff changeset
263 size_t s_prefix_table[CX_STRSTR_SBO_SIZE];
580
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
264
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
265 // check needle length and use appropriate prefix table
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
266 // if the pattern exceeds static prefix table, allocate on the heap
643
5700ba9154ab #228 make buffer sizes adjustable at compile time
Mike Becker <universe@uap-core.de>
parents: 628
diff changeset
267 bool useheap = needle.length >= CX_STRSTR_SBO_SIZE;
591
7df0bcaecffa fix over-optimization of strstr
Mike Becker <universe@uap-core.de>
parents: 590
diff changeset
268 register size_t *ptable = useheap ? calloc(needle.length + 1,
7df0bcaecffa fix over-optimization of strstr
Mike Becker <universe@uap-core.de>
parents: 590
diff changeset
269 sizeof(size_t)) : s_prefix_table;
580
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
270
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
271 // keep counter in registers
580
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
272 register size_t i, j;
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
273
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
274 // fill prefix table
580
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
275 i = 0;
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
276 j = 0;
591
7df0bcaecffa fix over-optimization of strstr
Mike Becker <universe@uap-core.de>
parents: 590
diff changeset
277 ptable[i] = j;
580
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
278 while (i < needle.length) {
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
279 while (j >= 1 && needle.ptr[j - 1] != needle.ptr[i]) {
591
7df0bcaecffa fix over-optimization of strstr
Mike Becker <universe@uap-core.de>
parents: 590
diff changeset
280 j = ptable[j - 1];
580
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
281 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
282 i++;
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
283 j++;
591
7df0bcaecffa fix over-optimization of strstr
Mike Becker <universe@uap-core.de>
parents: 590
diff changeset
284 ptable[i] = j;
580
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
285 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
286
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
287 // search
580
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
288 cxstring result = {NULL, 0};
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
289 i = 0;
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
290 j = 1;
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
291 while (i < haystack.length) {
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
292 while (j >= 1 && haystack.ptr[i] != needle.ptr[j - 1]) {
591
7df0bcaecffa fix over-optimization of strstr
Mike Becker <universe@uap-core.de>
parents: 590
diff changeset
293 j = ptable[j - 1];
580
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
294 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
295 i++;
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
296 j++;
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
297 if (j - 1 == needle.length) {
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
298 size_t start = i - needle.length;
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
299 result.ptr = haystack.ptr + start;
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
300 result.length = haystack.length - start;
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
301 break;
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
302 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
303 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
304
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
305 // if prefix table was allocated on the heap, free it
580
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
306 if (ptable != s_prefix_table) {
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
307 free(ptable);
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
308 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
309
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
310 return result;
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
311 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
312
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
313 cxmutstr cx_strstr_m(
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
314 cxmutstr haystack,
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
315 cxstring needle
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
316 ) {
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
317 cxstring result = cx_strstr(cx_strcast(haystack), needle);
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
318 return (cxmutstr) {(char *) result.ptr, result.length};
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
319 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
320
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
321 size_t cx_strsplit(
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
322 cxstring string,
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
323 cxstring delim,
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
324 size_t limit,
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
325 cxstring *output
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
326 ) {
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
327 // special case: output limit is zero
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
328 if (limit == 0) return 0;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
329
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
330 // special case: delimiter is empty
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
331 if (delim.length == 0) {
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
332 output[0] = string;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
333 return 1;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
334 }
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
335
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
336 // special cases: delimiter is at least as large as the string
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
337 if (delim.length >= string.length) {
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
338 // exact match
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
339 if (cx_strcmp(string, delim) == 0) {
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
340 output[0] = cx_strn(string.ptr, 0);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
341 output[1] = cx_strn(string.ptr + string.length, 0);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
342 return 2;
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
343 } else {
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
344 // no match possible
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
345 output[0] = string;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
346 return 1;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
347 }
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
348 }
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
349
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
350 size_t n = 0;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
351 cxstring curpos = string;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
352 while (1) {
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
353 ++n;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
354 cxstring match = cx_strstr(curpos, delim);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
355 if (match.length > 0) {
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
356 // is the limit reached?
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
357 if (n < limit) {
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
358 // copy the current string to the array
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
359 cxstring item = cx_strn(curpos.ptr, match.ptr - curpos.ptr);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
360 output[n - 1] = item;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
361 size_t processed = item.length + delim.length;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
362 curpos.ptr += processed;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
363 curpos.length -= processed;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
364 } else {
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
365 // limit reached, copy the _full_ remaining string
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
366 output[n - 1] = curpos;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
367 break;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
368 }
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
369 } else {
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
370 // no more matches, copy last string
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
371 output[n - 1] = curpos;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
372 break;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
373 }
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
374 }
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
375
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
376 return n;
580
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
377 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
378
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
379 size_t cx_strsplit_a(
693
494d9b20b99e fix missing const qualifier for allocator
Mike Becker <universe@uap-core.de>
parents: 657
diff changeset
380 CxAllocator const *allocator,
580
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
381 cxstring string,
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
382 cxstring delim,
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
383 size_t limit,
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
384 cxstring **output
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
385 ) {
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
386 // find out how many splits we're going to make and allocate memory
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
387 size_t n = 0;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
388 cxstring curpos = string;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
389 while (1) {
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
390 ++n;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
391 cxstring match = cx_strstr(curpos, delim);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
392 if (match.length > 0) {
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
393 // is the limit reached?
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
394 if (n < limit) {
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
395 size_t processed = match.ptr - curpos.ptr + delim.length;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
396 curpos.ptr += processed;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
397 curpos.length -= processed;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
398 } else {
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
399 // limit reached
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
400 break;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
401 }
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
402 } else {
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
403 // no more matches
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
404 break;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
405 }
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
406 }
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
407 *output = cxCalloc(allocator, n, sizeof(cxstring));
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
408 return cx_strsplit(string, delim, n, *output);
580
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
409 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
410
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
411 size_t cx_strsplit_m(
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
412 cxmutstr string,
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
413 cxstring delim,
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
414 size_t limit,
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
415 cxmutstr *output
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
416 ) {
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
417 return cx_strsplit(cx_strcast(string),
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
418 delim, limit, (cxstring *) output);
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
419 }
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
420
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
421 size_t cx_strsplit_ma(
693
494d9b20b99e fix missing const qualifier for allocator
Mike Becker <universe@uap-core.de>
parents: 657
diff changeset
422 CxAllocator const *allocator,
580
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
423 cxmutstr string,
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
424 cxstring delim,
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
425 size_t limit,
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
426 cxmutstr **output
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
427 ) {
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
428 return cx_strsplit_a(allocator, cx_strcast(string),
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
429 delim, limit, (cxstring **) output);
aac47db8da0b more implementations of string functions
Mike Becker <universe@uap-core.de>
parents: 579
diff changeset
430 }
581
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
431
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
432 int cx_strcmp(
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
433 cxstring s1,
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
434 cxstring s2
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
435 ) {
581
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
436 if (s1.length == s2.length) {
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
437 return memcmp(s1.ptr, s2.ptr, s1.length);
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
438 } else if (s1.length > s2.length) {
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
439 return 1;
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
440 } else {
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
441 return -1;
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
442 }
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
443 }
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
444
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
445 int cx_strcasecmp(
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
446 cxstring s1,
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
447 cxstring s2
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
448 ) {
581
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
449 if (s1.length == s2.length) {
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
450 #ifdef _WIN32
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
451 return _strnicmp(s1.ptr, s2.ptr, s1.length);
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
452 #else
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
453 return strncasecmp(s1.ptr, s2.ptr, s1.length);
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
454 #endif
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
455 } else if (s1.length > s2.length) {
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
456 return 1;
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
457 } else {
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
458 return -1;
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
459 }
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
460 }
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
461
657
3eeadf666d6b add CxListComparator compatible string compare functions
Mike Becker <universe@uap-core.de>
parents: 645
diff changeset
462 int cx_strcmp_p(
3eeadf666d6b add CxListComparator compatible string compare functions
Mike Becker <universe@uap-core.de>
parents: 645
diff changeset
463 void const *s1,
3eeadf666d6b add CxListComparator compatible string compare functions
Mike Becker <universe@uap-core.de>
parents: 645
diff changeset
464 void const *s2
3eeadf666d6b add CxListComparator compatible string compare functions
Mike Becker <universe@uap-core.de>
parents: 645
diff changeset
465 ) {
3eeadf666d6b add CxListComparator compatible string compare functions
Mike Becker <universe@uap-core.de>
parents: 645
diff changeset
466 cxstring const *left = s1;
3eeadf666d6b add CxListComparator compatible string compare functions
Mike Becker <universe@uap-core.de>
parents: 645
diff changeset
467 cxstring const *right = s2;
3eeadf666d6b add CxListComparator compatible string compare functions
Mike Becker <universe@uap-core.de>
parents: 645
diff changeset
468 return cx_strcmp(*left, *right);
3eeadf666d6b add CxListComparator compatible string compare functions
Mike Becker <universe@uap-core.de>
parents: 645
diff changeset
469 }
3eeadf666d6b add CxListComparator compatible string compare functions
Mike Becker <universe@uap-core.de>
parents: 645
diff changeset
470
3eeadf666d6b add CxListComparator compatible string compare functions
Mike Becker <universe@uap-core.de>
parents: 645
diff changeset
471 int cx_strcasecmp_p(
3eeadf666d6b add CxListComparator compatible string compare functions
Mike Becker <universe@uap-core.de>
parents: 645
diff changeset
472 void const *s1,
3eeadf666d6b add CxListComparator compatible string compare functions
Mike Becker <universe@uap-core.de>
parents: 645
diff changeset
473 void const *s2
3eeadf666d6b add CxListComparator compatible string compare functions
Mike Becker <universe@uap-core.de>
parents: 645
diff changeset
474 ) {
3eeadf666d6b add CxListComparator compatible string compare functions
Mike Becker <universe@uap-core.de>
parents: 645
diff changeset
475 cxstring const *left = s1;
3eeadf666d6b add CxListComparator compatible string compare functions
Mike Becker <universe@uap-core.de>
parents: 645
diff changeset
476 cxstring const *right = s2;
3eeadf666d6b add CxListComparator compatible string compare functions
Mike Becker <universe@uap-core.de>
parents: 645
diff changeset
477 return cx_strcasecmp(*left, *right);
3eeadf666d6b add CxListComparator compatible string compare functions
Mike Becker <universe@uap-core.de>
parents: 645
diff changeset
478 }
3eeadf666d6b add CxListComparator compatible string compare functions
Mike Becker <universe@uap-core.de>
parents: 645
diff changeset
479
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
480 cxmutstr cx_strdup_a(
693
494d9b20b99e fix missing const qualifier for allocator
Mike Becker <universe@uap-core.de>
parents: 657
diff changeset
481 CxAllocator const *allocator,
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
482 cxstring string
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
483 ) {
581
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
484 cxmutstr result = {
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
485 cxMalloc(allocator, string.length + 1),
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
486 string.length
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
487 };
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
488 if (result.ptr == NULL) {
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
489 result.length = 0;
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
490 return result;
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
491 }
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
492 memcpy(result.ptr, string.ptr, string.length);
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
493 result.ptr[string.length] = '\0';
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
494 return result;
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
495 }
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
496
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
497 cxstring cx_strtrim(cxstring string) {
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
498 cxstring result = string;
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
499 // TODO: optimize by comparing multiple bytes at once
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
500 while (result.length > 0 && isspace(*result.ptr)) {
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
501 result.ptr++;
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
502 result.length--;
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
503 }
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
504 while (result.length > 0 && isspace(result.ptr[result.length - 1])) {
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
505 result.length--;
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
506 }
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
507 return result;
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
508 }
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
509
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
510 cxmutstr cx_strtrim_m(cxmutstr string) {
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
511 cxstring result = cx_strtrim(cx_strcast(string));
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
512 return (cxmutstr) {(char *) result.ptr, result.length};
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
513 }
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
514
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
515 bool cx_strprefix(
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
516 cxstring string,
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
517 cxstring prefix
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
518 ) {
581
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
519 if (string.length < prefix.length) return false;
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
520 return memcmp(string.ptr, prefix.ptr, prefix.length) == 0;
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
521 }
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
522
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
523 bool cx_strsuffix(
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
524 cxstring string,
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
525 cxstring suffix
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
526 ) {
581
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
527 if (string.length < suffix.length) return false;
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
528 return memcmp(string.ptr + string.length - suffix.length,
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
529 suffix.ptr, suffix.length) == 0;
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
530 }
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
531
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
532 bool cx_strcaseprefix(
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
533 cxstring string,
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
534 cxstring prefix
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
535 ) {
581
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
536 if (string.length < prefix.length) return false;
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
537 #ifdef _WIN32
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
538 return _strnicmp(string.ptr, prefix.ptr, prefix.length) == 0;
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
539 #else
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
540 return strncasecmp(string.ptr, prefix.ptr, prefix.length) == 0;
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
541 #endif
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
542 }
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
543
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
544 bool cx_strcasesuffix(
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
545 cxstring string,
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
546 cxstring suffix
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
547 ) {
581
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
548 if (string.length < suffix.length) return false;
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
549 #ifdef _WIN32
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
550 return _strnicmp(string.ptr+string.length-suffix.length,
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
551 suffix.ptr, suffix.length) == 0;
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
552 #else
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
553 return strncasecmp(string.ptr + string.length - suffix.length,
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
554 suffix.ptr, suffix.length) == 0;
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
555 #endif
c067394737ca implement more string functions
Mike Becker <universe@uap-core.de>
parents: 580
diff changeset
556 }
582
96fa7fa6af4f implement strupper and strlower
Mike Becker <universe@uap-core.de>
parents: 581
diff changeset
557
96fa7fa6af4f implement strupper and strlower
Mike Becker <universe@uap-core.de>
parents: 581
diff changeset
558 void cx_strlower(cxmutstr string) {
96fa7fa6af4f implement strupper and strlower
Mike Becker <universe@uap-core.de>
parents: 581
diff changeset
559 cx_for_n(i, string.length) {
593
ea9b41b5ebbc explicitly cast int to char
Mike Becker <universe@uap-core.de>
parents: 591
diff changeset
560 string.ptr[i] = (char) tolower(string.ptr[i]);
582
96fa7fa6af4f implement strupper and strlower
Mike Becker <universe@uap-core.de>
parents: 581
diff changeset
561 }
96fa7fa6af4f implement strupper and strlower
Mike Becker <universe@uap-core.de>
parents: 581
diff changeset
562 }
96fa7fa6af4f implement strupper and strlower
Mike Becker <universe@uap-core.de>
parents: 581
diff changeset
563
96fa7fa6af4f implement strupper and strlower
Mike Becker <universe@uap-core.de>
parents: 581
diff changeset
564 void cx_strupper(cxmutstr string) {
96fa7fa6af4f implement strupper and strlower
Mike Becker <universe@uap-core.de>
parents: 581
diff changeset
565 cx_for_n(i, string.length) {
593
ea9b41b5ebbc explicitly cast int to char
Mike Becker <universe@uap-core.de>
parents: 591
diff changeset
566 string.ptr[i] = (char) toupper(string.ptr[i]);
582
96fa7fa6af4f implement strupper and strlower
Mike Becker <universe@uap-core.de>
parents: 581
diff changeset
567 }
96fa7fa6af4f implement strupper and strlower
Mike Becker <universe@uap-core.de>
parents: 581
diff changeset
568 }
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
569
643
5700ba9154ab #228 make buffer sizes adjustable at compile time
Mike Becker <universe@uap-core.de>
parents: 628
diff changeset
570 #ifndef CX_STRREPLACE_INDEX_BUFFER_SIZE
5700ba9154ab #228 make buffer sizes adjustable at compile time
Mike Becker <universe@uap-core.de>
parents: 628
diff changeset
571 #define CX_STRREPLACE_INDEX_BUFFER_SIZE 64
5700ba9154ab #228 make buffer sizes adjustable at compile time
Mike Becker <universe@uap-core.de>
parents: 628
diff changeset
572 #endif
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
573
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
574 struct cx_strreplace_ibuf {
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
575 size_t *buf;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
576 struct cx_strreplace_ibuf *next;
590
02a56701a5cb fix missing zero-termination in strreplace
Mike Becker <universe@uap-core.de>
parents: 583
diff changeset
577 unsigned int len;
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
578 };
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
579
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
580 static void cx_strrepl_free_ibuf(struct cx_strreplace_ibuf *buf) {
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
581 while (buf) {
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
582 struct cx_strreplace_ibuf *next = buf->next;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
583 free(buf->buf);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
584 free(buf);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
585 buf = next;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
586 }
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
587 }
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
588
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
589 cxmutstr cx_strreplacen_a(
693
494d9b20b99e fix missing const qualifier for allocator
Mike Becker <universe@uap-core.de>
parents: 657
diff changeset
590 CxAllocator const *allocator,
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
591 cxstring str,
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
592 cxstring pattern,
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
593 cxstring replacement,
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
594 size_t replmax
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
595 ) {
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
596
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
597 if (pattern.length == 0 || pattern.length > str.length || replmax == 0)
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
598 return cx_strdup_a(allocator, str);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
599
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
600 // Compute expected buffer length
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
601 size_t ibufmax = str.length / pattern.length;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
602 size_t ibuflen = replmax < ibufmax ? replmax : ibufmax;
643
5700ba9154ab #228 make buffer sizes adjustable at compile time
Mike Becker <universe@uap-core.de>
parents: 628
diff changeset
603 if (ibuflen > CX_STRREPLACE_INDEX_BUFFER_SIZE) {
5700ba9154ab #228 make buffer sizes adjustable at compile time
Mike Becker <universe@uap-core.de>
parents: 628
diff changeset
604 ibuflen = CX_STRREPLACE_INDEX_BUFFER_SIZE;
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
605 }
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
606
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
607 // Allocate first index buffer
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
608 struct cx_strreplace_ibuf *firstbuf, *curbuf;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
609 firstbuf = curbuf = calloc(1, sizeof(struct cx_strreplace_ibuf));
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
610 if (!firstbuf) return cx_mutstrn(NULL, 0);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
611 firstbuf->buf = calloc(ibuflen, sizeof(size_t));
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
612 if (!firstbuf->buf) {
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
613 free(firstbuf);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
614 return cx_mutstrn(NULL, 0);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
615 }
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
616
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
617 // Search occurrences
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
618 cxstring searchstr = str;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
619 size_t found = 0;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
620 do {
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
621 cxstring match = cx_strstr(searchstr, pattern);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
622 if (match.length > 0) {
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
623 // Allocate next buffer in chain, if required
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
624 if (curbuf->len == ibuflen) {
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
625 struct cx_strreplace_ibuf *nextbuf =
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
626 calloc(1, sizeof(struct cx_strreplace_ibuf));
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
627 if (!nextbuf) {
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
628 cx_strrepl_free_ibuf(firstbuf);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
629 return cx_mutstrn(NULL, 0);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
630 }
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
631 nextbuf->buf = calloc(ibuflen, sizeof(size_t));
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
632 if (!nextbuf->buf) {
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
633 free(nextbuf);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
634 cx_strrepl_free_ibuf(firstbuf);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
635 return cx_mutstrn(NULL, 0);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
636 }
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
637 curbuf->next = nextbuf;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
638 curbuf = nextbuf;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
639 }
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
640
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
641 // Record match index
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
642 found++;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
643 size_t idx = match.ptr - str.ptr;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
644 curbuf->buf[curbuf->len++] = idx;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
645 searchstr.ptr = match.ptr + pattern.length;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
646 searchstr.length = str.length - idx - pattern.length;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
647 } else {
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
648 break;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
649 }
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
650 } while (searchstr.length > 0 && found < replmax);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
651
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
652 // Allocate result string
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
653 cxmutstr result;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
654 {
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
655 ssize_t adjlen = (ssize_t) replacement.length - (ssize_t) pattern.length;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
656 size_t rcount = 0;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
657 curbuf = firstbuf;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
658 do {
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
659 rcount += curbuf->len;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
660 curbuf = curbuf->next;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
661 } while (curbuf);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
662 result.length = str.length + rcount * adjlen;
590
02a56701a5cb fix missing zero-termination in strreplace
Mike Becker <universe@uap-core.de>
parents: 583
diff changeset
663 result.ptr = cxMalloc(allocator, result.length + 1);
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
664 if (!result.ptr) {
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
665 cx_strrepl_free_ibuf(firstbuf);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
666 return cx_mutstrn(NULL, 0);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
667 }
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
668 }
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
669
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
670 // Build result string
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
671 curbuf = firstbuf;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
672 size_t srcidx = 0;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
673 char *destptr = result.ptr;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
674 do {
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
675 for (size_t i = 0; i < curbuf->len; i++) {
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
676 // Copy source part up to next match
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
677 size_t idx = curbuf->buf[i];
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
678 size_t srclen = idx - srcidx;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
679 if (srclen > 0) {
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
680 memcpy(destptr, str.ptr + srcidx, srclen);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
681 destptr += srclen;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
682 srcidx += srclen;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
683 }
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
684
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
685 // Copy the replacement and skip the source pattern
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
686 srcidx += pattern.length;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
687 memcpy(destptr, replacement.ptr, replacement.length);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
688 destptr += replacement.length;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
689 }
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
690 curbuf = curbuf->next;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
691 } while (curbuf);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
692 memcpy(destptr, str.ptr + srcidx, str.length - srcidx);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
693
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
694 // Result is guaranteed to be zero-terminated
590
02a56701a5cb fix missing zero-termination in strreplace
Mike Becker <universe@uap-core.de>
parents: 583
diff changeset
695 result.ptr[result.length] = '\0';
02a56701a5cb fix missing zero-termination in strreplace
Mike Becker <universe@uap-core.de>
parents: 583
diff changeset
696
628
1e2be40f0cb5 use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents: 593
diff changeset
697 // Free index buffer
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
698 cx_strrepl_free_ibuf(firstbuf);
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
699
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
700 return result;
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
701 }
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
702
645
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
703 CxStrtokCtx cx_strtok(
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
704 cxstring str,
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
705 cxstring delim,
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
706 size_t limit
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
707 ) {
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
708 CxStrtokCtx ctx;
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
709 ctx.str = str;
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
710 ctx.delim = delim;
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
711 ctx.limit = limit;
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
712 ctx.pos = 0;
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
713 ctx.next_pos = 0;
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
714 ctx.delim_pos = 0;
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
715 ctx.found = 0;
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
716 ctx.delim_more = NULL;
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
717 ctx.delim_more_count = 0;
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
718 return ctx;
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
719 }
583
0f3c9662f9b5 add tests and missing implementations for strings
Mike Becker <universe@uap-core.de>
parents: 582
diff changeset
720
645
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
721 CxStrtokCtx cx_strtok_m(
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
722 cxmutstr str,
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
723 cxstring delim,
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
724 size_t limit
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
725 ) {
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
726 return cx_strtok(cx_strcast(str), delim, limit);
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
727 }
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
728
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
729 bool cx_strtok_next(
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
730 CxStrtokCtx *ctx,
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
731 cxstring *token
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
732 ) {
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
733 // abortion criteria
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
734 if (ctx->found >= ctx->limit || ctx->delim_pos >= ctx->str.length) {
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
735 return false;
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
736 }
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
737
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
738 // determine the search start
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
739 cxstring haystack = cx_strsubs(ctx->str, ctx->next_pos);
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
740
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
741 // search the next delimiter
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
742 cxstring delim = cx_strstr(haystack, ctx->delim);
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
743
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
744 // if found, make delim capture exactly the delimiter
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
745 if (delim.length > 0) {
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
746 delim.length = ctx->delim.length;
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
747 }
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
748
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
749 // if more delimiters are specified, check them now
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
750 if (ctx->delim_more_count > 0) {
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
751 cx_for_n(i, ctx->delim_more_count) {
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
752 cxstring d = cx_strstr(haystack, ctx->delim_more[i]);
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
753 if (d.length > 0 && (delim.length == 0 || d.ptr < delim.ptr)) {
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
754 delim.ptr = d.ptr;
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
755 delim.length = ctx->delim_more[i].length;
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
756 }
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
757 }
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
758 }
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
759
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
760 // store the token information and adjust the context
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
761 ctx->found++;
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
762 ctx->pos = ctx->next_pos;
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
763 token->ptr = &ctx->str.ptr[ctx->pos];
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
764 ctx->delim_pos = delim.length == 0 ?
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
765 ctx->str.length : (size_t) (delim.ptr - ctx->str.ptr);
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
766 token->length = ctx->delim_pos - ctx->pos;
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
767 ctx->next_pos = ctx->delim_pos + delim.length;
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
768
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
769 return true;
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
770 }
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
771
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
772 bool cx_strtok_next_m(
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
773 CxStrtokCtx *ctx,
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
774 cxmutstr *token
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
775 ) {
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
776 return cx_strtok_next(ctx, (cxstring *) token);
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
777 }
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
778
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
779 void cx_strtok_delim(
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
780 CxStrtokCtx *ctx,
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
781 cxstring const *delim,
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
782 size_t count
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
783 ) {
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
784 ctx->delim_more = delim;
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
785 ctx->delim_more_count = count;
ec50abb285ad add strtok API - fixes #220
Mike Becker <universe@uap-core.de>
parents: 643
diff changeset
786 }

mercurial