334 cxmutstr **output |
341 cxmutstr **output |
335 ) { |
342 ) { |
336 return cx_strsplit_a(allocator, cx_strcast(string), |
343 return cx_strsplit_a(allocator, cx_strcast(string), |
337 delim, limit, (cxstring **) output); |
344 delim, limit, (cxstring **) output); |
338 } |
345 } |
|
346 |
|
347 int cx_strcmp(cxstring s1, cxstring s2) { |
|
348 if (s1.length == s2.length) { |
|
349 return memcmp(s1.ptr, s2.ptr, s1.length); |
|
350 } else if (s1.length > s2.length) { |
|
351 return 1; |
|
352 } else { |
|
353 return -1; |
|
354 } |
|
355 } |
|
356 |
|
357 int cx_strcasecmp(cxstring s1, cxstring s2) { |
|
358 if (s1.length == s2.length) { |
|
359 #ifdef _WIN32 |
|
360 return _strnicmp(s1.ptr, s2.ptr, s1.length); |
|
361 #else |
|
362 return strncasecmp(s1.ptr, s2.ptr, s1.length); |
|
363 #endif |
|
364 } else if (s1.length > s2.length) { |
|
365 return 1; |
|
366 } else { |
|
367 return -1; |
|
368 } |
|
369 } |
|
370 |
|
371 cxmutstr cx_strdup_a(CxAllocator *allocator, cxstring string) { |
|
372 cxmutstr result = { |
|
373 cxMalloc(allocator, string.length + 1), |
|
374 string.length |
|
375 }; |
|
376 if (result.ptr == NULL) { |
|
377 result.length = 0; |
|
378 return result; |
|
379 } |
|
380 memcpy(result.ptr, string.ptr, string.length); |
|
381 result.ptr[string.length] = '\0'; |
|
382 return result; |
|
383 } |
|
384 |
|
385 cxstring cx_strtrim(cxstring string) { |
|
386 cxstring result = string; |
|
387 // TODO: optimize by comparing multiple bytes at once |
|
388 while (result.length > 0 && isspace(*result.ptr)) { |
|
389 result.ptr++; |
|
390 result.length--; |
|
391 } |
|
392 while (result.length > 0 && isspace(result.ptr[result.length - 1])) { |
|
393 result.length--; |
|
394 } |
|
395 return result; |
|
396 } |
|
397 |
|
398 cxmutstr cx_strtrim_m(cxmutstr string) { |
|
399 cxstring result = cx_strtrim(cx_strcast(string)); |
|
400 return (cxmutstr) {(char *) result.ptr, result.length}; |
|
401 } |
|
402 |
|
403 bool cx_strprefix(cxstring string, cxstring prefix) { |
|
404 if (string.length < prefix.length) return false; |
|
405 return memcmp(string.ptr, prefix.ptr, prefix.length) == 0; |
|
406 } |
|
407 |
|
408 bool cx_strsuffix(cxstring string, cxstring suffix) { |
|
409 if (string.length < suffix.length) return false; |
|
410 return memcmp(string.ptr + string.length - suffix.length, |
|
411 suffix.ptr, suffix.length) == 0; |
|
412 } |
|
413 |
|
414 bool cx_casestrprefix(cxstring string, cxstring prefix) { |
|
415 if (string.length < prefix.length) return false; |
|
416 #ifdef _WIN32 |
|
417 return _strnicmp(string.ptr, prefix.ptr, prefix.length) == 0; |
|
418 #else |
|
419 return strncasecmp(string.ptr, prefix.ptr, prefix.length) == 0; |
|
420 #endif |
|
421 } |
|
422 |
|
423 bool cx_casestrsuffix(cxstring string, cxstring suffix) { |
|
424 if (string.length < suffix.length) return false; |
|
425 #ifdef _WIN32 |
|
426 return _strnicmp(string.ptr+string.length-suffix.length, |
|
427 suffix.ptr, suffix.length) == 0; |
|
428 #else |
|
429 return strncasecmp(string.ptr + string.length - suffix.length, |
|
430 suffix.ptr, suffix.length) == 0; |
|
431 #endif |
|
432 } |