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.
This commit is contained in:
parent
7fc1d76037
commit
15d801625c
|
@ -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();
|
||||
|
|
|
@ -356,6 +356,41 @@ size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, const si
|
|||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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"
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue