BLI_string, dont pass unicode to ascii BLI_str_partition functions
[blender.git] / source / blender / blenlib / intern / string.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
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.
8  *
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.
13  *
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.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  * 
27  */
28
29 /** \file blender/blenlib/intern/string.c
30  *  \ingroup bli
31  */
32
33
34 #include <string.h>
35 #include <stdlib.h>
36 #include <stdarg.h>
37 #include <ctype.h>
38
39 #include "MEM_guardedalloc.h"
40
41 #include "BLI_dynstr.h"
42 #include "BLI_string.h"
43
44 #include "BLI_utildefines.h"
45
46 #ifdef __GNUC__
47 #  pragma GCC diagnostic error "-Wsign-conversion"
48 #endif
49
50 // #define DEBUG_STRSIZE
51
52 /**
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.
56  *
57  * \param str The string to be duplicated
58  * \param len The number of bytes to duplicate
59  * \retval Returns the duplicated string
60  */
61 char *BLI_strdupn(const char *str, const size_t len)
62 {
63         char *n = MEM_mallocN(len + 1, "strdup");
64         memcpy(n, str, len);
65         n[len] = '\0';
66         
67         return n;
68 }
69
70 /**
71  * Duplicates the cstring \a str into a newly mallocN'd
72  * string and returns it.
73  *
74  * \param str The string to be duplicated
75  * \retval Returns the duplicated string
76  */
77 char *BLI_strdup(const char *str)
78 {
79         return BLI_strdupn(str, strlen(str));
80 }
81
82 /**
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
86  * \retval Returns dst
87  */
88 char *BLI_strdupcat(const char *__restrict str1, const char *__restrict str2)
89 {
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;
93         char *str, *s;
94         
95         str = MEM_mallocN(str1_len + str2_len, "strdupcat");
96         s = str;
97
98         memcpy(s, str1, str1_len); s += str1_len;
99         memcpy(s, str2, str2_len);
100
101         return str;
102 }
103
104 /**
105  * Like strncpy but ensures dst is always
106  * '\0' terminated.
107  *
108  * \param dst Destination for copy
109  * \param src Source string to copy
110  * \param maxncpy Maximum number of characters to copy (generally
111  * the size of dst)
112  * \retval Returns dst
113  */
114 char *BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy)
115 {
116         size_t srclen = BLI_strnlen(src, maxncpy - 1);
117         BLI_assert(maxncpy != 0);
118
119 #ifdef DEBUG_STRSIZE
120         memset(dst, 0xff, sizeof(*dst) * maxncpy);
121 #endif
122
123         memcpy(dst, src, srclen);
124         dst[srclen] = '\0';
125         return dst;
126 }
127
128 /**
129  * Like strncpy but ensures dst is always
130  * '\0' terminated.
131  *
132  * \note This is a duplicate of #BLI_strncpy that returns bytes copied.
133  * And is a drop in replacement for 'snprintf(str, sizeof(str), "%s", arg);'
134  *
135  * \param dst Destination for copy
136  * \param src Source string to copy
137  * \param maxncpy Maximum number of characters to copy (generally
138  * the size of dst)
139  * \retval The number of bytes copied (The only difference from BLI_strncpy).
140  */
141 size_t BLI_strncpy_rlen(char *__restrict dst, const char *__restrict src, const size_t maxncpy)
142 {
143         size_t srclen = BLI_strnlen(src, maxncpy - 1);
144         BLI_assert(maxncpy != 0);
145
146 #ifdef DEBUG_STRSIZE
147         memset(dst, 0xff, sizeof(*dst) * maxncpy);
148 #endif
149
150         memcpy(dst, src, srclen);
151         dst[srclen] = '\0';
152         return srclen;
153 }
154
155 size_t BLI_strcpy_rlen(char *__restrict dst, const char *__restrict src)
156 {
157         size_t srclen = strlen(src);
158         memcpy(dst, src, srclen + 1);
159         return srclen;
160 }
161
162 /**
163  * Portable replacement for #vsnprintf
164  */
165 size_t BLI_vsnprintf(char *__restrict buffer, size_t maxncpy, const char *__restrict format, va_list arg)
166 {
167         size_t n;
168
169         BLI_assert(buffer != NULL);
170         BLI_assert(maxncpy > 0);
171         BLI_assert(format != NULL);
172
173         n = (size_t)vsnprintf(buffer, maxncpy, format, arg);
174
175         if (n != -1 && n < maxncpy) {
176                 buffer[n] = '\0';
177         }
178         else {
179                 buffer[maxncpy - 1] = '\0';
180         }
181
182         return n;
183 }
184
185 /**
186  * Portable replacement for #snprintf
187  */
188 size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format, ...)
189 {
190         size_t n;
191         va_list arg;
192
193 #ifdef DEBUG_STRSIZE
194         memset(dst, 0xff, sizeof(*dst) * maxncpy);
195 #endif
196
197         va_start(arg, format);
198         n = BLI_vsnprintf(dst, maxncpy, format, arg);
199         va_end(arg);
200
201         return n;
202 }
203
204 /**
205  * Print formatted string into a newly #MEM_mallocN'd string
206  * and return it.
207  */
208 char *BLI_sprintfN(const char *__restrict format, ...)
209 {
210         DynStr *ds;
211         va_list arg;
212         char *n;
213
214         BLI_assert(format != NULL);
215
216         va_start(arg, format);
217
218         ds = BLI_dynstr_new();
219         BLI_dynstr_vappendf(ds, format, arg);
220         n = BLI_dynstr_get_cstring(ds);
221         BLI_dynstr_free(ds);
222
223         va_end(arg);
224
225         return n;
226 }
227
228
229 /* match pythons string escaping, assume double quotes - (")
230  * TODO: should be used to create RNA animation paths.
231  * TODO: support more fancy string escaping. current code is primitive
232  *    this basically is an ascii version of PyUnicode_EncodeUnicodeEscape()
233  *    which is a useful reference. */
234 size_t BLI_strescape(char *__restrict dst, const char *__restrict src, const size_t maxncpy)
235 {
236         size_t len = 0;
237
238         BLI_assert(maxncpy != 0);
239
240         while (len < maxncpy) {
241                 switch (*src) {
242                         case '\0':
243                                 goto escape_finish;
244                         case '\\':
245                         case '"':
246                                 /* fall-through */
247
248                         /* less common but should also be support */
249                         case '\t':
250                         case '\n':
251                         case '\r':
252                                 if (len + 1 < maxncpy) {
253                                         *dst++ = '\\';
254                                         len++;
255                                 }
256                                 else {
257                                         /* not enough space to escape */
258                                         break;
259                                 }
260                                 /* fall-through */
261                         default:
262                                 *dst = *src;
263                                 break;
264                 }
265                 dst++;
266                 src++;
267                 len++;
268         }
269
270 escape_finish:
271
272         *dst = '\0';
273
274         return len;
275 }
276
277 /**
278  * Makes a copy of the text within the "" that appear after some text 'blahblah'
279  * i.e. for string 'pose["apples"]' with prefix 'pose[', it should grab "apples"
280  *
281  * - str: is the entire string to chop
282  * - prefix: is the part of the string to leave out
283  *
284  * Assume that the strings returned must be freed afterwards, and that the inputs will contain
285  * data we want...
286  *
287  * \return the offset and a length so as to avoid doing an allocation.
288  */
289 char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict prefix)
290 {
291         size_t prefixLen = strlen(prefix);
292         const char *startMatch, *endMatch;
293         
294         /* get the starting point (i.e. where prefix starts, and add prefixLen+1 to it to get be after the first " */
295         startMatch = strstr(str, prefix) + prefixLen + 1;
296         if (startMatch) {
297                 /* get the end point (i.e. where the next occurance of " is after the starting point) */
298
299                 endMatch = startMatch;
300                 while ((endMatch = strchr(endMatch, '"'))) {
301                         if (LIKELY(*(endMatch - 1) != '\\')) {
302                                 break;
303                         }
304                         else {
305                                 endMatch++;
306                         }
307                 }
308
309                 if (endMatch) {
310                         /* return the slice indicated */
311                         return BLI_strdupn(startMatch, (size_t)(endMatch - startMatch));
312                 }
313         }
314         return BLI_strdupn("", 0);
315 }
316
317 /**
318  * string with all instances of substr_old replaced with substr_new,
319  * Returns a copy of the cstring \a str into a newly mallocN'd
320  * and returns it.
321  *
322  * \note A rather wasteful string-replacement utility, though this shall do for now...
323  * Feel free to replace this with an even safe + nicer alternative
324  *
325  * \param str The string to replace occurrences of substr_old in
326  * \param substr_old The text in the string to find and replace
327  * \param substr_new The text in the string to find and replace
328  * \retval Returns the duplicated string
329  */
330 char *BLI_replacestrN(const char *__restrict str, const char *__restrict substr_old, const char *__restrict substr_new)
331 {
332         DynStr *ds = NULL;
333         size_t len_old = strlen(substr_old);
334         const char *match;
335
336         BLI_assert(substr_old[0] != '\0');
337
338         /* while we can still find a match for the old substring that we're searching for, 
339          * keep dicing and replacing
340          */
341         while ((match = strstr(str, substr_old))) {
342                 /* the assembly buffer only gets created when we actually need to rebuild the string */
343                 if (ds == NULL)
344                         ds = BLI_dynstr_new();
345                         
346                 /* if the match position does not match the current position in the string, 
347                  * copy the text up to this position and advance the current position in the string
348                  */
349                 if (str != match) {
350                         /* add the segment of the string from str to match to the buffer, then restore the value at match
351                          */
352                         BLI_dynstr_nappend(ds, str, (match - str));
353                         
354                         /* now our current position should be set on the start of the match */
355                         str = match;
356                 }
357                 
358                 /* add the replacement text to the accumulation buffer */
359                 BLI_dynstr_append(ds, substr_new);
360                 
361                 /* advance the current position of the string up to the end of the replaced segment */
362                 str += len_old;
363         }
364         
365         /* finish off and return a new string that has had all occurrences of */
366         if (ds) {
367                 char *str_new;
368                 
369                 /* add what's left of the string to the assembly buffer 
370                  * - we've been adjusting str to point at the end of the replaced segments
371                  */
372                 BLI_dynstr_append(ds, str);
373                 
374                 /* convert to new c-string (MEM_malloc'd), and free the buffer */
375                 str_new = BLI_dynstr_get_cstring(ds);
376                 BLI_dynstr_free(ds);
377                 
378                 return str_new;
379         }
380         else {
381                 /* just create a new copy of the entire string - we avoid going through the assembly buffer 
382                  * for what should be a bit more efficiency...
383                  */
384                 return BLI_strdup(str);
385         }
386
387
388 /**
389  * Compare two strings without regard to case.
390  *
391  * \retval True if the strings are equal, false otherwise.
392  */
393 int BLI_strcaseeq(const char *a, const char *b) 
394 {
395         return (BLI_strcasecmp(a, b) == 0);
396 }
397
398 /**
399  * Portable replacement for #strcasestr (not available in MSVC)
400  */
401 char *BLI_strcasestr(const char *s, const char *find)
402 {
403         register char c, sc;
404         register size_t len;
405         
406         if ((c = *find++) != 0) {
407                 c = tolower(c);
408                 len = strlen(find);
409                 do {
410                         do {
411                                 if ((sc = *s++) == 0)
412                                         return (NULL);
413                                 sc = tolower(sc);
414                         } while (sc != c);
415                 } while (BLI_strncasecmp(s, find, len) != 0);
416                 s--;
417         }
418         return ((char *) s);
419 }
420
421
422 int BLI_strcasecmp(const char *s1, const char *s2)
423 {
424         register int i;
425         register char c1, c2;
426
427         for (i = 0;; i++) {
428                 c1 = tolower(s1[i]);
429                 c2 = tolower(s2[i]);
430
431                 if (c1 < c2) {
432                         return -1;
433                 }
434                 else if (c1 > c2) {
435                         return 1;
436                 }
437                 else if (c1 == 0) {
438                         break;
439                 }
440         }
441
442         return 0;
443 }
444
445 int BLI_strncasecmp(const char *s1, const char *s2, size_t len)
446 {
447         register size_t i;
448         register char c1, c2;
449
450         for (i = 0; i < len; i++) {
451                 c1 = tolower(s1[i]);
452                 c2 = tolower(s2[i]);
453
454                 if (c1 < c2) {
455                         return -1;
456                 }
457                 else if (c1 > c2) {
458                         return 1;
459                 }
460                 else if (c1 == 0) {
461                         break;
462                 }
463         }
464
465         return 0;
466 }
467
468 /* compare number on the left size of the string */
469 static int left_number_strcmp(const char *s1, const char *s2, int *tiebreaker)
470 {
471         const char *p1 = s1, *p2 = s2;
472         int numdigit, numzero1, numzero2;
473
474         /* count and skip leading zeros */
475         for (numzero1 = 0; *p1 && (*p1 == '0'); numzero1++)
476                 p1++;
477         for (numzero2 = 0; *p2 && (*p2 == '0'); numzero2++)
478                 p2++;
479
480         /* find number of consecutive digits */
481         for (numdigit = 0; ; numdigit++) {
482                 if (isdigit(*(p1 + numdigit)) && isdigit(*(p2 + numdigit)))
483                         continue;
484                 else if (isdigit(*(p1 + numdigit)))
485                         return 1; /* s2 is bigger */
486                 else if (isdigit(*(p2 + numdigit)))
487                         return -1; /* s1 is bigger */
488                 else
489                         break;
490         }
491
492         /* same number of digits, compare size of number */
493         if (numdigit > 0) {
494                 int compare = (int)strncmp(p1, p2, (size_t)numdigit);
495
496                 if (compare != 0)
497                         return compare;
498         }
499
500         /* use number of leading zeros as tie breaker if still equal */
501         if (*tiebreaker == 0) {
502                 if (numzero1 > numzero2)
503                         *tiebreaker = 1;
504                 else if (numzero1 < numzero2)
505                         *tiebreaker = -1;
506         }
507
508         return 0;
509 }
510
511 /* natural string compare, keeping numbers in order */
512 int BLI_natstrcmp(const char *s1, const char *s2)
513 {
514         register int d1 = 0, d2 = 0;
515         register char c1, c2;
516         int tiebreaker = 0;
517
518         /* if both chars are numeric, to a left_number_strcmp().
519          * then increase string deltas as long they are 
520          * numeric, else do a tolower and char compare */
521
522         while (1) {
523                 c1 = tolower(s1[d1]);
524                 c2 = tolower(s2[d2]);
525                 
526                 if (isdigit(c1) && isdigit(c2)) {
527                         int numcompare = left_number_strcmp(s1 + d1, s2 + d2, &tiebreaker);
528                         
529                         if (numcompare != 0)
530                                 return numcompare;
531
532                         d1++;
533                         while (isdigit(s1[d1]))
534                                 d1++;
535                         d2++;
536                         while (isdigit(s2[d2]))
537                                 d2++;
538                         
539                         c1 = tolower(s1[d1]);
540                         c2 = tolower(s2[d2]);
541                 }
542         
543                 /* first check for '.' so "foo.bar" comes before "foo 1.bar" */
544                 if (c1 == '.' && c2 != '.')
545                         return -1;
546                 if (c1 != '.' && c2 == '.')
547                         return 1;
548                 else if (c1 < c2) {
549                         return -1;
550                 }
551                 else if (c1 > c2) {
552                         return 1;
553                 }
554                 else if (c1 == 0) {
555                         break;
556                 }
557                 d1++;
558                 d2++;
559         }
560
561         if (tiebreaker)
562                 return tiebreaker;
563         
564         /* we might still have a different string because of lower/upper case, in
565          * that case fall back to regular string comparison */
566         return strcmp(s1, s2);
567 }
568
569 void BLI_timestr(double _time, char *str, size_t maxlen)
570 {
571         /* format 00:00:00.00 (hr:min:sec) string has to be 12 long */
572         int  hr = ( (int)  _time) / (60 * 60);
573         int min = (((int)  _time) / 60 ) % 60;
574         int sec = ( (int)  _time) % 60;
575         int hun = ( (int) (_time   * 100.0)) % 100;
576
577         if (hr) {
578                 BLI_snprintf(str, maxlen, "%.2d:%.2d:%.2d.%.2d", hr, min, sec, hun);
579         }
580         else {
581                 BLI_snprintf(str, maxlen, "%.2d:%.2d.%.2d", min, sec, hun);
582         }
583 }
584
585 /* determine the length of a fixed-size string */
586 size_t BLI_strnlen(const char *s, const size_t maxlen)
587 {
588         size_t len;
589
590         for (len = 0; len < maxlen; len++, s++) {
591                 if (!*s)
592                         break;
593         }
594         return len;
595 }
596
597 void BLI_ascii_strtolower(char *str, const size_t len)
598 {
599         size_t i;
600
601         for (i = 0; (i < len) && str[i]; i++)
602                 if (str[i] >= 'A' && str[i] <= 'Z')
603                         str[i] += 'a' - 'A';
604 }
605
606 void BLI_ascii_strtoupper(char *str, const size_t len)
607 {
608         size_t i;
609
610         for (i = 0; (i < len) && str[i]; i++)
611                 if (str[i] >= 'a' && str[i] <= 'z')
612                         str[i] -= 'a' - 'A';
613 }
614
615 /**
616  * Strip trailing zeros from a float, eg:
617  *   0.0000 -> 0.0
618  *   2.0010 -> 2.001
619  *
620  * \param str
621  * \param pad
622  * \return The number of zeto's stripped.
623  */
624 int BLI_str_rstrip_float_zero(char *str, const char pad)
625 {
626         char *p = strchr(str, '.');
627         int totstrip = 0;
628         if (p) {
629                 char *end_p;
630                 p++;  /* position at first decimal place */
631                 end_p = p + (strlen(p) - 1);  /* position at last character */
632                 if (end_p > p) {
633                         while (end_p != p && *end_p == '0') {
634                                 *end_p = pad;
635                                 end_p--;
636                         }
637                 }
638         }
639
640         return totstrip;
641 }
642
643 /**
644  * Return index of a string in a string array.
645  *
646  * \param str The string to find.
647  * \param str_array Array of strings.
648  * \param str_array_len The length of the array, or -1 for a NULL-terminated array.
649  * \return The index of str in str_array or -1.
650  */
651 int BLI_str_index_in_array_n(const char *str, const char **str_array, const int str_array_len)
652 {
653         int index;
654         const char **str_iter = str_array;
655
656         for (index = 0; index < str_array_len; str_iter++, index++) {
657                 if (STREQ(str, *str_iter)) {
658                         return index;
659                 }
660         }
661         return -1;
662 }
663
664 /**
665  * Return index of a string in a string array.
666  *
667  * \param str The string to find.
668  * \param str_array Array of strings, (must be NULL-terminated).
669  * \return The index of str in str_array or -1.
670  */
671 int BLI_str_index_in_array(const char *str, const char **str_array)
672 {
673         int index;
674         const char **str_iter = str_array;
675
676         for (index = 0; *str_iter; str_iter++, index++) {
677                 if (STREQ(str, *str_iter)) {
678                         return index;
679                 }
680         }
681         return -1;
682 }
683
684 /**
685  * Find the first char matching one of the chars in \a delim, from left.
686  *
687  * \param str The string to search within.
688  * \param delim The set of delimiters to search for, as unicode values.
689  * \param sep Return value, set to the first delimiter found (or NULL if none found).
690  * \param suf Return value, set to next char after the first delimiter found (or NULL if none found).
691  * \return The length of the prefix (i.e. *sep - str).
692  */
693 size_t BLI_str_partition(const char *str, const char delim[], char **sep, char **suf)
694 {
695         return BLI_str_partition_ex(str, delim, sep, suf, false);
696 }
697
698 /**
699  * Find the first char matching one of the chars in \a delim, from right.
700  *
701  * \param str The string to search within.
702  * \param delim The set of delimiters to search for, as unicode values.
703  * \param sep Return value, set to the first delimiter found (or NULL if none found).
704  * \param suf Return value, set to next char after the first delimiter found (or NULL if none found).
705  * \return The length of the prefix (i.e. *sep - str).
706  */
707 size_t BLI_str_rpartition(const char *str, const char delim[], char **sep, char **suf)
708 {
709         return BLI_str_partition_ex(str, delim, sep, suf, true);
710 }
711
712 /**
713  * Find the first char matching one of the chars in \a delim, either from left or right.
714  *
715  * \param str The string to search within.
716  * \param delim The set of delimiters to search for, as unicode values.
717  * \param sep Return value, set to the first delimiter found (or NULL if none found).
718  * \param suf Return value, set to next char after the first delimiter found (or NULL if none found).
719  * \param from_right If %true, search from the right of \a str, else, search from its left.
720  * \return The length of the prefix (i.e. *sep - str).
721  */
722 size_t BLI_str_partition_ex(const char *str, const char delim[], char **sep, char **suf, const bool from_right)
723 {
724         const char *d;
725         char *(*func)(const char *str, int c) = from_right ? strrchr : strchr;
726
727         *sep = *suf = NULL;
728
729         for (d = delim; *d != '\0'; ++d) {
730                 char *tmp = func(str, *d);
731
732                 if (tmp && (from_right ? (*sep < tmp) : (!*sep || *sep > tmp))) {
733                         *sep = tmp;
734                 }
735         }
736
737         if (*sep) {
738                 *suf = *sep + 1;
739                 return (size_t)(*sep - str);
740         }
741
742         return strlen(str);
743 }