src/string.c

branch
constsstr
changeset 276
f1b2146d4805
parent 275
96f643d30ff1
child 288
6af5798342e8
equal deleted inserted replaced
275:96f643d30ff1 276:f1b2146d4805
215 #define ptable_w(useheap, ptable, index, src) do {\ 215 #define ptable_w(useheap, ptable, index, src) do {\
216 if (!useheap) ((uint8_t*)ptable)[index] = (uint8_t) src;\ 216 if (!useheap) ((uint8_t*)ptable)[index] = (uint8_t) src;\
217 else ((size_t*)ptable)[index] = src;\ 217 else ((size_t*)ptable)[index] = src;\
218 } while (0); 218 } while (0);
219 219
220 sstr_t sstrstr(sstr_t string, sstr_t match) { 220
221 if (match.length == 0) { 221 const char* ucx_strstr(
222 return string; 222 const char *str,
223 } 223 size_t length,
224 224 const char *match,
225 /* prepare default return value in case of no match */ 225 size_t matchlen,
226 sstr_t result = sstrn(NULL, 0); 226 size_t *newlen)
227 {
228 *newlen = length;
229 if (matchlen == 0) {
230 return str;
231 }
232
233 const char *result = NULL;
234 size_t resultlen = 0;
227 235
228 /* 236 /*
229 * IMPORTANT: 237 * IMPORTANT:
230 * our prefix table contains the prefix length PLUS ONE 238 * our prefix table contains the prefix length PLUS ONE
231 * this is our decision, because we want to use the full range of size_t 239 * this is our decision, because we want to use the full range of size_t
236 /* static prefix table */ 244 /* static prefix table */
237 static uint8_t s_prefix_table[256]; 245 static uint8_t s_prefix_table[256];
238 246
239 /* check pattern length and use appropriate prefix table */ 247 /* check pattern length and use appropriate prefix table */
240 /* if the pattern exceeds static prefix table, allocate on the heap */ 248 /* if the pattern exceeds static prefix table, allocate on the heap */
241 register int useheap = match.length > 255; 249 register int useheap = matchlen > 255;
242 register void* ptable = useheap ? 250 register void* ptable = useheap ?
243 calloc(match.length+1, sizeof(size_t)): s_prefix_table; 251 calloc(matchlen+1, sizeof(size_t)): s_prefix_table;
244 252
245 /* keep counter in registers */ 253 /* keep counter in registers */
246 register size_t i, j; 254 register size_t i, j;
247 255
248 /* fill prefix table */ 256 /* fill prefix table */
249 i = 0; j = 0; 257 i = 0; j = 0;
250 ptable_w(useheap, ptable, i, j); 258 ptable_w(useheap, ptable, i, j);
251 while (i < match.length) { 259 while (i < matchlen) {
252 while (j >= 1 && match.ptr[j-1] != match.ptr[i]) { 260 while (j >= 1 && match[j-1] != match[i]) {
253 ptable_r(j, useheap, ptable, j-1); 261 ptable_r(j, useheap, ptable, j-1);
254 } 262 }
255 i++; j++; 263 i++; j++;
256 ptable_w(useheap, ptable, i, j); 264 ptable_w(useheap, ptable, i, j);
257 } 265 }
258 266
259 /* search */ 267 /* search */
260 i = 0; j = 1; 268 i = 0; j = 1;
261 while (i < string.length) { 269 while (i < length) {
262 while (j >= 1 && string.ptr[i] != match.ptr[j-1]) { 270 while (j >= 1 && str[i] != match[j-1]) {
263 ptable_r(j, useheap, ptable, j-1); 271 ptable_r(j, useheap, ptable, j-1);
264 } 272 }
265 i++; j++; 273 i++; j++;
266 if (j-1 == match.length) { 274 if (j-1 == matchlen) {
267 size_t start = i - match.length; 275 size_t start = i - matchlen;
268 result.ptr = string.ptr + start; 276 result = str + start;
269 result.length = string.length - start; 277 resultlen = length - start;
270 break; 278 break;
271 } 279 }
272 } 280 }
273 281
274 /* if prefix table was allocated on the heap, free it */ 282 /* if prefix table was allocated on the heap, free it */
275 if (ptable != s_prefix_table) { 283 if (ptable != s_prefix_table) {
276 free(ptable); 284 free(ptable);
277 } 285 }
278 286
287 *newlen = resultlen;
288 return result;
289 }
290
291 sstr_t ucx_sstrstr(sstr_t string, scstr_t match) {
292 sstr_t result;
293
294 size_t reslen;
295 const char *resstr = ucx_strstr(string.ptr, string.length, match.ptr, match.length, &reslen);
296 if(!resstr) {
297 result.ptr = NULL;
298 result.length = 0;
299 return result;
300 }
301
302 size_t pos = resstr - string.ptr;
303 result.ptr = string.ptr + pos;
304 result.length = reslen;
305
306 return result;
307 }
308
309 scstr_t ucx_scstrstr(scstr_t string, scstr_t match) {
310 scstr_t result;
311
312 size_t reslen;
313 const char *resstr = ucx_strstr(string.ptr, string.length, match.ptr, match.length, &reslen);
314 if(!resstr) {
315 result.ptr = NULL;
316 result.length = 0;
317 return result;
318 }
319
320 size_t pos = resstr - string.ptr;
321 result.ptr = string.ptr + pos;
322 result.length = reslen;
323
279 return result; 324 return result;
280 } 325 }
281 326
282 #undef ptable_r 327 #undef ptable_r
283 #undef ptable_w 328 #undef ptable_w
284 329
285 sstr_t* sstrsplit(sstr_t s, sstr_t d, ssize_t *n) { 330 sstr_t* ucx_strsplit(scstr_t s, scstr_t d, ssize_t *n) {
286 return sstrsplit_a(ucx_default_allocator(), s, d, n); 331 return ucx_strsplit_a(ucx_default_allocator(), s, d, n);
287 } 332 }
288 333
289 sstr_t* sstrsplit_a(UcxAllocator *allocator, sstr_t s, sstr_t d, ssize_t *n) { 334 sstr_t* ucx_strsplit_a(UcxAllocator *allocator, scstr_t s, scstr_t d, ssize_t *n) {
290 if (s.length == 0 || d.length == 0) { 335 if (s.length == 0 || d.length == 0) {
291 *n = -1; 336 *n = -1;
292 return NULL; 337 return NULL;
293 } 338 }
294 339
313 ssize_t nmax = *n; 358 ssize_t nmax = *n;
314 size_t arrlen = 16; 359 size_t arrlen = 16;
315 sstr_t* result = (sstr_t*) alcalloc(allocator, arrlen, sizeof(sstr_t)); 360 sstr_t* result = (sstr_t*) alcalloc(allocator, arrlen, sizeof(sstr_t));
316 361
317 if (result) { 362 if (result) {
318 sstr_t curpos = s; 363 scstr_t curpos = s;
319 ssize_t j = 1; 364 ssize_t j = 1;
320 while (1) { 365 while (1) {
321 sstr_t match; 366 scstr_t match;
322 /* optimize for one byte delimiters */ 367 /* optimize for one byte delimiters */
323 if (d.length == 1) { 368 if (d.length == 1) {
324 match = curpos; 369 match = curpos;
325 for (size_t i = 0 ; i < curpos.length ; i++) { 370 for (size_t i = 0 ; i < curpos.length ; i++) {
326 if (curpos.ptr[i] == *(d.ptr)) { 371 if (curpos.ptr[i] == *(d.ptr)) {
328 break; 373 break;
329 } 374 }
330 match.length--; 375 match.length--;
331 } 376 }
332 } else { 377 } else {
333 match = sstrstr(curpos, d); 378 match = scstrstr(curpos, d);
334 } 379 }
335 if (match.length > 0) { 380 if (match.length > 0) {
336 /* is this our last try? */ 381 /* is this our last try? */
337 if (nmax == 0 || j < nmax) { 382 if (nmax == 0 || j < nmax) {
338 /* copy the current string to the array */ 383 /* copy the current string to the array */
339 sstr_t item = sstrn(curpos.ptr, match.ptr - curpos.ptr); 384 scstr_t item = scstrn(curpos.ptr, match.ptr - curpos.ptr);
340 result[j-1] = sstrdup_a(allocator, item); 385 result[j-1] = sstrdup_a(allocator, item);
341 size_t processed = item.length + d.length; 386 size_t processed = item.length + d.length;
342 curpos.ptr += processed; 387 curpos.ptr += processed;
343 curpos.length -= processed; 388 curpos.length -= processed;
344 389
380 } 425 }
381 426
382 return result; 427 return result;
383 } 428 }
384 429
385 int sstrcmp(sstr_t s1, sstr_t s2) { 430 int ucx_str_cmp(scstr_t s1, scstr_t s2) {
386 if (s1.length == s2.length) { 431 if (s1.length == s2.length) {
387 return memcmp(s1.ptr, s2.ptr, s1.length); 432 return memcmp(s1.ptr, s2.ptr, s1.length);
388 } else if (s1.length > s2.length) { 433 } else if (s1.length > s2.length) {
389 return 1; 434 return 1;
390 } else { 435 } else {
391 return -1; 436 return -1;
392 } 437 }
393 } 438 }
394 439
395 int sstrcasecmp(sstr_t s1, sstr_t s2) { 440 int ucx_str_casecmp(scstr_t s1, scstr_t s2) {
396 if (s1.length == s2.length) { 441 if (s1.length == s2.length) {
397 #ifdef _WIN32 442 #ifdef _WIN32
398 return _strnicmp(s1.ptr, s2.ptr, s1.length); 443 return _strnicmp(s1.ptr, s2.ptr, s1.length);
399 #else 444 #else
400 return strncasecmp(s1.ptr, s2.ptr, s1.length); 445 return strncasecmp(s1.ptr, s2.ptr, s1.length);
423 } 468 }
424 469
425 return newstring; 470 return newstring;
426 } 471 }
427 472
473
474 size_t ucx_strtrim(const char *s, size_t len, size_t *newlen) {
475 const char *newptr = s;
476 size_t length = len;
477
478 while(length > 0 && isspace(*newptr)) {
479 newptr++;
480 length--;
481 }
482 while(length > 0 && isspace(newptr[length-1])) {
483 length--;
484 }
485
486 *newlen = length;
487 return newptr - s;
488 }
489
428 sstr_t sstrtrim(sstr_t string) { 490 sstr_t sstrtrim(sstr_t string) {
429 sstr_t newstr = string; 491 sstr_t newstr;
430 492 newstr.ptr = string.ptr
431 while (newstr.length > 0 && isspace(*newstr.ptr)) { 493 + ucx_strtrim(string.ptr, string.length, &newstr.length);
432 newstr.ptr++; 494 return newstr;
433 newstr.length--; 495 }
434 } 496
435 while (newstr.length > 0 && isspace(newstr.ptr[newstr.length-1])) { 497 scstr_t scstrtrim(scstr_t string) {
436 newstr.length--; 498 scstr_t newstr;
437 } 499 newstr.ptr = string.ptr
438 500 + ucx_strtrim(string.ptr, string.length, &newstr.length);
439 return newstr; 501 return newstr;
440 } 502 }
441 503
442 int ucx_strprefix(scstr_t string, scstr_t prefix) { 504 int ucx_strprefix(scstr_t string, scstr_t prefix) {
443 if (string.length == 0) { 505 if (string.length == 0) {

mercurial