1 /* |
1 /* |
2 * File: sstring.c |
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
3 * Author: olaf |
3 * |
4 * |
4 * Copyright 2013 Olaf Wintermann. All rights reserved. |
5 * Created on 17. Juni 2010, 13:27 |
5 * |
|
6 * Redistribution and use in source and binary forms, with or without |
|
7 * modification, are permitted provided that the following conditions are met: |
|
8 * |
|
9 * 1. Redistributions of source code must retain the above copyright |
|
10 * notice, this list of conditions and the following disclaimer. |
|
11 * |
|
12 * 2. Redistributions in binary form must reproduce the above copyright |
|
13 * notice, this list of conditions and the following disclaimer in the |
|
14 * documentation and/or other materials provided with the distribution. |
|
15 * |
|
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
|
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
26 * POSSIBILITY OF SUCH DAMAGE. |
6 */ |
27 */ |
7 |
28 |
8 #include <stdlib.h> |
29 #include <stdlib.h> |
9 #include <strings.h> |
30 #include <string.h> |
10 #include <stdarg.h> |
31 #include <stdarg.h> |
11 |
32 |
12 #include "string.h" |
33 #include "string.h" |
13 |
34 |
14 sstr_t sstr (char *s) { |
35 sstr_t sstr(char *s) { |
15 sstr_t string; |
36 sstr_t string; |
16 string.ptr = s; |
37 string.ptr = s; |
17 string.length = strlen(s); |
38 string.length = strlen(s); |
18 return string; |
39 return string; |
19 } |
40 } |
20 |
41 |
21 sstr_t sstrn (char *s, size_t n) { |
42 sstr_t sstrn(char *s, size_t n) { |
22 sstr_t string; |
43 sstr_t string; |
23 string.ptr = s; |
44 string.ptr = s; |
24 string.length = n; |
45 string.length = n; |
25 return string; |
46 return string; |
26 } |
47 } |
27 |
48 |
28 size_t sstrnlen (size_t n, sstr_t s, ...) { |
49 size_t sstrnlen(size_t n, sstr_t s, ...) { |
29 va_list ap; |
50 va_list ap; |
30 size_t size = s.length; |
51 size_t size = s.length; |
31 va_start(ap, s); |
52 va_start(ap, s); |
32 |
53 |
33 for (int i=0;i<n-1;i++) { |
54 for (size_t i = 0 ; i < n-1 ; i++) { |
34 sstr_t str = va_arg(ap, sstr_t); |
55 sstr_t str = va_arg(ap, sstr_t); |
35 size += str.length; |
56 size += str.length; |
36 } |
57 } |
37 va_end(ap); |
58 va_end(ap); |
38 |
59 |
39 return size; |
60 return size; |
40 } |
61 } |
41 |
62 |
42 sstr_t sstrcat (sstr_t s, ...) { |
63 sstr_t sstrncat(size_t n, sstr_t s, sstr_t c1, ...) { |
43 va_list ap; |
|
44 va_start(ap, s); |
|
45 s.ptr[0] = 0; |
|
46 |
|
47 sstr_t str = va_arg (ap, sstr_t); |
|
48 while (str.ptr != NULL) { |
|
49 s.ptr = strncat (s.ptr, str.ptr, s.length); |
|
50 str = va_arg (ap, sstr_t); |
|
51 } |
|
52 va_end(ap); |
|
53 |
|
54 return s; |
|
55 } |
|
56 |
|
57 sstr_t sstrncat (size_t n, sstr_t s, sstr_t c1, ...) { |
|
58 va_list ap; |
64 va_list ap; |
59 va_start(ap, c1); |
65 va_start(ap, c1); |
60 s.ptr[0] = 0; |
66 s.ptr[0] = 0; |
61 |
67 |
62 size_t len = s.length; |
68 size_t len = s.length; |
76 memcpy(ptr, str.ptr, cplen); |
82 memcpy(ptr, str.ptr, cplen); |
77 len -= cplen; |
83 len -= cplen; |
78 ptr += cplen; |
84 ptr += cplen; |
79 } |
85 } |
80 va_end(ap); |
86 va_end(ap); |
|
87 s.length = ptr - s.ptr; |
81 |
88 |
82 return s; |
89 return s; |
83 } |
90 } |
84 |
91 |
85 sstr_t sstrsubs (sstr_t s, size_t start) { |
92 sstr_t sstrsubs(sstr_t s, size_t start) { |
86 return sstrsubsl (s, start, s.length-start); |
93 return sstrsubsl (s, start, s.length-start); |
87 } |
94 } |
88 |
95 |
89 sstr_t sstrsubsl (sstr_t s, size_t start, size_t length) { |
96 sstr_t sstrsubsl(sstr_t s, size_t start, size_t length) { |
90 sstr_t new_sstr; |
97 sstr_t new_sstr; |
91 if (start >= s.length) { |
98 if (start >= s.length) { |
92 return s; |
99 return s; |
93 } |
100 } |
94 if (length > s.length-start) { |
101 if (length > s.length-start) { |
108 size_t nmax = *n; |
115 size_t nmax = *n; |
109 *n = 1; |
116 *n = 1; |
110 |
117 |
111 /* special case: exact match - no processing needed */ |
118 /* special case: exact match - no processing needed */ |
112 if (s.length == d.length && strncmp(s.ptr, d.ptr, s.length) == 0) { |
119 if (s.length == d.length && strncmp(s.ptr, d.ptr, s.length) == 0) { |
113 result = malloc(sizeof(sstr_t)); |
120 *n = 0; |
114 result[0] = sstrn("", 0); |
121 return NULL; |
115 return result; |
|
116 } |
122 } |
117 sstr_t sv = sstrdup(s); |
123 sstr_t sv = sstrdup(s); |
118 |
124 |
119 for (int i = 0 ; i < s.length ; i++) { |
125 for (size_t i = 0 ; i < s.length ; i++) { |
120 if (sv.ptr[i] == d.ptr[0]) { |
126 if (sv.ptr[i] == d.ptr[0]) { |
121 _Bool match = 1; |
127 _Bool match = 1; |
122 for (int j = 1 ; j < d.length ; j++) { |
128 for (size_t j = 1 ; j < d.length ; j++) { |
123 if (j+i < s.length) { |
129 if (j+i < s.length) { |
124 match &= (sv.ptr[i+j] == d.ptr[j]); |
130 match &= (sv.ptr[i+j] == d.ptr[j]); |
125 } else { |
131 } else { |
126 match = 0; |
132 match = 0; |
127 break; |
133 break; |
128 } |
134 } |
129 } |
135 } |
130 if (match) { |
136 if (match) { |
131 (*n)++; |
137 (*n)++; |
132 for (int j = 0 ; j < d.length ; j++) { |
138 for (size_t j = 0 ; j < d.length ; j++) { |
133 sv.ptr[i+j] = 0; |
139 sv.ptr[i+j] = 0; |
134 } |
140 } |
135 i += d.length; |
141 i += d.length; |
136 } |
142 } |
137 } |
143 } |
138 if ((*n) == nmax) break; |
144 if ((*n) == nmax) break; |
139 } |
145 } |
140 result = malloc(sizeof(sstr_t) * (*n)); |
146 result = (sstr_t*) malloc(sizeof(sstr_t) * (*n)); |
141 |
147 |
142 char *pptr = sv.ptr; |
148 char *pptr = sv.ptr; |
143 for (int i = 0 ; i < *n ; i++) { |
149 for (size_t i = 0 ; i < *n ; i++) { |
144 size_t l = strlen(pptr); |
150 size_t l = strlen(pptr); |
145 char* ptr = malloc(l + 1); |
151 char* ptr = (char*) malloc(l + 1); |
146 memcpy(ptr, pptr, l); |
152 memcpy(ptr, pptr, l); |
147 ptr[l] = 0; |
153 ptr[l] = 0; |
148 |
154 |
149 result[i] = sstrn(ptr, l); |
155 result[i] = sstrn(ptr, l); |
150 pptr += l + d.length; |
156 pptr += l + d.length; |
160 } |
166 } |
161 |
167 |
162 sstr_t sstrdup(sstr_t s) { |
168 sstr_t sstrdup(sstr_t s) { |
163 sstr_t newstring; |
169 sstr_t newstring; |
164 newstring.ptr = (char*) malloc(s.length + 1); |
170 newstring.ptr = (char*) malloc(s.length + 1); |
165 if (newstring.ptr != NULL) { |
171 newstring.length = 0; |
|
172 if (newstring.ptr) { |
166 newstring.length = s.length; |
173 newstring.length = s.length; |
167 newstring.ptr[newstring.length] = 0; |
174 newstring.ptr[newstring.length] = 0; |
168 |
175 |
169 memcpy(newstring.ptr, s.ptr, s.length); |
176 memcpy(newstring.ptr, s.ptr, s.length); |
|
177 } else { |
|
178 newstring.length = 0; |
170 } |
179 } |
171 |
180 |
172 return newstring; |
181 return newstring; |
173 } |
182 } |
|
183 |
|
184 sstr_t sstrtrim(sstr_t string) { |
|
185 sstr_t newstr = string; |
|
186 if (string.length == 0) { |
|
187 return newstr; |
|
188 } |
|
189 |
|
190 size_t i; |
|
191 for(i=0;i<string.length;i++) { |
|
192 char c = string.ptr[i]; |
|
193 if(c > 32) { |
|
194 break; |
|
195 } |
|
196 } |
|
197 newstr.ptr = &string.ptr[i]; |
|
198 newstr.length = string.length - i; |
|
199 |
|
200 if(newstr.length == 0) { |
|
201 return newstr; |
|
202 } |
|
203 |
|
204 i = newstr.length - 1; |
|
205 for(;;) { |
|
206 char c = newstr.ptr[i]; |
|
207 if(c > 32) { |
|
208 break; |
|
209 } |
|
210 if(i > 0) { |
|
211 i--; |
|
212 } else { |
|
213 break; |
|
214 } |
|
215 } |
|
216 newstr.length = i + 1; |
|
217 |
|
218 return newstr; |
|
219 } |
|
220 |
174 |
221 |
175 // webserver extension |
222 // webserver extension |
176 |
223 |
177 int sstr_startswith(sstr_t string, sstr_t cmp) { |
224 int sstr_startswith(sstr_t string, sstr_t cmp) { |
178 sstr_t sub = sstrsubsl(string, 0, cmp.length); |
225 sstr_t sub = sstrsubsl(string, 0, cmp.length); |
181 } else { |
228 } else { |
182 return 0; |
229 return 0; |
183 } |
230 } |
184 } |
231 } |
185 |
232 |
186 sstr_t sstrtrim(sstr_t string) { |
|
187 sstr_t newstr = string; |
|
188 int i; |
|
189 for(i=0;i<string.length;i++) { |
|
190 char c = string.ptr[i]; |
|
191 if(c > 32) { |
|
192 break; |
|
193 } |
|
194 } |
|
195 |
|
196 newstr.ptr = &string.ptr[i]; |
|
197 newstr.length = string.length - i; |
|
198 |
|
199 for(i=newstr.length-1;i>=0;i--) { |
|
200 char c = newstr.ptr[i]; |
|
201 if(c > 32) { |
|
202 break; |
|
203 } |
|
204 } |
|
205 newstr.length = i + 1; |
|
206 |
|
207 return newstr; |
|
208 } |
|
209 |
|
210 sstr_t sstrdup_mp(UcxMempool *pool, sstr_t s) { |
233 sstr_t sstrdup_mp(UcxMempool *pool, sstr_t s) { |
211 sstr_t newstring; |
234 sstr_t newstring; |
212 newstring.ptr = (char*)ucx_mempool_malloc(pool, s.length + 1); |
235 newstring.ptr = (char*)ucx_mempool_malloc(pool, s.length + 1); |
213 if (newstring.ptr != NULL) { |
236 if (newstring.ptr != NULL) { |
214 newstring.length = s.length; |
237 newstring.length = s.length; |