diff options
author | Campbell Barton <ideasman42@gmail.com> | 2020-12-10 05:42:59 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2020-12-10 06:40:01 +0300 |
commit | 15d801625cbb2566815a6fed2fc036a14336fec0 (patch) | |
tree | d9f73879e45ffac3f4494ddecc4fad16ed5a856e /source/blender | |
parent | 7fc1d760378f5c538c44bc4730c98af820678e4d (diff) |
BLI_string: add BLI_str_unescape utility function
Performs the reverse of BLI_str_escape.
This allows logic to be removed from RNA path handling.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenlib/BLI_string.h | 2 | ||||
-rw-r--r-- | source/blender/blenlib/intern/string.c | 35 | ||||
-rw-r--r-- | source/blender/blenlib/tests/BLI_string_test.cc | 6 |
3 files changed, 42 insertions, 1 deletions
diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h index d88a28a2fb8..2d1f8ac9c5e 100644 --- a/source/blender/blenlib/BLI_string.h +++ b/source/blender/blenlib/BLI_string.h @@ -87,6 +87,8 @@ char *BLI_sprintfN(const char *__restrict format, ...) ATTR_WARN_UNUSED_RESULT size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, const size_t dst_maxncpy) ATTR_NONNULL(); +size_t BLI_str_unescape(char *__restrict dst, const char *__restrict src, const size_t src_maxncpy) + ATTR_NONNULL(); size_t BLI_str_format_int_grouped(char dst[16], int num) ATTR_NONNULL(); size_t BLI_str_format_uint64_grouped(char dst[16], uint64_t num) ATTR_NONNULL(); diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c index 4734753d304..c8b2f3f6e93 100644 --- a/source/blender/blenlib/intern/string.c +++ b/source/blender/blenlib/intern/string.c @@ -357,6 +357,41 @@ size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, const si } /** + * This roughly matches C and Python's string escaping with double quotes - `"`. + * + * The destination will never be larger than the source, it will either be the same + * or up to half when all characters are escaped. + * + * \param dst: The destination string, at least the size of `strlen(src) + 1`. + * \param src: The escaped source string. + * \param dst_maxncpy: The maximum number of bytes allowable to copy. + * + * \note This is used for for parsing animation paths in blend files. + */ +size_t BLI_str_unescape(char *__restrict dst, const char *__restrict src, const size_t src_maxncpy) +{ + size_t len = 0; + for (size_t i = 0; i < src_maxncpy && (*src != '\0'); i++, src++) { + char c = *src; + if (c == '\\') { + char c_next = *(src + 1); + if (((c_next == '"') && ((void)(c = '"'), true)) || /* Quote. */ + ((c_next == '\\') && ((void)(c = '\\'), true)) || /* Backslash. */ + ((c_next == 't') && ((void)(c = '\t'), true)) || /* Tab. */ + ((c_next == 'n') && ((void)(c = '\n'), true))) /* Newline. */ + { + i++; + src++; + } + } + + dst[len++] = c; + } + dst[len] = 0; + return len; +} + +/** * Makes a copy of the text within the "" that appear after some text 'blahblah' * i.e. for string 'pose["apples"]' with prefix 'pose[', it should grab "apples" * diff --git a/source/blender/blenlib/tests/BLI_string_test.cc b/source/blender/blenlib/tests/BLI_string_test.cc index 7ef2f5a888e..4b6cad12813 100644 --- a/source/blender/blenlib/tests/BLI_string_test.cc +++ b/source/blender/blenlib/tests/BLI_string_test.cc @@ -803,7 +803,7 @@ TEST_F(StringCasecmpNatural, TextAndNumbers) testReturnsMoreThanZeroForAll(positive); } -/* BLI_str_escape */ +/* BLI_str_escape, BLI_str_unescape */ class StringEscape : public testing::Test { protected: @@ -822,6 +822,10 @@ class StringEscape : public testing::Test { dst_test_len = BLI_str_escape(dst_test, item[0], SIZE_MAX); EXPECT_STREQ(dst_test, item[1]); EXPECT_EQ(dst_test_len, strlen(dst_test)); + /* Escape back. */ + dst_test_len = BLI_str_unescape(dst_test, item[1], strlen(item[1])); + EXPECT_STREQ(dst_test, item[0]); + EXPECT_EQ(dst_test_len, strlen(dst_test)); } } }; |