ucx/string.c

changeset 124
80609f9675f1
parent 0
1f419bd32da1
child 152
62921b370c60
equal deleted inserted replaced
123:55adc92e7c09 124:80609f9675f1
1 /* 1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 * 3 *
4 * Copyright 2013 Olaf Wintermann. All rights reserved. 4 * Copyright 2015 Olaf Wintermann. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met: 7 * modification, are permitted provided that the following conditions are met:
8 * 8 *
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
27 */ 27 */
28 28
29 #include <stdlib.h> 29 #include <stdlib.h>
30 #include <string.h> 30 #include <string.h>
31 #include <stdarg.h> 31 #include <stdarg.h>
32 #include <ctype.h>
32 33
33 #include "string.h" 34 #include "string.h"
34 #include "allocator.h" 35 #include "allocator.h"
35 36
36 sstr_t sstr(char *cstring) { 37 sstr_t sstr(char *cstring) {
59 va_end(ap); 60 va_end(ap);
60 61
61 return size; 62 return size;
62 } 63 }
63 64
64 sstr_t sstrncat(sstr_t s, size_t n, sstr_t c1, ...) { 65 static sstr_t sstrvcat_a(
66 UcxAllocator *a,
67 size_t count,
68 sstr_t s1,
69 sstr_t s2,
70 va_list ap) {
71 sstr_t str;
72 str.ptr = NULL;
73 str.length = 0;
74 if(count < 2) {
75 return str;
76 }
77
78 sstr_t *strings = (sstr_t*) calloc(count, sizeof(sstr_t));
79 if(!strings) {
80 return str;
81 }
82
83 // get all args and overall length
84 strings[0] = s1;
85 strings[1] = s2;
86 size_t strlen = s1.length + s2.length;
87 for (size_t i=2;i<count;i++) {
88 sstr_t s = va_arg (ap, sstr_t);
89 strings[i] = s;
90 strlen += s.length;
91 }
92
93 // create new string
94 str.ptr = (char*) almalloc(a, strlen + 1);
95 str.length = strlen;
96 if(!str.ptr) {
97 free(strings);
98 str.length = 0;
99 return str;
100 }
101
102 // concatenate strings
103 size_t pos = 0;
104 for (size_t i=0;i<count;i++) {
105 sstr_t s = strings[i];
106 memcpy(str.ptr + pos, s.ptr, s.length);
107 pos += s.length;
108 }
109
110 str.ptr[str.length] = '\0';
111
112 free(strings);
113
114 return str;
115 }
116
117 sstr_t sstrcat(size_t count, sstr_t s1, sstr_t s2, ...) {
65 va_list ap; 118 va_list ap;
66 va_start(ap, c1); 119 va_start(ap, s2);
67 s.ptr[0] = 0; 120 sstr_t s = sstrvcat_a(ucx_default_allocator(), count, s1, s2, ap);
68
69 size_t len = s.length;
70 size_t cplen = c1.length > len ? len : c1.length;
71 char *ptr = s.ptr;
72
73 memcpy(ptr, c1.ptr, cplen);
74 len -= cplen;
75 ptr += cplen;
76 for (size_t i = 1 ; i < n ; i++) {
77 sstr_t str = va_arg (ap, sstr_t);
78 cplen = str.length > len ? len : str.length;
79 if(cplen <= 0) {
80 va_end(ap);
81 return s;
82 }
83 memcpy(ptr, str.ptr, cplen);
84 len -= cplen;
85 ptr += cplen;
86 }
87 va_end(ap); 121 va_end(ap);
88 s.length = ptr - s.ptr; 122 return s;
89 123 }
124
125 sstr_t sstrcat_a(UcxAllocator *a, size_t count, sstr_t s1, sstr_t s2, ...) {
126 va_list ap;
127 va_start(ap, s2);
128 sstr_t s = sstrvcat_a(a, count, s1, s2, ap);
129 va_end(ap);
90 return s; 130 return s;
91 } 131 }
92 132
93 sstr_t sstrsubs(sstr_t s, size_t start) { 133 sstr_t sstrsubs(sstr_t s, size_t start) {
94 return sstrsubsl (s, start, s.length-start); 134 return sstrsubsl (s, start, s.length-start);
95 } 135 }
96 136
97 sstr_t sstrsubsl(sstr_t s, size_t start, size_t length) { 137 sstr_t sstrsubsl(sstr_t s, size_t start, size_t length) {
98 sstr_t new_sstr; 138 sstr_t new_sstr;
99 if (start >= s.length) { 139 if (start >= s.length) {
100 return s; 140 new_sstr.ptr = NULL;
101 } 141 new_sstr.length = 0;
102 if (length > s.length-start) { 142 } else {
103 length = s.length-start; 143 if (length > s.length-start) {
104 } 144 length = s.length-start;
105 new_sstr.ptr = &s.ptr[start]; 145 }
106 new_sstr.length = length; 146 new_sstr.ptr = &s.ptr[start];
147 new_sstr.length = length;
148 }
107 return new_sstr; 149 return new_sstr;
108 } 150 }
109 151
110 sstr_t sstrchr(sstr_t s, int c) { 152 sstr_t sstrchr(sstr_t s, int c) {
111 for(size_t i=0;i<s.length;i++) { 153 for(size_t i=0;i<s.length;i++) {
131 n.ptr = NULL; 173 n.ptr = NULL;
132 n.length = 0; 174 n.length = 0;
133 return n; 175 return n;
134 } 176 }
135 177
136 sstr_t* sstrsplit(sstr_t s, sstr_t d, size_t *n) { 178 sstr_t* sstrsplit(sstr_t s, sstr_t d, ssize_t *n) {
137 return sstrsplit_a(ucx_default_allocator(), s, d, n); 179 return sstrsplit_a(ucx_default_allocator(), s, d, n);
138 } 180 }
139 181
140 sstr_t* sstrsplit_a(UcxAllocator *allocator, sstr_t s, sstr_t d, size_t *n) { 182 sstr_t* sstrsplit_a(UcxAllocator *allocator, sstr_t s, sstr_t d, ssize_t *n) {
141 if (s.length == 0 || d.length == 0) { 183 if (s.length == 0 || d.length == 0) {
142 *n = -1; 184 *n = -1;
143 return NULL; 185 return NULL;
144 } 186 }
145 187
146 sstr_t* result; 188 sstr_t* result;
147 size_t nmax = *n; 189 ssize_t nmax = *n;
148 *n = 1; 190 *n = 1;
149 191
150 /* special case: exact match - no processing needed */ 192 /* special case: exact match - no processing needed */
151 if (sstrcmp(s, d) == 0) { 193 if (sstrcmp(s, d) == 0) {
152 *n = 0; 194 *n = 0;
177 i += d.length; 219 i += d.length;
178 } 220 }
179 } 221 }
180 if ((*n) == nmax) break; 222 if ((*n) == nmax) break;
181 } 223 }
182 result = (sstr_t*) allocator->malloc(allocator->pool, sizeof(sstr_t)*(*n)); 224 result = (sstr_t*) almalloc(allocator, sizeof(sstr_t)*(*n));
183 225
184 if (result) { 226 if (result) {
185 char *pptr = sv.ptr; 227 char *pptr = sv.ptr;
186 for (size_t i = 0 ; i < *n ; i++) { 228 for (ssize_t i = 0 ; i < *n ; i++) {
187 size_t l = strlen(pptr); 229 size_t l = strlen(pptr);
188 char* ptr = (char*) allocator->malloc(allocator->pool, l + 1); 230 char* ptr = (char*) almalloc(allocator, l + 1);
189 memcpy(ptr, pptr, l); 231 if (ptr) {
190 ptr[l] = 0; 232 memcpy(ptr, pptr, l);
191 233 ptr[l] = 0;
192 result[i] = sstrn(ptr, l); 234
193 pptr += l + d.length; 235 result[i] = sstrn(ptr, l);
236 pptr += l + d.length;
237 } else {
238 for (ssize_t j = i-1 ; j >= 0 ; j--) {
239 alfree(allocator, result[j].ptr);
240 }
241 alfree(allocator, result);
242 *n = -2;
243 break;
244 }
194 } 245 }
195 } else { 246 } else {
196 *n = -2; 247 *n = -2;
197 } 248 }
198 249
229 return sstrdup_a(ucx_default_allocator(), s); 280 return sstrdup_a(ucx_default_allocator(), s);
230 } 281 }
231 282
232 sstr_t sstrdup_a(UcxAllocator *allocator, sstr_t s) { 283 sstr_t sstrdup_a(UcxAllocator *allocator, sstr_t s) {
233 sstr_t newstring; 284 sstr_t newstring;
234 newstring.ptr = (char*)allocator->malloc(allocator->pool, s.length + 1); 285 newstring.ptr = (char*)almalloc(allocator, s.length + 1);
235 if (newstring.ptr) { 286 if (newstring.ptr) {
236 newstring.length = s.length; 287 newstring.length = s.length;
237 newstring.ptr[newstring.length] = 0; 288 newstring.ptr[newstring.length] = 0;
238 289
239 memcpy(newstring.ptr, s.ptr, s.length); 290 memcpy(newstring.ptr, s.ptr, s.length);
244 return newstring; 295 return newstring;
245 } 296 }
246 297
247 sstr_t sstrtrim(sstr_t string) { 298 sstr_t sstrtrim(sstr_t string) {
248 sstr_t newstr = string; 299 sstr_t newstr = string;
249 if (string.length == 0) { 300
250 return newstr; 301 while (newstr.length > 0 && isspace(*newstr.ptr)) {
251 } 302 newstr.ptr++;
252 303 newstr.length--;
253 size_t i; 304 }
254 for(i=0;i<string.length;i++) { 305 while (newstr.length > 0 && isspace(newstr.ptr[newstr.length-1])) {
255 char c = string.ptr[i]; 306 newstr.length--;
256 if(c > 32) { 307 }
257 break;
258 }
259 }
260 newstr.ptr = &string.ptr[i];
261 newstr.length = string.length - i;
262
263 if(newstr.length == 0) {
264 return newstr;
265 }
266
267 i = newstr.length - 1;
268 for(;;) {
269 char c = newstr.ptr[i];
270 if(c > 32) {
271 break;
272 }
273 if(i > 0) {
274 i--;
275 } else {
276 break;
277 }
278 }
279 newstr.length = i + 1;
280 308
281 return newstr; 309 return newstr;
282 } 310 }
283 311
284 int sstrprefix(sstr_t string, sstr_t prefix) { 312 int sstrprefix(sstr_t string, sstr_t prefix) {
309 } else { 337 } else {
310 return memcmp(string.ptr+string.length-suffix.length, 338 return memcmp(string.ptr+string.length-suffix.length,
311 suffix.ptr, suffix.length) == 0; 339 suffix.ptr, suffix.length) == 0;
312 } 340 }
313 } 341 }
342
343 sstr_t sstrlower(sstr_t string) {
344 sstr_t ret = sstrdup(string);
345 for (size_t i = 0; i < ret.length ; i++) {
346 ret.ptr[i] = tolower(ret.ptr[i]);
347 }
348 return ret;
349 }
350
351 sstr_t sstrlower_a(UcxAllocator *allocator, sstr_t string) {
352 sstr_t ret = sstrdup_a(allocator, string);
353 for (size_t i = 0; i < ret.length ; i++) {
354 ret.ptr[i] = tolower(ret.ptr[i]);
355 }
356 return ret;
357 }
358
359 sstr_t sstrupper(sstr_t string) {
360 sstr_t ret = sstrdup(string);
361 for (size_t i = 0; i < ret.length ; i++) {
362 ret.ptr[i] = toupper(ret.ptr[i]);
363 }
364 return ret;
365 }
366
367 sstr_t sstrupper_a(UcxAllocator *allocator, sstr_t string) {
368 sstr_t ret = sstrdup_a(allocator, string);
369 for (size_t i = 0; i < ret.length ; i++) {
370 ret.ptr[i] = toupper(ret.ptr[i]);
371 }
372 return ret;
373 }

mercurial