2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19 * All rights reserved.
21 * The Original Code is: all of this file.
23 * Contributor(s): none yet.
25 * ***** END GPL LICENSE BLOCK *****
29 /** \file blender/blenlib/intern/string.c
39 #include "MEM_guardedalloc.h"
41 #include "BLI_dynstr.h"
42 #include "BLI_string.h"
44 #include "BLI_utildefines.h"
47 # pragma GCC diagnostic error "-Wsign-conversion"
50 // #define DEBUG_STRSIZE
53 * Duplicates the first \a len bytes of cstring \a str
54 * into a newly mallocN'd string and returns it. \a str
55 * is assumed to be at least len bytes long.
57 * \param str The string to be duplicated
58 * \param len The number of bytes to duplicate
59 * \retval Returns the duplicated string
61 char *BLI_strdupn(const char *str, const size_t len)
63 char *n = MEM_mallocN(len + 1, "strdup");
71 * Duplicates the cstring \a str into a newly mallocN'd
72 * string and returns it.
74 * \param str The string to be duplicated
75 * \retval Returns the duplicated string
77 char *BLI_strdup(const char *str)
79 return BLI_strdupn(str, strlen(str));
83 * Appends the two strings, and returns new mallocN'ed string
84 * \param str1 first string for copy
85 * \param str2 second string for append
88 char *BLI_strdupcat(const char *__restrict str1, const char *__restrict str2)
90 /* include the NULL terminator of str2 only */
91 const size_t str1_len = strlen(str1);
92 const size_t str2_len = strlen(str2) + 1;
95 str = MEM_mallocN(str1_len + str2_len, "strdupcat");
98 memcpy(s, str1, str1_len); s += str1_len;
99 memcpy(s, str2, str2_len);
105 * Like strncpy but ensures dst is always
108 * \param dst Destination for copy
109 * \param src Source string to copy
110 * \param maxncpy Maximum number of characters to copy (generally
112 * \retval Returns dst
114 char *BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy)
116 size_t srclen = BLI_strnlen(src, maxncpy - 1);
117 BLI_assert(maxncpy != 0);
120 memset(dst, 0xff, sizeof(*dst) * maxncpy);
123 memcpy(dst, src, srclen);
129 * Like BLI_strncpy but ensures dst is always padded by given char, on both sides (unless src is empty).
131 * \param dst Destination for copy
132 * \param src Source string to copy
133 * \param pad the char to use for padding
134 * \param maxncpy Maximum number of characters to copy (generally the size of dst)
135 * \retval Returns dst
137 char *BLI_strncpy_ensure_pad(char *__restrict dst, const char *__restrict src, const char pad, size_t maxncpy)
139 BLI_assert(maxncpy != 0);
142 memset(dst, 0xff, sizeof(*dst) * maxncpy);
145 if (src[0] == '\0') {
149 /* Add heading/trailing wildcards if needed. */
153 if (src[idx] != pad) {
157 maxncpy--; /* trailing '\0' */
159 srclen = BLI_strnlen(src, maxncpy);
160 if ((src[srclen - 1] != pad) && (srclen == maxncpy)) {
164 memcpy(&dst[idx], src, srclen);
167 if (dst[idx - 1] != pad) {
177 * Like strncpy but ensures dst is always
180 * \note This is a duplicate of #BLI_strncpy that returns bytes copied.
181 * And is a drop in replacement for 'snprintf(str, sizeof(str), "%s", arg);'
183 * \param dst Destination for copy
184 * \param src Source string to copy
185 * \param maxncpy Maximum number of characters to copy (generally
187 * \retval The number of bytes copied (The only difference from BLI_strncpy).
189 size_t BLI_strncpy_rlen(char *__restrict dst, const char *__restrict src, const size_t maxncpy)
191 size_t srclen = BLI_strnlen(src, maxncpy - 1);
192 BLI_assert(maxncpy != 0);
195 memset(dst, 0xff, sizeof(*dst) * maxncpy);
198 memcpy(dst, src, srclen);
203 size_t BLI_strcpy_rlen(char *__restrict dst, const char *__restrict src)
205 size_t srclen = strlen(src);
206 memcpy(dst, src, srclen + 1);
211 * Portable replacement for #vsnprintf
213 size_t BLI_vsnprintf(char *__restrict buffer, size_t maxncpy, const char *__restrict format, va_list arg)
217 BLI_assert(buffer != NULL);
218 BLI_assert(maxncpy > 0);
219 BLI_assert(format != NULL);
221 n = (size_t)vsnprintf(buffer, maxncpy, format, arg);
223 if (n != -1 && n < maxncpy) {
227 buffer[maxncpy - 1] = '\0';
234 * Portable replacement for #snprintf
236 size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format, ...)
242 memset(dst, 0xff, sizeof(*dst) * maxncpy);
245 va_start(arg, format);
246 n = BLI_vsnprintf(dst, maxncpy, format, arg);
253 * Print formatted string into a newly #MEM_mallocN'd string
256 char *BLI_sprintfN(const char *__restrict format, ...)
262 BLI_assert(format != NULL);
264 va_start(arg, format);
266 ds = BLI_dynstr_new();
267 BLI_dynstr_vappendf(ds, format, arg);
268 n = BLI_dynstr_get_cstring(ds);
277 /* match pythons string escaping, assume double quotes - (")
278 * TODO: should be used to create RNA animation paths.
279 * TODO: support more fancy string escaping. current code is primitive
280 * this basically is an ascii version of PyUnicode_EncodeUnicodeEscape()
281 * which is a useful reference. */
282 size_t BLI_strescape(char *__restrict dst, const char *__restrict src, const size_t maxncpy)
286 BLI_assert(maxncpy != 0);
288 while (len < maxncpy) {
296 /* less common but should also be support */
300 if (len + 1 < maxncpy) {
305 /* not enough space to escape */
326 * Makes a copy of the text within the "" that appear after some text 'blahblah'
327 * i.e. for string 'pose["apples"]' with prefix 'pose[', it should grab "apples"
329 * - str: is the entire string to chop
330 * - prefix: is the part of the string to leave out
332 * Assume that the strings returned must be freed afterwards, and that the inputs will contain
335 * \return the offset and a length so as to avoid doing an allocation.
337 char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict prefix)
339 size_t prefixLen = strlen(prefix);
340 const char *startMatch, *endMatch;
342 /* get the starting point (i.e. where prefix starts, and add prefixLen+1 to it to get be after the first " */
343 startMatch = strstr(str, prefix) + prefixLen + 1;
345 /* get the end point (i.e. where the next occurance of " is after the starting point) */
347 endMatch = startMatch;
348 while ((endMatch = strchr(endMatch, '"'))) {
349 if (LIKELY(*(endMatch - 1) != '\\')) {
358 /* return the slice indicated */
359 return BLI_strdupn(startMatch, (size_t)(endMatch - startMatch));
362 return BLI_strdupn("", 0);
366 * string with all instances of substr_old replaced with substr_new,
367 * Returns a copy of the cstring \a str into a newly mallocN'd
370 * \note A rather wasteful string-replacement utility, though this shall do for now...
371 * Feel free to replace this with an even safe + nicer alternative
373 * \param str The string to replace occurrences of substr_old in
374 * \param substr_old The text in the string to find and replace
375 * \param substr_new The text in the string to find and replace
376 * \retval Returns the duplicated string
378 char *BLI_replacestrN(const char *__restrict str, const char *__restrict substr_old, const char *__restrict substr_new)
381 size_t len_old = strlen(substr_old);
384 BLI_assert(substr_old[0] != '\0');
386 /* while we can still find a match for the old substring that we're searching for,
387 * keep dicing and replacing
389 while ((match = strstr(str, substr_old))) {
390 /* the assembly buffer only gets created when we actually need to rebuild the string */
392 ds = BLI_dynstr_new();
394 /* if the match position does not match the current position in the string,
395 * copy the text up to this position and advance the current position in the string
398 /* add the segment of the string from str to match to the buffer, then restore the value at match
400 BLI_dynstr_nappend(ds, str, (match - str));
402 /* now our current position should be set on the start of the match */
406 /* add the replacement text to the accumulation buffer */
407 BLI_dynstr_append(ds, substr_new);
409 /* advance the current position of the string up to the end of the replaced segment */
413 /* finish off and return a new string that has had all occurrences of */
417 /* add what's left of the string to the assembly buffer
418 * - we've been adjusting str to point at the end of the replaced segments
420 BLI_dynstr_append(ds, str);
422 /* convert to new c-string (MEM_malloc'd), and free the buffer */
423 str_new = BLI_dynstr_get_cstring(ds);
429 /* just create a new copy of the entire string - we avoid going through the assembly buffer
430 * for what should be a bit more efficiency...
432 return BLI_strdup(str);
437 * Compare two strings without regard to case.
439 * \retval True if the strings are equal, false otherwise.
441 int BLI_strcaseeq(const char *a, const char *b)
443 return (BLI_strcasecmp(a, b) == 0);
447 * Portable replacement for #strcasestr (not available in MSVC)
449 char *BLI_strcasestr(const char *s, const char *find)
454 if ((c = *find++) != 0) {
459 if ((sc = *s++) == 0)
463 } while (BLI_strncasecmp(s, find, len) != 0);
470 int BLI_strcasecmp(const char *s1, const char *s2)
473 register char c1, c2;
493 int BLI_strncasecmp(const char *s1, const char *s2, size_t len)
496 register char c1, c2;
498 for (i = 0; i < len; i++) {
516 /* compare number on the left size of the string */
517 static int left_number_strcmp(const char *s1, const char *s2, int *tiebreaker)
519 const char *p1 = s1, *p2 = s2;
520 int numdigit, numzero1, numzero2;
522 /* count and skip leading zeros */
523 for (numzero1 = 0; *p1 && (*p1 == '0'); numzero1++)
525 for (numzero2 = 0; *p2 && (*p2 == '0'); numzero2++)
528 /* find number of consecutive digits */
529 for (numdigit = 0; ; numdigit++) {
530 if (isdigit(*(p1 + numdigit)) && isdigit(*(p2 + numdigit)))
532 else if (isdigit(*(p1 + numdigit)))
533 return 1; /* s2 is bigger */
534 else if (isdigit(*(p2 + numdigit)))
535 return -1; /* s1 is bigger */
540 /* same number of digits, compare size of number */
542 int compare = (int)strncmp(p1, p2, (size_t)numdigit);
548 /* use number of leading zeros as tie breaker if still equal */
549 if (*tiebreaker == 0) {
550 if (numzero1 > numzero2)
552 else if (numzero1 < numzero2)
559 /* natural string compare, keeping numbers in order */
560 int BLI_natstrcmp(const char *s1, const char *s2)
562 register int d1 = 0, d2 = 0;
563 register char c1, c2;
566 /* if both chars are numeric, to a left_number_strcmp().
567 * then increase string deltas as long they are
568 * numeric, else do a tolower and char compare */
571 c1 = tolower(s1[d1]);
572 c2 = tolower(s2[d2]);
574 if (isdigit(c1) && isdigit(c2)) {
575 int numcompare = left_number_strcmp(s1 + d1, s2 + d2, &tiebreaker);
581 while (isdigit(s1[d1]))
584 while (isdigit(s2[d2]))
587 c1 = tolower(s1[d1]);
588 c2 = tolower(s2[d2]);
591 /* first check for '.' so "foo.bar" comes before "foo 1.bar" */
592 if (c1 == '.' && c2 != '.')
594 if (c1 != '.' && c2 == '.')
612 /* we might still have a different string because of lower/upper case, in
613 * that case fall back to regular string comparison */
614 return strcmp(s1, s2);
618 * Like strcmp, but will ignore any heading/trailing pad char for comparison.
619 * So e.g. if pad is '*', '*world' and 'world*' will compare equal.
621 int BLI_strcmp_ignore_pad(const char *str1, const char *str2, const char pad)
623 size_t str1_len, str2_len;
625 while (*str1 == pad) {
628 while (*str2 == pad) {
632 str1_len = strlen(str1);
633 str2_len = strlen(str2);
635 while (str1_len && (str1[str1_len - 1] == pad)) {
638 while (str2_len && (str2[str2_len - 1] == pad)) {
642 if (str1_len == str2_len) {
643 return strncmp(str1, str2, str2_len);
645 else if (str1_len > str2_len) {
646 int ret = strncmp(str1, str2, str2_len);
653 int ret = strncmp(str1, str2, str1_len);
661 void BLI_timestr(double _time, char *str, size_t maxlen)
663 /* format 00:00:00.00 (hr:min:sec) string has to be 12 long */
664 int hr = ( (int) _time) / (60 * 60);
665 int min = (((int) _time) / 60 ) % 60;
666 int sec = ( (int) _time) % 60;
667 int hun = ( (int) (_time * 100.0)) % 100;
670 BLI_snprintf(str, maxlen, "%.2d:%.2d:%.2d.%.2d", hr, min, sec, hun);
673 BLI_snprintf(str, maxlen, "%.2d:%.2d.%.2d", min, sec, hun);
677 /* determine the length of a fixed-size string */
678 size_t BLI_strnlen(const char *s, const size_t maxlen)
682 for (len = 0; len < maxlen; len++, s++) {
689 void BLI_ascii_strtolower(char *str, const size_t len)
693 for (i = 0; (i < len) && str[i]; i++)
694 if (str[i] >= 'A' && str[i] <= 'Z')
698 void BLI_ascii_strtoupper(char *str, const size_t len)
702 for (i = 0; (i < len) && str[i]; i++)
703 if (str[i] >= 'a' && str[i] <= 'z')
708 * Strip trailing zeros from a float, eg:
714 * \return The number of zeto's stripped.
716 int BLI_str_rstrip_float_zero(char *str, const char pad)
718 char *p = strchr(str, '.');
722 p++; /* position at first decimal place */
723 end_p = p + (strlen(p) - 1); /* position at last character */
725 while (end_p != p && *end_p == '0') {
736 * Return index of a string in a string array.
738 * \param str The string to find.
739 * \param str_array Array of strings.
740 * \param str_array_len The length of the array, or -1 for a NULL-terminated array.
741 * \return The index of str in str_array or -1.
743 int BLI_str_index_in_array_n(const char *__restrict str, const char **__restrict str_array, const int str_array_len)
746 const char **str_iter = str_array;
748 for (index = 0; index < str_array_len; str_iter++, index++) {
749 if (STREQ(str, *str_iter)) {
757 * Return index of a string in a string array.
759 * \param str The string to find.
760 * \param str_array Array of strings, (must be NULL-terminated).
761 * \return The index of str in str_array or -1.
763 int BLI_str_index_in_array(const char *__restrict str, const char **__restrict str_array)
766 const char **str_iter = str_array;
768 for (index = 0; *str_iter; str_iter++, index++) {
769 if (STREQ(str, *str_iter)) {
776 bool BLI_strn_endswith(const char *__restrict str, const char *__restrict end, size_t slength)
778 size_t elength = strlen(end);
780 if (elength < slength) {
781 const char *iter = &str[slength - elength];
783 if (*iter++ != *end++) {
793 * Find if a string ends with another string.
795 * \param str The string to search within.
796 * \param end The string we look for at the end.
797 * \return If str ends with end.
799 bool BLI_str_endswith(const char *__restrict str, const char *end)
801 const size_t slength = strlen(str);
802 return BLI_strn_endswith(str, end, slength);
806 * Find the first char matching one of the chars in \a delim, from left.
808 * \param str The string to search within.
809 * \param delim The set of delimiters to search for, as unicode values.
810 * \param sep Return value, set to the first delimiter found (or NULL if none found).
811 * \param suf Return value, set to next char after the first delimiter found (or NULL if none found).
812 * \return The length of the prefix (i.e. *sep - str).
814 size_t BLI_str_partition(const char *str, const char delim[], char **sep, char **suf)
816 return BLI_str_partition_ex(str, delim, sep, suf, false);
820 * Find the first char matching one of the chars in \a delim, from right.
822 * \param str The string to search within.
823 * \param delim The set of delimiters to search for, as unicode values.
824 * \param sep Return value, set to the first delimiter found (or NULL if none found).
825 * \param suf Return value, set to next char after the first delimiter found (or NULL if none found).
826 * \return The length of the prefix (i.e. *sep - str).
828 size_t BLI_str_rpartition(const char *str, const char delim[], char **sep, char **suf)
830 return BLI_str_partition_ex(str, delim, sep, suf, true);
834 * Find the first char matching one of the chars in \a delim, either from left or right.
836 * \param str The string to search within.
837 * \param delim The set of delimiters to search for, as unicode values.
838 * \param sep Return value, set to the first delimiter found (or NULL if none found).
839 * \param suf Return value, set to next char after the first delimiter found (or NULL if none found).
840 * \param from_right If %true, search from the right of \a str, else, search from its left.
841 * \return The length of the prefix (i.e. *sep - str).
843 size_t BLI_str_partition_ex(const char *str, const char delim[], char **sep, char **suf, const bool from_right)
846 char *(*func)(const char *str, int c) = from_right ? strrchr : strchr;
850 for (d = delim; *d != '\0'; ++d) {
851 char *tmp = func(str, *d);
853 if (tmp && (from_right ? (*sep < tmp) : (!*sep || *sep > tmp))) {
860 return (size_t)(*sep - str);
867 * Format ints with decimal grouping.
870 * \param dst The resulting string
871 * \param num Number to format
872 * \return The length of \a dst
874 size_t BLI_str_format_int_grouped(char dst[16], int num)
880 const char separator = ',';
883 num_len = sprintf(src, "%d", num);
890 for (commas = 2 - num_len % 3; *p_src; commas = (commas + 1) % 3) {
893 *p_dst++ = separator;
898 return (size_t)(p_dst - dst);