BLI_math_rotation: properly name the quaternion power function.
[blender.git] / source / blender / blenlib / intern / string_utils.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) 2017 by the Blender FOundation.
19  * All rights reserved.
20  *
21  * Contributor(s): none yet.
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  *
25  */
26
27 /** \file blender/blenlib/intern/string_utils.c
28  *  \ingroup bli
29  */
30
31 #include <ctype.h>
32 #include <string.h>
33 #include <stdlib.h>
34
35 #include "MEM_guardedalloc.h"
36
37 #include "BLI_listbase.h"
38 #include "BLI_string.h"
39 #include "BLI_string_utf8.h"
40 #include "BLI_string_utils.h"
41 #include "BLI_utildefines.h"
42
43 #include "DNA_listBase.h"
44
45
46 #ifdef __GNUC__
47 #  pragma GCC diagnostic error "-Wsign-conversion"
48 #endif
49
50 /**
51  * Looks for a numeric suffix preceded by delim character on the end of
52  * name, puts preceding part into *left and value of suffix into *nr.
53  * Returns the length of *left.
54  *
55  * Foo.001 -> "Foo", 1
56  * Returning the length of "Foo"
57  *
58  * \param left: Where to return copy of part preceding delim
59  * \param nr: Where to return value of numeric suffix
60  * \param name: String to split
61  * \param delim: Delimiter character
62  * \return  Length of \a left
63  */
64 size_t BLI_split_name_num(char *left, int *nr, const char *name, const char delim)
65 {
66         const size_t name_len = strlen(name);
67
68         *nr = 0;
69         memcpy(left, name, (name_len + 1) * sizeof(char));
70
71         /* name doesn't end with a delimiter "foo." */
72         if ((name_len > 1 && name[name_len - 1] == delim) == 0) {
73                 size_t a = name_len;
74                 while (a--) {
75                         if (name[a] == delim) {
76                                 left[a] = '\0';  /* truncate left part here */
77                                 *nr = atol(name + a + 1);
78                                 /* casting down to an int, can overflow for large numbers */
79                                 if (*nr < 0)
80                                         *nr = 0;
81                                 return a;
82                         }
83                         else if (isdigit(name[a]) == 0) {
84                                 /* non-numeric suffix - give up */
85                                 break;
86                         }
87                 }
88         }
89
90         return name_len;
91 }
92
93 static bool is_char_sep(const char c)
94 {
95         return ELEM(c, '.', ' ', '-', '_');
96 }
97
98 /**
99  * based on `BLI_split_dirfile()` / `os.path.splitext()`,
100  * `"a.b.c"` -> (`"a.b"`, `".c"`).
101  */
102 void BLI_string_split_suffix(const char *string, char *r_body, char *r_suf, const size_t str_len)
103 {
104         size_t len = BLI_strnlen(string, str_len);
105         size_t i;
106
107         r_body[0] = r_suf[0] = '\0';
108
109         for (i = len; i > 0; i--) {
110                 if (is_char_sep(string[i])) {
111                         BLI_strncpy(r_body, string, i + 1);
112                         BLI_strncpy(r_suf, string + i,  (len + 1) - i);
113                         return;
114                 }
115         }
116
117         memcpy(r_body, string, len + 1);
118 }
119
120 /**
121  * `"a.b.c"` -> (`"a."`, `"b.c"`)
122  */
123 void BLI_string_split_prefix(const char *string, char *r_pre, char *r_body, const size_t str_len)
124 {
125         size_t len = BLI_strnlen(string, str_len);
126         size_t i;
127
128         r_body[0] = r_pre[0] = '\0';
129
130         for (i = 1; i < len; i++) {
131                 if (is_char_sep(string[i])) {
132                         i++;
133                         BLI_strncpy(r_pre, string, i + 1);
134                         BLI_strncpy(r_body, string + i, (len + 1) - i);
135                         return;
136                 }
137         }
138
139         BLI_strncpy(r_body, string, len);
140 }
141
142 /**
143  * Finds the best possible flipped (left/right) name. For renaming; check for unique names afterwards.
144  *
145  * \param r_name: flipped name, assumed to be a pointer to a string of at least \a name_len size.
146  * \param from_name: original name, assumed to be a pointer to a string of at least \a name_len size.
147  * \param strip_number: If set, remove number extensions.
148  */
149 void BLI_string_flip_side_name(char *r_name, const char *from_name, const bool strip_number, const size_t name_len)
150 {
151         size_t len;
152         char *prefix  = alloca(name_len);   /* The part before the facing */
153         char *suffix  = alloca(name_len);   /* The part after the facing */
154         char *replace = alloca(name_len);   /* The replacement string */
155         char *number  = alloca(name_len);   /* The number extension string */
156         char *index = NULL;
157         bool is_set = false;
158
159         *prefix = *suffix = *replace = *number = '\0';
160
161         /* always copy the name, since this can be called with an uninitialized string */
162         BLI_strncpy(r_name, from_name, name_len);
163
164         len = BLI_strnlen(from_name, name_len);
165         if (len < 3) {
166                 /* we don't do names like .R or .L */
167                 return;
168         }
169
170         /* We first check the case with a .### extension, let's find the last period */
171         if (isdigit(r_name[len - 1])) {
172                 index = strrchr(r_name, '.'); // last occurrence
173                 if (index && isdigit(index[1])) { // doesnt handle case bone.1abc2 correct..., whatever!
174                         if (strip_number == false) {
175                                 BLI_strncpy(number, index, name_len);
176                         }
177                         *index = 0;
178                         len = BLI_strnlen(r_name, name_len);
179                 }
180         }
181
182         BLI_strncpy(prefix, r_name, name_len);
183
184         /* first case; separator . - _ with extensions r R l L  */
185         if ((len > 1) && is_char_sep(r_name[len - 2])) {
186                 is_set = true;
187                 switch (r_name[len - 1]) {
188                         case 'l':
189                                 prefix[len - 1] = 0;
190                                 strcpy(replace, "r");
191                                 break;
192                         case 'r':
193                                 prefix[len - 1] = 0;
194                                 strcpy(replace, "l");
195                                 break;
196                         case 'L':
197                                 prefix[len - 1] = 0;
198                                 strcpy(replace, "R");
199                                 break;
200                         case 'R':
201                                 prefix[len - 1] = 0;
202                                 strcpy(replace, "L");
203                                 break;
204                         default:
205                                 is_set = false;
206                 }
207         }
208
209         /* case; beginning with r R l L, with separator after it */
210         if (!is_set && is_char_sep(r_name[1])) {
211                 is_set = true;
212                 switch (r_name[0]) {
213                         case 'l':
214                                 strcpy(replace, "r");
215                                 BLI_strncpy(suffix, r_name + 1, name_len);
216                                 prefix[0] = 0;
217                                 break;
218                         case 'r':
219                                 strcpy(replace, "l");
220                                 BLI_strncpy(suffix, r_name + 1, name_len);
221                                 prefix[0] = 0;
222                                 break;
223                         case 'L':
224                                 strcpy(replace, "R");
225                                 BLI_strncpy(suffix, r_name + 1, name_len);
226                                 prefix[0] = 0;
227                                 break;
228                         case 'R':
229                                 strcpy(replace, "L");
230                                 BLI_strncpy(suffix, r_name + 1, name_len);
231                                 prefix[0] = 0;
232                                 break;
233                         default:
234                                 is_set = false;
235                 }
236         }
237
238         if (!is_set && len > 5) {
239                 /* hrms, why test for a separator? lets do the rule 'ultimate left or right' */
240                 if (((index = BLI_strcasestr(prefix, "right")) == prefix) ||
241                     (index == prefix + len - 5))
242                 {
243                         is_set = true;
244                         if (index[0] == 'r') {
245                                 strcpy(replace, "left");
246                         }
247                         else {
248                                 strcpy(replace, (index[1] == 'I') ? "LEFT" : "Left");
249                         }
250                         *index = 0;
251                         BLI_strncpy(suffix, index + 5, name_len);
252                 }
253                 else if (((index = BLI_strcasestr(prefix, "left")) == prefix) ||
254                          (index == prefix + len - 4))
255                 {
256                         is_set = true;
257                         if (index[0] == 'l') {
258                                 strcpy(replace, "right");
259                         }
260                         else {
261                                 strcpy(replace, (index[1] == 'E') ? "RIGHT" : "Right");
262                         }
263                         *index = 0;
264                         BLI_strncpy(suffix, index + 4, name_len);
265                 }
266         }
267
268         BLI_snprintf(r_name, name_len, "%s%s%s%s", prefix, replace, suffix, number);
269 }
270
271
272 /* Unique name utils. */
273
274 /**
275  * Ensures name is unique (according to criteria specified by caller in unique_check callback),
276  * incrementing its numeric suffix as necessary. Returns true if name had to be adjusted.
277  *
278  * \param unique_check: Return true if name is not unique
279  * \param arg: Additional arg to unique_check--meaning is up to caller
280  * \param defname: To initialize name if latter is empty
281  * \param delim: Delimits numeric suffix in name
282  * \param name: Name to be ensured unique
283  * \param name_len: Maximum length of name area
284  * \return true if there if the name was changed
285  */
286 bool BLI_uniquename_cb(
287         UniquenameCheckCallback unique_check, void *arg, const char *defname, char delim, char *name, size_t name_len)
288 {
289         if (name[0] == '\0') {
290                 BLI_strncpy(name, defname, name_len);
291         }
292
293         if (unique_check(arg, name)) {
294                 char numstr[16];
295                 char *tempname = alloca(name_len);
296                 char *left = alloca(name_len);
297                 int number;
298                 size_t len = BLI_split_name_num(left, &number, name, delim);
299                 do {
300                         /* add 1 to account for \0 */
301                         const size_t numlen = BLI_snprintf(numstr, sizeof(numstr), "%c%03d", delim, ++number) + 1;
302
303                         /* highly unlikely the string only has enough room for the number
304                          * but support anyway */
305                         if ((len == 0) || (numlen >= name_len)) {
306                                 /* number is know not to be utf-8 */
307                                 BLI_strncpy(tempname, numstr, name_len);
308                         }
309                         else {
310                                 char *tempname_buf;
311                                 tempname_buf = tempname + BLI_strncpy_utf8_rlen(tempname, left, name_len - numlen);
312                                 memcpy(tempname_buf, numstr, numlen);
313                         }
314                 } while (unique_check(arg, tempname));
315
316                 BLI_strncpy(name, tempname, name_len);
317
318                 return true;
319         }
320
321         return false;
322 }
323
324 /* little helper macro for BLI_uniquename */
325 #ifndef GIVE_STRADDR
326 #  define GIVE_STRADDR(data, offset) ( ((char *)data) + offset)
327 #endif
328
329 /**
330  * Generic function to set a unique name. It is only designed to be used in situations
331  * where the name is part of the struct.
332  *
333  * For places where this is used, see constraint.c for example...
334  *
335  * \param name_offs: should be calculated using offsetof(structname, membername) macro from stddef.h
336  */
337 static bool uniquename_find_dupe(ListBase *list, void *vlink, const char *name, int name_offs)
338 {
339         Link *link;
340
341         for (link = list->first; link; link = link->next) {
342                 if (link != vlink) {
343                         if (STREQ(GIVE_STRADDR(link, name_offs), name)) {
344                                 return true;
345                         }
346                 }
347         }
348
349         return false;
350 }
351
352 static bool uniquename_unique_check(void *arg, const char *name)
353 {
354         struct {ListBase *lb; void *vlink; int name_offs; } *data = arg;
355         return uniquename_find_dupe(data->lb, data->vlink, name, data->name_offs);
356 }
357
358 /**
359  * Ensures that the specified block has a unique name within the containing list,
360  * incrementing its numeric suffix as necessary. Returns true if name had to be adjusted.
361  *
362  * \param list: List containing the block
363  * \param vlink: The block to check the name for
364  * \param defname: To initialize block name if latter is empty
365  * \param delim: Delimits numeric suffix in name
366  * \param name_offs: Offset of name within block structure
367  * \param name_len: Maximum length of name area
368  */
369 bool BLI_uniquename(ListBase *list, void *vlink, const char *defname, char delim, int name_offs, size_t name_len)
370 {
371         struct {ListBase *lb; void *vlink; int name_offs; } data;
372         data.lb = list;
373         data.vlink = vlink;
374         data.name_offs = name_offs;
375
376         BLI_assert(name_len > 1);
377
378         /* See if we are given an empty string */
379         if (ELEM(NULL, vlink, defname))
380                 return false;
381
382         return BLI_uniquename_cb(uniquename_unique_check, &data, defname, delim, GIVE_STRADDR(vlink, name_offs), name_len);
383 }
384
385 /* ------------------------------------------------------------------------- */
386 /** \name Join Strings
387  *
388  * For non array versions of these functions, use the macros:
389  * - #BLI_string_joinN
390  * - #BLI_string_join_by_sep_charN
391  * - #BLI_string_join_by_sep_char_with_tableN
392  *
393  * \{ */
394
395 /**
396  * Join an array of strings into a newly allocated, null terminated string.
397  */
398 char *BLI_string_join_arrayN(
399         const char *strings[], uint strings_len)
400 {
401         uint total_len = 1;
402         for (uint i = 0; i < strings_len; i++) {
403                 total_len += strlen(strings[i]);
404         }
405         char *result = MEM_mallocN(sizeof(char) * total_len, __func__);
406         char *c = result;
407         for (uint i = 0; i < strings_len; i++) {
408                 c += BLI_strcpy_rlen(c, strings[i]);
409         }
410         return result;
411 }
412
413 /**
414  * A version of #BLI_string_joinN that takes a separator which can be any character including '\0'.
415  */
416 char *BLI_string_join_array_by_sep_charN(
417         char sep, const char *strings[], uint strings_len)
418 {
419         uint total_len = 0;
420         for (uint i = 0; i < strings_len; i++) {
421                 total_len += strlen(strings[i]) + 1;
422         }
423         if (total_len == 0) {
424                 total_len = 1;
425         }
426
427         char *result = MEM_mallocN(sizeof(char) * total_len, __func__);
428         char *c = result;
429         if (strings_len != 0) {
430                 for (uint i = 0; i < strings_len; i++) {
431                         c += BLI_strcpy_rlen(c, strings[i]);
432                         *c = sep;
433                         c++;
434                 }
435                 c--;
436         }
437         *c = '\0';
438         return result;
439 }
440
441 /**
442  * A version of #BLI_string_join_array_by_sep_charN that takes a table array.
443  * The new location of each string is written into this array.
444  */
445 char *BLI_string_join_array_by_sep_char_with_tableN(
446         char sep, char *table[], const char *strings[], uint strings_len)
447 {
448         uint total_len = 0;
449         for (uint i = 0; i < strings_len; i++) {
450                 total_len += strlen(strings[i]) + 1;
451         }
452         if (total_len == 0) {
453                 total_len = 1;
454         }
455
456         char *result = MEM_mallocN(sizeof(char) * total_len, __func__);
457         char *c = result;
458         if (strings_len != 0) {
459                 for (uint i = 0; i < strings_len; i++) {
460                         table[i] = c;  /* <-- only difference to BLI_string_join_array_by_sep_charN. */
461                         c += BLI_strcpy_rlen(c, strings[i]);
462                         *c = sep;
463                         c++;
464                 }
465                 c--;
466         }
467         *c = '\0';
468         return result;
469 }
470
471 /** \} */